1 /** 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 package org.apache.openejb.server.webservices.saaj; 18 19 import org.apache.openejb.util.Logger; 20 import org.apache.openejb.util.LogCategory; 21 22 import javax.xml.soap.SOAPException; 23 import java.util.HashMap; 24 import java.util.Map; 25 26 class SaajFactoryFinder { 27 private static final Logger logger = Logger.getInstance(LogCategory.OPENEJB_WS, SaajFactoryFinder.class); 28 private static final String SAAJ_PROVIDER_PROPERTY = "org.apache.openejb.server.webservices.saaj.provider"; 29 30 private static SaajUniverse.Type DEFAULT_SAAJ_UNIVERSE = null; 31 32 private static final Map<String, Map<String, String>> SAAJ_FACTORIES = new HashMap<String, Map<String, String>>(); 33 static { 34 SAAJ_FACTORIES.put(SaajUniverse.Type.AXIS1.toString(), createSAAJInfo( 35 "org.apache.axis.soap.MessageFactoryImpl", 36 "org.apache.axis.soap.SOAPFactoryImpl", 37 "org.apache.axis.soap.SOAPConnectionFactoryImpl", 38 "org.apache.axis.soap.SAAJMetaFactoryImpl")); 39 SAAJ_FACTORIES.put(SaajUniverse.Type.AXIS2.toString(), createSAAJInfo( 40 "org.apache.axis2.saaj.MessageFactoryImpl", 41 "org.apache.axis2.saaj.SOAPFactoryImpl", 42 "org.apache.axis2.saaj.SOAPConnectionFactoryImpl", 43 "org.apache.axis2.saaj.SAAJMetaFactoryImpl")); 44 SAAJ_FACTORIES.put(SaajUniverse.Type.SUN.toString(), createSAAJInfo( 45 "com.sun.xml.messaging.saaj.soap.ver1_1.SOAPMessageFactory1_1Impl", 46 "com.sun.xml.messaging.saaj.soap.ver1_1.SOAPFactory1_1Impl", 47 "com.sun.xml.messaging.saaj.client.p2p.HttpSOAPConnectionFactory", 48 "com.sun.xml.messaging.saaj.soap.SAAJMetaFactoryImpl")); 49 50 initDefaultSAAJProvider(); 51 } 52 53 private static void initDefaultSAAJProvider() { 54 String provider = System.getProperty(SAAJ_PROVIDER_PROPERTY); 55 if (provider != null) { 56 if (provider.equalsIgnoreCase("axis2")) { 57 DEFAULT_SAAJ_UNIVERSE = SaajUniverse.Type.AXIS2; 58 } else if (provider.equalsIgnoreCase("sun")) { 59 DEFAULT_SAAJ_UNIVERSE = SaajUniverse.Type.SUN; 60 } else { 61 throw new RuntimeException("Invalid SAAJ universe specified: " + provider); 62 } 63 64 logger.info("Default SAAJ universe: " + DEFAULT_SAAJ_UNIVERSE); 65 } else { 66 logger.info("Default SAAJ universe not set"); 67 } 68 } 69 70 private static Map<String, String> createSAAJInfo(String messageFactory, String soapFactory, String soapConnectionFactory, String metaFactory) { 71 Map<String, String> map = new HashMap<String, String>(); 72 map.put("javax.xml.soap.MessageFactory", messageFactory); 73 map.put("javax.xml.soap.SOAPFactory", soapFactory); 74 map.put("javax.xml.soap.SOAPConnectionFactory", soapConnectionFactory); 75 map.put("javax.xml.soap.MetaFactory", metaFactory); 76 return map; 77 } 78 79 static Object find(String factoryPropertyName) throws SOAPException { 80 String factoryClassName = getFactoryClass(factoryPropertyName); 81 if (factoryClassName == null) { 82 throw new SOAPException("Provider for " + factoryPropertyName + " cannot be found", null); 83 } else { 84 return newInstance(factoryClassName); 85 } 86 } 87 88 private static String getFactoryClass(String factoryName) { 89 SaajUniverse.Type universe = SaajUniverse.getCurrentUniverse(); 90 if (universe == null || universe == SaajUniverse.Type.DEFAULT) { 91 if (DEFAULT_SAAJ_UNIVERSE == null) { 92 // Default SAAJ universe not set. 93 // Prefer Axis2 SAAJ if it is in class loader, otherwise use Sun's 94 if (isAxis2InClassLoader()) { 95 universe = SaajUniverse.Type.AXIS2; 96 } else { 97 universe = SaajUniverse.Type.SUN; 98 } 99 } else { 100 // Use default SAAJ universe 101 universe = DEFAULT_SAAJ_UNIVERSE; 102 } 103 } 104 105 return SAAJ_FACTORIES.get(universe.toString()).get(factoryName); 106 } 107 108 private static boolean isAxis2InClassLoader() { 109 try { 110 loadClass("org.apache.axis2.saaj.MessageFactoryImpl"); 111 return true; 112 } catch (ClassNotFoundException e) { 113 return false; 114 } 115 } 116 117 private static Class loadClass(String className) throws ClassNotFoundException { 118 ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); 119 if (classLoader == null) { 120 return Class.forName(className); 121 } else { 122 return classLoader.loadClass(className); 123 } 124 } 125 126 private static Object newInstance(String factoryClassName) throws SOAPException { 127 try { 128 Class factory = null; 129 try { 130 factory = loadClass(factoryClassName); 131 } catch (ClassNotFoundException cnfe) { 132 factory = SaajFactoryFinder.class.getClassLoader().loadClass(factoryClassName); 133 } 134 return factory.newInstance(); 135 } catch (ClassNotFoundException e) { 136 throw new SOAPException("Provider " + factoryClassName + " not found", e); 137 } catch (Exception e) { 138 throw new SOAPException("Provider " + factoryClassName + " could not be instantiated: " + e.getMessage(), e); 139 } 140 } 141 }