package org.safehaus.penrose.ldap; import java.util.*; import java.text.MessageFormat; import java.io.Serializable; /** * @author Endi S. Dewata */ public class DN implements Serializable, Comparable { public final static long serialVersionUID = 1L; public List<RDN> rdns; public String originalDn; public String normalizedDn; public DN parentDn; public String pattern; public transient MessageFormat formatter; public DN() { rdns = new ArrayList<RDN>(); } public DN(String dn) { originalDn = dn; } public DN(RDN rdn) { rdns = new ArrayList<RDN>(); rdns.add(rdn); } public synchronized void parse() throws Exception { if (rdns != null) return; rdns = new ArrayList<RDN>(); Collection<RDN> list = DNBuilder.parse(originalDn); for (RDN rdn : list) { rdns.add(rdn); } } public synchronized DN getDn(int start, int end) throws Exception { parse(); DNBuilder db = new DNBuilder(); for (int i=start; i<end; i++) { db.append(rdns.get(i)); } return db.toDn(); } public synchronized DN append(String dn) throws Exception { return append(new DN(dn)); } public synchronized DN append(RDN rdn) throws Exception { return append(new DN(rdn)); } public synchronized DN append(DN dn) throws Exception { DNBuilder db = new DNBuilder(); db.append(this); db.append(dn); return db.toDn(); } public synchronized DN prepend(String dn) throws Exception { return prepend(new DN(dn)); } public synchronized DN prepend(RDN rdn) throws Exception { return prepend(new DN(rdn)); } public synchronized DN prepend(DN dn) throws Exception { DNBuilder db = new DNBuilder(); db.append(dn); db.append(this); return db.toDn(); } public synchronized DN getSuffix(int i) throws Exception { return getDn(i, getLength()); } public synchronized DN getPrefix(int i) throws Exception { return getDn(0, i); } public synchronized DN getPrefix(String suffix) throws Exception { return getPrefix(new DN(suffix)); } public synchronized DN getPrefix(DN suffix) throws Exception { return getPrefix(getLength() - suffix.getLength()); } public synchronized String getPattern() throws Exception { if (pattern != null) return pattern; parse(); StringBuilder sb = new StringBuilder(); int counter = 0; for (RDN rdn : rdns) { counter = rdn.createPattern(counter); if (sb.length() > 0) sb.append(','); sb.append(rdn.getPattern()); } pattern = sb.toString(); return pattern; } public synchronized String format(Collection<Object> args) throws Exception { if (formatter == null) { formatter = new MessageFormat(getPattern()); } Collection<String> values = new ArrayList<String>(); for (Object arg : args) { String value = arg.toString(); values.add(LDAP.escape(value)); } return formatter.format(values.toArray()); } public synchronized boolean isEmpty() { if (originalDn == null) { return rdns == null || rdns.isEmpty(); } else { return "".equals(originalDn); } } public synchronized int getLength() throws Exception { parse(); return rdns.size(); } public synchronized RDN getRdn() throws Exception { parse(); if (rdns.size() == 0) return null; return rdns.get(0); } public synchronized RDN getRdn(int i) throws Exception { parse(); return rdns.get(i); } public synchronized Collection<RDN> getRdns() throws Exception { parse(); return rdns; } public synchronized String getOriginalDn() throws Exception { if (originalDn != null) return originalDn; StringBuilder sb = new StringBuilder(); if (rdns != null) { for (RDN rdn : rdns) { if (sb.length() > 0) sb.append(","); sb.append(rdn.getOriginal()); } } originalDn = sb.toString(); return originalDn; } public synchronized String getNormalizedDn() throws Exception { if (normalizedDn != null) return normalizedDn; parse(); StringBuilder sb = new StringBuilder(); for (RDN rdn : rdns) { if (sb.length() > 0) sb.append(","); sb.append(rdn.getNormalized()); } normalizedDn = sb.toString(); return normalizedDn; } public synchronized DN getParentDn() throws Exception { if (parentDn != null) return parentDn; parse(); DNBuilder db = new DNBuilder(); for (int i=1; i<rdns.size(); i++) { RDN rdn = rdns.get(i); db.append(rdn); } parentDn = db.toDn(); return parentDn; } public synchronized boolean endsWith(String suffix) throws Exception { return endsWith(new DN(suffix)); } public synchronized boolean endsWith(DN suffix) throws Exception { parse(); suffix.parse(); int i1 = rdns.size(); int i2 = suffix.rdns.size(); if (i1 < i2) return false; while (i1 > 0 && i2 > 0) { RDN rdn1 = rdns.get(i1-1); RDN rdn2 = suffix.rdns.get(i2-1); if (!rdn1.matches(rdn2)) return false; i1--; i2--; } return true; } public synchronized boolean matches(String dn) throws Exception { return matches(new DN(dn)); } public synchronized boolean matches(DN dn) throws Exception { if (dn == null) return false; if (getNormalizedDn().equals(dn.getNormalizedDn())) return true; parse(); dn.parse(); if (rdns.size() != dn.rdns.size()) return false; Iterator i = rdns.iterator(); Iterator j = dn.rdns.iterator(); while (i.hasNext() && j.hasNext()) { RDN rdn1 = (RDN)i.next(); RDN rdn2 = (RDN)j.next(); if (!rdn1.matches(rdn2)) return false; } return true; } public synchronized int hashCode() { try { return getOriginalDn().hashCode(); } catch (Exception e) { throw new RuntimeException(e.getMessage(), e); } } synchronized boolean equals(Object o1, Object o2) { if (o1 == null && o2 == null) return true; if (o1 != null) return o1.equals(o2); return o2.equals(o1); } public synchronized boolean equals(Object object) { if (this == object) return true; if (object == null) return false; try { if (object instanceof String) { String dn = (String)object; return equals(getOriginalDn(), dn); } if (object instanceof DN) { DN dn = (DN)object; return equals(getOriginalDn(), dn.getOriginalDn()); } } catch (Exception e) { throw new RuntimeException(e.getMessage(), e); } return false; } public synchronized int compareTo(Object object) { if (object == null) return 0; if (!(object instanceof DN)) return 0; DN dn = (DN)object; try { parse(); dn.parse(); } catch (Exception e) { throw new RuntimeException(e); } if (rdns.size() < dn.rdns.size()) return -1; if (rdns.size() > dn.rdns.size()) return 1; int i = rdns.size(); while (i > 0) { RDN rdn1 = rdns.get(i-1); RDN rdn2 = dn.rdns.get(i-1); int c = rdn1.compareTo(rdn2); if (c != 0) return c; i--; } return 0; } public synchronized String toString() { try { return getOriginalDn(); } catch (Exception e) { throw new RuntimeException(e.getMessage(), e); } } }