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.util.component; 018 019import java.lang.reflect.Field; 020import java.util.Collections; 021import java.util.HashMap; 022import java.util.HashSet; 023import java.util.Map; 024import java.util.Set; 025 026import org.apache.camel.Exchange; 027import org.apache.camel.util.IntrospectionSupport; 028import org.slf4j.Logger; 029import org.slf4j.LoggerFactory; 030 031/** 032 * Helper class to work with ApiMethod arguments to be extended by components. 033 */ 034public abstract class ApiMethodPropertiesHelper<C> { 035 036 protected static final Logger LOG = LoggerFactory.getLogger(ApiMethodPropertiesHelper.class); 037 038 // set of field names which are specific to the api, to be excluded from method argument considerations 039 protected final Set<String> componentConfigFields = new HashSet<String>(); 040 041 protected final Class<?> componentConfigClass; 042 protected final String propertyPrefix; 043 044 private final int prefixLength; 045 private final String camelCasePrefix; 046 047 protected ApiMethodPropertiesHelper(Class<C> componentConfiguration, String propertyPrefix) { 048 049 this.componentConfigClass = componentConfiguration; 050 this.propertyPrefix = propertyPrefix; 051 052 this.prefixLength = propertyPrefix.length(); 053 if (!Character.isLetterOrDigit(propertyPrefix.charAt(prefixLength - 1))) { 054 this.camelCasePrefix = propertyPrefix.substring(0, prefixLength - 1); 055 } else { 056 this.camelCasePrefix = null; 057 } 058 059 for (Field field : componentConfiguration.getDeclaredFields()) { 060 componentConfigFields.add(field.getName()); 061 } 062 } 063 064 /** 065 * Gets exchange header properties that start with propertyPrefix. 066 * 067 * @param exchange Camel exchange 068 * @param properties map to collect properties with required prefix 069 */ 070 public Map<String, Object> getExchangeProperties(Exchange exchange, Map<String, Object> properties) { 071 072 int nProperties = 0; 073 for (Map.Entry<String, Object> entry : exchange.getIn().getHeaders().entrySet()) { 074 final String key = entry.getKey(); 075 if (key.startsWith(propertyPrefix)) { 076 properties.put(key.substring(prefixLength), 077 entry.getValue()); 078 nProperties++; 079 } else if (camelCasePrefix != null && key.startsWith(camelCasePrefix)) { 080 // assuming all property names start with a lowercase character 081 final String propertyName = String.valueOf(Character.toLowerCase(key.charAt(prefixLength - 1))) 082 + key.substring(prefixLength); 083 properties.put(propertyName, entry.getValue()); 084 nProperties++; 085 } 086 } 087 LOG.debug("Found {} properties in exchange", nProperties); 088 return properties; 089 } 090 091 public void getEndpointProperties(Object endpointConfiguration, Map<String, Object> properties) { 092 093 Set<String> names = null; 094 if (IntrospectionSupport.getProperties(endpointConfiguration, properties, null, false)) { 095 names = properties.keySet(); 096 // remove component config properties so we only have endpoint properties 097 names.removeAll(componentConfigFields); 098 } 099 LOG.debug("Found endpoint properties {}", names); 100 } 101 102 public Set<String> getEndpointPropertyNames(Object endpointConfiguration) { 103 Map<String, Object> properties = new HashMap<String, Object>(); 104 getEndpointProperties(endpointConfiguration, properties); 105 return Collections.unmodifiableSet(properties.keySet()); 106 } 107 108 public Set<String> getValidEndpointProperties(Object endpointConfiguration) { 109 Set<String> fields = new HashSet<String>(); 110 for (Field field : endpointConfiguration.getClass().getDeclaredFields()) { 111 fields.add(field.getName()); 112 } 113 return Collections.unmodifiableSet(fields); 114 } 115 116}