Return-Path: Mailing-List: contact turbine-maven-dev-help@jakarta.apache.org; run by ezmlm Delivered-To: mailing list turbine-maven-dev@jakarta.apache.org Received: (qmail 28040 invoked by uid 97); 31 Dec 2002 07:04:04 -0000 Received: (qmail 28028 invoked by uid 98); 31 Dec 2002 07:04:03 -0000 X-Antivirus: nagoya (v4218 created Aug 14 2002) Received: (qmail 27989 invoked from network); 31 Dec 2002 07:04:00 -0000 Received: from daedalus.apache.org (HELO apache.org) (63.251.56.142) by nagoya.betaversion.org with SMTP; 31 Dec 2002 07:04:00 -0000 Received: (qmail 25654 invoked by uid 500); 31 Dec 2002 07:02:35 -0000 Received: (qmail 25646 invoked from network); 31 Dec 2002 07:02:35 -0000 Received: from icarus.apache.org (63.251.56.143) by daedalus.apache.org with SMTP; 31 Dec 2002 07:02:35 -0000 Received: (qmail 82651 invoked by uid 1162); 31 Dec 2002 07:02:33 -0000 Date: 31 Dec 2002 07:02:33 -0000 Message-ID: <20021231070233.82650.qmail@icarus.apache.org> From: jvanzyl@apache.org To: jakarta-turbine-maven-cvs@apache.org Subject: cvs commit: jakarta-turbine-maven/src/java/org/apache/maven/plugin PluginCacheManager.java X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N jvanzyl 2002/12/30 23:02:33 Added: src/java/org/apache/maven/plugin PluginCacheManager.java Log: refactoring. update to follow Revision Changes Path 1.1 jakarta-turbine-maven/src/java/org/apache/maven/plugin/PluginCacheManager.java Index: PluginCacheManager.java =================================================================== package org.apache.maven.plugin; /* ==================================================================== * The Apache Software License, Version 1.1 * * Copyright (c) 2001 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Apache" and "Apache Software Foundation" and * "Apache Maven" must not be used to endorse or promote products * derived from this software without prior written permission. For * written permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache", * "Apache Maven", nor may "Apache" appear in their name, without * prior written permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . */ import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.FileOutputStream; import java.util.Set; import java.util.HashSet; import java.util.Properties; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.Attributes; import org.xml.sax.InputSource; import org.xml.sax.SAXParseException; import org.xml.sax.helpers.DefaultHandler; /** */ public class PluginCacheManager extends DefaultHandler { /** Plug-in cache */ public static final String PLUGINS_CACHE = "plugins.cache"; /** Goal cache */ public static final String GOALS_CACHE = "goals.cache"; public static final String CALLBACKS_CACHE = "callbacks.cache"; /** Taglibs cache */ public static final String DYNAMIC_TAGLIBS_CACHE = "dynatag.cache"; public static final String PLUGIN_DEPS_CACHE = "plugin-dynatag-deps.cache"; private File pluginScript; private String pluginScriptDirectory; private String pluginName; /** * The goals caches contains a mapping of goal names to a description for the * goal and any prerequisite goals. */ private Properties goalCache = new Properties(); /** * The plugin cache contains a mapping of plugin name to the actual directory * name where the plugin is stored in maven's plugin directory. */ private Properties pluginCache = new Properties(); /** * Dyanamic tag libraries that are created within plugin.jelly scripts using * the jelly:define tags. So we might have something like the following: * * * * * * What will end up in the dynamic-taglibs.cache file is something like * the following: * * aptdoc=maven-aptdoc-1.0-SNAPSHOT */ private Properties dynaTagLibCache = new Properties(); /** * This is list of registered preGoals and postGoals in the various plugins. For * example the antlr plugin has preGoal set on java:compile goal to make sure that * that antlr can generate the requested sources before java:compile executes. In * this case we have something like the following registered in the callbacks.cache * file: * * java\:compile.pre=maven-antlr-plugin-1.1-SNAPSHOT * * Note that ":" is a key termination character to the Properties class so we * escape it to be identified as a ":" character. */ private Properties callbackCache = new Properties(); private Properties pluginDepsCache = new Properties(); private Set pluginGoals = new HashSet(); private Set dynaTagLibDecls = new HashSet(); // ---------------------------------------------------------------------- // A C C E S S O R S // ---------------------------------------------------------------------- /** * * @param goalCache */ public void setGoalCache( Properties goalCache ) { this.goalCache = goalCache; } /** * * @return */ public Properties getGoalCache() { return goalCache; } /** * * @param pluginCache */ public void setPluginCache( Properties pluginCache ) { this.pluginCache = pluginCache; } /** * * @return */ public Properties getPluginCache() { return pluginCache; } /** * * @param dynamicTagLibCache */ public void setDynaTagLibCache( Properties dynamicTagLibCache ) { this.dynaTagLibCache = dynamicTagLibCache; } /** * * @return */ public Properties getDynaTagLibCache() { return dynaTagLibCache; } /** * * @param callbackCache */ public void setCallbackCache( Properties callbackCache ) { this.callbackCache = callbackCache; } /** * * @return */ public Properties getCallbackCache() { return callbackCache; } /** * * @param pluginScript */ public void setPluginScript( File pluginScript ) { this.pluginScript = pluginScript; pluginScriptDirectory = pluginScript.getParentFile().getName(); pluginName = pluginScriptDirectory; // When we set a new plugin script to parse clear all our cached // values and start anew. pluginGoals.clear(); dynaTagLibDecls.clear(); } /** * * @return */ public File getPluginScript() { return pluginScript; } private File pluginsDir; /** * Set the pluginsDir attribute. * * @param pluginsDir */ public void setPluginsDir( File pluginsDir ) { this.pluginsDir = pluginsDir; } /** * Get the pluginsDir attribute. * * @return The */ public File getPluginsDir() { return pluginsDir; } /** * Set the pluginDepsCache attribute. * * @param pluginDepsCache */ public void setPluginDepsCache( Properties pluginDepsCache ) { this.pluginDepsCache = pluginDepsCache; } /** * Get the pluginDepsCache attribute. * * @return The */ public Properties getPluginDepsCache() { return pluginDepsCache; } // ---------------------------------------------------------------------- // I M P L E M E N T A T I O N // ---------------------------------------------------------------------- /** */ public void parse() { try { SAXParserFactory saxFactory = SAXParserFactory.newInstance(); saxFactory.setNamespaceAware( true ); SAXParser parser = saxFactory.newSAXParser(); InputSource is = new InputSource(new FileInputStream( getPluginScript() ) ); parser.parse(is, this); } catch (Exception e) { e.printStackTrace(); } } public void saveCache() throws Exception { getPluginCache().store( new FileOutputStream( new File( getPluginsDir(), PLUGINS_CACHE ) ), "plugins cache" ); getGoalCache().store( new FileOutputStream( new File( getPluginsDir(), GOALS_CACHE ) ), "goals cache" ); getCallbackCache().store( new FileOutputStream( new File( getPluginsDir(), CALLBACKS_CACHE ) ), "callbacks cache" ); getDynaTagLibCache().store( new FileOutputStream( new File( getPluginsDir(), DYNAMIC_TAGLIBS_CACHE ) ), "taglibs cache" ); getPluginDepsCache().store( new FileOutputStream( new File( getPluginsDir(), PLUGIN_DEPS_CACHE ) ), "plugin deps cache" ); } /** * Load on-disk cache information, if possible. */ void loadCache() { pluginCache = new Properties(); try { pluginCache.load( new FileInputStream( new File( getPluginsDir(), PLUGINS_CACHE ) ) ); } catch ( IOException e ) { // ignore, new cache. } goalCache = new Properties(); try { goalCache.load( new FileInputStream( new File( getPluginsDir(), GOALS_CACHE ) ) ); } catch ( IOException e ) { // ignore, new cache. } callbackCache = new Properties(); try { callbackCache.load( new FileInputStream( new File( getPluginsDir(), CALLBACKS_CACHE ) ) ); } catch ( IOException e ) { // ignore, new cache; } dynaTagLibCache = new Properties(); try { dynaTagLibCache.load( new FileInputStream( new File( getPluginsDir(), DYNAMIC_TAGLIBS_CACHE ) ) ); } catch ( IOException e ) { // ignore, new cache; } pluginDepsCache = new Properties(); try { pluginDepsCache.load( new FileInputStream( new File( getPluginsDir(), PLUGIN_DEPS_CACHE ) ) ); } catch ( IOException e ) { // ignore, new cache; } } /** * We are looking for namespace declarations like the following: * * xmlns:doc="doc" * * Here we know that the given plugin.jelly script (or any jelly script used * within Maven) has a dependency on the dyna tag lib named 'doc'. We need to * make sure that this dyna tag lib is ready for use when the plugin.jelly * script is run. * * @param prefix Prefix to be used in the jelly script. * @param uri Uri of the dyna tag lib. */ public void startPrefixMapping( String prefix, String uri ) { if ( uri.startsWith("jelly:") == false && uri.startsWith("dummy") == false && uri.equals("") == false ) { dynaTagLibDecls.add( uri ); String p = pluginDepsCache.getProperty( pluginName ); if ( p != null ) { p += "," + uri; } else { p = uri; } pluginDepsCache.setProperty( pluginName, p ); } } /** * Handles opening elements of the xml file. */ public void startElement(String uri, String localName, String rawName, Attributes attributes) { if( rawName.equals("goal") ) { String name = attributes.getValue( "name" ); String prereqs = attributes.getValue( "prereqs" ); String description = attributes.getValue( "description" ); String goalProperty = description + ">"; // Only tack on the descriptions if they are valid. if ( prereqs != null ) { goalProperty += prereqs; } goalCache.setProperty( name , goalProperty ); pluginCache.setProperty( name, pluginScriptDirectory ); pluginGoals.add( name ); } else if( rawName.equals( "preGoal" ) ) { String name = attributes.getValue( "name" ); callbackCache.setProperty( name + ".pre", pluginScriptDirectory ); } else if( rawName.equals( "postGoal" ) ) { String name = attributes.getValue( "name" ); callbackCache.setProperty( name + ".post", pluginScriptDirectory ); } /* else if( rawName.equals( "attainGoal" ) ) { String name = attributes.getValue( "name" ); // We're not using werkz here itself but we need to avoid circular // dependencies when a plugin tries to attain goals that are within // the plugin itself. We are assuming that the stated goal to attain // has already been encountered. Not perfect but I don't think we // should run into any trouble. if ( pluginGoals.contains( name ) == false ) { callbackCache.setProperty( name + ".pre", pluginScriptDirectory ); } } */ // I still have a case that's falling through which is the changelog plugin // and it's dependency on the doc plugin. I need to selectively remove // an individual entry in the CSV list and not the whole thing. else if( localName.equals( "taglib" ) && uri.equals( "jelly:define" ) ) { String tagLibUri = attributes.getValue( "uri" ); dynaTagLibCache.setProperty( tagLibUri, pluginScriptDirectory ); // We don't need to set a dependency if the dyna tag lib is in // the same jelly script where it's used. if ( dynaTagLibDecls.contains( tagLibUri ) ) { String prop = (String) pluginDepsCache.get( pluginName ); int tl = tagLibUri.length(); // If there is only one dependency then just remove the whole entry. if ( prop.indexOf(",") < 0 ) { pluginDepsCache.remove( pluginName ); } else { int i = prop.indexOf( tagLibUri + "," ); if ( i == 0) { // First prop = prop.substring( tl + 1 ); } else if ( i > 0 ) { // Middle prop = prop.substring( 0, i ) + prop.substring( i + tl + 1 ) ; } else { // The last entry prop = prop.substring( 0, prop.length() - tl - 1 ); } pluginDepsCache.put( pluginName, prop ); } } } } /** * Warning callback. * * @param spe The parse exception that caused the callback to be invoked. */ public void warning(SAXParseException spe) { printParseError("Warning", spe); } /** * Error callback. * * @param spe The parse exception that caused the callback to be invoked. */ public void error(SAXParseException spe) { printParseError("Error", spe); } /** * Fatal error callback. * * @param spe The parse exception that caused the callback to be invoked. */ public void fatalError(SAXParseException spe) { printParseError("Fatal Error", spe); } /** * Description of the Method */ private final void printParseError(String type, SAXParseException spe) { System.err.println(type + " [line " + spe.getLineNumber() + ", row " + spe.getColumnNumber() + "]: " + spe.getMessage()); } }