1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.codelibs.fess.api;
17
18 import java.io.IOException;
19 import java.io.PrintWriter;
20 import java.io.StringWriter;
21 import java.text.SimpleDateFormat;
22 import java.util.Date;
23 import java.util.List;
24 import java.util.Locale;
25 import java.util.Map;
26
27 import javax.servlet.http.HttpServletResponse;
28
29 import org.apache.commons.text.StringEscapeUtils;
30 import org.codelibs.core.CoreLibConstants;
31 import org.codelibs.core.lang.StringUtil;
32 import org.codelibs.fess.Constants;
33 import org.codelibs.fess.exception.InvalidAccessTokenException;
34 import org.lastaflute.web.util.LaRequestUtil;
35 import org.lastaflute.web.util.LaResponseUtil;
36
37 public abstract class BaseJsonApiManager extends BaseApiManager {
38
39 protected void writeJsonResponse(final int status, final String body, final Throwable t) {
40 if (t == null) {
41 writeJsonResponse(status, body, (String) null);
42 return;
43 }
44
45 if (t instanceof InvalidAccessTokenException) {
46 final InvalidAccessTokenException e = (InvalidAccessTokenException) t;
47 final HttpServletResponse response = LaResponseUtil.getResponse();
48 response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
49 response.setHeader("WWW-Authenticate", "Bearer error=\"" + e.getType() + "\"");
50 }
51
52 final StringBuilder sb = new StringBuilder();
53 if (StringUtil.isBlank(t.getMessage())) {
54 sb.append(t.getClass().getName());
55 } else {
56 sb.append(t.getMessage());
57 }
58 final StringWriter sw = new StringWriter();
59 t.printStackTrace(new PrintWriter(sw));
60 sb.append(" [ ").append(sw.toString()).append(" ]");
61 try {
62 sw.close();
63 } catch (final IOException ignore) {}
64 writeJsonResponse(status, body, sb.toString());
65 }
66
67 protected void writeJsonResponse(final int status, final String body, final String errMsg) {
68 String content = null;
69 if (status == 0) {
70 if (StringUtil.isNotBlank(body)) {
71 content = body;
72 }
73 } else {
74 content = "\"message\":" + escapeJson(errMsg);
75 }
76 writeJsonResponse(status, content);
77 }
78
79 protected void writeJsonResponse(final int status, final String body) {
80 final String callback = LaRequestUtil.getRequest().getParameter("callback");
81 final boolean isJsonp = StringUtil.isNotBlank(callback);
82
83 final StringBuilder buf = new StringBuilder(1000);
84 if (isJsonp) {
85 buf.append(escapeCallbackName(callback));
86 buf.append('(');
87 }
88 buf.append("{\"response\":");
89 buf.append("{\"version\":");
90 buf.append(Constants.WEB_API_VERSION);
91 buf.append(',');
92 buf.append("\"status\":");
93 buf.append(status);
94 if (StringUtil.isNotBlank(body)) {
95 buf.append(',');
96 buf.append(body);
97 }
98 buf.append('}');
99 buf.append('}');
100 if (isJsonp) {
101 buf.append(')');
102 }
103 write(buf.toString(), "text/javascript+json", Constants.UTF_8);
104
105 }
106
107 protected String escapeCallbackName(final String callbackName) {
108 return "/**/" + callbackName.replaceAll("[^0-9a-zA-Z_\\$\\.]", StringUtil.EMPTY);
109 }
110
111 protected String escapeJson(final Object obj) {
112 if (obj == null) {
113 return "null";
114 }
115
116 final StringBuilder buf = new StringBuilder(255);
117 if (obj instanceof String[]) {
118 buf.append('[');
119 boolean first = true;
120 for (final Object child : (String[]) obj) {
121 if (first) {
122 first = false;
123 } else {
124 buf.append(',');
125 }
126 buf.append(escapeJson(child));
127 }
128 buf.append(']');
129 } else if (obj instanceof List<?>) {
130 buf.append('[');
131 boolean first = true;
132 for (final Object child : (List<?>) obj) {
133 if (first) {
134 first = false;
135 } else {
136 buf.append(',');
137 }
138 buf.append(escapeJson(child));
139 }
140 buf.append(']');
141 } else if (obj instanceof Map<?, ?>) {
142 buf.append('{');
143 boolean first = true;
144 for (final Map.Entry<?, ?> entry : ((Map<?, ?>) obj).entrySet()) {
145 if (first) {
146 first = false;
147 } else {
148 buf.append(',');
149 }
150 buf.append(escapeJson(entry.getKey())).append(':').append(escapeJson(entry.getValue()));
151 }
152 buf.append('}');
153 } else if (obj instanceof Integer) {
154 buf.append(((Integer) obj).intValue());
155 } else if (obj instanceof Long) {
156 buf.append(((Long) obj).longValue());
157 } else if (obj instanceof Float) {
158 buf.append(((Float) obj).floatValue());
159 } else if (obj instanceof Double) {
160 buf.append(((Double) obj).doubleValue());
161 } else if (obj instanceof Boolean) {
162 buf.append(obj.toString());
163 } else if (obj instanceof Date) {
164 final SimpleDateFormat sdf = new SimpleDateFormat(CoreLibConstants.DATE_FORMAT_ISO_8601_EXTEND, Locale.ROOT);
165 buf.append('\"').append(StringEscapeUtils.escapeJson(sdf.format(obj))).append('\"');
166 } else {
167 buf.append('\"').append(StringEscapeUtils.escapeJson(obj.toString())).append('\"');
168 }
169 return buf.toString();
170 }
171
172 }