1 8 package org.apache.avalon.phoenix.components.configuration.validator; 9 10 import java.io.File ; 11 import java.io.IOException ; 12 import java.net.URL ; 13 import java.util.Collections ; 14 import java.util.HashMap ; 15 import java.util.Map ; 16 import org.apache.avalon.excalibur.i18n.ResourceManager; 17 import org.apache.avalon.excalibur.i18n.Resources; 18 import org.apache.avalon.excalibur.io.FileUtil; 19 import org.apache.avalon.excalibur.io.IOUtil; 20 import org.apache.avalon.framework.activity.Initializable; 21 import org.apache.avalon.framework.configuration.Configurable; 22 import org.apache.avalon.framework.configuration.Configuration; 23 import org.apache.avalon.framework.configuration.ConfigurationException; 24 import org.apache.avalon.framework.configuration.DefaultConfigurationSerializer; 25 import org.apache.avalon.framework.logger.AbstractLogEnabled; 26 import org.apache.avalon.phoenix.interfaces.ConfigurationValidator; 27 import org.apache.avalon.phoenix.interfaces.ConfigurationValidatorMBean; 28 import org.apache.excalibur.configuration.ConfigurationUtil; 29 import org.iso_relax.verifier.Schema; 30 import org.iso_relax.verifier.Verifier; 31 import org.iso_relax.verifier.VerifierConfigurationException; 32 import org.iso_relax.verifier.VerifierFactory; 33 import org.iso_relax.verifier.VerifierHandler; 34 import org.xml.sax.ErrorHandler ; 35 import org.xml.sax.SAXException ; 36 import org.xml.sax.SAXParseException ; 37 38 44 public class JarvConfigurationValidator extends AbstractLogEnabled 45 implements Configurable, Initializable, ConfigurationValidator, ConfigurationValidatorMBean 46 { 47 private static final Resources REZ = 48 ResourceManager.getPackageResources( JarvConfigurationValidator.class ); 49 50 private String m_schemaType; 51 52 private String m_schemaLanguage; 53 54 private String m_verifierFactoryClass; 55 56 private String m_debugPath; 57 58 private final DefaultConfigurationSerializer m_serializer = 59 new DefaultConfigurationSerializer(); 60 61 private final Map m_schemaURLs = Collections.synchronizedMap( new HashMap () ); 62 63 private final Map m_schemas = Collections.synchronizedMap( new HashMap () ); 64 65 private VerifierFactory m_verifierFactory; 66 67 78 public void configure( Configuration configuration ) 79 throws ConfigurationException 80 { 81 this.m_debugPath = configuration.getChild( "debug-output-path" ).getValue( null ); 82 this.m_schemaType = configuration.getAttribute( "schema-type" ); 83 this.m_schemaLanguage = configuration.getChild( "schema-language" ).getValue( null ); 84 this.m_verifierFactoryClass = 85 configuration.getChild( "verifier-factory-class" ).getValue( null ); 86 87 if( (null == this.m_schemaLanguage && null == this.m_verifierFactoryClass) 88 || (null != this.m_schemaLanguage && null != this.m_verifierFactoryClass) ) 89 { 90 throw new ConfigurationException( REZ.getString( "jarv.error.badconfig" ) ); 91 } 92 } 93 94 public void initialize() 95 throws Exception 96 { 97 if( null != this.m_schemaLanguage ) 98 { 99 this.m_verifierFactory = VerifierFactory.newInstance( this.m_schemaLanguage ); 100 } 101 else if( null != this.m_verifierFactoryClass ) 102 { 103 this.m_verifierFactory = 104 (VerifierFactory)Class.forName( this.m_verifierFactoryClass ).newInstance(); 105 } 106 107 if( null != this.m_debugPath ) 108 { 109 FileUtil.forceMkdir( new File ( m_debugPath ) ); 110 } 111 112 this.m_serializer.setIndent( true ); 113 } 114 115 private String createKey( String application, String block ) 116 { 117 return application + "." + block; 118 } 119 120 public void addSchema( String application, String block, String schemaType, String url ) 121 throws ConfigurationException 122 { 123 if( !this.m_schemaType.equals( schemaType ) ) 124 { 125 final String msg = REZ.getString( "jarv.error.badtype", schemaType, this.m_schemaType ); 126 127 throw new ConfigurationException( msg ); 128 } 129 130 try 131 { 132 final String key = createKey( application, block ); 133 134 this.m_schemas.put( key, this.m_verifierFactory.compileSchema( url ) ); 135 this.m_schemaURLs.put( key, url ); 136 } 137 catch( VerifierConfigurationException e ) 138 { 139 final String msg = REZ.getString( "jarv.error.schema.create", application, block, url ); 140 141 throw new ConfigurationException( msg, e ); 142 } 143 catch( SAXParseException e ) 144 { 145 final String msg = REZ.getString( "jarv.error.schema.parse", 146 application, 147 block, 148 new Integer ( e.getLineNumber() ), 149 new Integer ( e.getColumnNumber() ) ); 150 151 throw new ConfigurationException( msg, e ); 152 } 153 catch( Exception e ) 154 { 155 final String msg = REZ.getString( "jarv.error.schema", application, block, url ); 156 157 throw new ConfigurationException( msg, e ); 158 } 159 160 if( getLogger().isDebugEnabled() ) 161 getLogger().debug( "Created schema [app: " + application + ", block: " + block 162 + ", url: " + url + "]" ); 163 } 164 165 public boolean isFeasiblyValid( String application, String block, Configuration configuration ) 167 throws ConfigurationException 168 { 169 return true; 170 } 171 172 public boolean isValid( final String application, 173 final String block, 174 final Configuration configuration ) 175 throws ConfigurationException 176 { 177 final Schema schema = (Schema)this.m_schemas.get( createKey( application, block ) ); 178 final Configuration branched = ConfigurationUtil.branch( configuration, "root" ); 179 180 if( null == schema ) 181 { 182 final String msg = REZ.getString( "jarv.error.noschema", application, block ); 183 184 throw new ConfigurationException( msg ); 185 } 186 187 if( null != this.m_debugPath ) 188 { 189 writeDebugConfiguration( application, block, branched ); 190 } 191 192 try 193 { 194 final Verifier verifier = schema.newVerifier(); 195 final VerifierHandler handler = verifier.getVerifierHandler(); 196 197 verifier.setErrorHandler( new ErrorHandler () 198 { 199 public void warning( SAXParseException exception ) 200 throws SAXException 201 { 202 if( getLogger().isWarnEnabled() ) 203 getLogger().warn( "Valdating configuration [app: " + application 204 + ", block: " + block 205 + ", msg: " + exception.getMessage() + "]" ); 206 } 207 208 public void error( SAXParseException exception ) 209 throws SAXException 210 { 211 if( getLogger().isErrorEnabled() ) 212 getLogger().error( "Valdating configuration [app: " + application 213 + ", block: " + block 214 + ", msg: " + exception.getMessage() + "]" ); 215 } 216 217 public void fatalError( SAXParseException exception ) 218 throws SAXException 219 { 220 if( getLogger().isFatalErrorEnabled() ) 221 getLogger().fatalError( "Valdating configuration [app: " + application 222 + ", block: " + block 223 + ", msg: " + exception.getMessage() + "]" ); 224 225 } 226 } ); 227 228 this.m_serializer.serialize( handler, branched ); 229 230 return handler.isValid(); 231 } 232 catch( VerifierConfigurationException e ) 233 { 234 final String msg = REZ.getString( "jarv.valid.schema", application, block ); 235 236 throw new ConfigurationException( msg, e ); 237 } 238 catch( SAXException e ) 239 { 240 final String msg = REZ.getString( "jarv.valid.badparse", application, block ); 241 242 throw new ConfigurationException( msg, e ); 243 } 244 catch( IllegalStateException e ) 245 { 246 final String msg = REZ.getString( "jarv.valid.badparse", application, block ); 247 248 throw new ConfigurationException( msg, e ); 249 } 250 } 251 252 private void writeDebugConfiguration( final String application, 253 final String block, 254 final Configuration configuration ) 255 { 256 try 257 { 258 final File temp = File.createTempFile( application + "-" + block + "-", 259 ".xml", 260 new File ( this.m_debugPath ) ); 261 262 this.m_serializer.serializeToFile( temp, configuration ); 263 264 if( getLogger().isDebugEnabled() ) 265 getLogger().debug( "Configuration written at: " + temp ); 266 } 267 catch( Exception e ) 268 { 269 getLogger().error( "Unable to write debug output", e ); 270 } 271 } 272 273 public void removeSchema( String application, String block ) 274 { 275 this.m_schemaURLs.remove( createKey( application, block ) ); 276 277 if( null != this.m_schemas.remove( createKey( application, block ) ) 278 && getLogger().isDebugEnabled() ) 279 getLogger().debug( "Removed schema [app: " + application + ", block: " + block + "]" ); 280 } 281 282 public String getSchemaType( String application, String block ) 283 { 284 return this.m_schemaType; 285 } 286 287 public String getSchema( String application, String block ) 288 { 289 final String key = createKey( application, block ); 290 final String url = (String )this.m_schemaURLs.get( key ); 291 292 if( null != url ) 293 { 294 try 295 { 296 return IOUtil.toString( new URL ( url ).openStream() ); 297 } 298 catch( IOException e ) 299 { 300 getLogger().error( "Unable to read schema [app: " + application 301 + ", block: " + block + ", url: " + url + "]", e ); 302 } 303 } 304 305 return null; 306 } 307 } 308 | Popular Tags |