/**
* <copyright>
*
* Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) 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:
* Martin Taal
* </copyright>
*
* $Id: HbEClassAnnotator.java,v 1.7 2009/03/15 09:26:04 mtaal Exp $
*/
package org.eclipse.emf.teneo.hibernate.annotations;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.teneo.PersistenceOptions;
import org.eclipse.emf.teneo.annotations.mapper.EClassAnnotator;
import org.eclipse.emf.teneo.annotations.mapper.StoreMappingException;
import org.eclipse.emf.teneo.annotations.pamodel.PAnnotatedEClass;
import org.eclipse.emf.teneo.annotations.pamodel.PAnnotatedModel;
import org.eclipse.emf.teneo.ecore.EModelResolver;
import org.eclipse.emf.teneo.hibernate.hbannotation.Cache;
import org.eclipse.emf.teneo.hibernate.hbannotation.CacheConcurrencyStrategy;
import org.eclipse.emf.teneo.hibernate.hbannotation.HbannotationFactory;
import org.eclipse.emf.teneo.hibernate.hbannotation.Proxy;
import org.eclipse.emf.teneo.hibernate.hbmodel.HbAnnotatedEClass;
/**
* Sets the annotation on an eclass.
*
* @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
* @version $Revision: 1.7 $
*/
public class HbEClassAnnotator extends EClassAnnotator {
// The logger
protected static final Log log = LogFactory.getLog(HbEClassAnnotator.class);
private String defaultCacheStrategy = CacheConcurrencyStrategy.NONE
.getName();
private boolean optionSetProxy = false;
/**
* Returns the annotated version of an EClass, Returns false if no efeatures
* of this eclass should be annotated, true if its features can be
* annotated.
*/
@Override
protected boolean annotate(PAnnotatedEClass aClass) {
final boolean res = super.annotate(aClass);
final HbAnnotatedEClass hbClass = (HbAnnotatedEClass) aClass;
final EClass eclass = aClass.getModelEClass();
final Class<?> concreteClass = EModelResolver.instance().getJavaClass(
eclass);
// automatically add the proxy annotation
if (optionSetProxy && hbClass.getHbProxy() == null) {
if (concreteClass != null) {
final Proxy proxy = HbannotationFactory.eINSTANCE.createProxy();
proxy.setLazy(true);
// interface class is set below.
((HbAnnotatedEClass) aClass).setHbProxy(proxy);
log.debug("Set proxy to true (" + proxy.getProxyClass()
+ ") for eclass " + aClass.getModelEClass().getName());
}
}
if (hbClass.getHbProxy() != null && concreteClass != null) {
// todo add check that there is an impl class
aClass.setOnlyMapAsEntity(false);
// set interfacename if not set
final Proxy proxy = hbClass.getHbProxy();
final Class<?> interfaceClass = EModelResolver.instance()
.getJavaInterfaceClass(eclass);
if (interfaceClass != null) {
proxy.setProxyClass(interfaceClass.getName());
} else { // set the class itself
proxy.setProxyClass(concreteClass.getName());
}
}
// now handle the case of defaultCacheStrategy which is different than
// none
boolean hasCache = ((HbAnnotatedEClass) aClass).getHbCache() != null;
if (aClass.getPaSuperEntity() != null && hasCache) {
log
.warn("EClass: "
+ aClass.getModelEClass().getName()
+ " has a cache strategy defined while it has a superclass, this strategy is ignored.");
return res;
}
if (!hasCache
&& defaultCacheStrategy
.compareToIgnoreCase(CacheConcurrencyStrategy.NONE
.getName()) != 0) {
final CacheConcurrencyStrategy ccs = CacheConcurrencyStrategy
.getByName(defaultCacheStrategy);
if (ccs == null) {
throw new StoreMappingException(
"The default cache strategy: "
+ defaultCacheStrategy
+ " is not one of the allowed values (uppercase) "
+ "as defined in the JPA Hibernate Annotation Extensions.");
}
log.debug("Setting cache strategy " + defaultCacheStrategy + " on "
+ aClass.getModelEClass().getName());
final Cache cache = HbannotationFactory.eINSTANCE.createCache();
cache.setUsage(ccs);
((HbAnnotatedEClass) aClass).setHbCache(cache);
}
return res;
}
@Override
protected boolean addDiscriminator(PAnnotatedEClass aClass) {
final HbAnnotatedEClass hbClass = (HbAnnotatedEClass) aClass;
return hbClass.getDiscriminatorFormula() == null
&& (hbClass.getImmutable() == null || getPersistenceOptions()
.isDiscriminatorVersionOnImmutableEClass());
}
/*
* (non-Javadoc)
*
* @seeorg.eclipse.emf.teneo.annotations.mapper.AbstractAnnotator#
* setPersistenceOptions(org.eclipse.emf.teneo.PersistenceOptions)
*/
@Override
public void setPersistenceOptions(PersistenceOptions persistenceOptions) {
super.setPersistenceOptions(persistenceOptions);
defaultCacheStrategy = persistenceOptions.getDefaultCacheStrategy();
optionSetProxy = persistenceOptions.isSetProxy();
}
/** Set the super entity */
@Override
protected void setSuperEntity(PAnnotatedEClass aClass) {
assert (aClass.getPaSuperEntity() == null);
// let the superclass do it
if (aClass.getEntity() != null
&& aClass.getEntity().getExtends() != null) {
super.setSuperEntity(aClass);
return;
}
final EClass eclass = aClass.getModelEClass();
if (eclass.getESuperTypes().size() == 0) {
aClass.setPaSuperEntity(null);
return;
}
PAnnotatedEClass superAClass = getPaSuperEntity(aClass, false);
if (superAClass == null) {
superAClass = getPaSuperEntity(aClass, true);
}
aClass.setPaSuperEntity(superAClass);
}
/** Compute the annotated superclass, ignore interfaces if parameterized */
private PAnnotatedEClass getPaSuperEntity(PAnnotatedEClass aClass,
boolean allowInterfaces) {
final PAnnotatedModel model = aClass.getPaModel();
for (EClass superEClass : aClass.getModelEClass().getESuperTypes()) {
final PAnnotatedEClass x = model.getPAnnotated(superEClass);
if (x.getEntity() != null && x.getMappedSuperclass() == null
&& (allowInterfaces || !x.getModelEClass().isInterface())) {
return x;
}
}
return null;
}
/**
* Map Interface EClasses, default false, overridden by hibernate to return
* true
*/
@Override
protected boolean mapInterfaceEClass() {
return true;
}
/** Map a mapped superclass, this differs for jpox and hibernate */
@Override
protected boolean mapMappedSuperEClass() {
return true;
}
}