alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

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-2000 Sun
 * Microsystems, Inc. All Rights Reserved.
 */

package org.openide.src;

import java.util.List;
import java.util.ArrayList;

import org.openide.src.SourceException;
import org.openide.src.JavaDoc;
import org.openide.src.JavaDocTag;

/** Represents a JavaDoc comment block.
*
* @author Jaroslav Tulach, Petr Hrebejk, Petr Hamernik
*/
class JavaDocMemoryImpl implements JavaDoc, java.io.Serializable {

    protected String rawText;

    private transient  String text;

    // PENDING - clear this
 
    private static final JavaDocTagMemoryImpl[] EMPTY_ARRAY = new JavaDocTagMemoryImpl[] {};
    
    /**
     * Native line separator.
     */
    private static final String lineSeparator;
    
    /**
     * length of the native line separator.
     */
    private static final int lineSeparatorLength;
    
    private static final char LINEFEED = '\n';
    
    static {
        String sep = System.getProperty("line.separator"); // NOI18N
        if (sep == null ||
            sep.equals("\n")) { // NOI18N
            lineSeparator = null;
            lineSeparatorLength = 0;
        } else {
            lineSeparator = sep;
            lineSeparatorLength = sep.length();
        }
    }


    /** Constructs the JavaDoc object held in memory. Parses the tags from rawText
     */

    public JavaDocMemoryImpl( String rawText ) {
        this.rawText =  rawText;
    }

    /** Get the entire text of the comment.
    * @return the whole text
    */
    public String getRawText () {
        return rawText;
    }

    /** Set the raw text of the comment.
    * @param s the whole text to set
    * @exception SourceException if the modification cannot be performed
    */
    public void setRawText (String s) throws SourceException {
        rawText = s;
    }

    /** Get the actual text, cleared of all (non-inline) tags.
    * @return the plain text
    */
    public String getText () {
        if ( rawText == null )
            return ""; // NOI18N
        List tmp = new ArrayList();
        parseComment( tmp );
        return text;
    }

    /** Set the actual text.
    * @param s the actual text, without any (non-inline) tags
    * @exception SourceException if the modification cannot be performed
    */
    public void setText (String s) throws SourceException {
        // do a CRLF conversion because different line delimiters would
        // only obscure the text later.
        regenerateRawText( convertNewLines(s), getTags(), getSeeTags() );
    }

    /** Clears the javadoc from the source.
    */
    public void clearJavaDoc() throws SourceException {
        rawText = null;
    }

    /** Test if this javadoc is empty.
    * @return true if it is not generated to the source.
    */
    public boolean isEmpty() {
        return rawText == null;
    }

    /** Gets all tags from comment.
     */
    public JavaDocTag[] getTags() {
        if ( rawText == null )
            return EMPTY_ARRAY;

        List tagList = new ArrayList();

        parseComment( tagList );

        JavaDocTag[] tagArray = new JavaDocTag[ tagList.size() ];
        tagList.toArray( tagArray );

        return tagArray;
    }

    /** Gets all tags of given name
     */
    public JavaDocTag[] getTags( String name ) {
        JavaDocTag[] allTags = getTags();
        ArrayList resultList = new ArrayList( allTags.length );

        for( int i = 0; i < allTags.length; i++ ) {
            if ( allTags[i].name().equals( name ) )
                resultList.add( allTags[i] );
        }

        JavaDocTag result[] = new JavaDocTag[ resultList.size() ];
        resultList.toArray( result );
        return result;
    }

    /** Adds removes or sets tags used in this comment
     * @param elems the new initializers
     * @param action {@link #ADD}, {@link #REMOVE}, or {@link #SET}
     * @exception SourceException if impossible
     */
    synchronized public void  changeTags( JavaDocTag[] tags, int action ) throws SourceException {

        StringBuffer sb = new StringBuffer();

        switch ( action ) {
        case ADD:
        case SET:
            sb.append( action == ADD ? getRawText() : getText() );
            for( int i = 0; i < tags.length; i++ ) {
                sb.append( "\n" ).append( tags[i].toString() ); // NOI18N
            }
            setRawText( sb.toString() );
            break;

        case REMOVE:
            JavaDocTag currTags[] = getTags();
            sb.append( getText() );

            for( int i = 0; i < currTags.length; i++ ) {
                boolean found = false;
                String strTag = currTags[i].toString();
                for( int j = 0; j < tags.length; j ++ ) {
                    if ( strTag.equals( tags[j].toString() ) ) {
                        found = true;
                        break;
                    }
                }
                if ( !found )
                    sb.append( "\n" ).append( strTag ); // NOI18N
            }
            setRawText( sb.toString() );
            break;
        }
    }

