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.component.properties;
018
019 import java.io.FileInputStream;
020 import java.io.FileNotFoundException;
021 import java.io.IOException;
022 import java.io.InputStream;
023 import java.util.Map;
024 import java.util.Properties;
025
026 import org.apache.camel.CamelContext;
027 import org.apache.camel.util.IOHelper;
028 import org.apache.camel.util.ObjectHelper;
029
030 /**
031 * Default {@link org.apache.camel.component.properties.PropertiesResolver} which can resolve properties
032 * from file and classpath.
033 * <p/>
034 * You can denote <tt>classpath:</tt> or <tt>file:</tt> as prefix in the uri to select whether the file
035 * is located in the classpath or on the file system.
036 *
037 * @version
038 */
039 public class DefaultPropertiesResolver implements PropertiesResolver {
040
041 public Properties resolveProperties(CamelContext context, boolean ignoreMissingLocation, String... uri) throws Exception {
042 Properties answer = new Properties();
043
044 for (String path : uri) {
045 if (path.startsWith("ref:")) {
046 Properties prop = loadPropertiesFromRegistry(context, ignoreMissingLocation, path);
047 prop = prepareLoadedProperties(prop);
048 answer.putAll(prop);
049 } else if (path.startsWith("file:")) {
050 Properties prop = loadPropertiesFromFilePath(context, ignoreMissingLocation, path);
051 prop = prepareLoadedProperties(prop);
052 answer.putAll(prop);
053 } else {
054 // default to classpath
055 Properties prop = loadPropertiesFromClasspath(context, ignoreMissingLocation, path);
056 prop = prepareLoadedProperties(prop);
057 answer.putAll(prop);
058 }
059 }
060
061 return answer;
062 }
063
064 protected Properties loadPropertiesFromFilePath(CamelContext context, boolean ignoreMissingLocation, String path) throws IOException {
065 Properties answer = new Properties();
066
067 if (path.startsWith("file:")) {
068 path = ObjectHelper.after(path, "file:");
069 }
070
071 InputStream is = null;
072 try {
073 is = new FileInputStream(path);
074 answer.load(is);
075 } catch (FileNotFoundException e) {
076 if (!ignoreMissingLocation) {
077 throw e;
078 }
079 } finally {
080 IOHelper.close(is);
081 }
082
083 return answer;
084 }
085
086 protected Properties loadPropertiesFromClasspath(CamelContext context, boolean ignoreMissingLocation, String path) throws IOException {
087 Properties answer = new Properties();
088
089 if (path.startsWith("classpath:")) {
090 path = ObjectHelper.after(path, "classpath:");
091 }
092
093 InputStream is = context.getClassResolver().loadResourceAsStream(path);
094 if (is == null) {
095 if (!ignoreMissingLocation) {
096 throw new FileNotFoundException("Properties file " + path + " not found in classpath");
097 }
098 } else {
099 try {
100 answer.load(is);
101 } finally {
102 IOHelper.close(is);
103 }
104 }
105 return answer;
106 }
107
108 protected Properties loadPropertiesFromRegistry(CamelContext context, boolean ignoreMissingLocation, String path) throws IOException {
109 if (path.startsWith("ref:")) {
110 path = ObjectHelper.after(path, "ref:");
111 }
112 Properties answer = context.getRegistry().lookup(path, Properties.class);
113 if (answer == null && (!ignoreMissingLocation)) {
114 throw new FileNotFoundException("Properties " + path + " not found in registry");
115 }
116 return answer != null ? answer : new Properties();
117 }
118
119 /**
120 * Strategy to prepare loaded properties before being used by Camel.
121 * <p/>
122 * This implementation will ensure values are trimmed, as loading properties from
123 * a file with values having trailing spaces is not automatic trimmed by the Properties API
124 * from the JDK.
125 *
126 * @param properties the properties
127 * @return the prepared properties
128 */
129 protected Properties prepareLoadedProperties(Properties properties) {
130 Properties answer = new Properties();
131 for (Map.Entry<Object, Object> entry : properties.entrySet()) {
132 Object key = entry.getKey();
133 Object value = entry.getValue();
134 // trim string values which can be a problem when loading from a properties file and there
135 // is leading or trailing spaces in the value
136 if (value instanceof String) {
137 String s = (String) value;
138 s = s.trim();
139 value = s;
140 }
141 answer.put(key, value);
142 }
143 return answer;
144 }
145
146 }