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

(-)a/xml.schema.completion/nbproject/project.xml (+1 lines)
Lines 125-130 Link Here
125
                    <compile-dependency/>
125
                    <compile-dependency/>
126
                    <run-dependency>
126
                    <run-dependency>
127
                        <release-version>1</release-version>
127
                        <release-version>1</release-version>
128
                        <specification-version>1.17</specification-version>
128
                    </run-dependency>
129
                    </run-dependency>
129
                </dependency>
130
                </dependency>
130
                <dependency>
131
                <dependency>
(-)a/xml.schema.completion/src/org/netbeans/modules/xml/schema/completion/util/CompletionUtil.java (-27 / +99 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.util.ArrayList;
47
import java.util.*;
48
import java.util.HashMap;
49
import java.util.List;
50
import java.util.Stack;
51
import java.util.StringTokenizer;
52
import java.util.logging.Level;
48
import java.util.logging.Level;
53
import java.util.logging.Logger;
49
import java.util.logging.Logger;
54
import java.util.regex.Pattern;
50
import java.util.regex.Pattern;
Lines 63-89 Link Here
63
import org.netbeans.api.lexer.TokenSequence;
59
import org.netbeans.api.lexer.TokenSequence;
64
import org.netbeans.api.xml.lexer.XMLTokenId;
60
import org.netbeans.api.xml.lexer.XMLTokenId;
65
import org.netbeans.editor.BaseDocument;
61
import org.netbeans.editor.BaseDocument;
66
import org.netbeans.modules.xml.axi.AXIComponent;
62
import org.netbeans.modules.xml.axi.*;
67
import org.netbeans.modules.xml.axi.AXIDocument;
68
import org.netbeans.modules.xml.axi.AXIModel;
69
import org.netbeans.modules.xml.axi.AXIModelFactory;
70
import org.netbeans.modules.xml.axi.AXIType;
71
import org.netbeans.modules.xml.axi.AbstractAttribute;
72
import org.netbeans.modules.xml.axi.AbstractElement;
73
import org.netbeans.modules.xml.axi.AnyAttribute;
74
import org.netbeans.modules.xml.axi.AnyElement;
75
import org.netbeans.modules.xml.axi.Attribute;
76
import org.netbeans.modules.xml.axi.Element;
77
import org.netbeans.modules.xml.axi.datatype.Datatype;
63
import org.netbeans.modules.xml.axi.datatype.Datatype;
78
import org.netbeans.modules.xml.schema.completion.*;
64
import org.netbeans.modules.xml.schema.completion.*;
79
import org.netbeans.modules.xml.schema.completion.spi.CompletionModelProvider.CompletionModel;
65
import org.netbeans.modules.xml.schema.completion.spi.CompletionModelProvider.CompletionModel;
80
import org.netbeans.modules.xml.schema.model.Form;
66
import org.netbeans.modules.xml.schema.model.Form;
67
import org.netbeans.modules.xml.schema.model.GlobalElement;
68
import org.netbeans.modules.xml.schema.model.SchemaComponent;
69
import org.netbeans.modules.xml.schema.model.SchemaModel;
70
import org.netbeans.modules.xml.schema.model.visitor.FindSubstitutions;
81
import org.openide.filesystems.FileObject;
71
import org.openide.filesystems.FileObject;
82
import org.openide.loaders.DataObject;
72
import org.openide.loaders.DataObject;
83
import org.openide.windows.TopComponent;
73
import org.openide.windows.TopComponent;
84
74
85
/**
75
/**
86
 *
76
 * Utility class containing methods to query the model for completion suggestions.
77
 * 
87
 * @author Samaresh (Samaresh.Panda@Sun.Com)
78
 * @author Samaresh (Samaresh.Panda@Sun.Com)
88
 */
79
 */
89
public class CompletionUtil {
80
public class CompletionUtil {
Lines 243-270 Link Here
243
    }
234
    }
244
    
235
    
245
    /**
236
    /**
246
     * Returns the list of child-elements for a given element.
237
     * Returns the list of child elements for a given element. This includes
238
     * all available substitutions for child elements from all 
239
     * {@link CompletionModel}s in the specified completion context. It excludes
240
     * abstract elements
241
     * @param context the completion context for which to find all valid 
242
     * elements for insertion
243
     * @return all elements appropriate to be inserted in the specified context,
244
     * or {@code null} if no parent element can be found for the specified 
245
     * context.
247
     */
246
     */
248
    public static List<CompletionResultItem> getElements(
247
    public static List<CompletionResultItem> getElements(CompletionContextImpl context) {
249
            CompletionContextImpl context) {
250
        Element element = findAXIElementAtContext(context);
248
        Element element = findAXIElementAtContext(context);
251
        if(element == null)
249
        if(element == null) {
252
            return null;
250
            return null;
251
        }
253
        
252
        
254
        List<CompletionResultItem> results = new ArrayList<CompletionResultItem>();
253
        List<CompletionResultItem> results = new ArrayList<CompletionResultItem>();
255
        for(AbstractElement ae: element.getChildElements()) {
254
        for(AbstractElement ae: element.getChildElements()) {
256
            AXIComponent original = ae.getOriginal();
255
            AXIComponent original = ae.getOriginal();
257
            if(original.getTargetNamespace() == null) {  //no namespace
256
            if(original.getTargetNamespace() == null) {  //no namespace
258
                CompletionResultItem item = createResultItem(original, null, context);
257
                CompletionResultItem item = createResultItem(original, null, context);
259
                if(item != null)
258
                if(item != null) {
260
                    results.add(item);
259
                    results.add(item);
261
                continue;
260
                }
262
            }            
261
            } else if(original instanceof AnyElement) {
263
            if(original instanceof AnyElement) {
264
                results.addAll(substituteAny((AnyElement)original, context));
262
                results.addAll(substituteAny((AnyElement)original, context));
265
                continue;
263
            } else if(original instanceof Element) {
264
                Element childElement = (Element) original;
265
                if(!childElement.getAbstract()) {
266
                    addNSAwareCompletionItems(original, context, null, results);
267
                }
268
                addSubstitutionCompletionItems(childElement, context, results);
266
            }
269
            }
267
            addNSAwareCompletionItems(original,context,null,results);
268
        }
270
        }
269
        return results;
271
        return results;
270
    }
272
    }
Lines 329-334 Link Here
329
        }
331
        }
330
        return result;
332
        return result;
331
    }    
333
    }    
334
        
335
    /**
336
     * Find all possible substitutions for the specified {@link Element} within
337
     * the specified {@link CompletionContextImpl completion context}.
338
     * @param forSubstitution the Element to find substitutions for.
339
     * @param context the context to use to find available substitutions. All
340
     * available {@link CompletionModel}s' {@link SchemaModel}s will be searched.
341
     * @param results the result set to add the results to.
342
     */
