blob: 1b38fc5bf31a6f34708fce4d0def4685f347106b [file] [log] [blame]
/***************************************************************************
* Copyright (c) 2004 - 2008 Eike Stepper, 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
* Martin Taal - moved code from HibernateStore to this class
**************************************************************************/
package org.eclipse.emf.cdo.server.internal.hibernate;
import org.eclipse.emf.cdo.common.model.CDOClass;
import org.eclipse.emf.cdo.common.model.CDOClassProxy;
import org.eclipse.emf.cdo.common.model.CDOFeature;
import org.eclipse.emf.cdo.common.model.CDOPackage;
import org.eclipse.emf.cdo.common.model.CDOPackageInfo;
import org.eclipse.emf.cdo.internal.server.TransactionCommitContextImpl;
import org.eclipse.emf.cdo.server.IStoreAccessor.CommitContext;
import org.eclipse.emf.cdo.server.internal.hibernate.bundle.OM;
import org.eclipse.emf.cdo.spi.common.model.InternalCDOClass;
import org.eclipse.emf.cdo.spi.common.model.InternalCDOFeature;
import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackage;
import org.eclipse.net4j.util.ObjectUtil;
import org.eclipse.net4j.util.WrappedException;
import org.eclipse.net4j.util.io.IOUtil;
import org.eclipse.net4j.util.lifecycle.Lifecycle;
import org.eclipse.net4j.util.om.trace.ContextTracer;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.criterion.Expression;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.hibernate.tool.hbm2ddl.SchemaUpdate;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
* Delegate which stores and retrieves cdo packages.
* <p>
* TODO extend {@link Lifecycle}. See {@link #doActivate()} and {@link #doDeactivate()}.
*
* @author Eike Stepper
* @author Martin Taal
*/
public class HibernatePackageHandler extends Lifecycle
{
private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, HibernatePackageHandler.class);
private Configuration configuration;
private SessionFactory sessionFactory;
private int nextPackageID;
private int nextClassID;
private int nextFeatureID;
private Collection<CDOPackageInfo> cdoPackageInfos = null;
private HibernateStore hibernateStore;
/**
* TODO Necessary to pass/store/dump the properties from the store?
*/
public HibernatePackageHandler(HibernateStore store)
{
hibernateStore = store;
}
public List<CDOPackage> getCDOPackages()
{
List<CDOPackage> cdoPackages = new ArrayList<CDOPackage>();
if (HibernateThreadContext.isHibernateCommitContextSet())
{
CommitContext cc = HibernateThreadContext.getHibernateCommitContext().getCommitContext();
if (cc instanceof TransactionCommitContextImpl)
{
TransactionCommitContextImpl tx = (TransactionCommitContextImpl)cc;
for (CDOPackage cdoPackage : tx.getNewPackages())
{
cdoPackages.add(cdoPackage);
}
}
}
for (CDOPackage cdoPackage : hibernateStore.getRepository().getPackageManager().getPackages())
{
cdoPackages.add(cdoPackage);
}
for (CDOPackage cdoPackage : cdoPackages)
{
// force resolve
if (cdoPackage.getClassCount() == 0)
{
if (TRACER.isEnabled())
{
TRACER.trace("Returning " + cdoPackage.getPackageURI());
}
}
}
return cdoPackages;
}
public void writePackages(CDOPackage... cdoPackages)
{
if (TRACER.isEnabled())
{
TRACER.trace("Persisting new CDOPackages");
}
Session session = getSessionFactory().openSession();
Transaction tx = session.beginTransaction();
boolean err = true;
boolean updated = false;
try
{
for (CDOPackage cdoPackage : cdoPackages)
{
if (cdoPackageExistsAndIsUnchanged(cdoPackage))
{
OM.LOG.warn("CDOPackage " + cdoPackage.getPackageURI() + " already exists not persisting it again!");
continue;
}
if (TRACER.isEnabled())
{
TRACER.trace("Persisting CDOPackage " + cdoPackage.getPackageURI());
}
session.saveOrUpdate(cdoPackage);
updated = true;
}
tx.commit();
err = false;
}
finally
{
if (err)
{
tx.rollback();
}
session.close();
}
if (updated)
{
reset();
hibernateStore.reInitialize();
}
}
protected boolean cdoPackageExistsAndIsUnchanged(CDOPackage newCDOPackage)
{
CDOPackage[] cdoPackages = hibernateStore.getRepository().getPackageManager().getPackages();
for (CDOPackage cdoPackage : cdoPackages)
{
if (cdoPackage.getClassCount() > 0 && cdoPackage.getPackageURI().equals(newCDOPackage.getPackageURI()))
{
String ecore = cdoPackage.getEcore();
String newEcore = newCDOPackage.getEcore();
return ObjectUtil.equals(ecore, newEcore);
}
}
return false;
}
public void writePackage(CDOPackage cdoPackage)
{
if (cdoPackageExistsAndIsUnchanged(cdoPackage))
{
OM.LOG.warn("CDOPackage " + cdoPackage.getPackageURI() + " already exists not persisting it again!");
return;
}
Session session = getSessionFactory().openSession();
Transaction tx = session.beginTransaction();
boolean err = true;
try
{
if (TRACER.isEnabled())
{
TRACER.trace("Persisting CDOPackage " + cdoPackage.getPackageURI());
}
session.saveOrUpdate(cdoPackage);
tx.commit();
err = false;
}
finally
{
if (err)
{
tx.rollback();
}
session.close();
}
reset();
hibernateStore.reInitialize();
}
public Collection<CDOPackageInfo> getCDOPackageInfos()
{
readPackageInfos();
return cdoPackageInfos;
}
protected void readPackage(CDOPackage cdoPackage)
{
if (cdoPackage.getClassCount() > 0)
{ // already initialized go away
return;
}
if (TRACER.isEnabled())
{
TRACER.trace("Reading CDOPackage with uri " + cdoPackage.getPackageURI() + " from db");
}
Session session = getSessionFactory().openSession();
try
{
Criteria criteria = session.createCriteria(CDOPackage.class);
criteria.add(Expression.eq("packageURI", cdoPackage.getPackageURI()));
List<?> list = criteria.list();
if (list.size() != 1)
{
throw new IllegalArgumentException("CDOPackage with uri " + cdoPackage.getPackageURI()
+ " not present in the db");
}
if (TRACER.isEnabled())
{
TRACER.trace("Found " + list.size() + " CDOPackages in DB");
}
CDOPackage dbPackage = (CDOPackage)list.get(0);
if (TRACER.isEnabled())
{
TRACER.trace("Read CDOPackage: " + cdoPackage.getName());
}
((InternalCDOPackage)cdoPackage).setServerInfo(dbPackage.getServerInfo());
((InternalCDOPackage)cdoPackage).setName(dbPackage.getName());
((InternalCDOPackage)cdoPackage).setEcore(dbPackage.getEcore());
((InternalCDOPackage)cdoPackage).setMetaIDRange(cdoPackage.getMetaIDRange());
final List<CDOClass> cdoClasses = new ArrayList<CDOClass>();
for (CDOClass cdoClass : dbPackage.getClasses())
{
cdoClasses.add(cdoClass);
for (CDOClassProxy proxy : ((InternalCDOClass)cdoClass).getSuperTypeProxies())
{
proxy.setCDOPackageManager(hibernateStore.getRepository().getPackageManager());
}
for (CDOFeature cdoFeature : cdoClass.getFeatures())
{
final InternalCDOFeature internalFeature = (InternalCDOFeature)cdoFeature;
internalFeature.setContainingClass(cdoClass);
if (internalFeature.getReferenceTypeProxy() != null)
{
internalFeature.getReferenceTypeProxy().setCDOPackageManager(
hibernateStore.getRepository().getPackageManager());
}
}
// // force indices to be set
// if (cdoClass.getAllFeatures().length > 0)
// {
// ((InternalCDOClass)cdoClass).getFeatureIndex(0);
// }
}
((InternalCDOPackage)cdoPackage).setClassifiers(cdoClasses);
}
finally
{
session.close();
}
if (TRACER.isEnabled())
{
TRACER.trace("Finished reading CDOPackages");
}
}
protected void readPackageInfos()
{
if (cdoPackageInfos == null || cdoPackageInfos.size() == 0)
{
if (TRACER.isEnabled())
{
TRACER.trace("Reading CDOPackages from db");
}
Collection<CDOPackageInfo> result = new ArrayList<CDOPackageInfo>();
Session session = getSessionFactory().openSession();
try
{
Criteria criteria = session.createCriteria(CDOPackage.class);
List<?> list = criteria.list();
if (TRACER.isEnabled())
{
TRACER.trace("Found " + list.size() + " CDOPackages in DB");
}
for (Object object : list)
{
CDOPackage cdoPackage = (CDOPackage)object;
if (TRACER.isEnabled())
{
TRACER.trace("Read CDOPackage: " + cdoPackage.getName());
}
result.add(new CDOPackageInfo(cdoPackage.getPackageURI(), cdoPackage.isDynamic(),
cdoPackage.getMetaIDRange(), cdoPackage.getParentURI()));
((InternalCDOPackage)cdoPackage).setPackageManager(hibernateStore.getRepository().getPackageManager());
}
cdoPackageInfos = result;
}
finally
{
session.close();
}
}
if (TRACER.isEnabled())
{
TRACER.trace("Finished reading CDOPackages");
}
}
void doDropSchema()
{
final SchemaExport se = new SchemaExport(configuration);
se.drop(false, true);
}
public synchronized SessionFactory getSessionFactory()
{
if (sessionFactory == null)
{
sessionFactory = configuration.buildSessionFactory();
}
return sessionFactory;
}
public synchronized int getNextPackageID()
{
return nextPackageID++;
}
public synchronized int getNextClassID()
{
return nextClassID++;
}
public synchronized int getNextFeatureID()
{
return nextFeatureID++;
}
public void reset()
{
cdoPackageInfos = null;
}
@Override
protected void doActivate() throws Exception
{
super.doActivate();
initConfiguration();
initSchema();
}
@Override
protected void doDeactivate() throws Exception
{
if (sessionFactory != null)
{
sessionFactory.close();
sessionFactory = null;
}
super.doDeactivate();
}
protected void initConfiguration()
{
if (TRACER.isEnabled())
{
TRACER.trace("Initializing configuration for CDO metadata");
}
InputStream in = null;
try
{
in = OM.BUNDLE.getInputStream("mappings/meta.hbm.xml");
configuration = new Configuration();
configuration.addInputStream(in);
configuration.setProperties(HibernateUtil.getInstance().getPropertiesFromStore(hibernateStore));
}
catch (Exception ex)
{
throw WrappedException.wrap(ex);
}
finally
{
IOUtil.close(in);
}
}
protected void initSchema()
{
if (TRACER.isEnabled())
{
TRACER.trace("Updating db schema for Hibernate PackageHandler");
}
new SchemaUpdate(configuration).execute(true, true);
}
}