diff options
Diffstat (limited to 'jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java')
57 files changed, 8927 insertions, 0 deletions
diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/AbstractJavaConverter.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/AbstractJavaConverter.java new file mode 100644 index 0000000000..71d9610828 --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/AbstractJavaConverter.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright (c) 2010 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.jpa1.context.java; + +import org.eclipse.jpt.jpa.core.context.java.JavaAttributeMapping; +import org.eclipse.jpt.jpa.core.context.java.JavaConverter; +import org.eclipse.jpt.jpa.core.internal.context.java.AbstractJavaJpaContextNode; +import org.eclipse.jpt.jpa.core.resource.java.Annotation; +import org.eclipse.jpt.jpa.core.resource.java.JavaResourcePersistentAttribute; + +public abstract class AbstractJavaConverter + extends AbstractJavaJpaContextNode + implements JavaConverter +{ + protected AbstractJavaConverter(JavaAttributeMapping parent) { + super(parent); + } + + + // ********** misc ********** + + @Override + public JavaAttributeMapping getParent() { + return (JavaAttributeMapping) super.getParent(); + } + + protected JavaAttributeMapping getAttributeMapping() { + return this.getParent(); + } + + protected JavaResourcePersistentAttribute getResourcePersistentAttribute() { + return this.getAttributeMapping().getResourcePersistentAttribute(); + } + + public Annotation getConverterAnnotation() { + return this.getResourcePersistentAttribute().getAnnotation(this.getAnnotationName()); + } + + public void dispose() { + // NOP + } + + protected abstract String getAnnotationName(); +} diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/AbstractJavaOverrideContainer.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/AbstractJavaOverrideContainer.java new file mode 100644 index 0000000000..860b447bac --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/AbstractJavaOverrideContainer.java @@ -0,0 +1,587 @@ +/******************************************************************************* + * Copyright (c) 2010 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.jpa1.context.java; + +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; +import java.util.Vector; +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jpt.common.core.utility.TextRange; +import org.eclipse.jpt.common.utility.Filter; +import org.eclipse.jpt.common.utility.internal.CollectionTools; +import org.eclipse.jpt.common.utility.internal.iterables.CompositeListIterable; +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.SubIterableWrapper; +import org.eclipse.jpt.common.utility.internal.iterators.EmptyIterator; +import org.eclipse.jpt.common.utility.internal.iterators.FilteringIterator; +import org.eclipse.jpt.jpa.core.context.BaseColumn; +import org.eclipse.jpt.jpa.core.context.Override_; +import org.eclipse.jpt.jpa.core.context.TypeMapping; +import org.eclipse.jpt.jpa.core.context.VirtualOverride; +import org.eclipse.jpt.jpa.core.context.java.JavaJpaContextNode; +import org.eclipse.jpt.jpa.core.context.java.JavaOverride; +import org.eclipse.jpt.jpa.core.context.java.JavaOverrideContainer; +import org.eclipse.jpt.jpa.core.context.java.JavaReadOnlyOverride; +import org.eclipse.jpt.jpa.core.context.java.JavaVirtualOverride; +import org.eclipse.jpt.jpa.core.internal.context.BaseColumnTextRangeResolver; +import org.eclipse.jpt.jpa.core.internal.context.ContextContainerTools; +import org.eclipse.jpt.jpa.core.internal.context.JptValidator; +import org.eclipse.jpt.jpa.core.internal.context.OverrideTextRangeResolver; +import org.eclipse.jpt.jpa.core.internal.context.java.AbstractJavaJpaContextNode; +import org.eclipse.jpt.jpa.core.resource.java.Annotation; +import org.eclipse.jpt.jpa.core.resource.java.JavaResourcePersistentMember; +import org.eclipse.jpt.jpa.core.resource.java.NestableAnnotation; +import org.eclipse.jpt.jpa.core.resource.java.OverrideAnnotation; +import org.eclipse.jpt.jpa.db.Table; +import org.eclipse.wst.validation.internal.provisional.core.IMessage; +import org.eclipse.wst.validation.internal.provisional.core.IReporter; + +/** + * Java override container + * <p> + * <strong>NB:</strong> Although not typical, a Java override container can + * correspond to only a subset of the annotations in the Java source code. + * In that case, the index of a specified override must be translated to its + * corresponding annotation's index before we manipulate the annotations. + * <p> + * As of JPA 2.0, the only place we need these translations is for the attribute + * overrides for an embedded collection. If an embedded collection is a + * {@link java.util.Map Map}, the attribute overrides can override the mappings + * for either the map's keys or the map's values. The names of the overrides for + * the map's keys are prefixed with <code>"key."</code> while the overrides + * for the map's values are prefixed with <code>"value."</code>. + * (Just a bit of hack, courtesy of the JPA spec committee.) + */ +public abstract class AbstractJavaOverrideContainer< + O extends JavaOverrideContainer.Owner, + R extends JavaReadOnlyOverride, + S extends JavaOverride, + V extends JavaVirtualOverride, + A extends OverrideAnnotation + > + extends AbstractJavaJpaContextNode + implements JavaOverrideContainer +{ + // this can be null if the container is "read-only" (i.e. a "null" container) + protected final O owner; + + protected final Vector<S> specifiedOverrides = new Vector<S>(); + protected final SpecifiedOverrideContainerAdapter specifiedOverrideContainerAdapter = new SpecifiedOverrideContainerAdapter(); + + protected final Vector<V> virtualOverrides = new Vector<V>(); + protected final VirtualOverrideContainerAdapter virtualOverrideContainerAdapter = new VirtualOverrideContainerAdapter(); + + + protected AbstractJavaOverrideContainer(JavaJpaContextNode parent, O owner) { + super(parent); + this.owner = owner; + this.initializeSpecifiedOverrides(); + } + + + // ********** synchronize/update ********** + + @Override + public void synchronizeWithResourceModel() { + super.synchronizeWithResourceModel(); + this.syncSpecifiedOverrides(); + // the virtual overrides do not need a sync + } + + @Override + public void update() { + super.update(); + this.updateNodes(this.getSpecifiedOverrides()); + this.updateVirtualOverrides(); + } + + + // ********** overrides ********** + + public ListIterator<R> overrides() { + return this.getOverrides().iterator(); + } + + @SuppressWarnings("unchecked") + protected ListIterable<R> getOverrides() { + return new CompositeListIterable<R>(this.getReadOnlySpecifiedOverrides(), this.getReadOnlyVirtualOverrides()); + } + + public int overridesSize() { + return this.specifiedOverrides.size() + this.virtualOverrides.size(); + } + + public R getOverrideNamed(String name) { + return this.selectOverrideNamed(this.getOverrides(), name); + } + + + // ********** override conversions ********** + + /** + * <em>Silently</em> add the new virtual override before removing the + * specified override, or the <em>update</em> will discover the missing + * virtual override and add it preemptively. + */ + public V convertOverrideToVirtual(Override_ override) { + if (override.isVirtual()) { + throw new IllegalArgumentException("Override is already virtual: " + override); //$NON-NLS-1$ + } + + @SuppressWarnings("unchecked") + S specifiedOverride = (S) override; + int virtualIndex = this.virtualOverrides.size(); + String overrideName = specifiedOverride.getName(); + V virtualOverride = null; + // make sure the specified override actually overrides something before building the virtual override + if (this.overrideWillBeVirtual(overrideName, specifiedOverride)) { + virtualOverride = this.buildVirtualOverride(overrideName); + this.virtualOverrides.add(virtualIndex, virtualOverride); + } + + this.removeSpecifiedOverride(specifiedOverride); // trigger update + + if (virtualOverride != null) { + this.fireItemAdded(VIRTUAL_OVERRIDES_LIST, virtualIndex, virtualOverride); + } + return virtualOverride; + } + + /** + * Return whether the specified override name will be a + * <em>virtual</em> override when the specified specified override is + * removed from the container. The override name must be among the + * valid override names and it must not correspond to any of the + * remaining specified overrides. + */ + protected boolean overrideWillBeVirtual(String overrideName, S specifiedOverrideToBeRemoved) { + return CollectionTools.contains(this.allOverridableNames(), overrideName) && + (this.getSpecifiedOverrideNamed(overrideName, specifiedOverrideToBeRemoved) == null); + } + + /** + * <em>Silently</em> remove the virtual override and add the new specified + * override before naming the specified override, or the <em>update</em> + * will discover the dangling virtual override and remove it preemptively. + */ + public S convertOverrideToSpecified(VirtualOverride override) { + if ( ! override.isVirtual()) { + throw new IllegalArgumentException("Override is already specified: " + override); //$NON-NLS-1$ + } + + @SuppressWarnings("unchecked") + V virtualOverride = (V) override; + int virtualIndex = this.virtualOverrides.indexOf(virtualOverride); + this.virtualOverrides.remove(virtualIndex); + + int specifiedIndex = this.specifiedOverrides.size(); + S specifiedOverride = this.buildSpecifiedOverride(this.buildOverrideAnnotation(specifiedIndex)); + this.specifiedOverrides.add(specifiedIndex, specifiedOverride); + + this.initializeSpecifiedOverride(specifiedOverride, virtualOverride); // trigger update + + this.fireItemRemoved(VIRTUAL_OVERRIDES_LIST, virtualIndex, virtualOverride); + this.fireItemAdded(SPECIFIED_OVERRIDES_LIST, specifiedIndex, specifiedOverride); + return specifiedOverride; + } + + protected abstract void initializeSpecifiedOverride(S specifiedOverride, V virtualOverride); + + + // ********** specified overrides ********** + + public ListIterator<S> specifiedOverrides() { + return this.getSpecifiedOverrides().iterator(); + } + + protected ListIterable<S> getSpecifiedOverrides() { + return new LiveCloneListIterable<S>(this.specifiedOverrides); + } + + @SuppressWarnings("unchecked") + protected ListIterable<R> getReadOnlySpecifiedOverrides() { + // S should always be a subtype of R, but we can't enforce that in the + // class declaration... + return (ListIterable<R>) this.getSpecifiedOverrides(); + } + + public int specifiedOverridesSize() { + return this.specifiedOverrides.size(); + } + + public S getSpecifiedOverride(int index) { + return this.specifiedOverrides.get(index); + } + + public S getSpecifiedOverrideNamed(String name) { + return this.getSpecifiedOverrideNamed(name, null); + } + + @SuppressWarnings("unchecked") + protected S getSpecifiedOverrideNamed(String name, S exclude) { + return (S) this.selectOverrideNamed(this.getReadOnlySpecifiedOverrides(), name, exclude); + } + + protected S addSpecifiedOverride() { + return this.addSpecifiedOverride(this.specifiedOverrides.size()); + } + + protected S addSpecifiedOverride(int index) { + A annotation = this.buildOverrideAnnotation(index); + return this.addSpecifiedOverride_(index, annotation); + } + + @SuppressWarnings("unchecked") + protected A buildOverrideAnnotation(int index) { + int annotationIndex = this.calculateNewAnnotationIndex(index); + return (A) this.getResourcePersistentMember().addAnnotation(annotationIndex, this.getOverrideAnnotationName(), this.getOverrideContainerAnnotationName()); + } + + protected int calculateNewAnnotationIndex(int index) { + // if we are adding to the end of the specified list, + // put the annotation after all the existing annotations + if (index == this.specifiedOverrides.size()) { + return CollectionTools.size(this.getOverrideAnnotations()); + } + + // if we are adding to the front of the specified list, + // put the annotation before of all the existing annotations + if (index == 0) { + return 0; + } + + // if we are adding to the middle of the specified list, + // put the annotation immediately after all the previous override's + // existing annotation + return this.translateToAnnotationIndex(index - 1) + 1; + } + + /** + * pre-condition: override exists at the specified index + */ + protected int translateToAnnotationIndex(int index) { + return CollectionTools.indexOf(this.getOverrideAnnotations(), this.specifiedOverrides.get(index).getOverrideAnnotation()); + } + + protected abstract String getOverrideAnnotationName(); + + protected abstract String getOverrideContainerAnnotationName(); + + protected void removeSpecifiedOverride(S override) { + this.removeSpecifiedOverride(this.specifiedOverrides.indexOf(override)); + } + + protected void removeSpecifiedOverride(int index) { + this.removeOverrideAnnotation(index); + this.removeSpecifiedOverride_(index); + } + + protected void removeOverrideAnnotation(int index) { + int annotationIndex = this.translateToAnnotationIndex(index); + this.getResourcePersistentMember().removeAnnotation(annotationIndex, this.getOverrideAnnotationName(), this.getOverrideContainerAnnotationName()); + } + + protected void removeSpecifiedOverride_(int index) { + this.removeItemFromList(index, this.specifiedOverrides, SPECIFIED_OVERRIDES_LIST); + } + + public void moveSpecifiedOverride(int targetIndex, int sourceIndex) { + this.moveOverrideAnnotation(targetIndex, sourceIndex); + this.moveItemInList(targetIndex, sourceIndex, this.specifiedOverrides, SPECIFIED_OVERRIDES_LIST); + } + + protected void moveOverrideAnnotation(int targetIndex, int sourceIndex) { + int targetAnnotationIndex = this.translateToAnnotationIndex(targetIndex); + int sourceAnnotationIndex = this.translateToAnnotationIndex(sourceIndex); + this.getResourcePersistentMember().moveAnnotation(targetAnnotationIndex, sourceAnnotationIndex, this.getOverrideContainerAnnotationName()); + } + + protected void initializeSpecifiedOverrides() { + for (A annotation : this.getRelevantOverrideAnnotations()) { + this.specifiedOverrides.add(this.buildSpecifiedOverride(annotation)); + } + } + + protected abstract S buildSpecifiedOverride(A overrideAnnotation); + + protected void syncSpecifiedOverrides() { + ContextContainerTools.synchronizeWithResourceModel(this.specifiedOverrideContainerAdapter); + } + + protected Iterable<A> getRelevantOverrideAnnotations() { + return new FilteringIterable<A>(this.getOverrideAnnotations()) { + @Override + protected boolean accept(A annotation) { + String overrideName = annotation.getName(); + return (overrideName != null) && AbstractJavaOverrideContainer.this.owner.isRelevant(overrideName); + } + }; + } + + protected Iterable<A> getOverrideAnnotations() { + return new SubIterableWrapper<NestableAnnotation, A>( + CollectionTools.iterable(this.overrideAnnotations()) + ); + } + + protected Iterator<NestableAnnotation> overrideAnnotations() { + return (this.owner == null) ? EmptyIterator.<NestableAnnotation>instance() : this.overrideAnnotations_(); + } + + /** + * pre-condition: {@link #owner} is not <code>null</code> + */ + protected Iterator<NestableAnnotation> overrideAnnotations_() { + return this.getResourcePersistentMember().annotations(this.getOverrideAnnotationName(), this.getOverrideContainerAnnotationName()); + } + + protected void moveSpecifiedOverride_(int index, S override) { + this.moveItemInList(index, override, this.specifiedOverrides, SPECIFIED_OVERRIDES_LIST); + } + + protected S addSpecifiedOverride_(int index, A overrideAnnotation) { + S override = this.buildSpecifiedOverride(overrideAnnotation); + this.addItemToList(index, override, this.specifiedOverrides, SPECIFIED_OVERRIDES_LIST); + return override; + } + + protected void removeSpecifiedOverride_(S override) { + this.removeSpecifiedOverride_(this.specifiedOverrides.indexOf(override)); + } + + /** + * specified override container adapter + */ + protected class SpecifiedOverrideContainerAdapter + implements ContextContainerTools.Adapter<S, A> + { + public Iterable<S> getContextElements() { + return AbstractJavaOverrideContainer.this.getSpecifiedOverrides(); + } + public Iterable<A> getResourceElements() { + return AbstractJavaOverrideContainer.this.getRelevantOverrideAnnotations(); + } + @SuppressWarnings("unchecked") + public A getResourceElement(S contextElement) { + return (A) contextElement.getOverrideAnnotation(); + } + public void moveContextElement(int index, S element) { + AbstractJavaOverrideContainer.this.moveSpecifiedOverride_(index, element); + } + public void addContextElement(int index, A resourceElement) { + AbstractJavaOverrideContainer.this.addSpecifiedOverride_(index, resourceElement); + } + public void removeContextElement(S element) { + AbstractJavaOverrideContainer.this.removeSpecifiedOverride_(element); + } + } + + + // ********** virtual overrides ********** + + public ListIterator<V> virtualOverrides() { + return this.getVirtualOverrides().iterator(); + } + + protected ListIterable<V> getVirtualOverrides() { + return new LiveCloneListIterable<V>(this.virtualOverrides); + } + + public int virtualOverridesSize() { + return this.virtualOverrides.size(); + } + + @SuppressWarnings("unchecked") + protected ListIterable<R> getReadOnlyVirtualOverrides() { + // V should always be a subtype of R, but we can't enforce that in the + // class declaration... + return (ListIterable<R>) this.getVirtualOverrides(); + } + + protected void updateVirtualOverrides() { + ContextContainerTools.update(this.virtualOverrideContainerAdapter); + } + + /** + * Return the overridable names that are not already in the list of + * specified overrides. + */ + protected Iterable<String> getVirtualOverrideNames() { + return CollectionTools.iterable(this.virtualOverrideNames()); + } + + protected Iterator<String> virtualOverrideNames() { + return new FilteringIterator<String>(this.allOverridableNames()) { + @Override + protected boolean accept(String name) { + return AbstractJavaOverrideContainer.this.overrideIsVirtual(name); + } + }; + } + + protected boolean overrideIsVirtual(String name) { + return this.getSpecifiedOverrideNamed(name) == null; + } + + protected void moveVirtualOverride(int index, V override) { + this.moveItemInList(index, override, this.virtualOverrides, VIRTUAL_OVERRIDES_LIST); + } + + protected V addVirtualOverride(int index, String name) { + V override = this.buildVirtualOverride(name); + this.addItemToList(index, override, this.virtualOverrides, VIRTUAL_OVERRIDES_LIST); + return override; + } + + protected abstract V buildVirtualOverride(String name); + + protected void removeVirtualOverride(V override) { + this.removeItemFromList(override, this.virtualOverrides, VIRTUAL_OVERRIDES_LIST); + } + + /** + * virtual override container adapter + * NB: the context override is matched with a resource override by name + */ + protected class VirtualOverrideContainerAdapter + implements ContextContainerTools.Adapter<V, String> + { + public Iterable<V> getContextElements() { + return AbstractJavaOverrideContainer.this.getVirtualOverrides(); + } + public Iterable<String> getResourceElements() { + return AbstractJavaOverrideContainer.this.getVirtualOverrideNames(); + } + public String getResourceElement(V contextElement) { + return contextElement.getName(); + } + public void moveContextElement(int index, V element) { + AbstractJavaOverrideContainer.this.moveVirtualOverride(index, element); + } + public void addContextElement(int index, String resourceElement) { + AbstractJavaOverrideContainer.this.addVirtualOverride(index, resourceElement); + } + public void removeContextElement(V element) { + AbstractJavaOverrideContainer.this.removeVirtualOverride(element); + } + } + + + // ********** misc ********** + + public TypeMapping getTypeMapping() { + return this.owner.getTypeMapping(); + } + + protected JavaResourcePersistentMember getResourcePersistentMember() { + return this.owner.getResourcePersistentMember(); + } + + public TypeMapping getOverridableTypeMapping() { + return this.owner.getOverridableTypeMapping(); + } + + public Iterator<String> allOverridableNames() { + return (this.owner != null) ? this.owner.allOverridableNames() : EmptyIterator.<String>instance(); + } + + public boolean tableNameIsInvalid(String tableName) { + return this.owner.tableNameIsInvalid(tableName); + } + + public Iterator<String> candidateTableNames() { + return this.owner.candidateTableNames(); + } + + public Table resolveDbTable(String tableName) { + return this.owner.resolveDbTable(tableName); + } + + public String getDefaultTableName() { + return this.owner.getDefaultTableName(); + } + + public JptValidator buildValidator(Override_ override, OverrideTextRangeResolver textRangeResolver) { + return this.owner.buildValidator(override, this, textRangeResolver); + } + + public JptValidator buildColumnValidator(Override_ override, BaseColumn column, BaseColumn.Owner columnOwner, BaseColumnTextRangeResolver textRangeResolver) { + return this.owner.buildColumnValidator(override, column, columnOwner, textRangeResolver); + } + + public String getPossiblePrefix() { + return this.owner.getPossiblePrefix(); + } + + public String getWritePrefix() { + return this.owner.getWritePrefix(); + } + + protected R selectOverrideNamed(Iterable<R> overrides, String name) { + return this.selectOverrideNamed(overrides, name, null); + } + + protected R selectOverrideNamed(Iterable<R> overrides, String name, S exclude) { + for (R override : overrides) { + if (override == exclude) { + continue; // skip + } + if (this.valuesAreEqual(override.getName(), name)) { + return override; + } + } + return null; + } + + + // ********** code completion ********** + + @Override + public Iterator<String> javaCompletionProposals(int pos, Filter<String> filter, CompilationUnit astRoot) { + Iterator<String> result = super.javaCompletionProposals(pos, filter, astRoot); + if (result != null) { + return result; + } + for (R override : this.getOverrides()) { + result = override.javaCompletionProposals(pos, filter, astRoot); + if (result != null) { + return result; + } + } + return null; + } + + + // ********** validation ********** + + @Override + public void validate(List<IMessage> messages, IReporter reporter, CompilationUnit astRoot) { + super.validate(messages, reporter, astRoot); + for (R override: this.getOverrides()) { + override.validate(messages, reporter, astRoot); + } + } + + public TextRange getValidationTextRange(CompilationUnit astRoot) { + Annotation annotation = this.getValidationAnnotation(); + return (annotation != null) ? + annotation.getTextRange(astRoot) : + this.owner.getValidationTextRange(astRoot); + } + + protected Annotation getValidationAnnotation() { + JavaResourcePersistentMember resourceMember = this.getResourcePersistentMember(); + Annotation annotation = resourceMember.getAnnotation(this.getOverrideContainerAnnotationName()); + return (annotation != null) ? annotation : resourceMember.getAnnotation(this.getOverrideAnnotationName()); + } +} diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJarFile.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJarFile.java new file mode 100644 index 0000000000..16298f2d59 --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJarFile.java @@ -0,0 +1,238 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 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.jpa1.context.java; + +import java.util.Iterator; +import java.util.List; +import java.util.Vector; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IResource; +import org.eclipse.jpt.common.core.JptCommonCorePlugin; +import org.eclipse.jpt.common.core.JptResourceType; +import org.eclipse.jpt.common.core.utility.TextRange; +import org.eclipse.jpt.common.utility.internal.CollectionTools; +import org.eclipse.jpt.common.utility.internal.iterables.LiveCloneIterable; +import org.eclipse.jpt.jpa.core.JpaStructureNode; +import org.eclipse.jpt.jpa.core.context.AccessType; +import org.eclipse.jpt.jpa.core.context.PersistentType; +import org.eclipse.jpt.jpa.core.context.java.JarFile; +import org.eclipse.jpt.jpa.core.context.java.JavaPersistentType; +import org.eclipse.jpt.jpa.core.context.persistence.JarFileRef; +import org.eclipse.jpt.jpa.core.internal.context.ContextContainerTools; +import org.eclipse.jpt.jpa.core.internal.context.persistence.AbstractPersistenceXmlContextNode; +import org.eclipse.jpt.jpa.core.resource.java.JavaResourcePackageFragmentRoot; +import org.eclipse.jpt.jpa.core.resource.java.JavaResourcePersistentType; +import org.eclipse.wst.validation.internal.provisional.core.IMessage; +import org.eclipse.wst.validation.internal.provisional.core.IReporter; + +/** + * Context JAR file + */ +public class GenericJarFile + extends AbstractPersistenceXmlContextNode + implements JarFile, PersistentType.Owner +{ + protected final JavaResourcePackageFragmentRoot jarResourcePackageFragmentRoot; + + protected final Vector<JavaPersistentType> javaPersistentTypes = new Vector<JavaPersistentType>(); + protected final JavaPersistentTypeContainerAdapter javaPersistentTypeContainerAdapter = new JavaPersistentTypeContainerAdapter(); + + + // ********** constructor/initialization ********** + + public GenericJarFile(JarFileRef parent, JavaResourcePackageFragmentRoot jarResourcePackageFragmentRoot) { + super(parent); + this.jarResourcePackageFragmentRoot = jarResourcePackageFragmentRoot; + this.initializeJavaPersistentTypes(); + } + + + // ********** synchronize/update ********** + + @Override + public void synchronizeWithResourceModel() { + super.synchronizeWithResourceModel(); + this.syncJavaPersistentTypes(); + } + + @Override + public void update() { + super.update(); + this.updateNodes(this.getJavaPersistentTypes()); + } + + public JavaResourcePackageFragmentRoot getJarResourcePackageFragmentRoot() { + return this.jarResourcePackageFragmentRoot; + } + + + // ********** JpaStructureNode implementation ********** + + public String getId() { + return null; + } + + public TextRange getSelectionTextRange() { + return null; + } + + public JpaStructureNode getStructureNode(int textOffset) { + return null; + } + + public void dispose() { + // nothing yet + } + + + // ********** JpaContextNode implementation ********** + + @Override + public JptResourceType getResourceType() { + return JptCommonCorePlugin.JAR_RESOURCE_TYPE; + } + + + // ********** Java persistent types ********** + + public JavaPersistentType getPersistentType(String typeName) { + for (JavaPersistentType pt : this.getJavaPersistentTypes()) { + if (pt.getName().equals(typeName)) { + return pt; + } + } + return null; + } + + public Iterator<JavaPersistentType> javaPersistentTypes() { + return this.getJavaPersistentTypes().iterator(); + } + + protected Iterable<JavaPersistentType> getJavaPersistentTypes() { + return new LiveCloneIterable<JavaPersistentType>(this.javaPersistentTypes); + } + + public int javaPersistentTypesSize() { + return this.javaPersistentTypes.size(); + } + + protected void initializeJavaPersistentTypes() { + for (JavaResourcePersistentType jrpt : this.getJavaResourcePersistentTypes()) { + this.javaPersistentTypes.add(this.buildJavaPersistentType(jrpt)); + } + } + + protected void syncJavaPersistentTypes() { + ContextContainerTools.synchronizeWithResourceModel(this.javaPersistentTypeContainerAdapter); + } + + protected void addJavaPersistentType(JavaResourcePersistentType jrpt) { + JavaPersistentType javaPersistentType = this.buildJavaPersistentType(jrpt); + this.addItemToCollection(javaPersistentType, this.javaPersistentTypes, JAVA_PERSISTENT_TYPES_COLLECTION); + } + + protected void removeJavaPersistentType(JavaPersistentType javaPersistentType ) { + this.removeItemFromCollection(javaPersistentType, this.javaPersistentTypes, JAVA_PERSISTENT_TYPES_COLLECTION); + } + + /** + * the resource JAR holds only annotated types, so we can use them all for + * building the context types + */ + protected Iterable<JavaResourcePersistentType> getJavaResourcePersistentTypes() { + return CollectionTools.iterable(this.jarResourcePackageFragmentRoot.persistentTypes()); + } + + protected JavaPersistentType buildJavaPersistentType(JavaResourcePersistentType jrpt) { + return this.getJpaFactory().buildJavaPersistentType(this, jrpt); + } + + /** + * Java persistent type container adapter + */ + protected class JavaPersistentTypeContainerAdapter + implements ContextContainerTools.Adapter<JavaPersistentType, JavaResourcePersistentType> + { + public Iterable<JavaPersistentType> getContextElements() { + return GenericJarFile.this.getJavaPersistentTypes(); + } + public Iterable<JavaResourcePersistentType> getResourceElements() { + return GenericJarFile.this.getJavaResourcePersistentTypes(); + } + public JavaResourcePersistentType getResourceElement(JavaPersistentType contextElement) { + return contextElement.getResourcePersistentType(); + } + public void moveContextElement(int index, JavaPersistentType element) { + // ignore moves - we don't care about the order of the Java persistent types + } + public void addContextElement(int index, JavaResourcePersistentType resourceElement) { + // ignore the index - we don't care about the order of the Java persistent types + GenericJarFile.this.addJavaPersistentType(resourceElement); + } + public void removeContextElement(JavaPersistentType element) { + GenericJarFile.this.removeJavaPersistentType(element); + } + } + + + // ********** PersistentTypeContainer implementation ********** + + public Iterable<? extends PersistentType> getPersistentTypes() { + return this.getJavaPersistentTypes(); + } + + + // ********** PersistentType.Owner implementation ********** + + public AccessType getDefaultPersistentTypeAccess() { + return this.getPersistenceUnit().getDefaultAccess(); + } + + public AccessType getOverridePersistentTypeAccess() { + // no access type at this level overrides any local access type specification + return null; + } + + + // ********** JpaNode implementation ********** + + @Override + public JarFileRef getParent() { + return (JarFileRef) super.getParent(); + } + + protected JarFileRef getJarFileRef() { + return this.getParent(); + } + + @Override + public IResource getResource() { + return this.jarResourcePackageFragmentRoot.getFile(); + } + + + // ********** validation ********** + + @Override + public void validate(List<IMessage> messages, IReporter reporter) { + super.validate(messages, reporter); + // TODO validate 'javaPersistentTypes' + } + + public boolean isIn(org.eclipse.core.resources.IFolder folder) { + IResource member = folder.findMember(this.jarResourcePackageFragmentRoot.getFile().getName()); + IFile file = this.jarResourcePackageFragmentRoot.getFile(); + return member != null && file != null && member.equals(file); + } + + public TextRange getValidationTextRange() { + return this.getJarFileRef().getValidationTextRange(); + } +} diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaAssociationOverride.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaAssociationOverride.java new file mode 100644 index 0000000000..ebcec5ef3e --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaAssociationOverride.java @@ -0,0 +1,122 @@ +/******************************************************************************* + * Copyright (c) 2008, 2011 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.jpa1.context.java; + +import java.util.Iterator; +import java.util.List; +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jpt.common.utility.Filter; +import org.eclipse.jpt.jpa.core.context.ReadOnlyAssociationOverride; +import org.eclipse.jpt.jpa.core.context.RelationshipMapping; +import org.eclipse.jpt.jpa.core.context.java.JavaAssociationOverride; +import org.eclipse.jpt.jpa.core.context.java.JavaAssociationOverrideContainer; +import org.eclipse.jpt.jpa.core.context.java.JavaOverrideRelationship; +import org.eclipse.jpt.jpa.core.context.java.JavaVirtualAssociationOverride; +import org.eclipse.jpt.jpa.core.internal.context.java.AbstractJavaOverride; +import org.eclipse.jpt.jpa.core.resource.java.AssociationOverrideAnnotation; +import org.eclipse.wst.validation.internal.provisional.core.IMessage; +import org.eclipse.wst.validation.internal.provisional.core.IReporter; + +/** + * Specified Java association override + */ +public class GenericJavaAssociationOverride + extends AbstractJavaOverride<JavaAssociationOverrideContainer, AssociationOverrideAnnotation> + implements JavaAssociationOverride +{ + protected final JavaOverrideRelationship relationship; + + + public GenericJavaAssociationOverride(JavaAssociationOverrideContainer parent, AssociationOverrideAnnotation annotation) { + super(parent, annotation); + this.relationship = this.buildRelationship(); + } + + + // ********** synchronize/update ********** + + @Override + public void synchronizeWithResourceModel() { + super.synchronizeWithResourceModel(); + this.relationship.synchronizeWithResourceModel(); + } + + @Override + public void update() { + super.update(); + this.relationship.update(); + } + + + // ********** specified/virtual ********** + + @Override + public JavaVirtualAssociationOverride convertToVirtual() { + return (JavaVirtualAssociationOverride) super.convertToVirtual(); + } + + + // ********** relationship ********** + + public JavaOverrideRelationship getRelationship() { + return this.relationship; + } + + protected JavaOverrideRelationship buildRelationship() { + return this.getJpaFactory().buildJavaOverrideRelationship(this); + } + + + // ********** misc ********** + + public RelationshipMapping getMapping() { + return this.getContainer().getRelationshipMapping(this.name); + } + + public void initializeFrom(ReadOnlyAssociationOverride oldOverride) { + super.initializeFrom(oldOverride); + this.relationship.initializeFrom(oldOverride.getRelationship()); + } + + public void initializeFromVirtual(ReadOnlyAssociationOverride virtualOverride) { + super.initializeFromVirtual(virtualOverride); + this.relationship.initializeFromVirtual(virtualOverride.getRelationship()); + } + + + // ********** Java completion proposals ********** + + @Override + public Iterator<String> javaCompletionProposals(int pos, Filter<String> filter, CompilationUnit astRoot) { + Iterator<String> result = super.javaCompletionProposals(pos, filter, astRoot); + if (result != null) { + return result; + } + result = this.relationship.javaCompletionProposals(pos, filter, astRoot); + if (result != null) { + return result; + } + return null; + } + + @Override + protected Iterator<String> candidateNames() { + return this.getContainer().allOverridableNames(); + } + + + // ********** validation ********** + + @Override + public void validate(List<IMessage> messages, IReporter reporter, CompilationUnit astRoot) { + super.validate(messages, reporter, astRoot); + this.relationship.validate(messages, reporter, astRoot); + } +} diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaAssociationOverrideContainer.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaAssociationOverrideContainer.java new file mode 100644 index 0000000000..4d672822da --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaAssociationOverrideContainer.java @@ -0,0 +1,91 @@ +/******************************************************************************* + * Copyright (c) 2010, 2011 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.jpa1.context.java; + +import org.eclipse.jpt.jpa.core.context.AssociationOverride; +import org.eclipse.jpt.jpa.core.context.JoinColumn; +import org.eclipse.jpt.jpa.core.context.Relationship; +import org.eclipse.jpt.jpa.core.context.RelationshipMapping; +import org.eclipse.jpt.jpa.core.context.Table; +import org.eclipse.jpt.jpa.core.context.java.JavaAssociationOverride; +import org.eclipse.jpt.jpa.core.context.java.JavaAssociationOverrideContainer; +import org.eclipse.jpt.jpa.core.context.java.JavaJpaContextNode; +import org.eclipse.jpt.jpa.core.context.java.JavaReadOnlyAssociationOverride; +import org.eclipse.jpt.jpa.core.context.java.JavaVirtualAssociationOverride; +import org.eclipse.jpt.jpa.core.internal.context.JoinColumnTextRangeResolver; +import org.eclipse.jpt.jpa.core.internal.context.JptValidator; +import org.eclipse.jpt.jpa.core.internal.context.MappingTools; +import org.eclipse.jpt.jpa.core.internal.context.TableTextRangeResolver; +import org.eclipse.jpt.jpa.core.resource.java.AssociationOverrideAnnotation; +import org.eclipse.jpt.jpa.core.resource.java.AssociationOverridesAnnotation; + +/** + * Java attribute override container + */ +public class GenericJavaAssociationOverrideContainer + extends AbstractJavaOverrideContainer< + JavaAssociationOverrideContainer.Owner, + JavaReadOnlyAssociationOverride, + JavaAssociationOverride, + JavaVirtualAssociationOverride, + AssociationOverrideAnnotation + > + implements JavaAssociationOverrideContainer +{ + public GenericJavaAssociationOverrideContainer(JavaJpaContextNode parent, JavaAssociationOverrideContainer.Owner owner) { + super(parent, owner); + } + + + public RelationshipMapping getRelationshipMapping(String attributeName) { + return MappingTools.getRelationshipMapping(attributeName, this.owner.getOverridableTypeMapping()); + } + + public Relationship resolveOverriddenRelationship(String associationOverrideName) { + return this.owner.resolveOverriddenRelationship(associationOverrideName); + } + + public JptValidator buildJoinTableJoinColumnValidator(AssociationOverride override, JoinColumn column, org.eclipse.jpt.jpa.core.context.JoinColumn.Owner owner, JoinColumnTextRangeResolver textRangeResolver) { + return this.owner.buildJoinTableJoinColumnValidator(override, column, owner, textRangeResolver); + } + + public JptValidator buildJoinTableInverseJoinColumnValidator(AssociationOverride override, JoinColumn column, org.eclipse.jpt.jpa.core.context.JoinColumn.Owner owner, JoinColumnTextRangeResolver textRangeResolver) { + return this.owner.buildJoinTableInverseJoinColumnValidator(override, column, owner, textRangeResolver); + } + + public JptValidator buildTableValidator(AssociationOverride override, Table table, TableTextRangeResolver textRangeResolver) { + return this.owner.buildTableValidator(override, table, textRangeResolver); + } + + @Override + protected String getOverrideAnnotationName() { + return AssociationOverrideAnnotation.ANNOTATION_NAME; + } + + @Override + protected String getOverrideContainerAnnotationName() { + return AssociationOverridesAnnotation.ANNOTATION_NAME; + } + + @Override + protected JavaAssociationOverride buildSpecifiedOverride(AssociationOverrideAnnotation overrideAnnotation) { + return this.getJpaFactory().buildJavaAssociationOverride(this, overrideAnnotation); + } + + @Override + protected void initializeSpecifiedOverride(JavaAssociationOverride specifiedOverride, JavaVirtualAssociationOverride virtualOverride) { + specifiedOverride.initializeFromVirtual(virtualOverride); + } + + @Override + protected JavaVirtualAssociationOverride buildVirtualOverride(String name) { + return this.getJpaFactory().buildJavaVirtualAssociationOverride(this, name); + } +} diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaAttributeOverride.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaAttributeOverride.java new file mode 100644 index 0000000000..dda23b1611 --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaAttributeOverride.java @@ -0,0 +1,218 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 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.jpa1.context.java; + +import java.util.Iterator; +import java.util.List; +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jpt.common.utility.Filter; +import org.eclipse.jpt.common.utility.internal.CollectionTools; +import org.eclipse.jpt.jpa.core.context.BaseColumn; +import org.eclipse.jpt.jpa.core.context.NamedColumn; +import org.eclipse.jpt.jpa.core.context.ReadOnlyAttributeOverride; +import org.eclipse.jpt.jpa.core.context.TypeMapping; +import org.eclipse.jpt.jpa.core.context.java.JavaAttributeOverride; +import org.eclipse.jpt.jpa.core.context.java.JavaAttributeOverrideContainer; +import org.eclipse.jpt.jpa.core.context.java.JavaColumn; +import org.eclipse.jpt.jpa.core.context.java.JavaVirtualAttributeOverride; +import org.eclipse.jpt.jpa.core.internal.context.BaseColumnTextRangeResolver; +import org.eclipse.jpt.jpa.core.internal.context.JptValidator; +import org.eclipse.jpt.jpa.core.internal.context.NamedColumnTextRangeResolver; +import org.eclipse.jpt.jpa.core.internal.context.TypeMappingTools; +import org.eclipse.jpt.jpa.core.internal.context.java.AbstractJavaOverride; +import org.eclipse.jpt.jpa.core.internal.validation.DefaultJpaValidationMessages; +import org.eclipse.jpt.jpa.core.internal.validation.JpaValidationMessages; +import org.eclipse.jpt.jpa.core.resource.java.AttributeOverrideAnnotation; +import org.eclipse.jpt.jpa.core.resource.java.CompleteColumnAnnotation; +import org.eclipse.jpt.jpa.db.Table; +import org.eclipse.wst.validation.internal.provisional.core.IMessage; +import org.eclipse.wst.validation.internal.provisional.core.IReporter; + +/** + * Specified Java attribute override + */ +public class GenericJavaAttributeOverride + extends AbstractJavaOverride<JavaAttributeOverrideContainer, AttributeOverrideAnnotation> + implements JavaAttributeOverride, JavaColumn.Owner +{ + protected final JavaColumn column; + + + public GenericJavaAttributeOverride(JavaAttributeOverrideContainer parent, AttributeOverrideAnnotation annotation) { + super(parent, annotation); + this.column = this.buildColumn(); + } + + + // ********** synchronize/update ********** + + @Override + public void synchronizeWithResourceModel() { + super.synchronizeWithResourceModel(); + this.column.synchronizeWithResourceModel(); + } + + @Override + public void update() { + super.update(); + this.column.update(); + } + + + // ********** specified/virtual ********** + + @Override + public JavaVirtualAttributeOverride convertToVirtual() { + return (JavaVirtualAttributeOverride) super.convertToVirtual(); + } + + + // ********** column ********** + + public JavaColumn getColumn() { + return this.column; + } + + protected JavaColumn buildColumn() { + return this.getJpaFactory().buildJavaColumn(this, this); + } + + + // ********** misc ********** + + public void initializeFrom(ReadOnlyAttributeOverride oldOverride) { + super.initializeFrom(oldOverride); + this.column.initializeFrom(oldOverride.getColumn()); + } + + public void initializeFromVirtual(ReadOnlyAttributeOverride oldOverride) { + super.initializeFromVirtual(oldOverride); + this.column.initializeFromVirtual(oldOverride.getColumn()); + } + + + // ********** column owner implementation ********** + + public TypeMapping getTypeMapping() { + return this.getContainer().getTypeMapping(); + } + + public String getDefaultTableName() { + return this.getContainer().getDefaultTableName(); + } + + public Table resolveDbTable(String tableName) { + return this.getContainer().resolveDbTable(tableName); + } + + public String getDefaultColumnName() { + return this.name; + } + + public JptValidator buildColumnValidator(NamedColumn column, NamedColumnTextRangeResolver textRangeResolver) { + return this.getContainer().buildColumnValidator(this, (BaseColumn) column, this, (BaseColumnTextRangeResolver) textRangeResolver); + } + + public boolean tableNameIsInvalid(String tableName) { + return this.getContainer().tableNameIsInvalid(tableName); + } + + public Iterator<String> candidateTableNames() { + return this.getContainer().candidateTableNames(); + } + + public CompleteColumnAnnotation getColumnAnnotation() { + return this.getOverrideAnnotation().getNonNullColumn(); + } + + public void removeColumnAnnotation() { + this.getOverrideAnnotation().removeColumn(); + } + + + // ********** mapped by relationship ********** + + protected boolean isMappedByRelationship() { + return CollectionTools.contains(this.getMappedByRelationshipAttributeNames(), this.buildQualifier()); + } + + protected Iterable<String> getMappedByRelationshipAttributeNames() { + return TypeMappingTools.getMappedByRelationshipAttributeNames(this.getTypeMapping()); + } + + /** + * overridable names are (usually?) qualified with a container mapping, + * which may also be the one mapped by a relationship + */ + protected String buildQualifier() { + if (this.name == null) { + return null; + } + int index = this.name.indexOf('.'); + return (index == -1) ? this.name : this.name.substring(0, index); + } + + + // ********** Java completion proposals ********** + + @Override + public Iterator<String> javaCompletionProposals(int pos, Filter<String> filter, CompilationUnit astRoot) { + Iterator<String> result = super.javaCompletionProposals(pos, filter, astRoot); + if (result != null) { + return result; + } + result = this.column.javaCompletionProposals(pos, filter, astRoot); + if (result != null) { + return result; + } + return null; + } + + @Override + protected Iterator<String> candidateNames() { + return this.getContainer().allOverridableNames(); + } + + + // ********** validation ********** + + @Override + public void validate(List<IMessage> messages, IReporter reporter, CompilationUnit astRoot) { + super.validate(messages, reporter, astRoot); + + // [JPA 2.0] if the column is specified, or if the override is not mapped by a relationship, + // then the column is validated. + // (In JPA 1.0, the column will always be validated, since the override is never mapped by a + // relationship) + if (this.columnAnnotationIsSpecified() || ! this.isMappedByRelationship()) { + this.column.validate(messages, reporter, astRoot); + } + + // [JPA 2.0] if the override is mapped by a relationship, then that actually is in itself + // a validation error + // (We prevent implied overrides that are mapped by a relationship ... hopefully) + // (In JPA 1.0, this will never occur) + if (this.isMappedByRelationship()) { + messages.add( + DefaultJpaValidationMessages.buildMessage( + IMessage.HIGH_SEVERITY, + JpaValidationMessages.ATTRIBUTE_OVERRIDE_MAPPED_BY_RELATIONSHIP_AND_SPECIFIED, + EMPTY_STRING_ARRAY, + this, + this.getValidationTextRange(astRoot) + ) + ); + } + } + + protected boolean columnAnnotationIsSpecified() { + return this.getOverrideAnnotation().getColumn() != null; + } +} diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaAttributeOverrideContainer.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaAttributeOverrideContainer.java new file mode 100644 index 0000000000..26be7c2ef8 --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaAttributeOverrideContainer.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 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.jpa1.context.java; + +import org.eclipse.jpt.jpa.core.context.Column; +import org.eclipse.jpt.jpa.core.context.java.JavaAttributeOverride; +import org.eclipse.jpt.jpa.core.context.java.JavaAttributeOverrideContainer; +import org.eclipse.jpt.jpa.core.context.java.JavaJpaContextNode; +import org.eclipse.jpt.jpa.core.context.java.JavaReadOnlyAttributeOverride; +import org.eclipse.jpt.jpa.core.context.java.JavaVirtualAttributeOverride; +import org.eclipse.jpt.jpa.core.resource.java.AttributeOverrideAnnotation; +import org.eclipse.jpt.jpa.core.resource.java.AttributeOverridesAnnotation; + +/** + * Java attribute override container + */ +public class GenericJavaAttributeOverrideContainer + extends AbstractJavaOverrideContainer< + JavaAttributeOverrideContainer.Owner, + JavaReadOnlyAttributeOverride, + JavaAttributeOverride, + JavaVirtualAttributeOverride, + AttributeOverrideAnnotation + > + implements JavaAttributeOverrideContainer +{ + public GenericJavaAttributeOverrideContainer(JavaJpaContextNode parent, JavaAttributeOverrideContainer.Owner owner) { + super(parent, owner); + } + + + public Column resolveOverriddenColumn(String attributeName) { + return (attributeName == null) ? null : this.owner.resolveOverriddenColumn(attributeName); + } + + @Override + protected String getOverrideAnnotationName() { + return AttributeOverrideAnnotation.ANNOTATION_NAME; + } + + @Override + protected String getOverrideContainerAnnotationName() { + return AttributeOverridesAnnotation.ANNOTATION_NAME; + } + + @Override + protected JavaAttributeOverride buildSpecifiedOverride(AttributeOverrideAnnotation overrideAnnotation) { + return this.getJpaFactory().buildJavaAttributeOverride(this, overrideAnnotation); + } + + @Override + protected void initializeSpecifiedOverride(JavaAttributeOverride specifiedOverride, JavaVirtualAttributeOverride virtualOverride) { + specifiedOverride.initializeFromVirtual(virtualOverride); + } + + @Override + protected JavaVirtualAttributeOverride buildVirtualOverride(String name) { + return this.getJpaFactory().buildJavaVirtualAttributeOverride(this, name); + } +} diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaBasicMapping.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaBasicMapping.java new file mode 100644 index 0000000000..fc88aeed80 --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaBasicMapping.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright (c) 2006, 2010 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.jpa1.context.java; + +import org.eclipse.jpt.jpa.core.context.java.JavaPersistentAttribute; +import org.eclipse.jpt.jpa.core.internal.context.java.AbstractJavaBasicMapping; + +public class GenericJavaBasicMapping + extends AbstractJavaBasicMapping +{ + public GenericJavaBasicMapping(JavaPersistentAttribute parent) { + super(parent); + } +} diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaCascade.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaCascade.java new file mode 100644 index 0000000000..321792eaf2 --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaCascade.java @@ -0,0 +1,255 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 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.jpa1.context.java; + +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jpt.common.core.utility.TextRange; +import org.eclipse.jpt.jpa.core.context.java.JavaRelationshipMapping; +import org.eclipse.jpt.jpa.core.internal.context.java.AbstractJavaJpaContextNode; +import org.eclipse.jpt.jpa.core.internal.context.java.AbstractJavaRelationshipMapping; +import org.eclipse.jpt.jpa.core.jpa2.context.java.JavaCascade2_0; +import org.eclipse.jpt.jpa.core.jpa2.resource.java.RelationshipMapping2_0Annotation; +import org.eclipse.jpt.jpa.core.resource.java.RelationshipMappingAnnotation; + +public class GenericJavaCascade + extends AbstractJavaJpaContextNode + implements JavaCascade2_0 +{ + protected boolean all; + + protected boolean persist; + + protected boolean merge; + + protected boolean remove; + + protected boolean refresh; + + /* JPA 2.0 */ + protected boolean detach; + + + /** + * This is built directly by the mapping implementation; as opposed to via + * a platform-specific factory. + * @see AbstractJavaRelationshipMapping#buildCascade() + */ + public GenericJavaCascade(JavaRelationshipMapping parent) { + super(parent); + this.all = this.buildAll(); + this.persist = this.buildPersist(); + this.merge = this.buildMerge(); + this.remove = this.buildRemove(); + this.refresh = this.buildRefresh(); + this.detach = this.buildDetach(); + } + + + // ********** synchronize/update ********** + + @Override + public void synchronizeWithResourceModel() { + super.synchronizeWithResourceModel(); + this.setAll_(this.buildAll()); + this.setPersist_(this.buildPersist()); + this.setMerge_(this.buildMerge()); + this.setRemove_(this.buildRemove()); + this.setRefresh_(this.buildRefresh()); + this.setDetach_(this.buildDetach()); + } + + + // ********** all ********** + + public boolean isAll() { + return this.all; + } + + public void setAll(boolean all) { + if (all != this.all) { + this.getMappingAnnotationForUpdate().setCascadeAll(all); + this.setAll_(all); + } + } + + protected void setAll_(boolean all) { + boolean old = this.all; + this.all = all; + this.firePropertyChanged(ALL_PROPERTY, old, all); + } + + protected boolean buildAll() { + RelationshipMappingAnnotation annotation = this.getMappingAnnotation(); + return (annotation != null) && annotation.isCascadeAll(); + } + + + // ********** persist ********** + + public boolean isPersist() { + return this.persist; + } + + public void setPersist(boolean persist) { + if (persist != this.persist) { + this.getMappingAnnotationForUpdate().setCascadePersist(persist); + this.setPersist_(persist); + } + } + + protected void setPersist_(boolean persist) { + boolean old = this.persist; + this.persist = persist; + this.firePropertyChanged(PERSIST_PROPERTY, old, persist); + } + + protected boolean buildPersist() { + RelationshipMappingAnnotation annotation = this.getMappingAnnotation(); + return (annotation != null) && annotation.isCascadePersist(); + } + + + // ********** merge ********** + + public boolean isMerge() { + return this.merge; + } + + public void setMerge(boolean merge) { + if (merge != this.merge) { + this.getMappingAnnotationForUpdate().setCascadeMerge(merge); + this.setMerge_(merge); + } + } + + protected void setMerge_(boolean merge) { + boolean old = this.merge; + this.merge = merge; + this.firePropertyChanged(MERGE_PROPERTY, old, merge); + } + + protected boolean buildMerge() { + RelationshipMappingAnnotation annotation = this.getMappingAnnotation(); + return (annotation != null) && annotation.isCascadeMerge(); + } + + + // ********** remove ********** + + public boolean isRemove() { + return this.remove; + } + + public void setRemove(boolean remove) { + if (remove != this.remove) { + this.getMappingAnnotationForUpdate().setCascadeRemove(remove); + this.setRemove_(remove); + } + } + + protected void setRemove_(boolean remove) { + boolean oldRemove = this.remove; + this.remove = remove; + this.firePropertyChanged(REMOVE_PROPERTY, oldRemove, remove); + } + + protected boolean buildRemove() { + RelationshipMappingAnnotation annotation = this.getMappingAnnotation(); + return (annotation != null) && annotation.isCascadeRemove(); + } + + + // ********** refresh ********** + + public boolean isRefresh() { + return this.refresh; + } + + public void setRefresh(boolean refresh) { + if (refresh != this.refresh) { + this.getMappingAnnotationForUpdate().setCascadeRefresh(refresh); + this.setRefresh_(refresh); + } + } + + protected void setRefresh_(boolean refresh) { + boolean old = this.refresh; + this.refresh = refresh; + this.firePropertyChanged(REFRESH_PROPERTY, old, refresh); + } + + protected boolean buildRefresh() { + RelationshipMappingAnnotation annotation = this.getMappingAnnotation(); + return (annotation != null) && annotation.isCascadeRefresh(); + } + + + // ********** detach ********** + + public boolean isDetach() { + return this.detach; + } + + public void setDetach(boolean detach) { + if (detach != this.detach) { + this.getMappingAnnotationForUpdate2_0().setCascadeDetach(detach); + this.setDetach_(detach); + } + } + + protected void setDetach_(boolean detach) { + boolean old = this.detach; + this.detach = detach; + this.firePropertyChanged(DETACH_PROPERTY, old, detach); + } + + protected boolean buildDetach() { + return this.isJpa2_0Compatible() && this.buildDetach_(); + } + + protected boolean buildDetach_() { + RelationshipMapping2_0Annotation annotation = this.getMappingAnnotation2_0(); + return (annotation != null) && annotation.isCascadeDetach(); + } + + + + // ********** misc ********** + + @Override + public JavaRelationshipMapping getParent() { + return (JavaRelationshipMapping) super.getParent(); + } + + protected JavaRelationshipMapping getMapping() { + return this.getParent(); + } + + protected RelationshipMappingAnnotation getMappingAnnotation() { + return this.getMapping().getMappingAnnotation(); + } + + protected RelationshipMappingAnnotation getMappingAnnotationForUpdate() { + return this.getMapping().getAnnotationForUpdate(); + } + + protected RelationshipMapping2_0Annotation getMappingAnnotation2_0() { + return (RelationshipMapping2_0Annotation) this.getMappingAnnotation(); + } + + protected RelationshipMapping2_0Annotation getMappingAnnotationForUpdate2_0() { + return (RelationshipMapping2_0Annotation) this.getMappingAnnotationForUpdate(); + } + + public TextRange getValidationTextRange(CompilationUnit astRoot) { + RelationshipMappingAnnotation annotation = this.getMappingAnnotation(); + return (annotation == null) ? null : annotation.getCascadeTextRange(astRoot); + } +} diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaColumn.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaColumn.java new file mode 100644 index 0000000000..2af11ca6fa --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaColumn.java @@ -0,0 +1,221 @@ +/******************************************************************************* + * Copyright (c) 2006, 2010 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.jpa1.context.java; + +import org.eclipse.jpt.jpa.core.context.ReadOnlyColumn; +import org.eclipse.jpt.jpa.core.context.java.JavaColumn; +import org.eclipse.jpt.jpa.core.context.java.JavaJpaContextNode; +import org.eclipse.jpt.jpa.core.internal.context.java.AbstractJavaBaseColumn; +import org.eclipse.jpt.jpa.core.resource.java.CompleteColumnAnnotation; + +/** + * Java column + * <p> + * Note: The <code>Column</code> annotation is one of only 2 annotations that + * can be nested outside of an array (i.e. in an <code>AttributeOverride</code> + * annotation); the other is {@link GenericJavaJoinTable JoinTable}. + */ +public class GenericJavaColumn + extends AbstractJavaBaseColumn<CompleteColumnAnnotation, JavaColumn.Owner> + implements JavaColumn +{ + protected Integer specifiedLength; + protected int defaultLength; + + protected Integer specifiedPrecision; + protected int defaultPrecision; + + protected Integer specifiedScale; + protected int defaultScale; + + + public GenericJavaColumn(JavaJpaContextNode parent, JavaColumn.Owner owner) { + super(parent, owner); + this.specifiedLength = this.buildSpecifiedLength(); + this.specifiedPrecision = this.buildSpecifiedPrecision(); + this.specifiedScale = this.buildSpecifiedScale(); + } + + + // ********** synchronize/update ********** + + @Override + public void synchronizeWithResourceModel() { + super.synchronizeWithResourceModel(); + this.setSpecifiedLength_(this.buildSpecifiedLength()); + this.setSpecifiedPrecision_(this.buildSpecifiedPrecision()); + this.setSpecifiedScale_(this.buildSpecifiedScale()); + } + + @Override + public void update() { + super.update(); + this.setDefaultLength(this.buildDefaultLength()); + this.setDefaultPrecision(this.buildDefaultPrecision()); + this.setDefaultScale(this.buildDefaultScale()); + } + + + // ********** column annotation ********** + + @Override + public CompleteColumnAnnotation getColumnAnnotation() { + return this.owner.getColumnAnnotation(); + } + + @Override + protected void removeColumnAnnotation() { + this.owner.removeColumnAnnotation(); + } + + + // ********** length ********** + + public int getLength() { + return (this.specifiedLength != null) ? this.specifiedLength.intValue() : this.defaultLength; + } + + public Integer getSpecifiedLength() { + return this.specifiedLength; + } + + public void setSpecifiedLength(Integer length) { + if (this.valuesAreDifferent(this.specifiedLength, length)) { + this.getColumnAnnotation().setLength(length); + this.removeColumnAnnotationIfUnset(); + this.setSpecifiedLength_(length); + } + } + + protected void setSpecifiedLength_(Integer length) { + Integer old = this.specifiedLength; + this.specifiedLength = length; + this.firePropertyChanged(SPECIFIED_LENGTH_PROPERTY, old, length); + } + + protected Integer buildSpecifiedLength() { + return this.getColumnAnnotation().getLength(); + } + + public int getDefaultLength() { + return this.defaultLength; + } + + protected void setDefaultLength(int length) { + int old = this.defaultLength; + this.defaultLength = length; + this.firePropertyChanged(DEFAULT_LENGTH_PROPERTY, old, length); + } + + protected int buildDefaultLength() { + return DEFAULT_LENGTH; + } + + + // ********** precision ********** + + public int getPrecision() { + return (this.specifiedPrecision != null) ? this.specifiedPrecision.intValue() : this.defaultPrecision; + } + + public Integer getSpecifiedPrecision() { + return this.specifiedPrecision; + } + + public void setSpecifiedPrecision(Integer precision) { + if (this.valuesAreDifferent(this.specifiedPrecision, precision)) { + this.getColumnAnnotation().setPrecision(precision); + this.removeColumnAnnotationIfUnset(); + this.setSpecifiedPrecision_(precision); + } + } + + protected void setSpecifiedPrecision_(Integer precision) { + Integer old = this.specifiedPrecision; + this.specifiedPrecision = precision; + this.firePropertyChanged(SPECIFIED_PRECISION_PROPERTY, old, precision); + } + + protected Integer buildSpecifiedPrecision() { + return this.getColumnAnnotation().getPrecision(); + } + + public int getDefaultPrecision() { + return this.defaultPrecision; + } + + protected void setDefaultPrecision(int precision) { + int old = this.defaultPrecision; + this.defaultPrecision = precision; + this.firePropertyChanged(DEFAULT_PRECISION_PROPERTY, old, precision); + } + + protected int buildDefaultPrecision() { + return DEFAULT_PRECISION; + } + + + // ********** scale ********** + + public int getScale() { + return (this.specifiedScale != null) ? this.specifiedScale.intValue() : this.defaultScale; + } + + public Integer getSpecifiedScale() { + return this.specifiedScale; + } + + public void setSpecifiedScale(Integer scale) { + if (this.valuesAreDifferent(this.specifiedScale, scale)) { + this.getColumnAnnotation().setScale(scale); + this.removeColumnAnnotationIfUnset(); + this.setSpecifiedScale_(scale); + } + } + + protected void setSpecifiedScale_(Integer scale) { + Integer old = this.specifiedScale; + this.specifiedScale = scale; + this.firePropertyChanged(SPECIFIED_SCALE_PROPERTY, old, scale); + } + + protected Integer buildSpecifiedScale() { + return this.getColumnAnnotation().getScale(); + } + + public int getDefaultScale() { + return this.defaultScale; + } + + protected void setDefaultScale(int scale) { + int old = this.defaultScale; + this.defaultScale = scale; + this.firePropertyChanged(DEFAULT_SCALE_PROPERTY, old, scale); + } + + protected int buildDefaultScale() { + return DEFAULT_SCALE; + } + + + // ********** misc ********** + + public void initializeFrom(ReadOnlyColumn oldColumn) { + super.initializeFrom(oldColumn); + this.setSpecifiedLength(oldColumn.getSpecifiedLength()); + this.setSpecifiedPrecision(oldColumn.getSpecifiedPrecision()); + this.setSpecifiedScale(oldColumn.getSpecifiedScale()); + } + + public void initializeFromVirtual(ReadOnlyColumn virtualColumn) { + super.initializeFromVirtual(virtualColumn); + // ignore other settings? + } +} diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaDiscriminatorColumn.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaDiscriminatorColumn.java new file mode 100644 index 0000000000..a88cc6660c --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaDiscriminatorColumn.java @@ -0,0 +1,182 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 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.jpa1.context.java; + +import org.eclipse.jpt.jpa.core.context.DiscriminatorType; +import org.eclipse.jpt.jpa.core.context.java.JavaDiscriminatorColumn; +import org.eclipse.jpt.jpa.core.context.java.JavaEntity; +import org.eclipse.jpt.jpa.core.context.java.JavaPersistentType; +import org.eclipse.jpt.jpa.core.internal.context.java.AbstractJavaNamedColumn; +import org.eclipse.jpt.jpa.core.resource.java.DiscriminatorColumnAnnotation; +import org.eclipse.jpt.jpa.core.resource.java.JavaResourcePersistentType; + +/** + * Java discriminator column + */ +public class GenericJavaDiscriminatorColumn + extends AbstractJavaNamedColumn<DiscriminatorColumnAnnotation, JavaDiscriminatorColumn.Owner> + implements JavaDiscriminatorColumn +{ + protected DiscriminatorType specifiedDiscriminatorType; + protected DiscriminatorType defaultDiscriminatorType; + + protected Integer specifiedLength; + protected int defaultLength; + + + public GenericJavaDiscriminatorColumn(JavaEntity parent, JavaDiscriminatorColumn.Owner owner) { + super(parent, owner); + this.specifiedDiscriminatorType = this.buildSpecifiedDiscriminatorType(); + this.specifiedLength = this.buildSpecifiedLength(); + } + + + // ********** synchronize/update ********** + + @Override + public void synchronizeWithResourceModel() { + super.synchronizeWithResourceModel(); + this.setSpecifiedDiscriminatorType_(this.buildSpecifiedDiscriminatorType()); + this.setSpecifiedLength_(this.buildSpecifiedLength()); + } + + @Override + public void update() { + super.update(); + this.setDefaultDiscriminatorType(this.buildDefaultDiscriminatorType()); + this.setDefaultLength(this.buildDefaultLength()); + } + + + // ********** column annotation ********** + + @Override + public DiscriminatorColumnAnnotation getColumnAnnotation() { + return (DiscriminatorColumnAnnotation) this.getResourcePersistentType().getNonNullAnnotation(DiscriminatorColumnAnnotation.ANNOTATION_NAME); + } + + @Override + protected void removeColumnAnnotation() { + this.getResourcePersistentType().removeAnnotation(DiscriminatorColumnAnnotation.ANNOTATION_NAME); + } + + + // ********** discriminator type ********** + + public DiscriminatorType getDiscriminatorType() { + return (this.specifiedDiscriminatorType != null) ? this.specifiedDiscriminatorType : this.defaultDiscriminatorType; + } + + public DiscriminatorType getSpecifiedDiscriminatorType() { + return this.specifiedDiscriminatorType; + } + + public void setSpecifiedDiscriminatorType(DiscriminatorType discriminatorType) { + if (this.valuesAreDifferent(this.specifiedDiscriminatorType, discriminatorType)) { + this.getColumnAnnotation().setDiscriminatorType(DiscriminatorType.toJavaResourceModel(discriminatorType)); + this.removeColumnAnnotationIfUnset(); + this.setSpecifiedDiscriminatorType_(discriminatorType); + } + } + + protected void setSpecifiedDiscriminatorType_(DiscriminatorType discriminatorType) { + DiscriminatorType old = this.specifiedDiscriminatorType; + this.specifiedDiscriminatorType = discriminatorType; + this.firePropertyChanged(SPECIFIED_DISCRIMINATOR_TYPE_PROPERTY, old, discriminatorType); + } + + protected DiscriminatorType buildSpecifiedDiscriminatorType() { + return DiscriminatorType.fromJavaResourceModel(this.getColumnAnnotation().getDiscriminatorType()); + } + + public DiscriminatorType getDefaultDiscriminatorType() { + return this.defaultDiscriminatorType; + } + + protected void setDefaultDiscriminatorType(DiscriminatorType discriminatorType) { + DiscriminatorType old = this.defaultDiscriminatorType; + this.defaultDiscriminatorType = discriminatorType; + this.firePropertyChanged(DEFAULT_DISCRIMINATOR_TYPE_PROPERTY, old, discriminatorType); + } + + protected DiscriminatorType buildDefaultDiscriminatorType() { + return this.owner.getDefaultDiscriminatorType(); + } + + + // ********** length ********** + + public int getLength() { + return (this.specifiedLength != null) ? this.specifiedLength.intValue() : this.defaultLength; + } + + public Integer getSpecifiedLength() { + return this.specifiedLength; + } + + public void setSpecifiedLength(Integer length) { + if (this.valuesAreDifferent(this.specifiedLength, length)) { + this.getColumnAnnotation().setLength(length); + this.removeColumnAnnotationIfUnset(); + this.setSpecifiedLength_(length); + } + } + + protected void setSpecifiedLength_(Integer length) { + Integer old = this.specifiedLength; + this.specifiedLength = length; + this.firePropertyChanged(SPECIFIED_LENGTH_PROPERTY, old, length); + } + + protected Integer buildSpecifiedLength() { + return this.getColumnAnnotation().getLength(); + } + + public int getDefaultLength() { + return this.defaultLength; + } + + protected void setDefaultLength(int length) { + int old = this.defaultLength; + this.defaultLength = length; + this.firePropertyChanged(DEFAULT_LENGTH_PROPERTY, old, length); + } + + protected int buildDefaultLength() { + return this.owner.getDefaultLength(); + } + + + // ********** misc ********** + + @Override + public JavaEntity getParent() { + return (JavaEntity) super.getParent(); + } + + protected JavaEntity getEntity() { + return this.getParent(); + } + + protected JavaPersistentType getPersistentType() { + return this.getEntity().getPersistentType(); + } + + protected JavaResourcePersistentType getResourcePersistentType() { + return this.getPersistentType().getResourcePersistentType(); + } + + + // ********** validation ********** + + public boolean isResourceSpecified() { + return this.getColumnAnnotation().isSpecified(); + } +} diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaEmbeddable.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaEmbeddable.java new file mode 100644 index 0000000000..75bcc8579a --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaEmbeddable.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2007, 2009 Oracle. All rights reserved. + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0, which accompanies this distribution + * and is available at http://www.eclipse.org/legal/epl-v10.html. + * + * Contributors: + * Oracle - initial API and implementation + ******************************************************************************/ +package org.eclipse.jpt.jpa.core.internal.jpa1.context.java; + +import org.eclipse.jpt.common.utility.internal.ArrayTools; +import org.eclipse.jpt.jpa.core.MappingKeys; +import org.eclipse.jpt.jpa.core.context.java.JavaPersistentType; +import org.eclipse.jpt.jpa.core.internal.context.java.AbstractJavaEmbeddable; +import org.eclipse.jpt.jpa.core.resource.java.EmbeddableAnnotation; + +/** + * Java embeddable type mapping + */ +public class GenericJavaEmbeddable + extends AbstractJavaEmbeddable +{ + public GenericJavaEmbeddable(JavaPersistentType parent, EmbeddableAnnotation mappingAnnotation) { + super(parent, mappingAnnotation); + } + + @Override + public boolean attributeMappingKeyAllowed(String attributeMappingKey) { + //generic only allows basic and transient within an Embeddable + return ArrayTools.contains(ALLOWED_ATTRIBUTE_MAPPING_KEYS, attributeMappingKey); + } + + public static final String[] ALLOWED_ATTRIBUTE_MAPPING_KEYS = + new String[] { + MappingKeys.BASIC_ATTRIBUTE_MAPPING_KEY, + MappingKeys.TRANSIENT_ATTRIBUTE_MAPPING_KEY + }; +} diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaEmbeddedIdMapping.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaEmbeddedIdMapping.java new file mode 100644 index 0000000000..2db8014c83 --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaEmbeddedIdMapping.java @@ -0,0 +1,164 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 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.jpa1.context.java; + +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jpt.common.utility.internal.CollectionTools; +import org.eclipse.jpt.common.utility.internal.iterators.EmptyIterator; +import org.eclipse.jpt.common.utility.internal.iterators.FilteringIterator; +import org.eclipse.jpt.jpa.core.MappingKeys; +import org.eclipse.jpt.jpa.core.context.TypeMapping; +import org.eclipse.jpt.jpa.core.context.java.JavaAttributeOverrideContainer; +import org.eclipse.jpt.jpa.core.context.java.JavaEmbeddedIdMapping; +import org.eclipse.jpt.jpa.core.context.java.JavaPersistentAttribute; +import org.eclipse.jpt.jpa.core.internal.context.TypeMappingTools; +import org.eclipse.jpt.jpa.core.internal.context.java.AbstractJavaBaseEmbeddedMapping; +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.EmbeddedIdMapping2_0; +import org.eclipse.jpt.jpa.core.resource.java.EmbeddedIdAnnotation; +import org.eclipse.wst.validation.internal.provisional.core.IMessage; +import org.eclipse.wst.validation.internal.provisional.core.IReporter; + +/** + * Java embedded ID mapping + */ +public class GenericJavaEmbeddedIdMapping + extends AbstractJavaBaseEmbeddedMapping<EmbeddedIdAnnotation> + implements EmbeddedIdMapping2_0, JavaEmbeddedIdMapping +{ + /* 2.0 feature - a relationship may map this embedded id */ + protected boolean mappedByRelationship; + + + public GenericJavaEmbeddedIdMapping(JavaPersistentAttribute parent) { + super(parent); + } + + + // ********** synchronize/update ********** + + @Override + public void update() { + super.update(); + this.setMappedByRelationship(this.buildMappedByRelationship()); + } + + + // ********** mapped by relationship ********** + + public boolean isMappedByRelationship() { + return this.mappedByRelationship; + } + + protected void setMappedByRelationship(boolean value) { + boolean old = this.mappedByRelationship; + this.mappedByRelationship = value; + this.firePropertyChanged(MAPPED_BY_RELATIONSHIP_PROPERTY, old, value); + } + + protected boolean buildMappedByRelationship() { + return this.isJpa2_0Compatible() && this.buildMappedByRelationship_(); + } + + protected boolean buildMappedByRelationship_() { + return CollectionTools.contains(this.getMappedByRelationshipAttributeNames(), this.getName()); + } + + protected Iterable<String> getMappedByRelationshipAttributeNames() { + return TypeMappingTools.getMappedByRelationshipAttributeNames(this.getTypeMapping()); + } + + + // ********** misc ********** + + public String getKey() { + return MappingKeys.EMBEDDED_ID_ATTRIBUTE_MAPPING_KEY; + } + + @Override + protected String getAnnotationName() { + return EmbeddedIdAnnotation.ANNOTATION_NAME; + } + + @Override + protected Iterator<String> embeddableOverridableAttributeMappingNames() { + return (this.mappedByRelationship) ? + EmptyIterator.<String>instance() : + super.embeddableOverridableAttributeMappingNames(); + } + + @Override + protected JavaAttributeOverrideContainer.Owner buildAttributeOverrideContainerOwner() { + return new AttributeOverrideContainerOwner(); + } + + + // ********** validation ********** + + @Override + public void validate(List<IMessage> messages, IReporter reporter, CompilationUnit astRoot) { + super.validate(messages, reporter, astRoot); + + // [JPA 2.0] if the embedded id is mapped by a relationship, then any specified + // attribute overrides are in error + // (in JPA 1.0, this will obviously never be reached) + if (this.mappedByRelationship + && (this.attributeOverrideContainer.specifiedOverridesSize() > 0)) { + messages.add( + DefaultJpaValidationMessages.buildMessage( + IMessage.HIGH_SEVERITY, + JpaValidationMessages.EMBEDDED_ID_MAPPING_MAPPED_BY_RELATIONSHIP_AND_ATTRIBUTE_OVERRIDES_SPECIFIED, + EMPTY_STRING_ARRAY, + this.attributeOverrideContainer, + this.attributeOverrideContainer.getValidationTextRange(astRoot) + ) + ); + } + } + + // ********** attribute override container owner ********* + + protected class AttributeOverrideContainerOwner + extends AbstractJavaBaseEmbeddedMapping<EmbeddedIdAnnotation>.AttributeOverrideContainerOwner + { + @Override + public Iterator<String> allOverridableNames() { + return GenericJavaEmbeddedIdMapping.this.isMappedByRelationship() ? + EmptyIterator.<String>instance() : + super.allOverridableNames(); + } + + @Override + protected Iterator<String> allOverridableAttributeNames_(TypeMapping typeMapping) { + final Set<String> mappedByRelationshipAttributeNames = this.buildMappedByRelationshipAttributeNames(); + if (mappedByRelationshipAttributeNames.isEmpty()) { + return super.allOverridableAttributeNames_(typeMapping); + } + return new FilteringIterator<String>(super.allOverridableAttributeNames_(typeMapping)) { + @Override + protected boolean accept(String attributeName) { + // overridable names are (usually?) qualified with a container mapping, + // which may also be the one mapped by a relationship + int dotIndex = attributeName.indexOf('.'); + String qualifier = (dotIndex > 0) ? attributeName.substring(0, dotIndex) : attributeName; + return ! mappedByRelationshipAttributeNames.contains(qualifier); + } + }; + } + + protected Set<String> buildMappedByRelationshipAttributeNames() { + return CollectionTools.set(GenericJavaEmbeddedIdMapping.this.getMappedByRelationshipAttributeNames()); + } + } +} diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaEmbeddedMapping.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaEmbeddedMapping.java new file mode 100644 index 0000000000..660bc2d6af --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaEmbeddedMapping.java @@ -0,0 +1,284 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 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.jpa1.context.java; + +import java.util.Iterator; +import java.util.List; +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jpt.common.core.utility.TextRange; +import org.eclipse.jpt.common.utility.Filter; +import org.eclipse.jpt.common.utility.internal.CollectionTools; +import org.eclipse.jpt.common.utility.internal.iterators.CompositeIterator; +import org.eclipse.jpt.common.utility.internal.iterators.EmptyIterator; +import org.eclipse.jpt.jpa.core.MappingKeys; +import org.eclipse.jpt.jpa.core.context.AssociationOverride; +import org.eclipse.jpt.jpa.core.context.AssociationOverrideContainer; +import org.eclipse.jpt.jpa.core.context.AttributeMapping; +import org.eclipse.jpt.jpa.core.context.BaseColumn; +import org.eclipse.jpt.jpa.core.context.JoinColumn; +import org.eclipse.jpt.jpa.core.context.JoinTable; +import org.eclipse.jpt.jpa.core.context.OverrideContainer; +import org.eclipse.jpt.jpa.core.context.Override_; +import org.eclipse.jpt.jpa.core.context.Relationship; +import org.eclipse.jpt.jpa.core.context.Table; +import org.eclipse.jpt.jpa.core.context.TypeMapping; +import org.eclipse.jpt.jpa.core.context.java.JavaAssociationOverrideContainer; +import org.eclipse.jpt.jpa.core.context.java.JavaPersistentAttribute; +import org.eclipse.jpt.jpa.core.internal.context.AttributeMappingTools; +import org.eclipse.jpt.jpa.core.internal.context.BaseColumnTextRangeResolver; +import org.eclipse.jpt.jpa.core.internal.context.JoinColumnTextRangeResolver; +import org.eclipse.jpt.jpa.core.internal.context.JptValidator; +import org.eclipse.jpt.jpa.core.internal.context.MappingTools; +import org.eclipse.jpt.jpa.core.internal.context.OverrideTextRangeResolver; +import org.eclipse.jpt.jpa.core.internal.context.TableTextRangeResolver; +import org.eclipse.jpt.jpa.core.internal.context.java.AbstractJavaBaseEmbeddedMapping; +import org.eclipse.jpt.jpa.core.internal.jpa1.context.AssociationOverrideInverseJoinColumnValidator; +import org.eclipse.jpt.jpa.core.internal.jpa1.context.AssociationOverrideJoinColumnValidator; +import org.eclipse.jpt.jpa.core.internal.jpa1.context.AssociationOverrideJoinTableValidator; +import org.eclipse.jpt.jpa.core.internal.jpa1.context.AssociationOverrideValidator; +import org.eclipse.jpt.jpa.core.internal.jpa1.context.EmbeddableOverrideDescriptionProvider; +import org.eclipse.jpt.jpa.core.internal.jpa1.context.EntityTableDescriptionProvider; +import org.eclipse.jpt.jpa.core.internal.jpa1.context.JoinTableTableDescriptionProvider; +import org.eclipse.jpt.jpa.core.jpa2.context.java.JavaEmbeddedMapping2_0; +import org.eclipse.jpt.jpa.core.resource.java.EmbeddedAnnotation; +import org.eclipse.jpt.jpa.core.resource.java.JavaResourcePersistentMember; +import org.eclipse.wst.validation.internal.provisional.core.IMessage; +import org.eclipse.wst.validation.internal.provisional.core.IReporter; + +/** + * Java embedded mapping + */ +public class GenericJavaEmbeddedMapping + extends AbstractJavaBaseEmbeddedMapping<EmbeddedAnnotation> + implements JavaEmbeddedMapping2_0 +{ + protected final JavaAssociationOverrideContainer associationOverrideContainer; + + + public GenericJavaEmbeddedMapping(JavaPersistentAttribute parent) { + super(parent); + this.associationOverrideContainer = this.buildAssociationOverrideContainer(); + } + + + // ********** synchronize/update ********** + + @Override + public void synchronizeWithResourceModel() { + super.synchronizeWithResourceModel(); + this.associationOverrideContainer.synchronizeWithResourceModel(); + } + + @Override + public void update() { + super.update(); + this.associationOverrideContainer.update(); + } + + + // ********** association override container ********** + + protected JavaAssociationOverrideContainer buildAssociationOverrideContainer() { + return this.isJpa2_0Compatible() ? + this.getJpaFactory2_0().buildJavaAssociationOverrideContainer(this, this.buildAssociationOverrideContainerOwner()) : + new GenericJavaAssociationOverrideContainer(this, null); + } + + public JavaAssociationOverrideContainer getAssociationOverrideContainer() { + return this.associationOverrideContainer; + } + + protected JavaAssociationOverrideContainer.Owner buildAssociationOverrideContainerOwner() { + return new AssociationOverrideContainerOwner(); + } + + + // ********** embedded mappings ********** + + /** + * This is only to build the choices for a "mapped by" setting in a + * relationship mapping. JPA 2.0 does not support relationship mappings + * in an embedded ID class; so we only put this logic here. + */ + @Override + @SuppressWarnings("unchecked") + public Iterator<String> allMappingNames() { + return this.isJpa2_0Compatible() ? + new CompositeIterator<String>(super.allMappingNames(), this.allEmbeddableAttributeMappingNames()) : + super.allMappingNames(); + } + + protected Iterator<String> allEmbeddableAttributeMappingNames() { + return this.qualifiedEmbeddableOverridableMappingNames(AttributeMappingTools.ALL_MAPPING_NAMES_TRANSFORMER); + } + + @Override + public AttributeMapping resolveAttributeMapping(String attributeName) { + AttributeMapping resolvedMapping = super.resolveAttributeMapping(attributeName); + if (resolvedMapping != null) { + return resolvedMapping; + } + return this.isJpa2_0Compatible() ? this.resolveAttributeMapping_(attributeName) : null; + } + + protected AttributeMapping resolveAttributeMapping_(String attributeName) { + attributeName = this.unqualify(attributeName); + if (attributeName == null) { + return null; + } + // recurse into the embeddable mappings + for (AttributeMapping mapping : CollectionTools.iterable(this.embeddableAttributeMappings())) { + AttributeMapping resolvedMapping = mapping.resolveAttributeMapping(attributeName); + if (resolvedMapping != null) { + return resolvedMapping; + } + } + return null; + } + + + // ********** misc ********** + + public String getKey() { + return MappingKeys.EMBEDDED_ATTRIBUTE_MAPPING_KEY; + } + + @Override + protected String getAnnotationName() { + return EmbeddedAnnotation.ANNOTATION_NAME; + } + + @Override + public Relationship resolveOverriddenRelationship(String attributeName) { + return this.isJpa2_0Compatible() ? this.resolveOverriddenRelationship_(attributeName) : null; + } + + protected Relationship resolveOverriddenRelationship_(String attributeName) { + attributeName = this.unqualify(attributeName); + if (attributeName == null) { + return null; + } + AssociationOverride override = this.associationOverrideContainer.getSpecifiedOverrideNamed(attributeName); + // recurse into the target embeddable if necessary + return (override != null) ? override.getRelationship() : this.resolveOverriddenRelationshipInTargetEmbeddable(attributeName); + } + + protected Relationship resolveOverriddenRelationshipInTargetEmbeddable(String attributeName) { + return (this.targetEmbeddable == null) ? null : this.targetEmbeddable.resolveOverriddenRelationship(attributeName); + } + + + // ********** Java completion proposals ********** + + @Override + public Iterator<String> javaCompletionProposals(int pos, Filter<String> filter, CompilationUnit astRoot) { + Iterator<String> result = super.javaCompletionProposals(pos, filter, astRoot); + if (result != null) { + return result; + } + + result = this.associationOverrideContainer.javaCompletionProposals(pos, filter, astRoot); + if (result != null) { + return result; + } + + return null; + } + + + // ********** validation ********** + + @Override + protected void validateOverrides(List<IMessage> messages, IReporter reporter, CompilationUnit astRoot) { + super.validateOverrides(messages, reporter, astRoot); + this.associationOverrideContainer.validate(messages, reporter, astRoot); + } + + + // ********** association override container owner ********** + + protected class AssociationOverrideContainerOwner + implements JavaAssociationOverrideContainer.Owner + { + public JavaResourcePersistentMember getResourcePersistentMember() { + return GenericJavaEmbeddedMapping.this.getResourcePersistentAttribute(); + } + + public TypeMapping getTypeMapping() { + return GenericJavaEmbeddedMapping.this.getTypeMapping(); + } + + public TypeMapping getOverridableTypeMapping() { + return GenericJavaEmbeddedMapping.this.getTargetEmbeddable(); + } + + public Iterator<String> allOverridableNames() { + TypeMapping typeMapping = this.getOverridableTypeMapping(); + return (typeMapping != null) ? typeMapping.allOverridableAssociationNames() : EmptyIterator.<String>instance(); + } + + public Relationship resolveOverriddenRelationship(String attributeName) { + return MappingTools.resolveOverriddenRelationship(this.getOverridableTypeMapping(), attributeName); + } + + public boolean tableNameIsInvalid(String tableName) { + return this.getTypeMapping().tableNameIsInvalid(tableName); + } + + public Iterator<String> candidateTableNames() { + return this.getTypeMapping().allAssociatedTableNames(); + } + + public org.eclipse.jpt.jpa.db.Table resolveDbTable(String tableName) { + return this.getTypeMapping().resolveDbTable(tableName); + } + + public String getDefaultTableName() { + return this.getTypeMapping().getPrimaryTableName(); + } + + public String getPossiblePrefix() { + return null; + } + + public String getWritePrefix() { + return null; + } + + // no maps, so all overrides are relevant + public boolean isRelevant(String overrideName) { + return true; + } + + public TextRange getValidationTextRange(CompilationUnit astRoot) { + return GenericJavaEmbeddedMapping.this.getValidationTextRange(astRoot); + } + + public JptValidator buildValidator(Override_ override, OverrideContainer container, OverrideTextRangeResolver textRangeResolver) { + return new AssociationOverrideValidator((AssociationOverride) override, (AssociationOverrideContainer) container, textRangeResolver, new EmbeddableOverrideDescriptionProvider()); + } + + public JptValidator buildColumnValidator(Override_ override, BaseColumn column, BaseColumn.Owner owner, BaseColumnTextRangeResolver textRangeResolver) { + return new AssociationOverrideJoinColumnValidator((AssociationOverride) override, (JoinColumn) column, (JoinColumn.Owner) owner, (JoinColumnTextRangeResolver) textRangeResolver, new EntityTableDescriptionProvider()); + } + + public JptValidator buildJoinTableJoinColumnValidator(AssociationOverride override, JoinColumn column, JoinColumn.Owner owner, JoinColumnTextRangeResolver textRangeResolver) { + return new AssociationOverrideJoinColumnValidator(override, column, owner, textRangeResolver, new JoinTableTableDescriptionProvider()); + } + + public JptValidator buildJoinTableInverseJoinColumnValidator(AssociationOverride override, JoinColumn column, JoinColumn.Owner owner, JoinColumnTextRangeResolver textRangeResolver) { + return new AssociationOverrideInverseJoinColumnValidator(override, column, owner, textRangeResolver, new JoinTableTableDescriptionProvider()); + } + + public JptValidator buildTableValidator(AssociationOverride override, Table table, TableTextRangeResolver textRangeResolver) { + return new AssociationOverrideJoinTableValidator(override, (JoinTable) table, textRangeResolver); + } + } +} diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaEntity.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaEntity.java new file mode 100644 index 0000000000..e123367631 --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaEntity.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * Copyright (c) 2006, 2010 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.jpa1.context.java; + +import org.eclipse.jpt.jpa.core.context.java.JavaPersistentType; +import org.eclipse.jpt.jpa.core.internal.context.java.AbstractJavaEntity; +import org.eclipse.jpt.jpa.core.internal.jpa2.context.java.NullJavaCacheable2_0; +import org.eclipse.jpt.jpa.core.jpa2.context.Cacheable2_0; +import org.eclipse.jpt.jpa.core.jpa2.context.CacheableHolder2_0; +import org.eclipse.jpt.jpa.core.jpa2.context.java.JavaCacheable2_0; +import org.eclipse.jpt.jpa.core.jpa2.context.persistence.PersistenceUnit2_0; +import org.eclipse.jpt.jpa.core.resource.java.EntityAnnotation; + +public class GenericJavaEntity + extends AbstractJavaEntity +{ + // EclipseLink holds its cacheable in its caching + protected final JavaCacheable2_0 cacheable; + + + public GenericJavaEntity(JavaPersistentType parent, EntityAnnotation mappingAnnotation) { + super(parent, mappingAnnotation); + this.cacheable = this.buildCacheable(); + } + + + // ********** synchronize/update ********** + + @Override + public void synchronizeWithResourceModel() { + super.synchronizeWithResourceModel(); + this.cacheable.synchronizeWithResourceModel(); + } + + @Override + public void update() { + super.update(); + this.cacheable.update(); + } + + + // ********** cacheable ********** + + public JavaCacheable2_0 getCacheable() { + return this.cacheable; + } + + protected JavaCacheable2_0 buildCacheable() { + return this.isJpa2_0Compatible() ? + this.getJpaFactory2_0().buildJavaCacheable(this) : + new NullJavaCacheable2_0(this); + } + + public boolean calculateDefaultCacheable() { + Cacheable2_0 parentCacheable = this.getParentCacheable(); + return (parentCacheable != null) ? + parentCacheable.isCacheable() : + ((PersistenceUnit2_0) this.getPersistenceUnit()).calculateDefaultCacheable(); + } + + protected Cacheable2_0 getParentCacheable() { + CacheableHolder2_0 parentEntity = (CacheableHolder2_0) this.getParentEntity(); + return (parentEntity == null) ? null : parentEntity.getCacheable(); + } +} diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaEnumeratedConverter.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaEnumeratedConverter.java new file mode 100644 index 0000000000..0ef279813f --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaEnumeratedConverter.java @@ -0,0 +1,110 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 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.jpa1.context.java; + +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jpt.common.core.utility.TextRange; +import org.eclipse.jpt.jpa.core.context.Converter; +import org.eclipse.jpt.jpa.core.context.EnumType; +import org.eclipse.jpt.jpa.core.context.EnumeratedConverter; +import org.eclipse.jpt.jpa.core.context.java.JavaAttributeMapping; +import org.eclipse.jpt.jpa.core.context.java.JavaEnumeratedConverter; +import org.eclipse.jpt.jpa.core.resource.java.EnumeratedAnnotation; + +public class GenericJavaEnumeratedConverter + extends AbstractJavaConverter + implements JavaEnumeratedConverter +{ + protected final EnumeratedAnnotation enumeratedAnnotation; + + protected EnumType specifiedEnumType; + protected EnumType defaultEnumType; + + + public GenericJavaEnumeratedConverter(JavaAttributeMapping parent, EnumeratedAnnotation enumeratedAnnotation) { + super(parent); + this.enumeratedAnnotation = enumeratedAnnotation; + this.specifiedEnumType = this.buildSpecifiedEnumType(); + } + + + // ********** synchronize/update ********** + + @Override + public void synchronizeWithResourceModel() { + super.synchronizeWithResourceModel(); + this.setSpecifiedEnumType_(this.buildSpecifiedEnumType()); + } + + @Override + public void update() { + super.update(); + this.setDefaultEnumType(this.buildDefaultEnumType()); + } + + + // ********** enum type ********** + + public EnumType getEnumType() { + return (this.specifiedEnumType != null) ? this.specifiedEnumType : this.defaultEnumType; + } + + public EnumType getSpecifiedEnumType() { + return this.specifiedEnumType; + } + + public void setSpecifiedEnumType(EnumType enumType) { + this.enumeratedAnnotation.setValue(EnumType.toJavaResourceModel(enumType)); + this.setSpecifiedEnumType_(enumType); + } + + protected void setSpecifiedEnumType_(EnumType enumType) { + EnumType old = this.specifiedEnumType; + this.specifiedEnumType = enumType; + this.firePropertyChanged(SPECIFIED_ENUM_TYPE_PROPERTY, old, enumType); + } + + protected EnumType buildSpecifiedEnumType() { + return EnumType.fromJavaResourceModel(this.enumeratedAnnotation.getValue()); + } + + public EnumType getDefaultEnumType() { + return this.defaultEnumType; + } + + protected void setDefaultEnumType(EnumType enumType) { + EnumType old = this.defaultEnumType; + this.defaultEnumType = enumType; + this.firePropertyChanged(DEFAULT_ENUM_TYPE_PROPERTY, old, enumType); + } + + protected EnumType buildDefaultEnumType() { + return DEFAULT_ENUM_TYPE; + } + + + // ********** misc ********** + + public Class<? extends Converter> getType() { + return EnumeratedConverter.class; + } + + @Override + protected String getAnnotationName() { + return EnumeratedAnnotation.ANNOTATION_NAME; + } + + + // ********** validation ********** + + public TextRange getValidationTextRange(CompilationUnit astRoot) { + return this.enumeratedAnnotation.getTextRange(astRoot); + } +} diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaGeneratedValue.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaGeneratedValue.java new file mode 100644 index 0000000000..de5501141b --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaGeneratedValue.java @@ -0,0 +1,220 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 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.jpa1.context.java; + +import java.util.Iterator; +import java.util.List; +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jpt.common.core.utility.TextRange; +import org.eclipse.jpt.common.utility.Filter; +import org.eclipse.jpt.common.utility.internal.StringTools; +import org.eclipse.jpt.common.utility.internal.iterators.FilteringIterator; +import org.eclipse.jpt.jpa.core.context.GenerationType; +import org.eclipse.jpt.jpa.core.context.Generator; +import org.eclipse.jpt.jpa.core.context.java.JavaGeneratedValue; +import org.eclipse.jpt.jpa.core.context.java.JavaIdMapping; +import org.eclipse.jpt.jpa.core.internal.context.java.AbstractJavaJpaContextNode; +import org.eclipse.jpt.jpa.core.internal.validation.DefaultJpaValidationMessages; +import org.eclipse.jpt.jpa.core.internal.validation.JpaValidationMessages; +import org.eclipse.jpt.jpa.core.resource.java.GeneratedValueAnnotation; +import org.eclipse.wst.validation.internal.provisional.core.IMessage; +import org.eclipse.wst.validation.internal.provisional.core.IReporter; + +/** + * Java generated value + */ +public class GenericJavaGeneratedValue + extends AbstractJavaJpaContextNode + implements JavaGeneratedValue +{ + protected final GeneratedValueAnnotation generatedValueAnnotation; + + protected GenerationType specifiedStrategy; + protected GenerationType defaultStrategy; + + protected String specifiedGenerator; + protected String defaultGenerator; + + + public GenericJavaGeneratedValue(JavaIdMapping parent, GeneratedValueAnnotation generatedValueAnnotation) { + super(parent); + this.generatedValueAnnotation = generatedValueAnnotation; + this.specifiedStrategy = this.buildSpecifiedStrategy(); + this.specifiedGenerator = generatedValueAnnotation.getGenerator(); + } + + + // ********** synchronize/update ********** + + @Override + public void synchronizeWithResourceModel() { + super.synchronizeWithResourceModel(); + this.setSpecifiedStrategy_(this.buildSpecifiedStrategy()); + this.setSpecifiedGenerator_(this.generatedValueAnnotation.getGenerator()); + } + + @Override + public void update() { + super.update(); + this.setDefaultStrategy(this.buildDefaultStrategy()); + this.setDefaultGenerator(this.buildDefaultGenerator()); + } + + + // ********** strategy ********** + + public GenerationType getStrategy() { + return (this.specifiedStrategy != null) ? this.specifiedStrategy : this.defaultStrategy; + } + + public GenerationType getSpecifiedStrategy() { + return this.specifiedStrategy; + } + + public void setSpecifiedStrategy(GenerationType strategy) { + this.generatedValueAnnotation.setStrategy(GenerationType.toJavaResourceModel(strategy)); + this.setSpecifiedStrategy_(strategy); + } + + protected void setSpecifiedStrategy_(GenerationType strategy) { + GenerationType old = this.specifiedStrategy; + this.specifiedStrategy = strategy; + this.firePropertyChanged(SPECIFIED_STRATEGY_PROPERTY, old, strategy); + } + + protected GenerationType buildSpecifiedStrategy() { + return GenerationType.fromJavaResourceModel(this.generatedValueAnnotation.getStrategy()); + } + + public GenerationType getDefaultStrategy() { + return this.defaultStrategy; + } + + protected void setDefaultStrategy(GenerationType strategy) { + GenerationType old = this.defaultStrategy; + this.defaultStrategy = strategy; + this.firePropertyChanged(DEFAULT_STRATEGY_PROPERTY, old, strategy); + } + + protected GenerationType buildDefaultStrategy() { + return DEFAULT_STRATEGY; + } + + + // ********** generator ********** + + public String getGenerator() { + return (this.specifiedGenerator != null) ? this.specifiedGenerator : this.defaultGenerator; + } + + public String getSpecifiedGenerator() { + return this.specifiedGenerator; + } + + public void setSpecifiedGenerator(String generator) { + this.generatedValueAnnotation.setGenerator(generator); + this.setSpecifiedGenerator_(generator); + } + + protected void setSpecifiedGenerator_(String generator) { + String old = this.specifiedGenerator; + this.specifiedGenerator = generator; + this.firePropertyChanged(SPECIFIED_GENERATOR_PROPERTY, old, generator); + } + + public String getDefaultGenerator() { + return this.defaultGenerator; + } + + protected void setDefaultGenerator(String generator) { + String old = this.defaultGenerator; + this.defaultGenerator = generator; + this.firePropertyChanged(DEFAULT_GENERATOR_PROPERTY, old, generator); + } + + protected String buildDefaultGenerator() { + return null; + } + + public TextRange getGeneratorTextRange(CompilationUnit astRoot) { + return this.generatedValueAnnotation.getGeneratorTextRange(astRoot); + } + + + // ********** misc ********** + + public GeneratedValueAnnotation getGeneratedValueAnnotation() { + return this.generatedValueAnnotation; + } + + + // ********** Java completion proposals ********** + + @Override + public Iterator<String> javaCompletionProposals(int pos, Filter<String> filter, CompilationUnit astRoot) { + Iterator<String> result = super.javaCompletionProposals(pos, filter, astRoot); + if (result != null) { + return result; + } + if (this.generatorTouches(pos, astRoot)) { + return this.javaCandidateGeneratorNames(filter); + } + return null; + } + + protected boolean generatorTouches(int pos, CompilationUnit astRoot) { + return this.generatedValueAnnotation.generatorTouches(pos, astRoot); + } + + protected Iterator<String> javaCandidateGeneratorNames(Filter<String> filter) { + return StringTools.convertToJavaStringLiterals(this.candidateGeneratorNames(filter)); + } + + protected Iterator<String> candidateGeneratorNames(Filter<String> filter) { + return new FilteringIterator<String>(this.candidateGeneratorNames(), filter); + } + + protected Iterator<String> candidateGeneratorNames() { + return this.getPersistenceUnit().getUniqueGeneratorNames().iterator(); + } + + + // ********** validation ********** + + @Override + public void validate(List<IMessage> messages, IReporter reporter, CompilationUnit astRoot) { + super.validate(messages, reporter, astRoot); + + String generator = this.getGenerator(); + if (generator == null) { + return; + } + + for (Iterator<Generator> stream = this.getPersistenceUnit().generators(); stream.hasNext(); ) { + if (generator.equals(stream.next().getName())) { + return; + } + } + + messages.add( + DefaultJpaValidationMessages.buildMessage( + IMessage.HIGH_SEVERITY, + JpaValidationMessages.ID_MAPPING_UNRESOLVED_GENERATOR_NAME, + new String[] {generator}, + this.getParent(), + this.getGeneratorTextRange(astRoot) + ) + ); + } + + public TextRange getValidationTextRange(CompilationUnit astRoot) { + return this.generatedValueAnnotation.getTextRange(astRoot); + } +} diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaGeneratorContainer.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaGeneratorContainer.java new file mode 100644 index 0000000000..65d1ab157d --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaGeneratorContainer.java @@ -0,0 +1,283 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 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.jpa1.context.java; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jpt.common.core.utility.TextRange; +import org.eclipse.jpt.common.utility.Filter; +import org.eclipse.jpt.common.utility.internal.StringTools; +import org.eclipse.jpt.jpa.core.context.Generator; +import org.eclipse.jpt.jpa.core.context.java.JavaGenerator; +import org.eclipse.jpt.jpa.core.context.java.JavaGeneratorContainer; +import org.eclipse.jpt.jpa.core.context.java.JavaJpaContextNode; +import org.eclipse.jpt.jpa.core.context.java.JavaSequenceGenerator; +import org.eclipse.jpt.jpa.core.context.java.JavaTableGenerator; +import org.eclipse.jpt.jpa.core.internal.context.java.AbstractJavaJpaContextNode; +import org.eclipse.jpt.jpa.core.internal.validation.DefaultJpaValidationMessages; +import org.eclipse.jpt.jpa.core.internal.validation.JpaValidationMessages; +import org.eclipse.jpt.jpa.core.resource.java.SequenceGeneratorAnnotation; +import org.eclipse.jpt.jpa.core.resource.java.TableGeneratorAnnotation; +import org.eclipse.wst.validation.internal.provisional.core.IMessage; +import org.eclipse.wst.validation.internal.provisional.core.IReporter; + +public class GenericJavaGeneratorContainer + extends AbstractJavaJpaContextNode + implements JavaGeneratorContainer +{ + protected final Owner owner; + + protected JavaSequenceGenerator sequenceGenerator; + + protected JavaTableGenerator tableGenerator; + + + public GenericJavaGeneratorContainer(JavaJpaContextNode parent, Owner owner) { + super(parent); + this.owner = owner; + this.sequenceGenerator = this.buildSequenceGenerator(); + this.tableGenerator = this.buildTableGenerator(); + } + + + // ********** synchronize/update ********** + + @Override + public void synchronizeWithResourceModel() { + super.synchronizeWithResourceModel(); + this.syncSequenceGenerator(); + this.syncTableGenerator(); + } + + @Override + public void update() { + super.update(); + if (this.sequenceGenerator != null) { + this.sequenceGenerator.update(); + } + if (this.tableGenerator != null) { + this.tableGenerator.update(); + } + } + + + // ********** sequence generator ********** + + public JavaSequenceGenerator getSequenceGenerator() { + return this.sequenceGenerator; + } + + public JavaSequenceGenerator addSequenceGenerator() { + if (this.sequenceGenerator != null) { + throw new IllegalStateException("sequence generator already exists: " + this.sequenceGenerator); //$NON-NLS-1$ + } + SequenceGeneratorAnnotation annotation = this.buildSequenceGeneratorAnnotation(); + JavaSequenceGenerator generator = this.buildSequenceGenerator(annotation); + this.setSequenceGenerator(generator); + return generator; + } + + protected SequenceGeneratorAnnotation buildSequenceGeneratorAnnotation() { + return (SequenceGeneratorAnnotation) this.owner.getResourceAnnotatedElement().addAnnotation(SequenceGeneratorAnnotation.ANNOTATION_NAME); + } + + public void removeSequenceGenerator() { + if (this.sequenceGenerator == null) { + throw new IllegalStateException("sequence generator does not exist"); //$NON-NLS-1$ + } + this.owner.getResourceAnnotatedElement().removeAnnotation(SequenceGeneratorAnnotation.ANNOTATION_NAME); + this.setSequenceGenerator(null); + } + + protected JavaSequenceGenerator buildSequenceGenerator() { + SequenceGeneratorAnnotation annotation = this.getSequenceGeneratorAnnotation(); + return (annotation == null) ? null : this.buildSequenceGenerator(annotation); + } + + protected SequenceGeneratorAnnotation getSequenceGeneratorAnnotation() { + return (SequenceGeneratorAnnotation) this.owner.getResourceAnnotatedElement().getAnnotation(SequenceGeneratorAnnotation.ANNOTATION_NAME); + } + + protected JavaSequenceGenerator buildSequenceGenerator(SequenceGeneratorAnnotation sequenceGeneratorAnnotation) { + return this.getJpaFactory().buildJavaSequenceGenerator(this, sequenceGeneratorAnnotation); + } + + protected void syncSequenceGenerator() { + SequenceGeneratorAnnotation annotation = this.getSequenceGeneratorAnnotation(); + if (annotation == null) { + if (this.sequenceGenerator != null) { + this.setSequenceGenerator(null); + } + } else { + if ((this.sequenceGenerator != null) && (this.sequenceGenerator.getGeneratorAnnotation() == annotation)) { + this.sequenceGenerator.synchronizeWithResourceModel(); + } else { + this.setSequenceGenerator(this.buildSequenceGenerator(annotation)); + } + } + } + + protected void setSequenceGenerator(JavaSequenceGenerator sequenceGenerator) { + JavaSequenceGenerator old = this.sequenceGenerator; + this.sequenceGenerator = sequenceGenerator; + this.firePropertyChanged(SEQUENCE_GENERATOR_PROPERTY, old, sequenceGenerator); + } + + + // ********** table generator ********** + + public JavaTableGenerator getTableGenerator() { + return this.tableGenerator; + } + + public JavaTableGenerator addTableGenerator() { + if (this.tableGenerator != null) { + throw new IllegalStateException("table generator already exists: " + this.tableGenerator); //$NON-NLS-1$ + } + TableGeneratorAnnotation annotation = this.buildTableGeneratorAnnotation(); + JavaTableGenerator generator = this.buildTableGenerator(annotation); + this.setTableGenerator(generator); + return generator; + } + + protected TableGeneratorAnnotation buildTableGeneratorAnnotation() { + return (TableGeneratorAnnotation) this.owner.getResourceAnnotatedElement().addAnnotation(TableGeneratorAnnotation.ANNOTATION_NAME); + } + + public void removeTableGenerator() { + if (this.tableGenerator == null) { + throw new IllegalStateException("table generator does not exist"); //$NON-NLS-1$ + } + this.owner.getResourceAnnotatedElement().removeAnnotation(TableGeneratorAnnotation.ANNOTATION_NAME); + this.setTableGenerator(null); + } + + protected JavaTableGenerator buildTableGenerator() { + TableGeneratorAnnotation annotation = this.getTableGeneratorAnnotation(); + return (annotation == null) ? null : this.buildTableGenerator(annotation); + } + + protected TableGeneratorAnnotation getTableGeneratorAnnotation() { + return (TableGeneratorAnnotation) this.owner.getResourceAnnotatedElement().getAnnotation(TableGeneratorAnnotation.ANNOTATION_NAME); + } + + protected JavaTableGenerator buildTableGenerator(TableGeneratorAnnotation tableGeneratorAnnotation) { + return this.getJpaFactory().buildJavaTableGenerator(this, tableGeneratorAnnotation); + } + + protected void syncTableGenerator() { + TableGeneratorAnnotation annotation = this.getTableGeneratorAnnotation(); + if (annotation == null) { + if (this.tableGenerator != null) { + this.setTableGenerator(null); + } + } else { + if ((this.tableGenerator != null) && (this.tableGenerator.getGeneratorAnnotation() == annotation)) { + this.tableGenerator.synchronizeWithResourceModel(); + } else { + this.setTableGenerator(this.buildTableGenerator(annotation)); + } + } + } + + protected void setTableGenerator(JavaTableGenerator tableGenerator) { + JavaTableGenerator old = this.tableGenerator; + this.tableGenerator = tableGenerator; + this.firePropertyChanged(TABLE_GENERATOR_PROPERTY, old, tableGenerator); + } + + + // ********** code completion ********** + + @Override + public Iterator<String> javaCompletionProposals(int pos, Filter<String> filter, CompilationUnit astRoot) { + Iterator<String> result = super.javaCompletionProposals(pos, filter, astRoot); + if (result != null) { + return result; + } + if (this.tableGenerator != null) { + result = this.tableGenerator.javaCompletionProposals(pos, filter, astRoot); + if (result != null) { + return result; + } + } + if (this.sequenceGenerator != null) { + result = this.sequenceGenerator.javaCompletionProposals(pos, filter, astRoot); + if (result != null) { + return result; + } + } + return null; + } + + // ********** validation ********** + + @Override + public void validate(List<IMessage> messages, IReporter reporter, CompilationUnit astRoot) { + super.validate(messages, reporter, astRoot); + this.validateGenerators(messages, astRoot); + } + + protected void validateGenerators(List<IMessage> messages, CompilationUnit astRoot) { + for (JavaGenerator localGenerator : this.getGenerators()) { + String name = localGenerator.getName(); + if (StringTools.stringIsEmpty(name)){ + messages.add( + DefaultJpaValidationMessages.buildMessage( + IMessage.HIGH_SEVERITY, + JpaValidationMessages.GENERATOR_NAME_UNDEFINED, + new String[] {}, + localGenerator, + localGenerator.getNameTextRange(astRoot) + ) + ); + } else { + List<String> reportedNames = new ArrayList<String>(); + for (Iterator<Generator> globalGenerators = this.getPersistenceUnit().generators(); globalGenerators.hasNext(); ) { + if (localGenerator.duplicates(globalGenerators.next()) && !reportedNames.contains(name)) { + messages.add( + DefaultJpaValidationMessages.buildMessage( + IMessage.HIGH_SEVERITY, + JpaValidationMessages.GENERATOR_DUPLICATE_NAME, + new String[] {name}, + localGenerator, + localGenerator.getNameTextRange(astRoot) + ) + ); + reportedNames.add(name); + } + } + } + } + } + + protected Iterable<JavaGenerator> getGenerators() { + ArrayList<JavaGenerator> generators = new ArrayList<JavaGenerator>(); + this.addGeneratorsTo(generators); + return generators; + } + + protected void addGeneratorsTo(ArrayList<JavaGenerator> generators) { + if (this.sequenceGenerator != null) { + generators.add(this.sequenceGenerator); + } + if (this.tableGenerator != null) { + generators.add(this.tableGenerator); + } + } + + public TextRange getValidationTextRange(CompilationUnit astRoot) { + return this.owner.getResourceAnnotatedElement().getTextRange(astRoot); + } + +} diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaIdMapping.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaIdMapping.java new file mode 100644 index 0000000000..7f1aca7b89 --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaIdMapping.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2006, 2010 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.jpa1.context.java; + +import org.eclipse.jpt.jpa.core.context.java.JavaPersistentAttribute; +import org.eclipse.jpt.jpa.core.internal.context.java.AbstractJavaIdMapping; + + +public class GenericJavaIdMapping + extends AbstractJavaIdMapping +{ + public GenericJavaIdMapping(JavaPersistentAttribute parent) { + super(parent); + } +} diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaJoinColumn.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaJoinColumn.java new file mode 100644 index 0000000000..de4e5b0c85 --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaJoinColumn.java @@ -0,0 +1,212 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 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.jpa1.context.java; + +import java.util.Iterator; +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jpt.common.core.utility.TextRange; +import org.eclipse.jpt.common.utility.Filter; +import org.eclipse.jpt.common.utility.internal.StringTools; +import org.eclipse.jpt.common.utility.internal.iterables.EmptyIterable; +import org.eclipse.jpt.common.utility.internal.iterables.FilteringIterable; +import org.eclipse.jpt.jpa.core.context.ReadOnlyJoinColumn; +import org.eclipse.jpt.jpa.core.context.java.JavaJoinColumn; +import org.eclipse.jpt.jpa.core.context.java.JavaJpaContextNode; +import org.eclipse.jpt.jpa.core.internal.context.MappingTools; +import org.eclipse.jpt.jpa.core.internal.context.NamedColumnTextRangeResolver; +import org.eclipse.jpt.jpa.core.internal.context.java.AbstractJavaBaseColumn; +import org.eclipse.jpt.jpa.core.internal.context.java.AbstractJavaNamedColumn; +import org.eclipse.jpt.jpa.core.internal.context.java.JavaJoinColumnTextRangeResolver; +import org.eclipse.jpt.jpa.core.resource.java.JoinColumnAnnotation; +import org.eclipse.jpt.jpa.db.Column; +import org.eclipse.jpt.jpa.db.Table; + +/** + * Java join column + */ +public class GenericJavaJoinColumn + extends AbstractJavaBaseColumn<JoinColumnAnnotation, JavaJoinColumn.Owner> + implements JavaJoinColumn +{ + /** @see AbstractJavaNamedColumn#AbstractJavaNamedColumn(JavaJpaContextNode, org.eclipse.jpt.jpa.core.context.java.JavaNamedColumn.Owner, org.eclipse.jpt.jpa.core.resource.java.NamedColumnAnnotation) */ + protected /* final */ JoinColumnAnnotation columnAnnotation; // never null + + protected String specifiedReferencedColumnName; + protected String defaultReferencedColumnName; + + + public GenericJavaJoinColumn(JavaJpaContextNode parent, JavaJoinColumn.Owner owner) { + this(parent, owner, null); + } + + public GenericJavaJoinColumn(JavaJpaContextNode parent, JavaJoinColumn.Owner owner, JoinColumnAnnotation columnAnnotation) { + super(parent, owner, columnAnnotation); + this.specifiedReferencedColumnName = this.buildSpecifiedReferencedColumnName(); + } + + + // ********** synchronize/update ********** + + @Override + public void synchronizeWithResourceModel() { + super.synchronizeWithResourceModel(); + this.setSpecifiedReferencedColumnName_(this.buildSpecifiedReferencedColumnName()); + } + + @Override + public void update() { + super.update(); + this.setDefaultReferencedColumnName(this.buildDefaultReferencedColumnName()); + } + + + // ********** column annotation ********** + + @Override + public JoinColumnAnnotation getColumnAnnotation() { + return this.columnAnnotation; + } + + @Override + protected void setColumnAnnotation(JoinColumnAnnotation columnAnnotation) { + this.columnAnnotation = columnAnnotation; + } + + @Override + protected void removeColumnAnnotation() { + // we don't remove a join column annotation when it is empty + } + + + // ********** referenced column name ********** + + public String getReferencedColumnName() { + return (this.specifiedReferencedColumnName != null) ? this.specifiedReferencedColumnName : this.defaultReferencedColumnName; + } + + public String getSpecifiedReferencedColumnName() { + return this.specifiedReferencedColumnName; + } + + public void setSpecifiedReferencedColumnName(String name) { + if (this.valuesAreDifferent(this.specifiedReferencedColumnName, name)) { + this.getColumnAnnotation().setReferencedColumnName(name); + this.removeColumnAnnotationIfUnset(); + this.setSpecifiedReferencedColumnName_(name); + } + } + + protected void setSpecifiedReferencedColumnName_(String name) { + String old = this.specifiedReferencedColumnName; + this.specifiedReferencedColumnName = name; + this.firePropertyChanged(SPECIFIED_REFERENCED_COLUMN_NAME_PROPERTY, old, name); + } + + protected String buildSpecifiedReferencedColumnName() { + return this.getColumnAnnotation().getReferencedColumnName(); + } + + public String getDefaultReferencedColumnName() { + return this.defaultReferencedColumnName; + } + + protected void setDefaultReferencedColumnName(String name) { + String old = this.defaultReferencedColumnName; + this.defaultReferencedColumnName = name; + this.firePropertyChanged(DEFAULT_REFERENCED_COLUMN_NAME_PROPERTY, old, name); + } + + protected String buildDefaultReferencedColumnName() { + return MappingTools.buildJoinColumnDefaultReferencedColumnName(this.owner); + } + + public TextRange getReferencedColumnNameTextRange(CompilationUnit astRoot) { + TextRange textRange = this.getColumnAnnotation().getReferencedColumnNameTextRange(astRoot); + return (textRange != null) ? textRange : this.owner.getValidationTextRange(astRoot); + } + + + // ********** database stuff ********** + + public Table getReferencedColumnDbTable() { + return this.owner.getReferencedColumnDbTable(); + } + + protected Column getReferencedDbColumn() { + Table table = this.getReferencedColumnDbTable(); + return (table == null) ? null : table.getColumnForIdentifier(this.getReferencedColumnName()); + } + + public boolean referencedColumnIsResolved() { + return this.getReferencedDbColumn() != null; + } + + + // ********** misc ********** + + public void initializeFrom(ReadOnlyJoinColumn oldColumn) { + super.initializeFrom(oldColumn); + this.setSpecifiedReferencedColumnName(oldColumn.getSpecifiedReferencedColumnName()); + } + + public void initializeFromVirtual(ReadOnlyJoinColumn virtualColumn) { + super.initializeFromVirtual(virtualColumn); + this.setSpecifiedReferencedColumnName(virtualColumn.getReferencedColumnName()); + } + + public boolean isDefault() { + return this.owner.joinColumnIsDefault(this); + } + + @Override + protected String buildDefaultName() { + return MappingTools.buildJoinColumnDefaultName(this, this.owner); + } + + + // ********** Java completion proposals ********** + + @Override + public Iterator<String> connectedJavaCompletionProposals(int pos, Filter<String> filter, CompilationUnit astRoot) { + Iterator<String> result = super.connectedJavaCompletionProposals(pos, filter, astRoot); + if (result != null) { + return result; + } + if (this.referencedColumnNameTouches(pos, astRoot)) { + return this.getJavaCandidateReferencedColumnNames(filter).iterator(); + } + return null; + } + + protected boolean referencedColumnNameTouches(int pos, CompilationUnit astRoot) { + return this.getColumnAnnotation().referencedColumnNameTouches(pos, astRoot); + } + + protected Iterable<String> getJavaCandidateReferencedColumnNames(Filter<String> filter) { + return StringTools.convertToJavaStringLiterals(this.getCandidateReferencedColumnNames(filter)); + } + + protected Iterable<String> getCandidateReferencedColumnNames(Filter<String> filter) { + return new FilteringIterable<String>(this.getCandidateReferencedColumnNames(), filter); + } + + protected Iterable<String> getCandidateReferencedColumnNames() { + Table table = this.owner.getReferencedColumnDbTable(); + return (table != null) ? table.getSortedColumnIdentifiers() : EmptyIterable.<String> instance(); + } + + + // ********** validation ********** + + @Override + protected NamedColumnTextRangeResolver buildTextRangeResolver(CompilationUnit astRoot) { + return new JavaJoinColumnTextRangeResolver(this, astRoot); + } +} diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaJoinTable.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaJoinTable.java new file mode 100644 index 0000000000..cc6254661b --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaJoinTable.java @@ -0,0 +1,496 @@ +/******************************************************************************* + * Copyright (c) 2007, 2011 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.jpa1.context.java; + +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; +import java.util.Vector; +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jpt.common.core.utility.TextRange; +import org.eclipse.jpt.common.utility.Filter; +import org.eclipse.jpt.common.utility.internal.CollectionTools; +import org.eclipse.jpt.common.utility.internal.Tools; +import org.eclipse.jpt.common.utility.internal.iterables.EmptyListIterable; +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.SingleElementListIterable; +import org.eclipse.jpt.common.utility.internal.iterators.EmptyIterator; +import org.eclipse.jpt.jpa.core.context.Entity; +import org.eclipse.jpt.jpa.core.context.JoinColumn; +import org.eclipse.jpt.jpa.core.context.NamedColumn; +import org.eclipse.jpt.jpa.core.context.PersistentAttribute; +import org.eclipse.jpt.jpa.core.context.ReadOnlyBaseJoinColumn; +import org.eclipse.jpt.jpa.core.context.ReadOnlyJoinColumn; +import org.eclipse.jpt.jpa.core.context.ReadOnlyJoinTable; +import org.eclipse.jpt.jpa.core.context.RelationshipMapping; +import org.eclipse.jpt.jpa.core.context.TypeMapping; +import org.eclipse.jpt.jpa.core.context.java.JavaJoinColumn; +import org.eclipse.jpt.jpa.core.context.java.JavaJoinTable; +import org.eclipse.jpt.jpa.core.context.java.JavaJoinTableRelationshipStrategy; +import org.eclipse.jpt.jpa.core.internal.context.ContextContainerTools; +import org.eclipse.jpt.jpa.core.internal.context.JoinColumnTextRangeResolver; +import org.eclipse.jpt.jpa.core.internal.context.JptValidator; +import org.eclipse.jpt.jpa.core.internal.context.MappingTools; +import org.eclipse.jpt.jpa.core.internal.context.NamedColumnTextRangeResolver; +import org.eclipse.jpt.jpa.core.internal.resource.java.NullJoinColumnAnnotation; +import org.eclipse.jpt.jpa.core.resource.java.JoinColumnAnnotation; +import org.eclipse.jpt.jpa.core.resource.java.JoinTableAnnotation; +import org.eclipse.wst.validation.internal.provisional.core.IMessage; +import org.eclipse.wst.validation.internal.provisional.core.IReporter; + +/** + * Java join table + * <p> + * Note: The <code>JoinTable</code> annotation is one of only 2 annotations that + * can be nested outside of an array (i.e. in an <code>AssociationOverride</code> + * annotation); the other is {@link GenericJavaColumn Column}. + */ +public class GenericJavaJoinTable + extends GenericJavaReferenceTable<JoinTableAnnotation> + implements JavaJoinTable +{ + protected final Vector<JavaJoinColumn> specifiedInverseJoinColumns = new Vector<JavaJoinColumn>(); + protected final SpecifiedInverseJoinColumnContainerAdapter specifiedInverseJoinColumnContainerAdapter = new SpecifiedInverseJoinColumnContainerAdapter(); + protected final JavaJoinColumn.Owner inverseJoinColumnOwner; + + protected JavaJoinColumn defaultInverseJoinColumn; + + + public GenericJavaJoinTable(JavaJoinTableRelationshipStrategy parent, Owner owner) { + super(parent, owner); + this.inverseJoinColumnOwner = this.buildInverseJoinColumnOwner(); + this.initializeSpecifiedInverseJoinColumns(); + } + + @Override + protected JavaJoinColumn.Owner buildJoinColumnOwner() { + return new JoinColumnOwner(); + } + + + // ********** synchronize/update ********** + + @Override + public void synchronizeWithResourceModel() { + super.synchronizeWithResourceModel(); + this.syncSpecifiedInverseJoinColumns(); + if (this.defaultInverseJoinColumn != null) { + this.defaultInverseJoinColumn.synchronizeWithResourceModel(); + } + } + + @Override + public void update() { + super.update(); + this.updateNodes(this.getSpecifiedInverseJoinColumns()); + this.updateDefaultInverseJoinColumn(); + } + + + // ********** table annotation ********** + + @Override + public JoinTableAnnotation getTableAnnotation() { + return this.getRelationshipStrategy().getJoinTableAnnotation(); + } + + @Override + protected void removeTableAnnotation() { + // we don't remove a join table annotation when it is empty + } + + + // ********** inverse join columns ********** + + public ListIterator<JavaJoinColumn> inverseJoinColumns() { + return this.getInverseJoinColumns().iterator(); + } + + protected ListIterable<JavaJoinColumn> getInverseJoinColumns() { + return this.hasSpecifiedInverseJoinColumns() ? this.getSpecifiedInverseJoinColumns() : this.getDefaultInverseJoinColumns(); + } + + public int inverseJoinColumnsSize() { + return this.hasSpecifiedInverseJoinColumns() ? this.specifiedInverseJoinColumnsSize() : this.defaultInverseJoinColumnsSize(); + } + + public void convertDefaultToSpecifiedInverseJoinColumn() { + MappingTools.convertJoinTableDefaultToSpecifiedInverseJoinColumn(this); + } + + + // ********** specified inverse join columns ********** + + public ListIterator<JavaJoinColumn> specifiedInverseJoinColumns() { + return this.getSpecifiedInverseJoinColumns().iterator(); + } + + public ListIterable<JavaJoinColumn> getSpecifiedInverseJoinColumns() { + return new LiveCloneListIterable<JavaJoinColumn>(this.specifiedInverseJoinColumns); + } + + public int specifiedInverseJoinColumnsSize() { + return this.specifiedInverseJoinColumns.size(); + } + + public boolean hasSpecifiedInverseJoinColumns() { + return this.specifiedInverseJoinColumns.size() != 0; + } + + public JavaJoinColumn getSpecifiedInverseJoinColumn(int index) { + return this.specifiedInverseJoinColumns.get(index); + } + + public JavaJoinColumn addSpecifiedInverseJoinColumn() { + return this.addSpecifiedInverseJoinColumn(this.specifiedInverseJoinColumns.size()); + } + + public JavaJoinColumn addSpecifiedInverseJoinColumn(int index) { + JoinColumnAnnotation annotation = this.getTableAnnotation().addInverseJoinColumn(index); + return this.addSpecifiedInverseJoinColumn_(index, annotation); + } + + public void removeSpecifiedInverseJoinColumn(JoinColumn joinColumn) { + this.removeSpecifiedInverseJoinColumn(this.specifiedInverseJoinColumns.indexOf(joinColumn)); + } + + public void removeSpecifiedInverseJoinColumn(int index) { + this.getTableAnnotation().removeInverseJoinColumn(index); + this.removeTableAnnotationIfUnset(); + this.removeSpecifiedInverseJoinColumn_(index); + } + + protected void removeSpecifiedInverseJoinColumn_(int index) { + this.removeItemFromList(index, this.specifiedInverseJoinColumns, SPECIFIED_INVERSE_JOIN_COLUMNS_LIST); + } + + public void moveSpecifiedInverseJoinColumn(int targetIndex, int sourceIndex) { + this.getTableAnnotation().moveInverseJoinColumn(targetIndex, sourceIndex); + this.moveItemInList(targetIndex, sourceIndex, this.specifiedInverseJoinColumns, SPECIFIED_INVERSE_JOIN_COLUMNS_LIST); + } + + public void clearSpecifiedInverseJoinColumns() { + // for now, we have to remove annotations one at a time... + for (int i = this.specifiedInverseJoinColumns.size(); i-- > 0; ) { + this.removeSpecifiedInverseJoinColumn(i); + } + } + + protected void initializeSpecifiedInverseJoinColumns() { + for (JoinColumnAnnotation joinColumnAnnotation : this.getInverseJoinColumnAnnotations()) { + this.specifiedInverseJoinColumns.add(this.buildInverseJoinColumn(joinColumnAnnotation)); + } + } + + protected void syncSpecifiedInverseJoinColumns() { + ContextContainerTools.synchronizeWithResourceModel(this.specifiedInverseJoinColumnContainerAdapter); + } + + protected Iterable<JoinColumnAnnotation> getInverseJoinColumnAnnotations() { + return CollectionTools.iterable(this.getTableAnnotation().inverseJoinColumns()); + } + + protected void moveSpecifiedInverseJoinColumn_(int index, JavaJoinColumn joinColumn) { + this.moveItemInList(index, joinColumn, this.specifiedInverseJoinColumns, SPECIFIED_INVERSE_JOIN_COLUMNS_LIST); + } + + protected JavaJoinColumn addSpecifiedInverseJoinColumn_(int index, JoinColumnAnnotation joinColumnAnnotation) { + JavaJoinColumn joinColumn = this.buildInverseJoinColumn(joinColumnAnnotation); + this.addItemToList(index, joinColumn, this.specifiedInverseJoinColumns, SPECIFIED_INVERSE_JOIN_COLUMNS_LIST); + return joinColumn; + } + + protected void removeSpecifiedInverseJoinColumn_(JavaJoinColumn joinColumn) { + this.removeSpecifiedInverseJoinColumn_(this.specifiedInverseJoinColumns.indexOf(joinColumn)); + } + + /** + * specified inverse join column container adapter + */ + protected class SpecifiedInverseJoinColumnContainerAdapter + implements ContextContainerTools.Adapter<JavaJoinColumn, JoinColumnAnnotation> + { + public Iterable<JavaJoinColumn> getContextElements() { + return GenericJavaJoinTable.this.getSpecifiedInverseJoinColumns(); + } + public Iterable<JoinColumnAnnotation> getResourceElements() { + return GenericJavaJoinTable.this.getInverseJoinColumnAnnotations(); + } + public JoinColumnAnnotation getResourceElement(JavaJoinColumn contextElement) { + return contextElement.getColumnAnnotation(); + } + public void moveContextElement(int index, JavaJoinColumn element) { + GenericJavaJoinTable.this.moveSpecifiedInverseJoinColumn_(index, element); + } + public void addContextElement(int index, JoinColumnAnnotation resourceElement) { + GenericJavaJoinTable.this.addSpecifiedInverseJoinColumn_(index, resourceElement); + } + public void removeContextElement(JavaJoinColumn element) { + GenericJavaJoinTable.this.removeSpecifiedInverseJoinColumn_(element); + } + } + + protected JavaJoinColumn.Owner buildInverseJoinColumnOwner() { + return new InverseJoinColumnOwner(); + } + + + // ********** default inverse join column ********** + + public JavaJoinColumn getDefaultInverseJoinColumn() { + return this.defaultInverseJoinColumn; + } + + protected void setDefaultInverseJoinColumn(JavaJoinColumn joinColumn) { + JavaJoinColumn old = this.defaultInverseJoinColumn; + this.defaultInverseJoinColumn = joinColumn; + this.firePropertyChanged(DEFAULT_INVERSE_JOIN_COLUMN, old, joinColumn); + } + + protected ListIterable<JavaJoinColumn> getDefaultInverseJoinColumns() { + return (this.defaultInverseJoinColumn != null) ? + new SingleElementListIterable<JavaJoinColumn>(this.defaultInverseJoinColumn) : + EmptyListIterable.<JavaJoinColumn>instance(); + } + + protected int defaultInverseJoinColumnsSize() { + return (this.defaultInverseJoinColumn == null) ? 0 : 1; + } + + protected void updateDefaultInverseJoinColumn() { + if (this.buildsDefaultInverseJoinColumn()) { + if (this.defaultInverseJoinColumn == null) { + this.setDefaultInverseJoinColumn(this.buildInverseJoinColumn(new NullJoinColumnAnnotation(this.getTableAnnotation()))); + } else { + this.defaultInverseJoinColumn.update(); + } + } else { + this.setDefaultInverseJoinColumn(null); + } + } + + protected boolean buildsDefaultInverseJoinColumn() { + return ! this.hasSpecifiedInverseJoinColumns(); + } + + + // ********** misc ********** + + @Override + public JavaJoinTableRelationshipStrategy getParent() { + return (JavaJoinTableRelationshipStrategy) super.getParent(); + } + + protected JavaJoinTableRelationshipStrategy getRelationshipStrategy() { + return this.getParent(); + } + + @Override + protected String buildDefaultName() { + return this.getRelationshipStrategy().getJoinTableDefaultName(); + } + + public void initializeFrom(ReadOnlyJoinTable oldTable) { + super.initializeFrom(oldTable); + for (ReadOnlyJoinColumn joinColumn : CollectionTools.iterable(oldTable.specifiedInverseJoinColumns())) { + this.addSpecifiedInverseJoinColumn().initializeFrom(joinColumn); + } + } + + public void initializeFromVirtual(ReadOnlyJoinTable virtualTable) { + super.initializeFromVirtual(virtualTable); + for (ReadOnlyJoinColumn joinColumn : CollectionTools.iterable(virtualTable.inverseJoinColumns())) { + this.addSpecifiedInverseJoinColumn().initializeFromVirtual(joinColumn); + } + } + + protected JavaJoinColumn buildInverseJoinColumn(JoinColumnAnnotation joinColumnAnnotation) { + return this.buildJoinColumn(this.inverseJoinColumnOwner, joinColumnAnnotation); + } + + public RelationshipMapping getRelationshipMapping() { + return this.getRelationshipStrategy().getRelationship().getMapping(); + } + + public PersistentAttribute getPersistentAttribute() { + return this.getRelationshipMapping().getPersistentAttribute(); + } + + + // ********** Java completion proposals ********** + + @Override + public Iterator<String> javaCompletionProposals(int pos, Filter<String> filter, CompilationUnit astRoot) { + Iterator<String> result = super.javaCompletionProposals(pos, filter, astRoot); + if (result != null) { + return result; + } + for (JavaJoinColumn column : CollectionTools.iterable(this.inverseJoinColumns())) { + result = column.javaCompletionProposals(pos, filter, astRoot); + if (result != null) { + return result; + } + } + return null; + } + + + // ********** validation ********** + + @Override + protected void validateJoinColumns(List<IMessage> messages, IReporter reporter, CompilationUnit astRoot) { + super.validateJoinColumns(messages, reporter, astRoot); + this.validateJoinColumns(this.inverseJoinColumns(), messages, reporter, astRoot); + } + + public boolean validatesAgainstDatabase() { + return this.getRelationshipStrategy().validatesAgainstDatabase(); + } + + + // ********** join column owners ********** + + /** + * just a little common behavior + */ + protected abstract class AbstractJoinColumnOwner + implements JavaJoinColumn.Owner + { + protected AbstractJoinColumnOwner() { + super(); + } + + public TypeMapping getTypeMapping() { + return GenericJavaJoinTable.this.getRelationshipStrategy().getRelationship().getTypeMapping(); + } + + public PersistentAttribute getPersistentAttribute() { + return GenericJavaJoinTable.this.getPersistentAttribute(); + } + + /** + * @see MappingTools#buildJoinColumnDefaultName(org.eclipse.jpt.jpa.core.context.ReadOnlyJoinColumn, org.eclipse.jpt.jpa.core.context.ReadOnlyJoinColumn.Owner) + */ + public String getDefaultColumnName() { + throw new UnsupportedOperationException(); + } + + /** + * If there is a specified table name it needs to be the same + * the default table name. the table is always the join table + */ + public boolean tableNameIsInvalid(String tableName) { + return Tools.valuesAreDifferent(this.getDefaultTableName(), tableName); + } + + /** + * the join column can only be on the join table itself + */ + public Iterator<String> candidateTableNames() { + return EmptyIterator.instance(); + } + + public org.eclipse.jpt.jpa.db.Table resolveDbTable(String tableName) { + return Tools.valuesAreEqual(GenericJavaJoinTable.this.getName(), tableName) ? + GenericJavaJoinTable.this.getDbTable() : + null; + } + + /** + * by default, the join column is, obviously, in the join table; + * not sure whether it can be anywhere else... + */ + public String getDefaultTableName() { + return GenericJavaJoinTable.this.getName(); + } + + public TextRange getValidationTextRange(CompilationUnit astRoot) { + return GenericJavaJoinTable.this.getValidationTextRange(astRoot); + } + } + + + /** + * owner for "back-pointer" join columns; + * these point at the source/owning entity + */ + protected class JoinColumnOwner + extends AbstractJoinColumnOwner + { + protected JoinColumnOwner() { + super(); + } + + public Entity getRelationshipTarget() { + return GenericJavaJoinTable.this.getRelationshipStrategy().getRelationship().getEntity(); + } + + public String getAttributeName() { + return MappingTools.getTargetAttributeName(GenericJavaJoinTable.this.getRelationshipMapping()); + } + + public org.eclipse.jpt.jpa.db.Table getReferencedColumnDbTable() { + return this.getTypeMapping().getPrimaryDbTable(); + } + + public boolean joinColumnIsDefault(ReadOnlyBaseJoinColumn joinColumn) { + return GenericJavaJoinTable.this.defaultJoinColumn == joinColumn; + } + + public int joinColumnsSize() { + return GenericJavaJoinTable.this.joinColumnsSize(); + } + + public JptValidator buildColumnValidator(NamedColumn column, NamedColumnTextRangeResolver textRangeResolver) { + return GenericJavaJoinTable.this.getParent().buildJoinTableJoinColumnValidator((JoinColumn) column, this, (JoinColumnTextRangeResolver) textRangeResolver); + } + } + + + /** + * owner for "forward-pointer" join columns; + * these point at the target/inverse entity + */ + protected class InverseJoinColumnOwner + extends AbstractJoinColumnOwner + { + protected InverseJoinColumnOwner() { + super(); + } + + public Entity getRelationshipTarget() { + RelationshipMapping relationshipMapping = GenericJavaJoinTable.this.getRelationshipMapping(); + return (relationshipMapping == null) ? null : relationshipMapping.getResolvedTargetEntity(); + } + + public String getAttributeName() { + RelationshipMapping relationshipMapping = GenericJavaJoinTable.this.getRelationshipMapping(); + return (relationshipMapping == null) ? null : relationshipMapping.getName(); + } + + public org.eclipse.jpt.jpa.db.Table getReferencedColumnDbTable() { + Entity relationshipTarget = this.getRelationshipTarget(); + return (relationshipTarget == null) ? null : relationshipTarget.getPrimaryDbTable(); + } + + public boolean joinColumnIsDefault(ReadOnlyBaseJoinColumn joinColumn) { + return GenericJavaJoinTable.this.defaultInverseJoinColumn == joinColumn; + } + + public int joinColumnsSize() { + return GenericJavaJoinTable.this.inverseJoinColumnsSize(); + } + + public JptValidator buildColumnValidator(NamedColumn column, NamedColumnTextRangeResolver textRangeResolver) { + return GenericJavaJoinTable.this.getParent().buildJoinTableInverseJoinColumnValidator((JoinColumn) column, this, (JoinColumnTextRangeResolver) textRangeResolver); + } + } +} diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaLobConverter.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaLobConverter.java new file mode 100644 index 0000000000..9ccb2d3b51 --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaLobConverter.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 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.jpa1.context.java; + +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jpt.common.core.utility.TextRange; +import org.eclipse.jpt.jpa.core.context.Converter; +import org.eclipse.jpt.jpa.core.context.LobConverter; +import org.eclipse.jpt.jpa.core.context.java.JavaAttributeMapping; +import org.eclipse.jpt.jpa.core.context.java.JavaLobConverter; +import org.eclipse.jpt.jpa.core.resource.java.LobAnnotation; + +public class GenericJavaLobConverter + extends AbstractJavaConverter + implements JavaLobConverter +{ + protected final LobAnnotation lobAnnotation; + + public GenericJavaLobConverter(JavaAttributeMapping parent, LobAnnotation lobAnnotation) { + super(parent); + this.lobAnnotation = lobAnnotation; + } + + + // ********** misc ********** + + public Class<? extends Converter> getType() { + return LobConverter.class; + } + + @Override + protected String getAnnotationName() { + return LobAnnotation.ANNOTATION_NAME; + } + + + // ********** validation ********** + + public TextRange getValidationTextRange(CompilationUnit astRoot) { + return this.lobAnnotation.getTextRange(astRoot); + } +} diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaManyToManyMapping.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaManyToManyMapping.java new file mode 100644 index 0000000000..935834c6d3 --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaManyToManyMapping.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright (c) 2006, 2010 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.jpa1.context.java; + +import org.eclipse.jpt.jpa.core.context.java.JavaPersistentAttribute; +import org.eclipse.jpt.jpa.core.internal.context.java.AbstractJavaManyToManyMapping; + +public class GenericJavaManyToManyMapping + extends AbstractJavaManyToManyMapping +{ + public GenericJavaManyToManyMapping(JavaPersistentAttribute parent) { + super(parent); + } +} diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaManyToOneMapping.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaManyToOneMapping.java new file mode 100644 index 0000000000..4cdc288501 --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaManyToOneMapping.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright (c) 2006, 2010 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.jpa1.context.java; + +import org.eclipse.jpt.jpa.core.context.java.JavaPersistentAttribute; +import org.eclipse.jpt.jpa.core.internal.context.java.AbstractJavaManyToOneMapping; + +public class GenericJavaManyToOneMapping + extends AbstractJavaManyToOneMapping +{ + public GenericJavaManyToOneMapping(JavaPersistentAttribute parent) { + super(parent); + } +} diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaMappedSuperclass.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaMappedSuperclass.java new file mode 100644 index 0000000000..36d734b5b4 --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaMappedSuperclass.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2006, 2010 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.jpa1.context.java; + +import org.eclipse.jpt.jpa.core.context.java.JavaPersistentType; +import org.eclipse.jpt.jpa.core.internal.context.java.AbstractJavaMappedSuperclass; +import org.eclipse.jpt.jpa.core.resource.java.MappedSuperclassAnnotation; + +/** + * Java mapped superclass + */ +public class GenericJavaMappedSuperclass + extends AbstractJavaMappedSuperclass +{ + public GenericJavaMappedSuperclass(JavaPersistentType parent, MappedSuperclassAnnotation mappingAnnotation) { + super(parent, mappingAnnotation); + } +} diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaMappingJoinTableRelationshipStrategy.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaMappingJoinTableRelationshipStrategy.java new file mode 100644 index 0000000000..f411dfbf43 --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaMappingJoinTableRelationshipStrategy.java @@ -0,0 +1,97 @@ +/******************************************************************************* + * Copyright (c) 2009, 2011 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.jpa1.context.java; + +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jpt.common.core.utility.TextRange; +import org.eclipse.jpt.jpa.core.context.JoinColumn; +import org.eclipse.jpt.jpa.core.context.JoinTable; +import org.eclipse.jpt.jpa.core.context.Table; +import org.eclipse.jpt.jpa.core.context.JoinColumn.Owner; +import org.eclipse.jpt.jpa.core.context.java.JavaMappingJoinTableRelationship; +import org.eclipse.jpt.jpa.core.internal.context.JoinColumnTextRangeResolver; +import org.eclipse.jpt.jpa.core.internal.context.JptValidator; +import org.eclipse.jpt.jpa.core.internal.context.TableTextRangeResolver; +import org.eclipse.jpt.jpa.core.internal.context.java.AbstractJavaJoinTableRelationshipStrategy; +import org.eclipse.jpt.jpa.core.internal.jpa1.context.InverseJoinColumnValidator; +import org.eclipse.jpt.jpa.core.internal.jpa1.context.JoinColumnValidator; +import org.eclipse.jpt.jpa.core.internal.jpa1.context.JoinTableTableDescriptionProvider; +import org.eclipse.jpt.jpa.core.internal.jpa1.context.JoinTableValidator; +import org.eclipse.jpt.jpa.core.resource.java.JavaResourcePersistentAttribute; +import org.eclipse.jpt.jpa.core.resource.java.JoinTableAnnotation; + +public class GenericJavaMappingJoinTableRelationshipStrategy + extends AbstractJavaJoinTableRelationshipStrategy +{ + public GenericJavaMappingJoinTableRelationshipStrategy(JavaMappingJoinTableRelationship parent) { + super(parent); + } + + + // ********** join table annotation ********** + + public JoinTableAnnotation getJoinTableAnnotation() { + return (JoinTableAnnotation) this.getResourcePersistentAttribute().getNonNullAnnotation(JoinTableAnnotation.ANNOTATION_NAME); + } + + @Override + protected JoinTableAnnotation addJoinTableAnnotation() { + return (JoinTableAnnotation) this.getResourcePersistentAttribute().addAnnotation(JoinTableAnnotation.ANNOTATION_NAME); + } + + @Override + protected void removeJoinTableAnnotation() { + this.getResourcePersistentAttribute().removeAnnotation(JoinTableAnnotation.ANNOTATION_NAME); + } + + + // ********** misc ********** + + protected JavaResourcePersistentAttribute getResourcePersistentAttribute() { + return this.getRelationship().getMapping().getResourcePersistentAttribute(); + } + + @Override + public JavaMappingJoinTableRelationship getParent() { + return (JavaMappingJoinTableRelationship) super.getParent(); + } + + @Override + public JavaMappingJoinTableRelationship getRelationship() { + return this.getParent(); + } + + public boolean isOverridable() { + return this.getJpaPlatformVariation().isJoinTableOverridable(); + } + + + // ********** validation ********** + + public boolean validatesAgainstDatabase() { + return this.getRelationshipMapping().validatesAgainstDatabase(); + } + + public TextRange getValidationTextRange(CompilationUnit astRoot) { + return this.getRelationship().getValidationTextRange(astRoot); + } + + public JptValidator buildTableValidator(Table table, TableTextRangeResolver textRangeResolver) { + return new JoinTableValidator((JoinTable) table, textRangeResolver); + } + + public JptValidator buildJoinTableJoinColumnValidator(JoinColumn column, JoinColumn.Owner owner, JoinColumnTextRangeResolver textRangeResolver) { + return new JoinColumnValidator(column, owner, textRangeResolver, new JoinTableTableDescriptionProvider()); + } + + public JptValidator buildJoinTableInverseJoinColumnValidator(JoinColumn column, Owner owner, JoinColumnTextRangeResolver textRangeResolver) { + return new InverseJoinColumnValidator(column, owner, textRangeResolver, new JoinTableTableDescriptionProvider()); + } +} diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaNamedNativeQuery.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaNamedNativeQuery.java new file mode 100644 index 0000000000..feaee86f38 --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaNamedNativeQuery.java @@ -0,0 +1,85 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 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.jpa1.context.java; + +import org.eclipse.jpt.jpa.core.context.java.JavaJpaContextNode; +import org.eclipse.jpt.jpa.core.context.java.JavaNamedNativeQuery; +import org.eclipse.jpt.jpa.core.internal.context.java.AbstractJavaQuery; +import org.eclipse.jpt.jpa.core.resource.java.NamedNativeQueryAnnotation; + +/** + * <code>orm.xml</code> named native query + */ +public class GenericJavaNamedNativeQuery + extends AbstractJavaQuery<NamedNativeQueryAnnotation> + implements JavaNamedNativeQuery +{ + protected String resultClass; + + protected String resultSetMapping; + + + public GenericJavaNamedNativeQuery(JavaJpaContextNode parent, NamedNativeQueryAnnotation queryAnnotation) { + super(parent, queryAnnotation); + this.resultClass = queryAnnotation.getResultClass(); + this.resultSetMapping = queryAnnotation.getResultSetMapping(); + } + + + // ********** synchronize/update ********** + + @Override + public void synchronizeWithResourceModel() { + super.synchronizeWithResourceModel(); + this.setResultClass_(this.queryAnnotation.getResultClass()); + this.setResultSetMapping_(this.queryAnnotation.getResultSetMapping()); + } + + + // ********** result class ********** + + public String getResultClass() { + return this.resultClass; + } + + public void setResultClass(String resultClass) { + this.queryAnnotation.setResultClass(resultClass); + this.setResultClass_(resultClass); + } + + protected void setResultClass_(String resultClass) { + String old = this.resultClass; + this.resultClass = resultClass; + this.firePropertyChanged(RESULT_CLASS_PROPERTY, old, resultClass); + } + + public char getResultClassEnclosingTypeSeparator() { + return '.'; + } + + + // ********** result set mapping ********** + + public String getResultSetMapping() { + return this.resultSetMapping; + } + + public void setResultSetMapping(String resultSetMapping) { + this.queryAnnotation.setResultSetMapping(resultSetMapping); + this.setResultSetMapping_(resultSetMapping); + } + + protected void setResultSetMapping_(String resultSetMapping) { + String old = this.resultSetMapping; + this.resultSetMapping = resultSetMapping; + this.firePropertyChanged(RESULT_SET_MAPPING_PROPERTY, old, resultSetMapping); + } + +} diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaNamedQuery.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaNamedQuery.java new file mode 100644 index 0000000000..8c22d994ed --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaNamedQuery.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 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.jpa1.context.java; + +import org.eclipse.jpt.jpa.core.context.java.JavaJpaContextNode; +import org.eclipse.jpt.jpa.core.context.java.JavaNamedQuery; +import org.eclipse.jpt.jpa.core.internal.context.java.AbstractJavaQuery; +import org.eclipse.jpt.jpa.core.resource.java.NamedQueryAnnotation; + +/** + * Java named query + */ +public class GenericJavaNamedQuery + extends AbstractJavaQuery<NamedQueryAnnotation> + implements JavaNamedQuery +{ + public GenericJavaNamedQuery(JavaJpaContextNode parent, NamedQueryAnnotation queryAnnotation) { + super(parent, queryAnnotation); + } +} diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaNullAttributeMapping.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaNullAttributeMapping.java new file mode 100644 index 0000000000..864603a34e --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaNullAttributeMapping.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2006, 2010 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.jpa1.context.java; + +import org.eclipse.jpt.jpa.core.MappingKeys; +import org.eclipse.jpt.jpa.core.context.java.JavaPersistentAttribute; +import org.eclipse.jpt.jpa.core.internal.context.java.AbstractJavaAttributeMapping; +import org.eclipse.jpt.jpa.core.jpa2.context.MetamodelField; +import org.eclipse.jpt.jpa.core.resource.java.Annotation; + +/** + * null mapping used when an attribute's default mapping cannot be determined + */ +public class GenericJavaNullAttributeMapping + extends AbstractJavaAttributeMapping<Annotation> +{ + public GenericJavaNullAttributeMapping(JavaPersistentAttribute parent) { + super(parent); + } + + public String getKey() { + return MappingKeys.NULL_ATTRIBUTE_MAPPING_KEY; + } + + @Override + protected String getAnnotationName() { + return null; + } + + + // ********** metamodel ********** + + @Override + public MetamodelField getMetamodelField() { + return null; + } +} diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaOneToManyMapping.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaOneToManyMapping.java new file mode 100644 index 0000000000..bf84573cf3 --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaOneToManyMapping.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright (c) 2006, 2010 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.jpa1.context.java; + +import org.eclipse.jpt.jpa.core.context.java.JavaPersistentAttribute; +import org.eclipse.jpt.jpa.core.internal.context.java.AbstractJavaOneToManyMapping; + +public class GenericJavaOneToManyMapping + extends AbstractJavaOneToManyMapping +{ + public GenericJavaOneToManyMapping(JavaPersistentAttribute parent) { + super(parent); + } +} diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaOneToOneMapping.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaOneToOneMapping.java new file mode 100644 index 0000000000..c2f6397a6c --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaOneToOneMapping.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 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.jpa1.context.java; + +import org.eclipse.jpt.jpa.core.context.java.JavaPersistentAttribute; +import org.eclipse.jpt.jpa.core.internal.context.java.AbstractJavaOneToOneMapping; + +public class GenericJavaOneToOneMapping + extends AbstractJavaOneToOneMapping +{ + public GenericJavaOneToOneMapping(JavaPersistentAttribute parent) { + super(parent); + } +} diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaOrderable.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaOrderable.java new file mode 100644 index 0000000000..653657946e --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaOrderable.java @@ -0,0 +1,486 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 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.jpa1.context.java; + +import java.util.Iterator; +import java.util.List; +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jpt.common.core.utility.TextRange; +import org.eclipse.jpt.common.utility.Filter; +import org.eclipse.jpt.jpa.core.context.NamedColumn; +import org.eclipse.jpt.jpa.core.context.TypeMapping; +import org.eclipse.jpt.jpa.core.context.java.JavaAttributeMapping; +import org.eclipse.jpt.jpa.core.context.java.JavaNamedColumn; +import org.eclipse.jpt.jpa.core.context.java.JavaPersistentAttribute; +import org.eclipse.jpt.jpa.core.internal.context.JptValidator; +import org.eclipse.jpt.jpa.core.internal.context.NamedColumnTextRangeResolver; +import org.eclipse.jpt.jpa.core.internal.context.java.AbstractJavaJpaContextNode; +import org.eclipse.jpt.jpa.core.internal.jpa2.context.OrderColumnValidator; +import org.eclipse.jpt.jpa.core.internal.jpa2.context.java.GenericJavaOrderColumn2_0; +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.OrderColumn2_0; +import org.eclipse.jpt.jpa.core.jpa2.context.java.JavaOrderColumn2_0; +import org.eclipse.jpt.jpa.core.jpa2.context.java.JavaOrderable2_0; +import org.eclipse.jpt.jpa.core.jpa2.resource.java.OrderColumn2_0Annotation; +import org.eclipse.jpt.jpa.core.resource.java.JavaResourcePersistentAttribute; +import org.eclipse.jpt.jpa.core.resource.java.OrderByAnnotation; +import org.eclipse.jpt.jpa.db.Table; +import org.eclipse.wst.validation.internal.provisional.core.IMessage; +import org.eclipse.wst.validation.internal.provisional.core.IReporter; + +/** + * Java ordering + * <p> + * <strong>NB:</strong> Setting any flag to <code>false</code> (or setting the + * specified "order by" to <code>null</code>) can be a bit unpredictable. The + * intent is to set a flag to <code>true</code> (or set the specified "order by" + * to a non-<code>null</code> value). + * <p> + * <strong>(JPA 2.0 only) NB:</strong> If both the "order by" and the "order + * column" annotations are present (which is prohibited by the JPA spec), + * both are ignored. + */ +public class GenericJavaOrderable + extends AbstractJavaJpaContextNode + implements JavaOrderable2_0 +{ + protected String specifiedOrderBy; + protected boolean noOrdering = false; + protected boolean pkOrdering = false; + protected boolean customOrdering = false; + + // JPA 2.0 + protected final Owner owner; // this is null for JPA 1.0 mappings + protected boolean orderColumnOrdering = false; + protected final JavaOrderColumn2_0 orderColumn; + + + /** + * JPA 1.0 + */ + public GenericJavaOrderable(JavaAttributeMapping parent) { + this(parent, null); + } + + /** + * JPA 2.0 + */ + public GenericJavaOrderable(JavaAttributeMapping parent, Owner owner) { + super(parent); + this.specifiedOrderBy = this.buildSpecifiedOrderBy(); + this.noOrdering = this.buildNoOrdering(); + this.pkOrdering = this.buildPkOrdering(); + this.customOrdering = this.buildCustomOrdering(); + + this.owner = owner; + this.orderColumnOrdering = this.buildOrderColumnOrdering(); + this.orderColumn = this.buildOrderColumn(); + } + + + // ********** synchronize/update ********** + + @Override + public void synchronizeWithResourceModel() { + super.synchronizeWithResourceModel(); + + this.setSpecifiedOrderBy_(this.buildSpecifiedOrderBy()); + this.setNoOrdering_(this.buildNoOrdering()); + this.setPkOrdering_(this.buildPkOrdering()); + this.setCustomOrdering_(this.buildCustomOrdering()); + + this.setOrderColumnOrdering_(this.buildOrderColumnOrdering()); + this.orderColumn.synchronizeWithResourceModel(); + } + + @Override + public void update() { + super.update(); + this.orderColumn.update(); + } + + + // ********** specified order by ********** + + public String getSpecifiedOrderBy() { + return this.specifiedOrderBy; + } + + public void setSpecifiedOrderBy(String orderBy) { + if (orderBy != null) { + this.removeOrderColumnAnnotation(); + this.getOrderByAnnotationForUpdate().setValue(orderBy); + + this.setSpecifiedOrderBy_(orderBy); + this.setNoOrdering_(false); + this.setPkOrdering_(false); + this.setCustomOrdering_(true); + this.setOrderColumnOrdering_(false); + } else { + this.setNoOrdering(true); // hmmm... + } + } + + protected void setSpecifiedOrderBy_(String orderBy) { + String old = this.specifiedOrderBy; + this.specifiedOrderBy = orderBy; + this.firePropertyChanged(SPECIFIED_ORDER_BY_PROPERTY, old, orderBy); + } + + protected String buildSpecifiedOrderBy() { + if (this.orderColumnAnnotationIsPresent()) { + return null; + } + OrderByAnnotation orderByAnnotation = this.getOrderByAnnotation(); + return (orderByAnnotation == null) ? null : orderByAnnotation.getValue(); + } + + + // ********** no ordering ********** + + public boolean isNoOrdering() { + return this.noOrdering; + } + + public void setNoOrdering(boolean noOrdering) { + if (noOrdering) { + this.removeOrderColumnAnnotation(); + if (this.getOrderByAnnotation() != null) { + this.removeOrderByAnnotation(); + } + + this.setSpecifiedOrderBy_(null); + this.setNoOrdering_(true); + this.setPkOrdering_(false); + this.setCustomOrdering_(false); + this.setOrderColumnOrdering_(false); + } else { + this.setPkOrdering(true); // hmmm... + } + } + + protected void setNoOrdering_(boolean noOrdering) { + boolean old = this.noOrdering; + this.noOrdering = noOrdering; + this.firePropertyChanged(NO_ORDERING_PROPERTY, old, noOrdering); + } + + protected boolean buildNoOrdering() { + return this.isJpa2_0Compatible() ? this.buildNoOrdering2_0() : this.buildNoOrdering1_0(); + } + + /** + * both annotations are missing <em>or</em> both are present + */ + protected boolean buildNoOrdering2_0() { + boolean orderByMissing = (this.getOrderByAnnotation() == null); + boolean orderByPresent = ! orderByMissing; + boolean orderColumnMissing = (this.getOrderColumnAnnotation() == null); + boolean orderColumnPresent = ! orderColumnMissing; + return (orderByMissing && orderColumnMissing) || (orderByPresent && orderColumnPresent); + } + + /** + * the order-by annotation is missing + */ + protected boolean buildNoOrdering1_0() { + return this.getOrderByAnnotation() == null; + } + + + // ********** pk ordering ********** + + public boolean isPkOrdering() { + return this.pkOrdering; + } + + public void setPkOrdering(boolean pkOrdering) { + if (pkOrdering) { + this.removeOrderColumnAnnotation(); + OrderByAnnotation orderByAnnotation = this.getOrderByAnnotation(); + if (orderByAnnotation == null) { + this.addOrderByAnnotation(); + } else { + orderByAnnotation.setValue(null); + } + + this.setSpecifiedOrderBy_(null); + this.setNoOrdering_(false); + this.setPkOrdering_(true); + this.setCustomOrdering_(false); + this.setOrderColumnOrdering_(false); + } else { + this.setNoOrdering(true); // hmmm... + } + } + + protected void setPkOrdering_(boolean pkOrdering) { + boolean old = this.pkOrdering; + this.pkOrdering = pkOrdering; + this.firePropertyChanged(PK_ORDERING_PROPERTY, old, pkOrdering); + } + + /** + * the order-by annotation is present but no value specified + */ + protected boolean buildPkOrdering() { + if (this.orderColumnAnnotationIsPresent()) { + return false; + } + OrderByAnnotation orderByAnnotation = this.getOrderByAnnotation(); + return (orderByAnnotation != null) && (orderByAnnotation.getValue() == null); + } + + + // ********** custom ordering ********** + + public boolean isCustomOrdering() { + return this.customOrdering; + } + + public void setCustomOrdering(boolean customOrdering) { + if (customOrdering) { + this.setSpecifiedOrderBy(""); //$NON-NLS-1$ + } else { + this.setNoOrdering(true); // hmmm... + } + } + + protected void setCustomOrdering_(boolean customOrdering) { + boolean old = this.customOrdering; + this.customOrdering = customOrdering; + this.firePropertyChanged(CUSTOM_ORDERING_PROPERTY, old, customOrdering); + } + + /** + * the order-by annotation is present and it has a specified value + */ + protected boolean buildCustomOrdering() { + if (this.orderColumnAnnotationIsPresent()) { + return false; + } + OrderByAnnotation orderByAnnotation = this.getOrderByAnnotation(); + return (orderByAnnotation != null) && (orderByAnnotation.getValue() != null); + } + + + // ********** order column ordering ********** + + public boolean isOrderColumnOrdering() { + return this.orderColumnOrdering; + } + + public void setOrderColumnOrdering(boolean orderColumnOrdering) { + if (orderColumnOrdering) { + this.removeOrderByAnnotation(); + if (this.getOrderColumnAnnotation() == null) { + this.addOrderColumnAnnotation(); + } + + this.setSpecifiedOrderBy_(null); + this.setNoOrdering_(false); + this.setPkOrdering_(false); + this.setCustomOrdering_(false); + this.setOrderColumnOrdering_(true); + } else { + this.setNoOrdering(true); // hmmm... + } + } + + protected void setOrderColumnOrdering_(boolean orderColumnOrdering) { + boolean old = this.orderColumnOrdering; + this.orderColumnOrdering = orderColumnOrdering; + this.firePropertyChanged(ORDER_COLUMN_ORDERING_PROPERTY, old, orderColumnOrdering); + } + + /** + * JPA 2.0 only; + * the order column annotation is present <em>and</em> + * the order-by annotation is missing + */ + protected boolean buildOrderColumnOrdering() { + return this.orderColumnAnnotationIsPresent() && + (this.getOrderByAnnotation() == null); + } + + + // ********** order column ********** + + public JavaOrderColumn2_0 getOrderColumn() { + return this.orderColumn; + } + + protected JavaOrderColumn2_0 buildOrderColumn() { + JavaNamedColumn.Owner columnOwner = new OrderColumnOwner(); + return this.isJpa2_0Compatible() ? + this.getJpaFactory2_0().buildJavaOrderColumn(this, columnOwner) : + new GenericJavaOrderColumn2_0(this, columnOwner); + } + + + // ********** order by annotation ********** + + protected OrderByAnnotation getOrderByAnnotation() { + return (OrderByAnnotation) this.getResourcePersistentAttribute().getAnnotation(OrderByAnnotation.ANNOTATION_NAME); + } + + protected OrderByAnnotation getOrderByAnnotationForUpdate() { + OrderByAnnotation annotation = this.getOrderByAnnotation(); + return (annotation != null) ? annotation : this.addOrderByAnnotation(); + } + + protected OrderByAnnotation addOrderByAnnotation() { + return (OrderByAnnotation) this.getResourcePersistentAttribute().addAnnotation(OrderByAnnotation.ANNOTATION_NAME); + } + + protected void removeOrderByAnnotation() { + this.getResourcePersistentAttribute().removeAnnotation(OrderByAnnotation.ANNOTATION_NAME); + } + + + // ********** order column annotation ********** + + protected OrderColumn2_0Annotation getOrderColumnAnnotation() { + return (OrderColumn2_0Annotation) this.getResourcePersistentAttribute().getAnnotation(OrderColumn2_0Annotation.ANNOTATION_NAME); + } + + /** + * NB: Only return <code>true</code> for JPA 2.0 mappings. + */ + protected boolean orderColumnAnnotationIsPresent() { + return this.isJpa2_0Compatible() && (this.getOrderColumnAnnotation() != null); + } + + protected OrderColumn2_0Annotation addOrderColumnAnnotation() { + return (OrderColumn2_0Annotation) this.getResourcePersistentAttribute().addAnnotation(OrderColumn2_0Annotation.ANNOTATION_NAME); + } + + protected void removeOrderColumnAnnotation() { + if (this.orderColumnAnnotationIsPresent()) { + this.removeOrderColumnAnnotation_(); + } + } + + protected void removeOrderColumnAnnotation_() { + this.getResourcePersistentAttribute().removeAnnotation(OrderColumn2_0Annotation.ANNOTATION_NAME); + } + + + // ********** misc ********** + + @Override + public JavaAttributeMapping getParent() { + return (JavaAttributeMapping) super.getParent(); + } + + protected JavaAttributeMapping getAttributeMapping() { + return this.getParent(); + } + + protected JavaPersistentAttribute getPersistentAttribute() { + return this.getAttributeMapping().getPersistentAttribute(); + } + + public JavaResourcePersistentAttribute getResourcePersistentAttribute() { + return this.getPersistentAttribute().getResourcePersistentAttribute(); + } + + // JPA 2.0 only + public String getDefaultTableName() { + return this.owner.getTableName(); + } + + // JPA 2.0 only + protected Table resolveDbTable(String tableName) { + return this.owner.resolveDbTable(tableName); + } + + + // ********** Java completion proposals ********** + + @Override + public Iterator<String> javaCompletionProposals(int pos, Filter<String> filter, CompilationUnit astRoot) { + Iterator<String> result = super.javaCompletionProposals(pos, filter, astRoot); + if (result != null) { + return result; + } + + return this.orderColumn.javaCompletionProposals(pos, filter, astRoot); + } + + + // ********** validation ********** + + public TextRange getValidationTextRange(CompilationUnit astRoot) { + TextRange textRange = this.getOrderByAnnotationTextRange(astRoot); + return (textRange != null) ? textRange : this.getAttributeMapping().getValidationTextRange(astRoot); + } + + protected TextRange getOrderByAnnotationTextRange(CompilationUnit astRoot) { + OrderByAnnotation orderByAnnotation = this.getOrderByAnnotation(); + return (orderByAnnotation == null) ? null : orderByAnnotation.getTextRange(astRoot); + } + + @Override + public void validate(List<IMessage> messages, IReporter reporter, CompilationUnit astRoot) { + super.validate(messages, reporter, astRoot); + if (this.orderColumnAnnotationIsPresent() && (this.getOrderByAnnotation() != null)) { + messages.add( + DefaultJpaValidationMessages.buildMessage( + IMessage.HIGH_SEVERITY, + JpaValidationMessages.ORDER_COLUMN_AND_ORDER_BY_BOTH_SPECIFIED, + new String[] {this.getPersistentAttribute().getName()}, + this.getAttributeMapping(), + this.getOrderByAnnotationTextRange(astRoot) + ) + ); + } + if (this.orderColumnOrdering) { + //TODO validation message if type is not List + this.orderColumn.validate(messages, reporter, astRoot); + } + } + + + // ********** order column owner (JPA 2.0) ********** + + protected class OrderColumnOwner + implements JavaNamedColumn.Owner + { + public String getDefaultTableName() { + return GenericJavaOrderable.this.getDefaultTableName(); + } + + public Table resolveDbTable(String tableName) { + return GenericJavaOrderable.this.resolveDbTable(tableName); + } + + public String getDefaultColumnName() { + return this.getPersistentAttribute().getName() + "_ORDER"; //$NON-NLS-1$ + } + + public TypeMapping getTypeMapping() { + return this.getPersistentAttribute().getOwningTypeMapping(); + } + + public TextRange getValidationTextRange(CompilationUnit astRoot) { + return GenericJavaOrderable.this.getValidationTextRange(astRoot); + } + + public JptValidator buildColumnValidator(NamedColumn column, NamedColumnTextRangeResolver textRangeResolver) { + return new OrderColumnValidator((OrderColumn2_0) column, textRangeResolver); + } + + protected JavaPersistentAttribute getPersistentAttribute() { + return GenericJavaOrderable.this.getPersistentAttribute(); + } + } +} diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaOverrideRelationship.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaOverrideRelationship.java new file mode 100644 index 0000000000..e6804dbb4f --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaOverrideRelationship.java @@ -0,0 +1,247 @@ +/******************************************************************************* + * Copyright (c) 2009, 2011 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.jpa1.context.java; + +import java.util.Iterator; +import java.util.List; +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jpt.common.core.utility.TextRange; +import org.eclipse.jpt.common.utility.Filter; +import org.eclipse.jpt.jpa.core.context.Entity; +import org.eclipse.jpt.jpa.core.context.MappedByRelationship; +import org.eclipse.jpt.jpa.core.context.OverrideRelationship; +import org.eclipse.jpt.jpa.core.context.ReadOnlyJoinColumnRelationship; +import org.eclipse.jpt.jpa.core.context.ReadOnlyJoinTableRelationship; +import org.eclipse.jpt.jpa.core.context.ReadOnlyOverrideRelationship; +import org.eclipse.jpt.jpa.core.context.ReadOnlyRelationship; +import org.eclipse.jpt.jpa.core.context.Relationship; +import org.eclipse.jpt.jpa.core.context.RelationshipMapping; +import org.eclipse.jpt.jpa.core.context.TypeMapping; +import org.eclipse.jpt.jpa.core.context.java.JavaAssociationOverride; +import org.eclipse.jpt.jpa.core.context.java.JavaJoinColumnRelationshipStrategy; +import org.eclipse.jpt.jpa.core.context.java.JavaJoinTableRelationshipStrategy; +import org.eclipse.jpt.jpa.core.context.java.JavaRelationshipStrategy; +import org.eclipse.jpt.jpa.core.internal.context.java.AbstractJavaJpaContextNode; +import org.eclipse.jpt.jpa.core.internal.context.java.GenericJavaOverrideJoinColumnRelationshipStrategy; +import org.eclipse.jpt.jpa.core.internal.jpa2.context.java.GenericJavaOverrideJoinTableRelationshipStrategy2_0; +import org.eclipse.jpt.jpa.core.jpa2.context.java.JavaOverrideRelationship2_0; +import org.eclipse.wst.validation.internal.provisional.core.IMessage; +import org.eclipse.wst.validation.internal.provisional.core.IReporter; + +public class GenericJavaOverrideRelationship + extends AbstractJavaJpaContextNode + implements JavaOverrideRelationship2_0 +{ + protected JavaRelationshipStrategy strategy; + + protected final JavaJoinColumnRelationshipStrategy joinColumnStrategy; + + // JPA 2.0 + protected final JavaJoinTableRelationshipStrategy joinTableStrategy; + + + public GenericJavaOverrideRelationship(JavaAssociationOverride parent) { + super(parent); + this.joinColumnStrategy = this.buildJoinColumnStrategy(); + this.joinTableStrategy = this.buildJoinTableStrategy(); + } + + + // ********** synchronize/update ********** + + @Override + public void synchronizeWithResourceModel() { + super.synchronizeWithResourceModel(); + this.joinColumnStrategy.synchronizeWithResourceModel(); + this.joinTableStrategy.synchronizeWithResourceModel(); + } + + @Override + public void update() { + super.update(); + this.setStrategy(this.buildStrategy()); + this.joinColumnStrategy.update(); + this.joinTableStrategy.update(); + } + + + // ********** strategy ********** + + public JavaRelationshipStrategy getStrategy() { + return this.strategy; + } + + protected void setStrategy(JavaRelationshipStrategy strategy) { + JavaRelationshipStrategy old = this.strategy; + this.strategy = strategy; + this.firePropertyChanged(STRATEGY_PROPERTY, old, strategy); + } + + protected JavaRelationshipStrategy buildStrategy() { + if (this.isJpa2_0Compatible()) { + if (this.joinColumnStrategy.hasSpecifiedJoinColumns()) { + return this.joinColumnStrategy; + } + return this.joinTableStrategy; + } + return this.joinColumnStrategy; + } + + + // ********** join column strategy ********** + + public JavaJoinColumnRelationshipStrategy getJoinColumnStrategy() { + return this.joinColumnStrategy; + } + + public boolean strategyIsJoinColumn() { + return this.strategy == this.joinColumnStrategy; + } + + public void setStrategyToJoinColumn() { + this.joinColumnStrategy.addStrategy(); + this.joinTableStrategy.removeStrategy(); + } + + public boolean mayHaveDefaultJoinColumn() { + return false; + } + + protected JavaJoinColumnRelationshipStrategy buildJoinColumnStrategy() { + return new GenericJavaOverrideJoinColumnRelationshipStrategy(this); + } + + + // ********** join table strategy ********** + + public JavaJoinTableRelationshipStrategy getJoinTableStrategy() { + return this.joinTableStrategy; + } + + public boolean strategyIsJoinTable() { + return this.strategy == this.joinTableStrategy; + } + + public void setStrategyToJoinTable() { + this.joinTableStrategy.addStrategy(); + this.joinColumnStrategy.removeStrategy(); + } + + public boolean mayHaveDefaultJoinTable() { + return this.isVirtual() && this.strategyIsJoinTable(); + } + + protected JavaJoinTableRelationshipStrategy buildJoinTableStrategy() { + return this.isJpa2_0Compatible() ? + new GenericJavaOverrideJoinTableRelationshipStrategy2_0(this) : + new NullJavaJoinTableRelationshipStrategy(this); + } + + + // ********** conversions ********** + + public void initializeFrom(ReadOnlyRelationship oldRelationship) { + oldRelationship.initializeOn(this); + } + + public void initializeOn(Relationship newRelationship) { + newRelationship.initializeFromJoinTableRelationship(this); + newRelationship.initializeFromJoinColumnRelationship(this); + } + + public void initializeFromMappedByRelationship(MappedByRelationship oldRelationship) { + // NOP + } + + public void initializeFromJoinTableRelationship(ReadOnlyJoinTableRelationship oldRelationship) { + this.joinTableStrategy.initializeFrom(oldRelationship.getJoinTableStrategy()); + } + + public void initializeFromJoinColumnRelationship(ReadOnlyJoinColumnRelationship oldRelationship) { + this.joinColumnStrategy.initializeFrom(oldRelationship.getJoinColumnStrategy()); + } + + public void initializeFromVirtual(ReadOnlyOverrideRelationship virtualRelationship) { + virtualRelationship.initializeOnSpecified(this); + } + + public void initializeOnSpecified(OverrideRelationship specifiedRelationship) { + throw new UnsupportedOperationException(); + } + + public void initializeFromVirtualJoinTableRelationship(ReadOnlyJoinTableRelationship virtualRelationship) { + this.joinTableStrategy.initializeFromVirtual(virtualRelationship.getJoinTableStrategy()); + } + + public void initializeFromVirtualJoinColumnRelationship(ReadOnlyJoinColumnRelationship virtualRelationship) { + this.joinColumnStrategy.initializeFromVirtual(virtualRelationship.getJoinColumnStrategy()); + } + + + // ********** misc ********** + + @Override + public JavaAssociationOverride getParent() { + return (JavaAssociationOverride) super.getParent(); + } + + public JavaAssociationOverride getAssociationOverride() { + return this.getParent(); + } + + public TypeMapping getTypeMapping() { + return this.getAssociationOverride().getContainer().getTypeMapping(); + } + + public Entity getEntity() { + TypeMapping typeMapping = this.getTypeMapping(); + return (typeMapping instanceof Entity) ? (Entity) typeMapping : null; + } + + public boolean isVirtual() { + return false; + } + + public RelationshipMapping getMapping() { + return this.getAssociationOverride().getMapping(); + } + + + // ********** Java completion proposals ********** + + @Override + public Iterator<String> javaCompletionProposals(int pos, Filter<String> filter, CompilationUnit astRoot) { + Iterator<String> result = super.javaCompletionProposals(pos, filter, astRoot); + if (result != null) { + return result; + } + + result = this.joinColumnStrategy.javaCompletionProposals(pos, filter, astRoot); + if (result != null) { + return result; + } + + return this.joinTableStrategy.javaCompletionProposals(pos, filter, astRoot); + } + + + // ********** validation ********** + + public TextRange getValidationTextRange(CompilationUnit astRoot) { + return this.getAssociationOverride().getValidationTextRange(astRoot); + } + + @Override + public void validate(List<IMessage> messages, IReporter reporter, CompilationUnit astRoot) { + super.validate(messages, reporter, astRoot); + this.joinColumnStrategy.validate(messages, reporter, astRoot); + this.joinTableStrategy.validate(messages, reporter, astRoot); + } +} diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaPersistentAttribute.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaPersistentAttribute.java new file mode 100644 index 0000000000..21dd9cd90e --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaPersistentAttribute.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright (c) 2006, 2010 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.jpa1.context.java; + +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jpt.jpa.core.context.AccessType; +import org.eclipse.jpt.jpa.core.context.PersistentType; +import org.eclipse.jpt.jpa.core.internal.context.JptValidator; +import org.eclipse.jpt.jpa.core.internal.context.java.AbstractJavaPersistentAttribute; +import org.eclipse.jpt.jpa.core.internal.jpa1.context.GenericPersistentAttributeValidator; +import org.eclipse.jpt.jpa.core.resource.java.JavaResourcePersistentAttribute; + +/** + * Generic Java persistent attribute + */ +public class GenericJavaPersistentAttribute + extends AbstractJavaPersistentAttribute +{ + + public GenericJavaPersistentAttribute(PersistentType parent, JavaResourcePersistentAttribute jrpa) { + super(parent, jrpa); + } + + + // ********** access ********** + + /** + * JPA 1.0 does not support specified access, so we return <code>null</code>. + */ + @Override + public AccessType getSpecifiedAccess() { + return null; + } + + public void setSpecifiedAccess(AccessType access) { + throw new UnsupportedOperationException(); + } + + // ********** validation ********** + + @Override + protected JptValidator buildAttibuteValidator(CompilationUnit astRoot) { + return new GenericPersistentAttributeValidator(this, this, buildTextRangeResolver(astRoot)); + } +} diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaPersistentType.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaPersistentType.java new file mode 100644 index 0000000000..b66d1aecf2 --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaPersistentType.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2006, 2010 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.jpa1.context.java; + +import org.eclipse.jpt.jpa.core.context.AccessType; +import org.eclipse.jpt.jpa.core.context.PersistentType; +import org.eclipse.jpt.jpa.core.internal.context.java.AbstractJavaPersistentType; +import org.eclipse.jpt.jpa.core.resource.java.JavaResourcePersistentType; + +/** + * JPA 1.0 Java persistent type. + * The specified access is always null. + */ +public class GenericJavaPersistentType + extends AbstractJavaPersistentType +{ + public GenericJavaPersistentType(PersistentType.Owner parent, JavaResourcePersistentType jrpt) { + super(parent, jrpt); + } + + + // ********** access ********** + + /** + * Return <code>null</code> - JPA 1.0 does not support a specified access. + */ + @Override + protected AccessType buildSpecifiedAccess() { + return null; + } + + /** + * JPA 1.0 does not support a specified access. + */ + public void setSpecifiedAccess(AccessType specifiedAccess) { + throw new UnsupportedOperationException(); + } +} diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaPrimaryKeyJoinColumn.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaPrimaryKeyJoinColumn.java new file mode 100644 index 0000000000..8e5c92d5c4 --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaPrimaryKeyJoinColumn.java @@ -0,0 +1,208 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 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.jpa1.context.java; + +import java.util.Iterator; +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jpt.common.core.utility.TextRange; +import org.eclipse.jpt.common.utility.Filter; +import org.eclipse.jpt.common.utility.internal.StringTools; +import org.eclipse.jpt.common.utility.internal.iterables.EmptyIterable; +import org.eclipse.jpt.common.utility.internal.iterables.FilteringIterable; +import org.eclipse.jpt.jpa.core.context.java.JavaBaseJoinColumn; +import org.eclipse.jpt.jpa.core.context.java.JavaJpaContextNode; +import org.eclipse.jpt.jpa.core.context.java.JavaPrimaryKeyJoinColumn; +import org.eclipse.jpt.jpa.core.internal.context.NamedColumnTextRangeResolver; +import org.eclipse.jpt.jpa.core.internal.context.java.AbstractJavaNamedColumn; +import org.eclipse.jpt.jpa.core.internal.context.java.JavaPrimaryKeyJoinColumnTextRangeResolver; +import org.eclipse.jpt.jpa.core.resource.java.PrimaryKeyJoinColumnAnnotation; +import org.eclipse.jpt.jpa.db.Column; +import org.eclipse.jpt.jpa.db.Table; + +/** + * Java primary key join column + */ +public class GenericJavaPrimaryKeyJoinColumn + extends AbstractJavaNamedColumn<PrimaryKeyJoinColumnAnnotation, JavaBaseJoinColumn.Owner> + implements JavaPrimaryKeyJoinColumn +{ + /** @see AbstractJavaNamedColumn#AbstractJavaNamedColumn(org.eclipse.jpt.jpa.core.context.java.JavaJpaContextNode, org.eclipse.jpt.jpa.core.context.java.JavaNamedColumn.Owner, org.eclipse.jpt.jpa.core.resource.java.NamedColumnAnnotation) */ + protected /* final */ PrimaryKeyJoinColumnAnnotation columnAnnotation; // never null + + protected String specifiedReferencedColumnName; + protected String defaultReferencedColumnName; + + + public GenericJavaPrimaryKeyJoinColumn(JavaJpaContextNode parent, JavaBaseJoinColumn.Owner owner, PrimaryKeyJoinColumnAnnotation columnAnnotation) { + super(parent, owner, columnAnnotation); + this.specifiedReferencedColumnName = this.buildSpecifiedReferencedColumnName(); + } + + + // ********** synchronize/update ********** + + @Override + public void synchronizeWithResourceModel() { + super.synchronizeWithResourceModel(); + this.setSpecifiedReferencedColumnName_(this.buildSpecifiedReferencedColumnName()); + } + + @Override + public void update() { + super.update(); + this.setDefaultReferencedColumnName(this.buildDefaultReferencedColumnName()); + } + + + // ********** column annotation ********** + + @Override + public PrimaryKeyJoinColumnAnnotation getColumnAnnotation() { + return this.columnAnnotation; + } + + @Override + protected void setColumnAnnotation(PrimaryKeyJoinColumnAnnotation columnAnnotation) { + this.columnAnnotation = columnAnnotation; + } + + @Override + protected void removeColumnAnnotation() { + // we don't remove a pk join column annotation when it is empty + } + + + // ********** referenced column name ********** + + public String getReferencedColumnName() { + return (this.specifiedReferencedColumnName != null) ? this.specifiedReferencedColumnName : this.defaultReferencedColumnName; + } + + public String getSpecifiedReferencedColumnName() { + return this.specifiedReferencedColumnName; + } + + public void setSpecifiedReferencedColumnName(String name) { + if (this.valuesAreDifferent(this.specifiedReferencedColumnName, name)) { + this.columnAnnotation.setReferencedColumnName(name); + this.removeColumnAnnotationIfUnset(); + this.setSpecifiedReferencedColumnName_(name); + } + } + + protected void setSpecifiedReferencedColumnName_(String name) { + String old = this.specifiedReferencedColumnName; + this.specifiedReferencedColumnName = name; + this.firePropertyChanged(SPECIFIED_REFERENCED_COLUMN_NAME_PROPERTY, old, name); + } + + protected String buildSpecifiedReferencedColumnName() { + return this.columnAnnotation.getReferencedColumnName(); + } + + public String getDefaultReferencedColumnName() { + return this.defaultReferencedColumnName; + } + + protected void setDefaultReferencedColumnName(String name) { + String old = this.defaultReferencedColumnName; + this.defaultReferencedColumnName = name; + this.firePropertyChanged(DEFAULT_REFERENCED_COLUMN_NAME_PROPERTY, old, name); + } + + // TODO not correct when we start supporting + // primary key join columns in 1-1 mappings + protected String buildDefaultReferencedColumnName() { + return this.buildDefaultName(); + } + + + // ********** database stuff ********** + + public Table getReferencedColumnDbTable() { + return this.owner.getReferencedColumnDbTable(); + } + + protected Column getReferencedDbColumn() { + Table table = this.getReferencedColumnDbTable(); + return (table == null) ? null : table.getColumnForIdentifier(this.getReferencedColumnName()); + } + + public boolean referencedColumnIsResolved() { + return this.getReferencedDbColumn() != null; + } + + + // ********** misc ********** + + public boolean isDefault() { + return this.owner.joinColumnIsDefault(this); + } + + @Override + public String getTable() { + return this.owner.getDefaultTableName(); + } + + + // ********** Java completion proposals ********** + + @Override + public Iterator<String> connectedJavaCompletionProposals(int pos, Filter<String> filter, CompilationUnit astRoot) { + Iterator<String> result = super.connectedJavaCompletionProposals(pos, filter, astRoot); + if (result != null) { + return result; + } + if (this.referencedColumnNameTouches(pos, astRoot)) { + return this.getJavaCandidateReferencedColumnNames(filter).iterator(); + } + return null; + } + + public boolean referencedColumnNameTouches(int pos, CompilationUnit astRoot) { + return this.columnAnnotation.referencedColumnNameTouches(pos, astRoot); + } + + protected Iterable<String> getJavaCandidateReferencedColumnNames(Filter<String> filter) { + return StringTools.convertToJavaStringLiterals(this.getCandidateReferencedColumnNames(filter)); + } + + protected Iterable<String> getCandidateReferencedColumnNames(Filter<String> filter) { + return new FilteringIterable<String>(this.getCandidateReferencedColumnNames(), filter); + } + + protected Iterable<String> getCandidateReferencedColumnNames() { + Table table = this.owner.getReferencedColumnDbTable(); + return (table != null) ? table.getSortedColumnIdentifiers() : EmptyIterable.<String> instance(); + } + + + // ********** validation ********** + + @Override + protected NamedColumnTextRangeResolver buildTextRangeResolver(CompilationUnit astRoot) { + return new JavaPrimaryKeyJoinColumnTextRangeResolver(this, astRoot); + } + + public TextRange getReferencedColumnNameTextRange(CompilationUnit astRoot) { + TextRange textRange = this.columnAnnotation.getReferencedColumnNameTextRange(astRoot); + return textRange != null ? textRange : this.getValidationTextRange(astRoot); + } + + + // ********** misc ********** + + @Override + public void toString(StringBuilder sb) { + super.toString(sb); + sb.append("=>"); //$NON-NLS-1$ + sb.append(this.getReferencedColumnName()); + } +} diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaQueryContainer.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaQueryContainer.java new file mode 100644 index 0000000000..220db7e932 --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaQueryContainer.java @@ -0,0 +1,370 @@ +/******************************************************************************* + * Copyright (c) 2009, 2010 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.jpa1.context.java; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; +import java.util.Vector; +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jpt.common.core.utility.TextRange; +import org.eclipse.jpt.common.utility.internal.CollectionTools; +import org.eclipse.jpt.common.utility.internal.StringTools; +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.SubIterableWrapper; +import org.eclipse.jpt.common.utility.internal.iterators.CompositeIterator; +import org.eclipse.jpt.jpa.core.context.NamedNativeQuery; +import org.eclipse.jpt.jpa.core.context.NamedQuery; +import org.eclipse.jpt.jpa.core.context.Query; +import org.eclipse.jpt.jpa.core.context.java.JavaJpaContextNode; +import org.eclipse.jpt.jpa.core.context.java.JavaNamedNativeQuery; +import org.eclipse.jpt.jpa.core.context.java.JavaNamedQuery; +import org.eclipse.jpt.jpa.core.context.java.JavaQuery; +import org.eclipse.jpt.jpa.core.context.java.JavaQueryContainer; +import org.eclipse.jpt.jpa.core.internal.context.ContextContainerTools; +import org.eclipse.jpt.jpa.core.internal.context.java.AbstractJavaJpaContextNode; +import org.eclipse.jpt.jpa.core.internal.validation.DefaultJpaValidationMessages; +import org.eclipse.jpt.jpa.core.internal.validation.JpaValidationMessages; +import org.eclipse.jpt.jpa.core.resource.java.NamedNativeQueriesAnnotation; +import org.eclipse.jpt.jpa.core.resource.java.NamedNativeQueryAnnotation; +import org.eclipse.jpt.jpa.core.resource.java.NamedQueriesAnnotation; +import org.eclipse.jpt.jpa.core.resource.java.NamedQueryAnnotation; +import org.eclipse.jpt.jpa.core.resource.java.NestableAnnotation; +import org.eclipse.wst.validation.internal.provisional.core.IMessage; +import org.eclipse.wst.validation.internal.provisional.core.IReporter; + +/** + * Java query container + */ +public class GenericJavaQueryContainer + extends AbstractJavaJpaContextNode + implements JavaQueryContainer +{ + protected final Owner owner; + + protected final Vector<JavaNamedQuery> namedQueries = new Vector<JavaNamedQuery>(); + protected NamedQueryContainerAdapter namedQueryContainerAdapter = new NamedQueryContainerAdapter(); + + protected final Vector<JavaNamedNativeQuery> namedNativeQueries = new Vector<JavaNamedNativeQuery>(); + protected NamedNativeQueryContainerAdapter namedNativeQueryContainerAdapter = new NamedNativeQueryContainerAdapter(); + + + public GenericJavaQueryContainer(JavaJpaContextNode parent, Owner owner) { + super(parent); + this.owner = owner; + this.initializeNamedQueries(); + this.initializeNamedNativeQueries(); + } + + + // ********** synchronize/update ********** + + @Override + public void synchronizeWithResourceModel() { + super.synchronizeWithResourceModel(); + this.syncNamedQueries(); + this.syncNamedNativeQueries(); + } + + @Override + public void update() { + super.update(); + this.updateNodes(this.getNamedQueries()); + this.updateNodes(this.getNamedNativeQueries()); + } + + + // ********** named queries ********** + + public ListIterator<JavaNamedQuery> namedQueries() { + return this.getNamedQueries().iterator(); + } + + protected ListIterable<JavaNamedQuery> getNamedQueries() { + return new LiveCloneListIterable<JavaNamedQuery>(this.namedQueries); + } + + public int namedQueriesSize() { + return this.namedQueries.size(); + } + + public JavaNamedQuery addNamedQuery() { + return this.addNamedQuery(this.namedQueries.size()); + } + + public JavaNamedQuery addNamedQuery(int index) { + NamedQueryAnnotation annotation = this.buildNamedQueryAnnotation(index); + return this.addNamedQuery_(index, annotation); + } + + protected NamedQueryAnnotation buildNamedQueryAnnotation(int index) { + return (NamedQueryAnnotation) this.owner.getResourceAnnotatedElement().addAnnotation(index, NamedQueryAnnotation.ANNOTATION_NAME, NamedQueriesAnnotation.ANNOTATION_NAME); + } + + public void removeNamedQuery(NamedQuery namedQuery) { + this.removeNamedQuery(this.namedQueries.indexOf(namedQuery)); + } + + public void removeNamedQuery(int index) { + this.owner.getResourceAnnotatedElement().removeAnnotation(index, NamedQueryAnnotation.ANNOTATION_NAME, NamedQueriesAnnotation.ANNOTATION_NAME); + this.removeNamedQuery_(index); + } + + protected void removeNamedQuery_(int index) { + this.removeItemFromList(index, this.namedQueries, NAMED_QUERIES_LIST); + } + + public void moveNamedQuery(int targetIndex, int sourceIndex) { + this.owner.getResourceAnnotatedElement().moveAnnotation(targetIndex, sourceIndex, NamedQueriesAnnotation.ANNOTATION_NAME); + this.moveItemInList(targetIndex, sourceIndex, this.namedQueries, NAMED_QUERIES_LIST); + } + + protected void initializeNamedQueries() { + for (NamedQueryAnnotation annotation : this.getNamedQueryAnnotations()) { + this.namedQueries.add(this.buildNamedQuery(annotation)); + } + } + + protected JavaNamedQuery buildNamedQuery(NamedQueryAnnotation namedQueryAnnotation) { + return this.getJpaFactory().buildJavaNamedQuery(this, namedQueryAnnotation); + } + + protected void syncNamedQueries() { + ContextContainerTools.synchronizeWithResourceModel(this.namedQueryContainerAdapter); + } + + protected Iterable<NamedQueryAnnotation> getNamedQueryAnnotations() { + return new SubIterableWrapper<NestableAnnotation, NamedQueryAnnotation>( + CollectionTools.iterable(this.namedQueryAnnotations()) + ); + } + + protected Iterator<NestableAnnotation> namedQueryAnnotations() { + return this.owner.getResourceAnnotatedElement().annotations(NamedQueryAnnotation.ANNOTATION_NAME, NamedQueriesAnnotation.ANNOTATION_NAME); + } + + protected void moveNamedQuery_(int index, JavaNamedQuery namedQuery) { + this.moveItemInList(index, namedQuery, this.namedQueries, NAMED_QUERIES_LIST); + } + + protected JavaNamedQuery addNamedQuery_(int index, NamedQueryAnnotation namedQueryAnnotation) { + JavaNamedQuery query = this.buildNamedQuery(namedQueryAnnotation); + this.addItemToList(index, query, this.namedQueries, NAMED_QUERIES_LIST); + return query; + } + + protected void removeNamedQuery_(JavaNamedQuery namedQuery) { + this.removeNamedQuery_(this.namedQueries.indexOf(namedQuery)); + } + + /** + * named query container adapter + */ + protected class NamedQueryContainerAdapter + implements ContextContainerTools.Adapter<JavaNamedQuery, NamedQueryAnnotation> + { + public Iterable<JavaNamedQuery> getContextElements() { + return GenericJavaQueryContainer.this.getNamedQueries(); + } + public Iterable<NamedQueryAnnotation> getResourceElements() { + return GenericJavaQueryContainer.this.getNamedQueryAnnotations(); + } + public NamedQueryAnnotation getResourceElement(JavaNamedQuery contextElement) { + return contextElement.getQueryAnnotation(); + } + public void moveContextElement(int index, JavaNamedQuery element) { + GenericJavaQueryContainer.this.moveNamedQuery_(index, element); + } + public void addContextElement(int index, NamedQueryAnnotation resourceElement) { + GenericJavaQueryContainer.this.addNamedQuery_(index, resourceElement); + } + public void removeContextElement(JavaNamedQuery element) { + GenericJavaQueryContainer.this.removeNamedQuery_(element); + } + } + + + // ********** named native queries ********** + + public ListIterator<JavaNamedNativeQuery> namedNativeQueries() { + return this.getNamedNativeQueries().iterator(); + } + + protected ListIterable<JavaNamedNativeQuery> getNamedNativeQueries() { + return new LiveCloneListIterable<JavaNamedNativeQuery>(this.namedNativeQueries); + } + + public int namedNativeQueriesSize() { + return this.namedNativeQueries.size(); + } + + public JavaNamedNativeQuery addNamedNativeQuery() { + return this.addNamedNativeQuery(this.namedNativeQueries.size()); + } + + public JavaNamedNativeQuery addNamedNativeQuery(int index) { + NamedNativeQueryAnnotation annotation = this.buildNamedNativeQueryAnnotation(index); + return this.addNamedNativeQuery_(index, annotation); + } + + protected NamedNativeQueryAnnotation buildNamedNativeQueryAnnotation(int index) { + return (NamedNativeQueryAnnotation) this.owner.getResourceAnnotatedElement().addAnnotation(index, NamedNativeQueryAnnotation.ANNOTATION_NAME, NamedNativeQueriesAnnotation.ANNOTATION_NAME); + } + + public void removeNamedNativeQuery(NamedNativeQuery namedNativeQuery) { + this.removeNamedNativeQuery(this.namedNativeQueries.indexOf(namedNativeQuery)); + } + + public void removeNamedNativeQuery(int index) { + this.owner.getResourceAnnotatedElement().removeAnnotation(index, NamedNativeQueryAnnotation.ANNOTATION_NAME, NamedNativeQueriesAnnotation.ANNOTATION_NAME); + this.removeNamedNativeQuery_(index); + } + + protected void removeNamedNativeQuery_(int index) { + this.removeItemFromList(index, this.namedNativeQueries, NAMED_NATIVE_QUERIES_LIST); + } + + public void moveNamedNativeQuery(int targetIndex, int sourceIndex) { + this.owner.getResourceAnnotatedElement().moveAnnotation(targetIndex, sourceIndex, NamedNativeQueriesAnnotation.ANNOTATION_NAME); + this.moveItemInList(targetIndex, sourceIndex, this.namedNativeQueries, NAMED_NATIVE_QUERIES_LIST); + } + + protected void initializeNamedNativeQueries() { + for (NamedNativeQueryAnnotation annotation : this.getNamedNativeQueryAnnotations()) { + this.namedNativeQueries.add(this.buildNamedNativeQuery(annotation)); + } + } + + protected JavaNamedNativeQuery buildNamedNativeQuery(NamedNativeQueryAnnotation namedNativeQueryAnnotation) { + return this.getJpaFactory().buildJavaNamedNativeQuery(this, namedNativeQueryAnnotation); + } + + protected void syncNamedNativeQueries() { + ContextContainerTools.synchronizeWithResourceModel(this.namedNativeQueryContainerAdapter); + } + + protected Iterable<NamedNativeQueryAnnotation> getNamedNativeQueryAnnotations() { + return new SubIterableWrapper<NestableAnnotation, NamedNativeQueryAnnotation>( + CollectionTools.iterable(this.namedNativeQueryAnnotations()) + ); + } + + protected Iterator<NestableAnnotation> namedNativeQueryAnnotations() { + return this.owner.getResourceAnnotatedElement().annotations(NamedNativeQueryAnnotation.ANNOTATION_NAME, NamedNativeQueriesAnnotation.ANNOTATION_NAME); + } + + protected void moveNamedNativeQuery_(int index, JavaNamedNativeQuery namedNativeQuery) { + this.moveItemInList(index, namedNativeQuery, this.namedNativeQueries, NAMED_NATIVE_QUERIES_LIST); + } + + protected JavaNamedNativeQuery addNamedNativeQuery_(int index, NamedNativeQueryAnnotation namedNativeQueryAnnotation) { + JavaNamedNativeQuery query = this.buildNamedNativeQuery(namedNativeQueryAnnotation); + this.addItemToList(index, query, this.namedNativeQueries, NAMED_NATIVE_QUERIES_LIST); + return query; + } + + protected void removeNamedNativeQuery_(JavaNamedNativeQuery namedNativeQuery) { + this.removeNamedNativeQuery_(this.namedNativeQueries.indexOf(namedNativeQuery)); + } + + /** + * named native query container adapter + */ + protected class NamedNativeQueryContainerAdapter + implements ContextContainerTools.Adapter<JavaNamedNativeQuery, NamedNativeQueryAnnotation> + { + public Iterable<JavaNamedNativeQuery> getContextElements() { + return GenericJavaQueryContainer.this.getNamedNativeQueries(); + } + public Iterable<NamedNativeQueryAnnotation> getResourceElements() { + return GenericJavaQueryContainer.this.getNamedNativeQueryAnnotations(); + } + public NamedNativeQueryAnnotation getResourceElement(JavaNamedNativeQuery contextElement) { + return contextElement.getQueryAnnotation(); + } + public void moveContextElement(int index, JavaNamedNativeQuery element) { + GenericJavaQueryContainer.this.moveNamedNativeQuery_(index, element); + } + public void addContextElement(int index, NamedNativeQueryAnnotation resourceElement) { + GenericJavaQueryContainer.this.addNamedNativeQuery_(index, resourceElement); + } + public void removeContextElement(JavaNamedNativeQuery element) { + GenericJavaQueryContainer.this.removeNamedNativeQuery_(element); + } + } + + + // ********** validation ********** + + @Override + public void validate(List<IMessage> messages, IReporter reporter, CompilationUnit astRoot) { + super.validate(messages, reporter, astRoot); + this.validateQueries(messages, astRoot); + } + + protected void validateQueries(List<IMessage> messages, CompilationUnit astRoot) { + for (Iterator<JavaQuery> localQueries = this.queries(); localQueries.hasNext(); ) { + JavaQuery localQuery = localQueries.next(); + String name = localQuery.getName(); + if (StringTools.stringIsEmpty(name)){ + messages.add( + DefaultJpaValidationMessages.buildMessage( + IMessage.HIGH_SEVERITY, + JpaValidationMessages.QUERY_NAME_UNDEFINED, + new String[] {}, + localQuery, + localQuery.getNameTextRange(astRoot) + ) + ); + } else { + List<String> reportedNames = new ArrayList<String>(); + for (Iterator<Query> globalQueries = this.getPersistenceUnit().queries(); globalQueries.hasNext(); ) { + if (localQuery.duplicates(globalQueries.next()) && !reportedNames.contains(name)) { + messages.add( + DefaultJpaValidationMessages.buildMessage( + IMessage.HIGH_SEVERITY, + JpaValidationMessages.QUERY_DUPLICATE_NAME, + new String[] {name}, + localQuery, + localQuery.getNameTextRange(astRoot) + ) + ); + reportedNames.add(name); + } + } + } + String query = localQuery.getQuery(); + if (StringTools.stringIsEmpty(query)){ + messages.add( + DefaultJpaValidationMessages.buildMessage( + IMessage.HIGH_SEVERITY, + JpaValidationMessages.QUERY_STATEMENT_UNDEFINED, + new String[] {name}, + localQuery, + localQuery.getNameTextRange(astRoot) + ) + ); + } + } + } + + + @SuppressWarnings("unchecked") + public Iterator<JavaQuery> queries() { + return new CompositeIterator<JavaQuery>(this.namedNativeQueries(), this.namedQueries()); + } + + public TextRange getValidationTextRange(CompilationUnit astRoot) { + return this.owner.getResourceAnnotatedElement().getTextRange(astRoot); + } + +} diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaQueryHint.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaQueryHint.java new file mode 100644 index 0000000000..ee05688b83 --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaQueryHint.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 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.jpa1.context.java; + +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jpt.common.core.utility.TextRange; +import org.eclipse.jpt.jpa.core.context.java.JavaQuery; +import org.eclipse.jpt.jpa.core.context.java.JavaQueryHint; +import org.eclipse.jpt.jpa.core.internal.context.java.AbstractJavaJpaContextNode; +import org.eclipse.jpt.jpa.core.resource.java.QueryHintAnnotation; + +/** + * Java query hing + */ +public class GenericJavaQueryHint + extends AbstractJavaJpaContextNode + implements JavaQueryHint +{ + protected final QueryHintAnnotation queryHintAnnotation; + + protected String name; + protected String value; + + + public GenericJavaQueryHint(JavaQuery parent, QueryHintAnnotation queryHintAnnotation) { + super(parent); + this.queryHintAnnotation = queryHintAnnotation; + this.name = queryHintAnnotation.getName(); + this.value = queryHintAnnotation.getValue(); + } + + + // ********** synchronize/update ********** + + @Override + public void synchronizeWithResourceModel() { + super.synchronizeWithResourceModel(); + this.setName_(this.queryHintAnnotation.getName()); + this.setValue_(this.queryHintAnnotation.getValue()); + } + + + // ********** name ********** + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.queryHintAnnotation.setName(name); + this.setName_(name); + } + + protected void setName_(String name) { + String old = this.name; + this.name = name; + this.firePropertyChanged(NAME_PROPERTY, old, name); + } + + + // ********** value ********** + + public String getValue() { + return this.value; + } + + public void setValue(String value) { + this.queryHintAnnotation.setValue(value); + this.setValue_(value); + } + + protected void setValue_(String value) { + String old = this.value; + this.value = value; + this.firePropertyChanged(VALUE_PROPERTY, old, value); + } + + + // ********** validation ********** + + public TextRange getValidationTextRange(CompilationUnit astRoot) { + return this.queryHintAnnotation.getTextRange(astRoot); + } + + + // ********** miscelleneous ********** + + public QueryHintAnnotation getQueryHintAnnotation() { + return this.queryHintAnnotation; + } + + @Override + public void toString(StringBuilder sb) { + sb.append(this.name); + } + +} diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaReferenceTable.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaReferenceTable.java new file mode 100644 index 0000000000..5f8c567183 --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaReferenceTable.java @@ -0,0 +1,317 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 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.jpa1.context.java; + +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; +import java.util.Vector; +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jpt.common.utility.Filter; +import org.eclipse.jpt.common.utility.internal.CollectionTools; +import org.eclipse.jpt.common.utility.internal.iterables.EmptyListIterable; +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.SingleElementListIterable; +import org.eclipse.jpt.jpa.core.context.JoinColumn; +import org.eclipse.jpt.jpa.core.context.ReadOnlyJoinColumn; +import org.eclipse.jpt.jpa.core.context.ReadOnlyReferenceTable; +import org.eclipse.jpt.jpa.core.context.java.JavaJoinColumn; +import org.eclipse.jpt.jpa.core.context.java.JavaJpaContextNode; +import org.eclipse.jpt.jpa.core.context.java.JavaReferenceTable; +import org.eclipse.jpt.jpa.core.internal.context.ContextContainerTools; +import org.eclipse.jpt.jpa.core.internal.context.MappingTools; +import org.eclipse.jpt.jpa.core.internal.context.java.AbstractJavaTable; +import org.eclipse.jpt.jpa.core.internal.resource.java.NullJoinColumnAnnotation; +import org.eclipse.jpt.jpa.core.resource.java.JoinColumnAnnotation; +import org.eclipse.jpt.jpa.core.resource.java.ReferenceTableAnnotation; +import org.eclipse.wst.validation.internal.provisional.core.IMessage; +import org.eclipse.wst.validation.internal.provisional.core.IReporter; + +/** + * Java join table or collection table + */ +public abstract class GenericJavaReferenceTable<A extends ReferenceTableAnnotation> + extends AbstractJavaTable<A> + implements JavaReferenceTable +{ + protected final Vector<JavaJoinColumn> specifiedJoinColumns = new Vector<JavaJoinColumn>(); + protected final SpecifiedJoinColumnContainerAdapter specifiedJoinColumnContainerAdapter = new SpecifiedJoinColumnContainerAdapter(); + protected final JavaJoinColumn.Owner joinColumnOwner; + + protected JavaJoinColumn defaultJoinColumn; + + + protected GenericJavaReferenceTable(JavaJpaContextNode parent, Owner owner) { + super(parent, owner); + this.joinColumnOwner = this.buildJoinColumnOwner(); + this.initializeSpecifiedJoinColumns(); + } + + + // ********** synchronize/update ********** + + @Override + public void synchronizeWithResourceModel() { + super.synchronizeWithResourceModel(); + this.syncSpecifiedJoinColumns(); + } + + @Override + public void update() { + super.update(); + this.updateNodes(this.getSpecifiedJoinColumns()); + this.updateDefaultJoinColumn(); + } + + + // ********** join columns ********** + + public ListIterator<JavaJoinColumn> joinColumns() { + return this.getJoinColumns().iterator(); + } + + protected ListIterable<JavaJoinColumn> getJoinColumns() { + return this.hasSpecifiedJoinColumns() ? this.getSpecifiedJoinColumns() : this.getDefaultJoinColumns(); + } + + public int joinColumnsSize() { + return this.hasSpecifiedJoinColumns() ? this.specifiedJoinColumnsSize() : this.getDefaultJoinColumnsSize(); + } + + public void convertDefaultToSpecifiedJoinColumn() { + MappingTools.convertReferenceTableDefaultToSpecifiedJoinColumn(this); + } + + + // ********** specified join columns ********** + + public ListIterator<JavaJoinColumn> specifiedJoinColumns() { + return this.getSpecifiedJoinColumns().iterator(); + } + + protected ListIterable<JavaJoinColumn> getSpecifiedJoinColumns() { + return new LiveCloneListIterable<JavaJoinColumn>(this.specifiedJoinColumns); + } + + public int specifiedJoinColumnsSize() { + return this.specifiedJoinColumns.size(); + } + + public boolean hasSpecifiedJoinColumns() { + return this.specifiedJoinColumns.size() != 0; + } + + public JavaJoinColumn getSpecifiedJoinColumn(int index) { + return this.specifiedJoinColumns.get(index); + } + + public JavaJoinColumn addSpecifiedJoinColumn() { + return this.addSpecifiedJoinColumn(this.specifiedJoinColumns.size()); + } + + public JavaJoinColumn addSpecifiedJoinColumn(int index) { + JoinColumnAnnotation annotation = this.getTableAnnotation().addJoinColumn(index); + return this.addSpecifiedJoinColumn_(index, annotation); + } + + public void removeSpecifiedJoinColumn(JoinColumn joinColumn) { + this.removeSpecifiedJoinColumn(this.specifiedJoinColumns.indexOf(joinColumn)); + } + + public void removeSpecifiedJoinColumn(int index) { + this.getTableAnnotation().removeJoinColumn(index); + this.removeTableAnnotationIfUnset(); + this.removeSpecifiedJoinColumn_(index); + } + + protected void removeSpecifiedJoinColumn_(int index) { + this.removeItemFromList(index, this.specifiedJoinColumns, SPECIFIED_JOIN_COLUMNS_LIST); + } + + public void moveSpecifiedJoinColumn(int targetIndex, int sourceIndex) { + this.getTableAnnotation().moveJoinColumn(targetIndex, sourceIndex); + this.moveItemInList(targetIndex, sourceIndex, this.specifiedJoinColumns, SPECIFIED_JOIN_COLUMNS_LIST); + } + + protected void initializeSpecifiedJoinColumns() { + for (JoinColumnAnnotation joinColumnAnnotation : this.getJoinColumnAnnotations()) { + this.specifiedJoinColumns.add(this.buildJoinColumn(joinColumnAnnotation)); + } + } + + protected void syncSpecifiedJoinColumns() { + ContextContainerTools.synchronizeWithResourceModel(this.specifiedJoinColumnContainerAdapter); + } + + protected Iterable<JoinColumnAnnotation> getJoinColumnAnnotations() { + return CollectionTools.iterable(this.getTableAnnotation().joinColumns()); + } + + protected void moveSpecifiedJoinColumn_(int index, JavaJoinColumn joinColumn) { + this.moveItemInList(index, joinColumn, this.specifiedJoinColumns, SPECIFIED_JOIN_COLUMNS_LIST); + } + + protected JavaJoinColumn addSpecifiedJoinColumn_(int index, JoinColumnAnnotation joinColumnAnnotation) { + JavaJoinColumn joinColumn = this.buildJoinColumn(joinColumnAnnotation); + this.addItemToList(index, joinColumn, this.specifiedJoinColumns, SPECIFIED_JOIN_COLUMNS_LIST); + return joinColumn; + } + + protected void removeSpecifiedJoinColumn_(JavaJoinColumn joinColumn) { + this.removeSpecifiedJoinColumn_(this.specifiedJoinColumns.indexOf(joinColumn)); + } + + /** + * specified join column container adapter + */ + protected class SpecifiedJoinColumnContainerAdapter + implements ContextContainerTools.Adapter<JavaJoinColumn, JoinColumnAnnotation> + { + public Iterable<JavaJoinColumn> getContextElements() { + return GenericJavaReferenceTable.this.getSpecifiedJoinColumns(); + } + public Iterable<JoinColumnAnnotation> getResourceElements() { + return GenericJavaReferenceTable.this.getJoinColumnAnnotations(); + } + public JoinColumnAnnotation getResourceElement(JavaJoinColumn contextElement) { + return contextElement.getColumnAnnotation(); + } + public void moveContextElement(int index, JavaJoinColumn element) { + GenericJavaReferenceTable.this.moveSpecifiedJoinColumn_(index, element); + } + public void addContextElement(int index, JoinColumnAnnotation resourceElement) { + GenericJavaReferenceTable.this.addSpecifiedJoinColumn_(index, resourceElement); + } + public void removeContextElement(JavaJoinColumn element) { + GenericJavaReferenceTable.this.removeSpecifiedJoinColumn_(element); + } + } + + protected abstract JavaJoinColumn.Owner buildJoinColumnOwner(); + + + // ********** default join column ********** + + public JavaJoinColumn getDefaultJoinColumn() { + return this.defaultJoinColumn; + } + + protected void setDefaultJoinColumn(JavaJoinColumn joinColumn) { + JavaJoinColumn old = this.defaultJoinColumn; + this.defaultJoinColumn = joinColumn; + this.firePropertyChanged(DEFAULT_JOIN_COLUMN_PROPERTY, old, joinColumn); + } + + protected ListIterable<JavaJoinColumn> getDefaultJoinColumns() { + return (this.defaultJoinColumn != null) ? + new SingleElementListIterable<JavaJoinColumn>(this.defaultJoinColumn) : + EmptyListIterable.<JavaJoinColumn>instance(); + } + + protected int getDefaultJoinColumnsSize() { + return (this.defaultJoinColumn == null) ? 0 : 1; + } + + protected void updateDefaultJoinColumn() { + if (this.buildsDefaultJoinColumn()) { + if (this.defaultJoinColumn == null) { + this.setDefaultJoinColumn(this.buildJoinColumn(new NullJoinColumnAnnotation(this.getTableAnnotation()))); + } else { + this.defaultJoinColumn.update(); + } + } else { + this.setDefaultJoinColumn(null); + } + } + + protected boolean buildsDefaultJoinColumn() { + return ! this.hasSpecifiedJoinColumns(); + } + + + // ********** misc ********** + + protected void initializeFrom(ReadOnlyReferenceTable oldTable) { + super.initializeFrom(oldTable); + for (ReadOnlyJoinColumn joinColumn : CollectionTools.iterable(oldTable.specifiedJoinColumns())) { + this.addSpecifiedJoinColumn().initializeFrom(joinColumn); + } + } + + protected void initializeFromVirtual(ReadOnlyReferenceTable virtualTable) { + super.initializeFromVirtual(virtualTable); + for (ReadOnlyJoinColumn joinColumn : CollectionTools.iterable(virtualTable.joinColumns())) { + this.addSpecifiedJoinColumn().initializeFromVirtual(joinColumn); + } + } + + protected JavaJoinColumn buildJoinColumn(JoinColumnAnnotation joinColumnAnnotation) { + return this.buildJoinColumn(this.joinColumnOwner, joinColumnAnnotation); + } + + protected JavaJoinColumn buildJoinColumn(JavaJoinColumn.Owner jcOwner, JoinColumnAnnotation joinColumnAnnotation) { + return this.getJpaFactory().buildJavaJoinColumn(this, jcOwner, joinColumnAnnotation); + } + + @Override + protected String buildDefaultSchema() { + return this.getContextDefaultSchema(); + } + + @Override + protected String buildDefaultCatalog() { + return this.getContextDefaultCatalog(); + } + + + // ********** Java completion proposals ********** + + @Override + public Iterator<String> javaCompletionProposals(int pos, Filter<String> filter, CompilationUnit astRoot) { + Iterator<String> result = super.javaCompletionProposals(pos, filter, astRoot); + if (result != null) { + return result; + } + for (JavaJoinColumn column : CollectionTools.iterable(this.joinColumns())) { + result = column.javaCompletionProposals(pos, filter, astRoot); + if (result != null) { + return result; + } + } + return null; + } + + + // ********** validation ********** + + @Override + public void validate(List<IMessage> messages, IReporter reporter, CompilationUnit astRoot) { + boolean continueValidating = this.buildTableValidator(astRoot).validate(messages, reporter); + + //join column validation will handle the check for whether to validate against the database + //some validation messages are not database specific. If the database validation for the + //table fails we will stop there and not validate the join columns at all + if (continueValidating) { + this.validateJoinColumns(messages, reporter, astRoot); + } + } + + protected void validateJoinColumns(List<IMessage> messages, IReporter reporter, CompilationUnit astRoot) { + this.validateJoinColumns(this.joinColumns(), messages, reporter, astRoot); + } + + protected void validateJoinColumns(Iterator<JavaJoinColumn> joinColumns, List<IMessage> messages, IReporter reporter, CompilationUnit astRoot) { + while (joinColumns.hasNext()) { + joinColumns.next().validate(messages, reporter, astRoot); + } + } +} + diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaSecondaryTable.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaSecondaryTable.java new file mode 100644 index 0000000000..d65b862cc4 --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaSecondaryTable.java @@ -0,0 +1,400 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 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.jpa1.context.java; + +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; +import java.util.Vector; +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jpt.common.core.utility.TextRange; +import org.eclipse.jpt.common.utility.Filter; +import org.eclipse.jpt.common.utility.internal.CollectionTools; +import org.eclipse.jpt.common.utility.internal.iterables.EmptyListIterable; +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.SingleElementListIterable; +import org.eclipse.jpt.jpa.core.context.BaseJoinColumn; +import org.eclipse.jpt.jpa.core.context.NamedColumn; +import org.eclipse.jpt.jpa.core.context.PrimaryKeyJoinColumn; +import org.eclipse.jpt.jpa.core.context.ReadOnlyBaseJoinColumn; +import org.eclipse.jpt.jpa.core.context.TypeMapping; +import org.eclipse.jpt.jpa.core.context.java.JavaBaseJoinColumn; +import org.eclipse.jpt.jpa.core.context.java.JavaEntity; +import org.eclipse.jpt.jpa.core.context.java.JavaPrimaryKeyJoinColumn; +import org.eclipse.jpt.jpa.core.context.java.JavaSecondaryTable; +import org.eclipse.jpt.jpa.core.internal.context.BaseJoinColumnTextRangeResolver; +import org.eclipse.jpt.jpa.core.internal.context.ContextContainerTools; +import org.eclipse.jpt.jpa.core.internal.context.JptValidator; +import org.eclipse.jpt.jpa.core.internal.context.NamedColumnTextRangeResolver; +import org.eclipse.jpt.jpa.core.internal.context.java.AbstractJavaTable; +import org.eclipse.jpt.jpa.core.internal.jpa1.context.SecondaryTablePrimaryKeyJoinColumnValidator; +import org.eclipse.jpt.jpa.core.internal.resource.java.NullPrimaryKeyJoinColumnAnnotation; +import org.eclipse.jpt.jpa.core.resource.java.PrimaryKeyJoinColumnAnnotation; +import org.eclipse.jpt.jpa.core.resource.java.SecondaryTableAnnotation; +import org.eclipse.jpt.jpa.db.Table; +import org.eclipse.wst.validation.internal.provisional.core.IMessage; +import org.eclipse.wst.validation.internal.provisional.core.IReporter; + +/** + * Java secondary table + */ +public class GenericJavaSecondaryTable + extends AbstractJavaTable<SecondaryTableAnnotation> + implements JavaSecondaryTable +{ + /** @see AbstractJavaTable#AbstractJavaTable(org.eclipse.jpt.jpa.core.context.java.JavaJpaContextNode, org.eclipse.jpt.jpa.core.context.Table.Owner, org.eclipse.jpt.jpa.core.resource.java.BaseTableAnnotation) */ + protected /* final */ SecondaryTableAnnotation tableAnnotation; + + protected final Vector<JavaPrimaryKeyJoinColumn> specifiedPrimaryKeyJoinColumns = new Vector<JavaPrimaryKeyJoinColumn>(); + protected final SpecifiedPrimaryKeyJoinColumnContainerAdapter specifiedPrimaryKeyJoinColumnContainerAdapter = new SpecifiedPrimaryKeyJoinColumnContainerAdapter(); + protected final JavaBaseJoinColumn.Owner primaryKeyJoinColumnOwner; + + protected JavaPrimaryKeyJoinColumn defaultPrimaryKeyJoinColumn; + + + public GenericJavaSecondaryTable(JavaEntity parent, Owner owner, SecondaryTableAnnotation tableAnnotation) { + super(parent, owner, tableAnnotation); + this.primaryKeyJoinColumnOwner = this.buildPrimaryKeyJoinColumnOwner(); + this.initializeSpecifiedPrimaryKeyJoinColumns(); + } + + + // ********** synchronize/update ********** + + @Override + public void synchronizeWithResourceModel() { + super.synchronizeWithResourceModel(); + this.syncSpecifiedPrimaryKeyJoinColumns(); + } + + @Override + public void update() { + super.update(); + this.updateNodes(this.getSpecifiedPrimaryKeyJoinColumns()); + this.updateDefaultPrimaryKeyJoinColumn(); + } + + + // ********** table annotation ********** + + @Override + public SecondaryTableAnnotation getTableAnnotation() { + return this.tableAnnotation; + } + + /** + * @see AbstractJavaTable + */ + @Override + protected void setTableAnnotation(SecondaryTableAnnotation tableAnnotation) { + this.tableAnnotation = tableAnnotation; + } + + @Override + protected void removeTableAnnotation() { + // even though its name is required, we don't remove a secondary table' + // annotation when it is empty since it is part of a list and it's not + // obvious whether this would be very user-helpful... + } + + protected String getAnnotationName() { + return SecondaryTableAnnotation.ANNOTATION_NAME; + } + + + // ********** primary key join columns ********** + + public ListIterator<JavaPrimaryKeyJoinColumn> primaryKeyJoinColumns() { + return this.getPrimaryKeyJoinColumns().iterator(); + } + + protected ListIterable<JavaPrimaryKeyJoinColumn> getPrimaryKeyJoinColumns() { + return this.hasSpecifiedPrimaryKeyJoinColumns() ? this.getSpecifiedPrimaryKeyJoinColumns() : this.getDefaultPrimaryKeyJoinColumns(); + } + + public int primaryKeyJoinColumnsSize() { + return this.hasSpecifiedPrimaryKeyJoinColumns() ? this.specifiedPrimaryKeyJoinColumnsSize() : this.getDefaultPrimaryKeyJoinColumnsSize(); + } + + + // ********** specified primary key join columns ********** + + public ListIterator<JavaPrimaryKeyJoinColumn> specifiedPrimaryKeyJoinColumns() { + return this.getSpecifiedPrimaryKeyJoinColumns().iterator(); + } + + public ListIterable<JavaPrimaryKeyJoinColumn> getSpecifiedPrimaryKeyJoinColumns() { + return new LiveCloneListIterable<JavaPrimaryKeyJoinColumn>(this.specifiedPrimaryKeyJoinColumns); + } + + public int specifiedPrimaryKeyJoinColumnsSize() { + return this.specifiedPrimaryKeyJoinColumns.size(); + } + + protected boolean hasSpecifiedPrimaryKeyJoinColumns() { + return this.specifiedPrimaryKeyJoinColumns.size() != 0; + } + + public JavaPrimaryKeyJoinColumn addSpecifiedPrimaryKeyJoinColumn() { + return this.addSpecifiedPrimaryKeyJoinColumn(this.specifiedPrimaryKeyJoinColumns.size()); + } + + public JavaPrimaryKeyJoinColumn addSpecifiedPrimaryKeyJoinColumn(int index) { + PrimaryKeyJoinColumnAnnotation annotation = this.tableAnnotation.addPkJoinColumn(index); + return this.addSpecifiedPrimaryKeyJoinColumn_(index, annotation); + } + + public void removeSpecifiedPrimaryKeyJoinColumn(PrimaryKeyJoinColumn joinColumn) { + this.removeSpecifiedPrimaryKeyJoinColumn(this.specifiedPrimaryKeyJoinColumns.indexOf(joinColumn)); + } + + public void removeSpecifiedPrimaryKeyJoinColumn(int index) { + this.tableAnnotation.removePkJoinColumn(index); + this.removeTableAnnotationIfUnset(); + this.removeSpecifiedPrimaryKeyJoinColumn_(index); + } + + protected void removeSpecifiedPrimaryKeyJoinColumn_(int index) { + this.removeItemFromList(index, this.specifiedPrimaryKeyJoinColumns, SPECIFIED_PRIMARY_KEY_JOIN_COLUMNS_LIST); + } + + public void moveSpecifiedPrimaryKeyJoinColumn(int targetIndex, int sourceIndex) { + this.tableAnnotation.movePkJoinColumn(targetIndex, sourceIndex); + this.moveItemInList(targetIndex, sourceIndex, this.specifiedPrimaryKeyJoinColumns, SPECIFIED_PRIMARY_KEY_JOIN_COLUMNS_LIST); + } + + protected void initializeSpecifiedPrimaryKeyJoinColumns() { + for (PrimaryKeyJoinColumnAnnotation annotation : this.getPrimaryKeyJoinColumnAnnotations()) { + this.specifiedPrimaryKeyJoinColumns.add(this.buildPrimaryKeyJoinColumn(annotation)); + } + } + + protected void syncSpecifiedPrimaryKeyJoinColumns() { + ContextContainerTools.synchronizeWithResourceModel(this.specifiedPrimaryKeyJoinColumnContainerAdapter); + } + + protected Iterable<PrimaryKeyJoinColumnAnnotation> getPrimaryKeyJoinColumnAnnotations() { + return CollectionTools.iterable(this.tableAnnotation.pkJoinColumns()); + } + + protected void moveSpecifiedPrimaryKeyJoinColumn_(int index, JavaPrimaryKeyJoinColumn joinColumn) { + this.moveItemInList(index, joinColumn, this.specifiedPrimaryKeyJoinColumns, SPECIFIED_PRIMARY_KEY_JOIN_COLUMNS_LIST); + } + + protected JavaPrimaryKeyJoinColumn addSpecifiedPrimaryKeyJoinColumn_(int index, PrimaryKeyJoinColumnAnnotation pkJoinColumnAnnotation) { + JavaPrimaryKeyJoinColumn joinColumn = this.buildPrimaryKeyJoinColumn(pkJoinColumnAnnotation); + this.addItemToList(index, joinColumn, this.specifiedPrimaryKeyJoinColumns, SPECIFIED_PRIMARY_KEY_JOIN_COLUMNS_LIST); + return joinColumn; + } + + protected void removeSpecifiedPrimaryKeyJoinColumn_(JavaPrimaryKeyJoinColumn joinColumn) { + this.removeSpecifiedPrimaryKeyJoinColumn_(this.specifiedPrimaryKeyJoinColumns.indexOf(joinColumn)); + } + + /** + * specified primary key join column container adapter + */ + protected class SpecifiedPrimaryKeyJoinColumnContainerAdapter + implements ContextContainerTools.Adapter<JavaPrimaryKeyJoinColumn, PrimaryKeyJoinColumnAnnotation> + { + public Iterable<JavaPrimaryKeyJoinColumn> getContextElements() { + return GenericJavaSecondaryTable.this.getSpecifiedPrimaryKeyJoinColumns(); + } + public Iterable<PrimaryKeyJoinColumnAnnotation> getResourceElements() { + return GenericJavaSecondaryTable.this.getPrimaryKeyJoinColumnAnnotations(); + } + public PrimaryKeyJoinColumnAnnotation getResourceElement(JavaPrimaryKeyJoinColumn contextElement) { + return contextElement.getColumnAnnotation(); + } + public void moveContextElement(int index, JavaPrimaryKeyJoinColumn element) { + GenericJavaSecondaryTable.this.moveSpecifiedPrimaryKeyJoinColumn_(index, element); + } + public void addContextElement(int index, PrimaryKeyJoinColumnAnnotation resourceElement) { + GenericJavaSecondaryTable.this.addSpecifiedPrimaryKeyJoinColumn_(index, resourceElement); + } + public void removeContextElement(JavaPrimaryKeyJoinColumn element) { + GenericJavaSecondaryTable.this.removeSpecifiedPrimaryKeyJoinColumn_(element); + } + } + + protected JavaBaseJoinColumn.Owner buildPrimaryKeyJoinColumnOwner() { + return new PrimaryKeyJoinColumnOwner(); + } + + + // ********** default primary key join column ********** + + public JavaPrimaryKeyJoinColumn getDefaultPrimaryKeyJoinColumn() { + return this.defaultPrimaryKeyJoinColumn; + } + + protected void setDefaultPrimaryKeyJoinColumn(JavaPrimaryKeyJoinColumn joinColumn) { + JavaPrimaryKeyJoinColumn old = this.defaultPrimaryKeyJoinColumn; + this.defaultPrimaryKeyJoinColumn = joinColumn; + this.firePropertyChanged(DEFAULT_PRIMARY_KEY_JOIN_COLUMN, old, joinColumn); + } + + protected ListIterable<JavaPrimaryKeyJoinColumn> getDefaultPrimaryKeyJoinColumns() { + return (this.defaultPrimaryKeyJoinColumn != null) ? + new SingleElementListIterable<JavaPrimaryKeyJoinColumn>(this.defaultPrimaryKeyJoinColumn) : + EmptyListIterable.<JavaPrimaryKeyJoinColumn>instance(); + } + + protected int getDefaultPrimaryKeyJoinColumnsSize() { + return (this.defaultPrimaryKeyJoinColumn == null) ? 0 : 1; + } + + protected void updateDefaultPrimaryKeyJoinColumn() { + if (this.buildsDefaultPrimaryKeyJoinColumn()) { + if (this.defaultPrimaryKeyJoinColumn == null) { + this.setDefaultPrimaryKeyJoinColumn(this.buildPrimaryKeyJoinColumn(new NullPrimaryKeyJoinColumnAnnotation(this.tableAnnotation))); + } else { + this.defaultPrimaryKeyJoinColumn.update(); + } + } else { + this.setDefaultPrimaryKeyJoinColumn(null); + } + } + + protected boolean buildsDefaultPrimaryKeyJoinColumn() { + return ! this.hasSpecifiedPrimaryKeyJoinColumns(); + } + + + // ********** misc ********** + + @Override + public JavaEntity getParent() { + return (JavaEntity) super.getParent(); + } + + protected JavaEntity getEntity() { + return this.getParent(); + } + + public boolean isVirtual() { + return false; + } + + protected JavaPrimaryKeyJoinColumn buildPrimaryKeyJoinColumn(PrimaryKeyJoinColumnAnnotation pkJoinColumnAnnotation) { + return this.getJpaFactory().buildJavaPrimaryKeyJoinColumn(this, this.primaryKeyJoinColumnOwner, pkJoinColumnAnnotation); + } + + + // ********** defaults ********** + + /** + * a secondary table doesn't have a default name + */ + @Override + protected String buildDefaultName() { + return null; + } + + @Override + protected String buildDefaultSchema() { + return this.getContextDefaultSchema(); + } + + @Override + protected String buildDefaultCatalog() { + return this.getContextDefaultCatalog(); + } + + + // ********** code completion ********** + + @Override + public Iterator<String> javaCompletionProposals(int pos, Filter<String> filter, CompilationUnit astRoot) { + Iterator<String> result = super.javaCompletionProposals(pos, filter, astRoot); + if (result != null) { + return result; + } + for (JavaPrimaryKeyJoinColumn column : CollectionTools.iterable(this.primaryKeyJoinColumns())) { + result = column.javaCompletionProposals(pos, filter, astRoot); + if (result != null) { + return result; + } + } + return null; + } + + + // ********** validation ********** + + @Override + public void validate(List<IMessage> messages, IReporter reporter, CompilationUnit astRoot) { + boolean continueValidating = this.buildTableValidator(astRoot).validate(messages, reporter); + + //join column validation will handle the check for whether to validate against the database + //some validation messages are not database specific. If the database validation for the + //table fails we will stop there and not validate the join columns at all + if (continueValidating) { + for (Iterator<JavaPrimaryKeyJoinColumn> stream = this.primaryKeyJoinColumns(); stream.hasNext(); ) { + stream.next().validate(messages, reporter, astRoot); + } + } + } + + public boolean validatesAgainstDatabase() { + return this.connectionProfileIsActive(); + } + + + // ********** primary key join column owner adapter ********** + + protected class PrimaryKeyJoinColumnOwner + implements JavaBaseJoinColumn.Owner + { + protected JavaEntity getEntity() { + return GenericJavaSecondaryTable.this.getEntity(); + } + + public TypeMapping getTypeMapping() { + return this.getEntity(); + } + + public String getDefaultTableName() { + return GenericJavaSecondaryTable.this.getName(); + } + + public Table resolveDbTable(String tableName) { + return GenericJavaSecondaryTable.this.getDbTable(); + } + + public Table getReferencedColumnDbTable() { + return this.getTypeMapping().getPrimaryDbTable(); + } + + public int joinColumnsSize() { + return GenericJavaSecondaryTable.this.primaryKeyJoinColumnsSize(); + } + + public boolean joinColumnIsDefault(ReadOnlyBaseJoinColumn joinColumn) { + return GenericJavaSecondaryTable.this.defaultPrimaryKeyJoinColumn == joinColumn; + } + + public String getDefaultColumnName() { + if (this.joinColumnsSize() != 1) { + return null; + } + return this.getEntity().getPrimaryKeyColumnName(); + } + + public TextRange getValidationTextRange(CompilationUnit astRoot) { + return GenericJavaSecondaryTable.this.getValidationTextRange(astRoot); + } + + public JptValidator buildColumnValidator(NamedColumn column, NamedColumnTextRangeResolver textRangeResolver) { + return new SecondaryTablePrimaryKeyJoinColumnValidator(GenericJavaSecondaryTable.this, (BaseJoinColumn) column, this, (BaseJoinColumnTextRangeResolver) textRangeResolver); + } + } +} diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaSequenceGenerator.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaSequenceGenerator.java new file mode 100644 index 0000000000..88c717be27 --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaSequenceGenerator.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 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.jpa1.context.java; + +import org.eclipse.jpt.jpa.core.context.java.JavaJpaContextNode; +import org.eclipse.jpt.jpa.core.internal.context.java.AbstractJavaSequenceGenerator; +import org.eclipse.jpt.jpa.core.resource.java.SequenceGeneratorAnnotation; + +/** + * Java sequence generator + */ +public class GenericJavaSequenceGenerator + extends AbstractJavaSequenceGenerator<SequenceGeneratorAnnotation> +{ + public GenericJavaSequenceGenerator(JavaJpaContextNode parent, SequenceGeneratorAnnotation generatorAnnotation) { + super(parent, generatorAnnotation); + } + + + // ********** database stuff ********** + + /** + * The JPA 1.0 spec does not allow a sequence to specify a catalog. + */ + @Override + protected String getCatalog() { + return this.getContextDefaultCatalog(); + } + + /** + * The JPA 1.0 spec does not allow a sequence to specify a schema. + */ + @Override + protected String getSchema() { + return this.getContextDefaultSchema(); + } + +} diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaTable.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaTable.java new file mode 100644 index 0000000000..5b2a3ab0a7 --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaTable.java @@ -0,0 +1,103 @@ +/******************************************************************************* + * Copyright (c) 2006, 2010 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.jpa1.context.java; + +import org.eclipse.jpt.jpa.core.context.java.JavaEntity; +import org.eclipse.jpt.jpa.core.internal.context.java.AbstractJavaTable; +import org.eclipse.jpt.jpa.core.resource.java.JavaResourcePersistentType; +import org.eclipse.jpt.jpa.core.resource.java.TableAnnotation; + +/** + * Java table + */ +public class GenericJavaTable + extends AbstractJavaTable<TableAnnotation> +{ + public GenericJavaTable(JavaEntity parent, Owner owner) { + super(parent, owner); + } + + + // ********** table annotation ********** + + @Override + public TableAnnotation getTableAnnotation() { + // TODO get the NullTableAnnotation from the resource model or build it here in the context model?? + return (TableAnnotation) this.getResourcePersistentType().getNonNullAnnotation(this.getAnnotationName()); + } + + @Override + protected void removeTableAnnotation() { + this.getResourcePersistentType().removeAnnotation(this.getAnnotationName()); + } + + protected String getAnnotationName() { + return TableAnnotation.ANNOTATION_NAME; + } + + protected JavaResourcePersistentType getResourcePersistentType() { + return this.getEntity().getPersistentType().getResourcePersistentType(); + } + + + // ********** defaults ********** + + @Override + protected String buildDefaultName() { + return this.getEntity().getDefaultTableName(); + } + + /** + * Just to remember:<ol> + * <li>{@link org.eclipse.jpt.jpa.core.context.Entity#getDefaultSchema()}<br> + * check inheritance; get default schema from root + * <li>{@link org.eclipse.jpt.jpa.core.context.orm.EntityMappings#getSchema()}<br> + * check for specified schema + * <li>{@link org.eclipse.jpt.jpa.core.context.persistence.PersistenceUnit#getDefaultSchema()}<br> + * {@link org.eclipse.jpt.jpa.core.context.orm.OrmPersistenceUnitDefaults#getSchema()} + * <li>{@link org.eclipse.jpt.jpa.core.JpaProject#getDefaultSchema()}<br> + * check for user override project setting + * <li>{@link org.eclipse.jpt.jpa.db.Catalog#getDefaultSchema()}<br> + * or {@link org.eclipse.jpt.jpa.db.Database#getDefaultSchema()} + * </ol> + */ + @Override + protected String buildDefaultSchema() { + return this.getEntity().getDefaultSchema(); + } + + @Override + protected String buildDefaultCatalog() { + return this.getEntity().getDefaultCatalog(); + } + + + // ********** validation ********** + + public boolean validatesAgainstDatabase() { + return this.connectionProfileIsActive(); + } + + + // ********** misc ********** + + /** + * covariant override + */ + @Override + public JavaEntity getParent() { + return (JavaEntity) super.getParent(); + } + + protected JavaEntity getEntity() { + return this.getParent(); + } + +} diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaTableGenerator.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaTableGenerator.java new file mode 100644 index 0000000000..f553c9b717 --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaTableGenerator.java @@ -0,0 +1,567 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 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.jpa1.context.java; + +import java.util.Iterator; +import java.util.Vector; +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jpt.common.utility.Filter; +import org.eclipse.jpt.common.utility.internal.CollectionTools; +import org.eclipse.jpt.common.utility.internal.StringTools; +import org.eclipse.jpt.common.utility.internal.iterables.EmptyIterable; +import org.eclipse.jpt.common.utility.internal.iterables.FilteringIterable; +import org.eclipse.jpt.common.utility.internal.iterables.LiveCloneIterable; +import org.eclipse.jpt.common.utility.internal.iterators.EmptyIterator; +import org.eclipse.jpt.jpa.core.context.UniqueConstraint; +import org.eclipse.jpt.jpa.core.context.java.JavaJpaContextNode; +import org.eclipse.jpt.jpa.core.context.java.JavaTableGenerator; +import org.eclipse.jpt.jpa.core.context.java.JavaUniqueConstraint; +import org.eclipse.jpt.jpa.core.internal.context.ContextContainerTools; +import org.eclipse.jpt.jpa.core.internal.context.java.AbstractJavaGenerator; +import org.eclipse.jpt.jpa.core.resource.java.TableGeneratorAnnotation; +import org.eclipse.jpt.jpa.core.resource.java.UniqueConstraintAnnotation; +import org.eclipse.jpt.jpa.db.Database; +import org.eclipse.jpt.jpa.db.Schema; +import org.eclipse.jpt.jpa.db.SchemaContainer; +import org.eclipse.jpt.jpa.db.Table; + +/** + * Java table generator + */ +public class GenericJavaTableGenerator + extends AbstractJavaGenerator<TableGeneratorAnnotation> + implements JavaTableGenerator, UniqueConstraint.Owner +{ + protected String specifiedTable; + protected String defaultTable; + + protected String specifiedSchema; + protected String defaultSchema; + + protected String specifiedCatalog; + protected String defaultCatalog; + + protected String specifiedPkColumnName; + protected String defaultPkColumnName; + + protected String specifiedValueColumnName; + protected String defaultValueColumnName; + + protected String specifiedPkColumnValue; + protected String defaultPkColumnValue; + + protected final Vector<JavaUniqueConstraint> uniqueConstraints = new Vector<JavaUniqueConstraint>(); + protected final UniqueConstraintContainerAdapter uniqueConstraintContainerAdapter = new UniqueConstraintContainerAdapter(); + + + // ********** constructor ********** + + public GenericJavaTableGenerator(JavaJpaContextNode parent, TableGeneratorAnnotation generatorAnnotation) { + super(parent, generatorAnnotation); + this.specifiedTable = generatorAnnotation.getTable(); + this.specifiedSchema = generatorAnnotation.getSchema(); + this.specifiedCatalog = generatorAnnotation.getCatalog(); + this.specifiedPkColumnName = generatorAnnotation.getPkColumnName(); + this.specifiedValueColumnName = generatorAnnotation.getValueColumnName(); + this.specifiedPkColumnValue = generatorAnnotation.getPkColumnValue(); + this.initializeUniqueConstraints(); + } + + + // ********** synchronize/update ********** + + @Override + public void synchronizeWithResourceModel() { + super.synchronizeWithResourceModel(); + this.setSpecifiedTable_(this.generatorAnnotation.getTable()); + this.setSpecifiedSchema_(this.generatorAnnotation.getSchema()); + this.setSpecifiedCatalog_(this.generatorAnnotation.getCatalog()); + this.setSpecifiedPkColumnName_(this.generatorAnnotation.getPkColumnName()); + this.setSpecifiedValueColumnName_(this.generatorAnnotation.getValueColumnName()); + this.setSpecifiedPkColumnValue_(this.generatorAnnotation.getPkColumnValue()); + this.syncUniqueConstraints(); + } + + @Override + public void update() { + super.update(); + this.setDefaultTable(this.buildDefaultTable()); + this.setDefaultSchema(this.buildDefaultSchema()); + this.setDefaultCatalog(this.buildDefaultCatalog()); + this.setDefaultPkColumnName(this.buildDefaultPkColumnName()); + this.setDefaultValueColumnName(this.buildDefaultValueColumnName()); + this.setDefaultPkColumnValue(this.buildDefaultPkColumnValue()); + this.updateNodes(this.getUniqueConstraints()); + } + + + // ********** initial value ********** + + @Override + protected int buildDefaultInitialValue() { + return DEFAULT_INITIAL_VALUE; + } + + + // ********** table ********** + + public String getTable() { + return (this.specifiedTable != null) ? this.specifiedTable : this.defaultTable; + } + + public String getSpecifiedTable() { + return this.specifiedTable; + } + + public void setSpecifiedTable(String table) { + this.generatorAnnotation.setTable(table); + this.setSpecifiedTable_(table); + } + + protected void setSpecifiedTable_(String table) { + String old = this.specifiedTable; + this.specifiedTable = table; + this.firePropertyChanged(SPECIFIED_TABLE_PROPERTY, old, table); + } + + public String getDefaultTable() { + return this.defaultTable; + } + + protected void setDefaultTable(String table) { + String old = this.defaultTable; + this.defaultTable = table; + this.firePropertyChanged(DEFAULT_TABLE_PROPERTY, old, table); + } + + protected String buildDefaultTable() { + return null; // TODO the default table is determined by the runtime provider... + } + + public Table getDbTable() { + Schema dbSchema = this.getDbSchema(); + return (dbSchema == null) ? null : dbSchema.getTableForIdentifier(this.getTable()); + } + + + // ********** schema ********** + + @Override + public String getSchema() { + return (this.specifiedSchema != null) ? this.specifiedSchema : this.defaultSchema; + } + + public String getSpecifiedSchema() { + return this.specifiedSchema; + } + + public void setSpecifiedSchema(String schema) { + this.generatorAnnotation.setSchema(schema); + this.setSpecifiedSchema_(schema); + } + + protected void setSpecifiedSchema_(String schema) { + String old = this.specifiedSchema; + this.specifiedSchema = schema; + this.firePropertyChanged(SPECIFIED_SCHEMA_PROPERTY, old, schema); + } + + public String getDefaultSchema() { + return this.defaultSchema; + } + + protected void setDefaultSchema(String schema) { + String old = this.defaultSchema; + this.defaultSchema = schema; + this.firePropertyChanged(DEFAULT_SCHEMA_PROPERTY, old, schema); + } + + protected String buildDefaultSchema() { + return this.getContextDefaultSchema(); + } + + + // ********** catalog ********** + + @Override + public String getCatalog() { + return (this.specifiedCatalog != null) ? this.specifiedCatalog : this.defaultCatalog; + } + + public String getSpecifiedCatalog() { + return this.specifiedCatalog; + } + + public void setSpecifiedCatalog(String catalog) { + this.generatorAnnotation.setCatalog(catalog); + this.setSpecifiedCatalog_(catalog); + } + + protected void setSpecifiedCatalog_(String catalog) { + String old = this.specifiedCatalog; + this.specifiedCatalog = catalog; + this.firePropertyChanged(SPECIFIED_CATALOG_PROPERTY, old, catalog); + } + + public String getDefaultCatalog() { + return this.defaultCatalog; + } + + protected void setDefaultCatalog(String catalog) { + String old = this.defaultCatalog; + this.defaultCatalog = catalog; + this.firePropertyChanged(DEFAULT_CATALOG_PROPERTY, old, catalog); + } + + protected String buildDefaultCatalog() { + return this.getContextDefaultCatalog(); + } + + + // ********** primary key column name ********** + + public String getPkColumnName() { + return (this.specifiedPkColumnName != null) ? this.specifiedPkColumnName : this.defaultPkColumnName; + } + + public String getSpecifiedPkColumnName() { + return this.specifiedPkColumnName; + } + + public void setSpecifiedPkColumnName(String name) { + this.generatorAnnotation.setPkColumnName(name); + this.setSpecifiedPkColumnName_(name); + } + + protected void setSpecifiedPkColumnName_(String name) { + String old = this.specifiedPkColumnName; + this.specifiedPkColumnName = name; + this.firePropertyChanged(SPECIFIED_PK_COLUMN_NAME_PROPERTY, old, name); + } + + public String getDefaultPkColumnName() { + return this.defaultPkColumnName; + } + + protected void setDefaultPkColumnName(String name) { + String old = this.defaultPkColumnName; + this.defaultPkColumnName = name; + this.firePropertyChanged(DEFAULT_PK_COLUMN_NAME_PROPERTY, old, name); + } + + protected String buildDefaultPkColumnName() { + return null; // TODO the default pk column name is determined by the runtime provider... + } + + + // ********** value column name ********** + + public String getValueColumnName() { + return (this.specifiedValueColumnName != null) ? this.specifiedValueColumnName : this.defaultValueColumnName; + } + + public String getSpecifiedValueColumnName() { + return this.specifiedValueColumnName; + } + + public void setSpecifiedValueColumnName(String name) { + this.generatorAnnotation.setValueColumnName(name); + this.setSpecifiedValueColumnName_(name); + } + + protected void setSpecifiedValueColumnName_(String name) { + String old = this.specifiedValueColumnName; + this.specifiedValueColumnName = name; + this.firePropertyChanged(SPECIFIED_VALUE_COLUMN_NAME_PROPERTY, old, name); + } + + public String getDefaultValueColumnName() { + return this.defaultValueColumnName; + } + + protected void setDefaultValueColumnName(String name) { + String old = this.defaultValueColumnName; + this.defaultValueColumnName = name; + this.firePropertyChanged(DEFAULT_VALUE_COLUMN_NAME_PROPERTY, old, name); + } + + protected String buildDefaultValueColumnName() { + return null; // TODO the default value column name is determined by the runtime provider... + } + + + // ********** primary key column value ********** + + public String getPkColumnValue() { + return (this.specifiedPkColumnValue != null) ? this.specifiedPkColumnValue : this.defaultPkColumnValue; + } + + public String getSpecifiedPkColumnValue() { + return this.specifiedPkColumnValue; + } + + public void setSpecifiedPkColumnValue(String value) { + this.generatorAnnotation.setPkColumnValue(value); + this.setSpecifiedPkColumnValue_(value); + } + + protected void setSpecifiedPkColumnValue_(String value) { + String old = this.specifiedPkColumnValue; + this.specifiedPkColumnValue = value; + this.firePropertyChanged(SPECIFIED_PK_COLUMN_VALUE_PROPERTY, old, value); + } + + public String getDefaultPkColumnValue() { + return this.defaultPkColumnValue; + } + + protected void setDefaultPkColumnValue(String value) { + String old = this.defaultPkColumnValue; + this.defaultPkColumnValue = value; + this.firePropertyChanged(DEFAULT_PK_COLUMN_VALUE_PROPERTY, old, value); + } + + protected String buildDefaultPkColumnValue() { + return null; // TODO the default pk column value is determined by the runtime provider... + } + + + // ********** unique constraints ********** + + public Iterable<JavaUniqueConstraint> getUniqueConstraints() { + return new LiveCloneIterable<JavaUniqueConstraint>(this.uniqueConstraints); + } + + public int getUniqueConstraintsSize() { + return this.uniqueConstraints.size(); + } + + public JavaUniqueConstraint addUniqueConstraint() { + return this.addUniqueConstraint(this.uniqueConstraints.size()); + } + + public JavaUniqueConstraint addUniqueConstraint(int index) { + UniqueConstraintAnnotation constraintAnnotation = this.generatorAnnotation.addUniqueConstraint(index); + return this.addUniqueConstraint_(index, constraintAnnotation); + } + + public void removeUniqueConstraint(UniqueConstraint uniqueConstraint) { + this.removeUniqueConstraint(this.uniqueConstraints.indexOf(uniqueConstraint)); + } + + public void removeUniqueConstraint(int index) { + this.generatorAnnotation.removeUniqueConstraint(index); + this.removeUniqueConstraint_(index); + } + + protected void removeUniqueConstraint_(int index) { + this.removeItemFromList(index, this.uniqueConstraints, UNIQUE_CONSTRAINTS_LIST); + } + + public void moveUniqueConstraint(int targetIndex, int sourceIndex) { + this.generatorAnnotation.moveUniqueConstraint(targetIndex, sourceIndex); + this.moveItemInList(targetIndex, sourceIndex, this.uniqueConstraints, UNIQUE_CONSTRAINTS_LIST); + } + + protected void initializeUniqueConstraints() { + for (Iterator<UniqueConstraintAnnotation> stream = this.generatorAnnotation.uniqueConstraints(); stream.hasNext(); ) { + this.uniqueConstraints.add(this.buildUniqueConstraint(stream.next())); + } + } + + protected JavaUniqueConstraint buildUniqueConstraint(UniqueConstraintAnnotation constraintAnnotation) { + return this.getJpaFactory().buildJavaUniqueConstraint(this, this, constraintAnnotation); + } + + protected void syncUniqueConstraints() { + ContextContainerTools.synchronizeWithResourceModel(this.uniqueConstraintContainerAdapter); + } + + protected Iterable<UniqueConstraintAnnotation> getUniqueConstraintAnnotations() { + return CollectionTools.iterable(this.generatorAnnotation.uniqueConstraints()); + } + + protected void moveUniqueConstraint_(int index, JavaUniqueConstraint uniqueConstraint) { + this.moveItemInList(index, uniqueConstraint, this.uniqueConstraints, UNIQUE_CONSTRAINTS_LIST); + } + + protected JavaUniqueConstraint addUniqueConstraint_(int index, UniqueConstraintAnnotation constraintAnnotation) { + JavaUniqueConstraint constraint = this.buildUniqueConstraint(constraintAnnotation); + this.addItemToList(index, constraint, this.uniqueConstraints, UNIQUE_CONSTRAINTS_LIST); + return constraint; + } + + protected void removeUniqueConstraint_(JavaUniqueConstraint uniqueConstraint) { + this.removeUniqueConstraint_(this.uniqueConstraints.indexOf(uniqueConstraint)); + } + + /** + * unique constraint container adapter + */ + protected class UniqueConstraintContainerAdapter + implements ContextContainerTools.Adapter<JavaUniqueConstraint, UniqueConstraintAnnotation> + { + public Iterable<JavaUniqueConstraint> getContextElements() { + return GenericJavaTableGenerator.this.getUniqueConstraints(); + } + public Iterable<UniqueConstraintAnnotation> getResourceElements() { + return GenericJavaTableGenerator.this.getUniqueConstraintAnnotations(); + } + public UniqueConstraintAnnotation getResourceElement(JavaUniqueConstraint contextElement) { + return contextElement.getUniqueConstraintAnnotation(); + } + public void moveContextElement(int index, JavaUniqueConstraint element) { + GenericJavaTableGenerator.this.moveUniqueConstraint_(index, element); + } + public void addContextElement(int index, UniqueConstraintAnnotation resourceElement) { + GenericJavaTableGenerator.this.addUniqueConstraint_(index, resourceElement); + } + public void removeContextElement(JavaUniqueConstraint element) { + GenericJavaTableGenerator.this.removeUniqueConstraint_(element); + } + } + + + // ********** UniqueConstraint.Owner implementation ********** + + public Iterator<String> candidateUniqueConstraintColumnNames() { + org.eclipse.jpt.jpa.db.Table dbTable = this.getDbTable(); + return (dbTable != null) ? dbTable.getSortedColumnIdentifiers().iterator() : EmptyIterator.<String>instance(); + } + + + // ********** Java completion proposals ********** + + @Override + public Iterator<String> javaCompletionProposals(int pos, Filter<String> filter, CompilationUnit astRoot) { + Iterator<String> result = super.javaCompletionProposals(pos, filter, astRoot); + if (result != null) { + return result; + } + for (JavaUniqueConstraint constraint : this.getUniqueConstraints()) { + result = constraint.javaCompletionProposals(pos, filter, astRoot); + if (result != null) { + return result; + } + } + return null; + } + + /** + * called if the database is connected: + * table, schema, catalog, pkColumnName, valueColumnName + */ + @Override + public Iterator<String> connectedJavaCompletionProposals(int pos, Filter<String> filter, CompilationUnit astRoot) { + Iterator<String> result = super.connectedJavaCompletionProposals(pos, filter, astRoot); + if (result != null) { + return result; + } + if (this.tableTouches(pos, astRoot)) { + return this.getJavaCandidateTables(filter).iterator(); + } + if (this.schemaTouches(pos, astRoot)) { + return this.getJavaCandidateSchemata(filter).iterator(); + } + if (this.catalogTouches(pos, astRoot)) { + return this.getJavaCandidateCatalogs(filter).iterator(); + } + if (this.pkColumnNameTouches(pos, astRoot)) { + return this.getJavaCandidateColumnNames(filter).iterator(); + } + if (this.valueColumnNameTouches(pos, astRoot)) { + return this.getJavaCandidateColumnNames(filter).iterator(); + } + return null; + } + + // ********** code assist: table + + protected boolean tableTouches(int pos, CompilationUnit astRoot) { + return this.generatorAnnotation.tableTouches(pos, astRoot); + } + + protected Iterable<String> getJavaCandidateTables(Filter<String> filter) { + return StringTools.convertToJavaStringLiterals(this.getCandidateTables(filter)); + } + + protected Iterable<String> getCandidateTables(Filter<String> filter) { + return new FilteringIterable<String>(this.getCandidateTables(), filter); + } + + protected Iterable<String> getCandidateTables() { + Schema dbSchema = this.getDbSchema(); + return (dbSchema != null) ? dbSchema.getSortedTableIdentifiers() : EmptyIterable.<String> instance(); + } + + // ********** code assist: schema + + protected boolean schemaTouches(int pos, CompilationUnit astRoot) { + return this.generatorAnnotation.schemaTouches(pos, astRoot); + } + + protected Iterable<String> getJavaCandidateSchemata(Filter<String> filter) { + return StringTools.convertToJavaStringLiterals(this.getCandidateSchemata(filter)); + } + + protected Iterable<String> getCandidateSchemata(Filter<String> filter) { + return new FilteringIterable<String>(this.getCandidateSchemata(), filter); + } + + protected Iterable<String> getCandidateSchemata() { + SchemaContainer schemaContainer = this.getDbSchemaContainer(); + return (schemaContainer != null) ? schemaContainer.getSortedSchemaIdentifiers() : EmptyIterable.<String> instance(); + } + + // ********** code assist: catalog + + protected boolean catalogTouches(int pos, CompilationUnit astRoot) { + return this.generatorAnnotation.catalogTouches(pos, astRoot); + } + + protected Iterable<String> getJavaCandidateCatalogs(Filter<String> filter) { + return StringTools.convertToJavaStringLiterals(this.getCandidateCatalogs(filter)); + } + + protected Iterable<String> getCandidateCatalogs(Filter<String> filter) { + return new FilteringIterable<String>(this.getCandidateCatalogs(), filter); + } + + protected Iterable<String> getCandidateCatalogs() { + Database db = this.getDatabase(); + return (db != null) ? db.getSortedCatalogIdentifiers() : EmptyIterable.<String> instance(); + } + + // ********** code assist: pkColumnName + + protected boolean pkColumnNameTouches(int pos, CompilationUnit astRoot) { + return this.generatorAnnotation.pkColumnNameTouches(pos, astRoot); + } + + protected Iterable<String> getJavaCandidateColumnNames(Filter<String> filter) { + return StringTools.convertToJavaStringLiterals(this.getCandidateColumnNames(filter)); + } + + protected Iterable<String> getCandidateColumnNames(Filter<String> filter) { + return new FilteringIterable<String>(this.getCandidateColumnNames(), filter); + } + + protected Iterable<String> getCandidateColumnNames() { + Table table = this.getDbTable(); + return (table != null) ? table.getSortedColumnIdentifiers() : EmptyIterable.<String> instance(); + } + + // ********** code assist: valueColumnName + + protected boolean valueColumnNameTouches(int pos, CompilationUnit astRoot) { + return this.generatorAnnotation.valueColumnNameTouches(pos, astRoot); + } + +} diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaTemporalConverter.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaTemporalConverter.java new file mode 100644 index 0000000000..a48e67aeb5 --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaTemporalConverter.java @@ -0,0 +1,94 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 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.jpa1.context.java; + +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jpt.common.core.utility.TextRange; +import org.eclipse.jpt.jpa.core.context.Converter; +import org.eclipse.jpt.jpa.core.context.TemporalConverter; +import org.eclipse.jpt.jpa.core.context.TemporalType; +import org.eclipse.jpt.jpa.core.context.java.JavaAttributeMapping; +import org.eclipse.jpt.jpa.core.context.java.JavaTemporalConverter; +import org.eclipse.jpt.jpa.core.resource.java.TemporalAnnotation; + +public class GenericJavaTemporalConverter + extends AbstractJavaConverter + implements JavaTemporalConverter +{ + protected final TemporalAnnotation temporalAnnotation; + + protected TemporalType temporalType; + + + public GenericJavaTemporalConverter(JavaAttributeMapping parent, TemporalAnnotation temporalAnnotation) { + super(parent); + this.temporalAnnotation = temporalAnnotation; + this.temporalType = this.buildTemporalType(); + } + + + // ********** synchronize/update ********** + + @Override + public void synchronizeWithResourceModel() { + super.synchronizeWithResourceModel(); + this.setTemporalType_(this.buildTemporalType()); + } + + + // ********** temporal type ********** + + public TemporalType getTemporalType() { + return this.temporalType; + } + + public void setTemporalType(TemporalType temporalType) { + if (this.valuesAreDifferent(this.temporalType, temporalType)) { + this.temporalAnnotation.setValue(TemporalType.toJavaResourceModel(temporalType)); + this.removeTemporalAnnotationIfUnset(); + this.setTemporalType_(temporalType); + } + } + + protected void setTemporalType_(TemporalType temporalType) { + TemporalType old = this.temporalType; + this.temporalType = temporalType; + this.firePropertyChanged(TEMPORAL_TYPE_PROPERTY, old, temporalType); + } + + protected TemporalType buildTemporalType() { + return TemporalType.fromJavaResourceModel(this.temporalAnnotation.getValue()); + } + + + // ********** misc ********** + + public Class<? extends Converter> getType() { + return TemporalConverter.class; + } + + @Override + protected String getAnnotationName() { + return TemporalAnnotation.ANNOTATION_NAME; + } + + protected void removeTemporalAnnotationIfUnset() { + if (this.temporalAnnotation.isUnset()) { + this.temporalAnnotation.removeAnnotation(); + } + } + + + // ********** validation ********** + + public TextRange getValidationTextRange(CompilationUnit astRoot) { + return this.temporalAnnotation.getTextRange(astRoot); + } +} diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaTransientMapping.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaTransientMapping.java new file mode 100644 index 0000000000..37e46c1c56 --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaTransientMapping.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 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.jpa1.context.java; + +import org.eclipse.jpt.jpa.core.MappingKeys; +import org.eclipse.jpt.jpa.core.context.java.JavaPersistentAttribute; +import org.eclipse.jpt.jpa.core.context.java.JavaTransientMapping; +import org.eclipse.jpt.jpa.core.internal.context.java.AbstractJavaAttributeMapping; +import org.eclipse.jpt.jpa.core.jpa2.context.MetamodelField; +import org.eclipse.jpt.jpa.core.resource.java.TransientAnnotation; + +/** + * Java transient mapping + */ +public class GenericJavaTransientMapping + extends AbstractJavaAttributeMapping<TransientAnnotation> + implements JavaTransientMapping +{ + public GenericJavaTransientMapping(JavaPersistentAttribute parent) { + super(parent); + } + + public String getKey() { + return MappingKeys.TRANSIENT_ATTRIBUTE_MAPPING_KEY; + } + + @Override + protected String getAnnotationName() { + return TransientAnnotation.ANNOTATION_NAME; + } + + + // ********** metamodel ********** + + @Override + public MetamodelField getMetamodelField() { + return null; + } +} diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaUniqueConstraint.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaUniqueConstraint.java new file mode 100644 index 0000000000..43eef86ff7 --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaUniqueConstraint.java @@ -0,0 +1,135 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 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.jpa1.context.java; + +import java.util.Iterator; +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jpt.common.core.utility.TextRange; +import org.eclipse.jpt.common.utility.Filter; +import org.eclipse.jpt.common.utility.internal.CollectionTools; +import org.eclipse.jpt.common.utility.internal.StringTools; +import org.eclipse.jpt.common.utility.internal.iterators.FilteringIterator; +import org.eclipse.jpt.jpa.core.context.ReadOnlyUniqueConstraint; +import org.eclipse.jpt.jpa.core.context.java.JavaJpaContextNode; +import org.eclipse.jpt.jpa.core.context.java.JavaUniqueConstraint; +import org.eclipse.jpt.jpa.core.internal.context.java.AbstractJavaReadOnlyUniqueConstraint; +import org.eclipse.jpt.jpa.core.resource.java.UniqueConstraintAnnotation; + +public class GenericJavaUniqueConstraint + extends AbstractJavaReadOnlyUniqueConstraint + implements JavaUniqueConstraint +{ + protected Owner owner; + protected final UniqueConstraintAnnotation uniqueConstraintAnnotation; + + + public GenericJavaUniqueConstraint(JavaJpaContextNode parent, Owner owner, UniqueConstraintAnnotation uniqueConstraintAnnotation) { + super(parent); + this.owner = owner; + this.uniqueConstraintAnnotation = uniqueConstraintAnnotation; + this.initializeColumnNames(); + } + + + // ********** synchronize/update ********** + + @Override + public void synchronizeWithResourceModel() { + super.synchronizeWithResourceModel(); + this.syncColumnNames(); + } + + + // ********** column names ********** + + public void addColumnName(String columnName) { + this.addColumnName(this.columnNames.size(), columnName); + } + + public void addColumnName(int index, String columnName) { + this.uniqueConstraintAnnotation.addColumnName(index, columnName); + this.addItemToList(index, columnName, this.columnNames, COLUMN_NAMES_LIST); + } + + public void removeColumnName(String columnName) { + this.removeColumnName(this.columnNames.indexOf(columnName)); + } + + public void removeColumnName(int index) { + this.uniqueConstraintAnnotation.removeColumnName(index); + this.removeItemFromList(index, this.columnNames, COLUMN_NAMES_LIST); + } + + public void moveColumnName(int targetIndex, int sourceIndex) { + this.uniqueConstraintAnnotation.moveColumnName(targetIndex, sourceIndex); + this.moveItemInList(targetIndex, sourceIndex, this.columnNames, COLUMN_NAMES_LIST); + } + + protected void initializeColumnNames() { + for (Iterator<String> stream = this.uniqueConstraintAnnotation.columnNames(); stream.hasNext(); ) { + this.columnNames.add(stream.next()); + } + } + + @Override + protected Iterable<String> getResourceColumnNames() { + return CollectionTools.iterable(this.uniqueConstraintAnnotation.columnNames()); + } + + // ********** Java completion proposals ********** + + @Override + public Iterator<String> connectedJavaCompletionProposals(int pos, Filter<String> filter, CompilationUnit astRoot) { + Iterator<String> result = super.connectedJavaCompletionProposals(pos, filter, astRoot); + if (result != null) { + return result; + } + if (this.columnNamesTouches(pos, astRoot)) { + return this.javaCandidateColumnNames(filter); + } + return null; + } + + protected boolean columnNamesTouches(int pos, CompilationUnit astRoot) { + return this.uniqueConstraintAnnotation.columnNamesTouches(pos, astRoot); + } + + protected Iterator<String> javaCandidateColumnNames(Filter<String> filter) { + return StringTools.convertToJavaStringLiterals(this.candidateColumnNames(filter)); + } + + protected Iterator<String> candidateColumnNames(Filter<String> filter) { + return new FilteringIterator<String>(this.candidateColumnNames(), filter); + } + + protected Iterator<String> candidateColumnNames() { + return this.owner.candidateUniqueConstraintColumnNames(); + } + + + // ********** validation ********** + + public TextRange getValidationTextRange(CompilationUnit astRoot) { + return this.uniqueConstraintAnnotation.getTextRange(astRoot); + } + + + // ********** misc ********** + + public UniqueConstraintAnnotation getUniqueConstraintAnnotation() { + return this.uniqueConstraintAnnotation; + } + + public void initializeFrom(ReadOnlyUniqueConstraint oldUniqueConstraint) { + for (String columnName : oldUniqueConstraint.getColumnNames()) { + this.addColumnName(columnName); + } + } +} diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaVersionMapping.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaVersionMapping.java new file mode 100644 index 0000000000..9d66e365f5 --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaVersionMapping.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 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.jpa1.context.java; + +import org.eclipse.jpt.jpa.core.context.java.JavaPersistentAttribute; +import org.eclipse.jpt.jpa.core.internal.context.java.AbstractJavaVersionMapping; + +public class GenericJavaVersionMapping + extends AbstractJavaVersionMapping +{ + public GenericJavaVersionMapping(JavaPersistentAttribute parent) { + super(parent); + } +} diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaVirtualAssociationOverride.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaVirtualAssociationOverride.java new file mode 100644 index 0000000000..2333e0c4d1 --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaVirtualAssociationOverride.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright (c) 2010, 2011 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.jpa1.context.java; + +import org.eclipse.jpt.jpa.core.context.Relationship; +import org.eclipse.jpt.jpa.core.context.RelationshipMapping; +import org.eclipse.jpt.jpa.core.context.java.JavaAssociationOverride; +import org.eclipse.jpt.jpa.core.context.java.JavaAssociationOverrideContainer; +import org.eclipse.jpt.jpa.core.context.java.JavaVirtualAssociationOverride; +import org.eclipse.jpt.jpa.core.context.java.JavaVirtualOverrideRelationship; +import org.eclipse.jpt.jpa.core.internal.context.java.AbstractJavaVirtualOverride; + +/** + * Virtual Java association override + */ +public class GenericJavaVirtualAssociationOverride + extends AbstractJavaVirtualOverride<JavaAssociationOverrideContainer> + implements JavaVirtualAssociationOverride +{ + protected final JavaVirtualOverrideRelationship relationship; + + + public GenericJavaVirtualAssociationOverride(JavaAssociationOverrideContainer parent, String name) { + super(parent, name); + this.relationship = this.buildRelationship(); + } + + @Override + public void update() { + super.update(); + this.relationship.update(); + } + + @Override + public JavaAssociationOverride convertToSpecified() { + return (JavaAssociationOverride) super.convertToSpecified(); + } + + public RelationshipMapping getMapping() { + return this.getContainer().getRelationshipMapping(this.name); + } + + + // ********** relationship ********** + + public JavaVirtualOverrideRelationship getRelationship() { + return this.relationship; + } + + /** + * The relationship should be available (since its presence precipitated the + * creation of the virtual override). + */ + protected JavaVirtualOverrideRelationship buildRelationship() { + return this.getJpaFactory().buildJavaVirtualOverrideRelationship(this); + } + + public Relationship resolveOverriddenRelationship() { + return this.getContainer().resolveOverriddenRelationship(this.name); + } +} diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaVirtualAttributeOverride.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaVirtualAttributeOverride.java new file mode 100644 index 0000000000..9049ad974d --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaVirtualAttributeOverride.java @@ -0,0 +1,93 @@ +/******************************************************************************* + * Copyright (c) 2010 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.jpa1.context.java; + +import org.eclipse.jpt.jpa.core.context.Column; +import org.eclipse.jpt.jpa.core.context.ReadOnlyColumn; +import org.eclipse.jpt.jpa.core.context.TypeMapping; +import org.eclipse.jpt.jpa.core.context.java.JavaAttributeOverride; +import org.eclipse.jpt.jpa.core.context.java.JavaAttributeOverrideContainer; +import org.eclipse.jpt.jpa.core.context.java.JavaVirtualAttributeOverride; +import org.eclipse.jpt.jpa.core.context.java.JavaVirtualColumn; +import org.eclipse.jpt.jpa.core.internal.context.java.AbstractJavaVirtualOverride; + +/** + * Virtual Java attribute override + */ +public class GenericJavaVirtualAttributeOverride + extends AbstractJavaVirtualOverride<JavaAttributeOverrideContainer> + implements JavaVirtualAttributeOverride, JavaVirtualColumn.Owner +{ + protected final JavaVirtualColumn column; + + + public GenericJavaVirtualAttributeOverride(JavaAttributeOverrideContainer parent, String name) { + super(parent, name); + this.column = this.buildColumn(); + } + + @Override + public void update() { + super.update(); + this.column.update(); + } + + @Override + public JavaAttributeOverride convertToSpecified() { + return (JavaAttributeOverride) super.convertToSpecified(); + } + + + // ********** column ********** + + public JavaVirtualColumn getColumn() { + return this.column; + } + + /** + * The original column should be available (since the presence of its + * attribute is what precipitated the creation of the virtual override). + */ + protected JavaVirtualColumn buildColumn() { + return this.getJpaFactory().buildJavaVirtualColumn(this, this); + } + + + // ********** column owner implementation ********** + + public TypeMapping getTypeMapping() { + return this.getContainer().getTypeMapping(); + } + + public String getDefaultTableName() { + String overriddenColumnTable = this.getOverriddenColumnTable(); + return (overriddenColumnTable != null) ? overriddenColumnTable : this.getContainer().getDefaultTableName(); + } + + protected String getOverriddenColumnTable() { + ReadOnlyColumn overriddenColumn = this.resolveOverriddenColumn(); + // pretty sure this is the *specified* table... + return (overriddenColumn == null) ? null : overriddenColumn.getSpecifiedTable(); + } + + public String getDefaultColumnName() { + String overriddenColumnName = this.getOverriddenColumnName(); + return (overriddenColumnName != null) ? overriddenColumnName : this.name; + } + + protected String getOverriddenColumnName() { + ReadOnlyColumn overriddenColumn = this.resolveOverriddenColumn(); + return (overriddenColumn == null) ? null : overriddenColumn.getName(); + } + + public Column resolveOverriddenColumn() { + return this.getContainer().resolveOverriddenColumn(this.name); + } +} diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaVirtualColumn.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaVirtualColumn.java new file mode 100644 index 0000000000..0429f71344 --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaVirtualColumn.java @@ -0,0 +1,167 @@ +/******************************************************************************* + * Copyright (c) 2010 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.jpa1.context.java; + +import org.eclipse.jpt.jpa.core.context.Column; +import org.eclipse.jpt.jpa.core.context.java.JavaJpaContextNode; +import org.eclipse.jpt.jpa.core.context.java.JavaVirtualColumn; +import org.eclipse.jpt.jpa.core.internal.context.java.AbstractJavaVirtualBaseColumn; + +/** + * Java virtual column + */ +public class GenericJavaVirtualColumn + extends AbstractJavaVirtualBaseColumn<JavaVirtualColumn.Owner, Column> + implements JavaVirtualColumn +{ + protected Integer specifiedLength; + protected int defaultLength; + + protected Integer specifiedPrecision; + protected int defaultPrecision; + + protected Integer specifiedScale; + protected int defaultScale; + + + public GenericJavaVirtualColumn(JavaJpaContextNode parent, JavaVirtualColumn.Owner owner) { + super(parent, owner); + } + + + // ********** synchronize/update ********** + + @Override + public void update() { + super.update(); + + this.setSpecifiedLength(this.buildSpecifiedLength()); + this.setDefaultLength(this.buildDefaultLength()); + + this.setSpecifiedPrecision(this.buildSpecifiedPrecision()); + this.setDefaultPrecision(this.buildDefaultPrecision()); + + this.setSpecifiedScale(this.buildSpecifiedScale()); + this.setDefaultScale(this.buildDefaultScale()); + } + + + // ********** column ********** + + @Override + public Column getOverriddenColumn() { + return this.owner.resolveOverriddenColumn(); + } + + + // ********** length ********** + + public int getLength() { + return (this.specifiedLength != null) ? this.specifiedLength.intValue() : this.defaultLength; + } + + public Integer getSpecifiedLength() { + return this.specifiedLength; + } + + protected void setSpecifiedLength(Integer length) { + Integer old = this.specifiedLength; + this.specifiedLength = length; + this.firePropertyChanged(SPECIFIED_LENGTH_PROPERTY, old, length); + } + + protected Integer buildSpecifiedLength() { + return this.getOverriddenColumn().getSpecifiedLength(); + } + + public int getDefaultLength() { + return this.defaultLength; + } + + protected void setDefaultLength(int length) { + int old = this.defaultLength; + this.defaultLength = length; + this.firePropertyChanged(DEFAULT_LENGTH_PROPERTY, old, length); + } + + protected int buildDefaultLength() { + return DEFAULT_LENGTH; + } + + + // ********** precision ********** + + public int getPrecision() { + return (this.specifiedPrecision != null) ? this.specifiedPrecision.intValue() : this.defaultPrecision; + } + + public Integer getSpecifiedPrecision() { + return this.specifiedPrecision; + } + + protected void setSpecifiedPrecision(Integer precision) { + Integer old = this.specifiedPrecision; + this.specifiedPrecision = precision; + this.firePropertyChanged(SPECIFIED_PRECISION_PROPERTY, old, precision); + } + + protected Integer buildSpecifiedPrecision() { + return this.getOverriddenColumn().getSpecifiedPrecision(); + } + + public int getDefaultPrecision() { + return this.defaultPrecision; + } + + protected void setDefaultPrecision(int precision) { + int old = this.defaultPrecision; + this.defaultPrecision = precision; + this.firePropertyChanged(DEFAULT_PRECISION_PROPERTY, old, precision); + } + + protected int buildDefaultPrecision() { + return DEFAULT_PRECISION; + } + + + // ********** scale ********** + + public int getScale() { + return (this.specifiedScale != null) ? this.specifiedScale.intValue() : this.defaultScale; + } + + public Integer getSpecifiedScale() { + return this.specifiedScale; + } + + protected void setSpecifiedScale(Integer scale) { + Integer old = this.specifiedScale; + this.specifiedScale = scale; + this.firePropertyChanged(SPECIFIED_SCALE_PROPERTY, old, scale); + } + + protected Integer buildSpecifiedScale() { + return this.getOverriddenColumn().getSpecifiedScale(); + } + + public int getDefaultScale() { + return this.defaultScale; + } + + protected void setDefaultScale(int scale) { + int old = this.defaultScale; + this.defaultScale = scale; + this.firePropertyChanged(DEFAULT_SCALE_PROPERTY, old, scale); + } + + protected int buildDefaultScale() { + return DEFAULT_SCALE; + } +} diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaVirtualJoinColumn.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaVirtualJoinColumn.java new file mode 100644 index 0000000000..6848cb9c65 --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaVirtualJoinColumn.java @@ -0,0 +1,102 @@ +/******************************************************************************* + * Copyright (c) 2010 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.jpa1.context.java; + +import org.eclipse.jpt.jpa.core.context.JoinColumn; +import org.eclipse.jpt.jpa.core.context.ReadOnlyJoinColumn; +import org.eclipse.jpt.jpa.core.context.java.JavaJpaContextNode; +import org.eclipse.jpt.jpa.core.context.java.JavaVirtualJoinColumn; +import org.eclipse.jpt.jpa.core.internal.context.MappingTools; +import org.eclipse.jpt.jpa.core.internal.context.java.AbstractJavaVirtualBaseColumn; + +/** + * Java virtual join column + */ +public class GenericJavaVirtualJoinColumn + extends AbstractJavaVirtualBaseColumn<ReadOnlyJoinColumn.Owner, JoinColumn> + implements JavaVirtualJoinColumn +{ + protected final JoinColumn overriddenColumn; + + protected String specifiedReferencedColumnName; + protected String defaultReferencedColumnName; + + + public GenericJavaVirtualJoinColumn(JavaJpaContextNode parent, ReadOnlyJoinColumn.Owner owner, JoinColumn overriddenColumn) { + super(parent, owner); + this.overriddenColumn = overriddenColumn; + } + + + // ********** synchronize/update ********** + + @Override + public void update() { + super.update(); + + this.setSpecifiedReferencedColumnName(this.buildSpecifiedReferencedColumnName()); + this.setDefaultReferencedColumnName(this.buildDefaultReferencedColumnName()); + } + + + // ********** column ********** + + @Override + public JoinColumn getOverriddenColumn() { + return this.overriddenColumn; + } + + public boolean isDefault() { + return this.owner.joinColumnIsDefault(this); + } + + + // ********** referenced column name ********** + + public String getReferencedColumnName() { + return (this.specifiedReferencedColumnName != null) ? this.specifiedReferencedColumnName : this.defaultReferencedColumnName; + } + + public String getSpecifiedReferencedColumnName() { + return this.specifiedReferencedColumnName; + } + + protected void setSpecifiedReferencedColumnName(String name) { + String old = this.specifiedReferencedColumnName; + this.specifiedReferencedColumnName = name; + this.firePropertyChanged(SPECIFIED_REFERENCED_COLUMN_NAME_PROPERTY, old, name); + } + + protected String buildSpecifiedReferencedColumnName() { + return this.getOverriddenColumn().getSpecifiedReferencedColumnName(); + } + + public String getDefaultReferencedColumnName() { + return this.defaultReferencedColumnName; + } + + protected void setDefaultReferencedColumnName(String name) { + String old = this.defaultReferencedColumnName; + this.defaultReferencedColumnName = name; + this.firePropertyChanged(DEFAULT_REFERENCED_COLUMN_NAME_PROPERTY, old, name); + } + + protected String buildDefaultReferencedColumnName() { + return MappingTools.buildJoinColumnDefaultReferencedColumnName(this.owner); + } + + + // ********** misc ********** + + @Override + protected String buildDefaultName() { + return MappingTools.buildJoinColumnDefaultName(this, this.owner); + } +} diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaVirtualOverrideJoinColumnRelationshipStrategy.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaVirtualOverrideJoinColumnRelationshipStrategy.java new file mode 100644 index 0000000000..aeb114470b --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaVirtualOverrideJoinColumnRelationshipStrategy.java @@ -0,0 +1,335 @@ +/******************************************************************************* + * Copyright (c) 2010, 2011 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.jpa1.context.java; + +import java.util.ListIterator; +import java.util.Vector; +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jpt.common.core.utility.TextRange; +import org.eclipse.jpt.common.utility.internal.CollectionTools; +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.ListIterable; +import org.eclipse.jpt.common.utility.internal.iterables.LiveCloneListIterable; +import org.eclipse.jpt.common.utility.internal.iterables.SingleElementListIterable; +import org.eclipse.jpt.jpa.core.context.Entity; +import org.eclipse.jpt.jpa.core.context.JoinColumn; +import org.eclipse.jpt.jpa.core.context.JoinColumnRelationship; +import org.eclipse.jpt.jpa.core.context.JoinColumnRelationshipStrategy; +import org.eclipse.jpt.jpa.core.context.ReadOnlyBaseJoinColumn; +import org.eclipse.jpt.jpa.core.context.ReadOnlyJoinColumn; +import org.eclipse.jpt.jpa.core.context.Relationship; +import org.eclipse.jpt.jpa.core.context.RelationshipMapping; +import org.eclipse.jpt.jpa.core.context.TypeMapping; +import org.eclipse.jpt.jpa.core.context.java.JavaAssociationOverrideContainer; +import org.eclipse.jpt.jpa.core.context.java.JavaReadOnlyAssociationOverride; +import org.eclipse.jpt.jpa.core.context.java.JavaVirtualJoinColumn; +import org.eclipse.jpt.jpa.core.context.java.JavaVirtualJoinColumnRelationship; +import org.eclipse.jpt.jpa.core.context.java.JavaVirtualJoinColumnRelationshipStrategy; +import org.eclipse.jpt.jpa.core.context.java.JavaVirtualOverrideRelationship; +import org.eclipse.jpt.jpa.core.internal.context.ContextContainerTools; +import org.eclipse.jpt.jpa.core.internal.context.java.AbstractJavaJpaContextNode; + +public class GenericJavaVirtualOverrideJoinColumnRelationshipStrategy + extends AbstractJavaJpaContextNode + implements JavaVirtualJoinColumnRelationshipStrategy +{ + protected final Vector<JavaVirtualJoinColumn> specifiedJoinColumns = new Vector<JavaVirtualJoinColumn>(); + protected final SpecifiedJoinColumnContainerAdapter specifiedJoinColumnContainerAdapter; + protected final ReadOnlyJoinColumn.Owner joinColumnOwner; + + protected JavaVirtualJoinColumn defaultJoinColumn; + + + public GenericJavaVirtualOverrideJoinColumnRelationshipStrategy(JavaVirtualJoinColumnRelationship parent) { + super(parent); + this.specifiedJoinColumnContainerAdapter = this.buildSpecifiedJoinColumnContainerAdapter(); + this.joinColumnOwner = this.buildJoinColumnOwner(); + } + + + // ********** synchronize/update ********** + + @Override + public void update() { + super.update(); + this.updateSpecifiedJoinColumns(); + this.updateDefaultJoinColumn(); + } + + + // ********** join columns ********** + + public ListIterator<JavaVirtualJoinColumn> joinColumns() { + return this.getJoinColumns().iterator(); + } + + protected ListIterable<JavaVirtualJoinColumn> getJoinColumns() { + return this.hasSpecifiedJoinColumns() ? this.getSpecifiedJoinColumns() : this.getDefaultJoinColumns(); + } + + public int joinColumnsSize() { + return this.hasSpecifiedJoinColumns() ? this.specifiedJoinColumnsSize() : this.getDefaultJoinColumnsSize(); + } + + + // ********** specified join columns ********** + + public ListIterator<JavaVirtualJoinColumn> specifiedJoinColumns() { + return this.getSpecifiedJoinColumns().iterator(); + } + + protected ListIterable<JavaVirtualJoinColumn> getSpecifiedJoinColumns() { + return new LiveCloneListIterable<JavaVirtualJoinColumn>(this.specifiedJoinColumns); + } + + public int specifiedJoinColumnsSize() { + return this.specifiedJoinColumns.size(); + } + + public boolean hasSpecifiedJoinColumns() { + return this.specifiedJoinColumns.size() != 0; + } + + public JavaVirtualJoinColumn getSpecifiedJoinColumn(int index) { + return this.specifiedJoinColumns.get(index); + } + + protected void updateSpecifiedJoinColumns() { + ContextContainerTools.update(this.specifiedJoinColumnContainerAdapter); + } + + protected Iterable<JoinColumn> getOverriddenSpecifiedJoinColumns() { + JoinColumnRelationshipStrategy overriddenStrategy = this.getOverriddenStrategy(); + return (overriddenStrategy == null) ? + EmptyIterable.<JoinColumn>instance() : + CollectionTools.iterable(overriddenStrategy.specifiedJoinColumns()); + } + + protected void moveSpecifiedJoinColumn(int index, JavaVirtualJoinColumn joinColumn) { + this.moveItemInList(index, joinColumn, this.specifiedJoinColumns, SPECIFIED_JOIN_COLUMNS_LIST); + } + + protected JavaVirtualJoinColumn addSpecifiedJoinColumn(int index, JoinColumn joinColumn) { + JavaVirtualJoinColumn virtualJoinColumn = this.buildJoinColumn(joinColumn); + this.addItemToList(index, virtualJoinColumn, this.specifiedJoinColumns, SPECIFIED_JOIN_COLUMNS_LIST); + return virtualJoinColumn; + } + + protected void removeSpecifiedJoinColumn(JavaVirtualJoinColumn joinColumn) { + this.removeItemFromList(joinColumn, this.specifiedJoinColumns, SPECIFIED_JOIN_COLUMNS_LIST); + } + + protected SpecifiedJoinColumnContainerAdapter buildSpecifiedJoinColumnContainerAdapter() { + return new SpecifiedJoinColumnContainerAdapter(); + } + + /** + * specified join column container adapter + */ + protected class SpecifiedJoinColumnContainerAdapter + implements ContextContainerTools.Adapter<JavaVirtualJoinColumn, JoinColumn> + { + public Iterable<JavaVirtualJoinColumn> getContextElements() { + return GenericJavaVirtualOverrideJoinColumnRelationshipStrategy.this.getSpecifiedJoinColumns(); + } + public Iterable<JoinColumn> getResourceElements() { + return GenericJavaVirtualOverrideJoinColumnRelationshipStrategy.this.getOverriddenSpecifiedJoinColumns(); + } + public JoinColumn getResourceElement(JavaVirtualJoinColumn contextElement) { + return contextElement.getOverriddenColumn(); + } + public void moveContextElement(int index, JavaVirtualJoinColumn element) { + GenericJavaVirtualOverrideJoinColumnRelationshipStrategy.this.moveSpecifiedJoinColumn(index, element); + } + public void addContextElement(int index, JoinColumn resourceElement) { + GenericJavaVirtualOverrideJoinColumnRelationshipStrategy.this.addSpecifiedJoinColumn(index, resourceElement); + } + public void removeContextElement(JavaVirtualJoinColumn element) { + GenericJavaVirtualOverrideJoinColumnRelationshipStrategy.this.removeSpecifiedJoinColumn(element); + } + } + + protected ReadOnlyJoinColumn.Owner buildJoinColumnOwner() { + return new JoinColumnOwner(); + } + + + // ********** default join column ********** + + public JavaVirtualJoinColumn getDefaultJoinColumn() { + return this.defaultJoinColumn; + } + + protected void setDefaultJoinColumn(JavaVirtualJoinColumn joinColumn) { + JavaVirtualJoinColumn old = this.defaultJoinColumn; + this.defaultJoinColumn = joinColumn; + this.firePropertyChanged(DEFAULT_JOIN_COLUMN_PROPERTY, old, joinColumn); + } + + protected ListIterable<JavaVirtualJoinColumn> getDefaultJoinColumns() { + return (this.defaultJoinColumn != null) ? + new SingleElementListIterable<JavaVirtualJoinColumn>(this.defaultJoinColumn) : + EmptyListIterable.<JavaVirtualJoinColumn>instance(); + } + + protected int getDefaultJoinColumnsSize() { + return (this.defaultJoinColumn == null) ? 0 : 1; + } + + protected void updateDefaultJoinColumn() { + JoinColumn overriddenDefaultJoinColumn = this.getOverriddenDefaultJoinColumn(); + if (overriddenDefaultJoinColumn == null) { + if (this.defaultJoinColumn != null) { + this.setDefaultJoinColumn(null); + } + } else { + if ((this.defaultJoinColumn != null) && (this.defaultJoinColumn.getOverriddenColumn() == overriddenDefaultJoinColumn)) { + this.defaultJoinColumn.update(); + } else { + this.setDefaultJoinColumn(this.buildJoinColumn(overriddenDefaultJoinColumn)); + } + } + } + + protected JoinColumn getOverriddenDefaultJoinColumn() { + JoinColumnRelationshipStrategy overriddenStrategy = this.getOverriddenStrategy(); + return (overriddenStrategy == null) ? null : overriddenStrategy.getDefaultJoinColumn(); + } + + + // ********** misc ********** + + @Override + public JavaVirtualJoinColumnRelationship getParent() { + return (JavaVirtualJoinColumnRelationship) super.getParent(); + } + + public JavaVirtualJoinColumnRelationship getRelationship() { + return this.getParent(); + } + + protected JoinColumnRelationshipStrategy getOverriddenStrategy() { + JoinColumnRelationship relationship = this.getOverriddenJoinColumnRelationship(); + return (relationship == null) ? null : relationship.getJoinColumnStrategy(); + } + + protected JoinColumnRelationship getOverriddenJoinColumnRelationship() { + Relationship relationship = this.resolveOverriddenRelationship(); + return (relationship instanceof JoinColumnRelationship) ? (JoinColumnRelationship) relationship : null; + } + + protected Relationship resolveOverriddenRelationship() { + return this.getRelationship().resolveOverriddenRelationship(); + } + + public boolean isTargetForeignKey() { + RelationshipMapping relationshipMapping = this.getRelationshipMapping(); + return (relationshipMapping != null) && + relationshipMapping.getRelationship().isTargetForeignKey(); + } + + public TypeMapping getRelationshipSource() { + return this.isTargetForeignKey() ? + this.getRelationshipMapping().getResolvedTargetEntity() : + this.getAssociationOverrideContainer().getTypeMapping(); + } + + public TypeMapping getRelationshipTarget() { + return this.isTargetForeignKey() ? + this.getAssociationOverrideContainer().getTypeMapping() : + this.getRelationshipMappingTargetEntity(); + } + + protected TypeMapping getRelationshipMappingTargetEntity() { + RelationshipMapping mapping = this.getRelationshipMapping(); + return (mapping == null) ? null : mapping.getResolvedTargetEntity(); + } + + protected Entity getRelationshipTargetEntity() { + TypeMapping target = this.getRelationshipTarget(); + return (target instanceof Entity) ? (Entity) target : null; + } + + protected RelationshipMapping getRelationshipMapping() { + return this.getAssociationOverride().getMapping(); + } + + protected JavaReadOnlyAssociationOverride getAssociationOverride() { + return ((JavaVirtualOverrideRelationship) this.getRelationship()).getAssociationOverride(); + } + + protected JavaAssociationOverrideContainer getAssociationOverrideContainer() { + return this.getAssociationOverride().getContainer(); + } + + public String getTableName() { + return this.isTargetForeignKey() ? + this.getSourceTableName() : + this.getAssociationOverrideContainer().getDefaultTableName(); + } + + protected String getSourceTableName() { + TypeMapping typeMapping = this.getRelationshipSource(); + return (typeMapping == null) ? null : typeMapping.getPrimaryTableName(); + } + + public TextRange getValidationTextRange(CompilationUnit astRoot) { + return null; + } + + protected String getAttributeName() { + return this.getAssociationOverride().getName(); + } + + protected JavaVirtualJoinColumn buildJoinColumn(JoinColumn overriddenJoinColumn) { + return this.getJpaFactory().buildJavaVirtualJoinColumn(this, this.joinColumnOwner, overriddenJoinColumn); + } + + + // ********** join column owner ********** + + protected class JoinColumnOwner + implements ReadOnlyJoinColumn.Owner + { + protected JoinColumnOwner() { + super(); + } + + public String getDefaultTableName() { + return GenericJavaVirtualOverrideJoinColumnRelationshipStrategy.this.getTableName(); + } + + public String getDefaultColumnName() { + //built in MappingTools.buildJoinColumnDefaultName() + return null; + } + + public String getAttributeName() { + return GenericJavaVirtualOverrideJoinColumnRelationshipStrategy.this.getAttributeName(); + } + + public TypeMapping getTypeMapping() { + return GenericJavaVirtualOverrideJoinColumnRelationshipStrategy.this.getRelationshipSource(); + } + + public Entity getRelationshipTarget() { + return GenericJavaVirtualOverrideJoinColumnRelationshipStrategy.this.getRelationshipTargetEntity(); + } + + public boolean joinColumnIsDefault(ReadOnlyBaseJoinColumn joinColumn) { + return false; + } + + public int joinColumnsSize() { + return GenericJavaVirtualOverrideJoinColumnRelationshipStrategy.this.joinColumnsSize(); + } + } +} diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaVirtualOverrideRelationship.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaVirtualOverrideRelationship.java new file mode 100644 index 0000000000..b75f1d81a3 --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaVirtualOverrideRelationship.java @@ -0,0 +1,169 @@ +/******************************************************************************* + * Copyright (c) 2010, 2011 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.jpa1.context.java; + +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jpt.common.core.utility.TextRange; +import org.eclipse.jpt.jpa.core.context.Entity; +import org.eclipse.jpt.jpa.core.context.OverrideRelationship; +import org.eclipse.jpt.jpa.core.context.Relationship; +import org.eclipse.jpt.jpa.core.context.RelationshipMapping; +import org.eclipse.jpt.jpa.core.context.TypeMapping; +import org.eclipse.jpt.jpa.core.context.java.JavaVirtualAssociationOverride; +import org.eclipse.jpt.jpa.core.context.java.JavaVirtualJoinColumnRelationshipStrategy; +import org.eclipse.jpt.jpa.core.context.java.JavaVirtualJoinTableRelationshipStrategy; +import org.eclipse.jpt.jpa.core.context.java.JavaVirtualRelationshipStrategy; +import org.eclipse.jpt.jpa.core.internal.context.java.AbstractJavaJpaContextNode; +import org.eclipse.jpt.jpa.core.internal.jpa2.context.java.GenericJavaVirtualOverrideJoinTableRelationshipStrategy2_0; +import org.eclipse.jpt.jpa.core.jpa2.context.java.JavaVirtualOverrideRelationship2_0; + +public class GenericJavaVirtualOverrideRelationship + extends AbstractJavaJpaContextNode + implements JavaVirtualOverrideRelationship2_0 +{ + protected JavaVirtualRelationshipStrategy strategy; + + protected final JavaVirtualJoinColumnRelationshipStrategy joinColumnStrategy; + + // JPA 2.0 + protected final JavaVirtualJoinTableRelationshipStrategy joinTableStrategy; + + + public GenericJavaVirtualOverrideRelationship(JavaVirtualAssociationOverride parent) { + super(parent); + this.joinColumnStrategy = this.buildJoinColumnStrategy(); + this.joinTableStrategy = this.buildJoinTableStrategy(); + } + + + // ********** synchronize/update ********** + + @Override + public void update() { + super.update(); + this.setStrategy(this.buildStrategy()); + this.joinColumnStrategy.update(); + this.joinTableStrategy.update(); + } + + + // ********** strategy ********** + + public JavaVirtualRelationshipStrategy getStrategy() { + return this.strategy; + } + + protected void setStrategy(JavaVirtualRelationshipStrategy strategy) { + JavaVirtualRelationshipStrategy old = this.strategy; + this.strategy = strategy; + this.firePropertyChanged(STRATEGY_PROPERTY, old, strategy); + } + + protected JavaVirtualRelationshipStrategy buildStrategy() { + if (this.isJpa2_0Compatible()) { + if (this.joinColumnStrategy.hasSpecifiedJoinColumns()) { + return this.joinColumnStrategy; + } + return this.joinTableStrategy; + } + return this.joinColumnStrategy; + } + + + // ********** join column strategy ********** + + public JavaVirtualJoinColumnRelationshipStrategy getJoinColumnStrategy() { + return this.joinColumnStrategy; + } + + public boolean strategyIsJoinColumn() { + return this.strategy == this.joinColumnStrategy; + } + + public boolean mayHaveDefaultJoinColumn() { + return false; + } + + protected JavaVirtualJoinColumnRelationshipStrategy buildJoinColumnStrategy() { + return new GenericJavaVirtualOverrideJoinColumnRelationshipStrategy(this); + } + + + // ********** join table strategy ********** + + public JavaVirtualJoinTableRelationshipStrategy getJoinTableStrategy() { + return this.joinTableStrategy; + } + + public boolean strategyIsJoinTable() { + return this.strategy == this.joinTableStrategy; + } + + public boolean mayHaveDefaultJoinTable() { + return this.isVirtual(); + } + + protected JavaVirtualJoinTableRelationshipStrategy buildJoinTableStrategy() { + return new GenericJavaVirtualOverrideJoinTableRelationshipStrategy2_0(this); + } + + + // ********** conversions ********** + + public void initializeOn(Relationship newRelationship) { + newRelationship.initializeFromJoinTableRelationship(this); + newRelationship.initializeFromJoinColumnRelationship(this); + } + + public void initializeOnSpecified(OverrideRelationship specifiedRelationship) { + specifiedRelationship.initializeFromVirtualJoinColumnRelationship(this); + specifiedRelationship.initializeFromVirtualJoinTableRelationship(this); + } + + + // ********** misc ********** + + @Override + public JavaVirtualAssociationOverride getParent() { + return (JavaVirtualAssociationOverride) super.getParent(); + } + + public JavaVirtualAssociationOverride getAssociationOverride() { + return this.getParent(); + } + + public TypeMapping getTypeMapping() { + return this.getAssociationOverride().getContainer().getTypeMapping(); + } + + public Entity getEntity() { + TypeMapping typeMapping = this.getTypeMapping(); + return (typeMapping instanceof Entity) ? (Entity) typeMapping : null; + } + + public boolean isVirtual() { + return true; + } + + public RelationshipMapping getMapping() { + return this.getAssociationOverride().getMapping(); + } + + public Relationship resolveOverriddenRelationship() { + return this.getAssociationOverride().resolveOverriddenRelationship(); + } + + + // ********** validation ********** + + public TextRange getValidationTextRange(CompilationUnit astRoot) { + return null; + } +} diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaVirtualUniqueConstraint.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaVirtualUniqueConstraint.java new file mode 100644 index 0000000000..388f871257 --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/GenericJavaVirtualUniqueConstraint.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2008, 2010 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.jpa1.context.java; + +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jpt.common.core.utility.TextRange; +import org.eclipse.jpt.jpa.core.context.UniqueConstraint; +import org.eclipse.jpt.jpa.core.context.java.JavaJpaContextNode; +import org.eclipse.jpt.jpa.core.context.java.JavaVirtualUniqueConstraint; +import org.eclipse.jpt.jpa.core.internal.context.java.AbstractJavaReadOnlyUniqueConstraint; + +public class GenericJavaVirtualUniqueConstraint + extends AbstractJavaReadOnlyUniqueConstraint + implements JavaVirtualUniqueConstraint +{ + protected final UniqueConstraint overriddenUniqueConstraint; + + + public GenericJavaVirtualUniqueConstraint(JavaJpaContextNode parent, UniqueConstraint overriddenUniqueConstraint) { + super(parent); + this.overriddenUniqueConstraint = overriddenUniqueConstraint; + } + + + // ********** synchronize/update ********** + + @Override + public void update() { + super.update(); + this.syncColumnNames(); + } + + + // ********** validation ********** + + public TextRange getValidationTextRange(CompilationUnit astRoot) { + return null; + } + + + // ********** misc ********** + + public UniqueConstraint getOverriddenUniqueConstraint() { + return this.overriddenUniqueConstraint; + } + + @Override + protected Iterable<String> getResourceColumnNames() { + return this.overriddenUniqueConstraint.getColumnNames(); + } +} diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/NullJavaConverter.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/NullJavaConverter.java new file mode 100644 index 0000000000..3908130b3c --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/NullJavaConverter.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2010 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.jpa1.context.java; + +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jpt.common.core.utility.TextRange; +import org.eclipse.jpt.jpa.core.context.Converter; +import org.eclipse.jpt.jpa.core.context.java.JavaAttributeMapping; +import org.eclipse.jpt.jpa.core.context.java.JavaConverter; +import org.eclipse.jpt.jpa.core.internal.context.java.AbstractJavaJpaContextNode; +import org.eclipse.jpt.jpa.core.resource.java.Annotation; + +public class NullJavaConverter + extends AbstractJavaJpaContextNode + implements JavaConverter +{ + public NullJavaConverter(JavaAttributeMapping parent) { + super(parent); + } + + @Override + public JavaAttributeMapping getParent() { + return (JavaAttributeMapping) super.getParent(); + } + + public Class<? extends Converter> getType() { + return null; + } + + public Annotation getConverterAnnotation() { + return null; + } + + public void dispose() { + // NOP + } + + public TextRange getValidationTextRange(CompilationUnit astRoot) { + return null; + } +} diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/NullJavaJoinColumnRelationshipStrategy.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/NullJavaJoinColumnRelationshipStrategy.java new file mode 100644 index 0000000000..61ba4bc7bc --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/NullJavaJoinColumnRelationshipStrategy.java @@ -0,0 +1,166 @@ +/******************************************************************************* + * Copyright (c) 2010, 2011 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.jpa1.context.java; + +import java.util.ListIterator; +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jpt.common.core.utility.TextRange; +import org.eclipse.jpt.common.utility.internal.iterators.EmptyListIterator; +import org.eclipse.jpt.jpa.core.context.JoinColumn; +import org.eclipse.jpt.jpa.core.context.ReadOnlyJoinColumnRelationshipStrategy; +import org.eclipse.jpt.jpa.core.context.RelationshipMapping; +import org.eclipse.jpt.jpa.core.context.TypeMapping; +import org.eclipse.jpt.jpa.core.context.java.JavaJoinColumn; +import org.eclipse.jpt.jpa.core.context.java.JavaJoinColumnRelationship; +import org.eclipse.jpt.jpa.core.context.java.JavaJoinColumnRelationshipStrategy; +import org.eclipse.jpt.jpa.core.internal.context.java.AbstractJavaJpaContextNode; +import org.eclipse.jpt.jpa.db.Table; + +/** + * Used by + * {@link org.eclipse.jpt.jpa.core.internal.context.java.GenericJavaOneToManyRelationship#buildJoinColumnStrategy()} + * in a JPA 1.0 project. + */ +public class NullJavaJoinColumnRelationshipStrategy + extends AbstractJavaJpaContextNode + implements JavaJoinColumnRelationshipStrategy +{ + public NullJavaJoinColumnRelationshipStrategy(JavaJoinColumnRelationship parent) { + super(parent); + } + + + // ********** join columns ********** + + public ListIterator<JavaJoinColumn> joinColumns() { + return EmptyListIterator.<JavaJoinColumn>instance(); + } + + public int joinColumnsSize() { + return 0; + } + + + // ********** specified join columns ********** + + public ListIterator<JavaJoinColumn> specifiedJoinColumns() { + return EmptyListIterator.<JavaJoinColumn>instance(); + } + + public int specifiedJoinColumnsSize() { + return 0; + } + + public boolean hasSpecifiedJoinColumns() { + return false; + } + + public JavaJoinColumn getSpecifiedJoinColumn(int index) { + throw new UnsupportedOperationException(); + } + + public JavaJoinColumn addSpecifiedJoinColumn() { + throw new UnsupportedOperationException(); + } + + public JavaJoinColumn addSpecifiedJoinColumn(int index) { + throw new UnsupportedOperationException(); + } + + public void removeSpecifiedJoinColumn(JoinColumn joinColumn) { + throw new UnsupportedOperationException(); + } + + public void removeSpecifiedJoinColumn(int index) { + throw new UnsupportedOperationException(); + } + + public void moveSpecifiedJoinColumn(int targetIndex, int sourceIndex) { + throw new UnsupportedOperationException(); + } + + + // ********** default join column ********** + + public JavaJoinColumn getDefaultJoinColumn() { + return null; + } + + + // ********** misc ********** + + @Override + public JavaJoinColumnRelationship getParent() { + return (JavaJoinColumnRelationship) super.getParent(); + } + + public JavaJoinColumnRelationship getRelationship() { + return this.getParent(); + } + + protected RelationshipMapping getRelationshipMapping() { + return this.getRelationship().getMapping(); + } + + public String getTableName() { + return null; + } + + public TypeMapping getRelationshipSource() { + return this.getRelationshipMapping().getTypeMapping(); + } + + public TypeMapping getRelationshipTarget() { + return null; + } + + public boolean isTargetForeignKey() { + return false; + } + + public void initializeFrom(ReadOnlyJoinColumnRelationshipStrategy oldStrategy) { + // NOP + } + + public void initializeFromVirtual(ReadOnlyJoinColumnRelationshipStrategy oldStrategy) { + // NOP + } + + public void addStrategy() { + // NOP + } + + public void removeStrategy() { + // NOP + } + + public boolean isOverridable() { + return false; + } + + public boolean tableNameIsInvalid(String tableName) { + return true; + } + + public Table resolveDbTable(String tableName) { + return null; + } + + + // ********** validation ********** + + public TextRange getValidationTextRange(CompilationUnit astRoot) { + return null; + } + + public String getColumnTableNotValidDescription() { + return null; + } +} diff --git a/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/NullJavaJoinTableRelationshipStrategy.java b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/NullJavaJoinTableRelationshipStrategy.java new file mode 100644 index 0000000000..b5df2972f5 --- /dev/null +++ b/jpa/plugins/org.eclipse.jpt.jpa.core/src/org/eclipse/jpt/jpa/core/internal/jpa1/context/java/NullJavaJoinTableRelationshipStrategy.java @@ -0,0 +1,115 @@ +/******************************************************************************* + * Copyright (c) 2010, 2011 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.jpa1.context.java; + +import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jpt.common.core.utility.TextRange; +import org.eclipse.jpt.jpa.core.context.JoinColumn; +import org.eclipse.jpt.jpa.core.context.ReadOnlyJoinTableRelationshipStrategy; +import org.eclipse.jpt.jpa.core.context.JoinColumn.Owner; +import org.eclipse.jpt.jpa.core.context.java.JavaJoinTable; +import org.eclipse.jpt.jpa.core.context.java.JavaJoinTableRelationship; +import org.eclipse.jpt.jpa.core.context.java.JavaJoinTableRelationshipStrategy; +import org.eclipse.jpt.jpa.core.internal.context.JoinColumnTextRangeResolver; +import org.eclipse.jpt.jpa.core.internal.context.JptValidator; +import org.eclipse.jpt.jpa.core.internal.context.java.AbstractJavaJpaContextNode; +import org.eclipse.jpt.jpa.core.resource.java.JoinTableAnnotation; +import org.eclipse.jpt.jpa.db.Table; + +public class NullJavaJoinTableRelationshipStrategy + extends AbstractJavaJpaContextNode + implements JavaJoinTableRelationshipStrategy +{ + public NullJavaJoinTableRelationshipStrategy(JavaJoinTableRelationship parent) { + super(parent); + } + + + // ********** join table ********** + + public JavaJoinTable getJoinTable() { + return null; + } + + public JoinTableAnnotation getJoinTableAnnotation() { + return null; + } + + + // ********** validation ********** + + public TextRange getValidationTextRange(CompilationUnit astRoot) { + throw new UnsupportedOperationException(); + } + + + // ********** misc ********** + + @Override + public JavaJoinTableRelationship getParent() { + return (JavaJoinTableRelationship) super.getParent(); + } + + public JavaJoinTableRelationship getRelationship() { + return this.getParent(); + } + + public void initializeFrom(ReadOnlyJoinTableRelationshipStrategy oldStrategy) { + // NOP + } + + public void initializeFromVirtual(ReadOnlyJoinTableRelationshipStrategy virtualStrategy) { + // NOP + } + + public String getTableName() { + return null; + } + + public Table resolveDbTable(String tableName) { + return null; + } + + public boolean tableNameIsInvalid(String tableName) { + return true; + } + + public String getColumnTableNotValidDescription() { + return null; + } + + public String getJoinTableDefaultName() { + return null; + } + + public void addStrategy() { + // NOP + } + + public void removeStrategy() { + // NOP + } + + public boolean isOverridable() { + return false; + } + + public boolean validatesAgainstDatabase() { + return false; + } + + public JptValidator buildJoinTableJoinColumnValidator(JoinColumn column, Owner owner, JoinColumnTextRangeResolver textRangeResolver) { + throw new UnsupportedOperationException(); + } + + public JptValidator buildJoinTableInverseJoinColumnValidator(JoinColumn column, Owner owner, JoinColumnTextRangeResolver textRangeResolver) { + throw new UnsupportedOperationException(); + } +} |