/******************************************************************************* | |
* Copyright (c) 2012-2013 EclipseSource Muenchen GmbH 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: | |
* Edgar Mueller | |
******************************************************************************/ | |
package org.eclipse.emf.emfstore.internal.client.model.util; | |
import java.io.File; | |
import java.io.FileWriter; | |
import java.io.IOException; | |
import java.util.LinkedHashMap; | |
import java.util.Map; | |
import org.eclipse.core.runtime.IProgressMonitor; | |
import org.eclipse.core.runtime.NullProgressMonitor; | |
import org.eclipse.emf.ecore.resource.Resource; | |
import org.eclipse.emf.ecore.xmi.XMLResource; | |
import org.eclipse.emf.emfstore.client.ESLocalProject; | |
import org.eclipse.emf.emfstore.client.handler.ESChecksumErrorHandler; | |
import org.eclipse.emf.emfstore.internal.client.common.UnknownEMFStoreWorkloadCommand; | |
import org.eclipse.emf.emfstore.internal.client.model.Activator; | |
import org.eclipse.emf.emfstore.internal.client.model.ESWorkspaceProviderImpl; | |
import org.eclipse.emf.emfstore.internal.client.model.ProjectSpace; | |
import org.eclipse.emf.emfstore.internal.client.model.impl.api.ESLocalProjectImpl; | |
import org.eclipse.emf.emfstore.internal.common.model.Project; | |
import org.eclipse.emf.emfstore.internal.common.model.util.ModelUtil; | |
import org.eclipse.emf.emfstore.internal.common.model.util.SerializationException; | |
import org.eclipse.emf.emfstore.internal.server.model.impl.api.ESGlobalProjectIdImpl; | |
import org.eclipse.emf.emfstore.internal.server.model.impl.api.ESSessionIdImpl; | |
import org.eclipse.emf.emfstore.internal.server.model.impl.api.versionspec.ESVersionSpecImpl; | |
import org.eclipse.emf.emfstore.internal.server.model.versioning.VersionSpec; | |
import org.eclipse.emf.emfstore.server.exceptions.ESException; | |
import org.eclipse.emf.emfstore.server.model.versionspec.ESPrimaryVersionSpec; | |
/** | |
* Pre-defined error handlers. | |
* | |
* @author emueller | |
* @author Lucas Koehler | |
* | |
*/ | |
public enum ChecksumErrorHandler implements ESChecksumErrorHandler { | |
/** | |
* Logs the checksum comparison failure and continues execution of the caller. | |
*/ | |
LOG { | |
/** | |
* {@inheritDoc} | |
*/ | |
public boolean execute(ESLocalProject project, ESPrimaryVersionSpec versionSpec, IProgressMonitor monitor) | |
throws ESException { | |
WorkspaceUtil.logWarning(Messages.ChecksumErrorHandler_ChecksumComparisionFailed, null); | |
return true; | |
} | |
}, | |
/** | |
* Logs the checksum comparison failure detailed: the serialization of both project spaces is written in seperate | |
* files. The execution of the caller will then be continued. | |
*/ | |
LOG_DETAILED { | |
/** | |
* {@inheritDoc} | |
*/ | |
public boolean execute(ESLocalProject localProject, ESPrimaryVersionSpec versionSpec, IProgressMonitor monitor) | |
throws ESException { | |
WorkspaceUtil.logWarning("Checksum comparison failed.", null); //$NON-NLS-1$ | |
final Project project = ESLocalProjectImpl.class.cast(localProject).toInternalAPI().getProject(); | |
final ESLocalProject serverESProject = localProject | |
.getRemoteProject() | |
.checkout( | |
"log_error_checksum_debug_checkout", localProject.getUsersession(), versionSpec, new NullProgressMonitor()); //$NON-NLS-1$ | |
final Project serverProject = ESLocalProjectImpl.class.cast(serverESProject).toInternalAPI() | |
.getProject(); | |
try { | |
final Map<Object, Object> formatOptions = new LinkedHashMap<Object, Object>(); | |
formatOptions.put(XMLResource.OPTION_DECLARE_XML, Boolean.TRUE); | |
formatOptions.put(XMLResource.OPTION_FORMATTED, Boolean.TRUE); | |
final String localSerialization = ModelUtil | |
.eObjectToString(project, ModelUtil.getResourceSaveOptions()); | |
final String serverSerialization = ModelUtil.eObjectToString(serverProject, | |
ModelUtil.getResourceSaveOptions()); | |
serverESProject.delete(new NullProgressMonitor()); | |
final File localFile = Activator.getDefault().getBundle().getDataFile("localProjectSerialization.txt"); //$NON-NLS-1$ | |
final File serverFile = Activator.getDefault().getBundle() | |
.getDataFile("serverProjectSerialization.txt"); //$NON-NLS-1$ | |
final FileWriter fileWriterLocal = new FileWriter(localFile); | |
fileWriterLocal.write(localSerialization); | |
fileWriterLocal.close(); | |
final FileWriter fileWriterServer = new FileWriter(serverFile); | |
fileWriterServer.write(serverSerialization); | |
fileWriterServer.close(); | |
} catch (final SerializationException ex) { | |
WorkspaceUtil.logException("Couldn't log the serializations.", ex); //$NON-NLS-1$ | |
} catch (final IOException ex) { | |
WorkspaceUtil.logException("Couldn't save the serializations.", ex); //$NON-NLS-1$ | |
} | |
return true; | |
} | |
}, | |
/** | |
* Aborts execution of the caller. | |
*/ | |
CANCEL { | |
/** | |
* {@inheritDoc} | |
*/ | |
public boolean execute(ESLocalProject project, ESPrimaryVersionSpec versionSpec, IProgressMonitor monitor) | |
throws ESException { | |
return false; | |
} | |
}, | |
/** | |
* Fixes the checksum comparison failure by deleting the {@link ProjectSpace} that got | |
* in an inconsistent state and checking it out again.<br> | |
* <b>Note</b>: all references to the project space that will be deleted should to be taken care of. | |
*/ | |
AUTOCORRECT { | |
/** | |
* {@inheritDoc} | |
*/ | |
public boolean execute(final ESLocalProject project, final ESPrimaryVersionSpec versionSpec, | |
IProgressMonitor monitor) throws ESException { | |
final ESLocalProjectImpl localProjectImpl = (ESLocalProjectImpl) project; | |
final ProjectSpace projectSpace = localProjectImpl.toInternalAPI(); | |
final Resource projectResource = localProjectImpl.toInternalAPI().getProject().eResource(); | |
final Project fetchedProject = new UnknownEMFStoreWorkloadCommand<Project>(monitor) { | |
@Override | |
public Project run(IProgressMonitor monitor) throws ESException { | |
final ESSessionIdImpl sessionIdImpl = (ESSessionIdImpl) project.getUsersession().getSessionId(); | |
final ESGlobalProjectIdImpl globalProjectIdImpl = (ESGlobalProjectIdImpl) project | |
.getRemoteProject() | |
.getGlobalProjectId(); | |
final ESVersionSpecImpl<?, ? extends VersionSpec> versionSpecImpl = (ESVersionSpecImpl<?, ?>) versionSpec; | |
return ESWorkspaceProviderImpl | |
.getInstance() | |
.getConnectionManager() | |
.getProject( | |
sessionIdImpl.toInternalAPI(), | |
globalProjectIdImpl.toInternalAPI(), | |
ModelUtil.clone(versionSpecImpl.toInternalAPI())); | |
} | |
}.execute(); | |
if (fetchedProject == null) { | |
throw new ESException(Messages.ChecksumErrorHandler_ServerReturnedNullProject); | |
} | |
projectResource.getContents().clear(); | |
projectResource.getContents().add(fetchedProject); | |
try { | |
projectResource.save(ModelUtil.getResourceSaveOptions()); | |
} catch (final IOException ex) { | |
throw new ESException(Messages.ChecksumErrorHandler_SaveFailedWhileAutocorrect); | |
} | |
projectSpace.setProject(fetchedProject); | |
projectSpace.init(); | |
return true; | |
} | |
} | |
} |