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
052 * third-party code created using the UnboundID Server SDK. The properties that
053 * are available for use with this type of task include:
054 * <UL>
055 * <LI>The fully-qualified name of the Java class providing the logic for the
056 * third-party 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 ThirdPartyTask
063 extends Task
064 {
065 /**
066 * The fully-qualified name of the Java class that is used for the core
067 * third-party task.
068 */
069 static final String THIRD_PARTY_TASK_CLASS =
070 "com.unboundid.directory.sdk.extensions.ThirdPartyTask";
071
072
073
074 /**
075 * The name of the attribute used to specify the fully-qualified name of the
076 * Java class providing the task logic.
077 */
078 private static final String ATTR_THIRD_PARTY_TASK_CLASS =
079 "ds-third-party-task-java-class";
080
081
082
083 /**
084 * The name of the attribute used to provide arguments for the task.
085 */
086 private static final String ATTR_THIRD_PARTY_TASK_ARGUMENT =
087 "ds-third-party-task-argument";
088
089
090
091 /**
092 * The name of the object class used in third-party task entries.
093 */
094 private static final String OC_THIRD_PARTY_TASK =
095 "ds-third-party-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_THIRD_PARTY_TASK_CLASS,
104 INFO_DISPLAY_NAME_THIRD_PARTY_TASK_CLASS.get(),
105 INFO_DESCRIPTION_THIRD_PARTY_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_THIRD_PARTY_TASK_ARGUMENT,
115 INFO_DISPLAY_NAME_THIRD_PARTY_TASK_ARG.get(),
116 INFO_DESCRIPTION_THIRD_PARTY_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 = 8448474409066265724L;
125
126
127
128 // A list of the arguments for the task.
129 private final List<String> taskArguments;
130
131 // The name of the java class providing the logic for the third-party task.
132 private final String taskClassName;
133
134
135
136 /**
137 * Creates a new uninitialized third-party 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 ThirdPartyTask()
143 {
144 taskArguments = null;
145 taskClassName = null;
146 }
147
148
149
150
151 /**
152 * Creates a new third-party 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 Java class providing
158 * 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 ThirdPartyTask(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 third-party 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 Java class
179 * providing the logic for the task. It must
180 * 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 ThirdPartyTask(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, THIRD_PARTY_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 third-party task from the provided entry.
230 *
231 * @param entry The entry to use to create this third-party task.
232 *
233 * @throws TaskException If the provided entry cannot be parsed as a
234 * third-party task entry.
235 */
236 public ThirdPartyTask(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_THIRD_PARTY_TASK_CLASS);
244 if (taskClassName == null)
245 {
246 throw new TaskException(ERR_THIRD_PARTY_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_THIRD_PARTY_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 third-party task from the provided set of task properties.
268 *
269 * @param properties The set of task properties and their corresponding
270 * values to use for the task. It must not be
271 * {@code null}.
272 *
273 * @throws TaskException If the provided set of properties cannot be used to
274 * create a valid third-party task.
275 */
276 public ThirdPartyTask(final Map<TaskProperty,List<Object>> properties)
277 throws TaskException
278 {
279 super(THIRD_PARTY_TASK_CLASS, properties);
280
281 String className = null;
282 String[] args = null;
283 for (final Map.Entry<TaskProperty,List<Object>> entry :
284 properties.entrySet())
285 {
286 final TaskProperty p = entry.getKey();
287 final String attrName = p.getAttributeName();
288 final List<Object> values = entry.getValue();
289
290 if (attrName.equalsIgnoreCase(ATTR_THIRD_PARTY_TASK_CLASS))
291 {
292 className = parseString(p, values, null);
293 }
294 else if (attrName.equalsIgnoreCase(ATTR_THIRD_PARTY_TASK_ARGUMENT))
295 {
296 args = parseStrings(p, values, null);
297 }
298 }
299
300 if (className == null)
301 {
302 throw new TaskException(ERR_THIRD_PARTY_TASK_NO_CLASS.get(
303 getTaskEntryDN()));
304 }
305
306 taskClassName = className;
307
308 if (args == null)
309 {
310 taskArguments = Collections.emptyList();
311 }
312 else
313 {
314 taskArguments = Collections.unmodifiableList(Arrays.asList(args));
315 }
316 }
317
318
319
320 /**
321 * {@inheritDoc}
322 */
323 @Override()
324 public String getTaskName()
325 {
326 return INFO_TASK_NAME_THIRD_PARTY_TASK.get();
327 }
328
329
330
331 /**
332 * {@inheritDoc}
333 */
334 @Override()
335 public String getTaskDescription()
336 {
337 return INFO_TASK_DESCRIPTION_THIRD_PARTY_TASK.get();
338 }
339
340
341
342 /**
343 * Retrieves the fully-qualified name of the Java class providing the logic
344 * for the third-party task.
345 *
346 * @return The fully-qualified name of the Java class providing the logic
347 * for the third-party task.
348 */
349 public String getThirdPartyTaskClassName()
350 {
351 return taskClassName;
352 }
353
354
355
356 /**
357 * Retrieves a list of the arguments to provide to the third-party task.
358 *
359 * @return A list of the arguments to provide to the third-party task, or
360 * an empty list if there are no arguments.
361 */
362 public List<String> getThirdPartyTaskArguments()
363 {
364 return taskArguments;
365 }
366
367
368
369 /**
370 * {@inheritDoc}
371 */
372 @Override()
373 protected List<String> getAdditionalObjectClasses()
374 {
375 return Arrays.asList(OC_THIRD_PARTY_TASK);
376 }
377
378
379
380 /**
381 * {@inheritDoc}
382 */
383 @Override()
384 protected List<Attribute> getAdditionalAttributes()
385 {
386 final ArrayList<Attribute> attrList = new ArrayList<Attribute>(2);
387 attrList.add(new Attribute(ATTR_THIRD_PARTY_TASK_CLASS, taskClassName));
388
389 if (! taskArguments.isEmpty())
390 {
391 attrList.add(new Attribute(ATTR_THIRD_PARTY_TASK_ARGUMENT,
392 taskArguments));
393 }
394
395 return attrList;
396 }
397
398
399
400 /**
401 * {@inheritDoc}
402 */
403 @Override()
404 public List<TaskProperty> getTaskSpecificProperties()
405 {
406 return Collections.unmodifiableList(Arrays.asList(
407 PROPERTY_TASK_CLASS,
408 PROPERTY_TASK_ARG));
409 }
410
411
412
413 /**
414 * {@inheritDoc}
415 */
416 @Override()
417 public Map<TaskProperty,List<Object>> getTaskPropertyValues()
418 {
419 final LinkedHashMap<TaskProperty,List<Object>> props =
420 new LinkedHashMap<TaskProperty,List<Object>>(2);
421
422 props.put(PROPERTY_TASK_CLASS,
423 Collections.<Object>unmodifiableList(Arrays.asList(taskClassName)));
424
425 props.put(PROPERTY_TASK_ARG,
426 Collections.<Object>unmodifiableList(taskArguments));
427
428 props.putAll(super.getTaskPropertyValues());
429 return Collections.unmodifiableMap(props);
430 }
431 }