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.Collection; 027 import java.util.HashMap; 028 import java.util.Iterator; 029 import java.util.Map; 030 import org.jboss.dna.common.util.CheckArg; 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.Name; 035 import org.jboss.dna.graph.property.Property; 036 037 /** 038 * Instruction to read the properties and the number of children of the node at the specifed location. 039 * 040 * @author Randall Hauch 041 */ 042 public class ReadAllPropertiesRequest extends CacheableRequest implements Iterable<Property> { 043 044 private static final long serialVersionUID = 1L; 045 046 public static final int UNKNOWN_NUMBER_OF_CHILDREN = -1; 047 048 private final Location at; 049 private final String workspaceName; 050 private final Map<Name, Property> properties = new HashMap<Name, Property>(); 051 private int numberOfChildren = UNKNOWN_NUMBER_OF_CHILDREN; 052 private Location actualLocation; 053 054 /** 055 * Create a request to read the properties and number of children of a node at the supplied location. 056 * 057 * @param at the location of the node to be read 058 * @param workspaceName the name of the workspace containing the node 059 * @throws IllegalArgumentException if the location or workspace name is null 060 */ 061 public ReadAllPropertiesRequest( Location at, 062 String workspaceName ) { 063 CheckArg.isNotNull(at, "at"); 064 CheckArg.isNotNull(workspaceName, "workspaceName"); 065 this.workspaceName = workspaceName; 066 this.at = at; 067 } 068 069 /** 070 * {@inheritDoc} 071 * 072 * @see org.jboss.dna.graph.request.Request#isReadOnly() 073 */ 074 @Override 075 public boolean isReadOnly() { 076 return true; 077 } 078 079 /** 080 * Get the location defining the node that is to be read. 081 * 082 * @return the location of the node; never null 083 */ 084 public Location at() { 085 return at; 086 } 087 088 /** 089 * Get the name of the workspace in which the node exists. 090 * 091 * @return the name of the workspace; never null 092 */ 093 public String inWorkspace() { 094 return workspaceName; 095 } 096 097 /** 098 * Get the properties that were read from the {@link RepositoryConnection}. 099 * 100 * @return the properties, as a map of property name to property; never null 101 */ 102 public Map<Name, Property> getPropertiesByName() { 103 return properties; 104 } 105 106 /** 107 * Get the properties that were read from the {@link RepositoryConnection}. 108 * 109 * @return the collection of properties; never null 110 */ 111 public Collection<Property> getProperties() { 112 return properties.values(); 113 } 114 115 /** 116 * {@inheritDoc} 117 * 118 * @see java.lang.Iterable#iterator() 119 */ 120 public Iterator<Property> iterator() { 121 return getProperties().iterator(); 122 } 123 124 /** 125 * Add a property that was read from the {@link RepositoryConnection} 126 * 127 * @param property the property that was read 128 * @return the previous property that had the same name, or null if there was no previously-recorded property with the same 129 * name 130 * @throws IllegalArgumentException if the property is null 131 */ 132 public Property addProperty( Property property ) { 133 return this.properties.put(property.getName(), property); 134 } 135 136 /** 137 * Add a property that was read from the {@link RepositoryConnection} 138 * 139 * @param properties the properties that were read 140 * @throws IllegalArgumentException if the property is null 141 */ 142 public void addProperties( Property... properties ) { 143 for (Property property : properties) { 144 this.properties.put(property.getName(), property); 145 } 146 } 147 148 /** 149 * Get the number of children for this node. 150 * 151 * @return the number of children, or {@link #UNKNOWN_NUMBER_OF_CHILDREN} if the number of children was not yet read 152 */ 153 public int getNumberOfChildren() { 154 return numberOfChildren; 155 } 156 157 /** 158 * Set the number of children for this node 159 * 160 * @param numberOfChildren the number of children 161 * @throws IllegalArgumentException if the number of childre is negative 162 */ 163 public void setNumberOfChildren( int numberOfChildren ) { 164 CheckArg.isNonNegative(numberOfChildren, "numberOfChildren"); 165 this.numberOfChildren = numberOfChildren; 166 } 167 168 /** 169 * Sets the actual and complete location of the node whose properties have been read. This method must be called when 170 * processing the request, and the actual location must have a {@link Location#getPath() path}. 171 * 172 * @param actual the actual location of the node being read, or null if the {@link #at() current location} should be used 173 * @throws IllegalArgumentException if the actual location does not represent the {@link Location#isSame(Location) same 174 * location} as the {@link #at() current location}, or if the actual location does not have a path. 175 */ 176 public void setActualLocationOfNode( Location actual ) { 177 if (!at.isSame(actual)) { // not same if actual is null 178 throw new IllegalArgumentException(GraphI18n.actualLocationIsNotSameAsInputLocation.text(actual, at)); 179 } 180 assert actual != null; 181 if (!actual.hasPath()) { 182 throw new IllegalArgumentException(GraphI18n.actualLocationMustHavePath.text(actual)); 183 } 184 this.actualLocation = actual; 185 } 186 187 /** 188 * Get the actual location of the node whose properties were read. 189 * 190 * @return the actual location, or null if the actual location was not set 191 */ 192 public Location getActualLocationOfNode() { 193 return actualLocation; 194 } 195 196 /** 197 * {@inheritDoc} 198 * 199 * @see java.lang.Object#equals(java.lang.Object) 200 */ 201 @Override 202 public boolean equals( Object obj ) { 203 if (obj == this) return true; 204 if (this.getClass().isInstance(obj)) { 205 ReadAllPropertiesRequest that = (ReadAllPropertiesRequest)obj; 206 if (!this.at().equals(that.at())) return false; 207 if (!this.inWorkspace().equals(that.inWorkspace())) return false; 208 return true; 209 } 210 return false; 211 } 212 213 /** 214 * {@inheritDoc} 215 * 216 * @see java.lang.Object#toString() 217 */ 218 @Override 219 public String toString() { 220 return "read properties of " + at() + " in the \"" + workspaceName + "\" workspace"; 221 } 222 223 }