CVS: beepcore-java/src/org/beepcore/beep/core ProfileRegistry.java,1.14,1.15 ChannelImpl.java,1.11,1.12 TuningProfile.java,1.13,1.14 MessageMSG.java,1.10,1.11 PiggybackedMSG.java,1.3,1.4 SessionImpl.java,1.16,1.17 StartChannelProfile.java,1.2,1.3 BEEPError.java,1.9,1.10 MessageMSGImpl.java,1.1,1.2

Huston Franklin <[email protected]> Sat, 25 Feb 2006 09:48:39 -0800
Newsgroups gmane.network.beep.beepcore.java.cvs
Message-ID <[email protected]>
Update of /cvsroot/beepcore-java/beepcore-java/src/org/beepcore/beep/core
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6616/src/org/beepcore/beep/core

Modified Files:
	ProfileRegistry.java ChannelImpl.java TuningProfile.java 
	MessageMSG.java PiggybackedMSG.java SessionImpl.java 
	StartChannelProfile.java BEEPError.java MessageMSGImpl.java 
Log Message:
Refactored parsing into a separate package

Index: ProfileRegistry.java
===================================================================
RCS file: /cvsroot/beepcore-java/beepcore-java/src/org/beepcore/beep/core/ProfileRegistry.java,v
retrieving revision 1.14
retrieving revision 1.15
diff -C2 -r1.14 -r1.15
*** ProfileRegistry.java	7 Nov 2003 17:38:11 -0000	1.14
--- ProfileRegistry.java	25 Feb 2006 17:48:36 -0000	1.15
***************
*** 3,7 ****
   *
   * Copyright (c) 2001 Invisible Worlds, Inc.  All rights reserved.
!  * Copyright (c) 2001,2002 Huston Franklin.  All rights reserved.
   *
   * The contents of this file are subject to the Blocks Public License (the
--- 3,7 ----
   *
   * Copyright (c) 2001 Invisible Worlds, Inc.  All rights reserved.
!  * Copyright (c) 2001,2002,2004 Huston Franklin.  All rights reserved.
   *
   * The contents of this file are subject to the Blocks Public License (the
***************
*** 22,27 ****
--- 22,31 ----
  import org.apache.commons.logging.LogFactory;
  
+ import java.util.Collection;
  import java.util.Enumeration;
  import java.util.Hashtable;
+ import java.util.Iterator;
+ import java.util.LinkedList;
+ import java.util.Set;
  
  import org.beepcore.beep.util.StringUtil;
***************
*** 213,302 ****
          return this.localize;
      }
! 
!     byte[] getGreeting(Session session) {
!         return getGreeting(session, null);
!     }
! 
!     byte[] getGreeting(Session session, String features)
      {
!         int bufferSize = "<greeting></greeting>".length();
!         int profileCount = 0;
! 
!         profileCount = profileListeners.size();
! 
!         Enumeration e = profileListeners.keys();
! 
!         while (e.hasMoreElements()) {
!             bufferSize += ((String) e.nextElement()).length()
!                 + "<profile>".length();
!         }
! 
!         bufferSize++;
! 
!         StringBuffer sb = new StringBuffer(bufferSize);
! 
!         // Create Greeting
!         // Wish I could reset these.
!         Enumeration f = profileListeners.keys();
! 
!         sb.append("<greeting");
! 
!         if ((localize != null)
!                 &&!localize.equals(Constants.LOCALIZE_DEFAULT)) {
!             sb.append(" localize='");
!             sb.append(localize);
!             sb.append('\'');
!         }
! 
!         if (features != null) {
!             sb.append(" features='");
!             sb.append(features);
!             sb.append('\'');
!         }
! 
!         sb.append('>');
! 
!         while (f.hasMoreElements()) {
! 
!             // make sure this profile wants to be advertised
!             try {
!                 String profileName = (String) f.nextElement();
!                 InternalProfile profile =
!                     (InternalProfile) profileListeners.get(profileName);
!                 boolean callAdvertise = false;
!                 SessionTuningProperties sessionTuning =
!                     session.getTuningProperties();
! 
!                 // check the standard tuning settings first
!                 for (int i = 0;
!                         i < SessionTuningProperties.STANDARD_PROPERTIES.length;
!                         i++) {
! 
!                     if ((profile.tuning != null) && (sessionTuning != null) &&
!                         (profile.tuning.getProperty(SessionTuningProperties.STANDARD_PROPERTIES[i]) != null) &&
!                         (sessionTuning.getProperty(SessionTuningProperties.STANDARD_PROPERTIES[i]) != null))
!                     {
!                         callAdvertise = true;
!                     }
                  }
  
                  if ((profile.tuning == null) ||
                      (callAdvertise &&
                       profile.listener.advertiseProfile(session)))
                  {
!                     sb.append("<profile uri='");
!                     sb.append(profileName);
!                     sb.append("' />");
                  }
!             } catch (BEEPException x) {
!                 x.printStackTrace();
! 
                  continue;
              }
          }
! 
!         sb.append("</greeting>");
! 
!         return StringUtil.stringBufferToAscii(sb);
      }
  }
--- 217,262 ----
          return this.localize;
      }
!     
!     public Collection getAdvertisedProfiles(Session session)
      {
!         LinkedList advertise = new LinkedList();
!         
!         SessionTuningProperties sessionTuning =
!             session.getTuningProperties();
! 
!         Set profiles = profileListeners.keySet();
! 
!         for (Iterator p = profileListeners.keySet().iterator(); p.hasNext();) {
!             String profileUri = (String) p.next();
!             InternalProfile profile =
!                 (InternalProfile) profileListeners.get(profileUri);
!             boolean callAdvertise = false;
! 
!             // check the standard tuning settings first
!             for (int i = 0;
!                     i < SessionTuningProperties.STANDARD_PROPERTIES.length;
!                     i++) {
! 
!                 if ((profile.tuning != null) && (sessionTuning != null) &&
!                     (profile.tuning.getProperty(SessionTuningProperties.STANDARD_PROPERTIES[i]) != null) &&
!                     (sessionTuning.getProperty(SessionTuningProperties.STANDARD_PROPERTIES[i]) != null))
!                 {
!                     callAdvertise = true;
                  }
+             }
  
+             try {
                  if ((profile.tuning == null) ||
                      (callAdvertise &&
                       profile.listener.advertiseProfile(session)))
                  {
!                     advertise.add(profileUri);
                  }
!             } catch (BEEPException e) {
                  continue;
              }
          }
!         
!         return advertise;
      }
  }

