//
// Copyright 2010 Cinch Logic Pty Ltd.
//
// http://www.chililog.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.chililog.server.workbench.workers;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import org.chililog.server.common.BuildProperties;
import org.chililog.server.common.JsonTranslator;
import org.chililog.server.workbench.workers.AuthenticationAO.ExpiryType;
import org.chililog.server.workbench.workers.Worker.ContentIOStyle;
import org.jboss.netty.handler.codec.http.HttpResponseStatus;
/**
* <p>
* Encapsulates the result of invoking an API worker.
* </p>
* <p>
* It contains the details for constructing an HTTPResponse to return to the caller.
* </p>
*
* @author vibul
*
*/
public class ApiResult {
private HttpResponseStatus _responseStatus = HttpResponseStatus.OK;
private String _responseContentType = Worker.JSON_CONTENT_TYPE;
private ContentIOStyle _responseContentIOStyle = ContentIOStyle.ByteArray;
private Object _responseContent = null;
private HashMap<String, String> _headers = new HashMap<String, String>();
/**
* Basic constructor
*/
public ApiResult() {
return;
}
/**
* Builds an error result
*
* @param status
* HTTP Response status
* @param ex
* Exception describing the error
*/
public ApiResult(HttpResponseStatus status, Throwable ex) {
_responseStatus = status;
setResponseContentToJson(new ErrorAO(ex));
}
/**
* Builds a successful result with authentication token and content. <code>200 OK</code> is returned unless
* <code>contentToJsonify</code> is null, in which case <code>204 No Content</code> is returned
*
* @param authenticationToken
* The authentication token that was submitted in the request. It will be updated and returned in the
* response header for sliding expiry. For absolute expiry, it will not be returned.
* @param contentType
* response content MIME type
* @param content
* Object to convert into JSON format.
*/
public ApiResult(AuthenticationTokenAO authenticationToken, String contentType, Object content) {
BuildProperties buildProperties = BuildProperties.getInstance();
_responseStatus = (content == null ? HttpResponseStatus.NO_CONTENT : HttpResponseStatus.OK);
_responseContentType = contentType;
// For an sliding expiry token, we want to update the expiry time
if (authenticationToken.getExpiryType() == ExpiryType.Sliding) {
authenticationToken.updateExpiresOn();
}
_headers.put(Worker.AUTHENTICATION_TOKEN_HEADER, authenticationToken.toString());
_headers.put(Worker.AUTHENTICATION_SERVER_VERSION, buildProperties.getAppVersion());
_headers.put(Worker.AUTHENTICATION_SERVER_BUILD_TIMESTAMP, buildProperties.getBuildTimestamp());
if (content != null) {
if (content instanceof byte[]) {
_responseContent = content;
_responseContentIOStyle = ContentIOStyle.ByteArray;
} else if (content instanceof File) {
_responseContent = content;
_responseContentIOStyle = ContentIOStyle.File;
} else if (contentType != null && contentType.equals(Worker.JSON_CONTENT_TYPE)) {
// Try to turn it into JSON
setResponseContentToJson(content);
} else {
throw new UnsupportedOperationException("Cannot handled content of type "
+ content.getClass().getName());
}
}
}
/**
* Determines if the call is successful or not
*/
public boolean isSuccess() {
return _responseStatus == HttpResponseStatus.OK;
}
/**
* The HTTP Response status to return to the caller
*/
public HttpResponseStatus getResponseStatus() {
return _responseStatus;
}
public void setHttpResponseStatus(HttpResponseStatus httpResponseStatus) {
_responseStatus = httpResponseStatus;
}
/**
* The MIME type to return to the caller. Defaults to <code>text/json</code>
*/
public String getResponseContentType() {
return _responseContentType;
}
public void setResponseContentType(String responseContentType) {
_responseContentType = responseContentType;
}
/**
* <p>
* How the response content can be read.
* </p>
* <p>
* If <code>ByteArray</code>, <code>getResponseContent()</code> will return a <code>byte[]</code>. This is the
* default.
* </p>
* <p>
* If <code>File</code>, <code>getResponseContent()</code> will return a <code>java.io.File</code>.
* </p>
*/
public ContentIOStyle getResponseContentIOStyle() {
return _responseContentIOStyle;
}
public void setResponseContentIOStyle(ContentIOStyle responseContentIOStyle) {
_responseContentIOStyle = responseContentIOStyle;
}
/**
* <p>
* Returns the content to be downloaded to the caller. If null, there is no data.
* </p>
* <p>
* The data type of the return object is either: <code>byte[]</code> or <code>java.io.File</code>
* </p>
*/
public Object getResponseContent() {
return _responseContent;
}
public void setResponseContent(Object responseContent) {
_responseContent = responseContent;
}
/**
* Translates the specified object <code>o</code> into JSON and sets it as the content
*
* @param contentToJsonify
* Object to translate into JSON and then return to the caller
* @throws UnsupportedEncodingException
*/
public void setResponseContentToJson(Object contentToJsonify) {
try {
_responseContentType = Worker.JSON_CONTENT_TYPE;
_responseContentIOStyle = ContentIOStyle.ByteArray;
if (contentToJsonify == null) {
_responseContent = null;
} else {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(baos, true, Worker.JSON_CHARSET);
JsonTranslator.getInstance().toJson(contentToJsonify, ps);
ps.close();
_responseContent = baos.toByteArray();
}
} catch (Exception ex) {
// We should not get UnsupportedEncodingException ... but you never know.
// Just throw again
throw new RuntimeException(ex.getMessage(), ex);
}
}
/**
* Headers that will be returned to the caller
*/
public HashMap<String, String> getHeaders() {
return _headers;
}
}