Package thredds.cataloggen.config

Source Code of thredds.cataloggen.config.DatasetSource

/*
* 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: DatasetSource.java 63 2006-07-12 21:50:51Z edavis $

package thredds.cataloggen.config;

import thredds.catalog.*;
import thredds.cataloggen.config.CatalogRefInfo;
import thredds.cataloggen.DatasetEnhancer1;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

// @todo Add state machine to control what can happen when.
// State machine: 1) constructed and modified, 2) expanded, 3) named,
// 4) metadata-ified, and 5) sorted.

// @todo Implement DatasetSource type using Strategy pattern rather than subclassing.
// I.e., extract abstract methods into interface, config (type given to
// DatasetSource.factory()) determines the implementation used.
// Current subclassing is cumbersome and not so flexible as the factory must be
// modified when new implementation is added.

/**
* Represents a source from which a collection of datasets can be found and
* expanded into an InvCatalog. Besides expanding the DatasetSource, the datasets
* in the resulting catalog can be named, sorted, and have metadata added to them.
*
* <p>
* Currently an abstract class, three abstract methods must be implemented to
* make a concrete subclass. These methods are getTopLevelDataset():InvDataset,
* isCollection():boolean, and expandThisLevel(InvDataset):List. (In previous
* versions, expandThisType():void was the only abstract method.)
* </p>
*
* @author Ethan Davis
* @version $Id: DatasetSource.java 63 2006-07-12 21:50:51Z edavis $
*/
abstract public class DatasetSource
{
  static private org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(DatasetSource.class);

  /** The catalog that results from expanding this DatasetSource.  */
  protected InvCatalog resultingCatalog;

  /** Top-level dataset of the catalog generated by this DatasetSource. */
  protected InvDataset accessPointDataset;

  /** Information on the catalogRefs in the resulting catalog. */
  protected List catalogRefInfoList = new ArrayList();

  // attributes of the datasetSource element
  private String name;
  protected DatasetSourceType type;
  private DatasetSourceStructure structure;
  private boolean flatten = false;
  private String accessPoint;

  private String prefixUrlPath;

  // If true, create CatalogRefs for all collection datasets, otherwise
  // recurse into all collection datasets (default false).
  protected boolean createCatalogRefs = false;
//  protected boolean expandCatalogRef = false;
// @todo Decide if expandCatalogRef is done here in DatasetSource or by CatalogGen (or other DatasetSource caller).


  // Required child ResultService
  private ResultService resultService;

  // list of optional children of the datasetNamer element
  protected List datasetNamerList = new ArrayList();
  protected List datasetFilterList = new ArrayList();
  protected DatasetSorter datasetSorter = null;

  protected List datasetEnhancerList = new ArrayList();
  protected boolean addDatasetSize;

  // for validation
  protected boolean isValid = true;
  protected StringBuffer msgLog = new StringBuffer();

  /** Default Constructor */
  protected DatasetSource(){}

  /**
   * Factory method for this abstract class.
   * @param name
   * @param type
   * @param structure
   * @param accessPoint
   *
   * @throws IllegalArgumentException if DatasetSource type is null or unsupported.
   */
  public static final DatasetSource newDatasetSource( String name, DatasetSourceType type,
                                             DatasetSourceStructure structure,
                                             String accessPoint,
                                             ResultService resultService )
  {
    if ( type == null)
    {
      String tmpMsg = "DatasetSource type cannot be null";
      logger.error( "newDatasetSource(): " + tmpMsg);
      throw new IllegalArgumentException( tmpMsg);
    }

    DatasetSource tmpDsSource = null;

    if ( type == DatasetSourceType.getType( "Local"))
    {
      tmpDsSource = new LocalDatasetSource();
    }
    else if ( type == DatasetSourceType.getType( "DodsDir"))
    {
      tmpDsSource = new DodsDirDatasetSource();
    }
    else if ( type == DatasetSourceType.getType( "DodsFileServer"))
    {
      tmpDsSource = new DodsFileServerDatasetSource();
    }
    else if ( type == DatasetSourceType.getType( "GrADSDataServer"))
    {
      tmpDsSource = new GrADSDataServerDatasetSource();
    }
    else
    {
      String tmpMsg = "Unsupported DatasetSource type <" + type.toString() + ">.";
      logger.error( "newDatasetSource(): " + tmpMsg);
      throw new IllegalArgumentException( tmpMsg);
    }

    tmpDsSource.setName( name);
    tmpDsSource.setStructure( structure);
    tmpDsSource.setAccessPoint( accessPoint);
    tmpDsSource.setResultService( resultService);
    // Test validity and append messages to log.

    logger.debug( "DatasetSource(): constructor done.");
    StringBuilder log = new StringBuilder();
    if ( tmpDsSource.validate( log))
    {
      logger.debug( "DatasetSource(): new DatasetSource is valid: {}", log.toString());
    }
    else
    {
      logger.debug( "DatasetSource(): new DatasetSource is invalid: {}", log.toString());
    }

    return( tmpDsSource);
  }

  public InvCatalog getResultingCatalog() { return( this.resultingCatalog); }

  public List getCatalogRefInfoList()
  {
    return catalogRefInfoList;
  }


  public String getName() { return( this.name); }
  public void setName( String name) { this.name = name; }

  public DatasetSourceType getType() { return( this.type); }

  public DatasetSourceStructure getStructure() { return( this.structure); }
  public void setStructure( DatasetSourceStructure structure)
  {
    this.structure = structure;
    if ( this.structure == DatasetSourceStructure.FLAT)
      flatten = true;
    else
      flatten = false;
  }

  public boolean isFlatten() { return( this.flatten); }

  public String getAccessPoint() { return( this.accessPoint); }
  public void setAccessPoint( String accessPoint)
  { this.accessPoint = accessPoint; }

  public String getPrefixUrlPath() { return( this.prefixUrlPath); }
  public void setPrefixUrlPath( String prefixUrlPath )
  { this.prefixUrlPath = prefixUrlPath; }

  public ResultService getResultService() { return( this.resultService); }
  public void setResultService( ResultService resultService)
  { this.resultService = resultService; }

  public boolean isCreateCatalogRefs()
  { return( this.createCatalogRefs); }
  public void setCreateCatalogRefs( boolean createCatalogRefs)
  { this.createCatalogRefs = createCatalogRefs; }

//  public boolean isExpandCatalogRef()
//  {
//    return expandCatalogRef;
//  }
//
//  public void setExpandCatalogRef( boolean expandCatalogRef )
//  {
//    this.expandCatalogRef = expandCatalogRef;
//  }

  public java.util.List getDatasetNamerList() { return( this.datasetNamerList); }
  public void addDatasetNamer( DatasetNamer datasetNamer)
  { this.datasetNamerList.add( datasetNamer); }

  public java.util.List getDatasetFilterList() { return( this.datasetFilterList); }
  public void addDatasetFilter( DatasetFilter datasetFilter)
  { this.datasetFilterList.add( datasetFilter); }

  public DatasetSorter getDatasetSorter() { return ( this.datasetSorter ); }
  public void setDatasetSorter( DatasetSorter datasetSorter )
  { this.datasetSorter = datasetSorter; }

  public java.util.List getDatasetEnhancerList() { return( this.datasetEnhancerList ); }
  public void addDatasetEnhancer( DatasetEnhancer1 dsEnhancer)
  {
    if ( this.datasetEnhancerList == null) this.datasetEnhancerList = new ArrayList();
    this.datasetEnhancerList.add( dsEnhancer);
  }

  public boolean isAddDatasetSize() { return( this.addDatasetSize); }
  public void setAddDatasetSize( boolean addDatasetSize )
  { this.addDatasetSize = addDatasetSize; }

