001 /* 002 * Copyright 2008-2015 UnboundID Corp. 003 * All Rights Reserved. 004 */ 005 /* 006 * Copyright (C) 2015 UnboundID Corp. 007 * 008 * This program is free software; you can redistribute it and/or modify 009 * it under the terms of the GNU General Public License (GPLv2 only) 010 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only) 011 * as published by the Free Software Foundation. 012 * 013 * This program is distributed in the hope that it will be useful, 014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 016 * GNU General Public License for more details. 017 * 018 * You should have received a copy of the GNU General Public License 019 * along with this program; if not, see <http://www.gnu.org/licenses>. 020 */ 021 package com.unboundid.ldap.sdk.unboundidds.tasks; 022 023 024 025 import java.util.ArrayList; 026 import java.util.Arrays; 027 import java.util.Collections; 028 import java.util.Date; 029 import java.util.LinkedHashMap; 030 import java.util.List; 031 import java.util.Map; 032 033 import com.unboundid.ldap.sdk.Attribute; 034 import com.unboundid.ldap.sdk.Entry; 035 import com.unboundid.util.NotMutable; 036 import com.unboundid.util.ThreadSafety; 037 import com.unboundid.util.ThreadSafetyLevel; 038 039 import static com.unboundid.ldap.sdk.unboundidds.tasks.TaskMessages.*; 040 import static com.unboundid.util.Validator.*; 041 042 043 044 /** 045 * <BLOCKQUOTE> 046 * <B>NOTE:</B> This class is part of the Commercial Edition of the UnboundID 047 * LDAP SDK for Java. It is not available for use in applications that 048 * include only the Standard Edition of the LDAP SDK, and is not supported for 049 * use in conjunction with non-UnboundID products. 050 * </BLOCKQUOTE> 051 * This class defines a Directory Server task that can be used to invoke a task 052 * written as a Groovy script using the UnboundID Server SDK. The properties 053 * that are available for use with this type of task include: 054 * <UL> 055 * <LI>The fully-qualified name of the Groovy class providing the logic for 056 * the scripted task. This must be provided.</LI> 057 * <LI>A list of the arguments to use for the task.</LI> 058 * </UL> 059 */ 060 @NotMutable() 061 @ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 062 public final class GroovyScriptedTask 063 extends Task 064 { 065 /** 066 * The fully-qualified name of the Java class that is used for the core 067 * Groovy-scripted task. 068 */ 069 static final String GROOVY_SCRIPTED_TASK_CLASS = 070 "com.unboundid.directory.sdk.extensions.GroovyScriptedTask"; 071 072 073 074 /** 075 * The name of the attribute used to specify the fully-qualified name of the 076 * Groovy class providing the logic for the scripted task. 077 */ 078 private static final String ATTR_GROOVY_SCRIPTED_TASK_CLASS = 079 "ds-scripted-task-class"; 080 081 082 083 /** 084 * The name of the attribute used to provide arguments to the script. 085 */ 086 private static final String ATTR_GROOVY_SCRIPTED_TASK_ARGUMENT = 087 "ds-scripted-task-argument"; 088 089 090 091 /** 092 * The name of the object class used in Groovy-scripted task entries. 093 */ 094 private static final String OC_GROOVY_SCRIPTED_TASK = 095 "ds-groovy-scripted-task"; 096 097 098 099 /** 100 * The task property that will be used for the task class. 101 */ 102 static final TaskProperty PROPERTY_TASK_CLASS = 103 new TaskProperty(ATTR_GROOVY_SCRIPTED_TASK_CLASS, 104 INFO_DISPLAY_NAME_GROOVY_SCRIPTED_TASK_CLASS.get(), 105 INFO_DESCRIPTION_GROOVY_SCRIPTED_TASK_CLASS.get(), String.class, true, 106 false, false); 107 108 109 110 /** 111 * The task property that will be used for the task arguments. 112 */ 113 static final TaskProperty PROPERTY_TASK_ARG = 114 new TaskProperty(ATTR_GROOVY_SCRIPTED_TASK_ARGUMENT, 115 INFO_DISPLAY_NAME_GROOVY_SCRIPTED_TASK_ARG.get(), 116 INFO_DESCRIPTION_GROOVY_SCRIPTED_TASK_ARG.get(), String.class, false, 117 true, false); 118 119 120 121 /** 122 * The serial version UID for this serializable class. 123 */ 124 private static final long serialVersionUID = -1354970323227263273L; 125 126 127 128 // A list of the arguments for the task. 129 private final List<String> taskArguments; 130 131 // The name of the Groovy class providing the logic for the scripted task. 132 private final String taskClassName; 133 134 135 136 /** 137 * Creates a new uninitialized Groovy-scripted task instance which should only 138 * be used for obtaining general information about this task, including the 139 * task name, description, and supported properties. Attempts to use a task 140 * created with this constructor for any other reason will likely fail. 141 */ 142 public GroovyScriptedTask() 143 { 144 taskArguments = null; 145 taskClassName = null; 146 } 147 148 149 150 151 /** 152 * Creates a new Groovy-scripted task with the provided information. 153 * 154 * @param taskID The task ID to use for this task. If it is 155 * {@code null} then a UUID will be generated for use 156 * as the task ID. 157 * @param taskClassName The fully-qualified name of the Groovy class 158 * providing the logic for the task. It must not be 159 * {@code null}. 160 * @param taskArguments A list of the arguments for the task, in the form 161 * name=value. It may be {@code null} or empty if 162 * there should not be any arguments. 163 */ 164 public GroovyScriptedTask(final String taskID, final String taskClassName, 165 final List<String> taskArguments) 166 { 167 this(taskID, taskClassName, taskArguments, null, null, null, null, null); 168 } 169 170 171 172 /** 173 * Creates a new Groovy-scripted task with the provided information. 174 * 175 * @param taskID The task ID to use for this task. If it is 176 * {@code null} then a UUID will be generated 177 * for use as the task ID. 178 * @param taskClassName The fully-qualified name of the Groovy 179 * class providing the logic for the task. It 180 * must not be {@code null}. 181 * @param taskArguments A list of the arguments for the task, in 182 * the form name=value. It may be 183 * {@code null} or empty if there should not 184 * be any arguments. 185 * @param scheduledStartTime The time that this task should start 186 * running. 187 * @param dependencyIDs The list of task IDs that will be required 188 * to complete before this task will be 189 * eligible to start. 190 * @param failedDependencyAction Indicates what action should be taken if 191 * any of the dependencies for this task do 192 * not complete successfully. 193 * @param notifyOnCompletion The list of e-mail addresses of individuals 194 * that should be notified when this task 195 * completes. 196 * @param notifyOnError The list of e-mail addresses of individuals 197 * that should be notified if this task does 198 * not complete successfully. 199 */ 200 public GroovyScriptedTask(final String taskID, final String taskClassName, 201 final List<String> taskArguments, 202 final Date scheduledStartTime, 203 final List<String> dependencyIDs, 204 final FailedDependencyAction failedDependencyAction, 205 final List<String> notifyOnCompletion, 206 final List<String> notifyOnError) 207 { 208 super(taskID, GROOVY_SCRIPTED_TASK_CLASS, scheduledStartTime, 209 dependencyIDs, failedDependencyAction, notifyOnCompletion, 210 notifyOnError); 211 212 ensureNotNull(taskClassName); 213 214 this.taskClassName = taskClassName; 215 216 if (taskArguments == null) 217 { 218 this.taskArguments = Collections.emptyList(); 219 } 220 else 221 { 222 this.taskArguments = Collections.unmodifiableList(taskArguments); 223 } 224 } 225 226 227 228 /** 229 * Creates a new Groovy-scripted task from the provided entry. 230 * 231 * @param entry The entry to use to create this Groovy-scripted task. 232 * 233 * @throws TaskException If the provided entry cannot be parsed as a 234 * Groovy-scripted task entry. 235 */ 236 public GroovyScriptedTask(final Entry entry) 237 throws TaskException 238 { 239 super(entry); 240 241 242 // Get the task class name. It must be present. 243 taskClassName = entry.getAttributeValue(ATTR_GROOVY_SCRIPTED_TASK_CLASS); 244 if (taskClassName == null) 245 { 246 throw new TaskException(ERR_GROOVY_SCRIPTED_TASK_NO_CLASS.get( 247 getTaskEntryDN())); 248 } 249 250 251 // Get the task arguments. It may be absent. 252 final String[] args = 253 entry.getAttributeValues(ATTR_GROOVY_SCRIPTED_TASK_ARGUMENT); 254 if ((args == null) || (args.length == 0)) 255 { 256 taskArguments = Collections.emptyList(); 257 } 258 else 259 { 260 taskArguments = Collections.unmodifiableList(Arrays.asList(args)); 261 } 262 } 263 264 265 266 /** 267 * Creates a new Groovy-scripted task from the provided set of task 268 * properties. 269 * 270 * @param properties The set of task properties and their corresponding 271 * values to use for the task. It must not be 272 * {@code null}. 273 * 274 * @throws TaskException If the provided set of properties cannot be used to 275 * create a valid Groovy-scripted task. 276 */ 277 public GroovyScriptedTask(final Map<TaskProperty,List<Object>> properties) 278 throws TaskException 279 { 280 super(GROOVY_SCRIPTED_TASK_CLASS, properties); 281 282 String className = null; 283 String[] args = null; 284 for (final Map.Entry<TaskProperty,List<Object>> entry : 285 properties.entrySet()) 286 { 287 final TaskProperty p = entry.getKey(); 288 final String attrName = p.getAttributeName(); 289 final List<Object> values = entry.getValue(); 290 291 if (attrName.equalsIgnoreCase(ATTR_GROOVY_SCRIPTED_TASK_CLASS)) 292 { 293 className = parseString(p, values, null); 294 } 295 else if (attrName.equalsIgnoreCase(ATTR_GROOVY_SCRIPTED_TASK_ARGUMENT)) 296 { 297 args = parseStrings(p, values, null); 298 } 299 } 300 301 if (className == null) 302 { 303 throw new TaskException(ERR_GROOVY_SCRIPTED_TASK_NO_CLASS.get( 304 getTaskEntryDN())); 305 } 306 307 taskClassName = className; 308 309 if (args == null) 310 { 311 taskArguments = Collections.emptyList(); 312 } 313 else 314 { 315 taskArguments = Collections.unmodifiableList(Arrays.asList(args)); 316 } 317 } 318 319 320 321 /** 322 * {@inheritDoc} 323 */ 324 @Override() 325 public String getTaskName() 326 { 327 return INFO_TASK_NAME_GROOVY_SCRIPTED_TASK.get(); 328 } 329 330 331 332 /** 333 * {@inheritDoc} 334 */ 335 @Override() 336 public String getTaskDescription() 337 { 338 return INFO_TASK_DESCRIPTION_GROOVY_SCRIPTED_TASK.get(); 339 } 340 341 342 343 /** 344 * Retrieves the fully-qualified name of the Groovy class providing the logic 345 * for the scripted task. 346 * 347 * @return The fully-qualified name of the Groovy class providing the logic 348 * for the scripted task. 349 */ 350 public String getGroovyScriptedTaskClassName() 351 { 352 return taskClassName; 353 } 354 355 356 357 /** 358 * Retrieves a list of the arguments to provide to the Groovy-scripted task. 359 * 360 * @return A list of the arguments to provide to the Groovy-scripted task, or 361 * an empty list if there are no arguments. 362 */ 363 public List<String> getGroovyScriptedTaskArguments() 364 { 365 return taskArguments; 366 } 367 368 369 370 /** 371 * {@inheritDoc} 372 */ 373 @Override() 374 protected List<String> getAdditionalObjectClasses() 375 { 376 return Arrays.asList(OC_GROOVY_SCRIPTED_TASK); 377 } 378 379 380 381 /** 382 * {@inheritDoc} 383 */ 384 @Override() 385 protected List<Attribute> getAdditionalAttributes() 386 { 387 final ArrayList<Attribute> attrList = new ArrayList<Attribute>(2); 388 attrList.add(new Attribute(ATTR_GROOVY_SCRIPTED_TASK_CLASS, taskClassName)); 389 390 if (! taskArguments.isEmpty()) 391 { 392 attrList.add(new Attribute(ATTR_GROOVY_SCRIPTED_TASK_ARGUMENT, 393 taskArguments)); 394 } 395 396 return attrList; 397 } 398 399 400 401 /** 402 * {@inheritDoc} 403 */ 404 @Override() 405 public List<TaskProperty> getTaskSpecificProperties() 406 { 407 return Collections.unmodifiableList(Arrays.asList( 408 PROPERTY_TASK_CLASS, 409 PROPERTY_TASK_ARG)); 410 } 411 412 413 414 /** 415 * {@inheritDoc} 416 */ 417 @Override() 418 public Map<TaskProperty,List<Object>> getTaskPropertyValues() 419 { 420 final LinkedHashMap<TaskProperty,List<Object>> props = 421 new LinkedHashMap<TaskProperty,List<Object>>(2); 422 423 props.put(PROPERTY_TASK_CLASS, 424 Collections.<Object>unmodifiableList(Arrays.asList(taskClassName))); 425 426 props.put(PROPERTY_TASK_ARG, 427 Collections.<Object>unmodifiableList(taskArguments)); 428 429 props.putAll(super.getTaskPropertyValues()); 430 return Collections.unmodifiableMap(props); 431 } 432 }