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 2005/10/21 23:46:28 UTC
svn commit: r327589 [30/72] - in /incubator/roller/branches/roller_1.x: ./
contrib/ contrib/lib/ contrib/plugins/ contrib/plugins/src/
contrib/plugins/src/org/ contrib/plugins/src/org/roller/
contrib/plugins/src/org/roller/presentation/ contrib/plugins...
Added: incubator/roller/branches/roller_1.x/src/org/roller/presentation/atomapi/RollerAtomHandler.java
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/presentation/atomapi/RollerAtomHandler.java?rev=327589&view=auto
==============================================================================
--- incubator/roller/branches/roller_1.x/src/org/roller/presentation/atomapi/RollerAtomHandler.java (added)
+++ incubator/roller/branches/roller_1.x/src/org/roller/presentation/atomapi/RollerAtomHandler.java Fri Oct 21 14:27:36 2005
@@ -0,0 +1,881 @@
+/*
+ * Copyright 2005 David M Johnson (For RSS and Atom In Action)
+ *
+ * Licensed 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.
+ */
+package org.roller.presentation.atomapi;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.sql.Timestamp;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+import java.util.StringTokenizer;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.struts.util.RequestUtils;
+import org.roller.model.FileManager;
+import org.roller.model.Roller;
+import org.roller.model.WeblogManager;
+import org.roller.pojos.UserData;
+import org.roller.pojos.WeblogCategoryData;
+import org.roller.pojos.WeblogEntryData;
+import org.roller.pojos.WebsiteData;
+import org.roller.presentation.LoginServlet;
+import org.roller.presentation.RollerContext;
+import org.roller.util.RollerMessages;
+import org.roller.util.Utilities;
+
+import com.sun.syndication.feed.atom.Content;
+import com.sun.syndication.feed.atom.Entry;
+import com.sun.syndication.feed.atom.Link;
+import com.sun.syndication.io.impl.Base64;
+
+/**
+ * Roller's Atom Protocol implementation.
+ * <pre>
+ * Here are the URIs suppored:
+ *
+ * URI type URI form Handled by
+ * -------- -------- ----------
+ * Introspection URI /blog-name getIntrosection()
+ * Collection URI /blog-name/<collection-name> getCollection()
+ * Collection-next URI /blog-name/<collection-name>/id getCollection()
+ * Member URI /blog-name/<object-name> post<object-name>()
+ * Member URI /blog-name/<object-name>/id get<object-name>()
+ * Member URI /blog-name/<object-name>/id put<object-name>()
+ * Member URI /blog-name/<object-name>/id delete<object-name>()
+ *
+ * Until group blogging is supported username == blogname.
+ *
+ * Collection-names Object-names
+ * ---------------- ------------
+ * entries entry
+ * resources resource
+ * categories categories
+ * soon:
+ * users user
+ * templates template
+ * </pre>
+ *
+ * @author David M Johnson
+ */
+public class RollerAtomHandler implements AtomHandler
+{
+ private HttpServletRequest mRequest;
+ private Roller mRoller;
+ private RollerContext mRollerContext;
+ private String mUsername;
+ private int mMaxEntries = 20;
+ //private MessageDigest md5Helper = null;
+ //private MD5Encoder md5Encoder = new MD5Encoder();
+
+ private static Log mLogger =
+ LogFactory.getFactory().getInstance(RollerAtomHandler.class);
+
+ private SimpleDateFormat timestampFormat =
+ new SimpleDateFormat("yyyyMMddHHmmss" );
+
+ //---------------------------------------------------------------- construction
+
+ /**
+ * Create Atom handler for a request and attempt to authenticate user.
+ * If user is authenticated, then getAuthenticatedUsername() will return
+ * then user's name, otherwise it will return null.
+ */
+ public RollerAtomHandler(HttpServletRequest request)
+ {
+ mRequest = request;
+ mRoller = RollerContext.getRoller(request);
+ mRollerContext = RollerContext.getRollerContext(request);
+
+ // TODO: decide what to do about authentication, is WSSE going to fly?
+ mUsername = authenticateWSSE(request);
+ //mUsername = authenticateBASIC(request);
+
+ if (mUsername != null)
+ {
+ try
+ {
+ UserData user = mRoller.getUserManager().getUser(mUsername);
+ mRoller.setUser(user);
+ }
+ catch (Exception e)
+ {
+ mLogger.error("ERROR: setting user", e);
+ }
+ }
+ // try
+ // {
+ // md5Helper = MessageDigest.getInstance("MD5");
+ // }
+ // catch (NoSuchAlgorithmException e)
+ // {
+ // mLogger.debug("ERROR creating MD5 helper", e);
+ // }
+ }
+
+ /**
+ * Return username of authenticated user or null if there is none.
+ */
+ public String getAuthenticatedUsername()
+ {
+ return mUsername;
+ }
+
+ //---------------------------------------------------------------- introspection
+
+ /**
+ * Return Atom service document for site, getting blog-name from pathInfo.
+ * Since a user can (currently) have only one blog, one workspace is returned.
+ * The workspace will contain collections for entries, categories and resources.
+ */
+ public AtomService getIntrospection(String[] pathInfo) throws Exception
+ {
+ if (pathInfo.length == 1)
+ {
+ String username = pathInfo[0];
+ String absUrl = mRollerContext.getAbsoluteContextUrl(mRequest);
+
+ AtomService service = new AtomService();
+
+ AtomService.Workspace workspace = new AtomService.Workspace();
+ workspace.setTitle("Workspace: Collections for " + username);
+ service.addWorkspace(workspace);
+
+ AtomService.Collection entryCol = new AtomService.Collection();
+ entryCol.setTitle("Collection: Weblog Entries for " + username);
+ entryCol.setContents("entries");
+ entryCol.setHref(absUrl + "/atom/"+mUsername+"/entries");
+ workspace.addCollection(entryCol);
+
+ AtomService.Collection catCol = new AtomService.Collection();
+ catCol.setTitle("Collection: Categories for " + username);
+ catCol.setContents("categories");
+ catCol.setHref(absUrl + "/atom/"+mUsername+"/categories");
+ workspace.addCollection(catCol);
+
+ AtomService.Collection uploadCol = new AtomService.Collection();
+ uploadCol.setTitle("Collection: File uploads for " + username);
+ uploadCol.setContents("generic");
+ uploadCol.setHref(absUrl + "/atom/"+mUsername+"/resources");
+ workspace.addCollection(uploadCol);
+
+ return service;
+ }
+ throw new Exception("ERROR: bad URL in getIntrospection()");
+ }
+
+ //----------------------------------------------------------------- collections
+
+ /**
+ * Returns collection specified by pathInfo with no date range specified.
+ * Just calls the other getCollection(), but with offset = -1.
+ */
+ public AtomCollection getCollection(String[] pathInfo) throws Exception
+ {
+ return getCollection(pathInfo, null, new Date(), -1);
+ }
+
+ /**
+ * Returns collection specified by pathInfo, constrained by a date range and
+ * starting at an offset within the collection.Returns 20 items at a time.
+ * <pre>
+ * Supports these three collection URI forms:
+ * /<blog-name>/entries
+ * /<blog-name>/resources
+ * /<blog-name>/categories
+ * </pre>
+ * @param pathInfo Path info from URI
+ * @param start Don't include members updated before this date (null allowed)
+ * @param end Don't include members updated after this date (null allowed)
+ * @param offset Offset within collection (for paging)
+ */
+ public AtomCollection getCollection(
+ String[] pathInfo, Date start, Date end, int offset)
+ throws Exception
+ {
+ if (pathInfo.length > 0 && pathInfo[1].equals("entries"))
+ {
+ return getCollectionOfEntries(pathInfo, start, end, offset);
+ }
+ else if (pathInfo.length > 0 && pathInfo[1].equals("resources"))
+ {
+ return getCollectionOfResources(pathInfo, start, end, offset);
+ }
+ else if (pathInfo.length > 0 && pathInfo[1].equals("categories"))
+ {
+ return getCollectionOfCategories(pathInfo, start, end, offset);
+ }
+ throw new Exception("ERROR: bad URL in getCollection()");
+ }
+
+ /**
+ * Helper method that returns collection of entries, called by getCollection().
+ */
+ public AtomCollection getCollectionOfEntries(
+ String[] pathInfo, Date start, Date end, int offset)
+ throws Exception
+ {
+ String username = pathInfo[0];
+ String absUrl = mRollerContext.getAbsoluteContextUrl(mRequest);
+ WebsiteData website = mRoller.getUserManager().getWebsite(username);
+ List entries = null;
+ if (canView(website))
+ {
+ if (pathInfo.length == 2) // handle /blogname/entries
+ {
+ // return most recent blog entries
+ if (offset == -1)
+ {
+ entries = mRoller.getWeblogManager().getWeblogEntries(
+ website, // website
+ start, // startDate
+ end, // endDate
+ null, // catName
+ WeblogManager.ALL, // status
+ new Integer(mMaxEntries + 1)); // maxEntries
+ }
+ else
+ {
+ entries = mRoller.getWeblogManager().getWeblogEntries(
+ website, // website
+ start, // startDate
+ end, // endDate
+ null, // catName
+ WeblogManager.ALL, // status
+ offset, // offset (for range paging)
+ mMaxEntries + 1); // maxEntries
+ }
+ }
+ else if (pathInfo.length == 3) // handle /blogname/entries/entryid
+ {
+ // return entries previous to entry specified by pathInfo
+ String entryid = pathInfo[2];
+ WeblogManager wmgr = mRoller.getWeblogManager();
+ WeblogEntryData entry = wmgr.retrieveWeblogEntry(entryid);
+ entries = wmgr.getPreviousEntries(entry, null, mMaxEntries + 1);
+ }
+ else throw new Exception("ERROR: bad URL");
+
+ // build collection
+ AtomCollection col = new AtomCollection();
+ if (entries.size() > mMaxEntries)
+ {
+ // there are more entries, so include next link
+ WeblogEntryData lastEntry =
+ (WeblogEntryData)entries.get(entries.size() - 1);
+ col.setNext(createNextLink(lastEntry, start, end, offset));
+ }
+ // add up to max entries to collection
+ int count = 0;
+ Iterator iter = entries.iterator();
+ while (iter.hasNext() && count++ < mMaxEntries)
+ {
+ WeblogEntryData rollerEntry = (WeblogEntryData)iter.next();
+ AtomCollection.Member member = new AtomCollection.Member();
+ member.setTitle(rollerEntry.getDisplayTitle());
+ member.setUpdated(rollerEntry.getUpdateTime());
+ member.setHref(absUrl
+ + "/atom/" + username + "/entry/" + rollerEntry.getId());
+ col.addMember(member);
+ }
+ return col;
+ }
+ throw new Exception("ERROR: not authorized");
+ }
+
+ /**
+ * Helper method that returns collection of resources, called by getCollection().
+ */
+ public AtomCollection getCollectionOfResources(
+ String[] pathInfo, Date start, Date end, int offset) throws Exception
+ {
+ String username = pathInfo[0];
+ String absUrl = mRollerContext.getAbsoluteContextUrl(mRequest);
+ WebsiteData website = mRoller.getUserManager().getWebsite(username);
+ FileManager fmgr = mRoller.getFileManager();
+ File[] files = fmgr.getFiles(website);
+ if (canView(website))
+ {
+ AtomCollection col = new AtomCollection();
+ for (int i=0; i<files.length; i++)
+ {
+ AtomCollection.Member member = new AtomCollection.Member();
+ member.setTitle(files[i].getName());
+ member.setUpdated(new Date(files[i].lastModified()));
+ member.setHref(absUrl
+ + "/atom/" + username + "/resource/" + files[i].getName() );
+ col.addMember(member);
+ }
+ return col;
+ }
+ throw new Exception("ERROR: not authorized");
+ }
+
+ /**
+ * Helper method that returns collection of categories, called by getCollection().
+ */
+ public AtomCollection getCollectionOfCategories(
+ String[] pathInfo, Date start, Date end, int offset) throws Exception
+ {
+ String username = pathInfo[0];
+ String absUrl = mRollerContext.getAbsoluteContextUrl(mRequest);
+ WebsiteData website = mRoller.getUserManager().getWebsite(username);
+ WeblogManager wmgr = mRoller.getWeblogManager();
+ List items = wmgr.getWeblogCategories(website);
+ if (canView(website))
+ {
+ AtomCollection col = new AtomCollection();
+ Iterator iter = items.iterator();
+ Date now = new Date();
+ while (iter.hasNext())
+ {
+ WeblogCategoryData item = (WeblogCategoryData)iter.next();
+ AtomCollection.Member member = new AtomCollection.Member();
+ member.setTitle(item.getPath());
+ member.setUpdated(now);
+ member.setHref(
+ absUrl + "/atom/" + username + "/category/" + item.getId());
+ col.addMember(member);
+ }
+ return col;
+ }
+ throw new Exception("ERROR: not authorized");
+ }
+
+ //--------------------------------------------------------------------- entries
+
+ /**
+ * Create entry in the entry collection (a Roller blog has only one).
+ */
+ public Entry postEntry(String[] pathInfo, Entry entry) throws Exception
+ {
+ // authenticated client posted a weblog entry
+ String username = pathInfo[0];
+ WebsiteData website = mRoller.getUserManager().getWebsite(username);
+ if (canEdit(website))
+ {
+ // Save it and commit it
+ WeblogEntryData rollerEntry = createRollerEntry(website, entry);
+ rollerEntry.save();
+ mRoller.commit();
+
+ // Throttle one entry per second
+ // (MySQL timestamp has 1 sec resolution, damnit)
+ Thread.sleep(1000);
+
+ // TODO: ping the appropriate ping
+ // TODO: flush the cache on Atom post
+ //flushPageCache(mRequest);
+
+ return createAtomEntry(rollerEntry);
+ }
+ throw new Exception("ERROR not authorized to edit website");
+ }
+
+ /**
+ * Retrieve entry, URI like this /blog-name/entry/id
+ */
+ public Entry getEntry(String[] pathInfo) throws Exception
+ {
+ if (pathInfo.length == 3) // URI is /blogname/entries/entryid
+ {
+ WeblogEntryData entry =
+ mRoller.getWeblogManager().retrieveWeblogEntry(pathInfo[2]);
+ if (!canView(entry))
+ {
+ throw new Exception("ERROR not authorized to view entry");
+ }
+ else if (entry != null)
+ {
+ return createAtomEntry(entry);
+ }
+ throw new Exception("ERROR: entry not found");
+ }
+ throw new Exception("ERROR: bad URI");
+ }
+
+ /**
+ * Update entry, URI like this /blog-name/entry/id
+ */
+ public Entry putEntry(String[] pathInfo, Entry entry) throws Exception
+ {
+ if (pathInfo.length == 3) // URI is /blogname/entries/entryid
+ {
+ WeblogEntryData rollerEntry =
+ mRoller.getWeblogManager().retrieveWeblogEntry(pathInfo[2]);
+ if (canEdit(rollerEntry))
+ {
+ rollerEntry.setTitle(entry.getTitle());
+ rollerEntry.setText(((Content)entry.getContents().get(0)).getValue());
+ rollerEntry.setUpdateTime(new Timestamp(new Date().getTime()));
+ rollerEntry.save();
+ mRoller.commit();
+ return createAtomEntry(rollerEntry);
+ }
+ throw new Exception("ERROR not authorized to put entry");
+ }
+ throw new Exception("ERROR: bad URI");
+ }
+
+ /**
+ * Delete entry, URI like this /blog-name/entry/id
+ */
+ public void deleteEntry(String[] pathInfo) throws Exception
+ {
+ if (pathInfo.length == 3) // URI is /blogname/entries/entryid
+ {
+ WeblogEntryData rollerEntry =
+ mRoller.getWeblogManager().retrieveWeblogEntry(pathInfo[2]);
+ if (canEdit(rollerEntry))
+ {
+ rollerEntry.remove();
+ mRoller.commit();
+ return;
+ }
+ throw new Exception("ERROR not authorized to delete entry");
+ }
+ throw new Exception("ERROR: bad URI");
+ }
+
+ //-------------------------------------------------------------------- resources
+
+ /**
+ * Create new resource in generic collection (a Roller blog has only one).
+ * TODO: can we avoid saving temporary file?
+ * TODO: do we need to handle mutli-part MIME uploads?
+ * TODO: use Jakarta Commons File-upload?
+ */
+ public String postResource(String[] pathInfo,
+ String name, String contentType, InputStream is)
+ throws Exception
+ {
+ // authenticated client posted a weblog entry
+ String username = pathInfo[0];
+ WebsiteData website = mRoller.getUserManager().getWebsite(username);
+ if (canEdit(website) && pathInfo.length > 1)
+ {
+ try
+ {
+ FileManager fmgr = mRoller.getFileManager();
+ RollerMessages msgs = new RollerMessages();
+
+ // save to temp file
+ if (name == null)
+ {
+ throw new Exception(
+ "ERROR[postResource]: No 'name' present in HTTP headers");
+ }
+ File tempFile = File.createTempFile(name,"tmp");
+ FileOutputStream fos = new FileOutputStream(tempFile);
+ Utilities.copyInputToOutput(is, fos);
+ fos.close();
+
+ // If save is allowed by Roller system-wide policies
+ if (fmgr.canSave(website, name, tempFile.length(), msgs))
+ {
+ // Then save the file
+ FileInputStream fis = new FileInputStream(tempFile);
+ fmgr.saveFile(website, name, tempFile.length(), fis);
+ fis.close();
+
+ // TODO: build URL to uploaded file should be done in FileManager
+ String uploadPath = RollerContext.getUploadPath(
+ mRequest.getSession(true).getServletContext());
+ uploadPath += "/" + website.getUser().getUserName() + "/" + name;
+ return RequestUtils.printableURL(
+ RequestUtils.absoluteURL(mRequest, uploadPath));
+ }
+ tempFile.delete();
+ throw new Exception("File upload denied because:" + msgs.toString());
+ }
+ catch (Exception e)
+ {
+ String msg = "ERROR in atom.postResource";
+ mLogger.error(msg,e);
+ throw new Exception(msg);
+ }
+ }
+ throw new Exception("ERROR not authorized to edit website");
+ }
+
+ /**
+ * Get absolute path to resource specified by path info.
+ */
+ public String getResourceFilePath(String[] pathInfo) throws Exception
+ {
+ // ==> /<blogname>/resources/<filename>
+ String uploadPath = RollerContext.getUploadPath(
+ mRequest.getSession(true).getServletContext());
+ return uploadPath + File.separator + pathInfo[2];
+ }
+
+ /**
+ * Update resource specified by pathInfo using data from input stream.
+ * Expects pathInfo of form /blog-name/resources/name
+ */
+ public void putResource(String[] pathInfo,
+ String contentType, InputStream is) throws Exception
+ {
+ if (pathInfo.length > 2)
+ {
+ String name = pathInfo[2];
+ postResource(pathInfo, name, contentType, is);
+ }
+ throw new Exception("ERROR: bad pathInfo");
+ }
+
+ /**
+ * Delete resource specified by pathInfo.
+ * Expects pathInfo of form /blog-name/resources/name
+ */
+ public void deleteResource(String[] pathInfo) throws Exception
+ {
+ // authenticated client posted a weblog entry
+ String username = pathInfo[0];
+ WebsiteData website = mRoller.getUserManager().getWebsite(username);
+ if (canEdit(website) && pathInfo.length > 1)
+ {
+ try
+ {
+ FileManager fmgr = mRoller.getFileManager();
+ fmgr.deleteFile(website, pathInfo[2]);
+ }
+ catch (Exception e)
+ {
+ String msg = "ERROR in atom.deleteResource";
+ mLogger.error(msg,e);
+ throw new Exception(msg);
+ }
+ }
+ throw new Exception("ERROR not authorized to edit website");
+ }
+
+ //------------------------------------------------------------------ URI testers
+
+ /**
+ * True if URL is the introspection URI.
+ */
+ public boolean isIntrospectionURI(String[] pathInfo)
+ {
+ if (pathInfo.length == 1 && pathInfo[0].equals(mUsername)) return true;
+ return false;
+ }
+
+ /**
+ * True if URL is a entry URI.
+ */
+ public boolean isEntryURI(String[] pathInfo)
+ {
+ if (pathInfo.length > 1 && pathInfo[1].equals("entry")) return true;
+ return false;
+ }
+
+ /**
+ * True if URL is a resource URI.
+ */
+ public boolean isResourceURI(String[] pathInfo)
+ {
+ if (pathInfo.length > 1 && pathInfo[1].equals("resource")) return true;
+ return false;
+ }
+
+ /**
+ * True if URL is a category URI.
+ */
+ public boolean isCategoryURI(String[] pathInfo)
+ {
+ if (pathInfo.length > 1 && pathInfo[1].equals("category")) return true;
+ return false;
+ }
+
+ /**
+ * True if URL is a collection URI of any sort.
+ */
+ public boolean isCollectionURI(String[] pathInfo)
+ {
+ if (pathInfo.length > 1 && pathInfo[1].equals("entries")) return true;
+ if (pathInfo.length > 1 && pathInfo[1].equals("resources")) return true;
+ if (pathInfo.length > 1 && pathInfo[1].equals("categories")) return true;
+ return false;
+ }
+
+ /**
+ * True if URL is a entry collection URI.
+ */
+ public boolean isEntryCollectionURI(String[] pathInfo)
+ {
+ if (pathInfo.length > 1 && pathInfo[1].equals("entries")) return true;
+ return false;
+ }
+
+ /**
+ * True if URL is a resource collection URI.
+ */
+ public boolean isResourceCollectionURI(String[] pathInfo)
+ {
+ if (pathInfo.length > 1 && pathInfo[1].equals("resources")) return true;
+ return false;
+ }
+
+ /**
+ * True if URL is a category collection URI.
+ */
+ public boolean isCategoryCollectionURI(String[] pathInfo)
+ {
+ if (pathInfo.length > 1 && pathInfo[1].equals("categories")) return true;
+ return false;
+ }
+
+ //------------------------------------------------------------------ permissions
+
+ /**
+ * Return true if user is allowed to edit an entry.
+ */
+ private boolean canEdit(WeblogEntryData entry)
+ {
+ return entry.getWebsite().getUser().getUserName().equals(mUsername);
+ }
+
+ /**
+ * Return true if user is allowed to edit a website.
+ */
+ private boolean canEdit(WebsiteData website)
+ {
+ return website.getUser().getUserName().equals(mUsername);
+ }
+
+ /**
+ * Return true if user is allowed to view an entry.
+ */
+ private boolean canView(WeblogEntryData entry)
+ {
+ return canEdit(entry);
+ }
+
+ /**
+ * Return true if user is allowed to view a website.
+ */
+ private boolean canView(WebsiteData website)
+ {
+ return canEdit(website);
+ }
+
+ //-------------------------------------------------------------- authentication
+
+ /**
+ * Perform WSSE authentication based on information in request.
+ * Will not work if Roller password encryption is turned on.
+ */
+ protected String authenticateWSSE(HttpServletRequest request)
+ {
+ String wsseHeader = request.getHeader("X-WSSE");
+ if (wsseHeader == null) return null;
+
+ String ret = null;
+ String userName = null;
+ String created = null;
+ String nonce = null;
+ String passwordDigest = null;
+ String[] tokens = wsseHeader.split(",");
+ for (int i = 0; i < tokens.length; i++)
+ {
+ int index = tokens[i].indexOf('=');
+ if (index != -1)
+ {
+ String key = tokens[i].substring(0, index).trim();
+ String value = tokens[i].substring(index + 1).trim();
+ value = value.replaceAll("\"", "");
+ if (key.startsWith("UsernameToken"))
+ {
+ userName = value;
+ }
+ else if (key.equalsIgnoreCase("nonce"))
+ {
+ nonce = value;
+ }
+ else if (key.equalsIgnoreCase("passworddigest"))
+ {
+ passwordDigest = value;
+ }
+ else if (key.equalsIgnoreCase("created"))
+ {
+ created = value;
+ }
+ }
+ }
+ String digest = null;
+ try
+ {
+ UserData user = mRoller.getUserManager().getUser(userName);
+ digest = WSSEUtilities.generateDigest(
+ WSSEUtilities.base64Decode(nonce),
+ created.getBytes("UTF-8"),
+ user.getPassword().getBytes("UTF-8"));
+ if (digest.equals(passwordDigest))
+ {
+ ret = userName;
+ }
+ }
+ catch (Exception e)
+ {
+ mLogger.error("ERROR in wsseAuthenticataion: " + e.getMessage(), e);
+ }
+ return ret;
+ }
+
+ /**
+ * Untested (and currently unused) implementation of BASIC authentication
+ */
+ public String authenticateBASIC(HttpServletRequest request)
+ {
+ boolean valid = false;
+ String userID = null;
+ String password = null;
+ try
+ {
+ String authHeader = request.getHeader("Authorization");
+ if (authHeader != null)
+ {
+ StringTokenizer st = new StringTokenizer(authHeader);
+ if (st.hasMoreTokens())
+ {
+ String basic = st.nextToken();
+ if (basic.equalsIgnoreCase("Basic"))
+ {
+ String credentials = st.nextToken();
+ String userPass = new String(Base64.decode(credentials));
+ int p = userPass.indexOf(":");
+ if (p != -1)
+ {
+ userID = userPass.substring(0, p);
+ UserData user = mRoller.getUserManager().getUser(userID);
+ String realpassword = LoginServlet.getEncryptedPassword(
+ request, user.getUserName(), user.getPassword());
+ password = userPass.substring(p+1);
+ if ( (!userID.trim().equals(user.getUserName()))
+ && (!password.trim().equals(realpassword)))
+ {
+ valid = true;
+ }
+ }
+ }
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ mLogger.debug(e);
+ }
+ if (valid) return userID;
+ return null;
+ }
+
+ //----------------------------------------------------------- internal utilities
+
+ /**
+ * Create next member list suitable for use in entry collection.
+ * Puts state date, end date and off set in request parameters.
+ */
+ private String createNextLink(
+ WeblogEntryData entry, Date start, Date end, int offset)
+ {
+ SimpleDateFormat df = new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ssZ" );
+ String absUrl = mRollerContext.getAbsoluteContextUrl();
+ String url = absUrl + "/atom/" + mUsername + "/entries/" + entry.getId();
+ if (offset != -1 && start != null && end != null)
+ {
+ url = url + "?Range=" + df.format(start) + "/" + df.format(end);
+ }
+ else if (offset != -1 && start != null)
+ {
+ url = url + "?Range=" + df.format(start) + "/";
+ }
+ else if (offset != -1 && end != null)
+ {
+ url = url + "?Range=/" + df.format(end);
+ }
+ if (offset != -1)
+ {
+ url = url + "&offset=" + (offset + mMaxEntries);
+ }
+ return url;
+ }
+
+ /**
+ * Create a Rome Atom entry based on a Roller entry.
+ * Content is escaped.
+ * Link is stored as rel=alternate link.
+ */
+ private Entry createAtomEntry(WeblogEntryData entry)
+ {
+ Entry atomEntry = new Entry();
+ Content content = new Content();
+ content.setMode(Content.ESCAPED);
+ content.setValue(entry.getText());
+ List contents = new ArrayList();
+ contents.add(content);
+
+ atomEntry.setId( entry.getId());
+ atomEntry.setTitle( entry.getTitle());
+ atomEntry.setContents( contents);
+ atomEntry.setIssued( entry.getPubTime());
+ atomEntry.setModified( entry.getUpdateTime());
+
+ List links = new ArrayList();
+ Link altlink = new Link();
+ altlink.setRel("alternate");
+ altlink.setHref(entry.getPermaLink());
+ links.add(altlink);
+ atomEntry.setAlternateLinks(links);
+
+ return atomEntry;
+ }
+
+ /**
+ * Create a Roller weblog entry based on a Rome Atom entry object
+ */
+ private WeblogEntryData createRollerEntry(WebsiteData website, Entry entry)
+ {
+ Timestamp current = new Timestamp(System.currentTimeMillis());
+ Timestamp pubTime = current;
+ Timestamp updateTime = current;
+ if (entry.getIssued() != null)
+ {
+ pubTime = new Timestamp( entry.getIssued().getTime() );
+ }
+ if (entry.getModified() != null)
+ {
+ updateTime = new Timestamp( entry.getModified().getTime() );
+ }
+ WeblogEntryData rollerEntry = new WeblogEntryData();
+ rollerEntry.setTitle(entry.getTitle());
+ rollerEntry.setText( ((Content)entry.getContents().get(0)).getValue() );
+ rollerEntry.setPubTime(pubTime);
+ rollerEntry.setUpdateTime(updateTime);
+ rollerEntry.setWebsite(website);
+ rollerEntry.setPublishEntry( Boolean.TRUE );
+ rollerEntry.setCategory(website.getBloggerCategory());
+
+ return rollerEntry;
+ }
+}
Added: incubator/roller/branches/roller_1.x/src/org/roller/presentation/atomapi/WSSEUtilities.java
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/presentation/atomapi/WSSEUtilities.java?rev=327589&view=auto
==============================================================================
--- incubator/roller/branches/roller_1.x/src/org/roller/presentation/atomapi/WSSEUtilities.java (added)
+++ incubator/roller/branches/roller_1.x/src/org/roller/presentation/atomapi/WSSEUtilities.java Fri Oct 21 14:27:36 2005
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2005, Dave Johnson
+ *
+ * Licensed 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.
+ */
+package org.roller.presentation.atomapi;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.apache.commons.codec.binary.Base64;
+
+/**
+ * Utilties to support WSSE authentication.
+ * @author Dave Johnson
+ */
+public class WSSEUtilities {
+ public static synchronized String generateDigest(
+ byte[] nonce, byte[] created, byte[] password) {
+ String result = null;
+ try {
+ MessageDigest digester = MessageDigest.getInstance("SHA");
+ digester.reset();
+ digester.update(nonce);
+ digester.update(created);
+ digester.update(password);
+ byte[] digest = digester.digest();
+ result = new String(base64Encode(digest));
+ }
+ catch (NoSuchAlgorithmException e) {
+ result = null;
+ }
+ return result;
+ }
+ public static byte[] base64Decode(String value) throws IOException {
+ return Base64.decodeBase64(value.getBytes("UTF-8"));
+ }
+ public static String base64Encode(byte[] value) {
+ return new String(Base64.encodeBase64(value));
+ }
+ public static String generateWSSEHeader(String userName, String password)
+ throws UnsupportedEncodingException {
+
+ byte[] nonceBytes = Long.toString(new Date().getTime()).getBytes();
+ String nonce = new String(WSSEUtilities.base64Encode(nonceBytes));
+
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
+ String created = sdf.format(new Date());
+
+ String digest = WSSEUtilities.generateDigest(
+ nonceBytes, created.getBytes("UTF-8"), password.getBytes("UTF-8"));
+
+ StringBuffer header = new StringBuffer("UsernameToken Username=\"");
+ header.append(userName);
+ header.append("\", ");
+ header.append("PasswordDigest=\"");
+ header.append(digest);
+ header.append("\", ");
+ header.append("Nonce=\"");
+ header.append(nonce);
+ header.append("\", ");
+ header.append("Created=\"");
+ header.append(created);
+ header.append("\"");
+ return header.toString();
+ }
+}
Added: incubator/roller/branches/roller_1.x/src/org/roller/presentation/atomapi/package.html
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/presentation/atomapi/package.html?rev=327589&view=auto
==============================================================================
--- incubator/roller/branches/roller_1.x/src/org/roller/presentation/atomapi/package.html (added)
+++ incubator/roller/branches/roller_1.x/src/org/roller/presentation/atomapi/package.html Fri Oct 21 14:27:36 2005
@@ -0,0 +1,10 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+ <title></title>
+</head>
+<body>
+ROME-based Atom Protocol implementation.
+
+</body>
+</html>
Added: incubator/roller/branches/roller_1.x/src/org/roller/presentation/bookmarks/actions/BookmarkEditAction.java
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/presentation/bookmarks/actions/BookmarkEditAction.java?rev=327589&view=auto
==============================================================================
--- incubator/roller/branches/roller_1.x/src/org/roller/presentation/bookmarks/actions/BookmarkEditAction.java (added)
+++ incubator/roller/branches/roller_1.x/src/org/roller/presentation/bookmarks/actions/BookmarkEditAction.java Fri Oct 21 14:27:36 2005
@@ -0,0 +1,93 @@
+/*
+ * Created on Oct 21, 2003
+ */
+package org.roller.presentation.bookmarks.actions;
+
+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.roller.model.BookmarkManager;
+import org.roller.pojos.BookmarkData;
+import org.roller.pojos.FolderData;
+import org.roller.pojos.WebsiteData;
+import org.roller.presentation.RollerRequest;
+import org.roller.presentation.bookmarks.formbeans.BookmarkFormEx;
+import org.roller.presentation.forms.BookmarkForm;
+
+import java.util.LinkedList;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * @struts.action path="/editor/bookmarkEdit" name="bookmarkFormEx" validate="false"
+ * @struts.action-forward name="BookmarkForm" path="/bookmarks/BookmarkForm.jsp"
+ *
+ * @author Dave Johnson
+ */
+public class BookmarkEditAction extends Action
+{
+ public ActionForward execute(
+ ActionMapping mapping,
+ ActionForm actionForm,
+ HttpServletRequest request,
+ HttpServletResponse response)
+ throws Exception
+ {
+ RollerRequest rreq = RollerRequest.getRollerRequest(request);
+ WebsiteData wd = rreq.getWebsite();
+ BookmarkManager bmgr = rreq.getRoller().getBookmarkManager();
+ BookmarkFormEx form = (BookmarkFormEx)actionForm;
+
+ FolderData parentFolder = null;
+ if (null!=rreq.getBookmark() && null==request.getParameter("correct"))
+ {
+ // If request specifies bookmark and we are not correcting an
+ // already submitted form then load that bookmark into the form.
+ BookmarkData bd = rreq.getBookmark();
+ form.copyFrom(bd, request.getLocale());
+ request.setAttribute("state","edit");
+
+ // Pass bookmark's Folder on as attribute.
+ parentFolder = bd.getFolder();
+ }
+ else if (null != request.getParameter("correct"))
+ {
+ // We are correcting a previously submtted form.
+ request.setAttribute("state","correcting");
+
+ // Folder is specified by request param, pass it on as attribute.
+ parentFolder = bmgr.retrieveFolder(rreq.getFolder().getId());
+ }
+ else
+ {
+ // We are adding a new bookmark
+ request.setAttribute("state","add");
+
+ // Folder is specified by request param, pass it on as attribute.
+ parentFolder = bmgr.retrieveFolder(rreq.getFolder().getId());
+ }
+
+ // Build folder path for display on page
+ if (null != parentFolder)
+ {
+ request.setAttribute(
+ RollerRequest.FOLDERID_KEY, parentFolder.getId());
+
+ LinkedList folderPath = new LinkedList();
+ folderPath.add(0, parentFolder);
+ FolderData parent = parentFolder.getParent();
+ while (parent != null)
+ {
+ folderPath.add(0, parent);
+ parent = parent.getParent();
+ }
+ request.setAttribute("parentFolder", parentFolder);
+ request.setAttribute("folderPath", folderPath);
+ }
+
+ return mapping.findForward("BookmarkForm");
+ }
+
+}
Added: incubator/roller/branches/roller_1.x/src/org/roller/presentation/bookmarks/actions/BookmarkSaveAction.java
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/presentation/bookmarks/actions/BookmarkSaveAction.java?rev=327589&view=auto
==============================================================================
--- incubator/roller/branches/roller_1.x/src/org/roller/presentation/bookmarks/actions/BookmarkSaveAction.java (added)
+++ incubator/roller/branches/roller_1.x/src/org/roller/presentation/bookmarks/actions/BookmarkSaveAction.java Fri Oct 21 14:27:36 2005
@@ -0,0 +1,78 @@
+/*
+ * Created on Oct 21, 2003
+ */
+package org.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.roller.RollerPermissionsException;
+import org.roller.model.BookmarkManager;
+import org.roller.pojos.BookmarkData;
+import org.roller.pojos.FolderData;
+import org.roller.presentation.RollerRequest;
+import org.roller.presentation.bookmarks.formbeans.BookmarkFormEx;
+
+/**
+ * @struts.action path="/editor/bookmarkSave" name="bookmarkFormEx"
+ * validate="true" input="/editor/bookmarkEdit.do"
+ * @struts.action-forward name="Bookmarks" path="/editor/bookmarks.do?method=selectFolder"
+ *
+ * @author Dave Johnson
+ */
+public class BookmarkSaveAction extends Action
+{
+ public ActionForward execute(
+ ActionMapping mapping,
+ ActionForm actionForm,
+ HttpServletRequest request,
+ HttpServletResponse response)
+ throws Exception
+ {
+ ActionForward forward = mapping.findForward("Bookmarks");
+ try
+ {
+ BookmarkFormEx form = (BookmarkFormEx)actionForm;
+ RollerRequest rreq = RollerRequest.getRollerRequest(request);
+ BookmarkManager bmgr = rreq.getRoller().getBookmarkManager();
+
+ BookmarkData bd = null;
+ if (null != form.getId() && !form.getId().trim().equals(""))
+ {
+ bd = bmgr.retrieveBookmark(form.getId());
+ bd.save(); // should throw if save not permitted
+ }
+ else
+ {
+ bd = bmgr.createBookmark();
+
+ // Existing bookmarks already have folders, but this is a new one.
+ FolderData fd = bmgr.retrieveFolder(
+ request.getParameter(RollerRequest.FOLDERID_KEY));
+ bd.setFolder(fd);
+ }
+ form.copyTo(bd, request.getLocale());
+ bd.save();
+ rreq.getRoller().commit();
+
+ request.setAttribute(
+ RollerRequest.FOLDERID_KEY,bd.getFolder().getId());
+ }
+ catch (RollerPermissionsException e)
+ {
+ ActionErrors errors = new ActionErrors();
+ errors.add(null, new ActionError("error.permissions.deniedSave"));
+ saveErrors(request, errors);
+ forward = mapping.findForward("access-denied");
+ }
+ return forward;
+
+ }
+
+}
Added: incubator/roller/branches/roller_1.x/src/org/roller/presentation/bookmarks/actions/BookmarksAction.java
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/presentation/bookmarks/actions/BookmarksAction.java?rev=327589&view=auto
==============================================================================
--- incubator/roller/branches/roller_1.x/src/org/roller/presentation/bookmarks/actions/BookmarksAction.java (added)
+++ incubator/roller/branches/roller_1.x/src/org/roller/presentation/bookmarks/actions/BookmarksAction.java Fri Oct 21 14:27:36 2005
@@ -0,0 +1,301 @@
+/*
+ * Created on Oct 21, 2003
+ */
+package org.roller.presentation.bookmarks.actions;
+
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.LinkedList;
+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.roller.RollerException;
+import org.roller.model.BookmarkManager;
+import org.roller.pojos.BookmarkData;
+import org.roller.pojos.FolderData;
+import org.roller.pojos.WebsiteData;
+import org.roller.presentation.RollerRequest;
+import org.roller.presentation.bookmarks.formbeans.BookmarksForm;
+
+/**
+ * Actions that are initiated from the BookmarksForm.
+ *
+ * @struts.action name="bookmarksForm" path="/editor/bookmarks" parameter="method"
+ * @struts.action-forward name="BookmarksForm" path="/bookmarks/BookmarksForm.jsp"
+ *
+ * @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
+ {
+ RollerRequest rreq = RollerRequest.getRollerRequest(request);
+ if (rreq.isUserAuthorizedToEdit())
+ {
+ addModelObjects(request, (BookmarksForm)actionForm);
+ 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
+ {
+ RollerRequest rreq = RollerRequest.getRollerRequest(request);
+ if (rreq.isUserAuthorizedToEdit())
+ {
+ BookmarkManager bmgr = rreq.getRoller().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.retrieveFolder(folders[i]);
+ fd.remove(); // removes child folders and bookmarks too
+ }
+ }
+
+ String bookmarks[] = form.getSelectedBookmarks();
+ if (null != bookmarks)
+ {
+ for (int j = 0; j < bookmarks.length; j++)
+ {
+ bmgr.removeBookmark(bookmarks[j]);
+ }
+ }
+ rreq.getRoller().commit();
+
+ addModelObjects(request, (BookmarksForm)actionForm);
+ 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");
+ RollerRequest rreq = RollerRequest.getRollerRequest(request);
+ if (rreq.isUserAuthorizedToEdit())
+ {
+ try
+ {
+ BookmarkManager bmgr = rreq.getRoller().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.retrieveFolder(form.getMoveToFolderId());
+ if (null != folders)
+ {
+ for (int i = 0; i < folders.length; i++)
+ {
+ FolderData fd = bmgr.retrieveFolder(folders[i]);
+
+ // Don't move folder into itself.
+ if ( !fd.getId().equals(parent.getId())
+ && !parent.descendentOf(fd))
+ {
+ fd.setParent(parent);
+ fd.save();
+ }
+ 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++)
+ {
+ BookmarkData bd = bmgr.retrieveBookmark(bookmarks[j]);
+ bd.setFolder(parent);
+ bd.save();
+ }
+ }
+ rreq.getRoller().commit();
+
+ addModelObjects(request, (BookmarksForm)actionForm);
+ saveMessages(request, messages);
+ }
+ 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;
+ }
+
+ /**
+ * Load model objects for display in BookmarksForm.
+ * @param request
+ * @throws RollerException
+ */
+ private void addModelObjects(HttpServletRequest request, BookmarksForm form)
+ throws RollerException
+ {
+ RollerRequest rreq = RollerRequest.getRollerRequest(request);
+ WebsiteData wd = rreq.getWebsite();
+ BookmarkManager bmgr = rreq.getRoller().getBookmarkManager();
+
+ TreeSet 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();
+ }
+
+ FolderData folder = null;
+ if (null == folderId || folderId.equals("null"))
+ {
+ folder = bmgr.getRootFolder(wd);
+ }
+ else
+ {
+ folder = bmgr.retrieveFolder(folderId);
+ }
+ form.setFolderId(folder.getId());
+
+ request.setAttribute("folder", folder);
+ request.setAttribute("folders", folder.getFolders());
+ request.setAttribute("bookmarks", folder.getBookmarks());
+
+ if (null != folder.getParent())
+ {
+ LinkedList folderPath = new LinkedList();
+ folderPath.add(0, folder);
+ FolderData parent = folder.getParent();
+ while (parent != null)
+ {
+ folderPath.add(0, parent);
+ parent = parent.getParent();
+ }
+ request.setAttribute("folderPath", folderPath);
+
+ request.setAttribute(
+ RollerRequest.PARENTID_KEY, folder.getParent().getId());
+ }
+
+ // Build list of all folders, except for current one, sorted by path.
+ Iterator iter = bmgr.getAllFolders(wd).iterator();
+
+ // Build list of only children
+ //Iterator iter = folder.getFolders().iterator();
+
+ //int max = 20, count = 0;
+ while (iter.hasNext()) // && count < max)
+ {
+ //count++;
+ FolderData fd = (FolderData) iter.next();
+ if (!fd.getId().equals(folderId))
+ {
+ allFolders.add(fd);
+ }
+ }
+ request.setAttribute("allFolders", allFolders);
+ }
+
+ 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;
+ }
+ }
+}
Added: incubator/roller/branches/roller_1.x/src/org/roller/presentation/bookmarks/actions/FolderEditAction.java
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/presentation/bookmarks/actions/FolderEditAction.java?rev=327589&view=auto
==============================================================================
--- incubator/roller/branches/roller_1.x/src/org/roller/presentation/bookmarks/actions/FolderEditAction.java (added)
+++ incubator/roller/branches/roller_1.x/src/org/roller/presentation/bookmarks/actions/FolderEditAction.java Fri Oct 21 14:27:36 2005
@@ -0,0 +1,73 @@
+/*
+ * Created on Oct 21, 2003
+ */
+package org.roller.presentation.bookmarks.actions;
+
+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.roller.model.BookmarkManager;
+import org.roller.pojos.FolderData;
+import org.roller.presentation.RollerRequest;
+import org.roller.presentation.bookmarks.formbeans.FolderFormEx;
+
+import java.util.LinkedList;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * @struts.action path="/editor/folderEdit" name="folderFormEx" validate="false"
+ * @struts.action-forward name="FolderForm" path="/bookmarks/FolderForm.jsp"
+ *
+ * @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 = rreq.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();
+ }
+ 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.retrieveFolder(parentId);
+ }
+ else
+ {
+ // We are adding a new bookmark
+ request.setAttribute("state","add");
+
+ String parentId = request.getParameter(RollerRequest.PARENTID_KEY);
+ parentFolder = bmgr.retrieveFolder(parentId);
+ }
+
+ request.setAttribute(RollerRequest.PARENTID_KEY, parentFolder.getId());
+ request.setAttribute("parentFolder", parentFolder);
+
+ return mapping.findForward("FolderForm");
+ }
+
+}
Added: incubator/roller/branches/roller_1.x/src/org/roller/presentation/bookmarks/actions/FolderSaveAction.java
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/presentation/bookmarks/actions/FolderSaveAction.java?rev=327589&view=auto
==============================================================================
--- incubator/roller/branches/roller_1.x/src/org/roller/presentation/bookmarks/actions/FolderSaveAction.java (added)
+++ incubator/roller/branches/roller_1.x/src/org/roller/presentation/bookmarks/actions/FolderSaveAction.java Fri Oct 21 14:27:36 2005
@@ -0,0 +1,104 @@
+/*
+ * Created on Oct 21, 2003
+ */
+package org.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.roller.RollerException;
+import org.roller.RollerPermissionsException;
+import org.roller.model.BookmarkManager;
+import org.roller.pojos.FolderData;
+import org.roller.pojos.WebsiteData;
+import org.roller.presentation.RollerRequest;
+import org.roller.presentation.bookmarks.formbeans.FolderFormEx;
+
+/**
+ * @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);
+ WebsiteData wd = rreq.getWebsite();
+ BookmarkManager bmgr = rreq.getRoller().getBookmarkManager();
+
+ FolderData fd = null;
+ if (null != form.getId() && !form.getId().trim().equals(""))
+ {
+ fd = bmgr.retrieveFolder(form.getId());
+ fd.save(); // should throw if save not permitted
+ }
+ else
+ {
+ fd = bmgr.createFolder();
+
+ String parentId = request.getParameter(RollerRequest.PARENTID_KEY);
+ FolderData parent = null;
+ if (null != parentId && !parentId.trim().equalsIgnoreCase("null"))
+ {
+ parent = bmgr.retrieveFolder(parentId);
+ }
+ else
+ {
+ parent = bmgr.getRootFolder(wd);
+ }
+ fd.setParent(parent);
+ fd.setWebsite(wd);
+ }
+
+ // Copy form values to object
+ form.copyTo(fd, request.getLocale());
+
+ try
+ {
+ // Store object and commit
+ fd.save();
+ rreq.getRoller().commit();
+ }
+ catch (RollerPermissionsException e)
+ {
+ ActionErrors errors = new ActionErrors();
+ errors.add(null, new ActionError("error.permissions.deniedSave"));
+ saveErrors(request, errors);
+ forward = mapping.findForward("access-denied");
+ }
+ catch (RollerException re)
+ {
+ rreq.getRoller().rollback();
+ ActionErrors errors = new ActionErrors();
+ String msg = (null != re.getRootCause())
+ ? re.getRootCause().toString()
+ : re.toString();
+ errors.add(ActionErrors.GLOBAL_ERROR,
+ new ActionError("folderForm.save.exception", msg));
+ saveErrors(request,errors);
+ }
+
+ if (null != fd.getParent())
+ {
+ request.setAttribute(
+ RollerRequest.FOLDERID_KEY, fd.getParent().getId());
+ }
+ return forward;
+ }
+}
Added: incubator/roller/branches/roller_1.x/src/org/roller/presentation/bookmarks/actions/ImportBookmarksFormAction.java
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/presentation/bookmarks/actions/ImportBookmarksFormAction.java?rev=327589&view=auto
==============================================================================
--- incubator/roller/branches/roller_1.x/src/org/roller/presentation/bookmarks/actions/ImportBookmarksFormAction.java (added)
+++ incubator/roller/branches/roller_1.x/src/org/roller/presentation/bookmarks/actions/ImportBookmarksFormAction.java Fri Oct 21 14:27:36 2005
@@ -0,0 +1,161 @@
+
+package org.roller.presentation.bookmarks.actions;
+
+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.roller.model.BookmarkManager;
+import org.roller.presentation.RollerRequest;
+import org.roller.presentation.bookmarks.formbeans.FolderFormEx;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+
+/////////////////////////////////////////////////////////////////////////////
+/**
+ * @struts.action name="folderFormEx" path="/editor/importBookmarks"
+ * scope="request" input="/bookmarks/import.jsp" validate="false"
+ *
+ * @struts.action-forward name="importBookmarks.page" path="/bookmarks/import.jsp"
+ *
+ * TODO Should import into folder with same name as imported file
+ */
+public final class ImportBookmarksFormAction extends Action
+{
+ 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 IOException, ServletException
+ {
+ ActionErrors errors = new ActionErrors();
+ FolderFormEx theForm = (FolderFormEx)actionForm;
+ ActionForward fwd = mapping.findForward("importBookmarks.page");
+ if ( 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; //theForm.getWriteFile();
+
+ //retrieve the file representation
+ FormFile file = theForm.getBookmarksFile();
+ /*
+ //retrieve the file name
+ String fileName= file.getFileName();
+
+ //retrieve the content type
+ String contentType = file.getContentType();
+
+ //retrieve the file size
+ String size = (file.getFileSize() + " bytes");
+ */
+ 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
+ RollerRequest rreq =
+ RollerRequest.getRollerRequest(request);
+ BookmarkManager bm =
+ rreq.getRoller().getBookmarkManager();
+ bm.importBookmarks(rreq.getWebsite(), folderName, data);
+
+ rreq.getRoller().commit();
+ }
+ 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";
+ }
+ }
+ else
+ {
+ //write the file to the file specified
+ /*OutputStream bos =
+ new FileOutputStream(theForm.getFilePath());
+ int bytesRead = 0;
+ byte[] buffer = new byte[8192];
+ while ((bytesRead = stream.read(buffer, 0, 8192)) != -1) {
+ bos.write(buffer, 0, bytesRead);
+ }
+ bos.close();
+ data = "The file has been written to \""
+ + theForm.getFilePath() + "\"";
+ */
+ }
+ }
+ catch (Exception e)
+ {
+ errors.add(ActionErrors.GLOBAL_ERROR,
+ new ActionError("error.importing.bookmarks",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();
+ }
+ return fwd;
+ }
+}
+
Added: incubator/roller/branches/roller_1.x/src/org/roller/presentation/bookmarks/actions/package.html
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/presentation/bookmarks/actions/package.html?rev=327589&view=auto
==============================================================================
--- incubator/roller/branches/roller_1.x/src/org/roller/presentation/bookmarks/actions/package.html (added)
+++ incubator/roller/branches/roller_1.x/src/org/roller/presentation/bookmarks/actions/package.html Fri Oct 21 14:27:36 2005
@@ -0,0 +1,10 @@
+<!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/branches/roller_1.x/src/org/roller/presentation/bookmarks/formbeans/BookmarkFormEx.java
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/presentation/bookmarks/formbeans/BookmarkFormEx.java?rev=327589&view=auto
==============================================================================
--- incubator/roller/branches/roller_1.x/src/org/roller/presentation/bookmarks/formbeans/BookmarkFormEx.java (added)
+++ incubator/roller/branches/roller_1.x/src/org/roller/presentation/bookmarks/formbeans/BookmarkFormEx.java Fri Oct 21 14:27:36 2005
@@ -0,0 +1,60 @@
+/*
+ * Created on Apr 8, 2003
+ */
+package org.roller.presentation.bookmarks.formbeans;
+
+import org.roller.RollerException;
+import org.roller.pojos.BookmarkData;
+import org.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.roller.presentation.forms.BookmarkForm#setData(org.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/branches/roller_1.x/src/org/roller/presentation/bookmarks/formbeans/BookmarksForm.java
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/presentation/bookmarks/formbeans/BookmarksForm.java?rev=327589&view=auto
==============================================================================
--- incubator/roller/branches/roller_1.x/src/org/roller/presentation/bookmarks/formbeans/BookmarksForm.java (added)
+++ incubator/roller/branches/roller_1.x/src/org/roller/presentation/bookmarks/formbeans/BookmarksForm.java Fri Oct 21 14:27:36 2005
@@ -0,0 +1,69 @@
+/*
+ * Created on Oct 21, 2003
+ */
+package org.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/branches/roller_1.x/src/org/roller/presentation/bookmarks/formbeans/FolderFormEx.java
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/presentation/bookmarks/formbeans/FolderFormEx.java?rev=327589&view=auto
==============================================================================
--- incubator/roller/branches/roller_1.x/src/org/roller/presentation/bookmarks/formbeans/FolderFormEx.java (added)
+++ incubator/roller/branches/roller_1.x/src/org/roller/presentation/bookmarks/formbeans/FolderFormEx.java Fri Oct 21 14:27:36 2005
@@ -0,0 +1,88 @@
+
+package org.roller.presentation.bookmarks.formbeans;
+
+import org.apache.struts.upload.FormFile;
+import org.roller.RollerException;
+import org.roller.pojos.FolderData;
+import org.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/branches/roller_1.x/src/org/roller/presentation/bookmarks/formbeans/package.html
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/presentation/bookmarks/formbeans/package.html?rev=327589&view=auto
==============================================================================
--- incubator/roller/branches/roller_1.x/src/org/roller/presentation/bookmarks/formbeans/package.html (added)
+++ incubator/roller/branches/roller_1.x/src/org/roller/presentation/bookmarks/formbeans/package.html Fri Oct 21 14:27:36 2005
@@ -0,0 +1,10 @@
+<!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/branches/roller_1.x/src/org/roller/presentation/bookmarks/tags/ViewBookmarksTag.java
URL: http://svn.apache.org/viewcvs/incubator/roller/branches/roller_1.x/src/org/roller/presentation/bookmarks/tags/ViewBookmarksTag.java?rev=327589&view=auto
==============================================================================
--- incubator/roller/branches/roller_1.x/src/org/roller/presentation/bookmarks/tags/ViewBookmarksTag.java (added)
+++ incubator/roller/branches/roller_1.x/src/org/roller/presentation/bookmarks/tags/ViewBookmarksTag.java Fri Oct 21 14:27:36 2005
@@ -0,0 +1,234 @@
+package org.roller.presentation.bookmarks.tags;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.roller.model.BookmarkManager;
+import org.roller.pojos.BookmarkComparator;
+import org.roller.pojos.BookmarkData;
+import org.roller.pojos.FolderData;
+import org.roller.pojos.UserData;
+import org.roller.presentation.RollerContext;
+import org.roller.presentation.RollerRequest;
+import org.roller.util.Utilities;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.net.MalformedURLException;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.Vector;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.jsp.JspException;
+import javax.servlet.jsp.PageContext;
+import javax.servlet.jsp.tagext.Tag;
+
+
+/**
+ * @deprecated Is this class even in use anymore? -Lance
+ *
+ * <p>Displays a folder of bookmarks or a table that shows all folders.
+ * If the folderName property is set then this tag will display the bookmarks
+ * in that folder, separated by BR tag line breaks. If the folderName
+ * property is not set, this tag will display a table of bookmarks.
+ * </p>
+ * <p>The bookmarks table display uses the Folder Column and Row values
+ * to position the Folders in a table. The bookmarks within each folder
+ * are ordered using the Bookmark Priority value. A bookmark's HREF tag
+ * is given a CSS class of rBookmark_N where N is the Bookmark's Weight value.
+ * </p>
+ * @jsp.tag name="ViewBookmarks"
+ */
+public class ViewBookmarksTag extends org.roller.presentation.tags.HybridTag
+{
+ static final long serialVersionUID = -4357415994168654686L;
+
+ private static Log mLogger =
+ LogFactory.getFactory().getInstance(ViewBookmarksTag.class);
+
+ /** @jsp.attribute */
+ public String getFolderName() { return mFolderName; }
+ public void setFolderName(String v) { mFolderName = v; }
+ private String mFolderName = null;
+
+ /** @jsp.attribute */
+ public String getTitle() { return mTitle; }
+ public void setTitle(String v) { mTitle = v; }
+ private String mTitle = null;
+
+ /** @jsp.attribute */
+ public boolean getShowFolderName() { return mShowFolderName; }
+ public void setShowFolderName(boolean v) { mShowFolderName = v; }
+ private boolean mShowFolderName = true;
+
+ /** @jsp.attribute */
+ public boolean getExpandingFolder() { return mExpandingFolder; }
+ public void setExpandingFolder(boolean v) { mExpandingFolder = v; }
+ private boolean mExpandingFolder = false;
+
+ //------------------------------------------------------------------------
+
+ public String view( String folderName, String title )
+ {
+ mFolderName = folderName;
+ mTitle = title;
+ return emit();
+ }
+
+ public String view( String folderName, boolean showFolderName )
+ {
+ mFolderName = folderName;
+ mShowFolderName = showFolderName;
+ return emit();
+ }
+
+ public String view( String folderName, boolean showFolderName, boolean expandingFolder )
+ {
+ mFolderName = folderName;
+ mShowFolderName = showFolderName;
+ mExpandingFolder = expandingFolder;
+ return emit();
+ }
+
+ //-------------------------------------------------------------
+ /**
+ * Process start tag
+ * @return EVAL_SKIP_BODY
+ */
+ public int doStartTag( PrintWriter pw ) throws JspException
+ {
+ try
+ {
+ HttpServletRequest req =
+ (HttpServletRequest)pageContext.getRequest();
+ RollerRequest rreq = RollerRequest.getRollerRequest(req);
+ BookmarkManager bookmarkMgr =
+ rreq.getRoller().getBookmarkManager();
+ UserData user = rreq.getUser();
+
+ FolderData fd = bookmarkMgr.getFolder(
+ rreq.getWebsite(), mFolderName);
+
+ if ( fd == null )
+ {
+ pw.print("<span class=\"error\">");
+ pw.print("Error fetching folder named "+mFolderName);
+ pw.print("</span>");
+ return Tag.SKIP_BODY;
+ }
+ emitFolderHTML( pw, pageContext, fd, user );
+ return Tag.SKIP_BODY;
+ }
+ catch (Exception e)
+ {
+ mLogger.error("Exception",e);
+ throw new JspException(
+ e.getClass().toString()+": "+e.getMessage(),e);
+ }
+ }
+
+ //------------------------------------------------------------------------
+ public void emitBookmarkHTML( PrintWriter pw, PageContext ctx,
+ BookmarkData bookmark, UserData user )
+ throws IOException, MalformedURLException
+ {
+ HttpServletRequest request = (HttpServletRequest)ctx.getRequest();
+ String cpath = request.getContextPath();
+
+ String resourcePath = request.getContextPath()
+ + RollerContext.getUploadPath(pageContext.getServletContext())
+ + "/" + user.getUserName();
+
+ if ( bookmark.getImage()!=null
+ && !bookmark.getImage().trim().equals("") )
+ {
+ pw.print("<a href=\""+bookmark.getUrl()+"\">");
+ pw.println("<img src=\""
+ + resourcePath + "/" + bookmark.getImage() + "\" "
+ + "alt=\"" + bookmark.getName() + "\" /> " );
+ pw.println("</a><br />");
+ }
+ else if ( bookmark.getFeedUrl()!=null
+ && !bookmark.getFeedUrl().trim().equals("") )
+ {
+ pw.print("<a class=\"rBookmark\" href=\""+bookmark.getUrl()+"\"");
+ if ( !bookmark.getDescription().trim().equals("") )
+ {
+ pw.print(" title=\""+bookmark.getDescription()+"\"");
+ }
+ pw.print(" >");
+ pw.println( bookmark.getName()+"</a>");
+
+ pw.println( "<a href=\""+bookmark.getFeedUrl()+"\">" );
+ pw.print ( "<img src=\""+cpath+"/images/smrssbadge.gif\" " );
+ pw.println( "alt=\"URL of site's RSS feed\"" );
+ pw.println( "class=\"smrssbadge\" /></a>" );
+
+ pw.println( "<br />" );
+ }
+ else
+ {
+ pw.print( "<a href=\"" );
+ pw.print( bookmark.getUrl() );
+ pw.print( "\" " );
+ pw.print( "class=\"rBookmark" );
+ pw.print( bookmark.getWeight() );
+ pw.print( "\" " );
+ pw.print( "title=\"" );
+ pw.print( bookmark.getDescription() );
+ pw.print( "\" >" );
+ pw.print( bookmark.getName() );
+ pw.println( "</a><br />" );
+ }
+ }
+
+ //------------------------------------------------------------------------
+ public void emitFolderHTML( PrintWriter pw, PageContext ctx,
+ FolderData folder, UserData user )
+ throws IOException, MalformedURLException
+ {
+ HttpServletRequest request = (HttpServletRequest)ctx.getRequest();
+ String cpath = request.getContextPath();
+ // replace spaces with underscores
+ String divId = Utilities.stringReplace( folder.getName(), " ", "_" );
+ // remove single quotes to prevent javascript errors
+ divId = Utilities.stringReplace( divId, "'", "" );
+
+ if ( mShowFolderName && !mExpandingFolder )
+ {
+ pw.println( "<div class=\"rFolder\">"+folder.getName()+"</div>" );
+ }
+
+ if ( mShowFolderName && mExpandingFolder )
+ {
+ pw.print( "<div class=\"rFolder\"><a href=\"javascript:" );
+ pw.print( "toggleFolder('"+divId+"')\"><span id=\"i"+divId+"\">" );
+ pw.print( "+</span> "+folder.getName()+"</a></div>" );
+ pw.println( "<div id=\""+divId+"\" style=\"display: none\">" );
+ }
+
+ Collection bookmarks = folder.getBookmarks();
+ //java.util.Collections.sort( bookmarks, new BookmarkComparator() );
+ Iterator iter = bookmarks.iterator();
+ while ( iter.hasNext() )
+ {
+ BookmarkData bookmark = (BookmarkData)iter.next();
+ emitBookmarkHTML( pw, ctx, bookmark, user );
+ }
+
+ if (mShowFolderName && mExpandingFolder)
+ {
+ pw.println( "</div>" );
+ pw.println( "<script type=\"text/javascript\">" );
+ pw.println( "<!--" );
+ pw.println( " folderPreference('"+divId+"');" );
+ pw.println( "// -->");
+ pw.println( "</script>" );
+ }
+ }
+}
+