package net.sourceforge.gpstools.exif;
/* gpsdings
* Copyright (C) 2006 Moritz Ringler
* $Id: WriterFactory.java 441 2010-12-13 20:04:20Z ringler $
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import java.util.EnumMap;
import java.util.Map;
import java.util.Collections;
import net.sourceforge.gpstools.xmp.ExiftoolXMPWriter;
import net.sourceforge.gpstools.xmp.XMPWriter;
/**
Constructs and caches GpsExifWriter instances.
**/
@SuppressWarnings("deprecation")
public class WriterFactory {
/** An enum that identifies GpsExifWriter types. **/
public enum ExifWriter {
/** An ExifWriter that uses Phil Harvey's ExifTool perl script or
stand-alone executable. **/
Exiftool,
/** An ExifWriter that uses the exiv2 stand-alone executable. **/
Exiv2,
/** A fast ExifWriter that uses the libexiv2/gpsdingsjni JNI library.**/
Libexiv2,
/** A fast all-java ExifWriter with no maker note support. **/
MediaUtil,
/** Exiftool XMP writer. Consider using XMP instead. **/
ExiftoolXMP,
/** XMP **/
XMP,
/** Apache Sanselan ExifWriter **/
Sanselan,
/** Default **/
Default
}
/** Constructs a new WriterFactory with an empty writer cache. **/
public WriterFactory(){
// explicit default constructor.
}
private Map<ExifWriter, GpsExifWriter> instanceCache =
Collections.synchronizedMap(new EnumMap<ExifWriter, GpsExifWriter>(ExifWriter.class));
/** Returns an Exif writer of the specified type. Subsequent
invocations of this method with the same <code>type</code>
argument will always return the same object.
@param progOrLib the path of the program or library to use, can be
<code>null</code> if this factory has already returned a
writer of the specified type, if the writer is a java writer and
its resources are on the classpath, or if the writer is a JNI writer
and its JNI library is on the java library path
@param type the type of exif writer
@return a GpsExifWriter of the specified type
@throws InstantiationException if a writer of the specified type
cannot be instantiated
**/
public GpsExifWriter getWriter(String progOrLib, ExifWriter type) throws InstantiationException{
synchronized(instanceCache){
if(!instanceCache.containsKey(type)){
switch(type){
case Exiftool:
instanceCache.put(type, new ExiftoolExifWriter(progOrLib));
break;
case Exiv2:
instanceCache.put(type, new Exiv2ExifWriter(progOrLib));
break;
case Libexiv2:
GpsExifWriter jniWriter = JNIExiv2ExifWriter.newInstance(progOrLib);
if(jniWriter != null){
instanceCache.put(type, jniWriter);
} else {
throw new InstantiationException("Cannot load native exif writer.");
}
break;
case MediaUtil:
instanceCache.put(type, newWriter("net.sourceforge.gpstools.exif.MediaUtilExifWriter", -1));
break;
case ExiftoolXMP:
instanceCache.put(type, new ExiftoolXMPWriter(progOrLib));
break;
case XMP:
instanceCache.put(type, new XMPWriter());
break;
case Sanselan:
instanceCache.put(type, newWriter("net.sourceforge.gpstools.exif.SanselanExifWriter",-1));
break;
case Default:
GpsExifWriter writer = newWriter("net.sourceforge.gpstools.exif.MediaUtilExifWriter",0);
if (writer == null){
writer = newWriter("net.sourceforge.gpstools.exif.SanselanExifWriter", -1);
}
instanceCache.put(type, writer);
break;
}
}
}
return instanceCache.get(type);
}
/** Tries to infer the type of GpsExifWriter form the program/library name
and if successfull returns an Exif writer of that type. Subsequent
invocations of this method with the same argument
will always return the same object.
@param progOrLib the path of the program or library to use, if
<code>null</code> the returned writer will be a pure java writer
@return a GpsExifWriter or <code>null</code>
@throws InstantiationException if an error occurred instantiating the
writer
**/
public GpsExifWriter getWriter(String s) throws InstantiationException{
String sl = (s == null)? null : s.toLowerCase();
GpsExifWriter result = null;
if (sl == null){
result = getWriter(s, ExifWriter.MediaUtil);
} else if(sl.indexOf("gpsdingsjni") >= 0){
result = getWriter(s, ExifWriter.Libexiv2);
} else if(sl.indexOf("exiftool") >= 0){
result = getWriter(s, ExifWriter.Exiftool);
} else if (sl.indexOf("exiv2") >= 0){
result = getWriter(s, ExifWriter.Exiv2);
}
return result;
}
private static GpsExifWriter newWriter(String klass, int lenient) throws InstantiationException{
GpsExifWriter result = null;
Throwable t = null;
try{
Class<?> c = Class.forName(klass);
Object o = c.newInstance();
if(o instanceof GpsExifWriter){
result = (GpsExifWriter) o;
}
} catch (ClassNotFoundException cx){
t = cx;
} catch (IllegalAccessException iax){
t = iax;
} catch (NoClassDefFoundError ncdfe){
t = ncdfe;
}
if (t != null){
switch (lenient){
case 0: break; //do nothing
case 1: System.err.println(t);
//$FALL-THROUGH$
default: throw new Error(t);
}
}
return result;
}
}