/* * Copyright (c) 1998-2011 Caucho Technology -- all rights reserved * * This file is part of Resin(R) Open Source * * Each copy or derived work must preserve the copyright notice and this * notice unmodified. * * Resin Open Source is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Resin Open Source is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty * of NON-INFRINGEMENT. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with Resin Open Source; if not, write to the * * Free Software Foundation, Inc. * 59 Temple Place, Suite 330 * Boston, MA 02111-1307 USA * * @author Rodrigo Westrupp */ package com.caucho.amber.cfg; import com.caucho.amber.entity.Listener; import com.caucho.amber.field.*; import com.caucho.amber.idgen.IdGenerator; import com.caucho.amber.manager.AmberPersistenceUnit; import com.caucho.amber.table.AmberColumn; import com.caucho.amber.table.ForeignColumn; import com.caucho.amber.table.LinkColumns; import com.caucho.amber.table.AmberTable; import com.caucho.amber.type.*; import com.caucho.bytecode.*; import com.caucho.config.ConfigException; import com.caucho.jdbc.JdbcMetaData; import com.caucho.util.L10N; import java.lang.annotation.Annotation; import java.lang.reflect.AccessibleObject; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.Type; import javax.persistence.*; import javax.persistence.EmbeddedId; import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; import java.util.logging.Level; import java.util.logging.Logger; /** * Base concrete introspector for orm.xml and annotations. */ public class BaseConfigIntrospector extends AbstractConfigIntrospector { private static final Logger log = Logger.getLogger(BaseConfigIntrospector.class.getName()); private static final L10N L = new L10N(BaseConfigIntrospector.class); private static final Class []_annTypes = new Class[] { Basic.class, javax.persistence.Column.class, javax.persistence.Id.class, ElementCollection.class, EmbeddedId.class, ManyToOne.class, OneToMany.class, OneToOne.class, ManyToMany.class, Version.class, Transient.class }; final AmberConfigManager _configManager; final AmberPersistenceUnit _persistenceUnit; ArrayList<Completion> _linkCompletions = new ArrayList<Completion>(); ArrayList<Completion> _depCompletions = new ArrayList<Completion>(); HashMap<String, EmbeddableConfig> _embeddableConfigMap = new HashMap<String, EmbeddableConfig>(); ArrayList<EntityMappingsConfig> _entityMappingsList; // HashMap<String, EntityConfig> _entityConfigMap // = new HashMap<String, EntityConfig>(); // // HashMap<String, MappedSuperclassConfig> _mappedSuperclassConfigMap // = new HashMap<String, MappedSuperclassConfig>(); /** * Creates the introspector. */ public BaseConfigIntrospector(AmberConfigManager manager) { _configManager = manager; _persistenceUnit = manager.getPersistenceUnit(); } /** * Sets the entity mappings list. */ public void setEntityMappingsList(ArrayList<EntityMappingsConfig> entityMappingsList) { _entityMappingsList = entityMappingsList; } /** * Returns the entity config for a class name. */ public EntityConfig getEntityConfig(String className) { // jpa/0r41 if (_entityMappingsList == null) return null; // jpa/0s2l: mapping-file. HashMap<String, EntityConfig> entityMap; EntityConfig entityConfig; for (EntityMappingsConfig entityMappings : _entityMappingsList) { entityMap = entityMappings.getEntityMap(); if (entityMap != null) { entityConfig = entityMap.get(className); if (entityConfig != null) return entityConfig; } } return null; } /** * Returns the mapped superclass config for a class name. */ public MappedSuperclassConfig getMappedSuperclassConfig(String className) { if (_entityMappingsList == null) return null; HashMap<String, MappedSuperclassConfig> superclassMap; MappedSuperclassConfig superclassConfig; for (EntityMappingsConfig entityMappings : _entityMappingsList) { superclassMap = entityMappings.getMappedSuperclassMap(); if (superclassMap != null) { superclassConfig = superclassMap.get(className); if (superclassConfig != null) return superclassConfig; } } return null; } /** * Initializes the persistence unit meta data: * default listeners and so on. */ public void initMetaData(ArrayList<EntityMappingsConfig> entityMappingsList, AmberPersistenceUnit persistenceUnit) throws ConfigException { PersistenceUnitMetaDataConfig metaData = null; for (EntityMappingsConfig entityMappings : entityMappingsList) { metaData = entityMappings.getPersistenceUnitMetaData(); // It is undefined if this element occurs in multiple mapping // files within the same persistence unit. if (metaData != null) break; } if (metaData == null) return; PersistenceUnitDefaultsConfig defaults; defaults = metaData.getPersistenceUnitDefaults(); if (defaults == null) return; EntityListenersConfig entityListeners; entityListeners = defaults.getEntityListeners(); if (entityListeners == null) return; ArrayList<EntityListenerConfig> listeners; listeners = entityListeners.getEntityListeners(); for (EntityListenerConfig listener : listeners) introspectDefaultListener(listener, persistenceUnit); } public void introspectDefaultListener(EntityListenerConfig listener, AmberPersistenceUnit persistenceUnit) throws ConfigException { String className = listener.getClassName(); Class type = persistenceUnit.loadTempClass(className); if (type == null) throw new ConfigException(L.l("'{0}' is an unknown type for <entity-listener> in orm.xml", className)); ListenerType listenerType = persistenceUnit.addDefaultListener(type); introspectListener(type, listenerType); } public void introspectEntityListeners(Class type, EntityType entityType, AmberPersistenceUnit persistenceUnit) throws ConfigException { getInternalEntityListenersConfig(type, _annotationCfg); EntityListeners entityListenersAnn = (EntityListeners) _annotationCfg.getAnnotation(); EntityListenersConfig entityListenersCfg = _annotationCfg.getEntityListenersConfig(); Class listeners[] = null; /* // XML mapping takes higher priority than annotations. if (entityListenersCfg != null) listeners = entityListenersCfg.getEntityListeners().toArray(); else if (entityListenersAnn != null) listeners = entityListenersAnn.value(); else return; */ String entityTypeName = entityType.getBeanClass().getName(); for (int i = 0; listeners != null && i < listeners.length; i++) { Class cl = null; // Introspects annotation or xml. if (listeners[i] instanceof Class) cl = (Class) listeners[i]; else { /* EntityListenerConfig listenerConfig = (EntityListenerConfig) listeners[i]; String className = listenerConfig.getClassName(); cl = persistenceUnit.loadTempClass(className); if (cl == null) throw new ConfigException(L.l("'{0}' is an unknown type for <entity-listener> in orm.xml", className)); */ } if (persistenceUnit.getDefaultListener(cl.getName()) != null) continue; introspectEntityListener(cl, persistenceUnit, entityType, entityTypeName); } } public void introspectEntityListener(Class type, AmberPersistenceUnit persistenceUnit, EntityType sourceType, String sourceClassName) throws ConfigException { if (type == null) { throw new ConfigException(L.l("'{0}' is an unknown type for @EntityListeners annotated at class '{1}'", type.getName(), sourceClassName)); } Class parentClass = type.getSuperclass(); if (parentClass == null) { // java.lang.Object return; } /* else { // XXX: entity listener super-classes in a hierarchy might // not be annotated as entity listeners but they might have // @PreXxx or @PostXxx annotated methods. On the other hand, // needs to filter regular classes out. introspectEntityListener(parentClass, persistenceUnit, sourceType, sourceClassName); } */ // jpa/0r42 ListenerType listenerType = persistenceUnit.getEntityListener(type.getName()); ListenerType newListenerType = persistenceUnit.addEntityListener(sourceClassName, type); if (listenerType == null) { listenerType = newListenerType; introspectListener(type, listenerType); } sourceType.addListener(listenerType); } public void introspectListener(Class type, ListenerType listenerType) throws ConfigException { listenerType.setInstanceClassName(listenerType.getName() + "__ResinExt"); for (Method method : type.getDeclaredMethods()) { introspectCallbacks(listenerType, method); } } /** * Introspects the callbacks. */ public void introspectCallbacks(Class type, EntityType entityType) throws ConfigException { getInternalExcludeDefaultListenersConfig(type, _annotationCfg); if (! _annotationCfg.isNull()) entityType.setExcludeDefaultListeners(true); getInternalExcludeSuperclassListenersConfig(type, _annotationCfg); if (! _annotationCfg.isNull()) entityType.setExcludeSuperclassListeners(true); for (Method method : type.getDeclaredMethods()) { introspectCallbacks(entityType, method); } } /** * Introspects the callbacks. */ public void introspectCallbacks(AbstractEnhancedType type, Method method) throws ConfigException { Class []param = method.getParameterTypes(); String methodName = method.getName(); Class jClass = type.getBeanClass(); boolean isListener = type instanceof ListenerType; int n = ListenerType.CALLBACK_CLASS.length; for (int i = 1; i < n; i++) { getInternalCallbackConfig(i, jClass, method, methodName, _annotationCfg); if (! _annotationCfg.isNull()) { validateCallback(ListenerType.CALLBACK_CLASS[i].getName(), method, isListener); type.addCallback(i, method); } } } /** * Introspects named queries. */ void introspectNamedQueries(Class type, String typeName) { // jpa/0y0- getInternalNamedQueryConfig(type, _annotationCfg); NamedQuery namedQueryAnn = (NamedQuery) _annotationCfg.getAnnotation(); NamedQueryConfig namedQueryConfig = _annotationCfg.getNamedQueryConfig(); // getInternalNamedQueriesConfig(type); NamedQueries namedQueriesAnn = (NamedQueries) type.getAnnotation(NamedQueries.class); // NamedQueriesConfig namedQueriesConfig = _annotationCfg.getNamedQueriesConfig(); if ((namedQueryAnn == null) && (namedQueriesAnn == null)) return; NamedQuery namedQueryArray[]; if ((namedQueryAnn != null) && (namedQueriesAnn != null)) { throw new ConfigException(L.l("{0} may not have both @NamedQuery and @NamedQueries", typeName)); } else if (namedQueriesAnn != null) { namedQueryArray = namedQueriesAnn.value(); } else { namedQueryArray = new NamedQuery[] { namedQueryAnn }; } for (int i=0; i < namedQueryArray.length; i++) { namedQueryAnn = namedQueryArray[i]; _persistenceUnit.addNamedQuery(namedQueryAnn.name(), namedQueryAnn.query()); } } /** * Introspects named native queries. */ void introspectNamedNativeQueries(Class type, String typeName) { // jpa/0y2- getInternalNamedNativeQueryConfig(type, _annotationCfg); NamedNativeQuery namedNativeQueryAnn = (NamedNativeQuery) _annotationCfg.getAnnotation(); NamedNativeQueryConfig namedNativeQueryConfig = _annotationCfg.getNamedNativeQueryConfig(); NamedNativeQueries namedNativeQueriesAnn = (NamedNativeQueries) type.getAnnotation(NamedNativeQueries.class); if ((namedNativeQueryAnn == null) && (namedNativeQueriesAnn == null)) return; NamedNativeQuery namedNativeQueryArray[]; if ((namedNativeQueryAnn != null) && (namedNativeQueriesAnn != null)) { throw new ConfigException(L.l("{0} may not have both @NamedNativeQuery and @NamedNativeQueries", typeName)); } else if (namedNativeQueriesAnn != null) { namedNativeQueryArray = namedNativeQueriesAnn.value(); } else { namedNativeQueryArray = new NamedNativeQuery[] { namedNativeQueryAnn }; } for (int i=0; i < namedNativeQueryArray.length; i++) { namedNativeQueryAnn = namedNativeQueryArray[i]; NamedNativeQueryConfig nativeQueryConfig = new NamedNativeQueryConfig(); nativeQueryConfig.setQuery(namedNativeQueryAnn.query()); nativeQueryConfig.setResultClass(namedNativeQueryAnn.resultClass()); nativeQueryConfig.setResultSetMapping(namedNativeQueryAnn.resultSetMapping()); _persistenceUnit.addNamedNativeQuery(namedNativeQueryAnn.name(), nativeQueryConfig); } } /** * Introspects sql result set mappings. */ void introspectSqlResultSetMappings(Class type, EntityType entityType, String typeName) { // jpa/0y1- getInternalSqlResultSetMappingConfig(type, _annotationCfg); SqlResultSetMapping sqlResultSetMappingAnn = (SqlResultSetMapping) _annotationCfg.getAnnotation(); SqlResultSetMappingConfig sqlResultSetMappingConfig = _annotationCfg.getSqlResultSetMappingConfig(); SqlResultSetMappings sqlResultSetMappingsAnn = (SqlResultSetMappings) type.getAnnotation(SqlResultSetMappings.class); if ((sqlResultSetMappingAnn == null) && (sqlResultSetMappingsAnn == null)) return; SqlResultSetMapping sqlResultSetMappingArray[]; if ((sqlResultSetMappingAnn != null) && (sqlResultSetMappingsAnn != null)) { throw new ConfigException(L.l("{0} may not have both @SqlResultSetMapping and @SqlResultSetMappings", typeName)); } else if (sqlResultSetMappingsAnn != null) { sqlResultSetMappingArray = sqlResultSetMappingsAnn.value(); } else { sqlResultSetMappingArray = new SqlResultSetMapping[] { sqlResultSetMappingAnn }; } if (sqlResultSetMappingConfig != null) { _persistenceUnit.addSqlResultSetMapping(sqlResultSetMappingConfig.getName(), sqlResultSetMappingConfig); return; } for (int i=0; i < sqlResultSetMappingArray.length; i++) { sqlResultSetMappingAnn = sqlResultSetMappingArray[i]; String name = sqlResultSetMappingAnn.name(); EntityResult entities[] = sqlResultSetMappingAnn.entities(); ColumnResult columns[] = sqlResultSetMappingAnn.columns(); SqlResultSetMappingCompletion completion = new SqlResultSetMappingCompletion(entityType, name, entities, columns); _depCompletions.add(completion); } } /** * Completion callback for sql result set mappings. */ void addSqlResultSetMapping(String resultSetName, EntityResult entities[], ColumnResult columns[]) throws ConfigException { // jpa/0y1- SqlResultSetMappingConfig sqlResultSetMapping = new SqlResultSetMappingConfig(); // Adds @EntityResult. for (int i=0; i < entities.length; i++) { EntityResult entityResult = entities[i]; String className = entityResult.entityClass().getName(); EntityType resultType = _persistenceUnit.getEntityType(className); if (resultType == null) throw new ConfigException(L.l("entityClass '{0}' is not an @Entity bean for @SqlResultSetMapping '{1}'. The entityClass of an @EntityResult must be an @Entity bean.", className, resultSetName)); EntityResultConfig entityResultConfig = new EntityResultConfig(); entityResultConfig.setEntityClass(className); // @FieldResult annotations. FieldResult fields[] = entityResult.fields(); for (int j=0; j < fields.length; j++) { FieldResult fieldResult = fields[j]; String fieldName = fieldResult.name(); AmberField field = resultType.getField(fieldName); if (field == null) throw new ConfigException(L.l("@FieldResult with field name '{0}' is not a field for @EntityResult bean '{1}' in @SqlResultSetMapping '{2}'", fieldName, className, resultSetName)); String columnName = fieldResult.column(); if (columnName == null || columnName.length() == 0) throw new ConfigException(L.l("@FieldResult must have a column name defined and it must not be empty for '{0}' in @EntityResult '{1}' @SqlResultSetMapping '{2}'", fieldName, className, resultSetName)); FieldResultConfig fieldResultConfig = new FieldResultConfig(); fieldResultConfig.setName(fieldName); fieldResultConfig.setColumn(columnName); entityResultConfig.addFieldResult(fieldResultConfig); } sqlResultSetMapping.addEntityResult(entityResultConfig); } // Adds @ColumnResult. for (int i=0; i < columns.length; i++) { ColumnResult columnResult = columns[i]; String columnName = columnResult.name(); if (columnName == null || columnName.length() == 0) throw new ConfigException(L.l("@ColumnResult must have a column name defined and it must not be empty in @SqlResultSetMapping '{0}'", resultSetName)); ColumnResultConfig columnResultConfig = new ColumnResultConfig(); columnResultConfig.setName(columnName); sqlResultSetMapping.addColumnResult(columnResultConfig); } // Adds a global sql result set mapping to the persistence unit. _persistenceUnit.addSqlResultSetMapping(resultSetName, sqlResultSetMapping); } /** * Completes all partial bean introspection. */ public void configureLinks() throws ConfigException { RuntimeException exn = null; while (_linkCompletions.size() > 0) { Completion completion = _linkCompletions.remove(0); try { completion.complete(); } catch (Exception e) { if (e instanceof ConfigException) { log.warning(e.getMessage()); log.log(Level.FINEST, e.toString(), e); } else log.log(Level.WARNING, e.toString(), e); completion.getRelatedType().setConfigException(e); if (exn == null) exn = ConfigException.create(e); } } if (exn != null) throw exn; } /** * Completes all partial bean introspection. */ public void configureDependencies() throws ConfigException { RuntimeException exn = null; while (_depCompletions.size() > 0) { Completion completion = _depCompletions.remove(0); try { completion.complete(); } catch (Exception e) { if (e instanceof ConfigException) { log.warning(e.getMessage()); log.log(Level.FINEST, e.toString(), e); } else log.log(Level.WARNING, e.toString(), e); completion.getRelatedType().setConfigException(e); if (exn == null) exn = ConfigException.create(e); } } if (exn != null) throw exn; } /** * Introspects the fields. */ void introspectIdMethod(AmberPersistenceUnit persistenceUnit, EntityType entityType, EntityType parentType, Class type, Class idClass, MappedSuperclassConfig config) throws ConfigException, SQLException { ArrayList<IdField> keys = new ArrayList<IdField>(); IdField idField = null; AttributesConfig attributesConfig = null; if (config != null) attributesConfig = config.getAttributes(); for (Method method : type.getDeclaredMethods()) { String methodName = method.getName(); Class []paramTypes = method.getParameterTypes(); if (method.getDeclaringClass().equals(Object.class)) continue; if (! methodName.startsWith("get") || paramTypes.length != 0) { continue; } String fieldName = toFieldName(methodName.substring(3)); if (containsFieldOrCompletion(parentType, fieldName)) continue; getInternalIdConfig(type, method, fieldName, _annotationCfg); Annotation id = _annotationCfg.getAnnotation(); IdConfig idConfig = _annotationCfg.getIdConfig(); if (! _annotationCfg.isNull()) { idField = introspectId(persistenceUnit, entityType, method, fieldName, method.getReturnType(), idConfig); if (idField != null) keys.add(idField); } else { getInternalEmbeddedIdConfig(type, method, fieldName, _annotationCfg); Annotation embeddedId = _annotationCfg.getAnnotation(); EmbeddedIdConfig embeddedIdConfig = _annotationCfg.getEmbeddedIdConfig(); if (! _annotationCfg.isNull()) { idField = introspectEmbeddedId(persistenceUnit, entityType, method, fieldName, method.getReturnType()); break; } else { continue; } } } if (keys.size() == 0) { if (idField != null) { // @EmbeddedId was used. com.caucho.amber.field.EmbeddedId id = new com.caucho.amber.field.EmbeddedId(entityType, (EmbeddedIdField) idField); entityType.setId(id); } } else if (keys.size() == 1) { entityType.setId(new com.caucho.amber.field.Id(entityType, keys)); } else if (idClass == null) { throw new ConfigException(L.l("{0} has multiple @Id methods, but no @IdClass. Compound primary keys require either an @IdClass or exactly one @EmbeddedId field or property.", entityType.getName())); } else { CompositeId id = new CompositeId(entityType, keys); id.setKeyClass(idClass); entityType.setId(id); } } /** * Introspects the fields. */ void introspectIdField(AmberPersistenceUnit persistenceUnit, EntityType entityType, EntityType parentType, Class type, Class idClass, MappedSuperclassConfig config) throws ConfigException, SQLException { ArrayList<IdField> keys = new ArrayList<IdField>(); AttributesConfig attributesConfig = null; if (config != null) attributesConfig = config.getAttributes(); for (Field field : type.getDeclaredFields()) { String fieldName = field.getName(); if (containsFieldOrCompletion(parentType, fieldName)) continue; getInternalIdConfig(type, field, fieldName, _annotationCfg); Annotation id = _annotationCfg.getAnnotation(); IdConfig idConfig = _annotationCfg.getIdConfig(); if (_annotationCfg.isNull()) { getInternalEmbeddedIdConfig(type, field, fieldName, _annotationCfg); Annotation embeddedId = _annotationCfg.getAnnotation(); EmbeddedIdConfig embeddedIdConfig = _annotationCfg.getEmbeddedIdConfig(); if (_annotationCfg.isNull()) continue; } IdField idField = introspectId(persistenceUnit, entityType, field, fieldName, field.getType(), idConfig); if (idField != null) keys.add(idField); } if (keys.size() == 0) { } else if (keys.size() == 1) entityType.setId(new com.caucho.amber.field.Id(entityType, keys)); else if (idClass == null) { throw new ConfigException(L.l("{0} has multiple @Id fields, but no @IdClass. Compound primary keys require an @IdClass.", entityType.getName())); } else { CompositeId id = new CompositeId(entityType, keys); id.setKeyClass(idClass); entityType.setId(id); _configManager.introspect(idClass); } } /** * Check if it's field */ boolean isField(Class type, AbstractEnhancedConfig typeConfig, boolean isEmbeddable) throws ConfigException { if (type == null) return false; if (typeConfig != null) { String access = typeConfig.getAccess(); if (access != null) return access.equals("FIELD"); Class parentClass = type.getSuperclass(); if (parentClass == null) return false; else { getInternalEntityConfig(parentClass, _annotationCfg); EntityConfig superEntityConfig = _annotationCfg.getEntityConfig(); if (superEntityConfig == null) return false; return isField(parentClass, superEntityConfig, false); } } for (Field field : type.getDeclaredFields()) { for (Class annType : _annTypes) { if (field.getAnnotation(annType) != null) { return true; } } } return isField(type.getSuperclass(), null, false); } private IdField introspectId(AmberPersistenceUnit persistenceUnit, EntityType entityType, AccessibleObject field, String fieldName, Class fieldType, IdConfig idConfig) throws ConfigException, SQLException { javax.persistence.Id id = field.getAnnotation(javax.persistence.Id.class); Column column = field.getAnnotation(javax.persistence.Column.class); ColumnConfig columnConfig = null; GeneratedValueConfig generatedValueConfig = null; if (idConfig != null) { columnConfig = idConfig.getColumn(); generatedValueConfig = idConfig.getGeneratedValue(); } GeneratedValue gen = field.getAnnotation(GeneratedValue.class); AmberType amberType = persistenceUnit.createType(fieldType); KeyPropertyField idField; AmberColumn keyColumn = null; keyColumn = createColumn(entityType, field, fieldName, column, amberType, columnConfig); if (entityType.getTable() != null) { idField = new KeyPropertyField(entityType, fieldName, keyColumn); } else { idField = new KeyPropertyField(entityType, fieldName, keyColumn); return idField; } if (gen == null) { } else { JdbcMetaData metaData = null; /* XXX: validation needs to occur later try { metaData = persistenceUnit.getMetaData(); } catch (ConfigException e) { throw e; } catch (Exception e) { throw new ConfigException(L.l("Unable to get meta data for database. Meta data is needed for generated values."), e); } */ if (GenerationType.IDENTITY.equals(gen.strategy())) { /* XXX: validation later if (! metaData.supportsIdentity()) throw new ConfigException(L.l("'{0}' does not support identity.", metaData.getDatabaseName())); */ keyColumn.setGeneratorType("identity"); idField.setGenerator("identity"); } else if (GenerationType.SEQUENCE.equals(gen.strategy())) { /* XXX: validation later if (! metaData.supportsSequences()) throw new ConfigException(L.l("'{0}' does not support sequence.", metaData.getDatabaseName())); */ addSequenceIdGenerator(persistenceUnit, idField, gen); } else if (GenerationType.TABLE.equals(gen.strategy())) { addTableIdGenerator(persistenceUnit, idField, id); } else if (GenerationType.AUTO.equals(gen.strategy())) { keyColumn.setGeneratorType("auto"); idField.setGenerator("auto"); /* XXX: validation later if (metaData.supportsIdentity()) { keyColumn.setGeneratorType("identity"); idField.setGenerator("identity"); } else if (metaData.supportsSequences()) { addSequenceIdGenerator(persistenceUnit, idField, gen); } else { addTableIdGenerator(persistenceUnit, idField, id); } */ } } return idField; } private IdField introspectEmbeddedId(AmberPersistenceUnit persistenceUnit, EntityType ownerType, AccessibleObject field, String fieldName, Class fieldType) throws ConfigException, SQLException { IdField idField; EmbeddableType embeddableType = (EmbeddableType) _configManager.introspect(fieldType); if (embeddableType == null) throw new IllegalStateException("" + fieldType + " is an unsupported embeddable type"); idField = new EmbeddedIdField(ownerType, embeddableType, fieldName); return idField; } void addSequenceIdGenerator(AmberPersistenceUnit persistenceUnit, KeyPropertyField idField, GeneratedValue genAnn) throws ConfigException { idField.setGenerator("sequence"); idField.getColumn().setGeneratorType("sequence"); String name = genAnn.generator(); if (name == null || "".equals(name)) name = idField.getEntitySourceType().getTable().getName() + "_cseq"; IdGenerator gen = persistenceUnit.createSequenceGenerator(name, 1); idField.getEntitySourceType().setGenerator(idField.getName(), gen); } void addTableIdGenerator(AmberPersistenceUnit persistenceUnit, KeyPropertyField idField, javax.persistence.Id idAnn) throws ConfigException { idField.setGenerator("table"); idField.getColumn().setGeneratorType("table"); String name = null;// XXX: idAnn.name(); if (name == null || "".equals(name)) name = "caucho"; IdGenerator gen = persistenceUnit.getTableGenerator(name); if (gen == null) { String genName = "GEN_TABLE"; GeneratorTableType genTable; genTable = persistenceUnit.createGeneratorTable(genName); gen = genTable.createGenerator(name); // jpa/0g60 genTable.init(); persistenceUnit.putTableGenerator(name, gen); } idField.getEntitySourceType().setGenerator(idField.getName(), gen); } /** * Links a secondary table. */ void linkSecondaryTable(AmberTable primaryTable, AmberTable secondaryTable, PrimaryKeyJoinColumn []joinColumnsAnn) throws ConfigException { ArrayList<ForeignColumn> linkColumns = new ArrayList<ForeignColumn>(); for (AmberColumn column : primaryTable.getIdColumns()) { ForeignColumn linkColumn; PrimaryKeyJoinColumn joinAnn = getJoinColumn(joinColumnsAnn, column.getName()); String name; if (joinAnn == null) name = column.getName(); else name = joinAnn.name(); linkColumn = secondaryTable.createForeignColumn(name, column); linkColumn.setPrimaryKey(true); secondaryTable.addIdColumn(linkColumn); linkColumns.add(linkColumn); } LinkColumns link = new LinkColumns(secondaryTable, primaryTable, linkColumns); link.setSourceCascadeDelete(true); secondaryTable.setDependentIdLink(link); } /** * Links a secondary table. */ void linkInheritanceTable(AmberTable primaryTable, AmberTable secondaryTable, PrimaryKeyJoinColumn joinAnn, PrimaryKeyJoinColumnConfig pkJoinColumnCfg) throws ConfigException { PrimaryKeyJoinColumn joinAnns[] = null; if (joinAnn != null) joinAnns = new PrimaryKeyJoinColumn[] { joinAnn }; linkInheritanceTable(primaryTable, secondaryTable, joinAnns, pkJoinColumnCfg); } /** * Links a secondary table. */ void linkInheritanceTable(AmberTable primaryTable, AmberTable secondaryTable, PrimaryKeyJoinColumn []joinColumnsAnn, PrimaryKeyJoinColumnConfig pkJoinColumnCfg) throws ConfigException { ArrayList<ForeignColumn> linkColumns = new ArrayList<ForeignColumn>(); for (AmberColumn column : primaryTable.getIdColumns()) { ForeignColumn linkColumn; String name; if (joinColumnsAnn == null) { if (pkJoinColumnCfg == null) name = column.getName(); else name = pkJoinColumnCfg.getName(); } else { PrimaryKeyJoinColumn join; join = getJoinColumn(joinColumnsAnn, column.getName()); if (join == null) name = column.getName(); else name = join.name(); } linkColumn = secondaryTable.createForeignColumn(name, column); linkColumn.setPrimaryKey(true); secondaryTable.addIdColumn(linkColumn); linkColumns.add(linkColumn); } LinkColumns link = new LinkColumns(secondaryTable, primaryTable, linkColumns); link.setSourceCascadeDelete(true); secondaryTable.setDependentIdLink(link); // jpa/0l48 // link = new LinkColumns(primaryTable, // secondaryTable, // linkColumns); // // link.setSourceCascadeDelete(true); // // primaryTable.setDependentIdLink(link); } /** * Introspects the methods. */ void introspectMethods(AmberPersistenceUnit persistenceUnit, BeanType entityType, BeanType parentType, Class type, AbstractEnhancedConfig typeConfig) throws ConfigException { for (Method method : type.getDeclaredMethods()) { String methodName = method.getName(); Class []paramTypes = method.getParameterTypes(); if (method.getDeclaringClass().equals(Object.class)) continue; // jpa/0r38 // Callbacks are introspected in the main introspect() block. // introspectCallbacks(entityType, method); String propName; if (paramTypes.length != 0) { validateNonGetter(method); continue; } else if (methodName.startsWith("get")) { propName = methodName.substring(3); } else if (methodName.startsWith("is") && (method.getReturnType().equals(boolean.class) || method.getReturnType().equals(Boolean.class))) { propName = methodName.substring(2); } else { validateNonGetter(method); continue; } getInternalVersionConfig(type, method, propName, _annotationCfg); Annotation versionAnn = _annotationCfg.getAnnotation(); VersionConfig versionConfig = _annotationCfg.getVersionConfig(); if (! _annotationCfg.isNull()) { validateNonGetter(method); } else { Method setter = null; try { setter = getMethod(type, "set" + propName, new Class[] { method.getReturnType() }); } catch (Exception e) { log.log(Level.FINEST, e.toString(), e); } if (Modifier.isPrivate(method.getModifiers()) || setter == null || Modifier.isPrivate(setter.getModifiers())) { Annotation ann = isAnnotatedMethod(method); if (ann == null) { if (setter != null) ann = isAnnotatedMethod(setter); } else if (ann instanceof Transient) continue; if (ann != null) { throw error(method, L.l("'{0}' is not a valid annotation for {1}. Only public persistent property getters with matching setters may have property annotations.", ann.getClass(), getFullName(method))); } continue; } // ejb/0g03 for private if (Modifier.isStatic(method.getModifiers())) { // || ! method.isPublic()) { validateNonGetter(method); continue; } } String fieldName = toFieldName(propName); if (containsFieldOrCompletion(parentType, fieldName)) continue; Class fieldType = method.getReturnType(); introspectField(persistenceUnit, entityType, method, fieldName, fieldType, typeConfig); } } private Method getMethod(Class cl, String name, Class []param) { if (cl == null) return null; loop: for (Method method : cl.getDeclaredMethods()) { if (! method.getName().equals(name)) continue; Class []types = method.getParameterTypes(); if (types.length != param.length) continue; for (int i = 0; i < types.length; i++) { if (! param[i].equals(types[i])) continue loop; } return method; } return getMethod(cl.getSuperclass(), name, param); } /** * Introspects the fields. */ void introspectFields(AmberPersistenceUnit persistenceUnit, BeanType entityType, BeanType parentType, Class type, AbstractEnhancedConfig typeConfig, boolean isEmbeddable) throws ConfigException { if (entityType.isEntity() && ((EntityType) entityType).getId() == null) throw new ConfigException(L.l("{0} has no key", entityType)); for (Field field : type.getDeclaredFields()) { String fieldName = field.getName(); if (containsFieldOrCompletion(parentType, fieldName)) { continue; } if (Modifier.isStatic(field.getModifiers()) || Modifier.isTransient(field.getModifiers())) continue; Class fieldType = field.getType(); introspectField(persistenceUnit, entityType, field, fieldName, fieldType, typeConfig); } } void introspectField(AmberPersistenceUnit persistenceUnit, BeanType sourceType, AccessibleObject field, String fieldName, Class fieldType, AbstractEnhancedConfig typeConfig) throws ConfigException { EmbeddableConfig embeddableConfig = null; MappedSuperclassConfig mappedSuperOrEntityConfig = null; if (typeConfig instanceof EmbeddableConfig) embeddableConfig = (EmbeddableConfig) typeConfig; else if (typeConfig instanceof MappedSuperclassConfig) mappedSuperOrEntityConfig = (MappedSuperclassConfig) typeConfig; // jpa/0r37: interface fields must not be considered. Class jClass; if (field instanceof Field) jClass = ((Field) field).getDeclaringClass(); else jClass = ((Method) field).getDeclaringClass(); if (jClass.isInterface()) return; // jpa/0r37: fields declared in non-entity superclasses // must not be considered. BeanType declaringType; declaringType = _persistenceUnit.getEntityType(jClass.getName()); if (declaringType == null) declaringType = _persistenceUnit.getEmbeddable(jClass.getName()); if (declaringType == null) declaringType = _persistenceUnit.getMappedSuperclass(jClass.getName()); if (declaringType == null) return; AttributesConfig attributesConfig = null; IdConfig idConfig = null; BasicConfig basicConfig = null; OneToOneConfig oneToOneConfig = null; OneToManyConfig oneToManyConfig = null; ManyToOneConfig manyToOneConfig = null; ManyToManyConfig manyToManyConfig = null; VersionConfig versionConfig = null; ElementCollectionConfig elementCollectionConfig = null; if (mappedSuperOrEntityConfig != null) { attributesConfig = mappedSuperOrEntityConfig.getAttributes(); if (attributesConfig != null) { idConfig = attributesConfig.getId(fieldName); basicConfig = attributesConfig.getBasic(fieldName); oneToOneConfig = attributesConfig.getOneToOne(fieldName); oneToManyConfig = attributesConfig.getOneToMany(fieldName); elementCollectionConfig = null; // attributesConfig.getOneToMany(fieldName); manyToOneConfig = attributesConfig.getManyToOne(fieldName); manyToManyConfig = attributesConfig.getManyToMany(fieldName); versionConfig = attributesConfig.getVersion(fieldName); } } if (idConfig != null || field.isAnnotationPresent(javax.persistence.Id.class)) { validateAnnotations(field, fieldName, "@Id", _idAnnotations); if (! _idTypes.contains(fieldType.getName())) { throw error(field, L.l("{0} is an invalid @Id type for {1}.", fieldType.getName(), fieldName)); } } else if (basicConfig != null || field.isAnnotationPresent(javax.persistence.Basic.class)) { validateAnnotations(field, fieldName, "@Basic", _basicAnnotations); BasicConfig basic = new BasicConfig(this, sourceType, field, fieldName, fieldType); basic.complete(); } else if ((versionConfig != null) || field.isAnnotationPresent(javax.persistence.Version.class)) { validateAnnotations(field, fieldName, "@Version", _versionAnnotations); addVersion((EntityType) sourceType, field, fieldName, fieldType, versionConfig); } else if (field.isAnnotationPresent(javax.persistence.ManyToOne.class)) { validateAnnotations(field, fieldName, "@ManyToOne", _manyToOneAnnotations); ManyToOne ann = field.getAnnotation(ManyToOne.class); Class targetEntity = null; if (ann != null) targetEntity = ann.targetEntity(); else { targetEntity = manyToOneConfig.getTargetEntity(); } if (targetEntity == null || targetEntity.getName().equals("void")) { targetEntity = fieldType; } getInternalEntityConfig(targetEntity, _annotationCfg); Annotation targetEntityAnn = _annotationCfg.getAnnotation(); EntityConfig targetEntityConfig = _annotationCfg.getEntityConfig(); if (_annotationCfg.isNull()) { throw error(field, L.l("'{0}' is an illegal targetEntity for {1}. @ManyToOne relations must target a valid @Entity.", targetEntity.getName(), fieldName)); } if (! fieldType.isAssignableFrom(targetEntity)) { throw error(field, L.l("'{0}' is an illegal targetEntity for {1}. @ManyToOne targetEntity must be assignable to the field type '{2}'.", targetEntity.getName(), fieldName, fieldType.getName())); } EntityType entityType = (EntityType) sourceType; entityType.setHasDependent(true); _linkCompletions.add(new ManyToOneConfig(this, entityType, field, fieldName, fieldType)); } else if (oneToManyConfig != null || field.isAnnotationPresent(javax.persistence.OneToMany.class)) { validateAnnotations(field, fieldName, "@OneToMany", _oneToManyAnnotations); if (field.isAnnotationPresent(javax.persistence.MapKey.class)) { if (!fieldType.getName().equals("java.util.Map")) { throw error(field, L.l("'{0}' is an illegal @OneToMany/@MapKey type for {1}. @MapKey must be a java.util.Map", fieldType.getName(), fieldName)); } } else if (! _oneToManyTypes.contains(fieldType.getName())) { throw error(field, L.l("'{0}' is an illegal @OneToMany type for {1}. @OneToMany must be a java.util.Collection, java.util.List or java.util.Map", fieldType.getName(), fieldName)); } EntityType entityType = (EntityType) sourceType; _depCompletions.add(new OneToManyConfig(this, entityType, field, fieldName, fieldType)); } else if ((oneToOneConfig != null) || field.isAnnotationPresent(javax.persistence.OneToOne.class)) { validateAnnotations(field, fieldName, "@OneToOne", _oneToOneAnnotations); EntityType entityType = (EntityType) sourceType; OneToOneConfig oneToOne = new OneToOneConfig(this, entityType, field, fieldName, fieldType); if (oneToOne.isOwningSide()) _linkCompletions.add(oneToOne); else { _depCompletions.add(0, oneToOne); entityType.setHasDependent(true); } } else if ((manyToManyConfig != null) || field.isAnnotationPresent(javax.persistence.ManyToMany.class)) { if (field.isAnnotationPresent(javax.persistence.MapKey.class)) { if (! fieldType.getName().equals("java.util.Map")) { throw error(field, L.l("'{0}' is an illegal @ManyToMany/@MapKey type for {1}. @MapKey must be a java.util.Map", fieldType.getName(), fieldName)); } } ManyToManyConfig manyToMany = new ManyToManyConfig(this, (EntityType) sourceType, field, fieldName, fieldType); if (manyToMany.isOwningSide()) _linkCompletions.add(manyToMany); else _depCompletions.add(manyToMany); } else if (elementCollectionConfig != null || field.isAnnotationPresent(javax.persistence.ElementCollection.class)) { validateAnnotations(field, fieldName, "@ElementCollection", _elementCollectionAnnotations); if (! _elementCollectionTypes.contains(fieldType.getName())) { throw error(field, L.l("'{0}' is an illegal @ElementCollection type for {1}. @ElementCollection must be a java.util.Collection, java.util.List or java.util.Map", fieldType.getName(), fieldName)); } EntityType entityType = (EntityType) sourceType; ElementCollectionConfig comp = new ElementCollectionConfig(entityType, field, fieldName, fieldType); _depCompletions.add(comp); } else if (field.isAnnotationPresent(javax.persistence.Embedded.class)) { validateAnnotations(field, fieldName, "@Embedded", _embeddedAnnotations); EntityType entityType = (EntityType) sourceType; entityType.setHasDependent(true); _depCompletions.add(new EmbeddedCompletion(entityType, field, fieldName, fieldType, false)); } else if (field.isAnnotationPresent(javax.persistence.EmbeddedId.class)) { validateAnnotations(field, fieldName, "@EmbeddedId", _embeddedIdAnnotations); _depCompletions.add(new EmbeddedCompletion((EntityType) sourceType, field, fieldName, fieldType, true)); } else if (field.isAnnotationPresent(javax.persistence.Transient.class)) { } else { BasicConfig basic = new BasicConfig(this, sourceType, field, fieldName, fieldType); basic.complete(); } } void addVersion(EntityType sourceType, AccessibleObject field, String fieldName, Class fieldType, VersionConfig versionConfig) throws ConfigException { AmberPersistenceUnit persistenceUnit = sourceType.getPersistenceUnit(); Column columnAnn = field.getAnnotation(Column.class); ColumnConfig columnConfig = null; if (versionConfig != null) columnConfig = versionConfig.getColumn(); if (! _versionTypes.contains(fieldType.getName())) { throw error(field, L.l("{0} is an invalid @Version type for {1}.", fieldType.getName(), fieldName)); } AmberType amberType = persistenceUnit.createType(fieldType); AmberColumn fieldColumn = createColumn(sourceType, field, fieldName, columnAnn, amberType, columnConfig); VersionField version = new VersionField(sourceType, fieldName); version.setColumn(fieldColumn); sourceType.setVersionField(version); } private AmberColumn createColumn(BeanType beanType, AccessibleObject field, String fieldName, Column columnAnn, AmberType amberType, ColumnConfig columnConfig) throws ConfigException { EntityType entityType = null; if (beanType instanceof EntityType) entityType = (EntityType) beanType; String name; if (columnAnn != null && ! columnAnn.name().equals("")) name = (String) columnAnn.name(); else if (columnConfig != null && ! columnConfig.getName().equals("")) name = columnConfig.getName(); else name = toSqlName(fieldName); AmberColumn column = null; if (entityType == null) { // embeddable column = new AmberColumn(null, name, amberType); } else if (columnAnn != null && ! columnAnn.table().equals("")) { String tableName = columnAnn.table(); AmberTable table; table = entityType.getSecondaryTable(tableName); if (table == null) throw error(field, L.l("{0} @Column(table='{1}') is an unknown secondary table.", fieldName, tableName)); column = table.createColumn(name, amberType); } else if (entityType.getTable() != null) column = entityType.getTable().createColumn(name, amberType); else { // jpa/0ge2: MappedSuperclassType column = new AmberColumn(null, name, amberType); } if (column != null && columnAnn != null) { // primaryKey = column.primaryKey(); column.setUnique(columnAnn.unique()); column.setNotNull(! columnAnn.nullable()); //insertable = column.insertable(); //updateable = column.updatable(); if (! "".equals(columnAnn.columnDefinition())) column.setSQLType(columnAnn.columnDefinition()); column.setLength(columnAnn.length()); int precision = columnAnn.precision(); if (precision < 0) { throw error(field, L.l("{0} @Column precision cannot be less than 0.", fieldName)); } int scale = columnAnn.scale(); if (scale < 0) { throw error(field, L.l("{0} @Column scale cannot be less than 0.", fieldName)); } // this test implicitly works for case where // precision is not set explicitly (ie: set to 0 by default) // and scale is set if (scale > precision) { throw error(field, L.l("{0} @Column scale cannot be greater than precision. Must set precision to a non-zero value before setting scale.", fieldName)); } if (precision > 0) { column.setPrecision(precision); column.setScale(scale); } } return column; } public static JoinColumn getJoinColumn(JoinColumns joinColumns, String keyName) { if (joinColumns == null) return null; return getJoinColumn(joinColumns.value(), keyName); } private AmberColumn findColumn(ArrayList<AmberColumn> columns, String ref) { if (((ref == null) || ref.equals("")) && columns.size() == 1) return columns.get(0); for (AmberColumn column : columns) { if (column.getName().equals(ref)) return column; } return null; } public static JoinColumn getJoinColumn(JoinColumn []columnsAnn, String keyName) { if (columnsAnn == null || columnsAnn.length == 0) return null; for (int i = 0; i < columnsAnn.length; i++) { String ref = columnsAnn[i].referencedColumnName(); if (ref.equals("") || ref.equals(keyName)) return columnsAnn[i]; } return null; } public static PrimaryKeyJoinColumn getJoinColumn(PrimaryKeyJoinColumn []columnsAnn, String keyName) { if (columnsAnn == null || columnsAnn.length == 0) return null; for (int i = 0; i < columnsAnn.length; i++) { String ref = columnsAnn[i].referencedColumnName(); if (ref.equals("") || ref.equals(keyName)) return columnsAnn[i]; } return null; } /** * completes for dependent */ class EmbeddedCompletion extends CompletionImpl { private AccessibleObject _field; private String _fieldName; private Class _fieldType; // The same completion is used for both: // @Embedded or @EmbeddedId private boolean _embeddedId; EmbeddedCompletion(EntityType type, AccessibleObject field, String fieldName, Class fieldType, boolean embeddedId) { super(BaseConfigIntrospector.this, type, fieldName); _field = field; _fieldName = fieldName; _fieldType = fieldType; _embeddedId = embeddedId; } @Override public void complete() throws ConfigException { getInternalAttributeOverrideConfig(_entityType.getBeanClass(), _annotationCfg); AttributeOverride attributeOverrideAnn = (AttributeOverride) _annotationCfg.getAnnotation(); AttributeOverrideConfig attributeOverrideConfig = _annotationCfg.getAttributeOverrideConfig(); boolean hasAttributeOverride = ! _annotationCfg.isNull(); AttributeOverrides attributeOverridesAnn = _field.getAnnotation(AttributeOverrides.class); boolean hasAttributeOverrides = (attributeOverridesAnn != null); if (hasAttributeOverride && hasAttributeOverrides) { throw error(_field, L.l("{0} may not have both @AttributeOverride and @AttributeOverrides", _fieldName)); } AttributeOverride attOverridesAnn[] = null; if (attributeOverrideAnn != null) { attOverridesAnn = new AttributeOverride[] { attributeOverrideAnn }; } else if (attributeOverridesAnn != null) { attOverridesAnn = attributeOverridesAnn.value(); } AmberPersistenceUnit persistenceUnit = _entityType.getPersistenceUnit(); EmbeddableType type = persistenceUnit.createEmbeddable(_fieldType); EntityEmbeddedField embeddedField; if (_embeddedId) { embeddedField = _entityType.getId().getEmbeddedIdField(); } else { embeddedField = new EntityEmbeddedField(_entityType, type, _fieldName); } // embeddedField.setEmbeddedId(_embeddedId); embeddedField.setLazy(false); _entityType.addField(embeddedField); // XXX: todo ... // validateAttributeOverrides(_field, attributeOverridesAnn, type); AmberTable sourceTable = _entityType.getTable(); HashMap<String, AmberColumn> embeddedColumns = new HashMap<String, AmberColumn>(); HashMap<String, String> fieldNameByColumn = new HashMap<String, String>(); for (EmbeddedSubField subField : embeddedField.getSubFields()) { String embeddedFieldName = subField.getName(); String columnName = toSqlName(embeddedFieldName); boolean notNull = false; boolean unique = false; if (attOverridesAnn != null) { for (int j= 0; j < attOverridesAnn.length; j++) { if (embeddedFieldName.equals(attOverridesAnn[j].name())) { Column columnAnn = attOverridesAnn[j].column(); if (columnAnn != null) { columnName = columnAnn.name(); notNull = ! columnAnn.nullable(); unique = columnAnn.unique(); subField.getColumn().setName(columnName); subField.getColumn().setNotNull(notNull); subField.getColumn().setUnique(unique); } } } } /* AmberType amberType = _persistenceUnit.createType(fields.get(i).getJavaType().getName()); AmberColumn column = sourceTable.createColumn(columnName, amberType); column.setNotNull(notNull); column.setUnique(unique); embeddedColumns.put(columnName, column); fieldNameByColumn.put(columnName, embeddedFieldName); */ } /* embeddedField.setEmbeddedColumns(embeddedColumns); embeddedField.setFieldNameByColumn(fieldNameByColumn); */ embeddedField.init(); } } /** * completes for dependent */ class SqlResultSetMappingCompletion extends CompletionImpl { private String _name; private EntityResult _entities[]; private ColumnResult _columns[]; SqlResultSetMappingCompletion(EntityType type, String name, EntityResult entities[], ColumnResult columns[]) { super(BaseConfigIntrospector.this, type); _name = name; _entities = entities; _columns = columns; } @Override public void complete() throws ConfigException { addSqlResultSetMapping(_name, _entities, _columns); } } void getInternalEmbeddableConfig(Class type, AnnotationConfig annotationCfg) { annotationCfg.reset(type, Embeddable.class); EmbeddableConfig embeddableConfig = null; if (_embeddableConfigMap != null) embeddableConfig = _embeddableConfigMap.get(type.getName()); annotationCfg.setConfig(embeddableConfig); } void getInternalEntityConfig(Class type, AnnotationConfig annotationCfg) { annotationCfg.reset(type, Entity.class); EntityConfig entityConfig = getEntityConfig(type.getName()); annotationCfg.setConfig(entityConfig); } void getInternalMappedSuperclassConfig(Class type, AnnotationConfig annotationCfg) { annotationCfg.reset(type, MappedSuperclass.class); MappedSuperclassConfig mappedSuperConfig = getMappedSuperclassConfig(type.getName()); annotationCfg.setConfig(mappedSuperConfig); } void getInternalEntityListenersConfig(Class type, AnnotationConfig annotationCfg) { annotationCfg.reset(type, EntityListeners.class); EntityConfig entityConfig = getEntityConfig(type.getName()); if (entityConfig == null) return; annotationCfg.setConfig(entityConfig.getEntityListeners()); } void getInternalExcludeDefaultListenersConfig(Class type, AnnotationConfig annotationCfg) { annotationCfg.reset(type, ExcludeDefaultListeners.class); MappedSuperclassConfig entityConfig = getInternalMappedSuperclassOrEntityConfig(type.getName()); if (entityConfig == null) return; if (entityConfig.getExcludeDefaultListeners()) annotationCfg.setConfig(entityConfig.getExcludeDefaultListeners()); } void getInternalExcludeSuperclassListenersConfig(Class type, AnnotationConfig annotationCfg) { annotationCfg.reset(type, ExcludeSuperclassListeners.class); MappedSuperclassConfig entityConfig = getInternalMappedSuperclassOrEntityConfig(type.getName()); if (entityConfig == null) return; if (entityConfig.getExcludeSuperclassListeners()) annotationCfg.setConfig(entityConfig.getExcludeSuperclassListeners()); } void getInternalInheritanceConfig(Class type, AnnotationConfig annotationCfg) { annotationCfg.reset(type, Inheritance.class); EntityConfig entityConfig = getEntityConfig(type.getName()); if (entityConfig != null) { annotationCfg.setConfig(entityConfig.getInheritance()); } } void getInternalNamedQueryConfig(Class type, AnnotationConfig annotationCfg) { annotationCfg.reset(type, NamedQuery.class); EntityConfig entityConfig = getEntityConfig(type.getName()); if (entityConfig != null) { annotationCfg.setConfig(entityConfig.getNamedQuery()); } } void getInternalNamedNativeQueryConfig(Class type, AnnotationConfig annotationCfg) { annotationCfg.reset(type, NamedNativeQuery.class); EntityConfig entityConfig = getEntityConfig(type.getName()); if (entityConfig != null) { annotationCfg.setConfig(entityConfig.getNamedNativeQuery()); } } void getInternalSqlResultSetMappingConfig(Class type, AnnotationConfig annotationCfg) { annotationCfg.reset(type, SqlResultSetMapping.class); EntityConfig entityConfig = getEntityConfig(type.getName()); if (entityConfig != null) { annotationCfg.setConfig(entityConfig.getSqlResultSetMapping()); } } void getInternalTableConfig(Class type, AnnotationConfig annotationCfg) { annotationCfg.reset(type, javax.persistence.Table.class); EntityConfig entityConfig = getEntityConfig(type.getName()); if (entityConfig != null) { annotationCfg.setConfig(entityConfig.getTable()); } } void getInternalSecondaryTableConfig(Class type, AnnotationConfig annotationCfg) { annotationCfg.reset(type, SecondaryTable.class); EntityConfig entityConfig = getEntityConfig(type.getName()); if (entityConfig != null) { annotationCfg.setConfig(entityConfig.getSecondaryTable()); } } void getInternalIdClassConfig(Class type, AnnotationConfig annotationCfg) { annotationCfg.reset(type, IdClass.class); MappedSuperclassConfig entityConfig = getInternalMappedSuperclassOrEntityConfig(type.getName()); if (entityConfig == null) return; annotationCfg.setConfig(entityConfig.getIdClass()); } void getInternalPrimaryKeyJoinColumnConfig(Class type, AnnotationConfig annotationCfg) { annotationCfg.reset(type, PrimaryKeyJoinColumn.class); EntityConfig entityConfig = getEntityConfig(type.getName()); if (entityConfig != null) { annotationCfg.setConfig(entityConfig.getPrimaryKeyJoinColumn()); } } void getInternalDiscriminatorColumnConfig(Class type, AnnotationConfig annotationCfg) { annotationCfg.reset(type, DiscriminatorColumn.class); EntityConfig entityConfig = getEntityConfig(type.getName()); if (entityConfig != null) { annotationCfg.setConfig(entityConfig.getDiscriminatorColumn()); } } void getInternalOneToOneConfig(Class type, AccessibleObject field, String fieldName, AnnotationConfig annotationCfg) { annotationCfg.reset(field, OneToOne.class); MappedSuperclassConfig entityConfig = getInternalMappedSuperclassOrEntityConfig(type.getName()); if (entityConfig == null) return; AttributesConfig attributes = entityConfig.getAttributes(); if (attributes != null) { OneToOneConfig oneToOne = attributes.getOneToOne(fieldName); annotationCfg.setConfig(oneToOne); } } void getInternalOneToManyConfig(Class type, AccessibleObject field, String fieldName, AnnotationConfig annotationCfg) { annotationCfg.reset(field, OneToMany.class); MappedSuperclassConfig entityConfig = getInternalMappedSuperclassOrEntityConfig(type.getName()); if (entityConfig == null) return; AttributesConfig attributes = entityConfig.getAttributes(); if (attributes != null) { OneToManyConfig oneToMany = attributes.getOneToMany(fieldName); annotationCfg.setConfig(oneToMany); } } void getInternalManyToOneConfig(Class type, AccessibleObject field, String fieldName, AnnotationConfig annotationCfg) { annotationCfg.reset(field, ManyToOne.class); MappedSuperclassConfig entityConfig = getInternalMappedSuperclassOrEntityConfig(type.getName()); if (entityConfig == null) return; AttributesConfig attributes = entityConfig.getAttributes(); if (attributes != null) { ManyToOneConfig manyToOne = attributes.getManyToOne(fieldName); annotationCfg.setConfig(manyToOne); } } void getInternalManyToManyConfig(Class type, AccessibleObject field, String fieldName, AnnotationConfig annotationCfg) { annotationCfg.reset(field, ManyToMany.class); MappedSuperclassConfig entityConfig = getInternalMappedSuperclassOrEntityConfig(type.getName()); if (entityConfig == null) return; AttributesConfig attributes = entityConfig.getAttributes(); if (attributes != null) { ManyToManyConfig manyToMany = attributes.getManyToMany(fieldName); annotationCfg.setConfig(manyToMany); } } void getInternalIdConfig(Class type, AccessibleObject method, String fieldName, AnnotationConfig annotationCfg) { annotationCfg.reset(method, javax.persistence.Id.class); MappedSuperclassConfig mappedSuperclassOrEntityConfig = getInternalMappedSuperclassOrEntityConfig(type.getName()); if (mappedSuperclassOrEntityConfig == null) return; AttributesConfig attributes = mappedSuperclassOrEntityConfig.getAttributes(); if (attributes != null) { IdConfig id = attributes.getId(fieldName); annotationCfg.setConfig(id); } } void getInternalCallbackConfig(int callback, Class type, AccessibleObject method, String fieldName, AnnotationConfig annotationCfg) { annotationCfg.reset(method, ListenerType.CALLBACK_CLASS[callback]); MappedSuperclassConfig entityConfig = getInternalMappedSuperclassOrEntityConfig(type.getName()); if (entityConfig == null) return; AbstractListenerConfig callbackConfig; switch (callback) { case Listener.PRE_PERSIST: callbackConfig = entityConfig.getPrePersist(); break; case Listener.POST_PERSIST: callbackConfig = entityConfig.getPostPersist(); break; case Listener.PRE_REMOVE: callbackConfig = entityConfig.getPreRemove(); break; case Listener.POST_REMOVE: callbackConfig = entityConfig.getPostRemove(); break; case Listener.PRE_UPDATE: callbackConfig = entityConfig.getPreUpdate(); break; case Listener.POST_UPDATE: callbackConfig = entityConfig.getPostUpdate(); break; case Listener.POST_LOAD: callbackConfig = entityConfig.getPostLoad(); break; default: return; } if (callbackConfig == null) return; if (callbackConfig.getMethodName().equals(((Method) method).getName())) annotationCfg.setConfig(callbackConfig); } void getInternalEmbeddedIdConfig(Class type, AccessibleObject method, String fieldName, AnnotationConfig annotationCfg) { annotationCfg.reset(method, EmbeddedId.class); } void getInternalVersionConfig(Class type, AccessibleObject method, String fieldName, AnnotationConfig annotationCfg) { annotationCfg.reset(method, Version.class); } void getInternalJoinColumnConfig(Class type, AccessibleObject field, String fieldName, AnnotationConfig annotationCfg) { annotationCfg.reset(field, JoinColumn.class); } void getInternalJoinTableConfig(Class type, AccessibleObject field, String fieldName, AnnotationConfig annotationCfg) { annotationCfg.reset(field, JoinTable.class); } void getInternalMapKeyConfig(Class type, AccessibleObject field, String fieldName, AnnotationConfig annotationCfg) { annotationCfg.reset(field, MapKey.class); } void getInternalAttributeOverrideConfig(Class type, AnnotationConfig annotationCfg) { annotationCfg.reset(type, AttributeOverride.class); } private MappedSuperclassConfig getInternalMappedSuperclassOrEntityConfig(String name) { MappedSuperclassConfig mappedSuperclassConfig = null; mappedSuperclassConfig = getEntityConfig(name); if (mappedSuperclassConfig != null) return mappedSuperclassConfig; mappedSuperclassConfig = getMappedSuperclassConfig(name); return mappedSuperclassConfig; } static AttributeOverrideConfig convertAttributeOverrideAnnotationToConfig(Annotation attOverrideAnn) { /* Column columnAnn = attOverrideAnn.getAnnotation("column"); return createAttributeOverrideConfig(attOverrideAnn.getString("name"), columnAnn.getString("name"), columnAnn.getBoolean("nullable"), columnAnn.getBoolean("unique")); */ throw new UnsupportedOperationException(); } static AttributeOverrideConfig createAttributeOverrideConfig(String name, String columnName, boolean isNullable, boolean isUnique) { AttributeOverrideConfig attOverrideConfig = new AttributeOverrideConfig(); attOverrideConfig.setName(name); ColumnConfig columnConfig = new ColumnConfig(); columnConfig.setName(columnName); columnConfig.setNullable(isNullable); columnConfig.setUnique(isUnique); attOverrideConfig.setColumn(columnConfig); return attOverrideConfig; } }