KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > xdoclet > tagshandler > MergeTagsHandler


1 /*
2  * Copyright (c) 2001, 2002 The XDoclet team
3  * All rights reserved.
4  */

5 package xdoclet.tagshandler;
6
7 import java.io.BufferedWriter JavaDoc;
8 import java.io.File JavaDoc;
9 import java.io.FileWriter JavaDoc;
10 import java.io.IOException JavaDoc;
11 import java.net.MalformedURLException JavaDoc;
12 import java.net.URL JavaDoc;
13 import java.text.MessageFormat JavaDoc;
14 import java.util.Properties JavaDoc;
15
16 import org.apache.commons.logging.Log;
17
18 import xdoclet.TemplateSubTask;
19 import xdoclet.XDocletException;
20 import xdoclet.XDocletTagSupport;
21 import xdoclet.template.PrettyPrintWriter;
22 import xdoclet.template.TemplateParser;
23 import xdoclet.util.FileManager;
24 import xdoclet.util.LogUtil;
25
26 /**
27  * @author Ara Abrahamian (ara_e@email.com)
28  * @created Oct 15, 2001
29  * @xdoclet.taghandler namespace="Merge"
30  * @version $Revision: 1.13 $
31  */

32 public class MergeTagsHandler extends XDocletTagSupport
33 {
34
35     /**
36      * Evaluates the body if the file exists specified by the "file" attribute.
37      *
38      * @param template The body of the block tag
39      * @param attributes The attributes of the template tag
40      * @exception XDocletException
41      * @doc.tag type="block"
42      * @doc.param name="file" optional="false" description="The path to the file to be merged. The
43      * value of this parameter can have {0} in it, if so {0} is replaced with the current class name and system
44      * searches for the file in in mergeDir+packageName directory. {0} is for cases where you want to define and
45      * merge a file per each class."
46      */

47     public void ifMergeFileExists(String JavaDoc template, Properties JavaDoc attributes) throws XDocletException
48     {
49         Log log = LogUtil.getLog(MergeTagsHandler.class, "ifMergeFileExists");
50         String JavaDoc merge_file_pattern = attributes.getProperty("file");
51
52         if (log.isDebugEnabled()) {
53             log.debug("Pattern = " + merge_file_pattern);
54         }
55         if (merge_file_pattern != null) {
56             // .j is deprecated as the template file extension
57
if (merge_file_pattern.endsWith(".j")) {
58                 log.warn("Deprecated template file extension used for merge file, .j should now be .xdt");
59                 merge_file_pattern = merge_file_pattern.substring(0, merge_file_pattern.length() - 2) + ".xdt";
60             }
61
62             String JavaDoc contents = getMergeFileContents(merge_file_pattern);
63
64             if (contents != null) {
65                 if (log.isDebugEnabled())
66                     log.debug("Merge File found");
67
68                 generate(template);
69
70             }
71         }
72         else {
73             log.error("<XDtMerge:ifMergeFileExists/> file parameter missing from template file.");
74         }
75     }
76
77     /**
78      * Merge contents of the file designated by the file parameter and evaluates the body if the file is not found. It
79      * searches for the file in the directory specified by mergeDir configuration parameter.
80      *
81      * @param template The body of the block tag
82      * @param attributes The attributes of the template tag
83      * @exception XDocletException XDocletException if something goes wrong
84      * @doc.tag type="block"
85      * @doc.param name="file" optional="false" description="The path to the file to be merged. The
86      * value of this parameter can have {0} in it, if so {0} is replaced with the current class name and system
87      * searches for the file in in mergeDir+packageName directory. {0} is for cases where you want to define and
88      * merge a file per each class."
89      * @doc.param name="generateMergedFile" values="true,false" description="If true then process the
90      * merged file also, otherwise only merge it and do not process it. True if the default."
91      */

92     public void merge(String JavaDoc template, Properties JavaDoc attributes) throws XDocletException
93     {
94
95         Log log = LogUtil.getLog(MergeTagsHandler.class, "merge");
96         String JavaDoc merge_file_pattern = attributes.getProperty("file");
97
98         if (log.isDebugEnabled()) {
99             log.debug("Pattern = " + merge_file_pattern);
100         }
101         if (merge_file_pattern != null) {
102             // .j is deprecated as the template file extension
103
if (merge_file_pattern.endsWith(".j")) {
104                 log.warn("Deprecated template file extension used for merge file, .j should now be .xdt");
105                 merge_file_pattern = merge_file_pattern.substring(0, merge_file_pattern.length() - 2) + ".xdt";
106             }
107
108             String JavaDoc contents = getMergeFileContents(merge_file_pattern);
109
110             if (contents != null) {
111                 if (log.isDebugEnabled())
112                     log.debug("Merge File found");
113
114                 String JavaDoc generate_merged_file = attributes.getProperty("generateMergedFile");
115
116                 if (generate_merged_file != null && !generate_merged_file.equalsIgnoreCase("true") && !generate_merged_file.equalsIgnoreCase("yes")) {
117                     getEngine().print(contents);
118                 }
119                 else {
120                     generateUsingMergedFile(merge_file_pattern, contents);
121                 }
122             }
123             else {
124                 if (log.isDebugEnabled()) {
125                     log.debug("Merge File NOT found");
126                 }
127
128                 // use body of <XDtMerge:merge>
129
generateUsingMergedFile(((TemplateSubTask) getDocletContext().getActiveSubTask()).getTemplateURL().toString(), template);
130             }
131         }
132         else {
133             log.error("<XDtMerge:merge/> file parameter missing from template file, ignoring merge command.");
134             generate(template);
135         }
136
137     }
138
139     /**
140      * A utility method used for merging a file used by <XDtMerge:merge/>tag. If the mergeFilePattern parameter has a
141      * {0} in it then the {0} is replaced with the sybolic class name of the current class, and the package structure of
142      * the class is prefixed to it. If not search is done for the exact file with the name specified in
143      * mergeFilePattern. Both of these two searches search for the file in root directory designated of mergeDir config
144      * parameter. It uses xdoclet.util.FileManager to load the file. FileManager caches the content so that subsequent
145      * tries to load the file are served from memory, without reloading the file again and again.
146      *
147      * @param mergeFilePattern The exact file name or a string that has a {0} in it. {0} is substituted by symbolic
148      * class name of current class.
149      * @return The content of the text file.
150      * @see #merge(java.lang.String,java.util.Properties)
151      * @see PackageTagsHandler#packageNameAsPathFor(xjavadoc.XPackage)
152      * @see ClassTagsHandler#symbolicClassName()
153      * @see xdoclet.util.FileManager
154      */

155     protected String JavaDoc getMergeFileContents(String JavaDoc mergeFilePattern)
156     {
157         Log log = LogUtil.getLog(MergeTagsHandler.class, "getMergeFileContents");
158
159         String JavaDoc file = null;
160
161         try {
162             if (mergeFilePattern.indexOf("{0}") != -1) {
163                 if (getEngine() instanceof TemplateParser) {
164                     ((TemplateParser) getEngine()).addMergeFile(mergeFilePattern);
165                 }
166                 else {
167
168                     String JavaDoc ejb_name = MessageFormat.format(mergeFilePattern, new Object JavaDoc[]{AbstractProgramElementTagsHandler.getClassNameFor(getCurrentClass())});
169                     String JavaDoc merge_file_name = PackageTagsHandler.packageNameAsPathWithoutSubstitutionFor(getCurrentClass().getContainingPackage()) + File.separator + ejb_name;
170
171                     if (getDocletContext().getActiveSubTask().getMergeDir() != null) {
172                         File JavaDoc mergeFile = new File JavaDoc(getDocletContext().getActiveSubTask().getMergeDir(), merge_file_name);
173
174                         log.debug("Search for File " + mergeFile);
175
176                         if (mergeFile.exists()) {
177                             log.debug("Search for File OK");
178                             file = FileManager.getURLContent(mergeFile.toURL());
179                         }
180                         else {
181                             // Backwards Compatibility - check for templates still using .j file extensions
182
if (merge_file_name.endsWith(".xdt")) {
183                                 log.debug(".xdt mergefile not found, trying .j");
184                                 mergeFile = new File JavaDoc(getDocletContext().getActiveSubTask().getMergeDir(),
185                                     merge_file_name.substring(0, merge_file_name.length() - 4) + ".j");
186                                 log.debug(".xdt mergefile not found, search for File " + mergeFile);
187
188                                 if (mergeFile.exists()) {
189                                     log.debug("Search for File OK");
190                                     file = FileManager.getURLContent(mergeFile.toURL());
191                                 }
192                                 else {
193                                     log.debug("Search for File not OK");
194                                 }
195                             }
196                             else {
197                                 log.debug("Search for File not OK");
198                             }
199                         }
200                     }
201                 }
202             }
203             else {
204                 if (getDocletContext().getActiveSubTask().getMergeDir() != null) {
205                     File JavaDoc mergeFile = new File JavaDoc(getDocletContext().getActiveSubTask().getMergeDir(), mergeFilePattern);
206
207                     if (getEngine() instanceof TemplateParser) {
208                         TemplateParser parser = (TemplateParser) getEngine();
209
210                         // This avoids infinite loop when a merge file merge itself
211
if (parser.hasMergeFile(mergeFilePattern)) {
212                             return null;
213                         }
214                         else {
215                             parser.addMergeFile(mergeFilePattern);
216                         }
217                     }
218
219                     if (mergeFile.exists()) {
220                         log.debug("Merge file found in " + getDocletContext().getActiveSubTask().getMergeDir());
221                         file = FileManager.getURLContent(mergeFile.toURL());
222                     }
223                     else {
224                         // Backwards Compatibility - check for templates still using .j file extensions
225
if (mergeFilePattern.endsWith(".xdt")) {
226                             mergeFile = new File JavaDoc(getDocletContext().getActiveSubTask().getMergeDir(),
227                                 mergeFilePattern.substring(0, mergeFilePattern.length() - 4) + ".j");
228                             log.debug(".xdt mergefile not found, trying " + mergeFile.getName());
229
230                             if (mergeFile.exists()) {
231                                 log.debug("Merge file found in " + getDocletContext().getActiveSubTask().getMergeDir());
232                                 file = FileManager.getURLContent(mergeFile.toURL());
233                             }
234                             else {
235                                 log.debug("Merge file NOT found in " + getDocletContext().getActiveSubTask().getMergeDir());
236                             }
237                         }
238                         else {
239                             log.debug("Merge file NOT found in " + getDocletContext().getActiveSubTask().getMergeDir());
240                         }
241                     }
242                 }
243             }
244             if (file != null)
245                 return file;
246
247             // was not found in mergedir, try the jar
248
URL JavaDoc jarResource = getClass().getResource('/' + mergeFilePattern);
249
250             if (jarResource != null) {
251                 log.debug("Merge file found in jar");
252
253                 if (getEngine() instanceof TemplateParser) {
254                     TemplateParser parser = (TemplateParser) getEngine();
255
256                     // This avoids infinite loop when a merge file merge itself
257
if (parser.hasMergeFile(mergeFilePattern)) {
258                         return null;
259                     }
260                     else {
261                         parser.addMergeFile(mergeFilePattern);
262                     }
263                 }
264
265                 file = FileManager.getURLContent(jarResource);
266             }
267             else {
268                 // not found on file system or in jar.
269
file = null;
270             }
271         }
272         catch (MalformedURLException JavaDoc e) {
273             log.error(e.getMessage(), e);
274             return null;
275         }
276         return file;
277     }
278
279     /**
280      * Processes the file specified in merge_file_pattern that has the text content contents. It resets currentLineNum
281      * to 0 upon calling generate() and restores it back to its previous value. It also sets and restores templateFile.
282      *
283      * @param mergeFile The file to be merged
284      * @param contents Description of Parameter
285      * @exception XDocletException Description of Exception
286      * @see xdoclet.template.TemplateEngine#setTemplateURL(java.net.URL)
287      */

288     protected void generateUsingMergedFile(String JavaDoc mergeFile, String JavaDoc contents) throws XDocletException
289     {
290         try {
291             int lineNumber = getEngine().getCurrentLineNum();
292             URL JavaDoc prevTemplateUrl = ((TemplateSubTask) getDocletContext().getActiveSubTask()).getTemplateURL();
293
294             getEngine().setTemplateURL(new File JavaDoc(mergeFile).toURL());
295             getEngine().setCurrentLineNum(0);
296
297             generate(contents);
298
299             getEngine().setTemplateURL(prevTemplateUrl);
300             getEngine().setCurrentLineNum(lineNumber);
301         }
302         catch (MalformedURLException JavaDoc e) {
303             throw new XDocletException(e.getMessage());
304         }
305     }
306
307     /**
308      * A utility method used for generating the dest_file based on template_file template file.
309      *
310      * @param dest_file the path to the destination file prepended by value of the destDir configuration
311      * parameter.
312      * @param templateFileName the template file name
313      * @exception XDocletException Description of Exception
314      */

315     protected void generateFileUsingTemplate(String JavaDoc dest_file, String JavaDoc templateFileName) throws XDocletException
316     {
317         Log log = LogUtil.getLog(MergeTagsHandler.class, "generateFileUsingTemplate");
318
319         getXJavaDoc().getSourceClasses();
320
321         File JavaDoc file = new File JavaDoc(getDocletContext().getDestDir(), dest_file);
322
323         /*
324          * File beanFile = new File( destDir.toString(), javaFile( fullClassName() ) );
325          * How to check modification timestamps???
326          * if( file.exists() )
327          * {
328          * if( file.lastModified() > beanFile.lastModified() )
329          * {
330          * continue;
331          * }
332          * }
333          */

334         file.getParentFile().mkdirs();
335
336         try {
337             getEngine().setTemplateURL(new File JavaDoc(templateFileName).toURL());
338
339             String JavaDoc content = FileManager.getURLContent(((TemplateSubTask) getDocletContext().getActiveSubTask()).getTemplateURL());
340
341             if (content != null) {
342                 try {
343                     PrettyPrintWriter out = new PrettyPrintWriter(new BufferedWriter JavaDoc(new FileWriter JavaDoc(file)));
344
345                     getEngine().setWriter(out);
346                     getEngine().setCurrentLineNum(0);
347                     generate(content);
348                     out.close();
349                 }
350                 catch (IOException JavaDoc ex) {
351                     log.error("An error occured while writing output to file " + file, ex);
352                 }
353             }
354         }
355         catch (MalformedURLException JavaDoc e) {
356             throw new XDocletException(e.getMessage());
357         }
358     }
359 }
360
Popular Tags