8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster/**
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Copyright (c) 2005 Sun Microsystems Inc. All Rights Reserved
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * The contents of this file are subject to the terms
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * of the Common Development and Distribution License
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * (the License). You may not use this file except in
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * compliance with the License.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * You can obtain a copy of the License at
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * https://opensso.dev.java.net/public/CDDLv1.0.html or
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * opensso/legal/CDDLv1.0.txt
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * See the License for the specific language governing
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * permission and limitations under the License.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * When distributing Covered Code, include this CDDL
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Header Notice in each file and include the License file
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * at opensso/legal/CDDLv1.0.txt.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * If applicable, add the following below the CDDL Header,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * with the fields enclosed by brackets [] replaced by
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * your own identifying information:
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * "Portions Copyrighted [year] [name of copyright owner]"
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * $Id: IdServicesFactory.java,v 1.4 2008/06/27 20:56:23 arviranga Exp $
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
a335d7c88ef4381f965813458962419a72cb7098Neil Madden/*
a335d7c88ef4381f965813458962419a72cb7098Neil Madden * Portions Copyrighted 2014 ForgeRock, AS.
a335d7c88ef4381f965813458962419a72cb7098Neil Madden */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
a335d7c88ef4381f965813458962419a72cb7098Neil Maddenpackage com.sun.identity.idm;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.iplanet.am.sdk.AMSDKBundle;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.iplanet.am.util.SystemProperties;
a335d7c88ef4381f965813458962419a72cb7098Neil Maddenimport com.sun.identity.shared.debug.Debug;
a335d7c88ef4381f965813458962419a72cb7098Neil Maddenimport org.forgerock.openam.idm.LowerCaseIdCachedServicesDecorator;
a335d7c88ef4381f965813458962419a72cb7098Neil Maddenimport org.forgerock.openam.idm.LowerCaseIdServicesDecorator;
a335d7c88ef4381f965813458962419a72cb7098Neil Madden
a335d7c88ef4381f965813458962419a72cb7098Neil Maddenimport java.security.ProviderException;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster/**
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * A Factory which provides access to the Directory Services. This Class
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * provides API's to return the appropriate implementation classes for
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * configured packages (viz., ldap or remote).
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterpublic class IdServicesFactory {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
a335d7c88ef4381f965813458962419a72cb7098Neil Madden private static volatile IdServices idServices;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
a335d7c88ef4381f965813458962419a72cb7098Neil Madden private static final Debug DEBUG = Debug.getInstance("amIdm");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
a335d7c88ef4381f965813458962419a72cb7098Neil Madden private static volatile boolean isInitialized = false;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster private final static String CONFIGURED_SDK_PACKAGE_PROPERTY =
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster "com.iplanet.am.sdk.package";
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster private final static String SERVER_PACKAGE =
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster "com.iplanet.am.sdk.ldap";
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster private final static String REMOTE_PACKAGE =
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster "com.iplanet.am.sdk.remote";
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster private final static String SERVER_IDM_PACKAGE =
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster "com.sun.identity.idm.server";
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster private final static String REMOTE_IDM_PACKAGE =
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster "com.sun.identity.idm.remote";
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster private final static String ID_SERVICES_PROVIDER_CLASS =
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster "IdServicesProviderImpl";
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster private final static String REMOTE_SERVICES_PROVIDER_CLASS =
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster "IdRemoteServicesProviderImpl";
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster private final static String PACKAGE_SEPARATOR = ".";
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
a335d7c88ef4381f965813458962419a72cb7098Neil Madden /**
a335d7c88ef4381f965813458962419a72cb7098Neil Madden * System property to set to force all attribute names to be converted to lower case. Defaults to true.
a335d7c88ef4381f965813458962419a72cb7098Neil Madden */
a335d7c88ef4381f965813458962419a72cb7098Neil Madden private static final String USE_LOWERCASE_NAMES_PROPERTY = "org.forgerock.openam.idm.attribute.names.lower.case";
a335d7c88ef4381f965813458962419a72cb7098Neil Madden
a335d7c88ef4381f965813458962419a72cb7098Neil Madden /**
a335d7c88ef4381f965813458962419a72cb7098Neil Madden * Whether to convert all attribute names to lower case or not.
a335d7c88ef4381f965813458962419a72cb7098Neil Madden */
e4c435db2e64b396f97aabc84fa409decc921989Neil Madden private static volatile boolean useLowerCaseNames = false;
a335d7c88ef4381f965813458962419a72cb7098Neil Madden
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster private static void initialize() {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster String configuredSDK = SystemProperties.get(
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster CONFIGURED_SDK_PACKAGE_PROPERTY);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
e4c435db2e64b396f97aabc84fa409decc921989Neil Madden useLowerCaseNames = SystemProperties.getAsBoolean(USE_LOWERCASE_NAMES_PROPERTY, false);
a335d7c88ef4381f965813458962419a72cb7098Neil Madden
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster boolean isCriticalErrorIfClassNotFound = true;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if ((configuredSDK == null) || (configuredSDK.equals(SERVER_PACKAGE))) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Use the IdRepo server package if nothing has been configured or
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // if Package is configured
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster try {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster isCriticalErrorIfClassNotFound = false;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster instantiateImpls(SERVER_IDM_PACKAGE,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster ID_SERVICES_PROVIDER_CLASS,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster isCriticalErrorIfClassNotFound);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } catch (ProviderException pe) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Probably remote mode without the property being configured.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // So try initializing the REMOTE packages. Use try Remote SDK
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Package
a335d7c88ef4381f965813458962419a72cb7098Neil Madden if (DEBUG.messageEnabled()) {
a335d7c88ef4381f965813458962419a72cb7098Neil Madden DEBUG.message("IdServicesFactory.static{} - Initializing "
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster + "the server packages failed. Hence trying the "
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster + "remote client sdk pacakage");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster isCriticalErrorIfClassNotFound = true;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster instantiateImpls(REMOTE_IDM_PACKAGE,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster REMOTE_SERVICES_PROVIDER_CLASS,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster isCriticalErrorIfClassNotFound);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } else if (configuredSDK.equals(REMOTE_PACKAGE)) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Use the Remote idRepo Package
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster instantiateImpls(REMOTE_IDM_PACKAGE,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster REMOTE_SERVICES_PROVIDER_CLASS,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster isCriticalErrorIfClassNotFound);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } else { // Mostly a mis-configuration. Fall back to default.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // The configured package name does not match
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster instantiateImpls(SERVER_IDM_PACKAGE, ID_SERVICES_PROVIDER_CLASS,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster isCriticalErrorIfClassNotFound);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster isInitialized = true;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster private static void instantiateImpls(String packageName, String className,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster boolean isCriticalErrorIfClassNotFound) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster String providerClass = packageName + PACKAGE_SEPARATOR + className;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster try {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster IdServicesProvider idServicesProvider = (IdServicesProvider) Class
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster .forName(providerClass).newInstance();
a335d7c88ef4381f965813458962419a72cb7098Neil Madden IdServices impl = idServicesProvider.getProvider();
a335d7c88ef4381f965813458962419a72cb7098Neil Madden
a335d7c88ef4381f965813458962419a72cb7098Neil Madden // OPENAM-3159: Ensure attribute keys are always lower case for consistency
a335d7c88ef4381f965813458962419a72cb7098Neil Madden if (useLowerCaseNames) {
a335d7c88ef4381f965813458962419a72cb7098Neil Madden // Use correct decorator for cached vs non-cached implementations
a335d7c88ef4381f965813458962419a72cb7098Neil Madden impl = (impl instanceof IdCachedServices)
a335d7c88ef4381f965813458962419a72cb7098Neil Madden ? new LowerCaseIdCachedServicesDecorator((IdCachedServices) impl)
a335d7c88ef4381f965813458962419a72cb7098Neil Madden : new LowerCaseIdServicesDecorator(impl);
a335d7c88ef4381f965813458962419a72cb7098Neil Madden }
a335d7c88ef4381f965813458962419a72cb7098Neil Madden
a335d7c88ef4381f965813458962419a72cb7098Neil Madden idServices = impl;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } catch (InstantiationException e) {
a335d7c88ef4381f965813458962419a72cb7098Neil Madden DEBUG.error("IdServicesFactory.instantiateImpls()- "
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster + "Initializing Impls from package: " + packageName
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster + " FAILED!", e);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster throw new ProviderException(AMSDKBundle.getString("300"));
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } catch (IllegalAccessException e) {
a335d7c88ef4381f965813458962419a72cb7098Neil Madden DEBUG.error("IdServicesFactory.instantiateImpls()- "
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster + "Initializing Impls from package: " + packageName
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster + " FAILED!", e);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster throw new ProviderException(AMSDKBundle.getString("300"));
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } catch (ClassNotFoundException e) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster String message = "IdServicesFactory.instantiateImpls()- "
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster + "Initializing Impls from package: " + packageName
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster + " FAILED!";
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (isCriticalErrorIfClassNotFound) {
a335d7c88ef4381f965813458962419a72cb7098Neil Madden DEBUG.error(message, e);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } else {
a335d7c88ef4381f965813458962419a72cb7098Neil Madden DEBUG.warning(message, e);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster throw new ProviderException(AMSDKBundle.getString("300"));
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
a335d7c88ef4381f965813458962419a72cb7098Neil Madden if (DEBUG.messageEnabled()) {
a335d7c88ef4381f965813458962419a72cb7098Neil Madden DEBUG.message("IdServicesFactory.instantiateImpls() - "
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster + "Successfully initialized Impls Using Impl Package: "
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster + packageName + " for accessing Directory Services");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster private static boolean isInitialized() {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return isInitialized;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster public static IdServices getDataStoreServices() {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (!isInitialized()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster initialize();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return idServices;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster}