From d9ec3210a556f7c2e87512762f36be8534d3524c Mon Sep 17 00:00:00 2001 From: "Eric J. Bowersox" Date: Thu, 30 Dec 2004 23:01:07 +0000 Subject: [PATCH] initial sketch of trackback-handling servlet --- etc/web.xml | 13 +- .../venice/db/PostLinkDecoder.java | 4 +- .../silverwrist/venice/ui/RequestInput.java | 163 +++++++-------- .../venice/ui/conf/PostShortcutServlet.java | 8 +- .../venice/ui/conf/TrackbackServlet.java | 188 ++++++++++++++++++ .../venice/ui/helpers/HTTPError.java | 6 +- 6 files changed, 292 insertions(+), 90 deletions(-) create mode 100644 src/com/silverwrist/venice/ui/conf/TrackbackServlet.java diff --git a/etc/web.xml b/etc/web.xml index d41965c..a8db2ef 100644 --- a/etc/web.xml +++ b/etc/web.xml @@ -97,7 +97,7 @@ PostShortcut - Redirects the user to a comunity, conference, topic, or message. + Redirects the user to a community, conference, topic, or message. com.silverwrist.venice.ui.conf.PostShortcutServlet @@ -125,6 +125,12 @@ com.silverwrist.venice.ui.rpc.XmlRpcServlet + + Trackback + Handles trackback requests. + com.silverwrist.venice.ui.conf.TrackbackServlet + + @@ -192,6 +198,11 @@ /RPC2 + + Trackback + /trackback/* + + 60 diff --git a/src/com/silverwrist/venice/db/PostLinkDecoder.java b/src/com/silverwrist/venice/db/PostLinkDecoder.java index 96e5cd4..eda30bd 100644 --- a/src/com/silverwrist/venice/db/PostLinkDecoder.java +++ b/src/com/silverwrist/venice/db/PostLinkDecoder.java @@ -9,9 +9,9 @@ * * The Original Code is the Venice Web Community System. * - * The Initial Developer of the Original Code is Eric J. Bowersox , + * The Initial Developer of the Original Code is Eric J. Bowersox , * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are - * Copyright (C) 2001-02 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * Copyright (C) 2001-2004 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. * * Contributor(s): */ diff --git a/src/com/silverwrist/venice/ui/RequestInput.java b/src/com/silverwrist/venice/ui/RequestInput.java index 5bcad4f..5cf1a95 100644 --- a/src/com/silverwrist/venice/ui/RequestInput.java +++ b/src/com/silverwrist/venice/ui/RequestInput.java @@ -38,14 +38,14 @@ public interface RequestInput extends ServiceProvider public static final String LEFT_MENU_SESSION_ATTR = "LeftMenu"; /** - * Returns a String containing the real path for a given virtual path. For example, + * Returns a {@link java.lang.String String} containing the real path for a given virtual path. For example, * the virtual path "/index.html" has a real path of whatever file on the server's filesystem - * would be served by a request for "/index.html".

- * This method returns null if the virtual path cannot be translated to a real path for + * would be served by a request for "/index.html".

+ * This method returns null if the virtual path cannot be translated to a real path for * any reason. * - * @param s A String specifying a virtual path. - * @return A String specifying the real path, or null if the translation cannot + * @param s A String specifying a virtual path. + * @return A String specifying the real path, or null if the translation cannot * be performed. */ public String mapPath(String s); @@ -55,8 +55,8 @@ public interface RequestInput extends ServiceProvider * context under which Venice is installed. The context path always comes first in a request URI. The * path starts with a "/" character but does not end with a "/" character. * - * @return A String specifying the portion of the request URI that indicates the context - * of the request. + * @return A {@link java.lang.String String} specifying the portion of the request URI that indicates the + * context of the request. */ public String getContextPath(); @@ -64,28 +64,28 @@ public interface RequestInput extends ServiceProvider * Returns the part of this request's URI that calls the servlet. This includes either the servlet name * or a path to the servlet, but does not include any extra path information or a query string. * - * @return A String containing the name or path of the servlet being called, as specified - * in the request URI. + * @return A {@link java.lang.String String} containing the name or path of the servlet being called, as + * specified in the request URI. */ public String getServletPath(); /** * Returns any extra path information associated with the URI the client sent when it made this request. * The extra path information follows the servlet path but precedes the query string. This method - * returns null if there was no extra path information. In Venice, the path information is + * returns null if there was no extra path information. In Venice, the path information is * used to specify parameters in certain servlets. * - * @return A String specifying extra path information that comes after the servlet path - * but before the query string in the request URI; or null if the URI does not + * @return A {@link java.lang.String String} specifying extra path information that comes after the servlet path + * but before the query string in the request URI; or null if the URI does not * have any extra path information. */ public String getPathInfo(); /** * Returns the query string that is contained in the request URI after the path. This method returns - * null if the URI does not have a query string. + * null if the URI does not have a query string. * - * @return A String containing the query string or null if the URI contains + * @return A {@link java.lang.String String} containing the query string or null if the URI contains * no query string. */ public String getQueryString(); @@ -93,20 +93,20 @@ public interface RequestInput extends ServiceProvider /** * Returns the name of the HTTP method with which this request was made, for example, GET, POST, or PUT. * - * @return A String specifying the name of the method with which this request was made. + * @return A {@link java.lang.String String} specifying the name of the method with which this request was made. */ public String getVerb(); /** * Returns the Internet Protocol (IP) address of the client that sent the request. * - * @return A String containing the IP address of the client that sent the request. + * @return A {@link java.lang.String String} containing the IP address of the client that sent the request. */ public String getSourceAddress(); /** - * Returns true if the request parameter with the specified name is defined, - * false if not. For standard Venice requests, parameters are contained in the + * Returns true if the request parameter with the specified name is defined, + * false if not. For standard Venice requests, parameters are contained in the * query string or posted form data. * * @param name Parameter name to be checked. @@ -115,117 +115,120 @@ public interface RequestInput extends ServiceProvider public boolean hasParameter(String name); /** - * Returns the value of a request parameter as a String, or null if the + * Returns the value of a request parameter as a {@link java.lang.String String}, or null if the * parameter does not exist. For standard Venice requests, parameters are contained in the query - * string or posted form data.

