1 package org.codehaus.xfire.java.mapping;
2
3 import java.util.Collection;
4 import java.util.StringTokenizer;
5
6 import org.codehaus.xfire.java.type.ArrayType;
7 import org.codehaus.xfire.java.type.BeanType;
8 import org.codehaus.xfire.java.type.Type;
9 import org.dom4j.QName;
10
11
12 /***
13 * A type mapping which automatically generates types
14 * for java classes which are not registered, allowing
15 * easy deployment of java services.
16 *
17 * @author <a href="mailto:dan@envoisolutions.com">Dan Diephouse</a>
18 * @since Feb 21, 2004
19 */
20 public class AutoTypeMapping
21 extends CustomTypeMapping
22 {
23
24 public AutoTypeMapping( TypeMapping defaultTM )
25 {
26 super( defaultTM );
27 }
28
29 public AutoTypeMapping()
30 {
31 super();
32 }
33
34 /***
35 * @see org.codehaus.xfire.java.mapping.TypeMapping#getSerializer(java.lang.Class, javax.xml.namespace.QName)
36 */
37 public Type getType( Class javaType, QName xmlType )
38 {
39 Type type = super.getType(javaType, xmlType);
40
41 if ( type == null )
42 {
43 register( javaType, xmlType, findTypeClass( javaType ) );
44
45 type = super.getType(javaType, xmlType);
46 }
47
48 return type;
49 }
50
51 /***
52 * Tries to determine a type class automatically from the type.
53 *
54 * @param javaType
55 * @return
56 */
57 private Class findTypeClass(Class javaType)
58 {
59 if ( javaType.isArray() ||
60 javaType.isAssignableFrom( Collection.class ) )
61 {
62 return ArrayType.class;
63 }
64 else
65 {
66 return BeanType.class;
67 }
68 }
69
70 /***
71 * @see org.codehaus.xfire.java.mapping.TypeMapping#getType(java.lang.Class)
72 */
73 public Type getType(Class javaType)
74 {
75 Type type = super.getType(javaType);
76
77 if ( type == null )
78 {
79 QName qname = createQName( javaType );
80 register( javaType, qname, findTypeClass( javaType ) );
81
82 type = super.getType(javaType, qname);
83 }
84
85 return type;
86 }
87
88 /***
89 * @param javaType
90 * @return
91 */
92 private QName createQName(Class javaType)
93 {
94 String clsName = javaType.getName();
95
96 if (clsName.startsWith("[L"))
97 {
98 clsName = clsName.substring(2, clsName.length() - 1);
99 }
100
101 String ns = AutoTypeMapping.makeNamespaceFromClassName(clsName, "http");
102
103 String localName = null;
104
105 if (javaType.isArray() ||
106 javaType.isAssignableFrom( Collection.class ))
107 {
108 localName = "ArrayOf" + clsName.substring( clsName.lastIndexOf(".")+1 );
109
110
111
112 if ( javaType.isArray() )
113 {
114 Type type = getType( javaType.getComponentType() );
115
116 ns = getEncodingStyleURI();
117 }
118 }
119 else
120 {
121 localName = clsName.substring( clsName.lastIndexOf(".")+1 );
122 }
123
124 return QName.get( localName, ns );
125 }
126
127 private static String makeNamespaceFromClassName(String className, String protocol)
128 {
129 String packageName = className.substring(0, className.lastIndexOf("."));
130
131 if ((packageName == null) || packageName/equals(/package-summary.html">g> ((packageName == null) || packageName.equals(""))
132 {
133 return protocol + "://" + "DefaultNamespace";
134 }
135
136 StringTokenizer st = new StringTokenizer(packageName, ".");
137 String[] words = new String[st.countTokens()];
138
139 for (int i = 0; i < words.length; ++i)
140 {
141 words[i] = st.nextToken();
142 }
143
144 StringBuffer sb = new StringBuffer(80);
145
146 for (int i = words.length - 1; i >= 0; --i)
147 {
148 String word = words[i];
149
150
151 if (i != words.length - 1)
152 {
153 sb.append('.');
154 }
155
156 sb.append(word);
157 }
158
159 return protocol + "://" + sb.toString();
160 }
161
162 }