--- old/src/java.xml.ws/share/classes/com/sun/xml/internal/ws/spi/db/BindingContextFactory.java 2015-10-21 14:10:40.000000000 +0200 +++ new/src/java.xml.ws/share/classes/com/sun/xml/internal/ws/spi/db/BindingContextFactory.java 2015-10-21 14:10:40.000000000 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,6 +25,7 @@ package com.sun.xml.internal.ws.spi.db; +import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.logging.Level; @@ -156,17 +157,9 @@ + " based on '" + JAXB_CONTEXT_FACTORY_PROPERTY + "' System property"); } else { - // Find a default provider. Note we always ensure the list - // is always non-empty. - for (BindingContextFactory factory : factories()) { - if (LOGGER.isLoggable(Level.FINE)) - LOGGER.log(Level.FINE, - "Using SPI-determined databindng mode: " - + factory.getClass().getName()); - // Special case: no name lookup used. - return factory.newContext(bi); - } - + // Find a default provider. Note we always ensure the list is always non-empty. + BindingContext factory = getBindingContextFromSpi(factories(), bi); + if (factory != null) return factory; // Should never get here as the list is non-empty. LOGGER.log(Level.SEVERE, "No Binding Context Factories found."); throw new DatabindingException("No Binding Context Factories found."); @@ -178,7 +171,63 @@ throw new DatabindingException("Unknown Databinding mode: " + mode); } - static public boolean isContextSupported(Object o) { + /** + * Creates JAXB bindingContext with one of the provided factories. + * To filter appropriate factory {@link BindingContextFactory#isFor(String)} method is used. + * Currently known 2 appropriate factories: JAXB RI and MOXY. + * In case no suitable factory is found we are trying to create context with any given factory. + * + * @param factories given collection of factories. + * @param bindingInfo will be used to create bindingContext. + * @return Created context or null. Null will be returned if we were not able to create context with any given factory. + */ + private static BindingContext getBindingContextFromSpi(List factories, BindingInfo bindingInfo) { + List fallback = new ArrayList(); + BindingContext result; + for (BindingContextFactory factory : factories) { + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, "Found SPI-determined databindng mode: " + factory.getClass().getName()); + } + if (factory.isFor("org.eclipse.persistence.jaxb") || factory.isFor("com.sun.xml.internal.bind.v2.runtime")) { // filter (JAXB RI || MOXy) implementation + result = factory.newContext(bindingInfo); + if (result != null) { + return result; + } + } else { + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, "Skipped -> not JAXB."); + } + fallback.add(factory); + } + } + for (BindingContextFactory factory : fallback) { + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, "Fallback. Creating from: " + factory.getClass().getName()); + } + result = getContextOrNullIfError(factory, bindingInfo); + if (result != null) { + return result; + } + } + return null; + } + + /** + * Factory creates new context bases on provided bindingInfo. + * @param factory given factory. + * @param bindingInfo to be used to create context. + * @return Created context or null. Null will be returned if an error happened during the creation process. + */ + private static BindingContext getContextOrNullIfError(BindingContextFactory factory, BindingInfo bindingInfo) { + try { + return factory.newContext(bindingInfo); + } catch (Exception e) { + LOGGER.log(Level.WARNING, e.getMessage(), e); + return null; + } + } + + static public boolean isContextSupported(Object o) { if (o == null) return false; String pkgName = o.getClass().getPackage().getName(); for (BindingContextFactory f: factories()) if (f.isFor(pkgName)) return true; @@ -199,50 +248,4 @@ static public BindingContext getBindingContext(Marshaller m) { return getJAXBFactory(m).getContext(m); } - - /** - * Creates a new {@link BindingContext}. - * - *

- * {@link JAXBContext#newInstance(Class[]) JAXBContext.newInstance()} methods may - * return other JAXB providers that are not compatible with the JAX-RPC RI. - * This method guarantees that the JAX-WS RI will finds the JAXB RI. - * - * @param classes - * Classes to be bound. See {@link JAXBContext#newInstance(Class[])} for the meaning. - * @param typeRefs - * See {@link #TYPE_REFERENCES} for the meaning of this parameter. - * Can be null. - * @param subclassReplacements - * See {@link #SUBCLASS_REPLACEMENTS} for the meaning of this parameter. - * Can be null. - * @param defaultNamespaceRemap - * See {@link #DEFAULT_NAMESPACE_REMAP} for the meaning of this parameter. - * Can be null (and should be null for ordinary use of JAXB.) - * @param c14nSupport - * See {@link #CANONICALIZATION_SUPPORT} for the meaning of this parameter. - * @param ar - * See {@link #ANNOTATION_READER} for the meaning of this parameter. - * Can be null. - * @since JAXB 2.1 EA2 - */ -// public static BindingContext newInstance(@NotNull Class[] classes, -// @Nullable Collection typeRefs, -// @Nullable Map subclassReplacements, -// @Nullable String defaultNamespaceRemap, boolean c14nSupport, -// @Nullable RuntimeAnnotationReader ar) throws JAXBException { -// return ContextFactory.createContext(classes, typeRefs, subclassReplacements, -// defaultNamespaceRemap, c14nSupport, ar, false, false, false); -// } -// -// /** -// * @deprecated -// * Compatibility with older versions. -// */ -// public static BindingContext newInstance(@NotNull Class[] classes, -// @Nullable Collection typeRefs, -// @Nullable String defaultNamespaceRemap, boolean c14nSupport ) throws JAXBException { -// return newInstance(classes,typeRefs, Collections.emptyMap(), -// defaultNamespaceRemap,c14nSupport,null); -// } }