Commits

P_W999  committed 2629872

- fixed some problems
- added logic to read all tags (including unsupported tags)

  • Participants
  • Parent commits 60b9ba8

Comments (0)

Files changed (14)

File src/be/pw/jexif/DemoApp.java

 import java.io.FileInputStream;
 import java.io.IOException;
 import java.util.Locale;
+import java.util.Map;
+import java.util.Map.Entry;
 import java.util.Properties;
 import java.util.concurrent.TimeUnit;
 
 		LOG.info("FOCAL_LENGTH value is for read 4 = {}", info4.getTag(ExifIFD.FOCALLENGTH));
 		LOG.info("Writing 5 to FOCAL_LENGTH for write 1 -> {}", write1.setTag(ExifIFD.FOCALLENGTH, "5.0"));
 		LOG.info("FOCAL_LENGTH value is for write 1 = {}", write1.getTag(ExifIFD.FOCALLENGTH));
+		Map<String, String> all = info2.getAllTags();
+		for (Entry<String, String> e : all.entrySet()) {
+			LOG.info("ALL: {} : {}", e.getKey(), e.getValue());
+		}
 		watch.stop();
 
 		JExifInfo infoError = tool.getInfo(new File("c:\\does\\not\\exist"));

File src/be/pw/jexif/JExifInfo.java

 package be.pw.jexif;
 
 import java.io.File;
+import java.util.Map;
 
 import be.pw.jexif.enums.tag.Tag;
 import be.pw.jexif.exception.ExifError;
      *
      * @param tag   the tag to write to.
      * @param value the value to write.
-     * @return the result.
+     * @return the exact value that was read from the image after writing it.
      * @throws JExifException
      * @throws ExifError
      */
         exifTool.writeTagInfo(file, tag, value);
         return getExactTag(tag);
     }
+    
+    public Map<String, String> getAllTags() throws ExifError, JExifException {
+    	return exifTool.getAllTagInfo(file, false);
+    }
 
 }

File src/be/pw/jexif/JExifTool.java

 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
      *
      * @param file the image file from which tags shall be read from or written to.
      * @return a JExifInfo object.
+     * @throws IOException if the file does not exist of if it's folder
      */
     @Beta
-    public JExifInfo getInfo(final File file) {
+    public JExifInfo getInfo(final File file) throws IOException {
         Preconditions.checkNotNull(file);
+        if (!file.exists() || file.isDirectory()) {
+        	throw new IOException(Cal10nUtil.get(Errors.IO_FILE_NOT_VALID, file.getName()));
+        }
         return new JExifInfo(this, file);
     }
 
     }
 
     boolean writeTagInfo(final File file, final Tag tag, final String value) throws ExifError, JExifException {
-        if (value == null || value.isEmpty()) {
-            return clearTagInfo(file, tag);
-        }
         startIfNecessary();
         int i = 0;
         IAction action;
         return true;
     }
 
-    boolean clearTagInfo(final File file, final Tag tag) {
-        startIfNecessary();
-        throw new RuntimeException("Not implemented yet, sorry :O");
+    Map<String, String> getAllTagInfo(final File file, boolean exact) throws ExifError, JExifException {
+    	startIfNecessary();
+    	int i = 0;
+        IAction action;
+        EventHandler handler;
+        try {
+            LOG.trace("Starting readTagInfo");
+            if (exact) {
+                action = null;
+            } else {
+            	action = ActionFactory.createTagReadAllAction(file);
+            }
+            String[] arguments = action.buildArguments();
+            for (String argument : arguments) {
+                argsWriter.append(argument).append("\r\n");
+            }
+            handler = new EventHandler();
+            bus.register(handler);
+            LOG.trace("Registered the EventHandler");
+            argsWriter.flush();
+            while (!handler.isFinished() && i <= deadLock) {
+                Thread.sleep(50);
+                i += 50;
+            }
+            if (!handler.isFinished()) {
+                LOG.error(Cal10nUtil.get(Errors.DEADLOCK, i));
+                throw new JExifException(Cal10nUtil.get(Errors.DEADLOCK, i));
+            }
+            bus.unregister(handler);
+        } catch (IOException e) {
+            LOG.error(Cal10nUtil.get(Errors.IO_ARGSFILE), e);
+            throw new JExifException(e);
+        } catch (InterruptedException e) {
+            LOG.error(Cal10nUtil.get(Errors.INTERRUPTED_SLEEP), e);
+            throw new JExifException(e);
+        }
+        LOG.trace("Handler finished");
+        List<String> results = handler.getResultList();
+        List<String> errors = handler.getErrorList();
+        LOG.trace("Parsing results");
+        ResultHandler.run(action, results, errors);
+        Map<String, String> tags = action.getUnsupportedTags();
+        for (Entry<Tag, String> e : action.getResult().entrySet()) {
+        	tags.put(e.getKey().getName(), e.getValue());
+        }
+        return tags;
     }
 
 }

