diff options
Diffstat (limited to 'jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/utility/jdt/CombinationIndexedDeclarationAnnotationAdapter.java')
-rw-r--r-- | jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/utility/jdt/CombinationIndexedDeclarationAnnotationAdapter.java | 493 |
1 files changed, 0 insertions, 493 deletions
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/utility/jdt/CombinationIndexedDeclarationAnnotationAdapter.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/utility/jdt/CombinationIndexedDeclarationAnnotationAdapter.java deleted file mode 100644 index 2fbc8a715f..0000000000 --- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/utility/jdt/CombinationIndexedDeclarationAnnotationAdapter.java +++ /dev/null @@ -1,493 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2006, 2008 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.core.internal.utility.jdt; - -import java.util.List; -import org.eclipse.jdt.core.dom.ASTNode; -import org.eclipse.jdt.core.dom.Annotation; -import org.eclipse.jdt.core.dom.Expression; -import org.eclipse.jdt.core.dom.MarkerAnnotation; -import org.eclipse.jdt.core.dom.MemberValuePair; -import org.eclipse.jdt.core.dom.NormalAnnotation; -import org.eclipse.jdt.core.dom.SingleMemberAnnotation; -import org.eclipse.jpt.core.utility.jdt.DeclarationAnnotationAdapter; -import org.eclipse.jpt.core.utility.jdt.IndexedDeclarationAnnotationAdapter; -import org.eclipse.jpt.core.utility.jdt.ModifiedDeclaration; -import org.eclipse.jpt.utility.internal.StringTools; - -/** - * Manipulate an annotation that either occurs stand-alone, e.g. - * <pre> - * @Inner("zero") - * private int id; - * </pre> - * - * or is embedded in an element array within another annotation, e.g. - * <pre> - * @Outer(foo={@Inner("zero"), @Inner("one"), @Inner("two")}) - * private int id; - * - * annotationName = "Inner" - * containerAnnotationName = "Outer" - * elementName = "foo" - * index = 0-2 - * </pre> - * - * This is a useful pattern because a declaration cannot have more - * than one annotation of the same type, and allowing the stand-alone - * configuration reduces clutter. - * <br> - * NB: This configuration only makes sense for "top-level" annotations, as - * opposed to "nested" annotations. This is because annotation elements - * can only be declared with a type of a single annotation and annotations - * cannot be part of an inheritance hierarchy. - * For example, the following configurations cannot *both* be supported: - * <pre> - * @Foo(bar=@Outer(...)) - * private int id; - * - * @Foo(bar=@Inner(...)) // not allowed - * private int id; - * </pre> - * - * NB: Behavior is undefined when both the stand-alone and the nested - * configurations annotate the same declaration, e.g. - * <pre> - * // undefined behavior - * @Inner("zero") - * @Outer(foo={@Inner("zero"), @Inner("one"), @Inner("two")}) - * private int id; - * </pre> - */ -public class CombinationIndexedDeclarationAnnotationAdapter - implements IndexedDeclarationAnnotationAdapter -{ - - /** - * this adapter is used when the annotation is "stand-alone": - * <pre> - * @Inner("zero") - * </pre> - * and is only used when the index is 0 or 1 - */ - private final SimpleDeclarationAnnotationAdapter standAloneAnnotationAdapter; - - /** - * this adapter is used when the annotation is "nested": - * <pre> - * @Outer(foo={@Inner("zero"), @Inner("one")}) - * </pre> - */ - private final NestedIndexedDeclarationAnnotationAdapter nestedAnnotationAdapter; - - /** - * this adapter is for the "nested" annotation at the zero index; - * and is only used when the index is 1 - */ - private final NestedIndexedDeclarationAnnotationAdapter zeroNestedAnnotationAdapter; - - - // ********** constructors ********** - - /** - * default element name is "value" - * <pre> - * @Inner("zero") - * @Outer({@Inner("zero"), @Inner("one")}) - * </pre> - */ - public CombinationIndexedDeclarationAnnotationAdapter(String annotationName, String containerAnnotationName, int index) { - this(annotationName, containerAnnotationName, "value", index); - } - - public CombinationIndexedDeclarationAnnotationAdapter(String annotationName, String containerAnnotationName, String elementName, int index) { - this(new SimpleDeclarationAnnotationAdapter(annotationName), new SimpleDeclarationAnnotationAdapter(containerAnnotationName), elementName, index, annotationName); - } - - /** - * default element name is "value" - */ - public CombinationIndexedDeclarationAnnotationAdapter( - SimpleDeclarationAnnotationAdapter standAloneAnnotationAdapter, - SimpleDeclarationAnnotationAdapter containerAnnotationAdapter, - int index, - String nestedAnnotationName - ) { - this(standAloneAnnotationAdapter, containerAnnotationAdapter, "value", index, nestedAnnotationName); - } - - public CombinationIndexedDeclarationAnnotationAdapter( - SimpleDeclarationAnnotationAdapter standAloneAnnotationAdapter, - SimpleDeclarationAnnotationAdapter containerAnnotationAdapter, - String elementName, - int index, - String nestedAnnotationName - ) { - super(); - this.standAloneAnnotationAdapter = standAloneAnnotationAdapter; - this.nestedAnnotationAdapter = new NestedIndexedDeclarationAnnotationAdapter(containerAnnotationAdapter, elementName, index, nestedAnnotationName); - this.zeroNestedAnnotationAdapter = new NestedIndexedDeclarationAnnotationAdapter(containerAnnotationAdapter, elementName, 0, nestedAnnotationName); - } - - - // ********** DeclarationAnnotationAdapter implementation ********** - - public Annotation getAnnotation(ModifiedDeclaration declaration) { - if (this.getIndex() == 0) { - // check for the stand-alone annotation - Annotation standAloneAnnotation = this.getStandAloneAnnotation(declaration); - if (standAloneAnnotation != null) { - return standAloneAnnotation; - } - } - return this.getNestedAnnotation(declaration); - } - - /** - * <pre> - * [none] => @Inner - * or - * @Inner("lorem ipsum") => @Inner - * or - * @Inner(text="lorem ipsum") => @Inner - * or - * @Outer(foo={@Inner, @Inner}) => @Outer(foo={@Inner, @Inner, @Inner}) - * or - * @Outer(foo=@Inner) => @Outer(foo={@Inner, @Inner}) - * or - * @Inner => @Outer(foo={@Inner, @Inner}) - * etc. - * </pre> - */ - public MarkerAnnotation newMarkerAnnotation(ModifiedDeclaration declaration) { - return (MarkerAnnotation) this.newAnnotation(MARKER_ANNOTATION_FACTORY, declaration); - } - - public SingleMemberAnnotation newSingleMemberAnnotation(ModifiedDeclaration declaration) { - return (SingleMemberAnnotation) this.newAnnotation(SINGLE_MEMBER_ANNOTATION_FACTORY, declaration); - } - - public NormalAnnotation newNormalAnnotation(ModifiedDeclaration declaration) { - return (NormalAnnotation) this.newAnnotation(NORMAL_ANNOTATION_FACTORY, declaration); - } - - public void removeAnnotation(ModifiedDeclaration declaration) { - if (this.getIndex() == 0) { - // check for the stand-alone annotation - if (this.standAloneAnnotationIsPresent(declaration)) { - this.removeStandAloneAnnotation(declaration); - return; - } - } - this.removeNestedAnnotation(declaration); - if (this.nestedElementCanBeConvertedToStandAlone(declaration)) { - this.convertLastElementAnnotationToStandAloneAnnotation(declaration); - } - } - - public ASTNode getAstNode(ModifiedDeclaration declaration) { - // if the annotation is missing, delegate to the nested annotation adapter - Annotation annotation = this.getAnnotation(declaration); - return (annotation != null) ? annotation : this.nestedAnnotationAdapter.getAstNode(declaration); - } - - @Override - public String toString() { - return StringTools.buildToStringFor(this, this.getAnnotationName()); - } - - - // ********** IndexedDeclarationAnnotationAdapter implementation ********** - - public int getIndex() { - return this.nestedAnnotationAdapter.getIndex(); - } - - public void moveAnnotation(int newIndex, ModifiedDeclaration declaration) { - int oldIndex = this.getIndex(); - if (newIndex == oldIndex) { - return; - } - - Annotation standAloneAnnotation = this.getStandAloneAnnotation(declaration); - if (standAloneAnnotation == null) { - this.moveNestedAnnotation(newIndex, declaration); - if (this.nestedElementCanBeConvertedToStandAlone(declaration)) { - this.convertLastElementAnnotationToStandAloneAnnotation(declaration); - } - } else { - if ((oldIndex == 0) && (newIndex == 1)) { - // this is one of two situations where we transition from standalone to container - this.moveStandAloneAnnotationToContainerAnnotation(standAloneAnnotation, declaration); - this.moveNestedAnnotation(newIndex, declaration); - } else if (newIndex == 0) { - // we are moving a 'null' entry on top of the standalone, so remove it - this.removeStandAloneAnnotation(declaration); - } else { - throw new IllegalStateException("old index = " + oldIndex + "; new index = " + newIndex); - } - } - } - - - // ********** internal methods ********** - - /** - * build the appropriate new annotation, - * which may require moving the 0th annotation from "stand-alone" to "nested" - */ - private Annotation newAnnotation(AnnotationFactory annotationFactory, ModifiedDeclaration declaration) { - if (this.getIndex() == 0) { - return this.newZeroAnnotation(annotationFactory, declaration); - } - if (this.zeroNestedAnnotationIsPresent(declaration)) { - // manipulate the container annotation - ignore the stand-alone annotation(?) - // @Outer(foo=@Inner("zero")) => @Outer(foo={@Inner("zero"), @Inner}) - // or - // @Outer(foo={@Inner("zero"), @Inner("one")}) => @Outer(foo={@Inner("zero"), @Inner}) - return annotationFactory.newAnnotation(this.nestedAnnotationAdapter, declaration); - } - - // this is one of two situations where we transition from standalone to container - this.moveStandAloneAnnotationToContainerAnnotation(declaration); - // once the stand-alone annotation is moved to index=0, build the new annotation at index=1 - return annotationFactory.newAnnotation(this.nestedAnnotationAdapter, declaration); - } - - /** - * the index is 0 - build the appropriate new annotation, - * which may be either "stand-alone" or "nested" - */ - private Annotation newZeroAnnotation(AnnotationFactory annotationFactory, ModifiedDeclaration declaration) { - if (this.standAloneAnnotationIsPresent(declaration)) { - // replace the stand-alone annotation - ignore the container annotation(?) - // @Inner(text="lorem ipsum") => @Inner - return annotationFactory.newAnnotation(this.standAloneAnnotationAdapter, declaration); - } - if (this.containerAnnotationIsPresent(declaration)) { - // manipulate the container annotation - // @Outer(foo=@Inner(text="lorem ipsum")) => @Outer(foo=@Inner) - return annotationFactory.newAnnotation(this.nestedAnnotationAdapter, declaration); - } - // neither annotation is present - add a new stand-alone annotation - return annotationFactory.newAnnotation(this.standAloneAnnotationAdapter, declaration); - } - - /** - * move the stand-alone annotation to the container annotation at index=0 - */ - private void moveStandAloneAnnotationToContainerAnnotation(ModifiedDeclaration declaration) { - Annotation standAloneAnnotation = this.getStandAloneAnnotation(declaration); - if (standAloneAnnotation == null) { - throw new IllegalStateException("the stand-alone annotation is missing"); - } - this.moveStandAloneAnnotationToContainerAnnotation(standAloneAnnotation, declaration); - } - - /** - * move the specified, non-null, stand-alone annotation to - * the container annotation at index=0 - */ - private void moveStandAloneAnnotationToContainerAnnotation(Annotation standAloneAnnotation, ModifiedDeclaration declaration) { - if (standAloneAnnotation.isMarkerAnnotation()) { - this.zeroNestedAnnotationAdapter.newMarkerAnnotation(declaration); - } else if (standAloneAnnotation.isSingleMemberAnnotation()) { - Expression vv = ((SingleMemberAnnotation) standAloneAnnotation).getValue(); - vv = (Expression) ASTNode.copySubtree(vv.getAST(), vv); - this.zeroNestedAnnotationAdapter.newSingleMemberAnnotation(declaration).setValue(vv); - } else if (standAloneAnnotation.isNormalAnnotation()) { - NormalAnnotation newNA = this.zeroNestedAnnotationAdapter.newNormalAnnotation(declaration); - List<MemberValuePair> values = this.values(newNA); - for (MemberValuePair pair : this.values((NormalAnnotation) standAloneAnnotation)) { - values.add((MemberValuePair) ASTNode.copySubtree(pair.getAST(), pair)); - } - } else { - throw new IllegalStateException("unknown annotation type: " + standAloneAnnotation); - } - this.removeStandAloneAnnotation(declaration); - } - - /** - * return whether the "nested" annotation container has been reduced to - * a single element (and the array initializer is converted to just - * the single remaining element) and can be further converted to the - * "stand-alone" annotation: - * <pre> - * @Outer(foo={@Inner("zero"), @Inner("one")}) => - * @Outer(foo=@Inner("zero")) => - * @Inner("zero") - * </pre> - */ - private boolean nestedElementCanBeConvertedToStandAlone(ModifiedDeclaration declaration) { - Annotation containerAnnotation = this.getContainerAnnotation(declaration); - if (containerAnnotation == null) { - return false; - } - if (containerAnnotation.isMarkerAnnotation()) { - return false; - } - if (containerAnnotation.isSingleMemberAnnotation()) { - if (this.getElementName().equals("value")) { - return (((SingleMemberAnnotation) containerAnnotation).getValue().getNodeType() != ASTNode.ARRAY_INITIALIZER) - && (this.zeroNestedAnnotationAdapter.getAnnotation(declaration) != null); - } - return false; - } - if (containerAnnotation.isNormalAnnotation()) { - NormalAnnotation na = (NormalAnnotation) containerAnnotation; - if (na.values().size() == 0) { - return false; // there are no elements present - } - if (na.values().size() != 1) { - return false; // there are other elements present - leave them all alone - } - MemberValuePair pair = (MemberValuePair) na.values().get(0); - if (this.getElementName().equals(pair.getName().getFullyQualifiedName())) { - return (pair.getValue().getNodeType() != ASTNode.ARRAY_INITIALIZER) - && (this.zeroNestedAnnotationAdapter.getAnnotation(declaration) != null); - } - return false; - } - throw new IllegalStateException("unknown annotation type: " + containerAnnotation); - } - - /** - * move the annotation in the container annotation at index=0 - * to the stand-alone annotation - */ - private void convertLastElementAnnotationToStandAloneAnnotation(ModifiedDeclaration declaration) { - Annotation last = this.zeroNestedAnnotationAdapter.getAnnotation(declaration); - if (last == null) { - throw new IllegalStateException("the last nested annotation is missing"); - } else if (last.isMarkerAnnotation()) { - this.newStandAloneMarkerAnnotation(declaration); - } else if (last.isSingleMemberAnnotation()) { - Expression vv = ((SingleMemberAnnotation) last).getValue(); - vv = (Expression) ASTNode.copySubtree(vv.getAST(), vv); - this.newStandAloneSingleMemberAnnotation(declaration).setValue(vv); - } else if (last.isNormalAnnotation()) { - NormalAnnotation newNA = this.newStandAloneNormalAnnotation(declaration); - List<MemberValuePair> values = this.values(newNA); - for (MemberValuePair pair : this.values((NormalAnnotation) last)) { - values.add((MemberValuePair) ASTNode.copySubtree(pair.getAST(), pair)); - } - } else { - throw new IllegalStateException("unknown annotation type: " + last); - } - this.zeroNestedAnnotationAdapter.removeAnnotation(declaration); - } - - private boolean standAloneAnnotationIsPresent(ModifiedDeclaration declaration) { - return this.getStandAloneAnnotation(declaration) != null; - } - - private Annotation getStandAloneAnnotation(ModifiedDeclaration declaration) { - return this.standAloneAnnotationAdapter.getAnnotation(declaration); - } - - private MarkerAnnotation newStandAloneMarkerAnnotation(ModifiedDeclaration declaration) { - return this.standAloneAnnotationAdapter.newMarkerAnnotation(declaration); - } - - private SingleMemberAnnotation newStandAloneSingleMemberAnnotation(ModifiedDeclaration declaration) { - return this.standAloneAnnotationAdapter.newSingleMemberAnnotation(declaration); - } - - private NormalAnnotation newStandAloneNormalAnnotation(ModifiedDeclaration declaration) { - return this.standAloneAnnotationAdapter.newNormalAnnotation(declaration); - } - - private void removeStandAloneAnnotation(ModifiedDeclaration declaration) { - this.standAloneAnnotationAdapter.removeAnnotation(declaration); - } - - private Annotation getNestedAnnotation(ModifiedDeclaration declaration) { - return this.nestedAnnotationAdapter.getAnnotation(declaration); - } - - private void moveNestedAnnotation(int newIndex, ModifiedDeclaration declaration) { - this.nestedAnnotationAdapter.moveAnnotation(newIndex, declaration); - } - - private void removeNestedAnnotation(ModifiedDeclaration declaration) { - this.nestedAnnotationAdapter.removeAnnotation(declaration); - } - - private boolean containerAnnotationIsPresent(ModifiedDeclaration declaration) { - return this.getContainerAnnotation(declaration) != null; - } - - private Annotation getContainerAnnotation(ModifiedDeclaration declaration) { - return this.nestedAnnotationAdapter.getOuterAnnotationAdapter().getAnnotation(declaration); - } - - private boolean zeroNestedAnnotationIsPresent(ModifiedDeclaration declaration) { - return this.getZeroNestedAnnotation(declaration) != null; - } - - private Annotation getZeroNestedAnnotation(ModifiedDeclaration declaration) { - return this.zeroNestedAnnotationAdapter.getAnnotation(declaration); - } - - private String getAnnotationName() { - return this.nestedAnnotationAdapter.getAnnotationName(); - } - - private String getElementName() { - return this.nestedAnnotationAdapter.getElementName(); - } - - @SuppressWarnings("unchecked") - protected List<MemberValuePair> values(NormalAnnotation na) { - return na.values(); - } - - - // ********** annotation factories ********** - - /** - * define interface that allows us to "re-use" the nasty code in - * #newAnnotation(AnnotationFactory, ModifiedDeclaration) - */ - private interface AnnotationFactory { - Annotation newAnnotation(DeclarationAnnotationAdapter adapter, ModifiedDeclaration declaration); - } - - private static final AnnotationFactory MARKER_ANNOTATION_FACTORY = new AnnotationFactory() { - public Annotation newAnnotation(DeclarationAnnotationAdapter adapter, ModifiedDeclaration declaration) { - return adapter.newMarkerAnnotation(declaration); - } - @Override - public String toString() { - return "MarkerAnnotationFactory"; - } - }; - - private static final AnnotationFactory SINGLE_MEMBER_ANNOTATION_FACTORY = new AnnotationFactory() { - public Annotation newAnnotation(DeclarationAnnotationAdapter adapter, ModifiedDeclaration declaration) { - return adapter.newSingleMemberAnnotation(declaration); - } - @Override - public String toString() { - return "SingleMemberAnnotationFactory"; - } - }; - - private static final AnnotationFactory NORMAL_ANNOTATION_FACTORY = new AnnotationFactory() { - public Annotation newAnnotation(DeclarationAnnotationAdapter adapter, ModifiedDeclaration declaration) { - return adapter.newNormalAnnotation(declaration); - } - @Override - public String toString() { - return "NormalAnnotationFactory"; - } - }; - -} |