/*
* Copyright 2006-2008 Web Cohesion
*
* 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.codehaus.enunciate.config;
import org.apache.commons.digester.Digester;
import org.apache.commons.digester.Rule;
import org.apache.commons.digester.RuleSet;
import org.apache.commons.digester.parser.GenericParser;
import org.codehaus.enunciate.config.war.CopyResources;
import org.codehaus.enunciate.config.war.IncludeExcludeLibs;
import org.codehaus.enunciate.config.war.WebAppConfig;
import org.codehaus.enunciate.config.war.WebAppResource;
import org.codehaus.enunciate.contract.validation.DefaultValidator;
import org.codehaus.enunciate.contract.validation.Validator;
import org.codehaus.enunciate.main.webapp.FilterComponent;
import org.codehaus.enunciate.modules.BasicAppModule;
import org.codehaus.enunciate.modules.DeploymentModule;
import org.xml.sax.Attributes;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.*;
import java.util.*;
/**
* Base configuration object for enunciate.
*
* @author Ryan Heaton
*/
public class EnunciateConfiguration implements ErrorHandler {
private String label = "enunciate";
private String description = null;
private String generatedCodeLicenseFile = null;
private String deploymentProtocol = "http";
private String deploymentHost = "localhost:8080";
private String deploymentContext = null;
private String defaultSoapSubcontext = "/soap";
private String defaultRestSubcontext = "/rest";
private boolean isDefaultRestSubcontextSet = false;
private Validator validator = new DefaultValidator();
private final SortedSet<DeploymentModule> modules;
private final Map<String, String> namespaces = new HashMap<String, String>();
private final Map<String, String> contentTypes = new HashMap<String, String>();
private final Map<String, String> soapServices2Paths = new HashMap<String, String>();
private final List<APIImport> apiImports = new ArrayList<APIImport>();
private final Set<String> disabledRules = new TreeSet<String>();
private final Set<String> apiIncludePatterns = new TreeSet<String>();
private final Set<String> apiExcludePatterns = new TreeSet<String>();
private final Set<String> customResourceParameterAnnotations = new TreeSet<String>();
private final Set<String> systemResourceParameterAnnotations = new TreeSet<String>();
private boolean forceJAXWSSpecCompliance = false;
private boolean allowEmptyNamespace = true;
private boolean includeReferencedClasses = true;
private boolean excludeUnreferencedClasses = true;
private boolean includeReferenceTrailInErrors = false;
private boolean aggressiveWebMethodExcludePolicy = false;
private WebAppConfig webAppConfig;
private Set<String> facetIncludes = new TreeSet<String>();
private Set<String> facetExcludes = new TreeSet<String>();
/**
* Create a new enunciate configuration. The module list will be constructed
* using Sun's discovery mechanism.
*/
public EnunciateConfiguration() {
this((ClassLoader) null);
}
/**
* Create a new enunciate configuration. The module list will be constructed
* using Sun's discovery mechanism and the specified classloader.
*
* @param loader the classloader to use.
*/
public EnunciateConfiguration(ClassLoader loader) {
this.modules = new TreeSet<DeploymentModule>(new DeploymentModuleComparator());
Iterator discoveredModules = discoverModules(loader);
while (discoveredModules.hasNext()) {
DeploymentModule discoveredModule = (DeploymentModule) discoveredModules.next();
this.modules.add(discoveredModule);
}
this.modules.add(new BasicAppModule());
}
/**
* Discover the deployment modules.
* @return An iterator over the deployment modules.
* @param loader The classloader, or null if none.
*/
protected Iterator<DeploymentModule> discoverModules(ClassLoader loader) {
return loader == null ? ServiceLoader.load(DeploymentModule.class).iterator() : ServiceLoader.load(DeploymentModule.class, loader).iterator();
}
/**
* Construct an enunciate configuration with the specified set of modules.
*
* @param modules The modules.
*/
public EnunciateConfiguration(Collection<DeploymentModule> modules) {
this.modules = new TreeSet<DeploymentModule>(new DeploymentModuleComparator());
this.modules.addAll(modules);
}
/**
* The label for this enunciate project.
*
* @return The label for this enunciate project.
*/
public String getLabel() {
return label;
}
/**
* The label for this enunciate project.
*
* @param label The label for this enunciate project.
*/
public void setLabel(String label) {
this.label = label;
}
/**
* The description for this enunciated API.
*
* @return The description for this enunciated API.
*/
public String getDescription() {
return description;
}
/**
* The description for this enunciated API.
*
* @param description The description for this enunciated API.
*/
public void setDescription(String description) {
this.description = description;
}
/**
* A file on the filesystem to be read as containing the text for the license governing any Enunciate-generated code.
*
* @return A file on the filesystem to be read as containing the text for the license governing any Enunciate-generated code.
*/
public String getGeneratedCodeLicenseFile() {
return generatedCodeLicenseFile;
}
/**
* A file on the filesystem to be read as containing the text for the license governing any Enunciate-generated code.
*
* @param generatedCodeLicenseFile A file on the filesystem to be read as containing the text for the license governing any Enunciate-generated code.
*/
public void setGeneratedCodeLicenseFile(String generatedCodeLicenseFile) {
this.generatedCodeLicenseFile = generatedCodeLicenseFile;
}
/**
* The configured validator, if any.
*
* @return The configured validator, or null if none.
*/
public Validator getValidator() {
return validator;
}
/**
* The validator to use.
*
* @param validator The validator to use.
*/
public void setValidator(Validator validator) {
this.validator = validator;
}
/**
* The disabled rules.
*
* @return The disabled rules.
*/
public Set<String> getDisabledRules() {
return disabledRules;
}
/**
* Add a disabled rule.
*
* @param ruleId The id of the rule to disable.
*/
public void addDisabledRule(String ruleId) {
if (ruleId != null) {
this.disabledRules.add(ruleId);
}
}
/**
* The set of facets to include.
*
* @return The set of facets to include.
*/
public Set<String> getFacetIncludes() {
return facetIncludes;
}
/**
* Add a facet include.
*
* @param name The name.
*/
public void addFacetInclude(String name) {
if (name != null) {
this.facetIncludes.add(name);
}
}
/**
* The set of facets to exclude.
*
* @return The set of facets to exclude.
*/
public Set<String> getFacetExcludes() {
return facetExcludes;
}
/**
* Add a facet exclude.
*
* @param name The name.
*/
public void addFacetExclude(String name) {
if (name != null) {
this.facetExcludes.add(name);
}
}
/**
* The patterns for API includes.
*
* @return The patterns for API includes.
*/
public Set<String> getApiIncludePatterns() {
return apiIncludePatterns;
}
/**
* The API include pattern.
*
* @param pattern The API include pattern.
*/
public void addApiIncludePattern(String pattern) {
if (pattern != null) {
this.apiIncludePatterns.add(pattern);
}
}
/**
* The patterns for API excludes.
*
* @return The patterns for API excludes.
*/
public Set<String> getApiExcludePatterns() {
return apiExcludePatterns;
}
/**
* The API exclude pattern.
*
* @param pattern The API exclude pattern.
*/
public void addApiExcludePattern(String pattern) {
if (pattern != null) {
this.apiExcludePatterns.add(pattern);
}
}
/**
* The protocol that will be used when the app is deployed. Default: "http".
*
* @return The protocol that will be used when the app is deployed. Default: "http".
*/
public String getDeploymentProtocol() {
return deploymentProtocol;
}
/**
* The protocol that will be used when the app is deployed. Default: "http".
*
* @param deploymentProtocol The protocol that will be used when the app is deployed. Default: "http".
*/
public void setDeploymentProtocol(String deploymentProtocol) {
this.deploymentProtocol = deploymentProtocol;
}
/**
* The hostname of the host that will host the deployed app.
*
* @return The hostname of the host that will host the deployed app.
*/
public String getDeploymentHost() {
return deploymentHost;
}
/**
* The hostname of the host that will host the deployed app.
*
* @param deploymentHost The hostname of the host that will host the deployed app.
*/
public void setDeploymentHost(String deploymentHost) {
this.deploymentHost = deploymentHost;
}
/**
* Whether to force parameter names to be JAX-WS compliant.
*
* @return Whether to force parameter names to be JAX-WS compliant.
*/
public boolean isForceJAXWSSpecCompliance() {
return forceJAXWSSpecCompliance;
}
/**
* Whether to force parameter names to be JAX-WS compliant.
*
* @param forceJAXWSSpecCompliance Whether to force parameter names to be JAX-WS compliant.
*/
public void setForceJAXWSSpecCompliance(boolean forceJAXWSSpecCompliance) {
this.forceJAXWSSpecCompliance = forceJAXWSSpecCompliance;
}
/**
* Whether to allow the empty namespace on type/element definitions.
*
* @return Whether to allow the empty namespace on type/element definitions.
*/
public boolean isAllowEmptyNamespace() {
return allowEmptyNamespace;
}
/**
* Whether to allow the empty namespace on type/element definitions.
*
* @param allowEmptyNamespace Whether to allow the empty namespace on type/element definitions.
*/
public void setAllowEmptyNamespace(boolean allowEmptyNamespace) {
this.allowEmptyNamespace = allowEmptyNamespace;
}
/**
* Whether to include referencing type information in error messages.
*
* @return Whether to include referencing type information in error messages.
*/
public boolean isIncludeReferenceTrailInErrors() {
return includeReferenceTrailInErrors;
}
/**
* Whether to include referencing type information in error messages.
*
* @param includeReferenceTrailInErrors Whether to include referencing type information in error messages.
*/
public void setIncludeReferenceTrailInErrors(boolean includeReferenceTrailInErrors) {
this.includeReferenceTrailInErrors = includeReferenceTrailInErrors;
}
/**
* Whether web methods should be aggressively excluded.
*
* @return Whether web methods should be aggressively excluded.
*/
public boolean isAggressiveWebMethodExcludePolicy() {
return aggressiveWebMethodExcludePolicy;
}
/**
* Whether web methods should be aggressively excluded.
*
* @param aggressiveWebMethodExcludePolicy Whether web methods should be aggressively excluded.
*/
public void setAggressiveWebMethodExcludePolicy(boolean aggressiveWebMethodExcludePolicy) {
this.aggressiveWebMethodExcludePolicy = aggressiveWebMethodExcludePolicy;
}
/**
* Whether to include statically-referenced type definitions (default: true).
*
* @return Whether to include statically-referenced type definitions.
*/
public boolean isIncludeReferencedClasses() {
return includeReferencedClasses;
}
/**
* Whether to include statically-referenced type definitions (default: true).
*
* @param includeReferencedClasses Whether to include statically-referenced type definitions.
*/
public void setIncludeReferencedClasses(boolean includeReferencedClasses) {
this.includeReferencedClasses = includeReferencedClasses;
}
/**
* Whether to exclude classes that are not statically referenced (default: true).
*
* @return Whether to exclude classes that are not statically referenced.
*/
public boolean isExcludeUnreferencedClasses() {
return excludeUnreferencedClasses;
}
/**
* Whether to exclude classes that are not statically referenced.
*
* @param excludeUnreferencedClasses Whether to exclude classes that are not statically referenced.
*/
public void setExcludeUnreferencedClasses(boolean excludeUnreferencedClasses) {
this.excludeUnreferencedClasses = excludeUnreferencedClasses;
}
/**
* The configuration for the web app.
*
* @return The configuration for web app.
*/
public WebAppConfig getWebAppConfig() {
return webAppConfig;
}
/**
* The configuration for the web app.
*
* @param webAppConfig The configuration for the web app.
*/
public void setWebAppConfig(WebAppConfig webAppConfig) {
this.webAppConfig = webAppConfig;
}
/**
* The context at which the deployed app will be mounted.
*
* @return The context at which the deployed app will be mounted.
*/
public String getDeploymentContext() {
return deploymentContext;
}
/**
* The context at which the deployed app will be mounted.
*
* @param deploymentContext The context at which the deployed app will be mounted.
*/
public void setDeploymentContext(String deploymentContext) {
if (deploymentContext == null) {
deploymentContext = "";
}
if (!"".equals(deploymentContext)) {
if (!deploymentContext.startsWith("/")) {
deploymentContext = "/" + deploymentContext;
}
while (deploymentContext.endsWith("/")) {
deploymentContext = deploymentContext.substring(0, deploymentContext.length() - 1);
}
}
this.deploymentContext = deploymentContext;
}
/**
* Configures a namespace for the specified prefix.
*
* @param namespace The namespace.
* @param prefix The prefix.
*/
public void putNamespace(String namespace, String prefix) {
this.namespaces.put(namespace, prefix);
}
/**
* Configures a content type.
*
* @param type The value of the content type.
* @param id The id of the content type.
*/
public void putContentType(String type, String id) {
this.contentTypes.put(type, id);
}
/**
* The default soap context.
*
* @return The default soap context.
*/
public String getDefaultSoapSubcontext() {
return defaultSoapSubcontext;
}
/**
* The default soap context.
*
* @param defaultSoapSubcontext The default soap context.
*/
public void setDefaultSoapSubcontext(String defaultSoapSubcontext) {
if (defaultSoapSubcontext == null) {
throw new IllegalArgumentException("The default SOAP context must not be null.");
}
if ("".equals(defaultSoapSubcontext)) {
throw new IllegalArgumentException("The default SOAP context must not be the emtpy string.");
}
if (!defaultSoapSubcontext.startsWith("/")) {
defaultSoapSubcontext = "/" + defaultSoapSubcontext;
}
while (defaultSoapSubcontext.endsWith("/")) {
defaultSoapSubcontext = defaultSoapSubcontext.substring(0, defaultSoapSubcontext.length() - 1);
}
this.defaultSoapSubcontext = defaultSoapSubcontext;
}
/**
* The default rest context.
*
* @return The default rest context.
*/
public String getDefaultRestSubcontext() {
return defaultRestSubcontext;
}
/**
* The default rest context.
*
* @param defaultRestSubcontext The default rest context.
*/
public void setDefaultRestSubcontext(String defaultRestSubcontext) {
if (defaultRestSubcontext == null) {
throw new IllegalArgumentException("The default REST context must not be null.");
}
if ("".equals(defaultRestSubcontext)) {
throw new IllegalArgumentException("The default REST context must not be the emtpy string.");
}
if (!defaultRestSubcontext.startsWith("/")) {
defaultRestSubcontext = "/" + defaultRestSubcontext;
}
while (defaultRestSubcontext.endsWith("/")) {
defaultRestSubcontext = defaultRestSubcontext.substring(0, defaultRestSubcontext.length() - 1);
}
this.defaultRestSubcontext = defaultRestSubcontext;
this.isDefaultRestSubcontextSet = true;
}
/**
* Set the default rest context iff it hasn't been set yet.
*
* @param defaultRestSubcontext The default rest context.
*/
public void setDefaultRestSubcontextConditionally(String defaultRestSubcontext) {
if (!this.isDefaultRestSubcontextSet) {
setDefaultRestSubcontext(defaultRestSubcontext);
}
}
/**
* Adds a custom soap endpoint location for an SOAP service.
*
* @param serviceName The service name.
* @param relativePath The relative path to the service.
*/
public void addSoapEndpointLocation(String serviceName, String relativePath) {
if (serviceName == null) {
throw new IllegalArgumentException("A service name must be provided for a custom soap endpoint location.");
}
if (relativePath != null) {
if ("".equals(relativePath)) {
throw new IllegalArgumentException("A relative path for the custom soap location must be provided for the service name '" + serviceName + "'.");
}
if (!relativePath.startsWith("/")) {
relativePath = "/" + relativePath;
}
while (relativePath.endsWith("/")) {
relativePath = relativePath.substring(0, relativePath.length() - 1);
}
this.soapServices2Paths.put(serviceName, relativePath);
}
}
/**
* Add an API import to the configuration.
*
* @param apiImport The API import to add to the configuration.
*/
public void addAPIImport(APIImport apiImport) {
this.apiImports.add(apiImport);
}
/**
* Get the list of API imports for this configuration.
*
* @return the list of API imports for this configuration.
*/
public List<APIImport> getAPIImports() {
return apiImports;
}
/**
* The map of namespaces to prefixes.
*
* @return The map of namespaces to prefixes.
*/
public Map<String, String> getNamespacesToPrefixes() {
return this.namespaces;
}
/**
* The map of content types to ids.
*
* @return The map of content types to ids.
*/
public Map<String, String> getContentTypesToIds() {
return contentTypes;
}
/**
* Get the map of SOAP service names to custom paths.
*
* @return The map of soap service names to custom paths.
*/
public Map<String, String> getSoapServices2Paths() {
return soapServices2Paths;
}
/**
* The list of all deployment modules specified in the configuration.
*
* @return The list of all deployment modules specified in the configuration.
*/
public SortedSet<DeploymentModule> getAllModules() {
return modules;
}
/**
* Add a module to the list of modules.
*
* @param module The module to add.
*/
public void addModule(DeploymentModule module) {
this.modules.add(module);
}
/**
* The set of custom annotations that can be applied to indicate a resource parameter.
*
* @return The set of custom annotations that can be applied to indicate a resource parameter.
*/
public Set<String> getCustomResourceParameterAnnotations() {
return customResourceParameterAnnotations;
}
/**
* Add a custom annotation that can be applied to indicate a resource parameter.
*
* @param annotation The FQN of the annotation.
*/
public void addCustomResourceParameterAnnotation(String annotation) {
this.customResourceParameterAnnotations.add(annotation);
}
/**
* The set of annotations that can be applied to indicate a system-supplied resource parameter.
*
* @return The set of annotations that can be applied to indicate a system-supplied resource parameter.
*/
public Set<String> getSystemResourceParameterAnnotations() {
return systemResourceParameterAnnotations;
}
/**
* Add a custom annotation that can be applied to indicate a system resource parameter.
*
* @param annotation The FQN of the annotation.
*/
public void addSystemResourceParameterAnnotation(String annotation) {
this.systemResourceParameterAnnotations.add(annotation);
}
/**
* The list of enabled modules in the configuration.
*
* @return The list of enabled modules in the configuration.
*/
public List<DeploymentModule> getEnabledModules() {
ArrayList<DeploymentModule> enabledModules = new ArrayList<DeploymentModule>();
for (DeploymentModule module : getAllModules()) {
if (!module.isDisabled()) {
enabledModules.add(module);
}
}
return enabledModules;
}
/**
* Loads the configuration specified by the given config file.
*
* @param file The file.
*/
public void load(File file) throws IOException, SAXException {
load(new FileInputStream(file));
}
/**
* Loads the configuration specified by the given stream.
*
* @param in The stream.
*/
public void load(InputStream in) throws IOException, SAXException {
load(new InputStreamReader(in, "utf-8"));
}
/**
* Loads the configuration specified by the given stream.
*
* @param in The stream.
*/
public void load(Reader in) throws IOException, SAXException {
Digester digester = createDigester();
digester.setErrorHandler(this);
digester.setValidating(false);
digester.push(this);
//set any root-level attributes
digester.addSetProperties("enunciate");
//allow a validator to be configured.
digester.addObjectCreate("enunciate/validator", "class", DefaultValidator.class);
digester.addSetNext("enunciate/validator", "setValidator");
//set up the include/excludes
digester.addSetProperties("enunciate/api-classes");
digester.addCallMethod("enunciate/api-classes/include", "addApiIncludePattern", 1);
digester.addCallParam("enunciate/api-classes/include", 0, "pattern");
digester.addCallMethod("enunciate/api-classes/exclude", "addApiExcludePattern", 1);
digester.addCallParam("enunciate/api-classes/exclude", 0, "pattern");
//set up the ability to disable certain rules
digester.addCallMethod("enunciate/disable-rule", "addDisabledRule", 1);
digester.addCallParam("enunciate/disable-rule", 0, "id");
//set up the ability to include/exclude facets
digester.addCallMethod("enunciate/facets/include", "addFacetInclude", 1);
digester.addCallParam("enunciate/facets/include", 0, "name");
digester.addCallMethod("enunciate/facets/exclude", "addFacetExclude", 1);
digester.addCallParam("enunciate/facets/exclude", 0, "name");
//allow for classes and packages to be imported for JAXB.
digester.addObjectCreate("enunciate/api-import", APIImport.class);
digester.addSetProperties("enunciate/api-import",
new String[] {"classname", "class", "pattern", "seekSource"},
new String[] {"pattern", "pattern", "pattern", "seekSource"});
digester.addSetNext("enunciate/api-import", "addAPIImport");
//allow for the deployment configuration to be specified.
digester.addSetProperties("enunciate/deployment",
new String[] {"protocol", "host", "context"},
new String[] {"deploymentProtocol", "deploymentHost", "deploymentContext"});
//allow for namespace prefixes to be specified in the config file.
digester.addCallMethod("enunciate/namespaces/namespace", "putNamespace", 2);
digester.addCallParam("enunciate/namespaces/namespace", 0, "uri");
digester.addCallParam("enunciate/namespaces/namespace", 1, "id");
//allow for the default soap subcontext to be set.
digester.addSetProperties("enunciate/services/rest");
//allow for namespace prefixes to be specified in the config file.
digester.addCallMethod("enunciate/services/rest/content-types/content-type", "putContentType", 2);
digester.addCallParam("enunciate/services/rest/content-types/content-type", 0, "type");
digester.addCallParam("enunciate/services/rest/content-types/content-type", 1, "id");
//allow for custom resource parameter annotations.
digester.addCallMethod("enunciate/services/rest/custom-resource-parameter-annotation", "addCustomResourceParameterAnnotation", 1);
digester.addCallParam("enunciate/services/rest/custom-resource-parameter-annotation", 0, "qualifiedName");
//allow for the default soap subcontext to be set.
digester.addSetProperties("enunciate/services/soap", "defaultSubcontext", "defaultSoapSubcontext");
digester.addSetProperties("enunciate/services/soap", "aggressiveWebMethodExcludePolicy", "aggressiveWebMethodExcludePolicy");
//allow for custom location of soap endpoints
digester.addCallMethod("enunciate/services/soap/service", "addSoapEndpointLocation", 2);
digester.addCallParam("enunciate/services/soap/service", 0, "name");
digester.addCallParam("enunciate/services/soap/service", 1, "relativePath");
digester.addObjectCreate("enunciate/webapp", WebAppConfig.class);
digester.addSetProperties("enunciate/webapp");
digester.addSetNext("enunciate/webapp", "setWebAppConfig");
digester.addObjectCreate("enunciate/webapp/resource-env-ref", WebAppResource.class);
digester.addSetProperties("enunciate/webapp/resource-env-ref");
digester.addSetNext("enunciate/webapp/resource-env-ref", "addResourceEnvRef");
digester.addObjectCreate("enunciate/webapp/resource-ref", WebAppResource.class);
digester.addSetProperties("enunciate/webapp/resource-ref");
digester.addSetNext("enunciate/webapp/resource-ref", "addResourceRef");
digester.addObjectCreate("enunciate/webapp/env", WebAppResource.class);
digester.addSetProperties("enunciate/webapp/env");
digester.addSetNext("enunciate/webapp/env", "addEnvEntry");
//allow jboss options to be added.
digester.addCallMethod("enunciate/webapp/attribute", "addWebXmlAttribute", 2);
digester.addCallParam("enunciate/webapp/attribute", 0, "name");
digester.addCallParam("enunciate/webapp/attribute", 1, "value");
digester.addObjectCreate("enunciate/webapp/excludeJar", IncludeExcludeLibs.class);
digester.addSetProperties("enunciate/webapp/excludeJar");
digester.addSetNext("enunciate/webapp/excludeJar", "addExcludeLibs");
digester.addObjectCreate("enunciate/webapp/excludeLibs", IncludeExcludeLibs.class);
digester.addSetProperties("enunciate/webapp/excludeLibs");
digester.addSetNext("enunciate/webapp/excludeLibs", "addExcludeLibs");
digester.addObjectCreate("enunciate/webapp/includeLibs", IncludeExcludeLibs.class);
digester.addSetProperties("enunciate/webapp/includeLibs");
digester.addSetNext("enunciate/webapp/includeLibs", "addIncludeLibs");
digester.addCallMethod("enunciate/webapp/manifest/attribute", "addManifestAttribute", 3);
digester.addCallParam("enunciate/webapp/manifest/attribute", 0, "section");
digester.addCallParam("enunciate/webapp/manifest/attribute", 1, "name");
digester.addCallParam("enunciate/webapp/manifest/attribute", 2, "value");
digester.addObjectCreate("enunciate/webapp/resources", CopyResources.class);
digester.addSetProperties("enunciate/webapp/resources");
digester.addSetNext("enunciate/webapp/resources", "addCopyResources");
digester.addObjectCreate("enunciate/webapp/globalServletFilter", FilterComponent.class);
digester.addSetProperties("enunciate/webapp/globalServletFilter");
digester.addSetNext("enunciate/webapp/globalServletFilter", "addGlobalServletFilter");
digester.addCallMethod("enunciate/webapp/globalServletFilter/init-param", "addInitParam", 2);
digester.addCallParam("enunciate/webapp/globalServletFilter/init-param", 0, "name");
digester.addCallParam("enunciate/webapp/globalServletFilter/init-param", 1, "value");
//set up the module configuration.
for (DeploymentModule module : getAllModules()) {
String pattern = String.format("enunciate/modules/%s", module.getName());
digester.addRule(pattern, new PushModuleRule(module));
digester.addSetProperties(pattern);
if (module.getAliases() != null) {
for (String alias : module.getAliases()) {
pattern = String.format("enunciate/modules/%s", alias);
digester.addRule(pattern, new PushModuleRule(module));
digester.addSetProperties(pattern);
}
}
RuleSet configRules = module.getConfigurationRules();
if (configRules != null) {
digester.addRuleSet(configRules);
}
}
digester.parse(in);
}
/**
* Create the digester.
*
* @return The digester that was created.
*/
protected Digester createDigester() throws SAXException {
try {
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setNamespaceAware(false);
factory.setValidating(false);
Properties properties = new Properties();
properties.put("SAXParserFactory", factory);
// properties.put("schemaLocation", EnunciateConfiguration.class.getResource("enunciate.xsd").toString());
// properties.put("schemaLanguage", "http://www.w3.org/2001/XMLSchema");
SAXParser parser = GenericParser.newSAXParser(properties);
return new Digester(parser);
}
catch (ParserConfigurationException e) {
throw new SAXException(e);
}
}
/**
* Handle a warning.
*
* @param warning The warning.
*/
public void warning(SAXParseException warning) throws SAXException {
System.err.println(warning.getMessage());
}
/**
* Handle an error.
*
* @param error The error.
*/
public void error(SAXParseException error) throws SAXException {
throw error;
}
/**
* Handle a fatal.
*
* @param fatal The fatal.
*/
public void fatalError(SAXParseException fatal) throws SAXException {
throw fatal;
}
/**
* Rule to push a specific deployment module onto the digester stack.
*/
private static class PushModuleRule extends Rule {
private final DeploymentModule module;
public PushModuleRule(DeploymentModule module) {
this.module = module;
}
@Override
public void begin(String namespace, String name, Attributes attributes) throws Exception {
getDigester().push(module);
}
@Override
public void end(String namespace, String name) throws Exception {
getDigester().pop();
}
}
}