package er.attachment.processors; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import com.webobjects.appserver.WOContext; import com.webobjects.appserver.WORequest; import com.webobjects.eocontrol.EOEditingContext; import com.webobjects.foundation.NSData; import com.webobjects.foundation.NSTimestamp; import er.attachment.model.ERAttachmentData; import er.attachment.model.ERDatabaseAttachment; import er.extensions.foundation.ERXProperties; /** * ERDatabaseAttachmentProcessor implements storing attachment data as an attribute of an EO. * For more information about configuring an ERDatabaseAttachmentProcessor, see the top level documentation. * * @property er.attachment.[configurationName].db.webPath * @property er.attachment.db.webPath * @property er.attachment.[configurationName].db.smallData * @property er.attachment.db.smallData * * @author mschrag */ public class ERDatabaseAttachmentProcessor extends ERAttachmentProcessor<ERDatabaseAttachment> { @Override public ERDatabaseAttachment _process(EOEditingContext editingContext, File uploadedFile, String recommendedFileName, String mimeType, String configurationName, String ownerID, boolean pendingDelete) throws IOException { String webPath = ERXProperties.stringForKey("er.attachment." + configurationName + ".db.webPath"); if (webPath == null) { webPath = ERXProperties.stringForKeyWithDefault("er.attachment.db.webPath", "/${pk}${ext}"); } if (webPath == null) { throw new IllegalArgumentException("There is no 'er.attachment." + configurationName + ".db.webPath' or 'er.attachment.db.webPath' property set."); } else if (!webPath.startsWith("/")) { webPath = "/" + webPath; } boolean smallData = false; String smallDataStr = ERXProperties.stringForKey("er.attachment." + configurationName + ".db.smallData"); if (smallDataStr == null) { smallDataStr = ERXProperties.stringForKey("er.attachment.db.smallData"); } if (smallDataStr != null) { smallData = Boolean.parseBoolean(smallDataStr); } ERDatabaseAttachment attachment = ERDatabaseAttachment.createERDatabaseAttachment(editingContext, Boolean.TRUE, new NSTimestamp(), mimeType, recommendedFileName, Boolean.TRUE, Integer.valueOf((int) uploadedFile.length()), webPath); if (delegate() != null) { delegate().attachmentCreated(this, attachment); } try { attachment.setWebPath(ERAttachmentProcessor._parsePathTemplate(attachment, webPath, recommendedFileName)); NSData data = new NSData(uploadedFile.toURI().toURL()); if (smallData) { attachment.setSmallData(data); } else { ERAttachmentData attachmentData = ERAttachmentData.createERAttachmentData(editingContext); attachmentData.setData(data); attachment.setAttachmentDataRelationship(attachmentData); } if (delegate() != null) { delegate().attachmentAvailable(this, attachment); } } catch (IOException e) { attachment.delete(); throw e; } catch (RuntimeException e) { attachment.delete(); throw e; } finally { if (pendingDelete) { uploadedFile.delete(); } } return attachment; } @Override public InputStream attachmentInputStream(ERDatabaseAttachment attachment) throws FileNotFoundException { NSData data = attachment.smallData(); if (data == null) { ERAttachmentData attachmentData = attachment.attachmentData(); if (attachmentData != null) { data = attachmentData.data(); } } InputStream attachmentInputStream; if (data != null) { attachmentInputStream = data.stream(); } else { throw new FileNotFoundException("There was no data available for this attachment."); } return attachmentInputStream; } @Override public String attachmentUrl(ERDatabaseAttachment attachment, WORequest request, WOContext context) { return proxiedUrl(attachment, context); } @Override public void deleteAttachment(ERDatabaseAttachment attachment) { // cascade delete rules do this for us ... } }