package org.jgroups.conf; import org.jgroups.logging.Log; import org.jgroups.logging.LogFactory; import org.jgroups.util.Util; import java.util.HashMap; import java.util.Iterator; import java.util.Map; /** * Parses and encapsulates the specification for 1 protocol of the protocol stack, e.g. * <code>UNICAST(timeout=5000)</code> * @author Bela Ban */ public class ProtocolConfiguration { private final String protocol_name; private String properties_str; private final Map<String, String> properties=new HashMap<String, String>(); public static final String protocol_prefix="org.jgroups.protocols"; public static final Log log=LogFactory.getLog(ProtocolConfiguration.class); /** * Creates a new ProtocolConfiguration. * @param config_str The configuration specification for the protocol, e.g. * <pre>VERIFY_SUSPECT(timeout=1500)</pre> */ public ProtocolConfiguration(String config_str) throws Exception { int index=config_str.indexOf('('); // e.g. "UDP(in_port=3333)" int end_index=config_str.lastIndexOf(')'); if(index == -1) { protocol_name=config_str; properties_str=""; } else { if(end_index == -1) { throw new Exception("Configurator.ProtocolConfiguration(): closing ')' " + "not found in " + config_str + ": properties cannot be set !"); } else { properties_str=config_str.substring(index + 1, end_index); protocol_name=config_str.substring(0, index); } } parsePropertiesString(properties); } public ProtocolConfiguration(String protocol_name, Map<String,String> properties) { this.protocol_name=protocol_name; if(!properties.isEmpty()) { this.properties.putAll(properties); properties_str=propertiesToString(); } } public String getProtocolName() { return protocol_name; } public Map<String, String> getProperties() { return properties; } public String getPropertiesString() { return properties_str; } public Map<String, String> getOriginalProperties() throws Exception { Map<String, String> props=new HashMap<String, String>(); parsePropertiesString(props); return props; } public void substituteVariables() { for(Iterator<Map.Entry<String, String>> it=properties.entrySet().iterator(); it.hasNext();) { Map.Entry<String, String> entry=it.next(); String key=entry.getKey(); String val=entry.getValue(); String tmp=Util.substituteVariable(val); if(!val.equals(tmp)) { properties.put(key, tmp); } else { if(tmp.contains("${")) { if(log.isWarnEnabled()) log.warn("variable \"" + val + "\" in " + protocol_name + " could not be substituted; " + key + " is removed from properties"); it.remove(); } } } properties_str=propertiesToString(); } public String toString() { StringBuilder retval=new StringBuilder(); if(protocol_name == null) retval.append("<unknown>"); else retval.append(protocol_name); if(properties != null) retval.append("(" + Util.print(properties) + ')'); return retval.toString(); } public String propertiesToString() { return Util.printMapWithDelimiter(properties, ";"); } public String getProtocolString(boolean new_format) { return new_format? getProtocolStringNewXml() : getProtocolString(); } public String getProtocolString() { StringBuilder buf=new StringBuilder(protocol_name); if(!properties.isEmpty()) { boolean first=true; buf.append('('); for(Map.Entry<String,String> entry: properties.entrySet()) { String key=entry.getKey(); String val=entry.getValue(); if(first) first=false; else buf.append(';'); buf.append(getParameterString(key, val)); } buf.append(')'); } return buf.toString(); } public String getProtocolStringNewXml() { StringBuilder buf=new StringBuilder(protocol_name + ' '); if(!properties.isEmpty()) { boolean first=true; for(Map.Entry<String,String> entry: properties.entrySet()) { String key=entry.getKey(); String val=entry.getValue(); if(first) first=false; else buf.append(' '); buf.append(getParameterStringXml(key, val)); } } return buf.toString(); } protected static String getParameterString(String name, String value) { StringBuilder buf=new StringBuilder(name); if(value != null) buf.append('=').append(value); return buf.toString(); } protected static String getParameterStringXml(String name, String val) { StringBuilder buf=new StringBuilder(name); if(val != null) buf.append("=\"").append(val).append('\"'); return buf.toString(); } protected void parsePropertiesString(Map<String, String> properties) throws Exception { int index=0; /* "in_port=5555;out_port=6666" */ if(properties_str.length() > 0) { String[] components=properties_str.split(";"); for(String property : components) { String name, value; index=property.indexOf('='); if(index == -1) { throw new Exception("Configurator.ProtocolConfiguration(): '=' not found in " + property + " of " + protocol_name); } name=property.substring(0, index); value=property.substring(index + 1, property.length()); properties.put(name, value); } } } }