001 package org.apache.fulcrum.yaafi.framework.crypto;
002
003 /*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements. See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership. The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License. You may obtain a copy of the License at
011 *
012 * http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied. See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022 import org.apache.fulcrum.yaafi.framework.reflection.Clazz;
023
024 import java.io.InputStream;
025
026 /**
027 * Factory class to get a decrypting input stream for reading configuration
028 * files. The implementation uses dynamic class loading to make decryption
029 * an optional feature which is highly desirable when avoiding the ECCN
030 * export code problems.
031 *
032 * @author <a href="mailto:siegfried.goeschl@it20one.at">Siegfried Goeschl </a>
033 */
034
035 public class CryptoStreamFactory
036 {
037 /** is the instance already initialized */
038 private static boolean isInitialized;
039
040 /** the factory to create encrypting input streams */
041 private static Object cryptoStreamFactory;
042
043 /** the name of the class to be loaded */
044 private static String className = "org.apache.fulcrum.jce.crypto.CryptoStreamFactoryImpl";
045
046 /**
047 * Create a (potentially) decrypting input stream using the default
048 * password.
049 *
050 * @param is the input stream to be decrypted
051 * @param isEncrypted the encryption mode (true|false|auto)
052 * @return a decrypting input stream
053 * @throws Exception reading the input stream failed
054 */
055 public static InputStream getDecryptingInputStream( InputStream is, String isEncrypted )
056 throws Exception
057 {
058 InputStream result;
059
060 if( isEncrypted.equalsIgnoreCase("true") )
061 {
062 // a decrypting input stream was requested
063 result = createDecryptingInputStream(is, "getInputStream");
064 }
065 else if( isEncrypted.equalsIgnoreCase("auto") && hasCryptoStreamFactory())
066 {
067 // no user-supplied preferences but crypto stream is available
068 result = createDecryptingInputStream(is, "getSmartInputStream");
069 }
070 else if( isEncrypted.equalsIgnoreCase("auto") && !hasCryptoStreamFactory())
071 {
072 // no user-supplied perferences so we fall back to normal input stream
073 result = is;
074 }
075 else if( isEncrypted.equalsIgnoreCase("false") )
076 {
077 // just use normal input stream
078 result = is;
079 }
080 else
081 {
082 throw new IllegalArgumentException("Unknown decryption mode : " + isEncrypted);
083 }
084
085 return result;
086 }
087
088 /**
089 * Factory method to create a decrypting input stream.
090 *
091 * @param is the input stream to be decrypted
092 * @param factoryMethodName the name of the factory method
093 * @return a decrypting input stream
094 * @throws Exception creating the decrypting input stream failed
095 */
096 private static InputStream createDecryptingInputStream( InputStream is, String factoryMethodName )
097 throws Exception
098 {
099 Class[] signature = {InputStream.class};
100 Object[] args = {is};
101 Object cryptoStreamFactory = getCryptoStreamFactory();
102
103 if(cryptoStreamFactory == null)
104 {
105 throw new IllegalStateException("No CryptoStreamFactory available - unable to create a decrypting input stream");
106 }
107 else
108 {
109 return (InputStream) Clazz.invoke(cryptoStreamFactory, factoryMethodName, signature, args);
110 }
111 }
112
113 /**
114 * Factory method to create a CryptoStreamFactory.
115 */
116 private synchronized static Object getCryptoStreamFactory()
117 throws Exception
118 {
119 if(!isInitialized)
120 {
121 isInitialized = true;
122 ClassLoader clazzLoader = CryptoStreamFactory.class.getClassLoader();
123
124 if(Clazz.hasClazz(clazzLoader, className))
125 {
126 Class[] signature = {};
127 Object[] args = {};
128 Class clazz = Clazz.getClazz(clazzLoader, className);
129 cryptoStreamFactory = Clazz.newInstance(clazz, signature, args);
130 }
131 }
132
133 return cryptoStreamFactory;
134 }
135
136 /**
137 * @return true if a CryptoStreamFactory is available
138 */
139 private static boolean hasCryptoStreamFactory()
140 throws Exception
141 {
142 return ( getCryptoStreamFactory() != null );
143 }
144 }