PageRenderTime 29ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/modules/sdk/ant-mirrors-get/src/main/java/com/liferay/ant/mirrors/get/MirrorsGetTask.java

http://github.com/liferay/liferay-portal
Java | 643 lines | 545 code | 82 blank | 16 comment | 35 complexity | b61f72404ebbb69c16910d099b5f0e96 MD5 | raw file
Possible License(s): LGPL-2.0
  1. /**
  2. * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
  3. *
  4. * This library is free software; you can redistribute it and/or modify it under
  5. * the terms of the GNU Lesser General Public License as published by the Free
  6. * Software Foundation; either version 2.1 of the License, or (at your option)
  7. * any later version.
  8. *
  9. * This library is distributed in the hope that it will be useful, but WITHOUT
  10. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  11. * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
  12. * details.
  13. */
  14. package com.liferay.ant.mirrors.get;
  15. import java.io.ByteArrayOutputStream;
  16. import java.io.File;
  17. import java.io.FileOutputStream;
  18. import java.io.IOException;
  19. import java.io.InputStream;
  20. import java.io.OutputStream;
  21. import java.net.HttpURLConnection;
  22. import java.net.URI;
  23. import java.net.URL;
  24. import java.net.URLConnection;
  25. import java.util.Base64;
  26. import java.util.Enumeration;
  27. import java.util.regex.Matcher;
  28. import java.util.regex.Pattern;
  29. import java.util.zip.ZipFile;
  30. import org.apache.tools.ant.BuildException;
  31. import org.apache.tools.ant.Project;
  32. import org.apache.tools.ant.Task;
  33. import org.apache.tools.ant.taskdefs.Checksum;
  34. /**
  35. * @author Peter Yoo
  36. */
  37. public class MirrorsGetTask extends Task {
  38. @Override
  39. public void execute() throws BuildException {
  40. try {
  41. doExecute();
  42. }
  43. catch (IOException ioException) {
  44. throw new BuildException(ioException);
  45. }
  46. }
  47. public void setDest(File dest) {
  48. String destPath = dest.getPath();
  49. if (destPath.matches(".*\\$\\{.+\\}.*")) {
  50. Project project = getProject();
  51. _dest = new File(project.replaceProperties(destPath));
  52. }
  53. else {
  54. _dest = dest;
  55. }
  56. }
  57. public void setForce(boolean force) {
  58. _force = force;
  59. }
  60. public void setIgnoreErrors(boolean ignoreErrors) {
  61. _ignoreErrors = ignoreErrors;
  62. }
  63. public void setPassword(String password) {
  64. if (_password == null) {
  65. _password = password;
  66. }
  67. }
  68. public void setRetries(int retries) {
  69. _retries = retries;
  70. }
  71. public void setSkipChecksum(boolean skipChecksum) {
  72. _skipChecksum = skipChecksum;
  73. }
  74. public void setSrc(String src) {
  75. Matcher matcher = _basicAuthenticationURLPattern.matcher(src);
  76. if (matcher.matches()) {
  77. _username = matcher.group(2);
  78. _password = matcher.group(3);
  79. src = matcher.group(1) + matcher.group(4);
  80. }
  81. Project project = getProject();
  82. _src = project.replaceProperties(src);
  83. if (_src.startsWith("file:")) {
  84. return;
  85. }
  86. matcher = _srcPattern.matcher(_src);
  87. if (!matcher.find()) {
  88. throw new RuntimeException("Invalid src attribute: " + _src);
  89. }
  90. _fileName = matcher.group(2);
  91. _path = matcher.group(1);
  92. if (_path.startsWith("mirrors/")) {
  93. _path = _path.replaceFirst("mirrors", getMirrorsHostname());
  94. }
  95. while (_path.endsWith("/")) {
  96. _path = _path.substring(0, _path.length() - 1);
  97. }
  98. }
  99. public void setTryLocalNetwork(boolean tryLocalNetwork) {
  100. _tryLocalNetwork = tryLocalNetwork;
  101. }
  102. public void setUsername(String username) {
  103. if (_username == null) {
  104. _username = username;
  105. }
  106. }
  107. public void setVerbose(boolean verbose) {
  108. _verbose = verbose;
  109. }
  110. protected void copyFile(File sourceFile, File targetFile)
  111. throws IOException {
  112. StringBuilder sb = new StringBuilder();
  113. sb.append("Copying ");
  114. sb.append(sourceFile.getPath());
  115. sb.append(" to ");
  116. sb.append(targetFile.getPath());
  117. sb.append(".");
  118. System.out.println(sb.toString());
  119. URI sourceFileURI = sourceFile.toURI();
  120. long time = System.currentTimeMillis();
  121. int size = toFile(sourceFileURI.toURL(), targetFile);
  122. if (_verbose) {
  123. sb = new StringBuilder();
  124. sb.append("Copied ");
  125. sb.append(size);
  126. sb.append(" bytes in ");
  127. sb.append(System.currentTimeMillis() - time);
  128. sb.append(" milliseconds.");
  129. System.out.println(sb.toString());
  130. }
  131. }
  132. protected void doExecute() throws IOException {
  133. if (_src.startsWith("file:")) {
  134. File srcFile = new File(_src.substring("file:".length()));
  135. File targetFile = _dest;
  136. if (_dest.exists() && _dest.isDirectory()) {
  137. targetFile = new File(_dest, srcFile.getName());
  138. }
  139. copyFile(srcFile, targetFile);
  140. return;
  141. }
  142. Matcher matcher = _mirrorsHostNamePattern.matcher(_path);
  143. if (_tryLocalNetwork && matcher.find()) {
  144. String hostname = matcher.group();
  145. System.out.println(
  146. "The src attribute has an unnecessary reference to " +
  147. hostname);
  148. _path = _path.substring(hostname.length());
  149. while (_path.startsWith("/")) {
  150. _path = _path.substring(1);
  151. }
  152. }
  153. StringBuilder sb = new StringBuilder();
  154. sb.append(System.getProperty("user.home"));
  155. sb.append(File.separator);
  156. sb.append(".liferay");
  157. sb.append(File.separator);
  158. sb.append("mirrors");
  159. sb.append(File.separator);
  160. sb.append(getPlatformIndependentPath(_path));
  161. File localCacheDir = new File(sb.toString());
  162. File localCacheFile = new File(localCacheDir, _fileName);
  163. if (localCacheFile.exists() && !_force && isZipFileName(_fileName)) {
  164. _force = !isValidZip(localCacheFile);
  165. }
  166. if (localCacheFile.exists() && _force) {
  167. localCacheFile.delete();
  168. }
  169. if (!localCacheFile.exists()) {
  170. URL sourceURL = null;
  171. if (_tryLocalNetwork) {
  172. sb = new StringBuilder();
  173. sb.append("http://");
  174. sb.append(getMirrorsHostname());
  175. sb.append("/");
  176. sb.append(_path);
  177. sb.append("/");
  178. sb.append(_fileName);
  179. sourceURL = new URL(sb.toString());
  180. try {
  181. downloadFile(sourceURL, localCacheFile, _retries);
  182. }
  183. catch (IOException ioException) {
  184. URL defaultURL = new URL(_src);
  185. System.out.println(
  186. "Unable to connect to " + sourceURL +
  187. ", defaulting to " + defaultURL);
  188. downloadFile(defaultURL, localCacheFile);
  189. }
  190. }
  191. else {
  192. downloadFile(new URL(_src), localCacheFile);
  193. }
  194. }
  195. if (_dest.exists() && _dest.isDirectory()) {
  196. copyFile(localCacheFile, new File(_dest, _fileName));
  197. }
  198. else {
  199. copyFile(localCacheFile, _dest);
  200. }
  201. }
  202. protected void downloadFile(URL sourceURL, File targetFile)
  203. throws IOException {
  204. downloadFile(sourceURL, targetFile, 0);
  205. }
  206. protected void downloadFile(URL sourceURL, File targetFile, int retries)
  207. throws IOException {
  208. if (retries > 0) {
  209. for (int i = 0; i < retries; i++) {
  210. try {
  211. _downloadFile(sourceURL, targetFile);
  212. return;
  213. }
  214. catch (IOException ioException) {
  215. System.out.println(
  216. "Unable to connect to " + sourceURL +
  217. ", will retry in 30 seconds.");
  218. try {
  219. Thread.sleep(30000);
  220. }
  221. catch (InterruptedException interruptedException) {
  222. interruptedException.printStackTrace();
  223. }
  224. }
  225. }
  226. }
  227. _downloadFile(sourceURL, targetFile);
  228. }
  229. protected String getMirrorsHostname() {
  230. if (_mirrorsHostname != null) {
  231. return _mirrorsHostname;
  232. }
  233. Project project = getProject();
  234. _mirrorsHostname = project.getProperty("mirrors.hostname");
  235. return _mirrorsHostname;
  236. }
  237. protected String getPassword() {
  238. if (_password != null) {
  239. return _password;
  240. }
  241. Project project = getProject();
  242. _password = project.getProperty("mirrors.password");
  243. return _password;
  244. }
  245. protected String getPlatformIndependentPath(String path) {
  246. String[] separators = {"/", "\\"};
  247. for (String separator : separators) {
  248. if (!separator.equals(File.separator)) {
  249. path = path.replace(separator, File.separator);
  250. }
  251. }
  252. return path;
  253. }
  254. protected String getUsername() {
  255. if (_username != null) {
  256. return _username;
  257. }
  258. Project project = getProject();
  259. _username = project.getProperty("mirrors.username");
  260. return _username;
  261. }
  262. protected boolean isValidMD5(File file, URL url) throws IOException {
  263. if (_skipChecksum) {
  264. return true;
  265. }
  266. if ((file == null) || !file.exists()) {
  267. return false;
  268. }
  269. String remoteMD5 = null;
  270. try {
  271. remoteMD5 = toString(url);
  272. }
  273. catch (Exception exception) {
  274. if (_verbose) {
  275. System.out.println("Unable to access MD5 file");
  276. }
  277. return true;
  278. }
  279. Checksum checksum = new Checksum();
  280. checksum.setAlgorithm("MD5");
  281. checksum.setFile(file);
  282. checksum.setProject(new Project());
  283. checksum.setProperty("md5");
  284. checksum.execute();
  285. Project project = checksum.getProject();
  286. String localMD5 = project.getProperty("md5");
  287. return remoteMD5.contains(localMD5);
  288. }
  289. protected boolean isValidZip(File file) throws IOException {
  290. if (!file.exists()) {
  291. return false;
  292. }
  293. ZipFile zipFile = null;
  294. try {
  295. zipFile = new ZipFile(file, ZipFile.OPEN_READ);
  296. int count = 0;
  297. Enumeration<?> enumeration = zipFile.entries();
  298. while (enumeration.hasMoreElements()) {
  299. enumeration.nextElement();
  300. count++;
  301. }
  302. StringBuilder sb = new StringBuilder();
  303. sb.append(file.getPath());
  304. sb.append(" is a valid zip file with ");
  305. sb.append(count);
  306. sb.append(" entries.");
  307. System.out.println(sb.toString());
  308. return true;
  309. }
  310. catch (IOException ioException) {
  311. System.out.println(file.getPath() + " is an invalid zip file.");
  312. return false;
  313. }
  314. finally {
  315. if (zipFile != null) {
  316. zipFile.close();
  317. }
  318. }
  319. }
  320. protected boolean isZipFileName(String fileName) {
  321. if (fileName.endsWith(".ear") || fileName.endsWith(".jar") ||
  322. fileName.endsWith(".war") || fileName.endsWith(".zip")) {
  323. return true;
  324. }
  325. return false;
  326. }
  327. protected URLConnection openConnection(URL url) throws IOException {
  328. URLConnection urlConnection = null;
  329. while (true) {
  330. urlConnection = url.openConnection();
  331. if (!(urlConnection instanceof HttpURLConnection)) {
  332. break;
  333. }
  334. HttpURLConnection httpURLConnection =
  335. (HttpURLConnection)urlConnection;
  336. String password = getPassword();
  337. String username = getUsername();
  338. if ((password != null) && (username != null)) {
  339. String auth = username + ":" + password;
  340. Base64.Encoder encoder = Base64.getEncoder();
  341. httpURLConnection.setRequestProperty(
  342. "Authorization",
  343. "Basic " + encoder.encodeToString(auth.getBytes()));
  344. }
  345. int responseCode = httpURLConnection.getResponseCode();
  346. if ((responseCode != HttpURLConnection.HTTP_MOVED_PERM) &&
  347. (responseCode != HttpURLConnection.HTTP_MOVED_TEMP)) {
  348. break;
  349. }
  350. url = new URL(httpURLConnection.getHeaderField("Location"));
  351. }
  352. return urlConnection;
  353. }
  354. protected int toFile(URL url, File file) throws IOException {
  355. if (file.exists()) {
  356. file.delete();
  357. }
  358. File dir = file.getParentFile();
  359. if ((dir != null) && !dir.exists()) {
  360. dir.mkdirs();
  361. }
  362. OutputStream outputStream = new FileOutputStream(file);
  363. try {
  364. return toOutputStream(url, outputStream);
  365. }
  366. catch (IOException ioException) {
  367. if (file.exists()) {
  368. file.delete();
  369. }
  370. throw ioException;
  371. }
  372. finally {
  373. if (outputStream != null) {
  374. outputStream.close();
  375. }
  376. }
  377. }
  378. protected int toOutputStream(URL url, OutputStream outputStream)
  379. throws IOException {
  380. URLConnection urlConnection = openConnection(url);
  381. InputStream inputStream = urlConnection.getInputStream();
  382. try {
  383. byte[] bytes = new byte[1024 * 16];
  384. int read = 0;
  385. int size = 0;
  386. long time = System.currentTimeMillis();
  387. while ((read = inputStream.read(bytes)) > 0) {
  388. outputStream.write(bytes, 0, read);
  389. size += read;
  390. if (_verbose && ((System.currentTimeMillis() - time) > 100)) {
  391. System.out.print(".");
  392. time = System.currentTimeMillis();
  393. }
  394. }
  395. if (_verbose) {
  396. System.out.println("\n");
  397. }
  398. return size;
  399. }
  400. finally {
  401. if (inputStream != null) {
  402. inputStream.close();
  403. }
  404. }
  405. }
  406. protected String toString(URL url) throws IOException {
  407. OutputStream outputStream = new ByteArrayOutputStream();
  408. try {
  409. toOutputStream(url, outputStream);
  410. return outputStream.toString();
  411. }
  412. finally {
  413. if (outputStream != null) {
  414. outputStream.close();
  415. }
  416. }
  417. }
  418. private void _downloadFile(URL sourceURL, File targetFile)
  419. throws IOException {
  420. StringBuilder sb = new StringBuilder();
  421. sb.append("Downloading ");
  422. sb.append(sourceURL.toExternalForm());
  423. sb.append(" to ");
  424. sb.append(targetFile.getPath());
  425. sb.append(".");
  426. System.out.println(sb.toString());
  427. long time = System.currentTimeMillis();
  428. int size = 0;
  429. try {
  430. size = toFile(sourceURL, targetFile);
  431. }
  432. catch (IOException ioException) {
  433. targetFile.delete();
  434. if (!_ignoreErrors) {
  435. throw ioException;
  436. }
  437. ioException.printStackTrace();
  438. }
  439. if (_verbose) {
  440. sb = new StringBuilder();
  441. sb.append("Downloaded ");
  442. sb.append(sourceURL.toExternalForm());
  443. sb.append(". ");
  444. sb.append(size);
  445. sb.append(" bytes in ");
  446. sb.append(System.currentTimeMillis() - time);
  447. sb.append(" milliseconds.");
  448. System.out.println(sb.toString());
  449. }
  450. if (!isValidMD5(
  451. targetFile, new URL(sourceURL.toExternalForm() + ".md5"))) {
  452. targetFile.delete();
  453. throw new IOException(
  454. targetFile.getAbsolutePath() + " failed checksum.");
  455. }
  456. if (isZipFileName(targetFile.getName()) && !isValidZip(targetFile)) {
  457. targetFile.delete();
  458. throw new IOException(
  459. targetFile.getAbsolutePath() + " is an invalid zip file.");
  460. }
  461. }
  462. private static final Pattern _basicAuthenticationURLPattern =
  463. Pattern.compile("(https?://)([^:]+):([^@]+)@(.+)");
  464. private static final Pattern _mirrorsHostNamePattern = Pattern.compile(
  465. "^mirrors\\.[^\\.]+\\.liferay.com/");
  466. private static final Pattern _srcPattern = Pattern.compile(
  467. "https?://(.+/)(.+)");
  468. private File _dest;
  469. private String _fileName;
  470. private boolean _force;
  471. private boolean _ignoreErrors;
  472. private String _mirrorsHostname;
  473. private String _password;
  474. private String _path;
  475. private int _retries = 1;
  476. private boolean _skipChecksum;
  477. private String _src;
  478. private boolean _tryLocalNetwork = true;
  479. private String _username;
  480. private boolean _verbose;
  481. }