You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@river.apache.org by ni...@apache.org on 2008/12/10 06:09:43 UTC

svn commit: r724973 [7/9] - in /incubator/river/jtsk/skunk/niclas1/tools: ./ src/ src/main/ src/main/java/ src/main/java/com/ src/main/java/com/sun/ src/main/java/com/sun/jini/ src/main/java/com/sun/jini/tool/ src/main/java/com/sun/jini/tool/envcheck/ ...

Added: incubator/river/jtsk/skunk/niclas1/tools/src/main/java/com/sun/jini/tool/envcheck/SubVM.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/niclas1/tools/src/main/java/com/sun/jini/tool/envcheck/SubVM.java?rev=724973&view=auto
==============================================================================
--- incubator/river/jtsk/skunk/niclas1/tools/src/main/java/com/sun/jini/tool/envcheck/SubVM.java (added)
+++ incubator/river/jtsk/skunk/niclas1/tools/src/main/java/com/sun/jini/tool/envcheck/SubVM.java Tue Dec  9 21:09:41 2008
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.sun.jini.tool.envcheck;
+
+import java.io.ObjectOutputStream;
+import java.io.PrintStream;
+
+/**
+ * A container for a subtask which runs in a separate and returns a
+ * single object by writing that object to <code>System.out</code>.
+ */
+public class SubVM
+{
+
+    private static PrintStream origOut;
+
+    /**
+     * Entry point for the subtask. The first element of <code>args</code> must
+     * name a <code>SubVMTask</code> to run; the remaining elements comprise the
+     * arguments for the subtask.  That task is instantiated, and its
+     * <code>run(String[] args)</code> method called passing an array containing
+     * only the subtask arguments. The object returned by the <code>run</code>
+     * method is written to <code>System.out</code>. If the <code>run</code>
+     * method throws an exception, then that exception is written to
+     * <code>System.out</code> instead.
+     *
+     * @param args the command line arguments
+     */
+    public static void main( String[] args )
+    {
+        origOut = System.out;
+        System.setOut( System.err );
+        try
+        {
+            if( args.length == 0 )
+            {
+                String msg = "Missing SubVMTask to instantiate in arg 0";
+                writeResponse( new IllegalStateException( msg ) );
+                System.exit( 1 );
+            }
+            Class subVMTaskClass = Class.forName( args[ 0 ] );
+            SubVMTask task = (SubVMTask) subVMTaskClass.newInstance();
+            String[] newArgs = new String[args.length - 1];
+            System.arraycopy( args, 1, newArgs, 0, newArgs.length );
+            writeResponse( task.run( newArgs ) );
+            System.exit( 0 );
+        }
+        catch( Throwable t )
+        {
+            try
+            {
+                writeResponse( t );
+
+            }
+            catch( Throwable fatal )
+            {
+                fatal.printStackTrace();
+            }
+            System.exit( 1 );
+        }
+    }
+
+    /**
+     * Write the serialized form of the given object to <code>System.out</code>.
+     *
+     * @param obj the object to write
+     */
+    private static void writeResponse( Object obj ) throws Throwable
+    {
+        ObjectOutputStream os = new ObjectOutputStream( origOut );
+        os.writeObject( obj );
+        os.close();
+    }
+}

Added: incubator/river/jtsk/skunk/niclas1/tools/src/main/java/com/sun/jini/tool/envcheck/SubVMTask.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/niclas1/tools/src/main/java/com/sun/jini/tool/envcheck/SubVMTask.java?rev=724973&view=auto
==============================================================================
--- incubator/river/jtsk/skunk/niclas1/tools/src/main/java/com/sun/jini/tool/envcheck/SubVMTask.java (added)
+++ incubator/river/jtsk/skunk/niclas1/tools/src/main/java/com/sun/jini/tool/envcheck/SubVMTask.java Tue Dec  9 21:09:41 2008
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.sun.jini.tool.envcheck;
+
+/**
+ * A subtask to be run in a separate VM. Classes implementing this
+ * interface must provide a public no-arg constructor.
+ */
+public interface SubVMTask
+{
+
+    /**
+     * Run the subtask. Return an object representing the
+     * result of the task. If an unexpected exception is thrown
+     * in the body of the method, it should be caught and used
+     * as the returned object.
+     *
+     * @param args
+     * @return the task status object, which may be <code>null</code>
+     */
+    public Object run( String[] args );
+}

