001 /** 002 * Copyright 2005-2013 The Kuali Foundation 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 package org.kuali.rice.kns.document; 017 018 import org.apache.commons.codec.digest.DigestUtils; 019 import org.apache.commons.collections.CollectionUtils; 020 import org.apache.commons.lang.StringUtils; 021 import org.apache.struts.upload.FormFile; 022 import org.kuali.rice.kns.maintenance.Maintainable; 023 import org.kuali.rice.krad.bo.DocumentAttachment; 024 import org.kuali.rice.krad.bo.MultiDocumentAttachment; 025 import org.kuali.rice.krad.bo.PersistableAttachment; 026 import org.kuali.rice.krad.bo.PersistableAttachmentBase; 027 import org.kuali.rice.krad.bo.PersistableAttachmentList; 028 import org.kuali.rice.krad.bo.PersistableBusinessObject; 029 import org.kuali.rice.krad.util.ObjectUtils; 030 031 import javax.persistence.Transient; 032 import java.io.FileNotFoundException; 033 import java.io.IOException; 034 import java.lang.reflect.Method; 035 import java.util.ArrayList; 036 import java.util.Collections; 037 import java.util.HashMap; 038 import java.util.List; 039 import java.util.Map; 040 041 /** 042 * @author Kuali Rice Team (rice.collab@kuali.org) 043 */ 044 public class MaintenanceDocumentBase extends org.kuali.rice.krad.maintenance.MaintenanceDocumentBase implements MaintenanceDocument { 045 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(MaintenanceDocumentBase.class); 046 047 @Transient 048 protected transient FormFile fileAttachment; 049 050 public MaintenanceDocumentBase() { 051 super(); 052 } 053 054 public MaintenanceDocumentBase(String documentTypeName) { 055 super(documentTypeName); 056 } 057 058 @Override 059 public PersistableBusinessObject getDocumentBusinessObject() { 060 return (PersistableBusinessObject) super.getDocumentDataObject(); 061 } 062 063 /** 064 * Checks old maintainable bo has key values 065 */ 066 public boolean isOldBusinessObjectInDocument() { 067 boolean isOldBusinessObjectInExistence = false; 068 if (getOldMaintainableObject() == null || getOldMaintainableObject().getBusinessObject() == null) { 069 isOldBusinessObjectInExistence = false; 070 } else { 071 isOldBusinessObjectInExistence = getOldMaintainableObject().isOldBusinessObjectInDocument(); 072 } 073 return isOldBusinessObjectInExistence; 074 } 075 076 public Maintainable getNewMaintainableObject() { 077 return (Maintainable) newMaintainableObject; 078 } 079 080 public Maintainable getOldMaintainableObject() { 081 return (Maintainable) oldMaintainableObject; 082 } 083 084 public FormFile getFileAttachment() { 085 return this.fileAttachment; 086 } 087 088 public void setFileAttachment(FormFile fileAttachment) { 089 this.fileAttachment = fileAttachment; 090 } 091 092 @Override 093 public void populateDocumentAttachment() { 094 refreshAttachment(); 095 096 if (fileAttachment != null && StringUtils.isNotEmpty(fileAttachment.getFileName())) { 097 //Populate DocumentAttachment BO 098 if (attachment == null) { 099 attachment = new DocumentAttachment(); 100 } 101 102 byte[] fileContents; 103 try { 104 fileContents = fileAttachment.getFileData(); 105 if (fileContents.length > 0) { 106 attachment.setFileName(fileAttachment.getFileName()); 107 attachment.setContentType(fileAttachment.getContentType()); 108 attachment.setAttachmentContent(fileAttachment.getFileData()); 109 PersistableAttachment boAttachment = (PersistableAttachment) newMaintainableObject.getDataObject(); 110 boAttachment.setAttachmentContent(null); 111 attachment.setDocumentNumber(getDocumentNumber()); 112 } 113 } catch (FileNotFoundException e) { 114 LOG.error("Error while populating the Document Attachment", e); 115 throw new RuntimeException("Could not populate DocumentAttachment object", e); 116 } catch (IOException e) { 117 LOG.error("Error while populating the Document Attachment", e); 118 throw new RuntimeException("Could not populate DocumentAttachment object", e); 119 } 120 } else { 121 //fileAttachment isn't filled, populate from bo if it exists 122 PersistableAttachment boAttachment = (PersistableAttachment) newMaintainableObject.getDataObject(); 123 if (attachment == null 124 && boAttachment != null 125 && boAttachment.getAttachmentContent() != null) { 126 DocumentAttachment newAttachment = new DocumentAttachment(); 127 newAttachment.setDocumentNumber(getDocumentNumber()); 128 newAttachment.setAttachmentContent(boAttachment.getAttachmentContent()); 129 newAttachment.setContentType(boAttachment.getContentType()); 130 newAttachment.setFileName(boAttachment.getFileName()); 131 //null out boAttachment file, will be copied back before final save. 132 boAttachment.setAttachmentContent(null); 133 attachment = newAttachment; 134 } 135 } 136 } 137 138 @Override 139 public void populateAttachmentForBO() { 140 refreshAttachment(); 141 142 PersistableAttachment boAttachment = (PersistableAttachment) newMaintainableObject.getDataObject(); 143 144 if (ObjectUtils.isNotNull(getAttachmentPropertyName())) { 145 String attachmentPropNm = getAttachmentPropertyName(); 146 String attachmentPropNmSetter = "get" + attachmentPropNm.substring(0, 1).toUpperCase() + attachmentPropNm.substring(1, attachmentPropNm.length()); 147 FormFile attachmentFromBusinessObject; 148 149 if((boAttachment.getFileName() == null) && (boAttachment instanceof PersistableAttachment)) { 150 try { 151 Method[] methods = boAttachment.getClass().getMethods(); 152 for (Method method : methods) { 153 if (method.getName().equals(attachmentPropNmSetter)) { 154 attachmentFromBusinessObject = (FormFile)(boAttachment.getClass().getDeclaredMethod(attachmentPropNmSetter).invoke(boAttachment)); 155 if (attachmentFromBusinessObject != null) { 156 //boAttachment.setAttachmentContent(attachmentFromBusinessObject.getFileData()); 157 boAttachment.setFileName(attachmentFromBusinessObject.getFileName()); 158 boAttachment.setContentType(attachmentFromBusinessObject.getContentType()); 159 } 160 break; 161 } 162 } 163 } catch (Exception e) { 164 LOG.error("Not able to get the attachment " + e.getMessage()); 165 throw new RuntimeException("Not able to get the attachment " + e.getMessage()); 166 } 167 } 168 } 169 170 if((boAttachment.getFileName() == null) && (boAttachment instanceof PersistableAttachment) && (attachment != null)) { 171 //byte[] fileContents; 172 //fileContents = attachment.getAttachmentContent(); 173 if (attachment.getFileName() != null) { 174 boAttachment.setAttachmentContent(null); 175 boAttachment.setFileName(attachment.getFileName()); 176 boAttachment.setContentType(attachment.getContentType()); 177 } 178 } 179 } 180 181 @Override 182 public void populateAttachmentBeforeSave() { 183 PersistableAttachment boAttachment = (PersistableAttachment) newMaintainableObject.getDataObject(); 184 if (attachment != null 185 && attachment.getAttachmentContent() != null) { 186 boAttachment.setAttachmentContent(attachment.getAttachmentContent()); 187 } else { 188 boAttachment.setAttachmentContent(null); 189 boAttachment.setFileName(null); 190 boAttachment.setContentType(null); 191 } 192 } 193 194 @Override 195 public void populateBoAttachmentListBeforeSave() { 196 197 PersistableAttachmentList<PersistableAttachment> boAttachments = (PersistableAttachmentList<PersistableAttachment>) newMaintainableObject.getDataObject(); 198 if (CollectionUtils.isEmpty(attachments)) { 199 //there are no attachments. Clear out Bo Attachments 200 boAttachments.setAttachments(Collections.<PersistableAttachment>emptyList()); 201 return; 202 } 203 Map<String, MultiDocumentAttachment> files = new HashMap<String, MultiDocumentAttachment>(); 204 for (MultiDocumentAttachment multiAttach : attachments) { 205 String key = new StringBuffer(multiAttach.getFileName()).append("|").append(multiAttach.getContentType()).toString(); 206 files.put(key, multiAttach); 207 } 208 209 210 //want to just copy over file if possible, as there can be other fields that are not on PersistableAttachment 211 //these arrays should be somewhat synched by the other populate methods 212 if (CollectionUtils.isNotEmpty(boAttachments.getAttachments())) { 213 for (PersistableAttachment attach : boAttachments.getAttachments()) { 214 //try to get a new instance of the correct object... 215 String key = new StringBuffer(attach.getFileName()).append("|").append(attach.getContentType()).toString(); 216 if (files.containsKey(key)) { 217 attach.setAttachmentContent(files.get(key).getAttachmentContent()); 218 files.remove(key); 219 } 220 } 221 } 222 } 223 224 @Override 225 public void populateAttachmentListForBO() { 226 refreshAttachmentList(); 227 228 PersistableAttachmentList<PersistableAttachment> boAttachments = (PersistableAttachmentList<PersistableAttachment>) newMaintainableObject.getDataObject(); 229 230 if (ObjectUtils.isNotNull(getAttachmentListPropertyName())) { 231 //String collectionName = getAttachmentCollectionName(); 232 String attachmentPropNm = getAttachmentListPropertyName(); 233 String attachmentPropNmSetter = "get" + attachmentPropNm.substring(0, 1).toUpperCase() + attachmentPropNm.substring(1, attachmentPropNm.length()); 234 235 236 for (PersistableAttachment persistableAttachment : boAttachments.getAttachments()) { 237 if((persistableAttachment.getFileName() == null)) { 238 try { 239 FormFile attachmentFromBusinessObject = (FormFile)(persistableAttachment.getClass().getDeclaredMethod(attachmentPropNmSetter).invoke(persistableAttachment)); 240 if (attachmentFromBusinessObject != null) { 241 //persistableAttachment.setAttachmentContent( 242 // attachmentFromBusinessObject.getFileData()); 243 persistableAttachment.setFileName(attachmentFromBusinessObject.getFileName()); 244 persistableAttachment.setContentType(attachmentFromBusinessObject.getContentType()); 245 } 246 } catch (Exception e) { 247 LOG.error("Not able to get the attachment " + e.getMessage()); 248 throw new RuntimeException("Not able to get the attachment " + e.getMessage()); 249 } 250 } 251 } 252 } 253 if((CollectionUtils.isEmpty(boAttachments.getAttachments()) 254 && (CollectionUtils.isNotEmpty(attachments)))) { 255 256 List<PersistableAttachment> attachmentList = new ArrayList<PersistableAttachment>(); 257 for (MultiDocumentAttachment multiAttach : attachments) { 258 259 //try to get a new instance of the correct object... 260 if (multiAttach.getAttachmentContent().length > 0) { 261 PersistableAttachment persistableAttachment = convertDocToBoAttachment(multiAttach, false); 262 attachmentList.add(persistableAttachment); 263 } 264 } 265 boAttachments.setAttachments(attachmentList); 266 } 267 } 268 269 private PersistableAttachment convertDocToBoAttachment(MultiDocumentAttachment multiAttach, boolean copyFile) { 270 PersistableAttachment persistableAttachment = new PersistableAttachmentBase(); 271 272 if (copyFile 273 && multiAttach.getAttachmentContent() != null) { 274 persistableAttachment.setAttachmentContent(multiAttach.getAttachmentContent()); 275 } 276 persistableAttachment.setFileName(multiAttach.getFileName()); 277 persistableAttachment.setContentType(multiAttach.getContentType()); 278 return persistableAttachment; 279 } 280 281 @Override 282 public void populateDocumentAttachmentList() { 283 refreshAttachmentList(); 284 285 String attachmentPropNm = getAttachmentListPropertyName(); 286 String attachmentPropNmSetter = "get" + attachmentPropNm.substring(0, 1).toUpperCase() + attachmentPropNm.substring(1, attachmentPropNm.length()); 287 //don't have form fields to use to fill, but they should be populated on the DataObject. grab them from there. 288 PersistableAttachmentList<PersistableAttachment> boAttachmentList = (PersistableAttachmentList<PersistableAttachment>) newMaintainableObject.getDataObject(); 289 290 if (CollectionUtils.isNotEmpty(boAttachmentList.getAttachments())) { 291 292 293 //build map for comparison 294 Map<String, MultiDocumentAttachment> md5Hashes = new HashMap<String, MultiDocumentAttachment>(); 295 if (CollectionUtils.isNotEmpty(attachments)) { 296 for (MultiDocumentAttachment currentAttachment : attachments) { 297 md5Hashes.put(DigestUtils.md5Hex(currentAttachment.getAttachmentContent()), currentAttachment); 298 } 299 } 300 301 //Populate DocumentAttachment BO 302 attachments = new ArrayList<MultiDocumentAttachment>(); 303 304 for (PersistableAttachment persistableAttachment : boAttachmentList.getAttachments()) { 305 try { 306 FormFile attachmentFromBusinessObject = (FormFile)(persistableAttachment.getClass().getDeclaredMethod(attachmentPropNmSetter).invoke(persistableAttachment)); 307 if (attachmentFromBusinessObject != null) { 308 // 309 //byte[] fileContents = attachmentFromBusinessObject.getFileData(); 310 String md5Hex = DigestUtils.md5Hex(attachmentFromBusinessObject.getInputStream()); 311 if (md5Hashes.containsKey(md5Hex)) { 312 String newFileName = attachmentFromBusinessObject.getFileName(); 313 MultiDocumentAttachment multiAttach = md5Hashes.get(md5Hex); 314 if (multiAttach.getFileName().equals(newFileName)) { 315 attachments.add(multiAttach); 316 } else { 317 multiAttach.setFileName(attachmentFromBusinessObject.getFileName()); 318 multiAttach.setContentType(attachmentFromBusinessObject.getContentType()); 319 attachments.add(multiAttach); 320 } 321 md5Hashes.remove(md5Hex); 322 } else { 323 MultiDocumentAttachment attach = new MultiDocumentAttachment(); 324 attach.setFileName(attachmentFromBusinessObject.getFileName()); 325 attach.setContentType(attachmentFromBusinessObject.getContentType()); 326 attach.setAttachmentContent(attachmentFromBusinessObject.getFileData()); 327 attach.setDocumentNumber(getDocumentNumber()); 328 attachments.add(attach); 329 } 330 } else { 331 if (persistableAttachment.getFileName() != null 332 && persistableAttachment.getAttachmentContent() != null) { 333 MultiDocumentAttachment attach = new MultiDocumentAttachment(); 334 attach.setFileName(persistableAttachment.getFileName()); 335 attach.setContentType(persistableAttachment.getContentType()); 336 attach.setAttachmentContent(persistableAttachment.getAttachmentContent()); 337 attach.setDocumentNumber(getDocumentNumber()); 338 339 //set Bo's content to null 340 persistableAttachment.setAttachmentContent(null); 341 attachments.add(attach); 342 } 343 } 344 } catch (Exception e) { 345 LOG.error("Not able to get the attachment " + e.getMessage()); 346 throw new RuntimeException("Not able to get the attachment " + e.getMessage()); 347 } 348 } 349 350 } 351 } 352 353 }