You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@maven.apache.org by jv...@apache.org on 2002/12/31 08:02:33 UTC
cvs commit: jakarta-turbine-maven/src/java/org/apache/maven/plugin PluginCacheManager.java
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
* <http://www.apache.org/>.
*/
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:
*
* <define:taglib uri="aptdoc">
* <define:jellybean
* name="convert"
* className="org.apache.maven.aptdoc.AptToXdocConverter"
* method="doExecute"
* />
* </define:taglib>
*
* 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());
}
}