| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| */ |
| package org.apache.directory.shared.ldap.message.spi; |
| |
| |
| import java.lang.reflect.InvocationTargetException; |
| import java.lang.reflect.Method; |
| import java.util.Hashtable; |
| import java.util.Properties; |
| |
| import org.apache.directory.shared.i18n.I18n; |
| import org.apache.directory.shared.ldap.codec.LdapProvider; |
| |
| |
| /** |
| * Abstract Provider base class and factory for accessing berlib specific |
| * Provider implementations and their SPI implementation classes. |
| * |
| * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> |
| */ |
| public abstract class Provider |
| { |
| /** Default BER Library provider class name */ |
| public static final String DEFAULT_PROVIDER = LdapProvider.class.getName(); |
| |
| /** BER Library provider class name property */ |
| public static final String BERLIB_PROVIDER = "asn.1.berlib.provider"; |
| |
| /** The default file searched for on CP to load default provider props. */ |
| public static final String BERLIB_PROPFILE = "berlib.properties"; |
| |
| /** A provider monitor key. */ |
| public static final String PROVIDER_MONITOR_KEY = "asn.1.berlib.provider.monitor"; |
| |
| /** Message to use when using defaults */ |
| public static final String USING_DEFAULTS_MSG = "Could not find the ASN.1 berlib provider properties file: " |
| + "berlib.properties.\nFile is not present on the classpath " + "or in $JAVA_HOME/lib:\n\tjava.home = " |
| + System.getProperty( "java.home" ) + "\n\tjava.class.path = " + System.getProperty( "java.class.path" ); |
| |
| /** Use the no-op monitor by default unless we find something else */ |
| private static ProviderMonitor monitor; |
| |
| static |
| { |
| findMonitor( System.getProperties() ); |
| } |
| |
| |
| /* |
| * Checks to see if the provider monitor has been set as a system property. |
| * If it has try to instantiate it and use it. |
| */ |
| private static void findMonitor( Properties props ) |
| { |
| if ( props.containsKey( PROVIDER_MONITOR_KEY ) ) |
| { |
| String fqcn = System.getProperties().getProperty( PROVIDER_MONITOR_KEY ); |
| |
| if ( fqcn != null ) |
| { |
| Class<?> mc; |
| |
| try |
| { |
| mc = Class.forName( fqcn ); |
| monitor = ( ProviderMonitor ) mc.newInstance(); |
| } |
| catch ( ClassNotFoundException e ) |
| { |
| System.err.println( I18n.err( I18n.ERR_04177, fqcn ) ); |
| } |
| catch ( IllegalAccessException e ) |
| { |
| System.err.println( I18n.err( I18n.ERR_04178, fqcn ) ); |
| } |
| catch ( InstantiationException e ) |
| { |
| System.err.println( I18n.err( I18n.ERR_04179, fqcn ) ); |
| } |
| } |
| } |
| |
| if ( monitor == null ) |
| { |
| monitor = ProviderMonitor.NOOP_MONITOR; |
| } |
| } |
| |
| // ------------------------------------------------------------------------ |
| // Provider Properties |
| // ------------------------------------------------------------------------ |
| |
| /** The descriptive string to identify this provider */ |
| private final String name; |
| |
| /** The Provider's vendor name */ |
| private final String vendor; |
| |
| |
| // ------------------------------------------------------------------------ |
| // Constructors |
| // ------------------------------------------------------------------------ |
| |
| /** |
| * Creates an instance of a Provider. |
| * |
| * @param name |
| * a descriptive name for a provider |
| * @param vendor |
| * the berlib vendor used by the provider |
| */ |
| protected Provider( String name, String vendor ) |
| { |
| this.name = name; |
| this.vendor = vendor; |
| } |
| |
| |
| // ------------------------------------------------------------------------ |
| // Property Accessor Methods |
| // ------------------------------------------------------------------------ |
| |
| /** |
| * Gets the descriptive name for this Provider. |
| * |
| * @return the Provider's name. |
| */ |
| public final String getName() |
| { |
| return name; |
| } |
| |
| |
| /** |
| * Gets this Providers vendor name if it was provided. |
| * |
| * @return the vendor name for this provider or the String 'UNKNOWN' if it |
| * is not known. |
| */ |
| public final String getVendor() |
| { |
| return vendor; |
| } |
| |
| |
| /** |
| * Gets the encoder associated with this provider. |
| * |
| * @return the provider's encoder. |
| * @throws ProviderException |
| * if the provider or its encoder cannot be found |
| */ |
| public abstract ProviderEncoder getEncoder() throws ProviderException; |
| |
| |
| /** |
| * Gets the decoder associated with this provider. |
| * |
| * @return the provider's decoder. |
| * @throws ProviderException if the provider or its decoder cannot be found |
| * @param binaryAttributeDetector detects whether or not attributes are binary |
| * @param maxPDUSize the maximum size a PDU can be |
| */ |
| public abstract ProviderDecoder getDecoder( BinaryAttributeDetector binaryAttributeDetector, |
| int maxPDUSize ) |
| throws ProviderException; |
| |
| |
| // ------------------------------------------------------------------------ |
| // Factory/Environment Methods |
| // ------------------------------------------------------------------------ |
| |
| |
| /** |
| * Gets an instance of the configured Provider. The configured provider is |
| * the classname specified by the <code>asn.1.berlib.provider</code> |
| * property. The property is searched for within berlib.properties files |
| * that are on the java.class.path. If at least one berlib.properties is not |
| * found the default provider is used. The resultant value (default or |
| * otherwise) for the property can be overridden by command line properties. |
| * |
| * @return a singleton instance of the configured ASN.1 BER Library Provider |
| * @throws ProviderException |
| * if the provider cannot be found |
| */ |
| public static Provider getProvider() throws ProviderException |
| { |
| return getProvider( getEnvironment() ); |
| } |
| |
| |
| /** |
| * Gets an instance of the Provider specified by the <code> |
| * asn.1.berlib.provider</code> |
| * property value. The property is searched for within properties object |
| * passed in as a parameter for this method only. |
| * |
| * @param env |
| * the environment used to locate the provider |
| * @return a singleton instance of the ASN.1 BER Library Provider |
| * @throws ProviderException |
| * if the provider cannot be found |
| */ |
| public static Provider getProvider( Hashtable<Object, Object> env ) throws ProviderException |
| { |
| Provider provider; |
| String className = ( String ) env.get( BERLIB_PROVIDER ); |
| |
| // -------------------------------------------------------------------- |
| // Check for a valid property value |
| // -------------------------------------------------------------------- |
| if ( ( className == null ) || className.trim().equals( "" ) ) |
| { |
| throw new ProviderException( null, I18n.err( I18n.ERR_04180, BERLIB_PROVIDER ) ); |
| } |
| |
| try |
| { |
| Class<?> clazz = Class.forName( className ); |
| Method method = clazz.getMethod( "getProvider", (Class[])null ); |
| provider = ( Provider ) method.invoke( null, (Object[])null ); |
| } |
| catch ( ClassNotFoundException cnfe ) |
| { |
| ProviderException pe = new ProviderException( null, I18n.err( I18n.ERR_04181, className ) ); |
| pe.addThrowable( cnfe ); |
| throw pe; |
| } |
| catch ( NoSuchMethodException nsme ) |
| { |
| ProviderException pe = new ProviderException( null, I18n.err( I18n.ERR_04182, className ) ); |
| pe.addThrowable( nsme ); |
| throw pe; |
| } |
| catch ( IllegalAccessException iae ) |
| { |
| ProviderException pe = new ProviderException( null, I18n.err( I18n.ERR_04183, className ) ); |
| pe.addThrowable( iae ); |
| throw pe; |
| } |
| catch ( InvocationTargetException ite ) |
| { |
| ProviderException pe = new ProviderException( null, I18n.err( I18n.ERR_04184, className, ite.getTargetException() ) ); |
| pe.addThrowable( ite.getTargetException() ); |
| throw pe; |
| } |
| |
| return provider; |
| } |
| |
| |
| /** |
| * Loads the properties for the effective environment. First searches class |
| * path for the default berlib.properties file. If it cannot find the file |
| * on the classpath it loads the defaults in the default berlib.properties |
| * file found in $JAVA_HOME/lib/berlib.properties. If the default file is |
| * not found and no berlib.properties are found on the classpath then the |
| * default provider is used. Once the property is set overriding values are |
| * searched for in the System's properties specified at startup using the |
| * <code>-Dproperty=value</code><i>java</i> command-line arguments. |
| * |
| * @return the environment properties TODO why are we not throwing |
| * ProviderExceptions here? |
| */ |
| public static Properties getEnvironment() |
| { |
| // Prop file not on classpath so we complain and use the default! |
| Properties env = new Properties(); |
| env.setProperty( BERLIB_PROVIDER, DEFAULT_PROVIDER ); |
| monitor.usingDefaults( USING_DEFAULTS_MSG, env ); |
| return env; |
| } |
| } |