/** * <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: HbUtil.java,v 1.24 2009/03/15 14:49:46 mtaal Exp $ */ package org.eclipse.emf.teneo.hibernate; import java.util.Properties; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.eclipse.emf.common.notify.Adapter; import org.eclipse.emf.ecore.EAttribute; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EPackage; import org.eclipse.emf.ecore.EReference; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.ecore.util.FeatureMapUtil; import org.eclipse.emf.teneo.Constants; import org.eclipse.emf.teneo.hibernate.mapper.HbMapperConstants; import org.eclipse.emf.teneo.hibernate.mapping.HibernatePersistentStoreAdapter; import org.eclipse.emf.teneo.hibernate.mapping.econtainer.NewEContainerFeatureIDPropertyHandler; import org.eclipse.emf.teneo.hibernate.mapping.identifier.IdentifierCacheHandler; import org.eclipse.emf.teneo.hibernate.mapping.identifier.IdentifierPropertyHandler; import org.eclipse.emf.teneo.type.PersistentStoreAdapter; import org.eclipse.emf.teneo.util.StoreUtil; import org.hibernate.cfg.Environment; import org.hibernate.mapping.Collection; import org.hibernate.mapping.MetaAttribute; import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.Property; import org.hibernate.property.EmbeddedPropertyAccessor; import org.hibernate.property.PropertyAccessor; import org.hibernate.proxy.HibernateProxy; import org.hibernate.type.IdentifierType; import org.hibernate.type.PrimitiveType; import org.hibernate.type.StringType; import org.hibernate.type.Type; /** * Contains some utility methods. * * @author <a href="mailto:mtaal@elver.org">Martin Taal</a> * @version $Revision: 1.24 $ */ public class HbUtil { /** The logger */ private static Log log = LogFactory.getLog(HbUtil.class); /** Encode the id of an eobject */ public static String idToString(EObject eobj, HbDataStore hd) { final PersistentClass pc = hd.getPersistentClass(hd .getEntityNameStrategy().toEntityName(eobj.eClass())); if (pc == null) { // can happen with map entries return null; } Object id; if (eobj instanceof HibernateProxy) { id = ((HibernateProxy) eobj).getHibernateLazyInitializer() .getIdentifier(); } else { id = pc.getIdentifierProperty().getGetter(eobj.getClass()) .get(eobj); } if (id == null) { id = IdentifierCacheHandler.getInstance().getID(eobj); if (id == null) { return null; } } final Type t = pc.getIdentifierProperty().getType(); if (t instanceof PrimitiveType) { return ((PrimitiveType) t).toString(id); } else if (t instanceof StringType) { return (String) id; } return null; } /** Encode the id of an eobject */ public static Object stringToId(EClass eclass, HbDataStore hd, String id) { try { final PersistentClass pc = hd.getPersistentClass(hd .getEntityNameStrategy().toEntityName(eclass)); final Type t = pc.getIdentifierProperty().getType(); if (t instanceof IdentifierType) { return ((IdentifierType) t).stringToObject(id); } else if (t instanceof StringType) { return id; } return null; } catch (Exception e) { throw new HbStoreException("Exception while converting id: " + id + " of eclass " + eclass.getName()); } } /** Returns the correct accessor on the basis of the type of property */ public static PropertyAccessor getPropertyAccessor(Property mappedProperty, HbDataStore ds, String entityName) { if (mappedProperty.getMetaAttribute(HbMapperConstants.ID_META) != null) { // synthetic // ID return new IdentifierPropertyHandler(); } else if (mappedProperty .getMetaAttribute(HbMapperConstants.VERSION_META) != null) { return ds.getHbContext().createVersionAccessor(); } else if (mappedProperty.getName().compareToIgnoreCase( "_identifierMapper") == 0) { // name // is // used // by // hb return new EmbeddedPropertyAccessor(); // new // DummyPropertyHandler(); } else if (mappedProperty.getName().compareToIgnoreCase( HbConstants.PROPERTY_ECONTAINER) == 0) { return ds.getHbContext().createEContainerAccessor(); } else if (mappedProperty.getName().compareToIgnoreCase( HbConstants.PROPERTY_ECONTAINER_FEATURE_NAME) == 0) { return ds.getExtensionManager().getExtension( NewEContainerFeatureIDPropertyHandler.class); } else if (mappedProperty.getName().compareToIgnoreCase( HbConstants.PROPERTY_ECONTAINER_FEATURE_ID) == 0) { return ds.getHbContext().createEContainerFeatureIDAccessor(); } final EClass eClass = ds.getEntityNameStrategy().toEClass(entityName); final EStructuralFeature efeature = StoreUtil.getEStructuralFeature( eClass, mappedProperty.getName()); if (efeature == null) { throw new HbMapperException( "Feature not found for eclass/entity/property " + eClass.getName() + "/" + entityName + "/" + mappedProperty.getName()); } log.debug("Creating property accessor for " + mappedProperty.getName() + "/" + entityName + "/" + efeature.getName()); // check extra lazy final boolean extraLazy = mappedProperty.getValue() instanceof Collection && ((Collection) mappedProperty.getValue()).isExtraLazy(); if (FeatureMapUtil.isFeatureMap(efeature)) { return ds.getHbContext().createFeatureMapPropertyAccessor(efeature); } else if (efeature instanceof EReference) { final EReference eref = (EReference) efeature; if (eref.isMany()) { return ds.getHbContext().createEListAccessor(efeature, extraLazy, ds.getPersistenceOptions().isMapEMapAsTrueMap()); } else { return ds.getHbContext().createEReferenceAccessor(eref); } } else { final EAttribute eattr = (EAttribute) efeature; if (eattr.isMany()) { return ds.getHbContext().createEListAccessor(efeature, extraLazy, ds.getPersistenceOptions().isMapEMapAsTrueMap()); } else { // note also array types are going here! return ds.getHbContext().createEAttributeAccessor(eattr); } } } /** Returns the meta class uri, if not found then null is returned */ public static String getEClassNameFromFeatureMapMeta(PersistentClass pc) { MetaAttribute ma = pc .getMetaAttribute(HbMapperConstants.FEATUREMAP_META); if (ma == null) { return null; } return ma.getValue(); } /** * Returns the structural feature, handles the case of structural features * which are part of a feature map entry. public static EStructuralFeature * getFeature(PersistentClass pc, String propName, EPackage[] epacks) { * final MetaAttribute ma = pc.getMetaAttribute("eclass"); // TODO: * externalize final String eclassName; if (ma != null) { eclassName = * ma.getValue(); } else { eclassName = pc.getEntityName(); } return * StoreUtil.getEStructuralFeature(eclassName, propName, epacks); } */ /** * Creates and registers an emf data store using a set of generic store * properties */ public static HbDataStore getCreateDataStore(Properties props) { final String name = props.getProperty(Constants.PROP_NAME); HbDataStore eds = HbHelper.INSTANCE.getDataStore(name); if (eds != null) { return eds; } final Properties hbProps = new Properties(); hbProps.putAll(props); hbProps.put(Environment.USER, doTrim(props .getProperty(Constants.PROP_DB_USER))); hbProps.put(Environment.PASS, doTrim(props .getProperty(Constants.PROP_DB_PWD))); hbProps.put(Environment.DRIVER, doTrim(props .getProperty(Constants.PROP_DB_DRIVER))); hbProps.put(Environment.URL, doTrim(props .getProperty(Constants.PROP_DB_URL))); hbProps.put(Environment.DIALECT, doTrim(props .getProperty(Constants.PROP_DB_DIALECT))); EPackage[] epacks = StoreUtil.getEPackages(doTrim(props .getProperty(Constants.PROP_EPACKAGE_NSURI))); // create a EMF Data Store, this is retrieved later again eds = HbHelper.INSTANCE.createRegisterDataStore(name); eds.setProperties(hbProps); eds.setEPackages(epacks); eds.initialize(); return eds; } /** Convenience method */ private static String doTrim(String totrim) { if (totrim == null) { return null; } return totrim.trim(); } /** * Checks if an object has a HibernatePersistentStoreAdapter and if it * doesn't creates one and returns it. */ public static PersistentStoreAdapter getPersistentStoreAdapter( EObject eObject) { for (Adapter adapter : eObject.eAdapters()) { if (PersistentStoreAdapter.class.isAssignableFrom(adapter .getClass())) { return (PersistentStoreAdapter) adapter; } } final PersistentStoreAdapter adapter = new HibernatePersistentStoreAdapter(); eObject.eAdapters().add(adapter); return adapter; } }