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