You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@roller.apache.org by sn...@apache.org on 2006/05/02 00:23:34 UTC
svn commit: r398712 [14/32] - in /incubator/roller/trunk/src/org/apache: ./
roller/ roller/business/ roller/business/hibernate/
roller/business/referrers/ roller/business/runnable/
roller/business/search/ roller/business/search/operations/ roller/busin...
Added: incubator/roller/trunk/src/org/apache/roller/presentation/bookmarks/actions/BookmarksAction.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/apache/roller/presentation/bookmarks/actions/BookmarksAction.java?rev=398712&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/apache/roller/presentation/bookmarks/actions/BookmarksAction.java (added)
+++ incubator/roller/trunk/src/org/apache/roller/presentation/bookmarks/actions/BookmarksAction.java Mon May 1 15:23:02 2006
@@ -0,0 +1,381 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. The ASF licenses this file to You
+* under the Apache License, Version 2.0 (the "License"); you may not
+* use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License. For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+/*
+ * Created on Oct 21, 2003
+ */
+package org.apache.roller.presentation.bookmarks.actions;
+
+import java.text.MessageFormat;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+import java.util.LinkedList;
+import java.util.Set;
+import java.util.TreeSet;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.struts.action.ActionError;
+import org.apache.struts.action.ActionErrors;
+import org.apache.struts.action.ActionForm;
+import org.apache.struts.action.ActionForward;
+import org.apache.struts.action.ActionMapping;
+import org.apache.struts.action.ActionMessage;
+import org.apache.struts.action.ActionMessages;
+import org.apache.struts.actions.DispatchAction;
+import org.apache.roller.RollerException;
+import org.apache.roller.model.BookmarkManager;
+import org.apache.roller.model.Roller;
+import org.apache.roller.model.RollerFactory;
+import org.apache.roller.pojos.BookmarkData;
+import org.apache.roller.pojos.FolderData;
+import org.apache.roller.pojos.WebsiteData;
+import org.apache.roller.presentation.BasePageModel;
+import org.apache.roller.presentation.RollerRequest;
+import org.apache.roller.presentation.RollerSession;
+import org.apache.roller.presentation.bookmarks.formbeans.BookmarksForm;
+import org.apache.roller.presentation.cache.CacheManager;
+
+/**
+ * Actions that are initiated from the BookmarksForm.
+ *
+ * @struts.action name="bookmarksForm" path="/editor/bookmarks" parameter="method"
+ * @struts.action-forward name="BookmarksForm" path=".BookmarksForm"
+ *
+ * @author Dave Johnson
+ */
+public class BookmarksAction extends DispatchAction
+{
+ private static Log mLogger =
+ LogFactory.getFactory().getInstance(BookmarksAction.class);
+
+ /**
+ * Present the BookmarksForm loaded with folder specified by request.
+ * @param mapping Action mapping.
+ * @param actionForm Form bean.
+ * @param request Request.
+ * @param response Response.
+ * @return Forward to BookmarksForm or access-denied.
+ * @throws RollerException
+ */
+ public ActionForward selectFolder(
+ ActionMapping mapping,
+ ActionForm actionForm,
+ HttpServletRequest request,
+ HttpServletResponse response)
+ throws RollerException
+ {
+ BookmarksPageModel pageModel = new BookmarksPageModel(
+ request, response, mapping, (BookmarksForm)actionForm);
+ if (RollerSession.getRollerSession(request).isUserAuthorizedToAuthor(
+ pageModel.getFolder().getWebsite()))
+ {
+ request.setAttribute("model", pageModel);
+ return mapping.findForward("BookmarksForm");
+ }
+ else
+ {
+ return mapping.findForward("access-denied");
+ }
+ }
+
+ /**
+ * Delete folders and bookmarks indicated by BookmarksForm bean.
+ * @param mapping Action mapping.
+ * @param actionForm Form bean.
+ * @param request Request.
+ * @param response Response.
+ * @return Forward to BookmarksForm or access-denied.
+ * @throws RollerException
+ */
+ public ActionForward deleteSelected(
+ ActionMapping mapping,
+ ActionForm actionForm,
+ HttpServletRequest request,
+ HttpServletResponse response)
+ throws RollerException
+ {
+ Roller roller = RollerFactory.getRoller();
+ BookmarksPageModel pageModel = new BookmarksPageModel(
+ request, response, mapping, (BookmarksForm)actionForm);
+ WebsiteData website = pageModel.getFolder().getWebsite();
+ if (RollerSession.getRollerSession(request).isUserAuthorizedToAuthor(website))
+ {
+ BookmarkManager bmgr = roller.getBookmarkManager();
+ BookmarksForm form = (BookmarksForm)actionForm;
+
+ mLogger.debug("Deleting folders and bookmarks.");
+
+ String folders[] = form.getSelectedFolders();
+ if (null != folders)
+ {
+ for (int i = 0; i < folders.length; i++)
+ {
+ FolderData fd = bmgr.getFolder(folders[i]);
+ bmgr.removeFolder(fd); // removes child folders and bookmarks too
+ }
+ }
+
+ BookmarkData bookmark = null;
+ String bookmarks[] = form.getSelectedBookmarks();
+ if (null != bookmarks)
+ {
+ for (int j = 0; j < bookmarks.length; j++)
+ {
+ bookmark = bmgr.getBookmark(bookmarks[j]);
+ bmgr.removeBookmark(bookmark);
+ }
+ }
+ RollerFactory.getRoller().flush();
+
+ CacheManager.invalidate(website);
+
+ // recreate model now that folder is deleted
+ pageModel = new BookmarksPageModel(
+ request, response, mapping, (BookmarksForm)actionForm);
+ request.setAttribute("model", pageModel);
+ return mapping.findForward("BookmarksForm");
+ }
+ else
+ {
+ return mapping.findForward("access-denied");
+ }
+ }
+
+ /**
+ * Move folders and bookmarks indicated by BookmarksForm bean.
+ * @param mapping Action mapping.
+ * @param actionForm Form bean.
+ * @param request Request.
+ * @param response Response.
+ * @return Forward to BookmarksForm or access-denied.
+ * @throws RollerException
+ */
+ public ActionForward moveSelected(
+ ActionMapping mapping,
+ ActionForm actionForm,
+ HttpServletRequest request,
+ HttpServletResponse response)
+ throws RollerException
+ {
+ ActionMessages messages = new ActionMessages();
+ ActionForward forward = mapping.findForward("BookmarksForm");
+ Roller roller = RollerFactory.getRoller();
+ BookmarksPageModel pageModel = new BookmarksPageModel(
+ request, response, mapping, (BookmarksForm)actionForm);
+ request.setAttribute("model", pageModel);
+ WebsiteData website = pageModel.getFolder().getWebsite();
+
+ if (RollerSession.getRollerSession(request).isUserAuthorizedToAuthor(website))
+ {
+ try
+ {
+ BookmarkManager bmgr = roller.getBookmarkManager();
+ BookmarksForm form = (BookmarksForm)actionForm;
+
+ mLogger.debug("Moving folders and bookmarks to folder, id="
+ + form.getMoveToFolderId());
+
+ // Move subfolders to new folder.
+ String folders[] = form.getSelectedFolders();
+ FolderData parent = bmgr.getFolder(form.getMoveToFolderId());
+ if (null != folders)
+ {
+ for (int i = 0; i < folders.length; i++)
+ {
+ FolderData fd = bmgr.getFolder(folders[i]);
+
+ // Don't move folder into itself.
+ if ( !fd.getId().equals(parent.getId())
+ && !parent.descendentOf(fd))
+ {
+ fd.setParent(parent);
+ bmgr.saveFolder(fd);
+ }
+ else
+ {
+ messages.add(null, new ActionMessage(
+ "bookmarksForm.warn.notMoving",fd.getName()));
+ }
+ }
+ }
+
+ // Move bookmarks.
+ String bookmarks[] = form.getSelectedBookmarks();
+ if (null != bookmarks)
+ {
+ for (int j = 0; j < bookmarks.length; j++)
+ {
+ // maybe we should be using folder.addBookmark()?
+ BookmarkData bd = bmgr.getBookmark(bookmarks[j]);
+ bd.setFolder(parent);
+ bmgr.saveBookmark(bd);
+ }
+ }
+ RollerFactory.getRoller().flush();
+
+ CacheManager.invalidate(website);
+
+ saveMessages(request, messages);
+
+ // recreate model now that folder is altered
+ pageModel = new BookmarksPageModel(
+ request, response, mapping, (BookmarksForm)actionForm);
+ request.setAttribute("model", pageModel);
+ }
+ catch (RollerException e)
+ {
+ ActionErrors errors = new ActionErrors();
+ errors.add(null, new ActionError("bookmarksForm.error.move"));
+ saveErrors(request, errors);
+ }
+ }
+ else
+ {
+ forward = mapping.findForward("access-denied");
+ }
+ return forward;
+ }
+
+ private static final class FolderPathComparator implements Comparator
+ {
+ public int compare(Object o1, Object o2) {
+ FolderData f1 = (FolderData)o1;
+ FolderData f2 = (FolderData)o2;
+ int res = 0;
+ try
+ {
+ res = f1.getPath().compareTo(f2.getPath());
+ }
+ catch (RollerException e)
+ {
+ mLogger.error("ERROR: sorting folders");
+ }
+ return res;
+ }
+ }
+
+ public class BookmarksPageModel extends BasePageModel
+ {
+ private List folderPath = null;
+ private TreeSet allFolders = null;
+ private FolderData folder = null;
+
+ public BookmarksPageModel(
+ HttpServletRequest request,
+ HttpServletResponse response,
+ ActionMapping mapping,
+ BookmarksForm form) throws RollerException
+ {
+ super("", request, response, mapping);
+
+ RollerRequest rreq = RollerRequest.getRollerRequest(request);
+ RollerSession rollerSession = RollerSession.getRollerSession(request);
+ BookmarkManager bmgr = RollerFactory.getRoller().getBookmarkManager();
+
+ allFolders = new TreeSet(new FolderPathComparator());
+
+ // Find folderid wherever it may be
+ String folderId = (String)
+ request.getAttribute(RollerRequest.FOLDERID_KEY);
+ if (null == folderId)
+ {
+ folderId = request.getParameter(RollerRequest.FOLDERID_KEY);
+ }
+ if (null == folderId)
+ {
+ folderId = form.getFolderId();
+ }
+
+ if (null == folderId || folderId.equals("null"))
+ {
+ website = rreq.getWebsite();
+ folder = bmgr.getRootFolder(website);
+ folderId = folder.getId();
+ }
+ else
+ {
+ folder = bmgr.getFolder(folderId);
+ website = folder.getWebsite();
+ }
+ form.setFolderId(folder.getId());
+
+ if (null != folder.getParent())
+ {
+ folderPath = new LinkedList();
+ folderPath.add(0, folder);
+ FolderData parent = folder.getParent();
+ while (parent != null)
+ {
+ folderPath.add(0, parent);
+ parent = parent.getParent();
+ }
+ request.setAttribute(
+ RollerRequest.PARENTID_KEY, folder.getParent().getId());
+ }
+
+ // Build list of all folders, except for current one, sorted by path.
+ Iterator iter = bmgr.getAllFolders(website).iterator();
+ while (iter.hasNext())
+ {
+ FolderData fd = (FolderData) iter.next();
+ if (!fd.getId().equals(folderId))
+ {
+ allFolders.add(fd);
+ }
+ }
+ if (allFolders.size() > 0) {
+ request.setAttribute("allFolders", allFolders); // for Struts tags
+ } else {
+ allFolders = null;
+ }
+ request.setAttribute("folder", folder); // for Struts tags
+ }
+
+ public String getTitle()
+ {
+ if (folderPath == null || folderPath.isEmpty())
+ {
+ return bundle.getString("bookmarksForm.rootTitle");
+ }
+ else
+ {
+ return MessageFormat.format(
+ bundle.getString("bookmarksForm.folderTitle"),
+ new Object[] {folder.getName()});
+ }
+ }
+ public List getFolderPath()
+ {
+ return folderPath;
+ }
+ public Set getAllFolders()
+ {
+ return allFolders;
+ }
+ public FolderData getFolder()
+ {
+ return folder;
+ }
+
+
+ }
+}
Added: incubator/roller/trunk/src/org/apache/roller/presentation/bookmarks/actions/FolderEditAction.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/apache/roller/presentation/bookmarks/actions/FolderEditAction.java?rev=398712&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/apache/roller/presentation/bookmarks/actions/FolderEditAction.java (added)
+++ incubator/roller/trunk/src/org/apache/roller/presentation/bookmarks/actions/FolderEditAction.java Mon May 1 15:23:02 2006
@@ -0,0 +1,105 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. The ASF licenses this file to You
+* under the Apache License, Version 2.0 (the "License"); you may not
+* use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License. For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+/*
+ * Created on Oct 21, 2003
+ */
+package org.apache.roller.presentation.bookmarks.actions;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.struts.action.Action;
+import org.apache.struts.action.ActionForm;
+import org.apache.struts.action.ActionForward;
+import org.apache.struts.action.ActionMapping;
+import org.apache.roller.model.BookmarkManager;
+import org.apache.roller.model.RollerFactory;
+import org.apache.roller.pojos.FolderData;
+import org.apache.roller.presentation.BasePageModel;
+import org.apache.roller.presentation.RollerRequest;
+import org.apache.roller.presentation.bookmarks.formbeans.FolderFormEx;
+
+/**
+ * @struts.action path="/editor/folderEdit" name="folderFormEx" validate="false"
+ * @struts.action-forward name="FolderForm" path=".FolderForm"
+ *
+ * @author Dave Johnson
+ */
+public class FolderEditAction extends Action
+{
+ public ActionForward execute(
+ ActionMapping mapping,
+ ActionForm actionForm,
+ HttpServletRequest request,
+ HttpServletResponse response)
+ throws Exception
+ {
+ RollerRequest rreq = RollerRequest.getRollerRequest(request);
+ BookmarkManager bmgr = RollerFactory.getRoller().getBookmarkManager();
+ FolderFormEx form = (FolderFormEx)actionForm;
+
+ FolderData parentFolder = null;
+ if (null!=rreq.getFolder() && null==request.getParameter("correct"))
+ {
+ // If request specifies folder and we are not correcting an
+ // already submitted form then load that folder into the form.
+ request.setAttribute("state","edit");
+
+ FolderData fd = rreq.getFolder();
+ form.copyFrom(fd, request.getLocale());
+ parentFolder = fd.getParent();
+
+ BasePageModel pageModel = new BasePageModel(
+ "folderForm.add.title", request, response, mapping);
+ pageModel.setWebsite(parentFolder.getWebsite());
+ request.setAttribute("model", pageModel);
+ }
+ else if (null != request.getParameter("correct"))
+ {
+ // We are correcting a previously submtted form.
+ request.setAttribute("state","correcting");
+
+ String parentId = request.getParameter(RollerRequest.PARENTID_KEY);
+ parentFolder = bmgr.getFolder(parentId);
+
+ BasePageModel pageModel = new BasePageModel(
+ "folderForm.correct.title", request, response, mapping);
+ pageModel.setWebsite(parentFolder.getWebsite());
+ request.setAttribute("model", pageModel);
+ }
+ else
+ {
+ // We are adding a new bookmark
+ request.setAttribute("state","add");
+
+ String parentId = request.getParameter(RollerRequest.PARENTID_KEY);
+ parentFolder = bmgr.getFolder(parentId);
+
+ BasePageModel pageModel = new BasePageModel(
+ "folderForm.add.title", request, response, mapping);
+ pageModel.setWebsite(parentFolder.getWebsite());
+ request.setAttribute("model", pageModel);
+ }
+
+ request.setAttribute(RollerRequest.PARENTID_KEY, parentFolder.getId());
+ request.setAttribute("parentFolder", parentFolder);
+
+ return mapping.findForward("FolderForm");
+ }
+
+}
Added: incubator/roller/trunk/src/org/apache/roller/presentation/bookmarks/actions/FolderSaveAction.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/apache/roller/presentation/bookmarks/actions/FolderSaveAction.java?rev=398712&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/apache/roller/presentation/bookmarks/actions/FolderSaveAction.java (added)
+++ incubator/roller/trunk/src/org/apache/roller/presentation/bookmarks/actions/FolderSaveAction.java Mon May 1 15:23:02 2006
@@ -0,0 +1,105 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. The ASF licenses this file to You
+* under the Apache License, Version 2.0 (the "License"); you may not
+* use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License. For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+/*
+ * Created on Oct 21, 2003
+ */
+package org.apache.roller.presentation.bookmarks.actions;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.struts.action.Action;
+import org.apache.struts.action.ActionError;
+import org.apache.struts.action.ActionErrors;
+import org.apache.struts.action.ActionForm;
+import org.apache.struts.action.ActionForward;
+import org.apache.struts.action.ActionMapping;
+import org.apache.roller.model.BookmarkManager;
+import org.apache.roller.model.RollerFactory;
+import org.apache.roller.pojos.FolderData;
+import org.apache.roller.pojos.PermissionsData;
+import org.apache.roller.pojos.WebsiteData;
+import org.apache.roller.presentation.RollerRequest;
+import org.apache.roller.presentation.RollerSession;
+import org.apache.roller.presentation.bookmarks.formbeans.FolderFormEx;
+import org.apache.roller.presentation.cache.CacheManager;
+
+/**
+ * @struts.action path="/editor/folderSave" name="folderFormEx"
+ * validate="true" input="/editor/folderEdit.do"
+ * @struts.action-forward name="Bookmarks" path="/editor/bookmarks.do?method=selectFolder"
+ *
+ * @author Dave Johnson
+ */
+public class FolderSaveAction extends Action
+{
+ public ActionForward execute(
+ ActionMapping mapping,
+ ActionForm actionForm,
+ HttpServletRequest request,
+ HttpServletResponse response)
+ throws Exception
+ {
+ ActionForward forward = mapping.findForward("Bookmarks");
+ FolderFormEx form = (FolderFormEx)actionForm;
+ RollerRequest rreq = RollerRequest.getRollerRequest(request);
+ RollerSession rses = RollerSession.getRollerSession(request);
+ BookmarkManager bmgr = RollerFactory.getRoller().getBookmarkManager();
+ WebsiteData website = null;
+
+ FolderData fd = null;
+ if (null != form.getId() && !form.getId().trim().equals(""))
+ {
+ fd = bmgr.getFolder(form.getId());
+ website = fd.getWebsite();
+ }
+ else
+ {
+ fd = new FolderData();
+ String parentId = request.getParameter(RollerRequest.PARENTID_KEY);
+ FolderData parent = bmgr.getFolder(parentId);
+ website = parent.getWebsite();
+ fd.setParent(parent);
+ fd.setWebsite(website);
+ }
+
+ if (fd.getWebsite().hasUserPermissions(
+ rses.getAuthenticatedUser(), PermissionsData.AUTHOR))
+ {
+ // Copy form values to object
+ form.copyTo(fd, request.getLocale());
+ bmgr.saveFolder(fd);
+ RollerFactory.getRoller().flush();
+
+ CacheManager.invalidate(fd);
+ }
+ else
+ {
+ ActionErrors errors = new ActionErrors();
+ errors.add(null, new ActionError("error.permissions.deniedSave"));
+ saveErrors(request, errors);
+ forward = mapping.findForward("access-denied");
+ }
+ if (null != fd.getParent())
+ {
+ request.setAttribute(
+ RollerRequest.FOLDERID_KEY, fd.getParent().getId());
+ }
+ return forward;
+ }
+}
Added: incubator/roller/trunk/src/org/apache/roller/presentation/bookmarks/actions/ImportBookmarksFormAction.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/apache/roller/presentation/bookmarks/actions/ImportBookmarksFormAction.java?rev=398712&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/apache/roller/presentation/bookmarks/actions/ImportBookmarksFormAction.java (added)
+++ incubator/roller/trunk/src/org/apache/roller/presentation/bookmarks/actions/ImportBookmarksFormAction.java Mon May 1 15:23:02 2006
@@ -0,0 +1,198 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. The ASF licenses this file to You
+* under the Apache License, Version 2.0 (the "License"); you may not
+* use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License. For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+
+package org.apache.roller.presentation.bookmarks.actions;
+
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.struts.action.Action;
+import org.apache.struts.action.ActionError;
+import org.apache.struts.action.ActionErrors;
+import org.apache.struts.action.ActionForm;
+import org.apache.struts.action.ActionForward;
+import org.apache.struts.action.ActionMapping;
+import org.apache.struts.upload.FormFile;
+import org.apache.roller.model.BookmarkManager;
+import org.apache.roller.model.RollerFactory;
+import org.apache.roller.presentation.RollerRequest;
+import org.apache.roller.presentation.bookmarks.formbeans.FolderFormEx;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import org.apache.struts.action.ActionMessage;
+import org.apache.struts.action.ActionMessages;
+import org.apache.roller.RollerException;
+import org.apache.roller.model.Roller;
+import org.apache.roller.pojos.FolderData;
+import org.apache.roller.pojos.WebsiteData;
+import org.apache.roller.presentation.BasePageModel;
+import org.apache.roller.presentation.RollerSession;
+import org.apache.roller.presentation.cache.CacheManager;
+
+/////////////////////////////////////////////////////////////////////////////
+/**
+ * @struts.action name="folderFormEx" path="/editor/importBookmarks"
+ * scope="request" input=".import" validate="false"
+ *
+ * @struts.action-forward name="importBookmarks.page" path=".import"
+ *
+ * TODO Should import into folder with same name as imported file
+ */
+public final class ImportBookmarksFormAction extends Action {
+
+ private static final String HANDLE = "opmlupload.website.handle";
+ private static Log mLogger =
+ LogFactory.getFactory().getInstance(RollerRequest.class);
+
+ /**
+ * Request to import bookmarks
+ */
+ public ActionForward execute(
+ ActionMapping mapping,
+ ActionForm actionForm,
+ HttpServletRequest request,
+ HttpServletResponse response)
+ throws Exception {
+
+ ActionErrors errors = new ActionErrors();
+ FolderFormEx theForm = (FolderFormEx)actionForm;
+ ActionForward fwd = mapping.findForward("importBookmarks.page");
+
+ RollerRequest rreq = RollerRequest.getRollerRequest(request);
+ RollerSession rses = RollerSession.getRollerSession(request);
+ BookmarkManager bm = RollerFactory.getRoller().getBookmarkManager();
+
+ BasePageModel pageModel = new BasePageModel(
+ "bookmarksImport.title", request, response, mapping);
+ request.setAttribute("model", pageModel);
+
+ WebsiteData website = getWebsite(request);
+ pageModel.setWebsite(website);
+
+ // if user authorized and a file is being uploaded
+ if (rses.isUserAuthorizedToAuthor(website) && theForm.getBookmarksFile() != null) {
+
+ // this line is here for when the input page is upload-utf8.jsp,
+ // it sets the correct character encoding for the response
+ String encoding = request.getCharacterEncoding();
+ if ((encoding != null) && (encoding.equalsIgnoreCase("utf-8"))) {
+ response.setContentType("text/html; charset=utf-8");
+ }
+ boolean writeFile = false;
+
+ //retrieve the file representation
+ FormFile file = theForm.getBookmarksFile();
+ String data = null;
+ InputStream stream = null;
+ try {
+
+ //retrieve the file data
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ stream = file.getInputStream();
+ if (!writeFile) {
+ //only write files out that are less than 1MB
+ if (file.getFileSize() < (4*1024000)) {
+
+ byte[] buffer = new byte[8192];
+ int bytesRead = 0;
+ while ((bytesRead=stream.read(buffer,0,8192)) != -1) {
+ baos.write(buffer, 0, bytesRead);
+ }
+ data = new String(baos.toByteArray());
+
+ SimpleDateFormat formatter =
+ new SimpleDateFormat("yyyyMMddHHmmss");
+ Date now = new Date();
+ String folderName = "imported-" + formatter.format(now);
+
+ // Use Roller BookmarkManager to import bookmarks
+
+ bm.importBookmarks(website, folderName, data);
+ RollerFactory.getRoller().flush();
+ CacheManager.invalidate(website);
+
+ ActionMessages messages = new ActionMessages();
+ messages.add(ActionMessages.GLOBAL_MESSAGE,
+ new ActionMessage("bookmarksImport.imported", folderName));
+ saveMessages(request, messages);
+ }
+ else {
+ data = "The file is greater than 4MB, "
+ +" and has not been written to stream."
+ +" File Size: "+file.getFileSize()+" bytes. "
+ +" This is a limitation of this particular "
+ +" web application, hard-coded in "
+ +" org.apache.struts.webapp.upload.UploadAction";
+ errors.add(ActionErrors.GLOBAL_ERROR,
+ new ActionError("bookmarksImport.error",data));
+ }
+ }
+
+ }
+ catch (Exception e) {
+ errors.add(ActionErrors.GLOBAL_ERROR,
+ new ActionError("bookmarksImport.error",e.toString()));
+ saveErrors(request,errors);
+ mLogger.error("ERROR: importing bookmarks",e);
+ }
+ finally {
+ if ( stream!=null ) {
+ try { stream.close(); }
+ catch (Exception e) { mLogger.error("Closing stream",e); };
+ }
+ }
+ //destroy the temporary file created
+ file.destroy();
+ }
+ else if (!rses.isUserAuthorizedToAuthor(website)) {
+ fwd = mapping.findForward("access-denied");
+ }
+ return fwd;
+ }
+
+ /**
+ * Other actions can get the website handle from request params, but
+ * request params don't come accross in a file-upload post so we have to
+ * stash the website handle in the session.
+ */
+ public static WebsiteData getWebsite(HttpServletRequest request) throws RollerException {
+ RollerRequest rreq = RollerRequest.getRollerRequest(request);
+ WebsiteData website = rreq.getWebsite();
+ String folderid = request.getParameter(RollerRequest.FOLDERID_KEY);
+ if (website == null && folderid != null) {
+ BookmarkManager bm = RollerFactory.getRoller().getBookmarkManager();
+ FolderData folder = bm.getFolder(folderid);
+ website = folder.getWebsite();
+ }
+ if (website != null) {
+ request.getSession().setAttribute(HANDLE, website.getHandle());
+ }
+ else {
+ String handle = (String)request.getSession().getAttribute(HANDLE);
+ Roller roller = RollerFactory.getRoller();
+ website = roller.getUserManager().getWebsiteByHandle(handle);
+ }
+ return website;
+ }
+}
+
Added: incubator/roller/trunk/src/org/apache/roller/presentation/bookmarks/actions/package.html
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/apache/roller/presentation/bookmarks/actions/package.html?rev=398712&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/apache/roller/presentation/bookmarks/actions/package.html (added)
+++ incubator/roller/trunk/src/org/apache/roller/presentation/bookmarks/actions/package.html Mon May 1 15:23:02 2006
@@ -0,0 +1,27 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. The ASF licenses this file to You
+ under the Apache License, Version 2.0 (the "License"); you may not
+ use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License. For additional information regarding
+ copyright in this work, please see the NOTICE file in the top level
+ directory of this distribution.
+-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+ <title></title>
+</head>
+<body>
+Struts actions for bookmarks and folders.
+
+</body>
+</html>
Added: incubator/roller/trunk/src/org/apache/roller/presentation/bookmarks/formbeans/BookmarkFormEx.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/apache/roller/presentation/bookmarks/formbeans/BookmarkFormEx.java?rev=398712&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/apache/roller/presentation/bookmarks/formbeans/BookmarkFormEx.java (added)
+++ incubator/roller/trunk/src/org/apache/roller/presentation/bookmarks/formbeans/BookmarkFormEx.java Mon May 1 15:23:02 2006
@@ -0,0 +1,77 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. The ASF licenses this file to You
+* under the Apache License, Version 2.0 (the "License"); you may not
+* use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License. For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+/*
+ * Created on Apr 8, 2003
+ */
+package org.apache.roller.presentation.bookmarks.formbeans;
+
+import org.apache.roller.RollerException;
+import org.apache.roller.pojos.BookmarkData;
+import org.apache.roller.presentation.forms.BookmarkForm;
+
+/**
+ * Extends the BookmarkForm so that additional properties may be added.
+ * These properties are not persistent and are only needed for the UI.
+ *
+ * @struts.form name="bookmarkFormEx"
+ */
+public class BookmarkFormEx extends BookmarkForm
+{
+ private String mFolderId = null;
+
+ /**
+ *
+ */
+ public BookmarkFormEx()
+ {
+ super();
+ }
+
+ /**
+ * @param dataHolder
+ */
+ public BookmarkFormEx(BookmarkData dataHolder, java.util.Locale locale) throws RollerException
+ {
+ copyFrom(dataHolder, locale);
+ }
+
+ /**
+ * @return
+ */
+ public String getFolderId()
+ {
+ return mFolderId;
+ }
+
+ /**
+ * @param string
+ */
+ public void setFolderId(String string)
+ {
+ mFolderId = string;
+ }
+
+ /**
+ * @see org.apache.roller.presentation.forms.BookmarkForm#setData(org.apache.roller.pojos.BookmarkData)
+ */
+ public void copyFrom(BookmarkData dataHolder, java.util.Locale locale) throws RollerException
+ {
+ super.copyFrom(dataHolder, locale);
+ mFolderId = dataHolder.getFolder().getId();
+ }
+}
Added: incubator/roller/trunk/src/org/apache/roller/presentation/bookmarks/formbeans/BookmarksForm.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/apache/roller/presentation/bookmarks/formbeans/BookmarksForm.java?rev=398712&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/apache/roller/presentation/bookmarks/formbeans/BookmarksForm.java (added)
+++ incubator/roller/trunk/src/org/apache/roller/presentation/bookmarks/formbeans/BookmarksForm.java Mon May 1 15:23:02 2006
@@ -0,0 +1,86 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. The ASF licenses this file to You
+* under the Apache License, Version 2.0 (the "License"); you may not
+* use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License. For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+/*
+ * Created on Oct 21, 2003
+ */
+package org.apache.roller.presentation.bookmarks.formbeans;
+
+import org.apache.struts.action.ActionForm;
+
+/**
+ * @struts.form name="bookmarksForm"
+ */
+public class BookmarksForm extends ActionForm
+{
+ private String folderId = null;
+ private boolean moveContents = false;
+ private String moveToFolderId = null;
+ private String[] selectedBookmarks = null;
+ private String[] selectedFolders = null;
+
+ public String getFolderId()
+ {
+ return folderId;
+ }
+
+ public void setFolderId(String folderId)
+ {
+ this.folderId = folderId;
+ }
+
+ public boolean isMoveContents()
+ {
+ return moveContents;
+ }
+
+ public void setMoveContents(boolean moveContents)
+ {
+ this.moveContents = moveContents;
+ }
+
+ public String getMoveToFolderId()
+ {
+ return moveToFolderId;
+ }
+
+ public void setMoveToFolderId(String moveToFolderId)
+ {
+ this.moveToFolderId = moveToFolderId;
+ }
+
+ public String[] getSelectedBookmarks()
+ {
+ return selectedBookmarks;
+ }
+
+ public void setSelectedBookmarks(String[] selectedBookmarks)
+ {
+ this.selectedBookmarks = selectedBookmarks;
+ }
+
+ public String[] getSelectedFolders()
+ {
+ return selectedFolders;
+ }
+
+ public void setSelectedFolders(String[] selectedFolders)
+ {
+ this.selectedFolders = selectedFolders;
+ }
+
+}
Added: incubator/roller/trunk/src/org/apache/roller/presentation/bookmarks/formbeans/FolderFormEx.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/apache/roller/presentation/bookmarks/formbeans/FolderFormEx.java?rev=398712&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/apache/roller/presentation/bookmarks/formbeans/FolderFormEx.java (added)
+++ incubator/roller/trunk/src/org/apache/roller/presentation/bookmarks/formbeans/FolderFormEx.java Mon May 1 15:23:02 2006
@@ -0,0 +1,105 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. The ASF licenses this file to You
+* under the Apache License, Version 2.0 (the "License"); you may not
+* use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License. For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+
+package org.apache.roller.presentation.bookmarks.formbeans;
+
+import org.apache.struts.upload.FormFile;
+import org.apache.roller.RollerException;
+import org.apache.roller.pojos.FolderData;
+import org.apache.roller.presentation.forms.FolderForm;
+
+
+/**
+ * Extends the FolderForm so that additional properties may be added.
+ * These properties are not persistent and are only needed for the UI.
+ *
+ * @struts.form name="folderFormEx"
+ */
+public class FolderFormEx extends FolderForm
+{
+ private boolean mMoveContents = false;
+ private String mMoveToFolderId = null;
+ private String[] mSelectedBookmarks = null;
+ private String[] mSelectedFolders = null;
+ private transient FormFile mBookmarksFile = null;
+
+ public FolderFormEx()
+ {
+ super();
+ }
+
+ public FolderFormEx(FolderData folderData, java.util.Locale locale) throws RollerException
+ {
+ super(folderData, locale);
+ }
+
+ public String getShortenedDesc()
+ {
+ if ( getDescription().length() > 20 )
+ {
+ return getDescription().substring(0,19)+"...";
+ }
+ return getDescription();
+ }
+
+ public void setShortenedDesc( String desc )
+ {
+ // readonly
+ }
+
+ //------------------------------------------------- Property bookmarksFile
+
+ /** Bookmark file to be imported */
+ public void setBookmarksFile(FormFile file) { mBookmarksFile = file; }
+
+ /** Bookmark file to be imported */
+ public FormFile getBookmarksFile() { return mBookmarksFile; }
+
+ //-------------------------------------------------- Property moveContents
+
+ /** If true then contents should be moved when this folder is removed */
+ public boolean getMoveContents() { return mMoveContents; }
+
+ /** If true then contents should be moved when this folder is removed */
+ public void setMoveContents( boolean flag ) { mMoveContents = flag;}
+
+ //------------------------------------------------ Property moveToFolderId
+
+ /** Folder where contents should be moved if this folder is removed */
+ public String getMoveToFolderId() { return mMoveToFolderId; }
+
+ /** Folder where contents should be moved if this folder is removed */
+ public void setMoveToFolderId( String id ) { mMoveToFolderId = id;}
+
+ //--------------------------------------------- Property selectedBookmarks
+
+ /** Get selected bookmarks */
+ public String[] getSelectedBookmarks() { return mSelectedBookmarks; }
+
+ /** Set selected bookmarks */
+ public void setSelectedBookmarks( String[] b ) { mSelectedBookmarks = b; }
+
+ //--------------------------------------------- Property selectedBookmarks
+
+ /** Get selected folders */
+ public String[] getSelectedFolders() { return mSelectedFolders; }
+
+ /** Set selected bookmarks */
+ public void setSelectedFolders( String[] f ) { mSelectedFolders = f; }
+}
+
Added: incubator/roller/trunk/src/org/apache/roller/presentation/bookmarks/formbeans/package.html
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/apache/roller/presentation/bookmarks/formbeans/package.html?rev=398712&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/apache/roller/presentation/bookmarks/formbeans/package.html (added)
+++ incubator/roller/trunk/src/org/apache/roller/presentation/bookmarks/formbeans/package.html Mon May 1 15:23:02 2006
@@ -0,0 +1,27 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. The ASF licenses this file to You
+ under the Apache License, Version 2.0 (the "License"); you may not
+ use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License. For additional information regarding
+ copyright in this work, please see the NOTICE file in the top level
+ directory of this distribution.
+-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+ <title></title>
+</head>
+<body>
+Extended form beans needed for bookmarks and folders.
+
+</body>
+</html>
Added: incubator/roller/trunk/src/org/apache/roller/presentation/cache/Cache.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/apache/roller/presentation/cache/Cache.java?rev=398712&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/apache/roller/presentation/cache/Cache.java (added)
+++ incubator/roller/trunk/src/org/apache/roller/presentation/cache/Cache.java Mon May 1 15:23:02 2006
@@ -0,0 +1,78 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. The ASF licenses this file to You
+* under the Apache License, Version 2.0 (the "License"); you may not
+* use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License. For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+/*
+ * RollerCache.java
+ *
+ * Created on September 18, 2005, 10:59 AM
+ */
+
+package org.apache.roller.presentation.cache;
+
+import java.util.Map;
+import java.util.Set;
+
+
+/**
+ * Base interface representing a presentation cache in Roller.
+ *
+ * @author Allen Gilliland
+ */
+public interface Cache {
+
+ /**
+ * put an item in the cache.
+ */
+ public void put(String key, Object value);
+
+
+ /**
+ * get an item from the cache.
+ */
+ public Object get(String key);
+
+
+ /**
+ * remove an item from the cache.
+ */
+ public void remove(String key);
+
+
+ /**
+ * remove a set of items from the cache.
+ */
+ public void remove(Set keys);
+
+
+ /**
+ * clear the entire cache.
+ */
+ public void clear();
+
+
+ /**
+ * get a list of keys used in the cache.
+ */
+ public Set keySet();
+
+
+ /**
+ * get cache stats.
+ */
+ public Map stats();
+
+}
Added: incubator/roller/trunk/src/org/apache/roller/presentation/cache/CacheFactory.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/apache/roller/presentation/cache/CacheFactory.java?rev=398712&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/apache/roller/presentation/cache/CacheFactory.java (added)
+++ incubator/roller/trunk/src/org/apache/roller/presentation/cache/CacheFactory.java Mon May 1 15:23:02 2006
@@ -0,0 +1,42 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. The ASF licenses this file to You
+* under the Apache License, Version 2.0 (the "License"); you may not
+* use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License. For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+/*
+ * CacheFactory.java
+ *
+ * Created on October 26, 2005, 3:25 PM
+ */
+
+package org.apache.roller.presentation.cache;
+
+import java.util.Map;
+
+
+/**
+ * An interface representing a cache factory. Implementors of this interface
+ * are responsible for providing a method to construct cache implementations.
+ *
+ * In Roller you switch between various caching options by choosing a different
+ * cache factory before starting up the application.
+ *
+ * @author Allen Gilliland
+ */
+public interface CacheFactory {
+
+ public Cache constructCache(Map properties);
+
+}
Added: incubator/roller/trunk/src/org/apache/roller/presentation/cache/CacheHandler.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/apache/roller/presentation/cache/CacheHandler.java?rev=398712&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/apache/roller/presentation/cache/CacheHandler.java (added)
+++ incubator/roller/trunk/src/org/apache/roller/presentation/cache/CacheHandler.java Mon May 1 15:23:02 2006
@@ -0,0 +1,72 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. The ASF licenses this file to You
+* under the Apache License, Version 2.0 (the "License"); you may not
+* use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License. For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+/*
+ * CacheHandler.java
+ *
+ * Created on November 5, 2005, 7:33 PM
+ */
+
+package org.apache.roller.presentation.cache;
+
+import java.util.Map;
+import org.apache.roller.pojos.BookmarkData;
+import org.apache.roller.pojos.CommentData;
+import org.apache.roller.pojos.FolderData;
+import org.apache.roller.pojos.RefererData;
+import org.apache.roller.pojos.UserData;
+import org.apache.roller.pojos.WeblogCategoryData;
+import org.apache.roller.pojos.WeblogEntryData;
+import org.apache.roller.pojos.WeblogTemplate;
+import org.apache.roller.pojos.WebsiteData;
+
+
+/**
+ * A class which utilizes a cache.
+ *
+ * The primary purpose of this interface is to force cache handlers to implement
+ * the set of invalidate() methods which server as notifications of changed
+ * objects. Various caches can determine for themselves how to deal with changes
+ * to each type of object.
+ *
+ * @author Allen Gilliland
+ */
+public interface CacheHandler {
+
+ public void invalidate(WeblogEntryData entry);
+
+ public void invalidate(WebsiteData website);
+
+ public void invalidate(BookmarkData bookmark);
+
+ public void invalidate(FolderData folder);
+
+ public void invalidate(CommentData comment);
+
+ public void invalidate(RefererData referer);
+
+ public void invalidate(UserData user);
+
+ public void invalidate(WeblogCategoryData category);
+
+ public void invalidate(WeblogTemplate template);
+
+ public void clear();
+
+ public Map getStats();
+
+}
Added: incubator/roller/trunk/src/org/apache/roller/presentation/cache/CacheManager.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/apache/roller/presentation/cache/CacheManager.java?rev=398712&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/apache/roller/presentation/cache/CacheManager.java (added)
+++ incubator/roller/trunk/src/org/apache/roller/presentation/cache/CacheManager.java Mon May 1 15:23:02 2006
@@ -0,0 +1,462 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. The ASF licenses this file to You
+* under the Apache License, Version 2.0 (the "License"); you may not
+* use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License. For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+/*
+ * CacheManager.java
+ *
+ * Created on September 30, 2005, 4:28 PM
+ */
+
+package org.apache.roller.presentation.cache;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.roller.business.runnable.ContinuousWorkerThread;
+import org.apache.roller.business.runnable.Job;
+import org.apache.roller.config.RollerConfig;
+import org.apache.roller.pojos.BookmarkData;
+import org.apache.roller.pojos.CommentData;
+import org.apache.roller.pojos.FolderData;
+import org.apache.roller.pojos.RefererData;
+import org.apache.roller.pojos.UserData;
+import org.apache.roller.pojos.WeblogCategoryData;
+import org.apache.roller.pojos.WeblogEntryData;
+import org.apache.roller.pojos.WeblogTemplate;
+import org.apache.roller.pojos.WebsiteData;
+
+
+/**
+ * A governing class for Roller cache objects.
+ *
+ * The purpose of the CacheManager is to provide a level of abstraction between
+ * classes that use a cache and the implementations of a cache. This allows
+ * us to create easily pluggable cache implementations.
+ *
+ * The other purpose is to provide a single interface for interacting with all
+ * Roller caches at the same time. This is beneficial because as data
+ * changes in the system we often need to notify all caches that some part of
+ * their cached data needs to be invalidated, and the CacheManager makes that
+ * process easier.
+ *
+ * @author Allen Gilliland
+ */
+public class CacheManager {
+
+ private static Log mLogger = LogFactory.getLog(CacheManager.class);
+
+ private static final String DEFAULT_FACTORY =
+ "org.apache.roller.presentation.cache.ExpiringLRUCacheFactoryImpl";
+
+ // a reference to the cache factory in use
+ private static CacheFactory mCacheFactory = null;
+
+ // maintain a cache of the last expired time for each weblog
+ private static Cache lastExpiredCache = null;
+
+ // a list of all cache handlers who have obtained a cache
+ private static Set cacheHandlers = new HashSet();
+
+ private static ContinuousWorkerThread futureInvalidationsThread = null;
+
+
+ static {
+ // lookup what cache factory we want to use
+ String classname = RollerConfig.getProperty("cache.defaultFactory");
+
+ // use reflection to instantiate our factory class
+ try {
+ Class factoryClass = Class.forName(classname);
+ mCacheFactory = (CacheFactory) factoryClass.newInstance();
+ } catch(ClassCastException cce) {
+ mLogger.error("It appears that your factory does not implement "+
+ "the CacheFactory interface",cce);
+ } catch(Exception e) {
+ mLogger.error("Unable to instantiate cache factory ["+classname+"]"+
+ " falling back on default", e);
+ }
+
+ if(mCacheFactory == null) try {
+ // hmm ... failed to load the specified cache factory
+ // lets try our default
+ Class factoryClass = Class.forName(DEFAULT_FACTORY);
+ mCacheFactory = (CacheFactory) factoryClass.newInstance();
+ } catch(Exception e) {
+ mLogger.fatal("Failed to instantiate a cache factory", e);
+ }
+
+ mLogger.info("Cache Manager Initialized.");
+ mLogger.info("Default cache factory = "+mCacheFactory.getClass().getName());
+
+
+ // setup our cache for expiration dates
+ // TODO: this really should not be something that is cached here
+ // a better approach would be to add a weblog.lastChanged field
+ // and track this along with the WebsiteData object
+ String lastExpCacheFactory = RollerConfig.getProperty("cache.lastExpired.factory");
+ Map lastExpProps = new HashMap();
+ if(lastExpCacheFactory != null) {
+ lastExpProps.put("factory", lastExpCacheFactory);
+ }
+ lastExpiredCache = CacheManager.constructCache(null, lastExpProps);
+
+
+ // add custom handlers
+ String customHandlers = RollerConfig.getProperty("cache.customHandlers");
+ if(customHandlers != null && customHandlers.trim().length() > 0) {
+
+ String[] cHandlers = customHandlers.split(",");
+ for(int i=0; i < cHandlers.length; i++) {
+ // use reflection to instantiate the handler class
+ try {
+ Class handlerClass = Class.forName(cHandlers[i]);
+ CacheHandler customHandler =
+ (CacheHandler) handlerClass.newInstance();
+
+ cacheHandlers.add(customHandler);
+ } catch(ClassCastException cce) {
+ mLogger.error("It appears that your handler does not implement "+
+ "the CacheHandler interface",cce);
+ } catch(Exception e) {
+ mLogger.error("Unable to instantiate cache handler ["+cHandlers[i]+"]", e);
+ }
+ }
+ }
+
+ // determine future invalidations peering window
+ Integer peerTime = new Integer(5);
+ String peerTimeString = RollerConfig.getProperty("cache.futureInvalidations.peerTime");
+ try {
+ peerTime = new Integer(peerTimeString);
+ } catch(NumberFormatException nfe) {
+ // bad input from config file, default already set
+ }
+
+ // thread time is always 10 secs less than peer time to make sure
+ // there is a little overlap so we don't miss any entries
+ // this means every XX seconds we peer XX + 10 seconds into the future
+ int threadTime = (peerTime.intValue() * 60 * 1000) - (10 * 1000);
+
+ // start up future invalidations job, running continuously
+ futureInvalidationsThread = new ContinuousWorkerThread("future invalidations thread", threadTime);
+ Job futureInvalidationsJob = new FuturePostingsInvalidationJob();
+
+ // inputs
+ Map inputs = new HashMap();
+ inputs.put("peerTime", peerTime);
+ futureInvalidationsJob.input(inputs);
+
+ // set job and start it
+ futureInvalidationsThread.setJob(futureInvalidationsJob);
+ futureInvalidationsThread.start();
+ }
+
+
+ // a non-instantiable class
+ private CacheManager() {}
+
+
+ /**
+ * Ask the CacheManager to construct a cache.
+ *
+ * Normally the CacheManager will use whatever CacheFactory has been
+ * chosen for the system via the cache.defaultFactory property.
+ * However, it is possible to override the use of the default factory by
+ * supplying a "factory" property to this method. The value should
+ * be the full classname for the factory you want to use for constructing
+ * the cache.
+ *
+ * example:
+ * factory -> org.apache.roller.presentation.cache.LRUCacheFactoryImpl
+ *
+ * This allows Roller admins the ability to choose a caching strategy to
+ * use for the whole system, but override it in certain places where they
+ * see fit. It also allows users to write their own caching modifications
+ * and have them used only by specific caches.
+ */
+ public static Cache constructCache(CacheHandler handler, Map properties) {
+
+ mLogger.debug("Constructing new cache with props "+properties);
+
+ Cache cache = null;
+
+ if(properties != null && properties.containsKey("factory")) {
+ // someone wants a custom cache instance
+ String classname = (String) properties.get("factory");
+
+ try {
+ // use reflection to instantiate the factory class
+ Class factoryClass = Class.forName(classname);
+ CacheFactory factory = (CacheFactory) factoryClass.newInstance();
+
+ // now ask for a new cache
+ cache = factory.constructCache(properties);
+ } catch(ClassCastException cce) {
+ mLogger.error("It appears that your factory ["+classname+
+ "] does not implement the CacheFactory interface",cce);
+ } catch(Exception e) {
+ mLogger.error("Unable to instantiate cache factory ["+classname+
+ "] falling back on default", e);
+ }
+ }
+
+ if(cache == null) {
+ // ask our default cache factory for a new cache instance
+ cache = mCacheFactory.constructCache(properties);
+ }
+
+ // register the handler for this new cache
+ if(handler != null) {
+ cacheHandlers.add(handler);
+ }
+
+ return cache;
+ }
+
+
+ /**
+ * Register a CacheHandler to listen for object invalidations.
+ *
+ * This is here so that it's possible to to add classes which would respond
+ * to object invalidations without necessarily having to create a cache.
+ *
+ * An example would be a handler designed to notify other machines in a
+ * cluster when an object has been invalidated, or possibly the search
+ * index management classes are interested in knowing when objects are
+ * invalidated.
+ */
+ public static void registerHandler(CacheHandler handler) {
+
+ mLogger.debug("Registering handler "+handler);
+
+ if(handler != null) {
+ cacheHandlers.add(handler);
+ }
+ }
+
+
+ public static void invalidate(WeblogEntryData entry) {
+
+ mLogger.debug("invalidating entry = "+entry.getAnchor());
+
+ setLastExpiredDate(entry.getWebsite().getHandle());
+
+ Iterator handlers = cacheHandlers.iterator();
+ while(handlers.hasNext()) {
+ ((CacheHandler) handlers.next()).invalidate(entry);
+ }
+ }
+
+
+ public static void invalidate(WebsiteData website) {
+
+ mLogger.debug("invalidating website = "+website.getHandle());
+
+ setLastExpiredDate(website.getHandle());
+
+ Iterator handlers = cacheHandlers.iterator();
+ while(handlers.hasNext()) {
+ ((CacheHandler) handlers.next()).invalidate(website);
+ }
+ }
+
+
+ public static void invalidate(BookmarkData bookmark) {
+
+ mLogger.debug("invalidating bookmark = "+bookmark.getId());
+
+ setLastExpiredDate(bookmark.getWebsite().getHandle());
+
+ Iterator handlers = cacheHandlers.iterator();
+ while(handlers.hasNext()) {
+ ((CacheHandler) handlers.next()).invalidate(bookmark);
+ }
+ }
+
+
+ public static void invalidate(FolderData folder) {
+
+ mLogger.debug("invalidating folder = "+folder.getId());
+
+ setLastExpiredDate(folder.getWebsite().getHandle());
+
+ Iterator handlers = cacheHandlers.iterator();
+ while(handlers.hasNext()) {
+ ((CacheHandler) handlers.next()).invalidate(folder);
+ }
+ }
+
+
+ public static void invalidate(CommentData comment) {
+
+ mLogger.debug("invalidating comment = "+comment.getId());
+
+ setLastExpiredDate(comment.getWeblogEntry().getWebsite().getHandle());
+
+ Iterator handlers = cacheHandlers.iterator();
+ while(handlers.hasNext()) {
+ ((CacheHandler) handlers.next()).invalidate(comment);
+ }
+ }
+
+
+ public static void invalidate(RefererData referer) {
+
+ mLogger.debug("invalidating referer = "+referer.getId());
+
+ // NOTE: Invalidating an entire website for each referer is not
+ // good for our caching. This may need reevaluation later.
+ //lastExpiredCache.put(referer.getWebsite().getHandle(), new Date());
+
+ Iterator handlers = cacheHandlers.iterator();
+ while(handlers.hasNext()) {
+ ((CacheHandler) handlers.next()).invalidate(referer);
+ }
+ }
+
+
+ public static void invalidate(UserData user) {
+
+ mLogger.debug("invalidating user = "+user.getUserName());
+
+ Iterator handlers = cacheHandlers.iterator();
+ while(handlers.hasNext()) {
+ ((CacheHandler) handlers.next()).invalidate(user);
+ }
+ }
+
+
+ public static void invalidate(WeblogCategoryData category) {
+
+ mLogger.debug("invalidating category = "+category.getId());
+
+ setLastExpiredDate(category.getWebsite().getHandle());
+
+ Iterator handlers = cacheHandlers.iterator();
+ while(handlers.hasNext()) {
+ ((CacheHandler) handlers.next()).invalidate(category);
+ }
+ }
+
+
+ public static void invalidate(WeblogTemplate template) {
+
+ mLogger.debug("invalidating template = "+template.getId());
+
+ setLastExpiredDate(template.getWebsite().getHandle());
+
+ Iterator handlers = cacheHandlers.iterator();
+ while(handlers.hasNext()) {
+ ((CacheHandler) handlers.next()).invalidate(template);
+ }
+ }
+
+
+ /**
+ * Flush the entire cache system.
+ */
+ public static void clear() {
+
+ // update all expired dates
+ lastExpiredCache.clear();
+
+ // loop through all handlers and trigger a clear
+ CacheHandler handler = null;
+ Iterator handlers = cacheHandlers.iterator();
+ while(handlers.hasNext()) {
+ handler = (CacheHandler) handlers.next();
+
+ handler.clear();
+ }
+ }
+
+
+ /**
+ * Flush a single cache handler.
+ */
+ public static void clear(String handlerClass) {
+
+ // update all expired dates
+ lastExpiredCache.clear();
+
+ // loop through all handlers to find the one we want
+ CacheHandler handler = null;
+ Iterator handlers = cacheHandlers.iterator();
+ while(handlers.hasNext()) {
+ handler = (CacheHandler) handlers.next();
+
+ if(handler.getClass().getName().equals(handlerClass)) {
+ handler.clear();
+ }
+ }
+ }
+
+
+ public static void setLastExpiredDate(String weblogHandle) {
+ lastExpiredCache.put("lastExpired:"+weblogHandle, new Date());
+ }
+
+
+ /**
+ * Get the date of the last time the specified weblog was invalidated.
+ */
+ public static Date getLastExpiredDate(String weblogHandle) {
+ return (Date) lastExpiredCache.get("lastExpired:"+weblogHandle);
+ }
+
+
+ /**
+ * Compile stats from all registered handlers.
+ *
+ * This is basically a hacky version of instrumentation which is being
+ * thrown in because we don't have a full instrumentation strategy yet.
+ * This is here with the full expectation that it will be replaced by
+ * something a bit more elaborate, like JMX.
+ */
+ public static Map getStats() {
+
+ Map allStats = new HashMap();
+
+ CacheHandler handler = null;
+ Iterator handlers = cacheHandlers.iterator();
+ while(handlers.hasNext()) {
+ handler = (CacheHandler) handlers.next();
+
+ allStats.put(handler.getClass().getName(), handler.getStats());
+ }
+
+ return allStats;
+ }
+
+
+ /**
+ * Place to do any cleanup tasks for cache system.
+ */
+ public static void shutdown() {
+
+ // stop our future invalidations thread
+ if(futureInvalidationsThread != null) {
+ futureInvalidationsThread.interrupt();
+ }
+ }
+
+}
Added: incubator/roller/trunk/src/org/apache/roller/presentation/cache/ExpiringCacheEntry.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/apache/roller/presentation/cache/ExpiringCacheEntry.java?rev=398712&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/apache/roller/presentation/cache/ExpiringCacheEntry.java (added)
+++ incubator/roller/trunk/src/org/apache/roller/presentation/cache/ExpiringCacheEntry.java Mon May 1 15:23:02 2006
@@ -0,0 +1,90 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. The ASF licenses this file to You
+* under the Apache License, Version 2.0 (the "License"); you may not
+* use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License. For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+/*
+ * ExpiringCacheEntry.java
+ *
+ * Created on November 4, 2005, 12:10 PM
+ */
+
+package org.apache.roller.presentation.cache;
+
+import java.io.Serializable;
+
+
+/**
+ * A cache entry that expires.
+ *
+ * We use this class to wrap objects being cached and associate a timestamp
+ * and timeout period with them so we can know when they expire.
+ *
+ * @author Allen Gilliland
+ */
+public class ExpiringCacheEntry implements Serializable {
+
+ private Object value;
+ private long timeCached = -1;
+ private long timeout = 0;
+
+
+ public ExpiringCacheEntry(Object value, long timeout) {
+ this.value = value;
+
+ // make sure that we don't support negative values
+ if(timeout > 0) {
+ this.timeout = timeout;
+ }
+
+ this.timeCached = System.currentTimeMillis();
+ }
+
+
+ public long getTimeCached() {
+ return this.timeCached;
+ }
+
+
+ public long getTimeout() {
+ return this.timeout;
+ }
+
+
+ /**
+ * Retrieve the value of this cache entry.
+ *
+ * If the value has expired then we return null.
+ */
+ public Object getValue() {
+ if(this.hasExpired()) {
+ return null;
+ } else {
+ return this.value;
+ }
+ }
+
+
+ /**
+ * Determine if this cache entry has expired.
+ */
+ public boolean hasExpired() {
+
+ long now = System.currentTimeMillis();
+
+ return ((this.timeCached + this.timeout) < now);
+ }
+
+}
Added: incubator/roller/trunk/src/org/apache/roller/presentation/cache/ExpiringLRUCacheFactoryImpl.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/apache/roller/presentation/cache/ExpiringLRUCacheFactoryImpl.java?rev=398712&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/apache/roller/presentation/cache/ExpiringLRUCacheFactoryImpl.java (added)
+++ incubator/roller/trunk/src/org/apache/roller/presentation/cache/ExpiringLRUCacheFactoryImpl.java Mon May 1 15:23:02 2006
@@ -0,0 +1,73 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. The ASF licenses this file to You
+* under the Apache License, Version 2.0 (the "License"); you may not
+* use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License. For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+/*
+ * LRUCacheFactoryImpl.java
+ *
+ * Created on October 26, 2005, 3:33 PM
+ */
+
+package org.apache.roller.presentation.cache;
+
+import java.util.Map;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+
+/**
+ * Roller Expiring LRU cache factory.
+ *
+ * @author Allen Gilliland
+ */
+public class ExpiringLRUCacheFactoryImpl implements CacheFactory {
+
+ private static Log mLogger =
+ LogFactory.getLog(ExpiringLRUCacheFactoryImpl.class);
+
+
+ // protected so only the CacheManager can instantiate us
+ protected ExpiringLRUCacheFactoryImpl() {}
+
+
+ /**
+ * Construct a new instance of a Roller Expiring LRUCache.
+ */
+ public Cache constructCache(Map properties) {
+
+ int size = 100;
+ long timeout = 15 * 60;
+
+ try {
+ size = Integer.parseInt((String) properties.get("size"));
+ } catch(Exception e) {
+ // ignored
+ }
+
+ try {
+ timeout = Long.parseLong((String) properties.get("timeout"));
+ } catch(Exception e) {
+ // ignored
+ }
+
+ Cache cache = new ExpiringLRUCacheImpl(size, timeout);
+
+ mLogger.debug("new cache constructed. size="+size+", timeout="+timeout);
+
+ return cache;
+ }
+
+}
\ No newline at end of file
Added: incubator/roller/trunk/src/org/apache/roller/presentation/cache/ExpiringLRUCacheImpl.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/apache/roller/presentation/cache/ExpiringLRUCacheImpl.java?rev=398712&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/apache/roller/presentation/cache/ExpiringLRUCacheImpl.java (added)
+++ incubator/roller/trunk/src/org/apache/roller/presentation/cache/ExpiringLRUCacheImpl.java Mon May 1 15:23:02 2006
@@ -0,0 +1,102 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. The ASF licenses this file to You
+* under the Apache License, Version 2.0 (the "License"); you may not
+* use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License. For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+/*
+ * ExpiringLRUCacheImpl.java
+ *
+ * Created on November 6, 2005, 10:33 AM
+ */
+
+package org.apache.roller.presentation.cache;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+
+/**
+ * An LRU cache where entries expire after a given timeout period.
+ *
+ * @author Allen Gilliland
+ */
+public class ExpiringLRUCacheImpl extends LRUCacheImpl {
+
+ private static Log mLogger = LogFactory.getLog(ExpiringLRUCacheImpl.class);
+
+ private long timeout = 0;
+
+
+ protected ExpiringLRUCacheImpl() {
+
+ super();
+ this.timeout = 60 * 60 * 1000;
+ }
+
+
+ protected ExpiringLRUCacheImpl(int maxsize, long timeout) {
+
+ super(maxsize);
+
+ // timeout is specified in seconds; only positive values allowed
+ if(timeout > 0) {
+ this.timeout = timeout * 1000;
+ }
+ }
+
+
+ /**
+ * Store an entry in the cache.
+ *
+ * We wrap the cached object in our ExpiringCacheEntry object so that we
+ * can track when the entry has expired.
+ */
+ public synchronized void put(String key, Object value) {
+
+ ExpiringCacheEntry entry = new ExpiringCacheEntry(value, this.timeout);
+ super.put(key, entry);
+ }
+
+
+ /**
+ * Retrieve an entry from the cache.
+ *
+ * This LRU cache supports timeouts, so if the cached object has expired
+ * then we return null, just as if the entry wasn't found.
+ */
+ public Object get(String key) {
+
+ Object value = null;
+ ExpiringCacheEntry entry = null;
+
+ synchronized(this) {
+ entry = (ExpiringCacheEntry) super.get(key);
+ }
+
+ if (entry != null) {
+
+ value = entry.getValue();
+
+ // if the value is null then that means this entry expired
+ if (value == null) {
+ mLogger.debug("entry expired ["+key+"]");
+ super.remove(key);
+ }
+ }
+
+ return value;
+ }
+
+}
Added: incubator/roller/trunk/src/org/apache/roller/presentation/cache/FuturePostingsInvalidationJob.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/apache/roller/presentation/cache/FuturePostingsInvalidationJob.java?rev=398712&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/apache/roller/presentation/cache/FuturePostingsInvalidationJob.java (added)
+++ incubator/roller/trunk/src/org/apache/roller/presentation/cache/FuturePostingsInvalidationJob.java Mon May 1 15:23:02 2006
@@ -0,0 +1,135 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. The ASF licenses this file to You
+* under the Apache License, Version 2.0 (the "License"); you may not
+* use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License. For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+/*
+ * FuturePostingsInvalidationJob.java
+ *
+ * Created on February 14, 2006, 5:48 PM
+ */
+
+package org.apache.roller.presentation.cache;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.roller.business.runnable.Job;
+import org.apache.roller.model.RollerFactory;
+import org.apache.roller.model.WeblogManager;
+import org.apache.roller.pojos.WeblogEntryData;
+
+
+/**
+ * Trigger cache invalidations for entries published into the future.
+ *
+ * This job is meant to be run at timed intervals, it will not do any
+ * good to run this job only a single time.
+ *
+ * We do things in a somewhat counterintuitive manner, but it makes things
+ * easier on us from an operational point of view. We start by looking up
+ * all entries published between now and some time XX mins in the future. We
+ * then save that list and when XX mins has passed we invalidate the list and
+ * query for entries published in the next XX mins.
+ *
+ * Basically we are building a short term list of future published entries
+ * and expiring them once our wait period is over. This prevents us from
+ * having to somehow determine which entries published in the last XX mins
+ * had previously been published into the future.
+ *
+ * @author Allen Gilliland
+ */
+public class FuturePostingsInvalidationJob implements Job {
+
+ private static Log mLogger = LogFactory.getLog(FuturePostingsInvalidationJob.class);
+
+ // inputs from the user
+ private Map inputs = null;
+
+ // the list of entries we expire at the start of the next run
+ private List nextExpirations = null;
+
+ // how far into the future we will look ahead, in minutes
+ int peerTime = 5;
+
+ public void execute() {
+
+ mLogger.debug("starting");
+
+ // notify the cache manager of an invalidation
+ if(nextExpirations != null) {
+ WeblogEntryData entry = null;
+ Iterator entries = nextExpirations.iterator();
+ while(entries.hasNext()) {
+ entry = (WeblogEntryData) entries.next();
+
+ mLogger.debug("expiring "+entry.getAnchor());
+
+ CacheManager.invalidate(entry);
+ }
+ }
+
+ // look for postings from current time to current time plus XX mins
+ List expiringEntries = null;
+ try {
+ WeblogManager mgr = RollerFactory.getRoller().getWeblogManager();
+
+ // current time
+ Date start = new Date();
+
+ // XX mins in the future
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(start);
+ cal.add(Calendar.MINUTE, this.peerTime);
+ Date end = cal.getTime();
+
+ mLogger.debug("looking up entries between "+start+" and "+end);
+
+ // get all published entries between start and end date
+ expiringEntries = mgr.getWeblogEntries(null, start, end, null,
+ null, WeblogEntryData.PUBLISHED, null);
+
+ this.nextExpirations = expiringEntries;
+
+ } catch(Exception e) {
+ mLogger.error(e);
+ }
+
+ mLogger.debug("finished");
+ }
+
+
+ public Map output() {
+ return null;
+ }
+
+
+ public void input(Map input) {
+ this.inputs = input;
+
+ // extract peer time if possible
+ Integer pTime = (Integer) this.inputs.get("peerTime");
+ if(pTime != null) {
+ this.peerTime = pTime.intValue();
+ }
+
+ mLogger.info("Peeking "+this.peerTime+" minutes into the future each pass");
+ }
+
+}
Added: incubator/roller/trunk/src/org/apache/roller/presentation/cache/LRUCacheFactoryImpl.java
URL: http://svn.apache.org/viewcvs/incubator/roller/trunk/src/org/apache/roller/presentation/cache/LRUCacheFactoryImpl.java?rev=398712&view=auto
==============================================================================
--- incubator/roller/trunk/src/org/apache/roller/presentation/cache/LRUCacheFactoryImpl.java (added)
+++ incubator/roller/trunk/src/org/apache/roller/presentation/cache/LRUCacheFactoryImpl.java Mon May 1 15:23:02 2006
@@ -0,0 +1,65 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements. The ASF licenses this file to You
+* under the Apache License, Version 2.0 (the "License"); you may not
+* use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License. For additional information regarding
+* copyright in this work, please see the NOTICE file in the top level
+* directory of this distribution.
+*/
+/*
+ * LRUCacheFactoryImpl.java
+ *
+ * Created on November 6, 2005, 10:48 AM
+ */
+
+package org.apache.roller.presentation.cache;
+
+import java.util.Map;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+
+/**
+ * Roller LRU Cache factory.
+ *
+ * @author Allen Gilliland
+ */
+public class LRUCacheFactoryImpl implements CacheFactory {
+
+ private static Log mLogger = LogFactory.getLog(LRUCacheFactoryImpl.class);
+
+
+ // protected so that only the CacheManager can instantiate us
+ protected LRUCacheFactoryImpl() {}
+
+
+ /**
+ * Construct a new instance of a Roller LRUCache.
+ */
+ public Cache constructCache(Map properties) {
+
+ int size = 100;
+
+ try {
+ size = Integer.parseInt((String) properties.get("size"));
+ } catch(Exception e) {
+ // ignored
+ }
+
+ Cache cache = new LRUCacheImpl(size);
+
+ mLogger.debug("new cache constructed. size="+size);
+
+ return cache;
+ }
+
+}