All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.butor.json.JsonStreamHandler Maven / Gradle / Ivy

Go to download

This module enables fast and easy creation of sync., async., req./resp., req./resp. stream HTTP/json services.

There is a newer version: 1.0.29
Show newest version
/*******************************************************************************
 * Copyright 2013 butor.com
 * 
 * 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.butor.json;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.nio.ByteBuffer;

import org.butor.json.service.ResponseHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class JsonStreamHandler implements StreamHandler {
	protected Logger _logger = LoggerFactory.getLogger(getClass());

	private Class _rowClass = null;
	private ResponseHandler _responseHandler;
	private InputStream _is;
	private JsonHelper _jsh = new JsonHelper();
	private String _reqLogInfo;

	@Override
	public void parse(InputStream is_,
			ResponseHandler handler_, String loReqInfo_) throws IOException {
		
		_is = is_;
		_responseHandler = handler_;
		_reqLogInfo = loReqInfo_;
		Type t = ((ParameterizedType)_responseHandler.getClass().getGenericInterfaces()[0]).getActualTypeArguments()[0];
		if (t instanceof Class) {
			_rowClass = (Class)t;
		} else {
			_logger.error("Cannot determine the type for response handler {}!!!",_responseHandler);
		}

		int chunkCounter = -1;
		ByteBuffer bb = ByteBuffer.allocate(1024); // will grows if more space required
		bb.clear();
		while (true) {
			byte b = (byte) _is.read();
			if (b == -1)
				break;

			if (b == 0) {
				if (++chunkCounter == 0) {
					continue;
				}

				bb.flip();
				String chunk = new String(bb.array(), 0, bb.limit());
				handleChunk(chunk);
				bb.clear();
				continue;
			}

			if (chunkCounter >= 0)
				if (bb.remaining() == 0) {
					ByteBuffer tmp = ByteBuffer.allocate(bb.capacity() *2);
					tmp.clear();
					bb.flip();
					tmp.put(bb.array(), 0, bb.limit());
					bb = tmp;
				}
				bb.put(b);
		}
		_responseHandler.end();
	}

	/**
	 * Invoked when a message object (e.g: {@link ChannelBuffer}) was received
	 * from a remote peer.
	 */
	private void handleChunk(String chunk_) {
		if (chunk_.indexOf(Constants.RESPONSE_HEADER_CHUNK) > -1) {
			// header OK
			return;
		}
		if (chunk_.indexOf(Constants.RESPONSE_MESSAGE_CHUNK) > -1) {
			_logger.info("got message: {}, {}", _reqLogInfo, chunk_);
			JsonResponseMessage jrm = _jsh.deserialize(chunk_, JsonResponseMessage.class);
			_responseHandler.addMessage(jrm.getMessage());

		} else {
			_logger.info("got row: {}, {}", _reqLogInfo, chunk_);
			if (_rowClass == null) {
				_logger.error("We were not able to determine the rows type from the ResponseHandler.addRow(type) method!");
				return;
			}
			T row = _jsh.deserialize(chunk_, _rowClass);
			_responseHandler.addRow(row);
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy