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.util.Collections; 020import java.util.SortedMap; 021 022import org.apache.camel.CamelContext; 023import org.apache.camel.Component; 024import org.apache.camel.Endpoint; 025import org.apache.camel.InvalidPropertyException; 026import org.apache.camel.RuntimeCamelException; 027import org.apache.camel.util.IntrospectionSupport; 028import org.slf4j.Logger; 029import org.slf4j.LoggerFactory; 030 031/** 032 * Implements {@link org.apache.camel.EndpointConfiguration} for Endpoint implementations 033 * which are annotated with {@link org.apache.camel.spi.UriEndpoint} 034 * to use the {@link org.apache.camel.spi.UriParam} and {@link org.apache.camel.spi.UriParams} annotations 035 * to denote its parameters which can be specified via URI query parameters. 036 */ 037public class UriComponentConfiguration extends ComponentConfigurationSupport { 038 private static final Logger LOG = LoggerFactory.getLogger(UriComponentConfiguration.class); 039 040 private final Class<? extends Endpoint> endpointClass; 041 private final SortedMap<String, ParameterConfiguration> parameterConfigurationMap; 042 private boolean strictOnParameterNames = true; 043 044 public UriComponentConfiguration(Component component, Class<? extends Endpoint> endpointClass, 045 SortedMap<String, ParameterConfiguration> parameterConfigurationMap) { 046 super(component); 047 this.endpointClass = endpointClass; 048 this.parameterConfigurationMap = Collections.unmodifiableSortedMap(parameterConfigurationMap); 049 } 050 051 public UriComponentConfiguration(Component component, Class<? extends Endpoint> endpointClass) { 052 this(component, endpointClass, UriEndpointComponent.createParameterConfigurationMap(endpointClass)); 053 } 054 055 public UriComponentConfiguration(UriEndpointComponent component) { 056 this(component, component.getEndpointClass(), component.getParameterConfigurationMap()); 057 } 058 059 @Override 060 public Object getEndpointParameter(Endpoint endpoint, String name) throws RuntimeCamelException { 061 ParameterConfiguration config = getParameterConfiguration(name); 062 063 // lets try get the property regardless of if this maps to a valid property name 064 // then if the introspection fails we will get a valid error otherwise 065 // lets raise a warning afterwards that we should update the metadata on the endpoint class 066 Object answer = null; 067 try { 068 answer = IntrospectionSupport.getProperty(endpoint, name); 069 } catch (Exception e) { 070 throw new RuntimeCamelException( 071 "Failed to get property '" + name + "' on " + endpoint + " due " + e.getMessage(), e); 072 } 073 if (config == null) { 074 unknownPropertyName(name); 075 } 076 return answer; 077 } 078 079 @Override 080 public void setEndpointParameter(Endpoint endpoint, String name, Object value) throws RuntimeCamelException { 081 ParameterConfiguration config = getParameterConfiguration(name); 082 083 // lets try set the property regardless of if this maps to a valid property name 084 // then if the injection fails we will get a valid error otherwise 085 // lets raise a warning afterwards that we should update the metadata on the endpoint class 086 try { 087 IntrospectionSupport.setProperty(endpoint, name, value); 088 } catch (Exception e) { 089 throw new RuntimeCamelException("Failed to set property '" + name + "' on " + endpoint + " to value " 090 + value + " due " + e.getMessage(), e); 091 } 092 if (config == null) { 093 unknownPropertyName(name); 094 } 095 } 096 097 public CamelContext getCamelContext() { 098 return component.getCamelContext(); 099 } 100 101 public Class<? extends Endpoint> getEndpointClass() { 102 return endpointClass; 103 } 104 105 public boolean isStrictOnParameterNames() { 106 return strictOnParameterNames; 107 } 108 109 /** 110 * Strict mode is enabled by default but if disabled then invalid parameter names 111 * will not result in exceptions but we will just log warnings about their use 112 * 113 * @param strictOnParameterNames whether to throw exceptions if invalid 114 * parameter names are used or not 115 */ 116 public void setStrictOnParameterNames(boolean strictOnParameterNames) { 117 this.strictOnParameterNames = strictOnParameterNames; 118 } 119 120 @Override 121 public SortedMap<String, ParameterConfiguration> getParameterConfigurationMap() { 122 return parameterConfigurationMap; 123 } 124 125 @Override 126 protected void validatePropertyName(String name) { 127 ParameterConfiguration parameterConfiguration = getParameterConfiguration(name); 128 if (parameterConfiguration == null) { 129 unknownPropertyName(name); 130 } 131 } 132 133 @Override 134 protected Object validatePropertyValue(String name, Object value) { 135 ParameterConfiguration parameterConfiguration = getParameterConfiguration(name); 136 if (parameterConfiguration == null) { 137 unknownPropertyName(name); 138 return value; 139 } else { 140 Class<?> parameterType = parameterConfiguration.getParameterType(); 141 return getCamelContext().getTypeConverter().convertTo(parameterType, value); 142 } 143 } 144 145 protected void unknownPropertyName(String name) { 146 if (isStrictOnParameterNames()) { 147 throw new InvalidPropertyException(this, name, endpointClass); 148 } else { 149 LOG.warn("Using parameter " + name + " on endpoint " + getEndpointClass().getName() 150 + " which does not have a @UriParam annotation! " 151 + "Please add the @UriParam annotation to the " + name + " field"); 152 } 153 } 154 155}