001 /* 002 * JBoss DNA (http://www.jboss.org/dna) 003 * See the COPYRIGHT.txt file distributed with this work for information 004 * regarding copyright ownership. Some portions may be licensed 005 * to Red Hat, Inc. under one or more contributor license agreements. 006 * See the AUTHORS.txt file in the distribution for a full listing of 007 * individual contributors. 008 * 009 * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA 010 * is licensed to you under the terms of the GNU Lesser General Public License as 011 * published by the Free Software Foundation; either version 2.1 of 012 * the License, or (at your option) any later version. 013 * 014 * JBoss DNA is distributed in the hope that it will be useful, 015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 017 * Lesser General Public License for more details. 018 * 019 * You should have received a copy of the GNU Lesser General Public 020 * License along with this software; if not, write to the Free 021 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 022 * 02110-1301 USA, or see the FSF site: http://www.fsf.org. 023 */ 024 package org.jboss.dna.graph.request; 025 026 import java.util.Iterator; 027 import java.util.LinkedList; 028 import java.util.List; 029 import org.jboss.dna.common.util.CheckArg; 030 import org.jboss.dna.common.util.HashCode; 031 import org.jboss.dna.graph.GraphI18n; 032 import org.jboss.dna.graph.Location; 033 import org.jboss.dna.graph.connector.RepositoryConnection; 034 import org.jboss.dna.graph.property.Path; 035 import org.jboss.dna.graph.property.Property; 036 037 /** 038 * Instruction to read all of the children of a node at a specific location. 039 * 040 * @author Randall Hauch 041 */ 042 public class ReadAllChildrenRequest extends CacheableRequest implements Iterable<Location> { 043 044 private static final long serialVersionUID = 1L; 045 046 private final Location of; 047 private final String workspaceName; 048 private final List<Location> children = new LinkedList<Location>(); 049 private Location actualOf; 050 051 /** 052 * Create a request to read the children of a node at the supplied location in the designated workspace. 053 * 054 * @param of the location of the node whose children are to be read 055 * @param workspaceName the name of the workspace 056 * @throws IllegalArgumentException if the location or workspace name is null 057 */ 058 public ReadAllChildrenRequest( Location of, 059 String workspaceName ) { 060 CheckArg.isNotNull(of, "of"); 061 CheckArg.isNotNull(workspaceName, "workspaceName"); 062 this.of = of; 063 this.workspaceName = workspaceName; 064 } 065 066 /** 067 * {@inheritDoc} 068 * 069 * @see org.jboss.dna.graph.request.Request#isReadOnly() 070 */ 071 @Override 072 public boolean isReadOnly() { 073 return true; 074 } 075 076 /** 077 * Get the location defining the node whose children are to be read. 078 * 079 * @return the location of the parent node; never null 080 */ 081 public Location of() { 082 return of; 083 } 084 085 /** 086 * Get the name of the workspace in which the parent and children exist. 087 * 088 * @return the name of the workspace; never null 089 */ 090 public String inWorkspace() { 091 return workspaceName; 092 } 093 094 /** 095 * Get the children that were read from the {@link RepositoryConnection} after the request was processed. Each child is 096 * represented by a location. 097 * 098 * @return the children that were read; never null 099 */ 100 public List<Location> getChildren() { 101 return children; 102 } 103 104 /** 105 * {@inheritDoc} 106 * 107 * @see java.lang.Iterable#iterator() 108 */ 109 public Iterator<Location> iterator() { 110 return children.iterator(); 111 } 112 113 /** 114 * Add to the list of children that has been read the supplied children with the given path and identification properties. The 115 * children are added in order. 116 * 117 * @param children the locations of the children that were read 118 * @throws IllegalArgumentException if the parameter is null 119 * @throws IllegalStateException if the request is frozen 120 * @see #addChild(Location) 121 * @see #addChild(Path, Property) 122 * @see #addChild(Path, Property, Property...) 123 */ 124 public void addChildren( Iterable<Location> children ) { 125 checkNotFrozen(); 126 CheckArg.isNotNull(children, "children"); 127 for (Location child : children) { 128 if (child != null) this.children.add(child); 129 } 130 } 131 132 /** 133 * Add to the list of children that has been read the child with the given path and identification properties. The children 134 * should be added in order. 135 * 136 * @param child the location of the child that was read 137 * @throws IllegalArgumentException if the location is null 138 * @throws IllegalStateException if the request is frozen 139 * @see #addChild(Path, Property) 140 * @see #addChild(Path, Property, Property...) 141 */ 142 public void addChild( Location child ) { 143 checkNotFrozen(); 144 CheckArg.isNotNull(child, "child"); 145 this.children.add(child); 146 } 147 148 /** 149 * Add to the list of children that has been read the child with the given path and identification properties. The children 150 * should be added in order. 151 * 152 * @param pathToChild the path of the child that was just read 153 * @param firstIdProperty the first identification property of the child that was just read 154 * @param remainingIdProperties the remaining identification properties of the child that was just read 155 * @throws IllegalArgumentException if the path or identification properties are null 156 * @throws IllegalStateException if the request is frozen 157 * @see #addChild(Location) 158 * @see #addChild(Path, Property) 159 */ 160 public void addChild( Path pathToChild, 161 Property firstIdProperty, 162 Property... remainingIdProperties ) { 163 checkNotFrozen(); 164 Location child = Location.create(pathToChild, firstIdProperty, remainingIdProperties); 165 this.children.add(child); 166 } 167 168 /** 169 * Add to the list of children that has been read the child with the given path and identification property. The children 170 * should be added in order. 171 * 172 * @param pathToChild the path of the child that was just read 173 * @param idProperty the identification property of the child that was just read 174 * @throws IllegalArgumentException if the path or identification properties are null 175 * @throws IllegalStateException if the request is frozen 176 * @see #addChild(Location) 177 * @see #addChild(Path, Property, Property...) 178 */ 179 public void addChild( Path pathToChild, 180 Property idProperty ) { 181 checkNotFrozen(); 182 Location child = Location.create(pathToChild, idProperty); 183 this.children.add(child); 184 } 185 186 /** 187 * Sets the actual and complete location of the node whose children have been read. This method must be called when processing 188 * the request, and the actual location must have a {@link Location#getPath() path}. 189 * 190 * @param actualLocation the actual location of the node being read, or null if the {@link #of() current location} should be 191 * used 192 * @throws IllegalArgumentException if the actual location does not represent the {@link Location#isSame(Location) same 193 * location} as the {@link #of() current location}; if the actual location does not have a path; or if the actual 194 * workspace name is null 195 * @throws IllegalStateException if the request is frozen 196 */ 197 public void setActualLocationOfNode( Location actualLocation ) { 198 checkNotFrozen(); 199 if (!this.of.isSame(actualLocation)) { // not same if actualLocation is null 200 throw new IllegalArgumentException(GraphI18n.actualLocationIsNotSameAsInputLocation.text(actualLocation, of)); 201 } 202 assert actualLocation != null; 203 if (!actualLocation.hasPath()) { 204 throw new IllegalArgumentException(GraphI18n.actualLocationMustHavePath.text(actualLocation)); 205 } 206 this.actualOf = actualLocation; 207 } 208 209 /** 210 * Get the actual location of the node whose children were read. 211 * 212 * @return the actual location, or null if the actual location was not set 213 */ 214 public Location getActualLocationOfNode() { 215 return actualOf; 216 } 217 218 /** 219 * {@inheritDoc} 220 * 221 * @see org.jboss.dna.graph.request.Request#cancel() 222 */ 223 @Override 224 public void cancel() { 225 super.cancel(); 226 this.actualOf = null; 227 } 228 229 /** 230 * {@inheritDoc} 231 * 232 * @see java.lang.Object#hashCode() 233 */ 234 @Override 235 public int hashCode() { 236 return HashCode.compute(of, workspaceName); 237 } 238 239 /** 240 * {@inheritDoc} 241 * 242 * @see java.lang.Object#equals(java.lang.Object) 243 */ 244 @Override 245 public boolean equals( Object obj ) { 246 if (obj == this) return true; 247 if (this.getClass().isInstance(obj)) { 248 ReadAllChildrenRequest that = (ReadAllChildrenRequest)obj; 249 if (!this.of().equals(that.of())) return false; 250 if (!this.inWorkspace().equals(that.inWorkspace())) return false; 251 return true; 252 } 253 return false; 254 } 255 256 /** 257 * {@inheritDoc} 258 * 259 * @see java.lang.Object#toString() 260 */ 261 @Override 262 public String toString() { 263 String workspaceName = this.workspaceName != null ? "\"" + this.workspaceName + "\"" : "default"; 264 return "read children of " + of() + " in the \"" + workspaceName + "\" workspace"; 265 } 266 }