001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */
019: package org.apache.axis2.scripting;
020:
021: import java.io.File;
022: import java.io.IOException;
023: import java.io.InputStream;
024: import java.io.InputStreamReader;
025: import java.io.Reader;
026: import java.util.ArrayList;
027: import java.util.Iterator;
028: import java.util.List;
029:
030: import org.apache.axis2.AxisFault;
031: import org.apache.axis2.deployment.DeploymentEngine;
032: import org.apache.axis2.deployment.DeploymentErrorMsgs;
033: import org.apache.axis2.deployment.DeploymentException;
034: import org.apache.axis2.deployment.repository.util.DeploymentFileData;
035: import org.apache.axis2.deployment.repository.util.WSInfo;
036: import org.apache.axis2.description.AxisOperation;
037: import org.apache.axis2.description.AxisService;
038: import org.apache.axis2.description.AxisServiceGroup;
039: import org.apache.axis2.description.Parameter;
040: import org.apache.axis2.description.WSDL11ToAxisServiceBuilder;
041: import org.apache.axis2.description.WSDLToAxisServiceBuilder;
042: import org.apache.axis2.engine.AxisConfiguration;
043: import org.apache.axis2.i18n.Messages;
044: import org.apache.commons.logging.Log;
045: import org.apache.commons.logging.LogFactory;
046:
047: /**
048: * An Axis2 DeploymentEngine subclass for deploying script services
049: * supporting hot deploy and hot update.
050: */
051: public class ScriptDeploymentEngine extends DeploymentEngine {
052:
053: private static final Log log = LogFactory
054: .getLog(ScriptModule.class);
055:
056: public static final String SCRIPT_HOT_UPDATE_ = "scripts.hotupdate";
057:
058: private AxisConfiguration realAxisConfig;
059:
060: public ScriptDeploymentEngine(AxisConfiguration realAxisConfig) {
061: this .axisConfig = new AxisConfiguration();
062: this .realAxisConfig = realAxisConfig;
063: }
064:
065: public void loadRepository(File scriptsRepoFile)
066: throws DeploymentException {
067: this .repoListener = new ScriptRepositoryListener(this );
068: this .servicesDir = scriptsRepoFile;
069:
070: Parameter scriptsHotUpdateParameter = axisConfig
071: .getParameter(SCRIPT_HOT_UPDATE_);
072: this .hotUpdate = scriptsHotUpdateParameter == null
073: || "true".equals(scriptsHotUpdateParameter.getValue());
074: }
075:
076: public void doDeploy() {
077: List alreadyDeployed = new ArrayList();
078: for (int i = 0; i < wsToDeploy.size(); i++) {
079: try {
080:
081: DeploymentFileData archiveFileData = (DeploymentFileData) wsToDeploy
082: .get(i);
083: deployService(alreadyDeployed, archiveFileData);
084:
085: } catch (Exception e) {
086: e.printStackTrace();
087: log.warn("Exception deploying script service: "
088: + ((DeploymentFileData) wsToDeploy.get(i))
089: .getName());
090: }
091: }
092: wsToDeploy.clear();
093: }
094:
095: private void deployService(List alreadyDeployed,
096: DeploymentFileData archiveFileData) throws AxisFault {
097: File file = archiveFileData.getFile();
098:
099: File wsdlFile;
100: File scriptFile;
101: if (file.toString().endsWith(".wsdl")) {
102: wsdlFile = file;
103: scriptFile = getScriptForWSDL(wsdlFile);
104: } else {
105: scriptFile = file;
106: wsdlFile = getWSDLForScript(scriptFile);
107: }
108:
109: if (scriptFile != null && wsdlFile != null
110: && !alreadyDeployed.contains(scriptFile.toURI())
111: && scriptFile.exists() && wsdlFile.exists()) {
112: AxisService axisService = createService(wsdlFile,
113: scriptFile);
114: AxisServiceGroup axisServiceGroup = new AxisServiceGroup(
115: axisConfig);
116: axisServiceGroup.setServiceGroupClassLoader(axisService
117: .getClassLoader());
118: axisServiceGroup.setServiceGroupName(axisService.getName());
119: axisServiceGroup.addService(axisService);
120: realAxisConfig.addServiceGroup(axisServiceGroup);
121: alreadyDeployed.add(scriptFile.toURI());
122: log.info("Deployed script service '"
123: + axisService.getName() + "' for script: "
124: + scriptFile.getName());
125: }
126: }
127:
128: public void unDeploy() {
129: String serviceName = null;
130: List undeployed = new ArrayList();
131: for (int i = 0; i < wsToUnDeploy.size(); i++) {
132: try {
133: WSInfo wsInfo = (WSInfo) wsToUnDeploy.get(i);
134: // if (wsInfo.getType() == TYPE_SERVICE) {
135: if (isHotUpdate()) {
136: try {
137: serviceName = getAxisServiceName(wsInfo
138: .getFileName());
139: if (!undeployed.contains(serviceName)) {
140: realAxisConfig
141: .removeServiceGroup(serviceName);
142: undeployed.add(serviceName);
143: // TODO: need a way to also remove the ServiceGroup from the ConfigContext.applicationSessionServiceGroupContextTable
144: log
145: .info(Messages
146: .getMessage(
147: DeploymentErrorMsgs.SERVICE_REMOVED,
148: serviceName));
149: }
150: } catch (AxisFault axisFault) {
151: // May be a faulty service
152: realAxisConfig.removeFaultyService(serviceName);
153: log.debug("removeFaultyService: "
154: + wsInfo.getFileName());
155: }
156: } else {
157: realAxisConfig.removeFaultyService(serviceName);
158: log.debug("not hotUpdate, removeFaultyService: "
159: + wsInfo.getFileName());
160: }
161: // }
162: } catch (Exception e) {
163: log.warn(e);
164: }
165: }
166: wsToUnDeploy.clear();
167: }
168:
169: /*
170: * Override the DeploymentEngine method return an empty modules directory as
171: * its not required for script services
172: */
173: public File getModulesDir() {
174: return new File("");
175: }
176:
177: /**
178: * Gets the script associated with the wsdl. The associated script is the
179: * file with the same name as the wsdl file excluding the file suffix, for
180: * example, stockquote.js and stockquote.wsdl.
181: */
182: protected File getScriptForWSDL(File wsdlFile) {
183: String wsdlFileName = wsdlFile.getName();
184: String fileSuffix = wsdlFileName.substring(0, wsdlFileName
185: .lastIndexOf('.'));
186: File wsdlFileDir = wsdlFile.getParentFile();
187: String[] files = wsdlFileDir.list();
188: for (int i = 0; i < files.length; i++) {
189: if (!files[i].equals(wsdlFileName)
190: && files[i].startsWith(fileSuffix)) {
191: File scriptFile = new File(wsdlFileDir, files[i]);
192: return scriptFile;
193: }
194: }
195: return null;
196: }
197:
198: /**
199: * Gets the WSDL associated with the script. The associated WSDL is the file
200: * with the same name as the script file excluding the file suffix, for
201: * example, stockquote.js and stockquote.wsdl.
202: */
203: protected File getWSDLForScript(File scriptFile) {
204: String scriptFileName = scriptFile.getName();
205: String fileSuffix = scriptFileName.substring(0, scriptFileName
206: .lastIndexOf('.'));
207: File scriptFileDir = scriptFile.getParentFile();
208: File wsdlFile = new File(scriptFileDir, fileSuffix + ".wsdl");
209: return wsdlFile;
210: }
211:
212: /**
213: * Creates an Axis2 service for the script
214: */
215: protected AxisService createService(File wsdlFile, File scriptFile) {
216: AxisService axisService = null;
217: try {
218:
219: InputStream definition;
220: try {
221: definition = wsdlFile.toURL().openStream();
222: } catch (Exception e) {
223: throw new AxisFault("exception opening wsdl", e);
224: }
225:
226: WSDLToAxisServiceBuilder builder = new WSDL11ToAxisServiceBuilder(
227: definition);
228: builder.setServerSide(true);
229: axisService = builder.populateService();
230:
231: //axisService.setScope(Constants.SCOPE_APPLICATION);
232: Parameter userWSDL = new Parameter("useOriginalwsdl",
233: "true");
234: axisService.addParameter(userWSDL);
235:
236: Parameter scriptSrc = new Parameter(
237: ScriptReceiver.SCRIPT_SRC_PROP,
238: readScriptSource(scriptFile));
239: axisService.addParameter(scriptSrc);
240:
241: ScriptReceiver scriptReceiver = new ScriptReceiver();
242: axisService.addMessageReceiver(
243: "http://www.w3.org/2004/08/wsdl/in-out",
244: scriptReceiver);
245:
246: // TODO: Shouldn't this be done by WSDLToAxisServiceBuilder.populateService?
247: for (Iterator it = axisService.getOperations(); it
248: .hasNext();) {
249: AxisOperation operation = (AxisOperation) it.next();
250: operation.setMessageReceiver(scriptReceiver);
251: }
252:
253: Parameter scriptParam = new Parameter(
254: ScriptReceiver.SCRIPT_ATTR, scriptFile.toString());
255: axisService.addParameter(scriptParam);
256:
257: axisService.setName(scriptFile.getName().substring(0,
258: scriptFile.getName().lastIndexOf('.')));
259:
260: } catch (Throwable e) {
261: log.warn("AxisFault creating script service", e);
262: e.printStackTrace();
263: }
264:
265: return axisService;
266: }
267:
268: /**
269: * Reads the complete script source code into a String
270: */
271: protected String readScriptSource(File scriptFile) throws AxisFault {
272: InputStream is;
273: try {
274: is = scriptFile.toURL().openStream();
275: } catch (IOException e) {
276: throw new AxisFault("IOException opening script: "
277: + scriptFile, e);
278: }
279: try {
280: Reader reader = new InputStreamReader(is, "UTF-8");
281: char[] buffer = new char[1024];
282: StringBuffer source = new StringBuffer();
283: int count;
284: while ((count = reader.read(buffer)) > 0) {
285: source.append(buffer, 0, count);
286: }
287: return source.toString();
288: } catch (IOException e) {
289: throw new AxisFault("IOException reading script: "
290: + scriptFile, e);
291: } finally {
292: try {
293: is.close();
294: } catch (IOException e) {
295: throw new AxisFault("IOException closing script: "
296: + scriptFile, e);
297: }
298: }
299: }
300:
301: }
|