Fri, 24 Oct 2014 15:02:28 +0200
8054367: More references for endpoints
Summary: fix also reviewed by Iaroslav.Savytskyi@oracle.com, Alexander.Fomin@oracle.com
Reviewed-by: mullan, skoivu
1 /*
2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
26 package com.sun.xml.internal.ws.spi.db;
28 import java.util.Iterator;
29 import java.util.List;
30 import java.util.logging.Level;
31 import java.util.logging.Logger;
33 import javax.xml.bind.JAXBContext;
34 import javax.xml.bind.Marshaller;
37 import com.oracle.webservices.internal.api.databinding.DatabindingModeFeature;
38 import com.sun.xml.internal.ws.db.glassfish.JAXBRIContextFactory;
39 import com.sun.xml.internal.ws.util.ServiceConfigurationError;
40 import com.sun.xml.internal.ws.util.ServiceFinder;
42 /**
43 * BindingContextFactory
44 *
45 * @author shih-chang.chen@oracle.com
46 */
47 abstract public class BindingContextFactory {
48 public static final String DefaultDatabindingMode = DatabindingModeFeature.GLASSFISH_JAXB;
49 public static final String JAXB_CONTEXT_FACTORY_PROPERTY = BindingContextFactory.class.getName();
50 public static final Logger LOGGER = Logger.getLogger(BindingContextFactory.class.getName());
52 // This iterator adds exception checking for proper logging.
53 public static Iterator<BindingContextFactory> serviceIterator() {
54 final ServiceFinder<BindingContextFactory> sf = ServiceFinder
55 .find(BindingContextFactory.class);
56 final Iterator<BindingContextFactory> ibcf = sf.iterator();
58 return new Iterator<BindingContextFactory>() {
59 private BindingContextFactory bcf;
61 public boolean hasNext() {
62 while (true) {
63 try {
64 if (ibcf.hasNext()) {
65 bcf = ibcf.next();
66 return true;
67 } else
68 return false;
69 } catch (ServiceConfigurationError e) {
70 LOGGER.warning("skipping factory: ServiceConfigurationError: "
71 + e.getMessage());
72 } catch (NoClassDefFoundError ncdfe) {
73 LOGGER.fine("skipping factory: NoClassDefFoundError: "
74 + ncdfe.getMessage());
75 }
76 }
77 }
79 public BindingContextFactory next() {
80 if (LOGGER.isLoggable(Level.FINER))
81 LOGGER.finer("SPI found provider: " +
82 bcf.getClass().getName());
83 return bcf;
84 }
86 public void remove() {
87 throw new UnsupportedOperationException();
88 }
89 };
90 }
92 static private List<BindingContextFactory> factories() {
93 List<BindingContextFactory> factories = new java.util.ArrayList<BindingContextFactory>();
94 Iterator<BindingContextFactory> ibcf = serviceIterator();
95 while (ibcf.hasNext())
96 factories.add(ibcf.next());
98 // There should always be at least one factory available.
99 if (factories.isEmpty()) {
100 if (LOGGER.isLoggable(Level.FINER))
101 LOGGER.log(Level.FINER, "No SPI providers for BindingContextFactory found, adding: "
102 + JAXBRIContextFactory.class.getName());
103 factories.add(new JAXBRIContextFactory());
104 }
105 return factories;
106 }
108 abstract protected BindingContext newContext(JAXBContext context);
110 abstract protected BindingContext newContext(BindingInfo bi);
112 /**
113 * Check to see if the BindingContextFactory is for the databinding mode/flavor. The
114 * String parameter can be the package name of the JAXBContext implementation as well.
115 * @param databinding mode/flavor or the package name of the JAXBContext implementation.
116 * @return
117 */
118 abstract protected boolean isFor(String databinding);
120 /**
121 * @deprecated - Does jaxws need this?
122 */
123 abstract protected BindingContext getContext(Marshaller m);
125 static private BindingContextFactory getFactory(String mode) {
126 for (BindingContextFactory f: factories()) {
127 if (f.isFor(mode))
128 return f;
129 }
130 return null;
131 }
133 static public BindingContext create(JAXBContext context) throws DatabindingException {
134 return getJAXBFactory(context).newContext(context);
135 }
137 static public BindingContext create(BindingInfo bi) {
138 // Any mode configured in AbstractSEIModelImpl trumps all.
139 // System property comes next, then SPI-located.
140 String mode = bi.getDatabindingMode();
141 if (mode != null) {
142 if (LOGGER.isLoggable(Level.FINE))
143 LOGGER.log(Level.FINE, "Using SEI-configured databindng mode: "
144 + mode);
145 } else if ((mode = System.getProperty("BindingContextFactory")) != null) {
146 // The following is left for backward compatibility and should
147 // eventually be removed.
148 bi.setDatabindingMode(mode);
149 if (LOGGER.isLoggable(Level.FINE))
150 LOGGER.log(Level.FINE, "Using databindng: " + mode
151 + " based on 'BindingContextFactory' System property");
152 } else if ((mode = System.getProperty(JAXB_CONTEXT_FACTORY_PROPERTY)) != null) {
153 bi.setDatabindingMode(mode);
154 if (LOGGER.isLoggable(Level.FINE))
155 LOGGER.log(Level.FINE, "Using databindng: " + mode
156 + " based on '" + JAXB_CONTEXT_FACTORY_PROPERTY
157 + "' System property");
158 } else {
159 // Find a default provider. Note we always ensure the list
160 // is always non-empty.
161 for (BindingContextFactory factory : factories()) {
162 if (LOGGER.isLoggable(Level.FINE))
163 LOGGER.log(Level.FINE,
164 "Using SPI-determined databindng mode: "
165 + factory.getClass().getName());
166 // Special case: no name lookup used.
167 return factory.newContext(bi);
168 }
170 // Should never get here as the list is non-empty.
171 LOGGER.log(Level.SEVERE, "No Binding Context Factories found.");
172 throw new DatabindingException("No Binding Context Factories found.");
173 }
174 BindingContextFactory f = getFactory(mode);
175 if (f != null)
176 return f.newContext(bi);
177 LOGGER.severe("Unknown Databinding mode: " + mode);
178 throw new DatabindingException("Unknown Databinding mode: " + mode);
179 }
181 static public boolean isContextSupported(Object o) {
182 if (o == null) return false;
183 String pkgName = o.getClass().getPackage().getName();
184 for (BindingContextFactory f: factories()) if (f.isFor(pkgName)) return true;
185 return false;
186 }
188 static BindingContextFactory getJAXBFactory(Object o) {
189 String pkgName = o.getClass().getPackage().getName();
190 BindingContextFactory f = getFactory(pkgName);
191 if (f != null) return f;
192 throw new DatabindingException("Unknown JAXBContext implementation: " + o.getClass());
194 }
196 /**
197 * @deprecated - Does jaxws need this?
198 */
199 static public BindingContext getBindingContext(Marshaller m) {
200 return getJAXBFactory(m).getContext(m);
201 }
203 /**
204 * Creates a new {@link BindingContext}.
205 *
206 * <p>
207 * {@link JAXBContext#newInstance(Class[]) JAXBContext.newInstance()} methods may
208 * return other JAXB providers that are not compatible with the JAX-RPC RI.
209 * This method guarantees that the JAX-WS RI will finds the JAXB RI.
210 *
211 * @param classes
212 * Classes to be bound. See {@link JAXBContext#newInstance(Class[])} for the meaning.
213 * @param typeRefs
214 * See {@link #TYPE_REFERENCES} for the meaning of this parameter.
215 * Can be null.
216 * @param subclassReplacements
217 * See {@link #SUBCLASS_REPLACEMENTS} for the meaning of this parameter.
218 * Can be null.
219 * @param defaultNamespaceRemap
220 * See {@link #DEFAULT_NAMESPACE_REMAP} for the meaning of this parameter.
221 * Can be null (and should be null for ordinary use of JAXB.)
222 * @param c14nSupport
223 * See {@link #CANONICALIZATION_SUPPORT} for the meaning of this parameter.
224 * @param ar
225 * See {@link #ANNOTATION_READER} for the meaning of this parameter.
226 * Can be null.
227 * @since JAXB 2.1 EA2
228 */
229 // public static BindingContext newInstance(@NotNull Class[] classes,
230 // @Nullable Collection<TypeInfo> typeRefs,
231 // @Nullable Map<Class,Class> subclassReplacements,
232 // @Nullable String defaultNamespaceRemap, boolean c14nSupport,
233 // @Nullable RuntimeAnnotationReader ar) throws JAXBException {
234 // return ContextFactory.createContext(classes, typeRefs, subclassReplacements,
235 // defaultNamespaceRemap, c14nSupport, ar, false, false, false);
236 // }
237 //
238 // /**
239 // * @deprecated
240 // * Compatibility with older versions.
241 // */
242 // public static BindingContext newInstance(@NotNull Class[] classes,
243 // @Nullable Collection<TypeInfo> typeRefs,
244 // @Nullable String defaultNamespaceRemap, boolean c14nSupport ) throws JAXBException {
245 // return newInstance(classes,typeRefs, Collections.<Class,Class>emptyMap(),
246 // defaultNamespaceRemap,c14nSupport,null);
247 // }
248 }