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