001    /**
002     * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
013     */
014    
015    package com.liferay.util.axis;
016    
017    import com.liferay.portal.kernel.log.Log;
018    import com.liferay.portal.kernel.log.LogFactoryUtil;
019    import com.liferay.portal.kernel.servlet.StringServletResponse;
020    import com.liferay.portal.kernel.servlet.UncommittedServletResponse;
021    import com.liferay.portal.kernel.util.ContentTypes;
022    import com.liferay.portal.kernel.util.GetterUtil;
023    import com.liferay.portal.kernel.util.ReflectionUtil;
024    import com.liferay.portal.kernel.util.ServerDetector;
025    import com.liferay.portal.kernel.util.StringPool;
026    import com.liferay.portal.kernel.util.StringUtil;
027    import com.liferay.portal.kernel.xml.Document;
028    import com.liferay.portal.kernel.xml.SAXReaderUtil;
029    import com.liferay.util.servlet.ServletResponseUtil;
030    
031    import java.io.IOException;
032    
033    import java.lang.reflect.Field;
034    
035    import javax.servlet.ServletConfig;
036    import javax.servlet.ServletException;
037    import javax.servlet.http.HttpServletRequest;
038    import javax.servlet.http.HttpServletResponse;
039    
040    import org.apache.axis.utils.cache.MethodCache;
041    
042    /**
043     * @author Brian Wing Shun Chan
044     */
045    public class AxisServlet extends org.apache.axis.transport.http.AxisServlet {
046    
047            public void destroy() {
048                    if (ServerDetector.isWebLogic()) {
049                            doDestroy();
050                    }
051                    else {
052                            DestroyThread destroyThread = new DestroyThread();
053    
054                            destroyThread.start();
055    
056                            try {
057                                    destroyThread.join();
058                            }
059                            catch (InterruptedException ie) {
060                                    throw new RuntimeException(ie);
061                            }
062    
063                            Exception e = destroyThread.getException();
064    
065                            if (e != null) {
066                                    if (e instanceof RuntimeException) {
067                                            throw (RuntimeException)e;
068                                    }
069                                    else {
070                                            throw new RuntimeException(e);
071                                    }
072                            }
073                    }
074            }
075    
076            public void init(ServletConfig servletConfig) throws ServletException {
077                    _servletConfig = servletConfig;
078    
079                    if (ServerDetector.isWebLogic()) {
080                            doInit();
081                    }
082                    else {
083                            InitThread initThread = new InitThread();
084    
085                            initThread.start();
086    
087                            try {
088                                    initThread.join();
089                            }
090                            catch (InterruptedException ie) {
091                                    throw new ServletException(ie);
092                            }
093    
094                            Exception e = initThread.getException();
095    
096                            if (e != null) {
097                                    if (e instanceof ServletException) {
098                                            throw (ServletException)e;
099                                    }
100                                    else {
101                                            throw new ServletException(e);
102                                    }
103                            }
104                    }
105            }
106    
107            public void service(
108                            HttpServletRequest request, HttpServletResponse response)
109                    throws IOException, ServletException {
110    
111                    try {
112                            if (!_ready) {
113                                    return;
114                            }
115    
116                            StringServletResponse stringResponse = new StringServletResponse(
117                                    response);
118    
119                            super.service(request, stringResponse);
120    
121                            String contentType = stringResponse.getContentType();
122    
123                            response.setContentType(contentType);
124    
125                            String content = stringResponse.getString();
126    
127                            if (_fixContent) {
128                                    if (contentType.contains(ContentTypes.TEXT_HTML)) {
129                                            content = _HTML_TOP_WRAPPER.concat(content).concat(
130                                                    _HTML_BOTTOM_WRAPPER);
131                                    }
132                                    else if (contentType.contains(ContentTypes.TEXT_XML)) {
133                                            content = fixXml(content);
134                                    }
135                            }
136    
137                            ServletResponseUtil.write(
138                                    new UncommittedServletResponse(response),
139                                    content.getBytes(StringPool.UTF8));
140                    }
141                    catch (IOException ioe) {
142                            throw ioe;
143                    }
144                    catch (ServletException se) {
145                            throw se;
146                    }
147                    catch (Exception e) {
148                            throw new ServletException(e);
149                    }
150                    finally {
151                            try {
152                                    ThreadLocal<?> cache = (ThreadLocal<?>)_cacheField.get(null);
153    
154                                    if (cache != null) {
155                                            cache.remove();
156                                    }
157                            }
158                            catch (Exception e) {
159                                    _log.error(e, e);
160                            }
161                    }
162            }
163    
164            protected void doDestroy() {
165                    _ready = false;
166    
167                    super.destroy();
168            }
169    
170            protected void doInit() throws ServletException {
171                    super.init(_servletConfig);
172    
173                    _fixContent = GetterUtil.getBoolean(
174                            _servletConfig.getInitParameter("fix-content"), true);
175    
176                    _ready = true;
177            }
178    
179            protected String fixXml(String xml) throws Exception {
180                    if (xml.indexOf("<wsdl:definitions") == -1) {
181                            return xml;
182                    }
183    
184                    xml = StringUtil.replace(
185                            xml,
186                            new String[] {
187                                    "\r\n",
188                                    "\n",
189                                    "  ",
190                                    "> <",
191                                    _INCORRECT_LONG_ARRAY,
192                                    _INCORRECT_STRING_ARRAY
193                            },
194                            new String[] {
195                                    StringPool.BLANK,
196                                    StringPool.BLANK,
197                                    StringPool.BLANK,
198                                    "><",
199                                    _CORRECT_LONG_ARRAY,
200                                    _CORRECT_STRING_ARRAY
201                            });
202    
203                    Document document = SAXReaderUtil.read(xml);
204    
205                    return document.formattedString();
206            }
207    
208            private static final String _CORRECT_LONG_ARRAY =
209                    "<complexType name=\"ArrayOf_xsd_long\"><complexContent>" +
210                            "<restriction base=\"soapenc:Array\"><attribute ref=\"soapenc:" +
211                                    "arrayType\" wsdl:arrayType=\"soapenc:long[]\"/>" +
212                                            "</restriction></complexContent></complexType>";
213    
214            private static final String _CORRECT_STRING_ARRAY =
215                    "<complexType name=\"ArrayOf_xsd_string\"><complexContent>" +
216                            "<restriction base=\"soapenc:Array\"><attribute ref=\"soapenc:" +
217                                    "arrayType\" wsdl:arrayType=\"soapenc:string[]\"/>" +
218                                            "</restriction></complexContent></complexType>";
219    
220            private static final String _HTML_BOTTOM_WRAPPER = "</body></html>";
221    
222            private static final String _HTML_TOP_WRAPPER = "<html><body>";
223    
224            private static final String _INCORRECT_LONG_ARRAY =
225                    "<complexType name=\"ArrayOf_xsd_long\"><simpleContent><extension/>" +
226                            "</simpleContent></complexType>";
227    
228            private static final String _INCORRECT_STRING_ARRAY =
229                    "<complexType name=\"ArrayOf_xsd_string\"><simpleContent><extension/>" +
230                            "</simpleContent></complexType>";
231    
232            private static Log _log = LogFactoryUtil.getLog(AxisServlet.class);
233    
234            private static Field _cacheField;
235    
236            private boolean _fixContent;
237            private boolean _ready;
238            private ServletConfig _servletConfig;
239    
240            private class DestroyThread extends Thread {
241    
242                    public DestroyThread() {
243                            setDaemon(true);
244                    }
245    
246                    public Exception getException() {
247                            return _exception;
248                    }
249    
250                    public void run() {
251                            try {
252                                    doDestroy();
253                            }
254                            catch (Exception e) {
255                                    _exception = e;
256                            }
257                    }
258    
259                    private Exception _exception;
260    
261            }
262    
263            private class InitThread extends Thread {
264    
265                    public InitThread() {
266                            setDaemon(true);
267                    }
268    
269                    public Exception getException() {
270                            return _exception;
271                    }
272    
273                    public void run() {
274                            try {
275                                    doInit();
276                            }
277                            catch (Exception e) {
278                                    _exception = e;
279                            }
280                    }
281    
282                    private Exception _exception;
283    
284            }
285    
286            static {
287                    try {
288                            _cacheField = ReflectionUtil.getDeclaredField(
289                                    MethodCache.class, "cache");
290                    }
291                    catch (Exception e) {
292                            _log.error(e, e);
293                    }
294            }
295    
296    }