Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
IncludeDirective |
|
| 6.384615384615385;6.385 |
1 | /* | |
2 | * Copyright (C) 1998-2000 Semiotek Inc. All Rights Reserved. | |
3 | * | |
4 | * Redistribution and use in source and binary forms, with or without | |
5 | * modification, are permitted under the terms of either of the following | |
6 | * Open Source licenses: | |
7 | * | |
8 | * The GNU General Public License, version 2, or any later version, as | |
9 | * published by the Free Software Foundation | |
10 | * (http://www.fsf.org/copyleft/gpl.html); | |
11 | * | |
12 | * or | |
13 | * | |
14 | * The Semiotek Public License (http://webmacro.org/LICENSE.) | |
15 | * | |
16 | * This software is provided "as is", with NO WARRANTY, not even the | |
17 | * implied warranties of fitness to purpose, or merchantability. You | |
18 | * assume all risks and liabilities associated with its use. | |
19 | * | |
20 | * See www.webmacro.org for more information on the WebMacro project. | |
21 | */ | |
22 | ||
23 | package org.webmacro.directive; | |
24 | ||
25 | import java.io.IOException; | |
26 | import java.io.InputStream; | |
27 | import java.net.URL; | |
28 | import java.net.URLConnection; | |
29 | import java.util.StringTokenizer; | |
30 | ||
31 | import org.slf4j.Logger; | |
32 | ||
33 | import org.webmacro.Broker; | |
34 | import org.webmacro.Context; | |
35 | import org.webmacro.FastWriter; | |
36 | import org.webmacro.Macro; | |
37 | import org.webmacro.NotFoundException; | |
38 | import org.webmacro.PropertyException; | |
39 | import org.webmacro.ResourceException; | |
40 | import org.webmacro.Template; | |
41 | import org.webmacro.TemplateVisitor; | |
42 | import org.webmacro.engine.BuildContext; | |
43 | import org.webmacro.engine.BuildException; | |
44 | ||
45 | /** | |
46 | * IncludeDirective allows you to include other text files or Templates into | |
47 | * the current Template. | |
48 | * <p> | |
49 | * Syntax:<pre> | |
50 | * #include [as text|template|macro] quoted-string-variable | |
51 | *</pre> | |
52 | * | |
53 | * <code>IncludeDirective</code> has 4 modes of operation which are detailed | |
54 | * below.<p> | |
55 | * | |
56 | * Please note that #include is now the preferred way to include files or | |
57 | * templates. Although you can still use #parse (in the same manner as | |
58 | * described below), its use has been deprecated.<p> | |
59 | * | |
60 | * <b>Including as text</b><br> | |
61 | * Including a file as text causes the raw bytes of the file to be included | |
62 | * in the current template. The file is <b>not</b> considered to be a Template, | |
63 | * and is not parsed by WebMacro. This allows you to include external files | |
64 | * that contain javascript or stylesheets without fear of mangling by WebMacro's | |
65 | * parser.<p> | |
66 | * | |
67 | * Files included as text are found using the default <code>URLProvider</code>. | |
68 | * If the URLProvider cannot find the file, the Broker is asked to find it. | |
69 | * This allows you to include files from any of the following places: | |
70 | * <li>other websites | |
71 | * <li>local filesystem | |
72 | * <li>active classpath<p> | |
73 | * | |
74 | * Files included as text are located once. Changes to the included file | |
75 | * will not be found by WebMacro!<p> | |
76 | * | |
77 | * Examples:<pre> | |
78 | * | |
79 | * // include your system password file (not a good idea! :) | |
80 | * #include as text "/etc/password" | |
81 | * | |
82 | * // include the WebMacro homepage | |
83 | * #include as text "http://www.webmacro.org" | |
84 | * | |
85 | * // inlude a file that is in your classpath | |
86 | * #include as text "somefile.txt" | |
87 | * | |
88 | * </pre><br> | |
89 | * | |
90 | * <b>Including as template</b><br> | |
91 | * Including a file as template causes the file to be parsed and evaluated | |
92 | * by WebMacro using the current <code>Context</code>. The evaluated output of | |
93 | * the Template is included in your main template.<p> | |
94 | * | |
95 | * Please note that files included "as template" that contains #macro's <b>DO NOT</b> | |
96 | * make their #macro's available to the outer template. See "Including as macro" below | |
97 | * for this.<p> | |
98 | * | |
99 | * Files included as template are found in your <code>TemplatePath</code>. | |
100 | * This path, if not explicitly set in <code>WebMacro.properties</code>, defaults | |
101 | * to the system classpath (standalone and JSDK 1.0), or the "web-app" directory | |
102 | * (JSDK 2.x).<p> | |
103 | * | |
104 | * Files included as templates are located and conditionally reloaded/parsed when | |
105 | * they change.<p> | |
106 | * | |
107 | * Examples:<pre> | |
108 | * | |
109 | * // include a global header template | |
110 | * #include as template "header.wm" | |
111 | * | |
112 | * // include a header template from a subdirectory of your TemplatePath | |
113 | * #include as template "common/header.wm" | |
114 | * | |
115 | * // include a header template using an absolute path in your TemplatePath | |
116 | * #include as template "/mysite/common/header.wm" | |
117 | * | |
118 | * </pre><br> | |
119 | * | |
120 | * <b>Including as macro</b><br> | |
121 | * Including a file as a macro is similiar to the above, except that #macro's | |
122 | * defined in the included file <b>are</b> made available to the outer template. | |
123 | * "Macro" templates are found using the same TemplatePath settings as | |
124 | * "#include as template".<p> | |
125 | * | |
126 | * Files included as macros are located once. Changes to the included template | |
127 | * will not be found by WebMacro!<p> | |
128 | * | |
129 | * Exapmles:<pre> | |
130 | * | |
131 | * // include a template with macros | |
132 | * #include as macro "my_macros.wm" | |
133 | * | |
134 | * </pre><br> | |
135 | * | |
136 | * | |
137 | * <b>Including without qualification</b><br></a> | |
138 | * Including a file without first qualifing it as a <i>text</i> file or | |
139 | * <i>template</i> causes <code>IncludeDirective</code> to make some educated | |
140 | * guesses about what type of file it is.<p> | |
141 | * | |
142 | * If the filename contains <code>://</code>, it is assumed to be a URL and is | |
143 | * treated as if it were a <code>text</code> file.<p> | |
144 | * | |
145 | * Else if the filename ends with any of the configured template file extensions | |
146 | * (see below), it is assumed to be a template.<p> | |
147 | * | |
148 | * Else it is assumed to be <code>text</code>.<p> | |
149 | * | |
150 | * Examples:<pre> | |
151 | * | |
152 | * // include homepage of WebMacro -- assumed to be "as text" | |
153 | * #include "http://www.webmacro.org/" | |
154 | * | |
155 | * // include a template -- assumed to be "as template" | |
156 | * #include "header.wm" | |
157 | * | |
158 | * // include a text file from local filesystem -- assumed to be "as text" | |
159 | * #include "somefile.txt" | |
160 | * | |
161 | * </pre> | |
162 | * | |
163 | * | |
164 | * <b><code>WebMacro.properties</code> Configuration Options</b><br> | |
165 | * | |
166 | * <code>include.TemplateExtensions</code>: list of file extensions<br> | |
167 | * This list of file extensions is used to determine the file type of an | |
168 | * unqualified #include'd file.<p> | |
169 | * | |
170 | * The default set of extensions are: <code>wm, wmt, tml</code> | |
171 | * | |
172 | * @author <a href=mailto:ebr@tcdi.com>Eric B. Ridge</a> | |
173 | * @since the beginning, but consolidated with #parse post 0.97 | |
174 | * | |
175 | */ | |
176 | 891 | public class IncludeDirective extends Directive |
177 | { | |
178 | ||
179 | /** The file to include is a Template. */ | |
180 | public static final int TYPE_TEMPLATE = 0; | |
181 | /** The file to include as a Template containing #macro's. */ | |
182 | public static final int TYPE_MACRO = 1; | |
183 | /** The file to include is a static file. */ | |
184 | public static final int TYPE_TEXT = 2; | |
185 | /** The file to include is unknown. */ | |
186 | public static final int TYPE_DYNAMIC = 3; | |
187 | ||
188 | ||
189 | private static final int PARSE_AS_K = 1; | |
190 | private static final int PARSE_TEMPLATE_K = 2; | |
191 | private static final int PARSE_TEXT_K = 3; | |
192 | private static final int PARSE_MACRO_K = 4; | |
193 | private static final int PARSE_FILENAME = 5; | |
194 | ||
195 | 40 | private static final ArgDescriptor[] _args = new ArgDescriptor[]{ |
196 | new OptionalGroup(4), | |
197 | new KeywordArg(PARSE_AS_K, "as"), | |
198 | new OptionalGroup(1), | |
199 | new KeywordArg(PARSE_TEMPLATE_K, "template"), | |
200 | new OptionalGroup(1), | |
201 | new KeywordArg(PARSE_TEXT_K, "text"), | |
202 | new OptionalGroup(1), | |
203 | new KeywordArg(PARSE_MACRO_K, "macro"), | |
204 | new QuotedStringArg(PARSE_FILENAME), | |
205 | }; | |
206 | 40 | private static final DirectiveDescriptor _desc = new DirectiveDescriptor("include", null, _args, null); |
207 | ||
208 | public static DirectiveDescriptor getDescriptor () | |
209 | { | |
210 | 126 | return _desc; |
211 | } | |
212 | ||
213 | ||
214 | // | |
215 | // these values are customized for this directive during build() | |
216 | // | |
217 | ||
218 | /** Place holder for the TemplateExtensions configuration key name. */ | |
219 | 891 | private String TEMPLATE_EXTENSIONS_NAME = ".TemplateExtensions"; |
220 | ||
221 | ||
222 | /** Logging can be good */ | |
223 | protected Logger _log; | |
224 | /** The included file type. | |
225 | * One of TYPE_TEMPLATE, TYPE_STATIC, TYPE_MACRO, or TYPE_DYNAMIC. */ | |
226 | protected int _type; | |
227 | /** The filename as a Macro, if the filename arg is a Macro. */ | |
228 | protected Macro _macFilename; | |
229 | /** | |
230 | * The filename as a String, if it is something we can determine during | |
231 | * build(). | |
232 | */ | |
233 | protected String _strFilename; | |
234 | /** | |
235 | * The name given to the directive by webmacro configuration. Used in | |
236 | * conjuction with the <code>StrictCompatibility</code> configuration | |
237 | * and to make determinitaions on how the #included file should be included. | |
238 | */ | |
239 | protected String _directiveName; | |
240 | ||
241 | /** | |
242 | * Build this use of the directive.<p> | |
243 | * | |
244 | * The specified file to include is included during <b>build/parse</b> | |
245 | * time if:<br> | |
246 | * 1) The specified filename is a String, not a $Variable; and<br> | |
247 | * 2) The "as" keyword is <b>"macro"</b>; or<br> | |
248 | * 3) if the <code>Lazy</code> configuration option is set for | |
249 | * this directive.<p> | |
250 | * | |
251 | * Otherwise, template is found and including during runtime evaluation | |
252 | * of this directive. | |
253 | */ | |
254 | public final Object build (DirectiveBuilder builder, BuildContext bc) | |
255 | throws BuildException | |
256 | { | |
257 | 891 | Broker broker = bc.getBroker(); |
258 | 891 | _log = bc.getLog("IncludeDirective"); |
259 | // build configuration key names, since they're based | |
260 | // on the configured name of this directive | |
261 | 891 | _directiveName = builder.getName(); |
262 | 891 | TEMPLATE_EXTENSIONS_NAME = _directiveName + TEMPLATE_EXTENSIONS_NAME; |
263 | ||
264 | // determine what type of file we need to deal with | |
265 | 891 | if (builder.getArg(PARSE_TEXT_K, bc) != null) |
266 | { | |
267 | 3 | _type = TYPE_TEXT; |
268 | } | |
269 | 888 | else if (builder.getArg(PARSE_TEMPLATE_K, bc) != null) |
270 | { | |
271 | 2 | _type = TYPE_TEMPLATE; |
272 | } | |
273 | 886 | else if (builder.getArg(PARSE_MACRO_K, bc) != null) |
274 | { | |
275 | 19 | _type = TYPE_MACRO; |
276 | } | |
277 | else | |
278 | { | |
279 | 867 | _type = TYPE_DYNAMIC; |
280 | } | |
281 | ||
282 | ||
283 | // if the filename passed to us was a Macro (needs to be evaluated later) | |
284 | // then store it as _macFilename. Otherwise, assume it's a String | |
285 | // and we'll just use that string as the filename | |
286 | 891 | Object o = builder.getArg(PARSE_FILENAME, bc); |
287 | 891 | if (o instanceof Macro) |
288 | { | |
289 | 527 | if (_type == TYPE_TEXT || _type == TYPE_MACRO) |
290 | { | |
291 | 0 | _log.warn("Included a 'static' file type using a dynamic filename. " |
292 | + "File will be included, but any included #macro's will not at " + bc.getCurrentLocation()); | |
293 | } | |
294 | 527 | _macFilename = (Macro) o; |
295 | } | |
296 | else | |
297 | { | |
298 | 364 | _strFilename = o.toString(); |
299 | 364 | if (_strFilename == null || _strFilename.length() == 0) |
300 | 0 | throw makeBuildException("Filename cannot be null or empty"); |
301 | ||
302 | ||
303 | 364 | if (_type == TYPE_TEXT) |
304 | { | |
305 | // we're a static type, need to | |
306 | // include the file (by returning it) now, | |
307 | // during build time | |
308 | try | |
309 | { | |
310 | 3 | return getThingToInclude(broker, _type, _strFilename); |
311 | } | |
312 | 0 | catch (Exception e) |
313 | { | |
314 | 0 | throw makeBuildException("Unable to include as text", e); |
315 | } | |
316 | } | |
317 | 361 | else if (_type == TYPE_MACRO) |
318 | { | |
319 | // we're a template type. ned to get the template (already parsed) | |
320 | // and merge its macros into our build context. | |
321 | // then we return the template so its contents can also be included | |
322 | 19 | Template t = null; |
323 | try | |
324 | { | |
325 | 19 | t = getTemplate(broker, _strFilename); |
326 | 19 | bc.mergeConstants(t); |
327 | } | |
328 | 0 | catch (Exception e) |
329 | { | |
330 | 0 | throw makeBuildException("Unable to include as macro", e); |
331 | 19 | } |
332 | try { | |
333 | 19 | return t.evaluateAsString(bc); |
334 | } | |
335 | 0 | catch (PropertyException e) { |
336 | 0 | return ""; |
337 | } | |
338 | } | |
339 | 342 | else if (_type == TYPE_DYNAMIC) |
340 | { | |
341 | // being dynamic means we need to guess the | |
342 | // file type based on the file's extension | |
343 | // and take care of finding the file during runtime | |
344 | 340 | _type = guessType(broker, _strFilename); |
345 | } | |
346 | ||
347 | } | |
348 | ||
349 | // we are configured to be lazy, or we couldn't determine the filename | |
350 | // during the build() process (b/c it is a Macro) | |
351 | 869 | return this; |
352 | } | |
353 | ||
354 | /** | |
355 | * Write out the included file to the specified FastWriter. If the | |
356 | * included file is actually a template, it is evaluated against the | |
357 | * <code>context</code> parameter before being written to the FastWriter | |
358 | */ | |
359 | public void write (FastWriter out, Context context) | |
360 | throws PropertyException, IOException | |
361 | { | |
362 | 1814 | Broker broker = context.getBroker(); |
363 | ||
364 | // the filename arg passed to us was a Macro, so | |
365 | // evaluate and check it now | |
366 | 1814 | if (_macFilename != null) |
367 | { | |
368 | 1472 | _strFilename = _macFilename.evaluate(context).toString(); |
369 | 1472 | if (_strFilename == null || _strFilename.length() == 0) |
370 | { | |
371 | 0 | throw makePropertyException("Filename cannot be null or empty"); |
372 | } | |
373 | } | |
374 | ||
375 | 1814 | if (_log.isDebugEnabled() && context.getCurrentLocation().indexOf(_strFilename) > -1) |
376 | { | |
377 | // when in debug mode, output a warning if a template tries to include itself | |
378 | // there are situations where this is desired, but it's good to make | |
379 | // the user aware of what they're doing | |
380 | 0 | _log.warn(context.getCurrentLocation() + " includes itself."); |
381 | } | |
382 | ||
383 | // this should only be true if StrictCompatibility is set to false | |
384 | // and "as <something>" wasn't specified in the arg list | |
385 | 1814 | if (_type == TYPE_DYNAMIC) |
386 | 527 | _type = guessType(broker, _strFilename); |
387 | ||
388 | 1814 | _log.debug("Including '" + _strFilename + "' as " |
389 | + ((_type == TYPE_MACRO) ? "MACRO" | |
390 | : (_type == TYPE_TEMPLATE) ? "TEMPLATE" | |
391 | : (_type == TYPE_TEXT) ? "TEXT" | |
392 | : "UNKNOWN. Throwing exception")); | |
393 | ||
394 | 1814 | Object toInclude = getThingToInclude(broker, _type, _strFilename); |
395 | 1814 | switch (_type) |
396 | { | |
397 | case TYPE_MACRO: | |
398 | // during runtime evaluation of a template, | |
399 | // a TYPE_MACRO doesn't really work as expected. | |
400 | // we logged a warning above in build(), but | |
401 | // we still need to write it out as a template | |
402 | // so just fall through | |
403 | case TYPE_TEMPLATE: | |
404 | 1791 | ((Template) toInclude).write(out, context); |
405 | 1791 | break; |
406 | ||
407 | case TYPE_TEXT: | |
408 | // static types are strings | |
409 | 23 | out.write(toInclude.toString()); |
410 | 23 | break; |
411 | ||
412 | default: | |
413 | // should never happen | |
414 | 0 | throw makePropertyException("Unrecognized file type: " + _type); |
415 | } | |
416 | 1814 | } |
417 | ||
418 | /** | |
419 | * Get an array of Template file extensions we should use, if type==dynamic, | |
420 | * to decide if the specified file is a template or not. | |
421 | */ | |
422 | protected String[] getTemplateExtensions (Broker b) | |
423 | { | |
424 | 866 | String[] ret = (String[]) b.getBrokerLocal(TEMPLATE_EXTENSIONS_NAME); |
425 | ||
426 | 866 | if (ret == null) |
427 | { | |
428 | 4 | String prop = b.getSettings().getSetting(TEMPLATE_EXTENSIONS_NAME, "wm"); |
429 | 4 | StringTokenizer st = new StringTokenizer(prop, ",; "); |
430 | 4 | ret = new String[st.countTokens()]; |
431 | 4 | int x = 0; |
432 | 24 | while (st.hasMoreElements()) |
433 | { | |
434 | 20 | ret[x] = st.nextToken(); |
435 | 20 | x++; |
436 | } | |
437 | ||
438 | 4 | b.setBrokerLocal(TEMPLATE_EXTENSIONS_NAME, ret); |
439 | } | |
440 | ||
441 | 866 | return ret; |
442 | } | |
443 | ||
444 | /** | |
445 | * If the filename contains <i>://</i> assume it's a file b/c it's probably | |
446 | * a url.<p> | |
447 | * | |
448 | * If the filename ends with any of the configured | |
449 | * <code>ParseDirective.TemplateExtensions</code>, assume it's a template.<p> | |
450 | * | |
451 | * Otherwise, it must be a file | |
452 | */ | |
453 | protected int guessType (Broker b, String filename) | |
454 | { | |
455 | 867 | if (filename.indexOf("://") > -1) |
456 | { | |
457 | 1 | return TYPE_TEXT; |
458 | } | |
459 | else | |
460 | { | |
461 | 866 | String[] extensions = getTemplateExtensions(b); |
462 | 976 | for (int x = 0; x < extensions.length; x++) |
463 | { | |
464 | 954 | if (filename.endsWith(extensions[x])) |
465 | 844 | return TYPE_TEMPLATE; |
466 | } | |
467 | } | |
468 | ||
469 | 22 | return TYPE_TEXT; |
470 | } | |
471 | ||
472 | /** | |
473 | * Get the template or file that the user wants to include, based on the | |
474 | * specified type. This method does not know how to get a file whose type. | |
475 | * is "TYPE_DYNAMIC". | |
476 | */ | |
477 | protected Object getThingToInclude (Broker b, int type, String filename) throws PropertyException | |
478 | { | |
479 | 1817 | switch (type) |
480 | { | |
481 | case TYPE_TEMPLATE: | |
482 | // wants to include a template | |
483 | 1791 | return getTemplate(b, filename); |
484 | ||
485 | case TYPE_MACRO: | |
486 | // wants to include a template | |
487 | 0 | return getTemplate(b, filename); |
488 | ||
489 | case TYPE_TEXT: | |
490 | // wants to include a static file | |
491 | 26 | return getFile(b, filename); |
492 | ||
493 | case TYPE_DYNAMIC: | |
494 | // this should never happen | |
495 | 0 | throw makePropertyException("Internal Error. Never guessed file type"); |
496 | ||
497 | default: | |
498 | // default case should never happen b/c we take care of this | |
499 | // during build() | |
500 | 0 | throw makePropertyException("Internal Error. Unrecognized file type: " + type); |
501 | } | |
502 | } | |
503 | ||
504 | /** | |
505 | * Get a Template via the "template" provider known by the specified broker. | |
506 | */ | |
507 | protected Template getTemplate (Broker b, String name) throws PropertyException | |
508 | { | |
509 | try | |
510 | { | |
511 | 1810 | return (Template) b.get("template", name); |
512 | } | |
513 | 0 | catch (NotFoundException nfe) |
514 | { | |
515 | 0 | throw makePropertyException("Not found by template provider"); |
516 | } | |
517 | 0 | catch (ResourceException re) |
518 | { | |
519 | 0 | throw makePropertyException("Unable to get template", re); |
520 | } | |
521 | 0 | catch (Exception e) |
522 | { | |
523 | 0 | throw makePropertyException("Unexpected exception while getting template"); |
524 | } | |
525 | } | |
526 | ||
527 | /** | |
528 | * Get the contents of a file (local file or url) via the "url" provider | |
529 | * known by the specified broker. If the url provider can't find it | |
530 | * we check the Broker (Broker.getResource). | |
531 | */ | |
532 | protected String getFile (Broker b, String name) throws PropertyException | |
533 | { | |
534 | try | |
535 | { | |
536 | // first, ask the URL provider (if we have one) to find the file for us | |
537 | 26 | return b.get("url", name).toString(); |
538 | } | |
539 | 0 | catch (Exception e) |
540 | { | |
541 | // for whatever reason, the URL provider couldn't find the file | |
542 | // (maybe we don't have a URL provider?). No matter, directly | |
543 | // ask the Broker to load it as a resource | |
544 | 0 | URL url = null; |
545 | ||
546 | try | |
547 | { | |
548 | 0 | url = b.getResource(name); |
549 | 0 | if (url == null) // doh! the Broker couldn't find it either. Guess it doesn't exist |
550 | 0 | throw makePropertyException("Resource not found by URL provider or Broker"); |
551 | ||
552 | // open a URLConnection... | |
553 | 0 | URLConnection conn = url.openConnection(); |
554 | 0 | StringBuffer sb = new StringBuffer(); |
555 | 0 | InputStream in = conn.getInputStream(); |
556 | 0 | String enc = conn.getContentEncoding(); |
557 | 0 | if (enc == null) |
558 | 0 | enc = b.getSetting("TemplateEncoding"); |
559 | ||
560 | // ...and stream the contents of the URL into a String | |
561 | 0 | int cnt = 0; |
562 | 0 | byte[] buff = new byte[4096]; |
563 | 0 | while ((cnt = in.read(buff)) > 0) |
564 | { | |
565 | 0 | sb.append(new String(buff, 0, cnt, enc)); |
566 | } | |
567 | 0 | in.close(); |
568 | ||
569 | // return the string form of the resource. | |
570 | // This is what will be included in the template | |
571 | 0 | return sb.toString(); |
572 | } | |
573 | 0 | catch (IOException ioe) |
574 | { | |
575 | 0 | throw makePropertyException("Error streaming file from: " + url, ioe); |
576 | } | |
577 | } | |
578 | } | |
579 | ||
580 | public void accept (TemplateVisitor v) | |
581 | { | |
582 | 0 | v.beginDirective(_desc.name); |
583 | 0 | v.visitDirectiveArg("IncludeDirective", _strFilename); |
584 | 0 | v.endDirective(); |
585 | 0 | } |
586 | ||
587 | // | |
588 | // helper methods for throwing exceptions | |
589 | // | |
590 | ||
591 | private BuildException makeBuildException (String message) | |
592 | { | |
593 | 0 | return makeBuildException(message, null); |
594 | } | |
595 | ||
596 | private BuildException makeBuildException (String message, Exception cause) | |
597 | { | |
598 | 0 | message = "#" + _directiveName + " " + _strFilename + ": " + message; |
599 | 0 | if (cause != null) |
600 | 0 | return new BuildException(message, cause); |
601 | else | |
602 | 0 | return new BuildException(message); |
603 | } | |
604 | ||
605 | private PropertyException makePropertyException (String message) | |
606 | { | |
607 | 0 | return makePropertyException(message, null); |
608 | } | |
609 | ||
610 | private PropertyException makePropertyException (String message, Exception cause) | |
611 | { | |
612 | 0 | message = "#" + _directiveName + " " + _strFilename + ": " + message; |
613 | 0 | if (cause != null) |
614 | 0 | return new PropertyException(message, cause); |
615 | else | |
616 | 0 | return new PropertyException(message); |
617 | } | |
618 | } | |
619 |