diff options
author | slewis | 2007-02-27 17:44:52 +0000 |
---|---|---|
committer | slewis | 2007-02-27 17:44:52 +0000 |
commit | 7be76ac9260cc3b01d7eba9db3adb9f2269ca9e7 (patch) | |
tree | e9404b4c86b20a3bff1f3bb8405e134ab6fa7594 /incubation | |
parent | 9528acfe8c8019349ae7219026ba00faf52256da (diff) | |
download | org.eclipse.ecf-7be76ac9260cc3b01d7eba9db3adb9f2269ca9e7.tar.gz org.eclipse.ecf-7be76ac9260cc3b01d7eba9db3adb9f2269ca9e7.tar.xz org.eclipse.ecf-7be76ac9260cc3b01d7eba9db3adb9f2269ca9e7.zip |
Initial checkin to support bbapi
Diffstat (limited to 'incubation')
34 files changed, 2530 insertions, 0 deletions
diff --git a/incubation/bundles/org.eclipse.ecf.provider.vbulletin/.classpath b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/.classpath new file mode 100644 index 000000000..00e032c3d --- /dev/null +++ b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/.classpath @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="src" path="src"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/> + <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> + <classpathentry kind="output" path="target/classes"/> +</classpath> diff --git a/incubation/bundles/org.eclipse.ecf.provider.vbulletin/.project b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/.project new file mode 100644 index 000000000..0e302512e --- /dev/null +++ b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/.project @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>org.eclipse.ecf.provider.vbulletin</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.ManifestBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.SchemaBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>net.sourceforge.metrics.builder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.pde.PluginNature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + <nature>net.sourceforge.metrics.nature</nature> + </natures> +</projectDescription> diff --git a/incubation/bundles/org.eclipse.ecf.provider.vbulletin/META-INF/MANIFEST.MF b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/META-INF/MANIFEST.MF new file mode 100644 index 000000000..c1ce9f833 --- /dev/null +++ b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/META-INF/MANIFEST.MF @@ -0,0 +1,19 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: ECF vBulletin Provider +Bundle-SymbolicName: org.eclipse.ecf.provider.vbulletin;singleton:=true +Bundle-Version: 0.1.0 +Bundle-Activator: org.eclipse.ecf.internal.provider.vbulletin.Activator +Bundle-Vendor: Erkki Lindpere +Bundle-Localization: plugin +Require-Bundle: org.eclipse.core.runtime, + org.eclipse.ecf, + org.eclipse.ecf.bulletinboard, + org.eclipse.ecf.bulletinboard.commons +Eclipse-LazyStart: false +Import-Package: org.apache.commons.httpclient +Export-Package: org.eclipse.ecf.internal.provider.vbulletin;x-internal:=true, + org.eclipse.ecf.internal.provider.vbulletin.container;x-internal:=true, + org.eclipse.ecf.internal.provider.vbulletin.identity;x-internal:=true, + org.eclipse.ecf.internal.provider.vbulletin.internal;x-internal:=true +Bundle-RequiredExecutionEnvironment: J2SE-1.5 diff --git a/incubation/bundles/org.eclipse.ecf.provider.vbulletin/build.properties b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/build.properties new file mode 100644 index 000000000..110a2d2dc --- /dev/null +++ b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/build.properties @@ -0,0 +1,5 @@ +source.. = src/ +output.. = target/classes/ +bin.includes = META-INF/,\ + .,\ + plugin.xml diff --git a/incubation/bundles/org.eclipse.ecf.provider.vbulletin/plugin.xml b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/plugin.xml new file mode 100644 index 000000000..a6cf882a0 --- /dev/null +++ b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/plugin.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="UTF-8"?> +<?eclipse version="3.2"?> +<plugin> + <extension + point="org.eclipse.ecf.identity.namespace"> + <namespace + class="org.eclipse.ecf.internal.provider.vbulletin.identity.VBNamespace" + description="vBulletin Namespace" + name="ecf.vbulletin"/> + </extension> + <extension + point="org.eclipse.ecf.containerFactory"> + <containerFactory + class="org.eclipse.ecf.internal.provider.vbulletin.container.ContainerInstantiator" + description="vBulletin HTTP Client" + name="ecf.vbulletin.http"> + <property + name="org.eclipse.ecf.example.collab.ui.JoinGroupWizardPage.usenickname" + value="true"/> + <property + name="org.eclipse.ecf.example.collab.ui.JoinGroupWizardPage.usepassword" + value="true"/> + <property + name="org.eclipse.ecf.example.collab.ui.JoinGroupWizardPage.groupIDLabel" + value="URL:"/> + </containerFactory> + </extension> + +</plugin> diff --git a/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/Activator.java b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/Activator.java new file mode 100644 index 000000000..5bb777257 --- /dev/null +++ b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/Activator.java @@ -0,0 +1,55 @@ +package org.eclipse.ecf.internal.provider.vbulletin; + +import org.eclipse.core.runtime.Plugin; +import org.osgi.framework.BundleContext; + +/** + * The activator class controls the plug-in life cycle + */ +public class Activator extends Plugin { + + public static final String NAMESPACE_IDENTIFIER = "ecf.vbulletin"; + + // The plug-in ID + public static final String PLUGIN_ID = "org.eclipse.ecf.internal.provider.vbulletin"; + + // The shared instance + private static Activator plugin; + + /** + * The constructor + */ + public Activator() { + plugin = this; + } + + /* + * (non-Javadoc) + * @see org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext) + */ + public void start(BundleContext context) throws Exception { + super.start(context); + } + + /* + * (non-Javadoc) + * @see org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext) + */ + public void stop(BundleContext context) throws Exception { + plugin = null; + super.stop(context); + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static Activator getDefault() { + return plugin; + } + public static String getNamespaceIdentifier() { + return NAMESPACE_IDENTIFIER; + } + +} diff --git a/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/Forum.java b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/Forum.java new file mode 100644 index 000000000..143af1d32 --- /dev/null +++ b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/Forum.java @@ -0,0 +1,180 @@ +/******************************************************************************* + * Copyright (c) 2005, 2006 Erkki Lindpere and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Erkki Lindpere - initial API and implementation + *******************************************************************************/ +package org.eclipse.ecf.internal.provider.vbulletin; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Map; + +import org.apache.commons.httpclient.NameValuePair; +import org.eclipse.ecf.bulletinboard.BBException; +import org.eclipse.ecf.bulletinboard.IForum; +import org.eclipse.ecf.bulletinboard.IThread; +import org.eclipse.ecf.bulletinboard.IllegalWriteException; +import org.eclipse.ecf.core.identity.ID; +import org.eclipse.ecf.internal.bulletinboard.commons.AbstractBBObject; +import org.eclipse.ecf.internal.bulletinboard.commons.webapp.GetRequest; +import org.eclipse.ecf.internal.bulletinboard.commons.webapp.WebRequest; +import org.eclipse.ecf.internal.provider.vbulletin.identity.ForumID; + +public class Forum extends VBObject implements IForum { + private static final String E_READ_ONLY = "This forum is read only."; + + protected ForumID id; + + private Forum parent; + + protected ArrayList<IForum> subforums; + + private String description; + + public Forum(ForumID id, String name) { + super(name, READ_WRITE); + this.id = id; + this.parent = null; + this.subforums = new ArrayList<IForum>(); + } + + protected void setParent(Forum parent) { + this.parent = parent; + } + + protected void setDescription(String description) { + this.description = description; + } + + public String getDescription() { + return description; + } + + public int getType() { + return IForum.HOLDS_THREADS | IForum.HOLDS_FORUMS; + } + + public IForum getParentForum() { + return parent; + } + + public List<IForum> getSubForums() { + return subforums; + } + + public Collection<IThread> getThreads() { + VBParser parser = (VBParser) bb.getParser(); + Map<ID, IThread> threadMap = null; + WebRequest request = new GetRequest(bb.getHttpClient(), getURL(), ""); + request.addParameter(new NameValuePair("f", String.valueOf(id + .getLongValue()))); + try { + request.execute(); + String resp = request.getResponseBodyAsString(); + request.releaseConnection(); + threadMap = parser.parseThreads(resp); + for (IThread thread : threadMap.values()) { + ((AbstractBBObject) thread).setBulletinBoard(bb); + ((Thread) thread).forum = this; + } + } catch (IOException e) { + e.printStackTrace(); + } + return new HashSet<IThread>(threadMap.values()); + } + + public URL getURL() { + try { + return new URL(bb.getURL() + "forumdisplay.php?f=" + + id.getLongValue()); + } catch (MalformedURLException e) { + return null; + } + } + + public ID getID() { + return id; + } + + public IThread createThread() throws IllegalWriteException, BBException { + /* + * if ((mode & READ_ONLY) == READ_ONLY) { throw new + * IllegalWriteException(E_READ_ONLY); } Thread thread = new Thread(); + * thread.bb = bb; thread.forum = this; return thread; + */ + return null; + } + + public boolean postThread(IThread thread) throws IllegalWriteException, + BBException { + if ((mode & READ_ONLY) == READ_ONLY) { + throw new IllegalWriteException(E_READ_ONLY); + } + /* + * WebRequest request = new PostRequest(bb.getHttpClient(), bb.getURL(), + * "posting.php"); + * + * NameValuePair params[]; params = new NameValuePair[] { new + * NameValuePair("subject", thread.getPrePostMessage() .getName()), new + * NameValuePair("message", thread.getPrePostMessage() .getMessage()), + * new NameValuePair("f", id.getStringValue()), new + * NameValuePair("mode", "newtopic"), // checkbox : disabled new + * NameValuePair("disable_smilies", // "on"), // checkbox : disabled new + * NameValuePair("disable_bbcode", // "on"), // checkbox : disabled new + * NameValuePair("notify", "on"), new NameValuePair("post", "Submit") }; + * request.addParameters(params); request.execute(); // We seem to + * always have to get the response body. try { String resp = + * request.getResponseBodyAsString(); } catch (IOException e) { // TODO + * Auto-generated catch block e.printStackTrace(); } + * request.releaseConnection(); + */ + return true; + } + + public boolean prune(int pruneDays) throws IllegalWriteException, + BBException { + /* + * PHPBB Admin module checks GET_VARS for SID, so we need to pass it as + * a GET var to a POST method. + */ + // admin/pagestart.php + // line 50: if ($HTTP_GET_VARS['sid'] != $userdata['session_id']) + /* + * WebRequest request = new PostRequest(bb.getHttpClient(), bb.getURL(), + * "admin/admin_forum_prune.php?sid=" + bb.getSessionId()); + * request.setParameters(new NameValuePair[] { new + * NameValuePair("prunedays", String.valueOf(pruneDays)), new + * NameValuePair("f", id.getStringValue()), new NameValuePair("doprune", + * "Do Prune") }); request.execute(); /*try { + * System.out.println(request.getResponseBodyAsString()); } catch + * (IOException e) { // TODO Auto-generated catch block + * e.printStackTrace(); } + */ + // request.releaseConnection(); + return true; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof Forum) { + Forum grp = (Forum) obj; + return id.equals(grp.id); + } + return false; + } + + @Override + public int hashCode() { + return id.hashCode(); + } +} diff --git a/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/Member.java b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/Member.java new file mode 100644 index 000000000..7b820682c --- /dev/null +++ b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/Member.java @@ -0,0 +1,77 @@ +/******************************************************************************* + * Copyright (c) 2005, 2006 Erkki Lindpere and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Erkki Lindpere - initial API and implementation + *******************************************************************************/ +package org.eclipse.ecf.internal.provider.vbulletin; + +import java.util.Collection; +import java.util.Collections; +import java.util.Map; + +import org.eclipse.ecf.bulletinboard.IMember; +import org.eclipse.ecf.bulletinboard.IMemberGroup; +import org.eclipse.ecf.core.identity.ID; +import org.eclipse.ecf.internal.bulletinboard.commons.AbstractBulletinBoard; +import org.eclipse.ecf.internal.provider.vbulletin.identity.MemberID; + +public class Member extends VBObject implements IMember { + private static final long serialVersionUID = -1931142128734519538L; + + private ID id; + + public Member(ID id, String name) { + super(name, READ_ONLY); + this.id = id; + } + + public Member(String name) { + super(name, READ_ONLY); + this.id = null; + } + + public ID getID() { + return id; + } + + public boolean isMemberOf(IMemberGroup group) { + // TODO maybe a better way? + return group.getMembers().contains(this); + } + + public Collection<IMemberGroup> getGroups() { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof Member) { + Member grp = (Member) obj; + return id.equals(grp.id); + } + return false; + } + + @Override + public int hashCode() { + return id.hashCode(); + } + + public Map getProperties() { + return Collections.emptyMap(); + } + + @Override + public void setBulletinBoard(AbstractBulletinBoard bb) { + super.setBulletinBoard(bb); + if (this.id == null) { + this.id = bb.getID(); + } + } +} diff --git a/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/MemberGroup.java b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/MemberGroup.java new file mode 100644 index 000000000..1aa3e5ad5 --- /dev/null +++ b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/MemberGroup.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright (c) 2005, 2006 Erkki Lindpere and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Erkki Lindpere - initial API and implementation + *******************************************************************************/ +package org.eclipse.ecf.internal.provider.vbulletin; + +import java.util.Collection; +import java.util.Collections; + +import org.eclipse.ecf.bulletinboard.IMember; +import org.eclipse.ecf.bulletinboard.IMemberGroup; +import org.eclipse.ecf.core.identity.ID; +import org.eclipse.ecf.internal.provider.vbulletin.identity.MemberGroupID; + +public class MemberGroup extends VBObject implements IMemberGroup { + + private String description; + + private MemberGroupID id; + + public MemberGroup(MemberGroupID id, String name) { + super(name, READ_ONLY); + this.id = id; + } + + private void attainDetailsFetched() { + /*if (!detailsFetched) { + GetRequest request = new GetRequest(bb.getHttpClient(), + bb.getURL(), "groupcp.php"); + request.addParameter(new NameValuePair("g", String.valueOf(id + .getLongValue()))); + request.execute(); + String resp = null; + try { + resp = request.getResponseBodyAsString(); + } catch (IOException e) { + e.printStackTrace(); + } + request.releaseConnection(); + if (resp != null) { + MemberGroup group = bb.getParser().parseMemberGroup(resp); + group.detailsFetched = true; + this.description = group.getDescription(); + } + }*/ + } + + public String getDescription() { + attainDetailsFetched(); + return description; + } + + public Collection<IMember> getMembers() { + /*Map<ID, Member> map = null; + GetRequest request = new GetRequest(bb.getHttpClient(), bb.getURL(), + "groupcp.php"); + request.addParameter(new NameValuePair("g", String.valueOf(id + .getLongValue()))); + request.execute(); + String resp = null; + try { + resp = request.getResponseBodyAsString(); + } catch (IOException e) { + e.printStackTrace(); + } + request.releaseConnection(); + if (resp != null) { + map = bb.getParser().parseMemberLinks(resp); + for (Member member : map.values()) { + member.bb = bb; + } + } + return new HashSet<IMember>(map.values());*/ + return Collections.emptyList(); + } + + public ID getID() { + return id; + } + + protected void setDescription(String desc) { + this.description = desc; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof MemberGroup) { + MemberGroup grp = (MemberGroup) obj; + return id.equals(grp.id); + } + return false; + } + + @Override + public int hashCode() { + return id.hashCode(); + } +} diff --git a/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/Thread.java b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/Thread.java new file mode 100644 index 000000000..fc196b866 --- /dev/null +++ b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/Thread.java @@ -0,0 +1,252 @@ +/******************************************************************************* + * Copyright (c) 2005, 2006 Erkki Lindpere and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Erkki Lindpere - initial API and implementation + *******************************************************************************/ +package org.eclipse.ecf.internal.provider.vbulletin; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Date; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.commons.httpclient.Header; +import org.apache.commons.httpclient.NameValuePair; +import org.eclipse.ecf.bulletinboard.BBException; +import org.eclipse.ecf.bulletinboard.IForum; +import org.eclipse.ecf.bulletinboard.IMember; +import org.eclipse.ecf.bulletinboard.IPoll; +import org.eclipse.ecf.bulletinboard.IThread; +import org.eclipse.ecf.bulletinboard.IThreadMessage; +import org.eclipse.ecf.bulletinboard.IllegalWriteException; +import org.eclipse.ecf.core.identity.ID; +import org.eclipse.ecf.core.identity.IDCreateException; +import org.eclipse.ecf.internal.bulletinboard.commons.webapp.PostRequest; +import org.eclipse.ecf.internal.provider.vbulletin.identity.ThreadID; +import org.eclipse.ecf.internal.provider.vbulletin.identity.ThreadMessageID; +import org.eclipse.ecf.internal.provider.vbulletin.internal.ThreadMessageFactory; + +public class Thread extends VBObject implements IThread { + + private static final String E_READ_ONLY = "This thread is read only."; + + private ThreadID id; + + protected Forum forum; + + private IMember author; + + // private ThreadMessage prePostMessage; + + public ThreadMessageID lastReadMessageId; + + public Thread() { + super(null, READ_WRITE); + // FIXME this.prePostMessage = new ThreadMessage(); + // prePostMessage.setThread(this); + } + + public Thread(ThreadID id, String name) { + super(name, READ_WRITE); + this.id = id; + } + + public IPoll getPoll() { + return null; + } + + public IForum getForum() { + return forum; + } + + public List<IThreadMessage> getMessages() throws BBException { + return getNewMessages(); + } + + public List<IThreadMessage> getNewMessages() throws BBException { + ThreadBrowser2 browser = new ThreadBrowser2((VBulletin) bb, this); + List<IThreadMessage> msgs = browser.fetchNewMessages(); + if (msgs.size() > 0) { + lastReadMessageId = (ThreadMessageID) msgs.get(msgs.size() - 1) + .getID(); + for (IThreadMessage message : msgs) { + ThreadMessage msg = (ThreadMessage) message; + msg.setBulletinBoard(bb); + msg.thread = this; + IMember author = msg.author; + ((Member) author).setBulletinBoard(bb); + } + } + return msgs; + } + + public List<IThreadMessage> getNewMessages(ID lastReadId) + throws BBException { + if (lastReadId != null) { + lastReadMessageId = (ThreadMessageID) lastReadId; + } + return getNewMessages(); + } + + public URL getURL() { + try { + return new URL(bb.getURL(), "showthread.php?t=" + id.getLongValue()); + } catch (MalformedURLException e) { + // FIXME log.error(e.getMessage(), e); + return null; + } + } + + public ID getID() { + return id; + } + + public int getType() { + return 0; + } + + public IThreadMessage createReplyMessage() throws IllegalWriteException { + if ((mode & READ_ONLY) == READ_ONLY) { + throw new IllegalWriteException(E_READ_ONLY); + } + ThreadMessage msg = new ThreadMessage(); + msg.setBulletinBoard(bb); + msg.setThread(this); + return msg; + } + + public IThreadMessage createReplyMessage(IThreadMessage replyTo) + throws IllegalWriteException { + return null; + } + + public ID postReply(IThreadMessage message) throws IllegalWriteException, + BBException { + if ((mode & READ_ONLY) == READ_ONLY) { + throw new IllegalWriteException(E_READ_ONLY); + } + ThreadMessage msg = (ThreadMessage) message; + // FIXME assert msg.bb == bb; + assert msg.getThread() == this; + PostRequest request = new PostRequest(bb.getHttpClient(), bb.getURL(), + "newreply.php"); + NameValuePair[] params = new NameValuePair[] { + new NameValuePair("emailupdate", "9999"), + new NameValuePair("rating", "0") }; + request.addParameters(params); + params = new NameValuePair[] { + new NameValuePair("title", message.getName()), + new NameValuePair("message", msg.getMessage()), + new NameValuePair("iconid", "0"), new NameValuePair("s", ""), + new NameValuePair("do", "postreply"), + new NameValuePair("t", String.valueOf(id.getLongValue())) }; + request.addParameters(params); + if (message.getReplyTo() != null) { + params = new NameValuePair[] { new NameValuePair("p", String + .valueOf(((ThreadMessageID) message.getReplyTo().getID()) + .getLongValue())) }; + request.addParameters(params); + } + params = new NameValuePair[] { new NameValuePair("posthash", ""), + new NameValuePair("poststarttime", ""), + new NameValuePair("sbutton", "Submit Reply"), + new NameValuePair("parseurl", "1"), + // checkbox : disabled new NameValuePair("disablesmilies", "1"), + }; + request.addParameters(params); + try { + request.execute(); + // TODO: do we have to do this? + String resp = request.getResponseBodyAsString(); + Header newLocation = request.getMethod().getResponseHeader( + "Location"); + if (newLocation == null) { + throw ((VBParser) bb.getParser()).createVBException( + "The message was not posted.", resp); + } + Matcher m = Pattern.compile("showthread.php\\?p=([0-9]+)").matcher( + newLocation.getValue()); + if (m.find()) { + synchronized (this) { + lastReadMessageId = (ThreadMessageID) new ThreadMessageFactory() + .createBBObjectId(bb.getNamespace(), bb.getURL(), + m.group(1)); + return lastReadMessageId; + } + } else { + throw ((VBParser) bb.getParser()).createVBException( + "The message was not posted.", resp); + } + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (NumberFormatException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IDCreateException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return null; + } + + public int getSubscriptionStatus() { + return -1; + } + + public boolean updateSubscription(int newSubscriptionStatus) + throws BBException { + return false; + } + + public IThreadMessage getPrePostMessage() throws IllegalWriteException { + // return prePostMessage; + return null; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof Thread) { + Thread grp = (Thread) obj; + return id.equals(grp.id); + } + return false; + } + + @Override + public int hashCode() { + return id.hashCode(); + } + + public IMember getAuthor() { + return author; + } + + protected void setAuthor(IMember author) { + this.author = author; + } + + public int getNumberOfMessages() { + // TODO Auto-generated method stub + return 0; + } + + public Date getTimePosted() { + // TODO Auto-generated method stub + return null; + } + + public Date getTimeUpdated() { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/ThreadBrowser2.java b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/ThreadBrowser2.java new file mode 100644 index 000000000..6a2a337f2 --- /dev/null +++ b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/ThreadBrowser2.java @@ -0,0 +1,79 @@ +/******************************************************************************* + * Copyright (c) 2005, 2006 Erkki Lindpere and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Erkki Lindpere - initial API and implementation + *******************************************************************************/ +package org.eclipse.ecf.internal.provider.vbulletin; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.ecf.bulletinboard.BBException; +import org.eclipse.ecf.bulletinboard.IThreadMessage; +import org.eclipse.ecf.internal.bulletinboard.commons.webapp.PostRequest; +import org.eclipse.ecf.internal.bulletinboard.commons.webapp.WebRequest; +import org.eclipse.ecf.internal.provider.vbulletin.identity.ThreadID; + +/** + * TODO This threadbrowser assumes the user account settings to have been set to + * the reverse post sorting order. This option should be detected instead. + * + * @author Erkki + * + */ +public class ThreadBrowser2 { + Thread thread; + + private VBulletin bb; + + public ThreadBrowser2(VBulletin bb, Thread thread) { + this.bb = bb; + this.thread = thread; + } + + private static final int STARTPAGE = 1; + + private static final int NONE = -1; + + class SkippedStatus { + public boolean messagesSkipped = false; + }; + + public List<IThreadMessage> fetchNewMessages() throws BBException { + List<IThreadMessage> messages = new ArrayList<IThreadMessage>(); + try { + int nextPage = STARTPAGE; + SkippedStatus skipped = new SkippedStatus(); + while (nextPage > NONE) { + WebRequest req = createRequest(nextPage); + req.execute(); + String resp = req.getResponseBodyAsString(); + req.releaseConnection(); + messages.addAll(0, bb.getParser().parseMessages2(resp, + thread.lastReadMessageId, true, skipped)); + if (skipped.messagesSkipped) { + nextPage = NONE; + } else { + nextPage = bb.getParser().parseNextPage(resp); + } + } + } catch (IOException e) { + e.printStackTrace(); + } + return messages; + } + + public WebRequest createRequest(int page) { + WebRequest req = new PostRequest(bb.getHttpClient(), bb.getURL(), + "showthread.php?t=" + + ((ThreadID) thread.getID()).getLongValue() + "&page=" + + page); + return req; + } +} diff --git a/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/ThreadFactory.java b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/ThreadFactory.java new file mode 100644 index 000000000..e293ee044 --- /dev/null +++ b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/ThreadFactory.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright (c) 2005, 2006 Erkki Lindpere and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Erkki Lindpere - initial API and implementation + *******************************************************************************/ +package org.eclipse.ecf.internal.provider.vbulletin; + +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.Map; + +import org.eclipse.ecf.bulletinboard.IBBObject; +import org.eclipse.ecf.bulletinboard.IMember; +import org.eclipse.ecf.core.identity.ID; +import org.eclipse.ecf.core.identity.IDCreateException; +import org.eclipse.ecf.core.identity.Namespace; +import org.eclipse.ecf.internal.bulletinboard.commons.IBBObjectFactory; +import org.eclipse.ecf.internal.provider.vbulletin.identity.ThreadID; +import org.eclipse.ecf.internal.provider.vbulletin.identity.VBNamespace; + +public class ThreadFactory implements IBBObjectFactory { + public ID createBBObjectId(Namespace namespace, String stringValue) + throws IDCreateException { + try { + return new ThreadID((VBNamespace) namespace, new URI(stringValue)); + } catch (URISyntaxException e) { + throw new IDCreateException(e); + } + } + + public ID createBBObjectId(Namespace namespace, URL baseURL, String longValue) + throws IDCreateException { + try { + return new ThreadID((VBNamespace) namespace, baseURL, Long.parseLong(longValue)); + } catch (URISyntaxException e) { + throw new IDCreateException(e); + } + } + + public IBBObject createBBObject(ID id, String name, Map<String, Object> parameters) { + Thread t = new Thread((ThreadID) id, name); + if (parameters != null) { + if (parameters.containsKey("author")) { + t.setAuthor((IMember) parameters.get("author")); + } + } + return t; + } +}
\ No newline at end of file diff --git a/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/ThreadMessage.java b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/ThreadMessage.java new file mode 100644 index 000000000..49a0a6c76 --- /dev/null +++ b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/ThreadMessage.java @@ -0,0 +1,129 @@ +/******************************************************************************* + * Copyright (c) 2005, 2006 Erkki Lindpere and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Erkki Lindpere - initial API and implementation + *******************************************************************************/ +package org.eclipse.ecf.internal.provider.vbulletin; + +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Date; + +import org.eclipse.ecf.bulletinboard.IMember; +import org.eclipse.ecf.bulletinboard.IMessageBase; +import org.eclipse.ecf.bulletinboard.IThread; +import org.eclipse.ecf.bulletinboard.IThreadMessage; +import org.eclipse.ecf.bulletinboard.IllegalWriteException; +import org.eclipse.ecf.core.identity.ID; +import org.eclipse.ecf.internal.provider.vbulletin.identity.ThreadMessageID; + +public class ThreadMessage extends VBObject implements IThreadMessage { + + private static final String E_READ_ONLY = "This message is read only."; + + protected String message; + + protected IMember author; + + private ThreadMessageID id; + + protected Thread thread; + + protected int number; + + protected Date timePosted; + + public ThreadMessage(ThreadMessageID id, String name) { + super(name, READ_ONLY); + this.id = id; + this.number = -1; + } + + public ThreadMessage() { + super(null, READ_WRITE); + this.number = -1; + } + + public int getMessageNumber() { + return number; + } + + public String getMessage() { + return message; + } + + public IMember getFrom() { + return author; + } + + public IMessageBase getReplyTo() { + // TODO Implement reply relationships + return null; + } + + public void setReplyTo(IMessageBase message) throws IllegalWriteException { + // TODO Auto-generated method stub + } + + public ID getID() { + return id; + } + + public URL getURL() { + try { + return new URL(bb.getURL(), "showpost.php?p=" + id.getLongValue()); + } catch (MalformedURLException e) { + // FIXME log.error(e.getMessage(), e); + return null; + } + } + + public IThread getThread() { + return thread; + } + + /** + * @param thread + * The thread to set. + */ + protected void setThread(Thread thread) { + this.thread = thread; + } + + public void setName(String name) throws IllegalWriteException { + if ((mode & READ_ONLY) == READ_ONLY) { + throw new IllegalWriteException(E_READ_ONLY); + } + this.name = name; + } + + public void setMessage(String message) throws IllegalWriteException { + if ((mode & READ_ONLY) == READ_ONLY) { + throw new IllegalWriteException(E_READ_ONLY); + } + this.message = message; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof ThreadMessage) { + ThreadMessage grp = (ThreadMessage) obj; + return id.equals(grp.id); + } + return false; + } + + @Override + public int hashCode() { + return id.hashCode(); + } + + public Date getTimePosted() { + return timePosted; + } +} diff --git a/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/VBFactory.java b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/VBFactory.java new file mode 100644 index 000000000..90c7ac4b1 --- /dev/null +++ b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/VBFactory.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2005, 2006 Erkki Lindpere and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Erkki Lindpere - initial API and implementation + *******************************************************************************/ +package org.eclipse.ecf.internal.provider.vbulletin; + +import org.eclipse.ecf.internal.provider.vbulletin.container.VBContainer; + +public class VBFactory { + private static VBFactory instance; + + private VBFactory() { + super(); + } + + public static VBFactory getDefault() { + if (instance == null) { + instance = new VBFactory(); + } + return instance; + } + + public VBulletin createVB(VBContainer mainContainer) { + return new VBulletin(mainContainer); + } +} diff --git a/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/VBObject.java b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/VBObject.java new file mode 100644 index 000000000..6234dac1a --- /dev/null +++ b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/VBObject.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright (c) 2005, 2006 Erkki Lindpere and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Erkki Lindpere - initial API and implementation + *******************************************************************************/ +package org.eclipse.ecf.internal.provider.vbulletin; + +import org.eclipse.ecf.internal.bulletinboard.commons.AbstractBBObject; + +public abstract class VBObject extends AbstractBBObject { + + public VBObject(String name, int mode) { + super(name, mode); + } + +} diff --git a/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/VBParser.java b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/VBParser.java new file mode 100644 index 000000000..273dc715f --- /dev/null +++ b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/VBParser.java @@ -0,0 +1,428 @@ +/******************************************************************************* + * Copyright (c) 2005, 2006 Erkki Lindpere and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Erkki Lindpere - initial API and implementation + *******************************************************************************/ +package org.eclipse.ecf.internal.provider.vbulletin; + +import java.net.URL; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.eclipse.ecf.bulletinboard.BBException; +import org.eclipse.ecf.bulletinboard.IBBObject; +import org.eclipse.ecf.bulletinboard.IMember; +import org.eclipse.ecf.core.identity.ID; +import org.eclipse.ecf.core.identity.IDCreateException; +import org.eclipse.ecf.core.identity.Namespace; +import org.eclipse.ecf.internal.bulletinboard.commons.AbstractParser; +import org.eclipse.ecf.internal.bulletinboard.commons.IBBObjectFactory; +import org.eclipse.ecf.internal.bulletinboard.commons.parsing.DefaultPatternDescriptor; +import org.eclipse.ecf.internal.bulletinboard.commons.parsing.IPatternDescriptor; +import org.eclipse.ecf.internal.bulletinboard.commons.util.StringUtil; +import org.eclipse.ecf.internal.provider.vbulletin.ThreadBrowser2.SkippedStatus; +import org.eclipse.ecf.internal.provider.vbulletin.identity.ThreadMessageID; +import org.eclipse.ecf.internal.provider.vbulletin.internal.ForumFactory; +import org.eclipse.ecf.internal.provider.vbulletin.internal.GuestFactory; +import org.eclipse.ecf.internal.provider.vbulletin.internal.MemberFactory; +import org.eclipse.ecf.internal.provider.vbulletin.internal.MemberGroupFactory; +import org.eclipse.ecf.internal.provider.vbulletin.internal.ThreadMessageFactory; +import org.eclipse.ecf.internal.provider.vbulletin.internal.VBException; + +public class VBParser extends AbstractParser { + + public VBParser(Namespace namespace, URL baseURL) { + super(namespace, baseURL); + } + + private static final Pattern PAT_TITLE = Pattern + .compile("<title>(.*?)</title>"); + + public String parseTitle(CharSequence seq) { + Matcher m = PAT_TITLE.matcher(seq); + if (m.find()) { + return new String(m.group(1)); + } + return null; + } + + @Override + public IBBObjectFactory getMemberFactory() { + return new MemberFactory(); + } + + public Pattern getMemberNamePattern() { + return Pattern.compile("- View Profile: (.*?)</title>"); + } + + public static final Pattern PAT_FORUM = Pattern + .compile("<a href=\"forumdisplay.php?(?:.*?)f=([0-9]+)\">(.*?)</a>"); + + public Map<ID, Forum> parseForums(final CharSequence seq) { + Map<ID, Forum> forums = new LinkedHashMap<ID, Forum>(); + Matcher matcher = PAT_FORUM.matcher(seq); + while (matcher.find()) { + String name = StringUtil.stripHTMLTrim(matcher.group(2)); + // String desc = StringUtil.stripHTMLTrim(matcher.group(3)); + if (StringUtil.notEmptyStr(name)) { + ForumFactory ff = new ForumFactory(); + String idStr = matcher.group(1); + ID id = null; + try { + id = ff.createBBObjectId(namespace, baseURL, idStr); + } catch (NumberFormatException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IDCreateException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + Forum forum = (Forum) ff.createBBObject(id, name, null); + // forum.setDescription(desc); + forums.put(id, forum); + } + } + return forums; + } + + @Override + public IPatternDescriptor getThreadPattern() { + return DefaultPatternDescriptor + .defaultCustom( + Pattern + .compile( + "<a href=\"showthread.php?(?:.*?)t=([0-9]+?)\" id=\"thread_title_(?:[0-9]+?)\">(.*?)</a>(?:.*?)<div class=\"smallfont\">(.*?)</div>", + Pattern.DOTALL), new String[] { "id", + "name", "authorInfo" }); + } + + @Override + public IBBObjectFactory getThreadFactory() { + return new ThreadFactory(); + } + + public static final Pattern PAT_MSG_INFORMATION = Pattern + .compile( + "<div class=\"panel\">(?:.*?)<blockquote>(.*?)</blockquote>(?:.*?)</td>", + Pattern.DOTALL); + + public String parseInformationMessage(CharSequence seq) { + String msg = null; + Matcher m = PAT_MSG_INFORMATION.matcher(seq); + if (m.find()) { + msg = "vBulletin: " + m.group(1); + } + return msg; + } + + public static final Pattern PAT_MSG_POST_ERROR = Pattern + .compile( + "<!--POSTERROR do not remove this comment-->(.*?)<!--/POSTERROR do not remove this comment-->", + Pattern.DOTALL); + + public String parsePostErrorMessage(CharSequence seq) { + String msg = null; + Matcher m = PAT_MSG_POST_ERROR.matcher(seq); + if (m.find()) { + msg = "vBulletin: " + m.group(1); + } + return msg; + } + + protected BBException createVBException(String msg, CharSequence seq) { + String vbmsg = parseInformationMessage(seq); + if (vbmsg == null) { + vbmsg = parsePostErrorMessage(seq); + } + if (vbmsg != null) { + return new BBException(msg, new VBException(new String(StringUtil + .stripHTMLTrim(vbmsg)))); + } else { + return new BBException(msg); + } + } + + public static final Pattern PAT_THEAD_ATTRS = Pattern + // .compile("<title>(?:.*?) :: View topic - (.*?)</title>"); + .compile( + "<td class=\"navbar\"(?:.*?)><a href=\"/showthread.php\\?t=([0-9]+)(?:.*?)\">(.*?)</td>", + Pattern.DOTALL); + + public static final Pattern PAT_THEAD_ATTRS_FORUM = Pattern + .compile("<span class=\"navbar\">> <a href=\"forumdisplay.php\\?f=([0-9]+?)\">(.*?)</a></span>"); + + public static final IPatternDescriptor PD_THREAD_ATTRS = DefaultPatternDescriptor + .defaultIdAndName(PAT_THEAD_ATTRS); + + public static final IPatternDescriptor PD_THREAD_ATTRS_FORUM = DefaultPatternDescriptor + .defaultIdAndName(PAT_THEAD_ATTRS_FORUM); + + public Thread parseThreadPageForThreadAttributes(CharSequence seq) + throws BBException { + Thread t = (Thread) genericParser.parseSingleIdName(PD_THREAD_ATTRS, + seq, new ThreadFactory()); + if (t != null) { + Map<ID, IBBObject> forums = genericParser.parseMultiIdName( + PD_THREAD_ATTRS_FORUM, seq, new ForumFactory(), true); + Forum prev = null; + Forum f = null; + for (IBBObject obj : forums.values()) { + f = (Forum) obj; + if (prev != null) { + prev.subforums.add(f); + } + f.setParent(prev); + prev = f; + } + t.forum = f; + return t; + } else { + throw new BBException("Failed to parse the thread."); + } + } + + public static final Pattern PAT_MSG = Pattern.compile( + "<!-- post #([0-9]+) -->(.*)<!-- / post #\\1 -->", Pattern.DOTALL); + + public List<ThreadMessage> parseMessages2(final CharSequence seq, + final ID lastReadId, boolean desc, SkippedStatus skipped) + throws BBException { + Matcher m; + ThreadMessage msg; + List<ThreadMessage> messages = new ArrayList<ThreadMessage>(); + m = PAT_MSG.matcher(seq); + while (m.find()) { + ThreadMessageFactory tmf = new ThreadMessageFactory(); + ThreadMessageID id = null; + try { + id = (ThreadMessageID) tmf.createBBObjectId(namespace, baseURL, + m.group(1)); + } catch (NumberFormatException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IDCreateException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + if (lastReadId == null + || id.getLongValue() > ((ThreadMessageID) lastReadId) + .getLongValue()) { + String msgSrc = m.group(2); + msg = parseMessage2(id, msgSrc); + if (msg != null) { + if (desc) { + messages.add(0, msg); + } else { + messages.add(msg); + } + } + } else { + skipped.messagesSkipped = true; + } + } + return messages; + } + + public static final Pattern PAT_MSG_USER = Pattern + .compile("<a class=\"bigusername\" href=\"member.php?(.*)u=([0-9]+)\">(.*)</a>"); + + public static final Pattern PAT_MSG_TITLE = Pattern.compile( + "<!-- icon and title -->(.*)<!-- / icon and title -->", + Pattern.DOTALL); + + public static final Pattern PAT_MSG_MESSAGE = Pattern.compile( + "<!-- message -->(.*)<!-- / message -->", Pattern.DOTALL); + + public static final Pattern PAT_MSG_TIMESTAMP = Pattern.compile( + "<!-- status icon and date -->(.*)<!-- / status icon and date -->", + Pattern.DOTALL); + + @Override + public Long parseTimestamp(CharSequence seq) { + Long l = null; + final Locale locale = Locale.ENGLISH; + final String dateFormat = "MM-dd-yyyy"; + final String timeFormat = "hh:mm aa"; + final String dateTimeSeparator = ", "; + final DateFormat fmtTimestamp = new SimpleDateFormat(dateFormat + + dateTimeSeparator + timeFormat, locale); + final DateFormat fmtTime = new SimpleDateFormat(timeFormat, locale); + Matcher matcher; + matcher = PAT_MSG_TIMESTAMP.matcher(seq); + if (matcher.find()) { + String timestamp = StringUtil.stripHTMLFullTrim(matcher.group(1)); + timestamp = timestamp.replaceAll("1st", "1"); + timestamp = timestamp.replaceAll("2nd", "2"); + timestamp = timestamp.replaceAll("3rd", "3"); + timestamp = timestamp.replaceAll("th", ""); + if (timestamp.startsWith("Today") + || timestamp.startsWith("Yesterday")) { + String[] s = timestamp.split(dateTimeSeparator); + try { + Calendar now = Calendar.getInstance(fmtTime.getTimeZone()); + if ("Yesterday".equals(s[0])) { + now.add(Calendar.DATE, -1); + } + + Date d = fmtTime.parse(s[1]); + Calendar then = Calendar.getInstance(fmtTime.getTimeZone()); + then.setTime(d); + then.set(now.get(Calendar.YEAR), now.get(Calendar.MONTH), + now.get(Calendar.DATE)); + l = new Long(then.getTimeInMillis()); + } catch (ParseException e) { + e.printStackTrace(); + } + } else { + try { + l = new Long(fmtTimestamp.parse(timestamp).getTime()); + } catch (ParseException e) { + e.printStackTrace(); + } + } + } + return l; + } + + private ThreadMessage parseMessage2(final ID id, final CharSequence seq) { + ThreadMessage msg = null; + ThreadMessageFactory tmf = new ThreadMessageFactory(); + msg = (ThreadMessage) tmf.createBBObject(id, null, null); + Matcher m; + String uname; + Long l = parseTimestamp(seq); + if (l != null) { + msg.timePosted = new Date(l); + } + m = Pattern.compile( + "<div id=\"postmenu_" + ((ThreadMessageID) id).getLongValue() + + "\">(.*?)</div>", Pattern.DOTALL).matcher(seq); + if (m.find()) { + String userInfoStr = m.group(1); + m = PAT_MSG_USER.matcher(userInfoStr); + if (m.find()) { + MemberFactory mf = new MemberFactory(); + uname = new String(StringUtil.simpleStripHTML(m.group(3))); + ID uid = null; + try { + uid = mf.createBBObjectId(namespace, baseURL, m.group(2)); + } catch (NumberFormatException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IDCreateException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + msg.author = (IMember) mf.createBBObject(uid, uname, null); + } else { + // Didn't find a registered author, so the userinfo should + // contain only the username. + msg.author = new Member(new String(userInfoStr.trim())); + } + } + m = Pattern.compile( + "#<a href=\"showpost.php\\?p=" + + ((ThreadMessageID) id).getLongValue() + + "(?:.*?)><strong>([0-9]+)</strong></a>").matcher(seq); + m.find(); + msg.number = Integer.parseInt(m.group(1)); + m = PAT_MSG_TITLE.matcher(seq); + m.find(); + msg.setNameInternal(new String(StringUtil.stripHTMLTrim(m.group(1)))); + m = PAT_MSG_MESSAGE.matcher(seq); + m.find(); + String message = StringUtil.stripHTMLFullTrim(m.group(1)); + msg.message = message; + return msg; + } + + public static final Pattern PAT_PAGES = Pattern + .compile("<td class=\"vbmenu_control\"(?:.*?)>Page ([0-9]+) of ([0-9]+)</td>"); + + public int parseNextPage(CharSequence seq) { + Matcher m = PAT_PAGES.matcher(seq); + int next = -1; + if (m.find()) { + int current = Integer.parseInt(m.group(1)); + int last = Integer.parseInt(m.group(2)); + if (current < last) { + next = current + 1; + } + } + return next; + } + + public int parsePrevPage(CharSequence seq) { + Matcher m = PAT_PAGES.matcher(seq); + int prev = -1; + if (m.find()) { + int current = Integer.parseInt(m.group(1)); + if (current > 1) { + prev = current - 1; + } + } + return prev; + } + + @Override + public IPatternDescriptor getMemberPattern() { + return DefaultPatternDescriptor.defaultIdAndName(Pattern + .compile("<a href=\"member.php\\?u=([0-9]+?)\">(.*?)</a>")); + } + + @Override + public IPatternDescriptor getAuthorInfoMemberPattern() { + return DefaultPatternDescriptor + .defaultIdAndName(Pattern + .compile("<span(?:.*?)onclick=\"window.open('member.php\\?u=([0-9]+?)', '_self')\">(.*?)</span>")); + } + + @Override + public Pattern getMemberGroupContainerPattern() { + return Pattern + .compile( + "<form action=\"profile.php\\?do=joingroup\" method=\"post\">(.*?)</form>", + Pattern.DOTALL); + } + + @Override + public IBBObjectFactory getMemberGroupFactory() { + return new MemberGroupFactory(); + } + + @Override + public IPatternDescriptor getMemberGroupPattern() { + return DefaultPatternDescriptor + .reverseIdAndName(Pattern + .compile( + "<tr>(?:.*?)<td class=\"alt(?:[12]{1})\">(.*?)<div class=\"smallfont\">(?:.*?)</div>(?:.*?)<label for=\"rb_join_([0-9]+?)\">(?:.*?)</tr>", + Pattern.DOTALL)); + } + + @Override + public void throwException(final String msg, final CharSequence seq) + throws BBException { + throw createVBException(msg, seq); + } + + @Override + public IBBObjectFactory getGuestFactory() { + return new GuestFactory(); + } + +} diff --git a/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/VBulletin.java b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/VBulletin.java new file mode 100644 index 000000000..250c1de3a --- /dev/null +++ b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/VBulletin.java @@ -0,0 +1,225 @@ +/******************************************************************************* + * Copyright (c) 2005, 2006 Erkki Lindpere and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Erkki Lindpere - initial API and implementation + *******************************************************************************/ +package org.eclipse.ecf.internal.provider.vbulletin; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.commons.httpclient.NameValuePair; +import org.eclipse.ecf.bulletinboard.BBException; +import org.eclipse.ecf.bulletinboard.IBBCredentials; +import org.eclipse.ecf.bulletinboard.IForum; +import org.eclipse.ecf.bulletinboard.IThread; +import org.eclipse.ecf.bulletinboard.IThreadMessage; +import org.eclipse.ecf.core.ContainerConnectException; +import org.eclipse.ecf.core.identity.ID; +import org.eclipse.ecf.internal.bulletinboard.commons.AbstractBulletinBoard; +import org.eclipse.ecf.internal.bulletinboard.commons.webapp.GetRequest; +import org.eclipse.ecf.internal.bulletinboard.commons.webapp.PostRequest; +import org.eclipse.ecf.internal.bulletinboard.commons.webapp.WebRequest; +import org.eclipse.ecf.internal.provider.vbulletin.container.VBContainer; +import org.eclipse.ecf.internal.provider.vbulletin.identity.MemberID; +import org.eclipse.ecf.internal.provider.vbulletin.identity.ThreadID; +import org.eclipse.ecf.internal.provider.vbulletin.internal.MemberFactory; +import org.eclipse.ecf.internal.provider.vbulletin.internal.VBCookies; + +public class VBulletin extends AbstractBulletinBoard { + + private String sessionId; + + private String title; + + private Map<ID, Forum> cachedForums; + + public VBulletin(VBContainer mainContainer) { + super(mainContainer); + } + + protected void reset() { + this.cachedForums = new HashMap<ID, Forum>(); + super.reset(); + } + + public void postConnect() { + super.postConnect(); + parser = new VBParser(namespace, url); + } + + public void postDisconnect() { + parser = null; + super.postDisconnect(); + } + + /** + * @return Returns the sessionId. + */ + protected String getSessionId() { + return sessionId; + } + + public String getTitle() throws BBException { + if (this.title == null) { + GetRequest request = new GetRequest(httpClient, url, ""); + String resp = null; + try { + request.execute(); + resp = request.getResponseBodyAsString(); + } catch (IOException e) { + throw new BBException(e); + } + request.releaseConnection(); + if (resp != null) { + this.title = getParser().parseTitle(resp); + } + } + return this.title; + } + + public List<IForum> getForums() throws BBException { + if (cachedForums.isEmpty()) { + GetRequest request = new GetRequest(httpClient, url, ""); + try { + request.execute(); + String resp = request.getResponseBodyAsString(); + request.releaseConnection(); + cachedForums = getParser().parseForums(resp); + for (Forum forum : cachedForums.values()) { + forum.setBulletinBoard(this); + } + } catch (IOException e) { + // log.error(e); + } + } + return new ArrayList<IForum>(cachedForums.values()); + } + + public List<IForum> getTopLevelForums() throws BBException { + List<IForum> topForums = new ArrayList<IForum>(); + for (IForum forum : getForums()) { + if (forum.getParentForum() == null) { + topForums.add(forum); + } + } + return topForums; + } + + public IForum getForum(ID id) throws BBException { + if (cachedForums.isEmpty()) { + getForums(); + } + return cachedForums.get(id); + } + + public IThread getThread(ID id) throws BBException { + GetRequest request = new GetRequest(httpClient, url, "showthread.php"); + request.addParameter(new NameValuePair("t", String + .valueOf(((ThreadID) id).getLongValue()))); + String resp = null; + try { + request.execute(); + resp = request.getResponseBodyAsString(); + } catch (IOException e) { + e.printStackTrace(); + } + request.releaseConnection(); + if (resp != null) { + Thread t = getParser().parseThreadPageForThreadAttributes(resp); + t.setBulletinBoard(this); + return t; + } + return null; + } + + public IThreadMessage getMessage(ID id) throws BBException { + // TODO Auto-generated method stub + return null; + } + + @Override + protected WebRequest createMemberListRequest() { + return new GetRequest(httpClient, url, "memberlist.php"); + } + + @Override + protected WebRequest createMemberPageRequest(ID id) { + WebRequest request = new GetRequest(httpClient, url, "member.php"); + + NameValuePair params[] = { new NameValuePair("u", String + .valueOf(((MemberID) id).getLongValue())) }; + request.setParameters(params); + return request; + } + + public boolean login(IBBCredentials credentials) throws BBException { + PostRequest request = new PostRequest(httpClient, url, "login.php"); + NameValuePair params[] = { + new NameValuePair("vb_login_username", credentials + .getUsername()), + new NameValuePair("cookieuser", "1"), + new NameValuePair("vb_login_password", credentials + .getPassword()), new NameValuePair("submit", "Login"), + new NameValuePair("s", ""), new NameValuePair("do", "login"), + new NameValuePair("forceredirect", "0"), + new NameValuePair("vb_login_md5password", ""), + new NameValuePair("vb_login_md5password_utf", "") }; + request.setParameters(params); + try { + request.execute(); + request.releaseConnection(); + Map<String, String> detectedCookies = VBCookies + .detectCookies(httpClient.getState().getCookies()); + if (detectedCookies.containsKey(VBCookies.KEY_SESS_ID)) { + // We have a session id + sessionId = detectedCookies.get(VBCookies.KEY_SESS_ID); + } + if (detectedCookies.containsKey(VBCookies.KEY_USER_ID)) { + // We have a user id + ID id = new MemberFactory().createBBObjectId(namespace, url, + (String) detectedCookies.get(VBCookies.KEY_USER_ID)); + if (id == null) { + return false; + } else { + loggedInMemberId = id; + return true; + } + } + } catch (Exception e) { + throw new BBException(e); + } + return false; + } + + public boolean logout() throws BBException { + PostRequest request = new PostRequest(httpClient, url, "logout.php"); + try { + request.execute(); + request.releaseConnection(); + loggedInMemberId = null; + return true; + } catch (Exception e) { + throw new BBException(e); + } + } + + public VBParser getParser() { + return (VBParser) parser; + } + + @Override + protected WebRequest createMemberGroupListRequest() { + WebRequest request = new GetRequest(httpClient, url, "profile.php"); + request.addParameter(new NameValuePair("do", "editusergroups")); + return request; + } +} diff --git a/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/container/ContainerInstantiator.java b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/container/ContainerInstantiator.java new file mode 100644 index 000000000..9215ce139 --- /dev/null +++ b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/container/ContainerInstantiator.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2005, 2006 Erkki Lindpere and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Erkki Lindpere - initial API and implementation + *******************************************************************************/ +package org.eclipse.ecf.internal.provider.vbulletin.container; + +import org.eclipse.ecf.core.ContainerCreateException; +import org.eclipse.ecf.core.ContainerTypeDescription; +import org.eclipse.ecf.core.IContainer; +import org.eclipse.ecf.core.identity.ID; +import org.eclipse.ecf.core.identity.IDCreateException; +import org.eclipse.ecf.core.identity.IDFactory; +import org.eclipse.ecf.core.provider.IContainerInstantiator; + +public class ContainerInstantiator implements IContainerInstantiator { + + public IContainer createInstance(ContainerTypeDescription description, + Object[] args) throws ContainerCreateException { + ID guid; + try { + guid = IDFactory.getDefault().createGUID(); + } catch (IDCreateException e) { + throw new ContainerCreateException("Exception creating ID", e); + } + return new VBContainer(guid); + } + + public String[] getSupportedAdapterTypes( + ContainerTypeDescription description) { + return new String[] { "org.eclipse.ecf.bulletinboard.IBulletinBoardContainerAdapter" }; + } + + public Class[][] getSupportedParameterTypes( + ContainerTypeDescription description) { + return new Class[][] {}; + } + +} diff --git a/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/container/VBContainer.java b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/container/VBContainer.java new file mode 100644 index 000000000..f181aa928 --- /dev/null +++ b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/container/VBContainer.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2005, 2006 Erkki Lindpere and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Erkki Lindpere - initial API and implementation + *******************************************************************************/ +package org.eclipse.ecf.internal.provider.vbulletin.container; + +import org.eclipse.ecf.core.identity.ID; +import org.eclipse.ecf.core.identity.IDFactory; +import org.eclipse.ecf.core.identity.Namespace; +import org.eclipse.ecf.internal.bulletinboard.commons.AbstractBBContainer; +import org.eclipse.ecf.internal.provider.vbulletin.Activator; +import org.eclipse.ecf.internal.provider.vbulletin.VBFactory; + +public class VBContainer extends AbstractBBContainer { + + public VBContainer(ID id) { + super(id); + bb = VBFactory.getDefault().createVB(this); + } + + public Namespace getConnectNamespace() { + return IDFactory.getDefault().getNamespaceByName( + Activator.getNamespaceIdentifier()); + } +} diff --git a/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/identity/ForumID.java b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/identity/ForumID.java new file mode 100644 index 000000000..ec5d752c2 --- /dev/null +++ b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/identity/ForumID.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2005, 2006 Erkki Lindpere and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Erkki Lindpere - initial API and implementation + *******************************************************************************/ +package org.eclipse.ecf.internal.provider.vbulletin.identity; + +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.eclipse.ecf.internal.bulletinboard.commons.util.IDUtil; + +public class ForumID extends VBID { + + private static final long serialVersionUID = 6005970691318023633L; + + public ForumID(VBNamespace namespace, URI uri) throws URISyntaxException { + super(namespace, uri); + } + + public ForumID(VBNamespace namespace, URL baseURL, long longValue) + throws URISyntaxException { + super(namespace, IDUtil.composeURI(baseURL, "forumdisplay.php?f=" + + longValue)); + } + + public long getLongValue() { + Matcher m = Pattern.compile("forumdisplay.php\\?(?:.*?)f=([0-9]+)") + .matcher(uri.toString()); + if (m.find()) { + return Long.parseLong(m.group(1)); + } + return -1; + } +} diff --git a/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/identity/GuestID.java b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/identity/GuestID.java new file mode 100644 index 000000000..ce7f60c3d --- /dev/null +++ b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/identity/GuestID.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2005, 2006 Erkki Lindpere and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Erkki Lindpere - initial API and implementation + *******************************************************************************/ +package org.eclipse.ecf.internal.provider.vbulletin.identity; + +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; + +import org.eclipse.ecf.internal.bulletinboard.commons.util.IDUtil; + +public class GuestID extends VBID { + + private static final long serialVersionUID = 6005970691318023633L; + + public GuestID(VBNamespace namespace, URI uri) throws URISyntaxException { + super(namespace, uri); + } + + public GuestID(VBNamespace namespace, URL baseURL, String name) + throws URISyntaxException { + super(namespace, IDUtil.composeURI(baseURL, "member.php?u=0#" + name)); + } + + public long getLongValue() { + return 0; + } +} diff --git a/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/identity/MemberGroupID.java b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/identity/MemberGroupID.java new file mode 100644 index 000000000..945b28ce8 --- /dev/null +++ b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/identity/MemberGroupID.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2005, 2006 Erkki Lindpere and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Erkki Lindpere - initial API and implementation + *******************************************************************************/ +package org.eclipse.ecf.internal.provider.vbulletin.identity; + +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.eclipse.ecf.internal.bulletinboard.commons.util.IDUtil; + +public class MemberGroupID extends VBID { + + private static final long serialVersionUID = 6005970691318023633L; + + public MemberGroupID(VBNamespace namespace, URI uri) + throws URISyntaxException { + super(namespace, uri); + } + + public MemberGroupID(VBNamespace namespace, URL baseURL, long longValue) + throws URISyntaxException { + super(namespace, IDUtil.composeURI(baseURL, + "profile.php?do=editusergroups&usergroupid=" + longValue)); + } + + public long getLongValue() { + Matcher m = Pattern.compile( + "profile.php\\?do=editusergroups(?:.*?)usergroupid=([0-9]+)") + .matcher(uri.toString()); + if (m.find()) { + return Long.parseLong(m.group(1)); + } + return -1; + } +} diff --git a/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/identity/MemberID.java b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/identity/MemberID.java new file mode 100644 index 000000000..f2274120e --- /dev/null +++ b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/identity/MemberID.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2005, 2006 Erkki Lindpere and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Erkki Lindpere - initial API and implementation + *******************************************************************************/ +package org.eclipse.ecf.internal.provider.vbulletin.identity; + +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.eclipse.ecf.internal.bulletinboard.commons.util.IDUtil; + +public class MemberID extends VBID { + + private static final long serialVersionUID = 6005970691318023633L; + + public MemberID(VBNamespace namespace, URI uri) throws URISyntaxException { + super(namespace, uri); + } + + public MemberID(VBNamespace namespace, URL baseURL, long longValue) + throws URISyntaxException { + super(namespace, IDUtil + .composeURI(baseURL, "member.php?u=" + longValue)); + } + + public long getLongValue() { + Matcher m = Pattern.compile( + "member.php\\?(?:.*?)u=([0-9]+)").matcher( + uri.toString()); + if (m.find()) { + return Long.parseLong(m.group(1)); + } + return -1; + } +} diff --git a/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/identity/ThreadID.java b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/identity/ThreadID.java new file mode 100644 index 000000000..73f377613 --- /dev/null +++ b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/identity/ThreadID.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2005, 2006 Erkki Lindpere and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Erkki Lindpere - initial API and implementation + *******************************************************************************/ +package org.eclipse.ecf.internal.provider.vbulletin.identity; + +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.eclipse.ecf.internal.bulletinboard.commons.util.IDUtil; + +public class ThreadID extends VBID { + + private static final long serialVersionUID = 6005970691318023633L; + + public ThreadID(VBNamespace namespace, URI uri) + throws URISyntaxException { + super(namespace, uri); + } + + public ThreadID(VBNamespace namespace, URL baseURL, long longValue) + throws URISyntaxException { + super(namespace, IDUtil.composeURI(baseURL, "showthread.php?t=" + + longValue)); + } + + public long getLongValue() { + Matcher m = Pattern.compile("showthread.php\\?(?:.*?)t=([0-9]+)") + .matcher(uri.toString()); + if (m.find()) { + return Long.parseLong(m.group(1)); + } + return -1; + } +} diff --git a/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/identity/ThreadMessageID.java b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/identity/ThreadMessageID.java new file mode 100644 index 000000000..8cbcbb285 --- /dev/null +++ b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/identity/ThreadMessageID.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2005, 2006 Erkki Lindpere and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Erkki Lindpere - initial API and implementation + *******************************************************************************/ +package org.eclipse.ecf.internal.provider.vbulletin.identity; + +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.eclipse.ecf.internal.bulletinboard.commons.util.IDUtil; + +public class ThreadMessageID extends VBID { + + private static final long serialVersionUID = 6005970691318023633L; + + public ThreadMessageID(VBNamespace namespace, URI uri) + throws URISyntaxException { + super(namespace, uri); + } + + public ThreadMessageID(VBNamespace namespace, URL baseURL, long longValue) + throws URISyntaxException { + super(namespace, IDUtil.composeURI(baseURL, "showpost.php?p=" + + longValue)); + } + + public long getLongValue() { + Matcher m = Pattern.compile("showpost.php\\?(?:.*?)p=([0-9]+)") + .matcher(uri.toString()); + if (m.find()) { + return Long.parseLong(m.group(1)); + } + return -1; + } +} diff --git a/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/identity/VBID.java b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/identity/VBID.java new file mode 100644 index 000000000..0af2506ae --- /dev/null +++ b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/identity/VBID.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright (c) 2005, 2006 Erkki Lindpere and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Erkki Lindpere - initial API and implementation + *******************************************************************************/ +package org.eclipse.ecf.internal.provider.vbulletin.identity; + +import java.net.URI; +import java.net.URISyntaxException; + +import org.eclipse.ecf.core.identity.BaseID; + +public class VBID extends BaseID { + + private static final long serialVersionUID = 7679927919437059784L; + + protected URI uri; + + public VBID(VBNamespace namespace, URI uri) throws URISyntaxException { + super(namespace); + this.uri = uri; + } + + @Override + protected int namespaceCompareTo(BaseID o) { + if (!(o instanceof VBID)) { + throw new ClassCastException("Uncomparable types."); + } + return uri.compareTo(((VBID) o).uri); + } + + @Override + protected boolean namespaceEquals(BaseID o) { + if (!(o instanceof VBID)) { + return false; + } + return uri.equals(((VBID) o).uri); + } + + @Override + protected String namespaceGetName() { + return uri.toString(); + } + + @Override + protected int namespaceHashCode() { + return (int) uri.hashCode(); + } + + @Override + protected String namespaceToExternalForm() { + return uri.toString(); + } + +} diff --git a/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/identity/VBNamespace.java b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/identity/VBNamespace.java new file mode 100644 index 000000000..db7fa5680 --- /dev/null +++ b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/identity/VBNamespace.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * Copyright (c) 2005, 2006 Erkki Lindpere and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Erkki Lindpere - initial API and implementation + *******************************************************************************/ +package org.eclipse.ecf.internal.provider.vbulletin.identity; + +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.eclipse.ecf.core.identity.ID; +import org.eclipse.ecf.core.identity.IDCreateException; +import org.eclipse.ecf.core.identity.Namespace; +import org.eclipse.ecf.internal.bulletinboard.commons.PatternFactoryPair; +import org.eclipse.ecf.internal.provider.vbulletin.ThreadFactory; +import org.eclipse.ecf.internal.provider.vbulletin.internal.ForumFactory; +import org.eclipse.ecf.internal.provider.vbulletin.internal.MemberFactory; +import org.eclipse.ecf.internal.provider.vbulletin.internal.MemberGroupFactory; +import org.eclipse.ecf.internal.provider.vbulletin.internal.ThreadMessageFactory; + +public class VBNamespace extends Namespace { + + private static final long serialVersionUID = 5509243089799844682L; + + private static final String PROTOCOL = "http://"; + + private static final PatternFactoryPair[] ID_FACTORIES = { + new PatternFactoryPair(Pattern + .compile("(.*?)forumdisplay.php\\?(?:.*?)f=([0-9]+)"), + new ForumFactory()), + new PatternFactoryPair(Pattern + .compile("(.*?)showthread.php\\?(?:.*?)t=([0-9]+)"), + new ThreadFactory()), + new PatternFactoryPair(Pattern + .compile("(.*?)showpost.php\\?(?:.*?)p=([0-9]+)"), + new ThreadMessageFactory()), + new PatternFactoryPair(Pattern + .compile("(.*?)member.php\\?(?:.*?)u=([0-9]+)"), + new MemberFactory()), + new PatternFactoryPair( + Pattern + .compile("(.*?)profile.php\\?do=editusergroups(?:.*?)usergroupid=([0-9]+)"), + new MemberGroupFactory()) }; + + @Override + public ID createInstance(Object[] args) throws IDCreateException { + try { + ID id = null; + for (PatternFactoryPair creator : ID_FACTORIES) { + Matcher m = creator.getPattern() + .matcher((CharSequence) args[0]); + if (m.find()) { + id = creator.getFactory().createBBObjectId(this, + new URL(m.group(1)), m.group(2)); + return id; + } + } + return new VBID(this, new URI((String) args[0])); + } catch (URISyntaxException e) { + throw new IDCreateException("VB ID creation exception", e); + } catch (NumberFormatException e) { + throw new IDCreateException("VB ID creation exception", e); + } catch (MalformedURLException e) { + throw new IDCreateException("VB ID creation exception", e); + } + } + + @Override + public String getScheme() { + return PROTOCOL; + } + +} diff --git a/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/internal/ForumFactory.java b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/internal/ForumFactory.java new file mode 100644 index 000000000..1999bca57 --- /dev/null +++ b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/internal/ForumFactory.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 2005, 2006 Erkki Lindpere and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Erkki Lindpere - initial API and implementation + *******************************************************************************/ +package org.eclipse.ecf.internal.provider.vbulletin.internal; + +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.Map; + +import org.eclipse.ecf.bulletinboard.IBBObject; +import org.eclipse.ecf.core.identity.ID; +import org.eclipse.ecf.core.identity.IDCreateException; +import org.eclipse.ecf.core.identity.Namespace; +import org.eclipse.ecf.internal.bulletinboard.commons.IBBObjectFactory; +import org.eclipse.ecf.internal.provider.vbulletin.Forum; +import org.eclipse.ecf.internal.provider.vbulletin.identity.ForumID; +import org.eclipse.ecf.internal.provider.vbulletin.identity.VBNamespace; + +public class ForumFactory implements IBBObjectFactory { + public ID createBBObjectId(Namespace namespace, String stringValue) + throws IDCreateException { + try { + return new ForumID((VBNamespace) namespace, new URI(stringValue)); + } catch (URISyntaxException e) { + throw new IDCreateException(e); + } + } + + public ID createBBObjectId(Namespace namespace, URL baseURL, String longValue) + throws IDCreateException { + try { + return new ForumID((VBNamespace) namespace, baseURL, Long.parseLong(longValue)); + } catch (URISyntaxException e) { + throw new IDCreateException(e); + } + } + + public IBBObject createBBObject(ID id, String name, Map<String, Object> parameters) { + return new Forum((ForumID) id, name); + } +}
\ No newline at end of file diff --git a/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/internal/GuestFactory.java b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/internal/GuestFactory.java new file mode 100644 index 000000000..3d3eb95c1 --- /dev/null +++ b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/internal/GuestFactory.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright (c) 2005, 2006 Erkki Lindpere and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Erkki Lindpere - initial API and implementation + *******************************************************************************/ +package org.eclipse.ecf.internal.provider.vbulletin.internal; + +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.Map; + +import org.eclipse.ecf.bulletinboard.IBBObject; +import org.eclipse.ecf.core.identity.ID; +import org.eclipse.ecf.core.identity.IDCreateException; +import org.eclipse.ecf.core.identity.Namespace; +import org.eclipse.ecf.internal.bulletinboard.commons.IBBObjectFactory; +import org.eclipse.ecf.internal.provider.vbulletin.Member; +import org.eclipse.ecf.internal.provider.vbulletin.identity.GuestID; +import org.eclipse.ecf.internal.provider.vbulletin.identity.VBNamespace; + +public class GuestFactory implements IBBObjectFactory { + public ID createBBObjectId(Namespace namespace, String stringValue) + throws IDCreateException { + try { + return new GuestID((VBNamespace) namespace, new URI(stringValue)); + } catch (URISyntaxException e) { + throw new IDCreateException(e); + } + } + + public ID createBBObjectId(Namespace namespace, URL baseURL, + String longValue) throws IDCreateException { + try { + return new GuestID((VBNamespace) namespace, baseURL, longValue); + } catch (URISyntaxException e) { + throw new IDCreateException(e); + } + } + + public IBBObject createBBObject(ID id, String name, + Map<String, Object> parameters) { + return new Member((GuestID) id, name); + } +}
\ No newline at end of file diff --git a/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/internal/MemberFactory.java b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/internal/MemberFactory.java new file mode 100644 index 000000000..33b36c164 --- /dev/null +++ b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/internal/MemberFactory.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright (c) 2005, 2006 Erkki Lindpere and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Erkki Lindpere - initial API and implementation + *******************************************************************************/ +package org.eclipse.ecf.internal.provider.vbulletin.internal; + +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.Map; + +import org.eclipse.ecf.bulletinboard.IBBObject; +import org.eclipse.ecf.core.identity.ID; +import org.eclipse.ecf.core.identity.IDCreateException; +import org.eclipse.ecf.core.identity.Namespace; +import org.eclipse.ecf.internal.bulletinboard.commons.IBBObjectFactory; +import org.eclipse.ecf.internal.provider.vbulletin.Member; +import org.eclipse.ecf.internal.provider.vbulletin.identity.MemberID; +import org.eclipse.ecf.internal.provider.vbulletin.identity.VBNamespace; + +public class MemberFactory implements IBBObjectFactory { + public ID createBBObjectId(Namespace namespace, String stringValue) + throws IDCreateException { + try { + return new MemberID((VBNamespace) namespace, new URI(stringValue)); + } catch (URISyntaxException e) { + throw new IDCreateException(e); + } + } + + public ID createBBObjectId(Namespace namespace, URL baseURL, + String longValue) throws IDCreateException { + try { + return new MemberID((VBNamespace) namespace, baseURL, Long + .parseLong(longValue)); + } catch (URISyntaxException e) { + throw new IDCreateException(e); + } + } + + public IBBObject createBBObject(ID id, String name, + Map<String, Object> parameters) { + return new Member((MemberID) id, name); + } +}
\ No newline at end of file diff --git a/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/internal/MemberGroupFactory.java b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/internal/MemberGroupFactory.java new file mode 100644 index 000000000..5426f0974 --- /dev/null +++ b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/internal/MemberGroupFactory.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright (c) 2005, 2006 Erkki Lindpere and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Erkki Lindpere - initial API and implementation + *******************************************************************************/ +package org.eclipse.ecf.internal.provider.vbulletin.internal; + +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.Map; + +import org.eclipse.ecf.bulletinboard.IBBObject; +import org.eclipse.ecf.core.identity.ID; +import org.eclipse.ecf.core.identity.IDCreateException; +import org.eclipse.ecf.core.identity.Namespace; +import org.eclipse.ecf.internal.bulletinboard.commons.IBBObjectFactory; +import org.eclipse.ecf.internal.provider.vbulletin.MemberGroup; +import org.eclipse.ecf.internal.provider.vbulletin.identity.MemberGroupID; +import org.eclipse.ecf.internal.provider.vbulletin.identity.VBNamespace; + +public class MemberGroupFactory implements IBBObjectFactory { + public ID createBBObjectId(Namespace namespace, String stringValue) + throws IDCreateException { + try { + return new MemberGroupID((VBNamespace) namespace, new URI( + stringValue)); + } catch (URISyntaxException e) { + throw new IDCreateException(e); + } + } + + public ID createBBObjectId(Namespace namespace, URL baseURL, String longValue) + throws IDCreateException { + try { + return new MemberGroupID((VBNamespace) namespace, baseURL, + Long.parseLong(longValue)); + } catch (URISyntaxException e) { + throw new IDCreateException(e); + } + } + + public IBBObject createBBObject(ID id, String name, Map<String, Object> parameters) { + return new MemberGroup((MemberGroupID) id, name); + } +}
\ No newline at end of file diff --git a/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/internal/ThreadMessageFactory.java b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/internal/ThreadMessageFactory.java new file mode 100644 index 000000000..3917341af --- /dev/null +++ b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/internal/ThreadMessageFactory.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright (c) 2005, 2006 Erkki Lindpere and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Erkki Lindpere - initial API and implementation + *******************************************************************************/ +package org.eclipse.ecf.internal.provider.vbulletin.internal; + +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.Map; + +import org.eclipse.ecf.bulletinboard.IBBObject; +import org.eclipse.ecf.core.identity.ID; +import org.eclipse.ecf.core.identity.IDCreateException; +import org.eclipse.ecf.core.identity.Namespace; +import org.eclipse.ecf.internal.bulletinboard.commons.IBBObjectFactory; +import org.eclipse.ecf.internal.provider.vbulletin.ThreadMessage; +import org.eclipse.ecf.internal.provider.vbulletin.identity.ThreadMessageID; +import org.eclipse.ecf.internal.provider.vbulletin.identity.VBNamespace; + +public class ThreadMessageFactory implements IBBObjectFactory { + public ID createBBObjectId(Namespace namespace, String stringValue) + throws IDCreateException { + try { + return new ThreadMessageID((VBNamespace) namespace, new URI( + stringValue)); + } catch (URISyntaxException e) { + throw new IDCreateException(e); + } + } + + public ID createBBObjectId(Namespace namespace, URL baseURL, String longValue) + throws IDCreateException { + try { + return new ThreadMessageID((VBNamespace) namespace, baseURL, + Long.parseLong(longValue)); + } catch (URISyntaxException e) { + throw new IDCreateException(e); + } + } + + public IBBObject createBBObject(ID id, String name, Map<String, Object> parameters) { + return new ThreadMessage((ThreadMessageID) id, name); + } +}
\ No newline at end of file diff --git a/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/internal/VBCookies.java b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/internal/VBCookies.java new file mode 100644 index 000000000..4532d3bbc --- /dev/null +++ b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/internal/VBCookies.java @@ -0,0 +1,50 @@ +/******************************************************************************* + * Copyright (c) 2005, 2006 Erkki Lindpere and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Erkki Lindpere - initial API and implementation + *******************************************************************************/ +package org.eclipse.ecf.internal.provider.vbulletin.internal; + +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Pattern; + +import org.apache.commons.httpclient.Cookie; + +public class VBCookies { + public static final String KEY_SESS_ID = "vbulletin.sessionid"; + + public static final String KEY_USER_ID = "vbulletin.userid"; + + /** + * Matches an MD5. + */ + private static final Pattern PAT_SESS_ID = Pattern + .compile("[0-9abcdef]{32}"); + + /** + * Matches a name. + */ + private static final Pattern PAT_USER_ID = Pattern + .compile("bbuserid"); + + public static Map<String, String> detectCookies(Cookie[] cookies) { + Map<String, String> detected = new HashMap<String, String>(); + for (Cookie cookie : cookies) { + if (PAT_SESS_ID.matcher(cookie.getValue()).matches()) { + // detected session id + detected.put(KEY_SESS_ID, cookie.getValue()); + } else if (PAT_USER_ID.matcher(cookie.getName()).matches()) { + // detected user id + detected.put(KEY_USER_ID, cookie.getValue()); + } + } + return detected; + } + +} diff --git a/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/internal/VBException.java b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/internal/VBException.java new file mode 100644 index 000000000..8806099c8 --- /dev/null +++ b/incubation/bundles/org.eclipse.ecf.provider.vbulletin/src/org/eclipse/ecf/internal/provider/vbulletin/internal/VBException.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2005, 2006 Erkki Lindpere and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Erkki Lindpere - initial API and implementation + *******************************************************************************/ +package org.eclipse.ecf.internal.provider.vbulletin.internal; + +/** + * This exception is set as the cause of a BBException when an exception message + * was parseable from the vBulletin HTML after a failed operation. + * + * @author Erkki + */ +public class VBException extends Throwable { + private static final long serialVersionUID = -839635876922896171L; + + public VBException(String message) { + super(message); + } +} |