/*
 * Copyright 2000, University Corporation for Atmospheric Research
 * All Rights Reserved.
 * See file LICENSE for copying and redistribution conditions.
 *
 * $Id: Merger.java,v 1.3 2001-11-27 22:29:35 dglo Exp $
 */

package visad.data.netcdf.in;

import visad.*;


/**
 * Provides support for merging of virtual data objects.  This class merges
 * virtual data objects to the maximum extent possible.
 *
 * @author Steven R. Emmerson
 */
public class
Merger
{
    /**
     * The singleton instance.
     */
    private static Merger	instance;


    /**
     * Constructs from nothing.
     */
    protected Merger()
    {}


    /**
     * Returns an instance of this class.
     *
     * @return			An instance of this class.
     */
    public static Merger instance()
    {
	if (instance == null)
	{
	    synchronized(Merger.class)
	    {
		if (instance == null)
		    instance = new Merger();
	    }
	}

	return instance;
    }


    /**
     * Merges two virtual data objects.  The order of the objects sub-components
     * is preserved.
     *
     * @param data1		The first virtual data object.
     * @param data2		The second virtual data object.
     * @return			A virtual data object comprising the ordered
     *				merger of the two virtual data objects if 
     *				possible; otherwise null.  May be
     *				one of the input objects.
     * throws VisADException	VisAD failure.
     */
    public VirtualData merge(VirtualData data1, VirtualData data2)
	throws VisADException
    {
	return
	    data1 instanceof VirtualTuple
		? (VirtualData)merge((VirtualTuple)data1, data2)
		: data1 instanceof VirtualField
		    ? (VirtualData)merge((VirtualField)data1, data2)
		    : (VirtualData)null;
    }


    /**
     * Merges a virtual tuple with another virtual data object.  Order is
     * preserved.
     *
     * @param tuple		The virtual tuple.
     * @param data		The other virtual data object.
     * @return			tuple.
     * throws VisADException	VisAD failure.
     */
    protected VirtualTuple merge(VirtualTuple tuple, VirtualData data)
	throws VisADException
    {
	if (data instanceof VirtualTuple)
	{
	    merge(tuple, (VirtualTuple)data);
	}
	else
	{
	    int		n = tuple.size();
	    boolean	merged = false;

	    for (int i = 0; i < n; ++i)
	    {
		VirtualData     element = tuple.get(i);
		VirtualData     mergedElement = merge(element, data);

		if (mergedElement != null)
		{
		    tuple.replace(i, mergedElement);
		    merged = true;
		    break;
		}
	    }

	    if (!merged)
		tuple.add(data);
	}

	return tuple;
    }


    /**
     * Merges two virtual tuples.
     *
     * @param tuple1		The first virtual tuple.
     * @param tuple2		The second virtual tuple.
     * @return			tuple1.
     * throws VisADException	VisAD failure.
     */
    protected VirtualTuple merge(VirtualTuple tuple1, VirtualTuple tuple2)
	throws VisADException
    {
	int	n = tuple2.size();

	for (int i = 0; i < n; ++i)
	{
	    VirtualData	element = tuple2.get(i);

	    merge(tuple1, element);
	}

	return tuple1;		// always successful
    }


    /**
     * Merges a virtual field with another virtual data object.  Order is
     * preserved.
     *
     * @param field		The virtual field.
     * @param data		The other virtual data object.
     * @return			A virtual field comprising the merger of the
     *				input objects if possible; otherwise 
     *				null.  May be field.
     * throws VisADException	VisAD failure.
     */
    protected VirtualField merge(VirtualField field, VirtualData data)
	throws VisADException
    {
	return
	    field instanceof VirtualFlatField
		? (VirtualField)merge((VirtualFlatField)field, data)
		: data instanceof VirtualField
		    ? merge(field, (VirtualField)data)
		    : (VirtualField)null;
    }


    /**
     * Merges a virtual field with another virtual field.  Order is
     * preserved.
     *
     * @param field1		The first virtual field.
     * @param field2		The second virtual field.
     * @return			A virtual field comprising the merger of the
     *				input fields if possible; otherwise 
     *				null.  May be field1.
     * throws VisADException	VisAD failure.
     */
    protected VirtualField merge(VirtualField field1, VirtualField field2)
	throws VisADException
    {
	SampledSet	domain1 = field1.getDomainSet();

	return
	    (field1.getFunctionType().getDomain().equals(
		field2.getFunctionType().getDomain()) &&
	    domain1.equals(field2.getDomainSet()))
		? VirtualField.newVirtualField(
		    domain1, 
		    merge(field1.getRangeTuple(), field2.getRangeTuple()))
		: (VirtualField)null;
    }


    /**
     * Merges a virtual flat-field with another virtual data object.  Order is
     * preserved.
     *
     * @param field		The virtual flat-field.
     * @param data		The other virtual data object.
     * @return			A virtual field comprising the merger of the
     *				input objects if possible; otherwise 
     *				null.  May be field.
     * throws VisADException	VisAD failure.
     */
    protected VirtualField merge(VirtualFlatField field, VirtualData data)
	throws VisADException
    {
	return
	    data instanceof VirtualFlatField
		? (VirtualField)merge(field, (VirtualFlatField)data)
		: data instanceof VirtualField
		    ? (VirtualField)merge(field, (VirtualField)data)
		    : (VirtualField)null;
    }


    /**
     * Merges a virtual flat-field with a virtual field.  Simply uses
     * merge(VirtualField, VirtualField).  This method may
     * be overridden by subclasses.
     *
     * @param field1		The virtual flat-field.
     * @param field2		The virtual field.
     * @return			A virtual field comprising the merger of
     *				the input objects if possible; otherwise 
     *				null.
     * throws VisADException	VisAD failure.
     * @see #merge(VirtualField, VirtualField)
     */
    protected VirtualField merge(VirtualFlatField field1, VirtualField field2)
	throws VisADException
    {
	return 
	    merge((VirtualField)field1, (VirtualField)field2);
    }


    /**
     * Merges a virtual flat-field with another virtual flat-field.  Simply uses
     * merge(VirtualFlatField, VirtualFlatField).  This method may
     * be overridden by subclasses.
     *
     * @param field1		The virtual flat-field.
     * @param field2		The other virtual flat-field.
     * @return			A virtual flat-field comprising the merger of
     *				the input objects if possible; otherwise 
     *				null.  May be field1.
     * throws VisADException	VisAD failure.
     * @see #merge(VirtualFlatField, VirtualFlatField)
     */
    protected VirtualFlatField merge(
	    VirtualFlatField field1, VirtualFlatField field2)
	throws VisADException
    {
	return (VirtualFlatField)
	    merge((VirtualField)field1, (VirtualField)field2);
    }
}

 

Ads help maintain this website.