View Javadoc

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         // register primitive types manually since there is no way
176         // to do Class.forName("boolean") et al.
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         // Handle array'd types.
228         if ( className.endsWith("[]") )
229         {
230             className = "[L" + className.substring(0, className.length() - 2 ) + ";";
231         }
232         
233         return getClass().getClassLoader().loadClass( className );
234     }
235 }