OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [gnu/] [java/] [security/] [Engine.java] - Blame information for rev 775

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 769 jeremybenn
/* Engine -- generic getInstance method.
2
   Copyright (C) 2003, 2006  Free Software Foundation, Inc.
3
 
4
This file is part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2, or (at your option)
9
any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; see the file COPYING.  If not, write to the
18
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
02110-1301 USA.
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version. */
37
 
38
package gnu.java.security;
39
 
40
import gnu.java.lang.CPStringBuilder;
41
 
42
import java.lang.reflect.Constructor;
43
import java.lang.reflect.InvocationTargetException;
44
 
45
import java.security.NoSuchAlgorithmException;
46
import java.security.Provider;
47
import java.util.Enumeration;
48
 
49
/**
50
 * Generic implementation of the getInstance methods in the various
51
 * engine classes in java.security.
52
 * <p>
53
 * These classes ({@link java.security.Signature} for example) can be
54
 * thought of as the "chrome, upholstery, and steering wheel", and the SPI
55
 * (service provider interface, e.g. {@link java.security.SignatureSpi})
56
 * classes can be thought of as the "engine" -- providing the actual
57
 * functionality of whatever cryptographic algorithm the instance
58
 * represents.
59
 *
60
 * @see Provider
61
 * @author Casey Marshall
62
 */