Index: ChannelImpl.java
===================================================================
RCS file: /cvsroot/beepcore-java/beepcore-java/src/org/beepcore/beep/core/ChannelImpl.java,v
retrieving revision 1.11
retrieving revision 1.12
diff -C2 -r1.11 -r1.12
*** ChannelImpl.java	1 Jan 2004 19:12:51 -0000	1.11
--- ChannelImpl.java	25 Feb 2006 17:48:37 -0000	1.12
***************
*** 94,98 ****
  
      /** session this channel sends through. */
!     private SessionImpl session;
  
      /** message that we are receiving frames */
--- 94,98 ----
  
      /** session this channel sends through. */
!     SessionImpl session;
  
      /** message that we are receiving frames */

Index: TuningProfile.java
===================================================================
RCS file: /cvsroot/beepcore-java/beepcore-java/src/org/beepcore/beep/core/TuningProfile.java,v
retrieving revision 1.13
retrieving revision 1.14
diff -C2 -r1.13 -r1.14
*** TuningProfile.java	1 Jan 2004 19:12:51 -0000	1.13
--- TuningProfile.java	25 Feb 2006 17:48:37 -0000	1.14
***************
*** 24,27 ****
--- 24,28 ----
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
+ import org.beepcore.beep.core.serialize.ErrorElement;
  
  /**
***************
*** 113,122 ****
              // If we're here, the profile didn't succesfully send, so
              // send an error
!             BEEPError error = new BEEPError(451,
!                                             "UnknownError" + x.getMessage());
  
!             session.sendProfile(profile, error.createErrorMessage(),
                                  (ChannelImpl)channel);
!             abort(error, channel);
          }
      }
--- 114,126 ----
              // If we're here, the profile didn't succesfully send, so
              // send an error
!             ErrorElement error =
!                 new ErrorElement(451, "UnknownError " + x.getMessage());
!             String errorString =
!                 ((ChannelImpl)channel).session.parser.createErrorMessage(error);
  
!             session.sendProfile(profile, errorString,
                                  (ChannelImpl)channel);
!             abort(new BEEPError(error.getCode(), error.getDiagnostic(), error.getXmlLang()),
!                   channel);
          }
      }

Index: MessageMSG.java
===================================================================
RCS file: /cvsroot/beepcore-java/beepcore-java/src/org/beepcore/beep/core/MessageMSG.java,v
retrieving revision 1.10
retrieving revision 1.11
diff -C2 -r1.10 -r1.11
*** MessageMSG.java	3 Jun 2003 16:38:35 -0000	1.10
--- MessageMSG.java	25 Feb 2006 17:48:37 -0000	1.11
***************
*** 2,6 ****
   * MessageMSG.java  $Revision$ $Date$
   *
!  * Copyright (c) 2003 Huston Franklin.  All rights reserved.
   *
   * The contents of this file are subject to the Blocks Public License (the
--- 2,6 ----
   * MessageMSG.java  $Revision$ $Date$
   *
!  * Copyright (c) 2003-2004 Huston Franklin.  All rights reserved.
   *
   * The contents of this file are subject to the Blocks Public License (the
***************
*** 74,77 ****
--- 74,87 ----
  
      /**
+      * Sends an ERR reply to this MSG message.
+      *
+      * @param stream Payload to be sent.
+      *
+      * @see OutputDataStream
+      * @see MessageStatus
+      */
+     public MessageStatus sendERR(OutputDataStream stream) throws BEEPException;
+ 
+     /**
       * Sends a reply of type NUL to this MSG message. This is sent as the
       * completion to a MSG/ANS/NUL message exchange.

Index: PiggybackedMSG.java
===================================================================
RCS file: /cvsroot/beepcore-java/beepcore-java/src/org/beepcore/beep/core/PiggybackedMSG.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -r1.3 -r1.4
*** PiggybackedMSG.java	31 Dec 2003 17:46:28 -0000	1.3
--- PiggybackedMSG.java	25 Feb 2006 17:48:37 -0000	1.4
***************
*** 2,6 ****
   * RequestHandler.java  $Revision$ $Date$
   *
!  * Copyright (c) 2003 Huston Franklin.  All rights reserved.
   *
   * The contents of this file are subject to the Blocks Public License (the
--- 2,6 ----
   * RequestHandler.java  $Revision$ $Date$
   *
!  * Copyright (c) 2003-2004 Huston Franklin.  All rights reserved.
   *
   * The contents of this file are subject to the Blocks Public License (the
***************
*** 30,33 ****
--- 30,35 ----
  class PiggybackedMSG extends MessageMSGImpl implements MessageMSG {
  
+     private static final int MAX_PCDATA_SIZE = 4096;
+     
      PiggybackedMSG(ChannelImpl channel, byte[] data, boolean base64encoding)
      {
***************
*** 74,82 ****
          SessionImpl s = (SessionImpl)this.channel.getSession();
          ByteArrayOutputStream tmp =
!             new ByteArrayOutputStream(SessionImpl.MAX_PCDATA_SIZE);
          String data;
  
          while (stream.availableSegment()) {
!             BufferSegment b = stream.getNextSegment(SessionImpl.MAX_PCDATA_SIZE);
  
              tmp.write(b.getData(), 0, b.getLength());
--- 76,84 ----
          SessionImpl s = (SessionImpl)this.channel.getSession();
          ByteArrayOutputStream tmp =
!             new ByteArrayOutputStream(MAX_PCDATA_SIZE);
          String data;
  
          while (stream.availableSegment()) {
!             BufferSegment b = stream.getNextSegment(MAX_PCDATA_SIZE);
  
              tmp.write(b.getData(), 0, b.getLength());

Index: SessionImpl.java
===================================================================
RCS file: /cvsroot/beepcore-java/beepcore-java/src/org/beepcore/beep/core/SessionImpl.java,v
retrieving revision 1.16
retrieving revision 1.17
diff -C2 -r1.16 -r1.17
*** SessionImpl.java	1 Jan 2004 19:12:51 -0000	1.16
--- SessionImpl.java	25 Feb 2006 17:48:37 -0000	1.17
***************
*** 3,7 ****
   *
   * Copyright (c) 2001 Invisible Worlds, Inc.  All rights reserved.
!  * Copyright (c) 2001-2003 Huston Franklin.  All rights reserved.
   * Copyright (c) 2002 Kevin Kress.  All rights reserved.
   *
--- 3,7 ----
   *
   * Copyright (c) 2001 Invisible Worlds, Inc.  All rights reserved.
!  * Copyright (c) 2001-2004 Huston Franklin.  All rights reserved.
   * Copyright (c) 2002 Kevin Kress.  All rights reserved.
   *
***************
*** 30,42 ****
  import java.util.List;
  
- import javax.xml.parsers.*;
- 
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  
- import org.w3c.dom.*;
- 
- import org.xml.sax.SAXException;
- 
  import sun.misc.BASE64Decoder;
  
--- 30,36 ----
***************
*** 46,49 ****
--- 40,46 ----
  import org.beepcore.beep.core.event.SessionResetEvent;
  import org.beepcore.beep.core.event.SessionListener;
+ 
+ import org.beepcore.beep.core.serialize.*;
+ 
  import org.beepcore.beep.util.StringUtil;
  
***************
*** 89,93 ****
  
      /** @todo check this */
