001: /**
002: * Copyright (c) 2003-2007, David A. Czarnecki
003: * All rights reserved.
004: *
005: * Redistribution and use in source and binary forms, with or without
006: * modification, are permitted provided that the following conditions are met:
007: *
008: * Redistributions of source code must retain the above copyright notice, this list of conditions and the
009: * following disclaimer.
010: * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
011: * following disclaimer in the documentation and/or other materials provided with the distribution.
012: * Neither the name of "David A. Czarnecki" and "blojsom" nor the names of its contributors may be used to
013: * endorse or promote products derived from this software without specific prior written permission.
014: * Products derived from this software may not be called "blojsom", nor may "blojsom" appear in their name,
015: * without prior written permission of David A. Czarnecki.
016: *
017: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
018: * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
019: * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
020: * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
021: * EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
022: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
023: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
024: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
025: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
026: * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
027: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
028: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
029: * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
030: */package org.blojsom.plugin.common;
031:
032: import org.apache.commons.logging.Log;
033: import org.apache.commons.logging.LogFactory;
034: import org.blojsom.blog.Blog;
035: import org.blojsom.blog.Entry;
036: import org.blojsom.event.Event;
037: import org.blojsom.event.EventBroadcaster;
038: import org.blojsom.event.Listener;
039: import org.blojsom.plugin.Plugin;
040: import org.blojsom.plugin.PluginException;
041: import org.blojsom.plugin.admin.event.ProcessEntryEvent;
042: import org.blojsom.util.BlojsomConstants;
043: import org.blojsom.util.BlojsomUtils;
044:
045: import javax.servlet.ServletConfig;
046: import javax.servlet.ServletContext;
047: import javax.servlet.http.HttpServletRequest;
048: import javax.servlet.http.HttpServletResponse;
049: import java.io.File;
050: import java.util.HashMap;
051: import java.util.Map;
052: import java.util.Properties;
053: import java.util.TreeMap;
054:
055: /**
056: * FileAttachmentPlugin-The idea behind this plugin is taken from RSSEnclosure plugin.
057: *
058: * @author Sopan Shewale
059: * @version 1.0
060: * @since Blojsom Version 3.0
061: */
062: public class FileAttachmentPlugin implements Plugin, Listener {
063:
064: private Log _logger = LogFactory.getLog(FileAttachmentPlugin.class);
065: private static final String FILE_ATTACHMENT_TEMPLATE = "org/blojsom/plugin/common/templates/admin-file-attachment.vm";
066: private static final String FILE_ATTACHMENT = "FILE_ATTACHMENT";
067: private static final String FILE_ATTACHMENT_URL = "FILE_ATTACHMENT_URL";
068:
069: private static final String METADATA_FILE_ATTACHMENT = "file-attachment";
070:
071: protected EventBroadcaster _eventBroadcaster;
072: protected ServletConfig _servletConfig;
073: protected Properties _blojsomProperties;
074: protected String _resourcesDirectory;
075:
076: /**
077: * Default constructor
078: */
079: public FileAttachmentPlugin() {
080: }
081:
082: /**
083: * Set the default blojsom properties
084: *
085: * @param blojsomProperties Default blojsom properties
086: */
087: public void setBlojsomProperties(Properties blojsomProperties) {
088: _blojsomProperties = blojsomProperties;
089: }
090:
091: /**
092: * Set the {@link ServletConfig}
093: *
094: * @param servletConfig {@link ServletConfig}
095: */
096: public void setServletConfig(ServletConfig servletConfig) {
097: _servletConfig = servletConfig;
098: }
099:
100: /**
101: * Set the {@link EventBroadcaster}
102: *
103: * @param eventBroadcaster {@link EventBroadcaster}
104: */
105: public void setEventBroadcaster(EventBroadcaster eventBroadcaster) {
106: _eventBroadcaster = eventBroadcaster;
107: }
108:
109: /**
110: * Initialize this plugin. This method only called when the plugin is
111: * instantiated.
112: *
113: * @throws org.blojsom.plugin.PluginException
114: * If there is an error initializing the plugin
115: */
116: public void init() throws PluginException {
117: _resourcesDirectory = _blojsomProperties.getProperty(
118: BlojsomConstants.RESOURCES_DIRECTORY_IP,
119: BlojsomConstants.DEFAULT_RESOURCES_DIRECTORY);
120: _eventBroadcaster.addListener(this );
121:
122: _logger.debug("Initialized File Attachment plugin");
123: }
124:
125: /**
126: * Process the blog entries
127: *
128: * @param httpServletRequest Request
129: * @param httpServletResponse Response
130: * @param blog {@link Blog} instance
131: * @param context Context
132: * @param entries Blog entries retrieved for the particular request
133: * @return Modified set of blog entries
134: * @throws PluginException If there is an error processing the blog entries
135: */
136: public Entry[] process(HttpServletRequest httpServletRequest,
137: HttpServletResponse httpServletResponse, Blog blog,
138: Map context, Entry[] entries) throws PluginException {
139: ServletContext servletContext = _servletConfig
140: .getServletContext();
141: for (int i = 0; i < entries.length; i++) {
142: Entry entry = entries[i];
143: if (BlojsomUtils.checkMapForKey(entry.getMetaData(),
144: METADATA_FILE_ATTACHMENT)) {
145: String attachmentName = (String) entry.getMetaData()
146: .get(METADATA_FILE_ATTACHMENT);
147: File attachment = new File(servletContext
148: .getRealPath("/")
149: + _resourcesDirectory
150: + blog.getBlogId()
151: + "/"
152: + attachmentName);
153: if (attachment.exists()) {
154: if (_logger.isDebugEnabled()) {
155: _logger
156: .debug("Adding file-attachment to entry for file: "
157: + attachmentName);
158: }
159: StringBuffer attachmentElement = new StringBuffer();
160: String attachmentname = attachment.getName();
161: String url = blog.getBlogBaseURL()
162: + _resourcesDirectory + blog.getBlogId()
163: + "/" + attachmentname;
164: attachmentElement.append("<a href=\"");
165: attachmentElement.append(url);
166: attachmentElement.append("\">");
167: attachmentElement.append(attachmentname);
168: attachmentElement.append("</a>");
169: entry.getMetaData().put(METADATA_FILE_ATTACHMENT,
170: attachmentElement.toString());
171: _logger.debug("Added file attachment: "
172: + attachmentElement.toString());
173: }
174: }
175: }
176: return entries;
177: }
178:
179: /**
180: * Perform any cleanup for the plugin. Called after {@link #process}.
181: *
182: * @throws org.blojsom.plugin.PluginException
183: * If there is an error performing cleanup for this plugin
184: */
185: public void cleanup() throws PluginException {
186: }
187:
188: /**
189: * Called when BlojsomServlet is taken out of service
190: *
191: * @throws org.blojsom.plugin.PluginException
192: * If there is an error in finalizing this plugin
193: */
194: public void destroy() throws PluginException {
195: }
196:
197: /**
198: * Handle an event broadcast from another component
199: *
200: * @param event {@link org.blojsom.event.Event} to be handled
201: */
202: public void handleEvent(Event event) {
203: }
204:
205: /**
206: * Process an event from another component
207: *
208: * @param event {@link org.blojsom.event.Event} to be handled
209: */
210: public void processEvent(Event event) {
211: if (event instanceof ProcessEntryEvent) {
212: if (_logger.isDebugEnabled()) {
213: _logger.debug("Handling process blog entry event");
214: }
215: ProcessEntryEvent processBlogEntryEvent = (ProcessEntryEvent) event;
216: String blogId = processBlogEntryEvent.getBlog().getBlogId();
217:
218: Map templateAdditions = (Map) processBlogEntryEvent
219: .getContext().get("BLOJSOM_TEMPLATE_ADDITIONS");
220: if (templateAdditions == null) {
221: templateAdditions = new TreeMap();
222: }
223:
224: templateAdditions.put(getClass().getName(), "#parse('"
225: + FILE_ATTACHMENT_TEMPLATE + "')");
226: processBlogEntryEvent.getContext().put(
227: "BLOJSOM_TEMPLATE_ADDITIONS", templateAdditions);
228:
229: // Create a list of files in the user's resource directory
230: File resourceDirectory = new File(_servletConfig
231: .getServletContext().getRealPath("/")
232: + _resourcesDirectory + blogId + "/");
233: Map resourceFilesMap = null;
234: if (resourceDirectory.exists()) {
235: File[] resourceFiles = resourceDirectory.listFiles();
236:
237: if (resourceFiles != null) {
238: resourceFilesMap = new HashMap(resourceFiles.length);
239: for (int i = 0; i < resourceFiles.length; i++) {
240: File resourceFile = resourceFiles[i];
241: resourceFilesMap.put(resourceFile.getName(),
242: resourceFile.getName());
243: }
244: }
245: } else {
246: resourceFilesMap = new HashMap();
247: }
248: // Preserve the current file attachment if none submitted
249: if (processBlogEntryEvent.getEntry() != null) {
250: String currentAttachment = (String) processBlogEntryEvent
251: .getEntry().getMetaData().get(
252: METADATA_FILE_ATTACHMENT);
253: String currentAttachmentURL = (String) processBlogEntryEvent
254: .getEntry().getMetaData().get(
255: FILE_ATTACHMENT_URL);
256:
257: if (_logger.isDebugEnabled()) {
258: _logger.debug("Current Attachments: "
259: + currentAttachment);
260: }
261: processBlogEntryEvent.getContext().put(FILE_ATTACHMENT,
262: currentAttachment);
263: processBlogEntryEvent.getContext().put(
264: FILE_ATTACHMENT_URL,
265: BlojsomUtils
266: .escapeBrackets(currentAttachmentURL));
267:
268: }
269: String fileAttachment = BlojsomUtils.getRequestValue(
270: METADATA_FILE_ATTACHMENT, processBlogEntryEvent
271: .getHttpServletRequest());
272: String fileAttachmentURL = BlojsomUtils.getRequestValue(
273: FILE_ATTACHMENT_URL, processBlogEntryEvent
274: .getHttpServletRequest());
275:
276: if (!BlojsomUtils.checkNullOrBlank(fileAttachmentURL)
277: && (processBlogEntryEvent.getEntry() != null)) {
278: processBlogEntryEvent.getEntry().getMetaData().put(
279: fileAttachmentURL, fileAttachmentURL);
280: if (_logger.isDebugEnabled()) {
281: _logger
282: .debug("Added/updated File Attachment (explict): "
283: + fileAttachmentURL);
284: }
285: } else {
286: if (processBlogEntryEvent.getEntry() != null) {
287: processBlogEntryEvent.getEntry().getMetaData()
288: .remove(FILE_ATTACHMENT_URL);
289: }
290: if (!BlojsomUtils.checkNullOrBlank(fileAttachment)
291: && processBlogEntryEvent.getEntry() != null) {
292: processBlogEntryEvent.getEntry().getMetaData().put(
293: METADATA_FILE_ATTACHMENT, fileAttachment);
294: processBlogEntryEvent.getContext().put(
295: FILE_ATTACHMENT, fileAttachment);
296:
297: if (_logger.isDebugEnabled()) {
298: _logger
299: .debug("Added/updated File Attachment: "
300: + BlojsomUtils
301: .getFilenameFromPath(fileAttachment));
302: }
303: } else {
304: if (processBlogEntryEvent.getEntry() != null) {
305: processBlogEntryEvent.getEntry().getMetaData()
306: .remove(METADATA_FILE_ATTACHMENT);
307: }
308: processBlogEntryEvent.getContext().remove(
309: FILE_ATTACHMENT);
310: }
311: }
312:
313: resourceFilesMap = new TreeMap(resourceFilesMap);
314: processBlogEntryEvent.getContext().put(
315: "PLUGIN_FILE_ATTACHMENT_FILES", resourceFilesMap);
316: }
317: }
318:
319: /**
320: * File Attachment
321: *
322: * @author Sopan Shewale
323: */
324: public class FileAttachment {
325: private String url;
326: private String name;
327:
328: /**
329: * Contruct an File Attachment
330: *
331: * @param url URL to retrive the attached file
332: * @param name retrive the name of the File
333: */
334: public FileAttachment(String url, String name) {
335: this .url = url;
336: this .name = name;
337:
338: }
339:
340: /**
341: * get the URL for the attachment
342: *
343: * @return URL for the attachment
344: */
345: public String getUrl() {
346: return url;
347:
348: }
349:
350: /**
351: * Get the name of the attachment
352: *
353: * @return Name of the attachment
354: */
355: public String getName() {
356: return name;
357:
358: }
359:
360: }
361:
362: }
|