View Javadoc

1   /*
2    * ModeShape (http://www.modeshape.org)
3    * See the COPYRIGHT.txt file distributed with this work for information
4    * regarding copyright ownership.  Some portions may be licensed
5    * to Red Hat, Inc. under one or more contributor license agreements.
6    * See the AUTHORS.txt file in the distribution for a full listing of 
7    * individual contributors. 
8    *
9    * ModeShape is free software. Unless otherwise indicated, all code in ModeShape
10   * is licensed to you under the terms of the GNU Lesser General Public License as
11   * published by the Free Software Foundation; either version 2.1 of
12   * the License, or (at your option) any later version.
13   *
14   * ModeShape is distributed in the hope that it will be useful,
15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17   * Lesser General Public License for more details.
18   *
19   * You should have received a copy of the GNU Lesser General Public
20   * License along with this software; if not, write to the Free
21   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
23   */
24  package org.modeshape.graph.property.basic;
25  
26  import java.util.Arrays;
27  import java.util.Iterator;
28  import java.util.List;
29  import net.jcip.annotations.Immutable;
30  import org.modeshape.common.util.CheckArg;
31  import org.modeshape.graph.property.Name;
32  
33  /**
34   * An immutable version of a property that has 2 or more values. This is done for efficiency of the in-memory representation,
35   * since many properties will have just a single value, while others will have multiple values.
36   */
37  @Immutable
38  public class BasicMultiValueProperty extends BasicProperty {
39      private static final long serialVersionUID = 1L;
40  
41      private final List<Object> values;
42  
43      /**
44       * Create a property with 2 or more values. Note that the supplied list may be modifiable, as this object does not expose any
45       * means for modifying the contents.
46       * 
47       * @param name the property name
48       * @param values the property values
49       * @throws IllegalArgumentException if the values is null or does not have at least 2 values
50       */
51      public BasicMultiValueProperty( Name name,
52                                      List<Object> values ) {
53          super(name);
54          CheckArg.isNotNull(values, "values");
55          CheckArg.hasSizeOfAtLeast(values, 2, "values");
56          this.values = values;
57      }
58  
59      /**
60       * Create a property with 2 or more values.
61       * 
62       * @param name the property name
63       * @param values the property values
64       * @throws IllegalArgumentException if the values is null or does not have at least 2 values
65       */
66      public BasicMultiValueProperty( Name name,
67                                      Object... values ) {
68          super(name);
69          CheckArg.isNotNull(values, "values");
70          CheckArg.hasSizeOfAtLeast(values, 2, "values");
71          this.values = Arrays.asList(values);
72      }
73  
74      /**
75       * {@inheritDoc}
76       */
77      public boolean isEmpty() {
78          return false;
79      }
80  
81      /**
82       * {@inheritDoc}
83       */
84      public boolean isMultiple() {
85          return true;
86      }
87  
88      /**
89       * {@inheritDoc}
90       */
91      public boolean isSingle() {
92          return false;
93      }
94  
95      /**
96       * {@inheritDoc}
97       */
98      public int size() {
99          return values.size();
100     }
101 
102     /**
103      * {@inheritDoc}
104      * 
105      * @see org.modeshape.graph.property.Property#getFirstValue()
106      */
107     public Object getFirstValue() {
108         return values.get(0);
109     }
110 
111     /**
112      * {@inheritDoc}
113      */
114     public Iterator<Object> iterator() {
115         return new ReadOnlyIterator(values.iterator());
116     }
117 
118     protected class ReadOnlyIterator implements Iterator<Object> {
119 
120         private final Iterator<Object> values;
121 
122         protected ReadOnlyIterator( Iterator<Object> values ) {
123             assert values != null;
124             this.values = values;
125         }
126 
127         /**
128          * {@inheritDoc}
129          */
130         public boolean hasNext() {
131             return values.hasNext();
132         }
133 
134         /**
135          * {@inheritDoc}
136          */
137         public Object next() {
138             return values.next();
139         }
140 
141         /**
142          * {@inheritDoc}
143          */
144         public void remove() {
145             throw new UnsupportedOperationException();
146         }
147 
148     }
149 }