SMSEmbeddedLdapObject.java revision 8af80418ba1ec431c8027fa9668e5678658d3611
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster/**
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster* Copyright (c) 2009 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: SMSEmbeddedLdapObject.java,v 1.3 2009/10/28 04:24:27 hengming Exp $
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster*/
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster/*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Portions Copyrighted [2011] [ForgeRock AS]
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterpackage com.sun.identity.sm.ldap;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport java.text.MessageFormat;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport java.util.ArrayList;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport java.util.Collections;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport java.util.HashMap;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport java.util.HashSet;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport java.util.Iterator;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport java.util.LinkedHashSet;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport java.util.LinkedList;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport java.util.List;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport java.util.Map;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport java.util.ResourceBundle;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport java.util.Set;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport javax.naming.NamingEnumeration;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport javax.naming.NamingException;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport javax.naming.directory.DirContext;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport javax.naming.directory.ModificationItem;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.sun.identity.shared.ldap.util.DN;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.sun.identity.shared.locale.AMResourceBundleCache;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.sun.identity.shared.debug.Debug;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.sun.identity.shared.datastruct.OrderedSet;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.iplanet.sso.SSOException;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.iplanet.sso.SSOToken;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.iplanet.ums.IUMSConstants;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.sun.identity.sm.SMSEntry;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.sun.identity.sm.SMSException;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.sun.identity.sm.SMSNotificationManager;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.sun.identity.sm.SMSObjectDB;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport com.sun.identity.sm.SMSObjectListener;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport org.opends.server.core.AddOperation;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport org.opends.server.core.DeleteOperation;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport org.opends.server.core.ModifyOperation;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport org.opends.server.protocols.internal.InternalClientConnection;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport org.opends.server.protocols.internal.InternalSearchOperation;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport org.opends.server.protocols.ldap.LDAPAttribute;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport org.opends.server.protocols.ldap.LDAPModification;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport org.opends.server.types.DereferencePolicy;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport org.opends.server.types.DirectoryException;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport org.opends.server.types.ModificationType;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport org.opends.server.types.ResultCode;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport org.opends.server.types.SearchScope;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterimport org.opends.server.types.SearchResultEntry;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster/**
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * This object represents an LDAP entry in the directory server. The UMS have an
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * equivalent class called PersistentObject. The SMS could not integrate with
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * PersistentObject, because of the its dependecy on the Session object. This
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * would mean that, to instantiate an PersistentObject inside SMS, we need to
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * create an UMS instance, which would be having directory parameters of SMS.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * <p>
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * This class is used both to read and write information into the directory
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * server. The appropriate constructors discusses it is done.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * <p>
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * There can be only three types of SMS entries in the directory (i) entry with
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * organizationUnit object class (attribute: ou) (ii) entry with sunService
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * object class (attributes: ou, labeledURI, sunServiceSchema, sunPluginSchema,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * and sunKeyValue (sunXMLKeyValue, in the future) (iii) entry with
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * sunServiceComponent object class (attributes: ou, sunServiceID,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * sunSMSPriority, sunKeyValue. All the schema, configuration and plugin entries
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * will be stored using the above entries.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterpublic class SMSEmbeddedLdapObject extends SMSObjectDB
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster implements SMSObjectListener {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster static int entriesPresentCacheSize = 1000;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster static boolean initializedNotification;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster static Set entriesPresent = Collections.synchronizedSet(
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster new LinkedHashSet());
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster static Set entriesNotPresent = Collections.synchronizedSet(
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster new LinkedHashSet());
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Other parameters
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster static ResourceBundle bundle;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster static boolean initialized = false;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster static Debug debug;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster static LinkedHashSet OU_ATTR;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster static LinkedHashSet O_ATTR;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster static InternalClientConnection icConn;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster static LinkedHashSet smsAttributes;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster static final String SMS_EMBEDDED_LDAP_OBJECT_SEARCH_LIMIT =
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster "com.sun.identity.sm.sms_embedded_ldap_object_search_limit";
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /**
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Public constructor for SMSEmbeddedLdapObject
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster public SMSEmbeddedLdapObject() throws SMSException {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Initialized (should be called only once by SMSEntry)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster initialize();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /**
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Synchronized initialized method
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster private synchronized void initialize() throws SMSException {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (initialized) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Obtain the I18N resource bundle & Debug
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug = Debug.getInstance("amSMSEmbeddedLdap");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster AMResourceBundleCache amCache = AMResourceBundleCache.getInstance();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster bundle = amCache.getResBundle(IUMSConstants.UMS_BUNDLE_NAME,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster java.util.Locale.ENGLISH);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster OU_ATTR = new LinkedHashSet(1);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster OU_ATTR.add(getNamingAttribute());
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster O_ATTR = new LinkedHashSet(1);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster O_ATTR.add(getOrgNamingAttribute());
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster icConn = InternalClientConnection.getRootConnection();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster try {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster String serviceDN = SMSEntry.SERVICES_RDN + SMSEntry.COMMA +
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster getRootSuffix();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (!entryExists(serviceDN)) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster Map attrs = new HashMap();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster Set attrValues = new HashSet();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster attrValues.add(SMSEntry.OC_TOP);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster attrValues.add(SMSEntry.OC_ORG_UNIT);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster attrs.put(SMSEntry.ATTR_OBJECTCLASS, attrValues);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster create(serviceDN, attrs);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } catch (Exception e) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Unable to initialize (trouble!!)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.error("SMSEmbeddedLdapObject.initialize: " +
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster "Unable to initalize(exception):", e);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster throw (new SMSException(IUMSConstants.UMS_BUNDLE_NAME,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster IUMSConstants.CONFIG_MGR_ERROR, null));
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster String[] smsAttrs = getAttributeNames();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster smsAttributes = new LinkedHashSet(smsAttrs.length);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster for(int i=0; i<smsAttrs.length; i++) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster smsAttributes.add(smsAttrs[i]);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster initialized = true;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster private void initializeNotification() {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (!initializedNotification) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // If cache is enabled, register for notification to maintian
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // internal cache of entriesPresent
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (SMSNotificationManager.isCacheEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster SMSNotificationManager.getInstance()
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster .registerCallbackHandler(this);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster initializedNotification = true;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /**
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Reads in the object from persistent store, assuming that the guid and the
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * SSOToken are valid
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster public Map read(SSOToken token, String dn) throws SMSException,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster SSOException {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (dn == null || dn.length() == 0 ) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // This must not be possible return an exception.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.error("SMSEmbeddedLdapObject.read: Null or Empty DN=" + dn);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster throw new SMSException("", "sms-NO_SUCH_OBJECT");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (!DN.isDN(dn)) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.warning("SMSEmbeddedLdapObject: Invalid DN=" + dn);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster String[] args = {dn};
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster throw new SMSException(IUMSConstants.UMS_BUNDLE_NAME,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster "sms-INVALID_DN", args);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Check if entry does not exist
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (SMSNotificationManager.isCacheEnabled() &&
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster entriesNotPresent.contains(dn)) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (debug.messageEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.message("SMSEmbeddedLdapObject:read Entry not present: "+
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster dn + " (checked in cached)");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return (null);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster try {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster InternalSearchOperation iso = icConn.processSearch(dn,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster SearchScope.BASE_OBJECT, DereferencePolicy.NEVER_DEREF_ALIASES,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster 0, 0, false, "(|(objectclass=*)(objectclass=ldapsubentry))",
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster smsAttributes);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster ResultCode resultCode = iso.getResultCode();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (resultCode == ResultCode.SUCCESS) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster LinkedList searchResult = iso.getSearchEntries();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (!searchResult.isEmpty()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster SearchResultEntry entry =
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster (SearchResultEntry)searchResult.get(0);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster List attributes = entry.getAttributes();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return EmbeddedSearchResultIterator.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster convertLDAPAttributeSetToMap(attributes);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } else {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return null;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } else if (resultCode == ResultCode.NO_SUCH_OBJECT) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Add to not present Set
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster objectChanged(dn, DELETE);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (debug.messageEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.message("SMSEmbeddedLdapObject.read: " +
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster "entry not present:"+ dn);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return null;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } else {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (debug.warningEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.warning("SMSEmbeddedLdapObject.read: " +
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster "Error in accessing entry DN: " + dn +
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster ", error code = " + resultCode);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster throw new SMSException("", "sms-entry-cannot-access");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } catch (DirectoryException dex) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (debug.warningEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.warning("SMSEmbeddedLdapObject.read: " +
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster "Error in accessing entry DN: " + dn, dex);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster throw new SMSException(dex, "sms-entry-cannot-access");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /**
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Create an entry in the directory
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster public void create(SSOToken token, String dn, Map attrs)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster throws SMSException, SSOException {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster create(dn, attrs);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Update entryPresent cache
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster objectChanged(dn, ADD);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /**
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Create an entry in the directory using the principal name
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster private static void create(String dn, Map attrs)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster throws SMSException, SSOException {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster List attrList = copyMapToAttrList(attrs);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster AddOperation ao = icConn.processAdd(dn, attrList);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster ResultCode resultCode = ao.getResultCode();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (resultCode == ResultCode.SUCCESS) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (debug.messageEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.message(
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster "SMSEmbeddedLdapObject.create: Successfully created" +
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster " entry: " + dn);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } else if (resultCode == ResultCode.ENTRY_ALREADY_EXISTS) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // During install time and other times,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // this error gets throws due to unknown issue. Issue:
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Hence mask it.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.warning("SMSEmbeddedLdapObject.create: Entry " +
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster "Already Exists Error for DN" + dn);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } else {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.error("SMSEmbeddedLdapObject.create: Error creating entry: "+
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster dn + ", error code = " + resultCode);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster throw new SMSException("", "sms-entry-cannot-create");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /**
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Save the entry using the token provided. The principal provided will be
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * used to get the proxy connection.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster public void modify(SSOToken token, String dn, ModificationItem mods[])
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster throws SMSException, SSOException {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster List modList = copyModItemsToLDAPModList(mods);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster ModifyOperation mo = icConn.processModify(dn, modList);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster ResultCode resultCode = mo.getResultCode();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (resultCode == ResultCode.SUCCESS) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (debug.messageEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.message("SMSEmbeddedLdapObject.modify: Successfully " +
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster "modified entry: " + dn);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } else {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.error("SMSEmbeddedLdapObject.modify: Error modifying entry "+
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster dn + " by Principal: " + token.getPrincipal().getName() +
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster ", error code = " + resultCode );
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster throw new SMSException("", "sms-entry-cannot-modify");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /**
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Delete the entry in the directory. This will delete sub-entries also!
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster public void delete(SSOToken token, String dn) throws SMSException,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster SSOException {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Check if there are sub-entries, delete if present
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster Iterator se = subEntries(token, dn, "*", 0, false, false).iterator();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster while (se.hasNext()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster String entry = (String) se.next();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (debug.messageEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.message("SMSEmbeddedLdapObject: deleting sub-entry: " +
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster entry);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster delete(token, getNamingAttribute() + "=" + entry + "," + dn);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Check if there are suborganizations, delete if present
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // The recursive 'false' here has the scope SCOPE_ONE
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // while searching for the suborgs.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Loop through the suborg at the first level and if there
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // is no next suborg, delete that.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster Set subOrgNames = searchSubOrgNames(token, dn, "*", 0, false, false,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster false);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster for (Iterator so = subOrgNames.iterator(); so.hasNext(); ) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster String subOrg = (String) so.next();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (debug.messageEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.message("SMSEmbeddedLdapObject: deleting " +
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster "suborganization: " + subOrg);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster delete(token, subOrg);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster DeleteOperation dop = icConn.processDelete(dn);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster ResultCode resultCode = dop.getResultCode();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (resultCode != ResultCode.SUCCESS) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (debug.warningEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.warning("SMSEmbeddedLdapObject.delete: " +
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster "Unable to delete entry:" + dn);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster throw (new SMSException("", "sms-entry-cannot-delete"));
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster objectChanged(dn, DELETE);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /**
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Returns the sub-entry names. Returns a set of RDNs that are sub-entries.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * The paramter <code>numOfEntries</code> identifies the number of entries
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * to return, if <code>0</code> returns all the entries.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster public Set subEntries(SSOToken token, String dn, String filter,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster int numOfEntries, boolean sortResults, boolean ascendingOrder)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster throws SMSException, SSOException {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (filter == null) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster filter = "*";
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (debug.messageEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.message("SMSEmbeddedLdapObject: SubEntries search: " + dn);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Construct the filter
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster String sfilter = "(objectClass=*)";
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (!filter.equals("*")) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // This is a workaround for Issue 3823, where DS returns an
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // empty set if restarted during OpenSSO operation
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster String[] objs = { filter };
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster sfilter = MessageFormat.format(getSearchFilter(),(Object[])objs);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster Set answer = getSubEntries(token, dn, sfilter, numOfEntries,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster sortResults, ascendingOrder);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return (answer);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster private Set getSubEntries(SSOToken token, String dn, String filter,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster int numOfEntries, boolean sortResults, boolean ascendingOrder)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster throws SMSException, SSOException {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // sorting is not implemented
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Get the sub entries
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster try {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster InternalSearchOperation iso = icConn.processSearch(dn,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster SearchScope.SINGLE_LEVEL, DereferencePolicy.NEVER_DEREF_ALIASES,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster numOfEntries, 0, false, filter, OU_ATTR, null, null);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster ResultCode resultCode = iso.getResultCode();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (resultCode == ResultCode.NO_SUCH_OBJECT) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (debug.messageEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.message("SMSEmbeddedLdapObject.getSubEntries(): " +
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster "entry not present:" + dn);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } else if (resultCode == ResultCode.SIZE_LIMIT_EXCEEDED) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (debug.messageEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.message("SMSEmbeddedLdapObject.getSubEntries: " +
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster "size limit " + numOfEntries + " exceeded for " +
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster "sub-entries: " + dn);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } else if (resultCode != ResultCode.SUCCESS) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (debug.warningEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.warning("SMSEmbeddedLdapObject.getSubEntries: " +
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster "Unable to search for " + "sub-entries: " + dn);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster throw new SMSException("", "sms-entry-cannot-search");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Construct the results and return
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster Set answer = new OrderedSet();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster LinkedList searchResult = iso.getSearchEntries();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster for(Iterator iter = searchResult.iterator(); iter.hasNext(); ) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster SearchResultEntry entry = (SearchResultEntry)iter.next();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster String edn = entry.getDN().toString();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (!edn.toLowerCase().startsWith("ou=")) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster continue;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster String rdn = entry.getDN().getRDN().getAttributeValue(0)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster .toString();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster answer.add(rdn);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (debug.messageEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.message("SMSEmbeddedLdapObject.getSubEntries: " +
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster "Successfully obtained sub-entries for : " + dn);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return (answer);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } catch (DirectoryException dex) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (debug.warningEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.warning("SMSEmbeddedLdapObject.getSubEntries: " +
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster "Unable to search for " + "sub-entries: " + dn, dex);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster throw new SMSException(dex, "sms-entry-cannot-search");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /**
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Returns the sub-entry names. Returns a set of RDNs that are sub-entries.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * The paramter <code>numOfEntries</code> identifies the number of entries
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * to return, if <code>0</code> returns all the entries.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster public Set schemaSubEntries(SSOToken token, String dn, String filter,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster String sidFilter, int numOfEntries, boolean sortResults,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster boolean ascendingOrder) throws SMSException, SSOException {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (debug.messageEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.message("SMSEmbeddedLdapObject: schemaSubEntries search: " +
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster dn);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Construct the filter
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster String[] objs = { filter, sidFilter };
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster String sfilter = MessageFormat.format(
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster getServiceIdSearchFilter(), (Object[])objs);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster Set answer = getSubEntries(token, dn, sfilter, numOfEntries,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster sortResults, ascendingOrder);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return (answer);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster public String toString() {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return ("SMSEmbeddedLdapObject");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster public Iterator search(SSOToken token, String startDN, String filter,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster int numOfEntries, int timeLimit, boolean sortResults,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster boolean ascendingOrder, Set excludes)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster throws SSOException, SMSException {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster InternalSearchOperation iso = searchObjects(startDN, filter,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster SearchScope.WHOLE_SUBTREE, numOfEntries, sortResults,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster ascendingOrder);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster ResultCode resultCode = iso.getResultCode();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (resultCode == ResultCode.SIZE_LIMIT_EXCEEDED) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (debug.messageEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.message("SMSEmbeddedLdapObject.search:" +
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster " size limit exceeded. numOfEntries = " + numOfEntries);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } else if (resultCode != ResultCode.SUCCESS) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (debug.warningEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.warning("SMSEmbeddedLdapObject.searchEx: Unable to " +
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster "search. startDN = " + startDN + ", filter = " +
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster filter + ", resultCode = " + resultCode);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster throw new SMSException("", "sms-error-in-searching");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster Map answer = new HashMap();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster LinkedList searchResult = iso.getSearchEntries();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return new EmbeddedSearchResultIterator(searchResult, excludes);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /**
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Returns LDAP entries that match the filter, using the start DN provided
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * in method
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster public Set search(SSOToken token, String startDN, String filter,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster int numOfEntries, int timeLimit, boolean sortResults,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster boolean ascendingOrder) throws SSOException, SMSException {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (debug.messageEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.message("SMSEmbeddedLdapObject.search: startDN = " +
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster startDN + ", filter: " + filter);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster InternalSearchOperation iso = searchObjects(startDN, filter,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster SearchScope.WHOLE_SUBTREE, numOfEntries, sortResults,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster ascendingOrder);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster ResultCode resultCode = iso.getResultCode();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (resultCode == ResultCode.SIZE_LIMIT_EXCEEDED) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (debug.messageEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.message("SMSEmbeddedLdapObject.search:" +
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster " size limit exceeded. numOfEntries = " + numOfEntries);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } else if (resultCode != ResultCode.SUCCESS) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (debug.warningEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.warning("SMSEmbeddedLdapObject.search: Unable to " +
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster "search. startDN = " + startDN + ", filter = " +
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster filter + ", resultCode = " + resultCode);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster throw new SMSException("", "sms-error-in-searching");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster Set answer = new OrderedSet();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster LinkedList searchResult = iso.getSearchEntries();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster for(Iterator iter = searchResult.iterator(); iter.hasNext(); ) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster SearchResultEntry entry = (SearchResultEntry)iter.next();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster String dn = entry.getDN().toString();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster answer.add(dn);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (debug.messageEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.message("SMSEmbeddedLdapObject.search: returned " +
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster "successfully: " + filter + "\n\tObjects: " + answer);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return answer;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster private InternalSearchOperation searchObjects(String startDN,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster String filter, SearchScope scope, int numOfEntries,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster boolean sortResults, boolean ascendingOrder)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster throws SSOException, SMSException {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // sorting is not implemented
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster try {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Get the sub entries
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster InternalSearchOperation iso = icConn.processSearch(startDN, scope,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster DereferencePolicy.NEVER_DEREF_ALIASES, numOfEntries, 0, false,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster filter, null, null, null);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return iso;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } catch (DirectoryException dex) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (debug.warningEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.warning("SMSEmbeddedLdapObject.searchObjects: " +
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster "Unable to " + "search. startDN = " + startDN +
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster ", filter = " + filter, dex);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster throw new SMSException(dex, "sms-error-in-searching");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /**
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Checks if the provided DN exists. Used by PolicyManager.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /**
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Checks if the provided DN exists. Used by PolicyManager.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster public boolean entryExists(SSOToken token, String dn) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (debug.messageEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.message("SMSEmbeddedLdapObject.entryExists: checking if " +
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster "entry exists: " + dn);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster dn = (new DN(dn)).toRFCString().toLowerCase();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Check the caches
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (SMSNotificationManager.isCacheEnabled() &&
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster entriesPresent.contains(dn)) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (debug.messageEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.message("SMSEmbeddedLdapObject.entryExists: " +
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster "entry present in cache: " + dn);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return (true);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } else if (SMSNotificationManager.isCacheEnabled() &&
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster entriesNotPresent.contains(dn)) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (debug.messageEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.message("SMSEmbeddedLdapObject.entryExists: " +
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster "entry present in not-present-cache: " + dn);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return (false);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Check if entry exisits
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster boolean entryExists = entryExists(dn);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Update the cache
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (entryExists && SMSNotificationManager.isCacheEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster initializeNotification();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster entriesPresent.add(dn);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (entriesPresent.size() > entriesPresentCacheSize) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster synchronized (entriesPresent) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster Iterator items = entriesPresent.iterator();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (items.hasNext()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster items.next();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster items.remove();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } else if (SMSNotificationManager.isCacheEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster initializeNotification();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster entriesNotPresent.add(dn);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (entriesNotPresent.size() > entriesPresentCacheSize) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster synchronized (entriesNotPresent) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster Iterator items = entriesNotPresent.iterator();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (items.hasNext()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster items.next();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster items.remove();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return (entryExists);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /**
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Checks if the provided DN exists.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster private static boolean entryExists(String dn) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster try {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster InternalSearchOperation iso = icConn.processSearch(dn,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster SearchScope.BASE_OBJECT, DereferencePolicy.NEVER_DEREF_ALIASES,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster 0, 0, false, "(|(objectclass=*)(objectclass=ldapsubentry))",
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster null);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster ResultCode resultCode = iso.getResultCode();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (resultCode == ResultCode.SUCCESS) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return true;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } else {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (debug.warningEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.warning("SMSEmbeddedLdapObject:entryExists: " + dn +
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster "does not exist. resultCode = " + resultCode);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return false;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } catch (DirectoryException dex) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (debug.warningEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.warning("SMSEmbeddedLdapObject:entryExists: " + dn +
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster "does not exist.", dex);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return false;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /**
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Registration of Notification Callbacks
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster public void registerCallbackHandler(SMSObjectListener changeListener)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster throws SMSException {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster LDAPEventManager.addObjectChangeListener(changeListener);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster public void deregisterCallbackHandler(String id) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster LDAPEventManager.removeObjectChangeListener();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Method to convert Map to LDAPAttributeSet
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster private static List copyMapToAttrList(Map attrs) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if ((attrs == null) || (attrs.isEmpty())) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return null;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster List attrList = new ArrayList(attrs.size());
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster for(Iterator iter = attrs.keySet().iterator(); iter.hasNext(); ) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster String attrName = (String)iter.next();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster Set values = (Set)attrs.get(attrName);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if ((values != null) && (!values.isEmpty())) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster List valueList = new ArrayList();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster valueList.addAll(values);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster attrList.add(new LDAPAttribute(attrName, valueList));
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return attrList;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Method to covert JNDI ModificationItems to LDAPModificationSet
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster private static List copyModItemsToLDAPModList(
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster ModificationItem mods[]) throws SMSException {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if ((mods == null) || (mods.length == 0)) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return null;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster List modList = new ArrayList(mods.length);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster try {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster for (int i = 0; i < mods.length; i++) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster javax.naming.directory.Attribute dAttr =
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster mods[i].getAttribute();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster String attrName = dAttr.getID();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster List values = new ArrayList();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster for(NamingEnumeration ne = dAttr.getAll(); ne.hasMore();) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster values.add((String) ne.next());
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster ModificationType modType = null;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster switch (mods[i].getModificationOp()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster case DirContext.ADD_ATTRIBUTE:
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster modType = ModificationType.ADD;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster break;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster case DirContext.REPLACE_ATTRIBUTE:
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster modType = ModificationType.REPLACE;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster break;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster case DirContext.REMOVE_ATTRIBUTE:
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster modType = ModificationType.DELETE;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster break;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (modType != null) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster modList.add(new LDAPModification(modType,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster new LDAPAttribute(attrName, values)));
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } catch (NamingException nne) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster throw (new SMSException(nne,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster "sms-cannot-copy-fromModItemToModSet"));
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return (modList);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster public void objectChanged(String dn, int type) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster dn = (new DN(dn)).toRFCString().toLowerCase();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (type == DELETE) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Remove from entriesPresent Set
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster entriesPresent.remove(dn);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } else if (type == ADD) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Remove from entriesNotPresent set
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster entriesNotPresent.remove(dn);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster public void allObjectsChanged() {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Not clear why this class is implemeting the SMSObjectListener
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // interface.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (SMSEntry.debug.warningEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster SMSEntry.debug.warning("SMSEmbeddedLDAPObject.allObjectsChanged:" +
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster " got notifications, all objects changed");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster entriesPresent.clear();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster entriesNotPresent.clear();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /**
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Returns the suborganization names. Returns a set of RDNs that are
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * suborganization name. The paramter <code>numOfEntries</code> identifies
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * the number of entries to return, if <code>0</code> returns all the
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * entries.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster public Set searchSubOrgNames(SSOToken token, String dn, String filter,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster int numOfEntries, boolean sortResults, boolean ascendingOrder,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster boolean recursive) throws SMSException, SSOException {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (debug.messageEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.message("SMSEmbeddedLdapObject.searchSubOrgNames: search: " +
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster dn);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Instead of constructing the filter in the framework(SMSEntry.java),
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Construct the filter here in SMSEmbeddedLdapObject or the plugin
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * implementation to support JDBC or other data store.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster String[] objs = { filter };
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster String FILTER_PATTERN_ORG = "(&(objectclass=" +
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster SMSEntry.OC_REALM_SERVICE + ")(" + SMSEntry.ORGANIZATION_RDN +
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster "={0}))";
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster String sfilter = MessageFormat.format(FILTER_PATTERN_ORG,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster (Object[])objs);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster Set answer = searchSubOrganizationNames(dn, sfilter, numOfEntries,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster sortResults, ascendingOrder, recursive);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return (answer);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster private Set searchSubOrganizationNames(String dn, String filter,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster int numOfEntries, boolean sortResults, boolean ascendingOrder,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster boolean recursive) throws SMSException, SSOException {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster SearchScope scope = (recursive) ? SearchScope.WHOLE_SUBTREE :
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster SearchScope.SINGLE_LEVEL;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster InternalSearchOperation iso = searchObjects(dn, filter,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster scope, numOfEntries, sortResults, ascendingOrder);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster ResultCode resultCode = iso.getResultCode();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (resultCode == ResultCode.NO_SUCH_OBJECT) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (debug.messageEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.message("SMSEmbeddedLdapObject." +
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster "searchSubOrganizationNames: suborg not present:" + dn);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } else if (resultCode == ResultCode.SIZE_LIMIT_EXCEEDED) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (debug.messageEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.message("SMSEmbeddedLdapObject." +
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster "searchSubOrganizationNames: size limit exceeded. " +
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster "numOfEntries = " + numOfEntries + ", dn = " + dn);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster } else if (resultCode != ResultCode.SUCCESS) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (debug.warningEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.warning("SMSEmbeddedLdapObject." +
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster "searchSubOrganizationNames: Unable to search. dn = "+
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster dn + ", filter = " + filter + ", resultCode = " +
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster resultCode);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster throw new SMSException("", "sms-suborg-cannot-search");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster Set answer = new OrderedSet();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster LinkedList searchResult = iso.getSearchEntries();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster for(Iterator iter = searchResult.iterator(); iter.hasNext(); ) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster SearchResultEntry entry = (SearchResultEntry)iter.next();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster String edn = entry.getDN().toString();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster answer.add(edn);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (debug.messageEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.message("SMSEmbeddedLdapObject.searchSubOrganizationName: " +
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster "Successfully obtained suborganization names for : " + dn);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.message("SMSEmbeddedLdapObject.searchSubOrganizationName: " +
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster "Successfully obtained suborganization names : " +
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster answer.toString());
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return (answer);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /**
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Returns the organization names. Returns a set of RDNs that are
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * organization name. The paramter <code>numOfEntries</code> identifies
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * the number of entries to return, if <code>0</code> returns all the
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * entries.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster public Set searchOrganizationNames(SSOToken token, String dn,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster int numOfEntries, boolean sortResults, boolean ascendingOrder,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster String serviceName, String attrName, Set values)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster throws SMSException, SSOException {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (debug.messageEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.message("SMSEmbeddedLdapObject.searchOrganizationNames" +
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster " search dn: " + dn);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /*
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Instead of constructing the filter in the framework(SMSEntry.java),
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * Construct the filter here in SMSEmbeddedLdapObject or the plugin
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * implementation to support JDBC or other data store. To return
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * organization names that match the given attribute name and values,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * only exact matching is supported, and if more than one value is
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * provided the organization must have all these values for the
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * attribute. Basically an AND is performed for attribute values for
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * searching. The attributes can be under the service config as well
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * under the Realm/Organization directly. For eg.,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * (|(&(objectclass=sunRealmService)(&
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * (|(sunxmlkeyvalue=SERVICE_NAME-ATTR_NAME=VALUE1)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * (sunxmlkeyvalue=ATTR_NAME=VALUE1))
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * (|(sunxmlkeyvalue=SERVICE_NAME-ATTR_NAME=VALUE2)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * (sunxmlkeyvalue=ATTR_NAME=VALUE2))(...))
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * (&(objectclass=sunServiceComponent)(&
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * (|(sunxmlkeyvalue=SERVICE_NAME-ATTR_NAME=VALUE1)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * (sunxmlkeyvalue=ATTR_NAME=VALUE1))
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * (|(sunxmlkeyvalue=SERVICE_NAME-ATTR_NAME=VALUE2)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster * (sunxmlkeyvalue=ATTR_NAME=VALUE2))(...))
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster *
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster StringBuilder sb = new StringBuilder();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster sb.append("(&");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster for (Iterator itr = values.iterator(); itr.hasNext();) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster String val = (String) itr.next();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster sb.append("(|(").append(SMSEntry.ATTR_XML_KEYVAL).append("=")
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster .append(serviceName).append("-").append(attrName).append(
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster "=").append(val).append(")");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster sb.append("(").append(SMSEntry.ATTR_XML_KEYVAL).append("=").append(
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster attrName).append("=").append(val).append("))");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster sb.append(")");
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster String filter = sb.toString();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster String FILTER_PATTERN_SEARCH_ORG = "{0}";
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster String dataStore = SMSEntry.getDataStore(token);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if ((dataStore != null) && !dataStore.equals(
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster SMSEntry.DATASTORE_ACTIVE_DIR)
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster ) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Include the OCs only for sunDS, not Active Directory.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster //String FILTER_PATTERN_SEARCH_ORG = "(|(&(objectclass="
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster FILTER_PATTERN_SEARCH_ORG = "(|(&(objectclass="
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster + SMSEntry.OC_REALM_SERVICE + "){0})" + "(&(objectclass="
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster + SMSEntry.OC_SERVICE_COMP + "){0}))";
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster String[] objs = { filter };
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster String sfilter = MessageFormat.format(
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster FILTER_PATTERN_SEARCH_ORG, (Object[])objs);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster if (debug.messageEnabled()) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster debug.message("SMSEmbeddedLdapObject.searchOrganizationNames: " +
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster "orgNames search filter: " + sfilter);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster Set answer = searchSubOrganizationNames(dn, sfilter, numOfEntries,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster sortResults, ascendingOrder, true);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return (answer);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster public void shutdown() {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster}