KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > axis > handlers > JWSHandler


1 /*
2  * Copyright 2001-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.apache.axis.handlers;
18
19 import org.apache.axis.AxisFault;
20 import org.apache.axis.Constants;
21 import org.apache.axis.MessageContext;
22 import org.apache.axis.components.compiler.Compiler;
23 import org.apache.axis.components.compiler.CompilerError;
24 import org.apache.axis.components.compiler.CompilerFactory;
25 import org.apache.axis.components.logger.LogFactory;
26 import org.apache.axis.constants.Scope;
27 import org.apache.axis.handlers.soap.SOAPService;
28 import org.apache.axis.providers.java.RPCProvider;
29 import org.apache.axis.utils.ClassUtils;
30 import org.apache.axis.utils.ClasspathUtils;
31 import org.apache.axis.utils.JWSClassLoader;
32 import org.apache.axis.utils.Messages;
33 import org.apache.axis.utils.XMLUtils;
34 import org.apache.commons.logging.Log;
35 import org.w3c.dom.Document JavaDoc;
36 import org.w3c.dom.Element JavaDoc;
37
38 import java.io.File JavaDoc;
39 import java.io.FileNotFoundException JavaDoc;
40 import java.io.FileReader JavaDoc;
41 import java.io.FileWriter JavaDoc;
42 import java.util.HashMap JavaDoc;
43 import java.util.List JavaDoc;
44
45 /** A <code>JWSHandler</code> sets the target service and JWS filename
46  * in the context depending on the JWS configuration and the target URL.
47  *
48  * @author Glen Daniels (gdaniels@allaire.com)
49  * @author Doug Davis (dug@us.ibm.com)
50  * @author Sam Ruby (rubys@us.ibm.com)
51  */

