2
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4
* Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
6
* The contents of this file are subject to the terms of either the GNU
7
* General Public License Version 2 only ("GPL") or the Common
8
* Development and Distribution License("CDDL") (collectively, the
9
* "License"). You may not use this file except in compliance with the
10
* License. You can obtain a copy of the License at
11
* http://www.netbeans.org/cddl-gplv2.html
12
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
13
* specific language governing permissions and limitations under the
14
* License. When distributing the software, include this License Header
15
* Notice in each file and include the License file at
16
* nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
17
* particular file as subject to the "Classpath" exception as provided
18
* by Sun in the GPL Version 2 section of the License file that
19
* accompanied this code. If applicable, add the following below the
20
* License Header, with the fields enclosed by brackets [] replaced by
21
* your own identifying information:
22
* "Portions Copyrighted [year] [name of copyright owner]"
26
* The Original Software is NetBeans. The Initial Developer of the Original
27
* Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
28
* Microsystems, Inc. All Rights Reserved.
30
* If you wish your version of this file to be governed by only the CDDL
31
* or only the GPL Version 2, indicate your decision by adding
32
* "[Contributor] elects to include this software in this distribution
33
* under the [CDDL or GPL Version 2] license." If you do not indicate a
34
* single choice of license, a recipient has the option to distribute
35
* your version of this file under either the CDDL, the GPL Version 2 or
36
* to extend the choice of license to its licensees as provided above.
37
* However, if you add GPL Version 2 code and therefore, elected the GPL
38
* Version 2 license, then the option applies only if the new code is
39
* made subject to such option by the copyright holder.
42
package org.netbeans.modules.schema2beans;
46
import java.lang.reflect.*;
52
* @author Cliff Draper
54
* This is a utility class with several static methods for working
55
* with generic java beans. There are methods here for writing a java
56
* bean out {link writeBeanProperty}, for reading a java bean
57
* from XML {link readBean}, and for copying one java bean to
58
* another {link copyBean}.
60
public class JavaBeansUtil {
61
private JavaBeansUtil() {}
64
* This is the normal top level method for taking a Java Bean and
66
* @param obj the java bean to write out
67
* @param out the place to write it to
68
* @param propertyName the top level property
70
public static void writeBeanProperty(Object obj, Writer out, String propertyName) throws IOException, java.beans.IntrospectionException {
71
BeanWriter beanOut = new XmlBeanWriter(out);
72
writeBeanProperty(obj, beanOut, propertyName);
76
* If you want to write the java bean out in a different way from
77
* the standard XML writer, use this method.
79
public static void writeBeanProperty(Object obj, BeanWriter out, String propertyName) throws IOException, java.beans.IntrospectionException {
80
writeBeanProperty(obj, out, new HashMap(), propertyName);
84
* BeanWriter is the generic way of writing a java bean out.
86
public static interface BeanWriter {
87
public void beginPropertyName(String propertyName) throws IOException;
88
public void endPropertyName(String propertyName) throws IOException;
89
public void writeLeafObject(Object obj) throws IOException;
90
public void beginInnerNode() throws IOException;
91
public void endInnerNode() throws IOException;
95
* The methods in this class will do proper XML indention for you.
97
public static abstract class IndentingBeanWriter implements BeanWriter {
98
protected String indentBy;
99
protected String indent;
100
protected int indentLevel = 0;
101
protected List indentions;
103
public IndentingBeanWriter() {
107
public IndentingBeanWriter(String indentBy) {
111
public IndentingBeanWriter(String indent, String indentBy) {
112
this.indent = indent;
113
this.indentBy = indentBy;
114
this.indentions = new ArrayList();
115
this.indentions.add(indent); // indentLevel 0
118
public void beginInnerNode() throws IOException {
120
int indentionsSize = indentions.size();
121
if (indentionsSize <= indentLevel) {
122
indent = (String) indentions.get(indentionsSize-1);
125
indentions.add(indent);
127
} while (indentionsSize <= indentLevel);
129
indent = (String) indentions.get(indentLevel);
133
public void endInnerNode() throws IOException {
135
indent = (String) indentions.get(indentLevel);
139
public static class XmlBeanWriter extends IndentingBeanWriter implements BeanWriter {
140
protected Writer out;
142
public XmlBeanWriter(Writer out) {
147
public XmlBeanWriter(Writer out, String indentBy) {
152
public XmlBeanWriter(Writer out, String indent, String indentBy) {
153
super(indent, indentBy);
157
public void beginPropertyName(String propertyName) throws IOException {
159
out.write("<"+propertyName+">");
162
public void endPropertyName(String propertyName) throws IOException {
163
out.write("</"+propertyName+">\n");
166
public void writeLeafObject(Object obj) throws IOException {
167
XMLUtil.printXML(out, obj.toString(), false);
170
public void beginInnerNode() throws IOException {
171
super.beginInnerNode();
175
public void endInnerNode() throws IOException {
176
super.endInnerNode();
181
public static class HtmlBeanWriter extends IndentingBeanWriter implements BeanWriter {
182
protected Writer out;
184
public HtmlBeanWriter(Writer out) {
189
public HtmlBeanWriter(Writer out, String indentBy) {
194
public HtmlBeanWriter(Writer out, String indent, String indentBy) {
195
super(indent, indentBy);
199
public void beginPropertyName(String propertyName) throws IOException {
202
out.write("<th>"+propertyName+"</th>");
205
public void endPropertyName(String propertyName) throws IOException {
210
public void writeLeafObject(Object obj) throws IOException {
211
// leaf - write a table cell
213
XMLUtil.printXML(out, obj.toString(), false);
217
public void beginInnerNode() throws IOException {
218
super.beginInnerNode();
219
// inner node - write a nested table
220
out.write("<td><table width=\"100%\" border=\"1\">");
224
public void endInnerNode() throws IOException {
225
super.endInnerNode();
227
out.write("</table></td>");
231
public static void writeBeanProperty(Object obj, BeanWriter out, Map skipChildren, String propertyName) throws IOException, java.beans.IntrospectionException {
234
out.beginPropertyName(propertyName);
235
if (!isJavaBeanType(obj.getClass())) {
237
out.writeLeafObject(obj);
240
out.beginInnerNode();
241
writeBean(obj, out, skipChildren);
244
out.endPropertyName(propertyName);
248
* This method is similar to writeBeanProperty except that the
249
* outer property name is not known and not printed.
251
public static void writeBean(Object obj, Writer out) throws IOException, java.beans.IntrospectionException {
252
BeanWriter beanOut = new XmlBeanWriter(out);
253
writeBean(obj, beanOut);
256
public static void writeBean(Object obj, BeanWriter out) throws IOException, java.beans.IntrospectionException {
257
writeBean(obj, out, new HashMap());
260
public static void writeBean(Object obj, BeanWriter out, Map skipChildren) throws IOException, java.beans.IntrospectionException {
261
//System.out.println("obj="+obj);
264
// Make sure that we don't get into an infinite loop
265
if (skipChildren.containsKey(obj))
267
skipChildren.put(obj, null);
269
Class objCls = obj.getClass();
271
if (obj instanceof Collection) {
272
System.out.println("Hit Collection");
275
if (objCls.isArray()) {
276
System.out.println("Hit Array");
281
BeanInfo bi = Introspector.getBeanInfo(objCls);
282
PropertyDescriptor[] pds = bi.getPropertyDescriptors();
283
for (int i = 0 ; i < pds.length; ++i) {
284
PropertyDescriptor pd = pds[i];
285
Method reader = pd.getReadMethod();
288
Class propertyType = pd.getPropertyType();
289
String propertyName = pd.getName();
290
//System.out.println("pd.getName="+propertyName+" pd.getPropertyType="+pd.getPropertyType());
291
//System.out.println("reader="+reader);
292
Class declaringClass = reader.getDeclaringClass();
293
//System.out.println("reader.declaring="+declaringClass);
294
// Need to handle indexed properties
295
if (declaringClass.equals(Object.class))
297
if (propertyType == null)
299
Object childObj = null;
301
childObj = reader.invoke(obj, null);
302
} catch (java.lang.reflect.InvocationTargetException e) {
304
} catch (java.lang.IllegalAccessException e) {
307
if (childObj != null) {
308
if (childObj instanceof Collection) {
309
//System.out.println("childObj is Collection");
310
Iterator it = ((Collection)childObj).iterator();
311
while (it.hasNext()) {
312
Object childElement = it.next();
313
writeBeanProperty(childElement, out, skipChildren,
316
} else if (childObj.getClass().isArray()) {
317
//System.out.println("childObj is Array");
318
int size = Array.getLength(childObj);
319
for (int j = 0; j < size; ++j) {
320
Object childElement = Array.get(childObj, j);
321
writeBeanProperty(childElement, out, skipChildren,
325
writeBeanProperty(childObj, out, skipChildren,
330
skipChildren.remove(obj);
334
* Construct a new cls and fill in it's contents from in.
336
* @param cls the Class to construct from the XML.
337
* @param in the source of the XML.
339
public static Object readBean(Class cls, java.io.InputStream in) throws javax.xml.parsers.ParserConfigurationException, org.xml.sax.SAXException, java.io.IOException, java.beans.IntrospectionException, java.lang.NoSuchMethodException, java.lang.InstantiationException, java.lang.IllegalAccessException, java.lang.reflect.InvocationTargetException {
340
Constructor construct = cls.getConstructor(new Class[0]);
341
Object newValue = construct.newInstance(new Object[0]);
342
readBean(newValue, in);
347
* Fill in the contents of obj from the XML that's in in.
349
* @param obj the object to fill in from the XML.
350
* @param in the source of the XML.
352
public static void readBean(Object obj, java.io.InputStream in) throws javax.xml.parsers.ParserConfigurationException, org.xml.sax.SAXException, java.io.IOException, java.beans.IntrospectionException {
353
readBean(obj, new org.xml.sax.InputSource(in), false, null, null);
357
* Warning: in readNoEntityResolver character and entity references will
358
* not be read from any DTD in the XML source.
359
* However, this way is faster since no DTDs are looked up
360
* (possibly skipping network access) or parsed.
362
public static void readBeanNoEntityResolver(Object obj, java.io.InputStream in) throws javax.xml.parsers.ParserConfigurationException, org.xml.sax.SAXException, java.io.IOException, java.beans.IntrospectionException {
363
readBean(obj, new org.xml.sax.InputSource(in), false,
364
new org.xml.sax.EntityResolver() {
365
public org.xml.sax.InputSource resolveEntity(String publicId, String systemId) {
366
java.io.ByteArrayInputStream bin = new java.io.ByteArrayInputStream(new byte[0]);
367
return new org.xml.sax.InputSource(bin);
373
public static void readBean(Object obj, org.xml.sax.InputSource in, boolean validate, org.xml.sax.EntityResolver er, org.xml.sax.ErrorHandler eh) throws javax.xml.parsers.ParserConfigurationException, org.xml.sax.SAXException, java.io.IOException, java.beans.IntrospectionException {
374
javax.xml.parsers.DocumentBuilderFactory dbf = javax.xml.parsers.DocumentBuilderFactory.newInstance();
375
dbf.setValidating(validate);
376
javax.xml.parsers.DocumentBuilder db = dbf.newDocumentBuilder();
377
if (er != null) db.setEntityResolver(er);
378
if (eh != null) db.setErrorHandler(eh);
379
org.w3c.dom.Document doc = db.parse(in);
384
* Construct a new cls and fill in it's contents from document.
386
* @param cls the Class to construct from the XML.
387
* @param document the source of the XML.
389
public static Object readBean(Class cls, org.w3c.dom.Document document) throws java.beans.IntrospectionException, java.lang.NoSuchMethodException, java.lang.InstantiationException, java.lang.IllegalAccessException, java.lang.reflect.InvocationTargetException {
390
Constructor construct = cls.getConstructor(new Class[0]);
391
Object newValue = construct.newInstance(new Object[0]);
392
readBean(newValue, document);
397
* Fill in the contents of obj from the XML that's in document.
399
* @param obj the object to fill in from the XML.
400
* @param document the source of the XML.
402
public static void readBean(Object obj, org.w3c.dom.Document document) throws java.beans.IntrospectionException {
403
readBean(obj, document.getDocumentElement());
406
public static void readBean(Object obj, Node node) throws java.beans.IntrospectionException {
410
Class objCls = obj.getClass();
411
BeanInfo bi = Introspector.getBeanInfo(objCls);
412
PropertyDescriptor[] pds = bi.getPropertyDescriptors();
413
Map propertyWriters = new HashMap(); // <String, Method>
414
Map propertyTypes = new HashMap(); // <String, Class>
415
for (int i = 0 ; i < pds.length; ++i) {
416
PropertyDescriptor pd = pds[i];
417
Method writer = pd.getWriteMethod();
420
Class propertyType = pd.getPropertyType();
421
String propertyName = pd.getName();
422
Class declaringClass = writer.getDeclaringClass();
423
//System.out.println("pd.getName="+propertyName+" pd.getPropertyType="+pd.getPropertyType()+" declaringClass="+declaringClass);
424
if (declaringClass == null || declaringClass.equals(Object.class))
426
if (propertyType == null)
428
propertyWriters.put(propertyName, writer);
429
propertyTypes.put(propertyName, propertyType);
432
Map propertiesNewValues = new HashMap();
433
if (node.hasAttributes()) {
434
org.w3c.dom.NamedNodeMap attrs = node.getAttributes();
435
for (int i = 0; i < attrs.getLength(); ++i) {
436
Attr attr = (Attr) attrs.item(i);
437
String attrName = attr.getName();
438
if (!propertyWriters.containsKey(attrName)) {
439
attrName = Common.convertName(attrName);
440
if (!propertyWriters.containsKey(attrName)) {
441
attrName = Introspector.decapitalize(attrName);
442
if (!propertyWriters.containsKey(attrName)) {
444
System.out.println("Found attribute and did not find property in Java Bean: "+attr.getName());
449
Object newValue = convertValue((Class)propertyTypes.get(attrName),
451
propertiesNewValues.put(attrName, newValue);
454
org.w3c.dom.NodeList children = node.getChildNodes();
455
for (int i = 0, size = children.getLength(); i < size; ++i) {
456
org.w3c.dom.Node childNode = children.item(i);
457
if (!(childNode instanceof Element))
459
String childNodeName = (childNode.getLocalName() == null ? childNode.getNodeName().intern() : childNode.getLocalName().intern());
460
//System.out.println("Found child named "+childNodeName);
461
if (!propertyWriters.containsKey(childNodeName)) {
462
childNodeName = Common.convertName(childNodeName);
463
if (!propertyWriters.containsKey(childNodeName)) {
464
childNodeName = Introspector.decapitalize(childNodeName);
465
if (!propertyWriters.containsKey(childNodeName)) {
467
System.out.println("Found element and did not find property in Java Bean: "+childNode.getNodeName());
472
Class propertyType = (Class) propertyTypes.get(childNodeName);
473
Object newValue = null;
474
if (isJavaBeanType(propertyType)) {
475
Class propertyTypeOnce = propertyType;
476
if (propertyType.isArray())
477
propertyTypeOnce = propertyType.getComponentType();
479
//System.out.println("It's a Java Bean type");
480
Constructor construct = propertyTypeOnce.getConstructor(new Class[0]);
481
newValue = construct.newInstance(new Object[0]);
482
readBean(newValue, childNode);
483
} catch (java.lang.NoSuchMethodException e) {
486
} catch (java.lang.InstantiationException e) {
489
} catch (java.lang.IllegalAccessException e) {
492
} catch (java.lang.reflect.InvocationTargetException e) {
498
if (childNode.getFirstChild() == null)
501
nodeValue = childNode.getFirstChild().getNodeValue();
502
Class typeOfNewValue = propertyType;
503
if (propertyType.isArray())
504
typeOfNewValue = propertyType.getComponentType();
505
newValue = convertValue(typeOfNewValue, nodeValue);
507
//System.out.println("newValue="+newValue+" newValue.class="+newValue.getClass()+" propertyType="+propertyType.getName());
508
if (propertyType.isArray()) {
509
List values = (List) propertiesNewValues.get(childNodeName);
510
if (values == null) {
511
values = new ArrayList();
512
propertiesNewValues.put(childNodeName, values);
514
values.add(newValue);
516
propertiesNewValues.put(childNodeName, newValue);
520
for (Iterator it = propertiesNewValues.keySet().iterator();
522
String propertyName = (String) it.next();
523
Class propertyType = (Class) propertyTypes.get(propertyName);
524
Method writer = (Method) propertyWriters.get(propertyName);
526
//System.out.println("propertyName="+propertyName+" writer="+writer);
528
if (propertyType.isArray()) {
529
// convert our List into an array
530
List values = (List) propertiesNewValues.get(propertyName);
531
newValue = Array.newInstance(propertyType.getComponentType(),
533
//newValue = values.toArray((Object[])newValue);
534
for (int i = 0; i < values.size(); ++i) {
535
//System.out.println("i="+i+" values.get(i)="+values.get(i)+" values.get(i).class="+values.get(i).getClass());
536
Array.set(newValue, i, values.get(i));
539
newValue = propertiesNewValues.get(propertyName);
542
//System.out.println("newValue="+newValue+" newValue.class="+newValue.getClass());
544
writer.invoke(obj, new Object[] {newValue});
545
} catch (java.lang.reflect.InvocationTargetException e) {
548
} catch (java.lang.IllegalAccessException e) {
557
* Find matching properties between these 2 beans and copy over the
560
public static void copyBean(Object src, Object dest) throws java.beans.IntrospectionException {
561
copyBean(src, dest, Collections.EMPTY_MAP);
565
* Find matching properties between these 2 beans and copy over the
568
* @param nameMapping maps property names from the src object to the dest object.
570
public static void copyBean(Object src, Object dest, Map nameMapping) throws java.beans.IntrospectionException {
573
Class srcCls = src.getClass();
574
BeanInfo bi = Introspector.getBeanInfo(srcCls);
575
PropertyDescriptor[] pds = bi.getPropertyDescriptors();
576
Map propertyReaders = new HashMap(); // <String, Method>
577
Map propertyTypes = new HashMap(); // <String, Class>
578
for (int i = 0 ; i < pds.length; ++i) {
579
PropertyDescriptor pd = pds[i];
580
Method reader = pd.getReadMethod();
583
Class propertyType = pd.getPropertyType();
584
String propertyName = pd.getName();
585
Class declaringClass = reader.getDeclaringClass();
586
//System.out.println("pd.getName="+propertyName+" pd.getPropertyType="+pd.getPropertyType()+" declaringClass="+declaringClass);
587
if (declaringClass == null || declaringClass.equals(Object.class))
589
if (propertyType == null)
591
if (nameMapping.containsKey(propertyName))
592
propertyName = (String) nameMapping.get(propertyName);
593
propertyReaders.put(propertyName, reader);
594
propertyTypes.put(propertyName, propertyType);
597
Class destCls = dest.getClass();
598
bi = Introspector.getBeanInfo(destCls);
599
pds = bi.getPropertyDescriptors();
600
for (int i = 0 ; i < pds.length; ++i) {
601
PropertyDescriptor pd = pds[i];
602
Method writer = pd.getWriteMethod();
605
Class propertyType = pd.getPropertyType();
606
String propertyName = pd.getName();
607
Class declaringClass = writer.getDeclaringClass();
608
if (declaringClass == null || declaringClass.equals(Object.class))
610
if (propertyType == null)
612
if (propertyReaders.containsKey(propertyName)) {
613
// Found a common property
614
//System.out.println("copying propertyName="+propertyName);
616
Method reader = (Method) propertyReaders.get(propertyName);
617
Object srcValue = reader.invoke(src, null);
618
//System.out.println("srcValue="+srcValue);
619
if (isJavaBeanType(propertyType)) {
620
Class propertyTypeOnce = propertyType;
622
Object destValue = null;
623
if (propertyType.isArray()) {
624
propertyTypeOnce = propertyType.getComponentType();
625
size = Array.getLength(srcValue);
626
destValue = Array.newInstance(propertyTypeOnce, size);
628
for (int index = 0; index < size; ++index) {
629
Constructor construct = propertyTypeOnce.getConstructor(new Class[0]);
631
Object destValueOnce = construct.newInstance(new Object[0]);
632
if (propertyType.isArray()) {
633
Array.set(destValue, index, destValueOnce);
634
srcValueOnce = Array.get(srcValue, index);
636
destValue = destValueOnce;
637
srcValueOnce = srcValue;
639
copyBean(srcValueOnce, destValueOnce, nameMapping);
640
//System.out.println("destValueOnce.class="+destValueOnce.getClass());
641
//System.out.println("destValueOnce="+destValueOnce);
643
writer.invoke(dest, new Object[] {destValue});
644
} else if (propertyType.isAssignableFrom((Class)propertyTypes.get(propertyName))) {
645
writer.invoke(dest, new Object[] {srcValue});
647
//System.out.println("Wrong type!");
650
} catch (java.lang.IllegalAccessException e) {
652
} catch (java.lang.reflect.InvocationTargetException e) {
654
} catch (java.lang.NoSuchMethodException e) {
656
} catch (java.lang.InstantiationException e) {
664
* Determine if type is a java bean or not. This is a tough
665
* decision. This method is called to figure out at what types to
666
* stop recursing in the bean graph. Any type that is not simple
667
* enough is called a java bean.
669
public static boolean isJavaBeanType(Class type) {
670
if (Collection.class.isAssignableFrom(type))
672
if (type.isArray()) {
673
return isJavaBeanType(type.getComponentType());
675
String typeName = type.getName().intern();
676
if (typeName == "java.lang.String"||
677
typeName == "java.lang.Integer"|| typeName == "int" ||
678
typeName == "java.lang.Character"|| typeName == "char" ||
679
typeName == "java.lang.Long"|| typeName == "long" ||
680
typeName == "java.lang.Float"|| typeName == "float" ||
681
typeName == "java.lang.Double"|| typeName == "double" ||
682
typeName == "java.lang.Boolean"|| typeName == "boolean" ||
683
typeName == "java.lang.Short"|| typeName == "short" ||
684
typeName == "java.lang.Byte"|| typeName == "byte" ||
685
typeName == "java.math.BigDecimal"||
686
typeName == "java.math.BigInteger"||
687
typeName == "java.lang.Object" ||
688
typeName == "java.util.Calendar" || typeName == "java.util.Date" ||
689
typeName == "java.util.GregorianCalendar" ||
690
typeName == "javax.xml.namespace.QName" ||
691
typeName == "java.net.URL" || typeName == "java.net.URI")
697
* Convert a textual representation of type stored in value into a
698
* java object. If we don't know the type, then look for a
699
* constructor that takes a single String as a parameter.
701
public static Object convertValue(Class type, String value) {
702
String typeName = type.getName().intern();
703
if (typeName == "java.lang.String")
705
if (typeName == "java.lang.Boolean" || typeName == "boolean")
706
return Boolean.valueOf(value);
707
if (typeName == "java.lang.Integer" || typeName == "int")
708
return Integer.valueOf(value);
709
if (typeName == "java.lang.Long" || typeName == "long")
710
return Long.valueOf(value);
711
if (typeName == "java.lang.Float" || typeName == "float")
712
return Float.valueOf(value);
713
if (typeName == "java.lang.Double" || typeName == "double")
714
return Double.valueOf(value);
715
if (typeName == "java.lang.Byte" || typeName == "byte")
716
return Byte.valueOf(value);
717
if (typeName == "java.lang.Short" || typeName == "short")
718
return Short.valueOf(value);
719
if (typeName == "java.lang.Character" || typeName == "char")
720
return new Character(value.charAt(0));
721
if (typeName == "java.net.URL") {
723
return new java.net.URL(value);
724
} catch (java.net.MalformedURLException e) {
725
throw new RuntimeException(e);
728
if (typeName == "java.net.URI") {
730
return new java.net.URI(value);
731
} catch (java.net.URISyntaxException e) {
732
throw new RuntimeException(e);
735
if (typeName == "java.math.BigDecimal")
736
return new java.math.BigDecimal(value);
737
if (typeName == "java.math.BigInteger")
738
return new java.math.BigInteger(value);
739
if (typeName == "java.util.Calendar") {
740
// For XML Schema, we're trying to parse ISO8601 date time format
741
// CCYY-MM-DDThh:mm:ss+TZ:TZ
742
// 1999-05-31T13:20:00-05:00
743
// For -5 time zone, should use
744
// TimeZone.getAvailableIDs(-5*60*60*1000)
745
TimeZone tz = TimeZone.getDefault();
746
Calendar cal = Calendar.getInstance(tz);
748
String[] possibleFormats = {"yyyy-MM-dd'T'HH:mm:ss.S", "yyyy-MM-dd'T'HH:mm:ss", "yyyy-MM-dd"}; // NOI18N
749
java.text.ParsePosition pos = null;
750
for (int formatNum = 0; formatNum < possibleFormats.length; ++formatNum) {
751
pos = new java.text.ParsePosition(0);
752
java.text.SimpleDateFormat formatter = new java.text.SimpleDateFormat(possibleFormats[formatNum]);
753
formatter.setCalendar(cal);
754
date = formatter.parse(value, pos);
760
throw new java.lang.RuntimeException(Common.getMessage("MSG_BadParse", value));
766
Constructor c = null;
769
Class[] cc = new Class[] {java.lang.String.class};
770
c = type.getDeclaredConstructor(cc);
771
Object[] p = new Object[] {value};
772
return c.newInstance(p);
773
} catch (NoSuchMethodException me) {
774
throw new RuntimeException(me);
775
} catch (java.lang.InstantiationException e) {
776
throw new RuntimeException(e);
777
} catch (java.lang.IllegalAccessException e) {
778
throw new RuntimeException(e);
779
} catch (java.lang.reflect.InvocationTargetException e) {
780
throw new RuntimeException(e);
785
* Used for generating Java code for reading complicated types.
786
* @param typeName the java type to generate the method about, can also
789
public static void genReadType(Writer out, String typeName) throws IOException {
790
typeName = typeName.intern();
791
if (typeName == "java.util.Calendar") {
792
out.write("public static java.util.Calendar stringToCalendar(String value) throws java.text.ParseException {\n");
793
out.write("java.util.TimeZone tz = java.util.TimeZone.getDefault();\n");
794
out.write("java.util.Calendar cal = java.util.Calendar.getInstance(tz);\n");
795
out.write("java.util.Date date = null;\n");
796
out.write("String[] possibleFormats = {\"yyyy-MM-dd'T'HH:mm:ss.S\", \"yyyy-MM-dd'T'HH:mm:ss\", \"yyyy-MM-dd\"}; // NOI18N\n");
797
out.write("java.text.ParsePosition pos = null;\n");
798
out.write("for (int formatNum = 0; formatNum < possibleFormats.length; ++formatNum) {\n");
799
out.write("pos = new java.text.ParsePosition(0);\n");
800
out.write("java.text.SimpleDateFormat formatter = new java.text.SimpleDateFormat(possibleFormats[formatNum]);\n");
801
out.write("formatter.setCalendar(cal);\n");
802
out.write("date = formatter.parse(value, pos);\n");
803
out.write("if (date != null) {\n");
804
out.write("break;\n");
807
out.write("if (date == null) {\n");
808
out.write("throw new java.text.ParseException(\"Bad time/date parse of \"+value, pos.getErrorIndex());\n");
810
out.write("int len = value.length();\n");
811
out.write("if (pos.getIndex() < len) {\n");
812
out.write("if (value.charAt(pos.getIndex()) == 'Z') {\n");
813
out.write("// The Timezone is UTC\n");
814
out.write("tz = java.util.TimeZone.getTimeZone(\"GMT\");\n");
815
out.write("cal.setTimeZone(tz);\n");
816
out.write("} else {\n");
817
out.write("tz = java.util.TimeZone.getTimeZone(\"GMT\"+value.substring(pos.getIndex(), len));\n");
818
out.write("cal.setTimeZone(tz);\n");
821
out.write("cal.setTime(date);\n");
822
out.write("return cal;\n");
824
} else if (typeName == "base64Binary") {
825
out.write("public static byte[] decodeBase64BinaryString(String text) {\n");
826
out.write("final int decodeBase64Table[] = {62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51};\n");
827
out.write("StringBuffer cleanedEncoding = new StringBuffer();\n");
828
out.write("int len = text.length();\n");
829
out.write("// Get rid of extraneous characters (like whitespace).\n");
830
out.write("for (int i = 0; i < len; ++i) {\n");
831
out.write("if (text.charAt(i) > 0x20) {\n");
832
out.write("cleanedEncoding.append(text.charAt(i));\n");
835
out.write("char[] encodedText = cleanedEncoding.toString().toCharArray();\n");
836
out.write("len = encodedText.length;\n");
837
out.write("if (len == 0) {\n");
838
out.write("return new byte[0];\n");
840
out.write("int howManyBlocks = len / 4;\n");
841
out.write("int partialLen = 3;\n");
842
out.write("if (encodedText[len-1] == '=') {\n");
843
out.write("partialLen -= 1;\n");
844
out.write("if (encodedText[len-2] == '=') {\n");
845
out.write("partialLen -= 1;\n");
848
out.write("int resultLen = partialLen + (howManyBlocks - 1) * 3;\n");
849
out.write("byte[] result = new byte[resultLen];\n");
850
out.write("int resultIndex = 0;\n");
851
out.write("int encodedTextIndex = 0;\n");
852
out.write("for (int blockNum = 0; blockNum < howManyBlocks; ++blockNum) {\n");
853
out.write("int a = decodeBase64Table[encodedText[encodedTextIndex++] - '+'];\n");
854
out.write("int b = decodeBase64Table[encodedText[encodedTextIndex++] - '+'];\n");
855
out.write("int c = decodeBase64Table[encodedText[encodedTextIndex++] - '+'];\n");
856
out.write("int d = decodeBase64Table[encodedText[encodedTextIndex++] - '+'];\n");
858
out.write("result[resultIndex++] = (byte) ( (b >> 4) | (a << 2) );\n");
859
out.write("if (resultIndex < resultLen) {\n");
860
out.write("result[resultIndex++] = (byte) ( ((b & 0xf) << 4) | (c >> 2) );\n");
862
out.write("if (resultIndex < resultLen) {\n");
863
out.write("result[resultIndex++] = (byte) ( ((c & 0x3) << 6) | d);\n");
866
out.write("return result;\n");
872
* Used for generating Java code for writing complicated types.
873
* @param typeName the java type to generate the method about, can also
876
public static void genWriteType(Writer out, String typeName) throws IOException {
877
typeName = typeName.intern();
878
if (typeName == "java.util.Calendar") {
879
out.write("public static String calendarToString(java.util.Calendar cal) {\n");
880
out.write("java.util.Date date = cal.getTime();\n");
881
out.write("java.text.SimpleDateFormat formatter;\n");
882
out.write("if (cal.get(java.util.Calendar.HOUR) == 0 && cal.get(java.util.Calendar.MINUTE) == 0 && cal.get(java.util.Calendar.SECOND) == 0) {\n");
883
out.write("formatter = new java.text.SimpleDateFormat(\"yyyy-MM-dd\"); // NOI18N\n");
884
out.write("} else if (cal.get(java.util.Calendar.MILLISECOND) == 0) {\n");
885
out.write("formatter = new java.text.SimpleDateFormat(\"yyyy-MM-dd'T'HH:mm:ss\"); // NOI18N\n");
886
out.write("} else {\n");
887
out.write("formatter = new java.text.SimpleDateFormat(\"yyyy-MM-dd'T'HH:mm:ss.S\"); // NOI18N\n");
889
out.write("String result = formatter.format(date);\n");
890
out.write("if (java.util.TimeZone.getDefault().hasSameRules(cal.getTimeZone())) {\n");
891
out.write("return result;\n");
893
out.write("int offset = cal.getTimeZone().getOffset(0);\n");
894
out.write("if (offset == 0) {\n");
895
out.write("return result+\"Z\";\n");
897
out.write("int seconds = offset / 1000;\n");
898
out.write("if (seconds > 0) {\n");
899
out.write("result += \"+\";\n");
900
out.write("} else {\n");
901
out.write("seconds = -1 * seconds;\n");
902
out.write("result += \"-\";\n");
904
out.write("int hours = seconds / 3600;\n");
905
out.write("if (hours < 10) {\n");
906
out.write("result += \"0\";\n");
908
out.write("result += hours + \":\";\n");
909
out.write("int minutes = (seconds / 60) % 60;\n");
910
out.write("if (minutes < 10) {\n");
911
out.write("result += \"0\";\n");
913
out.write("result += minutes;\n");
914
out.write("return result;\n");
916
} else if (typeName == "base64Binary") {
917
out.write("public static String encodeBase64BinaryString(byte[] instance) {\n");
918
out.write("final char encodeBase64Table[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'};\n");
919
out.write("byte[] value = (byte[]) instance;\n");
920
out.write("int len = value.length;\n");
921
out.write("if (len == 0) {\n");
922
out.write("return \"\";\n");
924
out.write("int howManyBlocks = len / 3;\n");
925
out.write("int partialLen = len % 3;\n");
926
out.write("if (partialLen != 0) {\n");
927
out.write("howManyBlocks += 1;\n");
929
out.write("int resultLen = howManyBlocks * 4;\n");
930
out.write("StringBuffer result = new StringBuffer(resultLen);\n");
931
out.write("int valueIndex = 0;\n");
932
out.write("for (int blockNum = 0; blockNum < howManyBlocks; ++blockNum) {\n");
933
out.write("int a = value[valueIndex++];\n");
934
out.write("int b;\n");
935
out.write("int c;\n");
936
out.write("if (valueIndex < len) {\n");
937
out.write("b = value[valueIndex++];\n");
938
out.write("} else {\n");
939
out.write("b = 0;\n");
941
out.write("if (valueIndex < len) {\n");
942
out.write("c = value[valueIndex++];\n");
943
out.write("} else {\n");
944
out.write("c = 0;\n");
946
out.write("if (a < 0) {\n");
947
out.write("a += 256;\n");
949
out.write("if (b < 0) {\n");
950
out.write("b += 256;\n");
952
out.write("if (c < 0) {\n");
953
out.write("c += 256;\n");
955
out.write("result.append(encodeBase64Table[a >> 2]);\n");
956
out.write("result.append(encodeBase64Table[((a & 0x3) << 4) | (b >> 4)]);\n");
957
out.write("result.append(encodeBase64Table[((b & 0xf) << 2) | (c >> 6)]);\n");
958
out.write("result.append(encodeBase64Table[c & 0x3f]);\n");
960
out.write("if (partialLen == 1) {\n");
961
out.write("result.setCharAt(resultLen - 1, '=');\n");
962
out.write("result.setCharAt(resultLen - 2, '=');\n");
963
out.write("} else if (partialLen == 2) {\n");
964
out.write("result.setCharAt(resultLen - 1, '=');\n");
966
out.write("return result.toString();\n");
971
///////////////////////////////////////////////////////////////////////
974
* Create a bean with dummy values.
975
* If a bean property write method fails or the constructor to the bean
976
* fails, then a null value is used.
978
public static Object dummyBean(Class cls, int arraySize) throws java.beans.IntrospectionException {
980
// construct a new instance
981
if (!isJavaBeanType(cls)) {
982
return dummyValue(cls, arraySize);
987
Constructor construct = cls.getConstructor(new Class[0]);
988
obj = construct.newInstance(new Object[0]);
989
} catch (java.lang.NoSuchMethodException e) {
992
} catch (java.lang.InstantiationException e) {
995
} catch (java.lang.IllegalAccessException e) {
998
} catch (java.lang.reflect.InvocationTargetException e) {
1003
// stuff the bean with the dummy values
1004
BeanInfo bi = Introspector.getBeanInfo(cls);
1005
PropertyDescriptor[] pds = bi.getPropertyDescriptors();
1007
for (int i = 0 ; i < pds.length; ++i) {
1008
PropertyDescriptor pd = pds[i];
1009
Method writer = pd.getWriteMethod();
1010
if (writer == null) continue;
1011
Class propertyType = pd.getPropertyType();
1012
String propertyName = pd.getName();
1013
Class declaringClass = writer.getDeclaringClass();
1014
if (declaringClass == null || declaringClass.equals(Object.class)) continue;
1015
if (propertyType == null) continue;
1017
Object newValue=null;
1018
Object baseValue=null;
1019
if (isJavaBeanType(propertyType)) {
1020
Class baseType = propertyType;
1021
if (propertyType.isArray())
1022
baseType = propertyType.getComponentType();
1023
baseValue = dummyBean(baseType, arraySize);
1024
if (propertyType.isArray()) {
1025
// if array of beans, set each element
1026
newValue = Array.newInstance(baseType, arraySize);
1027
for (int ii=0; ii<arraySize; ++ii) {
1028
Array.set(newValue, ii, baseValue);
1031
newValue = baseValue;
1034
Class baseType = propertyType;
1035
if (propertyType.isArray())
1036
baseType = propertyType.getComponentType();
1037
baseValue = dummyValue(baseType, arraySize);
1038
if (propertyType.isArray()) {
1039
// if array, set each elements
1040
newValue = Array.newInstance(baseType, arraySize);
1041
for (int ii=0; ii<arraySize; ++ii) {
1042
Array.set(newValue, ii, baseValue);
1045
newValue = baseValue;
1049
// set the value to property
1051
writer.invoke(obj, new Object[] {newValue});
1052
} catch (java.lang.reflect.InvocationTargetException e) {
1053
// Let the null value be used
1054
e.printStackTrace();
1055
} catch (java.lang.IllegalAccessException e) {
1056
// Let the null value be used
1057
e.printStackTrace();
1061
// return the dummy bean
1067
* @return dummy value for a particular type. If it's not a standard
1068
* type, then look for a constructor that takes a single String as
1069
* a parameter; if that fails, then return null.
1071
public static Object dummyValue(Class type, int arraySize) {
1072
String typeName = type.getName().intern();
1073
if (Collection.class.isAssignableFrom(type)) {
1074
// if collection - make an arraylist of string
1075
ArrayList lst = new ArrayList();
1076
for (int ii=0; ii < arraySize; ++ii) {
1077
lst.add("collection-element");
1080
} else if (typeName == "java.lang.String")
1082
else if (typeName == "java.lang.Boolean" || typeName == "boolean")
1083
return Boolean.FALSE;
1084
else if (typeName == "java.lang.Integer" || typeName == "int")
1085
return Integer.valueOf("1");
1086
else if (typeName == "java.lang.Long" || typeName == "long")
1087
return Long.valueOf("1");
1088
else if (typeName == "java.lang.Float" || typeName == "float")
1089
return Float.valueOf("1.0");
1090
else if (typeName == "java.lang.Double" || typeName == "double")
1091
return Double.valueOf("1.0");
1092
else if (typeName == "java.lang.Byte" || typeName == "byte")
1093
return Byte.valueOf("1");
1094
else if (typeName == "java.lang.Short" || typeName == "short")
1095
return Short.valueOf("1");
1096
else if (typeName == "java.lang.Character" || typeName == "char")
1097
return new Character('C');
1098
else if (typeName == "java.math.BigDecimal")
1099
return new java.math.BigDecimal("1.0");
1100
else if (typeName == "java.math.BigInteger")
1101
return new java.math.BigInteger("1");
1102
else if (typeName == "java.util.Calendar") {
1103
Calendar cal = Calendar.getInstance();
1104
cal.setTime(new Date());
1107
// all other types, try to construct using string constructor.
1108
Constructor c = null;
1111
Class[] cc = new Class[] {java.lang.String.class};
1112
c = type.getDeclaredConstructor(cc);
1113
Object[] p = new Object[] {"string"};
1114
return c.newInstance(p);
1115
} catch (NoSuchMethodException e) {
1116
e.printStackTrace();
1118
} catch (java.lang.InstantiationException e) {
1119
e.printStackTrace();
1121
} catch (java.lang.IllegalAccessException e) {
1122
e.printStackTrace();
1124
} catch (java.lang.reflect.InvocationTargetException e) {
1125
e.printStackTrace();