//------------------------------------------------------------------------------ // Copyright (c) 2005, 2007 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 org.eclipse.emf.common.CommonPlugin; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.resource.URIConverter; import org.eclipse.epf.common.utils.FileUtil; import org.eclipse.epf.persistence.util.PersistenceResources; import org.eclipse.osgi.util.NLS; /** * @author Phong Nguyen Le * * @since 1.2 */ public class FailSafePersistenceHelper { private URI finalURI; private URI oldURI; private String currentTxID; private Resource resource; private URI tempURI; private String id; private String backupFile; private URIConverter converter; private boolean commitEmptyResource; public FailSafePersistenceHelper(Resource resource, String id) { this.resource = resource; this.id = id; this.converter = resource.getResourceSet() != null ? resource.getResourceSet().getURIConverter() : null; } public void setCommitEmptyResource(boolean commitEmptyResource) { this.commitEmptyResource = commitEmptyResource; } /** * Sets the temporary URI to save this resource to and it will be renamed to * the original URI when saving is done */ public URI setTempURI(String txID) { if (finalURI == null) { finalURI = oldURI = resource.getURI(); currentTxID = txID; tempURI = createTempURI(); resource.setURI(tempURI); } return tempURI; } private URI createTempURI() { return URI.createFileURI(new StringBuffer(MultiFileXMIResourceImpl.getTempDir()).append( File.separator).append(currentTxID) .append("new").append(id).toString()); //$NON-NLS-1$ } public String getBackupFilePath() { String backupFile = new StringBuffer(MultiFileXMIResourceImpl.getTempDir()) .append(File.separator) .append(currentTxID) .append("old").append(id).toString(); //$NON-NLS-1$ return backupFile; } private String toFileString(URI uri) { return FileManager.toFileString(uri, converter); } public void commit() { if (finalURI != null && (commitEmptyResource || !resource.getContents().isEmpty())) { File finalFile = new File(toFileString(finalURI)); boolean wasMove = !oldURI.equals(finalURI); if (wasMove) { } else { // back up the file // String backup = getBackupFilePath(); File bakFile = new File(backup); // trying to delete the old backup file if it exists // if (bakFile.exists()) { bakFile.delete(); } if (finalFile.exists()) { // some CM provider like ClearCase renamed the versioned // file it its repository as soon as user renamed the file // in the workspace. To avoid this, use only regular rename // routine of java.io.File instead of IResource routine // if (FileUtil.moveFile(finalFile, bakFile)) { backupFile = backup; } else { String msg = NLS.bind( PersistenceResources.renameError_msg, finalFile, backup); throw new MultiFileIOException(msg); } } } // rename the resource file to the original name // File currentFile = new File(wasMove ? toFileString(oldURI) : toFileString(resource.getURI())); boolean success = false; if (wasMove) { success = MultiFileSaveUtil.move(resource, currentFile, finalFile); } else { // some CM provider like ClearCase renamed the versioned file it // its repository as soon as user renamed the file // in the workspace. To avoid this, use only regular rename // routine of java.io.File instead of IResource routine // success = FileUtil.moveFile(currentFile, finalFile); } if (!success) { String msg = NLS.bind(PersistenceResources.renameError_msg, currentFile, finalFile); throw new MultiFileIOException(msg); } else { if (wasMove) { didMove(); } } } } /** * Subclass to override to handle post move */ protected void didMove() { } public void deleteBackup() { if (backupFile != null) { try { // FileManager.getInstance().delete(backupFile); new File(backupFile).delete(); backupFile = null; } catch (Throwable e) { CommonPlugin.INSTANCE.log(e); if (MultiFileSaveUtil.DEBUG) { e.printStackTrace(); } } } } public boolean hasTempURI() { if (currentTxID != null) { return createTempURI().equals(resource.getURI()); } return false; } public URI getFinalURI() { if (finalURI != null) { return finalURI; } return resource.getURI(); } public boolean restore() { File src = null, dest = null; boolean moved = false; if (backupFile != null) { src = new File(backupFile); dest = new File(toFileString(getFinalURI())); } else { moved = oldURI != null && !oldURI.equals(finalURI); if (moved) { File file = new File(toFileString(getFinalURI())); dest = new File(toFileString(oldURI)); moved = file.exists() && !dest.exists(); if (moved) { src = file; } } } if (src != null) { if (dest.exists()) { FileUtil.moveFile(dest,new File(toFileString(resource.getURI()))); } boolean success; if (moved) { success = MultiFileSaveUtil.move(resource, src, dest); // if(success) { // MultiFileSaveUtil.updateURIMappings(this, null); // } } else { success = FileUtil.moveFile(src,dest); } if (!success) { throw new MultiFileIOException(NLS.bind( PersistenceResources.restoreResourceError_msg, this)); } return true; } return false; } public void txFinished(boolean successful) { if (successful) { resource.setURI(finalURI); resource.setModified(false); FileManager.getInstance().refresh(resource); } else { restoreURI(); } currentTxID = null; finalURI = null; } /** * Restores the resource URI to the original one. This method must be call * after saving regarless of its success. * */ private void restoreURI() { if (oldURI != null) { resource.setURI(oldURI); } } }