View Javadoc

1   /*
2    * Copyright  2003-2004 The Apache Software Foundation.
3    *
4    *  Licensed under the Apache License, Version 2.0 (the "License");
5    *  you may not use this file except in compliance with the License.
6    *  You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *  Unless required by applicable law or agreed to in writing, software
11   *  distributed under the License is distributed on an "AS IS" BASIS,
12   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *  See the License for the specific language governing permissions and
14   *  limitations under the License.
15   *
16   */
17  
18  package org.apache.ws.security.components.crypto;
19  
20  import org.apache.commons.logging.Log;
21  import org.apache.commons.logging.LogFactory;
22  import org.apache.ws.security.util.Loader;
23  
24  import java.lang.reflect.Constructor;
25  import java.net.URL;
26  import java.util.Properties;
27  
28  /***
29   * CryptoFactory.
30   * <p/>
31   *
32   * @author Davanum Srinivas (dims@yahoo.com).
33   */
34  public abstract class CryptoFactory {
35      private static Log log = LogFactory.getLog(CryptoFactory.class);
36      private static final String defaultCryptoClassName = "org.apache.ws.security.components.crypto.Merlin";
37  
38      /***
39       * getInstance
40       * <p/>
41       * Returns an instance of Crypto. This method uses the file
42       * <code>crypto.properties</code> to determine which implementation to
43       * use. Thus the property <code>org.apache.ws.security.crypto.provider</code>
44       * must define the classname of the Crypto implementation. The file
45       * may contain other property definitions as well. These properties are
46       * handed over to the  Crypto implementation. The file
47       * <code>crypto.properties</code> is loaded with the
48       * <code>Loader.getResource()</code> method.
49       * <p/>
50       *
51       * @return The cyrpto implementation was defined
52       */
53      public static Crypto getInstance() {
54          return getInstance("crypto.properties");
55      }
56  
57      /***
58       * getInstance
59       * <p/>
60       * Returns an instance of Crypto. The properties are handed over the the crypto
61       * implementation. The porperties can be <code>null</code>. It is depenend on the
62       * Crypto implementation how the initialization is done in this case.
63       * <p/>
64       *
65       * @param cryptoClassName This is the crypto implementation class. No default is
66       *                        provided here.
67       * @param properties      The Properties that are forwarded to the crypto implementaion.
68       *                        These properties are dependend on the crypto implementatin
69       * @return The cyrpto implementation or null if no cryptoClassName was defined
70       */
71      public static Crypto getInstance(String cryptoClassName, Properties properties) {
72          return loadClass(cryptoClassName, properties);
73      }
74  
75      /***
76       * getInstance
77       * <p/>
78       * Returns an instance of Crypto. This method uses the specifed filename
79       * to load a property file. This file shall use the property
80       * <code>org.apache.ws.security.crypto.provider</code>
81       * to define the classname of the Crypto implementation. The file
82       * may contain other property definitions as well. These properties are
83       * handed over to the Crypto implementation. The specified file
84       * is loaded with the <code>Loader.getResource()</code> method.
85       * <p/>
86       *
87       * @param propFilename The name of the property file to load
88       * @return The cyrpto implementation that was defined
89       */
90      public static Crypto getInstance(String propFilename) {
91          Properties properties = null;
92          String cryptoClassName = null;
93  
94          // cryptoClassName = System.getProperty("org.apache.ws.security.crypto.provider");
95          if ((cryptoClassName == null) || (cryptoClassName.length() == 0)) {
96              properties = getProperties(propFilename);
97              // use the default Crypto implementation
98              cryptoClassName = properties.getProperty("org.apache.ws.security.crypto.provider",
99                      defaultCryptoClassName);
100         }
101         return loadClass(cryptoClassName, properties);
102     }
103 
104     private static Crypto loadClass(String cryptoClassName, Properties properties) {
105         Class cryptogenClass = null;
106         Crypto crypto = null;
107         try {
108             // instruct the class loader to load the crypto implementation
109             cryptogenClass = Loader.loadClass(cryptoClassName);
110         } catch (ClassNotFoundException e) {
111             throw new RuntimeException(cryptoClassName + " Not Found");
112         }
113         log.info("Using Crypto Engine [" + cryptoClassName + "]");
114         try {
115             Class[] classes = new Class[]{Properties.class};
116             Constructor c = cryptogenClass.getConstructor(classes);
117             crypto = (Crypto) c.newInstance(new Object[]{properties});
118             return crypto;
119         } catch (java.lang.Exception e) {
120             e.printStackTrace();
121             log.error("Unable to instantiate (1): " + cryptoClassName, e);
122         }
123         try {
124             // try to instantiate the Crypto subclass
125             crypto = (Crypto) cryptogenClass.newInstance();
126             return crypto;
127         } catch (java.lang.Exception e) {
128             e.printStackTrace();
129             log.error("Unable to instantiate (2): " + cryptoClassName, e);
130             throw new RuntimeException(cryptoClassName + " cannot create instance");
131         }
132     }
133 
134     /***
135      * Gets the properties for crypto.
136      * The functions loads the property file via
137      * {@link Loader.getResource(String)}, thus the property file
138      * should be accesible via the classpath
139      *
140      * @param propFilename the properties file to load
141      * @return a <code>Properties</code> object loaded from the filename
142      */
143     private static Properties getProperties(String propFilename) {
144         Properties properties = new Properties();
145         try {
146             URL url = Loader.getResource(propFilename);
147             properties.load(url.openStream());
148         } catch (Exception e) {
149             log.debug("Cannot find crypto property file: " + propFilename);
150             throw new RuntimeException("CryptoFactory: Cannot load properties: " +
151                     propFilename);
152         }
153         return properties;
154     }
155 }
156