![JAR search and dependency download from the Maven repository](/logo.png)
org.atmosphere.stomp.protocol.Parser Maven / Gradle / Ivy
/*
* Copyright 2014 Jeanfrancois Arcand
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.atmosphere.stomp.protocol;
import org.apache.activemq.apollo.broker.store.MessageRecord;
import org.apache.activemq.apollo.stomp.StompCodec;
import org.apache.activemq.apollo.stomp.StompFrameMessage;
import org.fusesource.hawtbuf.AsciiBuffer;
import org.fusesource.hawtbuf.Buffer;
import org.apache.activemq.apollo.stomp.StompFrame;
import scala.Tuple2;
import scala.collection.Iterator;
import java.io.ByteArrayOutputStream;
import java.util.HashMap;
import java.util.Map;
/**
*
* This class parses text stream that respects STOMP protocol to extract a structured {@link Frame} that provides a
* set of information. A {@link Frame} contains:
*
* - The {@link Action}
* - The {@link Header headers} and their values
* - The body in {@code String} value
*
*
*
*
* If the text stream violates the STOMP protocol, then several {@link ParseException} could be thrown.
* The {@link ParseException} class provides different subclasses that detail the cause.
*
*
* @author Guillaume DROUET
* @since 0.1
* @version 1.0
*/
public class Parser {
/**
* The stream parsed by this parser.
*/
private String stream;
/**
* Resulting frame.
*/
private StompFrame sm;
/**
* The exception that occurred of frame can't be decoded.
*/
private Exception error;
/**
*
* Builds a new {@link Parser} for the given text stream.
*
*
* @param textStream the {@code String} to parse
*/
public Parser(final String textStream) {
stream = textStream;
}
/**
*
* Parses the {@link #stream} to extract data.
*
*/
public void parse() {
try {
final MessageRecord mr = new MessageRecord();
mr.buffer_$eq(new Buffer(stream.getBytes()));
final StompFrameMessage sfm = StompCodec.decode(mr);
sm = sfm.frame();
} catch (Exception spe) {
error = spe;
}
}
/**
*
* Builds a {@link Frame} that provides information extracted from {@link #stream}. If {@link #parse()} has not
* been already called, then this method invokes it.
*
*
*
* If the result of the {@link #parse()} operation has detected any protocol violation, then the appropriate
* {@link ParseException} is thrown by this method.
*
*
* @return the message
* @throws ParseException if {@link #stream} violates STOMP protocol
*/
public Frame toFrame() throws ParseException {
// parse() not already called
if (sm == null && error == null) {
parse();
return toFrame();
// parse() failed
} else if (error != null) {
throw new ParseException(error);
}
// Read action
final Action action = Action.parse(sm.action().toString());
// Read headers
final Map headers = new HashMap();
final Iterator> it = sm.headers().iterator();
// TODO: check mandatory headers
while (it.hasNext()) {
final Tuple2 tuple = it.next();
headers.put(tuple._1().toString(), tuple._2().toString());
}
// Read body
final ByteArrayOutputStream content = new ByteArrayOutputStream();
sm.content().writeTo(content);
return new Frame(action, headers, new String(content.toByteArray()));
}
}