This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

View | Details | Raw Unified | Return to bug 25509
Collapse All | Expand All

(-)java.editor/src/org/netbeans/modules/java/editor/resources/Bundle.properties (+1 lines)
Lines 64-69 Link Here
64
# JavadocTokenId categories
64
# JavadocTokenId categories
65
javadoc-tag=Javadoc Tag
65
javadoc-tag=Javadoc Tag
66
html-tag=Javadoc HTML tag
66
html-tag=Javadoc HTML tag
67
javadoc-first-sentence=Javadoc First Sentence
67
68
68
#"Semantic" highlighting:
69
#"Semantic" highlighting:
69
mod-unused=Unused Element
70
mod-unused=Unused Element
(-)java.editor/src/org/netbeans/modules/java/editor/resources/fontsColors.xml (+4 lines)
Lines 130-136 Link Here
130
    <fontcolor name="html-tag" default="comment">
130
    <fontcolor name="html-tag" default="comment">
131
        <font style="bold" />
131
        <font style="bold" />
132
    </fontcolor>
132
    </fontcolor>
133
    <fontcolor name="javadoc-first-sentence" default="comment">
134
        <font style="bold" />
135
    </fontcolor>
133
136
137
134
<!-- XXX: should java module really define these colorings ??
138
<!-- XXX: should java module really define these colorings ??
135
139
136
    <fontcolor name="html-argument" foreColor="ff007c00" default="identifier"/>
140
    <fontcolor name="html-argument" foreColor="ff007c00" default="identifier"/>
(-)javadoc/nbproject/project.xml (+27 lines)
Lines 112-117 Link Here
112
                    </run-dependency>
112
                    </run-dependency>
113
                </dependency>
113
                </dependency>
114
                <dependency>
114
                <dependency>
115
                    <code-name-base>org.netbeans.modules.editor.lib2</code-name-base>
116
                    <build-prerequisite/>
117
                    <compile-dependency/>
118
                    <run-dependency>
119
                        <release-version>1</release-version>
120
                        <specification-version>1.40</specification-version>
121
                    </run-dependency>
122
                </dependency>
123
                <dependency>
124
                    <code-name-base>org.netbeans.modules.editor.mimelookup</code-name-base>
125
                    <build-prerequisite/>
126
                    <compile-dependency/>
127
                    <run-dependency>
128
                        <release-version>1</release-version>
129
                        <specification-version>1.21</specification-version>
130
                    </run-dependency>
131
                </dependency>
132
                <dependency>
133
                    <code-name-base>org.netbeans.modules.editor.settings</code-name-base>
134
                    <build-prerequisite/>
135
                    <compile-dependency/>
136
                    <run-dependency>
137
                        <release-version>1</release-version>
138
                        <specification-version>1.35</specification-version>
139
                    </run-dependency>
140
                </dependency>
141
                <dependency>
115
                    <code-name-base>org.netbeans.modules.java.hints</code-name-base>
142
                    <code-name-base>org.netbeans.modules.java.hints</code-name-base>
116
                    <build-prerequisite/>
143
                    <build-prerequisite/>
117
                    <compile-dependency/>
144
                    <compile-dependency/>