Added: incubator/river/jtsk/skunk/niclas1/tools/src/main/java/com/sun/jini/tool/envcheck/Util.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/niclas1/tools/src/main/java/com/sun/jini/tool/envcheck/Util.java?rev=724973&view=auto
==============================================================================
--- incubator/river/jtsk/skunk/niclas1/tools/src/main/java/com/sun/jini/tool/envcheck/Util.java (added)
+++ incubator/river/jtsk/skunk/niclas1/tools/src/main/java/com/sun/jini/tool/envcheck/Util.java Tue Dec  9 21:09:41 2008
@@ -0,0 +1,276 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.sun.jini.tool.envcheck;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.text.MessageFormat;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.Properties;
+import java.util.ResourceBundle;
+
+/**
+ * Miscellaneous utility methods for use by the checking framework
+ * and plugins.
+ */
+public class Util
+{
+
+    /**
+     * table of localization resources
+     */
+    private static final HashMap resourceMap = new HashMap();
+
+    /**
+     * the resource bundle for this class
+     */
+    private static ResourceBundle bundle = getResourceBundle( EnvCheck.class );
+
+    /**
+     * the properties which were provided to the local VM
+     */
+    private static Properties nonStandardProperties = null;
+
+    /**
+     * Validate the accessibility of the non-directory file identified by
+     * <code>name</code>. The file must exist, must not be a directory, and must
+     * be readable.  If any check fails, an error message is returned. If all
+     * checks are successful, <code>null</code> is returned.
+     *
+     * @param name the file name
+     * @param desc a short descriptive string which describes the file, suitable
+     *             for inclusion in the error message
+     * @return and error message, or <code>null</code> if all checks pass
+     */
+    public static String checkFileName( String name, String desc )
+    {
+        File file = new File( name );
+        String canonicalPath = null;
+        try
+        {
+            canonicalPath = file.getCanonicalPath();
+        }
+        catch( Exception e )
+        {
+            return getString( "util.cantresolve", bundle, desc, name );
+        }
+        if( !file.exists() )
+        {
+            return getString( "util.notexist", bundle, desc, canonicalPath );
+        }
+        if( file.isDirectory() )
+        {
+            return getString( "util.isdir", bundle, desc, canonicalPath );
+        }
+        if( !file.canRead() )
+        {
+            return getString( "util.cantread", bundle, desc, canonicalPath );
+        }
+        return null;
+    }
+
+    /**
+     * Check the accessibility of the given <code>URL</code>. If the
+     * url is a <code>file:</code> url, the usual file access checks are
+     * performed. For any other url a stream is opened, and a non-exceptional
+     * return is considered a success.
+     *
+     * @param url  the <code>URL</code> to check
+     * @param desc a description of the source of the url
+     * @return an error message, or <code>null</code> if the access check passes
+     */
+    public static String checkURL( URL url, String desc )
+    {
+        if( "file".equals( url.getProtocol() ) )
+        {
+            String path = url.getFile().replace( '/', File.separatorChar );
+            return checkFileName( path, desc );
+        }
+        else
+        {
+            try
+            {
+                url.openStream().close();
+                return null;
+            }
+            catch( IOException e )
+            {
+                return getString( "util.cantreadURL",
+                                  bundle,
+                                  url.toString(),
+                                  desc );
+            }
+        }
+    }
+
+    /**
+     * Validate the accessibility of the non-directory file identified by the
+     * system property <code>prop</code>. The system property must have a
+     * non-<code>null</code> value. The file identified by the value must exist,
+     * must not be a directory, and must be readable.  If any check fails, an
+     * error message is returned. If all checks are successful,
+     * <code>null</code> is returned.
+     *
+     * @param prop name of a system property whose value must be a file name
+     * @param desc a short descriptive string which describes the file, suitable
+     *             for inclusion in the error message
+     * @return an error message, or <code>null</code> if all checks pass
+     */
+    public static String checkSystemPropertyFile( String prop, String desc )
+    {
+        String name = System.getProperty( prop );
+        if( name == null )
+        {
+            return getString( "util.undef", bundle, desc );
+        }
+        return checkFileName( name, desc );
+    }
+
+    /**
+     * Get the resource bundle associated with class <code>clazz</code>.  The
+     * resource bundle name is constructed by the class name to lower case and
+     * inserting <code>.resources</code> in front of the name. Thus, if
+     * <code>clazz.getName()</code> returned <code>a.b.Foo</code> then the
+     * associated resource bundle name would be <code>a.b.resources.foo</code>.
+     * If no resource bundle having the associated name is found, a stack trace
+     * is printed and <code>null</code> is returned. The resource bundle is
+     * loaded using the class loader for the given class, and is cached so that
+     * the search is performed only once.
+     *
+     * @param clazz the class for which to obtain a resource bundle
+     * @return the resource bundle
+     */
+    public static ResourceBundle getResourceBundle( Class clazz )
+    {
+        if( resourceMap.containsKey( clazz ) )
+        {
+            return (ResourceBundle) resourceMap.get( clazz );
+        }
+        String className = clazz.getName();
+        int lastDot = className.lastIndexOf( "." );
+        if( lastDot < 0 )
+        {
+            throw new IllegalStateException( "Class is in default package" );
+        }
+        String pkgName = className.substring( 0, lastDot );
+        // includes leading '.'
+        String resourceName = className.substring( lastDot ).toLowerCase();
+        String bundleName = pkgName + ".resources" + resourceName;
+        ResourceBundle bundle = null;
+        try
+        {
+            bundle = ResourceBundle.getBundle( bundleName,
+                                               Locale.getDefault(),
+                                               clazz.getClassLoader() );
+        }
+        catch( MissingResourceException e )
+        {
+            e.printStackTrace(); //XXX should failures be silent?
+        }
+        resourceMap.put( clazz, bundle );
+        return bundle;
+    }
+
+    /**
+     * Get the format string associated with <code>key</code> in the
+     * given resource bundle. If <code>key</code> is not present in
+     * the bundle, a default format string is returned which will
+     * identify the missing key when printed.
+     *
+     * @param key    the key of the format string to retrieve
+     * @param bundle the bundle to retrieve the format string from
+     * @return the format string.
+     */
+    private static String getFormat( String key, ResourceBundle bundle )
+    {
+        String fmt = "no text found: \"" + key + "\" {0}";
+        if( bundle != null )
+        {
+            try
+            {
+                fmt = bundle.getString( key );
+            }
+            catch( MissingResourceException e )
+            {
+            }
+        }
+        return fmt;
+    }
+
+    /**
+     * Print out string according to resourceBundle format.
+     *
+     * @param key    the key of the format string to retrieve
+     * @param bundle the bundle to retrieve the format string from
+     */
+    public static String getString( String key, ResourceBundle bundle )
+    {
+        return MessageFormat.format( getFormat( key, bundle ), null );
+    }
+
+    /**
+     * Print out string according to resourceBundle format.
+     *
+     * @param key    the key of the format string to retrieve
+     * @param bundle the bundle to retrieve the format string from
+     * @param val    the value to substitute into the {0} parameter
+     */
+    public static String getString( String key, ResourceBundle bundle, Object val )
+    {
+        return MessageFormat.format( getFormat( key, bundle ), new Object[]{ val } );
+    }
+
+    /**
+     * Print out string according to resourceBundle format.
+     *
+     * @param key    the key of the format string to retrieve
+     * @param bundle the bundle to retrieve the format string from
+     * @param val1   the value to substitute into the {0} parameter
+     * @param val2   the value to substitute into the {1} parameter
+     */
+    public static String getString( String key,
+                                    ResourceBundle bundle,
+                                    Object val1,
+                                    Object val2 )
+    {
+        return MessageFormat.format( getFormat( key, bundle ),
+                                     new Object[]{ val1, val2 } );
+    }
+
+    /**
+     * Print out string according to resourceBundle format.
+     *
+     * @param key    the key of the format string to retrieve
+     * @param bundle the bundle to retrieve the format string from
+     * @param val1   the value to substitute into the {0} parameter
+     * @param val2   the value to substitute into the {1} parameter
+     * @param val3   the value to substitute into the {2} parameter
+     */
+    public static String getString( String key,
+                                    ResourceBundle bundle,
+                                    Object val1,
+                                    Object val2,
+                                    Object val3 )
+    {
+        return MessageFormat.format( getFormat( key, bundle ),
+                                     new Object[]{ val1, val2, val3 } );
+    }
+}

Added: incubator/river/jtsk/skunk/niclas1/tools/src/main/java/com/sun/jini/tool/envcheck/package.html
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/niclas1/tools/src/main/java/com/sun/jini/tool/envcheck/package.html?rev=724973&view=auto
==============================================================================
--- incubator/river/jtsk/skunk/niclas1/tools/src/main/java/com/sun/jini/tool/envcheck/package.html (added)
+++ incubator/river/jtsk/skunk/niclas1/tools/src/main/java/com/sun/jini/tool/envcheck/package.html Tue Dec  9 21:09:41 2008
@@ -0,0 +1,28 @@
+<!--
+ ! Licensed to the Apache Software Foundation (ASF) under one
+ ! or more contributor license agreements.  See the NOTICE file
+ ! distributed with this work for additional information
+ ! regarding copyright ownership. The ASF licenses this file
+ ! to you under the Apache License, Version 2.0 (the
+ ! "License"); you may not use this file except in compliance
+ ! with the License. You may obtain a copy of the License at
+ ! 
+ !      http://www.apache.org/licenses/LICENSE-2.0
+ ! 
+ ! Unless required by applicable law or agreed to in writing, software
+ ! distributed under the License is distributed on an "AS IS" BASIS,
+ ! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ! See the License for the specific language governing permissions and
+ ! limitations under the License.
+ !-->
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+
+</head>
+<body bgcolor="white">
+
+Tool for examining the run-time environment of a Jini component.
+
+</body>
+</html>

