/*******************************************************************************
* 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.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* This class represents processed type mapping (serialization) configuration, which is 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 TypeMappingConfigHolder extends BaseConfigHolder {
private HashMap<String, OperationConfig> m_operations = new HashMap<String, OperationConfig>();
private HashMap<String, List<String>> m_xmlNSFromJavaPkg = new HashMap<String, List<String>>();
private static final char NL = '\n';
private HashSet<String> m_javaTypes = new HashSet<String>();
private boolean m_enableNamespaceFolding = false;
private boolean m_operationAdded = false;
/**
* Introduces additional fully qualified Java class names to store
* These class names can be important for serialization purposes
*
* @param type fully qualified Java class name
*/
public void addJavaTypes( String type ) {
m_javaTypes.add( type );
}
/**
*
* @return a collection of stored Java class names
*/
public Collection<String> getJavaTypes() {
return Collections.unmodifiableCollection( m_javaTypes );
}
/**
* @return the collection of all per-operation configuration.
*/
public Collection<OperationConfig> getOperations() {
return Collections.unmodifiableCollection(m_operations.values());
}
/**
* @return the Set of operation names in configuration.
*/
public Set<String> getOperationNames() {
return Collections.unmodifiableSet(m_operations.keySet());
}
/**
* Set the configuration of a particular operation by name.
* @param opname the name of the operation
* @param operation the operation-specific configuration to set
*/
void setOperation(String opname, OperationConfig operation) {
checkReadOnly();
m_operations.put(opname, operation);
}
/**
* @return the Java package-to-XML namespace mappings (used to drive JAXB serialization/deserialization)
*/
public Map<String,List<String>> getPackageToNsMap() {
// TODO: how do we make inner list unmodifiable ?
return Collections.unmodifiableMap(m_xmlNSFromJavaPkg);
}
/**
* Set a package-to-namespace mapping.
* @param javaType the Java classname from which to obtain a package name
* @param xmlNs the associated XML namespace
*/
void setXmlNamespaceFromJavaPackage(String javaType, String xmlNs) {
checkReadOnly();
List<String> nsList = m_xmlNSFromJavaPkg.get(javaType);
if (nsList == null) {
nsList = new ArrayList<String>();
m_xmlNSFromJavaPkg.put(javaType, nsList);
}
nsList.add(xmlNs);
}
public boolean getEnableNamespaceFolding() {
return m_enableNamespaceFolding;
}
public void setEnableNamespaceFolding(boolean flag) {
m_enableNamespaceFolding = flag;
}
public boolean getOperationAdded() {
return m_operationAdded;
}
public void setOperationAdded(boolean flag) {
m_operationAdded = flag;
}
/**
* Safe copy method.
* @return a new object with a safe copy of the original data
*/
public TypeMappingConfigHolder copy() {
TypeMappingConfigHolder newCH = new TypeMappingConfigHolder();
newCH.m_readOnly = false;
newCH.m_enableNamespaceFolding = m_enableNamespaceFolding;
newCH.m_operations = copyOperations(m_operations);
newCH.m_xmlNSFromJavaPkg = new HashMap<String,List<String>>();
for (String javaName : m_xmlNSFromJavaPkg.keySet()) {
List<String> xmlNsList = m_xmlNSFromJavaPkg.get(javaName);
for (String xmlNs: xmlNsList) {
newCH.setXmlNamespaceFromJavaPackage(javaName, xmlNs);
}
}
newCH.m_javaTypes = new HashSet<String>();
if(m_javaTypes != null && !m_javaTypes.isEmpty()) {
for(String type: m_javaTypes) {
newCH.m_javaTypes.add(type);
}
}
return newCH;
}
private HashMap<String, OperationConfig> copyOperations(HashMap<String, OperationConfig> inOpMap) {
if (inOpMap == null) {
return null;
}
HashMap<String, OperationConfig> outOpMap = new HashMap<String, OperationConfig>();
for (Map.Entry<String, OperationConfig> entry : inOpMap.entrySet()) {
String key = entry.getKey();
OperationConfig inOp = entry.getValue();
OperationConfig outOp = ConfigUtils.copyOperationConfig(inOp);
outOpMap.put(key, outOp);
}
return outOpMap;
}
/*
* 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) {
sb.append("========== Type Mappings ==========" + NL);
sb.append("nsFolding: " + m_enableNamespaceFolding + "\n");
List<String> operations = new ArrayList<String> (m_operations.keySet()) ;
Collections.sort(operations);
for (String opname : operations) {
//for (String opname : m_operations.keySet()) {
OperationConfig cfg = m_operations.get(opname);
sb.append("Operation: " + opname + NL);
if (cfg.getRequestMessage() != null)
dumpMessageType(sb, " Request", cfg.getRequestMessage());
if (cfg.getResponseMessage() != null)
dumpMessageType(sb, " Response", cfg.getResponseMessage());
if (cfg.getErrorMessage() != null)
dumpMessageType(sb, " Error", cfg.getErrorMessage());
if (cfg.getRequestHeader() != null && !cfg.getRequestHeader().isEmpty()) {
dumpHeaderList(sb, " Request headers:", " ", cfg.getRequestHeader());
}
if (cfg.getResponseHeader() != null && !cfg.getResponseHeader().isEmpty()) {
dumpHeaderList(sb, " Response headers:", " ", cfg.getResponseHeader());
}
}
sb.append("Package Info:" + NL);
List<String> javaNames = new ArrayList<String> (m_xmlNSFromJavaPkg.keySet()) ;
Collections.sort(javaNames);
for (String javaName : javaNames) {
//for (String javaName : m_xmlNSFromJavaPkg.keySet()) {
List<String> xmlNsList = m_xmlNSFromJavaPkg.get(javaName);
for (String xmlNs: xmlNsList) {
sb.append(" java="+javaName+" xml="+xmlNs+NL);
}
}
}
private void dumpHeaderList(StringBuffer sb, String heading, String prefix, List<MessageHeaderConfig> mhcList) {
sb.append(heading + NL);
for (MessageHeaderConfig mhc : mhcList) {
dumpMessageHeader(sb, prefix, mhc);
}
}
private void dumpMessageHeader(StringBuffer sb, String prefix, MessageHeaderConfig mhc) {
sb.append(prefix + "element: " + mhc.getXmlElementName() + ", java=" + mhc.getJavaTypeName() + " xml=" + mhc.getXmlTypeName() + NL);
}
private void dumpMessageType(StringBuffer sb, String type, MessageTypeConfig msg) {
sb.append(type + ": " + "java=" + msg.getJavaTypeName() + " xml=" + msg.getXmlTypeName());
if (msg.hasAttachment) {
sb.append(" has-attachment");
}
sb.append(NL);
}
}