001: /*
002: * uDig - User Friendly Desktop Internet GIS client
003: * http://udig.refractions.net
004: * (C) 2004, Refractions Research Inc.
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation;
009: * version 2.1 of the License.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: */
017: package net.refractions.udig.catalog.internal.geotiff;
018:
019: import java.io.File;
020: import java.io.Serializable;
021: import java.net.MalformedURLException;
022: import java.net.URL;
023: import java.util.HashMap;
024: import java.util.Map;
025:
026: import javax.imageio.metadata.IIOMetadata;
027: import javax.media.jai.JAI;
028: import javax.media.jai.RenderedOp;
029:
030: import net.refractions.udig.catalog.IService;
031: import net.refractions.udig.catalog.ServiceExtension2;
032: import net.refractions.udig.catalog.geotiff.internal.Messages;
033:
034: import org.geotools.gce.geotiff.GeoTiffFormat;
035: import org.geotools.gce.geotiff.GeoTiffFormatFactorySpi;
036: import org.geotools.gce.geotiff.GeoTiffIIOMetadataAdapter;
037:
038: import com.sun.media.jai.operator.ImageReadDescriptor;
039:
040: /**
041: * Provides the interface to the catalog service extension point.
042: * <p>
043: * This class is responsible for ensuring that only those services that the GeoTiff plug-in is
044: * capable of processing are created.
045: * </p>
046: *
047: * @author mleslie
048: * @since 0.6.0
049: */
050: public class GeoTiffServiceExtension implements ServiceExtension2 {
051: /** <code>URL_PARAM</code> field */
052: public final static String URL_PARAM = "URL"; //$NON-NLS-1$
053:
054: private static GeoTiffFormatFactorySpi factory;
055: private static GeoTiffFormat format;
056:
057: /**
058: * Construct <code>GeoTiffServiceExtension</code>.
059: */
060: public GeoTiffServiceExtension() {
061: super ();
062: }
063:
064: public IService createService(URL id,
065: Map<String, Serializable> params) {
066: URL id2 = id;
067: if (id2 == null) {
068: id2 = extractID(params);
069: }
070: if (!canProcess(extractID(params))) {
071: return null;
072: }
073: GeoTiffServiceImpl service = new GeoTiffServiceImpl(
074: extractID(params), getFactory());
075: return service;
076: }
077:
078: private URL extractID(Map<String, Serializable> params) {
079: URL id;
080: if (params.containsKey(URL_PARAM)) {
081: Object param = params.get(URL_PARAM);
082: if (param instanceof String) {
083: try {
084: id = new URL((String) param);
085: } catch (MalformedURLException ex) {
086: return null;
087: }
088: } else if (param instanceof URL) {
089: id = (URL) param;
090: } else {
091: return null;
092: }
093: } else {
094: return null;
095: }
096: return id;
097: }
098:
099: private static GeoTiffFormat getFormat() {
100: if (format == null) {
101: format = (GeoTiffFormat) getFactory().createFormat();
102: }
103: return format;
104: }
105:
106: /**
107: * Finds or creates a GeoTiffFormatFactorySpi.
108: *
109: * @return Default GeoTiffFormatFactorySpi
110: */
111: public static GeoTiffFormatFactorySpi getFactory() {
112: if (factory == null) {
113: factory = new GeoTiffFormatFactorySpi();
114: }
115: return factory;
116: }
117:
118: private boolean canProcess(URL id) {
119: if (reasonForFailure(id) == null)
120: return true;
121: return false;
122: }
123:
124: public Map<String, Serializable> createParams(URL url) {
125: if (!canProcess(url))
126: return null;
127:
128: Map<String, Serializable> params = new HashMap<String, Serializable>();
129: if (url != null) {
130: params.put(URL_PARAM, url);
131: }
132: return params;
133: }
134:
135: public String reasonForFailure(Map<String, Serializable> params) {
136: return reasonForFailure(extractID(params));
137: }
138:
139: public String reasonForFailure(URL url) {
140: if (url == null) {
141: return Messages.GeoTiffServiceExtension_nullURL;
142: }
143:
144: if (!isSupportedExtension(url))
145: return Messages.GeoTiffServiceExtension_badExt;
146:
147: File file = null;
148: try {
149: file = new File(url.getFile());
150: } catch (IllegalArgumentException ex) {
151: return url.toExternalForm()
152: + Messages.GeoTiffServiceExtension_notFile;
153: }
154:
155: if (!file.exists())
156: return file + Messages.GeoTiffServiceExtension_notExist;
157:
158: String result = geotiffFile(file);
159: if (result != null)
160: return result;
161: try {
162: if (!getFormat().accepts(file))
163: return Messages.GeoTiffServiceExtension_unknown;
164: } catch (RuntimeException ex) {
165: return Messages.GeoTiffServiceExtension_unknown;
166: }
167: return null;
168: }
169:
170: private boolean isSupportedExtension(URL url) {
171: String file = url.getFile();
172: file = file.toLowerCase();
173:
174: return (file.endsWith(".tiff") || file.endsWith(".tif")); //$NON-NLS-1$
175: }
176:
177: private String geotiffFile(File file) {
178: RenderedOp img = null;
179: try {
180: img = JAI.create("ImageRead", file); //$NON-NLS-1$
181: } catch (Throwable e) {
182: return Messages.GeoTiffServiceExtension_notReadWError + e;
183: }
184: if (img == null) {
185: return Messages.GeoTiffServiceExtension_NotRead;
186: }
187:
188: // Get the metadata object.
189: Object metadataImage = img
190: .getProperty(ImageReadDescriptor.PROPERTY_NAME_METADATA_IMAGE);
191:
192: if (!(metadataImage instanceof IIOMetadata)) {
193: return Messages.GeoTiffServiceExtension_NotTiff1;
194: }
195:
196: IIOMetadata check = (IIOMetadata) metadataImage;
197:
198: GeoTiffIIOMetadataAdapter metadata = new GeoTiffIIOMetadataAdapter(
199: check);
200:
201: // does the GeoKey Directory exist?
202: boolean geoTiffFile = false;
203:
204: try {
205: metadata.getGeoKeyDirectoryVersion();
206: geoTiffFile = true;
207: } catch (UnsupportedOperationException ue) {
208: // this state is captured by the geoTiffFile flag == false
209: }
210:
211: if (!geoTiffFile)
212: return Messages.GeoTiffServiceExtension_NotTiff;
213:
214: return null;
215: }
216:
217: }
|