blob: e18725d505bd876c9f2cc511c3c2071f7aef4419 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2006, 2009 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.java;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jpt.core.JpaStructureNode;
import org.eclipse.jpt.core.MappingKeys;
import org.eclipse.jpt.core.context.PersistentAttribute;
import org.eclipse.jpt.core.context.PersistentType;
import org.eclipse.jpt.core.context.TypeMapping;
import org.eclipse.jpt.core.context.java.JavaAttributeMapping;
import org.eclipse.jpt.core.context.java.JavaPersistentAttribute;
import org.eclipse.jpt.core.context.java.JavaStructureNodes;
import org.eclipse.jpt.core.internal.validation.DefaultJpaValidationMessages;
import org.eclipse.jpt.core.internal.validation.JpaValidationMessages;
import org.eclipse.jpt.core.resource.java.Annotation;
import org.eclipse.jpt.core.resource.java.JavaResourceNode;
import org.eclipse.jpt.core.resource.java.JavaResourcePersistentAttribute;
import org.eclipse.jpt.core.utility.TextRange;
import org.eclipse.jpt.utility.Filter;
import org.eclipse.jpt.utility.internal.CollectionTools;
import org.eclipse.wst.validation.internal.provisional.core.IMessage;
/**
*
*/
public class GenericJavaPersistentAttribute
extends AbstractJavaJpaContextNode
implements JavaPersistentAttribute
{
protected String name;
protected JavaAttributeMapping defaultMapping;
protected JavaAttributeMapping specifiedMapping;
protected JavaResourcePersistentAttribute resourcePersistentAttribute;
public GenericJavaPersistentAttribute(PersistentType parent, JavaResourcePersistentAttribute jrpa) {
super(parent);
this.initialize(jrpa);
}
public String getId() {
return JavaStructureNodes.PERSISTENT_ATTRIBUTE_ID;
}
protected void initialize(JavaResourcePersistentAttribute jrpa) {
this.resourcePersistentAttribute = jrpa;
this.name = this.getResourceName();
initializeDefaultMapping();
initializeSpecifiedMapping();
}
protected void initializeDefaultMapping() {
this.defaultMapping = buildDefaultMapping();
}
protected JavaAttributeMapping buildDefaultMapping() {
JavaAttributeMapping defaultMapping = getJpaPlatform().buildDefaultJavaAttributeMapping(this);
JavaResourceNode resourceMapping = this.resourcePersistentAttribute.getNullMappingAnnotation(defaultMapping.getAnnotationName());
defaultMapping.initialize(resourceMapping);
return defaultMapping;
}
protected void initializeSpecifiedMapping() {
this.specifiedMapping = buildJavaAttributeMappingFromAnnotation(this.getJavaMappingAnnotationName());
}
public JavaResourcePersistentAttribute getResourcePersistentAttribute() {
return this.resourcePersistentAttribute;
}
@Override
public PersistentType getParent() {
return (PersistentType) super.getParent();
}
public PersistentType getPersistentType() {
return this.getParent();
}
public TypeMapping getTypeMapping() {
return this.getPersistentType().getMapping();
}
public String getPrimaryKeyColumnName() {
return this.getMapping().getPrimaryKeyColumnName();
}
public boolean isOverridableAttribute() {
return this.getMapping().isOverridableAttributeMapping();
}
public boolean isOverridableAssociation() {
return this.getMapping().isOverridableAssociationMapping();
}
public boolean isIdAttribute() {
return this.getMapping().isIdMapping();
}
public boolean isVirtual() {
return false;
}
public String getName() {
return this.name;
}
protected void setName(String newName) {
String oldName = this.name;
this.name = newName;
firePropertyChanged(NAME_PROPERTY, oldName, newName);
}
public JavaAttributeMapping getDefaultMapping() {
return this.defaultMapping;
}
/**
* clients do not set the "default" mapping
*/
protected void setDefaultMapping(JavaAttributeMapping newDefaultMapping) {
JavaAttributeMapping oldMapping = this.defaultMapping;
this.defaultMapping = newDefaultMapping;
firePropertyChanged(PersistentAttribute.DEFAULT_MAPPING_PROPERTY, oldMapping, newDefaultMapping);
}
public JavaAttributeMapping getSpecifiedMapping() {
return this.specifiedMapping;
}
/**
* clients do not set the "specified" mapping;
* use #setMappingKey(String)
*/
protected void setSpecifiedMapping(JavaAttributeMapping newSpecifiedMapping) {
JavaAttributeMapping oldMapping = this.specifiedMapping;
this.specifiedMapping = newSpecifiedMapping;
firePropertyChanged(PersistentAttribute.SPECIFIED_MAPPING_PROPERTY, oldMapping, newSpecifiedMapping);
}
public JavaAttributeMapping getMapping() {
return (this.specifiedMapping != null) ? this.specifiedMapping : this.defaultMapping;
}
public String getMappingKey() {
return this.getMapping().getKey();
}
/**
* return null if there is no "default" mapping for the attribute
*/
public String getDefaultMappingKey() {
return this.defaultMapping.getKey();
}
/**
* return null if there is no "specified" mapping for the attribute
*/
public String getSpecifiedMappingKey() {
return (this.specifiedMapping == null) ? null : this.specifiedMapping.getKey();
}
// TODO support morphing mappings, i.e. copying common settings over
// to the new mapping; this can't be done in the same was as XmlAttributeMapping
// since we don't know all the possible mapping types
public void setSpecifiedMappingKey(String newKey) {
if (newKey == getSpecifiedMappingKey()) {
return;
}
JavaAttributeMapping oldMapping = getSpecifiedMapping();
JavaAttributeMapping newMapping = buildJavaAttributeMappingFromMappingKey(newKey);
this.specifiedMapping = newMapping;
if (newMapping != null) {
this.resourcePersistentAttribute.setMappingAnnotation(newMapping.getAnnotationName());
}
else {
this.resourcePersistentAttribute.setMappingAnnotation(null);
}
firePropertyChanged(PersistentAttribute.SPECIFIED_MAPPING_PROPERTY, oldMapping, newMapping);
if (oldMapping != null) {
Collection<String> annotationsToRemove = CollectionTools.collection(oldMapping.correspondingAnnotationNames());
if (getMapping() != null) {
CollectionTools.removeAll(annotationsToRemove, getMapping().correspondingAnnotationNames());
}
for (String annotationName : annotationsToRemove) {
this.resourcePersistentAttribute.removeSupportingAnnotation(annotationName);
}
}
}
public JpaStructureNode getStructureNode(int textOffset) {
return this;
}
public boolean contains(int offset, CompilationUnit astRoot) {
TextRange fullTextRange = this.getFullTextRange(astRoot);
// 'fullTextRange' will be null if the attribute no longer exists in the java;
// the context model can be out of synch with the resource model
// when a selection event occurs before the context model has a
// chance to synch with the resource model via the update thread
return (fullTextRange == null) ? false : fullTextRange.includes(offset);
}
public TextRange getFullTextRange(CompilationUnit astRoot) {
return this.resourcePersistentAttribute.getTextRange(astRoot);
}
public TextRange getValidationTextRange(CompilationUnit astRoot) {
return this.getSelectionTextRange(astRoot);
}
public TextRange getSelectionTextRange(CompilationUnit astRoot) {
return this.resourcePersistentAttribute.getNameTextRange(astRoot);
}
public TextRange getSelectionTextRange() {
return getSelectionTextRange(this.buildASTRoot());
}
protected CompilationUnit buildASTRoot() {
return this.resourcePersistentAttribute.getJavaResourceCompilationUnit().buildASTRoot();
}
public void update() {
this.setName(this.getResourceName());
this.updateDefaultMapping();
this.updateSpecifiedMapping();
}
protected String getResourceName() {
return this.resourcePersistentAttribute.getName();
}
protected String getSpecifiedMappingAnnotationName() {
return (this.specifiedMapping == null) ? null : this.specifiedMapping.getAnnotationName();
}
protected void updateSpecifiedMapping() {
String javaMappingAnnotationName = this.getJavaMappingAnnotationName();
if (getSpecifiedMappingAnnotationName() != javaMappingAnnotationName) {
setSpecifiedMapping(buildJavaAttributeMappingFromAnnotation(javaMappingAnnotationName));
}
else {
if (getSpecifiedMapping() != null) {
getSpecifiedMapping().update(this.resourcePersistentAttribute.getMappingAnnotation(javaMappingAnnotationName));
}
}
}
protected void updateDefaultMapping() {
String defaultMappingKey = getJpaPlatform().getDefaultJavaAttributeMappingKey(this);
if (getDefaultMapping().getKey() != defaultMappingKey) {
JavaAttributeMapping oldDefaultMapping = this.defaultMapping;
this.defaultMapping = buildDefaultMapping();
firePropertyChanged(PersistentAttribute.DEFAULT_MAPPING_PROPERTY, oldDefaultMapping, this.defaultMapping);
}
else {
getDefaultMapping().update(this.resourcePersistentAttribute.getNullMappingAnnotation(this.defaultMapping.getAnnotationName()));
}
}
protected String getJavaMappingAnnotationName() {
Annotation mappingAnnotation = (Annotation) this.resourcePersistentAttribute.getMappingAnnotation();
if (mappingAnnotation != null) {
return mappingAnnotation.getAnnotationName();
}
return null;
}
protected JavaAttributeMapping buildJavaAttributeMappingFromMappingKey(String key) {
if (key == MappingKeys.NULL_ATTRIBUTE_MAPPING_KEY) {
return null;
}
JavaAttributeMapping mapping = getJpaPlatform().buildJavaAttributeMappingFromMappingKey(key, this);
//no mapping.initialize(JavaResourcePersistentAttribute) call here
//we do not yet have a mapping annotation so we can't call initialize
return mapping;
}
protected JavaAttributeMapping buildJavaAttributeMappingFromAnnotation(String annotationName) {
if (annotationName == null) {
return null;
}
JavaAttributeMapping mapping = getJpaPlatform().buildJavaAttributeMappingFromAnnotation(annotationName, this);
mapping.initialize(this.resourcePersistentAttribute.getMappingAnnotation(annotationName));
return mapping;
}
/**
* the mapping might be "default", but it still might be a "null" mapping...
*/
public boolean mappingIsDefault(JavaAttributeMapping mapping) {
return this.defaultMapping == mapping;
}
@Override
public Iterator<String> javaCompletionProposals(int pos, Filter<String> filter, CompilationUnit astRoot) {
Iterator<String> result = super.javaCompletionProposals(pos, filter, astRoot);
if (result != null) {
return result;
}
return this.getMapping().javaCompletionProposals(pos, filter, astRoot);
}
// ********** validation **********
@Override
public void validate(List<IMessage> messages, CompilationUnit astRoot) {
super.validate(messages, astRoot);
this.validateModifiers(messages, astRoot);
if (this.specifiedMapping != null) {
this.specifiedMapping.validate(messages, astRoot);
}
else if (this.defaultMapping != null) {
this.defaultMapping.validate(messages, astRoot);
}
}
protected void validateModifiers(List<IMessage> messages, CompilationUnit astRoot) {
if (getMappingKey() == MappingKeys.TRANSIENT_ATTRIBUTE_MAPPING_KEY) {
return;
}
if (this.resourcePersistentAttribute.isForField()) {
if (this.resourcePersistentAttribute.isFinal()) {
messages.add(this.buildAttributeMessage(JpaValidationMessages.PERSISTENT_ATTRIBUTE_FINAL_FIELD, astRoot));
}
if (this.resourcePersistentAttribute.isPublic()) {
messages.add(this.buildAttributeMessage(JpaValidationMessages.PERSISTENT_ATTRIBUTE_PUBLIC_FIELD, astRoot));
}
}
}
protected IMessage buildAttributeMessage(String msgID, CompilationUnit astRoot) {
return DefaultJpaValidationMessages.buildMessage(
IMessage.HIGH_SEVERITY,
msgID,
new String[] {getName()},
this,
getValidationTextRange(astRoot)
);
}
// ********** misc **********
@Override
public void toString(StringBuilder sb) {
super.toString(sb);
sb.append(this.name);
}
public void dispose() {
//nothing to dispose
}
}