/*
* 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 org.apache.geode.admin.internal;
import org.apache.geode.admin.*;
import org.apache.geode.internal.Assert;
import org.apache.geode.internal.i18n.LocalizedStrings;
import javax.xml.transform.*;
// import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stream.StreamResult;
import org.xml.sax.*;
// import org.xml.sax.ext.*;
import org.xml.sax.helpers.AttributesImpl;
import java.io.*;
import java.util.*;
/**
* Generates XML data that represents the managed entities in an
* <code>AdminDistributedSystem</code>. This class is used mainly for testing.
*
* @since GemFire 4.0
*/
public class ManagedEntityConfigXmlGenerator extends ManagedEntityConfigXml implements XMLReader {
/** An empty <code>Attributes</code> */
private static Attributes EMPTY = new AttributesImpl();
///////////////////////// Instance Fields ////////////////////////
/**
* The <code>AdminDistributedSystem</code> for which we are generating XML
*/
private AdminDistributedSystem system;
/** The content handler to which SAX events are generated */
private ContentHandler handler;
///////////////////////// Static Methods ////////////////////////
/**
* Generates an XML representation of all of the managed entities in the given
* <code>AdminDistributedSystem</code>.
*/
public static void generate(AdminDistributedSystem system, PrintWriter pw) {
(new ManagedEntityConfigXmlGenerator(system)).generate(pw);
}
///////////////////////// Constructors //////////////////////////
/**
* Creates a new generator for the given <code>AdminDistributedSystem</code>.
*/
private ManagedEntityConfigXmlGenerator(AdminDistributedSystem system) {
this.system = system;
}
/////////////////////// Instance Methods ///////////////////////
/**
* Generates XML and writes it to the given <code>PrintWriter</code>
*/
private void generate(PrintWriter pw) {
// Use JAXP's transformation API to turn SAX events into pretty
// XML text
try {
Source src = new SAXSource(this, new InputSource());
Result res = new StreamResult(pw);
TransformerFactory xFactory = TransformerFactory.newInstance();
Transformer xform = xFactory.newTransformer();
xform.setOutputProperty(OutputKeys.METHOD, "xml");
xform.setOutputProperty(OutputKeys.INDENT, "yes");
xform.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, SYSTEM_ID);
xform.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, PUBLIC_ID);
xform.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
xform.transform(src, res);
pw.flush();
} catch (Exception ex) {
RuntimeException ex2 = new RuntimeException(
LocalizedStrings.ManagedEntityConfigXmlGenerator_EXCEPTION_THROWN_WHILE_GENERATING_XML
.toLocalizedString());
ex2.initCause(ex);
throw ex2;
}
}
/**
* Called by the transformer to parse the "input source". We ignore the input source and, instead,
* generate SAX events to the {@link #setContentHandler ContentHandler}.
*/
public void parse(InputSource input) throws SAXException {
Assert.assertTrue(this.handler != null);
handler.startDocument();
AttributesImpl atts = new AttributesImpl();
atts.addAttribute("", "", ID, "", String.valueOf(this.system.getConfig().getSystemId()));
handler.startElement("", DISTRIBUTED_SYSTEM, DISTRIBUTED_SYSTEM, atts);
// Add generation methods here
try {
generateRemoteCommand();
generateDiscovery();
generateSSL();
generateCacheServers();
} catch (AdminException ex) {
throw new SAXException(
LocalizedStrings.ManagedEntityConfigXmlGenerator_AN_ADMINEXCEPTION_WAS_THROWN_WHILE_GENERATING_XML
.toLocalizedString(),
ex);
}
handler.endElement("", DISTRIBUTED_SYSTEM, DISTRIBUTED_SYSTEM);
handler.endDocument();
}
/**
* Generates XML for the remote command
*/
private void generateRemoteCommand() throws SAXException {
String remoteCommand = this.system.getRemoteCommand();
handler.startElement("", REMOTE_COMMAND, REMOTE_COMMAND, EMPTY);
handler.characters(remoteCommand.toCharArray(), 0, remoteCommand.length());
handler.endElement("", REMOTE_COMMAND, REMOTE_COMMAND);
}
/**
* Generates XML for locators in the distributed system
*/
private void generateDiscovery() throws SAXException {
handler.startElement("", LOCATORS, LOCATORS, EMPTY);
generateLocators();
handler.endElement("", LOCATORS, LOCATORS);
}
/**
* Generates XML for the distributed system's locators
*/
private void generateLocators() throws SAXException {
DistributionLocator[] locators = this.system.getDistributionLocators();
for (int i = 0; i < locators.length; i++) {
generateLocator(locators[i].getConfig());
}
}
/**
* Generates XML for a locator
*/
private void generateLocator(DistributionLocatorConfig config) throws SAXException {
AttributesImpl atts = new AttributesImpl();
atts.addAttribute("", "", PORT, "", String.valueOf(config.getPort()));
handler.startElement("", LOCATOR, LOCATOR, atts);
generateEntityConfig(config);
handler.endElement("", LOCATOR, LOCATOR);
}
/**
* Generates XML for attributes common to all managed entities.
*/
private void generateEntityConfig(ManagedEntityConfig config) throws SAXException {
String host = config.getHost();
if (host != null) {
handler.startElement("", HOST, HOST, EMPTY);
handler.characters(host.toCharArray(), 0, host.length());
handler.endElement("", HOST, HOST);
}
String remoteCommand = config.getRemoteCommand();
if (remoteCommand != null) {
handler.startElement("", REMOTE_COMMAND, REMOTE_COMMAND, EMPTY);
handler.characters(remoteCommand.toCharArray(), 0, remoteCommand.length());
handler.endElement("", REMOTE_COMMAND, REMOTE_COMMAND);
}
String workingDirectory = config.getWorkingDirectory();
if (workingDirectory != null) {
handler.startElement("", WORKING_DIRECTORY, WORKING_DIRECTORY, EMPTY);
handler.characters(workingDirectory.toCharArray(), 0, workingDirectory.length());
handler.endElement("", WORKING_DIRECTORY, WORKING_DIRECTORY);
}
String productDirectory = config.getProductDirectory();
if (productDirectory != null) {
handler.startElement("", PRODUCT_DIRECTORY, PRODUCT_DIRECTORY, EMPTY);
handler.characters(productDirectory.toCharArray(), 0, productDirectory.length());
handler.endElement("", PRODUCT_DIRECTORY, PRODUCT_DIRECTORY);
}
}
/**
* Generates XML for the SSL configuration of the distributed system.
*/
private void generateSSL() throws SAXException {
DistributedSystemConfig config = this.system.getConfig();
boolean sslEnabled = config.isSSLEnabled();
if (!sslEnabled) {
return;
}
AttributesImpl atts = new AttributesImpl();
atts.addAttribute("", "", AUTHENTICATION_REQUIRED, "",
String.valueOf(config.isSSLAuthenticationRequired()));
handler.startElement("", SSL, SSL, atts);
String protocols = config.getSSLProtocols();
if (protocols != null) {
handler.startElement("", PROTOCOLS, PROTOCOLS, EMPTY);
handler.characters(protocols.toCharArray(), 0, protocols.length());
handler.endElement("", PROTOCOLS, PROTOCOLS);
}
String ciphers = config.getSSLCiphers();
if (ciphers != null) {
handler.startElement("", CIPHERS, CIPHERS, EMPTY);
handler.characters(ciphers.toCharArray(), 0, ciphers.length());
handler.endElement("", CIPHERS, CIPHERS);
}
Properties sslProps = config.getSSLProperties();
for (Iterator iter = sslProps.entrySet().iterator(); iter.hasNext();) {
Map.Entry entry = (Map.Entry) iter.next();
String key = (String) entry.getKey();
String value = (String) entry.getValue();
handler.startElement("", PROPERTY, PROPERTY, EMPTY);
handler.startElement("", KEY, KEY, EMPTY);
handler.characters(key.toCharArray(), 0, key.length());
handler.endElement("", KEY, KEY);
handler.startElement("", VALUE, VALUE, EMPTY);
handler.characters(value.toCharArray(), 0, value.length());
handler.endElement("", VALUE, VALUE);
handler.endElement("", PROPERTY, PROPERTY);
}
handler.endElement("", SSL, SSL);
}
/**
* Generates an XML representation of the <code>CacheServer</code>s in the distributed system.
*/
private void generateCacheServers() throws SAXException, AdminException {
CacheServer[] servers = this.system.getCacheServers();
for (int i = 0; i < servers.length; i++) {
generateCacheServer(servers[i].getConfig());
}
}
/**
* Generates an XML representation of a <code>CacheServerConfig</code>.
*/
private void generateCacheServer(CacheServerConfig config) throws SAXException {
handler.startElement("", CACHE_SERVER, CACHE_SERVER, EMPTY);
generateEntityConfig(config);
String classpath = config.getClassPath();
if (classpath != null) {
handler.startElement("", CLASSPATH, CLASSPATH, EMPTY);
handler.characters(classpath.toCharArray(), 0, classpath.length());
handler.endElement("", CLASSPATH, CLASSPATH);
}
handler.endElement("", CACHE_SERVER, CACHE_SERVER);
}
/**
* Keep track of the content handler for use during {@link #parse(String)}.
*/
public void setContentHandler(ContentHandler handler) {
this.handler = handler;
}
public ContentHandler getContentHandler() {
return this.handler;
}
public ErrorHandler getErrorHandler() {
return this;
}
////////// Inherited methods that don't do anything //////////
public boolean getFeature(String name)
throws SAXNotRecognizedException, SAXNotSupportedException {
return false;
}
public void setFeature(String name, boolean value)
throws SAXNotRecognizedException, SAXNotSupportedException {
}
public Object getProperty(String name)
throws SAXNotRecognizedException, SAXNotSupportedException {
return null;
}
public void setProperty(String name, Object value)
throws SAXNotRecognizedException, SAXNotSupportedException {
}
public void setEntityResolver(EntityResolver resolver) {
}
public EntityResolver getEntityResolver() {
return this;
}
public void setDTDHandler(DTDHandler handler) {
}
public DTDHandler getDTDHandler() {
return null;
}
public void setErrorHandler(ErrorHandler handler) {
}
public void parse(String systemId) throws IOException, SAXException {
}
}