52 public class JWSHandler extends BasicHandler
53 {
54     protected static Log log =
55         LogFactory.getLog(JWSHandler.class.getName());
56
57     public final String JavaDoc OPTION_JWS_FILE_EXTENSION = "extension";
58     public final String JavaDoc DEFAULT_JWS_FILE_EXTENSION = Constants.JWS_DEFAULT_FILE_EXTENSION;
59
60     protected static HashMap JavaDoc soapServices = new HashMap JavaDoc();
61
62     /**
63      * Just set up the service, the inner service will do the rest...
64      */

65     public void invoke(MessageContext msgContext) throws AxisFault
66     {
67         if (log.isDebugEnabled()) {
68             log.debug("Enter: JWSHandler::invoke");
69         }
70
71         try {
72             setupService(msgContext);
73         } catch (Exception JavaDoc e) {
74             log.error( Messages.getMessage("exception00"), e );
75             throw AxisFault.makeFault(e);
76         }
77     }
78     
79     /**
80      * If our path ends in the right file extension (*.jws), handle all the
81      * work necessary to compile the source file if it needs it, and set
82      * up the "proxy" RPC service surrounding it as the MessageContext's
83      * active service.
84      *
85      */

86     protected void setupService(MessageContext msgContext) throws Exception JavaDoc {
87         // FORCE the targetService to be JWS if the URL is right.
88
String JavaDoc realpath = msgContext.getStrProp(Constants.MC_REALPATH);
89         String JavaDoc extension = (String JavaDoc)getOption(OPTION_JWS_FILE_EXTENSION);
90         if (extension == null) extension = DEFAULT_JWS_FILE_EXTENSION;
91         
92         if ((realpath!=null) && (realpath.endsWith(extension))) {
93             /* Grab the *.jws filename from the context - should have been */
94             /* placed there by another handler (ie. HTTPActionHandler) */
95             /***************************************************************/
96             String JavaDoc jwsFile = realpath;
97             String JavaDoc rel = msgContext.getStrProp(Constants.MC_RELATIVE_PATH);
98
99             // Check for file existance, report error with
100
// relative path to avoid giving out directory info.
101
File JavaDoc f2 = new File JavaDoc( jwsFile );
102             if (!f2.exists()) {
103                 throw new FileNotFoundException JavaDoc(rel);
104             }
105
106             if (rel.charAt(0) == '/') {
107                 rel = rel.substring(1);
108             }
109
110             int lastSlash = rel.lastIndexOf('/');
111             String JavaDoc dir = null;
112             
113             if (lastSlash > 0) {
114                 dir = rel.substring(0, lastSlash);
115             }
116             
117             String JavaDoc file = rel.substring(lastSlash + 1);
118             
119             String JavaDoc outdir = msgContext.getStrProp( Constants.MC_JWS_CLASSDIR );
120             if ( outdir == null ) outdir = "." ;
121             
122             // Build matching directory structure under the output
123
// directory. In other words, if we have:
124
// /webroot/jws1/Foo.jws
125
//
126
// That will be compiled to:
127
// .../jwsOutputDirectory/jws1/Foo.class
128
if (dir != null) {
129                 outdir = outdir + File.separator + dir;
130             }
131             
132             // Confirm output directory exists. If not, create it IF we're
133
// allowed to.
134
// !!! TODO: add a switch to control this.
135
File JavaDoc outDirectory = new File JavaDoc(outdir);
136             if (!outDirectory.exists()) {
137                 outDirectory.mkdirs();
138             }
139             
140             if (log.isDebugEnabled())
141                 log.debug("jwsFile: " + jwsFile );
142             
143             String JavaDoc jFile = outdir + File.separator + file.substring(0, file.length()-extension.length()+1) +
144                     "java" ;
145             String JavaDoc cFile = outdir + File.separator + file.substring(0, file.length()-extension.length()+1) +
146                     "class" ;
147             
148             if (log.isDebugEnabled()) {
149                 log.debug("jFile: " + jFile );
150                 log.debug("cFile: " + cFile );
151                 log.debug("outdir: " + outdir);
152             }
153             
154             File JavaDoc f1 = new File JavaDoc( cFile );
155
156             /* Get the class */
157             /*****************/
158             String JavaDoc clsName = null ;
159             //clsName = msgContext.getStrProp(Constants.MC_RELATIVE_PATH);
160
if ( clsName == null ) clsName = f2.getName();
161             if ( clsName != null && clsName.charAt(0) == '/' )
162                 clsName = clsName.substring(1);
163             
164             clsName = clsName.substring( 0, clsName.length()-extension.length() );
165             clsName = clsName.replace('/', '.');
166             
167             if (log.isDebugEnabled())
168                 log.debug("ClsName: " + clsName );
169             
170             /* Check to see if we need to recompile */
171             /****************************************/
172             if ( !f1.exists() || f2.lastModified() > f1.lastModified() ) {
173                 /* If the class file doesn't exist, or it's older than the */
174                 /* java file then recompile the java file. */
175                 /* Start by copying the *.jws file to *.java */
176                 /***********************************************************/
177                 log.debug(Messages.getMessage("compiling00", jwsFile) );
178                 log.debug(Messages.getMessage("copy00", jwsFile, jFile) );
179                 FileReader JavaDoc fr = new FileReader JavaDoc( jwsFile );
180                 FileWriter JavaDoc fw = new FileWriter JavaDoc( jFile );
181                 char[] buf = new char[4096];
182                 int rc ;
183                 while ( (rc = fr.read( buf, 0, 4095)) >= 0 )
184                     fw.write( buf, 0, rc );
185                 fw.close();
186                 fr.close();
187                 
188                 /* Now run javac on the *.java file */
189                 /************************************/
190                 log.debug("javac " + jFile );
191                 // Process proc = rt.exec( "javac " + jFile );
192
// proc.waitFor();
193
Compiler JavaDoc compiler = CompilerFactory.getCompiler();
194                 
195                 compiler.setClasspath(ClasspathUtils.getDefaultClasspath(msgContext));
196                 compiler.setDestination(outdir);
197                 compiler.addFile(jFile);
198                 
199                 boolean result = compiler.compile();
200                 
201                 /* Delete the temporary *.java file and check return code */
202                 /**********************************************************/
203                 (new File JavaDoc(jFile)).delete();
204                 
205                 if ( !result ) {
206                     /* Delete the *class file - sometimes it gets created even */
207                     /* when there are errors - so erase it so it doesn't */
208                     /* confuse us. */
209                     /***********************************************************/
210                     (new File JavaDoc(cFile)).delete();
211                     
212                     Document JavaDoc doc = XMLUtils.newDocument();
213                     
214                     Element JavaDoc root = doc.createElementNS("", "Errors");
215                     StringBuffer JavaDoc message = new StringBuffer JavaDoc("Error compiling ");
216                     message.append(jFile);
217                     message.append(":\n");
218                     
219                     List JavaDoc errors = compiler.getErrors();
220                     int count = errors.size();
221                     for (int i = 0; i < count; i++) {
222                         CompilerError error = (CompilerError) errors.get(i);
223                         if (i > 0) message.append("\n");
224                         message.append("Line ");
225                         message.append(error.getStartLine());
226                         message.append(", column ");
227                         message.append(error.getStartColumn());
228                         message.append(": ");
229                         message.append(error.getMessage());
230                     }
231                     root.appendChild( doc.createTextNode( message.toString() ) );
232                     throw new AxisFault( "Server.compileError",
233                                          Messages.getMessage("badCompile00", jFile),
234                                          null, new Element JavaDoc[] { root } );
235                 }
236                 ClassUtils.removeClassLoader( clsName );
237                 // And clean out the cached service.
238
soapServices.remove(clsName);
239             }
240             
241             ClassLoader JavaDoc cl = ClassUtils.getClassLoader(clsName);
242             if (cl == null) {
243                 cl = new JWSClassLoader(clsName,
244                                         msgContext.getClassLoader(),
245                                         cFile);
246             }
247             
248             msgContext.setClassLoader(cl);
249             
250             /* Create a new RPCProvider - this will be the "service" */
251             /* that we invoke. */
252             /******************************************************************/
253             // Cache the rpc service created to handle the class. The cache
254
// is based on class name, so only one .jws/.jwr class can be active
255
// in the system at a time.
256
SOAPService rpc = (SOAPService)soapServices.get(clsName);
257             if (rpc == null) {
258                 rpc = new SOAPService(new RPCProvider());
259                 rpc.setName(clsName);
260                 rpc.setOption(RPCProvider.OPTION_CLASSNAME, clsName );
261                 rpc.setEngine(msgContext.getAxisEngine());
262                 
263                 // Support specification of "allowedMethods" as a parameter.
264
String JavaDoc allowed = (String JavaDoc)getOption(RPCProvider.OPTION_ALLOWEDMETHODS);
265                 if (allowed == null) allowed = "*";
266                 rpc.setOption(RPCProvider.OPTION_ALLOWEDMETHODS, allowed);
267                 // Take the setting for the scope option from the handler
268
// parameter named "scope"
269
String JavaDoc scope = (String JavaDoc)getOption(RPCProvider.OPTION_SCOPE);
270                 if (scope == null) scope = Scope.DEFAULT.getName();
271                 rpc.setOption(RPCProvider.OPTION_SCOPE, scope);
272                 
273                 rpc.getInitializedServiceDesc(msgContext);
274                 
275                 soapServices.put(clsName, rpc);
276             }
277             
278             // Set engine, which hooks up type mappings.
279
rpc.setEngine(msgContext.getAxisEngine());
280             
281             rpc.init(); // ??
282

283             // OK, this is now the destination service!
284
msgContext.setService( rpc );
285         }
286
287         if (log.isDebugEnabled()) {
288             log.debug("Exit: JWSHandler::invoke");
289         }
290     }
291     
292     public void generateWSDL(MessageContext msgContext) throws AxisFault {
293         try {
294             setupService(msgContext);
295         } catch (Exception JavaDoc e) {
296             log.error( Messages.getMessage("exception00"), e );
297             throw AxisFault.makeFault(e);
298         }
299     }
300 }
301
Popular Tags