KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > schema2beans > GraphManager


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.schema2beans;
21
22 import java.util.*;
23 import java.io.*;
24
25 import org.w3c.dom.*;
26 import org.xml.sax.*;
27
28 import javax.xml.parsers.DocumentBuilder JavaDoc;
29 import javax.xml.parsers.DocumentBuilderFactory JavaDoc;
30
31 /**
32  *
33  *
34  */

35 public class GraphManager extends Object JavaDoc {
36
37     public static interface Writer {
38     public void write(OutputStream out, Document doc);
39     }
40
41     public static interface Factory {
42         public org.w3c.dom.Document JavaDoc createDocument(InputStream in,
43                                                    boolean validate);
44     }
45     
46     Document document = null;
47     NodeFactory factory = null;
48     HashMap bindingsMap = new HashMap();
49     BaseBean root;
50     private boolean writeCData = false;
51     
52     // When set to null (default), use XMLDocument instead
53
private Factory JavaDoc docFactory;
54     private Writer docWriter;
55
56     private String JavaDoc docTypePublic;
57     private String JavaDoc docTypeSystem;
58     
59     //
60
// The key is the input stream. This is how we can get the
61
// factory/writer when we are asked to build a Dom graph.
62
//
63
static Map factoryMap = Collections.synchronizedMap(new HashMap(2));
64     static Map writerMap = Collections.synchronizedMap(new HashMap(2));
65     
66
67     public GraphManager(BaseBean root) {
68         this.root = root;
69     }
70     
71     /**
72      * Associate a factory to a stream
73      */

74     public static void setFactory(InputStream in,
75                   GraphManager.Factory factory) throws Schema2BeansException {
76     setFactory(in, factory, null);
77     }
78     
79     /**
80      * Set an external factory to use instead of the default one
81      */

82     public static void setFactory(InputStream in, GraphManager.Factory factory,
83                   GraphManager.Writer writer) throws Schema2BeansException {
84     if (in == null)
85         throw new Schema2BeansException(Common.getMessage(
86         "InputStreamCantBeNull_msg"));
87
88     if (factory != null)
89         GraphManager.factoryMap.put(in, factory);
90     else
91         GraphManager.factoryMap.remove(in);
92
93     if (writer != null)
94         GraphManager.writerMap.put(in, writer);
95     else
96         GraphManager.writerMap.remove(in);
97     }
98
99     /**
100      * Set an external writer to use instead of the default one
101      */

102     public void setWriter(GraphManager.Writer writer) {
103         this.docWriter = writer;
104     }
105
106     public void setWriteCData(boolean value) {
107         writeCData = value;
108     }
109
110     public static Node createRootElementNode(String JavaDoc name) throws Schema2BeansRuntimeException {
111         String JavaDoc s = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n" +// NOI18N
112
"<" + name + "/>"; // NOI18N
113

114         ByteArrayInputStream in = new ByteArrayInputStream(s.getBytes());
115         Document doc = GraphManager.createXmlDocument(in, false);
116         NodeList children = doc.getChildNodes();
117         int length = children.getLength();
118         for (int i = 0; i < length; ++i) {
119             Node node = children.item(i);
120             if (node instanceof DocumentType) {
121                 //System.out.println("Found DocumentType where there should be none.");
122
doc.removeChild(node);
123                 --length;
124             }
125         }
126         return doc;
127     }
128
129     //
130
// Document created for this GraphManager. Called by the generated bean.
131
//
132
public void setXmlDocument(Node doc) throws Schema2BeansRuntimeException {
133     if (doc instanceof Document) {
134         this.document = (Document)doc;
135         this.setNodeFactory((Document)doc);
136
137         //
138
// The factory/writer should know about the doc now
139
// and no more about the original InputStream.
140
// (if the user specified a factory/writer)
141
//
142
Object JavaDoc o = GraphManager.factoryMap.get(doc);
143         if (o != null) {
144         this.docFactory = (GraphManager.Factory)o;
145         GraphManager.factoryMap.remove(doc);
146         }
147
148         o = GraphManager.writerMap.get(doc);
149         if (o != null) {
150         this.docWriter = (GraphManager.Writer)o;
151         GraphManager.writerMap.remove(doc);
152         }
153     }
154     else
155         throw new Schema2BeansRuntimeException(Common.getMessage(
156         "CantFindFactory_msg"));
157     }
158
159
160     /**
161      * This returns the DOM Document object, root
162      * of the current DOM graph. Operations that cause structural
163      * modifications to the DOM graph are not allowed. Indeed,
164      * modifying the DOM graph directly would cause the bean graph
165      * and its internal representation to be out of sync.
166      */

167     public Document getXmlDocument() {
168     return this.document;
169     }
170
171     public void setDoctype(String JavaDoc publicId, String JavaDoc systemId) {
172         //System.out.println("GraphManager.setDoctype: publicId="+publicId+" systemId="+systemId);
173
this.docTypePublic = publicId;
174     this.docTypeSystem = systemId;
175     }
176
177     /**
178      * Parse the DOM tree until the element named 'name' is found.
179      * Return the node of the name or null if not found.
180      * This method is used by the root bean generated class to get
181      * the root element of the DOM tree and start building the
182      * bean graph from here.
183      */

184     public static Node getElementNode(String JavaDoc name, Node doc) {
185     Node n;
186     for (n = doc.getFirstChild(); n != null; n = n.getNextSibling()) {
187         if (n.getNodeType() == Node.ELEMENT_NODE
188         && n.getNodeName().equals(name)) {
189         break;
190         }
191     }
192     return n;
193     }
194
195     /**
196      * This method is called by the createRoot() method of the root bean
197      * (part of the BaseBean class). The doc might not be available
198      * at the time of this call. In such a case, the method
199      * completeRootBinding is called afterwards with the doc value to complete
200      * the setup of the root.
201      *
202      * This makes sure that the root element of the object bindings
203      * between the beans and the DOM Nodes is created, before that the
204      * recursing creation of the graph begins.
205      */

206     public void createRootBinding(BaseBean beanRoot, BeanProp prop, Node doc) throws Schema2BeansException {
207     prop.registerDomNode(doc, null, beanRoot);
208     if (doc != null)
209         this.bindingsMap.put(doc, beanRoot.binding);
210     }
211
212     public void completeRootBinding(BaseBean beanRoot, Node doc) {
213     this.bindingsMap.put(doc, beanRoot.binding);
214     beanRoot.binding.setNode(doc);
215     }
216
217     /**
218      * This method sets the DOM nodes factory.
219      */

220     public void setNodeFactory(Document doc) {
221     this.factory = new NodeFactory(doc);
222     }
223
224     /**
225      * Return the DOM node factory
226      */

227     public NodeFactory getNodeFactory() {
228     return this.factory;
229     }
230
231     /**
232      * Return the root of the bean graph
233      */

234     public BaseBean getBeanRoot() {
235     return this.root;
236     }
237
238     /**
239      * OutputStream version of write()
240      */

241     void write(OutputStream out) throws IOException, Schema2BeansException {
242         //
243
// Code specific to the DOM implementation:
244
//
245
if (this.document == null)
246             throw new Schema2BeansException(Common.getMessage("CantGetDocument_msg"));
247         if (this.docWriter != null)
248             this.docWriter.write(out, this.document);
249         else {
250             XMLUtil.DOMWriter domWriter = getDOMWriter();
251             domWriter.write(out, document);
252         }
253     }
254
255     protected void write(OutputStream out, String JavaDoc encoding) throws java.io.IOException JavaDoc {
256         XMLUtil.DOMWriter domWriter = getDOMWriter();
257         domWriter.write(out, encoding, document);
258     }
259
260     protected void write(java.io.Writer JavaDoc out) throws java.io.IOException JavaDoc {
261         XMLUtil.DOMWriter domWriter = getDOMWriter();
262         domWriter.setWriter(out);
263         domWriter.write(document);
264     }
265
266     protected void write(java.io.Writer JavaDoc out, String JavaDoc encoding) throws java.io.IOException JavaDoc {
267         XMLUtil.DOMWriter domWriter = getDOMWriter();
268         domWriter.setWriter(out);
269         domWriter.write(document, encoding);
270     }
271
272     public void write(java.io.Writer JavaDoc out, Node node) throws java.io.IOException JavaDoc, Schema2BeansException {
273         XMLUtil.DOMWriter domWriter = getDOMWriter();
274         domWriter.setWriter(out);
275         domWriter.write(node);
276     }
277
278     protected XMLUtil.DOMWriter getDOMWriter() {
279         XMLUtil.DOMWriter domWriter = new XMLUtil.DOMWriter();
280         domWriter.setDocTypePublic(docTypePublic);
281         domWriter.setDocTypeSystem(docTypeSystem);
282         domWriter.setWriteCData(writeCData);
283         return domWriter;
284     }
285
286     /**
287      * Take the current DOM tree and readjust whitespace so that it
288      * looks pretty.
289      */

290     public void reindent(String JavaDoc indent) {
291         XMLUtil.reindent(document, indent);
292     }
293
294     /**
295      * Indent by 2 spaces for every @level.
296      */

297     protected static void printLevel(java.io.Writer JavaDoc out, int level, String JavaDoc indent) throws java.io.IOException JavaDoc {
298         StringBuffer JavaDoc outBuf = new StringBuffer JavaDoc();
299         printLevel(outBuf, level, indent);
300         out.write(outBuf.toString());
301     }
302
303     protected static void printLevel(StringBuffer JavaDoc out, int level, String JavaDoc indent) {
304         for (int i = 0; i < level; ++i) {
305             out.append(indent);
306         }
307     }
308
309     protected static void printLevel(java.io.Writer JavaDoc out, int level, String JavaDoc indent, String JavaDoc text) throws java.io.IOException JavaDoc {
310         StringBuffer JavaDoc outBuf = new StringBuffer JavaDoc();
311         printLevel(outBuf, level, indent, text);
312         out.write(outBuf.toString());
313     }
314
315     protected static void printLevel(OutputStream out, int level, String JavaDoc indent, String JavaDoc text) throws java.io.IOException JavaDoc {
316         OutputStreamWriter w = new OutputStreamWriter(out);
317         printLevel(w, level, indent, text);
318         w.flush();
319     }
320
321     protected static void printLevel(StringBuffer JavaDoc out, int level,
322                                      String JavaDoc indent, String JavaDoc text) {
323         printLevel(out, level, indent);
324         out.append(text);
325     }
326
327     /**
328      * Creates a DOM document from the input stream.
329      */

330     public static Document createXmlDocument(InputStream in, boolean validate) throws Schema2BeansRuntimeException {
331     return createXmlDocument(in, validate, null);
332     }
333
334     private static InputStream tee(InputStream in) throws IOException {
335         byte[] buf = new byte[4096];
336         ByteArrayOutputStream ba = new ByteArrayOutputStream();
337         int totalLength = 0;
338         int len;
339         while ((len = in.read(buf, 0, 4096)) > 0) {
340             ba.write(buf, 0, len);
341             totalLength += len;
342         }
343         System.out.println("schema2beans: in (length="+totalLength+"):");
344         System.out.println(ba.toString());
345         ByteArrayInputStream bain = new ByteArrayInputStream(ba.toByteArray());
346         return bain;
347     }
348
349     /**
350      * Creates a DOM document from the input stream.
351      */

352     public static Document createXmlDocument(InputStream in, boolean validate,
353                                              EntityResolver er) throws Schema2BeansRuntimeException {
354         if (in == null)
355             throw new IllegalArgumentException JavaDoc("in == null"); // NOI18N
356
try {
357             if (DDLogFlags.debug) {
358                 // Dump the contents to stdout
359
in = tee(in);
360             }
361
362             //
363
// Change the references to map the newly created doc
364
// The BaseBean instance is not created yet. The doc
365
// document will be used to get back the factories.
366
//
367
Object JavaDoc o = GraphManager.factoryMap.get(in);
368             if (o != null) {
369                 GraphManager.Factory f = (GraphManager.Factory)o;
370
371                 Document doc = f.createDocument(in, validate);
372
373                 GraphManager.factoryMap.remove(in);
374                 GraphManager.factoryMap.put(doc, o);
375
376                 Object JavaDoc o2 = GraphManager.writerMap.get(in);
377                 if (o2 != null) {
378                     GraphManager.writerMap.remove(in);
379                     GraphManager.writerMap.put(doc, o2);
380                 }
381                 return doc;
382             }
383             else {
384                 return createXmlDocument(new InputSource(in), validate, er, null);
385             }
386         } catch (Schema2BeansException e) {
387             throw new Schema2BeansRuntimeException(e);
388         } catch (IOException e) {
389             throw new Schema2BeansRuntimeException(e);
390         }
391     }
392
393
394     public static Document createXmlDocument(InputSource in, boolean validate) throws Schema2BeansException {
395     return createXmlDocument(in, validate, null, null);
396     }
397
398
399     public static Document createXmlDocument(InputSource in, boolean validate,
400                                              EntityResolver er, ErrorHandler eh) throws Schema2BeansException {
401         if (in == null)
402             throw new IllegalArgumentException JavaDoc("in == null"); // NOI18N
403
if (validate == false && er == null) {
404             // The client is not interested in any validation, so make
405
// see to it that any entity resolution doesn't hit the network
406
er = NullEntityResolver.newInstance();
407         }
408         try {
409             // Build a Document using JAXP
410
DocumentBuilderFactory JavaDoc dbf =
411                 DocumentBuilderFactory.newInstance();
412             dbf.setValidating(validate);
413
414             DocumentBuilder JavaDoc db = dbf.newDocumentBuilder();
415             if (er != null)
416                 db.setEntityResolver(er);
417             if (eh != null)
418                 db.setErrorHandler(eh);
419
420             if (DDLogFlags.debug) {
421                 System.out.println("createXmlDocument: validate="+validate+" dbf="+dbf+" db="+db+" er="+er);
422             }
423
424             return db.parse(in);
425         } catch (javax.xml.parsers.ParserConfigurationException JavaDoc e) {
426             throw new Schema2BeansNestedException(Common.getMessage("CantCreateXMLDOMDocument_msg"), e);
427         } catch (org.xml.sax.SAXException JavaDoc e) {
428             throw new Schema2BeansNestedException(Common.getMessage("CantCreateXMLDOMDocument_msg"), e);
429         } catch (IOException e) {
430             throw new Schema2BeansNestedException(Common.getMessage("CantCreateXMLDOMDocument_msg"), e);
431         }
432     }
433
434     /**
435      * This method is called by the generated beans when they are
436      * building themselves from a DOM tree.
437      * Typically, the first root bean calls this method with the
438      * DOM root node and the list of the properties that are expected
439      * under this node.
440      * This method parses the DOM sub-node of the node and matches their names
441      * with the names of the properties. When a match is found, the
442      * bean property object is called with the node found. If the node
443      * has no match in the bean properties, the node is ignored but
444      * the event is logged as it might reveal a problem in the bean tree
445      * (DTD element missing in the bean class graph).
446      *
447      */

448     public void fillProperties(BeanProp[] prop, Node node) throws Schema2BeansException {
449         BaseBean bean;
450         DOMBinding binding, newBinding;
451
452         if (prop == null || node == null)
453             return;
454
455         if (this.bindingsMap.get(node) == null) {
456             throw new Schema2BeansException(Common.getMessage(
457                                                               "CurrentNodeHasNoBinding_msg", new Integer JavaDoc(node.hashCode())));
458         }
459
460         // Store the property's dtdName's into a map for fast lookup,
461
// and be able to handle multiple properties with the same name.
462
Map dtdName2Prop = new HashMap(); // Map<String, BeanProp>
463
Map dupDtdNames = new HashMap(); // Map<String, List<BeanProp>>
464
for(int i=0; i<prop.length; i++) {
465             String JavaDoc dtdName = prop[i].dtdName;
466             if (dtdName2Prop.containsKey(dtdName)) {
467                 //System.out.println("Found duplicate dtdName="+dtdName);
468
List dupList = (List) dupDtdNames.get(dtdName);
469                 if (dupList == null) {
470                     dupList = new ArrayList();
471                     //dupList.add(dtdName2Prop.get(dtdName));
472
dupDtdNames.put(dtdName, dupList);
473                 }
474                 dupList.add(prop[i]);
475             } else {
476                 dtdName2Prop.put(dtdName, prop[i]);
477             }
478         }
479
480         // Assume that the DOM parsing takes longer than prop parsing
481
Map dupDtdNameIterators = new HashMap(); // Map<String, Iterator<BeanProp>>
482
for (Node n = node.getFirstChild(); n != null; n = n.getNextSibling()) {
483             if (n.getNodeType() == Node.ELEMENT_NODE) {
484                 String JavaDoc eltName = n.getNodeName();
485
486                 //System.out.println("eltName="+eltName);
487
BeanProp matchingProp = (BeanProp) dtdName2Prop.get(eltName);
488                 if (matchingProp != null) {
489                     List dupList = (List) dupDtdNames.get(eltName);
490                     if (dupList != null) {
491                         // There are mutliple BeanProp's with the same dtd name,
492
// figure out which one we should pick.
493
if (!Common.isArray(matchingProp.type)) {
494                             Iterator propIt = (Iterator) dupDtdNameIterators.get(eltName);
495                             //System.out.println("propIt="+propIt);
496
if (propIt == null) {
497                                 // First time, let the matchingProp load it,
498
// but set it up for next time.
499
propIt = dupList.iterator();
500                                 dupDtdNameIterators.put(eltName, propIt);
501                             } else if (propIt.hasNext()) {
502                                 matchingProp = (BeanProp) propIt.next();
503                             }
504                         }
505                     }
506                     binding = (DOMBinding)this.bindingsMap.get(n);
507
508                     if (DDLogFlags.debug) {
509                         String JavaDoc s = eltName + " N(" + n.hashCode()+") - " +
510                             (binding==null?"new node":"already bound B(" +
511                              binding.hashCode() +")");
512                         TraceLogger.put(TraceLogger.DEBUG,
513                                         TraceLogger.SVC_DD,
514                                         DDLogFlags.DBG_BLD, 1,
515                                         DDLogFlags.FOUNDNODE, s);
516                     }
517
518                     newBinding =
519                         matchingProp.registerDomNode(n, binding, null);
520
521                     if (newBinding != null) {
522
523                         if (Common.isBean(matchingProp.type))
524                             bean = (BaseBean)newBinding.getBean(matchingProp);
525                         else
526                             bean = null;
527
528                         if (DDLogFlags.debug) {
529                             String JavaDoc s = "B(" + newBinding.hashCode() +
530                                 ") - " + matchingProp.getPropClass().getName();
531                             TraceLogger.put(TraceLogger.DEBUG,
532                                             TraceLogger.SVC_DD,
533                                             DDLogFlags.DBG_BLD, 1,
534                                             DDLogFlags.BOUNDNODE, s);
535                         }
536
537                         if (bean != null) {
538                             //
539
// The property was a bean, fill up this bean.
540
// This is were the recursing call in the
541
// creation of the bean graph happens.
542
//
543
if (binding == null)
544                                 this.bindingsMap.put(n, newBinding);
545                             bean.createBean(n, this);
546                         }
547                     }
548                 } else {
549                     // log that there is no matching
550
if (DDLogFlags.debug) {
551                         TraceLogger.put(TraceLogger.DEBUG,
552                                         TraceLogger.SVC_DD,
553                                         DDLogFlags.DBG_BLD, 1,
554                                         DDLogFlags.NONODE, eltName);
555                     }
556                 }
557             } else {
558                 // Log that this is not an element
559
short t = n.getNodeType();
560                 String JavaDoc v = n.getNodeValue();
561                 if (DDLogFlags.debug) {
562                     TraceLogger.put(TraceLogger.DEBUG,
563                                     TraceLogger.SVC_DD,
564                                     DDLogFlags.DBG_BLD, 1,
565                                     DDLogFlags.NOTELT,
566                                     DDFactory.typeToString(t) +
567                                     " = " + Common.dumpHex(v));
568                 }
569             }
570         }
571     }
572
573     //////////////////////
574
//
575
// Event misc. methods, base on the name of the PropertyChanged event
576
//
577
// BaseBean getPropertyParent(String name)
578
// String getPropertyParentName(String name)
579
// String getPropertyName(String name)
580
// int getPropertyIndex(String name)
581
// String getAttributeName(String name)
582
// boolean isAttribute(String name)
583
//
584

585     /**
586      * Return the bean holding the property 'name' as a BaseBean object
587      */

588     public BaseBean getPropertyParent(String JavaDoc name) {
589         return (BaseBean) getPropertyParent(root, name);
590     }
591
592     public static Bean getPropertyParent(Bean theRoot, String JavaDoc name) {
593         String JavaDoc[] path = name.split("/", -1); // NOI18N
594
int n = path.length;
595         if (n < 2 || path[0].length() > 0) {
596             throw new IllegalArgumentException JavaDoc(Common.getMessage("NameShouldStartWithSlash_msg", name));
597         }
598         if (n == 2) {
599             return null;
600         }
601         Bean curBean = theRoot;
602         for (int i = 2; i < n - 1; i++) {
603             String JavaDoc[] element = path[i].split("[.]", 2); // NOI18N
604
String JavaDoc beanName = element[0];
605             int index;
606             if (element.length == 1) {
607                 index = 0;
608             } else {
609                 String JavaDoc indexName = element[1];
610                 if (indexName.indexOf('i') != -1) {
611                     throw new IllegalStateException JavaDoc(
612                             Common.getMessage("CantFindBeanBecausePartOfNameRemoved_msg", beanName, name));
613                 }
614                 index = Integer.parseInt(indexName, 16);
615             }
616             curBean = curBean.propertyById(beanName, index);
617             if (curBean == null) {
618                 throw new IllegalStateException JavaDoc(
619                         Common.getMessage("CantFindBeanMayHaveBeenRemoved_msg", beanName, name));
620             }
621         }
622         return curBean;
623     }
624     
625     public String JavaDoc getKeyPropertyName(String JavaDoc propName, String JavaDoc[] prop,
626                      String JavaDoc[] key) {
627     return this.getKeyPropertyName(propName, prop, key, false);
628     }
629
630     public String JavaDoc getKeyPropertyName(String JavaDoc propName) {
631     return this.getKeyPropertyName(propName, null, null, true);
632     }
633
634     /**
635      * Return the bean holding the property 'name' as a BaseBean object
636      */

637     public String JavaDoc getKeyPropertyName(String JavaDoc propName, String JavaDoc[] prop,
638                      String JavaDoc[] key, boolean keyName) {
639         return getKeyPropertyName(root, propName, prop, key, keyName);
640     }
641
642     public static String JavaDoc getKeyPropertyName(Bean theRoot,
643                                             String JavaDoc propName, String JavaDoc[] prop,
644                                             String JavaDoc[] key, boolean keyName) {
645
646     StringBuffer JavaDoc keyPropName = new StringBuffer JavaDoc();
647     Bean curBean = theRoot;
648     String JavaDoc beanName, indexName;
649     String JavaDoc name = propName;
650
651     if (name.charAt(0) == '/')
652         name = name.substring(1);
653
654     do {
655         int i = name.indexOf('/');
656         if (i != -1) {
657         beanName = name.substring(0, i);
658         name = name.substring(i+1);
659         }
660         else {
661         beanName = name;
662         name = null;
663         }
664
665         i = beanName.indexOf('.');
666
667         if (i != -1) {
668         indexName = beanName.substring(i+1);
669         beanName = beanName.substring(0, i);
670
671         if (indexName.indexOf('i') != -1)
672             throw new IllegalStateException JavaDoc(
673             Common.getMessage(
674             "CantFindBeanBecausePartOfNameRemoved_msg",
675             beanName, propName));
676         }
677         else
678         indexName = "0"; // NOI18N
679

680
681         if (theRoot.hasName(beanName)) {
682             curBean = theRoot;
683         } else {
684         if (curBean.getProperty(beanName).isBean()) {
685             curBean = curBean.propertyById(beanName,
686                            Integer.parseInt(indexName,
687                                     16));
688         } else
689             curBean = null;
690         }
691
692         keyPropName.append(beanName);
693
694         if (prop != null && curBean != null) {
695         // If a property name/key is defined, add it to the path
696
for (i=0; i<prop.length; i++) {
697             if (prop[i].equals(beanName)) {
698             keyPropName.append("."); // NOI18N
699
keyPropName.append(key[i]);
700             keyPropName.append("="); // NOI18N
701
String JavaDoc v = (String JavaDoc)curBean.getValue(key[i], 0);
702             if (v != null)
703                 keyPropName.append(v);
704             break;
705             }
706         }
707         } else if (keyName && curBean != null) {
708         // If any property has 'name', use it
709
BaseProperty[] l = curBean.listProperties();
710         for (i=0; i<l.length; i++) {
711             String JavaDoc n = l[i].getName();
712             if (n.toLowerCase().indexOf("name") != -1) { // NOI18N
713
keyPropName.append("."); // NOI18N
714
keyPropName.append(n);
715             keyPropName.append("="); // NOI18N
716
String JavaDoc v = (String JavaDoc)curBean.getValue(n, 0);
717             if (v != null)
718                 keyPropName.append(v);
719             break;
720             }
721         }
722         }
723
724         if (name != null)
725         keyPropName.append("/"); // NOI18N
726

727     } while (name != null && curBean != null);
728
729     return keyPropName.toString();
730     }
731
732
733     /**
734      * Return the bean holding the property 'name' as a BaseBean object
735      */

736     public static String JavaDoc trimPropertyName(String JavaDoc propName) {
737     StringBuffer JavaDoc name = new StringBuffer JavaDoc();
738     int i, j;
739     i = 0;
740     do {
741         j = propName.indexOf('.', i);
742         if (j==-1) {
743         name.append(propName.substring(i));
744         } else {
745         name.append(propName.substring(i, j));
746         i = propName.indexOf('/', j);
747         }
748     } while(j!=-1 && i!=-1);
749
750     return name.toString();
751     }
752
753     /**
754      * Return the name of the bean holding the property 'name'
755      */

756     public static String JavaDoc getPropertyParentName(String JavaDoc name) {
757     int i = name.lastIndexOf('/');
758     if (i != -1)
759         name = name.substring(0, i);
760     i = name.lastIndexOf('/');
761     if (i != -1)
762         name = name.substring(i+1);
763     i = name.lastIndexOf('.');
764     if (i != -1)
765         name = name.substring(0, i);
766
767     return name;
768     }
769
770     /**
771      * Return the name of the property of the PropertyChangeEvent named name.
772      * Any index or attribute is removed from the name of the event.
773      *
774      * single property: /Book/Chapter.2/Comment -> Comment
775      * indexed property: /Book/Chapter.4 -> Chapter
776      * attribute: /Book/Chapter.2:title -> Chapter
777      *
778      */

779     public static String JavaDoc getPropertyName(String JavaDoc name) {
780     int i = name.lastIndexOf('/');
781     if (i != -1)
782         name = name.substring(i+1);
783     // Remove the index value
784
i = name.lastIndexOf('.');
785     if (i != -1)
786         name = name.substring(0, i);
787     // If there is a still an attribute, remove it
788
i = name.lastIndexOf(':');
789     if (i != -1)
790         name = name.substring(0, i);
791
792     return name;
793     }
794
795     /**
796      * Return the name of the attribute if this is the name of an attribute,
797      * return null otherwise.
798      *
799      * single property: /Book/Chapter.2/Comment -> null
800      * indexed property: /Book/Chapter.4 -> null
801      * attribute: /Book/Chapter.2:title -> title
802      *
803      */

804     public String JavaDoc getAttributeName(String JavaDoc name) {
805     int i = name.lastIndexOf(':');
806     if (i != -1)
807         name = name.substring(i+1);
808     else
809         name = null;
810     return name;
811     }
812
813     /**
814      * Return true if this is the name of an attribute
815      */

816     public boolean isAttribute(String JavaDoc name) {
817     int i = name.lastIndexOf(':');
818     return (i != -1);
819     }
820
821     /**
822      * Return the index value of the property, as a string
823      */

824     private static String JavaDoc extractPropertyIndex(String JavaDoc name) {
825     int i = name.lastIndexOf('/');
826     if (i != -1)
827         name = name.substring(i+1);
828     i = name.lastIndexOf('.');
829     if (i != -1) {
830         name = name.substring(i+1);
831         i = name.lastIndexOf(':');
832         if (i != -1)
833         name = name.substring(0, i);
834     }
835     else
836         name = null;
837     return name;
838     }
839
840
841     /**
842      * If the property is an indexed property, return the index of
843      * the property.
844      */

845     public int getPropertyIndex(String JavaDoc name) {
846         return getPropertyIndex(root, name);
847     }
848     public static int getPropertyIndex(Bean theRoot, String JavaDoc name) {
849         String JavaDoc index = extractPropertyIndex(name);
850         if (index != null) {
851             int i = index.lastIndexOf('i');
852             if (i != -1) {
853                 // This is a removed property - return the old value
854
return Integer.parseInt(index.substring(i+1));
855             }
856             else {
857                 // Get the current index value
858
Bean bean = getPropertyParent(theRoot, name);
859                 if (bean != null) {
860                     BeanProp bp = bean.beanProp(getPropertyName(name));
861
862                     if (bp != null)
863                         return bp.idToIndex(Integer.parseInt(index, 16));
864                 }
865             }
866         }
867     
868         return -1;
869     }
870     
871     //
872
// Events misc. methods
873
//
874
/////////////////////////////
875

876     static public void debug(boolean d) {
877     DDLogFlags.debug = d;
878     }
879     
880     //
881
// Default values for scalar types. The idea is to allow the user to
882
// change the following default values (TODO).
883
//
884
public Object JavaDoc defaultScalarValue(int type) {
885     switch(type & Common.MASK_TYPE) {
886         case Common.TYPE_STRING:
887         return ""; // NOI18N
888
case Common.TYPE_BOOLEAN:
889         return Boolean.FALSE;
890         case Common.TYPE_BYTE:
891         return new Byte JavaDoc((byte)0);
892         case Common.TYPE_CHAR:
893         return new Character JavaDoc('\0');
894         case Common.TYPE_SHORT:
895         return new Short JavaDoc((short)0);
896         case Common.TYPE_INT:
897         return new Integer JavaDoc(0);
898         case Common.TYPE_LONG:
899         return new Long JavaDoc(0);
900         case Common.TYPE_FLOAT:
901         return new Float JavaDoc(0.0);
902         case Common.TYPE_DOUBLE:
903         return new Double JavaDoc(0.0);
904         default:
905             throw new IllegalArgumentException JavaDoc(Common.getMessage("UnknownType", type));
906     }
907     }
908 }
909
910
Popular Tags