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;
27import org.apache.harmony.security.Util;
28
29
30/**
31 *
32 * This class implements common functionality for all engine classes
33 *
34 */
35public class Engine {
36
37    // Service name
38    private final String serviceName;
39
40    // for getInstance(String algorithm, Object param) optimization:
41    // previous result
42    private Provider.Service returnedService;
43
44    // previous parameter
45    private String lastAlgorithm;
46
47    private int refreshNumber;
48
49    /**
50     * Provider
51     */
52    public Provider provider;
53
54    /**
55     * SPI instance
56     */
57    public Object spi;
58
59    /**
60     * Access to package visible api in java.security
61     */
62    public static SecurityAccess door;
63
64    /**
65     * Creates a Engine object
66     *
67     * @param service
68     */
69    public Engine(String service) {
70        this.serviceName = service;
71    }
72
73    /**
74     *
75     * Finds the appropriate service implementation and creates instance of the
76     * class that implements corresponding Service Provider Interface.
77     *
78     * @param algorithm
79     * @param service
80     * @throws NoSuchAlgorithmException
81     */
82    public synchronized void getInstance(String algorithm, Object param)
83            throws NoSuchAlgorithmException {
84        Provider.Service serv;
85
86        if (algorithm == null) {
87            throw new NoSuchAlgorithmException("Null algorithm name");
88        }
89        Services.refresh();
90        if (returnedService != null
91                && Util.equalsIgnoreCase(algorithm, lastAlgorithm)
92                && refreshNumber == Services.refreshNumber) {
93            serv = returnedService;
94        } else {
95            if (Services.isEmpty()) {
96                throw notFound(serviceName, algorithm);
97            }
98            serv = Services.getService(new StringBuilder(128)
99                    .append(serviceName).append(".").append(
100                            Util.toUpperCase(algorithm)).toString());
101            if (serv == null) {
102                throw notFound(serviceName, algorithm);
103            }
104            returnedService = serv;
105            lastAlgorithm = algorithm;
106            refreshNumber = Services.refreshNumber;
107        }
108        spi = serv.newInstance(param);
109        this.provider = serv.getProvider();
110    }
111
112    private NoSuchAlgorithmException notFound(String serviceName, String algorithm) throws NoSuchAlgorithmException {
113        throw new NoSuchAlgorithmException(serviceName + " " + algorithm + " implementation not found");
114    }
115
116    /**
117     *
118     * Finds the appropriate service implementation and creates instance of the
119     * class that implements corresponding Service Provider Interface.
120     *
121     * @param algorithm
122     * @param service
123     * @param provider
124     * @throws NoSuchAlgorithmException
125     */
126    public synchronized void getInstance(String algorithm, Provider provider,
127            Object param) throws NoSuchAlgorithmException {
128
129        Provider.Service serv = null;
130        if (algorithm == null) {
131            throw new NoSuchAlgorithmException("algorithm == null");
132        }
133        serv = provider.getService(serviceName, algorithm);
134        if (serv == null) {
135            throw notFound(serviceName, algorithm);
136        }
137        spi = serv.newInstance(param);
138        this.provider = provider;
139    }
140
141}
142