blob: baee4966b5b8dfdb4418c18d4200622640434734 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2006, 2008 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.TextRange;
import org.eclipse.jpt.core.context.PersistentAttribute;
import org.eclipse.jpt.core.context.java.JavaAttributeMapping;
import org.eclipse.jpt.core.context.java.JavaPersistentAttribute;
import org.eclipse.jpt.core.context.java.JavaPersistentType;
import org.eclipse.jpt.core.context.java.JavaStructureNodes;
import org.eclipse.jpt.core.context.java.JavaTypeMapping;
import org.eclipse.jpt.core.resource.java.Annotation;
import org.eclipse.jpt.core.resource.java.JavaResourcePersistentAttribute;
import org.eclipse.jpt.utility.internal.CollectionTools;
import org.eclipse.jpt.utility.internal.Filter;
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 persistentAttributeResource;
public GenericJavaPersistentAttribute(JavaPersistentType parent) {
super(parent);
}
public String getId() {
return JavaStructureNodes.PERSISTENT_ATTRIBUTE_ID;
}
public void initializeFromResource(JavaResourcePersistentAttribute persistentAttributeResource) {
this.persistentAttributeResource = persistentAttributeResource;
this.name = this.name(persistentAttributeResource);
initializeDefaultMapping(persistentAttributeResource);
initializeSpecifiedMapping(persistentAttributeResource);
}
protected void initializeDefaultMapping(JavaResourcePersistentAttribute persistentAttributeResource) {
this.defaultMapping = createDefaultJavaAttributeMapping(persistentAttributeResource);
}
protected void initializeSpecifiedMapping(JavaResourcePersistentAttribute persistentAttributeResource) {
String javaMappingAnnotationName = this.javaMappingAnnotationName(persistentAttributeResource);
this.specifiedMapping = createJavaAttributeMappingFromAnnotation(javaMappingAnnotationName, persistentAttributeResource);
}
public JavaResourcePersistentAttribute getPersistentAttributeResource() {
return this.persistentAttributeResource;
}
public JavaPersistentType persistentType() {
return (JavaPersistentType) this.parent();
}
public JavaTypeMapping typeMapping() {
return this.persistentType().getMapping();
}
public String primaryKeyColumnName() {
return this.getMapping().primaryKeyColumnName();
}
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 mappingKey() {
return this.getMapping().getKey();
}
/**
* return null if there is no "default" mapping for the attribute
*/
public String defaultMappingKey() {
return this.defaultMapping.getKey();
}
/**
* return null if there is no "specified" mapping for the attribute
*/
public String specifiedMappingKey() {
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 == specifiedMappingKey()) {
return;
}
JavaAttributeMapping oldMapping = getMapping();
JavaAttributeMapping newMapping = createJavaAttributeMappingFromMappingKey(newKey);
this.specifiedMapping = newMapping;
if (newMapping != null) {
this.persistentAttributeResource.setMappingAnnotation(newMapping.annotationName());
}
else {
this.persistentAttributeResource.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.persistentAttributeResource.removeAnnotation(annotationName);
}
}
}
public JpaStructureNode structureNode(int textOffset) {
return this;
}
public boolean contains(int offset, CompilationUnit astRoot) {
TextRange fullTextRange = this.fullTextRange(astRoot);
if (fullTextRange == null) {
//This happens if the attribute no longer exists in the java.
//The text selection event is fired before the update from java so our
//model has not yet had a chance to update appropriately. The list of
//JavaPersistentAttriubtes is stale at this point. For now, we are trying
//to avoid the NPE, not sure of the ultimate solution to these 2 threads accessing
//our model
return false;
}
return fullTextRange.includes(offset);
}
public TextRange fullTextRange(CompilationUnit astRoot) {
return this.persistentAttributeResource.textRange(astRoot);
}
public TextRange validationTextRange(CompilationUnit astRoot) {
return this.selectionTextRange(astRoot);
}
public TextRange selectionTextRange(CompilationUnit astRoot) {
return this.persistentAttributeResource.nameTextRange(astRoot);
}
public TextRange selectionTextRange() {
return selectionTextRange(this.persistentAttributeResource.getMember().astRoot());
}
public void update(JavaResourcePersistentAttribute persistentAttributeResource) {
this.persistentAttributeResource = persistentAttributeResource;
this.setName(this.name(persistentAttributeResource));
this.updateDefaultMapping(persistentAttributeResource);
this.updateSpecifiedMapping(persistentAttributeResource);
}
protected String name(JavaResourcePersistentAttribute persistentAttributeResource) {
return persistentAttributeResource.getName();
}
public String specifiedMappingAnnotationName() {
return (this.specifiedMapping == null) ? null : this.specifiedMapping.annotationName();
}
protected void updateSpecifiedMapping(JavaResourcePersistentAttribute persistentAttributeResource) {
String javaMappingAnnotationName = this.javaMappingAnnotationName(persistentAttributeResource);
if (specifiedMappingAnnotationName() != javaMappingAnnotationName) {
setSpecifiedMapping(createJavaAttributeMappingFromAnnotation(javaMappingAnnotationName, persistentAttributeResource));
}
else {
if (getSpecifiedMapping() != null) {
getSpecifiedMapping().update(persistentAttributeResource);
}
}
}
protected void updateDefaultMapping(JavaResourcePersistentAttribute persistentAttributeResource) {
String defaultMappingKey = jpaPlatform().defaultJavaAttributeMappingKey(this);
if (getDefaultMapping().getKey() != defaultMappingKey) {
setDefaultMapping(createDefaultJavaAttributeMapping(persistentAttributeResource));
}
else {
getDefaultMapping().update(persistentAttributeResource);
}
}
protected String javaMappingAnnotationName(JavaResourcePersistentAttribute persistentAttributeResource) {
Annotation mappingAnnotation = (Annotation) persistentAttributeResource.mappingAnnotation();
if (mappingAnnotation != null) {
return mappingAnnotation.getAnnotationName();
}
return null;
}
protected JavaAttributeMapping createJavaAttributeMappingFromMappingKey(String key) {
if (key == MappingKeys.NULL_ATTRIBUTE_MAPPING_KEY) {
return null;
}
return jpaPlatform().buildJavaAttributeMappingFromMappingKey(key, this);
}
protected JavaAttributeMapping createJavaAttributeMappingFromAnnotation(String annotationName, JavaResourcePersistentAttribute persistentAttributeResource) {
if (annotationName == null) {
return null;
}
JavaAttributeMapping mapping = jpaPlatform().buildJavaAttributeMappingFromAnnotation(annotationName, this);
mapping.initializeFromResource(persistentAttributeResource);
return mapping;
}
protected JavaAttributeMapping createDefaultJavaAttributeMapping(JavaResourcePersistentAttribute persistentAttributeResource) {
JavaAttributeMapping defaultMapping = jpaPlatform().buildDefaultJavaAttributeMapping(this);
defaultMapping.initializeFromResource(persistentAttributeResource);
return defaultMapping;
}
/**
* the mapping might be "default", but it still might be a "null" mapping...
*/
public boolean mappingIsDefault() {
return this.specifiedMapping == null;
}
@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 addToMessages(List<IMessage> messages, CompilationUnit astRoot) {
super.addToMessages(messages, astRoot);
if (this.specifiedMapping != null) {
this.specifiedMapping.addToMessages(messages, astRoot);
}
else if (this.defaultMapping != null) {
this.defaultMapping.addToMessages(messages, astRoot);
}
}
@Override
public void toString(StringBuilder sb) {
super.toString(sb);
sb.append(getName());
}
}