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.commands.executor; 023 024 import org.jboss.dna.graph.ExecutionContext; 025 import org.jboss.dna.graph.commands.CompositeCommand; 026 import org.jboss.dna.graph.commands.CopyBranchCommand; 027 import org.jboss.dna.graph.commands.CopyNodeCommand; 028 import org.jboss.dna.graph.commands.CreateNodeCommand; 029 import org.jboss.dna.graph.commands.DeleteBranchCommand; 030 import org.jboss.dna.graph.commands.GetChildrenCommand; 031 import org.jboss.dna.graph.commands.GetNodeCommand; 032 import org.jboss.dna.graph.commands.GetPropertiesCommand; 033 import org.jboss.dna.graph.commands.GraphCommand; 034 import org.jboss.dna.graph.commands.MoveBranchCommand; 035 import org.jboss.dna.graph.commands.RecordBranchCommand; 036 import org.jboss.dna.graph.commands.SetPropertiesCommand; 037 import org.jboss.dna.graph.connectors.RepositoryConnection; 038 import org.jboss.dna.graph.connectors.RepositorySourceException; 039 import org.jboss.dna.graph.properties.DateTime; 040 041 /** 042 * Abstract implementation of the {@link CommandExecutor} interface that provides implementations for all methods, making this a 043 * useful base class for all {@link CommandExecutor} implementations. Because all methods are implemented, subclasses only need to 044 * override methods that are appropriate or applicable, and all other commands will be processed correctly (even if new command 045 * interfaces are added in later versions). In some cases, as with {@link CompositeCommand} and {@link GetNodeCommand}, these 046 * implementations attempt to process the command. In other cases (e.g., {@link GetPropertiesCommand}, and 047 * {@link DeleteBranchCommand}), the methods do nothing and should be overridden if the command is to be processed. 048 * <p> 049 * The implementation is also designed to be instantated as needed. This may be once per call to 050 * {@link RepositoryConnection#execute(ExecutionContext, GraphCommand...)}, or may be once per transaction. Either way, this class 051 * is designed to allow subclasses to store additional state that may otherwise be expensive or undesirable to obtain repeatedly. 052 * However, this state should be independent of the commands that are processed, meaning that implementations should generally not 053 * change state as a result of processing specific commands. 054 * </p> 055 * 056 * @author Randall Hauch 057 */ 058 public abstract class AbstractCommandExecutor implements CommandExecutor { 059 060 private final ExecutionContext context; 061 private final String sourceName; 062 private final DateTime nowInUtc; 063 064 protected AbstractCommandExecutor( ExecutionContext context, 065 String sourceName ) { 066 this(context, sourceName, null); 067 } 068 069 protected AbstractCommandExecutor( ExecutionContext context, 070 String sourceName, 071 DateTime now ) { 072 assert context != null; 073 assert sourceName != null && sourceName.trim().length() != 0; 074 this.context = context; 075 this.sourceName = sourceName; 076 this.nowInUtc = now != null ? now.toUtcTimeZone() : context.getValueFactories().getDateFactory().createUtc(); 077 } 078 079 /** 080 * Get the environment in which these commands are being executed. 081 * 082 * @return the execution context; never null 083 */ 084 public ExecutionContext getExecutionContext() { 085 return context; 086 } 087 088 /** 089 * Get the name of the repository source. 090 * 091 * @return the source name; never null or empty 092 */ 093 public String getSourceName() { 094 return sourceName; 095 } 096 097 /** 098 * Get the current time associated with this executor. All calls to this method will result in the same time. 099 * 100 * @return the current time expressed in UTC 101 */ 102 public DateTime getCurrentTimeInUtc() { 103 return nowInUtc; 104 } 105 106 /** 107 * {@inheritDoc} 108 * <p> 109 * This implementation examines the instance to see which {@link GraphCommand command interfaces} are implemented by the 110 * command, and delegates to the appropriate methods. 111 * 112 * @see org.jboss.dna.graph.commands.executor.CommandExecutor#execute(org.jboss.dna.graph.commands.GraphCommand) 113 */ 114 public void execute( GraphCommand command ) throws RepositorySourceException { 115 if (command == null) return; 116 if (command instanceof CompositeCommand) { 117 execute((CompositeCommand)command); 118 // A composite command should only contain other commands and should not do anything on its own 119 return; 120 } 121 // The command could implement multiple "get" behaviors 122 if (command instanceof GetNodeCommand) { 123 execute((GetNodeCommand)command); 124 } else if (command instanceof GetPropertiesCommand) { 125 execute((GetPropertiesCommand)command); 126 } else if (command instanceof GetChildrenCommand) { 127 execute((GetChildrenCommand)command); 128 } 129 // The command could record the branch even if deleting or moving ... 130 if (command instanceof RecordBranchCommand) { 131 execute((RecordBranchCommand)command); 132 } 133 // If the command createa a node, it will have properties to set 134 if (command instanceof CreateNodeCommand) { 135 execute((CreateNodeCommand)command); 136 } else if (command instanceof SetPropertiesCommand) { 137 execute((SetPropertiesCommand)command); 138 } 139 // A copy command will either copy a branch or a node, but not both 140 if (command instanceof CopyBranchCommand) { 141 execute((CopyBranchCommand)command); 142 } else if (command instanceof CopyNodeCommand) { 143 execute((CopyNodeCommand)command); 144 } 145 // The command can either delete or move a branch, but a command can't do both (the move does delete) 146 if (command instanceof DeleteBranchCommand) { 147 execute((DeleteBranchCommand)command); 148 } else if (command instanceof MoveBranchCommand) { 149 execute((MoveBranchCommand)command); 150 } 151 } 152 153 /** 154 * {@inheritDoc} 155 * 156 * @see org.jboss.dna.graph.commands.executor.CommandExecutor#execute(org.jboss.dna.graph.commands.CompositeCommand) 157 */ 158 public void execute( CompositeCommand command ) throws RepositorySourceException { 159 assert command != null; 160 for (GraphCommand nestedCommand : command) { 161 execute(nestedCommand); 162 } 163 } 164 165 /** 166 * {@inheritDoc} 167 * <p> 168 * This method implementation simply delegates to both the {@link #execute(GetPropertiesCommand)} and 169 * {@link #execute(GetChildrenCommand)} methods, and should be overridden by subclasses that can process 170 * {@link GetNodeCommand} more efficiently as a single command. 171 * </p> 172 * 173 * @see org.jboss.dna.graph.commands.executor.CommandExecutor#execute(org.jboss.dna.graph.commands.GetNodeCommand) 174 */ 175 public void execute( GetNodeCommand command ) throws RepositorySourceException { 176 execute((GetPropertiesCommand)command); 177 execute((GetChildrenCommand)command); 178 } 179 180 /** 181 * {@inheritDoc} 182 * 183 * @see org.jboss.dna.graph.commands.executor.CommandExecutor#execute(org.jboss.dna.graph.commands.GetPropertiesCommand) 184 */ 185 public void execute( GetPropertiesCommand command ) throws RepositorySourceException { 186 } 187 188 /** 189 * {@inheritDoc} 190 * 191 * @see org.jboss.dna.graph.commands.executor.CommandExecutor#execute(org.jboss.dna.graph.commands.GetChildrenCommand) 192 */ 193 public void execute( GetChildrenCommand command ) throws RepositorySourceException { 194 } 195 196 /** 197 * {@inheritDoc} 198 * 199 * @see org.jboss.dna.graph.commands.executor.CommandExecutor#execute(org.jboss.dna.graph.commands.CreateNodeCommand) 200 */ 201 public void execute( CreateNodeCommand command ) throws RepositorySourceException { 202 } 203 204 /** 205 * {@inheritDoc} 206 * 207 * @see org.jboss.dna.graph.commands.executor.CommandExecutor#execute(org.jboss.dna.graph.commands.SetPropertiesCommand) 208 */ 209 public void execute( SetPropertiesCommand command ) throws RepositorySourceException { 210 } 211 212 /** 213 * {@inheritDoc} 214 * 215 * @see org.jboss.dna.graph.commands.executor.CommandExecutor#execute(org.jboss.dna.graph.commands.CopyNodeCommand) 216 */ 217 public void execute( CopyNodeCommand command ) throws RepositorySourceException { 218 } 219 220 /** 221 * {@inheritDoc} 222 * 223 * @see org.jboss.dna.graph.commands.executor.CommandExecutor#execute(org.jboss.dna.graph.commands.CopyBranchCommand) 224 */ 225 public void execute( CopyBranchCommand command ) throws RepositorySourceException { 226 } 227 228 /** 229 * {@inheritDoc} 230 * 231 * @see org.jboss.dna.graph.commands.executor.CommandExecutor#execute(org.jboss.dna.graph.commands.DeleteBranchCommand) 232 */ 233 public void execute( DeleteBranchCommand command ) throws RepositorySourceException { 234 } 235 236 /** 237 * {@inheritDoc} 238 * 239 * @see org.jboss.dna.graph.commands.executor.CommandExecutor#execute(org.jboss.dna.graph.commands.MoveBranchCommand) 240 */ 241 public void execute( MoveBranchCommand command ) throws RepositorySourceException { 242 } 243 244 /** 245 * {@inheritDoc} 246 * 247 * @see org.jboss.dna.graph.commands.executor.CommandExecutor#execute(org.jboss.dna.graph.commands.RecordBranchCommand) 248 */ 249 public void execute( RecordBranchCommand command ) throws RepositorySourceException { 250 } 251 252 /** 253 * {@inheritDoc} 254 * 255 * @see org.jboss.dna.graph.commands.executor.CommandExecutor#close() 256 */ 257 public void close() { 258 } 259 260 }