blob: aa98c24a99451aa7fd517be23d907b0dedffeab0 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2012 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.eclipselink.core.internal.context.orm;
import java.util.List;
import org.eclipse.jpt.common.core.resource.java.JavaResourceType;
import org.eclipse.jpt.jpa.core.context.PersistentType;
import org.eclipse.jpt.jpa.core.context.java.JavaPersistentType;
import org.eclipse.jpt.jpa.core.context.orm.EntityMappings;
import org.eclipse.jpt.jpa.core.context.orm.OrmAttributeMappingDefinition;
import org.eclipse.jpt.jpa.core.context.orm.OrmPersistentAttribute;
import org.eclipse.jpt.jpa.core.internal.context.orm.SpecifiedOrmPersistentType;
import org.eclipse.jpt.jpa.core.internal.validation.DefaultJpaValidationMessages;
import org.eclipse.jpt.jpa.core.internal.validation.JpaValidationMessages;
import org.eclipse.jpt.jpa.core.resource.orm.Attributes;
import org.eclipse.jpt.jpa.eclipselink.core.JptJpaEclipseLinkCorePlugin;
import org.eclipse.jpt.jpa.eclipselink.core.context.EclipseLinkAccessType;
import org.eclipse.jpt.jpa.eclipselink.core.context.orm.EclipseLinkEntityMappings;
import org.eclipse.jpt.jpa.eclipselink.core.context.orm.EclipseLinkOrmTypeMapping;
import org.eclipse.jpt.jpa.eclipselink.core.context.orm.EclipseLinkOrmPersistentType;
import org.eclipse.jpt.jpa.eclipselink.core.resource.orm.EclipseLinkOrmFactory;
import org.eclipse.jpt.jpa.eclipselink.core.resource.orm.XmlAccessMethods;
import org.eclipse.jpt.jpa.eclipselink.core.resource.orm.XmlAccessMethodsHolder;
import org.eclipse.jpt.jpa.eclipselink.core.resource.orm.XmlAttributeMapping;
import org.eclipse.jpt.jpa.eclipselink.core.resource.orm.XmlTypeMapping;
import org.eclipse.wst.validation.internal.provisional.core.IMessage;
/**
* <code>eclipselink-orm.xml</code> persistent type:<ul>
* <li>mapping
* <li>access
* <li>access-methods
* <li>attributes
* <li>super persistent type
* <li>Java persistent type
* </ul>
*/
public class EclipseLinkOrmPersistentTypeImpl
extends SpecifiedOrmPersistentType
implements EclipseLinkOrmPersistentType
{
protected String specifiedGetMethod;
protected String defaultGetMethod;
protected String specifiedSetMethod;
protected String defaultSetMethod;
protected boolean dynamic;
public EclipseLinkOrmPersistentTypeImpl(EntityMappings parent, XmlTypeMapping xmlTypeMapping) {
super(parent, xmlTypeMapping);
this.specifiedGetMethod = this.buildSpecifiedGetMethod();
this.specifiedSetMethod = this.buildSpecifiedSetMethod();
}
@Override
protected XmlTypeMapping getXmlTypeMapping() {
return (XmlTypeMapping) super.getXmlTypeMapping();
}
@Override
public EclipseLinkOrmTypeMapping getMapping() {
return (EclipseLinkOrmTypeMapping) super.getMapping();
}
// ********** synchronize/update **********
@Override
public void synchronizeWithResourceModel() {
super.synchronizeWithResourceModel();
this.setSpecifiedGetMethod_(this.buildSpecifiedGetMethod());
this.setSpecifiedSetMethod_(this.buildSpecifiedSetMethod());
}
@Override
public void update() {
super.update();
this.setDefaultGetMethod(this.buildDefaultGetMethod());
this.setDefaultSetMethod(this.buildDefaultSetMethod());
this.setDynamic(this.buildDynamic());
}
//*************** dynamic *****************
public boolean isDynamic() {
return this.dynamic;
}
protected void setDynamic(boolean dynamic) {
boolean old = this.dynamic;
this.dynamic = dynamic;
if (this.firePropertyChanged(DYNAMIC_PROPERTY, old, this.dynamic)) {
// clear out the Java persistent type here, it will be rebuilt during "update"
if (this.javaPersistentType != null) {
this.javaPersistentType.dispose();
this.setJavaPersistentType(null);
}
}
}
//Base the dynamic state only on the JavaResourceType being null.
//Otherwise, the access type affects the hierarchy
//and then the hierarchy affects the access type and we get stuck in an update.
//Validation will check that virtual access is set if it is dynamic.
protected boolean buildDynamic() {
return JptJpaEclipseLinkCorePlugin.nodeIsEclipseLinkVersionCompatible(this, JptJpaEclipseLinkCorePlugin.ECLIPSELINK_PLATFORM_VERSION_2_1)
&& this.resolveJavaResourceType() == null;
}
protected boolean isVirtualAccess() {
return this.getAccess() == EclipseLinkAccessType.VIRTUAL;
}
@Override
protected JavaPersistentType buildJavaPersistentType(JavaResourceType javaResourceType) {
if (this.isDynamic()) {
return this.buildVirtualJavaPersistentType();
}
return super.buildJavaPersistentType(javaResourceType);
}
protected JavaPersistentType buildVirtualJavaPersistentType() {
return new VirtualJavaPersistentType(this, this.getXmlTypeMapping());
}
@Override
public PersistentType getOverriddenPersistentType() {
if (this.isDynamic()) {
return null;
}
return super.getOverriddenPersistentType();
}
public OrmPersistentAttribute addVirtualAttribute(String attributeName, String mappingKey, String attributeType) {
// force the creation of an empty xml attribute container beforehand or it will trigger
// a sync and, if we do this after adding the attribute, clear out our context attributes
Attributes xmlAttributes = this.getXmlAttributesForUpdate();
this.getXmlTypeMapping().setAttributes(xmlAttributes); // possibly a NOP
OrmAttributeMappingDefinition md = this.getMappingFileDefinition().getAttributeMappingDefinition(mappingKey);
XmlAttributeMapping xmlMapping = (XmlAttributeMapping) md.buildResourceMapping(this.getResourceNodeFactory());
xmlMapping.setName(attributeName);
xmlMapping.setAttributeType(attributeType);
if (this.getAccess() != EclipseLinkAccessType.VIRTUAL) {
xmlMapping.setAccess(EclipseLinkAccessType.VIRTUAL.getOrmAccessType());
}
OrmPersistentAttribute specifiedAttribute = this.buildSpecifiedAttribute(xmlMapping);
// we need to add the attribute to the right spot in the list - stupid spec...
int specifiedIndex = this.getSpecifiedAttributeInsertionIndex(specifiedAttribute);
this.addItemToList(specifiedIndex, specifiedAttribute, this.specifiedAttributes, SPECIFIED_ATTRIBUTES_LIST);
specifiedAttribute.getMapping().addXmlAttributeMappingTo(xmlAttributes);
return specifiedAttribute;
}
//*************** get method *****************
public String getGetMethod() {
String specifiedGetMethod = this.getSpecifiedGetMethod();
return (specifiedGetMethod != null) ? specifiedGetMethod : this.defaultGetMethod;
}
public String getDefaultGetMethod() {
return this.defaultGetMethod;
}
//TODO get the default get method from the java VirtualAccessMethods annotation and from the super type
protected String buildDefaultGetMethod() {
if (getAccess() == EclipseLinkAccessType.VIRTUAL) {
String defaultGetMethod = getEntityMappings().getDefaultGetMethod();
return defaultGetMethod != null ? defaultGetMethod : DEFAULT_GET_METHOD;
}
return null;
}
protected void setDefaultGetMethod(String getMethod) {
String old = this.defaultGetMethod;
this.defaultGetMethod = getMethod;
this.firePropertyChanged(DEFAULT_GET_METHOD_PROPERTY, old, getMethod);
}
public String getSpecifiedGetMethod() {
return this.specifiedGetMethod;
}
public void setSpecifiedGetMethod(String getMethod) {
if (this.valuesAreDifferent(this.specifiedGetMethod, getMethod)) {
XmlAccessMethods xmlAccessMethods = this.getXmlAccessMethodsForUpdate();
this.setSpecifiedGetMethod_(getMethod);
xmlAccessMethods.setGetMethod(getMethod);
this.removeXmlAccessMethodsIfUnset();
}
}
protected void setSpecifiedGetMethod_(String getMethod) {
String old = this.specifiedGetMethod;
this.specifiedGetMethod = getMethod;
this.firePropertyChanged(SPECIFIED_GET_METHOD_PROPERTY, old, getMethod);
}
protected String buildSpecifiedGetMethod() {
XmlAccessMethods accessMethods = this.getXmlAccessMethods();
return accessMethods != null ? accessMethods.getGetMethod() : null;
}
//*************** set method *****************
public String getSetMethod() {
String specifiedSetMethod = this.getSpecifiedSetMethod();
return (specifiedSetMethod != null) ? specifiedSetMethod : this.defaultSetMethod;
}
public String getDefaultSetMethod() {
return this.defaultSetMethod;
}
protected void setDefaultSetMethod(String setMethod) {
String old = this.defaultSetMethod;
this.defaultSetMethod = setMethod;
this.firePropertyChanged(DEFAULT_SET_METHOD_PROPERTY, old, setMethod);
}
protected String buildDefaultSetMethod() {
if (getAccess() == EclipseLinkAccessType.VIRTUAL) {
//TODO get the default set method from the java VirtualAccessMethods annotation/super persistent type, embedded parent, etc
String defaultSetMethod = getEntityMappings().getDefaultSetMethod();
return defaultSetMethod != null ? defaultSetMethod : DEFAULT_SET_METHOD;
}
return null;
}
public String getSpecifiedSetMethod() {
return this.specifiedSetMethod;
}
public void setSpecifiedSetMethod(String setMethod) {
if (this.valuesAreDifferent(this.specifiedSetMethod, setMethod)) {
XmlAccessMethods xmlAccessMethods = this.getXmlAccessMethodsForUpdate();
this.setSpecifiedSetMethod_(setMethod);
xmlAccessMethods.setSetMethod(setMethod);
this.removeXmlAccessMethodsIfUnset();
}
}
protected void setSpecifiedSetMethod_(String setMethod) {
String old = this.specifiedSetMethod;
this.specifiedSetMethod = setMethod;
this.firePropertyChanged(SPECIFIED_SET_METHOD_PROPERTY, old, setMethod);
}
protected String buildSpecifiedSetMethod() {
XmlAccessMethods accessMethods = this.getXmlAccessMethods();
return accessMethods != null ? accessMethods.getSetMethod() : null;
}
//*************** XML access methods *****************
protected XmlAccessMethodsHolder getXmlAccessMethodsHolder() {
return this.getXmlTypeMapping();
}
protected XmlAccessMethods getXmlAccessMethods() {
return getXmlAccessMethodsHolder().getAccessMethods();
}
/**
* Build the XML access methods (and XML defaults and XML metadata if necessary) if it does not exist.
*/
protected XmlAccessMethods getXmlAccessMethodsForUpdate() {
XmlAccessMethods xmlAccessMethods = this.getXmlAccessMethodsHolder().getAccessMethods();
return (xmlAccessMethods != null) ? xmlAccessMethods : this.buildXmlAccessMethods();
}
protected XmlAccessMethods buildXmlAccessMethods() {
XmlAccessMethods xmlAccessMethods = this.buildXmlAccessMethods_();
this.getXmlAccessMethodsHolder().setAccessMethods(xmlAccessMethods);
return xmlAccessMethods;
}
protected XmlAccessMethods buildXmlAccessMethods_() {
return EclipseLinkOrmFactory.eINSTANCE.createXmlAccessMethods();
}
/**
* clear the XML access methods if appropriate
*/
protected void removeXmlAccessMethodsIfUnset() {
if (this.getXmlAccessMethods().isUnset()) {
this.getXmlAccessMethodsHolder().setAccessMethods(null);
}
}
@Override
protected EclipseLinkEntityMappings getEntityMappings() {
return (EclipseLinkEntityMappings) super.getEntityMappings();
}
@Override
protected void validateClass(List<IMessage> messages) {
if (this.isDynamic() && !this.isVirtualAccess()) {
messages.add(
DefaultJpaValidationMessages.buildMessage(
IMessage.HIGH_SEVERITY,
JpaValidationMessages.PERSISTENT_TYPE_UNRESOLVED_CLASS,
new String[] {this.getName()},
this,
this.mapping.getClassTextRange()
)
);
}
}
}