KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > axis > encoding > TypeMappingRegistryImpl


1 /*
2  * The Apache Software License, Version 1.1
3  *
4  *
5  * Copyright (c) 2001-2003 The Apache Software Foundation. All rights
6  * reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. The end-user documentation included with the redistribution,
21  * if any, must include the following acknowledgment:
22  * "This product includes software developed by the
23  * Apache Software Foundation (http://www.apache.org/)."
24  * Alternately, this acknowledgment may appear in the software itself,
25  * if and wherever such third-party acknowledgments normally appear.
26  *
27  * 4. The names "Axis" and "Apache Software Foundation" must
28  * not be used to endorse or promote products derived from this
29  * software without prior written permission. For written
30  * permission, please contact apache@apache.org.
31  *
32  * 5. Products derived from this software may not be called "Apache",
33  * nor may "Apache" appear in their name, without prior written
34  * permission of the Apache Software Foundation.
35  *
36  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
40  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47  * SUCH DAMAGE.
48  * ====================================================================
49  *
50  * This software consists of voluntary contributions made by many
51  * individuals on behalf of the Apache Software Foundation. For more
52  * information on the Apache Software Foundation, please see
53  * <http://www.apache.org/>.
54  */

55
56 package org.jboss.axis.encoding;
57
58 import org.jboss.axis.Constants;
59 import org.jboss.axis.utils.Messages;
60
61 import java.util.HashMap JavaDoc;
62
63 /**
64  * <p/>
65  * The TypeMappingRegistry keeps track of the individual TypeMappings.
66  * </p>
67  * <p/>
68  * The TypeMappingRegistry for axis contains a default type mapping
69  * that is set for either SOAP 1.1 or SOAP 1.2
70  * The default type mapping is a singleton used for the entire
71  * runtime and should not have anything new registered in it.
72  * </p>
73  * <p/>
74  * Instead the new TypeMappings for the deploy and service are
75  * made in a separate TypeMapping which is identified by
76  * the soap encoding. These new TypeMappings delegate back to
77  * the default type mapping when information is not found.
78  * </p>
79  * <p/>
80  * So logically we have:
81  * <pre>
82  * TMR
83  * | |
84  * | +---------------> DefaultTM
85  * | ^
86  * | |
87  * +----> TM --delegate---+
88  * </pre>
89  * <p/>
90  * But in the implementation, the TMR references
91  * "delegate" TypeMappings (TM') which then reference the actual TM's
92  * </p>
93  * <p/>
94  * So the picture is really:
95  * <pre>
96  * TMR
97  * | |
98  * | +-----------TM'------> DefaultTM
99  * | ^
100  * | |
101  * +-TM'-> TM ----+
102  * </pre>
103  * <p/>
104  * This extra indirection is necessary because the user may want to
105  * change the default type mapping. In such cases, the TMR
106  * just needs to adjust the TM' for the DefaultTM, and all of the
107  * other TMs will properly delegate to the new one. Here's the picture:
108  * <pre>
109  * TMR
110  * | |
111  * | +-----------TM'--+ DefaultTM
112  * | ^ |
113  * | | +---> New User Defined Default TM
114  * +-TM'-> TM ----+
115  * </pre>
116  * <p/>
117  * The other reason that it is necessary is when a deploy
118  * has a TMR, and then TMR's are defined for the individual services
119  * in such cases the delegate() method is invoked on the service
120  * to delegate to the deploy TMR
121  * <pre>
122  * Deploy TMR
123  * | |
124  * | +-----------TM'------> DefaultTM
125  * | ^
126  * | |
127  * +-TM'-> TM ----+
128  * <p/>
129  * Service TMR
130  * | |
131  * | +-----------TM'------> DefaultTM
132  * | ^
133  * | |
134  * +-TM'-> TM ----+
135  * <p/>
136  * ServiceTMR.delegate(DeployTMR)
137  * <p/>
138  * Deploy TMR
139  * | |
140  * | +------------TM'------> DefaultTM
141  * | ^ ^
142  * | | |
143  * +-TM'-> TM ----+ |
144  * ^ |
145  * +-------+ |
146  * | |
147  * | Service TMR |
148  * | | | |
149  * | | +----------TM'-+
150  * | |
151  * | |
152  * | +-TM'-> TM +
153  * | |
154  * +----------------+
155  * </pre>
156  * <p/>
157  * So now the service uses the DefaultTM of the Deploy TMR, and
158  * the Service TM properly delegates to the deploy's TM. And
159  * if either the deploy defaultTM or TMs change, the links are not broken.
160  * </p>
161  *
162  * @author James Snell (jasnell@us.ibm.com)
163  * @author Sam Ruby (rubys@us.ibm.com)
164  * Re-written for JAX-RPC Compliance by
165  * @author Rich Scheuerle (scheu@us.ibm.com
166  */

167 public class TypeMappingRegistryImpl implements TypeMappingRegistry
168 {
169
170    private HashMap JavaDoc mapTM; // Type Mappings keyed with Namespace URI
171
private TypeMapping defaultDelTM; // Delegate to default Type Mapping
172

173
174    /**
175     * Construct TypeMappingRegistry
176     */

177    public TypeMappingRegistryImpl()
178    {
179       mapTM = new HashMap JavaDoc();
180       if (Constants.URI_DEFAULT_SOAP_ENC.equals(Constants.URI_SOAP11_ENC))
181       {
182          defaultDelTM =
183                  new TypeMappingImpl(DefaultTypeMappingImpl.getSingleton());
184       }
185       else
186       {
187          defaultDelTM =
188                  new TypeMappingImpl(DefaultSOAPEncodingTypeMappingImpl.create());
189       }
190    }
191
192    /**
193     * delegate
194     * <p/>
195     * Changes the contained type mappings to delegate to
196     * their corresponding types in the secondary TMR.
197     */

198    public void delegate(TypeMappingRegistry secondaryTMR)
199    {
200
201       if (secondaryTMR == null || secondaryTMR == this)
202       {
203          return;
204       }
205       String JavaDoc[] keys = secondaryTMR.getRegisteredEncodingStyleURIs();
206 // String[] keys = null;
207
if (keys != null)
208       {
209          for (int i = 0; i < keys.length; i++)
210          {
211             try
212             {
213                String JavaDoc nsURI = keys[i];
214                TypeMapping tm = (TypeMapping)getTypeMapping(nsURI);
215                if (tm == null || tm == getDefaultTypeMapping())
216                {
217                   tm = (TypeMapping)createTypeMapping();
218                   tm.setSupportedEncodings(new String JavaDoc[]{nsURI});
219                   register(nsURI, tm);
220                }
221
222                if (tm != null)
223                {
224                   // Get the secondaryTMR's TM'
225
TypeMapping del = (TypeMapping)
226                           ((TypeMappingRegistryImpl)
227                           secondaryTMR).mapTM.get(nsURI);
228                   tm.setDelegate(del);
229                }
230
231             }
232             catch (Exception JavaDoc e)
233             {
234             }
235          }
236       }
237       // Change our defaultDelTM to delegate to the one in
238
// the secondaryTMR
239
if (defaultDelTM != null)
240       {
241          defaultDelTM.setDelegate(((TypeMappingRegistryImpl)secondaryTMR).defaultDelTM);
242       }
243
244    }
245
246
247
248    /********* JAX-RPC Compliant Method Definitions *****************/
249
250    /**
251     * The method register adds a TypeMapping instance for a specific
252     * namespace
253     *
254     * @param namespaceURI
255     * @param mapping - TypeMapping for specific namespaces
256     * @return Previous TypeMapping associated with the specified namespaceURI,
257     * or null if there was no TypeMapping associated with the specified namespaceURI
258     * @throws JAXRPCException - If there is any error in the registration
259     * of the TypeMapping for the specified namespace URI
260     */

261    public javax.xml.rpc.encoding.TypeMapping JavaDoc register(String JavaDoc namespaceURI,
262                                                       javax.xml.rpc.encoding.TypeMapping JavaDoc mapping)
263    {
264 // namespaceURI = "";
265
if (mapping == null ||
266               !(mapping instanceof TypeMapping))
267       {
268          throw new IllegalArgumentException JavaDoc(Messages.getMessage("badTypeMapping"));
269       }
270       if (namespaceURI == null)
271       {
272          throw new java.lang.IllegalArgumentException JavaDoc(Messages.getMessage("nullNamespaceURI"));
273       }
274       // Get or create a TypeMappingDelegate and set it to
275
// delegate to the new mapping.
276
TypeMappingDelegate del = (TypeMappingDelegate)
277               mapTM.get(namespaceURI);
278       if (del == null)
279       {
280          del = new TypeMappingDelegate((TypeMapping)mapping);
281          mapTM.put(namespaceURI, del);
282       }
283       else
284       {
285          del.setDelegate((TypeMapping)mapping);
286       }
287       return null; // Needs works
288
}
289
290    /**
291     * The method register adds a default TypeMapping instance. If a specific
292     * TypeMapping is not found, the default TypeMapping is used.
293     *
294     * @param mapping - TypeMapping for specific type namespaces
295     * <p/>
296     * java.lang.IllegalArgumentException -
297     * if an invalid type mapping is specified or the delegate is already set
298     */

299    public void registerDefault(javax.xml.rpc.encoding.TypeMapping JavaDoc mapping)
300    {
301       if (mapping == null ||
302               !(mapping instanceof TypeMapping))
303       {
304          throw new IllegalArgumentException JavaDoc(Messages.getMessage("badTypeMapping"));
305       }
306
307       /* Don't allow this call after the delegate() method since
308        * the TMR's TypeMappings will be using the default type mapping
309        * of the secondary TMR.
310        */

311       if (defaultDelTM.getDelegate() instanceof TypeMappingDelegate)
312       {
313          throw new IllegalArgumentException JavaDoc(Messages.getMessage("defaultTypeMappingSet"));
314       }
315
316       defaultDelTM.setDelegate((TypeMapping)mapping);
317    }
318
319    /**
320     * Gets the TypeMapping for the namespace. If not found, the default
321     * TypeMapping is returned.
322     *
323     * @param namespaceURI - The namespace URI of a Web Service
324     * @return The registered TypeMapping
325     * (which may be the default TypeMapping) or null.
326     */

327    public javax.xml.rpc.encoding.TypeMapping JavaDoc
328            getTypeMapping(String JavaDoc namespaceURI)
329    {
330 // namespaceURI = "";
331
TypeMapping del = (TypeMapping)mapTM.get(namespaceURI);
332       TypeMapping tm = null;
333       if (del != null)
334       {
335          tm = del.getDelegate();
336       }
337       if (tm == null)
338       {
339          tm = (TypeMapping)getDefaultTypeMapping();
340       }
341       return tm;
342    }
343
344    /**
345     * Obtain a type mapping for the given encodingStyle. If no specific
346     * mapping exists for this encodingStyle, we will create and register
347     * one before returning it.
348     *
349     * @param encodingStyle
350     * @return a registered TypeMapping for the given encodingStyle
351     */

352    public TypeMapping getOrMakeTypeMapping(String JavaDoc encodingStyle)
353    {
354       TypeMapping del = (TypeMapping)mapTM.get(encodingStyle);
355       TypeMapping tm = null;
356       if (del != null)
357       {
358          tm = del.getDelegate();
359       }
360       if (tm == null)
361       {
362          tm = (TypeMapping)createTypeMapping();
363          tm.setSupportedEncodings(new String JavaDoc[]{encodingStyle});
364          register(encodingStyle, tm);
365       }
366       return tm;
367    }
368
369    /**
370     * Unregisters the TypeMapping for the namespace.
371     *
372     * @param namespaceURI - The namespace URI
373     * @return The registered TypeMapping .
374     */

375    public javax.xml.rpc.encoding.TypeMapping JavaDoc
376            unregisterTypeMapping(String JavaDoc namespaceURI)
377    {
378       TypeMapping del = (TypeMapping)mapTM.get(namespaceURI);
379       TypeMapping tm = null;
380       if (del != null)
381       {
382          tm = del.getDelegate();
383          del.setDelegate(null);
384       }
385       return tm;
386    }
387
388    /**
389     * Removes the TypeMapping for the namespace.
390     *
391     * @param mapping The type mapping to remove
392     * @return true if found and removed
393     */

394    public boolean removeTypeMapping(javax.xml.rpc.encoding.TypeMapping JavaDoc mapping)
395    {
396       String JavaDoc[] ns = getRegisteredEncodingStyleURIs();
397       boolean rc = false;
398       for (int i = 0; i < ns.length; i++)
399       {
400          if (getTypeMapping(ns[i]) == mapping)
401          {
402             rc = true;
403             unregisterTypeMapping(ns[i]);
404          }
405       }
406       return rc;
407    }
408
409    /**
410     * Creates a new empty TypeMapping object for the specified
411     * encoding style or XML schema namespace.
412     *
413     * @return An empty generic TypeMapping object
414     */

415    public javax.xml.rpc.encoding.TypeMapping JavaDoc createTypeMapping()
416    {
417       return new TypeMappingImpl(defaultDelTM);
418    }
419
420
421    /**
422     * Gets a list of namespace URIs registered with this TypeMappingRegistry.
423     *
424     * @return String[] containing names of all registered namespace URIs
425     */

426    public String JavaDoc[] getRegisteredEncodingStyleURIs()
427    {
428       java.util.Set JavaDoc s = mapTM.keySet();
429       if (s != null)
430       {
431          String JavaDoc[] rc = new String JavaDoc[s.size()];
432          int i = 0;
433          java.util.Iterator JavaDoc it = s.iterator();
434          while (it.hasNext())
435          {
436             rc[i++] = (String JavaDoc)it.next();
437          }
438          return rc;
439       }
440       return null;
441    }
442
443
444    /**
445     * Removes all TypeMappings and namespaceURIs from this TypeMappingRegistry.
446     */

447    public void clear()
448    {
449       mapTM.clear();
450    }
451
452    /**
453     * Return the default TypeMapping
454     *
455     * @return TypeMapping or null
456     */

457    public javax.xml.rpc.encoding.TypeMapping JavaDoc getDefaultTypeMapping()
458    {
459       TypeMapping defaultTM = defaultDelTM;
460       while (defaultTM != null && defaultTM instanceof TypeMappingDelegate)
461       {
462          defaultTM = defaultTM.getDelegate();
463       }
464       return defaultTM;
465    }
466
467 }
468
Popular Tags