[Beepcore-java-commits] CVS: beepcore-java/src/org/beepcore/beep/core ProfileRegistry.java,1.14,1.15
Status: Beta
Brought to you by:
huston
From: Huston F. <hu...@us...> - 2006-02-25 17:48:40
|
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; |