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.admin;
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.Category;
036: import org.blojsom.blog.Entry;
037: import org.blojsom.event.EventBroadcaster;
038: import org.blojsom.fetcher.Fetcher;
039: import org.blojsom.fetcher.FetcherException;
040: import org.blojsom.plugin.PluginException;
041: import org.blojsom.plugin.admin.event.CategoryAddedEvent;
042: import org.blojsom.plugin.admin.event.CategoryDeletedEvent;
043: import org.blojsom.plugin.admin.event.CategoryUpdatedEvent;
044: import org.blojsom.util.BlojsomUtils;
045: import org.blojsom.util.BlojsomConstants;
046:
047: import javax.servlet.http.HttpServletRequest;
048: import javax.servlet.http.HttpServletResponse;
049: import java.io.BufferedReader;
050: import java.io.IOException;
051: import java.io.StringReader;
052: import java.util.Date;
053: import java.util.HashMap;
054: import java.util.Iterator;
055: import java.util.Map;
056:
057: /**
058: * EditBlogCategoriesPlugin
059: *
060: * @author David Czarnecki
061: * @version $Id: EditBlogCategoriesPlugin.java,v 1.5 2007/01/17 02:35:05 czarneckid Exp $
062: * @since blojsom 3.0
063: */
064: public class EditBlogCategoriesPlugin extends BaseAdminPlugin {
065:
066: private static Log _logger = LogFactory
067: .getLog(EditBlogCategoriesPlugin.class);
068:
069: // Localization constants
070: private static final String FAILED_PERMISSION_KEY = "failed.permission.text";
071: private static final String DELETED_CATEGORY_KEY = "deleted.category.text";
072: private static final String FAILED_DELETED_CATEGORY_KEY = "failed.deleted.category.text";
073: private static final String FAILED_LOAD_CATEGORY_KEY = "failed.load.category.text";
074: private static final String NO_CATEGORY_SPECIFIED_KEY = "no.category.specified.text";
075: private static final String FAILED_CATEGORY_METADATA_READ_KEY = "failed.category.metadata.read.text";
076: private static final String CATEGORY_ADD_SUCCESS_KEY = "category.add.success.text";
077: private static final String CATEGORY_UPDATE_SUCCESS_KEY = "category.update.success.text";
078: private static final String CATEGORY_CHANGE_FAILED_KEY = "category.change.failed.text";
079:
080: // Pages
081: private static final String EDIT_BLOG_CATEGORIES_PAGE = "/org/blojsom/plugin/admin/templates/admin-edit-blog-categories";
082: private static final String EDIT_BLOG_CATEGORY_PAGE = "/org/blojsom/plugin/admin/templates/admin-edit-blog-category";
083:
084: // Constants
085: private static final String BLOJSOM_PLUGIN_EDIT_BLOG_CATEGORIES_CATEGORY = "BLOJSOM_PLUGIN_EDIT_BLOG_CATEGORIES_CATEGORY";
086: private static final String BLOJSOM_PLUGIN_EDIT_BLOG_CATEGORIES_CATEGORY_METADATA = "BLOJSOM_PLUGIN_EDIT_BLOG_CATEGORIES_CATEGORY_METADATA";
087: private static final String BLOJSOM_PLUGIN_EDIT_BLOG_CATEGORIES_ALL_CATEGORIES = "BLOJSOM_PLUGIN_EDIT_BLOG_CATEGORIES_ALL_CATEGORIES";
088:
089: // Actions
090: private static final String ADD_BLOG_CATEGORY_ACTION = "add-blog-category";
091: private static final String DELETE_BLOG_CATEGORY_ACTION = "delete-blog-category";
092: private static final String EDIT_BLOG_CATEGORY_ACTION = "edit-blog-category";
093: private static final String UPDATE_BLOG_CATEGORY_ACTION = "update-blog-category";
094:
095: // Form elements
096: private static final String BLOG_CATEGORY_ID = "blog-category-id";
097: private static final String BLOG_CATEGORY_PARENT_ID = "blog-category-parent-id";
098: private static final String BLOG_CATEGORY_NAME = "blog-category-name";
099: private static final String BLOG_CATEGORY_DESCRIPTION = "blog-category-description";
100: private static final String BLOG_CATEGORY_META_DATA = "blog-category-meta-data";
101:
102: private static final String EDIT_BLOG_CATEGORIES_PERMISSION = "edit_blog_categories_permission";
103:
104: private Fetcher _fetcher;
105: private EventBroadcaster _eventBroadcaster;
106:
107: /**
108: * Default constructor.
109: */
110: public EditBlogCategoriesPlugin() {
111: }
112:
113: /**
114: * Set the {@link Fetcher}
115: *
116: * @param fetcher {@link Fetcher}
117: */
118: public void setFetcher(Fetcher fetcher) {
119: _fetcher = fetcher;
120: }
121:
122: /**
123: * Set the {@link EventBroadcaster}
124: *
125: * @param eventBroadcaster {@link EventBroadcaster}
126: */
127: public void setEventBroadcaster(EventBroadcaster eventBroadcaster) {
128: _eventBroadcaster = eventBroadcaster;
129: }
130:
131: /**
132: * Get the display name for a category prefering the description over the name
133: *
134: * @param category {@link Category}
135: * @return Display name (Description if available, otherwise Name)
136: */
137: protected String getDisplayName(Category category) {
138: if (!BlojsomUtils.checkNullOrBlank(category.getDescription())) {
139: return category.getDescription();
140: }
141:
142: return category.getName();
143: }
144:
145: /**
146: * Process the blog entries
147: *
148: * @param httpServletRequest Request
149: * @param httpServletResponse Response
150: * @param blog {@link Blog} instance
151: * @param context Context
152: * @param entries Blog entries retrieved for the particular request
153: * @return Modified set of blog entries
154: * @throws PluginException If there is an error processing the blog entries
155: */
156: public Entry[] process(HttpServletRequest httpServletRequest,
157: HttpServletResponse httpServletResponse, Blog blog,
158: Map context, Entry[] entries) throws PluginException {
159: if (!authenticateUser(httpServletRequest, httpServletResponse,
160: context, blog)) {
161: httpServletRequest.setAttribute(
162: BlojsomConstants.PAGE_PARAM, ADMIN_LOGIN_PAGE);
163:
164: return entries;
165: }
166:
167: String action = BlojsomUtils.getRequestValue(ACTION_PARAM,
168: httpServletRequest);
169: try {
170: Category[] allCategories = _fetcher.loadAllCategories(blog);
171: context.put(
172: BLOJSOM_PLUGIN_EDIT_BLOG_CATEGORIES_ALL_CATEGORIES,
173: allCategories);
174: } catch (FetcherException e) {
175: if (_logger.isErrorEnabled()) {
176: _logger.error(e);
177: }
178: }
179:
180: String username = getUsernameFromSession(httpServletRequest,
181: blog);
182: if (!checkPermission(blog, null, username,
183: EDIT_BLOG_CATEGORIES_PERMISSION)) {
184: httpServletRequest.setAttribute(
185: BlojsomConstants.PAGE_PARAM,
186: ADMIN_ADMINISTRATION_PAGE);
187: addOperationResultMessage(context, getAdminResource(
188: FAILED_PERMISSION_KEY, FAILED_PERMISSION_KEY, blog
189: .getBlogAdministrationLocale()));
190:
191: return entries;
192: }
193:
194: if (BlojsomUtils.checkNullOrBlank(action)) {
195: if (_logger.isDebugEnabled()) {
196: _logger.debug("User did not request edit action");
197: }
198: httpServletRequest.setAttribute(
199: BlojsomConstants.PAGE_PARAM,
200: ADMIN_ADMINISTRATION_PAGE);
201: } else if (PAGE_ACTION.equals(action)) {
202: if (_logger.isDebugEnabled()) {
203: _logger.debug("User requested edit categories page");
204: }
205: httpServletRequest.setAttribute(
206: BlojsomConstants.PAGE_PARAM,
207: EDIT_BLOG_CATEGORIES_PAGE);
208: } else if (DELETE_BLOG_CATEGORY_ACTION.equals(action)) {
209: if (_logger.isDebugEnabled()) {
210: _logger
211: .debug("User request blog category delete action");
212: }
213: String blogCategoryId = BlojsomUtils.getRequestValue(
214: BLOG_CATEGORY_ID, httpServletRequest);
215: if (_logger.isDebugEnabled()) {
216: _logger.debug("Delting blog category: "
217: + blogCategoryId);
218: }
219:
220: try {
221: Integer categoryID = Integer.valueOf(blogCategoryId);
222: Category blogCategoryToDelete = _fetcher.newCategory();
223: blogCategoryToDelete.setId(categoryID);
224: _fetcher.loadCategory(blog, blogCategoryToDelete);
225: _fetcher.deleteCategory(blog, blogCategoryToDelete);
226:
227: if (_logger.isDebugEnabled()) {
228: _logger.debug("Deleted blog category: "
229: + blogCategoryId);
230: }
231: addOperationResultMessage(
232: context,
233: formatAdminResource(
234: DELETED_CATEGORY_KEY,
235: DELETED_CATEGORY_KEY,
236: blog.getBlogAdministrationLocale(),
237: new Object[] { getDisplayName(blogCategoryToDelete) }));
238:
239: _eventBroadcaster
240: .broadcastEvent(new CategoryDeletedEvent(this ,
241: new Date(), blogCategoryToDelete, blog));
242: } catch (NumberFormatException e) {
243: addOperationResultMessage(context, formatAdminResource(
244: FAILED_DELETED_CATEGORY_KEY,
245: FAILED_DELETED_CATEGORY_KEY, blog
246: .getBlogAdministrationLocale(),
247: new Object[] { blogCategoryId }));
248: } catch (FetcherException e) {
249: if (_logger.isErrorEnabled()) {
250: _logger.error(e);
251: }
252:
253: addOperationResultMessage(context, formatAdminResource(
254: FAILED_DELETED_CATEGORY_KEY,
255: FAILED_DELETED_CATEGORY_KEY, blog
256: .getBlogAdministrationLocale(),
257: new Object[] { blogCategoryId }));
258: }
259:
260: httpServletRequest.setAttribute(
261: BlojsomConstants.PAGE_PARAM,
262: EDIT_BLOG_CATEGORIES_PAGE);
263: } else if (EDIT_BLOG_CATEGORY_ACTION.equals(action)) {
264: String blogCategoryId = BlojsomUtils.getRequestValue(
265: BLOG_CATEGORY_ID, httpServletRequest);
266: if (_logger.isDebugEnabled()) {
267: _logger.debug("Editing blog category: "
268: + blogCategoryId);
269: }
270: Category blogCategoryToEdit;
271:
272: try {
273: Integer categoryID = Integer.valueOf(blogCategoryId);
274: blogCategoryToEdit = _fetcher.newCategory();
275: blogCategoryToEdit.setId(categoryID);
276: _fetcher.loadCategory(blog, blogCategoryToEdit);
277:
278: context.put(
279: BLOJSOM_PLUGIN_EDIT_BLOG_CATEGORIES_CATEGORY,
280: blogCategoryToEdit);
281:
282: StringBuffer categoryPropertiesString = new StringBuffer();
283: Iterator keyIterator = blogCategoryToEdit.getMetaData()
284: .keySet().iterator();
285: Object key;
286: while (keyIterator.hasNext()) {
287: key = keyIterator.next();
288: categoryPropertiesString.append(key.toString())
289: .append("=").append(
290: blogCategoryToEdit.getMetaData()
291: .get(key)).append("\r\n");
292: }
293:
294: context
295: .put(
296: BLOJSOM_PLUGIN_EDIT_BLOG_CATEGORIES_CATEGORY_METADATA,
297: categoryPropertiesString.toString());
298: } catch (NumberFormatException e) {
299: addOperationResultMessage(context, formatAdminResource(
300: FAILED_LOAD_CATEGORY_KEY,
301: FAILED_LOAD_CATEGORY_KEY, blog
302: .getBlogAdministrationLocale(),
303: new Object[] { blogCategoryId }));
304: } catch (FetcherException e) {
305: if (_logger.isErrorEnabled()) {
306: _logger.error(e);
307: }
308:
309: addOperationResultMessage(context, formatAdminResource(
310: FAILED_LOAD_CATEGORY_KEY,
311: FAILED_LOAD_CATEGORY_KEY, blog
312: .getBlogAdministrationLocale(),
313: new Object[] { blogCategoryId }));
314: }
315:
316: httpServletRequest.setAttribute(
317: BlojsomConstants.PAGE_PARAM,
318: EDIT_BLOG_CATEGORY_PAGE);
319: } else if (ADD_BLOG_CATEGORY_ACTION.equals(action)
320: || UPDATE_BLOG_CATEGORY_ACTION.equals(action)) {
321: boolean isUpdatingCategory = UPDATE_BLOG_CATEGORY_ACTION
322: .equals(action);
323:
324: String blogCategoryName = BlojsomUtils.getRequestValue(
325: BLOG_CATEGORY_NAME, httpServletRequest);
326: // Check for blank or null category
327: if (BlojsomUtils.checkNullOrBlank(blogCategoryName)) {
328: httpServletRequest.setAttribute(
329: BlojsomConstants.PAGE_PARAM,
330: EDIT_BLOG_CATEGORIES_PAGE);
331: addOperationResultMessage(context, getAdminResource(
332: NO_CATEGORY_SPECIFIED_KEY,
333: NO_CATEGORY_SPECIFIED_KEY, blog
334: .getBlogAdministrationLocale()));
335:
336: return entries;
337: }
338:
339: blogCategoryName = BlojsomUtils.normalize(blogCategoryName);
340: blogCategoryName = BlojsomUtils
341: .addSlashes(blogCategoryName);
342:
343: String blogCategoryId = BlojsomUtils.getRequestValue(
344: BLOG_CATEGORY_ID, httpServletRequest);
345: String blogCategoryParentId = BlojsomUtils.getRequestValue(
346: BLOG_CATEGORY_PARENT_ID, httpServletRequest);
347: String blogCategoryDescription = BlojsomUtils
348: .getRequestValue(BLOG_CATEGORY_DESCRIPTION,
349: httpServletRequest);
350:
351: if (!isUpdatingCategory) {
352: if (_logger.isDebugEnabled()) {
353: _logger.debug("Adding blog category: "
354: + blogCategoryName);
355: }
356: } else {
357: if (_logger.isDebugEnabled()) {
358: _logger.debug("Updating blog category: "
359: + blogCategoryName);
360: }
361: }
362:
363: String blogCategoryMetaData = BlojsomUtils.getRequestValue(
364: BLOG_CATEGORY_META_DATA, httpServletRequest);
365: if (blogCategoryMetaData == null) {
366: blogCategoryMetaData = "";
367: }
368:
369: if (!isUpdatingCategory) {
370: if (_logger.isDebugEnabled()) {
371: _logger.debug("Adding blog category meta-data: "
372: + blogCategoryMetaData);
373: }
374: }
375:
376: // Separate the blog category meta-data into key/value pairs
377: BufferedReader br = new BufferedReader(new StringReader(
378: blogCategoryMetaData));
379: String input;
380: String[] splitInput;
381: Map categoryMetaData = new HashMap();
382: try {
383: while ((input = br.readLine()) != null) {
384: splitInput = input.split("=");
385: if (splitInput.length == 2) {
386: categoryMetaData.put(splitInput[0],
387: splitInput[1]);
388: }
389: }
390: } catch (IOException e) {
391: if (_logger.isErrorEnabled()) {
392: _logger.error(e);
393: }
394:
395: addOperationResultMessage(context, getAdminResource(
396: FAILED_CATEGORY_METADATA_READ_KEY,
397: FAILED_CATEGORY_METADATA_READ_KEY, blog
398: .getBlogAdministrationLocale()));
399: }
400:
401: Integer parentCategoryID = new Integer(0);
402: try {
403: parentCategoryID = Integer
404: .valueOf(blogCategoryParentId);
405: } catch (NumberFormatException e) {
406: }
407:
408: Category blogCategory;
409: if (!isUpdatingCategory) {
410: blogCategory = _fetcher.newCategory();
411: } else {
412: try {
413: blogCategory = _fetcher.newCategory();
414: Integer categoryID = Integer
415: .valueOf(blogCategoryId);
416: blogCategory.setId(categoryID);
417:
418: _fetcher.loadCategory(blog, blogCategory);
419: } catch (NumberFormatException e) {
420: addOperationResultMessage(context,
421: formatAdminResource(
422: CATEGORY_CHANGE_FAILED_KEY,
423: CATEGORY_CHANGE_FAILED_KEY,
424: blog.getBlogAdministrationLocale(),
425: new Object[] { blogCategoryId }));
426: httpServletRequest.setAttribute(
427: BlojsomConstants.PAGE_PARAM,
428: EDIT_BLOG_CATEGORIES_PAGE);
429:
430: return entries;
431: } catch (FetcherException e) {
432: if (_logger.isErrorEnabled()) {
433: _logger.error(e);
434: }
435:
436: addOperationResultMessage(context,
437: formatAdminResource(
438: CATEGORY_CHANGE_FAILED_KEY,
439: CATEGORY_CHANGE_FAILED_KEY,
440: blog.getBlogAdministrationLocale(),
441: new Object[] { blogCategoryId }));
442: httpServletRequest.setAttribute(
443: BlojsomConstants.PAGE_PARAM,
444: EDIT_BLOG_CATEGORIES_PAGE);
445:
446: return entries;
447: }
448: }
449:
450: if (!BlojsomUtils.checkNullOrBlank(blogCategoryParentId)) {
451: blogCategory.setParentCategoryId(parentCategoryID);
452: } else {
453: blogCategory.setParentCategoryId(null);
454: }
455:
456: blogCategory.setName(blogCategoryName);
457: blogCategory.setDescription(blogCategoryDescription);
458: blogCategory.setBlogId(blog.getId());
459: blogCategory.setMetaData(categoryMetaData);
460:
461: try {
462: _fetcher.saveCategory(blog, blogCategory);
463:
464: if (!isUpdatingCategory) {
465: if (_logger.isDebugEnabled()) {
466: _logger
467: .debug("Successfully added new blog category: "
468: + blogCategoryName);
469: }
470:
471: addOperationResultMessage(
472: context,
473: formatAdminResource(
474: CATEGORY_ADD_SUCCESS_KEY,
475: CATEGORY_ADD_SUCCESS_KEY,
476: blog.getBlogAdministrationLocale(),
477: new Object[] { getDisplayName(blogCategory) }));
478:
479: _eventBroadcaster
480: .broadcastEvent(new CategoryAddedEvent(
481: this , new Date(), blogCategory,
482: blog));
483: } else {
484: if (_logger.isDebugEnabled()) {
485: _logger
486: .debug("Successfully updated blog category: "
487: + blogCategoryName);
488: }
489:
490: addOperationResultMessage(
491: context,
492: formatAdminResource(
493: CATEGORY_UPDATE_SUCCESS_KEY,
494: CATEGORY_UPDATE_SUCCESS_KEY,
495: blog.getBlogAdministrationLocale(),
496: new Object[] { getDisplayName(blogCategory) }));
497:
498: _eventBroadcaster
499: .broadcastEvent(new CategoryUpdatedEvent(
500: this , new Date(), blogCategory,
501: blog));
502: }
503: } catch (FetcherException e) {
504: if (_logger.isErrorEnabled()) {
505: _logger.error(e);
506: }
507:
508: addOperationResultMessage(context, formatAdminResource(
509: CATEGORY_CHANGE_FAILED_KEY,
510: CATEGORY_CHANGE_FAILED_KEY, blog
511: .getBlogAdministrationLocale(),
512: new Object[] { getDisplayName(blogCategory) }));
513: }
514:
515: httpServletRequest.setAttribute(
516: BlojsomConstants.PAGE_PARAM,
517: EDIT_BLOG_CATEGORIES_PAGE);
518: }
519:
520: try {
521: Category[] allCategories = _fetcher.loadAllCategories(blog);
522: context.put(
523: BLOJSOM_PLUGIN_EDIT_BLOG_CATEGORIES_ALL_CATEGORIES,
524: allCategories);
525: } catch (FetcherException e) {
526: if (_logger.isErrorEnabled()) {
527: _logger.error(e);
528: }
529: }
530:
531: return entries;
532: }
533: }
|