/******************************************************************************* * Copyright (c) 1998, 2015 Oracle and/or its affiliates. All rights reserved. * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 * which accompanies this distribution. * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html * and the Eclipse Distribution License is available at * http://www.eclipse.org/org/documents/edl-v10.php. * * Contributors: * Oracle - initial API and implementation from Oracle TopLink * 05/16/2008-1.0M8 Guy Pelletier * - 218084: Implement metadata merging functionality between mapping files * 01/28/2009-2.0 Guy Pelletier * - 248293: JPA 2.0 Element Collections (part 1) * 04/27/2010-2.1 Guy Pelletier * - 309856: MappedSuperclasses from XML are not being initialized properly * 09/16/2010-2.2 Guy Pelletier * - 283028: Add support for letting an @Embeddable extend a @MappedSuperclass * 03/24/2011-2.3 Guy Pelletier * - 337323: Multi-tenant with shared schema support (part 1) ******************************************************************************/ package org.eclipse.persistence.internal.jpa.metadata.accessors.classes; import java.util.ArrayList; import java.util.List; import org.eclipse.persistence.internal.jpa.metadata.ORMetadata; import org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.BasicAccessor; import org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.BasicCollectionAccessor; import org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.BasicMapAccessor; import org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.ElementCollectionAccessor; import org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.EmbeddedAccessor; import org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.EmbeddedIdAccessor; import org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.IdAccessor; import org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.ManyToManyAccessor; import org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.ManyToOneAccessor; import org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.MappingAccessor; import org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.OneToManyAccessor; import org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.OneToOneAccessor; import org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.TransformationAccessor; import org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.TransientAccessor; import org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.VariableOneToOneAccessor; import org.eclipse.persistence.internal.jpa.metadata.accessors.mappings.VersionAccessor; import org.eclipse.persistence.internal.jpa.metadata.accessors.objects.MetadataAccessibleObject; import org.eclipse.persistence.internal.jpa.metadata.structures.ArrayAccessor; import org.eclipse.persistence.internal.jpa.metadata.structures.StructureAccessor; import org.eclipse.persistence.internal.jpa.metadata.xml.XMLEntityMappings; /** * Object to represent all the attributes of an XML defined entity, * mapped-superclass or embeddable. * * Key notes: * - any metadata mapped from XML to this class must be compared in the * equals method. * - any metadata mapped from XML to this class must be handled in the merge * method. (merging is done at the accessor/mapping level) * - any metadata mapped from XML to this class must be initialized in the * initXMLObject method. * - methods should be preserved in alphabetical order. * * @author Guy Pelletier * @since EclipseLink 1.0 */ public class XMLAttributes extends ORMetadata { private EmbeddedIdAccessor m_embeddedId; private List<BasicAccessor> m_basics; private List<BasicCollectionAccessor> m_basicCollections; private List<BasicMapAccessor> m_basicMaps; private List<ElementCollectionAccessor> m_elementCollections; private List<EmbeddedAccessor> m_embeddeds; private List<IdAccessor> m_ids; private List<ManyToManyAccessor> m_manyToManys; private List<ManyToOneAccessor> m_manyToOnes; private List<OneToManyAccessor> m_oneToManys; private List<OneToOneAccessor> m_oneToOnes; private List<VariableOneToOneAccessor> m_variableOneToOnes; private List<TransformationAccessor> m_transformations; private List<TransientAccessor> m_transients; private List<VersionAccessor> m_versions; private List<StructureAccessor> m_structures; private List<ArrayAccessor> m_arrays; /** * INTERNAL: */ public XMLAttributes() { super("<attributes>"); } /** * INTERNAL: */ @Override public boolean equals(Object objectToCompare) { if (objectToCompare instanceof XMLAttributes) { XMLAttributes attributes = (XMLAttributes) objectToCompare; if (! valuesMatch(m_embeddedId, attributes.getEmbeddedId())) { return false; } if (! valuesMatch(m_basics, attributes.getBasics())) { return false; } if (! valuesMatch(m_basicCollections, attributes.getBasicCollections())) { return false; } if (! valuesMatch(m_basicMaps, attributes.getBasicMaps())) { return false; } if (! valuesMatch(m_elementCollections, attributes.getElementCollections())) { return false; } if (! valuesMatch(m_embeddeds, attributes.getEmbeddeds())) { return false; } if (! valuesMatch(m_ids, attributes.getIds())) { return false; } if (! valuesMatch(m_manyToManys, attributes.getManyToManys())) { return false; } if (! valuesMatch(m_manyToOnes, attributes.getManyToOnes())) { return false; } if (! valuesMatch(m_oneToManys, attributes.getOneToManys())) { return false; } if (! valuesMatch(m_oneToOnes, attributes.getOneToOnes())) { return false; } if (! valuesMatch(m_variableOneToOnes, attributes.getVariableOneToOnes())) { return false; } if (! valuesMatch(m_transformations, attributes.getTransformations())) { return false; } if (! valuesMatch(m_transients, attributes.getTransients())) { return false; } if (! valuesMatch(m_structures, attributes.getStructures())) { return false; } if (! valuesMatch(m_arrays, attributes.getArrays())) { return false; } return valuesMatch(m_versions, attributes.getVersions()); } return false; } @Override public int hashCode() { int result = m_embeddedId != null ? m_embeddedId.hashCode() : 0; result = 31 * result + (m_basics != null ? m_basics.hashCode() : 0); result = 31 * result + (m_basicCollections != null ? m_basicCollections.hashCode() : 0); result = 31 * result + (m_basicMaps != null ? m_basicMaps.hashCode() : 0); result = 31 * result + (m_elementCollections != null ? m_elementCollections.hashCode() : 0); result = 31 * result + (m_embeddeds != null ? m_embeddeds.hashCode() : 0); result = 31 * result + (m_ids != null ? m_ids.hashCode() : 0); result = 31 * result + (m_manyToManys != null ? m_manyToManys.hashCode() : 0); result = 31 * result + (m_manyToOnes != null ? m_manyToOnes.hashCode() : 0); result = 31 * result + (m_oneToManys != null ? m_oneToManys.hashCode() : 0); result = 31 * result + (m_oneToOnes != null ? m_oneToOnes.hashCode() : 0); result = 31 * result + (m_variableOneToOnes != null ? m_variableOneToOnes.hashCode() : 0); result = 31 * result + (m_transformations != null ? m_transformations.hashCode() : 0); result = 31 * result + (m_transients != null ? m_transients.hashCode() : 0); result = 31 * result + (m_versions != null ? m_versions.hashCode() : 0); result = 31 * result + (m_structures != null ? m_structures.hashCode() : 0); result = 31 * result + (m_arrays != null ? m_arrays.hashCode() : 0); return result; } /** * INTERNAL: * This list is not cached and should not be cached since our accessors * may change in a merge. The accessors list gets rebuilt every time * this method is called (which should only ever be once!) */ public List<MappingAccessor> getAccessors() { List<MappingAccessor> accessors = new ArrayList<MappingAccessor>(); if (m_embeddedId != null) { accessors.add(m_embeddedId); } accessors.addAll(m_ids); accessors.addAll(m_basics); accessors.addAll(m_basicCollections); accessors.addAll(m_basicMaps); accessors.addAll(m_versions); accessors.addAll(m_embeddeds); accessors.addAll(m_elementCollections); accessors.addAll(m_transformations); accessors.addAll(m_transients); accessors.addAll(m_manyToManys); accessors.addAll(m_manyToOnes); accessors.addAll(m_oneToManys); accessors.addAll(m_oneToOnes); accessors.addAll(m_variableOneToOnes); accessors.addAll(m_structures); accessors.addAll(m_arrays); return accessors; } /** * INTERNAL: * Used for OX mapping. */ public List<ArrayAccessor> getArrays() { return m_arrays; } /** * INTERNAL: * Used for OX mapping. */ public List<BasicCollectionAccessor> getBasicCollections() { return m_basicCollections; } /** * INTERNAL: * Used for OX mapping. */ public List<BasicMapAccessor> getBasicMaps() { return m_basicMaps; } /** * INTERNAL: * Used for OX mapping. */ public List<BasicAccessor> getBasics() { return m_basics; } /** * INTERNAL: * Used for OX mapping. */ public List<ElementCollectionAccessor> getElementCollections() { return m_elementCollections; } /** * INTERNAL: * Used for OX mapping. */ public EmbeddedIdAccessor getEmbeddedId() { return m_embeddedId; } /** * INTERNAL: * Used for OX mapping. */ public List<EmbeddedAccessor> getEmbeddeds() { return m_embeddeds; } /** * INTERNAL: * Used for OX mapping. */ public List<IdAccessor> getIds() { return m_ids; } /** * INTERNAL: * Used for OX mapping. */ public List<ManyToManyAccessor> getManyToManys() { return m_manyToManys; } /** * INTERNAL: * Used for OX mapping. */ public List<ManyToOneAccessor> getManyToOnes() { return m_manyToOnes; } /** * INTERNAL: * Used for OX mapping. */ public List<OneToManyAccessor> getOneToManys() { return m_oneToManys; } /** * INTERNAL: * Used for OX mapping. */ public List<OneToOneAccessor> getOneToOnes() { return m_oneToOnes; } /** * INTERNAL: * Used for OX mapping. */ public List<StructureAccessor> getStructures() { return m_structures; } /** * INTERNAL: * Used for OX mapping. */ public List<TransformationAccessor> getTransformations() { return m_transformations; } /** * INTERNAL: * Used for OX mapping. */ public List<TransientAccessor> getTransients() { return m_transients; } /** * INTERNAL: * Used for OX mapping. */ public List<VariableOneToOneAccessor> getVariableOneToOnes() { return m_variableOneToOnes; } /** * INTERNAL: * Used for OX mapping. */ public List<VersionAccessor> getVersions() { return m_versions; } /** * INTERNAL: * This is going to initialize the accessible objects. */ @Override public void initXMLObject(MetadataAccessibleObject accessibleObject, XMLEntityMappings entityMappings) { super.initXMLObject(accessibleObject, entityMappings); // For merging purposes we will initialize the accessors with the owning // classes accessible object. The actual accessible object (field or // method) for each accessor will be set during the actual metadata // processing stage. // Initialize single objects. initXMLObject(m_embeddedId, accessibleObject); // Initialize lists of objects. initXMLObjects(m_basics, accessibleObject); initXMLObjects(m_basicCollections, accessibleObject); initXMLObjects(m_basicMaps, accessibleObject); initXMLObjects(m_elementCollections, accessibleObject); initXMLObjects(m_embeddeds, accessibleObject); initXMLObjects(m_ids, accessibleObject); initXMLObjects(m_manyToManys, accessibleObject); initXMLObjects(m_manyToOnes, accessibleObject); initXMLObjects(m_oneToManys, accessibleObject); initXMLObjects(m_oneToOnes, accessibleObject); initXMLObjects(m_variableOneToOnes, accessibleObject); initXMLObjects(m_transformations, accessibleObject); initXMLObjects(m_transients, accessibleObject); initXMLObjects(m_versions, accessibleObject); initXMLObjects(m_structures, accessibleObject); initXMLObjects(m_arrays, accessibleObject); } /** * INTERNAL: * Since we are controlling the merging and we know we'll be comparing * apples with apples, the casting is safe to assume. */ @Override public void merge(ORMetadata metadata) { if (metadata != null) { XMLAttributes attributes = (XMLAttributes) metadata; // ORMetadata object merging m_embeddedId = (EmbeddedIdAccessor) mergeORObjects(getEmbeddedId(), attributes.getEmbeddedId()); // ORMetadata list merging. m_basics = mergeORObjectLists(m_basics, attributes.getBasics()); m_basicCollections = mergeORObjectLists(m_basicCollections, attributes.getBasicCollections()); m_basicMaps = mergeORObjectLists(m_basicMaps, attributes.getBasicMaps()); m_elementCollections = mergeORObjectLists(m_elementCollections, attributes.getElementCollections()); m_embeddeds = mergeORObjectLists(m_embeddeds, attributes.getEmbeddeds()); m_ids = mergeORObjectLists(m_ids, attributes.getIds()); m_manyToManys = mergeORObjectLists(m_manyToManys, attributes.getManyToManys()); m_manyToOnes = mergeORObjectLists(m_manyToOnes, attributes.getManyToOnes()); m_oneToManys = mergeORObjectLists(m_oneToManys, attributes.getOneToManys()); m_oneToOnes = mergeORObjectLists(m_oneToOnes, attributes.getOneToOnes()); m_variableOneToOnes = mergeORObjectLists(m_variableOneToOnes, attributes.getVariableOneToOnes()); m_transformations = mergeORObjectLists(m_transformations, attributes.getTransformations()); m_transients = mergeORObjectLists(m_transients, attributes.getTransients()); m_versions = mergeORObjectLists(m_versions, attributes.getVersions()); m_structures = mergeORObjectLists(m_structures, attributes.getStructures()); m_arrays = mergeORObjectLists(m_arrays, attributes.getArrays()); } } /** * INTERNAL: * Used for OX mapping. */ public void setArrays(List<ArrayAccessor> arrays) { m_arrays = arrays; } /** * INTERNAL: * Used for OX mapping. */ public void setBasicCollections(List<BasicCollectionAccessor> basicCollections) { m_basicCollections = basicCollections; } /** * INTERNAL: * Used for OX mapping. */ public void setBasicMaps(List<BasicMapAccessor> basicMaps) { m_basicMaps = basicMaps; } /** * INTERNAL: * Used for OX mapping. */ public void setBasics(List<BasicAccessor> basics) { m_basics = basics; } /** * INTERNAL: * Used for OX mapping. */ public void setElementCollections(List<ElementCollectionAccessor> elementCollections) { m_elementCollections = elementCollections; } /** * INTERNAL: * Used for OX mapping. */ public void setEmbeddedId(EmbeddedIdAccessor embeddedId) { m_embeddedId = embeddedId; } /** * INTERNAL: * Used for OX mapping. */ public void setEmbeddeds(List<EmbeddedAccessor> embeddeds) { m_embeddeds = embeddeds; } /** * INTERNAL: * Used for OX mapping. */ public void setIds(List<IdAccessor> ids) { m_ids = ids; } /** * INTERNAL: * Used for OX mapping. */ public void setManyToManys(List<ManyToManyAccessor> manyToManys) { m_manyToManys = manyToManys; } /** * INTERNAL: * Used for OX mapping. */ public void setManyToOnes(List<ManyToOneAccessor> manyToOnes) { m_manyToOnes = manyToOnes; } /** * INTERNAL: * Used for OX mapping. */ public void setOneToManys(List<OneToManyAccessor> oneToManys) { m_oneToManys = oneToManys; } /** * INTERNAL: * Used for OX mapping. */ public void setOneToOnes(List<OneToOneAccessor> oneToOnes) { m_oneToOnes = oneToOnes; } /** * INTERNAL: * Used for OX mapping. */ public void setStructures(List<StructureAccessor> structures) { m_structures = structures; } /** * INTERNAL: * Used for OX mapping. */ public void setTransformations(List<TransformationAccessor> transformations) { m_transformations = transformations; } /** * INTERNAL: * Used for OX mapping. */ public void setTransients(List<TransientAccessor> transients) { m_transients = transients; } /** * INTERNAL: * Used for OX mapping. */ public void setVariableOneToOnes(List<VariableOneToOneAccessor> variableOneToOnes) { m_variableOneToOnes = variableOneToOnes; } /** * INTERNAL: * Used for OX mapping. */ public void setVersions(List<VersionAccessor> versions) { m_versions = versions; } }