Coverage Report - org.kuali.rice.kew.api.WorkflowDocumentFactory
 
Classes in this File Line Coverage Branch Coverage Complexity
WorkflowDocumentFactory
0%
0/68
0%
0/18
6.75
WorkflowDocumentFactory$ProviderHolder
0%
0/5
N/A
6.75
 
 1  
 /**
 2  
  * Copyright 2005-2011 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.kew.api;
 17  
 
 18  
 import org.apache.commons.lang.StringUtils;
 19  
 import org.kuali.rice.core.api.config.ConfigurationException;
 20  
 import org.kuali.rice.core.api.util.ClassLoaderUtils;
 21  
 import org.kuali.rice.kew.api.action.InvalidActionTakenException;
 22  
 import org.kuali.rice.kew.api.doctype.IllegalDocumentTypeException;
 23  
 import org.kuali.rice.kew.api.document.DocumentContentUpdate;
 24  
 import org.kuali.rice.kew.api.document.DocumentUpdate;
 25  
 
 26  
 import java.io.BufferedReader;
 27  
 import java.io.IOException;
 28  
 import java.io.InputStream;
 29  
 import java.io.InputStreamReader;
 30  
 import java.lang.reflect.InvocationTargetException;
 31  
 import java.lang.reflect.Method;
 32  
 
 33  
 /**
 34  
  * TODO ..
 35  
  *
 36  
  */
 37  0
 public final class WorkflowDocumentFactory {
 38  
 
 39  
         private static final String CREATE_METHOD_NAME = "createDocument";
 40  
         private static final String LOAD_METHOD_NAME = "loadDocument";
 41  
         
 42  
         /**
 43  
          * A lazy initialization holder class for the Provider.  Allows for
 44  
          * thread-safe initialization of shared resource.
 45  
          */
 46  0
         private static final class ProviderHolder {
 47  
             static final Object provider;
 48  
             static final Method createMethod;
 49  
             static final Method loadMethod;
 50  
             static {
 51  0
                 provider = loadProvider();
 52  0
                 createMethod = locateCreateMethod(provider);
 53  0
                 loadMethod = locateLoadMethod(provider);
 54  0
             }
 55  
         }
 56  
         
 57  
     /**
 58  
      * TODO 
 59  
      * 
 60  
      * @param principalId TODO
 61  
      * @param documentTypeName TODO
 62  
      * 
 63  
      * @return TODO
 64  
      * 
 65  
      * @throws IllegalArgumentException if principalId is null or blank
 66  
      * @throws IllegalArgumentException if documentTypeName is null or blank
 67  
      * @throws IllegalDocumentTypeException if the document type does not allow for creation of a document,
 68  
      * this can occur when the given document type is used only as a parent and has no route path configured
 69  
      * @throws InvalidActionTakenException if the caller is not allowed to execute this action
 70  
      */
 71  
     public static WorkflowDocument createDocument(String principalId, String documentTypeName) {
 72  0
             return createDocument(principalId, documentTypeName, null, null);
 73  
     }
 74  
     
 75  
     /**
 76  
      * TODO
 77  
      * 
 78  
      * @param principalId TODO
 79  
      * @param documentTypeName TODO
 80  
      * @param title TODO
 81  
      * 
 82  
      * @return TODO
 83  
      * 
 84  
      * @throws IllegalArgumentException if principalId is null or blank
 85  
      * @throws IllegalArgumentException if documentTypeName is null or blank
 86  
      * @throws IllegalDocumentTypeException if documentTypeName does not represent a valid document type
 87  
      */
 88  
     public static WorkflowDocument createDocument(String principalId, String documentTypeName, String title) {
 89  0
             DocumentUpdate.Builder builder = DocumentUpdate.Builder.create();
 90  0
             builder.setTitle(title);
 91  0
             return createDocument(principalId, documentTypeName, builder.build(), null);
 92  
     }
 93  
     
 94  
     /**
 95  
      * TODO
 96  
      * 
 97  
      * @param principalId TODO
 98  
      * @param documentTypeName TODO
 99  
      * @param documentUpdate TODO
 100  
      * @param documentContentUpdate TODO
 101  
      * 
 102  
      * @return TODO
 103  
      * 
 104  
      * @throws IllegalArgumentException if principalId is null or blank
 105  
      * @throws IllegalArgumentException if documentTypeName is null or blank
 106  
      * @throws IllegalDocumentTypeException if documentTypeName does not represent a valid document type
 107  
      */
 108  
         public static WorkflowDocument createDocument(String principalId, String documentTypeName, DocumentUpdate documentUpdate, DocumentContentUpdate documentContentUpdate) {
 109  0
                 if (StringUtils.isBlank(principalId)) {
 110  0
                         throw new IllegalArgumentException("principalId was null or blank");
 111  
                 }
 112  0
                 if (StringUtils.isBlank(documentTypeName)) {
 113  0
                         throw new IllegalArgumentException("documentTypeName was null or blank");
 114  
                 }
 115  
                 
 116  0
                 Object workflowDocument = null;
 117  
                 
 118  
                 try {
 119  0
                         workflowDocument = ProviderHolder.createMethod.invoke(ProviderHolder.provider, principalId, documentTypeName, documentUpdate, documentContentUpdate);
 120  0
                 } catch (IllegalAccessException e) {
 121  0
                         throw new ConfigurationException("Failed to invoke " + CREATE_METHOD_NAME, e);
 122  0
                 } catch (InvocationTargetException e) {
 123  0
                         if (e.getCause() instanceof RuntimeException) {
 124  0
                                 throw (RuntimeException)e.getCause();
 125  
                         }
 126  0
                         throw new ConfigurationException("Failed to invoke " + CREATE_METHOD_NAME, e);
 127  0
                 }
 128  
 
 129  0
                 if (!(workflowDocument instanceof WorkflowDocument)) {
 130  0
                         throw new ConfigurationException("Created document is not a proper instance of " + WorkflowDocument.class + ", was instead " + workflowDocument.getClass());
 131  
                 }
 132  0
                 return (WorkflowDocument)workflowDocument;
 133  
         }
 134  
         
 135  
         public static WorkflowDocument loadDocument(String principalId, String documentId) {
 136  0
                 if (StringUtils.isBlank(principalId)) {
 137  0
                         throw new IllegalArgumentException("principalId was null or blank");
 138  
                 }
 139  0
                 if (StringUtils.isBlank(documentId)) {
 140  0
                         throw new IllegalArgumentException("documentId was null or blank");
 141  
                 }
 142  
                                 
 143  0
                 Object workflowDocument = null;
 144  
                 
 145  
                 try {
 146  0
                         workflowDocument = ProviderHolder.loadMethod.invoke(ProviderHolder.provider, principalId, documentId);
 147  0
                 } catch (IllegalAccessException e) {
 148  0
                         throw new ConfigurationException("Failed to invoke " + LOAD_METHOD_NAME, e);
 149  0
                 } catch (InvocationTargetException e) {
 150  0
                         if (e.getCause() instanceof RuntimeException) {
 151  0
                                 throw (RuntimeException)e.getCause();
 152  
                         }
 153  0
                         throw new ConfigurationException("Failed to invoke " + LOAD_METHOD_NAME, e);
 154  0
                 }
 155  
 
 156  0
                 if (!(workflowDocument instanceof WorkflowDocument)) {
 157  0
                         throw new ConfigurationException("Loaded document is not a proper instance of " + WorkflowDocument.class + ", was instead " + workflowDocument.getClass());
 158  
                 }
 159  0
                 return (WorkflowDocument)workflowDocument;
 160  
         }
 161  
         
 162  
         private static Object loadProvider() {
 163  0
                 String providerClassName = null;
 164  0
                 String resource = null;
 165  
                 try {
 166  0
             resource = new StringBuilder().append("META-INF/services/").append(WorkflowDocument.class.getName()).toString();
 167  0
             final InputStream resourceStream = ClassLoaderUtils.getDefaultClassLoader().getResourceAsStream(resource.toString());
 168  0
             if (resourceStream != null) {
 169  0
                 BufferedReader reader = new BufferedReader(new InputStreamReader(resourceStream, "UTF-8"));
 170  0
                 providerClassName = reader.readLine().trim();
 171  0
                 reader.close();
 172  0
                 Class<?> providerClass = Class.forName(providerClassName);
 173  0
                 return newInstance(providerClass);
 174  
             } else {
 175  0
                 throw new ConfigurationException("Failed to locate a services definition file at " + resource);
 176  
             }
 177  0
         } catch (IOException e) {
 178  0
             throw new ConfigurationException("Failure processing services definition file at " + resource, e);
 179  0
         } catch (ClassNotFoundException e) {
 180  0
                 throw new ConfigurationException("Failed to load provider class: " + providerClassName, e);
 181  
         }
 182  
         }
 183  
         
 184  
         private static Object newInstance(Class<?> providerClass) {
 185  
                 try {
 186  0
                         return providerClass.newInstance();
 187  0
                 } catch (InstantiationException e) {
 188  0
                         throw new ConfigurationException("Failed to instantiate provider class: " + providerClass.getName(), e);
 189  0
                 } catch (IllegalAccessException e) {
 190  0
                         throw new ConfigurationException("Failed to instantiate provider class: " + providerClass.getName(), e);
 191  
                 }
 192  
         }
 193  
         
 194  
         private static Method locateCreateMethod(Object provider) {
 195  
         try {
 196  0
             return provider.getClass().getMethod(CREATE_METHOD_NAME, String.class, String.class, DocumentUpdate.class, DocumentContentUpdate.class);
 197  0
         } catch (NoSuchMethodException e) {
 198  0
             throw new ConfigurationException("Failed to locate valid createDocument method signature on provider class: " + provider.getClass().getName(), e);
 199  0
         } catch (SecurityException e) {
 200  0
             throw new ConfigurationException("Encountered security issue when attempting to access createDocument method on provider class: " + provider.getClass().getName(), e);
 201  
         }
 202  
         }
 203  
         
 204  
         private static Method locateLoadMethod(Object provider) {
 205  
         try {
 206  0
             return provider.getClass().getMethod(LOAD_METHOD_NAME, String.class, String.class);
 207  0
         } catch (NoSuchMethodException e) {
 208  0
             throw new ConfigurationException("Failed to locate valid createDocument method signature on provider class: " + provider.getClass().getName(), e);
 209  0
         } catch (SecurityException e) {
 210  0
             throw new ConfigurationException("Encountered security issue when attempting to access createDocument method on provider class: " + provider.getClass().getName(), e);
 211  
         }
 212  
         }
 213  
 
 214  
 }