KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > ui > text > comment > MultiCommentRegion


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

11
12 package org.eclipse.jdt.internal.ui.text.comment;
13
14 import java.util.Iterator JavaDoc;
15 import java.util.ListIterator JavaDoc;
16 import java.util.Map JavaDoc;
17
18 import org.eclipse.jface.preference.IPreferenceStore;
19
20 import org.eclipse.jface.text.BadLocationException;
21 import org.eclipse.jface.text.IDocument;
22 import org.eclipse.jface.text.TypedPosition;
23
24 import org.eclipse.jdt.ui.PreferenceConstants;
25
26 import org.eclipse.jdt.internal.ui.text.javadoc.ICommentTagConstants;
27
28 /**
29  * Multi-comment region in a source code document.
30  *
31  * @since 3.0
32  */

33 public class MultiCommentRegion extends CommentRegion implements ICommentTagConstants {
34
35     /** Should root tag parameter descriptions be indented after the tag? */
36     private final boolean fIndentDescriptions;
37
38     /** Should root tag parameter descriptions be indented? */
39     private final boolean fIndentRoots;
40
41     /** Should description of parameters go to the next line? */
42     private final boolean fParameterNewLine;
43
44     /** Should root tags be separated from description? */
45     private boolean fSeparateRoots;
46
47     /**
48      * Creates a new multi-comment region.
49      *
50      * @param document
51      * The document which contains the comment region
52      * @param position
53      * The position of this comment region in the document
54      * @param delimiter
55      * The line delimiter of this comment region
56      * @param preferences
57      * The formatting preferences for this region
58      * @param textMeasurement
59      * The text measurement. Can be <code>null</code>.
60      */

61     protected MultiCommentRegion(final IDocument document, final TypedPosition position, final String JavaDoc delimiter, final Map JavaDoc preferences, final ITextMeasurement textMeasurement) {
62         super(document, position, delimiter, preferences, textMeasurement);
63
64         fIndentRoots= IPreferenceStore.TRUE.equals(preferences.get(PreferenceConstants.FORMATTER_COMMENT_INDENTROOTTAGS));
65         fIndentDescriptions= IPreferenceStore.TRUE.equals(preferences.get(PreferenceConstants.FORMATTER_COMMENT_INDENTPARAMETERDESCRIPTION));
66         fSeparateRoots= IPreferenceStore.TRUE.equals(preferences.get(PreferenceConstants.FORMATTER_COMMENT_SEPARATEROOTTAGS));
67         fParameterNewLine= IPreferenceStore.TRUE.equals(preferences.get(PreferenceConstants.FORMATTER_COMMENT_NEWLINEFORPARAMETER));
68     }
69
70     /**
71      * @inheritDoc
72      */

73     protected boolean canAppend(final CommentLine line, final CommentRange previous, final CommentRange next, final int index, int count) {
74
75         final boolean blank= next.hasAttribute(COMMENT_BLANKLINE);
76
77         // Avoid wrapping punctuation
78
if (next.getLength() <= 2 && !blank && isNonAlphaNumeric(next))
79             return true;
80
81         if (fParameterNewLine && line.hasAttribute(COMMENT_PARAMETER) && line.getSize() > 1)
82             return false;
83
84         if (previous != null) {
85
86             if (previous.hasAttribute(COMMENT_ROOT))
87                 return true;
88
89             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)))
90                 return false;
91
92             if (next.hasAttribute(COMMENT_IMMUTABLE) && previous.hasAttribute(COMMENT_IMMUTABLE))
93                 return true;
94         }
95
96         if (fIndentRoots && !line.hasAttribute(COMMENT_ROOT) && !line.hasAttribute(COMMENT_PARAMETER))
97             count -= stringToLength(line.getIndentationReference());
98
99         // Avoid appending consecutive immutable ranges, which together exceed the line width
100
if (next.hasAttribute(COMMENT_IMMUTABLE) && (previous == null || !previous.hasAttribute(COMMENT_IMMUTABLE))) {
101             // Breaking the abstraction by directly accessing the list of ranges for looking ahead
102
Iterator JavaDoc iter= getRanges().iterator();
103             CommentRange current= null;
104             while (iter.hasNext() && current != next)
105                 current= (CommentRange) iter.next();
106             
107             if (current != null && iter.hasNext()) {
108                 try {
109                     int lineNumber= getDocument().getLineOfOffset(getOffset() + current.getOffset());
110                     CommentRange last= current;
111                     while (iter.hasNext()) {
112                         current= (CommentRange) iter.next();
113                         if (current.hasAttribute(COMMENT_IMMUTABLE) && getDocument().getLineOfOffset(getOffset() + current.getOffset()) == lineNumber)
114                             last= current;
115                         else
116                             break;
117                     }
118                     count -= last.getOffset() + last.getLength() - (next.getOffset() + next.getLength());
119                 } catch (BadLocationException e) {
120                     // Should not happen
121
}
122             }
123         }
124
125         return super.canAppend(line, previous, next, index, count);
126     }
127
128     /**
129      * @inheritDoc
130      */

