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 }