// // DataUtility.java // /* VisAD system for interactive analysis and visualization of numerical data. Copyright (C) 1996 - 2017 Bill Hibbard, Curtis Rueden, Tom Rink, Dave Glowacki, Steve Emmerson, Tom Whittaker, Don Murray, and Tommy Jasmin. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ package visad.util; // General Java import java.awt.Image; import java.awt.Toolkit; import java.awt.image.ColorModel; import java.awt.image.DirectColorModel; import java.awt.image.MemoryImageSource; import java.awt.image.PixelGrabber; import java.io.IOException; import java.util.ArrayList; import java.util.TreeSet; import java.util.Enumeration; import java.util.Iterator; import java.util.Comparator; import java.util.Vector; import java.util.StringTokenizer; // RMI classes import java.rmi.RemoteException; import visad.java2d.DisplayImplJ2D; import visad.java3d.DisplayImplJ3D; import visad.java3d.TwoDDisplayRendererJ3D; // GUI handling import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.*; // VisAD packages import visad.*; /** A general utility class for VisAD Data objects */ public class DataUtility { private static boolean init = false; private static FunctionType simpleImageType; private static RealType radiance; private static RealTupleType imageDomain; private static RealType line; private static RealType element; private int num_lines, num_elements; private static synchronized void makeTypes() throws VisADException { if (!init) { init = true; simpleImageType = (FunctionType) MathType.stringToType("((ImageElement, ImageLine) -> ImageRadiance)"); imageDomain = simpleImageType.getDomain(); line = (RealType) imageDomain.getComponent(1); element = (RealType) imageDomain.getComponent(0); MathType range = simpleImageType.getRange(); if (range instanceof RealType) { radiance = (RealType) range; } else { radiance = (RealType) ((RealTupleType) range).getComponent(0); } } } /** return a FlatField for a simple image from values[nlines][nelements] */ public static FlatField makeImage(float[][] values) throws VisADException, RemoteException { if (values == null) return null; int nlines = values.length; int nelements = 0; for (int l=0; l. * Ifnelements) nelements = values[l].length; } } if (!init) makeTypes(); FlatField image = new FlatField(simpleImageType, new Integer2DSet(imageDomain, nelements, nlines)); setPixels(image, values); return image; } /** set pixel values in a simple image, indexed as values[line][element] */ public static void setPixels(FlatField image, float[][] values) throws VisADException, RemoteException { if (values == null) return; Integer2DSet set = (Integer2DSet) image.getDomainSet(); int num_elements = set.getLength(0); int num_lines = set.getLength(1); float[][] vals = new float[1][num_lines * num_elements]; for (int i=0; i = 0 && height >= 0)) break; try { Thread.sleep(100); } catch (InterruptedException e) { } } while (true); if (ih.badImage) throw new IOException("Not an image"); // extract image pixels int numPixels = width * height; int[] words = new int[numPixels]; PixelGrabber grabber = new PixelGrabber( image.getSource(), 0, 0, width, height, words, 0, width); try { grabber.grabPixels(); } catch (InterruptedException e) { } ColorModel cm = grabber.getColorModel(); boolean doAlpha = cm.hasAlpha() && withAlpha; //System.out.println("do alpha: " + doAlpha); float[] red_pix = new float[numPixels]; float[] green_pix = new float[numPixels]; float[] blue_pix = new float[numPixels]; float[] alpha_pix = null; for (int i=0; i ((x, y) -> (r, g, b)) * to an AWT Image. If reverse flag is set, image will be upside-down. */ public static Image extractImage(FlatField field, boolean reverse) { try { GriddedSet set = (GriddedSet) field.getDomainSet(); int[] wh = set.getLengths(); int w = wh[0]; int h = wh[1]; double[][] samples = field.getValues(); int[] pixels = new int[samples[0].length]; if (samples.length == 3) { int len = samples[0].length; for (int i=0; i type typeis a RealTupleType, then * it is returned; otherwise, iftype* is a RealType, then a RealTupleType * containingtypeas the * only component is returned; otherwise, * iftypeis a SetType, then *((SetType)type).getDomain()is * returned. * @throws TypeExceptiontypeis the wrong type: it can't * be converted into a RealTupleType. * @throws VisADException Couldn't create necessary VisAD object. */ public static RealTupleType ensureRealTupleType(MathType type) throws TypeException, VisADException { RealTupleType result; if (type instanceof RealTupleType) result = (RealTupleType)type; else if (type instanceof RealType) result = new RealTupleType((RealType)type); else if (type instanceof SetType) result = ((SetType)type).getDomain(); else throw new TypeException( DataUtility.class.getName() + ".ensureRealTupleType(MathType): Can't convert MathType \"" + type + "\" into a RealTupleType"); return result; } /** * Ensures that a MathType is a TupleType. Converts if necessary. * @param type The math type to be "converted" to a TupleType. * @return The TupleType version oftype. * Iftypeis a TupleType, * then it is returned; otherwise, if *typeis a SetType, then *((SetType)type).getDomain()is * returned; otherwise, a TupleType containing *typeas the only component is * returned (iftypeis a RealType, * then the returned TupleType is a RealTupleType); * @throws VisADException Couldn't create necessary VisAD object. */ public static TupleType ensureTupleType(MathType type) throws VisADException { return type instanceof TupleType ? (TupleType)type : type instanceof SetType ? ((SetType)type).getDomain() // actually a RealTupleType : type instanceof RealType ? new RealTupleType((RealType)type) : new TupleType(new MathType[] {type}); } /** * Ensures that a Data is a Tuple. Creates a Tuple if necessary. * @param datum The math type to be "converted" to a Tuple. * @return The Tuple version ofdatum. If *datumis a Tuple, then it is * returned; otherwise, ifdatumis * a Real, then a RealTuple containing* datumas the only component is returned; * otherwise, a Tuple containingdatum* as the only component is returned. * @throws VisADException Couldn't create necessary VisAD object. * @throws RemoteException Java RMI failure. */ public static TupleIface ensureTuple(Data datum) throws VisADException, RemoteException { return datum instanceof TupleIface ? (TupleIface)datum : datum instanceof Real ? new RealTuple(new Real[] {(Real)datum}) : new Tuple(new Data[] {datum}); } /** * Gets the MathType of the domain of a Set. * @param set A set. * @return The MathType of the domain of the Set. */ public static RealTupleType getDomainType(Set set) { return ((SetType)set.getType()).getDomain(); } /** * Gets the MathType of the domain of a Function. * @param function A function. * @return The MathType of the domain of the function. * @throws VisADException Couldn't create necessary VisAD object. * @throws RemoteException Java RMI failure. */ public static RealTupleType getDomainType(Function function) throws VisADException, RemoteException { return ((FunctionType)function.getType()).getDomain(); } /** * Gets the MathType of the range of a Function. * @param function A function. * @return The MathType of the range of the function. * @throws VisADException Couldn't create necessary VisAD object. * @throws RemoteException Java RMI failure. */ public static MathType getRangeType(Function function) throws VisADException, RemoteException { return ((FunctionType)function.getType()).getRange(); } /** * Gets the TupleType of the range of a Function. * @param function A function. * @return The TupleType of the range of the function. * @throws VisADException Couldn't create necessary VisAD object. * @throws RemoteException Java RMI failure. */ public static TupleType getRangeTupleType(Function function) throws VisADException, RemoteException { return ensureTupleType(getRangeType(function)); } /** * Gets the MathType of the flat-range of a Function. * @param function A function. * @return The MathType of the flat-range of the function. * @throws VisADException Couldn't create necessary VisAD object. * @throws RemoteException Java RMI failure. */ public static RealTupleType getFlatRangeType(Function function) throws VisADException, RemoteException { return ((FunctionType)function.getType()).getFlatRange(); } /** * Gets the number of components in the range of a Function. NB: This differs * from visad.FlatField.getRangeDimension() in that it returns the number of * components in the actual range rather than the number of components in the * flat range. * @param function A function. * @return The number of components in the range of the * function. * @throws VisADException Couldn't create necessary VisAD object. * @throws RemoteException Java RMI failure. */ public static int getRangeDimension(Function function) throws VisADException, RemoteException { return getRangeTupleType(function).getDimension(); } /** * Gets the index of a component in a TupleType. If the TupleType * contains multiple instances of the component, then it is unspecified * which component index is returned. This method first looks for an * exact match via theequals(Object)method. If none is * found, then this method looks for an approximate match based on the *equalsExceptNameButUnits(MathType)method. * @param tupleType The type of the tuple. * @param componentType The MathType of the component. * @return The index of the component in the tuple * or -1 if the component is not in the tuple. * @throws VisADException Couldn't create necessary VisAD object. * @throws RemoteException Java RMI failure. */ public static int getComponentIndex(TupleType tupleType, MathType componentType) throws VisADException, RemoteException { /* * Return first exact match if found. */ for (int i = tupleType.getDimension(); --i >= 0; ) if (componentType.equals(tupleType.getComponent(i))) return i; /* * Return the first convertible-units match if found. */ for (int i = tupleType.getDimension(); --i >= 0; ) if (componentType.equalsExceptNameButUnits(tupleType.getComponent(i))) return i; return -1; } /** * Gets the index of a component in a Set. If the set contains multiple * instances of the component, then it is unspecified which component index is * returned. * @param set The Set. * @param componentType The MathType of the component. * @return The index of the component in the set or -1 if * the component is not in the set. * @throws VisADException Couldn't create necessary VisAD object. * @throws RemoteException Java RMI failure. */ public static int getComponentIndex(Set set, MathType componentType) throws VisADException, RemoteException { return getComponentIndex(((SetType)set.getType()).getDomain(), componentType); } /** * Gets the index of a component in the range of a Function. If the range * contains multiple instances of the component, then it is unspecified * which component index is returned. * @param function The Function. * @param componentType The MathType of the component. * @return The index of the component in the range of the * field or -1 if the component is not in the range * of the field (NB: this is not the flat-range * index). * @throws VisADException Couldn't create necessary VisAD object. * @throws RemoteException Java RMI failure. */ public static int getComponentIndex(Function function, MathType componentType) throws VisADException, RemoteException { return getComponentIndex(getRangeTupleType(function), componentType); } /** * Ensures that the range of a Field is a given type. Extracts from * the input field only if necessary. * @param field The input field. * @param newRangeType The desired type of range for the resulting * field. * @return A field with the desired range type. The range * data will be missing, however, if all * of it couldn't be extracted from the input * Field (i.e. * RETURN_VALUE.isMissing()will be * true. * @throws UnimplementedException * The desired range type is a TupleType and not * a RealTupleType. * @throws TypeException The new range type cannot be the range of a * field. * @throws VisADException Couldn't create necessary VisAD object. * @throws RemoteException Java RMI failure. */ public static Field ensureRange(Field field, MathType newRangeType) throws UnimplementedException, TypeException, VisADException, RemoteException { Field result; if (newRangeType.equals(getRangeType(field))) { result = field; } else if (newRangeType instanceof RealType) { int componentIndex = getComponentIndex(field, newRangeType); if (componentIndex >= 0) { result = field.extract(componentIndex); } else { result = new FlatField( new FunctionType(getDomainType(field), newRangeType), field.getDomainSet()); } } else if (newRangeType instanceof RealTupleType) { int realTupleIndex = getComponentIndex(field, newRangeType); if (realTupleIndex >= 0) { /* * The desired RealTuple range is a component of the input Field. */ result = (FlatField)field.extract(realTupleIndex); } else { /* * The desired RealTuple range is not a component of the input Field. * Extract each component of the desired RealTuple into a separate * Field and then combine the Field-s. */ RealTupleType newRangeRealTupleType = (RealTupleType)newRangeType; int componentCount = newRangeRealTupleType.getDimension(); ArrayList flatFields = new ArrayList(componentCount); for (int i = 0; i < componentCount; ++i) { int componentIndex = getComponentIndex(field, newRangeRealTupleType.getComponent(i)); if (componentIndex >= 0) flatFields.add(field.extract(componentIndex)); } if (flatFields.size() != componentCount) { /* Not all desired components exist in the range of the input Field */ result = new FlatField( new FunctionType(getDomainType(field), newRangeType), field.getDomainSet()); } else { /* All desired components exist in the range of the input Field */ result = (FlatField)FieldImpl.combine( (FlatField[])flatFields.toArray(new FlatField[componentCount])); } } } else if (newRangeType instanceof TupleType) { throw new UnimplementedException( "Can't yet create Field with range " + newRangeType + " from existing Field"); } else { throw new TypeException("Can't create Field with range " + newRangeType); } return result; } /** * Provides support for comparing RealTuple-s of the same RealTupleType. * * @author Steven R. Emmerson */ public static final class RealTupleComparator implements Comparator { /** * The single instance. */ public static final RealTupleComparator INSTANCE = new RealTupleComparator(); /** * Constructs from nothing. */ private RealTupleComparator() {} /** * Compares two RealTuple-s of the same RealTupleType. * * @param obj1 The first RealTuple. * @param obj2 The second RealTuple. It shall have the same * RealTupleType as the first RealTuple. * @return A negative integer, zero, or a positive integer * as the first RealTuple is less than, equal to, * or greater than the second RealTuple. * @throws ClassCastException * The types of the arguments prevent this * comparator from comparing them. */ public int compare(Object obj1, Object obj2) throws ClassCastException { RealTuple realTuple1 = (RealTuple)obj1; RealTuple realTuple2 = (RealTuple)obj2; try { int rank = realTuple1.getDimension(); int comp = 0; /* * Because Set rasterization has the last component as the outermost * dimension, the last tuple component is treated as the grossest one * for the purpose of comparison. Hence, components are compared in * decreasing order. */ for (int i = rank; --i >= 0 && comp == 0; ) comp = ((Real)realTuple1.getComponent(i)).compareTo( ((Real)realTuple2.getComponent(i))); return comp; } catch (Exception e) { /* * This is the only checked exception a Comparator is allowed to throw. * The original exception could be either a visad.VisADException or a * java.rmi.RemoteException. */ String reason = e.getMessage(); throw new ClassCastException("Can't compare RealTuple-s" + (reason == null ? "" : ": " + reason)); } } } /** * Provides support for comparing domain points that are reference to a * particular Field. */ private static class ReferencedDomainPoint implements Comparable { protected final RealTuple sample; protected final Field field; public ReferencedDomainPoint(RealTuple sample, Field field) { this.sample = sample; this.field = field; } public int compareTo(Object obj) { return RealTupleComparator.INSTANCE.compare( sample, ((ReferencedDomainPoint)obj).sample); } } /** * Consolidates fields. * @param fields The fields to consolidate. Each field shall * have the same FunctionType. * @return The input Fields consolidated into one Field. * The domain shall be a GriddedSet comprising the * union of the sample points of the fields. The * FunctionType shall be the same as that of the * input Field-s. When more than one input Field * has valid range data for the same domain point, * it is unspecified which range datum is used for * the output Field. * @throws FieldException The Field array has zero length. * @throws TypeException Input Field-s not all same type. * @throws VisADException Couldn't create necessary VisAD object. * @throws RemoteException Java RMI failure. */ public static Field consolidate(Field[] fields) throws FieldException, TypeException, VisADException, RemoteException { /* * Identify valid fields. */ ArrayList validFields = new ArrayList(fields.length); for (int i = 0; i < fields.length; ++i) { Field field = fields[i]; if (!field.isMissing()) validFields.add(field); } if (validFields.size() == 0) throw new FieldException( DataUtility.class.getName() + "(Field[]): Zero fields to consolidate"); /* * Determine the consolidated domain. */ FunctionType funcType = (FunctionType)fields[0].getType(); TreeSet consolidatedDomainTuples = new TreeSet(); for (Iterator iter = validFields.iterator(); iter.hasNext(); ) { Field field = (Field)iter.next(); if (!field.getType().equals(funcType)) throw new TypeException("Field type mismatch"); for (Enumeration en = field.domainEnumeration(); en.hasMoreElements(); ) { consolidatedDomainTuples.add( new ReferencedDomainPoint((RealTuple)en.nextElement(), field)); } } /* * Create the consolidated field (with no range data). */ Field field = fields[0]; float[][] domainFloats = new float[field.getDomainDimension()][consolidatedDomainTuples.size()]; Unit[] domainUnits = field.getDomainUnits(); int sampleIndex = 0; for (Iterator iter = consolidatedDomainTuples.iterator(); iter.hasNext(); ++sampleIndex) { RealTuple domainTuple = ((ReferencedDomainPoint)iter.next()).sample; for (int i = domainFloats.length; --i >= 0; ) domainFloats[i][sampleIndex] = (float)((Real)domainTuple.getComponent(i)).getValue(domainUnits[i]); } SampledSet consolidatedDomain = domainFloats.length == 1 ? (SampledSet)new Gridded1DSet( getDomainType(field), domainFloats, domainFloats[0].length, (CoordinateSystem)null, field.getDomainUnits(), (ErrorEstimate[])null) : domainFloats.length == 2 ? (SampledSet)new Irregular2DSet( getDomainType(field), domainFloats, (CoordinateSystem)null, field.getDomainUnits(), (ErrorEstimate[])null, (Delaunay)null) : domainFloats.length == 3 ? (SampledSet)new Irregular3DSet( getDomainType(field), domainFloats, (CoordinateSystem)null, field.getDomainUnits(), (ErrorEstimate[])null, (Delaunay)null) : (SampledSet)new IrregularSet( getDomainType(field), domainFloats, (CoordinateSystem)null, field.getDomainUnits(), (ErrorEstimate[])null); Field consolidatedField = field instanceof FlatField ? new FlatField(funcType, consolidatedDomain) : new FieldImpl(funcType, consolidatedDomain); /* * Set the range of the consolidated field. */ for (Iterator iter = consolidatedDomainTuples.iterator(); iter.hasNext(); ) { ReferencedDomainPoint point = (ReferencedDomainPoint)iter.next(); RealTuple domainTuple = point.sample; consolidatedField.setSample( domainTuple, point.field.evaluate(domainTuple)); } return consolidatedField; } /** * Creates a GriddedSet from a FlatField. The GriddedSet will be created from * the domain and flat-range of the FlatField. The first components in the * tuples of the GriddedSet will come from the domain of the FlatField and the * remaining components will come from the range of the FlatField. Note that, * because a GriddedSet doesn't have the ability to contain values in small * primitives (e.g. byte, short), the returned set may be significantly larger * than the input field. * @param field The FlatField from which to create a GriddedSet. * @param copy Whether or not to copy the range values from * the field (i.e.field.getFloats(copy) *). * @return The GriddedSet corresponding to the input * FlatField. * @throws VisADException Couldn't create necessary VisAD object. * @throws RemoteException Java RMI failure. */ public static GriddedSet createGriddedSet(FlatField field, boolean copy) throws VisADException, RemoteException { int domainRank = field.getDomainDimension(); int flatRangeRank = field.getRangeDimension(); RealType[] realTypes = new RealType[domainRank + flatRangeRank]; RealTupleType tupleType = getDomainType(field); for (int i = 0; i < domainRank; i++) realTypes[i] = (RealType)tupleType.getComponent(i); tupleType = getFlatRangeType(field); for (int i = 0; i < flatRangeRank; i++) realTypes[domainRank+i] = (RealType)tupleType.getComponent(i); float[][] samples = new float[realTypes.length][field.getLength()]; /* * The following gets the domain values in their actual units. */ System.arraycopy( field.getDomainSet().getSamples(), 0, samples, 0, domainRank); /* * The following gets the range values in their default units. */ System.arraycopy( field.getFloats(copy), 0, samples, domainRank, flatRangeRank); int[] lengths = new int[samples.length]; for (int i = samples.length; --i >= 0; ) lengths[i] = samples[i].length; Unit[] units = new Unit[realTypes.length]; System.arraycopy(field.getDomainUnits(), 0, units, 0, domainRank); System.arraycopy( field.getDefaultRangeUnits(), 0, units, domainRank, flatRangeRank); return GriddedSet.create( new RealTupleType(realTypes), samples, lengths, (CoordinateSystem)null, units, (ErrorEstimate[])null); } /** * Simplifies a MathType. Removes all enclosing, single-component TupleType-s * until the "core" is revealed (e.g. ScalarType, multi-component TupleType). * @param type The MathType to be simplified. * @return The simplest form corresponding to *type. * @throws VisADException Couldn't create necessary VisAD object. */ public static MathType simplify(MathType type) throws VisADException { while (type instanceof TupleType && ((TupleType)type).getDimension() == 1) type = ((TupleType)type).getComponent(0); return type; } /** * @deprecated Use getScalarTypes(Data, Vector) instead. */ public static int getRealTypes(Data data, Vector v) throws VisADException, RemoteException { return getRealTypes(new Data[] {data}, v, true, false); } /** * @deprecated Use getScalarTypes(Data[], Vector, boolean, boolean) instead. */ public static int getRealTypes(Data[] data, Vector v, boolean keepDupl, boolean doCoordSys) throws VisADException, RemoteException { int dupl = getScalarTypes(data, v, keepDupl, doCoordSys); int i = 0; while (i < v.size()) { ScalarType st = (ScalarType) v.elementAt(i); if (!(st instanceof RealType)) v.remove(i); else i++; } return dupl; } /** * Obtains a Vector consisting of all ScalarTypes present in a Data object's * MathType. * @param data The Data from which to extract the ScalarTypes. * @param v The Vector in which to store the ScalarTypes. * @throws VisADException Couldn't parse the Data's MathType. * @throws RemoteException Couldn't obtain the remote Data's MathType. * @return The number of duplicate ScalarTypes found. */ public static int getScalarTypes(Data data, Vector v) throws VisADException, RemoteException { return getScalarTypes(new Data[] {data}, v, true, false); } /** * Obtains a Vector consisting of all ScalarTypes present in an array of * Data objects' MathTypes. * @param data The array of Data from which to extract the * ScalarTypes. * @param v The Vector in which to store the ScalarTypes. * @param keepDupl Whether to add a RealType to the Vector when * it is already present there. * @param doCoordSys Whether to include ScalarTypes from * CoordinateSystem references. * @throws VisADException Couldn't parse a Data's MathType. * @throws RemoteException Couldn't obtain a remote Data's MathType. * @return The number of duplicate ScalarTypes found. */ public static int getScalarTypes(Data[] data, Vector v, boolean keepDupl, boolean doCoordSys) throws VisADException, RemoteException { Vector coord = (doCoordSys ? new Vector() : null); int[] dupl = new int[1]; dupl[0] = 0; for (int i=0; i0) { int vLen = types.size(); int dLen = Display.DisplayRealArray.length; // construct ScalarMaps ScalarMap[] maps = new ScalarMap[len]; for (int j=0; j = 0 && q < dLen) mapRange = Display.DisplayRealArray[q]; // construct mapping if (mapDomain == null || mapRange == null) { if (showErrors) { System.err.print("Warning: maps pair (" + name + ", " + q + ") has an invalid "); if (mapDomain == null && mapRange == null) { System.err.print("domain and range"); } else if (mapDomain == null) System.err.print("domain"); else System.err.print("range"); System.err.println(" and will be ignored"); } maps[j] = null; } else { try { maps[j] = new ScalarMap(mapDomain, mapRange); } catch (VisADException exc) { if (showErrors) { System.err.println("Warning: maps pair (" + name + ", " + q + ") cannot be converted to a ScalarMap"); } maps[j] = null; } } } return maps; } } return null; } /** * Converts an array of strings into a VisAD Tuple. * * @param s The array of strings to be converted to a VisAD Tuple. * * @return VisAD Tuple, or null if Tuple could not be created. */ public static Tuple stringsToTuple(String[] s) { return stringsToTuple(s, false); } /** * Converts an array of strings into a VisAD Tuple. * * @param s The array of strings to be converted to a VisAD Tuple. * @param printStackTraces true if the stack trace for * any exception should be printed. * * @return VisAD Tuple, or null if Tuple could not be created. */ public static Tuple stringsToTuple(String[] s, boolean printStackTraces) { try { if (s == null) return null; int len = s.length; if (len == 0) return null; Text[] text = new Text[len]; for (int i=0; i true if the stack trace for * any exception should be printed. * * @return Array of Strings, or null if array could not be created. */ public static String[] tupleToStrings(Tuple t, boolean printStackTraces) { if (t == null) return null; int len = t.getDimension(); try { String[] errors = new String[len]; for (int i=0; i true if the object is Serializable, false otherwise. */ public static boolean isSerializable(Object obj) { return isSerializable(obj, false); } /** * Verify that an object is Serializable by attempting to * serialize it. * * @param obj An object which needs to be serialized * @param printStackTraces true if the stack trace for * any exception should be printed. * * @return true if the object is Serializable, false otherwise. */ public static boolean isSerializable(Object obj, boolean printStackTraces) { java.io.ByteArrayOutputStream outBytes; outBytes = new java.io.ByteArrayOutputStream(); java.io.ObjectOutputStream outStream; try { outStream = new java.io.ObjectOutputStream(outBytes); } catch (java.io.IOException ioe) { if (printStackTraces) ioe.printStackTrace(); return false; } try { outStream.writeObject(obj); outStream.flush(); } catch (java.io.IOException ioe) { if (printStackTraces) ioe.printStackTrace(); return false; } java.io.ByteArrayInputStream inBytes; inBytes = new java.io.ByteArrayInputStream(outBytes.toByteArray()); try { outStream.close(); outBytes.close(); } catch (java.io.IOException ioe) { if (printStackTraces) ioe.printStackTrace(); return false; } java.io.ObjectInputStream inStream; try { inStream = new java.io.ObjectInputStream(inBytes); } catch (java.io.IOException ioe) { if (printStackTraces) ioe.printStackTrace(); return false; } Object obj2; try { obj2 = inStream.readObject(); } catch (java.io.IOException ioe) { if (printStackTraces) ioe.printStackTrace(); return false; } catch (ClassNotFoundException cnfe) { if (printStackTraces) cnfe.printStackTrace(); return false; } try { inStream.close(); inBytes.close(); } catch (java.io.IOException ioe) { if (printStackTraces) ioe.printStackTrace(); return false; } return true; } /** * Converts a remote Data object to a local Data object. * * @param data The Data object to be made local. * * @return Local Data object, or null if Data could not be converted. */ public static DataImpl makeLocal(Data data) { return makeLocal(data, false); } /** * Converts a remote Data object to a local Data object. * * @param data The Data object to be made local. * @param printStackTraces true if the stack trace for * any exception should be printed. * * @return Local Data object, or null if Data could not be converted. */ public static DataImpl makeLocal(Data data, boolean printStackTraces) { try { if (data != null) return data.local(); } catch (VisADException exc) { if (printStackTraces) exc.printStackTrace(); } catch (RemoteException exc) { if (printStackTraces) exc.printStackTrace(); } return null; } /** * Gets the specified sample of a VisAD Set. * * @param set The set to have a sample returned. * @param index The index of the sample to be returned. * @return The sample at the specified index. Will * be empty if the index is out-of-bounds. * Will have a single component if the set is * one-dimensional. * @throws VisADException Couldn't create necessary VisAD object. * @throws RemoteException Java RMI failure. */ public static RealTuple getSample(Set set, int index) throws VisADException, RemoteException { RealTuple sample; RealTupleType realTupleType = ((SetType) set.getType()).getDomain(); double[][] values = Unit.convertTuple(set.indexToDouble(new int[]{ index }), set.getSetUnits(), realTupleType.getDefaultUnits()); if ((index < 0) || (index >= set.getLength())) { sample = new RealTuple(realTupleType); } else { double[] doubles = new double[values.length]; for (int i = doubles.length; --i >= 0; ) { doubles[i] = values[i][0]; } sample = new RealTuple(realTupleType, doubles); } return sample; } /** * Gets the units of the (flat) components of the range of a FlatField. * * @param field The FlatField. * @return The units of the (flat) components of the * range of the FlatField. Won't be * null. */ public static Unit[] getRangeUnits(FlatField field) { Unit[][] units = field.getRangeUnits(); Unit[] result = new Unit[units.length]; for (int i = result.length; --i >= 0; ) { result[i] = units[i][0]; } return result; } /** * Make a RealType with a unique name for the given unit * * @param name name of the RealType * @param unit the default unit * * @return the RealType * * @throws VisADException problem creating the RealType */ public static RealType getUniqueRealType(String name, Unit unit) { return getUniqueRealType(name, unit, null, 0); } /** * Make a RealType with a unique name for the given unit * * @param name name of the RealType * @param unit the default unit * @param set the default set * @param attrMask the attribute mask * * @return the RealType or null if it still can't create a unique name */ public static RealType getUniqueRealType(String name, Unit unit, Set set, int attrMask) { RealType type = RealType.getRealType(name, unit, set, attrMask); if (type == null) { String newname = cleanTypeName(name) + "[unit:" + ((unit == null) ? "null" : cleanTypeName(unit.toString())) + "]"; type = RealType.getRealType(newname, unit, set, attrMask); } return type; } /** * Make a valid VisAD RealType name from the string. Remove * spaces, "." and parens. * @param name name to clean * @return cleaned up name */ public static String cleanTypeName(String name) { name = name.replace('.', '_'); name = name.replace(",","_"); name = name.replace("-","_"); // so doesn't get confused with -> name = name.replace("*","_"); // so it doesn't confuse regexes name = name.replace(' ', '_'); name = name.replace('(', '['); name = name.replace(')', ']'); while(name.indexOf("__")>=0) { name = name.replace("__","_"); } return name; } }
Ads help maintain this website.