/*******************************************************************************
* 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.web.servlet;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.butor.json.JsonHelper;
import org.butor.json.JsonRequest;
import org.butor.json.service.BinResponseHandler;
import org.butor.json.service.ResponseHandler;
import org.butor.utils.Message;
import org.butor.utils.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static com.google.common.base.Strings.isNullOrEmpty;
public class BinAjaxComponent extends BaseAjaxComponent {
protected Logger _logger = LoggerFactory.getLogger(getClass());
private JsonHelper _jsh = new JsonHelper();
public BinAjaxComponent(Object targetCmp) {
super(targetCmp);
}
@Override
public void process(final HttpServletRequest req_, final HttpServletResponse resp_)
throws ServletException, IOException {
OutputStream os = null;
BinResponseHandler streamer = null;
String serviceName = null;
JsonRequest jr = null;
try {
jr = findJsonRequest(req_);
List<?> params = _jsh.deserialize(jr.getServiceArgsJson(), List.class);
int nbArgs = params.size();
final JsonRequest fjr = jr;
serviceName = jr.getService();
if (StringUtil.isEmpty(serviceName))
throw new IllegalArgumentException("Missing serviceName");
Method m = findService(serviceName, nbArgs);
if (m == null)
throw new UnsupportedOperationException(
String.format("Service=%s with %d args doesn't exists",
serviceName, nbArgs +1));
os = resp_.getOutputStream();
final OutputStream fos = os;
streamer = new BinResponseHandler() {
@Override
public void end() {
}
@Override
public boolean addRow(byte[] row_) {
try {
fos.write(row_);
fos.flush();
return true;
} catch (IOException e) {
_logger.warn("Failed to addRow", e);
}
return false;
}
@Override
public boolean addMessage(Message message_) {
return true;
}
@Override
public void setContentType(String contentType, Map<String, String> headers) {
// TODO Auto-generated method stub
if (!isNullOrEmpty(contentType)) {
resp_.setContentType(contentType);
}
if (headers != null) {
for (String h : headers.keySet()) {
resp_.addHeader(h, headers.get(h));
}
}
}
@Override
public OutputStream getOutputStream() {
// TODO Auto-generated method stub
return fos;
}
@Override
public Class<byte[]> getResponseType() {
return byte[].class;
}
};
final ResponseHandler<byte[]> fStreamer = streamer;
AjaxContext ctx = new AjaxContext() {
@Override
public ResponseHandler<byte[]> getResponseHandler() {
return fStreamer;
}
@Override
public HttpServletResponse getHttpServletResponse() {
return resp_;
}
@Override
public HttpServletRequest getHttpServletRequest() {
return req_;
}
@Override
public JsonRequest getRequest() {
return fjr;
}
};
Class<?>[] pts = m.getParameterTypes();
Object[] args = new Object[pts.length];
args[0] = ctx;
for (int ii=1; ii<pts.length; ii++) {
Object par = params.get(ii-1);
String so = _jsh.serialize(par);
args[ii] = _jsh.deserialize(so, pts[ii]);
}
m.invoke(getTargetCmp(), args);
} catch (InvocationTargetException e) {
if (streamer != null)
handleException(streamer, serviceName, e.getTargetException());
} catch (Throwable e) {
if (streamer != null)
handleException(streamer, serviceName, e);
} finally {
if (streamer != null) {
try {
os.flush();
} catch (Exception e) {
_logger.warn("Oh shit! Failed in finally.", e);
//never mind
}
}
}
}
}