Re: ☠ patch of doom



Hi,

Lots of fixes to make stuff work better.  I would write something more
informative except my laptop battery sucks and will die in 2 minutes.  

Chat sending is close to working again.  

Will likely commit this tomorrow, so be ready.

Index: .classpath
===================================================================
RCS file: /cvs/gnome/yarrr/.classpath,v
retrieving revision 1.5
diff -u -r1.5 .classpath
--- .classpath	24 Mar 2005 11:15:41 -0000	1.5
+++ .classpath	29 Mar 2005 01:14:53 -0000
@@ -8,5 +8,6 @@
 	<classpathentry sourcepath="ECLIPSE_HOME/plugins/org.eclipse.jdt.source_3.0.0/src/org.junit_3.8.1/junitsrc.zip" kind="var" path="JUNIT_HOME/junit.jar"/>
 	<classpathentry kind="lib" path="/usr/share/java/xerces-j2.jar"/>
 	<classpathentry kind="lib" path="lib/xmlrpc-1.2-utf8.jar"/>
+	<classpathentry kind="lib" path="/usr/share/java/log4j.jar"/>
 	<classpathentry kind="output" path="bin"/>
 </classpath>
Index: build.xml
===================================================================
RCS file: /cvs/gnome/yarrr/build.xml,v
retrieving revision 1.3
diff -u -r1.3 build.xml
--- build.xml	24 Mar 2005 11:15:41 -0000	1.3
+++ build.xml	29 Mar 2005 01:14:53 -0000
@@ -49,7 +49,7 @@
 	<target name="package-servlet" depends="init">
 		<war destfile="${build}${servlet.path}.war" webxml="web/servlet-info.xml">
 			<fileset dir="${web}" includes="**/*"/>
-			<fileset dir="${build}" includes="*properties"/>
+			<fileset dir="${src}/org/gnome/yarrr/" includes="log4j.properties"/>
 			
 			<lib dir="/usr/share/java">
 		    		<include name="xerces-j2.jar"/>
Index: src/com/keypoint/PngEncoderB.java
===================================================================
RCS file: /cvs/gnome/yarrr/src/com/keypoint/PngEncoderB.java,v
retrieving revision 1.1
diff -u -r1.1 PngEncoderB.java
--- src/com/keypoint/PngEncoderB.java	23 Mar 2005 05:56:00 -0000	1.1
+++ src/com/keypoint/PngEncoderB.java	29 Mar 2005 01:14:54 -0000
@@ -1,15 +1,11 @@
 package com.keypoint;
 
-import java.awt.Image;
 import java.awt.image.BufferedImage;
 import java.awt.image.DataBuffer;
 import java.awt.image.IndexColorModel;
-import java.awt.image.ImageObserver;
-import java.awt.image.PixelGrabber;
 import java.awt.image.WritableRaster;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
-import java.util.zip.CRC32;
 import java.util.zip.Deflater;
 import java.util.zip.DeflaterOutputStream;
 
@@ -161,7 +157,6 @@
         }
         width = image.getWidth( null );
         height = image.getHeight( null );
