View Javadoc

1   /*
2    * (C)opyright 2010, Nikolaos Georgosopoulos
3    *
4    * This file is part of URLChecker.
5   
6       URLChecker is free software: you can redistribute it and/or modify
7       it under the terms of the Lesser General Public License as published by
8       the Free Software Foundation, either version 3 of the License, or
9       (at your option) any later version.
10  
11      URLChecker is distributed in the hope that it will be useful,
12      but WITHOUT ANY WARRANTY; without even the implied warranty of
13      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14      GNU General Public License for more details.
15  
16      You should have received a copy of the Lesser General Public License
17      along with URLChecker.  If not, see <http://www.gnu.org/licenses/>.
18  
19   */
20  package net.sf.urlchecker.communication;
21  
22  import java.text.MessageFormat;
23  import java.util.regex.Pattern;
24  
25  import net.sf.urlchecker.commands.RetryHandler;
26  import net.sf.urlchecker.communication.configurers.ClientConfigurer;
27  import net.sf.urlchecker.communication.configurers.ExceptionHandlersConfigurer;
28  import net.sf.urlchecker.communication.configurers.MethodsConfigurer;
29  import net.sf.urlchecker.communication.configurers.RetriesConfigurer;
30  import net.sf.urlchecker.communication.configurers.URLPatternConfigurer;
31  import net.sf.urlchecker.communication.configurers.ValidCodesConfigurer;
32  
33  import org.apache.commons.configuration.ConfigurationException;
34  import org.apache.commons.configuration.XMLConfiguration;
35  import org.apache.commons.httpclient.HttpClient;
36  import org.apache.commons.httpclient.HttpConnectionManager;
37  import org.apache.commons.httpclient.HttpMethod;
38  import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
39  import org.apache.commons.httpclient.SimpleHttpConnectionManager;
40  import org.apache.commons.httpclient.params.HttpMethodParams;
41  
42  /**
43   * A FACTORY for creating Communication objects.
44   * 
45   * <p>
46   * <b> $Id: CommunicationFactory.java 182 2010-12-13 22:51:53Z georgosn $</b>
47   * </p>
48   * 
49   * @author $LastChangedBy: georgosn $
50   * @version $LastChangedRevision: 182 $
51   */
52  public final class CommunicationFactory
53          extends
54          GenericCommunicationFactory<HttpClient, HttpConnectionManager, HTTPMethods, HttpMethod> {
55  
56      /** The Constant FACTORY. */
57      private static final CommunicationFactory FACTORY = new CommunicationFactory();
58  
59      /**
60       * Returns the single instance of CommunicationFactory.
61       * 
62       * @return single instance of CommunicationFactory
63       */
64      public static CommunicationFactory getInstance() {
65          return FACTORY;
66      }
67  
68      /**
69       * Instantiates a new communication FACTORY.
70       */
71      private CommunicationFactory() {
72          configured = false;
73          client = null;
74          multithreaded = false;
75  
76      }
77  
78      /**
79       * {@inheritDoc}
80       * 
81       * Configure client.
82       */
83      @Override
84      public HttpClient configureClient(final boolean localThreadSceme)
85              throws ConfigurationException {
86          synchronized (this) {
87              if (null == client) {
88  
89                  multithreaded = localThreadSceme;
90                  if (multithreaded) {
91                      manager = new MultiThreadedHttpConnectionManager();
92                  } else {
93                      manager = new SimpleHttpConnectionManager();
94                  }
95  
96                  XMLConfiguration config = null;
97  
98                  try {
99                      config = new XMLConfiguration(fileName);
100 
101                 } catch (final ConfigurationException e) {
102                     LOGGER.warn(MessageFormat.format(WARNINGS[0], new Object[] {
103                             fileName, FILE_NOT_FOUND }));
104                     try {
105                         config = new XMLConfiguration(
106                                 HTTPCONFIGURATION_FILENAME);
107                     } catch (final ConfigurationException e1) {
108                         LOGGER.warn(MessageFormat.format(WARNINGS[0],
109                                 new Object[] { HTTPCONFIGURATION_FILENAME,
110                                         NO_CONFIG }));
111 
112                     }
113                 } finally {
114                     if (config == null) {
115                         throw new ConfigurationException("no configuration");
116                     }
117                 }
118                 final ClientConfigurer current = new ClientConfigurer();
119                 client = current.configureWith(config);
120                 client.setHttpConnectionManager(manager);
121                 final RetriesConfigurer current1 = new RetriesConfigurer();
122                 maxretries = current1.configureWith(config);
123                 final MethodsConfigurer current2 = new MethodsConfigurer();
124                 methods = current2.configureWith(config);
125                 final ExceptionHandlersConfigurer current3 = new ExceptionHandlersConfigurer();
126                 exceptionHandlers = current3.configureWith(config);
127                 final ValidCodesConfigurer current4 = new ValidCodesConfigurer();
128                 validCodes = current4.configureWith(config);
129                 final URLPatternConfigurer current5 = new URLPatternConfigurer();
130                 final String pattern = current5.configureWith(config);
131                 urlpattern = null == pattern ? null : Pattern.compile(pattern);
132                 // last statement always
133                 configured = true;
134             } else {
135                 // in case a new client is requested with a different threading
136                 // scheme than the one that is active, throw a configuration
137                 // exception
138                 if (localThreadSceme != multithreaded) {
139                     throw new ConfigurationException(
140                             "Builder can only return one type of configuration until shutdown");
141                 }
142             }
143             return client;
144         }
145     }
146 
147     /*
148      * (non-Javadoc)
149      * 
150      * @see
151      * net.sf.urlchecker.communication.GenericCommunicationFactory#configureClient
152      * (boolean, java.lang.String)
153      */
154     /** {@inheritDoc} */
155     @Override
156     public HttpClient configureClient(boolean localThreadSceme, String FileName)
157             throws ConfigurationException {
158         synchronized (this) {
159             fileName = FileName;
160 
161             return configureClient(localThreadSceme);
162         }
163     }
164 
165     /**
166      * {@inheritDoc}
167      * 
168      * Gets the method.
169      */
170     @Override
171     public HttpMethod getMethod(final String source) {
172         if (!configured) {
173             throw new IllegalStateException();
174         }
175         HTTPMethods type = getMethodType(source);
176         if (null == type) {
177             type = HTTPMethods.HEAD;
178         }
179         final HttpMethod method = type.getMethod(source);
180         method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
181                 new RetryHandler());
182 
183         return method;
184     }
185 
186     /**
187      * {@inheritDoc}
188      * 
189      * Gets the method type.
190      */
191     @Override
192     public HTTPMethods getMethodType(final String source) {
193         if (!configured) {
194             throw new IllegalStateException();
195         }
196         synchronized (this) {
197             HTTPMethods retValue = methods.get(source);
198             if (retValue == null) {
199                 retValue = methods.get(null);
200             }
201 
202             return retValue;
203         }
204     }
205 
206     /**
207      * {@inheritDoc}
208      * 
209      * Shutdown.
210      */
211     @Override
212     public void shutdown() {
213         synchronized (this) {
214             if (multithreaded) {
215                 MultiThreadedHttpConnectionManager.shutdownAll();
216                 multithreaded = false;
217             }
218             if (null != client) {
219                 client.getState().clear();
220                 client.getState().clearCookies();
221                 client.getState().clearCredentials();
222                 client.getState().clearProxyCredentials();
223                 client = null;
224             }
225             configured = false;
226         }
227     }
228 
229 }