blob: 1ffaceb0e10313337c85ba67839c1637e310805a [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2006, 2013 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.orm;
import java.util.List;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IType;
import org.eclipse.jpt.common.core.internal.utility.JavaProjectTools;
import org.eclipse.jpt.common.core.resource.java.JavaResourceType;
import org.eclipse.jpt.common.core.utility.TextRange;
import org.eclipse.jpt.common.utility.internal.iterable.FilteringIterable;
import org.eclipse.jpt.common.utility.internal.iterable.IterableTools;
import org.eclipse.jpt.jpa.core.context.AttributeMapping;
import org.eclipse.jpt.jpa.core.context.Generator;
import org.eclipse.jpt.jpa.core.context.IdTypeMapping;
import org.eclipse.jpt.jpa.core.context.PersistentAttribute;
import org.eclipse.jpt.jpa.core.context.PersistentType;
import org.eclipse.jpt.jpa.core.context.SpecifiedColumn;
import org.eclipse.jpt.jpa.core.context.SpecifiedRelationship;
import org.eclipse.jpt.jpa.core.context.java.JavaPersistentType;
import org.eclipse.jpt.jpa.core.context.java.JavaTypeMapping;
import org.eclipse.jpt.jpa.core.context.orm.EntityMappings;
import org.eclipse.jpt.jpa.core.context.orm.OrmPersistentAttribute;
import org.eclipse.jpt.jpa.core.context.orm.OrmPersistentType;
import org.eclipse.jpt.jpa.core.context.orm.OrmTypeMapping;
import org.eclipse.jpt.jpa.core.internal.context.JpaValidator;
import org.eclipse.jpt.jpa.core.internal.context.TypeMappingTools;
import org.eclipse.jpt.jpa.core.internal.jpa1.context.GenericTypeMappingValidator;
import org.eclipse.jpt.jpa.core.resource.orm.XmlTypeMapping;
import org.eclipse.jpt.jpa.db.Schema;
import org.eclipse.jpt.jpa.db.Table;
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>orm.xml</code> type mapping
*/
public abstract class AbstractOrmTypeMapping<X extends XmlTypeMapping>
extends AbstractOrmXmlContextModel<OrmPersistentType>
implements OrmTypeMapping {
// never null
protected final X xmlTypeMapping;
protected Boolean specifiedMetadataComplete;
protected boolean overrideMetadataComplete;
protected String specifiedParentClass;
protected String defaultParentClass;
protected String fullyQualifiedParentClass;
protected AbstractOrmTypeMapping(OrmPersistentType parent, X xmlTypeMapping) {
super(parent);
this.xmlTypeMapping = xmlTypeMapping;
this.specifiedMetadataComplete = xmlTypeMapping.getMetadataComplete();
this.specifiedParentClass = this.buildSpecifiedParentClass();
}
// ********** synchronize/update **********
@Override
public void synchronizeWithResourceModel() {
super.synchronizeWithResourceModel();
setSpecifiedMetadataComplete_(xmlTypeMapping.getMetadataComplete());
setSpecifiedParentClass_(buildSpecifiedParentClass());
}
@Override
public void update() {
super.update();
setOverrideMetadataComplete(buildOverrideMetadataComplete());
setDefaultParentClass(buildDefaultParentClass());
setFullyQualifiedParentClass(buildFullyQualifiedParentClass());
}
// ********** metadata complete **********
/**
* If <code>entity-mappings/persistence-unit-metadata/xml-mapping-metadata-complete</code>
* is specified, it overrides anything set here.
*/
public boolean isMetadataComplete() {
if (this.overrideMetadataComplete) {
return true;
}
return (this.specifiedMetadataComplete != null) ? this.specifiedMetadataComplete.booleanValue() : false;
}
public Boolean getSpecifiedMetadataComplete() {
return this.specifiedMetadataComplete;
}
public void setSpecifiedMetadataComplete(Boolean metadataComplete) {
this.setSpecifiedMetadataComplete_(metadataComplete);
this.xmlTypeMapping.setMetadataComplete(metadataComplete);
}
protected void setSpecifiedMetadataComplete_(Boolean metadataComplete) {
Boolean old = this.specifiedMetadataComplete;
this.specifiedMetadataComplete = metadataComplete;
this.firePropertyChanged(SPECIFIED_METADATA_COMPLETE_PROPERTY, old, metadataComplete);
}
public boolean isOverrideMetadataComplete() {
return this.overrideMetadataComplete;
}
protected void setOverrideMetadataComplete(boolean metadataComplete) {
boolean old = this.overrideMetadataComplete;
this.overrideMetadataComplete = metadataComplete;
this.firePropertyChanged(OVERRIDE_METADATA_COMPLETE_PROPERTY, old, metadataComplete);
}
protected boolean buildOverrideMetadataComplete() {
return this.getPersistenceUnit().isXmlMappingMetadataComplete();
}
// ********** fully-qualified parent class **********
public String getFullyQualifiedParentClass() {
return this.fullyQualifiedParentClass;
}
protected void setFullyQualifiedParentClass(String parentClass) {
String old = this.fullyQualifiedParentClass;
this.fullyQualifiedParentClass = parentClass;
this.firePropertyChanged(FULLY_QUALIFIED_PARENT_CLASS_PROPERTY, old, parentClass);
}
protected String buildFullyQualifiedParentClass() {
return (this.specifiedParentClass == null) ?
this.defaultParentClass :
this.getEntityMappings().qualify(this.specifiedParentClass);
}
// ********** parent class **********
public String getParentClass() {
return (this.specifiedParentClass != null) ? this.specifiedParentClass : this.defaultParentClass;
}
public String getSpecifiedParentClass() {
return this.specifiedParentClass;
}
public void setSpecifiedParentClass(String parentClass) {
this.setSpecifiedParentClass_(parentClass);
this.setSpecifiedParentClassInXml(parentClass);
}
protected void setSpecifiedParentClass_(String parentClass) {
String old = this.specifiedParentClass;
this.specifiedParentClass = parentClass;
this.firePropertyChanged(SPECIFIED_PARENT_CLASS_PROPERTY, old, parentClass);
}
/**
* subclasses must override if they support specifying a parent class
*/
protected void setSpecifiedParentClassInXml(@SuppressWarnings("unused") String parentClass) {
// NOP
}
/**
* subclasses must override if they support specifying a parent class
*/
protected String buildSpecifiedParentClass() {
return null;
}
public String getDefaultParentClass() {
return this.defaultParentClass;
}
protected void setDefaultParentClass(String parentClass) {
String old = this.defaultParentClass;
this.defaultParentClass = parentClass;
this.firePropertyChanged(DEFAULT_PARENT_CLASS_PROPERTY, old, parentClass);
}
protected String buildDefaultParentClass() {
JavaResourceType javaResourceType = this.getJavaResourceType();
return (javaResourceType == null) ? null : javaResourceType.getSuperclassQualifiedName();
}
protected PersistentType getResolvedParentClass() {
if (this.fullyQualifiedParentClass == null) {
return null;
}
return this.getPersistenceUnit().getPersistentType(this.fullyQualifiedParentClass);
}
// ********** Java type mapping **********
public JavaTypeMapping getJavaTypeMapping() {
JavaPersistentType javaType = this.getJavaPersistentType();
if (javaType == null) {
return null;
}
return (javaType.getMappingKey() == this.getKey()) ? javaType.getMapping() : null;
}
public JavaTypeMapping getJavaTypeMappingForDefaults() {
return this.isMetadataComplete() ? null : this.getJavaTypeMapping();
}
// ********** misc **********
public OrmPersistentType getPersistentType() {
return this.parent;
}
public String getName() {
return this.getPersistentType().getName();
}
protected JavaPersistentType getJavaPersistentType() {
return this.getPersistentType().getJavaPersistentType();
}
public JavaResourceType getJavaResourceType() {
JavaPersistentType javaType = this.getJavaPersistentType();
return (javaType == null) ? null : javaType.getJavaResourceType();
}
protected EntityMappings getEntityMappings() {
return this.getPersistentType().getParent();
}
public boolean isMapped() {
return true;
}
/**
* A type's mapping is being changed. Copy the common settings from the old
* mapping to the new (this).
*/
public void initializeFrom(OrmTypeMapping oldMapping) {
this.setSpecifiedMetadataComplete(oldMapping.getSpecifiedMetadataComplete());
this.setOverrideMetadataComplete(oldMapping.isOverrideMetadataComplete());
}
public X getXmlTypeMapping() {
return this.xmlTypeMapping;
}
public boolean attributeIsDerivedId(String attributeName) {
return TypeMappingTools.attributeIsDerivedId(this, attributeName);
}
@Override
public void toString(StringBuilder sb) {
sb.append(this.getPersistentType().getName());
}
// ********** tables **********
public String getPrimaryTableName() {
return null;
}
public Table getPrimaryDbTable() {
return null;
}
public Table resolveDbTable(String tableName) {
return null;
}
public Schema getDbSchema() {
return null;
}
// ********** attribute mappings **********
public boolean attributeMappingKeyAllowed(String attributeMappingKey) {
return true;
}
public Iterable<AttributeMapping> getAttributeMappings() {
return IterableTools.transform(getPersistentType().getAttributes(), OrmPersistentAttribute.MAPPING_TRANSFORMER);
}
public Iterable<AttributeMapping> getAllAttributeMappings() {
return IterableTools.transform(getPersistentType().getAllAttributes(), PersistentAttribute.MAPPING_TRANSFORMER);
}
public Iterable<String> getOverridableAttributeNames() {
return IterableTools.children(getAttributeMappings(), AttributeMapping.ALL_OVERRIDABLE_ATTRIBUTE_MAPPING_NAMES_TRANSFORMER);
}
public Iterable<String> getAllOverridableAttributeNames() {
return IterableTools.children(getInheritanceHierarchy(), TypeMappingTools.OVERRIDABLE_ATTRIBUTE_NAMES_TRANSFORMER);
}
public Iterable<AttributeMapping> getAttributeMappings(final String mappingKey) {
return IterableTools.filter(getAttributeMappings(), new AttributeMapping.KeyEquals(mappingKey));
}
public Iterable<AttributeMapping> getAllAttributeMappings(final String mappingKey) {
return IterableTools.filter(getAllAttributeMappings(), new AttributeMapping.KeyEquals(mappingKey));
}
public Iterable<AttributeMapping> getNonTransientAttributeMappings() {
return new FilteringIterable<AttributeMapping>(getAllAttributeMappings(), AttributeMapping.IS_NOT_TRANSIENT);
}
public Iterable<AttributeMapping> getIdAttributeMappings() {
return IterableTools.filter(getAllAttributeMappings(), new IdTypeMapping.MappingIsIdMapping());
}
public AttributeMapping getIdAttributeMapping() {
Iterable<AttributeMapping> idMappings = getIdAttributeMappings();
if (IterableTools.size(idMappings) == 1) {
return IterableTools.get(idMappings, 0);
}
return null;
}
public SpecifiedColumn resolveOverriddenColumn(String attributeName) {
for (AttributeMapping attributeMapping : getAttributeMappings()) {
SpecifiedColumn column = attributeMapping.resolveOverriddenColumn(attributeName);
if (column != null) {
return column;
}
}
if ( ! isMetadataComplete()) {
JavaPersistentType javaPersistentType = getJavaPersistentType();
if (javaPersistentType != null) {
return javaPersistentType.getMapping().resolveOverriddenColumn(attributeName);
}
}
return null;
}
public Iterable<String> getOverridableAssociationNames() {
return IterableTools.children(getAttributeMappings(), AttributeMapping.ALL_OVERRIDABLE_ASSOCIATION_MAPPING_NAMES_TRANSFORMER);
}
public Iterable<String> getAllOverridableAssociationNames() {
return IterableTools.children(getInheritanceHierarchy(), TypeMappingTools.OVERRIDABLE_ASSOCIATION_NAMES_TRANSFORMER);
}
public SpecifiedRelationship resolveOverriddenRelationship(String attributeName) {
for (AttributeMapping attributeMapping : getAttributeMappings()) {
SpecifiedRelationship relationship = attributeMapping.resolveOverriddenRelationship(attributeName);
if (relationship != null) {
return relationship;
}
}
if ( ! isMetadataComplete()) {
JavaPersistentType javaPersistentType = getJavaPersistentType();
if (javaPersistentType != null) {
return javaPersistentType.getMapping().resolveOverriddenRelationship(attributeName);
}
}
return null;
}
// ********** text ranges **********
public TextRange getSelectionTextRange() {
return this.xmlTypeMapping.getSelectionTextRange();
}
public TextRange getAttributesTextRange() {
return this.getValidationTextRange(this.xmlTypeMapping.getAttributesTextRange());
}
// ********** refactoring **********
public Iterable<ReplaceEdit> createRenameTypeEdits(IType originalType, String newName) {
return IterableTools.<ReplaceEdit>emptyIterable();
}
public Iterable<ReplaceEdit> createMoveTypeEdits(IType originalType, IPackageFragment newPackage) {
return IterableTools.<ReplaceEdit>emptyIterable();
}
public Iterable<ReplaceEdit> createRenamePackageEdits(IPackageFragment originalPackage, String newName) {
return IterableTools.<ReplaceEdit>emptyIterable();
}
// ********** generators **********
public Iterable<Generator> getGenerators() {
return IterableTools.children(this.getAttributeMappings(), AttributeMapping.GENERATORS_TRANSFORMER);
}
// ********** validation **********
@Override
public void validate(List<IMessage> messages, IReporter reporter) {
super.validate(messages, reporter);
this.validateClass(messages, reporter);
}
protected void validateClass(List<IMessage> messages, IReporter reporter) {
if (this.getJavaResourceType() != null) {
this.buildTypeMappingValidator().validate(messages, reporter);
}
}
/**
* Pre-condition: the mapping's {@link #getJavaResourceType() Java resource
* type} is not <code>null</code>.
*/
protected JpaValidator buildTypeMappingValidator() {
return new GenericTypeMappingValidator(this);
}
public boolean validatesAgainstDatabase() {
return this.getPersistenceUnit().validatesAgainstDatabase();
}
public TextRange getValidationTextRange() {
return this.getPersistentType().getValidationTextRange();
}
protected Iterable<String> getCandidateClassNames() {
return JavaProjectTools.getJavaClassNames(this.getJavaProject());
}
}