blob: 34e74d22d09a70d14131bd90946d4d4913a2b948 [file] [log] [blame]
/*******************************************************************************
* 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:
* Otto von Wesendonk, Edgar Mueller - initial API and implementation
******************************************************************************/
package org.eclipse.emf.emfstore.internal.client.model.impl.api;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.Callable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.impl.ResourceImpl;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.xmi.XMIResource;
import org.eclipse.emf.emfstore.client.ESRemoteProject;
import org.eclipse.emf.emfstore.client.ESUsersession;
import org.eclipse.emf.emfstore.client.observer.ESCheckoutObserver;
import org.eclipse.emf.emfstore.client.util.RunESCommand;
import org.eclipse.emf.emfstore.internal.client.common.UnknownEMFStoreWorkloadCommand;
import org.eclipse.emf.emfstore.internal.client.model.ESWorkspaceProviderImpl;
import org.eclipse.emf.emfstore.internal.client.model.ModelFactory;
import org.eclipse.emf.emfstore.internal.client.model.ProjectSpace;
import org.eclipse.emf.emfstore.internal.client.model.ServerInfo;
import org.eclipse.emf.emfstore.internal.client.model.Usersession;
import org.eclipse.emf.emfstore.internal.client.model.connectionmanager.ConnectionManager;
import org.eclipse.emf.emfstore.internal.client.model.connectionmanager.ServerCall;
import org.eclipse.emf.emfstore.internal.common.APIUtil;
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.server.model.ProjectId;
import org.eclipse.emf.emfstore.internal.server.model.ProjectInfo;
import org.eclipse.emf.emfstore.internal.server.model.accesscontrol.ACOrgUnit;
import org.eclipse.emf.emfstore.internal.server.model.accesscontrol.ACUser;
import org.eclipse.emf.emfstore.internal.server.model.accesscontrol.roles.Role;
import org.eclipse.emf.emfstore.internal.server.model.accesscontrol.roles.ServerAdmin;
import org.eclipse.emf.emfstore.internal.server.model.impl.api.query.ESHistoryQueryImpl;
import org.eclipse.emf.emfstore.internal.server.model.impl.api.versionspec.ESPrimaryVersionSpecImpl;
import org.eclipse.emf.emfstore.internal.server.model.impl.api.versionspec.ESTagVersionSpecImpl;
import org.eclipse.emf.emfstore.internal.server.model.impl.api.versionspec.ESVersionSpecImpl;
import org.eclipse.emf.emfstore.internal.server.model.versioning.BranchInfo;
import org.eclipse.emf.emfstore.internal.server.model.versioning.HistoryInfo;
import org.eclipse.emf.emfstore.internal.server.model.versioning.PrimaryVersionSpec;
import org.eclipse.emf.emfstore.internal.server.model.versioning.VersionSpec;
import org.eclipse.emf.emfstore.internal.server.model.versioning.Versions;
import org.eclipse.emf.emfstore.server.exceptions.ESException;
import org.eclipse.emf.emfstore.server.model.ESBranchInfo;
import org.eclipse.emf.emfstore.server.model.ESGlobalProjectId;
import org.eclipse.emf.emfstore.server.model.ESHistoryInfo;
import org.eclipse.emf.emfstore.server.model.query.ESHistoryQuery;
import org.eclipse.emf.emfstore.server.model.versionspec.ESPrimaryVersionSpec;
import org.eclipse.emf.emfstore.server.model.versionspec.ESTagVersionSpec;
import org.eclipse.emf.emfstore.server.model.versionspec.ESVersionSpec;
/**
* Represents a remote project that is located on a remote server.
*
* @author wesendon
* @author emueller
*/
public class ESRemoteProjectImpl implements ESRemoteProject {
/**
* The current connection manager used to connect to the server(s).
*/
private final ProjectInfo projectInfo;
private final ServerInfo server;
/**
* Constructor.
*
* @param serverInfo
* the server the remote project is located on
* @param projectInfo
* information about which project to access
*/
public ESRemoteProjectImpl(ServerInfo serverInfo, ProjectInfo projectInfo) {
server = serverInfo;
this.projectInfo = projectInfo;
}
/**
*
* {@inheritDoc}
*
* @see org.eclipse.emf.emfstore.client.ESProject#getGlobalProjectId()
*/
public ESGlobalProjectId getGlobalProjectId() {
return RunESCommand.runWithResult(new Callable<ESGlobalProjectId>() {
public ESGlobalProjectId call() throws Exception {
return getProjectInfo().getProjectId().toAPI();
}
});
}
/**
*
* {@inheritDoc}
*
* @see org.eclipse.emf.emfstore.client.ESProject#getProjectName()
*/
public String getProjectName() {
return RunESCommand.runWithResult(new Callable<String>() {
public String call() throws Exception {
return getProjectInfo().getName();
}
});
}
/**
*
* {@inheritDoc}
*
* @see org.eclipse.emf.emfstore.client.ESProject#getBranches(org.eclipse.core.runtime.IProgressMonitor)
*/
public List<ESBranchInfo> getBranches(IProgressMonitor monitor) throws ESException {
return new UnknownEMFStoreWorkloadCommand<List<ESBranchInfo>>(monitor) {
@Override
public List<ESBranchInfo> run(IProgressMonitor monitor) throws ESException {
return APIUtil.mapToAPI(ESBranchInfo.class, new ServerCall<List<BranchInfo>>(getServerInfo()) {
@Override
protected List<BranchInfo> run() throws ESException {
final ConnectionManager connectionManager = ESWorkspaceProviderImpl.getInstance()
.getConnectionManager();
return connectionManager.getBranches(
getSessionId(),
projectInfo.getProjectId());
}
}.execute());
}
}.execute();
}
/**
*
* {@inheritDoc}
*
* @see org.eclipse.emf.emfstore.client.ESRemoteProject#getBranches(org.eclipse.emf.emfstore.client.ESUsersession,
* org.eclipse.core.runtime.IProgressMonitor)
*/
public List<ESBranchInfo> getBranches(ESUsersession usersession, IProgressMonitor monitor) throws ESException {
return APIUtil.mapToAPI(ESBranchInfo.class, new ServerCall<List<BranchInfo>>(getServerInfo()) {
@Override
protected List<BranchInfo> run() throws ESException {
return getConnectionManager().getBranches(
getSessionId(),
projectInfo.getProjectId());
}
}.execute());
}
/**
*
* {@inheritDoc}
*
* @see org.eclipse.emf.emfstore.client.ESProject#resolveVersionSpec(org.eclipse.emf.emfstore.server.model.versionspec.ESVersionSpec,
* org.eclipse.core.runtime.IProgressMonitor)
*/
public ESPrimaryVersionSpec resolveVersionSpec(final ESVersionSpec versionSpec, IProgressMonitor monitor)
throws ESException {
final ESVersionSpecImpl<?, ? extends VersionSpec> versionSpecImpl = (ESVersionSpecImpl<?, ?>) versionSpec;
final PrimaryVersionSpec primaryVersionSpec = new ServerCall<PrimaryVersionSpec>(getServerInfo(), monitor) {
@Override
protected PrimaryVersionSpec run() throws ESException {
return getConnectionManager().resolveVersionSpec(getSessionId(),
projectInfo.getProjectId(),
versionSpecImpl.toInternalAPI());
}
}.execute();
return primaryVersionSpec.toAPI();
}
/**
*
* {@inheritDoc}
*
* @see org.eclipse.emf.emfstore.client.ESRemoteProject#resolveVersionSpec(org.eclipse.emf.emfstore.client.ESUsersession,
* org.eclipse.emf.emfstore.server.model.versionspec.ESVersionSpec, org.eclipse.core.runtime.IProgressMonitor)
*/
public ESPrimaryVersionSpec resolveVersionSpec(ESUsersession session, final ESVersionSpec versionSpec,
IProgressMonitor monitor) throws ESException {
final Usersession usersession = ((ESUsersessionImpl) session).toInternalAPI();
final ESVersionSpecImpl<?, ? extends VersionSpec> versionSpecImpl = (ESVersionSpecImpl<?, ?>) versionSpec;
final PrimaryVersionSpec primaryVersionSpec = new ServerCall<PrimaryVersionSpec>(usersession) {
@Override
protected PrimaryVersionSpec run() throws ESException {
return getConnectionManager().resolveVersionSpec(getSessionId(),
projectInfo.getProjectId(),
versionSpecImpl.toInternalAPI());
}
}.execute();
return primaryVersionSpec.toAPI();
}
/**
*
* {@inheritDoc}
*
* @see org.eclipse.emf.emfstore.client.ESProject#getHistoryInfos(org.eclipse.emf.emfstore.server.model.query.ESHistoryQuery,
* org.eclipse.core.runtime.IProgressMonitor)
*/
public List<ESHistoryInfo> getHistoryInfos(final ESHistoryQuery<? extends ESHistoryQuery<?>> query,
IProgressMonitor monitor)
throws ESException {
@SuppressWarnings("unchecked")
final ESHistoryQueryImpl<ESHistoryQuery<? extends ESHistoryQuery<?>>, ?> queryImpl = (ESHistoryQueryImpl<ESHistoryQuery<? extends ESHistoryQuery<?>>, ?>) query;
return APIUtil.mapToAPI(ESHistoryInfo.class, new ServerCall<List<HistoryInfo>>(getServerInfo(), monitor) {
@Override
protected List<HistoryInfo> run() throws ESException {
return getConnectionManager().getHistoryInfo(
getSessionId(),
projectInfo.getProjectId(),
queryImpl.toInternalAPI());
}
}.execute());
}
/**
*
* {@inheritDoc}
*
* @see org.eclipse.emf.emfstore.client.ESRemoteProject#getHistoryInfos(org.eclipse.emf.emfstore.client.ESUsersession,
* org.eclipse.emf.emfstore.server.model.query.ESHistoryQuery, org.eclipse.core.runtime.IProgressMonitor)
*/
public List<ESHistoryInfo> getHistoryInfos(final ESUsersession session,
final ESHistoryQuery<? extends ESHistoryQuery<?>> query,
final IProgressMonitor monitor) throws ESException {
return RunESCommand.WithException.runWithResult(ESException.class, new Callable<List<ESHistoryInfo>>() {
public List<ESHistoryInfo> call() throws Exception {
final Usersession usersession = ((ESUsersessionImpl) session).toInternalAPI();
final ESHistoryQueryImpl<?, ?> queryImpl = (ESHistoryQueryImpl<?, ?>) query;
final List<HistoryInfo> historyInfos = new ServerCall<List<HistoryInfo>>(usersession,
monitor) {
@Override
protected List<HistoryInfo> run() throws ESException {
return getConnectionManager().getHistoryInfo(
getUsersession().getSessionId(),
getProjectInfo().getProjectId(),
queryImpl.toInternalAPI());
}
}.execute();
return APIUtil.mapToAPI(ESHistoryInfo.class, historyInfos);
}
});
}
/**
*
* {@inheritDoc}
*
* @see org.eclipse.emf.emfstore.client.ESProject#addTag(org.eclipse.emf.emfstore.server.model.versionspec.ESPrimaryVersionSpec,
* org.eclipse.emf.emfstore.server.model.versionspec.ESTagVersionSpec,
* org.eclipse.core.runtime.IProgressMonitor)
*/
public void addTag(final ESPrimaryVersionSpec primaryVersionSpec, final ESTagVersionSpec tagVersionSpec,
final IProgressMonitor monitor)
throws ESException {
final ESPrimaryVersionSpecImpl primaryVersionSpecImpl = (ESPrimaryVersionSpecImpl) primaryVersionSpec;
final ESTagVersionSpecImpl tagVersionSpecImpl = (ESTagVersionSpecImpl) tagVersionSpec;
RunESCommand.WithException.run(ESException.class, new Callable<Void>() {
public Void call() throws Exception {
return new ServerCall<Void>(getServerInfo(), monitor) {
@Override
protected Void run() throws ESException {
getConnectionManager().addTag(
getUsersession().getSessionId(),
getProjectInfo().getProjectId(),
primaryVersionSpecImpl.toInternalAPI(),
tagVersionSpecImpl.toInternalAPI());
return null;
}
}.execute();
}
});
}
/**
*
* {@inheritDoc}
*
* @see org.eclipse.emf.emfstore.client.ESProject#removeTag(org.eclipse.emf.emfstore.server.model.versionspec.ESPrimaryVersionSpec,
* org.eclipse.emf.emfstore.server.model.versionspec.ESTagVersionSpec,
* org.eclipse.core.runtime.IProgressMonitor)
*/
public void removeTag(final ESPrimaryVersionSpec versionSpec, final ESTagVersionSpec tag,
final IProgressMonitor monitor)
throws ESException {
final ESPrimaryVersionSpecImpl versionSpecImpl = (ESPrimaryVersionSpecImpl) versionSpec;
final ESTagVersionSpecImpl tagVersionSpecImpl = (ESTagVersionSpecImpl) tag;
RunESCommand.WithException.run(ESException.class, new Callable<Void>() {
public Void call() throws Exception {
new ServerCall<Void>(getServerInfo(), monitor) {
@Override
protected Void run() throws ESException {
getConnectionManager().removeTag(
getUsersession().getSessionId(),
projectInfo.getProjectId(),
versionSpecImpl.toInternalAPI(),
tagVersionSpecImpl.toInternalAPI());
return null;
}
}.execute();
return null;
}
});
}
/**
*
* {@inheritDoc}
*
* @see org.eclipse.emf.emfstore.client.ESRemoteProject#checkout(java.lang.String,
* org.eclipse.core.runtime.IProgressMonitor)
*/
public ESLocalProjectImpl checkout(final String name, final IProgressMonitor monitor)
throws ESException {
return RunESCommand.WithException.runWithResult(ESException.class, new Callable<ESLocalProjectImpl>() {
public ESLocalProjectImpl call() throws Exception {
return new ServerCall<ESLocalProjectImpl>(getServerInfo()) {
@Override
protected ESLocalProjectImpl run() throws ESException {
return checkout(name, getUsersession().toAPI(), monitor);
}
}.execute();
}
});
}
/**
*
* {@inheritDoc}
*
* @see org.eclipse.emf.emfstore.client.ESRemoteProject#checkout(java.lang.String,
* org.eclipse.emf.emfstore.client.ESUsersession, org.eclipse.core.runtime.IProgressMonitor)
*/
public ESLocalProjectImpl checkout(final String name, final ESUsersession usersession,
final IProgressMonitor monitor)
throws ESException {
return RunESCommand.WithException.runWithResult(ESException.class, new Callable<ESLocalProjectImpl>() {
public ESLocalProjectImpl call() throws Exception {
final ESPrimaryVersionSpec primaryVersionSpec = resolveVersionSpec(usersession, Versions.createHEAD()
.toAPI(), monitor);
return checkout(name, usersession, primaryVersionSpec, monitor);
}
});
}
/**
*
* {@inheritDoc}
*
* @see org.eclipse.emf.emfstore.client.ESRemoteProject#fetch(java.lang.String,
* org.eclipse.emf.emfstore.client.ESUsersession,
* org.eclipse.emf.emfstore.server.model.versionspec.ESPrimaryVersionSpec,
* org.eclipse.core.runtime.IProgressMonitor)
*/
public ESLocalProjectImpl fetch(final String name, final ESUsersession session,
final ESPrimaryVersionSpec versionSpec, final IProgressMonitor progressMonitor) throws ESException {
final SubMonitor parentMonitor = SubMonitor.convert(progressMonitor,
Messages.ESRemoteProjectImpl_Fetching_Title, 100);
final Usersession usersession = ((ESUsersessionImpl) session).toInternalAPI();
final ESPrimaryVersionSpecImpl primaryVersionSpecImpl = (ESPrimaryVersionSpecImpl) versionSpec;
final ProjectInfo projectInfoCopy = ModelUtil.clone(getProjectInfo());
projectInfoCopy.setVersion(primaryVersionSpecImpl.toInternalAPI());
return RunESCommand.WithException.runWithResult(ESException.class, new Callable<ESLocalProjectImpl>() {
public ESLocalProjectImpl call() throws Exception {
Project project = null;
final SubMonitor childMonitor = parentMonitor.newChild(40);
parentMonitor.subTask(Messages.ESRemoteProjectImpl_Fetching_Project);
project = new UnknownEMFStoreWorkloadCommand<Project>(childMonitor) {
@Override
public Project run(IProgressMonitor monitor) throws ESException {
return new ServerCall<Project>(usersession) {
@Override
protected Project run() throws ESException {
return getConnectionManager().getProject(usersession.getSessionId(),
getProjectInfo().getProjectId(),
projectInfoCopy.getVersion());
}
}.execute();
}
}.execute();
if (project == null) {
throw new ESException(Messages.ESRemoteProjectImpl_Server_Returned_Null_Project);
}
return initProjectSpace(usersession, projectInfoCopy, project, name).toAPI();
}
});
}
/**
*
* {@inheritDoc}
*
* @see org.eclipse.emf.emfstore.client.ESRemoteProject#checkout(java.lang.String,
* org.eclipse.emf.emfstore.client.ESUsersession,
* org.eclipse.emf.emfstore.server.model.versionspec.ESPrimaryVersionSpec,
* org.eclipse.core.runtime.IProgressMonitor)
*/
public ESLocalProjectImpl checkout(final String name, final ESUsersession session,
final ESPrimaryVersionSpec versionSpec, final IProgressMonitor progressMonitor)
throws ESException {
final ESLocalProjectImpl project = fetch(name, session, versionSpec, progressMonitor);
project.addToWorkspace(progressMonitor);
ESWorkspaceProviderImpl.getObserverBus().notify(ESCheckoutObserver.class)
.checkoutDone(project);
return project;
}
private ProjectSpace initProjectSpace(final Usersession usersession, final ProjectInfo projectInfoCopy,
Project project, String projectName) {
final ProjectSpace projectSpace = ModelFactory.eINSTANCE.createProjectSpace();
projectSpace.setProjectId(projectInfoCopy.getProjectId());
projectSpace.setProjectName(projectName);
projectSpace.setProjectDescription(projectInfoCopy.getDescription());
projectSpace.setBaseVersion(projectInfoCopy.getVersion());
projectSpace.setLastUpdated(new Date());
projectSpace.setUsersession(usersession);
projectSpace.setProject(project);
projectSpace.setResourceCount(0);
final ResourceSetImpl resourceSetImpl = new ResourceSetImpl();
final XMIResource res = (XMIResource) resourceSetImpl.createResource(ModelUtil.VIRTUAL_URI);
((ResourceImpl) res).setIntrinsicIDToEObjectMap(new HashMap<String, EObject>());
res.getContents().add(project);
projectSpace.setResourceSet(resourceSetImpl);
return projectSpace;
}
/**
*
* {@inheritDoc}
*
* @see org.eclipse.emf.emfstore.client.ESRemoteProject#delete(org.eclipse.core.runtime.IProgressMonitor)
*/
public void delete(final IProgressMonitor monitor) throws ESException {
RunESCommand.WithException.run(ESException.class, new Callable<Void>() {
public Void call() throws Exception {
getDeleteProjectServerCall()
.setProgressMonitor(monitor)
.setServer(getServerInfo())
.execute();
return null;
}
});
}
/**
*
* {@inheritDoc}
*
* @see org.eclipse.emf.emfstore.client.ESRemoteProject#delete(org.eclipse.emf.emfstore.client.ESUsersession,
* org.eclipse.core.runtime.IProgressMonitor)
*/
public void delete(ESUsersession session, final IProgressMonitor monitor) throws ESException {
final Usersession usersession = ((ESUsersessionImpl) session).toInternalAPI();
RunESCommand.WithException.run(ESException.class, new Callable<Void>() {
public Void call() throws Exception {
getDeleteProjectServerCall()
.setProgressMonitor(monitor)
.setUsersession(usersession)
.execute();
return null;
}
});
}
/**
*
* {@inheritDoc}
*
* @see org.eclipse.emf.emfstore.client.ESRemoteProject#getServer()
*/
public ESServerImpl getServer() {
return RunESCommand.runWithResult(new Callable<ESServerImpl>() {
public ESServerImpl call() throws Exception {
return getServerInfo().toAPI();
}
});
}
/**
*
* {@inheritDoc}
*
* @see org.eclipse.emf.emfstore.client.ESRemoteProject#getHeadVersion(org.eclipse.core.runtime.IProgressMonitor)
*/
public ESPrimaryVersionSpec getHeadVersion(final IProgressMonitor monitor) throws ESException {
return RunESCommand.WithException.runWithResult(ESException.class, new Callable<ESPrimaryVersionSpec>() {
public ESPrimaryVersionSpec call() throws Exception {
return resolveVersionSpec(Versions.createHEAD().toAPI(), monitor);
}
});
}
private boolean canDeleteFiles(ACOrgUnit<?> orgUnit, ProjectId projectId) {
final List<Role> roles = orgUnit.getRoles();
for (final Role role : roles) {
if (ServerAdmin.class.isInstance(role)) {
return true;
}
}
return false;
}
private ServerCall<Void> getDeleteProjectServerCall() {
return new ServerCall<Void>() {
@Override
protected Void run() throws ESException {
new UnknownEMFStoreWorkloadCommand<Void>(getProgressMonitor()) {
@Override
public Void run(IProgressMonitor monitor) throws ESException {
// TODO: do we need to resolve here once more to fetch the actual roles
// of a user?
// final ACOrgUnit user = ESWorkspaceProviderImpl
// .getInstance()
// .getConnectionManager()
// .get
// .getOrgUnit(getSessionId(), getUsersession().getACUser().getId());
//
final ACUser user = getUsersession().getACUser();
if (canDeleteFiles(user, getProjectInfo().getProjectId())) {
getConnectionManager()
.deleteProject(getSessionId(), getProjectInfo().getProjectId(), true);
} else {
getConnectionManager()
.deleteProject(getSessionId(), getProjectInfo().getProjectId(), false);
}
return null;
}
}.execute();
return null;
}
};
}
/**
* Returns the project info of this remote project.
*
* @return the project info of this remote project
*/
public ProjectInfo getProjectInfo() {
return projectInfo;
}
/**
* Returns the server info of this remote project.
*
* @return the server info of this remote project
*/
public ServerInfo getServerInfo() {
return server;
}
}