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 }