Coverage Report - org.kuali.rice.kew.doctype.service.impl.DocumentTypeServiceImpl
 
Classes in this File Line Coverage Branch Coverage Complexity
DocumentTypeServiceImpl
0%
0/164
0%
0/72
2.441
 
 1  
 /*
 2  
  * Copyright 2005-2007 The Kuali Foundation
 3  
  *
 4  
  *
 5  
  * Licensed under the Educational Community License, Version 2.0 (the "License");
 6  
  * you may not use this file except in compliance with the License.
 7  
  * You may obtain a copy of the License at
 8  
  *
 9  
  * http://www.opensource.org/licenses/ecl2.php
 10  
  *
 11  
  * Unless required by applicable law or agreed to in writing, software
 12  
  * distributed under the License is distributed on an "AS IS" BASIS,
 13  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14  
  * See the License for the specific language governing permissions and
 15  
  * limitations under the License.
 16  
  */
 17  
 package org.kuali.rice.kew.doctype.service.impl;
 18  
 
 19  
 import java.io.InputStream;
 20  
 import java.util.ArrayList;
 21  
 import java.util.Collection;
 22  
 import java.util.Iterator;
 23  
 import java.util.List;
 24  
 
 25  
 import org.apache.commons.collections.CollectionUtils;
 26  
 import org.jdom.Element;
 27  
 import org.kuali.rice.core.api.impex.ExportDataSet;
 28  
 import org.kuali.rice.kew.doctype.bo.DocumentType;
 29  
 import org.kuali.rice.kew.doctype.dao.DocumentTypeDAO;
 30  
 import org.kuali.rice.kew.doctype.service.DocumentTypePermissionService;
 31  
 import org.kuali.rice.kew.doctype.service.DocumentTypeService;
 32  
 import org.kuali.rice.kew.dto.DTOConverter;
 33  
 import org.kuali.rice.kew.dto.DocumentTypeDTO;
 34  
 import org.kuali.rice.kew.exception.WorkflowServiceErrorException;
 35  
 import org.kuali.rice.kew.exception.WorkflowServiceErrorImpl;
 36  
 import org.kuali.rice.kew.rule.bo.RuleAttribute;
 37  
 import org.kuali.rice.kew.service.KEWServiceLocator;
 38  
 import org.kuali.rice.kew.util.KEWConstants;
 39  
 import org.kuali.rice.kew.xml.DocumentTypeXmlParser;
 40  
 import org.kuali.rice.kew.xml.export.DocumentTypeXmlExporter;
 41  
 import org.kuali.rice.kns.util.ObjectUtils;
 42  
 import org.kuali.rice.ksb.api.KsbApiServiceLocator;
 43  
 
 44  
 
 45  
 /**
 46  
  * The standard implementation of the DocumentTypeService.
 47  
  *
 48  
  * @author Kuali Rice Team (rice.collab@kuali.org)
 49  
  */
 50  0
 public class DocumentTypeServiceImpl implements DocumentTypeService {
 51  
 
 52  0
     private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(DocumentTypeServiceImpl.class);
 53  
     protected static final String XML_FILE_PARSE_ERROR = "general.error.parsexml";
 54  
 
 55  
     public static final String DOCUMENT_TYPE_ID_CACHE_GROUP = "DocumentTypeId";
 56  
     public static final String DOCUMENT_TYPE_NAME_CACHE_GROUP = "DocumentTypeName";
 57  
     public static final String DOCUMENT_TYPE_DTO_ID_CACHE_GROUP = "DocumentTypeDTOId";
 58  
     public static final String DOCUMENT_TYPE_DTO_NAME_CACHE_GROUP = "DocumentTypeDTOName";
 59  
 
 60  
     public static final String DOCUMENT_TYPE_ID_CACHE_PREFIX = DOCUMENT_TYPE_ID_CACHE_GROUP + ":";
 61  
     public static final String DOCUMENT_TYPE_NAME_CACHE_PREFIX = DOCUMENT_TYPE_NAME_CACHE_GROUP + ":";
 62  
     public static final String DOCUMENT_TYPE_DTO_ID_CACHE_PREFIX = DOCUMENT_TYPE_DTO_ID_CACHE_GROUP + ":";
 63  
     public static final String DOCUMENT_TYPE_DTO_NAME_CACHE_PREFIX = DOCUMENT_TYPE_DTO_NAME_CACHE_GROUP + ":";
 64  
     public static final String CURRENT_ROOTS_IN_CACHE_KEY = "DocumentType:CurrentRootsInCache";
 65  
 
 66  
 
 67  
     private DocumentTypeDAO documentTypeDAO;
 68  
 
 69  
     public Collection<DocumentType> find(DocumentType documentType, String docTypeParentName, boolean climbHierarchy) {
 70  0
         DocumentType docTypeParent = this.findByName(docTypeParentName);
 71  0
         Collection<DocumentType> documentTypes = getDocumentTypeDAO().find(documentType, docTypeParent, climbHierarchy);
 72  
         //since we're here put them in the cache
 73  0
         for (Object documentType1 : documentTypes)
 74  
         {
 75  0
             insertIntoCache((DocumentType) documentType1);
 76  
         }
 77  0
         return documentTypes;
 78  
     }
 79  
 
 80  
     public DocumentType findById(Long documentTypeId) {
 81  0
             if (documentTypeId == null) {
 82  0
                     return null;
 83  
             }
 84  0
             DocumentType documentType = fetchFromCacheById(documentTypeId);
 85  0
             if (documentType == null) {
 86  0
                     documentType = getDocumentTypeDAO().findById(documentTypeId);
 87  0
                     insertIntoCache(documentType);
 88  
             }
 89  0
         return documentType;
 90  
     }
 91  
 
 92  
     public DocumentType findByDocumentId(String documentId) {
 93  0
             if (documentId == null) {
 94  0
                     return null;
 95  
             }
 96  0
             Long documentTypeId = getDocumentTypeDAO().findDocumentTypeIdByDocumentId(documentId);
 97  0
             return findById(documentTypeId);
 98  
     }
 99  
 
 100  
     public DocumentType findByName(String name) {
 101  0
             return this.findByName(name, true, true);
 102  
     }
 103  
 
 104  
     public DocumentType findByNameCaseInsensitive(String name) {
 105  0
             return this.findByName(name, false,true);
 106  
     }
 107  
 
 108  
     /**
 109  
      * 
 110  
      * This method seaches for a DocumentType by document name.
 111  
      * 
 112  
      * @param name
 113  
      * @param caseSensitive
 114  
      * @deprecated Use findByName(String name, boolean caseSensitive, boolean checkCache)
 115  
      * @return
 116  
      */
 117  
     protected DocumentType findByName(String name, boolean caseSensitive) {
 118  0
             if (name == null) {
 119  0
                     return null;
 120  
             }
 121  0
             DocumentType documentType = fetchFromCacheByName(name);
 122  0
         if (documentType == null) {
 123  0
                 documentType = getDocumentTypeDAO().findByName(name, caseSensitive);
 124  0
                 insertIntoCache(documentType);
 125  
         }
 126  0
             return documentType;
 127  
     }
 128  
 
 129  
     /**
 130  
      * 
 131  
      * This method seaches for a DocumentType by document name.
 132  
      * 
 133  
      * @param name DocumentType name
 134  
      * @param caseSensitive If false, case will be ignored
 135  
      * @param checkCache if false the cache will not be checked.
 136  
      * @return
 137  
      */
 138  
     protected DocumentType findByName(String name, boolean caseSensitive, boolean checkCache) {
 139  0
             if (name == null) {
 140  0
                     return null;
 141  
             }
 142  
             
 143  0
             DocumentType documentType = null;
 144  0
             if(checkCache){
 145  0
                     documentType = fetchFromCacheByName(name);
 146  
             }
 147  0
         if (documentType == null) {
 148  0
                 documentType = getDocumentTypeDAO().findByName(name, caseSensitive);
 149  0
                 insertIntoCache(documentType);
 150  
         }
 151  0
             return documentType;
 152  
     }
 153  
 
 154  
     /**
 155  
      * Fetches the DocumentType from the cache with the given document type name.  If there is no entry in the cache for the given
 156  
      * document type name, null is returned.
 157  
      */
 158  
     protected DocumentType fetchFromCacheByName(String documentTypeName) {
 159  0
             return (DocumentType) KsbApiServiceLocator.getCacheAdministrator().getFromCache(getNameCacheKey(documentTypeName));
 160  
     }
 161  
 
 162  
     /**
 163  
      * Fetches the DocumentType from the cache with the given document type id.  If there is no entry in the cache for the given
 164  
      * document type id, null is returned.
 165  
      */
 166  
     protected DocumentType fetchFromCacheById(Long documentTypeId) {
 167  0
             return (DocumentType) KsbApiServiceLocator.getCacheAdministrator().getFromCache(getIdCacheKey(documentTypeId));
 168  
     }
 169  
 
 170  
     /**
 171  
      * Returns the cache key for the given document type ID.
 172  
      */
 173  
     protected String getIdCacheKey(Long documentTypeId) {
 174  0
             return DOCUMENT_TYPE_ID_CACHE_PREFIX + documentTypeId.toString();
 175  
     }
 176  
 
 177  
     /**
 178  
      * Returns the cache key for the given document type name.
 179  
      */
 180  
     protected String getNameCacheKey(String documentTypeName) {
 181  0
             return DOCUMENT_TYPE_NAME_CACHE_PREFIX + documentTypeName;
 182  
     }
 183  
 
 184  
     /**
 185  
      * Inserts the given DocumentType into the name and id caches.  If the DocumentType is already in the cache,
 186  
      * these entries should  be overwritten.
 187  
      *
 188  
      * <p>If the given DocumentType does not represent the current version of the DocumentType then it
 189  
      * should not be inserted into the name cache.  This is because different versions of DocumentTypes have
 190  
      * different IDs but they all have the same name.  We want only the most recent version of the DocumentType
 191  
      * to be cached by name.
 192  
      */
 193  
     protected void insertIntoCache(DocumentType documentType) {
 194  0
             if (documentType == null) {
 195  0
                     return;
 196  
             }
 197  
             //don't cache by name if this isn't the current version
 198  0
             if (documentType.getCurrentInd().booleanValue()) {
 199  0
                     KsbApiServiceLocator.getCacheAdministrator().putInCache(getNameCacheKey(documentType.getName()), documentType, DOCUMENT_TYPE_NAME_CACHE_GROUP);
 200  
             }
 201  
 
 202  0
             KsbApiServiceLocator.getCacheAdministrator().putInCache(getIdCacheKey(documentType.getDocumentTypeId()), documentType, DOCUMENT_TYPE_ID_CACHE_GROUP);
 203  0
     }
 204  
 
 205  
     /**
 206  
      * Fetches the DocumentType from the cache with the given document type name.  If there is no entry in the cache for the given
 207  
      * document type name, null is returned.
 208  
      */
 209  
     protected DocumentTypeDTO fetchDTOFromCacheByName(String documentTypeName) {
 210  0
             return (DocumentTypeDTO) KsbApiServiceLocator.getCacheAdministrator().getFromCache(getDTONameCacheKey(documentTypeName));
 211  
     }
 212  
 
 213  
     /**
 214  
      * Fetches the DocumentType from the cache with the given document type id.  If there is no entry in the cache for the given
 215  
      * document type id, null is returned.
 216  
      */
 217  
     protected DocumentTypeDTO fetchDTOFromCacheById(Long documentTypeId) {
 218  0
             return (DocumentTypeDTO) KsbApiServiceLocator.getCacheAdministrator().getFromCache(getDTOIdCacheKey(documentTypeId));
 219  
     }
 220  
 
 221  
     /**
 222  
      * Returns the cache key for the given document type ID.
 223  
      */
 224  
     protected String getDTOIdCacheKey(Long documentTypeId) {
 225  0
             return DOCUMENT_TYPE_DTO_ID_CACHE_PREFIX + documentTypeId.toString();
 226  
     }
 227  
 
 228  
     /**
 229  
      * Returns the cache key for the given document type name.
 230  
      */
 231  
     protected String getDTONameCacheKey(String documentTypeName) {
 232  0
             return DOCUMENT_TYPE_DTO_NAME_CACHE_PREFIX + documentTypeName;
 233  
     }
 234  
 
 235  
     /**
 236  
      * Inserts the given DocumentType into the name and id caches.  If the DocumentType is already in the cache,
 237  
      * these entries should  be overwritten.
 238  
      *
 239  
      * <p>If the given DocumentType does not represent the current version of the DocumentType then it
 240  
      * should not be inserted into the name cache.  This is because different versions of DocumentTypes have
 241  
      * different IDs but they all have the same name.  We want only the most recent version of the DocumentType
 242  
      * to be cached by name.
 243  
      */
 244  
     protected void insertDTOIntoCache(DocumentTypeDTO documentType) {
 245  0
             if (documentType == null) {
 246  0
                     return;
 247  
             }
 248  
             //don't cache by name if this isn't the current version
 249  0
             if ( documentType.getDocTypeCurrentInd().equals(KEWConstants.ACTIVE_CD) ) {
 250  0
                     KsbApiServiceLocator.getCacheAdministrator().putInCache(getDTONameCacheKey(documentType.getName()), documentType, DOCUMENT_TYPE_DTO_NAME_CACHE_GROUP);
 251  
             }
 252  
 
 253  0
             KsbApiServiceLocator.getCacheAdministrator().putInCache(getDTOIdCacheKey(documentType.getDocTypeId()), documentType, DOCUMENT_TYPE_DTO_ID_CACHE_GROUP);
 254  0
     }
 255  
 
 256  
     /**
 257  
      * Flushes all DocumentTypes from the cache.
 258  
      */
 259  
     public void flushCache() {
 260  
             // invalidate locally because if we're doing an upload of a document hierarchy we can't wait the 5 secs for this nodes cache
 261  
                 //to be accurate-the data going in the db depends on it being accurate now.  This means the cache will be cleared multiple times
 262  
             //over during an upload and the subsequent notification to this node.
 263  0
             LOG.info("clearing DocumentType cache because of local update");
 264  0
             KsbApiServiceLocator.getCacheAdministrator().flushGroup(DOCUMENT_TYPE_ID_CACHE_GROUP);
 265  0
             KsbApiServiceLocator.getCacheAdministrator().flushGroup(DOCUMENT_TYPE_NAME_CACHE_GROUP);
 266  0
             KsbApiServiceLocator.getCacheAdministrator().flushGroup(DOCUMENT_TYPE_DTO_ID_CACHE_GROUP);
 267  0
             KsbApiServiceLocator.getCacheAdministrator().flushGroup(DOCUMENT_TYPE_DTO_NAME_CACHE_GROUP);
 268  0
             KsbApiServiceLocator.getCacheAdministrator().flushGroup(DocumentTypePermissionService.DOC_TYPE_PERM_CACHE_GROUP);
 269  0
             KsbApiServiceLocator.getCacheAdministrator().flushEntry(CURRENT_ROOTS_IN_CACHE_KEY);
 270  0
     }
 271  
 
 272  
     public void clearCacheForAttributeUpdate(RuleAttribute ruleAttribute) {
 273  0
             if (ruleAttribute.getRuleAttributeId() != null) {
 274  0
                     List documentTypeAttributes = this.documentTypeDAO.findDocumentTypeAttributes(ruleAttribute);
 275  0
                     if (documentTypeAttributes.size() != 0) {
 276  0
                             flushCache();
 277  
                     }
 278  
             }
 279  0
     }
 280  
 
 281  
     public void versionAndSave(DocumentType documentType) {
 282  
             try {
 283  
                     // at this point this save is designed to version the document type by creating an entire new record if this is going to be an update and
 284  
                     // not a create just throw and exception to be on the safe side
 285  0
                     if (documentType.getDocumentTypeId() != null && documentType.getVersionNumber() != null) {
 286  0
                             throw new RuntimeException("DocumentType configured for update and not versioning which we support");
 287  
                     }
 288  
 
 289  
                     // grab the old document. Don't Use Cached Version!
 290  0
                     DocumentType oldDocumentType = findByName(documentType.getName(), true, false);
 291  
                     // reset the children on the oldDocumentType
 292  
                     //oldDocumentType.resetChildren();
 293  0
                     Long existingDocTypeId = null;
 294  0
                     if (oldDocumentType != null) {
 295  0
                         existingDocTypeId = oldDocumentType.getDocumentTypeId();
 296  0
                         if (existingDocTypeId.longValue() > 0) {
 297  
                             // set version number on the new doc type using the max version from the database
 298  0
                             Integer maxVersionNumber = documentTypeDAO.getMaxVersionNumber(documentType.getName());
 299  0
                                 documentType.setVersion((maxVersionNumber != null) ? new Integer(maxVersionNumber.intValue() + 1) : new Integer(0));
 300  0
                                 oldDocumentType.setCurrentInd(Boolean.FALSE);
 301  0
                                 if ( LOG.isInfoEnabled() ) { 
 302  0
                                         LOG.info("Saving old document type Id " + oldDocumentType.getDocumentTypeId() + " name '" + oldDocumentType.getName() + "' (current = " + oldDocumentType.getCurrentInd() + ")");
 303  
                                 }
 304  0
                                 save(oldDocumentType, false);
 305  
                         }
 306  
                     }
 307  
                     // check to see that no current documents exist in database
 308  0
                     if (!CollectionUtils.isEmpty(documentTypeDAO.findAllCurrentByName(documentType.getName()))) {
 309  0
                         String errorMsg = "Found invalid 'current' document with name '" + documentType.getName() + "'.  None should exist.";
 310  0
                         LOG.error(errorMsg);
 311  0
                         throw new RuntimeException(errorMsg);
 312  
                     }
 313  
             // set up the previous current doc type on the new doc type
 314  0
             documentType.setPreviousVersionId(existingDocTypeId);
 315  0
             documentType.setCurrentInd(Boolean.TRUE);
 316  0
                     save(documentType, false);
 317  0
                     if ( LOG.isInfoEnabled() ) { 
 318  0
                             LOG.info("Saved current document type Id " + documentType.getDocumentTypeId() + " name '" + documentType.getName() + "' (current = " + documentType.getCurrentInd() + ")");
 319  
                     }
 320  
                     //attach the children to this new parent.  cloning the children would probably be a better way to go here...
 321  0
                     if (ObjectUtils.isNotNull(existingDocTypeId)) {
 322  
                         // documentType.getPreviousVersion() should not be null at this point
 323  0
                 for (Iterator iterator = getChildDocumentTypes(existingDocTypeId).iterator(); iterator.hasNext();) {
 324  
 //                            for (Iterator iterator = oldDocumentType.getChildrenDocTypes().iterator(); iterator.hasNext();) {
 325  0
                                     DocumentType child = (DocumentType) iterator.next();
 326  0
                                     child.setDocTypeParentId(documentType.getDocumentTypeId());
 327  0
                                     save(child, false);
 328  0
                                     if ( LOG.isInfoEnabled() ) { 
 329  0
                                             LOG.info("Saved child document type Id " + child.getDocumentTypeId() + " name '" + child.getName() + "' (parent = " + child.getDocTypeParentId() + ", current = " + child.getCurrentInd() + ")");
 330  
                                     }
 331  0
                             }
 332  
                     }
 333  
                     // initiate a save of this document type's parent document type, this will force a
 334  
                     // version check which should reveal (via an optimistic lock exception) whether or
 335  
                     // not there is a concurrent transaction
 336  
                     // which has modified the parent (and therefore made it non-current)
 337  
                     // be sure to get the parent doc type directly from the db and not from the cache
 338  0
                     if (documentType.getDocTypeParentId() != null) {
 339  0
                             DocumentType parent = getDocumentTypeDAO().findById(documentType.getDocTypeParentId());
 340  0
                             save(parent, false);
 341  0
                             if ( LOG.isInfoEnabled() ) { 
 342  0
                                     LOG.info("Saved parent document type Id " + parent.getDocumentTypeId() + " name '" + parent.getName() + "' (current = " + parent.getCurrentInd() + ")");
 343  
                             }
 344  
                     }
 345  
 
 346  
                     // finally, flush the cache and notify the rule cache of the DocumentType change
 347  0
                     flushCache();
 348  0
                     KEWServiceLocator.getRuleService().notifyCacheOfDocumentTypeChange(documentType);
 349  
             } finally {
 350  
                     // the double flush here is necessary because of a series of events which occur inside of
 351  
                     // notifyCacheOfDocumentTypeChange, see the documentation inside that service method for
 352  
                     // more information on the problem.  Essentially, the method ends up invoking methods on
 353  
                     // this service which re-cache document types, however the document types that get
 354  
                     // re-cached are ones pulled from the OJB cache that don't have the proper children
 355  
                     // on them
 356  
                     //
 357  
                     // also we flush in the finally block because if an exception is thrown then it's still possible
 358  
                     // the the "oldDocumentType" which was fetched from the cache has had it's dbLockVerNbr incremented
 359  0
                     flushCache();
 360  0
             }
 361  0
     }
 362  
 
 363  
     public void save(DocumentType documentType, boolean flushCache) {
 364  0
             getDocumentTypeDAO().save(documentType);
 365  0
             if (flushCache) {
 366  
                     // always clear the entire cache
 367  0
                     flushCache();
 368  0
                 KEWServiceLocator.getRuleService().notifyCacheOfDocumentTypeChange(documentType);
 369  0
                 flushCache();
 370  
             }
 371  0
     }
 372  
 
 373  
     public void save(DocumentType documentType) {
 374  0
             save(documentType, true);
 375  0
     }
 376  
 
 377  
     public DocumentTypeDAO getDocumentTypeDAO() {
 378  0
         return documentTypeDAO;
 379  
     }
 380  
 
 381  
     public void setDocumentTypeDAO(DocumentTypeDAO documentTypeDAO) {
 382  0
         this.documentTypeDAO = documentTypeDAO;
 383  0
     }
 384  
 
 385  
     public DocumentTypeDTO getDocumentTypeVO(Long documentTypeId) {
 386  0
         DocumentTypeDTO dto = fetchDTOFromCacheById(documentTypeId);
 387  0
         if ( dto == null ) {
 388  0
             DocumentType docType = findById(documentTypeId);
 389  0
             if ( docType == null ) {
 390  0
                     return null;
 391  
             }
 392  0
                 dto = DTOConverter.convertDocumentType(docType);
 393  0
                 insertDTOIntoCache(dto);
 394  
         }
 395  
         
 396  0
         return dto;
 397  
     }
 398  
 
 399  
     public DocumentTypeDTO getDocumentTypeVO(String documentTypeName) {
 400  0
         DocumentTypeDTO dto = fetchDTOFromCacheByName(documentTypeName);
 401  0
         if ( dto == null ) {
 402  0
             DocumentType docType = findByName(documentTypeName);
 403  0
             if ( docType == null ) {
 404  0
                     return null;
 405  
             }
 406  0
                 dto = DTOConverter.convertDocumentType(docType);
 407  0
                 insertDTOIntoCache(dto);
 408  
         }
 409  0
         return dto;
 410  
     }
 411  
 
 412  
     public synchronized List findAllCurrentRootDocuments() {
 413  0
             List currentRootsInCache = (List) KsbApiServiceLocator.getCacheAdministrator().getFromCache(CURRENT_ROOTS_IN_CACHE_KEY);
 414  
             //we can do this because we whack the entire cache when a new document type comes into the picture.
 415  0
             if (currentRootsInCache == null) {
 416  0
                     currentRootsInCache = getDocumentTypeDAO().findAllCurrentRootDocuments();
 417  0
                     KsbApiServiceLocator.getCacheAdministrator().putInCache(CURRENT_ROOTS_IN_CACHE_KEY, currentRootsInCache);
 418  
             }
 419  0
             return currentRootsInCache;
 420  
     }
 421  
 
 422  
     public List findAllCurrent() {
 423  0
         return getDocumentTypeDAO().findAllCurrent();
 424  
     }
 425  
 
 426  
     public List<DocumentType> findPreviousInstances(String documentTypeName) {
 427  0
         return getDocumentTypeDAO().findPreviousInstances(documentTypeName);
 428  
     }
 429  
 
 430  
     public DocumentType findRootDocumentType(DocumentType docType) {
 431  0
         if (docType.getParentDocType() != null) {
 432  0
             return findRootDocumentType(docType.getParentDocType());
 433  
         } else {
 434  0
             return docType;
 435  
         }
 436  
     }
 437  
 
 438  
     public void loadXml(InputStream inputStream, String principalId) {
 439  0
         DocumentTypeXmlParser parser = new DocumentTypeXmlParser();
 440  
         try {
 441  0
             parser.parseDocumentTypes(inputStream);
 442  0
         } catch (Exception e) {
 443  0
             WorkflowServiceErrorException wsee = new WorkflowServiceErrorException("Error parsing documentType XML file", new WorkflowServiceErrorImpl("Error parsing documentType XML file", XML_FILE_PARSE_ERROR));
 444  0
             wsee.initCause(e);
 445  0
             throw wsee;
 446  0
         }
 447  0
     }
 448  
 
 449  
     public Element export(ExportDataSet dataSet) {
 450  0
         DocumentTypeXmlExporter exporter = new DocumentTypeXmlExporter();
 451  0
         return exporter.export(dataSet);
 452  
     }
 453  
     
 454  
     @Override
 455  
         public boolean supportPrettyPrint() {
 456  0
                 return true;
 457  
         }
 458  
 
 459  
     public List getChildDocumentTypes(Long documentTypeId) {
 460  0
             List childDocumentTypes = new ArrayList();
 461  0
             List childIds = getDocumentTypeDAO().getChildDocumentTypeIds(documentTypeId);
 462  0
             for (Iterator iter = childIds.iterator(); iter.hasNext();) {
 463  0
                         Long childDocumentTypeId = (Long) iter.next();
 464  0
                         childDocumentTypes.add(findById(childDocumentTypeId));
 465  0
                 }
 466  0
             return childDocumentTypes;
 467  
     }
 468  
 
 469  
 }