/** * Reads JSON data from the reader and returns a search result. * * @return search result derived from the JSON * @throws IOException if an error occurs using the reader */ @Override @SuppressWarnings("unchecked") public SearchResult read() throws IOException { final SearchResult result = new SearchResult(sortBehavior); try { final JSONParser parser = new JSONParser(); final JSONArray jsonArray = (JSONArray) parser.parse(jsonReader); for (Object o : jsonArray) { final LdapEntry entry = new LdapEntry(sortBehavior); final JSONObject jsonObject = (JSONObject) o; for (Object k : jsonObject.keySet()) { final String attrName = (String) k; if ("dn".equalsIgnoreCase(attrName)) { entry.setDn((String) jsonObject.get(k)); } else { final LdapAttribute attr = new LdapAttribute(sortBehavior); attr.setName(attrName); attr.addStringValues((List<String>) jsonObject.get(k)); entry.addAttribute(attr); } } result.addEntry(entry); } } catch (ParseException e) { throw new IOException(e); } return result; }
/** * Creates a new ldap attribute. The collection of values is inspected for either String or byte[] * and the appropriate attribute is created. * * @param sb sort behavior * @param name of this attribute * @param values of this attribute * @return ldap attribute * @throws IllegalArgumentException if values contains something other than String or byte[] */ public static LdapAttribute createLdapAttribute( final SortBehavior sb, final String name, final Collection<Object> values) { final Collection<String> stringValues = new ArrayList<String>(); final Collection<byte[]> binaryValues = new ArrayList<byte[]>(); for (Object value : values) { if (value instanceof byte[]) { binaryValues.add((byte[]) value); } else if (value instanceof String) { stringValues.add((String) value); } else { throw new IllegalArgumentException("Values must contain either String or byte[]"); } } LdapAttribute la; if (!binaryValues.isEmpty()) { la = new LdapAttribute(sb, true); la.setName(name); la.addBinaryValues(binaryValues); } else { la = new LdapAttribute(sb, false); la.setName(name); la.addStringValues(stringValues); } return la; }
/** * Returns the attribute names in this entry. * * @return string array of attribute names */ public String[] getAttributeNames() { final String[] names = new String[entryAttributes.size()]; int i = 0; for (LdapAttribute la : entryAttributes.values()) { names[i++] = la.getName(); } return names; }
/** * Reads the values of {@link #searchAttribute} from the supplied attributes and calls {@link * #recursiveSearch} for each. * * @param conn to perform search operation on * @param entry to read * @param searchedDns list of DNs whose attributes have been read * @throws LdapException if a search error occurs */ private void readSearchAttribute( final Connection conn, final LdapEntry entry, final List<String> searchedDns) throws LdapException { if (entry != null) { final LdapAttribute attr = entry.getAttribute(searchAttribute); if (attr != null && !attr.isBinary()) { for (String s : attr.getStringValues()) { recursiveSearch(conn, s, entry, searchedDns); } } } }
/** * Reads a String value from the LdapEntry. * * @param entry the ldap entry * @param attribute the attribute name * @param nullValue the value which should be returning in case of a null value * @return the string */ public static String getString( final LdapEntry entry, final String attribute, final String nullValue) { final LdapAttribute attr = entry.getAttribute(attribute); if (attr == null) { return nullValue; } String v = null; if (attr.isBinary()) { final byte[] b = attr.getBinaryValue(); v = new String(b, Charset.forName("UTF-8")); } else { v = attr.getStringValue(); } if (StringUtils.isNotBlank(v)) { return v; } return nullValue; }
/** * Recursively gets the attribute(s) {@link #mergeAttributes} for the supplied dn and adds the * values to the supplied attributes. * * @param conn to perform search operation on * @param dn to get attribute(s) for * @param entry to merge with * @param searchedDns list of DNs that have been searched for * @throws LdapException if a search error occurs */ private void recursiveSearch( final Connection conn, final String dn, final LdapEntry entry, final List<String> searchedDns) throws LdapException { if (!searchedDns.contains(dn)) { LdapEntry newEntry = null; try { final SearchOperation search = new SearchOperation(conn); final SearchRequest sr = SearchRequest.newObjectScopeSearchRequest(dn, retAttrs); final SearchResult result = search.execute(sr).getResult(); newEntry = result.getEntry(dn); } catch (LdapException e) { logger.warn("Error retrieving attribute(s): {}", Arrays.toString(retAttrs), e); } searchedDns.add(dn); if (newEntry != null) { // recursively search new attributes readSearchAttribute(conn, newEntry, searchedDns); // merge new attribute values for (String s : mergeAttributes) { final LdapAttribute newAttr = newEntry.getAttribute(s); if (newAttr != null) { final LdapAttribute oldAttr = entry.getAttribute(s); if (oldAttr == null) { entry.addAttribute(newAttr); } else { if (newAttr.isBinary()) { for (byte[] value : newAttr.getBinaryValues()) { oldAttr.addBinaryValue(value); } } else { for (String value : newAttr.getStringValues()) { oldAttr.addStringValue(value); } } } } } } } }
/** {@inheritDoc} */ @Override protected void processAttributes( final Connection conn, final SearchRequest request, final LdapEntry entry) throws LdapException { final Map<LdapAttribute, Matcher> matchingAttrs = new HashMap<LdapAttribute, Matcher>(); for (LdapAttribute la : entry.getAttributes()) { // Match attribute ID against the pattern final Matcher matcher = RANGE_PATTERN.matcher(la.getName()); // If the attribute ID matches the pattern if (matcher.find()) { matchingAttrs.put(la, matcher); } } for (Map.Entry<LdapAttribute, Matcher> mEntry : matchingAttrs.entrySet()) { final LdapAttribute la = mEntry.getKey(); final Matcher matcher = mEntry.getValue(); final String msg = String.format("attribute '%s' entry '%s'", la.getName(), entry.getDn()); // Determine the attribute name without the range syntax final String attrTypeName = matcher.group(1); logger.debug("Found Range option {}", msg); if (attrTypeName == null || attrTypeName.isEmpty()) { logger.error("Unable to determine the attribute type name for {}", msg); throw new IllegalArgumentException( "Unable to determine the attribute type name for " + msg); } // Create or update the attribute whose ID has the range syntax removed LdapAttribute newAttr = entry.getAttribute(attrTypeName); if (newAttr == null) { newAttr = new LdapAttribute(la.getSortBehavior(), la.isBinary()); newAttr.setName(attrTypeName); entry.addAttribute(newAttr); } // Copy values if (la.isBinary()) { newAttr.addBinaryValues(la.getBinaryValues()); } else { newAttr.addStringValues(la.getStringValues()); } // Remove original attribute with range syntax from returned attributes entry.removeAttribute(la); // If the attribute ID ends with * we're done, otherwise increment if (!la.getName().endsWith(END_OF_RANGE)) { // Determine next attribute ID // CheckStyle:MagicNumber OFF final int start = Integer.parseInt(matcher.group(2)); final int end = Integer.parseInt(matcher.group(3)); // CheckStyle:MagicNumber ON final int diff = end - start; final String nextAttrID = String.format(RANGE_FORMAT, attrTypeName, end + 1, end + diff + 1); // Search for next increment of values logger.debug("Searching for '{}' to increment {}", nextAttrID, msg); final SearchOperation search = new SearchOperation(conn); final SearchRequest sr = SearchRequest.newObjectScopeSearchRequest(entry.getDn(), new String[] {nextAttrID}); final SearchResult result = search.execute(sr).getResult(); // Add all attributes to the search result entry.addAttributes(result.getEntry().getAttributes()); // Iterate processAttributes(conn, request, entry); } } }
/** * Creates an ldap entry containing binary data. * * @return ldap entry */ public static LdapEntry createLdapEntry() { // CheckStyle:MagicNumber OFF final LdapAttribute typeCol1 = new LdapAttribute(SortBehavior.ORDERED, true); typeCol1.setName("typeCol1"); typeCol1.addBinaryValue(new byte[] {0x20, 0x0F, 0x1F}, new byte[] {0x21}); final LdapAttribute typeCol2 = new LdapAttribute(SortBehavior.ORDERED, true); typeCol2.setName("typeCol2"); typeCol2.addBinaryValue(new byte[] {0x20, 0x0F, 0x1F}, new byte[] {0x21}); final LdapAttribute typeSet1 = new LdapAttribute(SortBehavior.ORDERED, true); typeSet1.setName("typeSet1"); typeSet1.addBinaryValue(new byte[] {0x22, 0x0F, 0x1F}, new byte[] {0x23}); final LdapAttribute typeSet2 = new LdapAttribute(SortBehavior.ORDERED, true); typeSet2.setName("typeSet2"); typeSet2.addBinaryValue(new byte[] {0x22, 0x0F, 0x1F}, new byte[] {0x23}); final LdapAttribute typeList1 = new LdapAttribute(SortBehavior.ORDERED, true); typeList1.setName("typeList1"); typeList1.addBinaryValue(new byte[] {0x24, 0x0F, 0x1F}, new byte[] {0x25}); final LdapAttribute typeList2 = new LdapAttribute(SortBehavior.ORDERED, true); typeList2.setName("typeList2"); typeList2.addBinaryValue(new byte[] {0x24, 0x0F, 0x1F}, new byte[] {0x25}); final LdapEntry entry = new LdapEntry(); entry.setDn("cn=Binary Entry,ou=people,dc=ldaptive,dc=org"); entry.addAttribute( new LdapAttribute("customname1", new byte[] {0x40, 0x41, 0x42, 0x43}), new LdapAttribute( "customname2", new byte[] {0x44, 0x45, 0x46, 0x47}, new byte[] {0x48, 0x49, 0x50, 0x51}), new LdapAttribute("type1", new byte[] {0x01}), new LdapAttribute("type2", new byte[] {0x02, 0x0F}), new LdapAttribute("binarythree", new byte[] {0x03, 0x0F, 0x1F}), typeCol1, typeCol2, typeSet1, typeSet2, typeList1, typeList2); return entry; // CheckStyle:MagicNumber ON }
/** * Creates an ldap entry containing float based string values. * * @return ldap entry */ public static LdapEntry createLdapEntry() { final LdapAttribute typeArray1 = new LdapAttribute(SortBehavior.ORDERED); typeArray1.setName("typeArray1"); typeArray1.addStringValue("301.1", "302.2"); final LdapAttribute typeArray2 = new LdapAttribute(SortBehavior.ORDERED); typeArray2.setName("typeArray2"); typeArray2.addStringValue("301.1", "302.2"); final LdapAttribute typeCol1 = new LdapAttribute(SortBehavior.ORDERED); typeCol1.setName("typeCol1"); typeCol1.addStringValue("501.5", "502.5"); final LdapAttribute typeCol2 = new LdapAttribute(SortBehavior.ORDERED); typeCol2.setName("typeCol2"); typeCol2.addStringValue("501.5", "502.5"); final LdapAttribute typeSet1 = new LdapAttribute(SortBehavior.ORDERED); typeSet1.setName("typeSet1"); typeSet1.addStringValue("601.6", "602.6"); final LdapAttribute typeSet2 = new LdapAttribute(SortBehavior.ORDERED); typeSet2.setName("typeSet2"); typeSet2.addStringValue("601.6", "602.6"); final LdapAttribute typeList1 = new LdapAttribute(SortBehavior.ORDERED); typeList1.setName("typeList1"); typeList1.addStringValue("701.7", "702.7"); final LdapAttribute typeList2 = new LdapAttribute(SortBehavior.ORDERED); typeList2.setName("typeList2"); typeList2.addStringValue("701.7", "702.7"); final LdapEntry entry = new LdapEntry(); entry.setDn("cn=Float Entry,ou=people,dc=ldaptive,dc=org"); entry.addAttribute( new LdapAttribute("type1", "100.1"), new LdapAttribute("type2", "200.2"), new LdapAttribute("numberthree", "300.3"), typeArray1, typeArray2, typeCol1, typeCol2, typeSet1, typeSet2, typeList1, typeList2); return entry; }
/** * Handle a single attribute. * * @param conn the search was performed on * @param request used to find the search entry * @param attr to handle * @throws LdapException if the LDAP returns an error */ protected void handleAttribute( final Connection conn, final SearchRequest request, final LdapAttribute attr) throws LdapException { if (attr != null) { attr.setName(handleAttributeName(conn, request, attr.getName())); if (attr.isBinary()) { final Set<byte[]> newValues = new HashSet<byte[]>(attr.size()); for (byte[] b : attr.getBinaryValues()) { newValues.add(handleAttributeValue(conn, request, b)); } attr.clear(); attr.addBinaryValues(newValues); } else { final Set<String> newValues = new HashSet<String>(attr.size()); for (String s : attr.getStringValues()) { newValues.add(handleAttributeValue(conn, request, s)); } attr.clear(); attr.addStringValues(newValues); } } }
/** * Removes an attribute from this ldap attributes. * * @param attr attribute to remove */ public void removeAttribute(final LdapAttribute... attr) { for (LdapAttribute a : attr) { entryAttributes.remove(a.getName().toLowerCase()); } }
/** * Adds an attribute to this ldap attributes. * * @param attr attribute to add */ public void addAttribute(final LdapAttribute... attr) { for (LdapAttribute a : attr) { entryAttributes.put(a.getName().toLowerCase(), a); } }
/** * Creates an ldap entry containing boolean based string values. * * @return ldap entry */ public static LdapEntry createLdapEntry() { final LdapAttribute typeArray1 = new LdapAttribute(SortBehavior.ORDERED); typeArray1.setName("typeArray1"); typeArray1.addStringValue("false", "true"); final LdapAttribute typeArray2 = new LdapAttribute(SortBehavior.ORDERED); typeArray2.setName("typeArray2"); typeArray2.addStringValue("false", "true"); final LdapAttribute typeCol1 = new LdapAttribute(SortBehavior.ORDERED); typeCol1.setName("typeCol1"); typeCol1.addStringValue("true", "false"); final LdapAttribute typeCol2 = new LdapAttribute(SortBehavior.ORDERED); typeCol2.setName("typeCol2"); typeCol2.addStringValue("false", "true"); final LdapAttribute typeSet1 = new LdapAttribute(SortBehavior.ORDERED); typeSet1.setName("typeSet1"); typeSet1.addStringValue("true", "false"); final LdapAttribute typeSet2 = new LdapAttribute(SortBehavior.ORDERED); typeSet2.setName("typeSet2"); typeSet2.addStringValue("true", "false"); final LdapAttribute typeList1 = new LdapAttribute(SortBehavior.ORDERED); typeList1.setName("typeList1"); typeList1.addStringValue("false", "true"); final LdapAttribute typeList2 = new LdapAttribute(SortBehavior.ORDERED); typeList2.setName("typeList2"); typeList2.addStringValue("true", "false"); final LdapEntry entry = new LdapEntry(); entry.setDn("cn=Boolean Entry,ou=people,dc=ldaptive,dc=org"); entry.addAttribute( new LdapAttribute("type1", "true"), new LdapAttribute("type2", "false"), new LdapAttribute("booleanthree", "true"), typeArray1, typeArray2, typeCol1, typeCol2, typeSet1, typeSet2, typeList1, typeList2); return entry; }