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());
      }
  }