1 28 29 package com.caucho.jaxb; 30 31 import javax.xml.bind.annotation.XmlType; 32 import javax.xml.namespace.QName ; 33 import static java.lang.Character .*; 34 import java.lang.reflect.Method ; 35 import java.lang.reflect.ParameterizedType ; 36 import java.lang.reflect.Type ; 37 import java.math.BigDecimal ; 38 import java.util.ArrayList ; 39 import java.util.Calendar ; 40 import java.util.Collection ; 41 import java.util.HashMap ; 42 import java.util.List ; 43 import java.util.Map ; 44 45 48 public class JAXBUtil { 49 private static final Map <Class ,String > _datatypeMap 50 = new HashMap <Class ,String >(); 51 52 public static void introspectClass(Class cl, 53 Collection <Class > jaxbClasses) 54 { 55 Method [] methods = cl.getMethods(); 56 57 for (Method method : methods) 58 introspectMethod(method, jaxbClasses); 59 } 60 61 66 public static void introspectMethod(Method method, 67 Collection <Class > jaxbClasses) 68 { 69 introspectType(method.getReturnType(), jaxbClasses); 70 71 Type[] params = method.getGenericParameterTypes(); 72 73 for (Type param : params) 74 introspectType(param, jaxbClasses); 75 76 81 } 82 83 86 private static void introspectType(Type type, Collection <Class > jaxbClasses) 87 { 88 if (type instanceof Class ) { 89 Class cl = (Class ) type; 90 91 if (! cl.isInterface()) 92 jaxbClasses.add((Class ) type); 93 } 94 else if (type instanceof ParameterizedType ) { 95 ParameterizedType pType = (ParameterizedType ) type; 96 97 introspectType(pType.getRawType(), jaxbClasses); 98 introspectType(pType.getOwnerType(), jaxbClasses); 99 100 Type[] arguments = pType.getActualTypeArguments(); 101 102 for (Type argument : arguments) 103 introspectType(argument, jaxbClasses); 104 } 105 else if (type != null) { 106 throw new UnsupportedOperationException ("Method arguments cannot have " + 108 "uninstantiated type variables " + 109 "or wildcards (" + type + ")"); 110 } 111 } 112 113 public static String classBasename(Class cl) 114 { 115 int i = cl.getName().lastIndexOf('$'); 116 117 if (i < 0) 118 i = cl.getName().lastIndexOf('.'); 119 120 return cl.getName().substring(i + 1); 121 } 122 123 126 private static boolean isPunctuation(char ch) 127 { 128 return "-.:\u00B7\u0387\u06DD\u06dd\u06de_".indexOf((int) ch) >= 0; 129 } 130 131 134 private static boolean isUncased(char ch) 135 { 136 return (! isLowerCase(ch)) && (! isUpperCase(ch)); 137 } 138 139 144 private static List <StringBuilder > splitIdentifier(String identifier) 145 { 146 List <StringBuilder > words = new ArrayList <StringBuilder >(); 147 StringBuilder word = new StringBuilder (); 148 char lastCh = 0; 149 150 for (int i = 0; i < identifier.length(); i++) { 151 char ch = identifier.charAt(i); 152 153 if (word.length() > 0 && isPunctuation(ch)) { 155 words.add(word); 156 word = new StringBuilder (); 157 } 158 else if (isDigit(ch)) { 159 if (word.length() > 0 && ! isDigit(lastCh)) { 160 words.add(word); 161 word = new StringBuilder (); 162 } 163 164 word.append(ch); 165 } 166 else if (i > 0) { if (isLowerCase(lastCh) && isUpperCase(ch)) { 168 words.add(word); 169 word = new StringBuilder (); 170 word.append(ch); 171 } 172 else if (isUpperCase(lastCh) && isLowerCase(ch)) { 173 176 if (word.length() > 1) { 177 word.deleteCharAt(word.length() - 1); 178 words.add(word); 179 } 180 181 word = new StringBuilder (); 182 word.append(lastCh); 183 word.append(ch); 184 } 185 else if (isLetter(lastCh) != isLetter(ch)) { 186 words.add(word); 187 word = new StringBuilder (); 188 word.append(ch); 189 } 190 else if (isUncased(lastCh) != isUncased(ch)) { 191 words.add(word); 192 word = new StringBuilder (); 193 word.append(ch); 194 } 195 else 196 word.append(ch); 197 } 198 else 199 word.append(ch); 200 201 lastCh = ch; 202 } 203 204 if (word.length() > 0) 205 words.add(word); 206 207 return words; 208 } 209 210 public static String identifierToXmlName(Class cl) 211 { 212 List <StringBuilder > words = splitIdentifier(classBasename(cl)); 213 StringBuilder xmlName = new StringBuilder (); 214 215 xmlName.append(toLowerCase(words.get(0).charAt(0))); 216 xmlName.append(words.get(0).substring(1)); 217 218 for (int i = 1; i < words.size(); i++) { 219 if (words.get(i).length() > 0) { 220 xmlName.append(toUpperCase(words.get(i).charAt(0))); 221 xmlName.append(words.get(i).substring(1)); 222 } 223 } 224 225 return xmlName.toString(); 226 } 227 228 public static String getXmlSchemaDatatype(Class cl) 229 { 230 232 if (_datatypeMap.containsKey(cl)) 233 return _datatypeMap.get(cl); 234 235 String name = null; 236 237 if (cl.isAnnotationPresent(XmlType.class)) { 238 XmlType xmlType = (XmlType) cl.getAnnotation(XmlType.class); 239 240 if (! "##default".equals(xmlType.name())) 241 name = xmlType.name(); 242 } 243 244 if (name == null) 245 name = identifierToXmlName(cl); 246 247 _datatypeMap.put(cl, name); 248 249 return name; 250 } 251 252 public static String qNameToString(QName qName) 253 { 254 if (qName.getPrefix() == null || "".equals(qName.getPrefix())) 255 return qName.getLocalPart(); 256 else 257 return qName.getPrefix() + ':' + qName.getLocalPart(); 258 } 259 260 261 static { 262 _datatypeMap.put(String .class, "xsd:string"); 263 264 _datatypeMap.put(BigDecimal .class, "xsd:decimal"); 265 266 _datatypeMap.put(Boolean .class, "xsd:boolean"); 267 _datatypeMap.put(boolean.class, "xsd:boolean"); 268 269 _datatypeMap.put(Byte [].class, "xsd:base64Binary"); _datatypeMap.put(byte[].class, "xsd:base64Binary"); 272 _datatypeMap.put(Byte .class, "xsd:byte"); 273 _datatypeMap.put(byte.class, "xsd:byte"); 274 275 _datatypeMap.put(Character .class, "xsd:unsignedShort"); 276 _datatypeMap.put(char.class, "xsd:unsignedShort"); 277 278 _datatypeMap.put(Calendar .class, "xsd:date"); 279 280 _datatypeMap.put(Double .class, "xsd:double"); 281 _datatypeMap.put(double.class, "xsd:double"); 282 283 _datatypeMap.put(Float .class, "xsd:float"); 284 _datatypeMap.put(float.class, "xsd:float"); 285 286 _datatypeMap.put(Integer .class, "xsd:int"); 287 _datatypeMap.put(int.class, "xsd:int"); 288 289 _datatypeMap.put(Long .class, "xsd:long"); 290 _datatypeMap.put(long.class, "xsd:long"); 291 292 _datatypeMap.put(Short .class, "xsd:short"); 293 _datatypeMap.put(short.class, "xsd:short"); 294 } 295 } 296 | Popular Tags |