donaldp 01/04/12 05:24:06 Modified: src/java/org/apache/phoenix/engine DefaultSarDeployer.java DefaultServerApplication.java PhoenixKernel.java src/java/org/apache/phoenix/engine/blocks BlockDAG.java src/java/org/apache/phoenix/engine/facilities DefaultComponentManagerBuilder.java Added: src/java/org/apache/phoenix/engine ApplicationFactory.java src/java/org/apache/phoenix/engine/facilities/classmanager PolicyClassLoader.java SarClassLoader.java src/java/org/apache/phoenix/engine/facilities/security AbstractPolicy.java DefaultPolicy.java Removed: src/java/org/apache/phoenix/engine ServerApplication.java src/java/org/apache/phoenix/engine/facilities DefaultPolicy.java SarClassLoader.java Log: Removed ServerApplication interface and directly use Application interface. Migrate across the Avalon ClassLoader/Security components and place them with facilities that use them in sub-directory ie AbstractPolicy+DefaultPolicy->phoenix.engine.facilities.security ie PolicyClassLoader+SarClassLoader->phoenix.engine.facilities.classManager Revision Changes Path 1.6 +6 -5 jakarta-avalon-phoenix/src/java/org/apache/phoenix/engine/DefaultSarDeployer.java Index: DefaultSarDeployer.java =================================================================== RCS file: /home/cvs/jakarta-avalon-phoenix/src/java/org/apache/phoenix/engine/DefaultSarDeployer.java,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- DefaultSarDeployer.java 2001/04/12 05:32:54 1.5 +++ DefaultSarDeployer.java 2001/04/12 12:23:58 1.6 @@ -24,6 +24,7 @@ import org.apache.avalon.Composer; import org.apache.avalon.DefaultComponentManager; import org.apache.avalon.DefaultContext; +import org.apache.avalon.atlantis.Application; import org.apache.avalon.atlantis.Kernel; import org.apache.avalon.camelot.AbstractCamelotDeployer; import org.apache.avalon.camelot.CamelotUtil; @@ -207,10 +208,10 @@ addEntry( name, entry ); final Kernel kernel = getKernel(); - ServerApplication serverApplication = null; + Application application = null; try { - serverApplication = (ServerApplication)kernel.getApplication( name ); + application = kernel.getApplication( name ); } catch( final ContainerException ce ) { @@ -229,7 +230,7 @@ { final Configuration configuration = getConfigurationFor( file ); final Configuration[] blocks = configuration.getChildren( "block" ); - handleBlocks( serverApplication, entry, blocks ); + handleBlocks( application, entry, blocks ); } catch( final ComponentManagerException cme ) { @@ -273,7 +274,7 @@ return deployer; } - protected void handleBlocks( final ServerApplication serverApplication, + protected void handleBlocks( final Application application, final ServerApplicationEntry saEntry, final Configuration[] blocks ) throws ComponentManagerException, ConfigurationException, DeploymentException @@ -326,7 +327,7 @@ entry.setBlockInfo( info ); entry.setConfiguration( block.getChild( "configuration" ) ); - try { serverApplication.add( name, entry ); } + try { application.add( name, entry ); } catch( final ContainerException ce ) { throw new DeploymentException( "Error adding component to container", ce ); 1.9 +30 -29 jakarta-avalon-phoenix/src/java/org/apache/phoenix/engine/DefaultServerApplication.java Index: DefaultServerApplication.java =================================================================== RCS file: /home/cvs/jakarta-avalon-phoenix/src/java/org/apache/phoenix/engine/DefaultServerApplication.java,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- DefaultServerApplication.java 2001/04/03 03:50:35 1.8 +++ DefaultServerApplication.java 2001/04/12 12:23:59 1.9 @@ -19,12 +19,13 @@ import org.apache.avalon.DefaultComponentManager; import org.apache.avalon.DefaultContext; import org.apache.avalon.Initializable; +import org.apache.avalon.atlantis.Application; import org.apache.avalon.atlantis.ApplicationException; import org.apache.avalon.camelot.AbstractContainer; -import org.apache.avalon.camelot.pipeline.AvalonState; import org.apache.avalon.camelot.ContainerException; import org.apache.avalon.camelot.Entry; import org.apache.avalon.camelot.Factory; +import org.apache.avalon.camelot.pipeline.AvalonState; import org.apache.avalon.camelot.pipeline.ComponentBuilder; import org.apache.avalon.camelot.pipeline.ComponentManagerBuilder; import org.apache.avalon.camelot.pipeline.ConfigurationRepository; @@ -45,16 +46,16 @@ import org.apache.phoenix.engine.facilities.DefaultContextBuilder; import org.apache.phoenix.engine.facilities.DefaultLogManager; import org.apache.phoenix.engine.facilities.DefaultLoggerBuilder; -import org.apache.phoenix.engine.facilities.DefaultPolicy; +import org.apache.phoenix.engine.facilities.security.DefaultPolicy; import org.apache.phoenix.engine.facilities.DefaultThreadManager; -import org.apache.phoenix.engine.facilities.SarClassLoader; +import org.apache.phoenix.engine.facilities.classmanager.SarClassLoader; import org.apache.phoenix.engine.phases.DefaultPhase; import org.apache.phoenix.engine.phases.Phase; import org.apache.phoenix.engine.phases.Traversal; import org.apache.phoenix.metainfo.DependencyDescriptor; /** - * This is the basic container of blocks. A server application + * This is the basic container of blocks. A server application * represents an aggregation of blocks that act together to form * an application. * @@ -63,7 +64,7 @@ */ public class DefaultServerApplication extends AbstractContainer - implements ServerApplication + implements Application, Configurable, Contextualizable { protected HashMap m_phases = new HashMap(); protected BlockDAG m_dag = new BlockDAG(); @@ -103,11 +104,11 @@ throws ConfigurationException { m_configuration = configuration; - } + } - public void init() - throws Exception - { + public void init() + throws Exception + { createComponents(); //setup the component manager @@ -124,13 +125,13 @@ { Phase phase = null; - phase = new DefaultPhase( Phase.FORWARD, + phase = new DefaultPhase( Phase.FORWARD, new StartupPipeline(), AvalonState.BASE, AvalonState.RUNNING ); m_phases.put( "startup", phase ); - phase = new DefaultPhase( Phase.REVERSE, + phase = new DefaultPhase( Phase.REVERSE, new ShutdownPipeline(), AvalonState.RUNNING, AvalonState.DISPOSED ); @@ -151,8 +152,8 @@ public void start() throws Exception { - // load blocks - try + // load blocks + try { getLogger().info( "Number of blocks to load: " + m_entries.size() ); final Phase phase = (Phase)m_phases.get( "startup" ); @@ -168,9 +169,9 @@ public void stop() throws Exception { - } + } - public void dispose() + public void dispose() throws Exception { getLogger().info( "Number of blocks to unload: " + m_entries.size() ); @@ -240,8 +241,8 @@ setupComponent( object, null, null ); } - protected void setupComponent( final Component object, - final String logName, + protected void setupComponent( final Component object, + final String logName, final Configuration configuration ) throws Exception { @@ -275,7 +276,7 @@ if( Phase.FORWARD == phase.getTraversal() ) { final Iterator entries = list(); - while( entries.hasNext() ) + while( entries.hasNext() ) { final String name = (String)entries.next(); m_dag.walkGraph( name, phase ); @@ -283,9 +284,9 @@ } else if( Phase.REVERSE == phase.getTraversal() ) { - //TODO: + //TODO: final Iterator entries = list(); - while( entries.hasNext() ) + while( entries.hasNext() ) { final String name = (String)entries.next(); //m_dag.reverseWalkGraph( name, phase ); @@ -295,7 +296,7 @@ { //TODO: Does this make sense ???? final Iterator entries = list(); - while( entries.hasNext() ) + while( entries.hasNext() ) { final String name = (String)entries.next(); final BlockEntry entry = (BlockEntry)getEntry( name ); @@ -320,9 +321,9 @@ } /** - * Retrieve a list of RoleEntry objects that were specified - * in configuration file and verify they were expected based - * on BlockInfo file. Also verify that all entries specified + * Retrieve a list of RoleEntry objects that were specified + * in configuration file and verify they were expected based + * on BlockInfo file. Also verify that all entries specified * in BlockInfo file have been provided. * * @param entry the BlockEntry describing block @@ -337,10 +338,10 @@ { final String role = roleEntrys[ i ].getRole(); final DependencyDescriptor descriptor = entry.getBlockInfo().getDependency( role ); - + if( null == descriptor ) { - final String message = "Unknown dependency " + roleEntrys[ i ].getName() + + final String message = "Unknown dependency " + roleEntrys[ i ].getName() + " with role " + role + " declared for Block " + name; getLogger().warn( message ); @@ -352,9 +353,9 @@ final DependencyDescriptor[] dependencies = entry.getBlockInfo().getDependencies(); for( int i = 0; i < dependencies.length; i++ ) { - final RoleEntry roleEntry = + final RoleEntry roleEntry = entry.getRoleEntry( dependencies[ i ].getRole() ); - + if( null == roleEntry ) { final String message = "Dependency " + dependencies[ i ].getRole() + @@ -385,7 +386,7 @@ m_componentBuilder ); componentManager.put( "org.apache.avalon.camelot.pipeline.ComponentManagerBuilder", m_componentManagerBuilder ); - componentManager.put( "org.apache.avalon.camelot.pipeline.ConfigurationRepository", + componentManager.put( "org.apache.avalon.camelot.pipeline.ConfigurationRepository", m_configurationRepository ); return componentManager; 1.2 +28 -20 jakarta-avalon-phoenix/src/java/org/apache/phoenix/engine/PhoenixKernel.java Index: PhoenixKernel.java =================================================================== RCS file: /home/cvs/jakarta-avalon-phoenix/src/java/org/apache/phoenix/engine/PhoenixKernel.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- PhoenixKernel.java 2001/04/12 05:32:54 1.1 +++ PhoenixKernel.java 2001/04/12 12:23:59 1.2 @@ -8,25 +8,27 @@ package org.apache.phoenix.engine; import org.apache.avalon.Composer; -import org.apache.avalon.atlantis.Kernel; +import org.apache.avalon.Contextualizable; import org.apache.avalon.atlantis.AbstractKernel; import org.apache.avalon.atlantis.Application; +import org.apache.avalon.atlantis.Kernel; import org.apache.avalon.camelot.Entry; +import org.apache.avalon.configuration.Configurable; import org.apache.log.LogKit; /** * The ServerKernel is the core of the Phoenix system. - * The kernel is responsible for orchestrating low level services - * such as loading, configuring and destroying blocks. It also + * The kernel is responsible for orchestrating low level services + * such as loading, configuring and destroying blocks. It also * gives access to basic facilities such as scheduling sub-systems, * protected execution contexts, naming and directory services etc. * - * Note that no facilities are available until after the Kernel has been + * Note that no facilities are available until after the Kernel has been * configured and initialized. * * @author <a href="mailto:[EMAIL PROTECTED]">Peter Donald</a> */ -public class PhoenixKernel +public class PhoenixKernel extends AbstractKernel implements Kernel { @@ -35,11 +37,11 @@ public PhoenixKernel() { m_entryClass = ServerApplicationEntry.class; - m_applicationClass = ServerApplication.class; + m_applicationClass = Application.class; } - public void init() - throws Exception + public void init() + throws Exception { System.out.println(); System.out.println( BANNER ); @@ -57,31 +59,37 @@ /** * Prepare an application before it is initialized. - * Overide to provide functionality. + * Overide to provide functionality. * Usually used to setLogger(), contextualize, compose, configure. * * @param name the name of application - * @param entry the application entry + * @param entry the application entry * @param application the application instance * @exception Exception if an error occurs */ - protected void prepareApplication( final String name, - final Entry entry, + protected void prepareApplication( final String name, + final Entry entry, final Application application ) throws Exception { final ServerApplicationEntry saEntry = (ServerApplicationEntry)entry; - final ServerApplication saApplication = (ServerApplication)application; + + setupLogger( application, LogKit.getLoggerFor( name ) ); - setupLogger( saApplication, LogKit.getLoggerFor( name ) ); - saApplication.contextualize( saEntry.getContext() ); - - if( saApplication instanceof Composer ) - { - ((Composer)saApplication).compose( saEntry.getComponentManager() ); + if( application instanceof Contextualizable ) + { + ((Contextualizable)application).contextualize( saEntry.getContext() ); } - saApplication.configure( saEntry.getConfiguration() ); + if( application instanceof Composer ) + { + ((Composer)application).compose( saEntry.getComponentManager() ); + } + + if( application instanceof Configurable ) + { + ((Configurable)application).configure( saEntry.getConfiguration() ); + } } protected void postAdd( final String name, final Entry entry ) 1.1 jakarta-avalon-phoenix/src/java/org/apache/phoenix/engine/ApplicationFactory.java Index: ApplicationFactory.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.phoenix.engine; import org.apache.avalon.atlantis.Application; /** * This interface is used to create an Application. * The application created is usually specific to a particular kernel. * * Note this should eventually be moved to Atlantis. * * @author <a href="mailto:[EMAIL PROTECTED]">Leo Simons</a> * @author <a href="mailto:[EMAIL PROTECTED]">Peter Donald</a> */ public interface ApplicationFactory { /** * Create new Application. * * @return the new Application */ Application createApplication(); } 1.6 +15 -15 jakarta-avalon-phoenix/src/java/org/apache/phoenix/engine/blocks/BlockDAG.java Index: BlockDAG.java =================================================================== RCS file: /home/cvs/jakarta-avalon-phoenix/src/java/org/apache/phoenix/engine/blocks/BlockDAG.java,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- BlockDAG.java 2001/04/03 03:50:35 1.5 +++ BlockDAG.java 2001/04/12 12:24:02 1.6 @@ -12,9 +12,9 @@ import org.apache.avalon.ComponentManager; import org.apache.avalon.ComponentManagerException; import org.apache.avalon.Composer; +import org.apache.avalon.atlantis.Application; import org.apache.avalon.camelot.ContainerException; import org.apache.phoenix.Block; -import org.apache.phoenix.engine.ServerApplication; import org.apache.phoenix.metainfo.DependencyDescriptor; import org.apache.phoenix.metainfo.ServiceDescriptor; @@ -27,12 +27,12 @@ extends AbstractLoggable implements Composer { - protected ServerApplication m_serverApplication; + protected Application m_application; public void compose( final ComponentManager componentManager ) throws ComponentManagerException { - m_serverApplication = (ServerApplication)componentManager. + m_application = (Application)componentManager. lookup( "org.apache.phoenix.engine.ServerApplication" ); } @@ -51,7 +51,7 @@ protected BlockEntry getBlockEntry( final String name ) throws Exception { - return (BlockEntry)m_serverApplication.getEntry( name ); + return (BlockEntry)m_application.getEntry( name ); //catch( final ContainerException ce ) } @@ -61,8 +61,8 @@ * @param name name of BlockEntry * @param entry the BlockEntry */ - protected void visitDependencies( final String name, - final BlockEntry entry, + protected void visitDependencies( final String name, + final BlockEntry entry, final BlockVisitor visitor ) throws Exception { @@ -74,10 +74,10 @@ final ServiceDescriptor serviceDescriptor = descriptors[ i ].getService(); final String role = descriptors[ i ].getRole(); - getLogger().debug( "Traversing dependency of " + name + " with role " + role + + getLogger().debug( "Traversing dependency of " + name + " with role " + role + " to provide service " + serviceDescriptor.getName() ); - //roleEntry should NEVER be null as it is checked when + //roleEntry should NEVER be null as it is checked when //entry is added to container final RoleEntry roleEntry = entry.getRoleEntry( role ); final String dependencyName = roleEntry.getName(); @@ -97,18 +97,18 @@ throws Exception { getLogger().debug( "Traversing reverse dependencies for " + name ); - - final Iterator entries = m_serverApplication.list(); - while( entries.hasNext() ) + + final Iterator entries = m_application.list(); + while( entries.hasNext() ) { final String blockName = (String)entries.next(); - final BlockEntry entry = getBlockEntry( blockName ); + final BlockEntry entry = getBlockEntry( blockName ); final RoleEntry[] roles = entry.getRoleEntrys(); for( int i = 0; i < roles.length; i++ ) { final String depends = roles[ i ].getName(); - + if( depends.equals( name ) ) { getLogger().debug( "Attempting to unload block " + blockName + @@ -121,13 +121,13 @@ } } - protected void visitBlock( final String name, + protected void visitBlock( final String name, final BlockEntry entry, final BlockVisitor visitor, final boolean forward ) throws Exception { - if( forward ) + if( forward ) { visitDependencies( name, entry, visitor ); } 1.5 +14 -13 jakarta-avalon-phoenix/src/java/org/apache/phoenix/engine/facilities/DefaultComponentManagerBuilder.java Index: DefaultComponentManagerBuilder.java =================================================================== RCS file: /home/cvs/jakarta-avalon-phoenix/src/java/org/apache/phoenix/engine/facilities/DefaultComponentManagerBuilder.java,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- DefaultComponentManagerBuilder.java 2001/04/03 03:50:36 1.4 +++ DefaultComponentManagerBuilder.java 2001/04/12 12:24:03 1.5 @@ -11,11 +11,12 @@ import org.apache.avalon.ComponentManagerException; import org.apache.avalon.Composer; import org.apache.avalon.DefaultComponentManager; +import org.apache.avalon.atlantis.Application; import org.apache.avalon.atlantis.Facility; import org.apache.avalon.camelot.ContainerException; import org.apache.avalon.camelot.Entry; import org.apache.avalon.camelot.pipeline.ComponentManagerBuilder; -import org.apache.phoenix.engine.ServerApplication; +import org.apache.avalon.component.ComponentException; import org.apache.phoenix.engine.blocks.BlockEntry; import org.apache.phoenix.engine.blocks.RoleEntry; import org.apache.phoenix.metainfo.BlockInfo; @@ -31,12 +32,12 @@ implements Facility, ComponentManagerBuilder, Composer { //container to get dependencies from - protected ServerApplication m_serverApplication; + protected Application m_application; public void compose( final ComponentManager componentManager ) throws ComponentManagerException { - m_serverApplication = (ServerApplication)componentManager. + m_application = (Application)componentManager. lookup( "org.apache.phoenix.engine.ServerApplication" ); } @@ -48,40 +49,40 @@ * @return the created ComponentManager */ public ComponentManager createComponentManager( String name, Entry entry ) - throws ComponentManagerException + throws ComponentException { final DefaultComponentManager componentManager = new DefaultComponentManager(); final BlockEntry blockEntry = (BlockEntry)entry; final BlockInfo info = (BlockInfo)blockEntry.getInfo(); final RoleEntry[] roleEntrys = blockEntry.getRoleEntrys(); - + for( int i = 0; i < roleEntrys.length; i++ ) { final String dependencyName = roleEntrys[ i ].getName(); - final ServiceDescriptor serviceDescriptor = + final ServiceDescriptor serviceDescriptor = info.getDependency( roleEntrys[ i ].getRole() ).getService(); try { - //dependency should NEVER be null here as it + //dependency should NEVER be null here as it //is validated at entry time - final BlockEntry dependency = - (BlockEntry)m_serverApplication.getEntry( dependencyName ); + final BlockEntry dependency = + (BlockEntry)m_application.getEntry( dependencyName ); //make sure that the block offers service it supposed to be providing final ServiceDescriptor[] services = dependency.getBlockInfo().getServices(); if( !BlockUtil.hasMatchingService( services, serviceDescriptor ) ) { - throw new ComponentManagerException( "Dependency " + dependencyName + - " does not offer service required: " + - serviceDescriptor ); + throw new ComponentException( "Dependency " + dependencyName + + " does not offer service required: " + + serviceDescriptor ); } componentManager.put( roleEntrys[ i ].getRole(), dependency.getBlock() ); } catch( final ContainerException ce ) {} } - + return componentManager; } } 1.1 jakarta-avalon-phoenix/src/java/org/apache/phoenix/engine/facilities/classmanager/PolicyClassLoader.java Index: PolicyClassLoader.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.phoenix.engine.facilities.classmanager; import java.net.URL; import java.net.URLClassLoader; import java.security.CodeSource; import java.security.PermissionCollection; import java.security.Permissions; import java.security.Policy; /** * Classloader that applies correct policy information. * * @author <a href="mailto:[EMAIL PROTECTED]">Peter Donald</a> */ public class PolicyClassLoader extends URLClassLoader { protected Policy m_policy; public PolicyClassLoader( final URL[] urls, final ClassLoader classLoader, final Policy policy ) { super( urls, classLoader ); m_policy = policy; } /** * Overide so we can have a per-application security policy with * no side-effects to other applications. * * @param codeSource the codeSource to get permissions for * @return the PermissionCollection */ protected PermissionCollection getPermissions( final CodeSource codeSource ) { if( null == m_policy ) { final Permissions permissions = new Permissions(); permissions.add( new java.security.AllPermission() ); return permissions; } else { return m_policy.getPermissions( codeSource ); } } } 1.1 jakarta-avalon-phoenix/src/java/org/apache/phoenix/engine/facilities/classmanager/SarClassLoader.java Index: SarClassLoader.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.phoenix.engine.facilities.classmanager; import java.io.File; import java.net.MalformedURLException; import java.net.URL; import java.security.Policy; import org.apache.avalon.ComponentManager; import org.apache.avalon.ComponentManagerException; import org.apache.avalon.Composer; import org.apache.avalon.Context; import org.apache.avalon.Contextualizable; import org.apache.avalon.Initializable; import org.apache.avalon.atlantis.Facility; import org.apache.avalon.util.io.ExtensionFileFilter; import org.apache.phoenix.engine.SarContextResources; /** * This component creates blocks and blockInfos. * * @author <a href="mailto:[EMAIL PROTECTED]">Peter Donald</a> */ public class SarClassLoader extends PolicyClassLoader implements Facility, Contextualizable, Composer, Initializable { protected File m_baseDirectory; public SarClassLoader() { super( new URL[ 0 ], Thread.currentThread().getContextClassLoader(), null ); } public void contextualize( final Context context ) { m_baseDirectory = (File)context.get( SarContextResources.APP_HOME_DIR ); } public void compose( final ComponentManager componentManager ) throws ComponentManagerException { m_policy = (Policy)componentManager.lookup( "java.security.Policy" ); } public void init() throws Exception { final File blockDir = (new File( m_baseDirectory, "blocks" )).getAbsoluteFile(); final File libDir = (new File( m_baseDirectory, "lib" )).getAbsoluteFile(); addURLs( blockDir, new String[] { ".bar" } ); addURLs( libDir, new String[] { ".jar", ".zip" } ); } protected void addURLs( final File directory, final String[] extentions ) throws MalformedURLException { final ExtensionFileFilter filter = new ExtensionFileFilter( extentions ); final File[] files = directory.listFiles( filter ); if( null == files ) return; addURLs( files ); } protected void addURLs( final File[] files ) throws MalformedURLException { for( int i = 0; i < files.length; i++ ) { addURL( files[ i ].toURL() ); } } public String toString() { final StringBuffer sb = new StringBuffer(); sb.append( "ClassLoader[" ); final URL[] urls = getURLs(); for( int i = 0; i < urls.length; i++ ) { sb.append( ' ' ); sb.append( urls[ i ] ); } sb.append( " ]" ); return sb.toString(); } } 1.1 jakarta-avalon-phoenix/src/java/org/apache/phoenix/engine/facilities/security/AbstractPolicy.java Index: AbstractPolicy.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.phoenix.engine.facilities.security; import java.io.File; import java.net.MalformedURLException; import java.net.URL; import java.security.AccessController; import java.security.CodeSource; import java.security.Permission; import java.security.PermissionCollection; import java.security.Permissions; import java.security.Policy; import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; import java.security.cert.Certificate; import java.util.ArrayList; import java.util.Enumeration; import java.util.PropertyPermission; import org.apache.avalon.Component; import org.apache.avalon.Loggable; import org.apache.avalon.util.io.FileUtil; import org.apache.log.Logger; /** * Abstract policy extended in avalon. * * @author <a href="mailto:[EMAIL PROTECTED]">Peter Donald</a> */ public abstract class AbstractPolicy extends Policy implements Component, Loggable { protected final static boolean DEBUG = true; protected final ArrayList m_entries = new ArrayList(); protected Logger m_logger; /** * Internal Policy Entry holder class. */ protected final static class PolicyEntry { CodeSource m_codeSource; Permissions m_permissions; } public void setLogger( final Logger logger ) { m_logger = logger; } /** * Overide so we can have a per-application security policy with * no side-effects to other applications. * * @param codeSource the codeSource to get permissions for * @return the PermissionCollection */ public PermissionCollection getPermissions( CodeSource codeSource ) { codeSource = normalize( codeSource ); getLogger().debug( "getPermissions(" + codeSource.getLocation() + ");" ); final Permissions permissions = new Permissions(); final int size = m_entries.size(); for( int i = 0; i < size; i++ ) { final PolicyEntry entry = (PolicyEntry)m_entries.get( i ); if( entry.m_codeSource.implies( codeSource ) ) { if( DEBUG ) { getLogger().debug( entry.m_codeSource.getLocation() + " implies " + codeSource.getLocation() ); } copyPermissions( permissions, entry.m_permissions ); } } if( DEBUG ) { getLogger().debug( codeSource.getLocation() + " permissions = " + permissions ); } return permissions; } /** * Refresh policy. Ignored in this implementation. */ public void refresh() { } /** * Normalizing CodeSource involves removing relative addressing * (like .. and .) for file urls. * * @param codeSource the codeSource to be normalized * @return the normalized codeSource */ protected CodeSource normalize( final CodeSource codeSource ) { final URL initialLocation = codeSource.getLocation(); // This is a bit of a hack. I don't know why CodeSource should behave like this // Fear not, this only seems to be a problem for home grown classloaders. // - Paul Hammant, Nov 2000 if( null == initialLocation ) return codeSource; String location = null; if( !initialLocation.getProtocol().equalsIgnoreCase( "file" ) ) { location = initialLocation.getFile(); location = FileUtil.normalize( location ); } else { final File file = new File( initialLocation.getFile() ); location = file.getAbsoluteFile().toString().replace( File.separatorChar, '/' ); location = FileUtil.normalize( location ); } URL finalLocation = null; try { finalLocation = new URL( initialLocation.getProtocol(), initialLocation.getHost(), initialLocation.getPort(), location ); } catch( final MalformedURLException mue ) { getLogger().warn( "Error building codeBase", mue ); } return new CodeSource( finalLocation, codeSource.getCertificates() ); } protected void copyPermissions( final Permissions destination, final Permissions src ) { final Enumeration enum = src.elements(); while( enum.hasMoreElements() ) { destination.add( (Permission)enum.nextElement() ); } } /** * Create a permission set for a codeBase. * These are read-write permissions and can be written till until the * time in which they are applied to code. * * @param location the location of codes to apply permission set to. * @param signers a comma seperated string of thos who signed codebase * @return the new permission set * @exception MalformedURLException if location string is malformed */ protected Permissions createPermissionSetFor( final String location, final Certificate[] signers ) throws MalformedURLException { final PolicyEntry entry = new PolicyEntry(); entry.m_codeSource = new CodeSource( new URL( location ), signers ); entry.m_codeSource = normalize( entry.m_codeSource ); getLogger().debug( "createPermissionSetFor(" + entry.m_codeSource.getLocation() + ");" ); entry.m_permissions = new Permissions(); m_entries.add( entry ); return entry.m_permissions; } protected final Logger getLogger() { return m_logger; } } 1.1 jakarta-avalon-phoenix/src/java/org/apache/phoenix/engine/facilities/security/DefaultPolicy.java Index: DefaultPolicy.java =================================================================== /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. */ package org.apache.phoenix.engine.facilities.security; import java.io.File; import java.io.InputStream; import java.lang.reflect.Constructor; import java.net.MalformedURLException; import java.net.URL; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.Permission; import java.security.PermissionCollection; import java.security.Permissions; import java.security.UnresolvedPermission; import java.security.cert.Certificate; import java.util.ArrayList; import java.util.HashMap; import java.util.Hashtable; import java.util.Iterator; import java.util.PropertyPermission; import java.util.StringTokenizer; import org.apache.avalon.Component; import org.apache.avalon.Context; import org.apache.avalon.Contextualizable; import org.apache.avalon.DefaultContext; import org.apache.avalon.Initializable; import org.apache.avalon.atlantis.Facility; import org.apache.avalon.configuration.Configurable; import org.apache.avalon.configuration.Configuration; import org.apache.avalon.configuration.ConfigurationException; import org.apache.avalon.util.PropertyException; import org.apache.avalon.util.PropertyUtil; /** * Policy that extracts information from policy files. * * @author <a href="mailto:[EMAIL PROTECTED]">Peter Donald</a> */ public class DefaultPolicy extends AbstractPolicy implements Facility, Contextualizable, Configurable, Initializable { protected DefaultContext m_context; public void contextualize( final Context context ) { m_context = new DefaultContext( System.getProperties(), context ); m_context.put( "/", File.separator ); } public void configure( final Configuration configuration ) throws ConfigurationException { final Configuration[] keyStoreConfigurations = configuration.getChildren( "keystore" ); final HashMap keyStores = configureKeyStores( keyStoreConfigurations ); final Configuration[] grants = configuration.getChildren( "grant" ); configureGrants( grants, keyStores ); } public void init() throws Exception { //these properties straight out ot ${java.home}/lib/security/java.policy final Permissions permissions = createPermissionSetFor( "file:/-", null ); permissions.add( new PropertyPermission( "os.name", "read" ) ); permissions.add( new PropertyPermission( "os.arch", "read" ) ); permissions.add( new PropertyPermission( "os.version", "read" ) ); permissions.add( new PropertyPermission( "file.separator", "read" ) ); permissions.add( new PropertyPermission( "path.separator", "read" ) ); permissions.add( new PropertyPermission( "line.separator", "read" ) ); permissions.add( new PropertyPermission( "java.version", "read" ) ); permissions.add( new PropertyPermission( "java.vendor", "read" ) ); permissions.add( new PropertyPermission( "java.vendor.url", "read" ) ); permissions.add( new PropertyPermission( "java.class.version", "read" ) ); permissions.add( new PropertyPermission( "java.vm.version", "read" ) ); permissions.add( new PropertyPermission( "java.vm.vendor", "read" ) ); permissions.add( new PropertyPermission( "java.vm.name", "read" ) ); permissions.add( new PropertyPermission( "java.specification.version", "read" ) ); permissions.add( new PropertyPermission( "java.specification.vendor", "read" ) ); permissions.add( new PropertyPermission( "java.specification.name", "read" ) ); permissions.add( new PropertyPermission( "java.vm.specification.version", "read" ) ); permissions.add( new PropertyPermission( "java.vm.specification.vendor", "read" ) ); permissions.add( new PropertyPermission( "java.vm.specification.name", "read" ) ); } protected HashMap configureKeyStores( final Configuration[] configurations ) throws ConfigurationException { final HashMap keyStores = new HashMap(); for( int i = 0; i < configurations.length; i++ ) { final Configuration configuration = configurations[ i ]; final String type = configuration.getAttribute( "type" ); final String location = configuration.getAttribute( "location" ); final String name = configuration.getAttribute( "name" ); try { final KeyStore keyStore = KeyStore.getInstance( type ); final URL url = new URL( location ); final InputStream ins = url.openStream(); keyStore.load( ins, null ); keyStores.put( name, keyStore ); } catch( final Exception e ) { throw new ConfigurationException( "Error configuring keystore " + name, e ); } } return keyStores; } protected void configureGrants( final Configuration[] configurations, final HashMap keyStores ) throws ConfigurationException { for( int i = 0; i < configurations.length; i++ ) { configureGrant( configurations[ i ], keyStores ); } } protected void configureGrant( final Configuration configuration, final HashMap keyStores ) throws ConfigurationException { //<grant signed-by="Fred" code-base="file:${sar.home}/blocks/*" key-store="foo-keystore"> //<permission class="java.io.FilePermission" target="/tmp/*" action="read,write" /> //</grant> final String signedBy = configuration.getAttribute( "signed-by", null ); final String keyStoreName = configuration.getAttribute( "key-store", null ); String codeBase = configuration.getAttribute( "code-base", null ); if( null != codeBase ) { codeBase = expand( codeBase ); } final Certificate[] signers = getSigners( signedBy, keyStoreName, keyStores ); Permissions permissions = null; try { permissions = createPermissionSetFor( codeBase, signers ); } catch( final MalformedURLException mue ) { throw new ConfigurationException( "Malformed code-base " + codeBase, mue ); } configurePermissions( configuration.getChildren( "permission" ), permissions, keyStores ); } protected void configurePermissions( final Configuration[] configurations, final Permissions permissions, final HashMap keyStores ) throws ConfigurationException { for( int i = 0; i < configurations.length; i++ ) { configurePermission( configurations[ i ], permissions, keyStores ); } } protected void configurePermission( final Configuration configuration, final Permissions permissions, final HashMap keyStores ) throws ConfigurationException { final String type = configuration.getAttribute( "class" ); final String actions = configuration.getAttribute( "actions", null ); final String signedBy = configuration.getAttribute( "signed-by", null ); final String keyStoreName = configuration.getAttribute( "key-store", null ); String target = configuration.getAttribute( "target", null ); if( null != target ) { target = expand( target ); } final Certificate[] signers = getSigners( signedBy, keyStoreName, keyStores ); final Permission permission = createPermission( type, target, actions, signers ); permissions.add( permission ); } protected String expand( final String value ) throws ConfigurationException { try { final Object resolvedValue = PropertyUtil.resolveProperty( value, m_context, false ); return resolvedValue.toString(); } catch( final PropertyException pe ) { throw new ConfigurationException( "Error resolving property " + value, pe ); } } protected Permission createPermission( final String type, final String target, final String actions, final Certificate[] signers ) throws ConfigurationException { if( null != signers ) { return createUnresolvedPermission( type, target, actions, signers ); } try { final Class c = Class.forName( type ); Class paramClasses[] = null; Object params[] = null; if( null == actions && null == target ) { paramClasses = new Class[ 0 ]; params = new Object[ 0 ]; } else if( null == actions ) { paramClasses = new Class[1]; paramClasses[0] = String.class; params = new Object[1]; params[0] = target; } else { paramClasses = new Class[2]; paramClasses[0] = String.class; paramClasses[1] = String.class; params = new Object[2]; params[0] = target; params[1] = actions; } final Constructor constructor = c.getConstructor( paramClasses ); final Object o = constructor.newInstance( params ); return (Permission)o; } catch( final ClassNotFoundException cnfe ) { return createUnresolvedPermission( type, target, actions, signers ); } catch( final Exception e ) { throw new ConfigurationException( "Failed to create permission " + type + " due to " + e, e ); } } protected Permission createUnresolvedPermission( final String type, final String target, final String actions, final Certificate[] signers ) { return new UnresolvedPermission( type, target, actions, signers ); } protected Certificate[] getSigners( final String signedBy, String keyStoreName, final HashMap keyStores ) throws ConfigurationException { if( null != signedBy && null == keyStoreName ) { keyStoreName = "default"; } Certificate[] signers = null; if( null != signedBy ) { signers = getCertificates( signedBy, keyStoreName, keyStores ); } return signers; } protected Certificate[] getCertificates( final String signedBy, final String keyStoreName, final HashMap keyStores ) throws ConfigurationException { final KeyStore keyStore = (KeyStore)keyStores.get( keyStoreName ); if( null == keyStore ) { throw new ConfigurationException( "Unable to aquire keyStore " + keyStoreName ); } final ArrayList certificateSet = new ArrayList(); final StringTokenizer tokenizer = new StringTokenizer( signedBy, "," ); while( tokenizer.hasMoreTokens() ) { final String alias = ((String)tokenizer.nextToken()).trim(); Certificate certificate = null; try { certificate = keyStore.getCertificate( alias ); } catch( final KeyStoreException kse ) { throw new ConfigurationException( "Error aquiring certificate " + alias, kse ); } if( null == certificate ) { throw new ConfigurationException( "Unable to locate alias " + alias + " in keystore named " + keyStoreName ); } if( !certificateSet.contains( certificate ) ) { if( DEBUG ) getLogger().debug( "Certificate " + certificate ); certificateSet.add( certificate ); } } return (Certificate[])certificateSet.toArray( new Certificate[ 0 ] ); } } --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]