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 */ 017package org.apache.camel.impl; 018 019import java.io.IOException; 020import java.net.URISyntaxException; 021import java.util.ArrayList; 022import java.util.Collections; 023import java.util.HashMap; 024import java.util.List; 025import java.util.Map; 026import java.util.Set; 027import java.util.SortedMap; 028 029import org.apache.camel.Component; 030import org.apache.camel.ComponentConfiguration; 031import org.apache.camel.Endpoint; 032import org.apache.camel.spi.EndpointCompleter; 033import org.apache.camel.util.ObjectHelper; 034import org.apache.camel.util.URISupport; 035import org.apache.camel.util.UnsafeUriCharactersEncoder; 036 037/** 038 * Useful base class for implementations of {@link ComponentConfiguration} 039 */ 040@Deprecated 041public abstract class ComponentConfigurationSupport implements ComponentConfiguration { 042 protected final Component component; 043 private Map<String, Object> propertyValues = new HashMap<>(); 044 private String baseUri; 045 046 public ComponentConfigurationSupport(Component component) { 047 this.component = component; 048 } 049 050 @Override 051 public Map<String, Object> getParameters() { 052 return Collections.unmodifiableMap(propertyValues); 053 } 054 055 @Override 056 public void setParameters(Map<String, Object> newValues) { 057 ObjectHelper.notNull(newValues, "propertyValues"); 058 this.propertyValues.clear(); 059 // lets validate each property as we set it 060 Set<Map.Entry<String, Object>> entries = newValues.entrySet(); 061 for (Map.Entry<String, Object> entry : entries) { 062 setParameter(entry.getKey(), entry.getValue()); 063 } 064 } 065 066 @Override 067 public Object getParameter(String name) { 068 validatePropertyName(name); 069 return propertyValues.get(name); 070 } 071 072 @Override 073 public void setParameter(String name, Object value) { 074 Object convertedValue = validatePropertyValue(name, value); 075 propertyValues.put(name, convertedValue); 076 } 077 078 /** 079 * Returns the base URI without any scheme or URI query parameters (property values) 080 */ 081 @Override 082 public String getBaseUri() { 083 return baseUri; 084 } 085 086 @Override 087 public void setBaseUri(String baseUri) { 088 this.baseUri = baseUri; 089 } 090 091 @Override 092 public Endpoint createEndpoint() throws Exception { 093 String uri = getUriString(); 094 return component.createEndpoint(uri); 095 } 096 097 /** 098 * Configures the properties on the given endpoint 099 */ 100 @Override 101 public void configureEndpoint(Endpoint endpoint) { 102 Map<String, Object> map = getParameters(); 103 if (map != null) { 104 Set<Map.Entry<String, Object>> entries = map.entrySet(); 105 for (Map.Entry<String, Object> entry : entries) { 106 setEndpointParameter(endpoint, entry.getKey(), entry.getValue()); 107 } 108 } 109 // TODO validate all the values are valid (e.g. mandatory) 110 } 111 112 @Override 113 public String getUriString() { 114 List<String> queryParams = new ArrayList<>(); 115 for (Map.Entry<String, Object> entry : getParameters().entrySet()) { 116 String key = entry.getKey(); 117 Object value = entry.getValue(); 118 // convert to "param=value" format here, order will be preserved 119 if (value instanceof List) { 120 for (Object item : (List<?>)value) { 121 queryParams.add(key + "=" + UnsafeUriCharactersEncoder.encode(item.toString())); 122 } 123 } else { 124 queryParams.add(key + "=" + UnsafeUriCharactersEncoder.encode(value.toString())); 125 } 126 } 127 queryParams.sort(null); 128 StringBuilder builder = new StringBuilder(); 129 String base = getBaseUri(); 130 if (base != null) { 131 builder.append(base); 132 } 133 String separator = "?"; 134 for (String entry : queryParams) { 135 builder.append(separator); 136 builder.append(entry); 137 separator = "&"; 138 } 139 return builder.toString(); 140 } 141 142 @Override 143 public void setUriString(String uri) throws URISyntaxException { 144 String path = uri; 145 int idx = path.indexOf('?'); 146 Map<String, Object> newParameters = Collections.emptyMap(); 147 if (idx >= 0) { 148 path = path.substring(0, idx); 149 String query = uri.substring(idx + 1); 150 newParameters = URISupport.parseQuery(query, true); 151 } 152 setBaseUri(path); 153 setParameters(newParameters); 154 } 155 156 @Override 157 public ParameterConfiguration getParameterConfiguration(String name) { 158 return getParameterConfigurationMap().get(name); 159 } 160 161 public List<String> completeEndpointPath(String completionText) { 162 if (component instanceof EndpointCompleter) { 163 EndpointCompleter completer = (EndpointCompleter) component; 164 return completer.completeEndpointPath(this, completionText); 165 } 166 return new ArrayList<>(); 167 } 168 169 public String createParameterJsonSchema() { 170 // favor loading the json schema from the built-time generated file 171 String defaultName = component.getCamelContext().resolveComponentDefaultName(component.getClass().getName()); 172 if (defaultName != null) { 173 try { 174 return component.getCamelContext().getComponentParameterJsonSchema(defaultName); 175 } catch (IOException e) { 176 // ignore as we fallback to create the json at runtime 177 } 178 } 179 180 // fallback to resolving at runtime 181 SortedMap<String, ParameterConfiguration> map = getParameterConfigurationMap(); 182 StringBuilder buffer = new StringBuilder("{\n \"properties\": {"); 183 boolean first = true; 184 for (Map.Entry<String, ParameterConfiguration> entry : map.entrySet()) { 185 if (first) { 186 first = false; 187 } else { 188 buffer.append(","); 189 } 190 buffer.append("\n "); 191 buffer.append(entry.getValue().toJson()); 192 } 193 buffer.append("\n }\n}\n"); 194 return buffer.toString(); 195 } 196 197 /** 198 * Allow implementations to validate whether a property name is valid 199 * and either throw an exception or log a warning of an unknown property being used 200 */ 201 protected void validatePropertyName(String name) { 202 } 203 204 /** 205 * Allow implementations to validate whether a property name is valid 206 * and either throw an exception or log a warning of an unknown property being used 207 * and to convert the given value to the correct type before updating the value. 208 */ 209 protected Object validatePropertyValue(String name, Object value) { 210 validatePropertyName(name); 211 return value; 212 } 213 214}