blob: 51603cec54f99b3f1ec43d2f95f100f50a56490e [file] [log] [blame]
//------------------------------------------------------------------------------
// Copyright (c) 2005, 2006 IBM Corporation and others.
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// which accompanies this distribution, and is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// Contributors:
// IBM Corporation - initial implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.persistence;
import java.io.File;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.emf.common.CommonPlugin;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.common.util.WrappedException;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.epf.common.serviceability.MsgBox;
import org.eclipse.epf.library.persistence.internal.IFailSafeSavable;
import org.eclipse.epf.persistence.refresh.RefreshJob;
import org.eclipse.epf.persistence.util.PersistenceResources;
import org.eclipse.epf.persistence.util.PersistenceUtil;
import org.eclipse.epf.services.IFileBasedLibraryPersister;
import org.eclipse.epf.uma.CapabilityPattern;
import org.eclipse.epf.uma.ContentDescription;
import org.eclipse.epf.uma.ContentElement;
import org.eclipse.epf.uma.DeliveryProcess;
import org.eclipse.epf.uma.DescribableElement;
import org.eclipse.epf.uma.MethodConfiguration;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.MethodLibrary;
import org.eclipse.epf.uma.MethodPlugin;
import org.eclipse.epf.uma.MethodUnit;
import org.eclipse.epf.uma.Process;
import org.eclipse.epf.uma.ProcessComponent;
import org.eclipse.epf.uma.UmaPackage;
import org.eclipse.epf.uma.ecore.impl.MultiResourceEObject;
import org.eclipse.epf.uma.util.UmaUtil;
import org.eclipse.osgi.util.NLS;
/**
* File-based implementation for IMethodLibraryPersister
*
* @author Phong Nguyen Le
* @since 1.0
*/
public class MethodLibraryPersister implements IFileBasedLibraryPersister {
private static class FolderInfo {
EClass eClazz;
boolean shared;
private String name;
/**
* @param clazz
* @param shared
*/
public FolderInfo(EClass clazz, boolean shared) {
super();
eClazz = clazz;
this.shared = shared;
this.name = lowerAndPluralize(clazz.getName());
}
}
public static final MethodLibraryPersister INSTANCE = new MethodLibraryPersister();
// need to expose this, jxi
public static final String RESOURCE_FOLDER = "resources"; //$NON-NLS-1$
private static final List folderInfos = new ArrayList();
static {
folderInfos.add(new FolderInfo(UmaPackage.eINSTANCE.getGuidance(),
false));
folderInfos.add(new FolderInfo(UmaPackage.eINSTANCE.getWorkProduct(),
true));
folderInfos
.add(new FolderInfo(UmaPackage.eINSTANCE.getActivity(), true));
}
protected List warnings;
public MethodLibraryPersister() {
}
/**
* Returns the correct path (relative to the plugin) of the file of the
* given content description or null if the given content does not be long
* to any plugin.
*
* @param content
* @return
*/
public static String getCorrectPath(ContentDescription content) {
return getCorrectPath((DescribableElement) content.eContainer(),
content);
}
private static String getCorrectPath(DescribableElement e,
ContentDescription content) {
if (e == null)
return null;
MethodPlugin plugin = UmaUtil.getMethodPlugin(e);
if (plugin == null) {
return null;
}
Resource resource = plugin.eResource();
URI uri;
if (resource instanceof MultiFileXMIResourceImpl) {
uri = ((MultiFileXMIResourceImpl) resource).getFinalURI();
} else {
uri = resource.getURI();
}
File pluginDir = new File(uri.toFileString()).getParentFile();
String folderPath = staticGetFolderPath(e.eClass());
String dir = new StringBuffer(pluginDir.getAbsolutePath()).append(
File.separator).append(folderPath).append(File.separator)
.toString();
return getNextAvailableFileName(dir, e, content);
}
static String getNextAvailableFileName(String dir, String requestedName,
MultiResourceEObject e) {
String currentFilename = null;
File currentFile = null;
MultiFileXMIResourceImpl resource = (MultiFileXMIResourceImpl) e
.eDirectResource();
if (resource != null) {
// keep existing file name during move if it is not taken yet. Don't
// try to match the element's name
//
String path = ((MultiFileXMIResourceImpl) e.eResource())
.getFinalURI().toFileString();
currentFile = new File(path);
currentFilename = currentFile.getName();
File file = new File(dir, currentFilename);
if (!file.exists()) {
// the element is being moved
//
return file.getAbsolutePath();
}
}
// element without a resource or path is already taken
//
String path = new StringBuffer(dir).append(requestedName).append(
MultiFileSaveUtil.DEFAULT_FILE_EXTENSION).toString();
File file = new File(path);
if(file.equals(currentFile)) {
return path;
}
if ((currentFilename != null && currentFilename.equals(requestedName))
|| file.exists()) {
for (int i = 2; true; i++) {
path = new StringBuffer(dir).append(requestedName).append(' ')
.append(i).append(
MultiFileSaveUtil.DEFAULT_FILE_EXTENSION)
.toString();
if (!new File(path).exists()) {
return path;
}
}
} else {
return path;
}
}
static String getNextAvailableFileName(String dir,
ContentDescription content) {
return getNextAvailableFileName(dir, (DescribableElement) content
.eContainer(), content);
}
private static String getNextAvailableFileName(String dir,
DescribableElement e, ContentDescription content) {
return getNextAvailableFileName(dir, e.getName(),
(MultiResourceEObject) content);
}
private static String staticGetFolderPath(EClass eClazz) {
int size = folderInfos.size();
FolderInfo info = null;
for (int i = 0; i < size; i++) {
FolderInfo folderInfo = (FolderInfo) folderInfos.get(i);
if (folderInfo.eClazz.isSuperTypeOf(eClazz)) {
info = folderInfo;
}
}
if (info != null) {
if (info.eClazz == eClazz || info.shared) {
return info.name;
} else {
return new StringBuffer(info.name).append(File.separatorChar)
.append(lowerAndPluralize(eClazz.getName())).toString();
}
} else {
return lowerAndPluralize(eClazz.getName());
}
}
public static String lowerAndPluralize(String name) {
name = name.toLowerCase();
if (name.endsWith("children")) { //$NON-NLS-1$
return name;
} else if (name.endsWith("child")) { //$NON-NLS-1$
return name + "ren"; //$NON-NLS-1$
} else if (name.endsWith("data")) { //$NON-NLS-1$
return name;
} else if (name.endsWith("datum")) { //$NON-NLS-1$
return name.substring(0, name.length() - 2) + "a"; //$NON-NLS-1$
} else if (name.endsWith("by")) { //$NON-NLS-1$
return name + "s"; //$NON-NLS-1$
} else if (name.endsWith("y")) { //$NON-NLS-1$
return name.substring(0, name.length() - 1) + "ies"; //$NON-NLS-1$
} else if (name.endsWith("ex")) { //$NON-NLS-1$
return name.substring(0, name.length() - 2) + "ices"; //$NON-NLS-1$
} else if (name.endsWith("x")) { //$NON-NLS-1$
return name + "es"; //$NON-NLS-1$
} else if (name.endsWith("us")) { //$NON-NLS-1$
return name.substring(0, name.length() - 2) + "i"; //$NON-NLS-1$
} else if (name.endsWith("ss")) { //$NON-NLS-1$
return name + "es"; //$NON-NLS-1$
} else if (name.endsWith("s")) { //$NON-NLS-1$
return name;
} else {
return name + "s"; //$NON-NLS-1$
}
}
/**
* Gets the path relative to the library root directory to the resource
* folder of the given MethodElement object.
*
* @param e
* @return
*/
public static String getResourcePath(MethodElement e) {
String folderPath = getElementPath(e);
if (folderPath == null || folderPath.equals("")) //$NON-NLS-1$
{
return RESOURCE_FOLDER;
} else if (folderPath.endsWith(File.separator)) {
return new StringBuffer(folderPath).append(RESOURCE_FOLDER)
.toString();
} else {
return new StringBuffer(folderPath).append(File.separator).append(
RESOURCE_FOLDER).toString();
}
}
public static String getElementPath(MethodElement e) {
MethodPlugin plugin = UmaUtil.getMethodPlugin(e);
if (plugin == null) {
if (!(e instanceof MethodConfiguration || e instanceof MethodLibrary)) {
// error: plugin element without a valid plugin set. This
// problem needs to be fixed.
// still see it from time to time,
// for example, when lick on a capability pattern in
// COnfiguration Explorer
System.out
.println("error in MethodLibraryPersister.getElementPath(): plugin element without a valid plugin. This problem needs to be fixed."); //$NON-NLS-1$
}
return ""; //$NON-NLS-1$
}
if (plugin.eContainer() == null) {
// error: plugin without library set. This problem needs to be
// fixed.
// still see it from time to time
System.out
.println("error in MethodLibraryPersister.getElementPath(): plugin without library set. This problem needs to be fixed."); //$NON-NLS-1$
return ""; //$NON-NLS-1$
}
String relPluginPath;
if (plugin.eResource() != null) {
Resource libRes = UmaUtil.getMethodLibrary(plugin).eResource();
if (libRes == plugin.eResource()) {
// the plugin is not saved yet
relPluginPath = plugin.getName();
} else {
URI uri = MultiFileSaveUtil.getFinalURI(plugin.eResource());
URI relUri = uri.deresolve(MultiFileSaveUtil
.getFinalURI(libRes));
relPluginPath = relUri.trimSegments(1).toFileString();
}
} else {
// the library is not saved yet
relPluginPath = plugin.getName();
}
String folderPath = staticGetFolderRelativePath(e);
return (folderPath.length() == 0 ? relPluginPath : new StringBuffer(
relPluginPath).append(File.separatorChar).append(folderPath)
.append(File.separatorChar).toString());
}
public static void main(String[] args) {
EClass eCls = UmaPackage.eINSTANCE.getTemplate();
System.out.println(eCls.getName());
}
/**
* Adjusts the location of the given resource and save all the resources
* that have been changed as the result of this adjustment
*
* @param resource
*/
public void adjustLocation(Resource resource) {
Set modifiedResources = new HashSet();
MultiFileSaveUtil.adjustLocation(resource, modifiedResources);
// save the modified resources
MultiFileResourceSetImpl resourceSet = (MultiFileResourceSetImpl) resource
.getResourceSet();
for (Iterator iter = modifiedResources.iterator(); iter.hasNext();) {
try {
resourceSet.save((Resource) iter.next(), null);
} catch (Exception e) {
CommonPlugin.INSTANCE.log(e);
}
}
}
public void save(Resource resource) throws Exception {
MultiFileResourceSetImpl resourceSet = (MultiFileResourceSetImpl) resource
.getResourceSet();
resourceSet.save(resource, null);
}
protected void deleteFiles(MethodElement e, String path,
ResourceSet resourceSet) {
if (new File(path).isDirectory() && !e.eIsProxy()) {
for (Iterator iter = resourceSet.getResources().iterator(); iter
.hasNext();) {
Resource res = (Resource) iter.next();
MethodElement me = PersistenceUtil.getMethodElement(res);
if (me != null && UmaUtil.isContainedBy(me, e)) {
res.unload();
iter.remove();
}
}
}
try {
FileManager.getInstance().deleteResource(path, null);
} catch (CoreException ex) {
CommonPlugin.INSTANCE.log(ex);
throw new WrappedException(ex);
}
}
/**
* Deletes the files associated with the given MethodElement
*
* @param e
*/
protected void delete(MethodElement e, Set modifiedResources) {
if (!UmaUtil.hasDirectResource(e)) {
return;
}
MultiFileXMIResourceImpl resource = (MultiFileXMIResourceImpl) e
.eResource();
MultiFileResourceSetImpl resourceSet = (MultiFileResourceSetImpl) resource
.getResourceSet();
// Don't delete this resource's file if it still contains other
// MethodElement
for (Iterator iter = resource.getContents().iterator(); iter.hasNext();) {
Object element = iter.next();
if (element instanceof MethodElement && element != e) {
resourceSet.removeURIMappings(e, modifiedResources);
resource.getContents().remove(e);
modifiedResources.add(resource);
return;
}
}
String path;
if (MultiFileSaveUtil.hasOwnFolder(e)) {
// path is the directory of the MethodPlugin/ProcessComponent
//
path = new File(resource.getFinalURI().toFileString()).getParent();
// unload/remove all resources under the folder
//
Collection unloadedResources = new ArrayList();
do {
unloadedResources.clear();
// collect all resources whose root element is contained by the
// given element
//
for (Iterator iter = new ArrayList(resourceSet.getResources())
.iterator(); iter.hasNext();) {
Resource res = (Resource) iter.next();
if (res.isLoaded()) {
MethodElement me = PersistenceUtil
.getMethodElement(res);
if (me != null && UmaUtil.isContainedBy(me, e)) {
unloadedResources.add(res);
}
}
}
for (Iterator iter = unloadedResources.iterator(); iter
.hasNext();) {
Resource res = (Resource) iter.next();
res.unload();
}
resourceSet.getResources().removeAll(unloadedResources);
} while (!unloadedResources.isEmpty());
} else {
path = resource.getFinalURI().toFileString();
}
try {
resourceSet.cleanUp(resource, modifiedResources);
} catch (Exception e1) {
CommonPlugin.INSTANCE.log(e1);
if (MultiFileSaveUtil.DEBUG) {
e1.printStackTrace();
}
}
deleteFiles(e, path, resourceSet);
}
/**
* @param e
* @param objectsWithDirectResources
*/
private static void getObjectsWithDirectResources(EObject e,
Collection objectsWithDirectResources) {
if (UmaUtil.hasDirectResource(e)) {
objectsWithDirectResources.add(e);
} else {
for (Iterator iter = e.eContents().iterator(); iter.hasNext();) {
getObjectsWithDirectResources((EObject) iter.next(),
objectsWithDirectResources);
}
}
}
/**
* @see org.eclipse.epf.services.IFileBasedLibraryPersister#delete(org.eclipse.epf.uma.MethodElement)
*/
public void delete(MethodElement e) {
// collect all elements with direct resources that are the given element
// or its offstring
ArrayList elements = new ArrayList();
getObjectsWithDirectResources(e, elements);
if (!elements.isEmpty()) {
Set modifiedResources = new HashSet();
for (Iterator iter = elements.iterator(); iter.hasNext();) {
delete((MethodElement) iter.next(), modifiedResources);
}
// save modified resources
//
for (Iterator iter = modifiedResources.iterator(); iter.hasNext();) {
Resource resource = (Resource) iter.next();
try {
save(resource);
} catch (Exception ex) {
throw new WrappedException(ex);
}
}
}
}
/**
* Gets the relative path of the folder that can store the content of the
* given MethodElement. The path is relative to its plugin folder or library
* folder if the element cannot be stored in a plugin.
*/
private static String staticGetFolderRelativePath(MethodElement e) {
if (e instanceof MethodPlugin) {
return ""; //$NON-NLS-1$
} else if (e instanceof ContentElement) {
return staticGetFolderPath(e.eClass());
} else if (e instanceof MethodConfiguration) {
return MultiFileSaveUtil.METHOD_CONFIGURATION_FOLDER_NAME;
}
MethodUnit unit = UmaUtil.getMethodUnit(e);
if (unit instanceof ProcessComponent) {
Process proc = ((ProcessComponent) unit).getProcess();
if (proc instanceof CapabilityPattern) {
return MultiFileSaveUtil.CAPABILITY_PATTERN_PATH;
} else if (proc instanceof DeliveryProcess) {
return MultiFileSaveUtil.DELIVERY_PROCESS_PATH;
}
} else if (unit instanceof ContentDescription) {
return staticGetFolderRelativePath((MethodElement) unit
.eContainer());
}
return ""; //$NON-NLS-1$
}
public String getFolderRelativePath(MethodElement e) {
return staticGetFolderRelativePath(e);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.epf.uma.util.IFileBasedLibraryPersister#getWarnings()
*/
public List getWarnings() {
if (warnings == null) {
warnings = new ArrayList();
}
return warnings;
}
static class FailSafePersister extends MethodLibraryPersister implements
FailSafeMethodLibraryPersister {
private Map saveOptions;
private TxRecord txRecord = new TxRecord() {
/*
* (non-Javadoc)
*
* @see org.eclipse.epf.persistence.TxRecord#clear()
*/
public void clear() {
if (warnings != null && !warnings.isEmpty()) {
// copy the warning to persister
//
FailSafePersister.this.warnings = Collections
.unmodifiableList(warnings);
}
super.clear();
}
};
private Map elementToInfoMapToDeleteFiles;
public FailSafePersister() {
saveOptions = new HashMap(
MultiFileResourceSetImpl.DEFAULT_SAVE_OPTIONS);
txRecord = new TxRecord();
saveOptions.put(MultiFileXMISaveImpl.TX_RECORD, txRecord);
elementToInfoMapToDeleteFiles = new HashMap();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.epf.persistence.MethodLibraryPersister#getWarnings()
*/
public List getWarnings() {
if (txRecord.getTxID() == null) {
return super.getWarnings();
}
return txRecord.getWarnings();
}
Map getSaveOptions() {
return saveOptions;
}
void checkMove(Resource resource) {
// disallow new operation on resource which has started operation
// that is not committed
MultiFileXMIResourceImpl mfResource = (MultiFileXMIResourceImpl) resource;
if (mfResource.txStarted()) {
throw new MultiFileIOException(NLS.bind(
PersistenceResources.moveResourceError_msg, resource));
}
}
/**
* @see org.eclipse.epf.uma.persistence.MethodLibraryPersister#save(org.eclipse.emf.ecore.resource.Resource)
*/
public void save(Resource resource) throws Exception {
if(resource.getResourceSet() instanceof MultiFileResourceSetImpl &&
resource instanceof MultiFileXMIResourceImpl) {
MultiFileResourceSetImpl resourceSet = (MultiFileResourceSetImpl) resource
.getResourceSet();
if (resourceSet == null) {
return;
}
// update version info in library resource if needed
//
Resource libResourceToSave = null;
MethodElement me = PersistenceUtil.getMethodElement(resource);
if(me != null) {
MethodLibrary lib = UmaUtil.getMethodLibrary(me);
if(lib != null) {
Resource libResource = lib.eResource();
if(libResource != null
&& libResource != resource
&& PersistenceUtil.checkToolVersion(libResource) != 0) {
libResourceToSave = libResource;
}
}
}
if (MultiFileXMISaveImpl.checkModifyRequired(saveOptions)) {
Collection<Resource> resources;
if(libResourceToSave != null) {
resources = new ArrayList<Resource>();
resources.add(resource);
resources.add(libResourceToSave);
}
else {
resources = Collections.singletonList(resource);
}
Resource[] resourceArray = new Resource[resources.size()];
resources.toArray(resourceArray);
resourceSet.checkModify(resourceArray, MsgBox.getDefaultShell());
MultiFileSaveUtil.checkOutOfSynch(resources);
MultiFileSaveUtil.checkFilePathLength(resources);
}
resourceSet.save(resource, saveOptions);
if(libResourceToSave != null) {
resourceSet.save(libResourceToSave, saveOptions);
}
}
else if(resource instanceof IFailSafeSavable) {
IFailSafeSavable failSafeSavable = (IFailSafeSavable) resource;
failSafeSavable.setTxID(txRecord.getTxID());
resource.save(saveOptions);
txRecord.getResourcesToCommit().add(resource);
}
else {
throw new IllegalAccessException("Resource must implement org.eclipse.epf.library.persistence.internal.IFailSafeSavable"); //$NON-NLS-1$
}
}
/**
* @see org.eclipse.epf.uma.persistence.MethodLibraryPersister#adjustLocation(org.eclipse.emf.ecore.resource.Resource)
*/
public void adjustLocation(Resource resource) {
checkMove(resource);
Set modifiedResources = new HashSet();
if (MultiFileSaveUtil.prepareAdjustLocation(
(MultiFileXMIResourceImpl) resource, modifiedResources)) {
txRecord.getResourcesToCommit().add(resource);
HashSet resourcesToCheck = new HashSet(modifiedResources);
resourcesToCheck.addAll(resourcesToCheck);
MultiFileSaveUtil.checkModify(resourcesToCheck);
if (!modifiedResources.isEmpty()) {
MultiFileSaveUtil.checkOutOfSynch(modifiedResources);
// save the modified resources
for (Iterator iter = modifiedResources.iterator(); iter
.hasNext();) {
try {
save((Resource) iter.next());
} catch (Exception e) {
CommonPlugin.INSTANCE.log(e);
throw new MultiFileIOException(e.toString());
}
}
}
}
commit();
}
public void adjustLocation(Collection resources) {
if (resources == null || resources.isEmpty()) {
return;
}
for (Iterator iter = resources.iterator(); iter.hasNext();) {
checkMove((Resource) iter.next());
}
Set modifiedResources = new HashSet();
HashSet resourcesToCheck = new HashSet();
for (Iterator iter = resources.iterator(); iter.hasNext();) {
MultiFileXMIResourceImpl resource = (MultiFileXMIResourceImpl) iter
.next();
if (MultiFileSaveUtil.prepareAdjustLocation(
(MultiFileXMIResourceImpl) resource, modifiedResources)) {
txRecord.getResourcesToCommit().add(resource);
resourcesToCheck.add(resource);
}
}
resourcesToCheck.addAll(modifiedResources);
if(!resourcesToCheck.isEmpty()) {
MultiFileSaveUtil.checkModify(resourcesToCheck);
}
if (!modifiedResources.isEmpty()) {
MultiFileSaveUtil.checkOutOfSynch(modifiedResources);
// save the modified resources
for (Iterator iter = modifiedResources.iterator(); iter
.hasNext();) {
try {
save((Resource) iter.next());
} catch (Exception e) {
CommonPlugin.INSTANCE.log(e);
throw new MultiFileIOException(e.toString());
}
}
}
commit();
}
/**
* @see org.eclipse.epf.uma.persistence.MethodLibraryPersister#deleteFiles(org.eclipse.epf.uma.MethodElement,
* java.lang.String, org.eclipse.emf.ecore.resource.ResourceSet)
*/
protected void deleteFiles(MethodElement e, String path,
ResourceSet resourceSet) {
// keep the info to really delete the files in commit()
elementToInfoMapToDeleteFiles.put(e, new Object[] { path,
resourceSet });
}
private void superDeleteFiles(MethodElement e, String path,
ResourceSet resourceSet) {
super.deleteFiles(e, path, resourceSet);
}
/**
* @see org.eclipse.epf.uma.util.IFileBasedLibraryPersister.FailSafeMethodLibraryPersister#commit()
*/
public void commit() {
// save is done
// call saveIsDone() on every saved file to rename it to the correct
// name
int size = txRecord.getResourcesToCommit().size();
for (int i = 0; i < size; i++) {
((IFailSafeSavable) txRecord.getResourcesToCommit()
.get(i)).commit();
}
// notify all commited resources that the transaction is done
for (int i = 0; i < size; i++) {
((IFailSafeSavable) txRecord.getResourcesToCommit()
.get(i)).txFinished(true);
}
// delete backup
for (int i = 0; i < size; i++) {
((IFailSafeSavable) txRecord.getResourcesToCommit()
.get(i)).deleteBackup();
}
txRecord.clear();
// delete files of deleted elements
//
for (Iterator iter = elementToInfoMapToDeleteFiles.entrySet()
.iterator(); iter.hasNext();) {
Map.Entry entry = (Map.Entry) iter.next();
Object[] info = (Object[]) entry.getValue();
String path = (String) info[0];
try {
superDeleteFiles((MethodElement) entry.getKey(), path,
(ResourceSet) info[1]);
} catch (Exception e) {
if (e instanceof WrappedException) {
e = ((WrappedException) e).exception();
}
String msg = PersistenceResources.ErrMsg_CouldNotDelete;
String otherMsg = null;
if (e instanceof CoreException) {
IStatus status = ((CoreException) e).getStatus();
if (status != null) {
otherMsg = UmaUtil.getMessage(status);
}
}
if (otherMsg == null) {
otherMsg = ""; //$NON-NLS-1$
}
msg = MessageFormat.format(msg, new Object[] { path,
otherMsg });
e = new Exception(msg, e);
getWarnings().add(e);
CommonPlugin.INSTANCE.log(e);
if (MultiFileSaveUtil.DEBUG) {
e.printStackTrace();
}
}
}
elementToInfoMapToDeleteFiles.clear();
}
/**
* @see org.eclipse.epf.uma.util.IFileBasedLibraryPersister.FailSafeMethodLibraryPersister#rollback()
*/
public void rollback() {
if (!txRecord.getResourcesToCommit().isEmpty()) {
try {
int max = txRecord.getResourcesToCommit().size() - 1;
ArrayList restoredResources = new ArrayList();
// Something went wrong, restore from backup
for (int i = max; i > -1; i--) {
IFailSafeSavable resource = (IFailSafeSavable) txRecord
.getResourcesToCommit().get(i);
if (resource.restore()) {
restoredResources.add(resource);
}
}
for (Iterator iter = restoredResources.iterator(); iter
.hasNext();) {
Resource resource = (Resource) iter
.next();
resource.setModified(true);
}
// delete temp files
for (int i = max; i > -1; i--) {
Resource resource = (Resource) txRecord
.getResourcesToCommit().get(i);
if (((IFailSafeSavable)resource).hasTempURI()) {
// uri keeps the path to temp file
try {
new File(resource.getURI().toFileString())
.delete();
} catch (Exception e) {
CommonPlugin.INSTANCE.log(e);
if (MultiFileSaveUtil.DEBUG) {
e.printStackTrace();
}
}
}
}
// notify all commited resources that the transaction is
// done
for (int i = max; i > -1; i--) {
((IFailSafeSavable) txRecord
.getResourcesToCommit().get(i))
.txFinished(false);
}
} catch (RuntimeException e) {
CommonPlugin.INSTANCE.log(e);
if (MultiFileSaveUtil.DEBUG) {
e.printStackTrace();
}
throw e;
}
}
txRecord.clear();
}
/**
* @see org.eclipse.epf.services.IFileBasedLibraryPersister#getFailSafePersister()
*/
public FailSafeMethodLibraryPersister getFailSafePersister() {
return this;
}
/**
* @see org.eclipse.epf.uma.util.IFileBasedLibraryPersister.FailSafeMethodLibraryPersister#getCurrentTxID()
*/
public String getCurrentTxID() {
return txRecord.getTxID();
}
}
FailSafePersister getFailSafePersister(Map options) {
FailSafePersister persister = new FailSafePersister();
persister.saveOptions.putAll(options);
// make sure that TX_RECORD still keeps the correct value
persister.saveOptions.put(MultiFileXMISaveImpl.TX_RECORD,
persister.txRecord);
return persister;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.epf.uma.util.IFileBasedLibraryPersister#hasOwnFolder(java.lang.Object)
*/
public boolean hasOwnFolder(Object e) {
return MultiFileSaveUtil.hasOwnFolder(e);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.epf.uma.util.IFileBasedLibraryPersister#hasOwnResource(java.lang.Object)
*/
public boolean hasOwnResource(Object e) {
return MultiFileSaveUtil.hasOwnResource(e,
MultiFileResourceSetImpl.DEFAULT_SAVE_SEPARATELY_CLASS_SET);
}
/**
* @see org.eclipse.epf.services.IFileBasedLibraryPersister#getFailSafePersister()
*/
public FailSafeMethodLibraryPersister getFailSafePersister() {
return new FailSafePersister();
}
public static class NonFailSafePersister extends MethodLibraryPersister
implements FailSafeMethodLibraryPersister {
/**
* @see org.eclipse.epf.uma.util.IFileBasedLibraryPersister.FailSafeMethodLibraryPersister#commit()
*/
public void commit() {
// do nothing
}
/**
* @see org.eclipse.epf.uma.util.IFileBasedLibraryPersister.FailSafeMethodLibraryPersister#rollback()
*/
public void rollback() {
// do nothing
}
/**
* @see org.eclipse.epf.uma.util.IFileBasedLibraryPersister.FailSafeMethodLibraryPersister#getCurrentTxID()
*/
public String getCurrentTxID() {
return null;
}
/**
* @see org.eclipse.epf.uma.util.IFileBasedLibraryPersister.FailSafeMethodLibraryPersister#adjustLocation(java.util.Collection)
*/
public void adjustLocation(Collection resources) {
for (Iterator iter = resources.iterator(); iter.hasNext();) {
adjustLocation((Resource) iter.next());
}
}
}
private static final FailSafeMethodLibraryPersister nonFailSafePersister = new NonFailSafePersister();
/*
* (non-Javadoc)
*
* @see org.eclipse.epf.uma.util.IFileBasedLibraryPersister#getFileExtension(java.lang.Object)
*/
public String getFileExtension(Object e) {
return MultiFileSaveUtil.DEFAULT_FILE_EXTENSION;
}
/* (non-Javadoc)
* @see org.eclipse.epf.uma.util.IFileBasedLibraryPersister#save(org.eclipse.epf.uma.MethodElement)
*/
public void save(MethodElement element) throws Exception {
if(!hasOwnResourceWithoutReferrer(element)) {
return;
}
MultiFileResourceSetImpl resourceSet = (MultiFileResourceSetImpl) UmaUtil.getMethodLibrary(element).eResource().getResourceSet();
Map options = resourceSet.getDefaultSaveOptions();
Resource res = ((InternalEObject)element).eDirectResource();
MultiFileXMIResourceImpl resource;
if(res instanceof MultiFileXMIResourceImpl) {
resource = (MultiFileXMIResourceImpl) res;
resourceSet.save(resource, options);
}
else {
URI uri = MultiFileSaveUtil.createFileURI(element);
resource = MultiFileSaveUtil.save(resourceSet, element, uri, options, false);
}
resource.updateTimeStamps();
String str = (String) options.get(MultiFileXMISaveImpl.REFRESH_NEW_RESOURCE);
if (str != null && Boolean.valueOf(str).booleanValue()) {
// notify RefreshJob the this resource is saved so it will not be
// reloaded after refreshing it
//
RefreshJob.getInstance().resourceSaved(resource);
// refresh the newly created resource so it is in synch with the
// workspace
//
FileManager.getInstance().refresh(resource);
}
}
/* (non-Javadoc)
* @see org.eclipse.epf.uma.util.IFileBasedLibraryPersister#hasOwnResourceWithoutReferrer(java.lang.Object)
*/
public boolean hasOwnResourceWithoutReferrer(Object e) {
return e instanceof MethodConfiguration;
}
public File createMethodPluginFolder(String pluginName, MethodLibrary library) {
File libDir = new File(library.eResource().getURI().toFileString()).getParentFile();
File pluginDir = new File(libDir, pluginName);
if(!pluginDir.exists()) {
if(!pluginDir.mkdirs()) {
throw new MultiFileIOException(NLS.bind("Cannot create directory ''{0}''.", pluginDir));
}
}
return pluginDir;
}
public File getDefaultMethodConfigurationFolder(MethodLibrary library) {
File libDir = new File(library.eResource().getURI().toFileString()).getParentFile();
File configDir = new File(libDir, MultiFileSaveUtil.METHOD_CONFIGURATION_FOLDER_NAME);
if(!configDir.exists()) {
if(!configDir.mkdirs()) {
throw new MultiFileIOException(NLS.bind("Cannot create directory ''{0}''.", configDir));
}
}
return configDir;
}
}