File src/be/pw/jexif/exception/JExifValidationException.java

+/*******************************************************************************
+ * Copyright 2012 P_W999
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package be.pw.jexif.exception;
+
+public class JExifValidationException extends JExifException {
+
+	/**
+	 * UID
+	 */
+	private static final long serialVersionUID = 3697142392447599863L;
+
+	/**
+	 * Hidden constructor to prevent creation of JExifExceptions without information
+	 */
+	@SuppressWarnings("unused")
+	private JExifValidationException() {
+		super();
+	}
+
+	/**
+	 * @param message the reason of the exception or a clear message for the user
+	 * @param cause the cause
+	 */
+	public JExifValidationException(final String message, final Throwable cause) {
+		super(message, cause);
+	}
+
+	/**
+	 * @param message the reason of the exception or a clear message for the user
+	 */
+	public JExifValidationException(final String message) {
+		super(message);
+	}
+
+	/**
+	 * @param cause the cause of the exception
+	 */
+	public JExifValidationException(final Throwable cause) {
+		super(cause);
+	}
+}

File src/be/pw/jexif/internal/action/AbstractAction.java

 	protected File file = null;
 	protected Set<Tag> tags = null;
 	private final Map<Tag, String> results;
+	private Map<String, String> unsupportedTags;
 	private UUID id = null;
 
 	protected AbstractAction() {
 		this.tags = new HashSet<>();
 		this.results = new HashMap<>();
+		this.unsupportedTags = new HashMap<>();
 		this.id = UUID.randomUUID();
 		LOG.debug("New action created with UUID {}", id);
 	}
 	public void addResult(final Tag tag, final String result) {
 		results.put(tag, result);
 	}
+	
+
+	@Override
+	public void addUnsupportedResult(final String tag, final String result) {
+		unsupportedTags.put(tag, result);
+	}
+
+	/**
+	 * @return the unsupportedTags
+	 */
+	@Override
+	public final Map<String, String> getUnsupportedTags() {
+		return unsupportedTags;
+	}
 
 }

File src/be/pw/jexif/internal/action/IAction.java

 	 */
 	void addResult(Tag tag, String result);
 
+	public abstract Map<String, String> getUnsupportedTags();
+
+	public abstract void addUnsupportedResult(final String tag, final String result);
+
 }

File src/be/pw/jexif/internal/action/impl/ActionFactory.java

 		TagReadExactAction read = new TagReadExactAction();
 		read.setParams(file, tags);
 		return read;
-
 	}
 
 	public static TagWriteAction createTagWriteAction(final File file, final Map<Tag, String> valuesToWrite) throws JExifValidationException, IOException {
 		TagWriteAction read = new TagWriteAction();
 		read.setParams(file, valuesToWrite);
 		return read;
-
+	}
+	
+	public static TagReadAllAction createTagReadAllAction(final File file) {
+		TagReadAllAction readAll = new TagReadAllAction();
+		readAll.setParams(file);
+		return readAll;
 	}
 }

File src/be/pw/jexif/internal/action/impl/TagReadAllAction.java

