/* * JBoss, Home of Professional Open Source. * Copyright 2006, Red Hat Middleware LLC, and individual contributors * as indicated by the @author tags. See the copyright.txt file in the * distribution for a full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.jboss.services.binding; import java.io.InputStream; import java.net.URL; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.Map; import javax.management.ObjectName; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import org.jboss.util.StringPropertyReplacer; import org.jboss.logging.Logger; /** * XML implementation of ServicesStore. * *

Reads/writes/manages the XML config file for the ServiceBinding Manager module * * @author Mike Finn. * @author Scott.Stark@jboss.org * @version $Revision: 57210 $ */ public class XMLServicesStore implements ServicesStore { private final Logger log = Logger.getLogger(getClass()); /** A thread-safe map of Map keyed by server name. */ private Map servers = Collections.synchronizedMap(new HashMap()); /** This method is not usable in this implementation as XMLServiceStore is read-only * * @param serverName * @param serviceName * @param config * @exception DuplicateServiceException never thrown * @exception UnsupportedOperationException("XMLServiceStore is read-only") always thrown */ public void addService(String serverName, ObjectName serviceName, ServiceConfig config) throws DuplicateServiceException { throw new UnsupportedOperationException("XMLServiceStore is read-only"); } /** * Looks up a service, by server name and service name. * If the server or service does not exist, a null object is returned. * * @param serverName The name of the server in the config file * @param serviceName The name of the service (i.e. the JMX object name) * * @returns ServiceConfig object. Null if server or service is not found. */ public ServiceConfig getService(String serverName, ObjectName serviceName) { Map serverMap = (Map) this.servers.get(serverName); ServiceConfig config = null; if( serverMap != null ) { config = (ServiceConfig) serverMap.get(serviceName); } return config; } /** This method is not usable in this implementation as XMLServiceStore is read-only * * @param serverName * @param serviceName * @exception UnsupportedOperationException("XMLServiceStore is read-only") always thrown */ public void removeService(String serverName, ObjectName serviceName) { throw new UnsupportedOperationException("XMLServiceStore is read-only"); } /** Loads XML config file into memory and parses it into ServiceConfig * objects. * * @throws Exception on any parse error */ public void load(URL cfgURL) throws Exception { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder parser = factory.newDocumentBuilder(); InputStream cfgIS = cfgURL.openStream(); Document configDoc = parser.parse(cfgIS, cfgURL.toString()); Element serviceBindings = configDoc.getDocumentElement(); NodeList servers = serviceBindings.getElementsByTagName("server"); int length = servers.getLength(); for(int s = 0; s < length; s ++) { Element server = (Element) servers.item(s); parseServer(server); } } /** Store is a noop as this is a read-only store */ public void store(URL cfgURL) throws Exception { } /** Parse /service-bindings/server/service-config element into a Map objects that are stored in the servers map keyed by server.name. */ private void parseServer(Element server) throws Exception { String serverName = server.getAttribute("name"); HashMap serverConfigurations = new HashMap(); NodeList serviceConfigs = server.getElementsByTagName("service-config"); int length = serviceConfigs.getLength(); for(int c = 0; c < length; c ++) { Element config = (Element) serviceConfigs.item(c); ServiceConfig serviceConfig = new ServiceConfig(); ObjectName serviceObjectName = parseConfig(config, serviceConfig); serverConfigurations.put(serviceObjectName, serviceConfig); } this.servers.put(serverName, serverConfigurations); } /** Parse /service-bindings/server/service-config element into the given ServiceConfig object. */ private ObjectName parseConfig(Element config, ServiceConfig serviceConfig) throws Exception { String serviceName = config.getAttribute("name"); ObjectName serviceObjectName = new ObjectName(serviceName); serviceConfig.setServiceName(serviceName); // Parse the delegate info String delegateClass = config.getAttribute("delegateClass"); if( delegateClass.length() == 0 ) delegateClass = "org.jboss.services.binding.AttributeMappingDelegate"; Element delegateConfig = null; NodeList delegateConfigs = config.getElementsByTagName("delegate-config"); if( delegateConfigs.getLength() > 0 ) delegateConfig = (Element) delegateConfigs.item(0); serviceConfig.setServiceConfigDelegateClassName(delegateClass); serviceConfig.setServiceConfigDelegateConfig(delegateConfig); // Parse the service bindings ArrayList bindingsArray = new ArrayList(); NodeList bindings = config.getElementsByTagName("binding"); int length = bindings.getLength(); for(int b = 0; b < length; b ++) { Element binding = (Element) bindings.item(b); ServiceBinding sb = parseBinding(binding); bindingsArray.add(sb); } ServiceBinding[] tmp = new ServiceBinding[bindingsArray.size()]; bindingsArray.toArray(tmp); serviceConfig.setBindings(tmp); return serviceObjectName; } /** Parse /service-bindings/server/service-config/binding element into a ServiceBinding object. Any attributes whose value contains a system property reference of the form ${x} will be replaced with the correcsponding System.getProperty("x") value if one exists. */ private ServiceBinding parseBinding(Element binding) throws Exception { String name = binding.getAttribute("name"); if (name != null) { name = StringPropertyReplacer.replaceProperties(name); } String hostName = binding.getAttribute("host"); if (hostName != null) { hostName = StringPropertyReplacer.replaceProperties(hostName); } if (hostName.length() == 0) hostName = null; String portStr = binding.getAttribute("port"); if (portStr != null) { portStr = StringPropertyReplacer.replaceProperties(portStr); } if (portStr.length() == 0) portStr = "0"; log.debug("parseBinding, name='" + name + "', host='" + hostName + "'" + ", port='" + portStr + "'"); int port = Integer.parseInt(portStr); ServiceBinding sb = new ServiceBinding(name, hostName, port); return sb; } }