package org.apollo.update;

import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.apollo.Service;
import org.apollo.fs.IndexedFileSystem;

/**
 * A class which services file requests.
 * 
 * @author Graham
 */
public final class UpdateService extends Service {

	/**
	 * The number of request types.
	 */
	private static final int REQUEST_TYPES = 3;

	/**
	 * The number of threads per request type.
	 */
	private static final int THREADS_PER_REQUEST_TYPE = Runtime.getRuntime().availableProcessors();

	/**
	 * The update dispatcher.
	 */
	private final UpdateDispatcher dispatcher = new UpdateDispatcher();

	/**
	 * The executor service.
	 */
	private final ExecutorService service;

	/**
	 * A list of request workers.
	 */
	private final List<RequestWorker<?, ?>> workers = new ArrayList<>();

	/**
	 * Creates the update service.
	 */
	public UpdateService() {
		int totalThreads = REQUEST_TYPES * THREADS_PER_REQUEST_TYPE;
		service = Executors.newFixedThreadPool(totalThreads);
	}

	/**
	 * Gets the update dispatcher.
	 * 
	 * @return The update dispatcher.
	 */
	public UpdateDispatcher getDispatcher() {
		return dispatcher;
	}

	/**
	 * Starts the threads in the pool.
	 */
	@Override
	public void start() {
		int release = getContext().getRelease().getReleaseNumber();
		try {
			Path base = Paths.get("data/fs/", Integer.toString(release));
			for (int i = 0; i < THREADS_PER_REQUEST_TYPE; i++) {
				workers.add(new JagGrabRequestWorker(dispatcher, new IndexedFileSystem(base, true)));
				workers.add(new OnDemandRequestWorker(dispatcher, new IndexedFileSystem(base, true)));
				workers.add(new HttpRequestWorker(dispatcher, new IndexedFileSystem(base, true)));
			}

			for (RequestWorker<?, ?> worker : workers) {
				service.submit(worker);
			}
		} catch (Exception ex) {
			System.err.println("Error adding request workers - " + ex.getMessage());
		}
	}

	/**
	 * Stops the threads in the pool.
	 */
	public void stop() {
		for (RequestWorker<?, ?> worker : workers) {
			worker.stop();
		}

		service.shutdownNow();
	}

}
@@ -21,16 +21,54 @@
 pdate;%0A%0A
+import java.io.FileNotFoundException;%0A
 import j
@@ -248,16 +248,81 @@
 ecutors;
+%0Aimport java.util.logging.Level;%0Aimport java.util.logging.Logger;
 %0A%0Aimport
@@ -743,24 +743,153 @@
 cessors();%0A%0A
+%09/**%0A%09 * The logger for this class.%0A%09 */%0A%09private static final Logger logger = Logger.getLogger(UpdateService.class.getName());%0A%0A
 %09/**%0A%09 * The
@@ -1517,54 +1517,8 @@
 %09%7D%0A%0A
-%09/**%0A%09 * Starts the threads in the pool.%0A%09 */%0A
 %09@Ov
@@ -2015,196 +2015,188 @@
 %09%09%7D%0A
-%0A
 %09%09
-%09for (RequestWorker%3C?, ?%3E worker : workers) %7B%0A%09%09%09%09service.submit(worker);%0A%09%09%09%7D%0A%09%09%7D catch (Exception ex) %7B%0A%09%09%09System.err.println(%22Error adding request workers - %22 + ex.getMessage());%0A%09%09%7D
+%7D catch (FileNotFoundException reason) %7B%0A%09%09%09logger.log(Level.SEVERE, %22Unable to find index or data files from the file system.%22, reason);%0A%09%09%7D%0A%0A%09%09workers.forEach(service::submit);
 %0A%09%7D%0A
@@ -2269,76 +2269,46 @@
 %7B%0A%09%09
-for (RequestWorker%3C?, ?%3E worker : workers) %7B%0A%09%09%09worker.
+workers.forEach(RequestWorker::
 stop
-(
 );%0A
-%09%09%7D%0A%0A
 %09%09se

Improve UpdateService by making it use a Logger and method referencing. - Use correct thrown exception. - Use forEach and method referencing where possible.