343
    private static void addSubstitutionCompletionItems(Element forSubstitution, CompletionContextImpl context, List<CompletionResultItem> results) {
344
        AXIModel model = forSubstitution.getModel();
345
        String nsUri = forSubstitution.getTargetNamespace();
346
        String localName = forSubstitution.getName();
347
        for (CompletionModel completionModel : context.getCompletionModels()) {
348
            SchemaModel schemaModel = completionModel.getSchemaModel();
349
            Set<GlobalElement> substitutions = FindSubstitutions.resolveSubstitutions(schemaModel, nsUri, localName);
350
            for (GlobalElement substitution : substitutions) {
351
                AXIComponent substitutionElement = getAxiComponent(model, substitution);
352
                addNSAwareCompletionItems(substitutionElement, context, completionModel, results);
353
            }
354
        }
355
    }
356
    
357
    
358
    /**
359
     * Finds the {@link AXIComponent} representing the specified 
360
     * {@link SchemaComponent}, from the specified {@link AXIModel}.
361
     * Modified from org.netbeans.modules.xml.axi.impl.Util.lookup(), 
362
     * org.netbeans.modules.xml.axi.impl.AXIModelImpl.lookup(), 
363
     * and org.netbeans.modules.xml.axi.impl.AXIModelImpl.lookupFromOtherModel().
364
     * @param model the model to search in to find the representation of the 
365
     * specified {@link SchemaComponent}
366
     * @param schemaComponent the {@link SchemaComponent} to search for a 
367
     * representation of
368
     * @return the AXI representation of the specified schema component, or null
369
     * if no AXI representation could be found for the schema component.
370
     */
371
    private static AXIComponent getAxiComponent(AXIModel model, SchemaComponent schemaComponent) {
372
        if(model.getSchemaModel() == schemaComponent.getModel()) {
373
            return findChild(model.getRoot(), schemaComponent);
374
        }
375
        if(!schemaComponent.isInDocumentModel()) {
376
            return null;
377
        }
378
        AXIModelFactory factory = AXIModelFactory.getDefault();
379
        AXIModel otherModel = factory.getModel(schemaComponent.getModel());
380
        return otherModel == null ? null : findChild(otherModel.getRoot(), schemaComponent);
381
    }
382
    
383
    /**
384
     * Finds an {@link AXIComponent} representation of the specified 
385
     * {@link SchemaComponent}, by searching the children of the specified
386
     * {@link AXIDocument}.
387
     * Adapted from org.netbeans.modules.xml.axi.impl.AXIDocumentImpl.findChild().
388
     * @param document the document to search through to find the representation
389
     * of the specified schema component
390
     * @param child the schema component whose representation to find in the 
391
     * specified document
392
     * @return the AXI representation of the specified schema component, from 
393
     * the specified document, or {@code null} if the schema component has no
394
     * representation in the children of the document.
395
     */
396
    private static AXIComponent findChild(AXIDocument document, SchemaComponent child) {
397
        for(AXIComponent childRepresentation : document.getChildren()) {
398
            if(childRepresentation.getPeer() == child) {
399
                return childRepresentation;
400
            }
401
        }
402
        return null;        
403
    }
332
    
404
    
