On Wed, 2002-07-10 at 01:38, John Casey wrote:
> This is kind of a bulk post, but see what you think...I've done quite a
> bit that I'm reporting here, so please be patient.
>
> 1. Forehead - since there doesn't appear to be a mailing list for this,
> I'm submitting my mod here...I've modified the Forehead class to watch
> out for directories specified in the forehead.conf but not in
> existence. It should ignore these.
Forehead is Bob's work, but I'm getting use to it but I can't tell what
you've changed exactly because you didn't send a patch.
> 2. I've modified the start scripts for Jelly that I originally
> submitted, and made them use the attached forehead.properties file to
> start. The current version depends on forehead.jar being in
> $JELLY_HOME/lib...I know this is wrong, I'm just not sure what the best
> fix is yet.
Not sure what you want us to do with this. Have you looked at the Maven
src/bin directory. The scripts there already use forehead.
> 3. I've created a couple of small tag libraries.
>
> The first is called interact. It allows the script to prompt the
> user for input, and stores the results in the JellyContext for later
> use. Initially, values collected are merely stored as Strings.
Cool!
> The second is called entrypoint, and is used to approximate the
> type of process flow seen in Ant. In short, it allows the author to
> define a set of entry points that are either public (default) or not -
> these are like Ant targets. Correspondingly, I've created a tag to
> control the execution of these entry points and their dependencies
> through command line arguments. If an entry point is specified on the
> command line, but is not public, an error is thrown and the entry point
> is skipped. This should help clear up any semantic confusion
> surrounding the usage of goals,etc. that I've read about
> recently...IMHO.
How is this different from what we have with goals using werkz?
> I realize that my tags aren't using the Resource class for
> locale-specific messages yet, but I thought it wise to wait for a
> go-ahead to integrate with the actual project.
>
> Anyway, enjoy, and please give me mucho feedback for making these better
> / scrapping them / etc.
Cool, thanks.
> Regards,
> John
>
>
>
>
> ----
>
>
> package com.werken.forehead;
>
> /*
> $Id: Forehead.java,v 1.2 2002/07/04 21:45:30 werken Exp $
>
> Copyright 2001 (C) The Werken Company. All Rights Reserved.
>
> Redistribution and use of this software and associated documentation
> ("Software"), with or without modification, are permitted provided
> that the following conditions are met:
>
> 1. Redistributions of source code must retain copyright
> statements and notices. Redistributions must also contain a
> copy of this document.
>
> 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 name "Forehead" must not be used to endorse or promote
> products derived from this Software without prior written
> permission of The Werken Company. For written permission,
> please contact [EMAIL PROTECTED]
>
> 4. Products derived from this Software may not be called "Forehead"
> nor may "Forehead" appear in their names without prior written
> permission of The Werken Company. Forehead is a registered
> trademark of The Werken Company.
>
> 5. Due credit should be given to the Forehead Project
> (http://drools.org/).
>
> THIS SOFTWARE IS PROVIDED BY THE WERKEN COMPANY AND CONTRIBUTORS
> ``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 WERKEN COMPANY 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.
>
> */
>
> import java.io.File;
> import java.io.FilenameFilter;
> import java.io.FileInputStream;
> import java.io.InputStream;
> import java.io.InputStreamReader;
> import java.io.BufferedReader;
> import java.io.Reader;
> import java.io.IOException;
> import java.lang.reflect.Method;
> import java.lang.reflect.Modifier;
> import java.lang.reflect.InvocationTargetException;
> import java.net.URL;
> import java.net.MalformedURLException;
> import java.util.HashMap;
> import java.util.Map;
> import java.util.Properties;
>
> /** ClassLoader configurator and application launcher.
> *
> * <p>
> * This is the main command-line entry-point into the
> * <code>forehead</code> framework. Please see
> * the <code>forehead</code> documentation for usage
> * instructions.
> * </p>
> *
> * @author <a href="mailto:[EMAIL PROTECTED]">bob mcwhirter</a>
> */
> public class Forehead
> {
> // ------------------------------------------------------------
> // Class members
> // ------------------------------------------------------------
>
> /** Singleton. */
> private static final Forehead INSTANCE = new Forehead();
>
> // ------------------------------------------------------------
> // Instance members
> // ------------------------------------------------------------
>
> /** ClassLoaders indexed by name. */
> private Map classLoaders;
>
> /** Root unnamed loader. */
> private ForeheadClassLoader rootLoader;
>
> /** The loader to use for entry-point lookup. */
> private ForeheadClassLoader entryLoader;
>
> /** The entry-point class. */
> private Class entryClass;
>
> /** The entry-point method. */
> private Method entryMethod;
>
> // ------------------------------------------------------------
> // Constructors
> // ------------------------------------------------------------
>
> /** Construct.
> */
> public Forehead()
> {
> this.classLoaders = new HashMap();
> }
>
> // ------------------------------------------------------------
> // Instance methods
> // ------------------------------------------------------------
>
> /** Configure from an <code>InputStream</code>.
> *
> * @param in <code>InputStream</code> carrying configuration information.
> *
> * @throws ForeheadException If there is an error during configuration.
> * @throws IOException If there is an error reading configuration information.
> * @throws ClassNotFoundException If unable to locate entry-point class.
> */
> public void config(InputStream in) throws ForeheadException, IOException,
>ClassNotFoundException
> {
> config( new BufferedReader( new InputStreamReader( in ) ) );
> }
>
> /** Configure from an <code>Reader</code>.
> *
> * @param in <code>Reader</code> carrying configuration information.
> *
> * @throws ForeheadException If there is an error during configuration.
> * @throws IOException If there is an error reading configuration information.
> * @throws ClassNotFoundException If unable to locate entry-point class.
> */
> public void config(Reader in) throws ForeheadException, IOException,
>ClassNotFoundException
> {
> if ( in instanceof BufferedReader )
> {
> config( in );
> }
> else
> {
> config( new BufferedReader( in ) );
> }
> }
>
> /** Configure from an <code>BufferedReader</code>.
> *
> * @param in <code>BufferedReader</code> carrying configuration information.
> *
> * @throws ForeheadException If there is an error during configuration.
> * @throws IOException If there is an error reading configuration information.
> * @throws ClassNotFoundException If unable to locate entry-point class.
> */
> public void config(BufferedReader in) throws ForeheadException, IOException,
>ClassNotFoundException
> {
> this.rootLoader = new ForeheadClassLoader( getClass().getClassLoader(),
> "$forehead-root$");
>
> String line = null;
>
> ForeheadClassLoader currentLoader = this.rootLoader;
>
> Properties props = new Properties();
>
> String entryLine = null;
>
> while ( ( line = in.readLine() ) != null )
> {
> line = line.trim();
>
> if ( "".equals( line ) )
> {
> continue;
> }
>
> if ( line.startsWith( "#" ) )
> {
> continue;
> }
>
> if ( line.startsWith( "+" ) )
> {
> String propName = line.substring( 1 );
> String propValue = System.getProperty( propName );
>
> if ( propValue == null )
> {
> throw new NoSuchPropertyException( propName );
> }
>
> props.setProperty( propName,
> propValue );
>
> continue;
> }
>
> if ( line.startsWith( "=" ) )
> {
> entryLine = line;
> continue;
> }
>
> ForeheadClassLoader parentLoader = null;
>
> if ( line.startsWith( "[" )
> &&
> line.endsWith( "]" ) )
> {
> String loaderName = line.substring( 1,
> line.length() - 1 );
>
> int dotLoc = loaderName.lastIndexOf( "." );
>
> if ( dotLoc > 0 )
> {
> String parentName = loaderName.substring( 0,
> dotLoc );
>
> parentLoader = getClassLoader( parentName );
>
> if ( parentLoader == null )
> {
> throw new NoSuchClassLoaderException( parentName );
> }
> }
> else
> {
> parentLoader = this.rootLoader;
> }
>
> currentLoader = createClassLoader( parentLoader, loaderName );
> }
> else
> {
> String resolvedLine = resolveProperties( line, props );
>
> load( resolvedLine,
> currentLoader );
> }
> }
>
>
> if ( entryLine == null )
> {
> throw new NoEntryDescriptorException();
> }
>
> setupEntry( entryLine );
> }
>
> /** Setup the entry-point.
> *
> * @param line The entry-point configuration line.
> *
> * @throws MalformedEntryDescriptorException If the entry-point descriptor is
>malformed.
> * @throws NoSuchClassLoaderException If the entry-point descriptor references
> * an unknown ClassLoader.
> * @throws ClassNotFoundException If unable to locate the entry-point class.
> */
> protected void setupEntry(String line)
> throws MalformedEntryDescriptorException, NoSuchClassLoaderException,
>ClassNotFoundException
> {
> int leftBrackLoc = line.indexOf( "[" );
>
> if ( leftBrackLoc < 0 )
> {
> throw new MalformedEntryDescriptorException( line );
> }
>
> int rightBrackLoc = line.indexOf( "]",
> leftBrackLoc + 1 );
>
> if ( rightBrackLoc < 0 )
> {
> throw new MalformedEntryDescriptorException( line );
> }
>
> String loaderName = line.substring( leftBrackLoc + 1,
> rightBrackLoc );
>
> String className = line.substring( rightBrackLoc + 1 ).trim();
>
> this.entryLoader = getClassLoader( loaderName );
>
> if ( this.entryLoader == null )
> {
> throw new NoSuchClassLoaderException( loaderName );
> }
>
> this.entryClass = Class.forName( className,
> true,
> this.entryLoader );
>
> }
>
> /** Load a glob, file, or URL into the specified classloader.
> *
> * @param line The path configuration line.
> * @param loader The loader to populate
> *
> * @throws MalformedURLException If the line does not represent
> * a valid path element.
> */
> protected void load(String line,
> ForeheadClassLoader loader) throws MalformedURLException
> {
> if ( line.indexOf( "*" ) >= 0 )
> {
> loadGlob( line,
> loader );
> }
> else
> {
> loadFileOrUrl( line,
> loader );
> }
> }
>
> /** Load a glob into the specified classloader.
> *
> * @param line The path configuration line.
> * @param loader The loader to populate
> *
> * @throws MalformedURLException If the line does not represent
> * a valid path element.
> */
> protected void loadGlob(String line,
> ForeheadClassLoader loader) throws MalformedURLException
> {
> File globFile = new File( line );
>
> File dir = globFile.getParentFile();
>
> String localName = globFile.getName();
>
> int starLoc = localName.indexOf( "*" );
>
> final String prefix = localName.substring( 0,
> starLoc );
>
> final String suffix = localName.substring( starLoc + 1 );
>
> if(dir.exists()){
> File[] matches = dir.listFiles(
> new FilenameFilter() {
> public boolean accept(File dir, String name)
> {
> if ( prefix != null
> &&
> !name.startsWith( prefix ) )
> {
> return false;
> }
>
> if ( suffix != null
> &&
> !name.endsWith( suffix ) )
> {
> return false;
> }
>
> return true;
> }
> }
> );
>
> for ( int i = 0 ; i < matches.length ; ++i )
> {
> loader.addURL( matches[i].toURL() );
> }
> }
> }
>
> /** Load a file or URL into the specified classloader.
> *
> * @param line The path configuration line.
> * @param loader The loader to populate
> *
> * @throws MalformedURLException If the line does not represent
> * a valid path element.
> */
> protected void loadFileOrUrl(String line,
> ForeheadClassLoader loader) throws
>MalformedURLException
> {
> URL url = null;
>
> File file = new File( line );
>
> if ( file.exists() )
> {
> url = file.toURL();
> }
> else
> {
> url = new URL( line );
> }
>
> loader.addURL( url );
> }
>
> /** Create a new ClassLoader given a parent and a name.
> *
> * @param parent The parent of the ClassLoader to create.
> * @param name The name of the ClassLoader to create.
> *
> * @return A newly configured <code>ClassLoader</code>.
> */
> protected ForeheadClassLoader createClassLoader(ForeheadClassLoader parent,
> String name)
> {
> ForeheadClassLoader loader = new ForeheadClassLoader( parent,
> name );
>
> this.classLoaders.put( name,
> loader );
>
> return loader;
> }
>
> /** Retrieve a ClassLoader by name.
> *
> * @param name The name of the ClassLoader to retrieve.
> *
> * @return The associated ClassLoader, or <code>null</code>
> * if none.
> */
> public ForeheadClassLoader getClassLoader(String name)
> {
> return (ForeheadClassLoader) this.classLoaders.get( name );
> }
>
> /** Resolve imported properties.
> *
> * @param input The string input to resolve properties.
> * @param props Properties to resolve against.
> *
> * @return The string with properties resolved.
> */
> public String resolveProperties(String input,
> Properties props)
> {
> String output = "";
>
> int cur = 0;
>
> int prefixLoc = 0;
> int suffixLoc = 0;
>
> while ( cur < input.length() )
> {
> prefixLoc = input.indexOf( "${",
> cur );
>
> if ( prefixLoc < 0 )
> {
> //output = output + input.substring( cur );
> break;
> }
>
> suffixLoc = input.indexOf( "}",
> prefixLoc );
>
> String propName = input.substring( prefixLoc + 2,
> suffixLoc );
>
> output = output + input.substring( cur, prefixLoc );
>
> output = output + props.getProperty( propName );
>
> cur = suffixLoc + 1;
> }
>
> output = output + input.substring( cur );
>
> return output;
> }
>
> /** Launch the wrapped application.
> *
> * @param args Command-line args to pass to wrapped application.
> *
> * @throws NoSuchEntryMethodException If unable to find the entry method on the
>class.
> * @throws IllegalAccessException If an error occurs while attempting to invoke
>the
> * entry-point method.
> * @throws InvocationTargetException If an error occurs while attempting to
>invoke the
> * entry-point method.
> */
> public void run(String[] args) throws NoSuchEntryMethodException,
>IllegalAccessException, InvocationTargetException
> {
> Method[] methods = this.entryClass.getMethods();
>
> for ( int i = 0 ; i < methods.length ; ++i )
> {
> if ( !"main".equals( methods[i].getName() ) )
> {
> continue;
> }
>
> int modifiers = methods[i].getModifiers();
>
> if ( !( Modifier.isStatic( modifiers )
> &&
> Modifier.isPublic( modifiers ) ) )
> {
> continue;
> }
>
> if ( methods[i].getReturnType() != Void.TYPE )
> {
> continue;
> }
>
> Class[] paramTypes = methods[i].getParameterTypes();
>
> if ( paramTypes.length != 1 )
> {
> continue;
> }
>
> if ( paramTypes[0] != String[].class )
> {
> continue;
> }
>
> this.entryMethod = methods[i];
> break;
> }
>
> if ( this.entryMethod == null )
> {
> throw new NoSuchEntryMethodException( this.entryClass,
> "public static void main(String[]
>args)" );
> }
>
> Thread.currentThread().setContextClassLoader( this.entryLoader );
>
> this.entryMethod.invoke( this.entryClass,
> new Object[] { args } );
> }
>
> // ------------------------------------------------------------
> // Class methods
> // ------------------------------------------------------------
>
> public static Forehead getInstance()
> {
> return INSTANCE;
> }
>
> /** Main.
> *
> * @param args Command-line arguments to pass to the wrapped
> * application.
> */
> public static void main(String[] args)
> {
> String confFileName = System.getProperty( "forehead.conf.file" );
>
> File confFile = new File( confFileName );
>
> Forehead forehead = Forehead.getInstance();
>
> try
> {
> forehead.config( new FileInputStream( confFile ) );
>
> forehead.run( args );
> }
> catch (NoSuchEntryMethodException e)
> {
> System.err.println( "No method on class " + e.getEntryClass() + "
>matching: " + e.getEntryMethodDescriptor() );
> e.printStackTrace();
> }
> catch (ForeheadException e)
> {
> System.err.println( "Error during configuration: " +
>e.getLocalizedMessage() );
> e.printStackTrace();
> }
> catch (MalformedURLException e)
> {
> e.printStackTrace();
> }
> catch (IOException e)
> {
> System.err.println( "Error reading configuration: " +
>e.getLocalizedMessage() );
> e.printStackTrace();
> }
> catch (ClassNotFoundException e)
> {
> System.err.println( e.getLocalizedMessage() );
> e.printStackTrace();
> }
> catch (Exception e)
> {
> e.printStackTrace();
> }
> }
> }
> ----
>
>
> +ant.home
> +jelly.home
> +tools.jar
>
> =[root.jelly] org.apache.commons.jelly.Jelly
>
> [root]
>
> [root.jelly]
> ${ant.home}/lib/*.jar
> ${jelly.home}/lib/*.jar
> ${jelly.home}/custom/*.jar
> ${jelly.home}/custom
>
> ----
>
> #!/bin/sh
>
> $JAVA_HOME/bin/java -classpath ${CLASSPATH}:${JELLY_HOME}/lib/forehead.jar \
> -Dforehead.conf.file=${JELLY_HOME}/bin/forehead.conf \
> -Dant.home=${ANT_HOME} -Djelly.home=${JELLY_HOME} \
> -Dtools.jar=${JAVA_HOME}/lib/tools.jar com.werken.forehead.Forehead $*
>
> ----
>
> @echo off
>
> %JAVA_HOME%\bin\java -classpath %CLASSPATH%;%JELLY_HOME\lib\forehead.jar
>-Dforehead.conf.file=%JELLY_HOME%\bin\forehead.conf -Dant.home=%ANT_HOME%
>-Djelly.home=%JELLY_HOME% -Dtools.jar=%JAVA_HOME\lib\tools.jar
>com.werken.forehead.Forehead %@
>
> ----
>
> --
> To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>
--
jvz.
Jason van Zyl
[EMAIL PROTECTED]
http://tambora.zenplex.org
In short, man creates for himself a new religion of a rational
and technical order to justify his work and to be justified in it.
-- Jacques Ellul, The Technological Society
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>