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.support.jsse; 018 019import java.io.FileInputStream; 020import java.io.FileNotFoundException; 021import java.io.IOException; 022import java.io.InputStream; 023import java.net.URL; 024import java.util.ArrayList; 025import java.util.List; 026 027import org.apache.camel.CamelContext; 028import org.apache.camel.CamelContextAware; 029import org.apache.camel.RuntimeCamelException; 030import org.apache.camel.spi.ClassResolver; 031import org.slf4j.Logger; 032import org.slf4j.LoggerFactory; 033 034/** 035 * Base class that provides optional integration with core Camel capabilities. 036 */ 037public class JsseParameters implements CamelContextAware { 038 039 private static final Logger LOG = LoggerFactory.getLogger(JsseParameters.class); 040 041 private CamelContext context; 042 043 /** 044 * @see #setCamelContext(CamelContext) 045 */ 046 @Override 047 public CamelContext getCamelContext() { 048 return context; 049 } 050 051 /** 052 * Sets the optional {@link CamelContext} used for integration with core capabilities 053 * such as Camel Property Placeholders and {@link ClassResolver}. 054 * 055 * @param context the context to use 056 */ 057 @Override 058 public void setCamelContext(CamelContext context) { 059 this.context = context; 060 } 061 062 /** 063 * Parses the value using the Camel Property Placeholder capabilities if 064 * a context is provided. Otherwise returns {@code value} as is. 065 * 066 * @param value the string to replace property tokens in 067 * @return the value 068 * 069 * @throws RuntimeCamelException if property placeholders were used and there was an error resolving them 070 * 071 * @see #setCamelContext(CamelContext) 072 */ 073 protected String parsePropertyValue(String value) throws RuntimeCamelException { 074 if (this.getCamelContext() != null) { 075 try { 076 return this.getCamelContext().resolvePropertyPlaceholders(value); 077 } catch (Exception e) { 078 throw new RuntimeCamelException("Error parsing property value: " + value, e); 079 } 080 } else { 081 return value; 082 } 083 } 084 085 /** 086 * Parses the values using the Camel Property Placeholder capabilities if 087 * a context is provided. Otherwise returns {@code values} as is. 088 * 089 * @param values the list of strings to replace property tokens in 090 * @return the list of strings 091 * 092 * @throws RuntimeCamelException if property placeholders were used and there was an error resolving them 093 * 094 * @see #parsePropertyValue(String) 095 */ 096 protected List<String> parsePropertyValues(List<String> values) throws RuntimeCamelException { 097 if (this.getCamelContext() == null) { 098 return values; 099 } else { 100 List<String> parsedValues = new ArrayList<>(values.size()); 101 for (String value : values) { 102 parsedValues.add(this.parsePropertyValue(value)); 103 } 104 return parsedValues; 105 } 106 } 107 108 /** 109 * Attempts to loads a resource using a number of different approaches. 110 * The loading of the resource, is attempted by treating the resource as a file path, 111 * a class path resource, a URL, and using the Camel Context's {@link ClassResolver} 112 * if a context is available in that order. An exception is thrown if the resource 113 * cannot be resolved to readable input stream using any of the above methods. 114 * 115 * @param resource the resource location 116 * @return the input stream for the resource 117 * 118 * @throws IOException if the resource cannot be resolved using any of the above methods 119 * 120 * @see #setCamelContext(CamelContext) 121 */ 122 protected InputStream resolveResource(String resource) throws IOException { 123 InputStream is = null; 124 125 // attempt as plain file first 126 try { 127 LOG.trace("Trying to open resource [{}] as a file.", resource); 128 is = new FileInputStream(resource); 129 LOG.debug("Opened resource [{}] as a file.", resource); 130 } catch (FileNotFoundException e) { 131 LOG.trace("Could not open resource [" + resource + "] as a file.", e); 132 } 133 134 // then prefer to use ClassResolver from CamelContext if possible 135 if (is == null && this.context != null) { 136 LOG.trace("Trying to open resource using the CamelContext ClassResolver [{}].", context.getClassResolver()); 137 try { 138 is = context.getClassResolver().loadResourceAsStream(resource); 139 if (is == null) { 140 LOG.trace("Could not to open resource [{}] using the CamelContext ClassResolver [{}].", 141 resource, context.getClassResolver()); 142 } else { 143 LOG.debug("Opened resource [{}] using the CamelContext ClassResolver [{}].", 144 resource, this.getClass().getClassLoader()); 145 } 146 } catch (Throwable e) { 147 LOG.trace("Could not open resource [" + resource + "] using the CamelContext ClassResolver.", e); 148 } 149 } 150 151 if (is == null && Thread.currentThread().getContextClassLoader() != null) { 152 LOG.trace("Trying to open resource [{}] as a class path resource with the TCCL [{}].", 153 resource, Thread.currentThread().getContextClassLoader()); 154 is = Thread.currentThread().getContextClassLoader().getResourceAsStream(resource); 155 156 if (is == null) { 157 LOG.trace("Could not open resource [{}] as a class path resource using the TCCL [{}].", 158 resource, Thread.currentThread().getContextClassLoader()); 159 } else { 160 LOG.debug("Opened resource [{}] as a class path resource with the TCCL [{}].", 161 resource, Thread.currentThread().getContextClassLoader()); 162 } 163 } 164 165 if (is == null) { 166 LOG.trace("Trying to open resource [{}] as a class path resource using the classloader [{}].", 167 resource, this.getClass().getClassLoader()); 168 is = this.getClass().getResourceAsStream(resource); 169 170 if (is == null) { 171 LOG.trace("Could not open resource [{}] as a class path resource using the classloader [{}].", 172 resource, this.getClass().getClassLoader()); 173 } else { 174 LOG.debug("Opened resource [{}] as a class path resource with the classloader [{}].", 175 resource, this.getClass().getClassLoader()); 176 } 177 } 178 179 if (is == null) { 180 try { 181 LOG.trace("Trying to open resource [{}] as a URL.", resource); 182 is = new URL(resource).openStream(); 183 LOG.debug("Opened resource [{}] as a URL.", resource); 184 } catch (IOException e) { 185 LOG.trace("Could not open resource [" + resource + "] as a URL.", e); 186 } 187 } 188 189 if (is == null) { 190 throw new IOException("Could not open " + resource + " as a file, class path resource, or URL."); 191 } 192 193 return is; 194 } 195 196}