001 /* 002 * CDDL HEADER START 003 * 004 * The contents of this file are subject to the terms of the 005 * Common Development and Distribution License, Version 1.0 only 006 * (the "License"). You may not use this file except in compliance 007 * with the License. 008 * 009 * You can obtain a copy of the license at 010 * trunk/opends/resource/legal-notices/OpenDS.LICENSE 011 * or https://OpenDS.dev.java.net/OpenDS.LICENSE. 012 * See the License for the specific language governing permissions 013 * and limitations under the License. 014 * 015 * When distributing Covered Code, include this CDDL HEADER in each 016 * file and include the License file at 017 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, 018 * add the following below this CDDL HEADER, with the fields enclosed 019 * by brackets "[]" replaced with your own identifying information: 020 * Portions Copyright [yyyy] [name of copyright owner] 021 * 022 * CDDL HEADER END 023 * 024 * 025 * Copyright 2008 Sun Microsystems, Inc. 026 */ 027 package org.opends.server.workflowelement; 028 029 import static org.opends.server.util.Validator.ensureNotNull; 030 import static org.opends.messages.ConfigMessages.*; 031 032 import java.util.List; 033 import java.util.TreeMap; 034 035 import org.opends.messages.Message; 036 import org.opends.server.admin.std.server.WorkflowElementCfg; 037 import org.opends.server.config.ConfigException; 038 import org.opends.server.types.Operation; 039 import org.opends.server.types.CanceledOperationException; 040 041 042 /** 043 * This class defines the super class for all the workflow elements. A workflow 044 * element is a task in a workflow. A workflow element can wrap a physical 045 * repository such as a local backend, a remote LDAP server or a local ldif 046 * file. A workflow element can also be used to route operations. This is the 047 * case for load balancing and distribution. And workflow element can be used 048 * in a virtual environment to transform data (DN and attribute renaming, 049 * attribute value renaming...). 050 * 051 * @param <T> The type of configuration handled by this workflow elelemnt. 052 */ 053 public abstract class WorkflowElement 054 <T extends WorkflowElementCfg> 055 { 056 // Indicates whether the workflow element encapsulates a private local 057 // backend. 058 private boolean isPrivate = false; 059 060 061 // The workflow element identifier. 062 private String workflowElementID = null; 063 064 065 // The set of workflow elements registered with the server. 066 // The workflow element identifier is used as a key in the map. 067 private static TreeMap<String, WorkflowElement> registeredWorkflowElements = 068 new TreeMap<String, WorkflowElement>(); 069 070 071 // A lock to protect access to the registered workflow elements. 072 private static Object registeredWorkflowElementsLock = new Object(); 073 074 075 // The parent of the workflow element (null if the workflow element is 076 // the root of the processing tree). 077 private WorkflowElement<?> parent = null; 078 079 080 /** 081 * Creates a new instance of the workflow element. 082 */ 083 public WorkflowElement() 084 { 085 // There is nothing to do in the constructor. 086 } 087 088 089 /** 090 * Initializes the instance of the workflow element. 091 * 092 * @param workflowElementID the workflow element identifier as defined 093 * in the configuration. 094 */ 095 public void initialize(String workflowElementID) 096 { 097 this.workflowElementID = workflowElementID; 098 } 099 100 101 /** 102 * Set the parent of the current workflow element. 103 * 104 * @param parent the parent of the workflow element 105 */ 106 protected void setParent(WorkflowElement<?> parent) 107 { 108 this.parent = parent; 109 } 110 111 112 /** 113 * Indicates whether the provided configuration is acceptable for 114 * this workflow elelement. 115 * 116 * @param configuration The workflow element configuration for 117 * which to make the determination. 118 * @param unacceptableReasons A list that may be used to hold the 119 * reasons that the provided 120 * configuration is not acceptable. 121 * 122 * @return {@code true} if the provided configuration is acceptable 123 * for this workflow element, or {@code false} if not. 124 */ 125 public boolean isConfigurationAcceptable( 126 WorkflowElementCfg configuration, 127 List<String> unacceptableReasons) 128 { 129 // This default implementation does not perform any special 130 // validation. It should be overridden by workflow element 131 // implementations that wish to perform more detailed validation. 132 return true; 133 } 134 135 136 /** 137 * Performs any finalization that might be required when this 138 * workflow element is unloaded. No action is taken in the default 139 * implementation. 140 */ 141 public void finalizeWorkflowElement() 142 { 143 // No action is required by default. 144 } 145 146 147 /** 148 * Executes the workflow element for an operation. 149 * 150 * @param operation the operation to execute 151 * 152 * @throws CanceledOperationException if this operation should be 153 * cancelled 154 */ 155 public abstract void execute(Operation operation) 156 throws CanceledOperationException; 157 158 159 /** 160 * Indicates whether the workflow element encapsulates a private 161 * local backend. 162 * 163 * @return <code>true</code> if the workflow element encapsulates a private 164 * local backend, <code>false</code> otherwise 165 */ 166 public boolean isPrivate() 167 { 168 return isPrivate; 169 } 170 171 172 /** 173 * Specifies whether the workflow element encapsulates a private local 174 * backend. 175 * 176 * @param isPrivate Indicates whether the workflow element encapsulates a 177 * private local backend. 178 */ 179 protected void setPrivate(boolean isPrivate) 180 { 181 this.isPrivate = isPrivate; 182 } 183 184 185 /** 186 * Provides the workflow element identifier. 187 * 188 * @return the worflow element identifier 189 */ 190 public String getWorkflowElementID() 191 { 192 return workflowElementID; 193 } 194 195 196 /** 197 * Registers the workflow element (this) with the server. 198 * 199 * @throws ConfigException If the workflow element ID for the provided 200 * workflow element conflicts with the workflow 201 * element ID of an existing workflow element. 202 */ 203 public void register() 204 throws ConfigException 205 { 206 ensureNotNull(workflowElementID); 207 208 synchronized (registeredWorkflowElementsLock) 209 { 210 // the workflow element must not be already registered 211 if (registeredWorkflowElements.containsKey(workflowElementID)) 212 { 213 Message message = ERR_CONFIG_WORKFLOW_ELEMENT_ALREADY_REGISTERED.get( 214 workflowElementID); 215 throw new ConfigException(message); 216 } 217 218 TreeMap<String, WorkflowElement> newWorkflowElements = 219 new TreeMap<String, WorkflowElement>(registeredWorkflowElements); 220 newWorkflowElements.put(workflowElementID, this); 221 registeredWorkflowElements = newWorkflowElements; 222 } 223 } 224 225 226 /** 227 * Deregisters the workflow element (this) with the server. 228 */ 229 public void deregister() 230 { 231 ensureNotNull(workflowElementID); 232 233 synchronized (registeredWorkflowElementsLock) 234 { 235 TreeMap<String, WorkflowElement> newWorkflowElements = 236 new TreeMap<String, WorkflowElement>(registeredWorkflowElements); 237 newWorkflowElements.remove(workflowElementID); 238 registeredWorkflowElements = newWorkflowElements; 239 } 240 } 241 242 243 /** 244 * Gets a workflow element that was registered with the server. 245 * 246 * @param workflowElementID the ID of the workflow element to get 247 * @return the requested workflow element 248 */ 249 public static WorkflowElement getWorkflowElement( 250 String workflowElementID) 251 { 252 return registeredWorkflowElements.get(workflowElementID); 253 } 254 255 256 /** 257 * Resets all the registered workflows. 258 */ 259 public static void resetConfig() 260 { 261 synchronized (registeredWorkflowElementsLock) 262 { 263 registeredWorkflowElements = new TreeMap<String, WorkflowElement>(); 264 } 265 } 266 267 } 268