package ejercicio.ejer_t5_descarga;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;

public class DescargaFase2 {

	private static final boolean EXIT_ON_EXCEPTION = true;

	private List<DownloadedWeb> webs = Collections
			.synchronizedList(new ArrayList<>());

	private AtomicInteger totalChars = new AtomicInteger();

	private CountDownLatch finishedTasks;

	private String downloadURL(URL website) throws IOException {

		URLConnection connection = website.openConnection();
		BufferedReader in = new BufferedReader(
				new InputStreamReader(connection.getInputStream()));

		StringBuilder response = new StringBuilder();
		String inputLine;

		while ((inputLine = in.readLine()) != null)
			response.append(inputLine);

		in.close();

		return response.toString();
	}

	public List<String> loadURLs() throws IOException {
		return Files.readAllLines(Paths.get("webs.txt"));
	}

	private void exec() throws InterruptedException {

		List<String> urls;
		try {
			urls = loadURLs();
		} catch (IOException e) {
			System.out
					.println("Error reading webs.txt file: " + e.getMessage());
			return;
		}

		finishedTasks = new CountDownLatch(urls.size());

		long startTime = System.currentTimeMillis();

		for (String url : urls) {
			new Thread(() -> downloadAndProcessWeb(url)).start();
		}

		finishedTasks.await();

		long totalTime = System.currentTimeMillis() - startTime;

		printFinalReport(totalTime);
		
		System.exit(0);

	}

	private void printFinalReport(long totalTime) {

		System.out.println();
		System.out.println("Final report");
		System.out.println();
		System.out.println("Total downloaded chars: " + totalChars);
		System.out.println("Total time: " + totalTime + "ms");
		System.out.println();

		for (DownloadedWeb web : webs) {
			System.out.println("Web: " + web.getUrl());
			String webContent = web.getWebContent();
			if (webContent != null) {
				System.out.println("Chars: " + web.getWebContent().length());
			} else {
				System.out.println(
						"Error: " + web.getException().getClass().getName());
			}
			System.out.println();
		}
	}

	private void downloadAndProcessWeb(String url) {
		try {

			long startTime = System.currentTimeMillis();

			synchronized (this) {
				System.out.println("Start downloading: " + url.trim());
			}

			String webContent = downloadURL(new URL(url));

			int chars = webContent.length();
			totalChars.addAndGet(chars);

			long time = System.currentTimeMillis() - startTime;

			synchronized (this) {
				System.out.println("Downloaded web " + url);
				System.out.println("   Characters: " + chars);
				System.out.println(
						"   First chars: " + webContent.substring(0, 100));
				System.out.println("   Time: " + time + "ms");
				System.out.println();
			}

			webs.add(new DownloadedWeb(url, webContent));

			finishedTasks.countDown();

		} catch (Exception e) {

			synchronized (this) {
				System.out.println("Error downloading web " + url + ": "
						+ e.getClass().getName());
			}

			webs.add(new DownloadedWeb(url, e));

			if (EXIT_ON_EXCEPTION) {
				while (finishedTasks.getCount() != 0) {
					finishedTasks.countDown();
				}
			} else {
				finishedTasks.countDown();
			}
		}
	}

	public static void main(String[] args) throws InterruptedException {
		new DescargaFase2().exec();
	}
}

@@ -541,20 +541,16 @@
 lections
-%0A%09%09%09
 .synchro
@@ -678,16 +678,51 @@
 Tasks;%0A%0A
+%09private boolean aborted = false;%0A%0A
 %09private
@@ -872,21 +872,16 @@
 dReader(
-%0A%09%09%09%09
 new Inpu
@@ -1375,22 +1375,16 @@
 stem.out
-%0A%09%09%09%09%09
 .println
@@ -1758,18 +1758,16 @@
 lTime);%0A
-%09%09
 %0A%09%09Syste
@@ -1787,24 +1787,37 @@
 %7D%0A%0A%09private 
+synchronized 
 void printFi
@@ -2332,23 +2332,16 @@
 println(
-%0A%09%09%09%09%09%09
 %22Error: 
@@ -2799,16 +2799,37 @@
 tTime;%0A%0A
+%09%09%09if (!aborted) %7B%0A%0A%09
 %09%09%09synch
@@ -2837,32 +2837,33 @@
 onized (this) %7B%0A
+%09
 %09%09%09%09System.out.p
@@ -2895,16 +2895,17 @@
 + url);%0A
+%09
 %09%09%09%09Syst
@@ -2947,24 +2947,25 @@
 chars);%0A%09%09%09%09
+%09
 System.out.p
@@ -2971,23 +2971,16 @@
 println(
-%0A%09%09%09%09%09%09
 %22   Firs
@@ -3023,24 +3023,25 @@
  100));%0A%09%09%09%09
+%09
 System.out.p
@@ -3075,24 +3075,25 @@
  %22ms%22);%0A%09%09%09%09
+%09
 System.out.p
@@ -3101,27 +3101,29 @@
 intln();%0A%09%09%09
+%09
 %7D%0A%0A
+%09
 %09%09%09webs.add(
@@ -3163,16 +3163,17 @@
 ));%0A%0A%09%09%09
+%09
 finished
@@ -3186,24 +3186,29 @@
 countDown();
+%0A%09%09%09%7D
 %0A%0A%09%09%7D catch 
@@ -3313,15 +3313,9 @@
 %22: %22
-%0A%09%09%09%09%09%09
+ 
 + e.
@@ -3408,24 +3408,44 @@
 XCEPTION) %7B%0A
+%09%09%09%09aborted = true;%0A
 %09%09%09%09while (f

Add aborted control in DescargarFase2