(-)javadoc/src/org/netbeans/modules/javadoc/highlighting/Factory.java (+69 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
27
 * If you wish your version of this file to be governed by only the CDDL
28
 * or only the GPL Version 2, indicate your decision by adding
29
 * "[Contributor] elects to include this software in this distribution
30
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
31
 * single choice of license, a recipient has the option to distribute
32
 * your version of this file under either the CDDL, the GPL Version 2 or
33
 * to extend the choice of license to its licensees as provided above.
34
 * However, if you add GPL Version 2 code and therefore, elected the GPL
35
 * Version 2 license, then the option applies only if the new code is
36
 * made subject to such option by the copyright holder.
37
 *
38
 * Contributor(s):
39
 *
40
 * Portions Copyrighted 2011 Sun Microsystems, Inc.
41
 */
42
43
package org.netbeans.modules.javadoc.highlighting;
44
45
import org.netbeans.spi.editor.highlighting.HighlightsLayer;
46
import org.netbeans.spi.editor.highlighting.HighlightsLayerFactory;
47
import org.netbeans.spi.editor.highlighting.ZOrder;
48
49
/**
50
 * The highlights layer factory.
51
 * 
52
 * @author Vita Stejskal
53
 */
54
public class Factory implements HighlightsLayerFactory {
55
    
56
    /** Creates a new instance of Factory */
57
    public Factory() {
58
    }
59
60
    public HighlightsLayer[] createLayers(HighlightsLayerFactory.Context context) {
61
        return new HighlightsLayer [] { HighlightsLayer.create(
62
            Highlighting.class.getName(), 
63
            ZOrder.SYNTAX_RACK, //NOI18N
64
            true, 
65
            new Highlighting(context.getDocument())
66
        )};
67
    }
68
    
69
}
(-)javadoc/src/org/netbeans/modules/javadoc/highlighting/Highlighting.java (+330 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
27
 * If you wish your version of this file to be governed by only the CDDL
28
 * or only the GPL Version 2, indicate your decision by adding
29
 * "[Contributor] elects to include this software in this distribution
30
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
31
 * single choice of license, a recipient has the option to distribute
32
 * your version of this file under either the CDDL, the GPL Version 2 or
33
 * to extend the choice of license to its licensees as provided above.
34
 * However, if you add GPL Version 2 code and therefore, elected the GPL
35
 * Version 2 license, then the option applies only if the new code is
36
 * made subject to such option by the copyright holder.
37
 *
38
 * Contributor(s):
39
 *
40
 * Portions Copyrighted 2011 Sun Microsystems, Inc.
41
 */
42
43
package org.netbeans.modules.javadoc.highlighting;
44
45
import java.util.ArrayList;
46
import java.util.ConcurrentModificationException;
47
import java.util.List;
48
import java.util.NoSuchElementException;
49
import java.util.logging.Level;
50
import java.util.logging.Logger;
51
import javax.swing.text.AttributeSet;
52
import javax.swing.text.BadLocationException;
53
import javax.swing.text.Document;
54
import javax.swing.text.Element;
55
import javax.swing.text.StyleConstants;
56
import org.netbeans.api.editor.mimelookup.MimeLookup;
57
import org.netbeans.api.editor.mimelookup.MimePath;
58
import org.netbeans.api.editor.settings.AttributesUtilities;
59
import org.netbeans.api.editor.settings.FontColorSettings;
60
import org.netbeans.api.java.lexer.JavadocTokenId;
61
import org.netbeans.api.lexer.TokenChange;
62
import org.netbeans.api.lexer.TokenHierarchy;
63
import org.netbeans.api.lexer.TokenHierarchyEvent;
64
import org.netbeans.api.lexer.TokenHierarchyListener;
65
import org.netbeans.api.lexer.TokenId;
66
import org.netbeans.api.lexer.TokenSequence;
67
import org.netbeans.spi.editor.highlighting.HighlightsSequence;
68
import org.netbeans.spi.editor.highlighting.support.AbstractHighlightsContainer;
69
import org.openide.util.Lookup;
70
import org.openide.util.WeakListeners;
71
72
/**
73
 * Highlights the first sentence of a javadoc comment.
74
 * 
75
 * @author Vita Stejskal
76
 */
77
public class Highlighting extends AbstractHighlightsContainer implements TokenHierarchyListener {
78
79
    private static final Logger LOG = Logger.getLogger(Highlighting.class.getName());
80
    
81
    public static final String LAYER_ID = "org.netbeans.modules.firstsentence.Highlighting"; //NOI18N
82
    
83
    private Document document;
84
    private TokenHierarchy<? extends Document> hierarchy = null;
85
    private long version = 0;
86
    
87
    /** Creates a new instance of Highlighting */
88
    public Highlighting(Document doc) {
89
        this.document = doc;
90
    }
91
92
    public HighlightsSequence getHighlights(int startOffset, int endOffset) {
93
        synchronized (this) {
94
            if (hierarchy == null) {
95
                hierarchy = TokenHierarchy.get(document);
96
                if (hierarchy != null) {
97
                    hierarchy.addTokenHierarchyListener(WeakListeners.create(TokenHierarchyListener.class, this, hierarchy));
98
                }
99
            }
100
101
            if (hierarchy != null) {
102
                return new HSImpl(version, hierarchy, startOffset, endOffset);
103
            } else {
104
                return HighlightsSequence.EMPTY;
105
            }
106
        }
107
    }
108
109
    // ----------------------------------------------------------------------
110
    //  TokenHierarchyListener implementation
111
    // ----------------------------------------------------------------------
112
113
    public void tokenHierarchyChanged(TokenHierarchyEvent evt) {
114
        TokenChange<?> tc = evt.tokenChange();
115
        int affectedArea [] = null;
116
        
117
        TokenSequence<? extends TokenId> seq = tc.currentTokenSequence();
118
        if (seq.language().equals(JavadocTokenId.language())) {
119
            // Change inside javadoc
120
            int [] firstSentence = findFirstSentence(seq);
121
            if (firstSentence != null) {
122
                if (tc.offset() <= firstSentence[1]) {
123
                    // Change before the end of the first sentence
124
                    affectedArea = firstSentence;
125
                }
126
            } else {
127
                // XXX: need the embedding token (i.e. JavaTokenId.JAVADOC_COMMENT*)
128
                // and fire a change in its whole area
129
                affectedArea = new int [] { tc.offset(), Integer.MAX_VALUE };
130
            }
131
        } else {
132
            // The change may or may not involve javadoc, so reset everyting.
133
            // It would be more efficient to traverse the changed area and
134
            // find out whether it really involves javadoc or not.
135
            affectedArea = new int [] { tc.offset(), Integer.MAX_VALUE };
136
        }
137
        
138
        if (affectedArea != null) {
139
            synchronized (this) {
140
                version++;
141
            }
142
143
            fireHighlightsChange(affectedArea[0], affectedArea[1]);
144
        }
145
    }
146
147
    // ----------------------------------------------------------------------
148
    //  Private implementation
149
    // ----------------------------------------------------------------------
150
151
    private int [] findFirstSentence(TokenSequence<? extends TokenId> seq) {
152
        seq.moveStart();
153
        if (seq.moveNext()) {
154
            int start = seq.offset();
155
            do {
156
                if (seq.token().id() == JavadocTokenId.DOT) {
157
                    return new int [] { start, seq.offset() };
158
                }
159
            } while (seq.moveNext());
160
        }
161
        
162
        return null;
163
    }
164
165
    private final class HSImpl implements HighlightsSequence {
166
        
167
        private long version;
168
        private TokenHierarchy<? extends Document> scanner;
169
        private List<TokenSequence<? extends TokenId>> sequences;
170
        private int startOffset;
171
        private int endOffset;
172
        
173
        private List<Integer> lines = null;
174
        private int linesIdx = -1;
175
        
176
        public HSImpl(long version, TokenHierarchy<? extends Document> scanner, int startOffset, int endOffset) {
177
            this.version = version;
178
            this.scanner = scanner;
179
            this.startOffset = startOffset;
180
            this.endOffset = endOffset;
181
            this.sequences = null;
182
        }
183
184
        public boolean moveNext() {
185
            synchronized (Highlighting.this) {
186
                checkVersion();
187
                
188
                if (sequences == null) {
189
                    // initialize
190
                    TokenSequence<?> seq = scanner.tokenSequence().subSequence(startOffset, endOffset);
191
                    sequences = new ArrayList<TokenSequence<? extends TokenId>>();
192
                    sequences.add(seq);
193
                }
194
195
                if (lines != null) {
196
                    if (linesIdx + 2 < lines.size()) {
197
                        linesIdx += 2;
198
                        return true;
199
                    }
200
                    
201
                    lines = null;
202
                    linesIdx = -1;
203
                }
204
                
205
                while (!sequences.isEmpty()) {
206
                    TokenSequence<? extends TokenId> seq = sequences.get(sequences.size() - 1);
207
208
                    if (seq.language().equals(JavadocTokenId.language())) {
209
                        int [] firstSentence = findFirstSentence(seq);
210
                        sequences.remove(sequences.size() - 1);
211
212
                        if (firstSentence != null) {
213
                            lines = splitByLines(firstSentence[0], firstSentence[1]);
214
                            if (lines != null) {
215
                                linesIdx = 0;
216
                                return true;
217
                            }
218
                        }
219
                    } else {
220
                        boolean hasNextToken;
221
222
                        while (true == (hasNextToken = seq.moveNext())) {
223
                            TokenSequence<?> embeddedSeq = seq.embedded();
224
                            if (embeddedSeq != null) {
225
                                sequences.add(sequences.size(), embeddedSeq);
226
                                break;
227
                            }
228
                        }
229
230
                        if (!hasNextToken) {
231
                            sequences.remove(sequences.size() - 1);
232
                        }
233
                    }
234
                }
235
236
                return false;
237
            }
238
        }
239
240
        public int getStartOffset() {
241
            synchronized (Highlighting.this) {
242
                checkVersion();
243
                
244
                if (sequences == null) {
245
                    throw new NoSuchElementException("Call moveNext() first."); //NOI18N
246
                }
247
248
                if (lines != null) {
249
                    return lines.get(linesIdx);
250
                } else {
251
                    throw new NoSuchElementException();
252
                }
253
            }
254
        }
255
256
        public int getEndOffset() {
257
            synchronized (Highlighting.this) {
258
                checkVersion();
259
                
260
                if (sequences == null) {
261
                    throw new NoSuchElementException("Call moveNext() first."); //NOI18N
262
                }
263
264
                if (lines != null) {
265
                    return lines.get(linesIdx + 1);
266
                } else {
267
                    throw new NoSuchElementException();
268
                }
269
            }
270
        }
271
272
        public AttributeSet getAttributes() {
273
            synchronized (Highlighting.this) {
274
                checkVersion();
275
                
276
                if (sequences == null) {
277
                    throw new NoSuchElementException("Call moveNext() first."); //NOI18N
278
                }
279
280
                if (lines != null) {
281
                    return MimeLookup.getLookup(MimePath.get("text/x-java")).lookup(FontColorSettings.class).getTokenFontColors("javadoc-first-sentence");
282
                } else {
283
                    throw new NoSuchElementException();
284
                }
285
            }
286
        }
287
        
288
        private void checkVersion() {
289
            if (this.version != Highlighting.this.version) {
290
                throw new ConcurrentModificationException();
291
            }
292
        }
293
        
294
        private List<Integer> splitByLines(int sentenceStart, int sentenceEnd) {
295
            ArrayList<Integer> lines = new ArrayList<Integer>();
296
            int offset = sentenceStart;
297
            
298
            try {
299
                while (offset < sentenceEnd) {
300
                    Element lineElement = document.getDefaultRootElement().getElement(
301
                        document.getDefaultRootElement().getElementIndex(offset));
302
303
                    int rowStart = offset == sentenceStart ? offset : lineElement.getStartOffset();
304
                    int rowEnd = lineElement.getEndOffset();
305
306
                    String line = document.getText(rowStart, rowEnd - rowStart);
307
                    int idx = 0;
308
                    while (idx < line.length() && 
309
                        (line.charAt(idx) == ' ' || 
310
                        line.charAt(idx) == '\t' || 
311
                        line.charAt(idx) == '*'))
312
                    {
313
                        idx++;
314
                    }
315
316
                    if (rowStart + idx < rowEnd) {
317
                        lines.add(rowStart + idx);
318
                        lines.add(Math.min(rowEnd, sentenceEnd));
319
                    }
320
321
                    offset = rowEnd + 1;
322
                }
323
            } catch (BadLocationException e) {
324
                LOG.log(Level.WARNING, "Can't determine javadoc first sentence", e);
325
            }
326
            
327
            return lines.isEmpty() ? null : lines;
328
        }
329
    } // End of HSImpl class
330
}
(-)javadoc/src/org/netbeans/modules/javadoc/resources/mf-layer.xml (+3 lines)
Lines 119-123 Link Here
119
            </folder>
119
            </folder>
120
        </folder>
120
        </folder>
121
    </folder>
121
    </folder>
122
    <folder name="Editors">
123
        <file name="org-netbeans-modules-javadoc-highlighting-Factory.instance" />
124
    </folder>
122
    
125
    
123
</filesystem>
126
</filesystem>

Return to bug 25509