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 }