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:
020: package org.wso2.esb;
021:
022: import org.apache.axis2.context.ConfigurationContext;
023: import org.apache.axis2.deployment.Deployer;
024: import org.apache.axis2.deployment.DeploymentClassLoader;
025: import org.apache.axis2.deployment.DeploymentException;
026: import org.apache.axis2.deployment.repository.util.DeploymentFileData;
027: import org.apache.commons.logging.Log;
028: import org.apache.commons.logging.LogFactory;
029: import org.apache.synapse.config.xml.MediatorFactory;
030: import org.apache.synapse.config.xml.MediatorFactoryFinder;
031: import org.apache.synapse.config.xml.MediatorSerializer;
032: import org.apache.synapse.config.xml.MediatorSerializerFinder;
033:
034: import java.io.*;
035: import java.net.URL;
036:
037: /**
038: * This will support the hot deployment and hot update of the mediators at runtime using the
039: * Axis2 concepts of deployers
040: */
041: public class MediatorDeployer implements Deployer {
042:
043: /**
044: * Holds the log variable for logging purposes
045: */
046: private static final Log log = LogFactory
047: .getLog(MediatorDeployer.class);
048:
049: /**
050: * ConfigurationContext of Axis2
051: */
052: private ConfigurationContext cfgCtx = null;
053:
054: /**
055: * Initializes the Deployer
056: *
057: * @param configurationContext - ConfigurationContext of Axis2 from which
058: * the deployer is initialized
059: */
060: public void init(ConfigurationContext configurationContext) {
061: this .cfgCtx = configurationContext;
062: }
063:
064: /**
065: * This will be called when there is a change in the specified deployement
066: * folder (in the axis2.xml) and this will load the relevant classe to the system and
067: * registeres them with the MediatorFactoryFinder
068: *
069: * @param deploymentFileData - describes the updated file
070: * @throws DeploymentException - in case an error on the deployment
071: */
072: public void deploy(DeploymentFileData deploymentFileData)
073: throws DeploymentException {
074:
075: log.info("Loading mediator from: "
076: + deploymentFileData.getAbsolutePath());
077:
078: // get the context class loader for the later restore of the context class loader
079: ClassLoader prevCl = Thread.currentThread()
080: .getContextClassLoader();
081:
082: try {
083:
084: DeploymentClassLoader urlCl = new DeploymentClassLoader(
085: new URL[] { deploymentFileData.getFile().toURL() },
086: null, prevCl);
087: Thread.currentThread().setContextClassLoader(urlCl);
088:
089: // MediatorFactory registration
090: URL facURL = urlCl
091: .findResource("META-INF/services/org.apache.synapse.config.xml.MediatorFactory");
092: if (facURL != null) {
093: InputStream facStream = facURL.openStream();
094: InputStreamReader facreader = new InputStreamReader(
095: facStream);
096:
097: StringBuffer facSB = new StringBuffer();
098: int c;
099: while ((c = facreader.read()) != -1) {
100: facSB.append((char) c);
101: }
102:
103: String[] facClassName = facSB.toString().split("\n");
104: for (int i = 0; i < facClassName.length; i++) {
105: log.info("Registering the Mediator factory: "
106: + facClassName[i]);
107: Class facClass = urlCl.loadClass(facClassName[i]);
108: MediatorFactory facInst = (MediatorFactory) facClass
109: .newInstance();
110: MediatorFactoryFinder.getInstance().getFactoryMap()
111: .put(facInst.getTagQName(), facClass);
112: log.info("Mediator loaded and registered for "
113: + "the tag name: " + facInst.getTagQName());
114: loadUIComponents(facInst.getTagQName()
115: .getLocalPart(), urlCl);
116: }
117: } else {
118: handleException("Unable to find the MediatorFactory implementation. "
119: + "Unable to register the MediatorFactory with the FactoryFinder");
120: }
121:
122: // MediatorSerializer registration
123: URL serURL = urlCl
124: .findResource("META-INF/services/org.apache.synapse.config.xml.MediatorSerializer");
125: if (serURL != null) {
126: InputStream serStream = serURL.openStream();
127: InputStreamReader serReader = new InputStreamReader(
128: serStream);
129:
130: StringBuffer serSB = new StringBuffer();
131: int c;
132: while ((c = serReader.read()) != -1) {
133: serSB.append((char) c);
134: }
135:
136: String[] serClassName = serSB.toString().split("\n");
137: for (int i = 0; i < serClassName.length; i++) {
138: log.info("Registering the Mediator serializer: "
139: + serClassName[i]);
140: Class serClass = urlCl.loadClass(serClassName[i]);
141: MediatorSerializer serInst = (MediatorSerializer) serClass
142: .newInstance();
143: MediatorSerializerFinder.getInstance()
144: .getSerializerMap().put(
145: serInst.getMediatorClassName(),
146: serInst);
147: log.info("Mediator loaded and registered for "
148: + "the serialization as: "
149: + serInst.getMediatorClassName());
150: }
151: } else {
152: handleException("Unable to find the MediatorSerializer implementation. "
153: + "Unable to register the MediatorSerializer with the SerializerFinder");
154:
155: }
156:
157: } catch (IOException e) {
158: handleException(
159: "I/O error in reading the mediator jar file", e);
160: } catch (ClassNotFoundException e) {
161: handleException(
162: "Unable to find the specified class on the path or in the jar file",
163: e);
164: } catch (IllegalAccessException e) {
165: handleException("Unable to load the class from the jar", e);
166: } catch (InstantiationException e) {
167: handleException(
168: "Unable to instantiate the class specified", e);
169: } finally {
170: // restore the class loader back
171: if (log.isDebugEnabled()) {
172: log
173: .debug("Restoring the context class loader to the original");
174: }
175: Thread.currentThread().setContextClassLoader(prevCl);
176: }
177: }
178:
179: private void loadUIComponents(String tagName,
180: DeploymentClassLoader clsL) {
181:
182: // finding the root directory for the UI stuff todo
183: String rootUIDir = "/home/ruwan/dev/esb/modules/distribution/target/wso2esb-SNAPSHOT/webapp/extensions/core/";
184:
185: // loading the view XSLT
186: loadFileFromJar("www/xslt/" + tagName + "_view.xsl", rootUIDir
187: + "xslt/mediators/" + tagName + "_view.xsl", clsL);
188:
189: // loading the edit XSLT
190: loadFileFromJar("www/xslt/" + tagName + "_edit.xsl", rootUIDir
191: + "xslt/mediators/" + tagName + "_edit.xsl", clsL);
192:
193: // loading the data collecting js
194: loadFileFromJar("www/js/" + tagName + "_mediator.js", rootUIDir
195: + "js/mediators/" + tagName + "_mediator.js", clsL);
196:
197: // appending the view XSL to the includes file
198: File includesXSL = new File(rootUIDir
199: + "xslt/mediators/custom_mediator_includes.xsl");
200: includesXSL.deleteOnExit();
201: try {
202: StringBuffer buff = new StringBuffer();
203: InputStreamReader srcReader = new InputStreamReader(
204: includesXSL.toURL().openStream());
205:
206: int c;
207: while ((c = srcReader.read()) != -1) {
208: buff.append((char) c);
209: }
210: String initInc = buff.toString();
211: if (!initInc.contains("<xsl:include href=" + tagName
212: + "_view.xsl />")) {
213: int breakPoint = initInc.indexOf("/>", initInc
214: .lastIndexOf("<xsl:include ")) + 2;
215: String modifiedInc = initInc.substring(0, breakPoint)
216: + "\n\t<xsl:include href=\"" + tagName
217: + "_view.xsl\" />"
218: + initInc.substring(breakPoint);
219: BufferedWriter out = new BufferedWriter(new FileWriter(
220: includesXSL));
221: out.write(modifiedInc);
222: out.flush();
223: out.close();
224: }
225: } catch (IOException e) {
226: e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
227: }
228:
229: // appending the data collecting js script file to the js.html
230: File jsHtml = new File(rootUIDir + "js.html");
231: try {
232: StringBuffer buff = new StringBuffer();
233: InputStreamReader srcReader = new InputStreamReader(jsHtml
234: .toURL().openStream());
235:
236: int c;
237: while ((c = srcReader.read()) != -1) {
238: buff.append((char) c);
239: }
240: if (!buff.toString().contains(
241: "<script language=\"javascript\" src=\"extensions/core/js/mediators/"
242: + tagName + "_mediator.js\"></script>")) {
243: BufferedWriter out = new BufferedWriter(new FileWriter(
244: jsHtml));
245: out
246: .write(buff.toString()
247: + "\n<script language=\"javascript\" src=\"extensions/core/js/mediators/"
248: + tagName + "_mediator.js\"></script>");
249: out.flush();
250: out.close();
251: }
252: } catch (IOException e) {
253: e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
254: }
255: }
256:
257: private void loadFileFromJar(String srcName, String dest,
258: DeploymentClassLoader clsL) {
259:
260: try {
261: URL srcURL = clsL.findResource(srcName);
262: File destFile = new File(dest);
263: if (!destFile.exists()) {
264: destFile.createNewFile();
265: }
266: StringBuffer buff = new StringBuffer();
267: InputStreamReader srcReader = new InputStreamReader(srcURL
268: .openStream());
269: int c;
270: while ((c = srcReader.read()) != -1) {
271: buff.append((char) c);
272: }
273: BufferedWriter out = new BufferedWriter(new FileWriter(
274: destFile));
275: out.write(buff.toString());
276: out.flush();
277: out.close();
278: } catch (IOException e) {
279: e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
280: }
281: }
282:
283: /**
284: * This will not be implemented because we do not support changing the directory at runtime
285: *
286: * @param string -
287: */
288: public void setDirectory(String string) {
289: // we do not support changing the directory
290: }
291:
292: /**
293: * This will not be implemented because we do not support changing the extension at runtime
294: *
295: * @param string -
296: */
297: public void setExtension(String string) {
298: // we do not support changing the extension
299: }
300:
301: /**
302: * This will be called when a particulr jar file is deleted from the specified folder
303: *
304: * @param string - filename of the deleted file
305: * @throws DeploymentException - incase of an error in undeployment
306: */
307: public void unDeploy(String string) throws DeploymentException {
308: // todo: implement the undeployement
309: }
310:
311: private void handleException(String message, Exception e)
312: throws DeploymentException {
313: if (log.isDebugEnabled()) {
314: log.debug(message, e);
315: }
316: throw new DeploymentException(message, e);
317: }
318:
319: private void handleException(String message)
320: throws DeploymentException {
321: if (log.isDebugEnabled()) {
322: log.debug(message);
323: }
324: throw new DeploymentException(message);
325: }
326: }
|