1 5 package xdoclet; 6 7 import java.io.File ; 8 import java.net.URL ; 9 import java.text.MessageFormat ; 10 import java.util.ArrayList ; 11 import java.util.Arrays ; 12 13 import java.util.HashMap ; 14 import java.util.Iterator ; 15 import java.util.List ; 16 import java.util.Map ; 17 18 import org.apache.commons.logging.Log; 19 import xjavadoc.XClass; 20 import xjavadoc.XJavaDoc; 21 22 import xdoclet.loader.ModuleFinder; 23 import xdoclet.tagshandler.AbstractProgramElementTagsHandler; 24 import xdoclet.tagshandler.PackageTagsHandler; 25 import xdoclet.template.TemplateEngine; 26 import xdoclet.template.TemplateException; 27 import xdoclet.template.TemplateParser; 28 import xdoclet.util.LogUtil; 29 30 37 public class GenerationManager 38 { 39 private final static File newestJar = ModuleFinder.getNewestFileOnClassPath(); 40 41 private static Map parserDb = null; 42 43 private final TemplateSubTask subTask; 44 45 private boolean guessGenerationNeeded = true; 46 47 private XJavaDoc _xJavaDoc; 48 49 55 public GenerationManager(XJavaDoc xJavaDoc, TemplateSubTask subTask) 56 { 57 if (xJavaDoc == null) { 58 throw new IllegalArgumentException ("xJavaDoc can't be null"); 59 } 60 _xJavaDoc = xJavaDoc; 61 this.subTask = subTask; 62 } 63 64 70 private static Map getParserDb() 71 { 72 if (parserDb == null) { 73 parserDb = new HashMap (); 74 } 75 return parserDb; 76 } 77 78 84 private static void updateParserDb(URL templateURL, String [] files) 85 { 86 String [] mergeFiles = (String []) getParserDb().get(new File (templateURL.getFile()).getName()); 88 List complete = new ArrayList (Arrays.asList(files)); 89 90 if (mergeFiles != null) { 91 for (int j = 0; j < mergeFiles.length; j++) { 92 String file = mergeFiles[j]; 93 94 if (!complete.contains(file)) { 95 complete.add(file); 96 } 97 } 98 } 99 getParserDb().put(new File (templateURL.getFile()).getName(), complete.toArray(new String [complete.size()])); 100 } 101 102 107 public boolean isGuessGenerationNeeded() 108 { 109 return guessGenerationNeeded; 110 } 111 112 121 public boolean isGenerationNeeded(XClass clazz, File file, boolean withTemplate) 122 throws XDocletException 123 { 124 Log log = LogUtil.getLog(GenerationManager.class, "generation"); 125 126 if (subTask.getContext().isForce()) { 127 log.debug("Force generation enabled"); 128 return true; 129 } 130 131 if (isGuessGenerationNeeded() == false) { 132 log.debug("guessGenerationNeeded enabled"); 133 return true; 134 } 135 136 if (isClasspathNewerThanFile(file)) 138 return true; 139 140 if (isClassHierarchyNewerThanFile(clazz, file)) 142 return true; 143 144 if (isTemplateNewerThanFile(withTemplate, file)) 146 return true; 147 148 return false; 149 } 150 151 160 public boolean isGenerationNeeded(File file) 161 throws XDocletException 162 { 163 Log log = LogUtil.getLog(GenerationManager.class, "generation"); 164 165 log.debug("Generation need check for " + file.getName()); 166 167 if (subTask.getContext().isForce()) { 168 log.debug("Force generation enabled"); 169 return true; 170 } 171 172 if (isGuessGenerationNeeded() == false) { 173 log.debug("guessGenerationNeeded enabled"); 174 return true; 175 } 176 177 if (isClasspathNewerThanFile(file) == true) 179 return true; 180 181 if (isGenerationNeeded(file, subTask.getTemplateURL())) { 183 return true; 184 } 185 186 log.debug("Generation need check for " + file.getName()); 187 188 190 for (Iterator i = _xJavaDoc.getSourceClasses().iterator(); i.hasNext(); ) { 191 if (isGenerationNeeded((XClass) i.next(), file, false)) { 192 return true; 193 } 194 } 195 196 return false; 197 } 198 199 204 public void setGuessGenerationNeeded(boolean guessGenerationNeeded) 205 { 206 this.guessGenerationNeeded = guessGenerationNeeded; 207 } 208 209 private boolean isClassHierarchyNewerThanFile(XClass clazz, File file) 210 { 211 Log log = LogUtil.getLog(GenerationManager.class, "generation"); 212 213 while (clazz != null) { 214 if (clazz.getQualifiedName().equals("java.lang.Object")) { 215 return false; 216 } 217 if (file.lastModified() < clazz.lastModified()) { 218 if (log.isDebugEnabled()) { 219 log.debug("Generation needed for '" + file.getAbsolutePath() + "' because " + clazz.getQualifiedName() + " is newer (it's in the class hierarchy)"); 220 } 221 return true; 222 } 223 clazz = clazz.getSuperclass(); 224 } 225 226 return false; 227 } 228 229 private boolean isTemplateNewerThanFile(boolean withTemplate, File file) throws XDocletException 230 { 231 Log log = LogUtil.getLog(GenerationManager.class, "generation"); 232 233 log.debug("Checking template. withTemplate=" + withTemplate); 234 235 if (withTemplate) { 236 if (isGenerationNeeded(file, subTask.getTemplateURL())) { 237 if (log.isDebugEnabled()) { 238 log.debug("Generation needed for '" + file.getAbsolutePath() + "' because template file is newer."); 239 } 240 241 return true; 242 } 243 } 244 245 return false; 246 } 247 248 private boolean isClasspathNewerThanFile(File file) 249 { 250 Log log = LogUtil.getLog(GenerationManager.class, "generation"); 251 252 if (file.lastModified() < newestJar.lastModified()) { 253 if (log.isDebugEnabled()) { 254 log.debug("Generation needed for '" + file.getAbsolutePath() + "' because " + newestJar.getName() + " is newer."); 255 } 256 return true; 257 } 258 259 if (log.isDebugEnabled()) { 260 log.debug("No files on classpath are newer than '" + file.getAbsolutePath() + "'"); 261 } 262 263 return false; 264 } 265 266 275 private boolean isGenerationNeeded(File file, URL templateURL) 276 throws XDocletException 277 { 278 Log log = LogUtil.getLog(GenerationManager.class, "xml"); 279 280 if (log.isDebugEnabled()) { 281 log.debug("Generation need check for " + file.getAbsolutePath()); 282 } 283 284 File templateFile = new File (subTask.getTemplateURL().getFile()); 286 287 if (templateFile.exists() && file.lastModified() < templateFile.lastModified()) { 288 if (log.isDebugEnabled()) { 289 log.debug("Generation needed for '" + file.getAbsolutePath() + "' because of timestamp of " + subTask.getTemplateURL()); 290 } 291 return true; 292 } 293 if (log.isDebugEnabled()) { 294 log.debug("Reject file '" + file.getAbsolutePath() + "' because of timestamp of " + subTask.getTemplateURL()); 295 } 296 297 String [] files; 299 300 if (getParserDb().get(templateFile) == null) { 301 TemplateEngine the_engine = subTask.getEngine(); 302 TemplateParser the_parser = TemplateParser.getParserInstance(); 303 304 subTask.setEngine(the_parser); 305 306 the_parser.setOutput(file); 308 the_parser.setTemplateURL(templateURL); 309 310 try { 311 the_parser.start(); 312 } 313 catch (TemplateException e) { 314 throw new XDocletException(e, e.toString()); 315 } 316 317 files = the_parser.getMergeFiles(); 318 if (files != null) { 319 updateParserDb(templateURL, files); 320 } 321 322 subTask.setEngine(the_engine); 324 } 325 else { 326 files = (String []) getParserDb().get(new File (templateURL.getFile()).getName()); 327 for (int i = 0; i < files.length; i++) { 328 if (log.isDebugEnabled()) { 329 log.debug(templateURL.getFile() + " : " + files[i]); 330 } 331 } 332 } 333 334 log.debug("Number of Merge files involved = " + files.length); 335 336 for (int i = 0; i < files.length; i++) { 337 String mergeFilePattern = files[i]; 338 List mergeFiles = new ArrayList (); 339 340 if (mergeFilePattern.indexOf("{0}") != -1) { 341 342 for (Iterator j = _xJavaDoc.getSourceClasses().iterator(); j.hasNext(); ) { 343 XClass aClass = (XClass) j.next(); 344 String ejbName = MessageFormat.format(mergeFilePattern, new Object []{AbstractProgramElementTagsHandler.getClassNameFor(aClass)}); 345 String mergeFileName = PackageTagsHandler.packageNameAsPathFor(aClass.getContainingPackage()) + File.separator + ejbName; 346 347 if (subTask.getMergeDir() != null) 348 mergeFiles.add(new File (subTask.getMergeDir(), mergeFileName)); 349 } 350 } 351 else { 352 if (subTask.getMergeDir() != null) 353 mergeFiles.add(new File (subTask.getMergeDir(), mergeFilePattern)); 354 } 355 for (Iterator iterator = mergeFiles.iterator(); iterator.hasNext(); ) { 356 File mergeFile = (File ) iterator.next(); 357 358 log.debug("Generation check for '" + file.getAbsolutePath() + "' because of " + mergeFile.getName()); 359 360 if (mergeFile.exists()) { 361 if (file.lastModified() < mergeFile.lastModified()) { 362 log.debug("Generation needed for '" + file.getAbsolutePath() + "' because of timestamp of " + mergeFile.getName()); 363 return true; 364 } 365 log.debug("Reject file '" + file.getAbsolutePath() + "' because of timestamp of " + mergeFile.getName()); 366 } 367 } 368 } 369 return false; 370 } 371 } 372 | Popular Tags |