001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041: package org.netbeans.modules.xml.axi.impl;
042:
043: import java.util.List;
044: import org.netbeans.modules.xml.axi.AXIComponent;
045: import org.netbeans.modules.xml.axi.AXIDocument;
046: import org.netbeans.modules.xml.axi.ContentModel;
047: import org.netbeans.modules.xml.schema.model.*;
048: import org.netbeans.modules.xml.schema.model.visitor.DeepSchemaVisitor;
049: import org.netbeans.modules.xml.xam.dom.NamedComponentReference;
050:
051: /**
052: * Creates and populates children for a parent AXIComponent.
053: * Parent AXIComponent must first construct a AXIModelBuilder and then
054: * call its populateChildren method to populate the list of children.
055: *
056: * This is a visitor, which visits each node in the schema model tree
057: * to construct the AXI model.
058: *
059: * @author Samaresh (Samaresh.Panda@Sun.Com)
060: */
061: public class AXIModelBuilder extends AbstractModelBuilder {
062:
063: /**
064: * Creates a new instance of AXIModelBuilder
065: */
066: public AXIModelBuilder(AXIComponent parent) {
067: super ((AXIModelImpl) parent.getModel());
068: this .parent = parent;
069: }
070:
071: /**
072: * Populates the children list for the specified schema component.
073: * @param schemaComponent the component, for which, children and attribute
074: * lists are to be populated.
075: * @param visitChildren in general, this should be true, except when this is
076: * being called for an Element's type. Purely to keep the type tree in the sharedPool.
077: * @children children to be populated.
078: * @attributes attributes to be populated.
079: */
080: public void populateChildren(SchemaComponent schemaComponent,
081: boolean visitChildren, List<AXIComponent> children) {
082: this .children = children;
083:
084: //For an Element's type (if global), we want to visit the
085: //type so that it gets stored in the shared pool.
086: if (!visitChildren) {
087: schemaComponent.accept(this );
088: return;
089: }
090:
091: //visit all children
092: for (SchemaComponent child : schemaComponent.getChildren()) {
093: child.accept(this );
094: }
095: }
096:
097: /**
098: * Visit Schema.
099: */
100: public void visit(Schema schema) {
101: }
102:
103: /**
104: * Visit AnyElement.
105: */
106: public void visit(
107: org.netbeans.modules.xml.schema.model.AnyElement schemaComponent) {
108: AXIComponent child = getAXIComponent(schemaComponent, false);
109: addChild(child);
110: }
111:
112: /**
113: * Visit AnyAttribute.
114: */
115: public void visit(AnyAttribute schemaComponent) {
116: AXIComponent child = getAXIComponent(schemaComponent, false);
117: addChild(child);
118: }
119:
120: /**
121: * Visit GlobalElement.
122: */
123: public void visit(GlobalElement component) {
124: AXIComponent child = getAXIComponent(component, true);
125: addChild(child);
126: }
127:
128: /**
129: * Visit LocalElement.
130: */
131: public void visit(LocalElement component) {
132: AXIComponent child = getAXIComponent(component, false);
133: addChild(child);
134: }
135:
136: /**
137: * Visit ElementReference.
138: */
139: public void visit(ElementReference component) {
140: AXIComponent child = getAXIComponent(component, false);
141: addChild(child);
142: }
143:
144: /**
145: * Visit GlobalAttribute.
146: */
147: public void visit(GlobalAttribute component) {
148: AXIComponent child = getAXIComponent(component, true);
149: addChild(child);
150: }
151:
152: /**
153: * Visit LocalAttribute.
154: */
155: public void visit(LocalAttribute component) {
156: AXIComponent child = getAXIComponent(component, false);
157: addChild(child);
158: }
159:
160: /**
161: * Visit AttributeReference.
162: */
163: public void visit(AttributeReference component) {
164: AXIComponent child = getAXIComponent(component, false);
165: addChild(child);
166: }
167:
168: /**
169: * Visit Sequence.
170: */
171: public void visit(Sequence component) {
172: AXIComponent child = getAXIComponent(component, false);
173: addChild(child);
174: }
175:
176: /**
177: * Visit Choice.
178: */
179: public void visit(Choice component) {
180: AXIComponent child = getAXIComponent(component, false);
181: addChild(child);
182: }
183:
184: /**
185: * Visit All.
186: */
187: public void visit(All component) {
188: AXIComponent child = getAXIComponent(component, false);
189: addChild(child);
190: }
191:
192: /**
193: * Visit GlobalGroup.
194: */
195: public void visit(GlobalGroup component) {
196: AXIComponent child = getAXIComponent(component, true);
197: addChild(child);
198: }
199:
200: /**
201: * Visit GroupReference.
202: */
203: public void visit(GroupReference component) {
204: NamedComponentReference ref = component.getRef();
205: if (ref == null)
206: return;
207: SchemaComponent sc = model.getReferenceableSchemaComponent(ref);
208: if (sc == null)
209: return;
210: AXIComponent child = getAXIComponent(sc, true);
211: addChild(child);
212: }
213:
214: /**
215: * Visit GlobalAttributeGroup.
216: */
217: public void visit(GlobalAttributeGroup component) {
218: AXIComponent child = getAXIComponent(component, true);
219: addChild(child);
220: }
221:
222: /**
223: * Visit AttributeGroupReference.
224: */
225: public void visit(AttributeGroupReference component) {
226: NamedComponentReference ref = component.getGroup();
227: if (ref == null)
228: return;
229: SchemaComponent sc = model.getReferenceableSchemaComponent(ref);
230: if (sc == null)
231: return;
232: AXIComponent child = getAXIComponent(sc, true);
233: addChild(child);
234: }
235:
236: /**
237: * Visit GlobalComplexType.
238: */
239: public void visit(GlobalComplexType component) {
240: AXIComponent child = getAXIComponent(component, true);
241: addChild(child);
242: }
243:
244: /**
245: * Visit LocalComplexType.
246: */
247: public void visit(LocalComplexType component) {
248: visitChildren(component);
249: }
250:
251: /**
252: * Visit ComplexContent.
253: */
254: public void visit(ComplexContent component) {
255: visitChildren(component);
256: }
257:
258: /**
259: * Visit SimpleContent.
260: */
261: public void visit(SimpleContent component) {
262: visitChildren(component);
263: }
264:
265: /**
266: * Visit ComplexExtension.
267: */
268: public void visit(SimpleExtension component) {
269: NamedComponentReference ref = component.getBase();
270: if (ref != null) {
271: SchemaComponent type = model
272: .getReferenceableSchemaComponent(ref);
273: if (type != null) {
274: AXIComponent child = getAXIComponent(type, true);
275: addChild(child);
276: }
277: }
278: visitChildren(component);
279: }
280:
281: /**
282: * Visit ComplexExtension.
283: */
284: public void visit(ComplexExtension component) {
285: NamedComponentReference ref = component.getBase();
286: if (ref != null) {
287: SchemaComponent type = model
288: .getReferenceableSchemaComponent(ref);
289: if (type != null) {
290: AXIComponent child = getAXIComponent(type, true);
291: addChild(child);
292: }
293: }
294: visitChildren(component);
295: }
296:
297: /**
298: * Returns an AXIComponent if one exists or creates one.
299: *
300: * When this method gets called with a global component, it looks up the model
301: * and returns the global AXI component, unless the parent is AXIDocument.
302: *
303: * For local components, it always creates one.
304: */
305: private AXIComponent getAXIComponent(
306: final SchemaComponent schemaComponent, boolean isGlobal) {
307: //when parent is schema or for non-global components,
308: //always create one.
309: if (parent instanceof AXIDocument || !isGlobal) {
310: return new AXIComponentCreator(getModel())
311: .createNew(schemaComponent);
312: }
313:
314: if (!getModel().fromSameSchemaModel(schemaComponent)) {
315: return getModel().lookupFromOtherModel(schemaComponent);
316: }
317:
318: return getModel().lookup(schemaComponent);
319: }
320:
321: /**
322: * Adds the new component to the children list.
323: */
324: private void addChild(AXIComponent child) {
325: if (child == null)
326: return;
327:
328: if (parent instanceof AXIDocument) {
329: children.add(child);
330: ((AXIDocumentImpl) parent).addToCache(child);
331: return;
332: }
333:
334: if (child instanceof ContentModel) {
335: Util.addProxyChildren(parent, child, children);
336: return;
337: }
338: children.add(child);
339: }
340:
341: ////////////////////////////////////////////////////////////////////
342: ////////////////////////// member variables ////////////////////////
343: ////////////////////////////////////////////////////////////////////
344: /**
345: * Parent AXIComponent for whom, children are being populated.
346: */
347: private AXIComponent parent;
348:
349: /**
350: * Ref to the original children list being passed by the caller.
351: */
352: private List<AXIComponent> children;
353: }
|