| /******************************************************************************* |
| * Copyright (c) 2009, 2015 Oracle. All rights reserved. |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License 2.0, which accompanies this distribution |
| * and is available at https://www.eclipse.org/legal/epl-2.0/. |
| * |
| * Contributors: |
| * Oracle - initial API and implementation |
| ******************************************************************************/ |
| package org.eclipse.jpt.jpa.core.internal.context.java; |
| |
| import java.util.List; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.jpt.common.core.utility.TextRange; |
| import org.eclipse.jpt.common.core.utility.ValidationMessage; |
| import org.eclipse.jpt.common.utility.internal.ArrayTools; |
| import org.eclipse.jpt.common.utility.internal.ObjectTools; |
| import org.eclipse.jpt.common.utility.internal.StringTools; |
| import org.eclipse.jpt.common.utility.internal.iterable.TransformationIterable; |
| import org.eclipse.jpt.jpa.core.context.AttributeMapping; |
| import org.eclipse.jpt.jpa.core.context.Entity; |
| import org.eclipse.jpt.jpa.core.context.RelationshipMapping; |
| import org.eclipse.jpt.jpa.core.context.RelationshipStrategy; |
| import org.eclipse.jpt.jpa.core.context.SpecifiedMappedByRelationshipStrategy; |
| import org.eclipse.jpt.jpa.core.context.SpecifiedPersistentAttribute; |
| import org.eclipse.jpt.jpa.core.context.java.JavaMappedByRelationship; |
| import org.eclipse.jpt.jpa.core.jpa2.context.OverrideRelationship2_0; |
| import org.eclipse.jpt.jpa.core.jpa2.context.SpecifiedMappingRelationshipStrategy2_0; |
| import org.eclipse.jpt.jpa.core.resource.java.OwnableRelationshipMappingAnnotation; |
| import org.eclipse.jpt.jpa.core.validation.JptJpaCoreValidationArgumentMessages; |
| import org.eclipse.jpt.jpa.core.validation.JptJpaCoreValidationMessages; |
| import org.eclipse.jpt.jpa.db.Table; |
| import org.eclipse.osgi.util.NLS; |
| import org.eclipse.wst.validation.internal.provisional.core.IMessage; |
| import org.eclipse.wst.validation.internal.provisional.core.IReporter; |
| |
| public class GenericJavaMappedByRelationshipStrategy |
| extends AbstractJavaContextModel<JavaMappedByRelationship> |
| implements SpecifiedMappingRelationshipStrategy2_0, SpecifiedMappedByRelationshipStrategy |
| { |
| protected String mappedByAttribute; |
| |
| |
| public GenericJavaMappedByRelationshipStrategy(JavaMappedByRelationship parent) { |
| super(parent); |
| this.mappedByAttribute = this.buildMappedByAttribute(); |
| } |
| |
| |
| // ********** synchronize/update ********** |
| |
| @Override |
| public void synchronizeWithResourceModel(IProgressMonitor monitor) { |
| super.synchronizeWithResourceModel(monitor); |
| this.setMappedByAttribute_(this.buildMappedByAttribute()); |
| } |
| |
| |
| // ********** mapped by attribute ********** |
| |
| public String getMappedByAttribute() { |
| return this.mappedByAttribute; |
| } |
| |
| public void setMappedByAttribute(String mappedByAttribute) { |
| if (ObjectTools.notEquals(mappedByAttribute, this.mappedByAttribute)) { |
| this.getMappingAnnotationForUpdate().setMappedBy(mappedByAttribute); |
| this.setMappedByAttribute_(mappedByAttribute); |
| } |
| } |
| |
| protected void setMappedByAttribute_(String mappedByAttribute) { |
| String old = this.mappedByAttribute; |
| this.mappedByAttribute = mappedByAttribute; |
| this.firePropertyChanged(MAPPED_BY_ATTRIBUTE_PROPERTY, old, mappedByAttribute); |
| } |
| |
| protected String buildMappedByAttribute() { |
| OwnableRelationshipMappingAnnotation annotation = this.getMappingAnnotation(); |
| return (annotation == null) ? null : annotation.getMappedBy(); |
| } |
| |
| |
| // ********** misc ********** |
| |
| protected OwnableRelationshipMappingAnnotation getMappingAnnotation() { |
| return this.getRelationship().getMappingAnnotation(); |
| } |
| |
| protected OwnableRelationshipMappingAnnotation getMappingAnnotationForUpdate() { |
| return this.getRelationship().getMappingAnnotationForUpdate(); |
| } |
| |
| public JavaMappedByRelationship getRelationship() { |
| return this.parent; |
| } |
| |
| public String getTableName() { |
| RelationshipMapping owner = this.getRelationshipOwner(); |
| return (owner == null) ? null : owner.getRelationship().getStrategy().getTableName(); |
| } |
| |
| public Table resolveDbTable(String tableName) { |
| RelationshipMapping owner = this.getRelationshipOwner(); |
| return (owner == null) ? null : owner.getRelationship().getStrategy().resolveDbTable(tableName); |
| } |
| |
| public boolean tableNameIsInvalid(String tableName) { |
| RelationshipMapping owner = this.getRelationshipOwner(); |
| return (owner != null) && owner.getRelationship().getStrategy().tableNameIsInvalid(tableName); |
| } |
| |
| public String getColumnTableNotValidDescription() { |
| //this will not be called if getRelationshipOwner() is null |
| return this.getRelationshipOwner().getRelationship().getStrategy().getColumnTableNotValidDescription(); |
| } |
| |
| protected RelationshipMapping getRelationshipOwner() { |
| return this.getRelationshipMapping().getRelationshipOwner(); |
| } |
| |
| public boolean isOverridable() { |
| return false; |
| } |
| |
| protected RelationshipMapping getRelationshipMapping() { |
| return this.getRelationship().getMapping(); |
| } |
| |
| public boolean relationshipIsOwnedBy(RelationshipMapping otherMapping) { |
| String thisEntityName = this.getEntityName(); |
| Entity otherEntity = otherMapping.getResolvedTargetEntity(); |
| String otherEntityName = (otherEntity == null) ? null : otherEntity.getName(); |
| return ObjectTools.equals(thisEntityName, otherEntityName) && |
| ObjectTools.equals(this.mappedByAttribute, otherMapping.getName()); |
| } |
| |
| protected String getEntityName() { |
| Entity entity = this.getRelationship().getEntity(); |
| return (entity == null) ? null : entity.getName(); |
| } |
| |
| public RelationshipStrategy selectOverrideStrategy(OverrideRelationship2_0 overrideRelationship) { |
| return null; // mapped-by strategies cannot be overridden |
| } |
| |
| public void addStrategy() { |
| if (this.mappedByAttribute == null) { |
| this.setMappedByAttribute(""); //$NON-NLS-1$ |
| } |
| } |
| |
| public void removeStrategy() { |
| if (this.mappedByAttribute != null) { |
| this.setMappedByAttribute(null); |
| } |
| } |
| |
| |
| // ********** java completion proposals ********** |
| |
| @Override |
| public Iterable<String> getCompletionProposals(int pos) { |
| Iterable<String> result = super.getCompletionProposals(pos); |
| if (result != null) { |
| return result; |
| } |
| OwnableRelationshipMappingAnnotation annotation = this.getMappingAnnotation(); |
| if ((annotation != null) && annotation.mappedByTouches(pos)) { |
| result = this.getJavaCandidateMappedByAttributeNames(); |
| } |
| return result; |
| } |
| |
| public Iterable<String> getCandidateMappedByAttributeNames() { |
| return this.getRelationshipMapping().getTargetEntityNonTransientAttributeNames(); |
| } |
| |
| protected Iterable<String> getJavaCandidateMappedByAttributeNames() { |
| return new TransformationIterable<String, String>(this.getCandidateMappedByAttributeNames(), |
| StringTools.JAVA_STRING_LITERAL_CONTENT_TRANSFORMER); |
| } |
| |
| // ********** validation ********** |
| |
| @Override |
| public void validate(List<IMessage> messages, IReporter reporter) { |
| super.validate(messages, reporter); |
| |
| if (this.mappedByAttribute == null) { |
| return; |
| } |
| |
| Entity targetEntity = this.getRelationshipMapping().getResolvedTargetEntity(); |
| if (targetEntity == null) { |
| return; // null target entity is validated elsewhere |
| } |
| |
| AttributeMapping mappedByMapping = targetEntity.resolveAttributeMapping(this.mappedByAttribute); |
| |
| if (mappedByMapping == null) { |
| messages.add( |
| this.buildMessage( |
| JptJpaCoreValidationMessages.MAPPING_UNRESOLVED_MAPPED_BY, |
| new String[] {this.mappedByAttribute} |
| ) |
| ); |
| return; |
| } |
| |
| if ( ! this.getRelationship().mayBeMappedBy(mappedByMapping)) { |
| messages.add( |
| this.buildMessage( |
| JptJpaCoreValidationMessages.MAPPING_INVALID_MAPPED_BY, |
| new String[] {this.mappedByAttribute} |
| ) |
| ); |
| return; |
| } |
| |
| // if mappedByMapping is not a relationship owner, then it should have |
| // been flagged in above rule (mappedByIsValid) |
| if ( ! ((RelationshipMapping) mappedByMapping).isRelationshipOwner()) { |
| messages.add( |
| this.buildMessage( |
| JptJpaCoreValidationMessages.MAPPING_MAPPED_BY_ON_BOTH_SIDES, |
| new String[] {this.mappedByAttribute} |
| ) |
| ); |
| } |
| } |
| |
| protected IMessage buildMessage(ValidationMessage msg, Object[] args) { |
| SpecifiedPersistentAttribute attribute = this.getRelationshipMapping().getPersistentAttribute(); |
| String attributeDescription = attribute.isVirtual() ? |
| JptJpaCoreValidationArgumentMessages.VIRTUAL_ATTRIBUTE_DESC : |
| JptJpaCoreValidationArgumentMessages.ATTRIBUTE_DESC; |
| TextRange textRange = attribute.isVirtual() ? |
| attribute.getValidationTextRange() : |
| this.getValidationTextRange(); |
| attributeDescription = NLS.bind(attributeDescription, attribute.getName()); |
| args = ArrayTools.add(args, 0, attributeDescription); |
| return this.buildValidationMessage(textRange, msg, args); |
| } |
| |
| public TextRange getValidationTextRange() { |
| TextRange textRange = this.getAnnotationMappedByTextRange(); |
| return (textRange != null) ? textRange : this.getRelationship().getValidationTextRange(); |
| } |
| |
| protected TextRange getAnnotationMappedByTextRange() { |
| OwnableRelationshipMappingAnnotation annotation = this.getMappingAnnotation(); |
| return (annotation == null) ? null : annotation.getMappedByTextRange(); |
| } |
| } |