333
    private static void addNSAwareCompletionItems(AXIComponent axi, 
405
    private static void addNSAwareCompletionItems(AXIComponent axi, 
334
        CompletionContextImpl context, CompletionModel cm, List<CompletionResultItem> results) {
406
        CompletionContextImpl context, CompletionModel cm, List<CompletionResultItem> results) {
(-)cec51eb4fe39 (+89 lines)
Added Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU General
10
 * Public License Version 2 only ("GPL") or the Common Development and
11
 * Distribution License("CDDL") (collectively, the "License"). You may not use
12
 * this file except in compliance with the License. You can obtain a copy of the
13
 * License at http://www.netbeans.org/cddl-gplv2.html or
14
 * nbbuild/licenses/CDDL-GPL-2-CP. See the License for the specific language
15
 * governing permissions and limitations under the License. When distributing
16
 * the software, include this License Header Notice in each file and include the
17
 * License file at nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
18
 * particular file as subject to the "Classpath" exception as provided by Oracle
19
 * in the GPL Version 2 section of the License file that accompanied this code.
20
 * If applicable, add the following below the License Header, with the fields
21
 * enclosed by brackets [] replaced by your own identifying information:
22
 * "Portions Copyrighted [year] [name of copyright owner]"
23
 *
24
 * If you wish your version of this file to be governed by only the CDDL or only
25
 * the GPL Version 2, indicate your decision by adding "[Contributor] elects to
26
 * include this software in this distribution under the [CDDL or GPL Version 2]
27
 * license." If you do not indicate a single choice of license, a recipient has
28
 * the option to distribute your version of this file under either the CDDL, the
29
 * GPL Version 2 or to extend the choice of license to its licensees as provided
30
 * above. However, if you add GPL Version 2 code and therefore, elected the GPL
31
 * Version 2 license, then the option applies only if the new code is made
32
 * subject to such option by the copyright holder.
33
 *
34
 * Contributor(s):
35
 *
36
 * Portions Copyrighted 2011 Sun Microsystems, Inc.
37
 */
38
package org.netbeans.modules.xml.schema.completion;
39
40
import java.util.List;
41
import junit.framework.Test;
42
import junit.framework.TestSuite;
43
import static org.hamcrest.CoreMatchers.not;
44
import static org.junit.Assert.assertThat;
45
46
/**
47
 * Tests for element substitution.
48
 * @author Daniel Bell (dbell@netbeans.org)
49
 */
50
public class AbstractElementTest extends AbstractTestCase {
51
52
    static final String COMPLETION_DOCUMENT = "resources/AbstractElementCompletion.xml";
53
    static final String PARENT_SCHEMA = "resources/AbstractElementParent.xsd";
54
    static final String CHILD_SCHEMA_ONE = "resources/AbstractElementChildOne.xsd";
55
    static final String CHILD_SCHEMA_TWO = "resources/AbstractElementChildTwo.xsd";
56
57
    public AbstractElementTest(String testName) {
58
        super(testName);
59
    }
60
61
    public static Test suite() {
62
        TestSuite suite = new TestSuite();
63
        suite.addTest(new AbstractElementTest("shouldNotSuggestAbstractElement"));
64
        suite.addTest(new AbstractElementTest("shouldExpandSubstitutionGroup"));
65
        return suite;
66
    }
67
    
68
    @Override
69
    public void setUp() throws Exception {
70
        setupCompletion(COMPLETION_DOCUMENT);
71
    }
72
        
73
    /**
74
     * Elements with {@code abstract="true"} should not be suggested
75
     */
76
    public void shouldNotSuggestAbstractElement() {
77
        List<CompletionResultItem> items = query(468);
78
        assertThat(items, not(containsSuggestions("child")));
79
    }
80
            
81
    /**
82
     * All available elements that can be substituted for elements in the 
83
     * completion context should be presented as completion options
84
     */
85
    public void shouldExpandSubstitutionGroup() {
86
        List<CompletionResultItem> items = query(468);
87
        assertThat(items, containsOnlySuggestions("c1:child-one", "c2:child-two"));
88
    }
89
}
(-)a/xml.schema.completion/test/unit/src/org/netbeans/modules/xml/schema/completion/AbstractTestCase.java (-5 / +72 lines)
Lines 43-50 Link Here
43
 */
43
 */
44
package org.netbeans.modules.xml.schema.completion;
44
package org.netbeans.modules.xml.schema.completion;
45
45
46
import java.util.ArrayList;
47
import java.util.Arrays;
46
import java.util.List;
48
import java.util.List;
47
import junit.framework.*;
49
import junit.framework.*;
50
import org.hamcrest.Description;
51
import org.hamcrest.Matcher;
52
import org.junit.internal.matchers.TypeSafeMatcher;
48
import org.netbeans.api.lexer.Language;
53
import org.netbeans.api.lexer.Language;
49
import org.netbeans.api.xml.lexer.XMLTokenId;
54
import org.netbeans.api.xml.lexer.XMLTokenId;
50
import org.netbeans.editor.BaseDocument;
55
import org.netbeans.editor.BaseDocument;
Lines 75-88 Link Here
75
    protected void tearDown() throws Exception {
80
    protected void tearDown() throws Exception {
76
    }
81
    }
77
    
82
    
78
    protected void setupCompletion(String path, StringBuffer buffer) throws Exception {
83
    /**
84
     * Set up the test for a particular XML document
85
     * @param path the XML document
86
     * @see #setupCompletion(java.lang.String, java.lang.StringBuffer) 
87
     */
88
    protected void setupCompletion(String path) throws Exception {
89
        setupCompletion(path, null);
90
    }
91
    
92
    
93
    /**
94
     * Set up the test for a particular XML document
95
     * @param path the XML document
96
     * @param content the content to insert into the document
97
     * @see #setupCompletion(java.lang.String)
98
     */
99
    protected void setupCompletion(String path, StringBuffer content) throws Exception {
79
        this.instanceResourcePath = path;
100
        this.instanceResourcePath = path;
80
        this.instanceFileObject = Util.getResourceAsFileObject(path);
101
        this.instanceFileObject = Util.getResourceAsFileObject(path);
81
        this.instanceDocument = Util.getResourceAsDocument(path);
102
        this.instanceDocument = Util.getResourceAsDocument(path);
82
        this.support = ((XMLSyntaxSupport)instanceDocument.getSyntaxSupport());
103
        this.support = ((XMLSyntaxSupport)instanceDocument.getSyntaxSupport());
83
        if(buffer != null) {
104
        if(content != null) {
84
            instanceDocument.remove(0, instanceDocument.getLength());
105
            instanceDocument.remove(0, instanceDocument.getLength());
85
            instanceDocument.insertString(0, buffer.toString(), null);
106
            instanceDocument.insertString(0, content.toString(), null);
86
        }
107
        }
87
        instanceDocument.putProperty(Language.class, XMLTokenId.language());        
108
        instanceDocument.putProperty(Language.class, XMLTokenId.language());        
88
    }
109
    }
Lines 90-104 Link Here
90
    /**
111
    /**
91
     * Queries and returns a list of completion items.
112
     * Queries and returns a list of completion items.
92
     * Each unit test is supposed to evaluate this result.
113
     * Each unit test is supposed to evaluate this result.
114
     * @param caretOffset the caret offset at which code completion is invoked
115
     * @return the code completion results 
93
     */
116
     */
94
    protected List<CompletionResultItem> query(int caretOffset) throws Exception {
117
    protected List<CompletionResultItem> query(int caretOffset) {
95
        assert(instanceFileObject  != null && instanceDocument != null);
118
        assert(instanceFileObject  != null && instanceDocument != null);
96
        CompletionQuery instance = new CompletionQuery(instanceFileObject);
119
        CompletionQuery instance = new CompletionQuery(instanceFileObject);
97
        return instance.getCompletionItems(instanceDocument, caretOffset);
120
        return instance.getCompletionItems(instanceDocument, caretOffset);
98
    }
121
    }
99
    
122
    
100
    protected void assertResult(List<CompletionResultItem> result,
123
    protected void assertResult(List<CompletionResultItem> result,
101
            String[] expectedResult) {
124
            String... expectedResult) {
102
        if(result == null && expectedResult == null) {
125
        if(result == null && expectedResult == null) {
103
            assert(true);
126
            assert(true);
104
            return;
127
            return;
Lines 136-141 Link Here
136
        }
159
        }
137
    }
160
    }
138
    
161
    
162
    protected Matcher<List<CompletionResultItem>> containsSuggestions(String... suggestions) {
163
        return new SuggestionsContaining(false, suggestions);
164
    }
165
    
166
    protected Matcher<List<CompletionResultItem>> containsOnlySuggestions(String... suggestions) {
167
        return new SuggestionsContaining(true, suggestions);
168
    }
169
    
139
    BaseDocument getDocument() {
170
    BaseDocument getDocument() {
140
        return instanceDocument;
171
        return instanceDocument;
141
    }
172
    }
Lines 153-156 Link Here
153
        context.initContext();
184
        context.initContext();
154
        return context;
185
        return context;
155
    }
186
    }
187
188
    private class SuggestionsContaining extends TypeSafeMatcher<List<CompletionResultItem>> {
189
190
        private final List<String> expectedSuggestionStrings;
191
        private final boolean expectingExactMatch;
192
        public SuggestionsContaining(boolean expectingExactMatch, String... suggestions) {
193
            this.expectedSuggestionStrings = Arrays.asList(suggestions);
194
            this.expectingExactMatch = expectingExactMatch;
195
        }
196
197
        @Override
198
        public boolean matchesSafely(List<CompletionResultItem> actual) {
199
            if(actual == null) {
200
                return false;
201
            }
202
            if(expectingExactMatch && actual.size() != expectedSuggestionStrings.size()) {
203
                return false;
204
            }
205
            List<String> actualSuggestionStrings = new ArrayList<String>(actual.size());
206
            for (CompletionResultItem result : actual) {
207
                actualSuggestionStrings.add(result.getItemText());
208
            }
209
            return actualSuggestionStrings.containsAll(expectedSuggestionStrings);
210
        }
211
212
        @Override
213
        public void describeTo(Description d) {
214
            d.appendText("completion results ");
215
            if(expectingExactMatch) {
216
                d.appendText("exactly matching ");
217
            } else {
218
                d.appendText("containing ");
219
            }
220
            d.appendValue(expectedSuggestionStrings);
221
        }
222
    }
