001    /*
002     * CDDL HEADER START
003     *
004     * The contents of this file are subject to the terms of the
005     * Common Development and Distribution License, Version 1.0 only
006     * (the "License").  You may not use this file except in compliance
007     * with the License.
008     *
009     * You can obtain a copy of the license at
010     * trunk/opends/resource/legal-notices/OpenDS.LICENSE
011     * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
012     * See the License for the specific language governing permissions
013     * and limitations under the License.
014     *
015     * When distributing Covered Code, include this CDDL HEADER in each
016     * file and include the License file at
017     * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
018     * add the following below this CDDL HEADER, with the fields enclosed
019     * by brackets "[]" replaced with your own identifying information:
020     *      Portions Copyright [yyyy] [name of copyright owner]
021     *
022     * CDDL HEADER END
023     *
024     *
025     *      Copyright 2008 Sun Microsystems, Inc.
026     */
027    package org.opends.server.types;
028    
029    
030    
031    import java.util.Collection;
032    import java.util.LinkedHashSet;
033    import java.util.List;
034    
035    import org.opends.server.admin.std.server.VirtualAttributeCfg;
036    import org.opends.server.api.VirtualAttributeProvider;
037    
038    
039    
040    /**
041     * This class defines a virtual attribute, which is a special kind of
042     * attribute whose values do not actually exist in persistent storage
043     * but rather are computed or otherwise obtained dynamically.
044     */
045    @org.opends.server.types.PublicAPI(
046         stability=org.opends.server.types.StabilityLevel.VOLATILE,
047         mayInstantiate=false,
048         mayExtend=false,
049         mayInvoke=true)
050    public final class VirtualAttribute
051           extends Attribute
052    {
053      // The entry with which this virtual attribute is associated.
054      private final Entry entry;
055    
056      // The virtual attribute provider for this virtual attribute.
057      private final VirtualAttributeProvider<
058                         ? extends VirtualAttributeCfg> provider;
059    
060      // The virtual attribute rule for this virtual attribute.
061      private final VirtualAttributeRule rule;
062    
063    
064    
065      /**
066       * Creates a new virtual attribute with the provided information.
067       *
068       * @param  attributeType  The attribute type for this virtual
069       *                        attribute.
070       * @param  entry          The entry in which this virtual attribute
071       *                        exists.
072    * @param  rule           The virutal attribute rule that governs
073       *                        the behavior of this virtual attribute.
074       */
075      public VirtualAttribute(AttributeType attributeType, Entry entry,
076                              VirtualAttributeRule rule)
077      {
078        super(attributeType);
079    
080        this.entry = entry;
081        this.rule  = rule;
082    
083        provider = rule.getProvider();
084      }
085    
086    
087    
088      /**
089       * Retrieves the entry in which this virtual attribute exists.
090       *
091       * @return  The entry in which this virtual attribute exists.
092       */
093      public Entry getEntry()
094      {
095        return entry;
096      }
097    
098    
099    
100      /**
101       * Retrieves the virtual attribute rule that governs the behavior of
102       * this virtual attribute.
103       *
104       * @return  The virtual attribute rule that governs the behavior of
105       *          this virtual attribute.
106       */
107      public VirtualAttributeRule getVirtualAttributeRule()
108      {
109        return rule;
110      }
111    
112    
113    
114      /**
115       * Retrieves the set of values for this attribute.  The returned set
116       * of values may be altered by the caller.
117       *
118       * @return  The set of values for this attribute.
119       */
120      @Override()
121      public LinkedHashSet<AttributeValue> getValues()
122      {
123        return provider.getValues(entry, rule);
124      }
125    
126    
127    
128      /**
129       * Indicates whether this attribute contains one or more values.
130       *
131       * @return  <CODE>true</CODE> if this attribute contains one or more
132       *          values, or <CODE>false</CODE> if it does not.
133       */
134      @Override()
135      public boolean hasValue()
136      {
137        return provider.hasValue(entry, rule);
138      }
139    
140    
141    
142      /**
143       * Indicates whether this attribute contains the specified value.
144       *
145       * @param  value  The value for which to make the determination.
146       *
147       * @return  <CODE>true</CODE> if this attribute has the specified
148       *          value, or <CODE>false</CODE> if not.
149       */
150      @Override()
151      public boolean hasValue(AttributeValue value)
152      {
153        return provider.hasValue(entry, rule, value);
154      }
155    
156    
157    
158      /**
159       * Indicates whether this attribute contains all the values in the
160       * collection.
161       *
162       * @param  values  The set of values for which to make the
163       *                 determination.
164       *
165       * @return  <CODE>true</CODE> if this attribute contains all the
166       *          values in the provided collection, or <CODE>false</CODE>
167       *          if it does not contain at least one of them.
168       */
169      @Override()
170      public boolean hasAllValues(Collection<AttributeValue> values)
171      {
172        return provider.hasAllValues(entry, rule, values);
173      }
174    
175    
176    
177      /**
178       * Indicates whether this attribute contains any of the values in
179       * the collection.
180       *
181       * @param  values  The set of values for which to make the
182       *                 determination.
183       *
184       * @return  <CODE>true</CODE> if this attribute contains at least
185       *          one of the values in the provided collection, or
186       *          <CODE>false</CODE> if it does not contain any of the
187       *          values.
188       */
189      @Override()
190      public boolean hasAnyValue(Collection<AttributeValue> values)
191      {
192        return provider.hasAnyValue(entry, rule, values);
193      }
194    
195    
196    
197      /**
198       * Indicates whether this attribute has any value(s) that match the
199       * provided substring.
200       *
201       * @param  subInitial  The subInitial component to use in the
202       *                     determination.
203       * @param  subAny      The subAny components to use in the
204       *                     determination.
205       * @param  subFinal    The subFinal component to use in the
206       *                     determination.
207       *
208       * @return  <CODE>UNDEFINED</CODE> if this attribute does not have a
209       *          substring matching rule, <CODE>TRUE</CODE> if at least
210       *          one value matches the provided substring, or
211       *          <CODE>FALSE</CODE> otherwise.
212       */
213      @Override()
214      public ConditionResult matchesSubstring(ByteString subInitial,
215                                              List<ByteString> subAny,
216                                              ByteString subFinal)
217      {
218        return provider.matchesSubstring(entry, rule, subInitial, subAny,
219                                         subFinal);
220      }
221    
222    
223    
224      /**
225       * Indicates whether this attribute has any value(s) that are
226       * greater than or equal to the provided value.
227       *
228       * @param  value  The value for which to make the determination.
229       *
230       * @return  <CODE>UNDEFINED</CODE> if this attribute does not have
231       *          an ordering matching rule, <CODE>TRUE</CODE> if at least
232       *          one value is greater than or equal to the provided
233       *          value, or <CODE>false</CODE> otherwise.
234       */
235      @Override()
236      public ConditionResult greaterThanOrEqualTo(AttributeValue value)
237      {
238        return provider.greaterThanOrEqualTo(entry, rule, value);
239      }
240    
241    
242    
243      /**
244       * Indicates whether this attribute has any value(s) that are less
245       * than or equal to the provided value.
246       *
247       * @param  value  The value for which to make the determination.
248       *
249       * @return  <CODE>UNDEFINED</CODE> if this attribute does not have
250       *          an ordering matching rule, <CODE>TRUE</CODE> if at least
251       *          one value is less than or equal to the provided value,
252       *          or <CODE>false</CODE> otherwise.
253       */
254      @Override()
255      public ConditionResult lessThanOrEqualTo(AttributeValue value)
256      {
257        return provider.lessThanOrEqualTo(entry, rule, value);
258      }
259    
260    
261    
262      /**
263       * Indicates whether this attribute has any value(s) that are
264       * approximately equal to the provided value.
265       *
266       * @param  value  The value for which to make the determination.
267       *
268       * @return  <CODE>UNDEFINED</CODE> if this attribute does not have
269       *          an approximate matching rule, <CODE>TRUE</CODE> if at
270       *          least one value is approximately equal to the provided
271       *          value, or <CODE>false</CODE> otherwise.
272       */
273      @Override()
274      public ConditionResult approximatelyEqualTo(AttributeValue value)
275      {
276        return provider.approximatelyEqualTo(entry, rule, value);
277      }
278    
279    
280    
281      /**
282       * Indicates whether this is a virtual attribute rather than a real
283       * attribute.
284       *
285       * @return  {@code true} if this is a virtual attribute, or
286       *          {@code false} if it is a real attribute.
287       */
288      @Override()
289      public boolean isVirtual()
290      {
291        return true;
292      }
293    
294    
295    
296      /**
297       * Creates a duplicate of this attribute that can be modified
298       * without impacting this attribute.
299       *
300       * @param omitValues <CODE>true</CODE> if the values should be
301       *        omitted.
302       *
303       * @return  A duplicate of this attribute that can be modified
304       *          without impacting this attribute.
305       */
306      @Override()
307      public Attribute duplicate(boolean omitValues)
308      {
309        return new VirtualAttribute(getAttributeType(), entry, rule);
310      }
311    
312    
313    
314      /**
315       * Appends a one-line string representation of this attribute to the
316       * provided buffer.
317       *
318       * @param  buffer  The buffer to which the information should be
319       *                 appended.
320       */
321      @Override()
322      public void toString(StringBuilder buffer)
323      {
324        buffer.append("VirtualAttribute(");
325        buffer.append(getAttributeType().getNameOrOID());
326        buffer.append(", {");
327    
328        boolean firstValue = true;
329        for (AttributeValue value : getValues())
330        {
331          if (! firstValue)
332          {
333            buffer.append(", ");
334          }
335    
336          value.toString(buffer);
337          firstValue = false;
338        }
339    
340        buffer.append("})");
341      }
342    }
343