KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > jasper > JspC


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

17
18 package org.apache.jasper;
19
20 import java.io.BufferedReader JavaDoc;
21 import java.io.CharArrayWriter JavaDoc;
22 import java.io.File JavaDoc;
23 import java.io.FileInputStream JavaDoc;
24 import java.io.FileNotFoundException JavaDoc;
25 import java.io.FileOutputStream JavaDoc;
26 import java.io.FileReader JavaDoc;
27 import java.io.FileWriter JavaDoc;
28 import java.io.IOException JavaDoc;
29 import java.io.PrintWriter JavaDoc;
30 import java.io.Writer JavaDoc;
31 import java.net.MalformedURLException JavaDoc;
32 import java.net.URL JavaDoc;
33 import java.net.URLClassLoader JavaDoc;
34 import java.util.ArrayList JavaDoc;
35 import java.util.Iterator JavaDoc;
36 import java.util.List JavaDoc;
37 import java.util.Map JavaDoc;
38 import java.util.HashMap JavaDoc;
39 import java.util.Stack JavaDoc;
40 import java.util.StringTokenizer JavaDoc;
41 import java.util.Vector JavaDoc;
42
43 import org.apache.commons.logging.Log;
44 import org.apache.commons.logging.LogFactory;
45 import org.apache.jasper.compiler.Compiler;
46 import org.apache.jasper.compiler.JspConfig;
47 import org.apache.jasper.compiler.JspRuntimeContext;
48 import org.apache.jasper.compiler.Localizer;
49 import org.apache.jasper.compiler.TagPluginManager;
50 import org.apache.jasper.compiler.TldLocationsCache;
51 import org.apache.jasper.servlet.JspCServletContext;
52
53 import org.apache.tools.ant.AntClassLoader;
54 import org.apache.tools.ant.Project;
55 import org.apache.tools.ant.util.FileUtils;
56
57 /**
58  * Shell for the jspc compiler. Handles all options associated with the
59  * command line and creates compilation contexts which it then compiles
60  * according to the specified options.
61  *
62  * This version can process files from a _single_ webapp at once, i.e.
63  * a single docbase can be specified.
64  *
65  * It can be used as an Ant task using:
66  * <pre>
67  * &lt;taskdef classname="org.apache.jasper.JspC" name="jasper2" &gt;
68  * &lt;classpath&gt;
69  * &lt;pathelement location="${java.home}/../lib/tools.jar"/&gt;
70  * &lt;fileset dir="${ENV.CATALINA_HOME}/server/lib"&gt;
71  * &lt;include name="*.jar"/&gt;
72  * &lt;/fileset&gt;
73  * &lt;fileset dir="${ENV.CATALINA_HOME}/common/lib"&gt;
74  * &lt;include name="*.jar"/&gt;
75  * &lt;/fileset&gt;
76  * &lt;path refid="myjars"/&gt;
77  * &lt;/classpath&gt;
78  * &lt;/taskdef&gt;
79  *
80  * &lt;jasper2 verbose="0"
81  * package="my.package"
82  * uriroot="${webapps.dir}/${webapp.name}"
83  * webXmlFragment="${build.dir}/generated_web.xml"
84  * outputDir="${webapp.dir}/${webapp.name}/WEB-INF/src/my/package" /&gt;
85  * </pre>
86  *
87  * @author Danno Ferrin
88  * @author Pierre Delisle
89  * @author Costin Manolache
90  * @author Yoav Shapira
91  */

