/******************************************************************************* * Copyright (c) 2010, 2011 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.jpt.common.core.utility.TextRange; import org.eclipse.jpt.common.utility.internal.iterables.EmptyIterable; import org.eclipse.jpt.common.utility.internal.iterables.EmptyListIterable; import org.eclipse.jpt.common.utility.internal.iterables.ListIterable; import org.eclipse.jpt.common.utility.internal.iterables.SingleElementListIterable; import org.eclipse.jpt.common.utility.internal.iterables.SuperListIterableWrapper; import org.eclipse.jpt.jpa.core.context.Entity; import org.eclipse.jpt.jpa.core.context.ReadOnlyBaseColumn; import org.eclipse.jpt.jpa.core.context.ReadOnlyBaseJoinColumn; import org.eclipse.jpt.jpa.core.context.ReadOnlyJoinColumn; import org.eclipse.jpt.jpa.core.context.ReadOnlyJoinColumnRelationship; import org.eclipse.jpt.jpa.core.context.ReadOnlyJoinColumnRelationshipStrategy; import org.eclipse.jpt.jpa.core.context.ReadOnlyNamedColumn; import org.eclipse.jpt.jpa.core.context.ReadOnlyRelationship; import org.eclipse.jpt.jpa.core.context.RelationshipMapping; import org.eclipse.jpt.jpa.core.context.TypeMapping; import org.eclipse.jpt.jpa.core.context.orm.OrmReadOnlyJoinColumn; import org.eclipse.jpt.jpa.core.context.orm.OrmVirtualJoinColumn; import org.eclipse.jpt.jpa.core.context.orm.OrmVirtualJoinColumnRelationshipStrategy; import org.eclipse.jpt.jpa.core.context.orm.OrmVirtualOverrideRelationship; import org.eclipse.jpt.jpa.core.internal.context.BaseColumnTextRangeResolver; import org.eclipse.jpt.jpa.core.internal.context.JptValidator; import org.eclipse.jpt.jpa.core.internal.context.NamedColumnTextRangeResolver; import org.eclipse.jpt.jpa.db.Table; import org.eclipse.wst.validation.internal.provisional.core.IMessage; import org.eclipse.wst.validation.internal.provisional.core.IReporter; public class GenericOrmVirtualOverrideJoinColumnRelationshipStrategy extends AbstractOrmXmlContextNode implements OrmVirtualJoinColumnRelationshipStrategy { protected final ContextListContainer specifiedJoinColumnContainer; protected final OrmReadOnlyJoinColumn.Owner joinColumnOwner; protected OrmVirtualJoinColumn defaultJoinColumn; public GenericOrmVirtualOverrideJoinColumnRelationshipStrategy(OrmVirtualOverrideRelationship parent) { super(parent); this.joinColumnOwner = this.buildJoinColumnOwner(); this.specifiedJoinColumnContainer = this.buildSpecifiedJoinColumnContainer(); } // ********** synchronize/update ********** @Override public void update() { super.update(); this.updateSpecifiedJoinColumns(); this.updateDefaultJoinColumn(); } // ********** join columns ********** public ListIterable getJoinColumns() { return this.hasSpecifiedJoinColumns() ? this.getSpecifiedJoinColumns() : this.getDefaultJoinColumns(); } public int getJoinColumnsSize() { return this.hasSpecifiedJoinColumns() ? this.getSpecifiedJoinColumnsSize() : this.getDefaultJoinColumnsSize(); } // ********** specified join columns ********** public ListIterable getSpecifiedJoinColumns() { return this.specifiedJoinColumnContainer.getContextElements(); } public int getSpecifiedJoinColumnsSize() { return this.specifiedJoinColumnContainer.getContextElementsSize(); } public boolean hasSpecifiedJoinColumns() { return this.getSpecifiedJoinColumnsSize() != 0; } public OrmVirtualJoinColumn getSpecifiedJoinColumn(int index) { return this.specifiedJoinColumnContainer.getContextElement(index); } protected void updateSpecifiedJoinColumns() { this.specifiedJoinColumnContainer.update(); } protected ListIterable getOverriddenSpecifiedJoinColumns() { ReadOnlyJoinColumnRelationshipStrategy overriddenStrategy = this.getOverriddenStrategy(); return (overriddenStrategy == null) ? EmptyListIterable.instance() : new SuperListIterableWrapper(overriddenStrategy.getSpecifiedJoinColumns()); } protected void moveSpecifiedJoinColumn(int index, OrmVirtualJoinColumn joinColumn) { this.specifiedJoinColumnContainer.moveContextElement(index, joinColumn); } protected OrmVirtualJoinColumn addSpecifiedJoinColumn(int index, ReadOnlyJoinColumn joinColumn) { return this.specifiedJoinColumnContainer.addContextElement(index, joinColumn); } protected void removeSpecifiedJoinColumn(OrmVirtualJoinColumn joinColumn) { this.specifiedJoinColumnContainer.removeContextElement(joinColumn); } protected ContextListContainer buildSpecifiedJoinColumnContainer() { return new SpecifiedJoinColumnContainer(); } /** * specified join column container */ protected class SpecifiedJoinColumnContainer extends ContextListContainer { @Override protected String getContextElementsPropertyName() { return SPECIFIED_JOIN_COLUMNS_LIST; } @Override protected OrmVirtualJoinColumn buildContextElement(ReadOnlyJoinColumn resourceElement) { return GenericOrmVirtualOverrideJoinColumnRelationshipStrategy.this.buildJoinColumn(resourceElement); } @Override protected ListIterable getResourceElements() { return GenericOrmVirtualOverrideJoinColumnRelationshipStrategy.this.getOverriddenSpecifiedJoinColumns(); } @Override protected ReadOnlyJoinColumn getResourceElement(OrmVirtualJoinColumn contextElement) { return contextElement.getOverriddenColumn(); } } protected OrmReadOnlyJoinColumn.Owner buildJoinColumnOwner() { return new JoinColumnOwner(); } // ********** default join column ********** public OrmVirtualJoinColumn getDefaultJoinColumn() { return this.defaultJoinColumn; } protected void setDefaultJoinColumn(OrmVirtualJoinColumn joinColumn) { OrmVirtualJoinColumn old = this.defaultJoinColumn; this.defaultJoinColumn = joinColumn; this.firePropertyChanged(DEFAULT_JOIN_COLUMN_PROPERTY, old, joinColumn); } protected ListIterable getDefaultJoinColumns() { return (this.defaultJoinColumn != null) ? new SingleElementListIterable(this.defaultJoinColumn) : EmptyListIterable.instance(); } protected int getDefaultJoinColumnsSize() { return (this.defaultJoinColumn == null) ? 0 : 1; } protected void updateDefaultJoinColumn() { ReadOnlyJoinColumn overriddenDefaultJoinColumn = this.getOverriddenDefaultJoinColumn(); if (overriddenDefaultJoinColumn == null) { if (this.defaultJoinColumn != null) { this.setDefaultJoinColumn(null); } } else { if ((this.defaultJoinColumn != null) && (this.defaultJoinColumn.getOverriddenColumn() == overriddenDefaultJoinColumn)) { this.defaultJoinColumn.update(); } else { this.setDefaultJoinColumn(this.buildJoinColumn(overriddenDefaultJoinColumn)); } } } protected ReadOnlyJoinColumn getOverriddenDefaultJoinColumn() { ReadOnlyJoinColumnRelationshipStrategy overriddenStrategy = this.getOverriddenStrategy(); return (overriddenStrategy == null) ? null : overriddenStrategy.getDefaultJoinColumn(); } // ********** misc ********** @Override public OrmVirtualOverrideRelationship getParent() { return (OrmVirtualOverrideRelationship) super.getParent(); } public OrmVirtualOverrideRelationship getRelationship() { return this.getParent(); } protected ReadOnlyJoinColumnRelationshipStrategy getOverriddenStrategy() { ReadOnlyJoinColumnRelationship relationship = this.getOverriddenJoinColumnRelationship(); return (relationship == null) ? null : relationship.getJoinColumnStrategy(); } protected ReadOnlyJoinColumnRelationship getOverriddenJoinColumnRelationship() { ReadOnlyRelationship relationship = this.resolveOverriddenRelationship(); return (relationship instanceof ReadOnlyJoinColumnRelationship) ? (ReadOnlyJoinColumnRelationship) relationship : null; } protected ReadOnlyRelationship resolveOverriddenRelationship() { return this.getRelationship().resolveOverriddenRelationship(); } public boolean isTargetForeignKey() { RelationshipMapping relationshipMapping = this.getRelationshipMapping(); return (relationshipMapping != null) && relationshipMapping.getRelationship().isTargetForeignKey(); } public TypeMapping getRelationshipSource() { return this.isTargetForeignKey() ? // relationship mapping is not null this.getRelationshipMapping().getResolvedTargetEntity() : this.getRelationship().getTypeMapping(); } public TypeMapping getRelationshipTarget() { return this.isTargetForeignKey() ? this.getRelationship().getTypeMapping() : // relationship mapping may still be null this.getRelationshipMappingTargetEntity(); } protected TypeMapping getRelationshipMappingTargetEntity() { RelationshipMapping mapping = this.getRelationshipMapping(); return (mapping == null) ? null : mapping.getResolvedTargetEntity(); } protected Entity getRelationshipTargetEntity() { TypeMapping target = this.getRelationshipTarget(); return (target instanceof Entity) ? (Entity) target : null; } protected RelationshipMapping getRelationshipMapping() { return this.getRelationship().getMapping(); } public String getTableName() { return this.isTargetForeignKey() ? this.getTargetDefaultTableName() : this.getRelationship().getDefaultTableName(); } protected String getTargetDefaultTableName() { TypeMapping typeMapping = this.getRelationshipMapping().getResolvedTargetEntity(); return (typeMapping == null) ? null : typeMapping.getPrimaryTableName(); } protected Table resolveDbTable(String tableName) { return this.isTargetForeignKey() ? this.resolveTargetDbTable(tableName) : this.getRelationship().resolveDbTable(tableName); } protected Table resolveTargetDbTable(String tableName) { TypeMapping typeMapping = this.getRelationshipMapping().getResolvedTargetEntity(); return (typeMapping == null) ? null : typeMapping.resolveDbTable(tableName); } protected boolean tableNameIsInvalid(String tableName) { return this.isTargetForeignKey() ? this.targetTableNameIsInvalid(tableName) : this.getRelationship().tableNameIsInvalid(tableName); } protected boolean targetTableNameIsInvalid(String tableName) { TypeMapping typeMapping = this.getRelationshipMapping().getResolvedTargetEntity(); return (typeMapping != null) && typeMapping.tableNameIsInvalid(tableName); } protected Table getReferencedColumnDbTable() { TypeMapping relationshipTarget = this.getRelationshipTarget(); return (relationshipTarget == null) ? null : relationshipTarget.getPrimaryDbTable(); } protected Iterable getCandidateTableNames() { return this.isTargetForeignKey() ? this.getTargetCandidateTableNames() : this.getRelationship().getCandidateTableNames(); } protected Iterable getTargetCandidateTableNames() { TypeMapping typeMapping = this.getRelationshipMapping().getResolvedTargetEntity(); return (typeMapping != null) ? typeMapping.getAllAssociatedTableNames() : EmptyIterable.instance(); } public TextRange getValidationTextRange() { return this.getRelationship().getValidationTextRange(); } protected String getAttributeName() { return this.getRelationship().getAttributeName(); } protected OrmVirtualJoinColumn buildJoinColumn(ReadOnlyJoinColumn overriddenJoinColumn) { return this.getContextNodeFactory().buildOrmVirtualJoinColumn(this, this.joinColumnOwner, overriddenJoinColumn); } // ********** validation ********** @Override public void validate(List messages, IReporter reporter) { super.validate(messages, reporter); for (OrmVirtualJoinColumn joinColumn : this.getJoinColumns()) { joinColumn.validate(messages, reporter); } } // ********** join column owner ********** protected class JoinColumnOwner implements OrmReadOnlyJoinColumn.Owner { protected JoinColumnOwner() { super(); } public String getDefaultTableName() { return GenericOrmVirtualOverrideJoinColumnRelationshipStrategy.this.getTableName(); } public String getDefaultColumnName() { //built in MappingTools.buildJoinColumnDefaultName() return null; } public String getAttributeName() { return GenericOrmVirtualOverrideJoinColumnRelationshipStrategy.this.getAttributeName(); } public TypeMapping getTypeMapping() { return GenericOrmVirtualOverrideJoinColumnRelationshipStrategy.this.getRelationshipSource(); } public Entity getRelationshipTarget() { return GenericOrmVirtualOverrideJoinColumnRelationshipStrategy.this.getRelationshipTargetEntity(); } public boolean tableNameIsInvalid(String tableName) { return GenericOrmVirtualOverrideJoinColumnRelationshipStrategy.this.tableNameIsInvalid(tableName); } public Iterable getCandidateTableNames() { return GenericOrmVirtualOverrideJoinColumnRelationshipStrategy.this.getCandidateTableNames(); } public Table resolveDbTable(String tableName) { return GenericOrmVirtualOverrideJoinColumnRelationshipStrategy.this.resolveDbTable(tableName); } public Table getReferencedColumnDbTable() { return GenericOrmVirtualOverrideJoinColumnRelationshipStrategy.this.getReferencedColumnDbTable(); } public boolean joinColumnIsDefault(ReadOnlyBaseJoinColumn joinColumn) { return false; } public int getJoinColumnsSize() { return GenericOrmVirtualOverrideJoinColumnRelationshipStrategy.this.getJoinColumnsSize(); } public TextRange getValidationTextRange() { return GenericOrmVirtualOverrideJoinColumnRelationshipStrategy.this.getValidationTextRange(); } public JptValidator buildColumnValidator(ReadOnlyNamedColumn column, NamedColumnTextRangeResolver textRangeResolver) { return GenericOrmVirtualOverrideJoinColumnRelationshipStrategy.this.getRelationship().buildColumnValidator((ReadOnlyBaseColumn) column, this, (BaseColumnTextRangeResolver) textRangeResolver); } } }