| /******************************************************************************* |
| * Copyright (c) 2007, 2015 Oracle. 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: |
| * Oracle - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.jpt.jpa.core.internal.context.persistence; |
| |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.Hashtable; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| import java.util.Vector; |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IFolder; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.OperationCanceledException; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.core.runtime.SubMonitor; |
| import org.eclipse.jdt.core.IPackageFragment; |
| import org.eclipse.jdt.core.IType; |
| import org.eclipse.jdt.core.JavaModelException; |
| import org.eclipse.jpt.common.core.resource.java.JavaResourceAbstractType; |
| import org.eclipse.jpt.common.core.resource.java.JavaResourceModel; |
| import org.eclipse.jpt.common.core.resource.java.JavaResourceType; |
| import org.eclipse.jpt.common.core.utility.BodySourceWriter; |
| import org.eclipse.jpt.common.core.utility.TextRange; |
| import org.eclipse.jpt.common.utility.internal.ObjectTools; |
| import org.eclipse.jpt.common.utility.internal.StringTools; |
| import org.eclipse.jpt.common.utility.internal.collection.CollectionTools; |
| import org.eclipse.jpt.common.utility.internal.collection.ListTools; |
| import org.eclipse.jpt.common.utility.internal.iterable.EmptyIterable; |
| import org.eclipse.jpt.common.utility.internal.iterable.EmptyListIterable; |
| import org.eclipse.jpt.common.utility.internal.iterable.IterableTools; |
| import org.eclipse.jpt.common.utility.internal.iterable.SubIterableWrapper; |
| import org.eclipse.jpt.common.utility.internal.iterable.TransformationIterable; |
| import org.eclipse.jpt.common.utility.internal.predicate.PredicateAdapter; |
| import org.eclipse.jpt.common.utility.internal.predicate.PredicateTools; |
| import org.eclipse.jpt.common.utility.internal.transformer.TransformerTools; |
| import org.eclipse.jpt.common.utility.iterable.ListIterable; |
| import org.eclipse.jpt.common.utility.predicate.Predicate; |
| import org.eclipse.jpt.common.utility.transformer.Transformer; |
| import org.eclipse.jpt.jpa.core.JpaFile; |
| import org.eclipse.jpt.jpa.core.JpaProject; |
| import org.eclipse.jpt.jpa.core.JpaStructureNode; |
| import org.eclipse.jpt.jpa.core.JptJpaCoreMessages; |
| import org.eclipse.jpt.jpa.core.context.AccessType; |
| import org.eclipse.jpt.jpa.core.context.DeleteTypeRefactoringParticipant; |
| import org.eclipse.jpt.jpa.core.context.Embeddable; |
| import org.eclipse.jpt.jpa.core.context.Entity; |
| import org.eclipse.jpt.jpa.core.context.Generator; |
| import org.eclipse.jpt.jpa.core.context.IdTypeMapping; |
| import org.eclipse.jpt.jpa.core.context.JpaNamedContextModel; |
| import org.eclipse.jpt.jpa.core.context.ManagedType; |
| import org.eclipse.jpt.jpa.core.context.ManagedTypeContainer; |
| import org.eclipse.jpt.jpa.core.context.MappingFile; |
| import org.eclipse.jpt.jpa.core.context.MappingFilePersistenceUnitDefaults; |
| import org.eclipse.jpt.jpa.core.context.MappingFilePersistenceUnitMetadata; |
| import org.eclipse.jpt.jpa.core.context.PersistentAttribute; |
| import org.eclipse.jpt.jpa.core.context.PersistentType; |
| import org.eclipse.jpt.jpa.core.context.PersistentTypeContainer; |
| import org.eclipse.jpt.jpa.core.context.Query; |
| import org.eclipse.jpt.jpa.core.context.TypeMapping; |
| import org.eclipse.jpt.jpa.core.context.TypeRefactoringParticipant; |
| import org.eclipse.jpt.jpa.core.context.java.JavaGenerator; |
| import org.eclipse.jpt.jpa.core.context.java.JavaManagedType; |
| import org.eclipse.jpt.jpa.core.context.java.JavaQuery; |
| import org.eclipse.jpt.jpa.core.context.java.JavaTypeMappingDefinition; |
| import org.eclipse.jpt.jpa.core.context.orm.EntityMappings; |
| import org.eclipse.jpt.jpa.core.context.orm.OrmQueryContainer; |
| import org.eclipse.jpt.jpa.core.context.persistence.ClassRef; |
| import org.eclipse.jpt.jpa.core.context.persistence.JarFileRef; |
| import org.eclipse.jpt.jpa.core.context.persistence.MappingFileRef; |
| import org.eclipse.jpt.jpa.core.context.persistence.MappingFileRefactoringParticipant; |
| import org.eclipse.jpt.jpa.core.context.persistence.Persistence; |
| import org.eclipse.jpt.jpa.core.context.persistence.PersistenceUnit; |
| import org.eclipse.jpt.jpa.core.context.persistence.PersistenceUnitTransactionType; |
| import org.eclipse.jpt.jpa.core.internal.jpa2.context.persistence.connection.NullConnection2_0; |
| import org.eclipse.jpt.jpa.core.internal.jpa2.context.persistence.options.NullOptions2_0; |
| import org.eclipse.jpt.jpa.core.internal.jpa2_1.context.persistence.schemagen.NullGenericSchemaGeneration2_1; |
| import org.eclipse.jpt.jpa.core.internal.plugin.JptJpaCorePlugin; |
| import org.eclipse.jpt.jpa.core.jpa2.JpaFactory2_0; |
| import org.eclipse.jpt.jpa.core.jpa2.JpaProject2_0; |
| import org.eclipse.jpt.jpa.core.jpa2.context.MappingFilePersistenceUnitDefaults2_0; |
| import org.eclipse.jpt.jpa.core.jpa2.context.MetamodelSourceType2_0; |
| import org.eclipse.jpt.jpa.core.jpa2.context.PersistentType2_0; |
| import org.eclipse.jpt.jpa.core.jpa2.context.persistence.connection.Connection2_0; |
| import org.eclipse.jpt.jpa.core.jpa2.context.persistence.options.Options2_0; |
| import org.eclipse.jpt.jpa.core.jpa2.context.persistence.options.SharedCacheMode2_0; |
| import org.eclipse.jpt.jpa.core.jpa2.context.persistence.options.ValidationMode2_0; |
| import org.eclipse.jpt.jpa.core.jpa2_1.context.persistence.PersistenceUnit2_1; |
| import org.eclipse.jpt.jpa.core.jpa2_1.context.persistence.schemagen.SchemaGeneration2_1; |
| import org.eclipse.jpt.jpa.core.jpql.JpaJpqlQueryHelper; |
| import org.eclipse.jpt.jpa.core.resource.orm.XmlEntityMappings; |
| import org.eclipse.jpt.jpa.core.resource.persistence.PersistenceFactory; |
| import org.eclipse.jpt.jpa.core.resource.persistence.XmlJarFileRef; |
| import org.eclipse.jpt.jpa.core.resource.persistence.XmlJavaClassRef; |
| import org.eclipse.jpt.jpa.core.resource.persistence.XmlMappingFileRef; |
| import org.eclipse.jpt.jpa.core.resource.persistence.XmlPersistenceUnit; |
| import org.eclipse.jpt.jpa.core.resource.persistence.XmlProperties; |
| import org.eclipse.jpt.jpa.core.resource.persistence.XmlProperty; |
| import org.eclipse.jpt.jpa.core.validation.JptJpaCoreValidationMessages; |
| import org.eclipse.osgi.util.NLS; |
| import org.eclipse.text.edits.DeleteEdit; |
| import org.eclipse.text.edits.ReplaceEdit; |
| import org.eclipse.wst.validation.internal.provisional.core.IMessage; |
| import org.eclipse.wst.validation.internal.provisional.core.IReporter; |
| |
| /** |
| * <code>persistence.xml</code> file |
| * <br> |
| * <code>persistence-unit</code> element |
| */ |
| public abstract class AbstractPersistenceUnit |
| extends AbstractPersistenceXmlContextModel<Persistence> |
| implements PersistenceUnit2_1 |
| { |
| protected final XmlPersistenceUnit xmlPersistenceUnit; |
| |
| protected String name; |
| |
| protected Boolean specifiedExcludeUnlistedClasses; |
| |
| protected PersistenceUnitTransactionType specifiedTransactionType; |
| protected PersistenceUnitTransactionType defaultTransactionType = PersistenceUnitTransactionType.JTA; |
| |
| protected String description; |
| |
| protected String provider; |
| |
| protected String jtaDataSource; |
| protected String nonJtaDataSource; |
| |
| /** |
| * Big performance enhancement! |
| * Use with caution since this contains no duplicates (e.g. class is listed in 2 different mappings files) |
| * Rebuilt at the *beginning* of {@link #update()} |
| * |
| * @see #rebuildManagedTypeMap() |
| */ |
| protected final Hashtable<String, ManagedType> managedTypeMap = new Hashtable<String, ManagedType>(); |
| |
| protected final ContextListContainer<MappingFileRef, XmlMappingFileRef> specifiedMappingFileRefContainer; |
| |
| /** |
| * Will be null if the implied mapping file should not be part of the context model. |
| * Otherwise will be equal to potentialImpliedMappingFileRef. |
| * |
| * @see #potentialImpliedMappingFileRef |
| */ |
| protected MappingFileRef impliedMappingFileRef; |
| |
| /** |
| * Store the implied mapping file ref here even if it is not part of the context model. |
| * This allows us to sync it in the syncWithResourceModel. In the update, determine if |
| * it should be part of the context model and set the impliedMappingFileRef appropriately. |
| * |
| * @see #impliedMappingFileRef |
| * @see #usesImpliedMappingFile() |
| */ |
| protected final MappingFileRef potentialImpliedMappingFileRef; |
| |
| protected final ContextListContainer<JarFileRef, XmlJarFileRef> jarFileRefContainer; |
| |
| protected final ContextListContainer<ClassRef, XmlJavaClassRef> specifiedClassRefContainer; |
| |
| protected final ContextCollectionContainer<ClassRef, JavaResourceAbstractType> impliedClassRefContainer; |
| |
| protected final ContextListContainer<Property, XmlProperty> propertyContainer; |
| |
| /* global generator definitions, defined elsewhere in model */ |
| protected final Vector<Generator> generators = new Vector<Generator>(); |
| |
| /* global query definitions, defined elsewhere in model */ |
| protected final Vector<Query> queries = new Vector<Query>(); |
| |
| protected boolean xmlMappingMetadataComplete; |
| protected AccessType defaultAccess; |
| protected String defaultCatalog; |
| protected String defaultSchema; |
| protected boolean defaultCascadePersist; |
| protected boolean defaultDelimitedIdentifiers; |
| |
| protected final Vector<JpaStructureNode> structureChildren = new Vector<JpaStructureNode>(); |
| |
| //****** JPA 2.0 features |
| protected Connection2_0 connection; |
| protected Options2_0 options; |
| |
| protected SharedCacheMode2_0 specifiedSharedCacheMode; |
| protected SharedCacheMode2_0 defaultSharedCacheMode; |
| |
| protected ValidationMode2_0 specifiedValidationMode; |
| protected ValidationMode2_0 defaultValidationMode = DEFAULT_VALIDATION_MODE; |
| |
| protected final Set<IFile> metamodelFiles = Collections.synchronizedSet(new HashSet<IFile>()); |
| |
| //****** JPA 2.1 features |
| protected SchemaGeneration2_1 schemaGeneration; |
| |
| |
| // ********** construction/initialization ********** |
| |
| /** |
| * NB: Be careful changing the order of the statements in this method |
| * (bug 258701 is one reason). |
| */ |
| protected AbstractPersistenceUnit(Persistence parent, XmlPersistenceUnit xmlPersistenceUnit) { |
| super(parent); |
| this.xmlPersistenceUnit = xmlPersistenceUnit; |
| this.name = xmlPersistenceUnit.getName(); |
| this.specifiedExcludeUnlistedClasses = xmlPersistenceUnit.getExcludeUnlistedClasses(); |
| this.specifiedTransactionType = this.buildSpecifiedTransactionType(); |
| this.description = xmlPersistenceUnit.getDescription(); |
| this.provider = xmlPersistenceUnit.getProvider(); |
| this.jtaDataSource = xmlPersistenceUnit.getJtaDataSource(); |
| this.nonJtaDataSource = xmlPersistenceUnit.getNonJtaDataSource(); |
| |
| // initialize the properties early because other things will need them...(?) |
| this.propertyContainer = this.buildPropertyContainer(); |
| this.initializeProperties(); |
| |
| this.specifiedMappingFileRefContainer = this.buildSpecifiedMappingFileRefContainer(); |
| this.potentialImpliedMappingFileRef = this.buildImpliedMappingFileRef(); |
| this.jarFileRefContainer = this.buildJarFileRefContainer(); |
| this.specifiedClassRefContainer = this.buildSpecifiedClassRefContainer(); |
| this.impliedClassRefContainer = this.buildImpliedClassRefContainer(); |
| |
| this.specifiedSharedCacheMode = this.buildSpecifiedSharedCacheMode(); |
| this.specifiedValidationMode = this.buildSpecifiedValidationMode(); |
| |
| this.initializeMetamodelFiles(); |
| this.initializeStructureChildren(); |
| } |
| |
| |
| // ********** synchronize/update ********** |
| |
| @Override |
| public void synchronizeWithResourceModel() { |
| super.synchronizeWithResourceModel(); |
| |
| this.setName_(this.xmlPersistenceUnit.getName()); |
| this.setSpecifiedExcludeUnlistedClasses_(this.xmlPersistenceUnit.getExcludeUnlistedClasses()); |
| this.setSpecifiedTransactionType_(this.buildSpecifiedTransactionType()); |
| this.setDescription_(this.xmlPersistenceUnit.getDescription()); |
| this.setProvider_(this.xmlPersistenceUnit.getProvider()); |
| this.setJtaDataSource_(this.xmlPersistenceUnit.getJtaDataSource()); |
| this.setNonJtaDataSource_(this.xmlPersistenceUnit.getNonJtaDataSource()); |
| |
| this.syncSpecifiedMappingFileRefs(); |
| this.syncImpliedMappingFileRef(); |
| |
| this.syncJarFileRefs(); |
| |
| this.syncSpecifiedClassRefs(); |
| this.synchronizeModelsWithResourceModel(this.getImpliedClassRefs()); |
| |
| this.syncProperties(); |
| |
| this.setSpecifiedSharedCacheMode_(this.buildSpecifiedSharedCacheMode()); |
| this.setSpecifiedValidationMode_(this.buildSpecifiedValidationMode()); |
| } |
| |
| @Override |
| public void update() { |
| super.update(); |
| |
| //Rebuild the managed type map first. I *think* if anything changes to cause |
| //this to be out of sync another update would be triggered by that change. |
| this.rebuildManagedTypeMap(); |
| |
| this.setDefaultTransactionType(this.buildDefaultTransactionType()); |
| |
| // update specified class refs before mapping file refs because of |
| // JpaFile root structure nodes - we want the mapping file to "win", |
| // as it would in a JPA runtime implementation |
| this.updateModels(this.getSpecifiedClassRefs()); |
| |
| this.updateModels(this.getSpecifiedMappingFileRefs()); |
| this.updateImpliedMappingFileRef(); |
| |
| this.updateModels(this.getJarFileRefs()); |
| |
| // update the implied class refs after all the other types, both |
| // specified here and specified in the mapping files, are in place |
| this.updateImpliedClassRefs(); |
| |
| this.updateModels(this.getProperties()); |
| |
| this.updatePersistenceUnitMetadata(); |
| |
| this.setGenerators(this.buildGenerators()); |
| this.setQueries(this.buildQueries()); |
| |
| this.setDefaultSharedCacheMode(this.buildDefaultSharedCacheMode()); |
| this.setDefaultValidationMode(this.buildDefaultValidationMode()); |
| |
| this.updateStructureChildren(); |
| } |
| |
| public void addRootStructureNodesTo(JpaFile jpaFile, Collection<JpaStructureNode> rootStructureNodes) { |
| for (MappingFileRef mappingFileRef : this.getMappingFileRefs()) { |
| mappingFileRef.addRootStructureNodesTo(jpaFile, rootStructureNodes); |
| } |
| for (ClassRef classRef : this.getClassRefs()) { |
| classRef.addRootStructureNodesTo(jpaFile, rootStructureNodes); |
| } |
| } |
| |
| // ********** JpaContextModel implementation ********** |
| |
| protected Persistence getPersistence() { |
| return this.parent; |
| } |
| |
| @Override |
| public PersistenceUnit getPersistenceUnit() { |
| return this; |
| } |
| |
| |
| // ********** JpaStructureNode implementation ********** |
| |
| public ContextType getContextType() { |
| return new ContextType(this); |
| } |
| |
| public Class<PersistenceUnit> getStructureType() { |
| return PersistenceUnit.class; |
| } |
| |
| public TextRange getSelectionTextRange() { |
| return this.xmlPersistenceUnit.getSelectionTextRange(); |
| } |
| |
| protected void initializeStructureChildren() { |
| CollectionTools.addAll(this.structureChildren, this.getMappingFileRefs()); |
| CollectionTools.addAll(this.structureChildren, this.getClassRefs()); |
| CollectionTools.addAll(this.structureChildren, this.getJarFileRefs()); |
| } |
| |
| protected void updateStructureChildren() { |
| Vector<JpaStructureNode> newChildren = new Vector<JpaStructureNode>(); |
| CollectionTools.addAll(newChildren, this.getMappingFileRefs()); |
| CollectionTools.addAll(newChildren, this.getClassRefs()); |
| CollectionTools.addAll(newChildren, this.getJarFileRefs()); |
| |
| this.synchronizeCollection(newChildren, this.structureChildren, STRUCTURE_CHILDREN_COLLECTION); |
| } |
| |
| public Iterable<JpaStructureNode> getStructureChildren() { |
| return IterableTools.cloneLive(this.structureChildren); |
| } |
| |
| public int getStructureChildrenSize() { |
| return this.structureChildren.size(); |
| } |
| |
| public TextRange getFullTextRange() { |
| return this.xmlPersistenceUnit.getFullTextRange(); |
| } |
| |
| public boolean containsOffset(int textOffset) { |
| return this.xmlPersistenceUnit.containsOffset(textOffset); |
| } |
| |
| public JpaStructureNode getStructureNode(int textOffset) { |
| for (JpaStructureNode child : this.getStructureChildren()) { |
| if (child.containsOffset(textOffset)) { |
| return child; |
| } |
| } |
| return this; |
| } |
| |
| public void dispose() { |
| for (MappingFileRef mappingFileRef : this.getMappingFileRefs()) { |
| mappingFileRef.dispose(); |
| } |
| } |
| |
| |
| // ********** name ********** |
| |
| public String getName() { |
| return this.name; |
| } |
| |
| public void setName(String name) { |
| this.setName_(name); |
| this.xmlPersistenceUnit.setName(name); |
| } |
| |
| protected void setName_(String name) { |
| String old = this.name; |
| this.name = name; |
| this.firePropertyChanged(NAME_PROPERTY, old, name); |
| } |
| |
| |
| // ********** transaction type ********** |
| |
| public PersistenceUnitTransactionType getTransactionType() { |
| return (this.specifiedTransactionType != null) ? this.specifiedTransactionType : this.defaultTransactionType; |
| } |
| |
| public PersistenceUnitTransactionType getSpecifiedTransactionType() { |
| return this.specifiedTransactionType; |
| } |
| |
| public void setSpecifiedTransactionType(PersistenceUnitTransactionType transactionType) { |
| this.setSpecifiedTransactionType_(transactionType); |
| this.xmlPersistenceUnit.setTransactionType(PersistenceUnitTransactionType.toXmlResourceModel(transactionType)); |
| } |
| |
| protected void setSpecifiedTransactionType_(PersistenceUnitTransactionType transactionType) { |
| PersistenceUnitTransactionType old = this.specifiedTransactionType; |
| this.specifiedTransactionType = transactionType; |
| this.firePropertyChanged(SPECIFIED_TRANSACTION_TYPE_PROPERTY, old, transactionType); |
| } |
| |
| public PersistenceUnitTransactionType getDefaultTransactionType() { |
| return this.defaultTransactionType; |
| } |
| |
| protected void setDefaultTransactionType(PersistenceUnitTransactionType transactionType) { |
| PersistenceUnitTransactionType old = this.defaultTransactionType; |
| this.defaultTransactionType = transactionType; |
| this.firePropertyChanged(DEFAULT_TRANSACTION_TYPE_PROPERTY, old, transactionType); |
| } |
| |
| protected PersistenceUnitTransactionType buildSpecifiedTransactionType() { |
| return PersistenceUnitTransactionType.fromXmlResourceModel(this.xmlPersistenceUnit.getTransactionType()); |
| } |
| |
| /** |
| * TODO - calculate default |
| * From the JPA spec: "In a Java EE environment, if this element is not |
| * specified, the default is JTA. In a Java SE environment, if this element |
| * is not specified, a default of RESOURCE_LOCAL may be assumed." |
| */ |
| protected PersistenceUnitTransactionType buildDefaultTransactionType() { |
| return PersistenceUnitTransactionType.JTA; //return JTA for now, fixing regression in bug 277524 |
| } |
| |
| |
| // ********** description ********** |
| |
| public String getDescription() { |
| return this.description; |
| } |
| |
| public void setDescription(String description) { |
| this.setDescription_(description); |
| this.xmlPersistenceUnit.setDescription(description); |
| } |
| |
| protected void setDescription_(String description) { |
| String old = this.description; |
| this.description = description; |
| this.firePropertyChanged(DESCRIPTION_PROPERTY, old, description); |
| } |
| |
| |
| // ********** provider ********** |
| |
| public String getProvider() { |
| return this.provider; |
| } |
| |
| public void setProvider(String provider) { |
| this.setProvider_(provider); |
| this.xmlPersistenceUnit.setProvider(provider); |
| } |
| |
| protected void setProvider_(String provider) { |
| String old = this.provider; |
| this.provider = provider; |
| this.firePropertyChanged(PROVIDER_PROPERTY, old, provider); |
| } |
| |
| |
| // ********** JTA data source ********** |
| |
| public String getJtaDataSource() { |
| return this.jtaDataSource; |
| } |
| |
| public void setJtaDataSource(String jtaDataSource) { |
| this.setJtaDataSource_(jtaDataSource); |
| this.xmlPersistenceUnit.setJtaDataSource(jtaDataSource); |
| } |
| |
| protected void setJtaDataSource_(String jtaDataSource) { |
| String old = this.jtaDataSource; |
| this.jtaDataSource = jtaDataSource; |
| this.firePropertyChanged(JTA_DATA_SOURCE_PROPERTY, old, jtaDataSource); |
| } |
| |
| |
| // ********** non-JTA data source ********** |
| |
| public String getNonJtaDataSource() { |
| return this.nonJtaDataSource; |
| } |
| |
| public void setNonJtaDataSource(String nonJtaDataSource) { |
| this.setNonJtaDataSource_(nonJtaDataSource); |
| this.xmlPersistenceUnit.setNonJtaDataSource(nonJtaDataSource); |
| } |
| |
| protected void setNonJtaDataSource_(String nonJtaDataSource) { |
| String old = this.nonJtaDataSource; |
| this.nonJtaDataSource = nonJtaDataSource; |
| this.firePropertyChanged(NON_JTA_DATA_SOURCE_PROPERTY, old, nonJtaDataSource); |
| } |
| |
| |
| // ********** mapping file refs ********** |
| |
| public ListIterable<MappingFileRef> getMappingFileRefs() { |
| return (this.impliedMappingFileRef == null) ? |
| this.getSpecifiedMappingFileRefs() : |
| this.getCombinedMappingFileRefs(); |
| } |
| |
| protected ListIterable<MappingFileRef> getCombinedMappingFileRefs() { |
| return IterableTools.insert( |
| this.impliedMappingFileRef, |
| this.getSpecifiedMappingFileRefs() |
| ); |
| } |
| |
| public int getMappingFileRefsSize() { |
| return (this.impliedMappingFileRef == null) ? |
| this.getSpecifiedMappingFileRefsSize() : |
| this.getCombinedMappingFileRefsSize(); |
| } |
| |
| protected int getCombinedMappingFileRefsSize() { |
| return this.getSpecifiedMappingFileRefsSize() + 1; |
| } |
| |
| public Iterable<MappingFileRef> getMappingFileRefsContaining(String typeName) { |
| return IterableTools.filter(this.getMappingFileRefs(), new ManagedTypeContainer.ContainsType(typeName)); |
| } |
| |
| protected Iterable<MappingFile> getMappingFiles() { |
| return IterableTools.removeNulls(this.getMappingFiles_()); |
| } |
| |
| protected Iterable<MappingFile> getMappingFiles_() { |
| return IterableTools.transform(this.getMappingFileRefs(), MappingFileRef.MAPPING_FILE_TRANSFORMER); |
| } |
| |
| |
| // ********** specified mapping file refs ********** |
| |
| public ListIterable<MappingFileRef> getSpecifiedMappingFileRefs() { |
| return this.specifiedMappingFileRefContainer; |
| } |
| |
| public int getSpecifiedMappingFileRefsSize() { |
| return this.specifiedMappingFileRefContainer.size(); |
| } |
| |
| public MappingFileRef addSpecifiedMappingFileRef(String fileName) { |
| return this.addSpecifiedMappingFileRef(this.getSpecifiedMappingFileRefsSize(), fileName); |
| } |
| |
| public MappingFileRef addSpecifiedMappingFileRef(int index, String fileName) { |
| XmlMappingFileRef xmlMappingFileRef = this.buildXmlMappingFileRef(fileName); |
| MappingFileRef mappingFileRef = this.specifiedMappingFileRefContainer.addContextElement(index, xmlMappingFileRef); |
| this.xmlPersistenceUnit.getMappingFiles().add(index, xmlMappingFileRef); |
| return mappingFileRef; |
| } |
| |
| protected XmlMappingFileRef buildXmlMappingFileRef(String fileName) { |
| XmlMappingFileRef ref = PersistenceFactory.eINSTANCE.createXmlMappingFileRef(); |
| ref.setFileName(fileName); |
| return ref; |
| } |
| |
| protected MappingFileRef buildSpecifiedMappingFileRef(XmlMappingFileRef xmlMappingFileRef) { |
| return this.getContextModelFactory().buildMappingFileRef(this, xmlMappingFileRef); |
| } |
| |
| public void removeSpecifiedMappingFileRef(MappingFileRef mappingFileRef) { |
| this.removeSpecifiedMappingFileRef(this.specifiedMappingFileRefContainer.indexOf(mappingFileRef)); |
| } |
| |
| public void removeSpecifiedMappingFileRef(int index) { |
| this.removeSpecifiedMappingFileRef_(index); |
| this.xmlPersistenceUnit.getMappingFiles().remove(index); |
| } |
| |
| protected void removeSpecifiedMappingFileRef_(int index) { |
| this.specifiedMappingFileRefContainer.remove(index); |
| } |
| |
| protected void syncSpecifiedMappingFileRefs() { |
| this.specifiedMappingFileRefContainer.synchronizeWithResourceModel(); |
| } |
| |
| protected ListIterable<XmlMappingFileRef> getXmlMappingFileRefs() { |
| // clone to reduce chance of concurrency problems |
| return IterableTools.cloneLive(this.xmlPersistenceUnit.getMappingFiles()); |
| } |
| |
| protected ContextListContainer<MappingFileRef, XmlMappingFileRef> buildSpecifiedMappingFileRefContainer() { |
| return new SpecifiedMappingFileRefContainer(SPECIFIED_MAPPING_FILE_REFS_LIST, new SpecifiedMappingFileRefContainerAdapter()); |
| // return this.buildSpecifiedContextListContainer(SPECIFIED_MAPPING_FILE_REFS_LIST, new SpecifiedMappingFileRefContainerAdapter()); |
| } |
| |
| /** |
| * specified mapping file ref container adapter |
| */ |
| public class SpecifiedMappingFileRefContainerAdapter |
| extends AbstractContainerAdapter<MappingFileRef, XmlMappingFileRef> |
| { |
| public MappingFileRef buildContextElement(XmlMappingFileRef resourceElement) { |
| return AbstractPersistenceUnit.this.buildSpecifiedMappingFileRef(resourceElement); |
| } |
| public ListIterable<XmlMappingFileRef> getResourceElements() { |
| return AbstractPersistenceUnit.this.getXmlMappingFileRefs(); |
| } |
| public XmlMappingFileRef extractResourceElement(MappingFileRef contextElement) { |
| return contextElement.getXmlMappingFileRef(); |
| } |
| } |
| |
| // TODO - remove once we remove need for dispose... |
| public class SpecifiedMappingFileRefContainer |
| extends SpecifiedContextListContainer<MappingFileRef, XmlMappingFileRef> |
| { |
| public SpecifiedMappingFileRefContainer(String aspectName, Container.Adapter<MappingFileRef, XmlMappingFileRef> adapter) { |
| super(aspectName, adapter); |
| } |
| @Override |
| public void clear() { |
| Object[] temp = this.elements.toArray(); |
| super.clear(); |
| for (Object element : temp) { |
| ((MappingFileRef) element).dispose(); |
| } |
| } |
| @Override |
| public MappingFileRef remove(int index) { |
| MappingFileRef element = super.remove(index); |
| element.dispose(); |
| return element; |
| } |
| @Override |
| public void remove(MappingFileRef element) { |
| super.remove(element); |
| element.dispose(); |
| } |
| @Override |
| public void removeAll(Iterable<MappingFileRef> contextElements) { |
| super.removeAll(contextElements); |
| for (MappingFileRef element : contextElements) { |
| element.dispose(); |
| } |
| } |
| } |
| |
| |
| // ********** implied mapping file ref ********** |
| |
| public MappingFileRef getImpliedMappingFileRef() { |
| return this.impliedMappingFileRef; |
| } |
| |
| protected void setImpliedMappingFileRef(MappingFileRef mappingFileRef) { |
| MappingFileRef old = this.impliedMappingFileRef; |
| this.impliedMappingFileRef = mappingFileRef; |
| this.firePropertyChanged(IMPLIED_MAPPING_FILE_REF_PROPERTY, old, mappingFileRef); |
| } |
| |
| protected MappingFileRef buildImpliedMappingFileRef() { |
| return this.getContextModelFactory().buildVirtualMappingFileRef(this); |
| } |
| |
| protected void syncImpliedMappingFileRef() { |
| this.potentialImpliedMappingFileRef.synchronizeWithResourceModel(); |
| } |
| |
| protected void updateImpliedMappingFileRef() { |
| if (this.usesImpliedMappingFile()) { |
| this.setImpliedMappingFileRef(this.potentialImpliedMappingFileRef); |
| this.impliedMappingFileRef.update(); |
| } |
| else if (this.impliedMappingFileRef != null) { |
| this.impliedMappingFileRef.dispose(); |
| this.setImpliedMappingFileRef(null); |
| } |
| } |
| |
| protected boolean usesImpliedMappingFile() { |
| return this.impliedMappingFileIsNotSpecified() && this.impliedMappingFileExists(); |
| } |
| |
| protected boolean impliedMappingFileIsNotSpecified() { |
| return ! this.impliedMappingFileIsSpecified(); |
| } |
| |
| protected boolean impliedMappingFileIsSpecified() { |
| return this.mappingFileIsSpecified(XmlEntityMappings.DEFAULT_RUNTIME_PATH_NAME); |
| } |
| |
| protected boolean mappingFileIsSpecified(String impliedMappingFileName) { |
| for (MappingFileRef specifiedMappingFileRef : this.getSpecifiedMappingFileRefs()) { |
| if (ObjectTools.equals(specifiedMappingFileRef.getFileName(), impliedMappingFileName)) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| protected boolean impliedMappingFileExists() { |
| return this.getJpaProject().getDefaultOrmXmlResource() != null; |
| } |
| |
| |
| // ********** JAR file refs ********** |
| |
| public ListIterable<JarFileRef> getJarFileRefs() { |
| return this.jarFileRefContainer; |
| } |
| |
| public int getJarFileRefsSize() { |
| return this.jarFileRefContainer.size(); |
| } |
| |
| public JarFileRef addJarFileRef(String fileName) { |
| return this.addJarFileRef(this.getJarFileRefsSize(), fileName); |
| } |
| |
| public JarFileRef addJarFileRef(int index, String fileName) { |
| XmlJarFileRef xmlJarFileRef = this.buildXmlJarFileRef(fileName); |
| JarFileRef jarFileRef = this.jarFileRefContainer.addContextElement(index, xmlJarFileRef); |
| this.xmlPersistenceUnit.getJarFiles().add(index, xmlJarFileRef); |
| return jarFileRef; |
| } |
| |
| protected XmlJarFileRef buildXmlJarFileRef(String fileName) { |
| XmlJarFileRef ref = PersistenceFactory.eINSTANCE.createXmlJarFileRef(); |
| ref.setFileName(fileName); |
| return ref; |
| } |
| |
| protected JarFileRef buildJarFileRef(XmlJarFileRef xmlJarFileRef) { |
| return this.getContextModelFactory().buildJarFileRef(this, xmlJarFileRef); |
| } |
| |
| public void removeJarFileRef(JarFileRef jarFileRef) { |
| this.removeJarFileRef(this.jarFileRefContainer.indexOf(jarFileRef)); |
| } |
| |
| public void removeJarFileRef(int index) { |
| this.removeJarFileRef_(index); |
| this.xmlPersistenceUnit.getJarFiles().remove(index); |
| } |
| |
| protected void removeJarFileRef_(int index) { |
| this.jarFileRefContainer.remove(index); |
| } |
| |
| protected void syncJarFileRefs() { |
| this.jarFileRefContainer.synchronizeWithResourceModel(); |
| } |
| |
| protected ListIterable<XmlJarFileRef> getXmlJarFileRefs() { |
| // clone to reduce chance of concurrency problems |
| return IterableTools.cloneLive(this.xmlPersistenceUnit.getJarFiles()); |
| } |
| |
| protected ContextListContainer<JarFileRef, XmlJarFileRef> buildJarFileRefContainer() { |
| return this.buildSpecifiedContextListContainer(JAR_FILE_REFS_LIST, new JarFileRefContainerAdapter()); |
| } |
| |
| /** |
| * JAR file ref container adapter |
| */ |
| public class JarFileRefContainerAdapter |
| extends AbstractContainerAdapter<JarFileRef, XmlJarFileRef> |
| { |
| public JarFileRef buildContextElement(XmlJarFileRef resourceElement) { |
| return AbstractPersistenceUnit.this.buildJarFileRef(resourceElement); |
| } |
| public ListIterable<XmlJarFileRef> getResourceElements() { |
| return AbstractPersistenceUnit.this.getXmlJarFileRefs(); |
| } |
| public XmlJarFileRef extractResourceElement(JarFileRef contextElement) { |
| return contextElement.getXmlJarFileRef(); |
| } |
| } |
| |
| // ********** class refs ********** |
| |
| @SuppressWarnings("unchecked") |
| public Iterable<ClassRef> getClassRefs() { |
| return IterableTools.concatenate( |
| this.getSpecifiedClassRefs(), |
| this.getImpliedClassRefs() |
| ); |
| } |
| |
| public int getClassRefsSize() { |
| return this.getSpecifiedClassRefsSize() + this.getImpliedClassRefsSize(); |
| } |
| |
| |
| // ********** specified class refs ********** |
| |
| public ListIterable<ClassRef> getSpecifiedClassRefs() { |
| return this.specifiedClassRefContainer; |
| } |
| |
| public int getSpecifiedClassRefsSize() { |
| return this.specifiedClassRefContainer.size(); |
| } |
| |
| public ClassRef addSpecifiedClassRef(String className) { |
| return this.addSpecifiedClassRef(this.getSpecifiedClassRefsSize(), className); |
| } |
| |
| public ClassRef addSpecifiedClassRef(int index, String className) { |
| XmlJavaClassRef xmlClassRef = this.buildXmlJavaClassRef(className); |
| ClassRef classRef = this.specifiedClassRefContainer.addContextElement(index, xmlClassRef); |
| this.xmlPersistenceUnit.getClasses().add(index, xmlClassRef); |
| return classRef; |
| } |
| |
| protected Iterable<ClassRef> addSpecifiedClassRefs(Iterable<JavaResourceAbstractType> javaResourceTypes) { |
| return this.addSpecifiedClassRefs(this.getSpecifiedClassRefsSize(), javaResourceTypes); |
| } |
| |
| protected Iterable<ClassRef> addSpecifiedClassRefs(int index, Iterable<JavaResourceAbstractType> javaResourceTypes) { |
| ArrayList<XmlJavaClassRef> xmlClassRefs = new ArrayList<XmlJavaClassRef>(); |
| for (JavaResourceAbstractType javaResourceType : javaResourceTypes) { |
| xmlClassRefs.add(this.buildXmlJavaClassRef(javaResourceType.getTypeBinding().getQualifiedName())); |
| } |
| Iterable<ClassRef> classRefs = this.specifiedClassRefContainer.addContextElements(index, xmlClassRefs); |
| this.xmlPersistenceUnit.getClasses().addAll(index, xmlClassRefs); |
| return classRefs; |
| } |
| |
| protected XmlJavaClassRef buildXmlJavaClassRef(String className) { |
| XmlJavaClassRef ref = PersistenceFactory.eINSTANCE.createXmlJavaClassRef(); |
| ref.setJavaClass(className); |
| return ref; |
| } |
| |
| protected ClassRef buildClassRef(XmlJavaClassRef xmlClassRef) { |
| return this.getContextModelFactory().buildClassRef(this, xmlClassRef); |
| } |
| |
| public void removeSpecifiedClassRef(ClassRef classRef) { |
| this.removeSpecifiedClassRef(this.specifiedClassRefContainer.indexOf(classRef)); |
| } |
| |
| public void removeSpecifiedClassRef(int index) { |
| this.removeSpecifiedClassRef_(index); |
| this.xmlPersistenceUnit.getClasses().remove(index); |
| } |
| |
| protected void removeSpecifiedClassRef_(int index) { |
| this.specifiedClassRefContainer.remove(index); |
| } |
| |
| public void removeSpecifiedClassRefs(Iterable<ClassRef> classRefs) { |
| ArrayList<XmlJavaClassRef> xmlClassRefs = new ArrayList<XmlJavaClassRef>(); |
| for (ClassRef classRef : classRefs) { |
| xmlClassRefs.add(classRef.getXmlClassRef()); |
| } |
| this.specifiedClassRefContainer.removeAll(classRefs); |
| this.xmlPersistenceUnit.getClasses().removeAll(xmlClassRefs); |
| } |
| |
| protected void syncSpecifiedClassRefs() { |
| this.specifiedClassRefContainer.synchronizeWithResourceModel(); |
| } |
| |
| protected ListIterable<XmlJavaClassRef> getXmlClassRefs() { |
| // clone to reduce chance of concurrency problems |
| return IterableTools.cloneLive(this.xmlPersistenceUnit.getClasses()); |
| } |
| |
| protected ContextListContainer<ClassRef, XmlJavaClassRef> buildSpecifiedClassRefContainer() { |
| return this.buildSpecifiedContextListContainer(SPECIFIED_CLASS_REFS_LIST, new SpecifiedClassRefContainerAdapter()); |
| } |
| |
| /** |
| * specified class ref container adapter |
| */ |
| public class SpecifiedClassRefContainerAdapter |
| extends AbstractContainerAdapter<ClassRef, XmlJavaClassRef> |
| { |
| public ClassRef buildContextElement(XmlJavaClassRef resourceElement) { |
| return AbstractPersistenceUnit.this.buildClassRef(resourceElement); |
| } |
| public ListIterable<XmlJavaClassRef> getResourceElements() { |
| return AbstractPersistenceUnit.this.getXmlClassRefs(); |
| } |
| public XmlJavaClassRef extractResourceElement(ClassRef contextElement) { |
| return contextElement.getXmlClassRef(); |
| } |
| } |
| |
| |
| // ********** virtual class refs ********** |
| |
| public Iterable<ClassRef> getImpliedClassRefs() { |
| return this.impliedClassRefContainer; |
| } |
| |
| public int getImpliedClassRefsSize() { |
| return this.impliedClassRefContainer.size(); |
| } |
| |
| protected ClassRef buildClassRef(JavaResourceAbstractType jrat) { |
| return this.getContextModelFactory().buildClassRef(this, jrat); |
| } |
| |
| protected void updateImpliedClassRefs() { |
| this.impliedClassRefContainer.update(); |
| } |
| |
| protected Iterable<JavaResourceAbstractType> getImpliedClassResourceTypes() { |
| return this.excludesUnlistedClasses() ? |
| EmptyIterable.<JavaResourceAbstractType>instance() : |
| this.getImpliedClassResourceTypes_(); |
| } |
| |
| /** |
| * Return the names of all the Java classes in the JPA project that are |
| * managed (i.e. have the appropriate annotation etc.) but not specified |
| * in the persistence unit or any of its mapping files. |
| */ |
| protected Iterable<JavaResourceAbstractType> getImpliedClassResourceTypes_() { |
| return IterableTools.filter(this.getJpaProject().getPotentialJavaSourceTypes(), new DoesNotSpecifyManagedType()); |
| } |
| |
| public class DoesNotSpecifyManagedType |
| extends PredicateAdapter<JavaResourceAbstractType> |
| { |
| @Override |
| public boolean evaluate(JavaResourceAbstractType jrat) { |
| return ! AbstractPersistenceUnit.this.specifiesManagedType(jrat.getTypeBinding().getQualifiedName()); |
| } |
| } |
| |
| protected ContextCollectionContainer<ClassRef, JavaResourceAbstractType> buildImpliedClassRefContainer() { |
| return this.buildVirtualContextCollectionContainer(IMPLIED_CLASS_REFS_COLLECTION, new ImpliedClassRefContainerAdapter()); |
| } |
| |
| /** |
| * default class ref container adapter |
| * <p> |
| * <strong>NB:</strong> The context class ref is matched with a java resource type. |
| * <p> |
| * This is used during <strong>both</strong> <em>sync</em> and |
| * <em>update</em> because the list of implied class refs can be modified |
| * in either situation. In particular, we cannot simply rely on |
| * <em>update</em> because there are situations where a <em>sync</em> is |
| * triggered but a follow-up <em>update</em> is not. (Of course, any |
| * change discovered here will trigger an <em>update</em>.) |
| * <p> |
| * The most obvious example is when the JPA project is configured to |
| * discover annotated classes and a Java class is annotated for the first |
| * time (via code editing, not via the context model). This will trigger |
| * a <em>sync</em>; but, since the unannotated class is not yet in the |
| * context model and, as a result, the context model's state is untouched, |
| * an <em>update</em> will not be triggered. |
| * <p> |
| * Obviously, other context model changes can change this collection (e.g. |
| * setting whether the persistence unit excludes unlisted classes); o the |
| * collection must also be synchronized during <em>update</em>. |
| */ |
| public class ImpliedClassRefContainerAdapter |
| extends AbstractContainerAdapter<ClassRef, JavaResourceAbstractType> |
| { |
| public ClassRef buildContextElement(JavaResourceAbstractType resourceElement) { |
| return AbstractPersistenceUnit.this.buildClassRef(resourceElement); |
| } |
| public Iterable<JavaResourceAbstractType> getResourceElements() { |
| return AbstractPersistenceUnit.this.getImpliedClassResourceTypes(); |
| } |
| public JavaResourceAbstractType extractResourceElement(ClassRef contextElement) { |
| return contextElement.getJavaResourceType(); |
| } |
| } |
| |
| |
| // ********** exclude unlisted classes ********** |
| |
| public boolean excludesUnlistedClasses() { |
| return (this.specifiedExcludeUnlistedClasses != null) ? this.specifiedExcludeUnlistedClasses.booleanValue() : this.getDefaultExcludeUnlistedClasses(); |
| } |
| |
| public Boolean getSpecifiedExcludeUnlistedClasses() { |
| return this.specifiedExcludeUnlistedClasses; |
| } |
| |
| public void setSpecifiedExcludeUnlistedClasses(Boolean specifiedExcludeUnlistedClasses) { |
| this.setSpecifiedExcludeUnlistedClasses_(specifiedExcludeUnlistedClasses); |
| this.xmlPersistenceUnit.setExcludeUnlistedClasses(this.specifiedExcludeUnlistedClasses); |
| } |
| |
| protected void setSpecifiedExcludeUnlistedClasses_(Boolean excludeUnlistedClasses) { |
| Boolean old = this.specifiedExcludeUnlistedClasses; |
| this.specifiedExcludeUnlistedClasses = excludeUnlistedClasses; |
| this.firePropertyChanged(SPECIFIED_EXCLUDE_UNLISTED_CLASSES_PROPERTY, old, excludeUnlistedClasses); |
| } |
| |
| public boolean getDefaultExcludeUnlistedClasses() { |
| return false; // ??? |
| } |
| |
| |
| // ********** properties ********** |
| |
| public ListIterable<Property> getProperties() { |
| return this.propertyContainer; |
| } |
| |
| public int getPropertiesSize() { |
| return this.propertyContainer.size(); |
| } |
| |
| public Property getProperty(String propertyName) { |
| if (propertyName == null) { |
| throw new NullPointerException(); |
| } |
| for (Property property : this.getProperties()) { |
| if (propertyName.equals(property.getName())) { |
| return property; |
| } |
| } |
| return null; |
| } |
| |
| public Iterable<Property> getPropertiesNamed(String propertyName) { |
| if (propertyName == null) { |
| throw new NullPointerException(); |
| } |
| return IterableTools.filter(this.getProperties(), new Property.NameEquals(propertyName)); |
| } |
| |
| public Iterable<Property> getPropertiesWithNamePrefix(final String propertyNamePrefix) { |
| if (propertyNamePrefix == null) { |
| throw new NullPointerException(); |
| } |
| return IterableTools.filter(this.getProperties(), new Property.NameStartsWith(propertyNamePrefix)); |
| } |
| |
| public Property addProperty() { |
| return this.addProperty(this.getPropertiesSize()); |
| } |
| |
| public Property addProperty(int index) { |
| XmlProperty xmlProperty = this.buildXmlProperty(); |
| Property property = this.addProperty_(index, xmlProperty); |
| |
| XmlProperties xmlProperties = this.xmlPersistenceUnit.getProperties(); |
| if (xmlProperties == null) { |
| xmlProperties = this.buildXmlProperties(); |
| this.xmlPersistenceUnit.setProperties(xmlProperties); |
| } |
| |
| xmlProperties.getProperties().add(index, xmlProperty); |
| if (property.getName() != null) { |
| this.propertyAdded(property.getName(), property.getValue()); |
| } |
| return property; |
| } |
| |
| protected XmlProperty buildXmlProperty() { |
| return PersistenceFactory.eINSTANCE.createXmlProperty(); |
| } |
| |
| protected Property buildProperty(XmlProperty xmlProperty) { |
| return this.getContextModelFactory().buildProperty(this, xmlProperty); |
| } |
| |
| protected XmlProperties buildXmlProperties() { |
| return PersistenceFactory.eINSTANCE.createXmlProperties(); |
| } |
| |
| public void setProperty(String propertyName, String value) { |
| this.setProperty(propertyName, value, false); |
| } |
| |
| public void setProperty(String propertyName, String value, boolean duplicatePropertyNamesAllowed) { |
| Property prev = this.getProperty(propertyName); |
| if (prev == null) { |
| if (value != null) { |
| this.addProperty(propertyName, value); // add [first] property |
| } |
| } else { |
| if (duplicatePropertyNamesAllowed) { |
| if (value == null) { |
| // do nothing? |
| } else { |
| this.addProperty(propertyName, value); // add [duplicate] property |
| } |
| } else { |
| if (value == null) { |
| this.removeProperty(prev); // remove existing property |
| } else { |
| prev.setValue(value); // change existing property |
| } |
| } |
| } |
| } |
| |
| protected void addProperty(String propertyName, String value) { |
| Property property = this.addProperty(); |
| property.setName(propertyName); |
| property.setValue(value); |
| } |
| |
| public void removeProperty(Property property) { |
| this.removeProperty(this.propertyContainer.indexOf(property)); |
| } |
| |
| public void removeProperty(String propertyName) { |
| if (propertyName == null) { |
| throw new NullPointerException(); |
| } |
| for (Property property : this.getProperties()) { |
| if (propertyName.equals(property.getName())) { |
| this.removeProperty(property); |
| return; |
| } |
| } |
| throw new IllegalArgumentException("invalid property name: " + propertyName); //$NON-NLS-1$ |
| } |
| |
| public void removeProperty(String propertyName, String value) { |
| if ((propertyName == null) || (value == null)) { |
| throw new NullPointerException(); |
| } |
| for (Property property : this.getProperties()) { |
| if (propertyName.equals(property.getName()) && value.equals(property.getValue())) { |
| this.removeProperty(property); |
| return; |
| } |
| } |
| throw new IllegalArgumentException("invalid property name/value pair: " + propertyName + " = " + value); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| |
| protected void removeProperty(int index) { |
| Property removedProperty = this.propertyContainer.remove(index); |
| this.xmlPersistenceUnit.getProperties().getProperties().remove(index); |
| |
| if (this.xmlPersistenceUnit.getProperties().getProperties().isEmpty()) { |
| this.xmlPersistenceUnit.setProperties(null); |
| } |
| |
| if (removedProperty.getName() != null) { |
| this.propertyRemoved(removedProperty.getName()); |
| } |
| } |
| |
| public void propertyNameChanged(String oldPropertyName, String newPropertyName, String value) { |
| if ((oldPropertyName == null) && (value == null)) { |
| //this is a property that is currently being added, we don't need to deal with it until the value is set |
| return; |
| } |
| if (oldPropertyName != null) { |
| this.propertyRemoved(oldPropertyName); |
| } |
| if (newPropertyName != null) { |
| this.propertyAdded(newPropertyName, value); |
| } |
| } |
| |
| public void propertyValueChanged(String propertyName, String newValue) { |
| this.connection.propertyValueChanged(propertyName, newValue); |
| this.options.propertyValueChanged(propertyName, newValue); |
| this.schemaGeneration.propertyValueChanged(propertyName, newValue); |
| } |
| |
| protected void propertyAdded(String propertyName, String value) { |
| this.propertyValueChanged(propertyName, value); |
| } |
| |
| protected void propertyRemoved(String propertyName) { |
| this.connection.propertyRemoved(propertyName); |
| this.options.propertyRemoved(propertyName); |
| this.schemaGeneration.propertyRemoved(propertyName); |
| } |
| |
| protected void initializeProperties() { |
| this.connection = this.buildConnection(); |
| this.options = this.buildOptions(); |
| this.schemaGeneration = this.buildSchemaGeneration(); |
| } |
| |
| protected Connection2_0 buildConnection() { |
| return this.isPersistenceXml2_0Compatible() ? |
| this.getContextModelFactory2_0().buildConnection(this) : |
| new NullConnection2_0(this); |
| } |
| |
| protected Options2_0 buildOptions() { |
| return this.isPersistenceXml2_0Compatible() ? |
| this.getContextModelFactory2_0().buildOptions(this) : |
| new NullOptions2_0(this); |
| } |
| |
| protected SchemaGeneration2_1 buildSchemaGeneration() { |
| return this.isPersistenceXml2_1Compatible() ? |
| this.getContextModelFactory2_1().buildSchemaGeneration(this) : |
| new NullGenericSchemaGeneration2_1(this); |
| } |
| |
| protected void syncProperties() { |
| this.propertyContainer.synchronizeWithResourceModel(); |
| } |
| |
| protected ListIterable<XmlProperty> getXmlProperties() { |
| XmlProperties xmlProperties = this.xmlPersistenceUnit.getProperties(); |
| // clone to reduce chance of concurrency problems |
| return (xmlProperties == null) ? |
| EmptyListIterable.<XmlProperty>instance() : |
| IterableTools.cloneLive(xmlProperties.getProperties()); |
| } |
| |
| protected Property addProperty_(int index, XmlProperty xmlProperty) { |
| Property property = this.propertyContainer.addContextElement(index, xmlProperty); |
| if (property.getName() != null) { |
| this.propertyAdded(property.getName(), property.getValue()); |
| } |
| return property; |
| } |
| |
| protected void removeProperty_(Property property) { |
| this.propertyContainer.remove(property); |
| if (property.getName() != null) { |
| this.propertyRemoved(property.getName()); |
| } |
| } |
| |
| protected ContextListContainer<Property, XmlProperty> buildPropertyContainer() { |
| return new PropertyContainer(PROPERTIES_LIST, new PropertyContainerAdapter()); |
| // return this.buildSpecifiedContextListContainer(PROPERTIES_LIST, new PropertyContainerAdapter()); |
| } |
| |
| /** |
| * property container adapter |
| */ |
| public class PropertyContainerAdapter |
| extends AbstractContainerAdapter<Property, XmlProperty> |
| { |
| public Property buildContextElement(XmlProperty resourceElement) { |
| return AbstractPersistenceUnit.this.buildProperty(resourceElement); |
| } |
| public ListIterable<XmlProperty> getResourceElements() { |
| return AbstractPersistenceUnit.this.getXmlProperties(); |
| } |
| public XmlProperty extractResourceElement(Property contextElement) { |
| return contextElement.getXmlProperty(); |
| } |
| } |
| |
| public class PropertyContainer |
| extends SpecifiedContextListContainer<Property, XmlProperty> |
| { |
| public PropertyContainer(String aspectName, Container.Adapter<Property, XmlProperty> adapter) { |
| super(aspectName, adapter); |
| } |
| @Override |
| protected Property add(int index, Property element) { |
| super.add(index, element); |
| if (element.getName() != null) { |
| propertyAdded(element.getName(), element.getValue()); |
| } |
| return element; |
| } |
| @Override |
| public void clear() { |
| Object[] temp = this.elements.toArray(); |
| super.clear(); |
| for (Object element : temp) { |
| this.dispose((Property) element); |
| } |
| } |
| @Override |
| public Property remove(int index) { |
| Property element = super.remove(index); |
| this.dispose(element); |
| return element; |
| } |
| @Override |
| public void remove(Property element) { |
| super.remove(element); |
| this.dispose(element); |
| } |
| @Override |
| public void removeAll(Iterable<Property> contextElements) { |
| super.removeAll(contextElements); |
| for (Property element : contextElements) { |
| this.dispose(element); |
| } |
| } |
| protected void dispose(Property element) { |
| if (element.getName() != null) { |
| propertyRemoved(element.getName()); |
| } |
| } |
| } |
| |
| |
| // ********** mapping file (orm.xml) persistence unit metadata & defaults ********** |
| |
| public boolean isXmlMappingMetadataComplete() { |
| return this.xmlMappingMetadataComplete; |
| } |
| |
| protected void setXmlMappingMetadataComplete(boolean xmlMappingMetadataComplete) { |
| boolean old = this.xmlMappingMetadataComplete; |
| this.xmlMappingMetadataComplete = xmlMappingMetadataComplete; |
| this.firePropertyChanged(XML_MAPPING_METADATA_COMPLETE_PROPERTY, old, xmlMappingMetadataComplete); |
| } |
| |
| protected boolean buildXmlMappingMetadataComplete(MappingFilePersistenceUnitMetadata metadata) { |
| return (metadata == null) ? false : metadata.isXmlMappingMetadataComplete(); |
| } |
| |
| public AccessType getDefaultAccess() { |
| return this.defaultAccess; |
| } |
| |
| protected void setDefaultAccess(AccessType access) { |
| AccessType old = this.defaultAccess; |
| this.defaultAccess = access; |
| this.firePropertyChanged(DEFAULT_ACCESS_PROPERTY, old, access); |
| } |
| |
| public String getDefaultCatalog() { |
| return this.defaultCatalog; |
| } |
| |
| protected void setDefaultCatalog(String catalog) { |
| String old = this.defaultCatalog; |
| this.defaultCatalog = catalog; |
| this.firePropertyChanged(DEFAULT_CATALOG_PROPERTY, old, catalog); |
| } |
| |
| protected String buildDefaultCatalog(MappingFilePersistenceUnitDefaults defaults) { |
| String catalog = (defaults == null) ? null : defaults.getCatalog(); |
| return (catalog != null) ? catalog : this.getJpaProject().getDefaultCatalog(); |
| } |
| |
| public String getDefaultSchema() { |
| return this.defaultSchema; |
| } |
| |
| protected void setDefaultSchema(String schema) { |
| String old = this.defaultSchema; |
| this.defaultSchema = schema; |
| this.firePropertyChanged(DEFAULT_SCHEMA_PROPERTY, old, schema); |
| } |
| |
| protected String buildDefaultSchema(MappingFilePersistenceUnitDefaults defaults) { |
| String schema = (defaults == null) ? null : defaults.getSchema(); |
| return (schema != null) ? schema : this.getJpaProject().getDefaultSchema(); |
| } |
| |
| public boolean getDefaultCascadePersist() { |
| return this.defaultCascadePersist; |
| } |
| |
| protected void setDefaultCascadePersist(boolean cascadePersist) { |
| boolean old = this.defaultCascadePersist; |
| this.defaultCascadePersist = cascadePersist; |
| this.firePropertyChanged(DEFAULT_CASCADE_PERSIST_PROPERTY, old, cascadePersist); |
| } |
| |
| protected boolean buildDefaultCascadePersist(MappingFilePersistenceUnitDefaults defaults) { |
| return (defaults == null) ? false : defaults.isCascadePersist(); |
| } |
| |
| public boolean getDefaultDelimitedIdentifiers() { |
| return this.defaultDelimitedIdentifiers; |
| } |
| |
| protected void setDefaultDelimitedIdentifiers(boolean delimitedIdentifiers) { |
| boolean old = this.defaultDelimitedIdentifiers; |
| this.defaultDelimitedIdentifiers = delimitedIdentifiers; |
| this.firePropertyChanged(DEFAULT_DELIMITED_IDENTIFIERS_PROPERTY, old, delimitedIdentifiers); |
| } |
| |
| protected boolean buildDefaultDelimitedIdentifiers(MappingFilePersistenceUnitDefaults defaults) { |
| return ( ! this.isJpa2_0Compatible()) ? false : |
| (defaults == null) ? false : ((MappingFilePersistenceUnitDefaults2_0) defaults).isDelimitedIdentifiers(); |
| } |
| |
| protected void updatePersistenceUnitMetadata() { |
| MappingFilePersistenceUnitMetadata metadata = this.getMetadata(); |
| this.setXmlMappingMetadataComplete(this.buildXmlMappingMetadataComplete(metadata)); |
| |
| MappingFilePersistenceUnitDefaults defaults = (metadata == null) ? null : metadata.getPersistenceUnitDefaults(); |
| this.setDefaultAccess((defaults == null) ? null : defaults.getAccess()); |
| this.setDefaultCatalog(this.buildDefaultCatalog(defaults)); |
| this.setDefaultSchema(this.buildDefaultSchema(defaults)); |
| this.setDefaultDelimitedIdentifiers(this.buildDefaultDelimitedIdentifiers(defaults)); |
| } |
| |
| /** |
| * return the first persistence unit metadata we encounter |
| * in a mapping file |
| */ |
| protected MappingFilePersistenceUnitMetadata getMetadata() { |
| for (MappingFileRef mappingFileRef : this.getMappingFileRefs()) { |
| if (mappingFileRef.persistenceUnitMetadataExists()) { |
| return mappingFileRef.getPersistenceUnitMetadata(); |
| } |
| } |
| return null; |
| } |
| |
| |
| // ********** PersistenceUnit2_0 implementation ********** |
| |
| public Connection2_0 getConnection() { |
| return this.connection; |
| } |
| |
| public Options2_0 getOptions() { |
| return this.options; |
| } |
| |
| |
| // ********** PersistenceUnit2_1 implementation ********** |
| |
| public SchemaGeneration2_1 getSchemaGeneration() { |
| return this.schemaGeneration; |
| } |
| |
| |
| |
| // ********** shared cache mode ********** |
| |
| public SharedCacheMode2_0 getSharedCacheMode() { |
| return (this.specifiedSharedCacheMode != null) ? this.specifiedSharedCacheMode : this.defaultSharedCacheMode; |
| } |
| |
| public SharedCacheMode2_0 getSpecifiedSharedCacheMode() { |
| return this.specifiedSharedCacheMode; |
| } |
| |
| public void setSpecifiedSharedCacheMode(SharedCacheMode2_0 specifiedSharedCacheMode) { |
| this.setSpecifiedSharedCacheMode_(specifiedSharedCacheMode); |
| this.xmlPersistenceUnit.setSharedCacheMode(SharedCacheMode2_0.toXmlResourceModel(specifiedSharedCacheMode)); |
| } |
| |
| protected void setSpecifiedSharedCacheMode_(SharedCacheMode2_0 sharedCacheMode) { |
| SharedCacheMode2_0 old = this.specifiedSharedCacheMode; |
| this.specifiedSharedCacheMode = sharedCacheMode; |
| this.firePropertyChanged(SPECIFIED_SHARED_CACHE_MODE_PROPERTY, old, sharedCacheMode); |
| } |
| |
| public SharedCacheMode2_0 getDefaultSharedCacheMode() { |
| return this.defaultSharedCacheMode; |
| } |
| |
| protected void setDefaultSharedCacheMode(SharedCacheMode2_0 defaultSharedCacheMode) { |
| SharedCacheMode2_0 old = this.defaultSharedCacheMode; |
| this.defaultSharedCacheMode = defaultSharedCacheMode; |
| this.firePropertyChanged(DEFAULT_SHARED_CACHE_MODE_PROPERTY, old, defaultSharedCacheMode); |
| } |
| |
| public boolean calculateDefaultCacheable() { |
| SharedCacheMode2_0 sharedCacheMode = this.getSharedCacheMode(); |
| if (sharedCacheMode == null) { |
| return false; // this can happen during initial update... |
| } |
| switch (sharedCacheMode) { |
| case NONE: |
| case ENABLE_SELECTIVE: |
| case UNSPECIFIED: |
| return false; |
| case ALL: |
| case DISABLE_SELECTIVE: |
| return true; |
| default: |
| throw new IllegalStateException("unknown mode: " + sharedCacheMode); //$NON-NLS-1$ |
| } |
| } |
| |
| protected SharedCacheMode2_0 buildSpecifiedSharedCacheMode() { |
| return SharedCacheMode2_0.fromXmlResourceModel(this.xmlPersistenceUnit.getSharedCacheMode()); |
| } |
| |
| protected SharedCacheMode2_0 buildDefaultSharedCacheMode() { |
| return SharedCacheMode2_0.UNSPECIFIED; |
| } |
| |
| // ********** validation mode ********** |
| |
| public ValidationMode2_0 getValidationMode() { |
| return (this.specifiedValidationMode != null) ? this.specifiedValidationMode : this.defaultValidationMode; |
| } |
| |
| public ValidationMode2_0 getSpecifiedValidationMode() { |
| return this.specifiedValidationMode; |
| } |
| |
| public void setSpecifiedValidationMode(ValidationMode2_0 specifiedValidationMode) { |
| this.setSpecifiedValidationMode_(specifiedValidationMode); |
| this.xmlPersistenceUnit.setValidationMode(ValidationMode2_0.toXmlResourceModel(specifiedValidationMode)); |
| } |
| |
| protected void setSpecifiedValidationMode_(ValidationMode2_0 validationMode) { |
| ValidationMode2_0 old = this.specifiedValidationMode; |
| this.specifiedValidationMode = validationMode; |
| this.firePropertyChanged(SPECIFIED_VALIDATION_MODE_PROPERTY, old, validationMode); |
| } |
| |
| public ValidationMode2_0 getDefaultValidationMode() { |
| return this.defaultValidationMode; |
| } |
| |
| protected void setDefaultValidationMode(ValidationMode2_0 defaultValidationMode) { |
| ValidationMode2_0 old = this.defaultValidationMode; |
| this.defaultValidationMode = defaultValidationMode; |
| this.firePropertyChanged(DEFAULT_VALIDATION_MODE_PROPERTY, old, defaultValidationMode); |
| } |
| |
| protected ValidationMode2_0 buildSpecifiedValidationMode() { |
| return ValidationMode2_0.fromXmlResourceModel(this.xmlPersistenceUnit.getValidationMode()); |
| } |
| |
| protected ValidationMode2_0 buildDefaultValidationMode() { |
| return DEFAULT_VALIDATION_MODE; |
| } |
| |
| |
| // ********** generators ********** |
| |
| public Iterable<Generator> getGenerators() { |
| return IterableTools.cloneLive(this.generators); |
| } |
| |
| public int getGeneratorsSize() { |
| return this.generators.size(); |
| } |
| |
| public Iterable<String> getUniqueGeneratorNames() { |
| return CollectionTools.hashSet(this.getNonEmptyGeneratorNames(), this.getGeneratorsSize()); |
| } |
| |
| protected Iterable<String> getNonEmptyGeneratorNames() { |
| return IterableTools.filter(this.getGeneratorNames(), StringTools.IS_NOT_BLANK); |
| } |
| |
| protected Iterable<String> getGeneratorNames() { |
| return new TransformationIterable<Generator, String>(this.getGenerators(), JpaNamedContextModel.NAME_TRANSFORMER); |
| } |
| |
| protected void setGenerators(Iterable<Generator> generators) { |
| this.synchronizeCollection(generators, this.generators, GENERATORS_COLLECTION); |
| } |
| |
| /** |
| * Generators are much like queries. |
| * @see #buildQueries() |
| */ |
| protected Iterable<Generator> buildGenerators() { |
| ArrayList<Generator> result = ListTools.arrayList(this.getMappingFileGenerators()); |
| |
| HashSet<String> mappingFileGeneratorNames = this.convertToNames(result); |
| HashMap<String, ArrayList<Generator>> allJavaGenerators = this.mapByName(this.getAllJavaGenerators()); |
| for (Map.Entry<String, ArrayList<Generator>> entry : allJavaGenerators.entrySet()) { |
| if ( ! mappingFileGeneratorNames.contains(entry.getKey())) { |
| result.addAll(entry.getValue()); |
| } |
| } |
| |
| return result; |
| } |
| |
| protected Iterable<Generator> getMappingFileGenerators() { |
| return IterableTools.children(this.getMappingFileRefs(), MappingFileRef.MAPPING_FILE_GENERATORS_TRANSFORMER); |
| } |
| |
| /** |
| * Include "overridden" Java generators. |
| */ |
| protected Iterable<Generator> getAllJavaGenerators() { |
| return IterableTools.children(this.getAllJavaTypeMappingsUnique(), TypeMapping.GENERATORS_TRANSFORMER); |
| } |
| |
| // ***** metadata conversion |
| public boolean hasConvertibleJavaGenerators() { |
| return ! this.getConvertibleJavaGenerators().isEmpty(); |
| } |
| |
| public void convertJavaGenerators(EntityMappings entityMappings, IProgressMonitor monitor) { |
| ArrayList<Generator> convertibleJavaGenerators = this.getConvertibleJavaGenerators(); |
| SubMonitor subMonitor = SubMonitor.convert(monitor, JptJpaCoreMessages.JAVA_METADATA_CONVERSION_IN_PROGRESS, convertibleJavaGenerators.size()); |
| for (Generator generator : convertibleJavaGenerators) { |
| this.convertJavaGenerator(entityMappings, (JavaGenerator) generator, subMonitor.newChild(1)); |
| } |
| subMonitor.setTaskName(JptJpaCoreMessages.JAVA_METADATA_CONVERSION_COMPLETE); |
| } |
| |
| protected void convertJavaGenerator(EntityMappings entityMappings, JavaGenerator generator, SubMonitor monitor) { |
| if (monitor.isCanceled()) { |
| throw new OperationCanceledException(JptJpaCoreMessages.JAVA_METADATA_CONVERSION_CANCELED); |
| } |
| monitor.setTaskName(NLS.bind(JptJpaCoreMessages.JAVA_METADATA_CONVERSION_CONVERT_GENERATOR, generator.getName())); |
| generator.convertTo(entityMappings); |
| generator.delete(); // delete any converted generators |
| } |
| |
| protected ArrayList<Generator> getConvertibleJavaGenerators() { |
| return this.extractConvertibleJavaModels(this.getAllJavaGenerators(), this.getMappingFileGenerators()); |
| } |
| |
| |
| // ********** queries ********** |
| |
| public Iterable<Query> getQueries() { |
| return IterableTools.cloneLive(this.queries); |
| } |
| |
| public int getQueriesSize() { |
| return this.queries.size(); |
| } |
| |
| public void addQuery(Query query) { |
| this.queries.add(query); |
| } |
| |
| protected void setQueries(Iterable<Query> queries) { |
| this.synchronizeCollection(queries, this.queries, QUERIES_COLLECTION); |
| } |
| |
| /** |
| * The persistence unit holds only <em>active</em> queries; |
| * i.e. the mapping file queries and the Java queries that are not |
| * "overridden" by mapping file queries (by query name). |
| * <p> |
| * <strong>NB:</strong> The list can contain queries with duplicate names; |
| * either when there are multiple mapping file queries with the same name |
| * or multiple, non-overridden Java queries with the same name. |
| */ |
| protected Iterable<Query> buildQueries() { |
| ArrayList<Query> result = ListTools.arrayList(this.getMappingFileQueries()); |
| |
| HashSet<String> mappingFileQueryNames = this.convertToNames(result); |
| HashMap<String, ArrayList<Query>> allJavaQueries = this.mapByName(this.getAllJavaQueries()); |
| for (Map.Entry<String, ArrayList<Query>> entry : allJavaQueries.entrySet()) { |
| if ( ! mappingFileQueryNames.contains(entry.getKey())) { |
| result.addAll(entry.getValue()); |
| } |
| } |
| |
| return result; |
| } |
| |
| protected Iterable<Query> getMappingFileQueries() { |
| return IterableTools.children(this.getMappingFileRefs(), MappingFileRef.MAPPING_FILE_QUERIES_TRANSFORMER); |
| } |
| |
| /** |
| * Include "overridden" Java queries. |
| */ |
| protected Iterable<Query> getAllJavaQueries() { |
| return IterableTools.children(this.getAllJavaTypeMappingsUnique(), TypeMapping.QUERIES_TRANSFORMER); |
| } |
| |
| protected Iterable<TypeMapping> getAllJavaTypeMappingsUnique() { |
| return IterableTools.transform(this.getAllJavaPersistentTypesUnique(), PersistentType.MAPPING_TRANSFORMER); |
| } |
| |
| // ***** metadata conversion |
| public boolean hasConvertibleJavaQueries() { |
| return ! this.getConvertibleJavaQueries().isEmpty(); |
| } |
| |
| public void convertJavaQueries(EntityMappings entityMappings, IProgressMonitor monitor) { |
| OrmQueryContainer queryContainer = entityMappings.getQueryContainer(); |
| ArrayList<Query> convertibleJavaQueries = this.getConvertibleJavaQueries(); |
| SubMonitor subMonitor = SubMonitor.convert(monitor, JptJpaCoreMessages.JAVA_METADATA_CONVERSION_IN_PROGRESS, convertibleJavaQueries.size()); |
| for (Query query : convertibleJavaQueries) { |
| this.convertJavaQuery(queryContainer, (JavaQuery) query, subMonitor.newChild(1)); |
| } |
| subMonitor.setTaskName(JptJpaCoreMessages.JAVA_METADATA_CONVERSION_COMPLETE); |
| } |
| |
| protected void convertJavaQuery(OrmQueryContainer queryContainer, JavaQuery query, SubMonitor monitor) { |
| if (monitor.isCanceled()) { |
| throw new OperationCanceledException(JptJpaCoreMessages.JAVA_METADATA_CONVERSION_CANCELED); |
| } |
| monitor.setTaskName(NLS.bind(JptJpaCoreMessages.JAVA_METADATA_CONVERSION_CONVERT_QUERY, query.getName())); |
| query.convertTo(queryContainer); |
| query.delete(); // delete any converted queries |
| } |
| |
| protected ArrayList<Query> getConvertibleJavaQueries() { |
| return this.extractConvertibleJavaModels(this.getAllJavaQueries(), this.getMappingFileQueries()); |
| } |
| |
| |
| // ********** managed types ********** |
| |
| @SuppressWarnings("unchecked") |
| public Iterable<ManagedType> getManagedTypes() { |
| return IterableTools.concatenate( |
| this.getMappingFileManagedTypes(), |
| this.getClassRefManagedTypes(), |
| this.getJarFileManagedTypes() |
| ); |
| } |
| |
| protected Iterable<ManagedType> getMappingFileManagedTypes() { |
| return IterableTools.children(this.getMappingFileRefs(), ManagedTypeContainer.TRANSFORMER); |
| } |
| |
| @SuppressWarnings("unchecked") |
| public Iterable<ManagedType> getJavaManagedTypes() { |
| return IterableTools.concatenate( |
| this.getClassRefManagedTypes(), |
| this.getJarFileManagedTypes() |
| ); |
| } |
| |
| /** |
| * Return the non-<code>null</code> class ref managed types, |
| * both specified and implied. |
| */ |
| protected Iterable<ManagedType> getClassRefManagedTypes() { |
| return IterableTools.removeNulls(this.getClassRefManagedTypes_()); |
| } |
| |
| /** |
| * Both specified and implied. May contain <code>null</code>s. |
| * @see #getClassRefManagedTypes() |
| */ |
| protected Iterable<ManagedType> getClassRefManagedTypes_() { |
| return IterableTools.transform(this.getClassRefs(), CLASS_REF_MANAGED_TYPE_TRANSFORMER); |
| } |
| |
| protected static final Transformer<ClassRef, ManagedType> CLASS_REF_MANAGED_TYPE_TRANSFORMER = TransformerTools.upcast(ClassRef.JAVA_MANAGED_TYPE_TRANSFORMER); |
| |
| /** |
| * We only get <em>annotated</em> types from jar files. |
| */ |
| protected Iterable<ManagedType> getJarFileManagedTypes() { |
| return IterableTools.children(this.getJarFileRefs(), ManagedTypeContainer.TRANSFORMER); |
| } |
| |
| public ManagedType getManagedType(String typeName) { |
| return typeName == null ? null : this.managedTypeMap.get(typeName); |
| } |
| |
| protected void rebuildManagedTypeMap() { |
| synchronized (this.managedTypeMap) { |
| this.managedTypeMap.clear(); |
| for (MappingFileRef mappingFileRef : this.getMappingFileRefs()) { |
| for (ManagedType mt : mappingFileRef.getManagedTypes()) { |
| if (mt.getName() != null) { |
| if (! this.managedTypeMap.containsKey(mt.getName())) { |
| this.managedTypeMap.put(mt.getName(), mt); |
| } |
| } |
| } |
| } |
| for (ClassRef classRef : this.getClassRefs()) { |
| ManagedType mt = classRef.getJavaManagedType(); |
| if (mt != null && mt.getName() != null) { |
| if (! this.managedTypeMap.containsKey(mt.getName())) { |
| this.managedTypeMap.put(mt.getName(), mt); |
| } |
| } |
| } |
| for (JarFileRef jarFileRef : this.getJarFileRefs()) { |
| for (ManagedType mt : jarFileRef.getManagedTypes()) { |
| if (mt.getName() != null) { |
| if (! this.managedTypeMap.containsKey(mt.getName())) { |
| this.managedTypeMap.put(mt.getName(), mt); |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| /** |
| * Ignore implied class refs and jar files. |
| */ |
| public boolean specifiesManagedType(String typeName) { |
| for (ClassRef classRef : this.getSpecifiedClassRefs()) { |
| if (classRef.isFor(typeName)) { |
| return true; |
| } |
| } |
| for (MappingFileRef mappingFileRef : this.getMappingFileRefs()) { |
| if (mappingFileRef.getManagedType(typeName) != null) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| /** |
| * Return a list of <em>all</em> the persistence unit's Java persistent |
| * types (including those referenced by the mapping files that are not |
| * marked "metadata complete") with those with duplicate names removed. |
| * Although this may not always be true, assume persistent types with |
| * the same name reference the same Java type. (<strong>NB:</strong> |
| * It's possible that a Java class in a jar file has the same name as a |
| * Java class in the project and they be different....) |
| * <p> |
| * This is really only useful for the calculation of generators and queries, |
| * which can be defined in Java annotations but still be "active" even |
| * though their corresponding Java types/attributes have been overridden in |
| * a mapping file. |
| * <p> |
| * The order of precedence:<ul> |
| * <li>mapping files |
| * <li>persistence unit class refs |
| * <li>jar files |
| * </ul> |
| */ |
| protected Iterable<PersistentType> getAllJavaPersistentTypesUnique() { |
| // order is significant(?) |
| HashMap<String, PersistentType> map = new HashMap<String, PersistentType>(); |
| this.addPersistentTypesTo(this.getJarFilePersistentTypes(), map); |
| this.addPersistentTypesTo(this.getClassRefPersistentTypes(), map); |
| this.addPersistentTypesTo(this.getMappingFileJavaPersistentTypes(), map); |
| return map.values(); |
| } |
| |
| /** |
| * Add the specified persistent types to |
| * the specified map keyed by persistent type name. |
| */ |
| protected void addPersistentTypesTo(Iterable<? extends PersistentType> persistentTypes, HashMap<String, PersistentType> map) { |
| for (PersistentType pt : persistentTypes) { |
| String ptName = pt.getName(); |
| if (ptName != null) { |
| map.put(ptName, pt); |
| } |
| } |
| } |
| |
| /** |
| * Return the non-<code>null</code> mapping file Java persistent types; |
| * i.e. the Java persistent types corresponding to the mapping file |
| * persistent types that are not marked "metadata complete". |
| * @see #getAllJavaPersistentTypesUnique() |
| */ |
| protected Iterable<PersistentType> getMappingFileJavaPersistentTypes() { |
| return IterableTools.removeNulls(this.getMappingFileJavaPersistentTypes_()); |
| } |
| |
| /** |
| * The returned list will contain a <code>null</code> for each mapping file |
| * persistent type that does not correspond to an existing Java type or is |
| * marked "metadata complete". |
| * @see #getMappingFileJavaPersistentTypes() |
| */ |
| protected Iterable<PersistentType> getMappingFileJavaPersistentTypes_() { |
| return IterableTools.transform(this.getMappingFilePersistentTypes(), PersistentType.OVERRIDDEN_PERSISTENT_TYPE_TRANSFORMER); |
| } |
| |
| public Iterable<PersistentType> getPersistentTypes() { |
| return IterableTools.downCast(IterableTools.filter(this.getManagedTypes(), TYPE_IS_PERSISTENT_TYPE)); |
| } |
| |
| protected static final Predicate<ManagedType> TYPE_IS_PERSISTENT_TYPE = new TypeIsPersistentType(); |
| public static class TypeIsPersistentType |
| extends PredicateAdapter<ManagedType> |
| { |
| @Override |
| public boolean evaluate(ManagedType mt) { |
| return mt.getManagedTypeType() == PersistentType.class; |
| } |
| } |
| |
| |
| public PersistentType getPersistentType(String typeName) { |
| ManagedType mt = this.getManagedType(typeName); |
| if ((mt != null) && (mt.getManagedTypeType() == PersistentType.class)) { |
| return (PersistentType) mt; |
| } |
| return null; |
| } |
| |
| protected Iterable<PersistentType> getMappingFilePersistentTypes() { |
| return IterableTools.children(this.getMappingFileRefs(), PersistentTypeContainer.TRANSFORMER); |
| } |
| |
| protected Iterable<PersistentType> getClassRefPersistentTypes() { |
| return IterableTools.downCast(IterableTools.filter( |
| this.getClassRefManagedTypes(), |
| TYPE_IS_PERSISTENT_TYPE)); |
| } |
| |
| protected Iterable<PersistentType> getJarFilePersistentTypes() { |
| return IterableTools.downCast(IterableTools.filter( |
| this.getJarFileManagedTypes(), |
| TYPE_IS_PERSISTENT_TYPE)); |
| } |
| |
| public Iterable<PersistentType> getJavaPersistentTypes() { |
| return IterableTools.downCast(IterableTools.filter( |
| this.getJavaManagedTypes(), |
| TYPE_IS_PERSISTENT_TYPE)); |
| } |
| |
| |
| // ********** type mappings ********** |
| |
| public Entity getEntity(String typeName) { |
| TypeMapping typeMapping = this.getTypeMapping(typeName); |
| return (typeMapping instanceof Entity) ? (Entity) typeMapping : null; |
| } |
| |
| public Embeddable getEmbeddable(String typeName) { |
| TypeMapping typeMapping = this.getTypeMapping(typeName); |
| return (typeMapping instanceof Embeddable) ? (Embeddable) typeMapping : null; |
| } |
| |
| public IdTypeMapping getIdTypeMapping(String typeName) { |
| TypeMapping typeMapping = this.getTypeMapping(typeName); |
| return (typeMapping instanceof IdTypeMapping) ? (IdTypeMapping) typeMapping : null; |
| } |
| |
| // TODO bjv - this should probably *not* return Java type mappings when PU is "metadata complete"... |
| protected TypeMapping getTypeMapping(String typeName) { |
| PersistentType persistentType = this.getPersistentType(typeName); |
| return (persistentType == null) ? null : persistentType.getMapping(); |
| } |
| |
| public Iterable<Entity> getEntities() { |
| return this.filterToEntities(this.getTypeMappings()); |
| } |
| |
| protected Iterable<Entity> filterToEntities(Iterable<TypeMapping> typeMappings) { |
| return new SubIterableWrapper<TypeMapping, Entity>(this.filterToEntities_(typeMappings)); |
| } |
| |
| protected Iterable<TypeMapping> filterToEntities_(Iterable<TypeMapping> typeMappings) { |
| return IterableTools.filter(typeMappings, PredicateTools.<TypeMapping>instanceOf(Entity.class)); |
| } |
| |
| // TODO bjv - this should probably *not* return Java type mappings when PU is "metadata complete"... |
| protected Iterable<TypeMapping> getTypeMappings() { |
| return IterableTools.transform(this.getPersistentTypes(), PersistentType.MAPPING_TRANSFORMER); |
| } |
| |
| /** |
| * Return the "active" entities. |
| * @see #getActiveTypeMappings() |
| */ |
| protected Iterable<Entity> getActiveEntities() { |
| return this.filterToEntities(this.getActiveTypeMappings()); |
| } |
| |
| /** |
| * Return the "active" type mappings, i.e. the mapping file type mappings and |
| * the Java type mappings that are not "overridden" by mapping file |
| * type mappings (by full qualified class name). |
| */ |
| protected Iterable<TypeMapping> getActiveTypeMappings(){ |
| ArrayList<TypeMapping> result = ListTools.arrayList(this.getMappingFileTypeMappings()); |
| |
| HashSet<String> mappingFileClassNames = this.convertToClassNames(result); |
| HashMap<String, ArrayList<TypeMapping>> javaTypeMappings = this.mapTypeMappingsByClassName(this.getJavaTypeMappings()); |
| for (Map.Entry<String, ArrayList<TypeMapping>> entry : javaTypeMappings.entrySet()) { |
| if ( ! mappingFileClassNames.contains(entry.getKey())) { |
| result.addAll(entry.getValue()); |
| } |
| } |
| |
| return result; |
| } |
| |
| /** |
| * Return all the type mappings defined in the persistence unit's mapping |
| * files (i.e. excluding the Java type mappings). |
| */ |
| protected Iterable<TypeMapping> getMappingFileTypeMappings() { |
| return IterableTools.transform(this.getMappingFilePersistentTypes(), PersistentType.MAPPING_TRANSFORMER); |
| } |
| |
| protected HashSet<String> convertToClassNames(Collection<? extends TypeMapping> typeMappings) { |
| HashSet<String> classNames = new HashSet<String>(typeMappings.size()); |
| for (TypeMapping typeMapping : typeMappings) { |
| classNames.add(typeMapping.getPersistentType().getName()); |
| } |
| return classNames; |
| } |
| |
| /** |
| * Return a map of the type mappings keyed by full qualified class name. |
| * Since there can be duplicate (erroneously) class names, |
| * each class name is mapped to a <em>list</em> of type mappings. |
| */ |
| protected <M extends TypeMapping> HashMap<String, ArrayList<M>> mapTypeMappingsByClassName(Iterable<M> typeMappings) { |
| HashMap<String, ArrayList<M>> map = new HashMap<String, ArrayList<M>>(); |
| for (M typeMapping : typeMappings) { |
| String typeMappingName = typeMapping.getPersistentType().getName(); |
| ArrayList<M> list = map.get(typeMappingName); |
| if (list == null) { |
| list = new ArrayList<M>(); |
| map.put(typeMappingName, list); |
| } |
| list.add(typeMapping); |
| } |
| return map; |
| } |
| |
| /** |
| * These may be overridden in the mapping files. |
| * @see #getJavaPersistentTypes() |
| */ |
| protected Iterable<TypeMapping> getJavaTypeMappings() { |
| return IterableTools.transform(this.getJavaPersistentTypes(), PersistentType.MAPPING_TRANSFORMER); |
| } |
| |
| |
| // ********** synchronize classes ********** |
| |
| public void synchronizeClasses(IProgressMonitor monitor) { |
| SubMonitor sm = SubMonitor.convert(monitor, 4); |
| |
| // gather up all the annotated Java types and types listed in the mapping files |
| HashSet<JavaResourceAbstractType> newClasses = CollectionTools.hashSet(this.getJpaProject().getPotentialJavaSourceTypes()); |
| HashSet<String> mappingFileTypeNames = this.getMappingFileTypeNames(); |
| |
| // calculate the class refs to be removed |
| ArrayList<ClassRef> deadClassRefs = new ArrayList<ClassRef>(); |
| for (ClassRef specifiedClassRef : this.getSpecifiedClassRefs()) { |
| JavaManagedType specifiedJMT = specifiedClassRef.getJavaManagedType(); |
| if (specifiedJMT == null) { |
| // specified type cannot be resolved |
| deadClassRefs.add(specifiedClassRef); |
| } else { |
| JavaResourceType specifiedJRT = specifiedJMT.getJavaResourceType(); |
| if ( ! newClasses.remove(specifiedJRT)) { |
| // specified type is resolved but not annotated |
| deadClassRefs.add(specifiedClassRef); |
| } else if (mappingFileTypeNames.contains(specifiedJRT.getTypeBinding().getQualifiedName())) { |
| // specified type is resolved but also listed in a mapping file |
| deadClassRefs.add(specifiedClassRef); |
| } |
| } |
| } |
| |
| // now check for any remaining newly-discovered types that are already listed in a mapping file |
| for (Iterator<JavaResourceAbstractType> stream = newClasses.iterator(); stream.hasNext(); ) { |
| JavaResourceAbstractType javaType = stream.next(); |
| if (mappingFileTypeNames.contains(javaType.getTypeBinding().getQualifiedName())) { |
| stream.remove(); |
| } |
| } |
| if (sm.isCanceled()) { |
| return; |
| } |
| sm.worked(1); |
| |
| this.removeSpecifiedClassRefs(deadClassRefs); |
| if (sm.isCanceled()) { |
| return; |
| } |
| sm.worked(1); |
| |
| this.addSpecifiedClassRefs(newClasses); |
| if (sm.isCanceled()) { |
| return; |
| } |
| sm.worked(1); |
| |
| // any changes to the XML file will update the specified class refs list |
| this.getXmlPersistenceUnit().sortClasses(); |
| sm.worked(1); |
| } |
| |
| /** |
| * Return the names of all the types specified in the persistence unit's |
| * mapping files. |
| */ |
| protected HashSet<String> getMappingFileTypeNames() { |
| HashSet<String> result = new HashSet<String>(); |
| for (MappingFileRef mappingFileRef : this.getMappingFileRefs()) { |
| for (ManagedType managedType : mappingFileRef.getManagedTypes()) { |
| result.add(managedType.getName()); |
| } |
| } |
| return result; |
| } |
| |
| // ********** add persistent types ********** |
| |
| /** |
| * Annotate the given types with the given mapping key |
| * Specify the types in the persistence.xml if listInPersistenceXml is true. |
| */ |
| public void addPersistentTypes(PersistentType.Config[] typeConfigs, boolean listInPersistenceXml, IProgressMonitor pm) { |
| SubMonitor sm = SubMonitor.convert(pm, 10); |
| this.annotateClasses(typeConfigs, sm.newChild(6)); |
| if (listInPersistenceXml) { |
| this.listInPersistenceXml(typeConfigs, sm.newChild(4)); |
| } else { |
| sm.subTask(JptJpaCoreMessages.MAKE_PERSISTENT_UPDATING_JPA_MODEL); |
| //TODO have to call this since I am modifying only the Java resource model |
| //in the non-'list in persisistence.xml' case |
| this.getJpaProject().synchronizeContextModel(); |
| sm.worked(4); |
| } |
| } |
| |
| protected void annotateClasses(PersistentType.Config[] typeConfigs, IProgressMonitor pm) { |
| SubMonitor sm = SubMonitor.convert(pm, typeConfigs.length); |
| sm.setTaskName(JptJpaCoreMessages.MAKE_PERSISTENT_PROCESSING_JAVA_CLASSES); |
| // TODO modify the context model - need to have API for creating a JavaPersistentType with a given mappingKey. |
| // be careful not to modify the context model in such a way that you end up with updates being run for |
| // every persistent type added. |
| for (PersistentType.Config typeConfig : typeConfigs) { |
| if (sm.isCanceled()) { |
| return; |
| } |
| String typeName = typeConfig.getName(); |
| sm.subTask(NLS.bind(JptJpaCoreMessages.MAKE_PERSISTENT_ANNOTATING_CLASS, typeName)); |
| JavaResourceAbstractType type = this.getJpaProject().getJavaResourceType(typeName); |
| type.addAnnotation(this.getJavaTypeMappingDefinition(typeConfig.getMappingKey()).getAnnotationName()); |
| sm.worked(1); |
| } |
| } |
| |
| protected void listInPersistenceXml(PersistentType.Config[] typeConfigs, IProgressMonitor pm) { |
| SubMonitor sm = SubMonitor.convert(pm, 11); |
| sm.setTaskName(JptJpaCoreMessages.MAKE_PERSISTENT_LISTING_IN_PERSISTENCE_XML); |
| Collection<XmlJavaClassRef> addedXmlClassRefs = new ArrayList<XmlJavaClassRef>(); |
| Collection<ClassRef> addedClassRefs = new ArrayList<ClassRef>(); |
| for (PersistentType.Config typeConfig : typeConfigs) { |
| String typeName = typeConfig.getName(); |
| XmlJavaClassRef xmlClassRef = this.buildXmlJavaClassRef(typeName); |
| addedXmlClassRefs.add(xmlClassRef); |
| addedClassRefs.add(this.buildClassRef(xmlClassRef)); |
| } |
| if (sm.isCanceled()) { |
| return; |
| } |
| sm.worked(1); |
| sm.subTask(JptJpaCoreMessages.MAKE_PERSISTENT_UPDATING_JPA_MODEL); |
| this.specifiedClassRefContainer.addAll(this.getSpecifiedClassRefsSize(), addedClassRefs); |
| sm.worked(5); |
| sm.subTask(JptJpaCoreMessages.MAKE_PERSISTENT_ADD_TO_PERSISTENCE_XML_RESOURCE_MODEL); |
| this.xmlPersistenceUnit.getClasses().addAll(addedXmlClassRefs); |
| sm.worked(5); |
| } |
| |
| protected JavaTypeMappingDefinition getJavaTypeMappingDefinition(String key) { |
| for (JavaTypeMappingDefinition definition : this.getJpaPlatform().getJavaTypeMappingDefinitions()) { |
| if (ObjectTools.equals(definition.getKey(), key)) { |
| return definition; |
| } |
| } |
| throw new IllegalArgumentException("Illegal type mapping key: " + key); //$NON-NLS-1$ |
| } |
| |
| |
| // ********** add classes to persistence unit ********** |
| |
| public void addClasses(Iterable<String> classNames, IProgressMonitor monitor) { |
| SubMonitor sm = SubMonitor.convert(monitor, IterableTools.size(classNames)); |
| for (String className : classNames) { |
| if(!classRefExists(className)) { |
| this.addSpecifiedClassRef(className); |
| } |
| sm.worked(1); |
| } |
| if (sm.isCanceled()) { |
| return; |
| } |
| |
| this.getXmlPersistenceUnit().sortClasses(); |
| sm.worked(1); |
| } |
| |
| private boolean classRefExists(String className) { |
| for (ClassRef classRef : this.getSpecifiedClassRefs()) { |
| if( classRef.getClassName().equals(className)) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| // ********** misc ********** |
| |
| public XmlPersistenceUnit getXmlPersistenceUnit() { |
| return this.xmlPersistenceUnit; |
| } |
| |
| protected HashSet<String> convertToNames(Collection<? extends JpaNamedContextModel> nodes) { |
| HashSet<String> names = new HashSet<String>(nodes.size()); |
| for (JpaNamedContextModel node : nodes) { |
| names.add(node.getName()); |
| } |
| return names; |
| } |
| |
| protected <N extends JpaNamedContextModel> HashMap<String, ArrayList<N>> mapByName(Iterable<N> nodes) { |
| HashMap<String, ArrayList<N>> map = new HashMap<String, ArrayList<N>>(); |
| for (N node : nodes) { |
| String nodeName = node.getName(); |
| ArrayList<N> list = map.get(nodeName); |
| if (list == null) { |
| list = new ArrayList<N>(); |
| map.put(nodeName, list); |
| } |
| list.add(node); |
| } |
| return map; |
| } |
| |
| /** |
| * Return the Java models that are neither overridden nor duplicated |
| * (by default any Java models with the same name are "duplicates"). |
| */ |
| protected <M extends JpaNamedContextModel> ArrayList<M> extractConvertibleJavaModels(Iterable<M> allJavaModels, Iterable<M> mappingFileModels) { |
| ArrayList<M> convertibleModels = new ArrayList<M>(); |
| |
| HashSet<String> mappingFileModelNames = this.convertToNames(ListTools.arrayList(mappingFileModels)); |
| HashMap<String, ArrayList<M>> allJavaModelsByName = this.mapByName(allJavaModels); |
| for (Map.Entry<String, ArrayList<M>> entry : allJavaModelsByName.entrySet()) { |
| String javaModelName = entry.getKey(); |
| if (StringTools.isBlank(javaModelName)) { |
| continue; // ignore any nodes with an empty name(?) |
| } |
| ArrayList<M> javaModelsWithSameName = entry.getValue(); |
| if ((javaModelsWithSameName.size() == 1) && ! mappingFileModelNames.contains(javaModelName)) { |
| convertibleModels.add(javaModelsWithSameName.get(0)); |
| } |
| } |
| |
| return convertibleModels; |
| } |
| |
| @Override |
| public void toString(StringBuilder sb) { |
| super.toString(sb); |
| sb.append(this.name); |
| } |
| |
| public Iterable<String> getPackageNames() { |
| Set<String> packageNames = new HashSet<String>(); |
| for (ManagedType mType : this.getJavaManagedTypes()) { |
| JavaResourceType jrt = mType.getJavaResourceType(); |
| packageNames.add(jrt.getTypeBinding().getPackageName()); |
| } |
| return packageNames; |
| } |
| |
| // ********** validation ********** |
| |
| @Override |
| public void validate(List<IMessage> messages, IReporter reporter) { |
| super.validate(messages, reporter); |
| this.validateMappingFiles(messages, reporter); |
| this.validateClassRefs(messages, reporter); |
| this.validateJarFileRefs(messages, reporter); |
| this.validateProperties(messages, reporter); |
| this.validateGenerators(messages, reporter); |
| this.validateQueries(messages, reporter); |
| this.validateEntityNames(messages); |
| } |
| |
| protected void validateMappingFiles(List<IMessage> messages, IReporter reporter) { |
| this.checkForMultiplePersistenceUnitMetadata(messages); |
| this.checkForDuplicateMappingFileRefs(messages); |
| for (MappingFileRef mappingFileRef : this.getMappingFileRefs()) { |
| mappingFileRef.validate(messages, reporter); |
| } |
| this.checkForDuplicateMappingFileClasses(messages); |
| } |
| |
| protected void checkForMultiplePersistenceUnitMetadata(List<IMessage> messages) { |
| ArrayList<MappingFileRef> pumdMappingFileRefs = ListTools.arrayList(this.getPersistenceUnitMetadataMappingFileRefs()); |
| if (pumdMappingFileRefs.size() > 1) { |
| for (MappingFileRef mappingFileRef : pumdMappingFileRefs) { |
| messages.add( |
| this.buildValidationMessage( |
| mappingFileRef.getMappingFile(), |
| mappingFileRef.getPersistenceUnitMetadata().getValidationTextRange(), |
| JptJpaCoreValidationMessages.MAPPING_FILE_EXTRANEOUS_PERSISTENCE_UNIT_METADATA, |
| mappingFileRef.getFileName() |
| ) |
| ); |
| } |
| } |
| } |
| |
| protected Iterable<MappingFileRef> getPersistenceUnitMetadataMappingFileRefs() { |
| return IterableTools.filter(this.getMappingFileRefs(), MappingFileRef.PERSISTENCE_UNIT_METADATA_EXISTS); |
| } |
| |
| protected void checkForDuplicateMappingFileRefs(List<IMessage> messages) { |
| for (Map.Entry<String, ArrayList<MappingFileRef>> entry : this.mapMappingFileRefsByFileName().entrySet()) { |
| String fileName = entry.getKey(); |
| if (StringTools.isNotBlank(fileName)) { |
| ArrayList<MappingFileRef> dups = entry.getValue(); |
| if (dups.size() > 1) { |
| for (MappingFileRef dup : dups) { |
| messages.add( |
| this.buildValidationMessage( |
| dup, |
| dup.getValidationTextRange(), |
| JptJpaCoreValidationMessages.PERSISTENCE_UNIT_DUPLICATE_MAPPING_FILE, |
| fileName |
| ) |
| ); |
| } |
| } |
| } |
| } |
| } |
| |
| /** |
| * Return the persistence unit's mapping file refs, both default and |
| * specified, keyed by their file names. |
| */ |
| protected HashMap<String, ArrayList<MappingFileRef>> mapMappingFileRefsByFileName() { |
| HashMap<String, ArrayList<MappingFileRef>> map = new HashMap<String, ArrayList<MappingFileRef>>(this.getMappingFileRefsSize()); |
| for (MappingFileRef mappingFileRef : this.getMappingFileRefs()) { |
| String fileName = mappingFileRef.getFileName(); |
| ArrayList<MappingFileRef> list = map.get(fileName); |
| if (list == null) { |
| list = new ArrayList<MappingFileRef>(); |
| map.put(fileName, list); |
| } |
| list.add(mappingFileRef); |
| } |
| return map; |
| } |
| |
| protected void checkForDuplicateMappingFileClasses(List<IMessage> messages) { |
| for (Map.Entry<String, ArrayList<ManagedType>> entry : this.mapMappingFileManagedTypesByName().entrySet()) { |
| String mtName = entry.getKey(); |
| if (StringTools.isNotBlank(mtName)) { |
| ArrayList<ManagedType> dups = entry.getValue(); |
| if (dups.size() > 1) { |
| for (ManagedType dup : dups) { |
| messages.add( |
| this.buildValidationMessage( |
| dup, |
| dup.getValidationTextRange(), |
| JptJpaCoreValidationMessages.PERSISTENT_TYPE_DUPLICATE_CLASS, |
| mtName |
| ) |
| ); |
| } |
| } |
| } |
| } |
| } |
| |
| /** |
| * Return the persistence unit's mapping file managed types |
| * keyed by their class names. |
| */ |
| protected HashMap<String, ArrayList<ManagedType>> mapMappingFileManagedTypesByName() { |
| HashMap<String, ArrayList<ManagedType>> map = new HashMap<String, ArrayList<ManagedType>>(); |
| for (ManagedType managedType : this.getMappingFileManagedTypes()) { |
| String mtName = managedType.getName(); |
| ArrayList<ManagedType> list = map.get(mtName); |
| if (list == null) { |
| list = new ArrayList<ManagedType>(); |
| map.put(mtName, list); |
| } |
| list.add(managedType); |
| } |
| return map; |
| } |
| |
| protected void validateClassRefs(List<IMessage> messages, IReporter reporter) { |
| this.checkForDuplicateClassRefs(messages); |
| for (ClassRef classRef : this.getClassRefs()) { |
| classRef.validate(messages, reporter); |
| } |
| } |
| |
| protected void checkForDuplicateClassRefs(List<IMessage> messages) { |
| for (Map.Entry<String, ArrayList<ClassRef>> entry : this.mapClassRefsByName().entrySet()) { |
| String className = entry.getKey(); |
| if (StringTools.isNotBlank(className)) { |
| ArrayList<ClassRef> dups = entry.getValue(); |
| if (dups.size() > 1) { |
| for (ClassRef dup : dups) { |
| messages.add( |
| this.buildValidationMessage( |
| dup, |
| dup.getValidationTextRange(), |
| JptJpaCoreValidationMessages.PERSISTENCE_UNIT_DUPLICATE_CLASS, |
| className |
| ) |
| ); |
| } |
| } |
| } |
| } |
| } |
| |
| /** |
| * Return the persistence unit's class refs, both specified and implied, |
| * keyed by their class names. |
| */ |
| protected HashMap<String, ArrayList<ClassRef>> mapClassRefsByName() { |
| HashMap<String, ArrayList<ClassRef>> map = new HashMap<String, ArrayList<ClassRef>>(this.getClassRefsSize()); |
| for (ClassRef classRef : this.getClassRefs()) { |
| String refName = classRef.getClassName(); |
| ArrayList<ClassRef> list = map.get(refName); |
| if (list == null) { |
| list = new ArrayList<ClassRef>(); |
| map.put(refName, list); |
| } |
| list.add(classRef); |
| } |
| return map; |
| } |
| |
| protected void validateJarFileRefs(List<IMessage> messages, IReporter reporter) { |
| this.checkForDuplicateJarFileRefs(messages); |
| for (JarFileRef jarFileRef : this.getJarFileRefs()) { |
| jarFileRef.validate(messages, reporter); |
| } |
| } |
| |
| protected void checkForDuplicateJarFileRefs(List<IMessage> messages) { |
| for (Map.Entry<String, ArrayList<JarFileRef>> entry : this.mapJarFileRefsByName().entrySet()) { |
| String fileName = entry.getKey(); |
| if (StringTools.isNotBlank(fileName)) { |
| ArrayList<JarFileRef> dups = entry.getValue(); |
| if (dups.size() > 1) { |
| for (JarFileRef dup : dups) { |
| messages.add( |
| this.buildValidationMessage( |
| dup, |
| dup.getValidationTextRange(), |
| JptJpaCoreValidationMessages.PERSISTENCE_UNIT_DUPLICATE_JAR_FILE, |
| fileName |
| ) |
| ); |
| } |
| } |
| } |
| } |
| } |
| |
| /** |
| * Return the persistence unit's jar file refs |
| * keyed by their file names. |
| */ |
| protected HashMap<String, ArrayList<JarFileRef>> mapJarFileRefsByName() { |
| HashMap<String, ArrayList<JarFileRef>> map = new HashMap<String, ArrayList<JarFileRef>>(this.getJarFileRefsSize()); |
| for (JarFileRef jarFileRef : this.getJarFileRefs()) { |
| String refName = jarFileRef.getFileName(); |
| ArrayList<JarFileRef> list = map.get(refName); |
| if (list == null) { |
| list = new ArrayList<JarFileRef>(); |
| map.put(refName, list); |
| } |
| list.add(jarFileRef); |
| } |
| return map; |
| } |
| |
| protected abstract void validateProperties(List<IMessage> messages, IReporter reporter); |
| |
| /** |
| * We validate generators here because Java persistent types that are |
| * overridden in the <code>orm.xml</code> file are |
| * not validated, but they may contain generators that are still "active" |
| * and need to be validated |
| * (i.e. a generator is <em>not</em> overridden when its entity or ID |
| * mapping is overridden in the <code>orm.xml</code> file). |
| * <p> |
| * <strong>NB:</strong> <em>Any</em> <code>orm.xml</code> generator can |
| * override <em>any</em> Java generator with the same name; they need not |
| * be defined on the same entity or ID mapping. Just a bit inconsistent with |
| * the typical "override" in JPA.... |
| */ |
| protected void validateGenerators(List<IMessage> messages, IReporter reporter) { |
| this.checkForGeneratorsWithSameName(messages); |
| for (Generator generator : this.getGenerators()) { |
| this.validate(generator, messages, reporter); |
| } |
| } |
| |
| protected void checkForGeneratorsWithSameName(List<IMessage> messages) { |
| HashMap<String, ArrayList<Generator>> generatorsByName = this.mapByName(this.getGenerators()); |
| for (Map.Entry<String, ArrayList<Generator>> entry : generatorsByName.entrySet()) { |
| String generatorName = entry.getKey(); |
| if (StringTools.isNotBlank(generatorName)) { // ignore empty names |
| ArrayList<Generator> dups = entry.getValue(); |
| if (dups.size() > 1) { |
| this.validateGeneratorsWithSameName(generatorName, dups, messages); |
| } |
| } |
| } |
| } |
| |
| /** |
| * All the specified generators have the same specified name. |
| * Mark them appropriately. |
| */ |
| protected void validateGeneratorsWithSameName(String generatorName, ArrayList<Generator> dups, List<IMessage> messages) { |
| for (Generator dup : dups) { |
| if (dup.supportsValidationMessages()) { |
| messages.add( |
| this.buildValidationMessage( |
| dup, |
| dup.getNameTextRange(), |
| JptJpaCoreValidationMessages.GENERATOR_DUPLICATE_NAME, |
| generatorName |
| ) |
| ); |
| } |
| } |
| } |
| |
| protected void validate(Generator generator, List<IMessage> messages, IReporter reporter) { |
| if (generator.supportsValidationMessages()) { |
| generator.validate(messages, reporter); |
| } |
| } |
| |
| /** |
| * <strong>NB:</strong> We validate queries here. |
| * @see #validateGenerators(List, IReporter) |
| */ |
| protected void validateQueries(List<IMessage> messages, IReporter reporter) { |
| this.checkForQueriesWithSameName(messages); |
| |
| JpaJpqlQueryHelper queryHelper = this.createJpqlQueryHelper(); |
| |
| for (Query query : this.getQueries()) { |
| this.validate(query, queryHelper, messages, reporter); |
| } |
| } |
| |
| protected void checkForQueriesWithSameName(List<IMessage> messages) { |
| HashMap<String, ArrayList<Query>> queriesByName = this.mapByName(this.getQueries()); |
| for (Map.Entry<String, ArrayList<Query>> entry : queriesByName.entrySet()) { |
| String queryName = entry.getKey(); |
| if (StringTools.isNotBlank(queryName)) { // ignore empty names |
| ArrayList<Query> dups = entry.getValue(); |
| if (dups.size() > 1) { |
| this.validateQueriesWithSameName(queryName, dups, messages); |
| } |
| } |
| } |
| } |
| |
| protected void validateQueriesWithSameName(String queryName, ArrayList<Query> dups, List<IMessage> messages) { |
| for (Query dup : dups) { |
| if (dup.supportsValidationMessages()) { |
| messages.add( |
| this.buildValidationMessage( |
| dup, |
| dup.getNameTextRange(), |
| JptJpaCoreValidationMessages.QUERY_DUPLICATE_NAME, |
| queryName |
| ) |
| ); |
| } |
| } |
| } |
| |
| protected void validate(Query query, JpaJpqlQueryHelper queryHelper, List<IMessage> messages, IReporter reporter) { |
| if (query.supportsValidationMessages()) { |
| query.validate(queryHelper, messages, reporter); |
| } |
| } |
| |
| protected void validateEntityNames(List<IMessage> messages) { |
| for (Map.Entry<String, ArrayList<Entity>> entry : this.mapTypeMappingsByName(this.getActiveEntities()).entrySet()) { |
| String entityName = entry.getKey(); |
| if (StringTools.isNotBlank(entityName)) { |
| ArrayList<Entity> dups = entry.getValue(); |
| if (dups.size() > 1) { |
| this.validateEntitiesWithSameName(entityName, dups, messages); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Return a map of the type mappings keyed by type mapping name (typically |
| * the short class name). |
| * Since there can be (erroneously) duplicate type mapping names, |
| * each type mapping name is mapped to a <em>list</em> of type mappings. |
| */ |
| protected <M extends TypeMapping> HashMap<String, ArrayList<M>> mapTypeMappingsByName(Iterable<M> typeMappings) { |
| HashMap<String, ArrayList<M>> map = new HashMap<String, ArrayList<M>>(); |
| for (M typeMapping : typeMappings) { |
| String typeMappingName = typeMapping.getName(); |
| ArrayList<M> list = map.get(typeMappingName); |
| if (list == null) { |
| list = new ArrayList<M>(); |
| map.put(typeMappingName, list); |
| } |
| list.add(typeMapping); |
| } |
| return map; |
| } |
| |
| protected void validateEntitiesWithSameName(String entityName, ArrayList<Entity> dups, List<IMessage> messages) { |
| for (Entity dup : dups) { |
| if (dup.supportsValidationMessages()) { |
| messages.add( |
| this.buildValidationMessage( |
| dup, |
| dup.getNameTextRange(), |
| JptJpaCoreValidationMessages.ENTITY_NAME_DUPLICATED, |
| entityName |
| ) |
| ); |
| } |
| } |
| } |
| |
| public boolean validatesAgainstDatabase() { |
| return this.connectionProfileIsActive(); |
| } |
| |
| public TextRange getValidationTextRange() { |
| TextRange textRange = this.xmlPersistenceUnit.getValidationTextRange(); |
| return (textRange != null) ? textRange : this.getPersistence().getValidationTextRange(); |
| } |
| |
| |
| // ********** refactoring ********** |
| |
| public Iterable<DeleteEdit> createDeleteTypeEdits(final IType type) { |
| return IterableTools.children(this.getSpecifiedClassRefs(), new DeleteTypeRefactoringParticipant.DeleteTypeEditsTransformer(type)); |
| } |
| |
| public Iterable<DeleteEdit> createDeleteMappingFileEdits(IFile file) { |
| return IterableTools.children(this.getSpecifiedMappingFileRefs(), new MappingFileRefactoringParticipant.DeleteMappingFileEditsTransformer(file)); |
| } |
| |
| @SuppressWarnings("unchecked") |
| public Iterable<ReplaceEdit> createRenameTypeEdits(IType originalType, String newName) { |
| return IterableTools.concatenate( |
| this.createSpecifiedClassRefRenameTypeEdits(originalType, newName), |
| this.createPersistenceUnitPropertiesRenameTypeEdits(originalType, newName)); |
| } |
| |
| protected Iterable<ReplaceEdit> createSpecifiedClassRefRenameTypeEdits(IType originalType, String newName) { |
| return IterableTools.children(this.getSpecifiedClassRefs(), new TypeRefactoringParticipant.RenameTypeEditsTransformer(originalType, newName)); |
| } |
| |
| protected Iterable<ReplaceEdit> createPersistenceUnitPropertiesRenameTypeEdits(IType originalType, String newName) { |
| return this.options.createRenameTypeEdits(originalType, newName); |
| } |
| |
| @SuppressWarnings("unchecked") |
| public Iterable<ReplaceEdit> createMoveTypeEdits(IType originalType, IPackageFragment newPackage) { |
| return IterableTools.concatenate( |
| this.createSpecifiedClassRefMoveTypeEdits(originalType, newPackage), |
| this.createPersistenceUnitPropertiesMoveTypeEdits(originalType, newPackage)); |
| } |
| |
| protected Iterable<ReplaceEdit> createSpecifiedClassRefMoveTypeEdits(IType originalType, IPackageFragment newPackage) { |
| return IterableTools.children(this.getSpecifiedClassRefs(), new TypeRefactoringParticipant.MoveTypeEditsTransformer(originalType, newPackage)); |
| } |
| |
| protected Iterable<ReplaceEdit> createPersistenceUnitPropertiesMoveTypeEdits(IType originalType, IPackageFragment newPackage) { |
| return this.options.createMoveTypeEdits(originalType, newPackage); |
| } |
| |
| |
| @SuppressWarnings("unchecked") |
| public Iterable<ReplaceEdit> createRenamePackageEdits(IPackageFragment originalPackage, String newName) { |
| return IterableTools.concatenate( |
| this.createSpecifiedClassRefRenamePackageEdits(originalPackage, newName), |
| this.createPersistenceUnitPropertiesRenamePackageEdits(originalPackage, newName)); |
| } |
| |
| protected Iterable<ReplaceEdit> createSpecifiedClassRefRenamePackageEdits(IPackageFragment originalPackage, String newName) { |
| return IterableTools.children(this.getSpecifiedClassRefs(), new TypeRefactoringParticipant.RenamePackageEditsTransformer(originalPackage, newName)); |
| } |
| |
| protected Iterable<ReplaceEdit> createPersistenceUnitPropertiesRenamePackageEdits(IPackageFragment originalPackage, String newName) { |
| return this.options.createRenamePackageEdits(originalPackage, newName); |
| } |
| |
| public Iterable<ReplaceEdit> createRenameFolderEdits(final IFolder originalFolder, final String newName) { |
| return this.createMappingFileRefRenameFolderEdits(originalFolder, newName); |
| } |
| |
| protected Iterable<ReplaceEdit> createMappingFileRefRenameFolderEdits(IFolder originalFolder, String newName) { |
| return IterableTools.children(this.getSpecifiedMappingFileRefs(), new MappingFileRefactoringParticipant.RenameFolderEditsTransformer(originalFolder, newName)); |
| } |
| |
| public Iterable<ReplaceEdit> createRenameMappingFileEdits(IFile originalFile, String newName) { |
| return IterableTools.children(this.getSpecifiedMappingFileRefs(), new MappingFileRefactoringParticipant.RenameMappingFileEditsTransformer(originalFile, newName)); |
| } |
| |
| public int findInsertLocationForMappingFileRef() { |
| return this.xmlPersistenceUnit.getLocationToInsertMappingFileRef(); |
| } |
| |
| public Iterable<ReplaceEdit> createMoveMappingFileEdits(IFile originalFile, IPath destination) { |
| return IterableTools.children(this.getMappingFileRefs(), new MappingFileRefactoringParticipant.MoveMappingFileEditsTransformer(originalFile, destination)); |
| } |
| |
| public Iterable<ReplaceEdit> createMoveFolderEdits(final IFolder originalFolder, final IPath runtimeDestination) { |
| return this.createMappingFileRefMoveFolderReplaceEdits(originalFolder, runtimeDestination); |
| } |
| |
| protected Iterable<ReplaceEdit> createMappingFileRefMoveFolderReplaceEdits(IFolder originalFolder, IPath destination) { |
| return IterableTools.children(this.getMappingFileRefs(), new MappingFileRefactoringParticipant.MoveFolderEditsTransformer(originalFolder, destination)); |
| } |
| |
| |
| // ********** metamodel ********** |
| // put metamodel stuff here so it can be shared by Generic and EclipseLink implementations |
| |
| public void initializeMetamodel() { |
| this.initializeMetamodelFiles_(); |
| } |
| |
| protected void initializeMetamodelFiles() { |
| if (this.isJpa2_0Compatible()) { |
| this.initializeMetamodelFiles_(); |
| } |
| } |
| |
| protected void initializeMetamodelFiles_() { |
| CollectionTools.addAll(this.metamodelFiles, this.getGeneratedMetamodelFiles()); |
| } |
| |
| protected Iterable<IFile> getGeneratedMetamodelFiles() { |
| return IterableTools.transform(this.getGeneratedMetamodelTopLevelTypes(), JavaResourceModel.FILE_TRANSFORMER); |
| } |
| |
| protected Iterable<JavaResourceAbstractType> getGeneratedMetamodelTopLevelTypes() { |
| return ((JpaProject2_0) this.getJpaProject()).getGeneratedMetamodelTopLevelTypes(); |
| } |
| |
| /** |
| * Not the prettiest code.... |
| */ |
| // TODO check monitor for cancel |
| public IStatus synchronizeMetamodel(IProgressMonitor monitor) { |
| HashMap<String, PersistentType> allPersistentTypes = this.getMetamodelPersistentTypes(); |
| |
| // build a list of the top-level types and a tree of their associated |
| // member types etc. |
| ArrayList<MetamodelSourceType2_0> topLevelTypes = new ArrayList<MetamodelSourceType2_0>(allPersistentTypes.size()); |
| HashMap<String, Collection<MetamodelSourceType2_0>> memberTypeTree = new HashMap<String, Collection<MetamodelSourceType2_0>>(); |
| for (PersistentType type1_0 : allPersistentTypes.values()) { |
| PersistentType2_0 type = (PersistentType2_0) type1_0; |
| String declaringTypeName = type.getDeclaringTypeName(); |
| MetamodelSourceType2_0 memberType = type; |
| while (true) { |
| if (declaringTypeName == null) { |
| topLevelTypes.add(memberType); |
| break; // stop at the top-level type |
| } |
| |
| // associate the member type with its declaring type |
| Collection<MetamodelSourceType2_0> memberTypes = memberTypeTree.get(declaringTypeName); |
| if (memberTypes == null) { |
| memberTypes = new ArrayList<MetamodelSourceType2_0>(); |
| memberTypeTree.put(declaringTypeName, memberTypes); |
| } |
| memberTypes.add(memberType); |
| |
| // move out to the member type's declaring type |
| String memberTypeName = declaringTypeName; |
| // check for a context persistent type |
| memberType = (PersistentType2_0) allPersistentTypes.get(memberTypeName); |
| if (memberType != null) { |
| break; // stop - this will be processed in the outer 'for' loop |
| } |
| // check for a Java resource persistent type |
| JavaResourceAbstractType jrat = this.getJpaProject().getJavaResourceType(memberTypeName); |
| if (jrat != null) { |
| declaringTypeName = jrat.getDeclaringTypeName(); |
| } else { |
| // check for a JDT type |
| IType jdtType = this.findJdtType(memberTypeName); |
| if (jdtType != null) { |
| IType jdtDeclaringType = jdtType.getDeclaringType(); |
| declaringTypeName = (jdtDeclaringType == null) ? null : jdtDeclaringType.getFullyQualifiedName('.'); |
| } else { |
| // assume we have a non-persistent top-level type...? |
| declaringTypeName = null; |
| } |
| } |
| if (declaringTypeName == null) { |
| memberType = this.selectSourceType(topLevelTypes, memberTypeName); |
| } else { |
| memberType = this.selectSourceType(memberTypeTree.get(declaringTypeName), memberTypeName); |
| } |
| if (memberType != null) { |
| break; // stop - this type has already been processed |
| } |
| memberType = this.buildNonPersistentMetamodelSourceType(memberTypeName); |
| } |
| } |
| |
| // remove any top-level type whose name differs from another only by case, |
| // since, on Windows, file names are case-insensitive :-( |
| // sort the original list so we end up with the same top-level type |
| // remaining every time (i.e. the one that sorts out first) |
| Collections.sort(topLevelTypes, MetamodelSourceType2_0.COMPARATOR); |
| HashSet<String> names = new HashSet<String>(topLevelTypes.size()); |
| for (Iterator<MetamodelSourceType2_0> stream = topLevelTypes.iterator(); stream.hasNext(); ) { |
| MetamodelSourceType2_0 topLevelType = stream.next(); |
| // hopefully this is case-insensitive enough... |
| if ( ! names.add(topLevelType.getName().toLowerCase())) { |
| stream.remove(); |
| } |
| } |
| |
| // copy the list of metamodel files... |
| HashSet<IFile> deadMetamodelFiles = new HashSet<IFile>(this.metamodelFiles); |
| this.metamodelFiles.clear(); |
| for (MetamodelSourceType2_0 topLevelType : topLevelTypes) { |
| IFile metamodelFile = topLevelType.getMetamodelFile(); |
| // ...remove whatever files are still present... |
| deadMetamodelFiles.remove(metamodelFile); |
| // ...rebuild the list of metamodel files... |
| if (this.fileIsGeneratedMetamodel(metamodelFile)) { // only add files with the Dali tag |
| this.metamodelFiles.add(metamodelFile); |
| } |
| } |
| // ...delete the files that are now gone |
| // [perform the deletes first - this is critical when a file has been |
| // renamed by only altering its name's case; since we will try to write |
| // out a new file that, on Windows, collides with the old file :-( ] |
| for (IFile deadMetamodelFile : deadMetamodelFiles) { |
| this.deleteMetamodelFile(deadMetamodelFile); |
| } |
| |
| // now generate the metamodel classes |
| for (MetamodelSourceType2_0 topLevelType : topLevelTypes) { |
| topLevelType.synchronizeMetamodel(memberTypeTree); |
| } |
| return Status.OK_STATUS; |
| } |
| |
| /** |
| * Gather up the persistent unit's types, eliminating duplicates; |
| * if we have persistent types with the same name in multiple locations, |
| * the last one we encounter wins |
| * (i.e. the classes in the <code>orm.xml</code> take precedence) |
| */ |
| protected HashMap<String, PersistentType> getMetamodelPersistentTypes() { |
| HashMap<String, PersistentType> allPersistentTypes = new HashMap<String, PersistentType>(); |
| this.addPersistentTypesTo(this.getMetamodelJarFilePersistentTypes(), allPersistentTypes); |
| this.addPersistentTypesTo(this.getMetamodelClassRefPersistentTypes(), allPersistentTypes); |
| this.addPersistentTypesTo(this.getMetamodelMappingFilePersistentTypes(), allPersistentTypes); |
| return allPersistentTypes; |
| } |
| |
| /** |
| * Remove any types that are not to be used in the metamodel. |
| * @see PersistentType2_0#getMetamodelType() |
| */ |
| protected Iterable<PersistentType2_0> getMetamodelJarFilePersistentTypes() { |
| return IterableTools.removeNulls(IterableTools.transform(this.getJarFilePersistentTypes2_0(), PersistentType2_0.METAMODEL_TYPE_TRANSFORMER)); |
| } |
| |
| protected Iterable<PersistentType2_0> getJarFilePersistentTypes2_0() { |
| return IterableTools.downCast(this.getJarFilePersistentTypes()); |
| } |
| |
| /** |
| * Remove any types that are not to be used in the metamodel. |
| * @see PersistentType2_0#getMetamodelType() |
| */ |
| protected Iterable<PersistentType2_0> getMetamodelClassRefPersistentTypes() { |
| return IterableTools.removeNulls(IterableTools.transform(this.getClassRefPersistentTypes2_0(), PersistentType2_0.METAMODEL_TYPE_TRANSFORMER)); |
| } |
| |
| protected Iterable<PersistentType2_0> getClassRefPersistentTypes2_0() { |
| return IterableTools.downCast(this.getClassRefPersistentTypes()); |
| } |
| |
| /** |
| * Remove any types that are not to be used in the metamodel. |
| * @see PersistentType2_0#getMetamodelType() |
| */ |
| protected Iterable<PersistentType2_0> getMetamodelMappingFilePersistentTypes() { |
| return IterableTools.removeNulls(IterableTools.transform(this.getMappingFilePersistentTypes2_0(), PersistentType2_0.METAMODEL_TYPE_TRANSFORMER)); |
| } |
| |
| protected Iterable<PersistentType2_0> getMappingFilePersistentTypes2_0() { |
| return IterableTools.downCast(this.getMappingFilePersistentTypes()); |
| } |
| |
| protected MetamodelSourceType2_0 selectSourceType(Iterable<MetamodelSourceType2_0> types, String typeName) { |
| if (types != null) { |
| for (MetamodelSourceType2_0 type : types) { |
| if (type.getName().equals(typeName)) { |
| return type; |
| } |
| } |
| } |
| return null; |
| } |
| |
| protected MetamodelSourceType2_0 buildNonPersistentMetamodelSourceType(String nonPersistentTypeName) { |
| return new NonPersistentMetamodelSourceType(nonPersistentTypeName, this.getJpaProject()); |
| } |
| |
| protected IType findJdtType(String typeName) { |
| try { |
| return this.getJpaProject().getJavaProject().findType(typeName); |
| } catch (JavaModelException ex) { |
| JptJpaCorePlugin.instance().logError(ex); |
| return null; |
| } |
| } |
| |
| protected void deleteMetamodelFile(IFile file) { |
| try { |
| this.deleteMetamodelFile_(file); |
| } catch (CoreException ex) { |
| JptJpaCorePlugin.instance().logError(ex); |
| } |
| } |
| |
| protected void deleteMetamodelFile_(IFile file) throws CoreException { |
| if (this.fileIsGeneratedMetamodel(file)) { |
| file.delete(true, null); // true = force |
| } |
| } |
| |
| protected boolean fileIsGeneratedMetamodel(IFile file) { |
| return ((JpaProject2_0) this.getJpaProject()).getGeneratedMetamodelTopLevelType(file) != null; |
| } |
| |
| public void disposeMetamodel() { |
| this.metamodelFiles.clear(); |
| } |
| |
| |
| // ***** Metamodel source for non-persistent types |
| public static class NonPersistentMetamodelSourceType |
| implements MetamodelSourceType2_0 |
| { |
| protected final String name; |
| protected final JpaProject jpaProject; |
| protected final MetamodelSourceType2_0.Synchronizer metamodelSynchronizer; |
| |
| public NonPersistentMetamodelSourceType(String name, JpaProject jpaProject) { |
| super(); |
| this.name = name; |
| this.jpaProject = jpaProject; |
| this.metamodelSynchronizer = this.buildMetamodelSynchronizer(); |
| } |
| |
| protected MetamodelSourceType2_0.Synchronizer buildMetamodelSynchronizer() { |
| return this.getJpaFactory().buildMetamodelSynchronizer(this); |
| } |
| |
| protected JpaFactory2_0 getJpaFactory() { |
| return (JpaFactory2_0) this.getJpaProject().getJpaPlatform().getJpaFactory(); |
| } |
| |
| public String getName() { |
| return this.name; |
| } |
| |
| public boolean isManaged() { |
| return false; |
| } |
| |
| public PersistentType getSuperPersistentType() { |
| return null; |
| } |
| |
| public ListIterable<? extends PersistentAttribute> getAttributes() { |
| return EmptyListIterable.instance(); |
| } |
| |
| public IFile getMetamodelFile() { |
| return this.metamodelSynchronizer.getFile(); |
| } |
| |
| public JpaProject getJpaProject() { |
| return this.jpaProject; |
| } |
| |
| public void synchronizeMetamodel(Map<String, Collection<MetamodelSourceType2_0>> memberTypeTree) { |
| this.metamodelSynchronizer.synchronize(memberTypeTree); |
| } |
| |
| public void printBodySourceOn(BodySourceWriter pw, Map<String, Collection<MetamodelSourceType2_0>> memberTypeTree) { |
| this.metamodelSynchronizer.printBodySourceOn(pw, memberTypeTree); |
| } |
| } |
| } |