
redora.util.JSONWriter Maven / Gradle / Ivy
/*
* Copyright 2009-2010 Nanjing RedOrange ltd (http://www.red-orange.cn)
*
* 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 redora.util;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import redora.api.fetch.Page;
import redora.exceptions.JSONException;
import redora.exceptions.PagingException;
import redora.service.BusinessRuleViolation;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.Date;
import java.util.Set;
import java.util.logging.Logger;
import static java.sql.Types.*;
import static java.util.logging.Level.INFO;
import static redora.db.SQLParameter.yyyyMMdd;
import static redora.db.SQLParameter.yyyyMMddHHMMSS;
/**
* Some common methods for JSON used in projects based on Redora. The writeXXX
* methods write JSON speak to an output stream.
*
* @author Nanjing RedOrange (www.red-orange.cn)
*
*/
public class JSONWriter {
static final transient Logger l = Logger.getLogger("redora.util.JSONWriter");
final PrintWriter out;
/**
* Possible statuses. Mind you in JSON the ordinal vale is used. So, when changing
* this also update redora.client.validation.BusinessRuleCheckHandler#ResponseStatus
*/
public enum ResponseStatus {
success, brViolated, expired, refused
}
/**
* Initialized by setting the output writer and setting the content-type
* to 'application/json'.
* @param resp (Mandatory)
* @throws IOException Passing on exception from getting the output writer
*/
public JSONWriter(@NotNull HttpServletResponse resp) throws IOException {
this(resp.getWriter());
resp.setContentType("application/json");
}
/**
* Creates a JSONWriter for usage outside a servlet container. Normally
* you only use this for testing or when you want to stream the output to disk.
* @param out (Mandatory)
*/
public JSONWriter(@NotNull PrintWriter out) {
this.out = out;
}
/** prints "null" */
public void nullOut() {
out.print("null");
}
/**
* Prints JSON key like 'key:'
* @param key (Mandatory)
*/
public void key(@NotNull String key) {
out.print(key);
out.print(':');
}
/**
* Prints JSON key like '"key":'
* @param key (Mandatory)
*/
public void keyQuoted(@NotNull String key) {
out.print('\"');
out.print(key);
out.print('\"');
out.print(':');
}
/**
* Writes 'normal' values from resultset to printwriter in a json style
* markup like key:value. It will quote the value according the sqlType.
*
* @param sqlType java.sql.Types
* @param key (Mandatory)
* @param value (Optional)
* @throws JSONException When escaping the characters fails
*/
public void rs(int sqlType, @NotNull String key, @Nullable String value) throws JSONException {
key(key);
if (value == null) {
nullOut();
} else if (sqlType == BIGINT || sqlType == INTEGER || sqlType == DOUBLE) {
out.print(value);
} else {
out.print('\"');
if (sqlType == CHAR) {
out.print(value);
} else {
new JSONTokener(value).stream(out);
}
out.print('\"');
}
}
/**
* Prints escaped and quoted like "'key':'value'"
* @param key (Mandatory)
* @param value (Mandatory)
* @throws JSONException Exceptions when escaping the value
*/
public void escaped(@NotNull String key, @Nullable String value) throws JSONException {
key(key);
if (value == null) {
nullOut();
} else {
out.print('\"');
new JSONTokener(value).stream(out);
out.print('\"');
}
}
public void quoteValue(@Nullable Object value) {
if (value == null) {
nullOut();
} else {
out.print('\"');
out.print(value);
out.print('\"');
}
}
public void quoted(@NotNull String key, @Nullable Object value) {
key(key);
quoteValue(value);
}
public void kvp(@NotNull String key, @Nullable Object value) {
key(key);
if (value == null)
nullOut();
else
out.print(value);
}
/**
* Writes 'normal' values from resultset to printwriter in a json style
* markup
*
* @param key
* @param in
* @param wasNull
*/
public void stream(@NotNull String key, InputStream in, boolean wasNull)
throws JSONException {
key(key);
if (wasNull) {
nullOut();
} else {
out.print('\"');
try {
new JSONTokener(new InputStreamReader(in, "UTF-8")).stream(out);
} catch (UnsupportedEncodingException ex) {
throw new JSONException(ex);
}
out.print('\"');
}
}
public void date(@NotNull String key, java.sql.Date date, boolean wasNull) {
if (wasNull && date == null) {
key(key);
nullOut();
} else {
date(key, new Date(date.getTime()));
}
}
public void date(@NotNull String key, @Nullable Date date) {
key(key);
if (date == null) {
nullOut();
} else {
out.print('\"');
out.print(yyyyMMdd.format(date));
out.print('\"');
}
}
public void dateTime(@NotNull String key, Date date, boolean wasNull) {
if (wasNull) {
key(key);
nullOut();
} else {
dateTime(key, new Date(date.getTime()));
}
}
public void dateTime(@NotNull String key, @Nullable Date date) {
key(key);
if (date == null) {
nullOut();
} else {
out.print('\"');
out.print(yyyyMMddHHMMSS.format(date));
out.print('\"');
}
}
public void start(int status) {
out.print("{response:{status:");
out.print(String.valueOf(status));
}
public void startSuccess() {
start(ResponseStatus.success.ordinal());
}
public void responseStart() {
startSuccess();
out.print(",data:");
}
public void responseEnd() {
out.print("}}");
}
public void responseSuccess() {
startSuccess();
out.print("}}");
}
/**
* The client is not logged in. The expired message is returned when the client needs to be logged in.
*/
public void expired() {
start(ResponseStatus.expired.ordinal());
responseEnd();
}
/**
* The client is logged in but it is trying to do something it is not allowed.
*/
public void refused() {
start(ResponseStatus.refused.ordinal());
responseEnd();
}
public void responseWithPageStart(@NotNull Page page) throws PagingException {
startSuccess();
out.print(",page:{");
out.print(page.toJSON());
out.print("},data:[");
}
public void responseWithArrayStart() {
startSuccess();
out.print(",data:[");
}
public void responseWithArrayEnd() {
out.print("]}}");
}
public void persist(@NotNull Set ret) {
if (ret.isEmpty()) {
responseSuccess();
} else {
l.log(INFO, "Responding {0} business rule violations", ret.size());
violation(ret);
}
}
public void violation(@NotNull Set ret) {
start(ResponseStatus.brViolated.ordinal());
out.print(",violations:[");
char comma = ' ';
for (BusinessRuleViolation br : ret) {
out.print(comma);
out.print(br.toJSON());
comma = ',';
}
out.print("]}}");
}
@Deprecated
public void customResponse(int status) {
start(status);
responseEnd();
}
public void print(char c) {
out.print(c);
}
@Deprecated //Create methods for this
public void print(String s) {
out.print(s);
}
public void flush() {
out.flush();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy