/jboss-as-7.1.1.Final/webservices/server-integration/src/main/java/org/jboss/as/webservices/publish/EndpointPublisherImpl.java
Java | 270 lines | 212 code | 24 blank | 34 comment | 18 complexity | 15a003bbeee1917a56b62052fd3bffab MD5 | raw file
Possible License(s): LGPL-2.1, Apache-2.0
1/*
2 * JBoss, Home of Professional Open Source.
3 * Copyright 2011, Red Hat, Inc., and individual contributors
4 * as indicated by the @author tags. See the copyright.txt file in the
5 * distribution for a full listing of individual contributors.
6 *
7 * This is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This software is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this software; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 */
22package org.jboss.as.webservices.publish;
23
24import static org.jboss.as.webservices.WSMessages.MESSAGES;
25
26import java.io.File;
27import java.lang.reflect.InvocationTargetException;
28import java.util.List;
29import java.util.Map;
30
31import javax.naming.NamingException;
32
33import org.apache.catalina.Container;
34import org.apache.catalina.Host;
35import org.apache.catalina.LifecycleException;
36import org.apache.catalina.Loader;
37import org.apache.catalina.Wrapper;
38import org.apache.catalina.core.StandardContext;
39import org.apache.catalina.startup.ContextConfig;
40import org.apache.tomcat.InstanceManager;
41import org.jboss.as.web.deployment.WebCtxLoader;
42import org.jboss.as.webservices.deployers.deployment.DeploymentAspectsProvider;
43import org.jboss.as.webservices.deployers.deployment.WSDeploymentBuilder;
44import org.jboss.as.webservices.service.ServerConfigService;
45import org.jboss.as.webservices.util.WSAttachmentKeys;
46import org.jboss.as.webservices.util.WSServices;
47import org.jboss.metadata.javaee.spec.ParamValueMetaData;
48import org.jboss.metadata.web.jboss.JBossServletMetaData;
49import org.jboss.metadata.web.jboss.JBossWebMetaData;
50import org.jboss.metadata.web.spec.ServletMappingMetaData;
51import org.jboss.msc.service.ServiceTarget;
52import org.jboss.ws.common.deployment.DeploymentAspectManagerImpl;
53import org.jboss.wsf.spi.SPIProvider;
54import org.jboss.wsf.spi.SPIProviderResolver;
55import org.jboss.wsf.spi.classloading.ClassLoaderProvider;
56import org.jboss.wsf.spi.deployment.Deployment;
57import org.jboss.wsf.spi.deployment.DeploymentAspect;
58import org.jboss.wsf.spi.deployment.DeploymentAspectManager;
59import org.jboss.wsf.spi.deployment.Endpoint;
60import org.jboss.wsf.spi.deployment.WSFServlet;
61import org.jboss.wsf.spi.management.EndpointRegistry;
62import org.jboss.wsf.spi.management.EndpointRegistryFactory;
63import org.jboss.wsf.spi.metadata.webservices.WebservicesMetaData;
64import org.jboss.wsf.spi.publish.Context;
65import org.jboss.wsf.spi.publish.EndpointPublisher;
66
67/**
68 * WS endpoint publisher, allows for publishing a WS endpoint on AS 7
69 *
70 * @author alessio.soldano@jboss.com
71 * @since 12-Jul-2011
72 */
73public final class EndpointPublisherImpl implements EndpointPublisher {
74
75 private Host host;
76
77 public EndpointPublisherImpl(Host host) {
78 this.host = host;
79 }
80
81 @Override
82 public Context publish(String context, ClassLoader loader, Map<String, String> urlPatternToClassNameMap) throws Exception {
83 return publish(null, context, loader, urlPatternToClassNameMap, null);
84 }
85
86 public Context publish(String context, ClassLoader loader, Map<String, String> urlPatternToClassNameMap, WebservicesMetaData metadata) throws Exception {
87 return publish(null, context, loader, urlPatternToClassNameMap, metadata);
88 }
89
90 public Context publish(ServiceTarget target, String context, ClassLoader loader, Map<String, String> urlPatternToClassNameMap, WebservicesMetaData metadata) throws Exception {
91 WSEndpointDeploymentUnit unit = new WSEndpointDeploymentUnit(loader, context, urlPatternToClassNameMap, metadata);
92 return new Context(context, publish(target, unit));
93 }
94
95 /**
96 * Publishes the endpoints declared to the provided WSEndpointDeploymentUnit
97 */
98 public List<Endpoint> publish(ServiceTarget target, WSEndpointDeploymentUnit unit) throws Exception {
99 List<DeploymentAspect> aspects = DeploymentAspectsProvider.getSortedDeploymentAspects();
100 ClassLoader origClassLoader = SecurityActions.getContextClassLoader();
101 Deployment dep = null;
102 try {
103 SecurityActions.setContextClassLoader(ClassLoaderProvider.getDefaultProvider().getServerIntegrationClassLoader());
104 WSDeploymentBuilder.getInstance().build(unit);
105 dep = unit.getAttachment(WSAttachmentKeys.DEPLOYMENT_KEY);
106 dep.addAttachment(ServiceTarget.class, target);
107 DeploymentAspectManager dam = new DeploymentAspectManagerImpl();
108 dam.setDeploymentAspects(aspects);
109 dam.deploy(dep);
110 // TODO: [JBWS-3426] fix this. START workaround
111 if (target == null) {
112 SPIProvider spiProvider = SPIProviderResolver.getInstance().getProvider();
113 EndpointRegistryFactory factory = spiProvider.getSPI(EndpointRegistryFactory.class);
114 EndpointRegistry registry = factory.getEndpointRegistry();
115 for (final Endpoint endpoint : dep.getService().getEndpoints()) {
116 registry.register(endpoint);
117 }
118 }
119 // END workaround
120 } finally {
121 if (dep != null) {
122 dep.removeAttachment(ServiceTarget.class);
123 }
124 SecurityActions.setContextClassLoader(origClassLoader);
125 }
126 Deployment deployment = unit.getAttachment(WSAttachmentKeys.DEPLOYMENT_KEY);
127 deployment.addAttachment(StandardContext.class, startWebApp(host, unit)); //TODO simplify and use findChild later in destroy()/stopWebApp()
128 return deployment.getService().getEndpoints();
129 }
130
131 private static StandardContext startWebApp(Host host, WSEndpointDeploymentUnit unit) throws Exception {
132 StandardContext context = new StandardContext();
133 try {
134 JBossWebMetaData jbwebMD = unit.getAttachment(WSAttachmentKeys.JBOSSWEB_METADATA_KEY);
135 context.setPath(jbwebMD.getContextRoot());
136 context.addLifecycleListener(new ContextConfig());
137 ServerConfigService config = (ServerConfigService)unit.getServiceRegistry().getService(WSServices.CONFIG_SERVICE).getService();
138 File docBase = new File(config.getValue().getServerTempDir(), jbwebMD.getContextRoot());
139 if (!docBase.exists()) {
140 docBase.mkdirs();
141 }
142 context.setDocBase(docBase.getPath());
143
144 final Loader loader = new WebCtxLoader(unit.getAttachment(WSAttachmentKeys.CLASSLOADER_KEY));
145 loader.setContainer(host);
146 context.setLoader(loader);
147 context.setInstanceManager(new LocalInstanceManager());
148
149 addServlets(jbwebMD, context);
150
151 host.addChild(context);
152 context.create();
153 } catch (Exception e) {
154 throw MESSAGES.createContextPhaseFailed(e);
155 }
156 try {
157 context.start();
158 } catch (LifecycleException e) {
159 throw MESSAGES.startContextPhaseFailed(e);
160 }
161 return context;
162 }
163
164 private static void addServlets(JBossWebMetaData jbwebMD, StandardContext context) {
165 for (JBossServletMetaData smd : jbwebMD.getServlets()) {
166 final String sc = smd.getServletClass();
167 if (sc.equals(WSFServlet.class.getName())) {
168 final String servletName = smd.getServletName();
169 List<ParamValueMetaData> params = smd.getInitParam();
170 List<String> urlPatterns = null;
171 for (ServletMappingMetaData smmd : jbwebMD.getServletMappings()) {
172 if (smmd.getServletName().equals(servletName)) {
173 urlPatterns = smmd.getUrlPatterns();
174 break;
175 }
176 }
177
178 WSFServlet wsfs = new WSFServlet();
179 Wrapper wsfsWrapper = context.createWrapper();
180 wsfsWrapper.setName(servletName);
181 wsfsWrapper.setServlet(wsfs);
182 wsfsWrapper.setServletClass(WSFServlet.class.getName());
183 for (ParamValueMetaData param : params) {
184 wsfsWrapper.addInitParameter(param.getParamName(), param.getParamValue());
185 }
186 context.addChild(wsfsWrapper);
187 for (String urlPattern : urlPatterns) {
188 context.addServletMapping(urlPattern, servletName);
189 }
190 }
191 }
192 }
193
194 @Override
195 public void destroy(Context context) throws Exception {
196 List<Endpoint> eps = context.getEndpoints();
197 if (eps == null || eps.isEmpty()) {
198 return;
199 }
200 Deployment deployment = eps.get(0).getService().getDeployment();
201 List<DeploymentAspect> aspects = DeploymentAspectsProvider.getSortedDeploymentAspects();
202 try {
203 stopWebApp(deployment.getAttachment(StandardContext.class));
204 } finally {
205 ClassLoader origClassLoader = SecurityActions.getContextClassLoader();
206 try {
207 SecurityActions.setContextClassLoader(ClassLoaderProvider.getDefaultProvider().getServerIntegrationClassLoader());
208 final ServiceTarget target = deployment.getAttachment(ServiceTarget.class);
209 // TODO: [JBWS-3426] fix this. START workaround
210 if (target == null) {
211 SPIProvider spiProvider = SPIProviderResolver.getInstance().getProvider();
212 EndpointRegistryFactory factory = spiProvider.getSPI(EndpointRegistryFactory.class);
213 EndpointRegistry registry = factory.getEndpointRegistry();
214 for (final Endpoint endpoint : deployment.getService().getEndpoints()) {
215 registry.unregister(endpoint);
216 }
217 }
218 // END workaround
219 DeploymentAspectManager dam = new DeploymentAspectManagerImpl();
220 dam.setDeploymentAspects(aspects);
221 dam.undeploy(deployment);
222 } finally {
223 SecurityActions.setContextClassLoader(origClassLoader);
224 }
225 }
226 }
227
228 private static void stopWebApp(StandardContext context) throws Exception {
229 try {
230 Container container = context.getParent();
231 container.removeChild(context);
232 context.stop();
233 } catch (LifecycleException e) {
234 throw MESSAGES.stopContextPhaseFailed(e);
235 }
236 try {
237 context.destroy();
238 } catch (Exception e) {
239 throw MESSAGES.destroyContextPhaseFailed(e);
240 }
241 }
242
243 private static class LocalInstanceManager implements InstanceManager {
244 LocalInstanceManager() {
245 }
246 @Override
247 public Object newInstance(String className) throws IllegalAccessException, InvocationTargetException, NamingException, InstantiationException, ClassNotFoundException {
248 return Class.forName(className).newInstance();
249 }
250
251 @Override
252 public Object newInstance(String fqcn, ClassLoader classLoader) throws IllegalAccessException, InvocationTargetException, NamingException, InstantiationException, ClassNotFoundException {
253 return Class.forName(fqcn, false, classLoader).newInstance();
254 }
255
256 @Override
257 public Object newInstance(Class<?> c) throws IllegalAccessException, InvocationTargetException, NamingException, InstantiationException {
258 return c.newInstance();
259 }
260
261 @Override
262 public void newInstance(Object o) throws IllegalAccessException, InvocationTargetException, NamingException {
263 throw new IllegalStateException();
264 }
265
266 @Override
267 public void destroyInstance(Object o) throws IllegalAccessException, InvocationTargetException {
268 }
269 }
270}