-     static final int MAX_PCDATA_SIZE = 4096;
      private static final int MAX_START_CHANNEL_WAIT = 60000;
      private static final int MAX_START_CHANNEL_INTERVAL = 100;
--- 86,89 ----
***************
*** 104,107 ****
--- 100,105 ----
      // Instance Data
      private Log log = LogFactory.getLog(this.getClass());
+     
+     ChannelZeroParser parser = new ChannelZeroParser();
  
      private int state;
***************
*** 122,126 ****
      private boolean overflow;
      private boolean allowChannelWindowUpdates;
-     private DocumentBuilder builder;    // generic XML parser
      private String serverName;
      private boolean sentServerName = false;
--- 120,123 ----
***************
*** 157,166 ****
          this.serverName = serverName;
  
-         try {
-             builder =
-                 DocumentBuilderFactory.newInstance().newDocumentBuilder();
-         } catch (ParserConfigurationException e) {
-             throw new BEEPException("Invalid parser configuration");
-         }
      }
  
--- 154,157 ----
***************
*** 473,512 ****
          String channelNumber = getNextFreeChannelNumber();
  
!         // create the message in a buffer and send it
!         StringBuffer startBuffer = new StringBuffer();
! 
!         startBuffer.append("<start number='");
!         startBuffer.append(channelNumber);
!         if (serverName != null && !sentServerName) {
!             startBuffer.append("' serverName='");
!             startBuffer.append(serverName);
!         }
!         startBuffer.append("'>");
! 
!         Iterator i = profiles.iterator();
! 
!         while (i.hasNext()) {
!             StartChannelProfile p = (StartChannelProfile) i.next();
! 
!             // @todo maybe we should check these against peerSupportedProfiles
!             startBuffer.append("<profile uri='");
!             startBuffer.append(p.uri);
!             startBuffer.append("' ");
! 
!             if (p.data == null) {
!                 startBuffer.append(" />");
!             } else {
!                 if (p.base64Encoding) {
!                     startBuffer.append("encoding='base64' ");
!                 }
! 
!                 startBuffer.append("><![CDATA[");
!                 startBuffer.append(p.data);
!                 startBuffer.append("]]></profile>");
!             }
          }
! 
!         startBuffer.append("</start>");
! 
          // @todo handle the data element
          // Create a channel
--- 464,476 ----
          String channelNumber = getNextFreeChannelNumber();
  
!         StartElement start;
!         
!         if (sentServerName) {
!             start = new StartElement(Integer.parseInt(channelNumber), profiles);
!         } else {
!             start = new StartElement(Integer.parseInt(channelNumber),
!                                      serverName, profiles);
          }
!         
          // @todo handle the data element
          // Create a channel
