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.v2.commands;
21  
22  import java.util.ArrayList;
23  import java.util.Iterator;
24  import java.util.List;
25  import java.util.concurrent.ExecutionException;
26  import java.util.concurrent.ExecutorService;
27  import java.util.concurrent.Executors;
28  import java.util.concurrent.Future;
29  import java.util.concurrent.TimeUnit;
30  
31  import net.sf.urlchecker.commands.CheckUrlsGeneric;
32  import net.sf.urlchecker.commands.Command;
33  import net.sf.urlchecker.commands.Context;
34  import net.sf.urlchecker.commands.Result;
35  import net.sf.urlchecker.events.BasicChainEvent;
36  import net.sf.urlchecker.events.EventTypes;
37  
38  import org.apache.commons.configuration.ConfigurationException;
39  import org.apache.http.client.HttpClient;
40  import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
41  import org.apache.http.protocol.HttpContext;
42  import org.apache.log4j.Logger;
43  
44  /**
45   * The Class CheckUrlsCommand for the new httpClient. Use this implementation
46   * together with the CommunicationBuilder in the v2.communication package if you
47   * want to move on to the new appache.http.client. The new Constructor in this
48   * class allows for deeper configuration of the execution environment.
49   * 
50   * <p>
51   * <b> $Id: CheckUrlsCommand.java 183 2010-12-17 19:10:21Z georgosn $</b>
52   * </p>
53   * 
54   * @author $LastChangedBy: georgosn $
55   * @version $LastChangedRevision: 183 $
56   */
57  public class CheckUrlsCommand extends CheckUrlsGeneric<HttpClient> {
58  
59      /** The Constant LOGGER. */
60      private static final Logger LOGGER = Logger.getLogger(CheckUrlsCommand.class
61                                                 .getName());
62  
63      /** The local context. */
64      protected final HttpContext localContext;
65  
66      /**
67       * Instantiates a new check URLs command.
68       * 
69       * @param successor
70       *            the successor
71       * @param newClient
72       *            the new client
73       */
74      public CheckUrlsCommand(Command successor, HttpClient newClient) {
75          super(successor, newClient);
76          localContext = null;
77      }
78  
79      /**
80       * Instantiates a new check URLs command.
81       * 
82       * @param successor
83       *            the successor
84       * @param newClient
85       *            the new client
86       * @param foreignContext
87       *            the foreign context
88       */
89      public CheckUrlsCommand(Command successor, HttpClient newClient,
90              HttpContext foreignContext) {
91          super(successor, newClient);
92          localContext = foreignContext;
93      }
94  
95      /*
96       * (non-Javadoc)
97       * 
98       * @see net.sf.urlchecker.commands.CheckUrlsGeneric#isMultithreaded()
99       */
100     /** {@inheritDoc} */
101     @Override
102     public boolean isMultithreaded() {
103         return client.getConnectionManager().getClass()
104                 .isAssignableFrom(ThreadSafeClientConnManager.class);
105     }
106 
107     /*
108      * (non-Javadoc)
109      * 
110      * @see
111      * net.sf.urlchecker.commands.CheckUrlsGeneric#multithreadedExecution(net
112      * .sf.urlchecker.commands.Context, java.util.Iterator)
113      */
114     /** {@inheritDoc} */
115     @Override
116     protected void multithreadedExecution(Context context, Iterator<Result> iter)
117             throws ConfigurationException {
118         final ExecutorService service = Executors.newFixedThreadPool(context
119                 .getResults().size());
120         final List<Future<CheckUrlsProcess>> tasks = new ArrayList<Future<CheckUrlsProcess>>();
121 
122         while (iter.hasNext()) {
123             fireEvent(new BasicChainEvent(this, context, EventTypes.FORK));
124             final CheckUrlsProcess process = new CheckUrlsProcess(client,
125                     localContext, iter.next());
126             final Future<CheckUrlsProcess> future = service.submit(process,
127                     process);
128             tasks.add(future);
129         }
130 
131         try {
132             for (final Future<CheckUrlsProcess> f : tasks) {
133                 final Result result = f.get().getResult();
134 
135                 if (LOGGER.isDebugEnabled()) {
136                     LOGGER.debug(result.getResult() + " for " + result.getURI()
137                             + " with " + result.getUserData());
138                 }
139             }
140 
141             service.shutdown();
142         } catch (final InterruptedException e) {
143             LOGGER.error(e);
144             fireEvent(new BasicChainEvent(this, context, EventTypes.EXCEPTION));
145         } catch (final ExecutionException e) {
146             LOGGER.error(e);
147             fireEvent(new BasicChainEvent(this, context, EventTypes.EXCEPTION));
148         } finally {
149             try {
150                 if (!service.isShutdown()) {
151                     service.awaitTermination(terminationTime, TimeUnit.SECONDS);
152                 }
153             } catch (final InterruptedException e) {
154                 LOGGER.error(e);
155                 fireEvent(new BasicChainEvent(this, context,
156                         EventTypes.EXCEPTION));
157             } finally {
158                 if (!service.isShutdown()) {
159                     service.shutdownNow();
160                 }
161             }
162         }
163     }
164 
165     /*
166      * (non-Javadoc)
167      * 
168      * @see
169      * net.sf.urlchecker.commands.CheckUrlsGeneric#singlethreadedExecution(java
170      * .util.Iterator)
171      */
172     /** {@inheritDoc} */
173     @Override
174     protected void singlethreadedExecution(Iterator<Result> iter)
175             throws ConfigurationException {
176         while (iter.hasNext()) {
177             final CheckUrlsProcess process = new CheckUrlsProcess(client,
178                     localContext, iter.next());
179             process.run();
180         }
181 
182     }
183 }