63
public final class Engine
64
{
65
 
66
  // Constants.
67
  // ------------------------------------------------------------------------
68
 
69
  /** Prefix for aliases. */
70
  private static final String ALG_ALIAS = "Alg.Alias.";
71
 
72
  /** Maximum number of aliases to try. */
73
  private static final int MAX_ALIASES = 5;
74
 
75
  /** Argument list for no-argument constructors. */
76
  private static final Object[] NO_ARGS = new Object[0];
77
 
78
  // Constructor.
79
  // ------------------------------------------------------------------------
80
 
81
  /** This class cannot be instantiated. */
82
  private Engine() { }
83
 
84
  /**
85
   * Return the implementation for <i>algorithm</i> for service <i>service</i>
86
   * from <i>provider</i>. The service is e.g. "Signature", and the algorithm
87
   * "DSA".
88
   *
89
   * @param service The service name.
90
   * @param algorithm The name of the algorithm to get.
91
   * @param provider The provider to get the implementation from.
92
   * @return The engine class for the specified algorithm; the object returned
93
   *         is typically a subclass of the SPI class for that service, but
94
   *         callers should check that this is so.
95
   * @throws NoSuchAlgorithmException If the implementation cannot be found or
96
   *           cannot be instantiated.
97
   * @throws InvocationTargetException If the SPI class's constructor throws an
98
   *           exception.
99
   * @throws IllegalArgumentException If any of the three arguments is null.
100
   */
101
  public static Object getInstance(String service, String algorithm,
102
                                   Provider provider)
103
      throws InvocationTargetException, NoSuchAlgorithmException
104
  {
105
    return getInstance(service, algorithm, provider, NO_ARGS);
106
  }
107
 
108
  /**
109
   * Return the implementation for <i>algorithm</i> for service <i>service</i>
110
   * from <i>provider</i>, passing <i>initArgs</i> to the SPI class's
111
   * constructor (which cannot be null; pass a zero-length array if the SPI
112
   * takes no arguments). The service is e.g. "Signature", and the algorithm
113
   * "DSA".
114
   *
115
   * @param service The service name.
116
   * @param algorithm The name of the algorithm to get.
117
   * @param provider The provider to get the implementation from.
118
   * @param initArgs The arguments to pass to the SPI class's constructor
119
   *          (cannot be null).
120
   * @return The engine class for the specified algorithm; the object returned
121
   *         is typically a subclass of the SPI class for that service, but
122
   *         callers should check that this is so.
123
   * @throws NoSuchAlgorithmException If the implementation cannot be found or
124
   *           cannot be instantiated.
125
   * @throws InvocationTargetException If the SPI class's constructor throws an
126
   *           exception.
127
   * @throws IllegalArgumentException If any of the four arguments is
128
   *           <code>null</code> or if either <code>service</code>, or
129
   *           <code>algorithm</code> is an empty string.
130
   */
131
  public static Object getInstance(String service, String algorithm,
132
                                   Provider provider, Object[] initArgs)
133
      throws InvocationTargetException, NoSuchAlgorithmException
134
  {
135
    if (service == null)
136
      throw new IllegalArgumentException("service MUST NOT be null");
137
    service = service.trim();
138
    if (service.length() == 0)
139
      throw new IllegalArgumentException("service MUST NOT be empty");
140
    if (algorithm == null)
141
      throw new IllegalArgumentException("algorithm MUST NOT be null");
142
    algorithm = algorithm.trim();
143
    if (algorithm.length() == 0)
144
      throw new IllegalArgumentException("algorithm MUST NOT be empty");
145
    if (provider == null)
146
      throw new IllegalArgumentException("provider MUST NOT be null");
147
    if (initArgs == null)
148
      throw new IllegalArgumentException("Constructor's parameters MUST NOT be null");
149
 
150
    Enumeration enumer = provider.propertyNames();
151
    String key = null;
152
    String alias;
153
    int count = 0;
154
    boolean algorithmFound = false;
155
    CPStringBuilder sb = new CPStringBuilder();
156
    while (enumer.hasMoreElements())
157
      {
158
        key = (String) enumer.nextElement();
159
        if (key.equalsIgnoreCase(service + "." + algorithm))
160
          {
161
            // remove the service portion from the key
162
            algorithm = key.substring(service.length() + 1);
163
            algorithmFound = true;
164
            break;
165
          }
166
        else if (key.equalsIgnoreCase(ALG_ALIAS + service + "." + algorithm))
167
          {
168
            alias = provider.getProperty(key);
169
            if (! algorithm.equalsIgnoreCase(alias)) // does not refer to itself
170
              {
171
                algorithm = alias;
172
                if (count++ > MAX_ALIASES)
173
                  {
174
                    sb.append("Algorithm [").append(algorithm)
175
                        .append("] of type [").append(service)
176
                        .append("] from provider [").append(provider)
177
                        .append("] has too many aliases");
178
                    throw new NoSuchAlgorithmException(sb.toString());
179
                  }
180
                // need to reset enumeration to now look for the alias
181
                enumer = provider.propertyNames();
182
              }
183
          }
184
      }
185
 
186
    if (! algorithmFound)
187
      {
188
        sb.append("Algorithm [").append(algorithm).append("] of type [")
189
            .append(service).append("] from provider [")
190
            .append(provider).append("] is not found");
191
        throw new NoSuchAlgorithmException(sb.toString());
192
      }
193
 
194
    // Find and instantiate the implementation
195
    Class clazz = null;
196
    ClassLoader loader = provider.getClass().getClassLoader();
197
    Constructor constructor = null;
198
    String className = provider.getProperty(key);
199
    sb.append("Class [").append(className).append("] for algorithm [")
200
        .append(algorithm).append("] of type [").append(service)
201
        .append("] from provider [").append(provider).append("] ");
202
    Throwable cause = null;
203
    try
204
      {
205
        if (loader != null)
206
          clazz = loader.loadClass(className);
207
        else
208
          clazz = Class.forName(className);
209
        constructor = getCompatibleConstructor(clazz, initArgs);
210
        return constructor.newInstance(initArgs);
211
      }
212
    catch (ClassNotFoundException x)
213
      {
214
        sb.append("cannot not be found");
215
        cause = x;
216
      }
217
    catch (IllegalAccessException x)
218
      {
219
        sb.append("cannot be accessed");
220
        cause = x;
221
      }
222
    catch (InstantiationException x)
223
      {
224
        sb.append("cannot be instantiated");
225
        cause = x;
226
      }
227
    catch (ExceptionInInitializerError x)
228
      {
229
        sb.append("cannot be initialized");
230
        cause = x;
231
      }
232
    catch (SecurityException x)
233
      {
234
        sb.append("caused a security violation");
235
        cause = x;
236
      }
237
    catch (NoSuchMethodException x)
238
      {
239
        sb.append("does not have/expose an appropriate constructor");
240
        cause = x;
241
      }
242
 
243
    NoSuchAlgorithmException x = new NoSuchAlgorithmException(sb.toString());
244
    x.initCause(cause);
245
    throw x;
246
  }
247
 
248
  /**
249
   * Find a constructor in the given class that can take the specified
250
   * argument list, allowing any of which to be null.
251
   *
252
   * @param clazz    The class from which to get the constructor.
253
   * @param initArgs The argument list to be passed to the constructor.
254
   * @return The constructor.
255
   * @throws NoSuchMethodException If no constructor of the given class
256
   *         can take the specified argument array.
257
   */
258
  private static Constructor getCompatibleConstructor(Class clazz,
259
                                                      Object[] initArgs)
260
    throws NoSuchMethodException
261
  {
262
    Constructor[] c = clazz.getConstructors();
263
    outer:for (int i = 0; i < c.length; i++)
264
      {
265
        Class[] argTypes = c[i].getParameterTypes();
266
        if (argTypes.length != initArgs.length)
267
          continue;
268
        for (int j = 0; j < argTypes.length; j++)
269
          {
270
            if (initArgs[j] != null &&
271
                !argTypes[j].isAssignableFrom(initArgs[j].getClass()))
272
              continue outer;
273
          }
274
        // If we reach this point, we know this constructor (c[i]) has
275
        // the same number of parameters as the target parameter list,
276
        // and all our parameters are either (1) null, or (2) assignable
277
        // to the target parameter type.
278
        return c[i];
279
      }
280
    throw new NoSuchMethodException();
281
  }
282
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.