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 org.jboss.dna.common.util.CheckArg;
025    import org.jboss.dna.graph.GraphI18n;
026    import org.jboss.dna.graph.Location;
027    import org.jboss.dna.graph.properties.Name;
028    import org.jboss.dna.graph.properties.Path;
029    
030    /**
031     * Instruction to rename an existing node (but keep it under the same parent). The same-name-sibling index will be determined
032     * automatically, based upon it's current location within the list of children.
033     * 
034     * @author Randall Hauch
035     */
036    public class RenameNodeRequest extends Request {
037    
038        private static final long serialVersionUID = 1L;
039    
040        private final Location at;
041        private final Name newName;
042        private Location actualOldLocation;
043        private Location actualNewLocation;
044    
045        /**
046         * Create a request to rename the node at the supplied location.
047         * 
048         * @param at the location of the node to be read
049         * @param newName the new name for the node
050         * @throws IllegalArgumentException if the location is null
051         */
052        public RenameNodeRequest( Location at,
053                                  Name newName ) {
054            CheckArg.isNotNull(at, "at");
055            CheckArg.isNotNull(newName, "newName");
056            this.at = at;
057            this.newName = newName;
058        }
059    
060        /**
061         * {@inheritDoc}
062         * 
063         * @see org.jboss.dna.graph.requests.Request#isReadOnly()
064         */
065        @Override
066        public boolean isReadOnly() {
067            return false;
068        }
069    
070        /**
071         * Get the location defining the node that is to be read.
072         * 
073         * @return the location of the node; never null
074         */
075        public Location at() {
076            return at;
077        }
078    
079        /**
080         * Get the new name for the node.
081         * 
082         * @return the new name; never null
083         */
084        public Name toName() {
085            return newName;
086        }
087    
088        /**
089         * Sets the actual and complete location of the node being renamed and its new location. This method must be called when
090         * processing the request, and the actual location must have a {@link Location#getPath() path}.
091         * 
092         * @param oldLocation the actual location of the node before being renamed
093         * @param newLocation the actual location of the node after being renamed
094         * @throws IllegalArgumentException if the either location is null or is missing its path, if the old location does not
095         *         represent the {@link Location#isSame(Location) same location} as the {@link #at() current location}, if the new
096         *         location does not have the same parent as the old location, or if the new location does not have the same
097         *         {@link Path.Segment#getName() name} on {@link Path#getLastSegment() last segment} as that {@link #toName()
098         *         specified on the request}
099         */
100        public void setActualLocations( Location oldLocation,
101                                        Location newLocation ) {
102            if (!at.isSame(oldLocation)) { // not same if actual is null
103                throw new IllegalArgumentException(GraphI18n.actualLocationIsNotSameAsInputLocation.text(oldLocation, at));
104            }
105            assert oldLocation != null;
106            if (newLocation == null) {
107                throw new IllegalArgumentException(GraphI18n.actualLocationIsNotSameAsInputLocation.text(newLocation, at));
108            }
109            if (!oldLocation.hasPath()) {
110                throw new IllegalArgumentException(GraphI18n.actualOldLocationMustHavePath.text(oldLocation));
111            }
112            if (!newLocation.hasPath()) {
113                throw new IllegalArgumentException(GraphI18n.actualNewLocationMustHavePath.text(newLocation));
114            }
115            Path newPath = newLocation.getPath();
116            if (!newPath.getParent().equals(oldLocation.getPath().getParent())) {
117                String msg = GraphI18n.actualNewLocationMustHaveSameParentAsOldLocation.text(newLocation, oldLocation);
118                throw new IllegalArgumentException(msg);
119            }
120            if (!newPath.getLastSegment().getName().equals(toName())) {
121                String msg = GraphI18n.actualNewLocationMustHaveSameNameAsRequest.text(newLocation, toName());
122                throw new IllegalArgumentException(msg);
123            }
124            this.actualNewLocation = newLocation;
125        }
126    
127        /**
128         * Get the actual location of the node before being renamed.
129         * 
130         * @return the actual location of the node before being renamed, or null if the actual location was not set
131         */
132        public Location getActualLocationBefore() {
133            return actualOldLocation;
134        }
135    
136        /**
137         * Get the actual location of the node after being renamed.
138         * 
139         * @return the actual location of the node after being renamed, or null if the actual location was not set
140         */
141        public Location getActualLocationAfter() {
142            return actualNewLocation;
143        }
144    
145        /**
146         * {@inheritDoc}
147         * 
148         * @see java.lang.Object#equals(java.lang.Object)
149         */
150        @Override
151        public boolean equals( Object obj ) {
152            if (this.getClass().isInstance(obj)) {
153                RenameNodeRequest that = (RenameNodeRequest)obj;
154                if (!this.at().equals(that.at())) return false;
155                if (!this.toName().equals(that.toName())) return false;
156                return true;
157            }
158            return false;
159        }
160    
161        /**
162         * {@inheritDoc}
163         * 
164         * @see java.lang.Object#toString()
165         */
166        @Override
167        public String toString() {
168            return "rename node at " + at() + " to " + toName();
169        }
170    
171    }