001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: /**
019: * @author Boris V. Kuznetsov
020: * @version $Revision$
021: */package org.apache.harmony.security.fortress;
022:
023: import java.security.AccessController;
024: import java.security.PrivilegedAction;
025: import java.security.Provider;
026: import java.security.Security;
027: import java.util.ArrayList;
028: import java.util.HashMap;
029: import java.util.Iterator;
030: import java.util.List;
031: import java.util.Map;
032: import java.util.Set;
033:
034: import org.apache.harmony.security.Util;
035:
036: /**
037: * This class contains information about all registered providers and preferred
038: * implementations for all "serviceName.algName".
039: *
040: */
041:
042: public class Services {
043:
044: // The HashMap that contains information about preferred implementations for
045: // all serviceName.algName in the registered providers
046: private static final Map<String, Provider.Service> services = new HashMap<String, Provider.Service>(
047: 512);
048:
049: // Need refresh flag
050: private static boolean needRefresh; // = false;
051:
052: /**
053: * Refresh number
054: */
055: static int refreshNumber = 1;
056:
057: // Registered providers
058: private static final List<Provider> providers = new ArrayList<Provider>(
059: 20);
060:
061: // Hash for quick provider access by name
062: private static final Map<String, Provider> providersNames = new HashMap<String, Provider>(
063: 20);
064:
065: static {
066: AccessController.doPrivileged(new PrivilegedAction<Object>() {
067: public Object run() {
068: loadProviders();
069: return null;
070: }
071: });
072: }
073:
074: // Load statically registered providers and init Services Info
075: private static void loadProviders() {
076: String providerClassName = null;
077: int i = 1;
078: ClassLoader cl = ClassLoader.getSystemClassLoader();
079: Provider p;
080:
081: while ((providerClassName = Security
082: .getProperty("security.provider." //$NON-NLS-1$
083: + i++)) != null) {
084: try {
085: p = (Provider) Class.forName(providerClassName.trim(),
086: true, cl).newInstance();
087: providers.add(p);
088: providersNames.put(p.getName(), p);
089: initServiceInfo(p);
090: } catch (ClassNotFoundException e) { // ignore Exceptions
091: } catch (IllegalAccessException e) {
092: } catch (InstantiationException e) {
093: }
094: }
095: Engine.door.renumProviders();
096: }
097:
098: /**
099: * Returns registered providers
100: *
101: * @return
102: */
103: public static Provider[] getProviders() {
104: return providers.toArray(new Provider[providers.size()]);
105: }
106:
107: /**
108: * Returns registered providers as List
109: *
110: * @return
111: */
112: public static List<Provider> getProvidersList() {
113: return new ArrayList<Provider>(providers);
114: }
115:
116: /**
117: * Returns the provider with the specified name
118: *
119: * @param name
120: * @return
121: */
122: public static Provider getProvider(String name) {
123: if (name == null) {
124: return null;
125: }
126: return providersNames.get(name);
127: }
128:
129: /**
130: * Inserts a provider at a specified position
131: *
132: * @param provider
133: * @param position
134: * @return
135: */
136: public static int insertProviderAt(Provider provider, int position) {
137: int size = providers.size();
138: if ((position < 1) || (position > size)) {
139: position = size + 1;
140: }
141: providers.add(position - 1, provider);
142: providersNames.put(provider.getName(), provider);
143: setNeedRefresh();
144: return position;
145: }
146:
147: /**
148: * Removes the provider
149: *
150: * @param providerNumber
151: */
152: public static void removeProvider(int providerNumber) {
153: Provider p = providers.remove(providerNumber - 1);
154: providersNames.remove(p.getName());
155: setNeedRefresh();
156: }
157:
158: /**
159: *
160: * Adds information about provider services into HashMap.
161: *
162: * @param p
163: */
164: public static void initServiceInfo(Provider p) {
165: Provider.Service serv;
166: String key;
167: String type;
168: String alias;
169: StringBuffer sb = new StringBuffer(128);
170:
171: for (Iterator<Provider.Service> it1 = p.getServices()
172: .iterator(); it1.hasNext();) {
173: serv = it1.next();
174: type = serv.getType();
175: sb.delete(0, sb.length());
176: key = sb.append(type).append(".").append( //$NON-NLS-1$
177: Util.toUpperCase(serv.getAlgorithm())).toString();
178: if (!services.containsKey(key)) {
179: services.put(key, serv);
180: }
181: for (Iterator<String> it2 = Engine.door.getAliases(serv); it2
182: .hasNext();) {
183: alias = it2.next();
184: sb.delete(0, sb.length());
185: key = sb.append(type)
186: .append(".").append(Util.toUpperCase(alias)) //$NON-NLS-1$
187: .toString();
188: if (!services.containsKey(key)) {
189: services.put(key, serv);
190: }
191: }
192: }
193: }
194:
195: /**
196: *
197: * Updates services hashtable for all registered providers
198: *
199: */
200: public static void updateServiceInfo() {
201: services.clear();
202: for (Iterator<Provider> it = providers.iterator(); it.hasNext();) {
203: initServiceInfo(it.next());
204: }
205: needRefresh = false;
206: }
207:
208: /**
209: * Returns true if services contain any provider information
210: * @return
211: */
212: public static boolean isEmpty() {
213: return services.isEmpty();
214: }
215:
216: /**
217: *
218: * Returns service description.
219: * Call refresh() before.
220: *
221: * @param key
222: * @return
223: */
224: public static Provider.Service getService(String key) {
225: return services.get(key);
226: }
227:
228: /**
229: * Prints Services content
230: */
231: // FIXME remove debug function
232: public static void printServices() {
233: refresh();
234: Set<String> s = services.keySet();
235: for (Iterator<String> i = s.iterator(); i.hasNext();) {
236: String key = i.next();
237: System.out.println(key + "=" + services.get(key)); //$NON-NLS-1$
238: }
239: }
240:
241: /**
242: * Set flag needRefresh
243: *
244: */
245: public static void setNeedRefresh() {
246: needRefresh = true;
247: }
248:
249: /**
250: * Refresh services info
251: *
252: */
253: public static void refresh() {
254: if (needRefresh) {
255: refreshNumber++;
256: updateServiceInfo();
257: }
258: }
259: }
|