/*
* Copyright 2006-2007 Dan Shellman
*
* Licensed 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 org.iscreen.ognl;
import java.util.Iterator;
import java.util.Set;
import org.iscreen.ConfigurationException;
import org.iscreen.impl.ConfiguredResource;
import org.iscreen.impl.DefaultValidationService;
import org.iscreen.impl.xml.XmlConfigConstraint;
import org.iscreen.impl.xml.XmlConfigDoc;
import org.iscreen.impl.xml.XmlConfigFailure;
import org.iscreen.impl.xml.XmlConfigLabel;
import org.iscreen.impl.xml.XmlConfigMapping;
import org.iscreen.impl.xml.XmlServiceFactory;
/**
* This factory constructs a ValidationService based upon an XML
* configuration (via file or String, etc.). This ValidationFactory
* supports XML files that use OGNL.
*
* @author Shellman, Dan
*/
public class OgnlXmlServiceFactory extends XmlServiceFactory
{
/**
* Default constructor.
*/
public OgnlXmlServiceFactory()
{
} //end OgnlXmlServiceFactory()
/**
* Registers an individual Validator configuration. This will create
* a configured Validator that can be referenced by other Validators or
* by adding a Validator to a Validation Set.
*
* @param globalDefaultResource The resource id, when all else fails.
* @param id The unique id of the Validator
* @param ref The unique id of the Validator this Validator references.
* This can be null and is optional.
* @param className The class name of the Validator (optional, but if
* there MUST be a valid ref).
* @param defaultResource The resource id if no id is defined locally.
* @param label The Label for the Validator. This is optional.
* @param doc The documentation for the Validator. This is optional.
* @param mappings The Set of mappings (can't be null, but can be empty).
* @param constraints The Set of constraints (can't be null, but can be empty).
* @param failures The Set of failures (can't be null, but can be empty).
*/
public void registerValidator( String globalDefaultResource,
String id,
String ref,
String className,
String defaultResource,
XmlConfigLabel label,
XmlConfigDoc doc,
Set mappings,
Set constraints,
Set failures )
{
OgnlConfiguredValidator validator;
if ( id == null || id.trim().equals( "" ) )
{
throw new ConfigurationException( "Invalid definition of a Validator. The id is missing. All validators must have a unique id." );
}
if ( ( className == null || className.trim().equals( "" ) ) &&
( ref == null || ref.trim().equals( "" ) ) )
{
throw new ConfigurationException( "Invalid definition of a Validator. Either the ref or the class name must be valid." );
}
validator = getValidator( id );
validator.setId( id );
validator.setClassName( className );
if ( ref != null && !ref.trim().equals( "" ) )
{
validator.setRef( getValidator( ref ) );
}
configureValidator( validator,
globalDefaultResource,
defaultResource,
label,
doc,
mappings,
constraints,
failures );
} //end registerValidator()
/**
* Registers a Validation Set.
*
* @param id The validation set's unique id.
*/
public void registerValidationSet( String id )
{
DefaultValidationService service;
if ( id == null || id.trim().equals( "" ) )
{
throw new ConfigurationException( "Invalid unique id for validation set. All validation sets must have a non-empty, unique id." );
}
//Check to see if it exists
if ( setMap.get( id ) == null )
{
service = new DefaultValidationService( id, getDefaultLocale() );
setMap.put( id, service );
}
} //end registerValidationSet()
/**
* Adds a 'use-validator' to a Validation Set. The 'use-validator' must
* reference a Validator.
*
* @param setId The Validation Set id.
* @param globalDefaultResource The configuration file's default resource
* (can be null/empty).
* @param defaultResource The Validation Set's default resource (optional).
* @param validatorRef The reference to a Validator (required).
* @param failFastFlag Whether to stop validations if this validator fails.
* @param label The label for this validator.
* @param doc Documentation for this use of the validator.
* @param mappings The mappings for this validator.
* @param constraints The constraints for this validator.
* @param failures The failures for this validator.
*/
public void addValidatorToSet( String setId,
String globalDefaultResource,
String defaultResource,
String validatorRef,
boolean failFastFlag,
String validatorName,
XmlConfigLabel label,
XmlConfigDoc doc,
Set mappings,
Set constraints,
Set failures )
{
OgnlConfiguredValidator validator;
DefaultValidationService service;
if ( validatorRef == null || validatorRef.trim().equals( "" ) )
{
throw new ConfigurationException( "Invalid reference to a Validator. The 'ref' attribute must be set and must point to a Validator." );
}
validator = new OgnlConfiguredValidator();
validator.setRef( getValidator( validatorRef ) );
configureValidator( validator,
globalDefaultResource,
defaultResource,
label,
doc,
mappings,
constraints,
failures );
validator.setFailFast( failFastFlag );
validator.setName( validatorName );
service = ( DefaultValidationService ) setMap.get( setId );
service.addValidatorWrapper( validator );
validator.setValidationService( service );
} //end addValidatorToSet()
/**
* Adds a validation set reference call to a validation set.
*
* @param setId The id of the containing Validation Set.
* @param setRefId The id of the Validation Set being referenced.
* @param failFastFlag Whether to continue validations if the set
* reports a failure.
* @param ifExp Whether to execute the validations in the referenced set.
* @param iterateExp Whether to iterate over the objects being mapped
* and validate each one.
* @param mapExp The mapping expression.
*/
public void addValidationSetToSet( String setId,
String setRefId,
boolean failFastFlag,
String name,
String ifExp,
String iterateExp,
String mapExp )
{
DefaultValidationService service;
DefaultValidationService referencedService;
OgnlValidationServiceValidator serviceWrapper;
//Grab the referenced service. If it doesn't exist, then create it.
referencedService = ( DefaultValidationService ) setMap.get( setRefId );
if ( referencedService == null )
{
referencedService = new DefaultValidationService( setRefId, getDefaultLocale() );
setMap.put( setRefId, referencedService );
}
//Configure the service "wrapper"
serviceWrapper = new OgnlValidationServiceValidator( referencedService );
serviceWrapper.setFailFast( failFastFlag );
serviceWrapper.setIfExpression( ifExp );
serviceWrapper.setIterateExpression( iterateExp );
serviceWrapper.setMapExpression( mapExp );
serviceWrapper.setName( name );
//This will never be null, since the registerValidationSet() will have
//been called before this method.
service = ( DefaultValidationService ) setMap.get( setId );
service.addValidatorWrapper( serviceWrapper );
} //end addValidationSetToSet()
/**
* Retrieves a OgnlConfiguredValidator with the given id. If one has not
* been previously registered, then create a blank one.
*
*
* @param id The Validator's id.
* @return Returns a Validator with the given id.
*/
public OgnlConfiguredValidator getValidator( String id )
{
OgnlConfiguredValidator validator;
validator = ( OgnlConfiguredValidator ) validatorMap.get( id );
if ( validator == null )
{
validator = new OgnlConfiguredValidator();
validator.setId( id );
validatorMap.put( id, validator );
}
return validator;
} //end getValidator()
// ***
// Protected methods
// ***
/**
* Handles the actual configuration of a Validator, whether via registration
* or by adding one to a Validation Set.
*/
protected void configureValidator( OgnlConfiguredValidator validator,
String globalDefaultResource,
String defaultResource,
XmlConfigLabel label,
XmlConfigDoc doc,
Set mappings,
Set constraints,
Set failures )
{
Iterator it;
//Configure the constraints.
it = constraints.iterator();
while ( it.hasNext() )
{
XmlConfigConstraint constraint;
constraint = ( XmlConfigConstraint ) it.next();
if ( constraint.getServiceId() == null ||
constraint.getServiceId().trim().equals( "" ) )
{
validator.addStaticProperty( constraint.getProperty(),
constraint.getValue() ); }
else
{
validator.addStaticProperty( constraint.getProperty(),
serviceMap.get( constraint.getServiceId() ) );
}
}
//Configure the failure objects.
it = failures.iterator();
while ( it.hasNext() )
{
XmlConfigFailure failure;
failure = ( XmlConfigFailure ) it.next();
if ( failure.getMessage() == null )
{
ConfiguredResource resource;
resource = getResource( failure.getResource(),
defaultResource,
globalDefaultResource );
validator.addStaticProperty( failure.getProperty(),
new OgnlResourceMessage( resource,
failure.getKey() ) );
}
else
{
validator.addStaticProperty( failure.getProperty(),
new OgnlMessage( failure.getMessage() ) );
}
}
//Configure mappings
it = mappings.iterator();
while ( it.hasNext() )
{
XmlConfigMapping mapping;
mapping = ( XmlConfigMapping ) it.next();
validator.addMapping( mapping.getFrom(), mapping.getTo() );
}
//TODO: this needs to be done better.
if ( label != null )
{
if ( label.getValue() != null )
{
validator.setLabel( label.getValue() );
}
else
{
validator.setLabel( getResource( label.getResourceId(),
defaultResource,
globalDefaultResource ),
label.getResourceKey() );
}
}
if ( doc != null )
{
validator.setDoc( doc.getContent() );
}
} //end configureValidator()
} //end OgnlXmlServiceFactory
|