You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by an...@apache.org on 2015/11/23 15:08:42 UTC
[5/9] tomee git commit: EOL
http://git-wip-us.apache.org/repos/asf/tomee/blob/5dd70c83/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/CxfRsHttpListener.java
----------------------------------------------------------------------
diff --git a/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/CxfRsHttpListener.java b/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/CxfRsHttpListener.java
index bbdbbd5..0bdd6d9 100644
--- a/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/CxfRsHttpListener.java
+++ b/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/CxfRsHttpListener.java
@@ -1,1097 +1,1097 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.openejb.server.cxf.rs;
-
-import org.apache.cxf.BusException;
-import org.apache.cxf.common.logging.LogUtils;
-import org.apache.cxf.endpoint.Endpoint;
-import org.apache.cxf.endpoint.EndpointException;
-import org.apache.cxf.endpoint.ManagedEndpoint;
-import org.apache.cxf.endpoint.Server;
-import org.apache.cxf.endpoint.ServerImpl;
-import org.apache.cxf.helpers.IOUtils;
-import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
-import org.apache.cxf.jaxrs.JAXRSServiceImpl;
-import org.apache.cxf.jaxrs.ext.RequestHandler;
-import org.apache.cxf.jaxrs.ext.ResourceComparator;
-import org.apache.cxf.jaxrs.lifecycle.ResourceProvider;
-import org.apache.cxf.jaxrs.lifecycle.SingletonResourceProvider;
-import org.apache.cxf.jaxrs.model.ClassResourceInfo;
-import org.apache.cxf.jaxrs.model.MethodDispatcher;
-import org.apache.cxf.jaxrs.model.OperationResourceInfo;
-import org.apache.cxf.jaxrs.model.ProviderInfo;
-import org.apache.cxf.jaxrs.model.wadl.WadlGenerator;
-import org.apache.cxf.jaxrs.provider.JAXBElementProvider;
-import org.apache.cxf.jaxrs.provider.json.JSONProvider;
-import org.apache.cxf.service.invoker.Invoker;
-import org.apache.cxf.transport.http.AbstractHTTPDestination;
-import org.apache.cxf.transport.http.HTTPTransportFactory;
-import org.apache.cxf.transport.servlet.BaseUrlHelper;
-import org.apache.openejb.AppContext;
-import org.apache.openejb.BeanContext;
-import org.apache.openejb.Injection;
-import org.apache.openejb.api.internal.Internal;
-import org.apache.openejb.api.jmx.Description;
-import org.apache.openejb.api.jmx.MBean;
-import org.apache.openejb.api.jmx.ManagedAttribute;
-import org.apache.openejb.api.jmx.ManagedOperation;
-import org.apache.openejb.assembler.classic.ServiceInfo;
-import org.apache.openejb.assembler.classic.util.ServiceConfiguration;
-import org.apache.openejb.assembler.classic.util.ServiceInfos;
-import org.apache.openejb.core.WebContext;
-import org.apache.openejb.dyni.DynamicSubclass;
-import org.apache.openejb.loader.IO;
-import org.apache.openejb.loader.SystemInstance;
-import org.apache.openejb.monitoring.LocalMBeanServer;
-import org.apache.openejb.monitoring.ObjectNameBuilder;
-import org.apache.openejb.rest.ThreadLocalContextManager;
-import org.apache.openejb.server.cxf.rs.event.ExtensionProviderRegistration;
-import org.apache.openejb.server.cxf.rs.event.ServerCreated;
-import org.apache.openejb.server.cxf.rs.event.ServerDestroyed;
-import org.apache.openejb.server.cxf.transport.util.CxfUtil;
-import org.apache.openejb.server.httpd.HttpRequest;
-import org.apache.openejb.server.httpd.HttpRequestImpl;
-import org.apache.openejb.server.httpd.HttpResponse;
-import org.apache.openejb.server.httpd.ServletRequestAdapter;
-import org.apache.openejb.server.rest.EJBRestServiceInfo;
-import org.apache.openejb.server.rest.InternalApplication;
-import org.apache.openejb.server.rest.RsHttpListener;
-import org.apache.openejb.util.AppFinder;
-import org.apache.openejb.util.LogCategory;
-import org.apache.openejb.util.Logger;
-import org.apache.openejb.util.proxy.ProxyEJB;
-import org.apache.webbeans.config.WebBeansContext;
-import org.apache.webbeans.container.BeanManagerImpl;
-import org.apache.webbeans.context.creational.CreationalContextImpl;
-
-import javax.enterprise.context.spi.CreationalContext;
-import javax.enterprise.inject.spi.Bean;
-import javax.management.ObjectName;
-import javax.management.openmbean.TabularData;
-import javax.naming.Context;
-import javax.servlet.ServletException;
-import javax.servlet.ServletOutputStream;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.ws.rs.core.Application;
-import javax.xml.bind.Marshaller;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Constructor;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.logging.Level;
-import java.util.regex.Pattern;
-
-import static org.apache.openejb.loader.JarLocation.jarLocation;
-
-public class CxfRsHttpListener implements RsHttpListener {
-
- private static final Logger LOGGER = Logger.getInstance(LogCategory.OPENEJB_RS, CxfRsHttpListener.class);
-
- private static final java.util.logging.Logger SERVER_IMPL_LOGGER = LogUtils.getL7dLogger(ServerImpl.class);
-
- public static final String CXF_JAXRS_PREFIX = "cxf.jaxrs.";
- public static final String PROVIDERS_KEY = CXF_JAXRS_PREFIX + "providers";
- public static final String STATIC_RESOURCE_KEY = CXF_JAXRS_PREFIX + "static-resources-list";
- public static final String STATIC_SUB_RESOURCE_RESOLUTION_KEY = "staticSubresourceResolution";
- public static final String RESOURCE_COMPARATOR_KEY = CXF_JAXRS_PREFIX + "resourceComparator";
-
- public static final boolean TRY_STATIC_RESOURCES = "true".equalsIgnoreCase(SystemInstance.get().getProperty("openejb.jaxrs.static-first", "true"));
- private static final String GLOBAL_PROVIDERS = SystemInstance.get().getProperty(PROVIDERS_KEY);
-
- private static final Map<String, String> STATIC_CONTENT_TYPES;
- private static final String[] DEFAULT_WELCOME_FILES = new String[]{ "/index.html", "/index.htm" };
-
- private final HTTPTransportFactory transportFactory;
- private final String wildcard;
- private AbstractHTTPDestination destination;
- private Server server;
- private String context = "";
- private String servlet = "";
- private final Collection<Pattern> staticResourcesList = new CopyOnWriteArrayList<Pattern>();
- private final List<ObjectName> jmxNames = new ArrayList<ObjectName>();
- private final Collection<CreationalContext<?>> toRelease = new LinkedHashSet<CreationalContext<?>>();
- private final Collection<CdiSingletonResourceProvider> singletons = new LinkedHashSet<CdiSingletonResourceProvider>();
-
- private static final char[] URL_SEP = new char[] { '?', '#', ';' };
-
- static {
- STATIC_CONTENT_TYPES = new HashMap<String, String>();
- STATIC_CONTENT_TYPES.put("html", "text/html");
- STATIC_CONTENT_TYPES.put("xhtml", "text/html");
- STATIC_CONTENT_TYPES.put("txt", "text/plain");
- STATIC_CONTENT_TYPES.put("css", "text/css");
- STATIC_CONTENT_TYPES.put("jpg", "image/jpg");
- STATIC_CONTENT_TYPES.put("png", "image/png");
- STATIC_CONTENT_TYPES.put("ico", "image/ico");
- STATIC_CONTENT_TYPES.put("pdf", "application/pdf");
- STATIC_CONTENT_TYPES.put("xsd", "application/xml");
-
- for (final ProviderInfo<RequestHandler> rh : org.apache.cxf.jaxrs.provider.ProviderFactory.getSharedInstance().getRequestHandlers()) {
- final RequestHandler provider = rh.getProvider();
- if (WadlGenerator.class.isInstance(provider)) {
- final WadlGenerator wadlGenerator = WadlGenerator.class.cast(provider);
- final String ignoreRequests = SystemInstance.get().getProperty("openejb.cxf-rs.wadl-generator.ignoreRequests");
- final String ignoreMessageWriters = SystemInstance.get().getProperty("openejb.cxf-rs.wadl-generator.ignoreMessageWriters", "false");
-
- if (ignoreRequests != null) {
- wadlGenerator.setIgnoreRequests(Boolean.parseBoolean(ignoreRequests));
- }
- // CXF-5319: bug in CXF? it prevents to get the wadl as json otherwise
- if (ignoreMessageWriters != null) {
- wadlGenerator.setIgnoreMessageWriters(Boolean.parseBoolean(ignoreMessageWriters));
- }
- }
- }
- }
-
- private String pattern;
-
- public CxfRsHttpListener(final HTTPTransportFactory httpTransportFactory, final String star) {
- transportFactory = httpTransportFactory;
- wildcard = star;
- }
-
- public void setUrlPattern(final String pattern) {
- this.pattern = pattern;
- }
-
- @Override
- public void onMessage(final HttpRequest httpRequest, final HttpResponse httpResponse) throws Exception {
- // fix the address (to manage multiple connectors)
- if (HttpRequestImpl.class.isInstance(httpRequest)) {
- final HttpRequestImpl requestImpl = HttpRequestImpl.class.cast(httpRequest);
- requestImpl.initPathFromContext(context);
- requestImpl.initServletPath(servlet);
- }
-
- boolean matchedStatic = false;
- if (TRY_STATIC_RESOURCES || (matchedStatic = matchPath(httpRequest))) {
- final String pathInfo = httpRequest.getPathInfo();
- if (serveStaticContent(httpRequest, httpResponse, pathInfo)) {
- if (matchedStatic) { // we should have gotten the resource
- throw new ServletException("Static resource " + pathInfo + " is not available");
- }
- return; // ok that's a surely rest service
- }
- }
-
- doInvoke(httpRequest, httpResponse);
- }
-
- // normal endpoint without static resource handling
- public void doInvoke(final HttpRequest httpRequest, final HttpResponse httpResponse) throws IOException {
- String baseURL = BaseUrlHelper.getBaseURL(pattern != null ? new ServletRequestAdapter(httpRequest) {
- @Override // we have a filter so we need the computed servlet path to not break CXF
- public String getServletPath() {
- return pattern;
- }
- } : httpRequest);
- if (!baseURL.endsWith("/")) {
- baseURL += "/";
- }
- httpRequest.setAttribute("org.apache.cxf.transport.endpoint.address", baseURL);
-
- final ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
- Thread.currentThread().setContextClassLoader(CxfUtil.initBusLoader());
- try {
- destination.invoke(null, httpRequest.getServletContext(), httpRequest, httpResponse);
- } catch (final Throwable t) {
- throw new IOException("Failed to invoke AbstractHTTPDestination", t);
- } finally {
- CxfUtil.clearBusLoader(oldLoader);
- }
- }
-
- public boolean matchPath(final HttpServletRequest request) {
- if (staticResourcesList.isEmpty()) {
- return false;
- }
-
- String path = request.getPathInfo();
- if (path == null) {
- path = "/";
- }
- for (final Pattern pattern : staticResourcesList) {
- if (pattern.matcher(path).matches()) {
- return true;
- }
- }
- return false;
- }
-
- public InputStream findStaticContent(final HttpServletRequest request, final String[] welcomeFiles) throws ServletException {
- String pathInfo = request.getRequestURI().substring(request.getContextPath().length());
- for (final char c : URL_SEP) {
- final int indexOf = pathInfo.indexOf(c);
- if (indexOf > 0) {
- pathInfo = pathInfo.substring(0, indexOf);
- }
- }
- InputStream is = request.getServletContext().getResourceAsStream(pathInfo);
- if (is == null && ("/".equals(pathInfo) || pathInfo.isEmpty())) {
- for (final String n : welcomeFiles) {
- is = request.getServletContext().getResourceAsStream(n);
- if (is != null) {
- break;
- }
- }
- }
- return is;
- }
-
- public boolean serveStaticContent(final HttpServletRequest request,
- final HttpServletResponse response,
- final String pathInfo) throws ServletException {
- final InputStream is = findStaticContent(request, DEFAULT_WELCOME_FILES);
- if (is == null) {
- return false;
- }
- try {
- final int ind = pathInfo.lastIndexOf(".");
- if (ind != -1 && ind < pathInfo.length()) {
- final String type = STATIC_CONTENT_TYPES.get(pathInfo.substring(ind + 1));
- if (type != null) {
- response.setContentType(type);
- }
- }
-
- final ServletOutputStream os = response.getOutputStream();
- IOUtils.copy(is, os);
- os.flush();
- response.setStatus(HttpURLConnection.HTTP_OK);
- } catch (final IOException ex) {
- throw new ServletException("Static resource " + pathInfo + " can not be written to the output stream");
- }
- return true;
- }
-
- @Deprecated
- @Override
- public void deploySingleton(final String contextRoot, final String fullContext, final Object o, final Application appInstance,
- final Collection<Object> additionalProviders, final ServiceConfiguration configuration) {
- deploy(contextRoot, o.getClass(), fullContext, new SingletonResourceProvider(o),
- o, appInstance, null, additionalProviders, configuration, null);
- }
-
- @Deprecated
- @Override
- public void deployPojo(final ClassLoader loader,
- final String contextRoot,
- final String fullContext,
- final Class<?> loadedClazz,
- final Application app,
- final Collection<Injection> injections,
- final Context context,
- final WebBeansContext owbCtx,
- final Collection<Object> additionalProviders,
- final ServiceConfiguration configuration) {
- deploy(contextRoot, loadedClazz, fullContext, new OpenEJBPerRequestPojoResourceProvider(loader, loadedClazz, injections, context, owbCtx),
- null, app, null, additionalProviders, configuration, null);
- }
-
- @Deprecated
- @Override
- public void deployEJB(final String contextRoot,
- final String fullContext,
- final BeanContext beanContext,
- final Collection<Object> additionalProviders,
- final ServiceConfiguration configuration) {
- final Object proxy = ProxyEJB.subclassProxy(beanContext);
-
- deploy(contextRoot, beanContext.getBeanClass(), fullContext, new NoopResourceProvider(beanContext.getBeanClass(), proxy),
- proxy, null, new OpenEJBEJBInvoker(Collections.singleton(beanContext)), additionalProviders, configuration, beanContext.getWebBeansContext());
- }
-
- private void deploy(final String contextRoot, final Class<?> clazz, final String address, final ResourceProvider rp, final Object serviceBean,
- final Application app, final Invoker invoker, final Collection<Object> additionalProviders, final ServiceConfiguration configuration,
- final WebBeansContext webBeansContext) {
- final ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
- Thread.currentThread().setContextClassLoader(CxfUtil.initBusLoader());
- try {
- final JAXRSServerFactoryBean factory = newFactory(address, createServiceJmxName(clazz.getClassLoader()), createEndpointName(app));
- configureFactory(additionalProviders, configuration, factory, webBeansContext);
- factory.setResourceClasses(clazz);
- context = contextRoot;
- if (context == null) {
- context = "";
- }
- if (!context.startsWith("/")) {
- context = "/" + context;
- }
-
- if (rp != null) {
- factory.setResourceProvider(rp);
- }
- if (app != null) {
- factory.setApplication(app);
- }
- if (invoker != null) {
- factory.setInvoker(invoker);
- }
- if (serviceBean != null) {
- factory.setServiceBean(serviceBean);
- } else {
- factory.setServiceClass(clazz);
- }
-
- server = factory.create();
- destination = (AbstractHTTPDestination) server.getDestination();
- fireServerCreated(oldLoader);
- } finally {
- if (oldLoader != null) {
- CxfUtil.clearBusLoader(oldLoader);
- }
- }
- }
-
- private void fireServerCreated(final ClassLoader oldLoader) {
- final Object ctx = AppFinder.findAppContextOrWeb(oldLoader, new AppFinder.Transformer<Object>() {
- @Override
- public Object from(final AppContext appCtx) {
- return appCtx;
- }
-
- @Override
- public Object from(final WebContext webCtx) {
- return webCtx;
- }
- });
- final AppContext appCtx = AppContext.class.isInstance(ctx) ? AppContext.class.cast(ctx) : WebContext.class.cast(ctx).getAppContext();
- WebContext webContext = appCtx == ctx ? null : WebContext.class.cast(ctx);
- if (webContext == null && appCtx.getWebContexts().size() == 1 && appCtx.getWebContexts().get(0).getClassLoader() == oldLoader) {
- webContext = appCtx.getWebContexts().get(0);
- }
- SystemInstance.get().fireEvent(new ServerCreated(server, appCtx, webContext, this.context));
- }
-
- private List<Object> providers(final Collection<ServiceInfo> services, final Collection<Object> additionalProviders, final WebBeansContext ctx) {
- final List<Object> instances = new ArrayList<Object>();
- final BeanManagerImpl bm = ctx == null ? null : ctx.getBeanManagerImpl();
- for (final Object o : additionalProviders) {
- if (o instanceof Class<?>) {
- final Class<?> clazz = (Class<?>) o;
- final String name = clazz.getName();
- if (shouldSkipProvider(name)) {
- continue;
- }
-
- if (bm != null && bm.isInUse()) {
- try {
- final Set<Bean<?>> beans = bm.getBeans(clazz);
- if (beans != null && !beans.isEmpty()) {
- final Bean<?> bean = bm.resolve(beans);
- final CreationalContextImpl<?> creationalContext = bm.createCreationalContext(bean);
- instances.add(bm.getReference(bean, clazz, creationalContext));
- toRelease.add(creationalContext);
- continue;
- }
- } catch (final Throwable th) {
- LOGGER.info("Can't use CDI to create provider " + name);
- }
- }
-
- final Collection<Object> instance = ServiceInfos.resolve(services, new String[]{name}, ProviderFactory.INSTANCE);
- if (instance != null && !instance.isEmpty()) {
- instances.add(instance.iterator().next());
- } else {
- try {
- instances.add(newProvider(clazz));
- } catch (final Exception e) {
- LOGGER.error("can't instantiate " + name, e);
- }
- }
- } else {
- final String name = o.getClass().getName();
- if (shouldSkipProvider(name)) {
- continue;
- }
- instances.add(o);
- }
- }
-
- return instances;
- }
-
- private static boolean shouldSkipProvider(final String name) {
- return "false".equalsIgnoreCase(SystemInstance.get().getProperty(name + ".activated", "true"))
- || name.startsWith("org.apache.wink.common.internal.");
- }
-
- private static void addMandatoryProviders(final Collection<Object> instances) {
- instances.add(EJBAccessExceptionMapper.INSTANCE);
- }
-
- private Object newProvider(final Class<?> clazz) throws IllegalAccessException, InstantiationException {
- return clazz.newInstance();
- }
-
- @Override
- public void undeploy() {
- // unregister all MBeans
- for (final ObjectName objectName : jmxNames) {
- LocalMBeanServer.unregisterSilently(objectName);
- }
-
- for (final CreationalContext<?> cc : toRelease) {
- try {
- cc.release();
- } catch (final Exception e) {
- LOGGER.warning(e.getMessage(), e);
- }
- }
- for (final CdiSingletonResourceProvider provider : singletons) {
- try {
- provider.release();
- } catch (final Exception e) {
- LOGGER.warning(e.getMessage(), e);
- }
- }
-
- final ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
- Thread.currentThread().setContextClassLoader(CxfUtil.initBusLoader());
- try {
- server.destroy();
- SystemInstance.get().fireEvent(new ServerDestroyed(server));
- } catch (final RuntimeException ise) {
- LOGGER.warning("Can't stop correctly the endpoint " + server);
- if (LOGGER.isDebugEnabled()) {
- LOGGER.debug(ise.getMessage(), ise);
- }
- } finally {
- if (oldLoader != null) {
- CxfUtil.clearBusLoader(oldLoader);
- }
- }
- }
-
- @Override
- public void deployApplication(final Application application, final String prefix, final String webContext,
- final Collection<Object> additionalProviders,
- final Map<String, EJBRestServiceInfo> restEjbs, final ClassLoader classLoader,
- final Collection<Injection> injections, final Context context, final WebBeansContext owbCtx,
- final ServiceConfiguration serviceConfiguration) {
- final ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
- Thread.currentThread().setContextClassLoader(CxfUtil.initBusLoader());
- try {
- final JAXRSServerFactoryBean factory = newFactory(prefix, createServiceJmxName(classLoader), createEndpointName(application));
- configureFactory(additionalProviders, serviceConfiguration, factory, owbCtx);
- factory.setApplication(application);
-
- final List<Class<?>> classes = new ArrayList<Class<?>>();
-
- for (final Class<?> clazz : application.getClasses()) {
- if (!additionalProviders.contains(clazz) && !clazz.isInterface()) {
- classes.add(clazz);
-
- final EJBRestServiceInfo restServiceInfo = getEjbRestServiceInfo(restEjbs, clazz);
-
- if (restServiceInfo != null) {
- final Object proxy = ProxyEJB.subclassProxy(restServiceInfo.context);
- factory.setResourceProvider(clazz, new NoopResourceProvider(restServiceInfo.context.getBeanClass(), proxy));
- } else {
- factory.setResourceProvider(clazz, new OpenEJBPerRequestPojoResourceProvider(
- classLoader, clazz, injections, context, owbCtx));
- }
- }
- }
-
- for (final Object o : application.getSingletons()) {
- if (!additionalProviders.contains(o)) {
- final Class<?> clazz = realClass(o.getClass());
- classes.add(clazz);
-
- final EJBRestServiceInfo restServiceInfo = getEjbRestServiceInfo(restEjbs, clazz);
-
- if (restServiceInfo != null) {
- final Object proxy = ProxyEJB.subclassProxy(restServiceInfo.context);
- factory.setResourceProvider(clazz, new NoopResourceProvider(restServiceInfo.context.getBeanClass(), proxy));
- } else {
- if (owbCtx.getBeanManagerImpl().isInUse()) {
- final CdiSingletonResourceProvider provider = new CdiSingletonResourceProvider(classLoader, clazz, o, injections, context, owbCtx);
- singletons.add(provider);
- factory.setResourceProvider(clazz, provider);
- } else {
- factory.setResourceProvider(clazz, new SingletonResourceProvider(o));
- }
- }
- }
- }
-
- factory.setResourceClasses(classes);
- factory.setInvoker(new AutoJAXRSInvoker(restEjbs));
-
- this.context = webContext;
- if (!webContext.startsWith("/")) {
- this.context = "/" + webContext;
- } // /webcontext/servlet for event firing
-
- final Level level = SERVER_IMPL_LOGGER.getLevel();
- try {
- SERVER_IMPL_LOGGER.setLevel(Level.OFF);
- } catch (final UnsupportedOperationException e) {
- //ignore
- }
- try {
- server = factory.create();
- fireServerCreated(oldLoader);
- } finally {
- try {
- SERVER_IMPL_LOGGER.setLevel(level);
- } catch (final UnsupportedOperationException e) {
- //ignore
- }
- }
-
- final int servletIdx = 1 + this.context.substring(1).indexOf('/');
- if (servletIdx > 0) {
- this.servlet = this.context.substring(servletIdx);
- this.context = this.context.substring(0, servletIdx);
- }
- destination = (AbstractHTTPDestination) server.getDestination();
-
- final String base;
- if (prefix.endsWith("/")) {
- base = prefix.substring(0, prefix.length() - 1);
- } else if (prefix.endsWith(wildcard)) {
- base = prefix.substring(0, prefix.length() - wildcard.length());
- } else {
- base = prefix;
- }
-
- // stack info to log to get nice logs
- logEndpoints(application, prefix, restEjbs, factory, base);
- } finally {
- if (oldLoader != null) {
- CxfUtil.clearBusLoader(oldLoader);
- }
- }
- }
-
- private EJBRestServiceInfo getEjbRestServiceInfo(final Map<String, EJBRestServiceInfo> restEjbs, final Class<?> clazz) {
- String name = clazz.getName();
- EJBRestServiceInfo restServiceInfo = restEjbs.get(name);
-
- if (name.endsWith(DynamicSubclass.IMPL_SUFFIX)) {
- name = name.substring(0, name.length() - DynamicSubclass.IMPL_SUFFIX.length());
- restServiceInfo = restEjbs.get(name);
- if (restServiceInfo != null) { // AutoJAXRSInvoker relies on it
- restEjbs.put(clazz.getName(), restServiceInfo);
- }
- }
- return restServiceInfo;
- }
-
- private static Class<?> realClass(final Class<?> aClass) {
- Class<?> result = aClass;
- while (result.getName().contains("$$")) {
- result = result.getSuperclass();
- if (result == null) {
- return aClass;
- }
- }
- return result;
- }
-
- private static String createEndpointName(final Application application) {
- if (application == null) {
- return "jaxrs-application";
- }
- if (InternalApplication.class.isInstance(application)) {
- final Application original = InternalApplication.class.cast(application).getOriginal();
- if (original != null) {
- return original.getClass().getSimpleName();
- }
- return "jaxrs-application";
- }
- return application.getClass().getSimpleName();
- }
-
- private static String createServiceJmxName(final ClassLoader classLoader) {
- final AppContext app = AppFinder.findAppContextOrWeb(classLoader, AppFinder.AppContextTransformer.INSTANCE);
- return app == null ? "application" : app.getId();
- }
-
- private void logEndpoints(final Application application, final String prefix,
- final Map<String, EJBRestServiceInfo> restEjbs,
- final JAXRSServerFactoryBean factory, final String base) {
- final List<Logs.LogResourceEndpointInfo> resourcesToLog = new ArrayList<Logs.LogResourceEndpointInfo>();
- int classSize = 0;
- int addressSize = 0;
-
- final JAXRSServiceImpl service = (JAXRSServiceImpl) factory.getServiceFactory().getService();
- final List<ClassResourceInfo> resources = service.getClassResourceInfos();
- for (final ClassResourceInfo info : resources) {
- if (info.getResourceClass() == null) { // possible?
- continue;
- }
-
- final String address = Logs.singleSlash(base, info.getURITemplate().getValue());
-
- final String clazz = info.getResourceClass().getName();
- final String type;
- if (restEjbs.containsKey(clazz)) {
- type = "EJB";
- } else {
- type = "Pojo";
- }
-
- classSize = Math.max(classSize, clazz.length());
- addressSize = Math.max(addressSize, address.length());
-
- int methodSize = 7;
- int methodStrSize = 0;
-
- final List<Logs.LogOperationEndpointInfo> toLog = new ArrayList<Logs.LogOperationEndpointInfo>();
-
- final MethodDispatcher md = info.getMethodDispatcher();
- for (final OperationResourceInfo ori : md.getOperationResourceInfos()) {
- final String httpMethod = ori.getHttpMethod();
- final String currentAddress = Logs.singleSlash(address, ori.getURITemplate().getValue());
- final String methodToStr = Logs.toSimpleString(ori.getMethodToInvoke());
- toLog.add(new Logs.LogOperationEndpointInfo(httpMethod, currentAddress, methodToStr));
-
- if (httpMethod != null) {
- methodSize = Math.max(methodSize, httpMethod.length());
- }
- addressSize = Math.max(addressSize, currentAddress.length());
- methodStrSize = Math.max(methodStrSize, methodToStr.length());
- }
-
- Collections.sort(toLog);
-
- resourcesToLog.add(new Logs.LogResourceEndpointInfo(type, address, clazz, toLog, methodSize, methodStrSize));
- }
-
- // effective logging
-
- LOGGER.info("REST Application: " + Logs.forceLength(prefix, addressSize, true) + " -> " + application.getClass().getName());
-
- Collections.sort(resourcesToLog);
-
- for (final Logs.LogResourceEndpointInfo resource : resourcesToLog) {
-
- // Init and register MBeans
- final ObjectNameBuilder jmxName = new ObjectNameBuilder("openejb.management")
- .set("j2eeType", "JAX-RS")
- .set("J2EEServer", "openejb")
- .set("J2EEApplication", base)
- .set("EndpointType", resource.type)
- .set("name", resource.classname);
-
- final ObjectName jmxObjectName = jmxName.build();
- LocalMBeanServer.registerDynamicWrapperSilently(
- new RestServiceMBean(resource),
- jmxObjectName);
-
- jmxNames.add(jmxObjectName);
-
- LOGGER.info(" Service URI: "
- + Logs.forceLength(resource.address, addressSize, true) + " -> "
- + Logs.forceLength(resource.type, 4, false) + " "
- + Logs.forceLength(resource.classname, classSize, true));
-
- for (final Logs.LogOperationEndpointInfo log : resource.operations) {
- LOGGER.info(" "
- + Logs.forceLength(log.http, resource.methodSize, false) + " "
- + Logs.forceLength(log.address, addressSize, true) + " -> "
- + Logs.forceLength(log.method, resource.methodStrSize, true));
- }
-
- resource.operations.clear();
- }
- resourcesToLog.clear();
- }
-
- private JAXRSServerFactoryBean newFactory(final String prefix, final String service, final String endpoint) {
- final JAXRSServerFactoryBean factory = new JAXRSServerFactoryBean() {
- @Override
- protected Endpoint createEndpoint() throws BusException, EndpointException {
- final Endpoint created = super.createEndpoint();
- created.put(ManagedEndpoint.SERVICE_NAME, service);
- created.put(ManagedEndpoint.ENDPOINT_NAME, endpoint);
- return created;
- }
- };
- factory.setDestinationFactory(transportFactory);
- factory.setBus(CxfUtil.getBus());
- factory.setAddress(prefix);
- return factory;
- }
-
- private void configureFactory(final Collection<Object> givenAdditionalProviders,
- final ServiceConfiguration serviceConfiguration,
- final JAXRSServerFactoryBean factory,
- final WebBeansContext ctx) {
- CxfUtil.configureEndpoint(factory, serviceConfiguration, CXF_JAXRS_PREFIX);
-
- final Collection<ServiceInfo> services = serviceConfiguration.getAvailableServices();
-
- final String staticSubresourceResolution = serviceConfiguration.getProperties().getProperty(CXF_JAXRS_PREFIX + STATIC_SUB_RESOURCE_RESOLUTION_KEY);
- if (staticSubresourceResolution != null) {
- factory.setStaticSubresourceResolution("true".equalsIgnoreCase(staticSubresourceResolution));
- }
-
- // resource comparator
- final String resourceComparator = serviceConfiguration.getProperties().getProperty(RESOURCE_COMPARATOR_KEY);
- if (resourceComparator != null) {
- try {
- ResourceComparator instance = (ResourceComparator) ServiceInfos.resolve(services, resourceComparator);
- if (instance == null) {
- instance = (ResourceComparator) Thread.currentThread().getContextClassLoader()
- .loadClass(resourceComparator).newInstance();
- }
- factory.setResourceComparator(instance);
- } catch (final Exception e) {
- LOGGER.error("Can't create the resource comparator " + resourceComparator, e);
- }
- }
-
- // static resources
- final String staticResources = serviceConfiguration.getProperties().getProperty(STATIC_RESOURCE_KEY);
- if (staticResources != null) {
- final String[] resources = staticResources.split(",");
- for (final String r : resources) {
- final String trimmed = r.trim();
- if (!trimmed.isEmpty()) {
- staticResourcesList.add(Pattern.compile(trimmed));
- }
- }
- }
-
- // providers
- Set<String> providersConfig = null;
-
- {
- final String provider = serviceConfiguration.getProperties().getProperty(PROVIDERS_KEY);
- if (provider != null) { // already ordered and high priority since they were configured manually
- providersConfig = new HashSet<String>();
- for (final String p : Arrays.asList(provider.split(","))) {
- providersConfig.add(p.trim());
- }
- }
-
- {
- if (GLOBAL_PROVIDERS != null) { // same idea, Note: this doesn't affect much cases which are not embedded so don't spend time on it
- if (providersConfig == null) {
- providersConfig = new HashSet<String>();
- }
- providersConfig.addAll(Arrays.asList(GLOBAL_PROVIDERS.split(",")));
- }
- }
- }
-
- // another property to configure the scanning of providers but this one is consistent with current cxf config
- // the other one is more generic but need another file
- final String key = CXF_JAXRS_PREFIX + "skip-provider-scanning";
- final boolean ignoreAutoProviders = "true".equalsIgnoreCase(SystemInstance.get().getProperty(key, serviceConfiguration.getProperties().getProperty(key, "false")));
- final Collection<Object> additionalProviders = ignoreAutoProviders ? Collections.emptyList() : givenAdditionalProviders;
- List<Object> providers = null;
- if (providersConfig != null) {
- providers = ServiceInfos.resolve(services, providersConfig.toArray(new String[providersConfig.size()]), ProviderFactory.INSTANCE);
- if (providers != null && additionalProviders != null && !additionalProviders.isEmpty()) {
- providers.addAll(sortProviders(serviceConfiguration, ctx, additionalProviders));
- }
- }
- if (providers == null) {
- providers = new ArrayList<Object>(4);
- if (additionalProviders != null && !additionalProviders.isEmpty()) {
- providers.addAll(sortProviders(serviceConfiguration, ctx, additionalProviders));
- } else {
- providers.addAll(defaultProviders());
- }
- }
-
- if (!ignoreAutoProviders) {
- addMandatoryProviders(providers);
- }
-
- SystemInstance.get().fireEvent(new ExtensionProviderRegistration(
- AppFinder.findAppContextOrWeb(Thread.currentThread().getContextClassLoader(), AppFinder.AppContextTransformer.INSTANCE), providers));
-
- LOGGER.info("Using providers:");
- for (final Object provider : providers) {
- LOGGER.info(" " + provider);
- }
- factory.setProviders(providers);
- }
-
- private List<Object> sortProviders(final ServiceConfiguration serviceConfiguration, final WebBeansContext ctx,
- final Collection<Object> additionalProviders) {
- final Collection<ServiceInfo> services = serviceConfiguration.getAvailableServices();
- final List<Object> loadedProviders = providers(services, additionalProviders, ctx);
- if ("true".equalsIgnoreCase(SystemInstance.get().getProperty("openejb.cxf.rs.skip-provider-sorting", "false"))) {
- return loadedProviders;
- }
-
- final String comparatorClass = serviceConfiguration.getProperties().getProperty(CXF_JAXRS_PREFIX + "provider-comparator");
-
- Comparator<Object> comparator = null;
- if (comparatorClass == null) {
- comparator = DefaultProviderComparator.INSTANCE;
- } else {
- final BeanManagerImpl bm = ctx.getBeanManagerImpl();
- if (bm != null && bm.isInUse()) {
- try {
- final Class<?> clazz = Thread.currentThread().getContextClassLoader().loadClass(comparatorClass);
- final Set<Bean<?>> beans = bm.getBeans(clazz);
- if (beans != null && !beans.isEmpty()) {
- final Bean<?> bean = bm.resolve(beans);
- final CreationalContextImpl<?> creationalContext = bm.createCreationalContext(bean);
- comparator = Comparator.class.cast(bm.getReference(bean, clazz, creationalContext));
- toRelease.add(creationalContext);
- }
- } catch (final Throwable th) {
- LOGGER.debug("Can't use CDI to load comparator " + comparatorClass);
- }
- }
-
- if (comparator == null) {
- comparator = Comparator.class.cast(ServiceInfos.resolve(services, comparatorClass));
- }
- if (comparator == null) {
- try {
- comparator = Comparator.class.cast(Thread.currentThread().getContextClassLoader().loadClass(comparatorClass).newInstance());
- } catch (final Exception e) {
- throw new IllegalArgumentException(e);
- }
- }
- }
- Collections.sort(loadedProviders, comparator);
- return loadedProviders;
- }
-
- private static List<Object> defaultProviders() {
- final JAXBElementProvider jaxb = new JAXBElementProvider();
- final Map<String, Object> jaxbProperties = new HashMap<String, Object>();
- jaxbProperties.put(Marshaller.JAXB_FRAGMENT, true);
- jaxb.setMarshallerProperties(jaxbProperties);
-
- final List<Object> providers = new ArrayList<Object>(4);
- providers.add(jaxb);
- providers.add(new JSONProvider());
- return providers;
- }
-
- // we use Object cause an app with a custom comparator can desire to compare instances
- private static final class DefaultProviderComparator implements Comparator<Object> {
- private static final DefaultProviderComparator INSTANCE = new DefaultProviderComparator();
- private static final ClassLoader SYSTEM_LOADER = ClassLoader.getSystemClassLoader();
-
- @Override
- public int compare(final Object o1, final Object o2) {
- if (o1 == o2 || (o1 != null && o1.equals(o2))) {
- return 0;
- }
- if (o1 == null) {
- return -1;
- }
- if (o2 == null) {
- return 1;
- }
-
- final Class<?> c1 = o1.getClass();
- final Class<?> c2 = o2.getClass();
-
- final ClassLoader classLoader1 = c1.getClassLoader();
- final ClassLoader classLoader2 = c2.getClassLoader();
-
- final boolean loadersNotNull = classLoader1 != null && classLoader2 != null;
-
- if (classLoader1 != classLoader2
- && loadersNotNull
- && !classLoader1.equals(classLoader2) && !classLoader2.equals(classLoader1)) {
- if (isParent(classLoader1, classLoader2)) {
- return 1;
- }
- if (isParent(classLoader2, classLoader1)) {
- return -1;
- }
- } else {
- final File l1 = jarLocation(c1);
- final File l2 = jarLocation(c2);
- if (l1 == null) {
- return 1;
- }
- if (l2 == null) {
- return -1;
- }
-
- try { // WEB-INF/classes will be before WEB-INF/lib automatically
- return l1.getCanonicalPath().compareTo(l2.getCanonicalPath());
- } catch (final IOException e) {
- // no-op: sort by class name
- }
- }
-
- return c1.getName().compareTo(c2.getName());
- }
-
- private static boolean isParent(final ClassLoader l1, final ClassLoader l2) {
- ClassLoader current = l2;
- while (current != null && current != SYSTEM_LOADER) {
- if (current.equals(l1) || l1.equals(current)) {
- return true;
- }
- current = current.getParent();
- }
- return false;
- }
- }
-
- private static class ProviderFactory implements ServiceInfos.Factory {
-
- private static final ServiceInfos.Factory INSTANCE = new ProviderFactory();
-
- @Override
- public Object newInstance(final Class<?> clazz) throws Exception {
- boolean found = false;
- Object instance = null;
- for (final Constructor<?> c : clazz.getConstructors()) {
- int contextAnnotations = 0;
- for (final Annotation[] annotations : c.getParameterAnnotations()) {
- for (final Annotation a : annotations) {
- if (javax.ws.rs.core.Context.class.equals(a.annotationType())) {
- contextAnnotations++;
- break;
- }
- }
- }
- if (contextAnnotations == c.getParameterTypes().length) {
- if (found) {
- LOGGER.warning("Found multiple matching constructor for " + clazz.getName());
- return instance;
- }
-
- final Object[] params = new Object[c.getParameterTypes().length];
- for (int i = 0; i < params.length; i++) {
- params[i] = ThreadLocalContextManager.findThreadLocal(c.getParameterTypes()[i]);
- // params[i] can be null if not a known type
- }
- instance = c.newInstance(params);
- found = true;
- }
- }
- if (instance != null) {
- return instance;
- }
- return clazz.newInstance();
- }
- }
-
- @SuppressWarnings("UnusedDeclaration")
- @MBean
- @Internal
- @Description("JAX-RS service information")
- public class RestServiceMBean {
-
- private final String type;
- private final String address;
- private final String classname;
- private final TabularData operations;
-
- public RestServiceMBean(final Logs.LogResourceEndpointInfo jmxName) {
- this.type = jmxName.type;
- this.address = jmxName.address;
- this.classname = jmxName.classname;
-
- final String[] names = new String[jmxName.operations.size()];
- final String[] values = new String[jmxName.operations.size()];
- int idx = 0;
- for (final Logs.LogOperationEndpointInfo operation : jmxName.operations) {
- names[idx] = operation.http + " " + operation.address;
- values[idx] = operation.method;
- idx++;
- }
- operations = LocalMBeanServer.tabularData("Operations", "Operations for this endpoint", names, values);
- }
-
- @ManagedAttribute
- @Description("The type of the REST service")
- public String getWadlUrl() {
- if (address.endsWith("?_wadl")) {
- return address;
- }
- return address + "?_wadl";
- }
-
- @ManagedOperation
- @Description("The type of the REST service")
- public String getWadl(final String format) {
- if (format != null && format.toLowerCase().contains("json")) {
- InputStream inputStream = null;
- try {
- final URL url = new URL(getWadlUrl() + "&_type=json");
- final HttpURLConnection connection = HttpURLConnection.class.cast(url.openConnection());
- connection.setRequestProperty("Accept", "application/json");
- connection.setRequestProperty("Content-type", "application/json");
- inputStream = connection.getInputStream();
- return IO.slurp(inputStream);
- } catch (final Exception e) {
- return e.getMessage();
- } finally {
- IO.close(inputStream);
- }
- } else { // xml
- try {
- return IO.slurp(new URL(getWadlUrl()));
- } catch (final IOException e) {
- return e.getMessage();
- }
- }
- }
-
- @ManagedAttribute
- @Description("The type of the REST service")
- public String getType() {
- return type;
- }
-
- @ManagedAttribute
- @Description("The REST service address")
- public String getAddress() {
- return address;
- }
-
- @ManagedAttribute
- @Description("The REST service class name")
- public String getClassname() {
- return classname;
- }
-
- @ManagedAttribute
- @Description("All available methods")
- public TabularData getOperations() {
- return operations;
- }
- }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openejb.server.cxf.rs;
+
+import org.apache.cxf.BusException;
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.endpoint.Endpoint;
+import org.apache.cxf.endpoint.EndpointException;
+import org.apache.cxf.endpoint.ManagedEndpoint;
+import org.apache.cxf.endpoint.Server;
+import org.apache.cxf.endpoint.ServerImpl;
+import org.apache.cxf.helpers.IOUtils;
+import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
+import org.apache.cxf.jaxrs.JAXRSServiceImpl;
+import org.apache.cxf.jaxrs.ext.RequestHandler;
+import org.apache.cxf.jaxrs.ext.ResourceComparator;
+import org.apache.cxf.jaxrs.lifecycle.ResourceProvider;
+import org.apache.cxf.jaxrs.lifecycle.SingletonResourceProvider;
+import org.apache.cxf.jaxrs.model.ClassResourceInfo;
+import org.apache.cxf.jaxrs.model.MethodDispatcher;
+import org.apache.cxf.jaxrs.model.OperationResourceInfo;
+import org.apache.cxf.jaxrs.model.ProviderInfo;
+import org.apache.cxf.jaxrs.model.wadl.WadlGenerator;
+import org.apache.cxf.jaxrs.provider.JAXBElementProvider;
+import org.apache.cxf.jaxrs.provider.json.JSONProvider;
+import org.apache.cxf.service.invoker.Invoker;
+import org.apache.cxf.transport.http.AbstractHTTPDestination;
+import org.apache.cxf.transport.http.HTTPTransportFactory;
+import org.apache.cxf.transport.servlet.BaseUrlHelper;
+import org.apache.openejb.AppContext;
+import org.apache.openejb.BeanContext;
+import org.apache.openejb.Injection;
+import org.apache.openejb.api.internal.Internal;
+import org.apache.openejb.api.jmx.Description;
+import org.apache.openejb.api.jmx.MBean;
+import org.apache.openejb.api.jmx.ManagedAttribute;
+import org.apache.openejb.api.jmx.ManagedOperation;
+import org.apache.openejb.assembler.classic.ServiceInfo;
+import org.apache.openejb.assembler.classic.util.ServiceConfiguration;
+import org.apache.openejb.assembler.classic.util.ServiceInfos;
+import org.apache.openejb.core.WebContext;
+import org.apache.openejb.dyni.DynamicSubclass;
+import org.apache.openejb.loader.IO;
+import org.apache.openejb.loader.SystemInstance;
+import org.apache.openejb.monitoring.LocalMBeanServer;
+import org.apache.openejb.monitoring.ObjectNameBuilder;
+import org.apache.openejb.rest.ThreadLocalContextManager;
+import org.apache.openejb.server.cxf.rs.event.ExtensionProviderRegistration;
+import org.apache.openejb.server.cxf.rs.event.ServerCreated;
+import org.apache.openejb.server.cxf.rs.event.ServerDestroyed;
+import org.apache.openejb.server.cxf.transport.util.CxfUtil;
+import org.apache.openejb.server.httpd.HttpRequest;
+import org.apache.openejb.server.httpd.HttpRequestImpl;
+import org.apache.openejb.server.httpd.HttpResponse;
+import org.apache.openejb.server.httpd.ServletRequestAdapter;
+import org.apache.openejb.server.rest.EJBRestServiceInfo;
+import org.apache.openejb.server.rest.InternalApplication;
+import org.apache.openejb.server.rest.RsHttpListener;
+import org.apache.openejb.util.AppFinder;
+import org.apache.openejb.util.LogCategory;
+import org.apache.openejb.util.Logger;
+import org.apache.openejb.util.proxy.ProxyEJB;
+import org.apache.webbeans.config.WebBeansContext;
+import org.apache.webbeans.container.BeanManagerImpl;
+import org.apache.webbeans.context.creational.CreationalContextImpl;
+
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.spi.Bean;
+import javax.management.ObjectName;
+import javax.management.openmbean.TabularData;
+import javax.naming.Context;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.core.Application;
+import javax.xml.bind.Marshaller;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Constructor;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.logging.Level;
+import java.util.regex.Pattern;
+
+import static org.apache.openejb.loader.JarLocation.jarLocation;
+
+public class CxfRsHttpListener implements RsHttpListener {
+
+ private static final Logger LOGGER = Logger.getInstance(LogCategory.OPENEJB_RS, CxfRsHttpListener.class);
+
+ private static final java.util.logging.Logger SERVER_IMPL_LOGGER = LogUtils.getL7dLogger(ServerImpl.class);
+
+ public static final String CXF_JAXRS_PREFIX = "cxf.jaxrs.";
+ public static final String PROVIDERS_KEY = CXF_JAXRS_PREFIX + "providers";
+ public static final String STATIC_RESOURCE_KEY = CXF_JAXRS_PREFIX + "static-resources-list";
+ public static final String STATIC_SUB_RESOURCE_RESOLUTION_KEY = "staticSubresourceResolution";
+ public static final String RESOURCE_COMPARATOR_KEY = CXF_JAXRS_PREFIX + "resourceComparator";
+
+ public static final boolean TRY_STATIC_RESOURCES = "true".equalsIgnoreCase(SystemInstance.get().getProperty("openejb.jaxrs.static-first", "true"));
+ private static final String GLOBAL_PROVIDERS = SystemInstance.get().getProperty(PROVIDERS_KEY);
+
+ private static final Map<String, String> STATIC_CONTENT_TYPES;
+ private static final String[] DEFAULT_WELCOME_FILES = new String[]{ "/index.html", "/index.htm" };
+
+ private final HTTPTransportFactory transportFactory;
+ private final String wildcard;
+ private AbstractHTTPDestination destination;
+ private Server server;
+ private String context = "";
+ private String servlet = "";
+ private final Collection<Pattern> staticResourcesList = new CopyOnWriteArrayList<Pattern>();
+ private final List<ObjectName> jmxNames = new ArrayList<ObjectName>();
+ private final Collection<CreationalContext<?>> toRelease = new LinkedHashSet<CreationalContext<?>>();
+ private final Collection<CdiSingletonResourceProvider> singletons = new LinkedHashSet<CdiSingletonResourceProvider>();
+
+ private static final char[] URL_SEP = new char[] { '?', '#', ';' };
+
+ static {
+ STATIC_CONTENT_TYPES = new HashMap<String, String>();
+ STATIC_CONTENT_TYPES.put("html", "text/html");
+ STATIC_CONTENT_TYPES.put("xhtml", "text/html");
+ STATIC_CONTENT_TYPES.put("txt", "text/plain");
+ STATIC_CONTENT_TYPES.put("css", "text/css");
+ STATIC_CONTENT_TYPES.put("jpg", "image/jpg");
+ STATIC_CONTENT_TYPES.put("png", "image/png");
+ STATIC_CONTENT_TYPES.put("ico", "image/ico");
+ STATIC_CONTENT_TYPES.put("pdf", "application/pdf");
+ STATIC_CONTENT_TYPES.put("xsd", "application/xml");
+
+ for (final ProviderInfo<RequestHandler> rh : org.apache.cxf.jaxrs.provider.ProviderFactory.getSharedInstance().getRequestHandlers()) {
+ final RequestHandler provider = rh.getProvider();
+ if (WadlGenerator.class.isInstance(provider)) {
+ final WadlGenerator wadlGenerator = WadlGenerator.class.cast(provider);
+ final String ignoreRequests = SystemInstance.get().getProperty("openejb.cxf-rs.wadl-generator.ignoreRequests");
+ final String ignoreMessageWriters = SystemInstance.get().getProperty("openejb.cxf-rs.wadl-generator.ignoreMessageWriters", "false");
+
+ if (ignoreRequests != null) {
+ wadlGenerator.setIgnoreRequests(Boolean.parseBoolean(ignoreRequests));
+ }
+ // CXF-5319: bug in CXF? it prevents to get the wadl as json otherwise
+ if (ignoreMessageWriters != null) {
+ wadlGenerator.setIgnoreMessageWriters(Boolean.parseBoolean(ignoreMessageWriters));
+ }
+ }
+ }
+ }
+
+ private String pattern;
+
+ public CxfRsHttpListener(final HTTPTransportFactory httpTransportFactory, final String star) {
+ transportFactory = httpTransportFactory;
+ wildcard = star;
+ }
+
+ public void setUrlPattern(final String pattern) {
+ this.pattern = pattern;
+ }
+
+ @Override
+ public void onMessage(final HttpRequest httpRequest, final HttpResponse httpResponse) throws Exception {
+ // fix the address (to manage multiple connectors)
+ if (HttpRequestImpl.class.isInstance(httpRequest)) {
+ final HttpRequestImpl requestImpl = HttpRequestImpl.class.cast(httpRequest);
+ requestImpl.initPathFromContext(context);
+ requestImpl.initServletPath(servlet);
+ }
+
+ boolean matchedStatic = false;
+ if (TRY_STATIC_RESOURCES || (matchedStatic = matchPath(httpRequest))) {
+ final String pathInfo = httpRequest.getPathInfo();
+ if (serveStaticContent(httpRequest, httpResponse, pathInfo)) {
+ if (matchedStatic) { // we should have gotten the resource
+ throw new ServletException("Static resource " + pathInfo + " is not available");
+ }
+ return; // ok that's a surely rest service
+ }
+ }
+
+ doInvoke(httpRequest, httpResponse);
+ }
+
+ // normal endpoint without static resource handling
+ public void doInvoke(final HttpRequest httpRequest, final HttpResponse httpResponse) throws IOException {
+ String baseURL = BaseUrlHelper.getBaseURL(pattern != null ? new ServletRequestAdapter(httpRequest) {
+ @Override // we have a filter so we need the computed servlet path to not break CXF
+ public String getServletPath() {
+ return pattern;
+ }
+ } : httpRequest);
+ if (!baseURL.endsWith("/")) {
+ baseURL += "/";
+ }
+ httpRequest.setAttribute("org.apache.cxf.transport.endpoint.address", baseURL);
+
+ final ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
+ Thread.currentThread().setContextClassLoader(CxfUtil.initBusLoader());
+ try {
+ destination.invoke(null, httpRequest.getServletContext(), httpRequest, httpResponse);
+ } catch (final Throwable t) {
+ throw new IOException("Failed to invoke AbstractHTTPDestination", t);
+ } finally {
+ CxfUtil.clearBusLoader(oldLoader);
+ }
+ }
+
+ public boolean matchPath(final HttpServletRequest request) {
+ if (staticResourcesList.isEmpty()) {
+ return false;
+ }
+
+ String path = request.getPathInfo();
+ if (path == null) {
+ path = "/";
+ }
+ for (final Pattern pattern : staticResourcesList) {
+ if (pattern.matcher(path).matches()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public InputStream findStaticContent(final HttpServletRequest request, final String[] welcomeFiles) throws ServletException {
+ String pathInfo = request.getRequestURI().substring(request.getContextPath().length());
+ for (final char c : URL_SEP) {
+ final int indexOf = pathInfo.indexOf(c);
+ if (indexOf > 0) {
+ pathInfo = pathInfo.substring(0, indexOf);
+ }
+ }
+ InputStream is = request.getServletContext().getResourceAsStream(pathInfo);
+ if (is == null && ("/".equals(pathInfo) || pathInfo.isEmpty())) {
+ for (final String n : welcomeFiles) {
+ is = request.getServletContext().getResourceAsStream(n);
+ if (is != null) {
+ break;
+ }
+ }
+ }
+ return is;
+ }
+
+ public boolean serveStaticContent(final HttpServletRequest request,
+ final HttpServletResponse response,
+ final String pathInfo) throws ServletException {
+ final InputStream is = findStaticContent(request, DEFAULT_WELCOME_FILES);
+ if (is == null) {
+ return false;
+ }
+ try {
+ final int ind = pathInfo.lastIndexOf(".");
+ if (ind != -1 && ind < pathInfo.length()) {
+ final String type = STATIC_CONTENT_TYPES.get(pathInfo.substring(ind + 1));
+ if (type != null) {
+ response.setContentType(type);
+ }
+ }
+
+ final ServletOutputStream os = response.getOutputStream();
+ IOUtils.copy(is, os);
+ os.flush();
+ response.setStatus(HttpURLConnection.HTTP_OK);
+ } catch (final IOException ex) {
+ throw new ServletException("Static resource " + pathInfo + " can not be written to the output stream");
+ }
+ return true;
+ }
+
+ @Deprecated
+ @Override
+ public void deploySingleton(final String contextRoot, final String fullContext, final Object o, final Application appInstance,
+ final Collection<Object> additionalProviders, final ServiceConfiguration configuration) {
+ deploy(contextRoot, o.getClass(), fullContext, new SingletonResourceProvider(o),
+ o, appInstance, null, additionalProviders, configuration, null);
+ }
+
+ @Deprecated
+ @Override
+ public void deployPojo(final ClassLoader loader,
+ final String contextRoot,
+ final String fullContext,
+ final Class<?> loadedClazz,
+ final Application app,
+ final Collection<Injection> injections,
+ final Context context,
+ final WebBeansContext owbCtx,
+ final Collection<Object> additionalProviders,
+ final ServiceConfiguration configuration) {
+ deploy(contextRoot, loadedClazz, fullContext, new OpenEJBPerRequestPojoResourceProvider(loader, loadedClazz, injections, context, owbCtx),
+ null, app, null, additionalProviders, configuration, null);
+ }
+
+ @Deprecated
+ @Override
+ public void deployEJB(final String contextRoot,
+ final String fullContext,
+ final BeanContext beanContext,
+ final Collection<Object> additionalProviders,
+ final ServiceConfiguration configuration) {
+ final Object proxy = ProxyEJB.subclassProxy(beanContext);
+
+ deploy(contextRoot, beanContext.getBeanClass(), fullContext, new NoopResourceProvider(beanContext.getBeanClass(), proxy),
+ proxy, null, new OpenEJBEJBInvoker(Collections.singleton(beanContext)), additionalProviders, configuration, beanContext.getWebBeansContext());
+ }
+
+ private void deploy(final String contextRoot, final Class<?> clazz, final String address, final ResourceProvider rp, final Object serviceBean,
+ final Application app, final Invoker invoker, final Collection<Object> additionalProviders, final ServiceConfiguration configuration,
+ final WebBeansContext webBeansContext) {
+ final ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
+ Thread.currentThread().setContextClassLoader(CxfUtil.initBusLoader());
+ try {
+ final JAXRSServerFactoryBean factory = newFactory(address, createServiceJmxName(clazz.getClassLoader()), createEndpointName(app));
+ configureFactory(additionalProviders, configuration, factory, webBeansContext);
+ factory.setResourceClasses(clazz);
+ context = contextRoot;
+ if (context == null) {
+ context = "";
+ }
+ if (!context.startsWith("/")) {
+ context = "/" + context;
+ }
+
+ if (rp != null) {
+ factory.setResourceProvider(rp);
+ }
+ if (app != null) {
+ factory.setApplication(app);
+ }
+ if (invoker != null) {
+ factory.setInvoker(invoker);
+ }
+ if (serviceBean != null) {
+ factory.setServiceBean(serviceBean);
+ } else {
+ factory.setServiceClass(clazz);
+ }
+
+ server = factory.create();
+ destination = (AbstractHTTPDestination) server.getDestination();
+ fireServerCreated(oldLoader);
+ } finally {
+ if (oldLoader != null) {
+ CxfUtil.clearBusLoader(oldLoader);
+ }
+ }
+ }
+
+ private void fireServerCreated(final ClassLoader oldLoader) {
+ final Object ctx = AppFinder.findAppContextOrWeb(oldLoader, new AppFinder.Transformer<Object>() {
+ @Override
+ public Object from(final AppContext appCtx) {
+ return appCtx;
+ }
+
+ @Override
+ public Object from(final WebContext webCtx) {
+ return webCtx;
+ }
+ });
+ final AppContext appCtx = AppContext.class.isInstance(ctx) ? AppContext.class.cast(ctx) : WebContext.class.cast(ctx).getAppContext();
+ WebContext webContext = appCtx == ctx ? null : WebContext.class.cast(ctx);
+ if (webContext == null && appCtx.getWebContexts().size() == 1 && appCtx.getWebContexts().get(0).getClassLoader() == oldLoader) {
+ webContext = appCtx.getWebContexts().get(0);
+ }
+ SystemInstance.get().fireEvent(new ServerCreated(server, appCtx, webContext, this.context));
+ }
+
+ private List<Object> providers(final Collection<ServiceInfo> services, final Collection<Object> additionalProviders, final WebBeansContext ctx) {
+ final List<Object> instances = new ArrayList<Object>();
+ final BeanManagerImpl bm = ctx == null ? null : ctx.getBeanManagerImpl();
+ for (final Object o : additionalProviders) {
+ if (o instanceof Class<?>) {
+ final Class<?> clazz = (Class<?>) o;
+ final String name = clazz.getName();
+ if (shouldSkipProvider(name)) {
+ continue;
+ }
+
+ if (bm != null && bm.isInUse()) {
+ try {
+ final Set<Bean<?>> beans = bm.getBeans(clazz);
+ if (beans != null && !beans.isEmpty()) {
+ final Bean<?> bean = bm.resolve(beans);
+ final CreationalContextImpl<?> creationalContext = bm.createCreationalContext(bean);
+ instances.add(bm.getReference(bean, clazz, creationalContext));
+ toRelease.add(creationalContext);
+ continue;
+ }
+ } catch (final Throwable th) {
+ LOGGER.info("Can't use CDI to create provider " + name);
+ }
+ }
+
+ final Collection<Object> instance = ServiceInfos.resolve(services, new String[]{name}, ProviderFactory.INSTANCE);
+ if (instance != null && !instance.isEmpty()) {
+ instances.add(instance.iterator().next());
+ } else {
+ try {
+ instances.add(newProvider(clazz));
+ } catch (final Exception e) {
+ LOGGER.error("can't instantiate " + name, e);
+ }
+ }
+ } else {
+ final String name = o.getClass().getName();
+ if (shouldSkipProvider(name)) {
+ continue;
+ }
+ instances.add(o);
+ }
+ }
+
+ return instances;
+ }
+
+ private static boolean shouldSkipProvider(final String name) {
+ return "false".equalsIgnoreCase(SystemInstance.get().getProperty(name + ".activated", "true"))
+ || name.startsWith("org.apache.wink.common.internal.");
+ }
+
+ private static void addMandatoryProviders(final Collection<Object> instances) {
+ instances.add(EJBAccessExceptionMapper.INSTANCE);
+ }
+
+ private Object newProvider(final Class<?> clazz) throws IllegalAccessException, InstantiationException {
+ return clazz.newInstance();
+ }
+
+ @Override
+ public void undeploy() {
+ // unregister all MBeans
+ for (final ObjectName objectName : jmxNames) {
+ LocalMBeanServer.unregisterSilently(objectName);
+ }
+
+ for (final CreationalContext<?> cc : toRelease) {
+ try {
+ cc.release();
+ } catch (final Exception e) {
+ LOGGER.warning(e.getMessage(), e);
+ }
+ }
+ for (final CdiSingletonResourceProvider provider : singletons) {
+ try {
+ provider.release();
+ } catch (final Exception e) {
+ LOGGER.warning(e.getMessage(), e);
+ }
+ }
+
+ final ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
+ Thread.currentThread().setContextClassLoader(CxfUtil.initBusLoader());
+ try {
+ server.destroy();
+ SystemInstance.get().fireEvent(new ServerDestroyed(server));
+ } catch (final RuntimeException ise) {
+ LOGGER.warning("Can't stop correctly the endpoint " + server);
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug(ise.getMessage(), ise);
+ }
+ } finally {
+ if (oldLoader != null) {
+ CxfUtil.clearBusLoader(oldLoader);
+ }
+ }
+ }
+
+ @Override
+ public void deployApplication(final Application application, final String prefix, final String webContext,
+ final Collection<Object> additionalProviders,
+ final Map<String, EJBRestServiceInfo> restEjbs, final ClassLoader classLoader,
+ final Collection<Injection> injections, final Context context, final WebBeansContext owbCtx,
+ final ServiceConfiguration serviceConfiguration) {
+ final ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
+ Thread.currentThread().setContextClassLoader(CxfUtil.initBusLoader());
+ try {
+ final JAXRSServerFactoryBean factory = newFactory(prefix, createServiceJmxName(classLoader), createEndpointName(application));
+ configureFactory(additionalProviders, serviceConfiguration, factory, owbCtx);
+ factory.setApplication(application);
+
+ final List<Class<?>> classes = new ArrayList<Class<?>>();
+
+ for (final Class<?> clazz : application.getClasses()) {
+ if (!additionalProviders.contains(clazz) && !clazz.isInterface()) {
+ classes.add(clazz);
+
+ final EJBRestServiceInfo restServiceInfo = getEjbRestServiceInfo(restEjbs, clazz);
+
+ if (restServiceInfo != null) {
+ final Object proxy = ProxyEJB.subclassProxy(restServiceInfo.context);
+ factory.setResourceProvider(clazz, new NoopResourceProvider(restServiceInfo.context.getBeanClass(), proxy));
+ } else {
+ factory.setResourceProvider(clazz, new OpenEJBPerRequestPojoResourceProvider(
+ classLoader, clazz, injections, context, owbCtx));
+ }
+ }
+ }
+
+ for (final Object o : application.getSingletons()) {
+ if (!additionalProviders.contains(o)) {
+ final Class<?> clazz = realClass(o.getClass());
+ classes.add(clazz);
+
+ final EJBRestServiceInfo restServiceInfo = getEjbRestServiceInfo(restEjbs, clazz);
+
+ if (restServiceInfo != null) {
+ final Object proxy = ProxyEJB.subclassProxy(restServiceInfo.context);
+ factory.setResourceProvider(clazz, new NoopResourceProvider(restServiceInfo.context.getBeanClass(), proxy));
+ } else {
+ if (owbCtx.getBeanManagerImpl().isInUse()) {
+ final CdiSingletonResourceProvider provider = new CdiSingletonResourceProvider(classLoader, clazz, o, injections, context, owbCtx);
+ singletons.add(provider);
+ factory.setResourceProvider(clazz, provider);
+ } else {
+ factory.setResourceProvider(clazz, new SingletonResourceProvider(o));
+ }
+ }
+ }
+ }
+
+ factory.setResourceClasses(classes);
+ factory.setInvoker(new AutoJAXRSInvoker(restEjbs));
+
+ this.context = webContext;
+ if (!webContext.startsWith("/")) {
+ this.context = "/" + webContext;
+ } // /webcontext/servlet for event firing
+
+ final Level level = SERVER_IMPL_LOGGER.getLevel();
+ try {
+ SERVER_IMPL_LOGGER.setLevel(Level.OFF);
+ } catch (final UnsupportedOperationException e) {
+ //ignore
+ }
+ try {
+ server = factory.create();
+ fireServerCreated(oldLoader);
+ } finally {
+ try {
+ SERVER_IMPL_LOGGER.setLevel(level);
+ } catch (final UnsupportedOperationException e) {
+ //ignore
+ }
+ }
+
+ final int servletIdx = 1 + this.context.substring(1).indexOf('/');
+ if (servletIdx > 0) {
+ this.servlet = this.context.substring(servletIdx);
+ this.context = this.context.substring(0, servletIdx);
+ }
+ destination = (AbstractHTTPDestination) server.getDestination();
+
+ final String base;
+ if (prefix.endsWith("/")) {
+ base = prefix.substring(0, prefix.length() - 1);
+ } else if (prefix.endsWith(wildcard)) {
+ base = prefix.substring(0, prefix.length() - wildcard.length());
+ } else {
+ base = prefix;
+ }
+
+ // stack info to log to get nice logs
+ logEndpoints(application, prefix, restEjbs, factory, base);
+ } finally {
+ if (oldLoader != null) {
+ CxfUtil.clearBusLoader(oldLoader);
+ }
+ }
+ }
+
+ private EJBRestServiceInfo getEjbRestServiceInfo(final Map<String, EJBRestServiceInfo> restEjbs, final Class<?> clazz) {
+ String name = clazz.getName();
+ EJBRestServiceInfo restServiceInfo = restEjbs.get(name);
+
+ if (name.endsWith(DynamicSubclass.IMPL_SUFFIX)) {
+ name = name.substring(0, name.length() - DynamicSubclass.IMPL_SUFFIX.length());
+ restServiceInfo = restEjbs.get(name);
+ if (restServiceInfo != null) { // AutoJAXRSInvoker relies on it
+ restEjbs.put(clazz.getName(), restServiceInfo);
+ }
+ }
+ return restServiceInfo;
+ }
+
+ private static Class<?> realClass(final Class<?> aClass) {
+ Class<?> result = aClass;
+ while (result.getName().contains("$$")) {
+ result = result.getSuperclass();
+ if (result == null) {
+ return aClass;
+ }
+ }
+ return result;
+ }
+
+ private static String createEndpointName(final Application application) {
+ if (application == null) {
+ return "jaxrs-application";
+ }
+ if (InternalApplication.class.isInstance(application)) {
+ final Application original = InternalApplication.class.cast(application).getOriginal();
+ if (original != null) {
+ return original.getClass().getSimpleName();
+ }
+ return "jaxrs-application";
+ }
+ return application.getClass().getSimpleName();
+ }
+
+ private static String createServiceJmxName(final ClassLoader classLoader) {
+ final AppContext app = AppFinder.findAppContextOrWeb(classLoader, AppFinder.AppContextTransformer.INSTANCE);
+ return app == null ? "application" : app.getId();
+ }
+
+ private void logEndpoints(final Application application, final String prefix,
+ final Map<String, EJBRestServiceInfo> restEjbs,
+ final JAXRSServerFactoryBean factory, final String base) {
+ final List<Logs.LogResourceEndpointInfo> resourcesToLog = new ArrayList<Logs.LogResourceEndpointInfo>();
+ int classSize = 0;
+ int addressSize = 0;
+
+ final JAXRSServiceImpl service = (JAXRSServiceImpl) factory.getServiceFactory().getService();
+ final List<ClassResourceInfo> resources = service.getClassResourceInfos();
+ for (final ClassResourceInfo info : resources) {
+ if (info.getResourceClass() == null) { // possible?
+ continue;
+ }
+
+ final String address = Logs.singleSlash(base, info.getURITemplate().getValue());
+
+ final String clazz = info.getResourceClass().getName();
+ final String type;
+ if (restEjbs.containsKey(clazz)) {
+ type = "EJB";
+ } else {
+ type = "Pojo";
+ }
+
+ classSize = Math.max(classSize, clazz.length());
+ addressSize = Math.max(addressSize, address.length());
+
+ int methodSize = 7;
+ int methodStrSize = 0;
+
+ final List<Logs.LogOperationEndpointInfo> toLog = new ArrayList<Logs.LogOperationEndpointInfo>();
+
+ final MethodDispatcher md = info.getMethodDispatcher();
+ for (final OperationResourceInfo ori : md.getOperationResourceInfos()) {
+ final String httpMethod = ori.getHttpMethod();
+ final String currentAddress = Logs.singleSlash(address, ori.getURITemplate().getValue());
+ final String methodToStr = Logs.toSimpleString(ori.getMethodToInvoke());
+ toLog.add(new Logs.LogOperationEndpointInfo(httpMethod, currentAddress, methodToStr));
+
+ if (httpMethod != null) {
+ methodSize = Math.max(methodSize, httpMethod.length());
+ }
+ addressSize = Math.max(addressSize, currentAddress.length());
+ methodStrSize = Math.max(methodStrSize, methodToStr.length());
+ }
+
+ Collections.sort(toLog);
+
+ resourcesToLog.add(new Logs.LogResourceEndpointInfo(type, address, clazz, toLog, methodSize, methodStrSize));
+ }
+
+ // effective logging
+
+ LOGGER.info("REST Application: " + Logs.forceLength(prefix, addressSize, true) + " -> " + application.getClass().getName());
+
+ Collections.sort(resourcesToLog);
+
+ for (final Logs.LogResourceEndpointInfo resource : resourcesToLog) {
+
+ // Init and register MBeans
+ final ObjectNameBuilder jmxName = new ObjectNameBuilder("openejb.management")
+ .set("j2eeType", "JAX-RS")
+ .set("J2EEServer", "openejb")
+ .set("J2EEApplication", base)
+ .set("EndpointType", resource.type)
+ .set("name", resource.classname);
+
+ final ObjectName jmxObjectName = jmxName.build();
+ LocalMBeanServer.registerDynamicWrapperSilently(
+ new RestServiceMBean(resource),
+ jmxObjectName);
+
+ jmxNames.add(jmxObjectName);
+
+ LOGGER.info(" Service URI: "
+ + Logs.forceLength(resource.address, addressSize, true) + " -> "
+ + Logs.forceLength(resource.type, 4, false) + " "
+ + Logs.forceLength(resource.classname, classSize, true));
+
+ for (final Logs.LogOperationEndpointInfo log : resource.operations) {
+ LOGGER.info(" "
+ + Logs.forceLength(log.http, resource.methodSize, false) + " "
+ + Logs.forceLength(log.address, addressSize, true) + " -> "
+ + Logs.forceLength(log.method, resource.methodStrSize, true));
+ }
+
+ resource.operations.clear();
+ }
+ resourcesToLog.clear();
+ }
+
+ private JAXRSServerFactoryBean newFactory(final String prefix, final String service, final String endpoint) {
+ final JAXRSServerFactoryBean factory = new JAXRSServerFactoryBean() {
+ @Override
+ protected Endpoint createEndpoint() throws BusException, EndpointException {
+ final Endpoint created = super.createEndpoint();
+ created.put(ManagedEndpoint.SERVICE_NAME, service);
+ created.put(ManagedEndpoint.ENDPOINT_NAME, endpoint);
+ return created;
+ }
+ };
+ factory.setDestinationFactory(transportFactory);
+ factory.setBus(CxfUtil.getBus());
+ factory.setAddress(prefix);
+ return factory;
+ }
+
+ private void configureFactory(final Collection<Object> givenAdditionalProviders,
+ final ServiceConfiguration serviceConfiguration,
+ final JAXRSServerFactoryBean factory,
+ final WebBeansContext ctx) {
+ CxfUtil.configureEndpoint(factory, serviceConfiguration, CXF_JAXRS_PREFIX);
+
+ final Collection<ServiceInfo> services = serviceConfiguration.getAvailableServices();
+
+ final String staticSubresourceResolution = serviceConfiguration.getProperties().getProperty(CXF_JAXRS_PREFIX + STATIC_SUB_RESOURCE_RESOLUTION_KEY);
+ if (staticSubresourceResolution != null) {
+ factory.setStaticSubresourceResolution("true".equalsIgnoreCase(staticSubresourceResolution));
+ }
+
+ // resource comparator
+ final String resourceComparator = serviceConfiguration.getProperties().getProperty(RESOURCE_COMPARATOR_KEY);
+ if (resourceComparator != null) {
+ try {
+ ResourceComparator instance = (ResourceComparator) ServiceInfos.resolve(services, resourceComparator);
+ if (instance == null) {
+ instance = (ResourceComparator) Thread.currentThread().getContextClassLoader()
+ .loadClass(resourceComparator).newInstance();
+ }
+ factory.setResourceComparator(instance);
+ } catch (final Exception e) {
+ LOGGER.error("Can't create the resource comparator " + resourceComparator, e);
+ }
+ }
+
+ // static resources
+ final String staticResources = serviceConfiguration.getProperties().getProperty(STATIC_RESOURCE_KEY);
+ if (staticResources != null) {
+ final String[] resources = staticResources.split(",");
+ for (final String r : resources) {
+ final String trimmed = r.trim();
+ if (!trimmed.isEmpty()) {
+ staticResourcesList.add(Pattern.compile(trimmed));
+ }
+ }
+ }
+
+ // providers
+ Set<String> providersConfig = null;
+
+ {
+ final String provider = serviceConfiguration.getProperties().getProperty(PROVIDERS_KEY);
+ if (provider != null) { // already ordered and high priority since they were configured manually
+ providersConfig = new HashSet<String>();
+ for (final String p : Arrays.asList(provider.split(","))) {
+ providersConfig.add(p.trim());
+ }
+ }
+
+ {
+ if (GLOBAL_PROVIDERS != null) { // same idea, Note: this doesn't affect much cases which are not embedded so don't spend time on it
+ if (providersConfig == null) {
+ providersConfig = new HashSet<String>();
+ }
+ providersConfig.addAll(Arrays.asList(GLOBAL_PROVIDERS.split(",")));
+ }
+ }
+ }
+
+ // another property to configure the scanning of providers but this one is consistent with current cxf config
+ // the
<TRUNCATED>