92 public class JspC implements Options {
93
94     public static final String JavaDoc DEFAULT_IE_CLASS_ID =
95             "clsid:8AD9C840-044E-11D1-B3E9-00805F499D93";
96
97     // Logger
98
protected static Log log = LogFactory.getLog(JspC.class);
99
100     protected static final String JavaDoc SWITCH_VERBOSE = "-v";
101     protected static final String JavaDoc SWITCH_HELP = "-help";
102     protected static final String JavaDoc SWITCH_OUTPUT_DIR = "-d";
103     protected static final String JavaDoc SWITCH_PACKAGE_NAME = "-p";
104     protected static final String JavaDoc SWITCH_CACHE = "-cache";
105     protected static final String JavaDoc SWITCH_CLASS_NAME = "-c";
106     protected static final String JavaDoc SWITCH_FULL_STOP = "--";
107     protected static final String JavaDoc SWITCH_COMPILE = "-compile";
108     protected static final String JavaDoc SWITCH_SOURCE = "-source";
109     protected static final String JavaDoc SWITCH_TARGET = "-target";
110     protected static final String JavaDoc SWITCH_URI_BASE = "-uribase";
111     protected static final String JavaDoc SWITCH_URI_ROOT = "-uriroot";
112     protected static final String JavaDoc SWITCH_FILE_WEBAPP = "-webapp";
113     protected static final String JavaDoc SWITCH_WEBAPP_INC = "-webinc";
114     protected static final String JavaDoc SWITCH_WEBAPP_XML = "-webxml";
115     protected static final String JavaDoc SWITCH_MAPPED = "-mapped";
116     protected static final String JavaDoc SWITCH_XPOWERED_BY = "-xpoweredBy";
117     protected static final String JavaDoc SWITCH_TRIM_SPACES = "-trimSpaces";
118     protected static final String JavaDoc SWITCH_CLASSPATH = "-classpath";
119     protected static final String JavaDoc SWITCH_DIE = "-die";
120     protected static final String JavaDoc SWITCH_POOLING = "-poolingEnabled";
121     protected static final String JavaDoc SWITCH_ENCODING = "-javaEncoding";
122     protected static final String JavaDoc SWITCH_SMAP = "-smap";
123     protected static final String JavaDoc SWITCH_DUMP_SMAP = "-dumpsmap";
124
125     protected static final String JavaDoc SHOW_SUCCESS ="-s";
126     protected static final String JavaDoc LIST_ERRORS = "-l";
127     protected static final int INC_WEBXML = 10;
128     protected static final int ALL_WEBXML = 20;
129     protected static final int DEFAULT_DIE_LEVEL = 1;
130     protected static final int NO_DIE_LEVEL = 0;
131
132     protected static final String JavaDoc[] insertBefore =
133     { "</web-app>", "<servlet-mapping>", "<session-config>",
134       "<mime-mapping>", "<welcome-file-list>", "<error-page>", "<taglib>",
135       "<resource-env-ref>", "<resource-ref>", "<security-constraint>",
136       "<login-config>", "<security-role>", "<env-entry>", "<ejb-ref>",
137       "<ejb-local-ref>" };
138
139     protected static int die;
140     protected String JavaDoc classPath = null;
141     protected URLClassLoader JavaDoc loader = null;
142     protected boolean trimSpaces = false;
143     protected boolean genStringAsCharArray = false;
144     protected boolean xpoweredBy;
145     protected boolean mappedFile = false;
146     protected boolean poolingEnabled = true;
147     protected File JavaDoc scratchDir;
148     protected String JavaDoc ieClassId = DEFAULT_IE_CLASS_ID;
149     protected String JavaDoc targetPackage;
150     protected String JavaDoc targetClassName;
151     protected String JavaDoc uriBase;
152     protected String JavaDoc uriRoot;
153     protected Project project;
154     protected int dieLevel;
155     protected boolean helpNeeded = false;
156     protected boolean compile = false;
157     protected boolean smapSuppressed = true;
158     protected boolean smapDumped = false;
159     protected boolean caching = true;
160     protected Map JavaDoc cache = new HashMap JavaDoc();
161
162     protected String JavaDoc compiler = null;
163
164     protected String JavaDoc compilerTargetVM = "1.4";
165     protected String JavaDoc compilerSourceVM = "1.4";
166
167     protected boolean classDebugInfo = true;
168
169     /**
170      * Throw an exception if there's a compilation error, or swallow it.
171      * Default is true to preserve old behavior.
172      */

173     protected boolean failOnError = true;
174
175     /**
176      * The file extensions to be handled as JSP files.
177      * Default list is .jsp and .jspx.
178      */

179     protected List JavaDoc extensions;
180
181     /**
182      * The pages.
183      */

184     protected List JavaDoc pages = new Vector JavaDoc();
185
186     /**
187      * Needs better documentation, this data member does.
188      * True by default.
189      */

190     protected boolean errorOnUseBeanInvalidClassAttribute = true;
191
192     /**
193      * The java file encoding. Default
194      * is UTF-8. Added per bugzilla 19622.
195      */

196     protected String JavaDoc javaEncoding = "UTF-8";
197
198     // Generation of web.xml fragments
199
protected String JavaDoc webxmlFile;
200     protected int webxmlLevel;
201     protected boolean addWebXmlMappings = false;
202
203     protected Writer JavaDoc mapout;
204     protected CharArrayWriter JavaDoc servletout;
205     protected CharArrayWriter JavaDoc mappingout;
206
207     /**
208      * The servlet context.
209      */

210     protected JspCServletContext context;
211
212     /**
213      * The runtime context.
214      * Maintain a dummy JspRuntimeContext for compiling tag files.
215      */

216     protected JspRuntimeContext rctxt;
217
218     /**
219      * Cache for the TLD locations
220      */

221     protected TldLocationsCache tldLocationsCache = null;
222
223     protected JspConfig jspConfig = null;
224     protected TagPluginManager tagPluginManager = null;
225
226     protected boolean verbose = false;
227     protected boolean listErrors = false;
228     protected boolean showSuccess = false;
229     protected int argPos;
230     protected boolean fullstop = false;
231     protected String JavaDoc args[];
232
233     public static void main(String JavaDoc arg[]) {
234         if (arg.length == 0) {
235             System.out.println(Localizer.getMessage("jspc.usage"));
236         } else {
237             try {
238                 JspC jspc = new JspC();
239                 jspc.setArgs(arg);
240                 if (jspc.helpNeeded) {
241                     System.out.println(Localizer.getMessage("jspc.usage"));
242                 } else {
243                     jspc.execute();
244                 }
245             } catch (JasperException je) {
246                 System.err.println(je);
247                 if (die != NO_DIE_LEVEL) {
248                     System.exit(die);
249                 }
250             }
251         }
252     }
253
254     public void setArgs(String JavaDoc[] arg) throws JasperException {
255         args = arg;
256         String JavaDoc tok;
257
258         dieLevel = NO_DIE_LEVEL;
259         die = dieLevel;
260
261         while ((tok = nextArg()) != null) {
262             if (tok.equals(SWITCH_VERBOSE)) {
263                 verbose = true;
264                 showSuccess = true;
265                 listErrors = true;
266             } else if (tok.equals(SWITCH_OUTPUT_DIR)) {
267                 tok = nextArg();
268                 setOutputDir( tok );
269             } else if (tok.equals(SWITCH_PACKAGE_NAME)) {
270                 targetPackage = nextArg();
271             } else if (tok.equals(SWITCH_COMPILE)) {
272                 compile=true;
273             } else if (tok.equals(SWITCH_CLASS_NAME)) {
274                 targetClassName = nextArg();
275             } else if (tok.equals(SWITCH_URI_BASE)) {
276                 uriBase=nextArg();
277             } else if (tok.equals(SWITCH_URI_ROOT)) {
278                 setUriroot( nextArg());
279             } else if (tok.equals(SWITCH_FILE_WEBAPP)) {
280                 setUriroot( nextArg());
281             } else if ( tok.equals( SHOW_SUCCESS ) ) {
282                 showSuccess = true;
283             } else if ( tok.equals( LIST_ERRORS ) ) {
284                 listErrors = true;
285             } else if (tok.equals(SWITCH_WEBAPP_INC)) {
286                 webxmlFile = nextArg();
287                 if (webxmlFile != null) {
288                     webxmlLevel = INC_WEBXML;
289                 }
290             } else if (tok.equals(SWITCH_WEBAPP_XML)) {
291                 webxmlFile = nextArg();
292                 if (webxmlFile != null) {
293                     webxmlLevel = ALL_WEBXML;
294                 }
295             } else if (tok.equals(SWITCH_MAPPED)) {
296                 mappedFile = true;
297             } else if (tok.equals(SWITCH_XPOWERED_BY)) {
298                 xpoweredBy = true;
299             } else if (tok.equals(SWITCH_TRIM_SPACES)) {
300                 setTrimSpaces(true);
301             } else if (tok.equals(SWITCH_CACHE)) {
302                 tok = nextArg();
303                 if ("false".equals(tok)) {
304                     caching = false;
305                 } else {
306                     caching = true;
307                 }
308             } else if (tok.equals(SWITCH_CLASSPATH)) {
309                 setClassPath(nextArg());
310             } else if (tok.startsWith(SWITCH_DIE)) {
311                 try {
312                     dieLevel = Integer.parseInt(
313                         tok.substring(SWITCH_DIE.length()));
314                 } catch (NumberFormatException JavaDoc nfe) {
315                     dieLevel = DEFAULT_DIE_LEVEL;
316                 }
317                 die = dieLevel;
318             } else if (tok.equals(SWITCH_HELP)) {
319                 helpNeeded = true;
320             } else if (tok.equals(SWITCH_POOLING)) {
321                 tok = nextArg();
322                 if ("false".equals(tok)) {
323                     poolingEnabled = false;
324                 } else {
325                     poolingEnabled = true;
326                 }
327             } else if (tok.equals(SWITCH_ENCODING)) {
328                 setJavaEncoding(nextArg());
329             } else if (tok.equals(SWITCH_SOURCE)) {
330                 setCompilerSourceVM(nextArg());
331             } else if (tok.equals(SWITCH_TARGET)) {
332                 setCompilerTargetVM(nextArg());
333             } else if (tok.equals(SWITCH_SMAP)) {
334                 smapSuppressed = false;
335             } else if (tok.equals(SWITCH_DUMP_SMAP)) {
336                 smapDumped = true;
337             } else {
338                 if (tok.startsWith("-")) {
339                     throw new JasperException("Unrecognized option: " + tok +
340                         ". Use -help for help.");
341                 }
342                 if (!fullstop) {
343                     argPos--;
344                 }
345                 // Start treating the rest as JSP Pages
346
break;
347             }
348         }
349
350         // Add all extra arguments to the list of files
351
while( true ) {
352             String JavaDoc file = nextFile();
353             if( file==null ) {
354                 break;
355             }
356             pages.add( file );
357         }
358     }
359
360     public boolean getKeepGenerated() {
361         // isn't this why we are running jspc?
362
return true;
363     }
364
365     public boolean getTrimSpaces() {
366         return trimSpaces;
367     }
368
369     public void setTrimSpaces(boolean ts) {
370         this.trimSpaces = ts;
371     }
372
373     public boolean isPoolingEnabled() {
374         return poolingEnabled;
375     }
376
377     public void setPoolingEnabled(boolean poolingEnabled) {
378         this.poolingEnabled = poolingEnabled;
379     }
380
381     public boolean isXpoweredBy() {
382         return xpoweredBy;
383     }
384
385     public void setXpoweredBy(boolean xpoweredBy) {
386         this.xpoweredBy = xpoweredBy;
387     }
388
389     public boolean getDisplaySourceFragment() {
390         return true;
391     }
392     
393     public boolean getErrorOnUseBeanInvalidClassAttribute() {
394         return errorOnUseBeanInvalidClassAttribute;
395     }
396
397     public void setErrorOnUseBeanInvalidClassAttribute(boolean b) {
398         errorOnUseBeanInvalidClassAttribute = b;
399     }
400
401     public int getTagPoolSize() {
402         return Constants.MAX_POOL_SIZE;
403     }
404
405     /**
406      * Are we supporting HTML mapped servlets?
407      */

408     public boolean getMappedFile() {
409         return mappedFile;
410     }
411
412     // Off-line compiler, no need for security manager
413
public Object JavaDoc getProtectionDomain() {
414         return null;
415     }
416
417     public boolean getSendErrorToClient() {
418         // implied send to System.err
419
return true;
420     }
421
422     public void setClassDebugInfo( boolean b ) {
423         classDebugInfo=b;
424     }
425
426     public boolean getClassDebugInfo() {
427         // compile with debug info
428
return classDebugInfo;
429     }
430
431      /**
432       * @see Options#isCaching()
433      */

434     public boolean isCaching() {
435         return caching;
436     }
437
438     /**
439      * @see Options#isCaching()
440      */

441     public void setCaching(boolean caching) {
442         this.caching = caching;
443     }
444
445     /**
446      * @see Options#getCache()
447      */

448     public Map JavaDoc getCache() {
449         return cache;
450     }
451
452     /**
453      * Background compilation check intervals in seconds
454      */

455     public int getCheckInterval() {
456         return 0;
457     }
458
459     /**
460      * Modification test interval.
461      */

462     public int getModificationTestInterval() {
463         return 0;
464     }
465
466     /**
467      * Is Jasper being used in development mode?
468      */

469     public boolean getDevelopment() {
470         return false;
471     }
472
473     /**
474      * Is the generation of SMAP info for JSR45 debuggin suppressed?
475      */

476     public boolean isSmapSuppressed() {
477         return smapSuppressed;
478     }
479
480     /**
481      * Set smapSuppressed flag.
482      */

483     public void setSmapSuppressed(boolean smapSuppressed) {
484         this.smapSuppressed = smapSuppressed;
485     }
486
487     
488     /**
489      * Should SMAP info for JSR45 debugging be dumped to a file?
490      */

491     public boolean isSmapDumped() {
492         return smapDumped;
493     }
494
495     /**
496      * Set smapSuppressed flag.
497      */

498     public void setSmapDumped(boolean smapDumped) {
499         this.smapDumped = smapDumped;
500     }
501
502     
503     /**
504      * Determines whether text strings are to be generated as char arrays,
505      * which improves performance in some cases.
506      *
507      * @param genStringAsCharArray true if text strings are to be generated as
508      * char arrays, false otherwise
509      */

510     public void setGenStringAsCharArray(boolean genStringAsCharArray) {
511         this.genStringAsCharArray = genStringAsCharArray;
512     }
513
514     /**
515      * Indicates whether text strings are to be generated as char arrays.
516      *
517      * @return true if text strings are to be generated as char arrays, false
518      * otherwise
519      */

520     public boolean genStringAsCharArray() {
521         return genStringAsCharArray;
522     }
523
524     /**
525      * Sets the class-id value to be sent to Internet Explorer when using
526      * <jsp:plugin> tags.
527      *
528      * @param ieClassId Class-id value
529      */

530     public void setIeClassId(String JavaDoc ieClassId) {
531         this.ieClassId = ieClassId;
532     }
533
534     /**
535      * Gets the class-id value that is sent to Internet Explorer when using
536      * <jsp:plugin> tags.
537      *
538      * @return Class-id value
539      */

540     public String JavaDoc getIeClassId() {
541         return ieClassId;
542     }
543
544     public File JavaDoc getScratchDir() {
545         return scratchDir;
546     }
547
548     public Class JavaDoc getJspCompilerPlugin() {
549        // we don't compile, so this is meanlingless
550
return null;
551     }
552
553     public String JavaDoc getJspCompilerPath() {
554        // we don't compile, so this is meanlingless
555
return null;
556     }
557
558     /**
559      * Compiler to use.
560      */

561     public String JavaDoc getCompiler() {
562         return compiler;
563     }
564
565     public void setCompiler(String JavaDoc c) {
566         compiler=c;
567     }
568
569     /**
570      * Compiler class name to use.
571      */

572     public String JavaDoc getCompilerClassName() {
573         return null;
574     }
575     
576     /**
577      * @see Options#getCompilerTargetVM
578      */

579     public String JavaDoc getCompilerTargetVM() {
580         return compilerTargetVM;
581     }
582
583     public void setCompilerTargetVM(String JavaDoc vm) {
584         compilerTargetVM = vm;
585     }
586
587     /**
588      * @see Options#getCompilerSourceVM()
589      */

590      public String JavaDoc getCompilerSourceVM() {
591          return compilerSourceVM;
592      }
593         
594     /**
595      * @see Options#getCompilerSourceVM()
596      */

597     public void setCompilerSourceVM(String JavaDoc vm) {
598         compilerSourceVM = vm;
599     }
600
601     public TldLocationsCache getTldLocationsCache() {
602         return tldLocationsCache;
603     }
604
605     /**
606      * Returns the encoding to use for
607      * java files. The default is UTF-8.
608      *
609      * @return String The encoding
610      */

611     public String JavaDoc getJavaEncoding() {
612         return javaEncoding;
613     }
614
615     /**
616      * Sets the encoding to use for
617      * java files.
618      *
619      * @param encodingName The name, e.g. "UTF-8"
620      */

621     public void setJavaEncoding(String JavaDoc encodingName) {
622         javaEncoding = encodingName;
623     }
624
625     public boolean getFork() {
626         return false;
627     }
628
629     public String JavaDoc getClassPath() {
630         if( classPath != null )
631             return classPath;
632         return System.getProperty("java.class.path");
633     }
634
635     public void setClassPath(String JavaDoc s) {
636         classPath=s;
637     }
638
639     /**
640      * Returns the list of file extensions
641      * that are treated as JSP files.
642      *
643      * @return The list of extensions
644      */

645     public List JavaDoc getExtensions() {
646         return extensions;
647     }
648
649     /**
650      * Adds the given file extension to the
651      * list of extensions handled as JSP files.
652      *
653      * @param extension The extension to add, e.g. "myjsp"
654      */

655     protected void addExtension(final String JavaDoc extension) {
656         if(extension != null) {
657             if(extensions == null) {
658                 extensions = new Vector JavaDoc();
659             }
660
661             extensions.add(extension);
662         }
663     }
664
665     /**
666      * Sets the project.
667      *
668      * @param theProject The project
669      */

670     public void setProject(final Project theProject) {
671         project = theProject;
672     }
673
674     /**
675      * Returns the project: may be null if not running
676      * inside an Ant project.
677      *
678      * @return The project
679      */

680     public Project getProject() {
681         return project;
682     }
683
684     /**
685      * Base dir for the webapp. Used to generate class names and resolve
686      * includes
687      */

688     public void setUriroot( String JavaDoc s ) {
689         if( s==null ) {
690             uriRoot = s;
691             return;
692         }
693         try {
694             uriRoot = resolveFile(s).getCanonicalPath();
695         } catch( Exception JavaDoc ex ) {
696             uriRoot = s;
697         }
698     }
699
700     /**
701      * Parses comma-separated list of JSP files to be processed. If the argument
702      * is null, nothing is done.
703      *
704      * <p>Each file is interpreted relative to uriroot, unless it is absolute,
705      * in which case it must start with uriroot.</p>
706      *
707      * @param jspFiles Comma-separated list of JSP files to be processed
708      */

709     public void setJspFiles(final String JavaDoc jspFiles) {
710         if(jspFiles == null) {
711             return;
712         }
713
714         StringTokenizer JavaDoc tok = new StringTokenizer JavaDoc(jspFiles, ",");
715         while (tok.hasMoreTokens()) {
716             pages.add(tok.nextToken());
717         }
718     }
719
720     /**
721      * Sets the compile flag.
722      *
723      * @param b Flag value
724      */

725     public void setCompile( final boolean b ) {
726         compile = b;
727     }
728
729     /**
730      * Sets the verbosity level. The actual number doesn't
731      * matter: if it's greater than zero, the verbose flag will
732      * be true.
733      *
734      * @param level Positive means verbose
735      */

736     public void setVerbose( final int level ) {
737         if (level > 0) {
738             verbose = true;
739             showSuccess = true;
740             listErrors = true;
741         }
742     }
743
744     public void setValidateXml( boolean b ) {
745         org.apache.jasper.xmlparser.ParserUtils.validating=b;
746     }
747
748     public void setListErrors( boolean b ) {
749         listErrors = b;
750     }
751
752     public void setOutputDir( String JavaDoc s ) {
753         if( s!= null ) {
754             scratchDir = resolveFile(s).getAbsoluteFile();
755         } else {
756             scratchDir=null;
757         }
758     }
759
760     public void setPackage( String JavaDoc p ) {
761         targetPackage=p;
762     }
763
764     /**
765      * Class name of the generated file ( without package ).
766      * Can only be used if a single file is converted.
767      * XXX Do we need this feature ?
768      */

769     public void setClassName( String JavaDoc p ) {
770         targetClassName=p;
771     }
772
773     /**
774      * File where we generate a web.xml fragment with the class definitions.
775      */

776     public void setWebXmlFragment( String JavaDoc s ) {
777         webxmlFile=resolveFile(s).getAbsolutePath();
778         webxmlLevel=INC_WEBXML;
779     }
780
781     /**
782      * File where we generate a complete web.xml with the class definitions.
783      */

784     public void setWebXml( String JavaDoc s ) {
785         webxmlFile=resolveFile(s).getAbsolutePath();
786         webxmlLevel=ALL_WEBXML;
787     }
788
789     public void setAddWebXmlMappings(boolean b) {
790         addWebXmlMappings = b;
791     }
792
793     /**
794      * Set the option that throws an exception in case of a compilation error.
795      */

796     public void setFailOnError(final boolean b) {
797         failOnError = b;
798     }
799
800     public boolean getFailOnError() {
801         return failOnError;
802     }
803
804     /**
805      * Obtain JSP configuration informantion specified in web.xml.
806      */

807     public JspConfig getJspConfig() {
808         return jspConfig;
809     }
810
811     public TagPluginManager getTagPluginManager() {
812         return tagPluginManager;
813     }
814
815     public void generateWebMapping( String JavaDoc file, JspCompilationContext clctxt )
816         throws IOException JavaDoc
817     {
818         String JavaDoc className = clctxt.getServletClassName();
819         String JavaDoc packageName = clctxt.getServletPackageName();
820
821         String JavaDoc thisServletName;
822         if ("".equals(packageName)) {
823             thisServletName = className;
824         } else {
825             thisServletName = packageName + '.' + className;
826         }
827
828         if (servletout != null) {
829             servletout.write("\n <servlet>\n <servlet-name>");
830             servletout.write(thisServletName);
831             servletout.write("</servlet-name>\n <servlet-class>");
832             servletout.write(thisServletName);
833             servletout.write("</servlet-class>\n </servlet>\n");
834         }
835         if (mappingout != null) {
836             mappingout.write("\n <servlet-mapping>\n <servlet-name>");
837             mappingout.write(thisServletName);
838             mappingout.write("</servlet-name>\n <url-pattern>");
839             mappingout.write(file.replace('\\', '/'));
840             mappingout.write("</url-pattern>\n </servlet-mapping>\n");
841
842         }
843     }
844
845     /**
846      * Include the generated web.xml inside the webapp's web.xml.
847      */

848     protected void mergeIntoWebXml() throws IOException JavaDoc {
849
850         File JavaDoc webappBase = new File JavaDoc(uriRoot);
851         File JavaDoc webXml = new File JavaDoc(webappBase, "WEB-INF/web.xml");
852         File JavaDoc webXml2 = new File JavaDoc(webappBase, "WEB-INF/web2.xml");
853         String JavaDoc insertStartMarker =
854             Localizer.getMessage("jspc.webinc.insertStart");
855         String JavaDoc insertEndMarker =
856             Localizer.getMessage("jspc.webinc.insertEnd");
857
858         BufferedReader JavaDoc reader = new BufferedReader JavaDoc(new FileReader JavaDoc(webXml));
859         BufferedReader JavaDoc fragmentReader =
860             new BufferedReader JavaDoc(new FileReader JavaDoc(webxmlFile));
861         PrintWriter JavaDoc writer = new PrintWriter JavaDoc(new FileWriter JavaDoc(webXml2));
862
863         // Insert the <servlet> and <servlet-mapping> declarations
864
int pos = -1;
865         String JavaDoc line = null;
866         while (true) {
867             line = reader.readLine();
868             if (line == null) {
869                 break;
870             }
871             // Skip anything previously generated by JSPC
872
if (line.indexOf(insertStartMarker) >= 0) {
873                 while (true) {
874                     line = reader.readLine();
875                     if (line == null) {
876                         return;
877                     }
878                     if (line.indexOf(insertEndMarker) >= 0) {
879                         line = reader.readLine();
880                         line = reader.readLine();
881                         if (line == null) {
882                             return;
883                         }
884                         break;
885                     }
886                 }
887             }
888             for (int i = 0; i < insertBefore.length; i++) {
889                 pos = line.indexOf(insertBefore[i]);
890                 if (pos >= 0)
891                     break;
892             }
893             if (pos >= 0) {
894                 writer.print(line.substring(0, pos));
895                 break;
896             } else {
897                 writer.println(line);
898             }
899         }
900
901         writer.println(insertStartMarker);
902         while (true) {
903             String JavaDoc line2 = fragmentReader.readLine();
904             if (line2 == null) {
905                 writer.println();
906                 break;
907             }
908             writer.println(line2);
909         }
910         writer.println(insertEndMarker);
911         writer.println();
912
913         for (int i = 0; i < pos; i++) {
914             writer.print(" ");
915         }
916         writer.println(line.substring(pos));
917
918         while (true) {
919             line = reader.readLine();
920             if (line == null) {
921                 break;
922             }
923             writer.println(line);
924         }
925         writer.close();
926
927         reader.close();
928         fragmentReader.close();
929
930         FileInputStream JavaDoc fis = new FileInputStream JavaDoc(webXml2);
931         FileOutputStream JavaDoc fos = new FileOutputStream JavaDoc(webXml);
932
933         byte buf[] = new byte[512];
934         while (true) {
935             int n = fis.read(buf);
936             if (n < 0) {
937                 break;
938             }
939             fos.write(buf, 0, n);
940         }
941
942         fis.close();
943         fos.close();
944
945         webXml2.delete();
946         (new File JavaDoc(webxmlFile)).delete();
947
948     }
949
950     protected void processFile(String JavaDoc file)
951         throws JasperException
952     {
953         ClassLoader JavaDoc originalClassLoader = null;
954
955         try {
956             // set up a scratch/output dir if none is provided
957
if (scratchDir == null) {
958                 String JavaDoc temp = System.getProperty("java.io.tmpdir");
959                 if (temp == null) {
960                     temp = "";
961                 }
962                 scratchDir = new File JavaDoc(new File JavaDoc(temp).getAbsolutePath());
963             }
964
965             String JavaDoc jspUri=file.replace('\\','/');
966             JspCompilationContext clctxt = new JspCompilationContext
967                 ( jspUri, false, this, context, null, rctxt );
968
969             /* Override the defaults */
970             if ((targetClassName != null) && (targetClassName.length() > 0)) {
971                 clctxt.setServletClassName(targetClassName);
972                 targetClassName = null;
973             }
974             if (targetPackage != null) {
975                 clctxt.setServletPackageName(targetPackage);
976             }
977
978             originalClassLoader = Thread.currentThread().getContextClassLoader();
979             if( loader==null ) {
980                 initClassLoader( clctxt );
981             }
982             Thread.currentThread().setContextClassLoader(loader);
983
984             clctxt.setClassLoader(loader);
985             clctxt.setClassPath(classPath);
986
987             Compiler JavaDoc clc = clctxt.createCompiler();
988
989             // If compile is set, generate both .java and .class, if
990
// .jsp file is newer than .class file;
991
// Otherwise only generate .java, if .jsp file is newer than
992
// the .java file
993
if( clc.isOutDated(compile) ) {
994                 clc.compile(compile, true);
995             }
996
997             // Generate mapping
998
generateWebMapping( file, clctxt );
999             if ( showSuccess ) {
1000                log.info( "Built File: " + file );
1001            }
1002
1003        } catch (JasperException je) {
1004            Throwable JavaDoc rootCause = je;
1005            while (rootCause instanceof JasperException
1006                    && ((JasperException) rootCause).getRootCause() != null) {
1007                rootCause = ((JasperException) rootCause).getRootCause();
1008            }
1009            if (rootCause != je) {
1010                log.error(Localizer.getMessage("jspc.error.generalException",
1011                                               file),
1012                          rootCause);
1013            }
1014
1015            // Bugzilla 35114.
1016
if(getFailOnError()) {
1017                throw je;
1018            } else {
1019                log.error(je.getMessage());
1020            }
1021
1022        } catch (Exception JavaDoc e) {
1023            if ((e instanceof FileNotFoundException JavaDoc) && log.isWarnEnabled()) {
1024                log.warn(Localizer.getMessage("jspc.error.fileDoesNotExist",
1025                                              e.getMessage()));
1026            }
1027            throw new JasperException(e);
1028        } finally {
1029            if(originalClassLoader != null) {
1030                Thread.currentThread().setContextClassLoader(originalClassLoader);
1031            }
1032        }
1033    }
1034
1035    /**
1036     * Locate all jsp files in the webapp. Used if no explicit
1037     * jsps are specified.
1038     */

1039    public void scanFiles( File JavaDoc base ) throws JasperException {
1040        Stack JavaDoc<String JavaDoc> dirs = new Stack JavaDoc<String JavaDoc>();
1041        dirs.push(base.toString());
1042
1043        // Make sure default extensions are always included
1044
if ((getExtensions() == null) || (getExtensions().size() < 2)) {
1045            addExtension("jsp");
1046            addExtension("jspx");
1047        }
1048
1049        while (!dirs.isEmpty()) {
1050            String JavaDoc s = dirs.pop();
1051            File JavaDoc f = new File JavaDoc(s);
1052            if (f.exists() && f.isDirectory()) {
1053                String JavaDoc[] files = f.list();
1054                String JavaDoc ext;
1055                for (int i = 0; (files != null) && i < files.length; i++) {
1056                    File JavaDoc f2 = new File JavaDoc(s, files[i]);
1057                    if (f2.isDirectory()) {
1058                        dirs.push(f2.getPath());
1059                    } else {
1060                        String JavaDoc path = f2.getPath();
1061                        String JavaDoc uri = path.substring(uriRoot.length());
1062                        ext = files[i].substring(files[i].lastIndexOf('.') +1);
1063                        if (getExtensions().contains(ext) ||
1064                            jspConfig.isJspPage(uri)) {
1065                            pages.add(path);
1066                        }
1067                    }
1068                }
1069            }
1070        }
1071    }
1072
1073    /**
1074     * Executes the compilation.
1075     *
1076     * @throws JasperException If an error occurs
1077     */

1078    public void execute() throws JasperException {
1079        if(log.isDebugEnabled()) {
1080            log.debug("execute() starting for " + pages.size() + " pages.");
1081        }
1082
1083        try {
1084            if (uriRoot == null) {
1085                if( pages.size() == 0 ) {
1086                    throw new JasperException(
1087                        Localizer.getMessage("jsp.error.jspc.missingTarget"));
1088                }
1089                String JavaDoc firstJsp = (String JavaDoc) pages.get( 0 );
1090                File JavaDoc firstJspF = new File JavaDoc( firstJsp );
1091                if (!firstJspF.exists()) {
1092                    throw new JasperException(
1093                        Localizer.getMessage("jspc.error.fileDoesNotExist",
1094                                             firstJsp));
1095                }
1096                locateUriRoot( firstJspF );
1097            }
1098
1099            if (uriRoot == null) {
1100                throw new JasperException(
1101                    Localizer.getMessage("jsp.error.jspc.no_uriroot"));
1102            }
1103
1104            if( context==null ) {
1105                initServletContext();
1106            }
1107
1108            // No explicit pages, we'll process all .jsp in the webapp
1109
if (pages.size() == 0) {
1110                scanFiles( new File JavaDoc( uriRoot ));
1111            }
1112
1113            File JavaDoc uriRootF = new File JavaDoc(uriRoot);
1114            if (!uriRootF.exists() || !uriRootF.isDirectory()) {
1115                throw new JasperException(
1116                    Localizer.getMessage("jsp.error.jspc.uriroot_not_dir"));
1117            }
1118
1119            initWebXml();
1120
1121            Iterator JavaDoc iter = pages.iterator();
1122            while (iter.hasNext()) {
1123                String JavaDoc nextjsp = iter.next().toString();
1124                File JavaDoc fjsp = new File JavaDoc(nextjsp);
1125                if (!fjsp.isAbsolute()) {
1126                    fjsp = new File JavaDoc(uriRootF, nextjsp);
1127                }
1128                if (!fjsp.exists()) {
1129                    if (log.isWarnEnabled()) {
1130                        log.warn
1131                            (Localizer.getMessage
1132                             ("jspc.error.fileDoesNotExist", fjsp.toString()));
1133                    }
1134                    continue;
1135                }
1136                String JavaDoc s = fjsp.getAbsolutePath();
1137                if (s.startsWith(uriRoot)) {
1138                    nextjsp = s.substring(uriRoot.length());
1139                }
1140                if (nextjsp.startsWith("." + File.separatorChar)) {
1141                    nextjsp = nextjsp.substring(2);
1142                }
1143                processFile(nextjsp);
1144            }
1145
1146            completeWebXml();
1147
1148            if (addWebXmlMappings) {
1149                mergeIntoWebXml();
1150            }
1151
1152        } catch (IOException JavaDoc ioe) {
1153            throw new JasperException(ioe);
1154
1155        } catch (JasperException je) {
1156            Throwable JavaDoc rootCause = je;
1157            while (rootCause instanceof JasperException
1158                    && ((JasperException) rootCause).getRootCause() != null) {
1159                rootCause = ((JasperException) rootCause).getRootCause();
1160            }
1161            if (rootCause != je) {
1162                rootCause.printStackTrace();
1163            }
1164            throw je;
1165        } finally {
1166            if (loader != null) {
1167                LogFactory.release(loader);
1168            }
1169        }
1170    }
1171
1172    // ==================== protected utility methods ====================
1173

1174    protected String JavaDoc nextArg() {
1175        if ((argPos >= args.length)
1176            || (fullstop = SWITCH_FULL_STOP.equals(args[argPos]))) {
1177            return null;
1178        } else {
1179            return args[argPos++];
1180        }
1181    }
1182
1183    protected String JavaDoc nextFile() {
1184        if (fullstop) argPos++;
1185        if (argPos >= args.length) {
1186            return null;
1187        } else {
1188            return args[argPos++];
1189        }
1190    }
1191
1192    protected void initWebXml() {
1193        try {
1194            if (webxmlLevel >= INC_WEBXML) {
1195                File JavaDoc fmapings = new File JavaDoc(webxmlFile);
1196                mapout = new FileWriter JavaDoc(fmapings);
1197                servletout = new CharArrayWriter JavaDoc();
1198                mappingout = new CharArrayWriter JavaDoc();
1199            } else {
1200                mapout = null;
1201                servletout = null;
1202                mappingout = null;
1203            }
1204            if (webxmlLevel >= ALL_WEBXML) {
1205                mapout.write(Localizer.getMessage("jspc.webxml.header"));
1206                mapout.flush();
1207            } else if ((webxmlLevel>= INC_WEBXML) && !addWebXmlMappings) {
1208                mapout.write(Localizer.getMessage("jspc.webinc.header"));
1209                mapout.flush();
1210            }
1211        } catch (IOException JavaDoc ioe) {
1212            mapout = null;
1213            servletout = null;
1214            mappingout = null;
1215        }
1216    }
1217
1218    protected void completeWebXml() {
1219        if (mapout != null) {
1220            try {
1221                servletout.writeTo(mapout);
1222                mappingout.writeTo(mapout);
1223                if (webxmlLevel >= ALL_WEBXML) {
1224                    mapout.write(Localizer.getMessage("jspc.webxml.footer"));
1225                } else if ((webxmlLevel >= INC_WEBXML) && !addWebXmlMappings) {
1226                    mapout.write(Localizer.getMessage("jspc.webinc.footer"));
1227                }
1228                mapout.close();
1229            } catch (IOException JavaDoc ioe) {
1230                // noting to do if it fails since we are done with it
1231
}
1232        }
1233    }
1234
1235    protected void initServletContext() {
1236        try {
1237            context =new JspCServletContext
1238                (new PrintWriter JavaDoc(System.out),
1239                 new URL JavaDoc("file:" + uriRoot.replace('\\','/') + '/'));
1240            tldLocationsCache = new TldLocationsCache(context, true);
1241        } catch (MalformedURLException JavaDoc me) {
1242            System.out.println("**" + me);
1243        }
1244        rctxt = new JspRuntimeContext(context, this);
1245        jspConfig = new JspConfig(context);
1246        tagPluginManager = new TagPluginManager(context);
1247    }
1248
1249    /**
1250     * Initializes the classloader as/if needed for the given
1251     * compilation context.
1252     *
1253     * @param clctxt The compilation context
1254     * @throws IOException If an error occurs
1255     */

1256    protected void initClassLoader(JspCompilationContext clctxt)
1257        throws IOException JavaDoc {
1258
1259        classPath = getClassPath();
1260
1261        ClassLoader JavaDoc jspcLoader = getClass().getClassLoader();
1262        if (jspcLoader instanceof AntClassLoader) {
1263            classPath += File.pathSeparator
1264                + ((AntClassLoader) jspcLoader).getClasspath();
1265        }
1266
1267        // Turn the classPath into URLs
1268
ArrayList JavaDoc<URL JavaDoc> urls = new ArrayList JavaDoc<URL JavaDoc>();
1269        StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc(classPath,
1270                                                        File.pathSeparator);
1271        while (tokenizer.hasMoreTokens()) {
1272            String JavaDoc path = tokenizer.nextToken();
1273            try {
1274                File JavaDoc libFile = new File JavaDoc(path);
1275                urls.add(libFile.toURL());
1276            } catch (IOException JavaDoc ioe) {
1277                // Failing a toCanonicalPath on a file that
1278
// exists() should be a JVM regression test,
1279
// therefore we have permission to freak uot
1280
throw new RuntimeException JavaDoc(ioe.toString());
1281            }
1282        }
1283
1284        File JavaDoc webappBase = new File JavaDoc(uriRoot);
1285        if (webappBase.exists()) {
1286            File JavaDoc classes = new File JavaDoc(webappBase, "/WEB-INF/classes");
1287            try {
1288                if (classes.exists()) {
1289                    classPath = classPath + File.pathSeparator
1290                        + classes.getCanonicalPath();
1291                    urls.add(classes.getCanonicalFile().toURL());
1292                }
1293            } catch (IOException JavaDoc ioe) {
1294                // failing a toCanonicalPath on a file that
1295
// exists() should be a JVM regression test,
1296
// therefore we have permission to freak out
1297
throw new RuntimeException JavaDoc(ioe.toString());
1298            }
1299            File JavaDoc lib = new File JavaDoc(webappBase, "/WEB-INF/lib");
1300            if (lib.exists() && lib.isDirectory()) {
1301                String JavaDoc[] libs = lib.list();
1302                for (int i = 0; i < libs.length; i++) {
1303                    if( libs[i].length() <5 ) continue;
1304                    String JavaDoc ext=libs[i].substring( libs[i].length() - 4 );
1305                    if (! ".jar".equalsIgnoreCase(ext)) {
1306                        if (".tld".equalsIgnoreCase(ext)) {
1307                            log.warn("TLD files should not be placed in "
1308                                     + "/WEB-INF/lib");
1309                        }
1310                        continue;
1311                    }
1312                    try {
1313                        File JavaDoc libFile = new File JavaDoc(lib, libs[i]);
1314                        classPath = classPath + File.pathSeparator
1315                            + libFile.getAbsolutePath();
1316                        urls.add(libFile.getAbsoluteFile().toURL());
1317                    } catch (IOException JavaDoc ioe) {
1318                        // failing a toCanonicalPath on a file that
1319
// exists() should be a JVM regression test,
1320
// therefore we have permission to freak out
1321
throw new RuntimeException JavaDoc(ioe.toString());
1322                    }
1323                }
1324            }
1325        }
1326
1327        // What is this ??
1328
urls.add(new File JavaDoc(clctxt.getRealPath("/")).getCanonicalFile().toURL());
1329
1330        URL JavaDoc urlsA[]=new URL JavaDoc[urls.size()];
1331        urls.toArray(urlsA);
1332        loader = new URLClassLoader JavaDoc(urlsA, this.getClass().getClassLoader());
1333
1334    }
1335
1336    /**
1337     * Find the WEB-INF dir by looking up in the directory tree.
1338     * This is used if no explicit docbase is set, but only files.
1339     * XXX Maybe we should require the docbase.
1340     */

1341    protected void locateUriRoot( File JavaDoc f ) {
1342        String JavaDoc tUriBase = uriBase;
1343        if (tUriBase == null) {
1344            tUriBase = "/";
1345        }
1346        try {
1347            if (f.exists()) {
1348                f = new File JavaDoc(f.getAbsolutePath());
1349                while (f != null) {
1350                    File JavaDoc g = new File JavaDoc(f, "WEB-INF");
1351                    if (g.exists() && g.isDirectory()) {
1352                        uriRoot = f.getCanonicalPath();
1353                        uriBase = tUriBase;
1354                        if (log.isInfoEnabled()) {
1355                            log.info(Localizer.getMessage(
1356                                        "jspc.implicit.uriRoot",
1357                                        uriRoot));
1358                        }
1359                        break;
1360                    }
1361                    if (f.exists() && f.isDirectory()) {
1362                        tUriBase = "/" + f.getName() + "/" + tUriBase;
1363                    }
1364
1365                    String JavaDoc fParent = f.getParent();
1366                    if (fParent == null) {
1367                        break;
1368                    } else {
1369                        f = new File JavaDoc(fParent);
1370                    }
1371
1372                    // If there is no acceptible candidate, uriRoot will
1373
// remain null to indicate to the CompilerContext to
1374
// use the current working/user dir.
1375
}
1376
1377                if (uriRoot != null) {
1378                    File JavaDoc froot = new File JavaDoc(uriRoot);
1379                    uriRoot = froot.getCanonicalPath();
1380                }
1381            }
1382        } catch (IOException JavaDoc ioe) {
1383            // since this is an optional default and a null value
1384
// for uriRoot has a non-error meaning, we can just
1385
// pass straight through
1386
}
1387    }
1388
1389    /**
1390     * Resolves the relative or absolute pathname correctly
1391     * in both Ant and command-line situations. If Ant launched
1392     * us, we should use the basedir of the current project
1393     * to resolve relative paths.
1394     *
1395     * See Bugzilla 35571.
1396     *
1397     * @param s The file
1398     * @return The file resolved
1399     */

1400     protected File JavaDoc resolveFile(final String JavaDoc s) {
1401         if(getProject() == null) {
1402             // Note FileUtils.getFileUtils replaces FileUtils.newFileUtils in Ant 1.6.3
1403
return FileUtils.newFileUtils().resolveFile(null, s);
1404         } else {
1405             return FileUtils.newFileUtils().resolveFile(getProject().getBaseDir(), s);
1406         }
1407     }
1408}
1409
Popular Tags