1 package org.codehaus.xfire.java.mapping;
2
3 import java.util.Hashtable;
4 import java.util.Iterator;
5 import org.codehaus.plexus.configuration.PlexusConfiguration;
6 import org.codehaus.plexus.configuration.PlexusConfigurationException;
7 import org.codehaus.plexus.personality.plexus.lifecycle.phase.Configurable;
8 import org.codehaus.xfire.SOAPConstants;
9 import org.codehaus.xfire.java.type.BooleanType;
10 import org.codehaus.xfire.java.type.DoubleType;
11 import org.codehaus.xfire.java.type.FloatType;
12 import org.codehaus.xfire.java.type.IntType;
13 import org.codehaus.xfire.java.type.LongType;
14 import org.codehaus.xfire.plexus.PlexusXFireComponent;
15 import org.dom4j.QName;
16
17 /***
18 * The default implementation of TypeMappingRegistry.
19 *
20 * @author <a href="mailto:dan@envoisolutions.com">Dan Diephouse</a>
21 * @since Feb 22, 2004
22 */
23 public class DefaultTypeMappingRegistry
24 extends PlexusXFireComponent
25 implements TypeMappingRegistry, Configurable
26 {
27 private Hashtable registry;
28
29 private TypeMapping defaultTM;
30
31 public DefaultTypeMappingRegistry()
32 {
33 registry = new Hashtable();
34 }
35
36 /***
37 * @see org.codehaus.xfire.java.mapping.TypeMappingRegistry#register(java.lang.String, org.codehaus.xfire.java.encoding.TypeMapping)
38 */
39 public TypeMapping register( String encodingStyleURI, TypeMapping mapping )
40 {
41 TypeMapping previous = (TypeMapping) registry.get( encodingStyleURI );
42
43 mapping.setEncodingStyleURI( encodingStyleURI );
44
45 registry.put( encodingStyleURI, mapping );
46
47 return previous;
48 }
49
50 /***
51 * @see org.codehaus.xfire.java.mapping.TypeMappingRegistry#registerDefault(org.codehaus.xfire.java.encoding.TypeMapping)
52 */
53 public void registerDefault( TypeMapping mapping )
54 {
55 defaultTM = mapping;
56 }
57
58 /***
59 * @see org.codehaus.xfire.java.mapping.TypeMappingRegistry#getDefaultTypeMapping()
60 */
61 public TypeMapping getDefaultTypeMapping()
62 {
63 return defaultTM;
64 }
65
66 /***
67 * @see org.codehaus.xfire.java.mapping.TypeMappingRegistry#getRegisteredEncodingStyleURIs()
68 */
69 public String[] getRegisteredEncodingStyleURIs()
70 {
71 return (String[]) registry.keySet().toArray(new String[0]);
72 }
73
74 /***
75 * @see org.codehaus.xfire.java.mapping.TypeMappingRegistry#getTypeMapping(java.lang.String)
76 */
77 public TypeMapping getTypeMapping( String encodingStyleURI )
78 {
79 return (TypeMapping) registry.get(encodingStyleURI);
80 }
81
82 /***
83 * @see org.codehaus.xfire.java.mapping.TypeMappingRegistry#createTypeMapping()
84 */
85 public TypeMapping createTypeMapping( boolean autoTypes )
86 {
87 return createTypeMapping( getDefaultTypeMapping(), autoTypes );
88 }
89
90 /***
91 * @see org.codehaus.xfire.java.mapping.TypeMappingRegistry#createTypeMapping(java.lang.String)
92 */
93 public TypeMapping createTypeMapping( String parentNamespace, boolean autoTypes )
94 {
95 return createTypeMapping( getTypeMapping( parentNamespace ), autoTypes );
96 }
97
98 protected TypeMapping createTypeMapping( TypeMapping parent, boolean autoTypes )
99 {
100 if ( autoTypes )
101 {
102 return new AutoTypeMapping( parent );
103 }
104 else
105 {
106 return new CustomTypeMapping( parent );
107 }
108 }
109
110 /***
111 * @see org.codehaus.xfire.java.mapping.TypeMappingRegistry#unregisterTypeMapping(java.lang.String)
112 */
113 public TypeMapping unregisterTypeMapping( String encodingStyleURI )
114 {
115 TypeMapping tm = (TypeMapping) registry.get(encodingStyleURI);
116 registry.remove(encodingStyleURI);
117 return tm;
118 }
119
120 /***
121 * @see org.codehaus.xfire.java.mapping.TypeMappingRegistry#removeTypeMapping(org.codehaus.xfire.java.encoding.TypeMapping)
122 */
123 public boolean removeTypeMapping( TypeMapping mapping )
124 {
125 int n = 0;
126
127 for ( Iterator itr = registry.values().iterator(); itr.hasNext(); )
128 {
129 if ( itr.next().equals( mapping ) )
130 {
131 itr.remove();
132 n++;
133 }
134 }
135
136 return (n > 0);
137 }
138
139 /***
140 * @see org.codehaus.xfire.java.mapping.TypeMappingRegistry#clear()
141 */
142 public void clear()
143 {
144 registry.clear();
145 }
146
147 /***
148 * @see org.apache.avalon.framework.configuration.Configurable#configure(org.apache.avalon.framework.configuration.Configuration)
149 */
150 public void configure(PlexusConfiguration config) throws PlexusConfigurationException
151 {
152 PlexusConfiguration tmConfig[] = config.getChildren("typeMapping");
153
154 for ( int i = 0; i < tmConfig.length; i++ )
155 {
156 configureTypeMapping( tmConfig[i] );
157 }
158 }
159
160 /***
161 * @param configuration
162 */
163 private void configureTypeMapping(PlexusConfiguration configuration)
164 throws PlexusConfigurationException
165 {
166 TypeMapping tm = createTypeMapping(false);
167
168 register( configuration.getAttribute( "namespace" ), tm );
169
170 if ( Boolean.valueOf( configuration.getAttribute("default", "false") ).booleanValue() )
171 registerDefault( tm );
172
173 PlexusConfiguration[] types = configuration.getChildren( "type" );
174
175
176
177 tm.register(boolean.class, QName.get("boolean", SOAPConstants.XSD), BooleanType.class);
178 tm.register(int.class, QName.get("int", SOAPConstants.XSD), IntType.class);
179 tm.register(double.class, QName.get("double", SOAPConstants.XSD), DoubleType.class);
180 tm.register(float.class, QName.get("float", SOAPConstants.XSD), FloatType.class);
181 tm.register(long.class, QName.get("long", SOAPConstants.XSD), LongType.class);
182
183 for ( int i = 0; i < types.length; i++ )
184 {
185 configureType( types[i], tm );
186 }
187 }
188
189 private void configureType( PlexusConfiguration configuration, TypeMapping tm )
190 throws PlexusConfigurationException
191 {
192 try
193 {
194 String ns = configuration.getAttribute("namespace");
195 String name = configuration.getAttribute("name");
196 QName qname = QName.get( name, ns );
197
198 Class clazz = loadClass( configuration.getAttribute("class") );
199 Class typeClass = loadClass( configuration.getAttribute("type") );
200
201 tm.register( clazz,
202 qname,
203 typeClass );
204
205 getLogger().debug( "Registered " + typeClass.getName() +
206 " for " + qname + " with class " + clazz.getName() );
207 }
208 catch (Exception e)
209 {
210 if ( e instanceof PlexusConfigurationException )
211 throw (PlexusConfigurationException) e;
212
213 throw new PlexusConfigurationException( "Could not configure type.", e );
214 }
215 }
216
217 /***
218 * Load a class from the class loader.
219 *
220 * @param className The name of the class.
221 * @return The class.
222 * @throws Exception
223 */
224 private Class loadClass( String className )
225 throws Exception
226 {
227
228 if ( className.endsWith("[]") )
229 {
230 className = "[L" + className.substring(0, className.length() - 2 ) + ";";
231 }
232
233 return getClass().getClassLoader().loadClass( className );
234 }
235 }