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