  public boolean validate( StringBuilder out)
  {
    this.isValid = true;

    // If log from construction has content, append to validation output msg.
    if (this.msgLog.length() > 0)
    {
      out.append( this.msgLog);
    }

    // Check that name is not null (it can be an empty string).
    if ( this.getName() == null)
    {
      this.isValid = false;
      out.append(" ** DatasetSource (5): null value for name is not valid.");
    }
    // Check that type is not null.
    if ( this.getType() == null)
    {
      this.isValid = false;
      out.append(" ** DatasetSource (6): null value for type is not valid (set with bad string?).");
    }
    // Check that structure is not null.
    if ( this.getStructure() == null)
    {
      this.isValid = false;
      out.append(" ** DatasetSource (7): null value for structure is not valid (set with bad string?).");
    }

    // Validate ResultService child element.
    if ( this.getResultService() != null )
    {
      this.isValid &= this.getResultService().validate( out);
    }

    // Validate DatasetNamer child elements.
    java.util.Iterator dsnIter = this.getDatasetNamerList().iterator();
    while (dsnIter.hasNext())
    {
      this.isValid &= ((DatasetNamer) dsnIter.next()).validate( out);
    }

    // Validate DatasetFilters child elements.
    java.util.Iterator dsfIter = this.getDatasetFilterList().iterator();
    while (dsfIter.hasNext())
    {
      this.isValid &= ((DatasetFilter) dsfIter.next()).validate( out);
    }

    return( this.isValid);
  }

  /** string representation */
  public String toString()
  {
    StringBuffer tmp = new StringBuffer();
    tmp.append( "DatasetSource[name:<" + this.getName() +
                "> type:<" + this.getType() +
                "> structure:<" + this.getStructure() +
                "> accessPoint:<" + this.getAccessPoint() +
                "> and children - " +
                "ResultService(" + this.getResultService().getName() + ") - " +
                "DatasetNamer(" + this.getDatasetNamerList().size() + ") - " +
                "DatasetFilter(" + this.getDatasetFilterList().size() + ")]");
    return( tmp.toString());
  }

  /**
   * Crawl this DatasetSource and generate a new InvCatalog, return the
   * top-level InvDataset.
   *
   * Each object found on the DatasetSource becomes an InvDataset if it is
   * accepted by at least one DatasetFilter. The catalog reflects the
   * heirarchical structure of the DatasetSource. All datasets are named
   * with the location of the object they represent on the dataset source.
   *
   * @return the top-level InvDataset in the generated InvCatalog.
   *
   * @throws IOException if the accessPoint for this DatasetSource is not a container dataset.
   */
  public InvDataset expand() throws IOException
  {
    // Get the new catalog being generated and its top-level dataset.
    this.resultingCatalog = this.createSkeletonCatalog( prefixUrlPath );
    this.accessPointDataset = (InvDataset) this.resultingCatalog.getDatasets().get( 0);

    // IOException thrown by createSkeletonCatalog() so this check should not be necessary.
    if ( ! this.isCollection( this.accessPointDataset) )
    {
      String tmpMsg = "The access point dataset <" + this.accessPointDataset.getName() + "> must be a collection dataset.";
      logger.warn( "expand(): {}", tmpMsg);
      throw new IOException( tmpMsg);
    }

    // Recurse into directory structure and expand.
    expandRecursive( this.accessPointDataset);

    // Finish the catalog.
    ((InvCatalogImpl) this.resultingCatalog).finish();

    // Remove empty collection datasets. @todo HACK - should use filters instead.
    this.recursivelyRemoveEmptyCollectionDatasets( this.accessPointDataset);

    // Return the top-level dataset.
    return( this.accessPointDataset);
  }

  /**
   *
   * @param accessPoints
   * @return the top-level dataset
   * @throws IOException if the main access point for this DatasetSource is not a container dataset or any of the given access points do not exist or are not under the main access point.
   */
  public InvDataset expand( List accessPoints) throws IOException
  {
    // Get the new catalog being generated and its top-level dataset.
    this.resultingCatalog = this.createSkeletonCatalog( prefixUrlPath );
    this.accessPointDataset = (InvDataset) this.resultingCatalog.getDatasets().get( 0);

    for ( Iterator it = accessPoints.iterator(); it.hasNext(); )
    {
      InvDataset curDs = this.createDataset( (String) it.next(), this.prefixUrlPath );
      // Recurse into directory structure and expand.
      expandRecursiveCollection( this.accessPointDataset, curDs);
    }

    // Finish the catalog.
    ((InvCatalogImpl) this.resultingCatalog).finish();

    // Remove empty collection datasets. @todo HACK - should use filters instead.
    this.recursivelyRemoveEmptyCollectionDatasets( this.accessPointDataset);

    // Return the top-level dataset.
    return( this.accessPointDataset);
  }

  private void expandRecursive( InvDataset collectionDataset)
  {
    // Get all datasets at this level.
    List listAllDatasets = this.expandThisLevel( collectionDataset, prefixUrlPath );
    InvDataset curChildDs = null;

    for( Iterator i = listAllDatasets.iterator(); i.hasNext(); )
    {
      curChildDs = (InvDataset) i.next();

      // Filter out unwanted datasets.
      if ( ! DatasetFilter.acceptDatasetByFilterGroup( this.getDatasetFilterList(), curChildDs, this.isCollection( curChildDs)))
        continue;

      // Expand each collection dataset.
      if ( this.isCollection( curChildDs))
      {
        expandRecursiveCollection( collectionDataset, curChildDs );
      }
      // Otherwise, add dataset to collection.
      else
      {
        // If not flattening the directory structure, add current dataset to parent dataset.
        if ( ! this.isFlatten())
        {
          ((InvDatasetImpl) collectionDataset).addDataset( (InvDatasetImpl) curChildDs);
        }
        // Otherwise, add current dataset to top-level dataset.
        else
        {
          ((InvDatasetImpl) this.accessPointDataset).addDataset( (InvDatasetImpl) curChildDs);
        }
      }
    }
  }

  private void expandRecursiveCollection( InvDataset collectionDataset, InvDataset childDs )
  {
    // If not creating a catalogRef, expand the current dataset.
    // @todo Make this determination based on current dataset.
    if ( ! this.createCatalogRefs)
    {
      // If not flattening the directory structure, add current collection dataset to parent dataset.
      if ( ! this.isFlatten())
      {
        ((InvDatasetImpl) collectionDataset).addDataset( (InvDatasetImpl) childDs);
      }
      this.expandRecursive( childDs);
    }
    // Otherwise, add current dataset as a catalogRef.
    else
    {
      // @todo Determine title and docName based on createCatalogRef object
      String title = childDs.getName();
      String docName = (childDs.getName() == null || childDs.getName().equals( ""))
                       ? "catalog.xml"
                       : childDs.getName() + "/catalog.xml";
//      if ( ! this.accessPoint.equals( this.resultService.getAccessPointHeader()))
//      {
//        // @todo HACK, HACK not always Files
//        String ap = new File( this.accessPoint).toURI().toString();
//        String aph = new File( this.resultService.getAccessPointHeader()).toURI().toString();
//        String relPath = ap.substring( aph.length() );
//        docName = relPath + ((relPath.endsWith( "/")) ? "" : "/") + docName;
//      }

      // Add catalogRef to the current dataset.
      InvCatalogRef curCatRef = new InvCatalogRef( (InvDatasetImpl) collectionDataset, title, docName);
      ((InvDatasetImpl) collectionDataset).addDataset( curCatRef);

      // Create a DatasetSource for the catalogRef and add info to the catalogRefInfoList.
      DatasetSource catRefDsSrc = DatasetSource.newDatasetSource( childDs.getName(), this.getType(), this.getStructure(),
                                                                  childDs.getName(), new ResultService( this.getResultService()));
      this.catalogRefInfoList.add( new CatalogRefInfo( title, docName, childDs, catRefDsSrc));
    }
  }

