1 /** 2 * Copyright 2005-2013 The Kuali Foundation 3 * 4 * Licensed under the Educational Community License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.opensource.org/licenses/ecl2.php 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package org.kuali.rice.krad.document; 17 18 import org.kuali.rice.kew.api.action.ActionType; 19 import org.kuali.rice.kew.framework.postprocessor.ActionTakenEvent; 20 import org.kuali.rice.kew.framework.postprocessor.DocumentRouteLevelChange; 21 import org.kuali.rice.kew.framework.postprocessor.DocumentRouteStatusChange; 22 import org.kuali.rice.kim.api.identity.Person; 23 import org.kuali.rice.krad.bo.AdHocRoutePerson; 24 import org.kuali.rice.krad.bo.AdHocRouteWorkgroup; 25 import org.kuali.rice.krad.bo.DocumentHeader; 26 import org.kuali.rice.krad.bo.Note; 27 import org.kuali.rice.krad.bo.PersistableBusinessObject; 28 import org.kuali.rice.krad.document.authorization.PessimisticLock; 29 import org.kuali.rice.krad.rules.rule.event.KualiDocumentEvent; 30 import org.kuali.rice.krad.util.NoteType; 31 import org.kuali.rice.krad.util.documentserializer.PropertySerializabilityEvaluator; 32 33 import java.util.List; 34 35 36 /** 37 * This is the Document interface. All entities that are regarded as "eDocs" in the system, including Maintenance documents and 38 * Transaction Processing documents should implement this interface as it defines methods that are necessary to interact with the 39 * underlying frameworks and components (i.e. notes, attachments, workflow, etc). 40 * 41 * @author Kuali Rice Team (rice.collab@kuali.org) 42 */ 43 public interface Document extends PersistableBusinessObject { 44 45 /** 46 * This retrieves the standard {@code DocumentHeader} object, which contains standard meta-data about a document. 47 * 48 * @return document header since all docs will have a document header 49 */ 50 DocumentHeader getDocumentHeader(); 51 52 /** 53 * Sets the associated {@code DocumentHeader} for this document. 54 * 55 * @param documentHeader 56 */ 57 void setDocumentHeader(DocumentHeader documentHeader); 58 59 /** 60 * All documents have a document header id. This is the quick accessor to that unique identifier and should return the same 61 * value as documentHeader.getDocumentHeaderId(). 62 * 63 * @return doc header id 64 */ 65 String getDocumentNumber(); 66 67 /** 68 * setter for document header id 69 * 70 * @param documentHeaderId 71 */ 72 void setDocumentNumber(String documentHeaderId); 73 74 /** 75 * This is the method to integrate with workflow, where we will actually populate the workflow defined data structure(s) so that 76 * workflow can routed based on this data. This method is responsible for passing over the proper Kuali (client system) data 77 * that will be used by workflow to determine how the document is actually routed. 78 */ 79 void populateDocumentForRouting(); 80 81 /** 82 * This is a method where we can get the xml of a document that the workflow system will use to base it's routing and search 83 * attributes on. 84 * 85 * @return the document serialized to an xml string 86 */ 87 String serializeDocumentToXml(); 88 89 /** 90 * This method is used to get the xml that should be used in a Route Report. In it's default implementation this will call the 91 * methods prepareForSave() and populateDocumentForRouting(). 92 */ 93 String getXmlForRouteReport(); 94 95 /** 96 * method to integrate with workflow, where we will actually handle the transitions of levels for documents 97 */ 98 void doRouteLevelChange(DocumentRouteLevelChange levelChangeEvent); 99 100 /** 101 * method to integrate with workflow where we will be able to perform logic for an action taken being performed on a document 102 */ 103 void doActionTaken(ActionTakenEvent event); 104 105 /** 106 * method to integrate with workflow where we will be able to perform logic after an action taken being performed on a document 107 * @since 2.1 108 */ 109 public void afterActionTaken(ActionType performed, ActionTakenEvent event); 110 111 /** 112 * This method will be called after the Workflow engine has completely finished processing a document. 113 * 114 * @param successfullyProcessed - true if the document was processed successfully, false otherwise 115 */ 116 void afterWorkflowEngineProcess(boolean successfullyProcessed); 117 118 /** 119 * This method will be called before the Workflow engine has begun processing a document. 120 */ 121 void beforeWorkflowEngineProcess(); 122 123 /** 124 * This method will be called before the Workflow engine has begun processing a document. 125 */ 126 List<String> getWorkflowEngineDocumentIdsToLock(); 127 128 /** 129 * Getter method to get the document title as it will appear in and be searchable in workflow. 130 */ 131 String getDocumentTitle(); 132 133 /** 134 * getter method to get the list of ad hoc route persons associated with a document at a point in time, this list is only valid 135 * for a given users version of a document as this state is only persisted in workflow itself when someone takes an action on a 136 * document 137 */ 138 List<AdHocRoutePerson> getAdHocRoutePersons(); 139 140 /** 141 * getter method to get the list of ad hoc route workgroups associated with a document at a point in time, this list is only 142 * valid for a given users version of a document as this state is only persisted in workflow itself when someone takes an action 143 * on a document 144 */ 145 List<AdHocRouteWorkgroup> getAdHocRouteWorkgroups(); 146 147 /** 148 * setter method to set the list of ad hoc route persons associated with a document at a point in time, this list is only valid 149 * for a given users version of a document as this state is only persisted in workflow itself when someone takes an action on a 150 * document 151 * 152 * @param adHocRoutePersons 153 */ 154 void setAdHocRoutePersons(List<AdHocRoutePerson> adHocRoutePersons); 155 156 /** 157 * setter method to set the list of ad hoc route workgroups associated with a document at a point in time, this list is only 158 * valid for a given users version of a document as this state is only persisted in workflow itself when someone takes an action 159 * on a document 160 * 161 * @param adHocRouteWorkgroups 162 */ 163 void setAdHocRouteWorkgroups(List<AdHocRouteWorkgroup> adHocRouteWorkgroups); 164 165 /** 166 * This method provides a hook that will be called before the document is saved. This method is useful for applying document 167 * level data to children. For example, if someone changes data at the document level, and that data needs to be propagated to 168 * child objects or child lists of objects, you can use this method to update the child object or iterate through the list of 169 * child objects and apply the document level data to them. Any document that follows this paradigm will need to make use of 170 * this method to apply all of those changes. 171 */ 172 void prepareForSave(); 173 174 /** 175 * Sends document off to the rules engine to verify business rules. 176 * 177 * @param event - indicates which document event was requested 178 * @throws org.kuali.rice.krad.exception.ValidationException - containing the MessageMap from the validation session. 179 */ 180 void validateBusinessRules(KualiDocumentEvent event); 181 182 /** 183 * Do any work on the document that requires the KualiDocumentEvent before the save. 184 * 185 * @param event - indicates which document event was requested 186 */ 187 void prepareForSave(KualiDocumentEvent event); 188 189 /** 190 * Do any work on the document after the save. 191 * 192 * @param event - indicates which document event was requested 193 */ 194 void postProcessSave(KualiDocumentEvent event); 195 196 /** 197 * This method provides a hook that will be called after a document is retrieved, but before it is returned from the 198 * DocumentService. 199 */ 200 void processAfterRetrieve(); 201 202 /** 203 * This method returns whether or not this document can be copied. 204 * 205 * @return True if it can be copied, false if not. 206 */ 207 boolean getAllowsCopy(); 208 209 /** 210 * Generate any necessary events required during the save event generation 211 * 212 * @return a list of document events that were triggered by the save event 213 */ 214 List<KualiDocumentEvent> generateSaveEvents(); 215 216 /** 217 * Handle the doRouteStatusChange event from the post processor 218 * 219 */ 220 void doRouteStatusChange(DocumentRouteStatusChange statusChangeEvent); 221 222 /** 223 * Returns the note type which should be used for notes associated with this document. 224 * This method should never return null. 225 * 226 * @return the note type supported by this document, this value should never be null 227 */ 228 NoteType getNoteType(); 229 230 /** 231 * Return the target PersistableBusinessObject that notes associated with this document should be attached to. 232 * In general, this method should never return null. However, it is permissible that it will return a 233 * business object which has not been persisted yet (and therefore does not have it's unique object id 234 * established). This is only valid in cases where the note type is {@link NoteType#BUSINESS_OBJECT}. 235 * 236 * In these cases it's the responsibility for implementers of the Document interface to handle storing transient 237 * copies of the document notes (in XML or otherwise) until the underlying note target has been persisted and can be attached 238 * to the document's notes via it's object id. 239 * 240 * @return the PersistableBusinessObject with which notes on this document should be associated 241 */ 242 PersistableBusinessObject getNoteTarget(); 243 244 /** 245 * Adds the given Note to the document's list of Notes. 246 * 247 * @param note the Note to add, must be non-null 248 */ 249 void addNote(Note note); 250 251 /** 252 * Returns a mutable list of all notes on the document. 253 * 254 * @return the list of notes associated with this document, if this document has no notes then an empty list will be returned 255 */ 256 List<Note> getNotes(); 257 258 /** 259 * Sets the document's list of notes to the given list. 260 * 261 * @param notes the list of notes to set on the document, must be non-null 262 */ 263 void setNotes(List<Note> notes); 264 265 /** 266 * Retrieves the note at the given index. 267 * 268 * @param index the zero-based index of the note to retrieve 269 * @return the note located at the given index 270 * @throws IndexOutOfBoundsException if the index is out of range 271 */ 272 Note getNote(int index); 273 274 /** 275 * Removes the given note from the document's list of notes. 276 * 277 * @param note the note to remove from the document's list of notes, must be non-null 278 * @return true if the note was successfully removed, false if the list did not contain the given note 279 */ 280 boolean removeNote(Note note); 281 282 /** 283 * This method gets a list of the {@link PessimisticLock} objects associated with this document 284 * 285 */ 286 List<PessimisticLock> getPessimisticLocks(); 287 288 /** 289 * This method updates the list of {@link PessimisticLock} objects on the document if changes could 290 * have been made 291 */ 292 void refreshPessimisticLocks(); 293 294 /** 295 * This method adds a new {@link PessimisticLock} to the document 296 * 297 * NOTE: LOCKS ADDED VIA THIS METHOD WILL NOT BE SAVED WITH THE DOCUMENT 298 * 299 * @param lock - the lock to add to the document 300 */ 301 void addPessimisticLock(PessimisticLock lock); 302 303 /** 304 * This is a method that is used by Kuali Pessimistic Locking to get the names (method to call values) 305 * of the {@link KualiDocumentActionBase} methods that should release locks 306 * 307 * @return the list of method names of an action that should clear locks for the current user 308 */ 309 List<String> getLockClearningMethodNames(); 310 /** 311 * Returns an evaluator object that determines whether a given property relative to the root object ({@link #wrapDocumentWithMetadataForXmlSerialization()} 312 * is serializable during the document serialization process. 313 * 314 * @return a fully initialized evaluator object, ready to be used for workflow routing 315 * 316 * @see org.kuali.rice.krad.service.DocumentSerializerService 317 * @see #wrapDocumentWithMetadataForXmlSerialization() 318 */ 319 320 String getBasePathToDocumentDuringSerialization(); 321 322 /** 323 * Returns an evaluator object that determines whether a given property relative to the root object ({@link #wrapDocumentWithMetadataForXmlSerialization()} 324 * is serializable during the document serialization process. 325 * 326 * @return a fully initialized evaluator object, ready to be used for workflow routing 327 * 328 * @see org.kuali.rice.krad.service.DocumentSerializerService 329 * @see #wrapDocumentWithMetadataForXmlSerialization() 330 */ 331 PropertySerializabilityEvaluator getDocumentPropertySerizabilityEvaluator(); 332 333 /** 334 * This method will return the root object to be serialized for workflow routing. If necessary, this method will wrap this document object with a wrapper (i.e. contains a reference back to this document). This 335 * wrapper may also contain references to additional objects that provide metadata useful to the workflow engine. 336 * 337 * If no wrappers are necessary, then this object may return "this" 338 * 339 * @return a wrapper object (most likely containing a reference to "this"), or "this" itself. 340 * @see org.kuali.rice.krad.workflow.KualiDocumentXmlMaterializer 341 */ 342 Object wrapDocumentWithMetadataForXmlSerialization(); 343 344 /** 345 * This method returns whether or not this document supports custom lock descriptors for pessimistic locking. 346 * 347 * @return True if the document can generate custom lock descriptors, false otherwise. 348 * @see #getCustomLockDescriptor(Person) 349 */ 350 boolean useCustomLockDescriptors(); 351 352 /** 353 * Generates a custom lock descriptor for pessimistic locking. This method should not be called unless {@link #useCustomLockDescriptors()} returns true. 354 * 355 * @param user The user trying to establish the lock. 356 * @return A String representing the lock descriptor. 357 * @see #useCustomLockDescriptors() 358 * @see org.kuali.rice.krad.service.PessimisticLockService 359 */ 360 String getCustomLockDescriptor(Person user); 361 }