|
What this is
Other links
The source code/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is NetBeans. The Initial Developer of the Original * Code is Sun Microsystems, Inc. Portions Copyright 1997-2004 Sun * Microsystems, Inc. All Rights Reserved. */ package org.netbeans.modules.javacore.jmiimpl.javamodel; import org.netbeans.jmi.javamodel.*; import org.netbeans.lib.java.parser.ASTree; import org.netbeans.lib.java.parser.ParserTokens; import org.netbeans.lib.java.parser.Token; import org.netbeans.mdr.handlers.BaseObjectHandler; import org.netbeans.mdr.persistence.StorageException; import org.netbeans.mdr.storagemodel.StorableObject; import org.netbeans.modules.javacore.ClassIndex; import org.netbeans.modules.javacore.JMManager; import org.netbeans.modules.javacore.parser.ASTProvider; import org.netbeans.modules.javacore.parser.ElementInfo; import org.netbeans.modules.javacore.parser.FeatureInfo; import org.netbeans.modules.javacore.parser.JavaDocParser; import org.openide.ErrorManager; import org.openide.util.Utilities; import javax.jmi.model.MofClass; import javax.jmi.reflect.ConstraintViolationException; import javax.jmi.reflect.RefFeatured; import javax.jmi.reflect.RefObject; import java.lang.reflect.Modifier; import java.util.*; import org.netbeans.api.mdr.MDRepository; import org.netbeans.modules.javacore.internalapi.JavaMetamodel; import org.netbeans.modules.javacore.parser.MDRParser; import org.netbeans.modules.javacore.parser.TypeRef; import org.openide.text.PositionBounds; /** Implementation of Feature object instance interface. * * @author Vladimir Hudec * @author Pavel Flaska */ public abstract class FeatureImpl extends SemiPersistentElement { public static final int DEPRECATED = 0x80000000; public static final String TYPE_PARAMETERS_ATTR = "typeParameters"; // NOI18N protected String javadocText = null; protected JavaDoc javadoc = null; protected LightAttrList annotations = null; /** Creates a new instance of FeatureImpl */ public FeatureImpl(StorableObject s) { super(s); } protected void initChildren() { annotations = createChildrenList(annotations, "annotations", // NOI18N ((FeatureInfo) getElementInfo()).annotations, CHANGED_ANNOTATION, false); } protected void resetChildren() { if (childrenInited) { if (annotations != null) { createChildrenList(annotations, "annotations", ((FeatureInfo) getElementInfo()).annotations, CHANGED_ANNOTATION, true); // NOI18N } } } /** * Returns the value of attribute annotations. * @return Value of annotations attribute. */ public List getAnnotations() { if (!childrenInited) { initChildren(); } return annotations != null ? annotations : Collections.EMPTY_LIST; } protected abstract void super_setModifiers(int modifiers); protected abstract int super_getModifiers(); /** * Returns the value of attribute modifiers. * @return Value of attribute modifiers. */ public int getModifiers() { int mods = super_getModifiers(); ClassDefinition cd = getDeclaringClass(); if (cd instanceof JavaClass) { JavaClass jc = (JavaClass)cd; if ((jc.getModifiers() & Modifier.STRICT) != 0) { mods = mods | Modifier.STRICT; } if (jc.isInterface()) { mods = mods | Modifier.PUBLIC; if (this instanceof Method) { mods |= Modifier.ABSTRACT; } } else { if (this instanceof Method && ((jc.getModifiers() & Modifier.FINAL) != 0)) { mods |= Modifier.FINAL; } } } return ~DEPRECATED & mods; } public int getSourceModifiers() { int mods = super_getModifiers(); return ~DEPRECATED & mods; } /** * Sets the value of modifiers attribute. See {@link #getModifiers} for description * on the attribute. * @param newValue New value to be set. */ public void setModifiers(int newValue) { boolean isDeprecated = isDeprecated(); objectChanged(CHANGED_MODIFIERS); super_setModifiers((newValue & ~DEPRECATED) | (isDeprecated ? DEPRECATED : 0)); } public boolean isDeprecated() { int mods = super_getModifiers(); return (mods & DEPRECATED) != 0; } public void setDeprecated(boolean deprecated) { throw new UnsupportedOperationException(); } /** * Returns the value of attribute javadocText. * * IT'S POSSIBLE TO USE SIMPLE IMPLEMENTATION JavaDocParser.surroundWithJavaDocStars() * * @return Value of attribute javadocText. */ public java.lang.String getJavadocText() { if (isChanged(CHANGED_JAVADOC) && javadoc != null) { List tags = javadoc.getTags(); JavaDocParser.JavaDocTag[] javaDocTags = null; if (tags != null) { javaDocTags = new JavaDocParser.JavaDocTag[tags.size()]; int i = 0; for (Iterator it = tags.iterator(); it.hasNext(); ) { TagValue tagValue = (TagValue) it.next(); javaDocTags[i++] = new JavaDocParser.JavaDocTag(tagValue.getDefinition().getName(), tagValue.getValue()); } } JavaDocParser parser = new JavaDocParser(javadoc.getText(), javaDocTags); return parser.getRawText(true); // reorder tags } else if (isChanged(CHANGED_JAVADOC)) return javadocText; else { MDRParser parser = getParser(); if (parser != null) { String s = parser.getJavaDoc(getASTree()); if (s == null) // there is no javadoc return null; if (s.startsWith("\n")) { return s.substring(1); } if (s.startsWith("\r\n")) { // to be sure that it works on Win too return s.substring(2); } return s; } } return null; } /** * Sets the value of javadocText attribute. See {@link #getJavadocText} for * description on the attribute. * @param newValue New value to be set. */ public void setJavadocText(java.lang.String newValue) { objectChanged(CHANGED_JAVADOC); javadoc = null; javadocText = newValue; if (Utilities.compareObjects(getParser().getJavaDoc(getASTree()), newValue)) { resetChange(CHANGED_JAVADOC); } } /** * Returns the value of attribute javadoc. * @return Value of attribute javadoc. */ public JavaDoc getJavadoc() { if (isChanged(CHANGED_JAVADOC) && javadoc != null) return javadoc; String javaDocText = getJavadocText(); if (javaDocText == null) return null; JavaModelPackage pkg = (JavaModelPackage) refImmediatePackage(); TagValueClassImpl tagValueClass = (TagValueClassImpl) pkg.getTagValue(); JavaDocClassImpl javaDocClass = (JavaDocClassImpl) pkg.getJavaDoc(); JavaDocParser parser = new JavaDocParser(javaDocText); JavaDocParser.JavaDocTag[] tags = parser.getTags(); List tagsList = new ArrayList(); String text = null; if (tags != null && tags.length > 0) { for (int i = 0; i < tags.length; i++) { JavaDocParser.JavaDocTag tag = tags[i]; if (tag.isText()) { text = tag.getValue(); continue; } String tagName = tag.getName(); String tagText = tag.getValue(); tagsList.add(tagValueClass.create(tagName, tagText)); } } JavaDocImpl javaDoc = (JavaDocImpl) javaDocClass.createJavaDoc(text, tagsList); if (javadocText != null) this.javadocText = null; changeChild(this.javadoc, javaDoc); return this.javadoc = javaDoc; } /** * Sets the value of javadoc attribute. See {@link #getJavadoc} for description * on the attribute. * @param newValue New value to be set. */ public void setJavadoc(JavaDoc newValue) { if (javadocText != null) throw new ConstraintViolationException(this, getNameAttr("javadoc"), "Can't set both JavaDoc as a text and as an object."); // NOI18N objectChanged(CHANGED_JAVADOC); changeChild(this.javadoc, newValue); this.javadoc = newValue; } /** Helper class */ public ClassDefinition getDeclaringClass() { RefFeatured obj = refImmediateComposite(); if (obj instanceof ClassDefinition) { return (ClassDefinition) obj; } else if (this instanceof Field && obj instanceof FieldGroup) { return ((FieldGroup) obj).getDeclaringClass(); } return null; } public PositionBounds getPosition() { ResourceImpl resource = (ResourceImpl)getResource(); PositionBounds result = resource.getFeaturePosition(this); if (result != null) return result; else { MDRepository repository = repository(); repository.beginTrans(false); try { if (((JMManager) JavaMetamodel.getManager()).getTransactionMutex().getClassPath() == null) { JavaMetamodel.getManager().setClassPath(resource); } return super.getPosition(); } finally { repository.endTrans(false); } } } /** Helper method */ protected RefObject getNameAttr(String name) { try { return ((MofClass) refMetaObject()).lookupElementExtended(name); } catch (javax.jmi.model.NameNotFoundException e) { return null; } } /** * Adds the new diff item to the list if the javaDoc is changed in element, * otherwise it does nothing. * todo (#pf): currently, we use only javadocText. * * @param diff list of collected differences where the new element is added */ protected void replaceJavaDoc(List diff) { if (isChanged(CHANGED_JAVADOC)) { ASTree tree = getASTree(); Token docToken = getParser().getComment(tree); // todo (#pf): now we only handle javaDoc text, we ignore // settings from model -- (For the time being it is enough // to provide information for compatability bridge.) String newContent = JavaDocParser.surroundWithJavaDocStars(javadocText); if (docToken.getType() == ParserTokens.DOC_COMMENT && javadocText != null) { // replace the original javaDoc if exists already diff.add(new DiffElement(docToken.getStartOffset(), docToken.getEndOffset(), indentJavaDoc(newContent).trim() ) ); // We cannot use general replaceNode method because it // doesn't work on padding token. (Method getFirstToken() // and getLastToken() cannot return token indexes because they // aren't in the token list.) // // replaceNode(diff, // getParser(), // docToken, // , // docToken.getStartOffset(), // null); } else { // we have to reset original javadoc if (javadocText == null) { int startOffset = docToken.getStartOffset(); int endOffset = docToken.getEndOffset(); if (getParser().getSourceText().length() > endOffset) { int temp = getParser().getSourceText().indexOf('\n', endOffset); if (temp > -1) { endOffset = temp + 1; } } diff.add(new DiffElement(startOffset, endOffset, "")); } else { // create new javaDoc in case it didn't exist yet // we will look for the last new line before the element. The // comment will be put before this new line. If the new line // does not exist before the element, we will put the javadoc // comment directly before the first char of the element. int startOffset = getLastNewLineOffset(docToken) + 1; if (startOffset < 0) { startOffset = docToken.getStartOffset(); } diff.add(new DiffElement(startOffset, startOffset, indentJavaDoc(newContent + '\n') ) ); } } } } /** * Looks for the last new line before the token in its paddings. * * @param token token to look for the new line before * @return offset of the last new line in the token's paddings */ private int getLastNewLineOffset(Token token) { Token[] pad = token.getPadding(); // previously, empty array was returned - with gjast.jar, it is possible // to get null value. We have to check it. if (pad == null) return -1; for (int i = pad.length; i > 0; i--) { if (pad[i-1].getType() == ParserTokens.EOL) { String value = getParser().getText(pad[i-1]); return pad[i-1].getStartOffset() + value.lastIndexOf('\n'); } } return -1; } /** * Replaces JavaDoc, leaves the paddings for the token as they * were. * * @param javadoc javadoc to be printed * @param token first element token * @param buf add doc to the buf * @param lastPrinted lastPrinted character * * @return index of the last printed character */ protected int printJavaDoc(String javadoc, Token token, StringBuffer buf, int lastPrinted) { ASTProvider parser = getParser(); String origSrc = parser.getSourceText(); Token comment = parser.getComment(getASTree()); String newJavadoc = indentJavaDoc(JavaDocParser.surroundWithJavaDocStars(getJavadocText())); if (comment.getType() == ParserTokens.DOC_COMMENT) { int startOffset = comment.getStartOffset(); if (lastPrinted < startOffset) buf.append(origSrc.substring(lastPrinted, startOffset)); buf.append(newJavadoc.trim()); lastPrinted = token.getStartOffset(); buf.append(origSrc.substring(comment.getEndOffset(), lastPrinted)); } else { int startOffset = getBeginIndex(); lastPrinted = token.getStartOffset(); String paddings = origSrc.substring(startOffset, lastPrinted); StringTokenizer tokenizer = new StringTokenizer(paddings, "\n", true); // NOI18N String toPrint = ""; while (tokenizer.hasMoreTokens()) { buf.append(toPrint); toPrint = tokenizer.nextToken(); } if (toPrint.length() == 0) { buf.append(newJavadoc); buf.append('\n'); buf.append(getIndentation()); } else { buf.append(newJavadoc); if (!toPrint.equals("\n")) // NOI18N buf.append('\n'); buf.append(toPrint); } } return lastPrinted; } protected void diffModifiers(List diffList, ASTree nextNode, ASTProvider parser) { String text = Modifier.toString(getSourceModifiers()); int nextToken = nextNode.getFirstToken(); int startOffset, endOffset; int startToken; endOffset = parser.getToken(nextToken).getStartOffset(); ASTree modifiers = getASTree().getSubTrees()[0]; if (modifiers != null) { startToken = modifiers.getFirstToken(); startOffset = parser.getToken(startToken).getStartOffset(); if (text.length() != 0) { int endToken = modifiers.getLastToken(); endOffset = parser.getToken(endToken).getEndOffset(); } } else { startOffset = endOffset; text += ' '; } for (Iterator annIt = getAnnotations().iterator(); annIt.hasNext(); ) { AnnotationImpl ann = (AnnotationImpl) annIt.next(); text = ann.getSourceText() + ' ' + text; } diffList.add(new DiffElement(startOffset, endOffset, text)); } /** * Generates element's javadoc and appends it to the buffer. * * @param buf buffer to append javadoc to * @return true, if there is JavaDoc, otherwise false */ public boolean generateNewJavaDoc(StringBuffer buf) { String javadoc = getJavadocText(); if (javadoc != null) { buf.append(indentJavaDoc(JavaDocParser.surroundWithJavaDocStars(javadoc))); buf.append('\n'); return true; } else return false; } /** * Generates element's modifiers and append them to the buffer. * Moreover, it appends also annotation for this feature. * * @param buf append modifiers to the buffer * @return true if there is any modifier, otherwise false */ public boolean generateNewModifiers(StringBuffer buf) { for (Iterator annIt = getAnnotations().iterator(); annIt.hasNext(); ) { AnnotationImpl ann = (AnnotationImpl) annIt.next(); buf.append(ann.getSourceText()).append(' '); } String modString = Modifier.toString(getSourceModifiers()); if (modString.length() > 0) { buf.append(modString); buf.append(' '); return true; } else return false; } /** * Find referenced resources using ClassIndex.findResourcesForIdentifier(). * Modifiers are considered to reduce number of resources */ Resource[] findReferencedResources() { return findReferencedResources(false); } /** * Find referenced resources using ClassIndex.findResourcesForIdentifier(). * Modifiers are considered to reduce number of resources */ Resource[] findReferencedResources(boolean includeLibraries) { int modifiers=getModifiers(); String name; Resource[] res; if (Modifier.isPrivate(modifiers)) { return new Resource[] {getResource()}; } if (this instanceof JavaClass) { name=((JavaClass)this).getSimpleName(); } else if (this instanceof Constructor) { name=((JavaClass)getDeclaringClass()).getSimpleName(); } else { name=getName(); } res=ClassIndex.findResourcesForIdentifier(name, includeLibraries); if (Modifier.isPublic(modifiers) || Modifier.isProtected(modifiers)) { if (this instanceof Field) { Element cd = getDeclaringClass(); while (!((cd instanceof JavaClass) && !((JavaClass) cd).isInner())) { cd = (Element) cd.refImmediateComposite(); } int mods = ((JavaClass) cd).getModifiers(); if (!(Modifier.isPublic(mods) || Modifier.isProtected(mods))) { return filterResourcesFromThisPackage(res); } } return res; } return filterResourcesFromThisPackage(res); } Resource[] filterResourcesFromThisPackage(Resource[] res) { List filteredResources=new ArrayList(res.length); String packageName=getResource().getPackageName(); for (int i=0;i |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.