counters, logging
authorFrantišek Kučera <franta-hg@frantovo.cz>
Mon, 17 Nov 2014 20:05:57 +0100
changeset 1227e41d7f5e8d
parent 11 f517bafcf812
child 13 28aa5f597457
counters, logging
java/copy-image-resizer/src/cz/frantovo/copyImageResizer/CopyImageResizerException.java
java/copy-image-resizer/src/cz/frantovo/copyImageResizer/Counters.java
java/copy-image-resizer/src/cz/frantovo/copyImageResizer/InvalidOptionsException.java
java/copy-image-resizer/src/cz/frantovo/copyImageResizer/RecursiveImageResizer.java
java/copy-image-resizer/src/cz/frantovo/copyImageResizer/RecursiveOptions.java
java/copy-image-resizer/src/cz/frantovo/copyImageResizer/cli/CLIStarter.java
     1.1 --- a/java/copy-image-resizer/src/cz/frantovo/copyImageResizer/CopyImageResizerException.java	Mon Nov 17 18:17:13 2014 +0100
     1.2 +++ b/java/copy-image-resizer/src/cz/frantovo/copyImageResizer/CopyImageResizerException.java	Mon Nov 17 20:05:57 2014 +0100
     1.3 @@ -18,10 +18,11 @@
     1.4  package cz.frantovo.copyImageResizer;
     1.5  
     1.6  /**
     1.7 + * Superclass for all exceptions in this program.
     1.8   *
     1.9   * @author Ing. František Kučera (frantovo.cz)
    1.10   */
    1.11 -public class CopyImageResizerException extends Exception {
    1.12 +public abstract class CopyImageResizerException extends Exception {
    1.13  
    1.14  	public CopyImageResizerException() {
    1.15  	}
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/java/copy-image-resizer/src/cz/frantovo/copyImageResizer/Counters.java	Mon Nov 17 20:05:57 2014 +0100
     2.3 @@ -0,0 +1,77 @@
     2.4 +/**
     2.5 + * copy-image-resizer
     2.6 + * Copyright © 2014 František Kučera (frantovo.cz)
     2.7 + *
     2.8 + * This program is free software: you can redistribute it and/or modify
     2.9 + * it under the terms of the GNU General Public License as published by
    2.10 + * the Free Software Foundation, either version 3 of the License, or
    2.11 + * (at your option) any later version.
    2.12 + *
    2.13 + * This program is distributed in the hope that it will be useful,
    2.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    2.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    2.16 + * GNU General Public License for more details.
    2.17 + *
    2.18 + * You should have received a copy of the GNU General Public License
    2.19 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
    2.20 + */
    2.21 +package cz.frantovo.copyImageResizer;
    2.22 +
    2.23 +import java.util.EnumMap;
    2.24 +import java.util.Map;
    2.25 +
    2.26 +/**
    2.27 + *
    2.28 + * @author Ing. František Kučera (frantovo.cz)
    2.29 + */
    2.30 +public class Counters {
    2.31 +
    2.32 +	private final Map<COUNTER_TYPE, Integer> data = new EnumMap(COUNTER_TYPE.class);
    2.33 +
    2.34 +	public int increment(COUNTER_TYPE counter) {
    2.35 +		synchronized (data) {
    2.36 +			int value = get(counter);
    2.37 +			value++;
    2.38 +			data.put(counter, value);
    2.39 +			return value;
    2.40 +		}
    2.41 +	}
    2.42 +
    2.43 +	public int get(COUNTER_TYPE counter) {
    2.44 +		Integer value = data.get(counter);
    2.45 +		return value == null ? 0 : value;
    2.46 +	}
    2.47 +
    2.48 +	@Override
    2.49 +	public String toString() {
    2.50 +		StringBuilder sb = new StringBuilder();
    2.51 +
    2.52 +		sb.append("Counters: ");
    2.53 +
    2.54 +		for (COUNTER_TYPE counter : COUNTER_TYPE.values()) {
    2.55 +			sb.append(counter);
    2.56 +			sb.append("=");
    2.57 +			sb.append(get(counter));
    2.58 +			sb.append(" ");
    2.59 +			
    2.60 +		}
    2.61 +
    2.62 +		return sb.toString();
    2.63 +	}
    2.64 +
    2.65 +	public static enum COUNTER_TYPE {
    2.66 +
    2.67 +		DIRECTORIES,
    2.68 +		FILES,
    2.69 +		RESIZED,
    2.70 +		SKIPPED_SMALLER,
    2.71 +		SKIPPED_UNKNOWN_EXTENSION,
    2.72 +		SKIPPED_ERROR;
    2.73 +
    2.74 +		@Override
    2.75 +		public String toString() {
    2.76 +			return name().toLowerCase();
    2.77 +		}
    2.78 +
    2.79 +	}
    2.80 +}
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/java/copy-image-resizer/src/cz/frantovo/copyImageResizer/InvalidOptionsException.java	Mon Nov 17 20:05:57 2014 +0100
     3.3 @@ -0,0 +1,68 @@
     3.4 +/**
     3.5 + * copy-image-resizer
     3.6 + * Copyright © 2014 František Kučera (frantovo.cz)
     3.7 + *
     3.8 + * This program is free software: you can redistribute it and/or modify
     3.9 + * it under the terms of the GNU General Public License as published by
    3.10 + * the Free Software Foundation, either version 3 of the License, or
    3.11 + * (at your option) any later version.
    3.12 + *
    3.13 + * This program is distributed in the hope that it will be useful,
    3.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    3.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    3.16 + * GNU General Public License for more details.
    3.17 + *
    3.18 + * You should have received a copy of the GNU General Public License
    3.19 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
    3.20 + */
    3.21 +package cz.frantovo.copyImageResizer;
    3.22 +
    3.23 +import java.util.ArrayList;
    3.24 +import java.util.Collection;
    3.25 +import java.util.Collections;
    3.26 +
    3.27 +/**
    3.28 + *
    3.29 + * @author Ing. František Kučera (frantovo.cz)
    3.30 + */
    3.31 +public class InvalidOptionsException extends CopyImageResizerException {
    3.32 +
    3.33 +	private final Collection<OptionProblem> problems = new ArrayList<>();
    3.34 +
    3.35 +	public Collection<OptionProblem> getProblems() {
    3.36 +		return Collections.unmodifiableCollection(problems);
    3.37 +	}
    3.38 +
    3.39 +	public void addProblem(OptionProblem p) {
    3.40 +		problems.add(p);
    3.41 +	}
    3.42 +
    3.43 +	public boolean hasProblems() {
    3.44 +		return !problems.isEmpty();
    3.45 +	}
    3.46 +
    3.47 +	public static class OptionProblem {
    3.48 +
    3.49 +		private final String description;
    3.50 +		private final Throwable exception;
    3.51 +
    3.52 +		public OptionProblem(String description) {
    3.53 +			this.description = description;
    3.54 +			this.exception = null;
    3.55 +		}
    3.56 +
    3.57 +		public OptionProblem(String description, Throwable exception) {
    3.58 +			this.description = description;
    3.59 +			this.exception = exception;
    3.60 +		}
    3.61 +
    3.62 +		public String getDescription() {
    3.63 +			return description;
    3.64 +		}
    3.65 +
    3.66 +		public Throwable getException() {
    3.67 +			return exception;
    3.68 +		}
    3.69 +	}
    3.70 +
    3.71 +}
     4.1 --- a/java/copy-image-resizer/src/cz/frantovo/copyImageResizer/RecursiveImageResizer.java	Mon Nov 17 18:17:13 2014 +0100
     4.2 +++ b/java/copy-image-resizer/src/cz/frantovo/copyImageResizer/RecursiveImageResizer.java	Mon Nov 17 20:05:57 2014 +0100
     4.3 @@ -37,6 +37,8 @@
     4.4  public class RecursiveImageResizer {
     4.5  
     4.6  	private static final Logger log = Logger.getLogger(RecursiveImageResizer.class.getName());
     4.7 +	
     4.8 +	private final Counters counters = new Counters();
     4.9  
    4.10  	private final SingleImageResizer resizer = new SingleImageResizer();
    4.11  
    4.12 @@ -46,8 +48,9 @@
    4.13  		this.options = options;
    4.14  	}
    4.15  
    4.16 -	public void resize() throws RecursiveException, ResizeException {
    4.17 +	public Counters resize() throws RecursiveException, ResizeException {
    4.18  		resizeDirectory(options.getInput());
    4.19 +		return counters;
    4.20  	}
    4.21  
    4.22  	private void resizeFile(File inputFile) throws ResizeException {
    4.23 @@ -70,7 +73,7 @@
    4.24  								resizer.resize(image, output, size, format);
    4.25  							}
    4.26  						} else {
    4.27 -							log.log(Level.FINER, "File: {0} has already required size → just copy", inputFileRelative);
    4.28 +							log.log(Level.FINER, "File: {0} has already required (or smaller) size → just copy", inputFileRelative);
    4.29  							justCopy(inputFile, outputFile);
    4.30  						}
    4.31  					}
     5.1 --- a/java/copy-image-resizer/src/cz/frantovo/copyImageResizer/RecursiveOptions.java	Mon Nov 17 18:17:13 2014 +0100
     5.2 +++ b/java/copy-image-resizer/src/cz/frantovo/copyImageResizer/RecursiveOptions.java	Mon Nov 17 20:05:57 2014 +0100
     5.3 @@ -63,4 +63,26 @@
     5.4  	public void addSize(SizeSpecification size) {
     5.5  		sizes.add(size);
     5.6  	}
     5.7 +
     5.8 +	public void validate() throws InvalidOptionsException {
     5.9 +		InvalidOptionsException e = new InvalidOptionsException();
    5.10 +
    5.11 +		if (input == null) {
    5.12 +			e.addProblem(new InvalidOptionsException.OptionProblem("input directory must be specified"));
    5.13 +		} else if (!input.isDirectory()) {
    5.14 +			e.addProblem(new InvalidOptionsException.OptionProblem("input directory must exist and be a directory: " + input));
    5.15 +		}
    5.16 +
    5.17 +		if (output == null) {
    5.18 +			e.addProblem(new InvalidOptionsException.OptionProblem("output directory must be specified"));
    5.19 +		}
    5.20 +
    5.21 +		if (sizes.isEmpty()) {
    5.22 +			e.addProblem(new InvalidOptionsException.OptionProblem("at least one size (output resolution) must be specified"));
    5.23 +		}
    5.24 +
    5.25 +		if (e.hasProblems()) {
    5.26 +			throw e;
    5.27 +		}
    5.28 +	}
    5.29  }
     6.1 --- a/java/copy-image-resizer/src/cz/frantovo/copyImageResizer/cli/CLIStarter.java	Mon Nov 17 18:17:13 2014 +0100
     6.2 +++ b/java/copy-image-resizer/src/cz/frantovo/copyImageResizer/cli/CLIStarter.java	Mon Nov 17 20:05:57 2014 +0100
     6.3 @@ -17,11 +17,14 @@
     6.4   */
     6.5  package cz.frantovo.copyImageResizer.cli;
     6.6  
     6.7 +import cz.frantovo.copyImageResizer.Counters;
     6.8 +import cz.frantovo.copyImageResizer.InvalidOptionsException;
     6.9  import cz.frantovo.copyImageResizer.RecursiveException;
    6.10  import cz.frantovo.copyImageResizer.RecursiveImageResizer;
    6.11  import cz.frantovo.copyImageResizer.RecursiveOptions;
    6.12  import cz.frantovo.copyImageResizer.ResizeException;
    6.13  import java.util.logging.Level;
    6.14 +import java.util.logging.LogRecord;
    6.15  import java.util.logging.Logger;
    6.16  
    6.17  /**
    6.18 @@ -37,10 +40,20 @@
    6.19  		try {
    6.20  			CLIParser parser = new CLIParser();
    6.21  			RecursiveOptions options = parser.parseOptions(args);
    6.22 +			options.validate();
    6.23  			RecursiveImageResizer resizer = new RecursiveImageResizer(options);
    6.24 -			resizer.resize();
    6.25 +			Counters counters = resizer.resize();
    6.26 +			log.log(Level.INFO, "Recursive copy/resize finished. {0}", counters);
    6.27  		} catch (CLIParserException e) {
    6.28  			log.log(Level.SEVERE, "Unable to parse CLI options", e);
    6.29 +		} catch (InvalidOptionsException e) {
    6.30 +			log.log(Level.SEVERE, "Invalid CLI options", e);
    6.31 +			for (InvalidOptionsException.OptionProblem p : e.getProblems()) {
    6.32 +				LogRecord r = new LogRecord(Level.SEVERE, "Option problem: {0}");
    6.33 +				r.setThrown(p.getException());
    6.34 +				r.setParameters(new Object[]{p.getDescription()});
    6.35 +				log.log(r);
    6.36 +			}
    6.37  		} catch (RecursiveException e) {
    6.38  			log.log(Level.SEVERE, "Error while processing filesystem hierarchy", e);
    6.39  		} catch (ResizeException e) {