1 package us.codecraft.webmagic.downloader.selenium;
2
3 import java.io.FileReader;
4 import java.io.IOException;
5 import java.net.MalformedURLException;
6 import java.net.URL;
7 import java.util.ArrayList;
8 import java.util.Collections;
9 import java.util.List;
10 import java.util.Properties;
11 import java.util.concurrent.BlockingDeque;
12 import java.util.concurrent.LinkedBlockingDeque;
13 import java.util.concurrent.atomic.AtomicInteger;
14
15 import org.openqa.selenium.WebDriver;
16 import org.openqa.selenium.chrome.ChromeDriver;
17 import org.openqa.selenium.chrome.ChromeOptions;
18 import org.openqa.selenium.firefox.FirefoxDriver;
19 import org.openqa.selenium.firefox.FirefoxOptions;
20 import org.openqa.selenium.phantomjs.PhantomJSDriver;
21 import org.openqa.selenium.phantomjs.PhantomJSDriverService;
22 import org.openqa.selenium.remote.DesiredCapabilities;
23 import org.openqa.selenium.remote.RemoteWebDriver;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
26
27
28
29
30
31
32 class WebDriverPool {
33 private Logger logger = LoggerFactory.getLogger(getClass());
34
35 private final static int DEFAULT_CAPACITY = 5;
36
37 private final int capacity;
38
39 private final static int STAT_RUNNING = 1;
40
41 private final static int STAT_CLODED = 2;
42
43 private AtomicInteger stat = new AtomicInteger(STAT_RUNNING);
44
45
46
47
48 private WebDriver mDriver = null;
49 private boolean mAutoQuitDriver = true;
50
51 private static final String DEFAULT_CONFIG_FILE = "/data/webmagic/webmagic-selenium/config.ini";
52 private static final String DRIVER_FIREFOX = "firefox";
53 private static final String DRIVER_CHROME = "chrome";
54 private static final String DRIVER_PHANTOMJS = "phantomjs";
55
56 protected static Properties sConfig;
57 protected static DesiredCapabilities sCaps;
58
59
60
61
62
63
64
65
66
67 public void configure() throws IOException {
68
69 sConfig = new Properties();
70 String configFile = DEFAULT_CONFIG_FILE;
71 if (System.getProperty("selenuim_config")!=null){
72 configFile = System.getProperty("selenuim_config");
73 }
74 sConfig.load(new FileReader(configFile));
75
76
77 sCaps = new DesiredCapabilities();
78 sCaps.setCapability("takesScreenshot", false);
79
80 String driver = sConfig.getProperty("driver", DRIVER_PHANTOMJS);
81
82
83 if (driver.equals(DRIVER_PHANTOMJS)) {
84
85 if (sConfig.getProperty("phantomjs_exec_path") != null) {
86 sCaps.setCapability(
87 PhantomJSDriverService.PHANTOMJS_EXECUTABLE_PATH_PROPERTY,
88 sConfig.getProperty("phantomjs_exec_path"));
89 } else {
90 throw new IOException(
91 String.format(
92 "Property '%s' not set!",
93 PhantomJSDriverService.PHANTOMJS_EXECUTABLE_PATH_PROPERTY));
94 }
95
96 if (sConfig.getProperty("phantomjs_driver_path") != null) {
97 System.out.println("Test will use an external GhostDriver");
98 sCaps.setCapability(
99 PhantomJSDriverService.PHANTOMJS_GHOSTDRIVER_PATH_PROPERTY,
100 sConfig.getProperty("phantomjs_driver_path"));
101 } else {
102 System.out
103 .println("Test will use PhantomJS internal GhostDriver");
104 }
105 }
106
107
108
109
110
111
112
113
114
115
116 ArrayList<String> cliArgsCap = new ArrayList<String>();
117 cliArgsCap.add("--web-security=false");
118 cliArgsCap.add("--ssl-protocol=any");
119 cliArgsCap.add("--ignore-ssl-errors=true");
120 sCaps.setCapability(PhantomJSDriverService.PHANTOMJS_CLI_ARGS,
121 cliArgsCap);
122
123
124 sCaps.setCapability(
125 PhantomJSDriverService.PHANTOMJS_GHOSTDRIVER_CLI_ARGS,
126 new String[] { "--logLevel="
127 + (sConfig.getProperty("phantomjs_driver_loglevel") != null ? sConfig
128 .getProperty("phantomjs_driver_loglevel")
129 : "INFO") });
130
131
132
133
134 if (isUrl(driver)) {
135 sCaps.setBrowserName("phantomjs");
136 mDriver = new RemoteWebDriver(new URL(driver), sCaps);
137 } else if (driver.equals(DRIVER_FIREFOX)) {
138 mDriver = new FirefoxDriver(new FirefoxOptions(sCaps));
139 } else if (driver.equals(DRIVER_CHROME)) {
140 mDriver = new ChromeDriver(new ChromeOptions().merge(sCaps));
141 } else if (driver.equals(DRIVER_PHANTOMJS)) {
142 mDriver = new PhantomJSDriver(sCaps);
143 }
144 }
145
146
147
148
149
150
151
152
153 private boolean isUrl(String urlString) {
154 try {
155 new URL(urlString);
156 return true;
157 } catch (MalformedURLException mue) {
158 return false;
159 }
160 }
161
162
163
164
165 private List<WebDriver> webDriverList = Collections
166 .synchronizedList(new ArrayList<WebDriver>());
167
168
169
170
171 private BlockingDeque<WebDriver> innerQueue = new LinkedBlockingDeque<WebDriver>();
172
173 public WebDriverPool(int capacity) {
174 this.capacity = capacity;
175 }
176
177 public WebDriverPool() {
178 this(DEFAULT_CAPACITY);
179 }
180
181
182
183
184
185
186 public WebDriver get() throws InterruptedException {
187 checkRunning();
188 WebDriver poll = innerQueue.poll();
189 if (poll != null) {
190 return poll;
191 }
192 if (webDriverList.size() < capacity) {
193 synchronized (webDriverList) {
194 if (webDriverList.size() < capacity) {
195
196
197 try {
198 configure();
199 innerQueue.add(mDriver);
200 webDriverList.add(mDriver);
201 } catch (IOException e) {
202 e.printStackTrace();
203 }
204
205
206
207
208
209 }
210 }
211
212 }
213 return innerQueue.take();
214 }
215
216 public void returnToPool(WebDriver webDriver) {
217 checkRunning();
218 innerQueue.add(webDriver);
219 }
220
221 protected void checkRunning() {
222 if (!stat.compareAndSet(STAT_RUNNING, STAT_RUNNING)) {
223 throw new IllegalStateException("Already closed!");
224 }
225 }
226
227 public void closeAll() {
228 boolean b = stat.compareAndSet(STAT_RUNNING, STAT_CLODED);
229 if (!b) {
230 throw new IllegalStateException("Already closed!");
231 }
232 for (WebDriver webDriver : webDriverList) {
233 logger.info("Quit webDriver" + webDriver);
234 webDriver.quit();
235 webDriver = null;
236 }
237 }
238
239 }