131     protected String JavaDoc getDelimiter(CommentLine predecessor, CommentLine successor, CommentRange previous, CommentRange next, String JavaDoc indentation) {
132
133         final String JavaDoc delimiter= super.getDelimiter(predecessor, successor, previous, next, indentation);
134
135         if (previous != null) {
136
137             // Blank line before <pre> tag
138
if (previous.hasAttribute(COMMENT_IMMUTABLE | COMMENT_SEPARATOR) && !next.hasAttribute(COMMENT_CODE) && !successor.hasAttribute(COMMENT_BLANKLINE))
139                 return delimiter + delimiter;
140
141 // else if (previous.hasAttribute(COMMENT_CODE) && !next.hasAttribute(COMMENT_CODE))
142
// return getDelimiter();
143
//
144
// // remove any asterisk borders inside code sections
145
// else if (previous.hasAttribute(COMMENT_CODE) && next.hasAttribute(COMMENT_CODE))
146
// return getDelimiter();
147

148             // Blank line after </pre> tag
149
else if (next.hasAttribute(COMMENT_IMMUTABLE | COMMENT_SEPARATOR) && !successor.hasAttribute(COMMENT_BLANKLINE) && !predecessor.hasAttribute(COMMENT_BLANKLINE))
150                 return delimiter + delimiter;
151
152             // Add blank line before first root/parameter tag, if "Blank line before Javadoc tags"
153
else if (fSeparateRoots && previous.hasAttribute(COMMENT_PARAGRAPH) && !successor.hasAttribute(COMMENT_BLANKLINE) && !predecessor.hasAttribute(COMMENT_BLANKLINE))
154                 return delimiter + delimiter;
155
156             else if (fIndentRoots && !predecessor.hasAttribute(COMMENT_ROOT) && !predecessor.hasAttribute(COMMENT_PARAMETER) && !predecessor.hasAttribute(COMMENT_BLANKLINE))
157                 return delimiter + stringToIndent(predecessor.getIndentationReference(), false);
158         }
159         return delimiter;
160     }
161
162     /**
163      * @inheritDoc
164      */

165     protected String JavaDoc getDelimiter(final CommentRange previous, final CommentRange next) {
166
167         if (previous != null) {
168
169             if (previous.hasAttribute(COMMENT_HTML) && next.hasAttribute(COMMENT_HTML))
170                 return ""; //$NON-NLS-1$
171

172             else if (next.hasAttribute(COMMENT_OPEN) || previous.hasAttribute(COMMENT_HTML | COMMENT_CLOSE))
173                 return ""; //$NON-NLS-1$
174

175             else if (!next.hasAttribute(COMMENT_CODE) && previous.hasAttribute(COMMENT_CODE))
176                 return ""; //$NON-NLS-1$
177

178             else if (next.hasAttribute(COMMENT_CLOSE) && previous.getLength() <= 2 && !isAlphaNumeric(previous))
179                 return ""; //$NON-NLS-1$
180

181             else if (previous.hasAttribute(COMMENT_OPEN) && next.getLength() <= 2 && !isAlphaNumeric(next))
182                 return ""; //$NON-NLS-1$
183
}
184         return super.getDelimiter(previous, next);
185     }
186
187     /**
188      * Should root tag parameter descriptions be indented after the tag?
189      *
190      * @return <code>true</code> iff the descriptions should be indented
191      * after, <code>false</code> otherwise.
192      */

193     protected final boolean isIndentDescriptions() {
194         return fIndentDescriptions;
195     }
196
197     /**
198      * Should root tag parameter descriptions be indented?
199      *
200      * @return <code>true</code> iff the root tags should be indented, <code>false</code>
201      * otherwise.
202      */

203     protected final boolean isIndentRoots() {
204         return fIndentRoots;
205     }
206
207     /**
208      * Marks the comment ranges confined by HTML ranges.
209      */

210     protected void markHtmlRanges() {
211         // Do nothing
212
}
213
214     /**
215      * Marks the comment range with its HTML tag attributes.
216      *
217      * @param range
218      * The comment range to mark
219      * @param token
220      * Token associated with the comment range
221      */

222     protected void markHtmlTag(final CommentRange range, final String JavaDoc token) {
223         // Do nothing
224
}
225
226     /**
227      * Marks the comment range with its javadoc tag attributes.
228      *
229      * @param range
230      * The comment range to mark
231      * @param token
232      * Token associated with the comment range
233      */

234     protected void markJavadocTag(final CommentRange range, final String JavaDoc token) {
235         range.markPrefixTag(COMMENT_ROOT_TAGS, COMMENT_TAG_PREFIX, token, COMMENT_ROOT);
236     }
237
238     /**
239      * @inheritDoc
240      */

241     protected void markRegion() {
242
243         int count= 0;
244         boolean paragraph= false;
245
246         String JavaDoc token= null;
247         CommentRange range= null;
248
249         for (final ListIterator JavaDoc iterator= getRanges().listIterator(); iterator.hasNext();) {
250
251             range= (CommentRange)iterator.next();
252             count= range.getLength();
253
254             if (count > 0) {
255
256                 token= getText(range.getOffset(), count).toLowerCase();
257
258                 markJavadocTag(range, token);
259                 if (!paragraph && (range.hasAttribute(COMMENT_ROOT) || range.hasAttribute(COMMENT_PARAMETER))) {
260                     range.setAttribute(COMMENT_PARAGRAPH);
261                     paragraph= true;
262                 }
263                 markHtmlTag(range, token);
264             }
265         }
266         markHtmlRanges();
267     }
268 }
269
Popular Tags