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 }