/* * 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 <code>null</code>. 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 <code>tuple</code>. * 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 <code>tuple1</code>. * 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 * <code>null</code>. May be <code>field</code>. * 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 * <code>null</code>. May be <code>field1</code>. * 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 * <code>null</code>. May be <code>field</code>. * 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 * <code>merge(VirtualField, VirtualField)</code>. 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 * <code>null</code>. * 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 * <code>merge(VirtualFlatField, VirtualFlatField)</code>. 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 * <code>null</code>. May be <code>field1</code>. * throws VisADException VisAD failure. * @see #merge(VirtualFlatField, VirtualFlatField) */ protected VirtualFlatField merge( VirtualFlatField field1, VirtualFlatField field2) throws VisADException { return (VirtualFlatField) merge((VirtualField)field1, (VirtualField)field2); } }