All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.thymeleaf.Configuration Maven / Gradle / Ivy

The newest version!
/*
 * =============================================================================
 * 
 *   Copyright (c) 2011-2013, The THYMELEAF team (http://www.thymeleaf.org)
 * 
 *   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.thymeleaf;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.thymeleaf.cache.ICacheManager;
import org.thymeleaf.dialect.IDialect;
import org.thymeleaf.doctype.DocTypeIdentifier;
import org.thymeleaf.doctype.resolution.IDocTypeResolutionEntry;
import org.thymeleaf.doctype.translation.IDocTypeTranslation;
import org.thymeleaf.dom.Element;
import org.thymeleaf.dom.NestableAttributeHolderNode;
import org.thymeleaf.dom.Node;
import org.thymeleaf.exceptions.AlreadyInitializedException;
import org.thymeleaf.exceptions.ConfigurationException;
import org.thymeleaf.exceptions.NotInitializedException;
import org.thymeleaf.messageresolver.IMessageResolver;
import org.thymeleaf.processor.ProcessorAndContext;
import org.thymeleaf.standard.StandardDialect;
import org.thymeleaf.templatemode.ITemplateModeHandler;
import org.thymeleaf.templateresolver.ITemplateResolver;
import org.thymeleaf.util.Validate;

/**
 * 

* General configuration class, containing all the configuration items * for a {@link TemplateEngine}, including all the info for every configured * {@link IDialect}. *

*

* Except for testing purposes, there is no reason why a user might need to use this * class directly. *

* * @author Daniel Fernández * * @since 1.0 * */ public final class Configuration { /** * @deprecated Deprecated in 2.1.0. Create a new instance of the StandardDialect using its constructors instead. * Will be removed in 3.0 */ @Deprecated public static final IDialect STANDARD_THYMELEAF_DIALECT = new StandardDialect(); private static final TemplateResolverComparator TEMPLATE_RESOLVER_COMPARATOR = new TemplateResolverComparator(); private static final MessageResolverComparator MESSAGE_RESOLVER_COMPARATOR = new MessageResolverComparator(); private Set dialectConfigurations = null; private Map dialectsByPrefix = null; private Set dialectSet = null; private Set templateResolvers = new LinkedHashSet(3); private Set messageResolvers = new LinkedHashSet(3); private Set templateModeHandlers = new LinkedHashSet(8); private ICacheManager cacheManager = null; private Map> mergedSpecificProcessorsByElementName; private Map> mergedSpecificProcessorsByAttributeName; private Map, Set> mergedNonSpecificProcessorsByNodeClass; private Map mergedExecutionAttributes = null; private Set mergedDocTypeResolutionEntries = null; private Set mergedDocTypeTranslations = null; private final Map templateModeHandlersByName = new HashMap(8,1.0f); private Set defaultMessageResolvers = null; private Set defaultTemplateModeHandlers = null; private volatile boolean initialized; public Configuration() { super(); final StandardDialect standardDialect = new StandardDialect(); this.dialectConfigurations = new LinkedHashSet(4); this.dialectConfigurations.add( new DialectConfiguration(standardDialect.getPrefix(), standardDialect)); this.initialized = false; } private boolean isInitialized() { return this.initialized; } private void checkNotInitialized() { if (isInitialized()) { throw new AlreadyInitializedException( "Cannot modify template engine configuration when it has already been initialized"); } } private void checkInitialized() { if (!isInitialized()) { throw new NotInitializedException("Configuration has not been initialized"); } } public synchronized void initialize() { if (!isInitialized()) { /* * Checking dialects exist */ if (this.dialectConfigurations == null) { throw new ConfigurationException("Cannot initialize: a dialect has not been set"); } /* * Initialize dialect configurations */ for (final DialectConfiguration dialectConfiguration : this.dialectConfigurations) { dialectConfiguration.initialize(); } /* * Initialize "dialects by prefix" map and the "dialect set" */ this.dialectsByPrefix = new LinkedHashMap(4,1.0f); for (final DialectConfiguration dialectConfiguration : this.dialectConfigurations) { this.dialectsByPrefix.put(dialectConfiguration.getPrefix(), dialectConfiguration.getDialect()); } this.dialectsByPrefix = Collections.unmodifiableMap(this.dialectsByPrefix); this.dialectSet = Collections.unmodifiableSet(new LinkedHashSet(this.dialectsByPrefix.values())); /* * Merge dialects */ final MergedDialectArtifacts mergedDialectArtifacts = mergeDialects(this.dialectConfigurations); this.mergedSpecificProcessorsByElementName = Collections.unmodifiableMap(mergedDialectArtifacts.getSpecificProcessorsByElementName()); this.mergedSpecificProcessorsByAttributeName = Collections.unmodifiableMap(mergedDialectArtifacts.getSpecificProcessorsByAttributeName()); this.mergedNonSpecificProcessorsByNodeClass = Collections.unmodifiableMap(mergedDialectArtifacts.getMergedNonSpecificProcessorsByNodeClass()); this.mergedExecutionAttributes = Collections.unmodifiableMap(mergedDialectArtifacts.getExecutionAttributes()); this.mergedDocTypeResolutionEntries = Collections.unmodifiableSet(mergedDialectArtifacts.getDocTypeResolutionEntries()); this.mergedDocTypeTranslations = Collections.unmodifiableSet(mergedDialectArtifacts.getDocTypeTranslations()); /* * Checking template resolvers */ if (this.templateResolvers == null || this.templateResolvers.size() <= 0) { throw new ConfigurationException("Cannot initialize: no template resolvers have been set"); } final List templateResolversList = new ArrayList(this.templateResolvers); for (final ITemplateResolver templateResolver : templateResolversList) { templateResolver.initialize(); } Collections.sort(templateResolversList, TEMPLATE_RESOLVER_COMPARATOR); this.templateResolvers = new LinkedHashSet(templateResolversList); /* * Checking message resolvers */ if (this.messageResolvers == null) { throw new ConfigurationException("Cannot initialize: message resolvers set is null"); } if (this.messageResolvers.size() == 0) { // No message resolvers have been set, so default initialization will be performed if (this.defaultMessageResolvers == null || this.defaultMessageResolvers.size() == 0) { throw new ConfigurationException( "Cannot initialize: no message resolvers have been set and " + "no default message resolvers have been set either."); } this.messageResolvers = this.defaultMessageResolvers; } for (final IMessageResolver messageResolver : this.messageResolvers) { messageResolver.initialize(); } final List messageResolversList = new ArrayList(this.messageResolvers); Collections.sort(messageResolversList, MESSAGE_RESOLVER_COMPARATOR); this.messageResolvers = new LinkedHashSet(messageResolversList); /* * Checking template mode handlers */ if (this.templateModeHandlers == null) { throw new ConfigurationException("Cannot initialize: template mode handlers set is null"); } if (this.templateModeHandlers.size() == 0) { // No message resolvers have been set, so default initialization will be performed if (this.defaultTemplateModeHandlers == null || this.defaultTemplateModeHandlers.size() == 0) { throw new ConfigurationException( "Cannot initialize: no template mode handlers have been set and " + "no default template mode handlers have been set either."); } this.templateModeHandlers = this.defaultTemplateModeHandlers; } for (final ITemplateModeHandler handler : this.templateModeHandlers) { if (this.templateModeHandlersByName.containsKey(handler.getTemplateModeName())) { throw new ConfigurationException( "More than one handler configured for template mode \"" + handler.getTemplateModeName() + "\""); } if (handler.getTemplateParser() == null) { throw new ConfigurationException( "Null parser returned by handler for template mode \"" + handler.getTemplateModeName() + "\""); } this.templateModeHandlersByName.put(handler.getTemplateModeName(), handler); } /* * Mark as initialized */ this.initialized = true; } } void printConfiguration() { ConfigurationPrinterHelper.printConfiguration( this.dialectConfigurations, this.templateResolvers, this.messageResolvers, this.cacheManager, this.templateModeHandlers); } public ICacheManager getCacheManager() { return this.cacheManager; } public void setCacheManager(final ICacheManager cacheManager) { // Can be set to null (= no caches) checkNotInitialized(); this.cacheManager = cacheManager; } public Set getDialectSet() { if (!isInitialized()) { // If we haven't initialized yet, compute return Collections.unmodifiableSet(new LinkedHashSet(getDialects().values())); } return this.dialectSet; } public Map getDialects() { if (!isInitialized()) { // If we haven't initialized yet, compute final Map dialects = new LinkedHashMap(4, 1.0f); for (final DialectConfiguration dialectConfiguration : this.dialectConfigurations) { dialects.put(dialectConfiguration.getPrefix(), dialectConfiguration.getDialect()); } return Collections.unmodifiableMap(dialects); } return this.dialectsByPrefix; } public void setDialects(final Map dialects) { checkNotInitialized(); Validate.notNull(dialects, "Dialect set cannot be null"); Validate.isTrue(dialects.size() > 0, "Dialect set cannot be empty"); this.dialectConfigurations.clear(); for (final Map.Entry dialectEntry : dialects.entrySet()) { this.dialectConfigurations.add(new DialectConfiguration(dialectEntry.getKey(), dialectEntry.getValue())); } } public void setDialect(final IDialect dialect) { checkNotInitialized(); Validate.notNull(dialect, "Dialect set cannot be null"); this.dialectConfigurations.clear(); this.dialectConfigurations.add(new DialectConfiguration(dialect.getPrefix(), dialect)); } public void addDialect(final String prefix, final IDialect dialect) { checkNotInitialized(); Validate.notNull(dialect, "Dialect set cannot be null"); this.dialectConfigurations.add(new DialectConfiguration(prefix, dialect)); } public void clearDialects() { checkNotInitialized(); this.dialectConfigurations.clear(); } public Set getTemplateResolvers() { return Collections.unmodifiableSet(this.templateResolvers); } public void setTemplateResolvers(final Set templateResolvers) { checkNotInitialized(); Validate.notNull(templateResolvers, "Template Resolver set cannot be null"); Validate.isTrue(templateResolvers.size() > 0, "Template Resolver set cannot be empty"); Validate.containsNoNulls(templateResolvers, "Template Resolver set cannot contain any nulls"); this.templateResolvers = new LinkedHashSet(templateResolvers); } public void addTemplateResolver(final ITemplateResolver templateResolver) { checkNotInitialized(); Validate.notNull(templateResolver, "Template Resolver cannot be null"); this.templateResolvers.add(templateResolver); } public void setTemplateResolver(final ITemplateResolver templateResolver) { checkNotInitialized(); Validate.notNull(templateResolver, "Template Resolver cannot be null"); this.templateResolvers = Collections.singleton(templateResolver); } public Set getMessageResolvers() { return Collections.unmodifiableSet(this.messageResolvers); } public void setMessageResolvers(final Set messageResolvers) { checkNotInitialized(); Validate.notNull(messageResolvers, "Message Resolver set cannot be null"); Validate.isTrue(messageResolvers.size() > 0, "Message Resolver set cannot be empty"); Validate.containsNoNulls(messageResolvers, "Message Resolver set cannot contain any nulls"); this.messageResolvers = new LinkedHashSet(messageResolvers); } public void addMessageResolver(final IMessageResolver messageResolver) { checkNotInitialized(); Validate.notNull(messageResolver, "Message Resolver cannot be null"); this.messageResolvers.add(messageResolver); } public void setMessageResolver(final IMessageResolver messageResolver) { checkNotInitialized(); Validate.notNull(messageResolver, "Message Resolver cannot be null"); this.messageResolvers = Collections.singleton(messageResolver); } public void setDefaultMessageResolvers(final Set defaultMessageResolvers) { checkNotInitialized(); Validate.notNull(defaultMessageResolvers, "Default Message Resolver set cannot be null"); Validate.isTrue(defaultMessageResolvers.size() > 0, "Default Message Resolver set cannot be empty"); Validate.containsNoNulls(defaultMessageResolvers, "Default Message Resolver set cannot contain any nulls"); this.defaultMessageResolvers = new LinkedHashSet(defaultMessageResolvers); } public Set getTemplateModeHandlers() { return Collections.unmodifiableSet(this.templateModeHandlers); } public ITemplateModeHandler getTemplateModeHandler(final String templateMode) { return this.templateModeHandlersByName.get(templateMode); } public void setTemplateModeHandlers(final Set templateModeHandlers) { checkNotInitialized(); Validate.notNull(templateModeHandlers, "Template Mode Handler set cannot be null"); Validate.isTrue(templateModeHandlers.size() > 0, "Template Mode Handler set cannot be empty"); Validate.containsNoNulls(templateModeHandlers, "Template Mode Handler set cannot contain any nulls"); this.templateModeHandlers = new LinkedHashSet(templateModeHandlers); } public void addTemplateModeHandler(final ITemplateModeHandler templateModeHandler) { checkNotInitialized(); Validate.notNull(templateModeHandler, "Template Mode Handler cannot be null"); this.templateModeHandlers.add(templateModeHandler); } public void setDefaultTemplateModeHandlers(final Set defaultTemplateModeHandlers) { checkNotInitialized(); Validate.notNull(defaultTemplateModeHandlers, "Default Template Mode Handler set cannot be null"); Validate.isTrue(defaultTemplateModeHandlers.size() > 0, "Default Template Mode Handler set cannot be empty"); Validate.containsNoNulls(defaultTemplateModeHandlers, "Default Template Mode Handler set cannot contain any nulls"); this.defaultTemplateModeHandlers = new LinkedHashSet(defaultTemplateModeHandlers); } public Set getDocTypeTranslations() { checkInitialized(); return this.mergedDocTypeTranslations; } public IDocTypeTranslation getDocTypeTranslationBySource(final String publicID, final String systemID) { checkInitialized(); for (final IDocTypeTranslation translation : this.mergedDocTypeTranslations) { if (translation.getSourcePublicID().matches(publicID) && translation.getSourceSystemID().matches(systemID)) { return translation; } } return null; } public Set getDocTypeResolutionEntries() { checkInitialized(); return this.mergedDocTypeResolutionEntries; } /** *

* Computes all the processors that should be applied to a specific {@link Node}. *

*

* Results are returned ordered by precedence. *

* * @param node the node to compute * @return an ArrayList with the list of processors, as {@link ProcessorAndContext} objects. */ public ArrayList computeProcessorsForNode(final Node node) { if (node instanceof NestableAttributeHolderNode) { final ArrayList processors = new ArrayList(2); final NestableAttributeHolderNode nestableNode = (NestableAttributeHolderNode) node; if (node instanceof Element) { final Element element = (Element) nestableNode; final Set processorsForElementName = this.mergedSpecificProcessorsByElementName.get(element.getNormalizedName()); if (processorsForElementName != null) { for (final ProcessorAndContext processorAndContext : processorsForElementName) { if (processorAndContext.matches(node)) { processors.add(processorAndContext); } } } } final String[] normalizedAttributeNames = nestableNode.unsafeGetAttributeNormalizedNames(); final int normalizedAttributesLen = nestableNode.numAttributes(); for (int i = 0; i < normalizedAttributesLen; i++) { final String normalizedAttributeName = normalizedAttributeNames[i]; final Set processorsForAttributeName = this.mergedSpecificProcessorsByAttributeName.get(normalizedAttributeName); if (processorsForAttributeName != null) { for (final ProcessorAndContext processorAndContext : processorsForAttributeName) { if (processorAndContext.matches(node)) { processors.add(processorAndContext); } } } } final Set applicableNonSpecificProcessors = getApplicableNonSpecificProcessorsToNodeClass(NestableAttributeHolderNode.class); if (applicableNonSpecificProcessors != null) { for (final ProcessorAndContext processorAndContext : applicableNonSpecificProcessors) { if (processorAndContext.matches(node)) { processors.add(processorAndContext); } } } if (processors.size() > 1) { // Order (usually by precedence) Collections.sort(processors); } return processors; } // // NODE IS NOT AN ELEMENT... // final Set applicableNonSpecificProcessors = getApplicableNonSpecificProcessorsToNodeClass(node.getClass()); if (applicableNonSpecificProcessors != null) { final ArrayList processors = new ArrayList(2); for (final ProcessorAndContext processorAndContext : applicableNonSpecificProcessors) { if (processorAndContext.matches(node)) { processors.add(processorAndContext); } } // Order (usually by precedence) Collections.sort(processors); return processors; } // No processors to be returned return null; } public Map getExecutionAttributes() { checkInitialized(); return this.mergedExecutionAttributes; } public Set getAllPrefixes() { checkInitialized(); return this.dialectsByPrefix.keySet(); } public boolean isPrefixManaged(final String prefix) { return this.dialectsByPrefix.containsKey(prefix); } private Set getApplicableNonSpecificProcessorsToNodeClass(final Class nodeClass) { Set result = null; for (final Map.Entry, Set> entry : this.mergedNonSpecificProcessorsByNodeClass.entrySet()) { final Class entryNodeClass = entry.getKey(); if (entryNodeClass.isAssignableFrom(nodeClass)) { if (result == null) { result = new HashSet(2); } result.addAll(entry.getValue()); } } return result; } private static MergedDialectArtifacts mergeDialects(final Set dialectConfigurations) { if (dialectConfigurations == null || dialectConfigurations.isEmpty()) { throw new ConfigurationException("No dialect has been specified"); } final Map> specificProcessorsByElementName = new HashMap>(20); final Map> specificProcessorsByAttributeName = new HashMap>(20); final Map, Set> nonSpecificProcessorsByNodeClass = new HashMap, Set>(20); final Map executionAttributes = new HashMap(20); final Set docTypeResolutionEntries = new HashSet(20); final Set docTypeTranslations = new HashSet(20); if (dialectConfigurations.size() == 1) { // No conflicts possible! final DialectConfiguration dialectConfiguration = dialectConfigurations.iterator().next(); final IDialect dialect = dialectConfiguration.getDialect(); specificProcessorsByElementName.putAll(dialectConfiguration.unsafeGetSpecificProcessorsByElementName()); specificProcessorsByAttributeName.putAll(dialectConfiguration.unsafeGetSpecificProcessorsByAttributeName()); nonSpecificProcessorsByNodeClass.putAll(dialectConfiguration.unsafeGetNonSpecificProcessorsByNodeClass()); executionAttributes.putAll(dialectConfiguration.getExecutionAttributes()); docTypeResolutionEntries.addAll(dialect.getDocTypeResolutionEntries()); docTypeTranslations.addAll(dialect.getDocTypeTranslations()); return new MergedDialectArtifacts( specificProcessorsByElementName, specificProcessorsByAttributeName, nonSpecificProcessorsByNodeClass, executionAttributes, dialect.getDocTypeResolutionEntries(), dialect.getDocTypeTranslations()); } /* * THERE ARE MORE THAN ONE DIALECT: MERGE THEM */ final Set> mergedDialectClasses = new HashSet>(5,1.0f); for (final DialectConfiguration dialectConfiguration : dialectConfigurations) { final IDialect dialect = dialectConfiguration.getDialect(); /* * Check the dialect is not being repeated */ if (mergedDialectClasses.contains(dialect.getClass())) { throw new ConfigurationException( "Dialect is declared twice: " + dialect.getClass().getName()); } /* * Aggregate all the processors assigned to a specific element name */ specificProcessorsByElementName.putAll(dialectConfiguration.unsafeGetSpecificProcessorsByElementName()); /* * Aggregate all the processors assigned to a specific attribute name */ specificProcessorsByAttributeName.putAll(dialectConfiguration.unsafeGetSpecificProcessorsByAttributeName()); /* * Aggregate all the processors not assigned to a specific attribute or element name */ nonSpecificProcessorsByNodeClass.putAll(dialectConfiguration.unsafeGetNonSpecificProcessorsByNodeClass()); /* * Merge execution attributes */ executionAttributes.putAll(dialectConfiguration.getExecutionAttributes()); /* * Check that two dialects do not specify conflicting DOCTYPE resolution entries * for the same PUBLIC and SYSTEM IDs. */ final Set dialectDocTypeResolutionEntries = dialect.getDocTypeResolutionEntries(); for (final IDocTypeResolutionEntry dialectDocTypeResolutionEntry : dialectDocTypeResolutionEntries) { boolean addDialectDocTypeResolutionEntry = true; final DocTypeIdentifier dialectDocTypeResolutionEntryPublicID = dialectDocTypeResolutionEntry.getPublicID(); final DocTypeIdentifier dialectDocTypeResolutionEntrySystemID = dialectDocTypeResolutionEntry.getSystemID(); for (final IDocTypeResolutionEntry docTypeResolutionEntry : docTypeResolutionEntries) { final DocTypeIdentifier docTypeResolutionEntryPublicID = docTypeResolutionEntry.getPublicID(); final DocTypeIdentifier docTypeResolutionEntrySystemID = docTypeResolutionEntry.getSystemID(); final boolean publicIDMatches; if (dialectDocTypeResolutionEntryPublicID == null) { publicIDMatches = (docTypeResolutionEntryPublicID == null); } else { publicIDMatches = (docTypeResolutionEntryPublicID != null && docTypeResolutionEntryPublicID.equals(dialectDocTypeResolutionEntryPublicID)); } final boolean systemIDMatches; if (dialectDocTypeResolutionEntrySystemID == null) { systemIDMatches = (docTypeResolutionEntrySystemID == null); } else { systemIDMatches = (docTypeResolutionEntrySystemID != null && docTypeResolutionEntrySystemID.equals(dialectDocTypeResolutionEntrySystemID)); } if (publicIDMatches && systemIDMatches) { if (!dialectDocTypeResolutionEntry.equals(docTypeResolutionEntry)) { throw new ConfigurationException( "Cannot initialize: two dialects provide different (non-equal) " + "DOCTYPE resolution entries for PUBLICID \"" + docTypeResolutionEntryPublicID + "\" and SYSTEMID \"" + docTypeResolutionEntrySystemID + "\""); } // No need to repeat an entry (even if it is a Set!) addDialectDocTypeResolutionEntry = false; } } if (addDialectDocTypeResolutionEntry) { docTypeResolutionEntries.add(dialectDocTypeResolutionEntry); } } /* * Check that two dialects do not specify conflicting DOCTYPE translations * for the same PUBLIC and SYSTEM IDs. */ final Set dialectDocTypeTranslations = dialect.getDocTypeTranslations(); for (final IDocTypeTranslation dialectDocTypeTranslation : dialectDocTypeTranslations) { boolean addDialectDocTypeTranslation = true; final DocTypeIdentifier dialectDocTypeTranslationSourcePublicID = dialectDocTypeTranslation.getSourcePublicID(); final DocTypeIdentifier dialectDocTypeTranslationSourceSystemID = dialectDocTypeTranslation.getSourceSystemID(); final DocTypeIdentifier dialectDocTypeTranslationTargetPublicID = dialectDocTypeTranslation.getTargetPublicID(); final DocTypeIdentifier dialectDocTypeTranslationTargetSystemID = dialectDocTypeTranslation.getTargetSystemID(); for (final IDocTypeTranslation docTypeTranslation : docTypeTranslations) { final DocTypeIdentifier docTypeTranslationSourcePublicID = docTypeTranslation.getSourcePublicID(); final DocTypeIdentifier docTypeTranslationSourceSystemID = docTypeTranslation.getSourceSystemID(); final DocTypeIdentifier docTypeTranslationTargetPublicID = docTypeTranslation.getTargetPublicID(); final DocTypeIdentifier docTypeTranslationTargetSystemID = docTypeTranslation.getTargetSystemID(); boolean sourcePublicIDMatches = false; boolean sourceSystemIDMatches = false; if (dialectDocTypeTranslationSourcePublicID == null) { sourcePublicIDMatches = (docTypeTranslationSourcePublicID == null); } else { sourcePublicIDMatches = (docTypeTranslationSourcePublicID != null && docTypeTranslationSourcePublicID.equals(dialectDocTypeTranslationSourcePublicID)); } if (dialectDocTypeTranslationSourceSystemID == null) { sourceSystemIDMatches = (docTypeTranslationSourceSystemID == null); } else { sourceSystemIDMatches = (docTypeTranslationSourceSystemID != null && docTypeTranslationSourceSystemID.equals(dialectDocTypeTranslationSourceSystemID)); } if (sourcePublicIDMatches && sourceSystemIDMatches) { final boolean targetPublicIDMatches; if (dialectDocTypeTranslationTargetPublicID == null) { targetPublicIDMatches = (docTypeTranslationTargetPublicID == null); } else { targetPublicIDMatches = (docTypeTranslationTargetPublicID != null && docTypeTranslationTargetPublicID.equals(dialectDocTypeTranslationTargetPublicID)); } final boolean targetSystemIDMatches; if (dialectDocTypeTranslationTargetSystemID == null) { targetSystemIDMatches = (docTypeTranslationTargetSystemID == null); } else { targetSystemIDMatches = (docTypeTranslationTargetSystemID != null && docTypeTranslationTargetSystemID.equals(dialectDocTypeTranslationTargetSystemID)); } if (!targetPublicIDMatches || !targetSystemIDMatches) { throw new ConfigurationException( "Cannot initialize: two dialects provide different (non-equal) " + "DOCTYPE translations for PUBLICID \"" + docTypeTranslationSourcePublicID + "\" and SYSTEMID \"" + docTypeTranslationSourceSystemID + "\""); } // No need to repeat a translation (even if it is a Set!) addDialectDocTypeTranslation = false; } } if (addDialectDocTypeTranslation) { docTypeTranslations.add(dialectDocTypeTranslation); } } mergedDialectClasses.add(dialect.getClass()); } return new MergedDialectArtifacts( specificProcessorsByElementName, specificProcessorsByAttributeName, nonSpecificProcessorsByNodeClass, executionAttributes, docTypeResolutionEntries, docTypeTranslations); } private static final class MergedDialectArtifacts { private final Map> specificProcessorsByElementName; private final Map> specificProcessorsByAttributeName; private final Map, Set> nonSpecificProcessorsByNodeClass; private final Map executionAttributes; private final Set docTypeResolutionEntries; private final Set docTypeTranslations; MergedDialectArtifacts( final Map> specificProcessorsByElementName, final Map> specificProcessorsByAttributeName, final Map,Set> nonSpecificProcessorsByNodeClass, final Map executionAttributes, final Set docTypeResolutionEntries, final Set docTypeTranslations) { super(); this.specificProcessorsByElementName = specificProcessorsByElementName; this.specificProcessorsByAttributeName = specificProcessorsByAttributeName; this.nonSpecificProcessorsByNodeClass = nonSpecificProcessorsByNodeClass; this.executionAttributes = executionAttributes; this.docTypeResolutionEntries = docTypeResolutionEntries; this.docTypeTranslations = docTypeTranslations; } public Map> getSpecificProcessorsByElementName() { return this.specificProcessorsByElementName; } public Map> getSpecificProcessorsByAttributeName() { return this.specificProcessorsByAttributeName; } public Map, Set> getMergedNonSpecificProcessorsByNodeClass() { return this.nonSpecificProcessorsByNodeClass; } public Map getExecutionAttributes() { return this.executionAttributes; } public Set getDocTypeResolutionEntries() { return this.docTypeResolutionEntries; } public Set getDocTypeTranslations() { return this.docTypeTranslations; } } private static class TemplateResolverComparator implements Comparator, Serializable { private static final long serialVersionUID = -4959505530260386645L; TemplateResolverComparator() { super(); } public int compare(final ITemplateResolver o1, final ITemplateResolver o2) { if (o1.getOrder() == null) { return -1; } if (o2.getOrder() == null) { return 1; } return o1.getOrder().compareTo(o2.getOrder()); } } private static class MessageResolverComparator implements Comparator, Serializable { private static final long serialVersionUID = 4700426328261944024L; MessageResolverComparator() { super(); } public int compare(final IMessageResolver o1, final IMessageResolver o2) { if (o1.getOrder() == null) { return -1; } if (o2.getOrder() == null) { return 1; } return o1.getOrder().compareTo(o2.getOrder()); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy