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-2006 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:
042: /*
043: * XMLBean.java
044: *
045: * Created on October 31, 2001, 2:47 PM
046: */
047:
048: package org.netbeans.xtest.pe.xmlbeans;
049:
050: import org.w3c.dom.*;
051: import java.io.*;
052: import javax.xml.parsers.*;
053: import org.netbeans.xtest.util.XMLFactoryUtil;
054: import org.netbeans.xtest.util.XMLWriter;
055: import org.xml.sax.SAXException;
056:
057: import java.util.*;
058: import java.lang.reflect.*;
059:
060: /**
061: * name of the class = name of the XML element
062: * currently - all beans must exist in the same package as XMLBean :-(
063: * attributes = public variables beginning with xml keyword
064: *
065: * @author mb115822
066: */
067: public abstract class XMLBean {
068:
069: public final static String[] XMLBEAN_PACKAGES = {
070: "org.netbeans.xtest.pe.xmlbeans",
071: "org.netbeans.xtest.pes.xmlbeans" };
072: public final static String XMLBEAN_ATT_PREFIX = "xmlat_";
073: public final static String XMLBEAN_ELEM_PREFIX = "xmlel_";
074: public final static String XMLBEAN_FILE_SUFFIX = ".xml";
075:
076: // debugging flag - should be set to false :-)
077: private static final boolean DEBUG = false;
078:
079: private static final void debugInfo(String message) {
080: if (DEBUG)
081: System.out.println("XMLBean." + message);
082: }
083:
084: public static final int ALL_ELEMENTS = -1;
085:
086: // pcdata of the XML element
087: public String xml_pcdata = null;
088: // cdata of the XML element
089: public String xml_cdata = null;
090:
091: /** Holds value of property id. */
092: private long id;
093:
094: // utility methods
095: public static Object[] addToArray(Object[] array, Object[] objs)
096: throws IllegalArgumentException {
097: debugInfo("addToArray(): array = " + array
098: + " objects to add = " + objs);
099: Object resultingArray;
100: int length = 0;
101: if (array == null) {
102: if ((objs == null)
103: | ((objs.length > 0) & (objs[0] == null))) {
104: debugInfo("addToArray(): both array and obj are null - there is nothing to do - return null");
105: return null;
106: } else {
107: debugInfo("addToArray(): array is null, but we can construct a new array with just one object");
108: resultingArray = Array.newInstance(objs[0].getClass(),
109: objs.length);
110: }
111: } else {
112: if (objs == null) {
113: debugInfo("addToArray(): objs is null - there is nothing to do - return the existing array");
114: return array;
115: } else {
116: debugInfo("addToArray(): adding to existing array");
117: Class arrayType = array.getClass().getComponentType();
118: length = array.length;
119: debugInfo("addToArray(): discovered array componennt type = "
120: + arrayType + " and length = " + length);
121: resultingArray = Array.newInstance(arrayType, length
122: + objs.length);
123: debugInfo("addToArray(): copying old array to new one ");
124: for (int i = 0; i < length; i++) {
125: Array.set(resultingArray, i, array[i]);
126: }
127: }
128: }
129:
130: debugInfo("addToArray(): adding the new objects at the end (position = "
131: + length + ")");
132: for (int i = 0; i < objs.length; i++) {
133: Array.set(resultingArray, length + i, objs[i]);
134: }
135: return (Object[]) resultingArray;
136: }
137:
138: // wrapper for a single object
139: public static Object[] addToArray(Object[] array, Object obj)
140: throws IllegalArgumentException {
141: if (obj != null) {
142: Object objArray = Array.newInstance(obj.getClass(), 1);
143: Array.set(objArray, 0, obj);
144: return addToArray(array, objArray);
145: } else {
146: return array;
147: }
148: }
149:
150: public static Object[] shrinkArray(Object[] array) {
151: if (array == null) {
152: return null;
153: } else {
154: int length = 0;
155: for (int i = 0; i < array.length; i++) {
156: if (array[i] != null) {
157: length++;
158: }
159: }
160: // construct the new array
161: Class arrayType = array.getClass().getComponentType();
162: Object resultingArray = Array
163: .newInstance(arrayType, length);
164: // now copy the old array to the shrinked one
165: for (int i = 0, j = 0; i < array.length; i++) {
166: if (array[i] != null) {
167: Array.set(resultingArray, j, array[i]);
168: j++;
169: }
170: }
171: // finally - return the array
172: return (Object[]) resultingArray;
173: }
174:
175: }
176:
177: public boolean isObjectValid(Object obj) {
178: if (obj != null) {
179: if (obj.getClass().isInstance(this )) {
180: return true;
181: }
182: }
183: return false;
184: }
185:
186: public static boolean equalObjectsByFields(Object obj1,
187: Object obj2, String[] fieldNames)
188: throws NoSuchFieldException {
189: debugInfo("compareObjectsByFields(): start");
190: if (fieldNames != null) {
191: if (fieldNames.length > 0) {
192: // now compare objects
193: try {
194: if (obj1.getClass().isInstance(obj2)) {
195: debugInfo("compareObjectsByFields(): objects are of the same type");
196: for (int i = 0; i < fieldNames.length; i++) {
197: Field field = obj1.getClass().getField(
198: fieldNames[i]);
199: debugInfo("compareObjectsByFields(): comparing field"
200: + field.getName());
201: Object value1 = field.get(obj1);
202: Object value2 = field.get(obj2);
203: if ((value1 == null) | (value2 == null)) {
204: debugInfo("compareObjectsByFields(): comparing for null");
205: if ((value1 == null) & (value2 == null)) {
206: debugInfo("compareObjectsByFields(): both values are null");
207: } else {
208: debugInfo("compareObjectsByFields(): comparing for null, but 2nd value is not null");
209: return false;
210: }
211: } else {
212: if (!value1.equals(value2)) {
213: debugInfo("compareObjectsByFields(): values differ, fieldName = "
214: + fieldNames[i]);
215: debugInfo("compareObjectsByFields(): value1="
216: + value1
217: + "; value2="
218: + value2);
219: return false;
220: }
221: }
222: }
223: debugInfo("compareObjectsByFields(): all fields are equal - true");
224: return true;
225: } else {
226: debugInfo("compareObjectsByFields(): objects are not of the same type - false");
227: return false;
228: }
229: } catch (NullPointerException npe) {
230: // there was some problem -> objects are not equal
231: debugInfo("compareObjectsByFields(): there was NPE, hence objects are not equal");
232: return false;
233: } catch (IllegalAccessException iae) {
234: debugInfo("compareObjectsByFields(): there was IllegalAccessException, throwing NoSuchFieldException");
235: throw new NoSuchFieldException(
236: " thrown IllegalAccessException: " + iae);
237: }
238: }
239: }
240: debugInfo("compareObjectsByFields(): throwing NoSuchAFieldException - fieldNames string is empty !!!");
241: throw new NoSuchFieldException(" No fields were specified");
242: }
243:
244: public boolean equalByAttributes(Object obj) {
245: debugInfo("equalByAttribues(): comparing XMLBean to another XMLBean by all its XML attributes");
246: try {
247: ArrayList attributeFieldList = new ArrayList();
248: Field[] fields = this .getClass().getFields();
249: for (int i = 0; i < fields.length; i++) {
250: Field field = fields[i];
251: if (field.getName().startsWith(
252: XMLBean.XMLBEAN_ATT_PREFIX)) {
253: attributeFieldList.add(field.getName());
254: }
255: }
256: String[] fieldNames = (String[]) (attributeFieldList
257: .toArray(new String[0]));
258: debugInfo("equalByAttribues(): got field names -> comparing");
259: return equalObjectsByFields(this , obj, fieldNames);
260: // get all fields
261: } catch (NoSuchFieldException nsfe) {
262: // this should not happen
263: debugInfo("equalByAttribues(): NoSuchFieldException - weird: "
264: + nsfe);
265: return false;
266: }
267: }
268:
269: public static XMLBean findXMLBean(XMLBean[] existingBeans,
270: XMLBean newBean) {
271: debugInfo("findXMLBean(): existingBeans = " + existingBeans
272: + ", newBean = " + newBean);
273: if (newBean == null) {
274: debugInfo("findXMLBean(): newBean is null - cannot find null :-)");
275: return null;
276: }
277: if (existingBeans == null) {
278: debugInfo("findXMLBean(): existingBeans is null - what shoud I compare :-)");
279: return null;
280: }
281: debugInfo("findXMLBean(): lets look for a bean ");
282: for (int i = 0; i < existingBeans.length; i++) {
283: if (newBean.equals(existingBeans[i])) {
284: debugInfo("addOrFindEqualBean():, found equal XMLBean");
285: return existingBeans[i];
286: }
287: }
288: return null;
289: }
290:
291: public static String cutPackage(String className) {
292: if (DEBUG)
293: System.out.println("XMLBean.cutPackage: className = "
294: + className);
295: int lastDot = className.lastIndexOf('.');
296: if (lastDot != -1) {
297: return className.substring(lastDot + 1);
298: } else {
299: return className;
300: }
301: }
302:
303: public static String cutPrefix(String aString, String prefix) {
304: if (prefix != null) {
305: if (!prefix.equals("")) {
306: if (aString.startsWith(prefix)) {
307: return aString.substring(prefix.length());
308: }
309: }
310: }
311: return aString;
312: }
313:
314: //
315:
316: public static void setField(Field field, Object obj, String value)
317: throws IllegalArgumentException, IllegalAccessException {
318: String fieldTypeName = field.getType().getName();
319: if (fieldTypeName.equals("java.lang.String")) {
320: field.set(obj, value);
321: return;
322: }
323: if (fieldTypeName.equals("int")) {
324: field.setInt(obj, Integer.parseInt(value));
325: return;
326: }
327: if (fieldTypeName.equals("short")) {
328: field.setShort(obj, Short.parseShort(value));
329: return;
330: }
331:
332: if (fieldTypeName.equals("long")) {
333: field.setLong(obj, Long.parseLong(value));
334: return;
335: }
336:
337: if (fieldTypeName.equals("float")) {
338: field.setFloat(obj, Float.parseFloat(value));
339: return;
340: }
341:
342: if (fieldTypeName.equals("double")) {
343: field.setDouble(obj, Double.parseDouble(value));
344: return;
345: }
346:
347: if (fieldTypeName.equals("boolean")) {
348: field
349: .setBoolean(obj, Boolean.valueOf(value)
350: .booleanValue());
351: return;
352: }
353:
354: if (fieldTypeName.equals("java.sql.Date")) {
355: field.set(obj, java.sql.Date.valueOf(value));
356: return;
357: }
358:
359: if (fieldTypeName.equals("java.sql.Timestamp")) {
360: field.set(obj, java.sql.Timestamp.valueOf(value));
361: return;
362: }
363:
364: throw new IllegalArgumentException("field type '"
365: + fieldTypeName + "' not supported");
366:
367: }
368:
369: protected void fillAttributes(NamedNodeMap atts)
370: throws NoSuchFieldException {
371: for (int i = 0; i < atts.getLength(); i++) {
372: Node attribute = atts.item(i);
373: String attributeName = attribute.getNodeName();
374: // do we have such a attribute in XMLBean ?
375: Field attField = this .getClass().getField(
376: XMLBean.XMLBEAN_ATT_PREFIX + attributeName);
377: if (attField != null) {
378: String value = attribute.getNodeValue();
379: if (DEBUG)
380: System.out
381: .println("XMLBean.fillAttributes(): setting field:"
382: + attField.getName()
383: + " with value = " + value);
384: try {
385: XMLBean.setField(attField, this , value);
386: } catch (Exception e) {
387: // will this work ???
388: NoSuchFieldException nsfe = new NoSuchFieldException(
389: "Cannot set field in XMLBean");
390: nsfe.fillInStackTrace();
391: throw nsfe;
392: }
393: }
394: }
395: }
396:
397: protected void fillElements(NodeList elements, int depth)
398: throws NoSuchFieldException, ClassNotFoundException {
399: // if depth is zero, we don't want dig deeper
400: if (depth == 0)
401: return;
402: // otherwise continue with getting the bean
403: XMLBeanSet xmlBeans = new XMLBeanSet();
404: for (int i = 0; i < elements.getLength(); i++) {
405: Node elementNode = elements.item(i);
406: // is it really element ?
407: switch (elementNode.getNodeType()) {
408:
409: case Node.ELEMENT_NODE:
410: Element element = (Element) elementNode;
411: String elementName = elementNode.getNodeName();
412: if (DEBUG)
413: System.out
414: .println("XMLBean.fillElements(): Got child element:"
415: + elementName);
416: Field elemField = this .getClass().getField(
417: XMLBean.XMLBEAN_ELEM_PREFIX + elementName);
418: if (DEBUG)
419: System.out
420: .println("XMLBean.fillElements(): Got field:"
421: + elemField.getName());
422: if (elemField != null) {
423: // ok, lets get the XMLBean instance
424: XMLBean childBean = getXMLBean(element, depth - 1);
425: if (DEBUG)
426: System.out
427: .println("XMLBean.fillElements(): got ChildBean!!!"
428: + childBean);
429: // store it together with all other instances of this type
430: xmlBeans.addXMLBean(elemField, childBean);
431: }
432: break;
433: case Node.TEXT_NODE:
434: if (DEBUG)
435: System.out
436: .println("XMLBean.fillElements(): Got TEXT_NODE:"
437: + elementNode.getNodeValue());
438: this .xml_pcdata = elementNode.getNodeValue();
439: break;
440:
441: case Node.CDATA_SECTION_NODE:
442: if (DEBUG)
443: System.out
444: .println("XMLBean.fillElements(): Got CDATA_NODE:"
445: + elementNode.getNodeValue());
446: this .xml_cdata = elementNode.getNodeValue();
447: break;
448: default:
449: if (DEBUG)
450: System.out
451: .println("XMLBean.fillElements(): Got unsupported node:"
452: + elementNode.getNodeValue());
453: }
454: }
455:
456: if (DEBUG)
457: System.out
458: .println("XMLBean.fillElements(): all elements processed, now fill variables");
459:
460: // now we can fill the variables with beans ...
461: Field[] fieldsToFill = xmlBeans.getFields();
462: if (DEBUG)
463: System.out.println("XMLBean.fillElements(): processing "
464: + fieldsToFill + " fields, length = "
465: + fieldsToFill.length);
466: for (int i = 0; i < fieldsToFill.length; i++) {
467:
468: Field field = fieldsToFill[i];
469: if (DEBUG)
470: System.out.println("XMLBean.fillElements(): Field i"
471: + i + " field=" + field);
472: if (DEBUG)
473: System.out
474: .println("XMLBean.fillElements(): filling this field:"
475: + field.getName());
476: // get all XML beans instances to be stored in this field
477: XMLBean[] xmlBeanInstances = xmlBeans.getXMLBeans(field);
478: // store all instances in the field variable
479: Object xmlBeanArray = Array.newInstance(field.getType()
480: .getComponentType(), xmlBeanInstances.length);
481: System.arraycopy(xmlBeanInstances, 0, xmlBeanArray, 0,
482: xmlBeanInstances.length);
483: try {
484: field.set(this , xmlBeanArray);
485: } catch (IllegalAccessException iae) {
486: throw new NoSuchFieldException(
487: "Cannot access requested field");
488: }
489: }
490: }
491:
492: public static XMLBean getXMLBean(Document doc)
493: throws ClassNotFoundException {
494: return getXMLBean(doc, ALL_ELEMENTS);
495: }
496:
497: public static XMLBean getXMLBean(Document doc, int depth)
498: throws ClassNotFoundException {
499: Element element = doc.getDocumentElement();
500: return getXMLBean(element, depth);
501: }
502:
503: public static XMLBean getXMLBean(Element element)
504: throws ClassNotFoundException {
505: return getXMLBean(element, ALL_ELEMENTS);
506: }
507:
508: public static XMLBean getXMLBean(Element element, int depth)
509: throws ClassNotFoundException {
510: // if depth is zero, we don't want dig deeper
511: if (depth == 0)
512: return null;
513: // otherwise continue with getting the bean
514: String elName = element.getTagName();
515: Class xmlBeanClass = null;
516: XMLBean xmlBean = null;
517: // try to load class
518: for (int i = 0; i < XMLBEAN_PACKAGES.length; i++) {
519: try {
520: xmlBeanClass = Class.forName(XMLBEAN_PACKAGES[i] + "."
521: + elName);
522: break;
523: } catch (ClassNotFoundException cnfe) {
524: // nothing happened, try next package
525: }
526: }
527: if (xmlBeanClass == null) {
528: // class not found
529: throw new ClassNotFoundException("Cannot find class "
530: + elName + " in all XMLBean specified packages");
531: }
532:
533: if (DEBUG)
534: System.out.println("Trying to instintiate " + elName);
535: Object aBean = null;
536: try {
537: aBean = xmlBeanClass.newInstance();
538: } catch (IllegalAccessException iae) {
539: throw new ClassNotFoundException(
540: "Cannot instintiate class - illegal access: "
541: + xmlBeanClass);
542: } catch (InstantiationException ie) {
543: throw new ClassNotFoundException(
544: "Cannot instintiate class: " + xmlBeanClass);
545: }
546: // is the bean instance of xmlBean ?
547: if (!XMLBean.class.isInstance(aBean)) {
548: throw new ClassNotFoundException("class " + xmlBeanClass
549: + " is not instance of XMLBean");
550: }
551: // try to instantiate the class - must have a constructor with no arguments
552: xmlBean = (XMLBean) aBean;
553:
554: if (DEBUG)
555: System.out
556: .println("XMLBean.getXMLBean(): instintiated new XMLBean");
557: // now we have the bean - so lets get attributes and fill them :-).
558: NamedNodeMap atts = element.getAttributes();
559: if (atts != null) {
560: if (atts.getLength() != 0) {
561: try {
562: xmlBean.fillAttributes(atts);
563: if (DEBUG)
564: System.out
565: .println("XMLBean.getXMLBean(): got attributes");
566: } catch (NoSuchFieldException nsfe) {
567: throw new ClassNotFoundException(
568: "Cannot fill defined attributes", nsfe);
569: }
570: }
571: }
572:
573: // do we have any children - lets get them as beans ... (or set pcdata if applicable)
574: NodeList childElements = element.getChildNodes();
575: if (childElements != null) {
576: if (childElements.getLength() != 0) {
577: if (DEBUG)
578: System.out
579: .println("XMLBean.getXMLBean(): have to process childElements, size="
580: + childElements.getLength());
581: try {
582: xmlBean.fillElements(childElements, depth);
583: } catch (NoSuchFieldException nsfe) {
584: throw new ClassNotFoundException(
585: "Cannot fill children elements - no such a field exception");
586: }
587: }
588: }
589: return xmlBean;
590: }
591:
592: public Document toDocument() throws DOMException {
593: return toDocument(ALL_ELEMENTS);
594: }
595:
596: public Document toDocument(int depth) throws DOMException {
597: if (DEBUG)
598: System.out.println("XMLBean:toDocument() begin");
599: Document doc = getDocumentBuilder().newDocument();
600: Element element = this .toElement(doc, depth);
601: doc.appendChild(element);
602: return doc;
603: }
604:
605: public Element toElement(Document doc) throws DOMException {
606: return toElement(doc, ALL_ELEMENTS);
607: }
608:
609: public Element toElement(Document doc, int depth)
610: throws DOMException {
611: if (DEBUG)
612: System.out.println("XMLBean:toElement() begin, this="
613: + this + " depth=" + depth);
614: // if depth is zero, we don't want serialize anymore, so return null,
615: if (depth == 0)
616: return null;
617: // otherwise continue with serialization
618: // get the name of the class - it will be used as the name of the
619: String fullClassName = this .getClass().getName();
620: if (DEBUG)
621: System.out.println("XMLBean:toElement() fullClassName="
622: + fullClassName);
623: Package p = this .getClass().getPackage();
624: if (DEBUG)
625: System.out.println("XMLBean:toElement() package=" + p);
626: //String packageName = p.getName();
627: //if (DEBUG) System.out.println("XMLBean:toElement() packageName="+packageName);
628: // element tag
629: String className = cutPackage(fullClassName);
630: if (DEBUG)
631: System.out.println("XMLBean:toElement() - className="
632: + className);
633: Element element = doc.createElement(className);
634:
635: // do we have any pcdata ?
636: if (this .xml_pcdata != null) {
637: if (DEBUG)
638: System.out.println("XMLBean:toElement() adding PCDATA:"
639: + this .xml_pcdata);
640: Text textNode = doc.createTextNode(this .xml_pcdata);
641: //textNode.setNodeValue();
642: element.appendChild(textNode);
643: }
644:
645: if (this .xml_cdata != null) {
646: if (DEBUG)
647: System.out.println("XMLBean:toElement() adding CDATA:"
648: + this .xml_cdata);
649:
650: CDATASection cdataNode = doc
651: .createCDATASection(this .xml_cdata);
652: element.appendChild(cdataNode);
653: }
654:
655: // now search for variables and add attributes/elements
656: Field[] fields = this .getClass().getFields();
657: for (int i = 0; i < fields.length; i++) {
658: Field field = fields[i];
659: if (DEBUG)
660: System.out
661: .println("XMLBean:toElement(): processing field="
662: + field.getName());
663: // search for attribute
664: String fieldName = field.getName();
665: if (fieldName.startsWith(XMLBEAN_ATT_PREFIX)) {
666: String attributeName = cutPrefix(fieldName,
667: XMLBEAN_ATT_PREFIX);
668: Object fieldValue = null;
669: try {
670: fieldValue = field.get(this );
671: } catch (IllegalAccessException iae) {
672: throw new DOMException(Short.MIN_VALUE,
673: "Cannot access XMLBean's field:" + field);
674: }
675: if (fieldValue != null) {
676: String value = fieldValue.toString();
677: if (DEBUG)
678: System.out
679: .println("XMLBean:toElement(): got attribute value = "
680: + fieldValue);
681: element.setAttribute(attributeName, value);
682: } else {
683: // nothing
684: if (DEBUG)
685: System.out
686: .println("XMLBean:toElement(): field value = "
687: + fieldValue);
688: }
689: }
690: // search for element
691: if (fieldName.startsWith(XMLBEAN_ELEM_PREFIX)) {
692: Object value = null;
693: try {
694: value = field.get(this );
695: } catch (IllegalAccessException iae) {
696: throw new DOMException(Short.MIN_VALUE,
697: "Cannot access XMLBean's field:" + field);
698: }
699: if (value != null) {
700: if (field.getType().isArray()) {
701: int length = Array.getLength(value);
702: for (int j = 0; j < length; j++) {
703: Object xmlBeanObject = Array.get(value, j);
704: if (xmlBeanObject != null) {
705: if (xmlBeanObject instanceof XMLBean) {
706: Element childElement = ((XMLBean) xmlBeanObject)
707: .toElement(doc, depth - 1);
708: if (childElement != null) {
709: element
710: .appendChild(childElement);
711: }
712: } else {
713: if (DEBUG)
714: System.out
715: .println("XMLBean:toElement() object in the array is not instanceof XMLBean");
716: }
717: }
718: }
719: } else {
720: if (DEBUG)
721: System.out
722: .println("XMLBean:toElement() - cannot handle elements from non arrays");
723: }
724: }
725: }
726: }
727: // n
728:
729: return element;
730: }
731:
732: /** Getter for property id.
733: * @return Value of property id.
734: */
735: public long getId() {
736: return this .id;
737: }
738:
739: /** Setter for property id.
740: * @param id New value of property id.
741: */
742: public void setId(long id) {
743: this .id = id;
744: }
745:
746: // other utility methods
747:
748: // XMLBean loader ...
749: public static XMLBean loadXMLBean(File xmlBeanFile)
750: throws IOException, ClassNotFoundException {
751: return loadXMLBean(xmlBeanFile, ALL_ELEMENTS);
752: }
753:
754: // loader which allows to specify depth of elements to be loaded
755: public static XMLBean loadXMLBean(File xmlBeanFile, int depth)
756: throws IOException, ClassNotFoundException {
757: if (xmlBeanFile == null)
758: throw new IllegalArgumentException(
759: "parameter cannot be null");
760: if (!xmlBeanFile.isFile()) {
761: throw new IOException("File " + xmlBeanFile
762: + " is not a valid file, cannot load XMLBean");
763: }
764: // parse the file
765: try {
766: Document doc = getDocumentBuilder().parse(xmlBeanFile);
767: XMLBean xmlBean = XMLBean.getXMLBean(doc, depth);
768: return xmlBean;
769: } catch (SAXException se) {
770: throw new IOException("Cannot parse XML, because of :"
771: + se.getMessage());
772: }
773: }
774:
775: // save XMLBean
776: public void saveXMLBean(File xmlBeanFile) throws IOException {
777: saveXMLBean(xmlBeanFile, ALL_ELEMENTS);
778: }
779:
780: // save XMLBean which allows to specify depth of XML elements to be saved
781: public void saveXMLBean(File xmlBeanFile, int depth)
782: throws IOException {
783: Document doc = this .toDocument(depth);
784: serializeToFile(doc, xmlBeanFile);
785: }
786:
787: // DocumentBuilder
788: protected static DocumentBuilder getDocumentBuilder() {
789: try {
790: return XMLFactoryUtil.newDocumentBuilder();
791: } catch (Exception e) {
792: throw new ExceptionInInitializerError(e);
793: }
794: }
795:
796: // serialize to File
797: protected static void serializeToStream(Document doc,
798: OutputStream out) throws IOException {
799: XMLWriter xmlWriter = new XMLWriter(out, "UTF-8");
800: xmlWriter.write(doc);
801: //out.close();
802: }
803:
804: // serialize to File
805: protected static void serializeToFile(Document doc, File outFile)
806: throws IOException {
807: OutputStream out = new FileOutputStream(outFile);
808: serializeToStream(doc, out);
809: out.close();
810: }
811:
812: // helper class for storing already instantiated XMLBeans grouped by
813: // element types
814: public static class XMLBeanSet {
815:
816: private HashMap fields;
817:
818: public XMLBeanSet() {
819: fields = new HashMap();
820: }
821:
822: public void addXMLBean(Field field, XMLBean xmlBean) {
823: ArrayList xmlBeansInstances = (ArrayList) fields.get(field);
824: if (xmlBeansInstances != null) {
825: xmlBeansInstances.add(xmlBean);
826: } else {
827: xmlBeansInstances = new ArrayList();
828: xmlBeansInstances.add(xmlBean);
829: fields.put(field, xmlBeansInstances);
830: }
831: }
832:
833: public XMLBean[] getXMLBeans(Field field) {
834: ArrayList xmlBeansInstances = (ArrayList) fields.get(field);
835: if (xmlBeansInstances != null) {
836: return (XMLBean[]) (xmlBeansInstances
837: .toArray(new XMLBean[0]));
838: } else {
839: return null;
840: }
841: }
842:
843: public Field[] getFields() {
844: return (Field[]) (fields.keySet().toArray(new Field[0]));
845: }
846:
847: }
848:
849: }
|