156
}
223
}
(-)cec51eb4fe39 (+21 lines)
Added Link Here
1
<?xml version="1.0" encoding="UTF-8"?>
2
<xs:schema version="1.0" 
3
           xmlns="urn:child1"
4
           xmlns:parent="urn:parent"
5
           targetNamespace="urn:child1"
6
           xmlns:xs="http://www.w3.org/2001/XMLSchema" 
7
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
8
           xsi:schemaLocation="http://www.w3.org/2001/XMLSchema XMLSchema.xsd
9
                               urn:parent AbstractElementParent.xsd"
10
           elementFormDefault="qualified" xml:lang="EN">
11
12
    <xs:import namespace="urn:parent" schemaLocation="AbstractElementParent.xsd"/> 
13
     
14
    <xs:element name="child-one" substitutionGroup="parent:child" type="ChildOne"/>
15
16
    <xs:complexType name="ChildOne">
17
        <xs:complexContent>
18
            <xs:extension base="parent:Child"/>
19
        </xs:complexContent>
20
    </xs:complexType>
21
</xs:schema>
(-)cec51eb4fe39 (+21 lines)
Added Link Here
1
<?xml version="1.0" encoding="UTF-8"?>
2
<xs:schema version="1.0" 
3
           xmlns="urn:child2"
4
           xmlns:parent="urn:parent"
5
           targetNamespace="urn:child2"
6
           xmlns:xs="http://www.w3.org/2001/XMLSchema" 
7
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
8
           xsi:schemaLocation="http://www.w3.org/2001/XMLSchema XMLSchema.xsd
9
                               urn:parent AbstractElementParent.xsd"
10
           elementFormDefault="qualified" xml:lang="EN">
11
12
    <xs:import namespace="urn:parent" schemaLocation="AbstractElementParent.xsd"/> 
13
     
14
    <xs:element name="child-two" substitutionGroup="parent:child" type="ChildTwo"/>
15
16
    <xs:complexType name="ChildTwo">
17
        <xs:complexContent>
18
            <xs:extension base="parent:Child"/>
19
        </xs:complexContent>
20
    </xs:complexType>
21
</xs:schema>
(-)cec51eb4fe39 (+11 lines)
Added Link Here
1
<?xml version="1.0" encoding="UTF-8"?>
2
<parent xmlns="urn:parent"
3
        xmlns:c1="urn:child1"
4
        xmlns:c2="urn:child2"
5
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
6
        xsi:schemaLocation="http://www.w3.org/2001/XMLSchema XMLSchema.xsd
7
                            urn:parent AbstractElementParent.xsd
8
                            urn:child1 AbstractElementChildOne.xsd
9
                            urn:child2 AbstractElementChildTwo.xsd">
10
    
11
</parent>
(-)cec51eb4fe39 (+23 lines)
Added Link Here
1
<?xml version="1.0" encoding="UTF-8"?>
2
<xs:schema version="1.0" 
3
           xmlns="urn:parent"
4
           targetNamespace="urn:parent"
5
           xmlns:xs="http://www.w3.org/2001/XMLSchema" 
6
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
7
           xsi:schemaLocation="http://www.w3.org/2001/XMLSchema XMLSchema.xsd"
8
           elementFormDefault="qualified" xml:lang="EN">
9
               
10
    <xs:element name="parent" type="Parent"/>
11
12
    <xs:element name="child" abstract="true"/>
13
14
    <xs:complexType name="Parent">
15
        <xs:sequence>
16
            <xs:element ref="child" maxOccurs="unbounded"/>
17
        </xs:sequence>
18
    </xs:complexType>
19
20
    <xs:complexType name="Child" abstract="true">
21
        <xs:attribute name="name" type="xs:string"/>
22
    </xs:complexType>
23
</xs:schema>
(-)a/xml.schema.completion/test/unit/src/org/netbeans/modules/xml/schema/completion/resources/Include.xml (-1 / +1 lines)
Lines 1-5 Link Here
1
<?xml version="1.0" encoding="UTF-8"?>
1
<?xml version="1.0" encoding="UTF-8"?>
2
<ns:Main2  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance\"
2
<ns:Main2  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3
   xmlns:ns="http://xml.netbeans.org/schema/Main"
3
   xmlns:ns="http://xml.netbeans.org/schema/Main"
4
   xsi:schemaLocation="http://xml.netbeans.org/schema/Main Main.xsd">
4
   xsi:schemaLocation="http://xml.netbeans.org/schema/Main Main.xsd">
5
       <
5
       <
(-)cec51eb4fe39 (+148 lines)
Added 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-2010 Oracle and/or its affiliates. All rights reserved.
6
7
Oracle and Java are registered trademarks of Oracle and/or its affiliates.
8
Other names may be trademarks of their respective owners.
9
10
The contents of this file are subject to the terms of either the GNU
11
General Public License Version 2 only ("GPL") or the Common
12
Development and Distribution License("CDDL") (collectively, the
13
"License"). You may not use this file except in compliance with the
14
License. You can obtain a copy of the License at
15
http://www.netbeans.org/cddl-gplv2.html
16
or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
17
specific language governing permissions and limitations under the
18
License.  When distributing the software, include this License Header
19
Notice in each file and include the License file at
20
nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
21
particular file as subject to the "Classpath" exception as provided
22
by Oracle in the GPL Version 2 section of the License file that
23
accompanied this code. If applicable, add the following below the
24
License Header, with the fields enclosed by brackets [] replaced by
25
your own identifying information:
26
"Portions Copyrighted [year] [name of copyright owner]"
27
28
Contributor(s):
29
30
The Original Software is NetBeans. The Initial Developer of the Original
31
Software is Sun Microsystems, Inc. Portions Copyright 1997-2009 Sun
32
Microsystems, Inc. All Rights Reserved.
33
34
If you wish your version of this file to be governed by only the CDDL
35
or only the GPL Version 2, indicate your decision by adding
36
"[Contributor] elects to include this software in this distribution
37
under the [CDDL or GPL Version 2] license." If you do not indicate a
38
single choice of license, a recipient has the option to distribute
39
your version of this file under either the CDDL, the GPL Version 2 or
40
to extend the choice of license to its licensees as provided above.
41
However, if you add GPL Version 2 code and therefore, elected the GPL
42
Version 2 license, then the option applies only if the new code is
43
made subject to such option by the copyright holder.
44
-->
45
<?xml-stylesheet type="text/xml" href="../nbbuild/javadoctools/apichanges.xsl"?>
46
<!DOCTYPE apichanges PUBLIC "-//NetBeans//DTD API changes list 1.0//EN" "../nbbuild/javadoctools/apichanges.dtd">
47
48
<!--
49
50
INFO FOR PEOPLE ADDING CHANGES:
51
52
Check the DTD (apichanges.dtd) for details on the syntax. You do not
53
need to regenerate the HTML, as this is part of Javadoc generation; just
54
change the XML. Rough syntax of a change (several parts optional):
55
56
<change>
57
    <api name="compiler"/>
