| [CDO] [message #913412] |
Sat, 15 September 2012 11:11  |
Eclipse User |
|
|
|
Hi,
I would like to change some model instances over the web.
Has anyone tried opening a CDOSession in a servlet environment?
KL
|
|
|
| Re: [CDO] In a servlet container [message #913434 is a reply to message #913412] |
Sat, 15 September 2012 12:45   |
Eclipse User |
|
|
|
Am 15.09.2012 17:11, schrieb Kenny Lee:
> Hi,
>
> I would like to change some model instances over the web.
>
> Has anyone tried opening a CDOSession in a servlet environment?
I've done that a couple of months ago. Here's some code that might help:
/**
* @author Eike Stepper
*/
public interface CDOService
{
public CDOView getView();
public CDOTransaction openTransaction();
public <T extends CDOObject> Object modify(T object, ITransactionalOperation<T> operation) throws CommitException;
public <T extends CDOObject> T modify(ITransactionalOperation<T> operation) throws CommitException;
/**
* @author Eike Stepper
*/
public interface ITransactionalOperation<T extends CDOObject>
{
public Object execute(T object, CDOTransaction transaction);
}
}
/**
* @author Eike Stepper
*/
public abstract class AbstractCDOService extends AbstractContextService implements CDOService
{
public static final String EXTERNAL_REPOSITORY_NAME = "external";
public static final String EXTERNAL_REPOSITORY_DIR = "externalRepositoryDir";
public static final String EXTERNAL_PORT = "externalPort";
public static final String SERVER_BROWSER_PORT = "serverBrowserPort";
public static final String ACCEPTOR_NAME = "default";
private CDOSession session;
private CDOView view;
public AbstractCDOService()
{
}
public CDOSession getSession()
{
return session;
}
@Override
public CDOView getView()
{
return view;
}
@Override
public CDOTransaction openTransaction()
{
return session.openTransaction();
}
@Override
public <T extends CDOObject> Object modify(T object, ITransactionalOperation<T> operation) throws CommitException
{
CDOTransaction transaction = session.openTransaction();
try
{
T transactionalObject = object == null ? null : transaction.getObject(object);
Object result = operation.execute(transactionalObject, transaction);
CDOCommitInfo commitInfo = transaction.commit();
view.waitForUpdate(commitInfo.getTimeStamp());
if (result instanceof CDOObject)
{
return view.getObject((CDOObject)result);
}
return result;
}
finally
{
transaction.close();
}
}
@Override
public <T extends CDOObject> T modify(ITransactionalOperation<T> operation) throws CommitException
{
@SuppressWarnings("unchecked")
T result = (T)modify((T)null, operation);
return result;
}
@Override
protected void init(ServletContext context)
{
IManagedContainer container = createContainer();
// Repository
JdbcDataSource dataSource = createDataSource(context);
IDBStore store = createStore(dataSource);
IRepository repository = createRepository(store);
CDOServerUtil.addRepository(container, repository);
// Server Browser
String serverBrowserPort = context.getInitParameter(SERVER_BROWSER_PORT);
if (serverBrowserPort != null)
{
register(container.getElement("org.eclipse.emf.cdo.server.browsers", "default", serverBrowserPort));
}
// External Connection
String externalPort = context.getInitParameter(EXTERNAL_PORT);
if (externalPort != null)
{
register(TCPUtil.getAcceptor(container, "0.0.0.0:" + externalPort));
}
// Internal Connection
register(JVMUtil.getAcceptor(container, ACCEPTOR_NAME));
IConnector connector = register(JVMUtil.getConnector(container, ACCEPTOR_NAME));
// Session
session = createSession(connector);
// View
view = createView();
}
protected IManagedContainer createContainer()
{
IManagedContainer container = register(ContainerUtil.createContainer());
Net4jUtil.prepareContainer(container);
JVMUtil.prepareContainer(container);
TCPUtil.prepareContainer(container);
CDONet4jServerUtil.prepareContainer(container);
CDODBUtil.prepareContainer(container);
container.registerFactory(new CDOServerBrowser.ContainerBased.Factory(container));
container.activate();
return container;
}
protected JdbcDataSource createDataSource(ServletContext context)
{
String databaseFolder = context.getInitParameter(EXTERNAL_REPOSITORY_DIR);
JdbcDataSource dataSource = register(new JdbcDataSource());
dataSource.setURL("jdbc:h2:" + databaseFolder);
return dataSource;
}
protected IDBStore createStore(DataSource dataSource)
{
IMappingStrategy mappingStrategy = CDODBUtil.createHorizontalMappingStrategy(false, false);
IDBAdapter dbAdapter = new H2Adapter();
IDBConnectionProvider dbConnectionProvider = DBUtil.createConnectionProvider(dataSource);
return CDODBUtil.createStore(mappingStrategy, dbAdapter, dbConnectionProvider);
}
protected IRepository createRepository(IStore store)
{
Map<String, String> props = new HashMap<String, String>();
props.put(IRepository.Props.OVERRIDE_UUID, "");
props.put(IRepository.Props.SUPPORTING_AUDITS, "false");
props.put(IRepository.Props.SUPPORTING_BRANCHES, "false");
return register(CDOServerUtil.createRepository(EXTERNAL_REPOSITORY_NAME, store, props));
}
protected CDOSession createSession(IConnector connector)
{
CDONet4jSessionConfiguration configuration = CDONet4jUtil.createNet4jSessionConfiguration();
configuration.setConnector(connector);
configuration.setRepositoryName(EXTERNAL_REPOSITORY_NAME);
configuration.setRevisionManager(CDORevisionUtil.createRevisionManager(CDORevisionCache.NOOP));
CDOSession session = register(configuration.openNet4jSession());
session.options().setPassiveUpdateMode(PassiveUpdateMode.CHANGES);
return session;
}
protected CDOView createView()
{
return session.openView();
}
}
/**
* @author Eike Stepper
*/
public abstract class AbstractContextService implements ServletContextListener
{
private final List<Object> dependencies = new ArrayList<Object>();
public AbstractContextService()
{
}
@Override
public final void contextInitialized(ServletContextEvent event)
{
try
{
init(event.getServletContext());
setInstance(this);
}
catch (Error ex)
{
ex.printStackTrace();
throw ex;
}
catch (RuntimeException ex)
{
ex.printStackTrace();
throw ex;
}
}
@Override
public final void contextDestroyed(ServletContextEvent event)
{
try
{
setInstance(null);
destroy();
}
catch (Error ex)
{
ex.printStackTrace();
throw ex;
}
catch (RuntimeException ex)
{
ex.printStackTrace();
throw ex;
}
}
protected abstract void setInstance(AbstractContextService instance);
protected abstract void init(ServletContext context);
protected void destroy()
{
for (int i = dependencies.size() - 1; i >= 0; --i)
{
Object dependency = dependencies.get(i);
LifecycleUtil.deactivate(dependency);
}
dependencies.clear();
}
protected final <T> T register(T dependency)
{
if (dependency instanceof DataSource && !(dependency instanceof LifecycleDataSource))
{
register(new LifecycleDataSource((DataSource)dependency));
}
else
{
dependencies.add(dependency);
}
return dependency;
}
}
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| Re: [CDO] In a servlet container [message #915297 is a reply to message #915070] |
Sun, 16 September 2012 22:33  |
Eclipse User |
|
|
|
Eike Stepper wrote on Sun, 16 September 2012 06:55Am 16.09.2012 12:17, schrieb Erdal Karaca:
> AFAIK, everything you put into the http session must be serializable: that is where you will get problems if the web
> container decides to un/serialize the CDOTransaction...
Yeah, probably easier to put something into the context that is easy to serialize and can open or provide a
CDOSession/CDOTransaction. Not sure about context lifecycle though and how that impacts resource cleanup.
I guess we can put the CDOSession's id into the HttpSession, but we have to keep the CDOSession object somewhere.
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
|