    /** Gets all @see tags
     */
    public JavaDocTag.See[] getSeeTags() {

        JavaDocTag[] allTags = getTags();
        ArrayList resultList = new ArrayList( allTags.length );

        for( int i = 0; i < allTags.length; i++ ) {
            if ( allTags[i] instanceof JavaDocTag.See )
                resultList.add( allTags[i] );
        }

        JavaDocTag.See result[] = new JavaDocTag.See[ resultList.size() ];
        resultList.toArray( result );
        return result;
    }


    /** Regenerates the rawText form tags
     */
    protected void regenerateRawText( String text, JavaDocTag[] tags, JavaDocTag.See[] seeTags ) {
        StringBuffer sb = new StringBuffer( text.length() + tags.length * 80 + seeTags.length * 80 );

        sb.append( text );

        for (int i = 0; i < tags.length; i++ ) {
            sb.append( tags[i].toString() );
        }

        for (int i = 0; i < seeTags.length; i++ ) {
            sb.append( seeTags[i].toString() );
        }

        rawText = sb.toString();
    }


    /** The JavaDoc of a class.
    * Class javadoc adds no special tags.
    */
    static class Class extends JavaDocMemoryImpl implements JavaDoc.Class {
        static final long serialVersionUID =3206093459760846163L;
        Class( String rawText ) {
            super( rawText );
        }
    }

