diff options
Diffstat (limited to 'hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/identifier/IdentifierUtil.java')
-rwxr-xr-x | hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/identifier/IdentifierUtil.java | 179 |
1 files changed, 179 insertions, 0 deletions
diff --git a/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/identifier/IdentifierUtil.java b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/identifier/IdentifierUtil.java new file mode 100755 index 000000000..ab1c4fdc7 --- /dev/null +++ b/hibernate/org.eclipse.emf.teneo.hibernate/src/org/eclipse/emf/teneo/hibernate/mapping/identifier/IdentifierUtil.java @@ -0,0 +1,179 @@ +/** + * <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: IdentifierUtil.java,v 1.9 2010/11/12 09:33:33 mtaal Exp $ + */ + +package org.eclipse.emf.teneo.hibernate.mapping.identifier; + +import java.io.Serializable; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.Hashtable; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.teneo.classloader.ClassLoaderResolver; +import org.eclipse.emf.teneo.classloader.StoreClassLoadException; +import org.eclipse.emf.teneo.hibernate.HbDataStore; +import org.eclipse.emf.teneo.hibernate.HbMapperException; +import org.hibernate.EntityMode; +import org.hibernate.engine.ForeignKeys; +import org.hibernate.engine.SessionImplementor; +import org.hibernate.impl.SessionFactoryImpl; +import org.hibernate.impl.SessionImpl; +import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.type.AbstractStandardBasicType; +import org.hibernate.type.Type; + +/** + * Different identifier related utilities. The current Elver store + * representation does not use the EMF id concept but uses the underlying + * hibernate identifier. This allows more flexibility than the EMF identifier. + * + * @author <a href="mailto:mtaal@elver.org">Martin Taal</a> + * @version $Revision: 1.9 $ + */ + +public class IdentifierUtil { + /** The logger */ + // private static Log log = LogFactory.getLog(IdentifierUtil.class); + /** Separator used in encoding the class name and value */ + private static final String ENCODING_SEPARATOR = ";"; + + /** HashTable with identifier types hashed by entityname */ + private static final Hashtable<String, Type> identifierTypeCache = new Hashtable<String, Type>(); + + /** HashTable with cached constructors */ + private static final Hashtable<String, Constructor<?>> constructorCache = new Hashtable<String, Constructor<?>>(); + + /** + * Returns the identifiertype on the basis of the class of the passed object + */ + public static Type getIdentifierType(String className, + SessionImplementor session) { + Type type = identifierTypeCache.get(className); + if (type != null) { + return type; + } + + final Type identifierType = ((SessionImpl) session).getFactory() + .getClassMetadata(className).getIdentifierType(); + identifierTypeCache.put(className, identifierType); + return identifierType; + } + + /** Converts an id to a string representation */ + public static String idToString(Object object, SessionImplementor session) { + + return createIDString( + getIdentifierType(object.getClass().getName(), session), + getID(object, session)); + } + + /** String to id */ + public static Serializable stringToId(String className, + SessionImplementor Session, String idStr) { + return extractID(getIdentifierType(className, Session), idStr); + } + + /** Creates the serializable id object from a string */ + private static Serializable extractID(Type type, String idString) { + // first handle the most common case + if (type instanceof AbstractStandardBasicType) { + final AbstractStandardBasicType<?> ntype = (AbstractStandardBasicType<?>) type; + return (Serializable) ntype.fromStringValue(idString); + } + + // for all other cases the classname of the type is encoded into the + // field + final String className = idString.substring(0, + idString.indexOf(ENCODING_SEPARATOR)); + final String strValue = idString.substring(1 + idString + .indexOf(ENCODING_SEPARATOR)); + + Constructor<?> constructor = constructorCache.get(className); + if (constructor == null) { + try { + final Class<?> clazz = ClassLoaderResolver + .classForName(className); + constructor = clazz + .getConstructor(new Class[] { String.class }); + } catch (StoreClassLoadException e) { + throw new HbMapperException("Class " + className + " not found"); + } catch (NoSuchMethodException e) { + throw new HbMapperException( + "Class " + + className + + " does not have a constructor with a String parameter!"); + } + } + if (constructor == null) { + throw new HbMapperException("Class " + className + + " does not have a constructor with a String parameter!"); + } + + try { + return (Serializable) constructor + .newInstance(new Object[] { strValue }); + } catch (InvocationTargetException e) { + throw new HbMapperException("Can not instantiate: " + className + + " using value " + strValue); + } catch (InstantiationException e) { + throw new HbMapperException("Can not instantiate: " + className + + " using value " + strValue); + } catch (IllegalAccessException e) { + throw new HbMapperException("Can not instantiate: " + className + + " using value " + strValue); + } + } + + /** Returns the id of the passed object */ + @SuppressWarnings("deprecation") + public static Serializable getID(EObject eobj, HbDataStore hd) { + final String entityName = hd.getEntityNameStrategy().toEntityName( + eobj.eClass()); + final EntityPersister entityPersister = ((SessionFactoryImpl) hd + .getSessionFactory()).getEntityPersister(entityName); + return entityPersister.getIdentifier(eobj, EntityMode.MAP); + } + + /** Returns the id of the passed object */ + public static Serializable getID(Object object, SessionImplementor session) { + Serializable id = session.getContextEntityIdentifier(object); + if (id != null) { + return id; + } + + // now with entity name + final String entityName = session.bestGuessEntityName(object); + id = ForeignKeys.getEntityIdentifierIfNotUnsaved(entityName, object, + session); + if (id != null) { + return id; + } + // now the slow way + return (Serializable) IdentifierCacheHandler.getInstance() + .getID(object); + } + + /** Creates an id string from a serializable object */ + private static String createIDString(Type type, Serializable id) { + if (type instanceof AbstractStandardBasicType) { + @SuppressWarnings("unchecked") + final AbstractStandardBasicType<Object> ntype = (AbstractStandardBasicType<Object>) type; + return ntype.toString(id); + } + + return id.getClass().getName() + ENCODING_SEPARATOR + id.toString(); + } +}
\ No newline at end of file |