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.Collection;
025 import java.util.Collections;
026 import java.util.HashSet;
027 import java.util.Iterator;
028 import java.util.Set;
029 import org.jboss.dna.common.util.CheckArg;
030 import org.jboss.dna.graph.GraphI18n;
031 import org.jboss.dna.graph.Location;
032 import org.jboss.dna.graph.properties.Name;
033
034 /**
035 * Instruction to remove properties from the node at the specified location.
036 *
037 * @author Randall Hauch
038 */
039 public class RemovePropertiesRequest extends Request implements Iterable<Name> {
040
041 private static final long serialVersionUID = 1L;
042
043 private final Location from;
044 private final Set<Name> propertyNames;
045 private Location actualLocation;
046
047 /**
048 * Create a request to remove the properties with the given names from the node at the supplied location.
049 *
050 * @param from the location of the node to be read
051 * @param propertyNames the names of the properties to be removed from the node
052 * @throws IllegalArgumentException if the location is null or if there are no properties to remove
053 */
054 public RemovePropertiesRequest( Location from,
055 Name... propertyNames ) {
056 CheckArg.isNotNull(from, "from");
057 CheckArg.isNotEmpty(propertyNames, "propertyNames");
058 this.from = from;
059 Set<Name> names = new HashSet<Name>();
060 for (Name name : propertyNames) {
061 if (name != null) names.add(name);
062 }
063 this.propertyNames = Collections.unmodifiableSet(names);
064 }
065
066 /**
067 * Create a request to remove the properties with the given names from the node at the supplied location.
068 *
069 * @param from the location of the node to be read
070 * @param propertyNames the names of the properties to be removed from the node
071 * @throws IllegalArgumentException if the location is null or if there are no properties to remove
072 */
073 public RemovePropertiesRequest( Location from,
074 Iterable<Name> propertyNames ) {
075 CheckArg.isNotNull(from, "from");
076 CheckArg.isNotNull(propertyNames, "propertyNames");
077 this.from = from;
078 Set<Name> names = new HashSet<Name>();
079 for (Name name : propertyNames) {
080 if (name != null) names.add(name);
081 }
082 this.propertyNames = Collections.unmodifiableSet(names);
083 CheckArg.isNotEmpty(this.propertyNames, "propertyNames");
084 }
085
086 /**
087 * Create a request to remove the properties with the given names from the node at the supplied location.
088 *
089 * @param from the location of the node to be read
090 * @param propertyNames the names of the properties to be removed from the node
091 * @throws IllegalArgumentException if the location is null or if there are no properties to remove
092 */
093 public RemovePropertiesRequest( Location from,
094 Iterator<Name> propertyNames ) {
095 CheckArg.isNotNull(from, "from");
096 CheckArg.isNotNull(propertyNames, "propertyNames");
097 this.from = from;
098 Set<Name> names = new HashSet<Name>();
099 while (propertyNames.hasNext()) {
100 Name name = propertyNames.next();
101 if (name != null) names.add(name);
102 }
103 this.propertyNames = Collections.unmodifiableSet(names);
104 CheckArg.isNotEmpty(this.propertyNames, "propertyNames");
105 }
106
107 /**
108 * {@inheritDoc}
109 *
110 * @see org.jboss.dna.graph.requests.Request#isReadOnly()
111 */
112 @Override
113 public boolean isReadOnly() {
114 return false;
115 }
116
117 /**
118 * Get the location defining the node from which the properties are to be removed.
119 *
120 * @return the location of the node; never null
121 */
122 public Location from() {
123 return from;
124 }
125
126 /**
127 * {@inheritDoc}
128 *
129 * @see java.lang.Iterable#iterator()
130 */
131 public Iterator<Name> iterator() {
132 return this.propertyNames.iterator();
133 }
134
135 /**
136 * Get the names of the properties that are to be removed from the node.
137 *
138 * @return the collection of property names; never null and never empty
139 */
140 public Collection<Name> propertyNames() {
141 return propertyNames;
142 }
143
144 /**
145 * Sets the actual and complete location of the node whose properties were removed. This method must be called when processing
146 * the request, and the actual location must have a {@link Location#getPath() path}.
147 *
148 * @param actual the actual location of the node being changed, or null if the {@link #from() current location} should be used
149 * @throws IllegalArgumentException if the actual location does not represent the {@link Location#isSame(Location) same
150 * location} as the {@link #from() current location}, or if the actual location does not have a path.
151 */
152 public void setActualLocationOfNode( Location actual ) {
153 if (!from.isSame(actual)) { // not same if actual is null
154 throw new IllegalArgumentException(GraphI18n.actualLocationIsNotSameAsInputLocation.text(actual, from));
155 }
156 assert actual != null;
157 if (!actual.hasPath()) {
158 throw new IllegalArgumentException(GraphI18n.actualLocationMustHavePath.text(actual));
159 }
160 this.actualLocation = actual;
161 }
162
163 /**
164 * Get the actual location of the node whose properties were removed.
165 *
166 * @return the actual location, or null if the actual location was not set
167 */
168 public Location getActualLocationOfNode() {
169 return actualLocation;
170 }
171
172 /**
173 * {@inheritDoc}
174 *
175 * @see java.lang.Object#equals(java.lang.Object)
176 */
177 @Override
178 public boolean equals( Object obj ) {
179 if (this.getClass().isInstance(obj)) {
180 RemovePropertiesRequest that = (RemovePropertiesRequest)obj;
181 if (!this.from().equals(that.from())) return false;
182 if (!this.propertyNames().equals(that.propertyNames())) return false;
183 return true;
184 }
185 return false;
186 }
187
188 /**
189 * {@inheritDoc}
190 *
191 * @see java.lang.Object#toString()
192 */
193 @Override
194 public String toString() {
195 return "remove from " + from() + " properties named " + propertyNames();
196 }
197
198 }