/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package cameljamod; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.SortedMap; import java.util.TreeMap; import static cameljamod.JamodUriResolver.*; import java.net.URI; import org.apache.camel.Component; import org.apache.camel.Endpoint; import org.apache.camel.RuntimeCamelException; import org.apache.camel.impl.ComponentConfigurationSupport; import org.apache.camel.impl.ParameterConfiguration; import org.apache.camel.util.URISupport; import org.apache.camel.util.UnsafeUriCharactersEncoder; /** * * @author justin */ public class JamodComponentConfiguration extends ComponentConfigurationSupport { private static final SortedMap<String, ParameterConfiguration> CONFIGS = new TreeMap<String, ParameterConfiguration>(); private final Map<String, Object> values = new HashMap<String, Object>(); public static final String PROTOCOL_KEY = "protocol"; public static final String HOST_NAME_KEY = "hostName"; public static final String PORT_KEY = "port"; public static final String DATA_TYPE_KEY = "dataType"; public static final DATA_TYPES DEFAULT_DATA_TYPE = DATA_TYPES.register; public static final String DEFAULT_HOST = "localhost"; //TODO this should probably be a constant somewhere else as a default port. public static final Integer DEFAULT_PORT = Integer.valueOf(1024); public static final PROTOCOL DEFAULT_PROTOCOL = PROTOCOL.tcp; public static final String REFERENCE_ADDRESS_KEY = "referenceAddress"; public static final Integer DEFAULT_REFERENCE_ADDRESS = Integer.valueOf(0); public static final String CHANGES_ONLY_KEY = "changesOnly"; static { CONFIGS.put(DATA_TYPE_KEY, new ParameterConfiguration("dataType", DATA_TYPES.class)); CONFIGS.put(HOST_NAME_KEY, new ParameterConfiguration("hostName", String.class)); CONFIGS.put(PROTOCOL_KEY, new ParameterConfiguration("protocol", PROTOCOL.class)); CONFIGS.put(PORT_KEY, new ParameterConfiguration("port", Integer.TYPE)); CONFIGS.put("delay", new ParameterConfiguration("delay", Integer.TYPE)); CONFIGS.put(REFERENCE_ADDRESS_KEY, new ParameterConfiguration("referenceAddress", Integer.TYPE)); CONFIGS.put("initialDelay", new ParameterConfiguration("initialDelay", Integer.TYPE)); CONFIGS.put("count", new ParameterConfiguration("count", Integer.TYPE)); CONFIGS.put(CHANGES_ONLY_KEY, new ParameterConfiguration(CHANGES_ONLY_KEY, Boolean.TYPE)); CONFIGS.put(JamodEndpoint.SLAVE_ID, new ParameterConfiguration(JamodEndpoint.SLAVE_ID, Integer.TYPE)); } //This is a list of the parameters that are ignored in the uri building private static final Set<String> IGNORED_PARAMS = new HashSet<String>(); static { IGNORED_PARAMS.add(DATA_TYPE_KEY); IGNORED_PARAMS.add(PORT_KEY); IGNORED_PARAMS.add(PROTOCOL_KEY); IGNORED_PARAMS.add(REFERENCE_ADDRESS_KEY); IGNORED_PARAMS.add(HOST_NAME_KEY); } public static enum PROTOCOL { tcp, udp } public static enum DATA_TYPES { discreteInputs, coils, registers, register, inputRegisters, inputRegister } public JamodComponentConfiguration(Component component) { super(component); } public SortedMap<String, ParameterConfiguration> getParameterConfigurationMap() { return Collections.unmodifiableSortedMap(CONFIGS); } public Object getEndpointParameter(Endpoint endpoint, String name) throws RuntimeCamelException { //TODO implement this return null; } public void setEndpointParameter(Endpoint endpoint, String name, Object value) throws RuntimeCamelException { //TODO implement this } @Override public String getBaseUri() { return String.format("jamod:%s://%s:%s/%s/%s", getProtocol(), getHostName(), getPort(), getDataType(), getReferenceAddress()); } @Override public void setUriString(final String uriString) throws URISyntaxException { try { String newUriString; final String prefix = "jamod:"; if (uriString.startsWith(prefix)) { newUriString = uriString.substring(prefix.length()); } else { newUriString = uriString; } URI uri = URI.create(newUriString); String protocolFromUri = getProtocolFromUri(uri); if (protocolFromUri == null) { protocolFromUri = DEFAULT_PROTOCOL.toString(); } setParameter(PROTOCOL_KEY, PROTOCOL.valueOf(protocolFromUri)); setParameter(PORT_KEY, getPortFromUri(uri)); setParameter(HOST_NAME_KEY, getHostFromUri(uri)); String dataTypeFromUri = getDataTypeFromUri(uri); if (dataTypeFromUri == null) { dataTypeFromUri = DEFAULT_DATA_TYPE.toString(); } setParameter(DATA_TYPE_KEY, DATA_TYPES.valueOf(dataTypeFromUri)); setParameter(REFERENCE_ADDRESS_KEY, getReferenceFromUri(uri)); int idx = newUriString.indexOf('?'); Map<String, Object> newParameters = Collections.emptyMap(); if (idx >= 0) { String query = newUriString.substring(idx + 1); newParameters = URISupport.parseQuery(query, true); } for (Map.Entry<String, Object> entry : newParameters.entrySet()) { final String key = entry.getKey(); final Object value = entry.getValue(); if (key.equals(CHANGES_ONLY_KEY)) { setParameter(key, value.toString().equalsIgnoreCase("true") ? Boolean.TRUE : Boolean.FALSE); } else { setParameter(key, value); } } } catch (ArrayIndexOutOfBoundsException ex) { throw new URISyntaxException(uriString, ex.getMessage()); } } @Override public String getUriString() { List<String> queryParams = new ArrayList<String>(); for (Map.Entry<String, Object> entry : getParameters().entrySet()) { if (IGNORED_PARAMS.contains(entry.getKey())) { //These don't need to go in the output. continue; } String key = entry.getKey(); Object value = entry.getValue(); // convert to "param=value" format here, order will be preserved if (value instanceof List) { for (Object item : (List<?>) value) { queryParams.add(key + "=" + UnsafeUriCharactersEncoder.encode(item.toString())); } } else { queryParams.add(key + "=" + UnsafeUriCharactersEncoder.encode(value.toString())); } } Collections.sort(queryParams); StringBuilder builder = new StringBuilder(); String base = getBaseUri(); if (base != null) { builder.append(base); } String separator = "?"; for (String entry : queryParams) { builder.append(separator); builder.append(entry); separator = "&"; } return builder.toString(); } public PROTOCOL getProtocol() { PROTOCOL p = (PROTOCOL) getParameter(PROTOCOL_KEY); if (p == null) { p = DEFAULT_PROTOCOL; } return p; } public String getHostName() { String retVal = (String) getParameter(HOST_NAME_KEY); if (retVal == null) { retVal = DEFAULT_HOST; } return retVal; } public Integer getPort() { Integer retVal = (Integer) getParameter(PORT_KEY); if (retVal == null) { retVal = DEFAULT_PORT; } return retVal; } public DATA_TYPES getDataType() { DATA_TYPES retVal = (DATA_TYPES) getParameter(DATA_TYPE_KEY); if (retVal == null) { retVal = DEFAULT_DATA_TYPE; } return retVal; } public Integer getReferenceAddress() { Integer retVal = (Integer) getParameter(REFERENCE_ADDRESS_KEY); if (retVal == null) { return DEFAULT_REFERENCE_ADDRESS; } return retVal; } }