1/*
2 *  Licensed to the Apache Software Foundation (ASF) under one or more
3 *  contributor license agreements.  See the NOTICE file distributed with
4 *  this work for additional information regarding copyright ownership.
5 *  The ASF licenses this file to You under the Apache License, Version 2.0
6 *  (the "License"); you may not use this file except in compliance with
7 *  the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 */
17
18/**
19* @author Boris V. Kuznetsov
20* @version $Revision$
21*/
22
23package org.apache.harmony.security.fortress;
24
25import java.security.NoSuchAlgorithmException;
26import java.security.Provider;
27
28import org.apache.harmony.security.internal.nls.Messages;
29
30
31/**
32 *
33 * This class implements common functionality for all engine classes
34 *
35 */
36public class Engine {
37
38    // Service name
39    private String serviceName;
40
41    // for getInstance(String algorithm, Object param) optimization:
42    // previous result
43    private Provider.Service returnedService;
44
45    // previous parameter
46    private String lastAlgorithm;
47
48    private int refreshNumber;
49
50    /**
51     * Provider
52     */
53    public Provider provider;
54
55    /**
56     * SPI instance
57     */
58    public Object spi;
59
60    /**
61     * Access to package visible api in java.security
62     */
63    public static SecurityAccess door;
64
65    /**
66     * Creates a Engine object
67     *
68     * @param service
69     */
70    public Engine(String service) {
71        this.serviceName = service;
72    }
73
74    /**
75     *
76     * Finds the appropriate service implementation and creates instance of the
77     * class that implements corresponding Service Provider Interface.
78     *
79     * @param algorithm
80     * @param service
81     * @throws NoSuchAlgorithmException
82     */
83    public synchronized void getInstance(String algorithm, Object param)
84            throws NoSuchAlgorithmException {
85        Provider.Service serv;
86
87        if (algorithm == null) {
88            throw new NoSuchAlgorithmException(Messages.getString("security.149")); //$NON-NLS-1$
89        }
90        Services.refresh();
91        if (returnedService != null
92                && algorithm.equalsIgnoreCase(lastAlgorithm)
93                && refreshNumber == Services.refreshNumber) {
94            serv = returnedService;
95        } else {
96            if (Services.isEmpty()) {
97                throw new NoSuchAlgorithmException(Messages.getString("security.14A", //$NON-NLS-1$
98                        serviceName, algorithm));
99            }
100            serv = Services.getService(new StringBuffer(128)
101                    .append(serviceName).append(".").append( //$NON-NLS-1$
102                            algorithm.toUpperCase()).toString());
103            if (serv == null) {
104                throw new NoSuchAlgorithmException(Messages.getString("security.14A", //$NON-NLS-1$
105                        serviceName, algorithm));
106            }
107            returnedService = serv;
108            lastAlgorithm = algorithm;
109            refreshNumber = Services.refreshNumber;
110        }
111        spi = serv.newInstance(param);
112        this.provider = serv.getProvider();
113    }
114
115    /**
116     *
117     * Finds the appropriate service implementation and creates instance of the
118     * class that implements corresponding Service Provider Interface.
119     *
120     * @param algorithm
121     * @param service
122     * @param provider
123     * @throws NoSuchAlgorithmException
124     */
125    public synchronized void getInstance(String algorithm, Provider provider,
126            Object param) throws NoSuchAlgorithmException {
127
128        Provider.Service serv = null;
129        if (algorithm == null) {
130            throw new NoSuchAlgorithmException(
131                    Messages.getString("security.14B", serviceName)); //$NON-NLS-1$
132        }
133        serv = provider.getService(serviceName, algorithm);
134        if (serv == null) {
135            throw new NoSuchAlgorithmException(Messages.getString("security.14A", //$NON-NLS-1$
136                    serviceName, algorithm));
137        }
138        spi = serv.newInstance(param);
139        this.provider = provider;
140    }
141
142}