/******************************************************************************* * Copyright (c) 2006, 2008 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.core.internal.context.orm; import java.util.ArrayList; import java.util.Collection; import java.util.Comparator; import java.util.Iterator; import java.util.List; import java.util.ListIterator; import org.eclipse.jpt.core.JpaStructureNode; import org.eclipse.jpt.core.JptCorePlugin; import org.eclipse.jpt.core.MappingKeys; import org.eclipse.jpt.core.context.AccessType; import org.eclipse.jpt.core.context.PersistentAttribute; import org.eclipse.jpt.core.context.PersistentType; import org.eclipse.jpt.core.context.java.JavaAttributeMapping; import org.eclipse.jpt.core.context.java.JavaBasicMapping; import org.eclipse.jpt.core.context.java.JavaEmbeddedIdMapping; import org.eclipse.jpt.core.context.java.JavaEmbeddedMapping; import org.eclipse.jpt.core.context.java.JavaIdMapping; import org.eclipse.jpt.core.context.java.JavaManyToManyMapping; import org.eclipse.jpt.core.context.java.JavaManyToOneMapping; import org.eclipse.jpt.core.context.java.JavaOneToManyMapping; import org.eclipse.jpt.core.context.java.JavaOneToOneMapping; import org.eclipse.jpt.core.context.java.JavaPersistentAttribute; import org.eclipse.jpt.core.context.java.JavaPersistentType; import org.eclipse.jpt.core.context.java.JavaTransientMapping; import org.eclipse.jpt.core.context.java.JavaVersionMapping; import org.eclipse.jpt.core.context.orm.EntityMappings; import org.eclipse.jpt.core.context.orm.OrmAttributeMapping; import org.eclipse.jpt.core.context.orm.OrmEmbeddable; import org.eclipse.jpt.core.context.orm.OrmEntity; import org.eclipse.jpt.core.context.orm.OrmMappedSuperclass; import org.eclipse.jpt.core.context.orm.OrmPersistentAttribute; import org.eclipse.jpt.core.context.orm.OrmPersistentType; import org.eclipse.jpt.core.context.orm.OrmStructureNodes; import org.eclipse.jpt.core.context.orm.OrmTypeMapping; import org.eclipse.jpt.core.context.orm.OrmTypeMappingProvider; import org.eclipse.jpt.core.resource.orm.AbstractXmlTypeMapping; import org.eclipse.jpt.core.resource.orm.Attributes; import org.eclipse.jpt.core.resource.orm.OrmFactory; import org.eclipse.jpt.core.resource.orm.XmlBasic; import org.eclipse.jpt.core.resource.orm.XmlEmbeddable; import org.eclipse.jpt.core.resource.orm.XmlEmbedded; import org.eclipse.jpt.core.resource.orm.XmlEmbeddedId; import org.eclipse.jpt.core.resource.orm.XmlEntity; import org.eclipse.jpt.core.resource.orm.XmlId; import org.eclipse.jpt.core.resource.orm.XmlManyToMany; import org.eclipse.jpt.core.resource.orm.XmlManyToOne; import org.eclipse.jpt.core.resource.orm.XmlMappedSuperclass; import org.eclipse.jpt.core.resource.orm.XmlOneToMany; import org.eclipse.jpt.core.resource.orm.XmlOneToOne; import org.eclipse.jpt.core.resource.orm.XmlTransient; import org.eclipse.jpt.core.resource.orm.XmlVersion; import org.eclipse.jpt.core.utility.TextRange; import org.eclipse.jpt.utility.internal.CollectionTools; import org.eclipse.jpt.utility.internal.iterators.ChainIterator; import org.eclipse.jpt.utility.internal.iterators.CloneListIterator; import org.eclipse.jpt.utility.internal.iterators.CompositeIterator; import org.eclipse.jpt.utility.internal.iterators.CompositeListIterator; import org.eclipse.jpt.utility.internal.iterators.EmptyListIterator; import org.eclipse.jpt.utility.internal.iterators.FilteringIterator; import org.eclipse.jpt.utility.internal.iterators.TransformationIterator; import org.eclipse.wst.validation.internal.provisional.core.IMessage; public class GenericOrmPersistentType extends AbstractOrmJpaContextNode implements OrmPersistentType { protected final List specifiedPersistentAttributes; protected final List virtualPersistentAttributes; protected final Collection typeMappingProviders; protected OrmTypeMapping ormTypeMapping; protected PersistentType parentPersistentType; public GenericOrmPersistentType(EntityMappings parent, String mappingKey) { super(parent); this.typeMappingProviders = buildTypeMappingProviders(); this.ormTypeMapping = buildOrmTypeMapping(mappingKey); this.specifiedPersistentAttributes = new ArrayList(); this.virtualPersistentAttributes = new ArrayList(); } public String getId() { return OrmStructureNodes.PERSISTENT_TYPE_ID; } public boolean isFor(String fullyQualifiedTypeName) { String className = getMapping().getClass_(); if (className == null) { return false; } if (className.equals(fullyQualifiedTypeName)) { return true; } if ((getEntityMappings().getPackage() + "." + className).equals(fullyQualifiedTypeName)) { return true; } return false; } protected OrmTypeMapping buildOrmTypeMapping(String key) { return getTypeMappingProvider(key).buildTypeMapping(getJpaFactory(), this); } protected Collection buildTypeMappingProviders() { Collection collection = new ArrayList(); collection.add(new OrmEntityProvider()); collection.add(new OrmMappedSuperclassProvider()); collection.add(new OrmEmbeddableProvider()); return collection; } protected OrmTypeMappingProvider getTypeMappingProvider(String key) { for (OrmTypeMappingProvider provider : this.typeMappingProviders) { if (provider.getKey().equals(key)) { return provider; } } throw new IllegalArgumentException(); } public OrmTypeMapping getMapping() { return this.ormTypeMapping; } public void setMappingKey(String newMappingKey) { if (this.getMappingKey() == newMappingKey) { return; } OrmTypeMapping oldMapping = getMapping(); this.ormTypeMapping = buildOrmTypeMapping(newMappingKey); getEntityMappings().changeMapping(this, oldMapping, this.ormTypeMapping); firePropertyChanged(MAPPING_PROPERTY, oldMapping, this.ormTypeMapping); } protected void setMappingKey_(String newMappingKey) { if (this.getMappingKey() == newMappingKey) { return; } OrmTypeMapping oldMapping = getMapping(); this.ormTypeMapping = buildOrmTypeMapping(newMappingKey); firePropertyChanged(MAPPING_PROPERTY, oldMapping, this.ormTypeMapping); } public Iterator inheritanceHierarchy() { // using a chain iterator to traverse up the inheritance tree return new ChainIterator(this) { @Override protected PersistentType nextLink(PersistentType pt) { return pt.getParentPersistentType(); } }; } public PersistentType getParentPersistentType() { return this.parentPersistentType; } public void setParentPersistentType(PersistentType newParentPersistentType) { if (attributeValueHasNotChanged(this.parentPersistentType, newParentPersistentType)) { return; } PersistentType oldParentPersistentType = this.parentPersistentType; this.parentPersistentType = newParentPersistentType; firePropertyChanged(PersistentType.PARENT_PERSISTENT_TYPE_PROPERTY, oldParentPersistentType, newParentPersistentType); } public AccessType getAccess() { return getMapping().getAccess(); } public void changeMapping(OrmPersistentAttribute ormPersistentAttribute, OrmAttributeMapping oldMapping, OrmAttributeMapping newMapping) { int sourceIndex = this.specifiedPersistentAttributes.indexOf(ormPersistentAttribute); if (sourceIndex != -1) { this.specifiedPersistentAttributes.remove(sourceIndex); oldMapping.removeFromResourceModel(getMapping().getTypeMappingResource()); } if (getMapping().getTypeMappingResource().getAttributes() == null) { getMapping().getTypeMappingResource().setAttributes(OrmFactory.eINSTANCE.createAttributes()); } int targetIndex = insertionIndex(ormPersistentAttribute); this.specifiedPersistentAttributes.add(targetIndex, ormPersistentAttribute); newMapping.addToResourceModel(getMapping().getTypeMappingResource()); oldMapping.initializeOn(newMapping); if (sourceIndex != -1) { //TODO are the source and target correct in this case, or is target off by one??? fireItemMoved(SPECIFIED_ATTRIBUTES_LIST, targetIndex, sourceIndex); } } public void makePersistentAttributeVirtual(OrmPersistentAttribute ormPersistentAttribute) { if (ormPersistentAttribute.isVirtual()) { throw new IllegalStateException("Attribute is already virtual"); } JavaPersistentAttribute javaPersistentAttribute = ormPersistentAttribute.getMapping().getJavaPersistentAttribute(); OrmPersistentAttribute virtualPersistentAttribute = null; if (javaPersistentAttribute != null) { virtualPersistentAttribute = createVirtualPersistentAttribute(javaPersistentAttribute); this.virtualPersistentAttributes.add(virtualPersistentAttribute); } this.removeSpecifiedPersistentAttribute(ormPersistentAttribute); if (virtualPersistentAttribute != null) { fireItemAdded(VIRTUAL_ATTRIBUTES_LIST, virtualAttributesSize() - 1, virtualPersistentAttribute); } } public void makePersistentAttributeSpecified(OrmPersistentAttribute ormPersistentAttribute) { makePersistentAttributeSpecified(ormPersistentAttribute, ormPersistentAttribute.getMappingKey()); } public void makePersistentAttributeSpecified(OrmPersistentAttribute ormPersistentAttribute, String mappingKey) { if (!ormPersistentAttribute.isVirtual()) { throw new IllegalStateException("Attribute is already specified"); } if (mappingKey == MappingKeys.NULL_ATTRIBUTE_MAPPING_KEY) { throw new IllegalStateException("Use makePersistentAttributeSpecified(OrmPersistentAttribute, String) instead and specify a mapping type"); } OrmPersistentAttribute newPersistentAttribute = getJpaFactory().buildOrmPersistentAttribute(this, mappingKey); if (getMapping().getTypeMappingResource().getAttributes() == null) { getMapping().getTypeMappingResource().setAttributes(OrmFactory.eINSTANCE.createAttributes()); } int insertionIndex = insertionIndex(newPersistentAttribute); this.specifiedPersistentAttributes.add(insertionIndex, newPersistentAttribute); newPersistentAttribute.getMapping().addToResourceModel(getMapping().getTypeMappingResource()); int removalIndex = this.virtualPersistentAttributes.indexOf(ormPersistentAttribute); this.virtualPersistentAttributes.remove(ormPersistentAttribute); newPersistentAttribute.getSpecifiedMapping().setName(ormPersistentAttribute.getName()); fireItemAdded(PersistentType.SPECIFIED_ATTRIBUTES_LIST, insertionIndex, newPersistentAttribute); fireItemRemoved(VIRTUAL_ATTRIBUTES_LIST, removalIndex, ormPersistentAttribute); } public Iterator allAttributeNames() { return this.attributeNames(this.allAttributes()); } public Iterator allAttributes() { return new CompositeIterator(new TransformationIterator>(this.inheritanceHierarchy()) { @Override protected Iterator transform(PersistentType pt) { return pt.attributes(); } }); } protected Iterator attributesNamed(final String attributeName) { return new FilteringIterator(attributes()) { @Override protected boolean accept(OrmPersistentAttribute o) { if (attributeName == null && o.getName() == null) { return true; } if (attributeName != null && attributeName.equals(o.getName())) { return true; } return false; } }; } public OrmPersistentAttribute getAttributeNamed(String attributeName) { Iterator stream = attributesNamed(attributeName); return (stream.hasNext()) ? stream.next() : null; } public Iterator attributeNames() { return this.attributeNames(this.attributes()); } protected Iterator attributeNames(Iterator attrs) { return new TransformationIterator(attrs) { @Override protected String transform(PersistentAttribute attribute) { return attribute.getName(); } }; } protected OrmPersistentAttribute specifiedAttributeNamed(String attributeName) { Iterator stream = specifiedAttributesNamed(attributeName); return (stream.hasNext()) ? stream.next() : null; } protected Iterator specifiedAttributesNamed(final String attributeName) { return new FilteringIterator(specifiedAttributes()) { @Override protected boolean accept(OrmPersistentAttribute ormPersistentAttribute) { return attributeName.equals(ormPersistentAttribute.getName()); } }; } @SuppressWarnings("unchecked") public ListIterator attributes() { return new CompositeListIterator(specifiedAttributes(), virtualAttributes()); } public int attributesSize() { return specifiedAttributesSize() + virtualAttributesSize(); } public ListIterator specifiedAttributes() { return new CloneListIterator(this.specifiedPersistentAttributes); } public int specifiedAttributesSize() { return this.specifiedPersistentAttributes.size(); } public ListIterator virtualAttributes() { return new CloneListIterator(this.virtualPersistentAttributes); } public int virtualAttributesSize() { return this.virtualPersistentAttributes.size(); } protected void addVirtualPersistentAttribute(OrmPersistentAttribute ormPersistentAttribute) { addItemToList(ormPersistentAttribute, this.virtualPersistentAttributes, OrmPersistentType.VIRTUAL_ATTRIBUTES_LIST); } protected void removeVirtualPersistentAttribute(OrmPersistentAttribute ormPersistentAttribute) { removeItemFromList(ormPersistentAttribute, this.virtualPersistentAttributes, OrmPersistentType.VIRTUAL_ATTRIBUTES_LIST); } public boolean containsVirtualPersistentAttribute(OrmPersistentAttribute ormPersistentAttribute) { return this.virtualPersistentAttributes.contains(ormPersistentAttribute); } public OrmPersistentAttribute addSpecifiedPersistentAttribute(String mappingKey, String attributeName) { OrmPersistentAttribute persistentAttribute = getJpaFactory().buildOrmPersistentAttribute(this, mappingKey); int index = insertionIndex(persistentAttribute); if (getMapping().getTypeMappingResource().getAttributes() == null) { getMapping().getTypeMappingResource().setAttributes(OrmFactory.eINSTANCE.createAttributes()); } this.specifiedPersistentAttributes.add(index, persistentAttribute); persistentAttribute.getMapping().addToResourceModel(getMapping().getTypeMappingResource()); persistentAttribute.getSpecifiedMapping().setName(attributeName); fireItemAdded(PersistentType.SPECIFIED_ATTRIBUTES_LIST, index, persistentAttribute); return persistentAttribute; } protected int insertionIndex(OrmPersistentAttribute persistentAttribute) { return CollectionTools.insertionIndexOf(this.specifiedPersistentAttributes, persistentAttribute, buildMappingComparator()); } protected Comparator buildMappingComparator() { return new Comparator() { public int compare(OrmPersistentAttribute o1, OrmPersistentAttribute o2) { int o1Sequence = o1.getMapping().getXmlSequence(); int o2Sequence = o2.getMapping().getXmlSequence(); if (o1Sequence < o2Sequence) { return -1; } if (o1Sequence == o2Sequence) { return 0; } return 1; } }; } protected void addSpecifiedPersistentAttribute_(OrmPersistentAttribute ormPersistentAttribute) { addItemToList(ormPersistentAttribute, this.specifiedPersistentAttributes, PersistentType.SPECIFIED_ATTRIBUTES_LIST); } protected void removeSpecifiedPersistentAttribute_(OrmPersistentAttribute ormPersistentAttribute) { removeItemFromList(ormPersistentAttribute, this.specifiedPersistentAttributes, PersistentType.SPECIFIED_ATTRIBUTES_LIST); } public void removeSpecifiedPersistentAttribute(OrmPersistentAttribute ormPersistentAttribute) { int index = this.specifiedPersistentAttributes.indexOf(ormPersistentAttribute); this.specifiedPersistentAttributes.remove(ormPersistentAttribute); ormPersistentAttribute.getMapping().removeFromResourceModel(this.ormTypeMapping.getTypeMappingResource()); fireItemRemoved(PersistentType.SPECIFIED_ATTRIBUTES_LIST, index, ormPersistentAttribute); } public String getName() { return getMapping().getClass_(); } public void classChanged(String oldClass, String newClass) { firePropertyChanged(NAME_PROPERTY, oldClass, newClass); } public boolean isMapped() { return true; } public String getMappingKey() { return getMapping().getKey(); } public JavaPersistentType getJavaPersistentType() { return getMapping().getJavaPersistentType(); } //TODO is there a way to avoid a method for every mapping type? //I am trying to take adavantage of generics here, but it sure is //leading to a lot of duplicated code. - KFM public void initialize(XmlEntity entity) { ((OrmEntity) getMapping()).initialize(entity); this.initializeParentPersistentType(); this.initializePersistentAttributes(entity); } public void initialize(XmlMappedSuperclass mappedSuperclass) { ((OrmMappedSuperclass) getMapping()).initialize(mappedSuperclass); this.initializeParentPersistentType(); this.initializePersistentAttributes(mappedSuperclass); } public void initialize(XmlEmbeddable embeddable) { ((OrmEmbeddable) getMapping()).initialize(embeddable); this.initializeParentPersistentType(); this.initializePersistentAttributes(embeddable); } protected void initializePersistentAttributes(AbstractXmlTypeMapping typeMapping) { Attributes attributes = typeMapping.getAttributes(); if (attributes != null) { this.initializeSpecifiedPersistentAttributes(attributes); } this.initializeVirtualPersistentAttributes(); } protected void initializeSpecifiedPersistentAttributes(Attributes attributes) { for (XmlId id : attributes.getIds()) { OrmPersistentAttribute ormPersistentAttribute = getJpaFactory().buildOrmPersistentAttribute(this, MappingKeys.ID_ATTRIBUTE_MAPPING_KEY); ormPersistentAttribute.initialize(id); this.specifiedPersistentAttributes.add(ormPersistentAttribute); } for (XmlEmbeddedId embeddedId : attributes.getEmbeddedIds()) { OrmPersistentAttribute ormPersistentAttribute = getJpaFactory().buildOrmPersistentAttribute(this, MappingKeys.EMBEDDED_ID_ATTRIBUTE_MAPPING_KEY); ormPersistentAttribute.initialize(embeddedId); this.specifiedPersistentAttributes.add(ormPersistentAttribute); } for (XmlBasic basic : attributes.getBasics()) { OrmPersistentAttribute ormPersistentAttribute = getJpaFactory().buildOrmPersistentAttribute(this, MappingKeys.BASIC_ATTRIBUTE_MAPPING_KEY); ormPersistentAttribute.initialize(basic); this.specifiedPersistentAttributes.add(ormPersistentAttribute); } for (XmlVersion version : attributes.getVersions()) { OrmPersistentAttribute ormPersistentAttribute = getJpaFactory().buildOrmPersistentAttribute(this, MappingKeys.VERSION_ATTRIBUTE_MAPPING_KEY); ormPersistentAttribute.initialize(version); this.specifiedPersistentAttributes.add(ormPersistentAttribute); } for (XmlManyToOne manyToOne : attributes.getManyToOnes()) { OrmPersistentAttribute ormPersistentAttribute = getJpaFactory().buildOrmPersistentAttribute(this, MappingKeys.MANY_TO_ONE_ATTRIBUTE_MAPPING_KEY); ormPersistentAttribute.initialize(manyToOne); this.specifiedPersistentAttributes.add(ormPersistentAttribute); } for (XmlOneToMany oneToMany : attributes.getOneToManys()) { OrmPersistentAttribute ormPersistentAttribute = getJpaFactory().buildOrmPersistentAttribute(this, MappingKeys.ONE_TO_MANY_ATTRIBUTE_MAPPING_KEY); ormPersistentAttribute.initialize(oneToMany); this.specifiedPersistentAttributes.add(ormPersistentAttribute); } for (XmlOneToOne oneToOne : attributes.getOneToOnes()) { OrmPersistentAttribute ormPersistentAttribute = getJpaFactory().buildOrmPersistentAttribute(this, MappingKeys.ONE_TO_ONE_ATTRIBUTE_MAPPING_KEY); ormPersistentAttribute.initialize(oneToOne); this.specifiedPersistentAttributes.add(ormPersistentAttribute); } for (XmlManyToMany manyToMany : attributes.getManyToManys()) { OrmPersistentAttribute ormPersistentAttribute = getJpaFactory().buildOrmPersistentAttribute(this, MappingKeys.MANY_TO_MANY_ATTRIBUTE_MAPPING_KEY); ormPersistentAttribute.initialize(manyToMany); this.specifiedPersistentAttributes.add(ormPersistentAttribute); } for (XmlEmbedded embedded : attributes.getEmbeddeds()) { OrmPersistentAttribute ormPersistentAttribute = getJpaFactory().buildOrmPersistentAttribute(this, MappingKeys.EMBEDDED_ATTRIBUTE_MAPPING_KEY); ormPersistentAttribute.initialize(embedded); this.specifiedPersistentAttributes.add(ormPersistentAttribute); } for (XmlTransient transientResource : attributes.getTransients()) { OrmPersistentAttribute ormPersistentAttribute = getJpaFactory().buildOrmPersistentAttribute(this, MappingKeys.TRANSIENT_ATTRIBUTE_MAPPING_KEY); ormPersistentAttribute.initialize(transientResource); this.specifiedPersistentAttributes.add(ormPersistentAttribute); } } protected void initializeVirtualPersistentAttributes() { ListIterator javaAttributes = javaPersistentAttributes(); while (javaAttributes.hasNext()) { JavaPersistentAttribute javaPersistentAttribute = javaAttributes.next(); if (specifiedAttributeNamed(javaPersistentAttribute.getName()) == null) { OrmPersistentAttribute ormPersistentAttribute = createVirtualPersistentAttribute(javaPersistentAttribute); this.virtualPersistentAttributes.add(ormPersistentAttribute); } } } protected ListIterator javaPersistentAttributes() { JavaPersistentType javaPersistentType = getJavaPersistentType(); if (javaPersistentType != null) { return javaPersistentType.attributes(); } return EmptyListIterator.instance(); } protected void initializeParentPersistentType() { JavaPersistentType javaPersistentType = getJavaPersistentType(); if (javaPersistentType != null) { this.parentPersistentType = javaPersistentType.getParentPersistentType(); } } public void update(XmlEntity entity) { if (getMappingKey() != MappingKeys.ENTITY_TYPE_MAPPING_KEY) { setMappingKey_(MappingKeys.ENTITY_TYPE_MAPPING_KEY); } ((OrmEntity) getMapping()).update(entity); this.updateParentPersistentType(); this.updatePersistentAttributes(entity); } public void update(XmlMappedSuperclass mappedSuperclass) { if (getMappingKey() != MappingKeys.MAPPED_SUPERCLASS_TYPE_MAPPING_KEY) { setMappingKey_(MappingKeys.MAPPED_SUPERCLASS_TYPE_MAPPING_KEY); } ((OrmMappedSuperclass) getMapping()).update(mappedSuperclass); this.updateParentPersistentType(); this.updatePersistentAttributes(mappedSuperclass); } public void update(XmlEmbeddable embeddable) { if (getMappingKey() != MappingKeys.EMBEDDABLE_TYPE_MAPPING_KEY) { setMappingKey_(MappingKeys.EMBEDDABLE_TYPE_MAPPING_KEY); } ((OrmEmbeddable) getMapping()).update(embeddable); this.updateParentPersistentType(); this.updatePersistentAttributes(embeddable); } protected void updateParentPersistentType() { JavaPersistentType javaPersistentType = getJavaPersistentType(); setParentPersistentType(javaPersistentType == null ? null : javaPersistentType.getParentPersistentType()); } protected void updatePersistentAttributes(AbstractXmlTypeMapping typeMapping) { ListIterator ormPersistentAttributes = this.specifiedAttributes(); if (typeMapping.getAttributes() != null) { this.updateIds(typeMapping.getAttributes(), ormPersistentAttributes); this.updateEmbeddedIds(typeMapping.getAttributes(), ormPersistentAttributes); this.updateBasics(typeMapping.getAttributes(), ormPersistentAttributes); this.updateVersions(typeMapping.getAttributes(), ormPersistentAttributes); this.updateManyToOnes(typeMapping.getAttributes(), ormPersistentAttributes); this.updateOneToManys(typeMapping.getAttributes(), ormPersistentAttributes); this.updateOneToOnes(typeMapping.getAttributes(), ormPersistentAttributes); this.updateManyToManys(typeMapping.getAttributes(), ormPersistentAttributes); this.updateEmbeddeds(typeMapping.getAttributes(), ormPersistentAttributes); this.updateTransients(typeMapping.getAttributes(), ormPersistentAttributes); } while (ormPersistentAttributes.hasNext()) { this.removeSpecifiedPersistentAttribute_(ormPersistentAttributes.next()); } this.updateVirtualPersistentAttributes(); } protected void updateVirtualAttribute(OrmPersistentAttribute ormPersistentAttribute, JavaPersistentAttribute javaAttribute) { String javaMappingKey = javaAttribute.getMappingKey(); JavaAttributeMapping javaAttributeMapping = javaAttribute.getMapping(); if (getMapping().isMetadataComplete()) { javaMappingKey = javaAttribute.getDefaultMappingKey(); javaAttributeMapping = javaAttribute.getDefaultMapping(); } if (javaMappingKey == MappingKeys.BASIC_ATTRIBUTE_MAPPING_KEY) { ormPersistentAttribute.update(new VirtualXmlBasic(getMapping(), (JavaBasicMapping) javaAttributeMapping, getMapping().isMetadataComplete())); } else if (javaMappingKey == MappingKeys.EMBEDDED_ATTRIBUTE_MAPPING_KEY) { ormPersistentAttribute.update(new VirtualXmlEmbedded(getMapping(), (JavaEmbeddedMapping) javaAttributeMapping, getMapping().isMetadataComplete())); } else if (javaMappingKey == MappingKeys.EMBEDDED_ID_ATTRIBUTE_MAPPING_KEY) { ormPersistentAttribute.update(new VirtualXmlEmbeddedId(getMapping(), (JavaEmbeddedIdMapping) javaAttributeMapping, getMapping().isMetadataComplete())); } else if (javaMappingKey == MappingKeys.ID_ATTRIBUTE_MAPPING_KEY) { ormPersistentAttribute.update(new VirtualXmlId(getMapping(), (JavaIdMapping) javaAttributeMapping, getMapping().isMetadataComplete())); } else if (javaMappingKey == MappingKeys.MANY_TO_MANY_ATTRIBUTE_MAPPING_KEY) { ormPersistentAttribute.update(new VirtualXmlManyToMany(ormPersistentAttribute, (JavaManyToManyMapping) javaAttributeMapping, getMapping().isMetadataComplete())); } else if (javaMappingKey == MappingKeys.MANY_TO_ONE_ATTRIBUTE_MAPPING_KEY) { ormPersistentAttribute.update(new VirtualXmlManyToOne((JavaManyToOneMapping) javaAttributeMapping, getMapping().isMetadataComplete())); } else if (javaMappingKey == MappingKeys.ONE_TO_MANY_ATTRIBUTE_MAPPING_KEY) { ormPersistentAttribute.update(new VirtualXmlOneToMany(ormPersistentAttribute, (JavaOneToManyMapping) javaAttributeMapping, getMapping().isMetadataComplete())); } else if (javaMappingKey == MappingKeys.ONE_TO_ONE_ATTRIBUTE_MAPPING_KEY) { ormPersistentAttribute.update(new VirtualXmlOneToOne((JavaOneToOneMapping) javaAttributeMapping, getMapping().isMetadataComplete())); } else if (javaMappingKey == MappingKeys.TRANSIENT_ATTRIBUTE_MAPPING_KEY) { ormPersistentAttribute.update(new VirtualXmlTransient((JavaTransientMapping) javaAttributeMapping, getMapping().isMetadataComplete())); } else if (javaMappingKey == MappingKeys.VERSION_ATTRIBUTE_MAPPING_KEY) { ormPersistentAttribute.update(new VirtualXmlVersion(getMapping(), (JavaVersionMapping) javaAttributeMapping, getMapping().isMetadataComplete())); } else if (javaMappingKey == MappingKeys.NULL_ATTRIBUTE_MAPPING_KEY) { ormPersistentAttribute.update(new VirtualXmlNullAttributeMapping(getMapping(), javaAttributeMapping, getMapping().isMetadataComplete())); } } protected void updateVirtualPersistentAttributes() { ListIterator javaAttributes = this.javaPersistentAttributes(); ListIterator xmlVirtualAttributes = this.virtualAttributes(); for (JavaPersistentAttribute javaAttribute : CollectionTools.iterable(javaAttributes)) { if (specifiedAttributeNamed(javaAttribute.getName()) == null) { if (xmlVirtualAttributes.hasNext()) { updateVirtualAttribute(xmlVirtualAttributes.next(), javaAttribute); } else { OrmPersistentAttribute ormPersistentAttribute = createVirtualPersistentAttribute(javaAttribute); addVirtualPersistentAttribute(ormPersistentAttribute); } } } while (xmlVirtualAttributes.hasNext()) { this.removeVirtualPersistentAttribute(xmlVirtualAttributes.next()); } } protected void addVirtualPersistentAttribute(JavaPersistentAttribute javaAttribute) { addVirtualPersistentAttribute(createVirtualPersistentAttribute(javaAttribute)); } protected OrmPersistentAttribute createVirtualPersistentAttribute(JavaPersistentAttribute javaAttribute) { String javaMappingKey = javaAttribute.getMappingKey(); JavaAttributeMapping javaAttributeMapping = javaAttribute.getMapping(); if (getMapping().isMetadataComplete()) { javaMappingKey = javaAttribute.getDefaultMappingKey(); javaAttributeMapping = javaAttribute.getDefaultMapping(); } OrmPersistentAttribute ormPersistentAttribute = getJpaFactory().buildOrmPersistentAttribute(this, javaMappingKey); if (javaMappingKey == MappingKeys.BASIC_ATTRIBUTE_MAPPING_KEY) { ormPersistentAttribute.initialize(new VirtualXmlBasic(getMapping(), (JavaBasicMapping) javaAttributeMapping, getMapping().isMetadataComplete())); } else if (javaMappingKey == MappingKeys.EMBEDDED_ID_ATTRIBUTE_MAPPING_KEY) { ormPersistentAttribute.initialize(new VirtualXmlEmbeddedId(getMapping(), (JavaEmbeddedIdMapping) javaAttributeMapping, getMapping().isMetadataComplete())); } else if (javaMappingKey == MappingKeys.EMBEDDED_ATTRIBUTE_MAPPING_KEY) { ormPersistentAttribute.initialize(new VirtualXmlEmbedded(getMapping(), (JavaEmbeddedMapping) javaAttributeMapping, getMapping().isMetadataComplete())); } else if (javaMappingKey == MappingKeys.ID_ATTRIBUTE_MAPPING_KEY) { ormPersistentAttribute.initialize(new VirtualXmlId(getMapping(), (JavaIdMapping) javaAttributeMapping, getMapping().isMetadataComplete())); } else if (javaMappingKey == MappingKeys.MANY_TO_MANY_ATTRIBUTE_MAPPING_KEY) { ormPersistentAttribute.initialize(new VirtualXmlManyToMany(ormPersistentAttribute, (JavaManyToManyMapping) javaAttributeMapping, getMapping().isMetadataComplete())); } else if (javaMappingKey == MappingKeys.MANY_TO_ONE_ATTRIBUTE_MAPPING_KEY) { ormPersistentAttribute.initialize(new VirtualXmlManyToOne((JavaManyToOneMapping) javaAttributeMapping, getMapping().isMetadataComplete())); } else if (javaMappingKey == MappingKeys.ONE_TO_MANY_ATTRIBUTE_MAPPING_KEY) { ormPersistentAttribute.initialize(new VirtualXmlOneToMany(ormPersistentAttribute, (JavaOneToManyMapping) javaAttributeMapping, getMapping().isMetadataComplete())); } else if (javaMappingKey == MappingKeys.ONE_TO_ONE_ATTRIBUTE_MAPPING_KEY) { ormPersistentAttribute.initialize(new VirtualXmlOneToOne((JavaOneToOneMapping) javaAttributeMapping, getMapping().isMetadataComplete())); } else if (javaMappingKey == MappingKeys.TRANSIENT_ATTRIBUTE_MAPPING_KEY) { ormPersistentAttribute.initialize(new VirtualXmlTransient((JavaTransientMapping) javaAttributeMapping, getMapping().isMetadataComplete())); } else if (javaMappingKey == MappingKeys.VERSION_ATTRIBUTE_MAPPING_KEY) { ormPersistentAttribute.initialize(new VirtualXmlVersion(getMapping(), (JavaVersionMapping) javaAttributeMapping, getMapping().isMetadataComplete())); } else if (javaMappingKey == MappingKeys.NULL_ATTRIBUTE_MAPPING_KEY) { ormPersistentAttribute.initialize(new VirtualXmlNullAttributeMapping(getMapping(), javaAttributeMapping, getMapping().isMetadataComplete())); } return ormPersistentAttribute; } protected void updateIds(Attributes attributes, ListIterator ormPersistentAttributes) { ListIterator ids = new CloneListIterator(attributes.getIds());//prevent ConcurrentModificiationException for (XmlId id : CollectionTools.iterable(ids)) { if (ormPersistentAttributes.hasNext()) { ormPersistentAttributes.next().update(id); } else { OrmPersistentAttribute ormPersistentAttribute = getJpaFactory().buildOrmPersistentAttribute(this, MappingKeys.ID_ATTRIBUTE_MAPPING_KEY); ormPersistentAttribute.initialize(id); addSpecifiedPersistentAttribute_(ormPersistentAttribute); } } } protected void updateEmbeddedIds(Attributes attributes, ListIterator ormPersistentAttributes) { ListIterator embeddedIds = new CloneListIterator(attributes.getEmbeddedIds());//prevent ConcurrentModificiationException for (XmlEmbeddedId embeddedId : CollectionTools.iterable(embeddedIds)) { if (ormPersistentAttributes.hasNext()) { ormPersistentAttributes.next().update(embeddedId); } else { OrmPersistentAttribute ormPersistentAttribute = getJpaFactory().buildOrmPersistentAttribute(this, MappingKeys.EMBEDDED_ID_ATTRIBUTE_MAPPING_KEY); ormPersistentAttribute.initialize(embeddedId); addSpecifiedPersistentAttribute_(ormPersistentAttribute); } } } protected void updateBasics(Attributes attributes, ListIterator ormPersistentAttributes) { ListIterator basics = new CloneListIterator(attributes.getBasics());//prevent ConcurrentModificiationException for (XmlBasic basic : CollectionTools.iterable(basics)) { if (ormPersistentAttributes.hasNext()) { ormPersistentAttributes.next().update(basic); } else { OrmPersistentAttribute ormPersistentAttribute = getJpaFactory().buildOrmPersistentAttribute(this, MappingKeys.BASIC_ATTRIBUTE_MAPPING_KEY); ormPersistentAttribute.initialize(basic); addSpecifiedPersistentAttribute_(ormPersistentAttribute); } } } protected void updateVersions(Attributes attributes, ListIterator ormPersistentAttributes) { ListIterator versions = new CloneListIterator(attributes.getVersions());//prevent ConcurrentModificiationException for (XmlVersion version : CollectionTools.iterable(versions)) { if (ormPersistentAttributes.hasNext()) { ormPersistentAttributes.next().update(version); } else { OrmPersistentAttribute ormPersistentAttribute = getJpaFactory().buildOrmPersistentAttribute(this, MappingKeys.VERSION_ATTRIBUTE_MAPPING_KEY); ormPersistentAttribute.initialize(version); addSpecifiedPersistentAttribute_(ormPersistentAttribute); } } } protected void updateManyToOnes(Attributes attributes, ListIterator ormPersistentAttributes) { ListIterator manyToOnes = new CloneListIterator(attributes.getManyToOnes());//prevent ConcurrentModificiationException for (XmlManyToOne manyToOne : CollectionTools.iterable(manyToOnes)) { if (ormPersistentAttributes.hasNext()) { ormPersistentAttributes.next().update(manyToOne); } else { OrmPersistentAttribute ormPersistentAttribute = getJpaFactory().buildOrmPersistentAttribute(this, MappingKeys.MANY_TO_ONE_ATTRIBUTE_MAPPING_KEY); ormPersistentAttribute.initialize(manyToOne); addSpecifiedPersistentAttribute_(ormPersistentAttribute); } } } protected void updateOneToManys(Attributes attributes, ListIterator ormPersistentAttributes) { ListIterator oneToManys = new CloneListIterator(attributes.getOneToManys());//prevent ConcurrentModificiationException for (XmlOneToMany oneToMany : CollectionTools.iterable(oneToManys)) { if (ormPersistentAttributes.hasNext()) { ormPersistentAttributes.next().update(oneToMany); } else { OrmPersistentAttribute ormPersistentAttribute = getJpaFactory().buildOrmPersistentAttribute(this, MappingKeys.ONE_TO_MANY_ATTRIBUTE_MAPPING_KEY); ormPersistentAttribute.initialize(oneToMany); addSpecifiedPersistentAttribute_(ormPersistentAttribute); } } } protected void updateOneToOnes(Attributes attributes, ListIterator ormPersistentAttributes) { ListIterator oneToOnes = new CloneListIterator(attributes.getOneToOnes());//prevent ConcurrentModificiationException for (XmlOneToOne oneToOne : CollectionTools.iterable(oneToOnes)) { if (ormPersistentAttributes.hasNext()) { ormPersistentAttributes.next().update(oneToOne); } else { OrmPersistentAttribute ormPersistentAttribute = getJpaFactory().buildOrmPersistentAttribute(this, MappingKeys.ONE_TO_ONE_ATTRIBUTE_MAPPING_KEY); ormPersistentAttribute.initialize(oneToOne); addSpecifiedPersistentAttribute_(ormPersistentAttribute); } } } protected void updateManyToManys(Attributes attributes, ListIterator ormPersistentAttributes) { ListIterator manyToManys = new CloneListIterator(attributes.getManyToManys());//prevent ConcurrentModificiationException for (XmlManyToMany manyToMany : CollectionTools.iterable(manyToManys)) { if (ormPersistentAttributes.hasNext()) { ormPersistentAttributes.next().update(manyToMany); } else { OrmPersistentAttribute ormPersistentAttribute = getJpaFactory().buildOrmPersistentAttribute(this, MappingKeys.MANY_TO_MANY_ATTRIBUTE_MAPPING_KEY); ormPersistentAttribute.initialize(manyToMany); addSpecifiedPersistentAttribute_(ormPersistentAttribute); } } } protected void updateEmbeddeds(Attributes attributes, ListIterator ormPersistentAttributes) { ListIterator embeddeds = new CloneListIterator(attributes.getEmbeddeds());//prevent ConcurrentModificiationException for (XmlEmbedded embedded : CollectionTools.iterable(embeddeds)) { if (ormPersistentAttributes.hasNext()) { ormPersistentAttributes.next().update(embedded); } else { OrmPersistentAttribute ormPersistentAttribute = getJpaFactory().buildOrmPersistentAttribute(this, MappingKeys.EMBEDDED_ATTRIBUTE_MAPPING_KEY); ormPersistentAttribute.initialize(embedded); addSpecifiedPersistentAttribute_(ormPersistentAttribute); } } } protected void updateTransients(Attributes attributes, ListIterator ormPersistentAttributes) { ListIterator transients = new CloneListIterator(attributes.getTransients());//prevent ConcurrentModificiationException for (XmlTransient transientResource : CollectionTools.iterable(transients)) { if (ormPersistentAttributes.hasNext()) { ormPersistentAttributes.next().update(transientResource); } else { OrmPersistentAttribute ormPersistentAttribute = getJpaFactory().buildOrmPersistentAttribute(this, MappingKeys.TRANSIENT_ATTRIBUTE_MAPPING_KEY); ormPersistentAttribute.initialize(transientResource); addSpecifiedPersistentAttribute_(ormPersistentAttribute); } } } public PersistentAttribute resolveAttribute(String attributeName) { Iterator attributes = attributesNamed(attributeName); if (attributes.hasNext()) { OrmPersistentAttribute attribute = attributes.next(); return attributes.hasNext() ? null /* more than one */: attribute; } else if (getParentPersistentType() != null) { return getParentPersistentType().resolveAttribute(attributeName); } else { return null; } } @Override public OrmPersistentType getOrmPersistentType() { return this; } public JpaStructureNode getStructureNode(int textOffset) { for (OrmPersistentAttribute attribute : CollectionTools.iterable(specifiedAttributes())) { if (attribute.contains(textOffset)) { return attribute; } } return this; } public boolean contains(int textOffset) { return this.ormTypeMapping.containsOffset(textOffset); } public TextRange getSelectionTextRange() { return this.ormTypeMapping.getSelectionTextRange(); } //******************** validation ********************** @Override public void addToMessages(List messages) { super.addToMessages(messages); try { getMapping().addToMessages(messages); } catch(Throwable t) { JptCorePlugin.log(t); } for (OrmPersistentAttribute persistentAttribute : CollectionTools.iterable(this.attributes())) { try { persistentAttribute.addToMessages(messages); } catch(Throwable t) { JptCorePlugin.log(t); } } } public TextRange getValidationTextRange() { return this.ormTypeMapping.getValidationTextRange(); } public void dispose() { if (getJavaPersistentType() != null) { getJavaPersistentType().dispose(); } } }