/*******************************************************************************
* Copyright 2012 Geoscience Australia
*
* 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 au.gov.ga.earthsci.worldwind.common.layers.kml.relativeio;
import gov.nasa.worldwind.exception.WWUnrecognizedException;
import gov.nasa.worldwind.ogc.kml.KMLConstants;
import gov.nasa.worldwind.ogc.kml.io.KMLDoc;
import gov.nasa.worldwind.util.Logging;
import gov.nasa.worldwind.util.WWIO;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.zip.ZipException;
import java.util.zip.ZipInputStream;
/**
* This class acts as a Factory for {@link RelativeKMLDoc} subclasses. Most of
* the code is from the KMLRoot class, but modified to pass in the parameters
* required to instanciate {@link RelativeKMLDoc} objects.
*
* @author Michael de Hoog (michael.dehoog@ga.gov.au)
*/
public class RelativeKMLDocFactory
{
/**
* Create a RelativeKMLDoc from a docSource.
*
* @param docSource
* either a {@link File}, a {@link URL}, or an
* {@link InputStream}, or a {@link String} identifying a file
* path or URL.
* @param contentType
* the content type of the data. Specify
* {@link KMLConstants#KML_MIME_TYPE} for plain KML and
* {@link KMLConstants#KMZ_MIME_TYPE} for KMZ. The content is
* treated as KML for any other value or a value of null.
* @param href
* the original address of the document if the file is a
* retrieved and cached file.
* @param parent
* the {@link KMLDoc} from which this new {@link KMLDoc} was
* referenced (null if this is root)
* @return A new {@link RelativeKMLDoc}.
*/
public static RelativeKMLDoc createKMLDoc(Object docSource, String contentType, String href, KMLDoc parent)
throws IOException
{
if (docSource == null)
{
String message = Logging.getMessage("nullValue.DocumentSourceIsNull");
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
if (docSource instanceof File)
return createDocSource((File) docSource, href, parent);
else if (docSource instanceof URL)
return createDocSource((URL) docSource, contentType, href, parent);
else if (docSource instanceof InputStream)
return createDocSource((InputStream) docSource, contentType, href, parent);
else if (docSource instanceof String)
{
File file = new File((String) docSource);
if (file.exists())
return createKMLDoc(file, contentType, href, parent);
URL url = WWIO.makeURL(docSource);
if (url != null)
return createKMLDoc(url, contentType, href, parent);
}
return null;
}
protected static RelativeKMLDoc createDocSource(File docSource, String href, KMLDoc parent) throws IOException
{
if (WWIO.isContentType(docSource, KMLConstants.KML_MIME_TYPE))
return new RelativeKMLFile(docSource, href, parent);
else if (WWIO.isContentType(docSource, KMLConstants.KMZ_MIME_TYPE))
{
try
{
return new RelativeKMZFile(docSource, href, parent);
}
catch (ZipException e)
{
// We've encountered some zip files that will not open with ZipFile, but will open
// with ZipInputStream. Try again, this time opening treating the file as a stream.
// See WWJINT-282.
return new RelativeKMZInputStream(new FileInputStream(docSource), WWIO.makeURI(docSource), href, parent);
}
}
else
throw new WWUnrecognizedException(Logging.getMessage("KML.UnrecognizedKMLFileType"));
}
protected static RelativeKMLDoc createDocSource(InputStream docSource, String contentType, String href,
KMLDoc parent) throws IOException
{
if (contentType != null && contentType.equals(KMLConstants.KMZ_MIME_TYPE))
return new RelativeKMZInputStream(docSource, null, href, parent);
else if (contentType == null && docSource instanceof ZipInputStream)
return new RelativeKMZInputStream(docSource, null, href, parent);
else
return new RelativeKMLInputStream(docSource, null, href, parent);
}
protected static RelativeKMLDoc createDocSource(URL docSource, String contentType, String href, KMLDoc parent)
throws IOException
{
URLConnection conn = docSource.openConnection();
if (contentType == null)
contentType = conn.getContentType();
if (!(KMLConstants.KMZ_MIME_TYPE.equals(contentType) || KMLConstants.KML_MIME_TYPE.equals(contentType)))
contentType = WWIO.makeMimeTypeForSuffix(WWIO.getSuffix(docSource.getPath()));
if (KMLConstants.KMZ_MIME_TYPE.equals(contentType))
return new RelativeKMZInputStream(conn.getInputStream(), WWIO.makeURI(docSource), href, parent);
else
return new RelativeKMLInputStream(conn.getInputStream(), WWIO.makeURI(docSource), href, parent);
}
}