
thredds.cataloggen.config.LocalDatasetSource Maven / Gradle / Ivy
/*
* Copyright 1998-2009 University Corporation for Atmospheric Research/Unidata
*
* Portions of this software were developed by the Unidata Program at the
* University Corporation for Atmospheric Research.
*
* Access and use of this software shall impose the following obligations
* and understandings on the user. The user is granted the right, without
* any fee or cost, to use, copy, modify, alter, enhance and distribute
* this software, and any derivative works thereof, and its supporting
* documentation for any purpose whatsoever, provided that this entire
* notice appears in all copies of the software, derivative works and
* supporting documentation. Further, UCAR requests that the user credit
* UCAR/Unidata in any publications that result from the use of this
* software or in any product that includes this software. The names UCAR
* and/or Unidata, however, may not be used in any advertising or publicity
* to endorse or promote any products or commercial entity unless specific
* written permission is obtained from UCAR/Unidata. The user also
* understands that UCAR/Unidata is not obligated to provide the user with
* any support, consulting, training or assistance of any kind with regard
* to the use, operation and performance of this software nor to provide
* the user with any updates, revisions, new versions or "bug fixes."
*
* THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL,
* INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
* FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE.
*/
// $Id: LocalDatasetSource.java 63 2006-07-12 21:50:51Z edavis $
package thredds.cataloggen.config;
import thredds.catalog.*;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;
/**
* Concrete implementation of DatasetSource for local disk sources.
*
* @author Ethan Davis
* @version $Id: LocalDatasetSource.java 63 2006-07-12 21:50:51Z edavis $
*/
public class LocalDatasetSource extends DatasetSource
{
static private org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(LocalDatasetSource.class);
// private static Log log = LogFactory.getLog( LocalDatasetSource.class);
private File accessPointHeaderFile = null;
private File accessPointFile = null;
LocalDatasetSource()
{
this.type = DatasetSourceType.getType( "Local");
}
protected InvDataset createDataset( String datasetLocation, String prefixUrlPath )
throws IOException
{
if ( datasetLocation == null) throw new NullPointerException( "Dataset location cannot be null.");
this.checkAccessPoint();
return( new LocalInvDataset( null, new File( datasetLocation), prefixUrlPath));
}
/**
* Build an unnamed InvCatalog for this DatasetSource and return the
* top-level InvDataset. The ResultService for this DatasetSource is
* used to create the InvService for the new InvCatalog. Each InvDataset
* in the catalog is named with the location of the object they represent
* on the dataset source.
*
* @return the top-level dataset of the newly constructed InvCatalog.
*
* @throws IOException if top-level dataset does not exist or is not a collection dataset.
*/
protected InvCatalog createSkeletonCatalog( String prefixUrlPath ) throws IOException
{
this.checkAccessPoint();
// Create catalog.
InvCatalogImpl catalog = new InvCatalogImpl( null, null, null );
//this.getName(), null, null);
// Create service.
InvService service = new InvService( this.getResultService().getName(),
this.getResultService().getServiceType().toString(),
this.getResultService().getBase(),
this.getResultService().getSuffix(),
this.getResultService().getDescription());
for ( Iterator it = this.getResultService().getProperties().iterator(); it.hasNext(); )
{
service.addProperty( (InvProperty) it.next() );
}
for ( Iterator it = this.getResultService().getServices().iterator(); it.hasNext(); )
{
service.addService( (InvService) it.next() );
}
// Add service to catalog.
catalog.addService( service);
// Create top-level dataset.
File apFile = new File( this.getAccessPoint() );
InvDatasetImpl topDs = new LocalInvDataset( null, apFile, prefixUrlPath);
// Set the serviceName (inherited by all datasets) in top-level dataset.
ThreddsMetadata tm = new ThreddsMetadata( false);
tm.setServiceName( service.getName());
InvMetadata md = new InvMetadata( topDs, null, XMLEntityResolver.CATALOG_NAMESPACE_10, "", true, true, null, tm);
ThreddsMetadata tm2 = new ThreddsMetadata( false);
tm2.addMetadata( md);
topDs.setLocalMetadata(tm2);
// Add top-level dataset to catalog.
catalog.addDataset( topDs);
// Tie up any loose ends in catalog with finish().
((InvCatalogImpl) catalog).finish();
return( catalog);
}
private void checkAccessPoint()
throws IOException
{
if ( accessPointHeaderFile == null )
{
// Check that the accessPointHeader local file exists.
File aphFile = new File( this.getResultService().getAccessPointHeader() );
if ( !aphFile.exists() ) throw new IOException( "The accessPointHeader local file does not exist <" + aphFile.getPath() + ">." );
// Check that the accessPoint local file exists.
File apFile = new File( this.getAccessPoint() );
if ( !apFile.exists() ) throw new IOException( "The accessPoint local file does not exist <" + apFile.getPath() + ">." );
if ( !apFile.isDirectory() ) throw new IOException( "The accessPoint local file is not a directory <" + apFile.getPath() + ">." );
// Check that accessPoint file starts with accessPointHeader.
if ( ! apFile.getPath().startsWith( aphFile.getPath() )
&& ! apFile.getCanonicalPath().startsWith( aphFile.getCanonicalPath() ) )
{
String tmpMsg = "The accessPoint <" + apFile.getPath() + " or " + apFile.getCanonicalPath() + "> must start with the accessPointHeader <" + aphFile.getPath() + " or " + aphFile.getCanonicalPath() + ">.";
logger.debug( "checkAccessPoint(): {}", tmpMsg );
throw new IOException( tmpMsg );
}
// Save the accessPointHeader as a URI so encodings and "/" vs "\" issues are handled.
accessPointHeaderFile = aphFile;
accessPointFile = apFile;
}
}
/**
* Return true if the given dataset is a collection dataset, false otherwise.
*
* @param dataset - the InvDataset to test for being a collection dataset.
* @return true if the given dataset is a collection dataset, false otherwise.
* @throws NullPointerException if the given InvDataset is null.
* @throws ClassCastException if the given InvDataset is not a LocalInvDataset.
*/
protected boolean isCollection( InvDataset dataset)
{
return( ((LocalInvDataset) dataset).isDirectory());
}
/**
* Return a list of the InvDatasets contained in the given collection dataset
* on this DatasetSource.
*
* @param dataset - the collection dataset to be expanded.
* @return A list of the InvDatasets contained in the given collection dataset.
* @throws IllegalArgumentException when given dataset is not a collection dataset.
* @throws NullPointerException if given dataset is null.
* @throws ClassCastException if the given InvDataset is not a LocalInvDataset.
*/
protected List expandThisLevel( InvDataset dataset, String prefixUrlPath )
{
if ( dataset == null) throw new NullPointerException( "Given dataset cannot be null.");
if ( ! isCollection( dataset)) throw new IllegalArgumentException( "Dataset \"" + dataset.getName() + "\" is not a collection dataset.");
// Deal with all files in this directory.
File theDir = new File( ((LocalInvDataset) dataset).getLocalPath() );
File[] allFiles = theDir.listFiles();
InvDataset curDs = null;
ArrayList list = new ArrayList();
for ( int i = 0; i < allFiles.length; i++)
{
try
{
curDs = new LocalInvDataset( dataset, allFiles[ i], prefixUrlPath );
}
catch ( IOException e )
{
// Given file doesn't exist or is not under the accessPointHeader directory, skip.
continue;
}
list.add( curDs);
}
return( list);
}
/**
* An InvDatasetImpl subclass to deal with datasets on local disk.
*/
private class LocalInvDataset extends InvDatasetImpl
{
private String relativePath;
private String catRelativePath;
private String localPath;
private boolean directory;
LocalInvDataset( InvDataset parent, File file, String prefixUrlPath) throws IOException
{
super( (InvDatasetImpl) parent, null, null, null, null );
if (logger.isDebugEnabled())
logger.debug( "LocalInvDataset(): parent=" + ( parent == null ? "" : parent.getName() ) + "; file=" + file.getPath());
if ( ! file.exists()) throw new IOException( "File <" + file.getPath() + "> does not exist.");
this.directory = file.isDirectory();
// Determine the datasets urlPath by removing accessPointHeader from localPath.
// (Use URIs to handle encoding and slash vs backslash issues.)
String uriStringFromFile = file.toURI().toString();
String uriStringFromCanonicalFile = file.getCanonicalFile().toURI().toString();
String aphUriStringFromFile = accessPointHeaderFile.toURI().toString();
String aphUriStringFromCanonicalFile = accessPointHeaderFile.getCanonicalFile().toURI().toString();
String apUriStringFromFile = accessPointFile.toURI().toString();
String apUriStringFromCanonicalFile = accessPointFile.getCanonicalFile().toURI().toString();
relativePath = null;
if (logger.isDebugEnabled()) {
logger.debug( "LocalInvDataset(): file URI=" + uriStringFromFile );
logger.debug( "LocalInvDataset(): canonical file URI=" + uriStringFromCanonicalFile );
logger.debug( "LocalInvDataset(): aph file URI=" + aphUriStringFromFile );
logger.debug( "LocalInvDataset(): aph canonical file URI=" + aphUriStringFromCanonicalFile );
}
// NOTE: Started using File.getCanonicalFile() to deal with comparisons containing this (".") or parent ("..") directories.
// But that caused caused comparison problems for symbolic links (e.g., on motherlode "/usr/local/apache/htdocs/motherlode/dods/model"
// does not start with "/usr/local/apache/htdocs/motherlode" because "model" is a link to "/data/ldm/pub/decoded/netcdf/GRIB").
if ( ! uriStringFromFile.startsWith( aphUriStringFromFile ) )
{
if ( ! uriStringFromCanonicalFile.startsWith( aphUriStringFromCanonicalFile ) )
{
String tmpMsg = "File <" + uriStringFromFile + " or " + uriStringFromCanonicalFile + "> must start with accessPointHeader <" + aphUriStringFromFile + " or " + aphUriStringFromCanonicalFile + ">.";
throw new IOException( tmpMsg );
}
else
{
relativePath = uriStringFromCanonicalFile.substring( aphUriStringFromCanonicalFile.length() );
catRelativePath = uriStringFromCanonicalFile.substring( apUriStringFromCanonicalFile.length());
localPath = file.getCanonicalPath();
}
}
else
{
relativePath = uriStringFromFile.substring( aphUriStringFromFile.length() );
catRelativePath = uriStringFromFile.substring( apUriStringFromFile.length() );
localPath = file.getAbsolutePath();
}
if (logger.isDebugEnabled()) {
logger.debug( "LocalInvDataset(): relativePath=" + relativePath );
logger.debug( "LocalInvDataset(): localPath=" + localPath );
}
if ( ! this.directory )
{
// Check if service base is relative to the catalog URL the accessPointHeader.
if ( LocalDatasetSource.this.getResultService().getBase().equals( "" )
&& ! LocalDatasetSource.this.getResultService().getServiceType().equals( ServiceType.COMPOUND) )
{
// String tmpUrlPath = prefixUrlPath == null || prefixUrlPath.equals( "")
// ? catRelativePath
// : prefixUrlPath + "/" + catRelativePath;
this.setUrlPath( catRelativePath );
}
else
{
String tmpUrlPath = prefixUrlPath == null || prefixUrlPath.equals( "" )
? relativePath
: prefixUrlPath + "/" + relativePath;
this.setUrlPath( tmpUrlPath );
}
// @todo Should make this optional, maybe with DatasetEnhancer1 (but by then only have dataset, not file).
if ( LocalDatasetSource.this.isAddDatasetSize() )
{
this.setDataSize( file.length());
}
}
String dsName = relativePath.endsWith( "/")
? relativePath.substring( 0, relativePath.length() - 1)
: relativePath;
int index = dsName.lastIndexOf('/');
if ( index != -1 ) dsName = dsName.substring( index + 1);
this.setName( dsName);
}
String getLocalPath() { return( this.localPath); }
void setLocalPath( String localPath ) { this.localPath = localPath; }
public boolean isDirectory() { return( this.directory); }
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy