| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You 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 flex.messaging.config; |
| |
| import flex.messaging.validators.ClassDeserializationValidator; |
| import org.w3c.dom.Document; |
| import org.w3c.dom.Node; |
| import org.w3c.dom.NodeList; |
| |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Locale; |
| import java.util.StringTokenizer; |
| |
| import flex.messaging.config.ThrottleSettings.Policy; |
| import flex.messaging.util.LocaleUtils; |
| |
| /** |
| * Processes DOM representation of a messaging configuration file. |
| * <p> |
| * Note: Since reference ids are used between elements, certain |
| * sections of the document need to be parsed first. |
| * </p> |
| * |
| * |
| */ |
| public abstract class ServerConfigurationParser extends AbstractConfigurationParser |
| { |
| /** |
| * Used to verify that advanced messaging support has been registered if necessary. |
| * If other configuration requires it, but it was not registered a ConfigurationException is thrown. |
| */ |
| private boolean verifyAdvancedMessagingSupport = false; |
| private boolean advancedMessagingSupportRegistered = false; |
| |
| @Override |
| protected void parseTopLevelConfig(Document doc) |
| { |
| Node root = selectSingleNode(doc, "/" + SERVICES_CONFIG_ELEMENT); |
| |
| if (root != null) |
| { |
| allowedChildElements(root, SERVICES_CONFIG_CHILDREN); |
| |
| securitySection(root); // Parse security before channels. |
| |
| serversSection(root); |
| |
| channelsSection(root); |
| |
| services(root); |
| |
| clusters(root); |
| |
| logging(root); |
| |
| system(root); |
| |
| flexClient(root); |
| |
| factories(root); |
| |
| messageFilters(root); |
| |
| validators(root); |
| |
| // Validate that any dependencies on advanced messaging support can be satisified at runtime. |
| if (verifyAdvancedMessagingSupport && !advancedMessagingSupportRegistered) |
| { |
| ConfigurationException e = new ConfigurationException(); |
| e.setMessage(REQUIRE_ADVANCED_MESSAGING_SUPPORT); |
| throw e; |
| } |
| } |
| else |
| { |
| // The services configuration root element must be '{SERVICES_CONFIG_ELEMENT}'. |
| ConfigurationException e = new ConfigurationException(); |
| e.setMessage(INVALID_SERVICES_ROOT, new Object[]{SERVICES_CONFIG_ELEMENT}); |
| throw e; |
| } |
| } |
| |
| private void clusters(Node root) |
| { |
| Node clusteringNode = selectSingleNode(root, CLUSTERS_ELEMENT); |
| if (clusteringNode != null) |
| { |
| allowedAttributesOrElements(clusteringNode, CLUSTERING_CHILDREN); |
| |
| NodeList clusters = selectNodeList(clusteringNode, CLUSTER_DEFINITION_ELEMENT); |
| for (int i = 0; i < clusters.getLength(); i++) |
| { |
| Node cluster = clusters.item(i); |
| requiredAttributesOrElements(cluster, CLUSTER_DEFINITION_CHILDREN); |
| String clusterName = getAttributeOrChildElement(cluster, ID_ATTR); |
| if (!isValidID(clusterName)) |
| continue; |
| |
| String propsFileName = getAttributeOrChildElement(cluster, CLUSTER_PROPERTIES_ATTR); |
| ClusterSettings clusterSettings = new ClusterSettings(); |
| clusterSettings.setClusterName(clusterName); |
| clusterSettings.setPropsFileName(propsFileName); |
| String className = getAttributeOrChildElement(cluster, CLASS_ATTR); |
| if (className != null && className.length() > 0) |
| clusterSettings.setImplementationClass(className); |
| |
| String defaultValue = getAttributeOrChildElement(cluster, ClusterSettings.DEFAULT_ELEMENT); |
| if (defaultValue != null && defaultValue.length() > 0) |
| { |
| if (defaultValue.equalsIgnoreCase(TRUE_STRING)) |
| clusterSettings.setDefault(true); |
| else if (!defaultValue.equalsIgnoreCase(FALSE_STRING)) |
| { |
| ConfigurationException e = new ConfigurationException(); |
| e.setMessage(10215, new Object[] {clusterName, defaultValue}); |
| throw e; |
| } |
| } |
| String ulb = getAttributeOrChildElement(cluster, ClusterSettings.URL_LOAD_BALANCING); |
| if (ulb != null && ulb.length() > 0) |
| { |
| if (ulb.equalsIgnoreCase(FALSE_STRING)) |
| { |
| clusterSettings.setURLLoadBalancing(false); |
| } |
| else if (!ulb.equalsIgnoreCase(TRUE_STRING)) |
| { |
| ConfigurationException e = new ConfigurationException(); |
| e.setMessage(10216, new Object[] {clusterName, ulb}); |
| throw e; |
| } |
| } |
| |
| NodeList properties = selectNodeList(cluster, PROPERTIES_ELEMENT + "/*"); |
| if (properties.getLength() > 0) |
| { |
| ConfigMap map = properties(properties, getSourceFileOf(cluster)); |
| clusterSettings.addProperties(map); |
| } |
| |
| ((MessagingConfiguration)config).addClusterSettings(clusterSettings); |
| |
| } |
| } |
| } |
| |
| |
| private void securitySection(Node root) |
| { |
| Node security = selectSingleNode(root, SECURITY_ELEMENT); |
| |
| if (security == null) |
| return; |
| |
| allowedChildElements(security, SECURITY_CHILDREN); |
| |
| NodeList list = selectNodeList(security, SECURITY_CONSTRAINT_DEFINITION_ELEMENT); |
| for (int i = 0; i < list.getLength(); i++) |
| { |
| Node constraint = list.item(i); |
| securityConstraint(constraint, false); |
| } |
| |
| list = selectNodeList(security, CONSTRAINT_INCLUDE_ELEMENT); |
| for (int i = 0; i < list.getLength(); i++) |
| { |
| Node include = list.item(i); |
| securityConstraintInclude(include); |
| } |
| |
| list = selectNodeList(security, LOGIN_COMMAND_ELEMENT); |
| for (int i = 0; i < list.getLength(); i++) |
| { |
| Node login = list.item(i); |
| LoginCommandSettings loginCommandSettings= new LoginCommandSettings(); |
| requiredAttributesOrElements(login, LOGIN_COMMAND_REQ_CHILDREN); |
| allowedAttributesOrElements(login, LOGIN_COMMAND_CHILDREN); |
| |
| String server = getAttributeOrChildElement(login, SERVER_ATTR); |
| if (server.length() == 0) |
| { |
| // Attribute '{SERVER_ATTR}' must be specified for element '{LOGIN_COMMAND_ELEMENT}' |
| ConfigurationException e = new ConfigurationException(); |
| e.setMessage(MISSING_ATTRIBUTE, new Object[]{SERVER_ATTR, LOGIN_COMMAND_ELEMENT}); |
| throw e; |
| } |
| loginCommandSettings.setServer(server); |
| |
| String loginClass = getAttributeOrChildElement(login, CLASS_ATTR); |
| if (loginClass.length() == 0) |
| { |
| // Attribute '{CLASS_ATTR}' must be specified for element '{LOGIN_COMMAND_ELEMENT}' |
| ConfigurationException e = new ConfigurationException(); |
| e.setMessage(MISSING_ATTRIBUTE, new Object[]{CLASS_ATTR, LOGIN_COMMAND_ELEMENT}); |
| throw e; |
| } |
| loginCommandSettings.setClassName(loginClass); |
| |
| boolean isPerClientAuth = Boolean.valueOf(getAttributeOrChildElement(login, PER_CLIENT_AUTH)); |
| loginCommandSettings.setPerClientAuthentication(isPerClientAuth); |
| |
| ((MessagingConfiguration)config).getSecuritySettings().addLoginCommandSettings(loginCommandSettings); |
| } |
| |
| boolean recreateHttpSessionAfterLogin = Boolean.valueOf(getAttributeOrChildElement(security, RECREATE_HTTPSESSION_AFTER_LOGIN_ELEMENT)); |
| ((MessagingConfiguration)config).getSecuritySettings().setRecreateHttpSessionAfterLogin(recreateHttpSessionAfterLogin); |
| } |
| |
| private SecurityConstraint securityConstraint(Node constraint, boolean inline) |
| { |
| SecurityConstraint sc; |
| |
| // Validation |
| allowedAttributesOrElements(constraint, SECURITY_CONSTRAINT_DEFINITION_CHILDREN); |
| |
| // Constraint by reference |
| String ref = getAttributeOrChildElement(constraint, REF_ATTR); |
| if (ref.length() > 0) |
| { |
| allowedAttributesOrElements(constraint, new String[] {REF_ATTR}); |
| |
| sc = ((MessagingConfiguration)config).getSecuritySettings().getConstraint(ref); |
| if (sc == null) |
| { |
| // {SECURITY_CONSTRAINT_DEFINITION_ELEMENT} not found for reference '{ref}'. |
| ConfigurationException e = new ConfigurationException(); |
| e.setMessage(REF_NOT_FOUND, new Object[]{SECURITY_CONSTRAINT_DEFINITION_ELEMENT, ref}); |
| throw e; |
| } |
| } |
| else |
| { |
| // New security constraint |
| String id = getAttributeOrChildElement(constraint, ID_ATTR); |
| |
| // If not inline, we must have a valid id to register the constraint! |
| if (inline) |
| { |
| sc = new SecurityConstraint(""); |
| } |
| else if (isValidID(id)) |
| { |
| sc = new SecurityConstraint(id); |
| ((MessagingConfiguration)config).getSecuritySettings().addConstraint(sc); |
| } |
| else |
| { |
| //Invalid {SECURITY_CONSTRAINT_DEFINITION_ELEMENT} id '{id}'. |
| ConfigurationException ex = new ConfigurationException(); |
| ex.setMessage(INVALID_ID, new Object[]{SECURITY_CONSTRAINT_DEFINITION_ELEMENT, id}); |
| ex.setDetails(INVALID_ID); |
| throw ex; |
| } |
| |
| // Authentication Method |
| String method = getAttributeOrChildElement(constraint, AUTH_METHOD_ELEMENT); |
| sc.setMethod(method); |
| |
| // Roles |
| Node rolesNode = selectSingleNode(constraint, ROLES_ELEMENT); |
| if (rolesNode != null) |
| { |
| allowedChildElements(rolesNode, ROLES_CHILDREN); |
| NodeList roles = selectNodeList(rolesNode, ROLE_ELEMENT); |
| for (int r = 0; r < roles.getLength(); r++) |
| { |
| Node roleNode = roles.item(r); |
| String role = evaluateExpression(roleNode, ".").toString().trim(); |
| if (role.length() > 0) |
| { |
| sc.addRole(role); |
| } |
| } |
| } |
| } |
| |
| return sc; |
| } |
| |
| private void securityConstraintInclude(Node constraintInclude) |
| { |
| // Validation |
| allowedAttributesOrElements(constraintInclude, CONSTRAINT_INCLUDE_CHILDREN); |
| |
| String src = getAttributeOrChildElement(constraintInclude, SRC_ATTR); |
| String dir = getAttributeOrChildElement(constraintInclude, DIRECTORY_ATTR); |
| if (src.length() > 0) |
| { |
| constraintIncludeFile(src); |
| } |
| else if (dir.length() > 0) |
| { |
| constraintIncludeDirectory(dir); |
| } |
| else |
| { |
| // The include element ''{0}'' must specify either the ''{1}'' or ''{2}'' attribute. |
| ConfigurationException ex = new ConfigurationException(); |
| ex.setMessage(MISSING_INCLUDE_ATTRIBUTES, new Object[]{constraintInclude.getNodeName(), SRC_ATTR, DIRECTORY_ATTR}); |
| throw ex; |
| } |
| } |
| |
| private void constraintIncludeFile(String src) |
| { |
| Document doc = loadDocument(src, fileResolver.getIncludedFile(src)); |
| doc.getDocumentElement().normalize(); |
| |
| // Check for <security-constraints> wrapping more than one definition |
| Node servicesNode = selectSingleNode(doc, SECURITY_CONSTRAINTS_ELEMENT); |
| if (servicesNode != null) |
| { |
| allowedChildElements(servicesNode, SECURITY_CONSTRAINTS_CHILDREN); |
| NodeList constraints = selectNodeList(servicesNode, SECURITY_CONSTRAINT_ELEMENT); |
| for (int a = 0; a < constraints.getLength(); a++) |
| { |
| Node constraint = constraints.item(a); |
| securityConstraint(constraint, false); |
| } |
| fileResolver.popIncludedFile(); |
| } |
| else // Check for single <security-constraint> |
| { |
| Node constraint = selectSingleNode(doc, "/" + SECURITY_CONSTRAINT_ELEMENT); |
| if (constraint != null) |
| { |
| securityConstraint(constraint, false); |
| fileResolver.popIncludedFile(); |
| } |
| else |
| { |
| // The {0} root element in file {1} must be ''{2}'' or ''{3}''. |
| ConfigurationException ex = new ConfigurationException(); |
| ex.setMessage(INVALID_INCLUDE_ROOT, new Object[]{CONSTRAINT_INCLUDE_ELEMENT, src, SECURITY_CONSTRAINTS_ELEMENT, SECURITY_CONSTRAINT_ELEMENT}); |
| throw ex; |
| } |
| } |
| } |
| |
| private void constraintIncludeDirectory(String dir) |
| { |
| List files = fileResolver.getFiles(dir); |
| for (int i = 0; i < files.size(); i++) |
| { |
| String src = (String) files.get(i); |
| constraintIncludeFile(src); |
| } |
| } |
| |
| private void serversSection(Node root) |
| { |
| // Only MessagingConfiguration supports the servers element configuration. |
| // The general ServicesConfiguration interface does not. |
| if (!(config instanceof MessagingConfiguration)) |
| return; |
| |
| Node serversNode = selectSingleNode(root, SERVERS_ELEMENT); |
| if (serversNode != null) |
| { |
| // Validation |
| allowedAttributesOrElements(serversNode, SERVERS_CHILDREN); |
| |
| NodeList servers = selectNodeList(serversNode, SERVER_ELEMENT); |
| for (int i = 0; i < servers.getLength(); i++) |
| { |
| Node server = servers.item(i); |
| serverDefinition(server); |
| } |
| } |
| } |
| |
| private void serverDefinition(Node server) |
| { |
| // Validation |
| requiredAttributesOrElements(server, SERVER_REQ_CHILDREN); |
| allowedAttributesOrElements(server, SERVER_CHILDREN); |
| |
| String id = getAttributeOrChildElement(server, ID_ATTR); |
| if (isValidID(id)) |
| { |
| SharedServerSettings settings = new SharedServerSettings(); |
| settings.setId(id); |
| settings.setSourceFile(getSourceFileOf(server)); |
| String className = getAttributeOrChildElement(server, CLASS_ATTR); |
| if (className.length() > 0) |
| { |
| settings.setClassName(className); |
| // Custom server properties. |
| NodeList properties = selectNodeList(server, PROPERTIES_ELEMENT + "/*"); |
| if (properties.getLength() > 0) |
| { |
| ConfigMap map = properties(properties, getSourceFileOf(server)); |
| settings.addProperties(map); |
| } |
| ((MessagingConfiguration)config).addSharedServerSettings(settings); |
| } |
| else |
| { |
| // Class not specified for {MESSAGE_FILTER_ELEMENT} '{id}'. |
| ConfigurationException ex = new ConfigurationException(); |
| ex.setMessage(CLASS_NOT_SPECIFIED, new Object[]{SERVER_ELEMENT, id}); |
| throw ex; |
| } |
| } |
| } |
| |
| private void channelsSection(Node root) |
| { |
| Node channelsNode = selectSingleNode(root, CHANNELS_ELEMENT); |
| if (channelsNode != null) |
| { |
| // Validation |
| allowedAttributesOrElements(channelsNode, CHANNELS_CHILDREN); |
| |
| NodeList channels = selectNodeList(channelsNode, CHANNEL_DEFINITION_ELEMENT); |
| for (int i = 0; i < channels.getLength(); i++) |
| { |
| Node channel = channels.item(i); |
| channelDefinition(channel); |
| } |
| |
| NodeList includes = selectNodeList(channelsNode, CHANNEL_INCLUDE_ELEMENT); |
| for (int i = 0; i < includes.getLength(); i++) |
| { |
| Node include = includes.item(i); |
| channelInclude(include); |
| } |
| } |
| } |
| |
| private void channelDefinition(Node channel) |
| { |
| // Validation |
| requiredAttributesOrElements(channel, CHANNEL_DEFINITION_REQ_CHILDREN); |
| allowedAttributesOrElements(channel, CHANNEL_DEFINITION_CHILDREN); |
| |
| String id = getAttributeOrChildElement(channel, ID_ATTR); |
| if (isValidID(id)) |
| { |
| // Don't allow multiple channels with the same id |
| if (config.getChannelSettings(id) != null) |
| { |
| // Cannot have multiple channels with the same id ''{0}''. |
| ConfigurationException e = new ConfigurationException(); |
| e.setMessage(DUPLICATE_CHANNEL_ERROR, new Object[]{id}); |
| throw e; |
| } |
| |
| ChannelSettings channelSettings = new ChannelSettings(id); |
| channelSettings.setSourceFile(getSourceFileOf(channel)); |
| |
| // Note whether the channel-definition was for a remote endpoint |
| String remote = getAttributeOrChildElement(channel, REMOTE_ATTR); |
| channelSettings.setRemote(Boolean.valueOf(remote)); |
| |
| // Endpoint |
| Node endpoint = selectSingleNode(channel, ENDPOINT_ELEMENT); |
| if (endpoint != null) |
| { |
| // Endpoint Validation |
| allowedAttributesOrElements(endpoint, ENDPOINT_CHILDREN); |
| |
| String type = getAttributeOrChildElement(endpoint, CLASS_ATTR); |
| channelSettings.setEndpointType(type); |
| |
| // The url attribute may also be specified by the deprecated uri attribute |
| String uri = getAttributeOrChildElement(endpoint, URL_ATTR); |
| if (uri == null || EMPTY_STRING.equals(uri)) |
| uri = getAttributeOrChildElement(endpoint, URI_ATTR); |
| channelSettings.setUri(uri); |
| |
| config.addChannelSettings(id, channelSettings); |
| } |
| |
| channelServerOnlyAttribute(channel, channelSettings); |
| |
| // Server reference |
| Node server = selectSingleNode(channel, SERVER_ELEMENT); |
| if (server != null) |
| { |
| requiredAttributesOrElements(server, CHANNEL_DEFINITION_SERVER_REQ_CHILDREN); |
| |
| String serverId = getAttributeOrChildElement(server, REF_ATTR); |
| channelSettings.setServerId(serverId); |
| } |
| |
| // Channel Properties |
| NodeList properties = selectNodeList(channel, PROPERTIES_ELEMENT + "/*"); |
| if (properties.getLength() > 0) |
| { |
| ConfigMap map = properties(properties, getSourceFileOf(channel)); |
| channelSettings.addProperties(map); |
| |
| // Sniff for adaptive-frequency under flex-client-queue-processor hich requires advanced messaging support. |
| if (!verifyAdvancedMessagingSupport) |
| { |
| ConfigMap outboundQueueProcessor = map.getPropertyAsMap(FLEX_CLIENT_OUTBOUND_QUEUE_PROCESSOR_ELEMENT, null); |
| if (outboundQueueProcessor != null) |
| { |
| // Flex client queue processor properties |
| ConfigMap queueProcessorProperties = outboundQueueProcessor.getPropertyAsMap(PROPERTIES_ELEMENT, null); |
| if (queueProcessorProperties != null) |
| { |
| // Sniff for adaptive-frequency which requires advanced messaging support. |
| boolean adaptiveFrequency = queueProcessorProperties.getPropertyAsBoolean(ADAPTIVE_FREQUENCY, false); |
| if (adaptiveFrequency) |
| verifyAdvancedMessagingSupport = true; |
| } |
| } |
| } |
| } |
| |
| // Channel Security |
| |
| // Security-constraint short-cut attribute |
| String ref = evaluateExpression(channel, "@" + SECURITY_CONSTRAINT_ATTR).toString().trim(); |
| if (ref.length() > 0) |
| { |
| SecurityConstraint sc = ((MessagingConfiguration)config).getSecuritySettings().getConstraint(ref); |
| if (sc != null) |
| { |
| channelSettings.setConstraint(sc); |
| } |
| else |
| { |
| // {SECURITY_CONSTRAINT_ELEMENT} not found for reference '{ref}' in channel '{id}'. |
| ConfigurationException ex = new ConfigurationException(); |
| ex.setMessage(REF_NOT_FOUND_IN_CHANNEL, new Object[]{SECURITY_CONSTRAINT_ATTR, ref, id}); |
| throw ex; |
| } |
| } |
| else |
| { |
| // Inline security element |
| Node security = selectSingleNode(channel, SECURITY_ELEMENT); |
| if (security != null) |
| { |
| allowedChildElements(security, EMBEDDED_SECURITY_CHILDREN); |
| Node constraint = selectSingleNode(security, SECURITY_CONSTRAINT_ELEMENT); |
| if (constraint != null) |
| { |
| SecurityConstraint sc = securityConstraint(constraint, true); |
| channelSettings.setConstraint(sc); |
| } |
| } |
| } |
| } |
| else |
| { |
| // Invalid {CHANNEL_DEFINITION_ELEMENT} id '{id}'. |
| ConfigurationException ex = new ConfigurationException(); |
| ex.setMessage(INVALID_ID, new Object[]{CHANNEL_DEFINITION_ELEMENT, id}); |
| ex.setDetails(INVALID_ID); |
| throw ex; |
| } |
| } |
| |
| private void channelServerOnlyAttribute(Node channel, ChannelSettings channelSettings) |
| { |
| String clientType = getAttributeOrChildElement(channel, CLASS_ATTR); |
| clientType = clientType.length() > 0? clientType : null; |
| |
| String serverOnlyString = getAttributeOrChildElement(channel, SERVER_ONLY_ATTR); |
| boolean serverOnly = serverOnlyString.length() > 0? Boolean.valueOf(serverOnlyString) : false; |
| |
| if (clientType == null && !serverOnly) // None set. |
| { |
| String url = channelSettings.getUri(); |
| boolean serverOnlyProtocol = (url.startsWith("samfsocket") || url.startsWith("amfsocket") || url.startsWith("ws")); |
| if (!serverOnlyProtocol) |
| { |
| // Endpoint ''{0}'' needs to have either class or server-only attribute defined. |
| ConfigurationException ce = new ConfigurationException(); |
| ce.setMessage(CLASS_OR_SERVER_ONLY_ERROR, new Object[]{channelSettings.getId()}); |
| throw ce; |
| } |
| channelSettings.setServerOnly(true); |
| } |
| else if (clientType != null && serverOnly) // Both set. |
| { |
| // Endpoint ''{0}'' cannot have both class and server-only attribute defined. |
| ConfigurationException ce = new ConfigurationException(); |
| ce.setMessage(CLASS_AND_SERVER_ONLY_ERROR, new Object[]{channelSettings.getId()}); |
| throw ce; |
| } |
| else // One of them set. |
| { |
| if (serverOnly) |
| channelSettings.setServerOnly(true); |
| else |
| channelSettings.setClientType(clientType); |
| } |
| } |
| |
| private void channelInclude(Node channelInclude) |
| { |
| // Validation |
| allowedAttributesOrElements(channelInclude, CHANNEL_INCLUDE_CHILDREN); |
| |
| String src = getAttributeOrChildElement(channelInclude, SRC_ATTR); |
| String dir = getAttributeOrChildElement(channelInclude, DIRECTORY_ATTR); |
| if (src.length() > 0) |
| { |
| channelIncludeFile(src); |
| } |
| else if (dir.length() > 0) |
| { |
| channelIncludeDirectory(dir); |
| } |
| else |
| { |
| // The include element ''{0}'' must specify either the ''{1}'' or ''{2}'' attribute. |
| ConfigurationException ex = new ConfigurationException(); |
| ex.setMessage(MISSING_INCLUDE_ATTRIBUTES, new Object[]{channelInclude.getNodeName(), SRC_ATTR, DIRECTORY_ATTR}); |
| throw ex; |
| } |
| } |
| |
| private void channelIncludeFile(String src) |
| { |
| Document doc = loadDocument(src, fileResolver.getIncludedFile(src)); |
| doc.getDocumentElement().normalize(); |
| |
| // Check for multiple channels in a single file. |
| Node channelsNode = selectSingleNode(doc, CHANNELS_ELEMENT); |
| if (channelsNode != null) |
| { |
| allowedChildElements(channelsNode, CHANNELS_CHILDREN); |
| NodeList channels = selectNodeList(channelsNode, CHANNEL_DEFINITION_ELEMENT); |
| for (int a = 0; a < channels.getLength(); a++) |
| { |
| Node service = channels.item(a); |
| channelDefinition(service); |
| } |
| fileResolver.popIncludedFile(); |
| } |
| else // Check for single channel in the file. |
| { |
| Node channel = selectSingleNode(doc, "/" + CHANNEL_DEFINITION_ELEMENT); |
| if (channel != null) |
| { |
| channelDefinition(channel); |
| fileResolver.popIncludedFile(); |
| } |
| else |
| { |
| // The {0} root element in file {1} must be '{CHANNELS_ELEMENT}' or '{CHANNEL_ELEMENT}'. |
| ConfigurationException ex = new ConfigurationException(); |
| ex.setMessage(INVALID_INCLUDE_ROOT, new Object[]{CHANNEL_INCLUDE_ELEMENT, src, CHANNELS_ELEMENT, CHANNEL_DEFINITION_ELEMENT}); |
| throw ex; |
| } |
| } |
| } |
| |
| private void channelIncludeDirectory(String dir) |
| { |
| List files = fileResolver.getFiles(dir); |
| for (int i = 0; i < files.size(); i++) |
| { |
| String src = (String) files.get(i); |
| channelIncludeFile(src); |
| } |
| } |
| |
| private void services(Node root) |
| { |
| Node servicesNode = selectSingleNode(root, SERVICES_ELEMENT); |
| if (servicesNode != null) |
| { |
| // Validation |
| allowedChildElements(servicesNode, SERVICES_CHILDREN); |
| |
| // Default Channels for the application |
| Node defaultChannels = selectSingleNode(servicesNode, DEFAULT_CHANNELS_ELEMENT); |
| if (defaultChannels != null) |
| { |
| allowedChildElements(defaultChannels, DEFAULT_CHANNELS_CHILDREN); |
| NodeList channels = selectNodeList(defaultChannels, CHANNEL_ELEMENT); |
| for (int c = 0; c < channels.getLength(); c++) |
| { |
| Node chan = channels.item(c); |
| allowedAttributes(chan, new String[] {REF_ATTR}); |
| defaultChannel(chan); |
| } |
| } |
| |
| // Service Includes |
| NodeList services = selectNodeList(servicesNode, SERVICE_INCLUDE_ELEMENT); |
| for (int i = 0; i < services.getLength(); i++) |
| { |
| Node service = services.item(i); |
| serviceInclude(service); |
| } |
| |
| // Service |
| services = selectNodeList(servicesNode, SERVICE_ELEMENT); |
| for (int i = 0; i < services.getLength(); i++) |
| { |
| Node service = services.item(i); |
| service(service); |
| } |
| } |
| } |
| |
| private void serviceInclude(Node serviceInclude) |
| { |
| // Validation |
| allowedAttributesOrElements(serviceInclude, SERVICE_INCLUDE_CHILDREN); |
| |
| String src = getAttributeOrChildElement(serviceInclude, SRC_ATTR); |
| String dir = getAttributeOrChildElement(serviceInclude, DIRECTORY_ATTR); |
| if (src.length() > 0) |
| { |
| serviceIncludeFile(src); |
| } |
| else if (dir.length() > 0) |
| { |
| serviceIncludeDirectory(dir); |
| } |
| else |
| { |
| // The include element ''{0}'' must specify either the ''{1}'' or ''{2}'' attribute. |
| ConfigurationException ex = new ConfigurationException(); |
| ex.setMessage(MISSING_INCLUDE_ATTRIBUTES, new Object[]{serviceInclude.getNodeName(), SRC_ATTR, DIRECTORY_ATTR}); |
| throw ex; |
| } |
| } |
| |
| private void serviceIncludeFile(String src) |
| { |
| Document doc = loadDocument(src, fileResolver.getIncludedFile(src)); |
| doc.getDocumentElement().normalize(); |
| |
| // Check for multiple services defined in a <services> tag |
| Node servicesNode = selectSingleNode(doc, SERVICES_ELEMENT); |
| if (servicesNode != null) |
| { |
| allowedChildElements(servicesNode, SERVICES_CHILDREN); |
| NodeList services = selectNodeList(servicesNode, SERVICE_ELEMENT); |
| for (int a = 0; a < services.getLength(); a++) |
| { |
| Node service = services.item(a); |
| service(service); |
| } |
| fileResolver.popIncludedFile(); |
| } |
| else // Check for single <service> definition. |
| { |
| Node service = selectSingleNode(doc, "/" + SERVICE_ELEMENT); |
| if (service != null) |
| { |
| service(service); |
| fileResolver.popIncludedFile(); |
| } |
| else |
| { |
| // The {0} root element in file {1} must be ''{2}'' or ''{3}''. |
| ConfigurationException ex = new ConfigurationException(); |
| ex.setMessage(INVALID_INCLUDE_ROOT, new Object[]{SERVICE_INCLUDE_ELEMENT, src, SERVICES_ELEMENT, SERVICE_ELEMENT}); |
| throw ex; |
| } |
| } |
| } |
| |
| private void serviceIncludeDirectory(String dir) |
| { |
| List files = fileResolver.getFiles(dir); |
| for (int i = 0; i < files.size(); i++) |
| { |
| String src = (String) files.get(i); |
| serviceIncludeFile(src); |
| } |
| } |
| |
| private void service(Node service) |
| { |
| // Validation |
| requiredAttributesOrElements(service, SERVICE_REQ_CHILDREN); |
| allowedAttributesOrElements(service, SERVICE_CHILDREN); |
| |
| String id = getAttributeOrChildElement(service, ID_ATTR); |
| if (isValidID(id)) |
| { |
| ServiceSettings serviceSettings = config.getServiceSettings(id); |
| if (serviceSettings == null) |
| { |
| serviceSettings = new ServiceSettings(id); |
| serviceSettings.setSourceFile(getSourceFileOf(service)); |
| config.addServiceSettings(serviceSettings); |
| } |
| else |
| { |
| // Duplicate service definition '{0}'. |
| ConfigurationException e = new ConfigurationException(); |
| e.setMessage(DUPLICATE_SERVICE_ERROR, new Object[]{id}); |
| throw e; |
| } |
| |
| // Service Class Name |
| String className = getAttributeOrChildElement(service, CLASS_ATTR); |
| if (className.length() > 0) |
| { |
| serviceSettings.setClassName(className); |
| |
| // Sniff for AdvancedMessagingSupport. |
| if (className.equals("flex.messaging.services.AdvancedMessagingSupport")) |
| advancedMessagingSupportRegistered = true; |
| } |
| else |
| { |
| // Class not specified for {SERVICE_ELEMENT} '{id}'. |
| ConfigurationException ex = new ConfigurationException(); |
| ex.setMessage(CLASS_NOT_SPECIFIED, new Object[]{SERVICE_ELEMENT, id}); |
| throw ex; |
| } |
| |
| // Service Message Types - deprecated |
| |
| // Service Properties |
| NodeList properties = selectNodeList(service, PROPERTIES_ELEMENT + "/*"); |
| if (properties.getLength() > 0) |
| { |
| ConfigMap map = properties(properties, getSourceFileOf(service)); |
| serviceSettings.addProperties(map); |
| } |
| |
| // Default Channels |
| Node defaultChannels = selectSingleNode(service, DEFAULT_CHANNELS_ELEMENT); |
| if (defaultChannels != null) |
| { |
| allowedChildElements(defaultChannels, DEFAULT_CHANNELS_CHILDREN); |
| NodeList channels = selectNodeList(defaultChannels, CHANNEL_ELEMENT); |
| for (int c = 0; c < channels.getLength(); c++) |
| { |
| Node chan = channels.item(c); |
| allowedAttributes(chan, new String[] {REF_ATTR}); |
| defaultChannel(chan, serviceSettings); |
| } |
| } |
| // Fall back on application's default channels |
| else if (config.getDefaultChannels().size() > 0) |
| { |
| for (Iterator iter = config.getDefaultChannels().iterator(); iter.hasNext();) |
| { |
| String channelId = (String)iter.next(); |
| ChannelSettings channel = config.getChannelSettings(channelId); |
| serviceSettings.addDefaultChannel(channel); |
| } |
| } |
| |
| // Default Security Constraint |
| Node defaultSecurityConstraint = selectSingleNode(service, DEFAULT_SECURITY_CONSTRAINT_ELEMENT); |
| if (defaultSecurityConstraint != null) |
| { |
| // Validation |
| requiredAttributesOrElements(defaultSecurityConstraint, new String[] {REF_ATTR}); |
| allowedAttributesOrElements(defaultSecurityConstraint, new String[] {REF_ATTR}); |
| |
| String ref = getAttributeOrChildElement(defaultSecurityConstraint, REF_ATTR); |
| if (ref.length() > 0) |
| { |
| SecurityConstraint sc = ((MessagingConfiguration)config).getSecuritySettings().getConstraint(ref); |
| if (sc == null) |
| { |
| // {SECURITY_CONSTRAINT_DEFINITION_ELEMENT} not found for reference '{ref}'. |
| ConfigurationException e = new ConfigurationException(); |
| e.setMessage(REF_NOT_FOUND, new Object[]{SECURITY_CONSTRAINT_DEFINITION_ELEMENT, ref}); |
| throw e; |
| } |
| serviceSettings.setConstraint(sc); |
| } |
| else |
| { |
| //Invalid default-security-constraint reference ''{0}'' in service ''{1}''. |
| ConfigurationException ex = new ConfigurationException(); |
| ex.setMessage(INVALID_SECURITY_CONSTRAINT_REF, new Object[]{ref, id}); |
| throw ex; |
| } |
| } |
| |
| // Adapter Definitions |
| Node adapters = selectSingleNode(service, ADAPTERS_ELEMENT); |
| if (adapters != null) |
| { |
| allowedChildElements(adapters, ADAPTERS_CHILDREN); |
| NodeList serverAdapters = selectNodeList(adapters, ADAPTER_DEFINITION_ELEMENT); |
| for (int a = 0; a < serverAdapters.getLength(); a++) |
| { |
| Node adapter = serverAdapters.item(a); |
| adapterDefinition(adapter, serviceSettings); |
| } |
| NodeList adapterIncludes = selectNodeList(adapters, ADAPTER_INCLUDE_ELEMENT); |
| for (int a = 0; a < adapterIncludes.getLength(); a++) |
| { |
| Node include = adapterIncludes.item(a); |
| adapterInclude(include, serviceSettings); |
| } |
| } |
| |
| // Destinations |
| NodeList list = selectNodeList(service, DESTINATION_ELEMENT); |
| for (int i = 0; i < list.getLength(); i++) |
| { |
| Node dest = list.item(i); |
| destination(dest, serviceSettings); |
| } |
| |
| // Destination Includes |
| list = selectNodeList(service, DESTINATION_INCLUDE_ELEMENT); |
| for (int i = 0; i < list.getLength(); i++) |
| { |
| Node dest = list.item(i); |
| destinationInclude(dest, serviceSettings); |
| } |
| } |
| else |
| { |
| //Invalid {SERVICE_ELEMENT} id '{id}'. |
| ConfigurationException ex = new ConfigurationException(); |
| ex.setMessage(INVALID_ID, new Object[]{SERVICE_ELEMENT, id}); |
| throw ex; |
| } |
| } |
| |
| /** |
| * A Flex application can declare default channels for its services. If a |
| * service specifies its own list of channels it overrides these defaults. |
| * <p> |
| * <default-channels><br/> |
| * <channel ref="channel-id"/><br/> |
| * <default-channels> |
| * </p> |
| * @param chan the channel node |
| */ |
| private void defaultChannel(Node chan) |
| { |
| String ref = getAttributeOrChildElement(chan, REF_ATTR); |
| |
| if (ref.length() > 0) |
| { |
| ChannelSettings channel = config.getChannelSettings(ref); |
| if (channel != null) |
| { |
| config.addDefaultChannel(channel.getId()); |
| } |
| else |
| { |
| // {0} not found for reference '{1}' |
| ConfigurationException e = new ConfigurationException(); |
| e.setMessage(REF_NOT_FOUND, new Object[]{CHANNEL_ELEMENT, ref}); |
| throw e; |
| } |
| } |
| else |
| { |
| //A default channel was specified without a reference for service '{0}'. |
| ConfigurationException ex = new ConfigurationException(); |
| ex.setMessage(INVALID_DEFAULT_CHANNEL, new Object[]{"MessageBroker"}); |
| throw ex; |
| } |
| } |
| |
| /** |
| * A service can declare default channels for its destinations. If a destination |
| * specifies its own list of channels it overrides these defaults. |
| * <p> |
| * <default-channels><br/> |
| * <channel ref="channel-id"/><br/> |
| * <default-channels> |
| * </p> |
| * @param chan the channel node |
| * @param serviceSettings service settings |
| */ |
| private void defaultChannel(Node chan, ServiceSettings serviceSettings) |
| { |
| String ref = getAttributeOrChildElement(chan, REF_ATTR); |
| |
| if (ref.length() > 0) |
| { |
| ChannelSettings channel = config.getChannelSettings(ref); |
| if (channel != null) |
| { |
| serviceSettings.addDefaultChannel(channel); |
| } |
| else |
| { |
| // {0} not found for reference '{1}' |
| ConfigurationException e = new ConfigurationException(); |
| e.setMessage(REF_NOT_FOUND, new Object[]{CHANNEL_ELEMENT, ref}); |
| throw e; |
| } |
| } |
| else |
| { |
| //A default channel was specified without a reference for service '{0}'. |
| ConfigurationException ex = new ConfigurationException(); |
| ex.setMessage(INVALID_DEFAULT_CHANNEL, new Object[]{serviceSettings.getId()}); |
| throw ex; |
| } |
| } |
| |
| private void adapterDefinition(Node adapter, ServiceSettings serviceSettings) |
| { |
| // Validation |
| requiredAttributesOrElements(adapter, ADAPTER_DEFINITION_REQ_CHILDREN); |
| allowedChildElements(adapter, ADAPTER_DEFINITION_CHILDREN); |
| |
| String serviceId = serviceSettings.getId(); |
| |
| String id = getAttributeOrChildElement(adapter, ID_ATTR); |
| if (isValidID(id)) |
| { |
| AdapterSettings adapterSettings = new AdapterSettings(id); |
| adapterSettings.setSourceFile(getSourceFileOf(adapter)); |
| String className = getAttributeOrChildElement(adapter, CLASS_ATTR); |
| |
| if (className.length() > 0) |
| { |
| adapterSettings.setClassName(className); |
| |
| // Default Adapter Check |
| boolean isDefault = Boolean.valueOf(getAttributeOrChildElement(adapter, DEFAULT_ATTR)); |
| if (isDefault) |
| { |
| adapterSettings.setDefault(isDefault); |
| |
| AdapterSettings defaultAdapter; |
| defaultAdapter = serviceSettings.getDefaultAdapter(); |
| |
| if (defaultAdapter != null) |
| { |
| // Duplicate default adapter '{0}' in service '{1}'. '{2}' has already been selected as the default. |
| ConfigurationException ex = new ConfigurationException(); |
| ex.setMessage(DUPLICATE_DEFAULT_ADAPTER, new Object[]{id, serviceId, defaultAdapter.getId()}); |
| throw ex; |
| } |
| } |
| |
| serviceSettings.addAdapterSettings(adapterSettings); |
| |
| // Adapter Properties |
| NodeList properties = selectNodeList(adapter, PROPERTIES_ELEMENT + "/*"); |
| if (properties.getLength() > 0) |
| { |
| ConfigMap map = properties(properties, getSourceFileOf(adapter)); |
| adapterSettings.addProperties(map); |
| } |
| } |
| else |
| { |
| // Class not specified for {ADAPTER_DEFINITION_ELEMENT} '{id}'. |
| ConfigurationException ex = new ConfigurationException(); |
| ex.setMessage(CLASS_NOT_SPECIFIED, new Object[]{ADAPTER_DEFINITION_ELEMENT, id}); |
| throw ex; |
| } |
| } |
| else |
| { |
| //Invalid {ADAPTER_DEFINITION_ELEMENT} id '{id}' for service '{serviceId}'. |
| ConfigurationException ex = new ConfigurationException(); |
| ex.setMessage(INVALID_ID_IN_SERVICE, new Object[]{ADAPTER_DEFINITION_ELEMENT, id, serviceId}); |
| throw ex; |
| } |
| } |
| |
| private void adapterInclude(Node adapterInclude, ServiceSettings serviceSettings) |
| { |
| // Validation |
| allowedAttributesOrElements(adapterInclude, ADAPTER_INCLUDE_CHILDREN); |
| |
| String src = getAttributeOrChildElement(adapterInclude, SRC_ATTR); |
| String dir = getAttributeOrChildElement(adapterInclude, DIRECTORY_ATTR); |
| if (src.length() > 0) |
| { |
| adapterIncludeFile(serviceSettings, src); |
| } |
| else if (dir.length() > 0) |
| { |
| adapterIncludeDirectory(serviceSettings, dir); |
| } |
| else |
| { |
| // Attribute '{0}' must be specified for element '{1}' |
| ConfigurationException ex = new ConfigurationException(); |
| ex.setMessage(MISSING_INCLUDE_ATTRIBUTES, new Object[]{adapterInclude.getNodeName(), SRC_ATTR, DIRECTORY_ATTR}); |
| throw ex; |
| } |
| } |
| |
| private void adapterIncludeDirectory(ServiceSettings serviceSettings, String dir) |
| { |
| List files = fileResolver.getFiles(dir); |
| for (int i = 0; i < files.size(); i++) |
| { |
| String src = (String) files.get(i); |
| adapterIncludeFile(serviceSettings, src); |
| } |
| } |
| |
| private void adapterIncludeFile(ServiceSettings serviceSettings, String src) |
| { |
| Document doc = loadDocument(src, fileResolver.getIncludedFile(src)); |
| doc.getDocumentElement().normalize(); |
| |
| // Check for multiple adapters defined in file wrapped in an <adapters> element |
| Node adaptersNode = selectSingleNode(doc, ADAPTERS_ELEMENT); |
| if (adaptersNode != null) |
| { |
| allowedChildElements(adaptersNode, ADAPTERS_CHILDREN); |
| NodeList adapters = selectNodeList(adaptersNode, ADAPTER_DEFINITION_ELEMENT); |
| for (int a = 0; a < adapters.getLength(); a++) |
| { |
| Node adapter = adapters.item(a); |
| adapterDefinition(adapter, serviceSettings); |
| } |
| fileResolver.popIncludedFile(); |
| } |
| else // Check for single adapter |
| { |
| Node adapter = selectSingleNode(doc, "/" + ADAPTER_DEFINITION_ELEMENT); |
| if (adapter != null) |
| { |
| adapterDefinition(adapter, serviceSettings); |
| fileResolver.popIncludedFile(); |
| } |
| else |
| { |
| // The {0} root element in file {1} must be ''{2}'' or ''{3}''. |
| ConfigurationException ex = new ConfigurationException(); |
| ex.setMessage(INVALID_INCLUDE_ROOT, new Object[]{ADAPTER_INCLUDE_ELEMENT, src, ADAPTERS_ELEMENT, ADAPTER_DEFINITION_ELEMENT}); |
| throw ex; |
| } |
| } |
| } |
| |
| private void destinationInclude(Node destInclude, ServiceSettings serviceSettings) |
| { |
| // Validation |
| allowedAttributesOrElements(destInclude, DESTINATION_INCLUDE_CHILDREN); |
| |
| String src = getAttributeOrChildElement(destInclude, SRC_ATTR); |
| String dir = getAttributeOrChildElement(destInclude, DIRECTORY_ATTR); |
| if (src.length() > 0) |
| { |
| destinationIncludeFile(serviceSettings, src); |
| } |
| else if (dir.length() > 0) |
| { |
| destinationIncludeDirectory(serviceSettings, dir); |
| } |
| else |
| { |
| // The include element ''{0}'' must specify either the ''{1}'' or ''{2}'' attribute. |
| ConfigurationException ex = new ConfigurationException(); |
| ex.setMessage(MISSING_INCLUDE_ATTRIBUTES, new Object[]{destInclude.getNodeName(), SRC_ATTR, DIRECTORY_ATTR}); |
| throw ex; |
| } |
| } |
| |
| private void destinationIncludeDirectory(ServiceSettings serviceSettings, String dir) |
| { |
| List files = fileResolver.getFiles(dir); |
| for (int i = 0; i < files.size(); i++) |
| { |
| String src = (String) files.get(i); |
| destinationIncludeFile(serviceSettings, src); |
| } |
| } |
| |
| private void destinationIncludeFile(ServiceSettings serviceSettings, String src) |
| { |
| Document doc = loadDocument(src, fileResolver.getIncludedFile(src)); |
| doc.getDocumentElement().normalize(); |
| |
| // Check for multiple destination defined in file. |
| Node destinationsNode = selectSingleNode(doc, DESTINATIONS_ELEMENT); |
| if (destinationsNode != null) |
| { |
| allowedChildElements(destinationsNode, DESTINATIONS_CHILDREN); |
| NodeList destinations = selectNodeList(destinationsNode, DESTINATION_ELEMENT); |
| for (int a = 0; a < destinations.getLength(); a++) |
| { |
| Node dest = destinations.item(a); |
| destination(dest, serviceSettings); |
| } |
| fileResolver.popIncludedFile(); |
| } |
| else // Check for single destination definition. |
| { |
| Node dest = selectSingleNode(doc, "/" + DESTINATION_ELEMENT); |
| if (dest != null) |
| { |
| destination(dest, serviceSettings); |
| fileResolver.popIncludedFile(); |
| } |
| else |
| { |
| // The {0} root element in file {1} must be ''{2}'' or ''{3}''. |
| ConfigurationException ex = new ConfigurationException(); |
| ex.setMessage(INVALID_INCLUDE_ROOT, new Object[]{DESTINATION_INCLUDE_ELEMENT, src, DESTINATIONS_ELEMENT, DESTINATION_ELEMENT}); |
| throw ex; |
| } |
| } |
| } |
| |
| private void destination(Node dest, ServiceSettings serviceSettings) |
| { |
| // Validation |
| requiredAttributesOrElements(dest, DESTINATION_REQ_CHILDREN); |
| allowedAttributes(dest, DESTINATION_ATTR); |
| allowedChildElements(dest, DESTINATION_CHILDREN); |
| |
| String serviceId = serviceSettings.getId(); |
| |
| DestinationSettings destinationSettings; |
| String id = getAttributeOrChildElement(dest, ID_ATTR); |
| if (isValidID(id)) |
| { |
| destinationSettings = (DestinationSettings)serviceSettings.getDestinationSettings().get(id); |
| if (destinationSettings != null) |
| { |
| // Duplicate destination definition '{id}' in service '{serviceId}'. |
| ConfigurationException e = new ConfigurationException(); |
| e.setMessage(DUPLICATE_DESTINATION_ERROR, new Object[]{id, serviceId}); |
| throw e; |
| } |
| |
| destinationSettings = new DestinationSettings(id); |
| destinationSettings.setSourceFile(getSourceFileOf(dest)); |
| serviceSettings.addDestinationSettings(destinationSettings); |
| } |
| else |
| { |
| //Invalid {DESTINATION_ELEMENT} id '{id}' for service '{serviceId}'. |
| ConfigurationException ex = new ConfigurationException(); |
| ex.setMessage(INVALID_ID_IN_SERVICE, new Object[]{DESTINATION_ELEMENT, id, serviceId}); |
| throw ex; |
| } |
| |
| // Destination Properties |
| NodeList properties = selectNodeList(dest, PROPERTIES_ELEMENT + "/*"); |
| if (properties.getLength() > 0) |
| { |
| ConfigMap map = properties(properties, getSourceFileOf(dest)); |
| destinationSettings.addProperties(map); |
| |
| // Sniff for <network><reliable>true|false</reliable></network> setting. |
| // Also sniff for inbound and outbound throttle policies of buffer and conflate. |
| // All these features are only supported when advanced messaging support is enabled. |
| if (!verifyAdvancedMessagingSupport) |
| { |
| ConfigMap networkSettings = map.getPropertyAsMap(NetworkSettings.NETWORK_ELEMENT, null); |
| if (networkSettings != null) |
| { |
| String reliable = networkSettings.getPropertyAsString(NetworkSettings.RELIABLE_ELEMENT, null); |
| if (reliable != null && Boolean.valueOf(reliable)) |
| { |
| verifyAdvancedMessagingSupport = true; |
| } |
| else |
| { |
| ConfigMap inbound = networkSettings.getPropertyAsMap(ThrottleSettings.ELEMENT_INBOUND, null); |
| if (inbound != null) |
| { |
| String policy = inbound.getPropertyAsString(ThrottleSettings.ELEMENT_POLICY, null); |
| if (policy != null && (Policy.BUFFER.toString().equalsIgnoreCase(policy) |
| || Policy.CONFLATE.toString().equalsIgnoreCase(policy))) |
| verifyAdvancedMessagingSupport = true; |
| } |
| if (!verifyAdvancedMessagingSupport) |
| { |
| ConfigMap outbound = networkSettings.getPropertyAsMap(ThrottleSettings.ELEMENT_OUTBOUND, null); |
| if (outbound != null) |
| { |
| String policy = outbound.getPropertyAsString(ThrottleSettings.ELEMENT_POLICY, null); |
| if (policy != null && (Policy.BUFFER.toString().equalsIgnoreCase(policy) |
| || Policy.CONFLATE.toString().equalsIgnoreCase(policy))) |
| verifyAdvancedMessagingSupport = true; |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| // Channels |
| destinationChannels(dest, destinationSettings, serviceSettings); |
| |
| // Security |
| destinationSecurity(dest, destinationSettings, serviceSettings); |
| |
| // Service Adapter |
| destinationAdapter(dest, destinationSettings, serviceSettings); |
| } |
| |
| private void destinationChannels(Node dest, DestinationSettings destinationSettings, ServiceSettings serviceSettings) |
| { |
| String destId = destinationSettings.getId(); |
| |
| // Channels attribute |
| String channelsList = evaluateExpression(dest, "@" + CHANNELS_ATTR).toString().trim(); |
| if (channelsList.length() > 0) |
| { |
| StringTokenizer st = new StringTokenizer(channelsList, LIST_DELIMITERS); |
| while (st.hasMoreTokens()) |
| { |
| String ref = st.nextToken().trim(); |
| ChannelSettings channel = config.getChannelSettings(ref); |
| if (channel != null) |
| { |
| destinationSettings.addChannelSettings(channel); |
| } |
| else |
| { |
| // {CHANNEL_ELEMENT} not found for reference '{ref}' in destination '{destId}'. |
| ConfigurationException ex = new ConfigurationException(); |
| ex.setMessage(REF_NOT_FOUND_IN_DEST, new Object[]{CHANNEL_ELEMENT, ref, destId}); |
| throw ex; |
| } |
| } |
| } |
| else |
| { |
| // Channels element |
| Node channelsNode = selectSingleNode(dest, CHANNELS_ELEMENT); |
| if (channelsNode != null) |
| { |
| allowedChildElements(channelsNode, DESTINATION_CHANNELS_CHILDREN); |
| NodeList channels = selectNodeList(channelsNode, CHANNEL_ELEMENT); |
| for (int c = 0; c < channels.getLength(); c++) |
| { |
| Node chan = channels.item(c); |
| |
| // Validation |
| requiredAttributesOrElements(chan, DESTINATION_CHANNEL_REQ_CHILDREN); |
| |
| String ref = getAttributeOrChildElement(chan, REF_ATTR); |
| if (ref.length() > 0) |
| { |
| ChannelSettings channel = config.getChannelSettings(ref); |
| if (channel != null) |
| { |
| destinationSettings.addChannelSettings(channel); |
| } |
| else |
| { |
| // {CHANNEL_ELEMENT} not found for reference '{ref}' in destination '{destId}'. |
| ConfigurationException ex = new ConfigurationException(); |
| ex.setMessage(REF_NOT_FOUND_IN_DEST, new Object[]{CHANNEL_ELEMENT, ref, destId}); |
| throw ex; |
| } |
| } |
| else |
| { |
| //Invalid {0} ref '{1}' in destination '{2}'. |
| ConfigurationException ex = new ConfigurationException(); |
| ex.setMessage(INVALID_REF_IN_DEST, new Object[]{CHANNEL_ELEMENT, ref, destId}); |
| throw ex; |
| } |
| } |
| } |
| else |
| { |
| // Finally, we fall back to the service's default channels |
| List defaultChannels = serviceSettings.getDefaultChannels(); |
| Iterator it = defaultChannels.iterator(); |
| while (it.hasNext()) |
| { |
| ChannelSettings channel = (ChannelSettings)it.next(); |
| destinationSettings.addChannelSettings(channel); |
| } |
| } |
| } |
| |
| if (destinationSettings.getChannelSettings().size() <= 0) |
| { |
| // Destination '{id}' must specify at least one channel. |
| ConfigurationException ex = new ConfigurationException(); |
| ex.setMessage(DEST_NEEDS_CHANNEL, new Object[]{destId}); |
| throw ex; |
| } |
| } |
| |
| private void destinationSecurity(Node dest, DestinationSettings destinationSettings, ServiceSettings serviceSettings) |
| { |
| String destId = destinationSettings.getId(); |
| |
| // Security-constraint short-cut attribute |
| String ref = evaluateExpression(dest, "@" + SECURITY_CONSTRAINT_ATTR).toString().trim(); |
| if (ref.length() > 0) |
| { |
| SecurityConstraint sc = ((MessagingConfiguration)config).getSecuritySettings().getConstraint(ref); |
| if (sc != null) |
| { |
| destinationSettings.setConstraint(sc); |
| } |
| else |
| { |
| // {SECURITY_CONSTRAINT_ELEMENT} not found for reference '{ref}' in destination '{destId}'. |
| ConfigurationException ex = new ConfigurationException(); |
| ex.setMessage(REF_NOT_FOUND_IN_DEST, new Object[]{SECURITY_CONSTRAINT_ATTR, ref, destId}); |
| throw ex; |
| } |
| } |
| else |
| { |
| // Inline security element |
| Node security = selectSingleNode(dest, SECURITY_ELEMENT); |
| if (security != null) |
| { |
| allowedChildElements(security, EMBEDDED_SECURITY_CHILDREN); |
| Node constraint = selectSingleNode(security, SECURITY_CONSTRAINT_ELEMENT); |
| if (constraint != null) |
| { |
| SecurityConstraint sc = securityConstraint(constraint, true); |
| destinationSettings.setConstraint(sc); |
| } |
| } |
| else |
| { |
| // Finally, we fall back to the service's default security constraint |
| SecurityConstraint sc = serviceSettings.getConstraint(); |
| if (sc != null) |
| { |
| destinationSettings.setConstraint(sc); |
| } |
| } |
| } |
| } |
| |
| private void destinationAdapter(Node dest, DestinationSettings destinationSettings, ServiceSettings serviceSettings) |
| { |
| String destId = destinationSettings.getId(); |
| |
| // Adapter attribute |
| String ref = evaluateExpression(dest, "@" + ADAPTER_ATTR).toString().trim(); |
| if (ref.length() > 0) |
| { |
| adapterReference(ref, destinationSettings, serviceSettings); |
| } |
| else |
| { |
| Node adapter = selectSingleNode(dest, ADAPTER_ELEMENT); |
| |
| // Adapter element |
| if (adapter != null) |
| { |
| allowedAttributesOrElements(adapter, DESTINATION_ADAPTER_CHILDREN); |
| ref = getAttributeOrChildElement(adapter, REF_ATTR); |
| adapterReference(ref, destinationSettings, serviceSettings); |
| } |
| else |
| { |
| // Default Adapter (optionally set at the service level) |
| AdapterSettings adapterSettings = serviceSettings.getDefaultAdapter(); |
| if (adapterSettings != null) |
| { |
| destinationSettings.setAdapterSettings(adapterSettings); |
| } |
| } |
| } |
| |
| if (destinationSettings.getAdapterSettings() == null) |
| { |
| // Destination '{id}' must specify at least one adapter. |
| ConfigurationException ex = new ConfigurationException(); |
| ex.setMessage(DEST_NEEDS_ADAPTER, new Object[]{destId}); |
| throw ex; |
| } |
| } |
| |
| private void adapterReference(String ref, DestinationSettings destinationSettings, ServiceSettings serviceSettings) |
| { |
| String destId = destinationSettings.getId(); |
| if (ref.length() > 0) |
| { |
| AdapterSettings adapterSettings = serviceSettings.getAdapterSettings(ref); |
| if (adapterSettings != null) |
| { |
| destinationSettings.setAdapterSettings(adapterSettings); |
| } |
| else |
| { |
| // {ADAPTER_ELEMENT} not found for reference '{ref}' in destination '{destId}'. |
| ConfigurationException ex = new ConfigurationException(); |
| ex.setMessage(REF_NOT_FOUND_IN_DEST, new Object[]{ADAPTER_ELEMENT, ref, destId}); |
| throw ex; |
| } |
| } |
| else |
| { |
| //Invalid {ADAPTER_ELEMENT} ref '{ref}' in destination '{destId}'. |
| ConfigurationException ex = new ConfigurationException(); |
| ex.setMessage(INVALID_REF_IN_DEST, new Object[]{ADAPTER_ELEMENT, ref, destId}); |
| throw ex; |
| } |
| } |
| |
| private void logging(Node root) |
| { |
| Node logging = selectSingleNode(root, LOGGING_ELEMENT); |
| if (logging != null) |
| { |
| // Validation |
| allowedAttributesOrElements(logging, LOGGING_CHILDREN); |
| |
| LoggingSettings settings = new LoggingSettings(); |
| |
| // Log Properties |
| NodeList properties = selectNodeList(logging, PROPERTIES_ELEMENT + "/*"); |
| if (properties.getLength() > 0) |
| { |
| ConfigMap map = properties(properties, getSourceFileOf(logging)); |
| settings.addProperties(map); |
| } |
| |
| NodeList targets = selectNodeList(logging, TARGET_ELEMENT); |
| for (int i = 0; i < targets.getLength(); i++) |
| { |
| Node targetNode = targets.item(i); |
| |
| // Target Validation |
| requiredAttributesOrElements(targetNode, TARGET_REQ_CHILDREN); |
| allowedAttributesOrElements(targetNode, TARGET_CHILDREN); |
| |
| String className = getAttributeOrChildElement(targetNode, CLASS_ATTR); |
| |
| if (className.length() > 0) |
| { |
| TargetSettings targetSettings = new TargetSettings(className); |
| String targetLevel = getAttributeOrChildElement(targetNode, LEVEL_ATTR); |
| |
| if (targetLevel.length() > 0) |
| targetSettings.setLevel(targetLevel); |
| |
| // Filters |
| Node filtersNode = selectSingleNode(targetNode, FILTERS_ELEMENT); |
| if (filtersNode != null) |
| { |
| allowedChildElements(filtersNode, FILTERS_CHILDREN); |
| NodeList filters = selectNodeList(filtersNode, PATTERN_ELEMENT); |
| for (int f = 0; f < filters.getLength(); f++) |
| { |
| Node pattern = filters.item(f); |
| String filter = evaluateExpression(pattern, ".").toString().trim(); |
| targetSettings.addFilter(filter); |
| } |
| } |
| |
| // Target Properties |
| properties = selectNodeList(targetNode, PROPERTIES_ELEMENT + "/*"); |
| if (properties.getLength() > 0) |
| { |
| ConfigMap map = properties(properties, getSourceFileOf(targetNode)); |
| targetSettings.addProperties(map); |
| } |
| |
| settings.addTarget(targetSettings); |
| } |
| } |
| |
| config.setLoggingSettings(settings); |
| } |
| } |
| |
| private void system(Node root) |
| { |
| Node system = selectSingleNode(root, SYSTEM_ELEMENT); |
| if (system == null) |
| { |
| // Create a default instance of SystemSettings which by default has setManagable as true |
| // and has setRedeployEnabled as false. |
| ((MessagingConfiguration)config).setSystemSettings(new SystemSettings()); |
| return; |
| } |
| |
| allowedAttributesOrElements(system, SYSTEM_CHILDREN); |
| |
| SystemSettings settings = new SystemSettings(); |
| |
| settings.setEnforceEndpointValidation(getAttributeOrChildElement(system, ENFORCE_ENDOINT_VALIDATION)); |
| locale(system, settings); |
| settings.setManageable(getAttributeOrChildElement(system, MANAGEABLE_ELEMENT)); |
| settings.setDotNetFrameworkVersion(getAttributeOrChildElement(system, DOTNET_FRAMEWORK_VERSION)); |
| redeploy(system, settings); |
| uuidGenerator(system, settings); |
| |
| ((MessagingConfiguration)config).setSystemSettings(settings); |
| } |
| |
| private void redeploy(Node system, SystemSettings settings) |
| { |
| Node redeployNode = selectSingleNode(system, REDEPLOY_ELEMENT); |
| if (redeployNode == null) |
| return; |
| |
| allowedAttributesOrElements(redeployNode, REDEPLOY_CHILDREN); |
| |
| String enabled = getAttributeOrChildElement(redeployNode, ENABLED_ELEMENT); |
| settings.setRedeployEnabled(enabled); |
| |
| String interval = getAttributeOrChildElement(redeployNode, WATCH_INTERVAL_ELEMENT); |
| if (interval.length() > 0) |
| { |
| settings.setWatchInterval(interval); |
| } |
| |
| NodeList watches = selectNodeList(redeployNode, WATCH_FILE_ELEMENT); |
| for (int i = 0; i < watches.getLength(); i++) |
| { |
| Node watchNode = watches.item(i); |
| String watch = evaluateExpression(watchNode, ".").toString().trim(); |
| if (watch.length() > 0) |
| { |
| settings.addWatchFile(watch); |
| } |
| } |
| |
| NodeList touches = selectNodeList(redeployNode, TOUCH_FILE_ELEMENT); |
| for (int i = 0; i < touches.getLength(); i++) |
| { |
| Node touchNode = touches.item(i); |
| String touch = evaluateExpression(touchNode, ".").toString().trim(); |
| if (touch.length() > 0) |
| { |
| settings.addTouchFile(touch); |
| } |
| } |
| } |
| |
| private void locale(Node system, SystemSettings settings) |
| { |
| Node localeNode = selectSingleNode(system, LOCALE_ELEMENT); |
| if (localeNode == null) |
| return; |
| |
| allowedAttributesOrElements(localeNode, LOCALE_CHILDREN); |
| |
| String defaultLocaleString = getAttributeOrChildElement(localeNode, DEFAULT_LOCALE_ELEMENT); |
| Locale defaultLocale = defaultLocaleString.length() > 0? LocaleUtils.buildLocale(defaultLocaleString) : LocaleUtils.buildLocale(null); |
| settings.setDefaultLocale(defaultLocale); |
| } |
| |
| private void uuidGenerator(Node system, SystemSettings settings) |
| { |
| Node uuidGenerator = selectSingleNode(system, UUID_GENERATOR_ELEMENT); |
| if (uuidGenerator == null) |
| return; |
| |
| requiredAttributesOrElements(uuidGenerator, UUID_GENERATOR_REQ_CHILDREN); |
| |
| String className = getAttributeOrChildElement(uuidGenerator, CLASS_ATTR); |
| if (className.length() == 0) |
| { |
| // Class not specified for {UUID_GENERATOR_ELEMENT} '{id}'. |
| ConfigurationException ex = new ConfigurationException(); |
| ex.setMessage(CLASS_NOT_SPECIFIED, new Object[]{UUID_GENERATOR_ELEMENT, ""}); |
| throw ex; |
| } |
| |
| settings.setUUIDGeneratorClassName(className); |
| } |
| |
| private void flexClient(Node root) |
| { |
| Node flexClient = selectSingleNode(root, FLEX_CLIENT_ELEMENT); |
| if (flexClient != null) |
| { |
| // Validation |
| allowedChildElements(flexClient, FLEX_CLIENT_CHILDREN); |
| |
| FlexClientSettings flexClientSettings = new FlexClientSettings(); |
| |
| // Timeout |
| String timeout = getAttributeOrChildElement(flexClient, FLEX_CLIENT_TIMEOUT_MINUTES_ELEMENT); |
| if (timeout.length() > 0) |
| { |
| try |
| { |
| long timeoutMinutes = Long.parseLong(timeout); |
| if (timeoutMinutes < 0) |
| { |
| // Invalid timeout minutes value ''{0}'' in the <flex-client> configuration section. Please specify a positive value or leave the element undefined in which case flex client instances on the server will be timed out when all associated sessions/connections have shut down. |
| ConfigurationException e = new ConfigurationException(); |
| e.setMessage(INVALID_FLEX_CLIENT_TIMEOUT, new Object[]{timeout}); |
| throw e; |
| } |
| flexClientSettings.setTimeoutMinutes(timeoutMinutes); |
| } |
| catch (NumberFormatException nfe) |
| { |
| // Invalid timeout minutes value ''{0}'' in the <flex-client> configuration section. Please specify a positive value or leave the element undefined in which case flex client instances on the server will be timed out when all associated sessions/connections have shut down. |
| ConfigurationException e = new ConfigurationException(); |
| e.setMessage(INVALID_FLEX_CLIENT_TIMEOUT, new Object[]{timeout}); |
| throw e; |
| } |
| } |
| else |
| { |
| flexClientSettings.setTimeoutMinutes(0); // Default to 0; in this case FlexClients are invalidated when all associated sessions have been invalidated. |
| } |
| |
| // Flex client queue processor |
| Node outboundQueueProcessor = selectSingleNode(flexClient, FLEX_CLIENT_OUTBOUND_QUEUE_PROCESSOR_ELEMENT); |
| if (outboundQueueProcessor != null) |
| { |
| // Validation |
| requiredAttributesOrElements(outboundQueueProcessor, FLEX_CLIENT_OUTBOUND_QUEUE_PROCESSOR_REQ_CHILDREN); |
| |
| // Flex client queue processor class |
| String outboundQueueProcessClass = getAttributeOrChildElement(outboundQueueProcessor, CLASS_ATTR); |
| if (outboundQueueProcessClass.length() > 0) |
| { |
| flexClientSettings.setFlexClientOutboundQueueProcessorClassName(outboundQueueProcessClass); |
| } |
| else |
| { |
| // Class not specified for {FLEX_CLIENT_OUTBOUND_QUEUE_PROCESSOR_ELEMENT} '{id}'. |
| ConfigurationException ex = new ConfigurationException(); |
| ex.setMessage(CLASS_NOT_SPECIFIED, new Object[]{FLEX_CLIENT_OUTBOUND_QUEUE_PROCESSOR_ELEMENT, ""}); |
| throw ex; |
| } |
| |
| // Flex client queue processor properties |
| NodeList properties = selectNodeList(outboundQueueProcessor, PROPERTIES_ELEMENT + "/*"); |
| if (properties.getLength() > 0) |
| { |
| ConfigMap map = properties(properties, getSourceFileOf(outboundQueueProcessor)); |
| flexClientSettings.setFlexClientOutboundQueueProcessorProperties(map); |
| // Sniff for adaptive-frequency which requires advanced messaging support. |
| boolean adaptiveFrequency = map.getPropertyAsBoolean(ADAPTIVE_FREQUENCY, false); |
| if (adaptiveFrequency) |
| verifyAdvancedMessagingSupport = true; |
| } |
| } |
| ((MessagingConfiguration)config).setFlexClientSettings(flexClientSettings); |
| } |
| } |
| |
| private void factories(Node root) |
| { |
| Node factories = selectSingleNode(root, FACTORIES_ELEMENT); |
| if (factories != null) |
| { |
| // Validation |
| allowedAttributesOrElements(factories, FACTORIES_CHILDREN); |
| |
| NodeList factoryList = selectNodeList(factories, FACTORY_ELEMENT); |
| for (int i = 0; i < factoryList.getLength(); i++) |
| { |
| Node factory = factoryList.item(i); |
| factory(factory); |
| } |
| } |
| } |
| |
| private void factory(Node factory) |
| { |
| // Validation |
| requiredAttributesOrElements(factory, FACTORY_REQ_CHILDREN); |
| |
| String id = getAttributeOrChildElement(factory, ID_ATTR); |
| String className = getAttributeOrChildElement(factory, CLASS_ATTR); |
| if (isValidID(id)) |
| { |
| FactorySettings factorySettings = new FactorySettings(id, className); |
| |
| // Factory Properties |
| NodeList properties = selectNodeList(factory, PROPERTIES_ELEMENT + "/*"); |
| if (properties.getLength() > 0) |
| { |
| ConfigMap map = properties(properties, getSourceFileOf(factory)); |
| factorySettings.addProperties(map); |
| } |
| ((MessagingConfiguration)config).addFactorySettings(id, factorySettings); |
| } |
| else |
| { |
| // Invalid {FACTORY_ELEMENT} id '{id}'. |
| ConfigurationException ex = new ConfigurationException(); |
| ex.setMessage(INVALID_ID, new Object[]{FACTORY_ELEMENT, id}); |
| ex.setDetails(INVALID_ID); |
| throw ex; |
| } |
| } |
| |
| private void messageFilters(Node root) |
| { |
| typedMessageFilters(root, ASYNC_MESSAGE_FILTERS_ELEMENT, ASYNC_MESSAGE_FILTERS_ELEMENT_CHILDREN); |
| typedMessageFilters(root, SYNC_MESSAGE_FILTERS_ELEMENT, SYNC_MESSAGE_FILTERS_ELEMENT_CHILDREN); |
| } |
| |
| private void typedMessageFilters(Node root, String filterTypeElement, String[] childrenElements) |
| { |
| Node messageFiltersNode = selectSingleNode(root, filterTypeElement); |
| if (messageFiltersNode == null) |
| return; |
| |
| // Validation |
| allowedChildElements(messageFiltersNode, childrenElements); |
| |
| // Message filter |
| NodeList messageFilters = selectNodeList(messageFiltersNode, FILTER_ELEMENT); |
| for (int i = 0; i < messageFilters.getLength(); i++) |
| { |
| Node messageFilter = messageFilters.item(i); |
| messageFilter(messageFilter, filterTypeElement); |
| } |
| } |
| |
| private void messageFilter(Node messageFilter, String filterType) |
| { |
| // Validation |
| requiredAttributesOrElements(messageFilter, FILTER_REQ_CHILDREN); |
| allowedAttributesOrElements(messageFilter, FILTER_CHILDREN); |
| |
| String id = getAttributeOrChildElement(messageFilter, ID_ATTR); |
| if (isValidID(id)) |
| { |
| // Message filter class name |
| String className = getAttributeOrChildElement(messageFilter, CLASS_ATTR); |
| if (className.length() > 0) |
| { |
| MessageFilterSettings messageFilterSettings = new MessageFilterSettings(); |
| messageFilterSettings.setId(id); |
| messageFilterSettings.setClassName(className); |
| // Record type of filter. |
| MessageFilterSettings.FilterType type = filterType.equals(ASYNC_MESSAGE_FILTERS_ELEMENT) ? |
| MessageFilterSettings.FilterType.ASYNC : |
| MessageFilterSettings.FilterType.SYNC; |
| messageFilterSettings.setFilterType(type); |
| // Custom server properties. |
| NodeList properties = selectNodeList(messageFilter, PROPERTIES_ELEMENT + "/*"); |
| if (properties.getLength() > 0) |
| { |
| ConfigMap map = properties(properties, getSourceFileOf(messageFilter)); |
| messageFilterSettings.addProperties(map); |
| } |
| ((MessagingConfiguration)config).addMessageFilterSettings(messageFilterSettings); |
| } |
| else |
| { |
| // Class not specified for {FILTER_ELEMENT} '{id}'. |
| ConfigurationException ex = new ConfigurationException(); |
| ex.setMessage(CLASS_NOT_SPECIFIED, new Object[]{FILTER_ELEMENT, id}); |
| throw ex; |
| } |
| } |
| } |
| |
| private void validators(Node root) |
| { |
| Node validatorsNode = selectSingleNode(root, VALIDATORS_ELEMENT); |
| if (validatorsNode == null) { |
| return; |
| } |
| |
| // Validation |
| allowedChildElements(validatorsNode, VALIDATORS_CHILDREN); |
| |
| // Validator |
| NodeList validators = selectNodeList(validatorsNode, VALIDATOR_ELEMENT); |
| if(validators.getLength() > 0) { |
| for (int i = 0; i < validators.getLength(); i++) { |
| Node validator = validators.item(i); |
| validator(validator); |
| } |
| } |
| } |
| |
| private void validator(Node validator) |
| { |
| // Validation |
| requiredAttributesOrElements(validator, VALIDATOR_REQ_CHILDREN); |
| allowedAttributesOrElements(validator, VALIDATOR_CHILDREN); |
| |
| ValidatorSettings validatorSettings = new ValidatorSettings(); |
| |
| // Validator class name |
| String className = getAttributeOrChildElement(validator, CLASS_ATTR); |
| if (className.length() > 0) |
| { |
| validatorSettings.setClassName(className); |
| } |
| else |
| { |
| // Class not specified for {VALIDATOR_ELEMENT} '{id}'. |
| ConfigurationException ex = new ConfigurationException(); |
| ex.setMessage(CLASS_NOT_SPECIFIED, new Object[]{VALIDATOR_ELEMENT, ""}); |
| throw ex; |
| } |
| |
| // Validator type |
| String type = getAttributeOrChildElement(validator, TYPE_ATTR); |
| if (type.length() > 0) |
| validatorSettings.setType(type); |
| |
| // Validator properties |
| NodeList properties = selectNodeList(validator, PROPERTIES_ELEMENT + "/*"); |
| if (properties.getLength() > 0) |
| { |
| ConfigMap map = properties(properties, getSourceFileOf(validator)); |
| validatorSettings.addProperties(map); |
| } |
| |
| ((MessagingConfiguration)config).addValidatorSettings(validatorSettings); |
| } |
| } |