Source Code Cross Referenced for JAXBUtils.java in  » Web-Services-AXIS2 » jax-ws » org » apache » axis2 » jaxws » message » databinding » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Web Services AXIS2 » jax ws » org.apache.axis2.jaxws.message.databinding 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Licensed to the Apache Software Foundation (ASF) under one
003:         * or more contributor license agreements. See the NOTICE file
004:         * distributed with this work for additional information
005:         * regarding copyright ownership. The ASF licenses this file
006:         * to you under the Apache License, Version 2.0 (the
007:         * "License"); you may not use this file except in compliance
008:         * with the License. You may obtain a copy of the License at
009:         *
010:         * http://www.apache.org/licenses/LICENSE-2.0
011:         *
012:         * Unless required by applicable law or agreed to in writing,
013:         * software distributed under the License is distributed on an
014:         * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015:         * KIND, either express or implied. See the License for the
016:         * specific language governing permissions and limitations
017:         * under the License.
018:         */
019:        package org.apache.axis2.jaxws.message.databinding;
020:
021:        import org.apache.axis2.java.security.AccessController;
022:        import org.apache.axis2.jaxws.ExceptionFactory;
023:        import org.apache.axis2.jaxws.i18n.Messages;
024:        import org.apache.axis2.jaxws.message.factory.ClassFinderFactory;
025:        import org.apache.axis2.jaxws.registry.FactoryRegistry;
026:        import org.apache.axis2.jaxws.utility.ClassUtils;
027:        import org.apache.axis2.jaxws.utility.JavaUtils;
028:        import org.apache.commons.logging.Log;
029:        import org.apache.commons.logging.LogFactory;
030:
031:        import javax.xml.bind.JAXBContext;
032:        import javax.xml.bind.JAXBException;
033:        import javax.xml.bind.JAXBIntrospector;
034:        import javax.xml.bind.Marshaller;
035:        import javax.xml.bind.Unmarshaller;
036:        import javax.xml.ws.Holder;
037:        import java.io.File;
038:        import java.io.IOException;
039:        import java.io.UnsupportedEncodingException;
040:        import java.net.URL;
041:        import java.net.URLDecoder;
042:        import java.security.PrivilegedActionException;
043:        import java.security.PrivilegedExceptionAction;
044:        import java.util.ArrayList;
045:        import java.util.Enumeration;
046:        import java.util.Iterator;
047:        import java.util.List;
048:        import java.util.Map;
049:        import java.util.TreeSet;
050:        import java.util.concurrent.ConcurrentHashMap;
051:
052:        /**
053:         * JAXB Utilites to pool JAXBContext and related objects. Currently the JAXBContext is pooled by
054:         * Class name.  We may change this to create and pool by package name.
055:         */
056:        public class JAXBUtils {
057:
058:            private static final Log log = LogFactory.getLog(JAXBUtils.class);
059:
060:            // Create a concurrent map to get the JAXBObject: keys are ClassLoader and Set<String>.
061:            private static Map<ClassLoader, Map<String, JAXBContextValue>> jaxbMap = new ConcurrentHashMap<ClassLoader, Map<String, JAXBContextValue>>();
062:
063:            private static Map<JAXBContext, Unmarshaller> umap = new ConcurrentHashMap<JAXBContext, Unmarshaller>();
064:
065:            private static Map<JAXBContext, Marshaller> mmap = new ConcurrentHashMap<JAXBContext, Marshaller>();
066:
067:            private static Map<JAXBContext, JAXBIntrospector> imap = new ConcurrentHashMap<JAXBContext, JAXBIntrospector>();
068:
069:            // From Lizet Ernand:
070:            // If you really care about the performance, 
071:            // and/or your application is going to read a lot of small documents, 
072:            // then creating Unmarshaller could be relatively an expensive operation. 
073:            // In that case, consider pooling Unmarshaller objects.
074:            // Different threads may reuse one Unmarshaller instance, 
075:            // as long as you don't use one instance from two threads at the same time. 
076:
077:            private static boolean ENABLE_ADV_POOLING = false;
078:
079:            // The maps are freed up when a LOAD FACTOR is hit
080:            private static int MAX_LOAD_FACTOR = 32;
081:
082:            // Construction Type
083:            public enum CONSTRUCTION_TYPE {
084:                BY_CLASS_ARRAY, BY_CONTEXT_PATH, UNKNOWN
085:            }
086:
087:            ;
088:
089:            /**
090:             * Get a JAXBContext for the class
091:             *
092:             * @param contextPackage Set<Package>
093:             * @return JAXBContext
094:             * @throws JAXBException
095:             * @deprecated
096:             */
097:            public static JAXBContext getJAXBContext(
098:                    TreeSet<String> contextPackages) throws JAXBException {
099:                return getJAXBContext(contextPackages,
100:                        new Holder<CONSTRUCTION_TYPE>(), contextPackages
101:                                .toString());
102:            }
103:
104:            /**
105:             * Get a JAXBContext for the class
106:             *
107:             * @param contextPackage  Set<Package>
108:             * @param contructionType (output value that indicates how the context was constructed)
109:             * @return JAXBContext
110:             * @throws JAXBException
111:             */
112:            public static JAXBContext getJAXBContext(
113:                    TreeSet<String> contextPackages,
114:                    Holder<CONSTRUCTION_TYPE> constructionType, String key)
115:                    throws JAXBException {
116:                // JAXBContexts for the same class can be reused and are supposed to be thread-safe
117:                if (log.isDebugEnabled()) {
118:                    log
119:                            .debug("Following packages are in this batch of getJAXBContext() :");
120:                    for (String pkg : contextPackages) {
121:                        log.debug(pkg);
122:                    }
123:                }
124:                // The JAXBContexts are keyed by ClassLoader and the set of Strings
125:                ClassLoader cl = getContextClassLoader();
126:
127:                // Get the innerMap 
128:                Map<String, JAXBContextValue> innerMap = jaxbMap.get(cl);
129:                if (innerMap == null) {
130:                    adjustPoolSize(jaxbMap);
131:                    innerMap = new ConcurrentHashMap<String, JAXBContextValue>();
132:                    jaxbMap.put(cl, innerMap);
133:                }
134:
135:                if (contextPackages == null) {
136:                    contextPackages = new TreeSet<String>();
137:                }
138:
139:                JAXBContextValue contextValue = innerMap.get(key);
140:                if (contextValue == null) {
141:                    adjustPoolSize(innerMap);
142:
143:                    // A pooled context was not found, so create one and put it in the map.
144:                    synchronized (contextPackages) {
145:                        // synchronized on contextPackages because this method may prune the contextPackages
146:                        contextValue = createJAXBContextValue(contextPackages,
147:                                cl);
148:                    }
149:                    // Put the new context in the map keyed by both the original and current list of packages
150:                    innerMap.put(key, contextValue);
151:                    innerMap.put(contextPackages.toString(), contextValue);
152:                    if (log.isDebugEnabled()) {
153:                        log.debug("JAXBContext [created] for "
154:                                + contextPackages.toString());
155:                    }
156:
157:                } else {
158:                    if (log.isDebugEnabled()) {
159:                        log.debug("JAXBContext [from pool] for "
160:                                + contextPackages.toString());
161:                    }
162:                }
163:                constructionType.value = contextValue.constructionType;
164:                return contextValue.jaxbContext;
165:            }
166:
167:            /**
168:             * Create a JAXBContext using the contextPackages
169:             *
170:             * @param contextPackages Set<String>
171:             * @param cl              ClassLoader
172:             * @return JAXBContextValue (JAXBContext + constructionType)
173:             * @throws JAXBException
174:             */
175:            private static JAXBContextValue createJAXBContextValue(
176:                    TreeSet<String> contextPackages, ClassLoader cl)
177:                    throws JAXBException {
178:
179:                JAXBContextValue contextValue = null;
180:                if (log.isDebugEnabled()) {
181:                    log
182:                            .debug("Following packages are in this batch of getJAXBContext() :");
183:                    for (String pkg : contextPackages) {
184:                        log.debug(pkg);
185:                    }
186:                }
187:                // The contextPackages is a set of package names that are constructed using PackageSetBuilder.
188:                // PackageSetBuilder gets the packages names from various sources.
189:                //   a) It walks the various annotations on the WebService collecting package names.
190:                //   b) It walks the wsdl/schemas and builds package names for each target namespace.
191:                //
192:                // The combination of these two sources should produce all of the package names.
193:                // -------------
194:                // Note that (b) is necessary for the following case:
195:                // An operation has a parameter named BASE.
196:                // Object DERIVED is an extension of BASE and is defined in a different package/schema.
197:                // In this case, there will not be any annotations on the WebService that reference DERIVED.
198:                // The only way to find the package for DERIVED is to walk the schemas.
199:                // -------------
200:
201:                Iterator<String> it = contextPackages.iterator();
202:                while (it.hasNext()) {
203:                    String p = it.next();
204:                    // Don't consider java and javax packages
205:                    // REVIEW: We might have to refine this
206:                    if (p.startsWith("java.") || p.startsWith("javax.")) {
207:                        it.remove();
208:                    }
209:                }
210:
211:                // There are two ways to construct the context.
212:                // 1) USE A CONTEXTPATH, which is a string containing
213:                //    all of the packages separated by colons.
214:                // 2) USE A CLASS[], which is an array of all of the classes
215:                //    involved in the marshal/unmarshal.
216:                //   
217:                // There are pros/cons with both approaches.
218:                // USE A CONTEXTPATH: 
219:                //    Pros: preferred way of doing this.  
220:                //          performant
221:                //          most dynamic
222:                //    Cons: Each package in context path must have an ObjectFactory
223:                //        
224:                //
225:                // USE CLASS[]:
226:                //    Pros: Doesn't require ObjectFactory in each package
227:                //    Cons: Hard to set up, must account for JAX-WS classes, etc.
228:                //          Does not work if arrays of classes are needed
229:                //          slower
230:                //
231:                //  The following code attempts to build a context path.  It then
232:                //  choose one of the two constructions above (prefer USE A CONTEXT_PATH)
233:                //
234:
235:                // The packages are examined to see if they have ObjectFactory/package-info classes.
236:                // Invalid packages are removed from the list
237:                it = contextPackages.iterator();
238:                boolean contextConstruction = true;
239:                boolean isJAXBFound = false;
240:                while (it.hasNext()) {
241:                    String p = it.next();
242:                    // See if this package has an ObjectFactory or package-info
243:                    if (checkPackage(p, cl)) {
244:                        // Flow to here indicates package can be used for CONTEXT construction
245:                        isJAXBFound = true;
246:                        if (log.isDebugEnabled()) {
247:                            log
248:                                    .debug("Package "
249:                                            + p
250:                                            + " contains an ObjectFactory or package-info class.");
251:                        }
252:                    } else {
253:                        // Flow to here indicates that the package is not valid for context construction.
254:                        // Perhaps the package is invalid.
255:                        if (log.isDebugEnabled()) {
256:                            log
257:                                    .debug("Package "
258:                                            + p
259:                                            + " does not contain an ObjectFactory or package-info class.  Searching for JAXB classes");
260:                        }
261:                        List<Class> classes = null;
262:                        classes = getAllClassesFromPackage(p, cl);
263:                        if (classes == null || classes.size() == 0) {
264:                            if (log.isDebugEnabled()) {
265:                                log
266:                                        .debug("Package "
267:                                                + p
268:                                                + " does not have any JAXB classes.  It is removed from the JAXB context path.");
269:                            }
270:                            it.remove();
271:                        } else {
272:                            // Classes are found in the package.  We cannot use the CONTEXT construction
273:                            contextConstruction = false;
274:                            if (log.isDebugEnabled()) {
275:                                log
276:                                        .debug("Package "
277:                                                + p
278:                                                + " does not contain ObjectFactory, but it does contain other JAXB classes.");
279:                            }
280:                        }
281:                    }
282:                }
283:
284:                if (!isJAXBFound) {
285:                    if (log.isDebugEnabled()) {
286:                        log
287:                                .debug("Both ObjectFactory & package-info not found in package hierachy");
288:                    }
289:                }
290:
291:                // The code above may have removed some packages from the list. 
292:                // Retry our lookup with the updated list
293:                Map<String, JAXBContextValue> innerMap = jaxbMap.get(cl);
294:                if (innerMap != null) {
295:                    contextValue = innerMap.get(contextPackages.toString());
296:                    if (contextValue != null) {
297:                        if (log.isDebugEnabled()) {
298:                            log
299:                                    .debug("Successfully found JAXBContext with updated context list:"
300:                                            + contextValue.jaxbContext
301:                                                    .toString());
302:                        }
303:                        return contextValue;
304:                    }
305:                }
306:
307:                // CONTEXT construction
308:                if (contextConstruction) {
309:                    JAXBContext context = createJAXBContextUsingContextPath(
310:                            contextPackages, cl);
311:                    if (context != null) {
312:                        contextValue = new JAXBContextValue(context,
313:                                CONSTRUCTION_TYPE.BY_CONTEXT_PATH);
314:                    }
315:                }
316:
317:                // CLASS construction
318:                if (contextValue == null) {
319:                    it = contextPackages.iterator();
320:                    List<Class> fullList = new ArrayList<Class>();
321:                    while (it.hasNext()) {
322:                        String pkg = it.next();
323:                        fullList.addAll(getAllClassesFromPackage(pkg, cl));
324:                    }
325:                    //Lets add all common array classes
326:                    addCommonArrayClasses(fullList);
327:                    Class[] classArray = fullList.toArray(new Class[0]);
328:                    JAXBContext context = JAXBContext_newInstance(classArray);
329:                    if (context != null) {
330:                        contextValue = new JAXBContextValue(context,
331:                                CONSTRUCTION_TYPE.BY_CLASS_ARRAY);
332:                    }
333:                }
334:                if (log.isDebugEnabled()) {
335:                    log.debug("Successfully created JAXBContext "
336:                            + contextValue.jaxbContext.toString());
337:                }
338:                return contextValue;
339:            }
340:
341:            /**
342:             * Get the unmarshaller.  You must call releaseUnmarshaller to put it back into the pool
343:             *
344:             * @param context JAXBContext
345:             * @return Unmarshaller
346:             * @throws JAXBException
347:             */
348:            public static Unmarshaller getJAXBUnmarshaller(JAXBContext context)
349:                    throws JAXBException {
350:                if (!ENABLE_ADV_POOLING) {
351:                    if (log.isDebugEnabled()) {
352:                        log.debug("Unmarshaller created [no pooling]");
353:                    }
354:                    return context.createUnmarshaller();
355:                }
356:                Unmarshaller u = umap.remove(context);
357:                if (u == null) {
358:                    if (log.isDebugEnabled()) {
359:                        log.debug("Unmarshaller created [not in pool]");
360:                    }
361:                    u = context.createUnmarshaller();
362:                } else {
363:                    if (log.isDebugEnabled()) {
364:                        log.debug("Unmarshaller obtained [from  pool]");
365:                    }
366:                }
367:                return u;
368:            }
369:
370:            /**
371:             * Release Unmarshaller Do not call this method if an exception occurred while using the
372:             * Unmarshaller. We object my be in an invalid state.
373:             *
374:             * @param context      JAXBContext
375:             * @param unmarshaller Unmarshaller
376:             */
377:            public static void releaseJAXBUnmarshaller(JAXBContext context,
378:                    Unmarshaller unmarshaller) {
379:                if (log.isDebugEnabled()) {
380:                    log.debug("Unmarshaller placed back into pool");
381:                }
382:                if (ENABLE_ADV_POOLING) {
383:                    adjustPoolSize(umap);
384:                    umap.put(context, unmarshaller);
385:                }
386:            }
387:
388:            /**
389:             * Get JAXBMarshaller
390:             *
391:             * @param context JAXBContext
392:             * @return Marshaller
393:             * @throws JAXBException
394:             */
395:            public static Marshaller getJAXBMarshaller(JAXBContext context)
396:                    throws JAXBException {
397:                Marshaller m = null;
398:                if (!ENABLE_ADV_POOLING) {
399:                    if (log.isDebugEnabled()) {
400:                        log.debug("Marshaller created [no pooling]");
401:                    }
402:                    m = context.createMarshaller();
403:                } else {
404:                    m = mmap.remove(context);
405:                    if (m == null) {
406:                        if (log.isDebugEnabled()) {
407:                            log.debug("Marshaller created [not in pool]");
408:                        }
409:                        m = context.createMarshaller();
410:                    } else {
411:                        if (log.isDebugEnabled()) {
412:                            log.debug("Marshaller obtained [from  pool]");
413:                        }
414:                    }
415:                }
416:                m.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE); // No PIs
417:                return m;
418:            }
419:
420:            /**
421:             * releaseJAXBMarshalller Do not call this method if an exception occurred while using the
422:             * Marshaller. We object my be in an invalid state.
423:             *
424:             * @param context    JAXBContext
425:             * @param marshaller Marshaller
426:             */
427:            public static void releaseJAXBMarshaller(JAXBContext context,
428:                    Marshaller marshaller) {
429:                if (log.isDebugEnabled()) {
430:                    log.debug("Marshaller placed back into pool");
431:                }
432:                if (ENABLE_ADV_POOLING) {
433:                    adjustPoolSize(mmap);
434:                    mmap.put(context, marshaller);
435:                }
436:            }
437:
438:            /**
439:             * get JAXB Introspector
440:             *
441:             * @param context JAXBContext
442:             * @return JAXBIntrospector
443:             * @throws JAXBException
444:             */
445:            public static JAXBIntrospector getJAXBIntrospector(
446:                    JAXBContext context) throws JAXBException {
447:                JAXBIntrospector i = null;
448:                if (!ENABLE_ADV_POOLING) {
449:                    if (log.isDebugEnabled()) {
450:                        log.debug("JAXBIntrospector created [no pooling]");
451:                    }
452:                    i = context.createJAXBIntrospector();
453:                } else {
454:                    i = imap.remove(context);
455:                    if (i == null) {
456:                        if (log.isDebugEnabled()) {
457:                            log.debug("JAXBIntrospector created [not in pool]");
458:                        }
459:                        i = context.createJAXBIntrospector();
460:                    } else {
461:                        if (log.isDebugEnabled()) {
462:                            log.debug("JAXBIntrospector obtained [from  pool]");
463:                        }
464:                    }
465:                }
466:                return i;
467:            }
468:
469:            /**
470:             * Release JAXBIntrospector Do not call this method if an exception occurred while using the
471:             * JAXBIntrospector. We object my be in an invalid state.
472:             *
473:             * @param context      JAXBContext
474:             * @param introspector JAXBIntrospector
475:             */
476:            public static void releaseJAXBIntrospector(JAXBContext context,
477:                    JAXBIntrospector introspector) {
478:                if (log.isDebugEnabled()) {
479:                    log.debug("JAXBIntrospector placed back into pool");
480:                }
481:                if (ENABLE_ADV_POOLING) {
482:                    adjustPoolSize(imap);
483:                    imap.put(context, introspector);
484:                }
485:            }
486:
487:            /**
488:             * @param p  Package
489:             * @param cl
490:             * @return true if each package has a ObjectFactory class or package-info
491:             */
492:            private static boolean checkPackage(String p, ClassLoader cl) {
493:
494:                // Each package must have an ObjectFactory
495:                if (log.isDebugEnabled()) {
496:                    log.debug("checking package :" + p);
497:
498:                }
499:                try {
500:                    Class cls = forName(p + ".ObjectFactory", false, cl);
501:                    if (cls != null) {
502:                        return true;
503:                    }
504:                    //Catch Throwable as ClassLoader can throw an NoClassDefFoundError that
505:                    //does not extend Exception. So we will absorb any Throwable exception here.
506:                } catch (Throwable e) {
507:                    if (log.isDebugEnabled()) {
508:                        log.debug("ObjectFactory Class Not Found " + e);
509:                        log.debug("...caused by " + e.getCause() + " "
510:                                + JavaUtils.stackToString(e));
511:                    }
512:                }
513:
514:                try {
515:                    Class cls = forName(p + ".package-info", false, cl);
516:                    if (cls != null) {
517:                        return true;
518:                    }
519:                    //Catch Throwable as ClassLoader can throw an NoClassDefFoundError that
520:                    //does not extend Exception. So we will absorb any Throwable exception here.
521:                } catch (Throwable e) {
522:                    if (log.isDebugEnabled()) {
523:                        log.debug("package-info Class Not Found " + e);
524:                        log.debug("...caused by " + e.getCause() + " "
525:                                + JavaUtils.stackToString(e));
526:                    }
527:                }
528:
529:                return false;
530:            }
531:
532:            /**
533:             * Create a JAXBContext using the contextpath approach
534:             *
535:             * @param packages
536:             * @param cl       ClassLoader
537:             * @return JAXBContext or null if unsuccessful
538:             */
539:            private static JAXBContext createJAXBContextUsingContextPath(
540:                    TreeSet<String> packages, ClassLoader cl) {
541:                JAXBContext context = null;
542:                String contextpath = "";
543:
544:                // Iterate through the classes and build the contextpath
545:                Iterator<String> it = packages.iterator();
546:                while (it.hasNext()) {
547:                    String p = it.next();
548:                    if (contextpath.length() != 0) {
549:                        contextpath += ":";
550:                    }
551:                    contextpath += p;
552:
553:                }
554:                try {
555:                    if (log.isDebugEnabled()) {
556:                        log
557:                                .debug("Attempting to create JAXBContext with contextPath="
558:                                        + contextpath);
559:                    }
560:                    context = JAXBContext_newInstance(contextpath, cl);
561:                    if (log.isDebugEnabled()) {
562:                        log.debug("  Successfully created JAXBContext:"
563:                                + context);
564:                    }
565:                } catch (Throwable e) {
566:                    if (log.isDebugEnabled()) {
567:                        log
568:                                .debug("  Unsuccessful: We will now use an alterative JAXBConstruct construction");
569:                        log.debug("  Reason " + e.toString());
570:                    }
571:                }
572:                return context;
573:            }
574:
575:            /**
576:             * This method will return all the Class names needed to construct a JAXBContext
577:             *
578:             * @param pkg         Package
579:             * @param ClassLoader cl
580:             * @return
581:             * @throws ClassNotFoundException if error occurs getting package
582:             */
583:            private static List<Class> getAllClassesFromPackage(String pkg,
584:                    ClassLoader cl) {
585:                if (pkg == null) {
586:                    return new ArrayList<Class>();
587:                }
588:
589:                /*
590:                 * This method is a best effort method.  We should always return an object.
591:                 */
592:
593:                ArrayList<Class> classes = new ArrayList<Class>();
594:
595:                try {
596:                    // This will load classes from directory
597:                    classes.addAll(getClassesFromDirectory(pkg, cl));
598:                } catch (ClassNotFoundException e) {
599:                    if (log.isDebugEnabled()) {
600:                        log
601:                                .debug("getClassesFromDirectory failed to get Classes");
602:                    }
603:                }
604:                try {
605:                    //If Clases not found in directory then look for jar that has these classes
606:                    if (classes.size() <= 0) {
607:                        //This will load classes from jar file.
608:                        ClassFinderFactory cff = (ClassFinderFactory) FactoryRegistry
609:                                .getFactory(ClassFinderFactory.class);
610:                        ClassFinder cf = cff.getClassFinder();
611:                        classes.addAll(cf.getClassesFromJarFile(pkg, cl));
612:                    }
613:                } catch (ClassNotFoundException e) {
614:                    if (log.isDebugEnabled()) {
615:                        log
616:                                .debug("getClassesFromJarFile failed to get Classes");
617:                    }
618:                }
619:
620:                return classes;
621:            }
622:
623:            private static ArrayList<Class> getClassesFromDirectory(String pkg,
624:                    ClassLoader cl) throws ClassNotFoundException {
625:                // This will hold a list of directories matching the pckgname. There may be more than one if a package is split over multiple jars/paths
626:                String pckgname = pkg;
627:                ArrayList<File> directories = new ArrayList<File>();
628:                try {
629:                    String path = pckgname.replace('.', '/');
630:                    // Ask for all resources for the path
631:                    Enumeration<URL> resources = cl.getResources(path);
632:                    while (resources.hasMoreElements()) {
633:                        directories.add(new File(URLDecoder.decode(resources
634:                                .nextElement().getPath(), "UTF-8")));
635:                    }
636:                } catch (UnsupportedEncodingException e) {
637:                    if (log.isDebugEnabled()) {
638:                        log
639:                                .debug(pckgname
640:                                        + " does not appear to be a valid package (Unsupported encoding)");
641:                    }
642:                    throw new ClassNotFoundException(Messages.getMessage(
643:                            "ClassUtilsErr2", pckgname));
644:                } catch (IOException e) {
645:                    if (log.isDebugEnabled()) {
646:                        log
647:                                .debug("IOException was thrown when trying to get all resources for "
648:                                        + pckgname);
649:                    }
650:                    throw new ClassNotFoundException(Messages.getMessage(
651:                            "ClassUtilsErr3", pckgname));
652:                }
653:
654:                ArrayList<Class> classes = new ArrayList<Class>();
655:                // For every directory identified capture all the .class files
656:                for (File directory : directories) {
657:                    if (log.isDebugEnabled()) {
658:                        log.debug("  Adding JAXB classes from directory: "
659:                                + directory.getName());
660:                    }
661:                    if (directory.exists()) {
662:                        // Get the list of the files contained in the package
663:                        String[] files = directory.list();
664:                        for (String file : files) {
665:                            // we are only interested in .class files
666:                            if (file.endsWith(".class")) {
667:                                // removes the .class extension
668:                                // TODO Java2 Sec
669:                                String className = pckgname + '.'
670:                                        + file.substring(0, file.length() - 6);
671:                                try {
672:                                    Class clazz = forName(className, false,
673:                                            getContextClassLoader());
674:                                    // Don't add any interfaces or JAXWS specific classes.  
675:                                    // Only classes that represent data and can be marshalled 
676:                                    // by JAXB should be added.
677:                                    if (!clazz.isInterface()
678:                                            && (clazz.isEnum() || ClassUtils
679:                                                    .getDefaultPublicConstructor(clazz) != null)
680:                                            && !ClassUtils.isJAXWSClass(clazz)
681:                                            && !java.lang.Exception.class
682:                                                    .isAssignableFrom(clazz)) {
683:
684:                                        // Ensure that all the referenced classes are loadable too
685:                                        clazz.getDeclaredMethods();
686:                                        clazz.getDeclaredFields();
687:
688:                                        if (log.isDebugEnabled()) {
689:                                            log.debug("Adding class: " + file);
690:                                        }
691:                                        classes.add(clazz);
692:
693:                                        // REVIEW:
694:                                        // Support of RPC list (and possibly other scenarios) requires that the array classes should also be present.
695:                                        // This is a hack until we can determine how to get this information.
696:
697:                                        // The arrayName and loadable name are different.  Get the loadable
698:                                        // name, load the array class, and add it to our list
699:                                        //className += "[]";
700:                                        //String loadableName = ClassUtils.getLoadableClassName(className);
701:
702:                                        //Class aClazz = Class.forName(loadableName, false, Thread.currentThread().getContextClassLoader());
703:                                    }
704:                                    //Catch Throwable as ClassLoader can throw an NoClassDefFoundError that
705:                                    //does not extend Exception
706:                                } catch (Throwable e) {
707:                                    if (log.isDebugEnabled()) {
708:                                        log
709:                                                .debug("Tried to load class "
710:                                                        + className
711:                                                        + " while constructing a JAXBContext.  This class will be skipped.  Processing Continues.");
712:                                        log
713:                                                .debug("  The reason that class could not be loaded:"
714:                                                        + e.toString());
715:                                        log.debug(JavaUtils.stackToString(e));
716:                                    }
717:                                }
718:
719:                            }
720:                        }
721:                    }
722:                }
723:
724:                return classes;
725:            }
726:
727:            private static String[] commonArrayClasses = new String[] {
728:                    // primitives
729:                    "boolean[]", "byte[]", "char[][]", "double[]", "float[]",
730:                    "int[]", "long[]", "short[]",
731:                    "java.lang.String[]",
732:                    // Others
733:                    "java.lang.Object[]", "java.awt.Image[]",
734:                    "java.math.BigDecimal[]", "java.math.BigInteger[]",
735:                    "java.util.Calendar[]", "javax.xml.namespace.QName[]" };
736:
737:            private static void addCommonArrayClasses(List<Class> list) {
738:                // Add common primitives arrays (necessary for RPC list type support)
739:                ClassLoader cl = getContextClassLoader();
740:
741:                for (int i = 0; i < commonArrayClasses.length; i++) {
742:                    String className = commonArrayClasses[i];
743:                    try {
744:                        // Load and add the class
745:                        Class cls = forName(ClassUtils
746:                                .getLoadableClassName(className), false, cl);
747:                        list.add(cls);
748:                        //Catch Throwable as ClassLoader can throw an NoClassDefFoundError that
749:                        //does not extend Exception
750:                    } catch (Throwable e) {
751:                        if (log.isDebugEnabled()) {
752:                            log
753:                                    .debug("Tried to load class "
754:                                            + className
755:                                            + " while constructing a JAXBContext.  This class will be skipped.  Processing Continues.");
756:                            log
757:                                    .debug("  The reason that class could not be loaded:"
758:                                            + e.toString());
759:                            log.debug(JavaUtils.stackToString(e));
760:                        }
761:                    }
762:                }
763:            }
764:
765:            /** @return ClassLoader */
766:            private static ClassLoader getContextClassLoader() {
767:                // NOTE: This method must remain private because it uses AccessController
768:                ClassLoader cl = null;
769:                try {
770:                    cl = (ClassLoader) AccessController
771:                            .doPrivileged(new PrivilegedExceptionAction() {
772:                                public Object run()
773:                                        throws ClassNotFoundException {
774:                                    return Thread.currentThread()
775:                                            .getContextClassLoader();
776:                                }
777:                            });
778:                } catch (PrivilegedActionException e) {
779:                    if (log.isDebugEnabled()) {
780:                        log.debug("Exception thrown from AccessController: "
781:                                + e);
782:                    }
783:                    throw ExceptionFactory.makeWebServiceException(e
784:                            .getException());
785:                }
786:
787:                return cl;
788:            }
789:
790:            /**
791:             * Return the class for this name
792:             *
793:             * @return Class
794:             */
795:            private static Class forName(final String className,
796:                    final boolean initialize, final ClassLoader classloader)
797:                    throws ClassNotFoundException {
798:                // NOTE: This method must remain private because it uses AccessController
799:                Class cl = null;
800:                try {
801:                    cl = (Class) AccessController
802:                            .doPrivileged(new PrivilegedExceptionAction() {
803:                                public Object run()
804:                                        throws ClassNotFoundException {
805:                                    // Class.forName does not support primitives
806:                                    Class cls = ClassUtils
807:                                            .getPrimitiveClass(className);
808:                                    if (cls == null) {
809:                                        cls = Class.forName(className,
810:                                                initialize, classloader);
811:                                    }
812:                                    return cls;
813:                                }
814:                            });
815:                } catch (PrivilegedActionException e) {
816:                    if (log.isDebugEnabled()) {
817:                        log.debug("Exception thrown from AccessController: "
818:                                + e);
819:                    }
820:                    throw (ClassNotFoundException) e.getException();
821:                }
822:
823:                return cl;
824:            }
825:
826:            /**
827:             * Create JAXBContext from context String and ClassLoader
828:             *
829:             * @param context
830:             * @param classloader
831:             * @return
832:             * @throws Exception
833:             */
834:            private static JAXBContext JAXBContext_newInstance(
835:                    final String context, final ClassLoader classloader)
836:                    throws Exception {
837:                // NOTE: This method must remain private because it uses AccessController
838:                JAXBContext jaxbContext = null;
839:                try {
840:                    if (log.isDebugEnabled()) {
841:                        if (context == null || context.length() == 0) {
842:                            log
843:                                    .debug("JAXBContext is constructed without a context String.");
844:                        } else {
845:                            log
846:                                    .debug("JAXBContext is constructed with a context of:"
847:                                            + context);
848:                        }
849:                    }
850:                    jaxbContext = (JAXBContext) AccessController
851:                            .doPrivileged(new PrivilegedExceptionAction() {
852:                                public Object run() throws JAXBException {
853:                                    return JAXBContext.newInstance(context,
854:                                            classloader);
855:                                }
856:                            });
857:                } catch (PrivilegedActionException e) {
858:                    if (log.isDebugEnabled()) {
859:                        log.debug("Exception thrown from AccessController: "
860:                                + e);
861:                    }
862:                    throw e.getException();
863:                }
864:
865:                return jaxbContext;
866:            }
867:
868:            /**
869:             * Create JAXBContext from Class[]
870:             *
871:             * @param classArray
872:             * @return
873:             * @throws Exception
874:             */
875:            private static JAXBContext JAXBContext_newInstance(
876:                    final Class[] classArray) throws JAXBException {
877:                // NOTE: This method must remain private because it uses AccessController
878:                JAXBContext jaxbContext = null;
879:                try {
880:                    if (log.isDebugEnabled()) {
881:                        if (classArray == null || classArray.length == 0) {
882:                            log
883:                                    .debug("JAXBContext is constructed with 0 input classes.");
884:                        } else {
885:                            log.debug("JAXBContext is constructed with "
886:                                    + classArray.length + " input classes.");
887:                        }
888:                    }
889:                    jaxbContext = (JAXBContext) AccessController
890:                            .doPrivileged(new PrivilegedExceptionAction() {
891:                                public Object run() throws JAXBException {
892:                                    return JAXBContext.newInstance(classArray);
893:                                }
894:                            });
895:                } catch (PrivilegedActionException e) {
896:                    if (log.isDebugEnabled()) {
897:                        log.debug("Exception thrown from AccessController: "
898:                                + e);
899:                        log.debug("  Exception is " + e.getException());
900:                    }
901:                    if (e.getException() instanceof  JAXBException) {
902:                        throw (JAXBException) e.getException();
903:                    } else if (e.getException() instanceof  RuntimeException) {
904:                        ExceptionFactory.makeWebServiceException(e
905:                                .getException());
906:                    }
907:                }
908:
909:                return jaxbContext;
910:            }
911:
912:            /**
913:             * Adjust the number of objects in the hash map if the limit is exceeded
914:             *
915:             * @param map
916:             */
917:            private static synchronized void adjustPoolSize(Map map) {
918:                if (map.size() > MAX_LOAD_FACTOR) {
919:                    // Remove every other Entry in the map.
920:                    Iterator it = map.entrySet().iterator();
921:                    boolean removeIt = false;
922:                    while (it.hasNext()) {
923:                        it.next();
924:                        if (removeIt) {
925:                            it.remove();
926:                        }
927:                        removeIt = !removeIt;
928:                    }
929:                }
930:            }
931:
932:            /** Holds the JAXBContext and the manner by which it was constructed */
933:            static class JAXBContextValue {
934:
935:                public JAXBContext jaxbContext;
936:                public CONSTRUCTION_TYPE constructionType;
937:
938:                public JAXBContextValue(JAXBContext jaxbContext,
939:                        CONSTRUCTION_TYPE constructionType) {
940:                    this.jaxbContext = jaxbContext;
941:                    this.constructionType = constructionType;
942:                }
943:            }
944:
945:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.