/** * Copyright (c) 2006 IBM Corporation and others. * 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: * IBM - Initial API and implementation */ package org.eclipse.emf.codegen.merge.java.facade.ast; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.eclipse.jdt.core.dom.ASTNode; import org.eclipse.jdt.core.dom.BodyDeclaration; import org.eclipse.jdt.core.dom.IExtendedModifier; import org.eclipse.jdt.core.dom.Modifier; import org.eclipse.jdt.core.dom.rewrite.ListRewrite; import org.eclipse.emf.codegen.merge.java.facade.JMember; import org.eclipse.emf.codegen.merge.java.facade.JNode; /** * Each <code>ASTJMember</code> has a reference to {@link BodyDeclaration} as a wrapped object. * * @param <T> wrapped body declaration type * * @since 2.2.0 */ public abstract class ASTJMember<T extends BodyDeclaration> extends ASTJNode<T> implements JMember { /** * Cached value of member comment. * @see #getComment() * @see #setComment(String) */ protected String comment = UNITIALIZED_STRING; /** * @param bodyDeclaration */ public ASTJMember(T bodyDeclaration) { super(bodyDeclaration); } @Override public void dispose() { comment = null; super.dispose(); } /** * Returns original flags of the member. * * @see org.eclipse.emf.codegen.merge.java.facade.AbstractJNode#getFlags() */ @Override public int getFlags() { return getASTNode().getModifiers(); } /** * Sets the flags of the member. * <p> * Note that <code>getFlags()</code> will not return the new value. * * @see org.eclipse.emf.codegen.merge.java.facade.ast.ASTJNode#setFlags(int) */ @Override public void setFlags(int flags) { BodyDeclaration bodyDeclaration = getASTNode(); ListRewrite listRewrite = rewriter.getListRewrite(bodyDeclaration, bodyDeclaration.getModifiersProperty()); // remove all existing modifiers @SuppressWarnings("unchecked") List<IExtendedModifier> existingModifiers = listRewrite.getRewrittenList(); for (IExtendedModifier modifier : existingModifiers) { if (modifier.isModifier()) { listRewrite.remove((ASTNode)modifier, null); } } // create new modifiers and add to rewrite @SuppressWarnings("unchecked") List<Modifier> newModifiers = bodyDeclaration.getAST().newModifiers(flags); for (Modifier modifier : newModifiers) { listRewrite.insertLast(modifier, null); } } public String getComment() { if (comment == UNITIALIZED_STRING) { comment = getFacadeHelper().toString(getASTNode().getJavadoc()); } return comment; } public void setComment(String comment) { this.comment = comment; setTrackedNodeProperty(getASTNode(), comment, getASTNode().getJavadocProperty(), ASTNode.JAVADOC); } /* (non-Javadoc) * @see org.eclipse.emf.codegen.merge.java.facade.ast.ASTJNode#remove(org.eclipse.emf.codegen.merge.java.facade.ast.ASTJNode) */ @Override public boolean remove(ASTJNode<?> node) { if (node.getParent() != this) { return false; } if (node instanceof ASTJAnnotation) { remove(node, getASTNode().getModifiersProperty()); return true; } return false; } /* (non-Javadoc) * @see org.eclipse.emf.codegen.merge.java.facade.ast.ASTJNode#insertSibling(org.eclipse.emf.codegen.merge.java.facade.ast.ASTJNode, org.eclipse.emf.codegen.merge.java.facade.ast.ASTJNode, boolean) */ @Override public boolean insertSibling(ASTJNode<?> node, ASTJNode<?> newSibling, boolean before) { if (newSibling.getParent() != null || node.getParent() != this) { return false; } if (newSibling instanceof ASTJAnnotation) { if (node instanceof ASTJAnnotation) { insert(newSibling, getASTNode().getModifiersProperty(), node, before); } else { insertLastAnnotation((ASTJAnnotation)newSibling); } return true; } return false; } /* (non-Javadoc) * @see org.eclipse.emf.codegen.merge.java.facade.ast.ASTJNode#addChild(org.eclipse.emf.codegen.merge.java.facade.ast.ASTJNode) */ @Override public boolean addChild(ASTJNode<?> child) { if (child.getParent() != null) { return false; } if (child instanceof ASTJAnnotation) { insertLastAnnotation((ASTJAnnotation)child); return true; } return false; } /* (non-Javadoc) * @see org.eclipse.emf.codegen.merge.java.facade.AbstractJNode#getChildren() */ @Override public List<JNode> getChildren() { if (!isDisposed()) { List<JNode> children = new ArrayList<JNode>(); children.addAll(getAnnotationList()); if (!children.isEmpty()) { return Collections.unmodifiableList(children); } } return Collections.emptyList(); } protected List<JNode> getAnnotationList() { List<JNode> annotations = new ArrayList<JNode>(); ListRewrite listRewrite = rewriter.getListRewrite(getASTNode(), getASTNode().getModifiersProperty()); @SuppressWarnings("unchecked") List<IExtendedModifier> modifiers = listRewrite.getRewrittenList(); for (IExtendedModifier extendedModifier : modifiers) { if (extendedModifier.isAnnotation()) { JNode annotation = getFacadeHelper().convertToNode(extendedModifier); // specify the exact parent of annotations ((ASTJNode<?>)annotation).setParent(this); annotations.add(annotation); } } return annotations; } /** * Insert annotation after the last annotation of the given body declaration. * <p> * Note that modifiers and annotations can alternate in the modifiers list. * This method inserts the new annotation after the last existing annotation. * * @param annotation */ protected void insertLastAnnotation(ASTJAnnotation annotation) { List<JNode> annotations = getAnnotationList(); if (annotations.size() > 0) { ASTJNode<?> lastAnnotation = (ASTJNode<?>)annotations.get(annotations.size() - 1); insert(annotation, getASTNode().getModifiersProperty(), lastAnnotation, false); } else { insertFirst(annotation, getASTNode().getModifiersProperty()); } } }