001
014
015 package com.liferay.util.axis;
016
017 import com.liferay.portal.kernel.exception.LoggedExceptionInInitializerError;
018 import com.liferay.portal.kernel.log.Log;
019 import com.liferay.portal.kernel.log.LogFactoryUtil;
020 import com.liferay.portal.kernel.servlet.BufferCacheServletResponse;
021 import com.liferay.portal.kernel.servlet.ServletResponseUtil;
022 import com.liferay.portal.kernel.servlet.UncommittedServletResponse;
023 import com.liferay.portal.kernel.util.ContentTypes;
024 import com.liferay.portal.kernel.util.GetterUtil;
025 import com.liferay.portal.kernel.util.ReflectionUtil;
026 import com.liferay.portal.kernel.util.ServerDetector;
027 import com.liferay.portal.kernel.util.StringBundler;
028 import com.liferay.portal.kernel.util.StringPool;
029 import com.liferay.portal.kernel.util.StringUtil;
030 import com.liferay.portal.kernel.xml.Document;
031 import com.liferay.portal.kernel.xml.UnsecureSAXReaderUtil;
032
033 import java.io.IOException;
034
035 import java.lang.reflect.Field;
036
037 import javax.servlet.ServletConfig;
038 import javax.servlet.ServletException;
039 import javax.servlet.http.HttpServletRequest;
040 import javax.servlet.http.HttpServletResponse;
041
042 import org.apache.axis.utils.cache.MethodCache;
043
044
047 public class AxisServlet extends org.apache.axis.transport.http.AxisServlet {
048
049 @Override
050 public void destroy() {
051 if (ServerDetector.isWebLogic()) {
052 doDestroy();
053 }
054 else {
055 Thread currentThread = Thread.currentThread();
056
057 ClassLoader contextClassLoader =
058 currentThread.getContextClassLoader();
059
060 Class<?> clazz = getClass();
061
062 currentThread.setContextClassLoader(clazz.getClassLoader());
063
064 try {
065 DestroyThread destroyThread = new DestroyThread();
066
067 destroyThread.start();
068
069 try {
070 destroyThread.join();
071 }
072 catch (InterruptedException ie) {
073 throw new RuntimeException(ie);
074 }
075
076 Exception e = destroyThread.getException();
077
078 if (e != null) {
079 if (e instanceof RuntimeException) {
080 throw (RuntimeException)e;
081 }
082 else {
083 throw new RuntimeException(e);
084 }
085 }
086 }
087 finally {
088 currentThread.setContextClassLoader(contextClassLoader);
089 }
090 }
091 }
092
093 @Override
094 public void init(ServletConfig servletConfig) throws ServletException {
095 _servletConfig = servletConfig;
096
097 StringBundler sb = new StringBundler(9);
098
099 sb.append("<complexType abstract=\"true\" name=\"OrderByComparator\">");
100 sb.append("<sequence><element name=\"ascending\" ");
101 sb.append("type=\"xsd:boolean\"/><element name=\"orderBy\" ");
102 sb.append("nillable=\"true\" type=\"soapenc:string\"/><element ");
103 sb.append("name=\"orderByConditionFields\" nillable=\"true\" ");
104 sb.append("type=\"impl:ArrayOf_xsd_string\"/><element ");
105 sb.append("name=\"orderByFields\" nillable=\"true\" ");
106 sb.append("type=\"impl:ArrayOf_xsd_string\"/></sequence>");
107 sb.append("</complexType>");
108
109 _correctOrderByComparator = sb.toString();
110
111 sb = new StringBundler(5);
112
113 sb.append("<complexType name=\"ArrayOf_xsd_long\"><complexContent>");
114 sb.append("<restriction base=\"soapenc:Array\"><attribute ");
115 sb.append("ref=\"soapenc:arrayType\" ");
116 sb.append("wsdl:arrayType=\"soapenc:long[]\"/></restriction>");
117 sb.append("</complexContent></complexType>");
118
119 _correctLongArray = sb.toString();
120
121 sb = new StringBundler(5);
122
123 sb.append("<complexType name=\"ArrayOf_xsd_string\"><complexContent>");
124 sb.append("<restriction base=\"soapenc:Array\"><attribute ");
125 sb.append("ref=\"soapenc:arrayType\" ");
126 sb.append("wsdl:arrayType=\"soapenc:string[]\"/></restriction>");
127 sb.append("</complexContent></complexType>");
128
129 _correctStringArray = sb.toString();
130
131 sb = new StringBundler(2);
132
133 sb.append("<complexType name=\"OrderByComparator\"><simpleContent>");
134 sb.append("<extension/></simpleContent></complexType>");
135
136 _incorrectOrderByComparator = sb.toString();
137
138 sb = new StringBundler(2);
139
140 sb.append("<complexType name=\"ArrayOf_xsd_long\"><simpleContent>");
141 sb.append("<extension/></simpleContent></complexType>");
142
143 _incorrectLongArray = sb.toString();
144
145 sb = new StringBundler(2);
146
147 sb.append("<complexType name=\"ArrayOf_xsd_string\"><simpleContent>");
148 sb.append("<extension/></simpleContent></complexType>");
149
150 _incorrectStringArray = sb.toString();
151
152 if (ServerDetector.isResin() || ServerDetector.isWebLogic()) {
153 doInit();
154 }
155 else {
156 InitThread initThread = new InitThread();
157
158 initThread.start();
159
160 try {
161 initThread.join();
162 }
163 catch (InterruptedException ie) {
164 throw new ServletException(ie);
165 }
166
167 Exception e = initThread.getException();
168
169 if (e != null) {
170 if (e instanceof ServletException) {
171 throw (ServletException)e;
172 }
173 else {
174 throw new ServletException(e);
175 }
176 }
177 }
178 }
179
180 @Override
181 public void service(
182 HttpServletRequest request, HttpServletResponse response)
183 throws IOException, ServletException {
184
185 try {
186 if (!_ready) {
187 return;
188 }
189
190 BufferCacheServletResponse bufferCacheServletResponse =
191 new BufferCacheServletResponse(response);
192
193 super.service(request, bufferCacheServletResponse);
194
195 String contentType = bufferCacheServletResponse.getContentType();
196
197 response.setContentType(contentType);
198
199 String content = bufferCacheServletResponse.getString();
200
201 if (_fixContent) {
202 if (contentType.contains(ContentTypes.TEXT_HTML)) {
203 content = _HTML_TOP_WRAPPER.concat(content).concat(
204 _HTML_BOTTOM_WRAPPER);
205 }
206 else if (contentType.contains(ContentTypes.TEXT_XML)) {
207 content = fixXml(content);
208 }
209 }
210
211 ServletResponseUtil.write(
212 new UncommittedServletResponse(response),
213 content.getBytes(StringPool.UTF8));
214 }
215 catch (IOException ioe) {
216 throw ioe;
217 }
218 catch (ServletException se) {
219 throw se;
220 }
221 catch (Exception e) {
222 throw new ServletException(e);
223 }
224 finally {
225 try {
226 ThreadLocal<?> cache = (ThreadLocal<?>)_CACHE_FIELD.get(null);
227
228 if (cache != null) {
229 cache.remove();
230 }
231 }
232 catch (Exception e) {
233 _log.error(e, e);
234 }
235 }
236 }
237
238 protected void doDestroy() {
239 _ready = false;
240
241 super.destroy();
242 }
243
244 protected void doInit() throws ServletException {
245 super.init(_servletConfig);
246
247 _fixContent = GetterUtil.getBoolean(
248 _servletConfig.getInitParameter("fix-content"), true);
249
250 _ready = true;
251 }
252
253 protected String fixXml(String xml) throws Exception {
254 if (!xml.contains("<wsdl:definitions")) {
255 return xml;
256 }
257
258 xml = StringUtil.replace(
259 xml,
260 new String[] {
261 "\r\n", "\n", " ", "> <", _incorrectOrderByComparator,
262 _incorrectLongArray, _incorrectStringArray
263 },
264 new String[] {
265 StringPool.BLANK, StringPool.BLANK, StringPool.BLANK, "><",
266 _correctOrderByComparator, _correctLongArray,
267 _correctStringArray
268 });
269
270 Document document = UnsecureSAXReaderUtil.read(xml);
271
272 return document.formattedString();
273 }
274
275 private static final Field _CACHE_FIELD;
276
277 private static final String _HTML_BOTTOM_WRAPPER = "</body></html>";
278
279 private static final String _HTML_TOP_WRAPPER = "<html><body>";
280
281 private static final Log _log = LogFactoryUtil.getLog(AxisServlet.class);
282
283 static {
284 try {
285 _CACHE_FIELD = ReflectionUtil.getDeclaredField(
286 MethodCache.class, "cache");
287 }
288 catch (Exception e) {
289 throw new LoggedExceptionInInitializerError(e);
290 }
291 }
292
293 private String _correctLongArray;
294 private String _correctOrderByComparator;
295 private String _correctStringArray;
296 private boolean _fixContent;
297 private String _incorrectLongArray;
298 private String _incorrectOrderByComparator;
299 private String _incorrectStringArray;
300 private boolean _ready;
301 private ServletConfig _servletConfig;
302
303 private class DestroyThread extends Thread {
304
305 public DestroyThread() {
306 setDaemon(true);
307 }
308
309 public Exception getException() {
310 return _exception;
311 }
312
313 @Override
314 public void run() {
315 try {
316 doDestroy();
317 }
318 catch (Exception e) {
319 _exception = e;
320 }
321 }
322
323 private Exception _exception;
324
325 }
326
327 private class InitThread extends Thread {
328
329 public InitThread() {
330 setDaemon(true);
331 }
332
333 public Exception getException() {
334 return _exception;
335 }
336
337 @Override
338 public void run() {
339 try {
340 doInit();
341 }
342 catch (Exception e) {
343 _exception = e;
344 }
345 }
346
347 private Exception _exception;
348
349 }
350
351 }