proyal      2002/07/13 12:48:21

  Added:       src/java/org/apache/avalon/phoenix/components/configuration/validator
                        DelegatingConfigurationValidator.java
                        JarvConfigurationValidator.java
                        Resources.properties
  Log:
  * JarvConfigurationValidator - Use JARV api to validate schemas.
  * DelegatingConfigurationValidator - Load multiple validators and delegate upon 
schema-type
  
  Revision  Changes    Path
  1.1                  
jakarta-avalon-phoenix/src/java/org/apache/avalon/phoenix/components/configuration/validator/DelegatingConfigurationValidator.java
  
  Index: DelegatingConfigurationValidator.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.txt file.
   */
  package org.apache.avalon.phoenix.components.configuration.validator;
  
  import java.util.Collections;
  import java.util.HashMap;
  import java.util.Iterator;
  import java.util.Map;
  
  import org.apache.avalon.excalibur.i18n.ResourceManager;
  import org.apache.avalon.excalibur.i18n.Resources;
  import org.apache.avalon.framework.activity.Disposable;
  import org.apache.avalon.framework.activity.Initializable;
  import org.apache.avalon.framework.configuration.Configurable;
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.configuration.ConfigurationException;
  import org.apache.avalon.framework.container.ContainerUtil;
  import org.apache.avalon.framework.logger.AbstractLogEnabled;
  import org.apache.avalon.phoenix.interfaces.ConfigurationValidator;
  
  /**
   * Default ConfigurationValidator implementation that allows schemas to be plugged-in
   *
   * @author <a href="mailto:[EMAIL PROTECTED]";>Peter Royal</a>
   */
  public class DelegatingConfigurationValidator extends AbstractLogEnabled
    implements Configurable, Initializable, Disposable, ConfigurationValidator
  {
      private static final Resources REZ =
        ResourceManager.getPackageResources( DelegatingConfigurationValidator.class );
  
      private Map m_blockTypeMap = Collections.synchronizedMap( new HashMap() );
      private Map m_delegates = new HashMap();
      private String m_supportedTypes;
  
      public void configure( Configuration configuration )
        throws ConfigurationException
      {
          final Configuration[] delegates = configuration.getChildren( "delegate" );
          final StringBuffer types = new StringBuffer();
  
          for( int i = 0; i < delegates.length; i++ )
          {
              final String type = delegates[i].getAttribute( "schema-type" );
  
              this.m_delegates.put( type, new DelegateEntry( type, 
delegates[i].getAttribute( "class" ), delegates[i] ) );
  
              if( i > 0 )
              {
                  types.append( "," );
              }
  
              types.append( type );
          }
  
          this.m_supportedTypes = types.toString();
      }
  
      public void initialize()
        throws Exception
      {
          for( Iterator i = m_delegates.values().iterator(); i.hasNext(); )
          {
              final DelegateEntry entry = ( DelegateEntry ) i.next();
              final Class clazz = Class.forName( entry.getClassName() );
              final ConfigurationValidator validator = ( ConfigurationValidator ) 
clazz.newInstance();
  
              ContainerUtil.enableLogging( validator, getLogger() );
              ContainerUtil.configure( validator, entry.getConfiguration() );
              ContainerUtil.initialize( validator );
  
              entry.setValidator( validator );
          }
      }
  
      public void dispose()
      {
          for( Iterator i = m_delegates.values().iterator(); i.hasNext(); )
          {
              ContainerUtil.dispose( ( ( DelegateEntry ) i.next() ).getValidator() );
          }
      }
  
      public void addSchema( String application, String block, String schemaType, 
String url )
        throws ConfigurationException
      {
          final DelegateEntry entry = ( DelegateEntry ) this.m_delegates.get( 
schemaType );
  
          if( entry == null )
          {
              throw new ConfigurationException( REZ.getString( "jarv.error.badtype", 
schemaType, this.m_supportedTypes ) );
          }
  
          entry.getValidator().addSchema( application, block, schemaType, url );
          this.m_blockTypeMap.put( createKey( application, block ), schemaType );
      }
  
      public boolean isFeasiblyValid( String application, String block, Configuration 
configuration )
        throws ConfigurationException
      {
          return getDelegate( application, block ).isFeasiblyValid( application, 
block, configuration );
      }
  
      public boolean isValid( String application, String block, Configuration 
configuration )
        throws ConfigurationException
      {
          return getDelegate( application, block ).isValid( application, block, 
configuration );
      }
  
      public void removeSchema( String application, String block )
      {
          try
          {
              getDelegate( application, block ).removeSchema( application, block );
          }
          catch( ConfigurationException e )
          {
              getLogger().warn( "Unable to remove schema [app: " + application + ", 
block: " + block + "]", e );
          }
      }
  
      private ConfigurationValidator getDelegate( String application, String block )
        throws ConfigurationException
      {
          final String type = ( String ) this.m_blockTypeMap.get( createKey( 
application, block ) );
  
          if( null == type )
          {
              throw new ConfigurationException( REZ.getString( "jarv.error.noschema", 
application, block ) );
          }
  
          return ( ( DelegateEntry ) this.m_delegates.get( type ) ).getValidator();
      }
  
      private String createKey( String application, String block )
      {
          return application + "." + block;
      }
  
      private class DelegateEntry
      {
          private final String schemaType;
          private final String className;
          private final Configuration configuration;
  
          private ConfigurationValidator validator;
  
          public DelegateEntry( String schemaType, String className, Configuration 
configuration )
          {
              this.className = className;
              this.configuration = configuration;
              this.schemaType = schemaType;
          }
  
          public String getSchemaType()
          {
              return this.schemaType;
          }
  
          public Configuration getConfiguration()
          {
              return this.configuration;
          }
  
          public String getClassName()
          {
              return this.className;
          }
  
          public ConfigurationValidator getValidator()
          {
              return this.validator;
          }
  
          public void setValidator( ConfigurationValidator validator )
          {
              this.validator = validator;
          }
      }
  }
  
  
  
  1.1                  