  /**
   * Crawl this DatasetSource and generate a new InvCatalog with all datasets
   * named, sorted, and organized as defined by this DatasetSource, return the
   * newly generated InvCatalog.
   *
   * @return the generated InvCatalog.
   *
   * @throws IOException if DatasetSource does not reference a container dataset.
   */
  public InvCatalog fullExpand() throws IOException
  {
    logger.debug( "fullExpand(): expanding DatasetSource named \"{}\"", this.getName());

    InvDataset topDs = this.expand();
    InvCatalog generatedCat = topDs.getParentCatalog();

    // Add metadata to all datasets.
    for ( Iterator it = this.getDatasetEnhancerList().iterator(); it.hasNext(); )
    {
      DatasetEnhancer1 dsE = (DatasetEnhancer1) it.next();
      dsE.addMetadata( topDs);
    }

    // Name all datasets.
    logger.debug( "fullExpand(): naming the datasets.");
    this.nameDatasets( (InvDatasetImpl) topDs );

    // Sort all datasets
    logger.debug( "fullExpand(): sorting the datasets.");
    this.sortDatasets( topDs);

    // Return the generated catalog
    ((InvCatalogImpl) generatedCat).finish();
    return( generatedCat);

  }

  /**
   * Creates an InvDataset to represent the dataset at the given location
   * on this DatasetSource.
   *
   * @param datasetLocation a String indicating the location of a dataset.
   * @param prefixUrlPath a path name to be prefixed on the urlPath
   * @return an InvDataset for the given dataset location.
   * @throws IOException if the dataset location does not correspond to an actual dataset or is not below the accessPointHeader directory.
   * @throws NullPointerException if the given dataset location is null.
   */
  abstract protected InvDataset createDataset( String datasetLocation, String prefixUrlPath )
          throws IOException;

  /**
   * 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.
   */
  abstract protected boolean isCollection( InvDataset dataset);

  /**
   * Return a skeleton InvCatalog for this DatasetSource. The skeleton catalog
   * is unnamed with a single top-level dataset representing the DatasetSource
   * accessPoint and a service built from the DatasetSource ResultService.
   *
   * @param prefixUrlPath
   * @return a skeleton InvCatalog for this DatasetSource.
   *
   * @throws IOException if top-level dataset does not exist or is not a collection dataset.
   */
  abstract protected InvCatalog createSkeletonCatalog( String prefixUrlPath ) throws IOException;

  /**
   * Return a list of the InvDatasets contained in the given collection dataset
   * on this DatasetSource.
   *
   * @param collectionDataset - the collection dataset to be expanded.
   * @param prefixUrlPath
   * @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.
   */
  abstract protected List expandThisLevel( InvDataset collectionDataset, String prefixUrlPath );

  /**
   * Use the list of dsNamers to name the given list of datasets.
   *
   * @param datasetContainer - a InvDatasetImpl that contains one or
   *  more datasets to be named.
   */
  private void nameDatasets( InvDatasetImpl datasetContainer)
  {
    if ( this.getDatasetNamerList().isEmpty()) return;
    if ( this.isFlatten())
    {
      logger.debug( "nameDatasets(): structure is FLAT calling nameDatasetList()");
      this.nameDatasetList( datasetContainer);
    }
    else
    {
      logger.debug( "nameDatasets(): structure is DIRECTORY_TREE calling" +
              " nameDatasetTree() on each dataset in dataset container");
      InvDatasetImpl curDs = null;
      for ( int j = 0; j < datasetContainer.getDatasets().size(); j++)
      {
        curDs = (InvDatasetImpl) datasetContainer.getDatasets().get( j);
        this.nameDatasetTree( curDs);
      }
    }
    return;
  }