***************
*** 517,521 ****
          OutputDataStream ds =
              new ByteOutputDataStream(MimeHeaders.BEEP_XML_CONTENT_TYPE,
!                                      StringUtil.stringBufferToAscii(startBuffer));
  
          if (tuning) {
--- 481,485 ----
          OutputDataStream ds =
              new ByteOutputDataStream(MimeHeaders.BEEP_XML_CONTENT_TYPE,
!                                      parser.serializeStart(start));
  
          if (tuning) {
***************
*** 898,919 ****
              throws BEEPException
      {
! 
!         // Send the profile
!         StringBuffer sb = new StringBuffer();
! 
!         sb.append("<profile uri='");
!         sb.append(uri);
! 
!         if (datum != null) {
!             sb.append("'><![CDATA[");
!             sb.append(datum);
!             sb.append("]]></profile>");
!         } else {
!             sb.append("' />");
!         }
  
          OutputDataStream ds =
              new ByteOutputDataStream(MimeHeaders.BEEP_XML_CONTENT_TYPE,
!                                      StringUtil.stringBufferToAscii(sb));
  
          // Store the Channel
--- 862,870 ----
              throws BEEPException
      {
!         ProfileElement p = new ProfileElement(uri, false, datum);
  
          OutputDataStream ds =
              new ByteOutputDataStream(MimeHeaders.BEEP_XML_CONTENT_TYPE,
!                                      parser.serializeProfile(p));
  
          // Store the Channel
***************
*** 1005,1010 ****
       * @throws BEEPException
       */
!     private void receiveCloseChannel(String channelNumber, String code,
!                                      String xmlLang, String data)
          throws BEEPError
      {
--- 956,961 ----
       * @throws BEEPException
       */
!     private void receiveCloseChannel(String channelNumber, int code,
!                                      String xmlLang, String diagnostic)
          throws BEEPError
      {
***************
*** 1205,1213 ****
  
          while (i.hasNext()) {
!             StartChannelProfile p = (StartChannelProfile) i.next();
  
              scl =
                  profileRegistry.getStartChannelListener(this.tuningProperties,
!                                                         p.uri);
  
              if (scl == null) {
--- 1156,1164 ----
  
          while (i.hasNext()) {
!             ProfileElement p = (ProfileElement) i.next();
  
              scl =
                  profileRegistry.getStartChannelListener(this.tuningProperties,
!                                                         p.getUri());
  
              if (scl == null) {
***************
*** 1215,1224 ****
              }
  
!             ch = new ChannelImpl(p.uri, channelNumber, this);
  
              try {
!                 String encoding = p.base64Encoding ? "base64" : "none";
  
!                 scl.startChannel(ch, encoding, p.data);
              } catch (StartChannelException e) {
                  this.enableIO();
--- 1166,1175 ----
              }
  
!             ch = new ChannelImpl(p.getUri(), channelNumber, this);
  
              try {
!                 String encoding = p.getBase64Encoding() ? "base64" : "none";
  
!                 scl.startChannel(ch, encoding, p.getData());
              } catch (StartChannelException e) {
                  this.enableIO();
***************
*** 1233,1241 ****
              }
  
!             if (p.data != null && ch.getStartData() == null) {
                  byte[] data;
!                 if (p.base64Encoding) {
                      try {
!                         data = new BASE64Decoder().decodeBuffer(p.data);
                      } catch (IOException e) {
                          ch.abort();
--- 1184,1192 ----
              }
  
!             if (p.getData() != null && ch.getStartData() == null) {
                  byte[] data;
!                 if (p.getBase64Encoding()) {
                      try {
!                         data = new BASE64Decoder().decodeBuffer(p.getData());
                      } catch (IOException e) {
                          ch.abort();
***************
*** 1246,1250 ****
                  } else {
                      try {
!                         data = p.data.getBytes("UTF-8"); 
                      } catch (UnsupportedEncodingException e) {
                          terminate("UTF-8 not supported");
--- 1197,1201 ----
                  } else {
                      try {
!                         data = p.getData().getBytes("UTF-8"); 
                      } catch (UnsupportedEncodingException e) {
                          terminate("UTF-8 not supported");
***************
*** 1254,1258 ****
                  
                  PiggybackedMSG msg = new PiggybackedMSG(ch, data,
!                                                         p.base64Encoding);
  
                  ch.setState(ChannelImpl.STATE_STARTING);
--- 1205,1209 ----
                  
                  PiggybackedMSG msg = new PiggybackedMSG(ch, data,
!                                                         p.getBase64Encoding());
  
                  ch.setState(ChannelImpl.STATE_STARTING);
***************
*** 1267,1271 ****
              } else {
                  try {
!                     sendProfile(p.uri, ch.getStartData(), ch);
                      ch.setState(ChannelImpl.STATE_ACTIVE);
                  } catch (BEEPException e) {
--- 1218,1222 ----
              } else {
                  try {
!                     sendProfile(p.getUri(), ch.getStartData(), ch);
                      ch.setState(ChannelImpl.STATE_ACTIVE);
                  } catch (BEEPException e) {
***************
*** 1277,1281 ****
                  fireChannelStarted(ch);
  
!                 if (p.data == null && ch.getState() != ChannelImpl.STATE_TUNING) {
                      this.enableIO();
                  }
--- 1228,1232 ----
                  fireChannelStarted(ch);
  
!                 if (p.getData() == null && ch.getState() != ChannelImpl.STATE_TUNING) {
                      this.enableIO();
                  }
***************
*** 1294,1329 ****
      }
  
-     private Element processMessage(Message message) throws BEEPException
-     {
- 
-         // check the message content type
-         if (!message.getDataStream().getInputStream().getContentType().equals(MimeHeaders.BEEP_XML_CONTENT_TYPE)) {
-             throw new BEEPException("Invalid content type for this message");
-         }
- 
-         // parse the stream
-         Document doc;
- 
-         try {
-             doc = builder.parse(message.getDataStream().getInputStream());
-         } catch (SAXException se) {
-             throw new BEEPException(ERR_MALFORMED_XML_MSG);
-         } catch (IOException ioe) {
-             throw new BEEPException(ERR_MALFORMED_XML_MSG);
-         }
- 
-         if (doc == null) {
-             throw new BEEPException(ERR_MALFORMED_XML_MSG);
-         }
- 
-         Element topElement = doc.getDocumentElement();
- 
-         if (topElement == null) {
-             throw new BEEPException(ERR_MALFORMED_XML_MSG);
-         }
- 
-         return topElement;
-     }
- 
      private void sendGreeting() throws BEEPException
      {
--- 1245,1248 ----
***************
*** 1331,1338 ****
  
          // get the greeting from the session
!         byte[] greeting = SessionImpl.this.getProfileRegistry().getGreeting(this);
          ByteOutputDataStream f =
              new ByteOutputDataStream(MimeHeaders.BEEP_XML_CONTENT_TYPE,
!                                      greeting);
  
          MessageMSG m = new MessageMSGImpl(this.zero, 0, null);
--- 1250,1260 ----
  
          // get the greeting from the session
!         Collection profiles = getProfileRegistry().getAdvertisedProfiles(this);
!         GreetingElement greeting =
!             new GreetingElement(null, getProfileRegistry().getLocalization(),
!                                 profiles);
          ByteOutputDataStream f =
              new ByteOutputDataStream(MimeHeaders.BEEP_XML_CONTENT_TYPE,
!                                      parser.serializeGreeting(greeting));
  
          MessageMSG m = new MessageMSGImpl(this.zero, 0, null);
***************
*** 1358,1487 ****
          public void processMSG(MessageMSG message) throws BEEPError
          {
!             Element topElement;
  
              try {
!                 topElement = processMessage(message);
!             } catch (BEEPException e) {
!                 throw new BEEPError(BEEPError.CODE_GENERAL_SYNTAX_ERROR,
!                                     ERR_MALFORMED_XML_MSG);
!             }
! 
!             String elementName = topElement.getTagName();
! 
!             if (elementName == null) {
!                 throw new BEEPError(BEEPError.CODE_PARAMETER_ERROR,
!                                     ERR_MALFORMED_XML_MSG);
              }
! 
!             // is this MSG a <start>
!             if (elementName.equals("start")) {
!                 log.debug("Received a start channel request");
! 
!                 String channelNumber = topElement.getAttribute("number");
! 
!                 if (channelNumber == null) {
!                     throw new BEEPError(BEEPError.CODE_PARAMETER_ERROR,
!                                         "Malformed <start>: no channel number");
!                 }
! 
!                 // this attribute is implied
!                 String serverName = topElement.getAttribute("serverName");
!                 NodeList profiles =
!                     topElement.getElementsByTagName("profile");
! 
!                 if (profiles == null) {
!                     throw new BEEPError(BEEPError.CODE_PARAMETER_ERROR,
!                                         "Malformed <start>: no profiles");
!                 }
! 
!                 LinkedList profileList = new LinkedList();
! 
!                 for (int i = 0; i < profiles.getLength(); i++) {
!                     Element profile = (Element) profiles.item(i);
!                     String uri = profile.getAttribute("uri");
! 
!                     if (uri == null) {
!                         throw new BEEPError(BEEPError.CODE_PARAMETER_ERROR,
!                                             "no profiles in start");
!                     }
! 
!                     String encoding = profile.getAttribute("encoding");
!                     boolean b64;
! 
!                     if ((encoding == null) || encoding.equals("")) {
!                         b64 = false;
!                     } else if (encoding.equalsIgnoreCase("base64")) {
!                         b64 = true;
!                     } else if (encoding.equalsIgnoreCase("none")) {
!                         b64 = false;
!                     } else {
!                         throw new BEEPError(BEEPError.CODE_PARAMETER_ERROR,
!                                             "unkown encoding in start");
!                     }
! 
!                     String data = null;
!                     Node dataNode = profile.getFirstChild();
! 
!                     if (dataNode != null) {
!                         data = dataNode.getNodeValue();
! 
!                         if (data.length() > MAX_PCDATA_SIZE) {
!                             throw new BEEPError(BEEPError.CODE_PARAMETER_ERROR,
!                                                 "Element's PCDATA exceeds " +
!                                                 "the maximum size");
!                         }
!                     }
! 
!                     profileList.add(new StartChannelProfile(uri, b64, data));
!                 }
! 
                  SessionImpl.this.zero.setAppData(message);
!                 SessionImpl.this.processStartChannel(channelNumber, profileList);
!             }
! 
!             // is this MSG a <close>
!             else if (elementName.equals("close")) {
!                 log.debug("Received a channel close request");
!                 
!                 try {
!                     String channelNumber = topElement.getAttribute("number");
! 
!                     if (channelNumber == null) {
!                         throw new BEEPError(BEEPError.CODE_PARAMETER_ERROR,
!                                             "Malformed <close>: no channel number");
!                     }
! 
!                     String code = topElement.getAttribute("code");
! 
!                     if (code == null) {
!                         throw new BEEPError(BEEPError.CODE_PARAMETER_ERROR,
!                                             "Malformed <close>: no code attribute");
!                     }
! 
!                     // this attribute is implied
!                     String xmlLang = topElement.getAttribute("xml:lang");
!                     String data = null;
!                     Node dataNode = topElement.getFirstChild();
! 
!                     if (dataNode != null) {
!                         data = dataNode.getNodeValue();
! 
!                         if (data.length() > MAX_PCDATA_SIZE) {
!                             throw new BEEPError(BEEPError.CODE_PARAMETER_ERROR,
!                                                 "Element's PCDATA exceeds " +
!                                                 "the maximum size");
!                         }
!                     }
!                     SessionImpl.this.zero.setAppData(message);
!                     SessionImpl.this.receiveCloseChannel(channelNumber, code,
!                                                          xmlLang, data);
!                 } catch (BEEPError e) {
!                     enableIO();
!                     throw e;
!                 }
! 
              } else {
!                 throw new BEEPError(BEEPError.CODE_PARAMETER_ERROR,
!                                     ERR_UNKNOWN_OPERATION_ELEMENT_MSG);
              }
          }
--- 1280,1304 ----
          public void processMSG(MessageMSG message) throws BEEPError
          {
!             ChannelIndication indication;
  
              try {
!                 indication = parser.parseIndication(message.getDataStream());
!             } catch (BEEPError e) {
!                 enableIO();
!                 throw e;
              }
!             
!             if (indication.getType() == ChannelIndication.START) {
!                 StartElement start = (StartElement)indication;
                  SessionImpl.this.zero.setAppData(message);
!                 SessionImpl.this.processStartChannel(Integer.toString(start.getChannelNumber()),
!                                                      start.getProfiles());
              } else {
!                 CloseElement close = (CloseElement)indication;
!                 SessionImpl.this.zero.setAppData(message);
!                 SessionImpl.this.receiveCloseChannel(Integer.toString(close.getChannelNumber()),
!                                                      close.getCode(),
!                                                      close.getXmlLang(),
!                                                      close.getDiagnostic());
              }
          }
***************
*** 1492,1560 ****
          public void receiveRPY(Message message)
          {
!             try {
!                 Element topElement = processMessage(message);
! 
!                 // is this RPY a <greeting>
!                 String elementName = topElement.getTagName();
! 
!                 if (elementName == null) {
!                     throw new BEEPException(ERR_MALFORMED_XML_MSG);
!                 } else if (!elementName.equals("greeting")) {
!                     throw new BEEPException(ERR_UNKNOWN_OPERATION_ELEMENT_MSG);
!                 }
  
!                 log.debug("Received a greeting");
! 
!                 // this attribute is implied
!                 String features = topElement.getAttribute("features");
! 
!                 // This attribute has a default value
!                 String localize = topElement.getAttribute("localize");
! 
!                 if (localize == null) {
!                     localize = Constants.LOCALIZE_DEFAULT;
!                 }
! 
!                 // Read the profiles - note, the greeting is valid
!                 // with 0 profiles
!                 NodeList profiles =
!                     topElement.getElementsByTagName("profile");
! 
!                 if (profiles.getLength() > 0) {
!                     LinkedList profileList = new LinkedList();
! 
!                     for (int i = 0; i < profiles.getLength(); i++) {
!                         Element profile = (Element) profiles.item(i);
!                         String uri = profile.getAttribute("uri");
! 
!                         if (uri == null) {
!                             throw new BEEPException("Malformed profile");
!                         }
! 
!                         String encoding = profile.getAttribute("encoding");
! 
!                         // encoding is not allowed in greetings
!                         if (encoding != null) {
! 
!                             // @todo check this
!                             // terminate("Invalid attribute 'encoding' in greeting.");
!                             // return;
!                         }
! 
!                         profileList.add(i, uri);
!                     }
  
!                     SessionImpl.this.peerSupportedProfiles =
!                         Collections.unmodifiableCollection(profileList);
!                 }
  
                  changeState(Session.SESSION_STATE_ACTIVE);
- 
-                 synchronized (this) {
-                     this.notifyAll();
-                 }
              } catch (BEEPException e) {
                  terminate("Problem with RPY: " + e.getMessage());
              }
          }
  
--- 1309,1328 ----
          public void receiveRPY(Message message)
          {
!             log.debug("Received a greeting");
  
!             try {
!                 GreetingElement greeting =
!                     parser.parseGreetingConfirmation(message.getDataStream());
  
!                 SessionImpl.this.peerSupportedProfiles = greeting.getProfiles();
  
                  changeState(Session.SESSION_STATE_ACTIVE);
              } catch (BEEPException e) {
                  terminate("Problem with RPY: " + e.getMessage());
              }
+ 
+             synchronized (this) {
+                 this.notifyAll();
+             }
          }
  
***************
*** 1596,1663 ****
          public void receiveRPY(Message message)
          {
              try {
!                 Element topElement = processMessage(message);
  
!                 // is this RPY a <greeting>
!                 String elementName = topElement.getTagName();
  
!                 if (elementName == null) {
!                     throw new BEEPException(ERR_MALFORMED_XML_MSG);
  
!                     // is this RPY a <profile>
!                 } else if (elementName.equals("profile")) {
!                     try {
!                         String uri = topElement.getAttribute("uri");
  
!                         if (uri == null) {
!                             throw new BEEPException("Malformed profile");
!                         }
! 
!                         String encoding =
!                             topElement.getAttribute("encoding");
! 
!                         if (encoding == null) {
!                             encoding = Constants.ENCODING_NONE;
!                         }
! 
!                         // see if there is data and then turn it into a message
!                         Node dataNode = topElement.getFirstChild();
!                         String data = null;
! 
!                         if (dataNode != null) {
!                             data = dataNode.getNodeValue();
! 
!                             if (data.length() > MAX_PCDATA_SIZE) {
!                                 throw new BEEPException("Element's PCDATA " +
!                                                         "exceeds the " +
!                                                         "maximum size");
!                             }
!                         }
! 
!                         channel.setEncoding(encoding);
!                         channel.setProfile(uri);
!                         channel.setStartData(data);
! 
!                         // set the state
!                         channel.setState(ChannelImpl.STATE_ACTIVE);
!                         channels.put(channel.getNumberAsString(), channel);
! 
!                         /**
!                          * @todo something with data
!                          */
! 
!                         // release the block waiting for the channel
!                         // to start or close
!                         synchronized (this) {
!                             this.notify();
!                         }
!                     } catch (Exception x) {
!                         throw new BEEPException(x);
!                     }
!                 } else {
!                     throw new BEEPException(ERR_UNKNOWN_OPERATION_ELEMENT_MSG);
!                 }
!             } catch (BEEPException e) {
!                 terminate("Problem with RPY: " + e.getMessage());
              }
          }
--- 1364,1392 ----
          public void receiveRPY(Message message)
          {
+             ProfileElement profile;
              try {
!                 profile =
!                     parser.parseStartConfirmation(message.getDataStream());
!             } catch (BEEPException e) {
!                 terminate("Problem with RPY: " + e.getMessage());
!                 return;
!             }
  
!             channel.setEncoding(profile.getBase64Encoding() ? "base64" : "none");
!             channel.setProfile(profile.getUri());
!             channel.setStartData(profile.getData());
  
!             // set the state
!             channel.setState(ChannelImpl.STATE_ACTIVE);
!             channels.put(channel.getNumberAsString(), channel);
  
!             /**
!              * @todo something with data
!              */
  
!             // release the block waiting for the channel
!             // to start or close
!             synchronized (this) {
!                 this.notify();
              }
          }
***************
*** 1668,1672 ****
  
              try {
!                 err = BEEPError.convertMessageERRToException(message);
              } catch (BEEPException e) {
                  terminate(e.getMessage());
--- 1397,1404 ----
  
              try {
!                 ErrorElement error = parser.parseError(message.getDataStream());
! 
!                 err = new BEEPError(error.getCode(), error.getDiagnostic(),
!                         error.getXmlLang());
              } catch (BEEPException e) {
                  terminate(e.getMessage());
***************
*** 1722,1753 ****
          {
              try {
!                 Element topElement = processMessage(message);
!                 String elementName = topElement.getTagName();
! 
!                 if (elementName == null) {
!                     throw new BEEPException(ERR_MALFORMED_XML_MSG);
! 
!                     // is this RPY an <ok> (the positive response to a
!                     // channel close)
!                 } else if (elementName.equals("ok")) {
                      log.debug("Received an OK for channel close");
- 
-                     // @todo we should fire an event instead.
-                     // set the state
-                     channel.setState(ChannelImpl.STATE_CLOSING);
-                     channels.remove(channel.getNumberAsString());
-                     channel.setState(ChannelImpl.STATE_CLOSED);
- 
-                     // release the block waiting for the channel to
-                     // start or close
-                     synchronized (this) {
-                         this.notify();
-                     }
-                 } else {
-                     throw new BEEPException(ERR_UNKNOWN_OPERATION_ELEMENT_MSG);
-                 }
              } catch (BEEPException e) {
                  terminate("Problem with RPY: " + e.getMessage());
              }
          }
  
--- 1454,1474 ----
          {
              try {
!                 parser.parseCloseConfirmation(message.getDataStream());
                      log.debug("Received an OK for channel close");
              } catch (BEEPException e) {
                  terminate("Problem with RPY: " + e.getMessage());
              }
+ 
+             // @todo we should fire an event instead.
+             // set the state
+             channel.setState(ChannelImpl.STATE_CLOSING);
+             channels.remove(channel.getNumberAsString());
+             channel.setState(ChannelImpl.STATE_CLOSED);
+ 
+             // release the block waiting for the channel to
+             // start or close
+             synchronized (this) {
+                 this.notify();
+             }
          }
  
***************
*** 1757,1761 ****
  
              try {
!                 err = BEEPError.convertMessageERRToException(message);
              } catch (BEEPException e) {
                  terminate(e.getMessage());
--- 1478,1485 ----
  
              try {
!                 ErrorElement error = parser.parseError(message.getDataStream());
! 
!                 err = new BEEPError(error.getCode(), error.getDiagnostic(),
!                         error.getXmlLang());
              } catch (BEEPException e) {
                  terminate(e.getMessage());

Index: StartChannelProfile.java
===================================================================
RCS file: /cvsroot/beepcore-java/beepcore-java/src/org/beepcore/beep/core/StartChannelProfile.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -r1.2 -r1.3
*** StartChannelProfile.java	8 Nov 2001 05:51:34 -0000	1.2
--- StartChannelProfile.java	25 Feb 2006 17:48:37 -0000	1.3
***************
*** 2,6 ****
   * StartChannelProfile.java  $Revision$ $Date$
   *
!  * Copyright (c) 2001 Invisible Worlds, Inc.  All rights reserved.
   *
   * The contents of this file are subject to the Blocks Public License (the
--- 2,6 ----
   * StartChannelProfile.java  $Revision$ $Date$
   *
!  * Copyright (c) 2004 Huston Franklin.  All rights reserved.
   *
   * The contents of this file are subject to the Blocks Public License (the
***************
*** 17,37 ****
  package org.beepcore.beep.core;
  
  
  /**
   * Class StartChannelProfile
   *
!  *
!  * @author Eric Dixon
!  * @author Huston Franklin
!  * @author Jay Kint
!  * @author Scott Pead
   * @version $Revision$, $Date$
   */
! public class StartChannelProfile {
! 
!     String uri;
!     boolean base64Encoding;
!     String data;
! 
      /**
       * Constructor StartChannelProfile
--- 17,30 ----
  package org.beepcore.beep.core;
  
+ import org.beepcore.beep.core.serialize.ProfileElement;
+ 
  
  /**
   * Class StartChannelProfile
   *
!  * @deprecated Use org.beepcore.beep.core.serialize.ProfileElement instead.
   * @version $Revision$, $Date$
   */
! public class StartChannelProfile extends ProfileElement {
      /**
       * Constructor StartChannelProfile
***************
*** 46,52 ****
                                 String data)
      {
!         this.uri = uri;
!         this.base64Encoding = base64Encoding;
!         this.data = data;
      }
  
--- 39,43 ----
                                 String data)
      {
!         super(uri, base64Encoding, data);
      }
  
***************
*** 60,66 ****
      public StartChannelProfile(String uri)
      {
!         this.uri = uri;
!         this.base64Encoding = false;
!         this.data = null;
      }
  }
--- 51,55 ----
      public StartChannelProfile(String uri)
      {
!         super(uri);
      }
  }

Index: BEEPError.java
===================================================================
RCS file: /cvsroot/beepcore-java/beepcore-java/src/org/beepcore/beep/core/BEEPError.java,v
retrieving revision 1.9
retrieving revision 1.10
diff -C2 -r1.9 -r1.10
*** BEEPError.java	18 Nov 2003 14:03:07 -0000	1.9
--- BEEPError.java	25 Feb 2006 17:48:37 -0000	1.10
***************
*** 3,7 ****
   *
   * Copyright (c) 2001 Invisible Worlds, Inc.  All rights reserved.
!  * Copyright (c) 2002 Huston Franklin.  All rights reserved.
   *
   * The contents of this file are subject to the Blocks Public License (the
--- 3,7 ----
   *
   * Copyright (c) 2001 Invisible Worlds, Inc.  All rights reserved.
!  * Copyright (c) 2002,2004 Huston Franklin.  All rights reserved.
   *
   * The contents of this file are subject to the Blocks Public License (the
***************
*** 19,31 ****
  
  
- import java.io.IOException;
- 
- import javax.xml.parsers.*;
- 
- import org.w3c.dom.*;
- 
- import org.xml.sax.SAXException;
- 
- 
  /**
   * Class BEEPError
--- 19,22 ----
***************
*** 132,262 ****
      }
  
-     /**
-      * Method createErrorMessage
-      *
-      *
-      * @return the XML error element that can be sent in a BEEP ERR message
-      *
-      */
-     public String createErrorMessage()
-     {
-         return createErrorMessage(this.code, this.getMessage(), this.xmlLang);
-     }
- 
-     /**
-      * Creates a <code>String</code> for an error element that can be sent
-      * in a BEEP ERR message.
-      *
-      * @param code Error code.
-      * @param diagnostic Error diagnostic.
-      */
-     public static String createErrorMessage(int code, String diagnostic)
-     {
-         return createErrorMessage(code, diagnostic, null);
-     }
- 
-     /**
-      * Creates a <code>String</code> for an error element that can be sent
-      * in a BEEP ERR message.
-      *
-      * @param code Error code.
-      * @param diagnostic Error diagnostic.
-      * @param xmlLang Language of the diagnostic message.
-      */
-     public static String createErrorMessage(int code, String diagnostic,
-                                      String xmlLang)
-     {
-         StringBuffer sb = new StringBuffer(128);
- 
-         sb.append("<error code='");
-         sb.append(code);
- 
-         if (xmlLang != null) {
-             sb.append("' xml:lang='");
-             sb.append(xmlLang);
-         }
- 
-         if (diagnostic != null) {
-             sb.append("' >");
-             sb.append(diagnostic);
-             sb.append("</error>");
-         } else {
-             sb.append("' />");
-         }
- 
-         return sb.toString();
-     }
- 
-     /**
-      * Method convertMessageERRToException
-      *
-      *
-      * @param message
-      *
-      * @return New <code>BEEPError</code> for the specified BEEP ERR message
-      *
-      * @throws BEEPException
-      *
-      */
-     protected static BEEPError convertMessageERRToException(Message message)
-             throws BEEPException
-     {
-         if (message.getMessageType() != Message.MESSAGE_TYPE_ERR) {
-             throw new IllegalArgumentException("messageType != ERR");
-         }
- 
-         // parse the stream
-         Document doc = null;
- 
-         try {
-             DocumentBuilder builder =
-                 DocumentBuilderFactory.newInstance().newDocumentBuilder();
- 
-             doc = builder.parse(message.getDataStream().getInputStream());
-         } catch (ParserConfigurationException e) {
-             throw new BEEPException("Invalid parser configuration");
-         } catch (SAXException e) {
-             throw new BEEPException(ERR_MALFORMED_XML_MSG);
-         } catch (IOException ioe) {
-             throw new BEEPException(ERR_MALFORMED_XML_MSG);
-         }
- 
-         if (doc == null) {
-             throw new BEEPException(ERR_MALFORMED_XML_MSG);
-         }
- 
-         Element topElement = doc.getDocumentElement();
- 
-         if (topElement == null) {
-             throw new BEEPException(ERR_MALFORMED_XML_MSG);
-         }
- 
-         // check for <error>
-         String elementName = topElement.getTagName();
- 
-         if (elementName == null) {
-             throw new BEEPException(ERR_MALFORMED_XML_MSG);
-         } else if (!elementName.equals("error")) {
-             throw new BEEPException("Unknown operation element");
-         }
- 
-         String code = topElement.getAttribute("code");
- 
-         if (code == null) {
-             throw new BEEPException(ERR_MALFORMED_XML_MSG);
-         }
- 
-         // this attribute is implied
-         String xmlLang = topElement.getAttribute("xml:lang");
-         Node dataNode = topElement.getFirstChild();
-         String data = null;
- 
-         if (dataNode != null) {
-             data = dataNode.getNodeValue();
-         }
- 
-         return new BEEPError(Integer.parseInt(code), data, xmlLang);
-     }
- 
      /** Success */
      public static final int CODE_SUCCESS = 200;
--- 123,126 ----

Index: MessageMSGImpl.java
===================================================================
RCS file: /cvsroot/beepcore-java/beepcore-java/src/org/beepcore/beep/core/MessageMSGImpl.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -r1.1 -r1.2
*** MessageMSGImpl.java	3 Jun 2003 16:38:35 -0000	1.1
--- MessageMSGImpl.java	25 Feb 2006 17:48:37 -0000	1.2
***************
*** 3,7 ****
   *
   * Copyright (c) 2001 Invisible Worlds, Inc.  All rights reserved.
!  * Copyright (c) 2003 Huston Franklin.  All rights reserved.
   *
   * The contents of this file are subject to the Blocks Public License (the
--- 3,7 ----
   *
   * Copyright (c) 2001 Invisible Worlds, Inc.  All rights reserved.
!  * Copyright (c) 2003-2004 Huston Franklin.  All rights reserved.
   *
   * The contents of this file are subject to the Blocks Public License (the
***************
*** 18,21 ****
--- 18,23 ----
  package org.beepcore.beep.core;
  
+ import org.beepcore.beep.core.serialize.ErrorElement;
+ 
  /**
   * Represents received BEEP MSG messages. Provides methods to reply to
***************
*** 79,84 ****
      public MessageStatus sendERR(BEEPError error) throws BEEPException
      {
          OutputDataStream stream =
!             new StringOutputDataStream(error.createErrorMessage());
          MessageStatus m = new MessageStatus(this.channel,
                                              Message.MESSAGE_TYPE_ERR,
--- 81,89 ----
      public MessageStatus sendERR(BEEPError error) throws BEEPException
      {
+         byte[] errorString =
+             channel.session.parser.serializeError(new ErrorElement(error.getCode(),
+                     error.getXMLLang(), error.getDiagnostic()));
          OutputDataStream stream =
!             new ByteOutputDataStream(errorString);
          MessageStatus m = new MessageStatus(this.channel,
                                              Message.MESSAGE_TYPE_ERR,
***************
*** 103,111 ****
          throws BEEPException
      {
!         String error = BEEPError.createErrorMessage(code, diagnostic);
          MessageStatus m = new MessageStatus(this.channel,
                                              Message.MESSAGE_TYPE_ERR,
                                              this.msgno,
!                                             new StringOutputDataStream(error));
          this.channel.sendMessage(m);
          return m;
--- 108,117 ----
          throws BEEPException
      {
!         ErrorElement error = new ErrorElement(code, diagnostic);
!         byte[] errorString = channel.session.parser.serializeError(error);
          MessageStatus m = new MessageStatus(this.channel,
                                              Message.MESSAGE_TYPE_ERR,
                                              this.msgno,
!                                             new ByteOutputDataStream(errorString));
          this.channel.sendMessage(m);
          return m;
***************
*** 129,137 ****
          throws BEEPException
      {
!         String error = BEEPError.createErrorMessage(code, diagnostic, xmlLang);
          MessageStatus m = new MessageStatus(this.channel,
                                              Message.MESSAGE_TYPE_ERR,
                                              this.msgno,
!                                             new StringOutputDataStream(error));
          this.channel.sendMessage(m);
          return m;
--- 135,154 ----
          throws BEEPException
      {
!         ErrorElement error = new ErrorElement(code, xmlLang, diagnostic);
!         byte[] errorString = channel.session.parser.serializeError(error);
!         MessageStatus m = new MessageStatus(this.channel,
!                                             Message.MESSAGE_TYPE_ERR,
!                                             this.msgno,
!                                             new ByteOutputDataStream(errorString));
!         this.channel.sendMessage(m);
!         return m;
!     }
!     
!     public MessageStatus sendERR(OutputDataStream stream) throws BEEPException
!     {
          MessageStatus m = new MessageStatus(this.channel,
                                              Message.MESSAGE_TYPE_ERR,
                                              this.msgno,
!                                             stream);
          this.channel.sendMessage(m);
          return m;



-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642