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