58
    <summary>Some brief description here, can use <b>XHTML</b></summary>
59
    <version major="1" minor="99"/>
60
    <date day="13" month="6" year="2001"/>
61
    <author login="jrhacker"/>
62
    <compatibility addition="yes"/>
63
    <description>
64
        The main description of the change here.
65
        Again can use full <b>XHTML</b> as needed.
66
    </description>
67
    <class package="org.openide.compiler" name="DoWhatIWantCompiler"/>
68
    <issue number="14309"/>
69
</change>
70
71
Also permitted elements: <package>, <branch>. <version> is API spec
72
version, recommended for all new changes. <compatibility> should say
73
if things were added/modified/deprecated/etc. and give all information
74
related to upgrading old code. List affected top-level classes and
75
link to issue numbers if applicable. See the DTD for more details.
76
77
Changes need not be in any particular order, they are sorted in various
78
ways by the stylesheet anyway.
79
80
Dates are assumed to mean "on the trunk". If you *also* make the same
81
change on a stabilization branch, use the <branch> tag to indicate this
82
and explain why the change was made on a branch in the <description>.
83
84
Please only change this file on the trunk! Rather: you can change it
85
on branches if you want, but these changes will be ignored; only the
86
trunk version of this file is important.
87
88
Deprecations do not count as incompatible, assuming that code using the
89
deprecated calls continues to see their documented behavior. But do
90
specify deprecation="yes" in <compatibility>.
91
92
This file is not a replacement for Javadoc: it is intended to list changes,
93
not describe the complete current behavior, for which ordinary documentation
94
is the proper place.
95
96
-->
97
98
<apichanges>
99
    <apidefs>
100
        <apidef name="model">Schema Model API</apidef>
101
        <apidef name="visitors">Schema Model Visitors</apidef>
102
    </apidefs>
103
104
    <changes>
105
        <change>
106
            <api name="visitors"/>
107
            <summary>Added FindSubstitutions to find all valid substitutions for global elements</summary>
108
            <version major="1" minor="17"/>
109
            <date day="28" month="10" year="2011"/>
110
            <author login="dbell"/>
111
            <compatibility addition="yes"/>
112
            <description>
113
                <p>
114
                    Added FindSubstitutions: a utility class that finds all 
115
                    valid substitutions (global elements) for a given 
116
                    substitution group head (also a global element). 
117
                    Substitutions are found from all schemas referenced by the 
118
                    target SchemaModel.
119
                </p>
120
            </description>
121
            <class package="org.netbeans.modules.xml.schema.visitor" name="FindSubstitutionsVisitor"/>
122
            <issue number="203793"/>
123
        </change>
124
    </changes>
125
126
    <htmlcontents>
127
        <!-- Generated from apichanges.xml -->
128
        <head>
129
            <title>Change History for the Schema Model API</title>
130
            <link rel="stylesheet" href="prose.css" type="text/css"/>
131
        </head>
132
        <body>
133
            <p class="overviewlink">
134
                <a href="@TOP@/overview-summary.html">Overview</a>
135
            </p>
136
            <h1>Introduction</h1>
137
            <p>
138
                This document lists changes made to the 
139
                <a href="@TOP@/overview-summary.html">Schema Model API</a>.
140
            </p>
141
            <!-- The actual lists of changes, as summaries and details: -->
142
            <hr/>
143
            <standard-changelists module-code-name="org.netbeans.modules.xml.schema.model/1"/>
144
            <hr/>
145
            <p>@FOOTER@</p>
146
        </body>
147
    </htmlcontents>
148
</apichanges>
(-)a/xml.schema.model/nbproject/project.properties (-1 / +2 lines)
Lines 45-48 Link Here
45
is.autoload=true
45
is.autoload=true
46
javac.source=1.6
46
javac.source=1.6
47
javadoc.arch=${basedir}/arch.xml
47
javadoc.arch=${basedir}/arch.xml
48
spec.version.base=1.16.0
48
javadoc.apichanges=${basedir}/apichanges.xml
49
spec.version.base=1.17.0
(-)a/xml.schema.model/src/org/netbeans/modules/xml/schema/model/GlobalElement.java (+5 lines)
Lines 87-92 Link Here
87
    Set<Final> getFinalDefault();
87
    Set<Final> getFinalDefault();
88
    Set<Final> getFinalEffective();
88
    Set<Final> getFinalEffective();
89
    
89
    
90
    /**
91
     * The substitution group to which this element belongs
92
     * @return the substitution group to which this element belongs, or null if
93
     * the element does not belong to a substitution group
94
     */
90
    NamedComponentReference<GlobalElement> getSubstitutionGroup();
95
    NamedComponentReference<GlobalElement> getSubstitutionGroup();
91
    void setSubstitutionGroup(NamedComponentReference<GlobalElement> element);
96
    void setSubstitutionGroup(NamedComponentReference<GlobalElement> element);
92
    
97
    
(-)a/xml.schema.model/src/org/netbeans/modules/xml/schema/model/SchemaModel.java (-1 / +1 lines)
Lines 110-116 Link Here
110
         * @param type type of the component.
110
         * @param type type of the component.
111
         */
111
         */
112
        <T extends NamedReferenceable> T resolve(String namespace, String localName, Class<T> type);
112
        <T extends NamedReferenceable> T resolve(String namespace, String localName, Class<T> type);
113
113
        
114
        /**
114
        /**
115
         * Returns true for schemas that are embedded inside other artifacts such as WSDLs and BPELs.
115
         * Returns true for schemas that are embedded inside other artifacts such as WSDLs and BPELs.
116
         * False in all other cases.
116
         * False in all other cases.
(-)cec51eb4fe39 (+165 lines)
Added Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU General
10
 * Public License Version 2 only ("GPL") or the Common Development and
11
 * Distribution License("CDDL") (collectively, the "License"). You may not use
12
 * this file except in compliance with the License. You can obtain a copy of the
13
 * License at http://www.netbeans.org/cddl-gplv2.html or
14
 * nbbuild/licenses/CDDL-GPL-2-CP. See the License for the specific language
15
 * governing permissions and limitations under the License. When distributing
16
 * the software, include this License Header Notice in each file and include the
17
 * License file at nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
18
 * particular file as subject to the "Classpath" exception as provided by Oracle
19
 * in the GPL Version 2 section of the License file that accompanied this code.
20
 * If applicable, add the following below the License Header, with the fields
21
 * enclosed by brackets [] replaced by your own identifying information:
22
 * "Portions Copyrighted [year] [name of copyright owner]"
23
 *
24
 * If you wish your version of this file to be governed by only the CDDL or only
25
 * the GPL Version 2, indicate your decision by adding "[Contributor] elects to
26
 * include this software in this distribution under the [CDDL or GPL Version 2]
27
 * license." If you do not indicate a single choice of license, a recipient has
28
 * the option to distribute your version of this file under either the CDDL, the
29
 * GPL Version 2 or to extend the choice of license to its licensees as provided
30
 * above. However, if you add GPL Version 2 code and therefore, elected the GPL
31
 * Version 2 license, then the option applies only if the new code is made
32
 * subject to such option by the copyright holder.
33
 *
34
 * Contributor(s):
35
 *
36
 * Portions Copyrighted 2011 Sun Microsystems, Inc.
37
 */
