一、前言
基于datanucleus源码包中的org.datanucleus.store.ldap.LDAPUtils工具类,对javax.naming.ldap定义轻量目录访问协议常用javax.naming.ldap.LdapName获取getEffectiveClassMetaData等相关操作,详情参见源码说明。
二、源码说明
LDAPUtils类依赖org.datanucleus.metadata、org.datanucleus.store、org.datanucleus.util依赖datanucleus-core包
package org.datanucleus.store.ldap;@b@@b@import java.lang.reflect.Constructor;@b@import java.lang.reflect.Method;@b@import java.lang.reflect.Modifier;@b@import java.util.ArrayList;@b@import java.util.Arrays;@b@import java.util.Collection;@b@import java.util.HashSet;@b@import java.util.Iterator;@b@import java.util.LinkedHashMap;@b@import java.util.LinkedHashSet;@b@import java.util.List;@b@import java.util.Map;@b@import java.util.Set;@b@import javax.naming.ContextNotEmptyException;@b@import javax.naming.InvalidNameException;@b@import javax.naming.NameNotFoundException;@b@import javax.naming.NamingEnumeration;@b@import javax.naming.NamingException;@b@import javax.naming.directory.Attribute;@b@import javax.naming.directory.Attributes;@b@import javax.naming.directory.BasicAttributes;@b@import javax.naming.directory.DirContext;@b@import javax.naming.directory.SearchControls;@b@import javax.naming.directory.SearchResult;@b@import javax.naming.ldap.LdapName;@b@import javax.naming.ldap.Rdn;@b@import org.datanucleus.ClassLoaderResolver;@b@import org.datanucleus.FetchPlan;@b@import org.datanucleus.OMFContext;@b@import org.datanucleus.Transaction;@b@import org.datanucleus.api.ApiAdapter;@b@import org.datanucleus.exceptions.NucleusDataStoreException;@b@import org.datanucleus.exceptions.NucleusObjectNotFoundException;@b@import org.datanucleus.metadata.AbstractClassMetaData;@b@import org.datanucleus.metadata.AbstractMemberMetaData;@b@import org.datanucleus.metadata.CollectionMetaData;@b@import org.datanucleus.metadata.ColumnMetaData;@b@import org.datanucleus.metadata.ElementMetaData;@b@import org.datanucleus.metadata.MetaDataManager;@b@import org.datanucleus.metadata.MetaDataUtils;@b@import org.datanucleus.query.compiler.QueryCompilation;@b@import org.datanucleus.store.ExecutionContext;@b@import org.datanucleus.store.FieldValues2;@b@import org.datanucleus.store.ObjectProvider;@b@import org.datanucleus.store.StoreManager;@b@import org.datanucleus.store.Type;@b@import org.datanucleus.store.connection.ManagedConnection;@b@import org.datanucleus.store.ldap.fieldmanager.AbstractMappingStrategy;@b@import org.datanucleus.store.ldap.fieldmanager.FetchFieldManager;@b@import org.datanucleus.util.ClassUtils;@b@import org.datanucleus.util.Localiser;@b@import org.datanucleus.util.NucleusLogger;@b@@b@public class LDAPUtils@b@{@b@ protected static final Localiser LOCALISER = Localiser.getInstance("org.datanucleus.store.ldap.Localisation", LDAPStoreManager.class.getClassLoader());@b@ public static final String[] NO_ATTRIBUTES = new String[0];@b@@b@ public static ObjectProvider getStateManagerForObject(Object object, ExecutionContext om, boolean persist)@b@ {@b@ ObjectProvider smpc = om.findObjectProvider(object, persist);@b@ return smpc;@b@ }@b@@b@ public static AbstractClassMetaData getEffectiveClassMetaData(AbstractMemberMetaData mmd, MetaDataManager mmgr)@b@ {@b@ ClassLoaderResolver clr = mmgr.getOMFContext().getClassLoaderResolver(null);@b@@b@ String[] fieldTypes = mmd.getFieldTypes();@b@ if ((fieldTypes != null) && (fieldTypes.length > 0))@b@ {@b@ fieldTypeCmd = mmgr.getMetaDataForClass(fieldTypes[0], clr);@b@ if (fieldTypeCmd != null)@b@ {@b@ return fieldTypeCmd;@b@ }@b@ }@b@@b@ AbstractClassMetaData fieldTypeCmd = mmgr.getMetaDataForClass(mmd.getType(), clr);@b@ if (fieldTypeCmd != null)@b@ {@b@ return fieldTypeCmd;@b@ }@b@@b@ AbstractClassMetaData collectionFieldTypeCmd = (mmd.getCollection() != null) ? mmd.getCollection().getElementClassMetaData(clr, mmgr) : null;@b@@b@ if (collectionFieldTypeCmd != null)@b@ {@b@ return collectionFieldTypeCmd;@b@ }@b@@b@ return null;@b@ }@b@@b@ public static AbstractMemberMetaData getMemberMetadataForAttributeName(AbstractClassMetaData cmd, String attributeName)@b@ {@b@ if ((cmd != null) && (attributeName != null))@b@ {@b@ List allMemberMetaData = getAllMemberMetaData(cmd);@b@ for (AbstractMemberMetaData mmd : allMemberMetaData)@b@ {@b@ String attributeNameForField = getAttributeNameForField(mmd);@b@ if (attributeName.equals(attributeNameForField))@b@ {@b@ return mmd;@b@ }@b@ }@b@ }@b@ return null;@b@ }@b@@b@ public static List<AbstractMemberMetaData> getAllMemberMetaData(AbstractClassMetaData cmd)@b@ {@b@ int[] fieldNumbers = cmd.getAllMemberPositions();@b@ return getMemberMetaData(fieldNumbers, cmd);@b@ }@b@@b@ public static List<AbstractMemberMetaData> getMemberMetaData(int[] fieldNumbers, AbstractClassMetaData cmd)@b@ {@b@ int[] arr$;@b@ int i$;@b@ List mmds = new ArrayList();@b@ if ((fieldNumbers != null) && (fieldNumbers.length > 0))@b@ {@b@ arr$ = fieldNumbers; int len$ = arr$.length; for (i$ = 0; i$ < len$; ++i$) { int fieldNumber = arr$[i$];@b@@b@ AbstractMemberMetaData mmd = cmd.getMetaDataForManagedMemberAtAbsolutePosition(fieldNumber);@b@ mmds.add(mmd);@b@ }@b@ }@b@ return mmds;@b@ }@b@@b@ public static boolean isEmbeddedField(AbstractMemberMetaData mmd)@b@ {@b@ return ((mmd.getEmbeddedMetaData() != null) || ((mmd.getElementMetaData() != null) && (mmd.getElementMetaData().getEmbeddedMetaData() != null)));@b@ }@b@@b@ public static boolean isHierarchicalMappedAtChild(ObjectProvider sm)@b@ {@b@ LocationInfo locationInfo = getLocationInfo(sm.getClassMetaData());@b@ return (locationInfo.parentFieldName != null);@b@ }@b@@b@ public static LdapName getParentDistingueshedName(LdapName dn, LdapName suffix)@b@ {@b@ LdapName parent = (LdapName)dn.getPrefix(dn.size() - suffix.size() - 1);@b@ return parent;@b@ }@b@@b@ private static Rdn getRdnForObject(StoreManager storeMgr, ObjectProvider sm)@b@ throws InvalidNameException@b@ {@b@ AbstractClassMetaData cmd = sm.getClassMetaData();@b@ int fieldNumber = cmd.getPKMemberPositions()[0];@b@ Object value = sm.provideField(fieldNumber);@b@ AbstractMemberMetaData mmd = cmd.getMetaDataForManagedMemberAtAbsolutePosition(fieldNumber);@b@ Attributes rdnAttributes = new BasicAttributes();@b@ AbstractMappingStrategy ms = AbstractMappingStrategy.findMappingStrategy(storeMgr, sm, mmd, rdnAttributes);@b@ ms.insert(value);@b@ Rdn rdn = new Rdn(rdnAttributes);@b@ return rdn;@b@ }@b@@b@ public static LdapName getDistinguishedNameForObject(StoreManager storeMgr, ObjectProvider sm)@b@ {@b@ return getDistinguishedNameForObject(storeMgr, sm, false);@b@ }@b@@b@ public static LdapName getDistinguishedNameForObject(StoreManager storeMgr, ObjectProvider sm, boolean forceFetchHierarchicalMappedDn)@b@ {@b@ return getDistinguishedNameForObject(storeMgr, sm, null, forceFetchHierarchicalMappedDn);@b@ }@b@@b@ private static LdapName getDistinguishedNameForObject(StoreManager storeMgr, ObjectProvider sm, Set<ObjectProvider> handledStateManagers, boolean forceFetchHierarchicalMappedDn)@b@ {@b@ LdapName dn;@b@ if (handledStateManagers == null)@b@ {@b@ handledStateManagers = new HashSet();@b@ }@b@ if (handledStateManagers.contains(sm))@b@ {@b@ throw new NucleusDataStoreException("Recursive loop detected while creating distinguished name for " + sm);@b@ }@b@ handledStateManagers.add(sm);@b@@b@ AbstractClassMetaData cmd = sm.getClassMetaData();@b@ LocationInfo locationInfo = getLocationInfo(cmd);@b@ try@b@ {@b@ SearchControls searchControls = getSearchControls(cmd);@b@ if ((sm.getEmbeddedOwners() != null) && (sm.getEmbeddedOwners().length > 0))@b@ {@b@ ObjectProvider owner = sm.getEmbeddedOwners()[0];@b@ dn = getDistinguishedNameForObject(storeMgr, owner, handledStateManagers, forceFetchHierarchicalMappedDn);@b@ dn.add(getRdnForObject(storeMgr, sm));@b@ }@b@ else if (searchControls.getSearchScope() == 0)@b@ {@b@ dn = locationInfo.dn;@b@ }@b@ else if (isHierarchicalMappedAtChild(sm))@b@ {@b@ LdapName parentDn;@b@ Rdn rdn = getRdnForObject(storeMgr, sm);@b@@b@ AbstractMemberMetaData parentFieldMmd = cmd.getMetaDataForMember(locationInfo.parentFieldName);@b@ if (forceFetchHierarchicalMappedDn)@b@ {@b@ AbstractClassMetaData parentFieldTypeCmd = sm.getExecutionContext().getMetaDataManager().getMetaDataForClass(parentFieldMmd.getType(), sm.getExecutionContext().getClassLoaderResolver());@b@@b@ LdapName base = getSearchBase(parentFieldTypeCmd, sm.getExecutionContext().getMetaDataManager());@b@ String ocFilter = getSearchFilter(cmd);@b@ String rdnFilter = "(" + rdn.getType() + "=" + rdn.getValue() + ")";@b@ String filter = (ocFilter != null) ? "(&" + ocFilter + rdnFilter + ")" : rdnFilter;@b@ ExecutionContext om = sm.getExecutionContext();@b@ ManagedConnection mconn = storeMgr.getConnection(om);@b@ try@b@ {@b@ DirContext ctx = (DirContext)mconn.getConnection();@b@ if (NucleusLogger.DATASTORE_RETRIEVE.isDebugEnabled())@b@ {@b@ NucleusLogger.DATASTORE_RETRIEVE.debug(LOCALISER.msg("LDAP.JNDI.search", base, filter, Integer.valueOf(searchControls.getSearchScope())));@b@ }@b@@b@ NamingEnumeration enumeration = ctx.search(base, filter, searchControls);@b@ if (enumeration.hasMoreElements())@b@ {@b@ SearchResult sr = (SearchResult)enumeration.nextElement();@b@ String srName = sr.getNameInNamespace();@b@ LdapName srDn = new LdapName(srName);@b@ parentDn = getParentDistingueshedName(srDn, locationInfo.suffix);@b@ enumeration.close();@b@ }@b@ else if (locationInfo.dn != null)@b@ {@b@ parentDn = locationInfo.dn;@b@ }@b@ else@b@ {@b@ throw new NucleusObjectNotFoundException("No distinguished name found for object " + sm.toString());@b@ }@b@@b@ }@b@ catch (NamingException e)@b@ {@b@ }@b@ finally@b@ {@b@ mconn.release();@b@ }@b@ }@b@ else@b@ {@b@ Object parentFieldValue = sm.provideField(parentFieldMmd.getAbsoluteFieldNumber());@b@ if (parentFieldValue != null)@b@ {@b@ ExecutionContext om = sm.getExecutionContext();@b@ boolean detached = om.getApiAdapter().isDetached(parentFieldValue);@b@ ObjectProvider parentSm = getStateManagerForObject(parentFieldValue, om, detached);@b@ if (parentSm == null)@b@ {@b@ throw new NucleusObjectNotFoundException("No state manager found for object " + parentFieldValue);@b@ }@b@ parentDn = getDistinguishedNameForObject(storeMgr, parentSm, handledStateManagers, forceFetchHierarchicalMappedDn);@b@ }@b@ else if (locationInfo.dn != null)@b@ {@b@ parentDn = locationInfo.dn;@b@ }@b@ else@b@ {@b@ handledStateManagers.remove(sm);@b@ LdapName smDn = getDistinguishedNameForObject(storeMgr, sm, handledStateManagers, true);@b@ parentDn = getParentDistingueshedName(smDn, locationInfo.suffix);@b@ }@b@ }@b@@b@ dn = composeDistinguishedName(parentDn, rdn, locationInfo.suffix);@b@ }@b@ else@b@ {@b@ dn = new LdapName(locationInfo.dn.toString());@b@ dn.add(getRdnForObject(storeMgr, sm));@b@ }@b@ }@b@ catch (InvalidNameException e)@b@ {@b@ throw new NucleusDataStoreException(e.getMessage(), e);@b@ }@b@@b@ return dn;@b@ }@b@@b@ public static LdapName getSearchBase(AbstractClassMetaData cmd, MetaDataManager mmgr)@b@ {@b@ LdapName dn;@b@ LocationInfo locationInfo;@b@ try {@b@ locationInfo = getLocationInfo(cmd);@b@ if ((locationInfo.parentFieldName != null) && (locationInfo.dn == null))@b@ {@b@ AbstractMemberMetaData parentMmd = cmd.getMetaDataForMember(locationInfo.parentFieldName);@b@ ClassLoaderResolver clr = mmgr.getOMFContext().getClassLoaderResolver(null);@b@ AbstractClassMetaData parentFieldCmd = mmgr.getMetaDataForClass(parentMmd.getType(), clr);@b@ LdapName parentDn = getSearchBase(parentFieldCmd, mmgr);@b@@b@ dn = composeDistinguishedName(parentDn, null, locationInfo.suffix);@b@ }@b@ else@b@ {@b@ dn = locationInfo.dn;@b@ }@b@ }@b@ catch (InvalidNameException e)@b@ {@b@ throw new NucleusDataStoreException(e.getMessage(), e);@b@ }@b@ return dn;@b@ }@b@@b@ public static SearchControls getSearchControls(AbstractClassMetaData cmd)@b@ {@b@ SearchControls searchControls = new SearchControls();@b@@b@ LocationInfo locationInfo = getLocationInfo(cmd);@b@ if (locationInfo.parentFieldName != null)@b@ {@b@ searchControls.setSearchScope(2);@b@ }@b@@b@ if (locationInfo.scope != -1)@b@ {@b@ searchControls.setSearchScope(locationInfo.scope);@b@ }@b@@b@ return searchControls;@b@ }@b@@b@ public static String getSearchFilter(AbstractClassMetaData cmd)@b@ {@b@ LocationInfo locationInfo = getLocationInfo(cmd);@b@ String urlFilter = locationInfo.filter;@b@@b@ Set objectClasses = getObjectClassesForClass(cmd);@b@ if (objectClasses.isEmpty())@b@ {@b@ return null;@b@ }@b@@b@ StringBuffer filter = new StringBuffer();@b@ if ((objectClasses.size() > 1) || (urlFilter != null))@b@ {@b@ filter.append("(&");@b@ for (String oc : objectClasses)@b@ {@b@ filter.append("(objectClass=");@b@ filter.append(oc);@b@ filter.append(")");@b@ }@b@ if (urlFilter != null)@b@ {@b@ filter.append(urlFilter);@b@ }@b@ filter.append(")");@b@ }@b@ else@b@ {@b@ filter.append("(objectClass=");@b@ filter.append((String)objectClasses.iterator().next());@b@ filter.append(")");@b@ }@b@ return filter.toString();@b@ }@b@@b@ public static LocationInfo getLocationInfo(AbstractClassMetaData cmd)@b@ {@b@ String raw = null;@b@ if ((cmd != null) && (cmd.hasExtension("dn")))@b@ {@b@ raw = cmd.getValueForExtension("dn");@b@ }@b@ else if ((cmd != null) && (cmd.getTable() != null))@b@ {@b@ raw = cmd.getTable();@b@ }@b@@b@ LocationInfo li = new LocationInfo();@b@@b@ if (raw != null)@b@ {@b@ String dnOrParentField = null;@b@ if (raw.startsWith("ldap:///"))@b@ {@b@ raw = raw.substring("ldap:///".length());@b@ String[] split = raw.split("\\?", 5);@b@@b@ if (split.length > 0)@b@ {@b@ dnOrParentField = split[0];@b@ }@b@@b@ if ((split.length <= 1) || @b@ (split.length > 2))@b@ {@b@ String scope = split[2];@b@ if (scope.length() > 0)@b@ {@b@ if ("base".equals(scope))@b@ {@b@ li.scope = 0;@b@ }@b@ else if ("one".equals(scope))@b@ {@b@ li.scope = 1;@b@ }@b@ else if ("sub".equals(scope))@b@ {@b@ li.scope = 2;@b@ }@b@ else@b@ {@b@ throw new NucleusDataStoreException("Invalid scope in LDAP URL: " + scope);@b@ }@b@ }@b@ }@b@@b@ if (split.length > 3)@b@ {@b@ String filter = split[3];@b@ if (filter.length() > 0)@b@ {@b@ li.filter = filter;@b@ }@b@ }@b@ }@b@ else@b@ {@b@ dnOrParentField = raw;@b@ }@b@@b@ if (dnOrParentField != null)@b@ {@b@ int left = dnOrParentField.indexOf(123);@b@ int right = dnOrParentField.indexOf(125);@b@ if ((left > -1) && (right > left))@b@ {@b@ li.parentFieldName = dnOrParentField.substring(left + 1, right);@b@ try@b@ {@b@ String suffix = dnOrParentField.substring(0, left);@b@ LdapName suffixDn = new LdapName(suffix);@b@ if ((suffixDn.size() > 0) && (suffixDn.getRdn(0).size() == 0))@b@ {@b@ suffixDn.remove(0);@b@ }@b@ li.suffix = suffixDn;@b@ }@b@ catch (InvalidNameException e)@b@ {@b@ throw new NucleusDataStoreException("Invalid LDAP DN: " + dnOrParentField);@b@ }@b@@b@ if ((dnOrParentField.length() <= right + 2) || (dnOrParentField.charAt(right + 1) != '|'))@b@ break label491;@b@ try@b@ {@b@ li.dn = new LdapName(dnOrParentField.substring(right + 2, dnOrParentField.length()));@b@ }@b@ catch (InvalidNameException e)@b@ {@b@ throw new NucleusDataStoreException("Invalid LDAP DN: " + dnOrParentField);@b@ }@b@@b@ }@b@@b@ try@b@ {@b@ li.dn = new LdapName(dnOrParentField);@b@ }@b@ catch (InvalidNameException e)@b@ {@b@ throw new NucleusDataStoreException("Invalid LDAP DN: " + dnOrParentField);@b@ }@b@@b@ }@b@@b@ }@b@@b@ label491: return li;@b@ }@b@@b@ public static String getEmptyValue(AbstractMemberMetaData mmd)@b@ {@b@ return mmd.getValueForExtension("empty-value");@b@ }@b@@b@ public static Object getAttributeValue(StoreManager storeMgr, ObjectProvider sm, String attributeName)@b@ {@b@ AbstractMemberMetaData pcMmd;@b@ try@b@ {@b@ pcMmd = getMemberMetadataForAttributeName(sm.getClassMetaData(), attributeName);@b@ Object pcFieldValue = sm.provideField(pcMmd.getAbsoluteFieldNumber());@b@@b@ Attributes pcAttributes = new BasicAttributes();@b@ AbstractMappingStrategy ms = AbstractMappingStrategy.findMappingStrategy(storeMgr, sm, pcMmd, pcAttributes);@b@ ms.insert(pcFieldValue);@b@ Attribute pcAttribute = pcAttributes.get(attributeName);@b@ Object pcAttributeValue = pcAttribute.get();@b@@b@ return pcAttributeValue;@b@ }@b@ catch (NamingException e)@b@ {@b@ throw new NucleusDataStoreException(e.getMessage(), e);@b@ }@b@ }@b@@b@ public static Collection<Object> getAttributeValuesFromLDAP(StoreManager storeMgr, ObjectProvider sm, String attributeName)@b@ {@b@ ManagedConnection mconn = storeMgr.getConnection(sm.getExecutionContext());@b@ try@b@ {@b@ LdapName dn = getDistinguishedNameForObject(storeMgr, sm, true);@b@ DirContext ctx = (DirContext)mconn.getConnection();@b@ if (NucleusLogger.DATASTORE_RETRIEVE.isDebugEnabled())@b@ {@b@ NucleusLogger.DATASTORE_RETRIEVE.debug(LOCALISER.msg("LDAP.JNDI.getAttributes", dn, attributeName, ""));@b@ }@b@ Attributes attributes = ctx.getAttributes(dn, new String[] { attributeName });@b@ Attribute attribute = attributes.get(attributeName);@b@ Collection pcAttributeValues = new ArrayList();@b@ if (attribute != null)@b@ {@b@ all = attribute.getAll();@b@ while (all.hasMoreElements())@b@ {@b@ pcAttributeValues.add(all.nextElement());@b@ }@b@ }@b@ NamingEnumeration all = pcAttributeValues;@b@@b@ return all; } catch (NamingException e) { } finally { mconn.release();@b@ }@b@ }@b@@b@ public static String getAttributeNameForField(AbstractMemberMetaData mmd)@b@ {@b@ String name = mmd.getName();@b@ if (mmd.hasExtension("dn"))@b@ {@b@ name = mmd.getValueForExtension("dn");@b@ }@b@ else if (mmd.hasExtension("attribute"))@b@ {@b@ name = mmd.getValueForExtension("attribute");@b@ }@b@ else if (mmd.getColumn() != null)@b@ {@b@ name = mmd.getColumn();@b@ }@b@ else if ((mmd.getColumnMetaData() != null) && (mmd.getColumnMetaData().length > 0))@b@ {@b@ name = mmd.getColumnMetaData()[0].getName();@b@ }@b@ return name;@b@ }@b@@b@ public static Set<String> getObjectClassesForClass(AbstractClassMetaData cmd)@b@ {@b@ Set ocs = new LinkedHashSet();@b@ if (cmd.hasExtension("objectClass"))@b@ {@b@ ocs.addAll(Arrays.asList(cmd.getValuesForExtension("objectClass")));@b@ }@b@ else if (cmd.getSchema() != null)@b@ {@b@ ocs.addAll(Arrays.asList(MetaDataUtils.getInstance().getValuesForCommaSeparatedAttribute(cmd.getSchema())));@b@ }@b@ return ocs;@b@ }@b@@b@ public static LdapName composeDistinguishedName(LdapName parentDn, Rdn rdn, LdapName suffix)@b@ throws InvalidNameException@b@ {@b@ LdapName dn = new LdapName(parentDn.getRdns());@b@ dn.addAll(suffix.getRdns());@b@ if (rdn != null)@b@ {@b@ dn.add(rdn);@b@ }@b@ return dn;@b@ }@b@@b@ public static Object getObjectByDN(StoreManager storeMgr, ExecutionContext om, Class type, String dnAsString)@b@ {@b@ AbstractClassMetaData cmd = om.getMetaDataManager().getMetaDataForClass(type, om.getClassLoaderResolver());@b@ LdapName base = getSearchBase(cmd, om.getMetaDataManager());@b@ try@b@ {@b@ LdapName dn = new LdapName(dnAsString);@b@ Rdn rdn = dn.getRdn(dn.size() - 1);@b@ String filter = "(" + rdn.getType() + "=" + rdn.getValue() + ")";@b@ List objects = getObjectsOfCandidateType(storeMgr, om, cmd, base, filter, true, false);@b@ if (objects.size() == 1)@b@ {@b@ return objects.get(0);@b@ }@b@ if (objects.size() == 0)@b@ {@b@ throw new NucleusObjectNotFoundException("No object found with type " + type + " and filter " + filter);@b@ }@b@@b@ throw new NucleusDataStoreException("Unambiguous match with type " + type + " and filter " + filter);@b@ }@b@ catch (NamingException e)@b@ {@b@ throw new NucleusDataStoreException(e.getMessage(), e);@b@ }@b@ }@b@@b@ public static Object getObjectByAttribute(StoreManager storeMgr, ExecutionContext om, Class type, String attributeName, String attributeValue, MetaDataManager mmgr)@b@ {@b@ String attributeFilter = "(" + attributeName + "=" + attributeValue + ")";@b@ AbstractClassMetaData cmd = om.getMetaDataManager().getMetaDataForClass(type, om.getClassLoaderResolver());@b@ LdapName base = getSearchBase(cmd, mmgr);@b@ List objects = getObjectsOfCandidateType(storeMgr, om, cmd, base, attributeFilter, true, false);@b@ if (objects.size() == 1)@b@ {@b@ return objects.get(0);@b@ }@b@ if (objects.size() == 0)@b@ {@b@ throw new NucleusObjectNotFoundException("No object found with type " + type + " and filter " + attributeFilter);@b@ }@b@@b@ throw new NucleusDataStoreException("Unambiguous match with type " + type + " and filter " + attributeFilter);@b@ }@b@@b@ public static void markForPersisting(Object pc, ExecutionContext om)@b@ {@b@ LDAPTransactionEventListener listener = getTransactionEventListener(om);@b@ listener.addObjectToPersist(pc);@b@ }@b@@b@ public static void markForRename(StoreManager storeMgr, Object pc, ExecutionContext om, LdapName oldDn, LdapName newDn)@b@ {@b@ ManagedConnection mconn = storeMgr.getConnection(om);@b@ try@b@ {@b@ DirContext ctx = (DirContext)mconn.getConnection();@b@ if (NucleusLogger.DATASTORE_PERSIST.isDebugEnabled())@b@ {@b@ NucleusLogger.DATASTORE_PERSIST.debug(LOCALISER.msg("LDAP.JNDI.rename", oldDn, newDn));@b@ }@b@ ctx.rename(oldDn, newDn);@b@ }@b@ catch (NamingException e)@b@ {@b@ }@b@ finally@b@ {@b@ mconn.release();@b@ }@b@ }@b@@b@ public static void markForDeletion(Object pc, ExecutionContext om)@b@ {@b@ LDAPTransactionEventListener listener = getTransactionEventListener(om);@b@ listener.addObjectToDelete(pc);@b@ }@b@@b@ public static void unmarkForDeletion(Object pc, ExecutionContext om)@b@ {@b@ LDAPTransactionEventListener listener = getTransactionEventListener(om);@b@ listener.removeObjectToDelete(pc);@b@ }@b@@b@ private static LDAPTransactionEventListener getTransactionEventListener(ExecutionContext om)@b@ {@b@ Transaction transaction = om.getTransaction();@b@ LDAPTransactionEventListener listener = (LDAPTransactionEventListener)transaction.getOptions().get("LDAPTransactionEventListener");@b@ if (listener == null)@b@ {@b@ listener = new LDAPTransactionEventListener(om);@b@ transaction.getOptions().put("LDAPTransactionEventListener", listener);@b@ transaction.addTransactionEventListener(listener);@b@ }@b@ return listener;@b@ }@b@@b@ public static List<Object> getObjectsOfCandidateType(StoreManager storeMgr, ExecutionContext om, QueryCompilation compilation, Map parameters, Class candidateClass, boolean subclasses, boolean ignoreCache, boolean inMemory)@b@ {@b@ String[] arr$;@b@ int i$;@b@ ClassLoaderResolver clr = om.getClassLoaderResolver();@b@ AbstractClassMetaData cmd = om.getMetaDataManager().getMetaDataForClass(candidateClass, clr);@b@ List results = getObjectsOfCandidateType(storeMgr, om, compilation, parameters, cmd, ignoreCache, inMemory);@b@ if (subclasses)@b@ {@b@ String[] subclassNames = om.getMetaDataManager().getSubclassesForClass(candidateClass.getName(), true);@b@ if (subclassNames != null)@b@ {@b@ arr$ = subclassNames; int len$ = arr$.length; for (i$ = 0; i$ < len$; ++i$) { String subclassName = arr$[i$];@b@@b@ AbstractClassMetaData subCmd = om.getMetaDataManager().getMetaDataForClass(subclassName, clr);@b@ results.addAll(getObjectsOfCandidateType(storeMgr, om, compilation, parameters, subCmd, ignoreCache, inMemory));@b@ }@b@ }@b@ }@b@ return results;@b@ }@b@@b@ private static List<Object> getObjectsOfCandidateType(StoreManager storeMgr, ExecutionContext om, QueryCompilation compilation, Map parameters, AbstractClassMetaData acmd, boolean ignoreCache, boolean inMemory)@b@ {@b@ List results = new ArrayList();@b@@b@ String classFilter = getSearchFilter(acmd);@b@ if (classFilter != null)@b@ {@b@ if (!(inMemory))@b@ {@b@ try@b@ {@b@ String className = "org.datanucleus.store.ldap.query.QueryToLDAPFilterMapper";@b@ Class cls = om.getClassLoaderResolver().classForName(className);@b@ Method method = ClassUtils.getMethodForClass(cls, "compile", null);@b@ Constructor constr = ClassUtils.getConstructorWithArguments(cls, new Class[] { QueryCompilation.class, Map.class, AbstractClassMetaData.class });@b@@b@ String filter = (String)method.invoke(constr.newInstance(new Object[] { compilation, parameters, acmd }), (Object[])null);@b@@b@ results = getObjectsOfCandidateType(storeMgr, om, acmd, null, filter, ignoreCache);@b@ }@b@ catch (Throwable e)@b@ {@b@ NucleusLogger.QUERY.warn(LOCALISER.msg("LDAP.Query.NativeQueryFailed"));@b@@b@ inMemory = true;@b@ }@b@ }@b@ if (inMemory)@b@ {@b@ results = getObjectsOfCandidateType(storeMgr, om, acmd, null, classFilter, ignoreCache);@b@ }@b@ }@b@ return results;@b@ }@b@@b@ public static List<Object> getObjectsOfCandidateType(StoreManager storeMgr, ExecutionContext om, AbstractClassMetaData candidateCmd, LdapName base, String additionalFilter, boolean subclasses, boolean ignoreCache)@b@ {@b@ String[] arr$;@b@ int i$;@b@ ClassLoaderResolver clr = om.getClassLoaderResolver();@b@ List results = getObjectsOfCandidateType(storeMgr, om, candidateCmd, base, additionalFilter, ignoreCache);@b@ if (subclasses)@b@ {@b@ String[] subclassNames = om.getMetaDataManager().getSubclassesForClass(candidateCmd.getFullClassName(), true);@b@ if (subclassNames != null)@b@ {@b@ arr$ = subclassNames; int len$ = arr$.length; for (i$ = 0; i$ < len$; ++i$) { String subclassName = arr$[i$];@b@@b@ AbstractClassMetaData subCmd = om.getMetaDataManager().getMetaDataForClass(subclassName, clr);@b@ results.addAll(getObjectsOfCandidateType(storeMgr, om, subCmd, base, additionalFilter, ignoreCache));@b@ }@b@ }@b@ }@b@ return results;@b@ }@b@@b@ private static List<Object> getObjectsOfCandidateType(StoreManager storeMgr, ExecutionContext om, AbstractClassMetaData cmd, LdapName base, String additionalFilter, boolean ignoreCache)@b@ {@b@ List results = new ArrayList();@b@@b@ ClassLoaderResolver clr = om.getClassLoaderResolver();@b@ Map entries = getEntries(storeMgr, om, cmd, base, additionalFilter, false, ignoreCache);@b@ for (Attributes attrs : entries.values())@b@ {@b@ results.add(om.findObjectUsingAID(new Type(clr.classForName(cmd.getFullClassName())), new FieldValues2(cmd, storeMgr, attrs, clr, om)@b@ {@b@ public void fetchFields(ObjectProvider sm)@b@ {@b@ sm.replaceFields(this.val$cmd.getPKMemberPositions(), new FetchFieldManager(this.val$storeMgr, sm, this.val$attrs));@b@@b@ List allMemberMetaData = LDAPUtils.getAllMemberMetaData(this.val$cmd);@b@ List basicMemberMetaData = new ArrayList();@b@ for (AbstractMemberMetaData mmd : allMemberMetaData)@b@ {@b@ mmd.getAbsoluteFieldNumber();@b@ if ((mmd.getRelationType(this.val$clr) == 0) && (!(mmd.isPersistentInterface(this.val$clr, this.val$om.getMetaDataManager()))) && (!(Collection.class.isAssignableFrom(mmd.getType()))) && (!(Map.class.isAssignableFrom(mmd.getType()))) && (!(mmd.getType().isArray())))@b@ {@b@ basicMemberMetaData.add(mmd);@b@ }@b@ }@b@ int[] basicMemberPosition = new int[basicMemberMetaData.size()];@b@ for (int i = 0; i < basicMemberMetaData.size(); ++i)@b@ {@b@ basicMemberPosition[i] = ((AbstractMemberMetaData)basicMemberMetaData.get(i)).getAbsoluteFieldNumber();@b@ }@b@ sm.replaceFields(basicMemberPosition, new FetchFieldManager(this.val$storeMgr, sm, this.val$attrs));@b@ }@b@@b@ public void fetchNonLoadedFields(ObjectProvider sm)@b@ {@b@ sm.replaceNonLoadedFields(this.val$cmd.getAllMemberPositions(), new FetchFieldManager(this.val$storeMgr, sm, this.val$attrs));@b@ }@b@@b@ public FetchPlan getFetchPlanForLoading()@b@ {@b@ return null;@b@ }@b@ }@b@ , ignoreCache, true));@b@ }@b@@b@ return results;@b@ }@b@@b@ public static Map<LdapName, Attributes> getEntries(StoreManager storeMgr, ExecutionContext om, AbstractClassMetaData candidateCmd, LdapName base, String additionalFilter, boolean subclasses, boolean ignoreCache)@b@ {@b@ ManagedConnection mconn = storeMgr.getConnection(om);@b@ try@b@ {@b@ String[] arr$;@b@ int i$;@b@ DirContext ctx = (DirContext)mconn.getConnection();@b@ ClassLoaderResolver clr = om.getClassLoaderResolver();@b@ Map results = getEntries(om, candidateCmd, ctx, base, additionalFilter, ignoreCache);@b@ if (subclasses)@b@ {@b@ subclassNames = om.getMetaDataManager().getSubclassesForClass(candidateCmd.getFullClassName(), true);@b@ if (subclassNames != null)@b@ {@b@ arr$ = subclassNames; int len$ = arr$.length; for (i$ = 0; i$ < len$; ++i$) { String subclassName = arr$[i$];@b@@b@ AbstractClassMetaData cmd = om.getMetaDataManager().getMetaDataForClass(subclassName, clr);@b@ results.putAll(getEntries(om, cmd, ctx, base, additionalFilter, ignoreCache));@b@ }@b@ }@b@ }@b@ String[] subclassNames = results;@b@@b@ return subclassNames; } finally { mconn.release();@b@ }@b@ }@b@@b@ private static Map<LdapName, Attributes> getEntries(ExecutionContext om, AbstractClassMetaData acmd, DirContext ctx, LdapName base, String additionalFilter, boolean ignoreCache)@b@ {@b@ Map results = new LinkedHashMap();@b@@b@ Class c = om.getClassLoaderResolver().classForName(acmd.getFullClassName());@b@ if ((c.isInterface()) || (Modifier.isAbstract(c.getModifiers())))@b@ {@b@ return results;@b@ }@b@@b@ try@b@ {@b@ if (base == null)@b@ {@b@ base = getSearchBase(acmd, om.getMetaDataManager());@b@ }@b@ String filter = getSearchFilter(acmd);@b@ if (additionalFilter != null)@b@ {@b@ filter = "(&" + filter + additionalFilter + ")";@b@ }@b@ SearchControls searchControls = getSearchControls(acmd);@b@@b@ if (NucleusLogger.DATASTORE_RETRIEVE.isDebugEnabled())@b@ {@b@ NucleusLogger.DATASTORE_RETRIEVE.debug(LOCALISER.msg("LDAP.JNDI.search", base, filter, Integer.valueOf(searchControls.getSearchScope())));@b@ }@b@@b@ NamingEnumeration enumeration = ctx.search(base.toString(), filter, searchControls);@b@ while (true) { Attributes attrs;@b@ LdapName dn;@b@ while (true) { if (!(enumeration.hasMoreElements()))@b@ break label245;@b@ SearchResult sr = (SearchResult)enumeration.nextElement();@b@ attrs = sr.getAttributes();@b@ String name = sr.getNameInNamespace();@b@ dn = new LdapName(name);@b@@b@ if ((searchControls.getSearchScope() != 2) || @b@ (!(dn.equals(base))))@b@ {@b@ break;@b@ }@b@@b@ }@b@@b@ label245: results.put(dn, attrs);@b@ }@b@@b@ }@b@ catch (NameNotFoundException nnfe)@b@ {@b@ }@b@ catch (NamingException ne)@b@ {@b@ throw new NucleusDataStoreException(ne.getMessage(), ne);@b@ }@b@@b@ return results;@b@ }@b@@b@ public static void insert(StoreManager storeMgr, LdapName dn, Attributes attributes, ExecutionContext om)@b@ {@b@ if (NucleusLogger.DATASTORE_PERSIST.isDebugEnabled())@b@ {@b@ NucleusLogger.DATASTORE_PERSIST.debug(LOCALISER.msg("LDAP.JNDI.createSubcontext", dn, attributes));@b@ }@b@ ManagedConnection mconn = storeMgr.getConnection(om);@b@ try@b@ {@b@ DirContext ctx = (DirContext)mconn.getConnection();@b@ ctx.bind(dn, null, attributes);@b@ }@b@ catch (NamingException ne)@b@ {@b@ }@b@ finally@b@ {@b@ mconn.release();@b@ }@b@ }@b@@b@ public static void update(StoreManager storeMgr, LdapName dn, Attributes attributes, ExecutionContext om)@b@ {@b@ if (NucleusLogger.DATASTORE_PERSIST.isDebugEnabled())@b@ {@b@ NucleusLogger.DATASTORE_PERSIST.debug(LOCALISER.msg("LDAP.JNDI.modifyAttributes", dn, "REPLACE", attributes));@b@ }@b@ ManagedConnection mconn = storeMgr.getConnection(om);@b@ try@b@ {@b@ DirContext ctx = (DirContext)mconn.getConnection();@b@ ctx.modifyAttributes(dn, 2, attributes);@b@ }@b@ catch (NamingException ne)@b@ {@b@ }@b@ finally@b@ {@b@ mconn.release();@b@ }@b@ }@b@@b@ public static void deleteRecursive(StoreManager storeMgr, LdapName dn, ExecutionContext om)@b@ {@b@ ManagedConnection mconn = storeMgr.getConnection(om);@b@ try@b@ {@b@ DirContext ctx = (DirContext)mconn.getConnection();@b@ deleteRecursive(dn, ctx);@b@ }@b@ catch (NamingException ne)@b@ {@b@ }@b@ finally@b@ {@b@ mconn.release();@b@ }@b@ }@b@@b@ public static void deleteRecursive(LdapName dn, DirContext ctx)@b@ throws NamingException@b@ {@b@ NamingEnumeration enumeration = ctx.search(dn, "(objectClass=*)", new SearchControls());@b@ while (enumeration.hasMoreElements())@b@ {@b@ SearchResult result = (SearchResult)enumeration.nextElement();@b@ String resultName = result.getNameInNamespace();@b@ LdapName resultDn = new LdapName(resultName);@b@ try@b@ {@b@ if (NucleusLogger.DATASTORE_PERSIST.isDebugEnabled())@b@ {@b@ NucleusLogger.DATASTORE_PERSIST.debug(LOCALISER.msg("LDAP.JNDI.destroySubcontext", resultDn));@b@ }@b@ ctx.unbind(resultDn);@b@ }@b@ catch (ContextNotEmptyException cnee)@b@ {@b@ deleteRecursive(resultDn, ctx);@b@ }@b@@b@ }@b@@b@ if (NucleusLogger.DATASTORE_PERSIST.isDebugEnabled())@b@ {@b@ NucleusLogger.DATASTORE_PERSIST.debug(LOCALISER.msg("LDAP.JNDI.destroySubcontext", dn));@b@ }@b@ ctx.unbind(dn);@b@ }@b@@b@ public static class LocationInfo@b@ {@b@ public LdapName dn;@b@ public String parentFieldName;@b@ public LdapName suffix;@b@ public String filter;@b@ public int scope;@b@@b@ public LocationInfo()@b@ {@b@ this.dn = null;@b@@b@ this.parentFieldName = null;@b@@b@ this.suffix = null;@b@@b@ this.filter = null;@b@@b@ this.scope = -1;@b@ }@b@ }@b@}