+/**
+ * 
+ */
+package be.pw.jexif.internal.action.impl;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import be.pw.jexif.enums.Errors;
+import be.pw.jexif.exception.JExifException;
+import be.pw.jexif.internal.action.AbstractAction;
+import be.pw.jexif.internal.constants.ExecutionConstant;
+import be.pw.jexif.internal.util.ArrayUtil;
+import be.pw.jexif.internal.util.Cal10nUtil;
+
+/**
+ * Action that reads all the tag values from an image.
+ * @author phillip
+ *
+ */
+public class TagReadAllAction extends AbstractAction {
+
+	/**
+	 * The logger for this class.
+	 */
+	private static final Logger LOG = LoggerFactory.getLogger(TagReadAllAction.class);
+	
+
+	
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public String[] buildArguments() throws JExifException {
+		try {
+			int size = 7;
+			String[] arguments = new String[size];
+			int i = 0;
+			arguments[i++] = ExecutionConstant.ECHO;
+			arguments[i++] = ExecutionConstant.START + " " + getId();
+			arguments[i++] = ExecutionConstant.SHORT_FORMAT;
+			arguments[i++] = file.getCanonicalPath();
+			arguments[i++] = ExecutionConstant.ECHO;
+			arguments[i++] = ExecutionConstant.STOP + " " + getId();
+			arguments[i] = ExecutionConstant.EXECUTE;
+			LOG.trace("Arguments are : " + ArrayUtil.toString(arguments));
+			return arguments;
+		} catch (IOException e) {
+			LOG.error(Cal10nUtil.get(Errors.IO_BUILD_ARGUMENTS), e);
+			throw new JExifException(e);
+		} 
+	}
+
+	void setParams(File file) {
+		this.file = file;
+	}
+
+	
+}

File src/be/pw/jexif/internal/result/impl/ParserFactory.java

 import be.pw.jexif.exception.JExifException;
 import be.pw.jexif.internal.action.IAction;
 import be.pw.jexif.internal.action.impl.TagReadAction;
+import be.pw.jexif.internal.action.impl.TagReadAllAction;
 import be.pw.jexif.internal.action.impl.TagReadExactAction;
 import be.pw.jexif.internal.action.impl.TagWriteAction;
 import be.pw.jexif.internal.result.IResultParser;
 		if (action.getClass().equals(TagWriteAction.class)) {
 			return new TagWriteParser();
 		}
+		if (action.getClass().equals(TagReadAllAction.class)) {
+			return new TagReadAllParser();
+		}
 		LOG.error(Cal10nUtil.get(Errors.PARSER_UNKNOWNTYPE, action.getClass().getName()));
 		throw new JExifException(Cal10nUtil.get(Errors.PARSER_UNKNOWNTYPE, action.getClass().getName()));
 	}

File src/be/pw/jexif/internal/result/impl/TagReadAllParser.java

+/*******************************************************************************
+ * Copyright 2012 P_W999
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package be.pw.jexif.internal.result.impl;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Preconditions;
+import com.google.common.base.Splitter;
+
+import be.pw.jexif.enums.Errors;
+import be.pw.jexif.enums.tag.Tag;
+import be.pw.jexif.internal.action.IAction;
+import be.pw.jexif.internal.action.impl.TagReadAllAction;
+import be.pw.jexif.internal.constants.ExecutionConstant;
+import be.pw.jexif.internal.result.IResultParser;
+import be.pw.jexif.internal.util.Cal10nUtil;
+import be.pw.jexif.internal.util.TagUtil;
+
+public class TagReadAllParser implements IResultParser {
+
+	private static final Logger LOG = LoggerFactory.getLogger(TagReadAllParser.class);
+	
+	@Override
+	public void parse(IAction action, String actionUID, List<String> result) {
+		Preconditions.checkArgument(action.getClass().equals(validFor()), Cal10nUtil.get(Errors.PARSER_MISMATCH, getClass().getSimpleName(), action.getClass().getSimpleName()));
+		Preconditions.checkArgument(action.getId().equals(actionUID), "Invalid action UID");
+		
+		Tag t;
+		String r;
+		for (String line : result) {
+			if (!line.contains(ExecutionConstant.EXIFTOOLREADY) && !line.isEmpty() && line.contains(":")) {
+				Iterable<String> output = Splitter.on(":").limit(2).omitEmptyStrings().trimResults().split(line);
+				Iterator<String> i = output.iterator();
+				String u = i.next();
+				t = TagUtil.forName(u);
+				if (i.hasNext()) { // result exists
+					r = i.next();
+				} else {
+					r = null;
+				}
+				if (i.hasNext()) {
+					LOG.warn("More values exist in the iterator for line: {}", line);
+				}
+				if (t != null && r != null && !r.isEmpty()) {
+					LOG.trace("Found results {} for Tag {}", r, t.getName());
+					action.addResult(t, r);
+				} else {
+					if (t == null) {
+						LOG.trace("Found unsupported tag: {}", u);
+						((TagReadAllAction) action).addUnsupportedResult(u, r);
+					} else {
+						LOG.warn("Could not add result {}", line);
+					}
+				}
+			}
+		}
+	}
+
+	@Override
+	public Class<? extends IAction> validFor() {
+		return TagReadAllAction.class;
+	}
+
+}

File src/be/pw/jexif/internal/result/impl/TagReadParser.java

 	 */
 	@Override
 	public final void parse(final IAction action, final String actionUID, final List<String> result)  {
-		Preconditions.checkArgument(!action.getClass().equals(validFor()), Cal10nUtil.get(Errors.PARSER_MISMATCH, getClass().getSimpleName(), action.getClass().getSimpleName()));
-		Preconditions.checkArgument(!action.getId().equals(actionUID), "Invalid action UID");
+		Preconditions.checkArgument(action.getClass().equals(validFor()), Cal10nUtil.get(Errors.PARSER_MISMATCH, getClass().getSimpleName(), action.getClass().getSimpleName()));
+		Preconditions.checkArgument(action.getId().equals(actionUID), "Invalid action UID");
 		
 		Tag t;
 		String r;
 					LOG.trace("Found results {} for Tag {}", r, t.getName());
 					action.addResult(t, r);
 				} else {
-					LOG.warn("Could not add result {0}", line);
+					LOG.warn("Could not add result {}", line);
 				}
 			}
 		}