38
package org.netbeans.modules.xml.schema.model.visitor;
39
40
import java.util.*;
41
import org.netbeans.modules.xml.schema.model.*;
42
import org.netbeans.modules.xml.xam.dom.NamedComponentReference;
43
import org.netbeans.modules.xml.xam.locator.CatalogModelException;
44
45
/**
46
 * Resolves substitutions for {@link GlobalElement}s which are referenced by
47
 * other {@link GlobalElement}s as substitution groups.
48
 *
49
 * @author Daniel Bell (dbell@netbeans.org)
50
 * @see #resolveSubstitutions
51
 * @since org.netbeans.modules.xml.schema.model/1 1.17
52
 */
53
public final class FindSubstitutions {
54
55
    private FindSubstitutions() {
56
    }
57
58
    /**
59
     * Find all substitutions for a {@link GlobalElement} that is referenced by
60
     * other {@link GlobalElement}s as a substitution group. All referenced
61
     * schemas (via &lt;import&gt; / &lt;include&gt; /&lt;redefine&gt;) are
62
     * searched for substitution possibilities.
63
     *
64
     * @param model the model to search for substitutions for the specified
65
     * substitution group head
66
     * @param namespaceUri the namespace URI of the substitution group head
67
     * @param localName local name of the substitution group head (must resolve
68
     * to a global element)
69
     * @return all possible substitutions for the specified type
70
     */
71
    public static Set<GlobalElement> resolveSubstitutions(SchemaModel model, String namespaceUri, String localName) {
72
        GlobalElement element = model.resolve(namespaceUri, localName, GlobalElement.class);
73
        if (element == null) {
74
            return Collections.emptySet();
75
        } else {
76
            return resolveSubstitutions(model, element);
77
        }
78
    }
79
80
    /**
81
     * Find all substitutions for a {@link GlobalElement} that is referenced by
82
     * other {@link GlobalElement}s as a substitution group. All referenced
83
     * schemas (via &lt;import&gt; / &lt;include&gt; /&lt;redefine&gt;) are
84
     * searched for substitution possibilities.
85
     *
86
     * @param model the model to search for substitutions for the specified
87
     * substitution group head
88
     * @param substitutionGroupHead the element for which to search for
89
     * substitutable elements
90
     * @return all elements reachable from the provided model that specify the
91
     * provided element as their {@code substitutionGroup}
92
     */
93
    static Set<GlobalElement> resolveSubstitutions(SchemaModel model, GlobalElement substitutionGroupHead) {
94
        Schema startSchema = model.getSchema();
95
        Collection<Schema> schemasToSearch = getSelfAndReferencedSchemas(startSchema);
96
97
        Visitor visitor = new Visitor(substitutionGroupHead);
98
        for (Schema schema : schemasToSearch) {
99
            schema.accept(visitor);
100
        }
101
        return Collections.unmodifiableSet(visitor.substitutions);
102
    }
103
104
    private static Collection<Schema> getSelfAndReferencedSchemas(Schema startSchema) {
105
        Set<Schema> referencedSchemas = new HashSet<Schema>();
106
        referencedSchemas.add(startSchema);
107
        collectReferencedSchemas(startSchema, referencedSchemas);
108
        return referencedSchemas;
109
    }
110
111
    private static void collectReferencedSchemas(Schema start, Set<Schema> schemas) {
112
        Collection<SchemaModelReference> referencedSchemas = start.getSchemaReferences();
113
        for (SchemaModelReference reference : referencedSchemas) {
114
            try {
115
                SchemaModel referencedModel = reference.resolveReferencedModel();
116
                Schema referencedSchema = referencedModel.getSchema();
117
                if (schemas.add(referencedSchema)) { //Don't add schema references more than once
118
                    collectReferencedSchemas(referencedSchema, schemas);
119
                }
120
            } catch (@SuppressWarnings("unused") CatalogModelException ex) {
121
                //Could not resolve schema reference
122
            }
123
        }
124
    }
125
126
    /**
127
     * A {@link SchemaVisitor visitor} to find all global elements specifying
128
     * the target element as their substitution group.
129
     */
130
    private static class Visitor extends DeepSchemaVisitor {
131
132
        private final Set<GlobalElement> substitutions = new LinkedHashSet<GlobalElement>();
133
        private final GlobalElement substitutionGroupBase;
134
135
        private Visitor(GlobalElement substitutionGroupBase) {
136
            this.substitutionGroupBase = substitutionGroupBase;
137
        }
138
139
        @Override
140
        public void visit(ElementReference element) {
141
            NamedComponentReference<GlobalElement> reference = element.getRef();
142
            if (!reference.isBroken()) {
143
                addIfInSubstitutionGroup(reference.get());
144
            }
145
            super.visit(element);
146
        }
147
148
        @Override
149
        public void visit(GlobalElement element) {
150
            addIfInSubstitutionGroup(element);
151
            super.visit(element);
152
        }
153
154
        private void addIfInSubstitutionGroup(GlobalElement potentialSubstitute) {
155
            NamedComponentReference<GlobalElement> substitutionGroupReference = potentialSubstitute.getSubstitutionGroup();
156
            boolean hasResolvableSubGroup = !(substitutionGroupReference == null || substitutionGroupReference.isBroken());
157
            if (hasResolvableSubGroup) {
158
                GlobalElement referencedSubstitutionGroup = substitutionGroupReference.get();
159
                if (substitutionGroupBase.equals(referencedSubstitutionGroup)) {
160
                    substitutions.add(potentialSubstitute);
161
                }
162
            }
163
        }
164
    }
165
}
(-)a/xml.schema.model/src/org/netbeans/modules/xml/schema/model/visitor/PreviewImpl.java (+8 lines)
Lines 68-73 Link Here
68
    /**
68
    /**
69
     * Returns a collection of schema components, all of which,
69
     * Returns a collection of schema components, all of which,
70
     * reference the same global schema component.
70
     * reference the same global schema component.
71
     * @return a Map of usages to their path from their respective schema's root.<br/>
72
     * Example: <br/>
73
     * <pre>
74
     * { 
75
     *    myElement : [mySchema > myElement], 
76
     *    myOtherElement : [myOtherSchema > myType > myOtherElement] 
77
     * }
78
     * </pre>
71
     */
79
     */
