ohair@286: /* ohair@286: * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. ohair@286: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ohair@286: * ohair@286: * This code is free software; you can redistribute it and/or modify it ohair@286: * under the terms of the GNU General Public License version 2 only, as ohair@286: * published by the Free Software Foundation. Oracle designates this ohair@286: * particular file as subject to the "Classpath" exception as provided ohair@286: * by Oracle in the LICENSE file that accompanied this code. ohair@286: * ohair@286: * This code is distributed in the hope that it will be useful, but WITHOUT ohair@286: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ohair@286: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ohair@286: * version 2 for more details (a copy is included in the LICENSE file that ohair@286: * accompanied this code). ohair@286: * ohair@286: * You should have received a copy of the GNU General Public License version ohair@286: * 2 along with this work; if not, write to the Free Software Foundation, ohair@286: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ohair@286: * ohair@286: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ohair@286: * or visit www.oracle.com if you need additional information or have any ohair@286: * questions. ohair@286: */ ohair@286: ohair@286: package com.sun.xml.internal.ws.spi.db; ohair@286: ohair@286: import java.util.Iterator; ohair@286: import java.util.List; ohair@286: import java.util.logging.Level; ohair@286: import java.util.logging.Logger; ohair@286: ohair@286: import javax.xml.bind.JAXBContext; ohair@286: import javax.xml.bind.Marshaller; ohair@286: ohair@286: import com.sun.xml.internal.org.jvnet.ws.databinding.DatabindingModeFeature; ohair@286: ohair@286: import com.sun.xml.internal.ws.db.glassfish.JAXBRIContextFactory; ohair@286: import com.sun.xml.internal.ws.policy.privateutil.ServiceConfigurationError; ohair@286: import com.sun.xml.internal.ws.util.ServiceFinder; ohair@286: ohair@286: /** ohair@286: * BindingContextFactory ohair@286: * ohair@286: * @author shih-chang.chen@oracle.com ohair@286: */ ohair@286: abstract public class BindingContextFactory { ohair@286: public static final String DefaultDatabindingMode = DatabindingModeFeature.GLASSFISH_JAXB; ohair@286: public static final String JAXB_CONTEXT_FACTORY_PROPERTY = BindingContextFactory.class.getName(); ohair@286: public static final Logger LOGGER = Logger.getLogger(BindingContextFactory.class.getName()); ohair@286: ohair@286: // This iterator adds exception checking for proper logging. ohair@286: public static Iterator serviceIterator() { ohair@286: final ServiceFinder sf = ServiceFinder ohair@286: .find(BindingContextFactory.class); ohair@286: final Iterator ibcf = sf.iterator(); ohair@286: ohair@286: return new Iterator() { ohair@286: private BindingContextFactory bcf; ohair@286: ohair@286: public boolean hasNext() { ohair@286: while (true) { ohair@286: try { ohair@286: if (ibcf.hasNext()) { ohair@286: bcf = ibcf.next(); ohair@286: return true; ohair@286: } else ohair@286: return false; ohair@286: } catch (ServiceConfigurationError e) { ohair@286: LOGGER.warning("skipping factory: ServiceConfigurationError: " ohair@286: + e.getMessage()); ohair@286: } catch (NoClassDefFoundError ncdfe) { ohair@286: LOGGER.fine("skipping factory: NoClassDefFoundError: " ohair@286: + ncdfe.getMessage()); ohair@286: } ohair@286: } ohair@286: } ohair@286: ohair@286: public BindingContextFactory next() { ohair@286: if (LOGGER.isLoggable(Level.FINER)) ohair@286: LOGGER.finer("SPI found provider: " + ohair@286: bcf.getClass().getName()); ohair@286: return bcf; ohair@286: } ohair@286: ohair@286: public void remove() { ohair@286: throw new UnsupportedOperationException(); ohair@286: } ohair@286: }; ohair@286: } ohair@286: ohair@286: static private List factories() { ohair@286: List factories = new java.util.ArrayList(); ohair@286: Iterator ibcf = serviceIterator(); ohair@286: while (ibcf.hasNext()) ohair@286: factories.add(ibcf.next()); ohair@286: ohair@286: // There should always be at least one factory available. ohair@286: if (factories.isEmpty()) { ohair@286: if (LOGGER.isLoggable(Level.FINER)) ohair@286: LOGGER.log(Level.FINER, "No SPI providers for BindingContextFactory found, adding: " ohair@286: + JAXBRIContextFactory.class.getName()); ohair@286: factories.add(new JAXBRIContextFactory()); ohair@286: } ohair@286: return factories; ohair@286: } ohair@286: ohair@286: abstract protected BindingContext newContext(JAXBContext context); ohair@286: ohair@286: abstract protected BindingContext newContext(BindingInfo bi); ohair@286: ohair@286: /** ohair@286: * Check to see if the BindingContextFactory is for the databinding mode/flavor. The ohair@286: * String parameter can be the package name of the JAXBContext implementation as well. ohair@286: * @param databinding mode/flavor or the package name of the JAXBContext implementation. ohair@286: * @return ohair@286: */ ohair@286: abstract protected boolean isFor(String str); ohair@286: ohair@286: /** ohair@286: * @deprecated - Does jaxws need this? ohair@286: */ ohair@286: abstract protected BindingContext getContext(Marshaller m); ohair@286: ohair@286: static private BindingContextFactory getFactory(String mode) { ohair@286: for (BindingContextFactory f: factories()) { ohair@286: if (f.isFor(mode)) ohair@286: return f; ohair@286: } ohair@286: return null; ohair@286: } ohair@286: ohair@286: static public BindingContext create(JAXBContext context) throws DatabindingException { ohair@286: return getJAXBFactory(context).newContext(context); ohair@286: } ohair@286: ohair@286: static public BindingContext create(BindingInfo bi) { ohair@286: // Any mode configured in AbstractSEIModelImpl trumps all. ohair@286: // System property comes next, then SPI-located. ohair@286: String mode = bi.getDatabindingMode(); ohair@286: if (mode != null) { ohair@286: if (LOGGER.isLoggable(Level.FINE)) ohair@286: LOGGER.log(Level.FINE, "Using SEI-configured databindng mode: " ohair@286: + mode); ohair@286: } else if ((mode = System.getProperty("BindingContextFactory")) != null) { ohair@286: // The following is left for backward compatibility and should ohair@286: // eventually be removed. ohair@286: bi.setDatabindingMode(mode); ohair@286: if (LOGGER.isLoggable(Level.FINE)) ohair@286: LOGGER.log(Level.FINE, "Using databindng: " + mode ohair@286: + " based on 'BindingContextFactory' System property"); ohair@286: } else if ((mode = System.getProperty(JAXB_CONTEXT_FACTORY_PROPERTY)) != null) { ohair@286: bi.setDatabindingMode(mode); ohair@286: if (LOGGER.isLoggable(Level.FINE)) ohair@286: LOGGER.log(Level.FINE, "Using databindng: " + mode ohair@286: + " based on '" + JAXB_CONTEXT_FACTORY_PROPERTY ohair@286: + "' System property"); ohair@286: } else { ohair@286: // Find a default provider. Note we always ensure the list ohair@286: // is always non-empty. ohair@286: for (BindingContextFactory factory : factories()) { ohair@286: if (LOGGER.isLoggable(Level.FINE)) ohair@286: LOGGER.log(Level.FINE, ohair@286: "Using SPI-determined databindng mode: " ohair@286: + factory.getClass().getName()); ohair@286: // Special case: no name lookup used. ohair@286: return factory.newContext(bi); ohair@286: } ohair@286: ohair@286: // Should never get here as the list is non-empty. ohair@286: LOGGER.log(Level.SEVERE, "No Binding Context Factories found."); ohair@286: throw new DatabindingException("No Binding Context Factories found."); ohair@286: } ohair@286: BindingContextFactory f = getFactory(mode); ohair@286: if (f != null) ohair@286: return f.newContext(bi); ohair@286: LOGGER.severe("Unknown Databinding mode: " + mode); ohair@286: throw new DatabindingException("Unknown Databinding mode: " + mode); ohair@286: } ohair@286: ohair@286: static public boolean isContextSupported(Object o) { ohair@286: if (o == null) return false; ohair@286: String pkgName = o.getClass().getPackage().getName(); ohair@286: for (BindingContextFactory f: factories()) if (f.isFor(pkgName)) return true; ohair@286: return false; ohair@286: } ohair@286: ohair@286: static BindingContextFactory getJAXBFactory(Object o) { ohair@286: String pkgName = o.getClass().getPackage().getName(); ohair@286: BindingContextFactory f = getFactory(pkgName); ohair@286: if (f != null) return f; ohair@286: throw new DatabindingException("Unknown JAXBContext implementation: " + o.getClass()); ohair@286: ohair@286: } ohair@286: ohair@286: /** ohair@286: * @deprecated - Does jaxws need this? ohair@286: */ ohair@286: static public BindingContext getBindingContext(Marshaller m) { ohair@286: return getJAXBFactory(m).getContext(m); ohair@286: } ohair@286: ohair@286: /** ohair@286: * Creates a new {@link BindingContext}. ohair@286: * ohair@286: *

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