tcurdt 02/05/14 05:50:05 Modified: src/java/org/apache/cocoon/components/language/generator ProgramGeneratorImpl.java Log: restructured the ProgramGenerator. Added the option "watchSource" (turned off by default) so it you can make changes inside the generated files inside the repository and it will compile them for you. This eases debugging of XSP... Revision Changes Path 1.17 +167 -100 xml-cocoon2/src/java/org/apache/cocoon/components/language/generator/ProgramGeneratorImpl.java Index: ProgramGeneratorImpl.java =================================================================== RCS file: /home/cvs/xml-cocoon2/src/java/org/apache/cocoon/components/language/generator/ProgramGeneratorImpl.java,v retrieving revision 1.16 retrieving revision 1.17 diff -u -r1.16 -r1.17 --- ProgramGeneratorImpl.java 14 Apr 2002 03:42:51 -0000 1.16 +++ ProgramGeneratorImpl.java 14 May 2002 12:50:05 -0000 1.17 @@ -80,24 +80,29 @@ import java.io.File; import java.net.MalformedURLException; +import java.util.Date; /** * The default implementation of <code>ProgramGenerator</code> * * @author <a href="mailto:[EMAIL PROTECTED]">Ricardo Rocha</a> * @author <a href="mailto:[EMAIL PROTECTED]">Vadim Gritsenko</a> - * @version CVS $Id: ProgramGeneratorImpl.java,v 1.16 2002/04/14 03:42:51 vgritsenko Exp $ + * @author <a href="mailto:[EMAIL PROTECTED]">Torsten Curdt</a> + * @version CVS $Id: ProgramGeneratorImpl.java,v 1.17 2002/05/14 12:50:05 tcurdt Exp $ */ public class ProgramGeneratorImpl extends AbstractLoggable implements ProgramGenerator, Contextualizable, Composable, Parameterizable, Disposable, ThreadSafe { /** The auto-reloading option */ - protected boolean autoReload = false; + protected boolean autoReload = true; /** The pre-loading option */ protected boolean preload = false; + /** The check for manual source changes in the repository*/ + protected boolean watchSource = false; + /** * The ComponentSelector for programs. Caches Program by program * source file. @@ -146,7 +151,9 @@ String webInf = ctx.getResource("/WEB-INF").toExternalForm(); this.contextDir = webInf.substring(0, webInf.length() - "WEB-INF".length()); } - getLogger().debug("Context directory is " + this.contextDir); + if (getLogger().isDebugEnabled()) { + getLogger().debug("Context directory is " + this.contextDir); + } } catch (MalformedURLException e) { getLogger().warn("Could not get context directory", e); this.contextDir = ""; @@ -179,6 +186,7 @@ this.autoReload = params.getParameterAsBoolean("auto-reload", autoReload); this.rootPackage = params.getParameter("root-package", "org.apache.cocoon.www"); this.preload = params.getParameterAsBoolean("preload", preload); + this.watchSource = params.getParameterAsBoolean("watch-source", watchSource); } /** @@ -224,144 +232,206 @@ // Create file name for the program generated from the provided source. final String normalizedName = getNormalizedName(id); - // Ensure no 2 requests for the same file overlap + if (getLogger().isDebugEnabled()) { + getLogger().debug("Loading serverpage fileName=[" + String.valueOf(fileName) + "]" + + " markupLanguageName=[" + String.valueOf(markupLanguageName) + "]" + + " programmingLanguageName=[" + String.valueOf(programmingLanguageName) + "]" + + " -> normalizedName=[" + String.valueOf(normalizedName) + "]"); + } + + markupLanguage = (MarkupLanguage) this.markupSelector.select(markupLanguageName); + programmingLanguage = (ProgrammingLanguage) this.languageSelector.select(programmingLanguageName); + programmingLanguage.setLanguageName(programmingLanguageName); + Program program = null; CompiledComponent programInstance = null; // Attempt to load program object from cache try { - programInstance = (CompiledComponent)this.cache.select(normalizedName); - } catch (Exception e) { - getLogger().debug("The instance was not accessible from the internal cache. Proceeding."); + programInstance = (CompiledComponent) this.cache.select(normalizedName); + } + catch (Exception e) { + if (getLogger().isDebugEnabled()) { + getLogger().debug("The serverpage [" + String.valueOf(id) + "] is not in the cache yet"); + } } if (programInstance == null && this.preload) { // Preloading: Load program if its source/[object file] is available try { - markupLanguage = - (MarkupLanguage)this.markupSelector.select(markupLanguageName); - programmingLanguage = - (ProgrammingLanguage)this.languageSelector.select(programmingLanguageName); - programmingLanguage.setLanguageName(programmingLanguageName); - program = programmingLanguage.preload(normalizedName, - this.workDir, markupLanguage.getEncoding()); + program = programmingLanguage.preload(normalizedName, this.workDir, markupLanguage.getEncoding()); this.cache.addGenerator(newManager, normalizedName, program); - programInstance = (CompiledComponent)this.cache.select(normalizedName); - } catch (Exception e) { - getLogger().debug("The program was not preloaded"); + programInstance = (CompiledComponent) this.cache.select(normalizedName); + + if (getLogger().isDebugEnabled()) { + getLogger().debug("Successfully preloaded serverpage [" + String.valueOf(id) + "]"); + } + } + catch (Exception e) { + if (getLogger().isErrorEnabled()) { + getLogger().error("The serverpage [" + String.valueOf(id) + "] could not be preloaded"); + } } } - /* - * FIXME: It's the program (not the instance) that must - * be queried for changes!!! - */ - if (programInstance != null && this.autoReload) { - // Autoreloading: Unload program if its source is modified - long lastModified = source.getLastModified(); - if (lastModified == 0 || programInstance.modifiedSince(lastModified)) { - // Release the component. - release(programInstance); - programInstance = null; - - // Unload program - if (programmingLanguage == null) { - programmingLanguage = - (ProgrammingLanguage)this.languageSelector.select(programmingLanguageName); - programmingLanguage.setLanguageName(programmingLanguageName); - } + if (programInstance == null) { + // no instance found + if (getLogger().isDebugEnabled()) { + getLogger().debug("Creating new serverpage for [" + String.valueOf(id) + "]"); + } + synchronized (this) { + generateSourcecode(source, normalizedName, markupLanguage, programmingLanguage, resolver); - programmingLanguage.unload(program, normalizedName, this.workDir); - this.cache.removeGenerator(normalizedName); - program = null; + programInstance = loadProgram(newManager, source, normalizedName, markupLanguage, programmingLanguage, resolver); } } + else { + // found an instance + if (this.autoReload) { + long sourceLastModified = source.getLastModified(); + // has XSP changed? + if (programInstance.modifiedSince(sourceLastModified) || sourceLastModified == 0) { + if (getLogger().isDebugEnabled()) { + getLogger().debug("ReCreating serverpage for [" + String.valueOf(id) + "]"); + } + synchronized (this) { + if (getLogger().isDebugEnabled()) { + getLogger().debug("Releasing old serverpage program [" + String.valueOf(id) + "]"); + } + release(programInstance); + programmingLanguage.unload(program, normalizedName, this.workDir); + this.cache.removeGenerator(normalizedName); + programInstance = null; + program = null; - // Not preloaded or just unloaded: (re)create. - if (programInstance == null) { - if (programmingLanguage == null) { - programmingLanguage = - (ProgrammingLanguage)this.languageSelector.select(programmingLanguageName); - programmingLanguage.setLanguageName(programmingLanguageName); + generateSourcecode(source, normalizedName, markupLanguage, programmingLanguage, resolver); + + programInstance = loadProgram(newManager, source, normalizedName, markupLanguage, programmingLanguage, resolver); + } + } + else { + // check the repository for changes at all? + if (this.watchSource) { + if (getLogger().isDebugEnabled()) { + getLogger().debug("Checking sourcecode of [" + String.valueOf(id) + "] for a change"); + } + File sourcecodeFile = new File(this.workDir, normalizedName + "." + programmingLanguage.getSourceExtension()); + // has sourcecode in repository changed ? + if (sourcecodeFile != null && sourcecodeFile.exists()) { + long sourcecodeLastModified = sourcecodeFile.lastModified(); + if (sourcecodeLastModified > sourceLastModified || sourceLastModified == 0 || sourcecodeLastModified == 0) { + if (getLogger().isDebugEnabled()) { + getLogger().debug("Create new serverpage program for [" + String.valueOf(id) + "] - repository has changed"); + } + synchronized (this) { + if (getLogger().isDebugEnabled()) { + getLogger().debug("Releasing old serverpage program [" + String.valueOf(id) + "]"); + } + release(programInstance); + //programmingLanguage.unload(program, normalizedName, this.workDir); + this.cache.removeGenerator(normalizedName); + programInstance = null; + program = null; + + programInstance = loadProgram(newManager, source, normalizedName, markupLanguage, programmingLanguage, resolver); + } + } + else { + if (getLogger().isDebugEnabled()) { + getLogger().debug("Sourcecode of [" + String.valueOf(id) + "] has not changed - returning program from cache"); + } + } + } + else { + if (getLogger().isErrorEnabled()) { + getLogger().error("Could not find sourcecode for [" + String.valueOf(id) + "]"); + } + } + } + } } - if (markupLanguage == null) { - markupLanguage = - (MarkupLanguage)this.markupSelector.select(markupLanguageName); + else { + if (getLogger().isDebugEnabled()) { + getLogger().debug("Not checking for modifications [autoReload=false] - using current version"); + } } - programInstance = this.createResource(newManager, - source, normalizedName, markupLanguage, - programmingLanguage, resolver); + } // Recompose with the new manager if needed if (programInstance instanceof Recomposable) { - ((Recomposable)programInstance).recompose(newManager); + ((Recomposable) programInstance).recompose(newManager); } - return programInstance; - } finally { + return (programInstance); + } + finally { source.recycle(); this.markupSelector.release(markupLanguage); this.languageSelector.release(programmingLanguage); } } - /** - * Helper method to create resources in a threadsafe manner. - */ - private CompiledComponent createResource(ComponentManager newManager, - Source source, - String normalizedName, - MarkupLanguage markupLanguage, - ProgrammingLanguage programmingLanguage, - SourceResolver resolver) + private CompiledComponent loadProgram( + ComponentManager newManager, + Source source, + String normalizedName, + MarkupLanguage markupLanguage, + ProgrammingLanguage programmingLanguage, + SourceResolver resolver) throws Exception { CompiledComponent programInstance = null; - // Prevent 2 requests from generating this resource simultaneously - synchronized (this) { - // Select first. Works for threads entering this synchronized block - // after another thread - try { - return (CompiledComponent)this.cache.select(normalizedName); - } catch (Exception cme) { } + try { + return (CompiledComponent) this.cache.select(normalizedName); + } + catch (Exception cme) { + } - // If failed, generate. This is for the first thread entering this block - getLogger().debug("Creating resource " + normalizedName); - try { - Program program = this.generateResource(source, - normalizedName, markupLanguage, programmingLanguage, resolver); + try { - // Store generated program in cache - this.cache.addGenerator(newManager, normalizedName, program); - } catch (LanguageException le) { - getLogger().debug("Language Exception", le); - throw new ProcessingException("Language Exception", le); + if (getLogger().isDebugEnabled()) { + getLogger().debug("Loading program [" + String.valueOf(normalizedName) + "]"); } + Program program = programmingLanguage.load(normalizedName, this.workDir, markupLanguage.getEncoding()); - // Select instance of newly generated program - try { - programInstance = (CompiledComponent)this.cache.select(normalizedName); - } catch (Exception cme) { - getLogger().debug("Can't load ServerPage", cme); - throw new ProcessingException("Can't load ServerPage", cme); + this.cache.addGenerator(newManager, normalizedName, program); + if (getLogger().isDebugEnabled()) { + getLogger().debug("Successfully loaded program [" + String.valueOf(normalizedName) + "]"); + } + } + catch (LanguageException le) { + if (getLogger().isErrorEnabled()) { + getLogger().error("Language Exception", le); + } + throw new ProcessingException("Language Exception", le); + } + + try { + programInstance = (CompiledComponent) this.cache.select(normalizedName); + } + catch (Exception cme) { + if (getLogger().isErrorEnabled()) { + getLogger().error("Can't load ServerPage", cme); } + throw new ProcessingException("Can't load ServerPage", cme); } - return programInstance; + return (programInstance); } - /** - * Generates Program out of Source using specified languages. - */ - private Program generateResource(Source source, - String normalizedName, - MarkupLanguage markupLanguage, - ProgrammingLanguage programmingLanguage, - SourceResolver resolver) + + private void generateSourcecode(Source source, + String normalizedName, + MarkupLanguage markupLanguage, + ProgrammingLanguage programmingLanguage, + SourceResolver resolver) throws Exception { + if (getLogger().isDebugEnabled()) { + getLogger().debug("Creating sourcecode for [" + String.valueOf(source.getSystemId()) + "]"); + } // Input Source // FIXME(VG): Use Source.toSAX() InputSource is = source.getInputSource(); @@ -383,12 +453,9 @@ sourceDir.mkdirs(); } IOUtils.serializeString(sourceFile, code); - - // [Compile]/Load generated program - Program program = programmingLanguage.load(normalizedName, - this.workDir, markupLanguage.getEncoding()); - - return program; + if (getLogger().isDebugEnabled()) { + getLogger().debug("Successfully created sourcecode for [" + String.valueOf(source.getSystemId()) + "]"); + } } public void release(CompiledComponent component) {
---------------------------------------------------------------------- In case of troubles, e-mail: [EMAIL PROTECTED] To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]