AMCommonUtils.java revision a14393818a78c503f7715c393044b33c86e90195
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2005 Sun Microsystems Inc. All Rights Reserved
*
* The contents of this file are subject to the terms
* of the Common Development and Distribution License
* (the License). You may not use this file except in
* compliance with the License.
*
* You can obtain a copy of the License at
* https://opensso.dev.java.net/public/CDDLv1.0.html or
* opensso/legal/CDDLv1.0.txt
* See the License for the specific language governing
* permission and limitations under the License.
*
* When distributing Covered Code, include this CDDL
* Header Notice in each file and include the License file
* at opensso/legal/CDDLv1.0.txt.
* If applicable, add the following below the CDDL Header,
* with the fields enclosed by brackets [] replaced by
* your own identifying information:
* "Portions Copyrighted [year] [name of copyright owner]"
*
* $Id: AMCommonUtils.java,v 1.7 2009/01/28 05:34:46 ww203982 Exp $
*
* Portions Copyright 2015 ForgeRock AS.
*/
package com.iplanet.am.sdk;
import com.iplanet.am.util.SystemProperties;
import com.iplanet.services.ldap.Attr;
import com.iplanet.services.ldap.AttrSet;
import com.iplanet.sso.SSOException;
import com.iplanet.sso.SSOToken;
import com.sun.identity.security.AdminTokenAction;
import com.sun.identity.shared.debug.Debug;
import com.sun.identity.sm.SMSException;
import com.sun.identity.sm.SchemaType;
import com.sun.identity.sm.ServiceConfig;
import com.sun.identity.sm.ServiceConfigManager;
import org.forgerock.openam.ldap.LDAPUtils;
import org.forgerock.opendj.ldap.DN;
import java.security.AccessController;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/**
* This class contains all the miscellaneous utility methods used in the
* <code>com.iplanet.am.sdk</code> package.
*
* @deprecated As of Sun Java System Access Manager 7.1.
*/
public class AMCommonUtils implements AMConstants {
// Constants
private static final String LOCALE_PROPERTY = "Locale";
private static final String AM_SDK_DEBUG_FILE = "amProfile";
/**
* Debug variable to be used by AM SDK package
*/
static Debug debug;
protected static Map supportedTypes = new HashMap();
protected static Map supportedEntitiesBasedOnType = new HashMap();
protected static Map supportedEntitiesBasedOnName = new HashMap();
protected static Map supportedNames = new HashMap();
protected static Map creationtemplateMap = new HashMap();
protected static Map statusAttributeMap = new HashMap();
private static final String LOCALE_INTEGRATION_PROPERTY =
"locale.integration";
private static final String EXTERNAL_ATTRIBUTES_FETCH_ENABLED_ATTR =
"iplanet-am-admin-console-external-attribute-fetch-enabled";
protected static boolean integrateLocale = true;
private static Set supportedEntities = new HashSet();
static {
debug = Debug.getInstance(AM_SDK_DEBUG_FILE);
String cCaller = SystemProperties.get(LOCALE_INTEGRATION_PROPERTY);
if ((cCaller == null) || (cCaller.equalsIgnoreCase("true"))) {
integrateLocale = true;
if (debug.messageEnabled()) {
debug.message("AM SDK: Locale integration enabled");
}
} else {
integrateLocale = false;
}
try {
populateManagedObjects();
} catch (Throwable t) {
if (debug.messageEnabled()) {
debug.message("AMCommonUtils:Initial: "
+ " Caught exception in static block", t);
}
}
}
/**
* Method to get the user locale.
*
* @param token
* SSOToken of the authenticated user
* @return a String value representing the user locale
*/
protected static String getUserLocale(SSOToken token) {
try {
String locale = token.getProperty(LOCALE_PROPERTY);
if (debug.messageEnabled()) {
debug.message("AMCommonUtils.getUserLocale(): locale = "
+ locale);
}
return locale;
} catch (SSOException ssoe) {
debug.error("AMCommonUtils.getUserLocale(): missing locale, "
+ "setting to null");
return null;
}
}
/**
* Combines 2 AttrSets and returns the result set. The original sets are not
* modified.
*
* @param attrSet1
* the first AttrSet
* @param attrSet2
* the second AttrSet
* @return an AttrSet which has combined values of attrSet1 & attrSet2
*/
protected static AttrSet combineAttrSets(AttrSet attrSet1, AttrSet attrSet2)
{
AttrSet retAttrSet = new AttrSet();
if (attrSet1 != null) {
int count = attrSet1.size();
for (int i = 0; i < count; i++) {
Attr attr = attrSet1.elementAt(i);
retAttrSet.add(attr);
}
}
if (attrSet2 != null) {
int count = attrSet2.size();
for (int i = 0; i < count; i++) {
Attr attr = attrSet2.elementAt(i);
retAttrSet.add(attr);
}
}
return retAttrSet;
}
/**
* Merge the values in two maps and return the result map. The values in the
* smaller map are merged with the larger map and the larger map is
* returned.
*
* @param mapA
* the first map
* @param mapB
* the second map
* @return a result map which the biggest of the two maps with values merged
* from the smaller one.
*/
protected static Map mergeMaps(Map mapA, Map mapB) {
if (mapA == null && mapB == null) {
return null;
}
if (mapA == null || mapA.isEmpty()) {
return mapB;
} else if (mapB == null || mapB.isEmpty()) {
return mapA;
}
// Find the map with smaller size and iterate through it.
Map bigMap = ((mapA.size() > mapB.size()) ? mapA : mapB);
Map smallMap = ((mapA.size() <= mapB.size()) ? mapA : mapB);
Iterator itr = smallMap.keySet().iterator();
while (itr.hasNext()) {
String attrName = (String) itr.next();
Set values = (Set) bigMap.get(attrName);
if (values != null) {
values.addAll((Set) smallMap.get(attrName));
} else {
bigMap.put(attrName, (Set) smallMap.get(attrName));
}
}
return bigMap;
}
protected static String mapSetToString(Map map) {
StringBuffer sb = new StringBuffer();
if (map != null && !map.isEmpty()) {
Iterator itr = map.keySet().iterator();
while (itr.hasNext()) {
String name = (String) itr.next();
Set values = (Set) map.get(name);
sb.append("\n\tName: ").append(name);
sb.append(" Values: ").append(values.toString());
}
} else {
sb.append("<empty>");
}
return sb.toString();
}
protected static String mapByteToString(Map map) {
StringBuffer sb = new StringBuffer();
if (map != null && !map.isEmpty()) {
Iterator itr = map.keySet().iterator();
while (itr.hasNext()) {
String name = (String) itr.next();
byte[][] values = (byte[][]) map.get(name);
sb.append("\n\tName: ").append(name);
sb.append(" Values: ").append(values);
}
} else {
sb.append("<empty>");
}
return sb.toString();
}
protected static Set getSetCopy(Set values) {
Set copyValues = Collections.EMPTY_SET;
if (!values.isEmpty()) {
copyValues = new HashSet(values.size());
Iterator itr = values.iterator();
while (itr.hasNext()) {
String value = (String) itr.next();
copyValues.add(value);
}
}
return copyValues;
}
/**
* Method to convert a String array to a set
*
* @param strs
* the String array
* @return a Set representing the String array
*/
protected static Set stringArrayToSet(String[] strs) {
int count = strs.length;
Set set = ((count > 0) ? new HashSet(count) : new HashSet());
for (int i = 0; i < count; i++) {
set.add(strs[i]);
}
return set;
}
protected static Map attrSetToMap(AttrSet attrSet) {
return attrSetToMap(attrSet, false);
}
/**
* Method to convert a AttrSet object to Map.
*
* @param attrSet
* the AttrSet to be converted to a Map
* @param fetchByteValues
* if false stringValues are added, if true byteValues are added.
* @return a Map containing attribute names as key's and a Set of attribute
* values or byte Values
*/
protected static Map attrSetToMap(AttrSet attrSet, boolean fetchByteValues)
{
Map attributesMap = new AMHashMap(fetchByteValues);
if (attrSet == null) {
return attributesMap;
}
int attrSetSize = attrSet.size();
if (!fetchByteValues) {
for (int i = 0; i < attrSetSize; i++) {
Attr attr = attrSet.elementAt(i);
String values[] = attr.getStringValues();
attributesMap.put(attr.getName(), stringArrayToSet(values));
}
} else {
for (int i = 0; i < attrSetSize; i++) {
Attr attr = attrSet.elementAt(i);
attributesMap.put(attr.getName(), attr.getByteValues());
}
}
return attributesMap;
}
/**
* Method to convert a Map to AttrSet.
*
* @param map
* a map contaning attribute names as keys and a Set of attribute
* values corresponding to each map key.
* @return an AttrSet having the contents of the supplied map
*/
protected static AttrSet mapToAttrSet(Map map) {
return mapToAttrSet(map, false);
}
/**
* Method to convert a Map to AttrSet.
*
* @param map
* a map contaning attribute names as keys and a Set of attribute
* values corresponding to each map key.
* @param byteValues
* if true then values are bytes otherwise strings
* @return an AttrSet having the contents of the supplied map
*/
protected static AttrSet mapToAttrSet(Map map, boolean byteValues) {
AttrSet attrSet = new AttrSet();
if (map == null) {
return attrSet;
}
if (!byteValues) {
Iterator itr = map.keySet().iterator();
while (itr.hasNext()) {
String attrName = (String) (itr.next());
Set set = (Set) (map.get(attrName));
String attrValues[] = (set == null ? null : (String[]) set
.toArray(new String[set.size()]));
attrSet.replace(new Attr(attrName, attrValues));
}
} else {
Iterator itr = map.keySet().iterator();
while (itr.hasNext()) {
String attrName = (String) (itr.next());
byte[][] attrValues = (byte[][]) (map.get(attrName));
attrSet.replace(new Attr(attrName, attrValues));
}
}
return attrSet;
}
/**
* Gets the principal DN String in RFC lowercase format from the SSOToken
*
* @param token
* a valid SSOToken
* @return a principal DN corresponding to token
* @throws SSOException
* if the token is not valid
*/
protected static String getPrincipalDN(SSOToken token) throws SSOException {
String principalName = token.getPrincipal().getName();
return LDAPUtils.formatToRFC(principalName);
}
/**
* Combines two sets which contains objectclass values of an entry in a case
* insensitive manner. OC values are sometimes returned by LDAP in mixed
* case and when duplicate values for Objectclass exists in a mixed case,
* there is a Object class violation Note: there is a possibility that this
* method will return null
*/
public static Set combineOCs(Set one, Set two) {
if (one == null || one.isEmpty()) {
return two;
}
if (two == null || two.isEmpty()) {
return one;
}
Set resultSet = new HashSet();
Iterator itr1 = one.iterator();
while (itr1.hasNext()) {
String value1 = (String) itr1.next();
resultSet.add(value1.toLowerCase());
}
Iterator itr2 = two.iterator();
while (itr2.hasNext()) {
String value2 = (String) itr2.next();
resultSet.add(value2.toLowerCase());
}
return resultSet;
}
/**
* Method to compare all the object classes in the Set with the specfied
* object class. Will do a case insensitive comparision.
*
* @param objectClasses
* Set of object classes
* @param objectClass
* the specified object class
* @return true if the specified object class is present. False otherwise.
*/
protected static boolean isObjectClassPresent(Set objectClasses,
String objectClass) {
if (objectClasses != null && !objectClasses.isEmpty()) {
Iterator itr = objectClasses.iterator();
while (itr.hasNext()) {
String serviceOC = (String) itr.next();
if (serviceOC.equalsIgnoreCase(objectClass)) {
return true;
}
}
}
return false;
}
/**
* Method which removes the specified object class from original set and
* returns the set of object classes that were removed.
*
* @param origSet
* the original Set
* @param removeOCs
* the Set of object classes to be removed
* @return the Set of object classes that were removed.
*/
public static Set updateAndGetRemovableOCs(Set origSet, Set removeOCs) {
// The remove OCs will be removed from the origSet and only the ones
// that were removed will be returned
Set returnOCs = removeOCs;
if (removeOCs != null && !removeOCs.isEmpty()) {
returnOCs = new HashSet();
Iterator itr1 = origSet.iterator();
while (itr1.hasNext()) {
String origOC = (String) itr1.next();
Iterator itr2 = removeOCs.iterator();
while (itr2.hasNext()) {
String removeOC = (String) itr2.next();
if (origOC.equalsIgnoreCase(removeOC)) {
// Can't remove from orig set directly. Will throw
// ConcurrentModificatiomException
returnOCs.add(origOC);
break;
}
}
}
origSet.removeAll(returnOCs);
}
return returnOCs;
}
/**
* Removes Empty sets from attribute-value maps. So that SDK does not try to
* remove these attributes from newly created entries. Such empty sets
* should be ignored, when entry is being created.
*
* @param attrMap
* @return map without empty set.
*/
public static Map removeEmptyValues(Map attrMap) {
Map finalMap = new HashMap();
Iterator iter = attrMap.keySet().iterator();
while (iter.hasNext()) {
String tStr = (String) iter.next();
Set s = (Set) attrMap.get(tStr);
if (!s.isEmpty()) {
finalMap.put(tStr, attrMap.get(tStr));
}
}
return finalMap;
}
protected static boolean populateManagedObjects() {
try {
SSOToken token = (SSOToken) AccessController
.doPrivileged(AdminTokenAction.getInstance());
ServiceConfigManager scm = new ServiceConfigManager("DAI", token);
ServiceConfig gc = scm.getGlobalConfig(null);
Set managedObjects = gc.getSubConfigNames("*", "ManagedObjects");
if (debug.messageEnabled()) {
debug.message("AMCommonUtils.populateManagedObjects. "
+ "managedObjects=" + managedObjects);
}
if (managedObjects == null || managedObjects.isEmpty()) {
return false;
// populateManagedObjectsWithDefaults();
}
Iterator mIter = managedObjects.iterator();
while (mIter.hasNext()) {
String mo = (String) mIter.next();
mo = mo.toLowerCase();
ServiceConfig sc = gc.getSubConfig(mo);
if (sc != null) {
Map attrs = sc.getAttributes();
String oc = getValue((Set) attrs.get("objectclass"), mo);
String ct = getValue((Set) attrs
.get("creationtemplatename"), mo);
String st = getValue((Set) attrs.get("searchtemplatename"),
mo);
String stAttrName = getValue((Set) attrs
.get("statusattribute"), mo);
String serviceName = getValue((Set) attrs
.get("servicename"), mo);
String parentRDN = getValue((Set) attrs
.get("parentcontainerdn"), mo);
String parentType = getValue((Set) attrs
.get("parentcontainertype"), mo);
/*
* Default to parent Type as an organization, if no value
* defined.
*/
int parentTypeInt = (parentType != null && parentType
.length() > 0) ? Integer.parseInt(parentType)
: AMObject.ORGANIZATION;
// Assumes a type is always defined in the config.
// TODO be careful with NPE here.
String typeS = getValue((Set) attrs.get("type"), mo);
int type = Integer.parseInt(typeS);
supportedTypes.put(mo, typeS);
supportedNames.put(typeS, mo);
if (oc != null) {
AMObjectClassManager.objectClassMap.put(typeS, oc);
AMObjectClassManager.objectTypeMap.put(oc, typeS);
}
if (st != null) {
AMSearchFilterManager.searchtemplateMap.put(typeS, st);
}
if (ct != null) {
creationtemplateMap.put(typeS, ct);
}
if (stAttrName != null) {
statusAttributeMap.put(typeS, stAttrName);
}
AMEntityType newType = new AMEntityType(mo, type,
serviceName, st, ct, parentRDN, parentTypeInt,
null, stAttrName, oc);
supportedEntities.add(newType);
supportedEntitiesBasedOnType.put(typeS, newType);
supportedEntitiesBasedOnName.put(mo, newType);
}
}
if (debug.messageEnabled()) {
debug.message("CreationTemplae MAP = "
+ creationtemplateMap.toString());
debug.message("SearchTemplate Map = "
+ AMSearchFilterManager.searchtemplateMap.toString());
debug.message("ObjectClass-Type Map = "
+ AMObjectClassManager.objectClassMap.toString());
debug.message("Type-ObjectClass MAP = "
+ AMObjectClassManager.objectTypeMap.toString());
debug.message("Supported names-type = "
+ supportedTypes.toString());
debug.message("Status Attributes= "
+ statusAttributeMap.toString());
}
} catch (SMSException se) {
if (debug.messageEnabled()) {
debug.message("AMCommonUtils.populateManagedObjects: "
+ " Got SMSException :", se);
}
return false;
// populateManagedObjectsWithDefaults();
} catch (SSOException ssoe) {
return false;
// populateManagedObjectsWithDefaults();
}
return true;
}
/**
* Returns a Set of supported entity types
*
*/
protected static Set getSupportedEntityTypes() {
return supportedEntities;
}
/**
* Method to check if the CallBack plugins are enabled for reading external
* attributes.
*/
protected static boolean isExternalGetAttributesEnabled(String orgDN) {
// Obtain the ServiceConfig
Set attrVal;
SSOToken token = (SSOToken) AccessController
.doPrivileged(AdminTokenAction.getInstance());
try {
// Get the org config
ServiceConfig sc = AMServiceUtils.getOrgConfig(token, orgDN,
ADMINISTRATION_SERVICE);
if (sc != null) {
Map attributes = sc.getAttributes();
attrVal = (Set) attributes
.get(EXTERNAL_ATTRIBUTES_FETCH_ENABLED_ATTR);
} else {
attrVal = getDefaultGlobalConfig(token,
EXTERNAL_ATTRIBUTES_FETCH_ENABLED_ATTR);
}
} catch (Exception ee) {
attrVal = getDefaultGlobalConfig(token,
EXTERNAL_ATTRIBUTES_FETCH_ENABLED_ATTR);
}
boolean enabled = false;
if (attrVal != null && !attrVal.isEmpty()) {
String val = (String) attrVal.iterator().next();
enabled = (val.equalsIgnoreCase("true"));
}
if (debug.messageEnabled()) {
debug.message("AMCommonUtils.isExternalGetAttributeEnabled() = "
+ enabled);
}
return enabled;
}
private static Set getDefaultGlobalConfig(SSOToken token, String attrName) {
// Org Config may not exist. Get default values
if (debug.messageEnabled()) {
debug.message("AMCommonUtils.getDefaultGlobalConfig() "
+ "Organization config for service ("
+ ADMINISTRATION_SERVICE + "," + attrName
+ ") not found. Obtaining default service "
+ "config values ..");
}
try {
Map defaultValues = AMServiceUtils.getServiceConfig(token,
ADMINISTRATION_SERVICE, SchemaType.ORGANIZATION);
if (defaultValues != null) {
return (Set) defaultValues.get(attrName);
}
} catch (Exception e) {
if (debug.warningEnabled()) {
debug.warning("AMCommonUtils.getDefaultGlobalConfig(): "
+ "Unable to get default global config information", e);
}
}
return null;
}
protected static void populateManagedObjectsWithDefaults() {
}
private static String getValue(Set ocSet, String objectName) {
if (ocSet == null || ocSet.isEmpty()) {
return null;
}
return ((String) ocSet.iterator().next());
}
}