package org.safehaus.penrose.source; import org.safehaus.penrose.session.Session; import org.safehaus.penrose.ldap.*; import org.safehaus.penrose.partition.Partition; import org.safehaus.penrose.filter.Filter; import org.safehaus.penrose.filter.PresentFilter; import org.ietf.ldap.LDAPException; import java.util.*; /** * @author Endi Sukma Dewata */ public class MergeSource extends Source { public final static String SOURCES = "sources"; public final static String ATTRIBUTES = "attributes"; public Collection<String> sourceNames = new LinkedHashSet<String>(); public Collection<String> attributeNames = new LinkedHashSet<String>(); public void init() throws Exception { String value = getParameter(SOURCES); String[] s = value.split(","); sourceNames.addAll(Arrays.asList(s)); value = getParameter(ATTRIBUTES); if (value != null) { for (String attributeName : value.split(",")) { attributeNames.add(attributeName.toLowerCase()); } } } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Add //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public void add( Session session, AddRequest request, AddResponse response ) throws Exception { boolean debug = log.isDebugEnabled(); if (debug) log.debug("Adding "+request.getDn()+"."); SourceManager sourceManager = partition.getSourceManager(); for (String sourceName : sourceNames) { Source source = sourceManager.getSource(sourceName); AddResponse newResponse = new AddResponse(); try { source.add(session, request, newResponse); } catch (LDAPException e) { log.debug(e.getMessage()); // ignore } } } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Bind //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public void bind( Session session, BindRequest request, BindResponse response ) throws Exception { boolean debug = log.isDebugEnabled(); if (debug) log.debug("Binding "+request.getDn()+"."); SourceManager sourceManager = partition.getSourceManager(); for (String sourceName : sourceNames) { Source source = sourceManager.getSource(sourceName); BindResponse newResponse = new BindResponse(); try { source.bind(session, request, newResponse); return; } catch (LDAPException e) { log.debug(e.getMessage()); // ignore } } response.setReturnCode(LDAP.INVALID_CREDENTIALS); throw LDAP.createException(LDAP.INVALID_CREDENTIALS); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Compare //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public void compare( Session session, CompareRequest request, CompareResponse response ) throws Exception { boolean debug = log.isDebugEnabled(); if (debug) log.debug("Comparing "+request.getDn()+"."); SourceManager sourceManager = partition.getSourceManager(); for (String sourceName : sourceNames) { Source source = sourceManager.getSource(sourceName); CompareResponse newResponse = new CompareResponse(); try { source.compare(session, request, newResponse); int rc = newResponse.getReturnCode(); if (rc == LDAP.COMPARE_TRUE) { response.setReturnCode(rc); return; } } catch (LDAPException e) { log.debug(e.getMessage()); // ignore } } response.setReturnCode(LDAP.COMPARE_FALSE); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Delete //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public void delete( Session session, DeleteRequest request, DeleteResponse response ) throws Exception { boolean debug = log.isDebugEnabled(); if (debug) log.debug("Deleting "+request.getDn()+"."); SourceManager sourceManager = partition.getSourceManager(); for (String sourceName : sourceNames) { Source source = sourceManager.getSource(sourceName); DeleteResponse newResponse = new DeleteResponse(); try { source.delete(session, request, newResponse); } catch (LDAPException e) { log.debug(e.getMessage()); // ignore } } } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Modify //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public void modify( Session session, ModifyRequest request, ModifyResponse response ) throws Exception { boolean debug = log.isDebugEnabled(); if (debug) log.debug("Modifying "+request.getDn()+"."); SourceManager sourceManager = partition.getSourceManager(); for (String sourceName : sourceNames) { log.debug("Modifying source "+sourceName+"."); Source source = sourceManager.getSource(sourceName); ModifyRequest newRequest = new ModifyRequest(); newRequest.setDn(request.getDn()); for (Modification modification : request.getModifications()) { Attribute attribute = modification.getAttribute(); String attributeName = attribute.getName(); if (!attributeNames.contains(attributeName.toLowerCase())) continue; Attribute newAttribute = new Attribute(attributeName); for (Object value : attribute.getValues()) { DN dn = new DN(value.toString()); try { source.find(session, dn); log.debug("Entry "+dn+" is in source "+sourceName+"."); newAttribute.addValue(value); } catch (Exception e) { log.debug("Entry "+dn+" is not in source "+sourceName+"."); // ignore } } if (newAttribute.isEmpty()) continue; Modification newModification = new Modification(modification.getType(), newAttribute); newRequest.addModification(newModification); } if (newRequest.getModifications().isEmpty()) continue; ModifyResponse newResponse = new ModifyResponse(); try { source.modify(session, newRequest, newResponse); } catch (LDAPException e) { log.debug(e.getMessage()); // ignore } } } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // ModRdn //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public void modrdn( Session session, ModRdnRequest request, ModRdnResponse response ) throws Exception { boolean debug = log.isDebugEnabled(); if (debug) log.debug("Renaming "+request.getDn()+"."); SourceManager sourceManager = partition.getSourceManager(); for (String sourceName : sourceNames) { Source source = sourceManager.getSource(sourceName); ModRdnResponse newResponse = new ModRdnResponse(); try { source.modrdn(session, request, newResponse); } catch (LDAPException e) { log.debug(e.getMessage()); // ignore } } } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Search //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public void search( Session session, SearchRequest request, SearchResponse response ) throws Exception { boolean debug = log.isDebugEnabled(); if (debug) log.debug("Searching "+request.getDn()+"."); Filter filter = request.getFilter(); Partition partition = getPartition(); SourceManager sourceManager = partition.getSourceManager(); final Collection<DN> list = new LinkedHashSet<DN>(); final Map<String,Map<DN,SearchResult>> maps = new LinkedHashMap<String,Map<DN,SearchResult>>(); for (String sourceName : sourceNames) { Source source = sourceManager.getSource(sourceName); final Map<DN,SearchResult> map = new LinkedHashMap<DN,SearchResult>(); maps.put(sourceName, map); SearchResponse newResponse = new SearchResponse() { public void add(SearchResult result) throws Exception { DN dn = result.getDn(); list.add(dn); map.put(dn, result); } }; try { source.search(session, request, newResponse); } catch (LDAPException e) { log.debug(e.getMessage()); // ignore } } boolean nullFilter = filter == null || filter instanceof PresentFilter && "objectClass".equalsIgnoreCase(((PresentFilter)filter).getAttribute()); for (DN dn : list) { SearchResult newResult = new SearchResult(); newResult.setDn(dn); Attributes newAttributes = newResult.getAttributes(); for (String sourceName : sourceNames) { Map<DN,SearchResult> map = maps.get(sourceName); SearchResult result = map.get(dn); if (result == null) { if (nullFilter) continue; Source source = sourceManager.getSource(sourceName); try { result = source.find(session, dn); } catch (Exception e) { log.debug(e.getMessage()); // ignore } if (result == null) continue; } newAttributes.add(result.getAttributes()); } response.add(newResult); } response.close(); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Unbind //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public void unbind( Session session, UnbindRequest request, UnbindResponse response ) throws Exception { boolean debug = log.isDebugEnabled(); if (debug) log.debug("Unbinding "+request.getDn()+"."); SourceManager sourceManager = partition.getSourceManager(); for (String sourceName : sourceNames) { Source source = sourceManager.getSource(sourceName); UnbindResponse newResponse = new UnbindResponse(); try { source.unbind(session, request, newResponse); } catch (LDAPException e) { log.debug(e.getMessage()); // ignore } } } }