Project Report: fawkez

Packagesummary org.jcoderz.commons.connector.http

org.jcoderz.commons.connector.http.HttpConnectionImpl

LineHitsNoteSource
1  /*
2   * $Id: HttpConnectionImpl.java 1011 2008-06-16 17:57:36Z amandel $
3   *
4   * Copyright 2006, The jCoderZ.org Project. All rights reserved.
5   *
6   * Redistribution and use in source and binary forms, with or without
7   * modification, are permitted provided that the following conditions are
8   * met:
9   *
10   *    * Redistributions of source code must retain the above copyright
11   *      notice, this list of conditions and the following disclaimer.
12   *    * Redistributions in binary form must reproduce the above
13   *      copyright notice, this list of conditions and the following
14   *      disclaimer in the documentation and/or other materials
15   *      provided with the distribution.
16   *    * Neither the name of the jCoderZ.org Project nor the names of
17   *      its contributors may be used to endorse or promote products
18   *      derived from this software without specific prior written
19   *      permission.
20   *
21   * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND
22   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24   * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS
25   * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
28   * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29   * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30   * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31   * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32   */
33  package org.jcoderz.commons.connector.http;
34  
35  import java.util.logging.Level;
36  import java.util.logging.Logger;
37  
38  import javax.resource.ResourceException;
39  
40  import org.jcoderz.commons.connector.ConnectionRequestFailedException;
41  import org.jcoderz.commons.connector.ConnectionResponseFailedException;
42  import org.jcoderz.commons.connector.ConnectionTimeoutErrorException;
43  import org.jcoderz.commons.connector.ConnectorConfiguration;
44  import org.jcoderz.commons.connector.ConnectorException;
45  import org.jcoderz.commons.connector.http.transport.ConnectorContext;
46  import org.jcoderz.commons.connector.http.transport
47          .HttpClientConnectionException;
48  import org.jcoderz.commons.connector.http.transport
49          .HttpConnectConnectionException;
50  import org.jcoderz.commons.connector.http.transport.HttpConnectionException;
51  import org.jcoderz.commons.connector.http.transport.HttpConnectorEventListener;
52  import org.jcoderz.commons.connector.http.transport.HttpEmptyResponseException;
53  import org.jcoderz.commons.connector.http.transport
54          .HttpInvalidResponseHeaderException;
55  import org.jcoderz.commons.connector.http.transport.HttpRequestResponseHeader;
56  import org.jcoderz.commons.connector.http.transport
57          .HttpServerConnectionException;
58  import org.jcoderz.commons.connector.http.transport
59          .HttpTimeoutConnectionException;
60  import org.jcoderz.commons.types.Url;
61  import org.jcoderz.commons.util.Assert;
62  
63  
64  
65  
66  /**
67   * Implementation of the HttpConnectionExtended interface.
68   * The implemented methods call the respective methods on
69   * the ManagedHttpConnection class.
70   *
71   */
72 (1)public final class HttpConnectionImpl
73        implements HttpConnectionExtended
74  {
75     /** Class name used for logging. */
760    private static final String CLASSNAME
77           = HttpConnectionImpl.class.getName();
78     /** Logger in use. */
790    private static final Logger logger
80           = Logger.getLogger(CLASSNAME);
81     /** Handle to the physical connection. Null means connection is invalid. */
82     private HttpManagedConnectionImpl mManagedConnection;
83     /** Flag indicating if the physical connection is closed by the managed
84         connection - if true the connection is disassociated by the application
85         server. */
860    private boolean mClosedByManagedConnection = false;
87     /** Delay for retries in milli seconds. */
88     private int mRequiredDelay;
89     /** Flag indicating that a delay for retries is necessary. */
900    private boolean mIsRetryRequired = false;
91     private final ConnectorConfiguration mConfig;
92  
93  
94     /**
95      * Constructor.
96      * Sets the calling ManagedPaymentProtocolConnection object.
97      *
98      * @param mc the managed connection creating this object
99      */
100     public HttpConnectionImpl (HttpManagedConnectionImpl mc)
1010    {
1020       mManagedConnection = mc;
1030       mConfig = ConfigurationFactory.getConfiguration();
1040    }
105  
106     /** {@inheritDoc} */
107     public byte[] sendAndReceive (byte[] message)
108 (2)         throws ResourceException, ConnectorException
109     {
1100       final String methodName = "sendAndReceive";
1110       if (logger.isLoggable(Level.FINER))
112        {
1130          logger.entering(CLASSNAME, methodName);
114        }
1150       Assert.notNull(message, "message");
116  
1170       mIsRetryRequired = false;
1180       byte[] result = null;
119        try
120        {
1210          result = getManagedConnection().sendAndReceive(message);
122        }
1230       catch (HttpClientConnectionException hce)
124        {
1250          handleClientConnectionException(hce);
126        }
1270       catch (HttpServerConnectionException hse)
128        {
1290          handleServerConnectionException(hse);
130        }
1310       catch (HttpConnectConnectionException hce)
132        {
1330          handleConnectConnectionException(hce);
134        }
1350       catch (HttpTimeoutConnectionException hte)
136        {
1370          handleTimeoutConnectionException(hte);
138        }
1390       catch (HttpInvalidResponseHeaderException hie)
140        {
1410          handleInvalidResponseHeaderException(hie);
142        }
1430       catch (HttpEmptyResponseException ere)
144        {
1450          handleEmptyResponseException(ere);
146        }
1470       catch (HttpConnectionException he)
148        {
1490          handleConnectionException(he);
1500       }
151  
1520       if (logger.isLoggable(Level.FINER))
153        {
1540          logger.exiting(CLASSNAME, methodName, result);
155        }
1560       return result;
157     }
158  
159     /** {@inheritDoc} */
160     public void setRequestResponseHeader (HttpRequestResponseHeader header)
161           throws ResourceException
162     {
1630       getManagedConnection().setRequestResponseHeader(header);
1640    }
165  
166     /** {@inheritDoc} */
167     public void setEventListener (HttpConnectorEventListener listener,
168           ConnectorContext context)
169     {
1700       getManagedConnection().setEventListener(listener, context);
1710    }
172  
173     private void handleClientConnectionException (HttpConnectionException ex)
174           throws ConnectionResponseFailedException
175     {
1760       logger.finer("Handling 'ClientConnectionException' " + ex.getMessage());
1770       if (mConfig.getHttpClientErrorResendFlag())
178        {
1790          mIsRetryRequired = true;
1800          mRequiredDelay = mConfig.getHttpClientErrorResendDelayInMilliSeconds();
181        }
1820       final ConnectionResponseFailedException cre
183              = new ConnectionResponseFailedException(getUrl(), ex);
1840       invalidateManagedConnection(cre);
1850       throw cre;
186     }
187  
188     private void handleServerConnectionException (HttpConnectionException ex)
189           throws ConnectionResponseFailedException
190     {
1910       logger.finer("Handling 'ServerConnectionException' " + ex.getMessage());
1920       if (mConfig.getHttpServerErrorResendFlag())
193        {
1940          mIsRetryRequired = true;
1950          mRequiredDelay
196                 = mConfig.getHttpServerErrorResendDelayInMilliSeconds();
197        }
1980       final ConnectionResponseFailedException cre
199              = new ConnectionResponseFailedException(getUrl(), ex);
2000       invalidateManagedConnection(cre);
2010       throw cre;
202     }
203  
204     private void handleConnectConnectionException (HttpConnectionException ex)
205           throws ConnectionRequestFailedException
206     {
2070       logger.finer("Handling 'ConnectConnectionException' " + ex.getMessage());
2080       final ConnectionRequestFailedException cre
209              = new ConnectionRequestFailedException(getUrl(), ex);
2100       invalidateManagedConnection(cre);
2110       throw cre;
212     }
213  
214     private void handleTimeoutConnectionException (HttpConnectionException ex)
215           throws ConnectionTimeoutErrorException
216     {
2170       logger.finer("Handling 'TimeoutConnectionException' " + ex.getMessage());
2180       if (mConfig.getHttpReadTimeoutErrorResendFlag())
219        {
2200          mIsRetryRequired = true;
2210          mRequiredDelay
222                 = mConfig.getHttpReadTimeoutErrorResendDelayInMilliSeconds();
223        }
2240       mIsRetryRequired = true;
2250       final StringBuffer previousFailure = new StringBuffer();
2260       previousFailure.append(ex.toString());
2270       final Throwable cause = ex.getCause();
2280       if (cause != null)
229        {
2300          previousFailure.append(" caused by ");
2310          previousFailure.append(cause.toString());
232        }
2330       final ConnectionTimeoutErrorException cte
234              = new ConnectionTimeoutErrorException(
235                    getUrl(), previousFailure.toString(), ex);
2360       invalidateManagedConnection(cte);
2370       throw cte;
238     }
239  
240     private void handleInvalidResponseHeaderException (
241           HttpConnectionException ex)
242           throws ConnectionResponseFailedException
243     {
2440       logger.finer("Handling 'InvalidResponseHeaderException' "
245              + ex.getMessage());
2460       mIsRetryRequired = false;
2470       final ConnectionResponseFailedException cre
248              = new ConnectionResponseFailedException(getUrl(), ex);
2490       invalidateManagedConnection(cre);
2500       throw cre;
251     }
252  
253     private void handleEmptyResponseException (
254           HttpConnectionException ex)
255           throws ConnectionResponseFailedException
256     {
2570       logger.finer("Handling 'HttpEmptyResponseException' "
258              + ex.getMessage());
2590       mIsRetryRequired = false;
2600       final ConnectionResponseFailedException cre
261              = new ConnectionResponseFailedException(getUrl(), ex);
2620       invalidateManagedConnection(cre);
2630       throw cre;
264     }
265  
266     private void handleConnectionException (HttpConnectionException ex)
267           throws ConnectionRequestFailedException
268     {
269 (3)      // TODO: retry policy for the "other" errors
270        // like a server closing whilst sending the request..
2710       logger.finer("Handling 'ConnectionException' " + ex.getMessage());
2720       mIsRetryRequired = false;
2730       final ConnectionRequestFailedException cre
274              = new ConnectionRequestFailedException(getUrl(), ex);
2750       invalidateManagedConnection(cre);
2760       throw cre;
277     }
278  
279     /** {@inheritDoc} */
280     public void close ()
281     {
2820       final String methodName = "close";
2830       logger.entering(CLASSNAME, methodName);
284  
285        // In case that the Connector detects an error on the
286        // HttpManagedConnection, it has the duty to notify the
287        // application server by calling the
288        // notifyAboutConnectionErrorOccurred() callback. In this case, the
289        // application server will call cleanup() on the HttpManagedConnection to
290        // disassociate its connection handle. We can recognize that, as
291        // mClosedByManagedConnection will be set.
2920       if (mManagedConnection == null && mClosedByManagedConnection)
293        {
294           // Connection handle already released by application server;
295           // Doesn't need an explicit close().
296           // trace message
2970          logger.finer("connection already closed by application server");
298           //
299        }
3000       else if (mManagedConnection == null && !mClosedByManagedConnection)
301        {
302           // trace message
3030          logger.finer("connection already closed");
304           //
305        }
306        else
307        {
308           // Notify the HttpManagedConnection that this connection handle no
309           // longer belongs to the HttpManagedConnection.
3100          getManagedConnection().disassociateConnection(this);
311            // Notify all registered EventListeners (Application Server) that
312           // this connection handle was closed.
3130          getManagedConnection().notifyAboutConnectionClosed(this);
314            // Disassociate this connection handle by forgetting to which
315           // HttpManagedConnection we belong. This connection handle is
316           // now invalid.
3170          disassociateManagedConnection(false);
318        }
3190       logger.exiting(CLASSNAME, methodName);
3200    }
321  
322     /**
323      * Gets the associated ManagedConnection.
324      *
325      * @return the HttpManagedConnectionImpl
326      * @throws IllegalStateException - if the managed connection handle
327      *          is not set
328      */
329     protected HttpManagedConnectionImpl getManagedConnection ()
330           throws IllegalStateException
331     {
3320       if (mManagedConnection == null)
333        {
3340          final String errorText = "Connection handle is invalid.";
3350          final IllegalStateException ise = new IllegalStateException(errorText);
3360          throw ise;
337        }
3380       return mManagedConnection;
339     }
340  
341     /**
342      * <p>Associate a different physical connection to this user-level
343      * connection.</p>
344      * <p>Called by the AbstractManagedConnection if transaction boundaries
345      * are crossed.</p>
346      *
347      * @param mc new physical connection instance
348      * @throws ResourceException - like defined in the interface
349      */
350     protected void associateManagedConnection (HttpManagedConnectionImpl mc)
351     {
3520       mManagedConnection = mc;
3530    }
354  
355     /**
356      * Disassociate this connection handle by forgetting to which
357      * ManagedConnection we belong. This connection handle is
358      * now invalid.
359      *
360      * @param closedByManagedConnection flag indicates if this managed
361      *          connnection is closed by itself
362      */
363     public void disassociateManagedConnection (boolean closedByManagedConnection)
364     {
3650       if (closedByManagedConnection)
366        {
3670          logger.finest("disassociated by ManagedConnection");
368        }
369        else
370        {
3710          logger.finest("disassociated by Connection");
372        }
373  
3740       mClosedByManagedConnection = closedByManagedConnection;
3750       mManagedConnection = null;
3760    }
377  
378     /**
379      * Disassociates the connection and marks it as broken.
380      */
381     private void invalidateManagedConnection (final Exception cause)
382     {
3830       getManagedConnection().disassociateConnection(this);
3840       getManagedConnection().notifyAboutConnectionErrorOccurred(
385              cause, this);
3860       disassociateManagedConnection(false);
3870    }
388  
389     private Url getUrl ()
390     {
3910       return getManagedConnection().getUrl();
392     }
393  
394     /**
395      * Gets the time in milli seconds required if another retry
396      * will be performed.
397      *
398      * @return int
399      *          the delay to use in HttpConnecionImpl
400      */
401     public int getRequiredDelayForRetries ()
402     {
4030       return mRequiredDelay;
404     }
405  
406     /**
407      * Gets the flag indicating that a retry is required if
408      * max number of retries is not exceeded.
409      * @return boolean
410      *          if true perform retry - else not
411      */
412     public boolean isRetryRequired ()
413     {
4140       return mIsRetryRequired;
415     }
416  }

Findings in this File

c (1) 72 : 0 Type Javadoc comment is missing an @author tag.
c (2) 108 : 17 Unable to get class information for ResourceException.
i (3) 269 : 0 Comment matches to-do format '(TODO|FIXME|CHECKME)'.