1 7 package org.jboss.xml.binding; 8 9 import org.jboss.logging.Logger; 10 import org.xml.sax.SAXException ; 11 12 import java.io.StringWriter ; 13 import java.util.List ; 14 import java.util.Map ; 15 import java.util.HashMap ; 16 import java.util.ArrayList ; 17 import java.util.Collection ; 18 import java.util.Iterator ; 19 import java.util.Properties ; 20 import java.lang.reflect.Method ; 21 import java.lang.reflect.Array ; 22 23 29 public class SchemalessMarshaller 30 { 31 private static final Logger log = Logger.getLogger(SchemalessMarshaller.class); 32 33 public static final String PROPERTY_JAXB_SCHEMA_LOCATION = "jaxb.schemaLocation"; 34 35 private final Properties props = new Properties (); 36 37 private final Map gettersPerClass = new HashMap (); 38 39 private final Content content = new Content(); 40 41 public void setProperty(String name, String value) 42 { 43 props.setProperty(name, value); 44 } 45 46 public void marshal(Object root, StringWriter writer) 47 { 48 log.debug("marshal: root=" + root); 49 50 content.startDocument(); 51 52 marshalObject(root, root.getClass().getName(), writer); 53 54 content.endDocument(); 55 56 writer.write("<?xml version=\""); 57 writer.write("1.0"); 58 writer.write("\" encoding=\""); 59 writer.write("UTF-8"); 60 writer.write("\"?>\n"); 61 62 ContentWriter contentWriter = new ContentWriter(writer, true); 63 try 64 { 65 content.handleContent(contentWriter); 66 } 67 catch(SAXException e) 68 { 69 log.error("Failed to write content.", e); 70 throw new IllegalStateException ("Failed to write content: " + e.getMessage()); 71 } 72 } 73 74 private void marshalObject(Object root, String localName, StringWriter writer) 75 { 76 List getters = getGetterList(root.getClass()); 77 AttributesImpl attrs = null; content.startElement(null, localName, localName, attrs); 79 80 for(int i = 0; i < getters.size(); ++i) 81 { 82 Method getter = (Method )getters.get(i); 83 Object child; 84 try 85 { 86 child = getter.invoke(root, null); 87 } 88 catch(Exception e) 89 { 90 log.error("Failed to invoke getter " + getter.getName() + " on " + root, e); 91 throw new IllegalStateException ( 92 "Failed to invoke getter " + getter.getName() + " on " + root + ": " + e.getMessage() 93 ); 94 } 95 96 if(child != null) 97 { 98 String childName = getter.getName().substring(3); 99 if(isAttributeType(child.getClass())) 100 { 101 marshalAttributeType(childName, child); 102 103 111 } 112 else if(child.getClass().isArray()) 113 { 114 content.startElement(null, childName, childName, null); 115 for(int arrInd = 0; arrInd < Array.getLength(child); ++arrInd) 116 { 117 Object o = Array.get(child, arrInd); 118 marshalCollectionItem(o, o.getClass().getName(), o.getClass().getName(), writer); 119 } 120 content.endElement(null, childName, childName); 121 } 122 else if(Collection .class.isAssignableFrom(child.getClass())) 123 { 124 content.startElement(null, childName, childName, null); 125 Collection col = (Collection )child; 126 for(Iterator iter = col.iterator(); iter.hasNext();) 127 { 128 Object o = iter.next(); 129 marshalCollectionItem(o, o.getClass().getName(), o.getClass().getName(), writer); 130 } 131 content.endElement(null, childName, childName); 132 } 133 else 134 { 135 marshalObject(child, childName, writer); 136 } 137 } 138 } 139 140 content.endElement(null, localName, localName); 141 } 142 143 private void marshalCollectionItem(Object o, String childName, String qName, StringWriter writer) 144 { 145 if(o != null) 146 { 147 if(isAttributeType(o.getClass())) 148 { 149 marshalAttributeType(childName, o); 150 } 151 else 152 { 153 marshalObject(o, qName, writer); 154 } 155 } 156 } 157 158 private void marshalAttributeType(String qName, Object child) 159 { 160 content.startElement(null, qName, qName, null); 161 String value = child.toString(); 162 content.characters(value.toCharArray(), 0, value.length()); 163 content.endElement(null, qName, qName); 164 } 165 166 private List getGetterList(Class aClass) 167 { 168 List getters = (List )gettersPerClass.get(aClass); 169 if(getters == null) 170 { 171 getters = new ArrayList (); 172 Method [] methods = aClass.getMethods(); 173 for(int i = 0; i < methods.length; ++i) 174 { 175 Method method = methods[i]; 176 if(method.getDeclaringClass() != Object .class) 177 { 178 if((method.getName().startsWith("get") || method.getName().startsWith("is")) && 179 (method.getParameterTypes() == null || method.getParameterTypes().length == 0)) 180 { 181 getters.add(method); 182 } 183 } 184 } 185 gettersPerClass.put(aClass, getters); 186 } 187 return getters; 188 } 189 190 static boolean isAttributeType(Class cls) 191 { 192 if(cls.isPrimitive() || 193 cls == Byte .class || 194 cls == Short .class || 195 cls == Integer .class || 196 cls == Long .class || 197 cls == Float .class || 198 cls == Double .class || 199 cls == Character .class || 200 cls == Boolean .class || 201 cls == String .class || 202 cls == java.util.Date .class) 203 { 204 return true; 205 } 206 else 207 { 208 return false; 209 } 210 } 211 } 212 | Popular Tags |