/*******************************************************************************
* Copyright (c) 2006-2010 eBay Inc. All Rights Reserved.
* 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
*******************************************************************************/
package org.ebayopensource.turmeric.runtime.common.impl.internal.config;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.ebayopensource.turmeric.runtime.common.pipeline.TransportOptions;
/**
* This class represents processed configuration of the message processor; common between client and server.
* <p>
* Note: Most ConfigHolder data is available in higher-level structures. Refer to ServiceDesc and related structures
* as the primary configuration in the public API for SOA framework.
* @author rmurphy
*
*/
public class MessageProcessorConfigHolder extends BaseConfigHolder {
// When adding properties, please ensure that copy(), dump(), and getters/setters
// are all covered for the new properties. Make sure setters call checkReadOnly().
// Hashmap indexed by binding, pointing to hashmap indexed by XML type.
private Map<String, Map<String, CustomSerializerConfig>> m_serializerMap
= new HashMap<String, Map<String, CustomSerializerConfig>>();
private Map<String, Map<String, TypeConverterConfig>> m_converterMap
= new HashMap<String, Map<String, TypeConverterConfig>>();
// Pipeline config, data binding config, protocol processor
private String m_requestPipelineClassName;
private String m_responsePipelineClassName;
private String m_requestDispatcherClassName;
private String m_responseDispatcherClassName;
private List<FrameworkHandlerConfig> m_loggingHandlers = new ArrayList<FrameworkHandlerConfig>();
private List<HandlerConfig> m_requestHandlers;
private List<HandlerConfig> m_responseHandlers;
private PipelineTreeConfig m_requestPipelineTree;
private PipelineTreeConfig m_responsePipelineTree;
private Map<String, SerializerConfig> m_dataBindings = new HashMap<String, SerializerConfig> ();
private List<ProtocolProcessorConfig> m_protocolProcessors = new ArrayList<ProtocolProcessorConfig> ();
private Map<String, String> m_transportClasses = new HashMap<String, String> ();
private Map<String, TransportOptions> m_transportOptions = new HashMap<String, TransportOptions> ();
private Map<String, Map<String, String>> m_transportHeaderOptions = new HashMap<String, Map<String, String>>();
private String m_errorMappingClass;
private String m_errorDataProviderClass;
private String m_configFilename;
private String m_groupFilename;
private static final char NL = '\n';
/*
* Safe copy method.
* @return a new object with a safe copy of the original data
*/
public MessageProcessorConfigHolder copy() {
//
// Current object copy pattern:
// When read-only: Gets of complex properties return full deep copy so subsequent caller modifications do not
// alter the source object's state. Sets are not allowed on any properties.
// When writeable: Gets return simple or complex objects directly, and they are alterable. Sets are
// accepted directly on all properties.
// Clone of a read-only object: Produces a new deep copy that starts out life writeable. It can be locked
// down subsequently to become a read-only object if desired, and will remain a full independent copy from
// the original.
MessageProcessorConfigHolder newCH = new MessageProcessorConfigHolder();
newCH.m_readOnly = false;
newCH.m_requestPipelineClassName = m_requestPipelineClassName;
newCH.m_responsePipelineClassName = m_responsePipelineClassName;
newCH.m_requestDispatcherClassName = m_requestDispatcherClassName;
newCH.m_responseDispatcherClassName = m_responseDispatcherClassName;
if (m_loggingHandlers != null) {
newCH.m_loggingHandlers = copyLoggingHandlers(m_loggingHandlers);
}
newCH.m_errorMappingClass = m_errorMappingClass;
newCH.m_errorDataProviderClass = m_errorDataProviderClass;
newCH.m_configFilename = m_configFilename;
newCH.m_groupFilename = m_groupFilename;
// Copy the following deep structures.
newCH.m_serializerMap = copyCustomSerializers(m_serializerMap);
newCH.m_converterMap = copyTypeConverters(m_converterMap);
newCH.m_requestPipelineTree = ConfigUtils.copyPipelineList(m_requestPipelineTree);
if (m_requestPipelineTree != null) {
newCH.m_requestHandlers = flattenTree(m_requestPipelineTree);
}
newCH.m_responsePipelineTree = ConfigUtils.copyPipelineList(m_responsePipelineTree);
if (m_responsePipelineTree != null) {
newCH.m_responseHandlers = flattenTree(m_responsePipelineTree);
}
newCH.m_dataBindings = copyDataBindings(m_dataBindings);
if (m_protocolProcessors != null) {
newCH.m_protocolProcessors = copyProcessorConfigList(m_protocolProcessors);
}
if (m_transportClasses != null) {
newCH.m_transportClasses = new HashMap<String, String>(m_transportClasses);
}
newCH.m_transportOptions = copyTransportOptions(m_transportOptions);
newCH.m_transportHeaderOptions = copyTransportHeaderOptions(m_transportHeaderOptions);
return newCH;
}
/**
* Deep-copies the local transport header options into another map.
* @return the newly-created map with a copy of the local transport header options.
*/
private Map<String, Map<String, String>> copyTransportHeaderOptions(Map<String, Map<String, String>> transportHeaderOptions) {
if (transportHeaderOptions == null) {
return null;
}
Map<String, Map<String, String>> newTransportHeaderOptions =
new HashMap<String, Map<String, String>>(transportHeaderOptions.size());
for (Map.Entry<String, Map<String, String>> transportHeaderOptionsMapEntry : transportHeaderOptions.entrySet()) {
newTransportHeaderOptions.put(transportHeaderOptionsMapEntry.getKey(),
new HashMap<String, String>(transportHeaderOptionsMapEntry.getValue()));
}
return newTransportHeaderOptions;
}
private List<FrameworkHandlerConfig> copyLoggingHandlers(List<FrameworkHandlerConfig> inHandlers) {
if (inHandlers == null) {
return null;
}
List<FrameworkHandlerConfig> outHandlers = new ArrayList<FrameworkHandlerConfig>();
for (FrameworkHandlerConfig inHandler : inHandlers) {
FrameworkHandlerConfig outHandler = ConfigUtils.copyFrameworkHandlerConfig(inHandler);
outHandlers.add(outHandler);
}
return outHandlers;
}
private List<ProtocolProcessorConfig> copyProcessorConfigList(List<ProtocolProcessorConfig> inList) {
if (inList == null) {
return null;
}
List<ProtocolProcessorConfig> outList = new ArrayList<ProtocolProcessorConfig>();
for (int i = 0; i < inList.size(); i++) {
outList.add(ConfigUtils.copyProcessorConfig(inList.get(i)));
}
return outList;
}
private Map<String, TransportOptions> copyTransportOptions(Map<String, TransportOptions> inMap) {
if (inMap == null) {
return null;
}
Map<String, TransportOptions> outMap = new HashMap<String, TransportOptions>();
for (Map.Entry<String, TransportOptions> entry : inMap.entrySet()) {
String key = entry.getKey();
TransportOptions inTC = entry.getValue();
TransportOptions outTC = ConfigUtils.copyTransportOptions(inTC);
outMap.put(key, outTC);
}
return outMap;
}
private HashMap<String, CustomSerializerConfig> copyOneSerializerMap(Map<String, CustomSerializerConfig> inMap) {
if (inMap == null) {
return null;
}
HashMap<String, CustomSerializerConfig> outMap = new HashMap<String, CustomSerializerConfig>();
for (Map.Entry<String, CustomSerializerConfig> entry : inMap.entrySet()) {
String key = entry.getKey();
CustomSerializerConfig inCS = entry.getValue();
CustomSerializerConfig outCS = ConfigUtils.copyCustomSerializer(inCS);
outMap.put(key, outCS);
}
return outMap;
}
private Map<String, Map<String, CustomSerializerConfig>> copyCustomSerializers(Map<String, Map<String, CustomSerializerConfig>> inMap) {
if (inMap == null) {
return null;
}
HashMap<String, Map<String, CustomSerializerConfig>> outMap = new HashMap<String, Map<String, CustomSerializerConfig>>();
for (Map.Entry<String, Map<String, CustomSerializerConfig>> entry : inMap.entrySet()) {
String key = entry.getKey();
Map<String, CustomSerializerConfig> inOneMap = entry.getValue();
Map<String, CustomSerializerConfig> outOneMap = copyOneSerializerMap(inOneMap);
outMap.put(key, outOneMap);
}
return outMap;
}
private Map<String, TypeConverterConfig> copyOneTypeConverterMap(Map<String, TypeConverterConfig> inMap) {
if (inMap == null) {
return null;
}
HashMap<String, TypeConverterConfig> outMap = new HashMap<String, TypeConverterConfig>();
for (Map.Entry<String, TypeConverterConfig> entry : inMap.entrySet()) {
String key = entry.getKey();
TypeConverterConfig inTC = entry.getValue();
TypeConverterConfig outTC = ConfigUtils.copyTypeConverter(inTC);
outMap.put(key, outTC);
}
return outMap;
}
private Map<String, SerializerConfig> copyDataBindings(Map<String, SerializerConfig> inBindings) {
if (inBindings == null) {
return null;
}
Map<String, SerializerConfig> outBindings = new HashMap<String, SerializerConfig>();
for (Map.Entry<String, SerializerConfig> entry : inBindings.entrySet()) {
String key = entry.getKey();
SerializerConfig inSC = entry.getValue();
SerializerConfig outSC = ConfigUtils.copySerializerConfig(inSC);
outBindings.put(key, outSC);
}
return outBindings;
}
private Map<String, Map<String, TypeConverterConfig>> copyTypeConverters(Map<String, Map<String, TypeConverterConfig>> inMap) {
if (inMap == null) {
return null;
}
Map<String, Map<String, TypeConverterConfig>> outMap = new HashMap<String, Map<String, TypeConverterConfig>>();
for (Map.Entry<String, Map<String, TypeConverterConfig>> entry : inMap.entrySet()) {
String key = entry.getKey();
Map<String, TypeConverterConfig> inOneMap = entry.getValue();
Map<String, TypeConverterConfig> outOneMap = copyOneTypeConverterMap(inOneMap);
outMap.put(key, outOneMap);
}
return outMap;
}
/**
* Get the configured map of custom serializers.
* @param bindingName the name of the binding whose map is to be retrieved.
* @return the serializer map for the data binding given by bindingName.
*/
public Map<String, CustomSerializerConfig> getCustomSerializerMap(String bindingName) {
Map<String, CustomSerializerConfig> retMap = m_serializerMap.get(bindingName);
if (retMap == null) {
retMap = new HashMap<String, CustomSerializerConfig>();
m_serializerMap.put(bindingName, retMap);
}
if (isReadOnly()) {
return copyOneSerializerMap(retMap);
}
return retMap;
}
/**
* Get the configured map of type converters.
* @param bindingName the name of the binding whose map is to be retrieved.
* @return the type converter map for the data binding given by bindingName.
*/
public Map<String, TypeConverterConfig> getTypeConverterMap(String bindingName) {
Map<String, TypeConverterConfig> retMap = m_converterMap.get(bindingName);
if (retMap == null) {
retMap = new HashMap<String, TypeConverterConfig>();
m_converterMap.put(bindingName, retMap);
}
if (isReadOnly()) // call recursively and return a copy.
return copyOneTypeConverterMap(retMap);
return retMap;
}
/**
* @return the request pipeline class name
*/
public String getRequestPipelineClassName() {
return m_requestPipelineClassName;
}
/**
* Set the request pipeline class name.
* @param requestPipelineClassName the class name to set
*/
public void setRequestPipelineClassName(String requestPipelineClassName) {
checkReadOnly();
this.m_requestPipelineClassName = requestPipelineClassName;
}
/**
* @return the response pipeline class name.
*/
public String getResponsePipelineClassName() {
return m_responsePipelineClassName;
}
/**
* Set the response pipeline class name.
* @param responsePipelineClassName the class name to set
*/
public void setResponsePipelineClassName(String responsePipelineClassName) {
checkReadOnly();
this.m_responsePipelineClassName = responsePipelineClassName;
}
/**
* @return the request dispatcher class name.
*/
public String getRequestDispatcherClassName() {
return m_requestDispatcherClassName;
}
/**
* Set the request dispatcher class name.
* @param requestDispatcherClassName the class name to set
*/
public void setRequestDispatcherClassName(String requestDispatcherClassName) {
checkReadOnly();
this.m_requestDispatcherClassName = requestDispatcherClassName;
}
/**
* @return the response dispatcher class name.
*/
public String getResponseDispatcherClassName() {
return m_responseDispatcherClassName;
}
/**
* Set the response dispatcher class name.
* @param responseDispatcherClassName the class name to set
*/
public void setResponseDispatcherClassName(String responseDispatcherClassName) {
checkReadOnly();
this.m_responseDispatcherClassName = responseDispatcherClassName;
}
/**
* @return the configured list of logging handler configuration entries.
*/
public List<FrameworkHandlerConfig> getLoggingHandlers() {
if (isReadOnly() && m_loggingHandlers != null) {
return copyLoggingHandlers(m_loggingHandlers);
}
return m_loggingHandlers;
}
/**
* @return the configured list of request handler configuration entries.
*/
public List<HandlerConfig> getRequestHandlers() {
if (isReadOnly() && m_requestHandlers != null) {
return new ArrayList<HandlerConfig>(m_requestHandlers);
}
return m_requestHandlers;
}
/**
* @return the configured list of response handler configuration entries.
*/
public List<HandlerConfig> getResponseHandlers() {
if (isReadOnly() && m_responseHandlers != null) {
return new ArrayList<HandlerConfig>(m_responseHandlers);
}
return m_responseHandlers;
}
/**
* @return the m_requestPipelineTree
* @uml.property name="m_requestPipelineTree"
*/
PipelineTreeConfig getRequestPipelineTree() {
if (isReadOnly()) {
return ConfigUtils.copyPipelineList(m_requestPipelineTree);
}
return m_requestPipelineTree;
}
/**
* @param requestTree the m_requestPipelineTree to set
* @uml.property name="m_requestPipelineTree"
*/
void setRequestPipelineTree(PipelineTreeConfig requestTree) {
checkReadOnly();
m_requestPipelineTree = requestTree;
m_requestHandlers = flattenTree(requestTree);
}
/**
* @return the m_responsePipelineTree
* @uml.property name="m_responsePipelineTree"
*/
PipelineTreeConfig getResponsePipelineTree() {
if (isReadOnly()) {
return ConfigUtils.copyPipelineList(m_responsePipelineTree);
}
return m_responsePipelineTree;
}
/**
* @param responseTree the m_responsePipelineTree to set
* @uml.property name="m_responsePipelineTree"
*/
void setResponsePipelineTree(PipelineTreeConfig responseTree) {
checkReadOnly();
m_responsePipelineTree = responseTree;
m_responseHandlers = flattenTree(responseTree);
}
/**
* @return the configured map of data binding configurations.
*/
public Map<String, SerializerConfig> getDataBindings() {
if (isReadOnly()) {
return copyDataBindings(m_dataBindings);
}
return m_dataBindings;
}
/**
* @return the ocnfigured list of protocol processor configurations.
*/
public List<ProtocolProcessorConfig> getProtocolProcessors() {
if (isReadOnly()) {
return new ArrayList<ProtocolProcessorConfig>(m_protocolProcessors);
}
return m_protocolProcessors;
}
/**
* @return the configured map of transport names and their associated options.
*/
public Map<String, TransportOptions> getTransportOptions() {
if (isReadOnly()) {
return copyTransportOptions(m_transportOptions);
}
return m_transportOptions;
}
/**
* Getter for the transport header options
* @return the configured map of transport names and their associated header options.
*/
public Map<String, Map<String, String>> getTransportHeaderOptions() {
if (isReadOnly()) {
return copyTransportHeaderOptions(m_transportHeaderOptions);
}
return m_transportHeaderOptions;
}
/**
* @return the configured map of transport names and their associated class names.
*/
public Map<String, String> getTransportClasses() {
if (isReadOnly()) {
return new HashMap<String, String>(m_transportClasses);
}
return m_transportClasses;
}
/**
* @return the name of the server-side error data provider class (which implements the ErrorDataProvider interface).
*/
public String getErrorDataProviderClass() {
return m_errorDataProviderClass;
}
/**
* Set the name of the server-side error data provider class.
* @param errorDataProviderClass the class name to set
*/
public void setErrorDataProviderClass(String errorDataProviderClass) {
checkReadOnly();
m_errorDataProviderClass = errorDataProviderClass;
}
/**
* @return the name of the server-side error mapping class (which implements the ErrorMapper interface).
*/
public String getErrorMappingClass() {
return m_errorMappingClass;
}
/**
* Set the name of the server-side error mapping class.
* @param errorMapClass the class name to set
*/
public void setErrorMappingClass(String errorMapClass) {
checkReadOnly();
m_errorMappingClass = errorMapClass;
}
/**
* @return the filename of the associated configuration.
*/
public String getConfigFilename() {
return m_configFilename;
}
/**
* Set the filename of the associated configuration.
* @param filename the filename to set
*/
public void setConfigFilename(String filename) {
m_configFilename = filename;
}
/**
* @return the filename of the referenced group configuration, or null if none.
*/
public String getGroupFilename() {
return m_groupFilename;
}
// TODO - it's possible to have "incomplete" handlers/chains from the group level entry. Check for these and remove or error out.
private static ArrayList<HandlerConfig> flattenTree(PipelineTreeConfig pipelineTree) {
ArrayList<HandlerConfig> outList = new ArrayList<HandlerConfig>();
if (pipelineTree == null) {
return outList;
}
List elements = pipelineTree.getHandlerOrChain();
for (Object element : elements) {
if (element instanceof HandlerConfig) {
outList.add((HandlerConfig)element);
} else if (element instanceof ChainConfig) {
ChainConfig chain = (ChainConfig) element;
for (HandlerConfig handler : chain.getHandler()) {
outList.add(handler);
}
}
}
return outList;
}
/*
* Provide a user-readable description of the configuration into a StringBuffer.
* @param sb the StringBuffer into which to write the description
*/
public void dump(StringBuffer sb) {
if (m_errorMappingClass != null) {
sb.append("errorMappingClass="+m_errorMappingClass+NL);
}
if (m_errorDataProviderClass != null) {
sb.append("errorDataProviderClass="+m_errorDataProviderClass+NL);
}
if (m_serializerMap != null) {
dumpSerializerMap(sb, m_serializerMap);
}
if (m_converterMap != null) {
dumpTypeConverters(sb, m_converterMap);
}
sb.append("========== Pipeline =========="+NL);
if (m_requestPipelineClassName != null) {
sb.append("requestPipelineClassName="+m_requestPipelineClassName+NL);
}
if (m_responsePipelineClassName != null) {
sb.append("responsePipelineClassName="+m_responsePipelineClassName+NL);
}
if (m_requestDispatcherClassName != null) {
sb.append("requestDispatcherClassName="+m_requestDispatcherClassName+NL);
}
if (m_responseDispatcherClassName != null) {
sb.append("responseDispatcherClassName="+m_responseDispatcherClassName+NL);
}
if (m_loggingHandlers != null && !m_loggingHandlers.isEmpty()) {
sb.append("Logging Handlers:" + NL);
for (FrameworkHandlerConfig handler : m_loggingHandlers) {
sb.append("Class name: " + handler.getClassName() + NL);
ConfigUtils.dumpStringMap(sb, handler.getOptions(), "\t");
}
}
if (m_requestPipelineTree != null) {
sb.append("Request Pipeline Tree:"+NL);
dumpPipelineTree(sb, m_requestPipelineTree);
}
if (m_requestHandlers != null) {
sb.append("Request Handler List:"+NL);
for (HandlerConfig handler : m_requestHandlers)
dumpHandler(sb, handler, "");
}
if (m_responsePipelineTree != null) {
sb.append("Response Pipeline Tree:"+NL);
dumpPipelineTree(sb, m_responsePipelineTree);
}
if (m_responseHandlers != null) {
sb.append("Response Handler List:"+NL);
for (HandlerConfig handler : m_responseHandlers)
dumpHandler(sb, handler, "");
}
sb.append("========== Data Bindings =========="+NL);
if (m_dataBindings != null) {
sb.append("Data Bindings:"+NL);
List<String> dataBindings = new ArrayList<String>(m_dataBindings.keySet());
Collections.sort(dataBindings);
for(String key : dataBindings) {
SerializerConfig value = m_dataBindings.get(key);
dumpDataBinding(sb, value);
}
}
if (m_protocolProcessors != null) {
sb.append("========== Protocol Processors =========="+NL);
for (ProtocolProcessorConfig pp : m_protocolProcessors) {
dumpProtocolProcessor(sb, pp);
}
}
sb.append("========== Transports ==========" + NL);
if (m_transportClasses != null) {
sb.append("Transports:" + NL);
List<String> transports = new ArrayList<String>(m_transportClasses.keySet());
Collections.sort(transports);
for (String key : transports) {
String transportClass = m_transportClasses.get(key);
TransportOptions options = m_transportOptions.get(key);
Map<String, String> headerOptions = m_transportHeaderOptions.get(key);
dumpTransport(sb, key, transportClass, options, headerOptions);
}
}
}
private void dumpSerializerMap(StringBuffer sb, Map<String, Map<String, CustomSerializerConfig>> serMap) {
sb.append("========== Custom Serializers =========="+NL);
List<String> serKeys = new ArrayList<String>(serMap.keySet());
Collections.sort(serKeys);
for(String serkey : serKeys) {
Map<String, CustomSerializerConfig> perDataBindingMap = serMap.get(serkey);
sb.append("Binding=" + serkey + NL);
List<String> javaTypeNameKeys = new ArrayList<String> (perDataBindingMap.keySet());
Collections.sort(javaTypeNameKeys);
for(String javaTypeNameKey : javaTypeNameKeys) {
//String javaTypeName = entry2.getKey();
CustomSerializerConfig cs = perDataBindingMap.get(javaTypeNameKey);
sb.append("\tcustomSer java type="+cs.getJavaTypeName());
if (cs.getSerializerClassName() != null) {
sb.append(NL+"\t\tser="+cs.getSerializerClassName());
}
if (cs.getDeserializerClassName() != null) {
sb.append(NL+"\t\tser="+cs.getDeserializerClassName());
}
sb.append(NL);
}
}
}
private void dumpTypeConverters(StringBuffer sb, Map<String, Map<String, TypeConverterConfig>> convMap) {
sb.append("========== Type converters =========="+NL);
List<String> convKeys = new ArrayList<String>(convMap.keySet());
Collections.sort(convKeys);
for(String key : convKeys) {
Map<String, TypeConverterConfig> dataBindingMap = convMap.get(key);
sb.append("Binding=" + key + NL);
List<String> dataKeys = new ArrayList<String> (dataBindingMap.keySet());
Collections.sort(dataKeys);
for(String dataKey : dataKeys) {
TypeConverterConfig tc = dataBindingMap.get(dataKey);
sb.append("\tcustomSer bound type="+tc.getBoundJavaTypeName());
if (tc.getValueJavaTypeName() != null) {
sb.append(NL+"\t\tvalue type="+tc.getValueJavaTypeName());
}
if (tc.getTypeConverterClassName() != null) {
sb.append(NL+"\t\type conv="+tc.getTypeConverterClassName());
}
if (tc.getXmlTypeName() != null) {
sb.append(NL+"\t\tXML type="+tc.getXmlTypeName());
}
sb.append(NL);
}
}
}
private static void dumpProtocolProcessor(StringBuffer sb, ProtocolProcessorConfig pp) {
sb.append("{name="+pp.getName());
if (pp.getVersion() != null)
sb.append(" version="+pp.getVersion());
if (pp.getIndicator() != null) {
if (pp.getIndicator().getURLPattern() != null) {
sb.append(NL+"\turl-indicator="+pp.getIndicator().getURLPattern());
}
if (pp.getIndicator().getTransportHeader() != null) {
sb.append(NL+"\ttransport-indicator="+ConfigUtils.NVToString(pp.getIndicator().getTransportHeader()));
}
}
if (pp.getClassName() != null) {
sb.append(NL+"\tclassname="+pp.getClassName());
}
sb.append("}"+NL);
}
private static void dumpDataBinding(StringBuffer sb, SerializerConfig db) {
sb.append("\tname="+db.getName());
if (db.getMimeType() != null) {
sb.append(" mimeType=" + db.getMimeType());
}
if (db.getSerializerFactoryClassName() != null) {
sb.append(NL+"\t\tserFactory="+db.getSerializerFactoryClassName());
}
if (db.getDeserializerFactoryClassName() != null) {
sb.append(NL+"\t\tdeserFactory="+db.getDeserializerFactoryClassName());
}
if (db.getOptions() != null && !db.getOptions().isEmpty()) {
sb.append(NL+"\t\tOptions:"+NL);
ConfigUtils.dumpStringMap(sb, db.getOptions(), "\t\t\t");
}
sb.append(NL);
}
private static void dumpTransport(StringBuffer sb, String name, String transportClass, TransportOptions options, Map<String, String> headerOptions) {
sb.append("\tname="+name);
if (transportClass != null) {
sb.append(" class=" + transportClass + NL);
}
if (options != null) {
ConfigUtils.dumpTransportOptions(sb, options, "\t\t");
}
sb.append(NL);
if (headerOptions != null && !headerOptions.isEmpty()) {
sb.append("headerOptions=").append(headerOptions.toString());
sb.append(NL);
}
}
private static void dumpHandler(StringBuffer sb, HandlerConfig h, String prefix) {
sb.append(prefix+"\t{name="+h.getName());
if (h.getClassName() != null) {
sb.append(",class=" + h.getClassName());
}
if (h.getPresence() != null) {
sb.append(",presence="+h.getPresence().toString());
}
if (h.isContinueOnError() != null) {
sb.append(",continue="+h.isContinueOnError().toString());
}
if (h.isRunOnError() != null) {
sb.append(",run="+h.isRunOnError().toString());
}
sb.append("}"+NL);
ConfigUtils.dumpOptionList(sb, h.getOptions(), prefix);
}
private static void dumpPipelineTree(StringBuffer sb, PipelineTreeConfig pipelineTree) {
List elements = pipelineTree.getHandlerOrChain();
for (Object element : elements) {
if (element instanceof HandlerConfig) {
dumpHandler(sb, (HandlerConfig) element, "");
} else if (element instanceof ChainConfig) {
ChainConfig chain = (ChainConfig) element;
sb.append("\tChain="+chain.getName());
if (chain.getPresence() != null)
sb.append(" presence="+chain.getPresence().toString());
sb.append(NL);
for (HandlerConfig handler : chain.getHandler()) {
sb.append("\t");
dumpHandler(sb, handler, "");
}
}
}
}
}