  /** Name the datasets contained in the given dataset.
   *  The given dataset contains a flat list of datasets. */
  private void nameDatasetList( InvDatasetImpl dataset)
  {
    // Create temporary dataset in which to hold named datasets.
    InvDatasetImpl namedDs = new InvDatasetImpl( dataset,
          "nameDatastList() temp dataset", null, null, null);
    // InvDatasetImpl(parentDs, name, dataType, serviceName, urlPath)
    dataset.addDataset( namedDs);

    // Loop through the DatasetNamers
    DatasetNamer curNamer = null;
    for ( int i = 0; i < this.datasetNamerList.size(); i++)
    {
      curNamer = (DatasetNamer) this.datasetNamerList.get( i);
      logger.debug( "nameDatasetList(): trying namer ({})", curNamer.getName());

      // If the current DatasetNamer adds a new level, create a new dataset.
      InvDatasetImpl addLevelDs = null;
      if ( curNamer.getAddLevel())
      {
        addLevelDs = new InvDatasetImpl( null, curNamer.getName(),
                                         null, null, null );
      }

      // Iterate over remaining unnamed datasets.
      InvDatasetImpl curDs = null;
      java.util.Iterator dsIter = dataset.getDatasets().iterator();
      while ( dsIter.hasNext())
      {
        curDs = (InvDatasetImpl) dsIter.next();
        logger.debug( "nameDatasetList(): try namer on this ds ({}-{})", curDs.getName(), curDs.getUrlPath() );

        // Try to name the current dataset.
        if ( curNamer.nameDataset( curDs))
        {
          logger.debug( "nameDatasetList(): ds named ({})", curDs.getName());
          // If adding a level, add named datasets to the added level dataset.
          if ( curNamer.getAddLevel())
          {
            addLevelDs.addDataset( curDs);
          }
          // Otherwise, add the named datasets to namedDs.
          else
          {
            namedDs.addDataset( curDs);
          }

          // Remove the now-named dataset from list of unnamed datasets.
          dsIter.remove();
        }
      } // END - InvDatasetImpl loop

      // If the namer added a level and a dataset was named by this namer, add the
      // new level to the list of named datasets.
      if ( curNamer.getAddLevel())
      {
        if ( addLevelDs.hasNestedDatasets())
        {
          namedDs.addDataset( addLevelDs);
        }
      }

    } // END - DatasetNamer loop
    namedDs.finish();

    // Once all datasets are named (or unnamable with these DatasetNamers),
    // add all the datasets in namedDs back into the given containerDataset.
    if (logger.isDebugEnabled()) {
      logger.debug( "nameDatasetList(): number of unnamed datasets is " + dataset.getDatasets().size() + ".");
      logger.debug( "nameDatasetList(): add named datasets back to container.");
    }
    for ( int i = 0; i < namedDs.getDatasets().size(); i++)
    {
      dataset.addDataset( (InvDatasetImpl) namedDs.getDatasets().get( i));
    }
    dataset.removeDataset( namedDs);

    return;
  }

  /** Name the datasets in the given dataset hierarchy using this
   *  DatasetSource's list of datasetNamers. */
  private void nameDatasetTree( InvDatasetImpl dataset)
  {
    // If dataset does not have a name, try naming it with dsNamers.
    // @todo Rethink naming of directories (look at how DatasetFilter deals with collection vs atomic datasets).
    if ( dataset.getName().equals("") || ! dataset.hasAccess())
    {
      logger.debug( "nameDatasetTree(): naming dataset ({})...", dataset.getUrlPath());
      DatasetNamer dsN = null;
      for ( int i = 0; i < this.datasetNamerList.size(); i++)
      {
        dsN = (DatasetNamer) this.datasetNamerList.get( i);
        if ( dsN.nameDataset( dataset))
        {
          logger.debug( "nameDatasetTree(): ... used namer ({})", dsN.getName());
          break;
        }
      }
    }

    // Try to name any child datasets.
    InvDatasetImpl curDs = null;
    for ( int j = 0; j < dataset.getDatasets().size(); j++)
    {
      curDs = (InvDatasetImpl) dataset.getDatasets().get( j);
      logger.debug( "nameDatasetTree(): recurse to name child dataset ({})", curDs.getUrlPath());
      this.nameDatasetTree( curDs);
    }

    return;
  }