jakarta-avalon-phoenix/src/java/org/apache/avalon/phoenix/components/configuration/validator/JarvConfigurationValidator.java
  
  Index: JarvConfigurationValidator.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.txt file.
   */
  package org.apache.avalon.phoenix.components.configuration.validator;
  
  import java.util.Collections;
  import java.util.HashMap;
  import java.util.Map;
  
  import org.xml.sax.ErrorHandler;
  import org.xml.sax.SAXException;
  import org.xml.sax.SAXParseException;
  
  import org.apache.avalon.excalibur.i18n.ResourceManager;
  import org.apache.avalon.excalibur.i18n.Resources;
  import org.apache.avalon.framework.activity.Initializable;
  import org.apache.avalon.framework.configuration.Configurable;
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.configuration.ConfigurationException;
  import org.apache.avalon.framework.configuration.DefaultConfigurationSerializer;
  import org.apache.excalibur.configuration.ConfigurationUtil;
  import org.apache.avalon.framework.logger.AbstractLogEnabled;
  import org.apache.avalon.phoenix.interfaces.ConfigurationValidator;
  
  import org.iso_relax.verifier.Schema;
  import org.iso_relax.verifier.Verifier;
  import org.iso_relax.verifier.VerifierConfigurationException;
  import org.iso_relax.verifier.VerifierFactory;
  import org.iso_relax.verifier.VerifierHandler;
  
  /**
   * A validator that is capable of validating any schema supported by the JARV
   * engine. <a 
href="http://iso-relax.sourceforge.net/";>http://iso-relax.sourceforge.net/</a>
   *
   * @author <a href="mailto:[EMAIL PROTECTED]";>Peter Royal</a>
   */
  public class JarvConfigurationValidator extends AbstractLogEnabled
    implements Configurable, Initializable, ConfigurationValidator
  {
      private static final Resources REZ =
        ResourceManager.getPackageResources( JarvConfigurationValidator.class );
  
      private String m_schemaType;
      private String m_schemaLanguage;
      private String m_verifierFactoryClass;
  
      private final DefaultConfigurationSerializer m_serializer = new 
DefaultConfigurationSerializer();
      private final Map m_schemas = Collections.synchronizedMap( new HashMap() );
      private VerifierFactory m_verifierFactory;
  
      /**
       * There are two possible configuration options for this class. They are 
mutually exclusive.
       * <ol>
       *   <li>&lt;schema-language&gt;<i>schema language 
uri</i>&lt;/schema-language&gt;</li>
       *   
<li>&lt;verifier-factory-class&gt;<i>classname</i>&lt;/verifier-factory-class&gt;<br>
       *      The fully-qualified classname to use as a verifier factory.
       *   </li>
       * </ol>
       *
       * @see 
http://iso-relax.sourceforge.net/apiDoc/org/iso_relax/verifier/VerifierFactory.html#newInstance(java.lang.String)
       */
      public void configure( Configuration configuration )
        throws ConfigurationException
      {
          this.m_schemaType = configuration.getAttribute( "schema-type" );
          this.m_schemaLanguage = configuration.getChild( "schema-language" 
).getValue( null );
          this.m_verifierFactoryClass = configuration.getChild( 
"verifier-factory-class" ).getValue( null );
  
          if( ( null == this.m_schemaLanguage && null == this.m_verifierFactoryClass )
            || ( null != this.m_schemaLanguage && null != this.m_verifierFactoryClass 
) )
          {
              throw new ConfigurationException( REZ.getString( "jarv.error.badconfig" 
) );
          }
      }
  
      public void initialize()
        throws Exception
      {
          if( null != this.m_schemaLanguage )
          {
              this.m_verifierFactory = VerifierFactory.newInstance( 
this.m_schemaLanguage );
          }
          else if( null != this.m_verifierFactoryClass )
          {
              this.m_verifierFactory = ( VerifierFactory ) Class.forName( 
this.m_verifierFactoryClass ).newInstance();
          }
      }
  
      private String createKey( String application, String block )
      {
          return application + "." + block;
      }
  
      public void addSchema( String application, String block, String schemaType, 
String url )
        throws ConfigurationException
      {
          if( !this.m_schemaType.equals( schemaType ) )
          {
              throw new ConfigurationException( REZ.getString( "jarv.error.badtype", 
schemaType, this.m_schemaType ) );
          }
  
          try
          {
              this.m_schemas.put( createKey( application, block ), 
this.m_verifierFactory.compileSchema( url ) );
          }
          catch( VerifierConfigurationException e )
          {
              throw new ConfigurationException( REZ.getString( 
"jarv.error.schema.create", application, block, url ), e );
          }
          catch( SAXParseException e )
          {
              final String msg = REZ.getString( "jarv.error.schema.parse",
                                                application,
                                                block,
                                                new Integer( e.getLineNumber() ),
                                                new Integer( e.getColumnNumber() ) );
  
              throw new ConfigurationException( msg, e );
          }
          catch( Exception e )
          {
              throw new ConfigurationException( REZ.getString( "jarv.error.schema", 
application, block, url ), e );
          }
  
          if( getLogger().isDebugEnabled() )
              getLogger().debug( "Created schema [app: " + application + ", block: " + 
block + ", url: " + url + "]" );
      }
  
      //JARV does not support feasability validation
      public boolean isFeasiblyValid( String application, String block, Configuration 
configuration )
        throws ConfigurationException
      {
          return true;
      }
  
      public boolean isValid( final String application, final String block, 
Configuration configuration )
        throws ConfigurationException
      {
          final Schema schema = ( Schema ) this.m_schemas.get( createKey( application, 
block ) );
  
          if( null == schema )
          {
              throw new ConfigurationException( REZ.getString( "jarv.error.noschema", 
application, block ) );
          }
  
          try
          {
              final Verifier verifier = schema.newVerifier();
              final VerifierHandler handler = verifier.getVerifierHandler();
  
              verifier.setErrorHandler( new ErrorHandler()
              {
                  public void warning( SAXParseException exception )
                    throws SAXException
                  {
                      if( getLogger().isWarnEnabled() )
                          getLogger().warn( "Valdating configuration [app: " + 
application + ", block: " + block
                                            + ", msg: " + exception.getMessage() + "]" 
);
                  }
  
                  public void error( SAXParseException exception )
                    throws SAXException
                  {
                      if( getLogger().isErrorEnabled() )
                          getLogger().error( "Valdating configuration [app: " + 
application + ", block: " + block
                                             + ", msg: " + exception.getMessage() + 
"]" );
                  }
  
                  public void fatalError( SAXParseException exception )
                    throws SAXException
                  {
                      if( getLogger().isFatalErrorEnabled() )
                          getLogger().fatalError( "Valdating configuration [app: " + 
application + ", block: " + block
                                                  + ", msg: " + exception.getMessage() 
+ "]" );
  
                  }
              } );
  
              this.m_serializer.serialize( handler, ConfigurationUtil.branch( 
configuration, "root" ) );
  
              return handler.isValid();
          }
          catch( VerifierConfigurationException e )
          {
              throw new ConfigurationException( REZ.getString( "jarv.valid.schema", 
application, block ), e );
          }
          catch( SAXException e )
          {
              throw new ConfigurationException( REZ.getString( "jarv.valid.badparse", 
application, block ), e );
          }
          catch( IllegalStateException e )
          {
              throw new ConfigurationException( REZ.getString( "jarv.valid.badparse", 
application, block ), e );
          }
      }
  
      public void removeSchema( String application, String block )
      {
          if( null != this.m_schemas.remove( createKey( application, block ) )
            && getLogger().isDebugEnabled() )
              getLogger().debug( "Removed schema [app: " + application + ", block: " + 
block + "]" );
      }
  }
  
  
  
  1.1                  
jakarta-avalon-phoenix/src/java/org/apache/avalon/phoenix/components/configuration/validator/Resources.properties
  
  Index: Resources.properties
  ===================================================================
  jarv.error.badconfig=Must specify either schema-language or verifier-factory-class
  jarv.error.badtype=Invalid schema type: {0}. Validator only supports {1}
  jarv.error.noschema=No schema found for application {0} block {1}
  jarv.error.schema=Unable to parse schema [app: {0}, block: {1}]
  jarv.error.schema.parse=Unable to parse schema [app: {0}, block: {1}, line: {2}, 
column: {3}]
  jarv.error.schema.create=Unable to create schema [app: {0}, block: {1}]
  jarv.valid.schema=Unable to verify configuration for application {0} block {1}
  jarv.valid.badparse=Unable to parse configuration for application {0} block {1}
  
  

--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to