001 package org.trails.component.blob;
002
003 import org.apache.commons.logging.Log;
004 import org.apache.commons.logging.LogFactory;
005 import org.apache.hivemind.util.Defense;
006 import org.apache.tapestry.IRequestCycle;
007 import org.apache.tapestry.engine.IEngineService;
008 import org.apache.tapestry.engine.ILink;
009 import org.apache.tapestry.services.DataSqueezer;
010 import org.apache.tapestry.services.LinkFactory;
011 import org.apache.tapestry.util.ContentType;
012 import org.apache.tapestry.web.WebResponse;
013 import org.trails.descriptor.IPropertyDescriptor;
014 import org.trails.descriptor.extension.BlobDescriptorExtension;
015 import org.trails.persistence.PersistenceService;
016
017 import java.io.IOException;
018 import java.io.OutputStream;
019 import java.io.Serializable;
020 import java.util.HashMap;
021 import java.util.Map;
022
023 public class BlobDownloadService implements IEngineService
024 {
025
026 private static final Log LOG = LogFactory.getLog(BlobDownloadService.class);
027
028 public static final String SERVICE_NAME = "download";
029
030 private LinkFactory _linkFactory;
031
032 private WebResponse _response;
033
034 private PersistenceService persistenceService;
035
036 private IFilePersister filePersister;
037
038 DataSqueezer dataSqueezer;
039
040 private static final String BLOBID_PARAMETER_NAME = "id";
041
042 private static final String PROP_DESC_PARAMETER_NAME = "propDesc";
043
044 public ILink getLink(boolean post, Object parameter)
045 {
046
047 Defense.isAssignable(((Object[]) parameter)[0], TrailsBlobAsset.class, "parameter");
048
049 TrailsBlobAsset asset = (TrailsBlobAsset) ((Object[]) parameter)[0];
050
051 Map<String, String> parameters = new HashMap<String, String>();
052
053 parameters.put(PROP_DESC_PARAMETER_NAME, dataSqueezer.squeeze(asset.getPropertyDescriptor()));
054 parameters.put(BLOBID_PARAMETER_NAME, dataSqueezer.squeeze(asset.getId()));
055
056 return _linkFactory.constructLink(this, false, parameters, true);
057
058 }
059
060 public void service(IRequestCycle cycle) throws IOException
061 {
062 String blobID = cycle.getParameter(BLOBID_PARAMETER_NAME);
063 String bytesProp = cycle.getParameter(PROP_DESC_PARAMETER_NAME);
064
065 IPropertyDescriptor propertyDescriptor = (IPropertyDescriptor) dataSqueezer.unsqueeze(bytesProp);
066 BlobDescriptorExtension blobDescriptor = propertyDescriptor.getExtension(BlobDescriptorExtension.class);
067
068 if (blobDescriptor != null && blobID != null && !"".equals(blobID))
069 {
070 Object model = persistenceService
071 .getInstance(propertyDescriptor.getBeanType(), (Serializable) dataSqueezer.unsqueeze(blobID));
072
073 if (model != null)
074 {
075 String fileName = filePersister.getFileName(propertyDescriptor, model);
076 String contentType = filePersister.getContentType(propertyDescriptor, model);
077 byte[] bytes = filePersister.getData(propertyDescriptor, model);
078
079 if (bytes.length > 0)
080 {
081 _response.setHeader("Expires", "0");
082 _response.setHeader("Cache-Control", "must-revalidate, post-check=0,pre-check=0");
083 _response.setHeader("Pragma", "public");
084 _response.setHeader("Content-Disposition",
085 blobDescriptor.getContentDisposition().getValue() +
086 (fileName != null ? "; filename=" + fileName : ""));
087 _response.setContentLength(bytes.length);
088
089 OutputStream output = null;
090 try
091 {
092 output = _response.getOutputStream(
093 contentType != null ? new ContentType(contentType) : new ContentType());
094 output.write(bytes);
095 } finally
096 {
097 try
098 {
099 if (output != null)
100 {
101 output.flush();
102 output.close();
103 }
104 } catch (Throwable t)
105 {
106 // do nothing;
107 }
108 }
109 } else
110 {
111 String errorText = "BlobDownloadServcie: entityName->" +
112 propertyDescriptor.getBeanType().getName() + ", blobID ->" + blobID +
113 " : has not been ingested yet";
114 LOG.info(errorText);
115 // muted kwc - throw new TrailsRuntimeException(errorText);
116 }
117 }
118
119 } else
120 {
121 String errorText = "BlobDownloadServcie: entityName->" + propertyDescriptor.getBeanType().getName() +
122 ", blobID ->" + blobID +
123 " : has not been ingested yet";
124 LOG.info(errorText);
125 // muted kwc - throw new TrailsRuntimeException(errorText);
126 }
127 }
128
129 public String getName()
130 {
131 return SERVICE_NAME;
132 }
133
134 public void setLinkFactory(LinkFactory linkFactory)
135 {
136 _linkFactory = linkFactory;
137 }
138
139 public void setResponse(WebResponse response)
140 {
141 _response = response;
142 }
143
144 public void setPersistenceService(PersistenceService persistenceService)
145 {
146 this.persistenceService = persistenceService;
147 }
148
149 public void setFilePersister(IFilePersister filePersister)
150 {
151 this.filePersister = filePersister;
152 }
153
154 public void setDataSqueezer(DataSqueezer dataSqueezer)
155 {
156 this.dataSqueezer = dataSqueezer;
157 }
158 }