From eed9839124d1b4ce894458a960d203e89e1c6898 Mon Sep 17 00:00:00 2001 From: lashini Date: Thu, 16 Jan 2025 14:08:10 +0530 Subject: [PATCH 1/5] Add CustomCXFNonSpringJaxrsServlet --- .../pom.xml | 83 +++ .../mgt/CustomCXFNonSpringJaxrsServlet.java | 688 ++++++++++++++++++ components/servlet-mgt/pom.xml | 25 + .../pom.xml | 96 +++ features/servlet-mgt/pom.xml | 39 + pom.xml | 16 +- 6 files changed, 946 insertions(+), 1 deletion(-) create mode 100644 components/servlet-mgt/org.wso2.carbon.identity.servlet.mgt/pom.xml create mode 100644 components/servlet-mgt/org.wso2.carbon.identity.servlet.mgt/src/main/java/org/wso2/carbon/identity/servlet/mgt/CustomCXFNonSpringJaxrsServlet.java create mode 100644 components/servlet-mgt/pom.xml create mode 100644 features/servlet-mgt/org.wso2.carbon.identity.servlet.mgt.server.feature/pom.xml create mode 100644 features/servlet-mgt/pom.xml diff --git a/components/servlet-mgt/org.wso2.carbon.identity.servlet.mgt/pom.xml b/components/servlet-mgt/org.wso2.carbon.identity.servlet.mgt/pom.xml new file mode 100644 index 000000000000..a0fcabbcbd22 --- /dev/null +++ b/components/servlet-mgt/org.wso2.carbon.identity.servlet.mgt/pom.xml @@ -0,0 +1,83 @@ + + + 4.0.0 + + org.wso2.carbon.identity.framework + identity-framework + 7.7.88-SNAPSHOT + ../../../pom.xml + + + org.wso2.carbon.identity.servlet.mgt + bundle + WSO2 Identity - Servlet Management Component + The Servlet Management backend component + http://wso2.org + + + + org.apache.cxf + cxf-core + provided + + + org.apache.cxf + cxf-rt-frontend-jaxrs + + + javax.ws.rs + javax.ws.rs-api + + + provided + + + javax.ws.rs + javax.ws.rs-api + provided + + + javax.servlet + javax.servlet-api + provided + + + + + + + org.apache.felix + maven-bundle-plugin + true + + + + ${project.artifactId} + + ${project.artifactId} + + org.wso2.carbon.identity.servlet.mgt.*; version="${carbon.identity.package.export.version}" + + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + + true + + + + com.github.spotbugs + spotbugs-maven-plugin + + true + + + + + + diff --git a/components/servlet-mgt/org.wso2.carbon.identity.servlet.mgt/src/main/java/org/wso2/carbon/identity/servlet/mgt/CustomCXFNonSpringJaxrsServlet.java b/components/servlet-mgt/org.wso2.carbon.identity.servlet.mgt/src/main/java/org/wso2/carbon/identity/servlet/mgt/CustomCXFNonSpringJaxrsServlet.java new file mode 100644 index 000000000000..93a344fe24b4 --- /dev/null +++ b/components/servlet-mgt/org.wso2.carbon.identity.servlet.mgt/src/main/java/org/wso2/carbon/identity/servlet/mgt/CustomCXFNonSpringJaxrsServlet.java @@ -0,0 +1,688 @@ +/* + * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). + * + * WSO2 LLC. 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.wso2.carbon.identity.servlet.mgt; + +import org.apache.cxf.Bus; +import org.apache.cxf.common.classloader.ClassLoaderUtils; +import org.apache.cxf.common.logging.LogUtils; +import org.apache.cxf.common.util.PrimitiveUtils; +import org.apache.cxf.common.util.PropertyUtils; +import org.apache.cxf.common.util.StringUtils; +import org.apache.cxf.feature.Feature; +import org.apache.cxf.helpers.CastUtils; +import org.apache.cxf.interceptor.Interceptor; +import org.apache.cxf.jaxrs.JAXRSServerFactoryBean; +import org.apache.cxf.jaxrs.lifecycle.PerRequestResourceProvider; +import org.apache.cxf.jaxrs.lifecycle.ResourceProvider; +import org.apache.cxf.jaxrs.lifecycle.SingletonResourceProvider; +import org.apache.cxf.jaxrs.model.ApplicationInfo; +import org.apache.cxf.jaxrs.model.ProviderInfo; +import org.apache.cxf.jaxrs.provider.ProviderFactory; +import org.apache.cxf.jaxrs.utils.InjectionUtils; +import org.apache.cxf.jaxrs.utils.ResourceUtils; +import org.apache.cxf.message.Message; +import org.apache.cxf.service.invoker.Invoker; +import org.apache.cxf.transport.http.DestinationRegistry; +import org.apache.cxf.transport.servlet.CXFNonSpringServlet; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.ws.rs.core.Application; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.*; +import java.util.logging.Logger; + +public class CustomCXFNonSpringJaxrsServlet extends CXFNonSpringServlet { + + private static final long serialVersionUID = -8916352798780577499L; + private static final Logger LOG = LogUtils.getL7dLogger(CustomCXFNonSpringJaxrsServlet.class); + private static final String USER_MODEL_PARAM = "user.model"; + private static final String SERVICE_ADDRESS_PARAM = "jaxrs.address"; + private static final String IGNORE_APP_PATH_PARAM = "jaxrs.application.address.ignore"; + private static final String SERVICE_CLASSES_PARAM = "jaxrs.serviceClasses"; + private static final String PROVIDERS_PARAM = "jaxrs.providers"; + private static final String FEATURES_PARAM = "jaxrs.features"; + private static final String OUT_INTERCEPTORS_PARAM = "jaxrs.outInterceptors"; + private static final String OUT_FAULT_INTERCEPTORS_PARAM = "jaxrs.outFaultInterceptors"; + private static final String IN_INTERCEPTORS_PARAM = "jaxrs.inInterceptors"; + private static final String INVOKER_PARAM = "jaxrs.invoker"; + private static final String SERVICE_SCOPE_PARAM = "jaxrs.scope"; + private static final String EXTENSIONS_PARAM = "jaxrs.extensions"; + private static final String LANGUAGES_PARAM = "jaxrs.languages"; + private static final String PROPERTIES_PARAM = "jaxrs.properties"; + private static final String SCHEMAS_PARAM = "jaxrs.schemaLocations"; + private static final String DOC_LOCATION_PARAM = "jaxrs.documentLocation"; + private static final String STATIC_SUB_RESOLUTION_PARAM = "jaxrs.static.subresources"; + private static final String SERVICE_SCOPE_SINGLETON = "singleton"; + private static final String SERVICE_SCOPE_REQUEST = "prototype"; + private static final String PARAMETER_SPLIT_CHAR = "class.parameter.split.char"; + private static final String DEFAULT_PARAMETER_SPLIT_CHAR = ","; + private static final String SPACE_PARAMETER_SPLIT_CHAR = "space"; + private static final String JAXRS_APPLICATION_PARAM = "javax.ws.rs.Application"; + + private static Map systemPropMap = new HashMap(); + private ClassLoader classLoader; + private Application application; + + static { + systemPropMap.put("rest.api.admin.attachment.max.size", "10485760"); + systemPropMap.put("rest.api.devportal.attachment.max.size", "10485760"); + systemPropMap.put("rest.api.publisher.attachment.max.size", "10485760"); + systemPropMap.put("rest.api.service.catalog.attachment.max.size", "10485760"); + } + + public CustomCXFNonSpringJaxrsServlet() { + } + + public CustomCXFNonSpringJaxrsServlet(Application app) { + + this.application = app; + } + + public CustomCXFNonSpringJaxrsServlet(Application app, DestinationRegistry destinationRegistry, Bus bus) { + + super(destinationRegistry, bus); + this.application = app; + } + + public void init(ServletConfig servletConfig) throws ServletException { + + super.init(servletConfig); + if (this.getApplication() != null) { + this.createServerFromApplication(servletConfig); + } else { + String applicationClass = servletConfig.getInitParameter("javax.ws.rs.Application"); + if (applicationClass != null) { + this.createServerFromApplication(applicationClass, servletConfig); + } else { + String splitChar = this.getParameterSplitChar(servletConfig); + JAXRSServerFactoryBean bean = new JAXRSServerFactoryBean(); + bean.setBus(this.getBus()); + String address = servletConfig.getInitParameter("jaxrs.address"); + if (address == null) { + address = "/"; + } + + bean.setAddress(address); + bean.setStaticSubresourceResolution(this.getStaticSubResolutionValue(servletConfig)); + String modelRef = servletConfig.getInitParameter("user.model"); + if (modelRef != null) { + bean.setModelRef(modelRef.trim()); + } + + this.setDocLocation(bean, servletConfig); + this.setSchemasLocations(bean, servletConfig); + this.setAllInterceptors(bean, servletConfig, splitChar); + this.setInvoker(bean, servletConfig); + Map, Map>> resourceClasses = this.getServiceClasses(servletConfig, modelRef != null, splitChar); + Map, ResourceProvider> resourceProviders = this.getResourceProviders(servletConfig, resourceClasses); + List providers = this.getProviders(servletConfig, splitChar); + bean.setResourceClasses(new ArrayList(resourceClasses.keySet())); + bean.setProviders(providers); + Iterator var10 = resourceProviders.entrySet().iterator(); + + while (var10.hasNext()) { + Map.Entry, ResourceProvider> entry = (Map.Entry) var10.next(); + bean.setResourceProvider((Class) entry.getKey(), (ResourceProvider) entry.getValue()); + } + + this.setExtensions(bean, servletConfig); + List features = this.getFeatures(servletConfig, splitChar); + bean.getFeatures().addAll(features); + bean.create(); + } + } + } + + protected String getParameterSplitChar(ServletConfig servletConfig) { + + String param = servletConfig.getInitParameter("class.parameter.split.char"); + return !StringUtils.isEmpty(param) && "space".equals(param.trim()) ? " " : ","; + } + + protected boolean getStaticSubResolutionValue(ServletConfig servletConfig) { + + String param = servletConfig.getInitParameter("jaxrs.static.subresources"); + return param != null ? Boolean.valueOf(param.trim()) : false; + } + + protected void setExtensions(JAXRSServerFactoryBean bean, ServletConfig servletConfig) { + + bean.setExtensionMappings(CastUtils.cast(parseMapSequence(servletConfig.getInitParameter("jaxrs.extensions")))); + bean.setLanguageMappings(CastUtils.cast(parseMapSequence(servletConfig.getInitParameter("jaxrs.languages")))); + Map properties = CastUtils.cast(parseMapSequence(servletConfig.getInitParameter("jaxrs.properties")), String.class, Object.class); + + //Custom impl to allow property values to be defined as system properties + for (Map.Entry entry : properties.entrySet()) { + String key = entry.getKey(); + String value = entry.getValue().toString(); + + if (value.startsWith("{systemProperties")) { + int begin = value.indexOf("'"); + int end = value.lastIndexOf("'"); + String propertyKey = value.substring(begin + 1, end); + String systemPropValue = System.getProperty(propertyKey); + if (systemPropValue != null && !systemPropValue.isEmpty()) { + properties.put(key, systemPropValue); + } else { + properties.put(key, systemPropMap.get(propertyKey)); + } + } + } + + if (properties != null && !properties.isEmpty()) { + bean.getProperties(true).putAll(properties); + } + } + + protected void setAllInterceptors(JAXRSServerFactoryBean bean, ServletConfig servletConfig, String splitChar) throws ServletException { + + this.setInterceptors(bean, servletConfig, "jaxrs.outInterceptors", splitChar); + this.setInterceptors(bean, servletConfig, "jaxrs.outFaultInterceptors", splitChar); + this.setInterceptors(bean, servletConfig, "jaxrs.inInterceptors", splitChar); + } + + protected void setSchemasLocations(JAXRSServerFactoryBean bean, ServletConfig servletConfig) { + + String schemas = servletConfig.getInitParameter("jaxrs.schemaLocations"); + if (schemas != null) { + String[] locations = schemas.split(" "); + List list = new ArrayList(); + String[] var6 = locations; + int var7 = locations.length; + + for (int var8 = 0; var8 < var7; ++var8) { + String loc = var6[var8]; + String theLoc = loc.trim(); + if (!theLoc.isEmpty()) { + list.add(theLoc); + } + } + + if (!list.isEmpty()) { + bean.setSchemaLocations(list); + } + + } + } + + protected void setDocLocation(JAXRSServerFactoryBean bean, ServletConfig servletConfig) { + + String wadlLoc = servletConfig.getInitParameter("jaxrs.documentLocation"); + if (wadlLoc != null) { + bean.setDocLocation(wadlLoc); + } + + } + + protected void setInterceptors(JAXRSServerFactoryBean bean, ServletConfig servletConfig, String paramName, String splitChar) throws ServletException { + + String value = servletConfig.getInitParameter(paramName); + if (value != null) { + String[] values = value.split(splitChar); + List> list = new ArrayList(); + String[] var8 = values; + int var9 = values.length; + + for (int var10 = 0; var10 < var9; ++var10) { + String interceptorVal = var8[var10]; + Map> props = new HashMap(); + String theValue = this.getClassNameAndProperties(interceptorVal, props); + if (!theValue.isEmpty()) { + try { + Class intClass = this.loadClass(theValue, "Interceptor"); + Object object = intClass.getDeclaredConstructor().newInstance(); + this.injectProperties(object, props); + list.add((Interceptor) object); + } catch (ServletException var16) { + throw var16; + } catch (Exception var17) { + LOG.warning("Interceptor class " + theValue + " can not be created"); + throw new ServletException(var17); + } + } + } + + if (!list.isEmpty()) { + if ("jaxrs.outInterceptors".equals(paramName)) { + bean.setOutInterceptors(list); + } else if ("jaxrs.outFaultInterceptors".equals(paramName)) { + bean.setOutFaultInterceptors(list); + } else { + bean.setInInterceptors(list); + } + } + + } + } + + protected void setInvoker(JAXRSServerFactoryBean bean, ServletConfig servletConfig) throws ServletException { + + String value = servletConfig.getInitParameter("jaxrs.invoker"); + if (value != null) { + Map> props = new HashMap(); + String theValue = this.getClassNameAndProperties(value, props); + if (!theValue.isEmpty()) { + try { + Class intClass = this.loadClass(theValue, "Invoker"); + Object object = intClass.getDeclaredConstructor().newInstance(); + this.injectProperties(object, props); + bean.setInvoker((Invoker) object); + } catch (ServletException var8) { + throw var8; + } catch (Exception var9) { + LOG.warning("Invoker class " + theValue + " can not be created"); + throw new ServletException(var9); + } + } + + } + } + + protected Map, Map>> getServiceClasses(ServletConfig servletConfig, boolean modelAvailable, String splitChar) throws ServletException { + + String serviceBeans = servletConfig.getInitParameter("jaxrs.serviceClasses"); + if (serviceBeans == null) { + if (modelAvailable) { + return Collections.emptyMap(); + } else { + throw new ServletException("At least one resource class should be specified"); + } + } else { + String[] classNames = serviceBeans.split(splitChar); + Map, Map>> map = new HashMap(); + String[] var7 = classNames; + int var8 = classNames.length; + + for (int var9 = 0; var9 < var8; ++var9) { + String cName = var7[var9]; + Map> props = new HashMap(); + String theName = this.getClassNameAndProperties(cName, props); + if (!theName.isEmpty()) { + Class cls = this.loadClass(theName); + map.put(cls, props); + } + } + + if (map.isEmpty()) { + throw new ServletException("At least one resource class should be specified"); + } else { + return map; + } + } + } + + protected List getFeatures(ServletConfig servletConfig, String splitChar) throws ServletException { + + String featuresList = servletConfig.getInitParameter("jaxrs.features"); + if (featuresList == null) { + return Collections.emptyList(); + } else { + String[] classNames = featuresList.split(splitChar); + List features = new ArrayList(); + String[] var6 = classNames; + int var7 = classNames.length; + + for (int var8 = 0; var8 < var7; ++var8) { + String cName = var6[var8]; + Map> props = new HashMap(); + String theName = this.getClassNameAndProperties(cName, props); + if (!theName.isEmpty()) { + Class cls = this.loadClass(theName); + if (Feature.class.isAssignableFrom(cls)) { + features.add((Feature) this.createSingletonInstance(cls, props, servletConfig)); + } + } + } + + return features; + } + } + + protected List getProviders(ServletConfig servletConfig, String splitChar) throws ServletException { + + String providersList = servletConfig.getInitParameter("jaxrs.providers"); + if (providersList == null) { + return Collections.emptyList(); + } else { + String[] classNames = providersList.split(splitChar); + List providers = new ArrayList(); + String[] var6 = classNames; + int var7 = classNames.length; + + for (int var8 = 0; var8 < var7; ++var8) { + String cName = var6[var8]; + Map> props = new HashMap(); + String theName = this.getClassNameAndProperties(cName, props); + if (!theName.isEmpty()) { + Class cls = this.loadClass(theName); + providers.add(this.createSingletonInstance(cls, props, servletConfig)); + } + } + + return providers; + } + } + + private String getClassNameAndProperties(String cName, Map> props) { + + String theName = cName.trim(); + int ind = theName.indexOf(40); + if (ind != -1 && theName.endsWith(")")) { + props.putAll(parseMapListSequence(theName.substring(ind + 1, theName.length() - 1))); + theName = theName.substring(0, ind).trim(); + } + + return theName; + } + + protected static Map> parseMapListSequence(String sequence) { + + if (sequence != null) { + sequence = sequence.trim(); + Map> map = new HashMap(); + String[] pairs = sequence.split(" "); + String[] var3 = pairs; + int var4 = pairs.length; + + for (int var5 = 0; var5 < var4; ++var5) { + String pair = var3[var5]; + String thePair = pair.trim(); + if (thePair.length() != 0) { + String[] values = thePair.split("="); + String key; + String value; + if (values.length == 2) { + key = values[0].trim(); + value = values[1].trim(); + } else { + key = thePair; + value = ""; + } + + List list = (List) map.get(key); + if (list == null) { + list = new LinkedList(); + map.put(key, list); + } + + ((List) list).add(value); + } + } + + return map; + } else { + return Collections.emptyMap(); + } + } + + protected Map, ResourceProvider> getResourceProviders(ServletConfig servletConfig, Map, Map>> resourceClasses) throws ServletException { + + String scope = servletConfig.getInitParameter("jaxrs.scope"); + if (scope != null && !"singleton".equals(scope) && !"prototype".equals(scope)) { + throw new ServletException("Only singleton and prototype scopes are supported"); + } else { + boolean isPrototype = "prototype".equals(scope); + Map, ResourceProvider> map = new HashMap(); + Iterator var6 = resourceClasses.entrySet().iterator(); + + while (var6.hasNext()) { + Map.Entry, Map>> entry = (Map.Entry) var6.next(); + Class c = (Class) entry.getKey(); + map.put(c, isPrototype ? new PerRequestResourceProvider(c) : new SingletonResourceProvider(this.createSingletonInstance(c, (Map) entry.getValue(), servletConfig), true)); + } + + return map; + } + } + + protected boolean isAppResourceLifecycleASingleton(Application app, ServletConfig servletConfig) { + + String scope = servletConfig.getInitParameter("jaxrs.scope"); + if (scope == null) { + scope = (String) app.getProperties().get("jaxrs.scope"); + } + + return "singleton".equals(scope); + } + + protected Object createSingletonInstance(Class cls, Map> props, ServletConfig sc) throws ServletException { + + Constructor c = ResourceUtils.findResourceConstructor(cls, false); + if (c == null) { + throw new ServletException("No valid constructor found for " + cls.getName()); + } else { + boolean isApplication = Application.class.isAssignableFrom(c.getDeclaringClass()); + + try { + Object provider; + if (c.getParameterTypes().length == 0) { + if (isApplication) { + provider = new ApplicationInfo((Application) c.newInstance(), this.getBus()); + } else { + provider = new ProviderInfo(c.newInstance(), this.getBus(), false, true); + } + } else { + Map, Object> values = new HashMap(); + values.put(ServletContext.class, sc.getServletContext()); + values.put(ServletConfig.class, sc); + provider = ProviderFactory.createProviderFromConstructor(c, values, this.getBus(), isApplication, true); + } + + Object instance = ((ProviderInfo) provider).getProvider(); + this.injectProperties(instance, props); + this.configureSingleton(instance); + return isApplication ? provider : instance; + } catch (InstantiationException var8) { + var8.printStackTrace(); + throw new ServletException("Resource class " + cls.getName() + " can not be instantiated"); + } catch (IllegalAccessException var9) { + var9.printStackTrace(); + throw new ServletException("Resource class " + cls.getName() + " can not be instantiated due to IllegalAccessException"); + } catch (InvocationTargetException var10) { + var10.printStackTrace(); + throw new ServletException("Resource class " + cls.getName() + " can not be instantiated due to InvocationTargetException"); + } + } + } + + private void injectProperties(Object instance, Map> props) { + + if (props != null && !props.isEmpty()) { + Method[] methods = instance.getClass().getMethods(); + Map methodsMap = new HashMap(); + Method[] var5 = methods; + int var6 = methods.length; + + for (int var7 = 0; var7 < var6; ++var7) { + Method m = var5[var7]; + methodsMap.put(m.getName(), m); + } + + Iterator var10 = props.entrySet().iterator(); + + while (var10.hasNext()) { + Map.Entry> entry = (Map.Entry) var10.next(); + Method m = (Method) methodsMap.get("set" + StringUtils.capitalize((String) entry.getKey())); + if (m != null) { + Class type = m.getParameterTypes()[0]; + Object value; + if (InjectionUtils.isPrimitive(type)) { + value = PrimitiveUtils.read((String) ((List) entry.getValue()).get(0), type); + } else { + value = entry.getValue(); + } + + InjectionUtils.injectThroughMethod(instance, m, value); + } + } + + } + } + + protected void configureSingleton(Object instance) { + } + + protected void createServerFromApplication(String applicationNames, ServletConfig servletConfig) throws ServletException { + + boolean ignoreApplicationPath = this.isIgnoreApplicationPath(servletConfig); + String[] classNames = applicationNames.split(this.getParameterSplitChar(servletConfig)); + if (classNames.length > 1 && ignoreApplicationPath) { + throw new ServletException("\"jaxrs.application.address.ignore\" parameter must be set to false for multiple Applications be supported"); + } else { + String[] var5 = classNames; + int var6 = classNames.length; + + for (int var7 = 0; var7 < var6; ++var7) { + String cName = var5[var7]; + ApplicationInfo providerApp = this.createApplicationInfo(cName, servletConfig); + Application app = (Application) providerApp.getProvider(); + JAXRSServerFactoryBean bean = ResourceUtils.createApplication(app, ignoreApplicationPath, this.getStaticSubResolutionValue(servletConfig), this.isAppResourceLifecycleASingleton(app, servletConfig), this.getBus()); + String splitChar = this.getParameterSplitChar(servletConfig); + this.setAllInterceptors(bean, servletConfig, splitChar); + this.setInvoker(bean, servletConfig); + this.setExtensions(bean, servletConfig); + this.setDocLocation(bean, servletConfig); + this.setSchemasLocations(bean, servletConfig); + List providers = this.getProviders(servletConfig, splitChar); + bean.setProviders(providers); + List features = this.getFeatures(servletConfig, splitChar); + bean.getFeatures().addAll(features); + bean.setBus(this.getBus()); + bean.setApplicationInfo(providerApp); + bean.create(); + } + + } + } + + protected boolean isIgnoreApplicationPath(ServletConfig servletConfig) { + + String ignoreParam = servletConfig.getInitParameter("jaxrs.application.address.ignore"); + return ignoreParam == null || PropertyUtils.isTrue(ignoreParam); + } + + protected void createServerFromApplication(ServletConfig servletConfig) throws ServletException { + + Application app = this.getApplication(); + JAXRSServerFactoryBean bean = ResourceUtils.createApplication(app, this.isIgnoreApplicationPath(servletConfig), this.getStaticSubResolutionValue(servletConfig), this.isAppResourceLifecycleASingleton(app, servletConfig), this.getBus()); + String splitChar = this.getParameterSplitChar(servletConfig); + this.setAllInterceptors(bean, servletConfig, splitChar); + this.setInvoker(bean, servletConfig); + this.setExtensions(bean, servletConfig); + this.setDocLocation(bean, servletConfig); + this.setSchemasLocations(bean, servletConfig); + List providers = this.getProviders(servletConfig, splitChar); + bean.setProviders(providers); + List features = this.getFeatures(servletConfig, splitChar); + bean.getFeatures().addAll(features); + bean.setBus(this.getBus()); + bean.setApplication(this.getApplication()); + bean.create(); + } + + protected Application createApplicationInstance(String appClassName, ServletConfig servletConfig) throws ServletException { + + return null; + } + + protected ApplicationInfo createApplicationInfo(String appClassName, ServletConfig servletConfig) throws ServletException { + + Application customApp = this.createApplicationInstance(appClassName, servletConfig); + if (customApp != null) { + return new ApplicationInfo(customApp, this.getBus()); + } else { + Map> props = new HashMap(); + appClassName = this.getClassNameAndProperties(appClassName, props); + Class appClass = this.loadApplicationClass(appClassName); + ApplicationInfo appInfo = (ApplicationInfo) this.createSingletonInstance(appClass, props, servletConfig); + Map servletProps = new HashMap(); + ServletContext servletContext = servletConfig.getServletContext(); + Enumeration names = servletContext.getInitParameterNames(); + + String name; + while (names.hasMoreElements()) { + name = (String) names.nextElement(); + servletProps.put(name, servletContext.getInitParameter(name)); + } + + names = servletConfig.getInitParameterNames(); + + while (names.hasMoreElements()) { + name = (String) names.nextElement(); + servletProps.put(name, servletConfig.getInitParameter(name)); + } + + appInfo.setOverridingProps(servletProps); + return appInfo; + } + } + + protected Class loadApplicationClass(String appClassName) throws ServletException { + + return this.loadClass(appClassName, "Application"); + } + + protected Class loadClass(String cName) throws ServletException { + + return this.loadClass(cName, "Resource"); + } + + protected Class loadClass(String cName, String classType) throws ServletException { + + try { + Class cls; + if (this.classLoader == null) { + cls = ClassLoaderUtils.loadClass(cName, org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrsServlet.class); + } else { + cls = this.classLoader.loadClass(cName); + } + + return cls; + } catch (ClassNotFoundException var4) { + throw new ServletException("No " + classType + " class " + cName.trim() + " can be found", var4); + } + } + + public void setClassLoader(ClassLoader loader) { + + this.classLoader = loader; + } + + protected Application getApplication() { + + return this.application; + } + + private static class ApplicationImpl extends Application { + + private Set applicationSingletons; + + ApplicationImpl(Set applicationSingletons) { + this.applicationSingletons = applicationSingletons; + } + + public Set getSingletons() { + return this.applicationSingletons; + } + } +} diff --git a/components/servlet-mgt/pom.xml b/components/servlet-mgt/pom.xml new file mode 100644 index 000000000000..862e69bc9c31 --- /dev/null +++ b/components/servlet-mgt/pom.xml @@ -0,0 +1,25 @@ + + + 4.0.0 + + org.wso2.carbon.identity.framework + identity-framework + 7.7.88-SNAPSHOT + ../../pom.xml + + + servlet-mgt + pom + WSO2 Carbon - Servlet Management + + This is a Carbon bundle that represent the Servlet Management Module. + + http://wso2.org + + + org.wso2.carbon.identity.servlet.mgt + + + diff --git a/features/servlet-mgt/org.wso2.carbon.identity.servlet.mgt.server.feature/pom.xml b/features/servlet-mgt/org.wso2.carbon.identity.servlet.mgt.server.feature/pom.xml new file mode 100644 index 000000000000..c665a83699db --- /dev/null +++ b/features/servlet-mgt/org.wso2.carbon.identity.servlet.mgt.server.feature/pom.xml @@ -0,0 +1,96 @@ + + + + + + org.wso2.carbon.identity.framework + servlet-management-feature + 7.7.88-SNAPSHOT + ../pom.xml + + + 4.0.0 + org.wso2.carbon.identity.servlet.mgt.server.feature + pom + Servlet Management Server Feature + http://wso2.org + This feature contains the core bundles required for Servlet Management Framework + + + + org.wso2.carbon.identity.framework + org.wso2.carbon.identity.servlet.mgt + + + + + + + org.wso2.maven + carbon-p2-plugin + ${carbon.p2.plugin.version} + + + 4-p2-feature-generation + package + + p2-feature-gen + + + org.wso2.carbon.identity.api.resource.mgt.server + ../../etc/feature.properties + + + org.wso2.carbon.p2.category.type:server + + + + + org.wso2.carbon.identity.framework:org.wso2.carbon.identity.servlet.mgt + + + + + + + + org.apache.maven.plugins + maven-antrun-plugin + 1.1 + + + clean_target + install + + + + + + + + + run + + + + + + + + diff --git a/features/servlet-mgt/pom.xml b/features/servlet-mgt/pom.xml new file mode 100644 index 000000000000..bdbf25cf9aa2 --- /dev/null +++ b/features/servlet-mgt/pom.xml @@ -0,0 +1,39 @@ + + + + + + org.wso2.carbon.identity.framework + identity-framework + 7.7.88-SNAPSHOT + ../../pom.xml + + + 4.0.0 + servlet-management-feature + pom + WSO2 Carbon - Servlet Management Feature + http://wso2.org + + + org.wso2.carbon.identity.servlet.mgt.server.feature + + + + diff --git a/pom.xml b/pom.xml index 9864b071f125..1f644167e7a0 100644 --- a/pom.xml +++ b/pom.xml @@ -74,6 +74,7 @@ components/rule-mgt components/action-mgt components/certificate-mgt + components/servlet-mgt features/extension-mgt components/consent-server-configs-mgt features/security-mgt @@ -110,6 +111,9 @@ features/rule-mgt features/action-mgt features/certificate-mgt + features/servlet-mgt + components/servlet-mgt + components/servlet-mgt/org.wso2.carbon.identity.servlet.mgt @@ -1698,6 +1702,11 @@ cxf-rt-rs-service-description ${apache.cxf-rt-rs-service-description.version} + + org.apache.cxf + cxf-rt-frontend-jaxrs + ${apache.cxf-rt-frontend-jaxrs.version} + org.codehaus.jettison jettison @@ -1718,6 +1727,11 @@ org.wso2.carbon.identity.central.log.mgt ${project.version} + + org.wso2.carbon.identity.framework + org.wso2.carbon.identity.servlet.mgt + ${project.version} + org.wso2.orbit.org.apache.commons commons-compress @@ -1821,7 +1835,7 @@ 9.0.11 - 2.7.16 + 3.6.4 3.3.7 1.4.0 5.1.1.RELEASE From f1e49432a22f47ee8f0f5125011abe264942d699 Mon Sep 17 00:00:00 2001 From: lashini Date: Thu, 16 Jan 2025 15:13:33 +0530 Subject: [PATCH 2/5] Add CustomCXFNonSpringJaxrsServlet --- .../mgt/CustomCXFNonSpringJaxrsServlet.java | 19 ++++++++++++++----- .../pom.xml | 2 +- pom.xml | 2 -- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/components/servlet-mgt/org.wso2.carbon.identity.servlet.mgt/src/main/java/org/wso2/carbon/identity/servlet/mgt/CustomCXFNonSpringJaxrsServlet.java b/components/servlet-mgt/org.wso2.carbon.identity.servlet.mgt/src/main/java/org/wso2/carbon/identity/servlet/mgt/CustomCXFNonSpringJaxrsServlet.java index 93a344fe24b4..47190e299738 100644 --- a/components/servlet-mgt/org.wso2.carbon.identity.servlet.mgt/src/main/java/org/wso2/carbon/identity/servlet/mgt/CustomCXFNonSpringJaxrsServlet.java +++ b/components/servlet-mgt/org.wso2.carbon.identity.servlet.mgt/src/main/java/org/wso2/carbon/identity/servlet/mgt/CustomCXFNonSpringJaxrsServlet.java @@ -41,16 +41,25 @@ import org.apache.cxf.transport.http.DestinationRegistry; import org.apache.cxf.transport.servlet.CXFNonSpringServlet; -import javax.servlet.ServletConfig; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.ws.rs.core.Application; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.logging.Logger; +import javax.servlet.ServletConfig; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.ws.rs.core.Application; + public class CustomCXFNonSpringJaxrsServlet extends CXFNonSpringServlet { private static final long serialVersionUID = -8916352798780577499L; diff --git a/features/servlet-mgt/org.wso2.carbon.identity.servlet.mgt.server.feature/pom.xml b/features/servlet-mgt/org.wso2.carbon.identity.servlet.mgt.server.feature/pom.xml index c665a83699db..ca8183eebed9 100644 --- a/features/servlet-mgt/org.wso2.carbon.identity.servlet.mgt.server.feature/pom.xml +++ b/features/servlet-mgt/org.wso2.carbon.identity.servlet.mgt.server.feature/pom.xml @@ -53,7 +53,7 @@ p2-feature-gen - org.wso2.carbon.identity.api.resource.mgt.server + org.wso2.carbon.identity.servlet.mgt.server ../../etc/feature.properties diff --git a/pom.xml b/pom.xml index 1f644167e7a0..84f829f9f6ea 100644 --- a/pom.xml +++ b/pom.xml @@ -112,8 +112,6 @@ features/action-mgt features/certificate-mgt features/servlet-mgt - components/servlet-mgt - components/servlet-mgt/org.wso2.carbon.identity.servlet.mgt From 57aa289d3f35012e1f8f679bd293795c5bf99d7c Mon Sep 17 00:00:00 2001 From: lashini Date: Thu, 16 Jan 2025 15:51:12 +0530 Subject: [PATCH 3/5] Remove unnecessary dependency --- .../org.wso2.carbon.identity.servlet.mgt/pom.xml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/components/servlet-mgt/org.wso2.carbon.identity.servlet.mgt/pom.xml b/components/servlet-mgt/org.wso2.carbon.identity.servlet.mgt/pom.xml index a0fcabbcbd22..f70c0136b01f 100644 --- a/components/servlet-mgt/org.wso2.carbon.identity.servlet.mgt/pom.xml +++ b/components/servlet-mgt/org.wso2.carbon.identity.servlet.mgt/pom.xml @@ -17,11 +17,6 @@ http://wso2.org - - org.apache.cxf - cxf-core - provided - org.apache.cxf cxf-rt-frontend-jaxrs @@ -60,6 +55,9 @@ org.wso2.carbon.identity.servlet.mgt.*; version="${carbon.identity.package.export.version}" + + javax.servlet.*; version="${imp.pkg.version.javax.servlet}" + From 77dfb0e086f161cb0a364d2f38c4aef99a9f0d8e Mon Sep 17 00:00:00 2001 From: lashini Date: Thu, 16 Jan 2025 15:58:20 +0530 Subject: [PATCH 4/5] fix formattings --- .../mgt/CustomCXFNonSpringJaxrsServlet.java | 1307 +++++++++-------- 1 file changed, 660 insertions(+), 647 deletions(-) diff --git a/components/servlet-mgt/org.wso2.carbon.identity.servlet.mgt/src/main/java/org/wso2/carbon/identity/servlet/mgt/CustomCXFNonSpringJaxrsServlet.java b/components/servlet-mgt/org.wso2.carbon.identity.servlet.mgt/src/main/java/org/wso2/carbon/identity/servlet/mgt/CustomCXFNonSpringJaxrsServlet.java index 47190e299738..e33cc99b7164 100644 --- a/components/servlet-mgt/org.wso2.carbon.identity.servlet.mgt/src/main/java/org/wso2/carbon/identity/servlet/mgt/CustomCXFNonSpringJaxrsServlet.java +++ b/components/servlet-mgt/org.wso2.carbon.identity.servlet.mgt/src/main/java/org/wso2/carbon/identity/servlet/mgt/CustomCXFNonSpringJaxrsServlet.java @@ -1,20 +1,20 @@ /* - * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). - * - * WSO2 LLC. 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. - */ +* Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com). +* +* WSO2 LLC. 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.wso2.carbon.identity.servlet.mgt; @@ -62,636 +62,649 @@ public class CustomCXFNonSpringJaxrsServlet extends CXFNonSpringServlet { - private static final long serialVersionUID = -8916352798780577499L; - private static final Logger LOG = LogUtils.getL7dLogger(CustomCXFNonSpringJaxrsServlet.class); - private static final String USER_MODEL_PARAM = "user.model"; - private static final String SERVICE_ADDRESS_PARAM = "jaxrs.address"; - private static final String IGNORE_APP_PATH_PARAM = "jaxrs.application.address.ignore"; - private static final String SERVICE_CLASSES_PARAM = "jaxrs.serviceClasses"; - private static final String PROVIDERS_PARAM = "jaxrs.providers"; - private static final String FEATURES_PARAM = "jaxrs.features"; - private static final String OUT_INTERCEPTORS_PARAM = "jaxrs.outInterceptors"; - private static final String OUT_FAULT_INTERCEPTORS_PARAM = "jaxrs.outFaultInterceptors"; - private static final String IN_INTERCEPTORS_PARAM = "jaxrs.inInterceptors"; - private static final String INVOKER_PARAM = "jaxrs.invoker"; - private static final String SERVICE_SCOPE_PARAM = "jaxrs.scope"; - private static final String EXTENSIONS_PARAM = "jaxrs.extensions"; - private static final String LANGUAGES_PARAM = "jaxrs.languages"; - private static final String PROPERTIES_PARAM = "jaxrs.properties"; - private static final String SCHEMAS_PARAM = "jaxrs.schemaLocations"; - private static final String DOC_LOCATION_PARAM = "jaxrs.documentLocation"; - private static final String STATIC_SUB_RESOLUTION_PARAM = "jaxrs.static.subresources"; - private static final String SERVICE_SCOPE_SINGLETON = "singleton"; - private static final String SERVICE_SCOPE_REQUEST = "prototype"; - private static final String PARAMETER_SPLIT_CHAR = "class.parameter.split.char"; - private static final String DEFAULT_PARAMETER_SPLIT_CHAR = ","; - private static final String SPACE_PARAMETER_SPLIT_CHAR = "space"; - private static final String JAXRS_APPLICATION_PARAM = "javax.ws.rs.Application"; - - private static Map systemPropMap = new HashMap(); - private ClassLoader classLoader; - private Application application; - - static { - systemPropMap.put("rest.api.admin.attachment.max.size", "10485760"); - systemPropMap.put("rest.api.devportal.attachment.max.size", "10485760"); - systemPropMap.put("rest.api.publisher.attachment.max.size", "10485760"); - systemPropMap.put("rest.api.service.catalog.attachment.max.size", "10485760"); - } - - public CustomCXFNonSpringJaxrsServlet() { - } - - public CustomCXFNonSpringJaxrsServlet(Application app) { - - this.application = app; - } - - public CustomCXFNonSpringJaxrsServlet(Application app, DestinationRegistry destinationRegistry, Bus bus) { - - super(destinationRegistry, bus); - this.application = app; - } - - public void init(ServletConfig servletConfig) throws ServletException { - - super.init(servletConfig); - if (this.getApplication() != null) { - this.createServerFromApplication(servletConfig); - } else { - String applicationClass = servletConfig.getInitParameter("javax.ws.rs.Application"); - if (applicationClass != null) { - this.createServerFromApplication(applicationClass, servletConfig); - } else { - String splitChar = this.getParameterSplitChar(servletConfig); - JAXRSServerFactoryBean bean = new JAXRSServerFactoryBean(); - bean.setBus(this.getBus()); - String address = servletConfig.getInitParameter("jaxrs.address"); - if (address == null) { - address = "/"; - } - - bean.setAddress(address); - bean.setStaticSubresourceResolution(this.getStaticSubResolutionValue(servletConfig)); - String modelRef = servletConfig.getInitParameter("user.model"); - if (modelRef != null) { - bean.setModelRef(modelRef.trim()); - } - - this.setDocLocation(bean, servletConfig); - this.setSchemasLocations(bean, servletConfig); - this.setAllInterceptors(bean, servletConfig, splitChar); - this.setInvoker(bean, servletConfig); - Map, Map>> resourceClasses = this.getServiceClasses(servletConfig, modelRef != null, splitChar); - Map, ResourceProvider> resourceProviders = this.getResourceProviders(servletConfig, resourceClasses); - List providers = this.getProviders(servletConfig, splitChar); - bean.setResourceClasses(new ArrayList(resourceClasses.keySet())); - bean.setProviders(providers); - Iterator var10 = resourceProviders.entrySet().iterator(); - - while (var10.hasNext()) { - Map.Entry, ResourceProvider> entry = (Map.Entry) var10.next(); - bean.setResourceProvider((Class) entry.getKey(), (ResourceProvider) entry.getValue()); - } - - this.setExtensions(bean, servletConfig); - List features = this.getFeatures(servletConfig, splitChar); - bean.getFeatures().addAll(features); - bean.create(); - } - } - } - - protected String getParameterSplitChar(ServletConfig servletConfig) { - - String param = servletConfig.getInitParameter("class.parameter.split.char"); - return !StringUtils.isEmpty(param) && "space".equals(param.trim()) ? " " : ","; - } - - protected boolean getStaticSubResolutionValue(ServletConfig servletConfig) { - - String param = servletConfig.getInitParameter("jaxrs.static.subresources"); - return param != null ? Boolean.valueOf(param.trim()) : false; - } - - protected void setExtensions(JAXRSServerFactoryBean bean, ServletConfig servletConfig) { - - bean.setExtensionMappings(CastUtils.cast(parseMapSequence(servletConfig.getInitParameter("jaxrs.extensions")))); - bean.setLanguageMappings(CastUtils.cast(parseMapSequence(servletConfig.getInitParameter("jaxrs.languages")))); - Map properties = CastUtils.cast(parseMapSequence(servletConfig.getInitParameter("jaxrs.properties")), String.class, Object.class); - - //Custom impl to allow property values to be defined as system properties - for (Map.Entry entry : properties.entrySet()) { - String key = entry.getKey(); - String value = entry.getValue().toString(); - - if (value.startsWith("{systemProperties")) { - int begin = value.indexOf("'"); - int end = value.lastIndexOf("'"); - String propertyKey = value.substring(begin + 1, end); - String systemPropValue = System.getProperty(propertyKey); - if (systemPropValue != null && !systemPropValue.isEmpty()) { - properties.put(key, systemPropValue); - } else { - properties.put(key, systemPropMap.get(propertyKey)); - } - } - } - - if (properties != null && !properties.isEmpty()) { - bean.getProperties(true).putAll(properties); - } - } - - protected void setAllInterceptors(JAXRSServerFactoryBean bean, ServletConfig servletConfig, String splitChar) throws ServletException { - - this.setInterceptors(bean, servletConfig, "jaxrs.outInterceptors", splitChar); - this.setInterceptors(bean, servletConfig, "jaxrs.outFaultInterceptors", splitChar); - this.setInterceptors(bean, servletConfig, "jaxrs.inInterceptors", splitChar); - } - - protected void setSchemasLocations(JAXRSServerFactoryBean bean, ServletConfig servletConfig) { - - String schemas = servletConfig.getInitParameter("jaxrs.schemaLocations"); - if (schemas != null) { - String[] locations = schemas.split(" "); - List list = new ArrayList(); - String[] var6 = locations; - int var7 = locations.length; - - for (int var8 = 0; var8 < var7; ++var8) { - String loc = var6[var8]; - String theLoc = loc.trim(); - if (!theLoc.isEmpty()) { - list.add(theLoc); - } - } - - if (!list.isEmpty()) { - bean.setSchemaLocations(list); - } - - } - } - - protected void setDocLocation(JAXRSServerFactoryBean bean, ServletConfig servletConfig) { - - String wadlLoc = servletConfig.getInitParameter("jaxrs.documentLocation"); - if (wadlLoc != null) { - bean.setDocLocation(wadlLoc); - } - - } - - protected void setInterceptors(JAXRSServerFactoryBean bean, ServletConfig servletConfig, String paramName, String splitChar) throws ServletException { - - String value = servletConfig.getInitParameter(paramName); - if (value != null) { - String[] values = value.split(splitChar); - List> list = new ArrayList(); - String[] var8 = values; - int var9 = values.length; - - for (int var10 = 0; var10 < var9; ++var10) { - String interceptorVal = var8[var10]; - Map> props = new HashMap(); - String theValue = this.getClassNameAndProperties(interceptorVal, props); - if (!theValue.isEmpty()) { - try { - Class intClass = this.loadClass(theValue, "Interceptor"); - Object object = intClass.getDeclaredConstructor().newInstance(); - this.injectProperties(object, props); - list.add((Interceptor) object); - } catch (ServletException var16) { - throw var16; - } catch (Exception var17) { - LOG.warning("Interceptor class " + theValue + " can not be created"); - throw new ServletException(var17); - } - } - } - - if (!list.isEmpty()) { - if ("jaxrs.outInterceptors".equals(paramName)) { - bean.setOutInterceptors(list); - } else if ("jaxrs.outFaultInterceptors".equals(paramName)) { - bean.setOutFaultInterceptors(list); - } else { - bean.setInInterceptors(list); - } - } - - } - } - - protected void setInvoker(JAXRSServerFactoryBean bean, ServletConfig servletConfig) throws ServletException { - - String value = servletConfig.getInitParameter("jaxrs.invoker"); - if (value != null) { - Map> props = new HashMap(); - String theValue = this.getClassNameAndProperties(value, props); - if (!theValue.isEmpty()) { - try { - Class intClass = this.loadClass(theValue, "Invoker"); - Object object = intClass.getDeclaredConstructor().newInstance(); - this.injectProperties(object, props); - bean.setInvoker((Invoker) object); - } catch (ServletException var8) { - throw var8; - } catch (Exception var9) { - LOG.warning("Invoker class " + theValue + " can not be created"); - throw new ServletException(var9); - } - } - - } - } - - protected Map, Map>> getServiceClasses(ServletConfig servletConfig, boolean modelAvailable, String splitChar) throws ServletException { - - String serviceBeans = servletConfig.getInitParameter("jaxrs.serviceClasses"); - if (serviceBeans == null) { - if (modelAvailable) { - return Collections.emptyMap(); - } else { - throw new ServletException("At least one resource class should be specified"); - } - } else { - String[] classNames = serviceBeans.split(splitChar); - Map, Map>> map = new HashMap(); - String[] var7 = classNames; - int var8 = classNames.length; - - for (int var9 = 0; var9 < var8; ++var9) { - String cName = var7[var9]; - Map> props = new HashMap(); - String theName = this.getClassNameAndProperties(cName, props); - if (!theName.isEmpty()) { - Class cls = this.loadClass(theName); - map.put(cls, props); - } - } - - if (map.isEmpty()) { - throw new ServletException("At least one resource class should be specified"); - } else { - return map; - } - } - } - - protected List getFeatures(ServletConfig servletConfig, String splitChar) throws ServletException { - - String featuresList = servletConfig.getInitParameter("jaxrs.features"); - if (featuresList == null) { - return Collections.emptyList(); - } else { - String[] classNames = featuresList.split(splitChar); - List features = new ArrayList(); - String[] var6 = classNames; - int var7 = classNames.length; - - for (int var8 = 0; var8 < var7; ++var8) { - String cName = var6[var8]; - Map> props = new HashMap(); - String theName = this.getClassNameAndProperties(cName, props); - if (!theName.isEmpty()) { - Class cls = this.loadClass(theName); - if (Feature.class.isAssignableFrom(cls)) { - features.add((Feature) this.createSingletonInstance(cls, props, servletConfig)); - } - } - } - - return features; - } - } - - protected List getProviders(ServletConfig servletConfig, String splitChar) throws ServletException { - - String providersList = servletConfig.getInitParameter("jaxrs.providers"); - if (providersList == null) { - return Collections.emptyList(); - } else { - String[] classNames = providersList.split(splitChar); - List providers = new ArrayList(); - String[] var6 = classNames; - int var7 = classNames.length; - - for (int var8 = 0; var8 < var7; ++var8) { - String cName = var6[var8]; - Map> props = new HashMap(); - String theName = this.getClassNameAndProperties(cName, props); - if (!theName.isEmpty()) { - Class cls = this.loadClass(theName); - providers.add(this.createSingletonInstance(cls, props, servletConfig)); - } - } - - return providers; - } - } - - private String getClassNameAndProperties(String cName, Map> props) { - - String theName = cName.trim(); - int ind = theName.indexOf(40); - if (ind != -1 && theName.endsWith(")")) { - props.putAll(parseMapListSequence(theName.substring(ind + 1, theName.length() - 1))); - theName = theName.substring(0, ind).trim(); - } - - return theName; - } - - protected static Map> parseMapListSequence(String sequence) { - - if (sequence != null) { - sequence = sequence.trim(); - Map> map = new HashMap(); - String[] pairs = sequence.split(" "); - String[] var3 = pairs; - int var4 = pairs.length; - - for (int var5 = 0; var5 < var4; ++var5) { - String pair = var3[var5]; - String thePair = pair.trim(); - if (thePair.length() != 0) { - String[] values = thePair.split("="); - String key; - String value; - if (values.length == 2) { - key = values[0].trim(); - value = values[1].trim(); - } else { - key = thePair; - value = ""; - } - - List list = (List) map.get(key); - if (list == null) { - list = new LinkedList(); - map.put(key, list); - } - - ((List) list).add(value); - } - } - - return map; - } else { - return Collections.emptyMap(); - } - } - - protected Map, ResourceProvider> getResourceProviders(ServletConfig servletConfig, Map, Map>> resourceClasses) throws ServletException { - - String scope = servletConfig.getInitParameter("jaxrs.scope"); - if (scope != null && !"singleton".equals(scope) && !"prototype".equals(scope)) { - throw new ServletException("Only singleton and prototype scopes are supported"); - } else { - boolean isPrototype = "prototype".equals(scope); - Map, ResourceProvider> map = new HashMap(); - Iterator var6 = resourceClasses.entrySet().iterator(); - - while (var6.hasNext()) { - Map.Entry, Map>> entry = (Map.Entry) var6.next(); - Class c = (Class) entry.getKey(); - map.put(c, isPrototype ? new PerRequestResourceProvider(c) : new SingletonResourceProvider(this.createSingletonInstance(c, (Map) entry.getValue(), servletConfig), true)); - } - - return map; - } - } - - protected boolean isAppResourceLifecycleASingleton(Application app, ServletConfig servletConfig) { - - String scope = servletConfig.getInitParameter("jaxrs.scope"); - if (scope == null) { - scope = (String) app.getProperties().get("jaxrs.scope"); - } - - return "singleton".equals(scope); - } - - protected Object createSingletonInstance(Class cls, Map> props, ServletConfig sc) throws ServletException { - - Constructor c = ResourceUtils.findResourceConstructor(cls, false); - if (c == null) { - throw new ServletException("No valid constructor found for " + cls.getName()); - } else { - boolean isApplication = Application.class.isAssignableFrom(c.getDeclaringClass()); - - try { - Object provider; - if (c.getParameterTypes().length == 0) { - if (isApplication) { - provider = new ApplicationInfo((Application) c.newInstance(), this.getBus()); - } else { - provider = new ProviderInfo(c.newInstance(), this.getBus(), false, true); - } - } else { - Map, Object> values = new HashMap(); - values.put(ServletContext.class, sc.getServletContext()); - values.put(ServletConfig.class, sc); - provider = ProviderFactory.createProviderFromConstructor(c, values, this.getBus(), isApplication, true); - } - - Object instance = ((ProviderInfo) provider).getProvider(); - this.injectProperties(instance, props); - this.configureSingleton(instance); - return isApplication ? provider : instance; - } catch (InstantiationException var8) { - var8.printStackTrace(); - throw new ServletException("Resource class " + cls.getName() + " can not be instantiated"); - } catch (IllegalAccessException var9) { - var9.printStackTrace(); - throw new ServletException("Resource class " + cls.getName() + " can not be instantiated due to IllegalAccessException"); - } catch (InvocationTargetException var10) { - var10.printStackTrace(); - throw new ServletException("Resource class " + cls.getName() + " can not be instantiated due to InvocationTargetException"); - } - } - } - - private void injectProperties(Object instance, Map> props) { - - if (props != null && !props.isEmpty()) { - Method[] methods = instance.getClass().getMethods(); - Map methodsMap = new HashMap(); - Method[] var5 = methods; - int var6 = methods.length; - - for (int var7 = 0; var7 < var6; ++var7) { - Method m = var5[var7]; - methodsMap.put(m.getName(), m); - } - - Iterator var10 = props.entrySet().iterator(); - - while (var10.hasNext()) { - Map.Entry> entry = (Map.Entry) var10.next(); - Method m = (Method) methodsMap.get("set" + StringUtils.capitalize((String) entry.getKey())); - if (m != null) { - Class type = m.getParameterTypes()[0]; - Object value; - if (InjectionUtils.isPrimitive(type)) { - value = PrimitiveUtils.read((String) ((List) entry.getValue()).get(0), type); - } else { - value = entry.getValue(); - } - - InjectionUtils.injectThroughMethod(instance, m, value); - } - } - - } - } - - protected void configureSingleton(Object instance) { - } - - protected void createServerFromApplication(String applicationNames, ServletConfig servletConfig) throws ServletException { - - boolean ignoreApplicationPath = this.isIgnoreApplicationPath(servletConfig); - String[] classNames = applicationNames.split(this.getParameterSplitChar(servletConfig)); - if (classNames.length > 1 && ignoreApplicationPath) { - throw new ServletException("\"jaxrs.application.address.ignore\" parameter must be set to false for multiple Applications be supported"); - } else { - String[] var5 = classNames; - int var6 = classNames.length; - - for (int var7 = 0; var7 < var6; ++var7) { - String cName = var5[var7]; - ApplicationInfo providerApp = this.createApplicationInfo(cName, servletConfig); - Application app = (Application) providerApp.getProvider(); - JAXRSServerFactoryBean bean = ResourceUtils.createApplication(app, ignoreApplicationPath, this.getStaticSubResolutionValue(servletConfig), this.isAppResourceLifecycleASingleton(app, servletConfig), this.getBus()); - String splitChar = this.getParameterSplitChar(servletConfig); - this.setAllInterceptors(bean, servletConfig, splitChar); - this.setInvoker(bean, servletConfig); - this.setExtensions(bean, servletConfig); - this.setDocLocation(bean, servletConfig); - this.setSchemasLocations(bean, servletConfig); - List providers = this.getProviders(servletConfig, splitChar); - bean.setProviders(providers); - List features = this.getFeatures(servletConfig, splitChar); - bean.getFeatures().addAll(features); - bean.setBus(this.getBus()); - bean.setApplicationInfo(providerApp); - bean.create(); - } - - } - } - - protected boolean isIgnoreApplicationPath(ServletConfig servletConfig) { - - String ignoreParam = servletConfig.getInitParameter("jaxrs.application.address.ignore"); - return ignoreParam == null || PropertyUtils.isTrue(ignoreParam); - } - - protected void createServerFromApplication(ServletConfig servletConfig) throws ServletException { - - Application app = this.getApplication(); - JAXRSServerFactoryBean bean = ResourceUtils.createApplication(app, this.isIgnoreApplicationPath(servletConfig), this.getStaticSubResolutionValue(servletConfig), this.isAppResourceLifecycleASingleton(app, servletConfig), this.getBus()); - String splitChar = this.getParameterSplitChar(servletConfig); - this.setAllInterceptors(bean, servletConfig, splitChar); - this.setInvoker(bean, servletConfig); - this.setExtensions(bean, servletConfig); - this.setDocLocation(bean, servletConfig); - this.setSchemasLocations(bean, servletConfig); - List providers = this.getProviders(servletConfig, splitChar); - bean.setProviders(providers); - List features = this.getFeatures(servletConfig, splitChar); - bean.getFeatures().addAll(features); - bean.setBus(this.getBus()); - bean.setApplication(this.getApplication()); - bean.create(); - } - - protected Application createApplicationInstance(String appClassName, ServletConfig servletConfig) throws ServletException { - - return null; - } - - protected ApplicationInfo createApplicationInfo(String appClassName, ServletConfig servletConfig) throws ServletException { - - Application customApp = this.createApplicationInstance(appClassName, servletConfig); - if (customApp != null) { - return new ApplicationInfo(customApp, this.getBus()); - } else { - Map> props = new HashMap(); - appClassName = this.getClassNameAndProperties(appClassName, props); - Class appClass = this.loadApplicationClass(appClassName); - ApplicationInfo appInfo = (ApplicationInfo) this.createSingletonInstance(appClass, props, servletConfig); - Map servletProps = new HashMap(); - ServletContext servletContext = servletConfig.getServletContext(); - Enumeration names = servletContext.getInitParameterNames(); - - String name; - while (names.hasMoreElements()) { - name = (String) names.nextElement(); - servletProps.put(name, servletContext.getInitParameter(name)); - } - - names = servletConfig.getInitParameterNames(); - - while (names.hasMoreElements()) { - name = (String) names.nextElement(); - servletProps.put(name, servletConfig.getInitParameter(name)); - } - - appInfo.setOverridingProps(servletProps); - return appInfo; - } - } - - protected Class loadApplicationClass(String appClassName) throws ServletException { - - return this.loadClass(appClassName, "Application"); - } - - protected Class loadClass(String cName) throws ServletException { - - return this.loadClass(cName, "Resource"); - } - - protected Class loadClass(String cName, String classType) throws ServletException { - - try { - Class cls; - if (this.classLoader == null) { - cls = ClassLoaderUtils.loadClass(cName, org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrsServlet.class); - } else { - cls = this.classLoader.loadClass(cName); - } - - return cls; - } catch (ClassNotFoundException var4) { - throw new ServletException("No " + classType + " class " + cName.trim() + " can be found", var4); - } - } - - public void setClassLoader(ClassLoader loader) { - - this.classLoader = loader; - } - - protected Application getApplication() { - - return this.application; - } - - private static class ApplicationImpl extends Application { + private static final long serialVersionUID = -8916352798780577499L; + private static final Logger LOG = LogUtils.getL7dLogger(CustomCXFNonSpringJaxrsServlet.class); + private static final String USER_MODEL_PARAM = "user.model"; + private static final String SERVICE_ADDRESS_PARAM = "jaxrs.address"; + private static final String IGNORE_APP_PATH_PARAM = "jaxrs.application.address.ignore"; + private static final String SERVICE_CLASSES_PARAM = "jaxrs.serviceClasses"; + private static final String PROVIDERS_PARAM = "jaxrs.providers"; + private static final String FEATURES_PARAM = "jaxrs.features"; + private static final String OUT_INTERCEPTORS_PARAM = "jaxrs.outInterceptors"; + private static final String OUT_FAULT_INTERCEPTORS_PARAM = "jaxrs.outFaultInterceptors"; + private static final String IN_INTERCEPTORS_PARAM = "jaxrs.inInterceptors"; + private static final String INVOKER_PARAM = "jaxrs.invoker"; + private static final String SERVICE_SCOPE_PARAM = "jaxrs.scope"; + private static final String EXTENSIONS_PARAM = "jaxrs.extensions"; + private static final String LANGUAGES_PARAM = "jaxrs.languages"; + private static final String PROPERTIES_PARAM = "jaxrs.properties"; + private static final String SCHEMAS_PARAM = "jaxrs.schemaLocations"; + private static final String DOC_LOCATION_PARAM = "jaxrs.documentLocation"; + private static final String STATIC_SUB_RESOLUTION_PARAM = "jaxrs.static.subresources"; + private static final String SERVICE_SCOPE_SINGLETON = "singleton"; + private static final String SERVICE_SCOPE_REQUEST = "prototype"; + private static final String PARAMETER_SPLIT_CHAR = "class.parameter.split.char"; + private static final String DEFAULT_PARAMETER_SPLIT_CHAR = ","; + private static final String SPACE_PARAMETER_SPLIT_CHAR = "space"; + private static final String JAXRS_APPLICATION_PARAM = "javax.ws.rs.Application"; + + private static Map systemPropMap = new HashMap(); + private ClassLoader classLoader; + private Application application; + + static { + systemPropMap.put("rest.api.admin.attachment.max.size", "10485760"); + systemPropMap.put("rest.api.devportal.attachment.max.size", "10485760"); + systemPropMap.put("rest.api.publisher.attachment.max.size", "10485760"); + systemPropMap.put("rest.api.service.catalog.attachment.max.size", "10485760"); + } + + public CustomCXFNonSpringJaxrsServlet() { + + } + + public CustomCXFNonSpringJaxrsServlet(Application app) { + + this.application = app; + } + + public CustomCXFNonSpringJaxrsServlet(Application app, DestinationRegistry destinationRegistry, Bus bus) { + + super(destinationRegistry, bus); + this.application = app; + } + + public void init(ServletConfig servletConfig) throws ServletException { + + super.init(servletConfig); + if (this.getApplication() != null) { + this.createServerFromApplication(servletConfig); + } else { + String applicationClass = servletConfig.getInitParameter(JAXRS_APPLICATION_PARAM); + if (applicationClass != null) { + this.createServerFromApplication(applicationClass, servletConfig); + } else { + String splitChar = this.getParameterSplitChar(servletConfig); + JAXRSServerFactoryBean bean = new JAXRSServerFactoryBean(); + bean.setBus(this.getBus()); + String address = servletConfig.getInitParameter(SERVICE_ADDRESS_PARAM); + if (address == null) { + address = "/"; + } + + bean.setAddress(address); + bean.setStaticSubresourceResolution(this.getStaticSubResolutionValue(servletConfig)); + String modelRef = servletConfig.getInitParameter(USER_MODEL_PARAM); + if (modelRef != null) { + bean.setModelRef(modelRef.trim()); + } + + this.setDocLocation(bean, servletConfig); + this.setSchemasLocations(bean, servletConfig); + this.setAllInterceptors(bean, servletConfig, splitChar); + this.setInvoker(bean, servletConfig); + Map, Map>> resourceClasses = this.getServiceClasses(servletConfig, + modelRef != null, splitChar); + Map, ResourceProvider> resourceProviders = this.getResourceProviders(servletConfig, + resourceClasses); + List providers = this.getProviders(servletConfig, splitChar); + bean.setResourceClasses(new ArrayList(resourceClasses.keySet())); + bean.setProviders(providers); + Iterator iterator = resourceProviders.entrySet().iterator(); + + while (iterator.hasNext()) { + Map.Entry, ResourceProvider> entry = (Map.Entry) iterator.next(); + bean.setResourceProvider((Class) entry.getKey(), (ResourceProvider) entry.getValue()); + } + + this.setExtensions(bean, servletConfig); + List features = this.getFeatures(servletConfig, splitChar); + bean.getFeatures().addAll(features); + bean.create(); + } + } + } + + protected String getParameterSplitChar(ServletConfig servletConfig) { + + String param = servletConfig.getInitParameter(PARAMETER_SPLIT_CHAR); + return !StringUtils.isEmpty(param) && SPACE_PARAMETER_SPLIT_CHAR.equals(param.trim()) ? " " + : DEFAULT_PARAMETER_SPLIT_CHAR; + } + + protected boolean getStaticSubResolutionValue(ServletConfig servletConfig) { + + String param = servletConfig.getInitParameter(STATIC_SUB_RESOLUTION_PARAM); + return param != null ? Boolean.valueOf(param.trim()) : false; + } + + protected void setExtensions(JAXRSServerFactoryBean bean, ServletConfig servletConfig) { + + bean.setExtensionMappings(CastUtils.cast(parseMapSequence(servletConfig.getInitParameter(EXTENSIONS_PARAM)))); + bean.setLanguageMappings(CastUtils.cast(parseMapSequence(servletConfig.getInitParameter(LANGUAGES_PARAM)))); + Map properties = CastUtils.cast(parseMapSequence( + servletConfig.getInitParameter(PROPERTIES_PARAM)), String.class, Object.class); + + //Custom impl to allow property values to be defined as system properties + for (Map.Entry entry : properties.entrySet()) { + String key = entry.getKey(); + String value = entry.getValue().toString(); + + if (value.startsWith("{systemProperties")) { + int begin = value.indexOf("'"); + int end = value.lastIndexOf("'"); + String propertyKey = value.substring(begin + 1, end); + String systemPropValue = System.getProperty(propertyKey); + if (systemPropValue != null && !systemPropValue.isEmpty()) { + properties.put(key, systemPropValue); + } else { + properties.put(key, systemPropMap.get(propertyKey)); + } + } + } + + if (properties != null && !properties.isEmpty()) { + bean.getProperties(true).putAll(properties); + } + } + + protected void setAllInterceptors(JAXRSServerFactoryBean bean, ServletConfig servletConfig, + String splitChar) throws ServletException { + + this.setInterceptors(bean, servletConfig, OUT_INTERCEPTORS_PARAM, splitChar); + this.setInterceptors(bean, servletConfig, OUT_FAULT_INTERCEPTORS_PARAM, splitChar); + this.setInterceptors(bean, servletConfig, IN_INTERCEPTORS_PARAM, splitChar); + } + + protected void setSchemasLocations(JAXRSServerFactoryBean bean, ServletConfig servletConfig) { + + String schemas = servletConfig.getInitParameter(SCHEMAS_PARAM); + if (schemas != null) { + String[] locations = schemas.split(" "); + List list = new ArrayList(); + String[] locationsArray = locations; + int locationsLength = locations.length; + + for (int iterator = 0; iterator < locationsLength; ++iterator) { + String loc = locationsArray[iterator]; + String theLoc = loc.trim(); + if (!theLoc.isEmpty()) { + list.add(theLoc); + } + } + + if (!list.isEmpty()) { + bean.setSchemaLocations(list); + } + } + } + + protected void setDocLocation(JAXRSServerFactoryBean bean, ServletConfig servletConfig) { + + String wadlLoc = servletConfig.getInitParameter(DOC_LOCATION_PARAM); + if (wadlLoc != null) { + bean.setDocLocation(wadlLoc); + } + } + + protected void setInterceptors(JAXRSServerFactoryBean bean, ServletConfig servletConfig, String paramName, + String splitChar) throws ServletException { + + String value = servletConfig.getInitParameter(paramName); + if (value != null) { + String[] values = value.split(splitChar); + List> list = new ArrayList(); + String[] valuesArray = values; + int valuesLength = values.length; + + for (int iterator = 0; iterator < valuesLength; ++iterator) { + String interceptorVal = valuesArray[iterator]; + Map> props = new HashMap(); + String theValue = this.getClassNameAndProperties(interceptorVal, props); + if (!theValue.isEmpty()) { + try { + Class intClass = this.loadClass(theValue, "Interceptor"); + Object object = intClass.getDeclaredConstructor().newInstance(); + this.injectProperties(object, props); + list.add((Interceptor) object); + } catch (ServletException exception) { + throw exception; + } catch (Exception exception) { + LOG.warning("Interceptor class " + theValue + " can not be created"); + throw new ServletException(exception); + } + } + } + + if (!list.isEmpty()) { + if ("jaxrs.outInterceptors".equals(paramName)) { + bean.setOutInterceptors(list); + } else if ("jaxrs.outFaultInterceptors".equals(paramName)) { + bean.setOutFaultInterceptors(list); + } else { + bean.setInInterceptors(list); + } + } + } + } + + protected void setInvoker(JAXRSServerFactoryBean bean, ServletConfig servletConfig) throws ServletException { + + String value = servletConfig.getInitParameter(INVOKER_PARAM); + if (value != null) { + Map> props = new HashMap(); + String theValue = this.getClassNameAndProperties(value, props); + if (!theValue.isEmpty()) { + try { + Class intClass = this.loadClass(theValue, "Invoker"); + Object object = intClass.getDeclaredConstructor().newInstance(); + this.injectProperties(object, props); + bean.setInvoker((Invoker) object); + } catch (ServletException exception) { + throw exception; + } catch (Exception exception) { + LOG.warning("Invoker class " + theValue + " can not be created"); + throw new ServletException(exception); + } + } + } + } + + protected Map, Map>> getServiceClasses(ServletConfig servletConfig, + boolean modelAvailable, String splitChar) + throws ServletException { + + String serviceBeans = servletConfig.getInitParameter(SERVICE_CLASSES_PARAM); + if (serviceBeans == null) { + if (modelAvailable) { + return Collections.emptyMap(); + } else { + throw new ServletException("At least one resource class should be specified"); + } + } else { + String[] classNames = serviceBeans.split(splitChar); + Map, Map>> map = new HashMap(); + String[] classNamesArray = classNames; + int classNamesLength = classNames.length; + + for (int iterator = 0; iterator < classNamesLength; ++iterator) { + String cName = classNamesArray[iterator]; + Map> props = new HashMap(); + String theName = this.getClassNameAndProperties(cName, props); + if (!theName.isEmpty()) { + Class cls = this.loadClass(theName); + map.put(cls, props); + } + } + + if (map.isEmpty()) { + throw new ServletException("At least one resource class should be specified"); + } else { + return map; + } + } + } + + protected List getFeatures(ServletConfig servletConfig, String splitChar) + throws ServletException { + + String featuresList = servletConfig.getInitParameter(FEATURES_PARAM); + if (featuresList == null) { + return Collections.emptyList(); + } else { + String[] classNames = featuresList.split(splitChar); + List features = new ArrayList(); + String[] classNamesArray = classNames; + int classNamesLength = classNames.length; + + for (int iterator = 0; iterator < classNamesLength; ++iterator) { + String cName = classNamesArray[iterator]; + Map> props = new HashMap(); + String theName = this.getClassNameAndProperties(cName, props); + if (!theName.isEmpty()) { + Class cls = this.loadClass(theName); + if (Feature.class.isAssignableFrom(cls)) { + features.add((Feature) this.createSingletonInstance(cls, props, servletConfig)); + } + } + } + return features; + } + } + + protected List getProviders(ServletConfig servletConfig, String splitChar) throws ServletException { + + String providersList = servletConfig.getInitParameter(PROVIDERS_PARAM); + if (providersList == null) { + return Collections.emptyList(); + } else { + String[] classNames = providersList.split(splitChar); + List providers = new ArrayList(); + String[] classNamesArray = classNames; + int classNamesLength = classNames.length; + + for (int iterator = 0; iterator < classNamesLength; ++iterator) { + String cName = classNamesArray[iterator]; + Map> props = new HashMap(); + String theName = this.getClassNameAndProperties(cName, props); + if (!theName.isEmpty()) { + Class cls = this.loadClass(theName); + providers.add(this.createSingletonInstance(cls, props, servletConfig)); + } + } + return providers; + } + } + + private String getClassNameAndProperties(String cName, Map> props) { + + String theName = cName.trim(); + int ind = theName.indexOf(40); + if (ind != -1 && theName.endsWith(")")) { + props.putAll(parseMapListSequence(theName.substring(ind + 1, theName.length() - 1))); + theName = theName.substring(0, ind).trim(); + } + + return theName; + } + + protected static Map> parseMapListSequence(String sequence) { + + if (sequence != null) { + sequence = sequence.trim(); + Map> map = new HashMap(); + String[] pairs = sequence.split(" "); + String[] pairsArray = pairs; + int pairsLength = pairs.length; + + for (int iterator = 0; iterator < pairsLength; ++iterator) { + String pair = pairsArray[iterator]; + String thePair = pair.trim(); + if (thePair.length() != 0) { + String[] values = thePair.split("="); + String key; + String value; + if (values.length == 2) { + key = values[0].trim(); + value = values[1].trim(); + } else { + key = thePair; + value = ""; + } + + List list = (List) map.get(key); + if (list == null) { + list = new LinkedList(); + map.put(key, list); + } + ((List) list).add(value); + } + } + return map; + } else { + return Collections.emptyMap(); + } + } + + protected Map, ResourceProvider> getResourceProviders(ServletConfig servletConfig, Map, + Map>> resourceClasses) throws ServletException { + + String scope = servletConfig.getInitParameter(SERVICE_SCOPE_PARAM); + if (scope != null && !SERVICE_SCOPE_SINGLETON.equals(scope) && !SERVICE_SCOPE_REQUEST.equals(scope)) { + throw new ServletException("Only singleton and prototype scopes are supported"); + } else { + boolean isPrototype = SERVICE_SCOPE_REQUEST.equals(scope); + Map, ResourceProvider> map = new HashMap(); + Iterator iterator = resourceClasses.entrySet().iterator(); + + while (iterator.hasNext()) { + Map.Entry, Map>> entry = (Map.Entry) iterator.next(); + Class entryKey = (Class) entry.getKey(); + map.put(entryKey, isPrototype ? new PerRequestResourceProvider(entryKey) : + new SingletonResourceProvider(this.createSingletonInstance(entryKey, (Map) entry.getValue(), + servletConfig), true)); + } + return map; + } + } + + protected boolean isAppResourceLifecycleASingleton(Application app, ServletConfig servletConfig) { + + String scope = servletConfig.getInitParameter(SERVICE_SCOPE_PARAM); + if (scope == null) { + scope = (String) app.getProperties().get(SERVICE_SCOPE_PARAM); + } + return SERVICE_SCOPE_SINGLETON.equals(scope); + } + + protected Object createSingletonInstance(Class cls, Map> props, ServletConfig sc) + throws ServletException { + + Constructor resourceConstructor = ResourceUtils.findResourceConstructor(cls, false); + if (resourceConstructor == null) { + throw new ServletException("No valid constructor found for " + cls.getName()); + } else { + boolean isApplication = Application.class.isAssignableFrom(resourceConstructor.getDeclaringClass()); + + try { + Object provider; + if (resourceConstructor.getParameterTypes().length == 0) { + if (isApplication) { + provider = new ApplicationInfo((Application) resourceConstructor.newInstance(), this.getBus()); + } else { + provider = new ProviderInfo(resourceConstructor.newInstance(), this.getBus(), + false, true); + } + } else { + Map, Object> values = new HashMap(); + values.put(ServletContext.class, sc.getServletContext()); + values.put(ServletConfig.class, sc); + provider = ProviderFactory.createProviderFromConstructor(resourceConstructor, values, + this.getBus(), isApplication, true); + } + + Object instance = ((ProviderInfo) provider).getProvider(); + this.injectProperties(instance, props); + this.configureSingleton(instance); + return isApplication ? provider : instance; + } catch (InstantiationException exception) { + throw new ServletException("Resource class " + cls.getName() + " can not be instantiated"); + } catch (IllegalAccessException exception) { + throw new ServletException("Resource class " + cls.getName() + " " + + "can not be instantiated due to IllegalAccessException"); + } catch (InvocationTargetException exception) { + throw new ServletException("Resource class " + cls.getName() + " " + + "can not be instantiated due to InvocationTargetException"); + } + } + } + + private void injectProperties(Object instance, Map> props) { + + if (props != null && !props.isEmpty()) { + Method[] methods = instance.getClass().getMethods(); + Map methodsMap = new HashMap(); + Method[] methodsArray = methods; + int methodsLength = methods.length; + + for (int iterator = 0; iterator < methodsLength; ++iterator) { + Method method = methodsArray[iterator]; + methodsMap.put(method.getName(), method); + } + + Iterator iterator = props.entrySet().iterator(); + + while (iterator.hasNext()) { + Map.Entry> entry = (Map.Entry) iterator.next(); + Method method = (Method) methodsMap.get("set" + StringUtils.capitalize((String) entry.getKey())); + if (method != null) { + Class type = method.getParameterTypes()[0]; + Object value; + if (InjectionUtils.isPrimitive(type)) { + value = PrimitiveUtils.read((String) ((List) entry.getValue()).get(0), type); + } else { + value = entry.getValue(); + } + InjectionUtils.injectThroughMethod(instance, method, value); + } + } + } + } + + protected void configureSingleton(Object instance) { + + } + + protected void createServerFromApplication(String applicationNames, ServletConfig servletConfig) + throws ServletException { + + boolean ignoreApplicationPath = this.isIgnoreApplicationPath(servletConfig); + String[] classNames = applicationNames.split(this.getParameterSplitChar(servletConfig)); + if (classNames.length > 1 && ignoreApplicationPath) { + throw new ServletException("\"jaxrs.application.address.ignore\" parameter must be set to false for " + + "multiple Applications be supported"); + } else { + String[] classNamesArray = classNames; + int classNamesLength = classNames.length; + + for (int iterator = 0; iterator < classNamesLength; ++iterator) { + String cName = classNamesArray[iterator]; + ApplicationInfo providerApp = this.createApplicationInfo(cName, servletConfig); + Application app = (Application) providerApp.getProvider(); + JAXRSServerFactoryBean bean = ResourceUtils.createApplication(app, ignoreApplicationPath, + this.getStaticSubResolutionValue(servletConfig), this.isAppResourceLifecycleASingleton(app, + servletConfig), this.getBus()); + String splitChar = this.getParameterSplitChar(servletConfig); + this.setAllInterceptors(bean, servletConfig, splitChar); + this.setInvoker(bean, servletConfig); + this.setExtensions(bean, servletConfig); + this.setDocLocation(bean, servletConfig); + this.setSchemasLocations(bean, servletConfig); + List providers = this.getProviders(servletConfig, splitChar); + bean.setProviders(providers); + List features = this.getFeatures(servletConfig, splitChar); + bean.getFeatures().addAll(features); + bean.setBus(this.getBus()); + bean.setApplicationInfo(providerApp); + bean.create(); + } + } + } + + protected boolean isIgnoreApplicationPath(ServletConfig servletConfig) { + + String ignoreParam = servletConfig.getInitParameter(IGNORE_APP_PATH_PARAM); + return ignoreParam == null || PropertyUtils.isTrue(ignoreParam); + } + + protected void createServerFromApplication(ServletConfig servletConfig) throws ServletException { + + Application app = this.getApplication(); + JAXRSServerFactoryBean bean = ResourceUtils.createApplication(app, this.isIgnoreApplicationPath(servletConfig), + this.getStaticSubResolutionValue(servletConfig), + this.isAppResourceLifecycleASingleton(app, servletConfig), this.getBus()); + String splitChar = this.getParameterSplitChar(servletConfig); + this.setAllInterceptors(bean, servletConfig, splitChar); + this.setInvoker(bean, servletConfig); + this.setExtensions(bean, servletConfig); + this.setDocLocation(bean, servletConfig); + this.setSchemasLocations(bean, servletConfig); + List providers = this.getProviders(servletConfig, splitChar); + bean.setProviders(providers); + List features = this.getFeatures(servletConfig, splitChar); + bean.getFeatures().addAll(features); + bean.setBus(this.getBus()); + bean.setApplication(this.getApplication()); + bean.create(); + } + + protected Application createApplicationInstance(String appClassName, ServletConfig servletConfig) + throws ServletException { + + return null; + } + + protected ApplicationInfo createApplicationInfo(String appClassName, ServletConfig servletConfig) + throws ServletException { + + Application customApp = this.createApplicationInstance(appClassName, servletConfig); + if (customApp != null) { + return new ApplicationInfo(customApp, this.getBus()); + } else { + Map> props = new HashMap(); + appClassName = this.getClassNameAndProperties(appClassName, props); + Class appClass = this.loadApplicationClass(appClassName); + ApplicationInfo appInfo = (ApplicationInfo) this.createSingletonInstance(appClass, props, servletConfig); + Map servletProps = new HashMap(); + ServletContext servletContext = servletConfig.getServletContext(); + Enumeration names = servletContext.getInitParameterNames(); + + String name; + while (names.hasMoreElements()) { + name = (String) names.nextElement(); + servletProps.put(name, servletContext.getInitParameter(name)); + } + + names = servletConfig.getInitParameterNames(); + + while (names.hasMoreElements()) { + name = (String) names.nextElement(); + servletProps.put(name, servletConfig.getInitParameter(name)); + } + + appInfo.setOverridingProps(servletProps); + return appInfo; + } + } + + protected Class loadApplicationClass(String appClassName) throws ServletException { + + return this.loadClass(appClassName, "Application"); + } + + protected Class loadClass(String cName) throws ServletException { + + return this.loadClass(cName, "Resource"); + } + + protected Class loadClass(String cName, String classType) throws ServletException { + + try { + Class aClass; + if (this.classLoader == null) { + aClass = ClassLoaderUtils.loadClass(cName, org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrsServlet.class); + } else { + aClass = this.classLoader.loadClass(cName); + } + + return aClass; + } catch (ClassNotFoundException exception) { + throw new ServletException("No " + classType + " class " + cName.trim() + " can be found", exception); + } + } + + public void setClassLoader(ClassLoader loader) { + + this.classLoader = loader; + } + + protected Application getApplication() { - private Set applicationSingletons; - - ApplicationImpl(Set applicationSingletons) { - this.applicationSingletons = applicationSingletons; - } - - public Set getSingletons() { - return this.applicationSingletons; - } - } + return this.application; + } + + private static class ApplicationImpl extends Application { + + private Set applicationSingletons; + + ApplicationImpl(Set applicationSingletons) { + + this.applicationSingletons = applicationSingletons; + } + + public Set getSingletons() { + + return this.applicationSingletons; + } + } } From fc7c8915cfbc59e1e07aadb70f49c5e9dff593a6 Mon Sep 17 00:00:00 2001 From: lashini Date: Tue, 21 Jan 2025 09:13:37 +0530 Subject: [PATCH 5/5] Bump version --- components/servlet-mgt/pom.xml | 2 +- features/servlet-mgt/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/components/servlet-mgt/pom.xml b/components/servlet-mgt/pom.xml index 862e69bc9c31..e65f44784b39 100644 --- a/components/servlet-mgt/pom.xml +++ b/components/servlet-mgt/pom.xml @@ -6,7 +6,7 @@ org.wso2.carbon.identity.framework identity-framework - 7.7.88-SNAPSHOT + 7.7.107-SNAPSHOT ../../pom.xml diff --git a/features/servlet-mgt/pom.xml b/features/servlet-mgt/pom.xml index bdbf25cf9aa2..c62da2e0327e 100644 --- a/features/servlet-mgt/pom.xml +++ b/features/servlet-mgt/pom.xml @@ -21,7 +21,7 @@ org.wso2.carbon.identity.framework identity-framework - 7.7.88-SNAPSHOT + 7.7.107-SNAPSHOT ../../pom.xml