/* | |
* Copyright (c) 2011 Eike Stepper (Berlin, Germany) 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: | |
* Eike Stepper - initial API and implementation | |
*/ | |
package org.eclipse.emf.ecp.cdo.internal.core; | |
import org.eclipse.emf.cdo.common.branch.CDOBranch; | |
import org.eclipse.emf.cdo.common.branch.CDOBranchPoint; | |
import org.eclipse.emf.cdo.net4j.CDONet4jSession; | |
import org.eclipse.emf.cdo.net4j.CDONet4jSessionConfiguration; | |
import org.eclipse.emf.cdo.server.db.CDODBUtil; | |
import org.eclipse.emf.cdo.server.db.IDBStore; | |
import org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy; | |
import org.eclipse.emf.cdo.session.CDOSessionConfigurationFactory; | |
import org.eclipse.emf.cdo.util.CDOUtil; | |
import org.eclipse.emf.cdo.workspace.CDOWorkspaceBase; | |
import org.eclipse.emf.cdo.workspace.CDOWorkspaceConfiguration; | |
import org.eclipse.emf.cdo.workspace.CDOWorkspaceUtil; | |
import org.eclipse.net4j.db.DBUtil; | |
import org.eclipse.net4j.db.IDBAdapter; | |
import org.eclipse.net4j.db.IDBConnectionProvider; | |
import org.eclipse.net4j.db.h2.H2Adapter; | |
import org.eclipse.net4j.util.UUIDGenerator; | |
import org.eclipse.net4j.util.io.IOUtil; | |
import org.eclipse.emf.common.notify.Notifier; | |
import org.eclipse.emf.common.util.EList; | |
import org.eclipse.emf.ecore.EObject; | |
import org.eclipse.emf.ecp.core.util.ECPModelContext; | |
import org.eclipse.emf.ecp.core.util.ECPProperties; | |
import org.eclipse.emf.ecp.spi.core.DefaultProvider; | |
import org.eclipse.emf.ecp.spi.core.InternalProject; | |
import org.eclipse.emf.ecp.spi.core.InternalRepository; | |
import org.eclipse.emf.ecp.spi.core.util.InternalChildrenList; | |
import org.h2.jdbcx.JdbcDataSource; | |
import java.io.File; | |
import java.io.PrintStream; | |
import java.util.Collection; | |
/** | |
* @author Eike Stepper | |
*/ | |
public class CDOProvider extends DefaultProvider { | |
public static final String NAME = "org.eclipse.emf.ecp.cdo.provider"; | |
public static final String PROP_CONNECTOR_TYPE = "connectorType"; | |
public static final String PROP_CONNECTOR_DESCRIPTION = "connectorDescription"; | |
public static final String PROP_REPOSITORY_NAME = "repositoryName"; | |
public static final String PROP_BRANCH_PATH = "branchPath"; | |
public static final String PROP_TIME_STAMP = "timeStamp"; | |
public static final String PROP_WORKSPACE_ID = "workspaceID"; | |
public static CDOProvider INSTANCE; | |
public CDOProvider() { | |
super(NAME); | |
INSTANCE = this; | |
CDOUtil.setLegacyModeDefault(true); | |
} | |
@Override | |
protected void doDispose() { | |
INSTANCE = null; | |
super.doDispose(); | |
} | |
@Override | |
public <T> T getAdapter(Object adaptable, Class<T> adapterType) { | |
T adapter = ECPProjectAdapterFactory.adapt(adaptable, adapterType); | |
if (adapter != null) { | |
return adapter; | |
} | |
return super.getAdapter(adaptable, adapterType); | |
} | |
@Override | |
public boolean isSlow(Object parent) { | |
if (parent instanceof CDOBranchWrapper) { | |
return true; | |
} | |
if (parent instanceof EObject) { | |
return true; | |
} | |
return super.isSlow(parent); | |
} | |
@Override | |
public void fillChildren(ECPModelContext context, Object parent, InternalChildrenList childrenList) { | |
if (parent instanceof InternalProject) { | |
InternalProject project = (InternalProject) parent; | |
CDOProjectData projectData = getProjectData(project); | |
childrenList.addChildren(projectData.getRootResource().getContents()); | |
} else if (parent instanceof InternalRepository) { | |
InternalRepository repository = (InternalRepository) parent; | |
CDOBranchWrapper wrapper = new CDOBranchWrapper(repository, CDOBranch.MAIN_BRANCH_NAME); | |
childrenList.addChild(wrapper); | |
} else if (parent instanceof CDOBranchWrapper) { | |
CDOBranchWrapper parentWrapper = (CDOBranchWrapper) parent; | |
InternalRepository repository = parentWrapper.getRepository(); | |
String branchPath = parentWrapper.getBranchPath(); | |
CDONet4jSession session = null; | |
try { | |
CDORepositoryData repositoryData = getRepositoryData(repository); | |
CDONet4jSessionConfiguration sessionConfiguration = repositoryData.createSessionConfiguration(); | |
session = sessionConfiguration.openNet4jSession(); | |
CDOBranch branch = session.getBranchManager().getBranch(branchPath); | |
for (CDOBranch child : branch.getBranches()) { | |
CDOBranchWrapper wrapper = new CDOBranchWrapper(repository, child.getPathName()); | |
childrenList.addChild(wrapper); | |
} | |
} finally { | |
IOUtil.close(session); | |
} | |
} else { | |
super.fillChildren(context, parent, childrenList); | |
} | |
} | |
/** {@inheritDoc} */ | |
public EList<Object> getElements(InternalProject project) { | |
// TODO: implement CDOProvider.addRootElement(project, rootElement) | |
throw new UnsupportedOperationException(); | |
} | |
@Override | |
public void handleLifecycle(ECPModelContext context, LifecycleEvent event) { | |
super.handleLifecycle(context, event); | |
if (context instanceof InternalProject) { | |
InternalProject project = (InternalProject) context; | |
switch (event) { | |
case CREATE: | |
createProject(project); | |
break; | |
case INIT: | |
break; | |
case DISPOSE: | |
disposeProject(project); | |
break; | |
case REMOVE: | |
removeProject(project); | |
break; | |
default: | |
break; | |
} | |
} | |
} | |
protected void createProject(InternalProject project) { | |
String workspaceID = UUIDGenerator.DEFAULT.generate(); | |
project.getProperties().addProperty(PROP_WORKSPACE_ID, workspaceID); | |
CDOProjectData projectData = getProjectData(project); | |
projectData.checkoutWorkspace(); | |
File folder = getProjectFolder(project); | |
PrintStream stream = null; | |
try { | |
stream = new PrintStream(new File(folder, "ecp.properties")); | |
stream.println("project.name = " + project.getName()); | |
} catch (Exception ex) { | |
Activator.log(ex); | |
} finally { | |
IOUtil.close(stream); | |
} | |
} | |
protected CDOWorkspaceConfiguration createWorkspaceConfiguration(InternalProject project) { | |
File folder = getProjectFolder(project); | |
folder.mkdirs(); | |
IDBStore localStore = createLocalStore(project, folder); | |
CDOWorkspaceBase base = createWorkspaceBase(project, folder); | |
CDOSessionConfigurationFactory remote = getRepositoryData(project.getRepository()); | |
ECPProperties properties = project.getProperties(); | |
String branchPath = properties.getValue(PROP_BRANCH_PATH); | |
String timeStamp = properties.getValue(PROP_TIME_STAMP); | |
CDOWorkspaceConfiguration config = CDOWorkspaceUtil.createWorkspaceConfiguration(); | |
config.setLocalRepositoryName(folder.getName()); // workspaceID | |
config.setStore(localStore); | |
config.setBase(base); | |
config.setRemote(remote); | |
config.setBranchPath(branchPath == null ? CDOBranch.MAIN_BRANCH_NAME : branchPath); | |
config.setTimeStamp(timeStamp == null ? CDOBranchPoint.UNSPECIFIED_DATE : Long.parseLong(timeStamp)); | |
return config; | |
} | |
protected CDOWorkspaceBase createWorkspaceBase(InternalProject project, File folder) { | |
File base = new File(folder, "base"); | |
base.mkdirs(); | |
return CDOWorkspaceUtil.createFolderWorkspaceBase(base); | |
} | |
protected IDBStore createLocalStore(InternalProject project, File folder) { | |
File local = new File(folder, "local"); | |
local.mkdirs(); | |
JdbcDataSource dataSource = new JdbcDataSource(); | |
dataSource.setURL("jdbc:h2:" + new File(local, "local").getAbsolutePath()); | |
IMappingStrategy mappingStrategy = CDODBUtil.createHorizontalMappingStrategy(false, false); | |
IDBAdapter dbAdapter = new H2Adapter(); | |
IDBConnectionProvider dbConnectionProvider = DBUtil.createConnectionProvider(dataSource); | |
return CDODBUtil.createStore(mappingStrategy, dbAdapter, dbConnectionProvider); | |
} | |
protected void disposeProject(InternalProject project) { | |
CDOProjectData data = (CDOProjectData) project.getProviderSpecificData(); | |
data.dispose(); | |
} | |
protected void removeProject(InternalProject project) { | |
File folder = getProjectFolder(project); | |
if (folder.exists()) { | |
if (!folder.delete()) { | |
folder.deleteOnExit(); | |
} | |
} | |
} | |
public static CDORepositoryData getRepositoryData(InternalRepository repository) { | |
synchronized (repository) { | |
CDORepositoryData data = (CDORepositoryData) repository.getProviderSpecificData(); | |
if (data == null) { | |
data = new CDORepositoryData(repository); | |
repository.setProviderSpecificData(data); | |
} | |
return data; | |
} | |
} | |
public static CDOProjectData getProjectData(InternalProject project) { | |
synchronized (project) { | |
CDOProjectData data = (CDOProjectData) project.getProviderSpecificData(); | |
if (data == null) { | |
data = new CDOProjectData(project); | |
project.setProviderSpecificData(data); | |
} | |
return data; | |
} | |
} | |
public static File getProjectFolder(InternalProject project) { | |
String workspaceID = project.getProperties().getValue(PROP_WORKSPACE_ID); | |
return new File(Activator.getInstance().getStateLocation().toFile(), workspaceID); | |
} | |
/** {@inheritDoc} */ | |
public void delete(InternalProject project, Collection<EObject> eObjects) { | |
// CDOResource cdoResource = getProjectData(project).getRootResource(); | |
// cdoResource.eContents().removeAll(eObjects); | |
} | |
/** {@inheritDoc} */ | |
public void cloneProject(final InternalProject projectToClone, InternalProject targetProject) { | |
throw new UnsupportedOperationException(); | |
} | |
/** {@inheritDoc} */ | |
public Notifier getRoot(InternalProject project) { | |
throw new UnsupportedOperationException(); | |
} | |
} |