| /******************************************************************************* |
| * Copyright (c) 1998, 2015 Oracle and/or its affiliates, IBM Corporation. All rights reserved. |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 |
| * which accompanies this distribution. |
| * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html |
| * and the Eclipse Distribution License is available at |
| * http://www.eclipse.org/org/documents/edl-v10.php. |
| * |
| * Contributors: |
| * Oracle - initial API and implementation from Oracle TopLink |
| * 05/16/2008-1.0M8 Guy Pelletier |
| * - 218084: Implement metadata merging functionality between mapping files |
| * 05/23/2008-1.0M8 Guy Pelletier |
| * - 211330: Add attributes-complete support to the EclipseLink-ORM.XML Schema |
| * 12/10/2008-1.1 Michael O'Brien |
| * - 257606: Add orm.xml schema validation true/(false) flag support in persistence.xml |
| * 01/28/2009-2.0 Guy Pelletier |
| * - 248293: JPA 2.0 Element Collections (part 1) |
| * 03/27/2009-2.0 Guy Pelletier |
| * - 241413: JPA 2.0 Add EclipseLink support for Map type attributes |
| * 03/08/2010-2.1 Guy Pelletier |
| * - 303632: Add attribute-type for mapping attributes to EclipseLink-ORM |
| * 05/14/2010-2.1 Guy Pelletier |
| * - 253083: Add support for dynamic persistence using ORM.xml/eclipselink-orm.xml |
| * 04/01/2011-2.3 Guy Pelletier |
| * - 337323: Multi-tenant with shared schema support (part 2) |
| * 09/20/2011-2.3.1 Guy Pelletier |
| * - 357476: Change caching default to ISOLATED for multitenant's using a shared EMF. |
| * 06/20/2012-2.5 Guy Pelletier |
| * - 350487: JPA 2.1 Specification defined support for Stored Procedure Calls |
| * 10/09/2012-2.5 Guy Pelletier |
| * - 374688: JPA 2.1 Converter support |
| * 08/18/2014-2.5 Jody Grassel (IBM Corporation) |
| * - 440802: xml-mapping-metadata-complete does not exclude @Entity annotated entities |
| ******************************************************************************/ |
| package org.eclipse.persistence.internal.jpa.metadata; |
| |
| import java.io.IOException; |
| import java.net.URISyntaxException; |
| import java.net.URL; |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.Enumeration; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import javax.persistence.spi.PersistenceUnitInfo; |
| |
| import org.eclipse.persistence.config.DescriptorCustomizer; |
| import org.eclipse.persistence.config.PersistenceUnitProperties; |
| import org.eclipse.persistence.exceptions.PersistenceUnitLoadingException; |
| import org.eclipse.persistence.exceptions.ValidationException; |
| import org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl; |
| import org.eclipse.persistence.internal.jpa.deployment.PersistenceUnitProcessor; |
| import org.eclipse.persistence.internal.jpa.deployment.PersistenceUnitProcessor.Mode; |
| import org.eclipse.persistence.internal.jpa.metadata.accessors.classes.ClassAccessor; |
| import org.eclipse.persistence.internal.jpa.metadata.accessors.classes.ConverterAccessor; |
| import org.eclipse.persistence.internal.jpa.metadata.accessors.classes.EmbeddableAccessor; |
| import org.eclipse.persistence.internal.jpa.metadata.accessors.classes.EntityAccessor; |
| import org.eclipse.persistence.internal.jpa.metadata.accessors.classes.MappedSuperclassAccessor; |
| import org.eclipse.persistence.internal.jpa.metadata.accessors.objects.MetadataAsmFactory; |
| import org.eclipse.persistence.internal.jpa.metadata.accessors.objects.MetadataClass; |
| import org.eclipse.persistence.internal.jpa.metadata.accessors.objects.MetadataFactory; |
| import org.eclipse.persistence.internal.jpa.metadata.converters.StructConverterMetadata; |
| import org.eclipse.persistence.internal.jpa.metadata.xml.XMLEntityMappings; |
| import org.eclipse.persistence.internal.jpa.metadata.xml.XMLEntityMappingsReader; |
| import org.eclipse.persistence.internal.sessions.AbstractSession; |
| import org.eclipse.persistence.jpa.Archive; |
| import org.eclipse.persistence.jpa.metadata.MetadataSource; |
| import org.eclipse.persistence.logging.AbstractSessionLog; |
| import org.eclipse.persistence.logging.SessionLog; |
| |
| /** |
| * INTERNAL: |
| * The object/relational metadata processor for the EJB3.0 specification. |
| * |
| * @author Guy Pelletier |
| * @since TopLink EJB 3.0 Reference Implementation |
| */ |
| public class MetadataProcessor { |
| protected ClassLoader m_loader; |
| protected MetadataFactory m_factory; |
| protected MetadataProject m_project; |
| protected AbstractSession m_session; |
| protected Map m_predeployProperties; |
| protected MetadataProcessor m_compositeProcessor; |
| protected Set<MetadataProcessor> m_compositeMemberProcessors; |
| protected MetadataSource m_metadataSource; |
| |
| /** |
| * INTERNAL: |
| * Empty processor to be used as a composite processor. |
| */ |
| public MetadataProcessor() {} |
| |
| /** |
| * INTERNAL: |
| * Called from EntityManagerSetupImpl. The 'real' EJB 3.0 processing |
| * that includes XML and annotations. |
| */ |
| public MetadataProcessor(PersistenceUnitInfo puInfo, AbstractSession session, ClassLoader loader, boolean weaveLazy, boolean weaveEager, boolean weaveFetchGroups, boolean multitenantSharedEmf, boolean multitenantSharedCache, Map predeployProperties, MetadataProcessor compositeProcessor) { |
| m_loader = loader; |
| m_session = session; |
| m_project = new MetadataProject(puInfo, session, weaveLazy, weaveEager, weaveFetchGroups, multitenantSharedEmf, multitenantSharedCache); |
| m_predeployProperties = predeployProperties; |
| m_compositeProcessor = compositeProcessor; |
| if (m_compositeProcessor != null) { |
| m_compositeProcessor.addCompositeMemberProcessor(this); |
| m_project.setCompositeProcessor(m_compositeProcessor); |
| } |
| } |
| |
| /** |
| * INTERNAL: |
| * Add containedProcessor to compositeProcessor. |
| */ |
| public void addCompositeMemberProcessor(MetadataProcessor compositeMemberProcessor) { |
| if (m_compositeMemberProcessors == null) { |
| m_compositeMemberProcessors = new HashSet(); |
| } |
| m_compositeMemberProcessors.add(compositeMemberProcessor); |
| } |
| |
| /** |
| * INTERNAL: |
| * Method to place EntityListener's on the descriptors from the given |
| * session. This call is made from the EntityManagerSetup deploy call. |
| */ |
| public void addEntityListeners() { |
| // Process the listeners for all the class accessors, but before |
| // doing so, update the accessors associated class since the loader |
| // should have changed changed. |
| for (EntityAccessor accessor : m_project.getEntityAccessors()) { |
| accessor.setJavaClass(accessor.getDescriptor().getJavaClass()); |
| accessor.processListeners(m_loader); |
| } |
| } |
| |
| /** |
| * INTERNAL: |
| * Method to place NamedQueries and NamedNativeQueries on the given session. |
| * This call is made from the EntityManagerSetup deploy call. |
| */ |
| public void addNamedQueries() { |
| m_project.processQueries(); |
| } |
| |
| /** |
| * INTERNAL: |
| * During EntityManagerSetup deploy, using the real class loader we must |
| * create our dynamic classes. |
| */ |
| public void createDynamicClasses() { |
| m_project.createDynamicClasses(m_loader); |
| } |
| |
| public void createRestInterfaces(){ |
| m_project.createRestInterfaces(m_loader); |
| } |
| |
| /** |
| * INTERNAL: |
| * Return compositeProcessor. |
| */ |
| public MetadataProcessor getCompositeProcessor() { |
| return m_compositeProcessor; |
| } |
| |
| /** |
| * INTERNAL: |
| */ |
| public MetadataFactory getMetadataFactory() { |
| return m_factory; |
| } |
| |
| /** |
| * INTERNAL: |
| */ |
| public MetadataSource getMetadataSource(){ |
| return m_metadataSource; |
| } |
| |
| /** |
| * INTERNAL: |
| * Returns projects owned by compositeProcessor minus the passed project. |
| */ |
| public Set<MetadataProject> getPearProjects(MetadataProject project) { |
| Set<MetadataProject> pearProjects = new HashSet(); |
| if (m_compositeMemberProcessors != null) { |
| for(MetadataProcessor processor : m_compositeMemberProcessors) { |
| MetadataProject pearProject = processor.getProject(); |
| if(pearProject != project) { |
| pearProjects.add(pearProject); |
| } |
| } |
| } |
| return pearProjects; |
| } |
| |
| /** |
| * INTERNAL: |
| * Return a set of class names for each entity, embeddable and mapped |
| * superclass found in the mapping files to be processed by the |
| * MetadataProcessor. |
| */ |
| public Set<String> getPersistenceUnitClassSetFromMappingFiles() { |
| HashSet<String> classSet = new HashSet<String>(); |
| |
| for (XMLEntityMappings entityMappings : m_project.getEntityMappings()) { |
| for (ClassAccessor entity : entityMappings.getEntities()) { |
| classSet.add(entityMappings.getPackageQualifiedClassName(entity.getClassName())); |
| } |
| |
| for (ClassAccessor embeddable : entityMappings.getEmbeddables()) { |
| classSet.add(entityMappings.getPackageQualifiedClassName(embeddable.getClassName())); |
| } |
| |
| for (ClassAccessor mappedSuperclass : entityMappings.getMappedSuperclasses()) { |
| classSet.add(entityMappings.getPackageQualifiedClassName(mappedSuperclass.getClassName())); |
| } |
| } |
| |
| return classSet; |
| } |
| |
| /** |
| * INTERNAL: |
| */ |
| public MetadataProject getProject() { |
| return m_project; |
| } |
| |
| /** |
| * INTERNAL: |
| * Adds a list of StructConverter string names that were defined in the |
| * metadata of this project to the native EclipseLink project. |
| * |
| * These StructConverters can be added to the Project to be processed later |
| */ |
| public void addStructConverterNames() { |
| List<String> structConverters = new ArrayList<String>(); |
| for (StructConverterMetadata converter: m_project.getStructConverters()) { |
| structConverters.add(converter.getConverterClassName()); |
| } |
| if (!structConverters.isEmpty()) { |
| m_session.getProject().setStructConverters(structConverters); |
| } |
| } |
| |
| /** |
| * INTERNAL: |
| * Handle an exception that occurred while processing ORM xml. |
| */ |
| protected void handleORMException(RuntimeException e, String mappingFile, boolean throwException){ |
| if (m_session == null) { |
| // Metadata processor is mainly used with a session. Java SE |
| // bootstrapping uses some functions such as ORM processing without |
| // a session. In these cases, it is impossible to get the session |
| // to properly handle the exception. As a result we log an error. |
| // The same code will be called later in the bootstrapping code |
| // and the error will be handled then. |
| AbstractSessionLog.getLog().log(SessionLog.WARNING, SessionLog.METADATA, EntityManagerSetupImpl.ERROR_LOADING_XML_FILE, new Object[] {mappingFile, e}); |
| } else if (!throwException) { |
| // fail quietly |
| m_session.log(SessionLog.WARNING, SessionLog.METADATA, EntityManagerSetupImpl.ERROR_LOADING_XML_FILE, new Object[] {mappingFile, e}); |
| } else { |
| // fail loudly |
| m_session.handleException(e); |
| } |
| } |
| |
| /** |
| * INTERNAL: |
| * This method is responsible for discovering all the entity classes for |
| * this PU and adding corresponding MetadataDescriptor in the |
| * MetadataProject. |
| * |
| * This method will also gather all the weavable classes for this PU. |
| * Currently, entity and embeddable classes are weavable. |
| * |
| * NOTE: The order of processing should not be changed as the steps are |
| * dependent on one another. |
| */ |
| protected void initPersistenceUnitClasses() { |
| // 1 - Iterate through the classes that are defined in the <mapping> |
| // files and add them to the map. This will merge the accessors where |
| // necessary. |
| HashMap<String, EntityAccessor> entities = new HashMap<String, EntityAccessor>(); |
| HashMap<String, EmbeddableAccessor> embeddables = new HashMap<String, EmbeddableAccessor>(); |
| |
| for (XMLEntityMappings entityMappings : m_project.getEntityMappings()) { |
| entityMappings.initPersistenceUnitClasses(entities, embeddables); |
| } |
| |
| // 2 - Iterate through all the XML entities and add them to the project |
| // and apply any persistence unit defaults. |
| for (EntityAccessor entity : entities.values()) { |
| // This will apply global persistence unit defaults. |
| m_project.addEntityAccessor(entity); |
| |
| // This will override any global settings. |
| entity.getEntityMappings().processEntityMappingsDefaults(entity); |
| } |
| |
| // 3 - Iterate though all the XML embeddables and add them to the |
| // project and apply any persistence unit defaults. |
| for (EmbeddableAccessor embeddable : embeddables.values()) { |
| // This will apply global persistence unit defaults. |
| m_project.addEmbeddableAccessor(embeddable); |
| |
| // This will override any global settings. |
| embeddable.getEntityMappings().processEntityMappingsDefaults(embeddable); |
| } |
| |
| // Check if the xml-mapping-metadata-complete was declared. If so, then ignore <class> entries defined |
| // in the persistence unit, as by definition only elements declared in ORM XML are to be permitted. |
| if (m_project.getPersistenceUnitMetadata() != null && m_project.getPersistenceUnitMetadata().isXMLMappingMetadataComplete()) { |
| return; |
| } |
| |
| // 4 - Iterate through the classes that are referenced from the |
| // persistence.xml file. |
| PersistenceUnitInfo persistenceUnitInfo = m_project.getPersistenceUnitInfo(); |
| List<String> classNames = new ArrayList<String>(); |
| |
| // Add all the <class> specifications. |
| classNames.addAll(persistenceUnitInfo.getManagedClassNames()); |
| |
| // Add all the classes from the <jar> specifications. |
| for (URL url : persistenceUnitInfo.getJarFileUrls()) { |
| classNames.addAll(PersistenceUnitProcessor.getClassNamesFromURL(url, m_loader, null)); |
| } |
| |
| // Add all the classes off the classpath at the persistence unit root url. |
| Set<String> unlistedClasses = Collections.EMPTY_SET; |
| if (! persistenceUnitInfo.excludeUnlistedClasses()) { |
| unlistedClasses = PersistenceUnitProcessor.getClassNamesFromURL(persistenceUnitInfo.getPersistenceUnitRootUrl(), m_loader, m_predeployProperties); |
| } |
| |
| // 5 - Go through all the class names we found and add those classes |
| // that have not yet been added. Be sure to check that the accessor |
| // does not already exist since adding an accessor will merge its |
| // contents with an existing accessor and we only want that to happen |
| // in the XML case. Also, don't add an entity accessor if an embeddable |
| // accessor to the same class exists (and vice versa). XML accessors |
| // are loaded first, so preserve what we find there. |
| Iterator<String> iterator = classNames.iterator(); |
| boolean unlisted = false; |
| while (iterator.hasNext() || !unlisted) { |
| if (!iterator.hasNext() && !unlisted) { |
| iterator = unlistedClasses.iterator(); |
| unlisted = true; |
| } |
| if (iterator.hasNext()) { |
| String className = iterator.next(); |
| MetadataClass candidateClass = m_factory.getMetadataClass(className, unlisted); |
| // JBoss Bug 227630: Do not process a null class whether it was from a |
| // NPE or a CNF, a warning or exception is thrown in loadClass() |
| if (candidateClass != null) { |
| if (PersistenceUnitProcessor.isEntity(candidateClass) && ! m_project.hasEntity(candidateClass) && ! m_project.hasEmbeddable(candidateClass)) { |
| m_project.addEntityAccessor(new EntityAccessor(PersistenceUnitProcessor.getEntityAnnotation(candidateClass), candidateClass, m_project)); |
| } else if (PersistenceUnitProcessor.isEmbeddable(candidateClass) && ! m_project.hasEmbeddable(candidateClass) && ! m_project.hasEntity(candidateClass)) { |
| m_project.addEmbeddableAccessor(new EmbeddableAccessor(PersistenceUnitProcessor.getEmbeddableAnnotation(candidateClass), candidateClass, m_project)); |
| } else if (PersistenceUnitProcessor.isStaticMetamodelClass(candidateClass)) { |
| m_project.addStaticMetamodelClass(PersistenceUnitProcessor.getStaticMetamodelAnnotation(candidateClass), candidateClass); |
| } else if (PersistenceUnitProcessor.isConverter(candidateClass) && ! m_project.hasConverterAccessor(candidateClass)) { |
| m_project.addConverterAccessor(new ConverterAccessor(PersistenceUnitProcessor.getConverterAnnotation(candidateClass), candidateClass, m_project)); |
| } else if (PersistenceUnitProcessor.isMappedSuperclass(candidateClass) && ! m_project.hasMappedSuperclass(candidateClass)) { |
| // ensure mapped superclasses will be added to the metamodel even if they do not have entity subclasses |
| // add the mapped superclass to keep track of it in case it is not processed later (has no subclasses). |
| m_project.addMappedSuperclass(new MappedSuperclassAccessor( |
| PersistenceUnitProcessor.getMappedSuperclassAnnotation(candidateClass), |
| candidateClass, m_project)); |
| } |
| } |
| } |
| } |
| } |
| |
| /** |
| * INTERNAL: |
| * This method is responsible for figuring out list of mapping files to |
| * read into XMLEntityMappings objects and store on the project. Note, |
| * the order the files are discovered and read is very important so do |
| * not change the order of invocation. |
| */ |
| public void loadMappingFiles(boolean throwExceptionOnFail) { |
| // Read all the standard XML mapping files first. |
| loadStandardMappingFiles(MetadataHelper.JPA_ORM_FILE); |
| |
| // Read all the explicitly specified mapping files second. |
| loadSpecifiedMappingFiles(throwExceptionOnFail); |
| |
| // Read all the standard eclipselink files last (if the user hasn't |
| // explicitly excluded them). The eclipselink orm files will be |
| // processed last therefore allowing them to override and merge |
| // metadata where necessary. Note: we want the eclipselink orm |
| // metadata to merge into standard jpa files and not vice versa. |
| // Loading them last will ensure this happens. |
| Boolean excludeEclipseLinkORM = Boolean.valueOf((String) m_project.getPersistenceUnitInfo().getProperties().get(PersistenceUnitProperties.EXCLUDE_ECLIPSELINK_ORM_FILE)); |
| if (! excludeEclipseLinkORM) { |
| loadStandardMappingFiles(MetadataHelper.ECLIPSELINK_ORM_FILE); |
| } |
| |
| if (m_metadataSource !=null) { |
| XMLEntityMappings entityMappings = m_metadataSource.getEntityMappings(this.m_predeployProperties, m_loader, m_session.getSessionLog()); |
| if (entityMappings != null) { |
| m_project.addEntityMappings(entityMappings); |
| } |
| } |
| } |
| |
| /** |
| * INTERNAL: |
| */ |
| protected void loadSpecifiedMappingFiles(boolean throwExceptionOnFail) { |
| PersistenceUnitInfo puInfo = m_project.getPersistenceUnitInfo(); |
| |
| for (String mappingFileName : puInfo.getMappingFileNames()) { |
| try { |
| Enumeration<URL> mappingFileURLs = m_loader.getResources(mappingFileName); |
| |
| if (!mappingFileURLs.hasMoreElements()){ |
| mappingFileURLs = m_loader.getResources("/./" + mappingFileName); |
| } |
| |
| if (mappingFileURLs.hasMoreElements()) { |
| URL nextURL = mappingFileURLs.nextElement(); |
| if (nextURL == null) { |
| nextURL = mappingFileURLs.nextElement(); |
| } |
| |
| if (mappingFileURLs.hasMoreElements()) { |
| // Switched to warning, same file can be on the classpath twice in some deployments, |
| // should not be an error. |
| Throwable throwable = ValidationException.nonUniqueMappingFileName(puInfo.getPersistenceUnitName(), mappingFileName); |
| getSessionLog().logThrowable(SessionLog.FINER, SessionLog.METADATA, throwable); |
| } |
| |
| // Read the document through OX and add it to the project. |
| m_project.addEntityMappings(XMLEntityMappingsReader.read(nextURL, m_loader, m_project.getPersistenceUnitInfo().getProperties())); |
| } else { |
| handleORMException(ValidationException.mappingFileNotFound(puInfo.getPersistenceUnitName(), mappingFileName), mappingFileName, throwExceptionOnFail); |
| } |
| } catch (IOException e) { |
| handleORMException(PersistenceUnitLoadingException.exceptionLoadingORMXML(mappingFileName, e), mappingFileName, throwExceptionOnFail); |
| } |
| } |
| } |
| |
| /** |
| * INTERNAL: |
| */ |
| protected void loadStandardMappingFiles(String ormXMLFile) { |
| PersistenceUnitInfo puInfo = m_project.getPersistenceUnitInfo(); |
| Collection<URL> rootUrls = new HashSet<URL>(puInfo.getJarFileUrls()); |
| rootUrls.add(puInfo.getPersistenceUnitRootUrl()); |
| |
| for (URL rootURL : rootUrls) { |
| getSessionLog().log(SessionLog.FINER, SessionLog.METADATA, "searching_for_default_mapping_file", new Object[] { ormXMLFile, rootURL }, true); |
| URL ormURL = null; |
| |
| Archive par = null; |
| try { |
| par = PersistenceUnitProcessor.getArchiveFactory(m_loader).createArchive(rootURL, null); |
| |
| if (par != null) { |
| ormURL = par.getEntryAsURL(ormXMLFile); |
| |
| if (ormURL != null) { |
| getSessionLog().log(SessionLog.FINER, SessionLog.METADATA, "found_default_mapping_file", new Object[] { ormURL, rootURL }, true); |
| |
| // Read the document through OX and add it to the project., pass persistence unit properties for any orm properties set there |
| XMLEntityMappings entityMappings = XMLEntityMappingsReader.read(ormURL, m_loader, m_project.getPersistenceUnitInfo().getProperties()); |
| entityMappings.setIsEclipseLinkORMFile(ormXMLFile.equals(MetadataHelper.ECLIPSELINK_ORM_FILE)); |
| m_project.addEntityMappings(entityMappings); |
| } |
| } |
| } catch (IOException e) { |
| throw new RuntimeException(e); |
| } catch (URISyntaxException e) { |
| throw new RuntimeException(e); |
| } finally { |
| if (par != null) { |
| par.close(); |
| } |
| } |
| } |
| } |
| |
| /** |
| * INTERNAL: |
| * Return the SessionLog from the Session. If the session is null, |
| * return the AbstractSessionLog's SessionLog. |
| * @return SessionLog |
| */ |
| protected SessionLog getSessionLog() { |
| if (m_session != null) { |
| return m_session.getSessionLog(); |
| } else { |
| return AbstractSessionLog.getLog(); |
| } |
| } |
| |
| /** |
| * INTERNAL: |
| * Process the customizer for those entities and embeddables that have one |
| * defined. This must be the last thing called on this processor before |
| * cleanup. |
| */ |
| public void processCustomizers() { |
| for (ClassAccessor classAccessor: m_project.getAccessorsWithCustomizer()) { |
| DescriptorCustomizer customizer = (DescriptorCustomizer) MetadataHelper.getClassInstance(classAccessor.getCustomizerClass().getName(), m_loader); |
| |
| try { |
| customizer.customize(classAccessor.getDescriptor().getClassDescriptor()); |
| } catch (Exception e) { |
| getSessionLog().logThrowable(SessionLog.FINER, SessionLog.METADATA, e); |
| } |
| } |
| } |
| |
| /** |
| * INTERNAL: |
| * Performs the initialization of the persistence unit classes and then |
| * processes the xml metadata. |
| * Note: Do not change the order of invocation of various methods. |
| */ |
| public void processEntityMappings(PersistenceUnitProcessor.Mode mode) { |
| if (mode == PersistenceUnitProcessor.Mode.ALL || mode == PersistenceUnitProcessor.Mode.COMPOSITE_MEMBER_INITIAL) { |
| m_factory = new MetadataAsmFactory(m_project.getLogger(), m_loader); |
| |
| // 1 - Process persistence unit meta data/defaults defined in ORM XML |
| // instance documents in the persistence unit. If multiple conflicting |
| // persistence unit meta data is found, this call will throw an |
| // exception. The meta data we find here will be applied in the |
| // initialize call below. |
| for (XMLEntityMappings entityMappings : m_project.getEntityMappings()) { |
| // Since this our first iteration through the entity mappings list, |
| // set the project and loader references. This is very important |
| // and must be done first! |
| entityMappings.setLoader(m_loader); |
| entityMappings.setProject(m_project); |
| entityMappings.setMetadataFactory(m_factory); |
| |
| // Process the persistence unit metadata if defined. |
| entityMappings.processPersistenceUnitMetadata(); |
| } |
| |
| // 2 - Initialize all the persistence unit class with the meta data we |
| // processed in step 1. |
| initPersistenceUnitClasses(); |
| |
| // 3 - Now process the entity mappings metadata. |
| for (XMLEntityMappings entityMappings : m_project.getEntityMappings()) { |
| entityMappings.process(); |
| } |
| } |
| } |
| |
| /** |
| * INTERNAL: |
| * Process the ORM metadata on this processors metadata project |
| * (representing a single persistence-unit) |
| */ |
| public void processORMMetadata(PersistenceUnitProcessor.Mode mode) { |
| if (mode == Mode.ALL || mode == Mode.COMPOSITE_MEMBER_INITIAL) { |
| m_project.processStage1(); |
| m_project.processStage2(); |
| } |
| |
| if (mode != PersistenceUnitProcessor.Mode.COMPOSITE_MEMBER_INITIAL) { |
| m_project.processStage3(mode); |
| } |
| } |
| |
| /** |
| * INTERNAL: |
| * Use this method to set the correct class loader that should be used |
| * during processing. Currently, the class loader should only change |
| * once, from preDeploy to deploy. |
| */ |
| public void setClassLoader(ClassLoader loader) { |
| m_loader = loader; |
| m_factory.setLoader(loader); |
| // Update the loader on all the entity mappings for this project. |
| for (XMLEntityMappings entityMappings : m_project.getEntityMappings()) { |
| entityMappings.setLoader(m_loader); |
| } |
| } |
| |
| /** |
| * INTERNAL: |
| * Use this method to set the MetadataSource class to use for loading |
| * extensible mappings |
| */ |
| public void setMetadataSource(MetadataSource source){ |
| m_metadataSource = source; |
| } |
| } |