001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common Development
008: * and Distribution License("CDDL") (collectively, the "License"). You
009: * may not use this file except in compliance with the License. You can obtain
010: * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
011: * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific
012: * language governing permissions and limitations under the License.
013: *
014: * When distributing the software, include this License Header Notice in each
015: * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
016: * Sun designates this particular file as subject to the "Classpath" exception
017: * as provided by Sun in the GPL Version 2 section of the License file that
018: * accompanied this code. If applicable, add the following below the License
019: * Header, with the fields enclosed by brackets [] replaced by your own
020: * identifying information: "Portions Copyrighted [year]
021: * [name of copyright owner]"
022: *
023: * Contributor(s):
024: *
025: * If you wish your version of this file to be governed by only the CDDL or
026: * only the GPL Version 2, indicate your decision by adding "[Contributor]
027: * elects to include this software in this distribution under the [CDDL or GPL
028: * Version 2] license." If you don't indicate a single choice of license, a
029: * recipient has the option to distribute your version of this file under
030: * either the CDDL, the GPL Version 2 or to extend the choice of license to
031: * its licensees as provided above. However, if you add GPL Version 2 code
032: * and therefore, elected the GPL Version 2 license, then the option applies
033: * only if the new code is made subject to such option by the copyright
034: * holder.
035: */
036:
037: package com.sun.xml.ws.transport.http;
038:
039: import com.sun.istack.NotNull;
040: import com.sun.istack.Nullable;
041: import com.sun.xml.ws.api.PropertySet;
042: import com.sun.xml.ws.api.message.ExceptionHasMessage;
043: import com.sun.xml.ws.api.message.Message;
044: import com.sun.xml.ws.api.message.Packet;
045: import com.sun.xml.ws.api.pipe.Codec;
046: import com.sun.xml.ws.api.pipe.ContentType;
047: import com.sun.xml.ws.api.server.AbstractServerAsyncTransport;
048: import com.sun.xml.ws.api.server.Adapter;
049: import com.sun.xml.ws.api.server.BoundEndpoint;
050: import com.sun.xml.ws.api.server.DocumentAddressResolver;
051: import com.sun.xml.ws.api.server.EndpointComponent;
052: import com.sun.xml.ws.api.server.Module;
053: import com.sun.xml.ws.api.server.PortAddressResolver;
054: import com.sun.xml.ws.api.server.SDDocument;
055: import com.sun.xml.ws.api.server.ServiceDefinition;
056: import com.sun.xml.ws.api.server.TransportBackChannel;
057: import com.sun.xml.ws.api.server.WSEndpoint;
058: import com.sun.xml.ws.api.server.WebServiceContextDelegate;
059: import com.sun.xml.ws.resources.WsservletMessages;
060: import com.sun.xml.ws.server.ServerRtException;
061: import com.sun.xml.ws.server.UnsupportedMediaException;
062: import com.sun.xml.ws.util.ByteArrayBuffer;
063:
064: import javax.xml.ws.Binding;
065: import javax.xml.ws.WebServiceException;
066: import javax.xml.ws.http.HTTPBinding;
067: import java.io.IOException;
068: import java.io.InputStream;
069: import java.io.OutputStream;
070: import java.io.OutputStreamWriter;
071: import java.io.PrintWriter;
072: import java.net.HttpURLConnection;
073: import java.util.Collections;
074: import java.util.HashMap;
075: import java.util.List;
076: import java.util.Map;
077: import java.util.Map.Entry;
078: import java.util.TreeMap;
079: import java.util.logging.Level;
080: import java.util.logging.Logger;
081:
082: /**
083: * {@link Adapter} that receives messages in HTTP.
084: *
085: * <p>
086: * This object also assigns unique query string (such as "xsd=1") to
087: * each {@link SDDocument} so that they can be served by HTTP GET requests.
088: *
089: * @author Kohsuke Kawaguchi
090: * @author Jitendra Kotamraju
091: */
092: public class HttpAdapter extends Adapter<HttpAdapter.HttpToolkit> {
093:
094: /**
095: * {@link SDDocument}s keyed by the query string like "?abc".
096: * Used for serving documents via HTTP GET.
097: *
098: * Empty if the endpoint doesn't have {@link ServiceDefinition}.
099: * Read-only.
100: */
101: public final Map<String, SDDocument> wsdls;
102:
103: /**
104: * Reverse map of {@link #wsdls}. Read-only.
105: */
106: public final Map<SDDocument, String> revWsdls;
107:
108: public final HttpAdapterList<? extends HttpAdapter> owner;
109:
110: /**
111: * Servlet URL pattern with which this {@link HttpAdapter} is associated.
112: */
113: public final String urlPattern;
114:
115: /**
116: * Creates a lone {@link HttpAdapter} that does not know of any other
117: * {@link HttpAdapter}s.
118: *
119: * This is convenient for creating an {@link HttpAdapter} for an environment
120: * where they don't know each other (such as JavaSE deployment.)
121: *
122: * @param endpoint web service endpoint
123: * @return singe adapter to process HTTP messages
124: */
125: public static HttpAdapter createAlone(WSEndpoint endpoint) {
126: return new DummyList().createAdapter("", "", endpoint);
127: }
128:
129: /**
130: * @deprecated
131: * remove as soon as we can update the test util.
132: */
133: protected HttpAdapter(WSEndpoint endpoint,
134: HttpAdapterList<? extends HttpAdapter> owner) {
135: this (endpoint, owner, null);
136: }
137:
138: protected HttpAdapter(WSEndpoint endpoint,
139: HttpAdapterList<? extends HttpAdapter> owner,
140: String urlPattern) {
141: super (endpoint);
142: this .owner = owner;
143: this .urlPattern = urlPattern;
144:
145: // fill in WSDL map
146: ServiceDefinition sdef = this .endpoint.getServiceDefinition();
147: if (sdef == null) {
148: wsdls = Collections.emptyMap();
149: revWsdls = Collections.emptyMap();
150: } else {
151: wsdls = new HashMap<String, SDDocument>(); // wsdl=1 --> Doc
152: // Sort WSDL, Schema documents based on SystemId so that the same
153: // document gets wsdl=x mapping
154: Map<String, SDDocument> systemIds = new TreeMap<String, SDDocument>();
155: for (SDDocument sdd : sdef) {
156: if (sdd == sdef.getPrimary()) { // No sorting for Primary WSDL
157: wsdls.put("wsdl", sdd);
158: wsdls.put("WSDL", sdd);
159: } else {
160: systemIds.put(sdd.getURL().toString(), sdd);
161: }
162: }
163:
164: int wsdlnum = 1;
165: int xsdnum = 1;
166: for (Map.Entry<String, SDDocument> e : systemIds.entrySet()) {
167: SDDocument sdd = e.getValue();
168: if (sdd.isWSDL()) {
169: wsdls.put("wsdl=" + (wsdlnum++), sdd);
170: }
171: if (sdd.isSchema()) {
172: wsdls.put("xsd=" + (xsdnum++), sdd);
173: }
174: }
175:
176: revWsdls = new HashMap<SDDocument, String>(); // Doc --> wsdl=1
177: for (Entry<String, SDDocument> e : wsdls.entrySet()) {
178: if (!e.getKey().equals("WSDL")) { // map Doc --> wsdl, not WSDL
179: revWsdls.put(e.getValue(), e.getKey());
180: }
181: }
182: }
183: }
184:
185: /**
186: * Returns the "/abc/def/ghi" portion if
187: * the URL pattern is "/abc/def/ghi/*".
188: */
189: public String getValidPath() {
190: if (urlPattern.endsWith("/*")) {
191: return urlPattern.substring(0, urlPattern.length() - 2);
192: } else {
193: return urlPattern;
194: }
195: }
196:
197: protected HttpToolkit createToolkit() {
198: return new HttpToolkit();
199: }
200:
201: /**
202: * Receives the incoming HTTP connection and dispatches
203: * it to JAX-WS. This method returns when JAX-WS completes
204: * processing the request and the whole reply is written
205: * to {@link WSHTTPConnection}.
206: *
207: * <p>
208: * This method is invoked by the lower-level HTTP stack,
209: * and "connection" here is an HTTP connection.
210: *
211: * <p>
212: * To populate a request {@link Packet} with more info,
213: * define {@link PropertySet.Property properties} on
214: * {@link WSHTTPConnection}.
215: *
216: * @param connection to receive/send HTTP messages for web service endpoints
217: * @throws IOException when I/O errors happen
218: */
219: public void handle(@NotNull
220: WSHTTPConnection connection) throws IOException {
221: if (connection.getRequestMethod().equals("GET")) {
222: // metadata query. let the interceptor run
223: for (EndpointComponent c : endpoint.getComponentRegistry()) {
224: HttpMetadataPublisher spi = c
225: .getSPI(HttpMetadataPublisher.class);
226: if (spi != null
227: && spi.handleMetadataRequest(this , connection))
228: return; // handled
229: }
230:
231: if (isMetadataQuery(connection.getQueryString())) {
232: // Sends published WSDL and schema documents as the default action.
233: publishWSDL(connection);
234: return;
235: }
236:
237: Binding binding = getEndpoint().getBinding();
238: if (!(binding instanceof HTTPBinding)) {
239: // Writes HTML page with all the endpoint descriptions
240: writeWebServicesHtmlPage(connection);
241: return;
242: }
243: }
244:
245: // normal request handling
246: HttpToolkit tk = pool.take();
247: try {
248: tk.handle(connection);
249: } finally {
250: pool.recycle(tk);
251: }
252: }
253:
254: /**
255: *
256: * @param con
257: * @param codec
258: * @return
259: * @throws IOException
260: * ExceptionHasMessage exception that contains particular fault message
261: * UnsupportedMediaException to indicate to send 415 error code
262: */
263: private Packet decodePacket(@NotNull
264: WSHTTPConnection con, @NotNull
265: Codec codec) throws IOException {
266: String ct = con.getRequestHeader("Content-Type");
267: InputStream in = con.getInput();
268: Packet packet = new Packet();
269: packet.soapAction = con.getRequestHeader("SOAPAction");
270: packet.wasTransportSecure = con.isSecure();
271: packet.acceptableMimeTypes = con.getRequestHeader("Accept");
272: packet.addSatellite(con);
273: packet.transportBackChannel = new Oneway(con);
274: packet.webServiceContextDelegate = con
275: .getWebServiceContextDelegate();
276:
277: if (dump) {
278: ByteArrayBuffer buf = new ByteArrayBuffer();
279: buf.write(in);
280: dump(buf, "HTTP request", con.getRequestHeaders());
281: in = buf.newInputStream();
282: }
283: codec.decode(in, ct, packet);
284: return packet;
285: }
286:
287: private void encodePacket(@NotNull
288: Packet packet, @NotNull
289: WSHTTPConnection con, @NotNull
290: Codec codec) throws IOException {
291: if (con.isClosed()) {
292: return; // Connection is already closed
293: }
294: Message responseMessage = packet.getMessage();
295: if (responseMessage == null) {
296: if (!con.isClosed()) {
297: // set the response code if not already set
298: // for example, 415 may have been set earlier for Unsupported Content-Type
299: if (con.getStatus() == 0)
300: con.setStatus(WSHTTPConnection.ONEWAY);
301: // close the response channel now
302: try {
303: con.getOutput().close(); // no payload
304: } catch (IOException e) {
305: throw new WebServiceException(e);
306: }
307: }
308: } else {
309: if (con.getStatus() == 0) {
310: // if the appliation didn't set the status code,
311: // set the default one.
312: con
313: .setStatus(responseMessage.isFault() ? HttpURLConnection.HTTP_INTERNAL_ERROR
314: : HttpURLConnection.HTTP_OK);
315: }
316:
317: ContentType contentType = codec
318: .getStaticContentType(packet);
319: if (contentType != null) {
320: con.setContentTypeResponseHeader(contentType
321: .getContentType());
322: OutputStream os = con.getProtocol().contains("1.1") ? con
323: .getOutput()
324: : new Http10OutputStream(con);
325: if (dump) {
326: ByteArrayBuffer buf = new ByteArrayBuffer();
327: codec.encode(packet, buf);
328: dump(buf, "HTTP response " + con.getStatus(), con
329: .getResponseHeaders());
330: buf.writeTo(os);
331: } else {
332: codec.encode(packet, os);
333: }
334: os.close();
335: } else {
336: ByteArrayBuffer buf = new ByteArrayBuffer();
337: contentType = codec.encode(packet, buf);
338: con.setContentTypeResponseHeader(contentType
339: .getContentType());
340: if (dump) {
341: dump(buf, "HTTP response " + con.getStatus(), con
342: .getResponseHeaders());
343: }
344: OutputStream os = con.getOutput();
345: buf.writeTo(os);
346: os.close();
347: }
348: }
349: }
350:
351: public void invokeAsync(final WSHTTPConnection con)
352: throws IOException {
353: final HttpToolkit tk = pool.take();
354: final Packet request;
355: try {
356: request = decodePacket(con, tk.codec);
357: } catch (ExceptionHasMessage e) {
358: LOGGER.log(Level.SEVERE, e.getMessage(), e);
359: Packet response = new Packet();
360: response.setMessage(e.getFaultMessage());
361: encodePacket(response, con, tk.codec);
362: pool.recycle(tk);
363: con.close();
364: return;
365: } catch (UnsupportedMediaException e) {
366: LOGGER.log(Level.SEVERE, e.getMessage(), e);
367: Packet response = new Packet();
368: con.setStatus(WSHTTPConnection.UNSUPPORTED_MEDIA);
369: encodePacket(response, con, tk.codec);
370: pool.recycle(tk);
371: con.close();
372: return;
373: }
374:
375: endpoint.schedule(request, new WSEndpoint.CompletionCallback() {
376: public void onCompletion(@NotNull
377: Packet response) {
378: try {
379: try {
380: encodePacket(response, con, tk.codec);
381: } catch (IOException ioe) {
382: LOGGER.log(Level.SEVERE, ioe.getMessage(), ioe);
383: }
384: pool.recycle(tk);
385: } finally {
386: con.close();
387: }
388: }
389: });
390: }
391:
392: final class AsyncTransport extends
393: AbstractServerAsyncTransport<WSHTTPConnection> {
394:
395: public AsyncTransport() {
396: super (endpoint);
397: }
398:
399: public void handleAsync(WSHTTPConnection con)
400: throws IOException {
401: super .handle(con);
402: }
403:
404: protected void encodePacket(WSHTTPConnection con, @NotNull
405: Packet packet, @NotNull
406: Codec codec) throws IOException {
407: HttpAdapter.this .encodePacket(packet, con, codec);
408: }
409:
410: protected @Nullable
411: String getAcceptableMimeTypes(WSHTTPConnection con) {
412: return null;
413: }
414:
415: protected @Nullable
416: TransportBackChannel getTransportBackChannel(
417: WSHTTPConnection con) {
418: return new Oneway(con);
419: }
420:
421: protected @NotNull
422: PropertySet getPropertySet(WSHTTPConnection con) {
423: return con;
424: }
425:
426: protected @NotNull
427: WebServiceContextDelegate getWebServiceContextDelegate(
428: WSHTTPConnection con) {
429: return con.getWebServiceContextDelegate();
430: }
431: }
432:
433: final class Oneway implements TransportBackChannel {
434: WSHTTPConnection con;
435:
436: Oneway(WSHTTPConnection con) {
437: this .con = con;
438: }
439:
440: public void close() {
441: if (!con.isClosed()) {
442: // close the response channel now
443: con.setStatus(WSHTTPConnection.ONEWAY);
444: try {
445: con.getOutput().close(); // no payload
446: } catch (IOException e) {
447: throw new WebServiceException(e);
448: }
449: con.close();
450: }
451: }
452: }
453:
454: final class HttpToolkit extends Adapter.Toolkit {
455: public void handle(WSHTTPConnection con) throws IOException {
456: try {
457: Packet packet = new Packet();
458: try {
459: packet = decodePacket(con, codec);
460: } catch (ExceptionHasMessage e) {
461: LOGGER.log(Level.SEVERE, e.getMessage(), e);
462: packet.setMessage(e.getFaultMessage());
463: } catch (UnsupportedMediaException e) {
464: LOGGER.log(Level.SEVERE, e.getMessage(), e);
465: con.setStatus(WSHTTPConnection.UNSUPPORTED_MEDIA);
466: } catch (ServerRtException e) {
467: LOGGER.log(Level.SEVERE, e.getMessage(), e);
468: }
469: if (packet.getMessage() != null
470: && !packet.getMessage().isFault()) {
471: try {
472: packet = head.process(packet, con
473: .getWebServiceContextDelegate(),
474: packet.transportBackChannel);
475: } catch (Exception e) {
476: LOGGER.log(Level.SEVERE, e.getMessage(), e);
477: if (!con.isClosed()) {
478: writeInternalServerError(con);
479: }
480: return;
481: }
482: }
483: encodePacket(packet, con, codec);
484: } finally {
485: if (!con.isClosed()) {
486: con.close();
487: }
488: }
489: }
490: }
491:
492: /**
493: * Returns true if the given query string is for metadata request.
494: *
495: * @param query
496: * String like "xsd=1" or "perhaps=some&unrelated=query".
497: * Can be null.
498: * @return true for metadata requests
499: * false for web service requests
500: */
501: private boolean isMetadataQuery(String query) {
502: // we intentionally return true even if documents don't exist,
503: // so that they get 404.
504: return query != null
505: && (query.equals("WSDL") || query.startsWith("wsdl") || query
506: .startsWith("xsd="));
507: }
508:
509: /**
510: * Sends out the WSDL (and other referenced documents)
511: * in response to the GET requests to URLs like "?wsdl" or "?xsd=2".
512: *
513: * @param con
514: * The connection to which the data will be sent.
515: *
516: * @throws IOException when I/O errors happen
517: */
518: public void publishWSDL(@NotNull
519: WSHTTPConnection con) throws IOException {
520: SDDocument doc = wsdls.get(con.getQueryString());
521: if (doc == null) {
522: writeNotFoundErrorPage(con, "Invalid Request");
523: return;
524: }
525:
526: con.setStatus(HttpURLConnection.HTTP_OK);
527: con.setContentTypeResponseHeader("text/xml;charset=\"utf-8\"");
528:
529: OutputStream os = con.getProtocol().contains("1.1") ? con
530: .getOutput() : new Http10OutputStream(con);
531:
532: final PortAddressResolver portAddressResolver = owner
533: .createPortAddressResolver(con.getBaseAddress());
534: final String address = portAddressResolver.getAddressFor(
535: endpoint.getServiceName(), endpoint.getPortName()
536: .getLocalPart());
537: assert address != null;
538: DocumentAddressResolver resolver = new DocumentAddressResolver() {
539: public String getRelativeAddressFor(@NotNull
540: SDDocument current, @NotNull
541: SDDocument referenced) {
542: // the map on endpoint should account for all SDDocument
543: assert revWsdls.containsKey(referenced);
544: return address + '?' + revWsdls.get(referenced);
545: }
546: };
547:
548: doc.writeTo(portAddressResolver, resolver, os);
549: os.close();
550: }
551:
552: /**
553: * HTTP/1.0 connections require Content-Length. So just buffer to find out
554: * the length.
555: */
556: private final static class Http10OutputStream extends
557: ByteArrayBuffer {
558: private final WSHTTPConnection con;
559:
560: Http10OutputStream(WSHTTPConnection con) {
561: this .con = con;
562: }
563:
564: @Override
565: public void close() throws IOException {
566: super .close();
567: con.setContentLengthResponseHeader(size());
568: OutputStream os = con.getOutput();
569: writeTo(os);
570: os.close();
571: }
572: }
573:
574: private void writeNotFoundErrorPage(WSHTTPConnection con,
575: String message) throws IOException {
576: con.setStatus(HttpURLConnection.HTTP_NOT_FOUND);
577: con
578: .setContentTypeResponseHeader("text/html; charset=\"utf-8\"");
579:
580: PrintWriter out = new PrintWriter(new OutputStreamWriter(con
581: .getOutput(), "UTF-8"));
582: out.println("<html>");
583: out.println("<head><title>");
584: out.println(WsservletMessages.SERVLET_HTML_TITLE());
585: out.println("</title></head>");
586: out.println("<body>");
587: out.println(WsservletMessages.SERVLET_HTML_NOT_FOUND(message));
588: out.println("</body>");
589: out.println("</html>");
590: out.close();
591: }
592:
593: private void writeInternalServerError(WSHTTPConnection con)
594: throws IOException {
595: con.setStatus(HttpURLConnection.HTTP_INTERNAL_ERROR);
596: con.getOutput().close(); // Sets the status code
597: }
598:
599: private static final class DummyList extends
600: HttpAdapterList<HttpAdapter> {
601: @Override
602: protected HttpAdapter createHttpAdapter(String name,
603: String urlPattern, WSEndpoint<?> endpoint) {
604: return new HttpAdapter(endpoint, this , urlPattern);
605: }
606: }
607:
608: private void dump(ByteArrayBuffer buf, String caption,
609: Map<String, List<String>> headers) throws IOException {
610: System.out.println("---[" + caption + "]---");
611: if (headers != null) {
612: for (Entry<String, List<String>> header : headers
613: .entrySet()) {
614: if (header.getValue().isEmpty()) {
615: // I don't think this is legal, but let's just dump it,
616: // as the point of the dump is to uncover problems.
617: System.out.println(header.getValue());
618: } else {
619: for (String value : header.getValue()) {
620: System.out.println(header.getKey() + ": "
621: + value);
622: }
623: }
624: }
625: }
626: buf.writeTo(System.out);
627: System.out.println("--------------------");
628: }
629:
630: /**
631: * Generates the listing of all services.
632: */
633: private void writeWebServicesHtmlPage(WSHTTPConnection con)
634: throws IOException {
635: if (!publishStatusPage)
636: return;
637:
638: // TODO: resurrect the ability to localize according to the current request.
639:
640: // standard browsable page
641: con.setStatus(WSHTTPConnection.OK);
642: con
643: .setContentTypeResponseHeader("text/html; charset=\"utf-8\"");
644:
645: PrintWriter out = new PrintWriter(new OutputStreamWriter(con
646: .getOutput(), "UTF-8"));
647: out.println("<html>");
648: out.println("<head><title>");
649: // out.println("Web Services");
650: out.println(WsservletMessages.SERVLET_HTML_TITLE());
651: out.println("</title></head>");
652: out.println("<body>");
653: // out.println("<h1>Web Services</h1>");
654: out.println(WsservletMessages.SERVLET_HTML_TITLE_2());
655:
656: // what endpoints do we have in this system?
657: Module module = getEndpoint().getContainer().getSPI(
658: Module.class);
659: List<BoundEndpoint> endpoints = Collections.emptyList();
660: if (module != null) {
661: endpoints = module.getBoundEndpoints();
662: }
663:
664: if (endpoints.isEmpty()) {
665: // out.println("<p>No JAX-WS context information available.</p>");
666: out.println(WsservletMessages
667: .SERVLET_HTML_NO_INFO_AVAILABLE());
668: } else {
669: out.println("<table width='100%' border='1'>");
670: out.println("<tr>");
671: out.println("<td>");
672: // out.println("Endpoint");
673: out.println(WsservletMessages
674: .SERVLET_HTML_COLUMN_HEADER_PORT_NAME());
675: out.println("</td>");
676:
677: out.println("<td>");
678: // out.println("Information");
679: out.println(WsservletMessages
680: .SERVLET_HTML_COLUMN_HEADER_INFORMATION());
681: out.println("</td>");
682: out.println("</tr>");
683:
684: for (BoundEndpoint a : endpoints) {
685: String endpointAddress = con.getBaseAddress()
686: + getValidPath();
687: out.println("<tr>");
688:
689: out.println("<td>");
690: out.println(WsservletMessages
691: .SERVLET_HTML_ENDPOINT_TABLE(a.getEndpoint()
692: .getServiceName(), a.getEndpoint()
693: .getPortName()));
694: out.println("</td>");
695:
696: out.println("<td>");
697: out.println(WsservletMessages
698: .SERVLET_HTML_INFORMATION_TABLE(
699: endpointAddress, a.getEndpoint()
700: .getImplementationClass()
701: .getName()));
702: out.println("</td>");
703:
704: out.println("</tr>");
705: }
706: out.println("</table>");
707: }
708: out.println("</body>");
709: out.println("</html>");
710: out.close();
711: }
712:
713: /**
714: * Dumps what goes across HTTP transport.
715: */
716: public static boolean dump = false;
717:
718: public static boolean publishStatusPage = true;
719:
720: static {
721: try {
722: dump = Boolean.getBoolean(HttpAdapter.class.getName()
723: + ".dump");
724: } catch (Throwable t) {
725: }
726: try {
727: publishStatusPage = System.getProperty(
728: HttpAdapter.class.getName() + ".publishStatusPage")
729: .equals("true");
730: } catch (Throwable t) {
731: }
732: }
733:
734: private static final Logger LOGGER = Logger
735: .getLogger(HttpAdapter.class.getName());
736: }
|