001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.camel.impl;
018
019 import java.util.ArrayList;
020 import java.util.Collections;
021 import java.util.LinkedHashMap;
022 import java.util.List;
023 import java.util.Map;
024 import java.util.Set;
025
026 import org.apache.camel.CamelContext;
027 import org.apache.camel.Component;
028 import org.apache.camel.EndpointConfiguration;
029 import org.apache.camel.TypeConverter;
030 import org.apache.camel.util.UnsafeUriCharactersEncoder;
031
032 /**
033 * Fallback implementation of {@link EndpointConfiguration} used by {@link Component}s
034 * that did not yet define a configuration type.
035 */
036 public final class MappedEndpointConfiguration extends DefaultEndpointConfiguration {
037 // TODO: need 2 sets to differentiate between user keys and fixed keys
038 private Map<String, Object> params = new LinkedHashMap<String, Object>();
039
040 MappedEndpointConfiguration(CamelContext camelContext) {
041 super(camelContext);
042 }
043
044 MappedEndpointConfiguration(CamelContext camelContext, String uri) {
045 super(camelContext);
046 setURI(uri);
047 }
048
049 @SuppressWarnings("unchecked")
050 public <T> T getParameter(String name) {
051 return (T) params.get(name);
052 }
053
054 @Override
055 public <T> void setParameter(String name, T value) {
056 params.put(name, value);
057 }
058
059 @Override
060 public boolean equals(Object other) {
061 if (other == null || !(other instanceof MappedEndpointConfiguration)) {
062 return false;
063 }
064 // if all parameters including scheme are the same, the component and uri must be the same too
065 return this == other || (this.getClass() == other.getClass() && params.equals(((MappedEndpointConfiguration)other).params));
066 }
067
068 @Override
069 public int hashCode() {
070 return params.hashCode();
071 }
072
073 @Override
074 protected void parseURI() {
075 ConfigurationHelper.populateFromURI(getCamelContext(), this, new ConfigurationHelper.ParameterSetter() {
076 @Override
077 public <T> void set(CamelContext camelContext, EndpointConfiguration config, String name, T value) {
078 if (name != null && value != null) {
079 params.put(name, value);
080 }
081 }
082 });
083 }
084
085 @Override
086 public String toUriString(UriFormat format) {
087 Set<Map.Entry<String, Object>> entries = params.entrySet();
088 List<String> queryParams = new ArrayList<String>();
089
090 String scheme = null;
091 String schemeSpecificPart = null;
092 String authority = null;
093 String path = null;
094 String fragment = null;
095
096 TypeConverter converter = getCamelContext().getTypeConverter();
097
098 // Separate URI values from query parameters
099 for (Map.Entry<String, Object> entry : entries) {
100 String key = entry.getKey();
101 Object value = entry.getValue();
102 if (key.equals(EndpointConfiguration.URI_SCHEME)) {
103 scheme = converter.convertTo(String.class, value);
104 } else if (key.equals(EndpointConfiguration.URI_SCHEME_SPECIFIC_PART)) {
105 schemeSpecificPart = converter.convertTo(String.class, value);
106 } else if (key.equals(EndpointConfiguration.URI_AUTHORITY)) {
107 authority = converter.convertTo(String.class, value);
108 } else if (key.equals(EndpointConfiguration.URI_USER_INFO)) {
109 // ignore, part of authority
110 } else if (key.equals(EndpointConfiguration.URI_HOST)) {
111 // ignore, part of authority
112 } else if (key.equals(EndpointConfiguration.URI_PORT)) {
113 // ignore, part of authority
114 } else if (key.equals(EndpointConfiguration.URI_PATH)) {
115 path = converter.convertTo(String.class, value);
116 } else if (key.equals(EndpointConfiguration.URI_QUERY)) {
117 // ignore, but this should not be the case, may be a good idea to log...
118 } else if (key.equals(EndpointConfiguration.URI_FRAGMENT)) {
119 fragment = converter.convertTo(String.class, value);
120 } else {
121 // convert to "param=value" format here, order will be preserved
122 if (value instanceof List) {
123 for (Object item : (List<?>)value) {
124 queryParams.add(key + "=" + UnsafeUriCharactersEncoder.encode(item.toString()));
125 }
126 } else {
127 queryParams.add(key + "=" + UnsafeUriCharactersEncoder.encode(value.toString()));
128 }
129 }
130 }
131
132 Collections.sort(queryParams);
133 String q = "";
134 for (String entry : queryParams) {
135 q += q.length() == 0 ? "" : "&";
136 q += entry;
137 }
138
139 StringBuffer u = new StringBuffer(64);
140 if (scheme != null) {
141 u.append(scheme); // SHOULD NOT be null
142 u.append(":");
143 }
144 if (authority != null) {
145 u.append("//");
146 u.append(authority);
147 u.append(path);
148 if (q.length() > 0) {
149 u.append("?");
150 u.append(q);
151 }
152 if (fragment != null) {
153 u.append("#");
154 u.append(fragment);
155 }
156 } else {
157 // add leading // if not provided
158 if (!schemeSpecificPart.startsWith("//")) {
159 u.append("//");
160 }
161 u.append(schemeSpecificPart);
162 }
163 return u.toString();
164 }
165 }