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 * Unless otherwise indicated, all code in JBoss DNA is licensed
010 * 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.Location;
029 import org.jboss.dna.graph.property.Path;
030 import org.jboss.dna.graph.request.CreateWorkspaceRequest.CreateConflictBehavior;
031
032 /**
033 * Request that an existing workspace be cloned into a target workspace with the supplied name. If the target workspace exists,
034 * the {@link #targetConflictBehavior() target conflict behavior} defines the behavior to be followed. If the workspace being
035 * cloned does not exist, the {@link #cloneConflictBehavior() clone conflict behavior} defines the behavior to be followed.
036 */
037 public final class CloneWorkspaceRequest extends ChangeRequest {
038
039 private static final long serialVersionUID = 1L;
040
041 /**
042 * The options for the behavior when a request specifies the name of the workspace to clone, but the cloned workspace does not
043 * exist.
044 */
045 public enum CloneConflictBehavior {
046 /** Do not perform the clone, and record as an {@link Request#setError(Throwable) error} on the request. */
047 DO_NOT_CLONE,
048
049 /** The clone operation is skipped quietly, resulting in an empty new workspace. */
050 SKIP_CLONE,
051 }
052
053 /**
054 * The default {@link CloneConflictBehavior} that will be used if it is unspecified.
055 */
056 public static final CloneConflictBehavior DEFAULT_CLONE_CONFLICT_BEHAVIOR = CloneConflictBehavior.DO_NOT_CLONE;
057
058 /**
059 * The default {@link CreateConflictBehavior} that will be used if it is unspecified.
060 */
061 public static final CreateConflictBehavior DEFAULT_CREATE_CONFLICT_BEHAVIOR = CreateConflictBehavior.DO_NOT_CREATE;
062
063 private final String nameOfWorkspaceToBeCloned;
064 private final String desiredNameOfTargetWorkspace;
065 private final CreateConflictBehavior createConflictBehavior;
066 private final CloneConflictBehavior cloneConflictBehavior;
067 private String actualWorkspaceName;
068 private Location actualLocationOfRoot;
069
070 /**
071 * Create a request to clone an existing workspace to create a new workspace, and specify the behavior should a workspace
072 * already exists with a name that matches the desired name for the new workspace.
073 *
074 * @param nameOfWorkspaceToBeCloned the name of the existing workspace that is to be cloned
075 * @param desiredNameOfTargetWorkspace the desired name of the target workspace
076 * @param createConflictBehavior the behavior if a workspace already exists with the same name
077 * @param cloneConflictBehavior the behavior if the workspace to be cloned does not exist
078 * @throws IllegalArgumentException if the either workspace name is null
079 */
080 public CloneWorkspaceRequest( String nameOfWorkspaceToBeCloned,
081 String desiredNameOfTargetWorkspace,
082 CreateConflictBehavior createConflictBehavior,
083 CloneConflictBehavior cloneConflictBehavior ) {
084 CheckArg.isNotNull(nameOfWorkspaceToBeCloned, "nameOfWorkspaceToBeCloned");
085 CheckArg.isNotNull(desiredNameOfTargetWorkspace, "desiredNameOfTargetWorkspace");
086 this.nameOfWorkspaceToBeCloned = nameOfWorkspaceToBeCloned;
087 this.desiredNameOfTargetWorkspace = desiredNameOfTargetWorkspace;
088 this.createConflictBehavior = createConflictBehavior != null ? createConflictBehavior : DEFAULT_CREATE_CONFLICT_BEHAVIOR;
089 this.cloneConflictBehavior = cloneConflictBehavior != null ? cloneConflictBehavior : DEFAULT_CLONE_CONFLICT_BEHAVIOR;
090 }
091
092 /**
093 * Get the name of the existing workspace that is to be cloned into the new workspace.
094 *
095 * @return the name of the existing workspace that is to be cloned; never null
096 */
097 public String nameOfWorkspaceToBeCloned() {
098 return nameOfWorkspaceToBeCloned;
099 }
100
101 /**
102 * Get the desired name for the target workspace.
103 *
104 * @return the desired name for the new workspace; never null
105 */
106 public String desiredNameOfTargetWorkspace() {
107 return desiredNameOfTargetWorkspace;
108 }
109
110 /**
111 * Get the desired behavior if a workspace already exists with the {@link #desiredNameOfTargetWorkspace() desired workspace
112 * name} .
113 *
114 * @return the desired behavior; never null
115 */
116 public CreateConflictBehavior targetConflictBehavior() {
117 return createConflictBehavior;
118 }
119
120 /**
121 * Get the desired behavior if the {@link #nameOfWorkspaceToBeCloned() cloned workspace} does not exist.
122 *
123 * @return the desired behavior; never null
124 */
125 public CloneConflictBehavior cloneConflictBehavior() {
126 return cloneConflictBehavior;
127 }
128
129 /**
130 * Get the actual name of the workspace that was created. This will be the same as the {@link #desiredNameOfTargetWorkspace()
131 * desired target name} unless there was a conflict and the {@link #targetConflictBehavior() desired behavior} was to
132 * {@link CreateConflictBehavior#CREATE_WITH_ADJUSTED_NAME alter the name}.
133 *
134 * @return the actual name of the workspace that was created, or null if a workspace was not created (yet)
135 */
136 public String getActualWorkspaceName() {
137 return actualWorkspaceName;
138 }
139
140 /**
141 * Set the actual name of the workspace that was created. This should be the same as the
142 * {@link #desiredNameOfTargetWorkspace() desired target name} unless there was a conflict and the
143 * {@link #targetConflictBehavior() desired behavior} was to {@link CreateConflictBehavior#CREATE_WITH_ADJUSTED_NAME alter the
144 * name}.
145 *
146 * @param actualWorkspaceName the actual name of the workspace that was created, or null if a workspace was not created
147 * @throws IllegalStateException if the request is frozen
148 */
149 public void setActualWorkspaceName( String actualWorkspaceName ) {
150 checkNotFrozen();
151 this.actualWorkspaceName = actualWorkspaceName;
152 }
153
154 /**
155 * Get the actual location of the root node in the new workspace, or null if the workspace was not (yet) created.
156 *
157 * @return the actual location of the root node in the new workspace, or null if the workspace was not (yet) created
158 */
159 public Location getActualLocationOfRoot() {
160 return actualLocationOfRoot;
161 }
162
163 /**
164 * Set the actual location of the root node in the new workspace.
165 *
166 * @param actualLocationOfRoot the actual location of the workspace's root node.
167 * @throws IllegalStateException if the request is frozen
168 */
169 public void setActualRootLocation( Location actualLocationOfRoot ) {
170 checkNotFrozen();
171 this.actualLocationOfRoot = actualLocationOfRoot;
172 }
173
174 /**
175 * {@inheritDoc}
176 *
177 * @see org.jboss.dna.graph.request.Request#isReadOnly()
178 */
179 @Override
180 public boolean isReadOnly() {
181 return false;
182 }
183
184 /**
185 * {@inheritDoc}
186 *
187 * @see org.jboss.dna.graph.request.Request#cancel()
188 */
189 @Override
190 public void cancel() {
191 super.cancel();
192 this.actualLocationOfRoot = null;
193 this.actualWorkspaceName = null;
194 }
195
196 /**
197 * {@inheritDoc}
198 *
199 * @see java.lang.Object#hashCode()
200 */
201 @Override
202 public int hashCode() {
203 return HashCode.compute(nameOfWorkspaceToBeCloned, desiredNameOfTargetWorkspace);
204 }
205
206 /**
207 * {@inheritDoc}
208 *
209 * @see java.lang.Object#equals(java.lang.Object)
210 */
211 @Override
212 public boolean equals( Object obj ) {
213 if (obj == this) return true;
214 if (this.getClass().isInstance(obj)) {
215 CloneWorkspaceRequest that = (CloneWorkspaceRequest)obj;
216 if (!this.nameOfWorkspaceToBeCloned.equals(that.nameOfWorkspaceToBeCloned())) return false;
217 if (!this.desiredNameOfTargetWorkspace.equals(that.desiredNameOfTargetWorkspace())) return false;
218 return true;
219 }
220 return false;
221 }
222
223 /**
224 * {@inheritDoc}
225 *
226 * @see java.lang.Object#toString()
227 */
228 @Override
229 public String toString() {
230 return "clone workspace \"" + nameOfWorkspaceToBeCloned() + "\" as workspace \"" + desiredNameOfTargetWorkspace() + "\"";
231 }
232
233 /**
234 * {@inheritDoc}
235 *
236 * @see org.jboss.dna.graph.request.ChangeRequest#changedLocation()
237 */
238 @Override
239 public Location changedLocation() {
240 return actualLocationOfRoot;
241 }
242
243 /**
244 * {@inheritDoc}
245 *
246 * @see org.jboss.dna.graph.request.ChangeRequest#changedWorkspace()
247 */
248 @Override
249 public String changedWorkspace() {
250 return actualWorkspaceName;
251 }
252
253 /**
254 * {@inheritDoc}
255 *
256 * @see org.jboss.dna.graph.request.ChangeRequest#changes(java.lang.String, org.jboss.dna.graph.property.Path)
257 */
258 @Override
259 public boolean changes( String workspace,
260 Path path ) {
261 return actualWorkspaceName != null && actualWorkspaceName.equals(workspace);
262 }
263 }