1 package org.codehaus.xfire.aegis.type.basic;
2
3 import java.beans.PropertyDescriptor;
4 import java.util.HashMap;
5 import java.util.Map;
6
7 import javax.xml.namespace.QName;
8
9 import org.apache.commons.logging.Log;
10 import org.apache.commons.logging.LogFactory;
11 import org.codehaus.xfire.XFireRuntimeException;
12 import org.codehaus.xfire.util.ClassLoaderUtils;
13 import org.codehaus.yom.Element;
14 import org.codehaus.yom.Elements;
15
16 public class XMLBeanTypeInfo
17 extends BeanTypeInfo
18 {
19 private static final Log logger = LogFactory.getLog(XMLBeanTypeInfo.class);
20 private String encodingUri;
21 private Element mapping;
22 private QName name;
23 private Map name2Nillable = new HashMap();
24
25 public XMLBeanTypeInfo(Class typeClass,
26 Element mapping)
27 {
28 super(typeClass);
29
30 this.mapping = mapping;
31 }
32
33 public QName getSchemaType()
34 {
35 if (name == null)
36 {
37 name = createQName(mapping, mapping.getAttributeValue("name"));
38 }
39
40 return name;
41 }
42
43 protected void mapProperty(PropertyDescriptor pd)
44 {
45 Element e = getPropertyElement(mapping, pd.getName());
46 String style = null;
47 String mappedName = null;
48
49 if (e != null)
50 {
51 String ignore = e.getAttributeValue("ignore");
52 if (ignore != null && ignore.equals("true"))
53 return;
54
55 logger.debug("Found mapping for property " + pd.getName());
56
57 style = e.getAttributeValue("style");
58 mappedName = e.getAttributeValue("mappedName");
59 }
60
61 if (style == null) style = "element";
62 if (mappedName == null) mappedName = createMappedName(pd);
63
64 if (e != null)
65 {
66 QName mappedType = createQName(e, e.getAttributeValue("typeName"));
67 if (mappedType != null) mapTypeName(mappedName, mappedType);
68
69 String nillableVal = e.getAttributeValue("nillable");
70 if (nillableVal != null && nillableVal.length() > 0)
71 {
72 name2Nillable.put(mappedName, Boolean.valueOf(nillableVal));
73 }
74 }
75
76 try
77 {
78
79 if (style.equals("element"))
80 mapElement(pd.getName(), mappedName);
81 else if (style.equals("attribute"))
82 mapAttribute(pd.getName(), mappedName);
83 else
84 throw new XFireRuntimeException("Invalid style: " + style);
85 }
86 catch(XFireRuntimeException ex)
87 {
88 ex.prepend("Couldn't create type for property " + pd.getName()
89 + " on " + getTypeClass());
90
91 throw ex;
92 }
93 }
94
95 private Element getPropertyElement(Element mapping2, String name2)
96 {
97 Elements elements = mapping2.getChildElements("property");
98 for (int i = 0; i < elements.size(); i++)
99 {
100 Element e = elements.get(i);
101 String name = e.getAttributeValue("name");
102
103 if (name != null && name.equals(name2))
104 {
105 return e;
106 }
107 }
108
109 return null;
110 }
111
112 private Class loadClass(String componentType)
113 {
114 try
115 {
116 return ClassLoaderUtils.loadClass(componentType, getClass());
117 }
118 catch (ClassNotFoundException e)
119 {
120 throw new XFireRuntimeException("Couldn't find component type: " + componentType, e);
121 }
122 }
123
124 protected QName createQName(Element e, String value)
125 {
126 if (value == null) return null;
127
128 int index = value.indexOf(":");
129
130 if (index == -1)
131 throw new XFireRuntimeException("Invalid QName in mapping: " + value);
132
133 String prefix = value.substring(0, index);
134 String localName = value.substring(index+1);
135 String ns = e.getNamespaceURI(prefix);
136
137 if (ns == null || localName == null)
138 throw new XFireRuntimeException("Invalid QName in mapping: " + value);
139
140 return new QName(ns, localName, prefix);
141 }
142
143 public boolean isNillable(String name)
144 {
145 Boolean nillable = (Boolean) name2Nillable.get(name);
146
147 if (nillable != null) return nillable.booleanValue();
148
149 return super.isNillable(name);
150 }
151 }