    /** The JavaDoc of a field.
    * 

Currently adds special @SerialField tag */ static class Field extends JavaDocMemoryImpl implements JavaDoc.Field { Field ( String rawText ) { super( rawText ); } /** Gets SerialField tags. */ public JavaDocTag.SerialField[] getSerialFieldTags() { JavaDocTag[] allTags = this.getTags(); ArrayList resultList = new ArrayList( allTags.length ); for( int i = 0; i < allTags.length; i++ ) { if ( allTags[i] instanceof JavaDocTag.SerialField ) resultList.add( allTags[i] ); } JavaDocTag.SerialField result[] = new JavaDocTag.SerialField[ resultList.size() ]; resultList.toArray( result ); return result; } } /** The JavaDoc of a method. Adds two special tags: @para tag and @throws tag. */ static class Method extends JavaDocMemoryImpl implements JavaDoc.Method { Method ( String rawText ) { super( rawText ); } /** Gets param tags. */ public JavaDocTag.Param[] getParamTags() { JavaDocTag[] allTags = this.getTags(); ArrayList resultList = new ArrayList( allTags.length ); for( int i = 0; i < allTags.length; i++ ) { if ( allTags[i] instanceof JavaDocTag.Param ) resultList.add( allTags[i] ); } JavaDocTag.Param result[] = new JavaDocTag.Param[ resultList.size() ]; resultList.toArray( result ); return result; } /** Gets throws tags. */ public JavaDocTag.Throws[] getThrowsTags() { JavaDocTag[] allTags = this.getTags(); ArrayList resultList = new ArrayList( allTags.length ); for( int i = 0; i < allTags.length; i++ ) { if ( allTags[i] instanceof JavaDocTag.Throws ) resultList.add( allTags[i] ); } JavaDocTag.Throws result[] = new JavaDocTag.Throws[ resultList.size() ]; resultList.toArray( result ); return result; } } // PRIVATE & UTILITY METHODS ---------------------------------------------------------- /** * Parses the rawText and generates list of tags; */ private void parseComment( List tagList ) { final int IN_TEXT = 1; final int TAG_GAP = 2; final int TAG_NAME = 3; final int TAG_TEXT = 4; int state = IN_TEXT; boolean newLine = true; String tagName = null; int tagStart = 0; int textStart = 0; int textEnd = 0; int lastNonWhite = -1; int len = rawText.length(); for (int inx = 0; inx < len; ++inx) { char ch = rawText.charAt(inx); boolean isWhite = Character.isWhitespace(ch); switch (state) { case IN_TEXT: if (newLine && ch == '@') { parseCommentComponent(tagList, null, 0, textEnd); tagStart = inx; state = TAG_NAME; } break; case TAG_NAME: if (isWhite) { tagName = rawText.substring(tagStart, inx); state = TAG_GAP; } break; case TAG_GAP: if (isWhite) { break; } textStart = inx; state = TAG_TEXT; // Fall through (in case of @tagname\n@anothertagname) case TAG_TEXT: if (newLine && ch == '@') { parseCommentComponent(tagList, tagName, textStart, lastNonWhite + 1); tagStart = inx; state = TAG_NAME; } break; } // more idiot-proof check for newline terminator: if (lineSeparator != null && inx + lineSeparatorLength <= len && rawText.regionMatches(inx, lineSeparator, 0, lineSeparatorLength)) { newLine = true; if (state == IN_TEXT) { textEnd = inx; } // advance the scan pointer after the separator string. inx += lineSeparatorLength - 1; } else if (ch == '\n') { newLine = true; if (state == IN_TEXT) { textEnd = inx; } } else if (!isWhite) { lastNonWhite = inx; newLine = false; } } // Finish what's currently being processed switch (state) { case TAG_NAME: tagName = rawText.substring(tagStart, len); /* fall thru */ case TAG_GAP: textStart = len; /* fall thru */ case TAG_TEXT: case IN_TEXT: parseCommentComponent(tagList, tagName, textStart, lastNonWhite + 1); break; }; } /** * Parses the tag. * Saves away the last parsed item. */ private void parseCommentComponent( List tagList, String tagName, int from, int upto) { String tx = upto <= from ? "" : rawText.substring(from, upto); // NOI18N if (tagName == null) { text = tx; } else { JavaDocTagMemoryImpl tag; if (tagName.equals("@exception") || tagName.equals("@throws")) { // NOI18N warnIfEmpty(tagName, tx); tag = new JavaDocTagMemoryImpl.Throws(tagName, tx); } else if (tagName.equals("@param")) { // NOI18N warnIfEmpty(tagName, tx); tag = new JavaDocTagMemoryImpl.Param(tagName, tx); } else if (tagName.equals("@see")) { // NOI18N warnIfEmpty( tagName, tx); tag = new JavaDocTagMemoryImpl.See(tagName, tx); } else if (tagName.equals("@serialField")) { // NOI18N warnIfEmpty( tagName, tx); tag = new JavaDocTagMemoryImpl.SerialField(tagName, tx); } else if (tagName.equals("@return")) { // NOI18N warnIfEmpty(tagName, tx); tag = new JavaDocTagMemoryImpl(tagName, tx); } else if (tagName.equals("@author")) { // NOI18N warnIfEmpty(tagName, tx); tag = new JavaDocTagMemoryImpl(tagName, tx); } else if (tagName.equals("@version")) { // NOI18N warnIfEmpty( tagName, tx); tag = new JavaDocTagMemoryImpl(tagName, tx); } else { tag = new JavaDocTagMemoryImpl(tagName, tx); } tagList.add(tag); } } // PENDING : REMOVE THIS METHOD private void warnIfEmpty( String tagName, String tx) { /* if (tx.length() == 0) { System.out.println("tag.tag_has_no_arguments" + tagName); // NOI18N } */ } static String convertNewLines(String input) { if (lineSeparator == null) return input; int firstIndex; /*System.err.println("original length = " + input.length()); // NOI18N for (int i = 0; i < input.length(); i++) { System.err.print(((int)input.charAt(i)) + ", "); } */ firstIndex = input.indexOf(lineSeparator); if (firstIndex == -1) return input; // replace from the beginning to the firstIndex StringBuffer result = new StringBuffer(); char[] contents = input.toCharArray(); if (firstIndex > 0) result.append(contents, 0, firstIndex); result.append(LINEFEED); firstIndex += lineSeparatorLength; int lastPos = firstIndex; while (firstIndex < contents.length) { firstIndex = input.indexOf(lineSeparator, firstIndex); if (firstIndex == -1) { // put there the rest of the string. result.append(contents, lastPos, contents.length - lastPos); return result.toString(); } // put the portion not containing the separator. result.append(contents, lastPos, firstIndex - lastPos); result.append(LINEFEED); firstIndex += lineSeparatorLength; lastPos = firstIndex; } // execution comes here only if the line.sep is the last thing // in the string. result.append(contents, lastPos, firstIndex - lastPos); //System.err.println("result length = " + result.length()); // NOI18N return result.toString(); } }

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

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.