< prev index next >

src/java.xml.bind/share/classes/javax/xml/bind/ContextFinder.java

Print this page

        

*** 66,75 **** --- 66,78 ---- * <p> * For this reason, we have to hard-code the class name into the API. */ private static final String PLATFORM_DEFAULT_FACTORY_CLASS = "com.sun.xml.internal.bind.v2.ContextFactory"; + // previous value of JAXBContext.JAXB_CONTEXT_FACTORY, using also this to ensure backwards compatibility + private static final String JAXB_CONTEXT_FACTORY_DEPRECATED = "javax.xml.bind.context.factory"; + private static final Logger logger; static { logger = Logger.getLogger("javax.xml.bind"); try {
*** 90,99 **** --- 93,110 ---- // just to be extra safe. in particular System.getProperty may throw // SecurityException. } } + private static ServiceLoaderUtil.ExceptionHandler<JAXBException> EXCEPTION_HANDLER = + new ServiceLoaderUtil.ExceptionHandler<JAXBException>() { + @Override + public JAXBException createException(Throwable throwable, String message) { + return new JAXBException(message, throwable); + } + }; + /** * If the {@link InvocationTargetException} wraps an exception that shouldn't be wrapped, * throw the wrapped exception. */ private static void handleInvocationTargetException(InvocationTargetException x) throws JAXBException {
*** 157,167 **** // some other type of exception - just wrap it throw new JAXBException(Messages.format(Messages.COULD_NOT_INSTANTIATE, className, x), x); } } ! static JAXBContext newInstance(String contextPath, Class spFactory, ClassLoader classLoader, Map properties) throws JAXBException { try { /* * javax.xml.bind.context.factory points to a class which has a * static method called 'createContext' that --- 168,181 ---- // some other type of exception - just wrap it throw new JAXBException(Messages.format(Messages.COULD_NOT_INSTANTIATE, className, x), x); } } ! static JAXBContext newInstance(String contextPath, ! Class spFactory, ! ClassLoader classLoader, ! Map properties) throws JAXBException { try { /* * javax.xml.bind.context.factory points to a class which has a * static method called 'createContext' that
*** 237,257 **** static JAXBContext newInstance(Class[] classes, Map properties, Class spFactory) throws JAXBException { try { Method m = spFactory.getMethod("createContext", Class[].class, Map.class); Object context = m.invoke(null, classes, properties); if (!(context instanceof JAXBContext)) { // the cast would fail, so generate an exception with a nice message throw handleClassCastException(context.getClass(), JAXBContext.class); } return (JAXBContext) context; ! } catch (NoSuchMethodException e) { ! throw new JAXBException(e); ! } catch (IllegalAccessException e) { throw new JAXBException(e); } catch (InvocationTargetException e) { handleInvocationTargetException(e); Throwable x = e; if (e.getTargetException() != null) --- 251,272 ---- static JAXBContext newInstance(Class[] classes, Map properties, Class spFactory) throws JAXBException { try { + Method m = spFactory.getMethod("createContext", Class[].class, Map.class); Object context = m.invoke(null, classes, properties); if (!(context instanceof JAXBContext)) { // the cast would fail, so generate an exception with a nice message throw handleClassCastException(context.getClass(), JAXBContext.class); } return (JAXBContext) context; ! ! } catch (NoSuchMethodException | IllegalAccessException e) { throw new JAXBException(e); + } catch (InvocationTargetException e) { handleInvocationTargetException(e); Throwable x = e; if (e.getTargetException() != null)
*** 259,271 **** throw new JAXBException(x); } } ! static JAXBContext find(String factoryId, String contextPath, ClassLoader classLoader, Map properties) throws JAXBException { ! ! // TODO: do we want/need another layer of searching in $java.home/lib/jaxb.properties like JAXP? StringTokenizer packages = new StringTokenizer(contextPath, ":"); if (!packages.hasMoreTokens()) { // no context is specified throw new JAXBException(Messages.format(Messages.NO_PACKAGE_IN_CONTEXTPATH)); --- 274,287 ---- throw new JAXBException(x); } } ! static JAXBContext find(String factoryId, ! String contextPath, ! ClassLoader classLoader, ! Map properties) throws JAXBException { StringTokenizer packages = new StringTokenizer(contextPath, ":"); if (!packages.hasMoreTokens()) { // no context is specified throw new JAXBException(Messages.format(Messages.NO_PACKAGE_IN_CONTEXTPATH));
*** 273,382 **** // search for jaxb.properties in the class loader of each class first logger.fine("Searching jaxb.properties"); while (packages.hasMoreTokens()) { // com.acme.foo - > com/acme/foo/jaxb.properties ! String className = classNameFromPackageProperties(factoryId, classLoader, packages.nextToken(":").replace('.', '/')); ! if (className != null) return newInstance(contextPath, className, classLoader, properties); } String factoryName = classNameFromSystemProperties(); if (factoryName != null) return newInstance(contextPath, factoryName, classLoader, properties); ! Class ctxFactory = (Class) ServiceLoaderUtil.lookupUsingOSGiServiceLoader("javax.xml.bind.JAXBContext", logger); ! if (ctxFactory != null) { ! return newInstance(contextPath, ctxFactory, classLoader, properties); ! } ! // TODO: SPEC change required! This is supposed to be! ! // JAXBContext obj = firstByServiceLoader(JAXBContext.class, EXCEPTION_HANDLER); ! // if (obj != null) return obj; ! // TODO: Deprecated - SPEC change required! factoryName = firstByServiceLoaderDeprecated(JAXBContext.class, classLoader); if (factoryName != null) return newInstance(contextPath, factoryName, classLoader, properties); // else no provider found logger.fine("Trying to create the platform default provider"); return newInstance(contextPath, PLATFORM_DEFAULT_FACTORY_CLASS, classLoader, properties); } ! static JAXBContext find(Class[] classes, Map properties) throws JAXBException { // search for jaxb.properties in the class loader of each class first logger.fine("Searching jaxb.properties"); for (final Class c : classes) { // this classloader is used only to load jaxb.properties, so doing this should be safe. ! if (c.getPackage() == null) continue; // this is possible for primitives, arrays, and classes that are loaded by poorly implemented ClassLoaders // TODO: do we want to optimize away searching the same package? org.Foo, org.Bar, com.Baz // classes from the same package might come from different class loades, so it might be a bad idea // TODO: it's easier to look things up from the class // c.getResourceAsStream("jaxb.properties"); ! String className = classNameFromPackageProperties(JAXBContext.JAXB_CONTEXT_FACTORY, getClassClassLoader(c), c.getPackage().getName().replace('.', '/')); ! if (className != null) return newInstance(classes, properties, className); } ! String factoryName = classNameFromSystemProperties(); ! if (factoryName != null) return newInstance(classes, properties, factoryName); ! Class ctxFactoryClass = (Class) ServiceLoaderUtil.lookupUsingOSGiServiceLoader("javax.xml.bind.JAXBContext", logger); ! if (ctxFactoryClass != null) { ! return newInstance(classes, properties, ctxFactoryClass); ! } ! // TODO: to be removed - deprecated!!! Requires SPEC change!!! String className = firstByServiceLoaderDeprecated(JAXBContext.class, getContextClassLoader()); if (className != null) return newInstance(classes, properties, className); ! // // TODO: supposed to be: ! // obj = firstByServiceLoader(JAXBContext.class, EXCEPTION_HANDLER); ! // if (obj != null) return obj; // else no provider found logger.fine("Trying to create the platform default provider"); return newInstance(classes, properties, PLATFORM_DEFAULT_FACTORY_CLASS); } ! private static String classNameFromPackageProperties(String factoryId, ClassLoader classLoader, String packageName) throws JAXBException { String resourceName = packageName + "/jaxb.properties"; logger.log(Level.FINE, "Trying to locate {0}", resourceName); Properties props = loadJAXBProperties(classLoader, resourceName); if (props != null) { if (props.containsKey(factoryId)) { return props.getProperty(factoryId); - } else { - throw new JAXBException(Messages.format(Messages.MISSING_PROPERTY, packageName, factoryId)); } } return null; } private static String classNameFromSystemProperties() throws JAXBException { ! logger.log(Level.FINE, "Checking system property {0}", JAXBContext.JAXB_CONTEXT_FACTORY); ! // search for a system property second (javax.xml.bind.JAXBContext) ! String factoryClassName = AccessController.doPrivileged(new GetPropertyAction(JAXBContext.JAXB_CONTEXT_FACTORY)); if (factoryClassName != null) { - logger.log(Level.FINE, " found {0}", factoryClassName); return factoryClassName; ! } else { // leave this here to assure compatibility ! logger.fine(" not found"); ! logger.log(Level.FINE, "Checking system property {0}", JAXBContext.class.getName()); ! factoryClassName = AccessController.doPrivileged(new GetPropertyAction(JAXBContext.class.getName())); if (factoryClassName != null) { - logger.log(Level.FINE, " found {0}", factoryClassName); return factoryClassName; - } else { - logger.fine(" not found"); } } return null; } ! private static Properties loadJAXBProperties(ClassLoader classLoader, String propFileName) throws JAXBException { Properties props = null; try { URL url; if (classLoader == null) --- 289,447 ---- // search for jaxb.properties in the class loader of each class first logger.fine("Searching jaxb.properties"); while (packages.hasMoreTokens()) { // com.acme.foo - > com/acme/foo/jaxb.properties ! String factoryClassName = ! classNameFromPackageProperties( ! classLoader, ! packages.nextToken(":").replace('.', '/'), ! factoryId, ! JAXB_CONTEXT_FACTORY_DEPRECATED); ! ! if (factoryClassName != null) { ! return newInstance(contextPath, factoryClassName, classLoader, properties); ! } } String factoryName = classNameFromSystemProperties(); if (factoryName != null) return newInstance(contextPath, factoryName, classLoader, properties); ! JAXBContextFactory obj = ServiceLoaderUtil.firstByServiceLoader( ! JAXBContextFactory.class, logger, EXCEPTION_HANDLER); ! if (obj != null) return obj.createContext(contextPath, classLoader, properties); ! // to ensure backwards compatibility factoryName = firstByServiceLoaderDeprecated(JAXBContext.class, classLoader); if (factoryName != null) return newInstance(contextPath, factoryName, classLoader, properties); + Class ctxFactory = (Class) ServiceLoaderUtil.lookupUsingOSGiServiceLoader( + "javax.xml.bind.JAXBContext", logger); + + if (ctxFactory != null) { + return newInstance(contextPath, ctxFactory, classLoader, properties); + } + // else no provider found logger.fine("Trying to create the platform default provider"); return newInstance(contextPath, PLATFORM_DEFAULT_FACTORY_CLASS, classLoader, properties); } ! static JAXBContext find(Class<?>[] classes, Map<String, ?> properties) throws JAXBException { // search for jaxb.properties in the class loader of each class first logger.fine("Searching jaxb.properties"); for (final Class c : classes) { // this classloader is used only to load jaxb.properties, so doing this should be safe. ! // this is possible for primitives, arrays, and classes that are ! // loaded by poorly implemented ClassLoaders ! if (c.getPackage() == null) continue; // TODO: do we want to optimize away searching the same package? org.Foo, org.Bar, com.Baz // classes from the same package might come from different class loades, so it might be a bad idea // TODO: it's easier to look things up from the class // c.getResourceAsStream("jaxb.properties"); ! String factoryClassName = ! classNameFromPackageProperties( ! getClassClassLoader(c), ! c.getPackage().getName().replace('.', '/'), ! JAXBContext.JAXB_CONTEXT_FACTORY, JAXB_CONTEXT_FACTORY_DEPRECATED); ! ! if (factoryClassName != null) return newInstance(classes, properties, factoryClassName); } ! String factoryClassName = classNameFromSystemProperties(); ! if (factoryClassName != null) return newInstance(classes, properties, factoryClassName); ! JAXBContextFactory factory = ! ServiceLoaderUtil.firstByServiceLoader(JAXBContextFactory.class, logger, EXCEPTION_HANDLER); ! ! if (factory != null) return factory.createContext(classes, properties); ! // to ensure backwards compatibility String className = firstByServiceLoaderDeprecated(JAXBContext.class, getContextClassLoader()); if (className != null) return newInstance(classes, properties, className); ! logger.fine("Trying to create the platform default provider"); ! Class ctxFactoryClass = ! (Class) ServiceLoaderUtil.lookupUsingOSGiServiceLoader("javax.xml.bind.JAXBContext", logger); ! ! if (ctxFactoryClass != null) { ! return newInstance(classes, properties, ctxFactoryClass); ! } // else no provider found logger.fine("Trying to create the platform default provider"); return newInstance(classes, properties, PLATFORM_DEFAULT_FACTORY_CLASS); } ! /** ! * first factoryId should be the preffered one, ! * more of those can be provided to support backwards compatibility ! */ ! private static String classNameFromPackageProperties(ClassLoader classLoader, ! String packageName, ! String ... factoryIds) throws JAXBException { ! String resourceName = packageName + "/jaxb.properties"; logger.log(Level.FINE, "Trying to locate {0}", resourceName); Properties props = loadJAXBProperties(classLoader, resourceName); if (props != null) { + for(String factoryId : factoryIds) { if (props.containsKey(factoryId)) { return props.getProperty(factoryId); } } + throw new JAXBException(Messages.format(Messages.MISSING_PROPERTY, packageName, factoryIds[0])); + } return null; } private static String classNameFromSystemProperties() throws JAXBException { ! ! String factoryClassName = getSystemProperty(JAXBContext.JAXB_CONTEXT_FACTORY); if (factoryClassName != null) { return factoryClassName; ! } ! // leave this here to assure compatibility ! factoryClassName = getDeprecatedSystemProperty(JAXB_CONTEXT_FACTORY_DEPRECATED); if (factoryClassName != null) { return factoryClassName; } + // leave this here to assure compatibility + factoryClassName = getDeprecatedSystemProperty(JAXBContext.class.getName()); + if (factoryClassName != null) { + return factoryClassName; } return null; } ! private static String getDeprecatedSystemProperty(String property) { ! String value = getSystemProperty(property); ! if (value != null) { ! logger.log(Level.WARNING, "Using non-standard property: {0}. Property {1} should be used instead.", ! new Object[] {property, JAXBContext.JAXB_CONTEXT_FACTORY}); ! } ! return value; ! } ! ! private static String getSystemProperty(String property) { ! logger.log(Level.FINE, "Checking system property {0}", property); ! String value = AccessController.doPrivileged(new GetPropertyAction(property)); ! if (value != null) { ! logger.log(Level.FINE, " found {0}", value); ! } else { ! logger.log(Level.FINE, " not found"); ! } ! return value; ! } ! ! private static Properties loadJAXBProperties(ClassLoader classLoader, ! String propFileName) throws JAXBException { Properties props = null; try { URL url; if (classLoader == null)
*** 478,498 **** } }); } } - // TODO: to be removed - SPEC change required // ServiceLoaderUtil.firstByServiceLoaderDeprecated should be used instead. @Deprecated ! static String firstByServiceLoaderDeprecated(Class spiClass, ClassLoader classLoader) throws JAXBException { final String jaxbContextFQCN = spiClass.getName(); logger.fine("Searching META-INF/services"); // search META-INF services next BufferedReader r = null; ! final String resource = new StringBuilder().append("META-INF/services/").append(jaxbContextFQCN).toString(); try { final InputStream resourceStream = (classLoader == null) ? ClassLoader.getSystemResourceAsStream(resource) : classLoader.getResourceAsStream(resource); --- 543,564 ---- } }); } } // ServiceLoaderUtil.firstByServiceLoaderDeprecated should be used instead. @Deprecated ! static String firstByServiceLoaderDeprecated(Class spiClass, ! ClassLoader classLoader) throws JAXBException { ! final String jaxbContextFQCN = spiClass.getName(); logger.fine("Searching META-INF/services"); // search META-INF services next BufferedReader r = null; ! final String resource = "META-INF/services/" + jaxbContextFQCN; try { final InputStream resourceStream = (classLoader == null) ? ClassLoader.getSystemResourceAsStream(resource) : classLoader.getResourceAsStream(resource);
*** 508,520 **** return factoryClassName; } else { logger.log(Level.FINE, "Unable to load:{0}", resource); return null; } - } catch (UnsupportedEncodingException e) { - // should never happen - throw new JAXBException(e); } catch (IOException e) { throw new JAXBException(e); } finally { try { if (r != null) { --- 574,583 ----
< prev index next >