KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > formatter > comment > MultiCommentRegion


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11
12 package org.eclipse.jdt.internal.formatter.comment;
13
14 import java.util.Iterator JavaDoc;
15 import java.util.ListIterator JavaDoc;
16
17 import org.eclipse.jdt.internal.formatter.CodeFormatterVisitor;
18 import org.eclipse.jface.text.BadLocationException;
19 import org.eclipse.jface.text.IDocument;
20 import org.eclipse.jface.text.Position;
21
22 /**
23  * Multi-comment region in a source code document.
24  *
25  * @since 3.0
26  */

27 public class MultiCommentRegion extends CommentRegion implements IJavaDocTagConstants {
28
29     /** Should root tag parameter descriptions be indented after the tag? */
30     private final boolean fIndentDescriptions;
31
32     /** Should root tag parameter descriptions be indented? */
33     private final boolean fIndentRoots;
34
35     /** Should description of parameters go to the next line? */
36     private final boolean fParameterNewLine;
37
38     /** Should root tags be separated from description? */
39     private boolean fSeparateRoots;
40
41     /**
42      * Creates a new multi-comment region.
43      *
44      * @param document the document which contains the comment region
45      * @param position the position of this comment region in the document
46      * @param formatter the given formatter
47      */

48     public MultiCommentRegion(final IDocument document, final Position position, final CodeFormatterVisitor formatter) {
49         super(document, position, formatter);
50
51         fIndentRoots= this.preferences.comment_indent_root_tags;
52         fIndentDescriptions= this.preferences.comment_indent_parameter_description;
53         fSeparateRoots= this.preferences.comment_insert_empty_line_before_root_tags;
54         fParameterNewLine= this.preferences.comment_insert_new_line_for_parameter;
55         fClear = this.preferences.comment_clear_blank_lines_in_block_comment;
56     }
57
58     /*
59      * @see org.eclipse.jdt.internal.corext.text.comment.CommentRegion#canAppend(org.eclipse.jdt.internal.corext.text.comment.CommentLine, org.eclipse.jdt.internal.corext.text.comment.CommentRange, org.eclipse.jdt.internal.corext.text.comment.CommentRange, int, int)
60      */

61     protected boolean canAppend(final CommentLine line, final CommentRange previous, final CommentRange next, final int index, int count) {
62
63         final boolean blank= next.hasAttribute(COMMENT_BLANKLINE);
64
65         // Avoid wrapping punctuation
66
if (next.getLength() <= 2 && !blank && isNonAlphaNumeric(next))
67             return true;
68
69         if (fParameterNewLine && line.hasAttribute(COMMENT_PARAMETER) && line.getSize() > 1)
70             return false;
71
72         if (previous != null) {
73             
74             if (index != 0 && (blank || previous.hasAttribute(COMMENT_BLANKLINE) || next.hasAttribute(COMMENT_PARAMETER) || next.hasAttribute(COMMENT_ROOT) || next.hasAttribute(COMMENT_SEPARATOR) || next.hasAttribute(COMMENT_NEWLINE) || previous.hasAttribute(COMMENT_BREAK) || previous.hasAttribute(COMMENT_SEPARATOR)))
75                 return false;
76             
77             if (previous.hasAttribute(COMMENT_ROOT))
78                 return true;
79
80             if (next.hasAttribute(COMMENT_IMMUTABLE) && previous.hasAttribute(COMMENT_IMMUTABLE))
81                 return true;
82         }
83
84         // always append elements that did not have any range separators
85
if (!next.hasAttribute(COMMENT_STARTS_WITH_RANGE_DELIMITER)) {
86             return true;
87         }
88
89         if (fIndentRoots && !line.hasAttribute(COMMENT_ROOT) && !line.hasAttribute(COMMENT_PARAMETER))
90             count -= stringToLength(line.getIndentationReference());
91
92         // Avoid appending consecutive immutable ranges, which together exceed the line width
93
if (next.hasAttribute(COMMENT_IMMUTABLE) && (previous == null || !previous.hasAttribute(COMMENT_IMMUTABLE))) {
94             // Breaking the abstraction by directly accessing the list of ranges for looking ahead
95
Iterator JavaDoc iter= getRanges().iterator();
96             CommentRange current= null;
97             while (iter.hasNext() && current != next)
98                 current= (CommentRange) iter.next();
99             
100             if (current != null && iter.hasNext()) {
101                 try {
102                     int lineNumber= getDocument().getLineOfOffset(getOffset() + current.getOffset());
103                     CommentRange last= current;
104                     while (iter.hasNext()) {
105                         current= (CommentRange) iter.next();
106                         if (current.hasAttribute(COMMENT_IMMUTABLE) && getDocument().getLineOfOffset(getOffset() + current.getOffset()) == lineNumber)
107                             last= current;
108                         else
109                             break;
110                     }
111                     count -= last.getOffset() + last.getLength() - (next.getOffset() + next.getLength());
112                 } catch (BadLocationException e) {
113                     // Should not happen
114
}
115             }
116         }
117
118         return super.canAppend(line, previous, next, index, count);
119     }
120
121     /*
122      * @see org.eclipse.jdt.internal.corext.text.comment.CommentRegion#getDelimiter(org.eclipse.jdt.internal.corext.text.comment.CommentLine, org.eclipse.jdt.internal.corext.text.comment.CommentLine, org.eclipse.jdt.internal.corext.text.comment.CommentRange, org.eclipse.jdt.internal.corext.text.comment.CommentRange, java.lang.String)
123      */

124     protected String JavaDoc getDelimiter(CommentLine predecessor, CommentLine successor, CommentRange previous, CommentRange next, String JavaDoc indentation) {
125
126         final String JavaDoc delimiter= super.getDelimiter(predecessor, successor, previous, next, indentation);
127
128         if (previous != null) {
129
130             // Blank line before <pre> tag
131
if (previous.hasAttribute(COMMENT_IMMUTABLE | COMMENT_SEPARATOR) && !next.hasAttribute(COMMENT_CODE) && !successor.hasAttribute(COMMENT_BLANKLINE))
132                 return delimiter + delimiter;
133
134             // Blank line after </pre> tag
135
else if (next.hasAttribute(COMMENT_IMMUTABLE | COMMENT_SEPARATOR) && !successor.hasAttribute(COMMENT_BLANKLINE) && !predecessor.hasAttribute(COMMENT_BLANKLINE))
136                 return delimiter + delimiter;
137
138             // Add blank line before first root/parameter tag, if "Blank line before Javadoc tags"
139
else if (fSeparateRoots && previous.hasAttribute(COMMENT_PARAGRAPH) && !successor.hasAttribute(COMMENT_BLANKLINE) && !predecessor.hasAttribute(COMMENT_BLANKLINE))
140                 return delimiter + delimiter;
141
142             else if (fIndentRoots && !predecessor.hasAttribute(COMMENT_ROOT) && !predecessor.hasAttribute(COMMENT_PARAMETER) && !predecessor.hasAttribute(COMMENT_BLANKLINE))
143                 return delimiter + stringToIndent(predecessor.getIndentationReference());
144         }
145         return delimiter;
146     }
147
148     /*
149      * @see org.eclipse.jdt.internal.corext.text.comment.CommentRegion#getDelimiter(org.eclipse.jdt.internal.corext.text.comment.CommentRange, org.eclipse.jdt.internal.corext.text.comment.CommentRange)
150      */

151     protected String JavaDoc getDelimiter(final CommentRange previous, final CommentRange next) {
152         // simply preserve range (~ word) breaks
153
if (previous != null && !previous.hasAttribute(COMMENT_STARTS_WITH_RANGE_DELIMITER)) {
154             return ""; //$NON-NLS-1$
155
} else {
156             return super.getDelimiter(previous, next);
157         }
158     }
159
160     /**
161      * Should root tag parameter descriptions be indented after the tag?
162      *
163      * @return <code>true</code> iff the descriptions should be indented
164      * after, <code>false</code> otherwise.
165      */

166     protected final boolean isIndentDescriptions() {
167         return fIndentDescriptions;
168     }
169
170     /**
171      * Should root tag parameter descriptions be indented?
172      *
173      * @return <code>true</code> iff the root tags should be indented,
174      * <code>false</code> otherwise.
175      */

176     protected final boolean isIndentRoots() {
177         return fIndentRoots;
178     }
179
180     /**
181      * Marks the comment ranges confined by HTML ranges.
182      */

183     protected void markHtmlRanges() {
184         // Do nothing
185
}
186
187     /**
188      * Marks the comment range with its HTML tag attributes.
189      *
190      * @param range the comment range to mark
191      * @param token token associated with the comment range
192      */

193     protected void markHtmlTag(final CommentRange range, final char[] token) {
194         // Do nothing
195
}
196
197     /**
198      * Marks the comment range with its javadoc tag attributes.
199      *
200      * @param range the comment range to mark
201      * @param token token associated with the comment range
202      */

203     protected void markJavadocTag(final CommentRange range, final char[] token) {
204         range.markPrefixTag(COMMENT_ROOT_TAGS, COMMENT_TAG_PREFIX, token, COMMENT_ROOT);
205     }
206
207     /*
208      * @see org.eclipse.jdt.internal.corext.text.comment.CommentRegion#markRegion()
209      */

210     protected void markRegion() {
211
212         int count= 0;
213         boolean paragraph= false;
214
215         char[] token= null;
216         CommentRange range= null;
217
218         for (final ListIterator JavaDoc iterator= getRanges().listIterator(); iterator.hasNext();) {
219
220             range= (CommentRange)iterator.next();
221             count= range.getLength();
222
223             if (count > 0) {
224
225                 token= getText(range.getOffset(), count).toLowerCase().toCharArray();
226
227                 markJavadocTag(range, token);
228                 if (!paragraph && (range.hasAttribute(COMMENT_ROOT) || range.hasAttribute(COMMENT_PARAMETER))) {
229                     range.setAttribute(COMMENT_PARAGRAPH);
230                     paragraph= true;
231                 }
232                 markHtmlTag(range, token);
233             }
234         }
235         markHtmlRanges();
236     }
237     
238     /*
239      * @see org.eclipse.jdt.internal.corext.text.comment.CommentRegion#createLine()
240      * @since 3.1
241      */

242     protected CommentLine createLine() {
243         return new MultiCommentLine(this);
244     }
245 }
246
Popular Tags