View Javadoc

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             // If this is an array of a primitive type, put the type
111             // we're creating in the default namespace.
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 		ifg> ((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 			// seperate with dot
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 }