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.NodeConflictBehavior;
028
029 /**
030 * Instruction that a branch be moved from one location into another.
031 *
032 * @author Randall Hauch
033 */
034 public class MoveBranchRequest extends Request {
035
036 private static final long serialVersionUID = 1L;
037
038 public static final NodeConflictBehavior DEFAULT_CONFLICT_BEHAVIOR = NodeConflictBehavior.APPEND;
039
040 private final Location from;
041 private final Location into;
042 private final NodeConflictBehavior conflictBehavior;
043 private Location actualOldLocation;
044 private Location actualNewLocation;
045
046 /**
047 * Create a request to move a branch from one location into another.
048 *
049 * @param from the location of the top node in the existing branch that is to be moved
050 * @param into the location of the existing node into which the branch should be moved
051 * @throws IllegalArgumentException if <code>from</code> or <code>into</code> are null
052 */
053 public MoveBranchRequest( Location from,
054 Location into ) {
055 this(from, into, DEFAULT_CONFLICT_BEHAVIOR);
056 }
057
058 /**
059 * Create a request to move a branch from one location into another.
060 *
061 * @param from the location of the top node in the existing branch that is to be moved
062 * @param into the location of the existing node into which the branch should be moved
063 * @param conflictBehavior the expected behavior if an equivalently-named child already exists at the <code>into</code>
064 * location
065 * @throws IllegalArgumentException if any of the parameters are null
066 */
067 public MoveBranchRequest( Location from,
068 Location into,
069 NodeConflictBehavior conflictBehavior ) {
070 CheckArg.isNotNull(from, "from");
071 CheckArg.isNotNull(into, "into");
072 CheckArg.isNotNull(conflictBehavior, "conflictBehavior");
073 this.from = from;
074 this.into = into;
075 this.conflictBehavior = conflictBehavior;
076 }
077
078 /**
079 * Get the location defining the top of the branch to be moved
080 *
081 * @return the from location; never null
082 */
083 public Location from() {
084 return from;
085 }
086
087 /**
088 * Get the location defining the parent where the branch is to be placed
089 *
090 * @return the to location; never null
091 */
092 public Location into() {
093 return into;
094 }
095
096 /**
097 * Get the expected behavior when copying the branch and the {@link #into() destination} already has a node with the same
098 * name.
099 *
100 * @return the behavior specification
101 */
102 public NodeConflictBehavior conflictBehavior() {
103 return conflictBehavior;
104 }
105
106 /**
107 * {@inheritDoc}
108 *
109 * @see org.jboss.dna.graph.requests.Request#isReadOnly()
110 */
111 @Override
112 public boolean isReadOnly() {
113 return false;
114 }
115
116 /**
117 * Sets the actual and complete location of the node being renamed and its new location. This method must be called when
118 * processing the request, and the actual location must have a {@link Location#getPath() path}.
119 *
120 * @param oldLocation the actual location of the node before being renamed
121 * @param newLocation the actual location of the node after being renamed
122 * @throws IllegalArgumentException if the either location is null, if the old location does not represent the
123 * {@link Location#isSame(Location) same location} as the {@link #from() from location}, if the new location does not
124 * represent the {@link Location#isSame(Location) same location} as the {@link #into() into location}, or if the
125 * either location does not have a path
126 */
127 public void setActualLocations( Location oldLocation,
128 Location newLocation ) {
129 if (!from.isSame(oldLocation)) { // not same if actual is null
130 throw new IllegalArgumentException(GraphI18n.actualLocationIsNotSameAsInputLocation.text(oldLocation, from));
131 }
132 if (!into.isSame(newLocation, false)) { // not same if actual is null
133 throw new IllegalArgumentException(GraphI18n.actualLocationIsNotSameAsInputLocation.text(newLocation, into));
134 }
135 assert oldLocation != null;
136 assert newLocation != null;
137 if (!oldLocation.hasPath()) {
138 throw new IllegalArgumentException(GraphI18n.actualOldLocationMustHavePath.text(oldLocation));
139 }
140 if (!newLocation.hasPath()) {
141 throw new IllegalArgumentException(GraphI18n.actualNewLocationMustHavePath.text(newLocation));
142 }
143 this.actualNewLocation = newLocation;
144 }
145
146 /**
147 * Get the actual location of the node before being moved.
148 *
149 * @return the actual location of the node before being moved, or null if the actual location was not set
150 */
151 public Location getActualLocationBefore() {
152 return actualOldLocation;
153 }
154
155 /**
156 * Get the actual location of the node after being moved.
157 *
158 * @return the actual location of the node after being moved, or null if the actual location was not set
159 */
160 public Location getActualLocationAfter() {
161 return actualNewLocation;
162 }
163
164 /**
165 * {@inheritDoc}
166 *
167 * @see java.lang.Object#equals(java.lang.Object)
168 */
169 @Override
170 public boolean equals( Object obj ) {
171 if (this.getClass().isInstance(obj)) {
172 MoveBranchRequest that = (MoveBranchRequest)obj;
173 if (!this.from().equals(that.from())) return false;
174 if (!this.into().equals(that.into())) return false;
175 if (!this.conflictBehavior().equals(that.conflictBehavior())) return false;
176 return true;
177 }
178 return false;
179 }
180
181 /**
182 * {@inheritDoc}
183 *
184 * @see java.lang.Object#toString()
185 */
186 @Override
187 public String toString() {
188 return "move branch " + from() + " into " + into();
189 }
190 }