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 }