blob: 117559e5b82a4745e40e9584e670312bedc697a2 [file] [log] [blame]
/*
* Copyright (c) 2015 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.cdo.internal.explorer.checkouts;
import org.eclipse.emf.cdo.CDOObject;
import org.eclipse.emf.cdo.CDOState;
import org.eclipse.emf.cdo.common.CDOCommonSession.Options.LockNotificationMode;
import org.eclipse.emf.cdo.common.CDOCommonSession.Options.PassiveUpdateMode;
import org.eclipse.emf.cdo.common.branch.CDOBranch;
import org.eclipse.emf.cdo.common.branch.CDOBranchManager;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.id.CDOIDGenerator;
import org.eclipse.emf.cdo.explorer.CDOExplorerManager.ElementsChangedEvent;
import org.eclipse.emf.cdo.explorer.repositories.CDORepository;
import org.eclipse.emf.cdo.server.IStore;
import org.eclipse.emf.cdo.server.db.CDODBUtil;
import org.eclipse.emf.cdo.server.db.mapping.IMappingStrategy;
import org.eclipse.emf.cdo.session.CDOSession;
import org.eclipse.emf.cdo.session.CDOSession.ExceptionHandler;
import org.eclipse.emf.cdo.session.CDOSessionConfiguration;
import org.eclipse.emf.cdo.session.CDOSessionConfigurationFactory;
import org.eclipse.emf.cdo.spi.workspace.InternalCDOWorkspace;
import org.eclipse.emf.cdo.view.CDOFetchRuleManager;
import org.eclipse.emf.cdo.view.CDOView;
import org.eclipse.emf.cdo.workspace.CDOWorkspace.DirtyStateChangedEvent;
import org.eclipse.emf.cdo.workspace.CDOWorkspace.ObjectStatesChangedEvent;
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.util.collection.Closeable;
import org.eclipse.net4j.util.event.IEvent;
import org.eclipse.net4j.util.event.IListener;
import org.eclipse.net4j.util.security.IPasswordCredentialsProvider;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.h2.jdbcx.JdbcDataSource;
import java.io.File;
import java.util.HashSet;
import java.util.Properties;
import java.util.Set;
/**
* @author Eike Stepper
*/
public class OfflineCDOCheckout extends CDOCheckoutImpl
{
public static final String PROP_DIRTY = "dirty";
private final IListener workspaceListener = new IListener()
{
public void notifyEvent(IEvent event)
{
if (event instanceof DirtyStateChangedEvent)
{
DirtyStateChangedEvent e = (DirtyStateChangedEvent)event;
setDirty(e.isDirty());
fireElementChangedEvent(ElementsChangedEvent.StructuralImpact.NONE);
}
else if (event instanceof ObjectStatesChangedEvent)
{
ObjectStatesChangedEvent e = (ObjectStatesChangedEvent)event;
Set<Object> objects = new HashSet<Object>();
CDOView view = getView();
for (CDOID id : e.getChangedIDs())
{
CDOObject object = view.getObject(id, false);
if (object != null)
{
objects.add(object);
}
}
getManager().fireElementsChangedEvent(objects.toArray());
}
}
};
private InternalCDOWorkspace workspace;
private boolean dirty;
public OfflineCDOCheckout()
{
}
public boolean isOffline()
{
return true;
}
public boolean isOnline()
{
return false;
}
@Override
public void setReadOnly(boolean readOnly)
{
throw new IllegalStateException("Checkout is offline: " + this);
}
public final InternalCDOWorkspace getWorkspace()
{
return workspace;
}
public final boolean isDirty()
{
if (workspace != null)
{
return workspace.isDirty();
}
return dirty;
}
public final void setDirty(boolean dirty)
{
if (this.dirty != dirty)
{
this.dirty = dirty;
save();
}
}
public CDOState getState(Object object)
{
if (object == this)
{
return isDirty() ? CDOState.DIRTY : CDOState.CLEAN;
}
if (workspace != null)
{
return workspace.getState(object);
}
return null;
}
@Override
public String getBranchPath()
{
if (workspace != null)
{
return workspace.getBranchPath();
}
return super.getBranchPath();
}
@Override
protected String doSetBranchPoint(int branchID, long timeStamp)
{
CDORepository repository = getRepository();
CDOSession session = repository.acquireSession();
try
{
CDOBranch branch = session.getBranchManager().getBranch(branchID);
if (branch != null)
{
String branchPath = branch.getPathName();
workspace.replace(branchPath, timeStamp);
return branchPath;
}
}
finally
{
repository.releaseSession();
}
return null;
}
@Override
protected void init(File folder, String type, Properties properties)
{
super.init(folder, type, properties);
dirty = Boolean.parseBoolean(properties.getProperty(PROP_DIRTY, "false"));
}
@Override
protected void collectProperties(Properties properties)
{
super.collectProperties(properties);
properties.setProperty(PROP_DIRTY, Boolean.toString(dirty));
}
@Override
protected CDOView openView(CDOSession session)
{
CDOSessionConfigurationFactory remote = new CDOSessionConfigurationFactory()
{
public CDOSessionConfiguration createSessionConfiguration()
{
return new RemoteSessionConfiguration();
}
};
File folder = getFolder();
File storeFolder = new File(folder, "store");
File dbPrefix = new File(storeFolder, "db");
JdbcDataSource dataSource = new JdbcDataSource();
dataSource.setURL("jdbc:h2:" + dbPrefix);
IMappingStrategy mappingStrategy = CDODBUtil.createHorizontalMappingStrategy(true, true, false);
IDBAdapter dbAdapter = DBUtil.getDBAdapter("h2");
IDBConnectionProvider connectionProvider = DBUtil.createConnectionProvider(dataSource);
IStore store = CDODBUtil.createStore(mappingStrategy, dbAdapter, connectionProvider);
File baseFolder = new File(folder, "base");
CDOWorkspaceBase base = CDOWorkspaceUtil.createFolderWorkspaceBase(baseFolder);
String localRepositoryName = getRepository().getName() + "-workspace" + getID();
int branchID = getBranchID();
long timeStamp = getTimeStamp();
CDOWorkspaceConfiguration configuration = CDOWorkspaceUtil.createWorkspaceConfiguration();
configuration.setLocalRepositoryName(localRepositoryName);
configuration.setRemote(remote);
configuration.setStore(store);
configuration.setBase(base);
if (storeFolder.isDirectory())
{
workspace = (InternalCDOWorkspace)configuration.open();
}
else
{
configuration.setBranchID(branchID);
configuration.setTimeStamp(timeStamp);
workspace = (InternalCDOWorkspace)configuration.checkout();
}
setBranchPath(workspace.getBranchPath());
setDirty(workspace.isDirty());
workspace.addListener(workspaceListener);
return workspace.openView();
}
@Override
protected void closeView()
{
super.closeView();
if (workspace != null)
{
workspace.close();
workspace = null;
}
}
@Override
protected CDOView doOpenView(boolean readOnly, ResourceSet resourceSet)
{
if (workspace == null)
{
return null;
}
if (readOnly)
{
return workspace.openView(resourceSet);
}
return workspace.openTransaction(resourceSet);
}
/**
* @author Eike Stepper
*/
private final class RemoteSessionConfiguration implements CDOSessionConfiguration, Closeable
{
private boolean closed;
public void addListener(IListener listener)
{
}
public void removeListener(IListener listener)
{
}
public boolean hasListeners()
{
return false;
}
public IListener[] getListeners()
{
return null;
}
public String getUserID()
{
return null;
}
public void setUserID(String userID)
{
}
public boolean isPassiveUpdateEnabled()
{
return false;
}
public void setPassiveUpdateEnabled(boolean passiveUpdateEnabled)
{
}
public PassiveUpdateMode getPassiveUpdateMode()
{
return null;
}
public void setPassiveUpdateMode(PassiveUpdateMode passiveUpdateMode)
{
}
public LockNotificationMode getLockNotificationMode()
{
return null;
}
public void setLockNotificationMode(LockNotificationMode mode)
{
}
public ExceptionHandler getExceptionHandler()
{
return null;
}
public void setExceptionHandler(ExceptionHandler exceptionHandler)
{
}
public CDOIDGenerator getIDGenerator()
{
return null;
}
public void setIDGenerator(CDOIDGenerator idGenerator)
{
}
public CDOFetchRuleManager getFetchRuleManager()
{
return null;
}
public void setFetchRuleManager(CDOFetchRuleManager fetchRuleManager)
{
}
public CDOBranchManager getBranchManager()
{
return null;
}
public void setBranchManager(CDOBranchManager branchManager)
{
}
@Deprecated
public org.eclipse.emf.cdo.common.protocol.CDOAuthenticator getAuthenticator()
{
return null;
}
public IPasswordCredentialsProvider getCredentialsProvider()
{
return null;
}
public void setCredentialsProvider(IPasswordCredentialsProvider credentialsProvider)
{
}
public boolean isActivateOnOpen()
{
return false;
}
public void setActivateOnOpen(boolean activateOnOpen)
{
}
public boolean isSessionOpen()
{
return !closed;
}
public CDOSession openSession()
{
CDORepository repository = getRepository();
return repository.acquireSession();
}
public void close()
{
if (!closed)
{
CDORepository repository = getRepository();
repository.releaseSession();
closed = true;
}
}
public boolean isClosed()
{
return closed;
}
}
}