diff options
author | kmoore | 2012-01-20 19:34:35 +0000 |
---|---|---|
committer | kmoore | 2012-01-20 19:34:35 +0000 |
commit | 2258fbd13be54d5fccdbb1d24970472f993b57c5 (patch) | |
tree | 16f51029f718adc444206e778263c866cdb4cb3f /jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse | |
parent | 2906afe6464d3be54b3d0455f1b3dd71603f7efd (diff) | |
download | webtools.dali-2258fbd13be54d5fccdbb1d24970472f993b57c5.tar.gz webtools.dali-2258fbd13be54d5fccdbb1d24970472f993b57c5.tar.xz webtools.dali-2258fbd13be54d5fccdbb1d24970472f993b57c5.zip |
added preliminary support for EclipseLink access-methods and VIRTUAL access type
Diffstat (limited to 'jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse')
16 files changed, 1475 insertions, 1419 deletions
diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/JpaPlatform.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/JpaPlatform.java index 84492737ae..00ca6ca37b 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/JpaPlatform.java +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/JpaPlatform.java @@ -9,6 +9,7 @@ ******************************************************************************/ package org.eclipse.jpt.jpa.core; +import java.util.Comparator; import org.eclipse.jpt.jpa.core.jpql.JpaJpqlQueryHelper; import org.eclipse.core.resources.IFile; @@ -21,6 +22,7 @@ import org.eclipse.jpt.jpa.core.context.java.JavaAttributeMappingDefinition; import org.eclipse.jpt.jpa.core.context.java.JavaTypeMappingDefinition; import org.eclipse.jpt.jpa.core.platform.JpaPlatformDescription; import org.eclipse.jpt.jpa.db.ConnectionProfileFactory; +import org.eclipse.wst.common.project.facet.core.DefaultVersionComparator; /** * This interface is to be implemented by a JPA vendor to provide extensions to @@ -185,6 +187,8 @@ public interface JpaPlatform interface Version { + Comparator<String> VERSION_COMPARATOR = new DefaultVersionComparator(); + /** * Return the platform's version. */ diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/JpaPlatformVariation.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/JpaPlatformVariation.java index 156628e336..a537fee196 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/JpaPlatformVariation.java +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/JpaPlatformVariation.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009, 2010 Oracle. All rights reserved. + * Copyright (c) 2009, 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. @@ -9,6 +9,9 @@ ******************************************************************************/ package org.eclipse.jpt.jpa.core; +import org.eclipse.jpt.common.core.JptResourceType; +import org.eclipse.jpt.jpa.core.context.AccessType; + /** * A JpaPlatform contains a JpaPlatformVariation. This is used for various jpa spec * items that are either optional or only supported by certain version of the spec. @@ -39,7 +42,10 @@ public interface JpaPlatformVariation * can be overridden with an association override. */ boolean isJoinTableOverridable(); - + + AccessType[] getSupportedAccessTypes(JptResourceType resourceType); + + AccessType[] GENERIC_SUPPORTED_ACCESS_TYPES = new AccessType[] {AccessType.FIELD, AccessType.PROPERTY}; public enum Supported { /** diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/JptJpaCorePlugin.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/JptJpaCorePlugin.java index 782ff77c8a..385fc9ba33 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/JptJpaCorePlugin.java +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/JptJpaCorePlugin.java @@ -33,7 +33,6 @@ import org.eclipse.jpt.common.core.JptResourceType; import org.eclipse.jpt.common.utility.internal.StringTools; import org.eclipse.jpt.jpa.core.context.XmlContextNode; import org.eclipse.jpt.jpa.core.internal.JptCoreMessages; -import org.eclipse.jpt.jpa.core.internal.GenericJpaPlatformFactory.SimpleVersion; import org.eclipse.jpt.jpa.core.internal.platform.JpaPlatformManagerImpl; import org.eclipse.jpt.jpa.core.internal.prefs.JpaPreferenceInitializer; import org.eclipse.jpt.jpa.core.platform.GenericPlatform; @@ -705,7 +704,11 @@ public class JptJpaCorePlugin } public static boolean nodeIsXml2_0Compatible(XmlContextNode xmlContextNode) { - return SimpleVersion.JPA_VERSION_COMPARATOR.compare(xmlContextNode.getResourceType().getVersion(), org.eclipse.jpt.jpa.core.resource.orm.v2_0.JPA2_0.SCHEMA_VERSION) >= 0; + return resourceTypeIsCompatible(xmlContextNode.getResourceType(), org.eclipse.jpt.jpa.core.resource.orm.v2_0.JPA2_0.SCHEMA_VERSION); + } + + public static boolean resourceTypeIsCompatible(JptResourceType resourceType, String version) { + return JpaPlatform.Version.VERSION_COMPARATOR.compare(resourceType.getVersion(), version) >= 0; } /** diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/context/AccessHolder.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/context/AccessHolder.java index 441e633b01..6f9d148890 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/context/AccessHolder.java +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/context/AccessHolder.java @@ -41,7 +41,7 @@ public interface AccessHolder String SPECIFIED_ACCESS_PROPERTY = "specifiedAccess"; //$NON-NLS-1$ /** - * Return the default access type, never null + * Return the default access type */ AccessType getDefaultAccess(); diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/context/AccessType.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/context/AccessType.java index c495c77c85..470aff4b37 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/context/AccessType.java +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/context/AccessType.java @@ -9,6 +9,9 @@ ******************************************************************************/ package org.eclipse.jpt.jpa.core.context; +import org.eclipse.jpt.common.core.JptResourceType; +import org.eclipse.jpt.jpa.core.JpaPlatform; + /** * Context model corresponding to:<ul> * <li>the XML resource model @@ -24,33 +27,34 @@ package org.eclipse.jpt.jpa.core.context; * pioneering adopters on the understanding that any code that uses this API * will almost certainly be broken (repeatedly) as the API evolves. * - * @version 2.2 + * @version 3.2 * @since 2.0 */ -public enum AccessType { +public class AccessType { - FIELD( + public static final AccessType FIELD = new AccessType( org.eclipse.jpt.jpa.core.resource.java.AccessType.FIELD, - org.eclipse.jpt.jpa.core.resource.orm.AccessType.FIELD - ), - PROPERTY( + org.eclipse.jpt.jpa.core.resource.orm.AccessType.FIELD, + "Field" //$NON-NLS-1$ + ); + public static final AccessType PROPERTY = new AccessType( org.eclipse.jpt.jpa.core.resource.java.AccessType.PROPERTY, - org.eclipse.jpt.jpa.core.resource.orm.AccessType.PROPERTY + org.eclipse.jpt.jpa.core.resource.orm.AccessType.PROPERTY, + "Property" //$NON-NLS-1$ ); - private org.eclipse.jpt.jpa.core.resource.java.AccessType javaAccessType; - private String ormAccessType; + protected final org.eclipse.jpt.jpa.core.resource.java.AccessType javaAccessType; + protected final String ormAccessType; + protected final String displayString; - AccessType(org.eclipse.jpt.jpa.core.resource.java.AccessType javaAccessType, String ormAccessType) { - if (javaAccessType == null) { - throw new NullPointerException(); - } + public AccessType(org.eclipse.jpt.jpa.core.resource.java.AccessType javaAccessType, String ormAccessType, String displayString) { if (ormAccessType == null) { throw new NullPointerException(); } this.javaAccessType = javaAccessType; this.ormAccessType = ormAccessType; + this.displayString = displayString; } public org.eclipse.jpt.jpa.core.resource.java.AccessType getJavaAccessType() { @@ -61,15 +65,18 @@ public enum AccessType { return this.ormAccessType; } + public String getDisplayString() { + return this.displayString; + } // ********** static methods ********** - public static AccessType fromJavaResourceModel(org.eclipse.jpt.jpa.core.resource.java.AccessType javaAccessType) { - return (javaAccessType == null) ? null : fromJavaResourceModel_(javaAccessType); + public static AccessType fromJavaResourceModel(org.eclipse.jpt.jpa.core.resource.java.AccessType javaAccessType, JpaPlatform jpaPlatform, JptResourceType resourceType) { + return (javaAccessType == null) ? null : fromJavaResourceModel_(javaAccessType, jpaPlatform, resourceType); } - private static AccessType fromJavaResourceModel_(org.eclipse.jpt.jpa.core.resource.java.AccessType javaAccessType) { - for (AccessType accessType : AccessType.values()) { + private static AccessType fromJavaResourceModel_(org.eclipse.jpt.jpa.core.resource.java.AccessType javaAccessType, JpaPlatform jpaPlatform, JptResourceType resourceType) { + for (AccessType accessType : jpaPlatform.getJpaVariation().getSupportedAccessTypes(resourceType)) { if (accessType.getJavaAccessType() == javaAccessType) { return accessType; } @@ -81,12 +88,12 @@ public enum AccessType { return (accessType == null) ? null : accessType.getJavaAccessType(); } - public static AccessType fromOrmResourceModel(String ormAccessType) { - return (ormAccessType == null) ? null : fromOrmResourceModel_(ormAccessType); + public static AccessType fromOrmResourceModel(String ormAccessType, JpaPlatform jpaPlatform, JptResourceType resourceType) { + return (ormAccessType == null) ? null : fromOrmResourceModel_(ormAccessType, jpaPlatform, resourceType); } - private static AccessType fromOrmResourceModel_(String ormAccessType) { - for (AccessType accessType : AccessType.values()) { + private static AccessType fromOrmResourceModel_(String ormAccessType, JpaPlatform jpaPlatform, JptResourceType resourceType) { + for (AccessType accessType : jpaPlatform.getJpaVariation().getSupportedAccessTypes(resourceType)) { if (accessType.getOrmAccessType().equals(ormAccessType)) { return accessType; } diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/context/ReadOnlyAccessHolder.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/context/ReadOnlyAccessHolder.java index 3cc216ecad..1165f759c8 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/context/ReadOnlyAccessHolder.java +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/context/ReadOnlyAccessHolder.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2010 Oracle. All rights reserved. + * Copyright (c) 2010, 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. @@ -9,8 +9,6 @@ ******************************************************************************/ package org.eclipse.jpt.jpa.core.context; -import org.eclipse.jpt.common.utility.model.Model; - /** * Common interface that can be used by clients interested only in a type * or attribute's access setting (e.g. a UI composite). @@ -21,11 +19,11 @@ import org.eclipse.jpt.common.utility.model.Model; * pioneering adopters on the understanding that any code that uses this API * will almost certainly be broken (repeatedly) as the API evolves. * - * @version 2.2 + * @version 3.2 * @since 2.2 */ public interface ReadOnlyAccessHolder - extends Model + extends JpaContextNode { /** * Return the access type, whether specified or defaulted. diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/GenericJpaPlatformFactory.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/GenericJpaPlatformFactory.java index fc25535ca5..7640a64d11 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/GenericJpaPlatformFactory.java +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/GenericJpaPlatformFactory.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009, 2011 Oracle. All rights reserved. + * Copyright (c) 2009, 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. @@ -9,13 +9,13 @@ ******************************************************************************/ package org.eclipse.jpt.jpa.core.internal; -import java.util.Comparator; +import org.eclipse.jpt.common.core.JptResourceType; import org.eclipse.jpt.jpa.core.JpaFacet; import org.eclipse.jpt.jpa.core.JpaPlatform; import org.eclipse.jpt.jpa.core.JpaPlatformFactory; import org.eclipse.jpt.jpa.core.JpaPlatformVariation; +import org.eclipse.jpt.jpa.core.context.AccessType; import org.eclipse.jpt.jpa.core.internal.jpa1.GenericJpaFactory; -import org.eclipse.wst.common.project.facet.core.DefaultVersionComparator; /** * All the state in the JPA platform should be "static" (i.e. unchanging once @@ -55,6 +55,9 @@ public class GenericJpaPlatformFactory public boolean isJoinTableOverridable() { return false; } + public AccessType[] getSupportedAccessTypes(JptResourceType resourceType) { + return GENERIC_SUPPORTED_ACCESS_TYPES; + } }; } @@ -62,8 +65,6 @@ public class GenericJpaPlatformFactory public static class SimpleVersion implements JpaPlatform.Version { protected final String jpaVersion; - public static final Comparator<String> JPA_VERSION_COMPARATOR = new DefaultVersionComparator(); - public SimpleVersion(String jpaVersion) { super(); this.jpaVersion = jpaVersion; @@ -84,7 +85,7 @@ public class GenericJpaPlatformFactory * For now, generic platforms are backward-compatible. */ public boolean isCompatibleWithJpaVersion(String version) { - return JPA_VERSION_COMPARATOR.compare(this.jpaVersion, version) >= 0; + return VERSION_COMPARATOR.compare(this.jpaVersion, version) >= 0; } @Override diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/context/java/AbstractJavaPersistentAttribute.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/context/java/AbstractJavaPersistentAttribute.java index 6438772fb5..bddecd461e 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/context/java/AbstractJavaPersistentAttribute.java +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/context/java/AbstractJavaPersistentAttribute.java @@ -176,7 +176,7 @@ public abstract class AbstractJavaPersistentAttribute */ protected AccessType buildSpecifiedAccess() { Access2_0Annotation accessAnnotation = this.getAccessAnnotation(); - return (accessAnnotation == null) ? null : AccessType.fromJavaResourceModel(accessAnnotation.getValue()); + return (accessAnnotation == null) ? null : AccessType.fromJavaResourceModel(accessAnnotation.getValue(), this.getJpaPlatform(), this.getResourceType()); } protected Access2_0Annotation getAccessAnnotation() { diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/context/java/AbstractJavaPersistentType.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/context/java/AbstractJavaPersistentType.java index 8b7c8ae5e4..53506af8ce 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/context/java/AbstractJavaPersistentType.java +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/context/java/AbstractJavaPersistentType.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2011 Oracle. All rights reserved. + * Copyright (c) 2006, 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. @@ -240,7 +240,7 @@ public abstract class AbstractJavaPersistentType } protected AccessType buildSpecifiedAccess() { - return AccessType.fromJavaResourceModel(this.getAccessAnnotation().getValue()); + return AccessType.fromJavaResourceModel(this.getAccessAnnotation().getValue(), this.getJpaPlatform(), this.getResourceType()); } public AccessType getDefaultAccess() { diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/context/orm/AbstractEntityMappings.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/context/orm/AbstractEntityMappings.java index 8184ae5fa5..0e6a9023ab 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/context/orm/AbstractEntityMappings.java +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/context/orm/AbstractEntityMappings.java @@ -332,7 +332,7 @@ public abstract class AbstractEntityMappings } protected AccessType buildSpecifiedAccess() { - return AccessType.fromOrmResourceModel(this.xmlEntityMappings.getAccess()); + return AccessType.fromOrmResourceModel(this.xmlEntityMappings.getAccess(), this.getJpaPlatform(), this.getResourceType()); } public AccessType getDefaultAccess() { diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/context/orm/AbstractOrmXmlContextNode.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/context/orm/AbstractOrmXmlContextNode.java index d6ec443ca7..75569ed57a 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/context/orm/AbstractOrmXmlContextNode.java +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/context/orm/AbstractOrmXmlContextNode.java @@ -60,7 +60,7 @@ public abstract class AbstractOrmXmlContextNode protected boolean isOrmXml2_0Compatible() { String version = this.getMappingFileRoot().getVersion(); try { - return (version != null) && SimpleVersion.JPA_VERSION_COMPARATOR.compare(version, "2.0") >= 0; //$NON-NLS-1$ + return (version != null) && SimpleVersion.VERSION_COMPARATOR.compare(version, "2.0") >= 0; //$NON-NLS-1$ } catch (VersionFormatException ex) { return false; } diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/context/orm/SpecifiedOrmPersistentAttribute.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/context/orm/SpecifiedOrmPersistentAttribute.java index 04178ae078..b2fc33f978 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/context/orm/SpecifiedOrmPersistentAttribute.java +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/context/orm/SpecifiedOrmPersistentAttribute.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2011 Oracle. All rights reserved. + * Copyright (c) 2006, 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. @@ -380,7 +380,7 @@ public abstract class SpecifiedOrmPersistentAttribute } protected AccessType buildSpecifiedAccess() { - return AccessType.fromOrmResourceModel(this.getXmlAccessHolder().getAccess()); + return AccessType.fromOrmResourceModel(this.getXmlAccessHolder().getAccess(), this.getJpaPlatform(), this.getResourceType()); } protected XmlAccessHolder getXmlAccessHolder() { diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/context/orm/SpecifiedOrmPersistentType.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/context/orm/SpecifiedOrmPersistentType.java new file mode 100644 index 0000000000..aad8269592 --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/context/orm/SpecifiedOrmPersistentType.java @@ -0,0 +1,1401 @@ +/******************************************************************************* + * Copyright (c) 2006, 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.core.internal.context.orm; + +import java.util.Collection; +import java.util.Comparator; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; +import java.util.Vector; +import org.eclipse.core.resources.IFile; +import org.eclipse.jdt.core.IPackageFragment; +import org.eclipse.jdt.core.IType; +import org.eclipse.jpt.common.core.resource.java.JavaResourceAbstractType; +import org.eclipse.jpt.common.core.resource.java.JavaResourceAnnotatedElement.Kind; +import org.eclipse.jpt.common.core.resource.java.JavaResourceField; +import org.eclipse.jpt.common.core.resource.java.JavaResourceMethod; +import org.eclipse.jpt.common.core.resource.java.JavaResourceType; +import org.eclipse.jpt.common.core.utility.BodySourceWriter; +import org.eclipse.jpt.common.core.utility.TextRange; +import org.eclipse.jpt.common.utility.Filter; +import org.eclipse.jpt.common.utility.internal.ClassName; +import org.eclipse.jpt.common.utility.internal.CollectionTools; +import org.eclipse.jpt.common.utility.internal.StringTools; +import org.eclipse.jpt.common.utility.internal.Tools; +import org.eclipse.jpt.common.utility.internal.iterables.ChainIterable; +import org.eclipse.jpt.common.utility.internal.iterables.CompositeIterable; +import org.eclipse.jpt.common.utility.internal.iterables.CompositeListIterable; +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.FilteringIterable; +import org.eclipse.jpt.common.utility.internal.iterables.ListIterable; +import org.eclipse.jpt.common.utility.internal.iterables.LiveCloneListIterable; +import org.eclipse.jpt.common.utility.internal.iterables.SingleElementIterable; +import org.eclipse.jpt.common.utility.internal.iterables.SuperListIterableWrapper; +import org.eclipse.jpt.common.utility.internal.iterables.TransformationIterable; +import org.eclipse.jpt.jpa.core.JpaStructureNode; +import org.eclipse.jpt.jpa.core.JptJpaCorePlugin; +import org.eclipse.jpt.jpa.core.context.AccessType; +import org.eclipse.jpt.jpa.core.context.PersistentType; +import org.eclipse.jpt.jpa.core.context.ReadOnlyPersistentAttribute; +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.OrmAttributeMapping; +import org.eclipse.jpt.jpa.core.context.orm.OrmAttributeMappingDefinition; +import org.eclipse.jpt.jpa.core.context.orm.OrmPersistentAttribute; +import org.eclipse.jpt.jpa.core.context.orm.OrmPersistentType; +import org.eclipse.jpt.jpa.core.context.orm.OrmReadOnlyPersistentAttribute; +import org.eclipse.jpt.jpa.core.context.orm.OrmStructureNodes; +import org.eclipse.jpt.jpa.core.context.orm.OrmTypeMapping; +import org.eclipse.jpt.jpa.core.context.orm.OrmTypeMappingDefinition; +import org.eclipse.jpt.jpa.core.internal.context.ContextContainerTools; +import org.eclipse.jpt.jpa.core.internal.context.java.AbstractJavaPersistentType; +import org.eclipse.jpt.jpa.core.internal.context.java.PropertyAccessor; +import org.eclipse.jpt.jpa.core.internal.context.orm.AbstractOrmXmlContextNode; +import org.eclipse.jpt.jpa.core.internal.validation.DefaultJpaValidationMessages; +import org.eclipse.jpt.jpa.core.internal.validation.JpaValidationMessages; +import org.eclipse.jpt.jpa.core.jpa2.context.MetamodelSourceType; +import org.eclipse.jpt.jpa.core.jpa2.context.java.JavaPersistentType2_0; +import org.eclipse.jpt.jpa.core.jpa2.context.orm.OrmPersistentType2_0; +import org.eclipse.jpt.jpa.core.resource.orm.Attributes; +import org.eclipse.jpt.jpa.core.resource.orm.OrmPackage; +import org.eclipse.jpt.jpa.core.resource.orm.XmlAttributeMapping; +import org.eclipse.jpt.jpa.core.resource.orm.XmlTypeMapping; +import org.eclipse.jpt.jpa.core.resource.xml.EmfTools; +import org.eclipse.text.edits.DeleteEdit; +import org.eclipse.text.edits.ReplaceEdit; +import org.eclipse.wst.validation.internal.provisional.core.IMessage; +import org.eclipse.wst.validation.internal.provisional.core.IReporter; + +/** + * specified <code>orm.xml</code> persistent type:<ul> + * <li>mapping + * <li>access + * <li>attributes + * <li>super persistent type + * <li>Java persistent type + * </ul> + */ +public abstract class SpecifiedOrmPersistentType + extends AbstractOrmXmlContextNode + implements OrmPersistentType2_0 +{ + protected OrmTypeMapping mapping; // never null + + protected JavaPersistentType javaPersistentType; + + protected AccessType specifiedAccess; + protected AccessType defaultAccess; // never null + + protected final Vector<OrmPersistentAttribute> specifiedAttributes = new Vector<OrmPersistentAttribute>(); + protected final SpecifiedAttributeContainerAdapter specifiedAttributeContainerAdapter = new SpecifiedAttributeContainerAdapter(); + + protected final Vector<OrmReadOnlyPersistentAttribute> virtualAttributes = new Vector<OrmReadOnlyPersistentAttribute>(); + + protected PersistentType superPersistentType; + + protected String declaringTypeName; + + protected final MetamodelSourceType.Synchronizer metamodelSynchronizer; + + + protected SpecifiedOrmPersistentType(EntityMappings parent, XmlTypeMapping xmlTypeMapping) { + super(parent); + this.mapping = this.buildMapping(xmlTypeMapping); + // 'javaPersistentType' is resolved in the update + this.specifiedAccess = this.buildSpecifiedAccess(); + this.defaultAccess = AccessType.FIELD; // keep this non-null + this.initializeSpecifiedAttributes(); + this.metamodelSynchronizer = this.buildMetamodelSynchronizer(); + } + + + // ********** synchronize/update ********** + + @Override + public void synchronizeWithResourceModel() { + super.synchronizeWithResourceModel(); + this.mapping.synchronizeWithResourceModel(); + this.syncJavaPersistentType(); + this.setSpecifiedAccess_(this.buildSpecifiedAccess()); + this.syncSpecifiedAttributes(); + this.synchronizeNodesWithResourceModel(this.getVirtualAttributes()); + } + + @Override + public void update() { + super.update(); + this.mapping.update(); + this.updateJavaPersistentType(); + this.setDefaultAccess(this.buildDefaultAccess()); + this.updateNodes(this.getSpecifiedAttributes()); + this.updateVirtualAttributes(); + this.setSuperPersistentType(this.buildSuperPersistentType()); + this.setDeclaringTypeName(this.buildDeclaringTypeName()); + } + + + // ********** mapping ********** + + public OrmTypeMapping getMapping() { + return this.mapping; + } + + public String getMappingKey() { + return this.mapping.getKey(); + } + + public void setMappingKey(String mappingKey) { + if (this.valuesAreDifferent(this.getMappingKey(), mappingKey)) { + this.setMappingKey_(mappingKey); + } + } + + protected void setMappingKey_(String mappingKey) { + OrmTypeMapping old = this.mapping; + OrmTypeMappingDefinition mappingDefinition = this.getMappingFileDefinition().getTypeMappingDefinition(mappingKey); + XmlTypeMapping xmlTypeMapping = mappingDefinition.buildResourceMapping(this.getResourceNodeFactory()); + this.mapping = this.buildMapping(xmlTypeMapping); + this.getEntityMappings().changeMapping(this, old, this.mapping); + this.firePropertyChanged(MAPPING_PROPERTY, old, this.mapping); + } + + protected OrmTypeMapping buildMapping(XmlTypeMapping xmlTypeMapping) { + OrmTypeMappingDefinition md = this.getMappingFileDefinition().getTypeMappingDefinition(xmlTypeMapping.getMappingKey()); + return md.buildContextMapping(this, xmlTypeMapping, this.getContextNodeFactory()); + } + + protected XmlTypeMapping getXmlTypeMapping() { + return this.mapping.getXmlTypeMapping(); + } + + public boolean isMapped() { + return true; + } + + + // ********** name ********** + + public String getName() { + return (this.javaPersistentType != null) ? + this.javaPersistentType.getName() : + this.getMappingClassName(); + } + + protected String getMappingClassName() { + return this.convertMappingClassName(this.mapping.getClass_()); + } + + public String getSimpleName(){ + String className = this.getName(); + return StringTools.stringIsEmpty(className) ? null : ClassName.getSimpleName(className); + } + + /** + * We clear out {@link #javaPersistentType} here because we cannot compare its name + * to the mapping's class name, since it may have been prefixed by the entity + * mappings package. + */ + public void mappingClassChanged(String oldClass, String newClass) { + this.firePropertyChanged(NAME_PROPERTY, this.convertMappingClassName(oldClass), this.convertMappingClassName(newClass)); + // clear out the Java type here, it will be rebuilt during "update" + if (this.javaPersistentType != null) { + this.javaPersistentType.dispose(); + this.setJavaPersistentType(null); + } + } + + /** + * Nested class names are specified with a <code>'$'</code> + * in <code>orm.xml</code>. + */ + protected String convertMappingClassName(String name) { + return (name == null) ? null : name.replace('$', '.'); + } + + + // ********** Java persistent type ********** + + public JavaPersistentType getJavaPersistentType() { + return this.javaPersistentType; + } + + protected void setJavaPersistentType(JavaPersistentType javaPersistentType) { + JavaPersistentType old = this.javaPersistentType; + this.javaPersistentType = javaPersistentType; + this.firePropertyChanged(JAVA_PERSISTENT_TYPE_PROPERTY, old, javaPersistentType); + } + + /** + * If the persistent type's mapping's class (name) changes during + * <em>sync</em>, the Java persistent type will be cleared out in + * {@link #mappingClassChanged(String, String)}. If we get here and + * the Java persistent type is still present, we can + * <em>sync</em> it. Of course, it might still be obsolete if the + * entity mappings's package has changed.... + * + * @see #updateJavaPersistentType() + */ + protected void syncJavaPersistentType() { + if (this.javaPersistentType != null) { + this.javaPersistentType.synchronizeWithResourceModel(); + } + } + + /** + * @see #syncJavaPersistentType() + */ + protected void updateJavaPersistentType() { + JavaResourceAbstractType resourceType = this.resolveJavaResourceType(); + if (resourceType == null) { + if (this.javaPersistentType != null) { + this.javaPersistentType.dispose(); + this.setJavaPersistentType(null); + } + } else { + if (this.javaPersistentType == null) { + this.setJavaPersistentType(this.buildJavaPersistentType(resourceType)); + } else { + if (this.javaPersistentType.getJavaResourceType() == resourceType) { + this.javaPersistentType.update(); + } else { + this.javaPersistentType.dispose(); + this.setJavaPersistentType(this.buildJavaPersistentType(resourceType)); + } + } + } + } + + /** + * Use {@link #getMappingClassName()} instead of {@link #getName()} to + * look up the Java resource type because {@link #getName()} + * simply delegates to the existing Java resource persistent type. (In + * which case we wouldn't need to resolve it, would we?) [bug 339560] + * @see #updateJavaPersistentType() + */ + protected JavaResourceAbstractType resolveJavaResourceType() { + return this.getEntityMappings().resolveJavaResourceType(this.getMappingClassName()); + } + + /** + * Return null it's an enum; don't build a JavaPersistentType + */ + protected JavaPersistentType buildJavaPersistentType(JavaResourceAbstractType jrat) { + return jrat.getKind() == Kind.TYPE ? this.buildJavaPersistentType((JavaResourceType) jrat) : null; + } + + protected JavaPersistentType buildJavaPersistentType(JavaResourceType jrpt) { + return this.getJpaFactory().buildJavaPersistentType(this, jrpt); + } + + + // ********** access ********** + + public AccessType getAccess() { + return (this.specifiedAccess != null) ? this.specifiedAccess : this.defaultAccess; + } + + public AccessType getSpecifiedAccess() { + return this.specifiedAccess; + } + + public void setSpecifiedAccess(AccessType access) { + this.setSpecifiedAccess_(access); + this.getXmlTypeMapping().setAccess(AccessType.toOrmResourceModel(access)); + } + + protected void setSpecifiedAccess_(AccessType access) { + AccessType old = this.specifiedAccess; + this.specifiedAccess = access; + this.firePropertyChanged(SPECIFIED_ACCESS_PROPERTY, old, access); + } + + protected AccessType buildSpecifiedAccess() { + return AccessType.fromOrmResourceModel(this.getXmlTypeMapping().getAccess(), this.getJpaPlatform(), this.getResourceType()); + } + + public AccessType getDefaultAccess() { + return this.defaultAccess; + } + + protected void setDefaultAccess(AccessType access) { + AccessType old = this.defaultAccess; + this.defaultAccess = access; + this.firePropertyChanged(DEFAULT_ACCESS_PROPERTY, old, access); + } + + protected AccessType buildDefaultAccess() { + if ( ! this.mapping.isMetadataComplete()) { + if (this.javaPersistentType != null) { + if (this.javaPersistentTypeHasSpecifiedAccess()) { + return this.javaPersistentType.getAccess(); + } + if (this.superPersistentType != null) { + return this.superPersistentType.getAccess(); + } + } + } + AccessType access = this.getMappingFileRoot().getAccess(); + return (access != null) ? access : AccessType.FIELD; // default to FIELD if no specified access found + } + + /** + * pre-condition: {@link #javaPersistentType} is not <code>null</code> + */ + protected boolean javaPersistentTypeHasSpecifiedAccess() { + return (this.javaPersistentType.getSpecifiedAccess() != null) || + this.javaPersistentType.hasAnyAnnotatedAttributes(); + } + + public AccessType getOwnerOverrideAccess() { + return this.getEntityMappings().getOverridePersistentTypeAccess(); + } + + public AccessType getOwnerDefaultAccess() { + return this.getEntityMappings().getDefaultPersistentTypeAccess(); + } + + + // ********** attributes ********** + + @SuppressWarnings("unchecked") + public ListIterable<OrmReadOnlyPersistentAttribute> getAttributes() { + return new CompositeListIterable<OrmReadOnlyPersistentAttribute>(this.getReadOnlySpecifiedAttributes(), this.getVirtualAttributes()); + } + + //TODO remove this compatibility method in the Juno release + public ListIterator<OrmReadOnlyPersistentAttribute> attributes() { + return this.getAttributes().iterator(); + } + + + public int getAttributesSize() { + return this.getSpecifiedAttributesSize() + this.getVirtualAttributesSize(); + } + + public Iterable<String> getAttributeNames() { + return this.convertToNames(this.getAttributes()); + } + + public OrmReadOnlyPersistentAttribute getAttributeNamed(String attributeName) { + Iterator<OrmReadOnlyPersistentAttribute> stream = this.getAttributesNamed(attributeName).iterator(); + return stream.hasNext() ? stream.next() : null; + } + + public Iterable<ReadOnlyPersistentAttribute> getAllAttributes() { + return new CompositeIterable<ReadOnlyPersistentAttribute>( + new TransformationIterable<PersistentType, Iterable<ReadOnlyPersistentAttribute>>(this.getInheritanceHierarchy()) { + @Override + protected Iterable<ReadOnlyPersistentAttribute> transform(PersistentType pt) { + return new SuperListIterableWrapper<ReadOnlyPersistentAttribute>(pt.getAttributes()); + } + } + ); + } + + //TODO remove this compatibility method in the Juno release + public Iterator<ReadOnlyPersistentAttribute> allAttributes() { + return getAllAttributes().iterator(); + } + + public Iterable<String> getAllAttributeNames() { + return this.convertToNames(this.getAllAttributes()); + } + + protected Iterable<OrmReadOnlyPersistentAttribute> getAttributesNamed(final String attributeName) { + return new FilteringIterable<OrmReadOnlyPersistentAttribute>(this.getAttributes()) { + @Override + protected boolean accept(OrmReadOnlyPersistentAttribute attribute) { + return Tools.valuesAreEqual(attributeName, attribute.getName()); + } + }; + } + + public ReadOnlyPersistentAttribute resolveAttribute(String attributeName) { + Iterator<OrmReadOnlyPersistentAttribute> attributes = this.getAttributesNamed(attributeName).iterator(); + if (attributes.hasNext()) { + OrmReadOnlyPersistentAttribute attribute = attributes.next(); + return attributes.hasNext() ? null /* more than one */: attribute; + } + // recurse + return (this.superPersistentType == null) ? null : this.superPersistentType.resolveAttribute(attributeName); + } + + protected Iterable<String> convertToNames(Iterable<? extends ReadOnlyPersistentAttribute> attributes) { + return new TransformationIterable<ReadOnlyPersistentAttribute, String>(attributes) { + @Override + protected String transform(ReadOnlyPersistentAttribute attribute) { + return attribute.getName(); + } + }; + } + + + // ********** attribute conversions ********** + + public OrmPersistentAttribute convertAttributeToSpecified(OrmReadOnlyPersistentAttribute virtualAttribute) { + return this.convertAttributeToSpecified(virtualAttribute, virtualAttribute.getMappingKey()); + } + + public OrmPersistentAttribute convertAttributeToSpecified(OrmReadOnlyPersistentAttribute virtualAttribute, String mappingKey) { + if ( ! virtualAttribute.isVirtual()) { + throw new IllegalArgumentException("Attribute is already specified: " + virtualAttribute); //$NON-NLS-1$ + } + if (mappingKey == null) { + // this typically happens when the virtual attribute does not have a mapping + throw new IllegalArgumentException("Use convertAttributeToSpecified(OrmReadOnlyPersistentAttribute, String) instead and specify a mapping key"); //$NON-NLS-1$ + } + return this.convertAttributeToSpecified_(virtualAttribute, mappingKey); + } + + /** + * <em>Silently</em> remove the virtual attribute and add specified + * attribute before triggering an <em>update</em> or the dangling + * virtual attribute will be removed preemptively. + */ + protected OrmPersistentAttribute convertAttributeToSpecified_(OrmReadOnlyPersistentAttribute virtualAttribute, String mappingKey) { + // silently remove the virtual attribute + int virtualIndex = this.virtualAttributes.indexOf(virtualAttribute); + this.virtualAttributes.remove(virtualIndex); + virtualAttribute.dispose(); + + // silently add the specified attribute + OrmAttributeMappingDefinition md = this.getMappingFileDefinition().getAttributeMappingDefinition(mappingKey); + XmlAttributeMapping xmlMapping = md.buildResourceMapping(this.getResourceNodeFactory()); + + 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.specifiedAttributes.add(specifiedIndex, specifiedAttribute); + + // this will trigger the initial update; + // no changes to either collection (virtual or specified) should be detected at this point + specifiedAttribute.getMapping().setName(virtualAttribute.getName()); + + // fire the list change events + this.fireItemRemoved(VIRTUAL_ATTRIBUTES_LIST, virtualIndex, virtualAttribute); + this.fireItemAdded(SPECIFIED_ATTRIBUTES_LIST, specifiedIndex, specifiedAttribute); + + // it should be safe to update the XML now + Attributes xmlAttributes = this.getXmlAttributesForUpdate(); + specifiedAttribute.getMapping().addXmlAttributeMappingTo(xmlAttributes); + // possibly a NOP, but needed when we trigger the creation of a new 'attributes' + this.getXmlTypeMapping().setAttributes(xmlAttributes); + + // copy over the specified access(?) + AccessType oldAccess = virtualAttribute.getJavaPersistentAttribute().getSpecifiedAccess(); + if (oldAccess != null) { + specifiedAttribute.setSpecifiedAccess(oldAccess); + } + return specifiedAttribute; + } + + // TODO this is used only by our tests... + // we cannot delegate to getAttributeNamed(String).convertToSpecified() + // because the tests use this method to add "orphan" xml attributes (that + // do not have a corresponding java attribute :( ) + public OrmPersistentAttribute addSpecifiedAttribute(String mappingKey, String attributeName) { + // 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 = md.buildResourceMapping(this.getResourceNodeFactory()); + + 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); + // the virtual attributes list should remain unchanged since the specified attribute has no name + this.addItemToList(specifiedIndex, specifiedAttribute, this.specifiedAttributes, SPECIFIED_ATTRIBUTES_LIST); + specifiedAttribute.getMapping().addXmlAttributeMappingTo(xmlAttributes); + + // this will trigger the update of the virtual attributes list + specifiedAttribute.getMapping().setName(attributeName); + + return specifiedAttribute; + } + + protected int getSpecifiedAttributeInsertionIndex(OrmPersistentAttribute attribute) { + return CollectionTools.insertionIndexOf(this.specifiedAttributes, attribute, this.getAttributeComparator()); + } + + protected Comparator<OrmPersistentAttribute> getAttributeComparator() { + return ATTRIBUTE_COMPARATOR; + } + + protected static final Comparator<OrmPersistentAttribute> ATTRIBUTE_COMPARATOR = + new Comparator<OrmPersistentAttribute>() { + public int compare(OrmPersistentAttribute attribute1, OrmPersistentAttribute attribute2) { + int seq1 = attribute1.getMapping().getXmlSequence(); + int seq2 = attribute2.getMapping().getXmlSequence(); + return (seq1 == seq2) ? 0 : (seq1 < seq2) ? -1 : 1; + } + }; + + /** + * <em>Silently</em> add the new virtual attribute before removing the + * specified attribute, or the <em>update</em> will discover the missing + * virtual attribute and add it preemptively. + */ + public OrmReadOnlyPersistentAttribute convertAttributeToVirtual(OrmPersistentAttribute specifiedAttribute) { + if (specifiedAttribute.isVirtual()) { + throw new IllegalArgumentException("Attribute is already virtual: " + specifiedAttribute); //$NON-NLS-1$ + } + + int virtualIndex = this.virtualAttributes.size(); + OrmReadOnlyPersistentAttribute virtualAttribute = null; + // make sure the corresponding resource Java attribute actually exists in the *current* type; + // do *not* take the context Java attribute directly from the specified ORM + // attribute we are converting since it may have come from a superclass; + // instead, use its resource Java attribute (which will match both name and access type, + // but we still need to check its parent type) + if (specifiedAttribute.getJavaResourceAttribute() != null) { + if (specifiedAttribute.getJavaResourceAttribute().getKind() == Kind.FIELD) { + JavaResourceField javaResourceField = (JavaResourceField) specifiedAttribute.getJavaResourceAttribute(); + if (this.javaResourceFieldWillBeVirtual(javaResourceField, specifiedAttribute)) { + virtualAttribute = this.buildVirtualAttribute(javaResourceField); + this.virtualAttributes.add(virtualIndex, virtualAttribute); + } + } + else { + PropertyAccessor propertyAccessor = (PropertyAccessor) specifiedAttribute.getJavaPersistentAttribute().getAccessor(); + JavaResourceMethod resourceGetter = propertyAccessor.getResourceGetter(); + JavaResourceMethod resourceSetter = propertyAccessor.getResourceSetter(); + + if (this.javaResourcePropertyWillBeVirtual(resourceGetter, resourceSetter, specifiedAttribute)) { + virtualAttribute = this.buildVirtualAttribute(resourceGetter, resourceSetter); + this.virtualAttributes.add(virtualIndex, virtualAttribute); + } + } + } + + this.removeSpecifiedAttribute(specifiedAttribute); // trigger update + + if (virtualAttribute != null) { + this.fireItemAdded(VIRTUAL_ATTRIBUTES_LIST, virtualIndex, virtualAttribute); + } + return virtualAttribute; + } + + /** + * Return whether the specified Java resource attribute will be a + * <em>virtual</em> attribute when the specified specified attribute is + * removed from the type. The Java resource attribute must be among the + * valid Java resource attributes and it must not correspond to any of the + * remaining specified attributes. + */ + protected boolean javaResourceFieldWillBeVirtual(JavaResourceField javaResourceField, OrmPersistentAttribute specifiedAttributeToBeRemoved) { + return CollectionTools.contains(this.getJavaResourceFields(), javaResourceField) && + (this.getSpecifiedAttributeFor(javaResourceField, specifiedAttributeToBeRemoved) == null); + } + + /** + * Return whether the specified Java resource attribute will be a + * <em>virtual</em> attribute when the specified specified attribute is + * removed from the type. The Java resource attribute must be among the + * valid Java resource attributes and it must not correspond to any of the + * remaining specified attributes. + */ + protected boolean javaResourcePropertyWillBeVirtual(JavaResourceMethod javaResourceGetter, JavaResourceMethod javaResourceSetter, OrmPersistentAttribute specifiedAttributeToBeRemoved) { + return CollectionTools.contains(this.getJavaResourceMethods(), javaResourceGetter) && + CollectionTools.contains(this.getJavaResourceMethods(), javaResourceSetter) && + (this.getSpecifiedAttributeFor(javaResourceGetter, javaResourceSetter, specifiedAttributeToBeRemoved) == null); + } + + + // ********** xml attributes ********** + + /** + * Return <code>null</code> if the <code>attributes</code> element is missing. + */ + protected Attributes getXmlAttributes() { + return this.getXmlTypeMapping().getAttributes(); + } + + /** + * Build a new <code>attributes</code> element if it is not present; + * but do <em>not</em> add it to the XML type mapping. Callers will have + * to add it to the XML type mapping when appropriate. + */ + protected Attributes getXmlAttributesForUpdate() { + Attributes xmlAttributes = this.getXmlAttributes(); + return (xmlAttributes != null) ? xmlAttributes : this.buildXmlAttributes(); + } + + protected Attributes buildXmlAttributes() { + return EmfTools.create(this.getResourceNodeFactory(), OrmPackage.eINSTANCE.getAttributes(), Attributes.class); + } + + protected void removeXmlAttributesIfUnset() { + if (this.getXmlAttributes().isUnset()) { + this.getXmlTypeMapping().setAttributes(null); + } + } + + + // ********** specified attributes ********** + + public ListIterable<OrmPersistentAttribute> getSpecifiedAttributes() { + return new LiveCloneListIterable<OrmPersistentAttribute>(this.specifiedAttributes); + } + + protected ListIterable<OrmReadOnlyPersistentAttribute> getReadOnlySpecifiedAttributes() { + return new SuperListIterableWrapper<OrmReadOnlyPersistentAttribute>(this.getSpecifiedAttributes()); + } + + public int getSpecifiedAttributesSize() { + return this.specifiedAttributes.size(); + } + + protected void removeSpecifiedAttribute(OrmPersistentAttribute attribute) { + this.removeSpecifiedAttribute_(attribute); + attribute.getMapping().removeXmlAttributeMappingFrom(this.getXmlAttributes()); + this.removeXmlAttributesIfUnset(); + } + + public void changeMapping(OrmPersistentAttribute attribute, OrmAttributeMapping oldMapping, OrmAttributeMapping newMapping) { + // keep the context model in sync with each change to the resource model + int sourceIndex = this.specifiedAttributes.indexOf(attribute); + this.specifiedAttributes.remove(sourceIndex); + oldMapping.removeXmlAttributeMappingFrom(this.getXmlAttributes()); + + int targetIndex = this.getSpecifiedAttributeInsertionIndex(attribute); + this.specifiedAttributes.add(targetIndex, attribute); + newMapping.addXmlAttributeMappingTo(this.getXmlAttributes()); + + oldMapping.initializeOn(newMapping); + + this.fireItemMoved(SPECIFIED_ATTRIBUTES_LIST, targetIndex, sourceIndex); + } + + protected void initializeSpecifiedAttributes() { + for (XmlAttributeMapping xmlMapping : this.getXmlAttributeMappings()) { + this.specifiedAttributes.add(this.buildSpecifiedAttribute(xmlMapping)); + } + } + + protected Iterable<XmlAttributeMapping> getXmlAttributeMappings() { + Attributes xmlAttributes = this.getXmlAttributes(); + return (xmlAttributes != null) ? xmlAttributes.getAttributeMappings() : EmptyIterable.<XmlAttributeMapping>instance(); + } + + protected OrmPersistentAttribute buildSpecifiedAttribute(XmlAttributeMapping xmlMapping) { + return this.getContextNodeFactory().buildOrmPersistentAttribute(this, xmlMapping); + } + + protected void syncSpecifiedAttributes() { + ContextContainerTools.synchronizeWithResourceModel(this.specifiedAttributeContainerAdapter); + } + + protected void moveSpecifiedAttribute_(int index, OrmPersistentAttribute attribute) { + this.moveItemInList(index, attribute, this.specifiedAttributes, SPECIFIED_ATTRIBUTES_LIST); + } + + protected void addSpecifiedAttribute_(int index, XmlAttributeMapping xmlMapping) { + OrmPersistentAttribute attribute = this.buildSpecifiedAttribute(xmlMapping); + this.addItemToList(index, attribute, this.specifiedAttributes, SPECIFIED_ATTRIBUTES_LIST); + } + + protected void removeSpecifiedAttribute_(OrmPersistentAttribute attribute) { + this.removeItemFromList(attribute, this.specifiedAttributes, SPECIFIED_ATTRIBUTES_LIST); + } + + /** + * specified attribute container adapter + */ + protected class SpecifiedAttributeContainerAdapter + implements ContextContainerTools.Adapter<OrmPersistentAttribute, XmlAttributeMapping> + { + public Iterable<OrmPersistentAttribute> getContextElements() { + return SpecifiedOrmPersistentType.this.getSpecifiedAttributes(); + } + public Iterable<XmlAttributeMapping> getResourceElements() { + return SpecifiedOrmPersistentType.this.getXmlAttributeMappings(); + } + public XmlAttributeMapping getResourceElement(OrmPersistentAttribute contextElement) { + return contextElement.getMapping().getXmlAttributeMapping(); + } + public void moveContextElement(int index, OrmPersistentAttribute element) { + SpecifiedOrmPersistentType.this.moveSpecifiedAttribute_(index, element); + } + public void addContextElement(int index, XmlAttributeMapping resourceElement) { + SpecifiedOrmPersistentType.this.addSpecifiedAttribute_(index, resourceElement); + } + public void removeContextElement(OrmPersistentAttribute element) { + SpecifiedOrmPersistentType.this.removeSpecifiedAttribute_(element); + } + } + + + // ********** virtual attributes ********** + + public ListIterable<OrmReadOnlyPersistentAttribute> getVirtualAttributes() { + return new LiveCloneListIterable<OrmReadOnlyPersistentAttribute>(this.virtualAttributes); + } + + public int getVirtualAttributesSize() { + return this.virtualAttributes.size(); + } + + /** + * The attributes are synchronized during the <em>update</em> because + * the list of resource attributes is determined by the access type + * which can be controlled in a number of different places.... + */ + protected void updateVirtualAttributes() { + if (getVirtualJavaAccess() == AccessType.FIELD) { + this.syncFieldAccessVirtualAttributes(); + } + else if (getVirtualJavaAccess() == AccessType.PROPERTY) { + this.syncPropertyAccessVirtualAttributes(); + } + } + + /** + * Initialize the attributes for AccessType.FIELD + * 1. all non-transient, non-static fields + * 2. all annotated methods(getters/setters) + */ + private void syncFieldAccessVirtualAttributes() { + HashSet<OrmReadOnlyPersistentAttribute> contextAttributes = CollectionTools.set(this.getVirtualAttributes()); + + this.syncFieldVirtualAttributes(contextAttributes, buildNonTransientNonStaticResourceFieldsFilter()); + if (!getMapping().isMetadataComplete()) { + this.syncAnnotatedPropertyVirtualAttributes(contextAttributes); + } + + // remove any leftover context attributes + for (OrmReadOnlyPersistentAttribute contextAttribute : contextAttributes) { + this.removeVirtualAttribute(contextAttribute); + } + } + + /** + * Initialize the attributes for XmlAccessType.PROPERTY + * 1. all getter/setter javabeans pairs + * 2. all annotated fields + * 3. all annotated methods getters/setters that don't have a matching pair + */ + private void syncPropertyAccessVirtualAttributes() { + HashSet<OrmReadOnlyPersistentAttribute> contextAttributes = CollectionTools.set(this.getVirtualAttributes()); + + if (!getMapping().isMetadataComplete()) { + this.syncFieldVirtualAttributes(contextAttributes, AbstractJavaPersistentType.ANNOTATED_RESOURCE_FIELDS_FILTER); + } + + Collection<JavaResourceMethod> resourceMethods = CollectionTools.collection(this.getJavaResourceMethods()); + //iterate through all resource methods searching for persistable getters + for (JavaResourceMethod getterMethod : this.getJavaResourceMethods(this.buildPersistablePropertyGetterMethodsFilter())) { + JavaResourceMethod setterMethod = AbstractJavaPersistentType.getValidSiblingSetMethod(getterMethod, resourceMethods); + if (javaResourcePropertyIsVirtual(getterMethod, setterMethod)) { + if (AbstractJavaPersistentType.methodsArePersistableProperties(getterMethod, setterMethod)) { + boolean match = false; + for (Iterator<OrmReadOnlyPersistentAttribute> stream = contextAttributes.iterator(); stream.hasNext();) { + OrmReadOnlyPersistentAttribute contextAttribute = stream.next(); + if (contextAttribute.isFor(getterMethod, setterMethod)) { + match = true; + contextAttribute.update(); + stream.remove(); + break; + } + } + if (!match) { + this.addVirtualAttribute(getVirtualAttributesSize(), this.buildVirtualAttribute(getterMethod, setterMethod)); + } + } + } + resourceMethods.remove(getterMethod); + resourceMethods.remove(setterMethod); + } + this.syncRemainingResourceVirtualMethods(contextAttributes, resourceMethods); + + // remove any leftover context attributes + for (OrmReadOnlyPersistentAttribute contextAttribute : contextAttributes) { + this.removeVirtualAttribute(contextAttribute); + } + } + + private void syncAnnotatedPropertyVirtualAttributes(HashSet<OrmReadOnlyPersistentAttribute> contextAttributes) { + Collection<JavaResourceMethod> resourceMethods = CollectionTools.collection(this.getJavaResourceMethods()); + //iterate through all resource methods searching for persistable getters + for (JavaResourceMethod getterMethod : this.getJavaResourceMethods(buildPersistablePropertyGetterMethodsFilter())) { + JavaResourceMethod setterMethod = AbstractJavaPersistentType.getValidSiblingSetMethod(getterMethod, resourceMethods); + if (javaResourcePropertyIsVirtual(getterMethod, setterMethod)) { + if (getterMethod.isAnnotated() || (setterMethod != null && setterMethod.isAnnotated())) { + boolean match = false; + for (Iterator<OrmReadOnlyPersistentAttribute> stream = contextAttributes.iterator(); stream.hasNext();) { + OrmReadOnlyPersistentAttribute contextAttribute = stream.next(); + if (contextAttribute.isFor(getterMethod, setterMethod)) { + match = true; + contextAttribute.update(); + stream.remove(); + break; + } + } + if (!match) { + this.addVirtualAttribute(getVirtualAttributesSize(), this.buildVirtualAttribute(getterMethod, setterMethod)); + } + } + } + resourceMethods.remove(getterMethod); + resourceMethods.remove(setterMethod); + } + this.syncRemainingResourceVirtualMethods(contextAttributes, resourceMethods); + } + + private void syncFieldVirtualAttributes(HashSet<OrmReadOnlyPersistentAttribute> contextAttributes, Filter<JavaResourceField> filter) { + for (JavaResourceField resourceField : this.getVirtualJavaResourceFields(filter)) { + boolean match = false; + for (Iterator<OrmReadOnlyPersistentAttribute> stream = contextAttributes.iterator(); stream.hasNext(); ) { + OrmReadOnlyPersistentAttribute contextAttribute = stream.next(); + if (contextAttribute.isFor(resourceField)) { + match = true; + contextAttribute.update(); + stream.remove(); + break; + } + } + if (!match) { + // added elements are sync'ed during construction or will be + // updated during the next "update" (which is triggered by + // their addition to the model) + this.addVirtualAttribute(this.getVirtualAttributesSize(), this.buildVirtualAttribute(resourceField)); + } + } + } + + private void syncRemainingResourceVirtualMethods(HashSet<OrmReadOnlyPersistentAttribute> contextAttributes, Collection<JavaResourceMethod> resourceMethods) { + //iterate through remaining resource methods and search for those that are annotated. + //all getter methods will already be used. + for (JavaResourceMethod resourceMethod : resourceMethods) { + if (resourceMethod.isAnnotated()) { + boolean match = false; + //annotated setter(or other random method) with no corresponding getter, bring into context model for validation purposes + for (Iterator<OrmReadOnlyPersistentAttribute> stream = contextAttributes.iterator(); stream.hasNext();) { + OrmReadOnlyPersistentAttribute contextAttribute = stream.next(); + if (contextAttribute.isFor(null, resourceMethod)) { + match = true; + contextAttribute.update(); + stream.remove(); + break; + } + } + if (!match) { + this.addVirtualAttribute(getVirtualAttributesSize(), this.buildVirtualAttribute(null, resourceMethod)); + } + } + } + } + + /** + * Return all the Java resource fields that do not have a + * corresponding <code>orm.xml</code> mapping currently + * specified in the <code>orm.xml</code> persistent type. + */ + protected Iterable<JavaResourceField> getVirtualJavaResourceFields() { + return new FilteringIterable<JavaResourceField>(this.getJavaResourceFields()) { + @Override + protected boolean accept(JavaResourceField javaResourceField) { + return SpecifiedOrmPersistentType.this.javaResourceFieldIsVirtual(javaResourceField); + } + }; + } + + protected Iterable<JavaResourceField> getJavaResourceFields() { + JavaResourceType javaResourceType = this.getJavaResourceType(); + if (javaResourceType == null) { + return EmptyListIterable.instance(); + } + return javaResourceType.getFields(); + } + + protected Iterable<JavaResourceField> getVirtualJavaResourceFields(Filter<JavaResourceField> filter) { + return new FilteringIterable<JavaResourceField>(getVirtualJavaResourceFields(), filter); + } + + protected Iterable<JavaResourceMethod> getJavaResourceMethods(Filter<JavaResourceMethod> filter) { + return new FilteringIterable<JavaResourceMethod>(getJavaResourceMethods(), filter); + } + + protected Iterable<JavaResourceMethod> getJavaResourceMethods() { + JavaResourceType javaResourceType = this.getJavaResourceType(); + if (javaResourceType == null) { + return EmptyListIterable.instance(); + } + return javaResourceType.getMethods(); + } + + public static Filter<JavaResourceField> buildNonTransientNonStaticResourceFieldsFilter() { + return AbstractJavaPersistentType.buildNonTransientNonStaticResourceFieldsFilter(); + } + + protected Filter<JavaResourceMethod> buildPersistablePropertyGetterMethodsFilter() { + return new Filter<JavaResourceMethod>() { + public boolean accept(JavaResourceMethod resourceMethod) { + return AbstractJavaPersistentType.methodIsPersistablePropertyGetter(resourceMethod, getJavaResourceMethods()); + } + }; + } + + protected JavaResourceType getJavaResourceType() { + return (this.javaPersistentType == null) ? null : this.javaPersistentType.getJavaResourceType(); + } + + /** + * Return the access type that determines which Java attributes are to be + * used for the <code>orm.xml</code> type's <em>virtual</em> attributes. + */ + protected AccessType getVirtualJavaAccess() { + if (this.specifiedAccess != null) { + return this.specifiedAccess; + } + if (this.mapping.isMetadataComplete()) { + return this.defaultAccess; + } + AccessType javaAccess = this.javaPersistentType == null ? null : this.javaPersistentType.getSpecifiedAccess(); + return (javaAccess != null) ? javaAccess : this.defaultAccess; + } + + protected boolean javaResourceFieldIsVirtual(JavaResourceField javaResourceField) { + return this.getSpecifiedAttributeFor(javaResourceField) == null; + } + + protected OrmPersistentAttribute getSpecifiedAttributeFor(JavaResourceField javaResourceField) { + return this.getSpecifiedAttributeFor(javaResourceField, null); + } + + /** + * Return the specified attribute corresponding to the specified Java + * resource field, ignoring the specified excluded attribute (since + * there can be more than one specified attribute per Java resource + * attribute; albeit erroneously). + */ + protected OrmPersistentAttribute getSpecifiedAttributeFor(JavaResourceField javaResourceField, OrmPersistentAttribute exclude) { + for (OrmPersistentAttribute ormAttribute : this.getSpecifiedAttributes()) { + if (ormAttribute == exclude) { + continue; // skip + } + if (ormAttribute.isFor(javaResourceField)) { + return ormAttribute; + } + } + return null; + } + + protected boolean javaResourcePropertyIsVirtual(JavaResourceMethod javaResourceGetter, JavaResourceMethod javaResourceSetter) { + return this.getSpecifiedAttributeFor(javaResourceGetter, javaResourceSetter) == null; + } + + protected OrmPersistentAttribute getSpecifiedAttributeFor(JavaResourceMethod javaResourceGetter, JavaResourceMethod javaResourceSetter) { + return this.getSpecifiedAttributeFor(javaResourceGetter, javaResourceSetter, null); + } + + /** + * Return the specified attribute corresponding to the specified Java + * resource field, ignoring the specified excluded attribute (since + * there can be more than one specified attribute per Java resource + * attribute; albeit erroneously). + */ + protected OrmPersistentAttribute getSpecifiedAttributeFor(JavaResourceMethod javaResourceGetter, JavaResourceMethod javaResourceSetter, OrmPersistentAttribute exclude) { + for (OrmPersistentAttribute ormAttribute : this.getSpecifiedAttributes()) { + if (ormAttribute == exclude) { + continue; // skip + } + if (ormAttribute.isFor(javaResourceGetter, javaResourceSetter)) { + return ormAttribute; + } + } + return null; + } + + protected void moveVirtualAttribute(int index, OrmReadOnlyPersistentAttribute virtualAttribute) { + this.moveItemInList(index, virtualAttribute, this.virtualAttributes, VIRTUAL_ATTRIBUTES_LIST); + } + + protected void addVirtualAttribute(int index, OrmReadOnlyPersistentAttribute virtualAttribute) { + this.addItemToList(index, virtualAttribute, this.virtualAttributes, VIRTUAL_ATTRIBUTES_LIST); + } + + protected OrmReadOnlyPersistentAttribute buildVirtualAttribute(JavaResourceField javaResourceField) { + return this.getContextNodeFactory().buildVirtualOrmPersistentField(this, javaResourceField); + } + + protected OrmReadOnlyPersistentAttribute buildVirtualAttribute(JavaResourceMethod javaResourceGetter, JavaResourceMethod javaResourceSetter) { + return this.getContextNodeFactory().buildVirtualOrmPersistentProperty(this, javaResourceGetter, javaResourceSetter); + } + + protected void removeVirtualAttribute(OrmReadOnlyPersistentAttribute virtualAttribute) { + virtualAttribute.dispose(); + this.removeItemFromList(virtualAttribute, this.virtualAttributes, VIRTUAL_ATTRIBUTES_LIST); + } + + + // ********** super persistent type ********** + + public PersistentType getSuperPersistentType() { + return this.superPersistentType; + } + + protected void setSuperPersistentType(PersistentType persistentType) { + PersistentType old = this.superPersistentType; + this.superPersistentType = persistentType; + this.firePropertyChanged(SUPER_PERSISTENT_TYPE_PROPERTY, old, persistentType); + } + + protected PersistentType buildSuperPersistentType() { + PersistentType spt = this.buildSuperPersistentType_(); + if (spt == null) { + return null; + } + // check for circular inheritance + return CollectionTools.contains(spt.getInheritanceHierarchy(), this) ? null : spt; + } + + protected PersistentType buildSuperPersistentType_() { + return (this.javaPersistentType == null) ? null : this.javaPersistentType.getSuperPersistentType(); + } + + + // ********** inheritance ********** + + public Iterable<PersistentType> getInheritanceHierarchy() { + return this.getInheritanceHierarchyOf(this); + } + + public Iterable<PersistentType> getAncestors() { + return this.getInheritanceHierarchyOf(this.superPersistentType); + } + + protected Iterable<PersistentType> getInheritanceHierarchyOf(PersistentType start) { + // using a chain iterable to traverse up the inheritance tree + return new ChainIterable<PersistentType>(start) { + @Override + protected PersistentType nextLink(PersistentType persistentType) { + return persistentType.getSuperPersistentType(); + } + }; + } + + + // ********** declaring type name ********** + + public String getDeclaringTypeName() { + return this.declaringTypeName; + } + + protected void setDeclaringTypeName(String name) { + String old = this.declaringTypeName; + this.declaringTypeName = name; + this.firePropertyChanged(DECLARING_TYPE_NAME_PROPERTY, old, name); + } + + protected String buildDeclaringTypeName() { + return this.isJpa2_0Compatible() ? this.buildDeclaringTypeName_() : null; + } + + protected String buildDeclaringTypeName_() { + return (this.javaPersistentType == null) ? + null : ((JavaPersistentType2_0) this.javaPersistentType).getDeclaringTypeName(); + } + + + // ********** metamodel ********** + + protected MetamodelSourceType.Synchronizer buildMetamodelSynchronizer() { + return this.isJpa2_0Compatible() ? + this.getJpaFactory2_0().buildMetamodelSynchronizer(this) : + null; + } + + public IFile getMetamodelFile() { + return (this.javaPersistentType == null) ? null : this.metamodelSynchronizer.getFile(); + } + + public void initializeMetamodel() { + // do nothing - probably shouldn't be called... + } + + public boolean isManaged() { + return true; + } + + /** + * All <code>orm.xml</code> persistent types must be able to generate a static metamodel + * because 1.0 <code>orm.xml</code> files can be referenced from 2.0 persistence.xml files. + */ + public void synchronizeMetamodel(Map<String, Collection<MetamodelSourceType>> memberTypeTree) { + if (this.javaPersistentType != null) { + this.metamodelSynchronizer.synchronize(memberTypeTree); + } + } + + public void printBodySourceOn(BodySourceWriter pw, Map<String, Collection<MetamodelSourceType>> memberTypeTree) { + if (this.javaPersistentType != null) { + this.metamodelSynchronizer.printBodySourceOn(pw, memberTypeTree); + } + } + + public void disposeMetamodel() { + // do nothing - probably shouldn't be called... + } + + + // ********** JpaStructureNode implementation ********** + + public String getId() { + return OrmStructureNodes.PERSISTENT_TYPE_ID; + } + + public JpaStructureNode getStructureNode(int textOffset) { + for (OrmPersistentAttribute attribute : this.getSpecifiedAttributes()) { + if (attribute.contains(textOffset)) { + return attribute; + } + } + return this; + } + + public TextRange getSelectionTextRange() { + return this.mapping.getSelectionTextRange(); + } + + public void dispose() { + if (this.javaPersistentType != null) { + this.javaPersistentType.dispose(); + } + for (OrmReadOnlyPersistentAttribute virtualAttribute : this.getVirtualAttributes()) { + virtualAttribute.dispose(); + } + } + + + // ********** PersistentType.Owner implementation ********** + + public AccessType getOverridePersistentTypeAccess() { + if (this.specifiedAccess != null) { + return this.specifiedAccess; + } + + if (this.superPersistentType instanceof OrmPersistentType) { + AccessType accessType = ((OrmPersistentType) this.superPersistentType).getSpecifiedAccess(); + if (accessType != null) { + return accessType; + } + } + + if (this.mapping.isMetadataComplete()) { + AccessType accessType = this.getOwnerDefaultAccess(); + if (accessType != null) { + return accessType; + } + } + + // no override access type + return null; + } + + public AccessType getDefaultPersistentTypeAccess() { + if (this.superPersistentType instanceof OrmPersistentType) { + AccessType accessType = ((OrmPersistentType) this.superPersistentType).getDefaultAccess(); + if (accessType != null) { + return accessType; + } + } + + return this.getOwnerDefaultAccess(); + } + + + //*********** refactoring *********** + + public Iterable<DeleteEdit> createDeleteTypeEdits(IType type) { + return this.isFor(type.getFullyQualifiedName('.')) ? + new SingleElementIterable<DeleteEdit>(this.mapping.createDeleteEdit()) : + EmptyIterable.<DeleteEdit>instance(); + } + + @SuppressWarnings("unchecked") + public Iterable<ReplaceEdit> createRenameTypeEdits(IType originalType, String newName) { + return new CompositeIterable<ReplaceEdit>( + this.mapping.createRenameTypeEdits(originalType, newName), + this.createSpecifiedAttributesRenameTypeEdits(originalType, newName) + ); + } + + protected Iterable<ReplaceEdit> createSpecifiedAttributesRenameTypeEdits(final IType originalType, final String newName) { + return new CompositeIterable<ReplaceEdit>( + new TransformationIterable<OrmPersistentAttribute, Iterable<ReplaceEdit>>(this.getSpecifiedAttributes()) { + @Override + protected Iterable<ReplaceEdit> transform(OrmPersistentAttribute persistentAttribute) { + return persistentAttribute.createRenameTypeEdits(originalType, newName); + } + } + ); + } + + @SuppressWarnings("unchecked") + public Iterable<ReplaceEdit> createMoveTypeEdits(IType originalType, IPackageFragment newPackage) { + return new CompositeIterable<ReplaceEdit>( + this.mapping.createMoveTypeEdits(originalType, newPackage), + this.createSpecifiedAttributesMoveTypeEdits(originalType, newPackage) + ); + } + + protected Iterable<ReplaceEdit> createSpecifiedAttributesMoveTypeEdits(final IType originalType, final IPackageFragment newPackage) { + return new CompositeIterable<ReplaceEdit>( + new TransformationIterable<OrmPersistentAttribute, Iterable<ReplaceEdit>>(this.getSpecifiedAttributes()) { + @Override + protected Iterable<ReplaceEdit> transform(OrmPersistentAttribute persistentAttribute) { + return persistentAttribute.createMoveTypeEdits(originalType, newPackage); + } + } + ); + } + + @SuppressWarnings("unchecked") + public Iterable<ReplaceEdit> createRenamePackageEdits(IPackageFragment originalPackage, String newName) { + return new CompositeIterable<ReplaceEdit>( + this.mapping.createRenamePackageEdits(originalPackage, newName), + this.createSpecifiedAttributesRenamePackageEdits(originalPackage, newName) + ); + } + + protected Iterable<ReplaceEdit> createSpecifiedAttributesRenamePackageEdits(final IPackageFragment originalPackage, final String newName) { + return new CompositeIterable<ReplaceEdit>( + new TransformationIterable<OrmPersistentAttribute, Iterable<ReplaceEdit>>(this.getSpecifiedAttributes()) { + @Override + protected Iterable<ReplaceEdit> transform(OrmPersistentAttribute persistentAttribute) { + return persistentAttribute.createRenamePackageEdits(originalPackage, newName); + } + } + ); + } + + + // ********** validation ********** + + @Override + public void validate(List<IMessage> messages, IReporter reporter) { + super.validate(messages, reporter); + this.validateClass(messages); + this.validateMapping(messages, reporter); + this.validateAttributes(messages, reporter); + } + + protected void validateClass(List<IMessage> messages) { + if (this.javaPersistentType == null) { + messages.add( + DefaultJpaValidationMessages.buildMessage( + IMessage.HIGH_SEVERITY, + JpaValidationMessages.PERSISTENT_TYPE_UNRESOLVED_CLASS, + new String[] {this.getName()}, + this, + this.mapping.getClassTextRange() + ) + ); + } + } + + protected void validateMapping(List<IMessage> messages, IReporter reporter) { + try { + this.mapping.validate(messages, reporter); + } catch(Throwable t) { + JptJpaCorePlugin.log(t); + } + } + + protected void validateAttributes(List<IMessage> messages, IReporter reporter) { + for (OrmReadOnlyPersistentAttribute attribute : this.getAttributes()) { + this.validateAttribute(attribute, messages, reporter); + } + } + + protected void validateAttribute(OrmReadOnlyPersistentAttribute attribute, List<IMessage> messages, IReporter reporter) { + try { + attribute.validate(messages, reporter); + } catch(Throwable t) { + JptJpaCorePlugin.log(t); + } + } + + public TextRange getValidationTextRange() { + return this.mapping.getValidationTextRange(); + } + + + // ********** misc ********** + + @Override + public EntityMappings getParent() { + return (EntityMappings) super.getParent(); + } + + protected EntityMappings getEntityMappings() { + return this.getParent(); + } + + public String getDefaultPackage() { + return this.getEntityMappings().getPackage(); + } + + public boolean isFor(String typeName) { + String name = this.getName(); + if (name == null) { + return false; + } + if (name.equals(typeName)) { + return true; + } + String defaultPackage = this.getDefaultPackage(); + if (defaultPackage == null) { + return false; + } + return (defaultPackage + '.' + name).equals(typeName); + } + + public boolean isIn(IPackageFragment packageFragment) { + String packageName = this.getPackageName(); + if (Tools.valuesAreEqual(packageName, packageFragment.getElementName())) { + return true; + } + String defaultPackage = this.getDefaultPackage(); + if (defaultPackage == null) { + return false; + } + packageName = (packageName == null) ? defaultPackage : defaultPackage + '.' + packageName; + return packageName.equals(packageFragment.getElementName()); + } + + protected String getPackageName() { + String className = this.getName(); + if (className == null) { + return null; + } + int lastPeriod = className.lastIndexOf('.'); + return (lastPeriod == -1) ? null : className.substring(0, lastPeriod); + } + + public boolean contains(int textOffset) { + return this.mapping.containsOffset(textOffset); + } + + public PersistentType getOverriddenPersistentType() { + return this.mapping.isMetadataComplete() ? null : this.javaPersistentType; + } + + @Override + public void toString(StringBuilder sb) { + sb.append(this.getName()); + } +} diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/orm/AbstractOrmPersistenceUnitDefaults.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/orm/AbstractOrmPersistenceUnitDefaults.java index 1189170be7..77e8e7936e 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/orm/AbstractOrmPersistenceUnitDefaults.java +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/orm/AbstractOrmPersistenceUnitDefaults.java @@ -105,7 +105,7 @@ public abstract class AbstractOrmPersistenceUnitDefaults protected AccessType buildSpecifiedAccess() { XmlPersistenceUnitDefaults xmlDefaults = this.getXmlDefaults(); - return (xmlDefaults == null) ? null : AccessType.fromOrmResourceModel(xmlDefaults.getAccess()); + return (xmlDefaults == null) ? null : AccessType.fromOrmResourceModel(xmlDefaults.getAccess(), this.getJpaPlatform(), this.getResourceType()); } diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/orm/GenericOrmPersistentType.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/orm/GenericOrmPersistentType.java index 9989b7c304..750bfb8d7e 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/orm/GenericOrmPersistentType.java +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/orm/GenericOrmPersistentType.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2011 Oracle. All rights reserved. + * Copyright (c) 2006, 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. @@ -9,73 +9,9 @@ ******************************************************************************/ package org.eclipse.jpt.jpa.core.internal.jpa1.context.orm; -import java.util.Collection; -import java.util.Comparator; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; -import java.util.Map; -import java.util.Vector; -import org.eclipse.core.resources.IFile; -import org.eclipse.jdt.core.IPackageFragment; -import org.eclipse.jdt.core.IType; -import org.eclipse.jpt.common.core.resource.java.JavaResourceAbstractType; -import org.eclipse.jpt.common.core.resource.java.JavaResourceAnnotatedElement.Kind; -import org.eclipse.jpt.common.core.resource.java.JavaResourceField; -import org.eclipse.jpt.common.core.resource.java.JavaResourceMethod; -import org.eclipse.jpt.common.core.resource.java.JavaResourceType; -import org.eclipse.jpt.common.core.utility.BodySourceWriter; -import org.eclipse.jpt.common.core.utility.TextRange; -import org.eclipse.jpt.common.utility.Filter; -import org.eclipse.jpt.common.utility.internal.ClassName; -import org.eclipse.jpt.common.utility.internal.CollectionTools; -import org.eclipse.jpt.common.utility.internal.StringTools; -import org.eclipse.jpt.common.utility.internal.Tools; -import org.eclipse.jpt.common.utility.internal.iterables.ChainIterable; -import org.eclipse.jpt.common.utility.internal.iterables.CompositeIterable; -import org.eclipse.jpt.common.utility.internal.iterables.CompositeListIterable; -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.FilteringIterable; -import org.eclipse.jpt.common.utility.internal.iterables.ListIterable; -import org.eclipse.jpt.common.utility.internal.iterables.LiveCloneListIterable; -import org.eclipse.jpt.common.utility.internal.iterables.SingleElementIterable; -import org.eclipse.jpt.common.utility.internal.iterables.SuperListIterableWrapper; -import org.eclipse.jpt.common.utility.internal.iterables.TransformationIterable; -import org.eclipse.jpt.jpa.core.JpaStructureNode; -import org.eclipse.jpt.jpa.core.JptJpaCorePlugin; -import org.eclipse.jpt.jpa.core.context.AccessType; -import org.eclipse.jpt.jpa.core.context.PersistentType; -import org.eclipse.jpt.jpa.core.context.ReadOnlyPersistentAttribute; -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.OrmAttributeMapping; -import org.eclipse.jpt.jpa.core.context.orm.OrmAttributeMappingDefinition; -import org.eclipse.jpt.jpa.core.context.orm.OrmPersistentAttribute; -import org.eclipse.jpt.jpa.core.context.orm.OrmPersistentType; -import org.eclipse.jpt.jpa.core.context.orm.OrmReadOnlyPersistentAttribute; -import org.eclipse.jpt.jpa.core.context.orm.OrmStructureNodes; -import org.eclipse.jpt.jpa.core.context.orm.OrmTypeMapping; -import org.eclipse.jpt.jpa.core.context.orm.OrmTypeMappingDefinition; -import org.eclipse.jpt.jpa.core.internal.context.ContextContainerTools; -import org.eclipse.jpt.jpa.core.internal.context.java.AbstractJavaPersistentType; -import org.eclipse.jpt.jpa.core.internal.context.java.PropertyAccessor; -import org.eclipse.jpt.jpa.core.internal.context.orm.AbstractOrmXmlContextNode; -import org.eclipse.jpt.jpa.core.internal.validation.DefaultJpaValidationMessages; -import org.eclipse.jpt.jpa.core.internal.validation.JpaValidationMessages; -import org.eclipse.jpt.jpa.core.jpa2.context.MetamodelSourceType; -import org.eclipse.jpt.jpa.core.jpa2.context.java.JavaPersistentType2_0; -import org.eclipse.jpt.jpa.core.jpa2.context.orm.OrmPersistentType2_0; -import org.eclipse.jpt.jpa.core.resource.orm.Attributes; -import org.eclipse.jpt.jpa.core.resource.orm.OrmPackage; -import org.eclipse.jpt.jpa.core.resource.orm.XmlAttributeMapping; +import org.eclipse.jpt.jpa.core.internal.context.orm.SpecifiedOrmPersistentType; import org.eclipse.jpt.jpa.core.resource.orm.XmlTypeMapping; -import org.eclipse.jpt.jpa.core.resource.xml.EmfTools; -import org.eclipse.text.edits.DeleteEdit; -import org.eclipse.text.edits.ReplaceEdit; -import org.eclipse.wst.validation.internal.provisional.core.IMessage; -import org.eclipse.wst.validation.internal.provisional.core.IReporter; /** * <code>orm.xml</code> persistent type:<ul> @@ -87,1315 +23,10 @@ import org.eclipse.wst.validation.internal.provisional.core.IReporter; * </ul> */ public class GenericOrmPersistentType - extends AbstractOrmXmlContextNode - implements OrmPersistentType2_0 + extends SpecifiedOrmPersistentType { - protected OrmTypeMapping mapping; // never null - - protected JavaPersistentType javaPersistentType; - - protected AccessType specifiedAccess; - protected AccessType defaultAccess; // never null - - protected final Vector<OrmPersistentAttribute> specifiedAttributes = new Vector<OrmPersistentAttribute>(); - protected final SpecifiedAttributeContainerAdapter specifiedAttributeContainerAdapter = new SpecifiedAttributeContainerAdapter(); - - protected final Vector<OrmReadOnlyPersistentAttribute> virtualAttributes = new Vector<OrmReadOnlyPersistentAttribute>(); - - protected PersistentType superPersistentType; - - protected String declaringTypeName; - - protected final MetamodelSourceType.Synchronizer metamodelSynchronizer; - public GenericOrmPersistentType(EntityMappings parent, XmlTypeMapping xmlTypeMapping) { - super(parent); - this.mapping = this.buildMapping(xmlTypeMapping); - // 'javaPersistentType' is resolved in the update - this.specifiedAccess = this.buildSpecifiedAccess(); - this.defaultAccess = AccessType.FIELD; // keep this non-null - this.initializeSpecifiedAttributes(); - this.metamodelSynchronizer = this.buildMetamodelSynchronizer(); - } - - - // ********** synchronize/update ********** - - @Override - public void synchronizeWithResourceModel() { - super.synchronizeWithResourceModel(); - this.mapping.synchronizeWithResourceModel(); - this.syncJavaPersistentType(); - this.setSpecifiedAccess_(this.buildSpecifiedAccess()); - this.syncSpecifiedAttributes(); - this.synchronizeNodesWithResourceModel(this.getVirtualAttributes()); - } - - @Override - public void update() { - super.update(); - this.mapping.update(); - this.updateJavaPersistentType(); - this.setDefaultAccess(this.buildDefaultAccess()); - this.updateNodes(this.getSpecifiedAttributes()); - this.updateVirtualAttributes(); - this.setSuperPersistentType(this.buildSuperPersistentType()); - this.setDeclaringTypeName(this.buildDeclaringTypeName()); - } - - - // ********** mapping ********** - - public OrmTypeMapping getMapping() { - return this.mapping; - } - - public String getMappingKey() { - return this.mapping.getKey(); - } - - public void setMappingKey(String mappingKey) { - if (this.valuesAreDifferent(this.getMappingKey(), mappingKey)) { - this.setMappingKey_(mappingKey); - } - } - - protected void setMappingKey_(String mappingKey) { - OrmTypeMapping old = this.mapping; - OrmTypeMappingDefinition mappingDefinition = this.getMappingFileDefinition().getTypeMappingDefinition(mappingKey); - XmlTypeMapping xmlTypeMapping = mappingDefinition.buildResourceMapping(this.getResourceNodeFactory()); - this.mapping = this.buildMapping(xmlTypeMapping); - this.getEntityMappings().changeMapping(this, old, this.mapping); - this.firePropertyChanged(MAPPING_PROPERTY, old, this.mapping); - } - - protected OrmTypeMapping buildMapping(XmlTypeMapping xmlTypeMapping) { - OrmTypeMappingDefinition md = this.getMappingFileDefinition().getTypeMappingDefinition(xmlTypeMapping.getMappingKey()); - return md.buildContextMapping(this, xmlTypeMapping, this.getContextNodeFactory()); - } - - protected XmlTypeMapping getXmlTypeMapping() { - return this.mapping.getXmlTypeMapping(); - } - - public boolean isMapped() { - return true; - } - - - // ********** name ********** - - public String getName() { - return (this.javaPersistentType != null) ? - this.javaPersistentType.getName() : - this.getMappingClassName(); - } - - protected String getMappingClassName() { - return this.convertMappingClassName(this.mapping.getClass_()); - } - - public String getSimpleName(){ - String className = this.getName(); - return StringTools.stringIsEmpty(className) ? null : ClassName.getSimpleName(className); - } - - /** - * We clear out {@link #javaPersistentType} here because we cannot compare its name - * to the mapping's class name, since it may have been prefixed by the entity - * mappings package. - */ - public void mappingClassChanged(String oldClass, String newClass) { - this.firePropertyChanged(NAME_PROPERTY, this.convertMappingClassName(oldClass), this.convertMappingClassName(newClass)); - // clear out the Java type here, it will be rebuilt during "update" - if (this.javaPersistentType != null) { - this.javaPersistentType.dispose(); - this.setJavaPersistentType(null); - } - } - - /** - * Nested class names are specified with a <code>'$'</code> - * in <code>orm.xml</code>. - */ - protected String convertMappingClassName(String name) { - return (name == null) ? null : name.replace('$', '.'); - } - - - // ********** Java persistent type ********** - - public JavaPersistentType getJavaPersistentType() { - return this.javaPersistentType; - } - - protected void setJavaPersistentType(JavaPersistentType javaPersistentType) { - JavaPersistentType old = this.javaPersistentType; - this.javaPersistentType = javaPersistentType; - this.firePropertyChanged(JAVA_PERSISTENT_TYPE_PROPERTY, old, javaPersistentType); - } - - /** - * If the persistent type's mapping's class (name) changes during - * <em>sync</em>, the Java persistent type will be cleared out in - * {@link #mappingClassChanged(String, String)}. If we get here and - * the Java persistent type is still present, we can - * <em>sync</em> it. Of course, it might still be obsolete if the - * entity mappings's package has changed.... - * - * @see #updateJavaPersistentType() - */ - protected void syncJavaPersistentType() { - if (this.javaPersistentType != null) { - this.javaPersistentType.synchronizeWithResourceModel(); - } - } - - /** - * @see #syncJavaPersistentType() - */ - protected void updateJavaPersistentType() { - JavaResourceAbstractType resourceType = this.resolveJavaResourceType(); - if (resourceType == null) { - if (this.javaPersistentType != null) { - this.javaPersistentType.dispose(); - this.setJavaPersistentType(null); - } - } else { - if (this.javaPersistentType == null) { - this.setJavaPersistentType(this.buildJavaPersistentType(resourceType)); - } else { - if (this.javaPersistentType.getJavaResourceType() == resourceType) { - this.javaPersistentType.update(); - } else { - this.javaPersistentType.dispose(); - this.setJavaPersistentType(this.buildJavaPersistentType(resourceType)); - } - } - } - } - - /** - * Use {@link #getMappingClassName()} instead of {@link #getName()} to - * look up the Java resource type because {@link #getName()} - * simply delegates to the existing Java resource persistent type. (In - * which case we wouldn't need to resolve it, would we?) [bug 339560] - * @see #updateJavaPersistentType() - */ - protected JavaResourceAbstractType resolveJavaResourceType() { - return this.getEntityMappings().resolveJavaResourceType(this.getMappingClassName()); - } - - /** - * Return null it's an enum; don't build a JavaPersistentType - */ - protected JavaPersistentType buildJavaPersistentType(JavaResourceAbstractType jrat) { - return jrat.getKind() == Kind.TYPE ? this.buildJavaPersistentType((JavaResourceType) jrat) : null; - } - - protected JavaPersistentType buildJavaPersistentType(JavaResourceType jrpt) { - return this.getJpaFactory().buildJavaPersistentType(this, jrpt); - } - - - // ********** access ********** - - public AccessType getAccess() { - return (this.specifiedAccess != null) ? this.specifiedAccess : this.defaultAccess; - } - - public AccessType getSpecifiedAccess() { - return this.specifiedAccess; - } - - public void setSpecifiedAccess(AccessType access) { - this.setSpecifiedAccess_(access); - this.getXmlTypeMapping().setAccess(AccessType.toOrmResourceModel(access)); - } - - protected void setSpecifiedAccess_(AccessType access) { - AccessType old = this.specifiedAccess; - this.specifiedAccess = access; - this.firePropertyChanged(SPECIFIED_ACCESS_PROPERTY, old, access); - } - - protected AccessType buildSpecifiedAccess() { - return AccessType.fromOrmResourceModel(this.getXmlTypeMapping().getAccess()); - } - - public AccessType getDefaultAccess() { - return this.defaultAccess; - } - - protected void setDefaultAccess(AccessType access) { - AccessType old = this.defaultAccess; - this.defaultAccess = access; - this.firePropertyChanged(DEFAULT_ACCESS_PROPERTY, old, access); - } - - protected AccessType buildDefaultAccess() { - if ( ! this.mapping.isMetadataComplete()) { - if (this.javaPersistentType != null) { - if (this.javaPersistentTypeHasSpecifiedAccess()) { - return this.javaPersistentType.getAccess(); - } - if (this.superPersistentType != null) { - return this.superPersistentType.getAccess(); - } - } - } - AccessType access = this.getMappingFileRoot().getAccess(); - return (access != null) ? access : AccessType.FIELD; // default to FIELD if no specified access found - } - - /** - * pre-condition: {@link #javaPersistentType} is not <code>null</code> - */ - protected boolean javaPersistentTypeHasSpecifiedAccess() { - return (this.javaPersistentType.getSpecifiedAccess() != null) || - this.javaPersistentType.hasAnyAnnotatedAttributes(); - } - - public AccessType getOwnerOverrideAccess() { - return this.getEntityMappings().getOverridePersistentTypeAccess(); - } - - public AccessType getOwnerDefaultAccess() { - return this.getEntityMappings().getDefaultPersistentTypeAccess(); - } - - - // ********** attributes ********** - - @SuppressWarnings("unchecked") - public ListIterable<OrmReadOnlyPersistentAttribute> getAttributes() { - return new CompositeListIterable<OrmReadOnlyPersistentAttribute>(this.getReadOnlySpecifiedAttributes(), this.getVirtualAttributes()); - } - - //TODO remove this compatibility method in the Juno release - public ListIterator<OrmReadOnlyPersistentAttribute> attributes() { - return this.getAttributes().iterator(); - } - - - public int getAttributesSize() { - return this.getSpecifiedAttributesSize() + this.getVirtualAttributesSize(); - } - - public Iterable<String> getAttributeNames() { - return this.convertToNames(this.getAttributes()); - } - - public OrmReadOnlyPersistentAttribute getAttributeNamed(String attributeName) { - Iterator<OrmReadOnlyPersistentAttribute> stream = this.getAttributesNamed(attributeName).iterator(); - return stream.hasNext() ? stream.next() : null; - } - - public Iterable<ReadOnlyPersistentAttribute> getAllAttributes() { - return new CompositeIterable<ReadOnlyPersistentAttribute>( - new TransformationIterable<PersistentType, Iterable<ReadOnlyPersistentAttribute>>(this.getInheritanceHierarchy()) { - @Override - protected Iterable<ReadOnlyPersistentAttribute> transform(PersistentType pt) { - return new SuperListIterableWrapper<ReadOnlyPersistentAttribute>(pt.getAttributes()); - } - } - ); - } - - //TODO remove this compatibility method in the Juno release - public Iterator<ReadOnlyPersistentAttribute> allAttributes() { - return getAllAttributes().iterator(); - } - - public Iterable<String> getAllAttributeNames() { - return this.convertToNames(this.getAllAttributes()); - } - - protected Iterable<OrmReadOnlyPersistentAttribute> getAttributesNamed(final String attributeName) { - return new FilteringIterable<OrmReadOnlyPersistentAttribute>(this.getAttributes()) { - @Override - protected boolean accept(OrmReadOnlyPersistentAttribute attribute) { - return Tools.valuesAreEqual(attributeName, attribute.getName()); - } - }; - } - - public ReadOnlyPersistentAttribute resolveAttribute(String attributeName) { - Iterator<OrmReadOnlyPersistentAttribute> attributes = this.getAttributesNamed(attributeName).iterator(); - if (attributes.hasNext()) { - OrmReadOnlyPersistentAttribute attribute = attributes.next(); - return attributes.hasNext() ? null /* more than one */: attribute; - } - // recurse - return (this.superPersistentType == null) ? null : this.superPersistentType.resolveAttribute(attributeName); - } - - protected Iterable<String> convertToNames(Iterable<? extends ReadOnlyPersistentAttribute> attributes) { - return new TransformationIterable<ReadOnlyPersistentAttribute, String>(attributes) { - @Override - protected String transform(ReadOnlyPersistentAttribute attribute) { - return attribute.getName(); - } - }; - } - - - // ********** attribute conversions ********** - - public OrmPersistentAttribute convertAttributeToSpecified(OrmReadOnlyPersistentAttribute virtualAttribute) { - return this.convertAttributeToSpecified(virtualAttribute, virtualAttribute.getMappingKey()); - } - - public OrmPersistentAttribute convertAttributeToSpecified(OrmReadOnlyPersistentAttribute virtualAttribute, String mappingKey) { - if ( ! virtualAttribute.isVirtual()) { - throw new IllegalArgumentException("Attribute is already specified: " + virtualAttribute); //$NON-NLS-1$ - } - if (mappingKey == null) { - // this typically happens when the virtual attribute does not have a mapping - throw new IllegalArgumentException("Use convertAttributeToSpecified(OrmReadOnlyPersistentAttribute, String) instead and specify a mapping key"); //$NON-NLS-1$ - } - return this.convertAttributeToSpecified_(virtualAttribute, mappingKey); - } - - /** - * <em>Silently</em> remove the virtual attribute and add specified - * attribute before triggering an <em>update</em> or the dangling - * virtual attribute will be removed preemptively. - */ - protected OrmPersistentAttribute convertAttributeToSpecified_(OrmReadOnlyPersistentAttribute virtualAttribute, String mappingKey) { - // silently remove the virtual attribute - int virtualIndex = this.virtualAttributes.indexOf(virtualAttribute); - this.virtualAttributes.remove(virtualIndex); - virtualAttribute.dispose(); - - // silently add the specified attribute - OrmAttributeMappingDefinition md = this.getMappingFileDefinition().getAttributeMappingDefinition(mappingKey); - XmlAttributeMapping xmlMapping = md.buildResourceMapping(this.getResourceNodeFactory()); - - 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.specifiedAttributes.add(specifiedIndex, specifiedAttribute); - - // this will trigger the initial update; - // no changes to either collection (virtual or specified) should be detected at this point - specifiedAttribute.getMapping().setName(virtualAttribute.getName()); - - // fire the list change events - this.fireItemRemoved(VIRTUAL_ATTRIBUTES_LIST, virtualIndex, virtualAttribute); - this.fireItemAdded(SPECIFIED_ATTRIBUTES_LIST, specifiedIndex, specifiedAttribute); - - // it should be safe to update the XML now - Attributes xmlAttributes = this.getXmlAttributesForUpdate(); - specifiedAttribute.getMapping().addXmlAttributeMappingTo(xmlAttributes); - // possibly a NOP, but needed when we trigger the creation of a new 'attributes' - this.getXmlTypeMapping().setAttributes(xmlAttributes); - - // copy over the specified access(?) - AccessType oldAccess = virtualAttribute.getJavaPersistentAttribute().getSpecifiedAccess(); - if (oldAccess != null) { - specifiedAttribute.setSpecifiedAccess(oldAccess); - } - return specifiedAttribute; - } - - // TODO this is used only by our tests... - // we cannot delegate to getAttributeNamed(String).convertToSpecified() - // because the tests use this method to add "orphan" xml attributes (that - // do not have a corresponding java attribute :( ) - public OrmPersistentAttribute addSpecifiedAttribute(String mappingKey, String attributeName) { - // 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 = md.buildResourceMapping(this.getResourceNodeFactory()); - - 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); - // the virtual attributes list should remain unchanged since the specified attribute has no name - this.addItemToList(specifiedIndex, specifiedAttribute, this.specifiedAttributes, SPECIFIED_ATTRIBUTES_LIST); - specifiedAttribute.getMapping().addXmlAttributeMappingTo(xmlAttributes); - - // this will trigger the update of the virtual attributes list - specifiedAttribute.getMapping().setName(attributeName); - - return specifiedAttribute; - } - - protected int getSpecifiedAttributeInsertionIndex(OrmPersistentAttribute attribute) { - return CollectionTools.insertionIndexOf(this.specifiedAttributes, attribute, this.getAttributeComparator()); - } - - protected Comparator<OrmPersistentAttribute> getAttributeComparator() { - return ATTRIBUTE_COMPARATOR; - } - - protected static final Comparator<OrmPersistentAttribute> ATTRIBUTE_COMPARATOR = - new Comparator<OrmPersistentAttribute>() { - public int compare(OrmPersistentAttribute attribute1, OrmPersistentAttribute attribute2) { - int seq1 = attribute1.getMapping().getXmlSequence(); - int seq2 = attribute2.getMapping().getXmlSequence(); - return (seq1 == seq2) ? 0 : (seq1 < seq2) ? -1 : 1; - } - }; - - /** - * <em>Silently</em> add the new virtual attribute before removing the - * specified attribute, or the <em>update</em> will discover the missing - * virtual attribute and add it preemptively. - */ - public OrmReadOnlyPersistentAttribute convertAttributeToVirtual(OrmPersistentAttribute specifiedAttribute) { - if (specifiedAttribute.isVirtual()) { - throw new IllegalArgumentException("Attribute is already virtual: " + specifiedAttribute); //$NON-NLS-1$ - } - - int virtualIndex = this.virtualAttributes.size(); - OrmReadOnlyPersistentAttribute virtualAttribute = null; - // make sure the corresponding resource Java attribute actually exists in the *current* type; - // do *not* take the context Java attribute directly from the specified ORM - // attribute we are converting since it may have come from a superclass; - // instead, use its resource Java attribute (which will match both name and access type, - // but we still need to check its parent type) - if (specifiedAttribute.getJavaResourceAttribute() != null) { - if (specifiedAttribute.getJavaResourceAttribute().getKind() == Kind.FIELD) { - JavaResourceField javaResourceField = (JavaResourceField) specifiedAttribute.getJavaResourceAttribute(); - if (this.javaResourceFieldWillBeVirtual(javaResourceField, specifiedAttribute)) { - virtualAttribute = this.buildVirtualAttribute(javaResourceField); - this.virtualAttributes.add(virtualIndex, virtualAttribute); - } - } - else { - PropertyAccessor propertyAccessor = (PropertyAccessor) specifiedAttribute.getJavaPersistentAttribute().getAccessor(); - JavaResourceMethod resourceGetter = propertyAccessor.getResourceGetter(); - JavaResourceMethod resourceSetter = propertyAccessor.getResourceSetter(); - - if (this.javaResourcePropertyWillBeVirtual(resourceGetter, resourceSetter, specifiedAttribute)) { - virtualAttribute = this.buildVirtualAttribute(resourceGetter, resourceSetter); - this.virtualAttributes.add(virtualIndex, virtualAttribute); - } - } - } - - this.removeSpecifiedAttribute(specifiedAttribute); // trigger update - - if (virtualAttribute != null) { - this.fireItemAdded(VIRTUAL_ATTRIBUTES_LIST, virtualIndex, virtualAttribute); - } - return virtualAttribute; - } - - /** - * Return whether the specified Java resource attribute will be a - * <em>virtual</em> attribute when the specified specified attribute is - * removed from the type. The Java resource attribute must be among the - * valid Java resource attributes and it must not correspond to any of the - * remaining specified attributes. - */ - protected boolean javaResourceFieldWillBeVirtual(JavaResourceField javaResourceField, OrmPersistentAttribute specifiedAttributeToBeRemoved) { - return CollectionTools.contains(this.getJavaResourceFields(), javaResourceField) && - (this.getSpecifiedAttributeFor(javaResourceField, specifiedAttributeToBeRemoved) == null); - } - - /** - * Return whether the specified Java resource attribute will be a - * <em>virtual</em> attribute when the specified specified attribute is - * removed from the type. The Java resource attribute must be among the - * valid Java resource attributes and it must not correspond to any of the - * remaining specified attributes. - */ - protected boolean javaResourcePropertyWillBeVirtual(JavaResourceMethod javaResourceGetter, JavaResourceMethod javaResourceSetter, OrmPersistentAttribute specifiedAttributeToBeRemoved) { - return CollectionTools.contains(this.getJavaResourceMethods(), javaResourceGetter) && - CollectionTools.contains(this.getJavaResourceMethods(), javaResourceSetter) && - (this.getSpecifiedAttributeFor(javaResourceGetter, javaResourceSetter, specifiedAttributeToBeRemoved) == null); - } - - - // ********** xml attributes ********** - - /** - * Return <code>null</code> if the <code>attributes</code> element is missing. - */ - protected Attributes getXmlAttributes() { - return this.getXmlTypeMapping().getAttributes(); - } - - /** - * Build a new <code>attributes</code> element if it is not present; - * but do <em>not</em> add it to the XML type mapping. Callers will have - * to add it to the XML type mapping when appropriate. - */ - protected Attributes getXmlAttributesForUpdate() { - Attributes xmlAttributes = this.getXmlAttributes(); - return (xmlAttributes != null) ? xmlAttributes : this.buildXmlAttributes(); - } - - protected Attributes buildXmlAttributes() { - return EmfTools.create(this.getResourceNodeFactory(), OrmPackage.eINSTANCE.getAttributes(), Attributes.class); - } - - protected void removeXmlAttributesIfUnset() { - if (this.getXmlAttributes().isUnset()) { - this.getXmlTypeMapping().setAttributes(null); - } - } - - - // ********** specified attributes ********** - - public ListIterable<OrmPersistentAttribute> getSpecifiedAttributes() { - return new LiveCloneListIterable<OrmPersistentAttribute>(this.specifiedAttributes); - } - - protected ListIterable<OrmReadOnlyPersistentAttribute> getReadOnlySpecifiedAttributes() { - return new SuperListIterableWrapper<OrmReadOnlyPersistentAttribute>(this.getSpecifiedAttributes()); - } - - public int getSpecifiedAttributesSize() { - return this.specifiedAttributes.size(); - } - - protected void removeSpecifiedAttribute(OrmPersistentAttribute attribute) { - this.removeSpecifiedAttribute_(attribute); - attribute.getMapping().removeXmlAttributeMappingFrom(this.getXmlAttributes()); - this.removeXmlAttributesIfUnset(); - } - - public void changeMapping(OrmPersistentAttribute attribute, OrmAttributeMapping oldMapping, OrmAttributeMapping newMapping) { - // keep the context model in sync with each change to the resource model - int sourceIndex = this.specifiedAttributes.indexOf(attribute); - this.specifiedAttributes.remove(sourceIndex); - oldMapping.removeXmlAttributeMappingFrom(this.getXmlAttributes()); - - int targetIndex = this.getSpecifiedAttributeInsertionIndex(attribute); - this.specifiedAttributes.add(targetIndex, attribute); - newMapping.addXmlAttributeMappingTo(this.getXmlAttributes()); - - oldMapping.initializeOn(newMapping); - - this.fireItemMoved(SPECIFIED_ATTRIBUTES_LIST, targetIndex, sourceIndex); - } - - protected void initializeSpecifiedAttributes() { - for (XmlAttributeMapping xmlMapping : this.getXmlAttributeMappings()) { - this.specifiedAttributes.add(this.buildSpecifiedAttribute(xmlMapping)); - } - } - - protected Iterable<XmlAttributeMapping> getXmlAttributeMappings() { - Attributes xmlAttributes = this.getXmlAttributes(); - return (xmlAttributes != null) ? xmlAttributes.getAttributeMappings() : EmptyIterable.<XmlAttributeMapping>instance(); - } - - protected OrmPersistentAttribute buildSpecifiedAttribute(XmlAttributeMapping xmlMapping) { - return this.getContextNodeFactory().buildOrmPersistentAttribute(this, xmlMapping); - } - - protected void syncSpecifiedAttributes() { - ContextContainerTools.synchronizeWithResourceModel(this.specifiedAttributeContainerAdapter); - } - - protected void moveSpecifiedAttribute_(int index, OrmPersistentAttribute attribute) { - this.moveItemInList(index, attribute, this.specifiedAttributes, SPECIFIED_ATTRIBUTES_LIST); - } - - protected void addSpecifiedAttribute_(int index, XmlAttributeMapping xmlMapping) { - OrmPersistentAttribute attribute = this.buildSpecifiedAttribute(xmlMapping); - this.addItemToList(index, attribute, this.specifiedAttributes, SPECIFIED_ATTRIBUTES_LIST); - } - - protected void removeSpecifiedAttribute_(OrmPersistentAttribute attribute) { - this.removeItemFromList(attribute, this.specifiedAttributes, SPECIFIED_ATTRIBUTES_LIST); - } - - /** - * specified attribute container adapter - */ - protected class SpecifiedAttributeContainerAdapter - implements ContextContainerTools.Adapter<OrmPersistentAttribute, XmlAttributeMapping> - { - public Iterable<OrmPersistentAttribute> getContextElements() { - return GenericOrmPersistentType.this.getSpecifiedAttributes(); - } - public Iterable<XmlAttributeMapping> getResourceElements() { - return GenericOrmPersistentType.this.getXmlAttributeMappings(); - } - public XmlAttributeMapping getResourceElement(OrmPersistentAttribute contextElement) { - return contextElement.getMapping().getXmlAttributeMapping(); - } - public void moveContextElement(int index, OrmPersistentAttribute element) { - GenericOrmPersistentType.this.moveSpecifiedAttribute_(index, element); - } - public void addContextElement(int index, XmlAttributeMapping resourceElement) { - GenericOrmPersistentType.this.addSpecifiedAttribute_(index, resourceElement); - } - public void removeContextElement(OrmPersistentAttribute element) { - GenericOrmPersistentType.this.removeSpecifiedAttribute_(element); - } - } - - - // ********** virtual attributes ********** - - public ListIterable<OrmReadOnlyPersistentAttribute> getVirtualAttributes() { - return new LiveCloneListIterable<OrmReadOnlyPersistentAttribute>(this.virtualAttributes); - } - - public int getVirtualAttributesSize() { - return this.virtualAttributes.size(); - } - - /** - * The attributes are synchronized during the <em>update</em> because - * the list of resource attributes is determined by the access type - * which can be controlled in a number of different places.... - */ - protected void updateVirtualAttributes() { - if (getVirtualJavaAccess() == AccessType.FIELD) { - this.syncFieldAccessVirtualAttributes(); - } - else if (getVirtualJavaAccess() == AccessType.PROPERTY) { - this.syncPropertyAccessVirtualAttributes(); - } - } - - /** - * Initialize the attributes for AccessType.FIELD - * 1. all non-transient, non-static fields - * 2. all annotated methods(getters/setters) - */ - private void syncFieldAccessVirtualAttributes() { - HashSet<OrmReadOnlyPersistentAttribute> contextAttributes = CollectionTools.set(this.getVirtualAttributes()); - - this.syncFieldVirtualAttributes(contextAttributes, buildNonTransientNonStaticResourceFieldsFilter()); - if (!getMapping().isMetadataComplete()) { - this.syncAnnotatedPropertyVirtualAttributes(contextAttributes); - } - - // remove any leftover context attributes - for (OrmReadOnlyPersistentAttribute contextAttribute : contextAttributes) { - this.removeVirtualAttribute(contextAttribute); - } - } - - /** - * Initialize the attributes for XmlAccessType.PROPERTY - * 1. all getter/setter javabeans pairs - * 2. all annotated fields - * 3. all annotated methods getters/setters that don't have a matching pair - */ - private void syncPropertyAccessVirtualAttributes() { - HashSet<OrmReadOnlyPersistentAttribute> contextAttributes = CollectionTools.set(this.getVirtualAttributes()); - - if (!getMapping().isMetadataComplete()) { - this.syncFieldVirtualAttributes(contextAttributes, AbstractJavaPersistentType.ANNOTATED_RESOURCE_FIELDS_FILTER); - } - - Collection<JavaResourceMethod> resourceMethods = CollectionTools.collection(this.getJavaResourceMethods()); - //iterate through all resource methods searching for persistable getters - for (JavaResourceMethod getterMethod : this.getJavaResourceMethods(this.buildPersistablePropertyGetterMethodsFilter())) { - JavaResourceMethod setterMethod = AbstractJavaPersistentType.getValidSiblingSetMethod(getterMethod, resourceMethods); - if (javaResourcePropertyIsVirtual(getterMethod, setterMethod)) { - if (AbstractJavaPersistentType.methodsArePersistableProperties(getterMethod, setterMethod)) { - boolean match = false; - for (Iterator<OrmReadOnlyPersistentAttribute> stream = contextAttributes.iterator(); stream.hasNext();) { - OrmReadOnlyPersistentAttribute contextAttribute = stream.next(); - if (contextAttribute.isFor(getterMethod, setterMethod)) { - match = true; - contextAttribute.update(); - stream.remove(); - break; - } - } - if (!match) { - this.addVirtualAttribute(getVirtualAttributesSize(), this.buildVirtualAttribute(getterMethod, setterMethod)); - } - } - } - resourceMethods.remove(getterMethod); - resourceMethods.remove(setterMethod); - } - this.syncRemainingResourceVirtualMethods(contextAttributes, resourceMethods); - - // remove any leftover context attributes - for (OrmReadOnlyPersistentAttribute contextAttribute : contextAttributes) { - this.removeVirtualAttribute(contextAttribute); - } - } - - private void syncAnnotatedPropertyVirtualAttributes(HashSet<OrmReadOnlyPersistentAttribute> contextAttributes) { - Collection<JavaResourceMethod> resourceMethods = CollectionTools.collection(this.getJavaResourceMethods()); - //iterate through all resource methods searching for persistable getters - for (JavaResourceMethod getterMethod : this.getJavaResourceMethods(buildPersistablePropertyGetterMethodsFilter())) { - JavaResourceMethod setterMethod = AbstractJavaPersistentType.getValidSiblingSetMethod(getterMethod, resourceMethods); - if (javaResourcePropertyIsVirtual(getterMethod, setterMethod)) { - if (getterMethod.isAnnotated() || (setterMethod != null && setterMethod.isAnnotated())) { - boolean match = false; - for (Iterator<OrmReadOnlyPersistentAttribute> stream = contextAttributes.iterator(); stream.hasNext();) { - OrmReadOnlyPersistentAttribute contextAttribute = stream.next(); - if (contextAttribute.isFor(getterMethod, setterMethod)) { - match = true; - contextAttribute.update(); - stream.remove(); - break; - } - } - if (!match) { - this.addVirtualAttribute(getVirtualAttributesSize(), this.buildVirtualAttribute(getterMethod, setterMethod)); - } - } - } - resourceMethods.remove(getterMethod); - resourceMethods.remove(setterMethod); - } - this.syncRemainingResourceVirtualMethods(contextAttributes, resourceMethods); - } - - private void syncFieldVirtualAttributes(HashSet<OrmReadOnlyPersistentAttribute> contextAttributes, Filter<JavaResourceField> filter) { - for (JavaResourceField resourceField : this.getVirtualJavaResourceFields(filter)) { - boolean match = false; - for (Iterator<OrmReadOnlyPersistentAttribute> stream = contextAttributes.iterator(); stream.hasNext(); ) { - OrmReadOnlyPersistentAttribute contextAttribute = stream.next(); - if (contextAttribute.isFor(resourceField)) { - match = true; - contextAttribute.update(); - stream.remove(); - break; - } - } - if (!match) { - // added elements are sync'ed during construction or will be - // updated during the next "update" (which is triggered by - // their addition to the model) - this.addVirtualAttribute(this.getVirtualAttributesSize(), this.buildVirtualAttribute(resourceField)); - } - } - } - - private void syncRemainingResourceVirtualMethods(HashSet<OrmReadOnlyPersistentAttribute> contextAttributes, Collection<JavaResourceMethod> resourceMethods) { - //iterate through remaining resource methods and search for those that are annotated. - //all getter methods will already be used. - for (JavaResourceMethod resourceMethod : resourceMethods) { - if (resourceMethod.isAnnotated()) { - boolean match = false; - //annotated setter(or other random method) with no corresponding getter, bring into context model for validation purposes - for (Iterator<OrmReadOnlyPersistentAttribute> stream = contextAttributes.iterator(); stream.hasNext();) { - OrmReadOnlyPersistentAttribute contextAttribute = stream.next(); - if (contextAttribute.isFor(null, resourceMethod)) { - match = true; - contextAttribute.update(); - stream.remove(); - break; - } - } - if (!match) { - this.addVirtualAttribute(getVirtualAttributesSize(), this.buildVirtualAttribute(null, resourceMethod)); - } - } - } - } - - /** - * Return all the Java resource fields that do not have a - * corresponding <code>orm.xml</code> mapping currently - * specified in the <code>orm.xml</code> persistent type. - */ - protected Iterable<JavaResourceField> getVirtualJavaResourceFields() { - return new FilteringIterable<JavaResourceField>(this.getJavaResourceFields()) { - @Override - protected boolean accept(JavaResourceField javaResourceField) { - return GenericOrmPersistentType.this.javaResourceFieldIsVirtual(javaResourceField); - } - }; - } - - protected Iterable<JavaResourceField> getJavaResourceFields() { - JavaResourceType javaResourceType = this.getJavaResourceType(); - if (javaResourceType == null) { - return EmptyListIterable.instance(); - } - return javaResourceType.getFields(); - } - - protected Iterable<JavaResourceField> getVirtualJavaResourceFields(Filter<JavaResourceField> filter) { - return new FilteringIterable<JavaResourceField>(getVirtualJavaResourceFields(), filter); - } - - protected Iterable<JavaResourceMethod> getJavaResourceMethods(Filter<JavaResourceMethod> filter) { - return new FilteringIterable<JavaResourceMethod>(getJavaResourceMethods(), filter); - } - - protected Iterable<JavaResourceMethod> getJavaResourceMethods() { - JavaResourceType javaResourceType = this.getJavaResourceType(); - if (javaResourceType == null) { - return EmptyListIterable.instance(); - } - return javaResourceType.getMethods(); - } - - public static Filter<JavaResourceField> buildNonTransientNonStaticResourceFieldsFilter() { - return AbstractJavaPersistentType.buildNonTransientNonStaticResourceFieldsFilter(); - } - - protected Filter<JavaResourceMethod> buildPersistablePropertyGetterMethodsFilter() { - return new Filter<JavaResourceMethod>() { - public boolean accept(JavaResourceMethod resourceMethod) { - return AbstractJavaPersistentType.methodIsPersistablePropertyGetter(resourceMethod, getJavaResourceMethods()); - } - }; - } - - protected JavaResourceType getJavaResourceType() { - return (this.javaPersistentType == null) ? null : this.javaPersistentType.getJavaResourceType(); - } - - /** - * Return the access type that determines which Java attributes are to be - * used for the <code>orm.xml</code> type's <em>virtual</em> attributes. - */ - protected AccessType getVirtualJavaAccess() { - if (this.specifiedAccess != null) { - return this.specifiedAccess; - } - if (this.mapping.isMetadataComplete()) { - return this.defaultAccess; - } - AccessType javaAccess = this.javaPersistentType == null ? null : this.javaPersistentType.getSpecifiedAccess(); - return (javaAccess != null) ? javaAccess : this.defaultAccess; - } - - protected boolean javaResourceFieldIsVirtual(JavaResourceField javaResourceField) { - return this.getSpecifiedAttributeFor(javaResourceField) == null; - } - - protected OrmPersistentAttribute getSpecifiedAttributeFor(JavaResourceField javaResourceField) { - return this.getSpecifiedAttributeFor(javaResourceField, null); - } - - /** - * Return the specified attribute corresponding to the specified Java - * resource field, ignoring the specified excluded attribute (since - * there can be more than one specified attribute per Java resource - * attribute; albeit erroneously). - */ - protected OrmPersistentAttribute getSpecifiedAttributeFor(JavaResourceField javaResourceField, OrmPersistentAttribute exclude) { - for (OrmPersistentAttribute ormAttribute : this.getSpecifiedAttributes()) { - if (ormAttribute == exclude) { - continue; // skip - } - if (ormAttribute.isFor(javaResourceField)) { - return ormAttribute; - } - } - return null; - } - - protected boolean javaResourcePropertyIsVirtual(JavaResourceMethod javaResourceGetter, JavaResourceMethod javaResourceSetter) { - return this.getSpecifiedAttributeFor(javaResourceGetter, javaResourceSetter) == null; - } - - protected OrmPersistentAttribute getSpecifiedAttributeFor(JavaResourceMethod javaResourceGetter, JavaResourceMethod javaResourceSetter) { - return this.getSpecifiedAttributeFor(javaResourceGetter, javaResourceSetter, null); - } - - /** - * Return the specified attribute corresponding to the specified Java - * resource field, ignoring the specified excluded attribute (since - * there can be more than one specified attribute per Java resource - * attribute; albeit erroneously). - */ - protected OrmPersistentAttribute getSpecifiedAttributeFor(JavaResourceMethod javaResourceGetter, JavaResourceMethod javaResourceSetter, OrmPersistentAttribute exclude) { - for (OrmPersistentAttribute ormAttribute : this.getSpecifiedAttributes()) { - if (ormAttribute == exclude) { - continue; // skip - } - if (ormAttribute.isFor(javaResourceGetter, javaResourceSetter)) { - return ormAttribute; - } - } - return null; - } - - protected void moveVirtualAttribute(int index, OrmReadOnlyPersistentAttribute virtualAttribute) { - this.moveItemInList(index, virtualAttribute, this.virtualAttributes, VIRTUAL_ATTRIBUTES_LIST); - } - - protected void addVirtualAttribute(int index, OrmReadOnlyPersistentAttribute virtualAttribute) { - this.addItemToList(index, virtualAttribute, this.virtualAttributes, VIRTUAL_ATTRIBUTES_LIST); - } - - protected OrmReadOnlyPersistentAttribute buildVirtualAttribute(JavaResourceField javaResourceField) { - return this.getContextNodeFactory().buildVirtualOrmPersistentField(this, javaResourceField); - } - - protected OrmReadOnlyPersistentAttribute buildVirtualAttribute(JavaResourceMethod javaResourceGetter, JavaResourceMethod javaResourceSetter) { - return this.getContextNodeFactory().buildVirtualOrmPersistentProperty(this, javaResourceGetter, javaResourceSetter); - } - - protected void removeVirtualAttribute(OrmReadOnlyPersistentAttribute virtualAttribute) { - virtualAttribute.dispose(); - this.removeItemFromList(virtualAttribute, this.virtualAttributes, VIRTUAL_ATTRIBUTES_LIST); - } - - - // ********** super persistent type ********** - - public PersistentType getSuperPersistentType() { - return this.superPersistentType; - } - - protected void setSuperPersistentType(PersistentType persistentType) { - PersistentType old = this.superPersistentType; - this.superPersistentType = persistentType; - this.firePropertyChanged(SUPER_PERSISTENT_TYPE_PROPERTY, old, persistentType); - } - - protected PersistentType buildSuperPersistentType() { - PersistentType spt = this.buildSuperPersistentType_(); - if (spt == null) { - return null; - } - // check for circular inheritance - return CollectionTools.contains(spt.getInheritanceHierarchy(), this) ? null : spt; - } - - protected PersistentType buildSuperPersistentType_() { - return (this.javaPersistentType == null) ? null : this.javaPersistentType.getSuperPersistentType(); - } - - - // ********** inheritance ********** - - public Iterable<PersistentType> getInheritanceHierarchy() { - return this.getInheritanceHierarchyOf(this); - } - - public Iterable<PersistentType> getAncestors() { - return this.getInheritanceHierarchyOf(this.superPersistentType); - } - - protected Iterable<PersistentType> getInheritanceHierarchyOf(PersistentType start) { - // using a chain iterable to traverse up the inheritance tree - return new ChainIterable<PersistentType>(start) { - @Override - protected PersistentType nextLink(PersistentType persistentType) { - return persistentType.getSuperPersistentType(); - } - }; - } - - - // ********** declaring type name ********** - - public String getDeclaringTypeName() { - return this.declaringTypeName; - } - - protected void setDeclaringTypeName(String name) { - String old = this.declaringTypeName; - this.declaringTypeName = name; - this.firePropertyChanged(DECLARING_TYPE_NAME_PROPERTY, old, name); - } - - protected String buildDeclaringTypeName() { - return this.isJpa2_0Compatible() ? this.buildDeclaringTypeName_() : null; - } - - protected String buildDeclaringTypeName_() { - return (this.javaPersistentType == null) ? - null : ((JavaPersistentType2_0) this.javaPersistentType).getDeclaringTypeName(); - } - - - // ********** metamodel ********** - - protected MetamodelSourceType.Synchronizer buildMetamodelSynchronizer() { - return this.isJpa2_0Compatible() ? - this.getJpaFactory2_0().buildMetamodelSynchronizer(this) : - null; - } - - public IFile getMetamodelFile() { - return (this.javaPersistentType == null) ? null : this.metamodelSynchronizer.getFile(); - } - - public void initializeMetamodel() { - // do nothing - probably shouldn't be called... - } - - public boolean isManaged() { - return true; - } - - /** - * All <code>orm.xml</code> persistent types must be able to generate a static metamodel - * because 1.0 <code>orm.xml</code> files can be referenced from 2.0 persistence.xml files. - */ - public void synchronizeMetamodel(Map<String, Collection<MetamodelSourceType>> memberTypeTree) { - if (this.javaPersistentType != null) { - this.metamodelSynchronizer.synchronize(memberTypeTree); - } - } - - public void printBodySourceOn(BodySourceWriter pw, Map<String, Collection<MetamodelSourceType>> memberTypeTree) { - if (this.javaPersistentType != null) { - this.metamodelSynchronizer.printBodySourceOn(pw, memberTypeTree); - } - } - - public void disposeMetamodel() { - // do nothing - probably shouldn't be called... - } - - - // ********** JpaStructureNode implementation ********** - - public String getId() { - return OrmStructureNodes.PERSISTENT_TYPE_ID; - } - - public JpaStructureNode getStructureNode(int textOffset) { - for (OrmPersistentAttribute attribute : this.getSpecifiedAttributes()) { - if (attribute.contains(textOffset)) { - return attribute; - } - } - return this; - } - - public TextRange getSelectionTextRange() { - return this.mapping.getSelectionTextRange(); - } - - public void dispose() { - if (this.javaPersistentType != null) { - this.javaPersistentType.dispose(); - } - for (OrmReadOnlyPersistentAttribute virtualAttribute : this.getVirtualAttributes()) { - virtualAttribute.dispose(); - } - } - - - // ********** PersistentType.Owner implementation ********** - - public AccessType getOverridePersistentTypeAccess() { - if (this.specifiedAccess != null) { - return this.specifiedAccess; - } - - if (this.superPersistentType instanceof OrmPersistentType) { - AccessType accessType = ((OrmPersistentType) this.superPersistentType).getSpecifiedAccess(); - if (accessType != null) { - return accessType; - } - } - - if (this.mapping.isMetadataComplete()) { - AccessType accessType = this.getOwnerDefaultAccess(); - if (accessType != null) { - return accessType; - } - } - - // no override access type - return null; - } - - public AccessType getDefaultPersistentTypeAccess() { - if (this.superPersistentType instanceof OrmPersistentType) { - AccessType accessType = ((OrmPersistentType) this.superPersistentType).getDefaultAccess(); - if (accessType != null) { - return accessType; - } - } - - return this.getOwnerDefaultAccess(); - } - - - //*********** refactoring *********** - - public Iterable<DeleteEdit> createDeleteTypeEdits(IType type) { - return this.isFor(type.getFullyQualifiedName('.')) ? - new SingleElementIterable<DeleteEdit>(this.mapping.createDeleteEdit()) : - EmptyIterable.<DeleteEdit>instance(); - } - - @SuppressWarnings("unchecked") - public Iterable<ReplaceEdit> createRenameTypeEdits(IType originalType, String newName) { - return new CompositeIterable<ReplaceEdit>( - this.mapping.createRenameTypeEdits(originalType, newName), - this.createSpecifiedAttributesRenameTypeEdits(originalType, newName) - ); - } - - protected Iterable<ReplaceEdit> createSpecifiedAttributesRenameTypeEdits(final IType originalType, final String newName) { - return new CompositeIterable<ReplaceEdit>( - new TransformationIterable<OrmPersistentAttribute, Iterable<ReplaceEdit>>(this.getSpecifiedAttributes()) { - @Override - protected Iterable<ReplaceEdit> transform(OrmPersistentAttribute persistentAttribute) { - return persistentAttribute.createRenameTypeEdits(originalType, newName); - } - } - ); - } - - @SuppressWarnings("unchecked") - public Iterable<ReplaceEdit> createMoveTypeEdits(IType originalType, IPackageFragment newPackage) { - return new CompositeIterable<ReplaceEdit>( - this.mapping.createMoveTypeEdits(originalType, newPackage), - this.createSpecifiedAttributesMoveTypeEdits(originalType, newPackage) - ); - } - - protected Iterable<ReplaceEdit> createSpecifiedAttributesMoveTypeEdits(final IType originalType, final IPackageFragment newPackage) { - return new CompositeIterable<ReplaceEdit>( - new TransformationIterable<OrmPersistentAttribute, Iterable<ReplaceEdit>>(this.getSpecifiedAttributes()) { - @Override - protected Iterable<ReplaceEdit> transform(OrmPersistentAttribute persistentAttribute) { - return persistentAttribute.createMoveTypeEdits(originalType, newPackage); - } - } - ); - } - - @SuppressWarnings("unchecked") - public Iterable<ReplaceEdit> createRenamePackageEdits(IPackageFragment originalPackage, String newName) { - return new CompositeIterable<ReplaceEdit>( - this.mapping.createRenamePackageEdits(originalPackage, newName), - this.createSpecifiedAttributesRenamePackageEdits(originalPackage, newName) - ); - } - - protected Iterable<ReplaceEdit> createSpecifiedAttributesRenamePackageEdits(final IPackageFragment originalPackage, final String newName) { - return new CompositeIterable<ReplaceEdit>( - new TransformationIterable<OrmPersistentAttribute, Iterable<ReplaceEdit>>(this.getSpecifiedAttributes()) { - @Override - protected Iterable<ReplaceEdit> transform(OrmPersistentAttribute persistentAttribute) { - return persistentAttribute.createRenamePackageEdits(originalPackage, newName); - } - } - ); - } - - - // ********** validation ********** - - @Override - public void validate(List<IMessage> messages, IReporter reporter) { - super.validate(messages, reporter); - this.validateClass(messages); - this.validateMapping(messages, reporter); - this.validateAttributes(messages, reporter); - } - - protected void validateClass(List<IMessage> messages) { - if (this.javaPersistentType == null) { - messages.add( - DefaultJpaValidationMessages.buildMessage( - IMessage.HIGH_SEVERITY, - JpaValidationMessages.PERSISTENT_TYPE_UNRESOLVED_CLASS, - new String[] {this.getName()}, - this, - this.mapping.getClassTextRange() - ) - ); - } - } - - protected void validateMapping(List<IMessage> messages, IReporter reporter) { - try { - this.mapping.validate(messages, reporter); - } catch(Throwable t) { - JptJpaCorePlugin.log(t); - } - } - - protected void validateAttributes(List<IMessage> messages, IReporter reporter) { - for (OrmReadOnlyPersistentAttribute attribute : this.getAttributes()) { - this.validateAttribute(attribute, messages, reporter); - } - } - - protected void validateAttribute(OrmReadOnlyPersistentAttribute attribute, List<IMessage> messages, IReporter reporter) { - try { - attribute.validate(messages, reporter); - } catch(Throwable t) { - JptJpaCorePlugin.log(t); - } - } - - public TextRange getValidationTextRange() { - return this.mapping.getValidationTextRange(); - } - - - // ********** misc ********** - - @Override - public EntityMappings getParent() { - return (EntityMappings) super.getParent(); - } - - protected EntityMappings getEntityMappings() { - return this.getParent(); - } - - public String getDefaultPackage() { - return this.getEntityMappings().getPackage(); - } - - public boolean isFor(String typeName) { - String name = this.getName(); - if (name == null) { - return false; - } - if (name.equals(typeName)) { - return true; - } - String defaultPackage = this.getDefaultPackage(); - if (defaultPackage == null) { - return false; - } - return (defaultPackage + '.' + name).equals(typeName); - } - - public boolean isIn(IPackageFragment packageFragment) { - String packageName = this.getPackageName(); - if (Tools.valuesAreEqual(packageName, packageFragment.getElementName())) { - return true; - } - String defaultPackage = this.getDefaultPackage(); - if (defaultPackage == null) { - return false; - } - packageName = (packageName == null) ? defaultPackage : defaultPackage + '.' + packageName; - return packageName.equals(packageFragment.getElementName()); - } - - protected String getPackageName() { - String className = this.getName(); - if (className == null) { - return null; - } - int lastPeriod = className.lastIndexOf('.'); - return (lastPeriod == -1) ? null : className.substring(0, lastPeriod); - } - - public boolean contains(int textOffset) { - return this.mapping.containsOffset(textOffset); - } - - public PersistentType getOverriddenPersistentType() { - return this.mapping.isMetadataComplete() ? null : this.javaPersistentType; - } - - @Override - public void toString(StringBuilder sb) { - sb.append(this.getName()); + super(parent, xmlTypeMapping); } } diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa2/Generic2_0JpaPlatformFactory.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa2/Generic2_0JpaPlatformFactory.java index f555be49ef..6fa423f14e 100644 --- a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa2/Generic2_0JpaPlatformFactory.java +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa2/Generic2_0JpaPlatformFactory.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2009, 2011 Oracle. All rights reserved. + * Copyright (c) 2009, 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. @@ -9,10 +9,12 @@ ******************************************************************************/ package org.eclipse.jpt.jpa.core.internal.jpa2; +import org.eclipse.jpt.common.core.JptResourceType; import org.eclipse.jpt.jpa.core.JpaFacet; import org.eclipse.jpt.jpa.core.JpaPlatform; import org.eclipse.jpt.jpa.core.JpaPlatformFactory; import org.eclipse.jpt.jpa.core.JpaPlatformVariation; +import org.eclipse.jpt.jpa.core.context.AccessType; import org.eclipse.jpt.jpa.core.internal.GenericJpaPlatform; import org.eclipse.jpt.jpa.core.internal.GenericJpaPlatformFactory.SimpleVersion; import org.eclipse.jpt.jpa.core.internal.JpaAnnotationProvider; @@ -56,6 +58,9 @@ public class Generic2_0JpaPlatformFactory public boolean isJoinTableOverridable() { return true; } + public AccessType[] getSupportedAccessTypes(JptResourceType resourceType) { + return GENERIC_SUPPORTED_ACCESS_TYPES; + } }; } } |