View Javadoc

1   /*
2    * Copyright 2005-2008 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.springframework.ldap.core;
17  
18  import java.io.Serializable;
19  import java.net.URI;
20  import java.net.URISyntaxException;
21  
22  import org.apache.commons.lang.StringUtils;
23  import org.apache.commons.lang.Validate;
24  
25  /**
26   * Represents part of an LdapRdn. As specified in RFC2253 an LdapRdn may be
27   * composed of several attributes, separated by "+". An
28   * LdapRdnComponent represents one of these attributes.
29   * 
30   * @author Mattias Hellborg Arthursson
31   * 
32   */
33  public class LdapRdnComponent implements Comparable, Serializable {
34  	private static final long serialVersionUID = -3296747972616243038L;
35  
36  	public static final boolean DONT_DECODE_VALUE = false;
37  
38  	private String key;
39  
40  	private String value;
41  
42  	/**
43  	 * Constructs an LdapRdnComponent without decoding the value.
44  	 * 
45  	 * @param key the Attribute name.
46  	 * @param value the Attribute value.
47  	 */
48  	public LdapRdnComponent(String key, String value) {
49  		this(key, value, DONT_DECODE_VALUE);
50  	}
51  
52  	/**
53  	 * Constructs an LdapRdnComponent, optionally decoding the value.
54  	 * 
55  	 * @param key the Atttribute name.
56  	 * @param value the Attribute value.
57  	 * @param decodeValue if <code>true</code> the value is decoded (typically
58  	 * used when a DN is parsed from a String), otherwise the value is used as
59  	 * specified.
60  	 */
61  	public LdapRdnComponent(String key, String value, boolean decodeValue) {
62  		Validate.notEmpty(key, "Key must not be empty");
63  		Validate.notEmpty(value, "Value must not be empty");
64  
65  		this.key = StringUtils.lowerCase(key);
66  		if (decodeValue) {
67  			this.value = LdapEncoder.nameDecode(value);
68  		}
69  		else {
70  			this.value = value;
71  		}
72  	}
73  
74  	/**
75  	 * Get the key (Attribute name) of this component.
76  	 * 
77  	 * @return the key.
78  	 */
79  	public String getKey() {
80  		return key;
81  	}
82  
83  	/**
84  	 * Set the key (Attribute name) of this component.
85  	 * 
86  	 * @param key the key.
87  	 * @deprecated Using this method changes the internal state of surrounding
88  	 * DistinguishedName instance. This should be avoided.
89  	 */
90  	public void setKey(String key) {
91  		this.key = key;
92  	}
93  
94  	/**
95  	 * Get the (Attribute) value of this component.
96  	 * 
97  	 * @return the value.
98  	 */
99  	public String getValue() {
100 		return value;
101 	}
102 
103 	/**
104 	 * Set the (Attribute) value of this component.
105 	 * 
106 	 * @param value the value.
107 	 * @deprecated Using this method changes the internal state of surrounding
108 	 * DistinguishedName instance. This should be avoided.
109 	 */
110 	public void setValue(String value) {
111 		this.value = value;
112 	}
113 
114 	/**
115 	 * Encode key and value to ldap.
116 	 * 
117 	 * @return Properly ldap escaped rdn.
118 	 */
119 	protected String encodeLdap() {
120 		StringBuffer buff = new StringBuffer(key.length() + value.length() * 2);
121 
122 		buff.append(key);
123 		buff.append('=');
124 		buff.append(LdapEncoder.nameEncode(value));
125 
126 		return buff.toString();
127 	}
128 
129 	/*
130 	 * (non-Javadoc)
131 	 * 
132 	 * @see java.lang.Object#toString()
133 	 */
134 	public String toString() {
135 		return getLdapEncoded();
136 	}
137 
138 	/**
139 	 * @return The LdapRdn as a string where the value is LDAP-encoded.
140 	 */
141 	public String getLdapEncoded() {
142 		return encodeLdap();
143 	}
144 
145 	/**
146 	 * Get a String representation of this instance for use in URLs.
147 	 * 
148 	 * @return a properly URL encoded representation of this instancs.
149 	 */
150 	public String encodeUrl() {
151 		// Use the URI class to properly URL encode the value.
152 		try {
153 			URI valueUri = new URI(null, null, value, null);
154 			return key + "=" + valueUri.toString();
155 		}
156 		catch (URISyntaxException e) {
157 			// This should really never happen...
158 			return key + "=" + "value";
159 		}
160 	}
161 
162 	/*
163 	 * (non-Javadoc)
164 	 * 
165 	 * @see java.lang.Object#hashCode()
166 	 */
167 	public int hashCode() {
168 		return key.toUpperCase().hashCode() ^ value.toUpperCase().hashCode();
169 	}
170 
171 	/*
172 	 * (non-Javadoc)
173 	 * 
174 	 * @see java.lang.Object#equals(java.lang.Object)
175 	 */
176 	public boolean equals(Object obj) {
177 		// Slightly more lenient equals comparison here to enable immutable
178 		// instances to equal mutable ones.
179 		if (obj != null && obj instanceof LdapRdnComponent) {
180 			LdapRdnComponent that = (LdapRdnComponent) obj;
181 			return StringUtils.equalsIgnoreCase(this.key, that.key)
182 					&& StringUtils.equalsIgnoreCase(this.value, that.value);
183 
184 		}
185 		else {
186 			return false;
187 		}
188 	}
189 
190 	/**
191 	 * Compare this instance to the supplied object.
192 	 * 
193 	 * @param obj the object to compare to.
194 	 * @throws ClassCastException if the object is not possible to cast to an
195 	 * LdapRdnComponent.
196 	 */
197 	public int compareTo(Object obj) {
198 		LdapRdnComponent that = (LdapRdnComponent) obj;
199 		return this.toString().compareTo(that.toString());
200 	}
201 
202 	/**
203 	 * Create an immutable copy of this instance. It will not be possible to
204 	 * modify the key or the value of the returned instance.
205 	 * 
206 	 * @return an immutable copy of this instance.
207 	 * @since 1.3
208 	 */
209 	public LdapRdnComponent immutableLdapRdnComponent() {
210 		return new ImmutableLdapRdnComponent(key, value);
211 	}
212 
213 	private static class ImmutableLdapRdnComponent extends LdapRdnComponent {
214 		private static final long serialVersionUID = -7099970046426346567L;
215 
216 		public ImmutableLdapRdnComponent(String key, String value) {
217 			super(key, value);
218 		}
219 
220 		public void setKey(String key) {
221 			throw new UnsupportedOperationException("SetValue not supported for this immutable LdapRdnComponent");
222 		}
223 
224 		public void setValue(String value) {
225 			throw new UnsupportedOperationException("SetKey not supported for this immutable LdapRdnComponent");
226 		}
227 	}
228 }