001 /*
002 * JBoss, Home of Professional Open Source.
003 * Copyright 2008, Red Hat Middleware LLC, and individual contributors
004 * as indicated by the @author tags. See the copyright.txt file in the
005 * distribution for a full listing of individual contributors.
006 *
007 * This is free software; you can redistribute it and/or modify it
008 * under the terms of the GNU Lesser General Public License as
009 * published by the Free Software Foundation; either version 2.1 of
010 * the License, or (at your option) any later version.
011 *
012 * This software is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015 * Lesser General Public License for more details.
016 *
017 * You should have received a copy of the GNU Lesser General Public
018 * License along with this software; if not, write to the Free
019 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021 */
022 package org.jboss.dna.graph.requests;
023
024 import java.util.Arrays;
025 import java.util.Collection;
026 import java.util.Collections;
027 import java.util.Iterator;
028 import java.util.LinkedList;
029 import java.util.List;
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.properties.Property;
034
035 /**
036 * Instruction to update the properties on the node at the specified location. Any property with no values will be removed.
037 *
038 * @author Randall Hauch
039 */
040 public class UpdatePropertiesRequest extends Request implements Iterable<Property> {
041
042 private static final long serialVersionUID = 1L;
043
044 private final Location on;
045 private final List<Property> properties;
046 private Location actualLocation;
047
048 /**
049 * Create a request to update the properties on the node at the supplied location.
050 *
051 * @param on the location of the node to be read
052 * @param properties the new properties on the node
053 * @throws IllegalArgumentException if the location is null or if there are no properties to update
054 */
055 public UpdatePropertiesRequest( Location on,
056 Property... properties ) {
057 CheckArg.isNotNull(on, "on");
058 CheckArg.isNotEmpty(properties, "properties");
059 this.on = on;
060 this.properties = Collections.unmodifiableList(Arrays.asList(properties));
061 }
062
063 /**
064 * Create a request to update the properties on the node at the supplied location.
065 *
066 * @param on the location of the node to be read
067 * @param properties the new properties on the node
068 * @throws IllegalArgumentException if the location is null or if there are no properties to update
069 */
070 public UpdatePropertiesRequest( Location on,
071 Iterable<Property> properties ) {
072 CheckArg.isNotNull(on, "on");
073 CheckArg.isNotNull(properties, "properties");
074 this.on = on;
075 List<Property> props = new LinkedList<Property>();
076 for (Property property : properties) {
077 if (property != null) props.add(property);
078 }
079 this.properties = Collections.unmodifiableList(props);
080 CheckArg.isNotEmpty(this.properties, "properties");
081 }
082
083 /**
084 * Create a request to update the properties on the node at the supplied location.
085 *
086 * @param on the location of the node to be read
087 * @param properties the new properties on the node
088 * @throws IllegalArgumentException if the location is null or if there are no properties to update
089 */
090 public UpdatePropertiesRequest( Location on,
091 Iterator<Property> properties ) {
092 CheckArg.isNotNull(on, "on");
093 CheckArg.isNotNull(properties, "properties");
094 this.on = on;
095 List<Property> props = new LinkedList<Property>();
096 while (properties.hasNext()) {
097 Property property = properties.next();
098 if (property != null) props.add(property);
099 }
100 this.properties = Collections.unmodifiableList(props);
101 CheckArg.isNotEmpty(this.properties, "properties");
102 }
103
104 /**
105 * {@inheritDoc}
106 *
107 * @see org.jboss.dna.graph.requests.Request#isReadOnly()
108 */
109 @Override
110 public boolean isReadOnly() {
111 return false;
112 }
113
114 /**
115 * Get the location defining the node that is to be updated.
116 *
117 * @return the location of the node; never null
118 */
119 public Location on() {
120 return on;
121 }
122
123 /**
124 * {@inheritDoc}
125 *
126 * @see java.lang.Iterable#iterator()
127 */
128 public Iterator<Property> iterator() {
129 return this.properties.iterator();
130 }
131
132 /**
133 * Get the properties for the node.
134 *
135 * @return the collection of properties; never null and never empty
136 */
137 public Collection<Property> properties() {
138 return properties;
139 }
140
141 /**
142 * Sets the actual and complete location of the node being updated. This method must be called when processing the request,
143 * and the actual location must have a {@link Location#getPath() path}.
144 *
145 * @param actual the actual location of the node being updated, or null if the {@link #on() current location} should be used
146 * @throws IllegalArgumentException if the actual location does represent the {@link Location#isSame(Location) same location}
147 * as the {@link #on() current location}, or if the actual location does not have a path.
148 */
149 public void setActualLocationOfNode( Location actual ) {
150 if (!on.isSame(actual)) { // not same if actual is null
151 throw new IllegalArgumentException(GraphI18n.actualLocationIsNotSameAsInputLocation.text(actual, on));
152 }
153 assert actual != null;
154 if (!actual.hasPath()) {
155 throw new IllegalArgumentException(GraphI18n.actualLocationMustHavePath.text(actual));
156 }
157 this.actualLocation = actual;
158 }
159
160 /**
161 * Get the actual location of the node that was updated.
162 *
163 * @return the actual location, or null if the actual location was not set
164 */
165 public Location getActualLocationOfNode() {
166 return actualLocation;
167 }
168
169 /**
170 * {@inheritDoc}
171 *
172 * @see java.lang.Object#equals(java.lang.Object)
173 */
174 @Override
175 public boolean equals( Object obj ) {
176 if (this.getClass().isInstance(obj)) {
177 UpdatePropertiesRequest that = (UpdatePropertiesRequest)obj;
178 if (!this.on().equals(that.on())) return false;
179 if (!this.properties().equals(that.properties())) return false;
180 return true;
181 }
182 return false;
183 }
184
185 /**
186 * {@inheritDoc}
187 *
188 * @see java.lang.Object#toString()
189 */
190 @Override
191 public String toString() {
192 return "update properties on " + on() + " to " + properties();
193 }
194
195 }