KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > schema2beansdev > GraphLink


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.schema2beansdev;
21
22 import java.util.List JavaDoc;
23 import java.util.ArrayList JavaDoc;
24 import java.util.Iterator JavaDoc;
25
26 import org.netbeans.modules.schema2beans.*;
27
28 /**
29  * @see GraphNode
30  *
31  * Roughtly, a GraphLink is used to hold attribute definitions or groupings.
32  */

33 public class GraphLink {
34     /*
35      * The element that this link is associated to. This element might
36      * be referenced by more than one GraphLink object.
37      */

38     GraphNode element;
39
40     /*
41      * Where this object is coming from.
42      */

43     private GraphLink parent;
44     
45     /*
46      * Point to the next link holding information about the element
47      * in the sequence.
48      *
49      * For example <!ELEMENT elt (a, b, c)>
50      *
51      * If this link element references a, the sibling references a link
52      * object defining the element b.
53      *
54      */

55     private GraphLink sibling;
56     
57     /*
58      * Point to a subnode link defining information about an element
59      * defined in a "one-more level of parenthese".
60      *
61      * For example <!ELEMENT elt (a, (b | c)+, d>
62      *
63      * If this link element references a, the sibling references a link
64      * object defining the element d and the child link element references
65      * a link defining the element b (this link has itself a sibling link
66      * on a link object defining c). Note that the prop of the child link
67      * element will be: SEQUENCE_OR | INSTANCE_1N.
68      *
69      */

70     private GraphLink child;
71
72     private transient GraphLink lastChild; // cache
73

74     /*
75      * The prop integers define some properties on the link or element.
76      * The link might either start to define a list of nodes as
77      * a sequence of nodes: a and b and c, or it might define
78      * a list of node choices: a or b or c.
79      *
80      * For example <!ELEMENT elt (a, b, c)> -> sequence
81      * <!ELEMENT elt (a | b | c)> -> choice
82      *
83      *
84      * Also, the set of nodes defined by the link might have some
85      * rules as they should be instanciated (as defined by the ?, * and +
86      * DTD characters).
87      *
88      * propElement applies to the element of this link (one element of the
89      * DTD represented by a unique GraphNode might have different
90      * property values depending where and how the element is referenced
91      * by other elements).
92      * propChildren applies to the set of children of this GraphLink.
93      *
94      * For example, <ELEMENT! elt a?, (b, c, d)+ e>
95      *
96      * The link associated to the element a has the propElement set to the
97      * ? value and the propChildren set to the + value.
98      */

99     int propElement;
100     int propChildren;
101
102     /**
103      * Name of the java bean property (java class attribute) that we're
104      * defining. If it's null, then we're used for grouping.
105      */

106     String JavaDoc name;
107     private String JavaDoc schemaName = null;
108     private String JavaDoc namespace = null;
109     private String JavaDoc defaultValue;
110     private boolean nillable;
111     
112     private Object JavaDoc object;
113
114     List JavaDoc extraData = new ArrayList JavaDoc();
115
116     GraphLink(String JavaDoc name) {
117         // Those are the default values
118
this.propElement = Common.SEQUENCE_AND | Common.TYPE_1;
119         this.propChildren = Common.SEQUENCE_AND | Common.TYPE_1;
120         this.name = name;
121         this.schemaName = name;
122     }
123
124     GraphLink(String JavaDoc name, String JavaDoc namespace) {
125         // Those are the default values
126
this.propElement = Common.SEQUENCE_AND | Common.TYPE_1;
127         this.propChildren = Common.SEQUENCE_AND | Common.TYPE_1;
128         this.name = name;
129         this.namespace = namespace;
130         this.schemaName = name;
131     }
132
133     public String JavaDoc getNamespace() {
134         return namespace;
135     }
136
137     public boolean isUnion() {
138         return element.isUnion();
139     }
140
141     public void setUnion(boolean value) {
142         element.setUnion(value);
143     }
144
145     public List JavaDoc getChildren() { // List<GraphLink>
146
List JavaDoc result = new ArrayList JavaDoc();
147         for (GraphLink l = child; l != null; l = l.sibling)
148             result.add(l);
149         return result;
150     }
151
152     /**
153      * Return our parents children minus this.
154      */

155     public List JavaDoc getSiblings() { // List<GraphLink>
156
List JavaDoc result = new ArrayList JavaDoc();
157         if (parent == null) {
158             // The graph isn't well connected, assume I'm first child.
159
for (GraphLink l = this; l != null; l = l.sibling)
160                 result.add(l);
161             return result;
162         }
163         for (GraphLink l = parent.child; l != null; l = l.sibling) {
164             if (l == this)
165                 continue;
166             result.add(l);
167         }
168         return result;
169     }
170
171     /**
172      * Return our parents children.
173      */

174     public List JavaDoc getSiblingsAndMe() { // List<GraphLink>
175
if (parent == null) {
176             // The graph isn't well connected, assume I'm first child.
177
List JavaDoc result = new ArrayList JavaDoc();
178             for (GraphLink l = this; l != null; l = l.sibling)
179                 result.add(l);
180             return result;
181         }
182         return parent.getChildren();
183     }
184
185     /**
186      * Get next sibling. This might return null.
187      */

188     public GraphLink getSibling() {
189         return sibling;
190     }
191
192     public GraphLink getLastSibling() {
193         // Check if our parent has kept track of it.
194
if (parent != null && parent.lastChild != null)
195             return parent.getLastChild();
196         if (sibling == null)
197             return this;
198         else
199             return sibling.getLastSibling();
200     }
201
202     /**
203      * This might return null.
204      */

205     public GraphLink getFirstChild() {
206         return child;
207     }
208
209     /**
210      * This might return null.
211      */

212     public GraphLink getLastChild() {
213         if (lastChild == null) {
214             if (child != null)
215                 lastChild = child.getLastSibling();
216         }
217         return lastChild;
218     }
219
220     /**
221      * Replaces child list.
222      */

223     public void setChild(GraphLink l) {
224         child = l;
225         child.parent = this;
226         lastChild = null;
227     }
228
229     private void addSibling(GraphLink l) {
230         if (sibling != null)
231             throw new RuntimeException JavaDoc("I am not the last sibling!");
232         sibling = l;
233         // Siblings share the same parent
234
l.parent = parent;
235         if (parent != null)
236             parent.lastChild = l;
237     }
238
239     /**
240      * Adds child to end of child list.
241      */

242     public void addChild(GraphLink l) {
243         if (child == null)
244             setChild(l);
245         else
246             child.getLastSibling().addSibling(l);
247     }
248     
249     /**
250      * This might return null.
251      */

252     public GraphLink getParent() {
253         return parent;
254     }
255
256     private void setParent(GraphLink l) {
257         parent = l;
258     }
259
260     boolean isSequenceAnd() {
261     // Apply only to the set of children
262
return ((this.propChildren & Common.SEQUENCE_AND) ==
263         Common.SEQUENCE_AND);
264     }
265     
266     boolean isSequenceOr() {
267     // Apply only to the set of children
268
return ((this.propChildren & Common.SEQUENCE_OR) ==
269         Common.SEQUENCE_OR);
270     }
271     
272     void setSequence(int prop) {
273     this.propChildren = (this.propChildren & Common.MASK_TYPE) | prop;
274     }
275     
276     void setElementInstance(int instance) {
277     this.propElement =
278         (this.propElement & Common.MASK_SEQUENCE) | instance;
279     }
280     
281     int getElementInstance() {
282     return (this.propElement & Common.MASK_INSTANCE);
283     }
284     
285     void setGroupInstance(int instance) {
286         this.propChildren =
287             (this.propChildren & Common.MASK_SEQUENCE) | instance;
288     }
289     
290     int getGroupInstance() {
291         return (this.propChildren & Common.MASK_INSTANCE);
292     }
293
294     /**
295      * Fill links with GraphLink's that we're mutually exclusive with.
296      */

297     public void getMutuallyExclusiveLinks(List JavaDoc links) { // List<GraphLink>
298
if (parent == null)
299             return;
300         //
301
// Mutual exclusion is caused by xsd:choice or '|': (a|b|c)
302
// From b's perspective, it's mutually exclusive with a and c.
303
// From a's perspective, it's mutually exclusive with b and c, etc.
304
// However, if the groupInstance can be more than 1, then
305
// we're not mutually exclusive: (a|b|c)*
306
//
307
if (parent.isSequenceOr() &&
308             (parent.getGroupInstance() == Common.TYPE_1 ||
309              parent.getGroupInstance() == Common.TYPE_0_1)) {
310             for (Iterator JavaDoc it = getSiblings().iterator(); it.hasNext(); ) {
311                 GraphLink l = (GraphLink) it.next();
312                 l.findAllBelowBranch(links);
313             }
314         }
315         parent.getMutuallyExclusiveLinks(links);
316     }
317
318     /**
319      * Starting from this GraphLink, fill in all links below it, including
320      * this one.
321      */

322     public void findAllBelowBranch(List JavaDoc links) { // List<GraphLink>
323
links.add(this);
324         if (child != null)
325             child.findAllBelowBranchAndSiblings(links);
326     }
327
328     public void findAllBelowBranchAndSiblings(List JavaDoc links) { // List<GraphLink>
329
GraphLink l = this;
330         for (; l != null; l = l.sibling) {
331             links.add(l);
332             if (l.child != null)
333                 l.child.findAllBelowBranchAndSiblings(links);
334         }
335     }
336     
337     String JavaDoc getDefaultValue() {
338         return defaultValue;
339     }
340
341     void setDefaultValue(String JavaDoc d) {
342         defaultValue = d;
343     }
344
345     void setObject(Object JavaDoc obj) {
346         this.object = obj;
347     }
348     
349     Object JavaDoc getObject() {
350         return this.object;
351     }
352
353     boolean isNillable() {
354         return nillable;
355     }
356
357     void setNillable(boolean value) {
358         nillable = value;
359     }
360     
361     String JavaDoc getSchemaName() {
362         return schemaName;
363     }
364     
365     public XPathIterator xPathIterator(String JavaDoc xpath) {
366         return new XPathIterator(this, xpath);
367     }
368
369     public static class XPathIterator implements java.util.Iterator JavaDoc {
370         private String JavaDoc xpath;
371         private String JavaDoc step;
372         private GraphLink curLink;
373         private int position;
374         
375         public XPathIterator(GraphLink startingLink, String JavaDoc xpath) {
376             this.xpath = xpath;
377             curLink = startingLink;
378             findNextStep();
379         }
380
381         // Figure out the next step, and advance the state.
382
private void findNextStep() {
383             if (position >= xpath.length()) {
384                 step = null;
385                 return;
386             }
387             int startingPos = position;
388             for (; position < xpath.length(); ++position) {
389                 if (xpath.charAt(position) == '/') {
390                     step = xpath.substring(startingPos, position);
391                     ++position;
392                     if (".".equals(step)) {
393                         // skip over intermediate '.'s
394
startingPos = position;
395                     } else {
396                         return;
397                     }
398                 }
399             }
400             step = xpath.substring(startingPos, position);
401             if (startingPos > 0 && ".".equals(step)) {
402                 step = null;
403             }
404         }
405
406         public boolean hasNext() {
407             if (step == null)
408                 return false;
409             return true;
410         }
411
412         /**
413          * Returns GraphLink's
414          */

415         public Object JavaDoc next() {
416             if (step == null)
417                 throw new java.util.NoSuchElementException JavaDoc();
418             GraphLink result = curLink;
419             while (".".equals(step)) {
420                 findNextStep();
421                 if (step == null)
422                     return result;
423             }
424             // Don't deal with namespaces
425
int colonPos = step.indexOf(':');
426             if (colonPos >= 0)
427                 step = step.substring(colonPos+1, step.length());
428             //System.out.println("step="+step);
429
// Now go look for step
430
result = result.lookForChild(step);
431             if (result == null) {
432                 // Not found.
433
step = null;
434                 position = xpath.length();
435                 return null;
436             }
437             if (result.element == null) {
438                 curLink = null;
439             } else {
440                 curLink = result.element.getGraphLink();
441             }
442
443             findNextStep();
444             return result;
445         }
446
447         public void remove() {
448             throw new UnsupportedOperationException JavaDoc();
449         }
450     }
451
452     /**
453      * Look amongst out children to see if we have one where
454      * searchName.equals(getSchemaName())
455      */

456     GraphLink lookForChild(String JavaDoc searchName) {
457         /*
458         System.out.println("this="+this);
459         System.out.println("this.element="+this.element);
460         System.out.println("this.schemaName="+this.getSchemaName());
461         System.out.println("this.sibling="+this.sibling);
462         System.out.println("this.child="+this.child);
463         */

464         
465         if (searchName.equals(getSchemaName()))
466             return this;
467         if (name == null) {
468             //System.out.println("Grouping");
469
if (child != null) {
470                 GraphLink childResult = child.lookForChild(searchName);
471                 if (childResult != null)
472                     return childResult;
473             }
474         }
475         if (sibling != null)
476             return sibling.lookForChild(searchName);
477         if (child != null)
478             return child.lookForChild(searchName);
479         return null;
480     }
481 }
482
Popular Tags