venice-main-classic/src/com/silverwrist/venice/db/PostLinkDecoder.java

372 lines
10 KiB
Java
Raw Normal View History

2001-01-31 13:55:37 -07:00
/*
* 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 <http://www.mozilla.org/MPL/>.
*
* 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 Community System.
*
* The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
* for Silverwrist Design Studios. Portions created by Eric J. Bowersox are
* Copyright (C) 2001 Eric J. Bowersox/Silverwrist Design Studios. All Rights Reserved.
*
* Contributor(s):
*/
package com.silverwrist.venice.db;
import java.sql.*;
import com.silverwrist.util.StringUtil;
import com.silverwrist.venice.ValidationException;
import com.silverwrist.venice.core.IDUtils;
public class PostLinkDecoder
{
/*--------------------------------------------------------------------------------
* Static data members
*--------------------------------------------------------------------------------
*/
private static final int MAX_LINK_LEN = 130;
private static final int MAX_SIG_LEN = 32;
private static final int MAX_CONF_LEN = 64;
/*--------------------------------------------------------------------------------
* Attributes
*--------------------------------------------------------------------------------
*/
private String signame = null;
private String confname = null;
private short topicnum = -1;
private int first_post = -1;
private int last_post = -1;
/*--------------------------------------------------------------------------------
* Constructor
*--------------------------------------------------------------------------------
*/
public PostLinkDecoder(String data) throws ValidationException
{
if (StringUtil.isStringEmpty(data))
throw new ValidationException("empty string");
if (data.length()>MAX_LINK_LEN)
throw new ValidationException("post link string too long");
// turn the data into a StringBuffer so we can parse it
StringBuffer work = new StringBuffer(data);
// First Test: Bang
int pos = work.toString().indexOf('!');
if (pos>0)
{ // We have "sig!something" ... store off the SIG name
setSIGName(work.substring(0,pos));
work.delete(0,pos+1);
if (work.length()==0)
return; // we had just "sig!" - that's the syntax for a SIG link
} // end if
else if (pos==0)
throw new ValidationException("! at beginning of string");
// Second Test: Dot Number One
pos = work.toString().indexOf('.');
if (pos<0)
{ // there's no dots in here...this must have been either "postlink" or "sig!conference"
if (signame!=null) // it's "sig!conference"
setConferenceName(work.toString());
else // it's "postlink"
setPostRange(work);
return;
} // end if
else if (pos==0)
throw new ValidationException(". at beginning of string");
// Peel off the initial substring.
String conf_or_topic = work.substring(0,pos);
work.delete(0,pos+1);
if (work.length()==0)
{ // we had "conference." or "topic." (or perhaps "sig!conference.")
if (signame==null)
{ // it's either "conference." or "topic." - try topic first
try
{ // try it as a topic number first...
setTopicNumber(conf_or_topic);
} // end try
catch (ValidationException ve)
{ // it's not a topic number - try it as a conference name!
setConferenceName(conf_or_topic);
} // end catch
} // end if
else // it was "sig!conference."...save it off
setConferenceName(conf_or_topic);
return; // all done here...
} // end if
// Third Test: Dot Number Two
pos = work.toString().indexOf('.');
if (pos<0)
{ // we had "conference.topic" or "topic.posts" (or perhaps "sig!conference.topic")
if (signame==null)
{ // we have "conference.topic" or "topic.posts" - have to determine this
boolean is_topic = false; // what does "work" currently hold?
try
{ // try the "topic.posts" possibility first...
setTopicNumber(conf_or_topic);
} // end try
catch (ValidationException ve)
{ // nope, it's gotta be "conference.topic"
setConferenceName(conf_or_topic);
is_topic = true;
} // end if
// complete the parsing here
if (is_topic)
setTopicNumber(work.toString());
else
setPostRange(work);
} // end if
else
{ // it's "sig!conference.topic"...set 'em up accordingly
setConferenceName(conf_or_topic);
setTopicNumber(work.toString());
} // end else
return; // all done
} // end if
else if (pos==0)
throw new ValidationException(". at beginning of string");
// We definitely have "conference.topic.something" (or "sig!conference.topic.sonething") now,
// so save off the conference name and topic number.
setConferenceName(conf_or_topic);
setTopicNumber(work.substring(0,pos));
work.delete(0,pos+1);
if (work.length()==0)
return; // we just had "conference.topic." or "sig!conference.topic.", which is valid
setPostRange(work); // the rest must be the post range!
} // end constructor
/*--------------------------------------------------------------------------------
* Internal functions
*--------------------------------------------------------------------------------
*/
private static boolean isAllDigits(String str)
{
for (int i=0; i<str.length(); i++)
{ // if any character is not a digit, bail out!
if (!(Character.isDigit(str.charAt(i))))
return false;
} // end for
return true;
} // end isAllDigits
private void setSIGName(String name) throws ValidationException
{
if (name.length()>MAX_SIG_LEN)
throw new ValidationException("SIG alias is too long");
if (!(IDUtils.isValidVeniceID(name)))
throw new ValidationException("SIG alias is not a valid Venice identifier");
signame = name;
} // end setSIGName
private void setConferenceName(String name) throws ValidationException
{
if (name.length()>MAX_CONF_LEN)
throw new ValidationException("conference alias is too long");
if (!(IDUtils.isValidVeniceID(name)))
throw new ValidationException("conference alias is not a valid Venice identifier");
confname = name;
} // end setConferenceName
private void setTopicNumber(String val) throws ValidationException
{
if (!isAllDigits(val))
throw new ValidationException("invalid topic number reference");
short temp_val;
try
{ // parse the temp value
temp_val = Short.parseShort(val);
} // end try
catch (NumberFormatException nfe)
{ // if there's a validation exception, it goes here
throw new ValidationException("invalid topic number reference");
} // end catch
topicnum = temp_val;
} // end setTopicNumber
private void setPostRange(StringBuffer buf) throws ValidationException
{
int pos = buf.toString().indexOf('-');
String temp = null;
int temp_val = -1;
if (pos>0)
{ // we've got "temp-something" here...make sure "temp" is a valid post number
temp = buf.substring(0,pos);
buf.delete(0,pos+1);
if (!isAllDigits(temp))
throw new ValidationException("invalid post number reference");
try
{ // parse the temp value
temp_val = Integer.parseInt(temp);
} // end try
catch (NumberFormatException nfe)
{ // if there's a validation exception, it goes here
throw new ValidationException("invalid post number reference");
} // end catch
if (buf.length()==0)
{ // we just had "first-"...set it up
first_post = temp_val;
last_post = -1;
return;
} // end if
} // end if
else if (pos==0)
throw new ValidationException("- at beginning of post range");
// the remaining string must be all digits at this point
if (!isAllDigits(buf.toString()))
throw new ValidationException("invalid post number reference");
try
{ // parse the first value
first_post = Integer.parseInt(buf.toString());
} // end try
catch (NumberFormatException nfe)
{ // if there's a validation exception, it goes here
throw new ValidationException("invalid post number reference");
} // end catch
if (temp!=null)
{ // we converted a "temp_val" above - include it
if (temp_val<first_post)
{ // put the "temp_val" up front
last_post = first_post;
first_post = temp_val;
} // end if
else // reverse order - arrange them correctly
last_post = temp_val;
} // end if
else // we have a "range" of one post
last_post = first_post;
} // end setPostRange
/*--------------------------------------------------------------------------------
* External operations
*--------------------------------------------------------------------------------
*/
public String getSIG()
{
return signame;
} // end getSIG
public String getConference()
{
return confname;
} // end getConference
public short getTopic()
{
return topicnum;
} // end getTopic
public int getFirstPost()
{
return first_post;
} // end getFirstPost
public int getLastPost()
{
return last_post;
} // end getFirstPost
public boolean needDatabaseVerification()
{
return ((signame!=null) || (confname!=null));
} // end needDatabaseVerification
public void verifyNames(Connection conn) throws ValidationException
{
try
{ // do the necessary database stuff
Statement stmt = conn.createStatement();
StringBuffer sql = new StringBuffer();
ResultSet rs;
if (signame!=null)
{ // verify the SIG name against the database
sql.append("SELECT sigid FROM sigs WHERE alias = '").append(SQLUtil.encodeString(signame));
sql.append("';");
rs = stmt.executeQuery(sql.toString());
if (!(rs.next()))
throw new ValidationException("SIG alias not found");
sql.setLength(0);
} // end if
if (confname!=null)
{ // verify the conference name against the database
sql.append("SELECT confid FROM confalias WHERE alias = '").append(SQLUtil.encodeString(confname));
sql.append("';");
rs = stmt.executeQuery(sql.toString());
if (!(rs.next()))
throw new ValidationException("conference alias not found");
} // end if
} // end try
catch (SQLException e)
{ // database error verifying stuff!
throw new ValidationException("unable to verify names in post link");
} // end catch
} // end verifyNames
} // end class PostLinkDecoder