File src/be/pw/jexif/internal/result/impl/TagWriteParser.java

 
 	@Override
 	public void parse(final IAction action, final String actionUID, final List<String> result) {
-		Preconditions.checkArgument(!action.getClass().equals(validFor()), Cal10nUtil.get(Errors.PARSER_MISMATCH, getClass().getSimpleName(), action.getClass().getSimpleName()));
-		Preconditions.checkArgument(!action.getId().equals(actionUID), "Invalid action UID");
+		Preconditions.checkArgument(action.getClass().equals(validFor()), Cal10nUtil.get(Errors.PARSER_MISMATCH, getClass().getSimpleName(), action.getClass().getSimpleName()));
+		Preconditions.checkArgument(action.getId().equals(actionUID), "Invalid action UID");
 
 		for (String line : result) {
 			if (!line.contains(ExecutionConstant.EXIFTOOLREADY) && !line.isEmpty()) {

File src/log4j.properties

 #      FATAL, ERROR, WARN, INFO, DEBUG
 #
 #------------------------------------------------------------------------------
-log4j.rootCategory=DEBUG, S
+log4j.rootCategory=INFO, S
 
 #log4j.logger.be.pw=DEBUG
 log4j.logger.be.pw.jexif.internal.thread.event.DebugHandler=FATAL

File test/be/pw/jexif/JExifToolTest.java

 import static org.fest.assertions.Assertions.assertThat;
 
 import java.io.File;
+import java.io.IOException;
 import java.util.Date;
 
 import org.fest.assertions.Fail;
 		tool = new JExifTool();
 	}
 
-	@BeforeMethod(groups = { "write", "medium" }, alwaysRun = false)
+	@BeforeMethod(groups = { "write", "medium" }, alwaysRun = true)
 	public void beforeWrite() throws Exception {
 		System.out.println("CREATING TEMP FILES");
 		write01 = File.createTempFile("testng_tmp_01", ".jpg");
 		assertThat(iso).isEqualTo("1600");
 	}
 
-	@Test(groups = { "read-human", "simple", "error" }, suiteName = "simple", expectedExceptions = { ExifError.class }, expectedExceptionsMessageRegExp = ".*File not found.*")
+	@Test(groups = { "read-human", "simple", "error" }, suiteName = "simple", expectedExceptions = { IOException.class }, expectedExceptionsMessageRegExp = "There was a problem reading the file fail.jpg")
 	public void testExifErrorOnFileNotFoundHumanReadable() throws Exception {
 		File nonExistingFile = new File("c:\\bla\\haha\\lol\\fail.jpg");
 		JExifInfo info = tool.getInfo(nonExistingFile);
 		info.getTag(ExifIFD.APERTUREVALUE);
 	}
 
-	@Test(groups = { "read-exact", "simple", "error" }, suiteName = "simple", expectedExceptions = { ExifError.class }, expectedExceptionsMessageRegExp = ".*File not found.*")
+	@Test(groups = { "read-exact", "simple", "error" }, suiteName = "simple", expectedExceptions = { IOException.class }, expectedExceptionsMessageRegExp = "There was a problem reading the file fail.jpg")
 	public void testExifErrorOnFileNotFoundExact() throws Exception {
 		File nonExistingFile = new File("c:\\bla\\haha\\lol\\fail.jpg");
 		JExifInfo info = tool.getInfo(nonExistingFile);