diff --git a/epics-util/pom.xml b/epics-util/pom.xml index 51340c06d..2483ff136 100644 --- a/epics-util/pom.xml +++ b/epics-util/pom.xml @@ -1,83 +1,83 @@ - - - 4.0.0 - 1.0.0-SNAPSHOT - org.epics - epics-util - org.epics.util - Basic Java utility classes to be shared across projects until - suitable replacements are available in the JDK. - - UTF-8 - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.6.2 - - 1.8 - 1.8 - - - - org.apache.maven.plugins - maven-source-plugin - 3.0.1 - - - attach-sources - - jar - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - 2.10.4 - - - attach-javadocs - - jar - - - - - - com.mycila - license-maven-plugin - 3.0 - - HEADER.TXT - - **/*.java - - - - - - - - junit - junit - 4.12 - test - - - org.mockito - mockito-all - 1.10.19 - test - - - org.hamcrest - hamcrest-all - 1.3 - test - - - + + + 4.0.0 + 1.0.0-SNAPSHOT + epics-util + org.epics.util + Basic Java utility classes to be shared across projects until + suitable replacements are available in the JDK. + + UTF-8 + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.6.2 + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-source-plugin + 3.0.1 + + + attach-sources + + jar + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.10.4 + + + attach-javadocs + + jar + + + + + + com.mycila + license-maven-plugin + 3.0 + + HEADER.TXT + + **/*.java + + + + + + + + junit + junit + 4.12 + test + + + org.mockito + mockito-all + 1.10.19 + test + + + org.hamcrest + hamcrest-all + 1.3 + test + + + org.epics + diff --git a/epics-vtype/pom.xml b/epics-vtype/pom.xml index d3ec416eb..30b58566d 100644 --- a/epics-vtype/pom.xml +++ b/epics-vtype/pom.xml @@ -1,92 +1,92 @@ - - - 4.0.0 - org.epics - epics-vtype-all - epics-vtype - 1.0.0-SNAPSHOT - pom - A set of standard types for value processing. - - UTF-8 - - - vtype - vtype-json - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.6.2 - - 1.8 - 1.8 - - - - org.apache.maven.plugins - maven-source-plugin - 3.0.1 - - - attach-sources - - jar - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - 2.10.4 - - - attach-javadocs - - jar - - - - - - com.mycila - license-maven-plugin - 3.0 - - HEADER.TXT - - **/*.java - - - - - - - - ${project.groupId} - epics-util - ${project.version} - - - junit - junit - 4.12 - test - - - org.mockito - mockito-all - 1.10.19 - test - - - org.hamcrest - hamcrest-all - 1.3 - test - - - + + + 4.0.0 + epics-vtype-all + epics-vtype + 1.0.0-SNAPSHOT + pom + A set of standard types for value processing. + + UTF-8 + + + vtype + vtype-json + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.6.2 + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-source-plugin + 3.0.1 + + + attach-sources + + jar + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.10.4 + + + attach-javadocs + + jar + + + + + + com.mycila + license-maven-plugin + 3.0 + + HEADER.TXT + + **/*.java + + + + + + + + ${project.groupId} + epics-util + ${project.version} + + + junit + junit + 4.12 + test + + + org.mockito + mockito-all + 1.10.19 + test + + + org.hamcrest + hamcrest-all + 1.3 + test + + + org.epics + diff --git a/epics-vtype/vtype/src/main/java/org/epics/vtype/IVImage.java b/epics-vtype/vtype/src/main/java/org/epics/vtype/IVImage.java new file mode 100644 index 000000000..ecbc6d281 --- /dev/null +++ b/epics-vtype/vtype/src/main/java/org/epics/vtype/IVImage.java @@ -0,0 +1,68 @@ +package org.epics.vtype; + +import org.epics.util.array.ListNumber; + +/** + * An immutable implementation of the {@link VImage} + * + * @author Kunal Shroff + * + */ +public class IVImage extends VImage { + + private final Alarm alarm; + private final Time time; + + private final int height; + private final int width; + private final ListNumber data; + private final VImageDataType imageDataType; + private final VImageType imageType; + + IVImage(int height, int width, ListNumber data, VImageDataType imageDataType, VImageType imageType, Alarm alarm, + Time time) { + super(); + VType.argumentNotNull("alarm", alarm); + VType.argumentNotNull("time", time); + this.alarm = alarm; + this.time = time; + this.height = height; + this.width = width; + this.data = data; + this.imageDataType = imageDataType; + this.imageType = imageType; + } + + public int getHeight() { + return height; + } + + public int getWidth() { + return width; + } + + public ListNumber getData() { + return data; + } + + @Override + public Alarm getAlarm() { + return alarm; + } + + @Override + public Time getTime() { + return time; + } + + @Override + public VImageDataType getDataType() { + return imageDataType; + } + + @Override + public VImageType getVImageType() { + return imageType; + } + +} diff --git a/epics-vtype/vtype/src/main/java/org/epics/vtype/IVTable.java b/epics-vtype/vtype/src/main/java/org/epics/vtype/IVTable.java new file mode 100644 index 000000000..adb67b3fa --- /dev/null +++ b/epics-vtype/vtype/src/main/java/org/epics/vtype/IVTable.java @@ -0,0 +1,68 @@ +/** + * Copyright (C) 2010-18 diirt developers. See COPYRIGHT.TXT + * All rights reserved. Use is subject to license terms. See LICENSE.TXT + */ +package org.epics.vtype; + +import java.util.List; +import org.epics.util.array.ListNumber; + +/** + * An immutable table that extends {@link VTable} + * + * @author carcassi, shroff + */ +class IVTable extends VTable { + + private final List> types; + private final List names; + private final List values; + private final int rowCount; + + IVTable(List> types, List names, List values) { + this.types = types; + this.names = names; + this.values = values; + int maxCount = 0; + for (Object array : values) { + maxCount = Math.max(maxCount, getDataSize(array)); + } + this.rowCount = maxCount; + } + + private static int getDataSize(Object data) { + if (data instanceof List) { + return ((List) data).size(); + } else if (data instanceof ListNumber) { + return ((ListNumber) data).size(); + } + + throw new IllegalArgumentException("Object " + data + " is not supported"); + } + + @Override + public int getColumnCount() { + return names.size(); + } + + @Override + public int getRowCount() { + return rowCount; + } + + @Override + public Class> getColumnType(int column) { + return types.get(column); + } + + @Override + public String getColumnName(int column) { + return names.get(column); + } + + @Override + public Object getColumnData(int column) { + return values.get(column); + } + +} diff --git a/epics-vtype/vtype/src/main/java/org/epics/vtype/VImage.java b/epics-vtype/vtype/src/main/java/org/epics/vtype/VImage.java new file mode 100644 index 000000000..c6e4c345c --- /dev/null +++ b/epics-vtype/vtype/src/main/java/org/epics/vtype/VImage.java @@ -0,0 +1,106 @@ +/** + * Copyright (C) 2010-18 diirt developers. See COPYRIGHT.TXT + * All rights reserved. Use is subject to license terms. See LICENSE.TXT + */ +package org.epics.vtype; + +import java.util.Objects; + +import org.epics.util.array.ListNumber; + +/** + * VImage represents an image. + * + * @author carcassi, shroff + */ +public abstract class VImage extends VType implements AlarmProvider, TimeProvider { + + /** + * Height of the image in pixels. + * + * @return image height + */ + public abstract int getHeight(); + + /** + * Width of the image in pixels. + * + * @return image width + */ + public abstract int getWidth(); + + /** + * Image data; + * + * @return ListNumber image data + */ + public abstract ListNumber getData(); + + /** + * Describes the type in which the data is stored {@link VImageDataType} + * + * @return image data type + */ + public abstract VImageDataType getDataType(); + + /** + * Returns the image type, The image type describes the mechanism in which the + * data is encoded and how it can be converted to something that can be + * rendered. + * + * @return the image type {@link VImageType} + */ + public abstract VImageType getVImageType(); + + /** + * Creates a new VImage. + * + * @param height image height + * @param width image width + * @param data image data + * @param imageDataType image data type + * @param vImageType image type + * @param alarm alarm information + * @param time timestamp + * @return + */ + public static VImage of(int height, int width, final ListNumber data, VImageDataType imageDataType, VImageType vImageType, Alarm alarm, Time time) { + return new IVImage(height, width, data, imageDataType, vImageType, alarm, time); + } + + @Override + public final boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj instanceof VImage) { + VImage other = (VImage) obj; + + return getClass().equals(other.getClass()) + && getHeight() == other.getHeight() + && getWidth() == other.getWidth() + && getData().equals(other.getData()) + && getDataType().equals(other.getDataType()) + && getVImageType().equals(other.getVImageType()) + && getAlarm().equals(other.getAlarm()) + && getTime().equals(other.getTime()); + } + + return false; + } + + @Override + public final int hashCode() { + int hash = 7; + hash = 23 * hash + Objects.hashCode(getHeight()); + hash = 23 * hash + Objects.hashCode(getWidth()); + hash = 23 * hash + Objects.hashCode(getData()); + hash = 23 * hash + Objects.hashCode(getDataType()); + hash = 23 * hash + Objects.hashCode(getVImageType()); + hash = 23 * hash + Objects.hashCode(getAlarm()); + hash = 23 * hash + Objects.hashCode(getTime()); + return hash; + } + +} diff --git a/epics-vtype/vtype/src/main/java/org/epics/vtype/VImageDataType.java b/epics-vtype/vtype/src/main/java/org/epics/vtype/VImageDataType.java new file mode 100644 index 000000000..ccca6735f --- /dev/null +++ b/epics-vtype/vtype/src/main/java/org/epics/vtype/VImageDataType.java @@ -0,0 +1,150 @@ +/** + * Copyright (C) 2010-18 diirt developers. See COPYRIGHT.TXT + * All rights reserved. Use is subject to license terms. See LICENSE.TXT + */ +package org.epics.vtype; +/** + * + * Data type description for {@link VImage} data. + * + * based on the the VImageDataType from org.epics.pvdata.pv + * @author mrk + * + */ +public enum VImageDataType { + /** + * Value has type boolean. + */ + pvBoolean, + /** + * Value has type byte. + */ + pvByte, + /** + * Value has type short. + */ + pvShort, + /** + * Value has type int. + */ + pvInt, + /** + * Value has type long. + */ + pvLong, + /** + * Value has type ubyte. + */ + pvUByte, + /** + * Value has type ushort. + */ + pvUShort, + /** + * Value has type uint. + */ + pvUInt, + /** + * Value has type ulong. + */ + pvULong, + /** + * value has type float. + */ + pvFloat, + /** + * Value has type double. + */ + pvDouble, + /** + * Value has type string. + */ + pvString; + + /** + * Is this an integer (signed or unsigned). true if byte, short, int, long, ubyte, ushort, uint, or ulong. + * @return true if it is an integer type + */ + public boolean isInteger() { + if( (ordinal() >= VImageDataType.pvByte.ordinal()) && (ordinal() <= VImageDataType.pvULong.ordinal()) ) { + return true; + } + return false; + } + + /** + * Is this an unsigned integer. true if ubyte, ushort, uint, or ulong. + * + * @return true if it is an unsigned integer type + */ + public boolean isUInteger() { + if( (ordinal() >= VImageDataType.pvUByte.ordinal()) && (ordinal() <= VImageDataType.pvULong.ordinal()) ) { + return true; + } + return false; + } + + /** + * Is this a Java numeric type? + * + * @return true if the type is a Java numeric type. + * The numeric types are byte, short, int, long, float, and double. + */ + public boolean isNumeric() { + if( (ordinal() >= VImageDataType.pvByte.ordinal()) && (ordinal() <= VImageDataType.pvDouble.ordinal()) ) { + return true; + } + return false; + } + + /** + * Is this a Java primitive type? + * + * @return true if the type is a Java primitive type. + * The numeric types and boolean are primitive types. + */ + public boolean isPrimitive() { + if(isNumeric()) return true; + if(ordinal() == VImageDataType.pvBoolean.ordinal()) return true; + return false; + } + + /** + * Get the VImageDataType for a string defining the type. + * + * @param type a character string defining the type + * @return the VImageDataType or null if an illegal type + */ + public static VImageDataType getVImageDataType(String type) { + if(type.equals("boolean")) return VImageDataType.pvBoolean; + if(type.equals("byte")) return VImageDataType.pvByte; + if(type.equals("short")) return VImageDataType.pvShort; + if(type.equals("int")) return VImageDataType.pvInt; + if(type.equals("long")) return VImageDataType.pvLong; + if(type.equals("ubyte")) return VImageDataType.pvUByte; + if(type.equals("ushort")) return VImageDataType.pvUShort; + if(type.equals("uint")) return VImageDataType.pvUInt; + if(type.equals("ulong")) return VImageDataType.pvULong; + if(type.equals("float")) return VImageDataType.pvFloat; + if(type.equals("double")) return VImageDataType.pvDouble; + if(type.equals("string")) return VImageDataType.pvString; + return null; + } + public String toString() { + switch(this) { + case pvBoolean: return "boolean"; + case pvByte: return "byte"; + case pvShort: return "short"; + case pvInt: return "int"; + case pvLong: return "long"; + case pvUByte: return "ubyte"; + case pvUShort: return "ushort"; + case pvUInt: return "uint"; + case pvULong: return "ulong"; + case pvFloat: return "float"; + case pvDouble: return "double"; + case pvString: return "string"; + } + throw new IllegalArgumentException("Unknown VImageDataType"); + } +} \ No newline at end of file diff --git a/epics-vtype/vtype/src/main/java/org/epics/vtype/VImageType.java b/epics-vtype/vtype/src/main/java/org/epics/vtype/VImageType.java new file mode 100644 index 000000000..190b34252 --- /dev/null +++ b/epics-vtype/vtype/src/main/java/org/epics/vtype/VImageType.java @@ -0,0 +1,122 @@ +/** + * Copyright (C) 2010-18 diirt developers. See COPYRIGHT.TXT + * All rights reserved. Use is subject to license terms. See LICENSE.TXT + */ + +package org.epics.vtype; + +/** + * Description of the the Image Type represented by the {@link VImage} + * + * @author Kunal Shroff + * + */ +public enum VImageType { + /** + * Image type constants + */ + TYPE_CUSTOM, + /** + * Monochromatic image + */ + TYPE_MONO, + /** + * Bayer pattern image, 1 value per pixel but with color filter on + * detector + */ + TYPE_BAYER, + /** + * RGB image with pixel color interleave, data array is [3, NX, NY] + */ + TYPE_RGB1, + /** + * RGB image with row color interleave, data array is [NX, 3, NY] + */ + TYPE_RGB2, + /** + * RGB image with plane color interleave, data array is [NX, NY, 3] + */ + TYPE_RGB3, + /** + * YUV image, 3 bytes encodes 1 RGB pixel + */ + TYPE_YUV444, + /** + * YUV image, 4 bytes encodes 2 RGB pixel + */ + TYPE_YUV422, + /** + * YUV image, 6 bytes encodes 4 RGB pixels + */ + TYPE_YUV411, + /** + * An image with 8-bit RGB color components, corresponding to a + * Windows-style BGR color model with the colors Blue, Green, and Red + * stored in 3 bytes. + */ + TYPE_3BYTE_BGR, + /** + * Represents an image with 8-bit RGBA color components with the colors + * Blue, Green, and Red stored in 3 bytes and 1 byte of alpha. + */ + TYPE_4BYTE_ABGR, + /** + * Represents an image with 8-bit RGBA color components with the colors + * Blue, Green, and Red stored in 3 bytes and 1 byte of alpha. + */ + TYPE_4BYTE_ABGR_PRE, + /** + * Represents an opaque byte-packed 1, 2, or 4 bit image. + */ + TYPE_BYTE_BINARY, + /** + * Represents a unsigned byte grayscale image, non-indexed. + */ + TYPE_BYTE_GRAY, + /** + * Represents an indexed byte image. + */ + TYPE_BYTE_INDEXED, + /** + * Represents an image with 8-bit RGBA color components packed into + * integer pixels. + * + */ + TYPE_INT_ARGB, + /** + * Represents an image with 8-bit RGBA color components packed into + * integer pixels. + * + */ + TYPE_INT_ARGB_PRE, + /** + * Represents an image with 8-bit RGB color components, corresponding to + * a Windows- or Solaris- style BGR color model, with the colors Blue, + * Green, and Red packed into integer pixels. + * + */ + TYPE_INT_BGR, + /** + * Represents an image with 8-bit RGB color components packed into + * integer pixels. + * + */ + TYPE_INT_RGB, + /** + * Represents an image with 5-5-5 RGB color components (5-bits red, + * 5-bits green, 5-bits blue) with no alpha. + * + */ + TYPE_USHORT_555_RGB, + /** + * Represents an image with 5-6-5 RGB color components (5-bits red, + * 6-bits green, 5-bits blue) with no alpha. + * + */ + TYPE_USHORT_565_RGB, + /** + * Represents an unsigned short grayscale image, non-indexed). + * + */ + TYPE_USHORT_GRAY +} \ No newline at end of file diff --git a/epics-vtype/vtype/src/main/java/org/epics/vtype/VTable.java b/epics-vtype/vtype/src/main/java/org/epics/vtype/VTable.java new file mode 100644 index 000000000..a29869211 --- /dev/null +++ b/epics-vtype/vtype/src/main/java/org/epics/vtype/VTable.java @@ -0,0 +1,79 @@ +/** + * Copyright (C) 2010-18 diirt developers. See COPYRIGHT.TXT + * All rights reserved. Use is subject to license terms. See LICENSE.TXT + */ +package org.epics.vtype; + +import java.util.List; +import org.epics.util.array.ListNumber; + +/** + * A table. Tables are collections of columns, each of which is composed of a + * String representing the name of the column and a list of a particular type + * (all elements of the same column must be of the same type). + * + * @author carcassi, shroff + */ +public abstract class VTable extends VType { + + /** + * The number of columns in the table. + * + * @return the number of columns + */ + abstract int getColumnCount(); + + /** + * The number of rows in the table. + * + * Currently, it is not clear whether all columns actually have the same number + * of rows, that is if all arrays have the same length. In the case of variable + * row, this will return the maximum row count, that is the length of the + * longest array/column. + * + * @return the number of rows + */ + abstract int getRowCount(); + + /** + * The type of the elements in the column. The column array will be an array of + * the given type. For primitive types, this function will return the TYPE class + * (such as {@link Double#TYPE}, while {@link #getColumnData(int) } will return + * a {@link ListNumber}. + * + * @param column the column index + * @return the type of this column + */ + abstract Class> getColumnType(int column); + + /** + * The name of the given column. + * + * @param column the column index + * @return the name of the column + */ + abstract String getColumnName(int column); + + /** + * The data for the given column. + * + * The data is going to be a {@link List} in case of objects or a + * {@link ListNumber} in case of a numeric primitive. + * + * @param column the column index + * @return the data of the column + */ + abstract Object getColumnData(int column); + + /** + * Create a new VTable + * + * @param types the types of each column + * @param names the name of each column + * @param values the values of each column + * @return an immutable instance of the VTable + */ + public static VTable of(List> types, List names, List values) { + return new IVTable(types, names, values); + } +} diff --git a/epics-vtype/vtype/src/main/java/org/epics/vtype/VType.java b/epics-vtype/vtype/src/main/java/org/epics/vtype/VType.java index a4dc0569c..bc5c21fc5 100644 --- a/epics-vtype/vtype/src/main/java/org/epics/vtype/VType.java +++ b/epics-vtype/vtype/src/main/java/org/epics/vtype/VType.java @@ -1,188 +1,190 @@ -/** - * Copyright information and license terms for this software can be - * found in the file LICENSE.TXT included with the distribution. - */ -package org.epics.vtype; - -import java.util.Arrays; -import java.util.Collection; -import java.util.List; -import org.epics.util.array.CollectionNumbers; -import org.epics.util.array.ListNumber; - -/** - * Tag interface to mark all the members of the value classes. - * - * @author carcassi - */ -public abstract class VType { - - private static final Collection> TYPES = Arrays.>asList( - VDouble.class, - VFloat.class, - VULong.class, - VLong.class, - VUInt.class, - VInt.class, - VUShort.class, - VShort.class, - VUByte.class, - VByte.class, - VEnum.class, - VBoolean.class, - VString.class, - VDoubleArray.class, - VFloatArray.class, - VULongArray.class, - VLongArray.class, - VUIntArray.class, - VIntArray.class, - VUShortArray.class, - VShortArray.class, - VUByteArray.class, - VByteArray.class); - - /** - * Returns the type of the object by returning the class object of one - * of the VXxx interfaces. The getClass() methods returns the - * concrete implementation type, which is of little use. If no - * super-interface is found, Object.class is used. - * - * @param obj an object implementing a standard type - * @return the type is implementing - */ - public static Class> typeOf(Object obj) { - if (obj == null) - return null; - - for (Class> type : TYPES) { - if (type.isInstance(obj)) { - return type; - } - } - - return Object.class; - } - - /** - * As {@link #toVType(java.lang.Object)} but throws an exception - * if conversion not possible. - * - * @param javaObject the value to wrap - * @return the new VType value - */ - public static VType toVTypeChecked(Object javaObject) { - VType value = toVType(javaObject); - if (value == null) { - throw new IllegalArgumentException("Value " + value + " cannot be converted to VType."); - } - return value; - } - - /** - * As {@link #toVType(java.lang.Object, org.epics.vtype.Alarm, org.epics.vtype.Time, org.epics.vtype.Display)} but throws an exception - * if conversion not possible. - * - * @param javaObject the value to wrap - * @param alarm the alarm - * @param time the time - * @param display the display - * @return the new VType value - */ - public static VType toVTypeChecked(Object javaObject, Alarm alarm, Time time, Display display) { - VType value = toVType(javaObject, alarm, time, display); - if (value == null) { - throw new IllegalArgumentException("Value " + value + " cannot be converted to VType."); - } - return value; - } - - /** - * Converts a standard java type to VTypes. Returns null if no conversion - * is possible. Calls {@link #toVType(java.lang.Object, org.epics.vtype.Alarm, org.epics.vtype.Time, org.epics.vtype.Display) } - * with no alarm, time now and no display. - * - * @param javaObject the value to wrap - * @return the new VType value - */ - public static VType toVType(Object javaObject) { - return toVType(javaObject, Alarm.none(), Time.now(), Display.none()); - } - - /** - * Converts a standard java type to VTypes. Returns null if no conversion - * is possible. Calls {@link #toVType(java.lang.Object, org.epics.vtype.Alarm, org.epics.vtype.Time, org.epics.vtype.Display) } - * with the given alarm, time now and no display. - * - * @param javaObject the value to wrap - * @param alarm the alarm - * @return the new VType value - */ - public static VType toVType(Object javaObject, Alarm alarm) { - return toVType(javaObject, alarm, Time.now(), Display.none()); - } - - /** - * Converts a standard java type to VTypes. Returns null if no conversion - * is possible. - * - * Types are converted as follow: - * - * Boolean -> VBoolean - * Number -> corresponding VNumber - * String -> VString - * number array -> corresponding VNumberArray - * ListNumber -> corresponding VNumberArray - * List -> if all elements are String, VStringArray - * - * - * @param javaObject the value to wrap - * @param alarm the alarm - * @param time the time - * @param display the display - * @return the new VType value - */ - public static VType toVType(Object javaObject, Alarm alarm, Time time, Display display) { - if (javaObject instanceof Number) { - return VNumber.of((Number) javaObject, alarm, time, display); - } else if (javaObject instanceof String) { - return VString.of((String) javaObject, alarm, time); - } else if (javaObject instanceof Boolean) { - return VBoolean.of((Boolean) javaObject, alarm, time); - } else if (javaObject instanceof byte[] - || javaObject instanceof short[] - || javaObject instanceof int[] - || javaObject instanceof long[] - || javaObject instanceof float[] - || javaObject instanceof double[]) { - return VNumberArray.of(CollectionNumbers.toList(javaObject), alarm, time, display); - } else if (javaObject instanceof ListNumber) { - return VNumberArray.of((ListNumber) javaObject, alarm, time, display); - } else if (javaObject instanceof String[]) { - return null;//newVStringArray(Arrays.asList((String[]) javaObject), alarm, time); - } else if (javaObject instanceof List) { - boolean matches = true; - List list = (List) javaObject; - for (Object object : list) { - if (!(object instanceof String)) { - matches = false; - } - } - if (matches) { - @SuppressWarnings("unchecked") - List newList = (List) list; - return null;//newVStringArray(Collections.unmodifiableList(newList), alarm, time); - } else { - return null; - } - } else { - return null; - } - } - - static void argumentNotNull(String argName, Object value) { - if (value == null) { - throw new NullPointerException(argName + " can't be null"); - } - } -} +/** + * Copyright information and license terms for this software can be + * found in the file LICENSE.TXT included with the distribution. + */ +package org.epics.vtype; + +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import org.epics.util.array.CollectionNumbers; +import org.epics.util.array.ListNumber; + +/** + * Tag interface to mark all the members of the value classes. + * + * @author carcassi + */ +public abstract class VType { + + private static final Collection> TYPES = Arrays.>asList( + VDouble.class, + VFloat.class, + VULong.class, + VLong.class, + VUInt.class, + VInt.class, + VUShort.class, + VShort.class, + VUByte.class, + VByte.class, + VEnum.class, + VBoolean.class, + VString.class, + VDoubleArray.class, + VFloatArray.class, + VULongArray.class, + VLongArray.class, + VUIntArray.class, + VIntArray.class, + VUShortArray.class, + VShortArray.class, + VUByteArray.class, + VByteArray.class, + VImage.class, + VTable.class); + + /** + * Returns the type of the object by returning the class object of one + * of the VXxx interfaces. The getClass() methods returns the + * concrete implementation type, which is of little use. If no + * super-interface is found, Object.class is used. + * + * @param obj an object implementing a standard type + * @return the type is implementing + */ + public static Class> typeOf(Object obj) { + if (obj == null) + return null; + + for (Class> type : TYPES) { + if (type.isInstance(obj)) { + return type; + } + } + + return Object.class; + } + + /** + * As {@link #toVType(java.lang.Object)} but throws an exception + * if conversion not possible. + * + * @param javaObject the value to wrap + * @return the new VType value + */ + public static VType toVTypeChecked(Object javaObject) { + VType value = toVType(javaObject); + if (value == null) { + throw new IllegalArgumentException("Value " + value + " cannot be converted to VType."); + } + return value; + } + + /** + * As {@link #toVType(java.lang.Object, org.epics.vtype.Alarm, org.epics.vtype.Time, org.epics.vtype.Display)} but throws an exception + * if conversion not possible. + * + * @param javaObject the value to wrap + * @param alarm the alarm + * @param time the time + * @param display the display + * @return the new VType value + */ + public static VType toVTypeChecked(Object javaObject, Alarm alarm, Time time, Display display) { + VType value = toVType(javaObject, alarm, time, display); + if (value == null) { + throw new IllegalArgumentException("Value " + value + " cannot be converted to VType."); + } + return value; + } + + /** + * Converts a standard java type to VTypes. Returns null if no conversion + * is possible. Calls {@link #toVType(java.lang.Object, org.epics.vtype.Alarm, org.epics.vtype.Time, org.epics.vtype.Display) } + * with no alarm, time now and no display. + * + * @param javaObject the value to wrap + * @return the new VType value + */ + public static VType toVType(Object javaObject) { + return toVType(javaObject, Alarm.none(), Time.now(), Display.none()); + } + + /** + * Converts a standard java type to VTypes. Returns null if no conversion + * is possible. Calls {@link #toVType(java.lang.Object, org.epics.vtype.Alarm, org.epics.vtype.Time, org.epics.vtype.Display) } + * with the given alarm, time now and no display. + * + * @param javaObject the value to wrap + * @param alarm the alarm + * @return the new VType value + */ + public static VType toVType(Object javaObject, Alarm alarm) { + return toVType(javaObject, alarm, Time.now(), Display.none()); + } + + /** + * Converts a standard java type to VTypes. Returns null if no conversion + * is possible. + * + * Types are converted as follow: + * + * Boolean -> VBoolean + * Number -> corresponding VNumber + * String -> VString + * number array -> corresponding VNumberArray + * ListNumber -> corresponding VNumberArray + * List -> if all elements are String, VStringArray + * + * + * @param javaObject the value to wrap + * @param alarm the alarm + * @param time the time + * @param display the display + * @return the new VType value + */ + public static VType toVType(Object javaObject, Alarm alarm, Time time, Display display) { + if (javaObject instanceof Number) { + return VNumber.of((Number) javaObject, alarm, time, display); + } else if (javaObject instanceof String) { + return VString.of((String) javaObject, alarm, time); + } else if (javaObject instanceof Boolean) { + return VBoolean.of((Boolean) javaObject, alarm, time); + } else if (javaObject instanceof byte[] + || javaObject instanceof short[] + || javaObject instanceof int[] + || javaObject instanceof long[] + || javaObject instanceof float[] + || javaObject instanceof double[]) { + return VNumberArray.of(CollectionNumbers.toList(javaObject), alarm, time, display); + } else if (javaObject instanceof ListNumber) { + return VNumberArray.of((ListNumber) javaObject, alarm, time, display); + } else if (javaObject instanceof String[]) { + return null;//newVStringArray(Arrays.asList((String[]) javaObject), alarm, time); + } else if (javaObject instanceof List) { + boolean matches = true; + List list = (List) javaObject; + for (Object object : list) { + if (!(object instanceof String)) { + matches = false; + } + } + if (matches) { + @SuppressWarnings("unchecked") + List newList = (List) list; + return null;//newVStringArray(Collections.unmodifiableList(newList), alarm, time); + } else { + return null; + } + } else { + return null; + } + } + + static void argumentNotNull(String argName, Object value) { + if (value == null) { + throw new NullPointerException(argName + " can't be null"); + } + } +} diff --git a/epics-vtype/vtype/src/test/java/org/epics/vtype/VImageTest.java b/epics-vtype/vtype/src/test/java/org/epics/vtype/VImageTest.java new file mode 100644 index 000000000..5ced6de40 --- /dev/null +++ b/epics-vtype/vtype/src/test/java/org/epics/vtype/VImageTest.java @@ -0,0 +1,64 @@ +package org.epics.vtype; + +import static org.junit.Assert.assertEquals; + +import java.awt.image.BufferedImage; +import java.awt.image.DataBufferByte; +import java.io.File; +import java.io.IOException; + +import javax.imageio.ImageIO; + +import org.epics.util.array.ArrayByte; +import org.epics.util.array.ListNumber; +import org.junit.Test; + +public class VImageTest { + + /** + * A test for the creation of a {@link VImage} data structure using an example image + */ + @Test + public void of() { + BufferedImage img = null; + VImage vImage = null; + boolean done = false; + try { + img = ImageIO.read(VType.class.getResource("Tulips.jpg")); + vImage = VImage.of(img.getHeight(), img.getWidth(), + ArrayByte.of(((DataBufferByte) img.getRaster().getDataBuffer()).getData()), VImageDataType.pvByte, + VImageType.TYPE_3BYTE_BGR, + Alarm.none(), Time.now()); + BufferedImage vImg = toImage(vImage); + for (int x = 0; x < vImage.getWidth(); x++) { + for (int y = 0; y < vImage.getHeight(); y++) { + assertEquals(img.getRGB(x, y), vImg.getRGB(x, y)); + } + } + done = true; + } catch (IOException e) { + } finally { + if (!done) { + BufferedImage bf = toImage(vImage); + try { + ImageIO.write(bf, "png", new File("src/test/resources/org/diirt/vtype/Tuplips-failed.jpg")); + } catch (IOException e) { + } + } + } + } + + private static BufferedImage toImage(VImage vImage) { + if (vImage.getVImageType() == VImageType.TYPE_3BYTE_BGR) { + BufferedImage image = new BufferedImage(vImage.getWidth(), vImage.getHeight(), BufferedImage.TYPE_3BYTE_BGR); + ListNumber data = vImage.getData(); + for (int i = 0; i < data.size(); i++) { + ((DataBufferByte) image.getRaster().getDataBuffer()).getData()[i] = data.getByte(i); + } + return image; + } else { + throw new UnsupportedOperationException( + "No support for creating a BufferedImage from Image Type: " + vImage.getVImageType()); + } + } +} diff --git a/epics-vtype/vtype/src/test/resources/org/epics/vtype/Tulips.jpg b/epics-vtype/vtype/src/test/resources/org/epics/vtype/Tulips.jpg new file mode 100644 index 000000000..54c51eb6a Binary files /dev/null and b/epics-vtype/vtype/src/test/resources/org/epics/vtype/Tulips.jpg differ diff --git a/pom.xml b/pom.xml index 0ef054900..bdb5e5708 100644 --- a/pom.xml +++ b/pom.xml @@ -34,6 +34,9 @@ pvDatabaseJava epics-core epics-deploy + epics-util + epics-vtype + gpclient diff --git a/pvDataJava/pom.xml b/pvDataJava/pom.xml index 8b40bdc94..4f0f2118e 100644 --- a/pvDataJava/pom.xml +++ b/pvDataJava/pom.xml @@ -42,4 +42,17 @@ https://github.com/epics-base/pvDataJava https://github.com/epics-base/pvDataJava + + + ${project.groupId} + epics-util + 1.0.0-SNAPSHOT + + + org.hamcrest + hamcrest-all + 1.3 + test + + diff --git a/pvDataJava/src/org/epics/pvdata/copy/package.html b/pvDataJava/src/org/epics/pvdata/copy/package.html index ebb177af4..4399d065a 100644 --- a/pvDataJava/src/org/epics/pvdata/copy/package.html +++ b/pvDataJava/src/org/epics/pvdata/copy/package.html @@ -18,5 +18,7 @@ + +
+ * Currently, it is not clear whether all columns actually have the same number + * of rows, that is if all arrays have the same length. In the case of variable + * row, this will return the maximum row count, that is the length of the + * longest array/column. + * + * @return the number of rows + */ + abstract int getRowCount(); + + /** + * The type of the elements in the column. The column array will be an array of + * the given type. For primitive types, this function will return the TYPE class + * (such as {@link Double#TYPE}, while {@link #getColumnData(int) } will return + * a {@link ListNumber}. + * + * @param column the column index + * @return the type of this column + */ + abstract Class> getColumnType(int column); + + /** + * The name of the given column. + * + * @param column the column index + * @return the name of the column + */ + abstract String getColumnName(int column); + + /** + * The data for the given column. + *
+ * The data is going to be a {@link List} in case of objects or a + * {@link ListNumber} in case of a numeric primitive. + * + * @param column the column index + * @return the data of the column + */ + abstract Object getColumnData(int column); + + /** + * Create a new VTable + * + * @param types the types of each column + * @param names the name of each column + * @param values the values of each column + * @return an immutable instance of the VTable + */ + public static VTable of(List> types, List names, List values) { + return new IVTable(types, names, values); + } +} diff --git a/epics-vtype/vtype/src/main/java/org/epics/vtype/VType.java b/epics-vtype/vtype/src/main/java/org/epics/vtype/VType.java index a4dc0569c..bc5c21fc5 100644 --- a/epics-vtype/vtype/src/main/java/org/epics/vtype/VType.java +++ b/epics-vtype/vtype/src/main/java/org/epics/vtype/VType.java @@ -1,188 +1,190 @@ -/** - * Copyright information and license terms for this software can be - * found in the file LICENSE.TXT included with the distribution. - */ -package org.epics.vtype; - -import java.util.Arrays; -import java.util.Collection; -import java.util.List; -import org.epics.util.array.CollectionNumbers; -import org.epics.util.array.ListNumber; - -/** - * Tag interface to mark all the members of the value classes. - * - * @author carcassi - */ -public abstract class VType { - - private static final Collection> TYPES = Arrays.>asList( - VDouble.class, - VFloat.class, - VULong.class, - VLong.class, - VUInt.class, - VInt.class, - VUShort.class, - VShort.class, - VUByte.class, - VByte.class, - VEnum.class, - VBoolean.class, - VString.class, - VDoubleArray.class, - VFloatArray.class, - VULongArray.class, - VLongArray.class, - VUIntArray.class, - VIntArray.class, - VUShortArray.class, - VShortArray.class, - VUByteArray.class, - VByteArray.class); - - /** - * Returns the type of the object by returning the class object of one - * of the VXxx interfaces. The getClass() methods returns the - * concrete implementation type, which is of little use. If no - * super-interface is found, Object.class is used. - * - * @param obj an object implementing a standard type - * @return the type is implementing - */ - public static Class> typeOf(Object obj) { - if (obj == null) - return null; - - for (Class> type : TYPES) { - if (type.isInstance(obj)) { - return type; - } - } - - return Object.class; - } - - /** - * As {@link #toVType(java.lang.Object)} but throws an exception - * if conversion not possible. - * - * @param javaObject the value to wrap - * @return the new VType value - */ - public static VType toVTypeChecked(Object javaObject) { - VType value = toVType(javaObject); - if (value == null) { - throw new IllegalArgumentException("Value " + value + " cannot be converted to VType."); - } - return value; - } - - /** - * As {@link #toVType(java.lang.Object, org.epics.vtype.Alarm, org.epics.vtype.Time, org.epics.vtype.Display)} but throws an exception - * if conversion not possible. - * - * @param javaObject the value to wrap - * @param alarm the alarm - * @param time the time - * @param display the display - * @return the new VType value - */ - public static VType toVTypeChecked(Object javaObject, Alarm alarm, Time time, Display display) { - VType value = toVType(javaObject, alarm, time, display); - if (value == null) { - throw new IllegalArgumentException("Value " + value + " cannot be converted to VType."); - } - return value; - } - - /** - * Converts a standard java type to VTypes. Returns null if no conversion - * is possible. Calls {@link #toVType(java.lang.Object, org.epics.vtype.Alarm, org.epics.vtype.Time, org.epics.vtype.Display) } - * with no alarm, time now and no display. - * - * @param javaObject the value to wrap - * @return the new VType value - */ - public static VType toVType(Object javaObject) { - return toVType(javaObject, Alarm.none(), Time.now(), Display.none()); - } - - /** - * Converts a standard java type to VTypes. Returns null if no conversion - * is possible. Calls {@link #toVType(java.lang.Object, org.epics.vtype.Alarm, org.epics.vtype.Time, org.epics.vtype.Display) } - * with the given alarm, time now and no display. - * - * @param javaObject the value to wrap - * @param alarm the alarm - * @return the new VType value - */ - public static VType toVType(Object javaObject, Alarm alarm) { - return toVType(javaObject, alarm, Time.now(), Display.none()); - } - - /** - * Converts a standard java type to VTypes. Returns null if no conversion - * is possible. - * - * Types are converted as follow: - * - * Boolean -> VBoolean - * Number -> corresponding VNumber - * String -> VString - * number array -> corresponding VNumberArray - * ListNumber -> corresponding VNumberArray - * List -> if all elements are String, VStringArray - * - * - * @param javaObject the value to wrap - * @param alarm the alarm - * @param time the time - * @param display the display - * @return the new VType value - */ - public static VType toVType(Object javaObject, Alarm alarm, Time time, Display display) { - if (javaObject instanceof Number) { - return VNumber.of((Number) javaObject, alarm, time, display); - } else if (javaObject instanceof String) { - return VString.of((String) javaObject, alarm, time); - } else if (javaObject instanceof Boolean) { - return VBoolean.of((Boolean) javaObject, alarm, time); - } else if (javaObject instanceof byte[] - || javaObject instanceof short[] - || javaObject instanceof int[] - || javaObject instanceof long[] - || javaObject instanceof float[] - || javaObject instanceof double[]) { - return VNumberArray.of(CollectionNumbers.toList(javaObject), alarm, time, display); - } else if (javaObject instanceof ListNumber) { - return VNumberArray.of((ListNumber) javaObject, alarm, time, display); - } else if (javaObject instanceof String[]) { - return null;//newVStringArray(Arrays.asList((String[]) javaObject), alarm, time); - } else if (javaObject instanceof List) { - boolean matches = true; - List list = (List) javaObject; - for (Object object : list) { - if (!(object instanceof String)) { - matches = false; - } - } - if (matches) { - @SuppressWarnings("unchecked") - List newList = (List) list; - return null;//newVStringArray(Collections.unmodifiableList(newList), alarm, time); - } else { - return null; - } - } else { - return null; - } - } - - static void argumentNotNull(String argName, Object value) { - if (value == null) { - throw new NullPointerException(argName + " can't be null"); - } - } -} +/** + * Copyright information and license terms for this software can be + * found in the file LICENSE.TXT included with the distribution. + */ +package org.epics.vtype; + +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import org.epics.util.array.CollectionNumbers; +import org.epics.util.array.ListNumber; + +/** + * Tag interface to mark all the members of the value classes. + * + * @author carcassi + */ +public abstract class VType { + + private static final Collection> TYPES = Arrays.>asList( + VDouble.class, + VFloat.class, + VULong.class, + VLong.class, + VUInt.class, + VInt.class, + VUShort.class, + VShort.class, + VUByte.class, + VByte.class, + VEnum.class, + VBoolean.class, + VString.class, + VDoubleArray.class, + VFloatArray.class, + VULongArray.class, + VLongArray.class, + VUIntArray.class, + VIntArray.class, + VUShortArray.class, + VShortArray.class, + VUByteArray.class, + VByteArray.class, + VImage.class, + VTable.class); + + /** + * Returns the type of the object by returning the class object of one + * of the VXxx interfaces. The getClass() methods returns the + * concrete implementation type, which is of little use. If no + * super-interface is found, Object.class is used. + * + * @param obj an object implementing a standard type + * @return the type is implementing + */ + public static Class> typeOf(Object obj) { + if (obj == null) + return null; + + for (Class> type : TYPES) { + if (type.isInstance(obj)) { + return type; + } + } + + return Object.class; + } + + /** + * As {@link #toVType(java.lang.Object)} but throws an exception + * if conversion not possible. + * + * @param javaObject the value to wrap + * @return the new VType value + */ + public static VType toVTypeChecked(Object javaObject) { + VType value = toVType(javaObject); + if (value == null) { + throw new IllegalArgumentException("Value " + value + " cannot be converted to VType."); + } + return value; + } + + /** + * As {@link #toVType(java.lang.Object, org.epics.vtype.Alarm, org.epics.vtype.Time, org.epics.vtype.Display)} but throws an exception + * if conversion not possible. + * + * @param javaObject the value to wrap + * @param alarm the alarm + * @param time the time + * @param display the display + * @return the new VType value + */ + public static VType toVTypeChecked(Object javaObject, Alarm alarm, Time time, Display display) { + VType value = toVType(javaObject, alarm, time, display); + if (value == null) { + throw new IllegalArgumentException("Value " + value + " cannot be converted to VType."); + } + return value; + } + + /** + * Converts a standard java type to VTypes. Returns null if no conversion + * is possible. Calls {@link #toVType(java.lang.Object, org.epics.vtype.Alarm, org.epics.vtype.Time, org.epics.vtype.Display) } + * with no alarm, time now and no display. + * + * @param javaObject the value to wrap + * @return the new VType value + */ + public static VType toVType(Object javaObject) { + return toVType(javaObject, Alarm.none(), Time.now(), Display.none()); + } + + /** + * Converts a standard java type to VTypes. Returns null if no conversion + * is possible. Calls {@link #toVType(java.lang.Object, org.epics.vtype.Alarm, org.epics.vtype.Time, org.epics.vtype.Display) } + * with the given alarm, time now and no display. + * + * @param javaObject the value to wrap + * @param alarm the alarm + * @return the new VType value + */ + public static VType toVType(Object javaObject, Alarm alarm) { + return toVType(javaObject, alarm, Time.now(), Display.none()); + } + + /** + * Converts a standard java type to VTypes. Returns null if no conversion + * is possible. + * + * Types are converted as follow: + * + * Boolean -> VBoolean + * Number -> corresponding VNumber + * String -> VString + * number array -> corresponding VNumberArray + * ListNumber -> corresponding VNumberArray + * List -> if all elements are String, VStringArray + * + * + * @param javaObject the value to wrap + * @param alarm the alarm + * @param time the time + * @param display the display + * @return the new VType value + */ + public static VType toVType(Object javaObject, Alarm alarm, Time time, Display display) { + if (javaObject instanceof Number) { + return VNumber.of((Number) javaObject, alarm, time, display); + } else if (javaObject instanceof String) { + return VString.of((String) javaObject, alarm, time); + } else if (javaObject instanceof Boolean) { + return VBoolean.of((Boolean) javaObject, alarm, time); + } else if (javaObject instanceof byte[] + || javaObject instanceof short[] + || javaObject instanceof int[] + || javaObject instanceof long[] + || javaObject instanceof float[] + || javaObject instanceof double[]) { + return VNumberArray.of(CollectionNumbers.toList(javaObject), alarm, time, display); + } else if (javaObject instanceof ListNumber) { + return VNumberArray.of((ListNumber) javaObject, alarm, time, display); + } else if (javaObject instanceof String[]) { + return null;//newVStringArray(Arrays.asList((String[]) javaObject), alarm, time); + } else if (javaObject instanceof List) { + boolean matches = true; + List list = (List) javaObject; + for (Object object : list) { + if (!(object instanceof String)) { + matches = false; + } + } + if (matches) { + @SuppressWarnings("unchecked") + List newList = (List) list; + return null;//newVStringArray(Collections.unmodifiableList(newList), alarm, time); + } else { + return null; + } + } else { + return null; + } + } + + static void argumentNotNull(String argName, Object value) { + if (value == null) { + throw new NullPointerException(argName + " can't be null"); + } + } +} diff --git a/epics-vtype/vtype/src/test/java/org/epics/vtype/VImageTest.java b/epics-vtype/vtype/src/test/java/org/epics/vtype/VImageTest.java new file mode 100644 index 000000000..5ced6de40 --- /dev/null +++ b/epics-vtype/vtype/src/test/java/org/epics/vtype/VImageTest.java @@ -0,0 +1,64 @@ +package org.epics.vtype; + +import static org.junit.Assert.assertEquals; + +import java.awt.image.BufferedImage; +import java.awt.image.DataBufferByte; +import java.io.File; +import java.io.IOException; + +import javax.imageio.ImageIO; + +import org.epics.util.array.ArrayByte; +import org.epics.util.array.ListNumber; +import org.junit.Test; + +public class VImageTest { + + /** + * A test for the creation of a {@link VImage} data structure using an example image + */ + @Test + public void of() { + BufferedImage img = null; + VImage vImage = null; + boolean done = false; + try { + img = ImageIO.read(VType.class.getResource("Tulips.jpg")); + vImage = VImage.of(img.getHeight(), img.getWidth(), + ArrayByte.of(((DataBufferByte) img.getRaster().getDataBuffer()).getData()), VImageDataType.pvByte, + VImageType.TYPE_3BYTE_BGR, + Alarm.none(), Time.now()); + BufferedImage vImg = toImage(vImage); + for (int x = 0; x < vImage.getWidth(); x++) { + for (int y = 0; y < vImage.getHeight(); y++) { + assertEquals(img.getRGB(x, y), vImg.getRGB(x, y)); + } + } + done = true; + } catch (IOException e) { + } finally { + if (!done) { + BufferedImage bf = toImage(vImage); + try { + ImageIO.write(bf, "png", new File("src/test/resources/org/diirt/vtype/Tuplips-failed.jpg")); + } catch (IOException e) { + } + } + } + } + + private static BufferedImage toImage(VImage vImage) { + if (vImage.getVImageType() == VImageType.TYPE_3BYTE_BGR) { + BufferedImage image = new BufferedImage(vImage.getWidth(), vImage.getHeight(), BufferedImage.TYPE_3BYTE_BGR); + ListNumber data = vImage.getData(); + for (int i = 0; i < data.size(); i++) { + ((DataBufferByte) image.getRaster().getDataBuffer()).getData()[i] = data.getByte(i); + } + return image; + } else { + throw new UnsupportedOperationException( + "No support for creating a BufferedImage from Image Type: " + vImage.getVImageType()); + } + } +} diff --git a/epics-vtype/vtype/src/test/resources/org/epics/vtype/Tulips.jpg b/epics-vtype/vtype/src/test/resources/org/epics/vtype/Tulips.jpg new file mode 100644 index 000000000..54c51eb6a Binary files /dev/null and b/epics-vtype/vtype/src/test/resources/org/epics/vtype/Tulips.jpg differ diff --git a/pom.xml b/pom.xml index 0ef054900..bdb5e5708 100644 --- a/pom.xml +++ b/pom.xml @@ -34,6 +34,9 @@ pvDatabaseJava epics-core epics-deploy + epics-util + epics-vtype + gpclient diff --git a/pvDataJava/pom.xml b/pvDataJava/pom.xml index 8b40bdc94..4f0f2118e 100644 --- a/pvDataJava/pom.xml +++ b/pvDataJava/pom.xml @@ -42,4 +42,17 @@ https://github.com/epics-base/pvDataJava https://github.com/epics-base/pvDataJava + + + ${project.groupId} + epics-util + 1.0.0-SNAPSHOT + + + org.hamcrest + hamcrest-all + 1.3 + test + + diff --git a/pvDataJava/src/org/epics/pvdata/copy/package.html b/pvDataJava/src/org/epics/pvdata/copy/package.html index ebb177af4..4399d065a 100644 --- a/pvDataJava/src/org/epics/pvdata/copy/package.html +++ b/pvDataJava/src/org/epics/pvdata/copy/package.html @@ -18,5 +18,7 @@ + +
- * Types are converted as follow: - *
+ * Types are converted as follow: + *