1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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
46
47
48
49
50
51
52
53
54
55
56
57 public class CheckUrlsCommand extends CheckUrlsGeneric<HttpClient> {
58
59
60 private static final Logger LOGGER = Logger.getLogger(CheckUrlsCommand.class
61 .getName());
62
63
64 protected final HttpContext localContext;
65
66
67
68
69
70
71
72
73
74 public CheckUrlsCommand(Command successor, HttpClient newClient) {
75 super(successor, newClient);
76 localContext = null;
77 }
78
79
80
81
82
83
84
85
86
87
88
89 public CheckUrlsCommand(Command successor, HttpClient newClient,
90 HttpContext foreignContext) {
91 super(successor, newClient);
92 localContext = foreignContext;
93 }
94
95
96
97
98
99
100
101 @Override
102 public boolean isMultithreaded() {
103 return client.getConnectionManager().getClass()
104 .isAssignableFrom(ThreadSafeClientConnManager.class);
105 }
106
107
108
109
110
111
112
113
114
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
167
168
169
170
171
172
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 }