| 1 | /* | 
| 2 |  *   Copyright (C) Christian Schulte, 2005-206 | 
| 3 |  *   All rights reserved. | 
| 4 |  * | 
| 5 |  *   Redistribution and use in source and binary forms, with or without | 
| 6 |  *   modification, are permitted provided that the following conditions | 
| 7 |  *   are met: | 
| 8 |  * | 
| 9 |  *     o Redistributions of source code must retain the above copyright | 
| 10 |  *       notice, this list of conditions and the following disclaimer. | 
| 11 |  * | 
| 12 |  *     o Redistributions in binary form must reproduce the above copyright | 
| 13 |  *       notice, this list of conditions and the following disclaimer in | 
| 14 |  *       the documentation and/or other materials provided with the | 
| 15 |  *       distribution. | 
| 16 |  * | 
| 17 |  *   THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, | 
| 18 |  *   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY | 
| 19 |  *   AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL | 
| 20 |  *   THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT, | 
| 21 |  *   INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | 
| 22 |  *   NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 
| 23 |  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 
| 24 |  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 
| 25 |  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 
| 26 |  *   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
| 27 |  * | 
| 28 |  *   $JOMC: JomcTool.java 4709 2013-01-02 06:17:48Z schulte $ | 
| 29 |  * | 
| 30 |  */ | 
| 31 | package org.jomc.tools; | 
| 32 |   | 
| 33 | import java.io.BufferedReader; | 
| 34 | import java.io.ByteArrayInputStream; | 
| 35 | import java.io.ByteArrayOutputStream; | 
| 36 | import java.io.FileNotFoundException; | 
| 37 | import java.io.IOException; | 
| 38 | import java.io.InputStream; | 
| 39 | import java.io.InputStreamReader; | 
| 40 | import java.io.OutputStreamWriter; | 
| 41 | import java.io.Reader; | 
| 42 | import java.io.StringReader; | 
| 43 | import java.lang.ref.Reference; | 
| 44 | import java.lang.ref.SoftReference; | 
| 45 | import java.lang.reflect.InvocationTargetException; | 
| 46 | import java.net.URL; | 
| 47 | import java.text.DateFormat; | 
| 48 | import java.text.Format; | 
| 49 | import java.text.MessageFormat; | 
| 50 | import java.text.ParseException; | 
| 51 | import java.text.SimpleDateFormat; | 
| 52 | import java.util.ArrayList; | 
| 53 | import java.util.Calendar; | 
| 54 | import java.util.Collections; | 
| 55 | import java.util.Enumeration; | 
| 56 | import java.util.HashMap; | 
| 57 | import java.util.List; | 
| 58 | import java.util.Locale; | 
| 59 | import java.util.Map; | 
| 60 | import java.util.ResourceBundle; | 
| 61 | import java.util.Set; | 
| 62 | import java.util.concurrent.ConcurrentHashMap; | 
| 63 | import java.util.concurrent.CopyOnWriteArrayList; | 
| 64 | import java.util.concurrent.CopyOnWriteArraySet; | 
| 65 | import java.util.logging.Level; | 
| 66 | import javax.activation.MimeTypeParseException; | 
| 67 | import org.apache.commons.io.IOUtils; | 
| 68 | import org.apache.commons.lang.StringEscapeUtils; | 
| 69 | import org.apache.commons.lang.StringUtils; | 
| 70 | import org.apache.velocity.Template; | 
| 71 | import org.apache.velocity.VelocityContext; | 
| 72 | import org.apache.velocity.app.VelocityEngine; | 
| 73 | import org.apache.velocity.exception.ParseErrorException; | 
| 74 | import org.apache.velocity.exception.ResourceNotFoundException; | 
| 75 | import org.apache.velocity.exception.VelocityException; | 
| 76 | import org.apache.velocity.runtime.RuntimeConstants; | 
| 77 | import org.apache.velocity.runtime.RuntimeServices; | 
| 78 | import org.apache.velocity.runtime.log.LogChute; | 
| 79 | import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader; | 
| 80 | import org.apache.velocity.runtime.resource.loader.URLResourceLoader; | 
| 81 | import org.jomc.model.Argument; | 
| 82 | import org.jomc.model.Dependency; | 
| 83 | import org.jomc.model.Implementation; | 
| 84 | import org.jomc.model.InheritanceModel; | 
| 85 | import org.jomc.model.JavaIdentifier; | 
| 86 | import org.jomc.model.JavaTypeName; | 
| 87 | import org.jomc.model.Message; | 
| 88 | import org.jomc.model.ModelObject; | 
| 89 | import org.jomc.model.ModelObjectException; | 
| 90 | import org.jomc.model.Modules; | 
| 91 | import org.jomc.model.Multiplicity; | 
| 92 | import org.jomc.model.Property; | 
| 93 | import org.jomc.model.Specification; | 
| 94 | import org.jomc.model.SpecificationReference; | 
| 95 | import org.jomc.model.Text; | 
| 96 | import org.jomc.model.Texts; | 
| 97 | import org.jomc.model.modlet.ModelHelper; | 
| 98 | import org.jomc.modlet.Model; | 
| 99 |   | 
| 100 | /** | 
| 101 |  * Base tool class. | 
| 102 |  * | 
| 103 |  * @author <a href="mailto:cs@schulte.it">Christian Schulte</a> | 
| 104 |  * @version $JOMC: JomcTool.java 4709 2013-01-02 06:17:48Z schulte $ | 
| 105 |  */ | 
| 106 | public class JomcTool | 
| 107 | { | 
| 108 |   | 
| 109 |     /** Listener interface. */ | 
| 110 |     public abstract static class Listener | 
| 111 |     { | 
| 112 |   | 
| 113 |         /** Creates a new {@code Listener} instance. */ | 
| 114 |         public Listener() | 
| 115 |         { | 
| 116 |             super(); | 
| 117 |         } | 
| 118 |   | 
| 119 |         /** | 
| 120 |          * Gets called on logging. | 
| 121 |          * | 
| 122 |          * @param level The level of the event. | 
| 123 |          * @param message The message of the event or {@code null}. | 
| 124 |          * @param throwable The throwable of the event or {@code null}. | 
| 125 |          * | 
| 126 |          * @throws NullPointerException if {@code level} is {@code null}. | 
| 127 |          */ | 
| 128 |         public void onLog( final Level level, final String message, final Throwable throwable ) | 
| 129 |         { | 
| 130 |             if ( level == null ) | 
| 131 |             { | 
| 132 |                 throw new NullPointerException( "level" ); | 
| 133 |             } | 
| 134 |         } | 
| 135 |   | 
| 136 |     } | 
| 137 |   | 
| 138 |     /** Empty byte array. */ | 
| 139 |     private static final byte[] NO_BYTES = | 
| 140 |     { | 
| 141 |     }; | 
| 142 |   | 
| 143 |     /** The prefix of the template location. */ | 
| 144 |     private static final String TEMPLATE_PREFIX = | 
| 145 |         JomcTool.class.getPackage().getName().replace( '.', '/' ) + "/templates/"; | 
| 146 |   | 
| 147 |     /** Constant for the default template profile. */ | 
| 148 |     private static final String DEFAULT_TEMPLATE_PROFILE = "jomc-java"; | 
| 149 |   | 
| 150 |     /** | 
| 151 |      * Constant for the name of the template profile property specifying a parent template profile name. | 
| 152 |      * @since 1.3 | 
| 153 |      */ | 
| 154 |     private static final String PARENT_TEMPLATE_PROFILE_PROPERTY_NAME = "parent-template-profile"; | 
| 155 |   | 
| 156 |     /** | 
| 157 |      * Constant for the name of the template profile property specifying the template encoding. | 
| 158 |      * @since 1.3 | 
| 159 |      */ | 
| 160 |     private static final String TEMPLATE_ENCODING_PROFILE_PROPERTY_NAME = "template-encoding"; | 
| 161 |   | 
| 162 |     /** | 
| 163 |      * The default encoding to use for reading templates. | 
| 164 |      * @since 1.3 | 
| 165 |      */ | 
| 166 |     private String defaultTemplateEncoding; | 
| 167 |   | 
| 168 |     /** The default template profile. */ | 
| 169 |     private static volatile String defaultTemplateProfile; | 
| 170 |   | 
| 171 |     /** | 
| 172 |      * The log level events are logged at by default. | 
| 173 |      * @see #getDefaultLogLevel() | 
| 174 |      */ | 
| 175 |     private static final Level DEFAULT_LOG_LEVEL = Level.WARNING; | 
| 176 |   | 
| 177 |     /** The default log level. */ | 
| 178 |     private static volatile Level defaultLogLevel; | 
| 179 |   | 
| 180 |     /** The model of the instance. */ | 
| 181 |     private Model model; | 
| 182 |   | 
| 183 |     /** The {@code VelocityEngine} of the instance. */ | 
| 184 |     private VelocityEngine velocityEngine; | 
| 185 |   | 
| 186 |     /** | 
| 187 |      * Flag indicating the default {@code VelocityEngine}. | 
| 188 |      * @since 1.2.4 | 
| 189 |      */ | 
| 190 |     private boolean defaultVelocityEngine; | 
| 191 |   | 
| 192 |     /** | 
| 193 |      * The location to search for templates in addition to searching the class path. | 
| 194 |      * @since 1.2 | 
| 195 |      */ | 
| 196 |     private URL templateLocation; | 
| 197 |   | 
| 198 |     /** The encoding to use for reading files. */ | 
| 199 |     private String inputEncoding; | 
| 200 |   | 
| 201 |     /** The encoding to use for writing files. */ | 
| 202 |     private String outputEncoding; | 
| 203 |   | 
| 204 |     /** | 
| 205 |      * The template parameters. | 
| 206 |      * @since 1.2 | 
| 207 |      */ | 
| 208 |     private Map<String, Object> templateParameters; | 
| 209 |   | 
| 210 |     /** The template profile of the instance. */ | 
| 211 |     private String templateProfile; | 
| 212 |   | 
| 213 |     /** The indentation string of the instance. */ | 
| 214 |     private String indentation; | 
| 215 |   | 
| 216 |     /** The line separator of the instance. */ | 
| 217 |     private String lineSeparator; | 
| 218 |   | 
| 219 |     /** The listeners of the instance. */ | 
| 220 |     private List<Listener> listeners; | 
| 221 |   | 
| 222 |     /** The log level of the instance. */ | 
| 223 |     private Level logLevel; | 
| 224 |   | 
| 225 |     /** | 
| 226 |      * The locale of the instance. | 
| 227 |      * @since 1.2 | 
| 228 |      */ | 
| 229 |     private Locale locale; | 
| 230 |   | 
| 231 |     /** Cached indentation strings. */ | 
| 232 |     private volatile Reference<Map<String, String>> indentationCache; | 
| 233 |   | 
| 234 |     /** | 
| 235 |      * Cached templates. | 
| 236 |      * @since 1.3 | 
| 237 |      */ | 
| 238 |     private volatile Reference<Map<String, TemplateData>> templateCache; | 
| 239 |   | 
| 240 |     /** | 
| 241 |      * Cached template profile context properties. | 
| 242 |      * @since 1.3 | 
| 243 |      */ | 
| 244 |     private volatile Reference<Map<String, java.util.Properties>> templateProfileContextPropertiesCache; | 
| 245 |   | 
| 246 |     /** | 
| 247 |      * Cached template profile properties. | 
| 248 |      * @since 1.3 | 
| 249 |      */ | 
| 250 |     private volatile Reference<Map<String, java.util.Properties>> templateProfilePropertiesCache; | 
| 251 |   | 
| 252 |     /** Cached Java keywords. */ | 
| 253 |     private volatile Reference<Set<String>> javaKeywordsCache; | 
| 254 |   | 
| 255 |     /** Creates a new {@code JomcTool} instance. */ | 
| 256 |     public JomcTool() | 
| 257 |     { | 
| 258 |         super(); | 
| 259 |     } | 
| 260 |   | 
| 261 |     /** | 
| 262 |      * Creates a new {@code JomcTool} instance taking a {@code JomcTool} instance to initialize the new instance with. | 
| 263 |      * | 
| 264 |      * @param tool The instance to initialize the new instance with. | 
| 265 |      * | 
| 266 |      * @throws NullPointerException if {@code tool} is {@code null}. | 
| 267 |      * @throws IOException if copying {@code tool} fails. | 
| 268 |      */ | 
| 269 |     public JomcTool( final JomcTool tool ) throws IOException | 
| 270 |     { | 
| 271 |         this(); | 
| 272 |   | 
| 273 |         if ( tool == null ) | 
| 274 |         { | 
| 275 |             throw new NullPointerException( "tool" ); | 
| 276 |         } | 
| 277 |   | 
| 278 |         this.indentation = tool.indentation; | 
| 279 |         this.inputEncoding = tool.inputEncoding; | 
| 280 |         this.lineSeparator = tool.lineSeparator; | 
| 281 |         this.listeners = tool.listeners != null ? new CopyOnWriteArrayList<Listener>( tool.listeners ) : null; | 
| 282 |         this.logLevel = tool.logLevel; | 
| 283 |         this.model = tool.model != null ? tool.model.clone() : null; | 
| 284 |         this.outputEncoding = tool.outputEncoding; | 
| 285 |         this.defaultTemplateEncoding = tool.defaultTemplateEncoding; | 
| 286 |         this.templateProfile = tool.templateProfile; | 
| 287 |         this.velocityEngine = tool.velocityEngine; | 
| 288 |         this.defaultVelocityEngine = tool.defaultVelocityEngine; | 
| 289 |         this.locale = tool.locale; | 
| 290 |         this.templateParameters = | 
| 291 |             tool.templateParameters != null | 
| 292 |             ? Collections.synchronizedMap( new HashMap<String, Object>( tool.templateParameters ) ) | 
| 293 |             : null; | 
| 294 |   | 
| 295 |         this.templateLocation = | 
| 296 |             tool.templateLocation != null ? new URL( tool.templateLocation.toExternalForm() ) : null; | 
| 297 |   | 
| 298 |     } | 
| 299 |   | 
| 300 |     /** | 
| 301 |      * Gets the list of registered listeners. | 
| 302 |      * <p>This accessor method returns a reference to the live list, not a snapshot. Therefore any modification you make | 
| 303 |      * to the returned list will be present inside the object. This is why there is no {@code set} method for the | 
| 304 |      * listeners property.</p> | 
| 305 |      * | 
| 306 |      * @return The list of registered listeners. | 
| 307 |      * | 
| 308 |      * @see #log(java.util.logging.Level, java.lang.String, java.lang.Throwable) | 
| 309 |      */ | 
| 310 |     public List<Listener> getListeners() | 
| 311 |     { | 
| 312 |         if ( this.listeners == null ) | 
| 313 |         { | 
| 314 |             this.listeners = new CopyOnWriteArrayList<Listener>(); | 
| 315 |         } | 
| 316 |   | 
| 317 |         return this.listeners; | 
| 318 |     } | 
| 319 |   | 
| 320 |     /** | 
| 321 |      * Gets the default log level events are logged at. | 
| 322 |      * <p>The default log level is controlled by system property {@code org.jomc.tools.JomcTool.defaultLogLevel} holding | 
| 323 |      * the log level to log events at by default. If that property is not set, the {@code WARNING} default is | 
| 324 |      * returned.</p> | 
| 325 |      * | 
| 326 |      * @return The log level events are logged at by default. | 
| 327 |      * | 
| 328 |      * @see #getLogLevel() | 
| 329 |      * @see Level#parse(java.lang.String) | 
| 330 |      */ | 
| 331 |     public static Level getDefaultLogLevel() | 
| 332 |     { | 
| 333 |         if ( defaultLogLevel == null ) | 
| 334 |         { | 
| 335 |             defaultLogLevel = Level.parse( System.getProperty( "org.jomc.tools.JomcTool.defaultLogLevel", | 
| 336 |                                                                DEFAULT_LOG_LEVEL.getName() ) ); | 
| 337 |   | 
| 338 |         } | 
| 339 |   | 
| 340 |         return defaultLogLevel; | 
| 341 |     } | 
| 342 |   | 
| 343 |     /** | 
| 344 |      * Sets the default log level events are logged at. | 
| 345 |      * | 
| 346 |      * @param value The new default level events are logged at or {@code null}. | 
| 347 |      * | 
| 348 |      * @see #getDefaultLogLevel() | 
| 349 |      */ | 
| 350 |     public static void setDefaultLogLevel( final Level value ) | 
| 351 |     { | 
| 352 |         defaultLogLevel = value; | 
| 353 |     } | 
| 354 |   | 
| 355 |     /** | 
| 356 |      * Gets the log level of the instance. | 
| 357 |      * | 
| 358 |      * @return The log level of the instance. | 
| 359 |      * | 
| 360 |      * @see #getDefaultLogLevel() | 
| 361 |      * @see #setLogLevel(java.util.logging.Level) | 
| 362 |      * @see #isLoggable(java.util.logging.Level) | 
| 363 |      */ | 
| 364 |     public final Level getLogLevel() | 
| 365 |     { | 
| 366 |         if ( this.logLevel == null ) | 
| 367 |         { | 
| 368 |             this.logLevel = getDefaultLogLevel(); | 
| 369 |   | 
| 370 |             if ( this.isLoggable( Level.CONFIG ) ) | 
| 371 |             { | 
| 372 |                 this.log( Level.CONFIG, getMessage( "defaultLogLevelInfo", this.logLevel.getLocalizedName() ), null ); | 
| 373 |             } | 
| 374 |         } | 
| 375 |   | 
| 376 |         return this.logLevel; | 
| 377 |     } | 
| 378 |   | 
| 379 |     /** | 
| 380 |      * Sets the log level of the instance. | 
| 381 |      * | 
| 382 |      * @param value The new log level of the instance or {@code null}. | 
| 383 |      * | 
| 384 |      * @see #getLogLevel() | 
| 385 |      * @see #isLoggable(java.util.logging.Level) | 
| 386 |      */ | 
| 387 |     public final void setLogLevel( final Level value ) | 
| 388 |     { | 
| 389 |         this.logLevel = value; | 
| 390 |     } | 
| 391 |   | 
| 392 |     /** | 
| 393 |      * Checks if a message at a given level is provided to the listeners of the instance. | 
| 394 |      * | 
| 395 |      * @param level The level to test. | 
| 396 |      * | 
| 397 |      * @return {@code true}, if messages at {@code level} are provided to the listeners of the instance; | 
| 398 |      * {@code false}, if messages at {@code level} are not provided to the listeners of the instance. | 
| 399 |      * | 
| 400 |      * @throws NullPointerException if {@code level} is {@code null}. | 
| 401 |      * | 
| 402 |      * @see #getLogLevel() | 
| 403 |      * @see #setLogLevel(java.util.logging.Level) | 
| 404 |      * @see #log(java.util.logging.Level, java.lang.String, java.lang.Throwable) | 
| 405 |      */ | 
| 406 |     public boolean isLoggable( final Level level ) | 
| 407 |     { | 
| 408 |         if ( level == null ) | 
| 409 |         { | 
| 410 |             throw new NullPointerException( "level" ); | 
| 411 |         } | 
| 412 |   | 
| 413 |         return level.intValue() >= this.getLogLevel().intValue(); | 
| 414 |     } | 
| 415 |   | 
| 416 |     /** | 
| 417 |      * Gets the Java package name of a specification. | 
| 418 |      * | 
| 419 |      * @param specification The specification to get the Java package name of. | 
| 420 |      * | 
| 421 |      * @return The Java package name of {@code specification} or {@code null}, if the specification does not reference a | 
| 422 |      * type. | 
| 423 |      * | 
| 424 |      * @throws NullPointerException if {@code specification} is {@code null}. | 
| 425 |      * @throws ModelObjectException if compiling the name of the referenced type to a {@code JavaTypeName} fails. | 
| 426 |      * | 
| 427 |      * @see Specification#getJavaTypeName() | 
| 428 |      * @see JavaTypeName#getPackageName() | 
| 429 |      * | 
| 430 |      * @deprecated As of JOMC 1.4, please use method {@link Specification#getJavaTypeName()}. This method will be | 
| 431 |      * removed in JOMC 2.0. | 
| 432 |      */ | 
| 433 |     @Deprecated | 
| 434 |     public String getJavaPackageName( final Specification specification ) throws ModelObjectException | 
| 435 |     { | 
| 436 |         if ( specification == null ) | 
| 437 |         { | 
| 438 |             throw new NullPointerException( "specification" ); | 
| 439 |         } | 
| 440 |   | 
| 441 |         final JavaTypeName javaTypeName = specification.getJavaTypeName(); | 
| 442 |         return javaTypeName != null ? javaTypeName.getPackageName() : null; | 
| 443 |     } | 
| 444 |   | 
| 445 |     /** | 
| 446 |      * Gets the Java type name of a specification. | 
| 447 |      * | 
| 448 |      * @param specification The specification to get the Java type name of. | 
| 449 |      * @param qualified {@code true}, to return the fully qualified type name (with package name prepended); | 
| 450 |      * {@code false}, to return the short type name (without package name prepended). | 
| 451 |      * | 
| 452 |      * @return The Java type name of the type referenced by the specification or {@code null}, if the specification does | 
| 453 |      * not reference a type. | 
| 454 |      * | 
| 455 |      * @throws NullPointerException if {@code specification} is {@code null}. | 
| 456 |      * @throws ModelObjectException if compiling the name of the referenced type to a {@code JavaTypeName} fails. | 
| 457 |      * | 
| 458 |      * @see Specification#getJavaTypeName() | 
| 459 |      * @see JavaTypeName#getName(boolean) | 
| 460 |      * | 
| 461 |      * @deprecated As of JOMC 1.4, please use method {@link Specification#getJavaTypeName()}. This method will be | 
| 462 |      * removed in JOMC 2.0. | 
| 463 |      */ | 
| 464 |     @Deprecated | 
| 465 |     public String getJavaTypeName( final Specification specification, final boolean qualified ) | 
| 466 |         throws ModelObjectException | 
| 467 |     { | 
| 468 |         if ( specification == null ) | 
| 469 |         { | 
| 470 |             throw new NullPointerException( "specification" ); | 
| 471 |         } | 
| 472 |   | 
| 473 |         final JavaTypeName javaTypeName = specification.getJavaTypeName(); | 
| 474 |         return javaTypeName != null ? javaTypeName.getName( qualified ) : null; | 
| 475 |     } | 
| 476 |   | 
| 477 |     /** | 
| 478 |      * Gets the Java class path location of a specification. | 
| 479 |      * | 
| 480 |      * @param specification The specification to return the Java class path location of. | 
| 481 |      * | 
| 482 |      * @return The Java class path location of {@code specification} or {@code null}, if the specification does not | 
| 483 |      * reference a type. | 
| 484 |      * | 
| 485 |      * @throws NullPointerException if {@code specification} is {@code null}. | 
| 486 |      * @throws ModelObjectException if compiling the name of the referenced type to a {@code JavaTypeName} fails. | 
| 487 |      * | 
| 488 |      * @see Specification#getJavaTypeName() | 
| 489 |      * @see JavaTypeName#getQualifiedName() | 
| 490 |      * | 
| 491 |      * @deprecated As of JOMC 1.4, please use method {@link Specification#getJavaTypeName()}. This method will be | 
| 492 |      * removed in JOMC 2.0. | 
| 493 |      */ | 
| 494 |     @Deprecated | 
| 495 |     public String getJavaClasspathLocation( final Specification specification ) throws ModelObjectException | 
| 496 |     { | 
| 497 |         if ( specification == null ) | 
| 498 |         { | 
| 499 |             throw new NullPointerException( "specification" ); | 
| 500 |         } | 
| 501 |   | 
| 502 |         final JavaTypeName javaTypeName = specification.getJavaTypeName(); | 
| 503 |         return javaTypeName != null ? javaTypeName.getQualifiedName().replace( '.', '/' ) : null; | 
| 504 |     } | 
| 505 |   | 
| 506 |     /** | 
| 507 |      * Gets the Java package name of a specification reference. | 
| 508 |      * | 
| 509 |      * @param reference The specification reference to get the Java package name of. | 
| 510 |      * | 
| 511 |      * @return The Java package name of {@code reference} or {@code null}, if the referenced specification is not found | 
| 512 |      * or does not reference a type. | 
| 513 |      * | 
| 514 |      * @throws NullPointerException if {@code reference} is {@code null}. | 
| 515 |      * @throws ModelObjectException if compiling the name of the referenced type to a {@code JavaTypeName} fails. | 
| 516 |      * | 
| 517 |      * @see Modules#getSpecification(java.lang.String) | 
| 518 |      * @see Specification#getJavaTypeName() | 
| 519 |      * @see JavaTypeName#getPackageName() | 
| 520 |      * | 
| 521 |      * @deprecated As of JOMC 1.4, please use method {@link Specification#getJavaTypeName()}. This method will be | 
| 522 |      * removed in JOMC 2.0. | 
| 523 |      */ | 
| 524 |     @Deprecated | 
| 525 |     public String getJavaPackageName( final SpecificationReference reference ) throws ModelObjectException | 
| 526 |     { | 
| 527 |         if ( reference == null ) | 
| 528 |         { | 
| 529 |             throw new NullPointerException( "reference" ); | 
| 530 |         } | 
| 531 |   | 
| 532 |         Specification s = null; | 
| 533 |         String javaPackageName = null; | 
| 534 |   | 
| 535 |         if ( this.getModules() != null | 
| 536 |              && ( s = this.getModules().getSpecification( reference.getIdentifier() ) ) != null ) | 
| 537 |         { | 
| 538 |             final JavaTypeName javaTypeName = s.getJavaTypeName(); | 
| 539 |             javaPackageName = javaTypeName != null ? javaTypeName.getPackageName() : null; | 
| 540 |         } | 
| 541 |         else if ( this.isLoggable( Level.WARNING ) ) | 
| 542 |         { | 
| 543 |             this.log( Level.WARNING, getMessage( "specificationNotFound", reference.getIdentifier() ), null ); | 
| 544 |         } | 
| 545 |   | 
| 546 |         return javaPackageName; | 
| 547 |     } | 
| 548 |   | 
| 549 |     /** | 
| 550 |      * Gets the name of a Java type of a given specification reference. | 
| 551 |      * | 
| 552 |      * @param reference The specification reference to get a Java type name of. | 
| 553 |      * @param qualified {@code true}, to return the fully qualified type name (with package name prepended); | 
| 554 |      * {@code false}, to return the short type name (without package name prepended). | 
| 555 |      * | 
| 556 |      * @return The Java type name of {@code reference} or {@code null}, if the referenced specification is not found | 
| 557 |      * or does not reference a type. | 
| 558 |      * | 
| 559 |      * @throws NullPointerException if {@code reference} is {@code null}. | 
| 560 |      * @throws ModelObjectException if compiling the name of the referenced type to a {@code JavaTypeName} fails. | 
| 561 |      * | 
| 562 |      * @see Modules#getSpecification(java.lang.String) | 
| 563 |      * @see Specification#getJavaTypeName() | 
| 564 |      * @see JavaTypeName#getName(boolean) | 
| 565 |      * | 
| 566 |      * @deprecated As of JOMC 1.4, please use method {@link Specification#getJavaTypeName()}. This method will be | 
| 567 |      * removed in JOMC 2.0. | 
| 568 |      */ | 
| 569 |     @Deprecated | 
| 570 |     public String getJavaTypeName( final SpecificationReference reference, final boolean qualified ) | 
| 571 |         throws ModelObjectException | 
| 572 |     { | 
| 573 |         if ( reference == null ) | 
| 574 |         { | 
| 575 |             throw new NullPointerException( "reference" ); | 
| 576 |         } | 
| 577 |   | 
| 578 |         Specification s = null; | 
| 579 |         String typeName = null; | 
| 580 |   | 
| 581 |         if ( this.getModules() != null | 
| 582 |              && ( s = this.getModules().getSpecification( reference.getIdentifier() ) ) != null ) | 
| 583 |         { | 
| 584 |             final JavaTypeName javaTypeName = s.getJavaTypeName(); | 
| 585 |             typeName = javaTypeName != null ? javaTypeName.getName( qualified ) : null; | 
| 586 |         } | 
| 587 |         else if ( this.isLoggable( Level.WARNING ) ) | 
| 588 |         { | 
| 589 |             this.log( Level.WARNING, getMessage( "specificationNotFound", reference.getIdentifier() ), null ); | 
| 590 |         } | 
| 591 |   | 
| 592 |         return typeName; | 
| 593 |     } | 
| 594 |   | 
| 595 |     /** | 
| 596 |      * Gets the Java package name of an implementation. | 
| 597 |      * | 
| 598 |      * @param implementation The implementation to get the Java package name of. | 
| 599 |      * | 
| 600 |      * @return The Java package name of {@code implementation} or {@code null}, if the implementation does not reference | 
| 601 |      * a type. | 
| 602 |      * | 
| 603 |      * @throws NullPointerException if {@code implementation} is {@code null}. | 
| 604 |      * @throws ModelObjectException if compiling the name of the referenced type to a {@code JavaTypeName} fails. | 
| 605 |      * | 
| 606 |      * @see Implementation#getJavaTypeName() | 
| 607 |      * @see JavaTypeName#getPackageName() | 
| 608 |      * | 
| 609 |      * @deprecated As of JOMC 1.4, please use method {@link Implementation#getJavaTypeName()}. This method will be | 
| 610 |      * removed in JOMC 2.0. | 
| 611 |      */ | 
| 612 |     @Deprecated | 
| 613 |     public String getJavaPackageName( final Implementation implementation ) throws ModelObjectException | 
| 614 |     { | 
| 615 |         if ( implementation == null ) | 
| 616 |         { | 
| 617 |             throw new NullPointerException( "implementation" ); | 
| 618 |         } | 
| 619 |   | 
| 620 |         final JavaTypeName javaTypeName = implementation.getJavaTypeName(); | 
| 621 |         return javaTypeName != null ? javaTypeName.getPackageName() : null; | 
| 622 |     } | 
| 623 |   | 
| 624 |     /** | 
| 625 |      * Gets the Java type name of an implementation. | 
| 626 |      * | 
| 627 |      * @param implementation The implementation to get the Java type name of. | 
| 628 |      * @param qualified {@code true}, to return the fully qualified type name (with package name prepended); | 
| 629 |      * {@code false}, to return the short type name (without package name prepended). | 
| 630 |      * | 
| 631 |      * @return The Java type name of the type referenced by the implementation or {@code null}, if the implementation | 
| 632 |      * does not reference a type. | 
| 633 |      * | 
| 634 |      * @throws NullPointerException if {@code implementation} is {@code null}. | 
| 635 |      * @throws ModelObjectException if compiling the name of the referenced type to a {@code JavaTypeName} fails. | 
| 636 |      * | 
| 637 |      * @see Implementation#getJavaTypeName() | 
| 638 |      * @see JavaTypeName#getName(boolean) | 
| 639 |      * | 
| 640 |      * @deprecated As of JOMC 1.4, please use method {@link Implementation#getJavaTypeName()}. This method will be | 
| 641 |      * removed in JOMC 2.0. | 
| 642 |      */ | 
| 643 |     @Deprecated | 
| 644 |     public String getJavaTypeName( final Implementation implementation, final boolean qualified ) | 
| 645 |         throws ModelObjectException | 
| 646 |     { | 
| 647 |         if ( implementation == null ) | 
| 648 |         { | 
| 649 |             throw new NullPointerException( "implementation" ); | 
| 650 |         } | 
| 651 |   | 
| 652 |         final JavaTypeName javaTypeName = implementation.getJavaTypeName(); | 
| 653 |         return javaTypeName != null ? javaTypeName.getName( qualified ) : null; | 
| 654 |     } | 
| 655 |   | 
| 656 |     /** | 
| 657 |      * Gets the Java class path location of an implementation. | 
| 658 |      * | 
| 659 |      * @param implementation The implementation to return the Java class path location of. | 
| 660 |      * | 
| 661 |      * @return The Java class path location of {@code implementation} or {@code null}, if the implementation does not | 
| 662 |      * reference a type. | 
| 663 |      * | 
| 664 |      * @throws NullPointerException if {@code implementation} is {@code null}. | 
| 665 |      * @throws ModelObjectException if compiling the name of the referenced type to a {@code JavaTypeName} fails. | 
| 666 |      * | 
| 667 |      * @see Implementation#getJavaTypeName() | 
| 668 |      * @see JavaTypeName#getQualifiedName() | 
| 669 |      * | 
| 670 |      * @deprecated As of JOMC 1.4, please use method {@link Implementation#getJavaTypeName()}. This method will be | 
| 671 |      * removed in JOMC 2.0. | 
| 672 |      */ | 
| 673 |     @Deprecated | 
| 674 |     public String getJavaClasspathLocation( final Implementation implementation ) throws ModelObjectException | 
| 675 |     { | 
| 676 |         if ( implementation == null ) | 
| 677 |         { | 
| 678 |             throw new NullPointerException( "implementation" ); | 
| 679 |         } | 
| 680 |   | 
| 681 |         final JavaTypeName javaTypeName = implementation.getJavaTypeName(); | 
| 682 |         return javaTypeName != null ? javaTypeName.getQualifiedName().replace( '.', '/' ) : null; | 
| 683 |     } | 
| 684 |   | 
| 685 |     /** | 
| 686 |      * Gets a list of names of all Java types an implementation implements. | 
| 687 |      * | 
| 688 |      * @param implementation The implementation to get names of all implemented Java types of. | 
| 689 |      * @param qualified {@code true}, to return the fully qualified type names (with package name prepended); | 
| 690 |      * {@code false}, to return the short type names (without package name prepended). | 
| 691 |      * | 
| 692 |      * @return An unmodifiable list of names of all Java types implemented by {@code implementation}. | 
| 693 |      * | 
| 694 |      * @throws NullPointerException if {@code implementation} is {@code null}. | 
| 695 |      * @throws ModelObjectException if compiling the name of a referenced type to a {@code JavaTypeName} fails. | 
| 696 |      * | 
| 697 |      * @deprecated As of JOMC 1.2, replaced by method {@link #getImplementedJavaTypeNames(org.jomc.model.Implementation, boolean)}. | 
| 698 |      * This method will be removed in version 2.0. | 
| 699 |      */ | 
| 700 |     @Deprecated | 
| 701 |     public List<String> getJavaInterfaceNames( final Implementation implementation, final boolean qualified ) | 
| 702 |         throws ModelObjectException | 
| 703 |     { | 
| 704 |         if ( implementation == null ) | 
| 705 |         { | 
| 706 |             throw new NullPointerException( "implementation" ); | 
| 707 |         } | 
| 708 |   | 
| 709 |         return this.getImplementedJavaTypeNames( implementation, qualified ); | 
| 710 |     } | 
| 711 |   | 
| 712 |     /** | 
| 713 |      * Gets a list of names of all Java types an implementation implements. | 
| 714 |      * | 
| 715 |      * @param implementation The implementation to get names of all implemented Java types of. | 
| 716 |      * @param qualified {@code true}, to return the fully qualified type names (with package name prepended); | 
| 717 |      * {@code false}, to return the short type names (without package name prepended). | 
| 718 |      * | 
| 719 |      * @return An unmodifiable list of names of all Java types implemented by {@code implementation}. | 
| 720 |      * | 
| 721 |      * @throws NullPointerException if {@code implementation} is {@code null}. | 
| 722 |      * @throws ModelObjectException if compiling the name of the referenced type to a {@code JavaTypeName} fails. | 
| 723 |      * | 
| 724 |      * @since 1.2 | 
| 725 |      * | 
| 726 |      * @see Implementation#getJavaTypeNames(org.jomc.model.Modules) | 
| 727 |      * | 
| 728 |      * @deprecated As of JOMC 1.4, please use method {@link Modules#getImplementedJavaTypeNames(java.lang.String)}. | 
| 729 |      * This method will be removed in JOMC 2.0. | 
| 730 |      */ | 
| 731 |     @Deprecated | 
| 732 |     public List<String> getImplementedJavaTypeNames( final Implementation implementation, final boolean qualified ) | 
| 733 |         throws ModelObjectException | 
| 734 |     { | 
| 735 |         if ( implementation == null ) | 
| 736 |         { | 
| 737 |             throw new NullPointerException( "implementation" ); | 
| 738 |         } | 
| 739 |   | 
| 740 |         List<String> col = null; | 
| 741 |   | 
| 742 |         if ( this.getModules() != null ) | 
| 743 |         { | 
| 744 |             final List<JavaTypeName> javaTypeNames = | 
| 745 |                 this.getModules().getImplementedJavaTypeNames( implementation.getIdentifier() ); | 
| 746 |   | 
| 747 |             if ( javaTypeNames != null ) | 
| 748 |             { | 
| 749 |                 col = new ArrayList<String>( javaTypeNames.size() ); | 
| 750 |   | 
| 751 |                 for ( int i = 0, s0 = javaTypeNames.size(); i < s0; i++ ) | 
| 752 |                 { | 
| 753 |                     if ( !col.contains( javaTypeNames.get( i ).getName( qualified ) ) ) | 
| 754 |                     { | 
| 755 |                         col.add( javaTypeNames.get( i ).getName( qualified ) ); | 
| 756 |                     } | 
| 757 |                 } | 
| 758 |             } | 
| 759 |         } | 
| 760 |         else if ( this.isLoggable( Level.WARNING ) ) | 
| 761 |         { | 
| 762 |             this.log( Level.WARNING, getMessage( "modulesNotFound", this.getModel().getIdentifier() ), null ); | 
| 763 |         } | 
| 764 |   | 
| 765 |         return Collections.unmodifiableList( col != null ? col : Collections.<String>emptyList() ); | 
| 766 |     } | 
| 767 |   | 
| 768 |     /** | 
| 769 |      * Gets the Java type name of an argument. | 
| 770 |      * | 
| 771 |      * @param argument The argument to get the Java type name of. | 
| 772 |      * | 
| 773 |      * @return The Java type name of the type referenced by the argument or {@code null}, if the argument does not | 
| 774 |      * reference a type. | 
| 775 |      * | 
| 776 |      * @throws NullPointerException if {@code argument} is {@code null}. | 
| 777 |      * @throws ModelObjectException if compiling the name of the referenced type to a {@code JavaTypeName} fails. | 
| 778 |      * | 
| 779 |      * @see Argument#getJavaTypeName() | 
| 780 |      * @see JavaTypeName#getName(boolean) | 
| 781 |      * | 
| 782 |      * @deprecated As of JOMC 1.4, please use method {@link Argument#getJavaTypeName()}. This method will be removed in | 
| 783 |      * JOMC 2.0. | 
| 784 |      */ | 
| 785 |     @Deprecated | 
| 786 |     public String getJavaTypeName( final Argument argument ) throws ModelObjectException | 
| 787 |     { | 
| 788 |         if ( argument == null ) | 
| 789 |         { | 
| 790 |             throw new NullPointerException( "argument" ); | 
| 791 |         } | 
| 792 |   | 
| 793 |         final JavaTypeName javaTypeName = argument.getJavaTypeName(); | 
| 794 |         return javaTypeName != null ? javaTypeName.getName( true ) : null; | 
| 795 |     } | 
| 796 |   | 
| 797 |     /** | 
| 798 |      * Gets a Java method parameter name of an argument. | 
| 799 |      * | 
| 800 |      * @param argument The argument to get the Java method parameter name of. | 
| 801 |      * | 
| 802 |      * @return The Java method parameter name of {@code argument}. | 
| 803 |      * | 
| 804 |      * @throws NullPointerException if {@code argument} is {@code null}. | 
| 805 |      * @throws ModelObjectException if compiling the name of the argument to a {@code JavaIdentifier} fails. | 
| 806 |      * | 
| 807 |      * @see Argument#getJavaVariableName() | 
| 808 |      * | 
| 809 |      * @since 1.2 | 
| 810 |      * | 
| 811 |      * @deprecated As of JOMC 1.4, please use method {@link Argument#getJavaVariableName()}. This method will be | 
| 812 |      * removed in JOMC 2.0. | 
| 813 |      */ | 
| 814 |     @Deprecated | 
| 815 |     public String getJavaMethodParameterName( final Argument argument ) throws ModelObjectException | 
| 816 |     { | 
| 817 |         if ( argument == null ) | 
| 818 |         { | 
| 819 |             throw new NullPointerException( "argument" ); | 
| 820 |         } | 
| 821 |   | 
| 822 |         return this.getJavaMethodParameterName( argument.getName() ); | 
| 823 |     } | 
| 824 |   | 
| 825 |     /** | 
| 826 |      * Gets the Java type name of a property. | 
| 827 |      * | 
| 828 |      * @param property The property to get the Java type name of. | 
| 829 |      * @param boxify {@code true}, to return the name of the Java wrapper class when the type is a Java primitive type; | 
| 830 |      * {@code false}, to return the exact binary name (unboxed name) of the Java type. | 
| 831 |      * | 
| 832 |      * @return The Java type name of the type referenced by the property or {@code null}, if the property does not | 
| 833 |      * reference a type. | 
| 834 |      * | 
| 835 |      * @throws NullPointerException if {@code property} is {@code null}. | 
| 836 |      * @throws ModelObjectException if compiling the name of the referenced type to a {@code JavaTypeName} fails. | 
| 837 |      * | 
| 838 |      * @see Property#getJavaTypeName() | 
| 839 |      * @see JavaTypeName#getBoxedName() | 
| 840 |      * @see JavaTypeName#getName(boolean) | 
| 841 |      * | 
| 842 |      * @deprecated As of JOMC 1.4, please use method {@link Property#getJavaTypeName()}. This method will be removed in | 
| 843 |      * JOMC 2.0. | 
| 844 |      */ | 
| 845 |     @Deprecated | 
| 846 |     public String getJavaTypeName( final Property property, final boolean boxify ) throws ModelObjectException | 
| 847 |     { | 
| 848 |         if ( property == null ) | 
| 849 |         { | 
| 850 |             throw new NullPointerException( "property" ); | 
| 851 |         } | 
| 852 |   | 
| 853 |         JavaTypeName javaTypeName = property.getJavaTypeName(); | 
| 854 |   | 
| 855 |         if ( javaTypeName != null ) | 
| 856 |         { | 
| 857 |             if ( boxify && javaTypeName.isPrimitive() ) | 
| 858 |             { | 
| 859 |                 javaTypeName = javaTypeName.getBoxedName(); | 
| 860 |             } | 
| 861 |   | 
| 862 |             return javaTypeName.getName( true ); | 
| 863 |         } | 
| 864 |   | 
| 865 |         return null; | 
| 866 |     } | 
| 867 |   | 
| 868 |     /** | 
| 869 |      * Gets a flag indicating the type of a given property is a Java primitive. | 
| 870 |      * | 
| 871 |      * @param property The property to query. | 
| 872 |      * | 
| 873 |      * @return {@code true}, if the Java type referenced by the property is primitive or {@code false}, if the property | 
| 874 |      * does not reference a type or if the Java type referenced by the property is not primitive. | 
| 875 |      * | 
| 876 |      * @throws NullPointerException if {@code property} is {@code null}. | 
| 877 |      * @throws ModelObjectException if compiling the name of the referenced type to a {@code JavaTypeName} fails. | 
| 878 |      * | 
| 879 |      * @see Property#getJavaTypeName() | 
| 880 |      * @see JavaTypeName#isPrimitive() | 
| 881 |      * | 
| 882 |      * @deprecated As of JOMC 1.4, please use method {@link Property#getJavaTypeName()}. This method will be removed in | 
| 883 |      * JOMC 2.0. | 
| 884 |      */ | 
| 885 |     @Deprecated | 
| 886 |     public boolean isJavaPrimitiveType( final Property property ) throws ModelObjectException | 
| 887 |     { | 
| 888 |         if ( property == null ) | 
| 889 |         { | 
| 890 |             throw new NullPointerException( "property" ); | 
| 891 |         } | 
| 892 |   | 
| 893 |         final JavaTypeName javaTypeName = property.getJavaTypeName(); | 
| 894 |         return javaTypeName != null && javaTypeName.isPrimitive(); | 
| 895 |     } | 
| 896 |   | 
| 897 |     /** | 
| 898 |      * Gets the name of a Java getter method of a given property. | 
| 899 |      * | 
| 900 |      * @param property The property to get a Java getter method name of. | 
| 901 |      * | 
| 902 |      * @return The Java getter method name of {@code property}. | 
| 903 |      * | 
| 904 |      * @throws NullPointerException if {@code property} is {@code null}. | 
| 905 |      * @throws ModelObjectException if compiling the name of the property to a {@code JavaIdentifier} fails. | 
| 906 |      * | 
| 907 |      * @see Property#getJavaGetterMethodName() | 
| 908 |      * | 
| 909 |      * @deprecated As of JOMC 1.4, please use method {@link Property#getJavaGetterMethodName()}. This method will be | 
| 910 |      * removed in JOMC 2.0. | 
| 911 |      */ | 
| 912 |     @Deprecated | 
| 913 |     public String getJavaGetterMethodName( final Property property ) throws ModelObjectException | 
| 914 |     { | 
| 915 |         if ( property == null ) | 
| 916 |         { | 
| 917 |             throw new NullPointerException( "property" ); | 
| 918 |         } | 
| 919 |   | 
| 920 |         String prefix = "get"; | 
| 921 |   | 
| 922 |         final String javaTypeName = this.getJavaTypeName( property, true ); | 
| 923 |         if ( Boolean.class.getName().equals( javaTypeName ) ) | 
| 924 |         { | 
| 925 |             prefix = "is"; | 
| 926 |         } | 
| 927 |   | 
| 928 |         return prefix + this.getJavaIdentifier( property.getName(), true ); | 
| 929 |     } | 
| 930 |   | 
| 931 |     /** | 
| 932 |      * Gets the name of a Java setter method of a given property. | 
| 933 |      * | 
| 934 |      * @param property The property to get a Java setter method name of. | 
| 935 |      * | 
| 936 |      * @return The Java setter method name of {@code property}. | 
| 937 |      * | 
| 938 |      * @throws NullPointerException if {@code property} is {@code null}. | 
| 939 |      * @throws ModelObjectException if compiling the name of the property to a {@code JavaIdentifier} fails. | 
| 940 |      * | 
| 941 |      * @see Property#getJavaSetterMethodName() | 
| 942 |      * | 
| 943 |      * @since 1.2 | 
| 944 |      * | 
| 945 |      * @deprecated As of JOMC 1.4, please use method {@link Property#getJavaSetterMethodName()}. This method will be | 
| 946 |      * removed in JOMC 2.0. | 
| 947 |      */ | 
| 948 |     @Deprecated | 
| 949 |     public String getJavaSetterMethodName( final Property property ) throws ModelObjectException | 
| 950 |     { | 
| 951 |         if ( property == null ) | 
| 952 |         { | 
| 953 |             throw new NullPointerException( "property" ); | 
| 954 |         } | 
| 955 |   | 
| 956 |         return "set" + this.getJavaIdentifier( property.getName(), true ); | 
| 957 |     } | 
| 958 |   | 
| 959 |     /** | 
| 960 |      * Gets a Java method parameter name of a property. | 
| 961 |      * | 
| 962 |      * @param property The property to get the Java method parameter name of. | 
| 963 |      * | 
| 964 |      * @return The Java method parameter name of {@code property}. | 
| 965 |      * | 
| 966 |      * @throws NullPointerException if {@code property} is {@code null}. | 
| 967 |      * @throws ModelObjectException if copmiling the name of the property to a {@code JavaIdentifier} fails. | 
| 968 |      * | 
| 969 |      * @see Property#getJavaVariableName() | 
| 970 |      * | 
| 971 |      * @since 1.2 | 
| 972 |      * | 
| 973 |      * @deprecated As of JOMC 1.4, please use method {@link Property#getJavaVariableName()}. This method will be | 
| 974 |      * removed in JOMC 2.0. | 
| 975 |      */ | 
| 976 |     @Deprecated | 
| 977 |     public String getJavaMethodParameterName( final Property property ) throws ModelObjectException | 
| 978 |     { | 
| 979 |         if ( property == null ) | 
| 980 |         { | 
| 981 |             throw new NullPointerException( "property" ); | 
| 982 |         } | 
| 983 |   | 
| 984 |         return this.getJavaMethodParameterName( property.getName() ); | 
| 985 |     } | 
| 986 |   | 
| 987 |     /** | 
| 988 |      * Gets a Java field name of a property. | 
| 989 |      * | 
| 990 |      * @param property The property to get the Java field name of. | 
| 991 |      * | 
| 992 |      * @return The Java field name of {@code property}. | 
| 993 |      * | 
| 994 |      * @throws NullPointerException if {@code property} is {@code null}. | 
| 995 |      * @throws ModelObjectException if compiling the name of the property to a {@code JavaIdentifier} fails. | 
| 996 |      * | 
| 997 |      * @see Property#getJavaVariableName() | 
| 998 |      * | 
| 999 |      * @since 1.3 | 
| 1000 |      * | 
| 1001 |      * @deprecated As of JOMC 1.4, please use method {@link Property#getJavaVariableName()}. This method will be removed | 
| 1002 |      * in JOMC 2.0. | 
| 1003 |      */ | 
| 1004 |     @Deprecated | 
| 1005 |     public String getJavaFieldName( final Property property ) throws ModelObjectException | 
| 1006 |     { | 
| 1007 |         if ( property == null ) | 
| 1008 |         { | 
| 1009 |             throw new NullPointerException( "property" ); | 
| 1010 |         } | 
| 1011 |   | 
| 1012 |         return this.getJavaFieldName( property.getName() ); | 
| 1013 |     } | 
| 1014 |   | 
| 1015 |     /** | 
| 1016 |      * Gets the name of a Java type of a given dependency. | 
| 1017 |      * | 
| 1018 |      * @param dependency The dependency to get a dependency Java type name of. | 
| 1019 |      * | 
| 1020 |      * @return The Java type name of the dependency or {@code null}, if the referenced specification is not found or | 
| 1021 |      * does not reference a type. | 
| 1022 |      * | 
| 1023 |      * @throws NullPointerException if {@code dependency} is {@code null}. | 
| 1024 |      * @throws ModelObjectException if compiling the name of the referenced type to a {@code JavaTypeName} fails. | 
| 1025 |      * | 
| 1026 |      * @see Dependency#getJavaTypeName(org.jomc.model.Modules) | 
| 1027 |      * @see JavaTypeName#getName(boolean) | 
| 1028 |      * | 
| 1029 |      * @deprecated As of JOMC 1.4, please use method {@link Modules#getDependencyJavaTypeName(java.lang.String, java.lang.String)}. | 
| 1030 |      * This method will be removed in JOMC 2.0. | 
| 1031 |      */ | 
| 1032 |     @Deprecated | 
| 1033 |     public String getJavaTypeName( final Dependency dependency ) throws ModelObjectException | 
| 1034 |     { | 
| 1035 |         if ( dependency == null ) | 
| 1036 |         { | 
| 1037 |             throw new NullPointerException( "dependency" ); | 
| 1038 |         } | 
| 1039 |   | 
| 1040 |         Specification s = null; | 
| 1041 |         StringBuilder typeName = null; | 
| 1042 |         String javaTypeName = null; | 
| 1043 |   | 
| 1044 |         try | 
| 1045 |         { | 
| 1046 |             if ( this.getModules() != null | 
| 1047 |                  && ( s = this.getModules().getSpecification( dependency.getIdentifier() ) ) != null ) | 
| 1048 |             { | 
| 1049 |                 if ( s.getClazz() != null ) | 
| 1050 |                 { | 
| 1051 |                     typeName = new StringBuilder( s.getClazz().length() ); | 
| 1052 |                     typeName.append( this.getJavaTypeName( s, true ) ); | 
| 1053 |   | 
| 1054 |                     if ( s.getMultiplicity() == Multiplicity.MANY && dependency.getImplementationName() == null ) | 
| 1055 |                     { | 
| 1056 |                         typeName.append( "[]" ); | 
| 1057 |                     } | 
| 1058 |   | 
| 1059 |                     javaTypeName = JavaTypeName.parse( typeName.toString() ).getName( true ); | 
| 1060 |                 } | 
| 1061 |             } | 
| 1062 |             else if ( this.isLoggable( Level.WARNING ) ) | 
| 1063 |             { | 
| 1064 |                 this.log( Level.WARNING, getMessage( "specificationNotFound", dependency.getIdentifier() ), null ); | 
| 1065 |             } | 
| 1066 |   | 
| 1067 |             return javaTypeName; | 
| 1068 |         } | 
| 1069 |         catch ( final ParseException e ) | 
| 1070 |         { | 
| 1071 |             throw new ModelObjectException( getMessage( "dependencyJavaTypeNameParseException", typeName, | 
| 1072 |                                                         getMessage( e ) ), e ); | 
| 1073 |   | 
| 1074 |         } | 
| 1075 |     } | 
| 1076 |   | 
| 1077 |     /** | 
| 1078 |      * Gets the name of a Java getter method of a given dependency. | 
| 1079 |      * | 
| 1080 |      * @param dependency The dependency to get a Java getter method name of. | 
| 1081 |      * | 
| 1082 |      * @return The Java getter method name of {@code dependency}. | 
| 1083 |      * | 
| 1084 |      * @throws NullPointerException if {@code dependency} is {@code null}. | 
| 1085 |      * @throws ModelObjectException if compiling the name of the dependency to a {@code JavaIdentifier} fails. | 
| 1086 |      * | 
| 1087 |      * @see Dependency#getJavaGetterMethodName() | 
| 1088 |      * | 
| 1089 |      * @deprecated As of JOMC 1.4, please use method {@link Dependency#getJavaGetterMethodName()}. This method will be | 
| 1090 |      * removed in JOMC 2.0. | 
| 1091 |      */ | 
| 1092 |     @Deprecated | 
| 1093 |     public String getJavaGetterMethodName( final Dependency dependency ) throws ModelObjectException | 
| 1094 |     { | 
| 1095 |         if ( dependency == null ) | 
| 1096 |         { | 
| 1097 |             throw new NullPointerException( "dependency" ); | 
| 1098 |         } | 
| 1099 |   | 
| 1100 |         return "get" + this.getJavaIdentifier( dependency.getName(), true ); | 
| 1101 |     } | 
| 1102 |   | 
| 1103 |     /** | 
| 1104 |      * Gets the name of a Java setter method of a given dependency. | 
| 1105 |      * | 
| 1106 |      * @param dependency The dependency to get a Java setter method name of. | 
| 1107 |      * | 
| 1108 |      * @return The Java setter method name of {@code dependency}. | 
| 1109 |      * | 
| 1110 |      * @throws NullPointerException if {@code dependency} is {@code null}. | 
| 1111 |      * @throws ModelObjectException if compiling the name of the dependency to a {@code JavaIdentifier} fails. | 
| 1112 |      * | 
| 1113 |      * @see Dependency#getJavaSetterMethodName() | 
| 1114 |      * | 
| 1115 |      * @since 1.2 | 
| 1116 |      * | 
| 1117 |      * @deprecated As of JOMC 1.4, please use method {@link Dependency#getJavaSetterMethodName()}. This method will be | 
| 1118 |      * removed in JOMC 2.0. | 
| 1119 |      */ | 
| 1120 |     @Deprecated | 
| 1121 |     public String getJavaSetterMethodName( final Dependency dependency ) throws ModelObjectException | 
| 1122 |     { | 
| 1123 |         if ( dependency == null ) | 
| 1124 |         { | 
| 1125 |             throw new NullPointerException( "dependency" ); | 
| 1126 |         } | 
| 1127 |   | 
| 1128 |         return "set" + this.getJavaIdentifier( dependency.getName(), true ); | 
| 1129 |     } | 
| 1130 |   | 
| 1131 |     /** | 
| 1132 |      * Gets a Java method parameter name of a dependency. | 
| 1133 |      * | 
| 1134 |      * @param dependency The dependency to get the Java method parameter name of. | 
| 1135 |      * | 
| 1136 |      * @return The Java method parameter name of {@code dependency}. | 
| 1137 |      * | 
| 1138 |      * @throws NullPointerException if {@code dependency} is {@code null}. | 
| 1139 |      * @throws ModelObjectException if compiling the name of the dependency to a {@code JavaIdentifier} fails. | 
| 1140 |      * | 
| 1141 |      * @see Dependency#getJavaVariableName() | 
| 1142 |      * | 
| 1143 |      * @since 1.2 | 
| 1144 |      * | 
| 1145 |      * @deprecated As of JOMC 1.4, please use method {@link Dependency#getJavaVariableName()}. This method will be | 
| 1146 |      * removed in JOMC 2.0. | 
| 1147 |      */ | 
| 1148 |     @Deprecated | 
| 1149 |     public String getJavaMethodParameterName( final Dependency dependency ) throws ModelObjectException | 
| 1150 |     { | 
| 1151 |         if ( dependency == null ) | 
| 1152 |         { | 
| 1153 |             throw new NullPointerException( "dependency" ); | 
| 1154 |         } | 
| 1155 |   | 
| 1156 |         return this.getJavaMethodParameterName( dependency.getName() ); | 
| 1157 |     } | 
| 1158 |   | 
| 1159 |     /** | 
| 1160 |      * Gets a Java field name of a dependency. | 
| 1161 |      * | 
| 1162 |      * @param dependency The dependency to get the Java field name of. | 
| 1163 |      * | 
| 1164 |      * @return The Java field name of {@code dependency}. | 
| 1165 |      * | 
| 1166 |      * @throws NullPointerException if {@code dependency} is {@code null}. | 
| 1167 |      * @throws ModelObjectException if compiling the name of the dependency to a {@code JavaIdentifier} fails. | 
| 1168 |      * | 
| 1169 |      * @see Dependency#getJavaVariableName() | 
| 1170 |      * | 
| 1171 |      * @since 1.3 | 
| 1172 |      * | 
| 1173 |      * @deprecated As of JOMC 1.4, please use method {@link Dependency#getJavaVariableName()}. This method will be | 
| 1174 |      * removed in JOMC 2.0. | 
| 1175 |      */ | 
| 1176 |     @Deprecated | 
| 1177 |     public String getJavaFieldName( final Dependency dependency ) throws ModelObjectException | 
| 1178 |     { | 
| 1179 |         if ( dependency == null ) | 
| 1180 |         { | 
| 1181 |             throw new NullPointerException( "dependency" ); | 
| 1182 |         } | 
| 1183 |   | 
| 1184 |         return this.getJavaFieldName( dependency.getName() ); | 
| 1185 |     } | 
| 1186 |   | 
| 1187 |     /** | 
| 1188 |      * Gets the name of a Java getter method of a given message. | 
| 1189 |      * | 
| 1190 |      * @param message The message to get a Java getter method name of. | 
| 1191 |      * | 
| 1192 |      * @return The Java getter method name of {@code message}. | 
| 1193 |      * | 
| 1194 |      * @throws NullPointerException if {@code message} is {@code null}. | 
| 1195 |      * @throws ModelObjectException if compiling the name of the message to a {@code JavaIdentifier} fails. | 
| 1196 |      * | 
| 1197 |      * @see Message#getJavaGetterMethodName() | 
| 1198 |      * | 
| 1199 |      * @deprecated As of JOMC 1.4, please use method {@link Message#getJavaGetterMethodName()}. This method will be | 
| 1200 |      * removed in JOMC 2.0. | 
| 1201 |      */ | 
| 1202 |     @Deprecated | 
| 1203 |     public String getJavaGetterMethodName( final Message message ) throws ModelObjectException | 
| 1204 |     { | 
| 1205 |         if ( message == null ) | 
| 1206 |         { | 
| 1207 |             throw new NullPointerException( "message" ); | 
| 1208 |         } | 
| 1209 |   | 
| 1210 |         return "get" + this.getJavaIdentifier( message.getName(), true ); | 
| 1211 |     } | 
| 1212 |   | 
| 1213 |     /** | 
| 1214 |      * Gets the name of a Java setter method of a given message. | 
| 1215 |      * | 
| 1216 |      * @param message The message to get a Java setter method name of. | 
| 1217 |      * | 
| 1218 |      * @return The Java setter method name of {@code message}. | 
| 1219 |      * | 
| 1220 |      * @throws NullPointerException if {@code message} is {@code null}. | 
| 1221 |      * @throws ModelObjectException if compiling the name of the message to a {@code JavaIdentifier} fails. | 
| 1222 |      * | 
| 1223 |      * @see Message#getJavaSetterMethodName() | 
| 1224 |      * | 
| 1225 |      * @since 1.2 | 
| 1226 |      * | 
| 1227 |      * @deprecated As of JOMC 1.4, please use method {@link Message#getJavaSetterMethodName()}. This method will be | 
| 1228 |      * removed in JOMC 2.0. | 
| 1229 |      */ | 
| 1230 |     @Deprecated | 
| 1231 |     public String getJavaSetterMethodName( final Message message ) throws ModelObjectException | 
| 1232 |     { | 
| 1233 |         if ( message == null ) | 
| 1234 |         { | 
| 1235 |             throw new NullPointerException( "message" ); | 
| 1236 |         } | 
| 1237 |   | 
| 1238 |         return "set" + this.getJavaIdentifier( message.getName(), true ); | 
| 1239 |     } | 
| 1240 |   | 
| 1241 |     /** | 
| 1242 |      * Gets a Java method parameter name of a message. | 
| 1243 |      * | 
| 1244 |      * @param message The message to get the Java method parameter name of. | 
| 1245 |      * | 
| 1246 |      * @return The Java method parameter name of {@code message}. | 
| 1247 |      * | 
| 1248 |      * @throws NullPointerException if {@code message} is {@code null}. | 
| 1249 |      * @throws ModelObjectException if compiling the name of the message to a {@code JavaIdentifier} fails. | 
| 1250 |      * | 
| 1251 |      * @see Message#getJavaVariableName() | 
| 1252 |      * | 
| 1253 |      * @since 1.2 | 
| 1254 |      * | 
| 1255 |      * @deprecated As of JOMC 1.4, please use method {@link Message#getJavaVariableName()}. This method will be removed | 
| 1256 |      * in JOMC 2.0. | 
| 1257 |      */ | 
| 1258 |     @Deprecated | 
| 1259 |     public String getJavaMethodParameterName( final Message message ) throws ModelObjectException | 
| 1260 |     { | 
| 1261 |         if ( message == null ) | 
| 1262 |         { | 
| 1263 |             throw new NullPointerException( "message" ); | 
| 1264 |         } | 
| 1265 |   | 
| 1266 |         return this.getJavaMethodParameterName( message.getName() ); | 
| 1267 |     } | 
| 1268 |   | 
| 1269 |     /** | 
| 1270 |      * Gets a Java field name of a message. | 
| 1271 |      * | 
| 1272 |      * @param message The message to get the Java field name of. | 
| 1273 |      * | 
| 1274 |      * @return The Java field name of {@code message}. | 
| 1275 |      * | 
| 1276 |      * @throws NullPointerException if {@code message} is {@code null}. | 
| 1277 |      * @throws ModelObjectException if compiling the name of the message to a {@code JavaIdentifier} fails. | 
| 1278 |      * | 
| 1279 |      * @see Message#getJavaVariableName() | 
| 1280 |      * | 
| 1281 |      * @since 1.3 | 
| 1282 |      * | 
| 1283 |      * @deprecated As of JOMC 1.4, please use method {@link Message#getJavaVariableName()}. This method will be removed | 
| 1284 |      * in JOMC 2.0. | 
| 1285 |      */ | 
| 1286 |     @Deprecated | 
| 1287 |     public String getJavaFieldName( final Message message ) throws ModelObjectException | 
| 1288 |     { | 
| 1289 |         if ( message == null ) | 
| 1290 |         { | 
| 1291 |             throw new NullPointerException( "message" ); | 
| 1292 |         } | 
| 1293 |   | 
| 1294 |         return this.getJavaFieldName( message.getName() ); | 
| 1295 |     } | 
| 1296 |   | 
| 1297 |     /** | 
| 1298 |      * Gets the Java modifier name of a dependency of a given implementation. | 
| 1299 |      * | 
| 1300 |      * @param implementation The implementation declaring the dependency to get a Java modifier name of. | 
| 1301 |      * @param dependency The dependency to get a Java modifier name of. | 
| 1302 |      * | 
| 1303 |      * @return The Java modifier name of {@code dependency} of {@code implementation}. | 
| 1304 |      * | 
| 1305 |      * @throws NullPointerException if {@code implementation} or {@code dependency} is {@code null}. | 
| 1306 |      * | 
| 1307 |      * @deprecated As of JOMC 1.4, please use method {@link Modules#getDependencyJavaModifierName(java.lang.String, java.lang.String)}. | 
| 1308 |      * This method will be removed in JOMC 2.0. | 
| 1309 |      */ | 
| 1310 |     @Deprecated | 
| 1311 |     public String getJavaModifierName( final Implementation implementation, final Dependency dependency ) | 
| 1312 |     { | 
| 1313 |         if ( implementation == null ) | 
| 1314 |         { | 
| 1315 |             throw new NullPointerException( "implementation" ); | 
| 1316 |         } | 
| 1317 |         if ( dependency == null ) | 
| 1318 |         { | 
| 1319 |             throw new NullPointerException( "dependency" ); | 
| 1320 |         } | 
| 1321 |   | 
| 1322 |         String modifierName = "private"; | 
| 1323 |   | 
| 1324 |         if ( this.getModules() != null ) | 
| 1325 |         { | 
| 1326 |             modifierName = | 
| 1327 |                 this.getModules().getDependencyJavaModifierName( implementation.getIdentifier(), dependency.getName() ); | 
| 1328 |   | 
| 1329 |             if ( modifierName == null ) | 
| 1330 |             { | 
| 1331 |                 modifierName = "private"; | 
| 1332 |             } | 
| 1333 |         } | 
| 1334 |   | 
| 1335 |         return modifierName; | 
| 1336 |     } | 
| 1337 |   | 
| 1338 |     /** | 
| 1339 |      * Gets the Java modifier name of a message of a given implementation. | 
| 1340 |      * | 
| 1341 |      * @param implementation The implementation declaring the message to get a Java modifier name of. | 
| 1342 |      * @param message The message to get a Java modifier name of. | 
| 1343 |      * | 
| 1344 |      * @return The Java modifier name of {@code message} of {@code implementation}. | 
| 1345 |      * | 
| 1346 |      * @throws NullPointerException if {@code implementation} or {@code message} is {@code null}. | 
| 1347 |      * | 
| 1348 |      * @deprecated As of JOMC 1.4, please use method {@link Modules#getMessageJavaModifierName(java.lang.String, java.lang.String)}. | 
| 1349 |      * This method will be removed in JOMC 2.0. | 
| 1350 |      */ | 
| 1351 |     @Deprecated | 
| 1352 |     public String getJavaModifierName( final Implementation implementation, final Message message ) | 
| 1353 |     { | 
| 1354 |         if ( implementation == null ) | 
| 1355 |         { | 
| 1356 |             throw new NullPointerException( "implementation" ); | 
| 1357 |         } | 
| 1358 |         if ( message == null ) | 
| 1359 |         { | 
| 1360 |             throw new NullPointerException( "message" ); | 
| 1361 |         } | 
| 1362 |   | 
| 1363 |         String modifierName = "private"; | 
| 1364 |   | 
| 1365 |         if ( this.getModules() != null ) | 
| 1366 |         { | 
| 1367 |             modifierName = | 
| 1368 |                 this.getModules().getMessageJavaModifierName( implementation.getIdentifier(), message.getName() ); | 
| 1369 |   | 
| 1370 |             if ( modifierName == null ) | 
| 1371 |             { | 
| 1372 |                 modifierName = "private"; | 
| 1373 |             } | 
| 1374 |         } | 
| 1375 |   | 
| 1376 |         return modifierName; | 
| 1377 |     } | 
| 1378 |   | 
| 1379 |     /** | 
| 1380 |      * Gets the Java modifier name of a property of a given implementation. | 
| 1381 |      * | 
| 1382 |      * @param implementation The implementation declaring the property to get a Java modifier name of. | 
| 1383 |      * @param property The property to get a Java modifier name of. | 
| 1384 |      * | 
| 1385 |      * @return The Java modifier name of {@code property} of {@code implementation}. | 
| 1386 |      * | 
| 1387 |      * @throws NullPointerException if {@code implementation} or {@code property} is {@code null}. | 
| 1388 |      * | 
| 1389 |      * @deprecated As of JOMC 1.4, please use method {@link Modules#getPropertyJavaModifierName(java.lang.String, java.lang.String)}. | 
| 1390 |      * This method will be removed in JOMC 2.0. | 
| 1391 |      */ | 
| 1392 |     @Deprecated | 
| 1393 |     public String getJavaModifierName( final Implementation implementation, final Property property ) | 
| 1394 |     { | 
| 1395 |         if ( implementation == null ) | 
| 1396 |         { | 
| 1397 |             throw new NullPointerException( "implementation" ); | 
| 1398 |         } | 
| 1399 |         if ( property == null ) | 
| 1400 |         { | 
| 1401 |             throw new NullPointerException( "property" ); | 
| 1402 |         } | 
| 1403 |   | 
| 1404 |         String modifierName = "private"; | 
| 1405 |   | 
| 1406 |         if ( this.getModules() != null ) | 
| 1407 |         { | 
| 1408 |             modifierName = | 
| 1409 |                 this.getModules().getPropertyJavaModifierName( implementation.getIdentifier(), property.getName() ); | 
| 1410 |   | 
| 1411 |             if ( modifierName == null ) | 
| 1412 |             { | 
| 1413 |                 modifierName = "private"; | 
| 1414 |             } | 
| 1415 |         } | 
| 1416 |   | 
| 1417 |         return modifierName; | 
| 1418 |     } | 
| 1419 |   | 
| 1420 |     /** | 
| 1421 |      * Formats a text to a Javadoc comment. | 
| 1422 |      * | 
| 1423 |      * @param text The text to format to a Javadoc comment. | 
| 1424 |      * @param indentationLevel The indentation level of the comment. | 
| 1425 |      * @param linePrefix The text to prepend lines with. | 
| 1426 |      * | 
| 1427 |      * @return {@code text} formatted to a Javadoc comment. | 
| 1428 |      * | 
| 1429 |      * @throws NullPointerException if {@code text} or {@code linePrefix} is {@code null}. | 
| 1430 |      * @throws IllegalArgumentException if {@code indentationLevel} is negative. | 
| 1431 |      * @throws ModelObjectException if compiling the type of the text to a {@code MimeType} fails. | 
| 1432 |      * | 
| 1433 |      * @deprecated As of JOMC 1.4, please use method {@link Text#getJavadocComment(java.lang.String, java.lang.String)}. | 
| 1434 |      * This method will be removed in JOMC 2.0. | 
| 1435 |      */ | 
| 1436 |     @Deprecated | 
| 1437 |     public String getJavadocComment( final Text text, final int indentationLevel, final String linePrefix ) | 
| 1438 |         throws ModelObjectException | 
| 1439 |     { | 
| 1440 |         if ( text == null ) | 
| 1441 |         { | 
| 1442 |             throw new NullPointerException( "text" ); | 
| 1443 |         } | 
| 1444 |         if ( linePrefix == null ) | 
| 1445 |         { | 
| 1446 |             throw new NullPointerException( "linePrefix" ); | 
| 1447 |         } | 
| 1448 |         if ( indentationLevel < 0 ) | 
| 1449 |         { | 
| 1450 |             throw new IllegalArgumentException( Integer.toString( indentationLevel ) ); | 
| 1451 |         } | 
| 1452 |   | 
| 1453 |         BufferedReader reader = null; | 
| 1454 |         boolean suppressExceptionOnClose = true; | 
| 1455 |   | 
| 1456 |         try | 
| 1457 |         { | 
| 1458 |             String javadoc = ""; | 
| 1459 |   | 
| 1460 |             if ( text.getValue() != null ) | 
| 1461 |             { | 
| 1462 |                 final String indent = this.getIndentation( indentationLevel ); | 
| 1463 |                 reader = new BufferedReader( new StringReader( text.getValue() ) ); | 
| 1464 |                 final StringBuilder builder = new StringBuilder( text.getValue().length() ); | 
| 1465 |   | 
| 1466 |                 String line; | 
| 1467 |                 while ( ( line = reader.readLine() ) != null ) | 
| 1468 |                 { | 
| 1469 |                     builder.append( this.getLineSeparator() ).append( indent ).append( linePrefix ). | 
| 1470 |                         append( line.replaceAll( "\\/\\*\\*", "/*" ).replaceAll( "\\*/", "/" ) ); | 
| 1471 |   | 
| 1472 |                 } | 
| 1473 |   | 
| 1474 |                 if ( builder.length() > 0 ) | 
| 1475 |                 { | 
| 1476 |                     javadoc = | 
| 1477 |                         builder.substring( this.getLineSeparator().length() + indent.length() + linePrefix.length() ); | 
| 1478 |   | 
| 1479 |                     if ( !text.getMimeType().match( "text/html" ) ) | 
| 1480 |                     { | 
| 1481 |                         javadoc = StringEscapeUtils.escapeHtml( javadoc ); | 
| 1482 |                     } | 
| 1483 |                 } | 
| 1484 |             } | 
| 1485 |   | 
| 1486 |             suppressExceptionOnClose = false; | 
| 1487 |             return javadoc; | 
| 1488 |         } | 
| 1489 |         catch ( final MimeTypeParseException e ) | 
| 1490 |         { | 
| 1491 |             throw new AssertionError( e ); | 
| 1492 |         } | 
| 1493 |         catch ( final IOException e ) | 
| 1494 |         { | 
| 1495 |             throw new AssertionError( e ); | 
| 1496 |         } | 
| 1497 |         finally | 
| 1498 |         { | 
| 1499 |             try | 
| 1500 |             { | 
| 1501 |                 if ( reader != null ) | 
| 1502 |                 { | 
| 1503 |                     reader.close(); | 
| 1504 |                 } | 
| 1505 |             } | 
| 1506 |             catch ( final IOException e ) | 
| 1507 |             { | 
| 1508 |                 if ( suppressExceptionOnClose ) | 
| 1509 |                 { | 
| 1510 |                     this.log( Level.SEVERE, getMessage( e ), e ); | 
| 1511 |                 } | 
| 1512 |                 else | 
| 1513 |                 { | 
| 1514 |                     throw new AssertionError( e ); | 
| 1515 |                 } | 
| 1516 |             } | 
| 1517 |         } | 
| 1518 |     } | 
| 1519 |   | 
| 1520 |     /** | 
| 1521 |      * Formats a text from a list of texts to a Javadoc comment. | 
| 1522 |      * | 
| 1523 |      * @param texts The list of texts to format to a Javadoc comment. | 
| 1524 |      * @param indentationLevel The indentation level of the comment. | 
| 1525 |      * @param linePrefix The text to prepend lines with. | 
| 1526 |      * | 
| 1527 |      * @return The text corresponding to the locale of the instance from the list of texts formatted to a Javadoc | 
| 1528 |      * comment. | 
| 1529 |      * | 
| 1530 |      * @throws NullPointerException if {@code texts} or {@code linePrefix} is {@code null}. | 
| 1531 |      * @throws IllegalArgumentException if {@code indentationLevel} is negative. | 
| 1532 |      * @throws ModelObjectException if compiling a referenced type to a {@code MimeType} fails. | 
| 1533 |      * | 
| 1534 |      * @see #getLocale() | 
| 1535 |      * | 
| 1536 |      * @since 1.2 | 
| 1537 |      * | 
| 1538 |      * @deprecated As of JOMC 1.4, please use method {@link Text#getJavadocComment(java.lang.String, java.lang.String)}. | 
| 1539 |      * This method will be removed in JOMC 2.0. | 
| 1540 |      */ | 
| 1541 |     @Deprecated | 
| 1542 |     public String getJavadocComment( final Texts texts, final int indentationLevel, final String linePrefix ) | 
| 1543 |         throws ModelObjectException | 
| 1544 |     { | 
| 1545 |         if ( texts == null ) | 
| 1546 |         { | 
| 1547 |             throw new NullPointerException( "texts" ); | 
| 1548 |         } | 
| 1549 |         if ( linePrefix == null ) | 
| 1550 |         { | 
| 1551 |             throw new NullPointerException( "linePrefix" ); | 
| 1552 |         } | 
| 1553 |         if ( indentationLevel < 0 ) | 
| 1554 |         { | 
| 1555 |             throw new IllegalArgumentException( Integer.toString( indentationLevel ) ); | 
| 1556 |         } | 
| 1557 |   | 
| 1558 |         return this.getJavadocComment( texts.getText( this.getLocale().getLanguage() ), indentationLevel, linePrefix ); | 
| 1559 |     } | 
| 1560 |   | 
| 1561 |     /** | 
| 1562 |      * Formats a string to a Java string with unicode escapes. | 
| 1563 |      * | 
| 1564 |      * @param str The string to format to a Java string or {@code null}. | 
| 1565 |      * | 
| 1566 |      * @return {@code str} formatted to a Java string or {@code null}. | 
| 1567 |      * | 
| 1568 |      * @see StringEscapeUtils#escapeJava(java.lang.String) | 
| 1569 |      */ | 
| 1570 |     public String getJavaString( final String str ) | 
| 1571 |     { | 
| 1572 |         return StringEscapeUtils.escapeJava( str ); | 
| 1573 |     } | 
| 1574 |   | 
| 1575 |     /** | 
| 1576 |      * Formats a string to a Java class path location. | 
| 1577 |      * | 
| 1578 |      * @param str The string to format or {@code null}. | 
| 1579 |      * @param absolute {@code true} to return an absolute class path location; {@code false} to return a relative | 
| 1580 |      * class path location. | 
| 1581 |      * | 
| 1582 |      * @return {@code str} formatted to a Java class path location. | 
| 1583 |      * | 
| 1584 |      * @since 1.3 | 
| 1585 |      * | 
| 1586 |      * @deprecated As of JOMC 1.4, please use {@link JavaTypeName#getQualifiedName()}. This method will be removed in | 
| 1587 |      * JOMC 2.0. | 
| 1588 |      */ | 
| 1589 |     @Deprecated | 
| 1590 |     public String getJavaClasspathLocation( final String str, final boolean absolute ) | 
| 1591 |     { | 
| 1592 |         String classpathLocation = null; | 
| 1593 |   | 
| 1594 |         if ( str != null ) | 
| 1595 |         { | 
| 1596 |             classpathLocation = str.replace( '.', '/' ); | 
| 1597 |   | 
| 1598 |             if ( absolute ) | 
| 1599 |             { | 
| 1600 |                 classpathLocation = "/" + classpathLocation; | 
| 1601 |             } | 
| 1602 |         } | 
| 1603 |   | 
| 1604 |         return classpathLocation; | 
| 1605 |     } | 
| 1606 |   | 
| 1607 |     /** | 
| 1608 |      * Formats a string to a Java identifier. | 
| 1609 |      * | 
| 1610 |      * @param str The string to format or {@code null}. | 
| 1611 |      * @param capitalize {@code true}, to return an identifier with the first character upper cased; {@code false}, to | 
| 1612 |      * return an identifier with the first character lower cased. | 
| 1613 |      * | 
| 1614 |      * @return {@code str} formatted to a Java identifier or {@code null}. | 
| 1615 |      * | 
| 1616 |      * @since 1.2 | 
| 1617 |      * | 
| 1618 |      * @deprecated As of JOMC 1.4, please use method {@link #toJavaVariableName(java.lang.String)}. This method will be | 
| 1619 |      * removed in JOMC 2.0. | 
| 1620 |      */ | 
| 1621 |     @Deprecated | 
| 1622 |     public String getJavaIdentifier( final String str, final boolean capitalize ) | 
| 1623 |     { | 
| 1624 |         String identifier = null; | 
| 1625 |   | 
| 1626 |         if ( str != null ) | 
| 1627 |         { | 
| 1628 |             final int len = str.length(); | 
| 1629 |             final StringBuilder builder = new StringBuilder( len ); | 
| 1630 |             boolean uc = capitalize; | 
| 1631 |   | 
| 1632 |             for ( int i = 0; i < len; i++ ) | 
| 1633 |             { | 
| 1634 |                 final char c = str.charAt( i ); | 
| 1635 |                 final String charString = Character.toString( c ); | 
| 1636 |   | 
| 1637 |                 if ( builder.length() > 0 ) | 
| 1638 |                 { | 
| 1639 |                     if ( Character.isJavaIdentifierPart( c ) ) | 
| 1640 |                     { | 
| 1641 |                         builder.append( uc ? charString.toUpperCase( this.getLocale() ) : charString ); | 
| 1642 |                         uc = false; | 
| 1643 |                     } | 
| 1644 |                     else | 
| 1645 |                     { | 
| 1646 |                         uc = true; | 
| 1647 |                     } | 
| 1648 |                 } | 
| 1649 |                 else | 
| 1650 |                 { | 
| 1651 |                     if ( Character.isJavaIdentifierStart( c ) ) | 
| 1652 |                     { | 
| 1653 |                         builder.append( uc ? charString.toUpperCase( this.getLocale() ) | 
| 1654 |                                         : charString.toLowerCase( this.getLocale() ) ); | 
| 1655 |   | 
| 1656 |                         uc = false; | 
| 1657 |                     } | 
| 1658 |                     else | 
| 1659 |                     { | 
| 1660 |                         uc = capitalize; | 
| 1661 |                     } | 
| 1662 |                 } | 
| 1663 |             } | 
| 1664 |   | 
| 1665 |             identifier = builder.toString(); | 
| 1666 |   | 
| 1667 |             if ( identifier.length() <= 0 && this.isLoggable( Level.WARNING ) ) | 
| 1668 |             { | 
| 1669 |                 this.log( Level.WARNING, getMessage( "invalidJavaIdentifier", str ), null ); | 
| 1670 |             } | 
| 1671 |         } | 
| 1672 |   | 
| 1673 |         return identifier; | 
| 1674 |     } | 
| 1675 |   | 
| 1676 |     /** | 
| 1677 |      * Formats a string to a Java method parameter name. | 
| 1678 |      * | 
| 1679 |      * @param str The string to format or {@code null}. | 
| 1680 |      * | 
| 1681 |      * @return {@code str} formatted to a Java method parameter name or {@code null}. | 
| 1682 |      * | 
| 1683 |      * @since 1.3 | 
| 1684 |      * | 
| 1685 |      * @deprecated As of JOMC 1.4, please use method {@link #toJavaVariableName(java.lang.String)}. This method will be | 
| 1686 |      * removed in JOMC 2.0. | 
| 1687 |      */ | 
| 1688 |     @Deprecated | 
| 1689 |     public String getJavaMethodParameterName( final String str ) | 
| 1690 |     { | 
| 1691 |         String methodParameterName = null; | 
| 1692 |   | 
| 1693 |         if ( str != null ) | 
| 1694 |         { | 
| 1695 |             final int len = str.length(); | 
| 1696 |             final StringBuilder builder = new StringBuilder( len ); | 
| 1697 |             boolean uc = false; | 
| 1698 |   | 
| 1699 |             for ( int i = 0; i < len; i++ ) | 
| 1700 |             { | 
| 1701 |                 final char c = str.charAt( i ); | 
| 1702 |                 final String charString = Character.toString( c ); | 
| 1703 |   | 
| 1704 |                 if ( builder.length() > 0 ) | 
| 1705 |                 { | 
| 1706 |                     if ( Character.isJavaIdentifierPart( c ) ) | 
| 1707 |                     { | 
| 1708 |                         builder.append( uc ? charString.toUpperCase( this.getLocale() ) : charString ); | 
| 1709 |                         uc = false; | 
| 1710 |                     } | 
| 1711 |                     else | 
| 1712 |                     { | 
| 1713 |                         uc = true; | 
| 1714 |                     } | 
| 1715 |                 } | 
| 1716 |                 else if ( Character.isJavaIdentifierStart( c ) ) | 
| 1717 |                 { | 
| 1718 |                     builder.append( charString.toLowerCase( this.getLocale() ) ); | 
| 1719 |                 } | 
| 1720 |             } | 
| 1721 |   | 
| 1722 |             methodParameterName = builder.toString(); | 
| 1723 |   | 
| 1724 |             if ( methodParameterName.length() <= 0 && this.isLoggable( Level.WARNING ) ) | 
| 1725 |             { | 
| 1726 |                 this.log( Level.WARNING, getMessage( "invalidJavaMethodParameterName", str ), null ); | 
| 1727 |             } | 
| 1728 |   | 
| 1729 |             if ( this.getJavaKeywords().contains( methodParameterName ) ) | 
| 1730 |             { | 
| 1731 |                 methodParameterName = "_" + methodParameterName; | 
| 1732 |             } | 
| 1733 |         } | 
| 1734 |   | 
| 1735 |         return methodParameterName; | 
| 1736 |     } | 
| 1737 |   | 
| 1738 |     /** | 
| 1739 |      * Formats a string to a Java field name. | 
| 1740 |      * | 
| 1741 |      * @param str The string to format or {@code null}. | 
| 1742 |      * | 
| 1743 |      * @return {@code str} formatted to a Java field name or {@code null}. | 
| 1744 |      * | 
| 1745 |      * @since 1.3 | 
| 1746 |      * | 
| 1747 |      * @deprecated As of JOMC 1.4, please use method {@link #toJavaVariableName(java.lang.String)}. This method will be | 
| 1748 |      * removed in JOMC 2.0. | 
| 1749 |      */ | 
| 1750 |     @Deprecated | 
| 1751 |     public String getJavaFieldName( final String str ) | 
| 1752 |     { | 
| 1753 |         String fieldName = null; | 
| 1754 |   | 
| 1755 |         if ( str != null ) | 
| 1756 |         { | 
| 1757 |             final int len = str.length(); | 
| 1758 |             final StringBuilder builder = new StringBuilder( len ); | 
| 1759 |             boolean uc = false; | 
| 1760 |   | 
| 1761 |             for ( int i = 0; i < len; i++ ) | 
| 1762 |             { | 
| 1763 |                 final char c = str.charAt( i ); | 
| 1764 |                 final String charString = Character.toString( c ); | 
| 1765 |   | 
| 1766 |                 if ( builder.length() > 0 ) | 
| 1767 |                 { | 
| 1768 |                     if ( Character.isJavaIdentifierPart( c ) ) | 
| 1769 |                     { | 
| 1770 |                         builder.append( uc ? charString.toUpperCase( this.getLocale() ) : charString ); | 
| 1771 |                         uc = false; | 
| 1772 |                     } | 
| 1773 |                     else | 
| 1774 |                     { | 
| 1775 |                         uc = true; | 
| 1776 |                     } | 
| 1777 |                 } | 
| 1778 |                 else if ( Character.isJavaIdentifierStart( c ) ) | 
| 1779 |                 { | 
| 1780 |                     builder.append( charString.toLowerCase( this.getLocale() ) ); | 
| 1781 |                 } | 
| 1782 |             } | 
| 1783 |   | 
| 1784 |             fieldName = builder.toString(); | 
| 1785 |   | 
| 1786 |             if ( fieldName.length() <= 0 && this.isLoggable( Level.WARNING ) ) | 
| 1787 |             { | 
| 1788 |                 this.log( Level.WARNING, getMessage( "invalidJavaFieldName", str ), null ); | 
| 1789 |             } | 
| 1790 |   | 
| 1791 |             if ( this.getJavaKeywords().contains( fieldName ) ) | 
| 1792 |             { | 
| 1793 |                 fieldName = "_" + fieldName; | 
| 1794 |             } | 
| 1795 |         } | 
| 1796 |   | 
| 1797 |         return fieldName; | 
| 1798 |     } | 
| 1799 |   | 
| 1800 |     /** | 
| 1801 |      * Formats a string to a Java constant name. | 
| 1802 |      * | 
| 1803 |      * @param str The string to format or {@code null}. | 
| 1804 |      * | 
| 1805 |      * @return {@code str} formatted to a Java constant name or {@code null}. | 
| 1806 |      * | 
| 1807 |      * @since 1.3 | 
| 1808 |      * | 
| 1809 |      * @deprecated As of JOMC 1.4, please use method {@link #toJavaConstantName(java.lang.String)}. This method will be | 
| 1810 |      * removed in JOMC 2.0. | 
| 1811 |      */ | 
| 1812 |     @Deprecated | 
| 1813 |     public String getJavaConstantName( final String str ) | 
| 1814 |     { | 
| 1815 |         String name = null; | 
| 1816 |   | 
| 1817 |         if ( str != null ) | 
| 1818 |         { | 
| 1819 |             final int len = str.length(); | 
| 1820 |             final StringBuilder builder = new StringBuilder( len ); | 
| 1821 |             boolean separator = false; | 
| 1822 |   | 
| 1823 |             for ( int i = 0; i < len; i++ ) | 
| 1824 |             { | 
| 1825 |                 final char c = str.charAt( i ); | 
| 1826 |   | 
| 1827 |                 if ( builder.length() > 0 ? Character.isJavaIdentifierPart( c ) : Character.isJavaIdentifierStart( c ) ) | 
| 1828 |                 { | 
| 1829 |                     if ( builder.length() > 0 ) | 
| 1830 |                     { | 
| 1831 |                         if ( !separator ) | 
| 1832 |                         { | 
| 1833 |                             final char previous = builder.charAt( builder.length() - 1 ); | 
| 1834 |                             separator = Character.isLowerCase( previous ) && Character.isUpperCase( c ); | 
| 1835 |                         } | 
| 1836 |   | 
| 1837 |                         if ( separator ) | 
| 1838 |                         { | 
| 1839 |                             builder.append( '_' ); | 
| 1840 |                         } | 
| 1841 |                     } | 
| 1842 |   | 
| 1843 |                     builder.append( c ); | 
| 1844 |                     separator = false; | 
| 1845 |                 } | 
| 1846 |                 else | 
| 1847 |                 { | 
| 1848 |                     separator = true; | 
| 1849 |                 } | 
| 1850 |             } | 
| 1851 |   | 
| 1852 |             name = builder.toString().toUpperCase( this.getLocale() ); | 
| 1853 |   | 
| 1854 |             if ( name.length() <= 0 && this.isLoggable( Level.WARNING ) ) | 
| 1855 |             { | 
| 1856 |                 this.log( Level.WARNING, getMessage( "invalidJavaConstantName", str ), null ); | 
| 1857 |             } | 
| 1858 |         } | 
| 1859 |   | 
| 1860 |         return name; | 
| 1861 |     } | 
| 1862 |   | 
| 1863 |     /** | 
| 1864 |      * Formats a string to a Java constant name. | 
| 1865 |      * | 
| 1866 |      * @param str The string to format or {@code null}. | 
| 1867 |      * | 
| 1868 |      * @return {@code str} formatted to a Java constant name or {@code null}. | 
| 1869 |      * | 
| 1870 |      * @throws ParseException if normalizing {@code str} to a {@code JavaIdentifier} fails. | 
| 1871 |      * | 
| 1872 |      * @since 1.3 | 
| 1873 |      * | 
| 1874 |      * @see JavaIdentifier#normalize(java.lang.String, org.jomc.model.JavaIdentifier.NormalizationMode) | 
| 1875 |      * @see org.jomc.model.JavaIdentifier.NormalizationMode#CONSTANT_NAME_CONVENTION | 
| 1876 |      */ | 
| 1877 |     public JavaIdentifier toJavaConstantName( final String str ) throws ParseException | 
| 1878 |     { | 
| 1879 |         JavaIdentifier constantName = null; | 
| 1880 |   | 
| 1881 |         if ( str != null ) | 
| 1882 |         { | 
| 1883 |             constantName = JavaIdentifier.normalize( str, JavaIdentifier.NormalizationMode.CONSTANT_NAME_CONVENTION ); | 
| 1884 |         } | 
| 1885 |   | 
| 1886 |         return constantName; | 
| 1887 |     } | 
| 1888 |   | 
| 1889 |     /** | 
| 1890 |      * Compiles a string to a Java method name. | 
| 1891 |      * | 
| 1892 |      * @param str The string to compile or {@code null}. | 
| 1893 |      * | 
| 1894 |      * @return {@code str} compiled to a {@code JavaIdentifier} or {@code null}, if {@code str} is {@code null}. | 
| 1895 |      * | 
| 1896 |      * @throws ParseException if compiling {@code str} to a {@code JavaIdentifier} fails. | 
| 1897 |      * | 
| 1898 |      * @since 1.4 | 
| 1899 |      * | 
| 1900 |      * @see JavaIdentifier#normalize(java.lang.String, org.jomc.model.JavaIdentifier.NormalizationMode) | 
| 1901 |      * @see org.jomc.model.JavaIdentifier.NormalizationMode#METHOD_NAME_CONVENTION | 
| 1902 |      */ | 
| 1903 |     public JavaIdentifier toJavaMethodName( final String str ) throws ParseException | 
| 1904 |     { | 
| 1905 |         JavaIdentifier variableName = null; | 
| 1906 |   | 
| 1907 |         if ( str != null ) | 
| 1908 |         { | 
| 1909 |             variableName = | 
| 1910 |                 JavaIdentifier.normalize( str, JavaIdentifier.NormalizationMode.METHOD_NAME_CONVENTION ); | 
| 1911 |   | 
| 1912 |         } | 
| 1913 |   | 
| 1914 |         return variableName; | 
| 1915 |     } | 
| 1916 |   | 
| 1917 |     /** | 
| 1918 |      * Compiles a string to a Java variable name. | 
| 1919 |      * | 
| 1920 |      * @param str The string to compile or {@code null}. | 
| 1921 |      * | 
| 1922 |      * @return {@code str} compiled to a {@code JavaIdentifier} or {@code null}, if {@code str} is {@code null}. | 
| 1923 |      * | 
| 1924 |      * @throws ParseException if compiling {@code str} to a {@code JavaIdentifier} fails. | 
| 1925 |      * | 
| 1926 |      * @since 1.4 | 
| 1927 |      * | 
| 1928 |      * @see JavaIdentifier#normalize(java.lang.String, org.jomc.model.JavaIdentifier.NormalizationMode) | 
| 1929 |      * @see org.jomc.model.JavaIdentifier.NormalizationMode#VARIABLE_NAME_CONVENTION | 
| 1930 |      */ | 
| 1931 |     public JavaIdentifier toJavaVariableName( final String str ) throws ParseException | 
| 1932 |     { | 
| 1933 |         JavaIdentifier variableName = null; | 
| 1934 |   | 
| 1935 |         if ( str != null ) | 
| 1936 |         { | 
| 1937 |             variableName = | 
| 1938 |                 JavaIdentifier.normalize( str, JavaIdentifier.NormalizationMode.VARIABLE_NAME_CONVENTION ); | 
| 1939 |   | 
| 1940 |         } | 
| 1941 |   | 
| 1942 |         return variableName; | 
| 1943 |     } | 
| 1944 |   | 
| 1945 |     /** | 
| 1946 |      * Gets a flag indicating the type referenced by a given specification is located in an unnamed Java package. | 
| 1947 |      * | 
| 1948 |      * @param specification The specification to query. | 
| 1949 |      * | 
| 1950 |      * @return {@code true}, if the type referenced by {@code specification} is located in an unnamed Java package; | 
| 1951 |      * {@code false}, if the specification does not reference a type or if the referenced type is not located in an | 
| 1952 |      * unnamed Java package. | 
| 1953 |      * | 
| 1954 |      * @throws NullPointerException if {@code specification} is {@code null}. | 
| 1955 |      * @throws ModelObjectException if compiling the name of the referenced type to a {@code JavaTypeName} fails. | 
| 1956 |      * | 
| 1957 |      * @see Specification#getJavaTypeName() | 
| 1958 |      * @see JavaTypeName#isUnnamedPackage() | 
| 1959 |      * | 
| 1960 |      * @deprecated As of JOMC 1.4, please use method {@link Specification#getJavaTypeName()}. This method will be | 
| 1961 |      * removed in JOMC 2.0. | 
| 1962 |      */ | 
| 1963 |     @Deprecated | 
| 1964 |     public boolean isJavaDefaultPackage( final Specification specification ) throws ModelObjectException | 
| 1965 |     { | 
| 1966 |         if ( specification == null ) | 
| 1967 |         { | 
| 1968 |             throw new NullPointerException( "specification" ); | 
| 1969 |         } | 
| 1970 |   | 
| 1971 |         final JavaTypeName javaTypeName = specification.getJavaTypeName(); | 
| 1972 |         return javaTypeName != null && javaTypeName.isUnnamedPackage(); | 
| 1973 |     } | 
| 1974 |   | 
| 1975 |     /** | 
| 1976 |      * Gets a flag indicating the type referenced by a given implementation is located in an unnamed Java package. | 
| 1977 |      * | 
| 1978 |      * @param implementation The implementation to query. | 
| 1979 |      * | 
| 1980 |      * @return {@code true}, if the type referenced by {@code implementation} is located in an unnamed Java package; | 
| 1981 |      * {@code false}, if the implementation does not reference a type or if the referenced type is not located in an | 
| 1982 |      * unnamed Java package. | 
| 1983 |      * | 
| 1984 |      * @throws NullPointerException if {@code implementation} is {@code null}. | 
| 1985 |      * @throws ModelObjectException if compiling the name of the referenced type to a {@code JavaTypeName} fails. | 
| 1986 |      * | 
| 1987 |      * @see Implementation#getJavaTypeName() | 
| 1988 |      * @see JavaTypeName#isUnnamedPackage() | 
| 1989 |      * | 
| 1990 |      * @deprecated As of JOMC 1.4, please use method {@link Implementation#getJavaTypeName()}. This method will be | 
| 1991 |      * removed in JOMC 2.0. | 
| 1992 |      */ | 
| 1993 |     @Deprecated | 
| 1994 |     public boolean isJavaDefaultPackage( final Implementation implementation ) throws ModelObjectException | 
| 1995 |     { | 
| 1996 |         if ( implementation == null ) | 
| 1997 |         { | 
| 1998 |             throw new NullPointerException( "implementation" ); | 
| 1999 |         } | 
| 2000 |   | 
| 2001 |         final JavaTypeName javaTypeName = implementation.getJavaTypeName(); | 
| 2002 |         return javaTypeName != null && javaTypeName.isUnnamedPackage(); | 
| 2003 |     } | 
| 2004 |   | 
| 2005 |     /** | 
| 2006 |      * Formats a string to a HTML string with HTML entities. | 
| 2007 |      * | 
| 2008 |      * @param str The string to format to a HTML string with HTML entities or {@code null}. | 
| 2009 |      * | 
| 2010 |      * @return {@code str} formatted to a HTML string with HTML entities or {@code null}. | 
| 2011 |      * | 
| 2012 |      * @since 1.2 | 
| 2013 |      */ | 
| 2014 |     public String getHtmlString( final String str ) | 
| 2015 |     { | 
| 2016 |         return str != null ? str.replace( "&", "&" ).replace( "<", "<" ).replace( ">", ">" ). | 
| 2017 |             replace( "\"", """ ).replace( "*", "∗" ) : null; | 
| 2018 |   | 
| 2019 |     } | 
| 2020 |   | 
| 2021 |     /** | 
| 2022 |      * Formats a string to a XML string with XML entities. | 
| 2023 |      * | 
| 2024 |      * @param str The string to format to a XML string with XML entities or {@code null}. | 
| 2025 |      * | 
| 2026 |      * @return {@code str} formatted to a XML string with XML entities or {@code null}. | 
| 2027 |      * | 
| 2028 |      * @see StringEscapeUtils#escapeXml(java.lang.String) | 
| 2029 |      * | 
| 2030 |      * @since 1.2 | 
| 2031 |      */ | 
| 2032 |     public String getXmlString( final String str ) | 
| 2033 |     { | 
| 2034 |         return StringEscapeUtils.escapeXml( str ); | 
| 2035 |     } | 
| 2036 |   | 
| 2037 |     /** | 
| 2038 |      * Formats a string to a JavaScript string applying JavaScript string rules. | 
| 2039 |      * | 
| 2040 |      * @param str The string to format to a JavaScript string by applying JavaScript string rules or {@code null}. | 
| 2041 |      * | 
| 2042 |      * @return {@code str} formatted to a JavaScript string with JavaScript string rules applied or {@code null}. | 
| 2043 |      * | 
| 2044 |      * @see StringEscapeUtils#escapeJavaScript(java.lang.String) | 
| 2045 |      * | 
| 2046 |      * @since 1.2 | 
| 2047 |      */ | 
| 2048 |     public String getJavaScriptString( final String str ) | 
| 2049 |     { | 
| 2050 |         return StringEscapeUtils.escapeJavaScript( str ); | 
| 2051 |     } | 
| 2052 |   | 
| 2053 |     /** | 
| 2054 |      * Formats a string to a SQL string. | 
| 2055 |      * | 
| 2056 |      * @param str The string to format to a SQL string or {@code null}. | 
| 2057 |      * | 
| 2058 |      * @return {@code str} formatted to a SQL string or {@code null}. | 
| 2059 |      * | 
| 2060 |      * @see StringEscapeUtils#escapeSql(java.lang.String) | 
| 2061 |      * | 
| 2062 |      * @since 1.2 | 
| 2063 |      */ | 
| 2064 |     public String getSqlString( final String str ) | 
| 2065 |     { | 
| 2066 |         return StringEscapeUtils.escapeSql( str ); | 
| 2067 |     } | 
| 2068 |   | 
| 2069 |     /** | 
| 2070 |      * Formats a string to a CSV string. | 
| 2071 |      * | 
| 2072 |      * @param str The string to format to a CSV string or {@code null}. | 
| 2073 |      * | 
| 2074 |      * @return {@code str} formatted to a CSV string or {@code null}. | 
| 2075 |      * | 
| 2076 |      * @see StringEscapeUtils#escapeCsv(java.lang.String) | 
| 2077 |      * | 
| 2078 |      * @since 1.2 | 
| 2079 |      */ | 
| 2080 |     public String getCsvString( final String str ) | 
| 2081 |     { | 
| 2082 |         return StringEscapeUtils.escapeCsv( str ); | 
| 2083 |     } | 
| 2084 |   | 
| 2085 |     /** | 
| 2086 |      * Formats a {@code Boolean} to a string. | 
| 2087 |      * | 
| 2088 |      * @param b The {@code Boolean} to format to a string or {@code null}. | 
| 2089 |      * | 
| 2090 |      * @return {@code b} formatted to a string. | 
| 2091 |      * | 
| 2092 |      * @see #getLocale() | 
| 2093 |      * | 
| 2094 |      * @since 1.2 | 
| 2095 |      */ | 
| 2096 |     public String getBooleanString( final Boolean b ) | 
| 2097 |     { | 
| 2098 |         final MessageFormat messageFormat = new MessageFormat( ResourceBundle.getBundle( | 
| 2099 |             JomcTool.class.getName().replace( '.', '/' ), this.getLocale() ). | 
| 2100 |             getString( b ? "booleanStringTrue" : "booleanStringFalse" ), this.getLocale() ); | 
| 2101 |   | 
| 2102 |         return messageFormat.format( null ); | 
| 2103 |     } | 
| 2104 |   | 
| 2105 |     /** | 
| 2106 |      * Gets the display language of a given language code. | 
| 2107 |      * | 
| 2108 |      * @param language The language code to get the display language of. | 
| 2109 |      * | 
| 2110 |      * @return The display language of {@code language}. | 
| 2111 |      * | 
| 2112 |      * @throws NullPointerException if {@code language} is {@code null}. | 
| 2113 |      */ | 
| 2114 |     public String getDisplayLanguage( final String language ) | 
| 2115 |     { | 
| 2116 |         if ( language == null ) | 
| 2117 |         { | 
| 2118 |             throw new NullPointerException( "language" ); | 
| 2119 |         } | 
| 2120 |   | 
| 2121 |         final Locale l = new Locale( language ); | 
| 2122 |         return l.getDisplayLanguage( l ); | 
| 2123 |     } | 
| 2124 |   | 
| 2125 |     /** | 
| 2126 |      * Formats a calendar instance to a string. | 
| 2127 |      * | 
| 2128 |      * @param calendar The calendar to format to a string. | 
| 2129 |      * | 
| 2130 |      * @return The date of {@code calendar} formatted using a short format style pattern. | 
| 2131 |      * | 
| 2132 |      * @throws NullPointerException if {@code calendar} is {@code null}. | 
| 2133 |      * | 
| 2134 |      * @see DateFormat#SHORT | 
| 2135 |      */ | 
| 2136 |     public String getShortDate( final Calendar calendar ) | 
| 2137 |     { | 
| 2138 |         if ( calendar == null ) | 
| 2139 |         { | 
| 2140 |             throw new NullPointerException( "calendar" ); | 
| 2141 |         } | 
| 2142 |   | 
| 2143 |         return DateFormat.getDateInstance( DateFormat.SHORT, this.getLocale() ).format( calendar.getTime() ); | 
| 2144 |     } | 
| 2145 |   | 
| 2146 |     /** | 
| 2147 |      * Formats a calendar instance to a string. | 
| 2148 |      * | 
| 2149 |      * @param calendar The calendar to format to a string. | 
| 2150 |      * | 
| 2151 |      * @return The date of {@code calendar} formatted using a medium format style pattern. | 
| 2152 |      * | 
| 2153 |      * @throws NullPointerException if {@code calendar} is {@code null}. | 
| 2154 |      * | 
| 2155 |      * @see DateFormat#MEDIUM | 
| 2156 |      * | 
| 2157 |      * @since 1.2 | 
| 2158 |      */ | 
| 2159 |     public String getMediumDate( final Calendar calendar ) | 
| 2160 |     { | 
| 2161 |         if ( calendar == null ) | 
| 2162 |         { | 
| 2163 |             throw new NullPointerException( "calendar" ); | 
| 2164 |         } | 
| 2165 |   | 
| 2166 |         return DateFormat.getDateInstance( DateFormat.MEDIUM, this.getLocale() ).format( calendar.getTime() ); | 
| 2167 |     } | 
| 2168 |   | 
| 2169 |     /** | 
| 2170 |      * Formats a calendar instance to a string. | 
| 2171 |      * | 
| 2172 |      * @param calendar The calendar to format to a string. | 
| 2173 |      * | 
| 2174 |      * @return The date of {@code calendar} formatted using a long format style pattern. | 
| 2175 |      * | 
| 2176 |      * @throws NullPointerException if {@code calendar} is {@code null}. | 
| 2177 |      * | 
| 2178 |      * @see DateFormat#LONG | 
| 2179 |      */ | 
| 2180 |     public String getLongDate( final Calendar calendar ) | 
| 2181 |     { | 
| 2182 |         if ( calendar == null ) | 
| 2183 |         { | 
| 2184 |             throw new NullPointerException( "calendar" ); | 
| 2185 |         } | 
| 2186 |   | 
| 2187 |         return DateFormat.getDateInstance( DateFormat.LONG, this.getLocale() ).format( calendar.getTime() ); | 
| 2188 |     } | 
| 2189 |   | 
| 2190 |     /** | 
| 2191 |      * Formats a calendar instance to a string. | 
| 2192 |      * | 
| 2193 |      * @param calendar The calendar to format to a string. | 
| 2194 |      * | 
| 2195 |      * @return The date of {@code calendar} formatted using an ISO-8601 format style. | 
| 2196 |      * | 
| 2197 |      * @throws NullPointerException if {@code calendar} is {@code null}. | 
| 2198 |      * | 
| 2199 |      * @see SimpleDateFormat yyyy-DDD | 
| 2200 |      * | 
| 2201 |      * @since 1.2 | 
| 2202 |      */ | 
| 2203 |     public String getIsoDate( final Calendar calendar ) | 
| 2204 |     { | 
| 2205 |         if ( calendar == null ) | 
| 2206 |         { | 
| 2207 |             throw new NullPointerException( "calendar" ); | 
| 2208 |         } | 
| 2209 |   | 
| 2210 |         return new SimpleDateFormat( "yyyy-DDD", this.getLocale() ).format( calendar.getTime() ); | 
| 2211 |     } | 
| 2212 |   | 
| 2213 |     /** | 
| 2214 |      * Formats a calendar instance to a string. | 
| 2215 |      * | 
| 2216 |      * @param calendar The calendar to format to a string. | 
| 2217 |      * | 
| 2218 |      * @return The time of {@code calendar} formatted using a short format style pattern. | 
| 2219 |      * | 
| 2220 |      * @throws NullPointerException if {@code calendar} is {@code null}. | 
| 2221 |      * | 
| 2222 |      * @see DateFormat#SHORT | 
| 2223 |      */ | 
| 2224 |     public String getShortTime( final Calendar calendar ) | 
| 2225 |     { | 
| 2226 |         if ( calendar == null ) | 
| 2227 |         { | 
| 2228 |             throw new NullPointerException( "calendar" ); | 
| 2229 |         } | 
| 2230 |   | 
| 2231 |         return DateFormat.getTimeInstance( DateFormat.SHORT, this.getLocale() ).format( calendar.getTime() ); | 
| 2232 |     } | 
| 2233 |   | 
| 2234 |     /** | 
| 2235 |      * Formats a calendar instance to a string. | 
| 2236 |      * | 
| 2237 |      * @param calendar The calendar to format to a string. | 
| 2238 |      * | 
| 2239 |      * @return The time of {@code calendar} formatted using a medium format style pattern. | 
| 2240 |      * | 
| 2241 |      * @throws NullPointerException if {@code calendar} is {@code null}. | 
| 2242 |      * | 
| 2243 |      * @see DateFormat#MEDIUM | 
| 2244 |      * | 
| 2245 |      * @since 1.2 | 
| 2246 |      */ | 
| 2247 |     public String getMediumTime( final Calendar calendar ) | 
| 2248 |     { | 
| 2249 |         if ( calendar == null ) | 
| 2250 |         { | 
| 2251 |             throw new NullPointerException( "calendar" ); | 
| 2252 |         } | 
| 2253 |   | 
| 2254 |         return DateFormat.getTimeInstance( DateFormat.MEDIUM, this.getLocale() ).format( calendar.getTime() ); | 
| 2255 |     } | 
| 2256 |   | 
| 2257 |     /** | 
| 2258 |      * Formats a calendar instance to a string. | 
| 2259 |      * | 
| 2260 |      * @param calendar The calendar to format to a string. | 
| 2261 |      * | 
| 2262 |      * @return The time of {@code calendar} formatted using a long format style pattern. | 
| 2263 |      * | 
| 2264 |      * @throws NullPointerException if {@code calendar} is {@code null}. | 
| 2265 |      * | 
| 2266 |      * @see DateFormat#LONG | 
| 2267 |      */ | 
| 2268 |     public String getLongTime( final Calendar calendar ) | 
| 2269 |     { | 
| 2270 |         if ( calendar == null ) | 
| 2271 |         { | 
| 2272 |             throw new NullPointerException( "calendar" ); | 
| 2273 |         } | 
| 2274 |   | 
| 2275 |         return DateFormat.getTimeInstance( DateFormat.LONG, this.getLocale() ).format( calendar.getTime() ); | 
| 2276 |     } | 
| 2277 |   | 
| 2278 |     /** | 
| 2279 |      * Formats a calendar instance to a string. | 
| 2280 |      * | 
| 2281 |      * @param calendar The calendar to format to a string. | 
| 2282 |      * | 
| 2283 |      * @return The time of {@code calendar} formatted using an ISO-8601 format style. | 
| 2284 |      * | 
| 2285 |      * @throws NullPointerException if {@code calendar} is {@code null}. | 
| 2286 |      * | 
| 2287 |      * @see SimpleDateFormat HH:mm | 
| 2288 |      * | 
| 2289 |      * @since 1.2 | 
| 2290 |      */ | 
| 2291 |     public String getIsoTime( final Calendar calendar ) | 
| 2292 |     { | 
| 2293 |         if ( calendar == null ) | 
| 2294 |         { | 
| 2295 |             throw new NullPointerException( "calendar" ); | 
| 2296 |         } | 
| 2297 |   | 
| 2298 |         return new SimpleDateFormat( "HH:mm", this.getLocale() ).format( calendar.getTime() ); | 
| 2299 |     } | 
| 2300 |   | 
| 2301 |     /** | 
| 2302 |      * Formats a calendar instance to a string. | 
| 2303 |      * | 
| 2304 |      * @param calendar The calendar to format to a string. | 
| 2305 |      * | 
| 2306 |      * @return The date and time of {@code calendar} formatted using a short format style pattern. | 
| 2307 |      * | 
| 2308 |      * @throws NullPointerException if {@code calendar} is {@code null}. | 
| 2309 |      * | 
| 2310 |      * @see DateFormat#SHORT | 
| 2311 |      */ | 
| 2312 |     public String getShortDateTime( final Calendar calendar ) | 
| 2313 |     { | 
| 2314 |         if ( calendar == null ) | 
| 2315 |         { | 
| 2316 |             throw new NullPointerException( "calendar" ); | 
| 2317 |         } | 
| 2318 |   | 
| 2319 |         return DateFormat.getDateTimeInstance( DateFormat.SHORT, DateFormat.SHORT, this.getLocale() ). | 
| 2320 |             format( calendar.getTime() ); | 
| 2321 |   | 
| 2322 |     } | 
| 2323 |   | 
| 2324 |     /** | 
| 2325 |      * Formats a calendar instance to a string. | 
| 2326 |      * | 
| 2327 |      * @param calendar The calendar to format to a string. | 
| 2328 |      * | 
| 2329 |      * @return The date and time of {@code calendar} formatted using a medium format style pattern. | 
| 2330 |      * | 
| 2331 |      * @throws NullPointerException if {@code calendar} is {@code null}. | 
| 2332 |      * | 
| 2333 |      * @see DateFormat#MEDIUM | 
| 2334 |      * | 
| 2335 |      * @since 1.2 | 
| 2336 |      */ | 
| 2337 |     public String getMediumDateTime( final Calendar calendar ) | 
| 2338 |     { | 
| 2339 |         if ( calendar == null ) | 
| 2340 |         { | 
| 2341 |             throw new NullPointerException( "calendar" ); | 
| 2342 |         } | 
| 2343 |   | 
| 2344 |         return DateFormat.getDateTimeInstance( DateFormat.MEDIUM, DateFormat.MEDIUM, this.getLocale() ). | 
| 2345 |             format( calendar.getTime() ); | 
| 2346 |   | 
| 2347 |     } | 
| 2348 |   | 
| 2349 |     /** | 
| 2350 |      * Formats a calendar instance to a string. | 
| 2351 |      * | 
| 2352 |      * @param calendar The calendar to format to a string. | 
| 2353 |      * | 
| 2354 |      * @return The date and time of {@code calendar} formatted using a long format style pattern. | 
| 2355 |      * | 
| 2356 |      * @throws NullPointerException if {@code calendar} is {@code null}. | 
| 2357 |      * | 
| 2358 |      * @see DateFormat#LONG | 
| 2359 |      */ | 
| 2360 |     public String getLongDateTime( final Calendar calendar ) | 
| 2361 |     { | 
| 2362 |         if ( calendar == null ) | 
| 2363 |         { | 
| 2364 |             throw new NullPointerException( "calendar" ); | 
| 2365 |         } | 
| 2366 |   | 
| 2367 |         return DateFormat.getDateTimeInstance( DateFormat.LONG, DateFormat.LONG, this.getLocale() ). | 
| 2368 |             format( calendar.getTime() ); | 
| 2369 |   | 
| 2370 |     } | 
| 2371 |   | 
| 2372 |     /** | 
| 2373 |      * Formats a calendar instance to a string. | 
| 2374 |      * | 
| 2375 |      * @param calendar The calendar to format to a string. | 
| 2376 |      * | 
| 2377 |      * @return The date and time of {@code calendar} formatted using a ISO-8601 format style. | 
| 2378 |      * | 
| 2379 |      * @throws NullPointerException if {@code calendar} is {@code null}. | 
| 2380 |      * | 
| 2381 |      * @see SimpleDateFormat yyyy-MM-dd'T'HH:mm:ssZ | 
| 2382 |      * | 
| 2383 |      * @since 1.2 | 
| 2384 |      */ | 
| 2385 |     public String getIsoDateTime( final Calendar calendar ) | 
| 2386 |     { | 
| 2387 |         if ( calendar == null ) | 
| 2388 |         { | 
| 2389 |             throw new NullPointerException( "calendar" ); | 
| 2390 |         } | 
| 2391 |   | 
| 2392 |         // JDK: As of JDK 7, "yyyy-MM-dd'T'HH:mm:ssXXX". | 
| 2393 |         return new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ssZ", this.getLocale() ).format( calendar.getTime() ); | 
| 2394 |     } | 
| 2395 |   | 
| 2396 |     /** | 
| 2397 |      * Gets a string describing the range of years for given calendars. | 
| 2398 |      * | 
| 2399 |      * @param start The start of the range. | 
| 2400 |      * @param end The end of the range. | 
| 2401 |      * | 
| 2402 |      * @return Formatted range of the years of {@code start} and {@code end} (e.g. {@code "start - end"}). | 
| 2403 |      * | 
| 2404 |      * @throws NullPointerException if {@code start} or {@code end} is {@code null}. | 
| 2405 |      */ | 
| 2406 |     public String getYears( final Calendar start, final Calendar end ) | 
| 2407 |     { | 
| 2408 |         if ( start == null ) | 
| 2409 |         { | 
| 2410 |             throw new NullPointerException( "start" ); | 
| 2411 |         } | 
| 2412 |         if ( end == null ) | 
| 2413 |         { | 
| 2414 |             throw new NullPointerException( "end" ); | 
| 2415 |         } | 
| 2416 |   | 
| 2417 |         final Format yearFormat = new SimpleDateFormat( "yyyy", this.getLocale() ); | 
| 2418 |         final int s = start.get( Calendar.YEAR ); | 
| 2419 |         final int e = end.get( Calendar.YEAR ); | 
| 2420 |         final StringBuilder years = new StringBuilder(); | 
| 2421 |   | 
| 2422 |         if ( s != e ) | 
| 2423 |         { | 
| 2424 |             if ( s < e ) | 
| 2425 |             { | 
| 2426 |                 years.append( yearFormat.format( start.getTime() ) ).append( " - " ). | 
| 2427 |                     append( yearFormat.format( end.getTime() ) ); | 
| 2428 |   | 
| 2429 |             } | 
| 2430 |             else | 
| 2431 |             { | 
| 2432 |                 years.append( yearFormat.format( end.getTime() ) ).append( " - " ). | 
| 2433 |                     append( yearFormat.format( start.getTime() ) ); | 
| 2434 |   | 
| 2435 |             } | 
| 2436 |         } | 
| 2437 |         else | 
| 2438 |         { | 
| 2439 |             years.append( yearFormat.format( start.getTime() ) ); | 
| 2440 |         } | 
| 2441 |   | 
| 2442 |         return years.toString(); | 
| 2443 |     } | 
| 2444 |   | 
| 2445 |     /** | 
| 2446 |      * Gets the model of the instance. | 
| 2447 |      * | 
| 2448 |      * @return The model of the instance. | 
| 2449 |      * | 
| 2450 |      * @see #getModules() | 
| 2451 |      * @see #setModel(org.jomc.modlet.Model) | 
| 2452 |      */ | 
| 2453 |     public final Model getModel() | 
| 2454 |     { | 
| 2455 |         if ( this.model == null ) | 
| 2456 |         { | 
| 2457 |             this.model = new Model(); | 
| 2458 |             this.model.setIdentifier( ModelObject.MODEL_PUBLIC_ID ); | 
| 2459 |         } | 
| 2460 |   | 
| 2461 |         return this.model; | 
| 2462 |     } | 
| 2463 |   | 
| 2464 |     /** | 
| 2465 |      * Sets the model of the instance. | 
| 2466 |      * | 
| 2467 |      * @param value The new model of the instance or {@code null}. | 
| 2468 |      * | 
| 2469 |      * @see #getModel() | 
| 2470 |      */ | 
| 2471 |     public final void setModel( final Model value ) | 
| 2472 |     { | 
| 2473 |         this.model = value; | 
| 2474 |     } | 
| 2475 |   | 
| 2476 |     /** | 
| 2477 |      * Gets the modules of the model of the instance. | 
| 2478 |      * | 
| 2479 |      * @return The modules of the model of the instance or {@code null}, if no modules are found. | 
| 2480 |      * | 
| 2481 |      * @see #getModel() | 
| 2482 |      * @see #setModel(org.jomc.modlet.Model) | 
| 2483 |      */ | 
| 2484 |     public final Modules getModules() | 
| 2485 |     { | 
| 2486 |         return ModelHelper.getModules( this.getModel() ); | 
| 2487 |     } | 
| 2488 |   | 
| 2489 |     /** | 
| 2490 |      * Gets the {@code VelocityEngine} of the instance. | 
| 2491 |      * | 
| 2492 |      * @return The {@code VelocityEngine} of the instance. | 
| 2493 |      * | 
| 2494 |      * @throws IOException if initializing a new velocity engine fails. | 
| 2495 |      * | 
| 2496 |      * @see #setVelocityEngine(org.apache.velocity.app.VelocityEngine) | 
| 2497 |      */ | 
| 2498 |     public final VelocityEngine getVelocityEngine() throws IOException | 
| 2499 |     { | 
| 2500 |         if ( this.velocityEngine == null ) | 
| 2501 |         { | 
| 2502 |             /** {@code LogChute} logging to the listeners of the tool. */ | 
| 2503 |             class JomcLogChute implements LogChute | 
| 2504 |             { | 
| 2505 |   | 
| 2506 |                 JomcLogChute() | 
| 2507 |                 { | 
| 2508 |                     super(); | 
| 2509 |                 } | 
| 2510 |   | 
| 2511 |                 public void init( final RuntimeServices runtimeServices ) throws Exception | 
| 2512 |                 { | 
| 2513 |                 } | 
| 2514 |   | 
| 2515 |                 public void log( final int level, final String message ) | 
| 2516 |                 { | 
| 2517 |                     this.log( level, message, null ); | 
| 2518 |                 } | 
| 2519 |   | 
| 2520 |                 public void log( final int level, final String message, final Throwable throwable ) | 
| 2521 |                 { | 
| 2522 |                     JomcTool.this.log( Level.FINEST, message, throwable ); | 
| 2523 |                 } | 
| 2524 |   | 
| 2525 |                 public boolean isLevelEnabled( final int level ) | 
| 2526 |                 { | 
| 2527 |                     return isLoggable( Level.FINEST ); | 
| 2528 |                 } | 
| 2529 |   | 
| 2530 |             } | 
| 2531 |   | 
| 2532 |             final VelocityEngine engine = new VelocityEngine(); | 
| 2533 |             engine.setProperty( RuntimeConstants.RUNTIME_REFERENCES_STRICT, Boolean.TRUE.toString() ); | 
| 2534 |             engine.setProperty( RuntimeConstants.VM_ARGUMENTS_STRICT, Boolean.TRUE.toString() ); | 
| 2535 |             engine.setProperty( RuntimeConstants.STRICT_MATH, Boolean.TRUE.toString() ); | 
| 2536 |             engine.setProperty( RuntimeConstants.RUNTIME_LOG_LOGSYSTEM, new JomcLogChute() ); | 
| 2537 |   | 
| 2538 |             engine.setProperty( RuntimeConstants.RESOURCE_LOADER, "class" ); | 
| 2539 |             engine.setProperty( "class.resource.loader.class", ClasspathResourceLoader.class.getName() ); | 
| 2540 |             engine.setProperty( "class.resource.loader.cache", Boolean.TRUE.toString() ); | 
| 2541 |   | 
| 2542 |             if ( this.getTemplateLocation() != null ) | 
| 2543 |             { | 
| 2544 |                 engine.setProperty( RuntimeConstants.RESOURCE_LOADER, "class,url" ); | 
| 2545 |                 engine.setProperty( "url.resource.loader.class", URLResourceLoader.class.getName() ); | 
| 2546 |                 engine.setProperty( "url.resource.loader.cache", Boolean.TRUE.toString() ); | 
| 2547 |                 engine.setProperty( "url.resource.loader.root", this.getTemplateLocation().toExternalForm() ); | 
| 2548 |                 engine.setProperty( "url.resource.loader.timeout", Integer.toString( 60000 ) ); | 
| 2549 |             } | 
| 2550 |   | 
| 2551 |             this.velocityEngine = engine; | 
| 2552 |             this.defaultVelocityEngine = true; | 
| 2553 |         } | 
| 2554 |   | 
| 2555 |         return this.velocityEngine; | 
| 2556 |     } | 
| 2557 |   | 
| 2558 |     /** | 
| 2559 |      * Sets the {@code VelocityEngine} of the instance. | 
| 2560 |      * | 
| 2561 |      * @param value The new {@code VelocityEngine} of the instance or {@code null}. | 
| 2562 |      * | 
| 2563 |      * @see #getVelocityEngine() | 
| 2564 |      */ | 
| 2565 |     public final void setVelocityEngine( final VelocityEngine value ) | 
| 2566 |     { | 
| 2567 |         this.velocityEngine = value; | 
| 2568 |         this.defaultVelocityEngine = false; | 
| 2569 |     } | 
| 2570 |   | 
| 2571 |     /** | 
| 2572 |      * Gets a new velocity context used for merging templates. | 
| 2573 |      * | 
| 2574 |      * @return A new velocity context used for merging templates. | 
| 2575 |      * | 
| 2576 |      * @throws IOException if creating a new context instance fails. | 
| 2577 |      * | 
| 2578 |      * @see #getTemplateParameters() | 
| 2579 |      */ | 
| 2580 |     public VelocityContext getVelocityContext() throws IOException | 
| 2581 |     { | 
| 2582 |         final Calendar now = Calendar.getInstance(); | 
| 2583 |         final VelocityContext ctx = | 
| 2584 |             new VelocityContext( new HashMap<String, Object>( this.getTemplateParameters() ) ); | 
| 2585 |   | 
| 2586 |         this.mergeTemplateProfileContextProperties( this.getTemplateProfile(), this.getLocale().getLanguage(), ctx ); | 
| 2587 |         this.mergeTemplateProfileContextProperties( this.getTemplateProfile(), null, ctx ); | 
| 2588 |   | 
| 2589 |         final Model clonedModel = this.getModel().clone(); | 
| 2590 |         final Modules clonedModules = ModelHelper.getModules( clonedModel ); | 
| 2591 |         assert clonedModules != null : "Unexpected missing modules for model '" + clonedModel.getIdentifier() + "'."; | 
| 2592 |   | 
| 2593 |         ctx.put( "model", clonedModel ); | 
| 2594 |         ctx.put( "modules", clonedModules ); | 
| 2595 |         ctx.put( "imodel", new InheritanceModel( clonedModules ) ); | 
| 2596 |         ctx.put( "tool", this ); | 
| 2597 |         ctx.put( "toolName", this.getClass().getName() ); | 
| 2598 |         ctx.put( "toolVersion", getMessage( "projectVersion" ) ); | 
| 2599 |         ctx.put( "toolUrl", getMessage( "projectUrl" ) ); | 
| 2600 |         ctx.put( "calendar", now.getTime() ); | 
| 2601 |   | 
| 2602 |         // JDK: As of JDK 7, "yyyy-MM-dd'T'HH:mm:ss.SSSXXX". | 
| 2603 |         ctx.put( "now", | 
| 2604 |                  new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ss.SSSZ", this.getLocale() ).format( now.getTime() ) ); | 
| 2605 |   | 
| 2606 |         ctx.put( "year", new SimpleDateFormat( "yyyy", this.getLocale() ).format( now.getTime() ) ); | 
| 2607 |         ctx.put( "month", new SimpleDateFormat( "MM", this.getLocale() ).format( now.getTime() ) ); | 
| 2608 |         ctx.put( "day", new SimpleDateFormat( "dd", this.getLocale() ).format( now.getTime() ) ); | 
| 2609 |         ctx.put( "hour", new SimpleDateFormat( "HH", this.getLocale() ).format( now.getTime() ) ); | 
| 2610 |         ctx.put( "minute", new SimpleDateFormat( "mm", this.getLocale() ).format( now.getTime() ) ); | 
| 2611 |         ctx.put( "second", new SimpleDateFormat( "ss", this.getLocale() ).format( now.getTime() ) ); | 
| 2612 |         ctx.put( "timezone", new SimpleDateFormat( "Z", this.getLocale() ).format( now.getTime() ) ); | 
| 2613 |         ctx.put( "shortDate", this.getShortDate( now ) ); | 
| 2614 |         ctx.put( "mediumDate", this.getMediumDate( now ) ); | 
| 2615 |         ctx.put( "longDate", this.getLongDate( now ) ); | 
| 2616 |         ctx.put( "isoDate", this.getIsoDate( now ) ); | 
| 2617 |         ctx.put( "shortTime", this.getShortTime( now ) ); | 
| 2618 |         ctx.put( "mediumTime", this.getMediumTime( now ) ); | 
| 2619 |         ctx.put( "longTime", this.getLongTime( now ) ); | 
| 2620 |         ctx.put( "isoTime", this.getIsoTime( now ) ); | 
| 2621 |         ctx.put( "shortDateTime", this.getShortDateTime( now ) ); | 
| 2622 |         ctx.put( "mediumDateTime", this.getMediumDateTime( now ) ); | 
| 2623 |         ctx.put( "longDateTime", this.getLongDateTime( now ) ); | 
| 2624 |         ctx.put( "isoDateTime", this.getIsoDateTime( now ) ); | 
| 2625 |   | 
| 2626 |         return ctx; | 
| 2627 |     } | 
| 2628 |   | 
| 2629 |     /** | 
| 2630 |      * Gets the template parameters of the instance. | 
| 2631 |      * <p>This accessor method returns a reference to the live map, not a snapshot. Therefore any modification you make | 
| 2632 |      * to the returned map will be present inside the object. This is why there is no {@code set} method for the | 
| 2633 |      * template parameters property.</p> | 
| 2634 |      * | 
| 2635 |      * @return The template parameters of the instance. | 
| 2636 |      * | 
| 2637 |      * @see #getVelocityContext() | 
| 2638 |      * | 
| 2639 |      * @since 1.2 | 
| 2640 |      */ | 
| 2641 |     public final Map<String, Object> getTemplateParameters() | 
| 2642 |     { | 
| 2643 |         if ( this.templateParameters == null ) | 
| 2644 |         { | 
| 2645 |             this.templateParameters = Collections.synchronizedMap( new HashMap<String, Object>() ); | 
| 2646 |         } | 
| 2647 |   | 
| 2648 |         return this.templateParameters; | 
| 2649 |     } | 
| 2650 |   | 
| 2651 |     /** | 
| 2652 |      * Gets the location to search for templates in addition to searching the class path. | 
| 2653 |      * | 
| 2654 |      * @return The location to search for templates in addition to searching the class path or {@code null}. | 
| 2655 |      * | 
| 2656 |      * @see #setTemplateLocation(java.net.URL) | 
| 2657 |      * | 
| 2658 |      * @since 1.2 | 
| 2659 |      */ | 
| 2660 |     public final URL getTemplateLocation() | 
| 2661 |     { | 
| 2662 |         return this.templateLocation; | 
| 2663 |     } | 
| 2664 |   | 
| 2665 |     /** | 
| 2666 |      * Sets the location to search for templates in addition to searching the class path. | 
| 2667 |      * | 
| 2668 |      * @param value The new location to search for templates in addition to searching the class path or {@code null}. | 
| 2669 |      * | 
| 2670 |      * @see #getTemplateLocation() | 
| 2671 |      * | 
| 2672 |      * @since 1.2 | 
| 2673 |      */ | 
| 2674 |     public final void setTemplateLocation( final URL value ) | 
| 2675 |     { | 
| 2676 |         this.templateLocation = value; | 
| 2677 |         this.templateProfileContextPropertiesCache = null; | 
| 2678 |         this.templateProfilePropertiesCache = null; | 
| 2679 |   | 
| 2680 |         if ( this.defaultVelocityEngine ) | 
| 2681 |         { | 
| 2682 |             this.setVelocityEngine( null ); | 
| 2683 |         } | 
| 2684 |     } | 
| 2685 |   | 
| 2686 |     /** | 
| 2687 |      * Gets the encoding to use for reading templates. | 
| 2688 |      * | 
| 2689 |      * @return The encoding to use for reading templates. | 
| 2690 |      * | 
| 2691 |      * @see #setTemplateEncoding(java.lang.String) | 
| 2692 |      * | 
| 2693 |      * @deprecated As of JOMC 1.3, replaced by method {@link #getDefaultTemplateEncoding()}. This method will be removed | 
| 2694 |      * in JOMC 2.0. | 
| 2695 |      */ | 
| 2696 |     @Deprecated | 
| 2697 |     public final String getTemplateEncoding() | 
| 2698 |     { | 
| 2699 |         return this.getDefaultTemplateEncoding(); | 
| 2700 |     } | 
| 2701 |   | 
| 2702 |     /** | 
| 2703 |      * Sets the encoding to use for reading templates. | 
| 2704 |      * | 
| 2705 |      * @param value The new encoding to use for reading templates or {@code null}. | 
| 2706 |      * | 
| 2707 |      * @see #getTemplateEncoding() | 
| 2708 |      * | 
| 2709 |      * @deprecated As of JOMC 1.3, replaced by method {@link #setDefaultTemplateEncoding(java.lang.String)}. This method | 
| 2710 |      * will be removed in JOMC 2.0. | 
| 2711 |      */ | 
| 2712 |     @Deprecated | 
| 2713 |     public final void setTemplateEncoding( final String value ) | 
| 2714 |     { | 
| 2715 |         this.setDefaultTemplateEncoding( value ); | 
| 2716 |     } | 
| 2717 |   | 
| 2718 |     /** | 
| 2719 |      * Gets the default encoding used for reading templates. | 
| 2720 |      * | 
| 2721 |      * @return The default encoding used for reading templates. | 
| 2722 |      * | 
| 2723 |      * @see #setDefaultTemplateEncoding(java.lang.String) | 
| 2724 |      * | 
| 2725 |      * @since 1.3 | 
| 2726 |      */ | 
| 2727 |     public final String getDefaultTemplateEncoding() | 
| 2728 |     { | 
| 2729 |         if ( this.defaultTemplateEncoding == null ) | 
| 2730 |         { | 
| 2731 |             this.defaultTemplateEncoding = getMessage( "buildSourceEncoding" ); | 
| 2732 |   | 
| 2733 |             if ( this.isLoggable( Level.CONFIG ) ) | 
| 2734 |             { | 
| 2735 |                 this.log( Level.CONFIG, getMessage( "defaultTemplateEncoding", this.defaultTemplateEncoding ), null ); | 
| 2736 |             } | 
| 2737 |         } | 
| 2738 |   | 
| 2739 |         return this.defaultTemplateEncoding; | 
| 2740 |     } | 
| 2741 |   | 
| 2742 |     /** | 
| 2743 |      * Sets the default encoding to use for reading templates. | 
| 2744 |      * | 
| 2745 |      * @param value The new default encoding to use for reading templates or {@code null}. | 
| 2746 |      * | 
| 2747 |      * @see #getDefaultTemplateEncoding() | 
| 2748 |      * | 
| 2749 |      * @since 1.3 | 
| 2750 |      */ | 
| 2751 |     public final void setDefaultTemplateEncoding( final String value ) | 
| 2752 |     { | 
| 2753 |         this.defaultTemplateEncoding = value; | 
| 2754 |         this.templateCache = null; | 
| 2755 |     } | 
| 2756 |   | 
| 2757 |     /** | 
| 2758 |      * Gets the template encoding of a given template profile. | 
| 2759 |      * | 
| 2760 |      * @param tp The template profile to get the template encoding of. | 
| 2761 |      * | 
| 2762 |      * @return The template encoding of the template profile identified by {@code tp} or the default template encoding | 
| 2763 |      * if no such encoding is defined. | 
| 2764 |      * | 
| 2765 |      * @throws NullPointerException if {@code tp} is {@code null}. | 
| 2766 |      * | 
| 2767 |      * @see #getDefaultTemplateEncoding() | 
| 2768 |      * | 
| 2769 |      * @since 1.3 | 
| 2770 |      */ | 
| 2771 |     public final String getTemplateEncoding( final String tp ) | 
| 2772 |     { | 
| 2773 |         if ( tp == null ) | 
| 2774 |         { | 
| 2775 |             throw new NullPointerException( "tp" ); | 
| 2776 |         } | 
| 2777 |   | 
| 2778 |         String te = null; | 
| 2779 |   | 
| 2780 |         try | 
| 2781 |         { | 
| 2782 |             te = this.getTemplateProfileProperties( tp ).getProperty( TEMPLATE_ENCODING_PROFILE_PROPERTY_NAME ); | 
| 2783 |         } | 
| 2784 |         catch ( final IOException e ) | 
| 2785 |         { | 
| 2786 |             if ( this.isLoggable( Level.SEVERE ) ) | 
| 2787 |             { | 
| 2788 |                 this.log( Level.SEVERE, getMessage( e ), e ); | 
| 2789 |             } | 
| 2790 |         } | 
| 2791 |   | 
| 2792 |         return te != null ? te : this.getDefaultTemplateEncoding(); | 
| 2793 |     } | 
| 2794 |   | 
| 2795 |     /** | 
| 2796 |      * Gets the encoding to use for reading files. | 
| 2797 |      * | 
| 2798 |      * @return The encoding to use for reading files. | 
| 2799 |      * | 
| 2800 |      * @see #setInputEncoding(java.lang.String) | 
| 2801 |      */ | 
| 2802 |     public final String getInputEncoding() | 
| 2803 |     { | 
| 2804 |         if ( this.inputEncoding == null ) | 
| 2805 |         { | 
| 2806 |             this.inputEncoding = new InputStreamReader( new ByteArrayInputStream( NO_BYTES ) ).getEncoding(); | 
| 2807 |   | 
| 2808 |             if ( this.isLoggable( Level.CONFIG ) ) | 
| 2809 |             { | 
| 2810 |                 this.log( Level.CONFIG, getMessage( "defaultInputEncoding", this.inputEncoding ), null ); | 
| 2811 |             } | 
| 2812 |         } | 
| 2813 |   | 
| 2814 |         return this.inputEncoding; | 
| 2815 |     } | 
| 2816 |   | 
| 2817 |     /** | 
| 2818 |      * Sets the encoding to use for reading files. | 
| 2819 |      * | 
| 2820 |      * @param value The new encoding to use for reading files or {@code null}. | 
| 2821 |      * | 
| 2822 |      * @see #getInputEncoding() | 
| 2823 |      */ | 
| 2824 |     public final void setInputEncoding( final String value ) | 
| 2825 |     { | 
| 2826 |         this.inputEncoding = value; | 
| 2827 |     } | 
| 2828 |   | 
| 2829 |     /** | 
| 2830 |      * Gets the encoding to use for writing files. | 
| 2831 |      * | 
| 2832 |      * @return The encoding to use for writing files. | 
| 2833 |      * | 
| 2834 |      * @see #setOutputEncoding(java.lang.String) | 
| 2835 |      */ | 
| 2836 |     public final String getOutputEncoding() | 
| 2837 |     { | 
| 2838 |         if ( this.outputEncoding == null ) | 
| 2839 |         { | 
| 2840 |             this.outputEncoding = new OutputStreamWriter( new ByteArrayOutputStream() ).getEncoding(); | 
| 2841 |   | 
| 2842 |             if ( this.isLoggable( Level.CONFIG ) ) | 
| 2843 |             { | 
| 2844 |                 this.log( Level.CONFIG, getMessage( "defaultOutputEncoding", this.outputEncoding ), null ); | 
| 2845 |             } | 
| 2846 |         } | 
| 2847 |   | 
| 2848 |         return this.outputEncoding; | 
| 2849 |     } | 
| 2850 |   | 
| 2851 |     /** | 
| 2852 |      * Sets the encoding to use for writing files. | 
| 2853 |      * | 
| 2854 |      * @param value The encoding to use for writing files or {@code null}. | 
| 2855 |      * | 
| 2856 |      * @see #getOutputEncoding() | 
| 2857 |      */ | 
| 2858 |     public final void setOutputEncoding( final String value ) | 
| 2859 |     { | 
| 2860 |         this.outputEncoding = value; | 
| 2861 |     } | 
| 2862 |   | 
| 2863 |     /** | 
| 2864 |      * Gets the default template profile. | 
| 2865 |      * <p>The default template profile is the implicit parent profile of any template profile not specifying a parent | 
| 2866 |      * template profile.</p> | 
| 2867 |      * | 
| 2868 |      * @return The default template profile. | 
| 2869 |      * | 
| 2870 |      * @see #setDefaultTemplateProfile(java.lang.String) | 
| 2871 |      * | 
| 2872 |      * @deprecated The {@code static} modifier of this method and support to setup the default template profile using | 
| 2873 |      * a system property will be removed in version 2.0. | 
| 2874 |      */ | 
| 2875 |     @Deprecated | 
| 2876 |     public static String getDefaultTemplateProfile() | 
| 2877 |     { | 
| 2878 |         if ( defaultTemplateProfile == null ) | 
| 2879 |         { | 
| 2880 |             defaultTemplateProfile = System.getProperty( "org.jomc.tools.JomcTool.defaultTemplateProfile", | 
| 2881 |                                                          DEFAULT_TEMPLATE_PROFILE ); | 
| 2882 |   | 
| 2883 |         } | 
| 2884 |   | 
| 2885 |         return defaultTemplateProfile; | 
| 2886 |     } | 
| 2887 |   | 
| 2888 |     /** | 
| 2889 |      * Sets the default template profile. | 
| 2890 |      * | 
| 2891 |      * @param value The new default template profile or {@code null}. | 
| 2892 |      * | 
| 2893 |      * @see #getDefaultTemplateProfile() | 
| 2894 |      * | 
| 2895 |      * @deprecated The {@code static} modifier of this method will be removed in version 2.0. | 
| 2896 |      */ | 
| 2897 |     @Deprecated | 
| 2898 |     public static void setDefaultTemplateProfile( final String value ) | 
| 2899 |     { | 
| 2900 |         defaultTemplateProfile = value; | 
| 2901 |     } | 
| 2902 |   | 
| 2903 |     /** | 
| 2904 |      * Gets the template profile of the instance. | 
| 2905 |      * | 
| 2906 |      * @return The template profile of the instance. | 
| 2907 |      * | 
| 2908 |      * @see #getDefaultTemplateProfile() | 
| 2909 |      * @see #setTemplateProfile(java.lang.String) | 
| 2910 |      */ | 
| 2911 |     public final String getTemplateProfile() | 
| 2912 |     { | 
| 2913 |         if ( this.templateProfile == null ) | 
| 2914 |         { | 
| 2915 |             this.templateProfile = getDefaultTemplateProfile(); | 
| 2916 |   | 
| 2917 |             if ( this.isLoggable( Level.CONFIG ) ) | 
| 2918 |             { | 
| 2919 |                 this.log( Level.CONFIG, getMessage( "defaultTemplateProfile", this.templateProfile ), null ); | 
| 2920 |             } | 
| 2921 |         } | 
| 2922 |   | 
| 2923 |         return this.templateProfile; | 
| 2924 |     } | 
| 2925 |   | 
| 2926 |     /** | 
| 2927 |      * Sets the template profile of the instance. | 
| 2928 |      * | 
| 2929 |      * @param value The new template profile of the instance or {@code null}. | 
| 2930 |      * | 
| 2931 |      * @see #getTemplateProfile() | 
| 2932 |      */ | 
| 2933 |     public final void setTemplateProfile( final String value ) | 
| 2934 |     { | 
| 2935 |         this.templateProfile = value; | 
| 2936 |     } | 
| 2937 |   | 
| 2938 |     /** | 
| 2939 |      * Gets the parent template profile of a given template profile. | 
| 2940 |      * | 
| 2941 |      * @param tp The template profile to get the parent template profile of. | 
| 2942 |      * | 
| 2943 |      * @return The parent template profile of the template profile identified by {@code tp}; the default template | 
| 2944 |      * profile, if no such parent template profile is defined; {@code null}, if {@code tp} denotes the default template | 
| 2945 |      * profile. | 
| 2946 |      * | 
| 2947 |      * @throws NullPointerException if {@code tp} is {@code null}. | 
| 2948 |      * | 
| 2949 |      * @see #getDefaultTemplateProfile() | 
| 2950 |      * | 
| 2951 |      * @since 1.3 | 
| 2952 |      */ | 
| 2953 |     public final String getParentTemplateProfile( final String tp ) | 
| 2954 |     { | 
| 2955 |         if ( tp == null ) | 
| 2956 |         { | 
| 2957 |             throw new NullPointerException( "tp" ); | 
| 2958 |         } | 
| 2959 |   | 
| 2960 |         String parentTemplateProfile = null; | 
| 2961 |   | 
| 2962 |         try | 
| 2963 |         { | 
| 2964 |             parentTemplateProfile = | 
| 2965 |                 this.getTemplateProfileProperties( tp ).getProperty( PARENT_TEMPLATE_PROFILE_PROPERTY_NAME ); | 
| 2966 |   | 
| 2967 |         } | 
| 2968 |         catch ( final IOException e ) | 
| 2969 |         { | 
| 2970 |             if ( this.isLoggable( Level.SEVERE ) ) | 
| 2971 |             { | 
| 2972 |                 this.log( Level.SEVERE, getMessage( e ), e ); | 
| 2973 |             } | 
| 2974 |         } | 
| 2975 |   | 
| 2976 |         return parentTemplateProfile != null ? parentTemplateProfile | 
| 2977 |                : tp.equals( this.getDefaultTemplateProfile() ) ? null : this.getDefaultTemplateProfile(); | 
| 2978 |   | 
| 2979 |     } | 
| 2980 |   | 
| 2981 |     /** | 
| 2982 |      * Gets the indentation string of the instance. | 
| 2983 |      * | 
| 2984 |      * @return The indentation string of the instance. | 
| 2985 |      * | 
| 2986 |      * @see #setIndentation(java.lang.String) | 
| 2987 |      */ | 
| 2988 |     public final String getIndentation() | 
| 2989 |     { | 
| 2990 |         if ( this.indentation == null ) | 
| 2991 |         { | 
| 2992 |             this.indentation = "    "; | 
| 2993 |   | 
| 2994 |             if ( this.isLoggable( Level.CONFIG ) ) | 
| 2995 |             { | 
| 2996 |                 this.log( Level.CONFIG, getMessage( "defaultIndentation", | 
| 2997 |                                                     StringEscapeUtils.escapeJava( this.indentation ) ), null ); | 
| 2998 |   | 
| 2999 |             } | 
| 3000 |         } | 
| 3001 |   | 
| 3002 |         return this.indentation; | 
| 3003 |     } | 
| 3004 |   | 
| 3005 |     /** | 
| 3006 |      * Gets an indentation string for a given indentation level. | 
| 3007 |      * | 
| 3008 |      * @param level The indentation level to get an indentation string for. | 
| 3009 |      * | 
| 3010 |      * @return The indentation string for {@code level}. | 
| 3011 |      * | 
| 3012 |      * @throws IllegalArgumentException if {@code level} is negative. | 
| 3013 |      * | 
| 3014 |      * @see #getIndentation() | 
| 3015 |      */ | 
| 3016 |     public final String getIndentation( final int level ) | 
| 3017 |     { | 
| 3018 |         if ( level < 0 ) | 
| 3019 |         { | 
| 3020 |             throw new IllegalArgumentException( Integer.toString( level ) ); | 
| 3021 |         } | 
| 3022 |   | 
| 3023 |         Map<String, String> map = this.indentationCache == null ? null : this.indentationCache.get(); | 
| 3024 |   | 
| 3025 |         if ( map == null ) | 
| 3026 |         { | 
| 3027 |             map = new ConcurrentHashMap<String, String>( 8 ); | 
| 3028 |             this.indentationCache = new SoftReference<Map<String, String>>( map ); | 
| 3029 |         } | 
| 3030 |   | 
| 3031 |         final String key = this.getIndentation() + "|" + level; | 
| 3032 |         String idt = map.get( key ); | 
| 3033 |   | 
| 3034 |         if ( idt == null ) | 
| 3035 |         { | 
| 3036 |             final StringBuilder b = new StringBuilder( this.getIndentation().length() * level ); | 
| 3037 |   | 
| 3038 |             for ( int i = level; i > 0; i-- ) | 
| 3039 |             { | 
| 3040 |                 b.append( this.getIndentation() ); | 
| 3041 |             } | 
| 3042 |   | 
| 3043 |             idt = b.toString(); | 
| 3044 |             map.put( key, idt ); | 
| 3045 |         } | 
| 3046 |   | 
| 3047 |         return idt; | 
| 3048 |     } | 
| 3049 |   | 
| 3050 |     /** | 
| 3051 |      * Sets the indentation string of the instance. | 
| 3052 |      * | 
| 3053 |      * @param value The new indentation string of the instance or {@code null}. | 
| 3054 |      * | 
| 3055 |      * @see #getIndentation() | 
| 3056 |      */ | 
| 3057 |     public final void setIndentation( final String value ) | 
| 3058 |     { | 
| 3059 |         this.indentation = value; | 
| 3060 |     } | 
| 3061 |   | 
| 3062 |     /** | 
| 3063 |      * Gets the line separator of the instance. | 
| 3064 |      * | 
| 3065 |      * @return The line separator of the instance. | 
| 3066 |      * | 
| 3067 |      * @see #setLineSeparator(java.lang.String) | 
| 3068 |      */ | 
| 3069 |     public final String getLineSeparator() | 
| 3070 |     { | 
| 3071 |         if ( this.lineSeparator == null ) | 
| 3072 |         { | 
| 3073 |             this.lineSeparator = System.getProperty( "line.separator", "\n" ); | 
| 3074 |   | 
| 3075 |             if ( this.isLoggable( Level.CONFIG ) ) | 
| 3076 |             { | 
| 3077 |                 this.log( Level.CONFIG, getMessage( "defaultLineSeparator", | 
| 3078 |                                                     StringEscapeUtils.escapeJava( this.lineSeparator ) ), null ); | 
| 3079 |   | 
| 3080 |             } | 
| 3081 |         } | 
| 3082 |   | 
| 3083 |         return this.lineSeparator; | 
| 3084 |     } | 
| 3085 |   | 
| 3086 |     /** | 
| 3087 |      * Sets the line separator of the instance. | 
| 3088 |      * | 
| 3089 |      * @param value The new line separator of the instance or {@code null}. | 
| 3090 |      * | 
| 3091 |      * @see #getLineSeparator() | 
| 3092 |      */ | 
| 3093 |     public final void setLineSeparator( final String value ) | 
| 3094 |     { | 
| 3095 |         this.lineSeparator = value; | 
| 3096 |     } | 
| 3097 |   | 
| 3098 |     /** | 
| 3099 |      * Gets the locale of the instance. | 
| 3100 |      * | 
| 3101 |      * @return The locale of the instance. | 
| 3102 |      * | 
| 3103 |      * @see #setLocale(java.util.Locale) | 
| 3104 |      * | 
| 3105 |      * @since 1.2 | 
| 3106 |      */ | 
| 3107 |     public final Locale getLocale() | 
| 3108 |     { | 
| 3109 |         if ( this.locale == null ) | 
| 3110 |         { | 
| 3111 |             this.locale = Locale.ENGLISH; | 
| 3112 |   | 
| 3113 |             if ( this.isLoggable( Level.CONFIG ) ) | 
| 3114 |             { | 
| 3115 |                 this.log( Level.CONFIG, getMessage( "defaultLocale", this.locale ), null ); | 
| 3116 |             } | 
| 3117 |         } | 
| 3118 |   | 
| 3119 |         return this.locale; | 
| 3120 |     } | 
| 3121 |   | 
| 3122 |     /** | 
| 3123 |      * Sets the locale of the instance. | 
| 3124 |      * | 
| 3125 |      * @param value The new locale of the instance or {@code null}. | 
| 3126 |      * | 
| 3127 |      * @see #getLocale() | 
| 3128 |      * | 
| 3129 |      * @since 1.2 | 
| 3130 |      */ | 
| 3131 |     public final void setLocale( final Locale value ) | 
| 3132 |     { | 
| 3133 |         this.locale = value; | 
| 3134 |     } | 
| 3135 |   | 
| 3136 |     /** | 
| 3137 |      * Gets a velocity template for a given name. | 
| 3138 |      * <p>This method searches templates at the following locations recursively in the shown order stopping whenever | 
| 3139 |      * a matching template is found. | 
| 3140 |      * <ol> | 
| 3141 |      *  <li><code>org/jomc/tools/templates/{@link #getTemplateProfile() profile}/{@link #getLocale() language}/<i>templateName</i></code></li> | 
| 3142 |      *  <li><code>org/jomc/tools/templates/{@link #getParentTemplateProfile(java.lang.String) parent profile}/{@link #getLocale() language}/<i>templateName</i></code></li> | 
| 3143 |      *  <li><code>org/jomc/tools/templates/{@link #getTemplateProfile() profile}/<i>templateName</i></code></li> | 
| 3144 |      *  <li><code>org/jomc/tools/templates/{@link #getParentTemplateProfile(java.lang.String) parent profile}/{@link #getLocale() language}/<i>templateName</i></code></li> | 
| 3145 |      * </ol></p> | 
| 3146 |      * | 
| 3147 |      * @param templateName The name of the template to get. | 
| 3148 |      * | 
| 3149 |      * @return The template matching {@code templateName}. | 
| 3150 |      * | 
| 3151 |      * @throws NullPointerException if {@code templateName} is {@code null}. | 
| 3152 |      * @throws FileNotFoundException if no such template is found. | 
| 3153 |      * @throws IOException if getting the template fails. | 
| 3154 |      * | 
| 3155 |      * @see #getTemplateProfile() | 
| 3156 |      * @see #getParentTemplateProfile(java.lang.String) | 
| 3157 |      * @see #getLocale() | 
| 3158 |      * @see #getTemplateEncoding(java.lang.String) | 
| 3159 |      * @see #getVelocityEngine() | 
| 3160 |      */ | 
| 3161 |     public Template getVelocityTemplate( final String templateName ) throws FileNotFoundException, IOException | 
| 3162 |     { | 
| 3163 |         if ( templateName == null ) | 
| 3164 |         { | 
| 3165 |             throw new NullPointerException( "templateName" ); | 
| 3166 |         } | 
| 3167 |   | 
| 3168 |         return this.getVelocityTemplate( this.getTemplateProfile(), templateName ); | 
| 3169 |     } | 
| 3170 |   | 
| 3171 |     /** | 
| 3172 |      * Notifies registered listeners. | 
| 3173 |      * | 
| 3174 |      * @param level The level of the event. | 
| 3175 |      * @param message The message of the event or {@code null}. | 
| 3176 |      * @param throwable The throwable of the event or {@code null}. | 
| 3177 |      * | 
| 3178 |      * @throws NullPointerException if {@code level} is {@code null}. | 
| 3179 |      * | 
| 3180 |      * @see #getListeners() | 
| 3181 |      * @see #isLoggable(java.util.logging.Level) | 
| 3182 |      */ | 
| 3183 |     public void log( final Level level, final String message, final Throwable throwable ) | 
| 3184 |     { | 
| 3185 |         if ( level == null ) | 
| 3186 |         { | 
| 3187 |             throw new NullPointerException( "level" ); | 
| 3188 |         } | 
| 3189 |   | 
| 3190 |         if ( this.isLoggable( level ) ) | 
| 3191 |         { | 
| 3192 |             for ( int i = this.getListeners().size() - 1; i >= 0; i-- ) | 
| 3193 |             { | 
| 3194 |                 this.getListeners().get( i ).onLog( level, message, throwable ); | 
| 3195 |             } | 
| 3196 |         } | 
| 3197 |     } | 
| 3198 |   | 
| 3199 |     private Template findVelocityTemplate( final String location, final String encoding ) throws IOException | 
| 3200 |     { | 
| 3201 |         try | 
| 3202 |         { | 
| 3203 |             return this.getVelocityEngine().getTemplate( location, encoding ); | 
| 3204 |         } | 
| 3205 |         catch ( final ResourceNotFoundException e ) | 
| 3206 |         { | 
| 3207 |             if ( this.isLoggable( Level.FINER ) ) | 
| 3208 |             { | 
| 3209 |                 this.log( Level.FINER, getMessage( "templateNotFound", location ), null ); | 
| 3210 |             } | 
| 3211 |   | 
| 3212 |             return null; | 
| 3213 |         } | 
| 3214 |         catch ( final ParseErrorException e ) | 
| 3215 |         { | 
| 3216 |             String m = getMessage( e ); | 
| 3217 |             m = m == null ? "" : " " + m; | 
| 3218 |   | 
| 3219 |             // JDK: As of JDK 6, "new IOException( message, cause )". | 
| 3220 |             throw (IOException) new IOException( getMessage( "invalidTemplate", location, m ) ).initCause( e ); | 
| 3221 |         } | 
| 3222 |         catch ( final VelocityException e ) | 
| 3223 |         { | 
| 3224 |             String m = getMessage( e ); | 
| 3225 |             m = m == null ? "" : " " + m; | 
| 3226 |   | 
| 3227 |             // JDK: As of JDK 6, "new IOException( message, cause )". | 
| 3228 |             throw (IOException) new IOException( getMessage( "velocityException", location, m ) ).initCause( e ); | 
| 3229 |         } | 
| 3230 |     } | 
| 3231 |   | 
| 3232 |     private java.util.Properties getTemplateProfileContextProperties( final String profileName, final String language ) | 
| 3233 |         throws IOException | 
| 3234 |     { | 
| 3235 |         Map<String, java.util.Properties> map = this.templateProfileContextPropertiesCache == null | 
| 3236 |                                                 ? null : this.templateProfileContextPropertiesCache.get(); | 
| 3237 |   | 
| 3238 |         if ( map == null ) | 
| 3239 |         { | 
| 3240 |             map = new ConcurrentHashMap<String, java.util.Properties>(); | 
| 3241 |             this.templateProfileContextPropertiesCache = new SoftReference<Map<String, java.util.Properties>>( map ); | 
| 3242 |         } | 
| 3243 |   | 
| 3244 |         final String key = profileName + "|" + language; | 
| 3245 |         java.util.Properties profileProperties = map.get( key ); | 
| 3246 |         boolean suppressExceptionOnClose = true; | 
| 3247 |   | 
| 3248 |         if ( profileProperties == null ) | 
| 3249 |         { | 
| 3250 |             InputStream in = null; | 
| 3251 |             URL url = null; | 
| 3252 |             profileProperties = new java.util.Properties(); | 
| 3253 |   | 
| 3254 |             final String resourceName = TEMPLATE_PREFIX + profileName + ( language == null ? "" : "/" + language ) | 
| 3255 |                                         + "/context.properties"; | 
| 3256 |   | 
| 3257 |             try | 
| 3258 |             { | 
| 3259 |                 url = this.getClass().getResource( "/" + resourceName ); | 
| 3260 |   | 
| 3261 |                 if ( url != null ) | 
| 3262 |                 { | 
| 3263 |                     in = url.openStream(); | 
| 3264 |   | 
| 3265 |                     if ( this.isLoggable( Level.CONFIG ) ) | 
| 3266 |                     { | 
| 3267 |                         this.log( Level.CONFIG, getMessage( "contextPropertiesFound", url.toExternalForm() ), null ); | 
| 3268 |                     } | 
| 3269 |   | 
| 3270 |                     profileProperties.load( in ); | 
| 3271 |                 } | 
| 3272 |                 else if ( this.getTemplateLocation() != null ) | 
| 3273 |                 { | 
| 3274 |                     if ( this.isLoggable( Level.CONFIG ) ) | 
| 3275 |                     { | 
| 3276 |                         this.log( Level.CONFIG, getMessage( "contextPropertiesNotFound", resourceName ), null ); | 
| 3277 |                     } | 
| 3278 |   | 
| 3279 |                     url = new URL( this.getTemplateLocation(), resourceName ); | 
| 3280 |                     in = url.openStream(); | 
| 3281 |   | 
| 3282 |                     if ( this.isLoggable( Level.CONFIG ) ) | 
| 3283 |                     { | 
| 3284 |                         this.log( Level.CONFIG, getMessage( "contextPropertiesFound", url.toExternalForm() ), null ); | 
| 3285 |                     } | 
| 3286 |   | 
| 3287 |                     profileProperties.load( in ); | 
| 3288 |                 } | 
| 3289 |                 else if ( this.isLoggable( Level.CONFIG ) ) | 
| 3290 |                 { | 
| 3291 |                     this.log( Level.CONFIG, getMessage( "contextPropertiesNotFound", resourceName ), null ); | 
| 3292 |                 } | 
| 3293 |   | 
| 3294 |                 suppressExceptionOnClose = false; | 
| 3295 |             } | 
| 3296 |             catch ( final FileNotFoundException e ) | 
| 3297 |             { | 
| 3298 |                 if ( this.isLoggable( Level.CONFIG ) ) | 
| 3299 |                 { | 
| 3300 |                     this.log( Level.CONFIG, getMessage( "contextPropertiesNotFound", url.toExternalForm() ), null ); | 
| 3301 |                 } | 
| 3302 |             } | 
| 3303 |             finally | 
| 3304 |             { | 
| 3305 |                 map.put( key, profileProperties ); | 
| 3306 |   | 
| 3307 |                 try | 
| 3308 |                 { | 
| 3309 |                     if ( in != null ) | 
| 3310 |                     { | 
| 3311 |                         in.close(); | 
| 3312 |                     } | 
| 3313 |                 } | 
| 3314 |                 catch ( final IOException e ) | 
| 3315 |                 { | 
| 3316 |                     if ( suppressExceptionOnClose ) | 
| 3317 |                     { | 
| 3318 |                         this.log( Level.SEVERE, getMessage( e ), e ); | 
| 3319 |                     } | 
| 3320 |                     else | 
| 3321 |                     { | 
| 3322 |                         throw e; | 
| 3323 |                     } | 
| 3324 |                 } | 
| 3325 |             } | 
| 3326 |         } | 
| 3327 |   | 
| 3328 |         return profileProperties; | 
| 3329 |     } | 
| 3330 |   | 
| 3331 |     private void mergeTemplateProfileContextProperties( final String profileName, final String language, | 
| 3332 |                                                         final VelocityContext velocityContext ) throws IOException | 
| 3333 |     { | 
| 3334 |         if ( profileName != null ) | 
| 3335 |         { | 
| 3336 |             final java.util.Properties templateProfileProperties = | 
| 3337 |                 this.getTemplateProfileContextProperties( profileName, language ); | 
| 3338 |   | 
| 3339 |             for ( final Enumeration<?> e = templateProfileProperties.propertyNames(); e.hasMoreElements(); ) | 
| 3340 |             { | 
| 3341 |                 final String name = e.nextElement().toString(); | 
| 3342 |                 final String value = templateProfileProperties.getProperty( name ); | 
| 3343 |                 final String[] values = value.split( "\\|" ); | 
| 3344 |   | 
| 3345 |                 if ( !velocityContext.containsKey( name ) ) | 
| 3346 |                 { | 
| 3347 |                     final String className = values[0]; | 
| 3348 |   | 
| 3349 |                     try | 
| 3350 |                     { | 
| 3351 |                         if ( values.length > 1 ) | 
| 3352 |                         { | 
| 3353 |                             final Class<?> valueClass = Class.forName( className ); | 
| 3354 |                             velocityContext.put( name, | 
| 3355 |                                                  valueClass.getConstructor( String.class ).newInstance( values[1] ) ); | 
| 3356 |                         } | 
| 3357 |                         else if ( value.contains( "|" ) ) | 
| 3358 |                         { | 
| 3359 |                             velocityContext.put( name, Class.forName( values[0] ).newInstance() ); | 
| 3360 |                         } | 
| 3361 |                         else | 
| 3362 |                         { | 
| 3363 |                             velocityContext.put( name, value ); | 
| 3364 |                         } | 
| 3365 |                     } | 
| 3366 |                     catch ( final InstantiationException ex ) | 
| 3367 |                     { | 
| 3368 |                         // JDK: As of JDK 6, "new IOException( message, cause )". | 
| 3369 |                         throw (IOException) new IOException( getMessage( | 
| 3370 |                             "contextPropertiesException", profileName + ( language != null ? ", " + language : "" ) ) ). | 
| 3371 |                             initCause( ex ); | 
| 3372 |   | 
| 3373 |                     } | 
| 3374 |                     catch ( final IllegalAccessException ex ) | 
| 3375 |                     { | 
| 3376 |                         // JDK: As of JDK 6, "new IOException( message, cause )". | 
| 3377 |                         throw (IOException) new IOException( getMessage( | 
| 3378 |                             "contextPropertiesException", profileName + ( language != null ? ", " + language : "" ) ) ). | 
| 3379 |                             initCause( ex ); | 
| 3380 |   | 
| 3381 |                     } | 
| 3382 |                     catch ( final InvocationTargetException ex ) | 
| 3383 |                     { | 
| 3384 |                         // JDK: As of JDK 6, "new IOException( message, cause )". | 
| 3385 |                         throw (IOException) new IOException( getMessage( | 
| 3386 |                             "contextPropertiesException", profileName + ( language != null ? ", " + language : "" ) ) ). | 
| 3387 |                             initCause( ex ); | 
| 3388 |   | 
| 3389 |                     } | 
| 3390 |                     catch ( final NoSuchMethodException ex ) | 
| 3391 |                     { | 
| 3392 |                         // JDK: As of JDK 6, "new IOException( message, cause )". | 
| 3393 |                         throw (IOException) new IOException( getMessage( | 
| 3394 |                             "contextPropertiesException", profileName + ( language != null ? ", " + language : "" ) ) ). | 
| 3395 |                             initCause( ex ); | 
| 3396 |   | 
| 3397 |                     } | 
| 3398 |                     catch ( final ClassNotFoundException ex ) | 
| 3399 |                     { | 
| 3400 |                         // JDK: As of JDK 6, "new IOException( message, cause )". | 
| 3401 |                         throw (IOException) new IOException( getMessage( | 
| 3402 |                             "contextPropertiesException", profileName + ( language != null ? ", " + language : "" ) ) ). | 
| 3403 |                             initCause( ex ); | 
| 3404 |   | 
| 3405 |                     } | 
| 3406 |                 } | 
| 3407 |             } | 
| 3408 |   | 
| 3409 |             this.mergeTemplateProfileContextProperties( this.getParentTemplateProfile( profileName ), language, | 
| 3410 |                                                         velocityContext ); | 
| 3411 |   | 
| 3412 |         } | 
| 3413 |     } | 
| 3414 |   | 
| 3415 |     private java.util.Properties getTemplateProfileProperties( final String profileName ) throws IOException | 
| 3416 |     { | 
| 3417 |         Map<String, java.util.Properties> map = this.templateProfilePropertiesCache == null | 
| 3418 |                                                 ? null : this.templateProfilePropertiesCache.get(); | 
| 3419 |   | 
| 3420 |         if ( map == null ) | 
| 3421 |         { | 
| 3422 |             map = new ConcurrentHashMap<String, java.util.Properties>(); | 
| 3423 |             this.templateProfilePropertiesCache = new SoftReference<Map<String, java.util.Properties>>( map ); | 
| 3424 |         } | 
| 3425 |   | 
| 3426 |         java.util.Properties profileProperties = map.get( profileName ); | 
| 3427 |         boolean suppressExceptionOnClose = true; | 
| 3428 |   | 
| 3429 |         if ( profileProperties == null ) | 
| 3430 |         { | 
| 3431 |             InputStream in = null; | 
| 3432 |             profileProperties = new java.util.Properties(); | 
| 3433 |   | 
| 3434 |             final String resourceName = TEMPLATE_PREFIX + profileName + "/profile.properties"; | 
| 3435 |             URL url = null; | 
| 3436 |   | 
| 3437 |             try | 
| 3438 |             { | 
| 3439 |                 url = this.getClass().getResource( "/" + resourceName ); | 
| 3440 |   | 
| 3441 |                 if ( url != null ) | 
| 3442 |                 { | 
| 3443 |                     in = url.openStream(); | 
| 3444 |   | 
| 3445 |                     if ( this.isLoggable( Level.CONFIG ) ) | 
| 3446 |                     { | 
| 3447 |                         this.log( Level.CONFIG, getMessage( "templateProfilePropertiesFound", url.toExternalForm() ), | 
| 3448 |                                   null ); | 
| 3449 |   | 
| 3450 |                     } | 
| 3451 |   | 
| 3452 |                     profileProperties.load( in ); | 
| 3453 |                 } | 
| 3454 |                 else if ( this.getTemplateLocation() != null ) | 
| 3455 |                 { | 
| 3456 |                     if ( this.isLoggable( Level.CONFIG ) ) | 
| 3457 |                     { | 
| 3458 |                         this.log( Level.CONFIG, getMessage( "templateProfilePropertiesNotFound", resourceName ), null ); | 
| 3459 |                     } | 
| 3460 |   | 
| 3461 |                     url = new URL( this.getTemplateLocation(), resourceName ); | 
| 3462 |                     in = url.openStream(); | 
| 3463 |   | 
| 3464 |                     if ( this.isLoggable( Level.CONFIG ) ) | 
| 3465 |                     { | 
| 3466 |                         this.log( Level.CONFIG, getMessage( "templateProfilePropertiesFound", url.toExternalForm() ), | 
| 3467 |                                   null ); | 
| 3468 |   | 
| 3469 |                     } | 
| 3470 |   | 
| 3471 |                     profileProperties.load( in ); | 
| 3472 |                 } | 
| 3473 |                 else if ( this.isLoggable( Level.CONFIG ) ) | 
| 3474 |                 { | 
| 3475 |                     this.log( Level.CONFIG, getMessage( "templateProfilePropertiesNotFound", resourceName ), null ); | 
| 3476 |                 } | 
| 3477 |   | 
| 3478 |                 suppressExceptionOnClose = false; | 
| 3479 |             } | 
| 3480 |             catch ( final FileNotFoundException e ) | 
| 3481 |             { | 
| 3482 |                 if ( this.isLoggable( Level.CONFIG ) ) | 
| 3483 |                 { | 
| 3484 |                     this.log( Level.CONFIG, getMessage( "templateProfilePropertiesNotFound", url.toExternalForm() ), | 
| 3485 |                               null ); | 
| 3486 |   | 
| 3487 |                 } | 
| 3488 |             } | 
| 3489 |             finally | 
| 3490 |             { | 
| 3491 |                 map.put( profileName, profileProperties ); | 
| 3492 |   | 
| 3493 |                 try | 
| 3494 |                 { | 
| 3495 |                     if ( in != null ) | 
| 3496 |                     { | 
| 3497 |                         in.close(); | 
| 3498 |                     } | 
| 3499 |                 } | 
| 3500 |                 catch ( final IOException e ) | 
| 3501 |                 { | 
| 3502 |                     if ( suppressExceptionOnClose ) | 
| 3503 |                     { | 
| 3504 |                         this.log( Level.SEVERE, getMessage( e ), e ); | 
| 3505 |                     } | 
| 3506 |                     else | 
| 3507 |                     { | 
| 3508 |                         throw e; | 
| 3509 |                     } | 
| 3510 |                 } | 
| 3511 |             } | 
| 3512 |         } | 
| 3513 |   | 
| 3514 |         return profileProperties; | 
| 3515 |     } | 
| 3516 |   | 
| 3517 |     private Set<String> getJavaKeywords() | 
| 3518 |     { | 
| 3519 |         Reader in = null; | 
| 3520 |         Set<String> set = this.javaKeywordsCache == null ? null : this.javaKeywordsCache.get(); | 
| 3521 |   | 
| 3522 |         try | 
| 3523 |         { | 
| 3524 |             if ( set == null ) | 
| 3525 |             { | 
| 3526 |                 in = new InputStreamReader( this.getClass().getResourceAsStream( | 
| 3527 |                     "/" + this.getClass().getPackage().getName().replace( ".", "/" ) + "/JavaKeywords.txt" ), "UTF-8" ); | 
| 3528 |   | 
| 3529 |                 set = new CopyOnWriteArraySet<String>( IOUtils.readLines( in ) ); | 
| 3530 |   | 
| 3531 |                 this.javaKeywordsCache = new SoftReference<Set<String>>( set ); | 
| 3532 |             } | 
| 3533 |         } | 
| 3534 |         catch ( final IOException e ) | 
| 3535 |         { | 
| 3536 |             throw new IllegalStateException( getMessage( e ), e ); | 
| 3537 |         } | 
| 3538 |         finally | 
| 3539 |         { | 
| 3540 |             try | 
| 3541 |             { | 
| 3542 |                 if ( in != null ) | 
| 3543 |                 { | 
| 3544 |                     in.close(); | 
| 3545 |                 } | 
| 3546 |             } | 
| 3547 |             catch ( final IOException e ) | 
| 3548 |             { | 
| 3549 |                 throw new IllegalStateException( getMessage( e ), e ); | 
| 3550 |             } | 
| 3551 |         } | 
| 3552 |   | 
| 3553 |         return set; | 
| 3554 |     } | 
| 3555 |   | 
| 3556 |     private Template getVelocityTemplate( final String tp, final String tn ) throws IOException | 
| 3557 |     { | 
| 3558 |         Template template = null; | 
| 3559 |   | 
| 3560 |         if ( tp != null ) | 
| 3561 |         { | 
| 3562 |             final String key = this.getLocale() + "|" + this.getTemplateProfile() + "|" | 
| 3563 |                                + this.getDefaultTemplateProfile() + "|" + tn; | 
| 3564 |   | 
| 3565 |             Map<String, TemplateData> map = this.templateCache == null | 
| 3566 |                                             ? null : this.templateCache.get(); | 
| 3567 |   | 
| 3568 |             if ( map == null ) | 
| 3569 |             { | 
| 3570 |                 map = new ConcurrentHashMap<String, TemplateData>( 32 ); | 
| 3571 |                 this.templateCache = new SoftReference<Map<String, TemplateData>>( map ); | 
| 3572 |             } | 
| 3573 |   | 
| 3574 |             TemplateData templateData = map.get( key ); | 
| 3575 |   | 
| 3576 |             if ( templateData == null ) | 
| 3577 |             { | 
| 3578 |                 templateData = new TemplateData(); | 
| 3579 |   | 
| 3580 |                 if ( !StringUtils.EMPTY.equals( this.getLocale().getLanguage() ) ) | 
| 3581 |                 { | 
| 3582 |                     templateData.location = TEMPLATE_PREFIX + tp + "/" + this.getLocale().getLanguage() + "/" + tn; | 
| 3583 |                     templateData.template = | 
| 3584 |                         this.findVelocityTemplate( templateData.location, this.getTemplateEncoding( tp ) ); | 
| 3585 |   | 
| 3586 |                 } | 
| 3587 |   | 
| 3588 |                 if ( templateData.template == null ) | 
| 3589 |                 { | 
| 3590 |                     templateData.location = TEMPLATE_PREFIX + tp + "/" + tn; | 
| 3591 |                     templateData.template = | 
| 3592 |                         this.findVelocityTemplate( templateData.location, this.getTemplateEncoding( tp ) ); | 
| 3593 |   | 
| 3594 |                 } | 
| 3595 |   | 
| 3596 |                 if ( templateData.template == null ) | 
| 3597 |                 { | 
| 3598 |                     template = this.getVelocityTemplate( this.getParentTemplateProfile( tp ), tn ); | 
| 3599 |   | 
| 3600 |                     if ( template == null ) | 
| 3601 |                     { | 
| 3602 |                         map.put( key, new TemplateData() ); | 
| 3603 |                         throw new FileNotFoundException( getMessage( "noSuchTemplate", tn ) ); | 
| 3604 |                     } | 
| 3605 |                 } | 
| 3606 |                 else | 
| 3607 |                 { | 
| 3608 |                     if ( this.isLoggable( Level.FINER ) ) | 
| 3609 |                     { | 
| 3610 |                         this.log( Level.FINER, getMessage( "templateInfo", tn, templateData.location ), null ); | 
| 3611 |                     } | 
| 3612 |   | 
| 3613 |                     template = templateData.template; | 
| 3614 |                     map.put( key, templateData ); | 
| 3615 |                 } | 
| 3616 |             } | 
| 3617 |             else if ( templateData.template == null ) | 
| 3618 |             { | 
| 3619 |                 throw new FileNotFoundException( getMessage( "noSuchTemplate", tn ) ); | 
| 3620 |             } | 
| 3621 |             else | 
| 3622 |             { | 
| 3623 |                 if ( this.isLoggable( Level.FINER ) ) | 
| 3624 |                 { | 
| 3625 |                     this.log( Level.FINER, getMessage( "templateInfo", tn, templateData.location ), null ); | 
| 3626 |                 } | 
| 3627 |   | 
| 3628 |                 template = templateData.template; | 
| 3629 |             } | 
| 3630 |         } | 
| 3631 |   | 
| 3632 |         return template; | 
| 3633 |     } | 
| 3634 |   | 
| 3635 |     private static String getMessage( final String key, final Object... arguments ) | 
| 3636 |     { | 
| 3637 |         return MessageFormat.format( ResourceBundle.getBundle( | 
| 3638 |             JomcTool.class.getName().replace( '.', '/' ) ).getString( key ), arguments ); | 
| 3639 |   | 
| 3640 |     } | 
| 3641 |   | 
| 3642 |     private static String getMessage( final Throwable t ) | 
| 3643 |     { | 
| 3644 |         return t != null ? t.getMessage() != null ? t.getMessage() : getMessage( t.getCause() ) : null; | 
| 3645 |     } | 
| 3646 |   | 
| 3647 |     /** @since 1.3 */ | 
| 3648 |     private static class TemplateData | 
| 3649 |     { | 
| 3650 |   | 
| 3651 |         private String location; | 
| 3652 |   | 
| 3653 |         private Template template; | 
| 3654 |   | 
| 3655 |     } | 
| 3656 |   | 
| 3657 | } |