Added: incubator/river/jtsk/skunk/niclas1/tools/src/main/java/com/sun/jini/tool/envcheck/plugins/CheckActivationSystem.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/niclas1/tools/src/main/java/com/sun/jini/tool/envcheck/plugins/CheckActivationSystem.java?rev=724973&view=auto
==============================================================================
--- incubator/river/jtsk/skunk/niclas1/tools/src/main/java/com/sun/jini/tool/envcheck/plugins/CheckActivationSystem.java (added)
+++ incubator/river/jtsk/skunk/niclas1/tools/src/main/java/com/sun/jini/tool/envcheck/plugins/CheckActivationSystem.java Tue Dec  9 21:09:41 2008
@@ -0,0 +1,158 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.sun.jini.tool.envcheck.plugins;
+
+import com.sun.jini.tool.envcheck.AbstractPlugin;
+import com.sun.jini.tool.envcheck.EnvCheck;
+import com.sun.jini.tool.envcheck.Reporter;
+import com.sun.jini.tool.envcheck.Reporter.Message;
+import com.sun.jini.tool.envcheck.SubVMTask;
+import java.rmi.activation.ActivationGroup;
+import java.security.AccessControlException;
+
+/**
+ * Plugin which checks the liveness of the activation system. The
+ * check will be performed if either:
+ *
+ * <ul>
+ * <li>the <code>Configuration</code> for the tool includes an entry
+ * named <code>activation</code> which is a boolean and has a
+ * value of <code>true</code>.
+ * <li>a service starter configuration is being checked and it contains
+ * an entry of type <code>SharedActivatableServiceDescriptor</code>.
+ * </ul>
+ * The check is performed by calling <code>ActivationGroup.getSystem()</code>.
+ * A non-exceptional return indicates liveness.
+ */
+public class CheckActivationSystem extends AbstractPlugin
+{
+
+    /**
+     * reference to the container
+     */
+    private EnvCheck envCheck;
+
+    /**
+     * flag indicating whether to perform the check
+     */
+    private static boolean doCheck = false;
+
+    /**
+     * Test whether to unconditionally test for the presence of the
+     * activation system. This will be the case if <code>opt</code> is
+     * the command-line option <code>-activation</code>.
+     *
+     * @param opt the command-line option
+     * @return true if the option is recognized by this plugin
+     */
+    public boolean isPluginOption( String opt )
+    {
+        if( opt.equals( "-activation" ) )
+        {
+            doCheck = true;
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Determine whether to perform this check, and perform the
+     * check if appropriate.
+     */
+    // XXX add support for non-default host/port values
+    public void run( EnvCheck envCheck )
+    {
+        this.envCheck = envCheck;
+        if( doCheck || envCheck.getGroupDescriptor() != null )
+        {
+            checkAvailability();
+        }
+    }
+
+    /**
+     * Performs the check
+     */
+    private void checkAvailability()
+    {
+        Message message;
+        String taskName = taskName( "CheckActivationTask" );
+        // OK if envCheck.getGroupDescriptor() returns null
+        Object launchReturn = envCheck.launch( null,
+                                               envCheck.getGroupDescriptor(),
+                                               taskName );
+        if( launchReturn == null )
+        {
+            message = new Message( Reporter.INFO,
+                                   getString( "running" ),
+                                   getString( "explanationString" ) );
+        }
+        else
+        {
+            Throwable ex = (Throwable) launchReturn;
+            Throwable t = ex.getCause();
+            if( t == null )
+            {
+                t = ex;
+            }
+            if( t instanceof java.rmi.ConnectException )
+            {
+                message = new Message( Reporter.WARNING,
+                                       getString( "notRunning" ),
+                                       t,
+                                       getString( "explanationString" ) );
+            }
+            else if( t instanceof AccessControlException )
+            {
+                message = new Message( Reporter.WARNING,
+                                       getString( "nopermission" ),
+                                       t,
+                                       getString( "noPermExplanationString" ) );
+            }
+            else
+            {
+                message = new Message( Reporter.WARNING,
+                                       getString( "unexpectedException" ),
+                                       ex,
+                                       getString( "unexpectedExplanationString" ) );
+            }
+        }
+        Reporter.print( message );
+    }
+
+    /**
+     * subtask to perform the actual check
+     */
+    public static class CheckActivationTask implements SubVMTask
+    {
+
+        public Object run( String[] args )
+        {
+//          don't make the test sensitive to policy settings for now
+//  	    System.setSecurityManager(new RMISecurityManager());
+            try
+            {
+                ActivationGroup.getSystem();
+                return null;
+            }
+            catch( Throwable e )
+            {
+                return e;
+            }
+        }
+    }
+}

Added: incubator/river/jtsk/skunk/niclas1/tools/src/main/java/com/sun/jini/tool/envcheck/plugins/CheckCodebase.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/niclas1/tools/src/main/java/com/sun/jini/tool/envcheck/plugins/CheckCodebase.java?rev=724973&view=auto
==============================================================================
--- incubator/river/jtsk/skunk/niclas1/tools/src/main/java/com/sun/jini/tool/envcheck/plugins/CheckCodebase.java (added)
+++ incubator/river/jtsk/skunk/niclas1/tools/src/main/java/com/sun/jini/tool/envcheck/plugins/CheckCodebase.java Tue Dec  9 21:09:41 2008
@@ -0,0 +1,473 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.sun.jini.tool.envcheck.plugins;
+
+import com.sun.jini.start.NonActivatableServiceDescriptor;
+import com.sun.jini.start.ServiceDescriptor;
+import com.sun.jini.start.SharedActivationGroupDescriptor;
+import com.sun.jini.tool.envcheck.AbstractPlugin;
+import com.sun.jini.tool.envcheck.EnvCheck;
+import com.sun.jini.tool.envcheck.Reporter;
+import com.sun.jini.tool.envcheck.Reporter.Message;
+import com.sun.jini.tool.envcheck.SubVMTask;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.InetAddress;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.UnknownHostException;
+import java.util.StringTokenizer;
+
+/**
+ * Plugin which performs a variety of checks on codebase components.  If not
+ * configured to perform service starter checks, the codebase is expected to be
+ * defined by the <code>java.rmi.server.codebase</code> system
+ * property. Otherwise, all of the codebases contained in the service
+ * descriptors of the service starter <code>Configuration</code> are examined
+ * (excepting <code>SharedActivationGroupDescriptors</code>, which do not have a
+ * codebase). First, an existence check is performed; the codebase string must
+ * be non-null and have length > 0 after white space is trimmed. Non-existence
+ * is reported as an error. Then the codebase is decomposed into tokens (URL
+ * strings). Each component in a codebase is checked for the following:
+ * <ul>
+ * <li>check for a valid URL. As a special case, an httpmd URL which
+ * is invalid because the necessary protocol handler was not loaded
+ * will result in the generation of an appropriate error message
+ * and explanation. Further checks are not done for invalid URLs.
+ * <li>check that the host name is expressed using a fully qualified domain name
+ * <li>check for the use of md5 hashes in httpmd URLs
+ * <li>check the ability to resolve the host name to an address
+ * <li>check for a host name of 'localhost'
+ * <li>check for the ability to access (connect to) the URL
+ * </ul>
+ * Failure of the first or last checks are displayed as errors. Failure of
+ * the other checks are displayed as warnings.
+ */
+public class CheckCodebase extends AbstractPlugin
+{
+
+    /**
+     * reference to the plugin container
+     */
+    EnvCheck envCheck;
+
+    /**
+     * Depending on whether service start checks are configured,
+     * either check the codebase system property or all of the
+     * <code>ServiceDescriptors</code> that are <code>instanceof</code>
+     * <code>NonActivatableServiceDescriptor</code>.
+     */
+    public void run( EnvCheck envCheck )
+    {
+        this.envCheck = envCheck;
+        String source;
+        String codebase;
+        if( envCheck.getDescriptors().length == 0 )
+        {
+            source = getString( "propsource" );
+            codebase = envCheck.getProperty( "java.rmi.server.codebase" );
+            doChecks( null, null, source, codebase );
+        }
+        else
+        {
+            ServiceDescriptor[] sd = envCheck.getDescriptors();
+            SharedActivationGroupDescriptor g = envCheck.getGroupDescriptor();
+            for( int i = 0; i < sd.length; i++ )
+            {
+                if( sd[ i ] instanceof NonActivatableServiceDescriptor )
+                {
+                    NonActivatableServiceDescriptor d =
+                        (NonActivatableServiceDescriptor) sd[ i ];
+                    source = getString( "desc" ) + " " + d.getImplClassName();
+                    codebase = d.getExportCodebase();
+                    doChecks( d, g, source, codebase );
+                }
+            }
+        }
+    }
+
+    /**
+     * Perform all of the checks on <code>codebase</code>.
+     *
+     * @param source   a string describing the source of the codebase for
+     *                 use in report messages
+     * @param codebase the codebase to check
+     */
+    private void doChecks( NonActivatableServiceDescriptor d,
+                           SharedActivationGroupDescriptor g,
+                           String source,
+                           String codebase )
+    {
+        if( checkExistance( source, codebase ) )
+        {
+            StringTokenizer tok = new StringTokenizer( codebase );
+            while( tok.hasMoreTokens() )
+            {
+                String urlToken = tok.nextToken();
+                URL url = checkURL( d, g, source, urlToken );
+                if( url != null )
+                {
+                    checkForFQDomain( url, source );
+                    checkForMD5( url, source );
+                    checkForKnownHost( url, source );
+                    checkForLocalHost( url, source );
+                    checkAccessibility( url, source );
+                }
+            }
+        }
+    }
+
+    /**
+     * Check for existence. <code>codebase</code> must be non-null
+     * and have length > 0 after trimming whitespace.
+     *
+     * @param source   identifies the source of the codebase
+     * @param codebase the codebase to check
+     * @return true if existence check is successful
+     */
+    private boolean checkExistance( String source, final String codebase )
+    {
+        Message message;
+        boolean gotCodebase;
+        if( codebase != null && codebase.trim().length() > 0 )
+        {
+            message = new Message( Reporter.INFO,
+                                   getString( "codebaseIs" ) + " " + codebase,
+                                   getString( "existenceExp" ) );
+            gotCodebase = true;
+        }
+        else
+        {
+            message = new Message( Reporter.INFO,
+                                   getString( "nocodebase" ),
+                                   getString( "existenceExp" ) );
+            gotCodebase = false;
+        }
+        Reporter.print( message, source );
+        return gotCodebase;
+    }
+
+    /**
+     * Check whether <code>urlToken</code> can be used to construct
+     * a <code>URL</code> object. If a <code>MalformedURLException</code>
+     * is thrown, check whether the protocol portion of the URL is
+     * <code>httpmd:</code>. If so, check whether the protocol handler is
+     * installed. If not, output an appropriate message. Otherwise, just
+     * complain generally that the URL is malformed.
+     *
+     * @param source   the source of the codebase
+     * @param urlToken the codebase component to check
+     * @return the corresponding URL object if successful, <code>null</code>
+     *         otherwise
+     */
+    private URL checkURL( NonActivatableServiceDescriptor d,
+                          SharedActivationGroupDescriptor g,
+                          String source,
+                          final String urlToken )
+    {
+        Message message;
+        URL url = null;
+        String[] args = new String[]{ urlToken };
+        Object lobj = envCheck.launch( d, g, taskName( "GetURLTask" ), args );
+        if( lobj instanceof URL )
+        {
+            url = (URL) lobj;
+        }
+        else if( lobj instanceof String )
+        {
+            String cause = (String) lobj;
+            if( cause.equals( "nohandler" ) )
+            {
+                message = new Message( Reporter.ERROR,
+                                       getString( "nohandler", urlToken ),
+                                       getString( "httpmdExp" ) );
+                Reporter.print( message, source );
+                try
+                {
+                    url = new URL( urlToken );
+                }
+                catch( MalformedURLException e )
+                { // should never happen
+                    message = new Message( Reporter.ERROR,
+                                           getString( "badURL", urlToken ),
+                                           e,
+                                           null );
+                    Reporter.print( message, source );
+                }
+            }
+            else
+            {
+                message =
+                    new Message( Reporter.ERROR,
+                                 getString( "badURL", urlToken ) + ": " + cause,
+                                 null );
+
+                Reporter.print( message, source );
+            }
+        }
+        else
+        {
+            handleUnexpectedSubtaskReturn( lobj, source );
+        }
+        return url;
+    }
+
+    /**
+     * Check the ability to resolve the host component of <code>url</code>
+     * to an <code>InetAddress</code>. If successful, this method is silent.
+     *
+     * @param url    the <code>URL</code> to check
+     * @param source the source of the <code>URL</code>
+     */
+    private void checkForKnownHost( final URL url, String source )
+    {
+        try
+        {
+            InetAddress.getByName( url.getHost() ).getCanonicalHostName();
+        }
+        catch( UnknownHostException e )
+        {
+            Message message = new Message( Reporter.ERROR,
+                                           getString( "noHost",
+                                                      url.getHost(),
+                                                      url ),
+                                           null );
+            Reporter.print( message, source );
+        }
+    }
+
+    /**
+     * Check whether the host component of <code>url</code> resolves
+     * to a loopback address.
+     *
+     * @param url    the <code>URL</code> to check
+     * @param source the source of the <code>URL</code>
+     */
+    private void checkForLocalHost( final URL url, String source )
+    {
+        try
+        {
+            if( InetAddress.getByName( url.getHost() ).isLoopbackAddress() )
+            {
+                Message message = new Message( Reporter.WARNING,
+                                               getString( "usedLocalhost", url ),
+                                               getString( "localhostExp" ) );
+                Reporter.print( message, source );
+            }
+        }
+        catch( Exception ignore )
+        { // accessibility check handles this failure
+        }
+    }
+
+    /**
+     * Check the accessibility of the codebase <code>URL</code> by opening a
+     * connection to it. This check fails if the <code>openConnection</code>
+     * call or subsequent <code>getInputStream </code> call throws an
+     * <code>IOException</code>, or if these calls do not complete within 5
+     * seconds. These two failure modes result in different error messages
+     * being output.
+     *
+     * @param url    the <code>URL</code> to check
+     * @param source the source of the <code>URL</code>
+     */
+    private void checkAccessibility( final URL url, String source )
+    {
+        Message message;
+        URLAccessor accessor = new URLAccessor( url );
+        Thread t = new Thread( accessor );
+        t.setDaemon( true );
+        t.start();
+        try
+        {
+            t.join( 5000, 0 );
+        }
+        catch( Exception e )
+        {
+            e.printStackTrace();
+        }
+        if( t.isAlive() )
+        {
+            message = new Message( Reporter.ERROR,
+                                   getString( "noresponse", url ),
+                                   null );
+        }
+        else if( accessor.getException() == null )
+        {
+            message = new Message( Reporter.INFO,
+                                   getString( "available", url ),
+                                   null );
+        }
+        else
+        {
+            message = new Message( Reporter.ERROR,
+                                   getString( "unavailable", url ),
+                                   accessor.getException(),
+                                   null );
+        }
+        Reporter.print( message, source );
+    }
+
+    /**
+     * Check for a fully qualified host name. To be valid, the host
+     * name must consist of at least two '.' separated tokens, and the
+     * last token must be one of the well-known top level domain names,
+     * or the last token must be a two character string which is assumed
+     * to be a country code.
+     *
+     * @param url    the <code>URL</code> to check
+     * @param source the source of the <code>URL</code>
+     */
+    private void checkForFQDomain( final URL url, String source )
+    {
+
+        String[] topLevelDomains = { "aero", "biz", "com", "coop", "edu",
+                                     "gov", "info", "int", "mil", "museum",
+                                     "name", "net", "org", "pro" };
+        String hostName = url.getHost();
+        int lastDot = hostName.lastIndexOf( '.' );
+        if( lastDot >= 0 && lastDot < hostName.length() - 1 )
+        {
+            String tld = hostName.substring( lastDot + 1 ); // top level domain
+            if( tld.length() == 2 )
+            {
+                return;
+            }
+            for( int i = 0; i < topLevelDomains.length; i++ )
+            {
+                if( tld.equals( topLevelDomains[ i ] ) )
+                {
+                    return;
+                }
+            }
+        }
+        Message message = new Message( Reporter.WARNING,
+                                       getString( "unqualified", url.getHost() ),
+                                       getString( "unqualifiedExp" ) );
+        Reporter.print( message, source );
+    }
+
+    /**
+     * Check for use of an MD5 httpmd URL. If the protocol of <code>url</code>
+     * is httpmd, then the hash function identifier is parsed from the
+     * file component of <code>url</code> and a string comparison is done.
+     *
+     * @param url    the <code>URL</code> to check
+     * @param source the source of the <code>URL</code>
+     */
+    private void checkForMD5( final URL url, String source )
+    {
+        if( !url.getProtocol().equalsIgnoreCase( "httpmd" ) )
+        {
+            return;
+        }
+        // can assume hashcode is present, or url construction would have failed
+        String target = url.getFile();
+        int lastSemi = target.lastIndexOf( ';' );
+        String hash = target.substring( lastSemi + 1 );
+        if( hash.startsWith( "md5" ) )
+        {
+            Message message = new Message( Reporter.WARNING,
+                                           getString( "usesmd5", url ),
+                                           getString( "usesmd5Exp" ) );
+            Reporter.print( message, source );
+        }
+    }
+
+    /**
+     * A <code>Runnable</code> which attempts to open a <code>URL</code>
+     * connection. If the attempt results in an exception being throw,
+     * the exception is stored for later access by the invoker of the thread.
+     */
+    private class URLAccessor implements Runnable
+    {
+
+        URL url;
+        Throwable exception = null;
+
+        URLAccessor( URL url )
+        {
+            this.url = url;
+        }
+
+        public void run()
+        {
+            try
+            {
+                URLConnection con = url.openConnection();
+                InputStream stream = con.getInputStream();
+            }
+            catch( IOException e )
+            {
+                exception = e;
+            }
+        }
+
+        Throwable getException()
+        {
+            return exception;
+        }
+    }
+
+    public static class GetURLTask implements SubVMTask
+    {
+
+        public Object run( String[] args )
+        {
+            String urlToken = args[ 0 ];
+            URL url;
+            try
+            {
+                url = new URL( urlToken );
+            }
+            catch( MalformedURLException e )
+            {
+                int firstColon = urlToken.indexOf( ':' );
+                if( firstColon > 0 )
+                {
+                    String protocol = urlToken.substring( 0, firstColon );
+                    if( protocol.equalsIgnoreCase( "httpmd" ) )
+                    {
+                        if( !httpmdHandlerInstalled() )
+                        {
+                            return "nohandler";
+                        }
+                    }
+                }
+                return e.getMessage();
+            }
+            return url;
+        }
+
+        private boolean httpmdHandlerInstalled()
+        {
+            try
+            {
+                new URL( "httpmd://localhost/foo;sha=0" );
+            }
+            catch( MalformedURLException e )
+            {
+                return false;
+            }
+            return true;
+        }
+    }
+}
+	
+

Added: incubator/river/jtsk/skunk/niclas1/tools/src/main/java/com/sun/jini/tool/envcheck/plugins/CheckConfig.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/niclas1/tools/src/main/java/com/sun/jini/tool/envcheck/plugins/CheckConfig.java?rev=724973&view=auto
==============================================================================
--- incubator/river/jtsk/skunk/niclas1/tools/src/main/java/com/sun/jini/tool/envcheck/plugins/CheckConfig.java (added)
+++ incubator/river/jtsk/skunk/niclas1/tools/src/main/java/com/sun/jini/tool/envcheck/plugins/CheckConfig.java Tue Dec  9 21:09:41 2008
@@ -0,0 +1,351 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.sun.jini.tool.envcheck.plugins;
+
+import com.sun.jini.start.NonActivatableServiceDescriptor;
+import com.sun.jini.start.ServiceDescriptor;
+import com.sun.jini.tool.envcheck.AbstractPlugin;
+import com.sun.jini.tool.envcheck.EnvCheck;
+import com.sun.jini.tool.envcheck.Reporter;
+import com.sun.jini.tool.envcheck.Reporter.Message;
+import com.sun.jini.tool.envcheck.SubVMTask;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.Set;
+import net.jini.config.Configuration;
+import net.jini.config.ConfigurationException;
+import net.jini.config.ConfigurationFile;
+import net.jini.config.ConfigurationProvider;
+
+/**
+ * Check the configuration files for services identified by service descriptors
+ * in the service starter configuration. For each
+ * <code>SharedActivatableServiceDescriptor</code> or
+ * <code>NonActivatableServiceDescriptor</code>, a check is made that the
+ * command line arguments are not <code>null</code> or empty and that a
+ * configuration can be instantiated from those arguments. The configuration is
+ * searched for all occurrences of <code>initialLookupGroups</code> entries and
+ * generates warnings for those set to <code>ALL_GROUPS</code>.
+ */
+public class CheckConfig extends AbstractPlugin
+{
+
+    /**
+     * reference to the plugin container
+     */
+    private EnvCheck envCheck;
+
+    /**
+     * If configured to perform JSK checks, perform checks for each descriptor.
+     * Any service which conforms to the same command line argument convention
+     * may be included in a JSK check.
+     *
+     * @param envCheck the plugin container
+     */
+    public void run( EnvCheck envCheck )
+    {
+        this.envCheck = envCheck;
+        ServiceDescriptor[] d = envCheck.getDescriptors();
+        for( int i = 0; i < d.length; i++ )
+        {
+            if( d[ i ] instanceof NonActivatableServiceDescriptor )
+            {
+                NonActivatableServiceDescriptor serviceDesc =
+                    (NonActivatableServiceDescriptor) d[ i ];
+                String source = getString( "descfor" )
+                                + " "
+                                + serviceDesc.getImplClassName();
+                if( checkArgs( serviceDesc, source ) )
+                {
+                    checkServiceConfig( serviceDesc, source );
+                }
+            }
+        }
+    }
+
+    /**
+     * Check that the arguments array obtained by calling
+     * <code>getServerConfigArgs</code> on the given service descriptor is
+     * non-<code>null</code> and has length > 0. This method is silent if the
+     * check is successful.
+     *
+     * @param d the <code>NonActivatableServiceDescriptor</code> to check
+     * @return true if the arguments are 'well formed'
+     */
+    private boolean checkArgs( NonActivatableServiceDescriptor d,
+                               String source )
+    {
+        String[] args = d.getServerConfigArgs();
+        if( args == null || args.length == 0 )
+        {
+            Message message = new Message( Reporter.ERROR,
+                                           getString( "emptydesclist" ),
+                                           getString( "emptydesclistExp" ) );
+            Reporter.print( message, source );
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Check the service configuration file by instantiating the configuration
+     * in a subtask created using the same properties and arguments that would
+     * be used to run the actual service. If instantiation is successful, the
+     * configuration file and overrides are presumed to be well-formed. If the
+     * load is successful, another subtask is run in the same way which checks
+     * for an <code>initialLookupGroups</code> entry of <code>ALL_GROUPS.</code>
+     * A warning is output if such an entry is found.
+     *
+     * @param d the <code>NonActivatableServiceDescriptor</code> to check
+     */
+    private void checkServiceConfig( NonActivatableServiceDescriptor d,
+                                     String source )
+    {
+        if( checkConfigLoad( d, source ) )
+        {
+            checkForAllGroups( d, source );
+        }
+    }
+
+    /**
+     * Execute the subtask which loads the configuration file.
+     *
+     * @param d      the service descriptor
+     * @param source the source of the arguments
+     * @return true if the load was successful
+     */
+    private boolean checkConfigLoad( NonActivatableServiceDescriptor d,
+                                     String source )
+    {
+        Message message;
+        String task = taskName( "ConfigTask" );
+        boolean ret = false;
+        Object o = envCheck.launch( d, envCheck.getGroupDescriptor(), task );
+        if( o instanceof Boolean )
+        {
+            if( ( (Boolean) o ).booleanValue() )
+            {
+                message = new Message( Reporter.INFO,
+                                       getString( "ssconfigOK" ),
+                                       getString( "ssconfigExp" ) );
+                ret = true;
+            }
+            else
+            {
+                message = new Message( Reporter.ERROR,
+                                       getString( "loadfailed" ),
+                                       getString( "ssconfigExp" ) );
+            }
+            Reporter.print( message, source );
+        }
+        else if( o instanceof ConfigurationException )
+        {
+            message = new Message( Reporter.ERROR,
+                                   getString( "loadfailed" ),
+                                   (Throwable) o,
+                                   getString( "ssconfigExp" ) );
+            Reporter.print( message, source );
+        }
+        else
+        {
+            handleUnexpectedSubtaskReturn( o, source );
+        }
+        return ret;
+    }
+
+    /**
+     * Execute the subtask which checks for ALL_GROUPS.
+     *
+     * @param d      the service descriptor
+     * @param source the source of the arguments
+     */
+    private void checkForAllGroups( NonActivatableServiceDescriptor d,
+                                    String source )
+    {
+        String task = taskName( "GetGroupsTask" );
+        Object o = envCheck.launch( d, envCheck.getGroupDescriptor(), task );
+        if( o instanceof GroupInfo[] )
+        {
+            Message message;
+            GroupInfo[] info = (GroupInfo[]) o;
+            if( info.length == 0 )
+            {
+                message = new Message( Reporter.INFO,
+                                       getString( "notallgroup" ),
+                                       getString( "allgroupExp" ) );
+                Reporter.print( message, source );
+            }
+            else
+            {
+                for( int i = 0; i < info.length; i++ )
+                {
+                    GroupInfo gi = info[ i ];
+                    if( gi.groups == null )
+                    {
+                        message = new Message( Reporter.WARNING,
+                                               getString( "allgroup" ),
+                                               getString( "allgroupExp" ) );
+                    }
+                    else
+                    {
+                        StringBuffer groupList = new StringBuffer();
+                        for( int j = 0; j < gi.groups.length; j++ )
+                        {
+                            String group = gi.groups[ j ];
+                            if( group.equals( "" ) )
+                            {
+                                group = "public";
+                            }
+                            if( j > 0 )
+                            {
+                                groupList.append( "," );
+                            }
+                            groupList.append( group );
+                        }
+                        message = new Message( Reporter.INFO,
+                                               getString( "groups",
+                                                          groupList.toString() ),
+                                               getString( "allgroupExp" ) );
+                    }
+                    Reporter.print( message, source + ": " + gi.entryName );
+                }
+            }
+        }
+        else
+        {
+            handleUnexpectedSubtaskReturn( o, source );
+        }
+    }
+
+    /**
+     * Struct to hold entryName/Group pairs
+     */
+    private static class GroupInfo implements Serializable
+    {
+
+        String entryName;
+        String[] groups;
+
+        GroupInfo( String entryName, String[] groups )
+        {
+            this.entryName = entryName;
+            this.groups = groups;
+        }
+    }
+
+    /**
+     * Subtask which obtains all <code>initialLookupGroups</code> entries and
+     * returns them in an array of <code>GroupInfo</code> objects.
+     */
+    public static class GetGroupsTask implements SubVMTask
+    {
+
+        /**
+         * Instantiate the configuration. <code>args</code> is stripped of its
+         * first value, which is the name of this task. The remaining args are
+         * used to instantiate the configuration. This operation should never
+         * fail since the configuration will have been instantiated previous in
+         * an identical way. Once instantiated, search for an ALL_GROUPS
+         * definition.
+         *
+         * @param args the args used to start this VM
+         * @return a <code>Boolean(false)</code> if no entries named
+         *         <code>initialLookupGroups,</code> or the value of
+         *         <code>initialLookupGroups</code> (a <code>String[]</code>) if
+         *         the entry is found.
+         */
+        public Object run( String[] args )
+        {
+            try
+            {
+                Configuration config =
+                    ConfigurationProvider.getInstance( args );
+                return getGroups( config );
+            }
+            catch( Exception e )
+            {
+                return e;
+            }
+        }
+
+        /**
+         * Search for all entries named <code>initialLookupGroups</code>
+         * in the configuration and return the array of <code>GroupInfo</code>
+         * objects containing the full entry name and associated groups
+         *
+         * @param conf the configuration to examine
+         * @return the <code>GroupInfo</code> array
+         */
+        private Object getGroups( Configuration conf )
+        {
+            ConfigurationFile cf = (ConfigurationFile) conf;
+            ArrayList list = new ArrayList();
+            Set names = cf.getEntryNames();
+            Iterator it = names.iterator();
+            while( it.hasNext() )
+            {
+                String name = (String) it.next();
+                int lastDot = name.lastIndexOf( ".initialLookupGroups" );
+                if( lastDot > 0 )
+                {
+                    String component = name.substring( 0, lastDot );
+                    try
+                    {
+                        String[] groups =
+                            (String[]) ( conf.getEntry( component,
+                                                        "initialLookupGroups",
+                                                        String[].class ) );
+                        list.add( new GroupInfo( name, groups ) );
+                    }
+                    catch( ConfigurationException e )
+                    {
+                        return e;
+                    }
+                }
+            }
+            return list.toArray( new GroupInfo[list.size()] );
+        }
+    }
+
+    /**
+     * Subtask to load the configuration
+     */
+    public static class ConfigTask implements SubVMTask
+    {
+
+        /**
+         * Instantiate the configuration using the given <code>args</code>.
+         *
+         * @return a <code>Boolean(true)</code> if successful, or the
+         *         exception thrown if unsuccessful
+         */
+        public Object run( String[] args )
+        {
+            try
+            {
+                ConfigurationProvider.getInstance( args );
+                return new Boolean( true );
+            }
+            catch( Exception e )
+            {
+                return e;
+            }
+	}
+    }
+}

Added: incubator/river/jtsk/skunk/niclas1/tools/src/main/java/com/sun/jini/tool/envcheck/plugins/CheckJDK1_4.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/niclas1/tools/src/main/java/com/sun/jini/tool/envcheck/plugins/CheckJDK1_4.java?rev=724973&view=auto
==============================================================================
--- incubator/river/jtsk/skunk/niclas1/tools/src/main/java/com/sun/jini/tool/envcheck/plugins/CheckJDK1_4.java (added)
+++ incubator/river/jtsk/skunk/niclas1/tools/src/main/java/com/sun/jini/tool/envcheck/plugins/CheckJDK1_4.java Tue Dec  9 21:09:41 2008
@@ -0,0 +1,146 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.sun.jini.tool.envcheck.plugins;
+
+import com.sun.jini.start.SharedActivationGroupDescriptor;
+import com.sun.jini.tool.envcheck.AbstractPlugin;
+import com.sun.jini.tool.envcheck.EnvCheck;
+import com.sun.jini.tool.envcheck.Reporter;
+import com.sun.jini.tool.envcheck.Reporter.Message;
+import com.sun.jini.tool.envcheck.SubVMTask;
+
+/**
+ * Check that the Java platform is at least version 1.4. This check is applied
+ * to the VM invoked by the command line being analyzed and the VM invoked by
+ * a <code>SharedActivationGroupDescriptor</code> if the
+ * descriptor's <code>getServerCommand()</code> method returns non-null.
+ */
+public class CheckJDK1_4 extends AbstractPlugin
+{
+
+    /**
+     * reference to the plugin  container
+     */
+    private EnvCheck envCheck;
+
+    /**
+     * name of task to execute
+     */
+    private String taskName = taskName( "JDK1_4Task" );
+
+    /**
+     * Check the validity of the activation group VM (if there is one)
+     *
+     * @param envCheck the container
+     */
+    public void run( EnvCheck envCheck )
+    {
+        this.envCheck = envCheck;
+        checkMainVM();
+        checkGroupVM();
+    }
+
+    /**
+     * Check the activation group VM. If there is a
+     * <code>SharedActivationGroupDescriptor</code> available from the
+     * container, invoke a subtask which verifies that the VM used to run that
+     * group is at least version 1.4.
+     */
+    private void checkGroupVM()
+    {
+        SharedActivationGroupDescriptor gd = envCheck.getGroupDescriptor();
+        if( gd != null )
+        {
+            String source;
+            String serverCommand = gd.getServerCommand();
+            if( serverCommand == null )
+            {
+                source = getString( "cmdlinejava", envCheck.getJavaCmd() );
+            }
+            else
+            {
+                source = getString( "groupjava", serverCommand );
+            }
+            processReturn( envCheck.launch( null, gd, taskName ), source );
+        }
+    }
+
+    /**
+     * Check the vm invoked by the command-line java command.
+     */
+    private void checkMainVM()
+    {
+        String source = getString( "mainsource", envCheck.getJavaCmd() );
+        processReturn( envCheck.launch( taskName ), source );
+    }
+
+    /**
+     * Process the object returned by the subtask. Prints a success or
+     * failure message based on the type and contents of <code>o</code>.
+     *
+     * @param o      the object returned by the subtask
+     * @param source the source description
+     */
+    private void processReturn( Object o, String source )
+    {
+        if( o instanceof Boolean )
+        {
+            Message message;
+            if( ( (Boolean) o ).booleanValue() )
+            {
+                message = new Message( Reporter.INFO,
+                                       getString( "goodjdk" ),
+                                       getString( "jdkExp" ) );
+            }
+            else
+            {
+                message = new Message( Reporter.INFO,
+                                       getString( "badjdk" ),
+                                       getString( "jdkExp" ) );
+            }
+            Reporter.print( message, source );
+        }
+        else
+        {
+            handleUnexpectedSubtaskReturn( o, source );
+        }
+    }
+
+    /**
+     * Subtask to check the VM version. If it is possible to load
+     * <code>java.rmi.server.RMIClassLoaderSpi</code>, then this VM is presumed
+     * to be at least version 1.4. The run method return a
+     * <code>Boolean(true)</code> if the version is OK.
+     */
+    public static class JDK1_4Task implements SubVMTask
+    {
+
+        public Object run( String[] args )
+        {
+            try
+            {
+                Class.forName( "java.rmi.server.RMIClassLoaderSpi" );
+                return new Boolean( true );
+            }
+            catch( ClassNotFoundException e )
+            {
+                return new Boolean( false );
+            }
+        }
+    }
+}

Added: incubator/river/jtsk/skunk/niclas1/tools/src/main/java/com/sun/jini/tool/envcheck/plugins/CheckJSKPlatform.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/niclas1/tools/src/main/java/com/sun/jini/tool/envcheck/plugins/CheckJSKPlatform.java?rev=724973&view=auto
==============================================================================
--- incubator/river/jtsk/skunk/niclas1/tools/src/main/java/com/sun/jini/tool/envcheck/plugins/CheckJSKPlatform.java (added)
+++ incubator/river/jtsk/skunk/niclas1/tools/src/main/java/com/sun/jini/tool/envcheck/plugins/CheckJSKPlatform.java Tue Dec  9 21:09:41 2008
@@ -0,0 +1,206 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.sun.jini.tool.envcheck.plugins;
+
+import com.sun.jini.start.SharedActivationGroupDescriptor;
+import com.sun.jini.tool.envcheck.AbstractPlugin;
+import com.sun.jini.tool.envcheck.EnvCheck;
+import com.sun.jini.tool.envcheck.Reporter;
+import com.sun.jini.tool.envcheck.Reporter.Message;
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.StringTokenizer;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
+
+/**
+ * Check whether <code>jsk-platform.jar</code> is in the classpath
+ * of the command-line being analyzed, and if the activation group
+ * if there is one.
+ */
+public class CheckJSKPlatform extends AbstractPlugin
+{
+
+    /**
+     * the plugin container
+     */
+    private EnvCheck envCheck;
+
+    /**
+     * classpath components already seen, to avoid circular reference loops
+     */
+    private HashSet seen = new HashSet();
+
+    /**
+     * Check the command line vm and the group, if there is one,
+     * for a classpath containing <code>jsk-platform.jar</code>.
+     *
+     * @param envCheck the plugin container
+     */
+    public void run( EnvCheck envCheck )
+    {
+        this.envCheck = envCheck;
+        String classpath = envCheck.getJarToRun();
+        if( classpath != null )
+        {
+            checkPlatform( classpath, getString( "jarfile" ) );
+        }
+        else
+        {
+            classpath = envCheck.getClasspath();
+            checkPlatform( classpath, getString( "cmdline" ) );
+        }
+        SharedActivationGroupDescriptor gd = envCheck.getGroupDescriptor();
+        if( gd != null )
+        {
+            classpath = gd.getClasspath();
+            checkPlatform( classpath, getString( "grouppath" ) );
+        }
+    }
+
+    /**
+     * Check <code>classpath</code> for the existence of
+     * <code>jsk-platform.jar</code>.
+     *
+     * @param classpath the classpath to check
+     * @param source    the source description
+     */
+    private void checkPlatform( String classpath, String source )
+    {
+        Message message;
+        String[] paths = parseClasspath( classpath, source );
+        for( int i = 0; i < paths.length; i++ )
+        {
+            if( paths[ i ].endsWith( "jsk-platform.jar" ) )
+            {
+                message = new Message( Reporter.INFO,
+                                       getString( "hasplatform" ),
+                                       getString( "platformExp" ) );
+                Reporter.print( message, source );
+                return;
+            }
+        }
+        message = new Message( Reporter.WARNING,
+                               getString( "noplatform" ),
+                               getString( "platformExp" ) );
+        Reporter.print( message, source );
+    }
+
+    /**
+     * Separate each of the components making up the classpath into
+     * separate tokens. For tokens which resolve to jar files, recursively
+     * include their Class-Path manifest entries if defined. Verify
+     * each component for existence and accessibility.
+     */
+    private String[] parseClasspath( String path, String source )
+    {
+        if( path == null || path.trim().length() == 0 )
+        {
+            return new String[0];
+        }
+        ArrayList list = new ArrayList();
+        StringTokenizer tok = new StringTokenizer( path, File.pathSeparator );
+        while( tok.hasMoreTokens() )
+        {
+            String item = tok.nextToken();
+            list.addAll( checkItem( item, source ) );
+        }
+        return (String[]) list.toArray( new String[list.size()] );
+    }
+
+    /**
+     * Checks a component on the classpath for existence and accessibility.
+     * If the item meets these criteria, it is placed in a list which
+     * is returned to the caller. If the item is a JAR file whose manifest
+     * which contains a <code>Class-Path</code> manifest entry, then each
+     * of those items are checked and conditionally added to the list
+     * as well (recursively). If an <code>item</code> has been seen
+     * previously, and empty list is returned immediately.
+     *
+     * @param item   the classpath component to verify
+     * @param source the source descriptive text
+     * @return the list containing this item and all items referred to by
+     *         this item.
+     */
+    private ArrayList checkItem( String item, String source )
+    {
+        Message message;
+        ArrayList list = new ArrayList();
+        if( seen.contains( item ) )
+        {
+            return list;
+        }
+        seen.add( item );
+        File itemFile = new File( item );
+        if( !itemFile.exists() )
+        {
+            message = new Message( Reporter.WARNING,
+                                   getString( "nosuchitem", item ),
+                                   null );
+            Reporter.print( message, source );
+            return list;
+        }
+        if( !itemFile.canRead() )
+        {
+            message = new Message( Reporter.WARNING,
+                                   getString( "unreadableitem", item ),
+                                   null );
+            Reporter.print( message, source );
+            return list;
+        }
+        list.add( item );
+        JarFile jar;
+        try
+        {
+            jar = new JarFile( item );
+        }
+        catch( IOException e )
+        {  // probably not a zip/jar file
+            return list;
+        }
+        Manifest manifest;
+        try
+        {
+            manifest = jar.getManifest();
+            if( manifest == null )
+            {
+                return list;
+            }
+        }
+        catch( IOException e )
+        {
+            e.printStackTrace();
+            return list;
+        }
+        String classPath = manifest.getMainAttributes().getValue( "Class-Path" );
+        if( classPath != null )
+        {
+            StringTokenizer tok = new StringTokenizer( classPath );
+            while( tok.hasMoreTokens() )
+            {
+                String fileName = tok.nextToken();
+                File nextJar = new File( itemFile.getParentFile(), fileName );
+                source = source + ": " + item + " Manifest Class-Path";
+                list.addAll( checkItem( nextJar.toString(), source ) );
+            }
+        }
+        return list;
+    }
+}

Added: incubator/river/jtsk/skunk/niclas1/tools/src/main/java/com/sun/jini/tool/envcheck/plugins/CheckJSKPolicy.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/niclas1/tools/src/main/java/com/sun/jini/tool/envcheck/plugins/CheckJSKPolicy.java?rev=724973&view=auto
==============================================================================
--- incubator/river/jtsk/skunk/niclas1/tools/src/main/java/com/sun/jini/tool/envcheck/plugins/CheckJSKPolicy.java (added)
+++ incubator/river/jtsk/skunk/niclas1/tools/src/main/java/com/sun/jini/tool/envcheck/plugins/CheckJSKPolicy.java Tue Dec  9 21:09:41 2008
@@ -0,0 +1,123 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.sun.jini.tool.envcheck.plugins;
+
+import com.sun.jini.start.SharedActivationGroupDescriptor;
+import com.sun.jini.tool.envcheck.AbstractPlugin;
+import com.sun.jini.tool.envcheck.EnvCheck;
+import com.sun.jini.tool.envcheck.Reporter;
+import com.sun.jini.tool.envcheck.Reporter.Message;
+import com.sun.jini.tool.envcheck.SubVMTask;
+
+/**
+ * Check whether <code>jsk-policy.jar</code> is installed in the extensions
+ * directory. For both the current VM and for the group VM (if any) load
+ * <code>net.jini.security.policy.DynamicPolicyProvider</code> and verify that
+ * it was loaded with the extension classloader by verifying that the parent
+ * loader is the bootstrap loader (<code>null</code>).  The group VM is checked
+ * only if the descriptors <code>getServerCommand()</code> method returns
+ * non-<code>null</code>
+ */
+public class CheckJSKPolicy extends AbstractPlugin
+{
+
+    private EnvCheck envCheck;
+    private String codebase;
+    private static String provider =
+        "net.jini.security.policy.DynamicPolicyProvider";
+
+    /**
+     * Perform the check both for the current VM, and for the group VM if a
+     * <code>SharedActivationGroupDescriptor</code> is available from the plugin
+     * container.
+     */
+    public void run( EnvCheck envCheck )
+    {
+        this.envCheck = envCheck;
+        checkPolicy( null );
+        SharedActivationGroupDescriptor gd = envCheck.getGroupDescriptor();
+        if( gd != null )
+        {
+            checkPolicy( gd );
+        }
+    }
+
+    /**
+     * Check the policy for the command line or group. If <code>gd</code>
+     * is <code>null</code>, the policy of the command line being analyzed
+     * is checked.
+     *
+     * @param gd the group descriptor, or <code>null</code>
+     */
+    private void checkPolicy( SharedActivationGroupDescriptor gd )
+    {
+        String source =
+            gd == null ? getString( "vmsource" )
+                       : getString( "groupsource", gd.getServerCommand() );
+        Object o = envCheck.launch( null, gd, taskName( "JSKPolicyTask" ) );
+        if( o instanceof Boolean )
+        {
+            Message message;
+            if( ( (Boolean) o ).booleanValue() )
+            {
+                message = new Message( Reporter.INFO,
+                                       getString( "policyOK" ),
+                                       getString( "policyExp" ) );
+            }
+            else
+            {
+                message = new Message( Reporter.ERROR,
+                                       getString( "policyBad" ),
+                                       getString( "missingPolicyExp" ) );
+            }
+            Reporter.print( message, source );
+        }
+        else
+        {
+            handleUnexpectedSubtaskReturn( o, source );
+        }
+    }
+
+    /**
+     * The task which checks the group VM.
+     */
+    public static class JSKPolicyTask implements SubVMTask
+    {
+
+        public Object run( String[] args )
+        {
+            try
+            {
+                Class c = Class.forName( provider );
+                if( c.getClassLoader().getParent() == null )
+                {
+                    return new Boolean( true );
+                }
+                else
+                {
+                    return new Boolean( false );
+                }
+            }
+            catch( ClassNotFoundException e )
+            {
+                return new Boolean( false );
+            }
+        }
+    }
+}
+