+ * string or posted form data.

* You should only use this method when you are sure the parameter has only one value. If the parameter - * might have more than one value, use {@link #getParameterValues(java.lang.String)}.

+ * might have more than one value, use {@link #getParameterValues(java.lang.String)}.

* If you use this method with a multivalued parameter, the value returned is equal to the first value - * in the array returned by getParameterValues. + * in the array returned by getParameterValues. * - * @param name A String specifying the name of the parameter. - * @return A String representing the single value of the parameter. + * @param name A String specifying the name of the parameter. + * @return A String representing the single value of the parameter. * @see #getParameterValues(java.lang.String) */ public String getParameter(String name); /** - * Returns the value of a request parameter as a int, or a specified default value if + * Returns the value of a request parameter as a int, or a specified default value if * the parameter does not exist. For standard Venice requests, parameters are contained in the query - * string or posted form data.

+ * string or posted form data.

* If you use this method with a multivalued parameter, the value returned is equal to the - * int equivalent of the first value in the array returned by getParameterValues. + * int equivalent of the first value in the array returned by + * {@link #getParameterValues(java.lang.String)}. * - * @param name A String specifying the name of the parameter. + * @param name A {@link java.lang.String String} specifying the name of the parameter. * @param default_value The default value to use for the parameter if the specified parameter does not exist. - * @return An int representing the single value of the parameter. + * @return An int representing the single value of the parameter. */ public int getParameterInt(String name, int default_value); /** - * Returns the value of a request parameter as a short, or a specified default value if + * Returns the value of a request parameter as a short, or a specified default value if * the parameter does not exist. For standard Venice requests, parameters are contained in the query - * string or posted form data.

+ * string or posted form data.

* If you use this method with a multivalued parameter, the value returned is equal to the - * short equivalent of the first value in the array returned by getParameterValues. + * short equivalent of the first value in the array returned by + * {@link #getParameterValues(java.lang.String)}. * - * @param name A String specifying the name of the parameter. + * @param name A {@link java.lang.String String} specifying the name of the parameter. * @param default_value The default value to use for the parameter if the specified parameter does not exist. - * @return A short representing the single value of the parameter. + * @return A short representing the single value of the parameter. */ public short getParameterShort(String name, short default_value); /** - * Returns the value of a request parameter as a long, or a specified default value if + * Returns the value of a request parameter as a long, or a specified default value if * the parameter does not exist. For standard Venice requests, parameters are contained in the query - * string or posted form data.

+ * string or posted form data.

* If you use this method with a multivalued parameter, the value returned is equal to the - * long equivalent of the first value in the array returned by getParameterValues. + * long equivalent of the first value in the array returned by + * {@link #getParameterValues(java.lang.String)}. * - * @param name A String specifying the name of the parameter. + * @param name A {@link java.lang.String String} specifying the name of the parameter. * @param default_value The default value to use for the parameter if the specified parameter does not exist. - * @return A long representing the single value of the parameter. + * @return A long representing the single value of the parameter. */ public long getParameterLong(String name, long default_value); /** - * Returns an Enumeration of String objects containing the names of the - * parameters contained in this request. If the request has no parameters, the method returns an empty - * Enumeration. + * Returns an {@link java.util.Enumeration Enumeration} of {@link java.lang.String String} objects containing + * the names of the parameters contained in this request. If the request has no parameters, the method returns + * an empty Enumeration. * - * @return An Enumeration of String objects, each String - * containing the name of a request parameter, or an empty Enumeration if the + * @return An Enumeration of String objects, each String + * containing the name of a request parameter, or an empty Enumeration if the * request has no parameters. */ public Enumeration getParameterNames(); /** - * Returns an array of String objects containing all of the values the given request - * parameter has, or null if the parameter does not exist.

+ * Returns an array of {@link java.lang.String String} objects containing all of the values the given request + * parameter has, or null if the parameter does not exist.

* If the parameter has a single value, the array has a length of 1. * - * @param name A String containing the name of the parameter whose value is requested. - * @return An array of String objects containing the parameter's values. + * @param name A String containing the name of the parameter whose value is requested. + * @return An array of String objects containing the parameter's values. * @see #getParameter(java.lang.String) */ public String[] getParameterValues(String name); /** - * Returns true if the specified parameter is a file parameter, false if - * not. If the parameter does not exist, the return value is false. + * Returns true if the specified parameter is a file parameter, false if + * not. If the parameter does not exist, the return value is false. * - * @param name A String containing the name of the parameter to test. + * @param name A {@link java.lang.String String} containing the name of the parameter to test. * @return See above. */ public boolean isFileParam(String name); /** * Returns the MIME type of the specified parameter. If the type cannot be determined, the return - * value is null.

+ * value is null.

* N.B.: For non-file parameters, or all parameters to a request that is not a file upload, the MIME * type is "text/plain". * - * @param name A String containing the name of the parameter to test. + * @param name A {@link java.lang.String String} containing the name of the parameter to test. * @return See above. */ public String getParameterType(String name); /** * Returns the size in bytes of the specified parameter. If the size cannot be determined, the return - * value is -1.

+ * value is -1.

* N.B.: For non-file parameters, or all parameters to a request that is not a file upload, the size * is the number of bytes occupied by the parameter, expressed in UTF-8 encoding. * - * @param name A String containing the name of the parameter to test. + * @param name A {@link java.lang.String String} containing the name of the parameter to test. * @return See above. */ public int getParameterSize(String name); /** - * Returns an InputStream reading from the data of the named file parameter. If the - * named parameter does not exist or is not a file parameter, returns null; + * Returns an {@link java.io.InputStream InputStream} reading from the data of the named file parameter. If the + * named parameter does not exist or is not a file parameter, returns null; * - * @param name A String containing the name of the parameter whose value is requested. + * @param name A {@link java.lang.String String} containing the name of the parameter whose value is requested. * @return See above. * @exception com.silverwrist.util.ServletMultipartException If there is a problem retrieving * the parameter data stream. @@ -233,20 +236,20 @@ public interface RequestInput extends ServiceProvider public InputStream getParameterDataStream(String name) throws ServletMultipartException; /** - * Returns true if the parameter set reflects the clicking of an image button with a - * specified name, false if not. + * Returns true if the parameter set reflects the clicking of an image button with a + * specified name, false if not. * - * @param name A String containing the name of the image button to test. + * @param name A {@link java.lang.String String} containing the name of the image button to test. * @return See above. */ public boolean isImageButtonClicked(String name); /** - * Returns the application-level attribute with the given name, or null if there is no + * Returns the application-level attribute with the given name, or null if there is no * attribute by that name. * - * @param name A String specifying the name of the attribute. - * @return An Object containing the value of the attribute, or null if no + * @param name A {@link java.lang.String String} specifying the name of the attribute. + * @return An {@link java.lang.Object Object} containing the value of the attribute, or null if no * attribute exists matching the given name. */ public Object getAppAttribute(String name); @@ -254,18 +257,18 @@ public interface RequestInput extends ServiceProvider /** * Sets the application-level attribute with the given name. * - * @param name A String specifying the name of the attribute. - * @param o The object to be bound as the value of that attribute, or null if the binding + * @param name A {@link java.lang.String String} specifying the name of the attribute. + * @param o The object to be bound as the value of that attribute, or null if the binding * is to be removed. */ public void setAppAttribute(String name, Object o); /** - * Returns the session-level attribute with the given name, or null if there is no + * Returns the session-level attribute with the given name, or null if there is no * attribute by that name. * - * @param name A String specifying the name of the attribute. - * @return An Object containing the value of the attribute, or null if no + * @param name A {@link java.lang.String String} specifying the name of the attribute. + * @return An {@link java.lang.Object Object} containing the value of the attribute, or null if no * attribute exists matching the given name. */ public Object getSessionAttribute(String name); @@ -273,18 +276,18 @@ public interface RequestInput extends ServiceProvider /** * Sets the session-level attribute with the given name. * - * @param name A String specifying the name of the attribute. - * @param o The object to be bound as the value of that attribute, or null if the binding + * @param name A {@link java.lang.String String} specifying the name of the attribute. + * @param o The object to be bound as the value of that attribute, or null if the binding * is to be removed. */ public void setSessionAttribute(String name, Object o); /** - * Returns the request-level attribute with the given name, or null if there is no + * Returns the request-level attribute with the given name, or null if there is no * attribute by that name. * - * @param name A String specifying the name of the attribute. - * @return An Object containing the value of the attribute, or null if no + * @param name A {@link java.lang.String String} specifying the name of the attribute. + * @return An {@link java.lang.Object Object} containing the value of the attribute, or null if no * attribute exists matching the given name. */ public Object getRequestAttribute(String name); @@ -292,8 +295,8 @@ public interface RequestInput extends ServiceProvider /** * Sets the request-level attribute with the given name. * - * @param name A String specifying the name of the attribute. - * @param o The object to be bound as the value of that attribute, or null if the binding + * @param name A {@link java.lang.String String} specifying the name of the attribute. + * @param o The object to be bound as the value of that attribute, or null if the binding * is to be removed. */ public void setRequestAttribute(String name, Object o); @@ -329,8 +332,8 @@ public interface RequestInput extends ServiceProvider public void setLocation(String str); /** - * Returns true if the "Log In" link is to be displayed on the outer frame, - * false if not. + * Returns true if the "Log In" link is to be displayed on the outer frame, + * false if not. * * @return See above. */ @@ -339,8 +342,8 @@ public interface RequestInput extends ServiceProvider /** * Sets whether or not the "Log In" link is to be displayed on the outer frame. * - * @param val true to display the "Log In" link on the outer frame, - * false to omit it. + * @param val true to display the "Log In" link on the outer frame, + * false to omit it. */ public void setDisplayLogin(boolean val); diff --git a/src/com/silverwrist/venice/ui/conf/PostShortcutServlet.java b/src/com/silverwrist/venice/ui/conf/PostShortcutServlet.java index 398a077..77064e5 100644 --- a/src/com/silverwrist/venice/ui/conf/PostShortcutServlet.java +++ b/src/com/silverwrist/venice/ui/conf/PostShortcutServlet.java @@ -9,15 +9,15 @@ * * The Original Code is the Venice Web Communities System. * - * The Initial Developer of the Original Code is Eric J. Bowersox , + * The Initial Developer of the Original Code is Eric J. Bowersox , * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are - * Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * Copyright (C) 2001-2004 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. * * Contributor(s): */ package com.silverwrist.venice.ui.conf; -import org.apache.log4j.*; +import org.apache.log4j.Logger; import com.silverwrist.venice.core.*; import com.silverwrist.venice.db.PostLinkDecoder; import com.silverwrist.venice.except.*; @@ -32,7 +32,7 @@ public class PostShortcutServlet extends BaseServlet implements LinkTypes *-------------------------------------------------------------------------------- */ - private static Category logger = Category.getInstance(PostShortcutServlet.class); + private static Logger logger = Logger.getLogger(PostShortcutServlet.class); /*-------------------------------------------------------------------------------- * Internal operations diff --git a/src/com/silverwrist/venice/ui/conf/TrackbackServlet.java b/src/com/silverwrist/venice/ui/conf/TrackbackServlet.java new file mode 100644 index 0000000..6725158 --- /dev/null +++ b/src/com/silverwrist/venice/ui/conf/TrackbackServlet.java @@ -0,0 +1,188 @@ +/* + * The contents of this file are subject to the Mozilla Public License Version 1.1 + * (the "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at . + * + * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT + * WARRANTY OF ANY KIND, either express or implied. See the License for the specific + * language governing rights and limitations under the License. + * + * The Original Code is the Venice Web Communities System. + * + * The Initial Developer of the Original Code is Eric J. Bowersox , + * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are + * Copyright (C) 2004 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * + * Contributor(s): + */ +package com.silverwrist.venice.ui.conf; + +import org.apache.log4j.Logger; +import com.silverwrist.venice.core.*; +import com.silverwrist.venice.db.PostLinkDecoder; +import com.silverwrist.venice.except.*; +import com.silverwrist.venice.ui.*; +import com.silverwrist.venice.ui.helpers.*; +import com.silverwrist.venice.ui.servlet.BaseServlet; + +public class TrackbackServlet extends BaseServlet +{ + /*-------------------------------------------------------------------------------- + * Static data members + *-------------------------------------------------------------------------------- + */ + + private static Logger logger = Logger.getLogger(TrackbackServlet.class); + + private static final int INVALID = 0; + private static final int COMMUNITY = 1; + private static final int CONFERENCE = 2; + private static final int TOPIC = 3; + private static final int POST = 4; + private static final int POST_RANGE = 5; + private static final int POST_OE_RANGE = 6; + + /*-------------------------------------------------------------------------------- + * Internal operations + *-------------------------------------------------------------------------------- + */ + + private static final int classifyPostLink(RequestInput req, PostLinkDecoder pld) + { + String s = pld.getCommunity(); + if (s==null) + return INVALID; // we must have the community or we're not valid + CommunityContext comm = null; + try + { // get the community context we're looking for + comm = req.getUser().getCommunityContext(s); + req.setRequestAttribute("current.community",comm); + + } // end try + catch (DataException e) + { // can't find the community - we're screwed + logger.error("unable to decode community \"" + s + "\"",e); + return INVALID; + + } // end catch + + s = pld.getConference(); + if (s==null) + return COMMUNITY; // community link only + + ConferenceContext conf = null; + try + { // get the conference context + conf = comm.getConferenceContext(s); + req.setRequestAttribute("current.conference",comm); + + } // end try + catch (DataException e) + { // can't find the conference - we're screwed + logger.error("unable to decode conference \"" + s + "\"",e); + return INVALID; + + } // end catch + catch (AccessError ae) + { // we can't get to the conference... + logger.error("AccessError getting conference \"" + s + "\"",ae); + return INVALID; + + } // end catch + + short tn = pld.getTopic(); + if (tn==-1) + return CONFERENCE; // only a conference locator + + TopicContext topic = null; + try + { // get the resulting topic number + topic = conf.getTopic(tn); + req.setRequestAttribute("current.topic",comm); + + } // end try + catch (DataException e) + { // we can't find the topic - we're screwed + logger.error("unable to decode topic \"" + tn + "\"",e); + return INVALID; + + } // end catch + catch (AccessError ae) + { // we can't get to the topic... + logger.error("AccessError getting topic \"" + tn + "\"",ae); + return INVALID; + + } // end catch + + int fp = pld.getFirstPost(); + if (fp==-1) + return TOPIC; // just referencing the topic + int lp = pld.getLastPost(); + if (fp==lp) + return POST; // single post + if (lp==-1) + return POST_OE_RANGE; // open-ended range of posts + return POST_RANGE; // normal range of posts + + } // end classifyPostLink + + /*-------------------------------------------------------------------------------- + * Implementations from class BaseServlet + *-------------------------------------------------------------------------------- + */ + + public Object process(RequestInput req) + { + String raw_link = req.getPathInfo().substring(1); + PostLinkDecoder decoder; + + if (logger.isDebugEnabled()) + logger.debug("decoding post link: " + raw_link); + + try + { // attempt to decode the path link information + decoder = new PostLinkDecoder(raw_link); + + } // end try + catch (ValidationException e) + { // the post link decoder failed + logger.error("Post link decode failed!",e); + return new HTTPError(400,"Invalid post link \"" + raw_link + "\": " + e.getMessage()); + + } // end catch + + // classify the post link and decode as much of it as we can + int what = classifyPostLink(req,decoder); + if (what==INVALID) + return new HTTPError(400,"Invalid post link \"" + raw_link + "\""); + + // at this point, trackback may only be applied to single posts, not ranges or anything higher + if (what!=POST) + return new HTTPError(400,"Trackback only applies to single posts"); + + TopicMessageContext msg = null; + try + { // get the message involved + TopicContext topic = (TopicContext)(req.getRequestAttribute("current.topic")); + msg = topic.getMessage(decoder.getFirstPost()); + + } // end try + catch (DataException e) + { // the post was not found + return new HTTPError(404,"Post not found: \"" + raw_link + "\""); + + } // end catch + catch (AccessError e) + { // could not access the post + return new HTTPError(403,"Post not accessible: \"" + raw_link + "\""); + + } // end catch + + // TODO: POST = add trackback + // GET = get list of trackbacks, may be with either ?__mode=rss (default) or ?__mode=view + + return null; + + } // end process + +} // end class TrackbackServlet diff --git a/src/com/silverwrist/venice/ui/helpers/HTTPError.java b/src/com/silverwrist/venice/ui/helpers/HTTPError.java index 23e2a1f..385a98c 100644 --- a/src/com/silverwrist/venice/ui/helpers/HTTPError.java +++ b/src/com/silverwrist/venice/ui/helpers/HTTPError.java @@ -9,9 +9,9 @@ * * The Original Code is the Venice Web Communities System. * - * The Initial Developer of the Original Code is Eric J. Bowersox , + * The Initial Developer of the Original Code is Eric J. Bowersox , * for Silverwrist Design Studios. Portions created by Eric J. Bowersox are - * Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. + * Copyright (C) 2001-2004 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved. * * Contributor(s): */ @@ -29,7 +29,7 @@ public class HTTPError extends ThrowableContent implements ContentExecute *-------------------------------------------------------------------------------- */ - private int code; + private final int code; /*-------------------------------------------------------------------------------- * Constructors