View Javadoc

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.kns.document;
17  
18  import org.apache.commons.codec.digest.DigestUtils;
19  import org.apache.commons.collections.CollectionUtils;
20  import org.apache.commons.lang.StringUtils;
21  import org.apache.struts.upload.FormFile;
22  import org.kuali.rice.kns.maintenance.Maintainable;
23  import org.kuali.rice.krad.bo.DocumentAttachment;
24  import org.kuali.rice.krad.bo.MultiDocumentAttachment;
25  import org.kuali.rice.krad.bo.PersistableAttachment;
26  import org.kuali.rice.krad.bo.PersistableAttachmentBase;
27  import org.kuali.rice.krad.bo.PersistableAttachmentList;
28  import org.kuali.rice.krad.bo.PersistableBusinessObject;
29  import org.kuali.rice.krad.util.ObjectUtils;
30  
31  import javax.persistence.Transient;
32  import java.io.FileNotFoundException;
33  import java.io.IOException;
34  import java.lang.reflect.Method;
35  import java.util.ArrayList;
36  import java.util.Collections;
37  import java.util.HashMap;
38  import java.util.List;
39  import java.util.Map;
40  
41  /**
42   * @author Kuali Rice Team (rice.collab@kuali.org)
43   */
44  public class MaintenanceDocumentBase extends org.kuali.rice.krad.maintenance.MaintenanceDocumentBase implements MaintenanceDocument {
45      private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(MaintenanceDocumentBase.class);
46  
47      @Transient
48      protected transient FormFile fileAttachment;
49  
50      public MaintenanceDocumentBase() {
51          super();
52      }
53  
54      public MaintenanceDocumentBase(String documentTypeName) {
55          super(documentTypeName);
56      }
57  
58      @Override
59      public PersistableBusinessObject getDocumentBusinessObject() {
60          return (PersistableBusinessObject) super.getDocumentDataObject();
61      }
62  
63      /**
64       * Checks old maintainable bo has key values
65       */
66      public boolean isOldBusinessObjectInDocument() {
67          boolean isOldBusinessObjectInExistence = false;
68          if (getOldMaintainableObject() == null || getOldMaintainableObject().getBusinessObject() == null) {
69              isOldBusinessObjectInExistence = false;
70          } else {
71              isOldBusinessObjectInExistence = getOldMaintainableObject().isOldBusinessObjectInDocument();
72          }
73          return isOldBusinessObjectInExistence;
74      }
75  
76      public Maintainable getNewMaintainableObject() {
77          return (Maintainable) newMaintainableObject;
78      }
79  
80      public Maintainable getOldMaintainableObject() {
81          return (Maintainable) oldMaintainableObject;
82      }
83  
84      public FormFile getFileAttachment() {
85          return this.fileAttachment;
86      }
87  
88      public void setFileAttachment(FormFile fileAttachment) {
89          this.fileAttachment = fileAttachment;
90      }
91  
92      @Override
93      public void populateDocumentAttachment() {
94          refreshAttachment();
95  
96          if (fileAttachment != null && StringUtils.isNotEmpty(fileAttachment.getFileName())) {
97              //Populate DocumentAttachment BO
98              if (attachment == null) {
99                  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 }