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 268342
Collapse All | Expand All

(-)a/collab.channel.chat.xml/manifest.mf (-1 / +1 lines)
Lines 1-6 Link Here
1
Manifest-Version: 1.0
1
Manifest-Version: 1.0
2
OpenIDE-Module: org.netbeans.modules.collab.channel.chat.xml/1
2
OpenIDE-Module: org.netbeans.modules.collab.channel.chat.xml/1
3
OpenIDE-Module-Specification-Version: 1.3
3
OpenIDE-Module-Specification-Version: 1.4
4
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/collab/channel/chat/xml/Bundle.properties
4
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/collab/channel/chat/xml/Bundle.properties
5
OpenIDE-Module-Layer: org/netbeans/modules/collab/channel/chat/xml/layer.xml
5
OpenIDE-Module-Layer: org/netbeans/modules/collab/channel/chat/xml/layer.xml
6
AutoUpdate-Show-In-Client: false
6
AutoUpdate-Show-In-Client: false
(-)a/collab.channel.chat.xml/nbproject/project.xml (-1 / +1 lines)
Lines 63-69 Link Here
63
                    <code-name-base>org.netbeans.modules.xml.text</code-name-base>
63
                    <code-name-base>org.netbeans.modules.xml.text</code-name-base>
64
                    <run-dependency>
64
                    <run-dependency>
65
                        <release-version>2</release-version>
65
                        <release-version>2</release-version>
66
                    <specification-version>1.16</specification-version>
66
                    <specification-version>1.60</specification-version>
67
                    </run-dependency>
67
                    </run-dependency>
68
                </dependency>
68
                </dependency>
69
            </module-dependencies>
69
            </module-dependencies>
(-)a/editor.completion/src/org/netbeans/modules/editor/completion/CompletionImpl.java (-1 / +4 lines)
Lines 638-644 Link Here
638
            public void run() {
638
            public void run() {
639
                List<TokenSequence<?>> seqs = TokenHierarchy.get(doc).embeddedTokenSequences(offset, true);
639
                List<TokenSequence<?>> seqs = TokenHierarchy.get(doc).embeddedTokenSequences(offset, true);
640
                TokenSequence<?> seq;
640
                TokenSequence<?> seq;
641
                
641
                if (seqs.size() == 1) {
642
                    // get the mime path from the document/kit
643
                    return;
644
                }
642
                if (seqs.isEmpty()) {
645
                if (seqs.isEmpty()) {
643
                    seq  = TokenHierarchy.get(doc).tokenSequence();
646
                    seq  = TokenHierarchy.get(doc).tokenSequence();
644
                } else {
647
                } else {
(-)a/editor.kit/manifest.mf (-1 / +1 lines)
Lines 2-6 Link Here
2
AutoUpdate-Show-In-Client: false
2
AutoUpdate-Show-In-Client: false
3
OpenIDE-Module: org.netbeans.modules.editor.kit
3
OpenIDE-Module: org.netbeans.modules.editor.kit
4
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/editor/kit/Bundle.properties
4
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/editor/kit/Bundle.properties
5
OpenIDE-Module-Specification-Version: 1.33
5
OpenIDE-Module-Specification-Version: 1.34
6
6
(-)a/editor.kit/nbproject/project.xml (-1 / +1 lines)
Lines 155-161 Link Here
155
                    <code-name-base>org.netbeans.modules.xml.text</code-name-base>
155
                    <code-name-base>org.netbeans.modules.xml.text</code-name-base>
156
                    <run-dependency>
156
                    <run-dependency>
157
                        <release-version>2</release-version>
157
                        <release-version>2</release-version>
158
                        <specification-version>1.16</specification-version>
158
                        <specification-version>1.60</specification-version>
159
                    </run-dependency>
159
                    </run-dependency>
160
                </dependency>
160
                </dependency>
161
                <dependency>
161
                <dependency>
(-)a/editor.structure/nbproject/project.xml (+1 lines)
Lines 176-181 Link Here
176
            <friend-packages>
176
            <friend-packages>
177
                <friend>org.netbeans.modules.mobility.svgcore</friend>
177
                <friend>org.netbeans.modules.mobility.svgcore</friend>
178
                <friend>org.netbeans.modules.xml.text</friend>
178
                <friend>org.netbeans.modules.xml.text</friend>
179
                <friend>org.netbeans.modules.xml.text.obsolete90</friend>
179
                <package>org.netbeans.modules.editor.structure.api</package>
180
                <package>org.netbeans.modules.editor.structure.api</package>
180
                <package>org.netbeans.modules.editor.structure.formatting</package>
181
                <package>org.netbeans.modules.editor.structure.formatting</package>
181
                <package>org.netbeans.modules.editor.structure.spi</package>
182
                <package>org.netbeans.modules.editor.structure.spi</package>
(-)a/hibernate/nbproject/project.properties (-2 / +2 lines)
Lines 40-50 Link Here
40
40
41
build.compiler.deprecation=false
41
build.compiler.deprecation=false
42
javac.compilerargs=-Xlint -Xlint:-serial
42
javac.compilerargs=-Xlint -Xlint:-serial
43
javac.source=1.7
43
javac.source=1.8
44
44
45
hibernate.test.dir=${nb_all}/contrib/hibernate/test
45
hibernate.test.dir=${nb_all}/contrib/hibernate/test
46
46
47
spec.version.base=1.34.0
47
spec.version.base=1.35.0
48
48
49
test.unit.cp.extra=\
49
test.unit.cp.extra=\
50
    ${nb_all}/libs.junit4/external/junit-4.12.jar:\
50
    ${nb_all}/libs.junit4/external/junit-4.12.jar:\
(-)a/hibernate/nbproject/project.xml (-18 / +35 lines)
Lines 162-167 Link Here
162
                    </run-dependency>
162
                    </run-dependency>
163
                </dependency>
163
                </dependency>
164
                <dependency>
164
                <dependency>
165
                    <code-name-base>org.netbeans.modules.editor.document</code-name-base>
166
                    <build-prerequisite/>
167
                    <compile-dependency/>
168
                    <run-dependency>
169
                        <specification-version>1.0</specification-version>
170
                    </run-dependency>
171
                </dependency>
172
                <dependency>
165
                    <code-name-base>org.netbeans.modules.editor.lib</code-name-base>
173
                    <code-name-base>org.netbeans.modules.editor.lib</code-name-base>
166
                    <build-prerequisite/>
174
                    <build-prerequisite/>
167
                    <compile-dependency/>
175
                    <compile-dependency/>
Lines 180-193 Link Here
180
                    </run-dependency>
188
                    </run-dependency>
181
                </dependency>
189
                </dependency>
182
                <dependency>
190
                <dependency>
183
                    <code-name-base>org.netbeans.modules.editor.document</code-name-base>
184
                    <build-prerequisite/>
185
                    <compile-dependency/>
186
                    <run-dependency>
187
                        <specification-version>1.0</specification-version>
188
                    </run-dependency>
189
                </dependency>
190
                <dependency>
191
                    <code-name-base>org.netbeans.modules.hibernate4lib</code-name-base>
191
                    <code-name-base>org.netbeans.modules.hibernate4lib</code-name-base>
192
                    <build-prerequisite/>
192
                    <build-prerequisite/>
193
                    <compile-dependency/>
193
                    <compile-dependency/>
Lines 250-256 Link Here
250
                        <release-version>1</release-version>
250
                        <release-version>1</release-version>
251
                        <specification-version>1.62</specification-version>
251
                        <specification-version>1.62</specification-version>
252
                    </run-dependency>
252
                    </run-dependency>
253
                </dependency>                
253
                </dependency>
254
                <dependency>
254
                <dependency>
255
                    <code-name-base>org.netbeans.modules.java.source.base</code-name-base>
255
                    <code-name-base>org.netbeans.modules.java.source.base</code-name-base>
256
                    <build-prerequisite/>
256
                    <build-prerequisite/>
Lines 269-274 Link Here
269
                    </run-dependency>
269
                    </run-dependency>
270
                </dependency>
270
                </dependency>
271
                <dependency>
271
                <dependency>
272
                    <code-name-base>org.netbeans.modules.lexer</code-name-base>
273
                    <build-prerequisite/>
274
                    <compile-dependency/>
275
                    <run-dependency>
276
                        <release-version>2</release-version>
277
                        <specification-version>1.64</specification-version>
278
                    </run-dependency>
279
                </dependency>
280
                <dependency>
272
                    <code-name-base>org.netbeans.modules.parsing.api</code-name-base>
281
                    <code-name-base>org.netbeans.modules.parsing.api</code-name-base>
273
                    <build-prerequisite/>
282
                    <build-prerequisite/>
274
                    <compile-dependency/>
283
                    <compile-dependency/>
Lines 366-371 Link Here
366
                    </run-dependency>
375
                    </run-dependency>
367
                </dependency>
376
                </dependency>
368
                <dependency>
377
                <dependency>
378
                    <code-name-base>org.netbeans.modules.xml.lexer</code-name-base>
379
                    <build-prerequisite/>
380
                    <compile-dependency/>
381
                    <run-dependency>
382
                        <specification-version>1.30</specification-version>
383
                    </run-dependency>
384
                </dependency>
385
                <dependency>
369
                    <code-name-base>org.netbeans.modules.xml.multiview</code-name-base>
386
                    <code-name-base>org.netbeans.modules.xml.multiview</code-name-base>
370
                    <build-prerequisite/>
387
                    <build-prerequisite/>
371
                    <compile-dependency/>
388
                    <compile-dependency/>
Lines 380-386 Link Here
380
                    <compile-dependency/>
397
                    <compile-dependency/>
381
                    <run-dependency>
398
                    <run-dependency>
382
                        <release-version>2</release-version>
399
                        <release-version>2</release-version>
383
                        <specification-version>1.16</specification-version>
400
                        <specification-version>1.60</specification-version>
384
                    </run-dependency>
401
                    </run-dependency>
385
                </dependency>
402
                </dependency>
386
                <dependency>
403
                <dependency>
Lines 448-461 Link Here
448
                    </run-dependency>
465
                    </run-dependency>
449
                </dependency>
466
                </dependency>
450
                <dependency>
467
                <dependency>
451
                    <code-name-base>org.openide.util.ui</code-name-base>
452
                    <build-prerequisite/>
453
                    <compile-dependency/>
454
                    <run-dependency>
455
                        <specification-version>9.3</specification-version>
456
                    </run-dependency>
457
                </dependency>
458
                <dependency>
459
                    <code-name-base>org.openide.util</code-name-base>
468
                    <code-name-base>org.openide.util</code-name-base>
460
                    <build-prerequisite/>
469
                    <build-prerequisite/>
461
                    <compile-dependency/>
470
                    <compile-dependency/>
Lines 472-477 Link Here
472
                    </run-dependency>
481
                    </run-dependency>
473
                </dependency>
482
                </dependency>
474
                <dependency>
483
                <dependency>
484
                    <code-name-base>org.openide.util.ui</code-name-base>
485
                    <build-prerequisite/>
486
                    <compile-dependency/>
487
                    <run-dependency>
488
                        <specification-version>9.3</specification-version>
489
                    </run-dependency>
490
                </dependency>
491
                <dependency>
475
                    <code-name-base>org.openide.windows</code-name-base>
492
                    <code-name-base>org.openide.windows</code-name-base>
476
                    <build-prerequisite/>
493
                    <build-prerequisite/>
477
                    <compile-dependency/>
494
                    <compile-dependency/>
(-)a/hibernate/src/org/netbeans/modules/hibernate/completion/CompletionContext.java (-68 / +93 lines)
Lines 47-65 Link Here
47
import org.netbeans.modules.hibernate.editor.EditorContextFactory;
47
import org.netbeans.modules.hibernate.editor.EditorContextFactory;
48
import org.netbeans.modules.hibernate.editor.DocumentContext;
48
import org.netbeans.modules.hibernate.editor.DocumentContext;
49
import java.util.ArrayList;
49
import java.util.ArrayList;
50
import java.util.Collections;
50
import java.util.List;
51
import java.util.List;
51
import java.util.logging.Level;
52
import java.util.logging.Level;
52
import java.util.logging.Logger;
53
import java.util.logging.Logger;
54
import javax.swing.text.BadLocationException;
53
import javax.swing.text.Document;
55
import javax.swing.text.Document;
54
import org.netbeans.editor.BaseDocument;
56
import org.netbeans.api.lexer.Token;
55
import org.netbeans.editor.TokenItem;
57
import org.netbeans.api.lexer.TokenSequence;
56
import org.netbeans.modules.xml.text.api.XMLDefaultTokenContext;
58
import org.netbeans.api.xml.lexer.XMLTokenId;
57
import org.netbeans.modules.xml.text.syntax.SyntaxElement;
59
import org.netbeans.modules.xml.text.api.dom.SyntaxElement;
58
import org.netbeans.modules.xml.text.syntax.XMLSyntaxSupport;
60
import org.netbeans.modules.xml.text.api.dom.XMLSyntaxSupport;
59
import org.netbeans.modules.xml.text.syntax.dom.EmptyTag;
61
import org.openide.util.Exceptions;
60
import org.netbeans.modules.xml.text.syntax.dom.EndTag;
61
import org.netbeans.modules.xml.text.syntax.dom.StartTag;
62
import org.netbeans.modules.xml.text.syntax.dom.Tag;
63
import org.w3c.dom.Node;
62
import org.w3c.dom.Node;
64
import org.w3c.dom.Text;
63
import org.w3c.dom.Text;
65
64
Lines 69-75 Link Here
69
 * @author Rohan Ranade (Rohan.Ranade@Sun.COM)
68
 * @author Rohan Ranade (Rohan.Ranade@Sun.COM)
70
 */
69
 */
71
public class CompletionContext {
70
public class CompletionContext {
72
    private ArrayList<String> existingAttributes;
71
    private List<String> existingAttributes = Collections.emptyList();
73
72
74
    public static enum CompletionType {
73
    public static enum CompletionType {
75
        TAG,
74
        TAG,
Lines 93-141 Link Here
93
        this.caretOffset = caretOffset;
92
        this.caretOffset = caretOffset;
94
93
95
        try {
94
        try {
96
            this.support = (XMLSyntaxSupport) ((BaseDocument)doc).getSyntaxSupport();
95
            this.support = XMLSyntaxSupport.getSyntaxSupport(doc);
97
        } catch (ClassCastException cce) {
96
        } catch (ClassCastException cce) {
98
            LOGGER.log(Level.FINE, cce.getMessage());
97
            LOGGER.log(Level.FINE, cce.getMessage());
99
            this.support = new XMLSyntaxSupport(((BaseDocument)doc));
98
            this.support = XMLSyntaxSupport.createSyntaxSupport(doc);
100
        }
99
        }
101
        this.documentContext = EditorContextFactory.getDocumentContext(doc, caretOffset);
100
        this.documentContext = EditorContextFactory.getDocumentContext(doc, caretOffset);
102
        this.lastTypedChar = support.lastTypedChar();
101
        this.lastTypedChar = support.lastTypedChar();
103
        initContext();
102
        try {
103
            initContext();
104
        } catch (BadLocationException ex) {
105
            // ignore
106
        }
104
    }
107
    }
105
    
108
    
106
    private void initContext() {
109
    private void initContext() throws BadLocationException {
107
        TokenItem token = documentContext.getCurrentToken();
110
        Token<XMLTokenId> token = documentContext.getCurrentToken();
108
        if(token == null)
111
        if(token == null)
109
            return;
112
            return;
110
        
113
        
111
        boolean tokenBoundary = (token.getOffset() == caretOffset) 
114
        boolean tokenBoundary = (documentContext.getCurrentTokenOffset() == caretOffset) 
112
                || ((token.getOffset() + token.getImage().length()) == caretOffset);
115
                || ((documentContext.getCurrentTokenOffset() + token.length()) == caretOffset);
113
        
116
        
114
        int id = token.getTokenID().getNumericID();
117
        XMLTokenId id = token.id();
115
        SyntaxElement element = documentContext.getCurrentElement();
118
        SyntaxElement element = documentContext.getCurrentElement();
119
        String chars = token.text().toString().trim();
120
        int tOffset = documentContext.getCurrentTokenOffset();
116
        switch (id) {
121
        switch (id) {
117
            //user enters < character
122
            //user enters < character
118
            case XMLDefaultTokenContext.TEXT_ID:
123
            case TEXT:
119
                String chars = token.getImage().trim();
124
                Token<XMLTokenId> previousTokenItem = support.getPreviousToken(tOffset);
125
                if (previousTokenItem == null) {
126
                    completionType = CompletionType.NONE;
127
                    break;
128
                }
129
                String text = previousTokenItem.text().toString().trim();
120
                if (chars != null && chars.equals("") &&
130
                if (chars != null && chars.equals("") &&
121
                        token.getPrevious().getImage().trim().equals("/>")) { // NOI18N
131
                        text.equals("/>")) { // NOI18N
122
                    completionType = CompletionType.NONE;
132
                    completionType = CompletionType.NONE;
123
                    break;
133
                    break;
124
                }
134
                }
125
                if (chars != null && chars.equals("") &&
135
                if (chars != null && chars.equals("") &&
126
                        token.getPrevious().getImage().trim().equals(">")) { // NOI18N
136
                        text.equals(">")) { // NOI18N
127
                    completionType = CompletionType.VALUE;
137
                    completionType = CompletionType.VALUE;
128
                    break;
138
                    break;
129
                }
139
                }
130
                if (chars != null && !chars.startsWith("<") &&
140
                if (chars != null && !chars.startsWith("<") &&
131
                        token.getPrevious().getImage().trim().equals(">")) { // NOI18N
141
                        text.equals(">")) { // NOI18N
132
142
133
                    completionType = CompletionType.VALUE;
143
                    completionType = CompletionType.VALUE;
134
                    typedChars = "";
144
                    typedChars = "";
135
                    break;
145
                    break;
136
                }
146
                }
137
                if (chars != null && !chars.equals("<") &&
147
                if (chars != null && !chars.equals("<") &&
138
                        token.getPrevious().getImage().trim().equals(">")) { // NOI18N
148
                        text.equals(">")) { // NOI18N
139
                    completionType = CompletionType.NONE;
149
                    completionType = CompletionType.NONE;
140
                    break;
150
                    break;
141
                }
151
                }
Lines 146-199 Link Here
146
                break;
156
                break;
147
157
148
            //start tag of an element
158
            //start tag of an element
149
            case XMLDefaultTokenContext.TAG_ID:
159
            case TAG:
150
                if (element instanceof EndTag) {
160
                String tagName = element.getNode().getNodeName();
161
                if (support.isEndTag(element)) {
151
                    completionType = CompletionType.NONE;
162
                    completionType = CompletionType.NONE;
152
                    break;
163
                    break;
153
                }
164
                }
154
                if (element instanceof EmptyTag) {
165
                if (support.isEmptyTag(element)) {
155
                    if (token != null &&
166
                    if (token != null &&
156
                            token.getImage().trim().equals("/>")) {
167
                            chars.equals("/>")) {
157
                        completionType = CompletionType.NONE;
168
                        completionType = CompletionType.NONE;
158
                        break;
169
                        break;
159
                    }
170
                    }
160
                    EmptyTag tag = (EmptyTag) element;
161
                    if (element.getElementOffset() + 1 == this.caretOffset) {
171
                    if (element.getElementOffset() + 1 == this.caretOffset) {
162
                        completionType = CompletionType.TAG;
172
                        completionType = CompletionType.TAG;
163
                        break;
173
                        break;
164
                    }
174
                    }
165
                    if (caretOffset > element.getElementOffset() + 1 &&
175
                    if (caretOffset > element.getElementOffset() + 1 &&
166
                            caretOffset <= element.getElementOffset() + 1 + tag.getTagName().length()) {
176
                            caretOffset <= element.getElementOffset() + 1 +tagName.length()) {
167
                        completionType = CompletionType.TAG;
177
                        completionType = CompletionType.TAG;
168
                        typedChars = tag.getTagName();
178
                        typedChars = tagName;
169
                        break;
179
                        break;
170
                    }
180
                    }
171
                    completionType = CompletionType.ATTRIBUTE;
181
                    completionType = CompletionType.ATTRIBUTE;
172
                    break;
182
                    break;
173
                }
183
                }
174
184
175
                if (element instanceof StartTag) {
185
                if (support.isStartTag(element)) {
176
                    if (token != null &&
186
                    if (token != null &&
177
                            token.getImage().trim().equals(">")) {
187
                            chars.equals(">")) {
178
                        completionType = CompletionType.NONE;
188
                        completionType = CompletionType.NONE;
179
                        break;
189
                        break;
180
                    }
190
                    }
181
                    if (token != null &&
191
                    if (token != null &&
182
                            token.getImage().trim().startsWith("</")) {
192
                            chars.startsWith("</")) {
183
                        typedChars = "";
193
                        typedChars = "";
184
                        completionType = CompletionType.VALUE;
194
                        completionType = CompletionType.VALUE;
185
                        break;
195
                        break;
186
                    }
196
                    }
187
                    if (element.getElementOffset() + 1 != this.caretOffset) {
197
                    if (element.getElementOffset() + 1 != this.caretOffset) {
188
                        StartTag tag = (StartTag) element;
198
                        typedChars = tagName;
189
                        typedChars = tag.getTagName();
190
                    }
199
                    }
191
                }
200
                }
192
                
201
                
193
                if (element instanceof Text) {
202
                if (element instanceof Text) {
194
                    if (token != null &&
203
                    if (token != null &&
195
                            token.getImage().trim().startsWith("</")) {
204
                            chars.startsWith("</")) {
196
                        typedChars = token.getPrevious().getImage().trim();
205
                        Token<XMLTokenId> previous = support.getPreviousToken(tOffset);
206
                        typedChars = previous.text().toString().trim();
197
                        completionType = CompletionType.VALUE;
207
                        completionType = CompletionType.VALUE;
198
                        break;
208
                        break;
199
                    }
209
                    }
Lines 207-247 Link Here
207
                break;
217
                break;
208
218
209
            //user enters an attribute name
219
            //user enters an attribute name
210
            case XMLDefaultTokenContext.ARGUMENT_ID:
220
            case ARGUMENT:
211
                completionType = CompletionType.ATTRIBUTE;
221
                completionType = CompletionType.ATTRIBUTE;
212
                typedChars = token.getImage().substring(0, caretOffset - token.getOffset());;
222
                typedChars = chars.substring(0, caretOffset - tOffset);
213
                break;
223
                break;
214
224
215
            //some random character
225
            //some random character
216
            case XMLDefaultTokenContext.CHARACTER_ID:
226
            case CHARACTER:
217
            //user enters = character, we should ignore all other operators
227
            //user enters = character, we should ignore all other operators
218
            case XMLDefaultTokenContext.OPERATOR_ID:
228
            case OPERATOR:
219
                completionType = CompletionType.NONE;
229
                completionType = CompletionType.NONE;
220
                break;
230
                break;
221
            //user enters either ' or "
231
            //user enters either ' or "
222
            case XMLDefaultTokenContext.VALUE_ID:
232
            case VALUE:
223
                if(!tokenBoundary) {
233
                if(!tokenBoundary) {
224
                    completionType = CompletionType.ATTRIBUTE_VALUE;
234
                    completionType = CompletionType.ATTRIBUTE_VALUE;
225
                    typedChars = token.getImage().substring(1, caretOffset - token.getOffset());
235
                    typedChars = chars.substring(1, caretOffset - tOffset);
226
                } else {
236
                } else {
227
                    completionType = CompletionType.NONE;
237
                    completionType = CompletionType.NONE;
228
                }
238
                }
229
                break;
239
                break;
230
240
231
            //user enters white-space character
241
            //user enters white-space character
232
            case XMLDefaultTokenContext.WS_ID:
242
            case WS:
233
                completionType = CompletionType.NONE;
243
                completionType = CompletionType.NONE;
234
                TokenItem prev = token.getPrevious();
244
                Token<XMLTokenId> prev = support.skip(tOffset, false, XMLTokenId.WS);
235
                while (prev != null &&
245
                if (prev == null) {
236
                        (prev.getTokenID().getNumericID() == XMLDefaultTokenContext.WS_ID)) {
246
                    completionType = CompletionType.NONE;
237
                    prev = prev.getPrevious();
247
                    break;
238
                }
248
                }
239
                
249
                if(prev.id() == XMLTokenId.ARGUMENT) {
240
                if(prev.getTokenID().getNumericID() == XMLDefaultTokenContext.ARGUMENT_ID) {
250
                    typedChars = prev.text().toString();
241
                    typedChars = prev.getImage();
242
                    completionType = CompletionType.ATTRIBUTE;
251
                    completionType = CompletionType.ATTRIBUTE;
243
                } else if ((prev.getTokenID().getNumericID() == XMLDefaultTokenContext.VALUE_ID) ||
252
                } else if ((prev.id() == XMLTokenId.VALUE) ||
244
                        (prev.getTokenID().getNumericID() == XMLDefaultTokenContext.TAG_ID)) {
253
                        (prev.id() == XMLTokenId.TAG)) {
245
                    completionType = CompletionType.ATTRIBUTE;
254
                    completionType = CompletionType.ATTRIBUTE;
246
                }
255
                }
247
                break;
256
                break;
Lines 274-301 Link Here
274
    
283
    
275
    public Node getTag() {
284
    public Node getTag() {
276
        SyntaxElement element = documentContext.getCurrentElement();
285
        SyntaxElement element = documentContext.getCurrentElement();
277
        return (element instanceof Tag) ? (Node) element : null;
286
        return element.getType() == Node.ELEMENT_NODE ? element.getNode() : null;
278
    }
287
    }
279
    
288
    
280
    public TokenItem getCurrentToken() {
289
    public Token<XMLTokenId> getCurrentToken() {
281
        return documentContext.getCurrentToken();
290
        return documentContext.getCurrentToken();
282
    }
291
    }
283
    
292
    
284
    public List<String> getExistingAttributes() {
293
    public int getCurrentTokenOffset() {
285
        if(existingAttributes != null)
294
        return documentContext.getCurrentTokenOffset();
286
            return existingAttributes;
295
    }
287
        existingAttributes = new ArrayList<String>();
296
    
288
        TokenItem item = documentContext.getCurrentToken().getPrevious();
297
    private List<String> getExistingAttributesLocked(TokenSequence ts) {
289
        while(item != null) {
298
        List<String> existingAttributes = new ArrayList<String>();
290
            if(item.getTokenID().getNumericID() ==
299
        while (ts.movePrevious()) {
291
                    XMLDefaultTokenContext.TAG_ID)
300
            Token<XMLTokenId> item = ts.token();
301
            XMLTokenId tokenId = item.id();
302
            if (tokenId == XMLTokenId.TAG) {
292
                break;
303
                break;
293
            if(item.getTokenID().getNumericID() ==
294
                    XMLDefaultTokenContext.ARGUMENT_ID) {
295
                existingAttributes.add(item.getImage());
296
            }
304
            }
297
            item = item.getPrevious();
305
            if (tokenId == XMLTokenId.ARGUMENT) {
306
                existingAttributes.add(item.text().toString());
307
            }
298
        }
308
        }
299
        return existingAttributes;
309
        return existingAttributes;
300
    }
310
    }
311
312
    public List<String> getExistingAttributes() {
313
        if (existingAttributes == null) {
314
            try {
315
                existingAttributes = (List<String>)support.runWithSequence(
316
                        documentContext.getCurrentTokenOffset(),
317
                        this::getExistingAttributesLocked
318
                );
319
            } catch (BadLocationException ex) {
320
                Exceptions.printStackTrace(ex);
321
            }
322
        }
323
        return existingAttributes;
324
    }
325
301
}
326
}
(-)a/hibernate/src/org/netbeans/modules/hibernate/completion/Completor.java (-9 / +9 lines)
Lines 118-124 Link Here
118
                }
118
                }
119
            }
119
            }
120
120
121
            setAnchorOffset(context.getCurrentToken().getOffset() + 1);
121
            setAnchorOffset(context.getCurrentTokenOffset() + 1);
122
            return results;
122
            return results;
123
        }
123
        }
124
    }
124
    }
Lines 156-162 Link Here
156
                }
156
                }
157
            }
157
            }
158
158
159
            setAnchorOffset(context.getCurrentToken().getOffset() + 1);
159
            setAnchorOffset(context.getCurrentTokenOffset() + 1);
160
            return results;
160
            return results;
161
        }
161
        }
162
    }
162
    }
Lines 184-192 Link Here
184
                }
184
                }
185
185
186
                if (typedChars.contains(".") || typedChars.equals("")) { // Switch to normal completion
186
                if (typedChars.contains(".") || typedChars.equals("")) { // Switch to normal completion
187
                    doNormalJavaCompletion(js, results, typedChars, context.getCurrentToken().getOffset() + 1);
187
                    doNormalJavaCompletion(js, results, typedChars, context.getCurrentTokenOffset() + 1);
188
                } else { // Switch to smart class path completion
188
                } else { // Switch to smart class path completion
189
                    doSmartJavaCompletion(js, results, typedChars, context.getCurrentToken().getOffset() + 1);
189
                    doSmartJavaCompletion(js, results, typedChars, context.getCurrentTokenOffset() + 1);
190
                }
190
                }
191
            } catch (IOException ex) {
191
            } catch (IOException ex) {
192
                Exceptions.printStackTrace(ex);
192
                Exceptions.printStackTrace(ex);
Lines 325-331 Link Here
325
                Exceptions.printStackTrace(ex);
325
                Exceptions.printStackTrace(ex);
326
            }
326
            }
327
327
328
            setAnchorOffset(context.getCurrentToken().getOffset() + 1);
328
            setAnchorOffset(context.getCurrentTokenOffset() + 1);
329
329
330
            return results;
330
            return results;
331
        }
331
        }
Lines 355-361 Link Here
355
                }
355
                }
356
            }
356
            }
357
357
358
            setAnchorOffset(context.getCurrentToken().getOffset() + 1);
358
            setAnchorOffset(context.getCurrentTokenOffset() + 1);
359
359
360
            return results;
360
            return results;
361
        }
361
        }
Lines 402-408 Link Here
402
                    results.add(item);
402
                    results.add(item);
403
                }
403
                }
404
            }
404
            }
405
            setAnchorOffset(context.getCurrentToken().getOffset() + 1);
405
            setAnchorOffset(context.getCurrentTokenOffset() + 1);
406
406
407
            return results;
407
            return results;
408
        }
408
        }
Lines 446-452 Link Here
446
                }
446
                }
447
            }
447
            }
448
448
449
            setAnchorOffset(context.getCurrentToken().getOffset() + 1);
449
            setAnchorOffset(context.getCurrentTokenOffset() + 1);
450
            return results;
450
            return results;
451
        }
451
        }
452
    }
452
    }
Lines 475-481 Link Here
475
                }
475
                }
476
            }
476
            }
477
477
478
            setAnchorOffset(context.getCurrentToken().getOffset() + 1);
478
            setAnchorOffset(context.getCurrentTokenOffset() + 1);
479
            return results;
479
            return results;
480
        }
480
        }
481
        
481
        
(-)a/hibernate/src/org/netbeans/modules/hibernate/completion/HibernateCfgCompletionManager.java (-16 / +29 lines)
Lines 49-63 Link Here
49
import java.util.HashMap;
49
import java.util.HashMap;
50
import java.util.List;
50
import java.util.List;
51
import java.util.Map;
51
import java.util.Map;
52
import javax.swing.text.BadLocationException;
52
import org.hibernate.cfg.Environment;
53
import org.hibernate.cfg.Environment;
53
import org.netbeans.editor.TokenItem;
54
import org.netbeans.api.lexer.Token;
55
import org.netbeans.api.lexer.TokenSequence;
56
import org.netbeans.api.xml.lexer.XMLTokenId;
54
import org.netbeans.modules.hibernate.cfg.HibernateCfgProperties;
57
import org.netbeans.modules.hibernate.cfg.HibernateCfgProperties;
55
import org.netbeans.modules.hibernate.cfg.HibernateCfgXmlConstants;
58
import org.netbeans.modules.hibernate.cfg.HibernateCfgXmlConstants;
56
import org.netbeans.modules.xml.text.syntax.SyntaxElement;
59
import org.netbeans.modules.xml.text.api.dom.SyntaxElement;
57
import org.netbeans.modules.xml.text.syntax.dom.StartTag;
60
import org.netbeans.modules.xml.text.api.dom.TagElement;
58
import org.netbeans.modules.xml.text.syntax.dom.Tag;
59
import org.openide.util.NbBundle;
61
import org.openide.util.NbBundle;
60
import org.w3c.dom.Text;
62
import org.w3c.dom.Node;
61
63
62
/**
64
/**
63
 * This class figures out the completion items for various attributes
65
 * This class figures out the completion items for various attributes
Lines 179-186 Link Here
179
            return anchorOffset;
181
            return anchorOffset;
180
        
182
        
181
        String tagName = context.getTag().getNodeName();
183
        String tagName = context.getTag().getNodeName();
182
        TokenItem attrib = ContextUtilities.getAttributeToken(context.getCurrentToken());
184
        Token<XMLTokenId> attrib = ContextUtilities.getAttributeToken(context.getDocumentContext());
183
        String attribName = attrib != null ? attrib.getImage() : null;
185
        String attribName = attrib != null ? attrib.text().toString(): null;
184
186
185
        Completor completor = locateCompletor(tagName, attribName);
187
        Completor completor = locateCompletor(tagName, attribName);
186
        if (completor != null) {
188
        if (completor != null) {
Lines 198-218 Link Here
198
        DocumentContext docContext = context.getDocumentContext();
200
        DocumentContext docContext = context.getDocumentContext();
199
        SyntaxElement curElem = docContext.getCurrentElement();
201
        SyntaxElement curElem = docContext.getCurrentElement();
200
        SyntaxElement prevElem = docContext.getCurrentElement().getPrevious();
202
        SyntaxElement prevElem = docContext.getCurrentElement().getPrevious();
201
        Tag propTag = null;
203
        TagElement propTag = null;
202
204
203
        // If current element is a start tag and its tag is <property>
205
        // If current element is a start tag and its tag is <property>
204
        // or the current element is text and its prev is a start <property> tag,
206
        // or the current element is text and its prev is a start <property> tag,
205
        // then do the code completion
207
        // then do the code completion
206
        if ((curElem instanceof StartTag) && ((StartTag) curElem).getTagName().equalsIgnoreCase(HibernateCfgXmlConstants.PROPERTY_TAG)) {
208
        if (curElem.getType() == Node.ELEMENT_NODE &&
207
            propTag = (StartTag) curElem;
209
            ((TagElement)curElem).isStart() && HibernateCfgXmlConstants.PROPERTY_TAG.equalsIgnoreCase(curElem.getNode().getNodeName())) {
208
        } else if ((curElem instanceof Text) && (prevElem instanceof StartTag) &&
210
            propTag = (TagElement) curElem;
209
                ((StartTag) prevElem).getTagName().equalsIgnoreCase(HibernateCfgXmlConstants.PROPERTY_TAG)) {
211
        } else if (curElem.getType() == Node.TEXT_NODE && 
210
            propTag = (StartTag) prevElem;
212
                (prevElem.getType() == Node.ELEMENT_NODE && ((TagElement)prevElem).isStart() &&
213
                HibernateCfgXmlConstants.PROPERTY_TAG.equalsIgnoreCase(prevElem.getNode().getNodeName()))) {
214
            propTag = (TagElement) prevElem;
211
        } else {
215
        } else {
212
            return anchorOffset;
216
            return anchorOffset;
213
        }
217
        }
214
        
218
        
215
        String propName = HibernateEditorUtil.getHbPropertyName(propTag);
219
        String propName = HibernateEditorUtil.getHbPropertyName(propTag.getNode());
216
        int caretOffset = context.getCaretOffset();
220
        int caretOffset = context.getCaretOffset();
217
        String typedChars = context.getTypedPrefix();
221
        String typedChars = context.getTypedPrefix();
218
        
222
        
Lines 231-238 Link Here
231
                    valueItems.add(item);
235
                    valueItems.add(item);
232
                }
236
                }
233
            }
237
            }
234
238
            try {
235
            anchorOffset = context.getCurrentToken().getPrevious().getOffset() + 1;
239
                anchorOffset = context.getDocumentContext().
240
                        runWithSequence((TokenSequence s) -> {
241
                            if (!s.movePrevious()) {
242
                                return -1;
243
                            }
244
                            return s.offset();
245
                        });
246
            } catch (BadLocationException ex) {
247
                anchorOffset = -1;
248
            }
236
        }
249
        }
237
        
250
        
238
        return anchorOffset;
251
        return anchorOffset;
(-)a/hibernate/src/org/netbeans/modules/hibernate/completion/HibernateMappingCompletionManager.java (-4 / +4 lines)
Lines 47-55 Link Here
47
import java.util.HashMap;
47
import java.util.HashMap;
48
import java.util.List;
48
import java.util.List;
49
import java.util.Map;
49
import java.util.Map;
50
import org.netbeans.editor.TokenItem;
50
import org.netbeans.api.lexer.Token;
51
import org.netbeans.api.xml.lexer.XMLTokenId;
51
import org.netbeans.modules.hibernate.mapping.HibernateMappingXmlConstants;
52
import org.netbeans.modules.hibernate.mapping.HibernateMappingXmlConstants;
52
import org.netbeans.spi.editor.completion.CompletionResultSet;
53
import org.openide.util.NbBundle;
53
import org.openide.util.NbBundle;
54
54
55
/**
55
/**
Lines 240-247 Link Here
240
            return anchorOffset;
240
            return anchorOffset;
241
        
241
        
242
        String tagName = context.getTag().getNodeName();
242
        String tagName = context.getTag().getNodeName();
243
        TokenItem attrib = ContextUtilities.getAttributeToken(context.getCurrentToken());
243
        Token<XMLTokenId> attrib = ContextUtilities.getAttributeToken(context.getDocumentContext());
244
        String attribName = attrib != null ? attrib.getImage() : null;
244
        String attribName = attrib != null ? attrib.text().toString(): null;
245
245
246
        Completor completor = locateCompletor(tagName, attribName);
246
        Completor completor = locateCompletor(tagName, attribName);
247
        if (completor != null) {
247
        if (completor != null) {
(-)a/hibernate/src/org/netbeans/modules/hibernate/completion/HibernateRevengCompletionManager.java (-3 / +4 lines)
Lines 47-53 Link Here
47
import java.util.HashMap;
47
import java.util.HashMap;
48
import java.util.List;
48
import java.util.List;
49
import java.util.Map;
49
import java.util.Map;
50
import org.netbeans.editor.TokenItem;
50
import org.netbeans.api.lexer.Token;
51
import org.netbeans.api.xml.lexer.XMLTokenId;
51
import org.netbeans.modules.hibernate.reveng.HibernateRevengXmlConstants;
52
import org.netbeans.modules.hibernate.reveng.HibernateRevengXmlConstants;
52
import org.openide.util.NbBundle;
53
import org.openide.util.NbBundle;
53
54
Lines 160-167 Link Here
160
            return anchorOffset;
161
            return anchorOffset;
161
        
162
        
162
        String tagName = context.getTag().getNodeName();
163
        String tagName = context.getTag().getNodeName();
163
        TokenItem attrib = ContextUtilities.getAttributeToken(context.getCurrentToken());
164
        Token<XMLTokenId> attrib = ContextUtilities.getAttributeToken(context.getDocumentContext());
164
        String attribName = attrib != null ? attrib.getImage() : null;
165
        String attribName = attrib != null ? attrib.text().toString(): null;
165
166
166
        Completor completor = locateCompletor(tagName, attribName);
167
        Completor completor = locateCompletor(tagName, attribName);
167
        if (completor != null) {
168
        if (completor != null) {
(-)a/hibernate/src/org/netbeans/modules/hibernate/editor/ContextUtilities.java (-90 / +50 lines)
Lines 44-56 Link Here
44
44
45
package org.netbeans.modules.hibernate.editor;
45
package org.netbeans.modules.hibernate.editor;
46
46
47
import javax.swing.text.BadLocationException;
47
import javax.xml.XMLConstants;
48
import javax.xml.XMLConstants;
48
import org.netbeans.editor.TokenItem;
49
import org.netbeans.api.lexer.Token;
49
import org.netbeans.modules.xml.text.api.XMLDefaultTokenContext;
50
import org.netbeans.api.lexer.TokenSequence;
50
import org.netbeans.modules.xml.text.syntax.SyntaxElement;
51
import org.netbeans.api.xml.lexer.XMLTokenId;
51
import org.netbeans.modules.xml.text.syntax.dom.EmptyTag;
52
52
import org.netbeans.modules.xml.text.syntax.dom.StartTag;
53
import static org.netbeans.api.xml.lexer.XMLTokenId.*;
53
import org.netbeans.modules.xml.text.syntax.dom.Tag;
54
import org.netbeans.modules.xml.text.api.dom.SyntaxElement;
55
import org.netbeans.modules.xml.text.api.dom.TagElement;
56
import org.w3c.dom.Node;
54
57
55
/**
58
/**
56
 *
59
 *
Lines 61-69 Link Here
61
    private ContextUtilities() {
64
    private ContextUtilities() {
62
    }
65
    }
63
    
66
    
64
    public static boolean isValueToken(TokenItem currentToken) {
67
    public static boolean isValueToken(Token<XMLTokenId> currentToken) {
65
        if(currentToken != null) {
68
        if(currentToken != null) {
66
            if (currentToken.getTokenID().getNumericID() == XMLDefaultTokenContext.VALUE_ID) {
69
            if (currentToken.id() == VALUE) {
67
                return true;
70
                return true;
68
            }
71
            }
69
        }
72
        }
Lines 71-79 Link Here
71
        return false;
74
        return false;
72
    }
75
    }
73
    
76
    
74
    public static boolean isTagToken(TokenItem currentToken) {
77
    public static boolean isTagToken(Token<XMLTokenId> currentToken) {
75
        if(currentToken != null) {
78
        if(currentToken != null) {
76
            if (currentToken.getTokenID().getNumericID() == XMLDefaultTokenContext.TAG_ID) {
79
            if (currentToken.id() == TAG) {
77
                return true;
80
                return true;
78
            }
81
            }
79
        }
82
        }
Lines 81-89 Link Here
81
        return false;
84
        return false;
82
    }
85
    }
83
    
86
    
84
    public static boolean isAttributeToken(TokenItem currentToken) {
87
    public static boolean isAttributeToken(Token<XMLTokenId> currentToken) {
85
        if(currentToken != null) {
88
        if(currentToken != null) {
86
            if (currentToken.getTokenID().getNumericID() == XMLDefaultTokenContext.ARGUMENT_ID) {
89
            if (currentToken.id() == ARGUMENT) {
87
                return true;
90
                return true;
88
            }
91
            }
89
        }
92
        }
Lines 91-178 Link Here
91
        return false;
94
        return false;
92
    }
95
    }
93
    
96
    
94
    public static TokenItem getAttributeToken(TokenItem currentToken) {
97
    public static Token<XMLTokenId> getAttributeToken(DocumentContext context) {
95
        if(currentToken == null )
96
            return null;
97
        
98
        if(isValueToken(currentToken)) {
99
            TokenItem equalsToken = currentToken.getPrevious();
100
            if(equalsToken == null)
101
                return null;
102
            
103
            while(equalsToken != null && equalsToken.getTokenID().getNumericID() != XMLDefaultTokenContext.OPERATOR_ID) {
104
                equalsToken = equalsToken.getPrevious();
105
            }
106
            
107
            if(equalsToken == null) {
108
                return null;
109
            }
110
        
111
            TokenItem argumentToken = equalsToken.getPrevious();
112
            if(argumentToken == null)
113
                return null;
114
            
115
            while(argumentToken != null && argumentToken.getTokenID().getNumericID() != XMLDefaultTokenContext.ARGUMENT_ID) {
116
                argumentToken = argumentToken.getPrevious();
117
            }
118
        
119
            return argumentToken;
120
        }
121
        
122
        return null;
123
    }
124
  
125
    public static Tag getCurrentTagElement(DocumentContext context) {
126
        SyntaxElement element = context.getCurrentElement();
127
        if(element instanceof StartTag) {
128
            return (StartTag) element;
129
        } else if(element instanceof EmptyTag) {
130
            return (EmptyTag) element;
131
        }
132
        
133
        return null;
134
    }
135
    
136
    public static TokenItem getAttributeToken(DocumentContext context) {
137
        if(context.getCurrentToken() == null )
98
        if(context.getCurrentToken() == null )
138
            return null;
99
            return null;
139
        
100
        try {
140
        if(isValueToken(context.getCurrentToken())) {
101
            return context.<Token<XMLTokenId>>runWithSequence((TokenSequence ts) -> {
141
            TokenItem equalsToken = context.getCurrentToken().getPrevious();
102
                if(!isValueToken(context.getCurrentToken())) {
142
            if(equalsToken == null)
103
                    return null;
143
                return null;
104
                }
144
            
105
                Token<XMLTokenId> equalsToken = null;
145
            //getTokenId() should not return null by JavaDoc. But in reality, it does reutrn null sometimes
106
                while (ts.movePrevious()) {
146
            // see issue 67661
107
                    Token<XMLTokenId> t = ts.token();
147
            if(equalsToken.getTokenID() == null) {
108
                    if (t.id() == OPERATOR) {
148
                return null;
109
                        equalsToken = t;
149
            }
110
                        break;
150
            while(equalsToken != null && equalsToken.getTokenID().getNumericID() != XMLDefaultTokenContext.OPERATOR_ID) {
111
                    }
151
                equalsToken = equalsToken.getPrevious();
112
                }
152
            }
113
                if(equalsToken == null) {
153
            
114
                    return null;
154
            if(equalsToken == null) {
115
                }
155
                return null;
116
                Token<XMLTokenId> argumentToken = null;
156
            }
117
                while (ts.movePrevious()) {
157
        
118
                    Token<XMLTokenId> t = ts.token();
158
            TokenItem argumentToken = equalsToken.getPrevious();
119
                    if (t.id() == ARGUMENT) {
159
            if(argumentToken == null)
120
                        argumentToken = t;
160
                return null;
121
                        break;
161
            
122
                    }
162
            while(argumentToken != null && argumentToken.getTokenID().getNumericID() != XMLDefaultTokenContext.ARGUMENT_ID) {
123
                }
163
                argumentToken = argumentToken.getPrevious();
124
                return argumentToken;
164
            }
125
            });
165
        
126
        } catch (BadLocationException ex) {
166
            return argumentToken;
167
        }
127
        }
168
        
169
        return null;
128
        return null;
170
    }
129
    }
171
    
130
    
172
    public static String getAttributeTokenImage(DocumentContext context) {
131
    public static String getAttributeTokenImage(DocumentContext context) {
173
        TokenItem tok = getAttributeToken(context);
132
        Token<XMLTokenId> tok = getAttributeToken(context);
174
        if(tok != null) {
133
        if(tok != null) {
175
            return tok.getImage();
134
            return tok.text().toString();
176
        }
135
        }
177
        
136
        
178
        return null;
137
        return null;
Lines 221-231 Link Here
221
        return nodeName.substring(0, colonIndex);
180
        return nodeName.substring(0, colonIndex);
222
    }
181
    }
223
    
182
    
224
    public static StartTag getRoot(SyntaxElement se) {
183
    public static SyntaxElement getRoot(SyntaxElement se) {
225
        StartTag root = null;
184
        SyntaxElement root = null;
226
        while( se != null) {
185
        while( se != null) {
227
            if(se instanceof StartTag) {
186
            if(se.getType() == Node.ELEMENT_NODE &&
228
                root = (StartTag)se;
187
               ((TagElement)se).isStart()) {
188
                root = se;
229
            }
189
            }
230
            se = se.getPrevious();
190
            se = se.getPrevious();
231
        }
191
        }
(-)a/hibernate/src/org/netbeans/modules/hibernate/editor/DocumentContext.java (-74 / +35 lines)
Lines 44-68 Link Here
44
44
45
package org.netbeans.modules.hibernate.editor;
45
package org.netbeans.modules.hibernate.editor;
46
46
47
import java.util.ArrayList;
48
import java.util.Collection;
47
import java.util.Collection;
49
import java.util.Collections;
50
import java.util.HashMap;
48
import java.util.HashMap;
51
import java.util.List;
52
import java.util.Map.Entry;
49
import java.util.Map.Entry;
53
import java.util.Stack;
54
import java.util.logging.Level;
50
import java.util.logging.Level;
55
import java.util.logging.Logger;
51
import java.util.logging.Logger;
56
import javax.swing.text.BadLocationException;
52
import javax.swing.text.BadLocationException;
57
import javax.swing.text.Document;
53
import javax.swing.text.Document;
58
import org.netbeans.editor.BaseDocument;
54
import org.netbeans.api.lexer.Token;
59
import org.netbeans.editor.TokenItem;
55
import org.netbeans.api.xml.lexer.XMLTokenId;
60
import org.netbeans.modules.xml.text.syntax.SyntaxElement;
56
import org.netbeans.modules.xml.text.api.dom.SyntaxElement;
61
import org.netbeans.modules.xml.text.syntax.XMLSyntaxSupport;
57
import org.netbeans.modules.xml.text.api.dom.XMLSyntaxSupport;
62
import org.netbeans.modules.xml.text.syntax.dom.EmptyTag;
63
import org.netbeans.modules.xml.text.syntax.dom.EndTag;
64
import org.netbeans.modules.xml.text.syntax.dom.StartTag;
65
import org.netbeans.modules.xml.text.syntax.dom.Tag;
66
import org.w3c.dom.Attr;
58
import org.w3c.dom.Attr;
67
import org.w3c.dom.NamedNodeMap;
59
import org.w3c.dom.NamedNodeMap;
68
import org.w3c.dom.Node;
60
import org.w3c.dom.Node;
Lines 83-91 Link Here
83
    private XMLSyntaxSupport syntaxSupport;
75
    private XMLSyntaxSupport syntaxSupport;
84
    private int caretOffset = -1;
76
    private int caretOffset = -1;
85
    private SyntaxElement element;
77
    private SyntaxElement element;
86
    private TokenItem token;
78
    private Token<XMLTokenId> token;
79
    private int tokenOffset;
87
    private boolean valid = false;
80
    private boolean valid = false;
88
    private StartTag docRoot;
81
    private SyntaxElement docRoot;
89
    private String defaultNamespace;
82
    private String defaultNamespace;
90
    private HashMap<String, String> declaredNamespaces =
83
    private HashMap<String, String> declaredNamespaces =
91
            new HashMap<String, String>();
84
            new HashMap<String, String>();
Lines 95-104 Link Here
95
    DocumentContext(Document document) {
88
    DocumentContext(Document document) {
96
        this.document = document;
89
        this.document = document;
97
        try {
90
        try {
98
            this.syntaxSupport = (XMLSyntaxSupport) ((BaseDocument)document).getSyntaxSupport();
91
            this.syntaxSupport = XMLSyntaxSupport.getSyntaxSupport(document);
99
        } catch (ClassCastException cce) {
92
        } catch (ClassCastException cce) {
100
            LOGGER.log(Level.FINE, cce.getMessage());
93
            LOGGER.log(Level.FINE, cce.getMessage());
101
            this.syntaxSupport = new XMLSyntaxSupport(((BaseDocument)document));
94
            this.syntaxSupport = XMLSyntaxSupport.createSyntaxSupport(document);
102
        }
95
        }
103
    }
96
    }
104
97
Lines 108-120 Link Here
108
    }
101
    }
109
102
110
    private void initialize() {
103
    private void initialize() {
111
        valid = true;
112
        declaredNamespaces.clear();
104
        declaredNamespaces.clear();
105
        if (syntaxSupport == null) {
106
            valid = false;
107
            return;
108
        }
113
        try {
109
        try {
114
            element = syntaxSupport.getElementChain(caretOffset);
110
            element = syntaxSupport.getElementChain(caretOffset);
115
            token = syntaxSupport.getTokenChain(caretOffset, Math.min(document.getLength(), caretOffset+1));
111
            int[] off = new int[2];
112
            token = syntaxSupport.getTokenAtPosition(caretOffset, off);
113
            tokenOffset = off[0];
116
            this.docRoot = ContextUtilities.getRoot(element);
114
            this.docRoot = ContextUtilities.getRoot(element);
117
            populateNamespaces();
115
            populateNamespaces();
116
            valid = true;
118
        } catch (BadLocationException ex) {
117
        } catch (BadLocationException ex) {
119
            // No context support available in this case
118
            // No context support available in this case
120
            valid = false;
119
            valid = false;
Lines 125-130 Link Here
125
        return this.valid;
124
        return this.valid;
126
    }
125
    }
127
126
127
    /*
128
    public int getCurrentTokenId() {
128
    public int getCurrentTokenId() {
129
        if (isValid()) {
129
        if (isValid()) {
130
            return token.getTokenID().getNumericID();
130
            return token.getTokenID().getNumericID();
Lines 132-139 Link Here
132
            return -1;
132
            return -1;
133
        }
133
        }
134
    }
134
    }
135
    */
135
136
136
    public TokenItem getCurrentToken() {
137
    public Token<XMLTokenId> getCurrentToken() {
137
        if (isValid()) {
138
        if (isValid()) {
138
            return token;
139
            return token;
139
        } else {
140
        } else {
Lines 143-206 Link Here
143
144
144
    public String getCurrentTokenImage() {
145
    public String getCurrentTokenImage() {
145
        if (isValid()) {
146
        if (isValid()) {
146
            return token.getImage();
147
            return token.text().toString();
147
        } else {
148
        } else {
148
            return null;
149
            return null;
149
        }
150
        }
150
    }
151
    }
152
    
153
    public int getCurrentTokenOffset() {
154
        return tokenOffset;
155
    }
151
156
152
    public SyntaxElement getCurrentElement() {
157
    public SyntaxElement getCurrentElement() {
153
        return this.element;
158
        return this.element;
154
    }
159
    }
155
    
156
    public List<String> getPathFromRoot() {
157
        if (isValid()) {
158
            SyntaxElement elementRef = this.element;
159
            Stack<SyntaxElement> stack = new Stack<SyntaxElement>();
160
161
            while (elementRef != null) {
162
                if ((elementRef instanceof EndTag) ||
163
                        (elementRef instanceof EmptyTag && stack.isEmpty()) ||
164
                        (elementRef instanceof StartTag && stack.isEmpty())) {
165
                    stack.push(elementRef);
166
                    elementRef = elementRef.getPrevious();
167
                    continue;
168
                }
169
                if (elementRef instanceof StartTag) {
170
                    StartTag start = (StartTag) elementRef;
171
                    if (stack.peek() instanceof EndTag) {
172
                        EndTag end = (EndTag) stack.peek();
173
                        if (end.getTagName().equals(start.getTagName())) {
174
                            stack.pop();
175
                        }
176
                    } else {
177
                        SyntaxElement e = (SyntaxElement) stack.peek();
178
                        String tagAtTop = (e instanceof StartTag) ? ((StartTag) e).getTagName() : ((EmptyTag) e).getTagName();
179
                        stack.push(elementRef);
180
                    }
181
                }
182
                elementRef = elementRef.getPrevious();
183
            }
184
185
            return createPath(stack);
186
        }
187
188
        return Collections.emptyList();
189
    }
190
191
    private List<String> createPath(Stack<SyntaxElement> stack) {
192
        ArrayList<String> pathList = new ArrayList<String>();
193
        while (!stack.isEmpty()) {
194
            SyntaxElement top = stack.pop();
195
            String tagName = (top instanceof StartTag) ? ((StartTag) top).getTagName() : ((EmptyTag) top).getTagName();
196
            if (tagName != null) {
197
                pathList.add(tagName);
198
            }
199
        }
200
201
        return Collections.unmodifiableList(pathList);
202
    }
203
204
    public Document getDocument() {
160
    public Document getDocument() {
205
        return this.document;
161
        return this.document;
206
    }
162
    }
Lines 223-229 Link Here
223
        return declaredNamespaces.values();
179
        return declaredNamespaces.values();
224
    }
180
    }
225
181
226
    public StartTag getDocRoot() {
182
    public SyntaxElement getDocRoot() {
227
        return docRoot;
183
        return docRoot;
228
    }
184
    }
229
185
Lines 234-240 Link Here
234
    private void populateNamespaces() {
190
    private void populateNamespaces() {
235
        // Find the a start or empty tag just before the current syntax element.
191
        // Find the a start or empty tag just before the current syntax element.
236
        SyntaxElement element = this.element;
192
        SyntaxElement element = this.element;
237
        while (element != null && !(element instanceof StartTag) && !(element instanceof EmptyTag)) {
193
        while (element != null && !syntaxSupport.isStartTag(element) && !syntaxSupport.isEmptyTag(element)) {
238
            element = element.getPrevious();
194
            element = element.getPrevious();
239
        }
195
        }
240
        if (element == null) {
196
        if (element == null) {
Lines 244-252 Link Here
244
        // To find all namespace declarations active at the caret offset, we
200
        // To find all namespace declarations active at the caret offset, we
245
        // need to look at xmlns attributes of the current element and its ancestors.
201
        // need to look at xmlns attributes of the current element and its ancestors.
246
        Node node = (Node)element;
202
        Node node = (Node)element;
247
        while (node != null) {
203
        while (node != null && element != null) {
248
            if (node instanceof StartTag || node instanceof EmptyTag) {
204
            if (syntaxSupport.isStartTag(element) || syntaxSupport.isEmptyTag(element)) {
249
                NamedNodeMap attributes = ((Tag)node).getAttributes();
205
                NamedNodeMap attributes = node.getAttributes();
250
                for (int index = 0; index < attributes.getLength(); index++) {
206
                for (int index = 0; index < attributes.getLength(); index++) {
251
                    Attr attr = (Attr) attributes.item(index);
207
                    Attr attr = (Attr) attributes.item(index);
252
                    String attrName = attr.getName();
208
                    String attrName = attr.getName();
Lines 265-270 Link Here
265
                }
221
                }
266
            }
222
            }
267
            node = node.getParentNode();
223
            node = node.getParentNode();
224
            element = syntaxSupport.getSyntaxElement(node);
268
        }
225
        }
269
    }
226
    }
270
    
227
    
Lines 297-300 Link Here
297
        hash = 61 * hash + (this.document != null ? this.document.hashCode() : 0);
254
        hash = 61 * hash + (this.document != null ? this.document.hashCode() : 0);
298
        return hash;
255
        return hash;
299
    }
256
    }
257
    
258
    public <T> T runWithSequence(XMLSyntaxSupport.SequenceCallable<T> callable) throws BadLocationException {
259
        return syntaxSupport.runWithSequence(caretOffset, callable);
260
    }
300
}
261
}
(-)a/hibernate/src/org/netbeans/modules/hibernate/hyperlink/HibernateCfgHyperlinkProvider.java (-7 / +2 lines)
Lines 50-56 Link Here
50
import org.netbeans.editor.BaseDocument;
50
import org.netbeans.editor.BaseDocument;
51
import org.netbeans.lib.editor.hyperlink.spi.HyperlinkProvider;
51
import org.netbeans.lib.editor.hyperlink.spi.HyperlinkProvider;
52
import org.netbeans.modules.hibernate.cfg.HibernateCfgXmlConstants;
52
import org.netbeans.modules.hibernate.cfg.HibernateCfgXmlConstants;
53
import org.netbeans.modules.xml.text.syntax.XMLSyntaxSupport;
53
import org.netbeans.modules.xml.text.api.dom.XMLSyntaxSupport;
54
54
55
/**
55
/**
56
 * Provides hyperlinking functionality for HibernateConfiguration files
56
 * Provides hyperlinking functionality for HibernateConfiguration files
Lines 86-97 Link Here
86
    }
86
    }
87
    
87
    
88
    public boolean isHyperlinkPoint(Document document, int offset) {
88
    public boolean isHyperlinkPoint(Document document, int offset) {
89
        if (!(document instanceof BaseDocument)) {
89
        if (XMLSyntaxSupport.getSyntaxSupport(document) == null) {
90
            return false;
91
        }
92
93
        BaseDocument doc = (BaseDocument) document;
94
        if (!(doc.getSyntaxSupport() instanceof XMLSyntaxSupport)) {
95
            return false;
90
            return false;
96
        }
91
        }
97
92
(-)a/hibernate/src/org/netbeans/modules/hibernate/hyperlink/HibernateMappingHyperlinkProvider.java (-7 / +2 lines)
Lines 50-56 Link Here
50
import org.netbeans.editor.BaseDocument;
50
import org.netbeans.editor.BaseDocument;
51
import org.netbeans.lib.editor.hyperlink.spi.HyperlinkProvider;
51
import org.netbeans.lib.editor.hyperlink.spi.HyperlinkProvider;
52
import org.netbeans.modules.hibernate.mapping.HibernateMappingXmlConstants;
52
import org.netbeans.modules.hibernate.mapping.HibernateMappingXmlConstants;
53
import org.netbeans.modules.xml.text.syntax.XMLSyntaxSupport;
53
import org.netbeans.modules.xml.text.api.dom.XMLSyntaxSupport;
54
54
55
/**
55
/**
56
 * Provides hyperlinking functionality for Hibernate mapping files
56
 * Provides hyperlinking functionality for Hibernate mapping files
Lines 112-123 Link Here
112
    }
112
    }
113
    
113
    
114
    public boolean isHyperlinkPoint(Document document, int offset) {
114
    public boolean isHyperlinkPoint(Document document, int offset) {
115
        if (!(document instanceof BaseDocument)) {
115
        if (XMLSyntaxSupport.getSyntaxSupport(document) == null) {
116
            return false;
117
        }
118
119
        BaseDocument doc = (BaseDocument) document;
120
        if (!(doc.getSyntaxSupport() instanceof XMLSyntaxSupport)) {
121
            return false;
116
            return false;
122
        }
117
        }
123
118
(-)a/hibernate/src/org/netbeans/modules/hibernate/hyperlink/HyperlinkEnv.java (-10 / +19 lines)
Lines 44-57 Link Here
44
package org.netbeans.modules.hibernate.hyperlink;
44
package org.netbeans.modules.hibernate.hyperlink;
45
45
46
import javax.swing.text.Document;
46
import javax.swing.text.Document;
47
import org.netbeans.editor.TokenItem;
47
import org.netbeans.api.lexer.Token;
48
import org.netbeans.api.xml.lexer.XMLTokenId;
48
import org.netbeans.modules.editor.NbEditorUtilities;
49
import org.netbeans.modules.editor.NbEditorUtilities;
49
import org.netbeans.modules.hibernate.editor.ContextUtilities;
50
import org.netbeans.modules.hibernate.editor.ContextUtilities;
50
import org.netbeans.modules.hibernate.editor.DocumentContext;
51
import org.netbeans.modules.hibernate.editor.DocumentContext;
51
import org.netbeans.modules.hibernate.editor.EditorContextFactory;
52
import org.netbeans.modules.hibernate.editor.EditorContextFactory;
52
import org.netbeans.modules.xml.text.syntax.SyntaxElement;
53
import org.netbeans.modules.xml.text.api.dom.SyntaxElement;
53
import org.netbeans.modules.xml.text.syntax.dom.Tag;
54
import org.openide.filesystems.FileObject;
54
import org.openide.filesystems.FileObject;
55
import org.w3c.dom.Node;
55
56
56
/**
57
/**
57
 *
58
 *
Lines 64-70 Link Here
64
    private String attribName;
65
    private String attribName;
65
    private String valueString;
66
    private String valueString;
66
    private int offset;
67
    private int offset;
67
    private TokenItem token;
68
    private Token<XMLTokenId> token;
68
    private DocumentContext documentContext;
69
    private DocumentContext documentContext;
69
70
70
    public static enum Type {
71
    public static enum Type {
Lines 99-111 Link Here
99
                currentTag = documentContext.getCurrentElement();
100
                currentTag = documentContext.getCurrentElement();
100
                attribName = ContextUtilities.getAttributeTokenImage(documentContext);
101
                attribName = ContextUtilities.getAttributeTokenImage(documentContext);
101
                token = documentContext.getCurrentToken();
102
                token = documentContext.getCurrentToken();
102
                valueString = token.getImage();
103
                valueString = token.text().toString();
103
                valueString = valueString.substring(1, valueString.length() - 1); // Strip quotes
104
                valueString = valueString.substring(1, valueString.length() - 1); // Strip quotes
104
            } else if (ContextUtilities.isAttributeToken(documentContext.getCurrentToken())) {
105
            } else if (ContextUtilities.isAttributeToken(documentContext.getCurrentToken())) {
105
                type = Type.ATTRIB;
106
                type = Type.ATTRIB;
106
                currentTag = documentContext.getCurrentElement();
107
                currentTag = documentContext.getCurrentElement();
107
                token = documentContext.getCurrentToken();
108
                token = documentContext.getCurrentToken();
108
                attribName = token.getImage();
109
                attribName = token.text().toString();
109
            }
110
            }
110
        }
111
        }
111
    }
112
    }
Lines 114-121 Link Here
114
        return attribName;
115
        return attribName;
115
    }
116
    }
116
117
117
    public Tag getCurrentTag() {
118
    public SyntaxElement getCurrentTag() {
118
        return currentTag instanceof Tag ? (Tag) currentTag : null;
119
        if (currentTag.getType() == Node.ELEMENT_NODE) {
120
            return currentTag;
121
        } else {
122
            return null;
123
        }
119
    }
124
    }
120
125
121
    public Document getDocument() {
126
    public Document getDocument() {
Lines 123-129 Link Here
123
    }
128
    }
124
129
125
    public String getTagName() {
130
    public String getTagName() {
126
        return getCurrentTag() != null ? getCurrentTag().getTagName() : null;
131
        return getCurrentTag() != null ? getCurrentTag().getNode().getNodeName(): null;
127
    }
132
    }
128
133
129
    public String getValueString() {
134
    public String getValueString() {
Lines 134-142 Link Here
134
        return type;
139
        return type;
135
    }
140
    }
136
141
137
    public TokenItem getToken() {
142
    public Token<XMLTokenId> getToken() {
138
        return token;
143
        return token;
139
    }
144
    }
145
    
146
    public int getTokenOffset() {
147
        return documentContext.getCurrentTokenOffset();
148
    }
140
149
141
    public int getOffset() {
150
    public int getOffset() {
142
        return offset;
151
        return offset;
(-)a/hibernate/src/org/netbeans/modules/hibernate/hyperlink/HyperlinkProcessor.java (-3 / +4 lines)
Lines 44-50 Link Here
44
44
45
package org.netbeans.modules.hibernate.hyperlink;
45
package org.netbeans.modules.hibernate.hyperlink;
46
46
47
import org.netbeans.editor.TokenItem;
47
import org.netbeans.api.lexer.Token;
48
import org.netbeans.api.xml.lexer.XMLTokenId;
48
49
49
/**
50
/**
50
 *
51
 *
Lines 54-60 Link Here
54
    public abstract void process(HyperlinkEnv env);
55
    public abstract void process(HyperlinkEnv env);
55
    
56
    
56
    public int[] getSpan(HyperlinkEnv env) {
57
    public int[] getSpan(HyperlinkEnv env) {
57
        TokenItem item = env.getToken();
58
        Token<XMLTokenId> item = env.getToken();
58
        return new int[] { item.getOffset() + 1, item.getOffset() + item.getImage().length() - 1 };
59
        return new int[] { env.getTokenOffset() + 1, env.getTokenOffset() + item.text().length() - 1 };
59
    }
60
    }
60
}
61
}
(-)a/hibernate/src/org/netbeans/modules/hibernate/hyperlink/JavaClassHyperlinkProcessor.java (-1 / +4 lines)
Lines 45-50 Link Here
45
45
46
import org.netbeans.modules.hibernate.editor.HibernateEditorUtil;
46
import org.netbeans.modules.hibernate.editor.HibernateEditorUtil;
47
import org.netbeans.modules.hibernate.mapping.HibernateMappingXmlConstants;
47
import org.netbeans.modules.hibernate.mapping.HibernateMappingXmlConstants;
48
import org.w3c.dom.Node;
48
49
49
/**
50
/**
50
 *
51
 *
Lines 58-64 Link Here
58
    @Override
59
    @Override
59
    public void process(HyperlinkEnv env) {
60
    public void process(HyperlinkEnv env) {
60
        String className = env.getValueString();
61
        String className = env.getValueString();
61
        String pack = env.getDocumentContext().getDocRoot().getAttribute(HibernateMappingXmlConstants.PACKAGE_ATTRIB);//NOI18N
62
        Node n = env.getDocumentContext().getDocRoot().getNode().getAttributes().
63
                getNamedItem(HibernateMappingXmlConstants.PACKAGE_ATTRIB);//NOI18N
64
        String pack = n == null ? null : n.getNodeValue();
62
        if(pack!=null &&  pack.length()>0){
65
        if(pack!=null &&  pack.length()>0){
63
            if(!className.contains(".")){
66
            if(!className.contains(".")){
64
                className = pack + "." +className;
67
                className = pack + "." +className;
(-)a/hibernate/src/org/netbeans/modules/hibernate/hyperlink/PropertyHyperlinkProcessor.java (-2 / +5 lines)
Lines 55-60 Link Here
55
import org.netbeans.modules.hibernate.editor.HibernateEditorUtil;
55
import org.netbeans.modules.hibernate.editor.HibernateEditorUtil;
56
import org.netbeans.modules.hibernate.mapping.HibernateMappingXmlConstants;
56
import org.netbeans.modules.hibernate.mapping.HibernateMappingXmlConstants;
57
import org.openide.util.Exceptions;
57
import org.openide.util.Exceptions;
58
import org.w3c.dom.Node;
58
59
59
/**
60
/**
60
 *
61
 *
Lines 68-78 Link Here
68
    @Override
69
    @Override
69
    public void process(HyperlinkEnv env) {
70
    public void process(HyperlinkEnv env) {
70
        try {
71
        try {
71
            String className0 = HibernateEditorUtil.getClassName(env.getCurrentTag());
72
            String className0 = HibernateEditorUtil.getClassName(env.getCurrentTag().getNode());
72
            if (className0 == null) {
73
            if (className0 == null) {
73
                return;
74
                return;
74
            }
75
            }
75
            String pack = env.getDocumentContext().getDocRoot().getAttribute(HibernateMappingXmlConstants.PACKAGE_ATTRIB);//NOI18N
76
        Node n = env.getDocumentContext().getDocRoot().getNode().getAttributes().
77
                getNamedItem(HibernateMappingXmlConstants.PACKAGE_ATTRIB);//NOI18N
78
        String pack = n == null ? null : n.getNodeValue();
76
            if(pack!=null &&  pack.length()>0){
79
            if(pack!=null &&  pack.length()>0){
77
                if(!className0.contains(".")){
80
                if(!className0.contains(".")){
78
                    className0 = pack + "." +className0;
81
                    className0 = pack + "." +className0;
(-)a/hibernate/src/org/netbeans/modules/hibernate/refactoring/HibernateRefactoringUtil.java (-240 / +264 lines)
Lines 62-67 Link Here
62
import javax.lang.model.element.PackageElement;
62
import javax.lang.model.element.PackageElement;
63
import javax.lang.model.element.TypeElement;
63
import javax.lang.model.element.TypeElement;
64
import javax.swing.text.BadLocationException;
64
import javax.swing.text.BadLocationException;
65
import javax.swing.text.Document;
65
import javax.swing.text.Position.Bias;
66
import javax.swing.text.Position.Bias;
66
import org.netbeans.api.java.classpath.ClassPath;
67
import org.netbeans.api.java.classpath.ClassPath;
67
import org.netbeans.api.java.source.CompilationController;
68
import org.netbeans.api.java.source.CompilationController;
Lines 70-89 Link Here
70
import org.netbeans.api.java.source.JavaSource.Phase;
71
import org.netbeans.api.java.source.JavaSource.Phase;
71
import org.netbeans.api.java.source.Task;
72
import org.netbeans.api.java.source.Task;
72
import org.netbeans.api.java.source.TreePathHandle;
73
import org.netbeans.api.java.source.TreePathHandle;
74
import org.netbeans.api.lexer.Token;
75
import org.netbeans.api.lexer.TokenSequence;
73
import org.netbeans.api.project.Project;
76
import org.netbeans.api.project.Project;
77
import org.netbeans.api.xml.lexer.XMLTokenId;
74
import org.netbeans.editor.BaseDocument;
78
import org.netbeans.editor.BaseDocument;
75
import org.netbeans.editor.TokenID;
76
import org.netbeans.editor.TokenItem;
77
import org.netbeans.modules.hibernate.cfg.HibernateCfgXmlConstants;
79
import org.netbeans.modules.hibernate.cfg.HibernateCfgXmlConstants;
78
import org.netbeans.modules.hibernate.editor.HibernateEditorUtil;
80
import org.netbeans.modules.hibernate.editor.HibernateEditorUtil;
79
import org.netbeans.modules.hibernate.mapping.HibernateMappingXmlConstants;
81
import org.netbeans.modules.hibernate.mapping.HibernateMappingXmlConstants;
80
import org.netbeans.modules.hibernate.service.api.HibernateEnvironment;
82
import org.netbeans.modules.hibernate.service.api.HibernateEnvironment;
81
import org.netbeans.modules.refactoring.api.Problem;
83
import org.netbeans.modules.refactoring.api.Problem;
82
import org.netbeans.modules.xml.text.api.XMLDefaultTokenContext;
84
import org.netbeans.modules.xml.text.api.dom.SyntaxElement;
83
import org.netbeans.modules.xml.text.syntax.SyntaxElement;
85
import org.netbeans.modules.xml.text.api.dom.XMLSyntaxSupport;
84
import org.netbeans.modules.xml.text.syntax.XMLSyntaxSupport;
85
import org.netbeans.modules.xml.text.syntax.dom.EmptyTag;
86
import org.netbeans.modules.xml.text.syntax.dom.StartTag;
87
import org.openide.ErrorManager;
86
import org.openide.ErrorManager;
88
import org.openide.cookies.EditorCookie;
87
import org.openide.cookies.EditorCookie;
89
import org.openide.filesystems.FileObject;
88
import org.openide.filesystems.FileObject;
Lines 297-449 Link Here
297
            // Get the document for this file
296
            // Get the document for this file
298
            DataObject dataObject = DataObject.find(mappingFile);
297
            DataObject dataObject = DataObject.find(mappingFile);
299
            EditorCookie result = dataObject.getCookie(EditorCookie.class);
298
            EditorCookie result = dataObject.getCookie(EditorCookie.class);
300
            String mappingPackage = null;
301
            if (result == null) {
299
            if (result == null) {
302
                throw new IllegalStateException("File " + mappingFile + " does not have an EditorCookie.");
300
                throw new IllegalStateException("File " + mappingFile + " does not have an EditorCookie.");
303
            }
301
            }
304
302
305
            CloneableEditorSupport editor = (CloneableEditorSupport) result;
303
            CloneableEditorSupport editor = (CloneableEditorSupport) result;
306
            BaseDocument document = (BaseDocument) editor.openDocument();
304
            Document document = editor.openDocument();
307
            XMLSyntaxSupport syntaxSupport = (XMLSyntaxSupport) document.getSyntaxSupport();
305
            XMLSyntaxSupport syntaxSupport = XMLSyntaxSupport.getSyntaxSupport(document);
306
            if (syntaxSupport == null) {
307
                return foundPlaces;
308
            }
309
            return syntaxSupport.runWithSequence(0, 
310
                    (TokenSequence ts) -> {
311
                        int start = document.getStartPosition().getOffset();
312
                        return getOccurPlacesLocked(syntaxSupport, start,
313
                                editor, ts, searchingForName, searchingPackageName);
314
            });
315
        } catch (BadLocationException | IOException ex) {
316
            ErrorManager.getDefault().notify(org.openide.ErrorManager.INFORMATIONAL, ex);
317
        }
318
        return foundPlaces;
319
    }
320
    
321
    private static List<OccurrenceItem> getOccurPlacesLocked(
322
            XMLSyntaxSupport sup,
323
            int start,
324
            CloneableEditorSupport editor,
325
            TokenSequence seq, 
326
            String searchingForName, boolean searchingPackageName) throws BadLocationException {
327
        List<OccurrenceItem> foundPlaces = new ArrayList<OccurrenceItem>();
328
        String mappingPackage = null;
329
        seq.move(start);
330
        while (seq.moveNext()) {
331
            Token<XMLTokenId> item = seq.token();
332
            XMLTokenId tokenId = item.id();
308
333
309
            int start = document.getStartPosition().getOffset();
334
            if (tokenId == XMLTokenId.TAG) {
310
            TokenItem item = syntaxSupport.getTokenChain(start, Math.min(start + 1, document.getLength()));
311
            if (item == null) {
312
                return null;
313
            }
314
335
315
            while (item != null) {
336
                SyntaxElement element = sup.getElementChain(seq.offset() + 1);
316
                TokenID tokenId = item.getTokenID();
337
                String[] attributeValues = null; // Multiple attributes can have class name as values
338
                boolean pkgValue = false; // To indicate the attributeValues are Java package, not full class name
339
                if (sup.isStartTag(element) || sup.isEmptyTag(element)) {
317
340
318
                if (tokenId == XMLDefaultTokenContext.TAG) {
341
                    Node theNode = (Node) element;
319
342
                    String nodeName = theNode.getNodeName();
320
                    SyntaxElement element = syntaxSupport.getElementChain(item.getOffset() + 1);
343
                    String itemImage = item.text().toString();
321
                    String[] attributeValues = null; // Multiple attributes can have class name as values
344
                    int itemOffset = seq.offset();
322
                    boolean pkgValue = false; // To indicate the attributeValues are Java package, not full class name
345
                    
323
                    if (element instanceof StartTag || element instanceof EmptyTag) {
346
                    if (nodeName.equalsIgnoreCase(HibernateMappingXmlConstants.MAPPING_TAG) &&
324
347
                            itemImage.contains(HibernateMappingXmlConstants.MAPPING_TAG)) {
325
                        Node theNode = (Node) element;
348
                        if(searchingPackageName) {
326
                        String nodeName = theNode.getNodeName();
327
                        String itemImage = item.getImage();
328
329
                        if (nodeName.equalsIgnoreCase(HibernateMappingXmlConstants.MAPPING_TAG) &&
330
                                itemImage.contains(HibernateMappingXmlConstants.MAPPING_TAG)) {
331
                            if(searchingPackageName) {
332
                                // <class> element
333
                                attributeValues = new String[1];
334
                                attributeValues[0] = getAttributeValue(theNode, HibernateMappingXmlConstants.PACKAGE_ATTRIB);
335
                                pkgValue = true;
336
                            } else {
337
                                mappingPackage = getAttributeValue(theNode, HibernateMappingXmlConstants.PACKAGE_ATTRIB);
338
                            }
339
                        } // Search the element/attrubutes that take class names
340
                        else if (nodeName.equalsIgnoreCase(HibernateMappingXmlConstants.CLASS_TAG) &&
341
                                itemImage.contains(HibernateMappingXmlConstants.CLASS_TAG)) {
342
                            // <class> element
349
                            // <class> element
343
                            attributeValues = new String[1];
350
                            attributeValues = new String[1];
344
                            attributeValues[0] = getAttributeValue(theNode, HibernateMappingXmlConstants.NAME_ATTRIB);
351
                            attributeValues[0] = getAttributeValue(theNode, HibernateMappingXmlConstants.PACKAGE_ATTRIB);
345
                        } else if (nodeName.equalsIgnoreCase(HibernateMappingXmlConstants.ONE_TO_MANY_TAG) &&
352
                            pkgValue = true;
346
                                itemImage.contains(HibernateMappingXmlConstants.ONE_TO_MANY_TAG)) {
353
                        } else {
347
                            // <one-to-many> element
354
                            mappingPackage = getAttributeValue(theNode, HibernateMappingXmlConstants.PACKAGE_ATTRIB);
348
                            attributeValues = new String[1];
349
                            attributeValues[0] = getAttributeValue(theNode, HibernateMappingXmlConstants.CLASS_ATTRIB);
350
                        } else if (nodeName.equalsIgnoreCase(HibernateMappingXmlConstants.COMPOSITE_ID_TAG) &&
351
                                itemImage.contains(HibernateMappingXmlConstants.COMPOSITE_ID_TAG)) {
352
                            // <composite-id> element
353
                            attributeValues = new String[1];
354
                            attributeValues[0] = getAttributeValue(theNode, HibernateMappingXmlConstants.CLASS_ATTRIB);
355
                        } else if (nodeName.equalsIgnoreCase(HibernateMappingXmlConstants.KEY_MANY_TO_ONE_TAG) &&
356
                                itemImage.contains(HibernateMappingXmlConstants.KEY_MANY_TO_ONE_TAG)) {
357
                            // <key-many-to-one> element
358
                            attributeValues = new String[1];
359
                            attributeValues[0] = getAttributeValue(theNode, HibernateMappingXmlConstants.CLASS_ATTRIB);
360
                        } else if (nodeName.equalsIgnoreCase(HibernateMappingXmlConstants.MANY_TO_ONE_TAG) &&
361
                                itemImage.contains(HibernateMappingXmlConstants.MANY_TO_ONE_TAG)) {
362
                            // <many-to-one> element
363
                            attributeValues = new String[1];
364
                            attributeValues[0] = getAttributeValue(theNode, HibernateMappingXmlConstants.CLASS_ATTRIB);
365
                        } else if (nodeName.equalsIgnoreCase(HibernateMappingXmlConstants.ONE_TO_ONE_TAG) &&
366
                                itemImage.contains(HibernateMappingXmlConstants.ONE_TO_ONE_TAG)) {
367
                            // <one-to-one> element
368
                            attributeValues = new String[1];
369
                            attributeValues[0] = getAttributeValue(theNode, HibernateMappingXmlConstants.CLASS_ATTRIB);
370
                        } else if (nodeName.equalsIgnoreCase(HibernateMappingXmlConstants.COMPONENT_TAG) &&
371
                                itemImage.contains(HibernateMappingXmlConstants.COMPONENT_TAG)) {
372
                            // <component> element
373
                            attributeValues = new String[1];
374
                            attributeValues[0] = getAttributeValue(theNode, HibernateMappingXmlConstants.CLASS_ATTRIB);
375
                        } else if (nodeName.equalsIgnoreCase(HibernateMappingXmlConstants.SUBCLASS_TAG) &&
376
                                itemImage.contains(HibernateMappingXmlConstants.SUBCLASS_TAG)) {
377
                            // <subclass> element
378
                            attributeValues = new String[2];
379
                            attributeValues[0] = getAttributeValue(theNode, HibernateMappingXmlConstants.NAME_ATTRIB);
380
                            attributeValues[1] = getAttributeValue(theNode, HibernateMappingXmlConstants.EXTENDS_ATTRIB);
381
                        } else if (nodeName.equalsIgnoreCase(HibernateMappingXmlConstants.JOINED_SUBCLASS_TAG) &&
382
                                itemImage.contains(HibernateMappingXmlConstants.JOINED_SUBCLASS_TAG)) {
383
                            // <joined-subclass> element
384
                            attributeValues = new String[3];
385
                            attributeValues[0] = getAttributeValue(theNode, HibernateMappingXmlConstants.NAME_ATTRIB);
386
                            attributeValues[1] = getAttributeValue(theNode, HibernateMappingXmlConstants.EXTENDS_ATTRIB);
387
                            attributeValues[2] = getAttributeValue(theNode, HibernateMappingXmlConstants.PERSISTER_ATTRIB);
388
                        } else if (nodeName.equalsIgnoreCase(HibernateMappingXmlConstants.UNION_SUBCLASS_TAG) &&
389
                                itemImage.contains(HibernateMappingXmlConstants.UNION_SUBCLASS_TAG)) {
390
                            // <union-subclass> element
391
                            attributeValues = new String[3];
392
                            attributeValues[0] = getAttributeValue(theNode, HibernateMappingXmlConstants.NAME_ATTRIB);
393
                            attributeValues[1] = getAttributeValue(theNode, HibernateMappingXmlConstants.EXTENDS_ATTRIB);
394
                            attributeValues[2] = getAttributeValue(theNode, HibernateMappingXmlConstants.PERSISTER_ATTRIB);
395
                        } else if (nodeName.equalsIgnoreCase(HibernateMappingXmlConstants.IMPORT_TAG) &&
396
                                itemImage.contains(HibernateMappingXmlConstants.IMPORT_TAG)) {
397
                            // <import> element
398
                            attributeValues = new String[1];
399
                            attributeValues[0] = getAttributeValue(theNode, HibernateMappingXmlConstants.CLASS_ATTRIB);
400
                        } else if (nodeName.equalsIgnoreCase(HibernateMappingXmlConstants.MANY_TO_MANY_TAG) &&
401
                                itemImage.contains(HibernateMappingXmlConstants.MANY_TO_MANY_TAG)) {
402
                            // <many-to-many> element
403
                            attributeValues = new String[1];
404
                            attributeValues[0] = getAttributeValue(theNode, HibernateMappingXmlConstants.CLASS_ATTRIB);
405
                        } else if(nodeName.equalsIgnoreCase("property") &&//NOI18N
406
                                itemImage.contains("property")) {//NOI18N
407
                            attributeValues = new String[1];
408
                            attributeValues[0] = getAttributeValue(theNode, HibernateMappingXmlConstants.TYPE_ATTRIB);
409
                        }
355
                        }
410
                        if (attributeValues != null) {
356
                    } // Search the element/attrubutes that take class names
411
                            for (int i = 0; i < attributeValues.length; i++) {
357
                    else if (nodeName.equalsIgnoreCase(HibernateMappingXmlConstants.CLASS_TAG) &&
358
                            itemImage.contains(HibernateMappingXmlConstants.CLASS_TAG)) {
359
                        // <class> element
360
                        attributeValues = new String[1];
361
                        attributeValues[0] = getAttributeValue(theNode, HibernateMappingXmlConstants.NAME_ATTRIB);
362
                    } else if (nodeName.equalsIgnoreCase(HibernateMappingXmlConstants.ONE_TO_MANY_TAG) &&
363
                            itemImage.contains(HibernateMappingXmlConstants.ONE_TO_MANY_TAG)) {
364
                        // <one-to-many> element
365
                        attributeValues = new String[1];
366
                        attributeValues[0] = getAttributeValue(theNode, HibernateMappingXmlConstants.CLASS_ATTRIB);
367
                    } else if (nodeName.equalsIgnoreCase(HibernateMappingXmlConstants.COMPOSITE_ID_TAG) &&
368
                            itemImage.contains(HibernateMappingXmlConstants.COMPOSITE_ID_TAG)) {
369
                        // <composite-id> element
370
                        attributeValues = new String[1];
371
                        attributeValues[0] = getAttributeValue(theNode, HibernateMappingXmlConstants.CLASS_ATTRIB);
372
                    } else if (nodeName.equalsIgnoreCase(HibernateMappingXmlConstants.KEY_MANY_TO_ONE_TAG) &&
373
                            itemImage.contains(HibernateMappingXmlConstants.KEY_MANY_TO_ONE_TAG)) {
374
                        // <key-many-to-one> element
375
                        attributeValues = new String[1];
376
                        attributeValues[0] = getAttributeValue(theNode, HibernateMappingXmlConstants.CLASS_ATTRIB);
377
                    } else if (nodeName.equalsIgnoreCase(HibernateMappingXmlConstants.MANY_TO_ONE_TAG) &&
378
                            itemImage.contains(HibernateMappingXmlConstants.MANY_TO_ONE_TAG)) {
379
                        // <many-to-one> element
380
                        attributeValues = new String[1];
381
                        attributeValues[0] = getAttributeValue(theNode, HibernateMappingXmlConstants.CLASS_ATTRIB);
382
                    } else if (nodeName.equalsIgnoreCase(HibernateMappingXmlConstants.ONE_TO_ONE_TAG) &&
383
                            itemImage.contains(HibernateMappingXmlConstants.ONE_TO_ONE_TAG)) {
384
                        // <one-to-one> element
385
                        attributeValues = new String[1];
386
                        attributeValues[0] = getAttributeValue(theNode, HibernateMappingXmlConstants.CLASS_ATTRIB);
387
                    } else if (nodeName.equalsIgnoreCase(HibernateMappingXmlConstants.COMPONENT_TAG) &&
388
                            itemImage.contains(HibernateMappingXmlConstants.COMPONENT_TAG)) {
389
                        // <component> element
390
                        attributeValues = new String[1];
391
                        attributeValues[0] = getAttributeValue(theNode, HibernateMappingXmlConstants.CLASS_ATTRIB);
392
                    } else if (nodeName.equalsIgnoreCase(HibernateMappingXmlConstants.SUBCLASS_TAG) &&
393
                            itemImage.contains(HibernateMappingXmlConstants.SUBCLASS_TAG)) {
394
                        // <subclass> element
395
                        attributeValues = new String[2];
396
                        attributeValues[0] = getAttributeValue(theNode, HibernateMappingXmlConstants.NAME_ATTRIB);
397
                        attributeValues[1] = getAttributeValue(theNode, HibernateMappingXmlConstants.EXTENDS_ATTRIB);
398
                    } else if (nodeName.equalsIgnoreCase(HibernateMappingXmlConstants.JOINED_SUBCLASS_TAG) &&
399
                            itemImage.contains(HibernateMappingXmlConstants.JOINED_SUBCLASS_TAG)) {
400
                        // <joined-subclass> element
401
                        attributeValues = new String[3];
402
                        attributeValues[0] = getAttributeValue(theNode, HibernateMappingXmlConstants.NAME_ATTRIB);
403
                        attributeValues[1] = getAttributeValue(theNode, HibernateMappingXmlConstants.EXTENDS_ATTRIB);
404
                        attributeValues[2] = getAttributeValue(theNode, HibernateMappingXmlConstants.PERSISTER_ATTRIB);
405
                    } else if (nodeName.equalsIgnoreCase(HibernateMappingXmlConstants.UNION_SUBCLASS_TAG) &&
406
                            itemImage.contains(HibernateMappingXmlConstants.UNION_SUBCLASS_TAG)) {
407
                        // <union-subclass> element
408
                        attributeValues = new String[3];
409
                        attributeValues[0] = getAttributeValue(theNode, HibernateMappingXmlConstants.NAME_ATTRIB);
410
                        attributeValues[1] = getAttributeValue(theNode, HibernateMappingXmlConstants.EXTENDS_ATTRIB);
411
                        attributeValues[2] = getAttributeValue(theNode, HibernateMappingXmlConstants.PERSISTER_ATTRIB);
412
                    } else if (nodeName.equalsIgnoreCase(HibernateMappingXmlConstants.IMPORT_TAG) &&
413
                            itemImage.contains(HibernateMappingXmlConstants.IMPORT_TAG)) {
414
                        // <import> element
415
                        attributeValues = new String[1];
416
                        attributeValues[0] = getAttributeValue(theNode, HibernateMappingXmlConstants.CLASS_ATTRIB);
417
                    } else if (nodeName.equalsIgnoreCase(HibernateMappingXmlConstants.MANY_TO_MANY_TAG) &&
418
                            itemImage.contains(HibernateMappingXmlConstants.MANY_TO_MANY_TAG)) {
419
                        // <many-to-many> element
420
                        attributeValues = new String[1];
421
                        attributeValues[0] = getAttributeValue(theNode, HibernateMappingXmlConstants.CLASS_ATTRIB);
422
                    } else if(nodeName.equalsIgnoreCase("property") &&//NOI18N
423
                            itemImage.contains("property")) {//NOI18N
424
                        attributeValues = new String[1];
425
                        attributeValues[0] = getAttributeValue(theNode, HibernateMappingXmlConstants.TYPE_ATTRIB);
426
                    }
427
                    if (attributeValues != null) {
428
                        for (int i = 0; i < attributeValues.length; i++) {
412
429
413
                                String text = document.getText(item.getOffset(), element.getElementLength());
430
                            String text = sup.getDocument().getText(itemOffset, element.getElementLength());
414
431
415
                                String value = attributeValues[i];
432
                            String value = attributeValues[i];
416
                                if (searchingPackageName && !pkgValue) {
433
                            if (searchingPackageName && !pkgValue) {
417
                                    value = getPackageName(value);
434
                                value = getPackageName(value);
418
                                }
435
                            }
419
436
420
                                if (value != null && (value.equals(searchingForName) || (mappingPackage!=null && mappingPackage.length()>0 && value.indexOf('.')==-1 && (mappingPackage + "." + value).equals(searchingForName)))) {
437
                            if (value != null && (value.equals(searchingForName) || (mappingPackage!=null && mappingPackage.length()>0 && value.indexOf('.')==-1 && (mappingPackage + "." + value).equals(searchingForName)))) {
421
438
422
                                    // TODO: can not just do indexof. It does not work correctly if there are multiple
439
                                // TODO: can not just do indexof. It does not work correctly if there are multiple
423
                                    // attributes have the same class searchingForName. Though, it does not make sense to have such case.
440
                                // attributes have the same class searchingForName. Though, it does not make sense to have such case.
424
441
425
                                    if (text.indexOf(value) != -1) {
442
                                if (text.indexOf(value) != -1) {
426
                                        int startOffset = item.getOffset() + text.indexOf(value);
443
                                    int startOffset = itemOffset + text.indexOf(value);
427
                                        int endOffset = startOffset + value.length();
444
                                    int endOffset = startOffset + value.length();
428
445
429
                                        PositionBounds loc = new PositionBounds(editor.createPositionRef(startOffset, Bias.Forward),
446
                                    PositionBounds loc = new PositionBounds(editor.createPositionRef(startOffset, Bias.Forward),
430
                                                editor.createPositionRef(endOffset, Bias.Forward));
447
                                            editor.createPositionRef(endOffset, Bias.Forward));
431
448
432
                                        foundPlaces.add(new OccurrenceItem(loc, text, value));
449
                                    foundPlaces.add(new OccurrenceItem(loc, text, value));
433
                                    }
434
                                }
450
                                }
435
                            }
451
                            }
436
                        }
452
                        }
437
                    }
453
                    }
438
                }
454
                }
439
                item = item.getNext();
440
            }
455
            }
441
        } catch (IOException ex) {
442
            ErrorManager.getDefault().notify(org.openide.ErrorManager.INFORMATIONAL, ex);
443
        } catch (BadLocationException ex) {
444
            ErrorManager.getDefault().notify(org.openide.ErrorManager.INFORMATIONAL, ex);
445
        }
456
        }
446
447
        return foundPlaces;
457
        return foundPlaces;
448
    }
458
    }
449
459
Lines 458-545 Link Here
458
            }
468
            }
459
469
460
            CloneableEditorSupport editor = (CloneableEditorSupport) result;
470
            CloneableEditorSupport editor = (CloneableEditorSupport) result;
461
            BaseDocument document = (BaseDocument) editor.openDocument();
471
            Document document = editor.openDocument();
462
            XMLSyntaxSupport syntaxSupport = (XMLSyntaxSupport) document.getSyntaxSupport();
472
            XMLSyntaxSupport syntaxSupport = XMLSyntaxSupport.getSyntaxSupport(document);
473
            if (syntaxSupport == null) {
474
                return foundPlaces;
475
            }
476
            foundPlaces = syntaxSupport.runWithSequence(0, 
477
                    (TokenSequence ts) -> {
478
                int start = document.getStartPosition().getOffset();
479
                return getJavaFieldOccurPlacesLocked(syntaxSupport, ts, start, editor, className, fieldName);
480
            });
481
        } catch (IOException  | BadLocationException ex) {
482
            ErrorManager.getDefault().notify(org.openide.ErrorManager.INFORMATIONAL, ex);
483
        }
484
        return foundPlaces;
485
    }
463
486
464
            int start = document.getStartPosition().getOffset();
465
            TokenItem item = syntaxSupport.getTokenChain(start, Math.min(start + 1, document.getLength()));
466
            if (item == null) {
467
                return null;
468
            }
469
487
470
            String text = null;
488
    private static List<OccurrenceItem> getJavaFieldOccurPlacesLocked(
471
            while (item != null) {
489
            XMLSyntaxSupport sup, TokenSequence seq, int start, 
472
                TokenID tokenId = item.getTokenID();
490
            CloneableEditorSupport editor, String className, String fieldName) throws BadLocationException {
491
        List<OccurrenceItem> foundPlaces = new ArrayList<OccurrenceItem>();
492
        seq.move(start);
493
        String text = null;
494
        while (seq.moveNext()) {
495
            Token<XMLTokenId> item = seq.token();
496
            XMLTokenId tokenId = item.id();
473
497
474
                if (tokenId == XMLDefaultTokenContext.TAG) {
498
            if (tokenId == XMLTokenId.TAG) {
475
                    // Did we find the <class> element
499
                // Did we find the <class> element
476
500
477
                    SyntaxElement element = syntaxSupport.getElementChain(item.getOffset() + 1);
501
                SyntaxElement element = sup.getElementChain(seq.offset() + 1);
478
                    String nameAttribValue = null;
502
                String nameAttribValue = null;
479
                    if (element instanceof StartTag || element instanceof EmptyTag) {
503
                if (sup.isStartTag(element) || sup.isEmptyTag(element)) {
480
504
481
                        Node theNode = (Node) element;
505
                    Node theNode = (Node) element;
482
                        String nodeName = theNode.getNodeName();
506
                    String nodeName = theNode.getNodeName();
483
                        String itemImage = item.getImage();
507
                    String itemImage = item.text().toString();
484
508
485
                        if ((nodeName.equalsIgnoreCase(HibernateMappingXmlConstants.PROPERTY_TAG) &&
509
                    if ((nodeName.equalsIgnoreCase(HibernateMappingXmlConstants.PROPERTY_TAG) &&
486
                                itemImage.contains(HibernateMappingXmlConstants.PROPERTY_TAG)) ||
510
                            itemImage.contains(HibernateMappingXmlConstants.PROPERTY_TAG)) ||
487
                                (nodeName.equalsIgnoreCase(HibernateMappingXmlConstants.ID_TAG) &&
511
                            (nodeName.equalsIgnoreCase(HibernateMappingXmlConstants.ID_TAG) &&
488
                                itemImage.contains(HibernateMappingXmlConstants.ID_TAG)) ||
512
                            itemImage.contains(HibernateMappingXmlConstants.ID_TAG)) ||
489
                                (nodeName.equalsIgnoreCase(HibernateMappingXmlConstants.SET_TAG) &&
513
                            (nodeName.equalsIgnoreCase(HibernateMappingXmlConstants.SET_TAG) &&
490
                                itemImage.contains(HibernateMappingXmlConstants.SET_TAG)) ||
514
                            itemImage.contains(HibernateMappingXmlConstants.SET_TAG)) ||
491
                                (nodeName.equalsIgnoreCase(HibernateMappingXmlConstants.COMPOSITE_ID_TAG) &&
515
                            (nodeName.equalsIgnoreCase(HibernateMappingXmlConstants.COMPOSITE_ID_TAG) &&
492
                                itemImage.contains(HibernateMappingXmlConstants.COMPOSITE_ID_TAG)) ||
516
                            itemImage.contains(HibernateMappingXmlConstants.COMPOSITE_ID_TAG)) ||
493
                                (nodeName.equalsIgnoreCase(HibernateMappingXmlConstants.KEY_PROPERTY_TAG) &&
517
                            (nodeName.equalsIgnoreCase(HibernateMappingXmlConstants.KEY_PROPERTY_TAG) &&
494
                                itemImage.contains(HibernateMappingXmlConstants.KEY_PROPERTY_TAG)) ||
518
                            itemImage.contains(HibernateMappingXmlConstants.KEY_PROPERTY_TAG)) ||
495
                                (nodeName.equalsIgnoreCase(HibernateMappingXmlConstants.KEY_MANY_TO_ONE_TAG) &&
519
                            (nodeName.equalsIgnoreCase(HibernateMappingXmlConstants.KEY_MANY_TO_ONE_TAG) &&
496
                                itemImage.contains(HibernateMappingXmlConstants.KEY_MANY_TO_ONE_TAG)) ||
520
                            itemImage.contains(HibernateMappingXmlConstants.KEY_MANY_TO_ONE_TAG)) ||
497
                                (nodeName.equalsIgnoreCase(HibernateMappingXmlConstants.VERSION_TAG) &&
521
                            (nodeName.equalsIgnoreCase(HibernateMappingXmlConstants.VERSION_TAG) &&
498
                                itemImage.contains(HibernateMappingXmlConstants.VERSION_TAG)) ||
522
                            itemImage.contains(HibernateMappingXmlConstants.VERSION_TAG)) ||
499
                                (nodeName.equalsIgnoreCase(HibernateMappingXmlConstants.TIMESTAMP_TAG) &&
523
                            (nodeName.equalsIgnoreCase(HibernateMappingXmlConstants.TIMESTAMP_TAG) &&
500
                                itemImage.contains(HibernateMappingXmlConstants.TIMESTAMP_TAG)) ||
524
                            itemImage.contains(HibernateMappingXmlConstants.TIMESTAMP_TAG)) ||
501
                                (nodeName.equalsIgnoreCase(HibernateMappingXmlConstants.MANY_TO_ONE_TAG) &&
525
                            (nodeName.equalsIgnoreCase(HibernateMappingXmlConstants.MANY_TO_ONE_TAG) &&
502
                                itemImage.contains(HibernateMappingXmlConstants.MANY_TO_ONE_TAG)) ||
526
                            itemImage.contains(HibernateMappingXmlConstants.MANY_TO_ONE_TAG)) ||
503
                                (nodeName.equalsIgnoreCase(HibernateMappingXmlConstants.ONE_TO_ONE_TAG) &&
527
                            (nodeName.equalsIgnoreCase(HibernateMappingXmlConstants.ONE_TO_ONE_TAG) &&
504
                                itemImage.contains(HibernateMappingXmlConstants.ONE_TO_ONE_TAG)) ||
528
                            itemImage.contains(HibernateMappingXmlConstants.ONE_TO_ONE_TAG)) ||
505
                                (nodeName.equalsIgnoreCase(HibernateMappingXmlConstants.COMPONENT_TAG) &&
529
                            (nodeName.equalsIgnoreCase(HibernateMappingXmlConstants.COMPONENT_TAG) &&
506
                                itemImage.contains(HibernateMappingXmlConstants.COMPONENT_TAG)) ||
530
                            itemImage.contains(HibernateMappingXmlConstants.COMPONENT_TAG)) ||
507
                                (nodeName.equalsIgnoreCase(HibernateMappingXmlConstants.ANY_TAG) &&
531
                            (nodeName.equalsIgnoreCase(HibernateMappingXmlConstants.ANY_TAG) &&
508
                                itemImage.contains(HibernateMappingXmlConstants.ANY_TAG)) ||
532
                            itemImage.contains(HibernateMappingXmlConstants.ANY_TAG)) ||
509
                                (nodeName.equalsIgnoreCase(HibernateMappingXmlConstants.MAP_TAG) &&
533
                            (nodeName.equalsIgnoreCase(HibernateMappingXmlConstants.MAP_TAG) &&
510
                                itemImage.contains(HibernateMappingXmlConstants.MAP_TAG)) ||
534
                            itemImage.contains(HibernateMappingXmlConstants.MAP_TAG)) ||
511
                                (nodeName.equalsIgnoreCase(HibernateMappingXmlConstants.LIST_TAG) &&
535
                            (nodeName.equalsIgnoreCase(HibernateMappingXmlConstants.LIST_TAG) &&
512
                                itemImage.contains(HibernateMappingXmlConstants.LIST_TAG))) {
536
                            itemImage.contains(HibernateMappingXmlConstants.LIST_TAG))) {
513
537
514
                            nameAttribValue = getAttributeValue(theNode, HibernateMappingXmlConstants.NAME_ATTRIB);
538
                        nameAttribValue = getAttributeValue(theNode, HibernateMappingXmlConstants.NAME_ATTRIB);
515
539
516
                            if (nameAttribValue != null && nameAttribValue.equals(fieldName)) {
540
                        if (nameAttribValue != null && nameAttribValue.equals(fieldName)) {
517
541
518
                                // Check class name
542
                            // Check class name
519
                                if (HibernateEditorUtil.getClassName(theNode).equals(className)) {
543
                            if (HibernateEditorUtil.getClassName(theNode).equals(className)) {
520
                                    text = document.getText(item.getOffset(), element.getElementLength());
544
                                text = sup.getDocument().getText(seq.offset(), element.getElementLength());
521
545
522
                                    // find the offset for the field name
546
                                // find the offset for the field name
523
                                    int index = text.indexOf(fieldName);
547
                                int index = text.indexOf(fieldName);
524
                                    int startOffset = item.getOffset() + index;
548
                                int startOffset = seq.offset() + index;
525
                                    int endOffset = startOffset + fieldName.length();
549
                                int endOffset = startOffset + fieldName.length();
526
                                    PositionBounds loc = new PositionBounds(editor.createPositionRef(startOffset, Bias.Forward),
550
                                PositionBounds loc = new PositionBounds(
527
                                            editor.createPositionRef(endOffset, Bias.Forward));
551
                                        editor.createPositionRef(startOffset, Bias.Forward),
552
                                        editor.createPositionRef(endOffset, Bias.Forward));
528
553
529
                                    foundPlaces.add(new OccurrenceItem(loc, text, fieldName));
554
                                foundPlaces.add(new OccurrenceItem(loc, text, fieldName));
530
                                }
531
                            }
555
                            }
532
                        }
556
                        }
533
                    }
557
                    }
534
                }
558
                }
535
                item = item.getNext();
536
            }
559
            }
537
        } catch (IOException ex) {
538
            ErrorManager.getDefault().notify(org.openide.ErrorManager.INFORMATIONAL, ex);
539
        } catch (BadLocationException ex) {
540
            ErrorManager.getDefault().notify(org.openide.ErrorManager.INFORMATIONAL, ex);
541
        }
560
        }
542
543
        return foundPlaces;
561
        return foundPlaces;
544
    }
562
    }
545
    
563
    
Lines 563-627 Link Here
563
581
564
            CloneableEditorSupport editor = (CloneableEditorSupport) result;
582
            CloneableEditorSupport editor = (CloneableEditorSupport) result;
565
            BaseDocument document = (BaseDocument) editor.openDocument();
583
            BaseDocument document = (BaseDocument) editor.openDocument();
566
            XMLSyntaxSupport syntaxSupport = (XMLSyntaxSupport) document.getSyntaxSupport();
584
            XMLSyntaxSupport syntaxSupport = XMLSyntaxSupport.getSyntaxSupport(document);
585
            if (syntaxSupport == null) {
586
                return foundPlaces;
587
            }
588
            return syntaxSupport.runWithSequence(0, 
589
                (TokenSequence ts) -> {
590
                    int start = document.getStartPosition().getOffset();
591
                    return getMappingResourceOccurPlacesLocked(syntaxSupport, ts, start, editor, resourceName, searchingPathOnly);
592
            });
593
        } catch (IOException | BadLocationException ex) {
594
            ErrorManager.getDefault().notify(org.openide.ErrorManager.INFORMATIONAL, ex);
595
        }
596
        return foundPlaces;
597
    }
567
598
568
            int start = document.getStartPosition().getOffset();
599
    private static List<OccurrenceItem> getMappingResourceOccurPlacesLocked(
569
            TokenItem item = syntaxSupport.getTokenChain(start, Math.min(start + 1, document.getLength()));
600
            XMLSyntaxSupport sup, TokenSequence seq, int start, CloneableEditorSupport editor, 
570
            if (item == null) {
601
            String resourceName, boolean searchingPathOnly) throws BadLocationException {
571
                return null;
602
        List<OccurrenceItem> foundPlaces = new ArrayList<OccurrenceItem>();
572
            }
603
        seq.move(start);
604
        String text = null;
605
        while (seq.moveNext()) {
606
            Token<XMLTokenId> item = seq.token();
607
            XMLTokenId tokenId = item.id();
573
608
574
            String text = null;
609
            if (tokenId == XMLTokenId.TAG) {
575
            while (item != null) {
610
                // Did we find the <class> element
576
                TokenID tokenId = item.getTokenID();
577
611
578
                if (tokenId == XMLDefaultTokenContext.TAG) {
612
                SyntaxElement element = sup.getElementChain(seq.offset() + 1);
579
                    // Did we find the <class> element
613
                String mappingResourceAttribValue = null;
614
                if (sup.isStartTag(element) || sup.isEmptyTag(element)) {
580
615
581
                    SyntaxElement element = syntaxSupport.getElementChain(item.getOffset() + 1);
616
                    Node theNode = (Node) element;
582
                    String mappingResourceAttribValue = null;
617
                    String nodeName = theNode.getNodeName();
583
                    if (element instanceof StartTag || element instanceof EmptyTag) {
618
                    String itemImage = item.text().toString();
584
619
585
                        Node theNode = (Node) element;
620
                    if(nodeName.equalsIgnoreCase(HibernateCfgXmlConstants.MAPPING_TAG) && 
586
                        String nodeName = theNode.getNodeName();
621
                            itemImage.contains(HibernateCfgXmlConstants.MAPPING_TAG)){ 
587
                        String itemImage = item.getImage();
588
622
589
                        if(nodeName.equalsIgnoreCase(HibernateCfgXmlConstants.MAPPING_TAG) && 
623
                        mappingResourceAttribValue = getAttributeValue(theNode, HibernateCfgXmlConstants.RESOURCE_ATTRIB);
590
                                itemImage.contains(HibernateCfgXmlConstants.MAPPING_TAG)){ 
624
                        if(mappingResourceAttribValue != null) {
625
                            if(searchingPathOnly) {
626
                                int lastIndex = mappingResourceAttribValue.lastIndexOf('/');
627
                                if (lastIndex > -1) {
628
                                    mappingResourceAttribValue = mappingResourceAttribValue.substring(0, lastIndex);
629
                                } else {
630
                                    mappingResourceAttribValue = "";
631
                                }
632
                            }
633
                            if (mappingResourceAttribValue.equals(resourceName)) {
634
                                text = sup.getDocument().getText(seq.offset(), element.getElementLength());
591
635
592
                            mappingResourceAttribValue = getAttributeValue(theNode, HibernateCfgXmlConstants.RESOURCE_ATTRIB);
636
                                // find the offset for the field name
593
                            if(mappingResourceAttribValue != null) {
637
                                int index = text.indexOf(resourceName);
594
                                if(searchingPathOnly) {
638
                                int startOffset = seq.offset() + index;
595
                                    int lastIndex = mappingResourceAttribValue.lastIndexOf('/');
639
                                int endOffset = startOffset + resourceName.length();
596
                                    if (lastIndex > -1) {
640
                                PositionBounds loc = new PositionBounds(editor.createPositionRef(startOffset, Bias.Forward),
597
                                        mappingResourceAttribValue = mappingResourceAttribValue.substring(0, lastIndex);
641
                                        editor.createPositionRef(endOffset, Bias.Forward));
598
                                    } else {
642
                                foundPlaces.add(new OccurrenceItem(loc, text, resourceName));
599
                                        mappingResourceAttribValue = "";
600
                                    }
601
                                }
602
                                if (mappingResourceAttribValue.equals(resourceName)) {
603
                                    text = document.getText(item.getOffset(), element.getElementLength());
604
605
                                    // find the offset for the field name
606
                                    int index = text.indexOf(resourceName);
607
                                    int startOffset = item.getOffset() + index;
608
                                    int endOffset = startOffset + resourceName.length();
609
                                    PositionBounds loc = new PositionBounds(editor.createPositionRef(startOffset, Bias.Forward),
610
                                            editor.createPositionRef(endOffset, Bias.Forward));
611
                                    foundPlaces.add(new OccurrenceItem(loc, text, resourceName));
612
                                }
613
                            }
643
                            }
614
                        }
644
                        }
615
                    }
645
                    }
616
                }
646
                }
617
                item = item.getNext();
618
            }
647
            }
619
        } catch (IOException ex) {
620
            ErrorManager.getDefault().notify(org.openide.ErrorManager.INFORMATIONAL, ex);
621
        } catch (BadLocationException ex) {
622
            ErrorManager.getDefault().notify(org.openide.ErrorManager.INFORMATIONAL, ex);
623
        }
648
        }
624
625
        return foundPlaces;
649
        return foundPlaces;
626
    }
650
    }
627
651
(-)a/j2ee.persistence/nbproject/project.properties (-2 / +2 lines)
Lines 40-47 Link Here
40
# Version 2 license, then the option applies only if the new code is
40
# Version 2 license, then the option applies only if the new code is
41
# made subject to such option by the copyright holder.
41
# made subject to such option by the copyright holder.
42
42
43
javac.source=1.7
43
javac.source=1.8
44
spec.version.base=1.52.0
44
spec.version.base=1.53.0
45
45
46
test.unit.run.cp.extra=${j2eeserver.dir}/modules/ext/jsr88javax.jar:${j2ee.persistence.dir}/modules/ext/eclipselink/eclipselink.jar:${j2ee.persistence.dir}/modules/ext/eclipselink/javax.persistence_2.1.0.v201304241213.jar:${masterfs.dir}/modules/org-netbeans-modules-masterfs.jar
46
test.unit.run.cp.extra=${j2eeserver.dir}/modules/ext/jsr88javax.jar:${j2ee.persistence.dir}/modules/ext/eclipselink/eclipselink.jar:${j2ee.persistence.dir}/modules/ext/eclipselink/javax.persistence_2.1.0.v201304241213.jar:${masterfs.dir}/modules/org-netbeans-modules-masterfs.jar
47
47
(-)a/j2ee.persistence/nbproject/project.xml (-1 / +1 lines)
Lines 463-469 Link Here
463
                    <compile-dependency/>
463
                    <compile-dependency/>
464
                    <run-dependency>
464
                    <run-dependency>
465
                        <release-version>2</release-version>
465
                        <release-version>2</release-version>
466
                        <specification-version>1.30</specification-version>
466
                        <specification-version>1.60</specification-version>
467
                    </run-dependency>
467
                    </run-dependency>
468
                </dependency>
468
                </dependency>
469
                <dependency>
469
                <dependency>
(-)a/j2ee.persistence/src/org/netbeans/modules/j2ee/persistence/editor/CompletionContext.java (-69 / +114 lines)
Lines 48-63 Link Here
48
import java.util.List;
48
import java.util.List;
49
import java.util.logging.Level;
49
import java.util.logging.Level;
50
import java.util.logging.Logger;
50
import java.util.logging.Logger;
51
import javax.swing.text.BadLocationException;
51
import javax.swing.text.Document;
52
import javax.swing.text.Document;
52
import org.netbeans.editor.BaseDocument;
53
import org.netbeans.api.lexer.Token;
53
import org.netbeans.editor.TokenItem;
54
import org.netbeans.api.lexer.TokenSequence;
54
import org.netbeans.modules.xml.text.api.XMLDefaultTokenContext;
55
import org.netbeans.api.xml.lexer.XMLTokenId;
55
import org.netbeans.modules.xml.text.syntax.SyntaxElement;
56
import org.netbeans.modules.xml.text.api.dom.SyntaxElement;
56
import org.netbeans.modules.xml.text.syntax.XMLSyntaxSupport;
57
import org.netbeans.modules.xml.text.api.dom.XMLSyntaxSupport;
57
import org.netbeans.modules.xml.text.syntax.dom.EmptyTag;
58
import org.netbeans.modules.xml.text.syntax.dom.EndTag;
59
import org.netbeans.modules.xml.text.syntax.dom.StartTag;
60
import org.netbeans.modules.xml.text.syntax.dom.Tag;
61
import org.w3c.dom.Node;
58
import org.w3c.dom.Node;
62
import org.w3c.dom.Text;
59
import org.w3c.dom.Text;
63
60
Lines 65-71 Link Here
65
 * Tracks context information for a code completion scenario
62
 * Tracks context information for a code completion scenario
66
 */
63
 */
67
public class CompletionContext {
64
public class CompletionContext {
68
    private ArrayList<String> existingAttributes;
65
    private List<String> existingAttributes;
69
66
70
    public static enum CompletionType {
67
    public static enum CompletionType {
71
        TAG,
68
        TAG,
Lines 89-137 Link Here
89
        this.caretOffset = caretOffset;
86
        this.caretOffset = caretOffset;
90
87
91
        try {
88
        try {
92
            this.support = (XMLSyntaxSupport) ((BaseDocument)doc).getSyntaxSupport();
89
            this.support = XMLSyntaxSupport.getSyntaxSupport(doc);
93
        } catch (ClassCastException cce) {
90
        } catch (ClassCastException cce) {
94
            LOGGER.log(Level.FINE, cce.getMessage());
91
            LOGGER.log(Level.FINE, cce.getMessage());
95
            this.support = new XMLSyntaxSupport(((BaseDocument)doc));
92
            this.support = XMLSyntaxSupport.createSyntaxSupport(doc);
96
        }
93
        }
97
        this.documentContext = EditorContextFactory.getDocumentContext(doc, caretOffset);
94
        this.documentContext = EditorContextFactory.getDocumentContext(doc, caretOffset);
98
        this.lastTypedChar = support.lastTypedChar();
95
        this.lastTypedChar = support.lastTypedChar();
99
        initContext();
96
        try {
97
            initContext();
98
        } catch (BadLocationException ex) {
99
            throw new IllegalStateException(ex);
100
        }
100
    }
101
    }
101
    
102
    
102
    private void initContext() {
103
    private void initContext() throws BadLocationException {
103
        TokenItem token = documentContext.getCurrentToken();
104
        Token<XMLTokenId> token = documentContext.getCurrentToken();
104
        if(token == null)
105
        if(token == null)
105
            return;
106
            return;
106
        
107
        
107
        boolean tokenBoundary = (token.getOffset() == caretOffset) 
108
        boolean tokenBoundary = (documentContext.getCurrentTokenOffset() == caretOffset) 
108
                || ((token.getOffset() + token.getImage().length()) == caretOffset);
109
                || ((documentContext.getCurrentTokenOffset() + token.length()) == caretOffset);
109
        
110
        
110
        int id = token.getTokenID().getNumericID();
111
        XMLTokenId id = token.id();
111
        SyntaxElement element = documentContext.getCurrentElement();
112
        SyntaxElement element = documentContext.getCurrentElement();
113
        int tOffset = documentContext.getCurrentTokenOffset();
114
        
112
        switch (id) {
115
        switch (id) {
113
            //
116
            //
114
            case XMLDefaultTokenContext.TEXT_ID:
117
            case TEXT:
115
                String chars = token.getImage().trim();
118
                String chars = token.text().toString().trim();
119
                Token<XMLTokenId> previousTokenItem = support.getPreviousToken(tOffset);
120
                if (previousTokenItem == null) {
121
                    completionType = CompletionType.NONE;
122
                    break;
123
                }
124
                String previousTokenText = previousTokenItem.text().toString().trim();
116
                if (chars != null && chars.equals("") &&
125
                if (chars != null && chars.equals("") &&
117
                        token.getPrevious().getImage().trim().equals("/>")) { // NOI18N
126
                        previousTokenText.equals("/>")) { // NOI18N
118
                    completionType = CompletionType.NONE;
127
                    completionType = CompletionType.NONE;
119
                    break;
128
                    break;
120
                }
129
                }
121
                if (chars != null && chars.equals("") &&
130
                if (chars != null && chars.equals("") &&
122
                        token.getPrevious().getImage().trim().equals(">")) { // NOI18N
131
                        previousTokenText.equals(">")) { // NOI18N
123
                    completionType = CompletionType.VALUE;
132
                    completionType = CompletionType.VALUE;
124
                    break;
133
                    break;
125
                }
134
                }
126
                if (chars != null && !chars.startsWith("<") &&
135
                if (chars != null && !chars.startsWith("<") &&
127
                        token.getPrevious().getImage().trim().equals(">")) { // NOI18N
136
                        previousTokenText.equals(">")) { // NOI18N
128
137
129
                    completionType = CompletionType.VALUE;
138
                    completionType = CompletionType.VALUE;
130
                    typedChars = token.getImage().substring(0, caretOffset - token.getOffset());
139
                    typedChars = token.text().subSequence(0, caretOffset - tOffset).toString();
131
                    break;
140
                    break;
132
                }
141
                }
133
                if (chars != null && !chars.equals("<") &&
142
                if (chars != null && !chars.equals("<") &&
134
                        token.getPrevious().getImage().trim().equals(">")) { // NOI18N
143
                        previousTokenText.equals(">")) { // NOI18N
135
                    completionType = CompletionType.NONE;
144
                    completionType = CompletionType.NONE;
136
                    break;
145
                    break;
137
                }
146
                }
Lines 142-195 Link Here
142
                break;
151
                break;
143
152
144
            //start tag of an element
153
            //start tag of an element
145
            case XMLDefaultTokenContext.TAG_ID:
154
            case TAG:
146
                if (element instanceof EndTag) {
155
                if (support.isEndTag(element)) {
147
                    completionType = CompletionType.NONE;
156
                    completionType = CompletionType.NONE;
148
                    break;
157
                    break;
149
                }
158
                }
150
                if (element instanceof EmptyTag) {
159
                if (support.isEmptyTag(element)) {
151
                    if (token != null &&
160
                    if (token != null &&
152
                            token.getImage().trim().equals("/>")) {
161
                            token.text().toString().trim().equals("/>")) {
153
                        completionType = CompletionType.NONE;
162
                        completionType = CompletionType.NONE;
154
                        break;
163
                        break;
155
                    }
164
                    }
156
                    EmptyTag tag = (EmptyTag) element;
157
                    if (element.getElementOffset() + 1 == this.caretOffset) {
165
                    if (element.getElementOffset() + 1 == this.caretOffset) {
158
                        completionType = CompletionType.TAG;
166
                        completionType = CompletionType.TAG;
159
                        break;
167
                        break;
160
                    }
168
                    }
161
                    if (caretOffset > element.getElementOffset() + 1 &&
169
                    if (caretOffset > element.getElementOffset() + 1 &&
162
                            caretOffset <= element.getElementOffset() + 1 + tag.getTagName().length()) {
170
                            caretOffset <= element.getElementOffset() + 1 +element.getNode().getNodeName().length()) {
163
                        completionType = CompletionType.TAG;
171
                        completionType = CompletionType.TAG;
164
                        typedChars = tag.getTagName();
172
                        typedChars = element.getNode().getNodeName();
165
                        break;
173
                        break;
166
                    }
174
                    }
167
                    completionType = CompletionType.ATTRIBUTE;
175
                    completionType = CompletionType.ATTRIBUTE;
168
                    break;
176
                    break;
169
                }
177
                }
170
178
171
                if (element instanceof StartTag) {
179
                if (support.isStartTag(element)) {
172
                    if (token != null &&
180
                    if (token != null &&
173
                            token.getImage().trim().equals(">")) {
181
                            token.text().toString().trim().equals(">")) {
174
                        completionType = CompletionType.NONE;
182
                        completionType = CompletionType.NONE;
175
                        break;
183
                        break;
176
                    }
184
                    }
177
                    if (token != null &&
185
                    if (token != null &&
178
                            token.getImage().trim().startsWith("</")) {
186
                            token.text().toString().trim().startsWith("</")) {
179
                        typedChars = "";
187
                        typedChars = "";
180
                        completionType = CompletionType.VALUE;
188
                        completionType = CompletionType.VALUE;
181
                        break;
189
                        break;
182
                    }
190
                    }
183
                    if (element.getElementOffset() + 1 != this.caretOffset) {
191
                    if (element.getElementOffset() + 1 != this.caretOffset) {
184
                        StartTag tag = (StartTag) element;
192
                        typedChars = element.getNode().getNodeName();
185
                        typedChars = tag.getTagName();
186
                    }
193
                    }
187
                }
194
                }
188
                
195
                
189
                if (element instanceof Text) {
196
                if (element instanceof Text) {
190
                    if (token != null &&
197
                    if (token != null &&
191
                            token.getImage().trim().startsWith("</")) {
198
                            token.text().toString().trim().startsWith("</")) {
192
                        typedChars = token.getPrevious().getImage().trim();
199
                        Token<XMLTokenId> prevToken = support.getPreviousToken(tOffset);
200
                        if (prevToken == null) {
201
                            completionType = CompletionType.NONE;
202
                            break;
203
                        }
204
                        typedChars = prevToken.text().toString().trim();
193
                        completionType = CompletionType.VALUE;
205
                        completionType = CompletionType.VALUE;
194
                        break;
206
                        break;
195
                    }
207
                    }
Lines 203-243 Link Here
203
                break;
215
                break;
204
216
205
            //user enters an attribute name
217
            //user enters an attribute name
206
            case XMLDefaultTokenContext.ARGUMENT_ID:
218
            case ARGUMENT:
207
                completionType = CompletionType.ATTRIBUTE;
219
                completionType = CompletionType.ATTRIBUTE;
208
                typedChars = token.getImage().substring(0, caretOffset - token.getOffset());;
220
                typedChars = token.text().toString().substring(0, caretOffset - tOffset);;
209
                break;
221
                break;
210
222
211
            //some random character
223
            //some random character
212
            case XMLDefaultTokenContext.CHARACTER_ID:
224
            case CHARACTER:
213
            //user enters = character, we should ignore all other operators
225
            //user enters = character, we should ignore all other operators
214
            case XMLDefaultTokenContext.OPERATOR_ID:
226
            case OPERATOR:
215
                completionType = CompletionType.NONE;
227
                completionType = CompletionType.NONE;
216
                break;
228
                break;
217
            //user enters either ' or "
229
            //user enters either ' or "
218
            case XMLDefaultTokenContext.VALUE_ID:
230
            case VALUE:
219
                if(!tokenBoundary) {
231
                if(!tokenBoundary) {
220
                    completionType = CompletionType.ATTRIBUTE_VALUE;
232
                    completionType = CompletionType.ATTRIBUTE_VALUE;
221
                    typedChars = token.getImage().substring(1, caretOffset - token.getOffset());
233
                    typedChars = token.text().subSequence(1, caretOffset - tOffset).toString();
222
                } else {
234
                } else {
223
                    completionType = CompletionType.NONE;
235
                    completionType = CompletionType.NONE;
224
                }
236
                }
225
                break;
237
                break;
226
238
227
            //user enters white-space character
239
            //user enters white-space character
228
            case XMLDefaultTokenContext.WS_ID:
240
            case WS:
229
                completionType = CompletionType.NONE;
241
                completionType = CompletionType.NONE;
230
                TokenItem prev = token.getPrevious();
242
                int[] offset = new int[1];
231
                while (prev != null &&
243
                Token<XMLTokenId> prev = support.runWithSequence(tOffset,
232
                        (prev.getTokenID().getNumericID() == XMLDefaultTokenContext.WS_ID)) {
244
                    (TokenSequence ts) -> {
233
                    prev = prev.getPrevious();
245
                        Token<XMLTokenId> t  = null;
246
                        boolean ok;
247
                        while ((ok = ts.movePrevious())) {
248
                            t = ts.token();
249
                            if (t.id() != XMLTokenId.WS) {
250
                                break;
251
                            }
252
                        }
253
                        if (ok) {
254
                            offset[0] = ts.offset();
255
                            return t;
256
                        } else {
257
                            return null;
258
                        }
259
                    }
260
                );
261
                if (prev == null) {
262
                    completionType = CompletionType.NONE;
263
                    break;
234
                }
264
                }
235
                
265
                int prevOffset = offset[0];
236
                if(prev.getTokenID().getNumericID() == XMLDefaultTokenContext.ARGUMENT_ID) {
266
237
                    typedChars = prev.getImage();
267
                if(prev.id() == XMLTokenId.ARGUMENT) {
268
                    typedChars = prev.text().toString();
238
                    completionType = CompletionType.ATTRIBUTE;
269
                    completionType = CompletionType.ATTRIBUTE;
239
                } else if ((prev.getTokenID().getNumericID() == XMLDefaultTokenContext.VALUE_ID) ||
270
                } else if ((prev.id() == XMLTokenId.VALUE) ||
240
                        (prev.getTokenID().getNumericID() == XMLDefaultTokenContext.TAG_ID)) {
271
                        (prev.id() == XMLTokenId.TAG)) {
241
                    completionType = CompletionType.ATTRIBUTE;
272
                    completionType = CompletionType.ATTRIBUTE;
242
                }
273
                }
243
                break;
274
                break;
Lines 270-296 Link Here
270
    
301
    
271
    public Node getTag() {
302
    public Node getTag() {
272
        SyntaxElement element = documentContext.getCurrentElement();
303
        SyntaxElement element = documentContext.getCurrentElement();
273
        return (element instanceof Tag) ? (Node) element : null;
304
        return element.getType() == Node.ELEMENT_NODE ? (Node) element : null;
274
    }
305
    }
275
    
306
    
276
    public TokenItem getCurrentToken() {
307
    public Token<XMLTokenId> getCurrentToken() {
277
        return documentContext.getCurrentToken();
308
        return documentContext.getCurrentToken();
278
    }
309
    }
279
    
310
    
311
    public int getCurrentTokenOffset() {
312
        return documentContext.getCurrentTokenOffset();
313
    }
314
    
315
    private List<String> getExistingAttributesLocked(TokenSequence ts) {
316
        List<String> existingAttributes = new ArrayList<String>();
317
        while (ts.movePrevious()) {
318
            Token<XMLTokenId> item = ts.token();
319
            XMLTokenId tokenId = item.id();
320
            if (tokenId == XMLTokenId.TAG) {
321
                break;
322
            }
323
            if (tokenId == XMLTokenId.ARGUMENT) {
324
                existingAttributes.add(item.text().toString());
325
            }
326
        }
327
        return existingAttributes;
328
    }
329
280
    public List<String> getExistingAttributes() {
330
    public List<String> getExistingAttributes() {
281
        if(existingAttributes != null)
331
        if (existingAttributes == null) {
282
            return existingAttributes;
332
            try {
283
        existingAttributes = new ArrayList<String>();
333
                existingAttributes = (List<String>)support.runWithSequence(
284
        TokenItem item = documentContext.getCurrentToken().getPrevious();
334
                        documentContext.getCurrentTokenOffset(),
285
        while(item != null) {
335
                        this::getExistingAttributesLocked
286
            if(item.getTokenID().getNumericID() ==
336
                );
287
                    XMLDefaultTokenContext.TAG_ID)
337
            } catch (BadLocationException ex) {
288
                break;
289
            if(item.getTokenID().getNumericID() ==
290
                    XMLDefaultTokenContext.ARGUMENT_ID) {
291
                existingAttributes.add(item.getImage());
292
            }
338
            }
293
            item = item.getPrevious();
294
        }
339
        }
295
        return existingAttributes;
340
        return existingAttributes;
296
    }
341
    }
(-)a/j2ee.persistence/src/org/netbeans/modules/j2ee/persistence/editor/ContextUtilities.java (-90 / +50 lines)
Lines 44-56 Link Here
44
44
45
package org.netbeans.modules.j2ee.persistence.editor;
45
package org.netbeans.modules.j2ee.persistence.editor;
46
46
47
import javax.swing.text.BadLocationException;
47
import javax.xml.XMLConstants;
48
import javax.xml.XMLConstants;
48
import org.netbeans.editor.TokenItem;
49
import org.netbeans.api.lexer.Token;
49
import org.netbeans.modules.xml.text.api.XMLDefaultTokenContext;
50
import org.netbeans.api.lexer.TokenSequence;
50
import org.netbeans.modules.xml.text.syntax.SyntaxElement;
51
import org.netbeans.api.xml.lexer.XMLTokenId;
51
import org.netbeans.modules.xml.text.syntax.dom.EmptyTag;
52
import static org.netbeans.api.xml.lexer.XMLTokenId.*;
52
import org.netbeans.modules.xml.text.syntax.dom.StartTag;
53
import org.netbeans.modules.xml.text.api.dom.SyntaxElement;
53
import org.netbeans.modules.xml.text.syntax.dom.Tag;
54
import org.netbeans.modules.xml.text.api.dom.TagElement;
55
import org.netbeans.modules.xml.text.api.dom.XMLSyntaxSupport;
56
import org.w3c.dom.Node;
54
57
55
/**
58
/**
56
 *
59
 *
Lines 61-69 Link Here
61
    private ContextUtilities() {
64
    private ContextUtilities() {
62
    }
65
    }
63
    
66
    
64
    public static boolean isValueToken(TokenItem currentToken) {
67
    public static boolean isValueToken(Token<XMLTokenId> currentToken) {
65
        if(currentToken != null) {
68
        if(currentToken != null) {
66
            if (currentToken.getTokenID().getNumericID() == XMLDefaultTokenContext.VALUE_ID) {
69
            if (currentToken.id() == VALUE) {
67
                return true;
70
                return true;
68
            }
71
            }
69
        }
72
        }
Lines 71-79 Link Here
71
        return false;
74
        return false;
72
    }
75
    }
73
    
76
    
74
    public static boolean isTagToken(TokenItem currentToken) {
77
    public static boolean isTagToken(Token<XMLTokenId> currentToken) {
75
        if(currentToken != null) {
78
        if(currentToken != null) {
76
            if (currentToken.getTokenID().getNumericID() == XMLDefaultTokenContext.TAG_ID) {
79
            if (currentToken.id() == TAG) {
77
                return true;
80
                return true;
78
            }
81
            }
79
        }
82
        }
Lines 81-89 Link Here
81
        return false;
84
        return false;
82
    }
85
    }
83
    
86
    
84
    public static boolean isAttributeToken(TokenItem currentToken) {
87
    public static boolean isAttributeToken(Token<XMLTokenId> currentToken) {
85
        if(currentToken != null) {
88
        if(currentToken != null) {
86
            if (currentToken.getTokenID().getNumericID() == XMLDefaultTokenContext.ARGUMENT_ID) {
89
            if (currentToken.id() == ARGUMENT) {
87
                return true;
90
                return true;
88
            }
91
            }
89
        }
92
        }
Lines 91-178 Link Here
91
        return false;
94
        return false;
92
    }
95
    }
93
    
96
    
94
    public static TokenItem getAttributeToken(TokenItem currentToken) {
97
    public static Token<XMLTokenId> getAttributeToken(DocumentContext context) {
95
        if(currentToken == null )
96
            return null;
97
        
98
        if(isValueToken(currentToken)) {
99
            TokenItem equalsToken = currentToken.getPrevious();
100
            if(equalsToken == null)
101
                return null;
102
            
103
            while(equalsToken != null && equalsToken.getTokenID().getNumericID() != XMLDefaultTokenContext.OPERATOR_ID) {
104
                equalsToken = equalsToken.getPrevious();
105
            }
106
            
107
            if(equalsToken == null) {
108
                return null;
109
            }
110
        
111
            TokenItem argumentToken = equalsToken.getPrevious();
112
            if(argumentToken == null)
113
                return null;
114
            
115
            while(argumentToken != null && argumentToken.getTokenID().getNumericID() != XMLDefaultTokenContext.ARGUMENT_ID) {
116
                argumentToken = argumentToken.getPrevious();
117
            }
118
        
119
            return argumentToken;
120
        }
121
        
122
        return null;
123
    }
124
  
125
    public static Tag getCurrentTagElement(DocumentContext context) {
126
        SyntaxElement element = context.getCurrentElement();
127
        if(element instanceof StartTag) {
128
            return (StartTag) element;
129
        } else if(element instanceof EmptyTag) {
130
            return (EmptyTag) element;
131
        }
132
        
133
        return null;
134
    }
135
    
136
    public static TokenItem getAttributeToken(DocumentContext context) {
137
        if(context.getCurrentToken() == null )
98
        if(context.getCurrentToken() == null )
138
            return null;
99
            return null;
139
        
100
        try {
140
        if(isValueToken(context.getCurrentToken())) {
101
            return context.<Token<XMLTokenId>>runWithSequence((TokenSequence ts) -> {
141
            TokenItem equalsToken = context.getCurrentToken().getPrevious();
102
                if(!isValueToken(context.getCurrentToken())) {
142
            if(equalsToken == null)
103
                    return null;
143
                return null;
104
                }
144
            
105
                Token<XMLTokenId> equalsToken = null;
145
            //getTokenId() should not return null by JavaDoc. But in reality, it does reutrn null sometimes
106
                while (ts.movePrevious()) {
146
            // see issue 67661
107
                    Token<XMLTokenId> t = ts.token();
147
            if(equalsToken.getTokenID() == null) {
108
                    if (t.id() == OPERATOR) {
148
                return null;
109
                        equalsToken = t;
149
            }
110
                        break;
150
            while(equalsToken != null && equalsToken.getTokenID().getNumericID() != XMLDefaultTokenContext.OPERATOR_ID) {
111
                    }
151
                equalsToken = equalsToken.getPrevious();
112
                }
152
            }
113
                if(equalsToken == null) {
153
            
114
                    return null;
154
            if(equalsToken == null) {
115
                }
155
                return null;
116
                Token<XMLTokenId> argumentToken = null;
156
            }
117
                while (ts.movePrevious()) {
157
        
118
                    Token<XMLTokenId> t = ts.token();
158
            TokenItem argumentToken = equalsToken.getPrevious();
119
                    if (t.id() == ARGUMENT) {
159
            if(argumentToken == null)
120
                        argumentToken = t;
160
                return null;
121
                        break;
161
            
122
                    }
162
            while(argumentToken != null && argumentToken.getTokenID().getNumericID() != XMLDefaultTokenContext.ARGUMENT_ID) {
123
                }
163
                argumentToken = argumentToken.getPrevious();
124
                return argumentToken;
164
            }
125
            });
165
        
126
        } catch (BadLocationException ex) {
166
            return argumentToken;
167
        }
127
        }
168
        
169
        return null;
128
        return null;
170
    }
129
    }
171
    
130
    
172
    public static String getAttributeTokenImage(DocumentContext context) {
131
    public static String getAttributeTokenImage(DocumentContext context) {
173
        TokenItem tok = getAttributeToken(context);
132
        Token<XMLTokenId> tok = getAttributeToken(context);
174
        if(tok != null) {
133
        if(tok != null) {
175
            return tok.getImage();
134
            return tok.text().toString();
176
        }
135
        }
177
        
136
        
178
        return null;
137
        return null;
Lines 221-231 Link Here
221
        return nodeName.substring(0, colonIndex);
180
        return nodeName.substring(0, colonIndex);
222
    }
181
    }
223
    
182
    
224
    public static StartTag getRoot(SyntaxElement se) {
183
    public static SyntaxElement getRoot(SyntaxElement se) {
225
        StartTag root = null;
184
        SyntaxElement root = null;
226
        while( se != null) {
185
        while( se != null) {
227
            if(se instanceof StartTag) {
186
            if(se.getType() == Node.ELEMENT_NODE &&
228
                root = (StartTag)se;
187
               ((TagElement)se).isStart()) {
188
                root = se;
229
            }
189
            }
230
            se = se.getPrevious();
190
            se = se.getPrevious();
231
        }
191
        }
(-)a/j2ee.persistence/src/org/netbeans/modules/j2ee/persistence/editor/DocumentContext.java (-76 / +28 lines)
Lines 55-68 Link Here
55
import java.util.logging.Logger;
55
import java.util.logging.Logger;
56
import javax.swing.text.BadLocationException;
56
import javax.swing.text.BadLocationException;
57
import javax.swing.text.Document;
57
import javax.swing.text.Document;
58
import org.netbeans.editor.BaseDocument;
58
import org.netbeans.api.lexer.Token;
59
import org.netbeans.editor.TokenItem;
59
import org.netbeans.api.xml.lexer.XMLTokenId;
60
import org.netbeans.modules.xml.text.syntax.SyntaxElement;
60
import org.netbeans.modules.xml.text.api.dom.SyntaxElement;
61
import org.netbeans.modules.xml.text.syntax.XMLSyntaxSupport;
61
import org.netbeans.modules.xml.text.api.dom.XMLSyntaxSupport;
62
import org.netbeans.modules.xml.text.syntax.dom.EmptyTag;
63
import org.netbeans.modules.xml.text.syntax.dom.EndTag;
64
import org.netbeans.modules.xml.text.syntax.dom.StartTag;
65
import org.netbeans.modules.xml.text.syntax.dom.Tag;
66
import org.w3c.dom.Attr;
62
import org.w3c.dom.Attr;
67
import org.w3c.dom.NamedNodeMap;
63
import org.w3c.dom.NamedNodeMap;
68
import org.w3c.dom.Node;
64
import org.w3c.dom.Node;
Lines 79-87 Link Here
79
    private XMLSyntaxSupport syntaxSupport;
75
    private XMLSyntaxSupport syntaxSupport;
80
    private int caretOffset = -1;
76
    private int caretOffset = -1;
81
    private SyntaxElement element;
77
    private SyntaxElement element;
82
    private TokenItem token;
78
    private Token<XMLTokenId> token;
79
    private int tokenOffset;
83
    private boolean valid = false;
80
    private boolean valid = false;
84
    private StartTag docRoot;
81
    private SyntaxElement docRoot;
85
    private String defaultNamespace;
82
    private String defaultNamespace;
86
    private HashMap<String, String> declaredNamespaces =
83
    private HashMap<String, String> declaredNamespaces =
87
            new HashMap<String, String>();
84
            new HashMap<String, String>();
Lines 93-102 Link Here
93
    DocumentContext(Document document) {
90
    DocumentContext(Document document) {
94
        this.document = document;
91
        this.document = document;
95
        try {
92
        try {
96
            this.syntaxSupport = (XMLSyntaxSupport) ((BaseDocument)document).getSyntaxSupport();
93
            this.syntaxSupport = XMLSyntaxSupport.getSyntaxSupport(document);
97
        } catch (ClassCastException cce) {
94
        } catch (ClassCastException cce) {
98
            LOGGER.log(Level.FINE, cce.getMessage());
95
            LOGGER.log(Level.FINE, cce.getMessage());
99
            this.syntaxSupport = new XMLSyntaxSupport(((BaseDocument)document));
96
            this.syntaxSupport = XMLSyntaxSupport.createSyntaxSupport(document);
100
        }
97
        }
101
    }
98
    }
102
99
Lines 110-116 Link Here
110
        declaredNamespaces.clear();
107
        declaredNamespaces.clear();
111
        try {
108
        try {
112
            element = syntaxSupport.getElementChain(caretOffset);
109
            element = syntaxSupport.getElementChain(caretOffset);
113
            token = syntaxSupport.getTokenChain(caretOffset, Math.min(document.getLength(), caretOffset+1));
110
            int[] off = new int[2];
111
            token = syntaxSupport.getNextToken(caretOffset, off);
112
            tokenOffset = off[0];
114
            this.docRoot = ContextUtilities.getRoot(element);
113
            this.docRoot = ContextUtilities.getRoot(element);
115
            populateNamespaces();
114
            populateNamespaces();
116
        } catch (BadLocationException ex) {
115
        } catch (BadLocationException ex) {
Lines 123-147 Link Here
123
        return this.valid;
122
        return this.valid;
124
    }
123
    }
125
124
126
    public int getCurrentTokenId() {
125
    public Token<XMLTokenId> getCurrentToken() {
127
        if (isValid()) {
128
            return token.getTokenID().getNumericID();
129
        } else {
130
            return -1;
131
        }
132
    }
133
134
    public TokenItem getCurrentToken() {
135
        if (isValid()) {
126
        if (isValid()) {
136
            return token;
127
            return token;
137
        } else {
128
        } else {
138
            return null;
129
            return null;
139
        }
130
        }
140
    }
131
    }
132
    
133
    public int getCurrentTokenOffset() {
134
        return tokenOffset;
135
    }
141
136
142
    public String getCurrentTokenImage() {
137
    public String getCurrentTokenImage() {
143
        if (isValid()) {
138
        if (isValid()) {
144
            return token.getImage();
139
            return token.text().toString();
145
        } else {
140
        } else {
146
            return null;
141
            return null;
147
        }
142
        }
Lines 151-204 Link Here
151
        return this.element;
146
        return this.element;
152
    }
147
    }
153
    
148
    
154
    public List<String> getPathFromRoot() {
155
        if (isValid()) {
156
            SyntaxElement elementRef = this.element;
157
            Stack<SyntaxElement> stack = new Stack<SyntaxElement>();
158
159
            while (elementRef != null) {
160
                if ((elementRef instanceof EndTag) ||
161
                        (elementRef instanceof EmptyTag && stack.isEmpty()) ||
162
                        (elementRef instanceof StartTag && stack.isEmpty())) {
163
                    stack.push(elementRef);
164
                    elementRef = elementRef.getPrevious();
165
                    continue;
166
                }
167
                if (elementRef instanceof StartTag) {
168
                    StartTag start = (StartTag) elementRef;
169
                    if (stack.peek() instanceof EndTag) {
170
                        EndTag end = (EndTag) stack.peek();
171
                        if (end.getTagName().equals(start.getTagName())) {
172
                            stack.pop();
173
                        }
174
                    } else {
175
                        SyntaxElement e = (SyntaxElement) stack.peek();
176
                        String tagAtTop = (e instanceof StartTag) ? ((StartTag) e).getTagName() : ((EmptyTag) e).getTagName();
177
                        stack.push(elementRef);
178
                    }
179
                }
180
                elementRef = elementRef.getPrevious();
181
            }
182
183
            return createPath(stack);
184
        }
185
186
        return Collections.emptyList();
187
    }
188
189
    private List<String> createPath(Stack<SyntaxElement> stack) {
190
        ArrayList<String> pathList = new ArrayList<String>();
191
        while (!stack.isEmpty()) {
192
            SyntaxElement top = stack.pop();
193
            String tagName = (top instanceof StartTag) ? ((StartTag) top).getTagName() : ((EmptyTag) top).getTagName();
194
            if (tagName != null) {
195
                pathList.add(tagName);
196
            }
197
        }
198
199
        return Collections.unmodifiableList(pathList);
200
    }
201
202
    public Document getDocument() {
149
    public Document getDocument() {
203
        return this.document;
150
        return this.document;
204
    }
151
    }
Lines 225-231 Link Here
225
        return declaredNamespaces.values();
172
        return declaredNamespaces.values();
226
    }
173
    }
227
174
228
    public StartTag getDocRoot() {
175
    public SyntaxElement getDocRoot() {
229
        return docRoot;
176
        return docRoot;
230
    }
177
    }
231
178
Lines 236-242 Link Here
236
    private void populateNamespaces() {
183
    private void populateNamespaces() {
237
        // Find the a start or empty tag just before the current syntax element.
184
        // Find the a start or empty tag just before the current syntax element.
238
        SyntaxElement element = this.element;
185
        SyntaxElement element = this.element;
239
        while (element != null && !(element instanceof StartTag) && !(element instanceof EmptyTag)) {
186
        while (element != null && !syntaxSupport.isStartTag(element) && !syntaxSupport.isEmptyTag(element)) {
240
            element = element.getPrevious();
187
            element = element.getPrevious();
241
        }
188
        }
242
        if (element == null) {
189
        if (element == null) {
Lines 246-254 Link Here
246
        // To find all namespace declarations active at the caret offset, we
193
        // To find all namespace declarations active at the caret offset, we
247
        // need to look at xmlns attributes of the current element and its ancestors.
194
        // need to look at xmlns attributes of the current element and its ancestors.
248
        Node node = (Node)element;
195
        Node node = (Node)element;
249
        while (node != null) {
196
        while (node != null && element != null) {
250
            if (node instanceof StartTag || node instanceof EmptyTag) {
197
            if (syntaxSupport.isStartTag(element) || syntaxSupport.isEmptyTag(element)) {
251
                NamedNodeMap attributes = ((Tag)node).getAttributes();
198
                NamedNodeMap attributes = node.getAttributes();
252
                for (int index = 0; index < attributes.getLength(); index++) {
199
                for (int index = 0; index < attributes.getLength(); index++) {
253
                    Attr attr = (Attr) attributes.item(index);
200
                    Attr attr = (Attr) attributes.item(index);
254
                    String attrName = attr.getName();
201
                    String attrName = attr.getName();
Lines 271-276 Link Here
271
                }
218
                }
272
            }
219
            }
273
            node = node.getParentNode();
220
            node = node.getParentNode();
221
            element = syntaxSupport.getSyntaxElement(node);
274
        }
222
        }
275
    }
223
    }
276
    
224
    
Lines 303-306 Link Here
303
        hash = 61 * hash + (this.document != null ? this.document.hashCode() : 0);
251
        hash = 61 * hash + (this.document != null ? this.document.hashCode() : 0);
304
        return hash;
252
        return hash;
305
    }
253
    }
254
255
    public <T> T runWithSequence(XMLSyntaxSupport.SequenceCallable<T> callable) throws BadLocationException {
256
        return syntaxSupport.runWithSequence(caretOffset, callable);
257
    }
306
}
258
}
(-)a/j2ee.persistence/src/org/netbeans/modules/j2ee/persistence/editor/completion/PUCompletionManager.java (-16 / +37 lines)
Lines 48-60 Link Here
48
import java.util.HashMap;
48
import java.util.HashMap;
49
import java.util.List;
49
import java.util.List;
50
import java.util.Map;
50
import java.util.Map;
51
import org.netbeans.editor.TokenItem;
51
import javax.swing.text.BadLocationException;
52
import org.netbeans.api.lexer.Token;
53
import org.netbeans.api.lexer.TokenSequence;
54
import org.netbeans.api.xml.lexer.XMLTokenId;
52
import org.netbeans.modules.j2ee.persistence.editor.*;
55
import org.netbeans.modules.j2ee.persistence.editor.*;
53
import org.netbeans.modules.j2ee.persistence.unit.PersistenceCfgProperties;
56
import org.netbeans.modules.j2ee.persistence.unit.PersistenceCfgProperties;
54
import org.netbeans.modules.xml.text.syntax.SyntaxElement;
57
import org.netbeans.modules.xml.text.api.dom.SyntaxElement;
55
import org.netbeans.modules.xml.text.syntax.dom.StartTag;
58
import org.netbeans.modules.xml.text.api.dom.TagElement;
56
import org.netbeans.modules.xml.text.syntax.dom.Tag;
59
import org.w3c.dom.Node;
57
import org.w3c.dom.Text;
58
60
59
/**
61
/**
60
 * This class figures out the completion items for various attributes
62
 * This class figures out the completion items for various attributes
Lines 109-116 Link Here
109
        }
111
        }
110
        
112
        
111
        String tagName = context.getTag().getNodeName();
113
        String tagName = context.getTag().getNodeName();
112
        TokenItem attrib = ContextUtilities.getAttributeToken(context.getCurrentToken());
114
        Token<XMLTokenId> attrib = ContextUtilities.getAttributeToken(context.getDocumentContext());
113
        String attribName = attrib != null ? attrib.getImage() : null;
115
        String attribName = attrib != null ? attrib.text().toString(): null;
114
116
115
        PUCompletor completor = locateCompletor(tagName, attribName);
117
        PUCompletor completor = locateCompletor(tagName, attribName);
116
        if (completor != null) {
118
        if (completor != null) {
Lines 128-136 Link Here
128
        DocumentContext docContext = context.getDocumentContext();
130
        DocumentContext docContext = context.getDocumentContext();
129
        SyntaxElement curElem = docContext.getCurrentElement();
131
        SyntaxElement curElem = docContext.getCurrentElement();
130
        SyntaxElement prevElem = docContext.getCurrentElement().getPrevious();
132
        SyntaxElement prevElem = docContext.getCurrentElement().getPrevious();
131
        Tag propTag;
133
        TagElement propTag;
132
134
133
        String tagName = (curElem instanceof StartTag) ? ((StartTag) curElem).getTagName() : ((prevElem instanceof StartTag) ? ((StartTag) prevElem).getTagName() : null);
135
        String tagName;
136
        
137
        if (curElem.getType() == Node.ELEMENT_NODE && ((TagElement)curElem).isStart()) {
138
            tagName = curElem.getNode().getNodeName();
139
        } else if (prevElem.getType() == Node.ELEMENT_NODE && ((TagElement)prevElem).isStart()) {
140
            tagName = prevElem.getNode().getNodeName();
141
        } else {
142
            tagName = null;
143
        }
134
        PUCompletor completor = locateCompletor(tagName, null);
144
        PUCompletor completor = locateCompletor(tagName, null);
135
        if (completor != null) {
145
        if (completor != null) {
136
            valueItems.addAll(completor.doCompletion(context));
146
            valueItems.addAll(completor.doCompletion(context));
Lines 142-157 Link Here
142
            // If current element is a start tag and its tag is <property>
152
            // If current element is a start tag and its tag is <property>
143
            // or the current element is text and its prev is a start <property> tag,
153
            // or the current element is text and its prev is a start <property> tag,
144
            // then do the code completion
154
            // then do the code completion
145
            if ((curElem instanceof StartTag) && ((StartTag) curElem).getTagName().equalsIgnoreCase(PersistenceCfgXmlConstants.PROPERTY_TAG)) {
155
            if (curElem.getType() == Node.ELEMENT_NODE && ((TagElement)curElem).isStart() && 
146
                propTag = (StartTag) curElem;
156
                PersistenceCfgXmlConstants.PROPERTY_TAG.equalsIgnoreCase(curElem.getNode().getNodeName())) {
147
            } else if ((curElem instanceof Text) && (prevElem instanceof StartTag) &&
157
                propTag = (TagElement)curElem;
148
                    ((StartTag) prevElem).getTagName().equalsIgnoreCase(PersistenceCfgXmlConstants.PROPERTY_TAG)) {
158
            } else if (curElem.getType() == Node.TEXT_NODE && (prevElem.getType() == Node.ELEMENT_NODE && ((TagElement)prevElem).isStart()) &&
149
                propTag = (StartTag) prevElem;
159
                    PersistenceCfgXmlConstants.PROPERTY_TAG.equalsIgnoreCase(prevElem.getNode().getNodeName())) {
160
                propTag = (TagElement)prevElem;
150
            } else {
161
            } else {
151
                return anchorOffset;
162
                return anchorOffset;
152
            }
163
            }
153
164
154
            String propName = JPAEditorUtil.getPersistencePropertyName(propTag);
165
            String propName = JPAEditorUtil.getPersistencePropertyName(propTag.getNode());
155
            int caretOffset = context.getCaretOffset();
166
            int caretOffset = context.getCaretOffset();
156
            String typedChars = context.getTypedPrefix();
167
            String typedChars = context.getTypedPrefix();
157
168
Lines 171-177 Link Here
171
                    }
182
                    }
172
                }
183
                }
173
184
174
                anchorOffset = context.getCurrentToken().getPrevious().getOffset() + 1;
185
                try {
186
                    anchorOffset = context.getDocumentContext().
187
                            runWithSequence((TokenSequence s) -> {
188
                                if (!s.movePrevious()) {
189
                                    return -1;
190
                                }
191
                                return s.offset();
192
                            });
193
                } catch (BadLocationException ex) {
194
                    anchorOffset = -1;
195
                }
175
            }
196
            }
176
        }
197
        }
177
        return anchorOffset;
198
        return anchorOffset;
(-)a/j2ee.persistence/src/org/netbeans/modules/j2ee/persistence/editor/completion/PUCompletor.java (-9 / +9 lines)
Lines 103-109 Link Here
103
                    }
103
                    }
104
                }
104
                }
105
            }
105
            }
106
            setAnchorOffset(context.getCurrentToken().getOffset() + 1);
106
            setAnchorOffset(context.getCurrentTokenOffset() + 1);
107
            return results;
107
            return results;
108
        }
108
        }
109
    }
109
    }
Lines 131-137 Link Here
131
                    results.add(item);
131
                    results.add(item);
132
            }
132
            }
133
133
134
            setAnchorOffset(context.getCurrentToken().getOffset() + 1);
134
            setAnchorOffset(context.getCurrentTokenOffset() + 1);
135
            return results;
135
            return results;
136
        }
136
        }
137
    }
137
    }
Lines 151-157 Link Here
151
                    results.add(item);
151
                    results.add(item);
152
                }
152
                }
153
            }
153
            }
154
            setAnchorOffset(context.getCurrentToken().getOffset() + 1);
154
            setAnchorOffset(context.getCurrentTokenOffset() + 1);
155
            return results;
155
            return results;
156
        }
156
        }
157
    }    
157
    }    
Lines 199-205 Link Here
199
                }
199
                }
200
            }
200
            }
201
201
202
            setAnchorOffset(context.getCurrentToken().getOffset() + 1);
202
            setAnchorOffset(context.getCurrentTokenOffset() + 1);
203
            return results;
203
            return results;
204
        }
204
        }
205
    }
205
    }
Lines 221-227 Link Here
221
                    return Collections.emptyList();
221
                    return Collections.emptyList();
222
                }
222
                }
223
                FileObject fo = NbEditorUtilities.getFileObject(context.getDocument());
223
                FileObject fo = NbEditorUtilities.getFileObject(context.getDocument());
224
                doJavaCompletion(fo, js, results, typedChars, context.getCurrentToken().getOffset());
224
                doJavaCompletion(fo, js, results, typedChars, context.getCurrentTokenOffset());
225
            } catch (IOException ex) {
225
            } catch (IOException ex) {
226
                Exceptions.printStackTrace(ex);
226
                Exceptions.printStackTrace(ex);
227
            }
227
            }
Lines 318-324 Link Here
318
                Exceptions.printStackTrace(ex);
318
                Exceptions.printStackTrace(ex);
319
            }
319
            }
320
320
321
            setAnchorOffset(context.getCurrentToken().getOffset() + 1);
321
            setAnchorOffset(context.getCurrentTokenOffset() + 1);
322
322
323
            return results;
323
            return results;
324
        }
324
        }
Lines 364-370 Link Here
364
                }
364
                }
365
            }
365
            }
366
366
367
            setAnchorOffset(context.getCurrentToken().getOffset() + 1);
367
            setAnchorOffset(context.getCurrentTokenOffset() + 1);
368
            return results;
368
            return results;
369
        }
369
        }
370
    }
370
    }
Lines 425-431 Link Here
425
                }
425
                }
426
            }
426
            }
427
427
428
            setAnchorOffset(context.getCurrentToken().getOffset() + 1);
428
            setAnchorOffset(context.getCurrentTokenOffset() + 1);
429
            return results;
429
            return results;
430
        }
430
        }
431
    }
431
    }
Lines 455-461 Link Here
455
                }
455
                }
456
            }
456
            }
457
457
458
            setAnchorOffset(context.getCurrentToken().getOffset() + 1);
458
            setAnchorOffset(context.getCurrentTokenOffset() + 1);
459
            return results;
459
            return results;
460
        }
460
        }
461
461
(-)a/j2ee.websphere6/nbproject/project.xml (-1 / +1 lines)
Lines 190-196 Link Here
190
                    <code-name-base>org.netbeans.modules.xml.text</code-name-base>
190
                    <code-name-base>org.netbeans.modules.xml.text</code-name-base>
191
                    <run-dependency>
191
                    <run-dependency>
192
                        <release-version>2</release-version>
192
                        <release-version>2</release-version>
193
                        <specification-version>1.16</specification-version>
193
                        <specification-version>1.60</specification-version>
194
                    </run-dependency>
194
                    </run-dependency>
195
                </dependency>
195
                </dependency>
196
                <dependency>
196
                <dependency>
(-)a/javafx2.editor/nbproject/project.xml (-1 / +1 lines)
Lines 277-283 Link Here
277
                    <compile-dependency/>
277
                    <compile-dependency/>
278
                    <run-dependency>
278
                    <run-dependency>
279
                        <release-version>2</release-version>
279
                        <release-version>2</release-version>
280
                        <specification-version>1.34</specification-version>
280
                        <specification-version>1.60</specification-version>
281
                    </run-dependency>
281
                    </run-dependency>
282
                </dependency>
282
                </dependency>
283
                <dependency>
283
                <dependency>
(-)a/nbbuild/cluster.properties (+1 lines)
Lines 556-561 Link Here
556
        xml.schema.model,\
556
        xml.schema.model,\
557
        xml.tax,\
557
        xml.tax,\
558
        xml.text,\
558
        xml.text,\
559
        xml.text.obsolete90,\
559
        xml.tools,\
560
        xml.tools,\
560
        xml.wsdl.model,\
561
        xml.wsdl.model,\
561
        xml.xam,\
562
        xml.xam,\
(-)a/nbbuild/javadoctools/links.xml (+1 lines)
Lines 250-252 Link Here
250
<link href="${javadoc.docs.org-netbeans-modules-docker-api}" offline="true" packagelistloc="${netbeans.javadoc.dir}/org-netbeans-modules-docker-api"/>
250
<link href="${javadoc.docs.org-netbeans-modules-docker-api}" offline="true" packagelistloc="${netbeans.javadoc.dir}/org-netbeans-modules-docker-api"/>
251
<link href="${javadoc.docs.org-netbeans-modules-csl-types}" offline="true" packagelistloc="${netbeans.javadoc.dir}/org-netbeans-modules-csl-types"/>
251
<link href="${javadoc.docs.org-netbeans-modules-csl-types}" offline="true" packagelistloc="${netbeans.javadoc.dir}/org-netbeans-modules-csl-types"/>
252
<link href="${javadoc.docs.org-netbeans-modules-csl-api}" offline="true" packagelistloc="${netbeans.javadoc.dir}/org-netbeans-modules-csl-api"/>
252
<link href="${javadoc.docs.org-netbeans-modules-csl-api}" offline="true" packagelistloc="${netbeans.javadoc.dir}/org-netbeans-modules-csl-api"/>
253
<link href="${javadoc.docs.org-netbeans-modules-xml-text}" offline="true" packagelistloc="${netbeans.javadoc.dir}/org-netbeans-modules-xml-text"/>
(-)a/nbbuild/javadoctools/properties.xml (+1 lines)
Lines 248-250 Link Here
248
<property name="javadoc.docs.org-netbeans-modules-docker-api" value="${javadoc.web.root}/org-netbeans-modules-docker-api"/>
248
<property name="javadoc.docs.org-netbeans-modules-docker-api" value="${javadoc.web.root}/org-netbeans-modules-docker-api"/>
249
<property name="javadoc.docs.org-netbeans-modules-csl-types" value="${javadoc.web.root}/org-netbeans-modules-csl-types"/>
249
<property name="javadoc.docs.org-netbeans-modules-csl-types" value="${javadoc.web.root}/org-netbeans-modules-csl-types"/>
250
<property name="javadoc.docs.org-netbeans-modules-csl-api" value="${javadoc.web.root}/org-netbeans-modules-csl-api"/>
250
<property name="javadoc.docs.org-netbeans-modules-csl-api" value="${javadoc.web.root}/org-netbeans-modules-csl-api"/>
251
<property name="javadoc.docs.org-netbeans-modules-xml-text" value="${javadoc.web.root}/org-netbeans-modules-xml-text"/>
(-)a/nbbuild/javadoctools/replaces.xml (+1 lines)
Lines 248-250 Link Here
248
<replacefilter token="@org-netbeans-modules-docker-api@" value="${javadoc.docs.org-netbeans-modules-docker-api}"/>
248
<replacefilter token="@org-netbeans-modules-docker-api@" value="${javadoc.docs.org-netbeans-modules-docker-api}"/>
249
<replacefilter token="@org-netbeans-modules-csl-types@" value="${javadoc.docs.org-netbeans-modules-csl-types}"/>
249
<replacefilter token="@org-netbeans-modules-csl-types@" value="${javadoc.docs.org-netbeans-modules-csl-types}"/>
250
<replacefilter token="@org-netbeans-modules-csl-api@" value="${javadoc.docs.org-netbeans-modules-csl-api}"/>
250
<replacefilter token="@org-netbeans-modules-csl-api@" value="${javadoc.docs.org-netbeans-modules-csl-api}"/>
251
<replacefilter token="@org-netbeans-modules-xml-text@" value="${javadoc.docs.org-netbeans-modules-xml-text}"/>
(-)a/spring.beans/nbproject/project.properties (-2 / +2 lines)
Lines 40-49 Link Here
40
# Version 2 license, then the option applies only if the new code is
40
# Version 2 license, then the option applies only if the new code is
41
# made subject to such option by the copyright holder.
41
# made subject to such option by the copyright holder.
42
42
43
javac.source=1.7
43
javac.source=1.8
44
javac.compilerargs=-Xlint -Xlint:-serial
44
javac.compilerargs=-Xlint -Xlint:-serial
45
45
46
spec.version.base=1.40.0
46
spec.version.base=1.41.0
47
47
48
test.config.stableBTD.includes=**/*Test.class
48
test.config.stableBTD.includes=**/*Test.class
49
test.config.stableBTD.excludes=\
49
test.config.stableBTD.excludes=\
(-)a/spring.beans/nbproject/project.xml (-17 / +33 lines)
Lines 145-150 Link Here
145
                    </run-dependency>
145
                    </run-dependency>
146
                </dependency>
146
                </dependency>
147
                <dependency>
147
                <dependency>
148
                    <code-name-base>org.netbeans.modules.editor.document</code-name-base>
149
                    <build-prerequisite/>
150
                    <compile-dependency/>
151
                    <run-dependency>
152
                        <specification-version>1.0</specification-version>
153
                    </run-dependency>
154
                </dependency>
155
                <dependency>
148
                    <code-name-base>org.netbeans.modules.editor.indent</code-name-base>
156
                    <code-name-base>org.netbeans.modules.editor.indent</code-name-base>
149
                    <build-prerequisite/>
157
                    <build-prerequisite/>
150
                    <compile-dependency/>
158
                    <compile-dependency/>
Lines 172-185 Link Here
172
                    </run-dependency>
180
                    </run-dependency>
173
                </dependency>
181
                </dependency>
174
                <dependency>
182
                <dependency>
175
                    <code-name-base>org.netbeans.modules.editor.document</code-name-base>
176
                    <build-prerequisite/>
177
                    <compile-dependency/>
178
                    <run-dependency>
179
                        <specification-version>1.0</specification-version>
180
                    </run-dependency>
181
                </dependency>
182
                <dependency>
183
                    <code-name-base>org.netbeans.modules.editor.mimelookup</code-name-base>
183
                    <code-name-base>org.netbeans.modules.editor.mimelookup</code-name-base>
184
                    <build-prerequisite/>
184
                    <build-prerequisite/>
185
                    <compile-dependency/>
185
                    <compile-dependency/>
Lines 372-377 Link Here
372
                    </run-dependency>
372
                    </run-dependency>
373
                </dependency>
373
                </dependency>
374
                <dependency>
374
                <dependency>
375
                    <code-name-base>org.netbeans.modules.xml.lexer</code-name-base>
376
                    <build-prerequisite/>
377
                    <compile-dependency/>
378
                    <run-dependency>
379
                        <specification-version>1.30</specification-version>
380
                    </run-dependency>
381
                </dependency>
382
                <dependency>
375
                    <code-name-base>org.netbeans.modules.xml.retriever</code-name-base>
383
                    <code-name-base>org.netbeans.modules.xml.retriever</code-name-base>
376
                    <build-prerequisite/>
384
                    <build-prerequisite/>
377
                    <compile-dependency/>
385
                    <compile-dependency/>
Lines 403-409 Link Here
403
                    <compile-dependency/>
411
                    <compile-dependency/>
404
                    <run-dependency>
412
                    <run-dependency>
405
                        <release-version>2</release-version>
413
                        <release-version>2</release-version>
406
                        <specification-version>1.16</specification-version>
414
                        <specification-version>1.60</specification-version>
407
                    </run-dependency>
415
                    </run-dependency>
408
                </dependency>
416
                </dependency>
409
                <dependency>
417
                <dependency>
Lines 480-493 Link Here
480
                    </run-dependency>
488
                    </run-dependency>
481
                </dependency>
489
                </dependency>
482
                <dependency>
490
                <dependency>
483
                    <code-name-base>org.openide.util.ui</code-name-base>
484
                    <build-prerequisite/>
485
                    <compile-dependency/>
486
                    <run-dependency>
487
                        <specification-version>9.3</specification-version>
488
                    </run-dependency>
489
                </dependency>
490
                <dependency>
491
                    <code-name-base>org.openide.util</code-name-base>
491
                    <code-name-base>org.openide.util</code-name-base>
492
                    <build-prerequisite/>
492
                    <build-prerequisite/>
493
                    <compile-dependency/>
493
                    <compile-dependency/>
Lines 504-509 Link Here
504
                    </run-dependency>
504
                    </run-dependency>
505
                </dependency>
505
                </dependency>
506
                <dependency>
506
                <dependency>
507
                    <code-name-base>org.openide.util.ui</code-name-base>
508
                    <build-prerequisite/>
509
                    <compile-dependency/>
510
                    <run-dependency>
511
                        <specification-version>9.3</specification-version>
512
                    </run-dependency>
513
                </dependency>
514
                <dependency>
507
                    <code-name-base>org.openide.windows</code-name-base>
515
                    <code-name-base>org.openide.windows</code-name-base>
508
                    <build-prerequisite/>
516
                    <build-prerequisite/>
509
                    <compile-dependency/>
517
                    <compile-dependency/>
Lines 582-587 Link Here
582
                        <code-name-base>org.openide.text</code-name-base>
590
                        <code-name-base>org.openide.text</code-name-base>
583
                    </test-dependency>
591
                    </test-dependency>
584
                    <test-dependency>
592
                    <test-dependency>
593
                        <code-name-base>org.netbeans.modules.lexer.nbbridge</code-name-base>
594
                    </test-dependency>
595
                    <test-dependency>
585
                        <code-name-base>org.openide.util.ui</code-name-base>
596
                        <code-name-base>org.openide.util.ui</code-name-base>
586
                        <compile-dependency/>
597
                        <compile-dependency/>
587
                        <test/>
598
                        <test/>
Lines 591-596 Link Here
591
                        <compile-dependency/>
602
                        <compile-dependency/>
592
                        <test/>
603
                        <test/>
593
                    </test-dependency>
604
                    </test-dependency>
605
                    <test-dependency>
606
                        <code-name-base>org.netbeans.modules.editor.mimelookup</code-name-base>
607
                        <compile-dependency/>
608
                        <test/>
609
                    </test-dependency>
594
                </test-type>
610
                </test-type>
595
            </test-dependencies>
611
            </test-dependencies>
596
            <friend-packages>
612
            <friend-packages>
(-)a/spring.beans/src/org/netbeans/modules/spring/beans/completion/CompletionContext.java (-121 / +115 lines)
Lines 48-67 Link Here
48
import java.util.List;
48
import java.util.List;
49
import javax.swing.text.BadLocationException;
49
import javax.swing.text.BadLocationException;
50
import javax.swing.text.Document;
50
import javax.swing.text.Document;
51
import org.netbeans.api.lexer.Token;
52
import org.netbeans.api.lexer.TokenSequence;
53
import org.netbeans.api.xml.lexer.XMLTokenId;
51
import org.netbeans.editor.BaseDocument;
54
import org.netbeans.editor.BaseDocument;
52
import org.netbeans.editor.TokenContextPath;
53
import org.netbeans.editor.TokenID;
54
import org.netbeans.editor.TokenItem;
55
import org.netbeans.modules.editor.NbEditorUtilities;
55
import org.netbeans.modules.editor.NbEditorUtilities;
56
import org.netbeans.modules.spring.beans.editor.DocumentContext;
56
import org.netbeans.modules.spring.beans.editor.DocumentContext;
57
import org.netbeans.modules.xml.text.api.XMLDefaultTokenContext;
57
import org.netbeans.modules.xml.text.api.dom.SyntaxElement;
58
import org.netbeans.modules.xml.text.syntax.SyntaxElement;
58
import org.netbeans.modules.xml.text.api.dom.XMLSyntaxSupport;
59
import org.netbeans.modules.xml.text.syntax.XMLKit;
59
import org.netbeans.modules.xml.text.syntax.XMLKit;
60
import org.netbeans.modules.xml.text.syntax.XMLSyntaxSupport;
61
import org.netbeans.modules.xml.text.syntax.dom.EmptyTag;
62
import org.netbeans.modules.xml.text.syntax.dom.EndTag;
63
import org.netbeans.modules.xml.text.syntax.dom.StartTag;
64
import org.netbeans.modules.xml.text.syntax.dom.Tag;
65
import org.netbeans.spi.editor.completion.CompletionProvider;
60
import org.netbeans.spi.editor.completion.CompletionProvider;
66
import org.openide.filesystems.FileObject;
61
import org.openide.filesystems.FileObject;
67
import org.openide.util.Exceptions;
62
import org.openide.util.Exceptions;
Lines 73-79 Link Here
73
 * @author Rohan Ranade (Rohan.Ranade@Sun.COM)
68
 * @author Rohan Ranade (Rohan.Ranade@Sun.COM)
74
 */
69
 */
75
public class CompletionContext {
70
public class CompletionContext {
76
    private ArrayList<String> existingAttributes;
71
    private List<String> existingAttributes;
77
72
78
    public static enum CompletionType {
73
    public static enum CompletionType {
79
        TAG,
74
        TAG,
Lines 97-106 Link Here
97
        this.caretOffset = caretOffset;
92
        this.caretOffset = caretOffset;
98
        this.fileObject = NbEditorUtilities.getFileObject(doc);
93
        this.fileObject = NbEditorUtilities.getFileObject(doc);
99
        this.queryType = queryType;
94
        this.queryType = queryType;
100
        initContext((BaseDocument) doc);
95
        try {
96
            initContext((BaseDocument) doc);
97
        } catch (BadLocationException ex) {
98
            Exceptions.printStackTrace(ex);
99
        }
101
    }
100
    }
102
101
103
    private void initContext(BaseDocument bDoc) {
102
    private void initContext(BaseDocument bDoc) throws BadLocationException {
104
        boolean copyResult = copyDocument(bDoc, internalDoc);
103
        boolean copyResult = copyDocument(bDoc, internalDoc);
105
        if(!copyResult) {
104
        if(!copyResult) {
106
            return;
105
            return;
Lines 108-164 Link Here
108
107
109
        Object sdp = bDoc.getProperty(Document.StreamDescriptionProperty);
108
        Object sdp = bDoc.getProperty(Document.StreamDescriptionProperty);
110
        internalDoc.putProperty(Document.StreamDescriptionProperty, sdp);
109
        internalDoc.putProperty(Document.StreamDescriptionProperty, sdp);
111
        this.support = (XMLSyntaxSupport) internalDoc.getSyntaxSupport();
110
        this.support = (XMLSyntaxSupport)XMLSyntaxSupport.getSyntaxSupport(internalDoc);
112
        this.documentContext = DocumentContext.create(internalDoc, caretOffset);
111
        this.documentContext = DocumentContext.create(internalDoc, caretOffset);
113
112
114
        // get last inserted character from the actual document
113
        // get last inserted character from the actual document
115
        this.lastTypedChar = ((XMLSyntaxSupport) bDoc.getSyntaxSupport()).lastTypedChar();
114
        this.lastTypedChar = support.lastTypedChar();
116
115
117
        if(documentContext == null) {
116
        if(documentContext == null) {
118
            return;
117
            return;
119
        }
118
        }
120
119
121
        TokenItem token = documentContext.getCurrentToken();
120
        Token<XMLTokenId> token = documentContext.getCurrentToken();
122
        if(token == null) {
121
        if(token == null) {
123
            return;
122
            return;
124
        }
123
        }
125
124
125
        int tOffset = documentContext.getCurrentTokenOffset();
126
        String tokenText = token.text().toString();
127
        XMLTokenId id = token.id();
128
        int tlen = token.length();
129
        
126
        // see issue #191651
130
        // see issue #191651
127
        // ExtSyntaxSupport returns token on base of caretoffset and caretoffset+1 which
131
        // ExtSyntaxSupport returns token on base of caretoffset and caretoffset+1 which
128
        //  returns ERROR token at line ending (just "/" means error). In that cases
132
        //  returns ERROR token at line ending (just "/" means error). In that cases
129
        //  is fake WS token created with position between previous and current error
133
        //  is fake WS token created with position between previous and current error
130
        //  token for purposes of CC. Possibly will be extended about more characters.
134
        //  token for purposes of CC. Possibly will be extended about more characters.
131
        if (token.getTokenID().getNumericID() == XMLDefaultTokenContext.ERROR_ID
135
        if (token.id() == XMLTokenId.ERROR
132
                && token.getImage().equals("/")) {
136
                && token.text().toString().equals("/")) {
133
            token = new WsToken(caretOffset, token);
137
            tokenText = " ";
138
            id = XMLTokenId.WS;
139
            tlen = 1;
140
            tOffset = caretOffset;
134
        }
141
        }
142
        boolean tokenBoundary = (tOffset == caretOffset)
143
                || ((tOffset + tlen) == caretOffset);
135
144
136
        boolean tokenBoundary = (token.getOffset() == caretOffset)
137
                || ((token.getOffset() + token.getImage().length()) == caretOffset);
138
139
        int id = token.getTokenID().getNumericID();
140
        SyntaxElement element = documentContext.getCurrentElement();
145
        SyntaxElement element = documentContext.getCurrentElement();
141
        switch (id) {
146
        switch (id) {
142
            //user enters < character
147
            //user enters < character
143
            case XMLDefaultTokenContext.TEXT_ID:
148
            case TEXT:
144
                String chars = token.getImage().trim();
149
                String chars = tokenText.trim();
145
                TokenItem previousTokenItem = token.getPrevious();
150
                Token<XMLTokenId> previousTokenItem = support.getPreviousToken(tOffset);
146
                if (previousTokenItem == null) {
151
                if (previousTokenItem == null) {
147
                    completionType = CompletionType.NONE;
152
                    completionType = CompletionType.NONE;
148
                    break;
153
                    break;
149
                }
154
                }
155
                String text = previousTokenItem.text().toString().trim();
150
                if (chars != null && chars.equals("") &&
156
                if (chars != null && chars.equals("") &&
151
                        previousTokenItem.getImage().trim().equals("/>")) { // NOI18N
157
                        text.equals("/>")) { // NOI18N
152
                    completionType = CompletionType.NONE;
158
                    completionType = CompletionType.NONE;
153
                    break;
159
                    break;
154
                }
160
                }
155
                if (chars != null && chars.equals("") &&
161
                if (chars != null && chars.equals("") &&
156
                        previousTokenItem.getImage().trim().equals(">")) { // NOI18N
162
                        text.trim().equals(">")) { // NOI18N
157
                    completionType = CompletionType.VALUE;
163
                    completionType = CompletionType.VALUE;
158
                    break;
164
                    break;
159
                }
165
                }
160
                if (chars != null && !chars.equals("<") &&
166
                if (chars != null && !chars.equals("<") &&
161
                        previousTokenItem.getImage().trim().equals(">")) { // NOI18N
167
                        text.trim().equals(">")) { // NOI18N
162
                    completionType = CompletionType.NONE;
168
                    completionType = CompletionType.NONE;
163
                    break;
169
                    break;
164
                }
170
                }
Lines 169-212 Link Here
169
                break;
175
                break;
170
176
171
            //start tag of an element
177
            //start tag of an element
172
            case XMLDefaultTokenContext.TAG_ID:
178
            case TAG:
173
                if (element instanceof EndTag) {
179
                if (support.isEndTag(element)) {
174
                    completionType = CompletionType.NONE;
180
                    completionType = CompletionType.NONE;
175
                    break;
181
                    break;
176
                }
182
                }
177
                if (element instanceof EmptyTag) {
183
                if (support.isEmptyTag(element)) {
178
                    if (token != null &&
184
                    if (tokenText.trim().equals("/>")) { // NOI18N
179
                            token.getImage().trim().equals("/>")) { // NOI18N
185
                        Token<XMLTokenId> prevToken = support.getPreviousToken(tOffset);
180
                        TokenItem prevToken = token.getPrevious();
186
                        if(prevToken != null && prevToken.id() == XMLTokenId.WS
181
                        if(prevToken != null && prevToken.getTokenID().getNumericID() == XMLDefaultTokenContext.WS_ID
187
                                && caretOffset == tOffset) {
182
                                && caretOffset == token.getOffset()) {
183
                            completionType = CompletionType.ATTRIBUTE;
188
                            completionType = CompletionType.ATTRIBUTE;
184
                        } else {
189
                        } else {
185
                            completionType = CompletionType.NONE;
190
                            completionType = CompletionType.NONE;
186
                        }
191
                        }
187
                        break;
192
                        break;
188
                    }
193
                    }
189
                    EmptyTag tag = (EmptyTag) element;
190
                    if (element.getElementOffset() + 1 == this.caretOffset) {
194
                    if (element.getElementOffset() + 1 == this.caretOffset) {
191
                        completionType = CompletionType.TAG;
195
                        completionType = CompletionType.TAG;
192
                        break;
196
                        break;
193
                    }
197
                    }
198
                    String tagName = element.getNode().getNodeName();
194
                    if (caretOffset > element.getElementOffset() + 1 &&
199
                    if (caretOffset > element.getElementOffset() + 1 &&
195
                            caretOffset <= element.getElementOffset() + 1 + tag.getTagName().length()) {
200
                            caretOffset <= element.getElementOffset() + 1 + tagName.length()) {
196
                        completionType = CompletionType.TAG;
201
                        completionType = CompletionType.TAG;
197
                        typedChars = tag.getTagName();
202
                        typedChars = tagName;
198
                        break;
203
                        break;
199
                    }
204
                    }
200
                    completionType = CompletionType.ATTRIBUTE;
205
                    completionType = CompletionType.ATTRIBUTE;
201
                    break;
206
                    break;
202
                }
207
                }
203
208
204
                if (element instanceof StartTag) {
209
                if (support.isStartTag(element)) {
205
                    if (token != null &&
210
                    if (tokenText.toString().trim().equals(">")) { // NOI18N
206
                            token.getImage().trim().equals(">")) { // NOI18N
211
                        Token<XMLTokenId> prevToken = support.getPreviousToken(tOffset);
207
                        TokenItem prevToken = token.getPrevious();
212
                        if(prevToken != null && prevToken.id() == XMLTokenId.WS
208
                        if(prevToken != null && prevToken.getTokenID().getNumericID() == XMLDefaultTokenContext.WS_ID
213
                                && caretOffset == tOffset) {
209
                                && caretOffset == token.getOffset()) {
210
                            completionType = CompletionType.ATTRIBUTE;
214
                            completionType = CompletionType.ATTRIBUTE;
211
                        } else {
215
                        } else {
212
                            completionType = CompletionType.NONE;
216
                            completionType = CompletionType.NONE;
Lines 214-221 Link Here
214
                        break;
218
                        break;
215
                    }
219
                    }
216
                    if (element.getElementOffset() + 1 != this.caretOffset) {
220
                    if (element.getElementOffset() + 1 != this.caretOffset) {
217
                        StartTag tag = (StartTag) element;
221
                        typedChars = element.getNode().getNodeName();
218
                        typedChars = tag.getTagName();
219
                    }
222
                    }
220
                }
223
                }
221
                if (lastTypedChar == '>') {
224
                if (lastTypedChar == '>') {
Lines 226-268 Link Here
226
                break;
229
                break;
227
230
228
            //user enters an attribute name
231
            //user enters an attribute name
229
            case XMLDefaultTokenContext.ARGUMENT_ID:
232
            case ARGUMENT:
230
                completionType = CompletionType.ATTRIBUTE;
233
                completionType = CompletionType.ATTRIBUTE;
231
                typedChars = token.getImage().substring(0, caretOffset - token.getOffset());;
234
                typedChars = tokenText.substring(0, caretOffset - tOffset);
232
                break;
235
                break;
233
236
234
            //some random character
237
            //some random character
235
            case XMLDefaultTokenContext.CHARACTER_ID:
238
            case CHARACTER:
236
            //user enters = character, we should ignore all other operators
239
            //user enters = character, we should ignore all other operators
237
            case XMLDefaultTokenContext.OPERATOR_ID:
240
            case OPERATOR:
238
                completionType = CompletionType.NONE;
241
                completionType = CompletionType.NONE;
239
                break;
242
                break;
240
            //user enters either ' or "
243
            //user enters either ' or "
241
            case XMLDefaultTokenContext.VALUE_ID:
244
            case VALUE:
242
                if(!tokenBoundary) {
245
                if(!tokenBoundary) {
243
                    completionType = CompletionType.ATTRIBUTE_VALUE;
246
                    completionType = CompletionType.ATTRIBUTE_VALUE;
244
                    typedChars = token.getImage().substring(1, caretOffset - token.getOffset());
247
                    typedChars = tokenText.subSequence(1, caretOffset - tOffset).toString();
245
                } else {
248
                } else {
246
                    completionType = CompletionType.NONE;
249
                    completionType = CompletionType.NONE;
247
                }
250
                }
248
                break;
251
                break;
249
252
250
            //user enters white-space character
253
            //user enters white-space character
251
            case XMLDefaultTokenContext.WS_ID:
254
            case WS:
252
                completionType = CompletionType.NONE;
255
                completionType = CompletionType.NONE;
253
256
                int[] offset = new int[1];
254
                TokenItem prev = token.getPrevious();
257
                Token<XMLTokenId> prev = support.runWithSequence(tOffset,
255
                while (prev != null &&
258
                    (TokenSequence ts) -> {
256
                        (prev.getTokenID().getNumericID() == XMLDefaultTokenContext.WS_ID)) {
259
                        Token<XMLTokenId> t  = null;
257
                    prev = prev.getPrevious();
260
                        boolean ok;
261
                        while ((ok = ts.movePrevious())) {
262
                            t = ts.token();
263
                            if (t.id() != XMLTokenId.WS) {
264
                                break;
265
                            }
266
                        }
267
                        if (ok) {
268
                            offset[0] = ts.offset();
269
                            return t;
270
                        } else {
271
                            return null;
272
                        }
273
                    }
274
                );
275
                if (prev == null) {
276
                    completionType = CompletionType.NONE;
277
                    break;
258
                }
278
                }
259
279
                int prevOffset = offset[0];
260
                if(prev.getTokenID().getNumericID() == XMLDefaultTokenContext.ARGUMENT_ID
280
                if(prev.id() == XMLTokenId.ARGUMENT
261
                        && prev.getOffset() + prev.getImage().length() == caretOffset) {
281
                        && prevOffset + prev.length() == caretOffset) {
262
                    typedChars = prev.getImage();
282
                    typedChars = prev.text().toString();
263
                    completionType = CompletionType.ATTRIBUTE;
283
                    completionType = CompletionType.ATTRIBUTE;
264
                } else if (((prev.getTokenID().getNumericID() == XMLDefaultTokenContext.VALUE_ID) ||
284
                } else if (((prev.id() == XMLTokenId.VALUE) ||
265
                        (prev.getTokenID().getNumericID() == XMLDefaultTokenContext.TAG_ID))
285
                        (prev.id() == XMLTokenId.TAG))
266
                        && !tokenBoundary) {
286
                        && !tokenBoundary) {
267
                    completionType = CompletionType.ATTRIBUTE;
287
                    completionType = CompletionType.ATTRIBUTE;
268
                }
288
                }
Lines 286-291 Link Here
286
                    try {
306
                    try {
287
                        String docText = src.getText(0, src.getLength());
307
                        String docText = src.getText(0, src.getLength());
288
                        dest.insertString(0, docText, null);
308
                        dest.insertString(0, docText, null);
309
//                        dest.putProperty(Language.class, src.getProperty(Language.class));
289
                    } catch(BadLocationException ble) {
310
                    } catch(BadLocationException ble) {
290
                        Exceptions.printStackTrace(ble);
311
                        Exceptions.printStackTrace(ble);
291
                        retVal[0] = false;
312
                        retVal[0] = false;
Lines 321-349 Link Here
321
342
322
    public Node getTag() {
343
    public Node getTag() {
323
        SyntaxElement element = documentContext.getCurrentElement();
344
        SyntaxElement element = documentContext.getCurrentElement();
324
        return (element instanceof Tag) ? (Node) element : null;
345
        return element.getType() == Node.ELEMENT_NODE ? element.getNode() : null;
325
    }
346
    }
326
347
327
    public TokenItem getCurrentToken() {
348
    public Token<XMLTokenId> getCurrentToken() {
328
        return documentContext.getCurrentToken();
349
        return documentContext.getCurrentToken();
329
    }
350
    }
351
    
352
    public int getCurrentTokenOffset() {
353
        return documentContext.getCurrentTokenOffset();
354
    }
355
    
356
    private List<String> getExistingAttributesLocked(TokenSequence ts) {
357
        List<String> existingAttributes = new ArrayList<String>();
358
        while (ts.movePrevious()) {
359
            Token<XMLTokenId> item = ts.token();
360
            XMLTokenId tokenId = item.id();
361
            if (tokenId == XMLTokenId.TAG) {
362
                break;
363
            }
364
            if (tokenId == XMLTokenId.ARGUMENT) {
365
                existingAttributes.add(item.text().toString());
366
            }
367
        }
368
        return existingAttributes;
369
    }
330
370
331
    public List<String> getExistingAttributes() {
371
    public List<String> getExistingAttributes() {
332
        if (existingAttributes == null) {
372
        if (existingAttributes == null) {
333
            existingAttributes = new ArrayList<String>();
373
            try {
334
            TokenItem item = documentContext.getCurrentToken().getPrevious();
374
                existingAttributes = (List<String>)support.runWithSequence(
335
            while (item != null) {
375
                        documentContext.getCurrentTokenOffset(),
336
                int tokenId = item.getTokenID().getNumericID();
376
                        this::getExistingAttributesLocked
337
                if (tokenId == XMLDefaultTokenContext.TAG_ID) {
377
                );
338
                    break;
378
            } catch (BadLocationException ex) {
339
                }
379
                Exceptions.printStackTrace(ex);
340
                if (tokenId == XMLDefaultTokenContext.ARGUMENT_ID) {
341
                    existingAttributes.add(item.getImage());
342
                }
343
                item = item.getPrevious();
344
            }
380
            }
345
        }
381
        }
346
347
        return existingAttributes;
382
        return existingAttributes;
348
    }
383
    }
349
384
Lines 362-406 Link Here
362
    public Document getDocument() {
397
    public Document getDocument() {
363
        return internalDoc;
398
        return internalDoc;
364
    }
399
    }
365
366
    private class WsToken implements TokenItem {
367
368
        private final int caretOffset;
369
        private final TokenItem currentToken;
370
371
        public WsToken(int caretOffset, TokenItem currentToken) {
372
            this.caretOffset = caretOffset;
373
            this.currentToken = currentToken;
374
        }
375
376
        @Override
377
        public TokenID getTokenID() {
378
            return XMLDefaultTokenContext.WS;
379
        }
380
381
        @Override
382
        public TokenContextPath getTokenContextPath() {
383
            return currentToken.getTokenContextPath();
384
        }
385
386
        @Override
387
        public int getOffset() {
388
            return caretOffset;
389
        }
390
391
        @Override
392
        public String getImage() {
393
            return " ";
394
        }
395
396
        @Override
397
        public TokenItem getNext() {
398
            return currentToken;
399
        }
400
401
        @Override
402
        public TokenItem getPrevious() {
403
            return currentToken.getPrevious();
404
        }
405
    }
406
}
400
}
(-)a/spring.beans/src/org/netbeans/modules/spring/beans/completion/CompletorRegistry.java (-3 / +4 lines)
Lines 55-61 Link Here
55
import org.netbeans.modules.spring.beans.completion.completors.AttributeValueCompletorFactory;
55
import org.netbeans.modules.spring.beans.completion.completors.AttributeValueCompletorFactory;
56
import java.util.HashMap;
56
import java.util.HashMap;
57
import java.util.Map;
57
import java.util.Map;
58
import org.netbeans.editor.TokenItem;
58
import org.netbeans.api.lexer.Token;
59
import org.netbeans.api.xml.lexer.XMLTokenId;
59
import org.netbeans.modules.spring.beans.BeansAttributes;
60
import org.netbeans.modules.spring.beans.BeansAttributes;
60
import org.netbeans.modules.spring.beans.BeansElements;
61
import org.netbeans.modules.spring.beans.BeansElements;
61
import org.netbeans.modules.spring.beans.completion.completors.BeanDependsOnCompletor;
62
import org.netbeans.modules.spring.beans.completion.completors.BeanDependsOnCompletor;
Lines 177-184 Link Here
177
    
178
    
178
    private Completor getAttributeValueCompletor(CompletionContext context) {
179
    private Completor getAttributeValueCompletor(CompletionContext context) {
179
        String tagName = extractVanilaTagName(context.getTag().getNodeName());
180
        String tagName = extractVanilaTagName(context.getTag().getNodeName());
180
        TokenItem attrib = ContextUtilities.getAttributeToken(context.getCurrentToken());
181
        Token<XMLTokenId> attrib = ContextUtilities.getAttributeToken(context.getDocumentContext());
181
        String attribName = attrib != null ? attrib.getImage() : null;
182
        String attribName = attrib != null ? attrib.text().toString(): null;
182
        CompletorFactory completorFactory = locateCompletorFactory(tagName, attribName);
183
        CompletorFactory completorFactory = locateCompletorFactory(tagName, attribName);
183
        if (completorFactory != null) {
184
        if (completorFactory != null) {
184
            Completor completor = completorFactory.createCompletor(context.getCaretOffset());
185
            Completor completor = completorFactory.createCompletor(context.getCaretOffset());
(-)a/spring.beans/src/org/netbeans/modules/spring/beans/completion/SpringXMLConfigCompletionProvider.java (-7 / +11 lines)
Lines 55-63 Link Here
55
import org.netbeans.modules.spring.beans.completion.CompletionContext.CompletionType;
55
import org.netbeans.modules.spring.beans.completion.CompletionContext.CompletionType;
56
import org.netbeans.modules.spring.beans.editor.DocumentContext;
56
import org.netbeans.modules.spring.beans.editor.DocumentContext;
57
import org.netbeans.modules.spring.beans.index.SpringIndex;
57
import org.netbeans.modules.spring.beans.index.SpringIndex;
58
import org.netbeans.modules.xml.text.syntax.SyntaxElement;
58
import org.netbeans.modules.xml.text.api.dom.SyntaxElement;
59
import org.netbeans.modules.xml.text.syntax.XMLSyntaxSupport;
59
import org.netbeans.modules.xml.text.api.dom.TagElement;
60
import org.netbeans.modules.xml.text.syntax.dom.StartTag;
60
import org.netbeans.modules.xml.text.api.dom.XMLSyntaxSupport;
61
import org.netbeans.spi.editor.completion.CompletionProvider;
61
import org.netbeans.spi.editor.completion.CompletionProvider;
62
import org.netbeans.spi.editor.completion.CompletionResultSet;
62
import org.netbeans.spi.editor.completion.CompletionResultSet;
63
import org.netbeans.spi.editor.completion.CompletionTask;
63
import org.netbeans.spi.editor.completion.CompletionTask;
Lines 66-71 Link Here
66
import org.openide.filesystems.FileObject;
66
import org.openide.filesystems.FileObject;
67
import org.openide.util.Exceptions;
67
import org.openide.util.Exceptions;
68
import org.w3c.dom.Attr;
68
import org.w3c.dom.Attr;
69
import org.w3c.dom.NamedNodeMap;
70
import org.w3c.dom.Node;
69
71
70
/**
72
/**
71
 * 
73
 * 
Lines 224-230 Link Here
224
226
225
        void updateSchemaLocation(Document doc, final int offset, final String namespace, final String schemaLocation) {
227
        void updateSchemaLocation(Document doc, final int offset, final String namespace, final String schemaLocation) {
226
                BaseDocument baseDoc = (BaseDocument) doc;
228
                BaseDocument baseDoc = (BaseDocument) doc;
227
                final XMLSyntaxSupport syntaxSupport = (XMLSyntaxSupport) baseDoc.getSyntaxSupport();
229
                final XMLSyntaxSupport syntaxSupport = XMLSyntaxSupport.getSyntaxSupport(doc);
228
230
229
                baseDoc.runAtomic(new Runnable() {
231
                baseDoc.runAtomic(new Runnable() {
230
232
Lines 232-242 Link Here
232
                    public void run() {
234
                    public void run() {
233
                        try {
235
                        try {
234
                            SyntaxElement element = syntaxSupport.getElementChain(offset);
236
                            SyntaxElement element = syntaxSupport.getElementChain(offset);
235
                            if (element instanceof StartTag) {
237
                            if (element.getType() == Node.ELEMENT_NODE &&
236
                                Attr attr = ((StartTag) element).getAttributeNode("xsi:schemaLocation");    //NOI18N
238
                                ((TagElement)element).isStart()) {
239
                                NamedNodeMap nnm = element.getNode().getAttributes();
240
                                Attr attr = (Attr)nnm.getNamedItem("xsi:schemaLocation");    //NOI18N
237
                                if (attr != null) {
241
                                if (attr != null) {
238
                                    String val = attr.getValue();
242
                                    String val = attr.getValue();
239
                                    if (val.indexOf(namespace) == -1) {
243
                                    if (!val.contains(namespace)) {
240
                                        attr.setValue(val + "\n       " + namespace + " " + schemaLocation);    //NOI18N
244
                                        attr.setValue(val + "\n       " + namespace + " " + schemaLocation);    //NOI18N
241
                                    }
245
                                    }
242
                                }
246
                                }
(-)a/spring.beans/src/org/netbeans/modules/spring/beans/completion/completors/AttributeValueCompletor.java (-1 / +1 lines)
Lines 67-73 Link Here
67
67
68
    @Override
68
    @Override
69
    protected int initAnchorOffset(CompletionContext context) {
69
    protected int initAnchorOffset(CompletionContext context) {
70
        return context.getCurrentToken().getOffset() + 1;
70
        return context.getCurrentTokenOffset() + 1;
71
    }
71
    }
72
    
72
    
73
    @Override
73
    @Override
(-)a/spring.beans/src/org/netbeans/modules/spring/beans/completion/completors/BeanDependsOnCompletor.java (-2 / +2 lines)
Lines 65-71 Link Here
65
65
66
    @Override
66
    @Override
67
    protected int initAnchorOffset(CompletionContext context) {
67
    protected int initAnchorOffset(CompletionContext context) {
68
        int index = context.getCurrentToken().getOffset() + 1;
68
        int index = context.getCurrentTokenOffset() + 1;
69
        String prefix = context.getTypedPrefix();
69
        String prefix = context.getTypedPrefix();
70
        if (StringUtils.hasText(prefix)) {
70
        if (StringUtils.hasText(prefix)) {
71
            int sepOffset = Math.max(Math.max(prefix.lastIndexOf(','), prefix.lastIndexOf(';')), prefix.lastIndexOf(' ')); // NOI18N
71
            int sepOffset = Math.max(Math.max(prefix.lastIndexOf(','), prefix.lastIndexOf(';')), prefix.lastIndexOf(' ')); // NOI18N
Lines 97-103 Link Here
97
            return Collections.emptySet();
97
            return Collections.emptySet();
98
        }
98
        }
99
        
99
        
100
        int startIdx = context.getCurrentToken().getOffset() + 1;
100
        int startIdx = context.getCurrentTokenOffset() + 1;
101
        int length = getAnchorOffset() - startIdx;
101
        int length = getAnchorOffset() - startIdx;
102
        
102
        
103
        if(length <= 0) {
103
        if(length <= 0) {
(-)a/spring.beans/src/org/netbeans/modules/spring/beans/completion/completors/BeanIdCompletor.java (-1 / +1 lines)
Lines 84-90 Link Here
84
84
85
    @Override
85
    @Override
86
    protected int initAnchorOffset(CompletionContext context) {
86
    protected int initAnchorOffset(CompletionContext context) {
87
        return context.getCurrentToken().getOffset() + 1;
87
        return context.getCurrentTokenOffset() + 1;
88
    }
88
    }
89
89
90
    @Override
90
    @Override
(-)a/spring.beans/src/org/netbeans/modules/spring/beans/completion/completors/BeansRefCompletor.java (-1 / +1 lines)
Lines 77-83 Link Here
77
77
78
    @Override
78
    @Override
79
    protected int initAnchorOffset(CompletionContext context) {
79
    protected int initAnchorOffset(CompletionContext context) {
80
        return context.getCurrentToken().getOffset() + 1;
80
        return context.getCurrentTokenOffset() + 1;
81
    }
81
    }
82
    
82
    
83
    @Override
83
    @Override
(-)a/spring.beans/src/org/netbeans/modules/spring/beans/completion/completors/JavaClassCompletor.java (-3 / +3 lines)
Lines 86-92 Link Here
86
86
87
    @Override
87
    @Override
88
    protected int initAnchorOffset(CompletionContext context) {
88
    protected int initAnchorOffset(CompletionContext context) {
89
        int idx = context.getCurrentToken().getOffset() + 1;
89
        int idx = context.getCurrentTokenOffset() + 1;
90
        String typedChars = context.getTypedPrefix();
90
        String typedChars = context.getTypedPrefix();
91
        if(typedChars.contains(".") || typedChars.equals("")) { 
91
        if(typedChars.contains(".") || typedChars.equals("")) { 
92
            int dotIndex = typedChars.lastIndexOf(".");
92
            int dotIndex = typedChars.lastIndexOf(".");
Lines 106-114 Link Here
106
        }
106
        }
107
107
108
        if (typedChars.contains(".") || typedChars.equals("")) { // Switch to normal completion
108
        if (typedChars.contains(".") || typedChars.equals("")) { // Switch to normal completion
109
            doNormalJavaCompletion(js, typedChars, context.getCurrentToken().getOffset() + 1);
109
            doNormalJavaCompletion(js, typedChars, context.getCurrentTokenOffset() + 1);
110
        } else { // Switch to smart class path completion
110
        } else { // Switch to smart class path completion
111
            doSmartJavaCompletion(js, typedChars, context.getCurrentToken().getOffset() + 1, context.getQueryType());
111
            doSmartJavaCompletion(js, typedChars, context.getCurrentTokenOffset() + 1, context.getQueryType());
112
        }
112
        }
113
    }
113
    }
114
    
114
    
(-)a/spring.beans/src/org/netbeans/modules/spring/beans/completion/completors/JavaMethodCompletor.java (-1 / +1 lines)
Lines 74-80 Link Here
74
74
75
    @Override
75
    @Override
76
    protected int initAnchorOffset(CompletionContext context) {
76
    protected int initAnchorOffset(CompletionContext context) {
77
        return context.getCurrentToken().getOffset() + 1;
77
        return context.getCurrentTokenOffset() + 1;
78
    }
78
    }
79
79
80
    @Override
80
    @Override
(-)a/spring.beans/src/org/netbeans/modules/spring/beans/completion/completors/JavaPackageCompletor.java (-2 / +2 lines)
Lines 71-77 Link Here
71
71
72
    @Override
72
    @Override
73
    protected int initAnchorOffset(CompletionContext context) {
73
    protected int initAnchorOffset(CompletionContext context) {
74
        int idx = context.getCurrentToken().getOffset() + 1;
74
        int idx = context.getCurrentTokenOffset() + 1;
75
        String typedChars = context.getTypedPrefix();
75
        String typedChars = context.getTypedPrefix();
76
        if (typedChars.contains(".") || typedChars.equals("")) {
76
        if (typedChars.contains(".") || typedChars.equals("")) {
77
            int dotIndex = typedChars.lastIndexOf(".");
77
            int dotIndex = typedChars.lastIndexOf(".");
Lines 89-95 Link Here
89
            return;
89
            return;
90
        }
90
        }
91
91
92
        doPackageCompletion(js, typedChars, context.getCurrentToken().getOffset() + 1);
92
        doPackageCompletion(js, typedChars, context.getCurrentTokenOffset() + 1);
93
    }
93
    }
94
94
95
    private void doPackageCompletion(JavaSource js, final String typedPrefix, final int substitutionOffset) throws IOException {
95
    private void doPackageCompletion(JavaSource js, final String typedPrefix, final int substitutionOffset) throws IOException {
(-)a/spring.beans/src/org/netbeans/modules/spring/beans/completion/completors/PNamespaceBeanRefCompletor.java (-4 / +5 lines)
Lines 43-49 Link Here
43
43
44
import java.io.IOException;
44
import java.io.IOException;
45
import java.util.List;
45
import java.util.List;
46
import org.netbeans.editor.TokenItem;
46
import org.netbeans.api.lexer.Token;
47
import org.netbeans.api.xml.lexer.XMLTokenId;
47
import org.netbeans.modules.spring.beans.completion.CompletionContext;
48
import org.netbeans.modules.spring.beans.completion.CompletionContext;
48
import org.netbeans.modules.spring.beans.completion.Completor;
49
import org.netbeans.modules.spring.beans.completion.Completor;
49
import org.netbeans.modules.spring.beans.completion.CompletorUtils;
50
import org.netbeans.modules.spring.beans.completion.CompletorUtils;
Lines 63-79 Link Here
63
64
64
    @Override
65
    @Override
65
    protected int initAnchorOffset(CompletionContext context) {
66
    protected int initAnchorOffset(CompletionContext context) {
66
        return context.getCurrentToken().getOffset() + 1;
67
        return context.getCurrentTokenOffset() + 1;
67
    }
68
    }
68
69
69
    @Override
70
    @Override
70
    protected void compute(CompletionContext context) throws IOException {
71
    protected void compute(CompletionContext context) throws IOException {
71
        TokenItem attribToken = ContextUtilities.getAttributeToken(context.getCurrentToken());
72
        Token<XMLTokenId> attribToken = ContextUtilities.getAttributeToken(context.getDocumentContext());
72
        if (attribToken == null) {
73
        if (attribToken == null) {
73
            return;
74
            return;
74
        }
75
        }
75
76
76
        String attribName = attribToken.getImage();
77
        String attribName = attribToken.text().toString();
77
        if (!ContextUtilities.isPNamespaceName(context.getDocumentContext(), attribName)) {
78
        if (!ContextUtilities.isPNamespaceName(context.getDocumentContext(), attribName)) {
78
            return;
79
            return;
79
        }
80
        }
(-)a/spring.beans/src/org/netbeans/modules/spring/beans/completion/completors/PropertyCompletor.java (-3 / +3 lines)
Lines 63-69 Link Here
63
import org.netbeans.modules.spring.java.Property;
63
import org.netbeans.modules.spring.java.Property;
64
import org.netbeans.modules.spring.java.PropertyFinder;
64
import org.netbeans.modules.spring.java.PropertyFinder;
65
import org.netbeans.modules.spring.java.PropertyType;
65
import org.netbeans.modules.spring.java.PropertyType;
66
import org.netbeans.modules.xml.text.syntax.dom.Tag;
66
import org.w3c.dom.Node;
67
67
68
/**
68
/**
69
 *
69
 *
Lines 77-83 Link Here
77
77
78
    @Override
78
    @Override
79
    protected int initAnchorOffset(CompletionContext context) {
79
    protected int initAnchorOffset(CompletionContext context) {
80
        int idx = context.getCurrentToken().getOffset() + 1;
80
        int idx = context.getCurrentTokenOffset() + 1;
81
        String typedPrefix = context.getTypedPrefix();
81
        String typedPrefix = context.getTypedPrefix();
82
        int offset = typedPrefix.lastIndexOf('.'); // NOI18N
82
        int offset = typedPrefix.lastIndexOf('.'); // NOI18N
83
        return idx + offset + 1;
83
        return idx + offset + 1;
Lines 97-103 Link Here
97
        js.runUserActionTask(new Task<CompilationController>() {
97
        js.runUserActionTask(new Task<CompilationController>() {
98
98
99
            public void run(CompilationController cc) throws Exception {
99
            public void run(CompilationController cc) throws Exception {
100
                Tag beanTag = (Tag) SpringXMLConfigEditorUtils.getBean(context.getTag());
100
                Node beanTag = SpringXMLConfigEditorUtils.getBean(context.getTag());
101
                if (beanTag == null) {
101
                if (beanTag == null) {
102
                    return;
102
                    return;
103
                }
103
                }
(-)a/spring.beans/src/org/netbeans/modules/spring/beans/completion/completors/ResourceCompletor.java (-1 / +1 lines)
Lines 63-69 Link Here
63
63
64
    @Override
64
    @Override
65
    protected int initAnchorOffset(CompletionContext context) {
65
    protected int initAnchorOffset(CompletionContext context) {
66
        int idx = context.getCurrentToken().getOffset() + 1;
66
        int idx = context.getCurrentTokenOffset() + 1;
67
        String typedChars = context.getTypedPrefix();
67
        String typedChars = context.getTypedPrefix();
68
        int lastSlashIndex = typedChars.lastIndexOf("/"); // NOI18N
68
        int lastSlashIndex = typedChars.lastIndexOf("/"); // NOI18N
69
        return idx + lastSlashIndex + 1;
69
        return idx + lastSlashIndex + 1;
(-)a/spring.beans/src/org/netbeans/modules/spring/beans/editor/ContextUtilities.java (-63 / +23 lines)
Lines 44-56 Link Here
44
44
45
package org.netbeans.modules.spring.beans.editor;
45
package org.netbeans.modules.spring.beans.editor;
46
46
47
import javax.swing.text.BadLocationException;
47
import javax.xml.XMLConstants;
48
import javax.xml.XMLConstants;
48
import org.netbeans.editor.TokenItem;
49
import org.netbeans.api.lexer.Token;
49
import org.netbeans.modules.xml.text.api.XMLDefaultTokenContext;
50
import org.netbeans.api.lexer.TokenSequence;
50
import org.netbeans.modules.xml.text.syntax.SyntaxElement;
51
import org.netbeans.api.xml.lexer.XMLTokenId;
51
import org.netbeans.modules.xml.text.syntax.dom.EmptyTag;
52
import org.netbeans.modules.xml.text.api.dom.SyntaxElement;
52
import org.netbeans.modules.xml.text.syntax.dom.StartTag;
53
import org.netbeans.modules.xml.text.api.dom.TagElement;
53
import org.netbeans.modules.xml.text.syntax.dom.Tag;
54
import org.openide.util.Exceptions;
55
import org.w3c.dom.Node;
54
56
55
/**
57
/**
56
 *
58
 *
Lines 74-82 Link Here
74
        return false;
76
        return false;
75
    }
77
    }
76
    
78
    
77
    public static boolean isValueToken(TokenItem currentToken) {
79
    public static boolean isValueToken(Token<XMLTokenId> currentToken) {
78
        if(currentToken != null) {
80
        if(currentToken != null) {
79
            if (currentToken.getTokenID().getNumericID() == XMLDefaultTokenContext.VALUE_ID) {
81
            if (currentToken.id() == XMLTokenId.VALUE) {
80
                return true;
82
                return true;
81
            }
83
            }
82
        }
84
        }
Lines 84-92 Link Here
84
        return false;
86
        return false;
85
    }
87
    }
86
    
88
    
87
    public static boolean isTagToken(TokenItem currentToken) {
89
    public static boolean isTagToken(Token<XMLTokenId> currentToken) {
88
        if(currentToken != null) {
90
        if(currentToken != null) {
89
            if (currentToken.getTokenID().getNumericID() == XMLDefaultTokenContext.TAG_ID) {
91
            if (currentToken.id() == XMLTokenId.TAG) {
90
                return true;
92
                return true;
91
            }
93
            }
92
        }
94
        }
Lines 94-102 Link Here
94
        return false;
96
        return false;
95
    }
97
    }
96
    
98
    
97
    public static boolean isAttributeToken(TokenItem currentToken) {
99
    public static boolean isAttributeToken(Token<XMLTokenId> currentToken) {
98
        if(currentToken != null) {
100
        if(currentToken != null) {
99
            if (currentToken.getTokenID().getNumericID() == XMLDefaultTokenContext.ARGUMENT_ID) {
101
            if (currentToken.id() == XMLTokenId.ARGUMENT) {
100
                return true;
102
                return true;
101
            }
103
            }
102
        }
104
        }
Lines 104-160 Link Here
104
        return false;
106
        return false;
105
    }
107
    }
106
    
108
    
107
    public static TokenItem getAttributeToken(TokenItem currentToken) {
109
    public static Token<XMLTokenId> getAttributeToken(DocumentContext context) {
108
        if(isValueToken(currentToken)) {
110
        return context.getSyntaxSupport().getAttributeToken(context.getCurrentTokenOffset());
109
            TokenItem equalsToken = currentToken.getPrevious();
110
            while(equalsToken.getTokenID().getNumericID() != XMLDefaultTokenContext.OPERATOR_ID) {
111
                equalsToken = equalsToken.getPrevious();
112
            }
113
        
114
            TokenItem argumentToken = equalsToken.getPrevious();
115
            while(argumentToken.getTokenID().getNumericID() != XMLDefaultTokenContext.ARGUMENT_ID) {
116
                argumentToken = argumentToken.getPrevious();
117
            }
118
        
119
            return argumentToken;
120
        }
121
        
122
        return null;
123
    }
124
  
125
    public static Tag getCurrentTagElement(DocumentContext context) {
126
        SyntaxElement element = context.getCurrentElement();
127
        if(element instanceof StartTag) {
128
            return (StartTag) element;
129
        } else if(element instanceof EmptyTag) {
130
            return (EmptyTag) element;
131
        }
132
        
133
        return null;
134
    }
135
    
136
    public static TokenItem getAttributeToken(DocumentContext context) {
137
        if(isValueToken(context.getCurrentToken())) {
138
            TokenItem equalsToken = context.getCurrentToken().getPrevious();
139
            while(equalsToken.getTokenID().getNumericID() != XMLDefaultTokenContext.OPERATOR_ID) {
140
                equalsToken = equalsToken.getPrevious();
141
            }
142
        
143
            TokenItem argumentToken = equalsToken.getPrevious();
144
            while(argumentToken.getTokenID().getNumericID() != XMLDefaultTokenContext.ARGUMENT_ID) {
145
                argumentToken = argumentToken.getPrevious();
146
            }
147
        
148
            return argumentToken;
149
        }
150
        
151
        return null;
152
    }
111
    }
153
    
112
    
154
    public static String getAttributeTokenImage(DocumentContext context) {
113
    public static String getAttributeTokenImage(DocumentContext context) {
155
        TokenItem tok = getAttributeToken(context);
114
        Token<XMLTokenId> tok = getAttributeToken(context);
156
        if(tok != null) {
115
        if(tok != null) {
157
            return tok.getImage();
116
            return tok.text().toString();
158
        }
117
        }
159
        
118
        
160
        return null;
119
        return null;
Lines 203-213 Link Here
203
        return nodeName.substring(0, colonIndex);
162
        return nodeName.substring(0, colonIndex);
204
    }
163
    }
205
    
164
    
206
    public static StartTag getRoot(SyntaxElement se) {
165
    public static SyntaxElement getRoot(SyntaxElement se) {
207
        StartTag root = null;
166
        SyntaxElement root = null;
208
        while( se != null) {
167
        while( se != null) {
209
            if(se instanceof StartTag) {
168
            if(se.getType() == Node.ELEMENT_NODE &&
210
                root = (StartTag)se;
169
               ((TagElement)se).isStart()) {
170
                root = se;
211
            }
171
            }
212
            se = se.getPrevious();
172
            se = se.getPrevious();
213
        }
173
        }
(-)a/spring.beans/src/org/netbeans/modules/spring/beans/editor/DocumentContext.java (-21 / +42 lines)
Lines 50-62 Link Here
50
import java.util.Map.Entry;
50
import java.util.Map.Entry;
51
import javax.swing.text.BadLocationException;
51
import javax.swing.text.BadLocationException;
52
import javax.swing.text.Document;
52
import javax.swing.text.Document;
53
import org.netbeans.editor.BaseDocument;
53
import org.netbeans.api.lexer.Token;
54
import org.netbeans.editor.TokenItem;
54
import org.netbeans.api.lexer.TokenSequence;
55
import org.netbeans.modules.xml.text.syntax.SyntaxElement;
55
import org.netbeans.api.xml.lexer.XMLTokenId;
56
import org.netbeans.modules.xml.text.syntax.XMLSyntaxSupport;
56
import org.netbeans.modules.xml.text.api.dom.SyntaxElement;
57
import org.netbeans.modules.xml.text.syntax.dom.EmptyTag;
57
import org.netbeans.modules.xml.text.api.dom.XMLSyntaxSupport;
58
import org.netbeans.modules.xml.text.syntax.dom.StartTag;
59
import org.netbeans.modules.xml.text.syntax.dom.Tag;
60
import org.w3c.dom.Attr;
58
import org.w3c.dom.Attr;
61
import org.w3c.dom.NamedNodeMap;
59
import org.w3c.dom.NamedNodeMap;
62
import org.w3c.dom.Node;
60
import org.w3c.dom.Node;
Lines 72-78 Link Here
72
    private XMLSyntaxSupport syntaxSupport;
70
    private XMLSyntaxSupport syntaxSupport;
73
    private int caretOffset = -1;
71
    private int caretOffset = -1;
74
    private SyntaxElement element;
72
    private SyntaxElement element;
75
    private TokenItem token;
73
    private Token<XMLTokenId> token;
74
    private int tokenOffset;
76
    private HashMap<String, String> declaredNamespaces =
75
    private HashMap<String, String> declaredNamespaces =
77
            new HashMap<String, String>();
76
            new HashMap<String, String>();
78
77
Lines 86-112 Link Here
86
    
85
    
87
    private DocumentContext(Document document, int caretOffset) throws BadLocationException {
86
    private DocumentContext(Document document, int caretOffset) throws BadLocationException {
88
        this.document = document;
87
        this.document = document;
89
        this.syntaxSupport = (XMLSyntaxSupport) ((BaseDocument) document).getSyntaxSupport();
88
        this.syntaxSupport = XMLSyntaxSupport.getSyntaxSupport(document);
90
        this.caretOffset = caretOffset;
89
        this.caretOffset = caretOffset;
91
        initialize();
90
        initialize();
92
    }
91
    }
93
92
94
    private void initialize() throws BadLocationException {
93
    private void initialize() throws BadLocationException {
95
        element = syntaxSupport.getElementChain(caretOffset);
94
        element = syntaxSupport.getElementChain(caretOffset);
96
        token = syntaxSupport.getTokenChain(caretOffset, Math.min(document.getLength(), caretOffset + 1));
95
        syntaxSupport.runWithSequence(caretOffset, 
96
            (TokenSequence ts) -> {
97
                token = syntaxSupport.getNextToken(caretOffset);
98
                tokenOffset = ts.offset();
99
                return null;
100
            }
101
        );
97
        populateNamespaces();
102
        populateNamespaces();
98
    }
103
    }
99
104
    
100
    public int getCurrentTokenId() {
105
    public XMLSyntaxSupport getSyntaxSupport() {
101
        return token.getTokenID().getNumericID();
106
        return syntaxSupport;
107
    }
108
    
109
    public <T> T runWithTokenSequence(int offset, XMLSyntaxSupport.SequenceCallable<T> callable) throws BadLocationException {
110
        return syntaxSupport.runWithSequence(offset, callable);
102
    }
111
    }
103
112
104
    public TokenItem getCurrentToken() {
113
    public int getCurrentTokenOffset() {
114
        return tokenOffset;
115
    }
116
    
117
    public Token<XMLTokenId> getCurrentToken() {
105
        return token;
118
        return token;
106
    }
119
    }
107
120
108
    public String getCurrentTokenImage() {
121
    public String getCurrentTokenImage() {
109
        return token.getImage();
122
        return token.text().toString();
110
    }
123
    }
111
124
112
    public SyntaxElement getCurrentElement() {
125
    public SyntaxElement getCurrentElement() {
Lines 142-148 Link Here
142
    private void populateNamespaces() {
155
    private void populateNamespaces() {
143
        // Find the a start or empty tag just before the current syntax element.
156
        // Find the a start or empty tag just before the current syntax element.
144
        SyntaxElement element = this.element;
157
        SyntaxElement element = this.element;
145
        while (element != null && !(element instanceof StartTag) && !(element instanceof EmptyTag)) {
158
        while (element != null && !(syntaxSupport.isStartTag(element)) && !(syntaxSupport.isEmptyTag(element))) {
146
            element = element.getPrevious();
159
            element = element.getPrevious();
147
        }
160
        }
148
        if (element == null) {
161
        if (element == null) {
Lines 151-160 Link Here
151
164
152
        // To find all namespace declarations active at the caret offset, we
165
        // To find all namespace declarations active at the caret offset, we
153
        // need to look at xmlns attributes of the current element and its ancestors.
166
        // need to look at xmlns attributes of the current element and its ancestors.
154
        Node node = (Node)element;
167
        while (element != null) {
155
        while (node != null) {
168
            Node node = element.getNode();
156
            if (node instanceof StartTag || node instanceof EmptyTag) {
169
            if (syntaxSupport.isStartTag(element) || syntaxSupport.isEmptyTag(element)) {
157
                NamedNodeMap attributes = ((Tag)node).getAttributes();
170
                NamedNodeMap attributes = node.getAttributes();
158
                for (int index = 0; index < attributes.getLength(); index++) {
171
                for (int index = 0; index < attributes.getLength(); index++) {
159
                    Attr attr = (Attr) attributes.item(index);
172
                    Attr attr = (Attr) attributes.item(index);
160
                    String attrName = attr.getName();
173
                    String attrName = attr.getName();
Lines 172-178 Link Here
172
                    }
185
                    }
173
                }
186
                }
174
            }
187
            }
175
            node = node.getParentNode();
188
            element = element.getParentElement();
176
        }
189
        }
177
    }
190
    }
191
    
192
    public int getNodeOffset(Node n) {
193
        return syntaxSupport.getNodeOffset(n);
194
    }
195
    
196
    public boolean isTag(SyntaxElement e) {
197
        return syntaxSupport.isStartTag(e) || syntaxSupport.isEmptyTag(e) || syntaxSupport.isEndTag(e);
198
    }
178
}
199
}
(-)a/spring.beans/src/org/netbeans/modules/spring/beans/editor/SpringXMLConfigEditorUtils.java (-24 / +30 lines)
Lines 56-64 Link Here
56
import javax.swing.text.BadLocationException;
56
import javax.swing.text.BadLocationException;
57
import javax.swing.text.Document;
57
import javax.swing.text.Document;
58
import javax.swing.text.StyledDocument;
58
import javax.swing.text.StyledDocument;
59
import org.netbeans.editor.BaseDocument;
59
import org.netbeans.api.lexer.Token;
60
import org.netbeans.editor.TokenItem;
60
import org.netbeans.api.lexer.TokenSequence;
61
import org.netbeans.editor.ext.ExtSyntaxSupport;
61
import org.netbeans.api.xml.lexer.XMLTokenId;
62
import org.netbeans.modules.spring.api.Action;
62
import org.netbeans.modules.spring.api.Action;
63
import org.netbeans.modules.spring.api.beans.model.Location;
63
import org.netbeans.modules.spring.api.beans.model.Location;
64
import org.netbeans.modules.spring.api.beans.model.SpringBean;
64
import org.netbeans.modules.spring.api.beans.model.SpringBean;
Lines 68-78 Link Here
68
import org.netbeans.modules.spring.beans.BeansAttributes;
68
import org.netbeans.modules.spring.beans.BeansAttributes;
69
import org.netbeans.modules.spring.beans.BeansElements;
69
import org.netbeans.modules.spring.beans.BeansElements;
70
import org.netbeans.modules.spring.beans.utils.StringUtils;
70
import org.netbeans.modules.spring.beans.utils.StringUtils;
71
import org.netbeans.modules.xml.text.syntax.SyntaxElement;
71
import org.netbeans.modules.xml.text.api.dom.SyntaxElement;
72
import org.netbeans.modules.xml.text.syntax.XMLSyntaxSupport;
72
import org.netbeans.modules.xml.text.api.dom.TagElement;
73
import org.netbeans.modules.xml.text.syntax.dom.EmptyTag;
73
import org.netbeans.modules.xml.text.api.dom.XMLSyntaxSupport;
74
import org.netbeans.modules.xml.text.syntax.dom.StartTag;
75
import org.netbeans.modules.xml.text.syntax.dom.Tag;
76
import org.openide.cookies.EditorCookie;
74
import org.openide.cookies.EditorCookie;
77
import org.openide.cookies.LineCookie;
75
import org.openide.cookies.LineCookie;
78
import org.openide.cookies.OpenCookie;
76
import org.openide.cookies.OpenCookie;
Lines 133-139 Link Here
133
        return "set" + String.valueOf(buffer); // NOI18N
131
        return "set" + String.valueOf(buffer); // NOI18N
134
    }
132
    }
135
133
136
    public static String getBeanFactoryMethod(Tag tag) {
134
    public static String getBeanFactoryMethod(Node tag) {
137
        Node bean = getBean(tag);
135
        Node bean = getBean(tag);
138
        if (bean != null) {
136
        if (bean != null) {
139
            NamedNodeMap attribs = bean.getAttributes();
137
            NamedNodeMap attribs = bean.getAttributes();
Lines 184-215 Link Here
184
        return null;
182
        return null;
185
    }
183
    }
186
184
187
    public static final Tag getDocumentRoot(Document doc) {
185
    public static final Node getDocumentRoot(Document doc) {
188
        Tag retTag = null;
186
        Node retTag = null;
189
        //  Temporary fix for IZ#155008 until Lexer migration
187
        //  Temporary fix for IZ#155008 until Lexer migration
190
        XMLSyntaxSupport syntaxSupport = null;
188
        XMLSyntaxSupport syntaxSupport = null;
191
        try {
189
        try {
192
            syntaxSupport = (XMLSyntaxSupport) ((BaseDocument) doc).getSyntaxSupport();
190
            syntaxSupport = XMLSyntaxSupport.getSyntaxSupport(doc);
193
        } catch (ClassCastException cce) {
191
        } catch (ClassCastException cce) {
194
            LOGGER.log(Level.FINE, cce.getMessage());
192
            LOGGER.log(Level.FINE, cce.getMessage());
195
            syntaxSupport = new XMLSyntaxSupport(((BaseDocument)doc));
193
            syntaxSupport = XMLSyntaxSupport.createSyntaxSupport(doc);
196
        }
194
        }
197
        if (syntaxSupport == null) return retTag;
195
        if (syntaxSupport == null) return retTag;
198
        try {
196
        try {
199
            TokenItem tok = syntaxSupport.getTokenChain(0,1);
197
            Token<XMLTokenId> tok = syntaxSupport.getNextToken(1);
200
            if(tok != null) {
198
            if(tok != null) {
201
                TokenItem prevTok = null;
199
                int off = syntaxSupport.runWithSequence(0, (TokenSequence s) -> {
202
                while((!ContextUtilities.isTagToken(tok)) && (tok != prevTok) ) {
200
                    s.move(0);
203
                    prevTok = tok;
201
                    while (s.moveNext()) {
204
                    if (tok.getNext() != null) {
202
                        Token<XMLTokenId> t = s.token();
205
                        tok = tok.getNext();
203
                        if (ContextUtilities.isTagToken(t)) {
204
                            return s.offset() + t.length();
205
                        }
206
                    }
206
                    }
207
                    return -1;
208
                });
209
                if (off == -1) {
210
                    return null;
207
                }
211
                }
208
                SyntaxElement element = syntaxSupport.getElementChain(tok.getOffset()+tok.getImage().length());
212
                SyntaxElement element = syntaxSupport.getElementChain(off);
209
                if(element instanceof StartTag || element instanceof EmptyTag) {
213
                if (element != null && element.getType() == Node.ELEMENT_NODE) {
210
                    Tag tag = (Tag) element;
214
                    TagElement te = (TagElement)element;
211
                    if(tag.getParentNode() instanceof org.w3c.dom.Document) {
215
                    if (te.isStart() || te.isSelfClosing()) {
212
                        return tag;
216
                        if(te.getNode().getParentNode() instanceof org.w3c.dom.Document) {
217
                            return te.getNode();
218
                        }
213
                    }
219
                    }
214
                }
220
                }
215
            }
221
            }
(-)a/spring.beans/src/org/netbeans/modules/spring/beans/hyperlink/HyperlinkEnv.java (-16 / +16 lines)
Lines 47-60 Link Here
47
import java.util.HashMap;
47
import java.util.HashMap;
48
import java.util.Map;
48
import java.util.Map;
49
import javax.swing.text.Document;
49
import javax.swing.text.Document;
50
import org.netbeans.api.lexer.Token;
51
import org.netbeans.api.xml.lexer.XMLTokenId;
50
import org.netbeans.editor.BaseDocument;
52
import org.netbeans.editor.BaseDocument;
51
import org.netbeans.editor.TokenItem;
52
import org.netbeans.modules.editor.NbEditorUtilities;
53
import org.netbeans.modules.editor.NbEditorUtilities;
53
import org.netbeans.modules.spring.beans.editor.ContextUtilities;
54
import org.netbeans.modules.spring.beans.editor.ContextUtilities;
54
import org.netbeans.modules.spring.beans.editor.DocumentContext;
55
import org.netbeans.modules.spring.beans.editor.DocumentContext;
55
import org.netbeans.modules.spring.beans.editor.SpringXMLConfigEditorUtils;
56
import org.netbeans.modules.spring.beans.editor.SpringXMLConfigEditorUtils;
56
import org.netbeans.modules.xml.text.syntax.SyntaxElement;
57
import org.netbeans.modules.xml.text.api.dom.SyntaxElement;
57
import org.netbeans.modules.xml.text.syntax.dom.Tag;
58
import org.openide.filesystems.FileObject;
58
import org.openide.filesystems.FileObject;
59
import org.w3c.dom.NamedNodeMap;
59
import org.w3c.dom.NamedNodeMap;
60
import org.w3c.dom.Node;
60
import org.w3c.dom.Node;
Lines 110-116 Link Here
110
    }
110
    }
111
111
112
    private void initialize() {
112
    private void initialize() {
113
        Tag currentTag = null;
113
        SyntaxElement currentTag = null;
114
        DocumentContext documentContext = DocumentContext.create(baseDocument, offset);
114
        DocumentContext documentContext = DocumentContext.create(baseDocument, offset);
115
        if (documentContext == null) {
115
        if (documentContext == null) {
116
            return;
116
            return;
Lines 118-160 Link Here
118
        
118
        
119
        declaredNamespaces = documentContext.getDeclaredNamespacesMap();
119
        declaredNamespaces = documentContext.getDeclaredNamespacesMap();
120
120
121
        TokenItem token = documentContext.getCurrentToken();
121
        Token<XMLTokenId> token = documentContext.getCurrentToken();
122
        if (token == null) {
122
        if (token == null) {
123
            return;
123
            return;
124
        }
124
        }
125
        
125
        
126
        tokenStartOffset = token.getOffset();
126
        tokenStartOffset = documentContext.getCurrentTokenOffset();
127
        tokenEndOffset = tokenStartOffset + token.getImage().length();
127
        tokenEndOffset = tokenStartOffset + token.length();
128
        tokenImage = token.getImage();
128
        tokenImage = token.text().toString();
129
        
129
        
130
        if (ContextUtilities.isValueToken(token)
130
        if (ContextUtilities.isValueToken(token)
131
                || ContextUtilities.isAttributeToken(documentContext.getCurrentToken())) {
131
                || ContextUtilities.isAttributeToken(documentContext.getCurrentToken())) {
132
            SyntaxElement element = documentContext.getCurrentElement();
132
            SyntaxElement element = documentContext.getCurrentElement();
133
            if (element instanceof Tag) {
133
            if (documentContext.isTag(element)) {
134
                currentTag  = (Tag) element;
134
                currentTag  = element;
135
            } else {
135
            } else {
136
                return;
136
                return;
137
            }
137
            }
138
            Tag beanTag = (Tag) SpringXMLConfigEditorUtils.getBean(currentTag);
138
            Node beanTag = SpringXMLConfigEditorUtils.getBean(currentTag.getNode());
139
            if (beanTag != null) {
139
            if (beanTag != null) {
140
                beanTagOffset = beanTag.getElementOffset();
140
                beanTagOffset = documentContext.getNodeOffset(beanTag);
141
                beanAttribs = collectAttributes(beanTag);
141
                beanAttribs = collectAttributes(beanTag);
142
            }
142
            }
143
            tagName = currentTag.getNodeName();
143
            tagName = currentTag.getNode().getNodeName();
144
        }
144
        }
145
        
145
        
146
        if (ContextUtilities.isValueToken(token)) {
146
        if (ContextUtilities.isValueToken(token)) {
147
            type = Type.ATTRIB_VALUE;
147
            type = Type.ATTRIB_VALUE;
148
            attribName = ContextUtilities.getAttributeTokenImage(documentContext);
148
            attribName = ContextUtilities.getAttributeTokenImage(documentContext);
149
            valueString = token.getImage();
149
            valueString = token.text().toString();
150
            valueString = valueString.substring(1, valueString.length() - 1); // Strip quotes
150
            valueString = valueString.substring(1, valueString.length() - 1); // Strip quotes
151
        } else if (ContextUtilities.isAttributeToken(documentContext.getCurrentToken())) {
151
        } else if (ContextUtilities.isAttributeToken(documentContext.getCurrentToken())) {
152
            type = Type.ATTRIB;
152
            type = Type.ATTRIB;
153
            attribName = token.getImage();
153
            attribName = token.text().toString();
154
        }
154
        }
155
    }
155
    }
156
    
156
    
157
    private Map<String, String> collectAttributes(Tag currentTag) {
157
    private Map<String, String> collectAttributes(Node currentTag) {
158
        Map<String, String> attribsMap = new HashMap<String, String>();
158
        Map<String, String> attribsMap = new HashMap<String, String>();
159
        NamedNodeMap attribsNodeMap = currentTag.getAttributes();
159
        NamedNodeMap attribsNodeMap = currentTag.getAttributes();
160
        for(int i = 0; i < attribsNodeMap.getLength(); i++) {
160
        for(int i = 0; i < attribsNodeMap.getLength(); i++) {
(-)a/spring.beans/src/org/netbeans/modules/spring/beans/hyperlink/SpringXMLConfigHyperlinkProvider.java (-4 / +2 lines)
Lines 55-61 Link Here
55
import org.netbeans.modules.spring.beans.utils.StringUtils;
55
import org.netbeans.modules.spring.beans.utils.StringUtils;
56
import org.netbeans.modules.spring.java.Public;
56
import org.netbeans.modules.spring.java.Public;
57
import org.netbeans.modules.spring.java.Static;
57
import org.netbeans.modules.spring.java.Static;
58
import org.netbeans.modules.xml.text.syntax.XMLSyntaxSupport;
58
import org.netbeans.modules.xml.text.api.dom.XMLSyntaxSupport;
59
59
60
/**
60
/**
61
 * Provides hyperlinking functionality for Spring XML Configuration files
61
 * Provides hyperlinking functionality for Spring XML Configuration files
Lines 124-132 Link Here
124
        if (!(document instanceof BaseDocument)) {
124
        if (!(document instanceof BaseDocument)) {
125
            return false;
125
            return false;
126
        }
126
        }
127
127
        if (XMLSyntaxSupport.getSyntaxSupport(document) == null) {
128
        BaseDocument doc = (BaseDocument) document;
129
        if (!(doc.getSyntaxSupport() instanceof XMLSyntaxSupport)) {
130
            return false;
128
            return false;
131
        }
129
        }
132
130
(-)a/spring.beans/src/org/netbeans/modules/spring/beans/model/impl/ConfigFileSpringBeanSource.java (-5 / +9 lines)
Lines 67-73 Link Here
67
import org.netbeans.modules.spring.beans.editor.SpringXMLConfigEditorUtils;
67
import org.netbeans.modules.spring.beans.editor.SpringXMLConfigEditorUtils;
68
import org.netbeans.modules.spring.beans.model.SpringBeanSource;
68
import org.netbeans.modules.spring.beans.model.SpringBeanSource;
69
import org.netbeans.modules.spring.beans.utils.StringUtils;
69
import org.netbeans.modules.spring.beans.utils.StringUtils;
70
import org.netbeans.modules.xml.text.syntax.dom.Tag;
70
import org.netbeans.modules.xml.text.api.dom.XMLSyntaxSupport;
71
import org.openide.filesystems.FileObject;
71
import org.openide.filesystems.FileObject;
72
import org.openide.filesystems.FileUtil;
72
import org.openide.filesystems.FileUtil;
73
import org.w3c.dom.NamedNodeMap;
73
import org.w3c.dom.NamedNodeMap;
Lines 145-150 Link Here
145
        
145
        
146
        private static final String REF_SUFFIX = "-ref"; // NOI18N
146
        private static final String REF_SUFFIX = "-ref"; // NOI18N
147
        private static final String NULL_PREFIX = "null_prefix";
147
        private static final String NULL_PREFIX = "null_prefix";
148
        
149
        private XMLSyntaxSupport support;
148
150
149
        public DocumentParser(File file, Document document) {
151
        public DocumentParser(File file, Document document) {
150
            this.file = file;
152
            this.file = file;
Lines 160-165 Link Here
160
            if (rootNode == null) {
162
            if (rootNode == null) {
161
                return;
163
                return;
162
            }
164
            }
165
            support = XMLSyntaxSupport.getSyntaxSupport(document);
163
            NodeList childNodes = rootNode.getChildNodes();
166
            NodeList childNodes = rootNode.getChildNodes();
164
167
165
            // prefixesMap caches the prefixes for tag nemes
168
            // prefixesMap caches the prefixes for tag nemes
Lines 198-205 Link Here
198
            String parent = getTrimmedAttr(node, BeansAttributes.PARENT); 
201
            String parent = getTrimmedAttr(node, BeansAttributes.PARENT); 
199
            String factoryBean = getTrimmedAttr(node, BeansAttributes.FACTORY_BEAN); 
202
            String factoryBean = getTrimmedAttr(node, BeansAttributes.FACTORY_BEAN); 
200
            String factoryMethod = getTrimmedAttr(node, BeansAttributes.FACTORY_METHOD); 
203
            String factoryMethod = getTrimmedAttr(node, BeansAttributes.FACTORY_METHOD); 
201
            Tag tag = (Tag)node;
204
            Location location = new ConfigFileLocation(FileUtil.toFileObject(file), 
202
            Location location = new ConfigFileLocation(FileUtil.toFileObject(file), tag.getElementOffset());
205
                    support.getNodeOffset(node));
203
            Set<SpringBeanProperty> properties = parseBeanProperties(node, prefixesMap);
206
            Set<SpringBeanProperty> properties = parseBeanProperties(node, prefixesMap);
204
            ConfigFileSpringBean bean = new ConfigFileSpringBean(id, names, clazz, parent, factoryBean, factoryMethod, properties, location);
207
            ConfigFileSpringBean bean = new ConfigFileSpringBean(id, names, clazz, parent, factoryBean, factoryMethod, properties, location);
205
            if (id != null) {
208
            if (id != null) {
Lines 227-236 Link Here
227
            }
230
            }
228
            
231
            
229
            // P Namespace items
232
            // P Namespace items
230
            String tagName = ((Tag)node).getTagName();
233
            String tagName = node.getNodeName();
231
            String prefix = prefixesMap.get(tagName);
234
            String prefix = prefixesMap.get(tagName);
232
            if (prefix == null) {
235
            if (prefix == null) {
233
                prefix = SpringXMLConfigEditorUtils.getPNamespacePrefix(document, ((Tag)node).getElementOffset());
236
                prefix = SpringXMLConfigEditorUtils.getPNamespacePrefix(document, 
237
                        support.getNodeOffset(node));
234
                if (prefix == null) {
238
                if (prefix == null) {
235
                    // this is caching the case when prefix declaration is missing
239
                    // this is caching the case when prefix declaration is missing
236
                    prefixesMap.put(tagName, NULL_PREFIX);
240
                    prefixesMap.put(tagName, NULL_PREFIX);
(-)a/spring.beans/src/org/netbeans/modules/spring/beans/refactoring/AttributeFinder.java (-23 / +22 lines)
Lines 42-52 Link Here
42
package org.netbeans.modules.spring.beans.refactoring;
42
package org.netbeans.modules.spring.beans.refactoring;
43
43
44
import javax.swing.text.BadLocationException;
44
import javax.swing.text.BadLocationException;
45
import org.netbeans.editor.BaseDocument;
45
import org.netbeans.api.lexer.Token;
46
import org.netbeans.editor.TokenID;
46
import org.netbeans.api.lexer.TokenSequence;
47
import org.netbeans.editor.TokenItem;
47
import org.netbeans.api.xml.lexer.XMLTokenId;
48
import org.netbeans.modules.xml.text.api.XMLDefaultTokenContext;
48
import org.netbeans.modules.xml.text.api.dom.XMLSyntaxSupport;
49
import org.netbeans.modules.xml.text.syntax.XMLSyntaxSupport;
50
49
51
/**
50
/**
52
 *
51
 *
Lines 65-91 Link Here
65
64
66
    public boolean find(String attrName) throws BadLocationException {
65
    public boolean find(String attrName) throws BadLocationException {
67
        foundOffset = -1;
66
        foundOffset = -1;
68
        BaseDocument doc = syntaxSupport.getDocument();
67
        Token<XMLTokenId> item = syntaxSupport.getNextToken(start);
69
        TokenItem item = syntaxSupport.getTokenChain(start, Math.min(start + 1, doc.getLength()));
68
        if (item == null || item.id() != XMLTokenId.TAG) {
70
        if (item == null || item.getTokenID() != XMLDefaultTokenContext.TAG) {
71
            return false;
69
            return false;
72
        }
70
        }
73
        item = item.getNext();
71
        return syntaxSupport.runWithSequence(start, (TokenSequence s) -> {
74
        String currentAttrName = null;
72
            String currentAttrName = null;
75
        while (item != null) {
73
            while (s.moveNext()) {
76
            TokenID id = item.getTokenID();
74
                Token<XMLTokenId> t = s.token();
77
            if (id == XMLDefaultTokenContext.ARGUMENT) {
75
                XMLTokenId id = t.id();
78
                currentAttrName = item.getImage();
76
                if (id == XMLTokenId.ARGUMENT) {
79
                if (currentAttrName != null && currentAttrName.equals(attrName)) {
77
                    currentAttrName = t.text().toString();
80
                    foundOffset = item.getOffset();
78
                    if (currentAttrName != null && currentAttrName.equals(attrName)) {
81
                    return true;
79
                        foundOffset = s.offset();
80
                        return true;
81
                    }
82
                } else if (id == XMLTokenId.TAG) {
83
                    break;
82
                }
84
                }
83
            } else if (id == XMLDefaultTokenContext.TAG) {
85
           } 
84
                break;
86
           return false;
85
            }
87
        });
86
            item = item.getNext();
87
        }
88
        return false;
89
    }
88
    }
90
89
91
    public int getFoundOffset() {
90
    public int getFoundOffset() {
(-)a/spring.beans/src/org/netbeans/modules/spring/beans/refactoring/AttributeValueFinder.java (-28 / +31 lines)
Lines 45-56 Link Here
45
package org.netbeans.modules.spring.beans.refactoring;
45
package org.netbeans.modules.spring.beans.refactoring;
46
46
47
import javax.swing.text.BadLocationException;
47
import javax.swing.text.BadLocationException;
48
import org.netbeans.editor.BaseDocument;
48
import org.netbeans.api.lexer.Token;
49
import org.netbeans.api.lexer.TokenSequence;
50
import org.netbeans.api.xml.lexer.XMLTokenId;
49
import org.netbeans.editor.SyntaxSupport;
51
import org.netbeans.editor.SyntaxSupport;
50
import org.netbeans.editor.TokenID;
52
import org.netbeans.modules.xml.text.api.dom.XMLSyntaxSupport;
51
import org.netbeans.editor.TokenItem;
52
import org.netbeans.editor.ext.ExtSyntaxSupport;
53
import org.netbeans.modules.xml.text.api.XMLDefaultTokenContext;
54
53
55
/**
54
/**
56
 *
55
 *
Lines 58-104 Link Here
58
 */
57
 */
59
public class AttributeValueFinder {
58
public class AttributeValueFinder {
60
59
61
    private final SyntaxSupport syntaxSupport;
60
    private final XMLSyntaxSupport xmlSupport;
62
    private final int start;
61
    private final int start;
63
62
64
    private int foundOffset = -1;
63
    private int foundOffset = -1;
65
    private String foundValue;
64
    private String foundValue;
66
65
67
    public AttributeValueFinder(SyntaxSupport syntaxSupport, int start) {
66
    public AttributeValueFinder(SyntaxSupport syntaxSupport, int start) {
68
        this.syntaxSupport = syntaxSupport;
69
        this.start = start;
67
        this.start = start;
68
        this.xmlSupport = XMLSyntaxSupport.getSyntaxSupport(syntaxSupport.getDocument());
69
    }
70
71
    public AttributeValueFinder(XMLSyntaxSupport syntaxSupport, int start) {
72
        this.start = start;
73
        this.xmlSupport = syntaxSupport;
70
    }
74
    }
71
75
72
    public boolean find(String attrName) throws BadLocationException {
76
    public boolean find(String attrName) throws BadLocationException {
73
        foundOffset = -1;
77
        foundOffset = -1;
74
        foundValue = null;
78
        foundValue = null;
75
        BaseDocument doc = syntaxSupport.getDocument();
79
        if (xmlSupport == null) {
76
        if (!(syntaxSupport instanceof ExtSyntaxSupport)) {
77
            return false;
80
            return false;
78
        }
81
        }
79
82
        Token<XMLTokenId> item = xmlSupport.getNextToken(start);
80
        TokenItem item = ((ExtSyntaxSupport) syntaxSupport).getTokenChain(start, Math.min(start + 1, doc.getLength()));
83
        if (item == null || item.id() != XMLTokenId.TAG) {
81
        if (item == null || item.getTokenID() != XMLDefaultTokenContext.TAG) {
82
            return false;
84
            return false;
83
        }
85
        }
84
        item = item.getNext();
86
        return xmlSupport.runWithSequence(start, (TokenSequence s) -> {
85
        String currentAttrName = null;
87
            String currentAttrName = null;
86
        while (item != null) {
88
            while (s.moveNext()) {
87
            TokenID id = item.getTokenID();
89
                Token<XMLTokenId> t = s.token();
88
            if (id == XMLDefaultTokenContext.ARGUMENT) {
90
                XMLTokenId id = t.id();
89
                currentAttrName = item.getImage();
91
                if (id == XMLTokenId.ARGUMENT) {
90
            } else if (id == XMLDefaultTokenContext.VALUE) {
92
                    currentAttrName = t.text().toString();
91
                if (currentAttrName != null && currentAttrName.equals(attrName)) {
93
                } else if (id == XMLTokenId.VALUE) {
92
                    foundOffset = item.getOffset();
94
                    if (currentAttrName != null && currentAttrName.equals(attrName)) {
93
                    foundValue = item.getImage();
95
                        foundOffset = s.offset();
94
                    return true;
96
                        foundValue = t.text().toString();
97
                        return true;
98
                    }
99
                } else if (id == XMLTokenId.TAG) {
100
                    break;
95
                }
101
                }
96
            } else if (id == XMLDefaultTokenContext.TAG) {
97
                break;
98
            }
102
            }
99
            item = item.getNext();
103
            return false;
100
        }
104
        });
101
        return false;
102
    }
105
    }
103
106
104
    public int getFoundOffset() {
107
    public int getFoundOffset() {
(-)a/spring.beans/src/org/netbeans/modules/spring/beans/refactoring/PropertyChildFinder.java (-8 / +7 lines)
Lines 47-56 Link Here
47
import org.netbeans.modules.spring.beans.BeansElements;
47
import org.netbeans.modules.spring.beans.BeansElements;
48
import org.netbeans.modules.spring.beans.editor.SpringXMLConfigEditorUtils;
48
import org.netbeans.modules.spring.beans.editor.SpringXMLConfigEditorUtils;
49
import org.netbeans.modules.spring.beans.utils.StringUtils;
49
import org.netbeans.modules.spring.beans.utils.StringUtils;
50
import org.netbeans.modules.xml.text.syntax.SyntaxElement;
50
import org.netbeans.modules.xml.text.api.dom.SyntaxElement;
51
import org.netbeans.modules.xml.text.syntax.XMLSyntaxSupport;
51
import org.netbeans.modules.xml.text.api.dom.XMLSyntaxSupport;
52
import org.netbeans.modules.xml.text.syntax.dom.StartTag;
53
import org.netbeans.modules.xml.text.syntax.dom.Tag;
54
import org.w3c.dom.Node;
52
import org.w3c.dom.Node;
55
import org.w3c.dom.NodeList;
53
import org.w3c.dom.NodeList;
56
54
Lines 74-84 Link Here
74
        foundOffset = -1;
72
        foundOffset = -1;
75
        value = null;
73
        value = null;
76
        SyntaxElement beanElement = syntaxSupport.getElementChain(start+1);
74
        SyntaxElement beanElement = syntaxSupport.getElementChain(start+1);
77
        if(!(beanElement instanceof StartTag)) {
75
        if (!syntaxSupport.isStartTag(beanElement)) {
78
            return false;
76
            return false;
79
        }
77
        }
80
        
78
        
81
        Tag beanTag = (Tag) beanElement;
79
        Node beanTag = beanElement.getNode();
82
        if(!BeansElements.BEAN.equals(beanTag.getNodeName())) {
80
        if(!BeansElements.BEAN.equals(beanTag.getNodeName())) {
83
            return false;
81
            return false;
84
        }
82
        }
Lines 89-96 Link Here
89
            if(BeansElements.PROPERTY.equals(n.getNodeName())) {
87
            if(BeansElements.PROPERTY.equals(n.getNodeName())) {
90
                String name = SpringXMLConfigEditorUtils.getAttribute(n, BeansAttributes.NAME);
88
                String name = SpringXMLConfigEditorUtils.getAttribute(n, BeansAttributes.NAME);
91
                if(StringUtils.hasText(name) && propertyName.equals(name)) {
89
                if(StringUtils.hasText(name) && propertyName.equals(name)) {
92
                    Tag propertyTag  = (Tag) n;
90
                    AttributeValueFinder delegate = new AttributeValueFinder(
93
                    AttributeValueFinder delegate = new AttributeValueFinder(syntaxSupport, propertyTag.getElementOffset());
91
                            syntaxSupport, 
92
                            syntaxSupport.getNodeOffset(n));
94
                    boolean retVal = delegate.find(BeansAttributes.NAME);
93
                    boolean retVal = delegate.find(BeansAttributes.NAME);
95
                    foundOffset = delegate.getFoundOffset();
94
                    foundOffset = delegate.getFoundOffset();
96
                    value = delegate.getValue();
95
                    value = delegate.getValue();
(-)a/spring.beans/src/org/netbeans/modules/spring/beans/refactoring/PropertyRefFinder.java (-3 / +4 lines)
Lines 50-55 Link Here
50
import javax.lang.model.element.TypeElement;
50
import javax.lang.model.element.TypeElement;
51
import javax.lang.model.type.TypeMirror;
51
import javax.lang.model.type.TypeMirror;
52
import javax.swing.text.BadLocationException;
52
import javax.swing.text.BadLocationException;
53
import javax.swing.text.Document;
53
import javax.swing.text.Position.Bias;
54
import javax.swing.text.Position.Bias;
54
import org.netbeans.api.java.source.CompilationController;
55
import org.netbeans.api.java.source.CompilationController;
55
import org.netbeans.api.java.source.ElementHandle;
56
import org.netbeans.api.java.source.ElementHandle;
Lines 68-74 Link Here
68
import org.netbeans.modules.spring.java.Property;
69
import org.netbeans.modules.spring.java.Property;
69
import org.netbeans.modules.spring.java.PropertyFinder;
70
import org.netbeans.modules.spring.java.PropertyFinder;
70
import org.netbeans.modules.spring.java.PropertyType;
71
import org.netbeans.modules.spring.java.PropertyType;
71
import org.netbeans.modules.xml.text.syntax.XMLSyntaxSupport;
72
import org.netbeans.modules.xml.text.api.dom.XMLSyntaxSupport;
72
import org.openide.filesystems.FileObject;
73
import org.openide.filesystems.FileObject;
73
import org.openide.text.PositionBounds;
74
import org.openide.text.PositionBounds;
74
import org.openide.text.PositionRef;
75
import org.openide.text.PositionRef;
Lines 88-94 Link Here
88
    public PropertyRefFinder(DocumentAccess docAccess, CompilationController cc, RenamedProperty renamedProperty) {
89
    public PropertyRefFinder(DocumentAccess docAccess, CompilationController cc, RenamedProperty renamedProperty) {
89
        this.docAccess = docAccess;
90
        this.docAccess = docAccess;
90
        BaseDocument document = (BaseDocument) docAccess.getDocument();
91
        BaseDocument document = (BaseDocument) docAccess.getDocument();
91
        syntaxSupport = (XMLSyntaxSupport) document.getSyntaxSupport();
92
        syntaxSupport = XMLSyntaxSupport.getSyntaxSupport(document);
92
        this.cc = cc;
93
        this.cc = cc;
93
        this.renamedProperty = renamedProperty;
94
        this.renamedProperty = renamedProperty;
94
    }
95
    }
Lines 203-209 Link Here
203
        }
204
        }
204
205
205
        // p-namespace
206
        // p-namespace
206
        BaseDocument document = syntaxSupport.getDocument();
207
        Document document = syntaxSupport.getDocument();
207
        String prefix = SpringXMLConfigEditorUtils.getPNamespacePrefix(document, beanOffset);
208
        String prefix = SpringXMLConfigEditorUtils.getPNamespacePrefix(document, beanOffset);
208
        if (prefix == null) {
209
        if (prefix == null) {
209
            return;
210
            return;
(-)a/spring.beans/test/unit/src/org/netbeans/modules/spring/beans/TestUtils.java (+3 lines)
Lines 51-56 Link Here
51
import java.io.FileOutputStream;
51
import java.io.FileOutputStream;
52
import java.io.IOException;
52
import java.io.IOException;
53
import java.io.InputStream;
53
import java.io.InputStream;
54
import org.netbeans.api.lexer.Language;
55
import org.netbeans.api.xml.lexer.XMLTokenId;
54
import org.netbeans.editor.BaseDocument;
56
import org.netbeans.editor.BaseDocument;
55
import org.netbeans.modules.spring.api.beans.SpringConstants;
57
import org.netbeans.modules.spring.api.beans.SpringConstants;
56
import org.openide.filesystems.FileUtil;
58
import org.openide.filesystems.FileUtil;
Lines 92-97 Link Here
92
    public static BaseDocument createSpringXMLConfigDocument(String content) throws Exception {
94
    public static BaseDocument createSpringXMLConfigDocument(String content) throws Exception {
93
        Class<?> kitClass = CloneableEditorSupport.getEditorKit(SpringConstants.CONFIG_MIME_TYPE).getClass();
95
        Class<?> kitClass = CloneableEditorSupport.getEditorKit(SpringConstants.CONFIG_MIME_TYPE).getClass();
94
        BaseDocument doc = new BaseDocument(kitClass, false);
96
        BaseDocument doc = new BaseDocument(kitClass, false);
97
        doc.putProperty(Language.class, XMLTokenId.language());
95
        doc.insertString(0, content, null);
98
        doc.insertString(0, content, null);
96
        return doc;
99
        return doc;
97
    }
100
    }
(-)a/spring.beans/test/unit/src/org/netbeans/modules/spring/beans/completion/CompletionContextTest.java (-2 / +15 lines)
Lines 44-51 Link Here
44
44
45
package org.netbeans.modules.spring.beans.completion;
45
package org.netbeans.modules.spring.beans.completion;
46
46
47
import junit.framework.TestCase;
47
import org.netbeans.api.editor.mimelookup.MimePath;
48
import org.netbeans.api.editor.mimelookup.test.MockMimeLookup;
49
import org.netbeans.api.xml.lexer.XMLTokenId;
48
import org.netbeans.editor.BaseDocument;
50
import org.netbeans.editor.BaseDocument;
51
import org.netbeans.junit.NbTestCase;
49
import org.netbeans.modules.spring.beans.TestUtils;
52
import org.netbeans.modules.spring.beans.TestUtils;
50
import org.netbeans.modules.spring.beans.completion.CompletionContext.CompletionType;
53
import org.netbeans.modules.spring.beans.completion.CompletionContext.CompletionType;
51
import static org.netbeans.spi.editor.completion.CompletionProvider.COMPLETION_QUERY_TYPE;
54
import static org.netbeans.spi.editor.completion.CompletionProvider.COMPLETION_QUERY_TYPE;
Lines 54-60 Link Here
54
 *
57
 *
55
 * @author Rohan Ranade (Rohan.Ranade@Sun.COM)
58
 * @author Rohan Ranade (Rohan.Ranade@Sun.COM)
56
 */
59
 */
57
public class CompletionContextTest extends TestCase {
60
public class CompletionContextTest extends NbTestCase {
61
62
    public CompletionContextTest(String name) {
63
        super(name);
64
    }
65
66
    @Override
67
    protected void setUp() throws Exception {
68
        MockMimeLookup.setInstances(MimePath.parse("text/xml"), XMLTokenId.language());
69
        super.setUp();
70
    }
58
71
59
    public void testAttributeValueCompletion() throws Exception {
72
    public void testAttributeValueCompletion() throws Exception {
60
        String config = TestUtils.createXMLConfigText("<bean id='petStore' " +
73
        String config = TestUtils.createXMLConfigText("<bean id='petStore' " +
(-)a/spring.beans/test/unit/src/org/netbeans/modules/spring/beans/refactoring/AttributeFinderTest.java (-2 / +2 lines)
Lines 48-54 Link Here
48
import junit.framework.TestCase;
48
import junit.framework.TestCase;
49
import org.netbeans.editor.BaseDocument;
49
import org.netbeans.editor.BaseDocument;
50
import org.netbeans.modules.spring.beans.TestUtils;
50
import org.netbeans.modules.spring.beans.TestUtils;
51
import org.netbeans.modules.xml.text.syntax.XMLSyntaxSupport;
51
import org.netbeans.modules.xml.text.api.dom.XMLSyntaxSupport;
52
52
53
/**
53
/**
54
 *
54
 *
Lines 63-69 Link Here
63
    public void testFind() throws Exception {
63
    public void testFind() throws Exception {
64
        final String contents = TestUtils.createXMLConfigText("<bean id='foo' class='org.example.Foo'><ref></ref></bean>");
64
        final String contents = TestUtils.createXMLConfigText("<bean id='foo' class='org.example.Foo'><ref></ref></bean>");
65
        BaseDocument doc = TestUtils.createSpringXMLConfigDocument(contents);
65
        BaseDocument doc = TestUtils.createSpringXMLConfigDocument(contents);
66
        final XMLSyntaxSupport syntaxSupport = (XMLSyntaxSupport)doc.getSyntaxSupport();
66
        final XMLSyntaxSupport syntaxSupport = XMLSyntaxSupport.getSyntaxSupport(doc);
67
        doc.render(new Runnable() {
67
        doc.render(new Runnable() {
68
            public void run() {
68
            public void run() {
69
                int beanOffset = contents.indexOf("<bean ");
69
                int beanOffset = contents.indexOf("<bean ");
(-)a/spring.beans/test/unit/src/org/netbeans/modules/spring/beans/refactoring/AttributeValueFinderTest.java (-2 / +2 lines)
Lines 48-54 Link Here
48
import junit.framework.TestCase;
48
import junit.framework.TestCase;
49
import org.netbeans.editor.BaseDocument;
49
import org.netbeans.editor.BaseDocument;
50
import org.netbeans.modules.spring.beans.TestUtils;
50
import org.netbeans.modules.spring.beans.TestUtils;
51
import org.netbeans.modules.xml.text.syntax.XMLSyntaxSupport;
51
import org.netbeans.modules.xml.text.api.dom.XMLSyntaxSupport;
52
52
53
/**
53
/**
54
 *
54
 *
Lines 63-69 Link Here
63
    public void testFind() throws Exception {
63
    public void testFind() throws Exception {
64
        final String contents = TestUtils.createXMLConfigText("<bean id='foo' class='org.example.Foo'><ref></ref></bean>");
64
        final String contents = TestUtils.createXMLConfigText("<bean id='foo' class='org.example.Foo'><ref></ref></bean>");
65
        BaseDocument doc = TestUtils.createSpringXMLConfigDocument(contents);
65
        BaseDocument doc = TestUtils.createSpringXMLConfigDocument(contents);
66
        final XMLSyntaxSupport syntaxSupport = (XMLSyntaxSupport)doc.getSyntaxSupport();
66
        final XMLSyntaxSupport syntaxSupport = XMLSyntaxSupport.getSyntaxSupport(doc);
67
        doc.render(new Runnable() {
67
        doc.render(new Runnable() {
68
            public void run() {
68
            public void run() {
69
                int beanOffset = contents.indexOf("<bean ");
69
                int beanOffset = contents.indexOf("<bean ");
(-)a/spring.beans/test/unit/src/org/netbeans/modules/spring/beans/refactoring/PropertyChildFinderTest.java (-2 / +2 lines)
Lines 46-52 Link Here
46
import junit.framework.TestCase;
46
import junit.framework.TestCase;
47
import org.netbeans.editor.BaseDocument;
47
import org.netbeans.editor.BaseDocument;
48
import org.netbeans.modules.spring.beans.TestUtils;
48
import org.netbeans.modules.spring.beans.TestUtils;
49
import org.netbeans.modules.xml.text.syntax.XMLSyntaxSupport;
49
import org.netbeans.modules.xml.text.api.dom.XMLSyntaxSupport;
50
50
51
/**
51
/**
52
 *
52
 *
Lines 61-67 Link Here
61
    public void testFind() throws Exception {
61
    public void testFind() throws Exception {
62
        final String contents = TestUtils.createXMLConfigText("<bean id='foo' class='org.example.Foo'><property name='foobar' value='sample'/></bean>");
62
        final String contents = TestUtils.createXMLConfigText("<bean id='foo' class='org.example.Foo'><property name='foobar' value='sample'/></bean>");
63
        BaseDocument doc = TestUtils.createSpringXMLConfigDocument(contents);
63
        BaseDocument doc = TestUtils.createSpringXMLConfigDocument(contents);
64
        final XMLSyntaxSupport syntaxSupport = (XMLSyntaxSupport)doc.getSyntaxSupport();
64
        final XMLSyntaxSupport syntaxSupport = XMLSyntaxSupport.getSyntaxSupport(doc);
65
        
65
        
66
        doc.render(new Runnable() {
66
        doc.render(new Runnable() {
67
            public void run() {
67
            public void run() {
(-)a/web.beans/nbproject/project.properties (-1 / +1 lines)
Lines 40-46 Link Here
40
# Version 2 license, then the option applies only if the new code is
40
# Version 2 license, then the option applies only if the new code is
41
# made subject to such option by the copyright holder
41
# made subject to such option by the copyright holder
42
42
43
javac.source=1.7
43
javac.source=1.8
44
requires.nb.javac=true
44
requires.nb.javac=true
45
45
46
test-unit-sys-prop.java.awt.headless=true
46
test-unit-sys-prop.java.awt.headless=true
(-)a/web.beans/nbproject/project.xml (-8 / +16 lines)
Lines 280-285 Link Here
280
                    </run-dependency>
280
                    </run-dependency>
281
                </dependency>
281
                </dependency>
282
                <dependency>
282
                <dependency>
283
                    <code-name-base>org.netbeans.modules.xml.lexer</code-name-base>
284
                    <build-prerequisite/>
285
                    <compile-dependency/>
286
                    <run-dependency>
287
                        <specification-version>1.30</specification-version>
288
                    </run-dependency>
289
                </dependency>
290
                <dependency>
283
                    <code-name-base>org.netbeans.modules.xml.retriever</code-name-base>
291
                    <code-name-base>org.netbeans.modules.xml.retriever</code-name-base>
284
                    <build-prerequisite/>
292
                    <build-prerequisite/>
285
                    <compile-dependency/>
293
                    <compile-dependency/>
Lines 364-377 Link Here
364
                    </run-dependency>
372
                    </run-dependency>
365
                </dependency>
373
                </dependency>
366
                <dependency>
374
                <dependency>
367
                    <code-name-base>org.openide.util.ui</code-name-base>
368
                    <build-prerequisite/>
369
                    <compile-dependency/>
370
                    <run-dependency>
371
                        <specification-version>9.3</specification-version>
372
                    </run-dependency>
373
                </dependency>
374
                <dependency>
375
                    <code-name-base>org.openide.util</code-name-base>
375
                    <code-name-base>org.openide.util</code-name-base>
376
                    <build-prerequisite/>
376
                    <build-prerequisite/>
377
                    <compile-dependency/>
377
                    <compile-dependency/>
Lines 388-393 Link Here
388
                    </run-dependency>
388
                    </run-dependency>
389
                </dependency>
389
                </dependency>
390
                <dependency>
390
                <dependency>
391
                    <code-name-base>org.openide.util.ui</code-name-base>
392
                    <build-prerequisite/>
393
                    <compile-dependency/>
394
                    <run-dependency>
395
                        <specification-version>9.3</specification-version>
396
                    </run-dependency>
397
                </dependency>
398
                <dependency>
391
                    <code-name-base>org.openide.windows</code-name-base>
399
                    <code-name-base>org.openide.windows</code-name-base>
392
                    <build-prerequisite/>
400
                    <build-prerequisite/>
393
                    <compile-dependency/>
401
                    <compile-dependency/>
(-)a/web.beans/src/org/netbeans/modules/web/beans/completion/BeansCompletionManager.java (-5 / +7 lines)
Lines 46-54 Link Here
46
import java.util.HashMap;
46
import java.util.HashMap;
47
import java.util.List;
47
import java.util.List;
48
import java.util.Map;
48
import java.util.Map;
49
import org.netbeans.api.lexer.Token;
50
import org.netbeans.api.xml.lexer.XMLTokenId;
49
import org.netbeans.editor.TokenItem;
51
import org.netbeans.editor.TokenItem;
50
import org.netbeans.modules.xml.text.syntax.SyntaxElement;
52
import org.netbeans.modules.xml.text.api.dom.SyntaxElement;
51
import org.netbeans.modules.xml.text.syntax.dom.StartTag;
53
import org.w3c.dom.Node;
52
54
53
/**
55
/**
54
 * This class figures out the completion items for various attributes
56
 * This class figures out the completion items for various attributes
Lines 88-95 Link Here
88
        }
90
        }
89
        
91
        
90
        String tagName = context.getTag().getNodeName();
92
        String tagName = context.getTag().getNodeName();
91
        TokenItem attrib = ContextUtilities.getAttributeToken(context.getCurrentToken());
93
        Token<XMLTokenId> attrib = ContextUtilities.getAttributeToken(context.getDocumentContext());
92
        String attribName = attrib != null ? attrib.getImage() : null;
94
        String attribName = attrib != null ? attrib.text().toString(): null;
93
95
94
        BeansCompletor completor = locateCompletor(tagName, attribName);
96
        BeansCompletor completor = locateCompletor(tagName, attribName);
95
        if (completor != null) {
97
        if (completor != null) {
Lines 108-114 Link Here
108
        SyntaxElement curElem = docContext.getCurrentElement();
110
        SyntaxElement curElem = docContext.getCurrentElement();
109
        SyntaxElement prevElem = docContext.getCurrentElement().getPrevious();
111
        SyntaxElement prevElem = docContext.getCurrentElement().getPrevious();
110
112
111
        String tagName = (curElem instanceof StartTag) ? ((StartTag) curElem).getTagName() : ((prevElem instanceof StartTag) ? ((StartTag) prevElem).getTagName() : null);
113
        String tagName = curElem.getType() == Node.ELEMENT_NODE ? curElem.getNode().getNodeName() : null;
112
        BeansCompletor completor = locateCompletor(tagName, null);
114
        BeansCompletor completor = locateCompletor(tagName, null);
113
        if (completor != null) {
115
        if (completor != null) {
114
            valueItems.addAll(completor.doCompletion(context));
116
            valueItems.addAll(completor.doCompletion(context));
(-)a/web.beans/src/org/netbeans/modules/web/beans/completion/BeansCompletor.java (-1 / +1 lines)
Lines 108-114 Link Here
108
                    return Collections.emptyList();
108
                    return Collections.emptyList();
109
                }
109
                }
110
                FileObject fo = NbEditorUtilities.getFileObject(context.getDocument());
110
                FileObject fo = NbEditorUtilities.getFileObject(context.getDocument());
111
                doJavaCompletion(fo, js, results, typedChars, context.getCurrentToken().getOffset());
111
                doJavaCompletion(fo, js, results, typedChars, context.getCurrentTokenOffset());
112
            } catch (IOException ex) {
112
            } catch (IOException ex) {
113
                Exceptions.printStackTrace(ex);
113
                Exceptions.printStackTrace(ex);
114
            }
114
            }
(-)a/web.beans/src/org/netbeans/modules/web/beans/completion/CompletionContext.java (-70 / +93 lines)
Lines 48-63 Link Here
48
import java.util.List;
48
import java.util.List;
49
import java.util.logging.Level;
49
import java.util.logging.Level;
50
import java.util.logging.Logger;
50
import java.util.logging.Logger;
51
import javax.swing.text.BadLocationException;
51
import javax.swing.text.Document;
52
import javax.swing.text.Document;
52
import org.netbeans.editor.BaseDocument;
53
import org.netbeans.api.lexer.Token;
53
import org.netbeans.editor.TokenItem;
54
import org.netbeans.api.lexer.TokenSequence;
54
import org.netbeans.modules.xml.text.api.XMLDefaultTokenContext;
55
import org.netbeans.api.xml.lexer.XMLTokenId;
55
import org.netbeans.modules.xml.text.syntax.SyntaxElement;
56
import org.netbeans.modules.xml.text.api.dom.SyntaxElement;
56
import org.netbeans.modules.xml.text.syntax.XMLSyntaxSupport;
57
import org.netbeans.modules.xml.text.api.dom.XMLSyntaxSupport;
57
import org.netbeans.modules.xml.text.syntax.dom.EmptyTag;
58
import org.openide.util.Exceptions;
58
import org.netbeans.modules.xml.text.syntax.dom.EndTag;
59
import org.netbeans.modules.xml.text.syntax.dom.StartTag;
60
import org.netbeans.modules.xml.text.syntax.dom.Tag;
61
import org.w3c.dom.Node;
59
import org.w3c.dom.Node;
62
import org.w3c.dom.Text;
60
import org.w3c.dom.Text;
63
61
Lines 65-71 Link Here
65
 * Tracks context information for a code completion scenario
63
 * Tracks context information for a code completion scenario
66
 */
64
 */
67
public class CompletionContext {
65
public class CompletionContext {
68
    private ArrayList<String> existingAttributes;
66
    private List<String> existingAttributes;
69
67
70
    public static enum CompletionType {
68
    public static enum CompletionType {
71
        TAG,
69
        TAG,
Lines 89-137 Link Here
89
        this.caretOffset = caretOffset;
87
        this.caretOffset = caretOffset;
90
88
91
        try {
89
        try {
92
            this.support = (XMLSyntaxSupport) ((BaseDocument)doc).getSyntaxSupport();
90
            this.support = XMLSyntaxSupport.getSyntaxSupport(doc);
93
        } catch (ClassCastException cce) {
91
        } catch (ClassCastException cce) {
94
            LOGGER.log(Level.FINE, cce.getMessage());
92
            LOGGER.log(Level.FINE, cce.getMessage());
95
            this.support = new XMLSyntaxSupport(((BaseDocument)doc));
93
            this.support = XMLSyntaxSupport.createSyntaxSupport(doc);
96
        }
94
        }
97
        this.documentContext = EditorContextFactory.getDocumentContext(doc, caretOffset);
95
        this.documentContext = EditorContextFactory.getDocumentContext(doc, caretOffset);
98
        this.lastTypedChar = support.lastTypedChar();
96
        this.lastTypedChar = support.lastTypedChar();
99
        initContext();
97
        try {
98
            initContext();
99
        } catch (BadLocationException ex) {
100
            // ignore
101
        }
100
    }
102
    }
101
    
103
    
102
    private void initContext() {
104
    private void initContext() throws BadLocationException {
103
        TokenItem token = documentContext.getCurrentToken();
105
        Token<XMLTokenId> token = documentContext.getCurrentToken();
104
        if(token == null)
106
        if(token == null)
105
            return;
107
            return;
106
        
108
        
107
        boolean tokenBoundary = (token.getOffset() == caretOffset) 
109
        boolean tokenBoundary = (documentContext.getCurrentTokenOffset() == caretOffset) 
108
                || ((token.getOffset() + token.getImage().length()) == caretOffset);
110
                || ((documentContext.getCurrentTokenOffset() + token.length()) == caretOffset);
109
        
111
        
110
        int id = token.getTokenID().getNumericID();
112
        XMLTokenId id = token.id();
111
        SyntaxElement element = documentContext.getCurrentElement();
113
        SyntaxElement element = documentContext.getCurrentElement();
114
        String chars = token.text().toString().trim();
115
        int tOffset = documentContext.getCurrentTokenOffset();
116
112
        switch (id) {
117
        switch (id) {
113
            //
118
            //
114
            case XMLDefaultTokenContext.TEXT_ID:
119
            case TEXT:
115
                String chars = token.getImage().trim();
120
                Token<XMLTokenId> previousTokenItem = support.getPreviousToken(tOffset);
121
                if (previousTokenItem == null) {
122
                    completionType = CompletionType.NONE;
123
                    break;
124
                }
125
                String text = previousTokenItem.text().toString().trim();
116
                if (chars != null && chars.equals("") &&
126
                if (chars != null && chars.equals("") &&
117
                        token.getPrevious().getImage().trim().equals("/>")) { // NOI18N
127
                        text.equals("/>")) { // NOI18N
118
                    completionType = CompletionType.NONE;
128
                    completionType = CompletionType.NONE;
119
                    break;
129
                    break;
120
                }
130
                }
121
                if (chars != null && chars.equals("") &&
131
                if (chars != null && chars.equals("") &&
122
                        token.getPrevious().getImage().trim().equals(">")) { // NOI18N
132
                        text.equals(">")) { // NOI18N
123
                    completionType = CompletionType.VALUE;
133
                    completionType = CompletionType.VALUE;
124
                    break;
134
                    break;
125
                }
135
                }
126
                if (chars != null && !chars.startsWith("<") &&
136
                if (chars != null && !chars.startsWith("<") &&
127
                        token.getPrevious().getImage().trim().equals(">")) { // NOI18N
137
                        text.equals(">")) { // NOI18N
128
138
129
                    completionType = CompletionType.VALUE;
139
                    completionType = CompletionType.VALUE;
130
                    typedChars = token.getImage().substring(0, caretOffset - token.getOffset());
140
                    typedChars = chars.substring(0, caretOffset - tOffset);
131
                    break;
141
                    break;
132
                }
142
                }
133
                if (chars != null && !chars.equals("<") &&
143
                if (chars != null && !chars.equals("<") &&
134
                        token.getPrevious().getImage().trim().equals(">")) { // NOI18N
144
                        text.equals(">")) { // NOI18N
135
                    completionType = CompletionType.NONE;
145
                    completionType = CompletionType.NONE;
136
                    break;
146
                    break;
137
                }
147
                }
Lines 142-195 Link Here
142
                break;
152
                break;
143
153
144
            //start tag of an element
154
            //start tag of an element
145
            case XMLDefaultTokenContext.TAG_ID:
155
            case TAG:
146
                if (element instanceof EndTag) {
156
                String tagName = element.getNode().getNodeName();
157
                if (support.isEndTag(element)) {
147
                    completionType = CompletionType.NONE;
158
                    completionType = CompletionType.NONE;
148
                    break;
159
                    break;
149
                }
160
                }
150
                if (element instanceof EmptyTag) {
161
                if (support.isEmptyTag(element)) {
151
                    if (token != null &&
162
                    if (chars.trim().equals("/>")) {
152
                            token.getImage().trim().equals("/>")) {
153
                        completionType = CompletionType.NONE;
163
                        completionType = CompletionType.NONE;
154
                        break;
164
                        break;
155
                    }
165
                    }
156
                    EmptyTag tag = (EmptyTag) element;
157
                    if (element.getElementOffset() + 1 == this.caretOffset) {
166
                    if (element.getElementOffset() + 1 == this.caretOffset) {
158
                        completionType = CompletionType.TAG;
167
                        completionType = CompletionType.TAG;
159
                        break;
168
                        break;
160
                    }
169
                    }
161
                    if (caretOffset > element.getElementOffset() + 1 &&
170
                    if (caretOffset > element.getElementOffset() + 1 &&
162
                            caretOffset <= element.getElementOffset() + 1 + tag.getTagName().length()) {
171
                            caretOffset <= element.getElementOffset() + 1 + tagName.length()) {
163
                        completionType = CompletionType.TAG;
172
                        completionType = CompletionType.TAG;
164
                        typedChars = tag.getTagName();
173
                        typedChars = tagName;
165
                        break;
174
                        break;
166
                    }
175
                    }
167
                    completionType = CompletionType.ATTRIBUTE;
176
                    completionType = CompletionType.ATTRIBUTE;
168
                    break;
177
                    break;
169
                }
178
                }
170
179
171
                if (element instanceof StartTag) {
180
                if (support.isStartTag(element)) {
172
                    if (token != null &&
181
                    if (token != null &&
173
                            token.getImage().trim().equals(">")) {
182
                            chars.equals(">")) {
174
                        completionType = CompletionType.NONE;
183
                        completionType = CompletionType.NONE;
175
                        break;
184
                        break;
176
                    }
185
                    }
177
                    if (token != null &&
186
                    if (token != null &&
178
                            token.getImage().trim().startsWith("</")) {
187
                            chars.startsWith("</")) {
179
                        typedChars = "";
188
                        typedChars = "";
180
                        completionType = CompletionType.VALUE;
189
                        completionType = CompletionType.VALUE;
181
                        break;
190
                        break;
182
                    }
191
                    }
183
                    if (element.getElementOffset() + 1 != this.caretOffset) {
192
                    if (element.getElementOffset() + 1 != this.caretOffset) {
184
                        StartTag tag = (StartTag) element;
193
                        typedChars = tagName;
185
                        typedChars = tag.getTagName();
186
                    }
194
                    }
187
                }
195
                }
188
                
196
                
189
                if (element instanceof Text) {
197
                if (element instanceof Text) {
190
                    if (token != null &&
198
                    if (token != null &&
191
                            token.getImage().trim().startsWith("</")) {
199
                            chars.startsWith("</")) {
192
                        typedChars = token.getPrevious().getImage().trim();
200
                        Token<XMLTokenId> previous = support.getPreviousToken(tOffset);
201
                        typedChars = previous.text().toString().trim();
193
                        completionType = CompletionType.VALUE;
202
                        completionType = CompletionType.VALUE;
194
                        break;
203
                        break;
195
                    }
204
                    }
Lines 203-243 Link Here
203
                break;
212
                break;
204
213
205
            //user enters an attribute name
214
            //user enters an attribute name
206
            case XMLDefaultTokenContext.ARGUMENT_ID:
215
            case ARGUMENT:
207
                completionType = CompletionType.ATTRIBUTE;
216
                completionType = CompletionType.ATTRIBUTE;
208
                typedChars = token.getImage().substring(0, caretOffset - token.getOffset());;
217
                typedChars = chars.substring(0, caretOffset - tOffset);
209
                break;
218
                break;
210
219
211
            //some random character
220
            //some random character
212
            case XMLDefaultTokenContext.CHARACTER_ID:
221
            case CHARACTER:
213
            //user enters = character, we should ignore all other operators
222
            //user enters = character, we should ignore all other operators
214
            case XMLDefaultTokenContext.OPERATOR_ID:
223
            case OPERATOR:
215
                completionType = CompletionType.NONE;
224
                completionType = CompletionType.NONE;
216
                break;
225
                break;
217
            //user enters either ' or "
226
            //user enters either ' or "
218
            case XMLDefaultTokenContext.VALUE_ID:
227
            case VALUE:
219
                if(!tokenBoundary) {
228
                if(!tokenBoundary) {
220
                    completionType = CompletionType.ATTRIBUTE_VALUE;
229
                    completionType = CompletionType.ATTRIBUTE_VALUE;
221
                    typedChars = token.getImage().substring(1, caretOffset - token.getOffset());
230
                    typedChars = chars.substring(1, caretOffset - tOffset);
222
                } else {
231
                } else {
223
                    completionType = CompletionType.NONE;
232
                    completionType = CompletionType.NONE;
224
                }
233
                }
225
                break;
234
                break;
226
235
227
            //user enters white-space character
236
            //user enters white-space character
228
            case XMLDefaultTokenContext.WS_ID:
237
            case WS:
229
                completionType = CompletionType.NONE;
238
                completionType = CompletionType.NONE;
230
                TokenItem prev = token.getPrevious();
239
                Token<XMLTokenId> prev = support.skip(tOffset, false, XMLTokenId.WS);
231
                while (prev != null &&
240
                if (prev == null) {
232
                        (prev.getTokenID().getNumericID() == XMLDefaultTokenContext.WS_ID)) {
241
                    completionType = CompletionType.NONE;
233
                    prev = prev.getPrevious();
242
                    break;
234
                }
243
                }
235
                
244
                if(prev.id() == XMLTokenId.ARGUMENT) {
236
                if(prev.getTokenID().getNumericID() == XMLDefaultTokenContext.ARGUMENT_ID) {
245
                    typedChars = prev.text().toString();
237
                    typedChars = prev.getImage();
238
                    completionType = CompletionType.ATTRIBUTE;
246
                    completionType = CompletionType.ATTRIBUTE;
239
                } else if ((prev.getTokenID().getNumericID() == XMLDefaultTokenContext.VALUE_ID) ||
247
                } else if ((prev.id() == XMLTokenId.VALUE) ||
240
                        (prev.getTokenID().getNumericID() == XMLDefaultTokenContext.TAG_ID)) {
248
                        (prev.id() == XMLTokenId.TAG)) {
241
                    completionType = CompletionType.ATTRIBUTE;
249
                    completionType = CompletionType.ATTRIBUTE;
242
                }
250
                }
243
                break;
251
                break;
Lines 270-296 Link Here
270
    
278
    
271
    public Node getTag() {
279
    public Node getTag() {
272
        SyntaxElement element = documentContext.getCurrentElement();
280
        SyntaxElement element = documentContext.getCurrentElement();
273
        return (element instanceof Tag) ? (Node) element : null;
281
        return element.getType() == Node.ELEMENT_NODE ? element.getNode() : null;
274
    }
282
    }
275
    
283
    
276
    public TokenItem getCurrentToken() {
284
    public Token<XMLTokenId> getCurrentToken() {
277
        return documentContext.getCurrentToken();
285
        return documentContext.getCurrentToken();
278
    }
286
    }
279
    
287
    
288
    public int getCurrentTokenOffset() {
289
        return documentContext.getCurrentTokenOffset();
290
    }
291
    
292
    private List<String> getExistingAttributesLocked(TokenSequence ts) {
293
        List<String> existingAttributes = new ArrayList<String>();
294
        while (ts.movePrevious()) {
295
            Token<XMLTokenId> item = ts.token();
296
            XMLTokenId tokenId = item.id();
297
            if (tokenId == XMLTokenId.TAG) {
298
                break;
299
            }
300
            if (tokenId == XMLTokenId.ARGUMENT) {
301
                existingAttributes.add(item.text().toString());
302
            }
303
        }
304
        return existingAttributes;
305
    }
306
280
    public List<String> getExistingAttributes() {
307
    public List<String> getExistingAttributes() {
281
        if(existingAttributes != null)
308
        if (existingAttributes == null) {
282
            return existingAttributes;
309
            try {
283
        existingAttributes = new ArrayList<String>();
310
                existingAttributes = (List<String>)support.runWithSequence(
284
        TokenItem item = documentContext.getCurrentToken().getPrevious();
311
                        documentContext.getCurrentTokenOffset(),
285
        while(item != null) {
312
                        this::getExistingAttributesLocked
286
            if(item.getTokenID().getNumericID() ==
313
                );
287
                    XMLDefaultTokenContext.TAG_ID)
314
            } catch (BadLocationException ex) {
288
                break;
315
                Exceptions.printStackTrace(ex);
289
            if(item.getTokenID().getNumericID() ==
290
                    XMLDefaultTokenContext.ARGUMENT_ID) {
291
                existingAttributes.add(item.getImage());
292
            }
316
            }
293
            item = item.getPrevious();
294
        }
317
        }
295
        return existingAttributes;
318
        return existingAttributes;
296
    }
319
    }
(-)a/web.beans/src/org/netbeans/modules/web/beans/completion/ContextUtilities.java (-92 / +26 lines)
Lines 44-56 Link Here
44
44
45
package org.netbeans.modules.web.beans.completion;
45
package org.netbeans.modules.web.beans.completion;
46
46
47
import javax.swing.text.BadLocationException;
47
import javax.xml.XMLConstants;
48
import javax.xml.XMLConstants;
49
import org.netbeans.api.lexer.Token;
50
import org.netbeans.api.lexer.TokenSequence;
51
import org.netbeans.api.xml.lexer.XMLTokenId;
52
import static org.netbeans.api.xml.lexer.XMLTokenId.ARGUMENT;
53
import static org.netbeans.api.xml.lexer.XMLTokenId.OPERATOR;
48
import org.netbeans.editor.TokenItem;
54
import org.netbeans.editor.TokenItem;
49
import org.netbeans.modules.xml.text.api.XMLDefaultTokenContext;
55
import org.netbeans.modules.xml.text.api.dom.SyntaxElement;
50
import org.netbeans.modules.xml.text.syntax.SyntaxElement;
56
import org.netbeans.modules.xml.text.api.dom.TagElement;
51
import org.netbeans.modules.xml.text.syntax.dom.EmptyTag;
57
import org.w3c.dom.Node;
52
import org.netbeans.modules.xml.text.syntax.dom.StartTag;
53
import org.netbeans.modules.xml.text.syntax.dom.Tag;
54
58
55
/**
59
/**
56
 *
60
 *
Lines 61-69 Link Here
61
    private ContextUtilities() {
65
    private ContextUtilities() {
62
    }
66
    }
63
    
67
    
64
    public static boolean isValueToken(TokenItem currentToken) {
68
    public static boolean isValueToken(Token<XMLTokenId> currentToken) {
65
        if(currentToken != null) {
69
        if(currentToken != null) {
66
            if (currentToken.getTokenID().getNumericID() == XMLDefaultTokenContext.VALUE_ID) {
70
            if (currentToken.id() == XMLTokenId.VALUE) {
67
                return true;
71
                return true;
68
            }
72
            }
69
        }
73
        }
Lines 71-79 Link Here
71
        return false;
75
        return false;
72
    }
76
    }
73
    
77
    
74
    public static boolean isTagToken(TokenItem currentToken) {
78
    public static boolean isTagToken(Token<XMLTokenId> currentToken) {
75
        if(currentToken != null) {
79
        if(currentToken != null) {
76
            if (currentToken.getTokenID().getNumericID() == XMLDefaultTokenContext.TAG_ID) {
80
            if (currentToken.id() == XMLTokenId.TAG) {
77
                return true;
81
                return true;
78
            }
82
            }
79
        }
83
        }
Lines 81-89 Link Here
81
        return false;
85
        return false;
82
    }
86
    }
83
    
87
    
84
    public static boolean isAttributeToken(TokenItem currentToken) {
88
    public static boolean isAttributeToken(Token<XMLTokenId> currentToken) {
85
        if(currentToken != null) {
89
        if(currentToken != null) {
86
            if (currentToken.getTokenID().getNumericID() == XMLDefaultTokenContext.ARGUMENT_ID) {
90
            if (currentToken.id() == XMLTokenId.ARGUMENT) {
87
                return true;
91
                return true;
88
            }
92
            }
89
        }
93
        }
Lines 91-178 Link Here
91
        return false;
95
        return false;
92
    }
96
    }
93
    
97
    
94
    public static TokenItem getAttributeToken(TokenItem currentToken) {
98
    public static Token<XMLTokenId> getAttributeToken(DocumentContext context) {
95
        if(currentToken == null )
99
        if(context.getCurrentToken() == null ) {
96
            return null;
100
            return null;
97
        
98
        if(isValueToken(currentToken)) {
99
            TokenItem equalsToken = currentToken.getPrevious();
100
            if(equalsToken == null)
101
                return null;
102
            
103
            while(equalsToken != null && equalsToken.getTokenID().getNumericID() != XMLDefaultTokenContext.OPERATOR_ID) {
104
                equalsToken = equalsToken.getPrevious();
105
            }
106
            
107
            if(equalsToken == null) {
108
                return null;
109
            }
110
        
111
            TokenItem argumentToken = equalsToken.getPrevious();
112
            if(argumentToken == null)
113
                return null;
114
            
115
            while(argumentToken != null && argumentToken.getTokenID().getNumericID() != XMLDefaultTokenContext.ARGUMENT_ID) {
116
                argumentToken = argumentToken.getPrevious();
117
            }
118
        
119
            return argumentToken;
120
        }
101
        }
121
        
102
        return context.getSyntaxSupport().getAttributeToken(context.getCurrentTokenOffset());
122
        return null;
123
    }
103
    }
124
  
104
125
    public static Tag getCurrentTagElement(DocumentContext context) {
126
        SyntaxElement element = context.getCurrentElement();
127
        if(element instanceof StartTag) {
128
            return (StartTag) element;
129
        } else if(element instanceof EmptyTag) {
130
            return (EmptyTag) element;
131
        }
132
        
133
        return null;
134
    }
135
    
136
    public static TokenItem getAttributeToken(DocumentContext context) {
137
        if(context.getCurrentToken() == null )
138
            return null;
139
        
140
        if(isValueToken(context.getCurrentToken())) {
141
            TokenItem equalsToken = context.getCurrentToken().getPrevious();
142
            if(equalsToken == null)
143
                return null;
144
            
145
            //getTokenId() should not return null by JavaDoc. But in reality, it does reutrn null sometimes
146
            // see issue 67661
147
            if(equalsToken.getTokenID() == null) {
148
                return null;
149
            }
150
            while(equalsToken != null && equalsToken.getTokenID().getNumericID() != XMLDefaultTokenContext.OPERATOR_ID) {
151
                equalsToken = equalsToken.getPrevious();
152
            }
153
            
154
            if(equalsToken == null) {
155
                return null;
156
            }
157
        
158
            TokenItem argumentToken = equalsToken.getPrevious();
159
            if(argumentToken == null)
160
                return null;
161
            
162
            while(argumentToken != null && argumentToken.getTokenID().getNumericID() != XMLDefaultTokenContext.ARGUMENT_ID) {
163
                argumentToken = argumentToken.getPrevious();
164
            }
165
        
166
            return argumentToken;
167
        }
168
        
169
        return null;
170
    }
171
    
172
    public static String getAttributeTokenImage(DocumentContext context) {
105
    public static String getAttributeTokenImage(DocumentContext context) {
173
        TokenItem tok = getAttributeToken(context);
106
        Token<XMLTokenId> tok = getAttributeToken(context);
174
        if(tok != null) {
107
        if(tok != null) {
175
            return tok.getImage();
108
            return tok.text().toString();
176
        }
109
        }
177
        
110
        
178
        return null;
111
        return null;
Lines 221-231 Link Here
221
        return nodeName.substring(0, colonIndex);
154
        return nodeName.substring(0, colonIndex);
222
    }
155
    }
223
    
156
    
224
    public static StartTag getRoot(SyntaxElement se) {
157
    public static SyntaxElement getRoot(SyntaxElement se) {
225
        StartTag root = null;
158
        SyntaxElement root = null;
226
        while( se != null) {
159
        while( se != null) {
227
            if(se instanceof StartTag) {
160
            if(se.getType() == Node.ELEMENT_NODE &&
228
                root = (StartTag)se;
161
               ((TagElement)se).isStart()) {
162
                root = se;
229
            }
163
            }
230
            se = se.getPrevious();
164
            se = se.getPrevious();
231
        }
165
        }
(-)a/web.beans/src/org/netbeans/modules/web/beans/completion/DocumentContext.java (-69 / +30 lines)
Lines 55-68 Link Here
55
import java.util.logging.Logger;
55
import java.util.logging.Logger;
56
import javax.swing.text.BadLocationException;
56
import javax.swing.text.BadLocationException;
57
import javax.swing.text.Document;
57
import javax.swing.text.Document;
58
import org.netbeans.api.lexer.Token;
59
import org.netbeans.api.xml.lexer.XMLTokenId;
58
import org.netbeans.editor.BaseDocument;
60
import org.netbeans.editor.BaseDocument;
59
import org.netbeans.editor.TokenItem;
61
import org.netbeans.editor.TokenItem;
60
import org.netbeans.modules.xml.text.syntax.SyntaxElement;
62
import org.netbeans.modules.xml.text.api.dom.SyntaxElement;
61
import org.netbeans.modules.xml.text.syntax.XMLSyntaxSupport;
63
import org.netbeans.modules.xml.text.api.dom.XMLSyntaxSupport;
62
import org.netbeans.modules.xml.text.syntax.dom.EmptyTag;
63
import org.netbeans.modules.xml.text.syntax.dom.EndTag;
64
import org.netbeans.modules.xml.text.syntax.dom.StartTag;
65
import org.netbeans.modules.xml.text.syntax.dom.Tag;
66
import org.w3c.dom.Attr;
64
import org.w3c.dom.Attr;
67
import org.w3c.dom.NamedNodeMap;
65
import org.w3c.dom.NamedNodeMap;
68
import org.w3c.dom.Node;
66
import org.w3c.dom.Node;
Lines 83-91 Link Here
83
    private XMLSyntaxSupport syntaxSupport;
81
    private XMLSyntaxSupport syntaxSupport;
84
    private int caretOffset = -1;
82
    private int caretOffset = -1;
85
    private SyntaxElement element;
83
    private SyntaxElement element;
86
    private TokenItem token;
84
    private Token<XMLTokenId> token;
85
    private int tokenOffset;
87
    private boolean valid = false;
86
    private boolean valid = false;
88
    private StartTag docRoot;
87
    private SyntaxElement docRoot;
89
    private String defaultNamespace;
88
    private String defaultNamespace;
90
    private HashMap<String, String> declaredNamespaces =
89
    private HashMap<String, String> declaredNamespaces =
91
            new HashMap<String, String>();
90
            new HashMap<String, String>();
Lines 95-104 Link Here
95
    DocumentContext(Document document) {
94
    DocumentContext(Document document) {
96
        this.document = document;
95
        this.document = document;
97
        try {
96
        try {
98
            this.syntaxSupport = (XMLSyntaxSupport) ((BaseDocument)document).getSyntaxSupport();
97
            this.syntaxSupport = XMLSyntaxSupport.getSyntaxSupport(document);
99
        } catch (ClassCastException cce) {
98
        } catch (ClassCastException cce) {
100
            LOGGER.log(Level.FINE, cce.getMessage());
99
            LOGGER.log(Level.FINE, cce.getMessage());
101
            this.syntaxSupport = new XMLSyntaxSupport(((BaseDocument)document));
100
            this.syntaxSupport = XMLSyntaxSupport.createSyntaxSupport(document);
102
        }
101
        }
103
    }
102
    }
104
103
Lines 112-118 Link Here
112
        declaredNamespaces.clear();
111
        declaredNamespaces.clear();
113
        try {
112
        try {
114
            element = syntaxSupport.getElementChain(caretOffset);
113
            element = syntaxSupport.getElementChain(caretOffset);
115
            token = syntaxSupport.getTokenChain(caretOffset, Math.min(document.getLength(), caretOffset+1));
114
            int[] bounds = new int[1];
115
            token = syntaxSupport.getTokenAtPosition(caretOffset, bounds);
116
            tokenOffset = bounds[0];
116
            this.docRoot = ContextUtilities.getRoot(element);
117
            this.docRoot = ContextUtilities.getRoot(element);
117
            populateNamespaces();
118
            populateNamespaces();
118
        } catch (BadLocationException ex) {
119
        } catch (BadLocationException ex) {
Lines 125-139 Link Here
125
        return this.valid;
126
        return this.valid;
126
    }
127
    }
127
128
128
    public int getCurrentTokenId() {
129
    public XMLTokenId getCurrentTokenId() {
129
        if (isValid()) {
130
        if (isValid()) {
130
            return token.getTokenID().getNumericID();
131
            return token.id();
131
        } else {
132
        } else {
132
            return -1;
133
            return null;
133
        }
134
        }
134
    }
135
    }
135
136
136
    public TokenItem getCurrentToken() {
137
    public Token<XMLTokenId> getCurrentToken() {
137
        if (isValid()) {
138
        if (isValid()) {
138
            return token;
139
            return token;
139
        } else {
140
        } else {
Lines 143-149 Link Here
143
144
144
    public String getCurrentTokenImage() {
145
    public String getCurrentTokenImage() {
145
        if (isValid()) {
146
        if (isValid()) {
146
            return token.getImage();
147
            return token.text().toString();
147
        } else {
148
        } else {
148
            return null;
149
            return null;
149
        }
150
        }
Lines 153-206 Link Here
153
        return this.element;
154
        return this.element;
154
    }
155
    }
155
    
156
    
156
    public List<String> getPathFromRoot() {
157
        if (isValid()) {
158
            SyntaxElement elementRef = this.element;
159
            Stack<SyntaxElement> stack = new Stack<SyntaxElement>();
160
161
            while (elementRef != null) {
162
                if ((elementRef instanceof EndTag) ||
163
                        (elementRef instanceof EmptyTag && stack.isEmpty()) ||
164
                        (elementRef instanceof StartTag && stack.isEmpty())) {
165
                    stack.push(elementRef);
166
                    elementRef = elementRef.getPrevious();
167
                    continue;
168
                }
169
                if (elementRef instanceof StartTag) {
170
                    StartTag start = (StartTag) elementRef;
171
                    if (stack.peek() instanceof EndTag) {
172
                        EndTag end = (EndTag) stack.peek();
173
                        if (end.getTagName().equals(start.getTagName())) {
174
                            stack.pop();
175
                        }
176
                    } else {
177
                        SyntaxElement e = (SyntaxElement) stack.peek();
178
                        String tagAtTop = (e instanceof StartTag) ? ((StartTag) e).getTagName() : ((EmptyTag) e).getTagName();
179
                        stack.push(elementRef);
180
                    }
181
                }
182
                elementRef = elementRef.getPrevious();
183
            }
184
185
            return createPath(stack);
186
        }
187
188
        return Collections.emptyList();
189
    }
190
191
    private List<String> createPath(Stack<SyntaxElement> stack) {
192
        ArrayList<String> pathList = new ArrayList<String>();
193
        while (!stack.isEmpty()) {
194
            SyntaxElement top = stack.pop();
195
            String tagName = (top instanceof StartTag) ? ((StartTag) top).getTagName() : ((EmptyTag) top).getTagName();
196
            if (tagName != null) {
197
                pathList.add(tagName);
198
            }
199
        }
200
201
        return Collections.unmodifiableList(pathList);
202
    }
203
204
    public Document getDocument() {
157
    public Document getDocument() {
205
        return this.document;
158
        return this.document;
206
    }
159
    }
Lines 223-240 Link Here
223
        return declaredNamespaces.values();
176
        return declaredNamespaces.values();
224
    }
177
    }
225
178
226
    public StartTag getDocRoot() {
179
    public SyntaxElement getDocRoot() {
227
        return docRoot;
180
        return docRoot;
228
    }
181
    }
229
182
230
    public int getCaretOffset() {
183
    public int getCaretOffset() {
231
        return this.caretOffset;
184
        return this.caretOffset;
232
    }
185
    }
186
    
187
    public int getCurrentTokenOffset() {
188
        return tokenOffset;
189
    }
233
190
234
    private void populateNamespaces() {
191
    private void populateNamespaces() {
235
        // Find the a start or empty tag just before the current syntax element.
192
        // Find the a start or empty tag just before the current syntax element.
236
        SyntaxElement element = this.element;
193
        SyntaxElement element = this.element;
237
        while (element != null && !(element instanceof StartTag) && !(element instanceof EmptyTag)) {
194
        while (element != null && !syntaxSupport.isStartTag(element) && !syntaxSupport.isEmptyTag(element)) {
238
            element = element.getPrevious();
195
            element = element.getPrevious();
239
        }
196
        }
240
        if (element == null) {
197
        if (element == null) {
Lines 244-252 Link Here
244
        // To find all namespace declarations active at the caret offset, we
201
        // To find all namespace declarations active at the caret offset, we
245
        // need to look at xmlns attributes of the current element and its ancestors.
202
        // need to look at xmlns attributes of the current element and its ancestors.
246
        Node node = (Node)element;
203
        Node node = (Node)element;
247
        while (node != null) {
204
        while (node != null && element != null) {
248
            if (node instanceof StartTag || node instanceof EmptyTag) {
205
            if (syntaxSupport.isStartTag(element) || syntaxSupport.isEmptyTag(element)) {
249
                NamedNodeMap attributes = ((Tag)node).getAttributes();
206
                NamedNodeMap attributes = node.getAttributes();
250
                for (int index = 0; index < attributes.getLength(); index++) {
207
                for (int index = 0; index < attributes.getLength(); index++) {
251
                    Attr attr = (Attr) attributes.item(index);
208
                    Attr attr = (Attr) attributes.item(index);
252
                    String attrName = attr.getName();
209
                    String attrName = attr.getName();
Lines 297-300 Link Here
297
        hash = 61 * hash + (this.document != null ? this.document.hashCode() : 0);
254
        hash = 61 * hash + (this.document != null ? this.document.hashCode() : 0);
298
        return hash;
255
        return hash;
299
    }
256
    }
257
    
258
    public XMLSyntaxSupport getSyntaxSupport() {
259
        return syntaxSupport;
260
    }
300
}
261
}
(-)a/web.core.syntax/src/org/netbeans/modules/web/core/xmlsyntax/JspXMLTokenContext.java (-1 lines)
Lines 52-58 Link Here
52
52
53
import org.netbeans.modules.xml.text.api.XMLDefaultTokenContext;
53
import org.netbeans.modules.xml.text.api.XMLDefaultTokenContext;
54
54
55
56
/**
55
/**
57
* Token context for JSP pages with XML content.
56
* Token context for JSP pages with XML content.
58
*
57
*
(-)a/xml.catalog/src/org/netbeans/modules/xml/catalog/CatalogEntityResolver.java (+2 lines)
Lines 55-60 Link Here
55
import org.netbeans.api.xml.services.*;
55
import org.netbeans.api.xml.services.*;
56
import org.openide.util.Lookup;
56
import org.openide.util.Lookup;
57
import javax.xml.transform.URIResolver;
57
import javax.xml.transform.URIResolver;
58
import org.openide.util.lookup.ServiceProvider;
58
59
59
/**
60
/**
60
 * An entity resolver that can resolve all registrations
61
 * An entity resolver that can resolve all registrations
Lines 68-73 Link Here
68
 * @author  Petr Kuzel
69
 * @author  Petr Kuzel
69
 * @version 1.0
70
 * @version 1.0
70
 */
71
 */
72
@ServiceProvider(service = UserCatalog.class)
71
public class CatalogEntityResolver extends UserCatalog implements EntityResolver, URIResolver {
73
public class CatalogEntityResolver extends UserCatalog implements EntityResolver, URIResolver {
72
74
73
    /** Creates new CatalogEntityResolver */
75
    /** Creates new CatalogEntityResolver */
(-)a/xml.catalog/src/org/netbeans/modules/xml/catalog/impl/SystemCatalogProvider.java (+2 lines)
Lines 46-51 Link Here
46
import java.io.IOException;
46
import java.io.IOException;
47
47
48
import org.netbeans.modules.xml.catalog.spi.CatalogProvider;
48
import org.netbeans.modules.xml.catalog.spi.CatalogProvider;
49
import org.openide.util.lookup.ServiceProvider;
49
50
50
/**
51
/**
51
 * Provide class representing SystemCatalogReader class.
52
 * Provide class representing SystemCatalogReader class.
Lines 53-58 Link Here
53
 * @author  Petr Kuzel
54
 * @author  Petr Kuzel
54
 * @version
55
 * @version
55
 */
56
 */
57
@ServiceProvider(service = CatalogProvider.class)
56
public class SystemCatalogProvider implements CatalogProvider {
58
public class SystemCatalogProvider implements CatalogProvider {
57
59
58
    public Class provideClass() throws IOException, ClassNotFoundException {
60
    public Class provideClass() throws IOException, ClassNotFoundException {
(-)a/xml.catalog/src/org/netbeans/modules/xml/catalog/impl/XCatalogProvider.java (+2 lines)
Lines 46-51 Link Here
46
import java.io.IOException;
46
import java.io.IOException;
47
47
48
import org.netbeans.modules.xml.catalog.spi.CatalogProvider;
48
import org.netbeans.modules.xml.catalog.spi.CatalogProvider;
49
import org.openide.util.lookup.ServiceProvider;
49
50
50
/**
51
/**
51
 * Provide class representing XCatalog class.
52
 * Provide class representing XCatalog class.
Lines 53-58 Link Here
53
 * @author  Petr Kuzel
54
 * @author  Petr Kuzel
54
 * @version
55
 * @version
55
 */
56
 */
57
@ServiceProvider(service = CatalogProvider.class)
56
public class XCatalogProvider implements CatalogProvider {
58
public class XCatalogProvider implements CatalogProvider {
57
59
58
    public Class provideClass() throws IOException, ClassNotFoundException {
60
    public Class provideClass() throws IOException, ClassNotFoundException {
(-)a/xml.catalog/src/org/netbeans/modules/xml/catalog/impl/sun/SunCatalogProvider.java (+2 lines)
Lines 46-51 Link Here
46
import java.io.IOException;
46
import java.io.IOException;
47
47
48
import org.netbeans.modules.xml.catalog.spi.CatalogProvider;
48
import org.netbeans.modules.xml.catalog.spi.CatalogProvider;
49
import org.openide.util.lookup.ServiceProvider;
49
50
50
/**
51
/**
51
 * Provide class representing Catalog reader class.
52
 * Provide class representing Catalog reader class.
Lines 53-58 Link Here
53
 * @author  Petr Kuzel
54
 * @author  Petr Kuzel
54
 * @version
55
 * @version
55
 */
56
 */
57
@ServiceProvider(service = CatalogProvider.class)
56
public class SunCatalogProvider implements CatalogProvider {
58
public class SunCatalogProvider implements CatalogProvider {
57
59
58
    public Class provideClass() throws IOException, ClassNotFoundException {
60
    public Class provideClass() throws IOException, ClassNotFoundException {
(-)a/xml.catalog/src/org/netbeans/modules/xml/catalog/resources/mf-layer.xml (-27 lines)
Lines 63-95 Link Here
63
        </folder>
63
        </folder>
64
    </folder>
64
    </folder>
65
65
66
    <!-- register services with Lookup -->  
67
    <folder name="Services">
68
        <folder name="Hidden">
69
70
            <file name="org-netbeans-modules-xml-catalog-CatalogEntityResolver.instance">
71
                <attr name="instanceOf" stringvalue="org.netbeans.api.xml.services.UserCatalog"/>
72
            </file>
73
            <folder name="CatalogProvider">
74
                <file name="org-netbeans-modules-xml-catalog-impl-sun-SunCatalogProvider.instance">
75
                    <attr name="instanceOf" stringvalue="org.netbeans.modules.xml.catalog.spi.CatalogProvider"/>
76
                    <attr name="position" intvalue="100"/>
77
                </file>
78
                <file name="org-netbeans-modules-xml-catalog-impl-SystemCatalogProvider.instance">
79
                    <attr name="instanceOf" stringvalue="org.netbeans.modules.xml.catalog.spi.CatalogProvider"/>
80
                    <attr name="position" intvalue="200"/>
81
                </file>
82
                <file name="org-netbeans-modules-xml-catalog-impl-XCatalogProvider.instance">
83
                    <attr name="instanceOf" stringvalue="org.netbeans.modules.xml.catalog.spi.CatalogProvider"/>
84
                    <attr name="position" intvalue="300"/>
85
                </file>
86
            </folder>
87
88
            <!-- Store mounted catalogs per project. -->
89
            <file name="org-netbeans-modules-xml-catalog-settings-CatalogSettings.settings" url="ProjectSettings.xml"/>
90
        </folder>
91
    </folder>
92
93
    <!-- register entities with system entity resolver -->
66
    <!-- register entities with system entity resolver -->
94
    <folder name="xml">
67
    <folder name="xml">
95
        <folder name="entities">
68
        <folder name="entities">
(-)a/xml.catalog/src/org/netbeans/modules/xml/catalog/settings/CatalogSettings.java (-1 / +2 lines)
Lines 49-55 Link Here
49
import java.util.logging.Level;
49
import java.util.logging.Level;
50
import org.netbeans.modules.xml.catalog.lib.IteratorIterator;
50
import org.netbeans.modules.xml.catalog.lib.IteratorIterator;
51
51
52
import org.openide.*;
53
import org.openide.util.io.NbMarshalledObject;
52
import org.openide.util.io.NbMarshalledObject;
54
53
55
import org.netbeans.modules.xml.catalog.spi.*;
54
import org.netbeans.modules.xml.catalog.spi.*;
Lines 57-62 Link Here
57
import org.openide.util.Lookup;
56
import org.openide.util.Lookup;
58
import org.openide.util.NbBundle;
57
import org.openide.util.NbBundle;
59
import org.openide.util.lookup.Lookups;
58
import org.openide.util.lookup.Lookups;
59
import org.openide.util.lookup.ServiceProvider;
60
60
61
61
62
/** 
62
/** 
Lines 92-97 Link Here
92
 *
92
 *
93
 * @author  Petr Kuzel
93
 * @author  Petr Kuzel
94
 */
94
 */
95
@ServiceProvider(service = CatalogSettings.class)
95
public final class CatalogSettings implements Externalizable {
96
public final class CatalogSettings implements Externalizable {
96
97
97
    /** Serial Version UID */
98
    /** Serial Version UID */
(-)a/xml.lexer/nbproject/project.xml (+9 lines)
Lines 45-50 Link Here
45
            <code-name-base>org.netbeans.modules.xml.lexer</code-name-base>
45
            <code-name-base>org.netbeans.modules.xml.lexer</code-name-base>
46
            <module-dependencies>
46
            <module-dependencies>
47
                <dependency>
47
                <dependency>
48
                    <code-name-base>org.netbeans.modules.editor.mimelookup</code-name-base>
49
                    <build-prerequisite/>
50
                    <compile-dependency/>
51
                    <run-dependency>
52
                        <release-version>1</release-version>
53
                        <specification-version>1.41</specification-version>
54
                    </run-dependency>
55
                </dependency>
56
                <dependency>
48
                    <code-name-base>org.netbeans.modules.lexer</code-name-base>
57
                    <code-name-base>org.netbeans.modules.lexer</code-name-base>
49
                    <build-prerequisite/>
58
                    <build-prerequisite/>
50
                    <compile-dependency/>
59
                    <compile-dependency/>
(-)a/xml.lexer/src/org/netbeans/api/xml/lexer/XMLTokenId.java (+2 lines)
Lines 46-51 Link Here
46
import java.util.EnumSet;
46
import java.util.EnumSet;
47
import java.util.HashMap;
47
import java.util.HashMap;
48
import java.util.Map;
48
import java.util.Map;
49
import org.netbeans.api.editor.mimelookup.MimeRegistration;
49
import org.netbeans.api.lexer.InputAttributes;
50
import org.netbeans.api.lexer.InputAttributes;
50
import org.netbeans.api.lexer.Language;
51
import org.netbeans.api.lexer.Language;
51
import org.netbeans.api.lexer.LanguagePath;
52
import org.netbeans.api.lexer.LanguagePath;
Lines 144-149 Link Here
144
        }
145
        }
145
    }.language();
146
    }.language();
146
    
147
    
148
    @MimeRegistration(mimeType = "text/xml", service = Language.class)
147
    public static Language<XMLTokenId> language() {
149
    public static Language<XMLTokenId> language() {
148
        return language;
150
        return language;
149
    }
151
    }
(-)a/xml.lexer/src/org/netbeans/lib/xml/lexer/XMLLexer.java (-1 / +4 lines)
Lines 361-370 Link Here
361
                            // note: it would be more correct to raise an error here,
361
                            // note: it would be more correct to raise an error here,
362
                            // and return TAG PartType=Start, BUT some code already expects
362
                            // and return TAG PartType=Start, BUT some code already expects
363
                            // unfinished tags to be reported as TEXT.
363
                            // unfinished tags to be reported as TEXT.
364
                            state = INIT;
364
                            state = ISI_TEXT;
365
                            input.backup(1);
365
                            input.backup(1);
366
                            break;
367
                            /*
366
                            return tokenFactory.createToken(
368
                            return tokenFactory.createToken(
367
                                    XMLTokenId.TEXT, input.readLength());
369
                                    XMLTokenId.TEXT, input.readLength());
370
                            */
368
                    }
371
                    }
369
                    break;
372
                    break;
370
                    
373
                    
(-)a/xml.lexer/src/org/netbeans/lib/xml/lexer/layer.xml (-4 lines)
Lines 45-54 Link Here
45
    <folder name="Editors">
45
    <folder name="Editors">
46
        <folder name="text">
46
        <folder name="text">
47
            <folder name="xml">
47
            <folder name="xml">
48
                <file name="language.instance">
49
                    <attr name="instanceCreate" methodvalue="org.netbeans.api.xml.lexer.XMLTokenId.language"/>
50
                    <attr name="instanceOf" stringvalue="org.netbeans.api.lexer.Language"/>
51
                </file>
52
            </folder>
48
            </folder>
53
        </folder>
49
        </folder>
54
    </folder>
50
    </folder>
(-)a/xml.lexer/test/unit/src/org/netbeans/api/xml/lexer/BrokenXMLTest.java (-1 / +1 lines)
Lines 66-72 Link Here
66
     */
66
     */
67
    public void testTokens() throws Exception {
67
    public void testTokens() throws Exception {
68
        XMLTokenId[] expectedIds = {XMLTokenId.PI_START, XMLTokenId.PI_TARGET, XMLTokenId.WS, XMLTokenId.PI_CONTENT,
68
        XMLTokenId[] expectedIds = {XMLTokenId.PI_START, XMLTokenId.PI_TARGET, XMLTokenId.WS, XMLTokenId.PI_CONTENT,
69
            XMLTokenId.PI_END, XMLTokenId.TEXT, XMLTokenId.TAG, XMLTokenId.TAG, XMLTokenId.TEXT, XMLTokenId.TEXT, XMLTokenId.TEXT,
69
            XMLTokenId.PI_END, XMLTokenId.TEXT, XMLTokenId.TAG, XMLTokenId.TAG, XMLTokenId.TEXT, XMLTokenId.TEXT, 
70
            XMLTokenId.TAG, XMLTokenId.TAG, XMLTokenId.TEXT, XMLTokenId.TAG, XMLTokenId.ERROR, 
70
            XMLTokenId.TAG, XMLTokenId.TAG, XMLTokenId.TEXT, XMLTokenId.TAG, XMLTokenId.ERROR, 
71
            XMLTokenId.TAG, XMLTokenId.TAG, XMLTokenId.TEXT, XMLTokenId.TAG, XMLTokenId.TAG, XMLTokenId.TEXT  };
71
            XMLTokenId.TAG, XMLTokenId.TAG, XMLTokenId.TEXT, XMLTokenId.TAG, XMLTokenId.TAG, XMLTokenId.TEXT  };
72
        javax.swing.text.Document document = getDocument("resources/broken.xml");
72
        javax.swing.text.Document document = getDocument("resources/broken.xml");
(-)a/xml.schema.completion/manifest.mf (-1 / +1 lines)
Lines 2-6 Link Here
2
OpenIDE-Module: org.netbeans.modules.xml.schema.completion
2
OpenIDE-Module: org.netbeans.modules.xml.schema.completion
3
OpenIDE-Module-Layer: org/netbeans/modules/xml/schema/completion/layer.xml
3
OpenIDE-Module-Layer: org/netbeans/modules/xml/schema/completion/layer.xml
4
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/xml/schema/completion/Bundle.properties
4
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/xml/schema/completion/Bundle.properties
5
OpenIDE-Module-Specification-Version: 1.31
5
OpenIDE-Module-Specification-Version: 1.32
6
AutoUpdate-Show-In-Client: false
6
AutoUpdate-Show-In-Client: false
(-)a/xml.schema.completion/nbproject/project.properties (-1 / +1 lines)
Lines 30-36 Link Here
30
# Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
30
# Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
31
# Microsystems, Inc. All Rights Reserved.
31
# Microsystems, Inc. All Rights Reserved.
32
32
33
javac.source=1.6
33
javac.source=1.8
34
javadoc.arch=${basedir}/arch.xml
34
javadoc.arch=${basedir}/arch.xml
35
# XXX should be deleted in simpletests branch (see project.xml entry):
35
# XXX should be deleted in simpletests branch (see project.xml entry):
36
test.qa-functional.cp.extra=\
36
test.qa-functional.cp.extra=\
(-)a/xml.schema.completion/nbproject/project.xml (-9 / +22 lines)
Lines 103-108 Link Here
103
                    </run-dependency>
103
                    </run-dependency>
104
                </dependency>
104
                </dependency>
105
                <dependency>
105
                <dependency>
106
                    <code-name-base>org.netbeans.modules.nbjunit</code-name-base>
107
                    <build-prerequisite/>
108
                    <compile-dependency/>
109
                    <run-dependency>
110
                        <release-version>1</release-version>
111
                        <specification-version>1.88</specification-version>
112
                    </run-dependency>
113
                </dependency>
114
                <dependency>
106
                    <code-name-base>org.netbeans.modules.projectapi</code-name-base>
115
                    <code-name-base>org.netbeans.modules.projectapi</code-name-base>
107
                    <build-prerequisite/>
116
                    <build-prerequisite/>
108
                    <compile-dependency/>
117
                    <compile-dependency/>
Lines 151-157 Link Here
151
                    <compile-dependency/>
160
                    <compile-dependency/>
152
                    <run-dependency>
161
                    <run-dependency>
153
                        <release-version>2</release-version>
162
                        <release-version>2</release-version>
154
                        <specification-version>1.16</specification-version>
163
                        <specification-version>1.60</specification-version>
155
                    </run-dependency>
164
                    </run-dependency>
156
                </dependency>
165
                </dependency>
157
                <dependency>
166
                <dependency>
Lines 195-208 Link Here
195
                    </run-dependency>
204
                    </run-dependency>
196
                </dependency>
205
                </dependency>
197
                <dependency>
206
                <dependency>
198
                    <code-name-base>org.openide.util.ui</code-name-base>
199
                    <build-prerequisite/>
200
                    <compile-dependency/>
201
                    <run-dependency>
202
                        <specification-version>9.3</specification-version>
203
                    </run-dependency>
204
                </dependency>
205
                <dependency>
206
                    <code-name-base>org.openide.util</code-name-base>
207
                    <code-name-base>org.openide.util</code-name-base>
207
                    <build-prerequisite/>
208
                    <build-prerequisite/>
208
                    <compile-dependency/>
209
                    <compile-dependency/>
Lines 218-223 Link Here
218
                        <specification-version>8.0</specification-version>
219
                        <specification-version>8.0</specification-version>
219
                    </run-dependency>
220
                    </run-dependency>
220
                </dependency>
221
                </dependency>
222
                <dependency>
223
                    <code-name-base>org.openide.util.ui</code-name-base>
224
                    <build-prerequisite/>
225
                    <compile-dependency/>
226
                    <run-dependency>
227
                        <specification-version>9.3</specification-version>
228
                    </run-dependency>
229
                </dependency>
221
            </module-dependencies>
230
            </module-dependencies>
222
            <test-dependencies>
231
            <test-dependencies>
223
                <test-type>
232
                <test-type>
Lines 253-258 Link Here
253
                        <code-name-base>org.netbeans.modules.xml.xdm</code-name-base>
262
                        <code-name-base>org.netbeans.modules.xml.xdm</code-name-base>
254
                        <recursive/>
263
                        <recursive/>
255
                    </test-dependency>
264
                    </test-dependency>
265
                    <test-dependency>
266
                        <code-name-base>org.netbeans.modules.xml.catalog</code-name-base>
267
                        <recursive/>
268
                    </test-dependency>
256
                </test-type>
269
                </test-type>
257
            </test-dependencies>
270
            </test-dependencies>
258
            <public-packages>
271
            <public-packages>
(-)a/xml.schema.completion/src/org/netbeans/modules/xml/schema/completion/CompletionQuery.java (-6 / +17 lines)
Lines 57-69 Link Here
57
import java.util.logging.Level;
57
import java.util.logging.Level;
58
import java.util.logging.Logger;
58
import java.util.logging.Logger;
59
import javax.swing.ImageIcon;
59
import javax.swing.ImageIcon;
60
import javax.swing.text.AbstractDocument;
60
import javax.swing.text.Document;
61
import javax.swing.text.Document;
61
import javax.swing.text.JTextComponent;
62
import javax.swing.text.JTextComponent;
62
import org.netbeans.api.editor.completion.Completion;
63
import org.netbeans.api.editor.completion.Completion;
64
import org.netbeans.api.lexer.Token;
65
import org.netbeans.api.lexer.TokenHierarchy;
66
import org.netbeans.api.lexer.TokenSequence;
67
import org.netbeans.api.xml.lexer.XMLTokenId;
63
import org.netbeans.editor.BaseDocument;
68
import org.netbeans.editor.BaseDocument;
64
import org.netbeans.modules.xml.schema.completion.util.CompletionContextImpl;
69
import org.netbeans.modules.xml.schema.completion.util.CompletionContextImpl;
65
import org.netbeans.modules.xml.schema.completion.util.CompletionUtil;
70
import org.netbeans.modules.xml.schema.completion.util.CompletionUtil;
66
import org.netbeans.modules.xml.text.syntax.XMLSyntaxSupport;
71
import org.netbeans.modules.xml.text.api.dom.XMLSyntaxSupport;
67
import org.netbeans.spi.editor.completion.CompletionItem;
72
import org.netbeans.spi.editor.completion.CompletionItem;
68
import org.netbeans.spi.editor.completion.CompletionResultSet;
73
import org.netbeans.spi.editor.completion.CompletionResultSet;
69
import org.netbeans.spi.editor.completion.CompletionTask;
74
import org.netbeans.spi.editor.completion.CompletionTask;
Lines 120-135 Link Here
120
    protected void prepareQuery(JTextComponent component) {
125
    protected void prepareQuery(JTextComponent component) {
121
        this.component = component;
126
        this.component = component;
122
    }
127
    }
123
    
128
124
    @Override
129
    @Override
125
    protected void query(CompletionResultSet resultSet, Document doc, int caretOffset) {
130
    protected void query(CompletionResultSet resultSet, Document doc, int caretOffset) {
126
        XMLSyntaxSupport support = 
131
        XMLSyntaxSupport support = XMLSyntaxSupport.getSyntaxSupport(doc);
127
            (XMLSyntaxSupport) ((BaseDocument) doc).getSyntaxSupport();
132
        if (support == null) {
133
            resultSet.finish();
134
            return;
135
        }
128
136
129
        CompletionResultItem endTagResultItem = CompletionUtil.getEndTagCompletionItem(
137
        CompletionResultItem endTagResultItem = CompletionUtil.getEndTagCompletionItem(
130
            component, (BaseDocument) doc);
138
            component, (BaseDocument) doc);
131
        List<CompletionResultItem> completionItems = null;
139
        List<CompletionResultItem> completionItems = null;
132
        if (! support.noCompletion(component) &&
140
        if (!CompletionUtil.noCompletion(component) &&
133
           (CompletionUtil.canProvideCompletion((BaseDocument) doc))) {
141
           (CompletionUtil.canProvideCompletion((BaseDocument) doc))) {
134
            
142
            
135
            resultSet.setWaitText(NbBundle.getMessage(CompletionQuery.class, "MSG_PreparingXmlSchemas")); // NOI18N
143
            resultSet.setWaitText(NbBundle.getMessage(CompletionQuery.class, "MSG_PreparingXmlSchemas")); // NOI18N
Lines 350-356 Link Here
350
        List<CompletionResultItem> completionItems = null;
358
        List<CompletionResultItem> completionItems = null;
351
        
359
        
352
        //Step 1: create a context
360
        //Step 1: create a context
353
        XMLSyntaxSupport support = (XMLSyntaxSupport) ((BaseDocument)doc).getSyntaxSupport();
361
        XMLSyntaxSupport support = XMLSyntaxSupport.getSyntaxSupport(doc);
362
        if (support == null) {
363
            return null;
364
        }
354
        context = new CompletionContextImpl(primaryFile, support, caretOffset);
365
        context = new CompletionContextImpl(primaryFile, support, caretOffset);
355
        
366
        
356
        //Step 2: Accumulate all models and initialize the context
367
        //Step 2: Accumulate all models and initialize the context
(-)a/xml.schema.completion/src/org/netbeans/modules/xml/schema/completion/SchemaBasedCompletionProvider.java (-3 / +4 lines)
Lines 48-54 Link Here
48
import org.netbeans.editor.BaseDocument;
48
import org.netbeans.editor.BaseDocument;
49
import org.netbeans.editor.Utilities;
49
import org.netbeans.editor.Utilities;
50
import org.netbeans.modules.xml.schema.completion.util.CompletionUtil;
50
import org.netbeans.modules.xml.schema.completion.util.CompletionUtil;
51
import org.netbeans.modules.xml.text.syntax.XMLSyntaxSupport;
51
import org.netbeans.modules.xml.text.api.dom.XMLSyntaxSupport;
52
import org.netbeans.spi.editor.completion.CompletionProvider;
52
import org.netbeans.spi.editor.completion.CompletionProvider;
53
import org.netbeans.spi.editor.completion.CompletionTask;
53
import org.netbeans.spi.editor.completion.CompletionTask;
54
import org.netbeans.spi.editor.completion.support.AsyncCompletionTask;
54
import org.netbeans.spi.editor.completion.support.AsyncCompletionTask;
Lines 76-83 Link Here
76
        }
76
        }
77
        if(doc == null)
77
        if(doc == null)
78
            return 0;
78
            return 0;
79
        XMLSyntaxSupport support = ((XMLSyntaxSupport)doc.getSyntaxSupport());
79
        XMLSyntaxSupport support = XMLSyntaxSupport.getSyntaxSupport(doc);
80
        if(support.noCompletion(component) || !CompletionUtil.canProvideCompletion(doc)) {
80
        if(support != null && CompletionUtil.noCompletion(component) || 
81
                !CompletionUtil.canProvideCompletion(doc)) {
81
            return 0;
82
            return 0;
82
        }
83
        }
83
        
84
        
(-)a/xml.schema.completion/src/org/netbeans/modules/xml/schema/completion/util/CompletionContextImpl.java (-132 / +167 lines)
Lines 44-54 Link Here
44
package org.netbeans.modules.xml.schema.completion.util;
44
package org.netbeans.modules.xml.schema.completion.util;
45
45
46
import java.net.URI;
46
import java.net.URI;
47
import java.net.URISyntaxException;
48
import java.util.*;
47
import java.util.*;
49
import java.util.logging.Level;
48
import java.util.logging.Level;
50
import java.util.logging.Logger;
49
import java.util.logging.Logger;
51
import javax.swing.text.AbstractDocument;
50
import javax.swing.text.AbstractDocument;
51
import javax.swing.text.BadLocationException;
52
import javax.swing.text.Document;
52
import javax.xml.XMLConstants;
53
import javax.xml.XMLConstants;
53
import javax.xml.namespace.QName;
54
import javax.xml.namespace.QName;
54
55
Lines 58-71 Link Here
58
import org.netbeans.api.lexer.TokenSequence;
59
import org.netbeans.api.lexer.TokenSequence;
59
import org.netbeans.api.xml.lexer.XMLTokenId;
60
import org.netbeans.api.xml.lexer.XMLTokenId;
60
import org.netbeans.editor.BaseDocument;
61
import org.netbeans.editor.BaseDocument;
61
import org.netbeans.editor.TokenItem;
62
import org.netbeans.modules.xml.axi.AbstractAttribute;
62
import org.netbeans.modules.xml.axi.AbstractAttribute;
63
import org.netbeans.modules.xml.axi.Element;
63
import org.netbeans.modules.xml.axi.Element;
64
import org.openide.filesystems.FileObject;
64
import org.openide.filesystems.FileObject;
65
import org.netbeans.modules.xml.text.syntax.dom.StartTag;
66
import org.netbeans.modules.xml.text.syntax.SyntaxElement;
67
import org.netbeans.modules.xml.text.syntax.XMLSyntaxSupport;
68
import org.netbeans.modules.xml.text.api.XMLDefaultTokenContext;
69
import org.netbeans.modules.xml.schema.completion.spi.CompletionContext;
65
import org.netbeans.modules.xml.schema.completion.spi.CompletionContext;
70
import org.netbeans.modules.xml.schema.completion.spi.CompletionContext.CompletionType;
66
import org.netbeans.modules.xml.schema.completion.spi.CompletionContext.CompletionType;
71
import org.netbeans.modules.xml.schema.completion.spi.CompletionModelProvider;
67
import org.netbeans.modules.xml.schema.completion.spi.CompletionModelProvider;
Lines 74-82 Link Here
74
import org.netbeans.modules.xml.schema.completion.util.CompletionUtil.DocRootAttribute;
70
import org.netbeans.modules.xml.schema.completion.util.CompletionUtil.DocRootAttribute;
75
import org.netbeans.modules.xml.schema.model.Schema;
71
import org.netbeans.modules.xml.schema.model.Schema;
76
import org.netbeans.modules.xml.schema.model.SchemaModel;
72
import org.netbeans.modules.xml.schema.model.SchemaModel;
77
import org.netbeans.modules.xml.text.syntax.dom.EmptyTag;
73
import org.netbeans.modules.xml.text.api.dom.SyntaxElement;
78
import org.netbeans.modules.xml.text.syntax.dom.EndTag;
74
import org.netbeans.modules.xml.text.api.dom.XMLSyntaxSupport;
79
import org.netbeans.modules.xml.text.syntax.dom.Tag;
80
import org.openide.util.Exceptions;
75
import org.openide.util.Exceptions;
81
import org.openide.util.Lookup;
76
import org.openide.util.Lookup;
82
import org.w3c.dom.Attr;
77
import org.w3c.dom.Attr;
Lines 96-106 Link Here
96
91
97
    private static final Logger _logger = Logger.getLogger(CompletionContextImpl.class.getName());
92
    private static final Logger _logger = Logger.getLogger(CompletionContextImpl.class.getName());
98
93
99
94
    private XMLSyntaxSupport support;
100
    private int completionAtOffset = -1;
95
    private int completionAtOffset = -1;
101
    private FileObject primaryFile;
96
    private FileObject primaryFile;
102
    private String typedChars;
97
    private String typedChars;
103
    private TokenItem token;
98
    private Token<XMLTokenId> token;
99
    private int tokenOffset;
104
    private SyntaxElement element;
100
    private SyntaxElement element;
105
    private String attribute;
101
    private String attribute;
106
    private DocRoot docRoot;
102
    private DocRoot docRoot;
Lines 110-121 Link Here
110
    /**
106
    /**
111
     * Tags on the path from root to the context element (the one the CC tries to fill)
107
     * Tags on the path from root to the context element (the one the CC tries to fill)
112
     */
108
     */
113
    private List<Tag> elementsFromRoot;
109
    private List<SyntaxElement> elementsFromRoot;
114
    private Map<String, String>  schemaLocationMap = new HashMap<String, String>();
110
    private Map<String, String>  schemaLocationMap = new HashMap<String, String>();
115
    private String schemaLocation;
111
    private String schemaLocation;
116
    private String noNamespaceSchemaLocation;
112
    private String noNamespaceSchemaLocation;
117
    private String defaultNamespace;
113
    private String defaultNamespace;
118
    private BaseDocument document;
114
    private Document document;
119
    private HashMap<String, CompletionModel> nsModelMap =
115
    private HashMap<String, CompletionModel> nsModelMap =
120
            new HashMap<String, CompletionModel>();
116
            new HashMap<String, CompletionModel>();
121
    private List<CompletionModel> noNSModels =
117
    private List<CompletionModel> noNSModels =
Lines 140-150 Link Here
140
    public CompletionContextImpl(FileObject primaryFile, XMLSyntaxSupport support,
136
    public CompletionContextImpl(FileObject primaryFile, XMLSyntaxSupport support,
141
        int offset) {
137
        int offset) {
142
        try {
138
        try {
139
            this.support = support;
143
            this.completionAtOffset = offset;
140
            this.completionAtOffset = offset;
144
            this.primaryFile = primaryFile;
141
            this.primaryFile = primaryFile;
145
            this.document = support.getDocument();
142
            this.document = support.getDocument();
146
            this.element = support.getElementChain(offset);
143
            this.element = support.getElementChain(offset);
147
            this.token = support.getPreviousToken(offset);
144
            int[] off = new int[2];
145
            this.token = support.getPreviousToken(offset, off);
146
            this.tokenOffset = off[0];
148
            this.docRoot = CompletionUtil.getDocRoot(document);
147
            this.docRoot = CompletionUtil.getDocRoot(document);
149
            this.lastTypedChar = support.lastTypedChar();
148
            this.lastTypedChar = support.lastTypedChar();
150
            populateNamespaces();            
149
            populateNamespaces();            
Lines 177-183 Link Here
177
            
176
            
178
    @Override
177
    @Override
179
    public BaseDocument getBaseDocument() {
178
    public BaseDocument getBaseDocument() {
180
        return document;
179
        return (BaseDocument)document;
181
    }
180
    }
182
    
181
    
183
    @Override
182
    @Override
Lines 238-246 Link Here
238
     * from previously added tags. Tags should be added starting from the root down
237
     * from previously added tags. Tags should be added starting from the root down
239
     * to the context position.
238
     * to the context position.
240
     */
239
     */
241
    private void addNamespacesFrom(Tag e) {
240
    private void addNamespacesFrom(SyntaxElement s) {
241
        Node e = s.getNode();
242
        NamedNodeMap attrs = e.getAttributes();
242
        NamedNodeMap attrs = e.getAttributes();
243
        String nodePrefix = getPrefix(e.getTagName(), false);
243
        String nodePrefix = getPrefix(e.getNodeName(), false);
244
        String version = null;
244
        String version = null;
245
        String xsltAttrName = null;
245
        String xsltAttrName = null;
246
        
246
        
Lines 281-291 Link Here
281
     * 
281
     * 
282
     * @param stack path from the context element (index 0) to the root (index N-1).
282
     * @param stack path from the context element (index 0) to the root (index N-1).
283
     */
283
     */
284
    private void addContextNamespaces(List<Tag> stack) {
284
    private void addContextNamespaces(List<SyntaxElement> stack) {
285
        // must iterate from root down to the context element, to properly override
285
        // must iterate from root down to the context element, to properly override
286
        // namespaces and replace default/noNamespace information.
286
        // namespaces and replace default/noNamespace information.
287
        for (int i = stack.size() - 1; i >= 0; i--) {
287
        for (int i = stack.size() - 1; i >= 0; i--) {
288
            Tag t = stack.get(i);
288
            SyntaxElement t = stack.get(i);
289
            addNamespacesFrom(t);
289
            addNamespacesFrom(t);
290
        }
290
        }
291
    }
291
    }
Lines 470-494 Link Here
470
        try {
470
        try {
471
            if (isTagAttributeRequired(tokenSequence)) {
471
            if (isTagAttributeRequired(tokenSequence)) {
472
                completionType = CompletionType.COMPLETION_TYPE_ATTRIBUTE;
472
                completionType = CompletionType.COMPLETION_TYPE_ATTRIBUTE;
473
                if (token.getTokenID().equals(XMLDefaultTokenContext.WS)) {
473
                if (token.id() == XMLTokenId.WS) {
474
                    typedChars = null;
474
                    typedChars = null;
475
                } else {
475
                } else {
476
                    String str = token.getImage();
476
                    String str = token.text().toString();
477
                    int e = str.length();
477
                    int e = str.length();
478
                    int l = Math.min(completionAtOffset - token.getOffset() /* initial quote */, e);
478
                    int l = Math.min(completionAtOffset - tokenOffset /* initial quote */, e);
479
                    typedChars = str.substring(0, l);
479
                    typedChars = str.substring(0, l);
480
                }
480
                }
481
                createPathFromRoot(element);
481
                createPathFromRoot(element);
482
                return true;
482
                return true;
483
            }
483
            }
484
            
484
            
485
            int id = token.getTokenID().getNumericID();
485
            XMLTokenId id = token.id();
486
            switch (id) {
486
            switch (id) {
487
                //user enters < character
487
                //user enters < character
488
                case XMLDefaultTokenContext.TEXT_ID:
488
                case TEXT:
489
                    String chars = token.getImage().trim();
489
                    String chars = token.text().toString().trim();
490
                    String previousTokenText = token.getPrevious() == null ? 
490
                    Token previous = support.getPreviousToken(tokenOffset);
491
                            "" :token.getPrevious().getImage().trim();
491
                    String previousTokenText = previous == null ? 
492
                            "" : previous.text().toString().trim();
492
                    if(chars != null && chars.startsWith("&")) {
493
                    if(chars != null && chars.startsWith("&")) {
493
                        completionType = CompletionType.COMPLETION_TYPE_UNKNOWN;
494
                        completionType = CompletionType.COMPLETION_TYPE_UNKNOWN;
494
                        break;
495
                        break;
Lines 519-536 Link Here
519
                    }
520
                    }
520
                    break;
521
                    break;
521
522
522
                case XMLDefaultTokenContext.BLOCK_COMMENT_ID:
523
                case BLOCK_COMMENT:
523
                    completionType = CompletionType.COMPLETION_TYPE_ELEMENT;
524
                    completionType = CompletionType.COMPLETION_TYPE_ELEMENT;
524
                    createPathFromRoot(element);
525
                    createPathFromRoot(element);
525
                    break;
526
                    break;
526
527
527
                //start tag of an element
528
                //start tag of an element
528
                case XMLDefaultTokenContext.TAG_ID:
529
                case TAG:
529
                    if(element instanceof EndTag) {
530
                    if(support.isEndTag(element)) {
530
                        completionType = CompletionType.COMPLETION_TYPE_UNKNOWN;
531
                        completionType = CompletionType.COMPLETION_TYPE_UNKNOWN;
531
                        break;
532
                        break;
532
                    }
533
                    }
533
                    if (element instanceof EmptyTag) {
534
                    if (support.isEmptyTag(element)) {
534
                        /*
535
                        /*
535
                        if (token != null &&
536
                        if (token != null &&
536
                            token.getImage().trim().equals("/>")) {
537
                            token.getImage().trim().equals("/>")) {
Lines 538-557 Link Here
538
                            break;
539
                            break;
539
                        }
540
                        }
540
                        */
541
                        */
541
                        EmptyTag tag = (EmptyTag) element;
542
                        String tagName = element.getNode().getNodeName();
542
                        if ((element.getElementOffset() + 1 == completionAtOffset) ||
543
                        if ((element.getElementOffset() + 1 == completionAtOffset) ||
543
                            (token.getOffset() + token.getImage().length() == completionAtOffset)) {
544
                            (tokenOffset + token.length()== completionAtOffset)) {
544
                            completionType = CompletionType.COMPLETION_TYPE_ELEMENT;
545
                            completionType = CompletionType.COMPLETION_TYPE_ELEMENT;
545
                            createPathFromRoot(element.getPrevious());
546
                            createPathFromRoot(element.getPrevious());
546
                            break;
547
                            break;
547
                        }
548
                        }
548
                        if (completionAtOffset > element.getElementOffset() + 1 &&
549
                        if (completionAtOffset > element.getElementOffset() + 1 &&
549
                            completionAtOffset <= (element.getElementOffset() + 1 +
550
                            completionAtOffset <= (element.getElementOffset() + 1 +
550
                                                  tag.getTagName().length())) {
551
                                                  tagName.length())) {
551
                            completionType = CompletionType.COMPLETION_TYPE_ELEMENT;
552
                            completionType = CompletionType.COMPLETION_TYPE_ELEMENT;
552
                            int index = completionAtOffset - element.getElementOffset() - 1;
553
                            int index = completionAtOffset - element.getElementOffset() - 1;
553
                            typedChars = index < 0 ? tag.getTagName() :
554
                            typedChars = index < 0 ? tagName :
554
                                tag.getTagName().substring(0, index);
555
                                tagName.substring(0, index);
555
                            createPathFromRoot(element.getPrevious());
556
                            createPathFromRoot(element.getPrevious());
556
                            break;
557
                            break;
557
                        }                        
558
                        }                        
Lines 559-568 Link Here
559
//***???pathFromRoot = getPathFromRoot(element);
560
//***???pathFromRoot = getPathFromRoot(element);
560
                        break;
561
                        break;
561
                    }
562
                    }
562
                    
563
                    if (element.getType() == Node.ELEMENT_NODE &&
563
                    if(element instanceof StartTag) {
564
                        support.isStartTag(element)) {
564
                        if(token != null &&
565
                        if(token != null &&
565
                           token.getImage().trim().equals(">")) {
566
                           token.text().toString().trim().equals(">")) {
566
                            createPathFromRoot(element);
567
                            createPathFromRoot(element);
567
                            completionType = CompletionType.COMPLETION_TYPE_ELEMENT_VALUE;
568
                            completionType = CompletionType.COMPLETION_TYPE_ELEMENT_VALUE;
568
                            break;
569
                            break;
Lines 570-579 Link Here
570
                        if(element.getElementOffset() + 1 == this.completionAtOffset) {
571
                        if(element.getElementOffset() + 1 == this.completionAtOffset) {
571
                            typedChars = null;
572
                            typedChars = null;
572
                        } else {
573
                        } else {
573
                            StartTag tag = (StartTag)element;
574
                            String tagName = element.getNode().getNodeName();
574
                            int index = completionAtOffset-element.getElementOffset()-1;
575
                            int index = completionAtOffset-element.getElementOffset()-1;
575
                            typedChars = index<0?tag.getTagName() :
576
                            typedChars = index < 0 ? tagName :
576
                                tag.getTagName().substring(0, index);
577
                                tagName.substring(0, index);
577
                        }
578
                        }
578
                    }
579
                    }
579
                    completionType = CompletionType.COMPLETION_TYPE_ELEMENT;
580
                    completionType = CompletionType.COMPLETION_TYPE_ELEMENT;
Lines 581-623 Link Here
581
                    break;
582
                    break;
582
583
583
                //user enters an attribute name
584
                //user enters an attribute name
584
                case XMLDefaultTokenContext.ARGUMENT_ID:
585
                case ARGUMENT:
585
//***???completionType = CompletionType.COMPLETION_TYPE_ATTRIBUTE;
586
//***???completionType = CompletionType.COMPLETION_TYPE_ATTRIBUTE;
586
//***???typedChars = token.getImage();
587
//***???typedChars = token.getImage();
587
//***???pathFromRoot = getPathFromRoot(element);
588
//***???pathFromRoot = getPathFromRoot(element);
588
                    break;
589
                    break;
589
590
590
                //some random character
591
                //some random character
591
                case XMLDefaultTokenContext.CHARACTER_ID:
592
                case CHARACTER:
592
                    completionType = CompletionType.COMPLETION_TYPE_UNKNOWN;
593
                    completionType = CompletionType.COMPLETION_TYPE_UNKNOWN;
593
                    break;
594
                    break;
594
                    
595
                    
595
                //user enters = character, we should ignore all other operators
596
                //user enters = character, we should ignore all other operators
596
                case XMLDefaultTokenContext.OPERATOR_ID:
597
                case OPERATOR:
597
                    completionType = CompletionType.COMPLETION_TYPE_UNKNOWN;
598
                    completionType = CompletionType.COMPLETION_TYPE_UNKNOWN;
598
                    break;
599
                    break;
599
                    
600
                    
600
                //user enters either ' or "
601
                //user enters either ' or "
601
                case XMLDefaultTokenContext.VALUE_ID: {
602
                case VALUE: {
602
                    //user enters start quote and no end quote exists
603
                    //user enters start quote and no end quote exists
603
                    if(token.getNext() == null) {
604
                    Token<XMLTokenId> next = support.getNextToken(tokenOffset + token.length());
604
                        if(lastTypedChar == '\'' || lastTypedChar == '\"')
605
                    if(next == null) {
606
                        if(lastTypedChar == '\'' || lastTypedChar == '\"') {
605
                            typedChars = null;
607
                            typedChars = null;
606
                        else 
608
                        }   else  {
607
                            typedChars = token.getImage().substring(1,
609
                            String tt = token.text().toString();
608
                                token.getImage().indexOf(">"));
610
                            typedChars = tt.substring(1, tt.indexOf(">"));
611
                        }
609
                    }                    
612
                    }                    
610
                    
613
                    
611
                    //user is inside start/end quotes
614
                    //user is inside start/end quotes
612
                    if(lastTypedChar != '\'' && lastTypedChar != '\"') {
615
                    if(lastTypedChar != '\'' && lastTypedChar != '\"') {
613
                        String str = token.getImage();
616
                        String str = token.text().toString();
614
                        if( str != null && !str.equals("\"\"") && !str.equals("\'\'") &&
617
                        if( str != null && !str.equals("\"\"") && !str.equals("\'\'") &&
615
                            (str.startsWith("\"") || str.startsWith("\'")) &&
618
                            (str.startsWith("\"") || str.startsWith("\'")) &&
616
                            (str.endsWith("\"") || str.endsWith("\'")) ) {
619
                            (str.endsWith("\"") || str.endsWith("\'")) ) {
617
                            int e = str.length() - 1;
620
                            int e = str.length() - 1;
618
                            int l = Math.min(completionAtOffset - token.getOffset() /* initial quote */, e);
621
                            int l = Math.min(completionAtOffset - tokenOffset /* initial quote */, e);
619
                            typedChars = str.substring(1, l);
622
                            typedChars = str.substring(1, l);
620
                            if(completionAtOffset == token.getOffset()+1)
623
                            if(completionAtOffset == tokenOffset + 1)
621
                                typedChars = "";
624
                                typedChars = "";
622
                        }
625
                        }
623
                    }
626
                    }
Lines 630-656 Link Here
630
                }
633
                }
631
634
632
                //user enters white-space character
635
                //user enters white-space character
633
                case XMLDefaultTokenContext.WS_ID:
636
                case WS: {
634
                    completionType = CompletionType.COMPLETION_TYPE_UNKNOWN;
637
                        completionType = CompletionType.COMPLETION_TYPE_UNKNOWN;
635
                    TokenItem prev = token.getPrevious();
638
                        boolean cont = support.runWithSequence(tokenOffset, (TokenSequence ts) -> {
636
                    while( prev != null &&
639
                            if (!ts.movePrevious()) {
637
                           (prev.getTokenID().getNumericID() == XMLDefaultTokenContext.WS_ID) ) {
640
                                return false;
638
                            prev = prev.getPrevious();
641
                            }
639
                    }
642
                            Token<XMLTokenId> prev = ts.token();
640
                    if( (prev.getTokenID().getNumericID() == XMLDefaultTokenContext.VALUE_ID) ||
643
                            while(ts.movePrevious()) {
641
                        (prev.getTokenID().getNumericID() == XMLDefaultTokenContext.TAG_ID) ) {
644
                                prev = ts.token();
642
                        //no attr completion for end tags
645
                                if (prev.id() != XMLTokenId.WS) {
643
                        if (prev.getImage().startsWith("</")) {
646
                                    break;
644
                            break;
647
                                }
645
                        } else {
648
                            }
646
                            completionType = CompletionType.COMPLETION_TYPE_ATTRIBUTE;
649
                            if( (prev.id() == XMLTokenId.VALUE) ||
647
                            createPathFromRoot(element);
650
                                    (prev.id() == XMLTokenId.TAG) ) {
648
                        }
651
                                //no attr completion for end tags
649
                        
652
                                if (prev.text().toString().startsWith("</")) {
650
//***???completionType = CompletionType.COMPLETION_TYPE_ATTRIBUTE;
653
                                    return true;
651
//***???pathFromRoot = getPathFromRoot(element);
654
                                } else {
652
                    }
655
                                    completionType = CompletionType.COMPLETION_TYPE_ATTRIBUTE;
656
                                    createPathFromRoot(element);
657
                                }
658
                                
659
                                //***???completionType = CompletionType.COMPLETION_TYPE_ATTRIBUTE;
660
                                //***???pathFromRoot = getPathFromRoot(element);
661
                            }
662
                            return false;
663
                        });
653
                    break;
664
                    break;
665
                }
654
666
655
                default:
667
                default:
656
                    completionType = CompletionType.COMPLETION_TYPE_UNKNOWN;
668
                    completionType = CompletionType.COMPLETION_TYPE_UNKNOWN;
Lines 674-696 Link Here
674
     * @return attribute name, or <code>null</code> in unexpected situations
686
     * @return attribute name, or <code>null</code> in unexpected situations
675
     */
687
     */
676
    private String findAttributeName() {
688
    private String findAttributeName() {
677
        TokenItem item = token;
689
        try {
678
        while (item != null) {
690
            return support.runWithSequence(tokenOffset, (TokenSequence ts) -> {
679
            int tid = item.getTokenID().getNumericID();
691
                Token<XMLTokenId> item = ts.token();
680
            switch (tid) {
692
                while (item != null) {
681
                case XMLDefaultTokenContext.VALUE_ID:
693
                    switch (item.id()) {
682
                case XMLDefaultTokenContext.OPERATOR_ID:
694
                        case VALUE:
683
                case XMLDefaultTokenContext.WS_ID:
695
                        case OPERATOR:
684
                case XMLDefaultTokenContext.TEXT_ID:
696
                        case WS:
685
                    item = item.getPrevious();
697
                        case TEXT:
686
                    break;
698
                            if (!ts.movePrevious()) {
687
                case XMLDefaultTokenContext.ARGUMENT_ID:
699
                                return null;
688
                    return item.getImage();
700
                            }
689
                default:
701
                            item = ts.token();
690
                    return null;
702
                            break;
691
            }
703
                        case ARGUMENT:
704
                            return item.text().toString();
705
                        default:
706
                            return null;
707
                    }
708
                }
709
                return null;
710
            });
711
        } catch (BadLocationException ex) {
712
            Exceptions.printStackTrace(ex);
713
            return null;
692
        }
714
        }
693
        return null;
694
    }
715
    }
695
716
696
    public List<DocRootAttribute> getDocRootAttributes() {
717
    public List<DocRootAttribute> getDocRootAttributes() {
Lines 716-740 Link Here
716
        //1st pass
737
        //1st pass
717
        if(se == null)
738
        if(se == null)
718
            return;
739
            return;
719
        Stack<Tag> stack = new Stack<Tag>();
740
        Stack<SyntaxElement> stack = new Stack<>();
720
        if(se instanceof EmptyTag)
741
        if(support.isEmptyTag(se))
721
            stack.push((Tag)se);
742
            stack.push(se);
743
        
722
        while( se != null) {
744
        while( se != null) {
723
            if( (se instanceof EndTag) ||
745
            if (
724
                (se instanceof StartTag && stack.isEmpty()) ) {
746
                (stack.isEmpty() && support.isStartTag(se)) ||
725
                stack.push((Tag)se);
747
                    support.isEndTag(se)) {
748
                stack.push(se);
726
                se = se.getPrevious();
749
                se = se.getPrevious();
727
                continue;
750
                continue;
728
            }
751
            }
729
            if(se instanceof StartTag) {
752
            if (support.isStartTag(se)) {
730
                StartTag start = (StartTag)se;
753
                if (support.isEndTag(stack.peek())) {
731
                if(stack.peek() instanceof EndTag) {
754
                    SyntaxElement end = stack.peek();
732
                    EndTag end = (EndTag)stack.peek();
755
                    if(end.getNode().getNodeName().equals(se.getNode().getNodeName())) {
733
                    if(end.getTagName().equals(start.getTagName())) {
734
                        stack.pop();
756
                        stack.pop();
735
                    }
757
                    }
736
                } else {
758
                } else {
737
                    stack.push((Tag)se);
759
                    stack.push(se);
738
                }
760
                }
739
            }
761
            }
740
            se = se.getPrevious();
762
            se = se.getPrevious();
Lines 751-764 Link Here
751
     * While creating the path it always adds items to the start of the list so
773
     * While creating the path it always adds items to the start of the list so
752
     * that the returned path starts from root, all the way to the current tag.
774
     * that the returned path starts from root, all the way to the current tag.
753
     */
775
     */
754
    private ArrayList<QName> createPath(Stack<Tag> stack) {
776
    private ArrayList<QName> createPath(Stack<SyntaxElement> stack) {
755
        ArrayList<QName> path = new ArrayList<QName>();
777
        ArrayList<QName> path = new ArrayList<QName>();
756
        ListIterator<Tag> tags = stack.listIterator();
778
        ListIterator<SyntaxElement> tags = stack.listIterator();
757
        while(tags.hasNext()) {
779
        while(tags.hasNext()) {
758
            Tag tag = tags.next();
780
            SyntaxElement tag = tags.next();
759
            //add to the start of the list
781
            //add to the start of the list
760
            path.add(0, createQName(tag));
782
            path.add(0, createQName(tag));
761
            if(isRoot(tag, tags.hasNext()?tags.next():null)) {
783
            if(isRoot(tag, tags.hasNext() ? tags.next() : null)) {
762
                return path;
784
                return path;
763
            }
785
            }
764
            tags.previous();//since we moved twice.
786
            tags.previous();//since we moved twice.
Lines 772-789 Link Here
772
     * However, there are exceptions to this and may not work well for cases when
794
     * However, there are exceptions to this and may not work well for cases when
773
     * you combine itmes from schemas with/without namespace.
795
     * you combine itmes from schemas with/without namespace.
774
     */
796
     */
775
    private boolean isRoot(Tag thisTag, Tag previousTag) {
797
    private boolean isRoot(SyntaxElement elem, SyntaxElement previousTag) {
776
        //no previous => this has to be the root
798
        //no previous => this has to be the root
799
        Node thisTag = elem.getNode();
777
        if(previousTag == null)
800
        if(previousTag == null)
778
            return true;
801
            return true;
779
        
802
        
780
        //if the tag declares a namespace and is diff from default, then it is root
803
        //if the tag declares a namespace and is diff from default, then it is root
781
        String prefix = CompletionUtil.getPrefixFromTag(thisTag.getTagName());
804
        String prefix = CompletionUtil.getPrefixFromTag(thisTag.getNodeName());
782
        Attr namespaceAttr = null;
805
        Attr namespaceAttr = null;
806
        NamedNodeMap attrs = thisTag.getAttributes();
783
        if(prefix==null) {
807
        if(prefix==null) {
784
            namespaceAttr = thisTag.getAttributeNode(XMLConstants.XMLNS_ATTRIBUTE);
808
            namespaceAttr = (Attr)attrs.getNamedItem(XMLConstants.XMLNS_ATTRIBUTE);
785
        } else {
809
        } else {
786
            namespaceAttr = thisTag.getAttributeNode(XMLConstants.XMLNS_ATTRIBUTE+":"+prefix);
810
            namespaceAttr = (Attr)attrs.getNamedItem(XMLConstants.XMLNS_ATTRIBUTE+":"+prefix);
787
        }
811
        }
788
        if(namespaceAttr != null) {
812
        if(namespaceAttr != null) {
789
            String namespace = namespaceAttr.getValue();
813
            String namespace = namespaceAttr.getValue();
Lines 801-810 Link Here
801
            }
825
            }
802
        }
826
        }
803
        
827
        
804
        return !fromSameNamespace(thisTag, previousTag);
828
        return !fromSameNamespace(thisTag, previousTag.getNode());
805
    }
829
    }
806
    
830
    
807
    private String getAttributeValue(Tag tag, String attrName) {
831
    private String getAttributeValue(Node tag, String attrName) {
808
        NamedNodeMap attrs = tag.getAttributes();
832
        NamedNodeMap attrs = tag.getAttributes();
809
        for(int i=0; i<attrs.getLength(); i++) {
833
        for(int i=0; i<attrs.getLength(); i++) {
810
            Node attr = attrs.item(i);
834
            Node attr = attrs.item(i);
Lines 823-830 Link Here
823
     * @param tag
847
     * @param tag
824
     * @return 
848
     * @return 
825
     */
849
     */
826
    private QName createQName(Tag tag) {
850
    private QName createQName(SyntaxElement tag) {
827
        String tagName = tag.getTagName();
851
        String tagName = tag.getNode().getNodeName();
828
        String prefix = CompletionUtil.getPrefixFromTag(tagName);
852
        String prefix = CompletionUtil.getPrefixFromTag(tagName);
829
        String lName = CompletionUtil.getLocalNameFromTag(tagName);     
853
        String lName = CompletionUtil.getLocalNameFromTag(tagName);     
830
        
854
        
Lines 833-846 Link Here
833
            throw new IllegalStateException();
857
            throw new IllegalStateException();
834
        }
858
        }
835
        for (int i = index; i < elementsFromRoot.size(); i++) {
859
        for (int i = index; i < elementsFromRoot.size(); i++) {
836
            Tag t = elementsFromRoot.get(i);
860
            SyntaxElement s = elementsFromRoot.get(i);
861
            NamedNodeMap atts = s.getNode().getAttributes();
837
            if (prefix == null) {
862
            if (prefix == null) {
838
                Attr attrNode = t.getAttributeNode(XMLConstants.XMLNS_ATTRIBUTE);
863
                Attr attrNode = (Attr)atts.getNamedItem(XMLConstants.XMLNS_ATTRIBUTE);
839
                if (attrNode != null) {
864
                if (attrNode != null) {
840
                    return new QName(attrNode.getValue(), lName);
865
                    return new QName(attrNode.getValue(), lName);
841
                }
866
                }
842
            } else {
867
            } else {
843
                Attr attrNode = t.getAttributeNode(XMLConstants.XMLNS_ATTRIBUTE+":"+prefix);
868
                Attr attrNode = (Attr)atts.getNamedItem(XMLConstants.XMLNS_ATTRIBUTE+":"+prefix);
844
                if(attrNode != null) {
869
                if(attrNode != null) {
845
                    return new QName(attrNode.getValue(), lName, prefix); //NOI18N
870
                    return new QName(attrNode.getValue(), lName, prefix); //NOI18N
846
                }
871
                }
Lines 856-864 Link Here
856
    /**
881
    /**
857
     * Determines if this and previous tags are from same namespaces.
882
     * Determines if this and previous tags are from same namespaces.
858
     */
883
     */
859
    private boolean fromSameNamespace(Tag current, Tag previous) {
884
    private boolean fromSameNamespace(Node current, Node previous) {
860
        String prevPrefix = CompletionUtil.getPrefixFromTag(previous.getTagName());
885
        String prevPrefix = CompletionUtil.getPrefixFromTag(previous.getNodeName());
861
        String thisPrefix = CompletionUtil.getPrefixFromTag(current.getTagName());
886
        String thisPrefix = CompletionUtil.getPrefixFromTag(current.getNodeName());
862
        String thisNS = (thisPrefix == null) ? declaredNamespaces.get(
887
        String thisNS = (thisPrefix == null) ? declaredNamespaces.get(
863
            XMLConstants.XMLNS_ATTRIBUTE) :
888
            XMLConstants.XMLNS_ATTRIBUTE) :
864
            declaredNamespaces.get(XMLConstants.XMLNS_ATTRIBUTE+":"+thisPrefix);
889
            declaredNamespaces.get(XMLConstants.XMLNS_ATTRIBUTE+":"+thisPrefix);
Lines 1057-1064 Link Here
1057
    }
1082
    }
1058
    
1083
    
1059
    public boolean canReplace(String text) {
1084
    public boolean canReplace(String text) {
1060
        if(completionType == CompletionType.COMPLETION_TYPE_ELEMENT && element instanceof Tag) {
1085
        if(completionType == CompletionType.COMPLETION_TYPE_ELEMENT && 
1061
            String name = ((Tag)element).getTagName();
1086
                element.getType() == Node.ELEMENT_NODE) {
1087
            String name = element.getNode().getNodeName();
1062
            if(name != null && name.equals(typedChars) && text.equals(name))
1088
            if(name != null && name.equals(typedChars) && text.equals(name))
1063
                return false;
1089
                return false;
1064
        }
1090
        }
Lines 1092-1107 Link Here
1092
        if(existingAttributes != null)
1118
        if(existingAttributes != null)
1093
            return existingAttributes;
1119
            return existingAttributes;
1094
        existingAttributes = new ArrayList<String>();
1120
        existingAttributes = new ArrayList<String>();
1095
        TokenItem item = token.getPrevious();
1121
        try {
1096
        while(item != null) {
1122
            support.runWithSequence(tokenOffset, (TokenSequence ts) -> {
1097
            if(item.getTokenID().getNumericID() ==
1123
                if (ts.movePrevious()) {
1098
                    XMLDefaultTokenContext.TAG_ID)
1124
                    return null;
1099
                break;
1125
                }
1100
            if(item.getTokenID().getNumericID() ==
1126
                Token<XMLTokenId> item;
1101
                    XMLDefaultTokenContext.ARGUMENT_ID) {
1127
                
1102
                existingAttributes.add(item.getImage());
1128
                while(ts.movePrevious()) {
1103
            }
1129
                    item = ts.token();
1104
            item = item.getPrevious();
1130
                    if(item.id() == XMLTokenId.TAG)
1131
                        break;
1132
                    if(item.id() == XMLTokenId.ARGUMENT) {
1133
                        existingAttributes.add(item.text().toString());
1134
                    }
1135
                }
1136
                return null;
1137
            });
1138
        } catch (BadLocationException ex) {
1139
            Exceptions.printStackTrace(ex);
1105
        }
1140
        }
1106
        return existingAttributes;
1141
        return existingAttributes;
1107
    }
1142
    }
(-)a/xml.schema.completion/src/org/netbeans/modules/xml/schema/completion/util/CompletionUtil.java (+35 lines)
Lines 88-93 Link Here
88
    public static final Pattern PATTERN_TEXT_TAG_EOLs = Pattern.compile("</?[\\s]+.*");
88
    public static final Pattern PATTERN_TEXT_TAG_EOLs = Pattern.compile("</?[\\s]+.*");
89
    
89
    
90
    private static final Logger _logger = Logger.getLogger(CompletionUtil.class.getName());
90
    private static final Logger _logger = Logger.getLogger(CompletionUtil.class.getName());
91
92
    public static boolean noCompletion(JTextComponent target) {
93
        if (target == null || target.getCaret() == null) {
94
            return false;
95
        }
96
        int offset = target.getCaret().getDot();
97
        if (offset < 0) {
98
            return false;
99
        }
100
        //no completion inside CDATA or comment section
101
        BaseDocument document = (BaseDocument) target.getDocument();
102
        ((AbstractDocument) document).readLock();
103
        try {
104
            TokenHierarchy th = TokenHierarchy.get(document);
105
            TokenSequence ts = th.tokenSequence();
106
            if (ts == null) {
107
                return false;
108
            }
109
            ts.move(offset);
110
            Token token = ts.token();
111
            if (token == null) {
112
                ts.moveNext();
113
                token = ts.token();
114
                if (token == null) {
115
                    return false;
116
                }
117
            }
118
            if (token.id() == XMLTokenId.CDATA_SECTION || token.id() == XMLTokenId.BLOCK_COMMENT || token.id() == XMLTokenId.PI_START || token.id() == XMLTokenId.PI_END || token.id() == XMLTokenId.PI_CONTENT || token.id() == XMLTokenId.PI_TARGET) {
119
                return true;
120
            }
121
        } finally {
122
            ((AbstractDocument) document).readUnlock();
123
        }
124
        return false;
125
    }
91
    
126
    
92
    /**
127
    /**
93
     * No instantiation.
128
     * No instantiation.
(-)a/xml.schema.completion/test/unit/src/org/netbeans/modules/xml/schema/completion/AbstractTestCase.java (-3 / +5 lines)
Lines 50-64 Link Here
50
import org.netbeans.api.lexer.Language;
50
import org.netbeans.api.lexer.Language;
51
import org.netbeans.api.xml.lexer.XMLTokenId;
51
import org.netbeans.api.xml.lexer.XMLTokenId;
52
import org.netbeans.editor.BaseDocument;
52
import org.netbeans.editor.BaseDocument;
53
import org.netbeans.junit.NbTestCase;
53
import org.netbeans.modules.xml.schema.completion.util.CompletionContextImpl;
54
import org.netbeans.modules.xml.schema.completion.util.CompletionContextImpl;
54
import org.netbeans.modules.xml.text.syntax.XMLSyntaxSupport;
55
import org.netbeans.modules.xml.text.api.dom.XMLSyntaxSupport;
55
import org.openide.filesystems.FileObject;
56
import org.openide.filesystems.FileObject;
56
57
57
/**
58
/**
58
 *
59
 *
59
 * @author Samaresh
60
 * @author Samaresh
60
 */
61
 */
61
public abstract class AbstractTestCase extends TestCase {
62
public abstract class AbstractTestCase extends NbTestCase {
62
    
63
    
63
    protected String instanceResourcePath;
64
    protected String instanceResourcePath;
64
    protected FileObject instanceFileObject;
65
    protected FileObject instanceFileObject;
Lines 71-76 Link Here
71
72
72
    @Override
73
    @Override
73
    protected void setUp() throws Exception {
74
    protected void setUp() throws Exception {
75
        
74
    }
76
    }
75
77
76
    @Override
78
    @Override
Lines 97-103 Link Here
97
        this.instanceResourcePath = path;
99
        this.instanceResourcePath = path;
98
        this.instanceFileObject = Util.getResourceAsFileObject(path);
100
        this.instanceFileObject = Util.getResourceAsFileObject(path);
99
        this.instanceDocument = Util.getResourceAsDocument(path);
101
        this.instanceDocument = Util.getResourceAsDocument(path);
100
        this.support = ((XMLSyntaxSupport)instanceDocument.getSyntaxSupport());
102
        this.support = XMLSyntaxSupport.getSyntaxSupport(instanceDocument);
101
        if(content != null) {
103
        if(content != null) {
102
            instanceDocument.remove(0, instanceDocument.getLength());
104
            instanceDocument.remove(0, instanceDocument.getLength());
103
            instanceDocument.insertString(0, content.toString(), null);
105
            instanceDocument.insertString(0, content.toString(), null);
(-)a/xml.schema.completion/test/unit/src/org/netbeans/modules/xml/schema/completion/BasicCompletionTest.java (-1 / +2 lines)
Lines 79-85 Link Here
79
        suite.addTest(new BasicCompletionTest("testEndtagCompletion2"));
79
        suite.addTest(new BasicCompletionTest("testEndtagCompletion2"));
80
        suite.addTest(new BasicCompletionTest("testEndtagCompletion3"));
80
        suite.addTest(new BasicCompletionTest("testEndtagCompletion3"));
81
        suite.addTest(new BasicCompletionTest("testCompletionWithAmpersand"));
81
        suite.addTest(new BasicCompletionTest("testCompletionWithAmpersand"));
82
        suite.addTest(new BasicCompletionTest("testSchemaFromRuntimeCatalog"));
82
  // disabled since it accesses Net:
83
  //      suite.addTest(new BasicCompletionTest("testSchemaFromRuntimeCatalog"));
83
        //suite.addTest(new BasicCompletionTest("testCompletionUsingSchemaFromCatalog"));
84
        //suite.addTest(new BasicCompletionTest("testCompletionUsingSchemaFromCatalog"));
84
        suite.addTest(new BasicCompletionTest("testWildcard1"));
85
        suite.addTest(new BasicCompletionTest("testWildcard1"));
85
        suite.addTest(new BasicCompletionTest("testWildcard2"));
86
        suite.addTest(new BasicCompletionTest("testWildcard2"));
(-)a/xml.text.obsolete90/build.xml (+5 lines)
Line 0 Link Here
1
<?xml version="1.0" encoding="UTF-8"?>
2
<project basedir="." default="netbeans" name="xml.text.obsolete90">
3
    <description>Builds, tests, and runs the project org.netbeans.modules.xml.text.obsolete90</description>
4
    <import file="../nbbuild/templates/projectized.xml"/>
5
</project>
(-)a/xml.text.obsolete90/manifest.mf (+6 lines)
Line 0 Link Here
1
Manifest-Version: 1.0
2
AutoUpdate-Show-In-Client: false
3
OpenIDE-Module: org.netbeans.modules.xml.text.obsolete90
4
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/xml/text/obsolete90/Bundle.properties
5
OpenIDE-Module-Implementation-Version: 1
6
OpenIDE-Module-Layer: org/netbeans/modules/xml/text/obsolete90/resources/mf-layer.xml
(-)a/xml.text.obsolete90/nbproject/project.properties (+4 lines)
Line 0 Link Here
1
is.autoload=true
2
javac.source=1.7
3
javac.compilerargs=-Xlint -Xlint:-serial
4
spec.version.base=1.0
(-)a/xml.text.obsolete90/nbproject/project.xml (+182 lines)
Line 0 Link Here
1
<?xml version="1.0" encoding="UTF-8"?>
2
<project xmlns="http://www.netbeans.org/ns/project/1">
3
    <type>org.netbeans.modules.apisupport.project</type>
4
    <configuration>
5
        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
6
            <code-name-base>org.netbeans.modules.xml.text.obsolete90</code-name-base>
7
            <module-dependencies>
8
                <dependency>
9
                    <code-name-base>org.netbeans.modules.editor.deprecated.pre65formatting</code-name-base>
10
                    <build-prerequisite/>
11
                    <compile-dependency/>
12
                    <run-dependency>
13
                        <release-version>0</release-version>
14
                        <specification-version>1.32</specification-version>
15
                    </run-dependency>
16
                </dependency>
17
                <dependency>
18
                    <code-name-base>org.netbeans.modules.editor.document</code-name-base>
19
                    <build-prerequisite/>
20
                    <compile-dependency/>
21
                    <run-dependency>
22
                        <specification-version>1.10</specification-version>
23
                    </run-dependency>
24
                </dependency>
25
                <dependency>
26
                    <code-name-base>org.netbeans.modules.editor.lib</code-name-base>
27
                    <build-prerequisite/>
28
                    <compile-dependency/>
29
                    <run-dependency>
30
                        <release-version>3</release-version>
31
                        <specification-version>4.8</specification-version>
32
                    </run-dependency>
33
                </dependency>
34
                <dependency>
35
                    <code-name-base>org.netbeans.modules.editor.mimelookup</code-name-base>
36
                    <build-prerequisite/>
37
                    <compile-dependency/>
38
                    <run-dependency>
39
                        <release-version>1</release-version>
40
                        <specification-version>1.41</specification-version>
41
                    </run-dependency>
42
                </dependency>
43
                <dependency>
44
                    <code-name-base>org.netbeans.modules.editor.structure</code-name-base>
45
                    <build-prerequisite/>
46
                    <compile-dependency/>
47
                    <run-dependency>
48
                        <release-version>1</release-version>
49
                    </run-dependency>
50
                </dependency>
51
                <dependency>
52
                    <code-name-base>org.netbeans.modules.lexer</code-name-base>
53
                    <build-prerequisite/>
54
                    <compile-dependency/>
55
                    <run-dependency>
56
                        <release-version>2</release-version>
57
                        <specification-version>1.64</specification-version>
58
                    </run-dependency>
59
                </dependency>
60
                <dependency>
61
                    <code-name-base>org.netbeans.modules.xml.core</code-name-base>
62
                    <build-prerequisite/>
63
                    <compile-dependency/>
64
                    <run-dependency>
65
                        <release-version>2</release-version>
66
                        <specification-version>1.44</specification-version>
67
                    </run-dependency>
68
                </dependency>
69
                <dependency>
70
                    <code-name-base>org.netbeans.modules.xml.lexer</code-name-base>
71
                    <build-prerequisite/>
72
                    <compile-dependency/>
73
                    <run-dependency>
74
                        <specification-version>1.30</specification-version>
75
                    </run-dependency>
76
                </dependency>
77
                <dependency>
78
                    <code-name-base>org.netbeans.modules.xml.text</code-name-base>
79
                    <build-prerequisite/>
80
                    <compile-dependency/>
81
                    <run-dependency>
82
                        <release-version>2</release-version>
83
                        <implementation-version/>
84
                    </run-dependency>
85
                </dependency>
86
                <dependency>
87
                    <code-name-base>org.openide.util</code-name-base>
88
                    <build-prerequisite/>
89
                    <compile-dependency/>
90
                    <run-dependency>
91
                        <specification-version>9.8</specification-version>
92
                    </run-dependency>
93
                </dependency>
94
                <dependency>
95
                    <code-name-base>org.openide.util.ui</code-name-base>
96
                    <build-prerequisite/>
97
                    <compile-dependency/>
98
                    <run-dependency>
99
                        <specification-version>9.7</specification-version>
100
                    </run-dependency>
101
                </dependency>
102
            </module-dependencies>
103
            <test-dependencies>
104
                <test-type>
105
                    <name>unit</name>
106
                    <test-dependency>
107
                        <code-name-base>org.netbeans.libs.junit4</code-name-base>
108
                        <compile-dependency/>
109
                    </test-dependency>
110
                    <test-dependency>
111
                        <code-name-base>org.netbeans.modules.editor</code-name-base>
112
                        <recursive/>
113
                        <compile-dependency/>
114
                        <test/>
115
                    </test-dependency>
116
                    <test-dependency>
117
                        <code-name-base>org.netbeans.modules.editor.mimelookup</code-name-base>
118
                        <compile-dependency/>
119
                    </test-dependency>
120
                    <test-dependency>
121
                        <code-name-base>org.netbeans.modules.editor.mimelookup.impl</code-name-base>
122
                        <recursive/>
123
                        <compile-dependency/>
124
                    </test-dependency>
125
                    <test-dependency>
126
                        <code-name-base>org.netbeans.modules.editor.settings.storage</code-name-base>
127
                        <recursive/>
128
                    </test-dependency>
129
                    <test-dependency>
130
                        <code-name-base>org.netbeans.modules.editor.structure</code-name-base>
131
                        <compile-dependency/>
132
                    </test-dependency>
133
                    <test-dependency>
134
                        <code-name-base>org.netbeans.modules.editor.util</code-name-base>
135
                        <compile-dependency/>
136
                    </test-dependency>
137
                    <test-dependency>
138
                        <code-name-base>org.netbeans.modules.nbjunit</code-name-base>
139
                        <recursive/>
140
                        <compile-dependency/>
141
                    </test-dependency>
142
                    <test-dependency>
143
                        <code-name-base>org.netbeans.modules.projectapi.nb</code-name-base>
144
                        <compile-dependency/>
145
                    </test-dependency>
146
                    <test-dependency>
147
                        <code-name-base>org.netbeans.modules.xml.lexer</code-name-base>
148
                        <compile-dependency/>
149
                    </test-dependency>
150
                    <test-dependency>
151
                        <code-name-base>org.netbeans.modules.xml.text</code-name-base>
152
                        <recursive/>
153
                        <compile-dependency/>
154
                        <test/>
155
                    </test-dependency>
156
                    <test-dependency>
157
                        <code-name-base>org.netbeans.modules.xml.xam</code-name-base>
158
                        <compile-dependency/>
159
                    </test-dependency>
160
                    <test-dependency>
161
                        <code-name-base>org.netbeans.modules.xml.xdm</code-name-base>
162
                        <compile-dependency/>
163
                    </test-dependency>
164
                    <test-dependency>
165
                        <code-name-base>org.openide.util.ui</code-name-base>
166
                        <compile-dependency/>
167
                    </test-dependency>
168
                    <test-dependency>
169
                        <code-name-base>org.openide.util.lookup</code-name-base>
170
                        <compile-dependency/>
171
                    </test-dependency>
172
                </test-type>
173
            </test-dependencies>
174
            <public-packages>
175
                <package>org.netbeans.modules.xml.text.api</package>
176
                <package>org.netbeans.modules.xml.text.indent</package>
177
                <package>org.netbeans.modules.xml.text.syntax</package>
178
                <package>org.netbeans.modules.xml.text.syntax.dom</package>
179
            </public-packages>
180
        </data>
181
    </configuration>
182
</project>
(-)a/xml.text/src/org/netbeans/modules/xml/text/api/XMLDefaultTokenContext.java (-1 / +3 lines)
Lines 43-48 Link Here
43
 */
43
 */
44
package org.netbeans.modules.xml.text.api;
44
package org.netbeans.modules.xml.text.api;
45
45
46
import org.netbeans.modules.xml.text.syntax.XMLTokenIDs;
46
import java.lang.reflect.Field;
47
import java.lang.reflect.Field;
47
import java.lang.reflect.Modifier;
48
import java.lang.reflect.Modifier;
48
import org.netbeans.editor.TokenContext;
49
import org.netbeans.editor.TokenContext;
Lines 58-65 Link Here
58
 * @version 1.00
59
 * @version 1.00
59
 * @contributor(s) XML Modifications Sandeep Singh Randhawa
60
 * @contributor(s) XML Modifications Sandeep Singh Randhawa
60
 * @integrator Petr Kuzel
61
 * @integrator Petr Kuzel
62
 * @deprecated This API uses an obsolete (Ext)Syntax API. Clients should use new Lexer API.
61
 */
63
 */
62
64
@Deprecated
63
public class XMLDefaultTokenContext extends TokenContext implements XMLTokenIDs {
65
public class XMLDefaultTokenContext extends TokenContext implements XMLTokenIDs {
64
66
65
    
67
    
(-)a/xml.text/src/org/netbeans/modules/xml/text/indent/XMLFormatter.java (+1 lines)
Lines 55-60 Link Here
55
import org.netbeans.editor.ext.FormatWriter;
55
import org.netbeans.editor.ext.FormatWriter;
56
import org.netbeans.editor.BaseDocument;
56
import org.netbeans.editor.BaseDocument;
57
import org.netbeans.modules.editor.structure.formatting.TagBasedFormatter;
57
import org.netbeans.modules.editor.structure.formatting.TagBasedFormatter;
58
import org.netbeans.modules.xml.text.indent.XMLFormatSupport;
58
import org.netbeans.modules.xml.text.syntax.XMLSyntaxSupport;
59
import org.netbeans.modules.xml.text.syntax.XMLSyntaxSupport;
59
import org.netbeans.modules.xml.text.syntax.XMLTokenIDs;
60
import org.netbeans.modules.xml.text.syntax.XMLTokenIDs;
60
61
(-)a/xml.text.obsolete90/src/org/netbeans/modules/xml/text/obsolete90/Bundle.properties (+5 lines)
Line 0 Link Here
1
OpenIDE-Module-Long-Description=\
2
    The SyntaxElement API was desinged around the old and now long-deprecated parser. \
3
    This module provides backward compatibility for module implementors who did not migrate to the new lexer and new SyntaxElement API found in the XML Text Editor module.
4
OpenIDE-Module-Name=XML Text Editor (obsolete)
5
OpenIDE-Module-Short-Description=Obsolete and deprecated APIs from XML Text Editor module
(-)a/xml.text.obsolete90/src/org/netbeans/modules/xml/text/obsolete90/ComplexValueSettingsFactory.java (+61 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2016 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 2016 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.xml.text.obsolete90;
43
44
import java.util.Collections;
45
import java.util.List;
46
import org.netbeans.modules.xml.text.api.XMLDefaultTokenContext;
47
import org.netbeans.modules.xml.text.syntax.DTDTokenContext;
48
49
/**
50
 *
51
 * @author sdedic
52
 */
53
public class ComplexValueSettingsFactory {
54
    public static List getXMLTokenContext() {
55
        return Collections.singletonList(XMLDefaultTokenContext.context);
56
    }
57
    // XXX: use lexer
58
    public static List getDTDTokenContext() {
59
        return Collections.singletonList(DTDTokenContext.context);
60
    }
61
}
(-)a/xml.text.obsolete90/src/org/netbeans/modules/xml/text/obsolete90/XMLSyntaxBridgeImpl.java (+98 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2016 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 2016 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.xml.text.obsolete90;
43
44
import javax.swing.text.Document;
45
import javax.swing.text.EditorKit;
46
import org.netbeans.api.editor.mimelookup.MimeRegistration;
47
import org.netbeans.api.editor.mimelookup.MimeRegistrations;
48
import org.netbeans.editor.BaseDocument;
49
import org.netbeans.editor.SyntaxSupport;
50
import org.netbeans.modules.xml.text.syntax.DTDKit;
51
import org.netbeans.modules.xml.text.syntax.DTDSyntaxTokenMapper;
52
import org.netbeans.modules.xml.text.syntax.DTDTokenContext;
53
import org.netbeans.modules.xml.text.syntax.ENTKit;
54
import org.netbeans.modules.xml.text.syntax.XMLDefaultSyntax;
55
import org.netbeans.modules.xml.text.syntax.XMLKit;
56
import org.netbeans.modules.xml.text.syntax.XMLSyntaxSupport;
57
import org.netbeans.modules.xml.text.syntax.bridge.LegacySyntaxBridge;
58
import org.netbeans.modules.xml.text.syntax.javacc.DTDSyntaxTokenManager;
59
import org.netbeans.modules.xml.text.syntax.javacc.lib.JJEditorSyntax;
60
61
/**
62
 *
63
 * @author sdedic
64
 */
65
@MimeRegistrations({
66
    @MimeRegistration(service = LegacySyntaxBridge.class, mimeType = "text/xml"),
67
    @MimeRegistration(service = LegacySyntaxBridge.class, mimeType = "application/xml-dtd"),
68
    @MimeRegistration(service = LegacySyntaxBridge.class, mimeType = "text/xml-external-parsed-entity")
69
})
70
public class XMLSyntaxBridgeImpl implements LegacySyntaxBridge {
71
72
    @Override
73
    public org.netbeans.editor.Syntax createSyntax(EditorKit host, Document doc, String mimeType) {
74
        if (DTDKit.MIME_TYPE.equals(mimeType)) {
75
            return new JJEditorSyntax( 
76
                new DTDSyntaxTokenManager(null).new Bridge(),
77
                new DTDSyntaxTokenMapper(),
78
                DTDTokenContext.contextPath
79
            );
80
81
        } else if (XMLKit.MIME_TYPE.equals(mimeType)) {
82
            return new XMLDefaultSyntax();
83
        } else if (ENTKit.MIME_TYPE.equals(mimeType)) {
84
            return new XMLDefaultSyntax();
85
        } else {
86
            return null;
87
        }
88
    }
89
90
    @Override
91
    public SyntaxSupport createSyntaxSupport(EditorKit host, Document doc, String mimeType) {
92
        if (XMLKit.MIME_TYPE.equals(mimeType) || ENTKit.MIME_TYPE.equals(mimeType)) {
93
            return new XMLSyntaxSupport((BaseDocument)doc);
94
        } else {
95
            return null;
96
        }
97
    }
98
}
(-)a/xml.text/src/org/netbeans/modules/xml/text/resources/DTDEditor-preferences.xml (-3 / +1 lines)
Lines 46-52 Link Here
46
<!DOCTYPE editor-preferences PUBLIC "-//NetBeans//DTD Editor Preferences 1.0//EN" "http://www.netbeans.org/dtds/EditorPreferences-1_0.dtd">
46
<!DOCTYPE editor-preferences PUBLIC "-//NetBeans//DTD Editor Preferences 1.0//EN" "http://www.netbeans.org/dtds/EditorPreferences-1_0.dtd">
47
47
48
<editor-preferences>
48
<editor-preferences>
49
    <entry name="token-context-list" value="org.netbeans.modules.xml.text.ComplexValueSettingsFactory.getDTDTokenContext" javaType="methodvalue" />
49
    <entry name="token-context-list" value="org.netbeans.modules.xml.text.obsolete90.ComplexValueSettingsFactory.getDTDTokenContext" javaType="methodvalue" />
50
    <entry name="indentEngine" value="org.netbeans.modules.xml.text.ComplexValueSettingsFactory.getDTDIndentEngine" javaType="methodvalue" />
51
    <entry name="abbrev-reset-acceptor" value="org.netbeans.modules.xml.text.ComplexValueSettingsFactory.getDTDAbbrevResetAcceptor" javaType="methodvalue" />
52
</editor-preferences>
50
</editor-preferences>
(-)a/xml.text/src/org/netbeans/modules/xml/text/resources/XMLEditor-preferences.xml (-5 / +1 lines)
Lines 46-54 Link Here
46
<!DOCTYPE editor-preferences PUBLIC "-//NetBeans//DTD Editor Preferences 1.0//EN" "http://www.netbeans.org/dtds/EditorPreferences-1_0.dtd">
46
<!DOCTYPE editor-preferences PUBLIC "-//NetBeans//DTD Editor Preferences 1.0//EN" "http://www.netbeans.org/dtds/EditorPreferences-1_0.dtd">
47
47
48
<editor-preferences>
48
<editor-preferences>
49
    <entry name="code-folding-enable" value="true" javaType="java.lang.Boolean" />
49
    <entry name="token-context-list" value="org.netbeans.modules.xml.text.obsolete90.ComplexValueSettingsFactory.getXMLTokenContext" javaType="methodvalue" />
50
    <entry name="token-context-list" value="org.netbeans.modules.xml.text.ComplexValueSettingsFactory.getXMLTokenContext" javaType="methodvalue" />
51
    <entry name="indentEngine" value="org.netbeans.modules.xml.text.ComplexValueSettingsFactory.getXMLIndentEngine" javaType="methodvalue" />
52
    <entry name="identifier-acceptor" value="org.netbeans.modules.xml.text.ComplexValueSettingsFactory.getXMLIdentifierAcceptor" javaType="methodvalue" />
53
    <entry name="abbrev-reset-acceptor" value="org.netbeans.modules.xml.text.ComplexValueSettingsFactory.getXMLAbbrevResetAcceptor" javaType="methodvalue" />
54
</editor-preferences>
50
</editor-preferences>
(-)a/xml.text/src/org/netbeans/modules/xml/text/resources/mf-layer.xml (-279 / +5 lines)
Lines 45-350 Link Here
45
-->
45
-->
46
<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.0//EN" "http://www.netbeans.org/dtds/filesystem-1_0.dtd">
46
<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.0//EN" "http://www.netbeans.org/dtds/filesystem-1_0.dtd">
47
<filesystem>
47
<filesystem>
48
    <folder name="Navigator">
49
        <folder name="Panels">
50
            <folder name="text">
51
                <folder name="xml">
52
                    <file name="org-netbeans-modules-xml-text-navigator-XMLNavigatorPanel.instance"/>
53
                </folder>
54
                <folder name="xsd+xml">
55
                    <file name="org-netbeans-modules-xml-text-navigator-XMLNavigatorPanel.instance"/>
56
                </folder>
57
                <folder name="xml-wsdl">
58
                    <file name="org-netbeans-modules-xml-text-navigator-XMLNavigatorPanel.instance"/>
59
                </folder>
60
                <folder name="x-ant+xml">
61
                    <file name="org-netbeans-modules-xml-text-navigator-XMLNavigatorPanel.instance"/>
62
                </folder>
63
                <folder name="x-dd-sjsas-servlet2.41">
64
                    <!-- sun-web.xml -->
65
                    <file name="org-netbeans-modules-xml-text-navigator-XMLNavigatorPanel.instance"/>
66
                </folder>
67
            </folder>
68
            <folder name="application">
69
                <folder name="xslt+xml">
70
                    <file name="org-netbeans-modules-xml-text-navigator-XMLNavigatorPanel.instance"/>
71
                </folder>
72
                <folder name="xhtml+xml">
73
                    <file name="org-netbeans-modules-xml-text-navigator-XMLNavigatorPanel.instance"/>
74
                </folder>
75
                <folder name="x-schema+xml">
76
                    <file name="org-netbeans-modules-xml-text-navigator-XMLNavigatorPanel.instance"/>
77
                </folder>
78
            </folder>
79
        </folder>
80
    </folder>
81
    
82
    <folder name="Services">
83
        <folder name="IndentEngine">
84
            <!--
85
            <file name="org-netbeans-modules-xml-text-settings-XMLIndentEngine.settings" url="XMLIndentEngine.xml">
86
                <attr name="SystemFileSystem.localizingBundle" stringvalue="org.netbeans.modules.xml.text.indent.Bundle"/>
87
            </file>
88
            -->
89
            <file name="org-netbeans-modules-xml-text-settings-DTDIndentEngine.settings" url="DTDIndentEngine.xml">
90
                <attr name="SystemFileSystem.localizingBundle" stringvalue="org.netbeans.modules.xml.text.indent.Bundle"/>
91
            </file>
92
        </folder> <!-- IndentEngine -->
93
94
        <!--
95
        <folder name="Hidden">
96
            <file name="org-netbeans-modules-xml-text-completion-ReloadActionPerformer.instance">
97
                <attr name="instanceOf" stringvalue="org.netbeans.modules.xml.core.actions.XMLUpdateDocumentAction$Performer"/>
98
            </file>
99
        </folder>
100
        -->
101
    </folder> <!-- Services -->
102
103
    <folder name="Editors">
48
    <folder name="Editors">
104
        <folder name="text">
49
        <folder name="text">
105
            <folder name="xml">
50
            <folder name="xml">
106
                <attr name="SystemFileSystem.localizingBundle" stringvalue="org.netbeans.modules.xml.text.resources.Bundle"/>
107
                
108
                <file name="org-netbeans-modules-xml-text-indent-XMLIndentTaskFactory.instance"/>
109
                
110
                <file name="AutoIndenter.instance">
111
                    <attr name="instanceOf" stringvalue="org.netbeans.spi.editor.typinghooks.TypedTextInterceptor$Factory"/>
112
                    <attr name="instanceCreate"
113
                          methodvalue="org.netbeans.modules.editor.indent.spi.support.AutomatedIndenting.createHotCharsIndenter"/>
114
                    <attr name="regex1" stringvalue="\s*\&lt;/\w+\>"/>
115
                </file>
116
117
                <folder name="CompletionProviders">
118
                    <file name="org-netbeans-modules-xml-text-completion-XMLCompletionProvider.instance"/>
119
                </folder>
120
121
                <folder name="BracesMatchers">
122
                    <file name="org-netbeans-modules-xml-text-bracematch-XMLBraceMatcherFactory.instance">
123
                        <attr name="position" intvalue="50"/>
124
                    </file>
125
                </folder>
126
127
                <folder name="FontsColors">
128
                    <folder name="NetBeans">
129
                        <folder name="Defaults">
130
                            <file name="org-netbeans-modules-xml-text-token-colorings.xml" url="XML-fontsColors.xml">
131
                                <attr name="SystemFileSystem.localizingBundle" stringvalue="org.netbeans.modules.xml.text.resources.Bundle"/>
132
                            </file>
133
                        </folder>
134
                    </folder>
135
                </folder>
136
                
137
                <folder name="DocumentModel">
138
                    <file name="org-netbeans-modules-xml-text-structure-XMLDocumentModelProvider.instance"/>
139
                </folder>
140
                
141
                <folder name="FoldManager">
142
                    <file name="org-netbeans-modules-xml-text-folding-XmlFoldManagerFactory.instance">
143
                	<attr name="position" intvalue="1100"/>
144
            	    </file>
145
                </folder>
146
                
147
                <folder name="Popup">
148
                    <file name="org-netbeans-modules-xml-actions-CollectXMLAction.shadow">
149
                        <attr name="originalFile" stringvalue="Actions/XML/org-netbeans-modules-xml-actions-CollectXMLAction.instance"/>
150
                        <attr name="position" intvalue="1600"/>
151
                    </file>
152
                    <file name="org-netbeans-modules-xml-actions-XMLViewActions.instance">
153
                        <attr name="position" intvalue="1400"/>
154
                    </file>
155
                    <!-- implicit separator provided by above action group -->
156
                    
157
                    <file name="format">
158
                        <attr name="position" intvalue="1200"/>
159
                    </file>
160
                    <file name="SeparatorAfterFormat.instance">
161
                        <attr name="instanceClass" stringvalue="javax.swing.JSeparator"/>
162
                        <attr name="position" intvalue="1800"/>
163
                    </file>                   
164
                    
165
                    <!-- Cut, Copy, Paste actions block -->
166
                    <file name="ToolsSeparator.instance"><attr name="instanceClass" stringvalue="javax.swing.JSeparator"/>    <attr name="position" intvalue="4100"/>
167
                    </file>
168
                    
169
                    <file name="org-openide-actions-ToolsAction.shadow">
170
                        <attr name="originalFile" stringvalue="Actions/System/org-openide-actions-ToolsAction.instance"/>
171
                        <attr name="position" intvalue="4200"/>
172
                    </file>
173
                </folder>
174
                
175
                <folder name="CodeTemplates">
176
                    <folder name="Defaults">
177
                        <file name="org-netbeans-modules-xml-text-xmlCodeTemplates.xml" url="XMLEditor-abbreviations.xml"/>
178
                    </folder>
179
                </folder>
180
                
181
                <folder name="Preferences">
51
                <folder name="Preferences">
182
                    <folder name="Defaults">
52
                    <folder name="Defaults">
183
                        <file name="org-netbeans-modules-xml-text-xmlPreferences.xml" url="XMLEditor-preferences.xml"/>
53
                        <file name="org-netbeans-modules-xml-text-xmlPreferences.xml" url="XMLEditor-preferences.xml"/>
184
                    </folder>
54
                    </folder>
185
                </folder>
55
                </folder>
186
                
187
                <file name="EditorKit.instance">
188
                    <attr name="instanceClass" stringvalue="org.netbeans.modules.xml.text.syntax.XMLKit"/>
189
                    <attr name="instanceOf" stringvalue="javax.swing.text.EditorKit,org.netbeans.modules.xml.text.syntax.XMLKit"/>
190
                    <attr name="beaninfo" boolvalue="false"/>
191
                </file>
192
                
193
                <!-- <folder name="Toolbars">
194
                    <folder name="Default">
195
                        <attr name="stop-macro-recording/XMLSeparator1.instance" boolvalue="true"/>
196
                        <file name="XMLSeparator1.instance">
197
                            <attr name="instanceClass" stringvalue="javax.swing.JSeparator"/>
198
                        </file>
199
200
                        <attr name="XMLSeparator1.instance/xml-comment" boolvalue="true"/>
201
                        <file name="xml-comment"/>
202
                        <attr name="xml-comment/xml-uncomment" boolvalue="true"/>
203
                        <file name="xml-uncomment"/>
204
                    </folder> <!__ Default __>
205
                </folder> -->
206
                <folder name="SideBar">
207
                    <file name="breadcrumbs.instance">
208
                        <attr name="location" stringvalue="South"/>
209
                        <attr name="position" intvalue="5237"/>
210
                        <attr name="scrollable" boolvalue="false"/>
211
                        <attr name="instanceCreate" methodvalue="org.netbeans.modules.editor.breadcrumbs.spi.BreadcrumbsController.createSideBarFactory" />
212
                    </file>
213
                </folder>
214
            </folder> <!-- xml -->
215
216
            <folder name="xml-external-parsed-entity">
217
                <attr name="SystemFileSystem.localizingBundle" stringvalue="org.netbeans.modules.xml.text.resources.Bundle"/>
218
                <!-- It reuses kit only -->
219
                <file name="EditorKit.instance">
220
                    <attr name="instanceClass" stringvalue="org.netbeans.modules.xml.text.syntax.ENTKit"/>
221
                    <attr name="instanceOf" stringvalue="javax.swing.text.EditorKit,org.netbeans.modules.xml.text.syntax.ENTKit"/>
222
                    <attr name="beaninfo" boolvalue="false"/>
223
                </file>
224
                
225
                <folder name="CompletionProviders">
226
                    <file name="org-netbeans-modules-xml-text-completion-XMLCompletionProvider.instance"/>
227
                </folder>
228
                
229
                <folder name="FontsColors">
230
                    <folder name="NetBeans">
231
                        <folder name="Defaults">
232
                            <file name="org-netbeans-modules-xml-text-token-colorings.xml" url="XML-fontsColors.xml">
233
                                <attr name="SystemFileSystem.localizingBundle" stringvalue="org.netbeans.modules.xml.text.resources.Bundle"/>
234
                            </file>
235
                        </folder>
236
                    </folder>
237
                </folder>                
238
                <folder name="DocumentModel">
56
                <folder name="DocumentModel">
239
                    <file name="org-netbeans-modules-xml-text-structure-XMLDocumentModelProvider.instance"/>
57
                    <file name="org-netbeans-modules-xml-text-structure-XMLDocumentModelProvider.instance"/>
240
                </folder>
58
                </folder>
241
                
59
            </folder>
242
                <folder name="FoldManager">
60
            <folder name="xml-external-parsed-entity">
243
                    <file name="org-netbeans-modules-xml-text-folding-XmlFoldManagerFactory.instance">
61
                <folder name="DocumentModel">
244
                	<attr name="position" intvalue="1100"/>
62
                    <file name="org-netbeans-modules-xml-text-structure-XMLDocumentModelProvider.instance"/>
245
            	    </file>
246
                </folder>
63
                </folder>
247
                
248
                <folder name="Popup">
249
                    <file name="org-netbeans-modules-xml-actions-CollectXMLAction.shadow">
250
                        <attr name="originalFile" stringvalue="Actions/XML/org-netbeans-modules-xml-actions-CollectXMLAction.instance"/>
251
                        <attr name="position" intvalue="1600"/>
252
                    </file>
253
                    <file name="org-netbeans-modules-xml-actions-XMLViewActions.instance">
254
                        <attr name="position" intvalue="1400"/>
255
                    </file>
256
                    <!-- implicit separator provided by above action group -->
257
                    
258
                    <file name="format">
259
                        <attr name="position" intvalue="1200"/>
260
                    </file>
261
                    <file name="SeparatorAfterFormat.instance">
262
                        <attr name="instanceClass" stringvalue="javax.swing.JSeparator"/>
263
                        <attr name="position" intvalue="1800"/>
264
                    </file>                   
265
                    
266
                    <!-- Cut, Copy, Paste actions block -->
267
                    <file name="ToolsSeparator.instance"><attr name="instanceClass" stringvalue="javax.swing.JSeparator"/>    <attr name="position" intvalue="4100"/>
268
                    </file>
269
                    
270
                    <file name="org-openide-actions-ToolsAction.shadow">
271
                        <attr name="originalFile" stringvalue="Actions/System/org-openide-actions-ToolsAction.instance"/>
272
                        <attr name="position" intvalue="4200"/>
273
                    </file>
274
                </folder>
275
                
276
                <folder name="CodeTemplates">
277
                    <folder name="Defaults">
278
                        <file name="org-netbeans-modules-xml-text-xmlCodeTemplates.xml" url="XMLEditor-abbreviations.xml"/>
279
                    </folder>
280
                </folder>
281
                
282
                <!-- <file name="Settings.settings" url="XMLEditor-options.xml"/> -->
283
                
284
            </folder> <!-- xml-external-parsed-entity -->
64
            </folder> <!-- xml-external-parsed-entity -->
285
        </folder> <!-- text -->
65
        </folder> <!-- text -->
286
287
        <folder name="application">
66
        <folder name="application">
288
            <folder name="xml-dtd">
67
            <folder name="xml-dtd">
289
                <attr name="SystemFileSystem.localizingBundle" stringvalue="org.netbeans.modules.xml.text.resources.Bundle"/>
290
                
291
                <folder name="FontsColors">
292
                    <folder name="NetBeans">
293
                        <folder name="Defaults">
294
                            <file name="org-netbeans-modules-xml-text-token-colorings.xml" url="DTD-fontsColors.xml">
295
                                <attr name="SystemFileSystem.localizingBundle" stringvalue="org.netbeans.modules.xml.text.resources.Bundle"/>
296
                            </file>
297
                        </folder>
298
                    </folder>
299
                </folder>
300
                
301
                <folder name="Popup">                    
302
                    <!-- implicit separator provided by below action group -->    
303
                    
304
                    
305
                    <file name="ToolsSeparator.instance"><attr name="instanceClass" stringvalue="javax.swing.JSeparator"/>    <attr name="position" intvalue="4200"/>
306
                    </file>
307
                    
308
                    <file name="org-netbeans-modules-xml-actions-CollectDTDAction.shadow">
309
                        <attr name="originalFile" stringvalue="Actions/XML/org-netbeans-modules-xml-actions-CollectDTDAction.instance"/>
310
                        <attr name="position" intvalue="4100"/>
311
                    </file>
312
                    <file name="org-openide-actions-ToolsAction.shadow">
313
                        <attr name="originalFile" stringvalue="Actions/System/org-openide-actions-ToolsAction.instance"/>
314
                        <attr name="position" intvalue="4300"/>
315
                    </file>
316
                </folder>
317
                
318
                <folder name="CodeTemplates">
319
                    <folder name="Defaults">
320
                        <file name="org-netbeans-modules-xml-text-dtdCodeTemplates.xml" url="DTDEditor-abbreviations.xml"/>
321
                    </folder>
322
                </folder>
323
                
324
                <folder name="Preferences">
68
                <folder name="Preferences">
325
                    <folder name="Defaults">
69
                    <folder name="Defaults">
326
                        <file name="org-netbeans-modules-xml-text-dtdPreferences.xml" url="DTDEditor-preferences.xml"/>
70
                        <file name="org-netbeans-modules-xml-text-dtdPreferences.xml" url="DTDEditor-preferences.xml"/>
327
                    </folder>
71
                    </folder>
328
                </folder>
72
                </folder>
329
                
330
                <file name="EditorKit.instance">
331
                    <attr name="instanceClass" stringvalue="org.netbeans.modules.xml.text.syntax.DTDKit"/>
332
                    <attr name="instanceOf" stringvalue="javax.swing.text.EditorKit,org.netbeans.modules.xml.text.syntax.DTDKit"/>
333
                    <attr name="beaninfo" boolvalue="false"/>
334
                </file>
335
            </folder> <!-- xml-dtd -->
336
        </folder> <!-- application -->
337
    </folder> <!-- Editors -->
338
    
339
    <folder name="OptionsDialog">
340
        <folder name="PreviewExamples">
341
            <folder name="application">
342
                <file name="xml-dtd" url="DTDExample"/>
343
            </folder>
344
            <folder name="text">
345
                <file name="xml" url="XMLExample"/>
346
            </folder>
73
            </folder>
347
        </folder>
74
        </folder>
348
    </folder>
75
    </folder> <!-- Editors -->
349
    
350
</filesystem>
76
</filesystem>
(-)a/xml.text/src/org/netbeans/modules/xml/text/syntax/SyntaxElement.java (-4 / +21 lines)
Lines 45-57 Link Here
45
package org.netbeans.modules.xml.text.syntax;
45
package org.netbeans.modules.xml.text.syntax;
46
46
47
import java.lang.ref.WeakReference;
47
import java.lang.ref.WeakReference;
48
import java.util.*;
49
48
50
import org.w3c.dom.*;
49
import org.w3c.dom.*;
51
50
52
import javax.swing.text.*;
51
import javax.swing.text.*;
53
52
54
import org.netbeans.editor.ext.*;
55
import org.netbeans.editor.*;
53
import org.netbeans.editor.*;
56
import org.openide.ErrorManager;
54
import org.openide.ErrorManager;
57
55
Lines 67-73 Link Here
67
 *
65
 *
68
 * @version 1.0
66
 * @version 1.0
69
 */
67
 */
70
public abstract class SyntaxElement {
68
public abstract class SyntaxElement implements org.netbeans.modules.xml.text.api.dom.SyntaxElement {
71
    
69
    
72
    // to do do not handle prolog as text!
70
    // to do do not handle prolog as text!
73
    // support PIs
71
    // support PIs
Lines 134-140 Link Here
134
    void setPrevious(SyntaxElement se) {
132
    void setPrevious(SyntaxElement se) {
135
        previous = new WeakReference(se);
133
        previous = new WeakReference(se);
136
    }
134
    }
137
    
135
138
    /**
136
    /**
139
     * Get previous SyntaxElement. Weakly cache results.
137
     * Get previous SyntaxElement. Weakly cache results.
140
     * @return previous SyntaxElement or <code>null</code> at document begining
138
     * @return previous SyntaxElement or <code>null</code> at document begining
Lines 243-248 Link Here
243
        public String toString() {
241
        public String toString() {
244
            return "Error" + super.toString();                                  // NOI18N
242
            return "Error" + super.toString();                                  // NOI18N
245
        }
243
        }
244
245
        @Override
246
        public int getType() {
247
            return NODE_ERROR;
248
        }
249
250
        @Override
251
        public Node getNode() {
252
            return null;
253
        }
254
255
        @Override
256
        public SyntaxElement getParentElement() {
257
            SyntaxElement x = this;
258
            while (x != null && x.getType() != Node.ELEMENT_NODE) {
259
                x = x.getPrevious();
260
            }
261
            return x;
262
        }
246
    }
263
    }
247
    
264
    
248
}
265
}
(-)a/xml.text/src/org/netbeans/modules/xml/text/syntax/XMLSyntaxSupport.java (-1 / +1 lines)
Lines 73-79 Link Here
73
 * @author  Petr Kuzel - use before strategy, use tokens whenever possible
73
 * @author  Petr Kuzel - use before strategy, use tokens whenever possible
74
 * @version 0.8
74
 * @version 0.8
75
 */
75
 */
76
public class XMLSyntaxSupport extends ExtSyntaxSupport implements XMLTokenIDs {
76
public final class XMLSyntaxSupport extends ExtSyntaxSupport implements XMLTokenIDs {
77
    
77
    
78
    private Reference reference = new SoftReference(null);  // cached helper
78
    private Reference reference = new SoftReference(null);  // cached helper
79
    private String systemId = null;  // cached refernce to DTD
79
    private String systemId = null;  // cached refernce to DTD
(-)a/xml.text/src/org/netbeans/modules/xml/text/syntax/XMLTokenContext.java (-2 lines)
Lines 43-50 Link Here
43
 */
43
 */
44
package org.netbeans.modules.xml.text.syntax;
44
package org.netbeans.modules.xml.text.syntax;
45
45
46
import org.netbeans.editor.BaseTokenCategory;
47
import org.netbeans.editor.BaseTokenID;
48
import org.netbeans.editor.TokenContext;
46
import org.netbeans.editor.TokenContext;
49
import org.netbeans.editor.TokenContextPath;
47
import org.netbeans.editor.TokenContextPath;
50
48
(-)a/xml.text/src/org/netbeans/modules/xml/text/syntax/dom/AttrImpl.java (+3 lines)
Lines 44-49 Link Here
44
44
45
package org.netbeans.modules.xml.text.syntax.dom;
45
package org.netbeans.modules.xml.text.syntax.dom;
46
46
47
import org.netbeans.modules.xml.text.syntax.XMLSyntaxSupport;
48
import org.netbeans.modules.xml.text.syntax.XMLTokenIDs;
47
import java.util.*;
49
import java.util.*;
48
import javax.swing.text.BadLocationException;
50
import javax.swing.text.BadLocationException;
49
51
Lines 51-56 Link Here
51
import org.netbeans.modules.xml.text.syntax.*;
53
import org.netbeans.modules.xml.text.syntax.*;
52
import org.netbeans.modules.xml.spi.dom.*;
54
import org.netbeans.modules.xml.spi.dom.*;
53
import org.netbeans.editor.*;
55
import org.netbeans.editor.*;
56
import org.netbeans.modules.xml.*;
54
57
55
/**
58
/**
56
 * Holds attribute: name-value pairs. It is returned by <code>Tag</code>
59
 * Holds attribute: name-value pairs. It is returned by <code>Tag</code>
(-)a/xml.text/src/org/netbeans/modules/xml/text/syntax/dom/CDATASectionImpl.java (+1 lines)
Lines 44-49 Link Here
44
44
45
package org.netbeans.modules.xml.text.syntax.dom;
45
package org.netbeans.modules.xml.text.syntax.dom;
46
46
47
import org.netbeans.modules.xml.text.syntax.XMLSyntaxSupport;
47
import org.w3c.dom.*;
48
import org.w3c.dom.*;
48
import org.netbeans.modules.xml.text.syntax.*;
49
import org.netbeans.modules.xml.text.syntax.*;
49
import org.netbeans.modules.xml.spi.dom.*;
50
import org.netbeans.modules.xml.spi.dom.*;
(-)a/xml.text/src/org/netbeans/modules/xml/text/syntax/dom/CommentImpl.java (+1 lines)
Lines 44-49 Link Here
44
44
45
package org.netbeans.modules.xml.text.syntax.dom;
45
package org.netbeans.modules.xml.text.syntax.dom;
46
46
47
import org.netbeans.modules.xml.text.syntax.XMLSyntaxSupport;
47
import org.w3c.dom.*;
48
import org.w3c.dom.*;
48
import org.netbeans.modules.xml.text.syntax.*;
49
import org.netbeans.modules.xml.text.syntax.*;
49
import org.netbeans.modules.xml.spi.dom.*;
50
import org.netbeans.modules.xml.spi.dom.*;
(-)a/xml.text/src/org/netbeans/modules/xml/text/syntax/dom/DocumentImpl.java (+1 lines)
Lines 44-49 Link Here
44
44
45
package org.netbeans.modules.xml.text.syntax.dom;
45
package org.netbeans.modules.xml.text.syntax.dom;
46
46
47
import org.netbeans.modules.xml.text.syntax.SyntaxElement;
47
import org.w3c.dom.*;
48
import org.w3c.dom.*;
48
import org.netbeans.modules.xml.text.syntax.*;
49
import org.netbeans.modules.xml.text.syntax.*;
49
import org.netbeans.modules.xml.spi.dom.*;
50
import org.netbeans.modules.xml.spi.dom.*;
(-)a/xml.text/src/org/netbeans/modules/xml/text/syntax/dom/DocumentTypeImpl.java (+2 lines)
Lines 44-49 Link Here
44
44
45
package org.netbeans.modules.xml.text.syntax.dom;
45
package org.netbeans.modules.xml.text.syntax.dom;
46
46
47
import org.netbeans.modules.xml.text.syntax.XMLSyntaxSupport;
48
import org.netbeans.modules.xml.text.syntax.XMLTokenIDs;
47
import org.w3c.dom.*;
49
import org.w3c.dom.*;
48
import org.netbeans.modules.xml.text.syntax.*;
50
import org.netbeans.modules.xml.text.syntax.*;
49
import org.netbeans.modules.xml.spi.dom.*;
51
import org.netbeans.modules.xml.spi.dom.*;
(-)a/xml.text/src/org/netbeans/modules/xml/text/syntax/dom/EmptyTag.java (+1 lines)
Lines 44-49 Link Here
44
44
45
package org.netbeans.modules.xml.text.syntax.dom;
45
package org.netbeans.modules.xml.text.syntax.dom;
46
46
47
import org.netbeans.modules.xml.text.syntax.XMLSyntaxSupport;
47
import java.util.*;
48
import java.util.*;
48
49
49
import org.w3c.dom.*;
50
import org.w3c.dom.*;
(-)a/xml.text/src/org/netbeans/modules/xml/text/syntax/dom/EndTag.java (+2 lines)
Lines 44-49 Link Here
44
44
45
package org.netbeans.modules.xml.text.syntax.dom;
45
package org.netbeans.modules.xml.text.syntax.dom;
46
46
47
import org.netbeans.modules.xml.text.syntax.XMLSyntaxSupport;
48
import org.netbeans.modules.xml.text.syntax.SyntaxElement;
47
import java.util.*;
49
import java.util.*;
48
50
49
import org.w3c.dom.*;
51
import org.w3c.dom.*;
(-)a/xml.text/src/org/netbeans/modules/xml/text/syntax/dom/EntityReferenceImpl.java (+1 lines)
Lines 44-49 Link Here
44
44
45
package org.netbeans.modules.xml.text.syntax.dom;
45
package org.netbeans.modules.xml.text.syntax.dom;
46
46
47
import org.netbeans.modules.xml.text.syntax.XMLSyntaxSupport;
47
import org.w3c.dom.*;
48
import org.w3c.dom.*;
48
import org.netbeans.modules.xml.text.syntax.*;
49
import org.netbeans.modules.xml.text.syntax.*;
49
import org.netbeans.modules.xml.spi.dom.*;
50
import org.netbeans.modules.xml.spi.dom.*;
(-)a/xml.text/src/org/netbeans/modules/xml/text/syntax/dom/StartTag.java (+2 lines)
Lines 44-49 Link Here
44
44
45
package org.netbeans.modules.xml.text.syntax.dom;
45
package org.netbeans.modules.xml.text.syntax.dom;
46
46
47
import org.netbeans.modules.xml.text.syntax.XMLSyntaxSupport;
48
import org.netbeans.modules.xml.text.syntax.SyntaxElement;
47
import java.util.*;
49
import java.util.*;
48
50
49
import org.w3c.dom.*;
51
import org.w3c.dom.*;
(-)a/xml.text/src/org/netbeans/modules/xml/text/syntax/dom/SyntaxNode.java (+16 lines)
Lines 44-49 Link Here
44
44
45
package org.netbeans.modules.xml.text.syntax.dom;
45
package org.netbeans.modules.xml.text.syntax.dom;
46
46
47
import org.netbeans.modules.xml.text.syntax.XMLSyntaxSupport;
48
import org.netbeans.modules.xml.text.syntax.SyntaxElement;
47
import org.w3c.dom.*;
49
import org.w3c.dom.*;
48
import org.netbeans.modules.xml.text.syntax.*;
50
import org.netbeans.modules.xml.text.syntax.*;
49
import org.netbeans.modules.xml.spi.dom.*;
51
import org.netbeans.modules.xml.spi.dom.*;
Lines 72-77 Link Here
72
        super( support, first, to);
74
        super( support, first, to);
73
    }
75
    }
74
76
77
    @Override
78
    public int getType() {
79
        return getNodeType();
80
    }
81
    
82
    @Override
83
    public Node getNode() {
84
        return this;
85
    }
75
    /**
86
    /**
76
     * Default implementation returning first previous <code>SyntaxNode</code>
87
     * Default implementation returning first previous <code>SyntaxNode</code>
77
     * or <code>null</code>. It is <code>StartTag</code> aware.
88
     * or <code>null</code>. It is <code>StartTag</code> aware.
Lines 341-345 Link Here
341
    public void setIdAttributeNode(Attr a, boolean b) {
352
    public void setIdAttributeNode(Attr a, boolean b) {
342
        throw new UOException ();
353
        throw new UOException ();
343
    }
354
    }
355
356
    @Override
357
    public org.netbeans.modules.xml.text.api.dom.SyntaxElement getParentElement() {
358
        return (SyntaxElement)getParentNode();
359
    }
344
    
360
    
345
}
361
}
(-)a/xml.text/src/org/netbeans/modules/xml/text/syntax/dom/Tag.java (+2 lines)
Lines 44-49 Link Here
44
44
45
package org.netbeans.modules.xml.text.syntax.dom;
45
package org.netbeans.modules.xml.text.syntax.dom;
46
46
47
import org.netbeans.modules.xml.text.syntax.XMLSyntaxSupport;
48
import org.netbeans.modules.xml.text.syntax.XMLTokenIDs;
47
import java.util.*;
49
import java.util.*;
48
import javax.swing.text.BadLocationException;
50
import javax.swing.text.BadLocationException;
49
51
(-)a/xml.text/src/org/netbeans/modules/xml/text/syntax/dom/TextImpl.java (+1 lines)
Lines 44-49 Link Here
44
44
45
package org.netbeans.modules.xml.text.syntax.dom;
45
package org.netbeans.modules.xml.text.syntax.dom;
46
46
47
import org.netbeans.modules.xml.text.syntax.XMLSyntaxSupport;
47
import org.w3c.dom.*;
48
import org.w3c.dom.*;
48
import org.netbeans.modules.xml.text.syntax.*;
49
import org.netbeans.modules.xml.text.syntax.*;
49
import org.netbeans.modules.xml.spi.dom.*;
50
import org.netbeans.modules.xml.spi.dom.*;
(-)a/xml.text/src/org/netbeans/modules/xml/text/syntax/dom/Util.java (-61 / +3 lines)
Lines 81-114 Link Here
81
     * @return the same value of stripped substring of it.
81
     * @return the same value of stripped substring of it.
82
     */
82
     */
83
    public static String actualAttributeValue(String attributeValue) {
83
    public static String actualAttributeValue(String attributeValue) {
84
        int ltIndex = attributeValue.indexOf('<');
84
        return org.netbeans.modules.xml.text.api.XMLTextUtils.actualAttributeValue(attributeValue);
85
        int gtIndex = attributeValue.indexOf('>');
86
        int firstUnwantedIndex = -1;
87
        if (gtIndex != -1) {
88
            if (ltIndex != -1 && ltIndex < gtIndex) {
89
                firstUnwantedIndex = ltIndex;
90
            } else {
91
                firstUnwantedIndex = gtIndex;
92
            }
93
        } else {
94
            firstUnwantedIndex = ltIndex;
95
        }
96
        
97
        if (firstUnwantedIndex != -1) {
98
            char charAtIndex = attributeValue.charAt(firstUnwantedIndex);
99
            while (charAtIndex == ' ' || charAtIndex == '\t' || charAtIndex  == '\n' ||
100
            charAtIndex == '\r' || charAtIndex == '<' || charAtIndex == '>') {
101
                firstUnwantedIndex--;
102
                if (firstUnwantedIndex < 0) {
103
                    break;
104
                }
105
                charAtIndex = attributeValue.charAt(firstUnwantedIndex);
106
            }
107
            
108
            return attributeValue.substring(0, firstUnwantedIndex + 1);
109
        } else {
110
            return attributeValue;
111
        }
112
    }
85
    }
113
    
86
    
114
    /**
87
    /**
Lines 118-135 Link Here
118
     * @return a string that may contain '<', '>', '\'', '"', '&'.
91
     * @return a string that may contain '<', '>', '\'', '"', '&'.
119
     */
92
     */
120
    public static String replaceEntityStringsWithChars(String value) {
93
    public static String replaceEntityStringsWithChars(String value) {
121
        StringBuffer buf = new StringBuffer(value);
94
        return org.netbeans.modules.xml.text.api.XMLTextUtils.replaceCharsWithEntityStrings(value);
122
        for (int entity = 0; entity < knownEntityStrings.length; entity++) {
123
            String curEntityString = knownEntityStrings[entity];
124
            int indexOfEntity = buf.toString().indexOf(curEntityString);
125
            while (indexOfEntity != -1) {
126
                buf.replace(indexOfEntity, indexOfEntity + curEntityString.length(),
127
                new String(new char[]{knownEntityChars[entity]}));
128
                indexOfEntity = buf.toString().indexOf(curEntityString);
129
            }
130
        }
131
        
132
        return buf.toString();
133
    }
95
    }
134
    
96
    
135
    /**
97
    /**
Lines 139-165 Link Here
139
     * @return a string that may contain &lt;", "&gt;", "&apos;", "&quot;" and "&amp;"
101
     * @return a string that may contain &lt;", "&gt;", "&apos;", "&quot;" and "&amp;"
140
     */
102
     */
141
    public static String replaceCharsWithEntityStrings(String value) {
103
    public static String replaceCharsWithEntityStrings(String value) {
142
    	if (value == null) {
104
        return org.netbeans.modules.xml.text.api.XMLTextUtils.replaceCharsWithEntityStrings(value);
143
    		return null;
144
    	}
145
        StringBuffer replBuf = new StringBuffer(value.length());
146
        for (int ind = 0; ind < value.length(); ind++) {
147
            boolean charReplaced = false;
148
            char curChar = value.charAt(ind);
149
            for (int entity = 0; entity < knownEntityChars.length; entity++) {
150
                if (curChar == knownEntityChars[entity]) {
151
                    replBuf.append(knownEntityStrings[entity]);
152
                    charReplaced = true;
153
                    break;
154
                }
155
            }
156
            
157
            if (!charReplaced) {
158
                replBuf.append(curChar);
159
            }
160
        }
161
        
162
        return replBuf.toString();
163
    }
105
    }
164
    
106
    
165
}
107
}
(-)a/xml.text.obsolete90/test/unit/data/goldenfiles/org/netbeans/modules/xml/text/indent/XMLFormatterTest/testReformatSample1.pass (+17 lines)
Line 0 Link Here
1
<?xml version="1.0" encoding="UTF-8"?>
2
3
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
4
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
6
         version="2.4">
7
    <session-config>
8
        <session-timeout>
9
            30
10
        </session-timeout>
11
    </session-config>
12
    <welcome-file-list>
13
        <welcome-file>
14
            index.jsp
15
        </welcome-file>
16
    </welcome-file-list>
17
</web-app>
(-)a/xml.text.obsolete90/test/unit/data/goldenfiles/org/netbeans/modules/xml/text/indent/XMLFormatterTest/testReformatSample2-.pass (+1716 lines)
Line 0 Link Here
1
<?xml version="1.0" encoding="UTF-8"?> <!-- -*- sgml-indent-step: 2 -*- -->
2
<!--
3
The contents of this file are subject to the terms of the Common Development
4
and Distribution License (the License). You may not use this file except in
5
compliance with the License.
6
7
You can obtain a copy of the License at http://www.netbeans.org/cddl.html
8
or http://www.netbeans.org/cddl.txt.
9
10
When distributing Covered Code, include this CDDL Header Notice in each file
11
and include the License file at http://www.netbeans.org/cddl.txt.
12
If applicable, add the following below the CDDL Header, with the fields
13
enclosed by brackets [] replaced by your own identifying information:
14
"Portions Copyrighted [year] [name of copyright owner]"
15
16
The Original Software is NetBeans. The Initial Developer of the Original
17
Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
18
Microsystems, Inc. All Rights Reserved.
19
-->
20
<project name="nbbuild" default="all" basedir=".">
21
    
22
    <import file="default.xml"/>
23
    
24
    <!-- To make people happy who want to do `ant clean all': -->
25
    <target name="all" depends="build,commit-validation" description="Build the IDE and run basic validation tests."/>
26
    
27
    <target name="all-nozip" depends="build-nozip,commit-validation" description="Build the IDE (no ZIP file, unpacked) and run basic validation tests."/>
28
    
29
    <target name="assure-ant">
30
        <condition property="ant.version.is.good">
31
            <!-- this is in 1.6.3 only -->
32
            <!-- actually needed for 'executable' attr on <javadoc>, at least -->
33
            <available classname="org.apache.tools.ant.types.mappers.FilterMapper"/>
34
        </condition>
35
        <fail unless="ant.version.is.good">
36
            You need to have ant 1.6.3 at least to build NetBeans.
37
        </fail>
38
    </target>
39
    
40
    <target name="bootstrap"
41
            description="Bootstrap NetBeans-specific Ant extensions."
42
            depends="-jdk-init,-assure-jdk-1.4,assure-ant">
43
        <echo message="Bootstrapping NetBeans-specific Ant extensions..."
44
        />
45
        <property name="ant.jar" value="${ant.home}/lib/ant.jar"/>
46
        <path id="bootstrap-cp">
47
            <pathelement location="${ant.jar}"/>
48
            <fileset dir="..">
49
                <!-- For JavaHelp indexing: -->
50
                <include name="nbbuild/external/jhall*.jar"/>
51
            </fileset>
52
        </path>
53
        <!-- Sanity check: -->
54
        <pathconvert pathsep=":" property="class.files.in.antsrc">
55
            <path>
56
                <fileset dir="antsrc">
57
                    <include name="**/*.class"/>
58
                </fileset>
59
            </path>
60
        </pathconvert>
61
        <fail>
62
            <condition>
63
                <not>
64
                    <equals arg1="${class.files.in.antsrc}" arg2=""/>
65
                </not>
66
            </condition>
67
            You have stray *.class files in ${basedir}/antsrc which you must remove.
68
            Probably you failed to clean your sources before updating them from CVS.
69
        </fail>
70
        <!-- OK, continue: -->
71
        <mkdir dir="build/antclasses"/>
72
        <javac srcdir="antsrc" destdir="build/antclasses" deprecation="true" debug="${build.compiler.debug}" source="1.4">
73
            <classpath refid="bootstrap-cp"/>
74
        </javac>
75
        <jar jarfile="nbantext.jar">
76
            <fileset dir="build/antclasses"/>
77
            <fileset dir="antsrc">
78
                <exclude name="**/*.java"/>
79
                <exclude name="**/package.html"/>
80
                <exclude name="package-list"/>
81
            </fileset>
82
        </jar>
83
    </target>
84
    
85
    <target name="init-module-list" depends="bootstrap">
86
        <!-- Define modules. -->
87
        <resolve name="modules" value="config.modules.${moduleconfig}"/>
88
        <resolve name="fixedmodules" value="config.fixedmodules.${moduleconfig}"/>
89
        <property name="allmodules" value="${fixedmodules},${modules}"/>
90
    </target>
91
    
92
    <target name="set-buildnumber" unless="buildnumber">
93
        <tstamp>
94
            <format property="buildnumber" pattern="yyMMdd"/>
95
        </tstamp>
96
        <tstamp>
97
            <format property="buildday" pattern="d MMM yyyy" locale="en" />
98
        </tstamp>
99
    </target>
100
    
101
    <target name="init" depends="init-module-list,set-buildnumber,init-tasks">
102
        <taskdef name="cleanall" classname="org.netbeans.nbbuild.CleanAll" classpath="nbantext.jar"/>
103
        <taskdef name="nbmerge" classname="org.netbeans.nbbuild.NbMerge" classpath="nbantext.jar"/>
104
        <taskdef name="for-each" classname="org.netbeans.nbbuild.ForEach" classpath="nbantext.jar"/>
105
        <taskdef name="getdependsclusters" classname="org.netbeans.nbbuild.GetDependsClusters" classpath="nbantext.jar"/>
106
        <taskdef name="repeat" classname="org.netbeans.nbbuild.Repeat" classpath="nbantext.jar"/>
107
        
108
        <!-- We need absolute path to ${netbeans.dest} -->
109
        <property name="netbeans.dest.abs" location="${netbeans.dest}"/>
110
        <!-- Overridable. Note: need not necessarily be a number at all): -->
111
        <property name="buildnum" value="dev-${buildnumber}"/>
112
        <property name="sanitystart.args" value="-J-Dnetbeans.close=true ${sanitystart.args.additional}"/>
113
        
114
        <!-- Set up automatic all-* targets: -->
115
        <taskdef name="insert-module-all-targets" classname="org.netbeans.nbbuild.InsertModuleAllTargets" classpath="nbantext.jar"/>
116
        <insert-module-all-targets/>
117
    </target>
118
    
119
    <target name="all-java/storagebuilder" depends="init">
120
        <antcall target="build-one-cluster-dependencies" inheritall="false">
121
            <param name="one.cluster.dependencies" value="nb.cluster.platform,nb.cluster.ide"/>
122
            <param name="one.cluster.name" value="this-cluster"/>
123
        </antcall>
124
        <echo message="Building java/storagebuilder library..."/>
125
        <ant dir="../java/storagebuilder" target="jar"/>
126
    </target>
127
    
128
    <target name="all-ide/branding" depends="init">
129
        <echo message="Building module ide/branding..."/>
130
        <getdependsclusters name="dependsClusters" list="${nb.clusters.list}"/>
131
        <antcall target="build-one-cluster-dependencies" inheritAll="false">
132
            <param name="one.cluster.dependencies" value="${dependsClusters}"/>
133
            <param name="one.cluster.name" value="this-cluster"/>
134
        </antcall>
135
        <ant dir="../ide/branding" target="netbeans"/>
136
    </target>
137
    
138
    <target name="all-installer" description="Dummy target for build system compatibility"/>
139
    
140
    <target name="all-tomcatint/tomcat5/bundled" depends="init">
141
        <getdependsclusters name="dependsClusters" list="${nb.clusters.list}"/>
142
        <antcall target="build-one-cluster-dependencies" inheritAll="false">
143
            <param name="one.cluster.dependencies" value="${dependsClusters}"/>
144
            <param name="one.cluster.name" value="this-cluster"/>
145
        </antcall>
146
        <!-- XXX this and xtest are clumsy: <antcall target="all-monitor"/> will not work since the subproject used by antcall does *not* have the synthetic targets! -->
147
        <ant dir="../monitor"/>
148
        <echo message="Building module tomcatint/tomcat5/bundled..."/>
149
        <ant dir="../tomcatint/tomcat5/bundled" target="netbeans"/>
150
    </target>
151
    
152
    <target name="all-translatedfiles" depends="init">
153
        <echo message="Building module translatedfiles..."/>
154
        <getdependsclusters name="dependsClusters" list="${nb.clusters.list}"/>
155
        <antcall target="build-one-cluster-dependencies" inheritAll="false">
156
            <param
157
                name="one.cluster.dependencies" 
158
                value="${dependsClusters}"/>
159
            <param name="one.cluster.name" value="this-cluster"/>
160
        </antcall>
161
        <ant dir="../translatedfiles" target="netbeans"/>
162
    </target>
163
    
164
    <target name="all-xtest" depends="init">
165
        <getdependsclusters name="dependsClusters" list="${clusters.list}"/>
166
        <antcall target="build-one-cluster-dependencies" inheritAll="false">
167
            <param name="one.cluster.dependencies" value="${dependsClusters}"/>
168
            <param name="one.cluster.name" value="this-cluster"/>
169
        </antcall>
170
        <ant dir="../xtest/nbjunit"/>
171
        <echo message="Building module xtest..."/>
172
        <ant dir="../xtest" antfile="build.xml" target="netbeans"/>
173
    </target>
174
    
175
    <!-- this is project is not a netbeans module project, so we do a no-op
176
       here.  The code in appsrvbridge gets built by XXX -->
177
    <target name="all-serverplugins/sun/appsrvbridge" depends="init">
178
        <echo message="Building module serverplugins/sun/appsrvbridge... NO-OP"/>
179
    </target>
180
    
181
    <!-- build NBMs for selected modules -->
182
    <target name="build-nbms" depends="init">
183
        <!-- It's good idea to call merge target before this one.
184
           NbMerge.java can set property "modules" to the list of realy
185
           built modules (excluding fixedmodules which must build everytime). -->
186
        <mkdir dir="nbms" />
187
        <property name="nbm.target.dir" location="nbms" />
188
        <for-each startdir=".." target="nbm" locations="${allmodules}"/>
189
    </target>
190
    <target name="nbm"/><!-- dummy target -->
191
  
192
    <property name="jnlp.signjar.keystore" location="build/default.keystore" />
193
    <available property="jnlp.signjar.keystore.exists" file="${jnlp.signjar.keystore}" />
194
    <target name="jnlp-generate-keystore" depends="init" unless="jnlp.signjar.keystore.exists" >
195
        <property name="jnlp.signjar.alias" value="jnlp" />
196
        <property name="jnlp.signjar.password" value="netbeans" />
197
        <property name="jnlp.signjar.vendor" value="CN=NetBeans, OU=NetBeans, O=netbeans.org, C=US" />
198
        
199
        <mkdir dir="${jnlp.signjar.keystore}/../" />
200
        <echo message="Going to create default keystore in ${jnlp.signjar.keystore}" />
201
        <genkey 
202
            alias="${jnlp.signjar.alias}"
203
            keystore="${jnlp.signjar.keystore}"
204
            storepass="${jnlp.signjar.password}"
205
            dname="${jnlp.signjar.vendor}"
206
        />
207
    </target>
208
    
209
    <target name="build-jnlp" depends="init,jnlp-generate-keystore">
210
        <fail message="Property jnlp.codebase must be set to final location of your JNLP files!" unless="jnlp.codebase" />
211
        <property name="jnlp.dest.dir" location="build/jnlp" />
212
        <mkdir dir="${jnlp.dest.dir}" />
213
        <for-each startdir=".." target="jnlp" locations="${config.modules.jnlp}"/>
214
    </target>
215
    
216
    <target name="set-config-to-javadoc" >
217
        <property name="moduleconfig" value="javadoc" />
218
    </target>
219
    
220
    <!-- build javadoc for selected modules -->
221
    <target name="build-javadoc" depends="set-config-to-javadoc,init" description="Builds Javadoc documentation for modules; on branches pass e.g. -Djavadoc.web.root=http://www.netbeans.org/download/release35/javadoc">
222
        <ant dir="." target="merge">
223
            <property name="modules" value="${modules}"/>
224
            <property name="fixedmodules" value="${fixedmodules}"/>
225
            <property name="merge.dependent.modules" value="true"/>
226
            <property name="stop.when.broken.module" value="false"/>
227
        </ant>
228
        
229
        <mkdir dir="build/ModulesExportedInterfaces" />
230
        <property name="export.interfaces" location="build/ModulesExportedInterfaces" />
231
        
232
        <mkdir dir="build/APIChanges" />
233
        <property name="export.apichanges" location="build/APIChanges" />
234
        
235
        <!-- build javadoc for supported APIs -->
236
        <for-each startdir=".." target="javadoc" locations="${fixedmodules}"/>
237
        <!-- build javadoc for unsupported APIs -->
238
        <for-each startdir=".." target="javadoc" locations="${modules}"/>
239
        
240
        <antcall inheritall="true" inheritrefs="true" target="javadoc-generate-xml" />
241
        <antcall inheritall="true" inheritrefs="true" target="javadoc-generate-html" />
242
        <antcall inheritall="true" inheritrefs="true" target="javadoc-check-broken-links" />
243
    </target>  
244
    
245
    <target name="javadoc-generate-xml" depends="set-config-to-javadoc,init" >
246
        <echo file="build/APIChanges/header.gen" >&lt;?xml version="1.0" encoding="UTF-8"?&gt;
247
            &lt;changes&gt;
248
        </echo>
249
        
250
        <echo file="build/APIChanges/footer.gen" >
251
            &lt;/changes&gt;
252
        </echo>
253
        
254
        <concat destfile="${netbeans.javadoc.dir}/apichanges.xml" >
255
            <fileset dir="build/APIChanges" includes="header.gen" />
256
            <fileset dir="build/APIChanges" includes="*" excludes="*.gen" />
257
            <fileset dir="build/APIChanges" includes="footer.gen" />
258
        </concat>
259
        
260
        
261
        <echo file="build/ModulesExportedInterfaces/header.gen" >&lt;?xml version="1.0" encoding="UTF-8"?&gt;
262
            &lt;apis&gt;
263
        </echo>
264
        
265
        <echo file="build/ModulesExportedInterfaces/footer.gen" >
266
            &lt;/apis&gt;
267
        </echo>
268
        
269
        <concat destfile="${netbeans.javadoc.dir}/modules.xml" >
270
            <fileset dir="build/ModulesExportedInterfaces" includes="header.gen" />
271
            <fileset dir="build/ModulesExportedInterfaces" includes="*" excludes="*.gen" />
272
            <fileset dir="build/ModulesExportedInterfaces" includes="footer.gen" />
273
        </concat>
274
        
275
        <taskdef 
276
            name="javadoc-index" 
277
            classpath="nbantext.jar" 
278
            classname="org.netbeans.nbbuild.JavadocIndex"
279
        />
280
        
281
        
282
        <javadoc-index target="${netbeans.javadoc.dir}/allclasses.xml" > 
283
            <packageslist dir="${netbeans.javadoc.dir}" >
284
                <include name="**/allclasses-noframe.html" />
285
            </packageslist>
286
        </javadoc-index>
287
    </target>
288
    
289
    
290
    <target name="javadoc-generate-html" depends="set-config-to-javadoc,init" >            
291
        <tstamp>
292
            <format property="modules-javadoc-date" pattern="d MMM yyyy" locale="en" />
293
        </tstamp>
294
        
295
        <style 
296
            in="${netbeans.javadoc.dir}/modules.xml" 
297
            out="${netbeans.javadoc.dir}/usecases.html" 
298
            style="javadoctools/export2usecases.xsl"
299
        >
300
            <param name="date" expression="${modules-javadoc-date}"/>
301
        </style>
302
        
303
        <style 
304
            in="${netbeans.javadoc.dir}/apichanges.xml" 
305
            out="${netbeans.javadoc.dir}/apichanges.html" 
306
            style="javadoctools/export2apichanges.xsl"
307
        >
308
            <param name="date" expression="${modules-javadoc-date}"/>
309
            <param name="changes-since-year" expression="${previous.release.year}"/>
310
            <param name="changes-since-day" expression="${previous.release.day}"/>
311
            <param name="changes-since-month" expression="${previous.release.month}"/>
312
            <param name="include-introduction" expression="true" />
313
        </style>
314
        
315
        <copy file="javadoctools/netbeans.css" tofile="${netbeans.javadoc.dir}/netbeans.css" />
316
        <condition property="javadoc.style.sheet.exists" >
317
            <available file="${netbeans.javadoc.dir}/org-openide-util/javadoc.css" />
318
        </condition>
319
        
320
        <fail unless="javadoc.style.sheet.exists" >
321
            The org-openide-util/javadoc.css has to exist as we are refering to
322
            it from to master module javadoc pages. If it does not anymore, update
323
            the javadoctools/export*.xsl templates.
324
        </fail>
325
        
326
        <style 
327
            in="${netbeans.javadoc.dir}/allclasses.xml" 
328
            out="${netbeans.javadoc.dir}/allclasses-frame.html" 
329
            style="javadoctools/export2allclasses.xsl"
330
        >
331
        </style>
332
        
333
        <style 
334
            in="${netbeans.javadoc.dir}/modules.xml" 
335
            out="${netbeans.javadoc.dir}/overview-frame.html" 
336
            style="javadoctools/export2allmodules.xsl"
337
        >
338
            <param name="date" expression="${modules-javadoc-date}"/>
339
        </style>
340
        
341
        <style 
342
            in="${netbeans.javadoc.dir}/modules.xml" 
343
            out="${netbeans.javadoc.dir}/layers.html" 
344
            style="javadoctools/export2layer.xsl"
345
        >
346
            <param name="date" expression="${modules-javadoc-date}"/>
347
        </style>
348
        
349
        <style 
350
            in="${netbeans.javadoc.dir}/modules.xml" 
351
            out="${netbeans.javadoc.dir}/overview-summary.html" 
352
            style="javadoctools/export2html.xsl"
353
        >
354
            <param name="date" expression="${modules-javadoc-date}"/>
355
        </style>
356
        
357
        
358
        <!-- at the end geneate the index.html so people know where to start -->      
359
        <echo file="${netbeans.javadoc.dir}/index.html" ><![CDATA[
360
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
361
<HTML><HEAD><TITLE>NetBeans API Index</TITLE>
362
</HEAD>
363
<FRAMESET cols="20%,80%" title="" onLoad="top.loadFrames()">
364
<FRAMESET rows="30%,70%" title="" onLoad="top.loadFrames()">
365
<FRAME src="overview-frame.html" name="packageListFrame" title="All Modules">
366
<FRAME src="allclasses-frame.html" name="packageFrame" title="All classes">
367
</FRAMESET>
368
<FRAME src="overview-summary.html" name="classFrame" title="Module, package, class and interface descriptions" scrolling="yes">
369
<NOFRAMES>
370
<H2>Frame Alert</H2>
371
<P>
372
This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client.
373
Link to<A HREF="overview-summary.html">Non-frame version.</A>
374
</NOFRAMES>
375
</FRAMESET>
376
</HTML>
377
        ]]></echo>
378
        
379
        <replace dir="${netbeans.javadoc.dir}">
380
            <include name="*.html"/>
381
            <replacefilter token="@JDK@" value="http://java.sun.com/j2se/1.4.2/docs/api"/>
382
            <replacefilter token="http://root/" value="." />
383
            <replacefilter token="$${javadoc.web.root}" value="." />
384
        </replace>
385
        
386
        <echo message="Javadoc index has been generated to ${netbeans.javadoc.dir}/index.html" />
387
    </target>
388
    
389
    
390
    <target name="javadoc-check-broken-links" depends="init" unless="javadoc.skip.brokenlinks.check" >
391
        <taskdef name="checklinks" classname="org.netbeans.nbbuild.CheckLinks">
392
            <classpath>
393
                <pathelement location="nbantext.jar"/>
394
            </classpath>
395
        </taskdef>
396
        <checklinks basedir="${netbeans.javadoc.dir}" checkexternal="${javadoc.check.external.links}" checkspaces="false" failonerror="true" >
397
            <include name="*/overview-summary.html"/>
398
            <include name="*/apichanges.html"/>
399
            <include name="*/architecture-summary.html"/>
400
            <include name="*/**/package-summary.html"/>
401
            <include name="*/**/doc-files/**/*.html"/>
402
            <include name="*.html" />
403
        </checklinks>
404
    </target>
405
    
406
    <target name="build-messaging" depends="init">
407
        <echo message="Starting a build for NetBeans (build ${buildnum}, config '${moduleconfig}') ..."/>
408
        <echo message="Selected modules: ${modules}"/>
409
        <echo message="OS: ${os.name} ${os.version}  Locale: ${user.language}_${user.region}"/>
410
        <echo message="Java: ${nbjdk.home}"/>
411
    </target>
412
    
413
    <!-- Use of nbmerge target has the effect of automatically depending on all-X for every module. -->
414
    <!-- It also runs deltree(dir=wherever) and copydir(src=../X/netbeans,dest=wherever) to create the IDE install. -->
415
416
    <target name="build-nozip" depends="clean-cluster-flags,build-clusters" description="Build the IDE but do not create a final ZIP file.">
417
        <loadproperties srcFile="${clusters.list.file}" />
418
        
419
        <loadproperties srcfile="${netbeans.dest.dir}/moduleCluster.properties" />
420
        
421
        <mkdir dir="${netbeans.dest.dir}/bin" />
422
        <copy file="../ide/launcher/unix/netbeans" todir="${netbeans.dest.dir}/bin" />
423
        <chmod file="${netbeans.dest.dir}/bin/netbeans" perm="ugo+rx"/>
424
        <copy file="../ide/launcher/windows/netbeans.exe" todir="${netbeans.dest.dir}/bin" />
425
        <copy file="../ide/launcher/windows/nb.exe" todir="${netbeans.dest.dir}/bin" />
426
        <copy file="../ide/launcher/os2/netbeans.cmd" todir="${netbeans.dest.dir}/bin" />
427
        <!-- if anybody knows better place for icons, let me know: jtulach@netbeans.org -->
428
        <copy file="../ide/launcher/os2/nbos2icons.zip" todir="${netbeans.dest.dir}/${nb.cluster.nb.dir}/" />
429
        
430
        <mkdir dir="${netbeans.dest.dir}/etc" />
431
        <copy file="../ide/launcher/netbeans.conf" todir="${netbeans.dest.dir}/etc" />
432
        
433
        <echo message="${netbeans.dest.dir}/${nb.cluster.platform.dir}/lib/nbexec" />
434
        <fixcrlf eol="lf" srcdir="${netbeans.dest.dir}" >
435
            <include name="etc/netbeans.conf" />
436
            <include name="bin/netbeans" />      
437
            <include name="${nb.cluster.platform.dir}/lib/nbexec" />      
438
        </fixcrlf>
439
        <fixcrlf eol="crlf" srcdir="${netbeans.dest.dir}" >
440
            <include name="bin/netbeans.cmd" />      
441
            <include name="${nb.cluster.platform.dir}/lib/nbexec.cmd" />      
442
        </fixcrlf>
443
        
444
        <echo file="${netbeans.dest.dir}/build_info">NetBeans dev build
445
            ------------------
446
            Number:   ${buildnumber}
447
            Date:     ${buildday}
448
            Branding:
449
            Branch:   trunk
450
            Tag:
451
        </echo>
452
    </target>
453
    
454
    <target name="build" depends="build-nozip"
455
            description="Create a complete build including a ZIP distribution (but do not try it).">
456
        <delete file="NetBeans-${buildnum}.zip"/>
457
        <delete file="NetBeans-${buildnum}-build-extra-data.zip"/>
458
        
459
        <property name="nb-extra-files" value="*.built,test/**,extra/**"/>
460
        
461
        <!-- package the zip file -->
462
        <zip destfile="NetBeans-${buildnum}.zip" update="true" duplicate="preserve">
463
            <zipfileset file="${netbeans.dest.dir}/bin/netbeans" filemode="755" prefix="${netbeans.dest}/bin"/>
464
            <zipfileset file="${netbeans.dest.dir}/${nb.cluster.platform.dir}/lib/nbexec" filemode="755" prefix="${netbeans.dest}/${nb.cluster.platform.dir}/lib"/>
465
            <zipfileset dir="${netbeans.dest.dir}/${nb.cluster.ide.dir}/ant/bin" filemode="755" prefix="${netbeans.dest}/${nb.cluster.ide.dir}/ant/bin">
466
                <exclude name="*.bat"/>
467
                <exclude name="*.cmd"/>
468
            </zipfileset>
469
            <zipfileset dir="${netbeans.dest.dir}" filemode="755" prefix="${netbeans.dest}">
470
                <include name="**/*.sh"/>
471
            </zipfileset>
472
            <zipfileset dir="${netbeans.dest.dir}" prefix="${netbeans.dest}" excludes="${nb-extra-files}">
473
                <!-- XXX exclude the temporary cluster for parts of openide -->
474
                <exclude name="tmp" />
475
                <exclude name="tmp/**/*" />
476
            </zipfileset>
477
        </zip>
478
        
479
        <!-- package the zip file with extra files not to be included in regular product package-->
480
        <!--
481
    <zip destfile="NetBeans-${buildnum}-build-extra-data.zip" update="true" duplicate="preserve">
482
        <zipfileset dir="${netbeans.dest.dir}" prefix="${netbeans.dest}" includes="${nb-extra-files}"/>
483
    </zip>
484
    -->
485
486
        <echo>Build created; see NetBeans-${buildnum}.zip (in nbbuild/).
487
            If you like, you may run the IDE straight from
488
            the ${netbeans.dest}/bin/ directory.
489
            (For example, type: ant tryme)
490
        </echo>
491
    </target>
492
    
493
    <target name="delete-and-merge" depends="merge-delete,merge" />   
494
    
495
    <target name="merge-delete" depends="init">
496
        <delete dir="${netbeans.dest}" />
497
    </target>
498
    
499
    <target name="merge" depends="build-messaging">
500
        <mkdir dir="${netbeans.dest.dir}"/>
501
        <nbmerge failonerror="${stop.when.broken.modules}" 
502
                 dest="${netbeans.dest}" 
503
                 topdir=".." 
504
                 fixedmodules="${fixedmodules}" 
505
                 modules="${modules}"
506
                 builtmodulesproperty="${built.modules.property}" 
507
                 targetprefix="all-" 
508
                 mergedependentmodules="${merge.dependent.modules}" >
509
        </nbmerge>
510
        <chmod perm="ugo+x">
511
            <fileset dir="${netbeans.dest.dir}">
512
                <include name="bin/netbeans"/>
513
                <include name="bin/**/*.pl"/>
514
                <include name="jakarta-tomcat-*/bin/*.sh"/>
515
            </fileset>
516
        </chmod>
517
    </target>
518
    
519
    <target name="build-platform" depends="init">
520
        <run-depend-build clusters-to-build="nb.cluster.platform,nb.cluster.harness"/>
521
    </target>
522
    
523
    <target name="build-cluster" depends="init">
524
        <run-depend-build clusters-to-build="${cluster-name}"/>
525
    </target>
526
    
527
    <macrodef name="resolve">
528
        <attribute name="name"/>
529
        <attribute name="value"/>
530
        <sequential>
531
            <property name="@{name}" value="${@{value}}"/>
532
        </sequential>
533
    </macrodef>
534
    
535
    <macrodef name="run-depend-build">
536
        <attribute name="clusters-to-build"/>
537
        <sequential>
538
            <echo>Repeat @{clusters-to-build}</echo>
539
            <repeat target="build-one-cluster" name="one.cluster.name" values="@{clusters-to-build}" /> 
540
        </sequential>
541
    </macrodef>
542
    
543
    <target name="build-clusters" depends="init">
544
        <run-depend-build clusters-to-build="${nb.clusters.list}"/> 
545
    </target>
546
    
547
    <target name="build-one-cluster-dependencies-check">
548
        <condition property="${one.cluster.name}-hasNoDependencies">
549
            <equals arg1="${one.cluster.dependencies}" arg2="" trim="true"/>
550
        </condition>
551
        <echo>Dependency prop :${one.cluster.name}-hasNoDependencies:</echo>
552
        <echo>Cluster dep :${one.cluster.dependencies}:</echo>
553
        <resolve name="test.prop" value="${one.cluster.name}-hasNoDependencies"/>
554
        <echo>Cluster dep prp:${test.prop}:</echo>
555
    </target>
556
    
557
    <target name="build-one-cluster-dependencies" 
558
            depends="build-one-cluster-dependencies-check"
559
            unless="${one.cluster.name}-hasNoDependencies">
560
        <run-depend-build clusters-to-build="${one.cluster.dependencies}"/> 
561
    </target>
562
    
563
    <target name="build-one-cluster-check">
564
        <condition property="${one.cluster.name}-is-built">
565
            <available file="${netbeans.dest.dir}/${one.cluster.name}.built"/>
566
        </condition>
567
        <resolve name="test1.prop" value="${one.cluster.name}-is-built"/>
568
        <echo>Cluster ${one.cluster.name} is :${test1.prop}:</echo>
569
    </target>
570
    
571
    <target name="build-one-cluster" unless="${one.cluster.name}-is-built" depends="build-one-cluster-check">
572
        <echo message="Building ${one.cluster.name} modules"/>
573
        <resolve name="one-cluster-modules" value="${one.cluster.name}"/>
574
        <resolve name="one-cluster-dependencies" value="${one.cluster.name}.depends"/>
575
        <echo>${one-cluster-modules}</echo>
576
        <echo>Dependencies: ${one-cluster-dependencies}</echo>
577
        <insert-module-all-targets/> <!-- we are in a subproject, so need to reinsert the targets... XXX <antcall> and thus <repeat> apparently reparses the Ant script from disk! -->
578
        <antcall target="build-one-cluster-dependencies" inheritAll="false">
579
            <param name="one.cluster.dependencies" value="${one-cluster-dependencies}"/>
580
            <param name="one.cluster.name" value="${one.cluster.name}"/>
581
        </antcall>
582
        <mkdir dir="${netbeans.dest.dir}"/>
583
        <nbmerge failonerror="${stop.when.broken.modules}" 
584
                 dest="${netbeans.dest.dir}" 
585
                 topdir="${nb_all}" 
586
                 fixedmodules="${one-cluster-modules}"
587
                 builtmodulesproperty="${built.modules.property}" 
588
                 targetprefix="all-" 
589
                 mergedependentmodules="false">
590
        </nbmerge>
591
        <touch file="${netbeans.dest.dir}/${one.cluster.name}.built"/>
592
    </target>
593
    
594
    <target name="zipclusters" depends="init">
595
        <mkdir dir="${netbeans.build.dir}/zips"/>
596
        <repeat target="zip-one-cluster" name="one.cluster.name" values="${clusters.list}" /> 
597
        
598
        <!-- package the misc files -->
599
        <zip destfile="${netbeans.build.dir}/zips/${clusters.prefix}-misc-${buildnum}.zip" update="true" duplicate="preserve">
600
            <zipfileset dir="${netbeans.dest.dir}" filemode="755">
601
                <include name="bin/netbeans"/>
602
            </zipfileset>
603
            <zipfileset dir="${netbeans.dest.dir}">
604
                <include name="bin/**"/>
605
                <include name="etc/**/"/>
606
            </zipfileset>
607
        </zip>
608
    </target>
609
    
610
    <target name="zip-one-cluster">
611
        <taskdef name="setclusterpatternset" classname="org.netbeans.nbbuild.SetClusterPatternSet" classpath="nbantext.jar"/>
612
        <taskdef name="setcluster" classname="org.netbeans.nbbuild.SetCluster" classpath="nbantext.jar"/>
613
        <loadproperties srcFile="${clusters.list.file}" />
614
        <loadproperties srcFile="cluster-description.properties" />
615
        <setcluster cluster="${one.cluster.name}" name="one.cluster.dir" />
616
        
617
        <setclusterpatternset cluster="${one.cluster.name}" name="${one.cluster.name}.files" trackingpath="${netbeans.dest.dir}" clusterdir="${one.cluster.dir}"/>
618
        
619
        <resolve name="zipcluster.file" value="${one.cluster.name}.pkg.filename"/>
620
        <zip destfile="${netbeans.build.dir}/zips/${clusters.prefix}-${zipcluster.file}-${buildnum}.zip" update="true" duplicate="preserve">
621
            <zipfileset dir="${netbeans.dest.dir}" filemode="755">
622
                <include name="${one.cluster.dir}/lib/nbexec"/>
623
            </zipfileset>
624
            <zipfileset dir="${netbeans.dest.dir}" filemode="755">
625
                <include name="${one.cluster.dir}/ant/bin/*"/>
626
                <exclude name="${one.cluster.dir}/ant/bin/*.bat"/>
627
                <exclude name="${one.cluster.dir}/ant/bin/*.cmd"/>
628
            </zipfileset>
629
            <zipfileset dir="${netbeans.dest.dir}">
630
                <patternset refID="${one.cluster.name}.files"/>
631
            </zipfileset>
632
        </zip>
633
    </target>
634
    
635
    <target name="create-rpms-proto">
636
        <mkdir dir="${netbeans.build.dir}/rpms"/>
637
        <repeat target="create-one-rpm-proto" name="one.cluster.name" values="${clusters.list}" /> 
638
    </target>
639
    
640
    <target name="create-one-rpm-proto">
641
        <taskdef name="setcluster" classname="org.netbeans.nbbuild.SetCluster" classpath="nbantext.jar"/>
642
        <loadproperties srcFile="cluster.properties" />
643
        <loadproperties srcFile="cluster-description.properties" />
644
        <setcluster cluster="${one.cluster.name}" name="one.cluster.dir" />
645
        <mkdir dir="${netbeans.build.dir}/rpms"/>
646
        
647
        <resolve name="pkg.name" value="${one.cluster.name}.pkg.name"/>
648
        <resolve name="pkg.version" value="${one.cluster.name}.pkg.version"/>
649
        <resolve name="pkg.desc" value="${one.cluster.name}.pkg.desc"/>
650
        <resolve name="pkg.vendor" value="${one.cluster.name}.pkg.vendor"/>
651
        <resolve name="pkg.email" value="${one.cluster.name}.pkg.email"/>
652
        <resolve name="pkg.rpm.name" value="${one.cluster.name}.pkg.rpm.name"/>
653
        <resolve name="pkg.rpm.requires" value="${one.cluster.name}.pkg.rpm.requires"/>
654
        <resolve name="pkg.rpm.group" value="${one.cluster.name}.pkg.rpm.group"/>
655
        <resolve name="pkg.rpm.url" value="${one.cluster.name}.pkg.rpm.url"/>
656
        <resolve name="pkg.rpm.copyright" value="${one.cluster.name}.pkg.rpm.copyright"/>
657
        <resolve name="pkg.rpm.map" value="${one.cluster.name}.pkg.rpm.map"/>
658
        <resolve name="pkg.rpm.prefix" value="${one.cluster.name}.pkg.rpm.prefix"/>
659
        
660
        <echo file="${netbeans.build.dir}/rpms/${pkg.rpm.name}.spec">
661
            %define global_product_version ${pkg.version}
662
            %define global_product_release 00
663
            %define _prefix ${pkg.rpm.prefix}
664
            Version: %{global_product_version}
665
            Release: %{global_product_release}
666
            Group: ${pkg.rpm.group}
667
            Copyright: ${pkg.rpm.copyright}
668
            Vendor: ${pkg.vendor}
669
            URL: ${pkg.rpm.url}
670
            Prefix: %_prefix
671
            AutoReqProv: no
672
            Name: ${pkg.rpm.name}
673
            Summary: ${pkg.name}
674
            %description 
675
            ${pkg.desc}
676
            
677
            %files
678
            
679
            %erpm_map ${pkg.rpm.map} nb_destdir
680
            
681
            %dir ${pkg.rpm.map}
682
            
683
        ${pkg.rpm.map}/${one.cluster.dir}</echo>
684
    </target>
685
    
686
    <target name="create-svr4s-proto">
687
        <mkdir dir="${netbeans.build.dir}/rpms"/>
688
        <repeat target="create-one-svr4-proto" name="one.cluster.name" values="${clusters.list}" /> 
689
    </target>
690
    
691
    <target name="create-one-svr4-proto">
692
        <taskdef name="setcluster" classname="org.netbeans.nbbuild.SetCluster" classpath="nbantext.jar"/>
693
        <loadproperties srcFile="cluster.properties" />
694
        <loadproperties srcFile="cluster-description.properties" />
695
        <setcluster cluster="${one.cluster.name}" name="one.cluster.dir" />
696
        <mkdir dir="${netbeans.build.dir}/svr4s"/>
697
        
698
        <resolve name="pkg.name" value="${one.cluster.name}.pkg.name"/>
699
        <resolve name="pkg.version" value="${one.cluster.name}.pkg.version"/>
700
        <resolve name="pkg.desc" value="${one.cluster.name}.pkg.desc"/>
701
        <resolve name="pkg.vendor" value="${one.cluster.name}.pkg.vendor"/>
702
        <resolve name="pkg.email" value="${one.cluster.name}.pkg.email"/>
703
        <resolve name="pkg.svr4.pkg" value="${one.cluster.name}.pkg.svr4.pkg"/>
704
        <resolve name="pkg.svr4.maxinst" value="${one.cluster.name}.pkg.svr4.maxinst"/>
705
        <resolve name="pkg.svr4.sunw_pkgvers" value="${one.cluster.name}.pkg.svr4.sunw_pkgvers"/>
706
        <resolve name="pkg.svr4.hotline" value="${one.cluster.name}.pkg.svr4.hotline"/>
707
        <resolve name="pkg.svr4.classes" value="${one.cluster.name}.pkg.svr4.classes"/>
708
        <resolve name="pkg.svr4.basedir" value="${one.cluster.name}.pkg.svr4.basedir"/>
709
        <resolve name="pkg.svr4.pkginst" value="${one.cluster.name}.pkg.svr4.pkginst"/>
710
        <resolve name="pkg.svr4.category" value="${one.cluster.name}.pkg.svr4.category"/>
711
        <echo file="${netbeans.build.dir}/svr4s/${pkg.svr4.pkg}.spec">
712
            PKG=${pkg.svr4.pkg}
713
            NAME=${pkg.name}
714
            ARCH=sparc
715
            VERSION=${pkg.version}
716
            MAXINST=${pkg.svr4.maxinst}
717
            CATEGORY=${pkg.svr4.category}
718
            SUNW_PKGVERS=${pkg.svr4.sunw_pkgvers}
719
            DESC=${pkg.desc}
720
            VENDOR=${pkg.vendor}
721
            HOTLINE=${pkg.svr4.hotline}
722
            EMAIL=${pkg.email}
723
            CLASSES=${pkg.svr4.classes}
724
            BASEDIR=${pkg.svr4.basedir}
725
        PKGINST=${pkg.svr4.pkginst}</echo>
726
    </target>
727
    
728
    <target name="sanity-check" depends="testuserdir-delete,sanity-start" description="Test whether the build can start up without problems."/>
729
    <target name="-testuserdir-delete-init" depends="init">
730
        <property name="test.user.dir.lock" location="${test.user.dir}/lock"/>
731
        <available property="app.running" file="${test.user.dir.lock}"/>
732
    </target>
733
    <target name="-testuserdir-delete-ok" depends="-testuserdir-delete-init" unless="app.running">
734
        <delete dir="${test.user.dir}"/>
735
    </target>
736
    <target name="-testuserdir-delete-fail" depends="-testuserdir-delete-init" if="app.running">
737
        <!-- #66799: best to warn about this condition... -->
738
        <fail>Will not delete ${test.user.dir} because ${test.user.dir.lock} still exists; kill any running process and delete lock file if necessary</fail>
739
    </target>
740
    <target name="testuserdir-delete" depends="-testuserdir-delete-ok,-testuserdir-delete-fail"/>
741
    <target name="sanity-start" depends="init,maybe-build-nozip,-jdk-init">
742
        <mkdir dir="${test.user.dir}"/>
743
        <echo>Starting the IDE as a sanity check...</echo>
744
        <echo>WARNING - the sanity-start target is deprecated. Use commit-validation instead.</echo>
745
        <!-- XXX better would be to scan start log for stacktraces and just show those; -->
746
        <!-- possibly after filtering for duplicates or something like this. -->
747
        <!-- Timeout is ten minutes; should be enough for valid start, while preventing -->
748
        <!-- a deadlock from hanging an automated build: -->
749
        <exec os="Windows NT Windows 95 Windows 98 Windows 2000 Windows 2003 Windows XP" executable="${netbeans.dest.abs}/bin/nb.exe" failonerror="yes" timeout="600000">
750
            <arg value="--jdkhome"/>
751
            <arg file="${nbjdk.home}"/>
752
            <arg value="--userdir"/>
753
            <arg file="${test.user.dir}"/>
754
            <arg line="${sanitystart.args}"/>
755
        </exec>
756
        <exec os="Linux SunOS Solaris Mac OS X" dir="." executable="sh" failonerror="yes" timeout="600000">
757
            <arg value="${netbeans.dest.abs}/bin/netbeans"/>
758
            <arg value="--jdkhome"/>
759
            <arg file="${nbjdk.home}"/>
760
            <arg value="--userdir"/>
761
            <arg file="${test.user.dir}"/>
762
            <arg line="${sanitystart.args}"/>
763
        </exec>
764
        <echo>Finished starting the IDE, pay attention to any reported errors.</echo>
765
    </target>
766
    
767
    <target name="check-for-build"  >
768
        <available property="have-build" file="${netbeans.dest.dir}/bin/netbeans"/>
769
    </target>
770
    <target name="maybe-build-nozip" depends="check-for-build" unless="have-build">
771
        <ant dir="${basedir}" target="build-nozip"/>
772
    </target>
773
    
774
    <target name="nozip-check" 
775
            depends="build-nozip,sanity-check">
776
        <echo>WARNING - the nozip-check target is deprecated. Use all-nozip instead.</echo>
777
    </target>
778
    
779
    <target name="tryme-setup-debug-args" if="debug.port" >
780
        <property name="debug.pause" value="n" />
781
        <property name="debug.server" value="y" />
782
        
783
        <property name="tryme.debug.args" value="-J-Xdebug -J-Xnoagent -J-Xrunjdwp:transport=dt_socket,suspend=${debug.pause},server=${debug.server},address=${debug.port}" />
784
    </target>
785
    
786
    <target name="tryme-debug" depends="-jdk-presetdef-nbjpdastart" description="Start IDE in debugger. May only be called from within IDE.">
787
        <nbjpdastart name="NetBeans" addressproperty="debug.port" transport="dt_socket">
788
            <classpath>
789
                <fileset dir="${netbeans.dest.dir}">
790
                    <include name="**/*.jar"/>
791
                </fileset>
792
            </classpath>
793
        </nbjpdastart>
794
        <property name="debug.server" value="n"/>
795
        <antcall target="tryme"/>
796
    </target>
797
    
798
    <target name="tryme-profile" depends="-jdk-presetdef-nbprofiledirect" description="Start IDE in debugger. May only be called from within IDE.">
799
        <property name="profiler.roots.path" value="profiler.roots.all" />
800
        <fileset id="profiler.roots.all" dir="${netbeans.dest.dir}">
801
            <include name="**/*.jar"/>
802
        </fileset>
803
        <nbprofiledirect 
804
            jvmargsprefix="-J" 
805
            jvmargsproperty="profiler.jvmargs" 
806
            mainclass="org.netbeans.Main"
807
        >
808
            <classpath>
809
                <fileset dir="${netbeans.dest.dir}">
810
                    <include name="**/*.jar"/>
811
                </fileset>
812
            </classpath>
813
            <rootspath>
814
                <fileset refid="${profiler.roots.path}" />
815
            </rootspath>
816
        </nbprofiledirect>
817
        
818
        <antcall target="tryme">
819
            <param name="tryme.args" value="${profiler.jvmargs}"/>
820
        </antcall>
821
    </target>
822
    
823
    <target name="tryme" depends="init,maybe-build-nozip,tryme-setup-debug-args,-jdk-init"
824
            description="Try running the IDE interactively (build it first if needed).
825
            It is possible to use -Ddebug.port=3234 -Ddebug.pause=y to start the system in debug mode" 
826
    >
827
        <property name="tryme.debug.args" value="" />
828
        
829
        <exec os="Windows NT Windows 95 Windows 98 Windows 2000 Windows 2003 Windows XP" executable="${netbeans.dest.abs}/bin/nb.exe" failonerror="yes">
830
            <arg value="--jdkhome"/>
831
            <arg file="${nbjdk.home}"/>
832
            <arg value="--userdir"/>
833
            <arg file="${test.user.dir}"/>
834
            <arg line="${tryme.args}"/>
835
            <arg line="${tryme.debug.args}" />
836
        </exec>
837
        <exec os="Linux SunOS Solaris Mac OS X" dir="." executable="sh" failonerror="yes">
838
            <arg value="${netbeans.dest}/bin/netbeans"/>
839
            <arg value="--jdkhome"/>
840
            <arg file="${nbjdk.home}"/>
841
            <arg value="--userdir"/>
842
            <arg file="${test.user.dir}"/>
843
            <arg line="${tryme.args}"/>
844
            <arg line="${tryme.debug.args}" />
845
        </exec>
846
    </target>
847
    
848
    <target name="l10n-kit" depends="init">
849
        <taskdef name="l10n" classname="org.netbeans.nbbuild.L10nTask"
850
                 classpath="nbantext.jar"/>
851
        <delete dir="${l10n.dist.dir}"/>
852
        <mkdir dir="${l10n.dist.dir}"/>
853
        <delete dir="tmp"/>
854
        <mkdir dir="tmp"/>
855
        <property name="nbroot" location=".."/>
856
        <l10n topdirs="${nbroot}" modules="${fixedmodules},${modules}"
857
              localizablefile="l10n.list" generatedfile="l10n.list.translated"
858
              distdir="${l10n.dist.dir}" changedfile="l10n.list.changed"
859
              builddir="tmp" buildnumber="${buildnumber}"
860
              excludepattern="**/ja/,**/*_ja.*"/>
861
        <delete dir="tmp"/>
862
    </target>
863
    
864
    <target name="bootstrap-javadoc"
865
            depends="bootstrap"
866
            description="Generate Javadoc for Ant extensions.">
867
        <!-- XXX this ought to be deleted at some point. -->
868
        <!-- Can be done anyway by apisupport/ant, and published as regular module Javadoc -->
869
        <!-- by the regular daily Javadoc build process. -->
870
        <!-- Then all of this stuff can be deleted from the www part of CVS. -->
871
        <mkdir dir="www/nbantext-javadoc"/>
872
        <delete>
873
            <fileset dir="www/nbantext-javadoc">
874
                <include name="**/*.html"/>
875
            </fileset>
876
        </delete>
877
        <tstamp/>
878
        <javadoc sourcepath="antsrc"
879
                 destdir="www/nbantext-javadoc"
880
                 packagenames="org.netbeans.nbbuild.*"
881
                 windowtitle="NetBeans Ant Extensions"
882
                 doctitle="Extended Ant Tasks for Building NetBeans"
883
                 nodeprecatedlist="true"
884
                 notree="true"
885
                 noindex="true"
886
                 nohelp="true"
887
                 nonavbar="true"
888
                 author="false"
889
                 version="false"
890
                 bottom="Built on ${buildday}"
891
        >
892
            <classpath refid="bootstrap-cp"/>
893
            <link href="http://nagoya.apache.org/gump/javadoc/ant/build/javadocs" offline="true" packagelistloc="antsrc"/>
894
        </javadoc>
895
    </target>
896
    
897
    <target name="clean-external">
898
        <subant target="clean">
899
            <fileset dir="..">
900
                <include name="*/external/build.xml"/>
901
                <include name="contrib/*/external/build.xml"/>
902
            </fileset>
903
        </subant>
904
    </target>
905
    
906
    <target name="real-clean" depends="clean,clean-external"
907
            description="Clean everything possible.">
908
        <echo message="Cleaning old builds..."/>
909
        <delete>
910
            <fileset dir=".">
911
                <include name="NetBeans-*.log"/>
912
                <include name="NetBeans-*.zip"/>
913
            </fileset>
914
        </delete>
915
        <!-- This step must be last: -->
916
        <echo message="Cleaning NetBeans-specific Ant extensions..."/>
917
        <delete file="nbantext.jar" quiet="true"/>
918
        <delete dir="build/antclasses"/>
919
    </target>
920
    
921
    <target name="ant-clean">
922
        <delete file="nbantext.jar"/>
923
    </target>
924
    
925
    <target name="clean-cluster-flags" unless="do-not-rebuild-clusters">
926
        <mkdir dir="${netbeans.dest.dir}"/>
927
        <delete includeEmptyDirs="true">
928
            <fileset dir="${netbeans.dest.dir}">
929
                <include name="*.built"/>
930
            </fileset>
931
        </delete>
932
    </target>
933
    
934
    <target name="localclean" depends="clean-cluster-flags,init">
935
        <delete dir="${test.user.dir}"/>
936
        <delete dir="build"/>
937
        <delete file="moduledefs-tmp.properties"/>
938
        <delete dir="nbms" />
939
        <delete dir="${netbeans.dest.dir}"/>
940
    </target>
941
    
942
    <!-- more correct but takes too long: <target name="localtest" depends="bootstrap,all-xtest/nbjunit" > -->
943
    <target name="localtest" depends="bootstrap">
944
        <ant dir="test" target="cleanresults"/>
945
        <ant dir="test" target="runtests"/>
946
    </target>
947
    <target name="localtest-nb" depends="localtest">
948
        <nbbrowse file="test/results/index.html"/>
949
    </target>
950
    <target name="localtest-single-nb" depends="bootstrap">
951
        <property name="unit.test.base" location="test/unit/src"/>
952
        <pathconvert property="xtest.includes" pathsep=",">
953
            <path path="${includes}"/>
954
            <mapper type="glob" from="${unit.test.base}${file.separator}*.java" to="*.class"/>
955
        </pathconvert>
956
        <property name="xtest.attribs" value="empty"/>
957
        <ant dir="test" target="cleanresults"/>
958
        <ant dir="test" target="runtests"/>
959
        <nbbrowse file="test/results/index.html"/>
960
    </target>
961
    <target name="localtest-single-nb-debug" depends="bootstrap,-jdk-presetdef-nbjpdastart">
962
        <property name="unit.test.base" location="test/unit/src"/>
963
        <pathconvert property="xtest.includes" pathsep=",">
964
            <path path="${includes}"/>
965
            <mapper type="glob" from="${unit.test.base}${file.separator}*.java" to="*.class"/>
966
        </pathconvert>
967
        <property name="xtest.attribs" value="empty"/>
968
        <ant dir="test" target="cleanresults"/>
969
        <nbjpdastart transport="dt_socket" addressproperty="jpda.address" name="${test.class}">
970
            <classpath>
971
                <!--
972
            <path location="test/work/sys/tests/unit/classes"/>
973
            <path location="test/work/sys/tests/"/>
974
            <path location="test/unit/src/"/>
975
            -->
976
                <path location="nbantext.jar"/>
977
            </classpath>
978
        </nbjpdastart>
979
        <ant dir="test" target="runtests">
980
            <property name="xtest.debug.address" value="${jpda.address}" />
981
            <property name="xtest.debug.pause" value="false" />
982
        </ant>
983
        <nbbrowse file="test/results/index.html"/>
984
    </target>
985
    
986
    <target name="cleanall" depends="init">
987
        <cleanall topdir=".." 
988
                  modules="${allmodules}" 
989
                  targetname="clean"
990
                  resolvedependencies="${resolve.clean.dependencies}"
991
                  deptargetprefix="all-"
992
                  failonerror="${stop.when.clean.error}" />
993
    </target>
994
    
995
    <target name="clean" depends="init,cleanall,localclean"
996
            description="Clean out (almost) all build products.">
997
        <echo message="Run `ant real-clean' if desired."/>
998
    </target>
999
    
1000
    <!-- This section contains properties and targets used to build -->
1001
    <!-- Solaris packages.                                          -->
1002
1003
    <property name="solpkg-pkgproto" value="pkgproto"/>
1004
    <property name="solpkg-pkgmk" value="pkgmk"/>
1005
    <property name="solpkg-proto-file" value="prototype"/>
1006
    <property name="solpkg-actual-dir" value="to-be-specified"/>
1007
    <property name="solpkg-pkg-dir" value="to-be-specified"/>
1008
    <property name="solpkg-pkg-dest-dir" value="to-be-specified"/>
1009
    
1010
    <!-- You can run this target to create the prototype file and create -->
1011
    <!-- the package, or if you need to modify the prototype file before -->
1012
    <!-- building the package, you can run the two subtargets            -->
1013
    <!-- separately.                                                     -->
1014
    <target name="solpkg-build" depends="solpkg-pkgproto,solpkg-pkgmk"
1015
            description="Generate a prototype file and create a Solaris package."/>
1016
    
1017
    <!-- This creates the pkg prototype file for a given directory and -->
1018
    <!-- its files.                                                    -->
1019
    <target name="solpkg-pkgproto"
1020
            description="Generate a prototype file.">
1021
        <exec executable="rm" failonerror="yes">
1022
            <arg value="-rf"/>
1023
            <arg value="${solpkg-proto-file}"/>
1024
        </exec>
1025
        <exec executable="${solpkg-pkgproto}" output="${solpkg-proto-file}" 
1026
              failonerror="yes">
1027
            <arg value="${solpkg-actual-dir}=${solpkg-pkg-dir}"/>
1028
        </exec>
1029
    </target>
1030
    
1031
    <!-- This creates the Solaris pkg for a given prototype file, pkginfo -->
1032
    <!-- file, and directory.                                             -->
1033
    <target name="solpkg-pkgmk"
1034
            description="Create a Solaris package.">
1035
        <exec executable="${solpkg-pkgmk}" failonerror="yes">
1036
            <arg value="-o"/>
1037
            <arg value="-f"/>
1038
            <arg value="${solpkg-proto-file}"/>
1039
            <arg value="-r"/>
1040
            <arg value="${solpkg-actual-dir}"/>
1041
            <arg value="-d"/>
1042
            <arg value="${solpkg-pkg-dest-dir}"/>
1043
        </exec>
1044
    </target>
1045
    
1046
    <!-- End of Solaris package section. -->
1047
1048
    
1049
    <!-- Localized builds -->
1050
    <target name="all-dutch" depends="set-dutch-locale,all"/>
1051
    <target name="all-russian" depends="set-russian-locale,all"/>
1052
    <target name="all-french" depends="set-french-locale,all"/>
1053
    <target name="all-ja-zh" depends="set-ja-zh_CN-locales,all"/>
1054
    
1055
    <target name="set-ja-zh_CN-locales">
1056
        <property name="locales" value="ja,zh_CN"/>
1057
        <property name="locjar.locales" value="${locales}"/>
1058
        <property name="locmakenbm.locales"   value="${locales}"/>
1059
        <property name="locjhindexer.locales" value="${locales}"/>
1060
        <property name="localized.build.locales" value="${locales}"/>
1061
    </target>
1062
    
1063
    <target name="set-dutch-locale">
1064
        <property name="locales" value="nl"/>
1065
        <property name="locjar.locales" value="${locales}"/>
1066
        <property name="locmakenbm.locales"   value="${locales}"/>
1067
        <property name="locjhindexer.locales" value="${locales}"/>
1068
        <property name="localized.build.locales" value="${locales}"/>
1069
    </target>
1070
    
1071
    <target name="set-russian-locale">
1072
        <property name="locales" value="ru"/>
1073
        <property name="locjar.locales" value="${locales}"/>
1074
        <property name="locmakenbm.locales"   value="${locales}"/>
1075
        <property name="locjhindexer.locales" value="${locales}"/>
1076
        <property name="localized.build.locales" value="${locales}"/>
1077
    </target>
1078
    
1079
    <target name="set-french-locale">
1080
        <property name="locales" value="fr"/>
1081
        <property name="locjar.locales" value="${locales}"/>
1082
        <property name="locmakenbm.locales"   value="${locales}"/>
1083
        <property name="locjhindexer.locales" value="${locales}"/>
1084
        <property name="localized.build.locales" value="${locales}"/>
1085
    </target>
1086
    
1087
    <!-- end of localized builds -->
1088
1089
1090
    <target name="print-selected-modules" depends="init" description="Prints list of modules to build in selected moduleconfig.">
1091
        <echo message="modules=${allmodules}"/>
1092
    </target>
1093
    
1094
    <target name="print-cvs-modules" depends="init" description="Prints list of cvs modules required to build in selected moduleconfig.">
1095
        <taskdef name="printcvsmodules" classname="org.netbeans.nbbuild.PrintCvsModules" classpath="nbantext.jar"/>
1096
        <printcvsmodules modules="${fixedmodules},${modules}" targetprefix="all-" />
1097
    </target>
1098
    
1099
    <target name="check-commit-validation">
1100
        <condition property="run.validation" >
1101
            <and>
1102
                <available file="../ide/test/build.xml" />
1103
                <available file="../jemmy/build.xml" />
1104
                <available file="../jellytools/build.xml" />
1105
                <available file="../xtest/build.xml" />
1106
                <or>
1107
                    <not>
1108
                        <isset property="nb.run.validation"/>
1109
                    </not>
1110
                    <istrue value="${nb.run.validation}"/>
1111
                </or>
1112
            </and>
1113
        </condition>
1114
    </target>
1115
    
1116
    <target 
1117
        name="unit-validation" 
1118
        description="Invokes all existing unit tests in all IDE modules.
1119
        Useful when one wants to deeply verify that his changes
1120
        work"
1121
    >
1122
        <ant dir="../xtest/instance" target="runtests" >
1123
            <property name="xtest.config" value="unit-nb" />
1124
        </ant>
1125
    </target>
1126
    
1127
    <target 
1128
        name="commit-validation" 
1129
        depends="commit-verification,commitValidation,no-commit-validation" 
1130
        description="Runs tests to validate IDE before commit."
1131
    />
1132
    
1133
    <target name="all-commitValidation" description="dummy target for build error recognition facility"/>
1134
    
1135
    <target 
1136
        name="commit-verification" 
1137
        description="Compares result of a build with golden files verifying various aspects of the exported interfaces"
1138
        depends="
1139
        all-verification,
1140
        check-files-layout,
1141
        check-public-packages,
1142
        check-friend-packages,
1143
        check-shared-packages,
1144
        check-modules,
1145
        check-dependencies,
1146
        check-implementation-dependencies,
1147
        check-cluster-dependencies,
1148
        check-cluster-implementation-dependencies,
1149
        check-clusters-content"
1150
    />
1151
    
1152
    <!-- JST: One day also add 
1153
    check-external-libraries
1154
  -->
1155
  
1156
    <target name="all-verification" >
1157
        <echo message="Runs verification tests to check the IDE before commit" />
1158
    </target>
1159
    
1160
    <!-- keep this target name at least for a while for backward compat -jglick -->
1161
    <target name="commitValidation" depends="all-commitValidation,check-commit-validation" if="run.validation">
1162
        <property name="xtest.home" location="../xtest"/>
1163
        <ant dir="${xtest.home}/instance" target="cleanresults">
1164
            <property name="xtest.config" value="commit-validation-nb"/>
1165
        </ant>
1166
        <ant dir="${xtest.home}/instance" target="cleantests">
1167
            <property name="xtest.config" value="commit-validation-nb"/>
1168
        </ant>
1169
        <ant dir="${xtest.home}/instance" target="runtests">
1170
            <property name="xtest.config" value="commit-validation-nb"/>
1171
            <property name="xtest.fail.on.failure" value="true"/>
1172
        </ant>
1173
    </target>
1174
    
1175
    <target name="no-commit-validation" depends="check-commit-validation" unless="run.validation">
1176
        <echo>
1177
            *** WARNING ***
1178
            You do not seem to have the modules needed to run the commit validation test suite. 
1179
            You may not commit any changes into the CVS repository without running these tests.
1180
            For more information: http://www.netbeans.org/community/guidelines/commit.html
1181
        </echo>
1182
    </target>
1183
    
1184
    <target name="sanity-build-from-source-pkg" depends="build-source">
1185
        <available file="${netbeans.build.dir}/${cluster.name}-src-${buildnum}.zip"
1186
                   property="pkg.available"/>
1187
        <fail message="Source package ${netbeans.build.dir}/${cluster.name}-src-${buildnum}.zip not available" unless="pkg.available"/>
1188
        <delete dir="testbuild"/>
1189
        <mkdir dir="testbuild"/>
1190
        <unzip dest="testbuild" src="${netbeans.build.dir}/${cluster.name}-src-${buildnum}.zip"/>
1191
        <property name="one.cluster.name" value="${cluster.name}"/>
1192
        <propertyset id="sanity-build">
1193
            <propertyref name="one.cluster.name"/>
1194
        </propertyset>
1195
        <echoproperties destfile="testbuild/nbbuild/user.properties">
1196
            <propertyset refid="sanity-build"/>
1197
        </echoproperties>
1198
        
1199
        <!-- it should call build of the refered cluster and not just hardcoded platform -->
1200
        <ant antfile="testbuild/nbbuild/build.xml" inheritall="false" target="build-one-cluster">
1201
            <property file="testbuild/nbbuild/user.properties"/>
1202
        </ant>
1203
        <delete dir="testbuild"/>
1204
    </target>
1205
    
1206
    <target name="build-source"
1207
            depends="init,set-buildnumber"
1208
            description="Packages sources needed to compile given by cluster.name (can be specified by -Dcluster.name=nb.cluster.platform"
1209
            if="cluster.name"
1210
    >
1211
        <property name="buildnum" value="dev-${buildnumber}"/>
1212
        <echo message="Packaging sources of ${cluster.name} modules"/>
1213
        <resolve name="cluster-modules" value="${cluster.name}"/>
1214
        <resolve name="harness-modules" value="nb.cluster.harness"/>
1215
        <mkdir dir="${netbeans.build.dir}"/>
1216
        <taskdef name="definefileset" classname="org.netbeans.nbbuild.PrintCvsModules" classpath="nbantext.jar"/>
1217
        <definefileset modules="${cluster-modules}" targetprefix="all-" id="source-modules" dir=".." />
1218
        <definefileset modules="${cluster-modules}" targetprefix="all-" id="external-modules" dir=".." mode="binaries" />
1219
        <definefileset modules="${harness-modules}" targetprefix="all-" id="harness-source-modules" dir=".." />
1220
        <definefileset modules="${harness-modules}" targetprefix="all-" id="harness-external-modules" dir=".." mode="binaries" />
1221
        <zip zipfile="${netbeans.build.dir}/${cluster.name}-src-${buildnum}.zip" duplicate="preserve">
1222
            <fileset refid="source-modules" />
1223
            <fileset refid="external-modules" />
1224
            <fileset refid="harness-source-modules" />
1225
            <fileset refid="harness-external-modules" />
1226
        </zip>
1227
    </target>
1228
    
1229
    <target name="generate-golden-files-init" depends="init,bootstrap" >
1230
        <property name="template.files.dir" location="build/golden" />
1231
        <property name="golden.files.dir" location="../ide/golden" />
1232
        <condition property="golden.files.eol" value="unix" >
1233
            <or>
1234
                <os family="unix" />
1235
                <os family="mac" />
1236
            </or>
1237
        </condition>
1238
        <property name="golden.files.eol" value="dos" />
1239
        
1240
        <mkdir dir="${template.files.dir}" />
1241
        
1242
        <!-- convert the golden files into platform default encoding -->
1243
        <fixcrlf srcdir="${golden.files.dir}" destdir="${template.files.dir}" eol="${golden.files.eol}" >
1244
            <include name="*txt" />
1245
        </fixcrlf>
1246
        
1247
    </target>
1248
    
1249
    
1250
    <target name="generate-golden-files" depends="generate-golden-files-init" >
1251
        <property name="generated.files.dir" location="build/generated" />
1252
        <mkdir dir="${generated.files.dir}" />
1253
        
1254
        <taskdef name="deps" classname="org.netbeans.nbbuild.ModuleDependencies" classpath="nbantext.jar"/>
1255
        
1256
        <deps>
1257
            <input name="platform" >
1258
                <jars dir="${netbeans.dest.dir}" >
1259
                    <include name="${nb.cluster.platform.dir}/**/*.jar" />
1260
                </jars>
1261
            </input>
1262
            <input name="ide" >
1263
                <jars dir="${netbeans.dest.dir}" >
1264
                    <include name="${nb.cluster.ide.dir}/**/*.jar" />
1265
                </jars>
1266
            </input>
1267
            <input name="j2ee" >
1268
                <jars dir="${netbeans.dest.dir}" >
1269
                    <include name="${nb.cluster.j2ee.dir}/**/*.jar" />
1270
                </jars>
1271
            </input>
1272
            <input name="nb" >
1273
                <jars dir="${netbeans.dest.dir}" >
1274
                    <include name="${nb.cluster.nb.dir}/**/*.jar" />
1275
                </jars>
1276
            </input>
1277
            <input name="harness" >
1278
                <jars dir="${netbeans.dest.dir}" >
1279
                    <include name="${nb.cluster.harness.dir}/**/*.jar" />
1280
                </jars>
1281
            </input>
1282
            
1283
            <output type="group-dependencies" file="${generated.files.dir}/cluster-deps.txt" />
1284
            <output type="group-implementation-dependencies" file="${generated.files.dir}/cluster-impl-deps.txt" />
1285
            <output type="modules" file="${generated.files.dir}/modules.txt" />
1286
            <output type="dependencies" file="${generated.files.dir}/deps.txt" />
1287
            <output type="implementation-dependencies" file="${generated.files.dir}/impl-deps.txt" />
1288
            <output type="public-packages" file="${generated.files.dir}/public-packages.txt" />
1289
            <output type="shared-packages" file="${generated.files.dir}/shared-packages.txt" />
1290
            <output type="friend-packages" file="${generated.files.dir}/friend-packages.txt" />
1291
            <output type="external-libraries" file="${generated.files.dir}/external-libraries.txt" />
1292
        </deps>
1293
    </target>
1294
    
1295
    <target name="check-public-packages" depends="generate-golden-files" >
1296
        <property name="check.public.packages.golden" location="${golden.files.dir}/public-packages.txt" />
1297
        <property name="check.public.packages.template" location="${template.files.dir}/public-packages.txt" />
1298
        <property name="check.public.packages.generated" location="${generated.files.dir}/public-packages.txt" />
1299
        
1300
        <condition property="check-public-packages-are-they-the-same" >
1301
            <filesmatch file1="${check.public.packages.template}" file2="${check.public.packages.generated}" />
1302
        </condition>
1303
        
1304
        
1305
        <exec os="Linux SunOS Solaris " dir="." executable="diff" failonerror="no" timeout="60000" >
1306
            <arg value="-U"/>
1307
            <arg value="15"/>
1308
            <arg value="${check.public.packages.template}" />
1309
            <arg value="${check.public.packages.generated}" />
1310
        </exec>
1311
        
1312
        <fail unless="check-public-packages-are-they-the-same" >!
1313
            *** Public packages has changed! ***
1314
            
1315
            Differences were found while comparing file 
1316
            ${check.public.packages.template}
1317
            with 
1318
            ${check.public.packages.generated}
1319
            
1320
            This means that the set of public packages changed since the previously known one.
1321
            Some packages may have been added, some of them may have been removed 
1322
            Either by changing manifest of a module or by adding or removing a class file
1323
            from a module package.
1324
            
1325
            
1326
            Changing the packages may or may not be ok. It means that an api of 
1327
            whole product changes and as such it is subject to review. If you passed
1328
            your review and want to change the list of public packages, then please
1329
            update the golden file at 
1330
            ${check.public.packages.golden}
1331
            and run the test once again. 
1332
            
1333
            Read more about the Verification Framework:
1334
            http://openide.netbeans.org/proposals/arch/clusters.html#verify
1335
            
1336
            Look at for information about reviews:
1337
            http://openide.netbeans.org/tutorial/review-steps.html
1338
            
1339
            Check the page about APIs:
1340
            http://openide.netbeans.org/tutorial/api-design.html#api
1341
        </fail>
1342
    </target>
1343
    
1344
    <target name="check-friend-packages" depends="generate-golden-files" >
1345
        <property name="check.friend.packages.golden" location="${golden.files.dir}/friend-packages.txt" />
1346
        <property name="check.friend.packages.template" location="${template.files.dir}/friend-packages.txt" />
1347
        <property name="check.friend.packages.generated" location="${generated.files.dir}/friend-packages.txt" />
1348
        
1349
        <condition property="check-friend-packages-are-they-the-same" >
1350
            <filesmatch file1="${check.friend.packages.template}" file2="${check.friend.packages.generated}" />
1351
        </condition>
1352
        
1353
        
1354
        <exec os="Linux SunOS Solaris " dir="." executable="diff" failonerror="no" timeout="60000" >
1355
            <arg value="-U"/>
1356
            <arg value="15"/>
1357
            <arg value="${check.friend.packages.template}" />
1358
            <arg value="${check.friend.packages.generated}" />
1359
        </exec>
1360
        
1361
        <fail unless="check-friend-packages-are-they-the-same" >!
1362
            *** Friend packages has changed! ***
1363
            
1364
            Differences were found while comparing file 
1365
            ${check.friend.packages.template}
1366
            with 
1367
            ${check.friend.packages.generated}
1368
            
1369
            This means that the set of friend packages changed since the previously known one.
1370
            Some packages may have been added, some of them may have been removed 
1371
            Either by changing manifest of a module or by adding or removing a class file
1372
            from a module package.
1373
            
1374
            
1375
            Changing the packages may or may not be ok. It means that an api of 
1376
            whole product changes and as such it is subject to review. If you passed
1377
            your review and want to change the list of friend packages, then please
1378
            update the golden file at 
1379
            ${check.friend.packages.golden}
1380
            and run the test once again. 
1381
            
1382
            Read more about the Verification Framework:
1383
            http://openide.netbeans.org/proposals/arch/clusters.html#verify
1384
            
1385
            Look at for information about reviews:
1386
            http://openide.netbeans.org/tutorial/review-steps.html
1387
            
1388
            Check the page about APIs:
1389
            http://openide.netbeans.org/tutorial/api-design.html#api
1390
        </fail>
1391
    </target>
1392
    
1393
    <target name="check-shared-packages" depends="generate-golden-files,-jdk-init" unless="have-jdk-1.5" >
1394
        <property name="check.shared.packages.golden" location="${golden.files.dir}/shared-packages.txt" />
1395
        <property name="check.shared.packages.template" location="${template.files.dir}/shared-packages.txt" />
1396
        <property name="check.shared.packages.generated" location="${generated.files.dir}/shared-packages.txt" />
1397
        
1398
        <condition property="check-shared-packages-are-they-the-same" >
1399
            <filesmatch file1="${check.shared.packages.template}" file2="${check.shared.packages.generated}" />
1400
        </condition>
1401
        
1402
        
1403
        <exec os="Linux SunOS Solaris Mac OS X" dir="." executable="diff" failonerror="no" timeout="60000" >
1404
            <arg value="-U"/>
1405
            <arg value="15"/>
1406
            <arg value="${check.shared.packages.template}" />
1407
            <arg value="${check.shared.packages.generated}" />
1408
        </exec>
1409
        
1410
        <fail unless="check-shared-packages-are-they-the-same" >!
1411
            *** Shared packages has changed! ***
1412
            
1413
            Differences were found while comparing file 
1414
            ${check.shared.packages.template}
1415
            with 
1416
            ${check.shared.packages.generated}
1417
            
1418
            This means that the set of shared packages changed since the previously known one.
1419
            Some packages may have been added, some of them may have been removed 
1420
            Either by changing manifest of a module or by adding or removing a class file
1421
            from a module package.
1422
            
1423
            
1424
            Removing shared packages is ok. Adding shared packages is silly, complicates
1425
            and slows down module system and startup of the application. Do not do that!
1426
            If you are removing a shared package please update 
1427
            ${check.shared.packages.golden}
1428
            and run the test once again. 
1429
            
1430
            Read more about the Verification Framework:
1431
            http://openide.netbeans.org/proposals/arch/clusters.html#verify
1432
            
1433
            Look at for information about reviews:
1434
            http://openide.netbeans.org/tutorial/review-steps.html
1435
            
1436
            Check the page about APIs:
1437
            http://openide.netbeans.org/tutorial/api-design.html#api
1438
        </fail>
1439
    </target>
1440
    
1441
    <target name="check-external-libraries" depends="generate-golden-files" >
1442
        <property name="check.external.libraries.golden" location="${golden.files.dir}/external-libraries.txt" />
1443
        <property name="check.external.libraries.template" location="${template.files.dir}/external-libraries.txt" />
1444
        <property name="check.external.libraries.generated" location="${generated.files.dir}/external-libraries.txt" />
1445
        
1446
        <condition property="check-external-libraries-are-they-the-same" >
1447
            <filesmatch file1="${check.external.libraries.template}" file2="${check.external.libraries.generated}" />
1448
        </condition>
1449
        
1450
        
1451
        <exec os="Linux SunOS Solaris Mac OS X" dir="." executable="diff" failonerror="no" timeout="60000" >
1452
            <arg value="-U"/>
1453
            <arg value="15"/>
1454
            <arg value="${check.external.libraries.template}" />
1455
            <arg value="${check.external.libraries.generated}" />
1456
        </exec>
1457
        
1458
        <fail unless="check-external-libraries-are-they-the-same" >!
1459
            *** List of external libraries has changed! ***
1460
            
1461
            Differences were found while comparing file 
1462
            ${check.external.libraries.template}
1463
            with 
1464
            ${check.external.libraries.generated}
1465
            
1466
            This means that the set of external libraries (JARs that are not NetBeans
1467
            modules or does not have NetBeans-Own-Library: true in manifest) has 
1468
            changed since the previously known one. Some libraries may have been added, 
1469
            some of them may have been removed, they MD5 checksum or size has been changed.
1470
            
1471
            Changing the external libraries is ok, but requires legal approval everytime
1472
            new version of a library is put into the product. If you have the approval
1473
            want to change the list of external libraries, then please
1474
            update the golden file at 
1475
            ${check.external.libraries.golden}
1476
            and run the test once again. 
1477
            
1478
            Read more about the Verification Framework:
1479
            http://openide.netbeans.org/proposals/arch/clusters.html#verify
1480
            
1481
            Look at for information about reviews:
1482
            http://openide.netbeans.org/tutorial/review-steps.html
1483
            
1484
            Check the page about APIs:
1485
            http://openide.netbeans.org/tutorial/api-design.html#api
1486
        </fail>
1487
    </target>
1488
    
1489
    <target name="check-modules" depends="generate-golden-files" >
1490
        <property name="check.modules.golden" location="${golden.files.dir}/modules.txt" />
1491
        <property name="check.modules.template" location="${template.files.dir}/modules.txt" />
1492
        <property name="check.modules.generated" location="${generated.files.dir}/modules.txt" />
1493
        
1494
        <condition property="check-modules-are-they-the-same" >
1495
            <filesmatch file1="${check.modules.template}" file2="${check.modules.generated}" />
1496
        </condition>
1497
        
1498
        
1499
        <exec os="Linux SunOS Solaris Mac OS X" dir="." executable="diff" failonerror="no" timeout="60000" >
1500
            <arg value="-U"/>
1501
            <arg value="15"/>
1502
            <arg value="${check.modules.template}" />
1503
            <arg value="${check.modules.generated}" />
1504
        </exec>
1505
        
1506
        <fail unless="check-modules-are-they-the-same" >!
1507
            *** List of modules has changed! ***
1508
            
1509
            Differences were found while comparing file 
1510
            ${check.modules.template}
1511
            with 
1512
            ${check.modules.generated}
1513
            
1514
            This means that the set of modules changed since the previously known one.
1515
            Adding or removing a module significatly affects the set of APIs the
1516
            product offers and as such is subject to review. If you passed
1517
            your review and want to change the list of modules, then please
1518
            update the golden file at 
1519
            ${check.modules.golden}
1520
            and run the test once again. 
1521
            
1522
            Read more about the Verification Framework:
1523
            http://openide.netbeans.org/proposals/arch/clusters.html#verify
1524
            
1525
            Look at for information about reviews:
1526
            http://openide.netbeans.org/tutorial/review-steps.html
1527
            
1528
            Check the page about APIs:
1529
            http://openide.netbeans.org/tutorial/api-design.html#api
1530
        </fail>
1531
    </target>
1532
    
1533
    <target name="check-dependencies" depends="generate-golden-files" >
1534
        <antcall target="check-dependencies-subroutine" >
1535
            <param name="check.dependencies.golden" location="${golden.files.dir}/deps.txt" />
1536
            <param name="check.dependencies.template" location="${template.files.dir}/deps.txt" />
1537
            <param name="check.dependencies.generated" location="${generated.files.dir}/deps.txt" />
1538
        </antcall>
1539
    </target>
1540
    
1541
    <target name="check-implementation-dependencies" depends="generate-golden-files" >
1542
        <antcall target="check-dependencies-subroutine" >
1543
            <param name="check.dependencies.golden" location="${golden.files.dir}/impl-deps.txt" />
1544
            <param name="check.dependencies.template" location="${template.files.dir}/impl-deps.txt" />
1545
            <param name="check.dependencies.generated" location="${generated.files.dir}/impl-deps.txt" />
1546
        </antcall>
1547
    </target>
1548
    
1549
    <target name="check-cluster-dependencies" depends="generate-golden-files" >
1550
        <antcall target="check-dependencies-subroutine" >
1551
            <param name="check.dependencies.golden" location="${golden.files.dir}/cluster-deps.txt" />
1552
            <param name="check.dependencies.template" location="${template.files.dir}/cluster-deps.txt" />
1553
            <param name="check.dependencies.generated" location="${generated.files.dir}/cluster-deps.txt" />
1554
        </antcall>
1555
    </target>
1556
    
1557
    <target name="check-cluster-implementation-dependencies" depends="generate-golden-files" >
1558
        <antcall target="check-dependencies-subroutine" >
1559
            <param name="check.dependencies.golden" location="${golden.files.dir}/cluster-impl-deps.txt" />
1560
            <param name="check.dependencies.template" location="${template.files.dir}/cluster-impl-deps.txt" />
1561
            <param name="check.dependencies.generated" location="${generated.files.dir}/cluster-impl-deps.txt" />
1562
        </antcall>
1563
    </target>
1564
    
1565
    <target name="check-dependencies-subroutine" >
1566
        <condition property="check-dependencies-are-they-the-same" >
1567
            <filesmatch file1="${check.dependencies.template}" file2="${check.dependencies.generated}" />
1568
        </condition>
1569
        
1570
        
1571
        <exec os="Linux SunOS Solaris Mac OS X" dir="." executable="diff" failonerror="no" timeout="60000" >
1572
            <arg value="-U"/>
1573
            <arg value="15"/>
1574
            <arg value="${check.dependencies.template}" />
1575
            <arg value="${check.dependencies.generated}" />
1576
        </exec>
1577
        
1578
        <fail unless="check-dependencies-are-they-the-same" >!
1579
            *** List of dependencies has changed! ***
1580
            
1581
            Differences were found while comparing file 
1582
            ${check.dependencies.template}
1583
            with 
1584
            ${check.dependencies.generated}
1585
            
1586
            This means that the set of dependencies changed since the previously known one.
1587
            Adding a dependency can restrict the ways how a final product can be assembled
1588
            and as such it forms an important aspect of API and is subject to review. 
1589
            If you passed your review or you are sure you want to change the 
1590
            list of dependencies, then please update the golden file at 
1591
            ${check.dependencies.golden}
1592
            and run the test once again. 
1593
            
1594
            Read more about the Verification Framework:
1595
            http://openide.netbeans.org/proposals/arch/clusters.html#verify
1596
            
1597
            Look at for information about reviews:
1598
            http://openide.netbeans.org/tutorial/review-steps.html
1599
            
1600
            Check the page about APIs and dependencies being important:
1601
            http://openide.netbeans.org/tutorial/api-design.html#api
1602
        </fail>
1603
    </target>
1604
    
1605
    
1606
    <target name="generate-files-layout" depends="generate-golden-files-init" >
1607
        <property name="generated.files.dir" location="build/generated" />
1608
        <mkdir dir="${generated.files.dir}" />
1609
        
1610
        <property name="check.files.layout.golden" location="${golden.files.dir}/files-layout.txt" />
1611
        <property name="check.files.layout.template" location="${template.files.dir}/files-layout.txt" />
1612
        <property name="check.files.layout.generated" location="${generated.files.dir}/files-layout.txt" />
1613
        
1614
        <property name="check-file-layout-root" location="${netbeans.dest.dir}" />
1615
        <fileset id="check-file-layout" dir="${check-file-layout-root}" casesensitive="yes" >
1616
            <include name="platform*/**" />
1617
            <include name="ide*/**" />
1618
            <include name="enterprise*/**" />
1619
            <include name="nb*/**" />
1620
            <include name="harness*/**" />
1621
        </fileset>
1622
        
1623
        <pathconvert property="check-file-layout" refid="check-file-layout" dirsep="/" pathsep="," >
1624
            <map from="${check-file-layout-root}${file.separator}" to="" />
1625
        </pathconvert>
1626
        <mkdir dir="build/generated" />
1627
        <echo message="${check-file-layout}${line.separator}" file="${check.files.layout.generated}" />
1628
        <replace file="${check.files.layout.generated}" token="," value="${line.separator}" />
1629
        <replace file="${check.files.layout.generated}" token="\" value="/" />
1630
        <condition property="check-files-are-they-the-same" >
1631
            <filesmatch file1="${check.files.layout.template}" file2="${check.files.layout.generated}" />
1632
        </condition>
1633
        
1634
        
1635
    </target>
1636
    
1637
    
1638
    <target name="check-files-layout" depends="generate-files-layout" >
1639
        <exec os="Linux SunOS Solaris Mac OS X" dir="." executable="diff" failonerror="no" timeout="60000" >
1640
            <arg value="-U"/>
1641
            <arg value="15"/>
1642
            <arg value="${check.files.layout.template}" />
1643
            <arg value="${check.files.layout.generated}" />
1644
        </exec>
1645
        
1646
        <fail unless="check-files-are-they-the-same" >!
1647
            *** Layout of files has changed! ***
1648
            
1649
            Differences were found while comparing file ${check.files.layout.generated} with 
1650
            ${check.files.layout.template}
1651
            This means that the layout of files changed since the previously known one.
1652
            Some files may have been added, some of them may have been removed or renamed. 
1653
            
1654
            Changing the layout may or may not be ok. If you are sure that you want to
1655
            change the layout of files, then update the golden file at 
1656
            ${check.files.layout.golden}
1657
            and run the test once again. If you got this warning without intending
1658
            to change the layout of files, think twice whether your commit is really
1659
            correct and consider asking for a review first.
1660
            
1661
            Read more about the Verification Framework:
1662
            http://openide.netbeans.org/proposals/arch/clusters.html#verify
1663
            
1664
            Look at for information about reviews:
1665
            http://openide.netbeans.org/tutorial/review-steps.html
1666
            
1667
            Check the page about APIs and files layout being an API:
1668
            http://openide.netbeans.org/tutorial/api-design.html#api
1669
        </fail>
1670
    </target>
1671
    
1672
    <target name="check-clusters-content" depends="bootstrap,init-tasks"> 
1673
        <taskdef name="checkcontent" classname="org.netbeans.nbbuild.CheckClustersContent" classpath="nbantext.jar"/>
1674
        <checkcontent clusters="${nb.clusters.list}" trackingPath="${netbeans.dest.dir}" kitDestDir="${netbeans.dest.dir}">
1675
            <exclude name="extra/**"/>
1676
            <exclude name="testtools/**"/>
1677
            <exclude name="bin/**"/>
1678
            <exclude name="README.html"/>
1679
            <exclude name="CREDITS.html"/>
1680
            <exclude name="LICENSE.txt"/>
1681
            <exclude name="DISTRIBUTION.txt"/>
1682
            <exclude name="THIRDPARTYLICENSE.txt"/>
1683
            <exclude name="nb.cluster.*"/>
1684
            <exclude name="etc/netbeans.conf"/>
1685
            <exclude name="build_info"/>
1686
            <exclude name="module_tracking.xml"/>
1687
            <exclude name="moduleCluster.properties"/>
1688
            <exclude name="netbeans.css"/>
1689
        </checkcontent>
1690
    </target>
1691
    
1692
    <target name="check-module-configs" depends="bootstrap" description="Sanity-check build.properties and cluster.properties.">
1693
        <taskdef name="checkmoduleconfigs" classname="org.netbeans.nbbuild.CheckModuleConfigs" classpath="nbantext.jar"/>
1694
        <checkmoduleconfigs nbroot=".."/>
1695
    </target>
1696
    
1697
    <target name="display-l10n-list-matches" description="Show which files are actually matched by an l10n.list in some module.">
1698
        <property name="nbroot" location=".."/>
1699
        <input addproperty="module">Select a top-level module (e.g. "java") to display results for:</input>
1700
        <property name="listfile" location="${nbroot}/${module}/l10n.list"/>
1701
        <echo>${listfile}:1: Matches follow... (click on hyperlinks from IDE!)</echo>
1702
        <echo>(warning: 'exclude' directives not honored here yet)</echo><!-- XXX use filtersets or something to fix -->
1703
        <apply parallel="false" executable="sh">
1704
            <arg value="-c"/>
1705
            <arg value="echo $0:1"/>
1706
            <fileset dir="${nbroot}" includesfile="${listfile}"/>
1707
        </apply>
1708
    </target>
1709
    
1710
    <target name="increment-spec-versions" depends="bootstrap,init-module-list" description="Increment all standard module specification versions. Pass -Dbranch=true if not on the trunk.">
1711
        <property name="branch" value="false"/>
1712
        <taskdef name="incrspecvers" classname="org.netbeans.nbbuild.IncrementSpecificationVersions" classpath="nbantext.jar"/>
1713
        <incrspecvers nbroot=".." modules="${allmodules}" branch="${branch}"/>
1714
    </target>
1715
    
1716
</project>
(-)a/xml.text.obsolete90/test/unit/data/goldenfiles/org/netbeans/modules/xml/text/indent/XMLFormatterTest/testReformatSample2.pass (+1739 lines)
Line 0 Link Here
1
<?xml version="1.0" encoding="UTF-8"?>
2
<!--
3
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4
5
Copyright 1997-2009 Sun Microsystems, Inc. All rights reserved.
6
7
8
The contents of this file are subject to the terms of either the GNU
9
General Public License Version 2 only ("GPL") or the Common
10
Development and Distribution License("CDDL") (collectively, the
11
"License"). You may not use this file except in compliance with the
12
License. You can obtain a copy of the License at
13
http://www.netbeans.org/cddl-gplv2.html
14
or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
15
specific language governing permissions and limitations under the
16
License.  When distributing the software, include this License Header
17
Notice in each file and include the License file at
18
nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
19
particular file as subject to the "Classpath" exception as provided
20
by Sun in the GPL Version 2 section of the License file that
21
accompanied this code. If applicable, add the following below the
22
License Header, with the fields enclosed by brackets [] replaced by
23
your own identifying information:
24
"Portions Copyrighted [year] [name of copyright owner]"
25
26
Contributor(s):
27
28
The Original Software is NetBeans. The Initial Developer of the Original
29
Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
30
Microsystems, Inc. All Rights Reserved.
31
32
If you wish your version of this file to be governed by only the CDDL
33
or only the GPL Version 2, indicate your decision by adding
34
"[Contributor] elects to include this software in this distribution
35
under the [CDDL or GPL Version 2] license." If you do not indicate a
36
single choice of license, a recipient has the option to distribute
37
your version of this file under either the CDDL, the GPL Version 2 or
38
to extend the choice of license to its licensees as provided above.
39
However, if you add GPL Version 2 code and therefore, elected the GPL
40
Version 2 license, then the option applies only if the new code is
41
made subject to such option by the copyright holder.
42
-->
43
<project name="nbbuild" default="all" basedir=".">
44
    
45
    <import file="default.xml"/>
46
    
47
    <!-- To make people happy who want to do `ant clean all': -->
48
    <target name="all" depends="build,commit-validation" description="Build the IDE and run basic validation tests."/>
49
    
50
    <target name="all-nozip" depends="build-nozip,commit-validation" description="Build the IDE (no ZIP file, unpacked) and run basic validation tests."/>
51
    
52
    <target name="assure-ant">
53
        <condition property="ant.version.is.good">
54
            <!-- this is in 1.6.3 only -->
55
            <!-- actually needed for 'executable' attr on <javadoc>, at least -->
56
            <available classname="org.apache.tools.ant.types.mappers.FilterMapper"/>
57
        </condition>
58
        <fail unless="ant.version.is.good">
59
            You need to have ant 1.6.3 at least to build NetBeans.
60
        </fail>
61
    </target>
62
    
63
    <target name="bootstrap"
64
            description="Bootstrap NetBeans-specific Ant extensions."
65
            depends="-jdk-init,-assure-jdk-1.4,assure-ant">
66
        <echo message="Bootstrapping NetBeans-specific Ant extensions..."
67
        />
68
        <property name="ant.jar" value="${ant.home}/lib/ant.jar"/>
69
        <path id="bootstrap-cp">
70
            <pathelement location="${ant.jar}"/>
71
            <fileset dir="..">
72
                <!-- For JavaHelp indexing: -->
73
                <include name="nbbuild/external/jhall*.jar"/>
74
            </fileset>
75
        </path>
76
        <!-- Sanity check: -->
77
        <pathconvert pathsep=":" property="class.files.in.antsrc">
78
            <path>
79
                <fileset dir="antsrc">
80
                    <include name="**/*.class"/>
81
                </fileset>
82
            </path>
83
        </pathconvert>
84
        <fail>
85
            <condition>
86
                <not>
87
                    <equals arg1="${class.files.in.antsrc}" arg2=""/>
88
                </not>
89
            </condition>
90
            You have stray *.class files in ${basedir}/antsrc which you must remove.
91
            Probably you failed to clean your sources before updating them from CVS.
92
        </fail>
93
        <!-- OK, continue: -->
94
        <mkdir dir="build/antclasses"/>
95
        <javac srcdir="antsrc" destdir="build/antclasses" deprecation="true" debug="${build.compiler.debug}" source="1.4">
96
            <classpath refid="bootstrap-cp"/>
97
        </javac>
98
        <jar jarfile="nbantext.jar">
99
            <fileset dir="build/antclasses"/>
100
            <fileset dir="antsrc">
101
                <exclude name="**/*.java"/>
102
                <exclude name="**/package.html"/>
103
                <exclude name="package-list"/>
104
            </fileset>
105
        </jar>
106
    </target>
107
    
108
    <target name="init-module-list" depends="bootstrap">
109
        <!-- Define modules. -->
110
        <resolve name="modules" value="config.modules.${moduleconfig}"/>
111
        <resolve name="fixedmodules" value="config.fixedmodules.${moduleconfig}"/>
112
        <property name="allmodules" value="${fixedmodules},${modules}"/>
113
    </target>
114
    
115
    <target name="set-buildnumber" unless="buildnumber">
116
        <tstamp>
117
            <format property="buildnumber" pattern="yyMMdd"/>
118
        </tstamp>
119
        <tstamp>
120
            <format property="buildday" pattern="d MMM yyyy" locale="en" />
121
        </tstamp>
122
    </target>
123
    
124
    <target name="init" depends="init-module-list,set-buildnumber,init-tasks">
125
        <taskdef name="cleanall" classname="org.netbeans.nbbuild.CleanAll" classpath="nbantext.jar"/>
126
        <taskdef name="nbmerge" classname="org.netbeans.nbbuild.NbMerge" classpath="nbantext.jar"/>
127
        <taskdef name="for-each" classname="org.netbeans.nbbuild.ForEach" classpath="nbantext.jar"/>
128
        <taskdef name="getdependsclusters" classname="org.netbeans.nbbuild.GetDependsClusters" classpath="nbantext.jar"/>
129
        <taskdef name="repeat" classname="org.netbeans.nbbuild.Repeat" classpath="nbantext.jar"/>
130
        
131
        <!-- We need absolute path to ${netbeans.dest} -->
132
        <property name="netbeans.dest.abs" location="${netbeans.dest}"/>
133
        <!-- Overridable. Note: need not necessarily be a number at all): -->
134
        <property name="buildnum" value="dev-${buildnumber}"/>
135
        <property name="sanitystart.args" value="-J-Dnetbeans.close=true ${sanitystart.args.additional}"/>
136
        
137
        <!-- Set up automatic all-* targets: -->
138
        <taskdef name="insert-module-all-targets" classname="org.netbeans.nbbuild.InsertModuleAllTargets" classpath="nbantext.jar"/>
139
        <insert-module-all-targets/>
140
    </target>
141
    
142
    <target name="all-java/storagebuilder" depends="init">
143
        <antcall target="build-one-cluster-dependencies" inheritall="false">
144
            <param name="one.cluster.dependencies" value="nb.cluster.platform,nb.cluster.ide"/>
145
            <param name="one.cluster.name" value="this-cluster"/>
146
        </antcall>
147
        <echo message="Building java/storagebuilder library..."/>
148
        <ant dir="../java/storagebuilder" target="jar"/>
149
    </target>
150
    
151
    <target name="all-ide/branding" depends="init">
152
        <echo message="Building module ide/branding..."/>
153
        <getdependsclusters name="dependsClusters" list="${nb.clusters.list}"/>
154
        <antcall target="build-one-cluster-dependencies" inheritAll="false">
155
            <param name="one.cluster.dependencies" value="${dependsClusters}"/>
156
            <param name="one.cluster.name" value="this-cluster"/>
157
        </antcall>
158
        <ant dir="../ide/branding" target="netbeans"/>
159
    </target>
160
    
161
    <target name="all-installer" description="Dummy target for build system compatibility"/>
162
    
163
    <target name="all-tomcatint/tomcat5/bundled" depends="init">
164
        <getdependsclusters name="dependsClusters" list="${nb.clusters.list}"/>
165
        <antcall target="build-one-cluster-dependencies" inheritAll="false">
166
            <param name="one.cluster.dependencies" value="${dependsClusters}"/>
167
            <param name="one.cluster.name" value="this-cluster"/>
168
        </antcall>
169
        <!-- XXX this and xtest are clumsy: <antcall target="all-monitor"/> will not work since the subproject used by antcall does *not* have the synthetic targets! -->
170
        <ant dir="../monitor"/>
171
        <echo message="Building module tomcatint/tomcat5/bundled..."/>
172
        <ant dir="../tomcatint/tomcat5/bundled" target="netbeans"/>
173
    </target>
174
    
175
    <target name="all-translatedfiles" depends="init">
176
        <echo message="Building module translatedfiles..."/>
177
        <getdependsclusters name="dependsClusters" list="${nb.clusters.list}"/>
178
        <antcall target="build-one-cluster-dependencies" inheritAll="false">
179
            <param
180
                name="one.cluster.dependencies" 
181
                value="${dependsClusters}"/>
182
            <param name="one.cluster.name" value="this-cluster"/>
183
        </antcall>
184
        <ant dir="../translatedfiles" target="netbeans"/>
185
    </target>
186
    
187
    <target name="all-xtest" depends="init">
188
        <getdependsclusters name="dependsClusters" list="${clusters.list}"/>
189
        <antcall target="build-one-cluster-dependencies" inheritAll="false">
190
            <param name="one.cluster.dependencies" value="${dependsClusters}"/>
191
            <param name="one.cluster.name" value="this-cluster"/>
192
        </antcall>
193
        <ant dir="../xtest/nbjunit"/>
194
        <echo message="Building module xtest..."/>
195
        <ant dir="../xtest" antfile="build.xml" target="netbeans"/>
196
    </target>
197
    
198
    <!-- this is project is not a netbeans module project, so we do a no-op
199
       here.  The code in appsrvbridge gets built by XXX -->
200
    <target name="all-serverplugins/sun/appsrvbridge" depends="init">
201
        <echo message="Building module serverplugins/sun/appsrvbridge... NO-OP"/>
202
    </target>
203
    
204
    <!-- build NBMs for selected modules -->
205
    <target name="build-nbms" depends="init">
206
        <!-- It's good idea to call merge target before this one.
207
           NbMerge.java can set property "modules" to the list of realy
208
           built modules (excluding fixedmodules which must build everytime). -->
209
        <mkdir dir="nbms" />
210
        <property name="nbm.target.dir" location="nbms" />
211
        <for-each startdir=".." target="nbm" locations="${allmodules}"/>
212
    </target>
213
    <target name="nbm"/><!-- dummy target -->
214
  
215
    <property name="jnlp.signjar.keystore" location="build/default.keystore" />
216
    <available property="jnlp.signjar.keystore.exists" file="${jnlp.signjar.keystore}" />
217
    <target name="jnlp-generate-keystore" depends="init" unless="jnlp.signjar.keystore.exists" >
218
        <property name="jnlp.signjar.alias" value="jnlp" />
219
        <property name="jnlp.signjar.password" value="netbeans" />
220
        <property name="jnlp.signjar.vendor" value="CN=NetBeans, OU=NetBeans, O=netbeans.org, C=US" />
221
        
222
        <mkdir dir="${jnlp.signjar.keystore}/../" />
223
        <echo message="Going to create default keystore in ${jnlp.signjar.keystore}" />
224
        <genkey 
225
            alias="${jnlp.signjar.alias}"
226
            keystore="${jnlp.signjar.keystore}"
227
            storepass="${jnlp.signjar.password}"
228
            dname="${jnlp.signjar.vendor}"
229
        />
230
    </target>
231
    
232
    <target name="build-jnlp" depends="init,jnlp-generate-keystore">
233
        <fail message="Property jnlp.codebase must be set to final location of your JNLP files!" unless="jnlp.codebase" />
234
        <property name="jnlp.dest.dir" location="build/jnlp" />
235
        <mkdir dir="${jnlp.dest.dir}" />
236
        <for-each startdir=".." target="jnlp" locations="${config.modules.jnlp}"/>
237
    </target>
238
    
239
    <target name="set-config-to-javadoc" >
240
        <property name="moduleconfig" value="javadoc" />
241
    </target>
242
    
243
    <!-- build javadoc for selected modules -->
244
    <target name="build-javadoc" depends="set-config-to-javadoc,init" description="Builds Javadoc documentation for modules; on branches pass e.g. -Djavadoc.web.root=http://www.netbeans.org/download/release35/javadoc">
245
        <ant dir="." target="merge">
246
            <property name="modules" value="${modules}"/>
247
            <property name="fixedmodules" value="${fixedmodules}"/>
248
            <property name="merge.dependent.modules" value="true"/>
249
            <property name="stop.when.broken.module" value="false"/>
250
        </ant>
251
        
252
        <mkdir dir="build/ModulesExportedInterfaces" />
253
        <property name="export.interfaces" location="build/ModulesExportedInterfaces" />
254
        
255
        <mkdir dir="build/APIChanges" />
256
        <property name="export.apichanges" location="build/APIChanges" />
257
        
258
        <!-- build javadoc for supported APIs -->
259
        <for-each startdir=".." target="javadoc" locations="${fixedmodules}"/>
260
        <!-- build javadoc for unsupported APIs -->
261
        <for-each startdir=".." target="javadoc" locations="${modules}"/>
262
        
263
        <antcall inheritall="true" inheritrefs="true" target="javadoc-generate-xml" />
264
        <antcall inheritall="true" inheritrefs="true" target="javadoc-generate-html" />
265
        <antcall inheritall="true" inheritrefs="true" target="javadoc-check-broken-links" />
266
    </target>  
267
    
268
    <target name="javadoc-generate-xml" depends="set-config-to-javadoc,init" >
269
        <echo file="build/APIChanges/header.gen" >&lt;?xml version="1.0" encoding="UTF-8"?&gt;
270
            &lt;changes&gt;
271
        </echo>
272
        
273
        <echo file="build/APIChanges/footer.gen" >
274
            &lt;/changes&gt;
275
        </echo>
276
        
277
        <concat destfile="${netbeans.javadoc.dir}/apichanges.xml" >
278
            <fileset dir="build/APIChanges" includes="header.gen" />
279
            <fileset dir="build/APIChanges" includes="*" excludes="*.gen" />
280
            <fileset dir="build/APIChanges" includes="footer.gen" />
281
        </concat>
282
        
283
        
284
        <echo file="build/ModulesExportedInterfaces/header.gen" >&lt;?xml version="1.0" encoding="UTF-8"?&gt;
285
            &lt;apis&gt;
286
        </echo>
287
        
288
        <echo file="build/ModulesExportedInterfaces/footer.gen" >
289
            &lt;/apis&gt;
290
        </echo>
291
        
292
        <concat destfile="${netbeans.javadoc.dir}/modules.xml" >
293
            <fileset dir="build/ModulesExportedInterfaces" includes="header.gen" />
294
            <fileset dir="build/ModulesExportedInterfaces" includes="*" excludes="*.gen" />
295
            <fileset dir="build/ModulesExportedInterfaces" includes="footer.gen" />
296
        </concat>
297
        
298
        <taskdef 
299
            name="javadoc-index" 
300
            classpath="nbantext.jar" 
301
            classname="org.netbeans.nbbuild.JavadocIndex"
302
        />
303
        
304
        
305
        <javadoc-index target="${netbeans.javadoc.dir}/allclasses.xml" > 
306
            <packageslist dir="${netbeans.javadoc.dir}" >
307
                <include name="**/allclasses-noframe.html" />
308
            </packageslist>
309
        </javadoc-index>
310
    </target>
311
    
312
    
313
    <target name="javadoc-generate-html" depends="set-config-to-javadoc,init" >            
314
        <tstamp>
315
            <format property="modules-javadoc-date" pattern="d MMM yyyy" locale="en" />
316
        </tstamp>
317
        
318
        <style 
319
            in="${netbeans.javadoc.dir}/modules.xml" 
320
            out="${netbeans.javadoc.dir}/usecases.html" 
321
            style="javadoctools/export2usecases.xsl"
322
        >
323
            <param name="date" expression="${modules-javadoc-date}"/>
324
        </style>
325
        
326
        <style 
327
            in="${netbeans.javadoc.dir}/apichanges.xml" 
328
            out="${netbeans.javadoc.dir}/apichanges.html" 
329
            style="javadoctools/export2apichanges.xsl"
330
        >
331
            <param name="date" expression="${modules-javadoc-date}"/>
332
            <param name="changes-since-year" expression="${previous.release.year}"/>
333
            <param name="changes-since-day" expression="${previous.release.day}"/>
334
            <param name="changes-since-month" expression="${previous.release.month}"/>
335
            <param name="include-introduction" expression="true" />
336
        </style>
337
        
338
        <copy file="javadoctools/netbeans.css" tofile="${netbeans.javadoc.dir}/netbeans.css" />
339
        <condition property="javadoc.style.sheet.exists" >
340
            <available file="${netbeans.javadoc.dir}/org-openide-util/javadoc.css" />
341
        </condition>
342
        
343
        <fail unless="javadoc.style.sheet.exists" >
344
            The org-openide-util/javadoc.css has to exist as we are refering to
345
            it from to master module javadoc pages. If it does not anymore, update
346
            the javadoctools/export*.xsl templates.
347
        </fail>
348
        
349
        <style 
350
            in="${netbeans.javadoc.dir}/allclasses.xml" 
351
            out="${netbeans.javadoc.dir}/allclasses-frame.html" 
352
            style="javadoctools/export2allclasses.xsl"
353
        >
354
        </style>
355
        
356
        <style 
357
            in="${netbeans.javadoc.dir}/modules.xml" 
358
            out="${netbeans.javadoc.dir}/overview-frame.html" 
359
            style="javadoctools/export2allmodules.xsl"
360
        >
361
            <param name="date" expression="${modules-javadoc-date}"/>
362
        </style>
363
        
364
        <style 
365
            in="${netbeans.javadoc.dir}/modules.xml" 
366
            out="${netbeans.javadoc.dir}/layers.html" 
367
            style="javadoctools/export2layer.xsl"
368
        >
369
            <param name="date" expression="${modules-javadoc-date}"/>
370
        </style>
371
        
372
        <style 
373
            in="${netbeans.javadoc.dir}/modules.xml" 
374
            out="${netbeans.javadoc.dir}/overview-summary.html" 
375
            style="javadoctools/export2html.xsl"
376
        >
377
            <param name="date" expression="${modules-javadoc-date}"/>
378
        </style>
379
        
380
        
381
        <!-- at the end geneate the index.html so people know where to start -->      
382
        <echo file="${netbeans.javadoc.dir}/index.html" ><![CDATA[
383
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
384
<HTML><HEAD><TITLE>NetBeans API Index</TITLE>
385
</HEAD>
386
<FRAMESET cols="20%,80%" title="" onLoad="top.loadFrames()">
387
<FRAMESET rows="30%,70%" title="" onLoad="top.loadFrames()">
388
<FRAME src="overview-frame.html" name="packageListFrame" title="All Modules">
389
<FRAME src="allclasses-frame.html" name="packageFrame" title="All classes">
390
</FRAMESET>
391
<FRAME src="overview-summary.html" name="classFrame" title="Module, package, class and interface descriptions" scrolling="yes">
392
<NOFRAMES>
393
<H2>Frame Alert</H2>
394
<P>
395
This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client.
396
Link to<A HREF="overview-summary.html">Non-frame version.</A>
397
</NOFRAMES>
398
</FRAMESET>
399
</HTML>
400
        ]]></echo>
401
        
402
        <replace dir="${netbeans.javadoc.dir}">
403
            <include name="*.html"/>
404
            <replacefilter token="@JDK@" value="http://java.sun.com/j2se/1.4.2/docs/api"/>
405
            <replacefilter token="http://root/" value="." />
406
            <replacefilter token="$${javadoc.web.root}" value="." />
407
        </replace>
408
        
409
        <echo message="Javadoc index has been generated to ${netbeans.javadoc.dir}/index.html" />
410
    </target>
411
    
412
    
413
    <target name="javadoc-check-broken-links" depends="init" unless="javadoc.skip.brokenlinks.check" >
414
        <taskdef name="checklinks" classname="org.netbeans.nbbuild.CheckLinks">
415
            <classpath>
416
                <pathelement location="nbantext.jar"/>
417
            </classpath>
418
        </taskdef>
419
        <checklinks basedir="${netbeans.javadoc.dir}" checkexternal="${javadoc.check.external.links}" checkspaces="false" failonerror="true" >
420
            <include name="*/overview-summary.html"/>
421
            <include name="*/apichanges.html"/>
422
            <include name="*/architecture-summary.html"/>
423
            <include name="*/**/package-summary.html"/>
424
            <include name="*/**/doc-files/**/*.html"/>
425
            <include name="*.html" />
426
        </checklinks>
427
    </target>
428
    
429
    <target name="build-messaging" depends="init">
430
        <echo message="Starting a build for NetBeans (build ${buildnum}, config '${moduleconfig}') ..."/>
431
        <echo message="Selected modules: ${modules}"/>
432
        <echo message="OS: ${os.name} ${os.version}  Locale: ${user.language}_${user.region}"/>
433
        <echo message="Java: ${nbjdk.home}"/>
434
    </target>
435
    
436
    <!-- Use of nbmerge target has the effect of automatically depending on all-X for every module. -->
437
    <!-- It also runs deltree(dir=wherever) and copydir(src=../X/netbeans,dest=wherever) to create the IDE install. -->
438
439
    <target name="build-nozip" depends="clean-cluster-flags,build-clusters" description="Build the IDE but do not create a final ZIP file.">
440
        <loadproperties srcFile="${clusters.list.file}" />
441
        
442
        <loadproperties srcfile="${netbeans.dest.dir}/moduleCluster.properties" />
443
        
444
        <mkdir dir="${netbeans.dest.dir}/bin" />
445
        <copy file="../ide/launcher/unix/netbeans" todir="${netbeans.dest.dir}/bin" />
446
        <chmod file="${netbeans.dest.dir}/bin/netbeans" perm="ugo+rx"/>
447
        <copy file="../ide/launcher/windows/netbeans.exe" todir="${netbeans.dest.dir}/bin" />
448
        <copy file="../ide/launcher/windows/nb.exe" todir="${netbeans.dest.dir}/bin" />
449
        <copy file="../ide/launcher/os2/netbeans.cmd" todir="${netbeans.dest.dir}/bin" />
450
        <!-- if anybody knows better place for icons, let me know: jtulach@netbeans.org -->
451
        <copy file="../ide/launcher/os2/nbos2icons.zip" todir="${netbeans.dest.dir}/${nb.cluster.nb.dir}/" />
452
        
453
        <mkdir dir="${netbeans.dest.dir}/etc" />
454
        <copy file="../ide/launcher/netbeans.conf" todir="${netbeans.dest.dir}/etc" />
455
        
456
        <echo message="${netbeans.dest.dir}/${nb.cluster.platform.dir}/lib/nbexec" />
457
        <fixcrlf eol="lf" srcdir="${netbeans.dest.dir}" >
458
            <include name="etc/netbeans.conf" />
459
            <include name="bin/netbeans" />      
460
            <include name="${nb.cluster.platform.dir}/lib/nbexec" />      
461
        </fixcrlf>
462
        <fixcrlf eol="crlf" srcdir="${netbeans.dest.dir}" >
463
            <include name="bin/netbeans.cmd" />      
464
            <include name="${nb.cluster.platform.dir}/lib/nbexec.cmd" />      
465
        </fixcrlf>
466
        
467
        <echo file="${netbeans.dest.dir}/build_info">NetBeans dev build
468
            ------------------
469
            Number:   ${buildnumber}
470
            Date:     ${buildday}
471
            Branding:
472
            Branch:   trunk
473
            Tag:
474
        </echo>
475
    </target>
476
    
477
    <target name="build" depends="build-nozip"
478
            description="Create a complete build including a ZIP distribution (but do not try it).">
479
        <delete file="NetBeans-${buildnum}.zip"/>
480
        <delete file="NetBeans-${buildnum}-build-extra-data.zip"/>
481
        
482
        <property name="nb-extra-files" value="*.built,test/**,extra/**"/>
483
        
484
        <!-- package the zip file -->
485
        <zip destfile="NetBeans-${buildnum}.zip" update="true" duplicate="preserve">
486
            <zipfileset file="${netbeans.dest.dir}/bin/netbeans" filemode="755" prefix="${netbeans.dest}/bin"/>
487
            <zipfileset file="${netbeans.dest.dir}/${nb.cluster.platform.dir}/lib/nbexec" filemode="755" prefix="${netbeans.dest}/${nb.cluster.platform.dir}/lib"/>
488
            <zipfileset dir="${netbeans.dest.dir}/${nb.cluster.ide.dir}/ant/bin" filemode="755" prefix="${netbeans.dest}/${nb.cluster.ide.dir}/ant/bin">
489
                <exclude name="*.bat"/>
490
                <exclude name="*.cmd"/>
491
            </zipfileset>
492
            <zipfileset dir="${netbeans.dest.dir}" filemode="755" prefix="${netbeans.dest}">
493
                <include name="**/*.sh"/>
494
            </zipfileset>
495
            <zipfileset dir="${netbeans.dest.dir}" prefix="${netbeans.dest}" excludes="${nb-extra-files}">
496
                <!-- XXX exclude the temporary cluster for parts of openide -->
497
                <exclude name="tmp" />
498
                <exclude name="tmp/**/*" />
499
            </zipfileset>
500
        </zip>
501
        
502
        <!-- package the zip file with extra files not to be included in regular product package-->
503
        <!--
504
    <zip destfile="NetBeans-${buildnum}-build-extra-data.zip" update="true" duplicate="preserve">
505
        <zipfileset dir="${netbeans.dest.dir}" prefix="${netbeans.dest}" includes="${nb-extra-files}"/>
506
    </zip>
507
    -->
508
509
        <echo>Build created; see NetBeans-${buildnum}.zip (in nbbuild/).
510
            If you like, you may run the IDE straight from
511
            the ${netbeans.dest}/bin/ directory.
512
            (For example, type: ant tryme)
513
        </echo>
514
    </target>
515
    
516
    <target name="delete-and-merge" depends="merge-delete,merge" />   
517
    
518
    <target name="merge-delete" depends="init">
519
        <delete dir="${netbeans.dest}" />
520
    </target>
521
    
522
    <target name="merge" depends="build-messaging">
523
        <mkdir dir="${netbeans.dest.dir}"/>
524
        <nbmerge failonerror="${stop.when.broken.modules}" 
525
                 dest="${netbeans.dest}" 
526
                 topdir=".." 
527
                 fixedmodules="${fixedmodules}" 
528
                 modules="${modules}"
529
                 builtmodulesproperty="${built.modules.property}" 
530
                 targetprefix="all-" 
531
                 mergedependentmodules="${merge.dependent.modules}" >
532
        </nbmerge>
533
        <chmod perm="ugo+x">
534
            <fileset dir="${netbeans.dest.dir}">
535
                <include name="bin/netbeans"/>
536
                <include name="bin/**/*.pl"/>
537
                <include name="jakarta-tomcat-*/bin/*.sh"/>
538
            </fileset>
539
        </chmod>
540
    </target>
541
    
542
    <target name="build-platform" depends="init">
543
        <run-depend-build clusters-to-build="nb.cluster.platform,nb.cluster.harness"/>
544
    </target>
545
    
546
    <target name="build-cluster" depends="init">
547
        <run-depend-build clusters-to-build="${cluster-name}"/>
548
    </target>
549
    
550
    <macrodef name="resolve">
551
        <attribute name="name"/>
552
        <attribute name="value"/>
553
        <sequential>
554
            <property name="@{name}" value="${@{value}}"/>
555
        </sequential>
556
    </macrodef>
557
    
558
    <macrodef name="run-depend-build">
559
        <attribute name="clusters-to-build"/>
560
        <sequential>
561
            <echo>Repeat @{clusters-to-build}</echo>
562
            <repeat target="build-one-cluster" name="one.cluster.name" values="@{clusters-to-build}" /> 
563
        </sequential>
564
    </macrodef>
565
    
566
    <target name="build-clusters" depends="init">
567
        <run-depend-build clusters-to-build="${nb.clusters.list}"/> 
568
    </target>
569
    
570
    <target name="build-one-cluster-dependencies-check">
571
        <condition property="${one.cluster.name}-hasNoDependencies">
572
            <equals arg1="${one.cluster.dependencies}" arg2="" trim="true"/>
573
        </condition>
574
        <echo>Dependency prop :${one.cluster.name}-hasNoDependencies:</echo>
575
        <echo>Cluster dep :${one.cluster.dependencies}:</echo>
576
        <resolve name="test.prop" value="${one.cluster.name}-hasNoDependencies"/>
577
        <echo>Cluster dep prp:${test.prop}:</echo>
578
    </target>
579
    
580
    <target name="build-one-cluster-dependencies" 
581
            depends="build-one-cluster-dependencies-check"
582
            unless="${one.cluster.name}-hasNoDependencies">
583
        <run-depend-build clusters-to-build="${one.cluster.dependencies}"/> 
584
    </target>
585
    
586
    <target name="build-one-cluster-check">
587
        <condition property="${one.cluster.name}-is-built">
588
            <available file="${netbeans.dest.dir}/${one.cluster.name}.built"/>
589
        </condition>
590
        <resolve name="test1.prop" value="${one.cluster.name}-is-built"/>
591
        <echo>Cluster ${one.cluster.name} is :${test1.prop}:</echo>
592
    </target>
593
    
594
    <target name="build-one-cluster" unless="${one.cluster.name}-is-built" depends="build-one-cluster-check">
595
        <echo message="Building ${one.cluster.name} modules"/>
596
        <resolve name="one-cluster-modules" value="${one.cluster.name}"/>
597
        <resolve name="one-cluster-dependencies" value="${one.cluster.name}.depends"/>
598
        <echo>${one-cluster-modules}</echo>
599
        <echo>Dependencies: ${one-cluster-dependencies}</echo>
600
        <insert-module-all-targets/> <!-- we are in a subproject, so need to reinsert the targets... XXX <antcall> and thus <repeat> apparently reparses the Ant script from disk! -->
601
        <antcall target="build-one-cluster-dependencies" inheritAll="false">
602
            <param name="one.cluster.dependencies" value="${one-cluster-dependencies}"/>
603
            <param name="one.cluster.name" value="${one.cluster.name}"/>
604
        </antcall>
605
        <mkdir dir="${netbeans.dest.dir}"/>
606
        <nbmerge failonerror="${stop.when.broken.modules}" 
607
                 dest="${netbeans.dest.dir}" 
608
                 topdir="${nb_all}" 
609
                 fixedmodules="${one-cluster-modules}"
610
                 builtmodulesproperty="${built.modules.property}" 
611
                 targetprefix="all-" 
612
                 mergedependentmodules="false">
613
        </nbmerge>
614
        <touch file="${netbeans.dest.dir}/${one.cluster.name}.built"/>
615
    </target>
616
    
617
    <target name="zipclusters" depends="init">
618
        <mkdir dir="${netbeans.build.dir}/zips"/>
619
        <repeat target="zip-one-cluster" name="one.cluster.name" values="${clusters.list}" /> 
620
        
621
        <!-- package the misc files -->
622
        <zip destfile="${netbeans.build.dir}/zips/${clusters.prefix}-misc-${buildnum}.zip" update="true" duplicate="preserve">
623
            <zipfileset dir="${netbeans.dest.dir}" filemode="755">
624
                <include name="bin/netbeans"/>
625
            </zipfileset>
626
            <zipfileset dir="${netbeans.dest.dir}">
627
                <include name="bin/**"/>
628
                <include name="etc/**/"/>
629
            </zipfileset>
630
        </zip>
631
    </target>
632
    
633
    <target name="zip-one-cluster">
634
        <taskdef name="setclusterpatternset" classname="org.netbeans.nbbuild.SetClusterPatternSet" classpath="nbantext.jar"/>
635
        <taskdef name="setcluster" classname="org.netbeans.nbbuild.SetCluster" classpath="nbantext.jar"/>
636
        <loadproperties srcFile="${clusters.list.file}" />
637
        <loadproperties srcFile="cluster-description.properties" />
638
        <setcluster cluster="${one.cluster.name}" name="one.cluster.dir" />
639
        
640
        <setclusterpatternset cluster="${one.cluster.name}" name="${one.cluster.name}.files" trackingpath="${netbeans.dest.dir}" clusterdir="${one.cluster.dir}"/>
641
        
642
        <resolve name="zipcluster.file" value="${one.cluster.name}.pkg.filename"/>
643
        <zip destfile="${netbeans.build.dir}/zips/${clusters.prefix}-${zipcluster.file}-${buildnum}.zip" update="true" duplicate="preserve">
644
            <zipfileset dir="${netbeans.dest.dir}" filemode="755">
645
                <include name="${one.cluster.dir}/lib/nbexec"/>
646
            </zipfileset>
647
            <zipfileset dir="${netbeans.dest.dir}" filemode="755">
648
                <include name="${one.cluster.dir}/ant/bin/*"/>
649
                <exclude name="${one.cluster.dir}/ant/bin/*.bat"/>
650
                <exclude name="${one.cluster.dir}/ant/bin/*.cmd"/>
651
            </zipfileset>
652
            <zipfileset dir="${netbeans.dest.dir}">
653
                <patternset refID="${one.cluster.name}.files"/>
654
            </zipfileset>
655
        </zip>
656
    </target>
657
    
658
    <target name="create-rpms-proto">
659
        <mkdir dir="${netbeans.build.dir}/rpms"/>
660
        <repeat target="create-one-rpm-proto" name="one.cluster.name" values="${clusters.list}" /> 
661
    </target>
662
    
663
    <target name="create-one-rpm-proto">
664
        <taskdef name="setcluster" classname="org.netbeans.nbbuild.SetCluster" classpath="nbantext.jar"/>
665
        <loadproperties srcFile="cluster.properties" />
666
        <loadproperties srcFile="cluster-description.properties" />
667
        <setcluster cluster="${one.cluster.name}" name="one.cluster.dir" />
668
        <mkdir dir="${netbeans.build.dir}/rpms"/>
669
        
670
        <resolve name="pkg.name" value="${one.cluster.name}.pkg.name"/>
671
        <resolve name="pkg.version" value="${one.cluster.name}.pkg.version"/>
672
        <resolve name="pkg.desc" value="${one.cluster.name}.pkg.desc"/>
673
        <resolve name="pkg.vendor" value="${one.cluster.name}.pkg.vendor"/>
674
        <resolve name="pkg.email" value="${one.cluster.name}.pkg.email"/>
675
        <resolve name="pkg.rpm.name" value="${one.cluster.name}.pkg.rpm.name"/>
676
        <resolve name="pkg.rpm.requires" value="${one.cluster.name}.pkg.rpm.requires"/>
677
        <resolve name="pkg.rpm.group" value="${one.cluster.name}.pkg.rpm.group"/>
678
        <resolve name="pkg.rpm.url" value="${one.cluster.name}.pkg.rpm.url"/>
679
        <resolve name="pkg.rpm.copyright" value="${one.cluster.name}.pkg.rpm.copyright"/>
680
        <resolve name="pkg.rpm.map" value="${one.cluster.name}.pkg.rpm.map"/>
681
        <resolve name="pkg.rpm.prefix" value="${one.cluster.name}.pkg.rpm.prefix"/>
682
        
683
        <echo file="${netbeans.build.dir}/rpms/${pkg.rpm.name}.spec">
684
            %define global_product_version ${pkg.version}
685
            %define global_product_release 00
686
            %define _prefix ${pkg.rpm.prefix}
687
            Version: %{global_product_version}
688
            Release: %{global_product_release}
689
            Group: ${pkg.rpm.group}
690
            Copyright: ${pkg.rpm.copyright}
691
            Vendor: ${pkg.vendor}
692
            URL: ${pkg.rpm.url}
693
            Prefix: %_prefix
694
            AutoReqProv: no
695
            Name: ${pkg.rpm.name}
696
            Summary: ${pkg.name}
697
            %description 
698
            ${pkg.desc}
699
            
700
            %files
701
            
702
            %erpm_map ${pkg.rpm.map} nb_destdir
703
            
704
            %dir ${pkg.rpm.map}
705
            
706
        ${pkg.rpm.map}/${one.cluster.dir}</echo>
707
    </target>
708
    
709
    <target name="create-svr4s-proto">
710
        <mkdir dir="${netbeans.build.dir}/rpms"/>
711
        <repeat target="create-one-svr4-proto" name="one.cluster.name" values="${clusters.list}" /> 
712
    </target>
713
    
714
    <target name="create-one-svr4-proto">
715
        <taskdef name="setcluster" classname="org.netbeans.nbbuild.SetCluster" classpath="nbantext.jar"/>
716
        <loadproperties srcFile="cluster.properties" />
717
        <loadproperties srcFile="cluster-description.properties" />
718
        <setcluster cluster="${one.cluster.name}" name="one.cluster.dir" />
719
        <mkdir dir="${netbeans.build.dir}/svr4s"/>
720
        
721
        <resolve name="pkg.name" value="${one.cluster.name}.pkg.name"/>
722
        <resolve name="pkg.version" value="${one.cluster.name}.pkg.version"/>
723
        <resolve name="pkg.desc" value="${one.cluster.name}.pkg.desc"/>
724
        <resolve name="pkg.vendor" value="${one.cluster.name}.pkg.vendor"/>
725
        <resolve name="pkg.email" value="${one.cluster.name}.pkg.email"/>
726
        <resolve name="pkg.svr4.pkg" value="${one.cluster.name}.pkg.svr4.pkg"/>
727
        <resolve name="pkg.svr4.maxinst" value="${one.cluster.name}.pkg.svr4.maxinst"/>
728
        <resolve name="pkg.svr4.sunw_pkgvers" value="${one.cluster.name}.pkg.svr4.sunw_pkgvers"/>
729
        <resolve name="pkg.svr4.hotline" value="${one.cluster.name}.pkg.svr4.hotline"/>
730
        <resolve name="pkg.svr4.classes" value="${one.cluster.name}.pkg.svr4.classes"/>
731
        <resolve name="pkg.svr4.basedir" value="${one.cluster.name}.pkg.svr4.basedir"/>
732
        <resolve name="pkg.svr4.pkginst" value="${one.cluster.name}.pkg.svr4.pkginst"/>
733
        <resolve name="pkg.svr4.category" value="${one.cluster.name}.pkg.svr4.category"/>
734
        <echo file="${netbeans.build.dir}/svr4s/${pkg.svr4.pkg}.spec">
735
            PKG=${pkg.svr4.pkg}
736
            NAME=${pkg.name}
737
            ARCH=sparc
738
            VERSION=${pkg.version}
739
            MAXINST=${pkg.svr4.maxinst}
740
            CATEGORY=${pkg.svr4.category}
741
            SUNW_PKGVERS=${pkg.svr4.sunw_pkgvers}
742
            DESC=${pkg.desc}
743
            VENDOR=${pkg.vendor}
744
            HOTLINE=${pkg.svr4.hotline}
745
            EMAIL=${pkg.email}
746
            CLASSES=${pkg.svr4.classes}
747
            BASEDIR=${pkg.svr4.basedir}
748
        PKGINST=${pkg.svr4.pkginst}</echo>
749
    </target>
750
    
751
    <target name="sanity-check" depends="testuserdir-delete,sanity-start" description="Test whether the build can start up without problems."/>
752
    <target name="-testuserdir-delete-init" depends="init">
753
        <property name="test.user.dir.lock" location="${test.user.dir}/lock"/>
754
        <available property="app.running" file="${test.user.dir.lock}"/>
755
    </target>
756
    <target name="-testuserdir-delete-ok" depends="-testuserdir-delete-init" unless="app.running">
757
        <delete dir="${test.user.dir}"/>
758
    </target>
759
    <target name="-testuserdir-delete-fail" depends="-testuserdir-delete-init" if="app.running">
760
        <!-- #66799: best to warn about this condition... -->
761
        <fail>Will not delete ${test.user.dir} because ${test.user.dir.lock} still exists; kill any running process and delete lock file if necessary</fail>
762
    </target>
763
    <target name="testuserdir-delete" depends="-testuserdir-delete-ok,-testuserdir-delete-fail"/>
764
    <target name="sanity-start" depends="init,maybe-build-nozip,-jdk-init">
765
        <mkdir dir="${test.user.dir}"/>
766
        <echo>Starting the IDE as a sanity check...</echo>
767
        <echo>WARNING - the sanity-start target is deprecated. Use commit-validation instead.</echo>
768
        <!-- XXX better would be to scan start log for stacktraces and just show those; -->
769
        <!-- possibly after filtering for duplicates or something like this. -->
770
        <!-- Timeout is ten minutes; should be enough for valid start, while preventing -->
771
        <!-- a deadlock from hanging an automated build: -->
772
        <exec os="Windows NT Windows 95 Windows 98 Windows 2000 Windows 2003 Windows XP" executable="${netbeans.dest.abs}/bin/nb.exe" failonerror="yes" timeout="600000">
773
            <arg value="--jdkhome"/>
774
            <arg file="${nbjdk.home}"/>
775
            <arg value="--userdir"/>
776
            <arg file="${test.user.dir}"/>
777
            <arg line="${sanitystart.args}"/>
778
        </exec>
779
        <exec os="Linux SunOS Solaris Mac OS X" dir="." executable="sh" failonerror="yes" timeout="600000">
780
            <arg value="${netbeans.dest.abs}/bin/netbeans"/>
781
            <arg value="--jdkhome"/>
782
            <arg file="${nbjdk.home}"/>
783
            <arg value="--userdir"/>
784
            <arg file="${test.user.dir}"/>
785
            <arg line="${sanitystart.args}"/>
786
        </exec>
787
        <echo>Finished starting the IDE, pay attention to any reported errors.</echo>
788
    </target>
789
    
790
    <target name="check-for-build"  >
791
        <available property="have-build" file="${netbeans.dest.dir}/bin/netbeans"/>
792
    </target>
793
    <target name="maybe-build-nozip" depends="check-for-build" unless="have-build">
794
        <ant dir="${basedir}" target="build-nozip"/>
795
    </target>
796
    
797
    <target name="nozip-check" 
798
            depends="build-nozip,sanity-check">
799
        <echo>WARNING - the nozip-check target is deprecated. Use all-nozip instead.</echo>
800
    </target>
801
    
802
    <target name="tryme-setup-debug-args" if="debug.port" >
803
        <property name="debug.pause" value="n" />
804
        <property name="debug.server" value="y" />
805
        
806
        <property name="tryme.debug.args" value="-J-Xdebug -J-Xnoagent -J-Xrunjdwp:transport=dt_socket,suspend=${debug.pause},server=${debug.server},address=${debug.port}" />
807
    </target>
808
    
809
    <target name="tryme-debug" depends="-jdk-presetdef-nbjpdastart" description="Start IDE in debugger. May only be called from within IDE.">
810
        <nbjpdastart name="NetBeans" addressproperty="debug.port" transport="dt_socket">
811
            <classpath>
812
                <fileset dir="${netbeans.dest.dir}">
813
                    <include name="**/*.jar"/>
814
                </fileset>
815
            </classpath>
816
        </nbjpdastart>
817
        <property name="debug.server" value="n"/>
818
        <antcall target="tryme"/>
819
    </target>
820
    
821
    <target name="tryme-profile" depends="-jdk-presetdef-nbprofiledirect" description="Start IDE in debugger. May only be called from within IDE.">
822
        <property name="profiler.roots.path" value="profiler.roots.all" />
823
        <fileset id="profiler.roots.all" dir="${netbeans.dest.dir}">
824
            <include name="**/*.jar"/>
825
        </fileset>
826
        <nbprofiledirect 
827
            jvmargsprefix="-J" 
828
            jvmargsproperty="profiler.jvmargs" 
829
            mainclass="org.netbeans.Main"
830
        >
831
            <classpath>
832
                <fileset dir="${netbeans.dest.dir}">
833
                    <include name="**/*.jar"/>
834
                </fileset>
835
            </classpath>
836
            <rootspath>
837
                <fileset refid="${profiler.roots.path}" />
838
            </rootspath>
839
        </nbprofiledirect>
840
        
841
        <antcall target="tryme">
842
            <param name="tryme.args" value="${profiler.jvmargs}"/>
843
        </antcall>
844
    </target>
845
    
846
    <target name="tryme" depends="init,maybe-build-nozip,tryme-setup-debug-args,-jdk-init"
847
            description="Try running the IDE interactively (build it first if needed).
848
            It is possible to use -Ddebug.port=3234 -Ddebug.pause=y to start the system in debug mode" 
849
    >
850
        <property name="tryme.debug.args" value="" />
851
        
852
        <exec os="Windows NT Windows 95 Windows 98 Windows 2000 Windows 2003 Windows XP" executable="${netbeans.dest.abs}/bin/nb.exe" failonerror="yes">
853
            <arg value="--jdkhome"/>
854
            <arg file="${nbjdk.home}"/>
855
            <arg value="--userdir"/>
856
            <arg file="${test.user.dir}"/>
857
            <arg line="${tryme.args}"/>
858
            <arg line="${tryme.debug.args}" />
859
        </exec>
860
        <exec os="Linux SunOS Solaris Mac OS X" dir="." executable="sh" failonerror="yes">
861
            <arg value="${netbeans.dest}/bin/netbeans"/>
862
            <arg value="--jdkhome"/>
863
            <arg file="${nbjdk.home}"/>
864
            <arg value="--userdir"/>
865
            <arg file="${test.user.dir}"/>
866
            <arg line="${tryme.args}"/>
867
            <arg line="${tryme.debug.args}" />
868
        </exec>
869
    </target>
870
    
871
    <target name="l10n-kit" depends="init">
872
        <taskdef name="l10n" classname="org.netbeans.nbbuild.L10nTask"
873
                 classpath="nbantext.jar"/>
874
        <delete dir="${l10n.dist.dir}"/>
875
        <mkdir dir="${l10n.dist.dir}"/>
876
        <delete dir="tmp"/>
877
        <mkdir dir="tmp"/>
878
        <property name="nbroot" location=".."/>
879
        <l10n topdirs="${nbroot}" modules="${fixedmodules},${modules}"
880
              localizablefile="l10n.list" generatedfile="l10n.list.translated"
881
              distdir="${l10n.dist.dir}" changedfile="l10n.list.changed"
882
              builddir="tmp" buildnumber="${buildnumber}"
883
              excludepattern="**/ja/,**/*_ja.*"/>
884
        <delete dir="tmp"/>
885
    </target>
886
    
887
    <target name="bootstrap-javadoc"
888
            depends="bootstrap"
889
            description="Generate Javadoc for Ant extensions.">
890
        <!-- XXX this ought to be deleted at some point. -->
891
        <!-- Can be done anyway by apisupport/ant, and published as regular module Javadoc -->
892
        <!-- by the regular daily Javadoc build process. -->
893
        <!-- Then all of this stuff can be deleted from the www part of CVS. -->
894
        <mkdir dir="www/nbantext-javadoc"/>
895
        <delete>
896
            <fileset dir="www/nbantext-javadoc">
897
                <include name="**/*.html"/>
898
            </fileset>
899
        </delete>
900
        <tstamp/>
901
        <javadoc sourcepath="antsrc"
902
                 destdir="www/nbantext-javadoc"
903
                 packagenames="org.netbeans.nbbuild.*"
904
                 windowtitle="NetBeans Ant Extensions"
905
                 doctitle="Extended Ant Tasks for Building NetBeans"
906
                 nodeprecatedlist="true"
907
                 notree="true"
908
                 noindex="true"
909
                 nohelp="true"
910
                 nonavbar="true"
911
                 author="false"
912
                 version="false"
913
                 bottom="Built on ${buildday}"
914
        >
915
            <classpath refid="bootstrap-cp"/>
916
            <link href="http://nagoya.apache.org/gump/javadoc/ant/build/javadocs" offline="true" packagelistloc="antsrc"/>
917
        </javadoc>
918
    </target>
919
    
920
    <target name="clean-external">
921
        <subant target="clean">
922
            <fileset dir="..">
923
                <include name="*/external/build.xml"/>
924
                <include name="contrib/*/external/build.xml"/>
925
            </fileset>
926
        </subant>
927
    </target>
928
    
929
    <target name="real-clean" depends="clean,clean-external"
930
            description="Clean everything possible.">
931
        <echo message="Cleaning old builds..."/>
932
        <delete>
933
            <fileset dir=".">
934
                <include name="NetBeans-*.log"/>
935
                <include name="NetBeans-*.zip"/>
936
            </fileset>
937
        </delete>
938
        <!-- This step must be last: -->
939
        <echo message="Cleaning NetBeans-specific Ant extensions..."/>
940
        <delete file="nbantext.jar" quiet="true"/>
941
        <delete dir="build/antclasses"/>
942
    </target>
943
    
944
    <target name="ant-clean">
945
        <delete file="nbantext.jar"/>
946
    </target>
947
    
948
    <target name="clean-cluster-flags" unless="do-not-rebuild-clusters">
949
        <mkdir dir="${netbeans.dest.dir}"/>
950
        <delete includeEmptyDirs="true">
951
            <fileset dir="${netbeans.dest.dir}">
952
                <include name="*.built"/>
953
            </fileset>
954
        </delete>
955
    </target>
956
    
957
    <target name="localclean" depends="clean-cluster-flags,init">
958
        <delete dir="${test.user.dir}"/>
959
        <delete dir="build"/>
960
        <delete file="moduledefs-tmp.properties"/>
961
        <delete dir="nbms" />
962
        <delete dir="${netbeans.dest.dir}"/>
963
    </target>
964
    
965
    <!-- more correct but takes too long: <target name="localtest" depends="bootstrap,all-xtest/nbjunit" > -->
966
    <target name="localtest" depends="bootstrap">
967
        <ant dir="test" target="cleanresults"/>
968
        <ant dir="test" target="runtests"/>
969
    </target>
970
    <target name="localtest-nb" depends="localtest">
971
        <nbbrowse file="test/results/index.html"/>
972
    </target>
973
    <target name="localtest-single-nb" depends="bootstrap">
974
        <property name="unit.test.base" location="test/unit/src"/>
975
        <pathconvert property="xtest.includes" pathsep=",">
976
            <path path="${includes}"/>
977
            <mapper type="glob" from="${unit.test.base}${file.separator}*.java" to="*.class"/>
978
        </pathconvert>
979
        <property name="xtest.attribs" value="empty"/>
980
        <ant dir="test" target="cleanresults"/>
981
        <ant dir="test" target="runtests"/>
982
        <nbbrowse file="test/results/index.html"/>
983
    </target>
984
    <target name="localtest-single-nb-debug" depends="bootstrap,-jdk-presetdef-nbjpdastart">
985
        <property name="unit.test.base" location="test/unit/src"/>
986
        <pathconvert property="xtest.includes" pathsep=",">
987
            <path path="${includes}"/>
988
            <mapper type="glob" from="${unit.test.base}${file.separator}*.java" to="*.class"/>
989
        </pathconvert>
990
        <property name="xtest.attribs" value="empty"/>
991
        <ant dir="test" target="cleanresults"/>
992
        <nbjpdastart transport="dt_socket" addressproperty="jpda.address" name="${test.class}">
993
            <classpath>
994
                <!--
995
            <path location="test/work/sys/tests/unit/classes"/>
996
            <path location="test/work/sys/tests/"/>
997
            <path location="test/unit/src/"/>
998
            -->
999
                <path location="nbantext.jar"/>
1000
            </classpath>
1001
        </nbjpdastart>
1002
        <ant dir="test" target="runtests">
1003
            <property name="xtest.debug.address" value="${jpda.address}" />
1004
            <property name="xtest.debug.pause" value="false" />
1005
        </ant>
1006
        <nbbrowse file="test/results/index.html"/>
1007
    </target>
1008
    
1009
    <target name="cleanall" depends="init">
1010
        <cleanall topdir=".." 
1011
                  modules="${allmodules}" 
1012
                  targetname="clean"
1013
                  resolvedependencies="${resolve.clean.dependencies}"
1014
                  deptargetprefix="all-"
1015
                  failonerror="${stop.when.clean.error}" />
1016
    </target>
1017
    
1018
    <target name="clean" depends="init,cleanall,localclean"
1019
            description="Clean out (almost) all build products.">
1020
        <echo message="Run `ant real-clean' if desired."/>
1021
    </target>
1022
    
1023
    <!-- This section contains properties and targets used to build -->
1024
    <!-- Solaris packages.                                          -->
1025
1026
    <property name="solpkg-pkgproto" value="pkgproto"/>
1027
    <property name="solpkg-pkgmk" value="pkgmk"/>
1028
    <property name="solpkg-proto-file" value="prototype"/>
1029
    <property name="solpkg-actual-dir" value="to-be-specified"/>
1030
    <property name="solpkg-pkg-dir" value="to-be-specified"/>
1031
    <property name="solpkg-pkg-dest-dir" value="to-be-specified"/>
1032
    
1033
    <!-- You can run this target to create the prototype file and create -->
1034
    <!-- the package, or if you need to modify the prototype file before -->
1035
    <!-- building the package, you can run the two subtargets            -->
1036
    <!-- separately.                                                     -->
1037
    <target name="solpkg-build" depends="solpkg-pkgproto,solpkg-pkgmk"
1038
            description="Generate a prototype file and create a Solaris package."/>
1039
    
1040
    <!-- This creates the pkg prototype file for a given directory and -->
1041
    <!-- its files.                                                    -->
1042
    <target name="solpkg-pkgproto"
1043
            description="Generate a prototype file.">
1044
        <exec executable="rm" failonerror="yes">
1045
            <arg value="-rf"/>
1046
            <arg value="${solpkg-proto-file}"/>
1047
        </exec>
1048
        <exec executable="${solpkg-pkgproto}" output="${solpkg-proto-file}" 
1049
              failonerror="yes">
1050
            <arg value="${solpkg-actual-dir}=${solpkg-pkg-dir}"/>
1051
        </exec>
1052
    </target>
1053
    
1054
    <!-- This creates the Solaris pkg for a given prototype file, pkginfo -->
1055
    <!-- file, and directory.                                             -->
1056
    <target name="solpkg-pkgmk"
1057
            description="Create a Solaris package.">
1058
        <exec executable="${solpkg-pkgmk}" failonerror="yes">
1059
            <arg value="-o"/>
1060
            <arg value="-f"/>
1061
            <arg value="${solpkg-proto-file}"/>
1062
            <arg value="-r"/>
1063
            <arg value="${solpkg-actual-dir}"/>
1064
            <arg value="-d"/>
1065
            <arg value="${solpkg-pkg-dest-dir}"/>
1066
        </exec>
1067
    </target>
1068
    
1069
    <!-- End of Solaris package section. -->
1070
1071
    
1072
    <!-- Localized builds -->
1073
    <target name="all-dutch" depends="set-dutch-locale,all"/>
1074
    <target name="all-russian" depends="set-russian-locale,all"/>
1075
    <target name="all-french" depends="set-french-locale,all"/>
1076
    <target name="all-ja-zh" depends="set-ja-zh_CN-locales,all"/>
1077
    
1078
    <target name="set-ja-zh_CN-locales">
1079
        <property name="locales" value="ja,zh_CN"/>
1080
        <property name="locjar.locales" value="${locales}"/>
1081
        <property name="locmakenbm.locales"   value="${locales}"/>
1082
        <property name="locjhindexer.locales" value="${locales}"/>
1083
        <property name="localized.build.locales" value="${locales}"/>
1084
    </target>
1085
    
1086
    <target name="set-dutch-locale">
1087
        <property name="locales" value="nl"/>
1088
        <property name="locjar.locales" value="${locales}"/>
1089
        <property name="locmakenbm.locales"   value="${locales}"/>
1090
        <property name="locjhindexer.locales" value="${locales}"/>
1091
        <property name="localized.build.locales" value="${locales}"/>
1092
    </target>
1093
    
1094
    <target name="set-russian-locale">
1095
        <property name="locales" value="ru"/>
1096
        <property name="locjar.locales" value="${locales}"/>
1097
        <property name="locmakenbm.locales"   value="${locales}"/>
1098
        <property name="locjhindexer.locales" value="${locales}"/>
1099
        <property name="localized.build.locales" value="${locales}"/>
1100
    </target>
1101
    
1102
    <target name="set-french-locale">
1103
        <property name="locales" value="fr"/>
1104
        <property name="locjar.locales" value="${locales}"/>
1105
        <property name="locmakenbm.locales"   value="${locales}"/>
1106
        <property name="locjhindexer.locales" value="${locales}"/>
1107
        <property name="localized.build.locales" value="${locales}"/>
1108
    </target>
1109
    
1110
    <!-- end of localized builds -->
1111
1112
1113
    <target name="print-selected-modules" depends="init" description="Prints list of modules to build in selected moduleconfig.">
1114
        <echo message="modules=${allmodules}"/>
1115
    </target>
1116
    
1117
    <target name="print-cvs-modules" depends="init" description="Prints list of cvs modules required to build in selected moduleconfig.">
1118
        <taskdef name="printcvsmodules" classname="org.netbeans.nbbuild.PrintCvsModules" classpath="nbantext.jar"/>
1119
        <printcvsmodules modules="${fixedmodules},${modules}" targetprefix="all-" />
1120
    </target>
1121
    
1122
    <target name="check-commit-validation">
1123
        <condition property="run.validation" >
1124
            <and>
1125
                <available file="../ide/test/build.xml" />
1126
                <available file="../jemmy/build.xml" />
1127
                <available file="../jellytools/build.xml" />
1128
                <available file="../xtest/build.xml" />
1129
                <or>
1130
                    <not>
1131
                        <isset property="nb.run.validation"/>
1132
                    </not>
1133
                    <istrue value="${nb.run.validation}"/>
1134
                </or>
1135
            </and>
1136
        </condition>
1137
    </target>
1138
    
1139
    <target 
1140
        name="unit-validation" 
1141
        description="Invokes all existing unit tests in all IDE modules.
1142
        Useful when one wants to deeply verify that his changes
1143
        work"
1144
    >
1145
        <ant dir="../xtest/instance" target="runtests" >
1146
            <property name="xtest.config" value="unit-nb" />
1147
        </ant>
1148
    </target>
1149
    
1150
    <target 
1151
        name="commit-validation" 
1152
        depends="commit-verification,commitValidation,no-commit-validation" 
1153
        description="Runs tests to validate IDE before commit."
1154
    />
1155
    
1156
    <target name="all-commitValidation" description="dummy target for build error recognition facility"/>
1157
    
1158
    <target 
1159
        name="commit-verification" 
1160
        description="Compares result of a build with golden files verifying various aspects of the exported interfaces"
1161
        depends="
1162
        all-verification,
1163
        check-files-layout,
1164
        check-public-packages,
1165
        check-friend-packages,
1166
        check-shared-packages,
1167
        check-modules,
1168
        check-dependencies,
1169
        check-implementation-dependencies,
1170
        check-cluster-dependencies,
1171
        check-cluster-implementation-dependencies,
1172
        check-clusters-content"
1173
    />
1174
    
1175
    <!-- JST: One day also add 
1176
    check-external-libraries
1177
  -->
1178
  
1179
    <target name="all-verification" >
1180
        <echo message="Runs verification tests to check the IDE before commit" />
1181
    </target>
1182
    
1183
    <!-- keep this target name at least for a while for backward compat -jglick -->
1184
    <target name="commitValidation" depends="all-commitValidation,check-commit-validation" if="run.validation">
1185
        <property name="xtest.home" location="../xtest"/>
1186
        <ant dir="${xtest.home}/instance" target="cleanresults">
1187
            <property name="xtest.config" value="commit-validation-nb"/>
1188
        </ant>
1189
        <ant dir="${xtest.home}/instance" target="cleantests">
1190
            <property name="xtest.config" value="commit-validation-nb"/>
1191
        </ant>
1192
        <ant dir="${xtest.home}/instance" target="runtests">
1193
            <property name="xtest.config" value="commit-validation-nb"/>
1194
            <property name="xtest.fail.on.failure" value="true"/>
1195
        </ant>
1196
    </target>
1197
    
1198
    <target name="no-commit-validation" depends="check-commit-validation" unless="run.validation">
1199
        <echo>
1200
            *** WARNING ***
1201
            You do not seem to have the modules needed to run the commit validation test suite. 
1202
            You may not commit any changes into the CVS repository without running these tests.
1203
            For more information: http://www.netbeans.org/community/guidelines/commit.html
1204
        </echo>
1205
    </target>
1206
    
1207
    <target name="sanity-build-from-source-pkg" depends="build-source">
1208
        <available file="${netbeans.build.dir}/${cluster.name}-src-${buildnum}.zip"
1209
                   property="pkg.available"/>
1210
        <fail message="Source package ${netbeans.build.dir}/${cluster.name}-src-${buildnum}.zip not available" unless="pkg.available"/>
1211
        <delete dir="testbuild"/>
1212
        <mkdir dir="testbuild"/>
1213
        <unzip dest="testbuild" src="${netbeans.build.dir}/${cluster.name}-src-${buildnum}.zip"/>
1214
        <property name="one.cluster.name" value="${cluster.name}"/>
1215
        <propertyset id="sanity-build">
1216
            <propertyref name="one.cluster.name"/>
1217
        </propertyset>
1218
        <echoproperties destfile="testbuild/nbbuild/user.properties">
1219
            <propertyset refid="sanity-build"/>
1220
        </echoproperties>
1221
        
1222
        <!-- it should call build of the refered cluster and not just hardcoded platform -->
1223
        <ant antfile="testbuild/nbbuild/build.xml" inheritall="false" target="build-one-cluster">
1224
            <property file="testbuild/nbbuild/user.properties"/>
1225
        </ant>
1226
        <delete dir="testbuild"/>
1227
    </target>
1228
    
1229
    <target name="build-source"
1230
            depends="init,set-buildnumber"
1231
            description="Packages sources needed to compile given by cluster.name (can be specified by -Dcluster.name=nb.cluster.platform"
1232
            if="cluster.name"
1233
    >
1234
        <property name="buildnum" value="dev-${buildnumber}"/>
1235
        <echo message="Packaging sources of ${cluster.name} modules"/>
1236
        <resolve name="cluster-modules" value="${cluster.name}"/>
1237
        <resolve name="harness-modules" value="nb.cluster.harness"/>
1238
        <mkdir dir="${netbeans.build.dir}"/>
1239
        <taskdef name="definefileset" classname="org.netbeans.nbbuild.PrintCvsModules" classpath="nbantext.jar"/>
1240
        <definefileset modules="${cluster-modules}" targetprefix="all-" id="source-modules" dir=".." />
1241
        <definefileset modules="${cluster-modules}" targetprefix="all-" id="external-modules" dir=".." mode="binaries" />
1242
        <definefileset modules="${harness-modules}" targetprefix="all-" id="harness-source-modules" dir=".." />
1243
        <definefileset modules="${harness-modules}" targetprefix="all-" id="harness-external-modules" dir=".." mode="binaries" />
1244
        <zip zipfile="${netbeans.build.dir}/${cluster.name}-src-${buildnum}.zip" duplicate="preserve">
1245
            <fileset refid="source-modules" />
1246
            <fileset refid="external-modules" />
1247
            <fileset refid="harness-source-modules" />
1248
            <fileset refid="harness-external-modules" />
1249
        </zip>
1250
    </target>
1251
    
1252
    <target name="generate-golden-files-init" depends="init,bootstrap" >
1253
        <property name="template.files.dir" location="build/golden" />
1254
        <property name="golden.files.dir" location="../ide/golden" />
1255
        <condition property="golden.files.eol" value="unix" >
1256
            <or>
1257
                <os family="unix" />
1258
                <os family="mac" />
1259
            </or>
1260
        </condition>
1261
        <property name="golden.files.eol" value="dos" />
1262
        
1263
        <mkdir dir="${template.files.dir}" />
1264
        
1265
        <!-- convert the golden files into platform default encoding -->
1266
        <fixcrlf srcdir="${golden.files.dir}" destdir="${template.files.dir}" eol="${golden.files.eol}" >
1267
            <include name="*txt" />
1268
        </fixcrlf>
1269
        
1270
    </target>
1271
    
1272
    
1273
    <target name="generate-golden-files" depends="generate-golden-files-init" >
1274
        <property name="generated.files.dir" location="build/generated" />
1275
        <mkdir dir="${generated.files.dir}" />
1276
        
1277
        <taskdef name="deps" classname="org.netbeans.nbbuild.ModuleDependencies" classpath="nbantext.jar"/>
1278
        
1279
        <deps>
1280
            <input name="platform" >
1281
                <jars dir="${netbeans.dest.dir}" >
1282
                    <include name="${nb.cluster.platform.dir}/**/*.jar" />
1283
                </jars>
1284
            </input>
1285
            <input name="ide" >
1286
                <jars dir="${netbeans.dest.dir}" >
1287
                    <include name="${nb.cluster.ide.dir}/**/*.jar" />
1288
                </jars>
1289
            </input>
1290
            <input name="j2ee" >
1291
                <jars dir="${netbeans.dest.dir}" >
1292
                    <include name="${nb.cluster.j2ee.dir}/**/*.jar" />
1293
                </jars>
1294
            </input>
1295
            <input name="nb" >
1296
                <jars dir="${netbeans.dest.dir}" >
1297
                    <include name="${nb.cluster.nb.dir}/**/*.jar" />
1298
                </jars>
1299
            </input>
1300
            <input name="harness" >
1301
                <jars dir="${netbeans.dest.dir}" >
1302
                    <include name="${nb.cluster.harness.dir}/**/*.jar" />
1303
                </jars>
1304
            </input>
1305
            
1306
            <output type="group-dependencies" file="${generated.files.dir}/cluster-deps.txt" />
1307
            <output type="group-implementation-dependencies" file="${generated.files.dir}/cluster-impl-deps.txt" />
1308
            <output type="modules" file="${generated.files.dir}/modules.txt" />
1309
            <output type="dependencies" file="${generated.files.dir}/deps.txt" />
1310
            <output type="implementation-dependencies" file="${generated.files.dir}/impl-deps.txt" />
1311
            <output type="public-packages" file="${generated.files.dir}/public-packages.txt" />
1312
            <output type="shared-packages" file="${generated.files.dir}/shared-packages.txt" />
1313
            <output type="friend-packages" file="${generated.files.dir}/friend-packages.txt" />
1314
            <output type="external-libraries" file="${generated.files.dir}/external-libraries.txt" />
1315
        </deps>
1316
    </target>
1317
    
1318
    <target name="check-public-packages" depends="generate-golden-files" >
1319
        <property name="check.public.packages.golden" location="${golden.files.dir}/public-packages.txt" />
1320
        <property name="check.public.packages.template" location="${template.files.dir}/public-packages.txt" />
1321
        <property name="check.public.packages.generated" location="${generated.files.dir}/public-packages.txt" />
1322
        
1323
        <condition property="check-public-packages-are-they-the-same" >
1324
            <filesmatch file1="${check.public.packages.template}" file2="${check.public.packages.generated}" />
1325
        </condition>
1326
        
1327
        
1328
        <exec os="Linux SunOS Solaris " dir="." executable="diff" failonerror="no" timeout="60000" >
1329
            <arg value="-U"/>
1330
            <arg value="15"/>
1331
            <arg value="${check.public.packages.template}" />
1332
            <arg value="${check.public.packages.generated}" />
1333
        </exec>
1334
        
1335
        <fail unless="check-public-packages-are-they-the-same" >!
1336
            *** Public packages has changed! ***
1337
            
1338
            Differences were found while comparing file 
1339
            ${check.public.packages.template}
1340
            with 
1341
            ${check.public.packages.generated}
1342
            
1343
            This means that the set of public packages changed since the previously known one.
1344
            Some packages may have been added, some of them may have been removed 
1345
            Either by changing manifest of a module or by adding or removing a class file
1346
            from a module package.
1347
            
1348
            
1349
            Changing the packages may or may not be ok. It means that an api of 
1350
            whole product changes and as such it is subject to review. If you passed
1351
            your review and want to change the list of public packages, then please
1352
            update the golden file at 
1353
            ${check.public.packages.golden}
1354
            and run the test once again. 
1355
            
1356
            Read more about the Verification Framework:
1357
            http://openide.netbeans.org/proposals/arch/clusters.html#verify
1358
            
1359
            Look at for information about reviews:
1360
            http://openide.netbeans.org/tutorial/review-steps.html
1361
            
1362
            Check the page about APIs:
1363
            http://openide.netbeans.org/tutorial/api-design.html#api
1364
        </fail>
1365
    </target>
1366
    
1367
    <target name="check-friend-packages" depends="generate-golden-files" >
1368
        <property name="check.friend.packages.golden" location="${golden.files.dir}/friend-packages.txt" />
1369
        <property name="check.friend.packages.template" location="${template.files.dir}/friend-packages.txt" />
1370
        <property name="check.friend.packages.generated" location="${generated.files.dir}/friend-packages.txt" />
1371
        
1372
        <condition property="check-friend-packages-are-they-the-same" >
1373
            <filesmatch file1="${check.friend.packages.template}" file2="${check.friend.packages.generated}" />
1374
        </condition>
1375
        
1376
        
1377
        <exec os="Linux SunOS Solaris " dir="." executable="diff" failonerror="no" timeout="60000" >
1378
            <arg value="-U"/>
1379
            <arg value="15"/>
1380
            <arg value="${check.friend.packages.template}" />
1381
            <arg value="${check.friend.packages.generated}" />
1382
        </exec>
1383
        
1384
        <fail unless="check-friend-packages-are-they-the-same" >!
1385
            *** Friend packages has changed! ***
1386
            
1387
            Differences were found while comparing file 
1388
            ${check.friend.packages.template}
1389
            with 
1390
            ${check.friend.packages.generated}
1391
            
1392
            This means that the set of friend packages changed since the previously known one.
1393
            Some packages may have been added, some of them may have been removed 
1394
            Either by changing manifest of a module or by adding or removing a class file
1395
            from a module package.
1396
            
1397
            
1398
            Changing the packages may or may not be ok. It means that an api of 
1399
            whole product changes and as such it is subject to review. If you passed
1400
            your review and want to change the list of friend packages, then please
1401
            update the golden file at 
1402
            ${check.friend.packages.golden}
1403
            and run the test once again. 
1404
            
1405
            Read more about the Verification Framework:
1406
            http://openide.netbeans.org/proposals/arch/clusters.html#verify
1407
            
1408
            Look at for information about reviews:
1409
            http://openide.netbeans.org/tutorial/review-steps.html
1410
            
1411
            Check the page about APIs:
1412
            http://openide.netbeans.org/tutorial/api-design.html#api
1413
        </fail>
1414
    </target>
1415
    
1416
    <target name="check-shared-packages" depends="generate-golden-files,-jdk-init" unless="have-jdk-1.5" >
1417
        <property name="check.shared.packages.golden" location="${golden.files.dir}/shared-packages.txt" />
1418
        <property name="check.shared.packages.template" location="${template.files.dir}/shared-packages.txt" />
1419
        <property name="check.shared.packages.generated" location="${generated.files.dir}/shared-packages.txt" />
1420
        
1421
        <condition property="check-shared-packages-are-they-the-same" >
1422
            <filesmatch file1="${check.shared.packages.template}" file2="${check.shared.packages.generated}" />
1423
        </condition>
1424
        
1425
        
1426
        <exec os="Linux SunOS Solaris Mac OS X" dir="." executable="diff" failonerror="no" timeout="60000" >
1427
            <arg value="-U"/>
1428
            <arg value="15"/>
1429
            <arg value="${check.shared.packages.template}" />
1430
            <arg value="${check.shared.packages.generated}" />
1431
        </exec>
1432
        
1433
        <fail unless="check-shared-packages-are-they-the-same" >!
1434
            *** Shared packages has changed! ***
1435
            
1436
            Differences were found while comparing file 
1437
            ${check.shared.packages.template}
1438
            with 
1439
            ${check.shared.packages.generated}
1440
            
1441
            This means that the set of shared packages changed since the previously known one.
1442
            Some packages may have been added, some of them may have been removed 
1443
            Either by changing manifest of a module or by adding or removing a class file
1444
            from a module package.
1445
            
1446
            
1447
            Removing shared packages is ok. Adding shared packages is silly, complicates
1448
            and slows down module system and startup of the application. Do not do that!
1449
            If you are removing a shared package please update 
1450
            ${check.shared.packages.golden}
1451
            and run the test once again. 
1452
            
1453
            Read more about the Verification Framework:
1454
            http://openide.netbeans.org/proposals/arch/clusters.html#verify
1455
            
1456
            Look at for information about reviews:
1457
            http://openide.netbeans.org/tutorial/review-steps.html
1458
            
1459
            Check the page about APIs:
1460
            http://openide.netbeans.org/tutorial/api-design.html#api
1461
        </fail>
1462
    </target>
1463
    
1464
    <target name="check-external-libraries" depends="generate-golden-files" >
1465
        <property name="check.external.libraries.golden" location="${golden.files.dir}/external-libraries.txt" />
1466
        <property name="check.external.libraries.template" location="${template.files.dir}/external-libraries.txt" />
1467
        <property name="check.external.libraries.generated" location="${generated.files.dir}/external-libraries.txt" />
1468
        
1469
        <condition property="check-external-libraries-are-they-the-same" >
1470
            <filesmatch file1="${check.external.libraries.template}" file2="${check.external.libraries.generated}" />
1471
        </condition>
1472
        
1473
        
1474
        <exec os="Linux SunOS Solaris Mac OS X" dir="." executable="diff" failonerror="no" timeout="60000" >
1475
            <arg value="-U"/>
1476
            <arg value="15"/>
1477
            <arg value="${check.external.libraries.template}" />
1478
            <arg value="${check.external.libraries.generated}" />
1479
        </exec>
1480
        
1481
        <fail unless="check-external-libraries-are-they-the-same" >!
1482
            *** List of external libraries has changed! ***
1483
            
1484
            Differences were found while comparing file 
1485
            ${check.external.libraries.template}
1486
            with 
1487
            ${check.external.libraries.generated}
1488
            
1489
            This means that the set of external libraries (JARs that are not NetBeans
1490
            modules or does not have NetBeans-Own-Library: true in manifest) has 
1491
            changed since the previously known one. Some libraries may have been added, 
1492
            some of them may have been removed, they MD5 checksum or size has been changed.
1493
            
1494
            Changing the external libraries is ok, but requires legal approval everytime
1495
            new version of a library is put into the product. If you have the approval
1496
            want to change the list of external libraries, then please
1497
            update the golden file at 
1498
            ${check.external.libraries.golden}
1499
            and run the test once again. 
1500
            
1501
            Read more about the Verification Framework:
1502
            http://openide.netbeans.org/proposals/arch/clusters.html#verify
1503
            
1504
            Look at for information about reviews:
1505
            http://openide.netbeans.org/tutorial/review-steps.html
1506
            
1507
            Check the page about APIs:
1508
            http://openide.netbeans.org/tutorial/api-design.html#api
1509
        </fail>
1510
    </target>
1511
    
1512
    <target name="check-modules" depends="generate-golden-files" >
1513
        <property name="check.modules.golden" location="${golden.files.dir}/modules.txt" />
1514
        <property name="check.modules.template" location="${template.files.dir}/modules.txt" />
1515
        <property name="check.modules.generated" location="${generated.files.dir}/modules.txt" />
1516
        
1517
        <condition property="check-modules-are-they-the-same" >
1518
            <filesmatch file1="${check.modules.template}" file2="${check.modules.generated}" />
1519
        </condition>
1520
        
1521
        
1522
        <exec os="Linux SunOS Solaris Mac OS X" dir="." executable="diff" failonerror="no" timeout="60000" >
1523
            <arg value="-U"/>
1524
            <arg value="15"/>
1525
            <arg value="${check.modules.template}" />
1526
            <arg value="${check.modules.generated}" />
1527
        </exec>
1528
        
1529
        <fail unless="check-modules-are-they-the-same" >!
1530
            *** List of modules has changed! ***
1531
            
1532
            Differences were found while comparing file 
1533
            ${check.modules.template}
1534
            with 
1535
            ${check.modules.generated}
1536
            
1537
            This means that the set of modules changed since the previously known one.
1538
            Adding or removing a module significatly affects the set of APIs the
1539
            product offers and as such is subject to review. If you passed
1540
            your review and want to change the list of modules, then please
1541
            update the golden file at 
1542
            ${check.modules.golden}
1543
            and run the test once again. 
1544
            
1545
            Read more about the Verification Framework:
1546
            http://openide.netbeans.org/proposals/arch/clusters.html#verify
1547
            
1548
            Look at for information about reviews:
1549
            http://openide.netbeans.org/tutorial/review-steps.html
1550
            
1551
            Check the page about APIs:
1552
            http://openide.netbeans.org/tutorial/api-design.html#api
1553
        </fail>
1554
    </target>
1555
    
1556
    <target name="check-dependencies" depends="generate-golden-files" >
1557
        <antcall target="check-dependencies-subroutine" >
1558
            <param name="check.dependencies.golden" location="${golden.files.dir}/deps.txt" />
1559
            <param name="check.dependencies.template" location="${template.files.dir}/deps.txt" />
1560
            <param name="check.dependencies.generated" location="${generated.files.dir}/deps.txt" />
1561
        </antcall>
1562
    </target>
1563
    
1564
    <target name="check-implementation-dependencies" depends="generate-golden-files" >
1565
        <antcall target="check-dependencies-subroutine" >
1566
            <param name="check.dependencies.golden" location="${golden.files.dir}/impl-deps.txt" />
1567
            <param name="check.dependencies.template" location="${template.files.dir}/impl-deps.txt" />
1568
            <param name="check.dependencies.generated" location="${generated.files.dir}/impl-deps.txt" />
1569
        </antcall>
1570
    </target>
1571
    
1572
    <target name="check-cluster-dependencies" depends="generate-golden-files" >
1573
        <antcall target="check-dependencies-subroutine" >
1574
            <param name="check.dependencies.golden" location="${golden.files.dir}/cluster-deps.txt" />
1575
            <param name="check.dependencies.template" location="${template.files.dir}/cluster-deps.txt" />
1576
            <param name="check.dependencies.generated" location="${generated.files.dir}/cluster-deps.txt" />
1577
        </antcall>
1578
    </target>
1579
    
1580
    <target name="check-cluster-implementation-dependencies" depends="generate-golden-files" >
1581
        <antcall target="check-dependencies-subroutine" >
1582
            <param name="check.dependencies.golden" location="${golden.files.dir}/cluster-impl-deps.txt" />
1583
            <param name="check.dependencies.template" location="${template.files.dir}/cluster-impl-deps.txt" />
1584
            <param name="check.dependencies.generated" location="${generated.files.dir}/cluster-impl-deps.txt" />
1585
        </antcall>
1586
    </target>
1587
    
1588
    <target name="check-dependencies-subroutine" >
1589
        <condition property="check-dependencies-are-they-the-same" >
1590
            <filesmatch file1="${check.dependencies.template}" file2="${check.dependencies.generated}" />
1591
        </condition>
1592
        
1593
        
1594
        <exec os="Linux SunOS Solaris Mac OS X" dir="." executable="diff" failonerror="no" timeout="60000" >
1595
            <arg value="-U"/>
1596
            <arg value="15"/>
1597
            <arg value="${check.dependencies.template}" />
1598
            <arg value="${check.dependencies.generated}" />
1599
        </exec>
1600
        
1601
        <fail unless="check-dependencies-are-they-the-same" >!
1602
            *** List of dependencies has changed! ***
1603
            
1604
            Differences were found while comparing file 
1605
            ${check.dependencies.template}
1606
            with 
1607
            ${check.dependencies.generated}
1608
            
1609
            This means that the set of dependencies changed since the previously known one.
1610
            Adding a dependency can restrict the ways how a final product can be assembled
1611
            and as such it forms an important aspect of API and is subject to review. 
1612
            If you passed your review or you are sure you want to change the 
1613
            list of dependencies, then please update the golden file at 
1614
            ${check.dependencies.golden}
1615
            and run the test once again. 
1616
            
1617
            Read more about the Verification Framework:
1618
            http://openide.netbeans.org/proposals/arch/clusters.html#verify
1619
            
1620
            Look at for information about reviews:
1621
            http://openide.netbeans.org/tutorial/review-steps.html
1622
            
1623
            Check the page about APIs and dependencies being important:
1624
            http://openide.netbeans.org/tutorial/api-design.html#api
1625
        </fail>
1626
    </target>
1627
    
1628
    
1629
    <target name="generate-files-layout" depends="generate-golden-files-init" >
1630
        <property name="generated.files.dir" location="build/generated" />
1631
        <mkdir dir="${generated.files.dir}" />
1632
        
1633
        <property name="check.files.layout.golden" location="${golden.files.dir}/files-layout.txt" />
1634
        <property name="check.files.layout.template" location="${template.files.dir}/files-layout.txt" />
1635
        <property name="check.files.layout.generated" location="${generated.files.dir}/files-layout.txt" />
1636
        
1637
        <property name="check-file-layout-root" location="${netbeans.dest.dir}" />
1638
        <fileset id="check-file-layout" dir="${check-file-layout-root}" casesensitive="yes" >
1639
            <include name="platform*/**" />
1640
            <include name="ide*/**" />
1641
            <include name="enterprise*/**" />
1642
            <include name="nb*/**" />
1643
            <include name="harness*/**" />
1644
        </fileset>
1645
        
1646
        <pathconvert property="check-file-layout" refid="check-file-layout" dirsep="/" pathsep="," >
1647
            <map from="${check-file-layout-root}${file.separator}" to="" />
1648
        </pathconvert>
1649
        <mkdir dir="build/generated" />
1650
        <echo message="${check-file-layout}${line.separator}" file="${check.files.layout.generated}" />
1651
        <replace file="${check.files.layout.generated}" token="," value="${line.separator}" />
1652
        <replace file="${check.files.layout.generated}" token="\" value="/" />
1653
        <condition property="check-files-are-they-the-same" >
1654
            <filesmatch file1="${check.files.layout.template}" file2="${check.files.layout.generated}" />
1655
        </condition>
1656
        
1657
        
1658
    </target>
1659
    
1660
    
1661
    <target name="check-files-layout" depends="generate-files-layout" >
1662
        <exec os="Linux SunOS Solaris Mac OS X" dir="." executable="diff" failonerror="no" timeout="60000" >
1663
            <arg value="-U"/>
1664
            <arg value="15"/>
1665
            <arg value="${check.files.layout.template}" />
1666
            <arg value="${check.files.layout.generated}" />
1667
        </exec>
1668
        
1669
        <fail unless="check-files-are-they-the-same" >!
1670
            *** Layout of files has changed! ***
1671
            
1672
            Differences were found while comparing file ${check.files.layout.generated} with 
1673
            ${check.files.layout.template}
1674
            This means that the layout of files changed since the previously known one.
1675
            Some files may have been added, some of them may have been removed or renamed. 
1676
            
1677
            Changing the layout may or may not be ok. If you are sure that you want to
1678
            change the layout of files, then update the golden file at 
1679
            ${check.files.layout.golden}
1680
            and run the test once again. If you got this warning without intending
1681
            to change the layout of files, think twice whether your commit is really
1682
            correct and consider asking for a review first.
1683
            
1684
            Read more about the Verification Framework:
1685
            http://openide.netbeans.org/proposals/arch/clusters.html#verify
1686
            
1687
            Look at for information about reviews:
1688
            http://openide.netbeans.org/tutorial/review-steps.html
1689
            
1690
            Check the page about APIs and files layout being an API:
1691
            http://openide.netbeans.org/tutorial/api-design.html#api
1692
        </fail>
1693
    </target>
1694
    
1695
    <target name="check-clusters-content" depends="bootstrap,init-tasks"> 
1696
        <taskdef name="checkcontent" classname="org.netbeans.nbbuild.CheckClustersContent" classpath="nbantext.jar"/>
1697
        <checkcontent clusters="${nb.clusters.list}" trackingPath="${netbeans.dest.dir}" kitDestDir="${netbeans.dest.dir}">
1698
            <exclude name="extra/**"/>
1699
            <exclude name="testtools/**"/>
1700
            <exclude name="bin/**"/>
1701
            <exclude name="README.html"/>
1702
            <exclude name="CREDITS.html"/>
1703
            <exclude name="LICENSE.txt"/>
1704
            <exclude name="DISTRIBUTION.txt"/>
1705
            <exclude name="THIRDPARTYLICENSE.txt"/>
1706
            <exclude name="nb.cluster.*"/>
1707
            <exclude name="etc/netbeans.conf"/>
1708
            <exclude name="build_info"/>
1709
            <exclude name="module_tracking.xml"/>
1710
            <exclude name="moduleCluster.properties"/>
1711
            <exclude name="netbeans.css"/>
1712
        </checkcontent>
1713
    </target>
1714
    
1715
    <target name="check-module-configs" depends="bootstrap" description="Sanity-check build.properties and cluster.properties.">
1716
        <taskdef name="checkmoduleconfigs" classname="org.netbeans.nbbuild.CheckModuleConfigs" classpath="nbantext.jar"/>
1717
        <checkmoduleconfigs nbroot=".."/>
1718
    </target>
1719
    
1720
    <target name="display-l10n-list-matches" description="Show which files are actually matched by an l10n.list in some module.">
1721
        <property name="nbroot" location=".."/>
1722
        <input addproperty="module">Select a top-level module (e.g. "java") to display results for:</input>
1723
        <property name="listfile" location="${nbroot}/${module}/l10n.list"/>
1724
        <echo>${listfile}:1: Matches follow... (click on hyperlinks from IDE!)</echo>
1725
        <echo>(warning: 'exclude' directives not honored here yet)</echo><!-- XXX use filtersets or something to fix -->
1726
        <apply parallel="false" executable="sh">
1727
            <arg value="-c"/>
1728
            <arg value="echo $0:1"/>
1729
            <fileset dir="${nbroot}" includesfile="${listfile}"/>
1730
        </apply>
1731
    </target>
1732
    
1733
    <target name="increment-spec-versions" depends="bootstrap,init-module-list" description="Increment all standard module specification versions. Pass -Dbranch=true if not on the trunk.">
1734
        <property name="branch" value="false"/>
1735
        <taskdef name="incrspecvers" classname="org.netbeans.nbbuild.IncrementSpecificationVersions" classpath="nbantext.jar"/>
1736
        <incrspecvers nbroot=".." modules="${allmodules}" branch="${branch}"/>
1737
    </target>
1738
    
1739
</project>
(-)a/xml.text.obsolete90/test/unit/data/input/XMLFormatterTest/testReformat/netbeans_build.xml (+1739 lines)
Line 0 Link Here
1
<?xml version="1.0" encoding="UTF-8"?>
2
<!--
3
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4
5
Copyright 1997-2009 Sun Microsystems, Inc. All rights reserved.
6
7
8
The contents of this file are subject to the terms of either the GNU
9
General Public License Version 2 only ("GPL") or the Common
10
Development and Distribution License("CDDL") (collectively, the
11
"License"). You may not use this file except in compliance with the
12
License. You can obtain a copy of the License at
13
http://www.netbeans.org/cddl-gplv2.html
14
or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
15
specific language governing permissions and limitations under the
16
License.  When distributing the software, include this License Header
17
Notice in each file and include the License file at
18
nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
19
particular file as subject to the "Classpath" exception as provided
20
by Sun in the GPL Version 2 section of the License file that
21
accompanied this code. If applicable, add the following below the
22
License Header, with the fields enclosed by brackets [] replaced by
23
your own identifying information:
24
"Portions Copyrighted [year] [name of copyright owner]"
25
26
Contributor(s):
27
28
The Original Software is NetBeans. The Initial Developer of the Original
29
Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
30
Microsystems, Inc. All Rights Reserved.
31
32
If you wish your version of this file to be governed by only the CDDL
33
or only the GPL Version 2, indicate your decision by adding
34
"[Contributor] elects to include this software in this distribution
35
under the [CDDL or GPL Version 2] license." If you do not indicate a
36
single choice of license, a recipient has the option to distribute
37
your version of this file under either the CDDL, the GPL Version 2 or
38
to extend the choice of license to its licensees as provided above.
39
However, if you add GPL Version 2 code and therefore, elected the GPL
40
Version 2 license, then the option applies only if the new code is
41
made subject to such option by the copyright holder.
42
-->
43
  <project name="nbbuild" default="all" basedir=".">
44
45
<import file="default.xml"/>
46
47
  <!-- To make people happy who want to do `ant clean all': -->
48
<target name="all" depends="build,commit-validation" description="Build the IDE and run basic validation tests."/>
49
50
  <target name="all-nozip" depends="build-nozip,commit-validation" description="Build the IDE (no ZIP file, unpacked) and run basic validation tests."/>
51
52
  <target name="assure-ant">
53
<condition property="ant.version.is.good">
54
          <!-- this is in 1.6.3 only -->
55
          <!-- actually needed for 'executable' attr on <javadoc>, at least -->
56
          <available classname="org.apache.tools.ant.types.mappers.FilterMapper"/>
57
</condition>
58
  <fail unless="ant.version.is.good">
59
        You need to have ant 1.6.3 at least to build NetBeans.
60
                       </fail>
61
    </target>
62
  
63
  <target name="bootstrap"
64
          description="Bootstrap NetBeans-specific Ant extensions."
65
          depends="-jdk-init,-assure-jdk-1.4,assure-ant">
66
   <echo message="Bootstrapping NetBeans-specific Ant extensions..."
67
/>
68
    <property name="ant.jar" value="${ant.home}/lib/ant.jar"/>
69
    <path id="bootstrap-cp">
70
     <pathelement location="${ant.jar}"/>
71
 <fileset dir="..">
72
        <!-- For JavaHelp indexing: -->
73
        <include name="nbbuild/external/jhall*.jar"/>
74
             </fileset>
75
  </path>
76
    <!-- Sanity check: -->
77
    <pathconvert pathsep=":" property="class.files.in.antsrc">
78
        <path>
79
            <fileset dir="antsrc">
80
                <include name="**/*.class"/>
81
            </fileset>
82
        </path>
83
    </pathconvert>
84
    <fail>
85
        <condition>
86
            <not>
87
                <equals arg1="${class.files.in.antsrc}" arg2=""/>
88
            </not>
89
        </condition>
90
        You have stray *.class files in ${basedir}/antsrc which you must remove.
91
        Probably you failed to clean your sources before updating them from CVS.
92
    </fail>
93
    <!-- OK, continue: -->
94
    <mkdir dir="build/antclasses"/>
95
    <javac srcdir="antsrc" destdir="build/antclasses" deprecation="true" debug="${build.compiler.debug}" source="1.4">
96
      <classpath refid="bootstrap-cp"/>
97
    </javac>
98
    <jar jarfile="nbantext.jar">
99
      <fileset dir="build/antclasses"/>
100
      <fileset dir="antsrc">
101
        <exclude name="**/*.java"/>
102
        <exclude name="**/package.html"/>
103
        <exclude name="package-list"/>
104
      </fileset>
105
    </jar>
106
  </target>
107
108
  <target name="init-module-list" depends="bootstrap">
109
    <!-- Define modules. -->
110
    <resolve name="modules" value="config.modules.${moduleconfig}"/>
111
    <resolve name="fixedmodules" value="config.fixedmodules.${moduleconfig}"/>
112
    <property name="allmodules" value="${fixedmodules},${modules}"/>
113
  </target>
114
115
  <target name="set-buildnumber" unless="buildnumber">
116
    <tstamp>
117
    	<format property="buildnumber" pattern="yyMMdd"/>
118
    </tstamp>
119
    <tstamp>
120
    	<format property="buildday" pattern="d MMM yyyy" locale="en" />
121
    </tstamp>
122
  </target>
123
124
  <target name="init" depends="init-module-list,set-buildnumber,init-tasks">
125
    <taskdef name="cleanall" classname="org.netbeans.nbbuild.CleanAll" classpath="nbantext.jar"/>
126
    <taskdef name="nbmerge" classname="org.netbeans.nbbuild.NbMerge" classpath="nbantext.jar"/>
127
    <taskdef name="for-each" classname="org.netbeans.nbbuild.ForEach" classpath="nbantext.jar"/>
128
    <taskdef name="getdependsclusters" classname="org.netbeans.nbbuild.GetDependsClusters" classpath="nbantext.jar"/>
129
    <taskdef name="repeat" classname="org.netbeans.nbbuild.Repeat" classpath="nbantext.jar"/>
130
131
    <!-- We need absolute path to ${netbeans.dest} -->
132
    <property name="netbeans.dest.abs" location="${netbeans.dest}"/>
133
    <!-- Overridable. Note: need not necessarily be a number at all): -->
134
    <property name="buildnum" value="dev-${buildnumber}"/>
135
    <property name="sanitystart.args" value="-J-Dnetbeans.close=true ${sanitystart.args.additional}"/>
136
137
    <!-- Set up automatic all-* targets: -->
138
    <taskdef name="insert-module-all-targets" classname="org.netbeans.nbbuild.InsertModuleAllTargets" classpath="nbantext.jar"/>
139
    <insert-module-all-targets/>
140
  </target>
141
  
142
  <target name="all-java/storagebuilder" depends="init">
143
    <antcall target="build-one-cluster-dependencies" inheritall="false">
144
      <param name="one.cluster.dependencies" value="nb.cluster.platform,nb.cluster.ide"/>
145
      <param name="one.cluster.name" value="this-cluster"/>
146
    </antcall>
147
    <echo message="Building java/storagebuilder library..."/>
148
    <ant dir="../java/storagebuilder" target="jar"/>
149
  </target>
150
151
  <target name="all-ide/branding" depends="init">
152
    <echo message="Building module ide/branding..."/>
153
    <getdependsclusters name="dependsClusters" list="${nb.clusters.list}"/>
154
    <antcall target="build-one-cluster-dependencies" inheritAll="false">
155
      <param name="one.cluster.dependencies" value="${dependsClusters}"/>
156
      <param name="one.cluster.name" value="this-cluster"/>
157
    </antcall>
158
    <ant dir="../ide/branding" target="netbeans"/>
159
  </target>
160
161
  <target name="all-installer" description="Dummy target for build system compatibility"/>
162
163
  <target name="all-tomcatint/tomcat5/bundled" depends="init">
164
    <getdependsclusters name="dependsClusters" list="${nb.clusters.list}"/>
165
    <antcall target="build-one-cluster-dependencies" inheritAll="false">
166
      <param name="one.cluster.dependencies" value="${dependsClusters}"/>
167
      <param name="one.cluster.name" value="this-cluster"/>
168
    </antcall>
169
    <!-- XXX this and xtest are clumsy: <antcall target="all-monitor"/> will not work since the subproject used by antcall does *not* have the synthetic targets! -->
170
    <ant dir="../monitor"/>
171
    <echo message="Building module tomcatint/tomcat5/bundled..."/>
172
    <ant dir="../tomcatint/tomcat5/bundled" target="netbeans"/>
173
  </target>
174
175
  <target name="all-translatedfiles" depends="init">
176
    <echo message="Building module translatedfiles..."/>
177
    <getdependsclusters name="dependsClusters" list="${nb.clusters.list}"/>
178
              <antcall target="build-one-cluster-dependencies" inheritAll="false">
179
      <param
180
 name="one.cluster.dependencies" 
181
value="${dependsClusters}"/>
182
      <param name="one.cluster.name" value="this-cluster"/>
183
    </antcall>
184
    <ant dir="../translatedfiles" target="netbeans"/>
185
  </target>
186
187
  <target name="all-xtest" depends="init">
188
    <getdependsclusters name="dependsClusters" list="${clusters.list}"/>
189
    <antcall target="build-one-cluster-dependencies" inheritAll="false">
190
      <param name="one.cluster.dependencies" value="${dependsClusters}"/>
191
      <param name="one.cluster.name" value="this-cluster"/>
192
    </antcall>
193
    <ant dir="../xtest/nbjunit"/>
194
    <echo message="Building module xtest..."/>
195
    <ant dir="../xtest" antfile="build.xml" target="netbeans"/>
196
  </target>
197
  
198
  <!-- this is project is not a netbeans module project, so we do a no-op
199
       here.  The code in appsrvbridge gets built by XXX -->
200
  <target name="all-serverplugins/sun/appsrvbridge" depends="init">
201
    <echo message="Building module serverplugins/sun/appsrvbridge... NO-OP"/>
202
  </target>
203
204
  <!-- build NBMs for selected modules -->
205
  <target name="build-nbms" depends="init">
206
      <!-- It's good idea to call merge target before this one.
207
           NbMerge.java can set property "modules" to the list of realy
208
           built modules (excluding fixedmodules which must build everytime). -->
209
      <mkdir dir="nbms" />
210
      <property name="nbm.target.dir" location="nbms" />
211
      <for-each startdir=".." target="nbm" locations="${allmodules}"/>
212
  </target>
213
  <target name="nbm"/><!-- dummy target -->
214
  
215
  <property name="jnlp.signjar.keystore" location="build/default.keystore" />
216
  <available property="jnlp.signjar.keystore.exists" file="${jnlp.signjar.keystore}" />
217
  <target name="jnlp-generate-keystore" depends="init" unless="jnlp.signjar.keystore.exists" >
218
    <property name="jnlp.signjar.alias" value="jnlp" />
219
    <property name="jnlp.signjar.password" value="netbeans" />
220
    <property name="jnlp.signjar.vendor" value="CN=NetBeans, OU=NetBeans, O=netbeans.org, C=US" />
221
    
222
    <mkdir dir="${jnlp.signjar.keystore}/../" />
223
    <echo message="Going to create default keystore in ${jnlp.signjar.keystore}" />
224
    <genkey 
225
        alias="${jnlp.signjar.alias}"
226
        keystore="${jnlp.signjar.keystore}"
227
        storepass="${jnlp.signjar.password}"
228
        dname="${jnlp.signjar.vendor}"
229
    />
230
  </target>
231
232
  <target name="build-jnlp" depends="init,jnlp-generate-keystore">
233
      <fail message="Property jnlp.codebase must be set to final location of your JNLP files!" unless="jnlp.codebase" />
234
      <property name="jnlp.dest.dir" location="build/jnlp" />
235
      <mkdir dir="${jnlp.dest.dir}" />
236
      <for-each startdir=".." target="jnlp" locations="${config.modules.jnlp}"/>
237
  </target>
238
  
239
  <target name="set-config-to-javadoc" >
240
      <property name="moduleconfig" value="javadoc" />
241
  </target>
242
243
  <!-- build javadoc for selected modules -->
244
  <target name="build-javadoc" depends="set-config-to-javadoc,init" description="Builds Javadoc documentation for modules; on branches pass e.g. -Djavadoc.web.root=http://www.netbeans.org/download/release35/javadoc">
245
      <ant dir="." target="merge">
246
          <property name="modules" value="${modules}"/>
247
          <property name="fixedmodules" value="${fixedmodules}"/>
248
          <property name="merge.dependent.modules" value="true"/>
249
          <property name="stop.when.broken.module" value="false"/>
250
      </ant>
251
      
252
      <mkdir dir="build/ModulesExportedInterfaces" />
253
      <property name="export.interfaces" location="build/ModulesExportedInterfaces" />
254
255
      <mkdir dir="build/APIChanges" />
256
      <property name="export.apichanges" location="build/APIChanges" />
257
            
258
      <!-- build javadoc for supported APIs -->
259
      <for-each startdir=".." target="javadoc" locations="${fixedmodules}"/>
260
      <!-- build javadoc for unsupported APIs -->
261
      <for-each startdir=".." target="javadoc" locations="${modules}"/>
262
      
263
      <antcall inheritall="true" inheritrefs="true" target="javadoc-generate-xml" />
264
      <antcall inheritall="true" inheritrefs="true" target="javadoc-generate-html" />
265
      <antcall inheritall="true" inheritrefs="true" target="javadoc-check-broken-links" />
266
  </target>  
267
      
268
  <target name="javadoc-generate-xml" depends="set-config-to-javadoc,init" >
269
      <echo file="build/APIChanges/header.gen" >&lt;?xml version="1.0" encoding="UTF-8"?&gt;
270
&lt;changes&gt;
271
</echo>
272
      
273
      <echo file="build/APIChanges/footer.gen" >
274
        &lt;/changes&gt;
275
      </echo>
276
      
277
      <concat destfile="${netbeans.javadoc.dir}/apichanges.xml" >
278
          <fileset dir="build/APIChanges" includes="header.gen" />
279
          <fileset dir="build/APIChanges" includes="*" excludes="*.gen" />
280
          <fileset dir="build/APIChanges" includes="footer.gen" />
281
      </concat>
282
283
      
284
      <echo file="build/ModulesExportedInterfaces/header.gen" >&lt;?xml version="1.0" encoding="UTF-8"?&gt;
285
&lt;apis&gt;
286
</echo>
287
      
288
      <echo file="build/ModulesExportedInterfaces/footer.gen" >
289
        &lt;/apis&gt;
290
      </echo>
291
      
292
      <concat destfile="${netbeans.javadoc.dir}/modules.xml" >
293
          <fileset dir="build/ModulesExportedInterfaces" includes="header.gen" />
294
          <fileset dir="build/ModulesExportedInterfaces" includes="*" excludes="*.gen" />
295
          <fileset dir="build/ModulesExportedInterfaces" includes="footer.gen" />
296
      </concat>
297
      
298
    <taskdef 
299
        name="javadoc-index" 
300
        classpath="nbantext.jar" 
301
        classname="org.netbeans.nbbuild.JavadocIndex"
302
    />
303
304
        
305
    <javadoc-index target="${netbeans.javadoc.dir}/allclasses.xml" > 
306
        <packageslist dir="${netbeans.javadoc.dir}" >
307
            <include name="**/allclasses-noframe.html" />
308
        </packageslist>
309
    </javadoc-index>
310
  </target>
311
  
312
  
313
  <target name="javadoc-generate-html" depends="set-config-to-javadoc,init" >            
314
      <tstamp>
315
        <format property="modules-javadoc-date" pattern="d MMM yyyy" locale="en" />
316
      </tstamp>
317
      
318
      <style 
319
        in="${netbeans.javadoc.dir}/modules.xml" 
320
        out="${netbeans.javadoc.dir}/usecases.html" 
321
        style="javadoctools/export2usecases.xsl"
322
      >
323
        <param name="date" expression="${modules-javadoc-date}"/>
324
      </style>
325
      
326
      <style 
327
        in="${netbeans.javadoc.dir}/apichanges.xml" 
328
        out="${netbeans.javadoc.dir}/apichanges.html" 
329
        style="javadoctools/export2apichanges.xsl"
330
      >
331
        <param name="date" expression="${modules-javadoc-date}"/>
332
        <param name="changes-since-year" expression="${previous.release.year}"/>
333
        <param name="changes-since-day" expression="${previous.release.day}"/>
334
        <param name="changes-since-month" expression="${previous.release.month}"/>
335
        <param name="include-introduction" expression="true" />
336
      </style>
337
      
338
    <copy file="javadoctools/netbeans.css" tofile="${netbeans.javadoc.dir}/netbeans.css" />
339
    <condition property="javadoc.style.sheet.exists" >
340
        <available file="${netbeans.javadoc.dir}/org-openide-util/javadoc.css" />
341
    </condition>
342
    
343
    <fail unless="javadoc.style.sheet.exists" >
344
    The org-openide-util/javadoc.css has to exist as we are refering to
345
    it from to master module javadoc pages. If it does not anymore, update
346
    the javadoctools/export*.xsl templates.
347
    </fail>
348
349
      <style 
350
        in="${netbeans.javadoc.dir}/allclasses.xml" 
351
        out="${netbeans.javadoc.dir}/allclasses-frame.html" 
352
        style="javadoctools/export2allclasses.xsl"
353
      >
354
      </style>
355
      
356
      <style 
357
        in="${netbeans.javadoc.dir}/modules.xml" 
358
        out="${netbeans.javadoc.dir}/overview-frame.html" 
359
        style="javadoctools/export2allmodules.xsl"
360
      >
361
        <param name="date" expression="${modules-javadoc-date}"/>
362
      </style>
363
      
364
      <style 
365
        in="${netbeans.javadoc.dir}/modules.xml" 
366
        out="${netbeans.javadoc.dir}/layers.html" 
367
        style="javadoctools/export2layer.xsl"
368
      >
369
        <param name="date" expression="${modules-javadoc-date}"/>
370
      </style>
371
      
372
      <style 
373
        in="${netbeans.javadoc.dir}/modules.xml" 
374
        out="${netbeans.javadoc.dir}/overview-summary.html" 
375
        style="javadoctools/export2html.xsl"
376
      >
377
        <param name="date" expression="${modules-javadoc-date}"/>
378
      </style>
379
      
380
      
381
    <!-- at the end geneate the index.html so people know where to start -->      
382
    <echo file="${netbeans.javadoc.dir}/index.html" ><![CDATA[
383
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
384
<HTML><HEAD><TITLE>NetBeans API Index</TITLE>
385
</HEAD>
386
<FRAMESET cols="20%,80%" title="" onLoad="top.loadFrames()">
387
<FRAMESET rows="30%,70%" title="" onLoad="top.loadFrames()">
388
<FRAME src="overview-frame.html" name="packageListFrame" title="All Modules">
389
<FRAME src="allclasses-frame.html" name="packageFrame" title="All classes">
390
</FRAMESET>
391
<FRAME src="overview-summary.html" name="classFrame" title="Module, package, class and interface descriptions" scrolling="yes">
392
<NOFRAMES>
393
<H2>Frame Alert</H2>
394
<P>
395
This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client.
396
Link to<A HREF="overview-summary.html">Non-frame version.</A>
397
</NOFRAMES>
398
</FRAMESET>
399
</HTML>
400
]]></echo>
401
402
        <replace dir="${netbeans.javadoc.dir}">
403
            <include name="*.html"/>
404
            <replacefilter token="@JDK@" value="http://java.sun.com/j2se/1.4.2/docs/api"/>
405
            <replacefilter token="http://root/" value="." />
406
            <replacefilter token="$${javadoc.web.root}" value="." />
407
        </replace>
408
    
409
    <echo message="Javadoc index has been generated to ${netbeans.javadoc.dir}/index.html" />
410
  </target>
411
  
412
  
413
  <target name="javadoc-check-broken-links" depends="init" unless="javadoc.skip.brokenlinks.check" >
414
        <taskdef name="checklinks" classname="org.netbeans.nbbuild.CheckLinks">
415
            <classpath>
416
                <pathelement location="nbantext.jar"/>
417
            </classpath>
418
        </taskdef>
419
        <checklinks basedir="${netbeans.javadoc.dir}" checkexternal="${javadoc.check.external.links}" checkspaces="false" failonerror="true" >
420
            <include name="*/overview-summary.html"/>
421
            <include name="*/apichanges.html"/>
422
            <include name="*/architecture-summary.html"/>
423
            <include name="*/**/package-summary.html"/>
424
            <include name="*/**/doc-files/**/*.html"/>
425
            <include name="*.html" />
426
        </checklinks>
427
  </target>
428
429
  <target name="build-messaging" depends="init">
430
    <echo message="Starting a build for NetBeans (build ${buildnum}, config '${moduleconfig}') ..."/>
431
    <echo message="Selected modules: ${modules}"/>
432
    <echo message="OS: ${os.name} ${os.version}  Locale: ${user.language}_${user.region}"/>
433
    <echo message="Java: ${nbjdk.home}"/>
434
  </target>
435
  
436
  <!-- Use of nbmerge target has the effect of automatically depending on all-X for every module. -->
437
  <!-- It also runs deltree(dir=wherever) and copydir(src=../X/netbeans,dest=wherever) to create the IDE install. -->
438
439
  <target name="build-nozip" depends="clean-cluster-flags,build-clusters" description="Build the IDE but do not create a final ZIP file.">
440
    <loadproperties srcFile="${clusters.list.file}" />
441
     
442
    <loadproperties srcfile="${netbeans.dest.dir}/moduleCluster.properties" />
443
        
444
    <mkdir dir="${netbeans.dest.dir}/bin" />
445
    <copy file="../ide/launcher/unix/netbeans" todir="${netbeans.dest.dir}/bin" />
446
    <chmod file="${netbeans.dest.dir}/bin/netbeans" perm="ugo+rx"/>
447
    <copy file="../ide/launcher/windows/netbeans.exe" todir="${netbeans.dest.dir}/bin" />
448
    <copy file="../ide/launcher/windows/nb.exe" todir="${netbeans.dest.dir}/bin" />
449
    <copy file="../ide/launcher/os2/netbeans.cmd" todir="${netbeans.dest.dir}/bin" />
450
    <!-- if anybody knows better place for icons, let me know: jtulach@netbeans.org -->
451
    <copy file="../ide/launcher/os2/nbos2icons.zip" todir="${netbeans.dest.dir}/${nb.cluster.nb.dir}/" />
452
453
    <mkdir dir="${netbeans.dest.dir}/etc" />
454
    <copy file="../ide/launcher/netbeans.conf" todir="${netbeans.dest.dir}/etc" />
455
456
    <echo message="${netbeans.dest.dir}/${nb.cluster.platform.dir}/lib/nbexec" />
457
    <fixcrlf eol="lf" srcdir="${netbeans.dest.dir}" >
458
      <include name="etc/netbeans.conf" />
459
      <include name="bin/netbeans" />      
460
      <include name="${nb.cluster.platform.dir}/lib/nbexec" />      
461
    </fixcrlf>
462
    <fixcrlf eol="crlf" srcdir="${netbeans.dest.dir}" >
463
      <include name="bin/netbeans.cmd" />      
464
      <include name="${nb.cluster.platform.dir}/lib/nbexec.cmd" />      
465
    </fixcrlf>
466
467
    <echo file="${netbeans.dest.dir}/build_info">NetBeans dev build
468
------------------
469
Number:   ${buildnumber}
470
Date:     ${buildday}
471
Branding:
472
Branch:   trunk
473
Tag:
474
    </echo>
475
  </target>
476
477
  <target name="build" depends="build-nozip"
478
          description="Create a complete build including a ZIP distribution (but do not try it).">
479
    <delete file="NetBeans-${buildnum}.zip"/>
480
    <delete file="NetBeans-${buildnum}-build-extra-data.zip"/>
481
482
    <property name="nb-extra-files" value="*.built,test/**,extra/**"/>
483
484
    <!-- package the zip file -->
485
    <zip destfile="NetBeans-${buildnum}.zip" update="true" duplicate="preserve">
486
      <zipfileset file="${netbeans.dest.dir}/bin/netbeans" filemode="755" prefix="${netbeans.dest}/bin"/>
487
      <zipfileset file="${netbeans.dest.dir}/${nb.cluster.platform.dir}/lib/nbexec" filemode="755" prefix="${netbeans.dest}/${nb.cluster.platform.dir}/lib"/>
488
      <zipfileset dir="${netbeans.dest.dir}/${nb.cluster.ide.dir}/ant/bin" filemode="755" prefix="${netbeans.dest}/${nb.cluster.ide.dir}/ant/bin">
489
        <exclude name="*.bat"/>
490
        <exclude name="*.cmd"/>
491
      </zipfileset>
492
      <zipfileset dir="${netbeans.dest.dir}" filemode="755" prefix="${netbeans.dest}">
493
        <include name="**/*.sh"/>
494
      </zipfileset>
495
      <zipfileset dir="${netbeans.dest.dir}" prefix="${netbeans.dest}" excludes="${nb-extra-files}">
496
        <!-- XXX exclude the temporary cluster for parts of openide -->
497
        <exclude name="tmp" />
498
        <exclude name="tmp/**/*" />
499
      </zipfileset>
500
    </zip>
501
    
502
    <!-- package the zip file with extra files not to be included in regular product package-->
503
    <!--
504
    <zip destfile="NetBeans-${buildnum}-build-extra-data.zip" update="true" duplicate="preserve">
505
        <zipfileset dir="${netbeans.dest.dir}" prefix="${netbeans.dest}" includes="${nb-extra-files}"/>
506
    </zip>
507
    -->
508
509
    <echo>Build created; see NetBeans-${buildnum}.zip (in nbbuild/).
510
If you like, you may run the IDE straight from
511
the ${netbeans.dest}/bin/ directory.
512
(For example, type: ant tryme)
513
    </echo>
514
  </target>
515
516
  <target name="delete-and-merge" depends="merge-delete,merge" />   
517
518
  <target name="merge-delete" depends="init">
519
    <delete dir="${netbeans.dest}" />
520
  </target>
521
  
522
  <target name="merge" depends="build-messaging">
523
    <mkdir dir="${netbeans.dest.dir}"/>
524
    <nbmerge failonerror="${stop.when.broken.modules}" 
525
             dest="${netbeans.dest}" 
526
             topdir=".." 
527
             fixedmodules="${fixedmodules}" 
528
             modules="${modules}"
529
             builtmodulesproperty="${built.modules.property}" 
530
             targetprefix="all-" 
531
             mergedependentmodules="${merge.dependent.modules}" >
532
    </nbmerge>
533
    <chmod perm="ugo+x">
534
      <fileset dir="${netbeans.dest.dir}">
535
        <include name="bin/netbeans"/>
536
        <include name="bin/**/*.pl"/>
537
        <include name="jakarta-tomcat-*/bin/*.sh"/>
538
      </fileset>
539
    </chmod>
540
  </target>
541
542
  <target name="build-platform" depends="init">
543
    <run-depend-build clusters-to-build="nb.cluster.platform,nb.cluster.harness"/>
544
  </target>
545
  
546
  <target name="build-cluster" depends="init">
547
    <run-depend-build clusters-to-build="${cluster-name}"/>
548
  </target>
549
550
  <macrodef name="resolve">
551
    <attribute name="name"/>
552
    <attribute name="value"/>
553
    <sequential>
554
      <property name="@{name}" value="${@{value}}"/>
555
    </sequential>
556
  </macrodef>
557
558
  <macrodef name="run-depend-build">
559
    <attribute name="clusters-to-build"/>
560
    <sequential>
561
      <echo>Repeat @{clusters-to-build}</echo>
562
      <repeat target="build-one-cluster" name="one.cluster.name" values="@{clusters-to-build}" /> 
563
    </sequential>
564
  </macrodef>
565
566
  <target name="build-clusters" depends="init">
567
     <run-depend-build clusters-to-build="${nb.clusters.list}"/> 
568
  </target>
569
570
  <target name="build-one-cluster-dependencies-check">
571
    <condition property="${one.cluster.name}-hasNoDependencies">
572
      <equals arg1="${one.cluster.dependencies}" arg2="" trim="true"/>
573
    </condition>
574
    <echo>Dependency prop :${one.cluster.name}-hasNoDependencies:</echo>
575
    <echo>Cluster dep :${one.cluster.dependencies}:</echo>
576
    <resolve name="test.prop" value="${one.cluster.name}-hasNoDependencies"/>
577
    <echo>Cluster dep prp:${test.prop}:</echo>
578
  </target>
579
580
  <target name="build-one-cluster-dependencies" 
581
          depends="build-one-cluster-dependencies-check"
582
          unless="${one.cluster.name}-hasNoDependencies">
583
    <run-depend-build clusters-to-build="${one.cluster.dependencies}"/> 
584
  </target>
585
586
  <target name="build-one-cluster-check">
587
    <condition property="${one.cluster.name}-is-built">
588
      <available file="${netbeans.dest.dir}/${one.cluster.name}.built"/>
589
    </condition>
590
    <resolve name="test1.prop" value="${one.cluster.name}-is-built"/>
591
    <echo>Cluster ${one.cluster.name} is :${test1.prop}:</echo>
592
  </target>
593
594
  <target name="build-one-cluster" unless="${one.cluster.name}-is-built" depends="build-one-cluster-check">
595
    <echo message="Building ${one.cluster.name} modules"/>
596
    <resolve name="one-cluster-modules" value="${one.cluster.name}"/>
597
    <resolve name="one-cluster-dependencies" value="${one.cluster.name}.depends"/>
598
    <echo>${one-cluster-modules}</echo>
599
    <echo>Dependencies: ${one-cluster-dependencies}</echo>
600
    <insert-module-all-targets/> <!-- we are in a subproject, so need to reinsert the targets... XXX <antcall> and thus <repeat> apparently reparses the Ant script from disk! -->
601
    <antcall target="build-one-cluster-dependencies" inheritAll="false">
602
      <param name="one.cluster.dependencies" value="${one-cluster-dependencies}"/>
603
      <param name="one.cluster.name" value="${one.cluster.name}"/>
604
    </antcall>
605
    <mkdir dir="${netbeans.dest.dir}"/>
606
    <nbmerge failonerror="${stop.when.broken.modules}" 
607
             dest="${netbeans.dest.dir}" 
608
             topdir="${nb_all}" 
609
             fixedmodules="${one-cluster-modules}"
610
             builtmodulesproperty="${built.modules.property}" 
611
             targetprefix="all-" 
612
             mergedependentmodules="false">
613
    </nbmerge>
614
    <touch file="${netbeans.dest.dir}/${one.cluster.name}.built"/>
615
  </target>
616
617
  <target name="zipclusters" depends="init">
618
    <mkdir dir="${netbeans.build.dir}/zips"/>
619
    <repeat target="zip-one-cluster" name="one.cluster.name" values="${clusters.list}" /> 
620
621
    <!-- package the misc files -->
622
    <zip destfile="${netbeans.build.dir}/zips/${clusters.prefix}-misc-${buildnum}.zip" update="true" duplicate="preserve">
623
      <zipfileset dir="${netbeans.dest.dir}" filemode="755">
624
         <include name="bin/netbeans"/>
625
      </zipfileset>
626
      <zipfileset dir="${netbeans.dest.dir}">
627
        <include name="bin/**"/>
628
        <include name="etc/**/"/>
629
      </zipfileset>
630
    </zip>
631
  </target>
632
633
  <target name="zip-one-cluster">
634
    <taskdef name="setclusterpatternset" classname="org.netbeans.nbbuild.SetClusterPatternSet" classpath="nbantext.jar"/>
635
    <taskdef name="setcluster" classname="org.netbeans.nbbuild.SetCluster" classpath="nbantext.jar"/>
636
    <loadproperties srcFile="${clusters.list.file}" />
637
    <loadproperties srcFile="cluster-description.properties" />
638
    <setcluster cluster="${one.cluster.name}" name="one.cluster.dir" />
639
    
640
    <setclusterpatternset cluster="${one.cluster.name}" name="${one.cluster.name}.files" trackingpath="${netbeans.dest.dir}" clusterdir="${one.cluster.dir}"/>
641
    
642
    <resolve name="zipcluster.file" value="${one.cluster.name}.pkg.filename"/>
643
    <zip destfile="${netbeans.build.dir}/zips/${clusters.prefix}-${zipcluster.file}-${buildnum}.zip" update="true" duplicate="preserve">
644
      <zipfileset dir="${netbeans.dest.dir}" filemode="755">
645
        <include name="${one.cluster.dir}/lib/nbexec"/>
646
      </zipfileset>
647
      <zipfileset dir="${netbeans.dest.dir}" filemode="755">
648
        <include name="${one.cluster.dir}/ant/bin/*"/>
649
        <exclude name="${one.cluster.dir}/ant/bin/*.bat"/>
650
        <exclude name="${one.cluster.dir}/ant/bin/*.cmd"/>
651
      </zipfileset>
652
      <zipfileset dir="${netbeans.dest.dir}">
653
        <patternset refID="${one.cluster.name}.files"/>
654
      </zipfileset>
655
    </zip>
656
  </target>
657
658
  <target name="create-rpms-proto">
659
    <mkdir dir="${netbeans.build.dir}/rpms"/>
660
    <repeat target="create-one-rpm-proto" name="one.cluster.name" values="${clusters.list}" /> 
661
  </target>
662
    
663
  <target name="create-one-rpm-proto">
664
    <taskdef name="setcluster" classname="org.netbeans.nbbuild.SetCluster" classpath="nbantext.jar"/>
665
    <loadproperties srcFile="cluster.properties" />
666
    <loadproperties srcFile="cluster-description.properties" />
667
    <setcluster cluster="${one.cluster.name}" name="one.cluster.dir" />
668
    <mkdir dir="${netbeans.build.dir}/rpms"/>
669
    
670
    <resolve name="pkg.name" value="${one.cluster.name}.pkg.name"/>
671
    <resolve name="pkg.version" value="${one.cluster.name}.pkg.version"/>
672
    <resolve name="pkg.desc" value="${one.cluster.name}.pkg.desc"/>
673
    <resolve name="pkg.vendor" value="${one.cluster.name}.pkg.vendor"/>
674
    <resolve name="pkg.email" value="${one.cluster.name}.pkg.email"/>
675
    <resolve name="pkg.rpm.name" value="${one.cluster.name}.pkg.rpm.name"/>
676
    <resolve name="pkg.rpm.requires" value="${one.cluster.name}.pkg.rpm.requires"/>
677
    <resolve name="pkg.rpm.group" value="${one.cluster.name}.pkg.rpm.group"/>
678
    <resolve name="pkg.rpm.url" value="${one.cluster.name}.pkg.rpm.url"/>
679
    <resolve name="pkg.rpm.copyright" value="${one.cluster.name}.pkg.rpm.copyright"/>
680
    <resolve name="pkg.rpm.map" value="${one.cluster.name}.pkg.rpm.map"/>
681
    <resolve name="pkg.rpm.prefix" value="${one.cluster.name}.pkg.rpm.prefix"/>
682
    
683
    <echo file="${netbeans.build.dir}/rpms/${pkg.rpm.name}.spec">
684
%define global_product_version ${pkg.version}
685
%define global_product_release 00
686
%define _prefix ${pkg.rpm.prefix}
687
Version: %{global_product_version}
688
Release: %{global_product_release}
689
Group: ${pkg.rpm.group}
690
Copyright: ${pkg.rpm.copyright}
691
Vendor: ${pkg.vendor}
692
URL: ${pkg.rpm.url}
693
Prefix: %_prefix
694
AutoReqProv: no
695
Name: ${pkg.rpm.name}
696
Summary: ${pkg.name}
697
%description 
698
${pkg.desc}
699
700
%files
701
702
%erpm_map ${pkg.rpm.map} nb_destdir
703
704
%dir ${pkg.rpm.map}
705
706
${pkg.rpm.map}/${one.cluster.dir}</echo>
707
  </target>
708
709
  <target name="create-svr4s-proto">
710
    <mkdir dir="${netbeans.build.dir}/rpms"/>
711
    <repeat target="create-one-svr4-proto" name="one.cluster.name" values="${clusters.list}" /> 
712
  </target>
713
714
  <target name="create-one-svr4-proto">
715
    <taskdef name="setcluster" classname="org.netbeans.nbbuild.SetCluster" classpath="nbantext.jar"/>
716
    <loadproperties srcFile="cluster.properties" />
717
    <loadproperties srcFile="cluster-description.properties" />
718
    <setcluster cluster="${one.cluster.name}" name="one.cluster.dir" />
719
    <mkdir dir="${netbeans.build.dir}/svr4s"/>
720
    
721
    <resolve name="pkg.name" value="${one.cluster.name}.pkg.name"/>
722
    <resolve name="pkg.version" value="${one.cluster.name}.pkg.version"/>
723
    <resolve name="pkg.desc" value="${one.cluster.name}.pkg.desc"/>
724
    <resolve name="pkg.vendor" value="${one.cluster.name}.pkg.vendor"/>
725
    <resolve name="pkg.email" value="${one.cluster.name}.pkg.email"/>
726
    <resolve name="pkg.svr4.pkg" value="${one.cluster.name}.pkg.svr4.pkg"/>
727
    <resolve name="pkg.svr4.maxinst" value="${one.cluster.name}.pkg.svr4.maxinst"/>
728
    <resolve name="pkg.svr4.sunw_pkgvers" value="${one.cluster.name}.pkg.svr4.sunw_pkgvers"/>
729
    <resolve name="pkg.svr4.hotline" value="${one.cluster.name}.pkg.svr4.hotline"/>
730
    <resolve name="pkg.svr4.classes" value="${one.cluster.name}.pkg.svr4.classes"/>
731
    <resolve name="pkg.svr4.basedir" value="${one.cluster.name}.pkg.svr4.basedir"/>
732
    <resolve name="pkg.svr4.pkginst" value="${one.cluster.name}.pkg.svr4.pkginst"/>
733
    <resolve name="pkg.svr4.category" value="${one.cluster.name}.pkg.svr4.category"/>
734
<echo file="${netbeans.build.dir}/svr4s/${pkg.svr4.pkg}.spec">
735
PKG=${pkg.svr4.pkg}
736
NAME=${pkg.name}
737
ARCH=sparc
738
VERSION=${pkg.version}
739
MAXINST=${pkg.svr4.maxinst}
740
CATEGORY=${pkg.svr4.category}
741
SUNW_PKGVERS=${pkg.svr4.sunw_pkgvers}
742
DESC=${pkg.desc}
743
VENDOR=${pkg.vendor}
744
HOTLINE=${pkg.svr4.hotline}
745
EMAIL=${pkg.email}
746
CLASSES=${pkg.svr4.classes}
747
BASEDIR=${pkg.svr4.basedir}
748
PKGINST=${pkg.svr4.pkginst}</echo>
749
  </target>
750
    
751
  <target name="sanity-check" depends="testuserdir-delete,sanity-start" description="Test whether the build can start up without problems."/>
752
    <target name="-testuserdir-delete-init" depends="init">
753
      <property name="test.user.dir.lock" location="${test.user.dir}/lock"/>
754
      <available property="app.running" file="${test.user.dir.lock}"/>
755
    </target>
756
    <target name="-testuserdir-delete-ok" depends="-testuserdir-delete-init" unless="app.running">
757
      <delete dir="${test.user.dir}"/>
758
    </target>
759
    <target name="-testuserdir-delete-fail" depends="-testuserdir-delete-init" if="app.running">
760
      <!-- #66799: best to warn about this condition... -->
761
      <fail>Will not delete ${test.user.dir} because ${test.user.dir.lock} still exists; kill any running process and delete lock file if necessary</fail>
762
    </target>
763
  <target name="testuserdir-delete" depends="-testuserdir-delete-ok,-testuserdir-delete-fail"/>
764
  <target name="sanity-start" depends="init,maybe-build-nozip,-jdk-init">
765
    <mkdir dir="${test.user.dir}"/>
766
    <echo>Starting the IDE as a sanity check...</echo>
767
    <echo>WARNING - the sanity-start target is deprecated. Use commit-validation instead.</echo>
768
    <!-- XXX better would be to scan start log for stacktraces and just show those; -->
769
    <!-- possibly after filtering for duplicates or something like this. -->
770
    <!-- Timeout is ten minutes; should be enough for valid start, while preventing -->
771
    <!-- a deadlock from hanging an automated build: -->
772
    <exec os="Windows NT Windows 95 Windows 98 Windows 2000 Windows 2003 Windows XP" executable="${netbeans.dest.abs}/bin/nb.exe" failonerror="yes" timeout="600000">
773
      <arg value="--jdkhome"/>
774
      <arg file="${nbjdk.home}"/>
775
      <arg value="--userdir"/>
776
      <arg file="${test.user.dir}"/>
777
      <arg line="${sanitystart.args}"/>
778
    </exec>
779
    <exec os="Linux SunOS Solaris Mac OS X" dir="." executable="sh" failonerror="yes" timeout="600000">
780
      <arg value="${netbeans.dest.abs}/bin/netbeans"/>
781
      <arg value="--jdkhome"/>
782
      <arg file="${nbjdk.home}"/>
783
      <arg value="--userdir"/>
784
      <arg file="${test.user.dir}"/>
785
      <arg line="${sanitystart.args}"/>
786
    </exec>
787
    <echo>Finished starting the IDE, pay attention to any reported errors.</echo>
788
  </target>
789
790
  <target name="check-for-build"  >
791
    <available property="have-build" file="${netbeans.dest.dir}/bin/netbeans"/>
792
  </target>
793
  <target name="maybe-build-nozip" depends="check-for-build" unless="have-build">
794
    <ant dir="${basedir}" target="build-nozip"/>
795
  </target>
796
797
  <target name="nozip-check" 
798
          depends="build-nozip,sanity-check">
799
    <echo>WARNING - the nozip-check target is deprecated. Use all-nozip instead.</echo>
800
  </target>
801
802
  <target name="tryme-setup-debug-args" if="debug.port" >
803
    <property name="debug.pause" value="n" />
804
    <property name="debug.server" value="y" />
805
    
806
    <property name="tryme.debug.args" value="-J-Xdebug -J-Xnoagent -J-Xrunjdwp:transport=dt_socket,suspend=${debug.pause},server=${debug.server},address=${debug.port}" />
807
  </target>
808
          
809
  <target name="tryme-debug" depends="-jdk-presetdef-nbjpdastart" description="Start IDE in debugger. May only be called from within IDE.">
810
    <nbjpdastart name="NetBeans" addressproperty="debug.port" transport="dt_socket">
811
      <classpath>
812
        <fileset dir="${netbeans.dest.dir}">
813
          <include name="**/*.jar"/>
814
        </fileset>
815
      </classpath>
816
    </nbjpdastart>
817
    <property name="debug.server" value="n"/>
818
    <antcall target="tryme"/>
819
  </target>
820
    
821
  <target name="tryme-profile" depends="-jdk-presetdef-nbprofiledirect" description="Start IDE in debugger. May only be called from within IDE.">
822
    <property name="profiler.roots.path" value="profiler.roots.all" />
823
    <fileset id="profiler.roots.all" dir="${netbeans.dest.dir}">
824
        <include name="**/*.jar"/>
825
    </fileset>
826
    <nbprofiledirect 
827
        jvmargsprefix="-J" 
828
        jvmargsproperty="profiler.jvmargs" 
829
        mainclass="org.netbeans.Main"
830
    >
831
      <classpath>
832
        <fileset dir="${netbeans.dest.dir}">
833
          <include name="**/*.jar"/>
834
        </fileset>
835
      </classpath>
836
      <rootspath>
837
          <fileset refid="${profiler.roots.path}" />
838
      </rootspath>
839
    </nbprofiledirect>
840
    
841
    <antcall target="tryme">
842
        <param name="tryme.args" value="${profiler.jvmargs}"/>
843
    </antcall>
844
  </target>
845
  
846
  <target name="tryme" depends="init,maybe-build-nozip,tryme-setup-debug-args,-jdk-init"
847
          description="Try running the IDE interactively (build it first if needed).
848
It is possible to use -Ddebug.port=3234 -Ddebug.pause=y to start the system in debug mode" 
849
   >
850
    <property name="tryme.debug.args" value="" />
851
  
852
    <exec os="Windows NT Windows 95 Windows 98 Windows 2000 Windows 2003 Windows XP" executable="${netbeans.dest.abs}/bin/nb.exe" failonerror="yes">
853
      <arg value="--jdkhome"/>
854
      <arg file="${nbjdk.home}"/>
855
      <arg value="--userdir"/>
856
      <arg file="${test.user.dir}"/>
857
      <arg line="${tryme.args}"/>
858
      <arg line="${tryme.debug.args}" />
859
    </exec>
860
    <exec os="Linux SunOS Solaris Mac OS X" dir="." executable="sh" failonerror="yes">
861
      <arg value="${netbeans.dest}/bin/netbeans"/>
862
      <arg value="--jdkhome"/>
863
      <arg file="${nbjdk.home}"/>
864
      <arg value="--userdir"/>
865
      <arg file="${test.user.dir}"/>
866
      <arg line="${tryme.args}"/>
867
      <arg line="${tryme.debug.args}" />
868
    </exec>
869
  </target>
870
  
871
  <target name="l10n-kit" depends="init">
872
    <taskdef name="l10n" classname="org.netbeans.nbbuild.L10nTask"
873
             classpath="nbantext.jar"/>
874
    <delete dir="${l10n.dist.dir}"/>
875
    <mkdir dir="${l10n.dist.dir}"/>
876
    <delete dir="tmp"/>
877
    <mkdir dir="tmp"/>
878
    <property name="nbroot" location=".."/>
879
    <l10n topdirs="${nbroot}" modules="${fixedmodules},${modules}"
880
          localizablefile="l10n.list" generatedfile="l10n.list.translated"
881
          distdir="${l10n.dist.dir}" changedfile="l10n.list.changed"
882
          builddir="tmp" buildnumber="${buildnumber}"
883
          excludepattern="**/ja/,**/*_ja.*"/>
884
    <delete dir="tmp"/>
885
  </target>
886
887
  <target name="bootstrap-javadoc"
888
          depends="bootstrap"
889
          description="Generate Javadoc for Ant extensions.">
890
    <!-- XXX this ought to be deleted at some point. -->
891
    <!-- Can be done anyway by apisupport/ant, and published as regular module Javadoc -->
892
    <!-- by the regular daily Javadoc build process. -->
893
    <!-- Then all of this stuff can be deleted from the www part of CVS. -->
894
    <mkdir dir="www/nbantext-javadoc"/>
895
    <delete>
896
        <fileset dir="www/nbantext-javadoc">
897
            <include name="**/*.html"/>
898
        </fileset>
899
    </delete>
900
    <tstamp/>
901
    <javadoc sourcepath="antsrc"
902
             destdir="www/nbantext-javadoc"
903
             packagenames="org.netbeans.nbbuild.*"
904
             windowtitle="NetBeans Ant Extensions"
905
             doctitle="Extended Ant Tasks for Building NetBeans"
906
             nodeprecatedlist="true"
907
             notree="true"
908
             noindex="true"
909
             nohelp="true"
910
             nonavbar="true"
911
             author="false"
912
             version="false"
913
             bottom="Built on ${buildday}"
914
    >
915
      <classpath refid="bootstrap-cp"/>
916
      <link href="http://nagoya.apache.org/gump/javadoc/ant/build/javadocs" offline="true" packagelistloc="antsrc"/>
917
    </javadoc>
918
  </target>
919
920
  <target name="clean-external">
921
    <subant target="clean">
922
      <fileset dir="..">
923
        <include name="*/external/build.xml"/>
924
        <include name="contrib/*/external/build.xml"/>
925
      </fileset>
926
    </subant>
927
  </target>
928
929
  <target name="real-clean" depends="clean,clean-external"
930
          description="Clean everything possible.">
931
    <echo message="Cleaning old builds..."/>
932
    <delete>
933
      <fileset dir=".">
934
        <include name="NetBeans-*.log"/>
935
        <include name="NetBeans-*.zip"/>
936
      </fileset>
937
    </delete>
938
    <!-- This step must be last: -->
939
    <echo message="Cleaning NetBeans-specific Ant extensions..."/>
940
    <delete file="nbantext.jar" quiet="true"/>
941
    <delete dir="build/antclasses"/>
942
  </target>
943
  
944
  <target name="ant-clean">
945
    <delete file="nbantext.jar"/>
946
  </target>
947
948
  <target name="clean-cluster-flags" unless="do-not-rebuild-clusters">
949
    <mkdir dir="${netbeans.dest.dir}"/>
950
    <delete includeEmptyDirs="true">
951
      <fileset dir="${netbeans.dest.dir}">
952
        <include name="*.built"/>
953
      </fileset>
954
    </delete>
955
  </target>
956
957
  <target name="localclean" depends="clean-cluster-flags,init">
958
    <delete dir="${test.user.dir}"/>
959
    <delete dir="build"/>
960
    <delete file="moduledefs-tmp.properties"/>
961
    <delete dir="nbms" />
962
    <delete dir="${netbeans.dest.dir}"/>
963
  </target>
964
  
965
  <!-- more correct but takes too long: <target name="localtest" depends="bootstrap,all-xtest/nbjunit" > -->
966
  <target name="localtest" depends="bootstrap">
967
    <ant dir="test" target="cleanresults"/>
968
    <ant dir="test" target="runtests"/>
969
  </target>
970
  <target name="localtest-nb" depends="localtest">
971
    <nbbrowse file="test/results/index.html"/>
972
  </target>
973
  <target name="localtest-single-nb" depends="bootstrap">
974
    <property name="unit.test.base" location="test/unit/src"/>
975
    <pathconvert property="xtest.includes" pathsep=",">
976
        <path path="${includes}"/>
977
        <mapper type="glob" from="${unit.test.base}${file.separator}*.java" to="*.class"/>
978
    </pathconvert>
979
    <property name="xtest.attribs" value="empty"/>
980
    <ant dir="test" target="cleanresults"/>
981
    <ant dir="test" target="runtests"/>
982
    <nbbrowse file="test/results/index.html"/>
983
  </target>
984
  <target name="localtest-single-nb-debug" depends="bootstrap,-jdk-presetdef-nbjpdastart">
985
    <property name="unit.test.base" location="test/unit/src"/>
986
    <pathconvert property="xtest.includes" pathsep=",">
987
        <path path="${includes}"/>
988
        <mapper type="glob" from="${unit.test.base}${file.separator}*.java" to="*.class"/>
989
    </pathconvert>
990
    <property name="xtest.attribs" value="empty"/>
991
    <ant dir="test" target="cleanresults"/>
992
    <nbjpdastart transport="dt_socket" addressproperty="jpda.address" name="${test.class}">
993
        <classpath>
994
            <!--
995
            <path location="test/work/sys/tests/unit/classes"/>
996
            <path location="test/work/sys/tests/"/>
997
            <path location="test/unit/src/"/>
998
            -->
999
            <path location="nbantext.jar"/>
1000
        </classpath>
1001
    </nbjpdastart>
1002
    <ant dir="test" target="runtests">
1003
        <property name="xtest.debug.address" value="${jpda.address}" />
1004
        <property name="xtest.debug.pause" value="false" />
1005
    </ant>
1006
    <nbbrowse file="test/results/index.html"/>
1007
  </target>
1008
1009
  <target name="cleanall" depends="init">
1010
    <cleanall topdir=".." 
1011
              modules="${allmodules}" 
1012
              targetname="clean"
1013
              resolvedependencies="${resolve.clean.dependencies}"
1014
              deptargetprefix="all-"
1015
              failonerror="${stop.when.clean.error}" />
1016
  </target>
1017
1018
  <target name="clean" depends="init,cleanall,localclean"
1019
          description="Clean out (almost) all build products.">
1020
    <echo message="Run `ant real-clean' if desired."/>
1021
  </target>
1022
1023
<!-- This section contains properties and targets used to build -->
1024
<!-- Solaris packages.                                          -->
1025
1026
  <property name="solpkg-pkgproto" value="pkgproto"/>
1027
  <property name="solpkg-pkgmk" value="pkgmk"/>
1028
  <property name="solpkg-proto-file" value="prototype"/>
1029
  <property name="solpkg-actual-dir" value="to-be-specified"/>
1030
  <property name="solpkg-pkg-dir" value="to-be-specified"/>
1031
  <property name="solpkg-pkg-dest-dir" value="to-be-specified"/>
1032
1033
  <!-- You can run this target to create the prototype file and create -->
1034
  <!-- the package, or if you need to modify the prototype file before -->
1035
  <!-- building the package, you can run the two subtargets            -->
1036
  <!-- separately.                                                     -->
1037
  <target name="solpkg-build" depends="solpkg-pkgproto,solpkg-pkgmk"
1038
          description="Generate a prototype file and create a Solaris package."/>
1039
1040
  <!-- This creates the pkg prototype file for a given directory and -->
1041
  <!-- its files.                                                    -->
1042
  <target name="solpkg-pkgproto"
1043
          description="Generate a prototype file.">
1044
    <exec executable="rm" failonerror="yes">
1045
      <arg value="-rf"/>
1046
      <arg value="${solpkg-proto-file}"/>
1047
    </exec>
1048
    <exec executable="${solpkg-pkgproto}" output="${solpkg-proto-file}" 
1049
          failonerror="yes">
1050
      <arg value="${solpkg-actual-dir}=${solpkg-pkg-dir}"/>
1051
    </exec>
1052
  </target>
1053
1054
  <!-- This creates the Solaris pkg for a given prototype file, pkginfo -->
1055
  <!-- file, and directory.                                             -->
1056
  <target name="solpkg-pkgmk"
1057
          description="Create a Solaris package.">
1058
    <exec executable="${solpkg-pkgmk}" failonerror="yes">
1059
      <arg value="-o"/>
1060
      <arg value="-f"/>
1061
      <arg value="${solpkg-proto-file}"/>
1062
      <arg value="-r"/>
1063
      <arg value="${solpkg-actual-dir}"/>
1064
      <arg value="-d"/>
1065
      <arg value="${solpkg-pkg-dest-dir}"/>
1066
    </exec>
1067
  </target>
1068
1069
<!-- End of Solaris package section. -->
1070
1071
1072
<!-- Localized builds -->
1073
  <target name="all-dutch" depends="set-dutch-locale,all"/>
1074
  <target name="all-russian" depends="set-russian-locale,all"/>
1075
  <target name="all-french" depends="set-french-locale,all"/>
1076
  <target name="all-ja-zh" depends="set-ja-zh_CN-locales,all"/>
1077
  
1078
  <target name="set-ja-zh_CN-locales">
1079
        <property name="locales" value="ja,zh_CN"/>
1080
        <property name="locjar.locales" value="${locales}"/>
1081
        <property name="locmakenbm.locales"   value="${locales}"/>
1082
        <property name="locjhindexer.locales" value="${locales}"/>
1083
        <property name="localized.build.locales" value="${locales}"/>
1084
  </target>
1085
  
1086
  <target name="set-dutch-locale">
1087
        <property name="locales" value="nl"/>
1088
        <property name="locjar.locales" value="${locales}"/>
1089
        <property name="locmakenbm.locales"   value="${locales}"/>
1090
        <property name="locjhindexer.locales" value="${locales}"/>
1091
        <property name="localized.build.locales" value="${locales}"/>
1092
  </target>
1093
1094
  <target name="set-russian-locale">
1095
        <property name="locales" value="ru"/>
1096
        <property name="locjar.locales" value="${locales}"/>
1097
        <property name="locmakenbm.locales"   value="${locales}"/>
1098
        <property name="locjhindexer.locales" value="${locales}"/>
1099
        <property name="localized.build.locales" value="${locales}"/>
1100
  </target>
1101
1102
  <target name="set-french-locale">
1103
        <property name="locales" value="fr"/>
1104
        <property name="locjar.locales" value="${locales}"/>
1105
        <property name="locmakenbm.locales"   value="${locales}"/>
1106
        <property name="locjhindexer.locales" value="${locales}"/>
1107
        <property name="localized.build.locales" value="${locales}"/>
1108
  </target>
1109
  
1110
<!-- end of localized builds -->
1111
1112
1113
  <target name="print-selected-modules" depends="init" description="Prints list of modules to build in selected moduleconfig.">
1114
    <echo message="modules=${allmodules}"/>
1115
  </target>
1116
1117
  <target name="print-cvs-modules" depends="init" description="Prints list of cvs modules required to build in selected moduleconfig.">
1118
    <taskdef name="printcvsmodules" classname="org.netbeans.nbbuild.PrintCvsModules" classpath="nbantext.jar"/>
1119
    <printcvsmodules modules="${fixedmodules},${modules}" targetprefix="all-" />
1120
  </target>
1121
1122
  <target name="check-commit-validation">
1123
    <condition property="run.validation" >
1124
        <and>
1125
          <available file="../ide/test/build.xml" />
1126
          <available file="../jemmy/build.xml" />
1127
          <available file="../jellytools/build.xml" />
1128
          <available file="../xtest/build.xml" />
1129
          <or>
1130
            <not>
1131
              <isset property="nb.run.validation"/>
1132
            </not>
1133
            <istrue value="${nb.run.validation}"/>
1134
          </or>
1135
        </and>
1136
    </condition>
1137
  </target>
1138
  
1139
  <target 
1140
    name="unit-validation" 
1141
    description="Invokes all existing unit tests in all IDE modules.
1142
 Useful when one wants to deeply verify that his changes
1143
 work"
1144
  >
1145
    <ant dir="../xtest/instance" target="runtests" >
1146
      <property name="xtest.config" value="unit-nb" />
1147
    </ant>
1148
  </target>
1149
  
1150
  <target 
1151
    name="commit-validation" 
1152
    depends="commit-verification,commitValidation,no-commit-validation" 
1153
    description="Runs tests to validate IDE before commit."
1154
  />
1155
1156
  <target name="all-commitValidation" description="dummy target for build error recognition facility"/>
1157
  
1158
  <target 
1159
    name="commit-verification" 
1160
    description="Compares result of a build with golden files verifying various aspects of the exported interfaces"
1161
    depends="
1162
    all-verification,
1163
    check-files-layout,
1164
    check-public-packages,
1165
    check-friend-packages,
1166
    check-shared-packages,
1167
    check-modules,
1168
    check-dependencies,
1169
    check-implementation-dependencies,
1170
    check-cluster-dependencies,
1171
    check-cluster-implementation-dependencies,
1172
    check-clusters-content"
1173
  />
1174
  
1175
  <!-- JST: One day also add 
1176
    check-external-libraries
1177
  -->
1178
  
1179
  <target name="all-verification" >
1180
    <echo message="Runs verification tests to check the IDE before commit" />
1181
  </target>
1182
1183
  <!-- keep this target name at least for a while for backward compat -jglick -->
1184
  <target name="commitValidation" depends="all-commitValidation,check-commit-validation" if="run.validation">
1185
    <property name="xtest.home" location="../xtest"/>
1186
    <ant dir="${xtest.home}/instance" target="cleanresults">
1187
        <property name="xtest.config" value="commit-validation-nb"/>
1188
    </ant>
1189
    <ant dir="${xtest.home}/instance" target="cleantests">
1190
        <property name="xtest.config" value="commit-validation-nb"/>
1191
    </ant>
1192
    <ant dir="${xtest.home}/instance" target="runtests">
1193
        <property name="xtest.config" value="commit-validation-nb"/>
1194
        <property name="xtest.fail.on.failure" value="true"/>
1195
    </ant>
1196
  </target>
1197
1198
  <target name="no-commit-validation" depends="check-commit-validation" unless="run.validation">
1199
    <echo>
1200
        *** WARNING ***
1201
        You do not seem to have the modules needed to run the commit validation test suite. 
1202
        You may not commit any changes into the CVS repository without running these tests.
1203
        For more information: http://www.netbeans.org/community/guidelines/commit.html
1204
    </echo>
1205
  </target>
1206
1207
  <target name="sanity-build-from-source-pkg" depends="build-source">
1208
    <available file="${netbeans.build.dir}/${cluster.name}-src-${buildnum}.zip"
1209
               property="pkg.available"/>
1210
    <fail message="Source package ${netbeans.build.dir}/${cluster.name}-src-${buildnum}.zip not available" unless="pkg.available"/>
1211
    <delete dir="testbuild"/>
1212
    <mkdir dir="testbuild"/>
1213
    <unzip dest="testbuild" src="${netbeans.build.dir}/${cluster.name}-src-${buildnum}.zip"/>
1214
    <property name="one.cluster.name" value="${cluster.name}"/>
1215
    <propertyset id="sanity-build">
1216
      <propertyref name="one.cluster.name"/>
1217
    </propertyset>
1218
    <echoproperties destfile="testbuild/nbbuild/user.properties">
1219
        <propertyset refid="sanity-build"/>
1220
    </echoproperties>
1221
1222
    <!-- it should call build of the refered cluster and not just hardcoded platform -->
1223
    <ant antfile="testbuild/nbbuild/build.xml" inheritall="false" target="build-one-cluster">
1224
      <property file="testbuild/nbbuild/user.properties"/>
1225
    </ant>
1226
    <delete dir="testbuild"/>
1227
  </target>
1228
1229
  <target name="build-source"
1230
    depends="init,set-buildnumber"
1231
    description="Packages sources needed to compile given by cluster.name (can be specified by -Dcluster.name=nb.cluster.platform"
1232
    if="cluster.name"
1233
  >
1234
    <property name="buildnum" value="dev-${buildnumber}"/>
1235
    <echo message="Packaging sources of ${cluster.name} modules"/>
1236
    <resolve name="cluster-modules" value="${cluster.name}"/>
1237
    <resolve name="harness-modules" value="nb.cluster.harness"/>
1238
    <mkdir dir="${netbeans.build.dir}"/>
1239
    <taskdef name="definefileset" classname="org.netbeans.nbbuild.PrintCvsModules" classpath="nbantext.jar"/>
1240
    <definefileset modules="${cluster-modules}" targetprefix="all-" id="source-modules" dir=".." />
1241
    <definefileset modules="${cluster-modules}" targetprefix="all-" id="external-modules" dir=".." mode="binaries" />
1242
    <definefileset modules="${harness-modules}" targetprefix="all-" id="harness-source-modules" dir=".." />
1243
    <definefileset modules="${harness-modules}" targetprefix="all-" id="harness-external-modules" dir=".." mode="binaries" />
1244
    <zip zipfile="${netbeans.build.dir}/${cluster.name}-src-${buildnum}.zip" duplicate="preserve">
1245
      <fileset refid="source-modules" />
1246
      <fileset refid="external-modules" />
1247
      <fileset refid="harness-source-modules" />
1248
      <fileset refid="harness-external-modules" />
1249
    </zip>
1250
  </target>
1251
  
1252
  <target name="generate-golden-files-init" depends="init,bootstrap" >
1253
    <property name="template.files.dir" location="build/golden" />
1254
    <property name="golden.files.dir" location="../ide/golden" />
1255
    <condition property="golden.files.eol" value="unix" >
1256
        <or>
1257
            <os family="unix" />
1258
            <os family="mac" />
1259
        </or>
1260
    </condition>
1261
    <property name="golden.files.eol" value="dos" />
1262
    
1263
    <mkdir dir="${template.files.dir}" />
1264
    
1265
    <!-- convert the golden files into platform default encoding -->
1266
    <fixcrlf srcdir="${golden.files.dir}" destdir="${template.files.dir}" eol="${golden.files.eol}" >
1267
        <include name="*txt" />
1268
    </fixcrlf>
1269
    
1270
  </target>
1271
  
1272
  
1273
  <target name="generate-golden-files" depends="generate-golden-files-init" >
1274
    <property name="generated.files.dir" location="build/generated" />
1275
    <mkdir dir="${generated.files.dir}" />
1276
    
1277
    <taskdef name="deps" classname="org.netbeans.nbbuild.ModuleDependencies" classpath="nbantext.jar"/>
1278
    
1279
    <deps>
1280
      <input name="platform" >
1281
        <jars dir="${netbeans.dest.dir}" >
1282
          <include name="${nb.cluster.platform.dir}/**/*.jar" />
1283
        </jars>
1284
      </input>
1285
      <input name="ide" >
1286
        <jars dir="${netbeans.dest.dir}" >
1287
          <include name="${nb.cluster.ide.dir}/**/*.jar" />
1288
        </jars>
1289
      </input>
1290
      <input name="j2ee" >
1291
        <jars dir="${netbeans.dest.dir}" >
1292
          <include name="${nb.cluster.j2ee.dir}/**/*.jar" />
1293
        </jars>
1294
      </input>
1295
      <input name="nb" >
1296
        <jars dir="${netbeans.dest.dir}" >
1297
          <include name="${nb.cluster.nb.dir}/**/*.jar" />
1298
        </jars>
1299
      </input>
1300
      <input name="harness" >
1301
        <jars dir="${netbeans.dest.dir}" >
1302
          <include name="${nb.cluster.harness.dir}/**/*.jar" />
1303
        </jars>
1304
      </input>
1305
      
1306
      <output type="group-dependencies" file="${generated.files.dir}/cluster-deps.txt" />
1307
      <output type="group-implementation-dependencies" file="${generated.files.dir}/cluster-impl-deps.txt" />
1308
      <output type="modules" file="${generated.files.dir}/modules.txt" />
1309
      <output type="dependencies" file="${generated.files.dir}/deps.txt" />
1310
      <output type="implementation-dependencies" file="${generated.files.dir}/impl-deps.txt" />
1311
      <output type="public-packages" file="${generated.files.dir}/public-packages.txt" />
1312
      <output type="shared-packages" file="${generated.files.dir}/shared-packages.txt" />
1313
      <output type="friend-packages" file="${generated.files.dir}/friend-packages.txt" />
1314
      <output type="external-libraries" file="${generated.files.dir}/external-libraries.txt" />
1315
    </deps>
1316
  </target>
1317
  
1318
  <target name="check-public-packages" depends="generate-golden-files" >
1319
    <property name="check.public.packages.golden" location="${golden.files.dir}/public-packages.txt" />
1320
    <property name="check.public.packages.template" location="${template.files.dir}/public-packages.txt" />
1321
    <property name="check.public.packages.generated" location="${generated.files.dir}/public-packages.txt" />
1322
  
1323
    <condition property="check-public-packages-are-they-the-same" >
1324
        <filesmatch file1="${check.public.packages.template}" file2="${check.public.packages.generated}" />
1325
    </condition>
1326
    
1327
    
1328
    <exec os="Linux SunOS Solaris " dir="." executable="diff" failonerror="no" timeout="60000" >
1329
      <arg value="-U"/>
1330
      <arg value="15"/>
1331
      <arg value="${check.public.packages.template}" />
1332
      <arg value="${check.public.packages.generated}" />
1333
    </exec>
1334
    
1335
    <fail unless="check-public-packages-are-they-the-same" >!
1336
    *** Public packages has changed! ***
1337
    
1338
    Differences were found while comparing file 
1339
    ${check.public.packages.template}
1340
    with 
1341
    ${check.public.packages.generated}
1342
    
1343
    This means that the set of public packages changed since the previously known one.
1344
    Some packages may have been added, some of them may have been removed 
1345
    Either by changing manifest of a module or by adding or removing a class file
1346
    from a module package.
1347
    
1348
    
1349
    Changing the packages may or may not be ok. It means that an api of 
1350
    whole product changes and as such it is subject to review. If you passed
1351
    your review and want to change the list of public packages, then please
1352
    update the golden file at 
1353
    ${check.public.packages.golden}
1354
    and run the test once again. 
1355
    
1356
    Read more about the Verification Framework:
1357
    http://openide.netbeans.org/proposals/arch/clusters.html#verify
1358
    
1359
    Look at for information about reviews:
1360
    http://openide.netbeans.org/tutorial/review-steps.html
1361
    
1362
    Check the page about APIs:
1363
    http://openide.netbeans.org/tutorial/api-design.html#api
1364
    </fail>
1365
  </target>
1366
  
1367
  <target name="check-friend-packages" depends="generate-golden-files" >
1368
    <property name="check.friend.packages.golden" location="${golden.files.dir}/friend-packages.txt" />
1369
    <property name="check.friend.packages.template" location="${template.files.dir}/friend-packages.txt" />
1370
    <property name="check.friend.packages.generated" location="${generated.files.dir}/friend-packages.txt" />
1371
  
1372
    <condition property="check-friend-packages-are-they-the-same" >
1373
        <filesmatch file1="${check.friend.packages.template}" file2="${check.friend.packages.generated}" />
1374
    </condition>
1375
    
1376
    
1377
    <exec os="Linux SunOS Solaris " dir="." executable="diff" failonerror="no" timeout="60000" >
1378
      <arg value="-U"/>
1379
      <arg value="15"/>
1380
      <arg value="${check.friend.packages.template}" />
1381
      <arg value="${check.friend.packages.generated}" />
1382
    </exec>
1383
    
1384
    <fail unless="check-friend-packages-are-they-the-same" >!
1385
    *** Friend packages has changed! ***
1386
    
1387
    Differences were found while comparing file 
1388
    ${check.friend.packages.template}
1389
    with 
1390
    ${check.friend.packages.generated}
1391
    
1392
    This means that the set of friend packages changed since the previously known one.
1393
    Some packages may have been added, some of them may have been removed 
1394
    Either by changing manifest of a module or by adding or removing a class file
1395
    from a module package.
1396
    
1397
    
1398
    Changing the packages may or may not be ok. It means that an api of 
1399
    whole product changes and as such it is subject to review. If you passed
1400
    your review and want to change the list of friend packages, then please
1401
    update the golden file at 
1402
    ${check.friend.packages.golden}
1403
    and run the test once again. 
1404
    
1405
    Read more about the Verification Framework:
1406
    http://openide.netbeans.org/proposals/arch/clusters.html#verify
1407
    
1408
    Look at for information about reviews:
1409
    http://openide.netbeans.org/tutorial/review-steps.html
1410
    
1411
    Check the page about APIs:
1412
    http://openide.netbeans.org/tutorial/api-design.html#api
1413
    </fail>
1414
  </target>
1415
  
1416
  <target name="check-shared-packages" depends="generate-golden-files,-jdk-init" unless="have-jdk-1.5" >
1417
    <property name="check.shared.packages.golden" location="${golden.files.dir}/shared-packages.txt" />
1418
    <property name="check.shared.packages.template" location="${template.files.dir}/shared-packages.txt" />
1419
    <property name="check.shared.packages.generated" location="${generated.files.dir}/shared-packages.txt" />
1420
  
1421
    <condition property="check-shared-packages-are-they-the-same" >
1422
        <filesmatch file1="${check.shared.packages.template}" file2="${check.shared.packages.generated}" />
1423
    </condition>
1424
    
1425
    
1426
    <exec os="Linux SunOS Solaris Mac OS X" dir="." executable="diff" failonerror="no" timeout="60000" >
1427
      <arg value="-U"/>
1428
      <arg value="15"/>
1429
      <arg value="${check.shared.packages.template}" />
1430
      <arg value="${check.shared.packages.generated}" />
1431
    </exec>
1432
    
1433
    <fail unless="check-shared-packages-are-they-the-same" >!
1434
    *** Shared packages has changed! ***
1435
    
1436
    Differences were found while comparing file 
1437
    ${check.shared.packages.template}
1438
    with 
1439
    ${check.shared.packages.generated}
1440
    
1441
    This means that the set of shared packages changed since the previously known one.
1442
    Some packages may have been added, some of them may have been removed 
1443
    Either by changing manifest of a module or by adding or removing a class file
1444
    from a module package.
1445
    
1446
    
1447
    Removing shared packages is ok. Adding shared packages is silly, complicates
1448
    and slows down module system and startup of the application. Do not do that!
1449
    If you are removing a shared package please update 
1450
    ${check.shared.packages.golden}
1451
    and run the test once again. 
1452
    
1453
    Read more about the Verification Framework:
1454
    http://openide.netbeans.org/proposals/arch/clusters.html#verify
1455
    
1456
    Look at for information about reviews:
1457
    http://openide.netbeans.org/tutorial/review-steps.html
1458
    
1459
    Check the page about APIs:
1460
    http://openide.netbeans.org/tutorial/api-design.html#api
1461
    </fail>
1462
  </target>
1463
1464
  <target name="check-external-libraries" depends="generate-golden-files" >
1465
    <property name="check.external.libraries.golden" location="${golden.files.dir}/external-libraries.txt" />
1466
    <property name="check.external.libraries.template" location="${template.files.dir}/external-libraries.txt" />
1467
    <property name="check.external.libraries.generated" location="${generated.files.dir}/external-libraries.txt" />
1468
  
1469
    <condition property="check-external-libraries-are-they-the-same" >
1470
        <filesmatch file1="${check.external.libraries.template}" file2="${check.external.libraries.generated}" />
1471
    </condition>
1472
    
1473
    
1474
    <exec os="Linux SunOS Solaris Mac OS X" dir="." executable="diff" failonerror="no" timeout="60000" >
1475
      <arg value="-U"/>
1476
      <arg value="15"/>
1477
      <arg value="${check.external.libraries.template}" />
1478
      <arg value="${check.external.libraries.generated}" />
1479
    </exec>
1480
    
1481
    <fail unless="check-external-libraries-are-they-the-same" >!
1482
    *** List of external libraries has changed! ***
1483
    
1484
    Differences were found while comparing file 
1485
    ${check.external.libraries.template}
1486
    with 
1487
    ${check.external.libraries.generated}
1488
    
1489
    This means that the set of external libraries (JARs that are not NetBeans
1490
    modules or does not have NetBeans-Own-Library: true in manifest) has 
1491
    changed since the previously known one. Some libraries may have been added, 
1492
    some of them may have been removed, they MD5 checksum or size has been changed.
1493
    
1494
    Changing the external libraries is ok, but requires legal approval everytime
1495
    new version of a library is put into the product. If you have the approval
1496
    want to change the list of external libraries, then please
1497
    update the golden file at 
1498
    ${check.external.libraries.golden}
1499
    and run the test once again. 
1500
    
1501
    Read more about the Verification Framework:
1502
    http://openide.netbeans.org/proposals/arch/clusters.html#verify
1503
    
1504
    Look at for information about reviews:
1505
    http://openide.netbeans.org/tutorial/review-steps.html
1506
    
1507
    Check the page about APIs:
1508
    http://openide.netbeans.org/tutorial/api-design.html#api
1509
    </fail>
1510
  </target>
1511
  
1512
  <target name="check-modules" depends="generate-golden-files" >
1513
    <property name="check.modules.golden" location="${golden.files.dir}/modules.txt" />
1514
    <property name="check.modules.template" location="${template.files.dir}/modules.txt" />
1515
    <property name="check.modules.generated" location="${generated.files.dir}/modules.txt" />
1516
  
1517
    <condition property="check-modules-are-they-the-same" >
1518
        <filesmatch file1="${check.modules.template}" file2="${check.modules.generated}" />
1519
    </condition>
1520
    
1521
    
1522
    <exec os="Linux SunOS Solaris Mac OS X" dir="." executable="diff" failonerror="no" timeout="60000" >
1523
      <arg value="-U"/>
1524
      <arg value="15"/>
1525
      <arg value="${check.modules.template}" />
1526
      <arg value="${check.modules.generated}" />
1527
    </exec>
1528
    
1529
    <fail unless="check-modules-are-they-the-same" >!
1530
    *** List of modules has changed! ***
1531
    
1532
    Differences were found while comparing file 
1533
    ${check.modules.template}
1534
    with 
1535
    ${check.modules.generated}
1536
    
1537
    This means that the set of modules changed since the previously known one.
1538
    Adding or removing a module significatly affects the set of APIs the
1539
    product offers and as such is subject to review. If you passed
1540
    your review and want to change the list of modules, then please
1541
    update the golden file at 
1542
    ${check.modules.golden}
1543
    and run the test once again. 
1544
    
1545
    Read more about the Verification Framework:
1546
    http://openide.netbeans.org/proposals/arch/clusters.html#verify
1547
    
1548
    Look at for information about reviews:
1549
    http://openide.netbeans.org/tutorial/review-steps.html
1550
    
1551
    Check the page about APIs:
1552
    http://openide.netbeans.org/tutorial/api-design.html#api
1553
    </fail>
1554
  </target>
1555
1556
  <target name="check-dependencies" depends="generate-golden-files" >
1557
    <antcall target="check-dependencies-subroutine" >
1558
        <param name="check.dependencies.golden" location="${golden.files.dir}/deps.txt" />
1559
        <param name="check.dependencies.template" location="${template.files.dir}/deps.txt" />
1560
        <param name="check.dependencies.generated" location="${generated.files.dir}/deps.txt" />
1561
    </antcall>
1562
  </target>
1563
  
1564
  <target name="check-implementation-dependencies" depends="generate-golden-files" >
1565
    <antcall target="check-dependencies-subroutine" >
1566
        <param name="check.dependencies.golden" location="${golden.files.dir}/impl-deps.txt" />
1567
        <param name="check.dependencies.template" location="${template.files.dir}/impl-deps.txt" />
1568
        <param name="check.dependencies.generated" location="${generated.files.dir}/impl-deps.txt" />
1569
    </antcall>
1570
  </target>
1571
1572
  <target name="check-cluster-dependencies" depends="generate-golden-files" >
1573
    <antcall target="check-dependencies-subroutine" >
1574
        <param name="check.dependencies.golden" location="${golden.files.dir}/cluster-deps.txt" />
1575
        <param name="check.dependencies.template" location="${template.files.dir}/cluster-deps.txt" />
1576
        <param name="check.dependencies.generated" location="${generated.files.dir}/cluster-deps.txt" />
1577
    </antcall>
1578
  </target>
1579
  
1580
  <target name="check-cluster-implementation-dependencies" depends="generate-golden-files" >
1581
    <antcall target="check-dependencies-subroutine" >
1582
        <param name="check.dependencies.golden" location="${golden.files.dir}/cluster-impl-deps.txt" />
1583
        <param name="check.dependencies.template" location="${template.files.dir}/cluster-impl-deps.txt" />
1584
        <param name="check.dependencies.generated" location="${generated.files.dir}/cluster-impl-deps.txt" />
1585
    </antcall>
1586
  </target>
1587
    
1588
  <target name="check-dependencies-subroutine" >
1589
    <condition property="check-dependencies-are-they-the-same" >
1590
        <filesmatch file1="${check.dependencies.template}" file2="${check.dependencies.generated}" />
1591
    </condition>
1592
    
1593
    
1594
    <exec os="Linux SunOS Solaris Mac OS X" dir="." executable="diff" failonerror="no" timeout="60000" >
1595
      <arg value="-U"/>
1596
      <arg value="15"/>
1597
      <arg value="${check.dependencies.template}" />
1598
      <arg value="${check.dependencies.generated}" />
1599
    </exec>
1600
    
1601
    <fail unless="check-dependencies-are-they-the-same" >!
1602
    *** List of dependencies has changed! ***
1603
    
1604
    Differences were found while comparing file 
1605
    ${check.dependencies.template}
1606
    with 
1607
    ${check.dependencies.generated}
1608
    
1609
    This means that the set of dependencies changed since the previously known one.
1610
    Adding a dependency can restrict the ways how a final product can be assembled
1611
    and as such it forms an important aspect of API and is subject to review. 
1612
    If you passed your review or you are sure you want to change the 
1613
    list of dependencies, then please update the golden file at 
1614
    ${check.dependencies.golden}
1615
    and run the test once again. 
1616
    
1617
    Read more about the Verification Framework:
1618
    http://openide.netbeans.org/proposals/arch/clusters.html#verify
1619
    
1620
    Look at for information about reviews:
1621
    http://openide.netbeans.org/tutorial/review-steps.html
1622
    
1623
    Check the page about APIs and dependencies being important:
1624
    http://openide.netbeans.org/tutorial/api-design.html#api
1625
    </fail>
1626
  </target>
1627
    
1628
    
1629
  <target name="generate-files-layout" depends="generate-golden-files-init" >
1630
    <property name="generated.files.dir" location="build/generated" />
1631
    <mkdir dir="${generated.files.dir}" />
1632
    
1633
    <property name="check.files.layout.golden" location="${golden.files.dir}/files-layout.txt" />
1634
    <property name="check.files.layout.template" location="${template.files.dir}/files-layout.txt" />
1635
    <property name="check.files.layout.generated" location="${generated.files.dir}/files-layout.txt" />
1636
  
1637
    <property name="check-file-layout-root" location="${netbeans.dest.dir}" />
1638
    <fileset id="check-file-layout" dir="${check-file-layout-root}" casesensitive="yes" >
1639
        <include name="platform*/**" />
1640
        <include name="ide*/**" />
1641
        <include name="enterprise*/**" />
1642
        <include name="nb*/**" />
1643
        <include name="harness*/**" />
1644
    </fileset>
1645
    
1646
    <pathconvert property="check-file-layout" refid="check-file-layout" dirsep="/" pathsep="," >
1647
        <map from="${check-file-layout-root}${file.separator}" to="" />
1648
    </pathconvert>
1649
    <mkdir dir="build/generated" />
1650
    <echo message="${check-file-layout}${line.separator}" file="${check.files.layout.generated}" />
1651
    <replace file="${check.files.layout.generated}" token="," value="${line.separator}" />
1652
    <replace file="${check.files.layout.generated}" token="\" value="/" />
1653
    <condition property="check-files-are-they-the-same" >
1654
        <filesmatch file1="${check.files.layout.template}" file2="${check.files.layout.generated}" />
1655
    </condition>
1656
    
1657
    
1658
  </target>
1659
  
1660
  
1661
  <target name="check-files-layout" depends="generate-files-layout" >
1662
    <exec os="Linux SunOS Solaris Mac OS X" dir="." executable="diff" failonerror="no" timeout="60000" >
1663
      <arg value="-U"/>
1664
      <arg value="15"/>
1665
      <arg value="${check.files.layout.template}" />
1666
      <arg value="${check.files.layout.generated}" />
1667
    </exec>
1668
    
1669
    <fail unless="check-files-are-they-the-same" >!
1670
    *** Layout of files has changed! ***
1671
    
1672
    Differences were found while comparing file ${check.files.layout.generated} with 
1673
    ${check.files.layout.template}
1674
    This means that the layout of files changed since the previously known one.
1675
    Some files may have been added, some of them may have been removed or renamed. 
1676
    
1677
    Changing the layout may or may not be ok. If you are sure that you want to
1678
    change the layout of files, then update the golden file at 
1679
    ${check.files.layout.golden}
1680
    and run the test once again. If you got this warning without intending
1681
    to change the layout of files, think twice whether your commit is really
1682
    correct and consider asking for a review first.
1683
    
1684
    Read more about the Verification Framework:
1685
    http://openide.netbeans.org/proposals/arch/clusters.html#verify
1686
    
1687
    Look at for information about reviews:
1688
    http://openide.netbeans.org/tutorial/review-steps.html
1689
    
1690
    Check the page about APIs and files layout being an API:
1691
    http://openide.netbeans.org/tutorial/api-design.html#api
1692
    </fail>
1693
  </target>
1694
1695
  <target name="check-clusters-content" depends="bootstrap,init-tasks"> 
1696
    <taskdef name="checkcontent" classname="org.netbeans.nbbuild.CheckClustersContent" classpath="nbantext.jar"/>
1697
    <checkcontent clusters="${nb.clusters.list}" trackingPath="${netbeans.dest.dir}" kitDestDir="${netbeans.dest.dir}">
1698
      <exclude name="extra/**"/>
1699
      <exclude name="testtools/**"/>
1700
      <exclude name="bin/**"/>
1701
      <exclude name="README.html"/>
1702
      <exclude name="CREDITS.html"/>
1703
      <exclude name="LICENSE.txt"/>
1704
      <exclude name="DISTRIBUTION.txt"/>
1705
      <exclude name="THIRDPARTYLICENSE.txt"/>
1706
      <exclude name="nb.cluster.*"/>
1707
      <exclude name="etc/netbeans.conf"/>
1708
      <exclude name="build_info"/>
1709
      <exclude name="module_tracking.xml"/>
1710
      <exclude name="moduleCluster.properties"/>
1711
      <exclude name="netbeans.css"/>
1712
    </checkcontent>
1713
  </target>
1714
  
1715
  <target name="check-module-configs" depends="bootstrap" description="Sanity-check build.properties and cluster.properties.">
1716
    <taskdef name="checkmoduleconfigs" classname="org.netbeans.nbbuild.CheckModuleConfigs" classpath="nbantext.jar"/>
1717
    <checkmoduleconfigs nbroot=".."/>
1718
  </target>
1719
1720
  <target name="display-l10n-list-matches" description="Show which files are actually matched by an l10n.list in some module.">
1721
    <property name="nbroot" location=".."/>
1722
    <input addproperty="module">Select a top-level module (e.g. "java") to display results for:</input>
1723
    <property name="listfile" location="${nbroot}/${module}/l10n.list"/>
1724
    <echo>${listfile}:1: Matches follow... (click on hyperlinks from IDE!)</echo>
1725
    <echo>(warning: 'exclude' directives not honored here yet)</echo><!-- XXX use filtersets or something to fix -->
1726
    <apply parallel="false" executable="sh">
1727
        <arg value="-c"/>
1728
        <arg value="echo $0:1"/>
1729
        <fileset dir="${nbroot}" includesfile="${listfile}"/>
1730
    </apply>
1731
  </target>
1732
  
1733
  <target name="increment-spec-versions" depends="bootstrap,init-module-list" description="Increment all standard module specification versions. Pass -Dbranch=true if not on the trunk.">
1734
    <property name="branch" value="false"/>
1735
    <taskdef name="incrspecvers" classname="org.netbeans.nbbuild.IncrementSpecificationVersions" classpath="nbantext.jar"/>
1736
    <incrspecvers nbroot=".." modules="${allmodules}" branch="${branch}"/>
1737
  </target>
1738
1739
</project>
(-)a/xml.text.obsolete90/test/unit/data/input/XMLFormatterTest/testReformat/web.xml (+17 lines)
Line 0 Link Here
1
<?xml version="1.0" encoding="UTF-8"?>
2
3
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
4
	 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5
	 xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
6
	 version="2.4">
7
             <session-config>
8
      <session-timeout>
9
30
10
        </session-timeout>
11
 </session-config>
12
 <welcome-file-list>
13
         	<welcome-file>
14
            index.jsp
15
  </welcome-file>
16
    </welcome-file-list>
17
            </web-app>
(-)a/xml.text/test/unit/src/org/netbeans/modules/xml/text/indent/XMLFormatterTest.java (-1 / +1 lines)
Lines 79-85 Link Here
79
    public static Test suite() {
79
    public static Test suite() {
80
        TestSuite suite = new TestSuite();
80
        TestSuite suite = new TestSuite();
81
        suite.addTest(new XMLFormatterTest("testReformatSample1"));
81
        suite.addTest(new XMLFormatterTest("testReformatSample1"));
82
        //suite.addTest(new XMLFormatterTest("testReformatSample2"));        
82
        suite.addTest(new XMLFormatterTest("testReformatSample2"));        
83
        return suite;
83
        return suite;
84
    }
84
    }
85
85
(-)a/xml.text/test/unit/src/org/netbeans/modules/xml/text/AbstractTestCase.java (-3 / +5 lines)
Lines 39-45 Link Here
39
 * 
39
 * 
40
 * Portions Copyrighted 2007 Sun Microsystems, Inc.
40
 * Portions Copyrighted 2007 Sun Microsystems, Inc.
41
 */
41
 */
42
package org.netbeans.modules.xml.text;
42
package org.netbeans.modules.xml.text.syntax;
43
43
44
import java.io.BufferedReader;
44
import java.io.BufferedReader;
45
import java.io.IOException;
45
import java.io.IOException;
Lines 52-64 Link Here
52
import org.netbeans.api.lexer.Language;
52
import org.netbeans.api.lexer.Language;
53
import org.netbeans.api.xml.lexer.XMLTokenId;
53
import org.netbeans.api.xml.lexer.XMLTokenId;
54
import org.netbeans.editor.BaseDocument;
54
import org.netbeans.editor.BaseDocument;
55
import org.netbeans.modules.xml.text.syntax.XMLSyntaxSupport;
56
import org.netbeans.modules.xml.xam.ModelSource;
55
import org.netbeans.modules.xml.xam.ModelSource;
57
import org.netbeans.modules.xml.xdm.XDMModel;
56
import org.netbeans.modules.xml.xdm.XDMModel;
58
import org.netbeans.modules.xml.xdm.diff.DefaultElementIdentity;
57
import org.netbeans.modules.xml.xdm.diff.DefaultElementIdentity;
59
import org.netbeans.modules.xml.xdm.diff.DiffFinder;
58
import org.netbeans.modules.xml.xdm.diff.DiffFinder;
60
import org.netbeans.modules.xml.xdm.diff.Difference;
59
import org.netbeans.modules.xml.xdm.diff.Difference;
61
import org.openide.util.Exceptions;
62
import org.openide.util.Lookup;
60
import org.openide.util.Lookup;
63
import org.openide.util.lookup.Lookups;
61
import org.openide.util.lookup.Lookups;
64
62
Lines 89-94 Link Here
89
    }
87
    }
90
                 
88
                 
91
    protected static BaseDocument getResourceAsDocument(String path) throws Exception {
89
    protected static BaseDocument getResourceAsDocument(String path) throws Exception {
90
        // AbstractTestCase was repackaged, tests typically contain path rooted at xml.text package.
91
        if (path.startsWith("syntax/")) {
92
            path = path.substring(7);
93
        }
92
        InputStream in = AbstractTestCase.class.getResourceAsStream(path);
94
        InputStream in = AbstractTestCase.class.getResourceAsStream(path);
93
        BaseDocument sd = new BaseDocument(true, "text/xml"); //NOI18N
95
        BaseDocument sd = new BaseDocument(true, "text/xml"); //NOI18N
94
        BufferedReader br = new BufferedReader(new InputStreamReader(in,"UTF-8"));
96
        BufferedReader br = new BufferedReader(new InputStreamReader(in,"UTF-8"));
(-)a/xml.text/test/unit/src/org/netbeans/modules/xml/text/syntax/XMLSyntaxSupportTest.java (-1 lines)
Lines 45-51 Link Here
45
import junit.framework.Test;
45
import junit.framework.Test;
46
import junit.framework.TestSuite;
46
import junit.framework.TestSuite;
47
import org.netbeans.editor.TokenItem;
47
import org.netbeans.editor.TokenItem;
48
import org.netbeans.modules.xml.text.AbstractTestCase;
49
48
50
/**
49
/**
51
 *
50
 *
(-)a/xml.text/apichanges.xml (+64 lines)
Lines 107-112 Link Here
107
    <!-- ACTUAL CHANGES BEGIN HERE: -->
107
    <!-- ACTUAL CHANGES BEGIN HERE: -->
108
108
109
    <changes>
109
    <changes>
110
        <change id="deprecated-syntax-api">
111
            <summary>Syntax API deprecated</summary>
112
            <version major="2" minor="60"/>
113
            <date day="11" month="10" year="2016"/>
114
            <author login="sdedic"/>
115
            <compatibility binary="compatible" source="incompatible" semantic="compatible" addition="yes" deprecation="yes" deletion="yes"/>
116
            <description>
117
                <p>
118
                    The xml.text.syntax API uses the old and long deprecated lexer. The API is now moved to a new compatibility-only 
119
                    <code>xml.text.deprecated90</code> module and a new API in <code>org.netbeans.modules.xml.text.api.dom</code> package is offered.               
120
                </p>
121
                <p>
122
                    The following classes/packages have been moved to xml.text.obsolete90 module:
123
                </p>
124
                <ul>
125
                    <li>
126
                        <code>org.netbeans.modules.xml.text.syntax</code>
127
                        <ul>
128
                            <li>DTDSyntaxTokenMapper</li>
129
                            <li>DTDTokenContext</li>
130
                            <li>SyntaxElement</li>
131
                            <li>UnicodeClasses</li>
132
                            <li>XMLDefaultSyntax</li>
133
                            <li>XMLSyntaxSupport</li>
134
                            <li>XMLSyntaxTokenMapper</li>
135
                            <li>XMLTokenIDs</li>
136
                        </ul>
137
                    </li>
138
                    <li>
139
                        <code>org.netbeans.modules.xml.text.syntax.dom</code>
140
                        <ul>
141
                            <li>AttrImpl</li>
142
                            <li>CDataSectionImpl</li>
143
                            <li>CommentImpl</li>
144
                            <li>DocumentTypeImpl</li>
145
                            <li>EmptyTag</li>
146
                            <li>EndTag</li>
147
                            <li>EntityReferenceImpl</li>
148
                            <li>ProcessingInstructionImpl</li>
149
                            <li>StartTag</li>
150
                            <li>SyntaxNode</li>
151
                            <li>TextImpl</li>
152
                            <li>Util</li>
153
                        </ul>
154
                    </li>
155
                    <li>
156
                        <code>org.netbeans.modules.xml.text.indent</code>
157
                        <ul>
158
                            <li>XMLFormatter</li>
159
                        </ul>
160
                    </li>
161
                    <li>
162
                        <code>org.netbeans.modules.xml.text.api</code>
163
                        <ul>
164
                            <li>XMLDefaultTokenContext</li>
165
                        </ul>
166
                    </li>
167
                </ul>
168
            </description>
169
            <class name="XMLTextUtils" package="org.netbeans.modules.xml.text.api"/>
170
            <package name="org.netbeans.modules.xml.text.syntax"/>
171
            <package name="org.netbeans.modules.xml.text.api.dom"/>
172
            <issue number="268342"/>
173
        </change>
110
        <change id="old-editor-settings-deprecation">
174
        <change id="old-editor-settings-deprecation">
111
            <summary>Removing old settings classes</summary>
175
            <summary>Removing old settings classes</summary>
112
            <version major="1" minor="16"/>
176
            <version major="1" minor="16"/>
(-)a/xml.text/manifest.mf (-1 / +2 lines)
Lines 3-6 Link Here
3
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/xml/text/resources/Bundle.properties
3
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/xml/text/resources/Bundle.properties
4
OpenIDE-Module-Layer: org/netbeans/modules/xml/text/resources/mf-layer.xml
4
OpenIDE-Module-Layer: org/netbeans/modules/xml/text/resources/mf-layer.xml
5
AutoUpdate-Show-In-Client: false
5
AutoUpdate-Show-In-Client: false
6
OpenIDE-Module-Specification-Version: 1.54
6
OpenIDE-Module-Implementation-Version: 1
7
(-)a/java.source/module-auto-deps.xml (-6 / +3 lines)
Lines 48-64 Link Here
48
48
49
<transformations version="1.0">
49
<transformations version="1.0">
50
    <transformationgroup>
50
    <transformationgroup>
51
        <description>The old editor settings and completion APIs have been deprecated, see http://wiki.netbeans.org/EditorSettingsUpgrade and update your module.</description>
51
        <description>XML SyntaxElement API that depends on obsolete Lexer was deprecated and removed from main module.</description>
52
        <transformation>
52
        <transformation>
53
            <trigger-dependency type="older">
53
            <trigger-dependency type="older">
54
                <module-dependency codenamebase="org.netbeans.modules.java.source" spec="0.141"/>
54
                <module-dependency codenamebase="org.netbeans.modules.xml.text" major="2" spec="1.60"/>
55
            </trigger-dependency>
55
            </trigger-dependency>
56
            <implies>
56
            <implies>
57
                <result>
57
                <result>
58
                    <module-dependency codenamebase="org.netbeans.modules.java.source.base" spec="1.1"/>
58
                    <module-dependency codenamebase="org.netbeans.modules.xml.text.obsolete90" spec="1.0"/>
59
                </result>
60
                <result>
61
                    <module-dependency codenamebase="org.netbeans.modules.java.source.compat8" spec="9.0"/>
62
                </result>
59
                </result>
63
            </implies>
60
            </implies>
64
        </transformation>
61
        </transformation>
(-)a/xml.text/nbproject/project.properties (-1 / +3 lines)
Lines 40-46 Link Here
40
# Version 2 license, then the option applies only if the new code is
40
# Version 2 license, then the option applies only if the new code is
41
# made subject to such option by the copyright holder.
41
# made subject to such option by the copyright holder.
42
42
43
javac.source=1.7
43
javac.source=1.8
44
44
45
test.unit.cp.extra=${openide.dir}/core/openide.jar:${openide.loaders.dir}/core/openide-loaders.jar
45
test.unit.cp.extra=${openide.dir}/core/openide.jar:${openide.loaders.dir}/core/openide-loaders.jar
46
test.unit.run.cp.extra=${test.unit.cp.extra}
46
test.unit.run.cp.extra=${test.unit.cp.extra}
Lines 52-54 Link Here
52
test.config.stableBTD.excludes=\
52
test.config.stableBTD.excludes=\
53
    org/netbeans/modules/xml/text/completion/CompletionJTest.class,\
53
    org/netbeans/modules/xml/text/completion/CompletionJTest.class,\
54
    org/netbeans/modules/xml/text/syntax/ColoringTest.class
54
    org/netbeans/modules/xml/text/syntax/ColoringTest.class
55
spec.version.base=1.60.0
56
(-)a/xml.text/nbproject/project.xml (-24 / +34 lines)
Lines 50-55 Link Here
50
            <code-name-base>org.netbeans.modules.xml.text</code-name-base>
50
            <code-name-base>org.netbeans.modules.xml.text</code-name-base>
51
            <module-dependencies>
51
            <module-dependencies>
52
                <dependency>
52
                <dependency>
53
                    <code-name-base>org.netbeans.api.annotations.common</code-name-base>
54
                    <build-prerequisite/>
55
                    <compile-dependency/>
56
                    <run-dependency>
57
                        <release-version>1</release-version>
58
                        <specification-version>1.28</specification-version>
59
                    </run-dependency>
60
                </dependency>
61
                <dependency>
53
                    <code-name-base>org.netbeans.api.progress</code-name-base>
62
                    <code-name-base>org.netbeans.api.progress</code-name-base>
54
                    <build-prerequisite/>
63
                    <build-prerequisite/>
55
                    <compile-dependency/>
64
                    <compile-dependency/>
Lines 131-136 Link Here
131
                    </run-dependency>
140
                    </run-dependency>
132
                </dependency>
141
                </dependency>
133
                <dependency>
142
                <dependency>
143
                    <code-name-base>org.netbeans.modules.editor.document</code-name-base>
144
                    <build-prerequisite/>
145
                    <compile-dependency/>
146
                    <run-dependency>
147
                        <specification-version>1.0</specification-version>
148
                    </run-dependency>
149
                </dependency>
150
                <dependency>
134
                    <code-name-base>org.netbeans.modules.editor.fold</code-name-base>
151
                    <code-name-base>org.netbeans.modules.editor.fold</code-name-base>
135
                    <build-prerequisite/>
152
                    <build-prerequisite/>
136
                    <compile-dependency/>
153
                    <compile-dependency/>
Lines 149-154 Link Here
149
                    </run-dependency>
166
                    </run-dependency>
150
                </dependency>
167
                </dependency>
151
                <dependency>
168
                <dependency>
169
                    <code-name-base>org.netbeans.modules.editor.indent.support</code-name-base>
170
                    <run-dependency>
171
                        <specification-version>1.40</specification-version>
172
                    </run-dependency>
173
                </dependency>
174
                <dependency>
152
                    <code-name-base>org.netbeans.modules.editor.lib</code-name-base>
175
                    <code-name-base>org.netbeans.modules.editor.lib</code-name-base>
153
                    <build-prerequisite/>
176
                    <build-prerequisite/>
154
                    <compile-dependency/>
177
                    <compile-dependency/>
Lines 167-180 Link Here
167
                    </run-dependency>
190
                    </run-dependency>
168
                </dependency>
191
                </dependency>
169
                <dependency>
192
                <dependency>
170
                    <code-name-base>org.netbeans.modules.editor.document</code-name-base>
171
                    <build-prerequisite/>
172
                    <compile-dependency/>
173
                    <run-dependency>
174
                        <specification-version>1.0</specification-version>
175
                    </run-dependency>
176
                </dependency>
177
                <dependency>
178
                    <code-name-base>org.netbeans.modules.editor.mimelookup</code-name-base>
193
                    <code-name-base>org.netbeans.modules.editor.mimelookup</code-name-base>
179
                    <build-prerequisite/>
194
                    <build-prerequisite/>
180
                    <compile-dependency/>
195
                    <compile-dependency/>
Lines 297-303 Link Here
297
                    <build-prerequisite/>
312
                    <build-prerequisite/>
298
                    <compile-dependency/>
313
                    <compile-dependency/>
299
                    <run-dependency>
314
                    <run-dependency>
300
                      <specification-version>7.61</specification-version>
315
                        <specification-version>7.61</specification-version>
301
                    </run-dependency>
316
                    </run-dependency>
302
                </dependency>
317
                </dependency>
303
                <dependency>
318
                <dependency>
Lines 325-338 Link Here
325
                    </run-dependency>
340
                    </run-dependency>
326
                </dependency>
341
                </dependency>
327
                <dependency>
342
                <dependency>
328
                    <code-name-base>org.openide.util.ui</code-name-base>
329
                    <build-prerequisite/>
330
                    <compile-dependency/>
331
                    <run-dependency>
332
                        <specification-version>9.3</specification-version>
333
                    </run-dependency>
334
                </dependency>
335
                <dependency>
336
                    <code-name-base>org.openide.util</code-name-base>
343
                    <code-name-base>org.openide.util</code-name-base>
337
                    <build-prerequisite/>
344
                    <build-prerequisite/>
338
                    <compile-dependency/>
345
                    <compile-dependency/>
Lines 349-354 Link Here
349
                    </run-dependency>
356
                    </run-dependency>
350
                </dependency>
357
                </dependency>
351
                <dependency>
358
                <dependency>
359
                    <code-name-base>org.openide.util.ui</code-name-base>
360
                    <build-prerequisite/>
361
                    <compile-dependency/>
362
                    <run-dependency>
363
                        <specification-version>9.3</specification-version>
364
                    </run-dependency>
365
                </dependency>
366
                <dependency>
352
                    <code-name-base>org.openide.windows</code-name-base>
367
                    <code-name-base>org.openide.windows</code-name-base>
353
                    <build-prerequisite/>
368
                    <build-prerequisite/>
354
                    <compile-dependency/>
369
                    <compile-dependency/>
Lines 356-367 Link Here
356
                        <specification-version>6.2</specification-version>
371
                        <specification-version>6.2</specification-version>
357
                    </run-dependency>
372
                    </run-dependency>
358
                </dependency>
373
                </dependency>
359
                <dependency>
360
                    <code-name-base>org.netbeans.modules.editor.indent.support</code-name-base>
361
                    <run-dependency>
362
                        <specification-version>1.40</specification-version>
363
                    </run-dependency>
364
                </dependency>
365
            </module-dependencies>
374
            </module-dependencies>
366
            <test-dependencies>
375
            <test-dependencies>
367
                <test-type>
376
                <test-type>
Lines 450-461 Link Here
450
                <friend>org.netbeans.modules.xml.schema.abe</friend>
459
                <friend>org.netbeans.modules.xml.schema.abe</friend>
451
                <friend>org.netbeans.modules.xml.schema.completion</friend>
460
                <friend>org.netbeans.modules.xml.schema.completion</friend>
452
                <friend>org.netbeans.modules.xml.schema.ui.basic</friend>
461
                <friend>org.netbeans.modules.xml.schema.ui.basic</friend>
462
                <friend>org.netbeans.modules.xml.text.obsolete90</friend>
453
                <friend>org.netbeans.modules.xsl</friend>
463
                <friend>org.netbeans.modules.xsl</friend>
454
                <friend>org.netbeans.modules.xslt.core</friend>
464
                <friend>org.netbeans.modules.xslt.core</friend>
455
                <package>org.netbeans.modules.xml.text.api</package>
465
                <package>org.netbeans.modules.xml.text.api</package>
466
                <package>org.netbeans.modules.xml.text.api.dom</package>
456
                <package>org.netbeans.modules.xml.text.navigator.base</package>
467
                <package>org.netbeans.modules.xml.text.navigator.base</package>
457
                <package>org.netbeans.modules.xml.text.syntax</package>
468
                <package>org.netbeans.modules.xml.text.syntax</package>
458
                <package>org.netbeans.modules.xml.text.syntax.dom</package>
459
            </friend-packages>
469
            </friend-packages>
460
        </data>
470
        </data>
461
    </configuration>
471
    </configuration>
(-)a/xml.text/src/org/netbeans/modules/xml/text/ComplexValueSettingsFactory.java (-12 lines)
Lines 42-55 Link Here
42
42
43
package org.netbeans.modules.xml.text;
43
package org.netbeans.modules.xml.text;
44
44
45
import java.util.Collections;
46
import java.util.List;
47
import org.netbeans.editor.Acceptor;
45
import org.netbeans.editor.Acceptor;
48
import org.netbeans.editor.AcceptorFactory;
46
import org.netbeans.editor.AcceptorFactory;
49
import org.netbeans.modules.xml.text.api.XMLDefaultTokenContext;
50
import org.netbeans.modules.xml.text.indent.DTDIndentEngine;
47
import org.netbeans.modules.xml.text.indent.DTDIndentEngine;
51
import org.netbeans.modules.xml.text.indent.XMLIndentEngine;
48
import org.netbeans.modules.xml.text.indent.XMLIndentEngine;
52
import org.netbeans.modules.xml.text.syntax.DTDTokenContext;
53
import org.openide.text.IndentEngine;
49
import org.openide.text.IndentEngine;
54
50
55
/**
51
/**
Lines 62-71 Link Here
62
    // XML settings factory methods
58
    // XML settings factory methods
63
    // -----------------------------------------------------------------------
59
    // -----------------------------------------------------------------------
64
    
60
    
65
    // XXX: use lexer
66
    public static List getXMLTokenContext() {
67
        return Collections.singletonList(XMLDefaultTokenContext.context);
68
    }
69
    // XXX: use new editor.indent API
61
    // XXX: use new editor.indent API
70
    public static IndentEngine getXMLIndentEngine() {
62
    public static IndentEngine getXMLIndentEngine() {
71
        return new XMLIndentEngine();
63
        return new XMLIndentEngine();
Lines 81-90 Link Here
81
    // DTD settings factory methods
73
    // DTD settings factory methods
82
    // -----------------------------------------------------------------------
74
    // -----------------------------------------------------------------------
83
    
75
    
84
    // XXX: use lexer
85
    public static List getDTDTokenContext() {
86
        return Collections.singletonList(DTDTokenContext.context);
87
    }
88
    // XXX: use new editor.indent API
76
    // XXX: use new editor.indent API
89
    public static IndentEngine getDTDIndentEngine() {
77
    public static IndentEngine getDTDIndentEngine() {
90
        return new DTDIndentEngine();
78
        return new DTDIndentEngine();
(-)a/xml.text/src/org/netbeans/modules/xml/text/api/XMLTextUtils.java (+203 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2016 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 2016 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.xml.text.api;
43
44
import org.netbeans.api.editor.document.AtomicLockDocument;
45
import org.netbeans.api.editor.document.LineDocument;
46
import org.netbeans.api.editor.document.LineDocumentUtils;
47
import org.netbeans.api.lexer.Token;
48
import org.netbeans.api.lexer.TokenSequence;
49
import org.netbeans.api.xml.lexer.XMLTokenId;
50
import org.netbeans.modules.xml.text.indent.XMLLexerFormatter;
51
52
/**
53
 * Miscellaneous utilities for working with XML in text form.  This class
54
 * replaces the old Util class which contains references to old lexer and was
55
 * removed to the {@code xml.text.obsolete90} module.
56
 * 
57
 * @author sdedic
58
 * @since 1.60
59
 */
60
public final class XMLTextUtils {
61
    private XMLTextUtils() {}
62
    
63
    /**
64
     * MIME type for the text/xml documents.
65
     */
66
    public static final String XML_MIME = "text/xml";
67
68
    static String[] knownEntityStrings = {"&lt;", "&gt;", "&apos;", "&quot;", "&amp;"};
69
70
    static char[] knownEntityChars = {'<', '>', '\'', '"', '&'};
71
72
    /**
73
     * Handle fuzziness of attribute end detection. Advances the passed TokenSequence
74
     * to the token <b>after</b> attribute value end delimiter. The delimiter (quote, doublequote)
75
     * is passed as a parameter. The method returns the token after the attribute value if the delimiter is
76
     * found and positions the TokenSequence to the returned token. If there's no delimiter,
77
     * the method returns {@code null} and the TokenSequence position/state is not defined.
78
     * 
79
     * @return Token after attribute value or null.
80
     */
81
    public static Token<XMLTokenId> skipAttributeValue(TokenSequence ts, char delim) {
82
        boolean ok = true;
83
        for (; ok; ok = ts.moveNext()) {
84
            Token<XMLTokenId> next = ts.token();
85
            CharSequence cs = next.text();
86
            if (cs.charAt(cs.length() - 1) == delim) {
87
                ts.moveNext();
88
                return ts.token();
89
            }
90
        }
91
        return null;
92
    }
93
    
94
    /**
95
     * This method looks for '<' and '>' characters in attributes values and
96
     * returns whitespace-stripped substring which does not contain '<' or '>'.
97
     * This method should be used to calculate an attribute value which has
98
     * not currently been closed.
99
     * @param attributeValue an original attribute value
100
     * @return the same value of stripped substring of it.
101
     */
102
    public static String actualAttributeValue(String attributeValue) {
103
        int ltIndex = attributeValue.indexOf('<'); // NOI18N
104
        int gtIndex = attributeValue.indexOf('>'); // NOI18N
105
        int firstUnwantedIndex = -1;
106
        if (gtIndex != -1) {
107
            if (ltIndex != -1 && ltIndex < gtIndex) {
108
                firstUnwantedIndex = ltIndex;
109
            } else {
110
                firstUnwantedIndex = gtIndex;
111
            }
112
        } else {
113
            firstUnwantedIndex = ltIndex;
114
        }
115
        
116
        if (firstUnwantedIndex != -1) {
117
            char charAtIndex = attributeValue.charAt(firstUnwantedIndex);
118
            while (charAtIndex == ' ' || charAtIndex == '\t' || charAtIndex  == '\n' ||
119
            charAtIndex == '\r' || charAtIndex == '<' || charAtIndex == '>') {
120
                firstUnwantedIndex--;
121
                if (firstUnwantedIndex < 0) {
122
                    break;
123
                }
124
                charAtIndex = attributeValue.charAt(firstUnwantedIndex);
125
            }
126
            
127
            return attributeValue.substring(0, firstUnwantedIndex + 1);
128
        } else {
129
            return attributeValue;
130
        }
131
    }
132
    
133
    /**
134
     * Replaces "&lt;", "&gt;", "&apos;", "&quot;", "&amp;" with
135
     * '<', '>', '\'', '"', '&'.
136
     * @param a string that may contain &lt;", "&gt;", "&apos;", "&quot;" and "&amp;"
137
     * @return a string that may contain '<', '>', '\'', '"', '&'.
138
     */
139
    public static String replaceEntityStringsWithChars(String value) {
140
        StringBuffer buf = new StringBuffer(value);
141
        for (int entity = 0; entity < knownEntityStrings.length; entity++) {
142
            String curEntityString = knownEntityStrings[entity];
143
            int indexOfEntity = buf.toString().indexOf(curEntityString);
144
            while (indexOfEntity != -1) {
145
                buf.replace(indexOfEntity, indexOfEntity + curEntityString.length(),
146
                new String(new char[]{knownEntityChars[entity]}));
147
                indexOfEntity = buf.toString().indexOf(curEntityString);
148
            }
149
        }
150
        
151
        return buf.toString();
152
    }
153
    
154
    /**
155
     * Replaces '<', '>', '\'', '"', '&' with
156
     * "&lt;", "&gt;", "&apos;", "&quot;", "&amp;".
157
     * @param a string that may contain '<', '>', '\'', '"', '&'.
158
     * @return a string that may contain &lt;", "&gt;", "&apos;", "&quot;" and "&amp;"
159
     */
160
    public static String replaceCharsWithEntityStrings(String value) {
161
    	if (value == null) {
162
    		return null;
163
    	}
164
        StringBuffer replBuf = new StringBuffer(value.length());
165
        for (int ind = 0; ind < value.length(); ind++) {
166
            boolean charReplaced = false;
167
            char curChar = value.charAt(ind);
168
            for (int entity = 0; entity < knownEntityChars.length; entity++) {
169
                if (curChar == knownEntityChars[entity]) {
170
                    replBuf.append(knownEntityStrings[entity]);
171
                    charReplaced = true;
172
                    break;
173
                }
174
            }
175
            
176
            if (!charReplaced) {
177
                replBuf.append(curChar);
178
            }
179
        }
180
        
181
        return replBuf.toString();
182
    }
183
184
185
    /**
186
     * Convenience method to reformat portion of document using XML reformatter.
187
     * @param doc
188
     * @param startOffset
189
     * @param endOffset 
190
     * @throw IllegalArgumentException if the document implementation is not compatible
191
     */
192
    public static void reformat(final LineDocument doc, final int startOffset, final int endOffset) {
193
        final XMLLexerFormatter formatter = new XMLLexerFormatter(null);
194
        AtomicLockDocument ald = LineDocumentUtils.asRequired(doc, AtomicLockDocument.class);
195
        ald.runAtomic(new Runnable() {
196
            public void run() {
197
                formatter.doReformat(doc, startOffset, endOffset);
198
            }
199
        });
200
    }
201
    
202
}
203
(-)a/xml.text/src/org/netbeans/modules/xml/text/api/dom/SyntaxElement.java (+125 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2016 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 2016 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.xml.text.api.dom;
43
44
import javax.swing.text.Document;
45
import org.netbeans.api.annotations.common.CheckForNull;
46
import org.w3c.dom.Node;
47
48
/**
49
 * Abstract predecessor for all syntax elements - nodes, tags, attributes. 
50
 * SyntaxElement represents a piece of XML document, similar to W3C Node, exposes offset
51
 * into the underlying text. Since the syntax model
52
 * can represent an error, which is not a W3C Node. For regular pieces of
53
 * text, W3C Node can be obtained ({@link #getNode}. Nodes obtained from SyntaxElements can be converted back
54
 * using {@link XMLSyntaxSupport#getSyntaxElement}.
55
 * <p/>
56
 * Obtaining previous or next element may result in lexing through the doucment - a document read
57
 * lock is internally obtained. If the caller plans to traverse through the document, document read lock for the
58
 * whole operation should be obtained, i.e. using {@link Document#render}.
59
 * <p/>
60
 * Erroneous pieces of text are represented by SyntaxElement, which is NOT convertible to a Node. Error elements
61
 * have the {@link #getType} or {@link #NODE_ERROR}. 
62
 * </p>
63
 * <i>Note:</i> use {@link #getType} instead of {@code instanceof} operator to check for a particular
64
 * element type. <b>Do not downcast</b> the {@code SyntaxElement}, use {@link #getNode} to get the DOM Node
65
 * implementation. If the {@link #getType} returns {@link Node#ELEMENT_NODE}, it is safe to downcast 
66
 * {@code SyntaxElement} to a {@link TagElement} and use extended interface.
67
 * 
68
 * @author sdedic
69
 * @sice 1.60
70
 */
71
public interface SyntaxElement {
72
    /**
73
     * Special type of element which represent an Erroneous piece of text
74
     */
75
    public static final int NODE_ERROR = -1;
76
    
77
    /**
78
     * Returns the next element in textual order.
79
     * @return next element or {@code null}
80
     */
81
    @CheckForNull
82
    public SyntaxElement getNext();
83
    
84
    /**
85
     * Provides the previous lexical element, in textual order
86
     * @return previous element or {@code null}
87
     */
88
    @CheckForNull
89
    public SyntaxElement getPrevious();
90
    
91
    /**
92
     * @return length of the element, including children
93
     */
94
    public int getElementLength();
95
    
96
    /**
97
     * Provides element's offset in the underlying document. Note that unless
98
     * accessed under document read-lock, the offset may not point a the correct place
99
     * in the document.
100
     * @return offset of the element start
101
     */
102
    public int getElementOffset();
103
    
104
    /**
105
     * Returns type of the node. The return value is one of the W3C Node types, 
106
     * or {@link #NODE_ERROR}
107
     * @return type of element
108
     */
109
    public int getType();
110
    
111
    /**
112
     * Returns Node, if the instance can be represented in W3C DOM model.
113
     * @return represented Node or {@code null}.
114
     */
115
    @CheckForNull
116
    public <T extends Node> T getNode();
117
    
118
    /**
119
     * Returns the parent element.
120
     * @return parent element or {@code null}
121
     */
122
    @CheckForNull
123
    public SyntaxElement getParentElement();
124
    
125
}
(-)a/xml.text/src/org/netbeans/modules/xml/text/api/dom/TagElement.java (+95 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2016 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 2016 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.xml.text.api.dom;
43
44
import org.netbeans.api.annotations.common.CheckForNull;
45
46
/**
47
 * Interface implemented by start/end tags. Use it to check what kind
48
 * of tag the SyntaxElement is. SyntaxElement can be only casted if its
49
 * {@link SyntaxElement#getType) returns {@link Node#ELEMENT_NODE}.
50
 * <p/>
51
 * {@link #getStartTag} and {@link #getEndTag} can be used to navigate over to
52
 * the paired element (and then possibly next in the textual order). Note that start
53
 * tag returns itself as start tag, and end tag returns itself from its {@code getEndTag}.
54
 * A self-closing tag will return itself from both methods.
55
 * <p/>
56
 * In order to access element's name or attributes, please use DOM API (e.g.
57
 * {@code element.getNode().getNodeName()} to get tag name).
58
 * 
59
 * @author Svatopluk Dedic
60
 * @since 1.60
61
 */
62
public interface TagElement extends SyntaxElement {
63
64
    /**
65
     * @return true, if the element is a regular start element
66
     */
67
    public boolean isStart();
68
    
69
    /**
70
     * @return true, if the element is a regular closing element.
71
     */
72
    public boolean isEnd();
73
74
    /**
75
     * @return true, if self-closing element without any textual content
76
     */
77
    public boolean isSelfClosing();
78
79
    /**
80
     * Start element for this TagElement. Returns itself if {@link #isStart} or {@link #isSelfClosing()} is true.
81
     * May return {@code null} if the document is not well formed
82
     * @return corresponding start element.
83
     */
84
    @CheckForNull
85
    public TagElement getStartTag();
86
87
    /**
88
     * Element element for this TagElement. Returns itself if {@link #isEnd} or {@link #isSelfClosing()} is true.
89
     * May return {@code null} if the document is not well formed
90
     * @return corresponding start element.
91
     */
92
    @CheckForNull
93
    public TagElement getEndTag();
94
    
95
}
(-)a/xml.text/src/org/netbeans/modules/xml/text/dom/XMLSyntaxSupport.java (-90 / +603 lines)
Lines 42-154 Link Here
42
 * made subject to such option by the copyright holder.
42
 * made subject to such option by the copyright holder.
43
 */
43
 */
44
44
45
package org.netbeans.modules.xml.text.dom;
45
package org.netbeans.modules.xml.text.api.dom;
46
46
47
import com.sun.istack.internal.NotNull;
48
import java.lang.ref.Reference;
49
import java.lang.ref.WeakReference;
50
import java.util.ArrayDeque;
51
import java.util.ArrayList;
52
import java.util.Arrays;
53
import java.util.Collections;
54
import java.util.Deque;
55
import java.util.EnumSet;
56
import java.util.LinkedList;
57
import java.util.List;
58
import java.util.Map;
59
import java.util.Stack;
47
import java.util.WeakHashMap;
60
import java.util.WeakHashMap;
61
import java.util.concurrent.Callable;
62
import java.util.function.BiPredicate;
48
import javax.swing.event.DocumentListener;
63
import javax.swing.event.DocumentListener;
49
import javax.swing.event.DocumentEvent;
64
import javax.swing.event.DocumentEvent;
50
65
51
import javax.swing.text.AbstractDocument;
66
import javax.swing.text.AbstractDocument;
52
import javax.swing.text.BadLocationException;
67
import javax.swing.text.BadLocationException;
68
import javax.swing.text.Document;
53
import javax.swing.text.JTextComponent;
69
import javax.swing.text.JTextComponent;
70
import org.netbeans.api.annotations.common.CheckForNull;
71
import org.netbeans.api.annotations.common.NonNull;
72
import org.netbeans.api.annotations.common.NullAllowed;
73
import org.netbeans.api.annotations.common.NullUnknown;
74
import org.netbeans.api.editor.document.LineDocument;
54
import org.netbeans.api.lexer.Token;
75
import org.netbeans.api.lexer.Token;
55
import org.netbeans.api.lexer.TokenHierarchy;
76
import org.netbeans.api.lexer.TokenHierarchy;
56
import org.netbeans.api.lexer.TokenSequence;
77
import org.netbeans.api.lexer.TokenSequence;
57
import org.netbeans.api.xml.lexer.XMLTokenId;
78
import org.netbeans.api.xml.lexer.XMLTokenId;
79
import static org.netbeans.api.xml.lexer.XMLTokenId.ARGUMENT;
80
import static org.netbeans.api.xml.lexer.XMLTokenId.OPERATOR;
58
import org.netbeans.editor.BaseDocument;
81
import org.netbeans.editor.BaseDocument;
59
import org.openide.util.WeakListeners;
82
import org.netbeans.modules.xml.text.dom.BaseSyntaxElement;
83
import org.netbeans.modules.xml.text.dom.CDATASection;
84
import org.netbeans.modules.xml.text.dom.Comment;
85
import org.netbeans.modules.xml.text.dom.DocumentType;
86
import org.netbeans.modules.xml.text.dom.EmptyTag;
87
import org.netbeans.modules.xml.text.dom.EndTag;
88
import org.netbeans.modules.xml.text.dom.ProcessingInstruction;
89
import org.netbeans.modules.xml.text.dom.StartTag;
90
import org.netbeans.modules.xml.text.dom.TextImpl;
91
import org.w3c.dom.NamedNodeMap;
92
import org.w3c.dom.Node;
60
93
61
/**
94
/**
62
 * Creates higher level syntax elements (DOM nodes) above token chain.
95
 * Creates higher level syntax elements (DOM nodes) above token chain from XML lexer.
63
 *
96
 * The support class provides API to access lexical tokens around a particular location
97
 * and build a navigable DOM-like structure for the text over the lexer output so the
98
 * clients may read attributes, values and traverse the document. The structure may
99
 * be built incrementally on demand so if the client traverses or works with the entire
100
 * structure, the document should be read-locked; otherwise the element starts/ends may get
101
 * screwed by concurrent document mutations.
102
 * <p/>
103
 * The XMLSyntaxSupport creates DOM node implementations based on the lexer tokens. The entire
104
 * structure is coupled together but its entry points are only weakly referenced; once the caller
105
 * looses all references to SyntaxElements and XMLSyntaxSupport, the entire structure may
106
 * be collected.
107
 * <p/>
108
 * SyntaxElements are created on-demand and incrementally. 
109
 * It's not guaranteed that {@link #getElementChain} returns the same instance 
110
 * for the same offset if called multiple times. Also when document is traversed starting from
111
 * different SyntaxElements, the same offset/place in the document may be represented by 
112
 * different SyntaxElement instances in both traversals. Use {@link SyntaxElement#getElementOffset} to
113
 * check if the underlying location is the same.
114
 * <p/>
115
 * In order to traverse through lexical {@link Token}s, the client may call {@link #runWithSequence(int, org.netbeans.modules.xml.text.api.dom.XMLSyntaxSupport.SequenceCallable)}
116
 * and get access to the {@link TokenSequence} of XML tokens. User code executes with document
117
 * read-locked and all calls from user code to {@link #getPreviousToken(int)}, {@link #getNextToken(int)} will use that
118
 * same sequence, so the sequence can be queried for current offset or repositioned.
119
 * 
64
 * @author  Samaresh Panda
120
 * @author  Samaresh Panda
121
 * @author Svatopluk Dedic
122
 * @since 1.60
65
 */
123
 */
66
public class XMLSyntaxSupport {
124
public final class XMLSyntaxSupport {
67
    
125
    
68
    /** Holds last character user have typed. */
126
    /** Holds last character user have typed. */
69
    private char lastInsertedChar = 'X';  // NOI18N
70
    private final DocumentMonitor documentMonitor;
127
    private final DocumentMonitor documentMonitor;
71
    private BaseDocument document;
128
    private final BaseDocument document;
72
    private static WeakHashMap<BaseDocument, XMLSyntaxSupport> supportMap =
129
    private final static Map<BaseDocument, Reference<XMLSyntaxSupport>> supportMap =
73
            new WeakHashMap<BaseDocument, XMLSyntaxSupport>();
130
            new WeakHashMap<>();
74
    
131
    
75
    /** Creates new XMLSyntaxSupport */
132
    /** Creates new XMLSyntaxSupport */
76
    private XMLSyntaxSupport(BaseDocument doc) {
133
    private XMLSyntaxSupport(BaseDocument doc) {
77
        this.document = doc;
134
        this.document = doc;
78
        documentMonitor = new DocumentMonitor();
135
        documentMonitor = createDocumentMonitor();
79
        DocumentListener l = WeakListeners.document(documentMonitor, doc);
136
    }
80
        doc.addDocumentListener(l);
137
    
138
    private DocumentMonitor createDocumentMonitor() {
139
        synchronized (document) {
140
            Object o = document.getProperty(DocumentMonitor.class);
141
            if (o != null) {
142
                return (DocumentMonitor)o;
143
            }
144
            DocumentMonitor m = new DocumentMonitor();
145
            document.addDocumentListener(m);
146
            document.putProperty(DocumentMonitor.class, m);
147
            return m;
148
        }        
149
    }
150
    
151
    /**
152
     * Creates a new instance for the given document. The instance will not be
153
     * registered anywhere; the caller is responsible for bookkeeping. The method
154
     * can return null if the document implementation is not appropriate (does
155
     * not offer appropriate API/services). NB editor documents are guaranteed
156
     * to work with this support.
157
     * 
158
     * @param d document
159
     * @return XML support instance, or {@code null} for incompatible documents.
160
     */
161
    @CheckForNull
162
    public static XMLSyntaxSupport createSyntaxSupport(Document d) {
163
        if (d == null) {
164
            throw new NullPointerException("Document may not be null");
165
        }
166
        if (!(d instanceof BaseDocument)) {
167
            return null;
168
        }
169
        BaseDocument doc = (BaseDocument)d;
170
        return new XMLSyntaxSupport(doc);
81
    }
171
    }
82
172
83
    public static XMLSyntaxSupport getSyntaxSupport(BaseDocument doc) {
173
    /**
84
        XMLSyntaxSupport support = supportMap.get(doc);
174
     * Obtains XML Syntax support for the document. The instance may be shared
175
     * with different callers working with the same Document instance. May return
176
     * {@code null} for an incompatible Document; NB Editor documents are guaranteed
177
     * to work.
178
     * 
179
     * @param d underlying document
180
     * @return syntax support
181
     */
182
    @CheckForNull
183
    public static XMLSyntaxSupport getSyntaxSupport(Document d) {
184
        if (d == null) {
185
            throw new NullPointerException("Document may not be null");
186
        }
187
        if (!(d instanceof BaseDocument)) {
188
            return null;
189
        }
190
        BaseDocument doc = (BaseDocument)d;
191
        XMLSyntaxSupport support = null;
192
        Reference<XMLSyntaxSupport> refSupport = supportMap.get(doc);
193
        if (refSupport != null) {
194
            support = refSupport.get();
195
        }
85
        if(support != null)
196
        if(support != null)
86
            return support;
197
            return support;
87
198
88
        support = new XMLSyntaxSupport(doc);
199
        support = new XMLSyntaxSupport(doc);
89
        supportMap.put(doc, support);
200
        supportMap.put(doc, new WeakReference<>(support));
90
        return support;
201
        return support;
91
    }
202
    }
92
203
93
    public BaseDocument getDocument() {
204
    /**
205
     * @return underlying Document instance
206
     */
207
    @NotNull
208
    public LineDocument getDocument() {
94
        return document;
209
        return document;
95
    }
210
    }
96
    
211
    
97
    /**
212
    /**
213
     * Run the given operation on a read-locked document. 
214
     * @param <T> return type
215
     * @param userCode code to execute under the lock
216
     * @return result of user code.
217
     * @throws BadLocationException propagated from the user code
218
     * @throws IllegalStateException if a checked exception occurs in user code
219
     */
220
    @NullUnknown
221
    public <T> T runLocked(Callable<T> userCode) throws BadLocationException {
222
        try {
223
            ((AbstractDocument)document).readLock();
224
            return userCode.call();
225
        } catch (BadLocationException | RuntimeException ex) {
226
            throw ex;
227
        } catch (Exception ex) {
228
            throw new IllegalStateException(ex);
229
        } finally {
230
            ((AbstractDocument)document).readUnlock();
231
        }
232
    }
233
    
234
    /**
235
     * Callback interface for user operation, which runs on lexical token sequence. 
236
     * If the client needs to iterativaly traverse {@link TokenSequence} of tokens in the document,
237
     * calling {@link #getNextToken(int)} could be expensive and unreliable, as each call locks/unlocks the
238
     * document. Clients may use {@link #runWithSequence(org.netbeans.api.lexer.Token, org.netbeans.modules.xml.text.api.dom.XMLSyntaxSupport.SequenceCallable)}
239
     * to get access to the TokenSequence and work with it under document read lock.
240
     * 
241
     * @param <T> result of the user code
242
     */
243
    public interface SequenceCallable<T> {
244
        /**
245
         * Callback which receives the TokenSequence instance
246
         * @param sequence initialized TokenSequence
247
         * @return user-defined value
248
         * @throws BadLocationException should be thrown if navigation fails; propagated from the {@code runWithSequence}
249
         */
250
        public T call(@NonNull TokenSequence sequence) throws BadLocationException;
251
    }
252
    
253
    private ThreadLocal<TokenSequence> cachedSequence = new ThreadLocal<>();
254
    
255
    private TokenSequence getSequence() {
256
        TokenSequence cached = cachedSequence.get();
257
        if (cached != null) {
258
            return cached;
259
        }
260
        TokenHierarchy th = TokenHierarchy.get(((AbstractDocument)document));
261
        TokenSequence ts = th.tokenSequence();
262
        return ts;
263
    }
264
    
265
    /**
266
     * Executes user code on token sequence from the document.
267
     * Read-locks the document, obtains {@link TokenSequence} from the Lexer and executes {@code userCode} 
268
     * passing the initialized sequence. The sequence is moved to the desired offset and the token that contains
269
     * or starts at that position. The client can move the sequence elsewhere.
270
     * <p/>
271
     * If the {@code userCode} calls this {@code SyntaxSupport} methods like {@link #getNextToken(int)}, they will use
272
     * the <b>same TokenSequence</b> as passed to {@code userCode}. This allows to combine navigation calls from {@link XMLSyntaxSupport}
273
     * with client's own sequence movements. The TokenSequence instance passed to {@code userCode} can be queried for
274
     * current token offset after navigation.
275
     * 
276
     * @param <T>
277
     * @param offset offset to position the sequence at
278
     * @param userCode code to execute
279
     * @return user-defined value
280
     * @throws BadLocationException if the user code throws BadLocationException
281
     * @throws IllegalStateException if the user code throws a checked exception
282
     */
283
    @NullUnknown
284
    public <T> T runWithSequence(int offset, SequenceCallable<T> userCode) throws BadLocationException {
285
        T result;
286
        TokenSequence old = null;
287
        try {
288
            ((AbstractDocument)document).readLock();
289
            old = cachedSequence.get();
290
            cachedSequence.remove();
291
            TokenSequence ts = getSequence();
292
            if (ts == null) {
293
                throw new BadLocationException("No sequence for position", offset); // NOI18N
294
            }
295
            cachedSequence.set(ts);
296
            synchronized (ts) {
297
                ts.move(offset);
298
                ts.moveNext();
299
                result = userCode.call(ts);
300
            }
301
        } finally {
302
            cachedSequence.set(old);
303
            ((AbstractDocument)document).readUnlock();
304
        }
305
        return result;
306
    }
307
    
308
    /**
309
     * Exeutes user code with {@link TokenSequence} positioned at a particular token.
310
     * This convenience method works much like {@link #runWithSequence(int, org.netbeans.modules.xml.text.api.dom.XMLSyntaxSupport.SequenceCallable)},
311
     * except that Token (its starting offset) is used to position the sequence instead of raw offset value. 
312
     * 
313
     * @param <T>
314
     * @param startFrom token to start from
315
     * @param userCode user code to execute
316
     * @return user-defined value
317
     * @throws BadLocationException if the user code throws BadLocationException
318
     */
319
    public <T> T runWithSequence(Token<XMLTokenId> startFrom, SequenceCallable<T> userCode) throws BadLocationException {
320
        T result;
321
        TokenSequence old = null;
322
        try {
323
            ((AbstractDocument)document).readLock();
324
            old = cachedSequence.get();
325
            cachedSequence.remove();
326
            TokenHierarchy th = TokenHierarchy.get(((AbstractDocument)document));
327
            TokenSequence ts = th.tokenSequence();
328
            if (ts == null) {
329
                throw new BadLocationException("No sequence for position", startFrom.offset(null)); // NOI18N
330
            }
331
            cachedSequence.set(ts);
332
            synchronized (ts) {
333
                ts.move(startFrom.offset(th));
334
                ts.moveNext();
335
                result = userCode.call(ts);
336
            }
337
        } finally {
338
            cachedSequence.set(old);
339
            ((AbstractDocument)document).readUnlock();
340
        }
341
        return result;
342
    }
343
    
344
    /**
98
     * Get token at given offet or previous one if at token boundary.
345
     * Get token at given offet or previous one if at token boundary.
99
     * It does not lock the document.
346
     * It does not lock the document. 
347
     * <p/>
348
     * Note: if the call is made within {@link #runWithSequence(int, org.netbeans.modules.xml.text.api.dom.XMLSyntaxSupport.SequenceCallable)} exection scope, the
349
     * search for previous token will use the same TokenSequence as passed to executed user callback.
350
     * 
100
     * @param offset valid position in document
351
     * @param offset valid position in document
101
     * @return TokenItem or <code>null</code> at the document beginning.
352
     * @return TokenItem or <code>null</code> at the document beginning.
102
     */
353
     */
103
    public Token getPreviousToken( int offset) throws BadLocationException {
354
    public Token<XMLTokenId> getPreviousToken( int offset) throws BadLocationException {
104
        if (offset == 0) return null;
355
        if (offset == 0) return null;
105
        if (offset < 0) throw new BadLocationException("Offset " +
356
        if (offset < 0) throw new BadLocationException("Offset " +
106
                offset + " cannot be less than 0.", offset);  //NOI18N
357
                offset + " cannot be less than 0.", offset);  //NOI18N
107
        ((AbstractDocument)document).readLock();
358
        ((AbstractDocument)document).readLock();
108
        try {
359
        try {
109
            TokenHierarchy th = TokenHierarchy.get(((AbstractDocument)document));
360
            TokenSequence ts = getSequence();
110
            TokenSequence ts = th.tokenSequence();
361
            synchronized (ts) {
111
            return getToken(ts, offset, false);
362
                return getToken(ts, offset, false, null);
363
            }
112
        } finally {
364
        } finally {
113
            ((AbstractDocument)document).readUnlock();
365
            ((AbstractDocument)document).readUnlock();
114
        }
366
        }
115
    }
367
    }
116
368
    
117
    /**
369
    /**
118
     * Get token at given offet or previous one if at token boundary.
370
     * Get token at given offet or previous one if at token boundary.
119
     * It does not lock the document.
371
     * 
372
     * It does not lock the document. 
373
     * <p/>
374
     * Note: if the call is made within {@link #runWithSequence(int, org.netbeans.modules.xml.text.api.dom.XMLSyntaxSupport.SequenceCallable)} exection scope, the
375
     * search for previous token will use the same TokenSequence as passed to executed user callback.
376
     * <p/>
377
     * This variant returns start + end (after the token) offsets for the caller's convenience.
378
     * 
120
     * @param offset valid position in document
379
     * @param offset valid position in document
380
     * @param tokenBounds output; will receive token start and end positions
121
     * @return TokenItem or <code>null</code> at the document beginning.
381
     * @return TokenItem or <code>null</code> at the document beginning.
122
     */
382
     */
123
    public Token getNextToken( int offset) throws BadLocationException {
383
    public Token<XMLTokenId> getPreviousToken(int offset, int[] tokenBounds) throws BadLocationException {
124
        if (offset == 0) return null;
384
        if (offset == 0) return null;
125
        if (offset < 0) throw new BadLocationException("Offset " +
385
        if (offset < 0) throw new BadLocationException("Offset " +
126
                offset + " cannot be less than 0.", offset);  //NOI18N
386
                offset + " cannot be less than 0.", offset);  //NOI18N
127
        ((AbstractDocument)document).readLock();
387
        ((AbstractDocument)document).readLock();
128
        try {
388
        try {
129
            TokenHierarchy th = TokenHierarchy.get(((AbstractDocument)document));
389
            TokenSequence ts = getSequence();
130
            TokenSequence ts = th.tokenSequence();
390
            synchronized (ts) {
131
            return getToken(ts, offset, true);
391
                return getToken(ts, offset, false, tokenBounds);
392
            }
132
        } finally {
393
        } finally {
133
            ((AbstractDocument)document).readUnlock();
394
            ((AbstractDocument)document).readUnlock();
134
        }
395
        }
135
    }
396
    }
136
    
397
    
137
    private Token getToken(TokenSequence ts, int offset, boolean next) {
398
    /**
138
        ts.move(offset);
399
     * Returns the token occupying the given position. The token either extends over this position, or
139
        Token token = ts.token();
400
     * it starts at that position (first token's char offset == offset).
140
        //there are cases when this could be null
401
     * 
141
        //in which case use the next one.
402
     * @param offset offset in text for which the Token should be produced
142
        if(token == null)
403
     * @return XML token occupying the position
143
            ts.moveNext();
404
     * @throws BadLocationException 
405
     */
406
    public Token<XMLTokenId> getTokenAtPosition(int offset, int[] tokenBounds) throws BadLocationException {
407
        return getNextToken(offset + 1, tokenBounds);
408
    }
144
409
410
    /**    
411
     * Retrieves the start of an attribute token. If the passed position does not correspond to
412
     * attribute value, operator or whitespace (between attribute name and value), {@code null}
413
     * is returned.
414
     * <p/>
415
     * Convenience method.
416
     * 
417
     * @param offset starting offset
418
     * @return token corresponding to the attribute name ({@link XMLTokenId#ARGUMENT}).
419
     */
420
    public Token<XMLTokenId> getAttributeToken(int offset) {
421
        try {
422
            return this.<Token<XMLTokenId>>runWithSequence(offset, (TokenSequence ts) -> {
423
                Token<XMLTokenId> currentToken = ts.token();
424
                if(currentToken.id() != XMLTokenId.VALUE) {
425
                    return null;
426
                }
427
                Token<XMLTokenId> equalsToken = null;
428
                while (ts.movePrevious()) {
429
                    Token<XMLTokenId> t = ts.token();
430
                    if (t.id() == OPERATOR) {
431
                        equalsToken = t;
432
                        break;
433
                    } else if (t.id() == XMLTokenId.ARGUMENT) {
434
                        return t;
435
                    } else if (t.id() != XMLTokenId.WS) {
436
                        return null;
437
                    }
438
                }
439
                if(equalsToken == null) {
440
                    return null;
441
                }
442
                while (ts.movePrevious()) {
443
                    Token<XMLTokenId> t = ts.token();
444
                    if (t.id() == ARGUMENT) {
445
                        return t;
446
                    } else if (t.id() != XMLTokenId.WS) {
447
                        return null;
448
                    }
449
                }
450
                return null;
451
            });
452
        } catch (BadLocationException ex) {
453
        }
454
        return null;
455
    }
456
    
457
    
458
    /**
459
     * Get token at given offet or previous one if at token boundary.
460
     * It does not lock the document. Returns {@code null} for invalid offsets.
461
     * 
462
     * @param offset valid position in document
463
     * @return Token instance
464
     */
465
    public Token<XMLTokenId> getNextToken( int offset) throws BadLocationException {
466
        if (offset == 0) {
467
            offset = 1;
468
        }
469
        if (offset < 0) throw new BadLocationException("Offset " +
470
                offset + " cannot be less than 0.", offset);  //NOI18N
471
        ((AbstractDocument)document).readLock();
472
        try {
473
            TokenSequence ts = getSequence();
474
            synchronized (ts) {
475
                return getToken(ts, offset, true, null);
476
            }
477
        } finally {
478
            ((AbstractDocument)document).readUnlock();
479
        }
480
    }
481
    
482
    /**
483
     * Get token at given offet or previous one if at token boundary.
484
     * It does not lock the document. Returns {@code null} for invalid offsets.
485
     * <p/>
486
     * This variant returns start + end (after the token) offsets for the caller's convenience.
487
     * 
488
     * @param offset valid position in document
489
     * @param tokenBounds output; will receive token start and end positions
490
     * @return Token instance
491
     */
492
    public Token getNextToken( int offset, int[] tokenBounds) throws BadLocationException {
493
        if (offset == 0) return null;
494
        if (offset < 0) throw new BadLocationException("Offset " +
495
                offset + " cannot be less than 0.", offset);  //NOI18N
496
        ((AbstractDocument)document).readLock();
497
        try {
498
            TokenSequence ts = getSequence();
499
            synchronized (ts) {
500
                return getToken(ts, offset, true, tokenBounds);
501
            }
502
        } finally {
503
            ((AbstractDocument)document).readUnlock();
504
        }
505
    }
506
    
507
    private Token getToken(TokenSequence ts, int offset, boolean next, int[] startOffset) {
508
        int diff = ts.move(offset);
509
        boolean ok;
145
        if(next) {
510
        if(next) {
146
            ts.moveNext();
511
            ok = ts.moveNext();
512
        } else if (diff > 0) {
513
            ok = ts.moveNext();
147
        } else {
514
        } else {
148
            ts.movePrevious();
515
            ok = ts.movePrevious();
149
        }
516
        }
150
        token = ts.token();
517
        if (!ok) {
151
        return token;
518
            return null;
519
        }
520
        if (startOffset != null) {
521
            startOffset[0] = ts.offset();
522
            if (startOffset.length > 1) {
523
                startOffset[1] = ts.offset() + ts.token().length();
524
            }
525
        }
526
        return ts.token();
152
    }
527
    }
153
528
154
    
529
    
Lines 158-170 Link Here
158
     * @param offset Offset in document where to search for SyntaxElement.
533
     * @param offset Offset in document where to search for SyntaxElement.
159
     * @return SyntaxElement Element surrounding or laying BEFORE the offset
534
     * @return SyntaxElement Element surrounding or laying BEFORE the offset
160
     * or <code>null</code> at document begining.
535
     * or <code>null</code> at document begining.
536
     * @throws javax.swing.text.BadLocationException when offset is invalid or navigation fails
161
     */
537
     */
162
    public SyntaxElement getElementChain(final int offset ) throws BadLocationException {
538
    public SyntaxElement getElementChain(final int offset ) throws BadLocationException {
163
539
164
        ((AbstractDocument)document).readLock();
540
        ((AbstractDocument)document).readLock();
165
        try {
541
        try {
166
            TokenHierarchy th = TokenHierarchy.get(((AbstractDocument)document));
542
            TokenSequence<XMLTokenId> ts = getSequence();
167
            TokenSequence<XMLTokenId> ts = th.tokenSequence();
168
            Token<XMLTokenId> token = initialize(ts, offset);
543
            Token<XMLTokenId> token = initialize(ts, offset);
169
            if(token == null)
544
            if(token == null)
170
                return null;
545
                return null;
Lines 198-210 Link Here
198
    }
573
    }
199
574
200
    private Token<XMLTokenId> initialize(TokenSequence ts, int offset) {
575
    private Token<XMLTokenId> initialize(TokenSequence ts, int offset) {
201
        ts.move(offset);
576
        int diff = ts.move(offset);
202
        Token<XMLTokenId> token = ts.token();
577
        Token<XMLTokenId> token = ts.token();
203
        if(token == null) {
578
        if (diff > 0) {
204
            if(!ts.moveNext())
579
            if (!ts.moveNext()) {
205
                return null;
580
                return null;
206
            token = ts.token();
581
            }
582
        } else if (!ts.movePrevious()) {
583
            return null;
207
        }
584
        }
585
        token = ts.token();
208
        XMLTokenId id = token.id();
586
        XMLTokenId id = token.id();
209
        String image = token.text().toString();
587
        String image = token.text().toString();
210
        if ( id == XMLTokenId.WS ||
588
        if ( id == XMLTokenId.WS ||
Lines 267-273 Link Here
267
            }
645
            }
268
            
646
            
269
            case TEXT: {
647
            case TEXT: {
270
                return new Text(this, token, start, end);
648
                return new TextImpl(this, token, start, end);
271
            }
649
            }
272
650
273
            case TAG: {
651
            case TAG: {
Lines 289-350 Link Here
289
            }
667
            }
290
668
291
            case ERROR: {
669
            case ERROR: {
292
                return new SyntaxElement.Error(this, token, start, end );
670
                return new BaseSyntaxElement.Error(this, token, start, end );
293
            }
671
            }
294
        }
672
        }
295
673
296
        return null;
674
        return null;
297
    }
675
    }
298
676
299
    /**
677
    /** 
300
     * No completion inside PI, CDATA, comment section.
678
     * Returns last inserted character. 
301
     * True only inside PI or CDATA section, false otherwise.
679
     * It's most likely one recently typed by user. Note that in order to start capturing
302
     * @param target
680
     * editor events, the XMLSupport must be activated for the document. When XMLSupport is first 
681
     * created for a Document, it does not provide any lastTypedChar; the subsequent edits are
682
     * recorded.
303
     */
683
     */
304
    public static boolean noCompletion(JTextComponent target) {
305
        if(target == null || target.getCaret() == null)
306
            return false;
307
        int offset = target.getCaret().getDot();
308
        if(offset < 0)
309
            return false;
310
        //no completion inside CDATA or comment section
311
        BaseDocument document = (BaseDocument)target.getDocument();
312
        ((AbstractDocument)document).readLock();
313
        try {
314
            TokenHierarchy th = TokenHierarchy.get(document);
315
            TokenSequence ts = th.tokenSequence();
316
            if(ts == null)
317
                return false;
318
            ts.move(offset);
319
            Token token = ts.token();
320
            if(token == null) {
321
                ts.moveNext();
322
                token = ts.token();
323
                if(token == null)
324
                    return false;
325
            }
326
            if( token.id() == XMLTokenId.CDATA_SECTION ||
327
               token.id() == XMLTokenId.BLOCK_COMMENT ||
328
               token.id() == XMLTokenId.PI_START ||
329
               token.id() == XMLTokenId.PI_END ||
330
               token.id() == XMLTokenId.PI_CONTENT ||
331
               token.id() == XMLTokenId.PI_TARGET ) {
332
               return true;
333
            }
334
        } finally {
335
            ((AbstractDocument)document).readUnlock();
336
        }
337
338
        return false;
339
    }
340
341
    /** Returns last inserted character. It's most likely one recently typed by user. */
342
    public final char lastTypedChar() {
684
    public final char lastTypedChar() {
343
        return lastInsertedChar;
685
        return documentMonitor.lastInsertedChar;
344
    }
686
    }
345
        
687
        
346
    /** Keep track of last typed character */
688
    /** Keep track of last typed character */
347
    private class DocumentMonitor implements DocumentListener {
689
    private static class DocumentMonitor implements DocumentListener {
690
        
691
        private char lastInsertedChar = 'X';  // NOI18N
348
        
692
        
349
        public void changedUpdate(DocumentEvent e) {
693
        public void changedUpdate(DocumentEvent e) {
350
        }
694
        }
Lines 362-366 Link Here
362
        public void removeUpdate(DocumentEvent e) {
706
        public void removeUpdate(DocumentEvent e) {
363
        }
707
        }
364
    }
708
    }
709
    
710
    /**
711
     * Determines if the SyntaxElement is a start or end tag.
712
     * 
713
     * @param n element to test
714
     * @return true, if the element is a start or end tag. False if Node does not represent a tag, or for an empty tag
715
     */
716
    public boolean isNormalTag(SyntaxElement n) {
717
        return isStartTag(n) || isEndTag(n);
718
    }
719
    
720
    /**
721
     * Determines if the SyntaxElement is a start tag.
722
     * Returns {@code false} if Node does not represent a start tag, or is a self-closed (empty content) tag
723
     * @param n element to test
724
     * @return true, if the element is a start tag.
725
     */
726
    public boolean isStartTag(SyntaxElement n) {
727
        return n instanceof StartTag;
728
    }
729
    
730
    /**
731
     * Returns true iff the element is a self-closing tag.
732
     * Returns true if and only if the SyntaxElement represents a self-closing tag without content. False otherwise.
733
     * @param n element to check
734
     * @return true, if self-closing tag
735
     */
736
    public boolean isEmptyTag(SyntaxElement n) {
737
        return n instanceof EmptyTag;
738
    }
739
    
740
    /**
741
     * Determines if the SyntaxElement is an end tag.
742
     * Returns {@code false} if Node does not represent an end tag, or is a self-closed (empty content) tag
743
     * @param n element to test
744
     * @return true, if the element is a start tag.
745
     */
746
    public boolean isEndTag(SyntaxElement n) {
747
        return n instanceof EndTag;
748
    }
749
    
750
    /**
751
     * Returns text offset of the Node start in the underlying document.
752
     * Returns -1 if the offset could not be determined. Use this method to find out
753
     * offset of a DOM Node obtained from a {@link SyntaxElement} or {@link XMLSyntaxSupport}
754
     * @param n
755
     * @return offset or -1 if the offset could not be determined.
756
     */
757
    public int getNodeOffset(Node n) {
758
        if (!(n instanceof SyntaxElement)) {
759
            if (n instanceof Document) {
760
                return 0;
761
            }
762
            return -1;
763
        } 
764
        return ((SyntaxElement)n).getElementOffset();
765
    }
766
    
767
    /**
768
     * Obtains a SyntaxElement for the W3C Node, if possible.
769
     * @param n the Node
770
     * @return corresponding SyntaxElement or {@code null}.
771
     */
772
    public SyntaxElement getSyntaxElement(Node n) {
773
        if (n instanceof SyntaxElement) {
774
            return (SyntaxElement)n;
775
        } else {
776
            return null;
777
        }
778
    }
779
    
780
    /**
781
     * Convenience method to get attribute value as string. Returns {@code null}
782
     * if the Node is not a start/empty element, or does not contain attribute of the specified name.
783
     * For namespaced names, you must use the exact {@code prefix:localName}.
784
     * 
785
     * @param n node
786
     * @param name attribute name
787
     * @return attribute (string) value or {@code null} if no such attribute exist for element n.
788
     */
789
    public static String getAttributeValue(Node n, String name) {
790
        NamedNodeMap a = n.getAttributes();
791
        if (a == null) {
792
            return null;
793
        }
794
        Node item = a.getNamedItem(name);
795
        if (item == null) {
796
            return null;
797
        }
798
        return item.getNodeValue();
799
    }
800
801
    /**
802
     * Constructs a path from the root of the document to the given syntax element.
803
     * 
804
     * @param element the element to start with
805
     * @return top-down path of SyntaxElements from the document root towards the original SyntaxElement
806
     */
807
    public List<SyntaxElement> getPathFromRoot(SyntaxElement element) {
808
        Deque<SyntaxElement> stack = new ArrayDeque<>();
809
        SyntaxElement elementRef = element;
810
        while (elementRef != null) {
811
            if (isEndTag(element) ||
812
                    (isEmptyTag(elementRef) && stack.isEmpty()) ||
813
                    (isStartTag(elementRef) && stack.isEmpty())) {
814
                stack.push(elementRef);
815
                elementRef = elementRef.getPrevious();
816
                continue;
817
            }
818
            if (isStartTag(elementRef)) {
819
                if (isEndTag(stack.peek())) {
820
                    SyntaxElement end = stack.peek();
821
                    if (end.getNode().getNodeName().equals(elementRef.getNode().getNodeName())) {
822
                        stack.pop();
823
                    }
824
                } else {
825
                    SyntaxElement e = stack.peek();
826
                    stack.push(elementRef);
827
                }
828
            }
829
            elementRef = elementRef.getPrevious();
830
        }
831
        // reverse:
832
        List<SyntaxElement> res = new ArrayList<>(stack.size());
833
        while ((elementRef = stack.poll()) != null) {
834
            res.add(elementRef);
835
        }
836
        return res;
837
    }
838
    
839
    /**
840
     * Skips forward or backward specified token types. Simplified variant of {@link #skip(int, boolean, java.util.function.BiPredicate)},
841
     * only token types to skip can be specified. The first token of type other than those passed in {@code skipTokens} will be returned from the method.
842
     * 
843
     * @param offset position to start at.
844
     * @param forward true means froward, false backward
845
     * @param skipTokens token types to skip
846
     * @return first token whose type does not match the specified values
847
     * @throws BadLocationException 
848
     */
849
    public Token<XMLTokenId> skip(int offset, boolean forward, XMLTokenId... skipTokens) throws BadLocationException {
850
        EnumSet<XMLTokenId> en = EnumSet.copyOf(Arrays.asList(skipTokens));
851
        return skip(offset, forward, (TokenSequence s, Token<XMLTokenId> t) -> en.contains(t.id()));
852
    }
853
    
854
    /**
855
     * Skips tokens matched by the predicate from the given offset. Positions {@link TokenSequence} on the specified offset,
856
     * then traverses either forward or backward, depending on a parameter until the predicate returns false. 
857
     * The token for which the predicate failed will be returned as the return value.
858
     * 
859
     * @param offset offset to start traversal
860
     * @param forward true for forward traversal, false for backward
861
     * @param pred predicate to match tokens. Method skips tokens that satisfy the predicate (until the first which does not)
862
     * @return
863
     * @throws BadLocationException 
864
     */
865
    public Token<XMLTokenId>  skip(int offset, boolean forward, BiPredicate<TokenSequence, Token<XMLTokenId>> pred) throws BadLocationException {
866
        Token<XMLTokenId> tukac = runWithSequence(offset, (TokenSequence s) -> {
867
            s.move(offset);
868
            while ((forward && s.moveNext()) || (!forward && s.movePrevious())) {
869
                if (!pred.test(s, s.token())) {
870
                    return s.token();
871
                }
872
            }
873
            return null;
874
        });
875
        return tukac;
876
    }
877
        
365
}
878
}
366
879
(-)a/projectapi/src/org/netbeans/spi/project/package.html (-12 / +20 lines)
Lines 36-55 Link Here
36
made subject to such option by the copyright holder.
36
made subject to such option by the copyright holder.
37
37
38
Contributor(s):
38
Contributor(s):
39
40
Portions Copyrighted 2016 Sun Microsystems, Inc.
39
-->
41
-->
40
<html>
42
<html>
41
<body>
43
<body>
42
44
    <p>
43
Support for defining project types.
45
        API for read-only access XML structure using DOM-like interface. Implemented over XML lexer,
44
46
        so the structure can be obtained even on malformed, unfinished or errneous documents.
45
<p>Each kind of project in the system needs to be loaded by a
47
        The caller may obtain a SyntaxElement corresponding to a given textual position in the XML document.
46
{@link org.netbeans.spi.project.ProjectFactory}, which defines how to recognize
48
        The SyntaxElement can be used to both read contents (attributes, tag name, ...) of the document,
47
projects on disk, load their metadata into memory, and save their metadata back
49
        or navigate to sibling, predecessor, parent or child Elements. SyntaxElement can be converted to 
48
to disk. {@link org.netbeans.spi.project.ProjectState} is used to let the
50
        DOM Node; DOM Nodes obtained originally as a result of SyntaxElement conversion can be converted
49
factory mark a project as being modified in memory.</p>
51
        back to SyntaxElements so the caller can retrieve their position within the document.
50
52
    </p>
51
<p>Projects will normally put implementations of several interfaces such as
53
    <p>
52
{@link org.netbeans.spi.project.ActionProvider} into their lookup.</p>
54
        It is advisable to perform searches or navigation through the document under a document read (write)
53
55
        lock. Implementations in this package read-lock the document internally, but generally no lock is
56
        preserved across method calls.
57
    </p>
58
    <p>
59
        The design / structure of the API is intentionally almost the same as with the obsoleted api located in
60
        <code>org.netbeans.modules.xml.text.syntax.dom</code> package to make the existing code migration easier.
61
    </p>
54
</body>
62
</body>
55
</html>
63
</html>
(-)a/xml.text/src/org/netbeans/modules/xml/text/breadcrumbs/BreadcrumbProvider.java (-21 / +21 lines)
Lines 62-68 Link Here
62
import org.netbeans.modules.editor.structure.api.DocumentElementListener;
62
import org.netbeans.modules.editor.structure.api.DocumentElementListener;
63
import org.netbeans.modules.editor.structure.api.DocumentModel;
63
import org.netbeans.modules.editor.structure.api.DocumentModel;
64
import org.netbeans.modules.editor.structure.api.DocumentModelException;
64
import org.netbeans.modules.editor.structure.api.DocumentModelException;
65
import org.netbeans.modules.xml.text.structure.XMLDocumentModelProvider;
65
import static org.netbeans.modules.xml.text.structure.XMLConstants.*;
66
import org.openide.cookies.OpenCookie;
66
import org.openide.cookies.OpenCookie;
67
import org.openide.loaders.DataObject;
67
import org.openide.loaders.DataObject;
68
import org.openide.util.Exceptions;
68
import org.openide.util.Exceptions;
Lines 151-161 Link Here
151
        DocumentElement el = mdl.getLeafElementForOffset(pos);
151
        DocumentElement el = mdl.getLeafElementForOffset(pos);
152
        OUT: while (el != null) {
152
        OUT: while (el != null) {
153
            switch (el.getType()) {
153
            switch (el.getType()) {
154
                case XMLDocumentModelProvider.XML_TAG:
154
                case XML_TAG:
155
                case XMLDocumentModelProvider.XML_EMPTY_TAG:
155
                case XML_EMPTY_TAG:
156
                case XMLDocumentModelProvider.XML_PI:
156
                case XML_PI:
157
                case XMLDocumentModelProvider.XML_CDATA:
157
                case XML_CDATA:
158
                case XMLDocumentModelProvider.XML_DOCTYPE:
158
                case XML_DOCTYPE:
159
                    break OUT;
159
                    break OUT;
160
                default:
160
                default:
161
                    el = el.getParentElement();
161
                    el = el.getParentElement();
Lines 220-233 Link Here
220
        @Override
220
        @Override
221
        public String getHtmlDisplayName() {
221
        public String getHtmlDisplayName() {
222
            switch (docEl.getType()) {
222
            switch (docEl.getType()) {
223
                case XMLDocumentModelProvider.XML_TAG:
223
                case XML_TAG:
224
                case XMLDocumentModelProvider.XML_EMPTY_TAG:
224
                case XML_EMPTY_TAG:
225
                    return docEl.getName();
225
                    return docEl.getName();
226
                case XMLDocumentModelProvider.XML_PI:
226
                case XML_PI:
227
                    return docEl.getName();
227
                    return docEl.getName();
228
                case XMLDocumentModelProvider.XML_CDATA:
228
                case XML_CDATA:
229
                    return Bundle.LABEL_CDATA();
229
                    return Bundle.LABEL_CDATA();
230
                case XMLDocumentModelProvider.XML_DOCTYPE:
230
                case XML_DOCTYPE:
231
                    return Bundle.LABEL_DOCTYPE();
231
                    return Bundle.LABEL_DOCTYPE();
232
                default:
232
                default:
233
                    // unsupported nodes
233
                    // unsupported nodes
Lines 243-259 Link Here
243
            String resource;
243
            String resource;
244
            
244
            
245
            switch (docEl.getType()) {
245
            switch (docEl.getType()) {
246
                case XMLDocumentModelProvider.XML_TAG:
246
                case XML_TAG:
247
                case XMLDocumentModelProvider.XML_EMPTY_TAG:
247
                case XML_EMPTY_TAG:
248
                    resource = TAG_16; 
248
                    resource = TAG_16; 
249
                    break;
249
                    break;
250
                case XMLDocumentModelProvider.XML_PI:
250
                case XML_PI:
251
                    resource = PI_16;
251
                    resource = PI_16;
252
                    break;
252
                    break;
253
                case XMLDocumentModelProvider.XML_CDATA:
253
                case XML_CDATA:
254
                    resource = CDATA_16;
254
                    resource = CDATA_16;
255
                    break;
255
                    break;
256
                case XMLDocumentModelProvider.XML_DOCTYPE:
256
                case XML_DOCTYPE:
257
                    resource = DOCTYPE_16;
257
                    resource = DOCTYPE_16;
258
                    break;
258
                    break;
259
                default:
259
                default:
Lines 293-303 Link Here
293
            List<BreadcrumbsElement> children = new ArrayList<>();
293
            List<BreadcrumbsElement> children = new ArrayList<>();
294
            for (DocumentElement ch : docEl.getChildren()) {
294
            for (DocumentElement ch : docEl.getChildren()) {
295
                switch (ch.getType()) {
295
                switch (ch.getType()) {
296
                    case XMLDocumentModelProvider.XML_TAG:
296
                    case XML_TAG:
297
                    case XMLDocumentModelProvider.XML_EMPTY_TAG:
297
                    case XML_EMPTY_TAG:
298
                    case XMLDocumentModelProvider.XML_PI:
298
                    case XML_PI:
299
                    case XMLDocumentModelProvider.XML_CDATA:
299
                    case XML_CDATA:
300
                    case XMLDocumentModelProvider.XML_DOCTYPE:
300
                    case XML_DOCTYPE:
301
                        children.add(createElement(ch, this));
301
                        children.add(createElement(ch, this));
302
                        break;
302
                        break;
303
                    default:
303
                    default:
(-)a/xml.text/src/org/netbeans/modules/xml/text/completion/GrammarManager.java (-8 / +7 lines)
Lines 62-70 Link Here
62
import org.netbeans.modules.xml.api.model.GrammarEnvironment;
62
import org.netbeans.modules.xml.api.model.GrammarEnvironment;
63
import org.netbeans.modules.xml.api.model.GrammarQuery;
63
import org.netbeans.modules.xml.api.model.GrammarQuery;
64
import org.netbeans.modules.xml.api.model.GrammarQueryManager;
64
import org.netbeans.modules.xml.api.model.GrammarQueryManager;
65
import org.netbeans.modules.xml.text.syntax.SyntaxElement;
65
import org.netbeans.modules.xml.text.api.dom.SyntaxElement;
66
import org.netbeans.modules.xml.text.syntax.XMLSyntaxSupport;
66
import org.netbeans.modules.xml.text.api.dom.XMLSyntaxSupport;
67
import org.netbeans.modules.xml.text.syntax.dom.SyntaxNode;
68
import org.openide.filesystems.FileChangeAdapter;
67
import org.openide.filesystems.FileChangeAdapter;
69
import org.openide.filesystems.FileChangeListener;
68
import org.openide.filesystems.FileChangeListener;
70
import org.openide.filesystems.FileEvent;
69
import org.openide.filesystems.FileEvent;
Lines 293-300 Link Here
293
                
292
                
294
                while (en.hasMoreElements()) {
293
                while (en.hasMoreElements()) {
295
                    Node next = (Node) en.nextElement();
294
                    Node next = (Node) en.nextElement();
296
                    if (next instanceof SyntaxNode) {
295
                    if (next instanceof SyntaxElement) {
297
                        SyntaxNode node = (SyntaxNode) next;
296
                        SyntaxElement node = (SyntaxElement) next;
298
                        int start = node.getElementOffset();
297
                        int start = node.getElementOffset();
299
                        int end = start + node.getElementLength();
298
                        int end = start + node.getElementLength();
300
                        if (end > max) max = end;
299
                        if (end > max) max = end;
Lines 359-368 Link Here
359
        SyntaxElement first = syntax.getElementChain(1);
358
        SyntaxElement first = syntax.getElementChain(1);
360
        while (true) {
359
        while (true) {
361
            if (first == null) break;
360
            if (first == null) break;
362
            if (first instanceof SyntaxNode) {
361
            Node node = first.getNode();
363
                SyntaxNode node = (SyntaxNode) first;
362
            if (node != null) {
364
                ctx.add(node);
363
                ctx.add(node);
365
                if (node.ELEMENT_NODE == node.getNodeType()) {
364
                if (Node.ELEMENT_NODE == node.getNodeType()) {
366
                    break;
365
                    break;
367
                }
366
                }
368
            }
367
            }
(-)a/xml.text/src/org/netbeans/modules/xml/text/completion/NodeSelector.java (-2 / +2 lines)
Lines 56-63 Link Here
56
import org.netbeans.editor.BaseDocument;
56
import org.netbeans.editor.BaseDocument;
57
import org.netbeans.modules.xml.api.model.GrammarQuery;
57
import org.netbeans.modules.xml.api.model.GrammarQuery;
58
import org.netbeans.modules.xml.api.model.HintContext;
58
import org.netbeans.modules.xml.api.model.HintContext;
59
import org.netbeans.modules.xml.text.api.dom.XMLSyntaxSupport;
59
import org.netbeans.modules.xml.text.completion.XMLCompletionQuery;
60
import org.netbeans.modules.xml.text.completion.XMLCompletionQuery;
60
import org.netbeans.modules.xml.text.syntax.XMLSyntaxSupport;
61
import org.openide.nodes.FilterNode;
61
import org.openide.nodes.FilterNode;
62
import org.openide.nodes.Node;
62
import org.openide.nodes.Node;
63
import org.openide.nodes.Sheet;
63
import org.openide.nodes.Sheet;
Lines 139-145 Link Here
139
        if (syntaxSupport == null) {
139
        if (syntaxSupport == null) {
140
            Document doc = pane.getDocument();
140
            Document doc = pane.getDocument();
141
            if (doc instanceof BaseDocument) {
141
            if (doc instanceof BaseDocument) {
142
                syntaxSupport = (XMLSyntaxSupport) ((BaseDocument)doc).getSyntaxSupport();
142
                syntaxSupport = XMLSyntaxSupport.getSyntaxSupport((BaseDocument)doc);
143
            }
143
            }
144
            if (syntaxSupport == null) {
144
            if (syntaxSupport == null) {
145
                return;
145
                return;
(-)a/xml.text/src/org/netbeans/modules/xml/text/completion/SyntaxQueryHelper.java (-73 / +95 lines)
Lines 45-56 Link Here
45
package org.netbeans.modules.xml.text.completion;
45
package org.netbeans.modules.xml.text.completion;
46
46
47
import javax.swing.text.BadLocationException;
47
import javax.swing.text.BadLocationException;
48
import org.netbeans.api.lexer.Token;
49
import org.netbeans.api.lexer.TokenSequence;
50
import org.netbeans.api.xml.lexer.XMLTokenId;
48
51
49
import org.netbeans.editor.*;
50
import org.netbeans.modules.xml.api.model.HintContext;
52
import org.netbeans.modules.xml.api.model.HintContext;
51
import org.netbeans.modules.xml.text.syntax.*;
53
import org.netbeans.modules.xml.text.api.dom.XMLSyntaxSupport;
52
import org.netbeans.modules.xml.text.syntax.dom.*;
54
import org.netbeans.modules.xml.text.api.dom.SyntaxElement;
53
import org.netbeans.modules.xml.text.api.XMLDefaultTokenContext;
55
import org.w3c.dom.Attr;
54
import org.w3c.dom.Element;
56
import org.w3c.dom.Element;
55
import org.w3c.dom.NamedNodeMap;
57
import org.w3c.dom.NamedNodeMap;
56
import org.w3c.dom.Node;
58
import org.w3c.dom.Node;
Lines 71-79 Link Here
71
    public final static int COMPLETION_TYPE_ENTITY = 4;
73
    public final static int COMPLETION_TYPE_ENTITY = 4;
72
    public final static int COMPLETION_TYPE_NOTATION = 5;
74
    public final static int COMPLETION_TYPE_NOTATION = 5;
73
    public final static int COMPLETION_TYPE_DTD = 6;
75
    public final static int COMPLETION_TYPE_DTD = 6;
76
    
77
    private XMLSyntaxSupport support;
74
78
75
    /** Currect oken or previous one if at token boundary */
79
    /** Currect oken or previous one if at token boundary */
76
    private TokenItem token = null;
80
    private Token<XMLTokenId> token = null;
81
    
82
    private int tokenOffset;
77
    
83
    
78
    private String preText = "";
84
    private String preText = "";
79
    
85
    
Lines 91-100 Link Here
91
97
92
    /** Creates a new instance of SyntaxQueryHelper */
98
    /** Creates a new instance of SyntaxQueryHelper */
93
    public SyntaxQueryHelper(XMLSyntaxSupport sup, int offset) throws BadLocationException, IllegalStateException {
99
    public SyntaxQueryHelper(XMLSyntaxSupport sup, int offset) throws BadLocationException, IllegalStateException {
100
        this.support = sup;
94
        tunedOffset = offset;
101
        tunedOffset = offset;
95
        token = sup.getPreviousToken( tunedOffset);
102
        sup.runWithSequence(tunedOffset, (TokenSequence seq) -> {
103
            token = sup.getPreviousToken(tunedOffset);
104
            tokenOffset = seq.offset();
105
            return null;
106
        });
107
        
96
        if( token != null ) { // inside document
108
        if( token != null ) { // inside document
97
            tokenBoundary = token.getOffset() + token.getImage().length() == tunedOffset;
109
            tokenBoundary = tokenOffset + token.length() == tunedOffset;
98
        } else {
110
        } else {
99
            //??? start of document no choice now, but should be prolog if not followed by it
111
            //??? start of document no choice now, but should be prolog if not followed by it
100
            throw new BadLocationException("No token found at current position", offset); // NOI18N
112
            throw new BadLocationException("No token found at current position", offset); // NOI18N
Lines 102-118 Link Here
102
114
103
        // find out last typed chars that can hint
115
        // find out last typed chars that can hint
104
116
105
        int itemOffset = token.getOffset();
117
        int itemOffset = tokenOffset;
106
        preText = "";
118
        preText = "";
107
        erase = 0;
119
        erase = 0;
108
        int eraseRight = 0;
120
        int eraseRight = 0;
109
        int id = token.getTokenID().getNumericID();
121
        XMLTokenId id = token.id();
110
122
111
        // determine last typed text, prefix text
123
        // determine last typed text, prefix text
112
124
113
        if ( tokenBoundary == false ) {
125
        if ( tokenBoundary == false ) {
114
126
115
            preText = token.getImage().substring( 0, tunedOffset - token.getOffset() );
127
            preText = token.text().toString().substring( 0, tunedOffset - tokenOffset);
116
            if ("".equals(preText)) throw new IllegalStateException("Cannot get token prefix at " + tunedOffset);
128
            if ("".equals(preText)) throw new IllegalStateException("Cannot get token prefix at " + tunedOffset);
117
129
118
            // manipulate tunedOffset to delete rest of an old name
130
            // manipulate tunedOffset to delete rest of an old name
Lines 121-131 Link Here
121
            if (sup.lastTypedChar() != '<' && sup.lastTypedChar() != '&') {
133
            if (sup.lastTypedChar() != '<' && sup.lastTypedChar() != '&') {
122
                switch (id) {
134
                switch (id) {
123
135
124
                    case XMLDefaultTokenContext.TAG_ID:
136
                    case TAG:
125
                    case XMLDefaultTokenContext.CHARACTER_ID:
137
                    case CHARACTER:
126
                    case XMLDefaultTokenContext.ARGUMENT_ID:
138
                    case ARGUMENT:
127
139
128
                        int i = token.getImage().length();
140
                        int i = token.length();
129
                        int tail = i - (tunedOffset - itemOffset);
141
                        int tail = i - (tunedOffset - itemOffset);
130
                        tunedOffset += tail;
142
                        tunedOffset += tail;
131
                        eraseRight = tail;
143
                        eraseRight = tail;
Lines 134-145 Link Here
134
            }
146
            }
135
         } else {
147
         } else {
136
           switch (id) {
148
           switch (id) {
137
                case XMLDefaultTokenContext.TEXT_ID:
149
                case TEXT:
138
                case XMLDefaultTokenContext.TAG_ID:
150
                case TAG:
139
                case XMLDefaultTokenContext.ARGUMENT_ID:
151
                case ARGUMENT:
140
                case XMLDefaultTokenContext.CHARACTER_ID:
152
                case CHARACTER:
141
                case XMLCompletionQuery.PI_CONTENT_ID:
153
                case PI_CONTENT:
142
                    preText = token.getImage();
154
                    preText = token.text().toString();
143
                    break;                        
155
                    break;                        
144
            }
156
            }
145
         }
157
         }
Lines 147-164 Link Here
147
        // adjust how much do you want to erase from the preText
159
        // adjust how much do you want to erase from the preText
148
160
149
        switch (id) {
161
        switch (id) {
150
            case XMLDefaultTokenContext.TAG_ID:
162
            case TAG:
151
                // do not erase start delimiters
163
                // do not erase start delimiters
152
                erase = preText.length() - 1 + eraseRight;
164
                erase = preText.length() - 1 + eraseRight;
153
                break;
165
                break;
154
            case XMLDefaultTokenContext.CHARACTER_ID:
166
            case CHARACTER:
155
                //entity references
167
                //entity references
156
                erase = preText.length() + -1 + eraseRight;
168
                erase = preText.length() + -1 + eraseRight;
157
                break;
169
                break;
158
            case XMLDefaultTokenContext.ARGUMENT_ID:
170
            case ARGUMENT:
159
                erase = preText.length() + eraseRight;
171
                erase = preText.length() + eraseRight;
160
                break;
172
                break;
161
            case XMLDefaultTokenContext.VALUE_ID:
173
            case VALUE:
162
                erase = preText.length();
174
                erase = preText.length();
163
                if (erase > 0 && (preText.charAt(0) == '\'' || preText.charAt(0) == '"')) {
175
                if (erase > 0 && (preText.charAt(0) == '\'' || preText.charAt(0) == '"')) {
164
                    // Because of attribute values, preText is adjusted in initContext
176
                    // Because of attribute values, preText is adjusted in initContext
Lines 172-185 Link Here
172
        if (element == null) throw new IllegalStateException("There exists a token therefore a syntax element must exist at " + offset + ", too.");
184
        if (element == null) throw new IllegalStateException("There exists a token therefore a syntax element must exist at " + offset + ", too.");
173
185
174
        // completion request originates from area covered by DOM, 
186
        // completion request originates from area covered by DOM, 
175
        if (element instanceof SyntaxNode && ((SyntaxNode)element).getNodeType() != Node.DOCUMENT_TYPE_NODE) {
187
        if (element.getType() != SyntaxElement.NODE_ERROR && element.getType() != Node.DOCUMENT_TYPE_NODE) {
176
            completionType = initContext();
188
            completionType = support.runLocked(this::initContext);
177
        } else {
189
        } else {
178
            // prolog, internal DTD no completition yet
190
            // prolog, internal DTD no completition yet
179
            completionType = COMPLETION_TYPE_DTD;
191
            completionType = COMPLETION_TYPE_DTD;
180
        }
192
        }
181
    }
193
    }
182
    
194
    
195
    public int getTokenOffset() {
196
        return tokenOffset;
197
    }
198
    
183
    /**
199
    /**
184
     * Find out what to complete: attribute, value, element, entity or notation?
200
     * Find out what to complete: attribute, value, element, entity or notation?
185
     * <p>
201
     * <p>
Lines 207-218 Link Here
207
     *          COMPLETION_TYPE_ENTITY = 4,
223
     *          COMPLETION_TYPE_ENTITY = 4,
208
     *          COMPLETION_TYPE_NOTATION = 5.
224
     *          COMPLETION_TYPE_NOTATION = 5.
209
     */
225
     */
210
    private int initContext() {
226
    private int initContext() throws BadLocationException {
211
        int id = token.getTokenID().getNumericID();
227
        XMLTokenId id = token.id();
212
        SyntaxNode syntaxNode = (SyntaxNode)element;
228
        final Node syntaxNode = element.getNode();
213
214
        switch ( id) {
229
        switch ( id) {
215
            case XMLDefaultTokenContext.TEXT_ID:
230
            case TEXT:
216
                if ( preText.endsWith("<" ) || preText.endsWith("</")) {
231
                if ( preText.endsWith("<" ) || preText.endsWith("</")) {
217
                    ctx.init(syntaxNode, "");
232
                    ctx.init(syntaxNode, "");
218
                    return COMPLETION_TYPE_ELEMENT;
233
                    return COMPLETION_TYPE_ELEMENT;
Lines 227-238 Link Here
227
                }
242
                }
228
//                break;
243
//                break;
229
                
244
                
230
            case XMLDefaultTokenContext.TAG_ID:
245
            case TAG:
231
                if ( StartTag.class.equals(syntaxNode.getClass()) 
246
                if (support.isNormalTag(element)) {
232
                || EmptyTag.class.equals(syntaxNode.getClass())) {
233
                    if (preText.equals("")) {  
247
                    if (preText.equals("")) {  
234
                        //??? should not occure
248
                        //??? should not occure
235
                        if (token.getImage().endsWith(">")) {
249
                        if (token.text().toString().endsWith(">")) {
236
                            ctx.init(syntaxNode, preText);
250
                            ctx.init(syntaxNode, preText);
237
                            return COMPLETION_TYPE_VALUE;
251
                            return COMPLETION_TYPE_VALUE;
238
                        } else {
252
                        } else {
Lines 253-277 Link Here
253
                        ctx.init(syntaxNode, preText.substring(1));
267
                        ctx.init(syntaxNode, preText.substring(1));
254
                        return COMPLETION_TYPE_ELEMENT;
268
                        return COMPLETION_TYPE_ELEMENT;
255
                    }
269
                    }
256
                } else if(EndTag.class.equals(syntaxNode.getClass()) && preText.startsWith("</")){
270
                } else if(support.isEndTag(element) && preText.startsWith("</")){
257
                    //endtag
271
                    //endtag
258
                    ctx.init(syntaxNode, preText.substring(2));
272
                    ctx.init(syntaxNode, preText.substring(2));
259
                    return COMPLETION_TYPE_ELEMENT;
273
                    return COMPLETION_TYPE_ELEMENT;
260
                } else {
274
                } else {
261
                    // pairing tag completion if not at boundary
275
                    // pairing tag completion if not at boundary
262
                    if ("".equals(preText) && token.getImage().endsWith(">")) {
276
                    if ("".equals(preText) && token.text().toString().endsWith(">")) {
263
                        ctx.init(syntaxNode, preText);
277
                        ctx.init(syntaxNode, preText);
264
                        return COMPLETION_TYPE_VALUE;
278
                        return COMPLETION_TYPE_VALUE;
265
                    }
279
                    }
266
                }
280
                }
267
                break;
281
                break;
268
                
282
                
269
            case XMLDefaultTokenContext.VALUE_ID:
283
            case VALUE:
270
                if (preText.endsWith("&")) {
284
                if (preText.endsWith("&")) {
271
                    ctx.init(syntaxNode, "");
285
                    ctx.init(syntaxNode, "");
272
                    return COMPLETION_TYPE_ENTITY;
286
                    return COMPLETION_TYPE_ENTITY;
273
                } else if ("".equals(preText)) {   //??? improve check to addres inner '"'
287
                } else if ("".equals(preText)) {   //??? improve check to addres inner '"'
274
                    String image = token.getImage();
288
                    String image = token.text().toString();
275
                    char ch = image.charAt(image.length()-1);
289
                    char ch = image.charAt(image.length()-1);
276
                    
290
                    
277
                    // findout if it is closing '
291
                    // findout if it is closing '
Lines 283-305 Link Here
283
                            return COMPLETION_TYPE_UNKNOWN;                            
297
                            return COMPLETION_TYPE_UNKNOWN;                            
284
                        }
298
                        }
285
299
286
                        boolean closing = false;
300
                        int res = support.<Integer>runWithSequence(tokenOffset, (TokenSequence seq) -> {
287
                        TokenItem prev = token.getPrevious();
301
                            Token<XMLTokenId> prev = support.getPreviousToken(tokenOffset);
302
                            boolean closing = false;
288
303
289
                        while (prev != null) {
304
                            while (prev != null) {
290
                            int tid = prev.getTokenID().getNumericID();
305
                                XMLTokenId tid = prev.id();
291
                            if (tid == XMLDefaultTokenContext.VALUE_ID) {
306
                                if (tid == XMLTokenId.VALUE) {
292
                                closing = true;
307
                                    closing = true;
293
                                break;
308
                                    break;
294
                            } else if (tid == XMLDefaultTokenContext.CHARACTER_ID) {
309
                                } else if (tid == XMLTokenId.CHARACTER) {
295
                                prev = prev.getPrevious();
310
                                    if (!seq.movePrevious()) {
311
                                        return COMPLETION_TYPE_UNKNOWN;
312
                                    }
313
                                    prev = seq.token();
314
                                } else {
315
                                    break;
316
                                }
317
                            }
318
                            if (closing == false) {
319
                                ctx.init(syntaxNode, preText);
320
                                return COMPLETION_TYPE_VALUE;
296
                            } else {
321
                            } else {
297
                                break;
322
                                return COMPLETION_TYPE_UNKNOWN;
298
                            }
323
                            }
299
                        }
324
                        });
300
                        if (closing == false) {
325
                        if (res != COMPLETION_TYPE_UNKNOWN) {
301
                            ctx.init(syntaxNode, preText);
326
                            return res;
302
                            return COMPLETION_TYPE_VALUE;
303
                        }
327
                        }
304
                    } else {
328
                    } else {
305
                        ctx.init(syntaxNode, preText);
329
                        ctx.init(syntaxNode, preText);
Lines 312-322 Link Here
312
                    int maxOffsetLessThanCurrent = -1;
336
                    int maxOffsetLessThanCurrent = -1;
313
                    Node curAttrNode = null;
337
                    Node curAttrNode = null;
314
                    for (int ind = 0; ind < attrs.getLength(); ind++) {
338
                    for (int ind = 0; ind < attrs.getLength(); ind++) {
315
                        AttrImpl attr = (AttrImpl)attrs.item(ind);
339
                        SyntaxElement attr = (SyntaxElement)attrs.item(ind);
316
                        int attrTokOffset = attr.getFirstToken().getOffset();
340
                        int attrTokOffset = attr.getElementOffset();
317
                        if (attrTokOffset > maxOffsetLessThanCurrent && attrTokOffset < token.getOffset()) {
341
                        if (attrTokOffset > maxOffsetLessThanCurrent && attrTokOffset < tokenOffset) {
318
                            maxOffsetLessThanCurrent = attrTokOffset;
342
                            maxOffsetLessThanCurrent = attrTokOffset;
319
                            curAttrNode = attr;
343
                            curAttrNode = (Node)attr;
320
                        }
344
                        }
321
                    }
345
                    }
322
346
Lines 333-351 Link Here
333
                }
357
                }
334
                break;
358
                break;
335
                
359
                
336
            case XMLDefaultTokenContext.OPERATOR_ID:
360
            case OPERATOR:
337
                if ("".equals(preText)) {
361
                if ("".equals(preText)) {
338
                    if ("=".equals(token.getImage())) {
362
                    if ("=".equals(token.text())) {
339
                        ctx.init(syntaxNode, "");
363
                        ctx.init(syntaxNode, "");
340
                        return COMPLETION_TYPE_VALUE;
364
                        return COMPLETION_TYPE_VALUE;
341
                    }
365
                    }
342
                }
366
                }
343
                break;
367
                break;
344
368
345
            case XMLDefaultTokenContext.WS_ID:
369
            case WS:
346
                if ((StartTag.class.equals(syntaxNode.getClass()) 
370
                if (support.isNormalTag(element)
347
                 || EmptyTag.class.equals(syntaxNode.getClass())) 
371
                 && !token.text().toString().startsWith("/")) {
348
                 && !token.getImage().startsWith("/")) {
349
                    ctx.init((Element)syntaxNode, ""); // GrammarQuery.v2 takes Element ctx 
372
                    ctx.init((Element)syntaxNode, ""); // GrammarQuery.v2 takes Element ctx 
350
                    return COMPLETION_TYPE_ATTRIBUTE;
373
                    return COMPLETION_TYPE_ATTRIBUTE;
351
                } else {
374
                } else {
Lines 354-368 Link Here
354
                }
377
                }
355
//                break;
378
//                break;
356
                
379
                
357
            case XMLDefaultTokenContext.ARGUMENT_ID:
380
            case ARGUMENT:
358
                if (StartTag.class.equals(syntaxNode.getClass()) 
381
                if (support.isStartTag(element)
359
                || EmptyTag.class.equals(syntaxNode.getClass())) {
382
                || support.isEmptyTag(element)) {
360
                    //try to find the current attribute 
383
                    //try to find the current attribute 
361
                    Tag tag = (Tag)syntaxNode;
384
                    NamedNodeMap nnm = syntaxNode.getAttributes();
362
                    NamedNodeMap nnm = tag.getAttributes();
363
                    for(int i = 0; i < nnm.getLength(); i++) {
385
                    for(int i = 0; i < nnm.getLength(); i++) {
364
                        AttrImpl attrNode = (AttrImpl)nnm.item(i);
386
                        Attr attrNode = (Attr)nnm.item(i);
365
                        if(attrNode.getFirstToken().getOffset() == token.getOffset()) {
387
                        if(support.getNodeOffset(attrNode) == tokenOffset) {
366
                            ctx.init(attrNode, preText);
388
                            ctx.init(attrNode, preText);
367
                        }
389
                        }
368
                    }
390
                    }
Lines 373-379 Link Here
373
                }
395
                }
374
                break;
396
                break;
375
                
397
                
376
            case XMLDefaultTokenContext.CHARACTER_ID:  // entity reference
398
            case CHARACTER:  // entity reference
377
                if (preText.startsWith("&#")) {
399
                if (preText.startsWith("&#")) {
378
                    // character ref, ignore
400
                    // character ref, ignore
379
                    return COMPLETION_TYPE_UNKNOWN;
401
                    return COMPLETION_TYPE_UNKNOWN;
Lines 384-390 Link Here
384
                    ctx.init(syntaxNode, preText.substring(1));
406
                    ctx.init(syntaxNode, preText.substring(1));
385
                    return COMPLETION_TYPE_ENTITY;
407
                    return COMPLETION_TYPE_ENTITY;
386
                } else if ("".equals(preText)) {
408
                } else if ("".equals(preText)) {
387
                    if (token.getImage().endsWith(";")) {
409
                    if (token.text().toString().endsWith(";")) {
388
                        ctx.init(syntaxNode, preText);
410
                        ctx.init(syntaxNode, preText);
389
                        return COMPLETION_TYPE_VALUE;
411
                        return COMPLETION_TYPE_VALUE;
390
                    }
412
                    }
Lines 408-414 Link Here
408
    }
430
    }
409
431
410
    /** Current token or previous one if at token boundary. */
432
    /** Current token or previous one if at token boundary. */
411
    public TokenItem getToken() {
433
    public Token<XMLTokenId> getToken() {
412
        return token;
434
        return token;
413
    }
435
    }
414
    
436
    
(-)a/xml.text/src/org/netbeans/modules/xml/text/completion/XMLCompletionProvider.java (-14 / +113 lines)
Lines 49-67 Link Here
49
import javax.swing.text.Document;
49
import javax.swing.text.Document;
50
import javax.swing.text.JTextComponent;
50
import javax.swing.text.JTextComponent;
51
import org.netbeans.api.editor.completion.Completion;
51
import org.netbeans.api.editor.completion.Completion;
52
import org.netbeans.api.lexer.Token;
53
import org.netbeans.api.lexer.TokenSequence;
54
import org.netbeans.api.xml.lexer.XMLTokenId;
52
import org.netbeans.editor.BaseDocument;
55
import org.netbeans.editor.BaseDocument;
53
import org.netbeans.editor.SyntaxSupport;
56
import org.netbeans.modules.xml.text.api.dom.XMLSyntaxSupport;
54
import org.netbeans.editor.TokenItem;
55
import org.netbeans.modules.xml.text.api.XMLDefaultTokenContext;
56
import org.netbeans.modules.xml.text.syntax.XMLSyntaxSupport;
57
import org.netbeans.editor.Utilities;
58
import org.netbeans.editor.ext.ExtSyntaxSupport;
57
import org.netbeans.editor.ext.ExtSyntaxSupport;
58
import org.netbeans.modules.xml.text.api.dom.SyntaxElement;
59
import org.netbeans.spi.editor.completion.CompletionItem;
59
import org.netbeans.spi.editor.completion.CompletionItem;
60
import org.netbeans.spi.editor.completion.CompletionResultSet;
60
import org.netbeans.spi.editor.completion.CompletionResultSet;
61
import org.netbeans.spi.editor.completion.support.AsyncCompletionQuery;
61
import org.netbeans.spi.editor.completion.support.AsyncCompletionQuery;
62
import org.netbeans.spi.editor.completion.support.AsyncCompletionTask;
62
import org.netbeans.spi.editor.completion.support.AsyncCompletionTask;
63
import org.netbeans.spi.editor.completion.CompletionProvider;
63
import org.netbeans.spi.editor.completion.CompletionProvider;
64
import org.netbeans.spi.editor.completion.CompletionTask;
64
import org.netbeans.spi.editor.completion.CompletionTask;
65
import org.openide.util.Exceptions;
65
import org.openide.util.NbBundle;
66
import org.openide.util.NbBundle;
66
67
67
/**
68
/**
Lines 80-95 Link Here
80
    
81
    
81
    @Override
82
    @Override
82
    public int getAutoQueryTypes(JTextComponent component, String typedText) {
83
    public int getAutoQueryTypes(JTextComponent component, String typedText) {
83
        SyntaxSupport support = Utilities.getDocument(component).getSyntaxSupport();
84
        XMLSyntaxSupport support = XMLSyntaxSupport.getSyntaxSupport(component.getDocument());
84
        if( (support == null) || !(support instanceof XMLSyntaxSupport))
85
        if( (support == null) || !(support instanceof XMLSyntaxSupport))
85
            return 0;
86
            return 0;
86
        
87
        
87
        int type = ((XMLSyntaxSupport)support).checkCompletion(component, typedText, false);
88
        int type = checkCompletion(support, component, typedText, false);
88
        if(type == ExtSyntaxSupport.COMPLETION_POPUP)
89
        if(type == ExtSyntaxSupport.COMPLETION_POPUP)
89
            return COMPLETION_QUERY_TYPE;
90
            return COMPLETION_QUERY_TYPE;
90
        
91
        
91
        return 0;
92
        return 0;
92
    }
93
    }
94
95
    /** Schedule content update making completion visible. */
96
    public static final int COMPLETION_POPUP = 0;
97
    /** Cancel request without changing completion visibility. */
98
    public static final int COMPLETION_CANCEL = 1;
99
    /** Update content immediatelly if it's currently visible. */
100
    public static final int COMPLETION_REFRESH = 2;
101
    /** Schedule content update if it's currently visible. */
102
    public static final int COMPLETION_POST_REFRESH = 3;
103
    /** Hide completion. */
104
    public static final int COMPLETION_HIDE = 4;
105
    
106
    private int checkCompletion(XMLSyntaxSupport support, JTextComponent target, String typedText, boolean visible ) {
107
        
108
        if( !visible ) {
109
            int retVal = COMPLETION_CANCEL;
110
            switch( typedText.charAt( typedText.length()-1 ) ) {
111
                case '/':
112
                    int dotPos = target.getCaret().getDot();
113
                    BaseDocument doc = (BaseDocument)target.getDocument();
114
                    if (dotPos >= 2) { // last char before inserted slash
115
                        try {
116
                            String txtBeforeSpace = doc.getText(dotPos-2, 2);
117
                            if( txtBeforeSpace.equals("</") )  // NOI18N
118
                                retVal = COMPLETION_POPUP;
119
                        } catch (BadLocationException e) {
120
                            Exceptions.printStackTrace(e);
121
                        }
122
                    }
123
                    break;
124
                    
125
                case '<':
126
                case '&':
127
                case '"':
128
                case '\'':
129
                    retVal = COMPLETION_POPUP;
130
                    break;
131
                case '>':
132
                    dotPos = target.getCaret().getDot();
133
                    try {
134
                        SyntaxElement sel = support.getElementChain(dotPos);
135
                        if(support.isStartTag(sel)) {
136
                            retVal = COMPLETION_POPUP;
137
                        }
138
                    } catch (BadLocationException e) {
139
                        //ignore
140
                    }
141
                    break;
142
            }
143
            if(noCompletion(support, target))
144
                return COMPLETION_HIDE;            
145
            return retVal;
146
        } else { // the pane is already visible
147
            switch (typedText.charAt(0)) {
148
                case '>':
149
                case ';':
150
                    return COMPLETION_HIDE;
151
            }
152
            //requestedAutoCompletion = true;
153
            return COMPLETION_POST_REFRESH; //requery it
154
        }
155
    }
156
    
157
    /**
158
     * No completion inside PI, CDATA, comment section.
159
     * True only inside PI or CDATA section, false otherwise.
160
     * @param target
161
     */
162
    boolean noCompletion(XMLSyntaxSupport support, JTextComponent target) {
163
        if(target == null || target.getCaret() == null)
164
            return false;
165
        int offset = target.getCaret().getDot();
166
        if(offset < 0)
167
            return false;            
168
        //no completion inside CDATA or comment section
169
        try {
170
            return support.<Boolean>runWithSequence(offset, (TokenSequence ts) -> {
171
                Token<XMLTokenId> token = ts.token();
172
                if (token == null) {
173
                    ts.moveNext();
174
                    token = ts.token();
175
                    if (token == null) {
176
                        return false;
177
                    }
178
                }
179
                if (token.id() == XMLTokenId.CDATA_SECTION
180
                        || token.id() == XMLTokenId.BLOCK_COMMENT
181
                        || token.id() == XMLTokenId.PI_START
182
                        || token.id() == XMLTokenId.PI_END
183
                        || token.id() == XMLTokenId.PI_CONTENT
184
                        || token.id() == XMLTokenId.PI_TARGET) {
185
                    return true;
186
                }
187
                return false;
188
            });
189
        } catch (BadLocationException ex) {
190
            Exceptions.printStackTrace(ex);
191
        }
192
        return false;
193
    }
93
    
194
    
94
    @Override
195
    @Override
95
    public CompletionTask createTask(int queryType, JTextComponent component) {
196
    public CompletionTask createTask(int queryType, JTextComponent component) {
Lines 112-127 Link Here
112
213
113
        @Override
214
        @Override
114
        protected void query(CompletionResultSet resultSet, Document doc, int caretOffset) {
215
        protected void query(CompletionResultSet resultSet, Document doc, int caretOffset) {
115
            SyntaxSupport syntaxSupport = Utilities.getSyntaxSupport(component); // fix for issue #185876
216
            XMLSyntaxSupport support = XMLSyntaxSupport.getSyntaxSupport(doc);
116
            XMLSyntaxSupport support = (syntaxSupport instanceof XMLSyntaxSupport ?
117
                (XMLSyntaxSupport) syntaxSupport : null);
118
            if (!ENABLED || support == null) {
217
            if (!ENABLED || support == null) {
119
                resultSet.finish();
218
                resultSet.finish();
120
                return;
219
                return;
121
            }
220
            }
122
            
221
            
123
            resultSet.setWaitText(NbBundle.getMessage(XMLCompletionProvider.class, "MSG_loading_dtd"));
222
            resultSet.setWaitText(NbBundle.getMessage(XMLCompletionProvider.class, "MSG_loading_dtd"));
124
            List<CompletionItem> items = QUERY.query(component, caretOffset, support);
223
            List<CompletionItem> items = QUERY.query(component, caretOffset, XMLSyntaxSupport.getSyntaxSupport((BaseDocument)doc));
125
            if(items != null) resultSet.addAllItems(items);
224
            if(items != null) resultSet.addAllItems(items);
126
            resultSet.finish();
225
            resultSet.finish();
127
        }
226
        }
Lines 166-175 Link Here
166
        //test whether we are just in text and eventually close the opened completion
265
        //test whether we are just in text and eventually close the opened completion
167
        //this is handy after end tag autocompletion when user doesn't complete the
266
        //this is handy after end tag autocompletion when user doesn't complete the
168
        //end tag and just types a text
267
        //end tag and just types a text
169
        XMLSyntaxSupport sup = (XMLSyntaxSupport)doc.getSyntaxSupport().get(XMLSyntaxSupport.class);
268
        XMLSyntaxSupport sup = XMLSyntaxSupport.getSyntaxSupport(doc);
170
        try {
269
        try {
171
            TokenItem ti = sup.getTokenChain(caretOffset <= 0 ? 0 : caretOffset - 1, caretOffset);
270
            Token<XMLTokenId> ti = sup.getNextToken(caretOffset <= 0 ? 1 : caretOffset - 1);
172
            if(ti != null && ti.getTokenID() == XMLDefaultTokenContext.TEXT && !ti.getImage().startsWith("<") && !ti.getImage().startsWith("&")) {
271
            if(ti != null && ti.id()== XMLTokenId.TEXT && !ti.text().toString().startsWith("<") && !ti.text().toString().startsWith("&")) {
173
                hideCompletion();
272
                hideCompletion();
174
            }
273
            }
175
        }catch(BadLocationException e) {
274
        }catch(BadLocationException e) {
(-)a/xml.text/src/org/netbeans/modules/xml/text/completion/XMLCompletionQuery.java (-30 / +46 lines)
Lines 52-58 Link Here
52
import javax.swing.text.BadLocationException;
52
import javax.swing.text.BadLocationException;
53
import javax.swing.text.Document;
53
import javax.swing.text.Document;
54
import org.netbeans.api.lexer.Token;
54
import org.netbeans.api.lexer.Token;
55
import org.netbeans.api.lexer.TokenHierarchy;
56
import org.netbeans.api.lexer.TokenId;
55
import org.netbeans.api.lexer.TokenId;
57
import org.netbeans.api.lexer.TokenSequence;
56
import org.netbeans.api.lexer.TokenSequence;
58
import org.netbeans.api.xml.lexer.XMLTokenId;
57
import org.netbeans.api.xml.lexer.XMLTokenId;
Lines 62-73 Link Here
62
import org.netbeans.editor.*;
61
import org.netbeans.editor.*;
63
import org.openide.ErrorManager;
62
import org.openide.ErrorManager;
64
63
65
import org.netbeans.modules.xml.text.syntax.*;
64
import org.netbeans.modules.xml.text.api.dom.XMLSyntaxSupport;
66
import org.netbeans.modules.xml.api.model.*;
65
import org.netbeans.modules.xml.api.model.*;
67
import org.netbeans.modules.xml.spi.dom.UOException;
66
import org.netbeans.modules.xml.spi.dom.UOException;
67
import org.netbeans.modules.xml.text.api.dom.SyntaxElement;
68
import org.netbeans.modules.xml.text.bracematch.XMLBraceMatcher;
68
import org.netbeans.modules.xml.text.bracematch.XMLBraceMatcher;
69
import org.netbeans.modules.xml.text.syntax.dom.SyntaxNode;
70
import org.netbeans.spi.editor.completion.CompletionItem;
69
import org.netbeans.spi.editor.completion.CompletionItem;
70
import org.openide.util.Exceptions;
71
import org.openide.util.NbBundle;
71
import org.openide.util.NbBundle;
72
72
73
/**
73
/**
Lines 83-89 Link Here
83
 * @version 1.01
83
 * @version 1.01
84
 */
84
 */
85
85
86
public class XMLCompletionQuery implements XMLTokenIDs {
86
public class XMLCompletionQuery {
87
    
87
    
88
    // the name of a property indentifing cached query
88
    // the name of a property indentifing cached query
89
    public static final String DOCUMENT_GRAMMAR_BINDING_PROP = "doc-bind-query";
89
    public static final String DOCUMENT_GRAMMAR_BINDING_PROP = "doc-bind-query";
Lines 103-113 Link Here
103
     * @param support syntax-support that will be used during resolving of the query.
103
     * @param support syntax-support that will be used during resolving of the query.
104
     * @return result of the query or null if there's no result.
104
     * @return result of the query or null if there's no result.
105
     */
105
     */
106
    public List<CompletionItem> query(JTextComponent component, int offset, SyntaxSupport support) {        
106
    public List<CompletionItem> query(JTextComponent component, int offset, XMLSyntaxSupport sup) {        
107
        BaseDocument doc = (BaseDocument)component.getDocument();
107
        BaseDocument doc = (BaseDocument)component.getDocument();
108
        if (doc == null) return null;
108
        if (doc == null) return null;
109
        XMLSyntaxSupport sup = (XMLSyntaxSupport)support.get(XMLSyntaxSupport.class);
110
        if( sup == null ) return null;// No SyntaxSupport for us, no hint for user        
111
        try {
109
        try {
112
            SyntaxQueryHelper helper = new SyntaxQueryHelper(sup, offset);
110
            SyntaxQueryHelper helper = new SyntaxQueryHelper(sup, offset);
113
            
111
            
Lines 165-171 Link Here
165
                ***************************************************************/
163
                ***************************************************************/
166
                
164
                
167
                if (list.isEmpty() && helper.getPreText().startsWith("</")) { // NOI18N
165
                if (list.isEmpty() && helper.getPreText().startsWith("</")) { // NOI18N
168
                    List stlist = findStartTag((SyntaxNode)helper.getSyntaxElement(), !helper.getPreText().endsWith("/") ? "/" : "");
166
                    List stlist = findStartTag(helper.getSyntaxElement(), !helper.getPreText().endsWith("/") ? "/" : "");
169
                    if (stlist != null && !stlist.isEmpty()) {
167
                    if (stlist != null && !stlist.isEmpty()) {
170
                        ElementResultItem item = (ElementResultItem)stlist.get(0); //we always get just one item
168
                        ElementResultItem item = (ElementResultItem)stlist.get(0); //we always get just one item
171
                        if(!XMLBraceMatcher.hasEndTag(doc, offset, item.getItemText()) &&
169
                        if(!XMLBraceMatcher.hasEndTag(doc, offset, item.getItemText()) &&
Lines 225-231 Link Here
225
//                            );                
223
//                            );                
226
            } else {
224
            } else {
227
                // prolog, internal DTD no completition yet
225
                // prolog, internal DTD no completition yet
228
                if (helper.getToken().getTokenID() == PI_CONTENT) {
226
                if (helper.getToken().id() == XMLTokenId.PI_CONTENT) {
229
                    if (helper.getPreText().endsWith("encoding=")) {                        // NOI18N
227
                    if (helper.getPreText().endsWith("encoding=")) {                        // NOI18N
230
//                        List encodings = new ArrayList(2);
228
//                        List encodings = new ArrayList(2);
231
//                        encodings.add(new XMLResultItem(0, "\"UTF-8\""));          // NOI18N
229
//                        encodings.add(new XMLResultItem(0, "\"UTF-8\""));          // NOI18N
Lines 337-344 Link Here
337
            int delLen = 0;
335
            int delLen = 0;
338
            String suffix = null;
336
            String suffix = null;
339
            if (helper.getToken() != null) {
337
            if (helper.getToken() != null) {
340
                if (helper.getToken().getTokenID() == XMLTokenIDs.TEXT) {
338
                if (helper.getToken().id() == XMLTokenId.TEXT) {
341
                    String c = helper.getToken().getImage();
339
                    String c = helper.getToken().text().toString();
342
                    String p = helper.getPreText();
340
                    String p = helper.getPreText();
343
                    // special case: do not remove text after newline to
341
                    // special case: do not remove text after newline to
344
                    // preserve formatting / indentation
342
                    // preserve formatting / indentation
Lines 352-359 Link Here
352
                    if (tagName != null) {
350
                    if (tagName != null) {
353
                        suffix = "</" + tagName + ">";
351
                        suffix = "</" + tagName + ">";
354
                    }
352
                    }
355
                } else if (helper.getToken().getTokenID() == XMLTokenIDs.VALUE) {
353
                } else if (helper.getToken().id() == XMLTokenId.VALUE) {
356
                    String c = helper.getToken().getImage();
354
                    String c = helper.getToken().text().toString();
357
                    delLen = c.length();
355
                    delLen = c.length();
358
                    if (c.charAt(0) == '"' ||
356
                    if (c.charAt(0) == '"' ||
359
                        c.charAt(0) == '\'') {
357
                        c.charAt(0) == '\'') {
Lines 363-369 Link Here
363
                    if (c.charAt(l) == '"' || c.charAt(l) == '\'') {
361
                    if (c.charAt(l) == '"' || c.charAt(l) == '\'') {
364
                        delLen--;
362
                        delLen--;
365
                    }
363
                    }
366
                } else if (helper.getToken().getTokenID() == XMLTokenIDs.TAG) {
364
                } else if (helper.getToken().id() == XMLTokenId.TAG) {
367
                    String tagName = shouldCloseTag(helper, doc, sup);
365
                    String tagName = shouldCloseTag(helper, doc, sup);
368
                    if (tagName != null) {
366
                    if (tagName != null) {
369
                        suffix = "</" + tagName + ">";
367
                        suffix = "</" + tagName + ">";
Lines 437-461 Link Here
437
        return result;
435
        return result;
438
    }
436
    }
439
    
437
    
440
    private String shouldCloseTag(SyntaxQueryHelper helper, Document doc, XMLSyntaxSupport sup) {
438
    private String shouldCloseTagLocked(TokenSequence ts) {
441
        TokenItem ti = helper.getToken();
439
        if (!ts.movePrevious()) {
442
        TokenItem previous = ti.getPrevious();
440
            return null;
443
        if (previous == null || previous.getTokenID() != XMLTokenIDs.TAG) {
441
        }
442
        Token<XMLTokenId> previous = ts.token();
443
        if (previous.id() != XMLTokenId.TAG) {
444
            // preceded by something else than tag name, i.e. argument, operator...
444
            // preceded by something else than tag name, i.e. argument, operator...
445
            return null;
445
            return null;
446
        }
446
        }
447
        String tagName  = previous.getImage();
447
        String tagName  = previous.text().toString();
448
        if (tagName.equals(">")) { // NOI18N
448
        if (tagName.equals(">")) { // NOI18N
449
            // closing brace of a tag, iterate towards tag's begin, skip attributes and their values.
449
            // closing brace of a tag, iterate towards tag's begin, skip attributes and their values.
450
             previous = previous.getPrevious();
450
            boolean ok;
451
            while (previous != null && previous.getTokenID() != XMLTokenIDs.TAG) {
451
            
452
                previous = previous.getPrevious();
452
            while (ok = !ts.movePrevious()) {
453
                previous = ts.token();
454
                if (previous.id() == XMLTokenId.TAG) {
455
                    break;
456
                }
453
            }
457
            }
454
            if (previous == null) {
458
            if (!ok) {
455
                return null;
459
                return null;
456
            }
460
            }
457
            // got tagname.
461
            // got tagname.
458
            tagName = previous.getImage();
462
            tagName = previous.text().toString();
459
        }
463
        }
460
        if (tagName.startsWith(END_TAG_PREFIX)) {
464
        if (tagName.startsWith(END_TAG_PREFIX)) {
461
            // traversal through preceding tags, counting end-start pairs not implemented.
465
            // traversal through preceding tags, counting end-start pairs not implemented.
Lines 465-472 Link Here
465
        } 
469
        } 
466
        // tag name does not include end sharp brace
470
        // tag name does not include end sharp brace
467
        tagName = tagName.substring(1, tagName.length()).trim();
471
        tagName = tagName.substring(1, tagName.length()).trim();
468
        TokenSequence<XMLTokenId> s = (TokenSequence<XMLTokenId>)TokenHierarchy.get(doc).tokenSequence();
472
        if (isClosingEndTagFoundAfter(ts.offset(), ts, tagName)) {
469
        if (isClosingEndTagFoundAfter(ti.getOffset(), s, tagName)) {
470
            // I know, there may be multiple levels of the same tag name, and the innermost may
473
            // I know, there may be multiple levels of the same tag name, and the innermost may
471
            // be missing...
474
            // be missing...
472
            return null;
475
            return null;
Lines 474-479 Link Here
474
        return tagName;
477
        return tagName;
475
    }
478
    }
476
    
479
    
480
    private String shouldCloseTag(SyntaxQueryHelper helper, Document doc, XMLSyntaxSupport sup) {
481
        Token<XMLTokenId> ti = helper.getToken();
482
        try {
483
            return sup.runWithSequence(helper.getTokenOffset(), this::shouldCloseTagLocked);
484
        } catch (BadLocationException ex) {
485
            Exceptions.printStackTrace(ex);
486
        }
487
        return null;
488
    }
489
    
477
    public static final String
490
    public static final String
478
        TAG_FIRST_CHAR = "<", //NOI18N
491
        TAG_FIRST_CHAR = "<", //NOI18N
479
        TAG_LAST_CHAR  = ">", //NOI18N
492
        TAG_LAST_CHAR  = ">", //NOI18N
Lines 583-596 Link Here
583
     * @param prefix that is prepended to created ElementResult e.g. '</'
596
     * @param prefix that is prepended to created ElementResult e.g. '</'
584
     * @return list with one ElementResult or empty.
597
     * @return list with one ElementResult or empty.
585
     */
598
     */
586
    private static List<CompletionItem> findStartTag(SyntaxNode text, String prefix) {
599
    private static List<CompletionItem> findStartTag(SyntaxElement text, String prefix) {
587
        //if ( Util.THIS.isLoggable() ) /* then */ Util.THIS.debug("XMLCompletionQuery.findStartTag: text=" + text);
600
        //if ( Util.THIS.isLoggable() ) /* then */ Util.THIS.debug("XMLCompletionQuery.findStartTag: text=" + text);
588
        
601
        
589
        Node parent = text.getParentNode();
602
        SyntaxElement parentEl = text.getParentElement();
603
        if (parentEl == null) {
604
            return Collections.EMPTY_LIST;
605
        }
606
        Node parent = parentEl.getNode();
590
        if (parent == null) {
607
        if (parent == null) {
591
            return Collections.EMPTY_LIST;
608
            return Collections.EMPTY_LIST;
592
        }
609
        }
593
        
594
        String name = parent.getNodeName();
610
        String name = parent.getNodeName();
595
        //if ( Util.THIS.isLoggable() ) Util.THIS.debug("    name=" + name);
611
        //if ( Util.THIS.isLoggable() ) Util.THIS.debug("    name=" + name);
596
        if ( name == null ) {
612
        if ( name == null ) {
Lines 606-612 Link Here
606
        return list;
622
        return list;
607
    }
623
    }
608
    
624
    
609
    private static List<CompletionItem> findStartTag(SyntaxNode text) {
625
    private static List<CompletionItem> findStartTag(SyntaxElement text) {
610
        return findStartTag(text, "");
626
        return findStartTag(text, "");
611
    }
627
    }
612
    
628
    
(-)a/xml.text/src/org/netbeans/modules/xml/text/completion/XMLResultItem.java (-19 / +24 lines)
Lines 62-72 Link Here
62
import javax.swing.JLabel;
62
import javax.swing.JLabel;
63
import javax.swing.UIManager;
63
import javax.swing.UIManager;
64
import org.netbeans.api.editor.completion.Completion;
64
import org.netbeans.api.editor.completion.Completion;
65
import org.netbeans.api.lexer.Token;
66
import org.netbeans.api.lexer.TokenSequence;
65
import org.netbeans.api.queries.FileEncodingQuery;
67
import org.netbeans.api.queries.FileEncodingQuery;
68
import org.netbeans.api.xml.lexer.XMLTokenId;
66
import org.netbeans.modules.xml.api.model.GrammarResult;
69
import org.netbeans.modules.xml.api.model.GrammarResult;
67
import org.netbeans.modules.xml.api.model.DescriptionSource;
70
import org.netbeans.modules.xml.api.model.DescriptionSource;
68
import org.netbeans.modules.xml.text.api.XMLDefaultTokenContext;
71
import org.netbeans.modules.xml.text.api.dom.XMLSyntaxSupport;
69
import org.netbeans.modules.xml.text.syntax.XMLSyntaxSupport;
70
import org.netbeans.spi.editor.completion.CompletionDocumentation;
72
import org.netbeans.spi.editor.completion.CompletionDocumentation;
71
import org.netbeans.spi.editor.completion.CompletionItem;
73
import org.netbeans.spi.editor.completion.CompletionItem;
72
import org.netbeans.spi.editor.completion.CompletionResultSet;
74
import org.netbeans.spi.editor.completion.CompletionResultSet;
Lines 240-262 Link Here
240
        }
242
        }
241
        return true;
243
        return true;
242
    }
244
    }
243
245
    
244
    //+++ fix for issues #166462, #173122
246
    private boolean isRemovingAvailableLocked(TokenSequence ts, Document doc, int offset, String replaceToText) {
245
    //    (http://www.netbeans.org/issues/show_bug.cgi?id=166462)
247
        ts.move(position);
246
    //    (http://www.netbeans.org/issues/show_bug.cgi?id=173122)
248
        boolean isTextRemovingAllowable = true;
247
    private boolean isTextRemovingAllowable(JTextComponent component,
249
        
248
        BaseDocument doc, String replaceToText, int offset) throws BadLocationException {
250
        while (ts.moveNext() && isTextRemovingAllowable) {
249
        XMLSyntaxSupport support = (XMLSyntaxSupport)
251
            Token<XMLTokenId> tokenItem = ts.token();
250
            org.netbeans.editor.Utilities.getSyntaxSupport(component);
252
            String tokenItemImage = tokenItem.text().toString();
251
        TokenItem tokenItem = support.getTokenChain(offset, doc.getLength());
252
        boolean isTextRemovingAllowable = (tokenItem == null);
253
        if (! isTextRemovingAllowable) {
254
            String tokenItemImage = tokenItem.getImage();
255
            if ((tokenItemImage != null) && (tokenItemImage.length() > 0)) {
253
            if ((tokenItemImage != null) && (tokenItemImage.length() > 0)) {
256
                // See also issue #228865. In this case, the token also may include a prefix
254
                // See also issue #228865. In this case, the token also may include a prefix
257
                // of the replacement value
255
                // of the replacement value
258
                String replaceInclPrefix;
256
                String replaceInclPrefix;
259
                int offs = Math.max(0, offset - tokenItem.getOffset());
257
                int offs = Math.max(0, offset - ts.offset());
260
                replaceInclPrefix = tokenItemImage.substring(0, offs) + replaceToText;
258
                replaceInclPrefix = tokenItemImage.substring(0, offs) + replaceToText;
261
                int diffPos = getFirstDiffPosition(tokenItemImage, replaceInclPrefix);
259
                int diffPos = getFirstDiffPosition(tokenItemImage, replaceInclPrefix);
262
                diffPos = diffPos == 0 ? 1 : diffPos;
260
                diffPos = diffPos == 0 ? 1 : diffPos;
Lines 268-277 Link Here
268
                        strText = replaceInclPrefix.length() >= diffPos ?
266
                        strText = replaceInclPrefix.length() >= diffPos ?
269
                            replaceInclPrefix.substring(0, diffPos) : replaceInclPrefix;
267
                            replaceInclPrefix.substring(0, diffPos) : replaceInclPrefix;
270
268
271
                    TokenID tokenID = tokenItem.getTokenID();
269
                    XMLTokenId id = tokenItem.id();
272
                    int id = (tokenID != null ? tokenID.getNumericID() : -1);
270
                    isTextRemovingAllowable = (id == XMLTokenId.TAG ?
273
274
                    isTextRemovingAllowable = (id == XMLDefaultTokenContext.TAG_ID ?
275
                        ! strImg.startsWith(strText) /* <= for tags */ :
271
                        ! strImg.startsWith(strText) /* <= for tags */ :
276
                        strImg.startsWith(strText)   /* <= for attributes */);
272
                        strImg.startsWith(strText)   /* <= for attributes */);
277
                }
273
                }
Lines 280-285 Link Here
280
        return isTextRemovingAllowable;
276
        return isTextRemovingAllowable;
281
    }
277
    }
282
278
279
    //+++ fix for issues #166462, #173122
280
    //    (http://www.netbeans.org/issues/show_bug.cgi?id=166462)
281
    //    (http://www.netbeans.org/issues/show_bug.cgi?id=173122)
282
    private boolean isTextRemovingAllowable(JTextComponent component,
283
        BaseDocument doc, String replaceToText, int offset) throws BadLocationException {
284
        XMLSyntaxSupport support = XMLSyntaxSupport.getSyntaxSupport(component.getDocument());
285
        return support.runWithSequence(offset, (TokenSequence ts) -> isRemovingAvailableLocked(ts, doc, offset, replaceToText));
286
    }
287
283
    /**
288
    /**
284
     * Calculates the index of the first difference between two strings. 
289
     * Calculates the index of the first difference between two strings. 
285
     * If they are differenent starting the first character, then 0 is returned.
290
     * If they are differenent starting the first character, then 0 is returned.
(-)a/xml.text/src/org/netbeans/modules/xml/text/dom/Attr.java (-146 / +276 lines)
Lines 44-56 Link Here
44
44
45
package org.netbeans.modules.xml.text.dom;
45
package org.netbeans.modules.xml.text.dom;
46
46
47
import org.netbeans.modules.xml.text.api.dom.XMLSyntaxSupport;
47
import java.util.*;
48
import java.util.*;
49
import javax.swing.text.BadLocationException;
50
import org.netbeans.api.editor.document.AtomicLockDocument;
51
import org.netbeans.api.editor.document.LineDocument;
52
import org.netbeans.api.editor.document.LineDocumentUtils;
48
53
49
import org.netbeans.api.lexer.Token;
54
import org.netbeans.api.lexer.Token;
55
import org.netbeans.api.lexer.TokenSequence;
50
import org.netbeans.api.xml.lexer.XMLTokenId;
56
import org.netbeans.api.xml.lexer.XMLTokenId;
51
import org.netbeans.modules.xml.spi.dom.AbstractNode;
57
import org.netbeans.modules.xml.spi.dom.AbstractNode;
52
import org.netbeans.modules.xml.spi.dom.NodeListImpl;
58
import org.netbeans.modules.xml.spi.dom.NodeListImpl;
59
import org.netbeans.modules.xml.text.api.dom.SyntaxElement;
60
import org.netbeans.modules.xml.text.api.XMLTextUtils;
61
import org.netbeans.modules.xml.text.api.dom.XMLSyntaxSupport.SequenceCallable;
62
import org.openide.util.Exceptions;
63
import org.w3c.dom.DOMException;
53
import org.w3c.dom.Element;
64
import org.w3c.dom.Element;
65
import org.w3c.dom.NamedNodeMap;
54
import org.w3c.dom.Node;
66
import org.w3c.dom.Node;
55
import org.w3c.dom.NodeList;
67
import org.w3c.dom.NodeList;
56
import org.w3c.dom.Text;
68
import org.w3c.dom.Text;
Lines 65-87 Link Here
65
 * @author Petr Kuzel
77
 * @author Petr Kuzel
66
 * @author asgeir@dimonsoftware.com
78
 * @author asgeir@dimonsoftware.com
67
 */
79
 */
68
public class Attr extends AbstractNode implements org.w3c.dom.Attr {
80
public class AttrImpl extends AbstractNode implements org.w3c.dom.Attr, SyntaxElement {
81
    private Token<XMLTokenId> first;
82
    private SyntaxElement parent;
83
    private XMLSyntaxSupport syntax;  // that produced us
84
    private int index;
69
    
85
    
70
    private Token<XMLTokenId> first;
86
    AttrImpl(XMLSyntaxSupport syntax, Token<XMLTokenId> first, SyntaxElement parent, int index) {
71
    
72
    private Element parent;
73
    
74
    private XMLSyntaxSupport syntax;  // that produced us
75
    
76
    Attr(XMLSyntaxSupport syntax, Token<XMLTokenId> first, Element parent) {
77
        this.parent = parent;
87
        this.parent = parent;
78
        this.first = first;
88
        this.first = first;
79
        this.syntax = syntax;
89
        this.syntax = syntax;
90
        this.index = index;
80
    }
91
    }
81
    
92
    
82
    public Token getFirstToken() {
93
    public Token getFirstToken() {
83
        return first;
94
        return first;
84
    }
95
    }
96
97
    @Override
98
    public SyntaxElement getParentElement() {
99
        return parent;
100
    }
85
    
101
    
86
    /**
102
    /**
87
     * @return list of child nodes (Text or EntityReference), never <code>null</code>
103
     * @return list of child nodes (Text or EntityReference), never <code>null</code>
Lines 97-102 Link Here
97
        
113
        
98
        return new NodeListImpl(list);
114
        return new NodeListImpl(list);
99
    }
115
    }
116
117
    @Override
118
    public SyntaxElement getNext() {
119
        if (parent == null) {
120
            return null;
121
        }
122
        NamedNodeMap attrs = ((Element)parent.getNode()).getAttributes();
123
        if (index < attrs.getLength() - 1) {
124
            return (SyntaxElement)attrs.item(index + 1);
125
        }  else {
126
            return parent.getNext();
127
        }
128
    }
129
130
    @Override
131
    public SyntaxElement getPrevious() {
132
        if (parent == null) {
133
            return null;
134
        }
135
        NamedNodeMap attrs = ((Element)parent.getNode()).getAttributes();
136
        if (index > 0) {
137
            return (SyntaxElement)attrs.item(index - 1);
138
        }  else {
139
            return parent.getPrevious();
140
        }
141
    }
142
143
    @Override
144
    public int getElementLength() {
145
        return getLength();
146
    }
147
148
    @Override
149
    public int getElementOffset() {
150
        return first.offset(null);
151
    }
152
153
    @Override
154
    public int getType() {
155
        return Node.ATTRIBUTE_NODE;
156
    }
157
158
    @Override
159
    public Node getNode() {
160
        return this;
161
    }
100
    
162
    
101
    /**
163
    /**
102
     * Get next sibling for non syntax element text.
164
     * Get next sibling for non syntax element text.
Lines 120-158 Link Here
120
    }
182
    }
121
    
183
    
122
    public Node getNextSibling() {
184
    public Node getNextSibling() {
123
        return null;  //according to DOM-1spec
185
        if (parent == null) {
186
            return null;
187
        }
188
        NamedNodeMap attrs = ((Element)parent.getNode()).getAttributes();
189
        if (index < attrs.getLength() - 1) {
190
            return attrs.item(index + 1);
191
        }  else {
192
            return null;
193
        }
124
    }
194
    }
125
    
195
    
126
    public Node getPreviousSibling() {
196
    public Node getPreviousSibling() {
127
        return null;  //according to DOM-1 spec
197
        if (parent == null) {
198
            return null;
199
        }
200
        NamedNodeMap attrs = ((Element)parent.getNode()).getAttributes();
201
        if (index > 0) {
202
            return attrs.item(index - 1);
203
        }  else {
204
            return null;
205
        }
206
    }
207
    
208
    private Node getFirstChildLocked(TokenSequence ts) {
209
        while (ts.moveNext()) {
210
            Token<XMLTokenId> t = ts.token();
211
            if (t.id() == XMLTokenId.VALUE) {
212
                // fuzziness to relax minor tokenization changes
213
                CharSequence image = t.text();
214
                if (image.length() == 1) {
215
                    char test = image.charAt(0);
216
                    if (test == '"' || test == '\'') {
217
                        if (ts.moveNext()) {
218
                            t = ts.token();
219
                        } else {
220
                            return null;
221
                        }
222
                    }
223
                }
224
                
225
                if (t.id() == XMLTokenId.VALUE) {
226
                    return new TextImpl(syntax, t, ts.offset(), ts.offset() + t.length(), this);
227
                } else {
228
                    return null;
229
                }
230
            }
231
        }
232
        return null;
128
    }
233
    }
129
    
234
    
130
    public Node getFirstChild() {
235
    public Node getFirstChild() {
131
//        TokenItem next = first;
236
        try {
132
//        for (; next != null; next = next.getNext()) {
237
            return syntax.runWithSequence(first, this::getFirstChildLocked);
133
//            if (next.getTokenID() == VALUE) {
238
        } catch (BadLocationException ex) {
134
//                // fuzziness to relax minor tokenization changes
239
            Exceptions.printStackTrace(ex);
135
//                String image = next.getImage();
240
            return null;
136
//                if (image.length() == 1) {
241
        }
137
//                    char test = image.charAt(0);
138
//                    if (test == '"' || test == '\'') {
139
//                        next = next.getNext();
140
//                    }
141
//                }
142
//                break;  // we are after opening "'"
143
//            }
144
//        }
145
//        if (next == null) return null;
146
//        if (next.getTokenID() == VALUE) {
147
//            return new TextImpl(syntax, next, this);  //!!! strip out ending "'", return standalone "'" token
148
//        } else {
149
//            throw new RuntimeException("Not recognized yet: " + next.getTokenID());
150
//        }
151
        return null;
152
    }
242
    }
153
    
243
    
154
    public Node getLastChild() {
244
    public Node getLastChild() {
155
        throw new RuntimeException("Not implemented yet");
245
        return getFirstChild();
156
    }
246
    }
157
    
247
    
158
    public String getNodeName() {
248
    public String getNodeName() {
Lines 160-167 Link Here
160
    }
250
    }
161
    
251
    
162
    public String getName() {
252
    public String getName() {
163
        //return first.getImage();
253
        return first.text().toString();
164
        return null;
165
    }
254
    }
166
    
255
    
167
    public boolean getSpecified() {
256
    public boolean getSpecified() {
Lines 169-250 Link Here
169
    }
258
    }
170
    
259
    
171
    public void setValue(String value) {
260
    public void setValue(String value) {
172
//        // Initialize oldValueStartPos and oldValueLength parameters
261
        class H implements SequenceCallable {
173
//        int oldValueStartPos = -1;
262
            int oldValueStartPos = -1;
174
//        int oldValueLength = 0;
263
            int oldValueLength = 0;
175
//        boolean notClosed = false;
264
            boolean notClosed = false;
176
//        char firstChar = '"';
265
            char firstChar = '"';
177
//        char lastChar = '\0';
266
            char lastChar = '\0';
178
//        TokenItem next = first;
267
            
179
//        for (; next != null; next = next.getNext()) {
268
            @Override
180
//            TokenID nextId = next.getTokenID();
269
            public Object call(TokenSequence ts) throws BadLocationException {
181
//
270
                Token<XMLTokenId> next = first;
182
//            if (oldValueStartPos != -1 && nextId != VALUE  && nextId != CHARACTER) {
271
                while (ts.moveNext()) {
183
//                break;
272
                    next = ts.token();
184
//            }
273
                    XMLTokenId nextId = next.id();
185
//
274
186
//            String nextImage = next.getImage();
275
                    if (oldValueStartPos != -1 && nextId != XMLTokenId.VALUE  && nextId != XMLTokenId.CHARACTER) {
187
//
276
                        break;
188
//            String actualImage = Util.actualAttributeValue(nextImage);
277
                    }
189
//            if (!nextImage.equals(actualImage)) {
278
190
//                notClosed = true;
279
                    String nextImage = next.text().toString();
191
//                nextImage = actualImage;
280
192
//            }
281
                    String actualImage = XMLTextUtils.actualAttributeValue(nextImage);
193
//
282
                    if (!nextImage.equals(actualImage)) {
194
//            if (nextId == VALUE && oldValueStartPos == -1 && nextImage.length() > 0) {
283
                        notClosed = true;
195
//                oldValueStartPos = next.getOffset();
284
                        nextImage = actualImage;
196
//                if (nextImage.charAt(0) == '"' || nextImage.charAt(0) == '\'') {
285
                    }
197
//                    firstChar = nextImage.charAt(0);
286
198
//                    oldValueStartPos++;
287
                    if (nextId == XMLTokenId.VALUE && oldValueStartPos == -1 && nextImage.length() > 0) {
199
//                    oldValueLength--;
288
                        oldValueStartPos = ts.offset();
200
//                }
289
                        if (nextImage.charAt(0) == '"' || nextImage.charAt(0) == '\'') {
201
//            }
290
                            firstChar = nextImage.charAt(0);
202
//
291
                            oldValueStartPos++;
203
//            if (oldValueStartPos != -1 && nextImage.length() > 0) {
292
                            oldValueLength--;
204
//                oldValueLength += nextImage.length();
293
                        }
205
//                lastChar = nextImage.charAt(nextImage.length()-1);
294
                    }
206
//            }
295
207
//
296
                    if (oldValueStartPos != -1 && nextImage.length() > 0) {
208
//            if (notClosed) {
297
                        oldValueLength += nextImage.length();
209
//                break;
298
                        lastChar = nextImage.charAt(nextImage.length()-1);
210
//            }
299
                    }
211
//        }
300
212
//
301
                    if (notClosed) {
213
//        if (lastChar == firstChar) {
302
                        break;
214
//            oldValueLength--;
303
                    }
215
//        }
304
                }
216
//
305
                if (lastChar == firstChar) {
217
//        // Replace known entities
306
                    oldValueLength--;
218
//        value = Util.replaceCharsWithEntityStrings(value);
307
                }
219
//
308
220
//        // Close the attribute if it was non-closed
309
                return null;
221
//        if (notClosed) {
310
            }
222
//            value += firstChar;
311
        }
223
//        }
312
        H h = new H();
224
//
313
        try {
225
//        // Replace the text in the document
314
            syntax.runWithSequence(first.offset(null), h);
226
//        BaseDocument doc = (BaseDocument)syntax.getDocument();
315
        } catch (BadLocationException ex) {
227
//        doc.atomicLock();
316
            throw new DOMException(DOMException.INVALID_STATE_ERR , ex.getMessage());
228
//        try {
317
        }
229
//            doc.remove(oldValueStartPos, oldValueLength);
318
230
//            doc.insertString(oldValueStartPos, value, null);
319
        // Replace known entities
231
//            doc.invalidateSyntaxMarks();
320
        value = XMLTextUtils.replaceCharsWithEntityStrings(value);
232
//        } catch( BadLocationException e ) {
321
233
//            throw new DOMException(DOMException.INVALID_STATE_ERR , e.getMessage());
322
        // Close the attribute if it was non-closed
234
//        } finally {
323
        if (h.notClosed) {
235
//            doc.atomicUnlock();
324
            value += h.firstChar;
236
//        }
325
        }
237
//
326
238
//        // Update the status of this object
327
        // Replace the text in the document
239
//        try {
328
        final LineDocument doc = syntax.getDocument();
240
//            int endOffset = oldValueStartPos + oldValueLength;
329
        AtomicLockDocument ald = LineDocumentUtils.asRequired(doc, AtomicLockDocument.class);
241
//            if (endOffset > doc.getLength()) {
330
        final BadLocationException[] ex = new BadLocationException[1];
242
//                endOffset = doc.getLength();
331
        final int fOldValStartPos = h.oldValueStartPos;
243
//            }
332
        final int fOldValLen = h.oldValueLength;
244
//            first = syntax.getTokenChain(first.getOffset(), endOffset);
333
        final String fValue = value;
245
//        } catch (BadLocationException e) {
334
        ald.runAtomic(() -> {;
246
//            throw new DOMException(DOMException.INVALID_STATE_ERR , e.getMessage());
335
            try {
247
//        }
336
                doc.remove(fOldValStartPos, fOldValLen);
337
                doc.insertString(fOldValStartPos, fValue, null);
338
                //doc.invalidateSyntaxMarks();
339
            } catch( BadLocationException e ) {
340
                ex[0] = e;
341
            }
342
        });
343
        if (ex[0] != null) {
344
            throw new DOMException(DOMException.INVALID_STATE_ERR , ex[0].getMessage());
345
        }
346
347
        // Update the status of this object
348
        try {
349
            int endOffset = fOldValStartPos + fOldValLen;
350
            if (endOffset > doc.getLength()) {
351
                endOffset = doc.getLength();
352
            }
353
            syntax.runWithSequence(first.offset(null), 
354
                (TokenSequence ts) -> {
355
                first = ts.token();
356
                return null;
357
            });
358
        } catch (BadLocationException e) {
359
            throw new DOMException(DOMException.INVALID_STATE_ERR , e.getMessage());
360
        }
248
    }
361
    }
249
    
362
    
250
    public void setNodeValue(String value) {
363
    public void setNodeValue(String value) {
Lines 259-300 Link Here
259
        return getValue();
372
        return getValue();
260
    }
373
    }
261
    
374
    
375
    private String getValueLocked(TokenSequence ts) {
376
        StringBuilder sb = new StringBuilder();
377
        boolean valStarted = false;
378
        V: while (ts.moveNext()) {
379
            Token<XMLTokenId> t = ts.token();
380
            switch (t.id()) {
381
                case CHARACTER:
382
                    if (!valStarted) {
383
                        return null;
384
                    }
385
                    // fall through
386
                case VALUE:  {
387
                    String image = t.text().toString();
388
                    String actual = XMLTextUtils.actualAttributeValue(image);
389
                    valStarted = true;
390
                    if (!image.equals(actual)) {
391
                        sb.append(actual);
392
                        break;
393
                    } else {
394
                        sb.append(image);
395
                    }
396
                    break;
397
                }
398
                case WS:
399
                case OPERATOR:
400
                    break;
401
                default:
402
                    break V;
403
            }
404
        }
405
        // Remove " and ' around the attribute value
406
        if (sb.length() > 0) {
407
            char firstChar = sb.charAt(0);
408
            if (firstChar == '"' ||  firstChar == '\'') {
409
                sb.deleteCharAt(0);
410
                if (sb.length() > 0 && sb.charAt(sb.length()-1) == firstChar) {
411
                    sb.deleteCharAt(sb.length()-1);
412
                }
413
            }
414
        }
415
        return XMLTextUtils.replaceEntityStringsWithChars(sb.toString());
416
    }
417
    
262
    public String getValue() {
418
    public String getValue() {
263
//        // Find the first value token.  Should be after "name="
419
        try {
264
//        TokenItem next = first;
420
            return syntax.runWithSequence(first, this::getValueLocked);
265
//        for (; next != null; next = next.getNext()) {
421
        } catch (BadLocationException ex) {
266
//            if (next.getTokenID() == VALUE) {
422
            Exceptions.printStackTrace(ex);
267
//                break;
423
            return null;
268
//            }
424
        }
269
//        }
270
//
271
//        // Add values of all value and character entity
272
//        StringBuffer buf = new StringBuffer();
273
//        while (next != null && (next.getTokenID() == VALUE || next.getTokenID() == CHARACTER)) {
274
//            String image = next.getImage();
275
//            String actual = Util.actualAttributeValue(image);
276
//            if (!image.equals(actual)) {
277
//                buf.append(actual);
278
//                break;
279
//            } else {
280
//                buf.append(image);
281
//            }
282
//            next = next.getNext();
283
//        }
284
//
285
//        // Remove " and ' around the attribute value
286
//        if (buf.length() > 0) {
287
//            char firstChar = buf.charAt(0);
288
//            if (firstChar == '"' ||  firstChar == '\'') {
289
//                buf.deleteCharAt(0);
290
//                if (buf.length() > 0 && buf.charAt(buf.length()-1) == firstChar) {
291
//                    buf.deleteCharAt(buf.length()-1);
292
//                }
293
//            }
294
//        }
295
//
296
//        return Util.replaceEntityStringsWithChars(buf.toString());
297
        return null;
298
    }
425
    }
299
    
426
    
300
    public short getNodeType() {
427
    public short getNodeType() {
Lines 307-313 Link Here
307
    
434
    
308
    public Element getOwnerElement() {
435
    public Element getOwnerElement() {
309
//        ((Tag)parent).retokenizeObject();
436
//        ((Tag)parent).retokenizeObject();
310
        return parent;
437
        if (parent == null) {
438
            return null;
439
        }
440
        return (Element)parent.getNode();
311
    }
441
    }
312
    
442
    
313
    /**
443
    /**
(-)a/xml.text/src/org/netbeans/modules/xml/text/dom/SyntaxElement.java (-16 / +42 lines)
Lines 46-55 Link Here
46
package org.netbeans.modules.xml.text.dom;
46
package org.netbeans.modules.xml.text.dom;
47
47
48
48
49
import org.netbeans.modules.xml.text.api.dom.XMLSyntaxSupport;
49
import java.lang.ref.WeakReference;
50
import java.lang.ref.WeakReference;
50
import javax.swing.text.BadLocationException;
51
import javax.swing.text.BadLocationException;
51
import org.netbeans.api.lexer.Token;
52
import org.netbeans.api.lexer.Token;
52
import org.netbeans.api.xml.lexer.XMLTokenId;
53
import org.netbeans.api.xml.lexer.XMLTokenId;
54
import org.netbeans.modules.xml.text.api.dom.SyntaxElement;
55
import org.w3c.dom.Node;
53
56
54
57
55
/**
58
/**
Lines 64-82 Link Here
64
 *
67
 *
65
 * @version 1.0
68
 * @version 1.0
66
 */
69
 */
67
public abstract class SyntaxElement {
70
public abstract class BaseSyntaxElement implements org.netbeans.modules.xml.text.api.dom.SyntaxElement {
68
    
71
    
69
    protected XMLSyntaxSupport support;
72
    protected XMLSyntaxSupport support;
70
    private WeakReference<Token> first; //a weak reference to the fist TokenItem of this SE
73
    private WeakReference<Token> first; //a weak reference to the fist TokenItem of this SE
71
    private WeakReference<SyntaxElement> previous;    // WR to the cached previous element
74
    private WeakReference<BaseSyntaxElement> previous;    // WR to the cached previous element
72
    private WeakReference<SyntaxElement> next;        // WR to the cached next element
75
    private WeakReference<BaseSyntaxElement> next;        // WR to the cached next element
73
    
76
    
74
    // let it be visible by static inner classes extending us
77
    // let it be visible by static inner classes extending us
75
    protected int offset;     // original position in document
78
    protected int offset;     // original position in document
76
    protected int length;     // original lenght in document
79
    protected int length;     // original lenght in document
77
    
80
    
78
    /** Creates new SyntaxElement */
81
    /** Creates new SyntaxElement */
79
    SyntaxElement(XMLSyntaxSupport support, Token<XMLTokenId> token, int start, int end)  {
82
    BaseSyntaxElement(XMLSyntaxSupport support, Token<XMLTokenId> token, int start, int end)  {
80
        this.support = support;
83
        this.support = support;
81
        this.offset = start;
84
        this.offset = start;
82
        this.length = end-start;
85
        this.length = end-start;
Lines 118-128 Link Here
118
        return length;
121
        return length;
119
    }
122
    }
120
    
123
    
121
    void setNext(SyntaxElement se) {
124
    void setNext(BaseSyntaxElement se) {
122
        next = new WeakReference(se);
125
        next = new WeakReference(se);
123
    }
126
    }
124
    
127
    
125
    void setPrevious(SyntaxElement se) {
128
    void setPrevious(BaseSyntaxElement se) {
126
        previous = new WeakReference(se);
129
        previous = new WeakReference(se);
127
    }
130
    }
128
    
131
    
Lines 131-138 Link Here
131
     * @return previous SyntaxElement or <code>null</code> at document begining
134
     * @return previous SyntaxElement or <code>null</code> at document begining
132
     * or illegal location.
135
     * or illegal location.
133
     */
136
     */
134
    public SyntaxElement getPrevious() {
137
    public BaseSyntaxElement getPrevious() {
135
        SyntaxElement cached_previous = (previous == null) ? null : previous.get();
138
        BaseSyntaxElement cached_previous = (previous == null) ? null : previous.get();
136
        if( cached_previous != null )
139
        if( cached_previous != null )
137
            return cached_previous;
140
            return cached_previous;
138
        try {
141
        try {
Lines 141-147 Link Here
141
                return null;
144
                return null;
142
            }
145
            }
143
            //data not inialized yet or GC'ed already - we need to parse again
146
            //data not inialized yet or GC'ed already - we need to parse again
144
            SyntaxElement new_previous = support.getElementChain( getElementOffset() - 1 );
147
            BaseSyntaxElement new_previous = (BaseSyntaxElement)support.getElementChain( getElementOffset() - 1 );
145
            if( new_previous != null ) {
148
            if( new_previous != null ) {
146
                setPrevious(new_previous); //weakly cache the element
149
                setPrevious(new_previous); //weakly cache the element
147
                new_previous.setNext(this);
150
                new_previous.setNext(this);
Lines 160-172 Link Here
160
     * @return next SyntaxElement or <code>null</code> at document end
163
     * @return next SyntaxElement or <code>null</code> at document end
161
     * or illegal location.
164
     * or illegal location.
162
     */
165
     */
163
    public SyntaxElement getNext() {
166
    public BaseSyntaxElement getNext() {
164
        SyntaxElement cached_next = next == null ? null : next.get();
167
        BaseSyntaxElement cached_next = next == null ? null : next.get();
165
        if( cached_next != null )
168
        if( cached_next != null )
166
            return cached_next;
169
            return cached_next;
167
        try {
170
        try {
168
            //data not inialized yet or GC'ed already - we need to parse again
171
            //data not inialized yet or GC'ed already - we need to parse again
169
            SyntaxElement new_next = support.getElementChain( offset+length);
172
            BaseSyntaxElement new_next = (BaseSyntaxElement)support.getElementChain( offset+length + 1);
170
            if( new_next != null ) {
173
            if( new_next != null ) {
171
                setNext(new_next); //weakly cache the element
174
                setNext(new_next); //weakly cache the element
172
                new_next.setPrevious(this);
175
                new_next.setPrevious(this);
Lines 179-185 Link Here
179
            return null;
182
            return null;
180
        }
183
        }
181
    }
184
    }
182
    
185
183
    /**
186
    /**
184
     * Print element content for debug purposes.
187
     * Print element content for debug purposes.
185
     */
188
     */
Lines 199-214 Link Here
199
     * DOM Node equals. It's not compatible with Object's equals specs!
202
     * DOM Node equals. It's not compatible with Object's equals specs!
200
     */
203
     */
201
    public boolean equals(Object obj) {
204
    public boolean equals(Object obj) {
202
        if (obj instanceof SyntaxElement) {
205
        if (obj instanceof BaseSyntaxElement) {
203
            if (((SyntaxElement)obj).offset == offset) return true;
206
            if (((BaseSyntaxElement)obj).offset == offset) return true;
204
        }
207
        }
205
        return false;
208
        return false;
206
    }
209
    }
207
        
210
        
211
    public String getName() {
212
        return null;
213
    }
214
    
208
    /**
215
    /**
209
     * It may stop some DOM traversing.  //!!!
216
     * It may stop some DOM traversing.  //!!!
210
     */
217
     */
211
    public static class Error extends SyntaxElement {
218
    public static class Error extends BaseSyntaxElement {
212
        public Error( XMLSyntaxSupport support, Token first, int start, int end ) {
219
        public Error( XMLSyntaxSupport support, Token first, int start, int end ) {
213
            super( support, first, start, end);
220
            super( support, first, start, end);
214
        }
221
        }
Lines 216-221 Link Here
216
        public String toString() {
223
        public String toString() {
217
            return "Error" + super.toString();                                  // NOI18N
224
            return "Error" + super.toString();                                  // NOI18N
218
        }
225
        }
226
227
        @Override
228
        public int getType() {
229
            return NODE_ERROR;
230
        }
231
232
        @Override
233
        public Node getNode() {
234
            return null;
235
        }
236
237
        @Override
238
        public SyntaxElement getParentElement() {
239
            BaseSyntaxElement x = this;
240
            while (x != null && x.getType() != Node.ELEMENT_NODE) {
241
                x = x.getPrevious();
242
            }
243
            return x;
244
        }
219
    }
245
    }
220
    
246
    
221
}
247
}
(-)a/xml.text/src/org/netbeans/modules/xml/text/dom/CDATASection.java (-2 / +23 lines)
Lines 44-70 Link Here
44
44
45
package org.netbeans.modules.xml.text.dom;
45
package org.netbeans.modules.xml.text.dom;
46
46
47
import org.netbeans.modules.xml.text.api.dom.XMLSyntaxSupport;
47
import org.netbeans.api.lexer.Token;
48
import org.netbeans.api.lexer.Token;
48
import org.netbeans.api.xml.lexer.XMLTokenId;
49
import org.netbeans.api.xml.lexer.XMLTokenId;
50
import org.w3c.dom.Node;
49
51
50
/**
52
/**
51
 * CDATA section representation.
53
 * CDATA section representation.
52
 */
54
 */
53
public class CDATASection extends Text {
55
public class CDATASection extends TextImpl implements org.w3c.dom.CDATASection {
54
56
55
    /**
57
    /**
56
     * Create content text node.
58
     * Create content text node.
57
     */
59
     */
58
    CDATASection(XMLSyntaxSupport support, Token<XMLTokenId> from, int start, int end) {
60
    public CDATASection(XMLSyntaxSupport support, Token<XMLTokenId> from, int start, int end) {
59
        super( support, from, start, end);
61
        super( support, from, start, end);
60
    }
62
    }
61
63
64
    @Override
65
    public String getNodeValue() {
66
        String text = first().text().toString();
67
        int start = 0;
68
        int end = text.length();
69
        if (text.startsWith("<![CDATA[")) {
70
            start = 9;
71
        }
72
        if (text.endsWith("]]>")) {
73
            end = text.length() - 3;
74
        }
75
        return text.substring(start, end);
76
    }
77
62
//    /**
78
//    /**
63
//     * Create attribute text node.
79
//     * Create attribute text node.
64
//     */
80
//     */
65
//    CDATASection(XMLSyntaxSupport syntax, Token from, Attr parent) {
81
//    CDATASection(XMLSyntaxSupport syntax, Token from, Attr parent) {
66
//        super( syntax, from, parent);
82
//        super( syntax, from, parent);
67
//    }
83
//    }
84
85
    @Override
86
    public short getNodeType() {
87
        return Node.CDATA_SECTION_NODE;
88
    }
68
    
89
    
69
}
90
}
70
91
(-)a/xml.text/src/org/netbeans/modules/xml/text/dom/Comment.java (-1 / +2 lines)
Lines 44-49 Link Here
44
44
45
package org.netbeans.modules.xml.text.dom;
45
package org.netbeans.modules.xml.text.dom;
46
46
47
import org.netbeans.modules.xml.text.api.dom.XMLSyntaxSupport;
47
import org.netbeans.api.lexer.Token;
48
import org.netbeans.api.lexer.Token;
48
import org.netbeans.api.xml.lexer.XMLTokenId;
49
import org.netbeans.api.xml.lexer.XMLTokenId;
49
import org.netbeans.modules.xml.spi.dom.ROException;
50
import org.netbeans.modules.xml.spi.dom.ROException;
Lines 57-63 Link Here
57
 */
58
 */
58
public class Comment extends SyntaxNode implements org.w3c.dom.Comment {
59
public class Comment extends SyntaxNode implements org.w3c.dom.Comment {
59
60
60
    Comment(XMLSyntaxSupport support, Token<XMLTokenId> from, int start, int end) {
61
    public Comment(XMLSyntaxSupport support, Token<XMLTokenId> from, int start, int end) {
61
        super( support, from, start, end);
62
        super( support, from, start, end);
62
    }
63
    }
63
64
(-)a/xml.text/src/org/netbeans/modules/xml/text/dom/Document.java (-3 / +3 lines)
Lines 45-56 Link Here
45
package org.netbeans.modules.xml.text.dom;
45
package org.netbeans.modules.xml.text.dom;
46
46
47
import org.netbeans.modules.xml.spi.dom.*;
47
import org.netbeans.modules.xml.spi.dom.*;
48
import org.w3c.dom.DOMException;
48
49
49
public class Document extends AbstractNode implements org.w3c.dom.Document {
50
public class Document extends AbstractNode implements org.w3c.dom.Document {
50
51
51
    SyntaxElement syntax;
52
    BaseSyntaxElement syntax;
52
53
53
    Document(SyntaxElement element) {
54
    Document(BaseSyntaxElement element) {
54
        syntax = element;
55
        syntax = element;
55
    }
56
    }
56
57
Lines 273-278 Link Here
273
        }
274
        }
274
275
275
    }
276
    }
276
277
}
277
}
278
278
(-)a/xml.text/src/org/netbeans/modules/xml/text/dom/DocumentType.java (-1 / +2 lines)
Lines 44-49 Link Here
44
44
45
package org.netbeans.modules.xml.text.dom;
45
package org.netbeans.modules.xml.text.dom;
46
46
47
import org.netbeans.modules.xml.text.api.dom.XMLSyntaxSupport;
47
import org.netbeans.api.lexer.Token;
48
import org.netbeans.api.lexer.Token;
48
import org.netbeans.api.xml.lexer.XMLTokenId;
49
import org.netbeans.api.xml.lexer.XMLTokenId;
49
import org.netbeans.modules.xml.spi.dom.*;
50
import org.netbeans.modules.xml.spi.dom.*;
Lines 55-61 Link Here
55
 */
56
 */
56
public class DocumentType extends SyntaxNode implements org.w3c.dom.DocumentType {
57
public class DocumentType extends SyntaxNode implements org.w3c.dom.DocumentType {
57
58
58
    DocumentType(XMLSyntaxSupport syntax, Token<XMLTokenId> first, int start, int end) {
59
    public DocumentType(XMLSyntaxSupport syntax, Token<XMLTokenId> first, int start, int end) {
59
        super (syntax, first, start, end);
60
        super (syntax, first, start, end);
60
    }
61
    }
61
62
(-)a/xml.text/src/org/netbeans/modules/xml/text/dom/EmptyTag.java (-5 / +21 lines)
Lines 45-50 Link Here
45
package org.netbeans.modules.xml.text.dom;
45
package org.netbeans.modules.xml.text.dom;
46
46
47
47
48
import org.netbeans.modules.xml.text.api.dom.XMLSyntaxSupport;
48
import org.netbeans.api.lexer.Token;
49
import org.netbeans.api.lexer.Token;
49
import org.netbeans.api.xml.lexer.XMLTokenId;
50
import org.netbeans.api.xml.lexer.XMLTokenId;
50
import org.w3c.dom.*;
51
import org.w3c.dom.*;
Lines 52-61 Link Here
52
53
53
public class EmptyTag extends Tag {
54
public class EmptyTag extends Tag {
54
55
55
    EmptyTag(XMLSyntaxSupport support, Token<XMLTokenId> from, int start, int end) {
56
    public EmptyTag(XMLSyntaxSupport support, Token<XMLTokenId> from, int start, int end) {
56
        super( support, from, start, end);
57
        super( support, from, start, end, from.text().toString().substring(1));
57
    }
58
    }
58
59
    
59
    public boolean hasChildNodes() {
60
    public boolean hasChildNodes() {
60
        return false;
61
        return false;
61
    }
62
    }
Lines 64-76 Link Here
64
        return NodeListImpl.EMPTY;
65
        return NodeListImpl.EMPTY;
65
    }
66
    }
66
    
67
    
67
    protected Tag getEndTag() {
68
    public Tag getEndTag() {
68
        return this;
69
        return this;
69
    }
70
    }
70
    
71
    
71
    protected Tag getStartTag() {
72
    public Tag getStartTag() {
72
        return this;
73
        return this;
73
    }
74
    }
75
76
    @Override
77
    public boolean isStart() {
78
        return false;
79
    }
80
81
    @Override
82
    public boolean isEnd() {
83
        return false;
84
    }
85
86
    @Override
87
    public boolean isSelfClosing() {
88
        return true;
89
    }
74
    
90
    
75
    public String toString() {
91
    public String toString() {
76
        StringBuffer ret = new StringBuffer( "EmptyTag(\"" + name + "\" " );
92
        StringBuffer ret = new StringBuffer( "EmptyTag(\"" + name + "\" " );
(-)a/xml.text/src/org/netbeans/modules/xml/text/dom/EndTag.java (-6 / +25 lines)
Lines 44-49 Link Here
44
44
45
package org.netbeans.modules.xml.text.dom;
45
package org.netbeans.modules.xml.text.dom;
46
46
47
import org.netbeans.modules.xml.text.api.dom.XMLSyntaxSupport;
47
import java.util.*;
48
import java.util.*;
48
49
49
import org.netbeans.api.lexer.Token;
50
import org.netbeans.api.lexer.Token;
Lines 57-65 Link Here
57
 */
58
 */
58
public class EndTag extends Tag {
59
public class EndTag extends Tag {
59
60
60
    EndTag(XMLSyntaxSupport support, Token<XMLTokenId> from, int start, int end) {
61
    public EndTag(XMLSyntaxSupport support, Token<XMLTokenId> from, int start, int end) {
61
        super( support, from, start, end);
62
        super(support, from, start, end, from.text().toString().substring(2));
62
        this.name = from.text().toString();
63
        if (name.equals("")) { // NOI18N
64
            // self-closing tag ? -- TODO
65
        }
63
    }
66
    }
64
67
65
    /**
68
    /**
Lines 75-81 Link Here
75
    }
78
    }
76
    
79
    
77
    public boolean hasChildNodes() {
80
    public boolean hasChildNodes() {
78
        SyntaxElement prev = getPrevious();
81
        BaseSyntaxElement prev = getPrevious();
79
        if (prev == null) return false;
82
        if (prev == null) return false;
80
        if (prev instanceof EndTag && ((EndTag)prev).getStartTag() == null) return false;
83
        if (prev instanceof EndTag && ((EndTag)prev).getStartTag() == null) return false;
81
        if (prev instanceof StartTag) return false;
84
        if (prev instanceof StartTag) return false;
Lines 95-101 Link Here
95
        return new NodeListImpl(list);
98
        return new NodeListImpl(list);
96
    }
99
    }
97
    
100
    
98
    protected Tag getStartTag() {
101
    public Tag getStartTag() {
99
        
102
        
100
        SyntaxNode prev = findPrevious();
103
        SyntaxNode prev = findPrevious();
101
        
104
        
Lines 121-129 Link Here
121
        return null;
124
        return null;
122
    }
125
    }
123
    
126
    
124
    protected Tag getEndTag() {
127
    public Tag getEndTag() {
125
        return this;
128
        return this;
126
    }
129
    }
130
131
    @Override
132
    public boolean isStart() {
133
        return false;
134
    }
135
136
    @Override
137
    public boolean isEnd() {
138
        return true;
139
    }
140
141
    @Override
142
    public boolean isSelfClosing() {
143
        return false;
144
    }
145
127
    
146
    
128
    public String toString() {
147
    public String toString() {
129
        return "EndTag(\"" + name + "\") " + first();
148
        return "EndTag(\"" + name + "\") " + first();
(-)a/xml.text/src/org/netbeans/modules/xml/text/dom/EntityReference.java (+1 lines)
Lines 44-49 Link Here
44
44
45
package org.netbeans.modules.xml.text.dom;
45
package org.netbeans.modules.xml.text.dom;
46
46
47
import org.netbeans.modules.xml.text.api.dom.XMLSyntaxSupport;
47
import org.netbeans.api.lexer.Token;
48
import org.netbeans.api.lexer.Token;
48
import org.netbeans.api.xml.lexer.XMLTokenId;
49
import org.netbeans.api.xml.lexer.XMLTokenId;
49
import org.w3c.dom.Node;
50
import org.w3c.dom.Node;
(-)a/xml.text/src/org/netbeans/modules/xml/text/dom/ProcessingInstruction.java (-3 / +13 lines)
Lines 44-49 Link Here
44
44
45
package org.netbeans.modules.xml.text.dom;
45
package org.netbeans.modules.xml.text.dom;
46
46
47
import org.netbeans.modules.xml.text.api.dom.XMLSyntaxSupport;
47
import org.netbeans.api.lexer.Token;
48
import org.netbeans.api.lexer.Token;
48
49
49
import org.netbeans.api.xml.lexer.XMLTokenId;
50
import org.netbeans.api.xml.lexer.XMLTokenId;
Lines 56-68 Link Here
56
 *
57
 *
57
 * @author  Petr Kuzel
58
 * @author  Petr Kuzel
58
 */
59
 */
59
public final class ProcessingInstruction extends SyntaxNode {
60
public final class ProcessingInstruction extends SyntaxNode implements org.w3c.dom.ProcessingInstruction {
60
    
61
    
61
    private String target;
62
    private String target;
62
    private String content;
63
    private String content;
63
64
64
    /** Creates a new instance of ProcessingInstructionImpl */
65
    /** Creates a new instance of ProcessingInstructionImpl */
65
    ProcessingInstruction(XMLSyntaxSupport syntax, Token<XMLTokenId> first,
66
    public ProcessingInstruction(XMLSyntaxSupport syntax, Token<XMLTokenId> first,
66
            int start, int end, String target, String content) {
67
            int start, int end, String target, String content) {
67
        super(syntax, first, start, end);
68
        super(syntax, first, start, end);
68
        this.target = target;
69
        this.target = target;
Lines 90-94 Link Here
90
    public void setData(String data) throws DOMException {
91
    public void setData(String data) throws DOMException {
91
        throw new ROException();
92
        throw new ROException();
92
    }
93
    }
93
    
94
95
    @Override
96
    public String getTarget() {
97
        return getNodeName();
98
    }
99
100
    @Override
101
    public String getData() {
102
        return getNodeValue();
103
    }
94
}
104
}
(-)a/xml.text/src/org/netbeans/modules/xml/text/dom/StartTag.java (-6 / +18 lines)
Lines 44-65 Link Here
44
44
45
package org.netbeans.modules.xml.text.dom;
45
package org.netbeans.modules.xml.text.dom;
46
46
47
import org.netbeans.modules.xml.text.api.dom.XMLSyntaxSupport;
47
import java.util.*;
48
import java.util.*;
48
49
49
import org.netbeans.api.lexer.Token;
50
import org.netbeans.api.lexer.Token;
50
import org.netbeans.api.xml.lexer.XMLTokenId;
51
import org.netbeans.api.xml.lexer.XMLTokenId;
51
import org.netbeans.modules.xml.spi.dom.NodeListImpl;
52
import org.netbeans.modules.xml.spi.dom.NodeListImpl;
53
import org.netbeans.modules.xml.text.api.dom.TagElement;
52
import org.w3c.dom.*;
54
import org.w3c.dom.*;
53
55
54
public class StartTag extends Tag {
56
public class StartTag extends Tag {
55
57
56
    StartTag(XMLSyntaxSupport support, Token<XMLTokenId> from, int start, int end) {
58
    public StartTag(XMLSyntaxSupport support, Token<XMLTokenId> from, int start, int end) {
57
        super( support, from, start, end);
59
        super( support, from, start, end, from.text().toString().substring(1));
58
        this.name = from.text().toString();
59
    }
60
    }
60
61
61
    public boolean hasChildNodes() {
62
    public boolean hasChildNodes() {
62
        SyntaxElement next = getNext();
63
        BaseSyntaxElement next = getNext();
63
        if (next == null) return false;
64
        if (next == null) return false;
64
        // if not well-formed
65
        // if not well-formed
65
        if (next instanceof StartTag && ((StartTag)next).getEndTag() == null) return false;
66
        if (next instanceof StartTag && ((StartTag)next).getEndTag() == null) return false;
Lines 80-90 Link Here
80
        return new NodeListImpl(list);
81
        return new NodeListImpl(list);
81
    }
82
    }
82
    
83
    
83
    protected Tag getStartTag() {
84
    public Tag getStartTag() {
84
        return this;
85
        return this;
85
    }
86
    }
86
    
87
    
87
    protected Tag getEndTag() {
88
    public Tag getEndTag() {
88
        
89
        
89
        SyntaxNode next = findNext();
90
        SyntaxNode next = findNext();
90
        
91
        
Lines 116-120 Link Here
116
        return ret.toString() + " " + first() + ")";
117
        return ret.toString() + " " + first() + ")";
117
    }
118
    }
118
    
119
    
120
    public boolean isStart() {
121
        return true;
122
    }
123
    
124
    public boolean isEnd() {
125
        return false;
126
    }
127
    
128
    public boolean isSelfClosing() {
129
        return false;
130
    }
119
}
131
}
120
132
(-)a/xml.text/src/org/netbeans/modules/xml/text/dom/SyntaxNode.java (-6 / +22 lines)
Lines 44-53 Link Here
44
44
45
package org.netbeans.modules.xml.text.dom;
45
package org.netbeans.modules.xml.text.dom;
46
46
47
import org.netbeans.modules.xml.text.api.dom.XMLSyntaxSupport;
47
import org.netbeans.modules.xml.spi.dom.*;
48
import org.netbeans.modules.xml.spi.dom.*;
48
import org.netbeans.api.lexer.Token;
49
import org.netbeans.api.lexer.Token;
50
import org.netbeans.modules.xml.text.api.dom.SyntaxElement;
49
import org.w3c.dom.Element;
51
import org.w3c.dom.Element;
50
import org.w3c.dom.Node;
52
import org.w3c.dom.Node;
53
import org.w3c.dom.Text;
51
import org.w3c.dom.TypeInfo;
54
import org.w3c.dom.TypeInfo;
52
import org.w3c.dom.UserDataHandler;
55
import org.w3c.dom.UserDataHandler;
53
56
Lines 67-79 Link Here
67
 * @version 1.0
70
 * @version 1.0
68
 */
71
 */
69
72
70
public abstract class SyntaxNode extends SyntaxElement implements org.w3c.dom.Node {
73
public abstract class SyntaxNode extends BaseSyntaxElement implements org.w3c.dom.Node {
71
74
72
    /** Creates new SyntaxNode */
75
    /** Creates new SyntaxNode */
73
    SyntaxNode(XMLSyntaxSupport support, Token first, int start, int end)  {
76
    SyntaxNode(XMLSyntaxSupport support, Token first, int start, int end)  {
74
        super( support, first, start, end);
77
        super( support, first, start, end);
75
    }
78
    }
76
79
80
    @Override
81
    public int getType() {
82
        return getNodeType();
83
    }
84
85
    @Override
86
    public Node getNode() {
87
        return this;
88
    }
77
    /**
89
    /**
78
     * Default implementation returning first previous <code>SyntaxNode</code>
90
     * Default implementation returning first previous <code>SyntaxNode</code>
79
     * or <code>null</code>. It is <code>StartTag</code> aware.
91
     * or <code>null</code>. It is <code>StartTag</code> aware.
Lines 92-99 Link Here
92
    /**
104
    /**
93
     * Find previous SyntaxNode instance or <code>null</code>.
105
     * Find previous SyntaxNode instance or <code>null</code>.
94
     */
106
     */
95
    static SyntaxNode findPrevious(SyntaxElement el) {
107
    static SyntaxNode findPrevious(BaseSyntaxElement el) {
96
        SyntaxElement prev = el.getPrevious();
108
        BaseSyntaxElement prev = el.getPrevious();
97
        while ((prev instanceof SyntaxNode) == false) {
109
        while ((prev instanceof SyntaxNode) == false) {
98
            if (prev == null) return null;            
110
            if (prev == null) return null;            
99
            prev = prev.getPrevious();
111
            prev = prev.getPrevious();
Lines 125-132 Link Here
125
    /**
137
    /**
126
     * Find previous SyntaxNode instance or <code>null</code>.
138
     * Find previous SyntaxNode instance or <code>null</code>.
127
     */
139
     */
128
    static SyntaxNode findNext(SyntaxElement el) {
140
    static SyntaxNode findNext(BaseSyntaxElement el) {
129
        SyntaxElement next = el.getNext();
141
        BaseSyntaxElement next = el.getNext();
130
        while ((next instanceof SyntaxNode) == false) {
142
        while ((next instanceof SyntaxNode) == false) {
131
            if (next == null) return null;            
143
            if (next == null) return null;            
132
            next = next.getNext();
144
            next = next.getNext();
Lines 141-146 Link Here
141
        return findNext(this);
153
        return findNext(this);
142
    }
154
    }
143
    
155
    
156
    public SyntaxElement getParentElement() {
157
        Node n = getParentNode();
158
        return n instanceof SyntaxElement ? (SyntaxElement)n : null;
159
    }
160
    
144
    /**
161
    /**
145
     * First previous start tag at higher level is my parent.
162
     * First previous start tag at higher level is my parent.
146
     * Skip all end-tag start-tag pairs at the same level.
163
     * Skip all end-tag start-tag pairs at the same level.
Lines 338-342 Link Here
338
    public void setIdAttributeNode(org.w3c.dom.Attr a, boolean b) {
355
    public void setIdAttributeNode(org.w3c.dom.Attr a, boolean b) {
339
        throw new UOException ();
356
        throw new UOException ();
340
    }
357
    }
341
    
342
}
358
}
(-)a/xml.text/src/org/netbeans/modules/xml/text/dom/Tag.java (-48 / +88 lines)
Lines 44-53 Link Here
44
44
45
package org.netbeans.modules.xml.text.dom;
45
package org.netbeans.modules.xml.text.dom;
46
46
47
import java.util.Collection;
47
import org.netbeans.modules.xml.text.api.dom.XMLSyntaxSupport;
48
import java.util.Map;
49
import java.util.HashMap;
50
import java.util.LinkedHashMap;
51
import javax.swing.text.BadLocationException;
48
import org.netbeans.api.lexer.Token;
52
import org.netbeans.api.lexer.Token;
53
import org.netbeans.api.lexer.TokenSequence;
54
import org.netbeans.api.xml.lexer.XMLTokenId;
55
import org.netbeans.modules.xml.spi.dom.NamedNodeMapImpl;
49
import org.netbeans.modules.xml.spi.dom.ROException;
56
import org.netbeans.modules.xml.spi.dom.ROException;
50
import org.netbeans.modules.xml.spi.dom.UOException;
57
import org.netbeans.modules.xml.spi.dom.UOException;
58
import org.netbeans.modules.xml.text.api.dom.TagElement;
59
import org.openide.util.Exceptions;
51
import org.w3c.dom.NamedNodeMap;
60
import org.w3c.dom.NamedNodeMap;
52
import org.w3c.dom.Node;
61
import org.w3c.dom.Node;
53
import org.w3c.dom.NodeList;
62
import org.w3c.dom.NodeList;
Lines 61-74 Link Here
61
 * <code>equals</code>. The <code>equals</code> is used for syntax element
70
 * <code>equals</code>. The <code>equals</code> is used for syntax element
62
 * purposes.
71
 * purposes.
63
 */
72
 */
64
public abstract class Tag extends SyntaxNode implements org.w3c.dom.Element {
73
public abstract class Tag extends SyntaxNode implements org.w3c.dom.Element, TagElement {
65
    
74
    
66
    protected NamedNodeMap domAttributes;
75
    protected NamedNodeMap domAttributes;
67
    
76
    
68
    protected String name;
77
    protected String name;
69
    
78
    
70
    Tag(XMLSyntaxSupport support, Token from, int start, int end) {
79
    Tag(XMLSyntaxSupport support, Token from, int start, int end, String name) {
71
        super(support, from, start, end);
80
        super(support, from, start, end);
81
        this.name = name;
72
    }
82
    }
73
    
83
    
74
    public final short getNodeType() {
84
    public final short getNodeType() {
Lines 83-136 Link Here
83
        return name;
93
        return name;
84
    }
94
    }
85
    
95
    
96
    private Map parseAttributes(TokenSequence ts) {
97
        HashMap map = new LinkedHashMap(3);
98
99
        int index = 0;
100
        SCAN_LOOP:
101
        while (ts.moveNext()) {
102
            Token<XMLTokenId> next = ts.token();
103
            XMLTokenId id = next.id();
104
            String name;
105
            String value;
106
            if (id == XMLTokenId.ARGUMENT) {
107
                Token attributeStart = next;
108
                name = next.text().toString();
109
                while (next.id() != XMLTokenId.VALUE) {
110
                    if (!ts.moveNext()) {
111
                        break SCAN_LOOP;
112
                    }
113
                    next = ts.token();
114
                    if (next.id() == XMLTokenId.ERROR) {
115
                        break SCAN_LOOP;
116
                    }
117
                }
118
119
                // fuzziness to relax minor tokenization changes
120
                String image = next.text().toString();
121
                char test = image.charAt(0);
122
                if (image.length() == 1) {
123
                    if (test == '"' || test == '\'') {
124
                        if (!ts.moveNext()) {
125
                            break SCAN_LOOP;
126
                        }
127
                        next = ts.token();
128
                    }
129
                }
130
131
                value = next.text().toString();
132
133
                Object key = NamedNodeMapImpl.createKey(name);
134
                map.put(key, new AttrImpl(support, attributeStart, this, index++));
135
136
                next = skipAttributeValue(ts, test);
137
                if (next == null) {
138
                    break SCAN_LOOP;
139
                }
140
            } else if (id == XMLTokenId.WS) {
141
                // just skip
142
            } else {
143
                break; // end of element markup
144
            }
145
        }
146
        return map;
147
    }
148
    
149
    private static Token skipAttributeValue(TokenSequence ts, char delim) {
150
        do { 
151
            Token t = ts.token();
152
            if (t.text().charAt(t.length() - 1) == delim) {
153
                return ts.moveNext() ? ts.token() : null;
154
            }
155
        } while (ts.moveNext());
156
        return null;
157
    }
158
    
86
    /**
159
    /**
87
     * Create properly bound attributes and cache results.
160
     * Create properly bound attributes and cache results.
88
     * Parse attributes from first token.
161
     * Parse attributes from first token.
89
     */
162
     */
90
    public synchronized NamedNodeMap getAttributes() {
163
    public synchronized NamedNodeMap getAttributes() {
91
        
164
        try {
92
//        HashMap map = new LinkedHashMap(3);
165
            return new NamedNodeMapImpl(
93
//
166
                    support.runWithSequence(offset, (TokenSequence ts) -> {
94
//        SCAN_LOOP:
167
                        return parseAttributes(ts);
95
//            for (TokenItem next = first().getNext(); next != null; next = next.getNext()) {
168
                    })
96
//                TokenID id = next.getTokenID();
169
            );
97
//                String name;
170
        } catch (BadLocationException ex) {
98
//                String value;
171
            Exceptions.printStackTrace(ex);
99
//                if (id == ARGUMENT) {
172
            return null;
100
//                    TokenItem attributeStart = next;
173
        }
101
//                    name = next.getImage();
102
//                    while (next.getTokenID() != VALUE) {
103
//                        next = next.getNext();
104
//                        if (next == null || next.getTokenID() == ERROR) break SCAN_LOOP;
105
//                    }
106
//
107
//                    // fuzziness to relax minor tokenization changes
108
//                    String image = next.getImage();
109
//                    char test = image.charAt(0);
110
//                    if (image.length() == 1) {
111
//                        if (test == '"' || test == '\'') {
112
//                            next = next.getNext();
113
//                        }
114
//                    }
115
//
116
//                    if (next == null) break SCAN_LOOP;
117
//                    value = next.getImage();
118
//
119
//                    Object key = NamedNodeMapImpl.createKey(name);
120
//                    map.put(key, new AttrImpl(support, attributeStart, this));
121
//
122
//                    next = Util.skipAttributeValue(next, test);
123
//                    if (next == null) break SCAN_LOOP;
124
//                } else if (id == WS) {
125
//                    // just skip
126
//                } else {
127
//                    break; // end of element markup
128
//                }
129
//            }
130
//
131
//            // domAttributes = new NamedNodeMapImpl(map);
132
//            return new NamedNodeMapImpl(map);
133
        return null;
134
    }
174
    }
135
    
175
    
136
    public String getAttribute(String name) {
176
    public String getAttribute(String name) {
Lines 276-284 Link Here
276
        return list.item(list.getLength());
316
        return list.item(list.getLength());
277
    }
317
    }
278
    
318
    
279
    protected abstract Tag getStartTag();
319
    public abstract Tag getStartTag();
280
    
320
    
281
    protected abstract Tag getEndTag();
321
    public abstract Tag getEndTag();
282
        
322
        
283
    // unsupported DOM level 2 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~    
323
    // unsupported DOM level 2 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~    
284
    public String getAttributeNS(String namespaceURI, String localName) {
324
    public String getAttributeNS(String namespaceURI, String localName) {
(-)a/xml.text/src/org/netbeans/modules/xml/text/dom/Text.java (-6 / +6 lines)
Lines 44-53 Link Here
44
44
45
package org.netbeans.modules.xml.text.dom;
45
package org.netbeans.modules.xml.text.dom;
46
46
47
import org.netbeans.modules.xml.text.api.dom.XMLSyntaxSupport;
47
import org.netbeans.api.lexer.Token;
48
import org.netbeans.api.lexer.Token;
48
import org.w3c.dom.*;
49
import org.w3c.dom.*;
49
import org.netbeans.modules.xml.spi.dom.*;
50
import org.netbeans.modules.xml.spi.dom.*;
50
import org.netbeans.editor.*;
51
51
52
/**
52
/**
53
 * DOM Text implementation. Note that it is automatically
53
 * DOM Text implementation. Note that it is automatically
Lines 58-79 Link Here
58
 *
58
 *
59
 * @author Petr Kuzel
59
 * @author Petr Kuzel
60
 */
60
 */
61
public class Text extends SyntaxNode implements org.w3c.dom.Text {
61
public class TextImpl extends SyntaxNode implements org.w3c.dom.Text {
62
62
63
    // if attribute text node then parent otherwise null
63
    // if attribute text node then parent otherwise null
64
    private Attr parent;
64
    private AttrImpl parent;
65
    
65
    
66
    /**
66
    /**
67
     * Create content text node.
67
     * Create content text node.
68
     */
68
     */
69
    Text(XMLSyntaxSupport support, Token from, int start, int end) {
69
    public TextImpl(XMLSyntaxSupport support, Token from, int start, int end) {
70
        super( support, from, start, end);
70
        super( support, from, start, end);
71
    }
71
    }
72
    
72
    
73
    /**
73
    /**
74
     * Create attribute text node.
74
     * Create attribute text node.
75
     */
75
     */
76
    Text(XMLSyntaxSupport syntax, Token from, int start, int end, Attr parent) {
76
    public TextImpl(XMLSyntaxSupport syntax, Token from, int start, int end, AttrImpl parent) {
77
        super( syntax, from, start, end);
77
        super( syntax, from, start, end);
78
        if (parent == null) throw new IllegalArgumentException();
78
        if (parent == null) throw new IllegalArgumentException();
79
        this.parent = parent;
79
        this.parent = parent;
Lines 108-114 Link Here
108
        return getData();
108
        return getData();
109
    }
109
    }
110
        
110
        
111
    public Text splitText(int offset) {
111
    public TextImpl splitText(int offset) {
112
        throw new ROException();
112
        throw new ROException();
113
    }
113
    }
114
 
114
 
(-)a/xml.text/src/org/netbeans/modules/xml/text/folding/XmlFoldManager.java (-2 / +2 lines)
Lines 68-76 Link Here
68
import org.netbeans.api.lexer.TokenHierarchy;
68
import org.netbeans.api.lexer.TokenHierarchy;
69
import org.netbeans.api.xml.lexer.XMLTokenId;
69
import org.netbeans.api.xml.lexer.XMLTokenId;
70
import org.netbeans.editor.Utilities;
70
import org.netbeans.editor.Utilities;
71
import org.netbeans.modules.xml.text.api.XMLTextUtils;
71
import org.netbeans.modules.xml.text.folding.TokenElement.Token;
72
import org.netbeans.modules.xml.text.folding.TokenElement.Token;
72
import org.netbeans.modules.xml.text.folding.TokenElement.TokenType;
73
import org.netbeans.modules.xml.text.folding.TokenElement.TokenType;
73
import org.netbeans.modules.xml.text.syntax.XMLKit;
74
74
75
/**
75
/**
76
 * This class is an implementation of @see org.netbeans.spi.editor.fold.FoldManager
76
 * This class is an implementation of @see org.netbeans.spi.editor.fold.FoldManager
Lines 93-99 Link Here
93
    private Preferences prefs;
93
    private Preferences prefs;
94
94
95
    public XmlFoldManager() {
95
    public XmlFoldManager() {
96
        prefs = MimeLookup.getLookup(XMLKit.MIME_TYPE).lookup(Preferences.class);
96
        prefs = MimeLookup.getLookup(XMLTextUtils.XML_MIME).lookup(Preferences.class);
97
    }
97
    }
98
98
99
99
(-)a/xml.text/src/org/netbeans/modules/xml/text/indent/XMLLexerFormatter.java (-174 / +192 lines)
Lines 45-56 Link Here
45
45
46
import java.io.IOException;
46
import java.io.IOException;
47
import java.util.ArrayList;
47
import java.util.ArrayList;
48
import java.util.LinkedList;
49
import java.util.List;
48
import java.util.List;
50
import java.util.Stack;
49
import java.util.Stack;
51
import java.util.logging.Logger;
50
import java.util.logging.Logger;
52
import javax.swing.text.BadLocationException;
51
import javax.swing.text.BadLocationException;
53
import javax.swing.text.Element;
52
import org.netbeans.api.editor.document.LineDocument;
53
import org.netbeans.api.editor.document.LineDocumentUtils;
54
import org.netbeans.api.lexer.LanguagePath;
54
import org.netbeans.api.lexer.LanguagePath;
55
import org.netbeans.api.lexer.TokenHierarchy;
55
import org.netbeans.api.lexer.TokenHierarchy;
56
import org.netbeans.api.lexer.TokenSequence;
56
import org.netbeans.api.lexer.TokenSequence;
Lines 104-110 Link Here
104
        });
104
        });
105
    }
105
    }
106
106
107
    public BaseDocument doReformat(BaseDocument doc, int startOffset, int endOffset) {
107
    public LineDocument doReformat(LineDocument doc, int startOffset, int endOffset) {
108
        spacesPerTab = IndentUtils.indentLevelSize(doc);
108
        spacesPerTab = IndentUtils.indentLevelSize(doc);
109
        try {
109
        try {
110
            List<TokenIndent> tags = getTags(doc, startOffset, endOffset);
110
            List<TokenIndent> tags = getTags(doc, startOffset, endOffset);
Lines 125-131 Link Here
125
        return doc;
125
        return doc;
126
    }
126
    }
127
127
128
    private void changePrettyText(BaseDocument doc, TokenIndent tag) throws BadLocationException {
128
    private void changePrettyText(LineDocument doc, TokenIndent tag) throws BadLocationException {
129
        //i expected the call IndentUtils.createIndentString() to return
129
        //i expected the call IndentUtils.createIndentString() to return
130
        //the correct string for the indent level, but it doesn't.
130
        //the correct string for the indent level, but it doesn't.
131
        //so this is just a workaround.
131
        //so this is just a workaround.
Lines 137-147 Link Here
137
        noNewline = tag.isNoNewline();
137
        noNewline = tag.isNoNewline();
138
        String newIndentText = IndentUtils.createIndentString(doc, spaces);
138
        String newIndentText = IndentUtils.createIndentString(doc, spaces);
139
        //String newIndentText = formatter.getIndentString(doc, tag.getIndentLevel());
139
        //String newIndentText = formatter.getIndentString(doc, tag.getIndentLevel());
140
        int previousEndOffset = Utilities.getFirstNonWhiteBwd(doc, so) + 1;
140
        int previousEndOffset = LineDocumentUtils.getPreviousNonWhitespace(doc, so) + 1;
141
        CharSequence temp = org.netbeans.lib.editor.util.swing.DocumentUtilities.getText(doc, previousEndOffset, so - previousEndOffset);
141
        CharSequence temp = org.netbeans.lib.editor.util.swing.DocumentUtilities.getText(doc, previousEndOffset, so - previousEndOffset);
142
        if(noNewline || so == 0 || CharSequences.indexOf(temp, "\n") != -1){ // NOI18N
142
        if(noNewline || so == 0 || CharSequences.indexOf(temp, "\n") != -1){ // NOI18N
143
            int i = Utilities.getRowFirstNonWhite(doc, so);
143
            int i = LineDocumentUtils.getLineFirstNonWhitespace(doc, so);
144
            int rowStart = Utilities.getRowStart(doc, so);
144
            int rowStart = LineDocumentUtils.getLineStart(doc, so);
145
            
145
            
146
            String currentIndent = doc.getText(rowStart, i - rowStart);
146
            String currentIndent = doc.getText(rowStart, i - rowStart);
147
            if (!currentIndent.equals(newIndentText)) {
147
            if (!currentIndent.equals(newIndentText)) {
Lines 202-208 Link Here
202
    /**
202
    /**
203
     * The processed document
203
     * The processed document
204
     */
204
     */
205
    private BaseDocument basedoc;
205
    private LineDocument basedoc;
206
206
207
    private void outsideAttributes() {
207
    private void outsideAttributes() {
208
        firstAttributeIndent = -1;
208
        firstAttributeIndent = -1;
Lines 258-266 Link Here
258
        } else {
258
        } else {
259
            try {
259
            try {
260
                // align with the actual tag:
260
                // align with the actual tag:
261
                indentLevel = Utilities.getVisualColumn(basedoc, 
261
                indentLevel = Utilities.getVisualColumn((BaseDocument)basedoc, 
262
                        Utilities.getFirstNonWhiteFwd(basedoc, 
262
                        LineDocumentUtils.getNextNonWhitespace(basedoc, 
263
                            Utilities.getRowStart(basedoc, tokenSequence.offset())));
263
                        LineDocumentUtils.getLineStart(basedoc, tokenSequence.offset())));
264
                if (!increase) {
264
                if (!increase) {
265
                    indentLevel = Math.max(- spacesPerTab, indentLevel - spacesPerTab);
265
                    indentLevel = Math.max(- spacesPerTab, indentLevel - spacesPerTab);
266
                }
266
                }
Lines 322-328 Link Here
322
            if (!indent) {
322
            if (!indent) {
323
                if (!selfClosed && onlyTags) {
323
                if (!selfClosed && onlyTags) {
324
                    indent = true;
324
                    indent = true;
325
                    int start = Utilities.getRowStart(basedoc, tokenSequence.offset());
325
                    int start = LineDocumentUtils.getLineStart(basedoc, tokenSequence.offset());
326
                    // do not indent closing tags, if the start & end tag will end up on the same line:
326
                    // do not indent closing tags, if the start & end tag will end up on the same line:
327
                    if (myIndent != null) {
327
                    if (myIndent != null) {
328
                        int openStart = myIndent.getStartOffset();
328
                        int openStart = myIndent.getStartOffset();
Lines 370-376 Link Here
370
            } else {
370
            } else {
371
                // align one space after the tagname:
371
                // align one space after the tagname:
372
                TokenIndent tagIndent = stack.peek();
372
                TokenIndent tagIndent = stack.peek();
373
                int current = Utilities.getVisualColumn(basedoc, tokenSequence.offset());
373
                int current = Utilities.getVisualColumn((BaseDocument)basedoc, tokenSequence.offset());
374
                if (tagIndent == null) {
374
                if (tagIndent == null) {
375
                    // fallback
375
                    // fallback
376
                    firstAttributeIndent = current;
376
                    firstAttributeIndent = current;
Lines 438-444 Link Here
438
        if (lastNewline == -1 || preserveWhitespace || !intersectsWithRange) {
438
        if (lastNewline == -1 || preserveWhitespace || !intersectsWithRange) {
439
            // even if outside selection range, we do not update indent; text will not affect following tags
439
            // even if outside selection range, we do not update indent; text will not affect following tags
440
            // we have to set the 'newLine' flag, if the last text line only contains whitespaces. 
440
            // we have to set the 'newLine' flag, if the last text line only contains whitespaces. 
441
            int nonWhitePos = Utilities.getFirstNonWhiteFwd(basedoc, currentOffset + Math.max(0, lastNewline), currentOffset + image.length());
441
            int nonWhitePos = LineDocumentUtils.getNextNonWhitespace(basedoc, currentOffset + Math.max(0, lastNewline), currentOffset + image.length());
442
            contentPresent |= nonWhitePos > -1;
442
            contentPresent |= nonWhitePos > -1;
443
            wasNewline &= nonWhitePos == -1;
443
            wasNewline &= nonWhitePos == -1;
444
            onlyTags &= nonWhitePos == -1;
444
            onlyTags &= nonWhitePos == -1;
Lines 451-457 Link Here
451
        while (lno < lineCount) {
451
        while (lno < lineCount) {
452
            currentOffset += lno == 0 ? 0 : lineSizes[lno - 1] + 1; // add 1 for newline
452
            currentOffset += lno == 0 ? 0 : lineSizes[lno - 1] + 1; // add 1 for newline
453
            int lineEnd = currentOffset + lineSizes[lno];
453
            int lineEnd = currentOffset + lineSizes[lno];
454
            nonWhiteStart = Utilities.getFirstNonWhiteFwd(basedoc, currentOffset, lineEnd);
454
            nonWhiteStart = LineDocumentUtils.getNextNonWhitespace(basedoc, currentOffset, lineEnd);
455
            // implies a check for nonWhitestart > -1
455
            // implies a check for nonWhitestart > -1
456
            if (nonWhiteStart >= startOffset && nonWhiteStart <= endOffset) {
456
            if (nonWhiteStart >= startOffset && nonWhiteStart <= endOffset) {
457
                // emit a tag at this position
457
                // emit a tag at this position
Lines 520-526 Link Here
520
     * XML and the use of the xml:space attribute.  Together they are used to
520
     * XML and the use of the xml:space attribute.  Together they are used to
521
     * calculate how much each token should be indented by.
521
     * calculate how much each token should be indented by.
522
     */
522
     */
523
    private List<TokenIndent> getTags(BaseDocument basedoc, int startOffset, int endOffset)
523
    private List<TokenIndent> getTags(LineDocument basedoc, int startOffset, int endOffset)
524
            throws BadLocationException, IOException {
524
            throws BadLocationException, IOException {
525
        
525
        
526
        
526
        
Lines 530-712 Link Here
530
530
531
        // this is that 1st PI or tag will increment the level to 0
531
        // this is that 1st PI or tag will increment the level to 0
532
        indentLevel = -spacesPerTab;
532
        indentLevel = -spacesPerTab;
533
        basedoc.readLock();
533
        List[] result = new List[1];
534
        try {
534
        Exception[] ble = new Exception[1];
535
            TokenHierarchy tokenHierarchy = TokenHierarchy.get(basedoc);
535
        basedoc.render(() -> {
536
            tokenSequence = tokenHierarchy.tokenSequence();
536
            try {
537
                result[0] = getTagsLocked(startOffset, endOffset);
538
            } catch (BadLocationException | IOException ex) {
539
                ble[0] = ex;
540
            }
541
        });
542
        if (ble[0] != null) {
543
            if (ble[0] instanceof BadLocationException) {
544
                throw (BadLocationException)ble[0];
545
            }
546
            if (ble[0] instanceof IOException) {
547
                throw (IOException)ble[0];
548
            } else {
549
                throw new IOException(ble[0]);
550
            }
551
        }
552
        return result[0];
553
    }
554
    
555
    private List<TokenIndent> getTagsLocked(int startOffset, int endOffset) throws BadLocationException, IOException {
556
        TokenHierarchy tokenHierarchy = TokenHierarchy.get(basedoc);
557
        tokenSequence = tokenHierarchy.tokenSequence();
558
        token = tokenSequence.token();
559
        // Add the text token, if any, before xml declaration to document node
560
        if (token != null && token.id() == XMLTokenId.TEXT) {
561
            if (tokenSequence.moveNext()) {
562
                token = tokenSequence.token();
563
            }
564
        }
565
        currentTokensSize = 0;
566
567
568
        // will be set to indent of 1st attribute of a tag. Will be reset to -1 by start tag
569
        firstAttributeIndent = -1;
570
        wasNewline = false;
571
572
        while (tokenSequence.moveNext()) {
573
            int indentLineStart = 1;
537
            token = tokenSequence.token();
574
            token = tokenSequence.token();
538
            // Add the text token, if any, before xml declaration to document node
575
            XMLTokenId tokenId = token.id();
539
            if (token != null && token.id() == XMLTokenId.TEXT) {
576
            CharSequence image = token.text();
540
                if (tokenSequence.moveNext()) {
577
            if (tokenSequence.offset() > endOffset) {
541
                    token = tokenSequence.token();
578
                break;
542
                }
543
            }
579
            }
544
            currentTokensSize = 0;
580
            tokenInSelectionRange = tokenSequence.offset() >= startOffset || tokenSequence.offset() + token.length() > endOffset;
545
            
581
            switch (tokenId) {
546
582
                case TAG: { // Tag is encountered and the required level of indenting determined.
547
            // will be set to indent of 1st attribute of a tag. Will be reset to -1 by start tag
583
                            // The tokens are only assessed if they are in the selection
548
            firstAttributeIndent = -1;
584
                            // range, which is the whole document if no text is selected.
549
            wasNewline = false;
585
                    int len = image.length();
550
            
586
                    firstAttributeIndent = -1;
551
            while (tokenSequence.moveNext()) {
587
                    if (image.charAt(len - 1) == '>') {// '/>' // NOI18N
552
                int indentLineStart = 1;
588
                        if (len == 2) {
553
                token = tokenSequence.token();
589
                            endTag(image, true);
554
                XMLTokenId tokenId = token.id();
590
                        } else {
555
                CharSequence image = token.text();
591
                            // end tag name marker
556
                if (tokenSequence.offset() > endOffset) {
592
                            tagClose(image);
593
                        }
594
                    } else {
595
                        if (startsWith(image, "</")) { // NOI18N
596
                            endTag(image, false);
597
                        } else {
598
                            startTag(image);
599
                        }
600
                        outsideAttributes();
601
                    }
557
                    break;
602
                    break;
558
                }
603
                }
559
                tokenInSelectionRange = tokenSequence.offset() >= startOffset || tokenSequence.offset() + token.length() > endOffset;
604
                case PI_START: {
560
                switch (tokenId) {
605
                    updateIndent(true, -1, preserveWhitespace);
561
                    case TAG: { // Tag is encountered and the required level of indenting determined.
606
                    //indentLevel += spacesPerTab;
562
                                // The tokens are only assessed if they are in the selection
607
                    if (tokenInSelectionRange && !preserveWhitespace) {
563
                                // range, which is the whole document if no text is selected.
608
                        TokenElement tag = new TokenElement(TokenType.TOKEN_PI_START_TAG, 
564
                        int len = image.length();
609
                                tokenId.name(), 
565
                        firstAttributeIndent = -1;
610
                                tokenSequence.offset(), 
566
                        if (image.charAt(len - 1) == '>') {// '/>' // NOI18N
611
                                tokenSequence.offset() + token.length(), indentLevel);
567
                            if (len == 2) {
612
                        TokenIndent ti = new TokenIndent(preserveWhitespace, tokenSequence.offset(), indentLevel);
568
                                endTag(image, true);
613
                        ti.markNoNewline();
569
                            } else {
614
                        tags.add(ti);
570
                                // end tag name marker
615
                    }
571
                                tagClose(image);
616
                    break;
572
                            }
617
                }
573
                        } else {
618
                case PI_END: {
574
                            if (startsWith(image, "</")) { // NOI18N
619
                    int l = updateIndent(false, -1, preserveWhitespace);
575
                                endTag(image, false);
620
                    if (wasNewline && tokenInSelectionRange) {
576
                            } else {
621
                        // 1st item on a new line, will indent according to the opening tag
577
                                startTag(image);
622
                        tags.add(new TokenIndent(false, tokenSequence.offset(), l));
578
                            }
623
                    }
579
                            outsideAttributes();
624
                    break;
625
                }
626
                case WS: {
627
                        // we assume there is nothing except whitespace
628
                        int lastNewline = lastIndexOf(image, '\n');
629
                        if (lastNewline == -1) {
630
                            // nothing special here
631
                            break;
580
                        }
632
                        }
633
                        wasNewline = true;
581
                        break;
634
                        break;
582
                    }
635
                }
583
                    case PI_START: {
636
                case PI_CONTENT:
584
                        updateIndent(true, -1, preserveWhitespace);
637
                    indentLineStart = 0;
585
                        //indentLevel += spacesPerTab;
638
                    // fall through
586
                        if (tokenInSelectionRange && !preserveWhitespace) {
639
                case TEXT: {
587
                            TokenElement tag = new TokenElement(TokenType.TOKEN_PI_START_TAG, 
640
                    text(image, indentLineStart);
588
                                    tokenId.name(), 
641
                    break;
589
                                    tokenSequence.offset(), 
642
                }
590
                                    tokenSequence.offset() + token.length(), indentLevel);
643
591
                            TokenIndent ti = new TokenIndent(preserveWhitespace, tokenSequence.offset(), indentLevel);
644
                /**
592
                            ti.markNoNewline();
645
                 * Block comments are aligned as follows:
593
                            tags.add(ti);
646
                 * - if there is some preceeding non-whitespace, do not format anything. E.g. comments after element. Skip entire comment from formatting
594
                        }
647
                 * - align 1st and last line at the appropriate indent level
595
                        break;
648
                 * - compute "shift" from the last line & indent level
596
                    }
649
                 * - shift INTERIOR of the comment by the computed shift
597
                    case PI_END: {
650
                 * 
598
                        int l = updateIndent(false, -1, preserveWhitespace);
651
                 * This algorithm tries to preserve internal formatting of the comment
599
                        if (wasNewline && tokenInSelectionRange) {
652
                 */
600
                            // 1st item on a new line, will indent according to the opening tag
653
                case BLOCK_COMMENT: {
601
                            tags.add(new TokenIndent(false, tokenSequence.offset(), l));
654
                    int currentOffset = tokenSequence.offset();
602
                        }
655
603
                        break;
656
                    splitLines(image);
604
                    }
657
605
                    case WS: {
658
                    int lineStart = LineDocumentUtils.getLineStart(basedoc, currentOffset);
606
                            // we assume there is nothing except whitespace
659
607
                            int lastNewline = lastIndexOf(image, '\n');
660
                    if (lineStart < currentOffset && 
608
                            if (lastNewline == -1) {
661
                         LineDocumentUtils.getPreviousNonWhitespace(basedoc, currentOffset, lineStart) > -1) {
609
                                // nothing special here
662
                        // we cannot indent comment start, will not touch even the rest of the comment.
610
                                break;
611
                            }
612
                            wasNewline = true;
613
                            break;
614
                    }
615
                    case PI_CONTENT:
616
                        indentLineStart = 0;
617
                        // fall through
618
                    case TEXT: {
619
                        text(image, indentLineStart);
620
                        break;
663
                        break;
621
                    }
664
                    }
622
665
623
                    /**
666
                    int lastLineStart = LineDocumentUtils.getLineStart(basedoc, currentOffset + token.length() - 1);
624
                     * Block comments are aligned as follows:
667
                    int lastIndent = IndentUtils.lineIndent(basedoc, lastLineStart);
625
                     * - if there is some preceeding non-whitespace, do not format anything. E.g. comments after element. Skip entire comment from formatting
626
                     * - align 1st and last line at the appropriate indent level
627
                     * - compute "shift" from the last line & indent level
628
                     * - shift INTERIOR of the comment by the computed shift
629
                     * 
630
                     * This algorithm tries to preserve internal formatting of the comment
631
                     */
632
                    case BLOCK_COMMENT: {
633
                        int currentOffset = tokenSequence.offset();
634
668
635
                        splitLines(image);
669
                    // align 1st and last row here:
670
                    int baseIndent = indentLevel + spacesPerTab;
671
                    // shift the rest of lines by this offset
672
                    int indentShift = baseIndent - lastIndent;
636
673
637
                        int lineStart = Utilities.getRowStart(basedoc, currentOffset);
674
                    // how much to shift the interior of the comment
638
675
639
                        if (lineStart < currentOffset && 
676
                    for (int lno = 0; lno < lineCount; lno++) {
640
                             Utilities.getFirstNonWhiteBwd(basedoc, currentOffset, lineStart) > -1) {
677
                        // indent 1st comment line, as if it was text:
641
                            // we cannot indent comment start, will not touch even the rest of the comment.
678
                        int lineEnd = LineDocumentUtils.getLineEnd(basedoc, currentOffset);
642
                            break;
679
680
                        int desiredIndent;
681
                        if (lno == 0 || lno == lineCount -1) {
682
                            desiredIndent = baseIndent;
683
                        } else {
684
                            desiredIndent = IndentUtils.lineIndent(basedoc, currentOffset) + indentShift;
643
                        }
685
                        }
644
                        
645
                        int lastLineStart = Utilities.getRowStart(basedoc, currentOffset + token.length() - 1);
646
                        int lastIndent = IndentUtils.lineIndent(basedoc, lastLineStart);
647
686
648
                        // align 1st and last row here:
687
                        if ((currentOffset >= startOffset || currentOffset + lineSizes[lno] > endOffset) && currentOffset < endOffset) {
649
                        int baseIndent = indentLevel + spacesPerTab;
688
                            tags.add(new TokenIndent(
650
                        // shift the rest of lines by this offset
689
                                false,
651
                        int indentShift = baseIndent - lastIndent;
690
                                currentOffset, Math.max(0, desiredIndent)
691
                            ));
692
                        }
693
                        currentOffset += lineSizes[lno] + 1;
694
                    }
695
                    break;
696
                }
652
697
653
                        // how much to shift the interior of the comment
654
                        
655
                        for (int lno = 0; lno < lineCount; lno++) {
656
                            // indent 1st comment line, as if it was text:
657
                            int lineEnd = Utilities.getRowEnd(basedoc, currentOffset);
658
                            
659
                            int desiredIndent;
660
                            if (lno == 0 || lno == lineCount -1) {
661
                                desiredIndent = baseIndent;
662
                            } else {
663
                                desiredIndent = IndentUtils.lineIndent(basedoc, currentOffset) + indentShift;
664
                            }
665
                            
666
                            if ((currentOffset >= startOffset || currentOffset + lineSizes[lno] > endOffset) && currentOffset < endOffset) {
667
                                tags.add(new TokenIndent(
668
                                    false,
669
                                    currentOffset, Math.max(0, desiredIndent)
670
                                ));
671
                            }
672
                            currentOffset += lineSizes[lno] + 1;
673
                        }
674
                        break;
675
                    }
676
                        
677
698
678
                    case CDATA_SECTION: {
699
                case CDATA_SECTION: {
679
                        // always form a non-empty content
700
                    // always form a non-empty content
680
                        contentPresent = true;
701
                    contentPresent = true;
681
                        onlyTags = false;
702
                    onlyTags = false;
682
                        wasNewline = false;
683
                    }
684
                    case CHARACTER:
685
                    case OPERATOR:
686
                    case PI_TARGET:
687
                    case DECLARATION:
688
                        break; //Do nothing for above case's
689
                    case ARGUMENT: //attribute of an element
690
                        attributeName();
691
                        break;
692
                    case VALUE:
693
                        attributeValue();
694
                        break;
695
696
                    case ERROR:
697
                    case EOL:
698
                    default:
699
                        throw new IOException("Invalid token found in document: "
700
                                + "Please use the text editor to resolve the issues...");
701
                }
702
                currentTokensSize += image.length();
703
                if (tokenId != XMLTokenId.WS && tokenId != XMLTokenId.TEXT && tokenId != XMLTokenId.PI_CONTENT) {
704
                    // clear indicator of the newline
705
                    wasNewline = false;
703
                    wasNewline = false;
706
                }
704
                }
705
                case CHARACTER:
706
                case OPERATOR:
707
                case PI_TARGET:
708
                case DECLARATION:
709
                    break; //Do nothing for above case's
710
                case ARGUMENT: //attribute of an element
711
                    attributeName();
712
                    break;
713
                case VALUE:
714
                    attributeValue();
715
                    break;
716
717
                case ERROR:
718
                case EOL:
719
                default:
720
                    throw new IOException("Invalid token found in document: "
721
                            + "Please use the text editor to resolve the issues...");
707
            }
722
            }
708
        } finally {
723
            currentTokensSize += image.length();
709
            basedoc.readUnlock();
724
            if (tokenId != XMLTokenId.WS && tokenId != XMLTokenId.TEXT && tokenId != XMLTokenId.PI_CONTENT) {
725
                // clear indicator of the newline
726
                wasNewline = false;
727
            }
710
        }
728
        }
711
        return tags;
729
        return tags;
712
    }
730
    }
(-)a/xml.text/src/org/netbeans/modules/xml/text/navigator/NavigatorTreeCellRenderer.java (-6 / +6 lines)
Lines 52-58 Link Here
52
import javax.swing.tree.DefaultTreeCellRenderer;
52
import javax.swing.tree.DefaultTreeCellRenderer;
53
import javax.swing.tree.TreeCellRenderer;
53
import javax.swing.tree.TreeCellRenderer;
54
import org.netbeans.modules.editor.structure.api.DocumentElement;
54
import org.netbeans.modules.editor.structure.api.DocumentElement;
55
import org.netbeans.modules.xml.text.structure.XMLDocumentModelProvider;
55
import static org.netbeans.modules.xml.text.structure.XMLConstants.*;
56
import org.openide.awt.HtmlRenderer;
56
import org.openide.awt.HtmlRenderer;
57
import org.openide.util.ImageUtilities;
57
import org.openide.util.ImageUtilities;
58
import org.openide.util.Utilities;
58
import org.openide.util.Utilities;
Lines 100-113 Link Here
100
        
100
        
101
        boolean containsError = tna.getChildrenErrorCount() > 0;
101
        boolean containsError = tna.getChildrenErrorCount() > 0;
102
        //normal icons
102
        //normal icons
103
        if(de.getType().equals(XMLDocumentModelProvider.XML_TAG)
103
        if(de.getType().equals(XML_TAG)
104
        || de.getType().equals(XMLDocumentModelProvider.XML_EMPTY_TAG)) {
104
        || de.getType().equals(XML_EMPTY_TAG)) {
105
            setIcon(TAG_ICON, containsError);
105
            setIcon(TAG_ICON, containsError);
106
        } else if(de.getType().equals(XMLDocumentModelProvider.XML_PI)) {
106
        } else if(de.getType().equals(XML_PI)) {
107
            setIcon(PI_ICON, containsError);
107
            setIcon(PI_ICON, containsError);
108
        } else if(de.getType().equals(XMLDocumentModelProvider.XML_DOCTYPE)) {
108
        } else if(de.getType().equals(XML_DOCTYPE)) {
109
            setIcon(DOCTYPE_ICON, containsError);
109
            setIcon(DOCTYPE_ICON, containsError);
110
        } else if(de.getType().equals(XMLDocumentModelProvider.XML_CDATA)) {
110
        } else if(de.getType().equals(XML_CDATA)) {
111
            setIcon(CDATA_ICON, containsError);
111
            setIcon(CDATA_ICON, containsError);
112
        }
112
        }
113
        
113
        
(-)a/xml.text/src/org/netbeans/modules/xml/text/navigator/TreeNodeAdapter.java (-28 / +24 lines)
Lines 47-67 Link Here
47
import java.util.ArrayList;
47
import java.util.ArrayList;
48
import java.util.Collections;
48
import java.util.Collections;
49
import java.util.Enumeration;
49
import java.util.Enumeration;
50
import java.util.HashMap;
51
import java.util.Iterator;
50
import java.util.Iterator;
52
import javax.swing.JTree;
51
import javax.swing.JTree;
53
import javax.swing.text.AttributeSet;
52
import javax.swing.text.AttributeSet;
54
import javax.swing.text.BadLocationException;
53
import javax.swing.text.BadLocationException;
55
import javax.swing.text.Document;
56
import javax.swing.tree.DefaultTreeModel;
54
import javax.swing.tree.DefaultTreeModel;
57
import javax.swing.tree.TreeNode;
55
import javax.swing.tree.TreeNode;
58
import javax.swing.tree.TreePath;
56
import javax.swing.tree.TreePath;
59
import org.netbeans.editor.BaseDocument;
60
import org.netbeans.modules.editor.structure.api.DocumentElement;
57
import org.netbeans.modules.editor.structure.api.DocumentElement;
61
import org.netbeans.modules.editor.structure.api.DocumentElementEvent;
58
import org.netbeans.modules.editor.structure.api.DocumentElementEvent;
62
import org.netbeans.modules.editor.structure.api.DocumentElementListener;
59
import org.netbeans.modules.editor.structure.api.DocumentElementListener;
63
import org.netbeans.modules.xml.text.folding.XmlFoldTypes;
60
import static org.netbeans.modules.xml.text.structure.XMLConstants.*;
64
import org.netbeans.modules.xml.text.structure.XMLDocumentModelProvider;
65
import org.openide.ErrorManager;
61
import org.openide.ErrorManager;
66
62
67
/**
63
/**
Lines 181-188 Link Here
181
    }
177
    }
182
    
178
    
183
    public String getText(boolean html) {
179
    public String getText(boolean html) {
184
        if(de.getType().equals(XMLDocumentModelProvider.XML_TAG)
180
        if(de.getType().equals(XML_TAG)
185
                || de.getType().equals(XMLDocumentModelProvider.XML_EMPTY_TAG)) {
181
                || de.getType().equals(XML_EMPTY_TAG)) {
186
            //XML TAG text
182
            //XML TAG text
187
            String attribsVisibleText = "";
183
            String attribsVisibleText = "";
188
            AttributeSet attribs = getDocumentElement().getAttributes();
184
            AttributeSet attribs = getDocumentElement().getAttributes();
Lines 220-236 Link Here
220
            
216
            
221
            return text.toString();
217
            return text.toString();
222
            
218
            
223
        } else if(de.getType().equals(XMLDocumentModelProvider.XML_PI)) {
219
        } else if(de.getType().equals(XML_PI)) {
224
            //PI text
220
            //PI text
225
            String documentText = getPIText();
221
            String documentText = getPIText();
226
            documentText = documentText.length() > TEXT_MAX_LEN ? documentText.substring(0,TEXT_MAX_LEN) + "..." : documentText;
222
            documentText = documentText.length() > TEXT_MAX_LEN ? documentText.substring(0,TEXT_MAX_LEN) + "..." : documentText;
227
            return documentText;
223
            return documentText;
228
        } else if(de.getType().equals(XMLDocumentModelProvider.XML_DOCTYPE)) {
224
        } else if(de.getType().equals(XML_DOCTYPE)) {
229
            //limit the text length
225
            //limit the text length
230
            String documentText = getDoctypeText();
226
            String documentText = getDoctypeText();
231
            String visibleText  = documentText.length() > TEXT_MAX_LEN ? documentText.substring(0,TEXT_MAX_LEN) + "..." : documentText;
227
            String visibleText  = documentText.length() > TEXT_MAX_LEN ? documentText.substring(0,TEXT_MAX_LEN) + "..." : documentText;
232
            return visibleText;
228
            return visibleText;
233
        } else if(de.getType().equals(XMLDocumentModelProvider.XML_CDATA)) {
229
        } else if(de.getType().equals(XML_CDATA)) {
234
            //limit the text length
230
            //limit the text length
235
            String documentText = getCDATAText();
231
            String documentText = getCDATAText();
236
            String visibleText  = documentText.length() > TEXT_MAX_LEN ? documentText.substring(0,TEXT_MAX_LEN) + "..." : documentText;
232
            String visibleText  = documentText.length() > TEXT_MAX_LEN ? documentText.substring(0,TEXT_MAX_LEN) + "..." : documentText;
Lines 241-254 Link Here
241
    }
237
    }
242
    
238
    
243
    public String getToolTipText() {
239
    public String getToolTipText() {
244
        if(de.getType().equals(XMLDocumentModelProvider.XML_TAG)
240
        if(de.getType().equals(XML_TAG)
245
                || de.getType().equals(XMLDocumentModelProvider.XML_EMPTY_TAG)) {
241
                || de.getType().equals(XML_EMPTY_TAG)) {
246
            return getAttribsText() + " " + getDocumentContent();
242
            return getAttribsText() + " " + getDocumentContent();
247
        } else if(de.getType().equals(XMLDocumentModelProvider.XML_PI)) {
243
        } else if(de.getType().equals(XML_PI)) {
248
            return getPIText();
244
            return getPIText();
249
        } else if(de.getType().equals(XMLDocumentModelProvider.XML_DOCTYPE)) {
245
        } else if(de.getType().equals(XML_DOCTYPE)) {
250
            return getDoctypeText();
246
            return getDoctypeText();
251
        } else if(de.getType().equals(XMLDocumentModelProvider.XML_CDATA)) {
247
        } else if(de.getType().equals(XML_CDATA)) {
252
            return getCDATAText();
248
            return getCDATAText();
253
        }
249
        }
254
        return "";
250
        return "";
Lines 323-337 Link Here
323
        DocumentElement ade = e.getChangedChild();
319
        DocumentElement ade = e.getChangedChild();
324
        
320
        
325
        if(debug) System.out.println(">>> +EVENT called on " + hashCode() + " - " + de + ": element " + ade + " is going to be added");
321
        if(debug) System.out.println(">>> +EVENT called on " + hashCode() + " - " + de + ": element " + ade + " is going to be added");
326
        if(ade.getType().equals(XMLDocumentModelProvider.XML_CONTENT)) {
322
        if(ade.getType().equals(XML_CONTENT)) {
327
            //create a text node listener
323
            //create a text node listener
328
            textElements.add(new TextElementWrapper(ade));
324
            textElements.add(new TextElementWrapper(ade));
329
            //update text text content of the node
325
            //update text text content of the node
330
            childTextElementChanged();
326
            childTextElementChanged();
331
        } else if(ade.getType().equals(XMLDocumentModelProvider.XML_ERROR)) {
327
        } else if(ade.getType().equals(XML_ERROR)) {
332
            //handle error element
328
            //handle error element
333
            markNodeAsError(this);
329
            markNodeAsError(this);
334
        } else if(ade.getType().equals(XMLDocumentModelProvider.XML_COMMENT)) {
330
        } else if(ade.getType().equals(XML_COMMENT)) {
335
            //do nothing for comments
331
            //do nothing for comments
336
        } else {
332
        } else {
337
            TreeNode tn = new TreeNodeAdapter(ade, tm, tree, this);
333
            TreeNode tn = new TreeNodeAdapter(ade, tm, tree, this);
Lines 416-424 Link Here
416
            if(child.equals(de)) return index;
412
            if(child.equals(de)) return index;
417
            
413
            
418
            //skip text and error tokens
414
            //skip text and error tokens
419
            if(!child.getType().equals(XMLDocumentModelProvider.XML_CONTENT)
415
            if(!child.getType().equals(XML_CONTENT)
420
                    && !child.getType().equals(XMLDocumentModelProvider.XML_ERROR)
416
                    && !child.getType().equals(XML_ERROR)
421
                    && !child.getType().equals(XMLDocumentModelProvider.XML_COMMENT)) index++;
417
                    && !child.getType().equals(XML_COMMENT)) index++;
422
        }
418
        }
423
        return -1;
419
        return -1;
424
    }
420
    }
Lines 428-434 Link Here
428
        
424
        
429
        if(debug) System.out.println(">>> -EVENT on " + hashCode() + " - " + de + ": element " + rde + " is going to be removed ");
425
        if(debug) System.out.println(">>> -EVENT on " + hashCode() + " - " + de + ": element " + rde + " is going to be removed ");
430
        
426
        
431
        if(rde.getType().equals(XMLDocumentModelProvider.XML_CONTENT)) {
427
        if(rde.getType().equals(XML_CONTENT)) {
432
            if(debug) System.out.println(">>> removing CONTENT element");
428
            if(debug) System.out.println(">>> removing CONTENT element");
433
            //remove the text eleemnt listener
429
            //remove the text eleemnt listener
434
            Iterator i = textElements.iterator();
430
            Iterator i = textElements.iterator();
Lines 440-448 Link Here
440
            textElements.removeAll(toRemove);
436
            textElements.removeAll(toRemove);
441
            //update text text content of the node
437
            //update text text content of the node
442
            childTextElementChanged();
438
            childTextElementChanged();
443
        } else if(rde.getType().equals(XMLDocumentModelProvider.XML_ERROR)) {
439
        } else if(rde.getType().equals(XML_ERROR)) {
444
            unmarkNodeAsError(this);
440
            unmarkNodeAsError(this);
445
        } else if(rde.getType().equals(XMLDocumentModelProvider.XML_COMMENT)) {
441
        } else if(rde.getType().equals(XML_COMMENT)) {
446
            //do nothing for comments
442
            //do nothing for comments
447
        } else {
443
        } else {
448
            if(debug) System.out.println(">>> removing tag element");
444
            if(debug) System.out.println(">>> removing tag element");
Lines 494-506 Link Here
494
            boolean textElementAdded = false;
490
            boolean textElementAdded = false;
495
            while(i.hasNext()) {
491
            while(i.hasNext()) {
496
                DocumentElement chde = (DocumentElement)i.next();
492
                DocumentElement chde = (DocumentElement)i.next();
497
                if(chde.getType().equals(XMLDocumentModelProvider.XML_CONTENT)) {
493
                if(chde.getType().equals(XML_CONTENT)) {
498
                    //create a text node listener
494
                    //create a text node listener
499
                    textElements.add(new TextElementWrapper(chde));
495
                    textElements.add(new TextElementWrapper(chde));
500
                    textElementAdded = true;
496
                    textElementAdded = true;
501
                } else if(chde.getType().equals(XMLDocumentModelProvider.XML_ERROR)) {
497
                } else if(chde.getType().equals(XML_ERROR)) {
502
                    markNodeAsError(this);
498
                    markNodeAsError(this);
503
                } else if(chde.getType().equals(XMLDocumentModelProvider.XML_COMMENT)) {
499
                } else if(chde.getType().equals(XML_COMMENT)) {
504
                    //do nothing for comments
500
                    //do nothing for comments
505
                } else {
501
                } else {
506
                    //add the adapter only when there isn't any
502
                    //add the adapter only when there isn't any
Lines 529-535 Link Here
529
            //System.out.println("childTextElementChanged(): " + getDocumentElement() + " has these children:");
525
            //System.out.println("childTextElementChanged(): " + getDocumentElement() + " has these children:");
530
            while(children.hasNext()) {
526
            while(children.hasNext()) {
531
                DocumentElement del = (DocumentElement)children.next();
527
                DocumentElement del = (DocumentElement)children.next();
532
                if(del.getType().equals(XMLDocumentModelProvider.XML_CONTENT)) {
528
                if(del.getType().equals(XML_CONTENT)) {
533
                    try {
529
                    try {
534
                        //the endoffset if increased by +1 due to still not yet resolved issue with element boundaries
530
                        //the endoffset if increased by +1 due to still not yet resolved issue with element boundaries
535
                        //should be removed once it is properly fixed. On the other hand the issue has no user impact now.
531
                        //should be removed once it is properly fixed. On the other hand the issue has no user impact now.
(-)a/xml.text/src/org/netbeans/modules/xml/text/resources/DTDEditor-preferences.xml (-1 lines)
Lines 46-52 Link Here
46
<!DOCTYPE editor-preferences PUBLIC "-//NetBeans//DTD Editor Preferences 1.0//EN" "http://www.netbeans.org/dtds/EditorPreferences-1_0.dtd">
46
<!DOCTYPE editor-preferences PUBLIC "-//NetBeans//DTD Editor Preferences 1.0//EN" "http://www.netbeans.org/dtds/EditorPreferences-1_0.dtd">
47
47
48
<editor-preferences>
48
<editor-preferences>
49
    <entry name="token-context-list" value="org.netbeans.modules.xml.text.ComplexValueSettingsFactory.getDTDTokenContext" javaType="methodvalue" />
50
    <entry name="indentEngine" value="org.netbeans.modules.xml.text.ComplexValueSettingsFactory.getDTDIndentEngine" javaType="methodvalue" />
49
    <entry name="indentEngine" value="org.netbeans.modules.xml.text.ComplexValueSettingsFactory.getDTDIndentEngine" javaType="methodvalue" />
51
    <entry name="abbrev-reset-acceptor" value="org.netbeans.modules.xml.text.ComplexValueSettingsFactory.getDTDAbbrevResetAcceptor" javaType="methodvalue" />
50
    <entry name="abbrev-reset-acceptor" value="org.netbeans.modules.xml.text.ComplexValueSettingsFactory.getDTDAbbrevResetAcceptor" javaType="methodvalue" />
52
</editor-preferences>
51
</editor-preferences>
(-)a/xml.text/src/org/netbeans/modules/xml/text/resources/XMLEditor-preferences.xml (-1 lines)
Lines 47-53 Link Here
47
47
48
<editor-preferences>
48
<editor-preferences>
49
    <entry name="code-folding-enable" value="true" javaType="java.lang.Boolean" />
49
    <entry name="code-folding-enable" value="true" javaType="java.lang.Boolean" />
50
    <entry name="token-context-list" value="org.netbeans.modules.xml.text.ComplexValueSettingsFactory.getXMLTokenContext" javaType="methodvalue" />
51
    <entry name="indentEngine" value="org.netbeans.modules.xml.text.ComplexValueSettingsFactory.getXMLIndentEngine" javaType="methodvalue" />
50
    <entry name="indentEngine" value="org.netbeans.modules.xml.text.ComplexValueSettingsFactory.getXMLIndentEngine" javaType="methodvalue" />
52
    <entry name="identifier-acceptor" value="org.netbeans.modules.xml.text.ComplexValueSettingsFactory.getXMLIdentifierAcceptor" javaType="methodvalue" />
51
    <entry name="identifier-acceptor" value="org.netbeans.modules.xml.text.ComplexValueSettingsFactory.getXMLIdentifierAcceptor" javaType="methodvalue" />
53
    <entry name="abbrev-reset-acceptor" value="org.netbeans.modules.xml.text.ComplexValueSettingsFactory.getXMLAbbrevResetAcceptor" javaType="methodvalue" />
52
    <entry name="abbrev-reset-acceptor" value="org.netbeans.modules.xml.text.ComplexValueSettingsFactory.getXMLAbbrevResetAcceptor" javaType="methodvalue" />
(-)a/xml.text/src/org/netbeans/modules/xml/text/structure/XMLConstants.java (+58 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2016 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 2016 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.xml.text.structure;
43
44
/**
45
 *
46
 * @author sdedic
47
 */
48
public class XMLConstants {
49
    public static final String XML_TAG = "tag";
50
    public static final String XML_EMPTY_TAG = "empty_tag";
51
    public static final String XML_CONTENT = "content";
52
    public static final String XML_PI = "pi";
53
    public static final String XML_CDATA = "cdata";
54
    public static final String XML_DOCTYPE = "doctype";
55
    public static final String XML_COMMENT = "comment";
56
    
57
    public static final String XML_ERROR = "error";
58
}
(-)a/xml.text/src/org/netbeans/modules/xml/text/structure/XMLDocumentModelProvider.java (-239 / +261 lines)
Lines 56-63 Link Here
56
import java.util.TreeSet;
56
import java.util.TreeSet;
57
import javax.swing.text.AttributeSet;
57
import javax.swing.text.AttributeSet;
58
import javax.swing.text.BadLocationException;
58
import javax.swing.text.BadLocationException;
59
import org.netbeans.api.lexer.Token;
60
import org.netbeans.api.lexer.TokenSequence;
61
import org.netbeans.api.xml.lexer.XMLTokenId;
59
import org.netbeans.editor.BaseDocument;
62
import org.netbeans.editor.BaseDocument;
60
import org.netbeans.editor.TokenItem;
61
import org.netbeans.modules.editor.structure.api.DocumentElement;
63
import org.netbeans.modules.editor.structure.api.DocumentElement;
62
import org.netbeans.modules.editor.structure.api.DocumentModel;
64
import org.netbeans.modules.editor.structure.api.DocumentModel;
63
import org.netbeans.modules.editor.structure.api.DocumentModel.DocumentChange;
65
import org.netbeans.modules.editor.structure.api.DocumentModel.DocumentChange;
Lines 65-84 Link Here
65
import org.netbeans.modules.editor.structure.api.DocumentModelException;
67
import org.netbeans.modules.editor.structure.api.DocumentModelException;
66
import org.netbeans.modules.editor.structure.api.DocumentModelUtils;
68
import org.netbeans.modules.editor.structure.api.DocumentModelUtils;
67
import org.netbeans.modules.editor.structure.spi.DocumentModelProvider;
69
import org.netbeans.modules.editor.structure.spi.DocumentModelProvider;
68
import org.netbeans.modules.xml.text.syntax.SyntaxElement;
70
import org.netbeans.modules.xml.text.api.dom.SyntaxElement;
69
import org.netbeans.modules.xml.text.syntax.XMLSyntaxSupport;
71
import org.netbeans.modules.xml.text.api.dom.XMLSyntaxSupport;
70
import org.netbeans.modules.xml.text.syntax.XMLTokenIDs;
71
import org.netbeans.modules.xml.text.syntax.dom.AttrImpl;
72
import org.netbeans.modules.xml.text.syntax.dom.CDATASectionImpl;
73
import org.netbeans.modules.xml.text.syntax.dom.CommentImpl;
74
import org.netbeans.modules.xml.text.syntax.dom.DocumentTypeImpl;
75
import org.netbeans.modules.xml.text.syntax.dom.EmptyTag;
76
import org.netbeans.modules.xml.text.syntax.dom.EndTag;
77
import org.netbeans.modules.xml.text.syntax.dom.ProcessingInstructionImpl;
78
import org.netbeans.modules.xml.text.syntax.dom.StartTag;
79
import org.netbeans.modules.xml.text.syntax.dom.Tag;
80
import org.openide.ErrorManager;
72
import org.openide.ErrorManager;
81
73
74
import static org.netbeans.modules.xml.text.structure.XMLConstants.*;
75
import org.w3c.dom.Attr;
76
import org.w3c.dom.DocumentType;
77
import org.w3c.dom.Node;
78
import org.w3c.dom.ProcessingInstruction;
82
79
83
/**
80
/**
84
 *
81
 *
Lines 96-264 Link Here
96
        if(debug) System.out.println("\n\n\n\n\n");
93
        if(debug) System.out.println("\n\n\n\n\n");
97
        if(debug) DocumentModelUtils.dumpElementStructure(model.getRootElement());
94
        if(debug) DocumentModelUtils.dumpElementStructure(model.getRootElement());
98
        
95
        
96
        XMLSyntaxSupport sup = XMLSyntaxSupport.getSyntaxSupport(model.getDocument());
97
        if (sup == null) {
98
            return;
99
        }
99
        ArrayList regenerate = new ArrayList(); //used to store elements to be regenerated
100
        ArrayList regenerate = new ArrayList(); //used to store elements to be regenerated
100
        
101
        
101
        for(int i = 0; i < changes.length; i++) {
102
        for(int i = 0; i < changes.length; i++) {
102
            DocumentChange dch = changes[i];
103
            DocumentChange dch = changes[i];
104
            int changeOffset = dch.getChangeStart().getOffset();
105
            Exception[] thrown = new Exception[1];
103
            
106
            
104
            int changeOffset = dch.getChangeStart().getOffset();
105
            int changeLength = dch.getChangeLength();
106
            
107
            //find an element in which the change happened
108
            DocumentElement leaf = model.getLeafElementForOffset(changeOffset);
109
            DocumentElement toRegenerate = leaf;
110
            
111
            if(debug) System.out.println("");
112
            if(debug) System.out.println(dch);
113
            try {
107
            try {
114
                if(debug) System.out.println("inserted text:'" + model.getDocument().getText(changeOffset, changeLength) + "'");
108
                sup.runWithSequence(changeOffset,
115
            }catch(BadLocationException e) {
109
                        (TokenSequence s) -> {
116
                ;
110
                            try {
117
            }
111
                                updateModelLocked(sup, regenerate, dtm, model, dch, s);
118
            if(debug) System.out.println("leaf = " + leaf);
112
                            } catch (DocumentModelException | DocumentModelTransactionCancelledException ex) {
119
            
113
                                thrown[0] = ex;
120
            //parse the document context
114
                            }
121
            XMLSyntaxSupport sup = (XMLSyntaxSupport)((BaseDocument)model.getDocument()).getSyntaxSupport();
115
                            return null;
122
            
116
                        }
123
            boolean textOnly = false;
117
                );
124
            boolean attribsOnly = false;
118
                if (thrown[0] != null) {
125
            try {
119
                    if (thrown[0] instanceof DocumentModelException) {
126
                //scan the inserted text - if it contains only text set textOnly flag
120
                        throw (DocumentModelException)thrown[0];
127
                TokenItem ti = sup.getTokenChain(changeOffset, changeOffset + 1);
128
                while(ti != null && ti.getOffset() < (changeOffset + changeLength)) {
129
                    if(ti.getTokenID() == XMLTokenIDs.TEXT
130
                            || ti.getTokenID() == XMLTokenIDs.DECLARATION
131
                            || ti.getTokenID() == XMLTokenIDs.BLOCK_COMMENT
132
                            || ti.getTokenID() == XMLTokenIDs.PI_CONTENT
133
                            || ti.getTokenID() == XMLTokenIDs.CDATA_SECTION) {
134
                        textOnly = true;
135
                        break;
136
                    }
121
                    }
137
                    if(ti.getTokenID() == XMLTokenIDs.ARGUMENT
122
                    if (thrown[0] instanceof DocumentModelTransactionCancelledException) {
138
                            || ti.getTokenID() == XMLTokenIDs.OPERATOR
123
                        throw (DocumentModelTransactionCancelledException)thrown[0];
139
                            || ti.getTokenID() == XMLTokenIDs.VALUE) {
140
                        attribsOnly = true;
141
                        break;
142
                    }
143
                    ti = ti.getNext();
144
                }
145
            }catch(BadLocationException e) {
146
                ErrorManager.getDefault().notify(ErrorManager.WARNING, e);
147
            }
148
            
149
            if(textOnly &&
150
                    ( leaf.getType().equals(XML_CONTENT)
151
                    || leaf.getType().equals(XML_DOCTYPE)
152
                    || leaf.getType().equals(XML_PI)
153
                    || leaf.getType().equals(XML_COMMENT)
154
                    || leaf.getType().equals(XML_CDATA))){
155
                //just a text written into a text element simply fire document element change event and do not regenerate anything
156
                //add the element update request into transaction
157
                if(debug) System.out.println("ONLY CONTENT UPDATE!!!");
158
                dtm.updateDocumentElementText(leaf);
159
                
160
                //do not scan the context tag if the change is only insert or remove of one character into a text (typing text perf. optimalization)
161
                if(dch.getChangeLength() == 1) {
162
                    continue;
163
                }
164
            }
165
            
166
            if((attribsOnly || dch.getChangeType() == DocumentChange.REMOVE)
167
                    && (leaf.getType().equals(XML_TAG)
168
                    || leaf.getType().equals(XML_EMPTY_TAG))) {
169
                if(debug) System.out.println("POSSIBLE ATTRIBS UPDATE!!!");
170
                //we need to parse the tag element attributes and set them according to the new values
171
                try {
172
                    SyntaxElement sel = sup.getElementChain(leaf.getStartOffset() + 1);
173
                    if(sel instanceof Tag || sel instanceof EmptyTag) {
174
                        //test whether the attributes changed
175
                        Map newAttrs = createAttributesMap((Tag)sel);
176
                        AttributeSet existing = leaf.getAttributes();
177
                        boolean update = false;
178
                        if(existing.getAttributeCount() == newAttrs.size()) {
179
                            Iterator itr = newAttrs.keySet().iterator();
180
                            while (itr.hasNext()) {
181
                                String attrName = (String) itr.next();
182
                                String attrValue = (String)newAttrs.get(attrName);
183
                                if(attrName != null && attrValue != null
184
                                        && !existing.containsAttribute(attrName, attrValue)) {
185
                                    update = true;
186
                                    break;
187
                                }
188
                                
189
                            }
190
                        } else update = true;
191
                        
192
                        if(update) {
193
                            dtm.updateDocumentElementAttribs(leaf, newAttrs);
194
                        }
195
                    }
196
                }catch(BadLocationException ble) {
197
                    ErrorManager.getDefault().notify(ErrorManager.WARNING, ble);
198
                }
199
            }
200
            
201
            //if one or more elements are deleted get correct paret to regenerate
202
            if((leaf.getStartOffset() == leaf.getEndOffset())
203
                    || (changeOffset == leaf.getStartOffset())
204
                    || (changeOffset == leaf.getEndOffset()))
205
                toRegenerate = leaf.getParentElement();
206
            else {
207
                //user written a tag or something what is not a text
208
                //we need to get the element's parent. Simple leaf.getParent() is not enought
209
                //since when an element is deleted then a wrong parent can be choosen
210
                if(leaf.getType().equals(XML_CONTENT)) {
211
                    do {
212
                        toRegenerate = toRegenerate.getParentElement();
213
                    } while(toRegenerate != null && toRegenerate.getType().equals(XML_CONTENT));
214
                    
215
                    if(toRegenerate == null) {
216
                        //no suitable parent found - the element is either a root or doesn't have any xml_tag ancestor => use root
217
                        toRegenerate = model.getRootElement();
218
                    }
124
                    }
219
                }
125
                }
126
            } catch (BadLocationException ex) {
220
            }
127
            }
221
            
128
        }
222
            if(toRegenerate == null) toRegenerate = model.getRootElement(); //root element is empty
223
            
224
            //now regenerate all sub-elements inside parent of the affected element
225
            
226
            //check if the element is not a descendant a one of the elements
227
            //which are going to be regenerated
228
            Iterator itr = regenerate.iterator();
229
            boolean hasAncestor = false;
230
            while(itr.hasNext()) {
231
                DocumentElement de = (DocumentElement)itr.next();
232
                if(de.equals(toRegenerate) || model.isDescendantOf(de, toRegenerate)) {
233
                    hasAncestor = true;
234
                    break;
235
                }
236
            }
237
            
238
            if(!hasAncestor) {
239
                //check whether the element is not an ancestor of one or more element
240
                //which are going to be regenerated
241
                ArrayList toRemove = new ArrayList();
242
                Iterator i2 = regenerate.iterator();
243
                while(i2.hasNext()) {
244
                    DocumentElement de = (DocumentElement)i2.next();
245
                    if(model.isDescendantOf(toRegenerate, de)) toRemove.add(de);
246
                }
247
                
248
                //now really remove the elements
249
                regenerate.removeAll(toRemove);
250
                
251
                //add the element - it will be likely regenerated in next model update
252
                regenerate.add(toRegenerate);
253
                
254
                //debug>>>
255
                if(debug) System.out.println("===================================================================");
256
                if(debug) System.out.println("change happened in " + leaf);
257
                if(debug) System.out.println("we will regenerate its parent " + toRegenerate);
258
                //<<<debug
259
            }
260
        } //end of the changes loop
261
        
262
        //update the model
129
        //update the model
263
        Iterator elementsToUpdate = regenerate.iterator();
130
        Iterator elementsToUpdate = regenerate.iterator();
264
        while(elementsToUpdate.hasNext()) {
131
        while(elementsToUpdate.hasNext()) {
Lines 267-273 Link Here
267
        }
134
        }
268
        
135
        
269
        if(measure) System.out.println("[xmlmodel] generated in " + (System.currentTimeMillis() - a));
136
        if(measure) System.out.println("[xmlmodel] generated in " + (System.currentTimeMillis() - a));
270
        
137
    }
138
    
139
    private void updateModelLocked(XMLSyntaxSupport sup, ArrayList regenerate, DocumentModel.DocumentModelModificationTransaction dtm,
140
            DocumentModel model, DocumentChange dch, TokenSequence seq)
141
            throws DocumentModelException, DocumentModelTransactionCancelledException, BadLocationException {
142
        int changeOffset = dch.getChangeStart().getOffset();
143
        int changeLength = dch.getChangeLength();
144
145
        //find an element in which the change happened
146
        DocumentElement leaf = model.getLeafElementForOffset(changeOffset);
147
        DocumentElement toRegenerate = leaf;
148
149
        if(debug) System.out.println("");
150
        if(debug) System.out.println(dch);
151
        try {
152
            if(debug) System.out.println("inserted text:'" + model.getDocument().getText(changeOffset, changeLength) + "'");
153
        }catch(BadLocationException e) {
154
            ;
155
        }
156
        if(debug) System.out.println("leaf = " + leaf);
157
158
        //parse the document context
159
        boolean textOnly = false;
160
        boolean attribsOnly = false;
161
        //scan the inserted text - if it contains only text set textOnly flag
162
        seq.move(changeOffset);
163
        W: while (seq.moveNext()) {
164
            Token<XMLTokenId>   ti = seq.token();
165
            XMLTokenId id = ti.id();
166
            switch (id) {
167
                case TEXT:
168
                case DECLARATION:
169
                case BLOCK_COMMENT:
170
                case PI_CONTENT:
171
                case CDATA_SECTION:
172
                    textOnly = true;
173
                    break W;
174
175
                case ARGUMENT:
176
                case OPERATOR:
177
                case VALUE:
178
                    attribsOnly = true;
179
                    break W;
180
            }
181
        }
182
        if(textOnly &&
183
                ( leaf.getType().equals(XML_CONTENT)
184
                || leaf.getType().equals(XML_DOCTYPE)
185
                || leaf.getType().equals(XML_PI)
186
                || leaf.getType().equals(XML_COMMENT)
187
                || leaf.getType().equals(XML_CDATA))){
188
            //just a text written into a text element simply fire document element change event and do not regenerate anything
189
            //add the element update request into transaction
190
            if(debug) System.out.println("ONLY CONTENT UPDATE!!!");
191
            dtm.updateDocumentElementText(leaf);
192
193
            //do not scan the context tag if the change is only insert or remove of one character into a text (typing text perf. optimalization)
194
            if(dch.getChangeLength() == 1) {
195
                return;
196
            }
197
        }
198
199
        if((attribsOnly || dch.getChangeType() == DocumentChange.REMOVE)
200
                && (leaf.getType().equals(XML_TAG)
201
                || leaf.getType().equals(XML_EMPTY_TAG))) {
202
            if(debug) System.out.println("POSSIBLE ATTRIBS UPDATE!!!");
203
            //we need to parse the tag element attributes and set them according to the new values
204
            try {
205
                SyntaxElement sel = sup.getElementChain(leaf.getStartOffset() + 1);
206
                if (sup.isStartTag(sel) || sup.isEmptyTag(sel)) {
207
                    //test whether the attributes changed
208
                    Map newAttrs = createAttributesMap(sel.getNode());
209
                    AttributeSet existing = leaf.getAttributes();
210
                    boolean update = false;
211
                    if(existing.getAttributeCount() == newAttrs.size()) {
212
                        Iterator itr = newAttrs.keySet().iterator();
213
                        while (itr.hasNext()) {
214
                            String attrName = (String) itr.next();
215
                            String attrValue = (String)newAttrs.get(attrName);
216
                            if(attrName != null && attrValue != null
217
                                    && !existing.containsAttribute(attrName, attrValue)) {
218
                                update = true;
219
                                break;
220
                            }
221
222
                        }
223
                    } else update = true;
224
225
                    if(update) {
226
                        dtm.updateDocumentElementAttribs(leaf, newAttrs);
227
                    }
228
                }
229
            }catch(BadLocationException ble) {
230
                ErrorManager.getDefault().notify(ErrorManager.WARNING, ble);
231
            }
232
        }
233
234
        //if one or more elements are deleted get correct paret to regenerate
235
        if((leaf.getStartOffset() == leaf.getEndOffset())
236
                || (changeOffset == leaf.getStartOffset())
237
                || (changeOffset == leaf.getEndOffset()))
238
            toRegenerate = leaf.getParentElement();
239
        else {
240
            //user written a tag or something what is not a text
241
            //we need to get the element's parent. Simple leaf.getParent() is not enought
242
            //since when an element is deleted then a wrong parent can be choosen
243
            if(leaf.getType().equals(XML_CONTENT)) {
244
                do {
245
                    toRegenerate = toRegenerate.getParentElement();
246
                } while(toRegenerate != null && toRegenerate.getType().equals(XML_CONTENT));
247
248
                if(toRegenerate == null) {
249
                    //no suitable parent found - the element is either a root or doesn't have any xml_tag ancestor => use root
250
                    toRegenerate = model.getRootElement();
251
                }
252
            }
253
        }
254
255
        if(toRegenerate == null) toRegenerate = model.getRootElement(); //root element is empty
256
257
        //now regenerate all sub-elements inside parent of the affected element
258
259
        //check if the element is not a descendant a one of the elements
260
        //which are going to be regenerated
261
        Iterator itr = regenerate.iterator();
262
        boolean hasAncestor = false;
263
        while(itr.hasNext()) {
264
            DocumentElement de = (DocumentElement)itr.next();
265
            if(de.equals(toRegenerate) || model.isDescendantOf(de, toRegenerate)) {
266
                hasAncestor = true;
267
                break;
268
            }
269
        }
270
271
        if(!hasAncestor) {
272
            //check whether the element is not an ancestor of one or more element
273
            //which are going to be regenerated
274
            ArrayList toRemove = new ArrayList();
275
            Iterator i2 = regenerate.iterator();
276
            while(i2.hasNext()) {
277
                DocumentElement de = (DocumentElement)i2.next();
278
                if(model.isDescendantOf(toRegenerate, de)) toRemove.add(de);
279
            }
280
281
            //now really remove the elements
282
            regenerate.removeAll(toRemove);
283
284
            //add the element - it will be likely regenerated in next model update
285
            regenerate.add(toRegenerate);
286
287
            //debug>>>
288
            if(debug) System.out.println("===================================================================");
289
            if(debug) System.out.println("change happened in " + leaf);
290
            if(debug) System.out.println("we will regenerate its parent " + toRegenerate);
291
            //<<<debug
292
        }
271
    }
293
    }
272
    
294
    
273
    /** generates document elements within an area defined by startoffset and
295
    /** generates document elements within an area defined by startoffset and
Lines 279-292 Link Here
279
        int endOffset = de.getEndOffset();
301
        int endOffset = de.getEndOffset();
280
        
302
        
281
        BaseDocument doc = (BaseDocument)model.getDocument();
303
        BaseDocument doc = (BaseDocument)model.getDocument();
282
        XMLSyntaxSupport sup = new XMLSyntaxSupport(doc);
304
        XMLSyntaxSupport sup = XMLSyntaxSupport.createSyntaxSupport(doc);
283
        
305
        
284
        if(debug) System.out.println("[XMLDocumentModelProvider] regenerating " + de);
306
        if(debug) System.out.println("[XMLDocumentModelProvider] regenerating " + de);
285
        
307
        
286
        Set addedElements = new TreeSet(DocumentModel.ELEMENTS_COMPARATOR);
308
        Set addedElements = new TreeSet(DocumentModel.ELEMENTS_COMPARATOR);
287
        ArrayList skipped = new ArrayList();
309
        ArrayList skipped = new ArrayList();
288
        try {
310
        try {
289
            Stack elementsStack = new Stack(); //we need this to determine tags nesting
311
            Stack<SyntaxElement> elementsStack = new Stack<>(); //we need this to determine tags nesting
290
            
312
            
291
            //the syntax element is created for token on offset - 1
313
            //the syntax element is created for token on offset - 1
292
            //so I need to add 1 to the startOffset
314
            //so I need to add 1 to the startOffset
Lines 294-300 Link Here
294
            
316
            
295
            //scan the document for syntax elements - from startOffset to endOffset
317
            //scan the document for syntax elements - from startOffset to endOffset
296
            while(sel != null && getSyntaxElementEndOffset(sel) <= endOffset) {
318
            while(sel != null && getSyntaxElementEndOffset(sel) <= endOffset) {
297
                if(sel instanceof SyntaxElement.Error) {
319
                if(sel.getType() == SyntaxElement.NODE_ERROR) {
298
                    //add error element into the structure
320
                    //add error element into the structure
299
                    if(debug) System.out.println("Error found! => adding error element.");
321
                    if(debug) System.out.println("Error found! => adding error element.");
300
                    String errorText = doc.getText(sel.getElementOffset(), sel.getElementLength());
322
                    String errorText = doc.getText(sel.getElementOffset(), sel.getElementLength());
Lines 313-328 Link Here
313
                            from, to));
335
                            from, to));
314
                }
336
                }
315
                
337
                
316
                if(sel instanceof StartTag) {
338
                if(sup.isStartTag(sel)) {
317
                    //test if there is already an existing documet element in the model
339
                    //test if there is already an existing documet element in the model
318
                    StartTag stag = (StartTag)sel;
340
                    String nn = sel.getNode().getNodeName();
319
                    DocumentElement tagDE = DocumentModelUtils.findElement(model, sel.getElementOffset(), stag.getTagName(), XML_TAG);
341
                    DocumentElement tagDE = DocumentModelUtils.findElement(model, sel.getElementOffset(), nn, XML_TAG);
320
                    
342
                    
321
                    //do not skip the 'de' element which is to be regenerated
343
                    //do not skip the 'de' element which is to be regenerated
322
                    if(tagDE != null && !tagDE.equals(de)) {
344
                    if(tagDE != null && !tagDE.equals(de)) {
323
                        //test if the element has also correct end tag
345
                        //test if the element has also correct end tag
324
                        SyntaxElement endTagCheck = sup.getElementChain(Math.min(doc.getLength(), tagDE.getEndOffset() + 1));
346
                        SyntaxElement endTagCheck = sup.getElementChain(Math.min(doc.getLength(), tagDE.getEndOffset() + 1));
325
                        if(endTagCheck instanceof EndTag && ((EndTag)endTagCheck).getTagName().equals(stag.getTagName())) {
347
                        if(sup.isEndTag(endTagCheck) && endTagCheck.getNode().getNodeName().equals(nn)) {
326
                            //there is an element - skip it - analyze an element after the end of the
348
                            //there is an element - skip it - analyze an element after the end of the
327
                            //existing element
349
                            //existing element
328
                            if(debug) System.out.println("found existing element " + tagDE + " => skipping");
350
                            if(debug) System.out.println("found existing element " + tagDE + " => skipping");
Lines 336-348 Link Here
336
                    //add the tag syntax element into stack
358
                    //add the tag syntax element into stack
337
                    elementsStack.push(sel);
359
                    elementsStack.push(sel);
338
                    
360
                    
339
                } else if(sel instanceof EndTag) {
361
                } else if (sup.isEndTag(sel)) {
340
                    if(!elementsStack.isEmpty()) {
362
                    if(!elementsStack.isEmpty()) {
341
                        StartTag latest = (StartTag)elementsStack.peek();
363
                        SyntaxElement latest = elementsStack.peek();
342
                        if(((EndTag)sel).getTagName().equals(latest.getTagName())) {
364
                        String nn = latest.getNode().getNodeName();
365
                        if((sel.getNode().getNodeName().equals(nn))) {
343
                            //we have encountered a pair end tag to open tag on the peek of the stack
366
                            //we have encountered a pair end tag to open tag on the peek of the stack
344
                            Map attribs = createAttributesMap(latest);
367
                            Map attribs = createAttributesMap(latest.getNode());
345
                            addedElements.add(dtm.addDocumentElement(latest.getTagName(), XML_TAG, attribs,
368
                            addedElements.add(dtm.addDocumentElement(nn, XML_TAG, attribs,
346
                                    latest.getElementOffset(), getSyntaxElementEndOffset(sel)));
369
                                    latest.getElementOffset(), getSyntaxElementEndOffset(sel)));
347
                            //remove the open tag syntax element from the stack
370
                            //remove the open tag syntax element from the stack
348
                            elementsStack.pop();
371
                            elementsStack.pop();
Lines 352-358 Link Here
352
                            
375
                            
353
                            //I need to save the pop-ed elements for the case that there isn't
376
                            //I need to save the pop-ed elements for the case that there isn't
354
                            //any matching start tag found
377
                            //any matching start tag found
355
                            ArrayList savedElements = new ArrayList();
378
                            ArrayList<SyntaxElement> savedElements = new ArrayList<>();
356
                            //this semaphore is used behind the loop to detect whether a
379
                            //this semaphore is used behind the loop to detect whether a
357
                            //matching start has been found
380
                            //matching start has been found
358
                            boolean foundStartTag = false;
381
                            boolean foundStartTag = false;
Lines 361-375 Link Here
361
                                SyntaxElement s = (SyntaxElement)elementsStack.pop();
384
                                SyntaxElement s = (SyntaxElement)elementsStack.pop();
362
                                savedElements.add(s);
385
                                savedElements.add(s);
363
                                
386
                                
364
                                Tag start = (Tag)s;
387
                                int soff = s.getElementOffset();
365
                                Tag end = (Tag)sel;
388
                                String sn = s.getNode().getNodeName();
389
                                String en = s.getNode().getNodeName();
366
                                
390
                                
367
                                if(s instanceof StartTag && start.getTagName().equals(end.getTagName())) {
391
                                if(sup.isStartTag(s) && sn.equals(en)) {
368
                                    //found a matching start tag
392
                                    //found a matching start tag
369
                                    //XXX I am not sure whether this algorith is correct
393
                                    //XXX I am not sure whether this algorith is correct
370
                                    Map attribs = createAttributesMap((StartTag)s);
394
                                    Map attribs = createAttributesMap(s.getNode());
371
                                    addedElements.add(dtm.addDocumentElement(start.getTagName(), XML_TAG, attribs,
395
                                    addedElements.add(dtm.addDocumentElement(sn, XML_TAG, attribs,
372
                                            start.getElementOffset(), getSyntaxElementEndOffset(end)));
396
                                            soff, getSyntaxElementEndOffset(sel)));
373
                                    
397
                                    
374
                                    foundStartTag = true;
398
                                    foundStartTag = true;
375
                                    break; //break the while loop
399
                                    break; //break the while loop
Lines 385-433 Link Here
385
                            }
409
                            }
386
                        }
410
                        }
387
                    }
411
                    }
388
                } else if(sel instanceof EmptyTag) {
412
                } else if(sup.isEmptyTag(sel)) {
389
                    Map attribs = createAttributesMap((Tag)sel);
413
                    Map attribs = createAttributesMap(sel.getNode());
390
                    addedElements.add(dtm.addDocumentElement(((EmptyTag)sel).getTagName(), XML_EMPTY_TAG, attribs,
414
                    addedElements.add(dtm.addDocumentElement(sel.getNode().getNodeName(), XML_EMPTY_TAG, attribs,
391
                            sel.getElementOffset(), getSyntaxElementEndOffset(sel)));
392
                } else if (sel instanceof CDATASectionImpl) {
393
                    //CDATA section
394
                    addedElements.add(dtm.addDocumentElement("cdata", XML_CDATA, Collections.EMPTY_MAP,
395
                            sel.getElementOffset(), getSyntaxElementEndOffset(sel)));
396
                } else if (sel instanceof ProcessingInstructionImpl) {
397
                    //PI section
398
                    String nodeName = ((ProcessingInstructionImpl)sel).getNodeName();
399
                    //if the nodename is not parsed, then the element is somehow broken => do not show it.
400
                    if(nodeName != null) {
401
                        addedElements.add(dtm.addDocumentElement(nodeName, XML_PI, Collections.EMPTY_MAP,
402
                                sel.getElementOffset(), getSyntaxElementEndOffset(sel)));
403
                    }
404
                } else if (sel instanceof DocumentTypeImpl) {
405
                    //document type <!DOCTYPE xxx [...]>
406
                    String nodeName = ((DocumentTypeImpl)sel).getName();
407
                    //if the nodename is not parsed, then the element is somehow broken => do not show it.
408
                    if(nodeName != null) {
409
                        addedElements.add(dtm.addDocumentElement(nodeName, XML_DOCTYPE, Collections.EMPTY_MAP,
410
                                sel.getElementOffset(), getSyntaxElementEndOffset(sel)));
411
                    }
412
                } else if (sel instanceof CommentImpl) {
413
                    //comment element <!-- xxx -->
414
                    //DO NOT CREATE ELEMENT FOR COMMENTS
415
                    addedElements.add(dtm.addDocumentElement("comment", XML_COMMENT, Collections.EMPTY_MAP,
416
                            sel.getElementOffset(), getSyntaxElementEndOffset(sel)));
415
                            sel.getElementOffset(), getSyntaxElementEndOffset(sel)));
417
                } else {
416
                } else {
418
                    //everything else is content
417
                    switch (sel.getType()) {
419
                    int from = sel.getElementOffset();
418
                        case Node.CDATA_SECTION_NODE:
420
                    // because of changeset #1d6a31161c70, all elements report end at the last char, but that is not
419
                            addedElements.add(dtm.addDocumentElement("cdata", XML_CDATA, Collections.EMPTY_MAP,
421
                    // what is expected from the DocumentElement.
420
                                    sel.getElementOffset(), getSyntaxElementEndOffset(sel)));
422
                    int to = getSyntaxElementEndOffset(sel) + 1;
421
                            break;
423
                    if(from < to) {
422
                        case Node.PROCESSING_INSTRUCTION_NODE: {
424
                        //Do not allow empty elements to be added:
423
                            //PI section
425
                        //Otherwise it causes problems in DocumentModel.ELEMENTS_COMPARATOR
424
                            String nodeName = ((ProcessingInstruction)sel.getNode()).getNodeName();
426
                        //(idential elements are considered as unequal (the reason why this
425
                            //if the nodename is not parsed, then the element is somehow broken => do not show it.
427
                        //required is distinguishing elements after text deletion) and subsequently
426
                            if(nodeName != null) {
428
                        //the empty elements are added and removed all over again after each model
427
                                addedElements.add(dtm.addDocumentElement(nodeName, XML_PI, Collections.EMPTY_MAP,
429
                        //update which causes performance problems.
428
                                        sel.getElementOffset(), getSyntaxElementEndOffset(sel)));
430
                        addedElements.add(dtm.addDocumentElement("...", XML_CONTENT, Collections.EMPTY_MAP, from, to));
429
                            }
430
                            break;
431
                        }
432
                        case Node.DOCUMENT_TYPE_NODE: {
433
                            //document type <!DOCTYPE xxx [...]>
434
                            String nodeName = ((DocumentType)sel.getNode()).getName();
435
                            //if the nodename is not parsed, then the element is somehow broken => do not show it.
436
                            if(nodeName != null) {
437
                                addedElements.add(dtm.addDocumentElement(nodeName, XML_DOCTYPE, Collections.EMPTY_MAP,
438
                                        sel.getElementOffset(), getSyntaxElementEndOffset(sel)));
439
                            }
440
                            break;
441
                        }
442
                        case Node.COMMENT_NODE:
443
                            //comment element <!-- xxx -->
444
                            //DO NOT CREATE ELEMENT FOR COMMENTS
445
                            addedElements.add(dtm.addDocumentElement("comment", XML_COMMENT, Collections.EMPTY_MAP,
446
                                    sel.getElementOffset(), getSyntaxElementEndOffset(sel)));
447
                            break;
448
                        default:
449
                            //everything else is content
450
                            int from = sel.getElementOffset();
451
                            // because of changeset #1d6a31161c70, all elements report end at the last char, but that is not
452
                            // what is expected from the DocumentElement.
453
                            int to = getSyntaxElementEndOffset(sel) + 1;
454
                            if(from < to) {
455
                                //Do not allow empty elements to be added:
456
                                //Otherwise it causes problems in DocumentModel.ELEMENTS_COMPARATOR
457
                                //(idential elements are considered as unequal (the reason why this
458
                                //required is distinguishing elements after text deletion) and subsequently
459
                                //the empty elements are added and removed all over again after each model
460
                                //update which causes performance problems.
461
                                addedElements.add(dtm.addDocumentElement("...", XML_CONTENT, Collections.EMPTY_MAP, from, to));
462
                            }
431
                    }
463
                    }
432
                }
464
                }
433
                //find next syntax element
465
                //find next syntax element
Lines 499-527 Link Here
499
        return sel.getElementOffset() + sel.getElementLength() -1;
531
        return sel.getElementOffset() + sel.getElementLength() -1;
500
    }
532
    }
501
    
533
    
502
    private Map createAttributesMap(Tag tag) {
534
    private Map createAttributesMap(Node tag) {
503
        if(tag.getAttributes().getLength() == 0) {
535
        if(tag.getAttributes().getLength() == 0) {
504
            return Collections.EMPTY_MAP;
536
            return Collections.EMPTY_MAP;
505
        } else {
537
        } else {
506
            HashMap map = new LinkedHashMap(tag.getAttributes().getLength());
538
            HashMap map = new LinkedHashMap(tag.getAttributes().getLength());
507
            for(int i = 0; i < tag.getAttributes().getLength(); i++) {
539
            for(int i = 0; i < tag.getAttributes().getLength(); i++) {
508
                AttrImpl attr = (AttrImpl)tag.getAttributes().item(i);
540
                Attr attr = (Attr)tag.getAttributes().item(i);
509
                map.put(attr.getName(), attr.getValue());
541
                map.put(attr.getName(), attr.getValue());
510
            }
542
            }
511
            return map;
543
            return map;
512
        }
544
        }
513
    }
545
    }
514
    
546
    
515
    public static final String XML_TAG = "tag";
516
    public static final String XML_EMPTY_TAG = "empty_tag";
517
    public static final String XML_CONTENT = "content";
518
    public static final String XML_PI = "pi";
519
    public static final String XML_CDATA = "cdata";
520
    public static final String XML_DOCTYPE = "doctype";
521
    public static final String XML_COMMENT = "comment";
522
    
523
    public static final String XML_ERROR = "error";
524
    
525
    
547
    
526
    private static final boolean debug = Boolean.getBoolean("org.netbeans.modules.xml.text.structure.debug");
548
    private static final boolean debug = Boolean.getBoolean("org.netbeans.modules.xml.text.structure.debug");
527
    private static final boolean measure = Boolean.getBoolean("org.netbeans.modules.xml.text.structure.measure");
549
    private static final boolean measure = Boolean.getBoolean("org.netbeans.modules.xml.text.structure.measure");
(-)a/xml.text/src/org/netbeans/modules/xml/text/syntax/DTDKit.java (-11 / +3 lines)
Lines 44-50 Link Here
44
package org.netbeans.modules.xml.text.syntax;
44
package org.netbeans.modules.xml.text.syntax;
45
45
46
import javax.swing.text.Document;
46
import javax.swing.text.Document;
47
import org.netbeans.api.editor.mimelookup.MimeLookup;
48
import org.netbeans.api.editor.mimelookup.MimePath;
47
import org.netbeans.editor.Syntax;
49
import org.netbeans.editor.Syntax;
50
import org.netbeans.modules.xml.text.syntax.bridge.LegacySyntaxBridge;
48
import org.netbeans.modules.xml.text.syntax.javacc.lib.*;
51
import org.netbeans.modules.xml.text.syntax.javacc.lib.*;
49
import org.netbeans.modules.xml.text.syntax.javacc.*;
52
import org.netbeans.modules.xml.text.syntax.javacc.*;
50
53
Lines 70-88 Link Here
70
     */
73
     */
71
    public static final String MIME_TYPE = "application/xml-dtd"; // NOI18N
74
    public static final String MIME_TYPE = "application/xml-dtd"; // NOI18N
72
    
75
    
73
    /** Create new instance of syntax coloring parser */
74
    @Override
75
    public Syntax createSyntax(Document doc) {
76
        return new JJEditorSyntax( 
77
            new DTDSyntaxTokenManager(null).new Bridge(),
78
            new DTDSyntaxTokenMapper(),
79
            DTDTokenContext.contextPath
80
        );
81
    }
82
83
    @Override
76
    @Override
84
    public String getContentType() {
77
    public String getContentType() {
85
        return MIME_TYPE;
78
        return MIME_TYPE;
86
    }
79
    }
87
88
}
80
}
(-)a/xml.text/src/org/netbeans/modules/xml/text/syntax/ENTKit.java (-18 lines)
Lines 42-52 Link Here
42
42
43
package org.netbeans.modules.xml.text.syntax;
43
package org.netbeans.modules.xml.text.syntax;
44
44
45
import javax.swing.text.Document;
46
import org.netbeans.editor.BaseDocument;
47
import org.netbeans.editor.Syntax;
48
import org.netbeans.editor.SyntaxSupport;
49
50
/**
45
/**
51
 *
46
 *
52
 * @author samaresh
47
 * @author samaresh
Lines 61-81 Link Here
61
     */
56
     */
62
    public static final String MIME_TYPE = "text/xml-external-parsed-entity"; // NOI18N
57
    public static final String MIME_TYPE = "text/xml-external-parsed-entity"; // NOI18N
63
    
58
    
64
    /** Create new instance of syntax coloring parser */
65
    @Override
66
    public Syntax createSyntax(Document doc) {
67
        return new XMLDefaultSyntax();
68
    }
69
70
    @Override
59
    @Override
71
    public String getContentType() {
60
    public String getContentType() {
72
        return MIME_TYPE;
61
        return MIME_TYPE;
73
    }
62
    }
74
75
    /** Create syntax support */
76
    @Override
77
    public SyntaxSupport createSyntaxSupport(BaseDocument doc) {
78
        return new XMLSyntaxSupport(doc);
79
    }
80
    
81
}
63
}
(-)a/xml.text/src/org/netbeans/modules/xml/text/syntax/UniKit.java (+26 lines)
Lines 47-55 Link Here
47
47
48
import javax.swing.text.Document;
48
import javax.swing.text.Document;
49
import javax.swing.text.BadLocationException;
49
import javax.swing.text.BadLocationException;
50
import org.netbeans.api.editor.mimelookup.MimeLookup;
51
import org.netbeans.editor.BaseDocument;
52
import org.netbeans.editor.Syntax;
53
import org.netbeans.editor.SyntaxSupport;
50
54
51
import org.netbeans.modules.editor.NbEditorKit;
55
import org.netbeans.modules.editor.NbEditorKit;
52
import org.netbeans.modules.xml.api.EncodingUtil;
56
import org.netbeans.modules.xml.api.EncodingUtil;
57
import org.netbeans.modules.xml.text.syntax.bridge.LegacySyntaxBridge;
53
58
54
/**
59
/**
55
 * Editor kit implementation for xml content type.
60
 * Editor kit implementation for xml content type.
Lines 112-115 Link Here
112
        super.write(out, doc, pos, len);
117
        super.write(out, doc, pos, len);
113
    }
118
    }
114
119
120
    @Override
121
    public Syntax createSyntax(Document doc) {
122
        Syntax syn = null;
123
        LegacySyntaxBridge bridge = MimeLookup.getLookup(getContentType()).lookup(LegacySyntaxBridge.class);
124
        if (bridge != null) {
125
            syn = bridge.createSyntax(this, doc, getContentType());
126
        }
127
        return syn != null ? syn : super.createSyntax(doc);
128
    }
129
130
    /** Create syntax support */
131
    @Override
132
    public SyntaxSupport createSyntaxSupport(BaseDocument doc) {
133
        SyntaxSupport syn = null;
134
        LegacySyntaxBridge bridge = MimeLookup.getLookup(getContentType()).lookup(LegacySyntaxBridge.class);
135
        if (bridge != null) {
136
            syn = bridge.createSyntaxSupport(this, doc, getContentType());
137
        }
138
        return syn != null ? syn : super.createSyntaxSupport(doc);
139
    }
140
    
115
}
141
}
(-)a/xml.text/src/org/netbeans/modules/xml/text/syntax/XMLKit.java (-3 / +15 lines)
Lines 54-59 Link Here
54
import javax.swing.text.JTextComponent;
54
import javax.swing.text.JTextComponent;
55
import javax.swing.text.BadLocationException;
55
import javax.swing.text.BadLocationException;
56
import javax.swing.*;
56
import javax.swing.*;
57
import org.netbeans.api.editor.mimelookup.MimeLookup;
57
import org.netbeans.api.lexer.Language;
58
import org.netbeans.api.lexer.Language;
58
import org.netbeans.api.xml.lexer.XMLTokenId;
59
import org.netbeans.api.xml.lexer.XMLTokenId;
59
import org.openide.awt.StatusDisplayer;
60
import org.openide.awt.StatusDisplayer;
Lines 65-70 Link Here
65
66
66
import org.netbeans.modules.xml.text.XmlCommentHandler;
67
import org.netbeans.modules.xml.text.XmlCommentHandler;
67
import org.netbeans.modules.xml.text.completion.NodeSelector;
68
import org.netbeans.modules.xml.text.completion.NodeSelector;
69
import static org.netbeans.modules.xml.text.syntax.DTDKit.MIME_TYPE;
70
import org.netbeans.modules.xml.text.syntax.bridge.LegacySyntaxBridge;
68
71
69
72
70
/**
73
/**
Lines 106-112 Link Here
106
    /** Create new instance of syntax coloring parser */
109
    /** Create new instance of syntax coloring parser */
107
    @Override
110
    @Override
108
    public Syntax createSyntax(Document doc) {
111
    public Syntax createSyntax(Document doc) {
109
        return new XMLDefaultSyntax();
112
        Syntax syn = null;
113
        LegacySyntaxBridge bridge = MimeLookup.getLookup(MIME_TYPE).lookup(LegacySyntaxBridge.class);
114
        if (bridge != null) {
115
            syn = bridge.createSyntax(this, doc, MIME_TYPE);
116
        }
117
        return syn != null ? syn : super.createSyntax(doc);
110
    }
118
    }
111
119
112
    @Override
120
    @Override
Lines 120-130 Link Here
120
        }
128
        }
121
    }
129
    }
122
130
123
124
    /** Create syntax support */
131
    /** Create syntax support */
125
    @Override
132
    @Override
126
    public SyntaxSupport createSyntaxSupport(BaseDocument doc) {
133
    public SyntaxSupport createSyntaxSupport(BaseDocument doc) {
127
        return new XMLSyntaxSupport(doc);
134
        SyntaxSupport syn = null;
135
        LegacySyntaxBridge bridge = MimeLookup.getLookup(MIME_TYPE).lookup(LegacySyntaxBridge.class);
136
        if (bridge != null) {
137
            syn = bridge.createSyntaxSupport(this, doc, MIME_TYPE);
138
        }
139
        return syn != null ? syn : super.createSyntaxSupport(doc);
128
    }
140
    }
129
    
141
    
130
    @Override
142
    @Override
(-)a/xml.text/src/org/netbeans/modules/xml/text/syntax/bridge/LegacySyntaxBridge.java (+59 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2016 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 2016 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.xml.text.syntax.bridge;
43
44
import javax.swing.text.Document;
45
import javax.swing.text.EditorKit;
46
import org.netbeans.editor.Syntax;
47
import org.netbeans.editor.SyntaxSupport;
48
49
/**
50
 * Transitional interface, which keeps old Syntax-related classes in a 
51
 * obsolete/deprecated module. Not intended to be implemented by regular clients.
52
 * Implementations should be registered in MIME Lookup for the particular MIME type.
53
 * 
54
 * @author sdedic
55
 */
56
public interface LegacySyntaxBridge {
57
    public Syntax          createSyntax(EditorKit host, Document doc, String mimeType);
58
    public SyntaxSupport   createSyntaxSupport(EditorKit host, Document doc, String mimeType);
59
}
(-)a/xml.text/test/unit/src/org/netbeans/modules/xml/text/AbstractTestCase.java (-4 / +4 lines)
Lines 52-64 Link Here
52
import org.netbeans.api.lexer.Language;
52
import org.netbeans.api.lexer.Language;
53
import org.netbeans.api.xml.lexer.XMLTokenId;
53
import org.netbeans.api.xml.lexer.XMLTokenId;
54
import org.netbeans.editor.BaseDocument;
54
import org.netbeans.editor.BaseDocument;
55
import org.netbeans.modules.xml.text.syntax.XMLSyntaxSupport;
55
import org.netbeans.junit.NbTestCase;
56
import org.netbeans.modules.xml.text.api.dom.XMLSyntaxSupport;
56
import org.netbeans.modules.xml.xam.ModelSource;
57
import org.netbeans.modules.xml.xam.ModelSource;
57
import org.netbeans.modules.xml.xdm.XDMModel;
58
import org.netbeans.modules.xml.xdm.XDMModel;
58
import org.netbeans.modules.xml.xdm.diff.DefaultElementIdentity;
59
import org.netbeans.modules.xml.xdm.diff.DefaultElementIdentity;
59
import org.netbeans.modules.xml.xdm.diff.DiffFinder;
60
import org.netbeans.modules.xml.xdm.diff.DiffFinder;
60
import org.netbeans.modules.xml.xdm.diff.Difference;
61
import org.netbeans.modules.xml.xdm.diff.Difference;
61
import org.openide.util.Exceptions;
62
import org.openide.util.Lookup;
62
import org.openide.util.Lookup;
63
import org.openide.util.lookup.Lookups;
63
import org.openide.util.lookup.Lookups;
64
64
Lines 67-73 Link Here
67
 * Various tests include, sanity, regression, performance etc.
67
 * Various tests include, sanity, regression, performance etc.
68
 * @author Samaresh (samaresh.panda@sun.com)
68
 * @author Samaresh (samaresh.panda@sun.com)
69
 */
69
 */
70
public class AbstractTestCase extends TestCase {
70
public class AbstractTestCase extends NbTestCase {
71
    
71
    
72
    public AbstractTestCase(String testName) {
72
    public AbstractTestCase(String testName) {
73
        super(testName);
73
        super(testName);
Lines 131-137 Link Here
131
        BaseDocument doc = getResourceAsDocument(path);
131
        BaseDocument doc = getResourceAsDocument(path);
132
        //must set the language inside unit tests
132
        //must set the language inside unit tests
133
        doc.putProperty(Language.class, XMLTokenId.language());
133
        doc.putProperty(Language.class, XMLTokenId.language());
134
        return ((XMLSyntaxSupport)doc.getSyntaxSupport());
134
        return XMLSyntaxSupport.getSyntaxSupport(doc);
135
    }
135
    }
136
136
137
    /**
137
    /**
(-)a/xml.text/test/unit/src/org/netbeans/modules/xml/text/dom/XMLSyntaxSupportTest.java (+2 lines)
Lines 42-52 Link Here
42
42
43
package org.netbeans.modules.xml.text.dom;
43
package org.netbeans.modules.xml.text.dom;
44
44
45
import org.netbeans.modules.xml.text.api.dom.XMLSyntaxSupport;
45
import junit.framework.Test;
46
import junit.framework.Test;
46
import junit.framework.TestSuite;
47
import junit.framework.TestSuite;
47
import org.netbeans.api.lexer.Token;
48
import org.netbeans.api.lexer.Token;
48
import org.netbeans.editor.BaseDocument;
49
import org.netbeans.editor.BaseDocument;
49
import org.netbeans.modules.xml.text.AbstractTestCase;
50
import org.netbeans.modules.xml.text.AbstractTestCase;
51
import org.netbeans.modules.xml.text.api.dom.SyntaxElement;
50
52
51
/**
53
/**
52
 *
54
 *
(-)a/xml.text/test/unit/src/org/netbeans/modules/xml/text/indent/XMLLexerFormatterTest.java (-49 / +50 lines)
Lines 43-48 Link Here
43
43
44
import org.netbeans.modules.xml.text.AbstractTestCase;
44
import org.netbeans.modules.xml.text.AbstractTestCase;
45
import junit.framework.*;
45
import junit.framework.*;
46
import org.netbeans.api.editor.document.LineDocument;
46
import org.netbeans.editor.BaseDocument;
47
import org.netbeans.editor.BaseDocument;
47
48
48
/**
49
/**
Lines 81-103 Link Here
81
     * with a document that represents expected outcome.
82
     * with a document that represents expected outcome.
82
     */
83
     */
83
    public void testFormat() throws Exception {
84
    public void testFormat() throws Exception {
84
        BaseDocument inputDoc = getDocument("indent/input.xml");
85
        LineDocument inputDoc = getDocument("indent/input.xml");
85
        //format the inputDoc
86
        //format the inputDoc
86
        XMLLexerFormatter formatter = new XMLLexerFormatter(null);
87
        XMLLexerFormatter formatter = new XMLLexerFormatter(null);
87
        BaseDocument formattedDoc = formatter.doReformat(inputDoc, 0, inputDoc.getLength());
88
        LineDocument formattedDoc = formatter.doReformat(inputDoc, 0, inputDoc.getLength());
88
        System.out.println(formattedDoc.getText(0, formattedDoc.getLength()));
89
        System.out.println(formattedDoc.getText(0, formattedDoc.getLength()));
89
        BaseDocument outputDoc = getDocument("indent/output.xml");
90
        LineDocument outputDoc = getDocument("indent/output.xml");
90
        assert (compare(formattedDoc, outputDoc));
91
        assertTrue (compare(formattedDoc, outputDoc));
91
    }
92
    }
92
93
93
    public void testFormatSubsection() throws Exception {
94
    public void testFormatSubsection() throws Exception {
94
        BaseDocument inputDoc = getDocument("indent/input_sub.xml");
95
        BaseDocument inputDoc = getDocument("indent/input_sub.xml");
95
        //format a subsection of the inputDoc
96
        //format a subsection of the inputDoc
96
        XMLLexerFormatter formatter = new XMLLexerFormatter(null);
97
        XMLLexerFormatter formatter = new XMLLexerFormatter(null);
97
        BaseDocument formattedDoc = formatter.doReformat(inputDoc, 72, 97);
98
        LineDocument formattedDoc = formatter.doReformat(inputDoc, 72, 97);
98
        System.out.println(formattedDoc.getText(0, formattedDoc.getLength()));
99
        System.out.println(formattedDoc.getText(0, formattedDoc.getLength()));
99
        BaseDocument outputDoc = getDocument("indent/output_sub.xml");
100
        LineDocument outputDoc = getDocument("indent/output_sub.xml");
100
        assert (compare(formattedDoc, outputDoc));
101
        assertTrue (compare(formattedDoc, outputDoc));
101
    }
102
    }
102
103
103
    // #139160
104
    // #139160
Lines 105-114 Link Here
105
        BaseDocument inputDoc = getDocument("indent/input2.xsd");
106
        BaseDocument inputDoc = getDocument("indent/input2.xsd");
106
        //format the inputDoc
107
        //format the inputDoc
107
        XMLLexerFormatter formatter = new XMLLexerFormatter(null);
108
        XMLLexerFormatter formatter = new XMLLexerFormatter(null);
108
        BaseDocument formattedDoc = formatter.doReformat(inputDoc, 0, inputDoc.getLength());
109
        LineDocument formattedDoc = formatter.doReformat(inputDoc, 0, inputDoc.getLength());
109
        System.out.println(formattedDoc.getText(0, formattedDoc.getLength()));
110
        System.out.println(formattedDoc.getText(0, formattedDoc.getLength()));
110
        BaseDocument outputDoc = getDocument("indent/output2.xsd");
111
        LineDocument outputDoc = getDocument("indent/output2.xsd");
111
        assert (compare(formattedDoc, outputDoc));
112
        assertTrue (compare(formattedDoc, outputDoc));
112
    }
113
    }
113
114
114
    public void testFormatPerformance() throws Exception {
115
    public void testFormatPerformance() throws Exception {
Lines 134-153 Link Here
134
        BaseDocument inputDoc = getDocument("indent/input_sub1.xml");
135
        BaseDocument inputDoc = getDocument("indent/input_sub1.xml");
135
        //format a subsection of the inputDoc
136
        //format a subsection of the inputDoc
136
        XMLLexerFormatter formatter = new XMLLexerFormatter(null);
137
        XMLLexerFormatter formatter = new XMLLexerFormatter(null);
137
        BaseDocument formattedDoc = formatter.doReformat(inputDoc, 46, 74);
138
        LineDocument formattedDoc = formatter.doReformat(inputDoc, 46, 74);
138
        System.out.println(formattedDoc.getText(0, formattedDoc.getLength()));
139
        System.out.println(formattedDoc.getText(0, formattedDoc.getLength()));
139
        BaseDocument outputDoc = getDocument("indent/output_sub1.xml");
140
        LineDocument outputDoc = getDocument("indent/output_sub1.xml");
140
        assert (compare(formattedDoc, outputDoc));
141
        assertTrue (compare(formattedDoc, outputDoc));
141
    }
142
    }
142
143
143
    public void testFormatSubsection2() throws Exception {
144
    public void testFormatSubsection2() throws Exception {
144
        BaseDocument inputDoc = getDocument("indent/input_sub2.xml");
145
        BaseDocument inputDoc = getDocument("indent/input_sub2.xml");
145
        //format a subsection of the inputDoc
146
        //format a subsection of the inputDoc
146
        XMLLexerFormatter formatter = new XMLLexerFormatter(null);
147
        XMLLexerFormatter formatter = new XMLLexerFormatter(null);
147
        BaseDocument formattedDoc = formatter.doReformat(inputDoc, 63, 80);
148
        LineDocument formattedDoc = formatter.doReformat(inputDoc, 63, 80);
148
        System.out.println(formattedDoc.getText(0, formattedDoc.getLength()));
149
        System.out.println(formattedDoc.getText(0, formattedDoc.getLength()));
149
        BaseDocument outputDoc = getDocument("indent/output_sub2.xml");
150
        LineDocument outputDoc = getDocument("indent/output_sub2.xml");
150
        assert (compare(formattedDoc, outputDoc));
151
        assertTrue (compare(formattedDoc, outputDoc));
151
    }
152
    }
152
153
153
    // #170343
154
    // #170343
Lines 155-164 Link Here
155
        BaseDocument inputDoc = getDocument("indent/input_preserve.xml");
156
        BaseDocument inputDoc = getDocument("indent/input_preserve.xml");
156
        //format the inputDoc
157
        //format the inputDoc
157
        XMLLexerFormatter formatter = new XMLLexerFormatter(null);
158
        XMLLexerFormatter formatter = new XMLLexerFormatter(null);
158
        BaseDocument formattedDoc = formatter.doReformat(inputDoc, 0, inputDoc.getLength());
159
        LineDocument formattedDoc = formatter.doReformat(inputDoc, 0, inputDoc.getLength());
159
        System.out.println(formattedDoc.getText(0, formattedDoc.getLength()));
160
        System.out.println(formattedDoc.getText(0, formattedDoc.getLength()));
160
        BaseDocument outputDoc = getDocument("indent/output_preserve.xml");
161
        LineDocument outputDoc = getDocument("indent/output_preserve.xml");
161
        assert (compare(formattedDoc, outputDoc));
162
        assertTrue (compare(formattedDoc, outputDoc));
162
    }
163
    }
163
164
164
    // #170343
165
    // #170343
Lines 166-175 Link Here
166
        BaseDocument inputDoc = getDocument("indent/input_withpreserve.xml");
167
        BaseDocument inputDoc = getDocument("indent/input_withpreserve.xml");
167
        //format the inputDoc
168
        //format the inputDoc
168
        XMLLexerFormatter formatter = new XMLLexerFormatter(null);
169
        XMLLexerFormatter formatter = new XMLLexerFormatter(null);
169
        BaseDocument formattedDoc = formatter.doReformat(inputDoc, 0, inputDoc.getLength());
170
        LineDocument formattedDoc = formatter.doReformat(inputDoc, 0, inputDoc.getLength());
170
        System.out.println(formattedDoc.getText(0, formattedDoc.getLength()));
171
        System.out.println(formattedDoc.getText(0, formattedDoc.getLength()));
171
        BaseDocument outputDoc = getDocument("indent/output_withpreserve.xml");
172
        LineDocument outputDoc = getDocument("indent/output_withpreserve.xml");
172
        assert (compare(formattedDoc, outputDoc));
173
        assertTrue (compare(formattedDoc, outputDoc));
173
    }
174
    }
174
175
175
    // #170343
176
    // #170343
Lines 178-187 Link Here
178
        //format the inputDoc
179
        //format the inputDoc
179
        XMLLexerFormatter formatter = new XMLLexerFormatter(null);
180
        XMLLexerFormatter formatter = new XMLLexerFormatter(null);
180
        System.out.println("SECTION:" + inputDoc.getText(91, 87));
181
        System.out.println("SECTION:" + inputDoc.getText(91, 87));
181
        BaseDocument formattedDoc = formatter.doReformat(inputDoc, 91, 91 + 87);
182
        LineDocument formattedDoc = formatter.doReformat(inputDoc, 91, 91 + 87);
182
        System.out.println(formattedDoc.getText(0, formattedDoc.getLength()));
183
        System.out.println(formattedDoc.getText(0, formattedDoc.getLength()));
183
        BaseDocument outputDoc = getDocument("indent/output_preserve.xml");
184
        LineDocument outputDoc = getDocument("indent/output_preserve.xml");
184
        assert (compare(formattedDoc, outputDoc));
185
        assertTrue(compare(formattedDoc, outputDoc));
185
    }
186
    }
186
187
187
188
Lines 189-218 Link Here
189
        BaseDocument inputDoc = getDocument("indent/input_contentIndent.xml");
190
        BaseDocument inputDoc = getDocument("indent/input_contentIndent.xml");
190
        //format the inputDoc
191
        //format the inputDoc
191
        XMLLexerFormatter formatter = new XMLLexerFormatter(null);
192
        XMLLexerFormatter formatter = new XMLLexerFormatter(null);
192
        BaseDocument formattedDoc = formatter.doReformat(inputDoc, 0, inputDoc.getLength());
193
        LineDocument formattedDoc = formatter.doReformat(inputDoc, 0, inputDoc.getLength());
193
        System.out.println(formattedDoc.getText(0, formattedDoc.getLength()));
194
        System.out.println(formattedDoc.getText(0, formattedDoc.getLength()));
194
        BaseDocument outputDoc = getDocument("indent/output_contentIndent.xml");
195
        LineDocument outputDoc = getDocument("indent/output_contentIndent.xml");
195
        assert (compare(formattedDoc, outputDoc));
196
        assertTrue(compare(formattedDoc, outputDoc));
196
    }
197
    }
197
198
198
    public void testFormat_AttrsIndent() throws Exception {
199
    public void testFormat_AttrsIndent() throws Exception {
199
        BaseDocument inputDoc = getDocument("indent/input_attrsIndent.xml");
200
        BaseDocument inputDoc = getDocument("indent/input_attrsIndent.xml");
200
        //format the inputDoc
201
        //format the inputDoc
201
        XMLLexerFormatter formatter = new XMLLexerFormatter(null);
202
        XMLLexerFormatter formatter = new XMLLexerFormatter(null);
202
        BaseDocument formattedDoc = formatter.doReformat(inputDoc, 0, inputDoc.getLength());
203
        LineDocument formattedDoc = formatter.doReformat(inputDoc, 0, inputDoc.getLength());
203
        System.out.println(formattedDoc.getText(0, formattedDoc.getLength()));
204
        System.out.println(formattedDoc.getText(0, formattedDoc.getLength()));
204
        BaseDocument outputDoc = getDocument("indent/output_attrsIndent.xml");
205
        LineDocument outputDoc = getDocument("indent/output_attrsIndent.xml");
205
        assert (compare(formattedDoc, outputDoc));
206
        assertTrue (compare(formattedDoc, outputDoc));
206
    }
207
    }
207
208
208
    public void testFormat_ProcessingIndent() throws Exception {
209
    public void testFormat_ProcessingIndent() throws Exception {
209
        BaseDocument inputDoc = getDocument("indent/input_processingXml.xml");
210
        BaseDocument inputDoc = getDocument("indent/input_processingXml.xml");
210
        //format the inputDoc
211
        //format the inputDoc
211
        XMLLexerFormatter formatter = new XMLLexerFormatter(null);
212
        XMLLexerFormatter formatter = new XMLLexerFormatter(null);
212
        BaseDocument formattedDoc = formatter.doReformat(inputDoc, 0, inputDoc.getLength());
213
        LineDocument formattedDoc = formatter.doReformat(inputDoc, 0, inputDoc.getLength());
213
        System.out.println(formattedDoc.getText(0, formattedDoc.getLength()));
214
        System.out.println(formattedDoc.getText(0, formattedDoc.getLength()));
214
        BaseDocument outputDoc = getDocument("indent/output_processingXml.xml");
215
        LineDocument outputDoc = getDocument("indent/output_processingXml.xml");
215
        assert (compare(formattedDoc, outputDoc));
216
        assertTrue (compare(formattedDoc, outputDoc));
216
    }
217
    }
217
    
218
    
218
    
219
    
Lines 220-268 Link Here
220
        BaseDocument inputDoc = getDocument("indent/input_nestedSame.xml");
221
        BaseDocument inputDoc = getDocument("indent/input_nestedSame.xml");
221
        //format the inputDoc
222
        //format the inputDoc
222
        XMLLexerFormatter formatter = new XMLLexerFormatter(null);
223
        XMLLexerFormatter formatter = new XMLLexerFormatter(null);
223
        BaseDocument formattedDoc = formatter.doReformat(inputDoc, 0, inputDoc.getLength());
224
        LineDocument formattedDoc = formatter.doReformat(inputDoc, 0, inputDoc.getLength());
224
        System.out.println(formattedDoc.getText(0, formattedDoc.getLength()));
225
        System.out.println(formattedDoc.getText(0, formattedDoc.getLength()));
225
        BaseDocument outputDoc = getDocument("indent/output_nestedSame.xml");
226
        LineDocument outputDoc = getDocument("indent/output_nestedSame.xml");
226
        assert (compare(formattedDoc, outputDoc));
227
        assertTrue (compare(formattedDoc, outputDoc));
227
    }
228
    }
228
    
229
    
229
    public void testFormatWithCdataContent217342() throws Exception {
230
    public void testFormatWithCdataContent217342() throws Exception {
230
        BaseDocument inputDoc = getDocument("indent/input_cdataContent.xml");
231
        BaseDocument inputDoc = getDocument("indent/input_cdataContent.xml");
231
        //format the inputDoc
232
        //format the inputDoc
232
        XMLLexerFormatter formatter = new XMLLexerFormatter(null);
233
        XMLLexerFormatter formatter = new XMLLexerFormatter(null);
233
        BaseDocument formattedDoc = formatter.doReformat(inputDoc, 0, inputDoc.getLength());
234
        LineDocument formattedDoc = formatter.doReformat(inputDoc, 0, inputDoc.getLength());
234
        System.out.println(formattedDoc.getText(0, formattedDoc.getLength()));
235
        System.out.println(formattedDoc.getText(0, formattedDoc.getLength()));
235
        BaseDocument outputDoc = getDocument("indent/output_cdataContent.xml");
236
        LineDocument outputDoc = getDocument("indent/output_cdataContent.xml");
236
        assert (compare(formattedDoc, outputDoc));
237
        assertTrue (compare(formattedDoc, outputDoc));
237
    }
238
    }
238
239
239
    public void testFormatBreaksMixedContent216986() throws Exception {
240
    public void testFormatBreaksMixedContent216986() throws Exception {
240
        BaseDocument inputDoc = getDocument("indent/input_breaksMixedContent.xml");
241
        BaseDocument inputDoc = getDocument("indent/input_breaksMixedContent.xml");
241
        //format the inputDoc
242
        //format the inputDoc
242
        XMLLexerFormatter formatter = new XMLLexerFormatter(null);
243
        XMLLexerFormatter formatter = new XMLLexerFormatter(null);
243
        BaseDocument formattedDoc = formatter.doReformat(inputDoc, 0, inputDoc.getLength());
244
        LineDocument formattedDoc = formatter.doReformat(inputDoc, 0, inputDoc.getLength());
244
        System.out.println(formattedDoc.getText(0, formattedDoc.getLength()));
245
        System.out.println(formattedDoc.getText(0, formattedDoc.getLength()));
245
        BaseDocument outputDoc = getDocument("indent/output_breaksMixedContent.xml");
246
        LineDocument outputDoc = getDocument("indent/output_breaksMixedContent.xml");
246
        assert (compare(formattedDoc, outputDoc));
247
        assertTrue (compare(formattedDoc, outputDoc));
247
    }
248
    }
248
    
249
    
249
    public void testFormatNewlinesInTags217995() throws Exception {
250
    public void testFormatNewlinesInTags217995() throws Exception {
250
        BaseDocument inputDoc = getDocument("indent/input_newlineInTags.xml");
251
        BaseDocument inputDoc = getDocument("indent/input_newlineInTags.xml");
251
        //format the inputDoc
252
        //format the inputDoc
252
        XMLLexerFormatter formatter = new XMLLexerFormatter(null);
253
        XMLLexerFormatter formatter = new XMLLexerFormatter(null);
253
        BaseDocument formattedDoc = formatter.doReformat(inputDoc, 0, inputDoc.getLength());
254
        LineDocument formattedDoc = formatter.doReformat(inputDoc, 0, inputDoc.getLength());
254
        System.out.println(formattedDoc.getText(0, formattedDoc.getLength()));
255
        System.out.println(formattedDoc.getText(0, formattedDoc.getLength()));
255
        BaseDocument outputDoc = getDocument("indent/output_newlineInTags.xml");
256
        LineDocument outputDoc = getDocument("indent/output_newlineInTags.xml");
256
        assert (compare(formattedDoc, outputDoc));
257
        assertTrue (compare(formattedDoc, outputDoc));
257
    }
258
    }
258
    
259
    
259
    public void testFormatTagAtLineStartAfterContent238985() throws Exception {
260
    public void testFormatTagAtLineStartAfterContent238985() throws Exception {
260
        BaseDocument inputDoc = getDocument("indent/input_tagAtStatOfLine.xml");
261
        BaseDocument inputDoc = getDocument("indent/input_tagAtStatOfLine.xml");
261
        //format the inputDoc
262
        //format the inputDoc
262
        XMLLexerFormatter formatter = new XMLLexerFormatter(null);
263
        XMLLexerFormatter formatter = new XMLLexerFormatter(null);
263
        BaseDocument formattedDoc = formatter.doReformat(inputDoc, 0, inputDoc.getLength());
264
        LineDocument formattedDoc = formatter.doReformat(inputDoc, 0, inputDoc.getLength());
264
        System.out.println(formattedDoc.getText(0, formattedDoc.getLength()));
265
        System.out.println(formattedDoc.getText(0, formattedDoc.getLength()));
265
        BaseDocument outputDoc = getDocument("indent/output_tagAtStatOfLine.xml");
266
        LineDocument outputDoc = getDocument("indent/output_tagAtStatOfLine.xml");
266
        assert (compare(formattedDoc, outputDoc));
267
        assertTrue (compare(formattedDoc, outputDoc));
267
    }
268
    }
268
}
269
}
(-)a/xml.text/test/unit/src/org/netbeans/modules/xml/text/syntax/XMLSyntaxSupportTest.java (-4 / +8 lines)
Lines 44-51 Link Here
44
44
45
import junit.framework.Test;
45
import junit.framework.Test;
46
import junit.framework.TestSuite;
46
import junit.framework.TestSuite;
47
import org.netbeans.api.lexer.Token;
48
import org.netbeans.api.xml.lexer.XMLTokenId;
47
import org.netbeans.editor.TokenItem;
49
import org.netbeans.editor.TokenItem;
48
import org.netbeans.modules.xml.text.AbstractTestCase;
50
import org.netbeans.modules.xml.text.AbstractTestCase;
51
import org.netbeans.modules.xml.text.api.dom.XMLSyntaxSupport;
52
import org.netbeans.modules.xml.text.api.dom.SyntaxElement;
49
53
50
/**
54
/**
51
 *
55
 *
Lines 85-95 Link Here
85
89
86
    public void testTokens() throws Exception {
90
    public void testTokens() throws Exception {
87
        XMLSyntaxSupport support = getSyntaxSupport("syntax/test.xml");
91
        XMLSyntaxSupport support = getSyntaxSupport("syntax/test.xml");
88
        TokenItem token = support.getPreviousToken(30);
92
        Token<XMLTokenId> token = support.getPreviousToken(30);
89
        System.out.println("Token: " + token.getTokenID().getName() + " Text: " + token.getImage());
93
        System.out.println("Token: " + token.id().name() + " Text: " + token.text());
90
        token = support.getPreviousToken(31);
94
        token = support.getPreviousToken(31);
91
        System.out.println("Token: " + token.getTokenID().getName() + " Text: " + token.getImage());
95
        System.out.println("Token: " + token.id().name() + " Text: " + token.text());
92
        token = support.getPreviousToken(32);
96
        token = support.getPreviousToken(32);
93
        System.out.println("Token: " + token.getTokenID().getName() + " Text: " + token.getImage());
97
        System.out.println("Token: " + token.id().name() + " Text: " + token.text());
94
    }
98
    }
95
}
99
}
(-)a/xml/manifest.mf (-1 / +1 lines)
Lines 4-7 Link Here
4
OpenIDE-Module-Install: org/netbeans/modules/xml/CoreModuleInstall.class
4
OpenIDE-Module-Install: org/netbeans/modules/xml/CoreModuleInstall.class
5
OpenIDE-Module-Layer: org/netbeans/modules/xml/resources/mf-layer.xml
5
OpenIDE-Module-Layer: org/netbeans/modules/xml/resources/mf-layer.xml
6
AutoUpdate-Show-In-Client: false
6
AutoUpdate-Show-In-Client: false
7
OpenIDE-Module-Specification-Version: 1.32
7
OpenIDE-Module-Specification-Version: 1.33
(-)a/xml/nbproject/project.xml (-1 / +1 lines)
Lines 170-176 Link Here
170
                    <compile-dependency/>
170
                    <compile-dependency/>
171
                    <run-dependency>
171
                    <run-dependency>
172
                        <release-version>2</release-version>
172
                        <release-version>2</release-version>
173
                        <specification-version>1.16</specification-version>
173
                        <specification-version>1.60</specification-version>
174
                    </run-dependency>
174
                    </run-dependency>
175
                </dependency>
175
                </dependency>
176
                <dependency>
176
                <dependency>
(-)a/xsl/manifest.mf (-1 / +1 lines)
Lines 4-7 Link Here
4
OpenIDE-Module-Layer: org/netbeans/modules/xsl/resources/mf-layer.xml
4
OpenIDE-Module-Layer: org/netbeans/modules/xsl/resources/mf-layer.xml
5
OpenIDE-Module-Requires: org.openide.util.HttpServer$Impl
5
OpenIDE-Module-Requires: org.openide.util.HttpServer$Impl
6
AutoUpdate-Show-In-Client: false
6
AutoUpdate-Show-In-Client: false
7
OpenIDE-Module-Specification-Version: 1.44
7
OpenIDE-Module-Specification-Version: 1.45
(-)a/xsl/nbproject/project.xml (-1 / +1 lines)
Lines 142-148 Link Here
142
                    <compile-dependency/>
142
                    <compile-dependency/>
143
                    <run-dependency>
143
                    <run-dependency>
144
                        <release-version>2</release-version>
144
                        <release-version>2</release-version>
145
                        <specification-version>1.16</specification-version>
145
                        <specification-version>1.60</specification-version>
146
                    </run-dependency>
146
                    </run-dependency>
147
                </dependency>
147
                </dependency>
148
                <dependency>
148
                <dependency>

Return to bug 268342