72
    public Map<SchemaComponent, List<SchemaComponent>> getUsages() {
80
    public Map<SchemaComponent, List<SchemaComponent>> getUsages() {
73
        return usages;
81
        return usages;
(-)a/xml.schema.model/test/unit/src/org/netbeans/modules/xml/schema/model/TestCatalogModel.java (-13 / +22 lines)
Lines 41-56 Link Here
41
 * Version 2 license, then the option applies only if the new code is
41
 * Version 2 license, then the option applies only if the new code is
42
 * made subject to such option by the copyright holder.
42
 * made subject to such option by the copyright holder.
43
 */
43
 */
44
45
/*
46
 * TestCatalogModel.java
47
 *
48
 * Created on April 2, 2006, 10:41 AM
49
 *
50
 * To change this template, choose Tools | Template Manager
51
 * and open the template in the editor.
52
 */
53
54
package org.netbeans.modules.xml.schema.model;
44
package org.netbeans.modules.xml.schema.model;
55
45
56
import java.io.File;
46
import java.io.File;
Lines 60-72 Link Here
60
import java.util.HashMap;
50
import java.util.HashMap;
61
import java.util.Map;
51
import java.util.Map;
62
import javax.swing.text.Document;
52
import javax.swing.text.Document;
53
import org.junit.rules.ExternalResource;
54
import org.junit.rules.TestRule;
63
import org.netbeans.editor.BaseDocument;
55
import org.netbeans.editor.BaseDocument;
64
import org.netbeans.editor.BaseKit;
65
import org.netbeans.modules.xml.retriever.catalog.impl.CatalogFileWrapperDOMImpl;
56
import org.netbeans.modules.xml.retriever.catalog.impl.CatalogFileWrapperDOMImpl;
66
import org.netbeans.modules.xml.retriever.catalog.impl.CatalogWriteModelImpl;
57
import org.netbeans.modules.xml.retriever.catalog.impl.CatalogWriteModelImpl;
58
import org.netbeans.modules.xml.xam.ModelSource;
67
import org.netbeans.modules.xml.xam.locator.CatalogModel;
59
import org.netbeans.modules.xml.xam.locator.CatalogModel;
68
import org.netbeans.modules.xml.xam.locator.CatalogModelException;
60
import org.netbeans.modules.xml.xam.locator.CatalogModelException;
69
import org.netbeans.modules.xml.xam.ModelSource;
70
import org.openide.cookies.SaveCookie;
61
import org.openide.cookies.SaveCookie;
71
import org.openide.filesystems.FileObject;
62
import org.openide.filesystems.FileObject;
72
import org.openide.filesystems.FileUtil;
63
import org.openide.filesystems.FileUtil;
Lines 79-85 Link Here
79
 *
70
 *
80
 * @author girix
71
 * @author girix
81
 */
72
 */
82
83
public class TestCatalogModel extends CatalogWriteModelImpl{
73
public class TestCatalogModel extends CatalogWriteModelImpl{
84
    private TestCatalogModel(File file) throws IOException{
74
    private TestCatalogModel(File file) throws IOException{
85
        super(file);
75
        super(file);
Lines 234-238 Link Here
234
    public void clearDocumentPool() {
224
    public void clearDocumentPool() {
235
        fileToDocumentMap = null;
225
        fileToDocumentMap = null;
236
    }
226
    }
227
    
228
    /**
229
     * A JUnit {@link TestRule} that stops tests from interfering with one 
230
     * another. JUnit will automatically set up/clean up the catalog when this
231
     * rule is used. <br/>
232
     * Usage:<br/>
233
     * {@code @Rule public final TestRule catalogMaintainer = TestCatalogModel.maintainer()}
234
     * @return the TestRule
235
     */
236
    public static TestRule maintainer() {
237
        return new ExternalResource() {
238
239
            @Override
240
            protected void after() {
241
                getDefault().clearDocumentPool();
242
            }
243
        
244
        };
245
    }
237
}
246
}
238
247
(-)cec51eb4fe39 (+21 lines)
Added Link Here
1
<?xml version="1.0" encoding="UTF-8"?>
2
<xs:schema version="1.0" 
3
           xmlns="urn:child1"
4
           xmlns:parent="urn:parent"
5
           targetNamespace="urn:child1"
6
           xmlns:xs="http://www.w3.org/2001/XMLSchema" 
7
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
8
           xsi:schemaLocation="http://www.w3.org/2001/XMLSchema XMLSchema.xsd
9
                               urn:parent SubstitutionGroupParent.xsd"
10
           elementFormDefault="qualified" xml:lang="EN">
11
12
    <xs:import namespace="urn:parent" schemaLocation="SubstitutionGroupParent.xsd"/> 
13
     
14
    <xs:element name="child-one" substitutionGroup="parent:child" type="ChildOne"/>
15
16
    <xs:complexType name="ChildOne">
17
        <xs:complexContent>
18
            <xs:extension base="parent:Child"/>
19
        </xs:complexContent>
20
    </xs:complexType>
21
</xs:schema>
(-)cec51eb4fe39 (+21 lines)
Added Link Here
1
<?xml version="1.0" encoding="UTF-8"?>
2
<xs:schema version="1.0" 
3
           xmlns="urn:child2"
4
           xmlns:parent="urn:parent"
5
           targetNamespace="urn:child2"
6
           xmlns:xs="http://www.w3.org/2001/XMLSchema" 
7
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
8
           xsi:schemaLocation="http://www.w3.org/2001/XMLSchema XMLSchema.xsd
9
                               urn:parent SubstitutionGroupParent.xsd"
10
           elementFormDefault="qualified" xml:lang="EN">
11
12
    <xs:import namespace="urn:parent" schemaLocation="SubstitutionGroupParent.xsd"/> 
13
     
14
    <xs:element name="child-two" substitutionGroup="parent:child" type="ChildTwo"/>
15
16
    <xs:complexType name="ChildTwo">
17
        <xs:complexContent>
18
            <xs:extension base="parent:Child"/>
19
        </xs:complexContent>
20
    </xs:complexType>
21
</xs:schema>
(-)cec51eb4fe39 (+23 lines)
Added Link Here
1
<?xml version="1.0" encoding="UTF-8"?>
2
<xs:schema version="1.0" 
3
           xmlns="urn:parent"
4
           targetNamespace="urn:parent"
5
           xmlns:xs="http://www.w3.org/2001/XMLSchema" 
6
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
7
           xsi:schemaLocation="http://www.w3.org/2001/XMLSchema XMLSchema.xsd"
8
           elementFormDefault="qualified" xml:lang="EN">
9
               
10
    <xs:element name="parent" type="Parent"/>
11
12
    <xs:element name="child" abstract="true"/>
13
14
    <xs:complexType name="Parent">
15
        <xs:sequence>
16
            <xs:element ref="child" maxOccurs="unbounded"/>
17
        </xs:sequence>
18
    </xs:complexType>
19
20
    <xs:complexType name="Child" abstract="true">
21
        <xs:attribute name="name" type="xs:string"/>
22
    </xs:complexType>
23
</xs:schema>
(-)cec51eb4fe39 (+108 lines)
Added Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU General
10
 * Public License Version 2 only ("GPL") or the Common Development and
11
 * Distribution License("CDDL") (collectively, the "License"). You may not use
12
 * this file except in compliance with the License. You can obtain a copy of the
13
 * License at http://www.netbeans.org/cddl-gplv2.html or
14
 * nbbuild/licenses/CDDL-GPL-2-CP. See the License for the specific language
15
 * governing permissions and limitations under the License. When distributing
16
 * the software, include this License Header Notice in each file and include the
17
 * License file at nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
18
 * particular file as subject to the "Classpath" exception as provided by Oracle
19
 * in the GPL Version 2 section of the License file that accompanied this code.
20
 * If applicable, add the following below the License Header, with the fields
21
 * enclosed by brackets [] replaced by your own identifying information:
22
 * "Portions Copyrighted [year] [name of copyright owner]"
23
 *
24
 * If you wish your version of this file to be governed by only the CDDL or only
25
 * the GPL Version 2, indicate your decision by adding "[Contributor] elects to
26
 * include this software in this distribution under the [CDDL or GPL Version 2]
27
 * license." If you do not indicate a single choice of license, a recipient has
28
 * the option to distribute your version of this file under either the CDDL, the
29
 * GPL Version 2 or to extend the choice of license to its licensees as provided
30
 * above. However, if you add GPL Version 2 code and therefore, elected the GPL
31
 * Version 2 license, then the option applies only if the new code is made
32
 * subject to such option by the copyright holder.
33
 *
34
 * Contributor(s):
35
 *
36
 * Portions Copyrighted 2011 Sun Microsystems, Inc.
37
 */
38
package org.netbeans.modules.xml.schema.model.visitor;
39
40
import java.util.Set;
41
import static org.hamcrest.CoreMatchers.is;
42
import static org.junit.Assert.assertThat;
43
import org.junit.Before;
44
import org.junit.Rule;
45
import org.junit.Test;
46
import static org.junit.matchers.JUnitMatchers.hasItem;
47
import org.junit.rules.TestRule;
48
import org.netbeans.modules.xml.schema.model.GlobalElement;
49
import org.netbeans.modules.xml.schema.model.TestCatalogModel;
50
import org.netbeans.modules.xml.schema.model.Util;
51
import org.netbeans.modules.xml.schema.model.impl.SchemaModelImpl;
52
53
/**
54
 * Tests for {@link FindSubstitutionsVisitor}
55
 * @author Daniel Bell (dbell@netbeans.org)
56
 */
57
public class FindSubstitutionsVisitorTest {
58
    public static final String PARENT_NS_URI = "urn:parent";
59
    public static final String SUBSTITUTION_GROUP_HEAD = "child";
60
    private static final String PARENT_SCHEMA = "resources/SubstitutionGroupParent.xsd";
61
    private static final String CHILD_SCHEMA_ONE = "resources/SubstitutionGroupChildOne.xsd";
62
    private static final String CHILD_SCHEMA_TWO = "resources/SubstitutionGroupChildTwo.xsd";
63
    private static final String SUBSTITUTION_ELEMENT_ONE = "child-one";
64
    private static final String SUBSTITUTION_ELEMENT_TWO = "child-two";
65
    
66
    @Rule
67
    public final TestRule catalogMaintainer = TestCatalogModel.maintainer();
68
    
69
    private SchemaModelImpl parentModel;
70
    private SchemaModelImpl childModelOne;
71
    private SchemaModelImpl childModelTwo;
72
    
73
    @Before
74
    public void setUp() throws Exception {
75
        childModelOne = load(CHILD_SCHEMA_ONE);
76
        childModelTwo = load(CHILD_SCHEMA_TWO);
77
        parentModel = load(PARENT_SCHEMA);
78
    }
79
    
80
    /**
81
     * Each schema imports a substitution group base, and defines a global 
82
     * element that is part of this substitution group.
83
     * FindSubstitutionsVisitor should resolve this substitution.
84
     */
85
    @Test
86
    public void shouldResolveSubstitutionsFromLinkedSchemas() {
87
        GlobalElement substitutionGroupHead = getCachedElement(parentModel, SUBSTITUTION_GROUP_HEAD);
88
        GlobalElement expectedSubstitutionOne = getCachedElement(childModelOne, SUBSTITUTION_ELEMENT_ONE);
89
        GlobalElement expectedSubstitutionTwo = getCachedElement(childModelTwo, SUBSTITUTION_ELEMENT_TWO);
90
        
91
        Set<GlobalElement> possibleSubstitutionsOne = FindSubstitutions.resolveSubstitutions(childModelOne, substitutionGroupHead);
92
        Set<GlobalElement> possibleSubstitutionsTwo = FindSubstitutions.resolveSubstitutions(childModelTwo, substitutionGroupHead);
93
94
        assertThat(possibleSubstitutionsOne.size(), is(1));
95
        assertThat(possibleSubstitutionsOne, hasItem(expectedSubstitutionOne));
96
        
97
        assertThat(possibleSubstitutionsTwo.size(), is(1));
98
        assertThat(possibleSubstitutionsTwo, hasItem(expectedSubstitutionTwo)); //Should used cached substitution group head
99
    }
100
        
101
    private static GlobalElement getCachedElement(SchemaModelImpl model, String localName) {
102
        return model.getGlobalComponentsIndexSupport().findByNameAndType(localName, GlobalElement.class);
103
    }
104
105
    private static SchemaModelImpl load(String schemaPath) throws Exception {
106
        return Util.toSchemaModelImpl(Util.loadSchemaModel2(schemaPath));
107
    }
108
}
(-)a/xml.xam/src/org/netbeans/modules/xml/xam/dom/AbstractDocumentComponent.java (+5 lines)
Lines 821-826 Link Here
821
	CatalogModel nr = (CatalogModel) 
821
	CatalogModel nr = (CatalogModel) 
822
	    getModel().getModelSource().getLookup().lookup(CatalogModel.class);
822
	    getModel().getModelSource().getLookup().lookup(CatalogModel.class);
823
823
824
        if(nr == null) {
825
            String error = String.format("Cannot resolve file [hint = %s, backup = %s], because no CatalogModel exists in lookup", hint, backup);
826
            throw new CatalogModelException(error);
827
        }
828
        
824
	// try hint
829
	// try hint
825
	ModelSource ms = resolveModelSource(hint, getModel().getModelSource(), 
830
	ModelSource ms = resolveModelSource(hint, getModel().getModelSource(), 
826
	    nr);
831
	    nr);

Return to bug 203793