-        this.image = image;
 
         if (!establishStorageInfo())
         {
Index: src/org/gnome/yarrr/ActiveTopic.java
===================================================================
RCS file: /cvs/gnome/yarrr/src/org/gnome/yarrr/ActiveTopic.java,v
retrieving revision 1.6
diff -u -r1.6 ActiveTopic.java
--- src/org/gnome/yarrr/ActiveTopic.java	24 Mar 2005 20:15:29 -0000	1.6
+++ src/org/gnome/yarrr/ActiveTopic.java	29 Mar 2005 01:14:54 -0000
@@ -3,15 +3,13 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Iterator;
+import java.util.List;
 import java.util.Vector;
 
-import org.gnome.yarrr.xmlrpc.XmlRpcDemarshaller;
-import org.gnome.yarrr.xmlrpc.XmlRpcHandler;
-
 /*
  * Created on Mar 16, 2005
  */
-public class ActiveTopic implements XmlRpcDemarshaller {
+public class ActiveTopic extends ReferencableObject {
 	
 	private class WaitObject {
 		String name;
@@ -26,46 +24,43 @@
 	Topic topic;
 	Yarrr yarrr;
 	
-	ArrayList/*LiveComment*/ liveComments;
-	Chat thechat;
+	ArrayList /* ClosedComment */ closedComments;
+	ArrayList /* Discussion*/ discussions;
     Whiteboard theWhiteboard;
 	
 	ArrayList/*PollWaiter*/ waitObjects;
 	
-	public synchronized LiveComment openComment() {
-		LiveComment comment = new LiveComment(this);
-		liveComments.add(comment);
-		return comment;
-	}
-	
 	public ActiveTopic(Yarrr yarrr, Topic topic) {
 		this.yarrr = yarrr;
 		this.topic = topic;
-		liveComments = new ArrayList();
+		closedComments = new ArrayList();
+		discussions = new ArrayList();
 		waitObjects = new ArrayList();
-		
-		this.thechat = new Chat(this);
+
         this.theWhiteboard = new Whiteboard(this);
+        yarrr.getRegistry().register(this);
 	}
 	
-	public synchronized LiveComment getComment(int id) {
-		for (Iterator i = liveComments.iterator(); i.hasNext();) {
-			LiveComment comment = (LiveComment) i.next();
-			if (comment.getId() == id)
-				return comment;
-		}
-		return null;
+	public synchronized ClosedComment addClosedComment(String contents) {
+		ClosedComment comment = new ClosedComment(this, contents);
+		this.closedComments.add(comment);
+		return comment;
 	}
 	
-	public synchronized Chat getChat() {
-		return thechat;
+	public synchronized Discussion openDiscussion() {
+		Discussion d = new Discussion(this);
+		this.discussions.add(d);
+		return d;
 	}
-
+	
+	public synchronized List getDiscussions() {
+		return new Vector(this.discussions);
+	}
+	
     public synchronized Whiteboard getWhiteboard() {
         return theWhiteboard;
     }
 
-
 	private WaitObject findWaitObject(String name) {
 		for (Iterator i = waitObjects.iterator(); i.hasNext(); ) {
 			WaitObject obj = (WaitObject) i.next();
@@ -76,11 +71,12 @@
 		return null;
 	}
 	
-	public synchronized void signalChanged(String changed) {
+	public synchronized void signalChanged(ReferencableObject obj) {
 		ArrayList l = new ArrayList();
-		l.add(changed);
+		l.add(this.getRegistry().getReference(obj));
 		signalChanged(l);
 	}
+	
 	public synchronized void signalChanged(Collection changed) {
 		System.out.println("signalChanged: "+changed);
 		for (Iterator i = changed.iterator(); i.hasNext(); ) {
@@ -130,17 +126,21 @@
 		} while (changed.size() == 0);
 		return changed;
 	}
-	
-	static public Object xmlRpcDemarshal(Object xmlRpcObject, XmlRpcHandler handler) throws DemarshallingException 
-	{
-		try {
-			YarrrXmlRpcMethods methods = (YarrrXmlRpcMethods) handler;
-			Long id = new Long((String)xmlRpcObject);
-			return methods.getYarrr().lookupActiveTopic(id.longValue());
-		} catch (NumberFormatException e) {
-			throw new DemarshallingException(e);
-		}
+
+	public List getClosedComments() {
+		return closedComments;
 	}
-	static public Class xmlRpcMarshalledType = String.class;
 
+	public ReferencableObjectRegistry getRegistry() {
+		return this.yarrr.getRegistry();
+	}
+
+	/* We want to delegate to the topic for this */
+	public long getReferenceId() {
+		return this.topic.getReferenceId();
+	}
+
+	public void setReferenceId(long id) {
+		this.topic.setReferenceId(id);
+	}
 }
Index: src/org/gnome/yarrr/Chat.java
===================================================================
RCS file: /cvs/gnome/yarrr/src/org/gnome/yarrr/Chat.java,v
retrieving revision 1.4
diff -u -r1.4 Chat.java
--- src/org/gnome/yarrr/Chat.java	24 Mar 2005 20:15:29 -0000	1.4
+++ src/org/gnome/yarrr/Chat.java	29 Mar 2005 01:14:54 -0000
@@ -18,7 +18,7 @@
  * @author walters
  *
  */
-public class Chat {
+public class Chat extends ReferencableObject {
 	
 	static Log logger = LogFactory.getLog(Chat.class);
 	
@@ -74,14 +74,15 @@
 	
 	public Chat(ActiveTopic topic) {
 		this.topic = topic;
-		this.messages = new ArrayList();	
+		this.messages = new ArrayList();
+		this.topic.getRegistry().register(this);
 	}
 	
 	synchronized public void addMessage(String author, String contents) {
 		Message msg = new Message(author, contents);
 		this.messages.add(msg);
 		this.version++;
-		this.topic.signalChanged("chat");
+		this.topic.signalChanged(this);
 	}
 	
 	synchronized public int getVersion() {
Index: src/org/gnome/yarrr/LiveComment.java
===================================================================
RCS file: /cvs/gnome/yarrr/src/org/gnome/yarrr/LiveComment.java,v
retrieving revision 1.4
diff -u -r1.4 LiveComment.java
--- src/org/gnome/yarrr/LiveComment.java	24 Mar 2005 20:15:29 -0000	1.4
+++ src/org/gnome/yarrr/LiveComment.java	29 Mar 2005 01:14:54 -0000
@@ -8,7 +8,6 @@
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.Vector;
-import java.util.concurrent.atomic.AtomicInteger;
 
 import org.gnome.yarrr.xmlrpc.XmlRpcHandler;
 import org.gnome.yarrr.xmlrpc.XmlRpcMarshaller;
@@ -16,7 +15,7 @@
 /**
  * @author alex
  */
-public class LiveComment {
+public class LiveComment extends ReferencableObject {
 	private final int MAX_OLD_VERSIONS = 10;
 	
 	static class Content implements XmlRpcMarshaller {
@@ -35,13 +34,13 @@
 	static class EditingConflictException extends Exception {
 		private static final long serialVersionUID = 1L;
 	}
+	
 	static class TooOldVersionException extends Exception {
 		private static final long serialVersionUID = 1L;
 	}
 	
 	private ActiveTopic topic;
-	private static AtomicInteger idseq = new AtomicInteger(1);
-	private int id; // id of the live comment in the topic
+	private String closer;
 	private Date startTime;
 	private ArrayList authors; // List of names for now
 	private String contents;
@@ -65,11 +64,6 @@
 		return null;
 	}
 	
-	
-	public int getId() {
-		return id;
-	}
-	
 	/**
 	 * Gets the current text contents of the comment, and the
 	 * version of the content. 
@@ -94,6 +88,7 @@
 	 * @param basedOnVersion the version of the comment this change was based on
 	 * @return the new version number
 	 * @throws EditingConflictException if there is a conflict updating the text
+	 * @throws ClosedCommentException if comment has been closed
 	 */
 	synchronized public int updateContents(String author, StringDiff diff, int basedOnVersion) throws EditingConflictException {
 		String newContent = diff.applyTo(contents);
@@ -107,7 +102,7 @@
 			authors.add(author);
 		}
 		
-		topic.signalChanged("livecomment");
+		topic.signalChanged(this);
 		return version;
 	}
 	
@@ -129,11 +124,11 @@
 		contents = "";
 		version = 0;
 		authors = new ArrayList();
-		this.id = idseq.getAndAdd(1);
 	}
 	
 	public LiveComment(ActiveTopic topic) {
 		this();
 		this.topic = topic;
+		topic.getRegistry().register(this);
 	}
 }
Index: src/org/gnome/yarrr/Stroke.java
===================================================================
RCS file: /cvs/gnome/yarrr/src/org/gnome/yarrr/Stroke.java,v
retrieving revision 1.2
diff -u -r1.2 Stroke.java
--- src/org/gnome/yarrr/Stroke.java	23 Mar 2005 05:55:59 -0000	1.2
+++ src/org/gnome/yarrr/Stroke.java	29 Mar 2005 01:14:54 -0000
@@ -46,10 +46,9 @@
      * @see org.gnome.yarrr.xmlrpc.XmlRpcMarshaller#xmlRpcMarshal(org.gnome.yarrr.xmlrpc.XmlRpcHandler)
      */
     public Object xmlRpcMarshal(XmlRpcHandler handler) {
-        Object marshalledPoints = handler.recursivelyMarshal(points);
         Hashtable table = new Hashtable();
         table.put("id", id);
-        table.put("points", marshalledPoints);
+        table.put("points", points);
         return table;
     }
     
Index: src/org/gnome/yarrr/Topic.java
===================================================================
RCS file: /cvs/gnome/yarrr/src/org/gnome/yarrr/Topic.java,v
retrieving revision 1.2
diff -u -r1.2 Topic.java
--- src/org/gnome/yarrr/Topic.java	24 Mar 2005 20:15:29 -0000	1.2
+++ src/org/gnome/yarrr/Topic.java	29 Mar 2005 01:14:54 -0000
@@ -4,38 +4,18 @@
  */
 package org.gnome.yarrr;
 
-import java.util.Hashtable;
-import java.util.Map;
-import java.util.concurrent.atomic.AtomicLong;
 
 /**
  * Describes the persistant state of a topic.
  */
-public class Topic {
-	private Long id;
+public class Topic extends ReferencableObject {
 	private String name;
-	// Should be in database later
-	private static AtomicLong idseq = new AtomicLong(0);
-	private static Map topicMap = new Hashtable();
 	
 	public Topic(String name) {
 		this.name = name;
-		this.id = new Long(idseq.addAndGet(1));
-		topicMap.put(name, this);
-	}
-	
-	public long getId() {
-		return id.longValue();
 	}
 	
 	public String getName() {
 		return name;
-	}
-	public void setName(String name) {
-		this.name = name;
-	}
-
-	public static Topic lookupTopic(String name) {
-		return (Topic) topicMap.get(name);
 	}
 }
Index: src/org/gnome/yarrr/Whiteboard.java
===================================================================
RCS file: /cvs/gnome/yarrr/src/org/gnome/yarrr/Whiteboard.java,v
retrieving revision 1.2
diff -u -r1.2 Whiteboard.java
--- src/org/gnome/yarrr/Whiteboard.java	23 Mar 2005 05:55:59 -0000	1.2
+++ src/org/gnome/yarrr/Whiteboard.java	29 Mar 2005 01:14:54 -0000
@@ -26,12 +26,9 @@
  * @author dmalcolm
  * 
  */
-public class Whiteboard {
+public class Whiteboard extends ReferencableObject {
     /**
      * @author dmalcolm
-     *
-     * TODO To change the template for this generated type comment go to
-     * Window - Preferences - Java - Code Style - Code Templates
      */
     public class StrokeFetchResult implements XmlRpcMarshaller {
         List strokeIds;
@@ -65,12 +62,13 @@
     Whiteboard(ActiveTopic topic) {
         this.topic = topic;
         this.strokes = new ArrayList();
+        this.topic.getRegistry().register(this);
     }
     
     synchronized public int addStroke(Stroke stroke) {
         this.strokes.add(stroke);
         this.version++;
-        this.topic.signalChanged("whiteboard");
+        this.topic.signalChanged(this);
         return this.version;
     }
     
Index: src/org/gnome/yarrr/Yarrr.java
===================================================================
RCS file: /cvs/gnome/yarrr/src/org/gnome/yarrr/Yarrr.java,v
retrieving revision 1.4
diff -u -r1.4 Yarrr.java
--- src/org/gnome/yarrr/Yarrr.java	24 Mar 2005 20:15:29 -0000	1.4
+++ src/org/gnome/yarrr/Yarrr.java	29 Mar 2005 01:14:54 -0000
@@ -4,11 +4,13 @@
 package org.gnome.yarrr;
 
 import java.io.IOException;
+import java.net.URL;
 import java.util.HashMap;
 import java.util.Map;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.log4j.PropertyConfigurator;
 import org.apache.xmlrpc.XmlRpcHandler;
 import org.gnome.yarrr.xmlrpc.StandaloneXmlRpcServer;
 
@@ -19,31 +21,45 @@
 	static Log logger = LogFactory.getLog(XmlRpcHandler.class);
 
 	StandaloneXmlRpcServer rpcServer;
-	private Map /*Long,ActiveTopic*/ activeTopics;
+	private Map /*String,ActiveTopic*/ activeTopics;
+	
+	/* Should go away later when we have a DB */
+	private Map /*String,Topic */ topics;
+	
 	private XmlRpcHandler handler;
+	private ReferencableObjectRegistry registry;
 	
 	/**
 	 * This function is just used initially to test stuff a bit
 	 */
 	private void setupTestObjects() {
 		Topic testTopic = new Topic("Welcome to Yarrr");
+		this.topics.put(testTopic.getName(), testTopic);
 		
 		ActiveTopic active = activateTopic(testTopic);
+		active.addClosedComment("Yarrr rocks!  That's my comment.");
 		
-		LiveComment comment = active.openComment();
-		active.openComment();
-		
-		Chat chat = active.getChat();
+		Discussion discussion = active.openDiscussion();
+		discussion.openComment();
+		discussion.openComment();
 	}
 	
 	public Yarrr() {
 		activeTopics = new HashMap();
+		topics = new HashMap();
 		handler = new YarrrXmlRpcMethods(this);
+		registry = new ReferencableObjectRegistry();
+		
+		URL props = Yarrr.class.getResource("log4j.properties");
+		if (props == null)
+			throw new IllegalArgumentException("no properties found!");
+		PropertyConfigurator.configure(props);
+		
 		setupTestObjects();
 	}
 	
 	public synchronized Topic lookupTopic(String name) {
-		return Topic.lookupTopic(name);
+		return (Topic) this.topics.get(name);
 	}
 
 	/**
@@ -56,16 +72,16 @@
 	public synchronized ActiveTopic activateTopic(Topic topic) {
 		ActiveTopic activeTopic;
 		
-		activeTopic = lookupActiveTopic(topic.getId());
+		activeTopic = lookupActiveTopic(topic);
 		if (activeTopic == null) {
 			activeTopic = new ActiveTopic(this, topic);
-			activeTopics.put(new Long(topic.getId()), activeTopic);
+			activeTopics.put(topic, activeTopic);
 		}
 		return activeTopic;
 	}
 	
-	public synchronized ActiveTopic lookupActiveTopic(long id) {
-		return (ActiveTopic) activeTopics.get(new Long(id));
+	public synchronized ActiveTopic lookupActiveTopic(Topic topic) {
+		return (ActiveTopic) activeTopics.get(topic);
 	}
 	
 	public void stop() {
@@ -91,5 +107,9 @@
 		
 		logger.info("Yarrr shutting down.");
 		yarrr.stop();
+	}
+
+	public ReferencableObjectRegistry getRegistry() {
+		return this.registry;
 	}
 }
Index: src/org/gnome/yarrr/YarrrServlet.java
===================================================================
RCS file: /cvs/gnome/yarrr/src/org/gnome/yarrr/YarrrServlet.java,v
retrieving revision 1.3
diff -u -r1.3 YarrrServlet.java
--- src/org/gnome/yarrr/YarrrServlet.java	24 Mar 2005 20:15:29 -0000	1.3
+++ src/org/gnome/yarrr/YarrrServlet.java	29 Mar 2005 01:14:54 -0000
@@ -6,14 +6,11 @@
 import java.io.IOException;
 import java.io.OutputStream;
 import java.io.PrintWriter;
-import java.net.MalformedURLException;
-import java.net.URL;
 
 import javax.servlet.RequestDispatcher;
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletRequestWrapper;
 import javax.servlet.http.HttpServletResponse;
 
 import org.apache.xmlrpc.XmlRpcServer;
@@ -62,7 +59,8 @@
     public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
     	String path;
     	Topic topic;
-    	long topicid;
+    	ActiveTopic active;
+    	String topicref;
     	
     	path = request.getPathInfo();
     	if (path == null) {
@@ -78,12 +76,16 @@
     		handleUnknownTopic(request, response);
     		return;
     	}
-    	topicid = topic.getId();
+    	
+    	// TODO Implicitly active topic here; later we will want to be able
+    	// to get an overview of all topics
+    	active = yarrr.activateTopic(topic);
+    	
+    	topicref = yarrr.getRegistry().getReference(active);
     	
     	String fileParam = request.getParameter("file");
         if (fileParam != null && fileParam.equals("whiteboard.png")) {
-            ActiveTopic atopic = this.yarrr.lookupActiveTopic(topic.getId());
-            Whiteboard whiteboard = atopic.getWhiteboard();
+            Whiteboard whiteboard = active.getWhiteboard();
             String versionStr = request.getParameter("version");
             int version;
             if (versionStr!=null) {
@@ -94,7 +96,7 @@
             response.setContentType("image/png");
             whiteboard.getImage(version, response.getOutputStream());
         } else {
-        	RequestDispatcher dispatcher = getServletContext().getRequestDispatcher("/topic.jsp?topicname=" + topic.getName() + "&topicid=" + topicid);
+        	RequestDispatcher dispatcher = getServletContext().getRequestDispatcher("/topic.jsp?topicname=" + topic.getName() + "&topicid=" + topicref);
         	if (dispatcher == null)
         		super.doGet(request, response);
         	else {
Index: src/org/gnome/yarrr/YarrrXmlRpcMethods.java
===================================================================
RCS file: /cvs/gnome/yarrr/src/org/gnome/yarrr/YarrrXmlRpcMethods.java,v
retrieving revision 1.8
diff -u -r1.8 YarrrXmlRpcMethods.java
--- src/org/gnome/yarrr/YarrrXmlRpcMethods.java	24 Mar 2005 20:15:29 -0000	1.8
+++ src/org/gnome/yarrr/YarrrXmlRpcMethods.java	29 Mar 2005 01:14:54 -0000
@@ -3,6 +3,7 @@
  */
 package org.gnome.yarrr;
 
+import java.util.List;
 import java.util.Vector;
 
 import org.apache.commons.logging.Log;
@@ -16,17 +17,29 @@
 	static Log logger = LogFactory.getLog(Chat.class);
 	Yarrr yarrr;
 	
-	public LiveComment.Content getLiveComment(ActiveTopic topic, int commentId) {
-		
-		LiveComment comment = topic.getComment(commentId);
-		LiveComment.Content content = comment.getContents();
-		
-		return content;
+	public Vector /* Discussion */ getDiscussions (ActiveTopic topic) {
+		List discussions;
+		discussions = topic.getDiscussions();
+		return new Vector(discussions);
 	}
 	
-	public Vector getLiveCommentDiff(ActiveTopic topic, int commentId, int oldVersion) throws Exception {
-		LiveComment comment = topic.getComment(commentId);
-
+	public Chat getChat(Discussion discussion) {
+		return discussion.getChat();
+	}
+	
+	public Vector /* LiveComment */ getLiveComments(Discussion discussion) {
+		return new Vector(discussion.getComments()); 
+	}
+	
+	public Vector /* LiveComment */ getClosedComments(ActiveTopic topic) {
+		return new Vector(topic.getClosedComments());
+	}
+	
+	public String getClosedCommentContent(ClosedComment comment) {
+		return comment.getContent();
+	}
+	
+	public Vector getLiveCommentDiff(LiveComment comment, int oldVersion) throws Exception {
 		StringDiff diff;
 		int version;
 		
@@ -41,21 +54,20 @@
 		return res;
 	}
 	
-	public int updateLiveComment(ActiveTopic topic, int commentId, StringDiff diff, int version) throws Exception {
-		LiveComment comment = topic.getComment(commentId);
+	public int updateLiveComment(LiveComment comment, StringDiff diff, int version) throws Exception {
 		int newVersion = comment.updateContents("nobody", diff, version);
 		
 		return newVersion;
 	}
 	
-	public int addChatMessage(ActiveTopic topic, String author, String contents) {
-		Chat c = topic.getChat();
+	public int addChatMessage(Discussion discussion, String author, String contents) {
+		Chat c = discussion.getChat();
 		c.addMessage(author, contents);
 		return 0;
 	}
 	
-	public Chat.MessageFetchResult getMessagesSince(ActiveTopic topic, int version) {
-		Chat c = topic.getChat();
+	public Chat.MessageFetchResult getMessagesSince(Discussion discussion, int version) {
+		Chat c = discussion.getChat();
 		return c.getMessagesSince(version);
 	}
 	
Index: src/org/gnome/yarrr/xmlrpc/XmlRpcDemarshaller.java
===================================================================
RCS file: /cvs/gnome/yarrr/src/org/gnome/yarrr/xmlrpc/XmlRpcDemarshaller.java,v
retrieving revision 1.1
diff -u -r1.1 XmlRpcDemarshaller.java
--- src/org/gnome/yarrr/xmlrpc/XmlRpcDemarshaller.java	17 Mar 2005 14:24:13 -0000	1.1
+++ src/org/gnome/yarrr/xmlrpc/XmlRpcDemarshaller.java	29 Mar 2005 01:14:54 -0000
@@ -3,6 +3,8 @@
  */
 package org.gnome.yarrr.xmlrpc;
 
+import org.gnome.yarrr.ReferencableObjectRegistry.UnreferencedObjectException;
+
 /**
  * @author alex
  */
@@ -13,6 +15,9 @@
 			super(s);
 		}
 		public DemarshallingException(Exception e) {
+			super(e);
+		}
+		public DemarshallingException(UnreferencedObjectException e) {
 			super(e);
 		}
 	}
Index: src/org/gnome/yarrr/xmlrpc/XmlRpcHandler.java
===================================================================
RCS file: /cvs/gnome/yarrr/src/org/gnome/yarrr/xmlrpc/XmlRpcHandler.java,v
retrieving revision 1.9
diff -u -r1.9 XmlRpcHandler.java
--- src/org/gnome/yarrr/xmlrpc/XmlRpcHandler.java	24 Mar 2005 20:15:31 -0000	1.9
+++ src/org/gnome/yarrr/xmlrpc/XmlRpcHandler.java	29 Mar 2005 01:14:54 -0000
@@ -17,6 +17,7 @@
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.xmlrpc.XmlRpc;
+import org.gnome.yarrr.xmlrpc.XmlRpcMarshaller.MarshallingException;
 
 /**
  * @author alex
@@ -129,7 +130,7 @@
 		return out;
 	}
 	
-	public Object recursivelyMarshal(Object obj) {
+	public Object recursivelyMarshal(Object obj) throws MarshallingException {
 		if (obj instanceof XmlRpcMarshaller) {
 			obj = ((XmlRpcMarshaller) obj).xmlRpcMarshal(this);
 		}
@@ -200,6 +201,7 @@
 			}
 			
 			Object res = executeDemarshalled(methodName, params);
+			logger.info("method " + methodName + " returned: " + res);
 			return res;
 		} catch (Exception e) {
 			logger.warn(e);
Index: src/org/gnome/yarrr/xmlrpc/XmlRpcMarshaller.java
===================================================================
RCS file: /cvs/gnome/yarrr/src/org/gnome/yarrr/xmlrpc/XmlRpcMarshaller.java,v
retrieving revision 1.2
diff -u -r1.2 XmlRpcMarshaller.java
--- src/org/gnome/yarrr/xmlrpc/XmlRpcMarshaller.java	18 Mar 2005 17:04:10 -0000	1.2
+++ src/org/gnome/yarrr/xmlrpc/XmlRpcMarshaller.java	29 Mar 2005 01:14:54 -0000
@@ -7,10 +7,19 @@
  * @author alex
  */
 public interface XmlRpcMarshaller {
+	public static class MarshallingException extends Exception {
+		private static final long serialVersionUID = 1L;
+		public MarshallingException(String s) {
+			super(s);
+		}
+		public MarshallingException(Exception e) {
+			super(e);
+		}
+	}
 	/**
 	 * Marshal a custom object to its xmlrpc form
 	 * @param handler the xmlrpc handler
 	 * @return an object suitable to passing through xmlrpc
 	 */
-	public Object xmlRpcMarshal(XmlRpcHandler handler);
+	public Object xmlRpcMarshal(XmlRpcHandler handler) throws MarshallingException;
 }
Index: web/comment.js
===================================================================
RCS file: /cvs/gnome/yarrr/web/comment.js,v
retrieving revision 1.5
diff -u -r1.5 comment.js
--- web/comment.js	24 Mar 2005 15:52:13 -0000	1.5
+++ web/comment.js	29 Mar 2005 01:14:54 -0000
@@ -1,7 +1,6 @@
-function Comment(topicid, id, textarea) {
-  this.topicid = topicid;
+function Comment(id, containerid) {
   this.id = id;
-  this.textarea = textarea
+  this.containerid = containerid;
   this.edited_timeout = null;
 
   this.sending = false;
@@ -15,11 +14,17 @@
   this.old_text = "";
   this.old_version = undefined;
 
+  var containerelt = window.document.getElementById(containerid);
+  containerelt.innerHTML += "<div class=\"comment\" id=\"" + id + "\"><b>Open Comment</b><br/>";
+  containerelt.innerHTML += "<textarea class=\"commentarea\" wrap=\"virtual\" id=\"commentarea-" + id + "\"></textarea>";
+  containerelt.innerHTML += "</div>";
+  
+  this.textarea = window.document.getElementById("commentarea-" + id);
   var comment = this;
-  textarea.onkeydown = function() { comment.handleEdited(); };
-  textarea.onkeyup = function() { comment.handleEdited(); };
-  textarea.onmousedown = function() { comment.handleEdited(); };
-  textarea.onmouseup = function() { comment.handleEdited(); };
+  this.textarea.onkeydown = function() { comment.handleEdited(); };
+  this.textarea.onkeyup = function() { comment.handleEdited(); };
+  this.textarea.onmousedown = function() { comment.handleEdited(); };
+  this.textarea.onmouseup = function() { comment.handleEdited(); };
 }
 
 Comment.prototype.toString = function() { 
Index: web/topic.js
===================================================================
RCS file: /cvs/gnome/yarrr/web/topic.js,v
retrieving revision 1.14
diff -u -r1.14 topic.js
--- web/topic.js	24 Mar 2005 20:15:30 -0000	1.14
+++ web/topic.js	29 Mar 2005 01:14:54 -0000
@@ -1,7 +1,11 @@
 var errorLog = new ErrorLogger("Yarrr Debug Log", "errorLog");
 var xmlrpc = importModule("xmlrpc");
 var yarrr = new xmlrpc.ServerProxy("yarrr", 
-	["getLiveComment", 
+	["getDiscussions",
+	"getChat",
+	"getLiveComments", 
+	"getClosedComments",
+	"getClosedCommentContent",
 	"updateLiveComment", 
 	"getLiveCommentDiff", 
 	"pollForChanges", 
@@ -11,21 +15,30 @@
 	"getStrokeIdsSince"
 	]);
 
-function Chat(topicid) {
-  this.topicid = topicid;
-  this.windowId = "chatwindow";
-  this.authorEltId = "authorName";
-  this.chatTextId = "chatWindowInput";
+function Chat(id, containerid) {
+  this.id = id;
+  this.containerid = containerid;
   
   this.old_version = 0;
+  
+  var container = window.document.getElementById(containerid);
+  container.innerHTML += "<div><div class=\"chatwindow\" id=\"" + id + "\"></div><form name=\"chatform-" + id + "\" class=\"chatwindowinput\"><input type=\"text\" id=\"chatwindow-" + id + "\"/><input type=\"submit\" value=\"Send\"/><br/></form></div>";
+  
+  var form = window.document["chatform-" + id]
+  var chat = this;
+  form.onsubmit = function () { chat.send(); return false; };
+}
+
+Chat.prototype.sendCallback = function (result, err) {
+  chatText.value = "";
 }
 
 Chat.prototype.send = function () {
-  var chatText = window.document.getElementById(this.chatTextId);
-  var authorName = window.document.getElementById(this.authorEltId);
+  var chatText = window.document.getElementById("chatwindow-" + this.id);
+  var authorName = window.document.getElementById("authorName");
   errorLog.reportEvent("sending chat message: " + chatText.value);
-  yarrr.addChatMessage(this.topicid, authorName.value, chatText.value);
-  chatText.value = "";
+  var chat = this;
+  yarrr.addChatMessage(this.id, authorName.value, chatText.value, function (result, err) { chat.sendCallback (result,err); } );
 }
 
 Chat.prototype._formatDate = function(date) {
@@ -37,59 +50,140 @@
    return hours + ":" + minutes;
 }
 
-Chat.prototype.update = function () {
-   var chatComments = yarrr.getMessagesSince(this.topicid, this.old_version)
-   this.old_version = chatComments.version;
-   var messages = chatComments.messages;
+Chat.prototype.updateCallback = function (result, err) {
+  var chatComments = result;
+  this.old_version = chatComments.version;
+  var messages = chatComments.messages;
 
-   var chatWindow = window.document.getElementById(this.windowId);
-   errorLog.reportEvent("Chat.update: returned " + messages.length + " messages ");
+  var chatWindow = window.document.getElementById(this.id);
+  errorLog.reportEvent("Chat.update: returned " + messages.length + " messages ");
     
-   for (var i = 0; i < messages.length; i++) {
-     chatWindow.innerHTML += "<span class=\"chatdate\">" + this._formatDate(messages[i].date) + "</span> &nbsp; &nbsp; ";
-     chatWindow.innerHTML += "<span class=\"chatauthor\">" + messages[i].author + "</span> &nbsp; &nbsp; ";
-     chatWindow.innerHTML += "<span class=\"chatcontent\">" + messages[i].contents + "</span><br/>";
-   }
-   // FIXME: bad hack, should actually determine the height offset and scroll there...
-   // this will break when we get enough text :-)
-   chatWindow.scrollTop = 1000000;
+  for (var i = 0; i < messages.length; i++) {
+    chatWindow.innerHTML += "<span class=\"chatdate\">" + this._formatDate(messages[i].date) + "</span> &nbsp; &nbsp; ";
+    chatWindow.innerHTML += "<span class=\"chatauthor\">" + messages[i].author + "</span> &nbsp; &nbsp; ";
+    chatWindow.innerHTML += "<span class=\"chatcontent\">" + messages[i].contents + "</span><br/>";
+  }
+  // FIXME: bad hack, should actually determine the height offset and scroll there...
+  // this will break when we get enough text :-)
+  chatWindow.scrollTop = 1000000;
+}
+
+Chat.prototype.update = function (discussionid) {
+   var chat = this;
+   yarrr.getMessagesSince(this.id, this.old_version, function (result, err) { chat.updateCallback (result, err); } );
+}
+
+function Discussion(id) {
+  this.id = id;
+  this.livecomments = {};
+  this.chat = null;
+  var discussion = this;
+  
+  var discussions = window.document.getElementById("discussions");
+  discussions.innerHTML += "<div class=\"discussion\" id=\"" + this.id + "\">";
+  discussions.innerHTML += "  <div id=\"discussion-discussions-" + this.id + "\"></div>";
+  discussions.innerHTML += "  <div id=\"discussion-chat-" + this.id + "\"></div>";
+  discussions.innerHTML += "</div>";
+  
+  yarrr.getChat(id, function (result, err) { discussion.initChat(result, err); });
+  yarrr.getLiveComments(id, function (result, err) { discussion.initLiveComments(result, err); });
+}
+
+Discussion.prototype.initLiveComments = function (result, err) {
+  errorLog.reportEvent("Discussion.initLiveComments() returned" + result + ", " + err);
+  var comments = result;
+  for (var i = 0; i < comments.length; i++) {
+    this.livecomments[comments[i]] = new Comment(comments[i], "discussion-discussions-" + this.id);
+  }
+}
+
+Discussion.prototype.initChat = function(result, err) {
+  errorLog.reportEvent("Discussion.initChat() returned" + result + ", " + err);
+  this.chat = new Chat(result, "discussion-chat-" + this.id);
+}
+
+Discussion.prototype.update = function() {
+  for (comment in this.livecomments) {
+    comment.update();
+  }
+  for (comment in this.closedcomments) {
+    comment.update();
+  }
+  this.chat.update();
+}
+
+function ClosedComment(id, topicid) {
+  this.id = id;
+  this.topicid = topicid;
+ 
+  var topicelt = window.document.getElementById("closedcomments");
+  topicelt.innerHTML += "<div class=\"closedcomment\" id=\"" + id + "\"><b>Closed Comment</b><br/>";
+  topicelt.innerHTML += "</div>";
+  
+  var comment = this;
+  yarrr.getClosedCommentContent(id, function (result, err) { comment.getClosedCommentContentResult(result, err); });
 }
 
-function Topic(varref, id, whiteboardNodeId) {
-  this.varref = varref;
+ClosedComment.prototype.getClosedCommentContentResult = function (result, err) {
+  var content = result;
+  errorLog.reportEvent("getcontent returned" + result + ", " + err);
+  var contentelt = window.document.getElementById(this.id);
+  // FIXME HTML quoting
+  contentelt.innerHTML += content;
+}
+
+function Topic(id) {
   this.id = id;
-  this.comments = new Array();
+  this.closedcomments = {};
+  this.discussions = new Object();
   this.edited_timeout = null;
   
-  // Test initialization for now
-  var comment1 = new Comment(id, 1, window.document.myform.comment1);
-  var comment2 = new Comment(id, 2, window.document.myform.comment2);
-  this.comments[0] = comment1;
-  this.comments[1] = comment2;
-  this.chat = new Chat(id);
-  this.whiteboard = new Whiteboard(yarrr, whiteboardNodeId, id, 640, 480);
+  var topic = this;
+  yarrr.getClosedComments(id, function (result, err) { topic.initClosedComments(result, err); });
 }
 
 Topic.prototype.getId = function() {
   return this.id;
 }
 
-Topic.prototype.updateComments = function() {
-  for (var i = 0; i < this.comments.length; i++) {
-    this.comments[i].update();
+Topic.prototype.initClosedComments = function (result, err) {
+  errorLog.reportEvent("Topic.initClosedComments() returned" + result + ", " + err);
+  var comments = result;
+  for (var i = 0; i < comments.length; i++) {
+    this.closedcomments[comments[i]] = new ClosedComment(comments[i], this.id);
   }
 }
 
-Topic.prototype.updateChat = function() {
-  this.chat.update();
+Topic.prototype.getDiscussionsCallback = function (result, err) {
+  errorLog.reportEvent("getDiscussions returned " + result + ", err: " + err);
+  var currentDiscussions = result;
+  // Topics should probably be versioned, need getNewDiscussionsSince()
+  for (var i = 0; i < currentDiscussions.length; i++) {
+    var discussion = currentDiscussions[i];
+    if (this.discussions[discussion] == undefined) {
+      this.discussions[discussion] = new Discussion(discussion);
+    }
+  }
+  for (var discussion in this.discussions) {
+    /*
+    if (currentDiscussions[discussion] == undefined) {
+      // Should not happen for now
+      alert("Discussion " + discussion + " went away??");
+      // FIXME need to fix HTML in this case
+      delete this.discussions[discussion];
+    }
+    */
+    this.discussions[discussions].update();
+  }
 }
 
-Topic.prototype.updateWhiteboard = function() {
-  this.whiteboard.update();
+Topic.prototype.updateDiscussions = function() {
+  var topic = this;
+  yarrr.getDiscussions(this.id, function (result, err) { topic.getDiscussionsCallback(result, err); });
 }
 
-Topic.prototype.getChat = function() {
-  return this.chat;
+Topic.prototype.updateWhiteboard = function() {
+  this.whiteboard.update();
 }
 
 function setYarrrName() {
@@ -98,9 +192,8 @@
   errorLog.reportEvent("changed name to " + authorName.value);
 }
 
+/*
 function refresh(result, err) {
-  // enable poll immediately to avoid race condition
-  yarrr.pollForChanges(theTopic.getId(), ["livecomment", "chat", "whiteboard"], refresh);
   for (var i = 0; i < result.length; i++) {
     var event = result[i];
     errorLog.reportEvent("refresh event \"" + event + "\"");
@@ -115,10 +208,12 @@
 	  theTopic.updateWhiteboard();
     }
   }
+  yarrr.pollForChanges(theTopic.getId(), ["livecomment", "chat", "whiteboard"], refresh);
 }
+*/
 
 function init() {
-  theTopic = new Topic("theTopic", topicid, "whiteboardCanvas");
+  theTopic = new Topic(topicid);
   
   errorLog.reportEvent("init");
   
@@ -129,7 +224,9 @@
   } else {
     authorName.value = "anonymous";
   }
-
-  refresh(["livecomment", "chat", "whiteboard"], null)
   
-}
+  theTopic.updateDiscussions();
+  /*
+  refresh([topicid], null)
+  */
+}
\ No newline at end of file
Index: web/topic.jsp
===================================================================
RCS file: /cvs/gnome/yarrr/web/topic.jsp,v
retrieving revision 1.1
diff -u -r1.1 topic.jsp
--- web/topic.jsp	24 Mar 2005 20:15:30 -0000	1.1
+++ web/topic.jsp	29 Mar 2005 01:14:54 -0000
@@ -21,7 +21,7 @@
 <script type="text/javascript" src="../whiteboard.js"></script>
 
 <script type="text/javascript">
-  topicid = "" + <%= request.getParameter("topicid") %>;
+  topicid = "<%= request.getParameter("topicid") %>";
 </script>
 
 <div id="whiteboardCanvas"></div>
@@ -39,25 +39,16 @@
   </div>
 </div>
 <div id="topiccontents">
-
-  <b>Edit this text:</b><br/>
-  <form name="myform">
-    <textarea class="chatsummary" wrap="virtual" name="comment1"></textarea>
-    <textarea class="chatsummary" wrap="virtual" name="comment2"></textarea>
-  </form>
-
-  <div id="chatwindow">
-    <form name="addchatmessage" onsubmit="theTopic.getChat().send(); return false;">
-      <input type="text" id="chatWindowInput" />
-      <input type="submit" value="Send"/>
-      <br/>
+  <h3>Comments</h3>
+  <div id="closedcomments"></div>
+  <hr/>
+  <h3>Discussions</h3>
+  <div id="discussions"></div>
+  <div id="opencomment">
+    <form>
+      <input type="button" value="Open Comment" onclick="newLiveComment();"/>
     </form>
   </div>
-  
-  <div id="whiteboard">
-	<b>Whiteboard</b><br/>
-	<p>You can sketch here:</p>	
-   </div>  
 </div>
 </body>
 </html>
Index: web/jsolait/lib/urllib.js
===================================================================
RCS file: /cvs/gnome/yarrr/web/jsolait/lib/urllib.js,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 urllib.js
--- web/jsolait/lib/urllib.js	17 Mar 2005 09:34:41 -0000	1.1.1.1
+++ web/jsolait/lib/urllib.js	29 Mar 2005 01:14:54 -0000
@@ -253,7 +253,7 @@
                             xmlhttp = null;
                         }
                     }catch(e){
-                        
+                       alert(e) 
                     }
                 }
             }
Index: web/stylesheets/chat.css
===================================================================
RCS file: /cvs/gnome/yarrr/web/stylesheets/chat.css,v
retrieving revision 1.3
diff -u -r1.3 chat.css
--- web/stylesheets/chat.css	18 Mar 2005 09:18:23 -0000	1.3
+++ web/stylesheets/chat.css	29 Mar 2005 01:14:54 -0000
@@ -1,17 +1,17 @@
 
-.chatsummary {
+.comment {
 	width: 80%;
 	height: 150px;
 }
 
-#chatwindow {
+.chatwindow {
 	overflow: auto;
 	height: 300px;
 	width: 80%;
 	border: 1px solid #f0f0f0;
 }
 
-#chatWindowInput {
+.chatwindowinput {
 	width: 80%;
 	float: left;
 }
Index: bin/.cvsignore
===================================================================
RCS file: bin/.cvsignore
diff -N bin/.cvsignore
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ bin/.cvsignore	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,1 @@
+yarrr.war
Index: src/org/gnome/yarrr/ClosedComment.java
===================================================================
RCS file: src/org/gnome/yarrr/ClosedComment.java
diff -N src/org/gnome/yarrr/ClosedComment.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/org/gnome/yarrr/ClosedComment.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,47 @@
+/*
+ * Created on Mar 28, 2005
+ */
+package org.gnome.yarrr;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * @author walters
+ */
+public class ClosedComment extends ReferencableObject {
+	ActiveTopic topic;
+	private int version;
+	String content;
+	Set /* String */ proponents;
+	
+	public ClosedComment(ActiveTopic topic, String content) {
+		this.topic = topic;
+		this.content = content;
+		this.proponents = new HashSet();
+		topic.getRegistry().register(this);
+	}
+	
+	public String getContent() {
+		return content;
+	}
+	
+	/* TODO Proponent should be a Person object */
+	public synchronized int addProponent(String proponent) {
+		if (this.proponents.contains(proponent))
+			throw new IllegalArgumentException("Proponent already added: " + proponent);
+		this.proponents.add(proponent);
+		this.version++;
+		topic.signalChanged(this);
+		return this.version;
+	}
+	
+	public int getVersion() {
+		return this.version;
+	}
+	
+	public synchronized Set getProponents() {
+		return new HashSet(proponents);
+	}
+}
+
Index: src/org/gnome/yarrr/Discussion.java
===================================================================
RCS file: src/org/gnome/yarrr/Discussion.java
diff -N src/org/gnome/yarrr/Discussion.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/org/gnome/yarrr/Discussion.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,44 @@
+/*
+ * Created on Mar 24, 2005
+ */
+package org.gnome.yarrr;
+
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+import java.util.Vector;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * @author walters
+ */
+public class Discussion extends ReferencableObject {
+
+	static Log logger = LogFactory.getLog(Discussion.class);
+	private static Map topicMap = new Hashtable();
+	
+	private ActiveTopic topic;
+	private List /* LiveComment */ comments;
+	private Chat chat;
+	
+	public Discussion(ActiveTopic topic) {
+		this.topic = topic;
+		this.comments = new Vector();
+		this.chat = new Chat(this.topic);
+		topic.getRegistry().register(this);
+	}
+	
+	public synchronized void openComment() {
+		this.comments.add(new LiveComment(this.topic));
+	}
+	
+	public synchronized List /* LiveComment */ getComments() {
+		return new Vector(comments);
+	}
+	
+	public Chat getChat() {
+		return this.chat;
+	}
+}
Index: src/org/gnome/yarrr/ReferencableObject.java
===================================================================
RCS file: src/org/gnome/yarrr/ReferencableObject.java
diff -N src/org/gnome/yarrr/ReferencableObject.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/org/gnome/yarrr/ReferencableObject.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,50 @@
+/*
+ * Created on Mar 24, 2005
+ */
+package org.gnome.yarrr;
+
+import org.gnome.yarrr.ReferencableObjectRegistry.UnreferencedObjectException;
+import org.gnome.yarrr.xmlrpc.XmlRpcDemarshaller;
+import org.gnome.yarrr.xmlrpc.XmlRpcHandler;
+import org.gnome.yarrr.xmlrpc.XmlRpcMarshaller;
+
+/**
+ * @author walters
+ */
+public abstract class ReferencableObject implements XmlRpcDemarshaller, XmlRpcMarshaller {
+
+	protected long referenceId;
+
+	public long getReferenceId() {
+		return this.referenceId;
+	}
+
+	public void setReferenceId(long id) {
+		this.referenceId = id;
+	}
+
+	static public Object xmlRpcDemarshal(Object xmlRpcObject, XmlRpcHandler handler) throws DemarshallingException {
+		try {
+			YarrrXmlRpcMethods methods = (YarrrXmlRpcMethods) handler;
+			String objref = (String) xmlRpcObject;
+			Object ret = methods.getYarrr().getRegistry().lookup(objref);
+			if (ret == null)
+				throw new DemarshallingException("Unreferenced object "
+						+ objref);
+			return ret;
+		} catch (UnreferencedObjectException e) {
+			throw new XmlRpcDemarshaller.DemarshallingException(e);
+		}
+	}
+
+	static public Class xmlRpcMarshalledType = String.class;
+
+	public Object xmlRpcMarshal(XmlRpcHandler handler) throws MarshallingException {
+		YarrrXmlRpcMethods methods = (YarrrXmlRpcMethods) handler;
+		try {
+			return methods.getYarrr().getRegistry().getReference(this);
+		} catch (UnreferencedObjectException e) {
+			throw new XmlRpcMarshaller.MarshallingException(e);
+		}
+	}
+}
Index: src/org/gnome/yarrr/ReferencableObjectRegistry.java
===================================================================
RCS file: src/org/gnome/yarrr/ReferencableObjectRegistry.java
diff -N src/org/gnome/yarrr/ReferencableObjectRegistry.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/org/gnome/yarrr/ReferencableObjectRegistry.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,73 @@
+/*
+ * Created on Mar 24, 2005
+ */
+package org.gnome.yarrr;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * @author walters
+ */
+public class ReferencableObjectRegistry {
+	
+	static Log logger = LogFactory.getLog(ReferencableObjectRegistry.class);
+	/**
+	 * @author walters
+	 */
+	public class UnreferencedObjectException extends RuntimeException {
+		private static final long serialVersionUID = 1L;
+
+		public UnreferencedObjectException() {
+		}
+
+		public UnreferencedObjectException(Throwable e) {
+			super(e);
+		}
+
+		public UnreferencedObjectException(String string) {
+			super(string);
+		}
+	}
+
+	private Map /* Long,Object */objectRegistry;
+
+	AtomicLong idseq;
+
+	public ReferencableObjectRegistry() {
+		this.objectRegistry = new HashMap();
+		idseq = new AtomicLong();
+	}
+
+	public void register(ReferencableObject obj) {
+		long newid = idseq.addAndGet(1);
+		obj.setReferenceId(newid);
+		logger.info("Registering object " + getReference(obj));
+		objectRegistry.put(new Long(newid), obj);
+	}
+
+	public String getReference(ReferencableObject obj) throws UnreferencedObjectException {
+		long id = obj.getReferenceId();
+		if (id == 0)
+			throw new UnreferencedObjectException("Unregistered object " + obj);
+		return obj.getClass().toString() + "/" + obj.getReferenceId();
+	}
+
+	public Object lookup(String reference) throws UnreferencedObjectException {
+		int index;
+
+		logger.debug("Looking up object " + reference);
+
+		try {
+			index = reference.indexOf('/');
+			long id = Long.parseLong(reference.substring(index + 1));
+			return this.objectRegistry.get(new Long(id));
+		} catch (IndexOutOfBoundsException e) {
+			throw new UnreferencedObjectException(e);
+		}
+	}
+}
Index: src/org/gnome/yarrr/log4j.properties
===================================================================
RCS file: src/org/gnome/yarrr/log4j.properties
diff -N src/org/gnome/yarrr/log4j.properties
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/org/gnome/yarrr/log4j.properties	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,9 @@
+### direct log messages to stdout ###
+log4j.appender.yarrr=org.apache.log4j.ConsoleAppender
+log4j.appender.yarrr.Target=System.out
+log4j.appender.yarrr.layout=org.apache.log4j.PatternLayout
+log4j.appender.yarrr.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
+
+log4j.logger.org.gnome.yarrr=info, yarrr
+log4j.logger.org.gnome.yarrr.xmlrpc.YarrrXmlRpcMethods=info, yarrr
+ 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]