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 }