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.request;
25
26 import java.util.Collection;
27 import java.util.HashMap;
28 import java.util.Iterator;
29 import java.util.Map;
30 import org.modeshape.common.util.CheckArg;
31 import org.modeshape.common.util.HashCode;
32 import org.modeshape.graph.GraphI18n;
33 import org.modeshape.graph.Location;
34 import org.modeshape.graph.connector.RepositoryConnection;
35 import org.modeshape.graph.property.Name;
36 import org.modeshape.graph.property.Property;
37
38 /**
39 * Instruction to read the properties and the number of children of the node at the specifed location.
40 */
41 public class ReadAllPropertiesRequest extends CacheableRequest implements Iterable<Property> {
42
43 private static final long serialVersionUID = 1L;
44
45 public static final int UNKNOWN_NUMBER_OF_CHILDREN = -1;
46
47 private final Location at;
48 private final String workspaceName;
49 private final Map<Name, Property> properties = new HashMap<Name, Property>();
50 private int numberOfChildren = UNKNOWN_NUMBER_OF_CHILDREN;
51 private Location actualLocation;
52
53 /**
54 * Create a request to read the properties and number of children of a node at the supplied location.
55 *
56 * @param at the location of the node to be read
57 * @param workspaceName the name of the workspace containing the node
58 * @throws IllegalArgumentException if the location or workspace name is null
59 */
60 public ReadAllPropertiesRequest( Location at,
61 String workspaceName ) {
62 CheckArg.isNotNull(at, "at");
63 CheckArg.isNotNull(workspaceName, "workspaceName");
64 this.workspaceName = workspaceName;
65 this.at = at;
66 }
67
68 /**
69 * {@inheritDoc}
70 *
71 * @see org.modeshape.graph.request.Request#isReadOnly()
72 */
73 @Override
74 public boolean isReadOnly() {
75 return true;
76 }
77
78 /**
79 * Get the location defining the node that is to be read.
80 *
81 * @return the location of the node; never null
82 */
83 public Location at() {
84 return at;
85 }
86
87 /**
88 * Get the name of the workspace in which the node exists.
89 *
90 * @return the name of the workspace; never null
91 */
92 public String inWorkspace() {
93 return workspaceName;
94 }
95
96 /**
97 * Get the properties that were read from the {@link RepositoryConnection}.
98 *
99 * @return the properties, as a map of property name to property; never null
100 */
101 public Map<Name, Property> getPropertiesByName() {
102 return properties;
103 }
104
105 /**
106 * Get the properties that were read from the {@link RepositoryConnection}.
107 *
108 * @return the collection of properties; never null
109 */
110 public Collection<Property> getProperties() {
111 return properties.values();
112 }
113
114 /**
115 * {@inheritDoc}
116 *
117 * @see java.lang.Iterable#iterator()
118 */
119 public Iterator<Property> iterator() {
120 return getProperties().iterator();
121 }
122
123 /**
124 * Add a property that was read from the {@link RepositoryConnection}
125 *
126 * @param property the property that was read
127 * @return the previous property that had the same name, or null if there was no previously-recorded property with the same
128 * name
129 * @throws IllegalArgumentException if the property is null
130 * @throws IllegalStateException if the request is frozen
131 */
132 public Property addProperty( Property property ) {
133 checkNotFrozen();
134 return this.properties.put(property.getName(), property);
135 }
136
137 /**
138 * Add a property that was read from the {@link RepositoryConnection}
139 *
140 * @param properties the properties that were read
141 * @throws IllegalArgumentException if the property is null
142 * @throws IllegalStateException if the request is frozen
143 */
144 public void addProperties( Property... properties ) {
145 checkNotFrozen();
146 for (Property property : properties) {
147 this.properties.put(property.getName(), property);
148 }
149 }
150
151 /**
152 * Add a property that was read from the {@link RepositoryConnection}
153 *
154 * @param properties the properties that were read
155 * @throws IllegalArgumentException if the property is null
156 * @throws IllegalStateException if the request is frozen
157 */
158 public void addProperties( Iterable<Property> properties ) {
159 checkNotFrozen();
160 for (Property property : properties) {
161 this.properties.put(property.getName(), property);
162 }
163 }
164
165 /**
166 * Get the number of children for this node.
167 *
168 * @return the number of children, or {@link #UNKNOWN_NUMBER_OF_CHILDREN} if the number of children was not yet read
169 */
170 public int getNumberOfChildren() {
171 return numberOfChildren;
172 }
173
174 /**
175 * Set the number of children for this node
176 *
177 * @param numberOfChildren the number of children
178 * @throws IllegalArgumentException if the number of childre is negative
179 * @throws IllegalStateException if the request is frozen
180 */
181 public void setNumberOfChildren( int numberOfChildren ) {
182 checkNotFrozen();
183 CheckArg.isNonNegative(numberOfChildren, "numberOfChildren");
184 this.numberOfChildren = numberOfChildren;
185 }
186
187 /**
188 * Sets the actual and complete location of the node whose properties have been read. This method must be called when
189 * processing the request, and the actual location must have a {@link Location#getPath() path}.
190 *
191 * @param actual the actual location of the node being read, or null if the {@link #at() current location} should be used
192 * @throws IllegalArgumentException if the actual location is null or does not have a path.
193 * @throws IllegalStateException if the request is frozen
194 */
195 public void setActualLocationOfNode( Location actual ) {
196 checkNotFrozen();
197 CheckArg.isNotNull(actual, "actual");
198 if (!actual.hasPath()) {
199 throw new IllegalArgumentException(GraphI18n.actualLocationMustHavePath.text(actual));
200 }
201 this.actualLocation = actual;
202 }
203
204 /**
205 * Get the actual location of the node whose properties were read.
206 *
207 * @return the actual location, or null if the actual location was not set
208 */
209 public Location getActualLocationOfNode() {
210 return actualLocation;
211 }
212
213 /**
214 * {@inheritDoc}
215 *
216 * @see org.modeshape.graph.request.Request#cancel()
217 */
218 @Override
219 public void cancel() {
220 super.cancel();
221 this.actualLocation = null;
222 }
223
224 /**
225 * {@inheritDoc}
226 *
227 * @see java.lang.Object#hashCode()
228 */
229 @Override
230 public int hashCode() {
231 return HashCode.compute(at, workspaceName);
232 }
233
234 /**
235 * {@inheritDoc}
236 *
237 * @see java.lang.Object#equals(java.lang.Object)
238 */
239 @Override
240 public boolean equals( Object obj ) {
241 if (obj == this) return true;
242 if (this.getClass().isInstance(obj)) {
243 ReadAllPropertiesRequest that = (ReadAllPropertiesRequest)obj;
244 if (!this.at().isSame(that.at())) return false;
245 if (!this.inWorkspace().equals(that.inWorkspace())) return false;
246 return true;
247 }
248 return false;
249 }
250
251 /**
252 * {@inheritDoc}
253 *
254 * @see java.lang.Object#toString()
255 */
256 @Override
257 public String toString() {
258 return "read properties of " + at() + " in the \"" + workspaceName + "\" workspace";
259 }
260
261 @Override
262 public RequestType getType() {
263 return RequestType.READ_ALL_PROPERTIES;
264 }
265 }