  private void sortDatasets( InvDataset dataset)
  {
    if ( this.getDatasetSorter() == null)
    {
      // Create default dataset Comparator (matches pre-DatasetSorter behaviour).
      DatasetSorter defaultSorter = new DatasetSorter(
              new java.util.Comparator()
              {
                public int compare( Object obj1, Object obj2 )
                {
                  InvDataset ds1 = (InvDataset) obj1;
                  InvDataset ds2 = (InvDataset) obj2;
                  return ( -ds1.getName().compareTo( ds2.getName() ) );
                }
              }
      );
      defaultSorter.sortNestedDatasets( dataset);
    }
    else
    {
      this.getDatasetSorter().sortNestedDatasets( dataset);
    }

    return;
  }

  private void recursivelyRemoveEmptyCollectionDatasets( InvDataset parentDataset)
  {
    InvDataset curDs = null;
    for ( Iterator it = parentDataset.getDatasets().iterator(); it.hasNext(); )
    {
      curDs = (InvDataset) it.next();

      // Do not remove accessible dataset.
      if ( curDs.hasAccess()) continue;

      // Do not remove catalogRef datasets.
      if ( curDs instanceof InvCatalogRef) continue;

      // Recurse into collection datasets children.
      if ( curDs.hasNestedDatasets())
      {
        this.recursivelyRemoveEmptyCollectionDatasets( curDs);
      }
      // Remove any empty collection datasets.
      else
      {
        it.remove();
      }
    }
  }

  public boolean equals( Object o )
  {
    if ( this == o ) return true;
    if ( !( o instanceof DatasetSource ) ) return false;

    final DatasetSource datasetSource = (DatasetSource) o;

    if ( createCatalogRefs != datasetSource.createCatalogRefs ) return false;
//    if ( expandCatalogRef != datasetSource.expandCatalogRef ) return false;
    if ( flatten != datasetSource.flatten ) return false;
    if ( accessPoint != null ? !accessPoint.equals( datasetSource.accessPoint ) : datasetSource.accessPoint != null ) return false;
    if ( datasetFilterList != null ? !datasetFilterList.equals( datasetSource.datasetFilterList ) : datasetSource.datasetFilterList != null ) return false;
    if ( datasetNamerList != null ? !datasetNamerList.equals( datasetSource.datasetNamerList ) : datasetSource.datasetNamerList != null ) return false;
    if ( name != null ? !name.equals( datasetSource.name ) : datasetSource.name != null ) return false;
    if ( resultService != null ? !resultService.equals( datasetSource.resultService ) : datasetSource.resultService != null ) return false;
    if ( type != null ? !type.equals( datasetSource.type ) : datasetSource.type != null ) return false;

    return true;
  }

  public int hashCode()
  {
    if ( hashCode == 0)
    {
      int result = 17;
      result = ( name != null ? name.hashCode() : 0 );
      result = 29 * result + ( type != null ? type.hashCode() : 0 );
      result = 29 * result + ( flatten ? 1 : 0 );
      result = 29 * result + ( accessPoint != null ? accessPoint.hashCode() : 0 );
      result = 29 * result + ( createCatalogRefs ? 1 : 0 );
//      result = 29 * result + ( expandCatalogRef ? 1 : 0 );
      result = 29 * result + ( resultService != null ? resultService.hashCode() : 0 );
      result = 29 * result + ( datasetNamerList != null ? datasetNamerList.hashCode() : 0 );
      result = 29 * result + ( datasetFilterList != null ? datasetFilterList.hashCode() : 0 );
      hashCode = result;
    }
    return hashCode;
  }
  private volatile int hashCode = 0;
}
TOP

Related Classes of thredds.cataloggen.config.DatasetSource

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.