001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements. See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership. The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License. You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied. See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 *
019 */
020 package org.apache.directory.shared.ldap.schema;
021
022
023 import java.io.Serializable;
024 import javax.naming.NamingException;
025
026
027 /**
028 * Attribute specification bean used to store the schema information for an
029 * attributeType definition.
030 *
031 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
032 * @version $Rev: 702493 $
033 */
034 public abstract class AbstractAttributeType extends AbstractSchemaObject implements Serializable, AttributeType
035 {
036 // ------------------------------------------------------------------------
037 // Specification Attributes
038 // ------------------------------------------------------------------------
039
040 /** whether or not this type is single valued */
041 private boolean isSingleValue = false;
042
043 /** whether or not this type is a collective attribute */
044 private boolean isCollective = false;
045
046 /** whether or not this type can be modified by directory users */
047 private boolean canUserModify = true;
048
049 /** the usage for this attributeType */
050 private UsageEnum usage = UsageEnum.USER_APPLICATIONS;
051
052 /** the length of this attribute in bytes */
053 private int length = -1;
054
055
056 // ------------------------------------------------------------------------
057 // C O N S T R U C T O R S
058 // ------------------------------------------------------------------------
059
060 /**
061 * Creates an AttributeType using a unique OID.
062 *
063 * @param oid
064 * the IANA OID number for the attributeType
065 */
066 protected AbstractAttributeType( String oid )
067 {
068 super( oid );
069 }
070
071
072 // ------------------------------------------------------------------------
073 // Accessor Methods for Specification Properties
074 // ------------------------------------------------------------------------
075
076 /**
077 * @see AttributeType#isSingleValue()
078 * @return true if only one value can exist for this AttributeType, false
079 * otherwise
080 */
081 public boolean isSingleValue()
082 {
083 return isSingleValue;
084 }
085
086
087 /**
088 * @see AttributeType#isCollective()
089 * @return true if the attribute is collective, false otherwise
090 */
091 public boolean isCollective()
092 {
093 return isCollective;
094 }
095
096
097 /**
098 * @see AttributeType#isCanUserModify()
099 * @return true if users can modify it, false if only the directory can.
100 */
101 public boolean isCanUserModify()
102 {
103 return canUserModify;
104 }
105
106
107 /**
108 * @see AttributeType#getUsage()
109 * @return a type safe UsageEnum
110 */
111 public UsageEnum getUsage()
112 {
113 return usage;
114 }
115
116
117 /**
118 * @see AttributeType#getLength()
119 * @return the length of the attribute
120 */
121 public int getLength()
122 {
123 return length;
124 }
125
126
127 // ------------------------------------------------------------------------
128 // M U T A T O R S
129 // ------------------------------------------------------------------------
130
131
132 /**
133 * Sets whether or not an attribute of this AttributeType single valued or
134 * multi-valued.
135 *
136 * @param singleValue
137 * true if its is single valued, false if multi-valued
138 */
139 protected void setSingleValue( boolean singleValue )
140 {
141 isSingleValue = singleValue;
142 }
143
144
145 /**
146 * Sets whether or not an attribute of this AttributeType is a collective.
147 *
148 * @param collective
149 * true if it is collective, false otherwise
150 */
151 protected void setCollective( boolean collective )
152 {
153 isCollective = collective;
154 }
155
156
157 /**
158 * Sets whether or not an attribute of this AttributeType can be modified by
159 * directory users.
160 *
161 * @param canUserModify
162 * true if directory users can modify, false otherwise
163 */
164 protected void setCanUserModify( boolean canUserModify )
165 {
166 this.canUserModify = canUserModify;
167 }
168
169
170 /**
171 * The usage class for this attributeType.
172 *
173 * @param usage
174 * the way attributes of this AttributeType are used in the DSA
175 */
176 protected void setUsage( UsageEnum usage )
177 {
178 this.usage = usage;
179 }
180
181
182 /**
183 * Sets the length limit of this AttributeType based on its associated
184 * syntax.
185 *
186 * @param length
187 * the new length to set
188 */
189 protected void setLength( int length )
190 {
191 this.length = length;
192 }
193
194
195 // -----------------------------------------------------------------------
196 // Additional Methods
197 // -----------------------------------------------------------------------
198 /**
199 * Checks to see if this AttributeType is the ancestor of another
200 * attributeType.
201 *
202 * @param descendant the perspective descendant to check
203 * @return true if the descendant is truly a derived from this AttributeType
204 * @throws NamingException if there are problems resolving superior types
205 */
206 public boolean isAncestorOf( AttributeType descendant ) throws NamingException
207 {
208 if ( ( descendant == null ) || equals( descendant ) )
209 {
210 return false;
211 }
212
213 return isAncestorOrEqual( this, descendant );
214 }
215
216
217 /**
218 * Checks to see if this AttributeType is the descendant of another
219 * attributeType.
220 *
221 * @param ancestor the perspective ancestor to check
222 * @return true if this AttributeType truly descends from the ancestor
223 * @throws NamingException if there are problems resolving superior types
224 */
225 public boolean isDescendantOf( AttributeType ancestor ) throws NamingException
226 {
227 if ( ( ancestor == null ) || equals( ancestor ) )
228 {
229 return false;
230 }
231
232 return isAncestorOrEqual( ancestor, this );
233 }
234
235
236 /**
237 * Recursive method which checks to see if a descendant is really an ancestor or if the two
238 * are equal.
239 *
240 * @param ancestor the possible ancestor of the descendant
241 * @param descendant the possible descendant of the ancestor
242 * @return true if the ancestor equals the descendant or if the descendant is really
243 * a subtype of the ancestor. otherwise false
244 * @throws NamingException if there are issues with superior attribute resolution
245 */
246 private boolean isAncestorOrEqual( AttributeType ancestor, AttributeType descendant ) throws NamingException
247 {
248 if ( ( ancestor == null ) || ( descendant == null ) )
249 {
250 return false;
251 }
252
253 if ( ancestor.equals( descendant ) )
254 {
255 return true;
256 }
257
258 return isAncestorOrEqual( ancestor, descendant.getSuperior() );
259 }
260 }