From a64b263c2098a181c490accd731334889861b6ec Mon Sep 17 00:00:00 2001 From: gene Date: Thu, 12 Oct 2006 21:12:00 +0000 Subject: [PATCH 0001/2572] Created folder remotely From 6c140031ba53518fbe1d7c1b7d9540fb8febd3e8 Mon Sep 17 00:00:00 2001 From: gene Date: Thu, 12 Oct 2006 21:39:04 +0000 Subject: [PATCH 0002/2572] Imported State Street project files --- .../statestreet/fxa/load/ColumnMap.java | 32 +++ .../statestreet/fxa/load/DataTransformer.java | 261 ++++++++++++++++++ .../custom/statestreet/fxa/load/FieldTrf.java | 27 ++ .../fxa/load/IdentityFieldTrf.java | 20 ++ .../custom/statestreet/fxa/load/MDDump.java | 43 +++ .../fxa/load/OneToOneFieldTrf.java | 48 ++++ .../statestreet/fxa/load/StringFieldTrf.java | 20 ++ .../fxa/load/SubStringFieldTrf.java | 28 ++ .../fxa/load/UpperCaseStringFieldTrf.java | 18 ++ .../fxa/load/ZeroOrMoreToOneFieldTrf.java | 35 +++ .../fxa/utils/AccessConnectionFactory.java | 28 ++ 11 files changed, 560 insertions(+) create mode 100644 src/deltix/custom/statestreet/fxa/load/ColumnMap.java create mode 100644 src/deltix/custom/statestreet/fxa/load/DataTransformer.java create mode 100644 src/deltix/custom/statestreet/fxa/load/FieldTrf.java create mode 100644 src/deltix/custom/statestreet/fxa/load/IdentityFieldTrf.java create mode 100644 src/deltix/custom/statestreet/fxa/load/MDDump.java create mode 100644 src/deltix/custom/statestreet/fxa/load/OneToOneFieldTrf.java create mode 100644 src/deltix/custom/statestreet/fxa/load/StringFieldTrf.java create mode 100644 src/deltix/custom/statestreet/fxa/load/SubStringFieldTrf.java create mode 100644 src/deltix/custom/statestreet/fxa/load/UpperCaseStringFieldTrf.java create mode 100644 src/deltix/custom/statestreet/fxa/load/ZeroOrMoreToOneFieldTrf.java create mode 100644 src/deltix/custom/statestreet/fxa/utils/AccessConnectionFactory.java diff --git a/src/deltix/custom/statestreet/fxa/load/ColumnMap.java b/src/deltix/custom/statestreet/fxa/load/ColumnMap.java new file mode 100644 index 00000000..ec459184 --- /dev/null +++ b/src/deltix/custom/statestreet/fxa/load/ColumnMap.java @@ -0,0 +1,32 @@ +package deltix.custom.statestreet.fxa.load; + +import java.sql.*; +import java.util.*; + +/** + * + */ +public class ColumnMap { + private Map mMap = new HashMap (); + + public ColumnMap () { + } + + public void put (String columnName, int idx) { + mMap.put (columnName, idx); + } + + public void init (ResultSetMetaData md) throws SQLException { + for (int col = 1; col <= md.getColumnCount (); col++) + put (md.getColumnName (col), col); + } + + public int getIdx (String columnName) { + Integer ret = mMap.get (columnName); + + if (ret == null) + throw new RuntimeException ("Column " + columnName + " was not found."); + + return (ret); + } +} diff --git a/src/deltix/custom/statestreet/fxa/load/DataTransformer.java b/src/deltix/custom/statestreet/fxa/load/DataTransformer.java new file mode 100644 index 00000000..3c540f2b --- /dev/null +++ b/src/deltix/custom/statestreet/fxa/load/DataTransformer.java @@ -0,0 +1,261 @@ +package deltix.custom.statestreet.fxa.load; + +import deltix.custom.statestreet.fxa.utils.JDBCUtils; +import java.sql.*; + +/** + * + */ +public class DataTransformer { + private Connection mOutputConnection; + private FieldTrf [] mFieldTrfs; + private String mTableName; + private boolean mMerge; + private int mNumOutColumns; + private Object [][] mBuffer; + private int mBufferCount; + private PreparedStatement mStatement; + private int mNumProcessed; + + public static FieldTrf [] buildDirectMapping (ResultSetMetaData md) + throws SQLException + { + int columnCount = md.getColumnCount (); + FieldTrf [] ret = new FieldTrf [columnCount]; + + for (int col = 0; col < columnCount; col++) + ret [col] = new IdentityFieldTrf (md.getColumnName (col + 1)); + + return (ret); + } + + public DataTransformer ( + Connection outConn, + FieldTrf [] fieldTrfs, + String outTableName, + int batchSize, + boolean merge + ) + throws SQLException + { + mOutputConnection = outConn; + mFieldTrfs = fieldTrfs; + mTableName = outTableName; + mMerge = merge; + + mNumOutColumns = 0; + + for (FieldTrf field : mFieldTrfs) + mNumOutColumns += field.getNumOutColumns (); + + mBuffer = new Object [batchSize][mNumOutColumns]; + mBufferCount = 0; + + StringBuffer sql = new StringBuffer (); + int numFields = mFieldTrfs.length; + + if (mMerge) { + sql.append ("MERGE INTO \""); + sql.append (mTableName); + sql.append ("\" USING (SELECT "); + + int numValues = 0; + int pkStart = -1; + FieldTrf pk = null; + + for (int fieldIdx = 0; fieldIdx < numFields; fieldIdx++) { + FieldTrf field = mFieldTrfs [fieldIdx]; + + if (fieldIdx == numFields - 1) { + pkStart = numValues; + pk = field; + } + + int numCols = field.getNumOutColumns (); + + for (int ii = 0; ii < numCols; ii++) { + String outName = field.getOutColumnName (ii); + String expr = field.getOutExpression (ii); + + if (numValues > 0) + sql.append (","); + + sql.append (expr); + sql.append (" \"__"); + sql.append (numValues); + sql.append ("\""); + + numValues++; + } + } + + sql.append (" FROM DUAL) ON ("); + + for (int ii = pkStart; ii < numValues; ii++) { + if (ii > pkStart) + sql.append (" AND "); + + sql.append ("\"__"); + sql.append (ii); + sql.append ("\"=\""); + sql.append (pk.getOutColumnName (ii - pkStart)); + sql.append ("\""); + } + + sql.append (") WHEN MATCHED THEN UPDATE SET "); + + numValues = 0; + + for (int fieldIdx = 0; fieldIdx < numFields - 1; fieldIdx++) { + FieldTrf field = mFieldTrfs [fieldIdx]; + int numCols = field.getNumOutColumns (); + + for (int ii = 0; ii < numCols; ii++) { + if (numValues > 0) + sql.append (","); + + sql.append ("\""); + sql.append (field.getOutColumnName (ii)); + sql.append ("\"=\"__"); + sql.append (numValues); + sql.append ("\""); + + numValues++; + } + } + + sql.append (" WHEN NOT MATCHED THEN INSERT ("); + + numValues = 0; + + for (int fieldIdx = 0; fieldIdx < numFields; fieldIdx++) { + FieldTrf field = mFieldTrfs [fieldIdx]; + int numCols = field.getNumOutColumns (); + + for (int ii = 0; ii < numCols; ii++) { + if (numValues > 0) + sql.append (","); + + sql.append ("\""); + sql.append (field.getOutColumnName (ii)); + sql.append ("\""); + + numValues++; + } + } + + sql.append (") VALUES ("); + + for (int ii = 0; ii < numValues; ii++) { + if (ii > 0) + sql.append (","); + + sql.append ("\"__"); + sql.append (ii); + sql.append ("\""); + } + + sql.append (")"); + } + else { + sql.append ("INSERT INTO \""); + sql.append (mTableName); + sql.append ("\" ("); + + int numValues = 0; + + for (int fieldIdx = 0; fieldIdx < numFields; fieldIdx++) { + FieldTrf field = mFieldTrfs [fieldIdx]; + int numCols = field.getNumOutColumns (); + + for (int ii = 0; ii < numCols; ii++) { + if (numValues > 0) + sql.append (","); + + sql.append ("\""); + sql.append (field.getOutColumnName (ii)); + sql.append ("\""); + + numValues++; + } + } + + sql.append (") VALUES ("); + + numValues = 0; + + for (int fieldIdx = 0; fieldIdx < numFields; fieldIdx++) { + FieldTrf field = mFieldTrfs [fieldIdx]; + int numCols = field.getNumOutColumns (); + + for (int ii = 0; ii < numCols; ii++) { + if (numValues > 0) + sql.append (","); + + sql.append (field.getOutExpression (ii)); + + numValues++; + } + } + + sql.append (")"); + } + + mStatement = mOutputConnection.prepareStatement (sql.toString ()); + } + + private void flush () + throws SQLException + { + int numInBatch = 0; + + for (int ii = 0; ii < mBufferCount; ii++) { + Object [] recBuffer = mBuffer [ii]; + + for (int jj = 0; jj < recBuffer.length; jj++) + mStatement.setObject (jj + 1, recBuffer [jj]); + + mNumProcessed++; + numInBatch++; + mStatement.addBatch (); + } + + if (numInBatch > 0) + mStatement.executeBatch (); + + mBufferCount = 0; + + System.out.print (" " + mNumProcessed + " processed \r"); + } + + public void transformAll (ResultSet in) + throws SQLException + { + ColumnMap inMap = new ColumnMap (); + + inMap.init (in.getMetaData ()); + + for (FieldTrf field : mFieldTrfs) + field.init (inMap); + + while (in.next ()) { + if (mBufferCount == mBuffer.length) + flush (); + + Object [] recBuffer = mBuffer [mBufferCount]; + int offset = 0; + + for (FieldTrf ft : mFieldTrfs) { + ft.transform (in, recBuffer, offset); + offset += ft.getNumOutColumns (); + } + + mBufferCount++; + } + + if (mBufferCount != 0) + flush (); + + System.out.println (); + } +} diff --git a/src/deltix/custom/statestreet/fxa/load/FieldTrf.java b/src/deltix/custom/statestreet/fxa/load/FieldTrf.java new file mode 100644 index 00000000..1a61147a --- /dev/null +++ b/src/deltix/custom/statestreet/fxa/load/FieldTrf.java @@ -0,0 +1,27 @@ +package deltix.custom.statestreet.fxa.load; + +import java.sql.*; + +/** + * + */ +public abstract class FieldTrf { + public abstract int getNumOutColumns (); + + public abstract String getOutColumnName (int idx); + + public String getOutExpression (int idx) { + return ("?"); + } + + public abstract void init ( + ColumnMap inMap + ); + + public abstract void transform ( + ResultSet in, + Object [] out, + int offset + ) + throws SQLException; +} diff --git a/src/deltix/custom/statestreet/fxa/load/IdentityFieldTrf.java b/src/deltix/custom/statestreet/fxa/load/IdentityFieldTrf.java new file mode 100644 index 00000000..600d4e61 --- /dev/null +++ b/src/deltix/custom/statestreet/fxa/load/IdentityFieldTrf.java @@ -0,0 +1,20 @@ +package deltix.custom.statestreet.fxa.load; + +import java.sql.*; + +/** + * + */ +public class IdentityFieldTrf extends OneToOneFieldTrf { + public IdentityFieldTrf (String name) { + this (name, name); + } + + public IdentityFieldTrf (String inName, String outName) { + super (inName, outName); + } + + protected Object transform (Object in) { + return (in); + } +} diff --git a/src/deltix/custom/statestreet/fxa/load/MDDump.java b/src/deltix/custom/statestreet/fxa/load/MDDump.java new file mode 100644 index 00000000..ace4e91d --- /dev/null +++ b/src/deltix/custom/statestreet/fxa/load/MDDump.java @@ -0,0 +1,43 @@ +package deltix.custom.statestreet.fxa.load; + +import java.io.*; +import java.sql.*; + +import deltix.custom.statestreet.fxa.utils.*; + +/** + * Usage: java deltix.custom.statestreet.fxa.load.MDDump <mdb file> <table name> + */ +public class MDDump { + public static void main (String [] args) throws Exception { + File mdb = new File (args [0]); + String tname = args [1]; + Connection conn = AccessConnectionFactory.open (mdb); + Statement stmt = conn.createStatement (); + ResultSet rs = stmt.executeQuery ("select * from [" + tname + "]"); + ResultSetMetaData md = rs.getMetaData (); + + for (int col = 1; col <= md.getColumnCount (); col++) { + String jt = md.getColumnTypeName (col); + String cname = md.getColumnName (col); + + System.out.print ("\""); + System.out.print (cname); + System.out.print ("\""); + + for (int ii = cname.length (); ii < 46; ii++) + System.out.print (" "); + + if (jt.equals ("REAL")) + System.out.print ("FLOAT"); + else if (jt.equals ("DATETIME")) + System.out.print ("TIMESTAMP(0)"); + else + System.out.print ("VARCHAR2(255)"); + + System.out.println (","); + } + + conn.close (); + } +} diff --git a/src/deltix/custom/statestreet/fxa/load/OneToOneFieldTrf.java b/src/deltix/custom/statestreet/fxa/load/OneToOneFieldTrf.java new file mode 100644 index 00000000..de4cf7f6 --- /dev/null +++ b/src/deltix/custom/statestreet/fxa/load/OneToOneFieldTrf.java @@ -0,0 +1,48 @@ +package deltix.custom.statestreet.fxa.load; + +import java.sql.*; + +/** + * + */ +public abstract class OneToOneFieldTrf extends ZeroOrMoreToOneFieldTrf { + private final String mInName; + private int mInIndex = -1; + + public OneToOneFieldTrf (String name) { + super (name); + mInName = name; + } + + public OneToOneFieldTrf (String inName, String outName) { + super (outName); + mInName = inName; + } + + public void init ( + ColumnMap inMap + ) + { + mInIndex = inMap.getIdx (mInName); + } + + public String getInColumnName () { + return (mInName); + } + + protected Object getInObject (ResultSet in) + throws SQLException + { + return (in.getObject (mInIndex)); + } + + protected abstract Object transform (Object in); + + public final Object transform ( + ResultSet in + ) + throws SQLException + { + return (transform (getInObject (in))); + } +} diff --git a/src/deltix/custom/statestreet/fxa/load/StringFieldTrf.java b/src/deltix/custom/statestreet/fxa/load/StringFieldTrf.java new file mode 100644 index 00000000..633ed8dd --- /dev/null +++ b/src/deltix/custom/statestreet/fxa/load/StringFieldTrf.java @@ -0,0 +1,20 @@ +package deltix.custom.statestreet.fxa.load; + +/** + * + */ +public abstract class StringFieldTrf extends OneToOneFieldTrf { + public StringFieldTrf (String name) { + super (name); + } + + public StringFieldTrf (String inName, String outName) { + super (inName, outName); + } + + protected abstract String transform (String in); + + protected final Object transform (Object in) { + return (transform ((String) in)); + } +} diff --git a/src/deltix/custom/statestreet/fxa/load/SubStringFieldTrf.java b/src/deltix/custom/statestreet/fxa/load/SubStringFieldTrf.java new file mode 100644 index 00000000..a19bc257 --- /dev/null +++ b/src/deltix/custom/statestreet/fxa/load/SubStringFieldTrf.java @@ -0,0 +1,28 @@ +package deltix.custom.statestreet.fxa.load; + +/** + * + */ +public class SubStringFieldTrf extends StringFieldTrf { + private int mStartIdx; + private int mEndIdx; + + public SubStringFieldTrf (String name, int startIdx, int endIdx) { + super (name); + mStartIdx = startIdx; + mEndIdx = endIdx; + } + + public SubStringFieldTrf (String inName, String outName, int startIdx, int endIdx) { + super (inName, outName); + mStartIdx = startIdx; + mEndIdx = endIdx; + } + + protected String transform (String in) { + if (mEndIdx < 0) + return (in.substring (mStartIdx)); + else + return (in.substring (mStartIdx, mEndIdx)); + } +} diff --git a/src/deltix/custom/statestreet/fxa/load/UpperCaseStringFieldTrf.java b/src/deltix/custom/statestreet/fxa/load/UpperCaseStringFieldTrf.java new file mode 100644 index 00000000..abdba8d6 --- /dev/null +++ b/src/deltix/custom/statestreet/fxa/load/UpperCaseStringFieldTrf.java @@ -0,0 +1,18 @@ +package deltix.custom.statestreet.fxa.load; + +/** + * + */ +public class UpperCaseStringFieldTrf extends StringFieldTrf { + public UpperCaseStringFieldTrf (String name) { + super (name); + } + + public UpperCaseStringFieldTrf (String inName, String outName) { + super (inName, outName); + } + + protected String transform (String in) { + return (in.toUpperCase ()); + } +} diff --git a/src/deltix/custom/statestreet/fxa/load/ZeroOrMoreToOneFieldTrf.java b/src/deltix/custom/statestreet/fxa/load/ZeroOrMoreToOneFieldTrf.java new file mode 100644 index 00000000..56d59ba2 --- /dev/null +++ b/src/deltix/custom/statestreet/fxa/load/ZeroOrMoreToOneFieldTrf.java @@ -0,0 +1,35 @@ +package deltix.custom.statestreet.fxa.load; + +import java.sql.*; + +/** + * + */ +public abstract class ZeroOrMoreToOneFieldTrf extends FieldTrf { + private final String mOutName; + + public ZeroOrMoreToOneFieldTrf (String outName) { + mOutName = outName; + } + + public int getNumOutColumns () { + return (1); + } + + public String getOutColumnName (int idx) { + return (mOutName); + } + + protected abstract Object transform (ResultSet in) + throws SQLException; + + public final void transform ( + ResultSet in, + Object [] out, + int offset + ) + throws SQLException + { + out [offset] = transform (in); + } +} diff --git a/src/deltix/custom/statestreet/fxa/utils/AccessConnectionFactory.java b/src/deltix/custom/statestreet/fxa/utils/AccessConnectionFactory.java new file mode 100644 index 00000000..b6be06ae --- /dev/null +++ b/src/deltix/custom/statestreet/fxa/utils/AccessConnectionFactory.java @@ -0,0 +1,28 @@ +package deltix.custom.statestreet.fxa.utils; + +import java.sql.*; +import java.io.*; +import java.util.logging.*; + +/** + * + */ +public class AccessConnectionFactory { + static { + try { + Class.forName ("sun.jdbc.odbc.JdbcOdbcDriver"); + } catch (Throwable x) { + Common.LOGGER.log (Level.SEVERE, "Failed to load the ODBC/JDBC driver", x); + System.exit (1); + } + } + + public static Connection open (File f) throws SQLException { + return ( + DriverManager.getConnection ( + "jdbc:odbc:Driver={Microsoft Access Driver (*.mdb)};DBQ=" + f.getPath () + + ";READONLY=true}" + ) + ); + } +} From eea4e81298a3a72d300c4fe4960af5984a3ad1e9 Mon Sep 17 00:00:00 2001 From: gene Date: Tue, 17 Oct 2006 18:30:12 +0000 Subject: [PATCH 0003/2572] Checked in framework sources --- src/deltix/tsdb/io/pub/AbstractDataStore.java | 41 + src/deltix/util/Util.java | 873 ++++++++++++++++++ src/deltix/util/awt/Arrows.java | 115 +++ src/deltix/util/awt/AwtUtil.java | 22 + .../util/collections/ArrayEnumeration.java | 33 + src/deltix/util/collections/QuickList.java | 444 +++++++++ src/deltix/util/io/IOUtil.java | 840 +++++++++++++++++ src/deltix/util/io/InputStreamSink.java | 48 + src/deltix/util/io/ProcessHelper.java | 136 +++ src/deltix/util/io/StreamPump.java | 122 +++ src/deltix/util/io/Timeout.java | 72 ++ src/deltix/util/jdbc/JDBCUtils.java | 95 ++ src/deltix/util/jdbc/TableOp.java | 10 + .../util/lang/LocalizableException.java | 131 +++ src/deltix/util/memory/DataExchangeUtils.java | 108 +++ src/deltix/util/memory/EstimatorUtils.java | 76 ++ .../util/memory/MemorySizeEstimator.java | 20 + src/deltix/util/progress/Estimator.java | 94 ++ .../util/progress/ProgressIndicator.java | 13 + src/deltix/util/swing/AbstractApp.java | 64 ++ src/deltix/util/swing/Arrow.java | 204 ++++ src/deltix/util/swing/FileField.java | 181 ++++ src/deltix/util/swing/FormTextField.java | 48 + src/deltix/util/swing/IntegerTextField.java | 91 ++ src/deltix/util/swing/Line.java | 86 ++ src/deltix/util/swing/NonEmptyTextField.java | 85 ++ src/deltix/util/swing/ParsingException.java | 21 + src/deltix/util/swing/ParsingTextField.java | 47 + src/deltix/util/swing/SimpleAction.java | 113 +++ src/deltix/util/swing/StandardAction.java | 89 ++ src/deltix/util/swing/StandardDialog.java | 61 ++ src/deltix/util/swing/SwingUtil.java | 168 ++++ src/deltix/util/swing/VerticalForm.java | 145 +++ .../util/swing/treeedit/NodeAdapter.java | 174 ++++ .../swing/treeedit/NodeChangeListener.java | 8 + .../util/swing/treeedit/NodeRenderer.java | 44 + src/deltix/util/swing/treeedit/Test.java | 113 +++ .../util/swing/treeedit/TreeEditorNode.java | 262 ++++++ .../util/swing/treeedit/TreeEditorPanel.java | 264 ++++++ .../util/swing/treeedit/actions.properties | 8 + src/deltix/util/time/AbsoluteDate.java | 138 +++ src/deltix/util/time/DurationFormat.java | 37 + 42 files changed, 5744 insertions(+) create mode 100644 src/deltix/tsdb/io/pub/AbstractDataStore.java create mode 100644 src/deltix/util/Util.java create mode 100644 src/deltix/util/awt/Arrows.java create mode 100644 src/deltix/util/awt/AwtUtil.java create mode 100644 src/deltix/util/collections/ArrayEnumeration.java create mode 100644 src/deltix/util/collections/QuickList.java create mode 100644 src/deltix/util/io/IOUtil.java create mode 100644 src/deltix/util/io/InputStreamSink.java create mode 100644 src/deltix/util/io/ProcessHelper.java create mode 100644 src/deltix/util/io/StreamPump.java create mode 100644 src/deltix/util/io/Timeout.java create mode 100644 src/deltix/util/jdbc/JDBCUtils.java create mode 100644 src/deltix/util/jdbc/TableOp.java create mode 100644 src/deltix/util/lang/LocalizableException.java create mode 100644 src/deltix/util/memory/DataExchangeUtils.java create mode 100644 src/deltix/util/memory/EstimatorUtils.java create mode 100644 src/deltix/util/memory/MemorySizeEstimator.java create mode 100644 src/deltix/util/progress/Estimator.java create mode 100644 src/deltix/util/progress/ProgressIndicator.java create mode 100644 src/deltix/util/swing/AbstractApp.java create mode 100644 src/deltix/util/swing/Arrow.java create mode 100644 src/deltix/util/swing/FileField.java create mode 100644 src/deltix/util/swing/FormTextField.java create mode 100644 src/deltix/util/swing/IntegerTextField.java create mode 100644 src/deltix/util/swing/Line.java create mode 100644 src/deltix/util/swing/NonEmptyTextField.java create mode 100644 src/deltix/util/swing/ParsingException.java create mode 100644 src/deltix/util/swing/ParsingTextField.java create mode 100644 src/deltix/util/swing/SimpleAction.java create mode 100644 src/deltix/util/swing/StandardAction.java create mode 100644 src/deltix/util/swing/StandardDialog.java create mode 100644 src/deltix/util/swing/SwingUtil.java create mode 100644 src/deltix/util/swing/VerticalForm.java create mode 100644 src/deltix/util/swing/treeedit/NodeAdapter.java create mode 100644 src/deltix/util/swing/treeedit/NodeChangeListener.java create mode 100644 src/deltix/util/swing/treeedit/NodeRenderer.java create mode 100644 src/deltix/util/swing/treeedit/Test.java create mode 100644 src/deltix/util/swing/treeedit/TreeEditorNode.java create mode 100644 src/deltix/util/swing/treeedit/TreeEditorPanel.java create mode 100644 src/deltix/util/swing/treeedit/actions.properties create mode 100644 src/deltix/util/time/AbsoluteDate.java create mode 100644 src/deltix/util/time/DurationFormat.java diff --git a/src/deltix/tsdb/io/pub/AbstractDataStore.java b/src/deltix/tsdb/io/pub/AbstractDataStore.java new file mode 100644 index 00000000..d9ef12c8 --- /dev/null +++ b/src/deltix/tsdb/io/pub/AbstractDataStore.java @@ -0,0 +1,41 @@ +package deltix.tsdb.io.pub; + +import java.io.*; + +/** + * A persistent object used to store structured data of some sort. + */ +public interface AbstractDataStore { + /** + * Create a new object on disk and format internally. The data store is + * left open for read-write at the end of this method. + */ + public void format () throws IOException; + + /** + * Close the store and delete all underlying files from disk. + */ + public void delete () throws IOException; + + /** + * Determines whether the store is open. + */ + public boolean isOpen (); + + /** + * Open the data store. + */ + public void open (boolean readOnly) throws IOException; + + /** + * Flush all data to disk. The disk data store is guaranteed to be consistent + * at the end of this method, if it succesfully completes. + */ + public void flush () throws IOException; + + /** + * Close the data store and release all resources, such as caches and + * file descriptors. + */ + public void close () throws IOException; +} diff --git a/src/deltix/util/Util.java b/src/deltix/util/Util.java new file mode 100644 index 00000000..fa77998a --- /dev/null +++ b/src/deltix/util/Util.java @@ -0,0 +1,873 @@ +package deltix.util; + +import deltix.util.memory.DataExchangeUtils; +import java.io.*; +import java.net.*; +import java.security.*; +import java.sql.*; +import java.util.*; +import java.util.logging.*; +import java.rmi.RemoteException; +import org.xml.sax.SAXException; +import java.lang.reflect.*; +import java.lang.reflect.Array; + +/** Set of usefull methods */ +public class Util { + public static final Logger LOGGER = Logger.getLogger ("deltix.util"); + + public static void writeNullableString (String s, ObjectOutput os) + throws IOException + { + os.writeBoolean (s == null); + + if (s != null) + os.writeUTF (s); + } + + public static String readNullableString (ObjectInput is) + throws IOException + { + if (is.readBoolean ()) + return (null); + + return (is.readUTF ()); + } + + /** + * Call a static method of the specified class. Figure out the method + * signature from the types of the supplied arguments (which must not contain + * null elements). + */ + public static Object callStaticMethod ( + String className, + String methodName, + Object [] args + ) + throws + ClassNotFoundException, + NoSuchMethodException, + InvocationTargetException, + IllegalAccessException + { + Class c = Class.forName (className); + Class [] paramTypes = new Class [args.length]; + for (int ii = 0; ii < args.length; ii++) + paramTypes [ii] = args [ii].getClass (); + + Method m = c.getMethod (methodName, paramTypes); + return (m.invoke (null, args)); + } + + /** + * Call a method of the specified class. Figure out the method + * signature from the types of the supplied arguments (which must not contain + * null elements). + */ + public static Object callNonStaticMethod ( + Object object, + String methodName, + Object [] args + ) + throws + ClassNotFoundException, + NoSuchMethodException, + InvocationTargetException, + IllegalAccessException + { + Class [] paramTypes = new Class [args.length]; + for (int ii = 0; ii < args.length; ii++) + paramTypes [ii] = args [ii].getClass (); + + Method m = object.getClass ().getMethod (methodName, paramTypes); + return (m.invoke (object, args)); + } + + /** + * Gets to the bottom of the exception. + */ + public static Throwable unwrap (Throwable ex) { + + Throwable result = ex; + while (result != null) { + Throwable nested; + + if (result instanceof SAXException) + nested = ((SAXException) result).getException (); + else if (result instanceof RemoteException) + nested = ((RemoteException) result).detail; + else if (result instanceof InvocationTargetException) + nested = ((InvocationTargetException) result).getTargetException (); + else + nested = result.getCause(); + + if (nested == null) + break; + + result = nested; + } + + return result; + } + + /** + * Same as System.getProperty (prop, def), but returns + * null if access to system properties is prohibited. + */ + public static String getSysProp (String prop, String def) { + try { + return (System.getProperty (prop, def)); + } catch (java.security.AccessControlException acx) { + return (null); + } + } + + /** + * Same as System.getProperty (prop), but returns + * null if access to system properties is prohibited. + */ + public static String getSysProp (String prop) { + try { + return (System.getProperty (prop)); + } catch (java.security.AccessControlException acx) { + return (null); + } + } + + public static URL getResource (String path) + throws MalformedURLException + { + if (path.indexOf (":") > 0) + return (new URL (path)); + else + return (Util.class.getClassLoader ().getResource (path)); + } + + public static URL getResourceNoX (String path) { + try { + return (getResource (path)); + } catch (MalformedURLException mux) { + LOGGER.log (Level.SEVERE, "Error getting resource '" + path + "'", mux); + return (null); + } + } + + public static void handleException (Exception x) { + LOGGER.log (Level.SEVERE, "Ignoring (but Logging) Exception ...", x); + } + + /** + * Closes a RandomAccessFile without throwing an exception. Checks for null. + */ + public static void close (RandomAccessFile wr) { + if (wr != null) + try { + wr.close (); + } catch (Exception x) { + handleException (x); + } + } + + /** + * Closes a Writer without throwing an exception. Checks for null. + */ + public static void delete (Writer wr) { + if (wr != null) + try { + wr.close (); + } catch (Exception x) { + handleException (x); + } + } + + /** + * Deletes a File. If fails, logs an error message. + */ + public static void delete (File f) { + if (f != null && !f.delete ()) + LOGGER.log ( + Level.SEVERE, + "Failed to delete file " + f + ); + } + + /** + * Closes a Writer without throwing an exception. Checks for null. + */ + public static void close (Writer wr) { + if (wr != null) + try { + wr.close (); + } catch (Exception x) { + handleException (x); + } + } + + /** + * Closes a Zip File without throwing an exception. Checks for null. + */ + public static void close (java.util.zip.ZipFile z) { + if (z != null) + try { + z.close (); + } catch (Exception x) { + handleException (x); + } + } + + + /** + * Closes a Reader without throwing an exception. Checks for null. + */ + public static void close (Reader rd) { + if (rd != null) + try { + rd.close (); + } catch (Exception x) { + handleException (x); + } + } + + /** + * Closes an InputStream without throwing an exception. Checks for null. + */ + public static void close (InputStream is) { + if (is != null) + try { + is.close (); + } catch (Exception x) { + handleException (x); + } + } + + /** + * Closes an OutputStream without throwing an exception. Checks for null. + */ + public static void close (OutputStream os) { + if (os != null) + try { + os.close (); + } catch (Exception x) { + handleException (x); + } + } + + /** + * Closes a Socket without throwing an exception. Checks for null. + */ + public static void close (Socket s) { + if (s != null) + try { + s.close (); + } catch (Exception x) { + handleException (x); + } + } + + /** + * Closes a ServerSocket without throwing an exception. Checks for null. + */ + public static void close (ServerSocket s) { + if (s != null) + try { + s.close (); + } catch (Exception x) { + handleException (x); + } + } + + /** + * Closes a JDBC Connection without throwing an exception. + * Checks for null. + */ + public static void close (java.sql.Connection conn) { + if (conn != null) + try { + conn.close (); + } catch (Exception x) { + handleException (x); + } + } + + /** + * Rolls back any changes made in connection without throwing an exception. + * Checks for null. + */ + public static void rollback (java.sql.Connection conn) { + if (conn != null) + try { + conn.rollback (); + } catch (Exception x) { + handleException (x); + } + } + + + /** + * Closes a Statement without throwing an exception. Checks for null. + */ + public static void close (Statement stmt) { + if (stmt != null) + try { + stmt.close (); + } catch (Exception x) { + handleException (x); + } + } + + /** + * Closes a ResultSet without throwing an exception. Checks for null. + */ + public static void close (ResultSet rs) { + if (rs != null) + try { + rs.close (); + } catch (Exception x) { + handleException (x); + } + } + + /** + * Returns the difference between the specified segments of + * arr1 and arr2, MSBF. + */ + public static int arraycomp ( + byte [] arr1, + int off1, + byte [] arr2, + int off2, + int len + ) + { + int diff = 0; + + for (int ii = 0; ii < len && diff == 0; ii++) + diff = arr1 [off1 + ii] - arr2 [off2 + ii]; + + return (diff); + } + + /** + * Returns the difference between the specified segments of + * arr1 and arr2, MSBF, comparing bytes' unsigned values. + */ + public static int arrayucomp ( + byte [] arr1, + int off1, + byte [] arr2, + int off2, + int len + ) + { + for (int ii = 0; ii < len; ii++) { + int b1 = ((int) arr1 [off1 + ii]) & 0xFF; + int b2 = ((int) arr2 [off2 + ii]) & 0xFF; + + int diff = b1 - b2; + + if (diff != 0) + return (diff); + } + + return (0); + } + + public static void arraydump ( + PrintStream ps, + byte [] bytes, + int offset, + int n + ) + { + for (int jj = 0; jj < n; jj++) { + if (jj > 0) + ps.print ("."); + + ps.print (bytes [offset + jj] & 0xFF); + } + } + + public static void arraydump ( + StringBuffer sb, + byte [] bytes, + int offset, + int n + ) + { + for (int jj = 0; jj < n; jj++) { + if (jj > 0) + sb.append ("."); + + sb.append (bytes [offset + jj] & 0xFF); + } + } + + public static String arraydump ( + byte [] bytes, + int offset, + int n + ) + { + StringBuffer sb = new StringBuffer (); + arraydump (sb, bytes, offset, n); + return (sb.toString ()); + } + + /** + * returns obj == null ? 1 : obj.hashCode () + */ + public static int xhashCode (Object obj) { + return (obj == null ? 1 : obj.hashCode ()); + } + + /** + * Adds up hash codes of all array elements, plus array length. + */ + public static int arrayHashCode (Object [] arr) { + if (arr == null) + return (0); + + int ret = arr.length; + + for (int ii = 0; ii < arr.length; ii++) + ret += xhashCode (arr [ii]); + + return (ret); + } + + /** + * Method identical to "obj1.equals(obj2)", it also handles null values. + */ + public static boolean xequals(Object obj1, Object obj2) + { + return obj1 == obj2 || // shortcut + ((obj1 != null) ? (obj2 != null) && obj1.equals (obj2) : obj2 == null); + } + + /** + * Method identical to "obj1.compareTo(obj2)==0", it also handles null values. + */ + public static boolean xcompare(Comparable obj1, Comparable obj2) + { + return obj1 == obj2 || // shortcut + (obj1 != null ? obj1.compareTo (obj2)==0 : obj2 == null); + } + + + /** + * Identical to equals() but handles Number.equals() problem: + * + * ( new Integer (1).equals (new Long (1)) != true ) + * + * This method allows to compare different Number types by actual value. + */ + public static boolean xequals2(Object o1, Object o2) + { + if (o1 == o2) + return true; + + if (o1 == null || o2 == null) + return o1 == o2; + + if (o1 instanceof Number && o2 instanceof Number) { + Class c1 = o1.getClass (); + Class c2 = o2.getClass (); + + if (c1 == c2) + return o1.equals (o2); + + if (c1 != Double.class && c1 != Float.class && c2 != Double.class && c2 != Float.class) { + return ((Number) o1).longValue () == ((Number) o2).longValue (); + } else { + return ((Number) o1).doubleValue () == ((Number) o2).doubleValue (); + } + } else { + return o1.equals (o2); + } + } + + public static final double SMALL_NUMBER = 0.0000000000000001; + + /** + * Identical to equals() but handles Number.equals() problem: + * + * ( new Integer (1).equals (new Long (1)) != true ) + * + * This method allows to compare different Number types by actual value. + */ + public static boolean equalsEpsilon(Object o1, Object o2) + { + if (o1 == o2) { + return true; + } + + if (o1 == null || o2 == null) { + return o1 == o2; + } + + if (o1 instanceof Number && o2 instanceof Number) { + Class c1 = o1.getClass (); + Class c2 = o2.getClass (); + + if (c1 == c2) { + return o1.equals (o2); + } + + if (c1 != Double.class && c1 != Float.class && c2 != Double.class && c2 != Float.class) { + return ((Number) o1).longValue () == ((Number) o2).longValue (); + } else { + return Math.abs (((Number) o1).doubleValue () - ((Number) o2).doubleValue ()) < SMALL_NUMBER; + } + } else { + return o1.equals (o2); + } + } + + /** + * Given a Class object, attempts to find its .class location [returns null + * if no such definition can be found]. Use for testing/debugging only. + * @param cls class to lookup + * @return URL that points to the class definition [null if not found]. + * (From http://www.javaworld.com/javaqa/2003-07/01-qa-0711-classsrc_p.html) + */ + public static URL getClassLocation(final Class cls) + { + if (cls == null) + throw new IllegalArgumentException ("null input: cls"); + + URL result = null; + final String clsAsResource = cls.getName ().replace ('.', '/').concat (".class"); + + final ProtectionDomain pd = cls.getProtectionDomain (); + // java.lang.Class contract does not specify if 'pd' can ever be null; + // it is not the case for Sun's implementations, but guard against null + // just in case: + if (pd != null) { + final CodeSource cs = pd.getCodeSource (); + // 'cs' can be null depending on the classloader behavior: + if (cs != null) + result = cs.getLocation (); + + if (result != null) { + // Convert a code source location into a full class file location + // for some common cases: + if ("file".equals (result.getProtocol ())) { + try { + if (result.toExternalForm ().endsWith (".jar") || + result.toExternalForm ().endsWith (".zip")) + result = new URL ("jar:".concat (result.toExternalForm ()) + .concat ("!/").concat (clsAsResource)); + else if (new File (result.getFile ()).isDirectory ()) + result = new URL (result, clsAsResource); + } catch (MalformedURLException ignore) {} + } + } + } + + if (result == null) { + // Try to find 'cls' definition as a resource; this is not + // documented to be legal, but Sun's implementations seem to allow this: + final ClassLoader clsLoader = cls.getClassLoader (); + + result = clsLoader != null ? + clsLoader.getResource (clsAsResource) : + ClassLoader.getSystemResource (clsAsResource); + } + + return result; + } + + /** + * Return string byte length (encoded as UTF8), + * same as s.getBytes("UTF8").length but faster + */ + public static int strlenUTF8(String s) + { + int i, len = s.length (), cnt = 0; + for (i = 0; i < len; i++) { + char ch = s.charAt (i); + if (ch <= 0x7F) { + cnt += 1; + } else if (ch <= 0x7FF) { + cnt += 2; + } else if (ch <= 0x7FFF) { + cnt += 3; + } else if (ch <= 0x7FFFF) { + cnt += 4; + } else { + throw new RuntimeException ("Character is a way too big: " + Long.toHexString (ch)); + } + } + return cnt; + } + + private static long mLastUsedMemory; + private static long mLastTotalMemory; + + /** + * Prints current memory usage and memory usage delta to System.out. + */ + public static synchronized void dumpMemoryUsage(String msgText) + { + + System.gc (); + System.runFinalization (); + System.gc (); + + long freeMemory = Runtime.getRuntime ().freeMemory (); + long totalMemory = Runtime.getRuntime ().totalMemory (); + + StringBuffer msg = new StringBuffer (256); + msg.append ("(M)"); + if (msgText != null) { + msg.append (" ["); + msg.append (msgText); + msg.append (']'); + } + + msg.append (" JVM Memory: "); + msg.append (freeMemory * 100 / totalMemory); + msg.append ("% free."); + + if (mLastTotalMemory != totalMemory) { + msg.append (" (*) Total memory changed to: "); + msg.append (totalMemory); + mLastTotalMemory = totalMemory; + } + + long newUsedMemory = totalMemory - freeMemory; + + msg.append (" Used memory change: "); + msg.append (newUsedMemory - mLastUsedMemory); + msg.append (" bytes"); + + mLastUsedMemory = newUsedMemory; + + System.out.println (msg.toString ()); + } + + /** + * Return a comma separated list of elements or "null". + * @param array - array to print + */ + public static String printArray(Object[] array) + { + if (array == null) + return "null"; + + StringBuffer sb = new StringBuffer ("["); + if (array.length > 0) { + sb.append (array[0]); + for (int i = 1; i < array.length; i++) { + sb.append (", "); + sb.append (array[i]); + } + } + sb.append ("]"); + return sb.toString (); + } + + /** + * @return stack trace of given throwable as String + */ + public static String printStackTrace (Throwable t) { + StringWriter swr = new StringWriter (512); + PrintWriter pwr = new PrintWriter (swr); + t.printStackTrace(pwr); + pwr.close(); + return swr.toString(); + } + + /** @return Array of all interfaces implemented by given class (calls cls.getInterfaces() recursively), never null */ + public static Class [] getClassInterfaces (Class cls) { + List result = new ArrayList (); + + if (cls.isInterface()) + result.add (cls); + + + Class c = cls; + while (c != null) { + Class [] interfaces = c.getInterfaces(); + for (int i = 0; i < interfaces.length; i++) { + Class cc = interfaces [i]; + if ( ! result.contains(cc)) // joined multi inheritance + result.add(cc); + } + c = c.getSuperclass(); + } + return (Class []) result.toArray(new Class [result.size()]); + } + + /** @return true if given cls is instanceof interface specified by className */ + public static boolean isntanceOf (Class cls, String className) { + + Class c = cls; + while (c != null) { + if (className.equals(c.getName())) + return true; + + Class [] interfaces = c.getInterfaces(); + for (int i = 0; i < interfaces.length; i++) { + if (className.equals(interfaces [i].getName())) + return true; + } + c = c.getSuperclass(); + } + return false; + } + + + /** + * @param propName System property name + * @param defaultValue default value + * @param minValue minimum value (inclusive) or Long.MIN_VALUE + * @param maxValue maximum value (inclusive) or Long.MAX_VALUE + * @return long property value + */ + public static long getLongSystemProperty (String propName, long defaultValue, long minValue, long maxValue) { + long result = + Long.parseLong(System.getProperty (propName, String.valueOf (defaultValue))); + + if (result < minValue) { + System.err.println("Property \"" + propName + "\" cannot be less than " + minValue); + result = minValue; + } + if (result > maxValue) { + System.err.println("Property \"" + propName + "\" cannot be more than " + maxValue); + result = maxValue; + } + return result; + } + + public static int getIntSystemProperty (String propName, int defaultValue, int minValue, int maxValue) { + return (int) getLongSystemProperty(propName, defaultValue, minValue, maxValue); + } + + + /** + * @param propName System property name + * @param defaultValue default value + * @param minValue minimum value (inclusive) or Double.MIN_VALUE + * @param maxValue maximum value (inclusive) or Double.MAX_VALUE + * @return double property value + */ + public static double getDoubleSystemProperty (String propName, double defaultValue, double minValue, double maxValue) { + double result = + Double.parseDouble(System.getProperty (propName, String.valueOf (defaultValue))); + + if (result < minValue) { + System.err.println("Property \"" + propName + "\" cannot be less than " + minValue); + result = minValue; + } + if (result > maxValue) { + System.err.println("Property \"" + propName + "\" cannot be more than " + maxValue); + result = maxValue; + } + return result; + } + + /** + * Return the length of the specified array, or 0 if the array is null. + */ + public static int arraylen (Object [] array) { + return (array == null ? 0 : array.length); + } + + /** + * Append the element to the specified array, returning a new array of the same + * type. If the array is null, and the element is not, construct an array of + * components whose type is that of the element. + * + * @exception IllegalArgumentException If both arguments are null. + */ + public static Object [] arrayadd (Object [] array, Object newObject) { + return (arrayadd (array, arraylen (array), newObject)); + } + + /** + * Insert the element into the specified array, returning a new array of the same + * type. If the array is null, and the element is not, construct an array of + * components whose type is that of the element. + * + * @exception IllegalArgumentException + * If both arguments are null. + * @exception ArrayIndexOutOfBoundsException + * If atIdx is greater than array length. + */ + public static Object [] arrayadd (Object [] array, int atIdx, Object newObject) { + if (array == null && newObject == null) + throw new IllegalArgumentException ("array == null && newObject == null"); + + int oldDim = arraylen (array); + + if (atIdx < 0 || atIdx > oldDim) + throw new ArrayIndexOutOfBoundsException (atIdx); + + Class compType = + array == null ? + newObject.getClass () : + array.getClass ().getComponentType (); + + Object [] ret = (Object []) Array.newInstance (compType, oldDim + 1); + + if (array != null) { + System.arraycopy (array, 0, ret, 0, atIdx); + System.arraycopy (array, atIdx, ret, atIdx + 1, oldDim - atIdx); + } + + ret [atIdx] = newObject; + + return (ret); + } + + /** + * Remove an element from the specified array, returning a new array of the same + * type. + * + * @exception ArrayIndexOutOfBoundsException + * If atIdx is out of bounds. + */ + public static Object [] arraydel (Object [] array, int atIdx) { + int oldDim = array.length; + + if (atIdx < 0 || atIdx >= oldDim) + throw new ArrayIndexOutOfBoundsException (atIdx); + + Class compType = array.getClass ().getComponentType (); + Object [] ret = (Object []) Array.newInstance (compType, oldDim - 1); + int shiftIdx = atIdx + 1; + + System.arraycopy (array, 0, ret, 0, atIdx); + System.arraycopy (array, shiftIdx, ret, atIdx, oldDim - shiftIdx); + + return (ret); + } + + /** + * Find an element in the specified array that equals to the specified element + * and remove it. If element is not found, return array. + */ + public static Object [] arraydel (Object [] array, Object elem) { + int idx = indexOf (array, elem); + + if (idx < 0) + return (array); + + return (arraydel (array, idx)); + } + + /** + * Find an element in the specified array that equals to the specified element + * and return its index, or -1 if not found. + */ + public static int indexOf (Object [] array, Object elem) { + int len = arraylen (array); + + for (int ii = 0; ii < len; ii++) + if (xequals (array [ii], elem)) + return (ii); + + return (-1); + } +} diff --git a/src/deltix/util/awt/Arrows.java b/src/deltix/util/awt/Arrows.java new file mode 100644 index 00000000..852fbcc9 --- /dev/null +++ b/src/deltix/util/awt/Arrows.java @@ -0,0 +1,115 @@ +package deltix.util.awt; + +import java.awt.*; + +public class Arrows { + public static final int STYLE_OPEN = 1; + public static final int STYLE_CLOSED = 2; + public static final int STYLE_FILLED = 3; + + public static final int POSITION_MIDDLE = 1; + public static final int POSITION_END = 2; + + /** + * Draws a line between (x0, y0) and (x1, y1), with a directional arrow + * in the middle. The arrowhead is 2*a pixels long and 2*b pixels wide, + * total. + * + */ + public static void drawArrow (Graphics g, int x0, int y0, int x1, int y1, int a, int b) { + drawArrow (g, x0, y0, x1, y1, a, b, POSITION_MIDDLE, STYLE_OPEN); + } + + /** + * Draws a line between (x0, y0) and (x1, y1), with a directional arrow + * in the middle. The arrowhead is 2*a pixels long and 2*b pixels wide, + * total. + * + */ + public static void drawArrow ( + Graphics g, + int x0, + int y0, + int x1, + int y1, + int a, + int b, + int pos, + int style + ) + { + int [] xs = new int [3]; + int [] ys = new int [3]; + + getArrowHead (x0, y0, x1, y1, a, b, pos, xs, ys); + + g.drawLine (x0, y0, x1, y1); + + if (style == STYLE_FILLED) + g.fillPolygon (xs, ys, 3); + else { + g.drawLine (xs [0], ys [0], xs [1], ys [1]); + g.drawLine (xs [1], ys [1], xs [2], ys [2]); + + if (style == STYLE_CLOSED) + g.drawLine (xs [0], ys [0], xs [2], ys [2]); + } + } + + /** + * Returns arrowhead coordinates. The arrowhead is 2*a pixels long and 2*b pixels wide, + * total. + * + */ + public static void getArrowHead ( + int x0, + int y0, + int x1, + int y1, + int a, + int b, + int pos, + int [] retXs, + int [] retYs + ) + { + double dx = x1 - x0; + double dy = y1 - y0; + double l = Math.sqrt (dx * dx + dy * dy); + double ka = a / l; + double dxa = ka * dx; + double dya = ka * dy; + double kb = b / l; + double dxb = kb * dx; + double dyb = kb * dy; + int px, py; + + if (pos == POSITION_MIDDLE) { + double mx = (x1 + x0) * 0.5; + double my = (y1 + y0) * 0.5; + + px = (int) (mx + dxa); + py = (int) (my + dya); + } + else if (pos == POSITION_END) { + px = x1; + py = y1; + } + else + throw new IllegalArgumentException ("pos == " + pos); + + double tx = px - dxa - dxa; + double ty = py - dya - dya; + int lx = (int) (tx + dyb); + int ly = (int) (ty - dxb); + int rx = (int) (tx - dyb); + int ry = (int) (ty + dxb); + + retXs [0] = lx; + retXs [1] = px; + retXs [2] = rx; + retYs [0] = ly; + retYs [1] = py; + retYs [2] = ry; + } +} diff --git a/src/deltix/util/awt/AwtUtil.java b/src/deltix/util/awt/AwtUtil.java new file mode 100644 index 00000000..a5268f15 --- /dev/null +++ b/src/deltix/util/awt/AwtUtil.java @@ -0,0 +1,22 @@ +package deltix.util.awt; + +import java.awt.*; + +public class AwtUtil { + + public static Point centerComponent (Rectangle rExt, Rectangle rInt) { + int x = rExt.x + (rExt.width - rInt.width)/2; + int y = rExt.y + (rExt.height - rInt.height)/2; + Dimension screenDim = Toolkit.getDefaultToolkit().getScreenSize(); + if (x > screenDim.width) + x = screenDim.width - rInt.width; + if (y > screenDim.height) + x = screenDim.height - rInt.height; + if (x < 0) + x = 0; + if (y < 0) + y = 0; + return new Point (x, y); + } + +} diff --git a/src/deltix/util/collections/ArrayEnumeration.java b/src/deltix/util/collections/ArrayEnumeration.java new file mode 100644 index 00000000..637d8c26 --- /dev/null +++ b/src/deltix/util/collections/ArrayEnumeration.java @@ -0,0 +1,33 @@ +package deltix.util.collections; + +import java.util.*; + +public class ArrayEnumeration implements Enumeration { + + private Object [] mArray; + private int mIdx; + private boolean mHasNext; + + public ArrayEnumeration (Object [] array){ + mArray = array; + mIdx = 0; + mHasNext =(array != null && array.length > 0); + } + + public boolean hasMoreElements(){ + return mHasNext; + } + + public Object nextElement(){ + + if (mHasNext){ + Object o = mArray[mIdx]; + mIdx++; + mHasNext =(mIdx < mArray.length); + return o; + } + else throw new NoSuchElementException("No Elements left in Enumeration"); + + } + +} \ No newline at end of file diff --git a/src/deltix/util/collections/QuickList.java b/src/deltix/util/collections/QuickList.java new file mode 100644 index 00000000..5b6cd85f --- /dev/null +++ b/src/deltix/util/collections/QuickList.java @@ -0,0 +1,444 @@ +package deltix.util.collections; + +import java.util.Enumeration; + +/** + * The quickest possible implementation of a bi-directional link list. + * Requires that all elements extend the static nested class Entry. + * This allows to avoid entry wrapper object creation, characteristic + * to java.util.LinkedList. Entries cannot be shared between two or more + * QuickLists. This class is not synchronized. + */ +public final class QuickList implements java.io.Serializable { + /** + * Turn this on if problems are suspected in the use of this class + */ + public static final boolean DO_ASSERTIONS = false; + + public static class BadEntryException extends RuntimeException { + public BadEntryException (Entry e) { + super ( + "Next and previous pointers of entry " + + e + " are in an incosistent state." + ); + } + } + + public static final class EntryEnumeration implements Enumeration { + private Entry mCur; + + public EntryEnumeration (Entry entry) { + mCur = entry; + } + + public boolean hasMoreElements () { + return (!(mCur instanceof BoundaryEntry)); + } + + public Object nextElement () { + Entry e = mCur; + mCur = mCur.next (); + return (e); + } + } + + public static abstract class Entry implements java.io.Serializable { + protected Entry mPrevious = null; + protected Entry mNext = null; + + /** + * Unlinks the entry from the list it is in. This operation + * is illegal on entries that have previously been unlinked from + * a list, and will cause chain corruption. Entries are + * not run-time protected against double-unlinking, + * because we are trying to make this operation as fast + * as computerly possible. + */ + public final void unlink () { + if (DO_ASSERTIONS) { + if (mNext == null || mPrevious == null) + throw new RuntimeException (this + " is not linked."); + } + + mNext.mPrevious = mPrevious; + mPrevious.mNext = mNext; + + if (DO_ASSERTIONS) + mNext = mPrevious = null; + } + + /** + * Unlinks the entry from the list it is in. + * + * @exception BadEntryException + * When the entry is in an illegal state. + * + * @return Whether the entry has just been safely unlinked, + * false if it has been safely unlinked before. + */ + public boolean safeUnlink () { + if (mPrevious == null && mNext == null) + return (false); + + if (mPrevious != null && mNext != null) { + unlink (); + mPrevious = null; + mNext = null; + return (true); + } + + throw new BadEntryException (this); + } + + /** + * Returns the next entry in the list, or null + * if this is the last one. + */ + public final Entry next () { + if (DO_ASSERTIONS) { + if (mNext == this) + throw new RuntimeException (this + ": mNext == this"); + + if (mPrevious == this) + throw new RuntimeException (this + ": mPrevious == this"); + } + + if (mNext instanceof BoundaryEntry) + return (null); + else + return (mNext); + } + + /** + * Returns the previous entry in the list, or null + * if this is the first one. + */ + public final Entry previous () { + if (DO_ASSERTIONS) { + if (mNext == this) + throw new RuntimeException (this + ": mNext == this"); + + if (mPrevious == this) + throw new RuntimeException (this + ": mPrevious == this"); + } + + if (mPrevious instanceof BoundaryEntry) + return (null); + else + return (mPrevious); + } + + /** + * Returns the next entry in the list, or the tail + * BoundaryEntry, if this is the last one. + */ + public final Entry nextOrBoundary () { + if (DO_ASSERTIONS) { + if (mNext == this) + throw new RuntimeException (this + ": mNext == this"); + + if (mPrevious == this) + throw new RuntimeException (this + ": mPrevious == this"); + } + + return (mNext); + } + + /** + * Returns the previous entry in the list, or the head + * BoundaryEntry, if this is the first one. + */ + public final Entry previousOrBoundary () { + if (DO_ASSERTIONS) { + if (mNext == this) + throw new RuntimeException (this + ": mNext == this"); + + if (mPrevious == this) + throw new RuntimeException (this + ": mPrevious == this"); + } + + return (mPrevious); + } + } + + /** + * Used to bound the entry chain. Each QuickList contains one + * BoundaryEntry in the beginning, and one BoundaryEntry in the end + * of the chain. + */ + public static class BoundaryEntry extends Entry { + public boolean safeUnlink () { + throw new IllegalArgumentException ( + "Cannot unlink a BoundaryEntry." + ); + } + } + + private BoundaryEntry mHead; + private BoundaryEntry mTail; + + /** + * Creates an empty list. + */ + public QuickList () { + mHead = new BoundaryEntry (); + mTail = new BoundaryEntry (); + + mHead.mNext = mTail; + mTail.mPrevious = mHead; + } + + public boolean isEmpty () { + return (mHead.mNext == mTail); + } + + /** + * Returns the head instance of BoundaryEntry. + */ + public BoundaryEntry getHeadBoundaryEntry () { + return (mHead); + } + + /** + * Returns the tail instance of BoundaryEntry. + */ + public BoundaryEntry getTailBoundaryEntry () { + return (mTail); + } + + /** + * Returns the first entry without unlinking it + * from the list, or null if the list is empty. + */ + public Entry getFirst () { + Entry first = mHead.mNext; + + return (first == mTail ? null : first); + } + + /** + * Returns the first entry without unlinking it + * from the list, or the tail boundary entry if the list is empty. + */ + public Entry getFirstOrTail () { + return (mHead.mNext); + } + + /** + * Returns the last entry without unlinking it + * from the list, or null if the list is empty. + */ + public Entry getLast () { + Entry last = mTail.mPrevious; + + return (last == mHead ? null : last); + } + + /** + * Returns the last entry without unlinking it + * from the list, or the head boundary entry if the list is empty. + */ + public Entry getLastOrHead () { + return (mTail.mPrevious); + } + + /** + * Unsafely unlinks all entries (i.e. the unlinked entries have + * no knowledge of what just happened and continue to point to their + * former neighbors). + */ + public void clear () { + if (DO_ASSERTIONS) { + while (mHead.mNext != mTail) + mHead.mNext.unlink (); + } + else + unlinkBetweenExclusive (mHead, mTail); + } + + /** + * Unsafely unlinks all entries between, but excluding, + * previous and next + * (i.e. the unlinked entries have + * no knowledge of what just happened and continue to point to their + * former neighbors). No checks are made that + * previous and next are, indeed, in + * the same list and that they are there in the correct order. + */ + public static void unlinkBetweenExclusive ( + Entry previous, + Entry next + ) + { + if (DO_ASSERTIONS) { + previous.mNext.mPrevious = null; + next.mPrevious.mNext = null; + } + + previous.mNext = next; + next.mPrevious = previous; + } + + /** + * Links a chain of entries between two specified entries. + * If there have been any entries between the two specified entries, + * they are unsafely unlinked hereby (i.e. the unlinked entries have + * no knowledge of what just happened and continue to point to their + * former neighbors). + */ + public static void linkChainBetween ( + Entry previous, + Entry firstInChain, + Entry lastInChain, + Entry next + ) + { + if (DO_ASSERTIONS) { + if (previous.mNext != next) { + previous.mNext.mPrevious = null; + next.mPrevious.mNext = null; + } + + if (firstInChain.mPrevious != null) + throw new RuntimeException ( + firstInChain + " was not properly unlinked: mPrevious == " + + firstInChain.mPrevious + ); + + if (lastInChain.mNext != null) + throw new RuntimeException ( + lastInChain + " was not properly unlinked: mNext == " + + lastInChain.mNext + ); + } + + previous.mNext = firstInChain; + firstInChain.mPrevious = previous; + lastInChain.mNext = next; + next.mPrevious = lastInChain; + } + + /** + * Links an entire other list between two specified entries. + * The other list is made invalid by this call and should not be used + * unless clear'ed beforehand. + * If there have been any entries between the two specified entries, + * they are unsafely unlinked hereby (i.e. the unlinked entries have + * no knowledge of what just happened and continue to point to their + * former neighbors). + */ + public static void linkBetween ( + Entry previous, + QuickList l, + Entry next + ) + { + if (!l.isEmpty ()) + linkChainBetween (previous, l.mHead.mNext, l.mTail.mPrevious, next); + } + + /** + * Links a chain of entries at the head of the list. + */ + public void linkChainFirst (Entry firstInChain, Entry lastInChain) { + linkChainBetween (mHead, firstInChain, lastInChain, mHead.mNext); + } + + /** + * Links a chain of entries at the tail of the list. + */ + public void linkChainLast (Entry firstInChain, Entry lastInChain) { + linkChainBetween (mTail.mPrevious, firstInChain, lastInChain, mTail); + } + + /** + * Links a chain of entries after the specified one. + */ + public static void linkChainAfter (Entry previous, Entry firstInChain, Entry lastInChain) { + linkChainBetween (previous, firstInChain, lastInChain, previous.mNext); + } + + /** + * Links a chain of entries before the specified one. + */ + public static void linkChainBefore (Entry firstInChain, Entry lastInChain, Entry next) { + linkChainBetween (next.mPrevious, firstInChain, lastInChain, next); + } + + /** + * Links the entry at the head of the list. + */ + public void linkFirst (Entry e) { + linkChainFirst (e, e); + } + + /** + * Links the entry at the tail of the list. + */ + public void linkLast (Entry e) { + linkChainLast (e, e); + } + + /** + * Links the entry after the specified one. + */ + public static void linkAfter (Entry previous, Entry e) { + linkChainAfter (previous, e, e); + } + + /** + * Links the entry before the specified one. + */ + public static void linkBefore (Entry e, Entry next) { + linkChainBefore (e, e, next); + } + + /** + * Links an entire other list at the head of the list. + * The other list is made invalid by this call and should not be used + * unless clear'ed beforehand. + */ + public void linkFirst (QuickList l) { + if (!l.isEmpty ()) + linkChainFirst (l.mHead.mNext, l.mTail.mPrevious); + } + + /** + * Links an entire other list at the tail of the list. + * The other list is made invalid by this call and should not be used + * unless clear'ed beforehand. + */ + public void linkLast (QuickList l) { + if (!l.isEmpty ()) + linkChainLast (l.mHead.mNext, l.mTail.mPrevious); + } + + /** + * Links an entire other list after the specified entry. + * The other list is made invalid by this call and should not be used + * unless clear'ed beforehand. The specified entry should be part of another + * list, which by the virtue of calling this method is inserted into. + */ + public static void linkAfter (Entry previous, QuickList l) { + if (!l.isEmpty ()) + linkChainAfter (previous, l.mHead.mNext, l.mTail.mPrevious); + } + + /** + * Links an entire other list before the specified entry. + * The other list is made invalid by this call and should not be used + * unless clear'ed beforehand. The specified entry should be part of another + * list, which by the virtue of calling this method is inserted into. + */ + public static void linkBefore (QuickList l, Entry next) { + if (!l.isEmpty ()) + linkChainBefore (l.mHead.mNext, l.mTail.mPrevious, next); + } + + /** + * Returns an enumeration of all entries. + */ + public Enumeration entries () { + return (new EntryEnumeration (mHead.mNext)); + } +} diff --git a/src/deltix/util/io/IOUtil.java b/src/deltix/util/io/IOUtil.java new file mode 100644 index 00000000..ba372307 --- /dev/null +++ b/src/deltix/util/io/IOUtil.java @@ -0,0 +1,840 @@ +package deltix.util.io; + +import java.io.*; +import java.util.*; +import java.util.zip.*; + +import java.nio.channels.FileLock; + +import deltix.util.Util; + +/** + * + */ +public class IOUtil { + /** + * Return the short name of teh file without the extension. + */ + public static String getNameNoExt (File f) { + String name = f.getName (); + int dotIdx = name.lastIndexOf ('.'); + if (dotIdx < 0) + return (name); + else + return (name.substring (0, dotIdx)); + } + + /** + * Clones the Serializable object by first writing it to a byte stream + * and then reading it back. + * + * @param object the Serializable object being cloned + * + * @return Object - the cloned object + * + * @throws CloneNotSupportedException - thrown when the afore-mentioned cloning algorithm fails + */ + public static Object clone(Serializable object) + throws CloneNotSupportedException + { + Object clone = null; + + try { + ByteArrayOutputStream baos = new ByteArrayOutputStream (4096); + ObjectOutputStream oos = new ObjectOutputStream (baos); + oos.writeObject (object); + oos.close (); + + ByteArrayInputStream bais = new ByteArrayInputStream (baos.toByteArray ()); + ObjectInputStream ois = new ObjectInputStream (bais); + clone = ois.readObject (); + ois.close (); + } catch (Exception x) { + x.printStackTrace(); + throw new CloneNotSupportedException (x.getMessage ()); + } + + return clone; + } + + /** + * Reads entire stream into bufffer + * + * @param is the InputStream to read + * @param readBlockSize - [IMPORTANT] - expected size of the stream or block size + * + * @return Input Stream as array of bytes + * @throws IOException - InputStream.read() fails + */ + public static byte[] getStreamBytes(InputStream is, final int readBlockSize) + throws IOException + { + + int bufSize = 0; // actual bytes read + int bufCapacity = readBlockSize; // current buffer capacity + byte buf[] = new byte[bufCapacity]; + + try { + while (true) { + int bytesRead = is.read (buf, bufSize, readBlockSize); + + //System.err.println ("request.is.read() bytesRead=" + bytesRead); + + bufSize += (bytesRead > 0) ? bytesRead : 0; + + if (bytesRead <= 0) // no more data? + break; + + if (bufSize + readBlockSize > bufCapacity) { + // buffer is full but we have more bytes in stream - realloc + bufCapacity += 2 * readBlockSize; + + byte[] newbuf = new byte[bufCapacity]; + System.arraycopy (buf, 0, newbuf, 0, bufSize); + buf = newbuf; + } + } + } finally { + // Closing stream is responsibility of stream creator! + // if (is != null) is.close(); + } + + byte[] result = new byte[bufSize]; + if (bufSize > 0) + System.arraycopy (buf, 0, result, 0, bufSize); + return result; + } + + /** Copy src file into dest */ + public static void copyFile (File src, File dest) + throws IOException, InterruptedException + { + FileInputStream in = null; + FileOutputStream out = null; + + try { + in = new FileInputStream (src); + out = new FileOutputStream (dest); + + StreamPump.pump (in, out); + } finally { + Util.close (in); + Util.close (out); + } + } + + /** + * Copies file and creates full destination path if needed + */ + public static void copyFileWithPathCreate (File src, File dest) + throws IOException, InterruptedException + { + File directory = dest.getParentFile(); + if (!directory.exists()){ + directory.mkdirs(); + } + copyFile (src, dest); + } + + public static void mkParentDirIfNeeded (File f) + throws FileNotFoundException + { + mkDirIfNeeded (f.getParentFile ()); + } + + public static void mkDirIfNeeded (File f) + throws FileNotFoundException + { + if (!f.isDirectory () && !f.mkdirs ()) + throw new FileNotFoundException ("Cannot create " + f.getPath ()); + } + + public static void removeRecursive ( + File file, + FileFilter filter, + boolean includeThisFile + ) + throws IOException + { + if (file.isDirectory ()) { + File [] fileElements = file.listFiles (filter); + + if (fileElements != null) + for (int iElement = 0; iElement < fileElements.length; iElement++) + removeRecursive (fileElements [iElement], filter, true); + } + + if (includeThisFile) + file.delete (); + } + + public static void removeRecursive (File file) + throws IOException + { + removeRecursive (file, null, true); + } + + public static void removeRecursiveBefore (File file, Date date, + boolean includeThisDir) + throws IOException + { + long lastMod = file.lastModified(); + + if (file.isDirectory ()) { + File [] fileElements = file.listFiles (); + for (int iElement = 0; iElement < fileElements.length; iElement++) + removeRecursiveBefore (fileElements [iElement], date); + } + + if (includeThisDir && lastMod < date.getTime()) + file.delete (); + } + + public static void removeRecursiveBefore (File file, Date date) + throws IOException + { + long lastMod = file.lastModified(); + + if (file.isDirectory ()) { + File [] fileElements = file.listFiles (); + for (int iElement = 0; iElement < fileElements.length; iElement++) + removeRecursiveBefore (fileElements [iElement], date); + } + + if (lastMod < date.getTime()) + file.delete (); + } + + public static void readFile (File file, OutputStream out) + throws IOException, InterruptedException + { + FileInputStream fis = new FileInputStream (file); + + try { + StreamPump.pump (fis, out); + } finally { + Util.close (fis); + } + } + + public static String readTextFromClassPath (String relPath) + throws IOException, InterruptedException + { + InputStream is = openResourceAsStream (relPath); + + try { + return (readFromReader (new InputStreamReader (is))); + } finally { + Util.close (is); + } + } + + public static String readTextFile (String filepath) + throws IOException, InterruptedException + { + FileReader fr = null; + + try { + fr = new FileReader (filepath); + return (readFromReader (fr)); + } finally { + Util.close (fr); + } + } + + public static String readTextFile (File f) + throws IOException, InterruptedException + { + FileReader fr = null; + + try { + fr = new FileReader (f); + return (readFromReader (fr)); + } finally { + Util.close (fr); + } + } + + /** + */ + public static String readFromStream (InputStream is, String encoding) + throws IOException, InterruptedException + { + return (readFromReader (new InputStreamReader (is, encoding))); + } + + /** + */ + public static String readFromStream (InputStream is) + throws IOException, InterruptedException + { + return (readFromReader (new InputStreamReader (is))); + } + + /** + */ + public static String readFromReader (Reader r) + throws IOException, InterruptedException + { + if (!(r instanceof BufferedReader)) + r = new BufferedReader (r); + + StringBuffer fileContents = new StringBuffer (); + char [] tmpContent = new char [4096]; + + for (;;) { + int numRead = r.read (tmpContent, 0, tmpContent.length); + + if (Thread.interrupted ()) + throw new InterruptedException (); + + if (numRead < 0) + break; + + fileContents.append (tmpContent, 0, numRead); + } + + return (fileContents.toString ()); + } + + public static void writeTextFile (String filepath, String content) + throws IOException + { + FileWriter fw = new FileWriter (filepath); + + fw.write(content); + fw.close (); + } + + public static void writeBytes ( + File file, + byte [] bytes, + int offset, + int length + ) + throws IOException + { + FileOutputStream fos = new FileOutputStream (file); + + try { + fos.write (bytes, offset, length); + } finally { + Util.close (fos); + } + } + + public static byte [] readBytes (File file) + throws IOException + { + int flen = (int) file.length (); + byte [] ret = new byte [flen]; + + readBytes (file, ret, 0, flen); + return (ret); + } + + public static void readBytes ( + File file, + byte [] bytes, + int offset, + int length + ) + throws IOException + { + FileInputStream fis = new FileInputStream (file); + + try { + new DataInputStream (fis).readFully (bytes, offset, length); + } finally { + Util.close (fis); + } + } + + public static Properties readPropsFromFile (File file) + throws IOException + { + Properties props = new Properties (); + FileInputStream fis = new FileInputStream (file); + + try { + props.load (fis); + } finally { + Util.close (fis); + } + + return (props); + } + + /** + * Opens a resource as stream, but throws a FileNotFoundException + * if not found. + */ + public static InputStream openResourceAsStream (String relPath) + throws FileNotFoundException + { + InputStream is = + IOUtil.class.getClassLoader ().getResourceAsStream (relPath); + + if (is == null) + throw new FileNotFoundException ("CLASSPATH/" + relPath); + + return (is); + } + + public static void copyResource (String path, OutputStream os) + throws IOException, InterruptedException + { + InputStream is = openResourceAsStream (path); + + try { + StreamPump.pump (is, os); + is.close (); + } finally { + Util.close (is); + } + } + + public static Properties readPropsFromClassPath (String relPath) + throws IOException + { + Properties props = new Properties (); + InputStream is = openResourceAsStream (relPath); + + try { + props.load (is); + } finally { + Util.close (is); + } + + return (props); + } + + public static void extractResource (String resource, File dest) + throws IOException, InterruptedException + { + InputStream is = null; + OutputStream os = null; + + try { + is = IOUtil.class.getClassLoader ().getResourceAsStream (resource); + + if (is == null) + throw new FileNotFoundException (resource); + + os = new FileOutputStream (dest); + StreamPump.pump (is, os); + os.close (); + is.close (); + } finally { + Util.close (is); + Util.close (os); + } + } + + public static void storePropsToFile ( + Properties props, + File file, + String header + ) + throws IOException + { + FileOutputStream fos = new FileOutputStream (file); + + try { + props.store (fos, header); + } finally { + Util.close (fos); + } + } + + /** + * Checks if the file is present. + * @exception FileNotFoundException If the file does not exists. + */ + public static void assertExists (File f) throws FileNotFoundException { + if (!f.exists ()) + throw (new FileNotFoundException (f.getPath ())); + } + + private static final String SPECIAL_ZIP_ENTRY_NAME = "SERIALIZED-OBJECT"; + + public static boolean looksLikeZip (File f) { + return (f.getName ().toLowerCase ().endsWith (".zip")); + } + + public static OutputStream openMaybeZip (OutputStream fos, boolean compress) + throws IOException + { + if (compress) { + ZipOutputStream zipos = new ZipOutputStream (fos); + zipos.putNextEntry (new ZipEntry (SPECIAL_ZIP_ENTRY_NAME)); + return (zipos); + } + else + return (fos); + } + + public static InputStream openMaybeZip (InputStream fis, boolean compress) + throws IOException + { + if (compress) { + ZipInputStream zipis = new ZipInputStream (fis); + zipis.getNextEntry (); + return (zipis); + } + else + return (fis); + } + + public static InputStream openInputMaybeZip (File f, boolean compress) + throws IOException + { + return ( + openMaybeZip ( + new BufferedInputStream (new FileInputStream (f)), + compress + ) + ); + } + + public static InputStream openInputMaybeZip (File f) + throws IOException + { + return (openInputMaybeZip (f, looksLikeZip (f))); + } + + public static OutputStream openOutputMaybeZip (File f, boolean compress) + throws IOException + { + return ( + openMaybeZip ( + new BufferedOutputStream (new FileOutputStream (f)), + compress + ) + ); + } + + public static OutputStream openOutputMaybeZip (File f) + throws IOException + { + return (openOutputMaybeZip (f, looksLikeZip (f))); + } + + public static void closeMaybeZip (InputStream is) throws IOException { + is.close (); + } + + public static void closeMaybeZip (OutputStream os) throws IOException { + if (os instanceof ZipOutputStream) { + ZipOutputStream zipos = (ZipOutputStream) os; + zipos.closeEntry (); + zipos.finish (); + } + else + os.close (); + } + + /** + * Read a serializable object from file. + * + * @param in_is InputStream to read from. + * @param compress Whether to treat the file is zipped. + */ + public static Serializable readSerializable (InputStream in_is, boolean compress) + throws IOException, ClassNotFoundException + { + InputStream is = openMaybeZip (in_is, compress); + ObjectInputStream ois = new ObjectInputStream (is); + Serializable ret = (Serializable) ois.readObject (); + + return (ret); + } + + /** + * Read a serializable object from file. + * + * @param f File to read from. + * @param compress Whether to treat the file is zipped. + */ + public static Serializable readSerializable (File f, boolean compress) + throws IOException, ClassNotFoundException + { + FileInputStream fis = new FileInputStream (f); + + try { + return (readSerializable (fis, compress)); + } finally { + Util.close (fis); + } + } + + /** + * Read a serializable object from file. If the file has the ".zip" extension, + * it is treated as compressed. + * + * @param f File to read from. + */ + public static Serializable readSerializable (File f) + throws IOException, ClassNotFoundException + { + return (readSerializable (f, looksLikeZip (f))); + } + + /** + * Write a serializable object to file. + * + * @param f File to write to. + * @param compress Whether to zip up the object. + */ + public static void writeSerializable ( + File f, + Serializable obj, + boolean compress + ) + throws IOException + { + FileOutputStream fos = new FileOutputStream (f); + + try { + OutputStream os = openMaybeZip (fos, compress); + + { + ObjectOutputStream oos = new ObjectOutputStream (os); + oos.writeObject (obj); + oos.flush (); + } + + closeMaybeZip (os); + } finally { + Util.close (fos); + } + } + + /** + * Write a serializable object to file. If the file has the ".zip" extension, + * the object is compressed on write, and a zip file is created. + * + * @param f File to write to. + */ + public static void writeSerializable (File f, Serializable obj) + throws IOException + { + writeSerializable (f, obj, looksLikeZip (f)); + } + + /** + * Copies files from the specified directory to the specified directory. + * @param from -- directory to copy files from + * @param to -- directory to copy files to + * @param create -- if true and to directory does not exist create it. + * @param recursive -- if true also copies child directories + * @param filter -- if not null only copies files that satisfy the specified filter + * @param excludeFilter -- if not null does not copy files that satisfy the filter + */ + public static void copyDirectory ( + File from, + File to, + boolean create, + boolean recursive, + FilenameFilter filter, + FilenameFilter excludeFilter + ) + throws IOException, InterruptedException + { + if (create){ + if (!to.exists()){ + to.mkdirs(); + } + } + File [] fileList = from.listFiles(filter); + for (int i = 0; i < fileList.length; i++){ + File f = fileList [i]; + if ((excludeFilter == null)||(!excludeFilter.accept(to, f.getName()))){ + File copy = new File (to, f.getName()); + if (f.isDirectory()){ + copy.mkdir(); + if (recursive){ + copyDirectory (f, copy, false, recursive, filter, excludeFilter); + } + } + else{ + copyFile(f, copy); + } + } + } + } + + private static String getCmdAsString (String [] arr) { + StringBuffer sb = new StringBuffer (); + + for (int ii = 0; ii < arr.length; ii++) { + if (ii > 0) + sb.append (' '); + sb.append ('\''); + sb.append (arr [ii]); + sb.append ('\''); + } + + return (sb.toString ()); + } + + public static long getFreeDiskSpaceOn(File filesys) + throws IOException, InterruptedException { + if (!filesys.exists()) + throw new FileNotFoundException(filesys.getPath()); + + String fsep = System.getProperty("file.separator"); + String[] cmd = null; + boolean dos = true; + + if (fsep.equals("\\")) + cmd = new String[] { "cmd.exe", "/c", "dir", filesys.getPath()}; + else { + cmd = new String[] { "/usr/bin/df", "-k", filesys.getPath()}; + dos = false; + } + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + try { + int ret = + ProcessHelper.execAndWait( + cmd, + null, + null, + false, + baos, + true, + null, + false); + } catch (IOException e) { + cmd = new String[] { "df", "-k", filesys.getPath()}; + int ret = + ProcessHelper.execAndWait( + cmd, + null, + null, + false, + baos, + true, + null, + false); + + if (ret != 0) + throw new IOException( + "Command\n" + getCmdAsString(cmd) + "\nexited with " + ret); + } + String s = new String(baos.toByteArray()); + + if (System.getProperty("debug.diskspace") != null) + System.out.println( + "Output from\n" + getCmdAsString(cmd) + ":\n" + s); + + int pos = -1; + long value = 0; + + if (dos) { + pos = s.lastIndexOf(" bytes free"); + + if (pos < 0) + throw new IOException( + "Unrecognized output from\n" + + getCmdAsString(cmd) + + ":\n" + + s); + long exp = 1; + + for (;;) { + pos--; + + char ch = s.charAt(pos); + + if (ch == ' ') + break; + + if (ch == ',') + continue; + + value += exp * (ch - '0'); + exp *= 10; + } + + } else { + StringTokenizer st = new StringTokenizer(s); + for (int i = 1; i < 11; i++) { + st.nextToken(); + if (i == 10) + value = Long.parseLong(st.nextToken()); + value *= 1024; // df -k gives us in kilobytes + } + + } + + return (value); + } + + /** + * Method attempts to obtian exclusive lock on given file. + * Can be used e.g. to prevent two instances of application from running at the same time. + * Example: + *
+     * FileLock lock = null;
+     * try {
+     *    lock = IOUtil.lock ("fleet.client.lock", true);
+     *    runApplication (...);
+     * } finally {
+     *       IOUtil.unlock (lock);
+     * }
+     * 
+ * + * + * + * @param fileLockName - name of the log file to be created in user home directory + * @param exitProcessOnFail - specify true to exit the process on lock failure or any other error + * @return non-null FileLock if given file can be locked + */ + public static final FileLock lock (String fileLockName, boolean exitProcessOnFail) { + + File lockFile = new File (System.getProperty ("user.home"), fileLockName); + FileLock result = null; + try { + result = new RandomAccessFile (lockFile, "rw").getChannel().tryLock(); + } catch (IOException xcp) { + xcp.printStackTrace(); + } + + if (result == null) { + System.err.println("Looks like application is already running (cannot create file lock " + + lockFile.getAbsolutePath() + ")"); + + if (exitProcessOnFail) + System.exit (1); + } + + + return result; + } + + /** + * @param lock - lock obtained by lock() + */ + public static final void unlock (FileLock lock) { + if (lock != null) { + try { + lock.release (); + } catch (IOException ignore) { + ignore.printStackTrace(); + } + } + } + + + + public static final class FileOnlyFilter implements FileFilter { + + public boolean accept(File pathname) + { + return pathname.isFile (); + } + } +} diff --git a/src/deltix/util/io/InputStreamSink.java b/src/deltix/util/io/InputStreamSink.java new file mode 100644 index 00000000..b0f68820 --- /dev/null +++ b/src/deltix/util/io/InputStreamSink.java @@ -0,0 +1,48 @@ +package deltix.util.io; + +import java.io.InputStream; + +/** + * Caps an InputStream. This kind of Thread reads the + * specified InputStream until it hits the EOF, completely + * discarding the contents. Useful to attach this to the + * InputStreams of a Process, so the process does not block + * forever when it fills the buffers. + */ +public class InputStreamSink extends Thread { + private InputStream mInputStream; + private boolean mClose; + + /** + * Constructs an InputStreamSink. + * + * @param is The input stream to empty. + * @param close Whether to close the stream when it ends. + */ + public InputStreamSink (InputStream is, boolean close) { + mInputStream = is; + mClose = close; + } + + /** + * Constructs an InputStreamSink which will close the stream at EOF. + * + * @param is The input stream to empty. + */ + public InputStreamSink (InputStream is) { + this (is, true); + } + + public void run () { + try { + byte [] buf = new byte [512]; + + while (mInputStream.read (buf) >= 0); + + if (mClose) + mInputStream.close (); + } catch (Exception x) { + x.printStackTrace (); + } + } +} diff --git a/src/deltix/util/io/ProcessHelper.java b/src/deltix/util/io/ProcessHelper.java new file mode 100644 index 00000000..632c8913 --- /dev/null +++ b/src/deltix/util/io/ProcessHelper.java @@ -0,0 +1,136 @@ +package deltix.util.io; + +import java.io.*; + +/** + * Helps execute commands in separate processes. + */ +public class ProcessHelper { + /** + * Starts a system process and waits for completion. + * + * @param cmd The command to execute. + * @param envp The environment. + * @param stdin The stream from which the process will read. + * @param closeStdin Whether to close stdin at EOF. + * @param stdout The stream into which the process will write its output. + * @param closeStdout Whether to close stdout at EOF. + * @param stderr The stream into which the process will write its errors. + * @param closeStderr Whether to close stderr at EOF. + * @return The exit code of the process. + * + * @exception IOException + * When Runtime.exec () throws it. + * @exception InterruptedException + * When Process.waitFor () throws it. + */ + public static int execAndWait ( + String [] cmd, + String [] envp, + InputStream stdin, + boolean closeStdin, + OutputStream stdout, + boolean closeStdout, + OutputStream stderr, + boolean closeStderr + ) + throws IOException, InterruptedException + { + Process proc = exec (cmd, envp, stdin, closeStdin, stdout, closeStdout, + stderr, closeStderr); + + proc.waitFor (); + return (proc.exitValue ()); + } + + /** + * Starts a system process and returns asynchronously. + * + * @param cmd The command to execute. + * @param envp The environment. + * @param stdin The stream from which the process will read. + * @param closeStdin Whether to close stdin at EOF. + * @param stdout The stream into which the process will write its output. + * @param closeStdout Whether to close stdout at EOF. + * @param stderr The stream into which the process will write its errors. + * @param closeStderr Whether to close stderr at EOF. + * @return The process object. + * + * @exception IOException When Runtime.exec () throws it. + */ + public static Process exec ( + String [] cmd, + String [] envp, + InputStream stdin, + boolean closeStdin, + OutputStream stdout, + boolean closeStdout, + OutputStream stderr, + boolean closeStderr + ) + throws IOException + { + Process proc = Runtime.getRuntime ().exec (cmd, envp); + InputStream proc_stderr = proc.getErrorStream (); + InputStream proc_stdout = proc.getInputStream (); + OutputStream proc_stdin = proc.getOutputStream (); + + if (stdout == null) + new InputStreamSink (proc_stdout).start (); + else + new StreamPump (proc_stdout, stdout, true, closeStdout).start (); + + if (stderr == null) + new InputStreamSink (proc_stderr).start (); + else + new StreamPump (proc_stderr, stderr, true, closeStderr).start (); + + if (stdin != null) + new StreamPump (stdin, proc_stdin, closeStderr, true).start (); + + return (proc); + } + + /** + * Starts a system process, which inherits the current standard + * output streams, and waits for completion. The input stream is + * currently not inherited. + * + * @param cmd The command to execute. + * @param envp The environment. + * @return The exit code of the process. + * + * @exception IOException + * When Runtime.exec () throws it. + * @exception InterruptedException + * When Process.waitFor () throws it. + */ + public static int execAndWait ( + String [] cmd, + String [] envp + ) + throws IOException, InterruptedException + { + return (execAndWait (cmd, envp, null, false, System.out, false, + System.err, false)); + } + + /** + * Starts a system process, which inherits the current standard + * input/output streams, and waits for completion. + * + * @param cmd The command to execute. + * @return The exit code of the process. + * + * @exception IOException + * When Runtime.exec () throws it. + * @exception InterruptedException + * When Process.waitFor () throws it. + */ + public static int execAndWait (String [] cmd) + throws IOException, InterruptedException + { + return (execAndWait (cmd, null)); + } + +} diff --git a/src/deltix/util/io/StreamPump.java b/src/deltix/util/io/StreamPump.java new file mode 100644 index 00000000..5a1a95ec --- /dev/null +++ b/src/deltix/util/io/StreamPump.java @@ -0,0 +1,122 @@ +package deltix.util.io; + +import deltix.util.progress.ProgressIndicator; +import deltix.util.Util; +import java.io.*; + + +/** + * Pumps the content of an InputStream into an OutputStream. + */ +public class StreamPump extends Thread { + private InputStream mInputStream; + private OutputStream mOutputStream; + private boolean mCloseInput; + private boolean mCloseOutput; + + /** + * Constructs a StreamPump. + * + * @param is The input stream to pump from. + * @param os The output stream to pump into. + * @param closeInput Whether to close the input stream when it ends. + * @param closeOutput Whether to close the output stream when + * the input stream ends. + */ + public StreamPump ( + InputStream is, + OutputStream os, + boolean closeInput, + boolean closeOutput + ) + { + mInputStream = is; + mOutputStream = os; + mCloseInput = closeInput; + mCloseOutput = closeOutput; + } + + /** + * Constructs a StreamPump which will close both streams at EOF. + * + * @param is The input stream to empty. + */ + public StreamPump (InputStream is, OutputStream os) { + this (is, os, true, true); + } + + public static long pump (InputStream is, OutputStream os) + throws IOException, InterruptedException + { + return (pump (is, os, 4096)); + } + + public static long pump (InputStream is, OutputStream os, int bufSize) + throws IOException, InterruptedException + { + return (pump (is, os, -1, bufSize, null, 0, 0)); + } + + public static long pump ( + InputStream is, + OutputStream os, + long maxBytes, + int bufSize, + ProgressIndicator listener, + double workDonePrior, + double workPerByte + ) + throws IOException, InterruptedException + { + if (maxBytes <= 0) + maxBytes = Long.MAX_VALUE; + + byte [] buf = new byte [bufSize]; + double workDone = workDonePrior; + long bytesDone = 0; + + for (;;) { + int numToRead = buf.length; + + if (numToRead > maxBytes) + numToRead = (int) maxBytes; + + int n = is.read (buf, 0, numToRead); + + if (n < 0) + break; + + if (n > 0) + os.write (buf, 0, n); + + if (Thread.interrupted ()) + throw new InterruptedException (); + + if (listener != null) { + workDone += n * workPerByte; + listener.setWorkDone (workDone); + } + + bytesDone += n; + + if (bytesDone >= maxBytes) + break; + } + + return (bytesDone); + } + + public void run () { + try { + pump (mInputStream, mOutputStream); + } catch (Exception x) { + x.printStackTrace (); + } finally { + if (mCloseInput) + Util.close (mInputStream); + + if (mCloseOutput) + Util.close (mOutputStream); + } + } +} diff --git a/src/deltix/util/io/Timeout.java b/src/deltix/util/io/Timeout.java new file mode 100644 index 00000000..856d4f1b --- /dev/null +++ b/src/deltix/util/io/Timeout.java @@ -0,0 +1,72 @@ +package deltix.util.io; + +/** + * Class that will execute an action after a specified + * period of time. + */ +public class Timeout implements Runnable { + private Runnable mAction; + private long mTimeout; + private Thread mThread = null; + + /** + * Constructs a new instance of the timer. The timer is + * not armed on construction. + * + * @param action The Runnable to run after the timeout. + * @param timeout The timeout in milliseconds. + */ + public Timeout (Runnable action, long timeout) { + mAction = action; + mTimeout = timeout; + } + + /** + * Constructs a new instance of the timer. The timer is + * not armed on construction. + * + * @param timeout The timeout in milliseconds. + */ + public Timeout (long timeout) { + mAction = this; + mTimeout = timeout; + } + + private void executeAction () { + mAction.run (); + } + + /** + * Runs after the timeout. Override to determine behavior. + * By default, this method throws a RuntimeException. + */ + public void run () { + throw (new RuntimeException ()); + } + + /** + * Arms the timeout. + */ + public void arm () { + mThread = + new Thread () { + public void run () { + try { + sleep (mTimeout); + executeAction (); + } catch (InterruptedException x) { + } + } + }; + + mThread.start (); + } + + /** + * Disarms the timeout. + */ + public void disarm () { + mThread.interrupt (); + mThread = null; + } +} diff --git a/src/deltix/util/jdbc/JDBCUtils.java b/src/deltix/util/jdbc/JDBCUtils.java new file mode 100644 index 00000000..cfff182d --- /dev/null +++ b/src/deltix/util/jdbc/JDBCUtils.java @@ -0,0 +1,95 @@ +package deltix.util.jdbc; + +import deltix.custom.statestreet.fxa.utils.*; +import java.sql.*; +import java.util.logging.*; + +/** + * + */ +public class JDBCUtils { + /** + * Converts NaN to NULL + */ + public static void setDouble (PreparedStatement ps, int idx, double v) + throws SQLException + { + if (Double.isNaN (v)) + ps.setNull (idx, Types.FLOAT); + else + ps.setDouble (idx, v); + } + + public static int queryInt (PreparedStatement ps) throws SQLException { + ResultSet rs = ps.executeQuery (); + + try { + if (!rs.next ()) + throw new SQLException ("No rows returned"); + + int ret = rs.getInt (1); + + if (rs.next ()) + throw new SQLException ("Multiple rows returned"); + + return (ret); + } finally { + rs.close (); + } + } + + public static void close (Connection conn) { + if (conn != null) + try { + conn.close (); + } catch (Throwable x) { + Common.LOGGER.log (Level.SEVERE, "Error while closing a connection", x); + } + } + + public static void close (Statement stmt) { + if (stmt != null) + try { + stmt.close (); + } catch (Throwable x) { + Common.LOGGER.log (Level.SEVERE, "Error while closing a statement", x); + } + } + + public static void truncateTable (Connection conn, String tname) + throws SQLException + { + exec (conn, "TRUNCATE TABLE \"" + tname + "\""); + } + + public static void deleteTable (Connection conn, String tname) + throws SQLException + { + exec (conn, "DELETE FROM \"" + tname + "\""); + } + + public static void prepare (Connection conn, String tname, TableOp op) + throws SQLException + { + switch (op) { + case APPEND: break; + case DELETE: deleteTable (conn, tname); break; + case TRUNCATE: truncateTable (conn, tname); break; + } + } + + public static void exec (Connection conn, String sql) + throws SQLException + { + Statement stmt = conn.createStatement (); + + try { + stmt.execute (sql); + stmt.close (); + stmt = null; + } finally { + close (stmt); + } + } + +} diff --git a/src/deltix/util/jdbc/TableOp.java b/src/deltix/util/jdbc/TableOp.java new file mode 100644 index 00000000..9cd4a8c8 --- /dev/null +++ b/src/deltix/util/jdbc/TableOp.java @@ -0,0 +1,10 @@ +package deltix.util.jdbc; + +/** + * + */ +public enum TableOp { + APPEND, + DELETE, + TRUNCATE +}; diff --git a/src/deltix/util/lang/LocalizableException.java b/src/deltix/util/lang/LocalizableException.java new file mode 100644 index 00000000..36095b73 --- /dev/null +++ b/src/deltix/util/lang/LocalizableException.java @@ -0,0 +1,131 @@ +package deltix.util.lang; + +import java.util.*; +import java.text.*; + +/** + * Framework class for exceptions that automatically format their + * LocalizedMessage by using a resource bundle. In order to use this class: + * + *
    + *
  1. Derive your child exception class from this class. Suppose that your + * exception class is deltix.gobbler.FooException. + *
  2. Define a resource bundle called + * deltixlab/gobbler/exceptions. The best way of doing this is + * to create a properties resource bundle + * codebase/deltixlab/gobbler/exception.properties. This bundle will + * contain the translations of this exception. + *
  3. Now there are two ways of referencing the individual messages. + * If a LocalizableException instance is constructed with no + * addlKey argument, then the message in the resource bundle + * will be keyed by the short class name fo the exception. + * If a LocalizableException instance is constructed with a + * addlKey argument, then the message in the resource bundle + * will be keyed by the a string starting with the short class name, + * followed by a ".", and then by the supplied addlKey. In all cases the + * addlKey starts with the exception's short class name. For instance, + * you can have the following messages in your bundle: + *
    FooException=The foo bar named {0} is out of order.
    + *FooException.unknown=The unknown foo bar is out of order.
    + * In order to reference the first and second messages respectively, + * you would throw the exceptions as follows: + *
    throw new FooException (new Object [] { fooBarName });
    + *...
    + *throw new FooException ("unknown");
    + *
  4. Note that if the exception class is renamed, all recource bundles + * must be updated. + *
+ */ +public abstract class LocalizableException extends Exception { + static final long serialVersionUID = -2562626847072156603L; + + public static final String RB_NAME = "exceptions"; + + private Object [] mParameters; + private String mAddlKey; + private Locale mLocale = Locale.getDefault (); + + /** + * SPecial constructor that defeats the rest of the framework. + * Used when you need to construct a child of LocalizableException that does not + * have any message. + */ + protected LocalizableException () { + super (); + mParameters = null; + mAddlKey = null; + } + + protected LocalizableException (Object [] parameters) { + this (null, parameters); + } + + protected LocalizableException (Object [] parameters, Exception e) { + this (null, parameters, e); + } + + protected LocalizableException ( + String addlKey, + Object [] parameters + ) + { + super (); + mParameters = parameters; + mAddlKey = addlKey; + } + + protected LocalizableException ( + String addlKey, + Object [] parameters, + Exception e + ) + { + super (e); + mParameters = parameters; + mAddlKey = addlKey; + } + + public String getMessage () { + return (getLocalizedMessage ()); + } + + public void setLocale (Locale locale) { + mLocale = locale; + } + + public String getLocalizedMessage () { + return (getLocalizedMessage (mLocale)); + } + + /** + * Formats the message for the arbitrary locale. + */ + public String getLocalizedMessage (Locale locale) { + String myClassName = getClass ().getName (); + int dot = myClassName.lastIndexOf ("."); + String rbName; + String key; + + if (dot == -1) { + rbName = RB_NAME; + key = myClassName; + } + else { + int firstCharOfShortClassName = dot + 1; + String pack = + myClassName.substring ( + 0, + firstCharOfShortClassName + ); + + rbName = pack.replace ('.', '/') + RB_NAME; + key = myClassName.substring (firstCharOfShortClassName); + } + + if (mAddlKey != null) + key = key + "." + mAddlKey; + + ResourceBundle rb = ResourceBundle.getBundle (rbName, locale); + return (MessageFormat.format (rb.getString (key), mParameters)); + } +} diff --git a/src/deltix/util/memory/DataExchangeUtils.java b/src/deltix/util/memory/DataExchangeUtils.java new file mode 100644 index 00000000..1444a75c --- /dev/null +++ b/src/deltix/util/memory/DataExchangeUtils.java @@ -0,0 +1,108 @@ +package deltix.util.memory; + +/** + * Reads/writes primitive values from/to an array of bytes, + * in precisely the same format as DataInput/DataOutput. + */ +public class DataExchangeUtils { + private static int b (byte [] bytes, int offset) { + return (((int) bytes [offset]) & 0xFF); + } + + private static void b (byte [] bytes, int offset, int byt) { + bytes [offset] = (byte) (byt & 0xFF); + } + + private static void b (byte [] bytes, int offset, long byt) { + bytes [offset] = (byte) (byt & 0xFF); + } + + private static long lb (byte [] bytes, int offset) { + return (((long) bytes [offset]) & 0xFF); + } + + public static short readShort (byte [] bytes, int offset) { + return ((short) + (b (bytes, offset) << 8 | + b (bytes, offset + 1)) + ); + } + + public static void writeShort (byte [] bytes, int offset, short s) { + b (bytes, offset, s >>> 8); + b (bytes, offset + 1, s); + } + + public static int readInt (byte [] bytes, int offset) { + return ( + b (bytes, offset) << 24 | + b (bytes, offset + 1) << 16 | + b (bytes, offset + 2) << 8 | + b (bytes, offset + 3) + ); + } + + public static int readIntInvertBytes (byte [] bytes, int offset) { + return ( + b (bytes, offset) | + b (bytes, offset + 1) << 8 | + b (bytes, offset + 2) << 16 | + b (bytes, offset + 3) << 24 + ); + } + + public static void writeInt (byte [] bytes, int offset, int i) { + b (bytes, offset, i >>> 24); + b (bytes, offset + 1, i >>> 16); + b (bytes, offset + 2, i >>> 8); + b (bytes, offset + 3, i); + } + + public static void writeIntInvertBytes (byte [] bytes, int offset, int i) { + b (bytes, offset, i); + b (bytes, offset + 1, i >>> 8); + b (bytes, offset + 2, i >>> 16); + b (bytes, offset + 3, i >>> 24); + } + + public static float readFloat (byte [] bytes, int offset) { + return (Float.intBitsToFloat (readInt (bytes, offset))); + } + + public static void writeFloat (byte [] bytes, int offset, float f) { + writeInt (bytes, offset, Float.floatToIntBits (f)); + } + + public static long readLong (byte [] bytes, int offset) { + return ( + lb (bytes, offset) << 56 | + lb (bytes, offset + 1) << 48 | + lb (bytes, offset + 2) << 40 | + lb (bytes, offset + 3) << 32 | + lb (bytes, offset + 4) << 24 | + lb (bytes, offset + 5) << 16 | + lb (bytes, offset + 6) << 8 | + lb (bytes, offset + 7) + ); + } + + public static void writeLong (byte [] bytes, int offset, long l) { + b (bytes, offset, l >>> 56); + b (bytes, offset + 1, l >>> 48); + b (bytes, offset + 2, l >>> 40); + b (bytes, offset + 3, l >>> 32); + b (bytes, offset + 4, l >>> 24); + b (bytes, offset + 5, l >>> 16); + b (bytes, offset + 6, l >>> 8); + b (bytes, offset + 7, l); + } + + public static double readDouble (byte [] bytes, int offset) { + return (Double.longBitsToDouble (readLong (bytes, offset))); + } + + public static void writeDouble (byte [] bytes, int offset, double d) { + writeLong (bytes, offset, Double.doubleToLongBits (d)); + } + +} diff --git a/src/deltix/util/memory/EstimatorUtils.java b/src/deltix/util/memory/EstimatorUtils.java new file mode 100644 index 00000000..6d477198 --- /dev/null +++ b/src/deltix/util/memory/EstimatorUtils.java @@ -0,0 +1,76 @@ +package deltix.util.memory; + +/** + * + */ +public abstract class EstimatorUtils implements MemorySizeEstimator { + public static int getSizeInMemory (byte [] a) { + return (a == null ? 0 : (7 + ARRAY_OVERHEAD + a.length) / 8 * 8); + } + + public static int getSizeInMemory (boolean [] a) { + return (a == null ? 0 : (7 + ARRAY_OVERHEAD + a.length * SIZE_OF_BOOLEAN) / 8 * 8); + } + + public static int getSizeInMemory (short [] a) { + return (a == null ? 0 : (7 + ARRAY_OVERHEAD + a.length * SIZE_OF_SHORT) / 8 * 8); + } + + public static int getSizeInMemory (char [] a) { + return (a == null ? 0 : (7 + ARRAY_OVERHEAD + a.length * SIZE_OF_CHAR) / 8 * 8); + } + + public static int getSizeInMemory (int [] a) { + return (a == null ? 0 : (7 + ARRAY_OVERHEAD + a.length * SIZE_OF_INT) / 8 * 8); + } + + public static int getSizeInMemory (long [] a) { + return (a == null ? 0 : (7 + ARRAY_OVERHEAD + a.length * SIZE_OF_LONG) / 8 * 8); + } + + public static int getSizeInMemory (float [] a) { + return (a == null ? 0 : (7 + ARRAY_OVERHEAD + a.length * SIZE_OF_FLOAT) / 8 * 8); + } + + public static int getSizeInMemory (double [] a) { + return (a == null ? 0 : (7 + ARRAY_OVERHEAD + a.length * SIZE_OF_DOUBLE) / 8 * 8); + } + + public static int getSizeInMemory (MemorySizeEstimator obj) { + return (obj == null ? 0 : obj.getSizeInMemory ()); + } + + public static int getSizeInMemory (String s) { + return ( + s == null ? + 0 : + ((45 + s.length () * SIZE_OF_CHAR) / 8) * 8 + ); + } + + public static int getSizeInMemory (Object obj) { + if (obj == null) + return (0); + + if (obj instanceof MemorySizeEstimator) + return (getSizeInMemory ((MemorySizeEstimator) obj)); + + if (obj instanceof String) + return (getSizeInMemory ((String) obj)); + + return (OBJECT_OVERHEAD); + } + + public static int getSizeInMemory (Object [] a) { + if (a == null) + return (0); + + int used = (7 + ARRAY_OVERHEAD + a.length * SIZE_OF_POINTER) / 8 * 8; + + for (int ii = 0; ii < a.length; ii++) + used += getSizeInMemory (a [ii]); + + return (used); + } + +} diff --git a/src/deltix/util/memory/MemorySizeEstimator.java b/src/deltix/util/memory/MemorySizeEstimator.java new file mode 100644 index 00000000..8a5c28be --- /dev/null +++ b/src/deltix/util/memory/MemorySizeEstimator.java @@ -0,0 +1,20 @@ +package deltix.util.memory; + +/** + * Implemented by objects that can estimate the size they occupy in memory. + */ +public interface MemorySizeEstimator { + public static final int OBJECT_OVERHEAD = 8; + public static final int ARRAY_OVERHEAD = 12; + public static final int SIZE_OF_BYTE = 1; + public static final int SIZE_OF_BOOLEAN = 1; + public static final int SIZE_OF_CHAR = 2; + public static final int SIZE_OF_SHORT = 2; + public static final int SIZE_OF_INT = 4; + public static final int SIZE_OF_LONG = 8; + public static final int SIZE_OF_FLOAT = 4; + public static final int SIZE_OF_DOUBLE = 8; + public static final int SIZE_OF_POINTER = 4; + + public int getSizeInMemory (); +} diff --git a/src/deltix/util/progress/Estimator.java b/src/deltix/util/progress/Estimator.java new file mode 100644 index 00000000..46dd96b9 --- /dev/null +++ b/src/deltix/util/progress/Estimator.java @@ -0,0 +1,94 @@ +package deltix.util.progress; + +/** + * Estimnates time remaining in a lengthy process. Methods are thread-safe. + */ +public class Estimator { + private double mWorkDone = 0; + private double mTotalWork = 0; + private double mWorkDoneAtBaseTime = 0; + private long mBaseTime = System.currentTimeMillis (); + + public Estimator () { + } + + public synchronized void setTotalWork (double v) { + if (v <= 0) + throw new IllegalArgumentException ("totalWork == " + v + " <= 0"); + + mTotalWork = v; + } + + public synchronized double getTotalWork () { + return (mTotalWork); + } + + public synchronized void setWorkDone (double workDone) { + if (workDone < 0) + throw new IllegalArgumentException ("workDone == " + workDone + " < 0"); + + if (workDone > mTotalWork) + throw new IllegalArgumentException ("workDone == " + workDone + " > totalWork == " + mTotalWork); + + mWorkDone = workDone; + } + + public synchronized double getWorkDone () { + return (mWorkDone); + } + + public synchronized boolean isWorkCompleted () { + return (mWorkDone == mTotalWork); + } + + /** + * Reset time estimation + */ + public synchronized void setWorkDoneAndResetTime (double workDone) { + setWorkDone (workDone); + mWorkDoneAtBaseTime = mWorkDone; + mBaseTime = System.currentTimeMillis (); + } + + public synchronized double getFractionDone () { + return (mWorkDone / mTotalWork); + } + + /** + * Return currently estimated rate of work. + * + * @return Rate in units of work per second. If no work has been + * done, return 0. If elapsed time is 0, return NaN. + */ + public synchronized double getEstimatedRate () { + return ((mWorkDone - mWorkDoneAtBaseTime) / getTimeSinceLastReset ()); + } + + /** + * Return the elapsed time since last reset. + * + * @return Time in seconds. + */ + public synchronized double getTimeSinceLastReset () { + return ((System.currentTimeMillis () - mBaseTime) * 0.001); + } + + public synchronized double getWorkRemaining () { + return (mTotalWork - mWorkDone); + } + + /** + * Return estimated remaining time. This is equivalent to + * getWorkRemaining () * getEstimatedRate (). + * + * @return Estimated remaining time, in seconds. If no work has been + * done, return NaN. If elapsed time is 0, return NaN. + */ + public synchronized double getTimeRemaining () { + return (getWorkRemaining () / getEstimatedRate ()); + } + + public synchronized void incrementWorkDone (double inc) { + setWorkDone (mWorkDone + inc); + } +} diff --git a/src/deltix/util/progress/ProgressIndicator.java b/src/deltix/util/progress/ProgressIndicator.java new file mode 100644 index 00000000..b9a7809f --- /dev/null +++ b/src/deltix/util/progress/ProgressIndicator.java @@ -0,0 +1,13 @@ +package deltix.util.progress; + +/** + * An abstract entity capable of indicating the progress of a process. + * Implementations are required to be thread-safe. + */ +public interface ProgressIndicator { + public void setTotalWork (double v); + + public void setWorkDone (double v); + + public void incrementWorkDone (double inc); +} diff --git a/src/deltix/util/swing/AbstractApp.java b/src/deltix/util/swing/AbstractApp.java new file mode 100644 index 00000000..5da4c557 --- /dev/null +++ b/src/deltix/util/swing/AbstractApp.java @@ -0,0 +1,64 @@ +package deltix.util.swing; + +import java.util.logging.*; +import java.io.*; +import javax.swing.*; + +import deltix.util.io.*; + +public abstract class AbstractApp extends JFrame { + protected AbstractApp () { + setDefaultCloseOperation (EXIT_ON_CLOSE); + } + + public void handle (Throwable x) { + SwingUtil.staticHandle (this, x); + } + + public void handle ( + Throwable x, + Logger logger, + Level logLevel + ) + { + SwingUtil.staticHandle (this, x, logger, logLevel); + } + + public void syncInvoke (Runnable r) + throws InterruptedException + { + try { + if (SwingUtilities.isEventDispatchThread ()) + r.run (); + else + SwingUtilities.invokeAndWait (r); + } catch (java.lang.reflect.InvocationTargetException x) { + handle (x); + } + } + + public void syncHandle (final Throwable x) + throws InterruptedException + { + syncInvoke ( + new Runnable () { + public void run () { + handle (x); + } + } + ); + } + + public void printUsage () throws IOException, InterruptedException { + String cname = getClass ().getName (); + int dot = cname.lastIndexOf ('.'); + String path; + + if (dot > 0) + path = cname.substring (0, dot + 1).replace ('.', '/') + "usage.txt"; + else + path = "usage.txt"; + + IOUtil.copyResource (path, System.out); + } +} diff --git a/src/deltix/util/swing/Arrow.java b/src/deltix/util/swing/Arrow.java new file mode 100644 index 00000000..cbe9e21a --- /dev/null +++ b/src/deltix/util/swing/Arrow.java @@ -0,0 +1,204 @@ +package deltix.util.swing; + +import javax.swing.*; +import java.awt.*; + +import deltix.util.awt.*; + +/** + * Draws an arrow. + * + * @see deltix.util.awt.Arrows + */ +public class Arrow extends JComponent { + public static final int VERTICAL = 1; + public static final int HORIZONTAL = 2; + + private int mOrientation; + private int mPosition; + private int mStyle; + private Stroke mStroke; + private int mArrowHeadWidth; + private int mArrowHeadLength; + + public Arrow ( + int orientation, + int width, + int length + ) + { + this (orientation, Arrows.POSITION_END, Arrows.STYLE_FILLED, width, length); + } + + public Arrow ( + int orientation, + int position, + int style, + int width, + int length + ) + { + this ( + orientation, + position, + style, + width, + length, + Color.black, + new BasicStroke (1) + ); + } + + public Arrow ( + int orientation, + int position, + int style, + int width, + int length, + Color color, + Stroke stroke + ) + { + mOrientation = orientation; + mPosition = position; + mStyle = style; + mArrowHeadWidth = width; + mArrowHeadLength = length; + mStroke = stroke; + setForeground (color); + + Dimension prefSize = new Dimension (); + Dimension minSize = new Dimension (); + + if (mOrientation == VERTICAL) { + minSize.width = prefSize.width = mArrowHeadWidth; + minSize.height = mArrowHeadLength + 1; + prefSize.height = mArrowHeadLength * 2; + } + else { + minSize.height = prefSize.height = mArrowHeadWidth; + prefSize.width = mArrowHeadLength * 2; + minSize.width = mArrowHeadLength + 1; + } + + setPreferredSize (prefSize); + setMinimumSize (minSize); + } + + /** + * Returns the orientation property. + */ + public int getOrientation () { + return (mOrientation); + } + + /** + * Assigns the orientation property. + */ + public void setOrientation (int value) { + mOrientation = value; + } + + /** + * Returns the position property. + */ + public int getPosition () { + return (mPosition); + } + + /** + * Assigns the position property. + */ + public void setPosition (int value) { + mPosition = value; + } + + /** + * Returns the style property. + */ + public int getStyle () { + return (mStyle); + } + + /** + * Assigns the style property. + */ + public void setStyle (int value) { + mStyle = value; + } + + /** + * Returns the arrowHeadLength property. + */ + public int getArrowHeadLength () { + return (mArrowHeadLength); + } + + /** + * Assigns the arrowHeadLength property. + */ + public void setArrowHeadLength (int value) { + mArrowHeadLength = value; + } + + /** + * Returns the arrowHeadWidth property. + */ + public int getArrowHeadWidth () { + return (mArrowHeadWidth); + } + + /** + * Assigns the arrowHeadWidth property. + */ + public void setArrowHeadWidth (int value) { + mArrowHeadWidth = value; + } + + /** + * Returns the stroke property. + */ + public Stroke getStroke () { + return (mStroke); + } + + /** + * Assigns the stroke property. + */ + public void setStroke (Stroke value) { + mStroke = value; + } + + public void paint (Graphics g) { + int w = getWidth (); + int h = getHeight (); + int x0; + int y0; + int x1; + int y1; + + if (mOrientation == HORIZONTAL) { + y0 = y1 = h / 2; + x0 = 0; + x1 = w; + } + else { + x0 = x1 = w / 2; + y0 = 0; + y1 = h; + } + + Graphics2D g2 = (Graphics2D) g; + + g2.setColor (getForeground ()); + g2.setStroke (mStroke); + + Arrows.drawArrow ( + g, x0, y0, x1, y1, + mArrowHeadLength / 2, + mArrowHeadWidth / 2, + mPosition, + mStyle + ); + } +} diff --git a/src/deltix/util/swing/FileField.java b/src/deltix/util/swing/FileField.java new file mode 100644 index 00000000..78023fed --- /dev/null +++ b/src/deltix/util/swing/FileField.java @@ -0,0 +1,181 @@ +package deltix.util.swing; + +import java.text.*; +import java.io.*; +import java.util.*; +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; + +/** + * A combination of text field and a button. The button opens + * a file selector. User can see and type in the path into + * the text field without opening a file selector. This is suitable + * for forms where a form field has a file as its value. + */ +public class FileField extends JPanel { + public static final int VALID_ANY_PATH = 0; + public static final int VALID_EXISTING_DIR = 1; + public static final int VALID_EXISTING_FILE = 2; + public static final int VALID_EXISTING_OR_NEW_DIR = 3; + + public static final int VALID_ALLOW_NULL = 0x100; + + private static final ResourceBundle RB = + ResourceBundle.getBundle ("deltix.util.swing.ui"); + + private JFileChooser mFileChooser = new JFileChooser (); + private NonEmptyTextField mPathField = new NonEmptyTextField (true); + private JButton mDialogButton = new JButton ("..."); + private int mValidationMode = VALID_ANY_PATH; + + public FileField () { + super (new BorderLayout ()); + + add (mPathField, BorderLayout.CENTER); + add (mDialogButton, BorderLayout.EAST); + + mDialogButton.addActionListener ( + new ActionListener () { + public void actionPerformed (ActionEvent e) { + dialog (); + } + } + ); + + mFileChooser.setApproveButtonText (RB.getString ("selectFile")); + } + + /** + * If user types in a directory path, and the directory does not exist, + * create this directory. Failure to create this directory causes + * the control to fail validation. + */ + public void setValidationMode (int mode) { + mValidationMode = mode; + + switch (mValidationMode & 0xFF) { + case VALID_ANY_PATH: + mFileChooser.setFileSelectionMode (JFileChooser.FILES_AND_DIRECTORIES); + break; + + case VALID_EXISTING_DIR: + case VALID_EXISTING_OR_NEW_DIR: + mFileChooser.setFileSelectionMode (JFileChooser.DIRECTORIES_ONLY); + break; + + case VALID_EXISTING_FILE: + mFileChooser.setFileSelectionMode (JFileChooser.FILES_ONLY); + break; + } + } + + public void setEnabled (boolean flag) { + super.setEnabled (flag); + mPathField.setEnabled (flag); + mDialogButton.setEnabled (flag); + } + + public String getPath () throws ParsingException { + File f = getFile (); + + if (f == null) + return (null); + + return (f.getPath ()); + } + + private void complain (ParsingException px) + throws ParsingException + { + mPathField.complain (px); + throw (px); + } + + public File getFile () throws ParsingException { + if ((mValidationMode & VALID_ALLOW_NULL) != 0 && + mPathField.getText ().trim ().length () == 0) + return (null); + + String text = mPathField.getValue (); + File f = new File (text); + String path = f.getPath (); + + if (!f.isAbsolute ()) + complain (new ParsingException ("relativePath", path)); + + switch (mValidationMode & 0xFF) { + case VALID_EXISTING_DIR: + if (!f.isDirectory ()) + complain (new ParsingException ("notDir", path)); + break; + + case VALID_EXISTING_OR_NEW_DIR: + if (!f.isDirectory ()) { + int status = + JOptionPane.showOptionDialog ( + this, + MessageFormat.format ( + RB.getString ("confirmDirCreation"), + new Object [] { path } + ), + RB.getString ("confirmation"), + JOptionPane.YES_NO_OPTION, + JOptionPane.QUESTION_MESSAGE, + null, + null, + null + ); + + if (status != JOptionPane.YES_OPTION) { + mPathField.highlight (); + throw new ParsingException (); + } + + if (!f.mkdirs ()) + complain (new ParsingException ("notDir", path)); + } + break; + + case VALID_EXISTING_FILE: + if (!f.isFile ()) + complain (new ParsingException ("notFile", path)); + break; + } + + return (f); + } + + public void setPath (String value) { + mPathField.setText (value == null ? "" : value); + } + + public void setFile (File value) { + setPath (value == null ? "" : value.getPath ()); + } + + /** + * Exposes the embedded JFileChooser so caller can configure it. For + * example: field.fileChooser ().setFileFilter (...). + */ + public JFileChooser fileChooser () { + return (mFileChooser); + } + + private void dialog () { + String text = mPathField.getText (); + + if (text.length () != 0) + mFileChooser.setSelectedFile (new File (text)); + + int ret = mFileChooser.showOpenDialog (this); + + if (ret == JFileChooser.APPROVE_OPTION) + setFile (mFileChooser.getSelectedFile ()); + } + + public void complain (String errorMsg) { + mPathField.complain (errorMsg); + } +} + diff --git a/src/deltix/util/swing/FormTextField.java b/src/deltix/util/swing/FormTextField.java new file mode 100644 index 00000000..5fc1ae00 --- /dev/null +++ b/src/deltix/util/swing/FormTextField.java @@ -0,0 +1,48 @@ +package deltix.util.swing; + +import javax.swing.*; +import java.util.*; + +import deltix.util.*; + +/** + * Additional functionality to JTextField. + */ +public class FormTextField extends JTextField { + public FormTextField (String text, int columns) { + super (text, columns); + } + + public FormTextField (String text) { + super (text); + } + + public FormTextField (int columns) { + super (columns); + } + + public FormTextField () { + super (); + } + + public void highlight () { + requestFocus (); + select (0, getText ().length ()); + } + + public void complain (String errorMessage) { + JOptionPane.showMessageDialog ( + this, + errorMessage, + SwingUtil.ERROR_TITLE, + JOptionPane.ERROR_MESSAGE + ); + + highlight (); + } + + public void complain (Throwable t) { + complain (t.getLocalizedMessage ()); + } + +} diff --git a/src/deltix/util/swing/IntegerTextField.java b/src/deltix/util/swing/IntegerTextField.java new file mode 100644 index 00000000..2b23d7c1 --- /dev/null +++ b/src/deltix/util/swing/IntegerTextField.java @@ -0,0 +1,91 @@ +package deltix.util.swing; + +import java.util.*; +import java.text.*; +import javax.swing.*; + +/** + * A text field that parses the content as Integer. + */ +public class IntegerTextField extends ParsingTextField { + private int mValue; + private int mMinValue = Integer.MIN_VALUE; + private int mMaxValue = Integer.MAX_VALUE; + + /** + * Constructs a IntegerTextField with the specified value and + * size. + */ + public IntegerTextField (int value, int columns) { + super (String.valueOf (value), columns); + } + + /** + * Constructs a IntegerTextField with the specified value and + * size and min/max constraints. + */ + public IntegerTextField (int value, int columns, int min, int max) { + super (String.valueOf (value), columns); + mMinValue = min; + mMaxValue = max; + } + + /** + * Constructs a IntegerTextField with the specified String and + * size and min/max constraints. + */ + public IntegerTextField (String text, int columns, int min, int max) { + super (text, columns); + mMinValue = min; + mMaxValue = max; + } + + protected void doParse (String text) + throws ParsingException + { + try { + mValue = Integer.parseInt (text.trim ()); + } catch (NumberFormatException x) { + throw new ParsingException ("int", text); + } + if (mValue < mMinValue) + throw new ParsingException("minInt", new Object [] {text, + String.valueOf(mMinValue),String.valueOf(mMaxValue)}); + if (mValue > mMaxValue) + throw new ParsingException("maxInt", new Object [] {text, + String.valueOf(mMinValue),String.valueOf(mMaxValue)}); + } + + public void setMaxValue (int value) { + mMaxValue = value; + } + + public void setMinValue (int value) { + mMinValue = value; + } + + public int getMaxValue () { + return (mMaxValue); + } + + public int getMinValue () { + return (mMinValue); + } + + /** + * Returns the int value currently contained in the field. + * If a parsing error occurs, the field displays an error message, + * waits for the user to acknowledge it, sets focus on itself, + * then throws a ParsingException. + * + * @exception ParsingException When the parsing fails. + */ + public int getIntegerValue () throws ParsingException { + parse (); + return (mValue); + } + + public void setIntegerValue (int v) { + setText (String.valueOf (v)); + } +} diff --git a/src/deltix/util/swing/Line.java b/src/deltix/util/swing/Line.java new file mode 100644 index 00000000..48428c81 --- /dev/null +++ b/src/deltix/util/swing/Line.java @@ -0,0 +1,86 @@ +package deltix.util.swing; + +import javax.swing.*; +import java.awt.*; + +/** + * Draws a line + */ +public class Line extends JComponent { + public static final int VERTICAL = 1; + public static final int HORIZONTAL = 2; + + private int mOrientation; + private Stroke mStroke; + + public Line (int orientation) { + this (orientation, new BasicStroke (1)); + } + + public Line (int orientation, Stroke stroke) { + mOrientation = orientation; + mStroke = stroke; + } + + public Line (int orientation, Stroke stroke, Color color) { + this (orientation, stroke); + setForeground (color); + } + + /** + * Returns the orientation property. + */ + public int getOrientation () { + return (mOrientation); + } + + /** + * Assigns the orientation property. + */ + public void setOrientation (int value) { + mOrientation = value; + repaint (); + } + + /** + * Returns the stroke property. + */ + public Stroke getStroke () { + return (mStroke); + } + + /** + * Assigns the stroke property. + */ + public void setStroke (Stroke value) { + mStroke = value; + repaint (); + } + + public void paint (Graphics g) { + int w = getWidth (); + int h = getHeight (); + int x0; + int y0; + int x1; + int y1; + + if (mOrientation == HORIZONTAL) { + y0 = y1 = h / 2; + x0 = 0; + x1 = w; + } + else { + x0 = x1 = w / 2; + y0 = 0; + y1 = h; + } + + Graphics2D g2 = (Graphics2D) g; + + g2.setColor (getForeground ()); + g2.setStroke (mStroke); + + g2.drawLine (x0, y0, x1, y1); + } +} diff --git a/src/deltix/util/swing/NonEmptyTextField.java b/src/deltix/util/swing/NonEmptyTextField.java new file mode 100644 index 00000000..89a13af1 --- /dev/null +++ b/src/deltix/util/swing/NonEmptyTextField.java @@ -0,0 +1,85 @@ +package deltix.util.swing; + +import java.util.*; +import java.text.*; +import javax.swing.*; + +/** + * A text field that forces the content to be non-empty. + * Also, this field can be configured to automatically + * trim its value. + */ +public class NonEmptyTextField extends ParsingTextField { + private String mValue; + private boolean mTrim; + + /** + * Constructs a NonEmptyTextField with the specified value and size. + * + * @trim Whether to automatically trim the value. + */ + public NonEmptyTextField (String value, int columns, boolean trim) { + super (value, columns); + mTrim = trim; + } + + /** + * Constructs a NonEmptyTextField with the specified value. + * + * @trim Whether to automatically trim the value. + */ + public NonEmptyTextField (String value, boolean trim) { + super (value); + mTrim = trim; + } + + /** + * Constructs a NonEmptyTextField with the specified size. + * + * @trim Whether to automatically trim the value. + */ + public NonEmptyTextField (int columns, boolean trim) { + super (columns); + mTrim = trim; + } + + /** + * Constructs a NonEmptyTextField. + * + * @trim Whether to automatically trim the value. + */ + public NonEmptyTextField (boolean trim) { + super (); + mTrim = trim; + } + + protected void doParse (String text) + throws ParsingException + { + mValue = text; + + if (mTrim) + mValue = mValue.trim (); + + if (mValue.length () == 0) + throw new ParsingException ("empty", (String) null); + } + + /** + * Returns the text value currently contained in the field. + * If the value is empty, the field displays an error message, + * waits for the user to acknowledge it, sets focus on itself, + * then throws a ParsingException. + * + * @exception ParsingException When the parsing fails. + */ + public String getValue () throws ParsingException { + parse (); + return (mValue); + } + + public boolean isEmpty () { + String text = getText(); + return (text == null || text.trim().length() == 0); + } +} diff --git a/src/deltix/util/swing/ParsingException.java b/src/deltix/util/swing/ParsingException.java new file mode 100644 index 00000000..791cb7c5 --- /dev/null +++ b/src/deltix/util/swing/ParsingException.java @@ -0,0 +1,21 @@ +package deltix.util.swing; + +import deltix.util.lang.*; + +public class ParsingException extends LocalizableException { + public ParsingException (String key, String badText) { + super (key, new Object [] { badText }); + } + + public ParsingException (String key, String badText, Exception x) { + super (key, new Object [] { badText }, x); + } + + public ParsingException (String key, Object [] badObjects) { + super (key, badObjects ); + } + + public ParsingException () { + super (); + } +} diff --git a/src/deltix/util/swing/ParsingTextField.java b/src/deltix/util/swing/ParsingTextField.java new file mode 100644 index 00000000..a297e23b --- /dev/null +++ b/src/deltix/util/swing/ParsingTextField.java @@ -0,0 +1,47 @@ +package deltix.util.swing; + +import javax.swing.*; +import java.util.*; + +import deltix.util.*; + +/** + * Base class for implementing text fields that parse the text according + * to some rules, such as expecting a numeric value. If an exception + * is thrown while parsing, this field will display an error message, + * select its entire text, and grab focus. + */ +public abstract class ParsingTextField extends FormTextField { + protected ParsingTextField (String text, int columns) { + super (text, columns); + } + + protected ParsingTextField (String text) { + super (text); + } + + protected ParsingTextField (int columns) { + super (columns); + } + + protected ParsingTextField () { + super (); + } + + /** + * Override to parse the text. + */ + protected abstract void doParse (String text) + throws ParsingException; + + protected final void parse () throws ParsingException { + String text = getText (); + + try { + doParse (text); + } catch (ParsingException x) { + complain (x); + throw x; + } + } +} diff --git a/src/deltix/util/swing/SimpleAction.java b/src/deltix/util/swing/SimpleAction.java new file mode 100644 index 00000000..9b4622f5 --- /dev/null +++ b/src/deltix/util/swing/SimpleAction.java @@ -0,0 +1,113 @@ +package deltix.util.swing; + +import java.lang.reflect.*; +import java.awt.event.*; + +/** + * Extension of StandardAction, which delegates the action to a void no-arguments + * method whose name coincides with the name of the action. Also, the supplied + * object may provide a public boolean nameEnabled () method, + * to which the action will then delegate its own isEnabled method. + * Please see + * {@link deltix.util.swing.StandardAction} documentation for a detailed description + * of how action properties are retrieved, based on the package of the object and + * the name key. The supplied object must be of a public class. + *

+ * Usage: + *

+ *private Action          MY_ACTION =
+ *    new SimpleAction (this, "methodName");
+ *
+ */ +public final class SimpleAction extends StandardAction { + private static final Class [] NO_ARGS_SIG = { }; + + private Object mObject; + private Method mMethod; + private Method mCheckMethod; + + /** + * Constructs a StandardAction which will call a method of the + * supplied object, whose name is identical to the name key. + * + * @exception RuntimeException If such a method was not found. + */ + public SimpleAction (Object delegate, String nameKey, String imageType) { + super (delegate.getClass (), nameKey, imageType); + mObject = delegate; + + Class c = mObject.getClass (); + + while (c != Object.class) { + try { + mMethod = c.getDeclaredMethod (nameKey, NO_ARGS_SIG); + break; + } catch (NoSuchMethodException x) { + } + + c = c.getSuperclass (); + } + + if (mMethod == null) + throw new RuntimeException ( + "Did not find public void " + nameKey + " () in class " + + mObject.getClass () + " or any of its ancestors." + ); + + try { + mCheckMethod = c.getDeclaredMethod (nameKey + "Enabled", NO_ARGS_SIG); + } catch (NoSuchMethodException x) { + mCheckMethod = null; + } + } + + /** + * Constructs a StandardAction which will call a method of the + * supplied delegateClass on the supplied object, whose name is identical + * to the name key. + * + * @exception RuntimeException If such a method was not found. + */ + public SimpleAction (Class delegateClass, Object delegate, String nameKey, String imageType) { + super (delegateClass, nameKey, imageType); + mObject = delegate; + + try { + mMethod = delegateClass.getDeclaredMethod (nameKey, NO_ARGS_SIG); + } catch (NoSuchMethodException x) { + throw new RuntimeException (x.toString ()); + } + } + + /** + * Same as above, but hardcodes image type to gif. + */ + public SimpleAction (Object delegate, String nameKey) { + this (delegate, nameKey, "gif"); + } + + /** + * Same as above, but allows for specifying delegateClass. + */ + public SimpleAction (Class delegateClass, Object delegate, String nameKey) { + this (delegateClass, delegate, nameKey, "gif"); + } + + public void actionPerformed (ActionEvent e) { + try { + mMethod.invoke (mObject, (Object []) null); /** @todo: casting to (Object[]) to suppress javac v1.5 warning */ + } catch (IllegalAccessException iax) { + throw new RuntimeException ( + "Failed to invoke " + mMethod + ": " + iax.toString () + ); + } catch (InvocationTargetException itx) { + Throwable cause = itx.getTargetException (); + if (cause instanceof RuntimeException) + throw ((RuntimeException) cause); + else if (cause instanceof Error) + throw ((Error) cause); + else + throw new RuntimeException (cause); + } + } +} diff --git a/src/deltix/util/swing/StandardAction.java b/src/deltix/util/swing/StandardAction.java new file mode 100644 index 00000000..667c1c57 --- /dev/null +++ b/src/deltix/util/swing/StandardAction.java @@ -0,0 +1,89 @@ +package deltix.util.swing; + +import javax.swing.AbstractAction; +import java.util.ResourceBundle; +import java.util.MissingResourceException; +import javax.swing.KeyStroke; + + +/** + * Base class for Action implementations. Action properties + * name, tooltip and icon are retrieved, based on a single key. + *

+ * Usage: + *

+ *private Action          MY_ACTION =
+ *    new StandardAction (MyClass.class, "myKey") {
+ *        public void actionPerformed (ActionEvent e) { doSomething (); }
+ *    };
+ *
+ * + */ +public abstract class StandardAction extends AbstractAction { + /** + * Creates a standard action as follows: + * + *
    + *
  1. Figures out the package name of the specified class. + *
  2. Loads the icon image from this package's resource path, + * where the icon name is same as the nameKey argument; + * extension imageType. + *
  3. The action name is retrieved from the resource bundle + * called actions, under the same package, under the key of + * nameKey. + *
  4. The tooltip text is retrieved from the resource bundle + * called actions, under the same package, under the key of + * nameKey.tt. + *
+ * + * @param nameKey Used to look up the action properties. + */ + public StandardAction (Class forClass, String nameKey, String imageType) { + String className = forClass.getName (); + int dot = className.lastIndexOf ('.'); + + if (dot < 0) + dot = 0; + + String packName = className.substring (0, dot); + String packPath = packName.replace ('.', '/'); + ResourceBundle rb = ResourceBundle.getBundle (packPath + "/actions"); + + try { + putValue (NAME, rb.getString (nameKey)); + } catch (MissingResourceException mrx) { + // Ignore the name + } + + putValue (SHORT_DESCRIPTION, rb.getString (nameKey + ".tt")); + + putValue ( + SMALL_ICON, + SwingUtil.loadIcon ( + packPath + "/" + nameKey + "." + imageType + ) + ); + + // kbd accelerator (hot key) + try { + putValue (ACCELERATOR_KEY, KeyStroke.getKeyStroke(rb.getString (nameKey + ".key"))); + } catch (MissingResourceException mrx) { + // Ignore the missing hotkey + } + + // mnemonic + try { + putValue (MNEMONIC_KEY, new Integer(rb.getString (nameKey + ".mnemonic").charAt(0))); + } catch (MissingResourceException mrx) { + // Ignore the missing mnemonic + } + + } + + /** + * Same as above, hardcodes image type to gif. + */ + public StandardAction (Class forClass, String nameKey) { + this (forClass, nameKey, "gif"); + } +} diff --git a/src/deltix/util/swing/StandardDialog.java b/src/deltix/util/swing/StandardDialog.java new file mode 100644 index 00000000..b46ac710 --- /dev/null +++ b/src/deltix/util/swing/StandardDialog.java @@ -0,0 +1,61 @@ +package deltix.util.swing; + +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; + +/** + * Dialog with a number of named buttons at the bottom. Non-modal by default, + * don't forget to call setModal (true) if desired. + */ +public class StandardDialog extends JDialog { + private int mStatus; + private JPanel mMainPanel = new JPanel (); + + public int getStatus () { + return (mStatus); + } + + public JPanel getMainPanel () { + return (mMainPanel); + } + + /** + * Child classes override for validation + */ + public boolean acceptStdAction (int status) { + return (true); + } + + public StandardDialog (Component parent, final String [] buttonNames) { + super (JOptionPane.getFrameForComponent (parent)); + + Container cp = getContentPane (); + cp.setLayout (new BorderLayout ()); + cp.add (mMainPanel, BorderLayout.CENTER); + + JPanel btns = new JPanel (); + cp.add (btns, BorderLayout.SOUTH); + + for (int ii = 0; ii < buttonNames.length; ii++) { + final int status = ii; + + JButton btn = + new JButton ( + new AbstractAction (buttonNames [ii]) { + public void actionPerformed (ActionEvent e) { + if (acceptStdAction (status)) { + mStatus = status; + dispose (); + } + } + } + ); + + btns.add (btn); + + if (ii == 0) + getRootPane ().setDefaultButton (btn); + } + } +} diff --git a/src/deltix/util/swing/SwingUtil.java b/src/deltix/util/swing/SwingUtil.java new file mode 100644 index 00000000..85086d69 --- /dev/null +++ b/src/deltix/util/swing/SwingUtil.java @@ -0,0 +1,168 @@ +package deltix.util.swing; + +import java.awt.*; +import java.io.*; +import java.util.*; +import java.util.logging.*; +import javax.swing.*; + +import deltix.util.Util; +import deltix.util.io.StreamPump; + +/** + * Colleciton of static utilities + */ +public abstract class SwingUtil { + public static final String ERROR_TITLE = + ResourceBundle.getBundle ("deltix/util/swing/exceptions").getString ("errorTitle"); + + public static void expandEntireTree (JTree tree) { + for (int ii = 0; ii < tree.getRowCount(); ii++) { + tree.expandRow (ii); + } + } + + public static ResourceBundle getBundle (String name) { + try { + return (ResourceBundle.getBundle (name)); + } catch (MissingResourceException mrx) { + staticHandle (mrx); + System.exit (1); + return (null); + } + } + + public static ImageIcon loadIcon (String relPath) { + Image img = loadImage (relPath); + + return (img == null ? null : new ImageIcon (img)); + } + + public static Image loadImage (String relPath) { + InputStream is = + Util.class.getClassLoader ().getResourceAsStream (relPath); + + if (is == null) + return (null); + + try { + return (loadImage (is)); + } catch (Throwable x) { + Util.LOGGER.log ( + Level.WARNING, + "Failed to read image from relative path " + relPath, + x + ); + return (null); + } finally { + Util.close (is); + } + } + + public static Image loadImage (File file) throws IOException { + InputStream is = new FileInputStream (file); + + try { + return (loadImage (is)); + } catch (Throwable x) { + Util.LOGGER.log ( + Level.WARNING, + "Failed to read image file " + file, + x + ); + return (null); + } finally { + Util.close (is); + } + } + + public static Image loadImage (InputStream is) + throws InterruptedException, IOException + { + ByteArrayOutputStream baos = new ByteArrayOutputStream (100000); + + try { + StreamPump.pump (is, baos); + } finally { + Util.close (is); + } + + return (loadImage (baos.toByteArray ())); + } + + public static Image loadImage (byte [] bytes) + throws InterruptedException + { + Toolkit tk = Toolkit.getDefaultToolkit (); + Image img = tk.createImage (bytes); + + ensureImageIsLoaded (img); + + return (img); + } + + public static Image ensureImageIsLoaded (Image img) + throws InterruptedException + { + Toolkit tk = Toolkit.getDefaultToolkit (); + + while (!tk.prepareImage (img, -1, -1, null)) + Thread.sleep (1); + + return (img); + } + + protected SwingUtil () { + } + + private static String getMsg (Throwable x) { + String msg = x.getLocalizedMessage (); + + if (msg == null || msg.length () == 0) + return ("Exception: " + x.getClass ().getName ()); + + return (msg); + } + + public static void staticHandle ( + Component parent, + Throwable x, + Logger logger, + Level logLevel + ) + { + x = Util.unwrap (x); + + if (logger != null) + logger.log (logLevel, "Uncaught Exception", x); + + JOptionPane.showMessageDialog ( + parent, + getMsg (x), + x.getClass ().getName (), + JOptionPane.ERROR_MESSAGE + ); + } + + public static void staticHandle (Component parent, Throwable x) { + staticHandle (parent, x, Util.LOGGER, Level.WARNING); + } + + public static void staticHandle (Throwable x) { + staticHandle (null, x); + } + + public static void asyncInvoke (Runnable r) { + if (SwingUtilities.isEventDispatchThread()) + r.run(); + else + SwingUtilities.invokeLater (r); + } + + public static void setWindowsLookAndFeel () { + try { + UIManager.setLookAndFeel ("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); + } catch (Throwable e) { + } + } +} diff --git a/src/deltix/util/swing/VerticalForm.java b/src/deltix/util/swing/VerticalForm.java new file mode 100644 index 00000000..f9e799c7 --- /dev/null +++ b/src/deltix/util/swing/VerticalForm.java @@ -0,0 +1,145 @@ +package deltix.util.swing; + +import java.util.*; +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; + +public class VerticalForm extends JPanel { + private GridBagConstraints mC = new GridBagConstraints (); + private Set mSwitchComponents = new HashSet (); + + public VerticalForm () { + super (new GridBagLayout ()); + + mC.gridy = 0; + mC.insets.left = 4; + mC.insets.right = 4; + mC.insets.top = 4; + mC.insets.bottom = 4; + + addContainerListener ( + new ContainerListener () { + public void componentAdded (ContainerEvent e) { + Component c = e.getChild (); + + if (mSwitchComponents.contains (c)) + c.setEnabled (isEnabled ()); + } + + public void componentRemoved (ContainerEvent e) { + mSwitchComponents.remove (e.getChild ()); + } + } + ); + } + + /** + * Adds a spring with a 1.0 weight + */ + public void addSpring () { + addSpring (1.0); + } + + /** + * Adds a spring, i.e. expandable space. This is useful if the form + * consists of vertically non-expandable rows, which is the most + * frequent situation. The spring is where the space will be filled. + */ + public void addSpring (double weighty) { + mC.gridwidth = 2; + mC.gridx = 0; + mC.fill = GridBagConstraints.VERTICAL; + mC.weighty = weighty; + add (new JLabel (), mC); + mC.gridy++; + } + + private void setWeightAndFill (JComponent comp) { + if (comp instanceof JTextArea || + comp instanceof JScrollPane) + { + mC.weightx = 1; + mC.weighty = 1; + mC.fill = GridBagConstraints.BOTH; + } + else if (comp instanceof AbstractButton || comp instanceof JSpinner) { + mC.weightx = 0; + mC.weighty = 0; + mC.fill = GridBagConstraints.NONE; + mC.anchor = GridBagConstraints.WEST; + } + else { + mC.weightx = 1; + mC.weighty = 0; + mC.fill = GridBagConstraints.HORIZONTAL; + } + } + + public void addRow (JComponent comp) { + addRow (comp, true); + } + + public void addRow (JComponent comp, boolean disableWithForm) { + if (disableWithForm) + mSwitchComponents.add (comp); + + mC.gridx = 0; + mC.gridwidth = 2; + + setWeightAndFill (comp); + add (comp, mC); + + mC.gridy++; + } + + public void addLine () { + addRow (new Line (Line.HORIZONTAL)); + } + + public void addField (String label, JComponent comp) { + addField (label, comp, !(comp instanceof JLabel)); + } + + public void addField (String label, JComponent comp, boolean disableWithForm) { + addField (new JLabel (label), comp, disableWithForm); + } + + public void addField (JLabel jl, JComponent comp) { + addField (jl, comp, !(comp instanceof JLabel)); + } + + public void addField (JLabel jl, JComponent comp, boolean disableWithForm) { + if (disableWithForm) + mSwitchComponents.add (comp); + + mC.gridwidth = 1; + mC.gridx = 0; + mC.weightx = 0; + mC.weighty = 0; + mC.anchor = GridBagConstraints.WEST; + + add (jl, mC); + + mC.gridx = 1; + + setWeightAndFill (comp); + + add (comp, mC); + + mC.gridy++; + } + + public void setEnabled (boolean flag) { + super.setEnabled (flag); + + int numComps = getComponentCount (); + + for (int ii = 0; ii < numComps; ii++) { + Component c = getComponent (ii); + + if (mSwitchComponents.contains (c)) + c.setEnabled (flag); + } + } +} diff --git a/src/deltix/util/swing/treeedit/NodeAdapter.java b/src/deltix/util/swing/treeedit/NodeAdapter.java new file mode 100644 index 00000000..81d5bc8d --- /dev/null +++ b/src/deltix/util/swing/treeedit/NodeAdapter.java @@ -0,0 +1,174 @@ +/* + * NodeAdapter.java + * + * Created on July 13, 2004, 10:34 AM + */ + +package deltix.util.swing.treeedit; + +import java.util.*; +import javax.swing.*; +import javax.swing.tree.*; + +import deltix.util.collections.*; + +/** + * Internal class that adapts the {@link TreeEditorNode} class to JTree. + */ +final class NodeAdapter implements TreeNode { + private TreeEditorPanel mPanel; + private NodeAdapter mParent; + private TreeEditorNode mUserNode; + private boolean mChildrenUpdated = false; + private NodeAdapter [] mChildNodeAdapters; + + public NodeAdapter (TreeEditorPanel panel, TreeEditorNode userNode) { + mParent = null; + mPanel = panel; + mUserNode = userNode; + mUserNode.setCallback (this); + } + + public NodeAdapter (NodeAdapter parent, TreeEditorNode userNode) { + mParent = parent; + mPanel = parent.mPanel; + mUserNode = userNode; + mUserNode.setCallback (this); + } + + void updateChildren () { + if (mChildrenUpdated) + return; + + int numChildren = mUserNode.getNumChildren (); + + if (numChildren == TreeEditorNode.LEAF_NODE) { + mChildNodeAdapters = null; + return; + } + + mChildNodeAdapters = new NodeAdapter [numChildren]; + + for (int ii = 0; ii < numChildren; ii++) + mChildNodeAdapters [ii] = + new NodeAdapter (this, mUserNode.getChild (ii)); + + mChildrenUpdated = true; + } + + public Enumeration children () { + updateChildren (); + return (new ArrayEnumeration (mChildNodeAdapters)); + } + + public boolean getAllowsChildren () { + updateChildren (); + return (mChildNodeAdapters != null); + } + + public TreeNode getChildAt (int idx) { + updateChildren (); + return (mChildNodeAdapters [idx]); + } + + public int getChildCount () { + updateChildren (); + return (mChildNodeAdapters == null ? 0 : mChildNodeAdapters.length); + } + + public int getIndex (TreeNode treeNode) { + updateChildren (); + if (mChildNodeAdapters == null) + return (-1); + + for (int ii = 0; ii < mChildNodeAdapters.length; ii++) + if (mChildNodeAdapters [ii] == treeNode) + return (ii); + + return (-1); + } + + public TreeNode getParent () { + return (mParent); + } + + public boolean isLeaf () { + updateChildren (); + return (mChildNodeAdapters == null); + } + + TreeEditorNode getUserNode () { + return (mUserNode); + } + + void reload () { + mChildrenUpdated = false; + updateChildren (); + mPanel.getTreeModel ().reload (this); + } + + TreePath getPath () { + int depth = 1; + TreeNode node = this; + + for (;;) { + TreeNode next = node.getParent (); + + if (next == null) + break; + + depth++; + node = next; + } + + Object [] path = new Object [depth]; + + node = this; + + for (;;) { + depth--; + path [depth] = node; + + if (depth == 0) + break; + + node = node.getParent (); + } + + return (new TreePath (path)); + } + + final void select () { + /** + * Reset selection momentarily in order to + * force the reloading of the node's form. + */ + mPanel.getTree ().setSelectionPath (null); + mPanel.getTree ().setSelectionPath (getPath ()); + } + + final void selectAndStartEditing () { + select (); + mPanel.edit (); + } + + final void updateFormHeaderFromEditedNode () { + mPanel.updateFormHeaderFromEditedNode (); + } + + final void editInCreationMode (TreeEditorNode node) { + mPanel.editInCreationMode (node); + } + + final void setSaveEnabled (boolean flag) { + mPanel.setSaveEnabled (flag); + } + + final void setCancelEnabled (boolean flag) { + mPanel.setCancelEnabled (flag); + } + + final void show () { + mPanel.getTree ().expandPath (getPath ()); + } +} diff --git a/src/deltix/util/swing/treeedit/NodeChangeListener.java b/src/deltix/util/swing/treeedit/NodeChangeListener.java new file mode 100644 index 00000000..ae618651 --- /dev/null +++ b/src/deltix/util/swing/treeedit/NodeChangeListener.java @@ -0,0 +1,8 @@ +package deltix.util.swing.treeedit; + +/** + * Called when a node is edited and successfully saved. + */ +public interface NodeChangeListener { + public void nodeChanged (TreeEditorNode node); +} diff --git a/src/deltix/util/swing/treeedit/NodeRenderer.java b/src/deltix/util/swing/treeedit/NodeRenderer.java new file mode 100644 index 00000000..e57a4d92 --- /dev/null +++ b/src/deltix/util/swing/treeedit/NodeRenderer.java @@ -0,0 +1,44 @@ +package deltix.util.swing.treeedit; + +import java.util.*; +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +import javax.swing.tree.*; + +import deltix.util.swing.*; + +class NodeRenderer extends DefaultTreeCellRenderer { + private Font mDefaultFont = getFont (); + + public Component getTreeCellRendererComponent ( + JTree jTree, + Object node, + boolean selected, + boolean expanded, + boolean leaf, + int row, + boolean hasFocus + ) + { + JLabel label = (JLabel) + super.getTreeCellRendererComponent ( + jTree, + node, + selected, + expanded, + leaf, + row, + hasFocus + ); + + /** + * Reset font because it may have been tweaked + */ + label.setFont (mDefaultFont); + + NodeAdapter anode = (NodeAdapter) node; + + return (anode.getUserNode ().render (selected, hasFocus, label)); + } +} diff --git a/src/deltix/util/swing/treeedit/Test.java b/src/deltix/util/swing/treeedit/Test.java new file mode 100644 index 00000000..271d8191 --- /dev/null +++ b/src/deltix/util/swing/treeedit/Test.java @@ -0,0 +1,113 @@ +/* + * Test.java + * + * Created on July 13, 2004, 11:07 AM + */ + +package deltix.util.swing.treeedit; + +import java.util.*; +import javax.swing.*; +import javax.swing.event.*; +import java.awt.*; +import java.awt.event.*; + +import deltix.util.swing.*; + +/** + * + */ +public class Test extends TreeEditorNode { + private String mLabel; + private int mLevel; + private ArrayList mChildren = new ArrayList (); + + public Test (int level) { + mLevel = level; + mLabel = mLevel + "-" + hashCode (); + + if (mLevel < 4) + mChildren.add (new Test (mLevel + 1)); + } + + public int getNumChildren () { + return (mChildren == null ? LEAF_NODE : mChildren.size ()); + } + + public TreeEditorNode getChild (int idx) { + return ((TreeEditorNode) mChildren.get (idx)); + } + + public String getLabelText () { + return (mLabel); + } + + /** + * Return the color for the label to display, or null. + */ + public Color getColor () { + int k = (mLevel * 16) % 256; + + return (new Color (k, 255 - k, 255 - k)); + } + + public JPopupMenu getMenu () { + JPopupMenu menu = new JPopupMenu (); + + menu.add ( + new JMenuItem ( + new AbstractAction ("Add Child") { + public void actionPerformed (ActionEvent e) { + addChild (); + } + } + ) + ); + + return (menu); + } + + private IntegerTextField mLevelField; + private JTextField mLabelField; + + public void configureForm (VerticalForm form) { + mLevelField = new IntegerTextField (mLevel, 5); + mLabelField = new JTextField (getLabelText (), 16); + + form.addField ("Level", mLevelField); + form.addField ("Label", mLabelField); + } + + public boolean acceptChanges () { + try { + String lbl = mLabelField.getText (); + int lvl = mLevelField.getIntegerValue (); + + if (!super.acceptChanges ()) + return (false); + + mLabel = lbl; + mLevel = lvl; + reload (); + return (true); + } catch (ParsingException x) { + return (false); + } + } + + private void addChild () { + mChildren.add (new Test (mLevel + 1)); + reload (); + } + + public static void main (String [] args) throws Exception { + JFrame f = new JFrame ("test"); + TreeEditorPanel ted = new TreeEditorPanel (new Test (0)); + f.getContentPane ().add (ted); + f.setDefaultCloseOperation (f.EXIT_ON_CLOSE); + f.setSize (800, 600); + f.setVisible (true); + + ted.setDividerLocation (0.5); + } +} diff --git a/src/deltix/util/swing/treeedit/TreeEditorNode.java b/src/deltix/util/swing/treeedit/TreeEditorNode.java new file mode 100644 index 00000000..fdd2633c --- /dev/null +++ b/src/deltix/util/swing/treeedit/TreeEditorNode.java @@ -0,0 +1,262 @@ +package deltix.util.swing.treeedit; + +import java.util.*; +import java.awt.*; +import javax.swing.*; + +import deltix.util.swing.*; + +/** + * Interface implemented by the user of the Tree Editor component. + */ +public abstract class TreeEditorNode { + public static final int LEAF_NODE = -1; + + public interface Filter { + public boolean accept (TreeEditorNode node); + } + + private NodeAdapter mCallback; + + void setCallback (NodeAdapter a) { + mCallback = a; + } + + /** + * Return the label to display, or null. + */ + public String getLabelText () { + return (null); + } + + /** + * Return the font for the label to display. + */ + public Font getFont (Font defFont) { + return (defFont); + } + + /** + * Return the color for the label to display, or null. + */ + public Color getColor () { + return (null); + } + + /** + * Return an icon to display, or null. + */ + public Icon getIcon () { + return (null); + } + + /** + * User can override this method instead of {@link #getColor}, + * {@link #getFont}, {@link #getLabelText} and {@link #getIcon}. Default + * implementation sets the above properties in the label. + */ + public void configureLabel ( + JLabel label, + boolean selected, + boolean hasFocus + ) + { + label.setOpaque (!selected); + + Color c = getColor (); + Font f = getFont (label.getFont ()); + + if (c != null) + label.setForeground (c); + + if (f != null) + label.setFont (f); + + Icon icon = getIcon (); + + label.setIcon (icon); + label.setDisabledIcon (icon); + label.setText (getLabelText ()); + } + + /** + * User can override this method instead of {@link #configureLabel}, + * to realize the full power of JTree. + */ + public JComponent render ( + boolean selected, + boolean hasFocus, + JLabel defaultRendering + ) + { + configureLabel (defaultRendering, selected, hasFocus); + return (defaultRendering); + } + + /** + * Return a popup menu to show when this node is activated + * by a popup trigger (such as a right mouse button click). + * Return null if no menu should be shown. + */ + public JPopupMenu getMenu () { + return (null); + } + + /** + * Return the number of children, or {@link #LEAF_NODE}. + * Default implementation returns {@link #LEAF_NODE}. + */ + public int getNumChildren () { + return (LEAF_NODE); + } + + /** + * Returns a child by index. Default implementation throws an + * IllegalStateException. + */ + public TreeEditorNode getChild (int idx) { + throw new IllegalStateException ("this is a leaf node"); + } + + /** + * Determine whether there is anything to edit. Default implementation + * returns true. + */ + public boolean isEditable () { + return (true); + } + + /** + * Called to add content to an empty form. + * Default implementation does nothing. + */ + public void configureForm (VerticalForm form) { + } + + /** + * Called after the form becomes editable. + */ + public void beginEdit (VerticalForm form) { + } + + /** + * Called after the node is succesfully edited in creation mode. + */ + public void created () { + } + + /** + * Called after the user fails to complete the creation process. + */ + public void creationCanceled () { + } + + /** + * Called when user hits "Save". Return whether it is OK to proceed + * with saving the values. If false is returned, the values in the + * user object must not be edited. + */ + public boolean acceptChanges () { + return (true); + } + + /** + * Updates the display of this node and its children. + */ + public final void reload () { + if (mCallback != null) + mCallback.reload (); + } + + /** + * Select this node + */ + public final void select () { + if (mCallback != null) + mCallback.select (); + } + + /** + * Select this node and start editing it + */ + public final void selectAndStartEditing () { + mCallback.selectAndStartEditing (); + } + + /** + * Edit the specified node (usually unconnected to the tree). + * If editing succeeds, node gets an additional created () notification. + * If editing is canceled, node gets a creationCanceled () notification. + */ + public final void editInCreationMode (TreeEditorNode node) { + mCallback.editInCreationMode (node); + } + + public final void updateFormHeaderFromEditedNode () { + mCallback.updateFormHeaderFromEditedNode (); + } + + /** + * Returns the parent TreeEditorNode + */ + public TreeEditorNode getParent () { + NodeAdapter nap = (NodeAdapter) mCallback.getParent (); + + return (nap == null ? null : nap.getUserNode ()); + } + + /** + * Sets the accessibility of the Save button + */ + protected final void setSaveEnabled (boolean flag) { + mCallback.setSaveEnabled (flag); + } + + /** + * Sets the accessibility of the Cancel button - use with caution, + * user should normally be able to cancel. + */ + protected final void setCancelEnabled (boolean flag) { + mCallback.setCancelEnabled (flag); + } + + /** + * Expand the tree and scroll to make this node visible + */ + public void show () { + mCallback.show (); + } + + public final TreeEditorNode find (Filter filter) { + if (mCallback == null) + throw new IllegalStateException (this + " is not in the tree"); + + if (filter.accept (this)) + return (this); + + mCallback.updateChildren (); + + int numChildren = getNumChildren (); + + for (int ii = 0; ii < numChildren; ii++) { + TreeEditorNode node = getChild (ii).find (filter); + + if (node != null) + return (node); + } + + return (null); + } + + public final TreeEditorNode findNodeByType (final Class type) { + return ( + find ( + new Filter () { + public boolean accept (TreeEditorNode node) { + return (type.isAssignableFrom (node.getClass ())); + } + } + ) + ); + } +} diff --git a/src/deltix/util/swing/treeedit/TreeEditorPanel.java b/src/deltix/util/swing/treeedit/TreeEditorPanel.java new file mode 100644 index 00000000..6d42d007 --- /dev/null +++ b/src/deltix/util/swing/treeedit/TreeEditorPanel.java @@ -0,0 +1,264 @@ +package deltix.util.swing.treeedit; + +import java.io.*; +import java.util.*; +import java.awt.*; +import java.awt.event.*; +import javax.swing.*; +import javax.swing.tree.*; +import javax.swing.event.*; +import javax.swing.border.*; + +import deltix.util.swing.*; + +public class TreeEditorPanel extends JSplitPane { + private final Action EDIT_ACTION = + new SimpleAction (this, "edit"); + + private final Action SAVE_ACTION = + new SimpleAction (this, "save"); + + private final Action CANCEL_ACTION = + new SimpleAction (this, "cancel"); + + public static final Border HEADER_BORDER = + BorderFactory.createEmptyBorder (3, 24, 3, 24); + + private static final Color mDisabledColor = new Color (0xF8F8F8); + private static final Color mEnabledColor = new Color (0xFFFFFF); + + private DefaultTreeModel mTreeModel; + private JTree mTree; + private JLabel mStockHeader = new JLabel (" "); + private JPanel mFormPanel = new JPanel (new BorderLayout ()); + private JPanel mBottom = new JPanel (new FlowLayout ()); + private VerticalForm mForm; + private JComponent mFormHeader = null; + private TreeEditorNode mSelectedNode; + private TreeEditorNode mEditedNode; + private boolean mCreationMode; + private JButton mEditBtn = new JButton (EDIT_ACTION); + private JButton mSaveBtn = new JButton (SAVE_ACTION); + private JButton mCancelBtn = new JButton (CANCEL_ACTION); + private Collection mNodeChangeListeners = + new HashSet (); + + public TreeEditorPanel (TreeEditorNode root) { + super (HORIZONTAL_SPLIT); + + mTreeModel = new DefaultTreeModel (new NodeAdapter (this, root)); + mTree = new JTree (mTreeModel); + mTree.setShowsRootHandles (true); + mTree.setCellRenderer (new NodeRenderer ()); + mTree.addMouseListener ( + new MouseAdapter () { + public void mousePressed (MouseEvent e) { + if (e.isPopupTrigger ()) { + popup (e.getX (), e.getY ()); + } + } + + public void mouseReleased (MouseEvent e) { + if (e.isPopupTrigger ()) { + popup (e.getX (), e.getY ()); + } + } + } + ); + + mTree.addTreeSelectionListener ( + new TreeSelectionListener () { + public void valueChanged (TreeSelectionEvent e) { + selectionChanged (e.getNewLeadSelectionPath ()); + } + } + ); + + setLeftComponent (new JScrollPane (mTree)); + + mForm = new VerticalForm (); + JScrollPane scroller = new JScrollPane (mForm); + + mFormPanel.add (scroller, BorderLayout.CENTER); + mFormPanel.add (mBottom, BorderLayout.SOUTH); + + setRightComponent (mFormPanel); + setEditing (null); + EDIT_ACTION.setEnabled (false); + } + + DefaultTreeModel getTreeModel () { + return (mTreeModel); + } + + JTree getTree () { + return (mTree); + } + + /** + * Controls the visibility of buttons such as "Edit", "Save" and + * "Cancel". Applications that use the tree editor as a slave + * might set this to false. + */ + public void setBottomButtonsVisible (boolean flag) { + mBottom.setVisible (flag); + } + + public void save () { + if (mEditedNode.acceptChanges ()) { + TreeEditorNode node = mEditedNode; + + setEditing (null); + + if (mCreationMode) { + node.created (); + node.select (); + } + + setFormFromNode (mSelectedNode); + + fireNodeChanged (node); + } + } + + public void cancel () { + if (mCreationMode) + mEditedNode.creationCanceled (); + + mForm.removeAll (); + mEditedNode.configureForm (mForm); + mForm.revalidate (); + setEditing (null); + + if (mCreationMode) + setFormFromNode (mSelectedNode); + } + + public void edit () { + mCreationMode = false; + setEditing (mSelectedNode); + mSelectedNode.beginEdit (mForm); + } + + public void editInCreationMode (TreeEditorNode node) { + mCreationMode = true; + setFormFromNode (node); + setEditing (node); + node.beginEdit (mForm); + } + + private void setEditing (TreeEditorNode node) { + mEditedNode = node; + mTree.setBackground (node == null ? mEnabledColor : mDisabledColor); + mTree.setEnabled (node == null); + mForm.setEnabled (node != null); + + mBottom.removeAll (); + + if (node == null) + mBottom.add (mEditBtn); + else { + /** + * Enable save/cancel by default, node can reset. + */ + SAVE_ACTION.setEnabled (true); + CANCEL_ACTION.setEnabled (true); + + mBottom.add (mSaveBtn); + mBottom.add (mCancelBtn); + } + + mBottom.revalidate (); + mBottom.repaint (); + } + + public void updateFormHeaderFromEditedNode () { + if (mEditedNode != null) + setFormHeader (mEditedNode); + } + + private void setFormHeader (TreeEditorNode userNode) { + JComponent c = userNode.render (true, true, mStockHeader); + + if (mFormHeader == c) + return; + + if (mFormHeader != null) + mFormPanel.remove (mFormHeader); + + mFormHeader = c; + + if (mFormHeader != null) { + mFormHeader.setBorder (HEADER_BORDER); + mFormPanel.add (mFormHeader, BorderLayout.NORTH); + } + } + + private void setFormFromNode (TreeEditorNode userNode) { + mForm.removeAll (); + + if (userNode != null) { + setFormHeader (userNode); + userNode.configureForm (mForm); + } + + mFormPanel.revalidate (); + mFormPanel.repaint (); + } + + private void selectionChanged (TreePath newPath) { + if (newPath == null) { + mSelectedNode = null; + EDIT_ACTION.setEnabled (false); + } + else { + mSelectedNode = ((NodeAdapter) newPath.getLastPathComponent ()).getUserNode (); + EDIT_ACTION.setEnabled (mSelectedNode.isEditable ()); + } + + setFormFromNode (mSelectedNode); + } + + private void popup (int x, int y) { + if (!mTree.isEnabled ()) + return; + + TreePath selPath = mTree.getPathForLocation (x, y); + + if (selPath == null) + return; + + NodeAdapter node = + (NodeAdapter) selPath.getLastPathComponent (); + + JPopupMenu menu = node.getUserNode ().getMenu (); + + if (menu != null) + menu.show (mTree, x, y); + } + + public void expandEntireTree () { + SwingUtil.expandEntireTree (mTree); + } + + final void setSaveEnabled (boolean flag) { + SAVE_ACTION.setEnabled (flag); + } + + final void setCancelEnabled (boolean flag) { + CANCEL_ACTION.setEnabled (flag); + } + + public void addNodeChangeListener (NodeChangeListener listener) { + mNodeChangeListeners.add (listener); + } + + public void removeNodeChangeListener (NodeChangeListener listener) { + mNodeChangeListeners.remove (listener); + } + + void fireNodeChanged (TreeEditorNode node) { + for (NodeChangeListener listener : mNodeChangeListeners) + listener.nodeChanged (node); + } +} diff --git a/src/deltix/util/swing/treeedit/actions.properties b/src/deltix/util/swing/treeedit/actions.properties new file mode 100644 index 00000000..1e49b533 --- /dev/null +++ b/src/deltix/util/swing/treeedit/actions.properties @@ -0,0 +1,8 @@ +edit Edit +edit.tt Edit properties. + +save Save +save.tt Save edits. + +cancel Cancel +cancel.tt Cancel edits. diff --git a/src/deltix/util/time/AbsoluteDate.java b/src/deltix/util/time/AbsoluteDate.java new file mode 100644 index 00000000..0feb43e6 --- /dev/null +++ b/src/deltix/util/time/AbsoluteDate.java @@ -0,0 +1,138 @@ +package deltix.util.time; + +import java.util.*; +import java.io.*; + +/** + * A bean holding an absolute (time- and time zone-unrelated) date. + */ +public class AbsoluteDate implements Comparable { + static final long serialVersionUID = 1L; + private static final short EXTERNAL_VERSION = 1; + + private short mYear; + private byte mMonth; // 1-based! + private byte mDay; // 1-based! + + public AbsoluteDate (int year, int month, int day) { + if (year < 0 || year > Short.MAX_VALUE) + throw new IllegalArgumentException ("Illegal year value: " + year); + + if (month < 1 || month > 12) + throw new IllegalArgumentException ("Illegal month value: " + month); + + if (day < 1 || day > 31) + throw new IllegalArgumentException ("Illegal day value: " + day); + + mYear = (short) year; + mMonth = (byte) month; + mDay = (byte) day; + } + + public AbsoluteDate (Calendar cal) { + mYear = (short) cal.get (Calendar.YEAR); + mMonth = (byte) (1 + cal.get (Calendar.MONTH)); + mDay = (byte) cal.get (Calendar.DAY_OF_MONTH); + } + + public AbsoluteDate (int num) { + mDay = (byte) (num % 100); + + num = num / 100; + + mMonth = (byte) (num % 100); + + mYear = (short) (num / 100); + } + + public AbsoluteDate (String s) { + StringTokenizer stk = new StringTokenizer (s, "-"); + + if (stk.countTokens () == 3) { + mYear = Short.parseShort (stk.nextToken ()); + mMonth = Byte.parseByte (stk.nextToken ()); + mDay = Byte.parseByte (stk.nextToken ()); + } + else + throw new NumberFormatException ("Illegal AbsoluteDate: " + s); + } + + public String toString () { + return (mYear + "-" + mMonth + "-" + mDay); + } + + public int toInt () { + return (mYear * 10000 + mMonth * 100 + mDay); + } + + public int getYear () { + return (mYear); + } + + public int getMonth () { + return (mMonth); + } + + public int getDay () { + return (mDay); + } + + public void toCalendar (Calendar cal) { + cal.set (Calendar.YEAR, mYear); + cal.set (Calendar.MONTH, mMonth - 1); + cal.set (Calendar.DAY_OF_MONTH, mDay); + } + + public int hashCode () { + return (toInt ()); + } + + public boolean equals (Object other) { + if (!(other instanceof AbsoluteDate)) + return (false); + + AbsoluteDate d = (AbsoluteDate) other; + + return ( + d.mDay == mDay && + d.mMonth == mMonth && + d.mYear == mYear + ); + } + + public int compareTo (AbsoluteDate o) { + int dif; + + dif = mYear - o.getYear (); + + if (dif != 0) + return (dif); + + dif = mMonth - o.getMonth (); + + if (dif != 0) + return (dif); + + return (mDay - o.getDay ()); + } + + public void readExternal (ObjectInput in) + throws IOException + { + short version = in.readShort (); + mYear = in.readShort (); + mMonth = in.readByte (); + mDay = in.readByte (); + } + + public void writeExternal (ObjectOutput out) + throws IOException + { + out.writeShort (EXTERNAL_VERSION); + out.writeShort (mYear); + out.writeByte (mMonth); + out.writeByte (mDay); + } + + +} diff --git a/src/deltix/util/time/DurationFormat.java b/src/deltix/util/time/DurationFormat.java new file mode 100644 index 00000000..6e937e6f --- /dev/null +++ b/src/deltix/util/time/DurationFormat.java @@ -0,0 +1,37 @@ +package deltix.util.time; + +/** + * + */ +public class DurationFormat { + private void f2 (StringBuffer sb, int value) { + if (value < 10) + sb.append ("0"); + + sb.append (value); + } + + public String format (double seconds) { + int isec = (int) seconds; + + int secComp = isec % 60; + + isec /= 60; + + int minComp = isec % 60; + + isec /= 60; + + int hourComp = isec; + + StringBuffer sb = new StringBuffer (); + + sb.append (hourComp); + sb.append (":"); + f2 (sb, minComp); + sb.append (":"); + f2 (sb, secComp); + + return (sb.toString ()); + } +} From 922098467efcb73a303fca3e68d26d4a07e7e622 Mon Sep 17 00:00:00 2001 From: gene Date: Tue, 17 Oct 2006 18:32:51 +0000 Subject: [PATCH 0004/2572] --- src/deltix/custom/statestreet/fxa/load/DataTransformer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/deltix/custom/statestreet/fxa/load/DataTransformer.java b/src/deltix/custom/statestreet/fxa/load/DataTransformer.java index 3c540f2b..d4091fcd 100644 --- a/src/deltix/custom/statestreet/fxa/load/DataTransformer.java +++ b/src/deltix/custom/statestreet/fxa/load/DataTransformer.java @@ -1,6 +1,6 @@ package deltix.custom.statestreet.fxa.load; -import deltix.custom.statestreet.fxa.utils.JDBCUtils; +import deltix.util.jdbc.JDBCUtils; import java.sql.*; /** From 24b4f62cb8a118b61b04986092ff964c4de343a5 Mon Sep 17 00:00:00 2001 From: gene Date: Tue, 17 Oct 2006 21:41:12 +0000 Subject: [PATCH 0005/2572] --- src/deltix/util/jdbc/JDBCUtils.java | 9 +++++++++ src/deltix/util/swing/treeedit/TreeEditorNode.java | 6 ++++++ src/deltix/util/swing/treeedit/TreeEditorPanel.java | 4 +++- 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/deltix/util/jdbc/JDBCUtils.java b/src/deltix/util/jdbc/JDBCUtils.java index cfff182d..f49f4162 100644 --- a/src/deltix/util/jdbc/JDBCUtils.java +++ b/src/deltix/util/jdbc/JDBCUtils.java @@ -38,6 +38,15 @@ public static int queryInt (PreparedStatement ps) throws SQLExcept } } + public static void rollbackNoExceptions (Connection conn) { + if (conn != null) + try { + conn.rollback (); + } catch (Throwable x) { + Common.LOGGER.log (Level.SEVERE, "Error while rolling back a transaction", x); + } + } + public static void close (Connection conn) { if (conn != null) try { diff --git a/src/deltix/util/swing/treeedit/TreeEditorNode.java b/src/deltix/util/swing/treeedit/TreeEditorNode.java index fdd2633c..1a80c254 100644 --- a/src/deltix/util/swing/treeedit/TreeEditorNode.java +++ b/src/deltix/util/swing/treeedit/TreeEditorNode.java @@ -145,6 +145,12 @@ public void beginEdit (VerticalForm form) { public void created () { } + /** + * Called after the node is succesfully edited NOT in creation mode. + */ + public void updated () { + } + /** * Called after the user fails to complete the creation process. */ diff --git a/src/deltix/util/swing/treeedit/TreeEditorPanel.java b/src/deltix/util/swing/treeedit/TreeEditorPanel.java index 6d42d007..be7b4eea 100644 --- a/src/deltix/util/swing/treeedit/TreeEditorPanel.java +++ b/src/deltix/util/swing/treeedit/TreeEditorPanel.java @@ -114,7 +114,9 @@ public void save () { node.created (); node.select (); } - + else + node.updated (); + setFormFromNode (mSelectedNode); fireNodeChanged (node); From cd5b410a5e1083e9e5dfbd068e0002093c544e25 Mon Sep 17 00:00:00 2001 From: gene Date: Wed, 18 Oct 2006 21:38:33 +0000 Subject: [PATCH 0006/2572] --- src/deltix/util/Util.java | 6 ++-- src/deltix/util/collections/QuickList.java | 34 +++++++++++----------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/deltix/util/Util.java b/src/deltix/util/Util.java index fa77998a..d0bd6fe1 100644 --- a/src/deltix/util/Util.java +++ b/src/deltix/util/Util.java @@ -447,7 +447,7 @@ public static boolean xequals(Object obj1, Object obj2) /** * Method identical to "obj1.compareTo(obj2)==0", it also handles null values. */ - public static boolean xcompare(Comparable obj1, Comparable obj2) + public static boolean xcompare(Comparable obj1, T obj2) { return obj1 == obj2 || // shortcut (obj1 != null ? obj1.compareTo (obj2)==0 : obj2 == null); @@ -680,7 +680,7 @@ public static String printStackTrace (Throwable t) { /** @return Array of all interfaces implemented by given class (calls cls.getInterfaces() recursively), never null */ public static Class [] getClassInterfaces (Class cls) { - List result = new ArrayList (); + List result = new ArrayList (); if (cls.isInterface()) result.add (cls); @@ -696,7 +696,7 @@ public static String printStackTrace (Throwable t) { } c = c.getSuperclass(); } - return (Class []) result.toArray(new Class [result.size()]); + return result.toArray(new Class [result.size()]); } /** @return true if given cls is instanceof interface specified by className */ diff --git a/src/deltix/util/collections/QuickList.java b/src/deltix/util/collections/QuickList.java index 5b6cd85f..e86581cb 100644 --- a/src/deltix/util/collections/QuickList.java +++ b/src/deltix/util/collections/QuickList.java @@ -9,7 +9,7 @@ * to java.util.LinkedList. Entries cannot be shared between two or more * QuickLists. This class is not synchronized. */ -public final class QuickList implements java.io.Serializable { +public final class QuickList implements java.io.Serializable { /** * Turn this on if problems are suspected in the use of this class */ @@ -24,7 +24,7 @@ public BadEntryException (Entry e) { } } - public static final class EntryEnumeration implements Enumeration { + public static final class EntryEnumeration > implements Enumeration { private Entry mCur; public EntryEnumeration (Entry entry) { @@ -35,14 +35,14 @@ public boolean hasMoreElements () { return (!(mCur instanceof BoundaryEntry)); } - public Object nextElement () { - Entry e = mCur; + @SuppressWarnings("unchecked") public T nextElement () { + T e = (T) mCur; mCur = mCur.next (); return (e); } } - public static abstract class Entry implements java.io.Serializable { + public static abstract class Entry > implements java.io.Serializable { protected Entry mPrevious = null; protected Entry mNext = null; @@ -94,7 +94,7 @@ public boolean safeUnlink () { * Returns the next entry in the list, or null * if this is the last one. */ - public final Entry next () { + @SuppressWarnings("unchecked") public final T next () { if (DO_ASSERTIONS) { if (mNext == this) throw new RuntimeException (this + ": mNext == this"); @@ -106,14 +106,14 @@ public final Entry next () { if (mNext instanceof BoundaryEntry) return (null); else - return (mNext); + return ((T) mNext); } /** * Returns the previous entry in the list, or null * if this is the first one. */ - public final Entry previous () { + @SuppressWarnings("unchecked") public final T previous () { if (DO_ASSERTIONS) { if (mNext == this) throw new RuntimeException (this + ": mNext == this"); @@ -125,7 +125,7 @@ public final Entry previous () { if (mPrevious instanceof BoundaryEntry) return (null); else - return (mPrevious); + return ((T) mPrevious); } /** @@ -166,7 +166,7 @@ public final Entry previousOrBoundary () { * BoundaryEntry in the beginning, and one BoundaryEntry in the end * of the chain. */ - public static class BoundaryEntry extends Entry { + public static final class BoundaryEntry extends Entry { public boolean safeUnlink () { throw new IllegalArgumentException ( "Cannot unlink a BoundaryEntry." @@ -210,10 +210,10 @@ public BoundaryEntry getTailBoundaryEntry () { * Returns the first entry without unlinking it * from the list, or null if the list is empty. */ - public Entry getFirst () { + @SuppressWarnings("unchecked") public T getFirst () { Entry first = mHead.mNext; - return (first == mTail ? null : first); + return (first == mTail ? null : (T) first); } /** @@ -228,10 +228,10 @@ public Entry getFirstOrTail () { * Returns the last entry without unlinking it * from the list, or null if the list is empty. */ - public Entry getLast () { + @SuppressWarnings("unchecked") public T getLast () { Entry last = mTail.mPrevious; - return (last == mHead ? null : last); + return (last == mHead ? null : (T) last); } /** @@ -368,14 +368,14 @@ public static void linkChainBefore (Entry firstInChain, Entry lastInChain, Entry /** * Links the entry at the head of the list. */ - public void linkFirst (Entry e) { + public void linkFirst (T e) { linkChainFirst (e, e); } /** * Links the entry at the tail of the list. */ - public void linkLast (Entry e) { + public void linkLast (T e) { linkChainLast (e, e); } @@ -438,7 +438,7 @@ public static void linkBefore (QuickList l, Entry next) { /** * Returns an enumeration of all entries. */ - public Enumeration entries () { + @SuppressWarnings("unchecked") public Enumeration entries () { return (new EntryEnumeration (mHead.mNext)); } } From 206ac658102fa0bf1aaceebb8a5ea4f31312a1ee Mon Sep 17 00:00:00 2001 From: gene Date: Thu, 19 Oct 2006 13:00:23 +0000 Subject: [PATCH 0007/2572] --- src/deltix/util/Util.java | 9 + .../util/cmdline/DefaultApplication.java | 283 ++++++++++++++++++ src/deltix/util/jdbc/JDBCUtils.java | 9 + src/deltix/util/swing/treeedit/Test.java | 2 +- .../util/swing/treeedit/TreeEditorNode.java | 2 +- 5 files changed, 303 insertions(+), 2 deletions(-) create mode 100644 src/deltix/util/cmdline/DefaultApplication.java diff --git a/src/deltix/util/Util.java b/src/deltix/util/Util.java index d0bd6fe1..5b001d76 100644 --- a/src/deltix/util/Util.java +++ b/src/deltix/util/Util.java @@ -34,6 +34,15 @@ public static String readNullableString (ObjectInput is) return (is.readUTF ()); } + /** + * Loads and instantiates the specified class using the no-argument constructor + */ + public static Object newInstance (String className) + throws ClassNotFoundException, InstantiationException, IllegalAccessException + { + return (Class.forName (className).newInstance ()); + } + /** * Call a static method of the specified class. Figure out the method * signature from the types of the supplied arguments (which must not contain diff --git a/src/deltix/util/cmdline/DefaultApplication.java b/src/deltix/util/cmdline/DefaultApplication.java new file mode 100644 index 00000000..21d039e0 --- /dev/null +++ b/src/deltix/util/cmdline/DefaultApplication.java @@ -0,0 +1,283 @@ +package deltix.util.cmdline; + +import deltix.util.Util; +import java.util.*; +import org.xml.sax.SAXParseException; + +/** + * Helps parse command-line arguments and handle exceptions. + *

+ * Usage: + *

+ *public class MyApp extends deltix.util.cmdline.DefaultApplication {
+ *    protected MyApp (String [] args) { 
+ *        super (args); 
+ *    }
+ *
+ *    protected void run () throws Throwable {
+ *        ...
+ *    }
+ *
+ *    public static void main (String [] args) {
+ *        new MyApp (args).start ();
+ *    }
+ *}
+ *
+ */ +public abstract class DefaultApplication { + private String [] mArgs; + private Map mMap = new HashMap (); + private String mDebugMode; + private boolean mVerbose; + + protected DefaultApplication (String [] args) { + mArgs = args; + + for (int ii = 0; ii < mArgs.length; ii++) + mMap.put (mArgs [ii], ii); + + mDebugMode = getArgValue ("-debug"); + mVerbose = isArgSpecified ("-verbose"); + } + + /** + * Returns whether the application should give verbose + * information about the progress. This is controlled by + * passing the -verbose argument on the command + * line. + */ + public boolean isVerboseMode () { + return (mVerbose); + } + + /** + * Returns whether the application should give debug + * information about the specified area. This is controlled by + * passing the -debug <value> arguments on + * the command line. The <value> is checked for containing + * the string passed as parameter to this method. + * + * @param mode The symbolic name of a debuggable functional area. + * @return If the -debug <value> + * command argument sequence was + * specified, and the <value> argument + * contains the specified symbolic name. + */ + public boolean isDebugMode (String mode) { + return (mDebugMode != null && mDebugMode.indexOf (mode) != -1); + } + + /** + * Returns the command line argument array. + */ + public String [] getArgs () { + return (mArgs); + } + + /** + * Returns whether the specified argument was present on the + * command line. + * + * @param key The argument being looked for. + */ + public boolean isArgSpecified (String key) { + return (mMap.containsKey (key)); + } + + /** + * Returns the position of the specified argument on the + * command line. + * + * @param key The argument being looked for. + * @return The 0-based index of the argument, + * or -1 if not found. + */ + public int findArg (String key) { + Integer idx = (Integer) mMap.get (key); + if (idx == null) + return (-1); + else + return (idx.intValue ()); + } + + /** + * Returns the argument following the specified argument on the + * command line. + * + * @param key The argument being looked for. + * @return The next argument following key, + * or null if not found, or if + * key was the last argument. + */ + public String getArgValue (String key) { + return (getArgValue (key, null)); + } + + /** + * Returns the argument following the specified argument on the + * command line, or default value, if the + * former is not specified. + * + * @param key The argument being looked for. + * @param defval The value to return if the argument is not + * specified. + * @return The next argument following key, + * or null if not found, or if + * key was the last argument. + */ + public String getArgValue (String key, String defval) { + int idx = findArg (key); + if (idx == -1 || idx + 1 >= mArgs.length) + return (defval); + else + return (mArgs [idx + 1]); + } + + /** + * Returns an integer argument, or default value, if the + * former is not specified. + * + * @param key The argument being looked for. + * @param defval The value to return if the argument is not + * specified. + * @return The integer value of the next argument + * following key, + * or the value of defval if not found, + * or if key was the last argument. + */ + public int getIntArgValue (String key, int defval) { + String str = getArgValue (key); + if (str == null) + return (defval); + else + return (Integer.parseInt (str)); + } + + /** + * Returns a long integer argument, or default value, if the + * former is not specified. + * + * @param key The argument being looked for. + * @param defval The value to return if the argument is not + * specified. + * @return The integer value of the next argument + * following key, + * or the value of defval if not found, + * or if key was the last argument. + */ + public long getLongArgValue (String key, long defval) { + String str = getArgValue (key); + if (str == null) + return (defval); + else + return (Long.parseLong (str)); + } + + /** + * Returns a double argument, or default value, if the + * former is not specified. + * + * @param key The argument being looked for. + * @param defval The value to return if the argument is not + * specified. + * @return The double value of the next argument + * following key, + * or the value of defval if not found, + * or if key was the last argument. + */ + public double getDoubleArgValue (String key, double defval) { + String str = getArgValue (key); + if (str == null) + return (defval); + else + return (Double.parseDouble (str)); + } + + /** + * Returns the argument following the specified argument on the + * command line. If it is not specified, an exception is thrown. + * + * @param key The argument being looked for. + * @return The next argument following key. + * @exception IllegalArgumentException + * If key is not present, or is the last + * argument on the command line. + */ + public String getMandatoryArgValue (String key) + throws IllegalArgumentException + { + int idx = findArg (key); + if (idx == -1) + throw new IllegalArgumentException ( + "Argument '" + key + "' is missing." + ); + + int next = idx + 1; + + if (next >= mArgs.length) + throw new IllegalArgumentException ( + "Argument '" + key + "' must be followed by a value." + ); + + return (mArgs [idx + 1]); + } + + /** + * Override to do the work. + */ + protected abstract void run () throws Throwable; + + /** + * Prints out a standardized diagnostic line. Handles + * known wrapper exceptions intelligently, such as, + * for example, prints out the line number and position + * if a SAXParseException is thrown. + */ + public static void printException ( + Throwable x, + boolean wantStackTrace + ) + { + if (x instanceof SAXParseException) { + SAXParseException saxx = (SAXParseException) x; + System.err.print ( + ">>> XML Error at " + saxx.getLineNumber () + "." + + saxx.getColumnNumber () + ); + } + else + System.err.print (">>> Error"); + + Throwable ux = Util.unwrap (x); + + System.err.println (": " + ux.getClass ().getName () + ": " + ux.getMessage ()); + + if (wantStackTrace) + ux.printStackTrace (); + } + + /** + * Prints out a standardized diagnostic line. Handles + * known wrapper exceptions intelligently, such as, + * for example, prints out the line number and position + * if a SAXParseException is thrown. If the debug mode includes + * trace, the stack trace is printed out. + */ + public void handleException (Throwable x) { + printException (x, isDebugMode ("trace")); + } + + /** + * Call from a main method to run the application. + * This will handle exceptions, and make sure that if an + * exception is caught, the VM process will exit with an error code. + */ + protected void start () { + try { + run (); + } catch (Throwable x) { + handleException (x); + System.exit (1); + } + } +} diff --git a/src/deltix/util/jdbc/JDBCUtils.java b/src/deltix/util/jdbc/JDBCUtils.java index f49f4162..4c7dd003 100644 --- a/src/deltix/util/jdbc/JDBCUtils.java +++ b/src/deltix/util/jdbc/JDBCUtils.java @@ -65,6 +65,15 @@ public static void close (Statement stmt) { } } + public static void close (ResultSet rs) { + if (rs != null) + try { + rs.close (); + } catch (Throwable x) { + Common.LOGGER.log (Level.SEVERE, "Error while closing a result set", x); + } + } + public static void truncateTable (Connection conn, String tname) throws SQLException { diff --git a/src/deltix/util/swing/treeedit/Test.java b/src/deltix/util/swing/treeedit/Test.java index 271d8191..b8068605 100644 --- a/src/deltix/util/swing/treeedit/Test.java +++ b/src/deltix/util/swing/treeedit/Test.java @@ -20,7 +20,7 @@ public class Test extends TreeEditorNode { private String mLabel; private int mLevel; - private ArrayList mChildren = new ArrayList (); + private ArrayList mChildren = new ArrayList (); public Test (int level) { mLevel = level; diff --git a/src/deltix/util/swing/treeedit/TreeEditorNode.java b/src/deltix/util/swing/treeedit/TreeEditorNode.java index 1a80c254..ad135898 100644 --- a/src/deltix/util/swing/treeedit/TreeEditorNode.java +++ b/src/deltix/util/swing/treeedit/TreeEditorNode.java @@ -254,7 +254,7 @@ public final TreeEditorNode find (Filter filter) { return (null); } - public final TreeEditorNode findNodeByType (final Class type) { + public final TreeEditorNode findNodeByType (final Class type) { return ( find ( new Filter () { From 47d78c01add6235ab7c42844c2cba43dd0828016 Mon Sep 17 00:00:00 2001 From: gene Date: Fri, 20 Oct 2006 23:09:46 +0000 Subject: [PATCH 0008/2572] --- src/deltix/util/jdbc/JDBCUtils.java | 14 ++++++++- src/deltix/util/time/TimeFormatter.java | 42 +++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 src/deltix/util/time/TimeFormatter.java diff --git a/src/deltix/util/jdbc/JDBCUtils.java b/src/deltix/util/jdbc/JDBCUtils.java index 4c7dd003..ec17fd3c 100644 --- a/src/deltix/util/jdbc/JDBCUtils.java +++ b/src/deltix/util/jdbc/JDBCUtils.java @@ -20,6 +20,18 @@ public static void setDouble (PreparedStatement ps, int idx, double ps.setDouble (idx, v); } + /** + * Converts NaN to NULL + */ + public static void updateDouble (ResultSet rs, int idx, double v) + throws SQLException + { + if (Double.isNaN (v)) + rs.updateNull (idx); + else + rs.updateDouble (idx, v); + } + public static int queryInt (PreparedStatement ps) throws SQLException { ResultSet rs = ps.executeQuery (); @@ -34,7 +46,7 @@ public static int queryInt (PreparedStatement ps) throws SQLExcept return (ret); } finally { - rs.close (); + close (rs); } } diff --git a/src/deltix/util/time/TimeFormatter.java b/src/deltix/util/time/TimeFormatter.java new file mode 100644 index 00000000..85643ce4 --- /dev/null +++ b/src/deltix/util/time/TimeFormatter.java @@ -0,0 +1,42 @@ +package deltix.util.time; + +import java.util.*; +import java.text.*; + +/** + * Thread-safe wrapper around SimpleDateFormat. + */ +public class TimeFormatter { + public static final TimeFormatter GMT_INSTANCE = + new TimeFormatter (); + + private DateFormat mDF; + + public TimeFormatter () { + this ("GMT"); + } + + public TimeFormatter (String tz) { + this ("yyyy-MM-dd HH:mm:ss z", tz); + } + + public TimeFormatter (String formatSpec, String tz) { + this (formatSpec, TimeZone.getTimeZone (tz)); + } + + public TimeFormatter (String formatSpec, TimeZone tz) { + mDF = new SimpleDateFormat (formatSpec); + mDF.setTimeZone (tz); + } + + protected void finalize () throws Throwable { + } + + public String format (long t) { + return (format (new Date (t))); + } + + public synchronized String format (Date t) { + return (mDF.format (t)); + } +} From ad045692d14614254d2ba9937eda0276435be065 Mon Sep 17 00:00:00 2001 From: gene Date: Sat, 21 Oct 2006 17:50:06 +0000 Subject: [PATCH 0009/2572] Fixed CSV output to handle commas and any text requiring escaping --- src/deltix/util/io/CSV.java | 41 +++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 src/deltix/util/io/CSV.java diff --git a/src/deltix/util/io/CSV.java b/src/deltix/util/io/CSV.java new file mode 100644 index 00000000..5c51d5f6 --- /dev/null +++ b/src/deltix/util/io/CSV.java @@ -0,0 +1,41 @@ +package deltix.util.io; + +import java.io.*; + +/** + * + */ +public class CSV { + public static void printCell (String unescapedText, Writer wr) throws IOException { + int len = unescapedText.length (); + + if (len == 0) + return; + + boolean needEscape = false; + + search: for (int ii = 0; ii < len; ii++) { + switch (unescapedText.charAt (ii)) { + case '"': + case ',': + needEscape = true; + break search; + } + } + + if (needEscape) + wr.write ('"'); + + for (int ii = 0; ii < len; ii++) { + char ch = unescapedText.charAt (ii); + + if (ch == '"') + wr.write ('"'); + + wr.write (ch); + } + + if (needEscape) + wr.write ('"'); + } +} From 60df122f333dc7d8a4289d4c3426d124c4559338 Mon Sep 17 00:00:00 2001 From: gene Date: Sat, 21 Oct 2006 21:39:59 +0000 Subject: [PATCH 0010/2572] --- .../util/io/ClassLoaderFilenameResolver.java | 46 ++ src/deltix/util/io/FilenameResolver.java | 20 + .../util/io/NonCachingSearchPathResolver.java | 37 ++ src/deltix/util/jdbc/AtStatement.java | 25 ++ src/deltix/util/jdbc/CommitStatement.java | 15 + src/deltix/util/jdbc/DatabaseOperation.java | 17 + src/deltix/util/jdbc/JDBCUtils.java | 55 +++ src/deltix/util/jdbc/JavaCallStatement.java | 33 ++ src/deltix/util/jdbc/ORACLE.java | 167 +++++++ src/deltix/util/jdbc/PromptStatement.java | 18 + src/deltix/util/jdbc/SQLScriptStatement.java | 64 +++ src/deltix/util/jdbc/Script.java | 420 ++++++++++++++++++ .../util/jdbc/ScriptExecutionEnvironment.java | 17 + src/deltix/util/jdbc/ScriptStatement.java | 10 + src/deltix/util/lang/StringUtils.java | 370 +++++++++++++++ 15 files changed, 1314 insertions(+) create mode 100644 src/deltix/util/io/ClassLoaderFilenameResolver.java create mode 100644 src/deltix/util/io/FilenameResolver.java create mode 100644 src/deltix/util/io/NonCachingSearchPathResolver.java create mode 100644 src/deltix/util/jdbc/AtStatement.java create mode 100644 src/deltix/util/jdbc/CommitStatement.java create mode 100644 src/deltix/util/jdbc/DatabaseOperation.java create mode 100644 src/deltix/util/jdbc/JavaCallStatement.java create mode 100644 src/deltix/util/jdbc/ORACLE.java create mode 100644 src/deltix/util/jdbc/PromptStatement.java create mode 100644 src/deltix/util/jdbc/SQLScriptStatement.java create mode 100644 src/deltix/util/jdbc/Script.java create mode 100644 src/deltix/util/jdbc/ScriptExecutionEnvironment.java create mode 100644 src/deltix/util/jdbc/ScriptStatement.java create mode 100644 src/deltix/util/lang/StringUtils.java diff --git a/src/deltix/util/io/ClassLoaderFilenameResolver.java b/src/deltix/util/io/ClassLoaderFilenameResolver.java new file mode 100644 index 00000000..83e1dfc2 --- /dev/null +++ b/src/deltix/util/io/ClassLoaderFilenameResolver.java @@ -0,0 +1,46 @@ +package deltix.util.io; + +import java.io.*; + +/** + * Adapts java.lang.ClassLoader to the FilenameResolver interface. + */ +public class ClassLoaderFilenameResolver implements FilenameResolver { + private ClassLoader mDelegate; + + /** + * Creates an instance of FilenameResolver, which delegates all requests + * to delegate. + */ + public ClassLoaderFilenameResolver (ClassLoader delegate) { + mDelegate = delegate; + } + + /** + * Creates an instance of FilenameResolver, which delegates all requests + * to the system ClassLoader. + */ + public ClassLoaderFilenameResolver () { + this (null); + } + + /** + * Throws an exception. + */ + public File find (String relPath) { + throw new RuntimeException ( + "Impossible to get a File out of a ClassLoader" + ); + } + + /** + * Opens a resource using the underlying class loader. + */ + public InputStream open (String relPath) throws IOException { + return ( + mDelegate == null ? + ClassLoader.getSystemResourceAsStream (relPath) : + mDelegate.getResourceAsStream (relPath) + ); + } +} diff --git a/src/deltix/util/io/FilenameResolver.java b/src/deltix/util/io/FilenameResolver.java new file mode 100644 index 00000000..ee704a53 --- /dev/null +++ b/src/deltix/util/io/FilenameResolver.java @@ -0,0 +1,20 @@ +package deltix.util.io; + +import java.io.*; + +/** + * Abstracts the notion of searching for files by relative path. + */ +public interface FilenameResolver { + /** + * Searches for the specified file or directory by relative path + * in a way that is implementation-dependent. + */ + public File find (String relPath) throws IOException; + + /** + * Opens the specified file or directory by relative path + * in a way that is implementation-dependent. + */ + public InputStream open (String relPath) throws IOException; +} diff --git a/src/deltix/util/io/NonCachingSearchPathResolver.java b/src/deltix/util/io/NonCachingSearchPathResolver.java new file mode 100644 index 00000000..21bc66ee --- /dev/null +++ b/src/deltix/util/io/NonCachingSearchPathResolver.java @@ -0,0 +1,37 @@ +package deltix.util.io; + +import java.io.*; + +/** + * Searches for files under a set of root directories. This class + * does not try to create and cache a map of all directories, so it + * will be inefficient in the rare instances when the number of + * roots is really large. + */ +public class NonCachingSearchPathResolver implements FilenameResolver { + private File [] mRoots; + + /** + * @param roots A set of directories that are sequentially + * searched for the specified files. + */ + public NonCachingSearchPathResolver (File [] roots) { + mRoots = roots; + } + + public File find (String relPath) throws IOException { + for (int ii = 0; ii < mRoots.length; ii++) { + File test = new File (mRoots [ii], relPath); + + if (test.exists ()) + return (test); + } + + return (null); + } + + public InputStream open (String relPath) throws IOException { + File f = find (relPath); + return (f == null ? null : new FileInputStream (f)); + } +} diff --git a/src/deltix/util/jdbc/AtStatement.java b/src/deltix/util/jdbc/AtStatement.java new file mode 100644 index 00000000..aafeab54 --- /dev/null +++ b/src/deltix/util/jdbc/AtStatement.java @@ -0,0 +1,25 @@ +package deltix.util.jdbc; + +import java.io.IOException; +import java.sql.SQLException; + +import deltix.util.io.FilenameResolver; + +class AtStatement implements ScriptStatement { + private Script mScript; + + public AtStatement (String relPath, FilenameResolver scriptFinder) throws IOException { + mScript = new Script (); + mScript.setScriptFinder (scriptFinder); + mScript.read (relPath); + } + + public void execute (ScriptExecutionEnvironment env) + throws SQLException, InterruptedException, IOException + { + mScript.setConnection (env.getConnection ()); + mScript.setLogger (env.getLogger ()); + mScript.setParameterValues (env.getParameterValues ()); + mScript.execute (); + } +} \ No newline at end of file diff --git a/src/deltix/util/jdbc/CommitStatement.java b/src/deltix/util/jdbc/CommitStatement.java new file mode 100644 index 00000000..8721d52e --- /dev/null +++ b/src/deltix/util/jdbc/CommitStatement.java @@ -0,0 +1,15 @@ +package deltix.util.jdbc; + +import java.sql.SQLException; + +class CommitStatement implements ScriptStatement { + public CommitStatement () { + } + + public void execute (ScriptExecutionEnvironment env) + throws SQLException, InterruptedException + { + env.getLogger ().println ("COMMIT"); + env.getConnection ().commit (); + } +} diff --git a/src/deltix/util/jdbc/DatabaseOperation.java b/src/deltix/util/jdbc/DatabaseOperation.java new file mode 100644 index 00000000..16974c55 --- /dev/null +++ b/src/deltix/util/jdbc/DatabaseOperation.java @@ -0,0 +1,17 @@ +package deltix.util.jdbc; + +import java.sql.*; +import java.io.*; + +/** + * Some action on an open connection. + */ +public interface DatabaseOperation { + /** + * Performs the action. Must not close Connection. + * + * @param env The execution environment. + */ + public void run (ScriptExecutionEnvironment env) + throws SQLException, InterruptedException, IOException; +} diff --git a/src/deltix/util/jdbc/JDBCUtils.java b/src/deltix/util/jdbc/JDBCUtils.java index ec17fd3c..133c78bd 100644 --- a/src/deltix/util/jdbc/JDBCUtils.java +++ b/src/deltix/util/jdbc/JDBCUtils.java @@ -3,6 +3,7 @@ import deltix.custom.statestreet.fxa.utils.*; import java.sql.*; import java.util.logging.*; +import java.util.*; /** * @@ -50,6 +51,45 @@ public static int queryInt (PreparedStatement ps) throws SQLExcept } } + public static int queryInt (Connection conn, String query) + throws SQLException + { + PreparedStatement ps = conn.prepareStatement (query); + + try { + return (queryInt (ps)); + } finally { + close (ps); + } + } + + public static List queryStrings (PreparedStatement ps) + throws SQLException + { + ResultSet rs = ps.executeQuery (); + ArrayList ret = new ArrayList (); + try { + while (rs.next ()) + ret.add (rs.getString (1)); + + return (ret); + } finally { + close (rs); + } + } + + public static List queryStrings (Connection conn, String query) + throws SQLException + { + PreparedStatement ps = conn.prepareStatement (query); + + try { + return (queryStrings (ps)); + } finally { + close (ps); + } + } + public static void rollbackNoExceptions (Connection conn) { if (conn != null) try { @@ -121,5 +161,20 @@ public static void exec (Connection conn, String sql) close (stmt); } } + + public static void exec (Connection conn, List sqlList) + throws SQLException + { + Statement stmt = conn.createStatement (); + try { + for (String sql : sqlList) + stmt.execute (sql); + + stmt.close (); + stmt = null; + } finally { + close (stmt); + } + } } diff --git a/src/deltix/util/jdbc/JavaCallStatement.java b/src/deltix/util/jdbc/JavaCallStatement.java new file mode 100644 index 00000000..fe068e83 --- /dev/null +++ b/src/deltix/util/jdbc/JavaCallStatement.java @@ -0,0 +1,33 @@ +package deltix.util.jdbc; + +import java.io.IOException; +import java.sql.SQLException; + +import deltix.util.Util; + +class JavaCallStatement implements ScriptStatement { + private String mClassName; + + public JavaCallStatement (String className) throws IOException + { + mClassName = className; + } + + public void execute (ScriptExecutionEnvironment env) + throws SQLException, IOException, InterruptedException + { + env.getLogger ().println ("CALL new " + mClassName + " ().run (connection)"); + + DatabaseOperation op; + + try { + op = (DatabaseOperation) Util.newInstance (mClassName); + } catch (ClassCastException x) { + throw new SQLException ("Class '" + mClassName + " is not an instance of DatabaseOperation"); + } catch (Exception x) { + throw new SQLException ("Cannot instantiate class '" + mClassName + "': " + x); + } + + op.run (env); + } +} diff --git a/src/deltix/util/jdbc/ORACLE.java b/src/deltix/util/jdbc/ORACLE.java new file mode 100644 index 00000000..bd5a1f22 --- /dev/null +++ b/src/deltix/util/jdbc/ORACLE.java @@ -0,0 +1,167 @@ +package deltix.util.jdbc; + +import java.util.*; +import java.util.logging.*; +import java.text.*; +import java.sql.*; +import java.io.*; + +import deltix.util.Util; + +/** @deprecated */ +public class ORACLE { + public static void loadDriver () throws ClassNotFoundException { + Class.forName ("oracle.jdbc.driver.OracleDriver"); + } + + static { + try { + loadDriver (); + } catch (ClassNotFoundException cnfx) { + Util.LOGGER.log (Level.SEVERE, "Failed to load the ORACLE JDBC driver", cnfx); + } + } + + public static void test (Connection conn) throws SQLException { + Statement stmt = conn.createStatement (); + + try { + ResultSet rs = stmt.executeQuery ("SELECT 1 FROM DUAL"); + + if (!rs.next ()) + throw new SQLException ("Selected 0 rows from DUAL (???)"); + + rs.close (); + } finally { + JDBCUtils.close (stmt); + } + } + + private static final int OUTSIDE = 1; + private static final int PLSQL = 2; + private static final int DDL = 3; + + public static List readSqlFile (LineNumberReader lnrd) + throws IOException + { + ArrayList queries = new ArrayList (); + int state = OUTSIDE; + StringBuffer sb = new StringBuffer (); + + for (;;) { + String l = lnrd.readLine(); + + if (l == null) + break; + + l = l.trim (); + + if (l.startsWith ("--") || l.length () == 0) + continue; + + if (state == OUTSIDE) { + String low = l.toLowerCase (); + + if (low.startsWith ("create") && low.indexOf ("package") != -1) + state = PLSQL; + else + state = DDL; + } + + if (state == PLSQL) { + if (l.equals ("/")) + state = OUTSIDE; + else { + sb.append (l); + sb.append (' '); + } + } else { + if (l.endsWith (";")) { + sb.append (l.substring (0, l.length () - 1)); + state = OUTSIDE; + } + else { + sb.append (l); + sb.append (' '); + } + } + + if (state == OUTSIDE) { + queries.add (sb.toString ()); + sb.setLength (0); + } + } + + return (queries); + } + + public static List readSqlFile (File f) + throws IOException + { + FileReader frd = new FileReader (f); + + try { + return (readSqlFile (new LineNumberReader (frd))); + } finally { + frd.close (); + } + } + + + public static List getTableNames (Connection conn) + throws SQLException + { + return (JDBCUtils.queryStrings (conn, "SELECT TABLE_NAME FROM USER_TABLES")); + } + + public static List getViewNames (Connection conn) + throws SQLException + { + return (JDBCUtils.queryStrings (conn, "SELECT VIEW_NAME FROM USER_VIEWS")); + } + + public static List getSequenceNames (Connection conn) + throws SQLException + { + return (JDBCUtils.queryStrings (conn, "SELECT SEQUENCE_NAME FROM USER_SEQUENCES")); + } + + public static void dropObjects ( + Connection conn, + String templateSql, + List objects + ) + throws SQLException + { + Statement stmt = conn.createStatement (); + + try { + for (Object obj : objects) + stmt.execute ( + MessageFormat.format (templateSql, new Object [] { obj }) + ); + } finally { + JDBCUtils.close (stmt); + } + } + + public static void dropTables (Connection conn, List tables) + throws SQLException + { + dropObjects (conn, "DROP TABLE {0} CASCADE CONSTRAINTS", tables); + } + + public static void dropViews (Connection conn, List views) + throws SQLException + { + dropObjects (conn, "DROP VIEW {0}", views); + } + + public static void dropSequences (Connection conn, List sequences) + throws SQLException + { + dropObjects (conn, "DROP SEQUENCE {0}", sequences); + } + + +} diff --git a/src/deltix/util/jdbc/PromptStatement.java b/src/deltix/util/jdbc/PromptStatement.java new file mode 100644 index 00000000..46dd45e5 --- /dev/null +++ b/src/deltix/util/jdbc/PromptStatement.java @@ -0,0 +1,18 @@ +package deltix.util.jdbc; + +import java.sql.SQLException; + + +class PromptStatement implements ScriptStatement { + private String mPrompt; + + public PromptStatement (String prompt) { + mPrompt = prompt; + } + + public void execute (ScriptExecutionEnvironment env) + throws SQLException, InterruptedException + { + env.getLogger ().println (mPrompt); + } +} \ No newline at end of file diff --git a/src/deltix/util/jdbc/SQLScriptStatement.java b/src/deltix/util/jdbc/SQLScriptStatement.java new file mode 100644 index 00000000..1e24f8d5 --- /dev/null +++ b/src/deltix/util/jdbc/SQLScriptStatement.java @@ -0,0 +1,64 @@ +package deltix.util.jdbc; + +import deltix.util.lang.StringUtils; +import java.sql.SQLException; + + +class SQLScriptStatement implements ScriptStatement { + private String mSQL; + + public SQLScriptStatement (String sql) { + mSQL = sql; + } + + public void execute (ScriptExecutionEnvironment env) + throws SQLException, InterruptedException + { + if (Thread.interrupted ()) + throw new InterruptedException (); + + String exeSQL; + String [] paramValues = env.getParameterValues (); + + if (paramValues != null) { + StringBuffer sb = new StringBuffer (); + int pos = 0; + int len = mSQL.length (); + + for (;;) { + int idx = mSQL.indexOf ("&", pos); + + if (idx == -1) + break; + + int idx1 = idx + 1; + + if (idx1 == len) + break; + + char ch = mSQL.charAt (idx1); + int pidx = ch - '1'; + + if (pidx > 0 && pidx < paramValues.length) { + sb.append (mSQL, pos, idx); + sb.append (paramValues [pidx]); + pos = idx + 2; + } + } + + sb.append (mSQL, pos, len); + exeSQL = sb.toString (); + } + else + exeSQL = mSQL; + + if (env.getLogger () != null) + env.getLogger ().println (exeSQL); + + try { + env.getStockStatement ().execute (exeSQL); + } catch (SQLException ex) { + throw ex; + } + } +} diff --git a/src/deltix/util/jdbc/Script.java b/src/deltix/util/jdbc/Script.java new file mode 100644 index 00000000..8b2ba488 --- /dev/null +++ b/src/deltix/util/jdbc/Script.java @@ -0,0 +1,420 @@ +package deltix.util.jdbc; + +import java.util.*; +import java.text.*; +import java.sql.*; +import java.io.*; + +import deltix.util.*; +import deltix.util.io.*; +import deltix.util.lang.*; + +/** + * Mimics the script execution behavior of SQL*Plus, with some limitations + * and extensions. + */ +public class Script { + private static final int OUTSIDE = 1; + private static final int PLSQL = 2; + private static final int DDL = 3; + + private List mStatements = new ArrayList (); + private Connection mConnection = null; + private Statement mStockStatement = null; + private String [] mParamValues = null; + private PrintWriter mLogger = null; + private FilenameResolver mScriptFinder = null; + private ScriptExecutionEnvironment mEnv = + new ScriptExecutionEnvironment () { + public Statement getStockStatement () { + return (mStockStatement); + } + + public String[] getParameterValues () { + return (mParamValues); + } + + public PrintWriter getLogger () { + return (mLogger); + } + + public Connection getConnection () { + return (mConnection); + } + }; + + /** + * Constructs an empty script. + */ + public Script () { + } + + /** + * Returns the connection property. + */ + public Connection getConnection () { + return (mConnection); + } + + /** + * Assigns the connection property. + */ + public void setConnection (Connection value) + throws SQLException + { + mConnection = value; + } + + /** + * Returns the paramValues property. + * Occurrences of &1 in the script + * are substituted with paramValues [0], + * etc. If the script does not use parameters, + * this argument can be null. Parameters with numbers + * greater than paramValues.length + 1 + * will not be replaced at all, and will most + * likely cause a SQL error. + */ + public String [] getParameterValues () { + return (mParamValues); + } + + /** + * Assigns the paramValues property. + * Occurrences of &1 in the script + * are substituted with paramValues [0], + * etc. If the script does not use parameters, + * this argument can be null. Parameters with numbers + * greater than paramValues.length + 1 + * will not be replaced at all, and will most + * likely cause a SQL error. + * + * @exception IllegalArgumentException + * When more than 9 parameters are specified. + */ + public void setParameterValues (String [] value) { + int num = value.length; + + if (num > 9) + throw new IllegalArgumentException ( + "Only &1 .. &9 (nine parameters) are supported." + ); + + mParamValues = value; + } + + /** + * Returns the logger property. If not null, + * each statement is logged to this logger before execution. + */ + public PrintWriter getLogger () { + return (mLogger); + } + + /** + * Assigns the logger property. If not null, + * each statement is logged to this logger before execution. + */ + public void setLogger (PrintWriter value) { + mLogger = value; + } + + /** + * Returns the scriptFinder property, used to resolve + * script inclusion. + */ + public FilenameResolver getScriptFinder () { + return (mScriptFinder); + } + + /** + * Assigns the scriptFinder property, used to resolve + * script inclusion. + */ + public void setScriptFinder ( + FilenameResolver value + ) + { + mScriptFinder = value; + } + + /** + * Reads the script from a Reader. + * @exception IOException When various IO errors occur. + */ + public void read (Reader rd) throws IOException { + mStatements.clear (); + + LineNumberReader lnrd = new LineNumberReader (rd); + int state = OUTSIDE; + StringBuffer sb = new StringBuffer (); + + for (;;) { + String l = lnrd.readLine(); + //System.out.println (">>> " + state + " " + l + "<<<"); + + if (l == null) + break; + + String test = + l.trim ().toLowerCase ().replace ('\t', ' '); + // + // Test for empty line. + // + if (test.length () == 0) + continue; + // + // Test for comments. We support only the entire line + // being a comment (starts with --). + // + if (test.startsWith ("--")) + continue; + + if (state == OUTSIDE) { + // + // Test for prompt statement + // + if (test.startsWith ("prompt")) { + mStatements.add ( + new PromptStatement (test.substring (6).trim ()) + ); + + continue; + } + // + // Test for script execute. We support only @-statements + // that lie entirely on one line. + // + if (test.charAt (0) == '@') { + int testLength = test.length (); + int first = + test.charAt (1) == '@' ? 2 : 1; + + int last = + test.charAt (testLength - 1) == ';' ? + testLength - 1 : testLength; + + mStatements.add ( + new AtStatement ( + test.substring (first, last).trim (), + mScriptFinder + ) + ); + + continue; + } + // + // Test for EXIT + // + if (test.startsWith ("exit")) + break; + + // + // Test for COMMIT + // + if (test.startsWith ("commit")) { + mStatements.add (new CommitStatement ()); + continue; + } + + // + // Test for CALL + // + if (test.startsWith ("call")) { + StringTokenizer stk = new StringTokenizer (l); + + stk.nextToken (); // call + + if (!stk.hasMoreTokens ()) + throw new IOException ( + "Class name expected after 'call'" + ); + + String className = stk.nextToken (); + + mStatements.add (new JavaCallStatement (className)); + continue; + } + + // + // Test for WHENEVER + // + if (test.startsWith ("whenever ")) { + // For now, ignore... + continue; + } + + // + // Test for SET + // + if (test.startsWith ("set ")) { + // For now, ignore... + continue; + } + + // + // Test for PL/SQL. We support only blocks whose first line is: + // create ... [function|procedure|package|type] ... + // or + // define ... + // or + // begin ... + // + if ( + test.startsWith ("create ") && + ( + test.indexOf (" package ") != -1 || + test.indexOf (" function ") != -1 || + test.indexOf (" type ") != -1 || + test.indexOf (" trigger ") != -1 || + test.indexOf (" procedure ") != -1 + ) || + test.startsWith ("create or replace ") && + ( + test.indexOf (" package ") != -1 || + test.indexOf (" function ") != -1 || + test.indexOf (" type ") != -1 || + test.indexOf (" trigger ") != -1 || + test.indexOf (" procedure ") != -1 + ) || + test.startsWith ("define") || + test.startsWith ("declare") || + test.startsWith ("begin") + ) + state = PLSQL; + else + state = DDL; + } + + if (state == PLSQL) { + if (test.equals ("/")) + state = OUTSIDE; + else { + sb.append (l); + sb.append ('\n'); + } + } else { + if (test.endsWith (";")) { + int endIdx = l.lastIndexOf (";"); + sb.append (l.substring (0, endIdx)); + state = OUTSIDE; + } + else { + sb.append (l); + sb.append ('\n'); + } + } + + if (state == OUTSIDE) { + String sql = sb.toString (); + //System.out.println (">>> [" + sql + "]"); + + mStatements.add (new SQLScriptStatement (sql)); + sb.setLength (0); + } + } + } + + /** + * Reads the script from a File. + * @exception IOException When various IO errors occur. + */ + public void read (File f) throws IOException { + FileReader frd = new FileReader (f); + + try { + read (frd); + } finally { + Util.close (frd); + } + } + + /** + * Reads the script from an InputStream. + * @exception IOException When various IO errors occur. + */ + public void read (InputStream is) throws IOException { + InputStreamReader isrd = new InputStreamReader (is); + + try { + read (isrd); + } finally { + Util.close (isrd); + } + } + + /** + * Uses the Script's own ScriptFinder to open the file, then read it. + * + * @exception FileNotFoundException When the script was not found. + * @exception IOException When various IO errors occur. + */ + public void read (String relPath) throws IOException { + if (relPath.lastIndexOf (".") == -1) + relPath += ".sql"; + + InputStream is = mScriptFinder.open (relPath); + + if (is == null) + throw new FileNotFoundException (relPath); + + try { + read (is); + } finally { + Util.close (is); + } + } + + /** + * Executes the script. + */ + public void execute () + throws SQLException, InterruptedException, IOException + { + mStockStatement = mConnection.createStatement (); + + try { + for (ScriptStatement s : mStatements) + s.execute (mEnv); + } finally { + JDBCUtils.close (mStockStatement); + } + } + + /** + * Usage: <user> <password> <connectString> + * <script> [ <param1> ... ] + */ + public static void main (String [] args) throws Exception { + String user = args [0]; + String pwd = args [1]; + String connect = args [2]; + File file = new File (args [3]); + + oracle.jdbc.driver.OracleDriver.class.getName (); + + Connection conn = + DriverManager.getConnection (connect, user, pwd); + + Script script = new Script (); + + script.setConnection (conn); + script.setLogger (new PrintWriter (System.out)); + script.setScriptFinder ( + new NonCachingSearchPathResolver ( + new File [] { + file.getParentFile () + } + ) + ); + script.read (file); + + String [] paramValues = new String [args.length - 4]; + System.arraycopy (args, 4, paramValues, 0, paramValues.length); + + script.setParameterValues (paramValues); + + script.execute (); + conn.close (); + } +} diff --git a/src/deltix/util/jdbc/ScriptExecutionEnvironment.java b/src/deltix/util/jdbc/ScriptExecutionEnvironment.java new file mode 100644 index 00000000..918387e3 --- /dev/null +++ b/src/deltix/util/jdbc/ScriptExecutionEnvironment.java @@ -0,0 +1,17 @@ +package deltix.util.jdbc; + +import java.sql.*; +import java.io.*; + +/** + * + */ +public interface ScriptExecutionEnvironment { + public Connection getConnection (); + + public String [] getParameterValues (); + + public PrintWriter getLogger (); + + public Statement getStockStatement (); +} diff --git a/src/deltix/util/jdbc/ScriptStatement.java b/src/deltix/util/jdbc/ScriptStatement.java new file mode 100644 index 00000000..23a6d8bb --- /dev/null +++ b/src/deltix/util/jdbc/ScriptStatement.java @@ -0,0 +1,10 @@ +package deltix.util.jdbc; + +import java.io.IOException; +import java.sql.SQLException; + + +interface ScriptStatement { + public void execute (ScriptExecutionEnvironment env) + throws SQLException, InterruptedException, IOException; +} \ No newline at end of file diff --git a/src/deltix/util/lang/StringUtils.java b/src/deltix/util/lang/StringUtils.java new file mode 100644 index 00000000..33fd4100 --- /dev/null +++ b/src/deltix/util/lang/StringUtils.java @@ -0,0 +1,370 @@ +package deltix.util.lang; + +import java.util.StringTokenizer; + +public class StringUtils { + /** + * Capitalizes first letter of each word in the buffer, and lowercases + * each letter after the first of each word. + */ + public static String niceCaps (String s) { + StringBuffer sb = new StringBuffer (s); + niceCaps (sb); + return (sb.toString ()); + } + + /** + * Capitalizes first letter of each word in the buffer, and lowercases + * each letter after the first of each word. + */ + public static void niceCaps (StringBuffer buf) { + boolean capIt = true; + for (int i = 0; i < buf.length(); i++) { + char curChar = buf.charAt(i); + if (curChar == ' ') + capIt = true; + else if (capIt) { + buf.setCharAt (i, Character.toUpperCase(curChar)); + capIt = false; + } + else + buf.setCharAt (i, Character.toLowerCase(curChar)); + } + } + + public static String replace ( + String where, + String [] what, + String [] with + ) + { + StringBuffer sb = new StringBuffer (where.length ()); + if (replace (where, what, with, sb, true)) + return (sb.toString ()); + else + return (where); + } + + public static void replace ( + String where, + String [] what, + String [] with, + StringBuffer out + ) + { + replace (where, what, with, out, true); + } + + private static boolean replace ( + String where, + String [] what, + String [] with, + StringBuffer out, + boolean failIfNotFound + ) + { + int numPatterns = what.length; + int length = where.length (); + + int pos = 0; + + for (;;) { + int next = -1; + int patternIdx = -1; + // + // Find the closest match + // + for (int ii = 0; ii < numPatterns; ii++) { + int found = where.indexOf (what [ii], pos); + + if (found < pos) + continue; + + if (next == -1 || found < next) { + next = found; + patternIdx = ii; + } + } + + if (next == -1) + break; + + while (pos < next) + out.append (where.charAt (pos++)); + + out.append (with [patternIdx]); + + pos += what [patternIdx].length (); + } + + if (pos == 0 && failIfNotFound) + return (false); + + while (pos < length) + out.append (where.charAt (pos++)); + + return (true); + } + + public static int parseDecimalInt (byte [] bytes, int offset, int len) { + skipSpace: while (len > 0) + switch (bytes [offset]) { + case ' ': + case '\t': + len--; + offset++; + break; + + default: + break skipSpace; + } + + skipSpace: while (len > 0) + switch (bytes [offset + len - 1]) { + case ' ': + case '\t': + len--; + break; + + default: + break skipSpace; + } + + int s; + + switch (bytes [offset]) { + case '+': + offset++; + len--; + s = 1; + break; + + case '-': + offset++; + len--; + s = -1; + break; + + default: + s = 1; + break; + } + + int v = 0; + + while (len > 0) { + int digit = bytes [offset] - '0'; + + if (digit < 0 || digit > 9) + throw new NumberFormatException ( + "bytes [" + offset + "] = " + bytes [offset] + ); + + v = v * 10 + digit; + + len--; + offset++; + } + + return (s * v); + } + + public static long parseDecimalLong (byte [] bytes, int offset, int len) { + skipSpace: while (len > 0) + switch (bytes [offset]) { + case ' ': + case '\t': + len--; + offset++; + break; + + default: + break skipSpace; + } + + skipSpace: while (len > 0) + switch (bytes [offset + len - 1]) { + case ' ': + case '\t': + len--; + break; + + default: + break skipSpace; + } + + int s; + + switch (bytes [offset]) { + case '+': + offset++; + len--; + s = 1; + break; + + case '-': + offset++; + len--; + s = -1; + break; + + default: + s = 1; + break; + } + + long v = 0; + + while (len > 0) { + int digit = bytes [offset] - '0'; + + if (digit < 0 || digit > 9) + throw new NumberFormatException ( + "bytes [" + offset + "] = " + bytes [offset] + ); + + v = v * 10 + digit; + len--; + offset++; + } + + return (s * v); + } + + public static double parseDecimalDouble (byte [] bytes, int offset, int len) { + skipSpace: while (len > 0) + switch (bytes [offset]) { + case ' ': + case '\t': + len--; + offset++; + break; + + default: + break skipSpace; + } + + skipSpace: while (len > 0) + switch (bytes [offset + len - 1]) { + case ' ': + case '\t': + len--; + break; + + default: + break skipSpace; + } + + int s; + + switch (bytes [offset]) { + case '+': + offset++; + len--; + s = 1; + break; + + case '-': + offset++; + len--; + s = -1; + break; + + default: + s = 1; + break; + } + + double v = 0; + boolean frac = false; + double m = 0.1; + + while (len > 0 && !frac) { + byte b = bytes [offset]; + + len--; + offset++; + + if (b == '.') { + frac = true; + break; + } + + int digit = b - '0'; + + if (digit < 0 || digit > 9) + throw new NumberFormatException ( + "bytes [" + offset + "] = " + b + ); + + v = v * 10 + digit; + } + + if (frac) + while (len > 0) { + byte b = bytes [offset]; + + len--; + offset++; + + int digit = b - '0'; + + if (digit < 0 || digit > 9) + throw new NumberFormatException ( + "bytes [" + offset + "] = " + b + ); + + v = v + digit * m; + m *= 0.1; + } + + return (s * v); + } + + /** @return string trimmed of spaces, or null if input is empty string or null */ + public static String trim (String str) { + if (str != null) { + str = str.trim (); + if (str.length() == 0) + str = null; + } + return str; + } + + public static String [] parseCommaSeparatedList (String str) { + String [] cols = null; + if (str != null) { + StringTokenizer tok = new StringTokenizer(str, ", "); + int num = tok.countTokens (); + cols = new String [num]; + int count = 0; + while (tok.hasMoreTokens ()) + cols [count++] = tok.nextToken (); + } + return (cols); + } + + public static String createCommaSepList (String [] strs) { + if (strs == null) + return (null); + + StringBuffer buf = new StringBuffer(); + if (strs != null) + for (int i = 0; i < strs.length; i++) { + if (i > 0) + buf.append (", "); + buf.append (strs [i]); + } + return (buf.toString()); + } + + public static void main (String [] args) { + byte [] b = args [0].getBytes(); + + System.out.println (parseDecimalLong (b, 0, b.length)); + } + + +} + + From 45e59aa425045a6fe2b317f34bbd7b863e67eb99 Mon Sep 17 00:00:00 2001 From: gene Date: Sun, 22 Oct 2006 14:23:59 +0000 Subject: [PATCH 0011/2572] --- src/deltix/util/jdbc/AtStatement.java | 14 +- src/deltix/util/jdbc/CommitStatement.java | 5 +- src/deltix/util/jdbc/JSQLPlus.java | 60 ++++++ src/deltix/util/jdbc/JavaCallStatement.java | 2 +- src/deltix/util/jdbc/PromptStatement.java | 2 +- src/deltix/util/jdbc/SQLScriptStatement.java | 19 +- src/deltix/util/jdbc/Script.java | 177 ++---------------- .../util/jdbc/ScriptExecutionEnvironment.java | 87 ++++++++- .../util/jdbc/ScriptExecutionLogger.java | 8 + 9 files changed, 181 insertions(+), 193 deletions(-) create mode 100644 src/deltix/util/jdbc/JSQLPlus.java create mode 100644 src/deltix/util/jdbc/ScriptExecutionLogger.java diff --git a/src/deltix/util/jdbc/AtStatement.java b/src/deltix/util/jdbc/AtStatement.java index aafeab54..779e3d13 100644 --- a/src/deltix/util/jdbc/AtStatement.java +++ b/src/deltix/util/jdbc/AtStatement.java @@ -5,21 +5,19 @@ import deltix.util.io.FilenameResolver; +/** + * Invoke another script + */ class AtStatement implements ScriptStatement { private Script mScript; - public AtStatement (String relPath, FilenameResolver scriptFinder) throws IOException { - mScript = new Script (); - mScript.setScriptFinder (scriptFinder); - mScript.read (relPath); + public AtStatement (Script script) throws IOException { + mScript = script; } public void execute (ScriptExecutionEnvironment env) throws SQLException, InterruptedException, IOException { - mScript.setConnection (env.getConnection ()); - mScript.setLogger (env.getLogger ()); - mScript.setParameterValues (env.getParameterValues ()); mScript.execute (); } -} \ No newline at end of file +} diff --git a/src/deltix/util/jdbc/CommitStatement.java b/src/deltix/util/jdbc/CommitStatement.java index 8721d52e..e196f933 100644 --- a/src/deltix/util/jdbc/CommitStatement.java +++ b/src/deltix/util/jdbc/CommitStatement.java @@ -9,7 +9,8 @@ public CommitStatement () { public void execute (ScriptExecutionEnvironment env) throws SQLException, InterruptedException { - env.getLogger ().println ("COMMIT"); - env.getConnection ().commit (); + env.getLogger ().logCommand ("COMMIT"); + if (env.getConnection () != null) + env.getConnection ().commit (); } } diff --git a/src/deltix/util/jdbc/JSQLPlus.java b/src/deltix/util/jdbc/JSQLPlus.java new file mode 100644 index 00000000..0732154a --- /dev/null +++ b/src/deltix/util/jdbc/JSQLPlus.java @@ -0,0 +1,60 @@ +package deltix.util.jdbc; + +import deltix.util.io.NonCachingSearchPathResolver; +import java.io.File; +import java.sql.Connection; +import java.sql.DriverManager; + +/** + * Provides functionality to ORACLE's SQL*Plus interpreter, with many restrictions and + * a few enhancements. + */ +public class JSQLPlus { + private static ScriptExecutionLogger LOGGER = + new ScriptExecutionLogger () { + public void logCommand (String cmd) { + System.out.println (cmd); + } + }; + + /** + * Usage: <user> <password> <connectString> + * <script> [ <param1> ... ] + */ + public static void main (String [] args) throws Exception { + String user = args [0]; + String pwd = args [1]; + String connect = args [2]; + File file = new File (args [3]); + + oracle.jdbc.driver.OracleDriver.class.getName (); + + Connection conn = null; //tmp + //DriverManager.getConnection (connect, user, pwd); + + ScriptExecutionEnvironment env = new ScriptExecutionEnvironment (); + + env.setConnection (conn); + env.setLogger (LOGGER); + env.setScriptFinder ( + new NonCachingSearchPathResolver ( + new File [] { + file.getParentFile () + } + ) + ); + String [] paramValues = new String [args.length - 4]; + System.arraycopy (args, 4, paramValues, 0, paramValues.length); + + env.setParameterValues (paramValues); + + Script script = new Script (env); + + script.read (file); + + script.execute (); + + if (conn != null) + conn.close (); + } +} diff --git a/src/deltix/util/jdbc/JavaCallStatement.java b/src/deltix/util/jdbc/JavaCallStatement.java index fe068e83..164a3991 100644 --- a/src/deltix/util/jdbc/JavaCallStatement.java +++ b/src/deltix/util/jdbc/JavaCallStatement.java @@ -16,7 +16,7 @@ public JavaCallStatement (String className) throws IOException public void execute (ScriptExecutionEnvironment env) throws SQLException, IOException, InterruptedException { - env.getLogger ().println ("CALL new " + mClassName + " ().run (connection)"); + env.getLogger ().logCommand ("CALL new " + mClassName + " ().run (env)"); DatabaseOperation op; diff --git a/src/deltix/util/jdbc/PromptStatement.java b/src/deltix/util/jdbc/PromptStatement.java index 46dd45e5..63dae022 100644 --- a/src/deltix/util/jdbc/PromptStatement.java +++ b/src/deltix/util/jdbc/PromptStatement.java @@ -13,6 +13,6 @@ public PromptStatement (String prompt) { public void execute (ScriptExecutionEnvironment env) throws SQLException, InterruptedException { - env.getLogger ().println (mPrompt); + env.getLogger ().logCommand (mPrompt); } } \ No newline at end of file diff --git a/src/deltix/util/jdbc/SQLScriptStatement.java b/src/deltix/util/jdbc/SQLScriptStatement.java index 1e24f8d5..eb720c16 100644 --- a/src/deltix/util/jdbc/SQLScriptStatement.java +++ b/src/deltix/util/jdbc/SQLScriptStatement.java @@ -1,8 +1,6 @@ package deltix.util.jdbc; -import deltix.util.lang.StringUtils; -import java.sql.SQLException; - +import java.sql.*; class SQLScriptStatement implements ScriptStatement { private String mSQL; @@ -53,12 +51,17 @@ public void execute (ScriptExecutionEnvironment env) exeSQL = mSQL; if (env.getLogger () != null) - env.getLogger ().println (exeSQL); + env.getLogger ().logCommand (exeSQL); + + if (env.getConnection () != null) { + Statement stmt = env.getConnection ().createStatement (); - try { - env.getStockStatement ().execute (exeSQL); - } catch (SQLException ex) { - throw ex; + try { + stmt.execute (exeSQL); + stmt.close (); + } finally { + JDBCUtils.close (stmt); + } } } } diff --git a/src/deltix/util/jdbc/Script.java b/src/deltix/util/jdbc/Script.java index 8b2ba488..97ec0397 100644 --- a/src/deltix/util/jdbc/Script.java +++ b/src/deltix/util/jdbc/Script.java @@ -18,124 +18,15 @@ public class Script { private static final int PLSQL = 2; private static final int DDL = 3; - private List mStatements = new ArrayList (); - private Connection mConnection = null; - private Statement mStockStatement = null; - private String [] mParamValues = null; - private PrintWriter mLogger = null; - private FilenameResolver mScriptFinder = null; - private ScriptExecutionEnvironment mEnv = - new ScriptExecutionEnvironment () { - public Statement getStockStatement () { - return (mStockStatement); - } - - public String[] getParameterValues () { - return (mParamValues); - } - - public PrintWriter getLogger () { - return (mLogger); - } - - public Connection getConnection () { - return (mConnection); - } - }; + private List mStatements = + new ArrayList (); + private ScriptExecutionEnvironment mEnv; /** * Constructs an empty script. */ - public Script () { - } - - /** - * Returns the connection property. - */ - public Connection getConnection () { - return (mConnection); - } - - /** - * Assigns the connection property. - */ - public void setConnection (Connection value) - throws SQLException - { - mConnection = value; - } - - /** - * Returns the paramValues property. - * Occurrences of &1 in the script - * are substituted with paramValues [0], - * etc. If the script does not use parameters, - * this argument can be null. Parameters with numbers - * greater than paramValues.length + 1 - * will not be replaced at all, and will most - * likely cause a SQL error. - */ - public String [] getParameterValues () { - return (mParamValues); - } - - /** - * Assigns the paramValues property. - * Occurrences of &1 in the script - * are substituted with paramValues [0], - * etc. If the script does not use parameters, - * this argument can be null. Parameters with numbers - * greater than paramValues.length + 1 - * will not be replaced at all, and will most - * likely cause a SQL error. - * - * @exception IllegalArgumentException - * When more than 9 parameters are specified. - */ - public void setParameterValues (String [] value) { - int num = value.length; - - if (num > 9) - throw new IllegalArgumentException ( - "Only &1 .. &9 (nine parameters) are supported." - ); - - mParamValues = value; - } - - /** - * Returns the logger property. If not null, - * each statement is logged to this logger before execution. - */ - public PrintWriter getLogger () { - return (mLogger); - } - - /** - * Assigns the logger property. If not null, - * each statement is logged to this logger before execution. - */ - public void setLogger (PrintWriter value) { - mLogger = value; - } - - /** - * Returns the scriptFinder property, used to resolve - * script inclusion. - */ - public FilenameResolver getScriptFinder () { - return (mScriptFinder); - } - - /** - * Assigns the scriptFinder property, used to resolve - * script inclusion. - */ - public void setScriptFinder ( - FilenameResolver value - ) - { - mScriptFinder = value; + public Script (ScriptExecutionEnvironment env) { + mEnv = env; } /** @@ -194,12 +85,11 @@ public void read (Reader rd) throws IOException { test.charAt (testLength - 1) == ';' ? testLength - 1 : testLength; - mStatements.add ( - new AtStatement ( - test.substring (first, last).trim (), - mScriptFinder - ) - ); + Script subScript = new Script (mEnv); + + subScript.read (test.substring (first, last).trim ()); + + mStatements.add (new AtStatement (subScript)); continue; } @@ -353,7 +243,7 @@ public void read (String relPath) throws IOException { if (relPath.lastIndexOf (".") == -1) relPath += ".sql"; - InputStream is = mScriptFinder.open (relPath); + InputStream is = mEnv.getScriptFinder ().open (relPath); if (is == null) throw new FileNotFoundException (relPath); @@ -371,50 +261,9 @@ public void read (String relPath) throws IOException { public void execute () throws SQLException, InterruptedException, IOException { - mStockStatement = mConnection.createStatement (); - - try { - for (ScriptStatement s : mStatements) - s.execute (mEnv); - } finally { - JDBCUtils.close (mStockStatement); - } + for (ScriptStatement s : mStatements) + s.execute (mEnv); } - /** - * Usage: <user> <password> <connectString> - * <script> [ <param1> ... ] - */ - public static void main (String [] args) throws Exception { - String user = args [0]; - String pwd = args [1]; - String connect = args [2]; - File file = new File (args [3]); - - oracle.jdbc.driver.OracleDriver.class.getName (); - Connection conn = - DriverManager.getConnection (connect, user, pwd); - - Script script = new Script (); - - script.setConnection (conn); - script.setLogger (new PrintWriter (System.out)); - script.setScriptFinder ( - new NonCachingSearchPathResolver ( - new File [] { - file.getParentFile () - } - ) - ); - script.read (file); - - String [] paramValues = new String [args.length - 4]; - System.arraycopy (args, 4, paramValues, 0, paramValues.length); - - script.setParameterValues (paramValues); - - script.execute (); - conn.close (); - } } diff --git a/src/deltix/util/jdbc/ScriptExecutionEnvironment.java b/src/deltix/util/jdbc/ScriptExecutionEnvironment.java index 918387e3..d86871a1 100644 --- a/src/deltix/util/jdbc/ScriptExecutionEnvironment.java +++ b/src/deltix/util/jdbc/ScriptExecutionEnvironment.java @@ -1,17 +1,86 @@ package deltix.util.jdbc; +import deltix.util.io.*; import java.sql.*; -import java.io.*; /** * */ -public interface ScriptExecutionEnvironment { - public Connection getConnection (); - - public String [] getParameterValues (); - - public PrintWriter getLogger (); - - public Statement getStockStatement (); +public class ScriptExecutionEnvironment { + private Connection mConnection = null; + private String [] mParameterValues = null; + private ScriptExecutionLogger mLogger = null; + private FilenameResolver mScriptFinder; + + /** + * Returns the DB connection, or null + */ + public Connection getConnection () { + return (mConnection); + } + + /** + * See the documentation for {@link #getConnection} + */ + public void setConnection (Connection value) { + mConnection = value; + } + + /** + * Returns the parameterValues property. + */ + public String [] getParameterValues () { + return (mParameterValues); + } + + /** + * Returns the parameterValues property. + * Occurrences of &1 in the script + * are substituted with parameterValues [0], + * etc. If the script does not use parameters, + * this argument can be null. Parameters with numbers + * greater than paramValues.length + 1 + * will not be replaced at all, and will most + * likely cause a SQL error. + */ + public void setParameterValues (String [] value) { + int num = value.length; + + if (num > 9) + throw new IllegalArgumentException ( + "Only &1 .. &9 (nine parameters) are supported." + ); + + mParameterValues = value; + } + + /** + * Returns the logger property. + */ + public ScriptExecutionLogger getLogger () { + return (mLogger); + } + + /** + * See the documentation for {@link #getLogger} + */ + public void setLogger (ScriptExecutionLogger value) { + mLogger = value; + } + + /** + * Returns the scriptFinder property. + */ + public FilenameResolver getScriptFinder () { + return (mScriptFinder); + } + + /** + * See the documentation for {@link #getScriptFinder} + */ + public void setScriptFinder (FilenameResolver value) { + mScriptFinder = value; + } + + } diff --git a/src/deltix/util/jdbc/ScriptExecutionLogger.java b/src/deltix/util/jdbc/ScriptExecutionLogger.java new file mode 100644 index 00000000..db665471 --- /dev/null +++ b/src/deltix/util/jdbc/ScriptExecutionLogger.java @@ -0,0 +1,8 @@ +package deltix.util.jdbc; + +/** + * + */ +public interface ScriptExecutionLogger { + public void logCommand (String cmd); +} From c5e860016ef54c7558171255af978b1d178f793f Mon Sep 17 00:00:00 2001 From: gene Date: Sun, 22 Oct 2006 23:13:18 +0000 Subject: [PATCH 0012/2572] --- src/deltix/util/jdbc/JSQLPlus.java | 12 +++++++++--- src/deltix/util/swing/SwingUtil.java | 15 ++++++++++++++- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/deltix/util/jdbc/JSQLPlus.java b/src/deltix/util/jdbc/JSQLPlus.java index 0732154a..31e17992 100644 --- a/src/deltix/util/jdbc/JSQLPlus.java +++ b/src/deltix/util/jdbc/JSQLPlus.java @@ -1,9 +1,11 @@ package deltix.util.jdbc; +import java.io.*; +import java.sql.*; +import java.util.*; + import deltix.util.io.NonCachingSearchPathResolver; -import java.io.File; -import java.sql.Connection; -import java.sql.DriverManager; + /** * Provides functionality to ORACLE's SQL*Plus interpreter, with many restrictions and @@ -13,7 +15,11 @@ public class JSQLPlus { private static ScriptExecutionLogger LOGGER = new ScriptExecutionLogger () { public void logCommand (String cmd) { + System.out.println ("========================="); + System.out.println (new java.util.Date () + ":"); System.out.println (cmd); + System.out.println ("========================="); + System.out.println (); } }; diff --git a/src/deltix/util/swing/SwingUtil.java b/src/deltix/util/swing/SwingUtil.java index 85086d69..ddaf0798 100644 --- a/src/deltix/util/swing/SwingUtil.java +++ b/src/deltix/util/swing/SwingUtil.java @@ -152,13 +152,26 @@ public static void staticHandle (Throwable x) { staticHandle (null, x); } - public static void asyncInvoke (Runnable r) { + public static void asyncInvoke (Runnable r) { if (SwingUtilities.isEventDispatchThread()) r.run(); else SwingUtilities.invokeLater (r); } + public static void asyncHandle (final Component parent, final Throwable x) { + if (SwingUtilities.isEventDispatchThread()) + staticHandle (parent, x); + else + SwingUtilities.invokeLater ( + new Runnable () { + public void run () { + staticHandle (parent, x); + } + } + ); + } + public static void setWindowsLookAndFeel () { try { UIManager.setLookAndFeel ("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); From ccb5bdf5ca473516b3819e23f07d6838bc601f43 Mon Sep 17 00:00:00 2001 From: gene Date: Mon, 23 Oct 2006 16:36:29 +0000 Subject: [PATCH 0013/2572] --- src/deltix/util/Justification.java | 10 ++ src/deltix/util/Util.java | 46 +++++- .../util/io/ClassLoaderFilenameResolver.java | 60 +++++-- .../util/io/NonCachingSearchPathResolver.java | 6 +- src/deltix/util/jdbc/AtStatement.java | 2 +- src/deltix/util/jdbc/DatabaseOperation.java | 2 +- src/deltix/util/jdbc/JDBCUtils.java | 156 +++++++++++++++++- src/deltix/util/jdbc/JSQLPlus.java | 8 + src/deltix/util/jdbc/JavaCallStatement.java | 2 +- src/deltix/util/jdbc/SQLScriptStatement.java | 35 +++- src/deltix/util/jdbc/Script.java | 16 +- .../util/jdbc/ScriptExecutionEnvironment.java | 25 ++- .../util/jdbc/ScriptExecutionLogger.java | 7 + src/deltix/util/jdbc/ScriptStatement.java | 2 +- src/deltix/util/swing/AbstractApp.java | 62 +++++-- src/deltix/util/swing/SwingUtil.java | 32 +++- src/deltix/util/swing/VerticalForm.java | 2 +- 17 files changed, 413 insertions(+), 60 deletions(-) create mode 100644 src/deltix/util/Justification.java diff --git a/src/deltix/util/Justification.java b/src/deltix/util/Justification.java new file mode 100644 index 00000000..5680eed2 --- /dev/null +++ b/src/deltix/util/Justification.java @@ -0,0 +1,10 @@ +package deltix.util; + +/** + * Left, right or center. + */ +public enum Justification { + LEFT, + RIGHT, + CENTER +} diff --git a/src/deltix/util/Util.java b/src/deltix/util/Util.java index 5b001d76..59f51e83 100644 --- a/src/deltix/util/Util.java +++ b/src/deltix/util/Util.java @@ -14,7 +14,8 @@ /** Set of usefull methods */ public class Util { - public static final Logger LOGGER = Logger.getLogger ("deltix.util"); + public static final String LOGGER_NAME = "deltix.util"; + public static final Logger LOGGER = Logger.getLogger (LOGGER_NAME); public static void writeNullableString (String s, ObjectOutput os) throws IOException @@ -879,4 +880,47 @@ public static int indexOf (Object [] array, Object elem) { return (-1); } + + public static void format ( + StringBuffer out, + Object obj, + Justification j, + int width, + String clip + ) + { + String s = obj.toString (); + int length = s.length (); + int diff = width - length; + + if (diff < 0) { + int clipLength = clip.length (); + int showLength = width - clipLength; + + if (showLength > 0) { + out.append (s, 0, showLength); + showLength = 0; + } + + out.append (clip, 0, clipLength + showLength); + } + else { + int lpad, rpad; + + switch (j) { + case LEFT: lpad = diff; rpad = 0; break; + case RIGHT: rpad = diff; lpad = 0; break; + case CENTER: lpad = diff / 2; rpad = diff - lpad; break; + default: throw new RuntimeException ("Unrecognized: " + j); + } + + for (int ii = 0; ii < lpad; ii++) + out.append (" "); + + out.append (s); + + for (int ii = 0; ii < rpad; ii++) + out.append (" "); + } + } } diff --git a/src/deltix/util/io/ClassLoaderFilenameResolver.java b/src/deltix/util/io/ClassLoaderFilenameResolver.java index 83e1dfc2..2cdde8f5 100644 --- a/src/deltix/util/io/ClassLoaderFilenameResolver.java +++ b/src/deltix/util/io/ClassLoaderFilenameResolver.java @@ -6,29 +6,48 @@ * Adapts java.lang.ClassLoader to the FilenameResolver interface. */ public class ClassLoaderFilenameResolver implements FilenameResolver { + public static final FilenameResolver STD_CLASSPATH_RESOLVER = + new ClassLoaderFilenameResolver ( + ClassLoaderFilenameResolver.class.getClassLoader () + ); + private ClassLoader mDelegate; + private String [] mRoots; /** * Creates an instance of FilenameResolver, which delegates all requests * to delegate. - */ - public ClassLoaderFilenameResolver (ClassLoader delegate) { + * + * @param delegate A ClassLoader on which getResourceAsStream () is called. + * Supply null to use the SystemClassLoader. + * @param roots A set of paths that are sequentially + * searched for the specified relative paths. Not supplying any arguments + * is equivalent to supplying a single empty string, which causes + * the search to start at the top. + */ + public ClassLoaderFilenameResolver (ClassLoader delegate, String ... roots) { mDelegate = delegate; + mRoots = roots.length == 0 ? new String [] { "" } : roots; } /** * Creates an instance of FilenameResolver, which delegates all requests * to the system ClassLoader. + * + * @param roots A set of paths that are sequentially + * searched for the specified relative paths. Not supplying any arguments + * is equivalent to supplying a single empty string, which causes + * the search to start at the top. */ - public ClassLoaderFilenameResolver () { - this (null); + public ClassLoaderFilenameResolver (String ... roots) { + this (null, roots); } /** * Throws an exception. */ public File find (String relPath) { - throw new RuntimeException ( + throw new UnsupportedOperationException ( "Impossible to get a File out of a ClassLoader" ); } @@ -37,10 +56,31 @@ public File find (String relPath) { * Opens a resource using the underlying class loader. */ public InputStream open (String relPath) throws IOException { - return ( - mDelegate == null ? - ClassLoader.getSystemResourceAsStream (relPath) : - mDelegate.getResourceAsStream (relPath) - ); + StringBuffer sb = new StringBuffer (); + + for (String root : mRoots) { + if (root.length () > 0) { + sb.append (root); + + if (!root.endsWith ("/")) + sb.append ("/"); + } + + sb.append (relPath); + + String resultingPath = sb.toString (); + + InputStream is = + mDelegate == null ? + ClassLoader.getSystemResourceAsStream (resultingPath) : + mDelegate.getResourceAsStream (resultingPath); + + if (is != null) + return (is); + + sb.setLength (0); + } + + return (null); } } diff --git a/src/deltix/util/io/NonCachingSearchPathResolver.java b/src/deltix/util/io/NonCachingSearchPathResolver.java index 21bc66ee..a24209e3 100644 --- a/src/deltix/util/io/NonCachingSearchPathResolver.java +++ b/src/deltix/util/io/NonCachingSearchPathResolver.java @@ -15,13 +15,13 @@ public class NonCachingSearchPathResolver implements FilenameResolver { * @param roots A set of directories that are sequentially * searched for the specified files. */ - public NonCachingSearchPathResolver (File [] roots) { + public NonCachingSearchPathResolver (File ... roots) { mRoots = roots; } public File find (String relPath) throws IOException { - for (int ii = 0; ii < mRoots.length; ii++) { - File test = new File (mRoots [ii], relPath); + for (File root : mRoots) { + File test = new File (root, relPath); if (test.exists ()) return (test); diff --git a/src/deltix/util/jdbc/AtStatement.java b/src/deltix/util/jdbc/AtStatement.java index 779e3d13..cc8e85a1 100644 --- a/src/deltix/util/jdbc/AtStatement.java +++ b/src/deltix/util/jdbc/AtStatement.java @@ -16,7 +16,7 @@ public AtStatement (Script script) throws IOException { } public void execute (ScriptExecutionEnvironment env) - throws SQLException, InterruptedException, IOException + throws SQLException, InterruptedException { mScript.execute (); } diff --git a/src/deltix/util/jdbc/DatabaseOperation.java b/src/deltix/util/jdbc/DatabaseOperation.java index 16974c55..5e0fd71c 100644 --- a/src/deltix/util/jdbc/DatabaseOperation.java +++ b/src/deltix/util/jdbc/DatabaseOperation.java @@ -13,5 +13,5 @@ public interface DatabaseOperation { * @param env The execution environment. */ public void run (ScriptExecutionEnvironment env) - throws SQLException, InterruptedException, IOException; + throws SQLException, InterruptedException; } diff --git a/src/deltix/util/jdbc/JDBCUtils.java b/src/deltix/util/jdbc/JDBCUtils.java index 133c78bd..085d1703 100644 --- a/src/deltix/util/jdbc/JDBCUtils.java +++ b/src/deltix/util/jdbc/JDBCUtils.java @@ -1,9 +1,11 @@ package deltix.util.jdbc; -import deltix.custom.statestreet.fxa.utils.*; import java.sql.*; import java.util.logging.*; import java.util.*; +import java.io.*; + +import deltix.util.*; /** * @@ -95,7 +97,7 @@ public static void rollbackNoExceptions (Connection conn) { try { conn.rollback (); } catch (Throwable x) { - Common.LOGGER.log (Level.SEVERE, "Error while rolling back a transaction", x); + Util.LOGGER.log (Level.SEVERE, "Error while rolling back a transaction", x); } } @@ -104,7 +106,7 @@ public static void close (Connection conn) { try { conn.close (); } catch (Throwable x) { - Common.LOGGER.log (Level.SEVERE, "Error while closing a connection", x); + Util.LOGGER.log (Level.SEVERE, "Error while closing a connection", x); } } @@ -113,7 +115,7 @@ public static void close (Statement stmt) { try { stmt.close (); } catch (Throwable x) { - Common.LOGGER.log (Level.SEVERE, "Error while closing a statement", x); + Util.LOGGER.log (Level.SEVERE, "Error while closing a statement", x); } } @@ -122,7 +124,7 @@ public static void close (ResultSet rs) { try { rs.close (); } catch (Throwable x) { - Common.LOGGER.log (Level.SEVERE, "Error while closing a result set", x); + Util.LOGGER.log (Level.SEVERE, "Error while closing a result set", x); } } @@ -177,4 +179,148 @@ public static void exec (Connection conn, List sqlList) close (stmt); } } + + public static void formatResultSet ( + StringBuffer out, + ResultSet rs, + int maxLineWidth, + boolean printHeaders, + String left, + String columnSeparator, + String right, + char headerUnderscore, + String clip, + Justification [] columnJustification + ) + throws SQLException + { + if (left == null) + left = ""; + + if (right == null) + right = ""; + + if (columnSeparator == null) + columnSeparator = "|"; + + ResultSetMetaData rsmd = rs.getMetaData (); + int numColumns = rsmd.getColumnCount (); + List rows = new ArrayList (); + String [] headers = null; + int [] widths = new int [numColumns]; + + if (printHeaders) { + headers = new String [numColumns]; + + for (int ii = 0; ii < numColumns; ii++) { + String label = rsmd.getColumnLabel (ii + 1); + headers [ii] = label; + widths [ii] = label.length (); + } + } + + while (rs.next ()) { + Object [] row = new Object [numColumns]; + + for (int ii = 0; ii < numColumns; ii++) { + String value = rs.getString (ii + 1); + row [ii] = value; + widths [ii] = value.length (); + } + + rows.add (row); + } + + int formatOverhead = + left.length () + right.length () + + columnSeparator.length () * (numColumns - 1); + + int availWidth = maxLineWidth - formatOverhead; + int avgWidth = availWidth / numColumns; + int totalWidth = 0; + int totalWidthOfColsLEAvg = 0; + + for (int w : widths) { + totalWidth += w; + + if (w <= avgWidth) + totalWidthOfColsLEAvg += w; + } + + /* + * If we exceed the width quota, shrink columns that are + * larger than average + */ + if (totalWidth > availWidth) { + double totalWidthOfColsGrAvg = totalWidth - totalWidthOfColsLEAvg; + double widthAvailForLargeCols = availWidth - totalWidthOfColsLEAvg; + + double k = widthAvailForLargeCols / totalWidthOfColsGrAvg; + + if (k >= 1) + throw new RuntimeException ("logic error"); + + for (int ii = 0; ii < numColumns; ii++) { + int w = widths [ii]; + + if (w > avgWidth) + w = (int) (w * k); + + /* + * Even maxLineWidth will be overridden to show at least one char per column. + */ + if (w == 0) + w = 1; + + widths [ii] = w; + } + } + + int lineWidth = formatOverhead; + + for (int w : widths) + lineWidth += w; + + if (printHeaders) { + out.append (left); + + for (int ii = 0; ii < numColumns; ii++) { + if (ii > 0) + out.append (columnSeparator); + + String header = headers [ii]; + + Util.format (out, header, Justification.CENTER, widths [ii], clip); + } + + out.append (right); + out.append ("\n"); + + for (int ii = 0; ii < lineWidth; ii++) + out.append (headerUnderscore); + + out.append ("\n"); + } + + for (Object [] row : rows) { + out.append (left); + + for (int ii = 0; ii < numColumns; ii++) { + if (ii > 0) + out.append (columnSeparator); + + Object cell = row [ii]; + Justification j = + columnJustification == null || columnJustification.length <= ii ? + Justification.RIGHT : + columnJustification [ii]; + + Util.format (out, cell, j, widths [ii], clip); + } + + out.append (right); + out.append ("\n"); + } + } + } diff --git a/src/deltix/util/jdbc/JSQLPlus.java b/src/deltix/util/jdbc/JSQLPlus.java index 31e17992..e3aaf167 100644 --- a/src/deltix/util/jdbc/JSQLPlus.java +++ b/src/deltix/util/jdbc/JSQLPlus.java @@ -14,6 +14,14 @@ public class JSQLPlus { private static ScriptExecutionLogger LOGGER = new ScriptExecutionLogger () { + public int getWidth () { + return (80); + } + + public void logResults (String text) { + System.out.println (text); + } + public void logCommand (String cmd) { System.out.println ("========================="); System.out.println (new java.util.Date () + ":"); diff --git a/src/deltix/util/jdbc/JavaCallStatement.java b/src/deltix/util/jdbc/JavaCallStatement.java index 164a3991..204ffad8 100644 --- a/src/deltix/util/jdbc/JavaCallStatement.java +++ b/src/deltix/util/jdbc/JavaCallStatement.java @@ -14,7 +14,7 @@ public JavaCallStatement (String className) throws IOException } public void execute (ScriptExecutionEnvironment env) - throws SQLException, IOException, InterruptedException + throws SQLException, InterruptedException { env.getLogger ().logCommand ("CALL new " + mClassName + " ().run (env)"); diff --git a/src/deltix/util/jdbc/SQLScriptStatement.java b/src/deltix/util/jdbc/SQLScriptStatement.java index eb720c16..d547f39a 100644 --- a/src/deltix/util/jdbc/SQLScriptStatement.java +++ b/src/deltix/util/jdbc/SQLScriptStatement.java @@ -12,9 +12,6 @@ public SQLScriptStatement (String sql) { public void execute (ScriptExecutionEnvironment env) throws SQLException, InterruptedException { - if (Thread.interrupted ()) - throw new InterruptedException (); - String exeSQL; String [] paramValues = env.getParameterValues (); @@ -50,14 +47,38 @@ public void execute (ScriptExecutionEnvironment env) else exeSQL = mSQL; - if (env.getLogger () != null) - env.getLogger ().logCommand (exeSQL); + ScriptExecutionLogger logger = env.getLogger (); + + if (logger != null) + logger.logCommand (exeSQL); if (env.getConnection () != null) { - Statement stmt = env.getConnection ().createStatement (); + PreparedStatement stmt = + env.getConnection ().prepareStatement (exeSQL); try { - stmt.execute (exeSQL); + if (logger != null && exeSQL.toLowerCase ().trim ().startsWith ("select")) { + ResultSet rs = stmt.executeQuery (); + StringBuffer sb = new StringBuffer (); + + JDBCUtils.formatResultSet ( + sb, + rs, + logger.getWidth (), + true, + "| ", + " | ", + " |", + '-', + "...", + null + ); + + logger.logResults (sb.toString ()); + } + else + stmt.execute (); + stmt.close (); } finally { JDBCUtils.close (stmt); diff --git a/src/deltix/util/jdbc/Script.java b/src/deltix/util/jdbc/Script.java index 97ec0397..56b9886a 100644 --- a/src/deltix/util/jdbc/Script.java +++ b/src/deltix/util/jdbc/Script.java @@ -47,8 +47,8 @@ public void read (Reader rd) throws IOException { if (l == null) break; - String test = - l.trim ().toLowerCase ().replace ('\t', ' '); + String lineLower = l.toLowerCase (); + String test = lineLower.trim ().replace ('\t', ' '); // // Test for empty line. // @@ -66,8 +66,10 @@ public void read (Reader rd) throws IOException { // Test for prompt statement // if (test.startsWith ("prompt")) { + int pos = lineLower.indexOf ("prompt"); + mStatements.add ( - new PromptStatement (test.substring (6).trim ()) + new PromptStatement (l.substring (pos + 6).trim ()) ); continue; @@ -259,10 +261,14 @@ public void read (String relPath) throws IOException { * Executes the script. */ public void execute () - throws SQLException, InterruptedException, IOException + throws SQLException, InterruptedException { - for (ScriptStatement s : mStatements) + for (ScriptStatement s : mStatements) { + if (Thread.interrupted ()) + throw new InterruptedException (); + s.execute (mEnv); + } } diff --git a/src/deltix/util/jdbc/ScriptExecutionEnvironment.java b/src/deltix/util/jdbc/ScriptExecutionEnvironment.java index d86871a1..fae6e548 100644 --- a/src/deltix/util/jdbc/ScriptExecutionEnvironment.java +++ b/src/deltix/util/jdbc/ScriptExecutionEnvironment.java @@ -7,11 +7,28 @@ * */ public class ScriptExecutionEnvironment { - private Connection mConnection = null; - private String [] mParameterValues = null; - private ScriptExecutionLogger mLogger = null; + private Connection mConnection; + private String [] mParameterValues; + private ScriptExecutionLogger mLogger; private FilenameResolver mScriptFinder; - + + public ScriptExecutionEnvironment ( + Connection conn, + ScriptExecutionLogger logger, + FilenameResolver scriptFinder, + String ... params + ) + { + mConnection = conn; + mLogger = logger; + mScriptFinder = scriptFinder; + mParameterValues = params; + } + + public ScriptExecutionEnvironment () { + this (null, null, ClassLoaderFilenameResolver.STD_CLASSPATH_RESOLVER); + } + /** * Returns the DB connection, or null */ diff --git a/src/deltix/util/jdbc/ScriptExecutionLogger.java b/src/deltix/util/jdbc/ScriptExecutionLogger.java index db665471..18d437cb 100644 --- a/src/deltix/util/jdbc/ScriptExecutionLogger.java +++ b/src/deltix/util/jdbc/ScriptExecutionLogger.java @@ -5,4 +5,11 @@ */ public interface ScriptExecutionLogger { public void logCommand (String cmd); + + public void logResults (String text); + + /** + * Width in characters + */ + public int getWidth (); } diff --git a/src/deltix/util/jdbc/ScriptStatement.java b/src/deltix/util/jdbc/ScriptStatement.java index 23a6d8bb..e86274b6 100644 --- a/src/deltix/util/jdbc/ScriptStatement.java +++ b/src/deltix/util/jdbc/ScriptStatement.java @@ -6,5 +6,5 @@ interface ScriptStatement { public void execute (ScriptExecutionEnvironment env) - throws SQLException, InterruptedException, IOException; + throws SQLException, InterruptedException; } \ No newline at end of file diff --git a/src/deltix/util/swing/AbstractApp.java b/src/deltix/util/swing/AbstractApp.java index 5da4c557..12d51b2f 100644 --- a/src/deltix/util/swing/AbstractApp.java +++ b/src/deltix/util/swing/AbstractApp.java @@ -1,18 +1,43 @@ package deltix.util.swing; +import java.awt.event.*; import java.util.logging.*; import java.io.*; import javax.swing.*; +import deltix.util.*; import deltix.util.io.*; public abstract class AbstractApp extends JFrame { protected AbstractApp () { - setDefaultCloseOperation (EXIT_ON_CLOSE); + this (EXIT_ON_CLOSE); + } + + protected AbstractApp (int defaultCloseOperation) { + setDefaultCloseOperation (defaultCloseOperation); + + addWindowListener ( + new WindowAdapter () { + public void windowClosing (WindowEvent e) { + AbstractApp.this.windowClosing (e); + } + } + ); + } + + protected void windowClosing (WindowEvent e) { } public void handle (Throwable x) { - SwingUtil.staticHandle (this, x); + handle (x, Level.SEVERE); + } + + public void handle ( + Throwable x, + Level logLevel + ) + { + handle (x, Util.LOGGER, logLevel); } public void handle ( @@ -24,6 +49,27 @@ public void handle ( SwingUtil.staticHandle (this, x, logger, logLevel); } + public void asyncHandle (Throwable x) { + asyncHandle (x, Level.SEVERE); + } + + public void asyncHandle ( + Throwable x, + Level logLevel + ) + { + asyncHandle (x, Util.LOGGER, logLevel); + } + + public void asyncHandle ( + Throwable x, + Logger logger, + Level logLevel + ) + { + SwingUtil.asyncHandle (this, x, logger, logLevel); + } + public void syncInvoke (Runnable r) throws InterruptedException { @@ -37,18 +83,6 @@ public void syncInvoke (Runnable r) } } - public void syncHandle (final Throwable x) - throws InterruptedException - { - syncInvoke ( - new Runnable () { - public void run () { - handle (x); - } - } - ); - } - public void printUsage () throws IOException, InterruptedException { String cname = getClass ().getName (); int dot = cname.lastIndexOf ('.'); diff --git a/src/deltix/util/swing/SwingUtil.java b/src/deltix/util/swing/SwingUtil.java index ddaf0798..cc0ff1f4 100644 --- a/src/deltix/util/swing/SwingUtil.java +++ b/src/deltix/util/swing/SwingUtil.java @@ -144,12 +144,17 @@ public static void staticHandle ( ); } - public static void staticHandle (Component parent, Throwable x) { - staticHandle (parent, x, Util.LOGGER, Level.WARNING); + public static void staticHandle ( + Component parent, + Throwable x, + Level logLevel + ) + { + staticHandle (parent, x, Util.LOGGER, logLevel); } public static void staticHandle (Throwable x) { - staticHandle (null, x); + staticHandle (null, x, Level.SEVERE); } public static void asyncInvoke (Runnable r) { @@ -159,14 +164,29 @@ public static void asyncInvoke (Runnable r) { SwingUtilities.invokeLater (r); } - public static void asyncHandle (final Component parent, final Throwable x) { + public static void asyncHandle ( + final Component parent, + final Throwable x, + final Level level + ) + { + asyncHandle (parent, x, Util.LOGGER, level); + } + + public static void asyncHandle ( + final Component parent, + final Throwable x, + final Logger logger, + final Level level + ) + { if (SwingUtilities.isEventDispatchThread()) - staticHandle (parent, x); + staticHandle (parent, x, logger, level); else SwingUtilities.invokeLater ( new Runnable () { public void run () { - staticHandle (parent, x); + staticHandle (parent, x, logger, level); } } ); diff --git a/src/deltix/util/swing/VerticalForm.java b/src/deltix/util/swing/VerticalForm.java index f9e799c7..088f35d8 100644 --- a/src/deltix/util/swing/VerticalForm.java +++ b/src/deltix/util/swing/VerticalForm.java @@ -5,7 +5,7 @@ import java.awt.event.*; import javax.swing.*; -public class VerticalForm extends JPanel { +public class VerticalForm extends EnablingPanel { private GridBagConstraints mC = new GridBagConstraints (); private Set mSwitchComponents = new HashSet (); From e40a026d967350da165e881774e74847c7c182ff Mon Sep 17 00:00:00 2001 From: gene Date: Mon, 23 Oct 2006 21:12:51 +0000 Subject: [PATCH 0014/2572] --- src/deltix/util/collections/ArrayList.vtl | 767 ++++++++++++++++++ src/deltix/util/collections/HashMapBase.java | 194 +++++ .../util/collections/PrimitiveEnumeration.vtl | 7 + src/deltix/util/jdbc/PromptStatement.java | 4 +- src/deltix/util/jdbc/SQLScriptStatement.java | 47 +- src/deltix/util/jdbc/Script.java | 6 + .../util/jdbc/ScriptExecutionEnvironment.java | 38 + 7 files changed, 1020 insertions(+), 43 deletions(-) create mode 100644 src/deltix/util/collections/ArrayList.vtl create mode 100644 src/deltix/util/collections/HashMapBase.java create mode 100644 src/deltix/util/collections/PrimitiveEnumeration.vtl diff --git a/src/deltix/util/collections/ArrayList.vtl b/src/deltix/util/collections/ArrayList.vtl new file mode 100644 index 00000000..f77851e1 --- /dev/null +++ b/src/deltix/util/collections/ArrayList.vtl @@ -0,0 +1,767 @@ +package deltix.util.collections; + +import java.util.*; + +import deltix.util.memory.*; + +/** + * Resizable array of primitive ${prim}s. Much more efficient than + * keeping a java.util.ArrayList of ${wrap}. + */ +public final class ${wrap}ArrayList + extends AbstractList + implements List, Cloneable, java.io.Serializable, MemorySizeEstimator +{ + static final long serialVersionUID = 1L; + + /** + * The array buffer into which the elements of the ArrayList are stored. + * The capacity of the ArrayList is the length of this array buffer. + * + * @serial + */ + private ${prim} elementData[]; + + /** + * The size of the ArrayList (the number of elements it contains). + * + * @serial + */ + private int size; + + public int getSizeInMemory () { + return (OBJECT_OVERHEAD + elementData.length * ${size}); + } + + /** + * Constructs an empty list with the specified initial capacity. + * + * @param initialCapacity the initial capacity of the list. + * @exception IllegalArgumentException if the specified initial capacity + * is negative + */ + public ${wrap}ArrayList(int initialCapacity) { + super(); + if (initialCapacity < 0) + throw new IllegalArgumentException("Illegal Capacity: "+ + initialCapacity); + this.elementData = new ${prim} [initialCapacity]; + } + + /** + * Constructs an empty list. + */ + public ${wrap}ArrayList() { + this(10); + } + + /** + * Constructs a list containing the elements of the specified + * collection, in the order they are returned by the collection's + * iterator. The ArrayList instance has an initial capacity of + * 110% the size of the specified collection. + * + * @param c the collection whose elements are to be placed into this list. + */ + public ${wrap}ArrayList(Collection c) { + size = c.size (); + elementData = new ${prim} [(size*110) / 100]; + // Allow 10% room for growth + Iterator iter = c.iterator (); + int idx = 0; + + while (iter.hasNext ()) + elementData [idx] = +#if( $wrap == "Object" ) + iter.next (); +#else + ((${wrap}) iter.next ()).${prim}Value (); +#end + } + + public ${wrap}ArrayList (${prim} [] arr) { + size = arr.length; + elementData = new ${prim} [(size*110) / 100]; + for (int idx = 0; idx < size; idx++) + elementData[idx] = arr[idx]; + } + + /** + * Trims the capacity of this ArrayList instance to be the + * list's current size. An application can use this operation to minimize + * the storage of an ArrayList instance. + */ + public void trimToSize() { + modCount++; + int oldCapacity = elementData.length; + if (size < oldCapacity) { + ${prim} oldData [] = elementData; + elementData = new ${prim} [size]; + System.arraycopy (oldData, 0, elementData, 0, size); + } + } + + /** + * Increases the capacity of this ArrayList instance, if + * necessary, to ensure that it can hold at least the number of elements + * specified by the minimum capacity argument. + * + * @param minCapacity the desired minimum capacity. + */ + public void ensureCapacity(int minCapacity) { + modCount++; + int oldCapacity = elementData.length; + if (minCapacity > oldCapacity) { + ${prim} oldData [] = elementData; + int newCapacity = (oldCapacity * 3)/2 + 1; + if (newCapacity < minCapacity) + newCapacity = minCapacity; + elementData = new ${prim} [newCapacity]; + System.arraycopy (oldData, 0, elementData, 0, size); + } + } + + /** + * Returns the number of elements in this list. + * + * @return the number of elements in this list. + */ + public int size () { + return size; + } + + /** + * Tests if this list has no elements. + * + * @return true if this list has no elements; + * false otherwise. + */ + public boolean isEmpty() { + return size == 0; + } + +#if( $wrap == "Object" ) + /** + * Returns an array containing all of the elements in this list in the + * correct order. The runtime type of the returned array is that of the + * specified array. If the list fits in the specified array, it is + * returned therein. Otherwise, a new array is allocated with the runtime + * type of the specified array and the size of this list.

+ * + * If the list fits in the specified array with room to spare (i.e., the + * array has more elements than the list), the element in the array + * immediately following the end of the collection is set to + * null. + * + * @param a the array into which the elements of the list are to + * be stored, if it is big enough; otherwise, a new array of the + * same runtime type is allocated for this purpose. + * @return an array containing the elements of the list. + * @throws ArrayStoreException if the runtime type of a is not a supertype + * of ${wrap}. + */ + public Object [] toArray(Object a[]) { + if (a.length < size) + a = (Object[]) + java.lang.reflect.Array.newInstance ( + a.getClass ().getComponentType (), + size + ); + + System.arraycopy (elementData, 0, a, 0, size); + + if (a.length > size) + a [size] = null; + + return a; + } + + /** + * Returns the element at the specified position in this list. + * + * @param index index of element to return. + * @return the element at the specified position in this list. + * @throws IndexOutOfBoundsException if index is out of range (index + * < 0 || index >= size()). + */ + public Object get (int index) { + return (get${wrap} (index)); + } + +#else + /** + * Returns the element at the specified position in this list. + * + * @param index index of element to return. + * @return the element at the specified position in this list. + * @throws IndexOutOfBoundsException if index is out of range (index + * < 0 || index >= size()). + */ + public Object get (int index) { + return new ${wrap} (get${wrap} (index)); + } + + /** + * Returns an array containing all of the elements in this list in the + * correct order. The runtime type of the returned array is that of the + * specified array. If the list fits in the specified array, it is + * returned therein. Otherwise, a new array is allocated with the runtime + * type of the specified array and the size of this list.

+ * + * If the list fits in the specified array with room to spare (i.e., the + * array has more elements than the list), the element in the array + * immediately following the end of the collection is set to + * null. + * + * @param a the array into which the elements of the list are to + * be stored, if it is big enough; otherwise, a new array of the + * same runtime type is allocated for this purpose. + * @return an array containing the elements of the list. + * @throws ArrayStoreException if the runtime type of a is not a supertype + * of ${wrap}. + */ + public Object [] toArray(Object a[]) { + if (a.length < size) + a = new ${wrap} [size]; + + for (int ii = 0; ii < size; ii++) + a [ii] = new ${wrap} (elementData [ii]); + + if (a.length > size) + a [size] = null; + + return a; + } + + /** + * Returns true if this list contains the specified element. + * + * @param elem element whose presence in this List is to be tested. + */ + public boolean contains (Object elem) { + return indexOf (elem) >= 0; + } + + /** + * Searches for the first occurence of the given argument, testing + * for equality. + * + * @param elem an object. + * @return the index of the first occurrence of the argument in this + * list; returns -1 if the object is not found. + */ + public int indexOf(Object elem) { + return (indexOf (((${wrap}) elem).${prim}Value ())); + } + + /** + * Returns the index of the last occurrence of the specified ${prim} in + * this list. + * + * @param elem the desired element. + * @return the index of the last occurrence of the specified ${prim} in + * this list; returns -1 if the object is not found. + */ + public int lastIndexOf (Object elem) { + return (lastIndexOf (((${wrap}) elem).${prim}Value ())); + } + + /** + * Replaces the element at the specified position in this list with + * the specified element. + * + * @param index index of element to replace. + * @param element element to be stored at the specified position. + * @return the element previously at the specified position. + * @throws IndexOutOfBoundsException if index out of range + * (index < 0 || index >= size()). + */ + public Object set (int index, Object element) { + return (new ${wrap} (set (index, ((${wrap}) element).${prim}Value ()))); + } + + /** + * Appends the specified element to the end of this list. + * + * @param o element to be appended to this list. + * @return true (as per the general contract of Collection.add). + */ + public boolean add (Object o) { + return (add (((${wrap}) o).${prim}Value ())); + } + + /** + * Inserts the specified element at the specified position in this + * list. Shifts the element currently at that position (if any) and + * any subsequent elements to the right (adds one to their indices). + * + * @param index index at which the specified element is to be inserted. + * @param element element to be inserted. + * @throws IndexOutOfBoundsException if index is out of range + * (index < 0 || index > size()). + */ + public void add (int index, Object element) { + add (index, ((${wrap}) element).${prim}Value ()); + } +#end + + /** + * Returns true if this list contains the specified element. + * + * @param elem element whose presence in this List is to be tested. + */ + public boolean contains (${prim} elem) { + return indexOf (elem) >= 0; + } + + /** + * Searches for the first occurence of the given argument, testing + * for equality. + * + * @param elem an object. + * @return the index of the first occurrence of the argument in this + * list; returns -1 if the object is not found. + */ + public int indexOf (${prim} elem) { + for (int i = 0; i < size; i++) + if (elem == elementData[i]) + return i; + return -1; + } + + /** + * Returns the index of the last occurrence of the specified ${prim} in + * this list. + * + * @param elem the desired element. + * @return the index of the last occurrence of the specified ${prim} in + * this list; returns -1 if the object is not found. + */ + public int lastIndexOf (${prim} elem) { + for (int i = size-1; i >= 0; i--) + if (elem == elementData [i]) + return i; + return -1; + } + + /** + * Returns a copy of this ${wrap}ArrayList instance. + * + * @return a clone of this ${wrap}ArrayList instance. + */ + public Object clone () { + try { + ${wrap}ArrayList v = (${wrap}ArrayList) super.clone(); + v.elementData = new ${prim} [size]; + System.arraycopy (elementData, 0, v.elementData, 0, size); + v.modCount = 0; + return v; + } catch (CloneNotSupportedException e) { + // this shouldn't happen, since we are Cloneable + throw new InternalError(); + } + } + + /** + * Returns an Object array containing all of the elements in this list + * in the correct order. + * + * @return an array containing all of the elements in this list + * in the correct order. + */ + public Object [] toArray() { + Object [] result = new Object[size]; + return toArray (result); + } + + /** + * Returns a ${prim} array containing all of the elements in this list + * in the correct order. + * + * @return an array containing all of the elements in this list + * in the correct order. + */ + public ${prim} [] to${wrap}Array () { + ${prim} [] ret = new ${prim} [size]; + System.arraycopy (elementData, 0, ret, 0, size); + return (ret); + } + + + // Positional Access Operations + + /** + * Returns the element at the specified position in this list. + * + * @param index index of element to return. + * @return the element at the specified position in this list. + * @throws IndexOutOfBoundsException if index is out of range (index + * < 0 || index >= size()). + */ + public ${prim} get${wrap} (int index) { + RangeCheck(index); + return elementData[index]; + } + + /** + * Returns the element at the specified position in this list, bypassing + * the range check. + * @param index index of element to return. + * @return the element at the specified position in this list. + */ + public ${prim} get${wrap}NoRangeCheck (int index) { + return elementData [index]; + } + + /** + * Replaces the element at the specified position in this list with + * the specified element. + * + * @param index index of element to replace. + * @param element element to be stored at the specified position. + * @return the element previously at the specified position. + * @throws IndexOutOfBoundsException if index out of range + * (index < 0 || index >= size()). + */ + public ${prim} set (int index, ${prim} element) { + RangeCheck(index); + ${prim} oldValue = elementData[index]; + elementData[index] = element; + return oldValue; + } + + /** + * Appends the specified element to the end of this list. + * + * @param d element to be appended to this list. + * @return true (as per the general contract of Collection.add). + */ + public boolean add (${prim} d) { + ensureCapacity(size + 1); // Increments modCount!! + elementData[size++] = d; + return true; + } + + /** + * Inserts the specified element at the specified position in this + * list. Shifts the element currently at that position (if any) and + * any subsequent elements to the right (adds one to their indices). + * + * @param index index at which the specified element is to be inserted. + * @param element element to be inserted. + * @throws IndexOutOfBoundsException if index is out of range + * (index < 0 || index > size()). + */ + public void add (int index, ${prim} element) { + if (index > size || index < 0) + throw new IndexOutOfBoundsException( + "Index: "+index+", Size: "+size); + + ensureCapacity (size+1); // Increments modCount!! + System.arraycopy(elementData, index, elementData, index + 1, + size - index); + elementData[index] = element; + size++; + } + + /** + * Removes the element at the specified position in this list. + * Shifts any subsequent elements to the left (subtracts one from their + * indices). + * + * @param index the index of the element to removed. + * @return the element that was removed from the list. + * @throws IndexOutOfBoundsException if index out of range (index + * < 0 || index >= size()). + */ + public Object remove (int index) { +#if( $wrap == "Object" ) + return (removeObject (index)); +#else + return (new ${wrap} (remove${wrap} (index))); +#end + } + + /** + * Removes the element at the specified position in this list. + * Shifts any subsequent elements to the left (subtracts one from their + * indices). + * + * @param index the index of the element to removed. + * @return the element that was removed from the list. + * @throws IndexOutOfBoundsException if index out of range (index + * < 0 || index >= size()). + */ + public ${prim} remove${wrap} (int index) { + RangeCheck(index); + + modCount++; + ${prim} oldValue = elementData[index]; + + int numMoved = size - index - 1; + if (numMoved > 0) + System.arraycopy(elementData, index+1, elementData, index, + numMoved); + + size--; + return oldValue; + } + + /** + * Removes all of the elements from this list. The list will + * be empty after this call returns. + */ + public void clear() { + modCount++; + size = 0; + } + + /** + * Appends all of the elements in the specified Collection to the end of + * this list, in the order that they are returned by the + * specified Collection's Iterator. The behavior of this operation is + * undefined if the specified Collection is modified while the operation + * is in progress. (This implies that the behavior of this call is + * undefined if the specified Collection is this list, and this + * list is nonempty.) + * + * @param c the elements to be inserted into this list. + * @throws IndexOutOfBoundsException if index out of range (index + * < 0 || index > size()). + */ + public boolean addAll (Collection c) { + modCount++; + int numNew = c.size(); + ensureCapacity(size + numNew); + + Iterator e = c.iterator(); + for (int i=0; i(index + * < 0 || index > size()). + */ + public boolean addAll(int index, Collection c) { + if (index > size || index < 0) + throw new IndexOutOfBoundsException( + "Index: "+index+", Size: "+size); + + int numNew = c.size(); + ensureCapacity(size + numNew); // Increments modCount!! + + int numMoved = size - index; + if (numMoved > 0) + System.arraycopy(elementData, index, elementData, index + numNew, + numMoved); + + Iterator e = c.iterator(); + for (int i=0; i(toIndex - fromIndex) elements. + * (If toIndex==fromIndex, this operation has no effect.) + * + * @param fromIndex index of first element to be removed. + * @param toIndex index after last element to be removed. + */ + public void removeRange (int fromIndex, int toIndex) { + modCount++; + int numMoved = size - toIndex; + System.arraycopy ( + elementData, toIndex, elementData, fromIndex, numMoved + ); + size -= (toIndex - fromIndex); + } + + /** + * Check if the given index is in range. If not, throw an appropriate + * runtime exception. + */ + private void RangeCheck(int index) { + if (index >= size || index < 0) + throw new IndexOutOfBoundsException( + "Index: "+index+", Size: "+size); + } + + /** + * Save the state of the ArrayList instance to a stream (that + * is, serialize it). + * + * @serialData The length of the array backing the ArrayList + * instance is emitted (int), followed by all of its elements + * (each an Object) in the proper order. + */ + private synchronized void writeObject(java.io.ObjectOutputStream s) + throws java.io.IOException + { + // Write out array length + s.writeInt(size); + + // Write out all elements in the proper order. + for (int i=0; iArrayList instance from a stream (that is, + * deserialize it). + */ + private synchronized void readObject (java.io.ObjectInputStream s) + throws java.io.IOException, ClassNotFoundException + { + // Read in array length and allocate array + size = s.readInt(); + elementData = new ${prim} [size]; + + // Read in all elements in the proper order. + for (int i=0; i= mThreshold) + rehash (2 * tableSize ()); + } + + protected final void onRemove (int pos) { + mStatus [pos] = DELETED; + mCount--; + } + + public void ensureCapacity (int capacity) { + if (mThreshold < capacity) + rehash (2*capacity); + } + + public void clear () { + Arrays.fill (mStatus, EMPTY); + mUsedCells = mCount = 0; + } + + /// serialization code + + static final long serialVersionUID = 1L; + static final short mSerialVersion = 1; + + private void writeObject (java.io.ObjectOutputStream out) + throws java.io.IOException + { + out.writeShort (mSerialVersion); + } + + private void readObject (java.io.ObjectInputStream in) + throws java.io.IOException, ClassNotFoundException + { + short readSerialVersion = in.readShort(); + } + +} diff --git a/src/deltix/util/collections/PrimitiveEnumeration.vtl b/src/deltix/util/collections/PrimitiveEnumeration.vtl new file mode 100644 index 00000000..65586d8d --- /dev/null +++ b/src/deltix/util/collections/PrimitiveEnumeration.vtl @@ -0,0 +1,7 @@ +package deltix.util.collections; + +import java.util.Enumeration; + +public interface ${wrap}Enumeration extends Enumeration { + public ${prim} next${abbr}Element (); +} diff --git a/src/deltix/util/jdbc/PromptStatement.java b/src/deltix/util/jdbc/PromptStatement.java index 63dae022..e15b1422 100644 --- a/src/deltix/util/jdbc/PromptStatement.java +++ b/src/deltix/util/jdbc/PromptStatement.java @@ -13,6 +13,6 @@ public PromptStatement (String prompt) { public void execute (ScriptExecutionEnvironment env) throws SQLException, InterruptedException { - env.getLogger ().logCommand (mPrompt); + env.getLogger ().logCommand (env.substituteParameters (mPrompt)); } -} \ No newline at end of file +} diff --git a/src/deltix/util/jdbc/SQLScriptStatement.java b/src/deltix/util/jdbc/SQLScriptStatement.java index d547f39a..fff9d1e3 100644 --- a/src/deltix/util/jdbc/SQLScriptStatement.java +++ b/src/deltix/util/jdbc/SQLScriptStatement.java @@ -12,53 +12,18 @@ public SQLScriptStatement (String sql) { public void execute (ScriptExecutionEnvironment env) throws SQLException, InterruptedException { - String exeSQL; - String [] paramValues = env.getParameterValues (); - - if (paramValues != null) { - StringBuffer sb = new StringBuffer (); - int pos = 0; - int len = mSQL.length (); - - for (;;) { - int idx = mSQL.indexOf ("&", pos); - - if (idx == -1) - break; - - int idx1 = idx + 1; - - if (idx1 == len) - break; - - char ch = mSQL.charAt (idx1); - int pidx = ch - '1'; - - if (pidx > 0 && pidx < paramValues.length) { - sb.append (mSQL, pos, idx); - sb.append (paramValues [pidx]); - pos = idx + 2; - } - } - - sb.append (mSQL, pos, len); - exeSQL = sb.toString (); - } - else - exeSQL = mSQL; - + String exeSQL = env.substituteParameters (mSQL); ScriptExecutionLogger logger = env.getLogger (); if (logger != null) logger.logCommand (exeSQL); if (env.getConnection () != null) { - PreparedStatement stmt = - env.getConnection ().prepareStatement (exeSQL); + Statement stmt = env.getConnection ().createStatement (); try { if (logger != null && exeSQL.toLowerCase ().trim ().startsWith ("select")) { - ResultSet rs = stmt.executeQuery (); + ResultSet rs = stmt.executeQuery (exeSQL); StringBuffer sb = new StringBuffer (); JDBCUtils.formatResultSet ( @@ -66,9 +31,9 @@ public void execute (ScriptExecutionEnvironment env) rs, logger.getWidth (), true, - "| ", + "", " | ", - " |", + "", '-', "...", null @@ -77,7 +42,7 @@ public void execute (ScriptExecutionEnvironment env) logger.logResults (sb.toString ()); } else - stmt.execute (); + stmt.execute (exeSQL); stmt.close (); } finally { diff --git a/src/deltix/util/jdbc/Script.java b/src/deltix/util/jdbc/Script.java index 56b9886a..bd9a262e 100644 --- a/src/deltix/util/jdbc/Script.java +++ b/src/deltix/util/jdbc/Script.java @@ -62,6 +62,12 @@ public void read (Reader rd) throws IOException { continue; if (state == OUTSIDE) { + // + // Test for exit statement. + // + if (test.startsWith ("exit")) { + break; + } // // Test for prompt statement // diff --git a/src/deltix/util/jdbc/ScriptExecutionEnvironment.java b/src/deltix/util/jdbc/ScriptExecutionEnvironment.java index fae6e548..697ca6a4 100644 --- a/src/deltix/util/jdbc/ScriptExecutionEnvironment.java +++ b/src/deltix/util/jdbc/ScriptExecutionEnvironment.java @@ -99,5 +99,43 @@ public void setScriptFinder (FilenameResolver va mScriptFinder = value; } + public String substituteParameters ( + String in + ) + { + if (mParameterValues == null) + return (in); + + StringBuffer sb = new StringBuffer (); + int pos = 0; + int len = in.length (); + + for (;;) { + int idx = in.indexOf ("&", pos); + + if (idx == -1) + break; + + int idx1 = idx + 1; + if (idx1 == len) + break; + + char ch = in.charAt (idx1); + int pidx = ch - '1'; + + if (pidx >= 0 && pidx < mParameterValues.length) { + sb.append (in, pos, idx); + sb.append (mParameterValues [pidx]); + pos = idx + 2; + } + else { + sb.append (in, pos, idx1); + pos = idx1; + } + } + + sb.append (in, pos, len); + return (sb.toString ()); + } } From f6a807fec22ca9a5d7a06a8dd0158a956338008b Mon Sep 17 00:00:00 2001 From: gene Date: Tue, 24 Oct 2006 16:25:46 +0000 Subject: [PATCH 0015/2572] --- src/deltix/util/jdbc/Script.java | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/deltix/util/jdbc/Script.java b/src/deltix/util/jdbc/Script.java index bd9a262e..bd132eb1 100644 --- a/src/deltix/util/jdbc/Script.java +++ b/src/deltix/util/jdbc/Script.java @@ -85,17 +85,24 @@ public void read (Reader rd) throws IOException { // that lie entirely on one line. // if (test.charAt (0) == '@') { - int testLength = test.length (); + String lineTrimmed = l.trim (); + int lineLength = lineTrimmed.length (); + int first = - test.charAt (1) == '@' ? 2 : 1; + lineTrimmed.charAt (1) == '@' ? 2 : 1; int last = - test.charAt (testLength - 1) == ';' ? - testLength - 1 : testLength; + lineTrimmed.charAt (lineLength - 1) == ';' ? + lineLength - 1 : lineLength; Script subScript = new Script (mEnv); - subScript.read (test.substring (first, last).trim ()); + // Hack : discard parameters + String s = lineTrimmed.substring (first, last).trim (); + StringTokenizer stk = new StringTokenizer (s); + String fname = stk.nextToken (); + + subScript.read (fname); mStatements.add (new AtStatement (subScript)); From 6333a6bbdc887560c2eb0ff69c5b695f348b1dad Mon Sep 17 00:00:00 2001 From: gene Date: Tue, 24 Oct 2006 18:55:30 +0000 Subject: [PATCH 0016/2572] Added CSV splitter utility. Created runjava Rerouted fxa batch files to use runjava. --- src/deltix/util/jdbc/ScriptExecutionEnvironment.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/deltix/util/jdbc/ScriptExecutionEnvironment.java b/src/deltix/util/jdbc/ScriptExecutionEnvironment.java index 697ca6a4..21cd4736 100644 --- a/src/deltix/util/jdbc/ScriptExecutionEnvironment.java +++ b/src/deltix/util/jdbc/ScriptExecutionEnvironment.java @@ -25,6 +25,15 @@ public ScriptExecutionEnvironment ( mParameterValues = params; } + public ScriptExecutionEnvironment (ScriptExecutionEnvironment copy) { + this ( + copy.getConnection (), + copy.getLogger (), + copy.getScriptFinder (), + copy.getParameterValues () + ); + } + public ScriptExecutionEnvironment () { this (null, null, ClassLoaderFilenameResolver.STD_CLASSPATH_RESOLVER); } From 3024ceeb39552de02df9620a964b49e046efde8d Mon Sep 17 00:00:00 2001 From: jacob Date: Wed, 1 Nov 2006 00:16:24 +0000 Subject: [PATCH 0017/2572] primitive ArrayLists primitive to {primitive, Object} HashMaps --- .../util/collections/ArrayEnumeration.java | 32 +-- src/deltix/util/collections/HashMapBase.java | 229 +++++++++--------- 2 files changed, 131 insertions(+), 130 deletions(-) diff --git a/src/deltix/util/collections/ArrayEnumeration.java b/src/deltix/util/collections/ArrayEnumeration.java index 637d8c26..9d74b97d 100644 --- a/src/deltix/util/collections/ArrayEnumeration.java +++ b/src/deltix/util/collections/ArrayEnumeration.java @@ -1,33 +1,33 @@ package deltix.util.collections; -import java.util.*; +import java.util.Enumeration; +import java.util.NoSuchElementException; public class ArrayEnumeration implements Enumeration { - - private Object [] mArray; + + private Object[] mArray; private int mIdx; private boolean mHasNext; - - public ArrayEnumeration (Object [] array){ + + public ArrayEnumeration(Object[] array) { mArray = array; mIdx = 0; - mHasNext =(array != null && array.length > 0); + mHasNext = (array != null && array.length > 0); } - - public boolean hasMoreElements(){ + + public boolean hasMoreElements() { return mHasNext; } - - public Object nextElement(){ - - if (mHasNext){ + + public Object nextElement() { + + if (mHasNext) { Object o = mArray[mIdx]; mIdx++; - mHasNext =(mIdx < mArray.length); + mHasNext = (mIdx < mArray.length); return o; - } - else throw new NoSuchElementException("No Elements left in Enumeration"); - + } else throw new NoSuchElementException("No Elements left in Enumeration"); + } } \ No newline at end of file diff --git a/src/deltix/util/collections/HashMapBase.java b/src/deltix/util/collections/HashMapBase.java index a3337c76..6176f7e3 100644 --- a/src/deltix/util/collections/HashMapBase.java +++ b/src/deltix/util/collections/HashMapBase.java @@ -1,36 +1,35 @@ package deltix.util.collections; -import java.util.*; -import java.io.*; +import deltix.util.memory.MemorySizeEstimator; -import deltix.util.memory.*; +import java.io.Serializable; +import java.util.Arrays; /** - * Long open addressing hash map with - * quadratic probing. + * Long open addressing hash map with + * quadratic probing. */ -public abstract class HashMapBase - implements Cloneable, Serializable, MemorySizeEstimator -{ - protected static final byte EMPTY = 0; - protected static final byte DELETED = 1; - protected static final byte FILLED = 2; - - private byte [] mStatus; - private int mThreshold; - - private int mCount = 0; - private int mUsedCells = 0; - - public int getSizeInMemory () { +public abstract class HashMapBase + implements Cloneable, Serializable, MemorySizeEstimator { + protected static final byte EMPTY = 0; + protected static final byte DELETED = 1; + protected static final byte FILLED = 2; + + private byte[] mStatus; + private int mThreshold; + + private int mCount = 0; + private int mUsedCells = 0; + + public int getSizeInMemory() { return (OBJECT_OVERHEAD + mStatus.length); } - + /** - * Reasonably quick test for prime numbers - * with 0 memory requirement. + * Reasonably quick test for prime numbers + * with 0 memory requirement. */ - private static boolean isPrime (int n) { + private static boolean isPrime(int n) { for (int i = 3; (i * i) <= n; i += 2) if (n % i == 0) return (false); @@ -39,155 +38,157 @@ private static boolean isPrime (int n) { } /** - * Returns the lowest prime number greater or equal to n. + * Returns the lowest prime number greater or equal to n. */ - private static int nextPrime (int n) { + private static int nextPrime(int n) { if (n % 2 == 0) n++; - for (; !isPrime (n); n += 2); + for (; !isPrime(n); n += 2) ; return (n); } - /** - * Allocates the internal table. - */ - protected void alloc (int tabSize) { - tabSize = nextPrime (tabSize); + /** + * Allocates the internal table. + */ + protected void alloc(int tabSize) { + tabSize = nextPrime(tabSize); - allocValues (tabSize); - allocKeys (tabSize); - mStatus = new byte [tabSize]; - mThreshold = tabSize / 2; - } + allocValues(tabSize); + allocKeys(tabSize); + mStatus = new byte[tabSize]; + mThreshold = tabSize / 2; + } /** - * Constructs a has map with specified capacity, i.e. - * number of elements that can be added before it is resized. - * The actual internal table size is at least 2*capacity. + * Constructs a has map with specified capacity, i.e. + * number of elements that can be added before it is resized. + * The actual internal table size is at least 2*capacity. */ - public HashMapBase (int initCapacity) { - alloc (Math.max (11, initCapacity * 2 + 1)); + public HashMapBase(int initCapacity) { + alloc(Math.max(11, initCapacity * 2 + 1)); } /** - * Constructs a has map with default capacity. + * Constructs a has map with default capacity. */ - public HashMapBase () { - this (11); + public HashMapBase() { + this(11); } /** - * Returns the number of elements after which the table will get - * resized. + * Returns the number of elements after which the table will get + * resized. */ - public int getCapacity () { - return (mThreshold); + public int getCapacity() { + return (mThreshold); } /** - * Returns the count of elements currently in the map. + * Returns the count of elements currently in the map. */ - public int size () { - return (mCount); + public int size() { + return (mCount); } /** - * Returns whether the map is empty. + * Returns whether the map is empty. */ - public boolean isEmpty () { - return (mCount == 0); + public boolean isEmpty() { + return (mCount == 0); } /** - * Returns the size of the internal arrays. + * Returns the size of the internal arrays. */ - protected int tableSize () { - return (mStatus.length); + protected int tableSize() { + return (mStatus.length); } - protected boolean isFound (int pos) { - return (mStatus [pos] == FILLED); + protected boolean isFound(int pos) { + return (mStatus[pos] == FILLED); } - protected boolean isCellEmpty (int pos) { - return (mStatus [pos] == EMPTY); + protected boolean isCellEmpty(int pos) { + return (mStatus[pos] == EMPTY); } - protected abstract void allocValues (int size); - protected abstract void allocKeys (int size); - protected abstract int rehashOne (Object keys, Object values, int idx); - protected abstract Object keyArray (); - protected abstract Object valueArray (); - - protected final void rehash (int newCapacity) { - Object saveKeys = keyArray (); - Object saveValues = valueArray (); - byte [] saveStatus = mStatus; + protected abstract void allocValues(int size); + + protected abstract void allocKeys(int size); - int tabSize = tableSize (); + protected abstract int rehashOne(Object keys, Object values, int idx); - if (newCapacity < tabSize) - throw new IllegalArgumentException ("Requested " + - newCapacity + " elements, but size is already " + - tabSize - ); - else if (newCapacity == tabSize) - return; + protected abstract Object keyArray(); - alloc (newCapacity); + protected abstract Object valueArray(); - for (int ii = 0; ii < tabSize; ii++) - if (saveStatus [ii] == FILLED) { - int pos = rehashOne (saveKeys, saveValues, ii); - mStatus [pos] = FILLED; - } - - mUsedCells = mCount; + protected final void rehash(int newCapacity) { + Object saveKeys = keyArray(); + Object saveValues = valueArray(); + byte[] saveStatus = mStatus; + + int tabSize = tableSize(); + + if (newCapacity < tabSize) + throw new IllegalArgumentException("Requested " + + newCapacity + " elements, but size is already " + + tabSize + ); + else if (newCapacity == tabSize) + return; + + alloc(newCapacity); + + for (int ii = 0; ii < tabSize; ii++) + if (saveStatus[ii] == FILLED) { + int pos = rehashOne(saveKeys, saveValues, ii); + mStatus[pos] = FILLED; + } + + mUsedCells = mCount; } - protected final void onPut (int pos, boolean wasNotFound) { - mStatus [pos] = FILLED; - if (wasNotFound) { - mCount++; - mUsedCells ++; - } + protected final void onPut(int pos, boolean wasNotFound) { + mStatus[pos] = FILLED; + if (wasNotFound) { + mCount++; + mUsedCells++; + } - if (mUsedCells >= mThreshold) - rehash (2 * tableSize ()); + if (mUsedCells >= mThreshold) + rehash(2 * tableSize()); } - - protected final void onRemove (int pos) { - mStatus [pos] = DELETED; - mCount--; + + protected final void onRemove(int pos) { + mStatus[pos] = DELETED; + mCount--; } - - public void ensureCapacity (int capacity) { - if (mThreshold < capacity) - rehash (2*capacity); + + public void ensureCapacity(int capacity) { + if (mThreshold < capacity) + rehash(2 * capacity); } - public void clear () { - Arrays.fill (mStatus, EMPTY); - mUsedCells = mCount = 0; + public void clear() { + Arrays.fill(mStatus, EMPTY); + mUsedCells = mCount = 0; } /// serialization code - static final long serialVersionUID = 1L; + static final long serialVersionUID = 1L; static final short mSerialVersion = 1; - private void writeObject (java.io.ObjectOutputStream out) - throws java.io.IOException - { - out.writeShort (mSerialVersion); + private void writeObject(java.io.ObjectOutputStream out) + throws java.io.IOException { + out.writeShort(mSerialVersion); } - private void readObject (java.io.ObjectInputStream in) - throws java.io.IOException, ClassNotFoundException - { + private void readObject(java.io.ObjectInputStream in) + throws java.io.IOException, ClassNotFoundException { short readSerialVersion = in.readShort(); } From 07c24a3735391aad1c4f9a0ea153e7a9dbf7ae2e Mon Sep 17 00:00:00 2001 From: jacob Date: Thu, 2 Nov 2006 22:51:41 +0000 Subject: [PATCH 0018/2572] primitive ArrayLists primitive to {primitive, Object} HashMaps --- src/deltix/util/collections/ArrayList.vtl | 2 +- src/deltix/util/collections/PrimitiveEnumeration.vtl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/deltix/util/collections/ArrayList.vtl b/src/deltix/util/collections/ArrayList.vtl index f77851e1..d3dddf17 100644 --- a/src/deltix/util/collections/ArrayList.vtl +++ b/src/deltix/util/collections/ArrayList.vtl @@ -1,4 +1,4 @@ -package deltix.util.collections; +package deltix.util.collections.generated; import java.util.*; diff --git a/src/deltix/util/collections/PrimitiveEnumeration.vtl b/src/deltix/util/collections/PrimitiveEnumeration.vtl index 65586d8d..4ae7cacf 100644 --- a/src/deltix/util/collections/PrimitiveEnumeration.vtl +++ b/src/deltix/util/collections/PrimitiveEnumeration.vtl @@ -1,4 +1,4 @@ -package deltix.util.collections; +package deltix.util.collections.generated; import java.util.Enumeration; From 8e59d02756950a018275fcf0b2a2a3b575867dfb Mon Sep 17 00:00:00 2001 From: gene Date: Mon, 6 Nov 2006 21:22:53 +0000 Subject: [PATCH 0019/2572] --- src/deltix/util/io/IOUtil.java | 17 +++++ src/deltix/util/jdbc/ORACLE.java | 19 +++++- src/deltix/util/lang/MathUtil.java | 106 +++++++++++++++++++++++++++++ 3 files changed, 141 insertions(+), 1 deletion(-) create mode 100644 src/deltix/util/lang/MathUtil.java diff --git a/src/deltix/util/io/IOUtil.java b/src/deltix/util/io/IOUtil.java index ba372307..dce36052 100644 --- a/src/deltix/util/io/IOUtil.java +++ b/src/deltix/util/io/IOUtil.java @@ -12,6 +12,23 @@ * */ public class IOUtil { + /** + * Output character ch n times to Writer + * wr. + */ + public static void pad (char ch, int n, Writer wr) throws IOException { + for (int ii = 0; ii < n; ii++) + wr.write (ch); + } + + /** + * Output character ch n times to PrintStream + * ps. + */ + public static void pad (char ch, int n, PrintStream ps) throws IOException { + for (int ii = 0; ii < n; ii++) + ps.print (ch); + } /** * Return the short name of teh file without the extension. */ diff --git a/src/deltix/util/jdbc/ORACLE.java b/src/deltix/util/jdbc/ORACLE.java index bd5a1f22..9357fd23 100644 --- a/src/deltix/util/jdbc/ORACLE.java +++ b/src/deltix/util/jdbc/ORACLE.java @@ -8,7 +8,6 @@ import deltix.util.Util; -/** @deprecated */ public class ORACLE { public static void loadDriver () throws ClassNotFoundException { Class.forName ("oracle.jdbc.driver.OracleDriver"); @@ -22,6 +21,24 @@ public static void loadDriver () throws ClassNotFoundException { } } + public static Connection openThinConnection ( + String host, + int port, + String sid, + String user, + String password + ) + throws SQLException + { + return ( + DriverManager.getConnection ( + "jdbc:oracle:thin:@" + host + ":" + port + ":" + sid, + user, + password + ) + ); + } + public static void test (Connection conn) throws SQLException { Statement stmt = conn.createStatement (); diff --git a/src/deltix/util/lang/MathUtil.java b/src/deltix/util/lang/MathUtil.java new file mode 100644 index 00000000..466fbb23 --- /dev/null +++ b/src/deltix/util/lang/MathUtil.java @@ -0,0 +1,106 @@ +package deltix.util.lang; + +public class MathUtil { + public static final double TWO_PI = Math.PI * 2; + + /** + * Returns 1 if a && !b, -1 if !a && b, 0 if a == b. + */ + public static int sign (boolean a, boolean b) { + return (a ? (b ? 0 : 1) : (b ? -1 : 0)); + } + + /** + * Returns 1, -1, or 0 if the argument is + * greater, less than, or equal to 0 respectively. + */ + public static int sign (double x) { + return (x > 0 ? 1 : x < 0 ? -1 : 0); + } + + /** + * Returns 1, -1, or 0 if the argument is + * greater, less than, or equal to 0 respectively. + */ + public static int sign (float x) { + return (x > 0 ? 1 : x < 0 ? -1 : 0); + } + + /** + * Returns 1, -1, or 0 if the argument is + * greater, less than, or equal to 0 respectively. + */ + public static int sign (int x) { + return (x > 0 ? 1 : x < 0 ? -1 : 0); + } + + /** + * Returns 1, -1, or 0 if the argument is + * greater, less than, or equal to 0 respectively. + */ + public static int sign (long x) { + return (x > 0 ? 1 : x < 0 ? -1 : 0); + } + + /** + * Returns the fractional part of the argument. Result is negative if + * the argument is negative. + */ + public static float frac (float x) { + return (x - (int) x); + } + + /** + * Returns the fractional part of the argument. Result is negative if + * the argument is negative. + */ + public static double frac (double x) { + return (x - (int) x); + } + + /** + * Returns the ceiling of log2 of the argument, i.e. + * the smallest integer k such that 2k >= v. + */ + public static int log2 (int v) { + int ret = 0; + int cmp = 1; + + while (v > cmp) { + ret++; + cmp <<= 1; + } + + return (ret); + } + + /** + * Normalize the angle so that it is whithin the range of (-PI .. PI]. + */ + public static double normalizeAnglePlusMinusPi (double a) { + if (a <= -Math.PI) + do { + a += TWO_PI; + } while (a <= -Math.PI); + else + while (a > TWO_PI) + a -= TWO_PI; + + return (a); + } + + /** + * Normalize the angle so that it is whithin the range of [0 .. 2*PI). + */ + public static double normalizeAngleZeroTwoPi (double a) { + if (a < 0) + do { + a += TWO_PI; + } while (a < 0); + else + while (a >= TWO_PI) + a -= TWO_PI; + + return (a); + } +} From e8e7599e2da26cff66c4fcc5f237fd210063494f Mon Sep 17 00:00:00 2001 From: gene Date: Tue, 7 Nov 2006 16:08:29 +0000 Subject: [PATCH 0020/2572] --- src/deltix/tsdb/io/pub/AbstractDataStore.java | 10 ++++----- src/deltix/tsdb/io/pub/SystemIOException.java | 21 +++++++++++++++++++ 2 files changed, 26 insertions(+), 5 deletions(-) create mode 100644 src/deltix/tsdb/io/pub/SystemIOException.java diff --git a/src/deltix/tsdb/io/pub/AbstractDataStore.java b/src/deltix/tsdb/io/pub/AbstractDataStore.java index d9ef12c8..2eae5157 100644 --- a/src/deltix/tsdb/io/pub/AbstractDataStore.java +++ b/src/deltix/tsdb/io/pub/AbstractDataStore.java @@ -10,12 +10,12 @@ public interface AbstractDataStore { * Create a new object on disk and format internally. The data store is * left open for read-write at the end of this method. */ - public void format () throws IOException; + public void format (); /** * Close the store and delete all underlying files from disk. */ - public void delete () throws IOException; + public void delete (); /** * Determines whether the store is open. @@ -25,17 +25,17 @@ public interface AbstractDataStore { /** * Open the data store. */ - public void open (boolean readOnly) throws IOException; + public void open (boolean readOnly); /** * Flush all data to disk. The disk data store is guaranteed to be consistent * at the end of this method, if it succesfully completes. */ - public void flush () throws IOException; + public void flush (); /** * Close the data store and release all resources, such as caches and * file descriptors. */ - public void close () throws IOException; + public void close (); } diff --git a/src/deltix/tsdb/io/pub/SystemIOException.java b/src/deltix/tsdb/io/pub/SystemIOException.java new file mode 100644 index 00000000..86c09621 --- /dev/null +++ b/src/deltix/tsdb/io/pub/SystemIOException.java @@ -0,0 +1,21 @@ +package deltix.tsdb.io.pub; + +import java.io.IOException; + +/** + * Unchecked exception, used to wrap the checked java.io.IOException + * occurring because of system problems. + */ +public class SystemIOException extends RuntimeException { + public SystemIOException (String msg, IOException iox) { + super (msg, iox); + } + + public SystemIOException (IOException iox) { + super ("System IO error", iox); + } + + public SystemIOException (String msg) { + super (msg); + } +} From 0cbb9d2b431a1804991294a182d97bbbb0f97676 Mon Sep 17 00:00:00 2001 From: gene Date: Wed, 8 Nov 2006 13:04:39 +0000 Subject: [PATCH 0021/2572] --- .../util/collections/ByteArrayComparator.java | 14 ++++++++ .../util/collections/PrimitiveComparator.vtl | 33 +++++++++++++++++++ .../UnsignedByteArrayComparator.java | 22 +++++++++++++ src/deltix/util/memory/DataExchangeUtils.java | 20 ++++++++--- 4 files changed, 85 insertions(+), 4 deletions(-) create mode 100644 src/deltix/util/collections/ByteArrayComparator.java create mode 100644 src/deltix/util/collections/PrimitiveComparator.vtl create mode 100644 src/deltix/util/collections/UnsignedByteArrayComparator.java diff --git a/src/deltix/util/collections/ByteArrayComparator.java b/src/deltix/util/collections/ByteArrayComparator.java new file mode 100644 index 00000000..c8f6e27e --- /dev/null +++ b/src/deltix/util/collections/ByteArrayComparator.java @@ -0,0 +1,14 @@ +package deltix.util.collections; + +/** + * Compares sequences of bytes. + */ +public interface ByteArrayComparator { + public int compare ( + byte [] data1, + int offset1, + byte [] data2, + int offset2, + int dataSize + ); +} diff --git a/src/deltix/util/collections/PrimitiveComparator.vtl b/src/deltix/util/collections/PrimitiveComparator.vtl new file mode 100644 index 00000000..14cef7bd --- /dev/null +++ b/src/deltix/util/collections/PrimitiveComparator.vtl @@ -0,0 +1,33 @@ +package deltix.util.collections.generated; + +import deltix.util.memory.*; +import deltix.util.collections.*; + +/** + * Compares keys as ${prim}s. + */ +public final class ${wrap}Comparator implements ByteArrayComparator { + private int mOrder; + + private ${wrap}Comparator (int order) { + mOrder = order; + } + + public int compare (byte [] key1, int offset1, byte [] key2, int offset2, int keySize) { + assert (keySize == MemorySizeEstimator.${size}); + + ${prim} f1 = DataExchangeUtils.read${abbr} (key1, offset1); + ${prim} f2 = DataExchangeUtils.read${abbr} (key2, offset2); + + if (f1 == f2) + return (0); + else if (f1 > f2) + return (mOrder); + else + return (-mOrder); + } + + public static final ${wrap}Comparator ASCENDING = new ${wrap}Comparator (1); + + public static final ${wrap}Comparator DESCENDING = new ${wrap}Comparator (-1); +} diff --git a/src/deltix/util/collections/UnsignedByteArrayComparator.java b/src/deltix/util/collections/UnsignedByteArrayComparator.java new file mode 100644 index 00000000..4bc35848 --- /dev/null +++ b/src/deltix/util/collections/UnsignedByteArrayComparator.java @@ -0,0 +1,22 @@ +package deltix.util.collections; + +import deltix.util.Util; + +/** + * Compares bytes arrays as unsigned MSBF. + */ +public final class UnsignedByteArrayComparator implements ByteArrayComparator { + private int mOrder; + + private UnsignedByteArrayComparator (int order) { + mOrder = order; + } + + public int compare (byte [] key1, int offset1, byte [] key2, int offset2, int keySize) { + return (mOrder * Util.arrayucomp (key1, offset1, key2, offset2, keySize)); + } + + public static final ByteArrayComparator ASCENDING = new UnsignedByteArrayComparator (1); + + public static final ByteArrayComparator DESCENDING = new UnsignedByteArrayComparator (-1); +} diff --git a/src/deltix/util/memory/DataExchangeUtils.java b/src/deltix/util/memory/DataExchangeUtils.java index 1444a75c..6ee8ddfe 100644 --- a/src/deltix/util/memory/DataExchangeUtils.java +++ b/src/deltix/util/memory/DataExchangeUtils.java @@ -33,12 +33,24 @@ public static void writeShort (byte [] bytes, int offset, short s) { b (bytes, offset + 1, s); } + public static char readChar (byte [] bytes, int offset) { + return ((char) + (b (bytes, offset) << 8 | + b (bytes, offset + 1)) + ); + } + + public static void writeChar (byte [] bytes, int offset, char s) { + b (bytes, offset, s >>> 8); + b (bytes, offset + 1, s); + } + public static int readInt (byte [] bytes, int offset) { return ( - b (bytes, offset) << 24 | - b (bytes, offset + 1) << 16 | - b (bytes, offset + 2) << 8 | - b (bytes, offset + 3) + b (bytes, offset) << 24 | + b (bytes, offset + 1) << 16 | + b (bytes, offset + 2) << 8 | + b (bytes, offset + 3) ); } From fc4894a430a0fe5659b9e61308935c72bcab5f3c Mon Sep 17 00:00:00 2001 From: gene Date: Wed, 8 Nov 2006 20:30:45 +0000 Subject: [PATCH 0022/2572] --- src/deltix/util/memory/DataExchangeUtils.java | 42 ++++++++++++------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/src/deltix/util/memory/DataExchangeUtils.java b/src/deltix/util/memory/DataExchangeUtils.java index 6ee8ddfe..78195cd6 100644 --- a/src/deltix/util/memory/DataExchangeUtils.java +++ b/src/deltix/util/memory/DataExchangeUtils.java @@ -5,21 +5,21 @@ * in precisely the same format as DataInput/DataOutput. */ public class DataExchangeUtils { - private static int b (byte [] bytes, int offset) { - return (((int) bytes [offset]) & 0xFF); - } - - private static void b (byte [] bytes, int offset, int byt) { - bytes [offset] = (byte) (byt & 0xFF); - } - - private static void b (byte [] bytes, int offset, long byt) { - bytes [offset] = (byte) (byt & 0xFF); - } - - private static long lb (byte [] bytes, int offset) { - return (((long) bytes [offset]) & 0xFF); - } + private static int b (byte [] bytes, int offset) { + return (((int) bytes [offset]) & 0xFF); + } + + private static void b (byte [] bytes, int offset, int byt) { + bytes [offset] = (byte) (byt & 0xFF); + } + + private static void b (byte [] bytes, int offset, long byt) { + bytes [offset] = (byte) (byt & 0xFF); + } + + private static long lb (byte [] bytes, int offset) { + return (((long) bytes [offset]) & 0xFF); + } public static short readShort (byte [] bytes, int offset) { return ((short) @@ -28,11 +28,23 @@ public static short readShort (byte [] bytes, int offset) { ); } + public static int readUnsignedShort (byte [] bytes, int offset) { + return ( + (b (bytes, offset) << 8 | + b (bytes, offset + 1)) + ); + } + public static void writeShort (byte [] bytes, int offset, short s) { b (bytes, offset, s >>> 8); b (bytes, offset + 1, s); } + public static void writeUnsignedShort (byte [] bytes, int offset, int s) { + b (bytes, offset, s >>> 8); + b (bytes, offset + 1, s); + } + public static char readChar (byte [] bytes, int offset) { return ((char) (b (bytes, offset) << 8 | From 8b64903ee26dedae6362de66949ee1237ae59a6d Mon Sep 17 00:00:00 2001 From: gene Date: Wed, 8 Nov 2006 23:39:14 +0000 Subject: [PATCH 0023/2572] --- src/deltix/tsdb/io/pub/SystemIOException.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/deltix/tsdb/io/pub/SystemIOException.java b/src/deltix/tsdb/io/pub/SystemIOException.java index 86c09621..26bc5f50 100644 --- a/src/deltix/tsdb/io/pub/SystemIOException.java +++ b/src/deltix/tsdb/io/pub/SystemIOException.java @@ -12,7 +12,7 @@ public SystemIOException (String msg, IOException iox) { } public SystemIOException (IOException iox) { - super ("System IO error", iox); + super ("System IO error: " + iox, iox); } public SystemIOException (String msg) { From d57afe31b3fa07f5ce197525638f492b314f0688 Mon Sep 17 00:00:00 2001 From: gene Date: Thu, 9 Nov 2006 13:44:28 +0000 Subject: [PATCH 0024/2572] --- src/deltix/util/net/TCPLogger.java | 70 ++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 src/deltix/util/net/TCPLogger.java diff --git a/src/deltix/util/net/TCPLogger.java b/src/deltix/util/net/TCPLogger.java new file mode 100644 index 00000000..9eab3d53 --- /dev/null +++ b/src/deltix/util/net/TCPLogger.java @@ -0,0 +1,70 @@ +package deltix.util.net; + +import java.io.*; +import java.net.*; + +import deltix.util.*; + +/** + * + */ +public class TCPLogger { + static class Tee extends Thread { + private OutputStream mLog; + private InputStream mIn; + private OutputStream mOut; + + public Tee (String id, InputStream is, OutputStream os) + throws IOException + { + mLog = new FileOutputStream (id); + mIn = is; + mOut = os; + } + + public void run () { + byte [] buf = new byte [1024]; + + try { + for (;;) { + int numRead = mIn.read (buf); + + if (numRead < 0) + break; + + mOut.write (buf, 0, numRead); + mOut.flush (); + + mLog.write (buf, 0, numRead); + mLog.flush (); + } + } catch (IOException iox) { + iox.printStackTrace (); + } + + Util.close (mLog); + } + } + + public static void main (String [] args) throws Exception { + String delegateHost = args [0]; + int localPort = Integer.parseInt (args [1]); + int delegatePort = Integer.parseInt (args [2]); + + ServerSocket ss = new ServerSocket (localPort); + + System.out.println ("Server ready on port " + ss.getLocalPort ()); + + int num = 0; + + for (;;) { + Socket s = ss.accept (); + num++; + + Socket delegate = new Socket (delegateHost, delegatePort); + + new Tee ("req-" + num + ".txt", s.getInputStream (), delegate.getOutputStream ()).start (); + new Tee ("resp-" + num + ".txt", delegate.getInputStream (), s.getOutputStream ()).start (); + } + } +} From f58878612ca29f9139b5ab5b425c0277438a48db Mon Sep 17 00:00:00 2001 From: gene Date: Fri, 10 Nov 2006 19:46:27 +0000 Subject: [PATCH 0025/2572] WIP on java updater --- .../{tsdb/io/pub => util/io}/AbstractDataStore.java | 8 +------- .../{tsdb/io/pub => util/io}/SystemIOException.java | 2 +- 2 files changed, 2 insertions(+), 8 deletions(-) rename src/deltix/{tsdb/io/pub => util/io}/AbstractDataStore.java (74%) rename src/deltix/{tsdb/io/pub => util/io}/SystemIOException.java (90%) diff --git a/src/deltix/tsdb/io/pub/AbstractDataStore.java b/src/deltix/util/io/AbstractDataStore.java similarity index 74% rename from src/deltix/tsdb/io/pub/AbstractDataStore.java rename to src/deltix/util/io/AbstractDataStore.java index 2eae5157..01b3bf33 100644 --- a/src/deltix/tsdb/io/pub/AbstractDataStore.java +++ b/src/deltix/util/io/AbstractDataStore.java @@ -1,4 +1,4 @@ -package deltix.tsdb.io.pub; +package deltix.util.io; import java.io.*; @@ -27,12 +27,6 @@ public interface AbstractDataStore { */ public void open (boolean readOnly); - /** - * Flush all data to disk. The disk data store is guaranteed to be consistent - * at the end of this method, if it succesfully completes. - */ - public void flush (); - /** * Close the data store and release all resources, such as caches and * file descriptors. diff --git a/src/deltix/tsdb/io/pub/SystemIOException.java b/src/deltix/util/io/SystemIOException.java similarity index 90% rename from src/deltix/tsdb/io/pub/SystemIOException.java rename to src/deltix/util/io/SystemIOException.java index 26bc5f50..701fe752 100644 --- a/src/deltix/tsdb/io/pub/SystemIOException.java +++ b/src/deltix/util/io/SystemIOException.java @@ -1,4 +1,4 @@ -package deltix.tsdb.io.pub; +package deltix.util.io; import java.io.IOException; From 65c9a9b9db493568662e7448968081932e72884a Mon Sep 17 00:00:00 2001 From: gene Date: Fri, 10 Nov 2006 21:32:56 +0000 Subject: [PATCH 0026/2572] --- src/deltix/util/time/AbsoluteDate.java | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/deltix/util/time/AbsoluteDate.java b/src/deltix/util/time/AbsoluteDate.java index 0feb43e6..c99d600d 100644 --- a/src/deltix/util/time/AbsoluteDate.java +++ b/src/deltix/util/time/AbsoluteDate.java @@ -15,6 +15,22 @@ public class AbsoluteDate implements Comparable { private byte mDay; // 1-based! public AbsoluteDate (int year, int month, int day) { + set (year, month, day); + } + + public AbsoluteDate (Calendar cal) { + set (cal); + } + + public AbsoluteDate (int num) { + set (num); + } + + public AbsoluteDate (String s) { + set (s); + } + + public void set (int year, int month, int day) { if (year < 0 || year > Short.MAX_VALUE) throw new IllegalArgumentException ("Illegal year value: " + year); @@ -29,13 +45,13 @@ public AbsoluteDate (int year, int month, int day) { mDay = (byte) day; } - public AbsoluteDate (Calendar cal) { + public void set (Calendar cal) { mYear = (short) cal.get (Calendar.YEAR); mMonth = (byte) (1 + cal.get (Calendar.MONTH)); mDay = (byte) cal.get (Calendar.DAY_OF_MONTH); } - public AbsoluteDate (int num) { + public void set (int num) { mDay = (byte) (num % 100); num = num / 100; @@ -45,7 +61,7 @@ public AbsoluteDate (int num) { mYear = (short) (num / 100); } - public AbsoluteDate (String s) { + public void set (String s) { StringTokenizer stk = new StringTokenizer (s, "-"); if (stk.countTokens () == 3) { From 93fdd832182e27db99455953f4e791c807fffc8f Mon Sep 17 00:00:00 2001 From: gene Date: Sun, 12 Nov 2006 22:36:53 +0000 Subject: [PATCH 0027/2572] --- .../util/io/ByteArrayInputStreamEx.java | 96 +++++++++++++++++++ .../util/io/ByteArrayOutputStreamEx.java | 44 +++++++++ .../util/io/ByteCountingOutputStream.java | 33 +++++++ src/deltix/util/io/Download.java | 21 ++++ src/deltix/util/io/NullOutputStream.java | 21 ++++ src/deltix/util/jdbc/JDBCUtils.java | 29 +++++- src/deltix/util/jdbc/SystemSQLException.java | 21 ++++ src/deltix/util/time/AbsoluteDate.java | 3 + 8 files changed, 265 insertions(+), 3 deletions(-) create mode 100644 src/deltix/util/io/ByteArrayInputStreamEx.java create mode 100644 src/deltix/util/io/ByteArrayOutputStreamEx.java create mode 100644 src/deltix/util/io/ByteCountingOutputStream.java create mode 100644 src/deltix/util/io/Download.java create mode 100644 src/deltix/util/io/NullOutputStream.java create mode 100644 src/deltix/util/jdbc/SystemSQLException.java diff --git a/src/deltix/util/io/ByteArrayInputStreamEx.java b/src/deltix/util/io/ByteArrayInputStreamEx.java new file mode 100644 index 00000000..fbf9d9fd --- /dev/null +++ b/src/deltix/util/io/ByteArrayInputStreamEx.java @@ -0,0 +1,96 @@ +package deltix.util.io; + +import deltix.util.collections.generated.ByteArrayList; + +/** + * Extension of java.io.ByteArrayInputStream + */ +public class ByteArrayInputStreamEx extends java.io.ByteArrayInputStream { + private static final byte [] DUMMY = { }; + + /** + * Creates ByteArrayInputStream + * that cannot read anything (will return EOFimmediately). It can be later reset. + */ + public ByteArrayInputStreamEx () { + super (DUMMY); + } + + /** + * Creates ByteArrayInputStream + * that uses buf as its + * buffer array. + * The buffer array is not copied. The buffer's mark is + * set to 0. + * + * @param buf the input buffer. + */ + public ByteArrayInputStreamEx (byte [] buf) { + super (buf); + } + + /** + * Creates ByteArrayInputStream + * that uses buf as its + * buffer array. The initial value of pos + * is offset and the initial value + * of count is the minimum of offset+length + * and buf.length. + * The buffer array is not copied. The buffer's mark is + * set to the specified offset. + * + * @param buf the input buffer. + * @param offset the offset in the buffer of the first byte to read. + * @param length the maximum number of bytes to read from the buffer. + */ + public ByteArrayInputStreamEx (byte [] buf, int offset, int length) { + super (buf, offset, length); + } + + /** + * Creates ByteArrayInputStream + * that reads the incoming {@link ByteArrayList} + */ + public ByteArrayInputStreamEx (ByteArrayList blist) { + super (blist.getInternalBuffer (), 0, blist.size ()); + } + + /** + * Returns the current position. + */ + public int getPosition () { + return (pos); + } + + /** + * Sets the current position. + */ + public void setPosition (int p) { + pos = p; + } + + /** + * Returns the underlying buffer + */ + public byte [] getBuffer () { + return (buf); + } + + public void setBuffer (byte [] b) { + buf = b; + } + + /** + * Returns the read limit + */ + public int getLimit () { + return (count); + } + + /** + * Sets the read limit + */ + public void setLimit (int n) { + count = n; + } +} diff --git a/src/deltix/util/io/ByteArrayOutputStreamEx.java b/src/deltix/util/io/ByteArrayOutputStreamEx.java new file mode 100644 index 00000000..de91b0e0 --- /dev/null +++ b/src/deltix/util/io/ByteArrayOutputStreamEx.java @@ -0,0 +1,44 @@ +package deltix.util.io; + +import java.io.*; + +/** + * Allows access to the internal buffer. + */ +public class ByteArrayOutputStreamEx extends ByteArrayOutputStream { + /** + * Creates a new byte array output stream. The buffer capacity is + * initially 32 bytes, though its size increases if necessary. + */ + public ByteArrayOutputStreamEx () { + } + + /** + * Creates a new byte array output stream, with a buffer capacity of + * the specified size, in bytes. + * + * @param size the initial size. + * @exception IllegalArgumentException if size is negative. + */ + public ByteArrayOutputStreamEx (int size) { + super (size); + } + + public byte [] getInternalBuffer () { + return (buf); + } + + /** + * Resets the current position. Seeking forward will lead to arbitrary + * data being placed in the buffer. + */ + public void reset (int position) { + if (position > buf.length) { + byte newbuf [] = new byte [Math.max (buf.length << 1, position)]; + System.arraycopy (buf, 0, newbuf, 0, count); + buf = newbuf; + } + + count = position; + } +} diff --git a/src/deltix/util/io/ByteCountingOutputStream.java b/src/deltix/util/io/ByteCountingOutputStream.java new file mode 100644 index 00000000..73ff5cd2 --- /dev/null +++ b/src/deltix/util/io/ByteCountingOutputStream.java @@ -0,0 +1,33 @@ +package deltix.util.io; + +import java.io.*; + +/** + * Counts bytes that pass through. + */ +public class ByteCountingOutputStream extends FilterOutputStream { + private long mNumBytesWritten = 0; + + public ByteCountingOutputStream (OutputStream os) { + super (os); + } + + public long getNumBytesWritten () { + return (mNumBytesWritten); + } + + public void write (byte [] b) throws IOException { + out.write (b); + mNumBytesWritten += b.length; + } + + public void write (byte [] b, int off, int len) throws IOException { + out.write (b, off, len); + mNumBytesWritten += len; + } + + public void write (int b) throws IOException { + mNumBytesWritten++; + out.write (b); + } +} diff --git a/src/deltix/util/io/Download.java b/src/deltix/util/io/Download.java new file mode 100644 index 00000000..6c7e5f2f --- /dev/null +++ b/src/deltix/util/io/Download.java @@ -0,0 +1,21 @@ +package deltix.util.io; + +import java.io.*; +import java.net.*; + +/** + * + */ +public class Download { + + public static void main (String [] args) throws Exception { + URL url = new URL (args [0]); + FileOutputStream os = new FileOutputStream (args [1]); + InputStream is = url.openStream (); + + StreamPump.pump (is, os); + + os.close (); + } + +} diff --git a/src/deltix/util/io/NullOutputStream.java b/src/deltix/util/io/NullOutputStream.java new file mode 100644 index 00000000..be9acadc --- /dev/null +++ b/src/deltix/util/io/NullOutputStream.java @@ -0,0 +1,21 @@ +package deltix.util.io; + +import java.io.OutputStream; + +/** + * Null output. + * + * Example of use: code that uses Java serialization only to traverse object graph. + */ +public class NullOutputStream extends OutputStream { + + public void write(int b) {} + + public void write(byte b[]) {} + + public void write(byte b[], int off, int len) {} + + public void flush() {} + + public void close() {} +} diff --git a/src/deltix/util/jdbc/JDBCUtils.java b/src/deltix/util/jdbc/JDBCUtils.java index 085d1703..0aaac6cc 100644 --- a/src/deltix/util/jdbc/JDBCUtils.java +++ b/src/deltix/util/jdbc/JDBCUtils.java @@ -53,12 +53,15 @@ public static int queryInt (PreparedStatement ps) throws SQLExcept } } - public static int queryInt (Connection conn, String query) + public static int queryInt (Connection conn, String query, Object ... params) throws SQLException { PreparedStatement ps = conn.prepareStatement (query); try { + for (int ii = 0; ii < params.length; ii++) + ps.setObject (ii + 1, params [ii]); + return (queryInt (ps)); } finally { close (ps); @@ -80,12 +83,15 @@ public static List queryStrings (PreparedStatement ps) } } - public static List queryStrings (Connection conn, String query) + public static List queryStrings (Connection conn, String query, Object ... params) throws SQLException { PreparedStatement ps = conn.prepareStatement (query); try { + for (int ii = 0; ii < params.length; ii++) + ps.setObject (ii + 1, params [ii]); + return (queryStrings (ps)); } finally { close (ps); @@ -149,7 +155,7 @@ public static void prepare (Connection conn, String tname, TableOp case TRUNCATE: truncateTable (conn, tname); break; } } - + /* public static void exec (Connection conn, String sql) throws SQLException { @@ -163,6 +169,23 @@ public static void exec (Connection conn, String sql) close (stmt); } } + */ + public static void exec (Connection conn, String sql, Object ... params) + throws SQLException + { + PreparedStatement ps = conn.prepareStatement (sql); + + try { + for (int ii = 0; ii < params.length; ii++) + ps.setObject (ii + 1, params [ii]); + + ps.execute (); + ps.close (); + ps = null; + } finally { + close (ps); + } + } public static void exec (Connection conn, List sqlList) throws SQLException diff --git a/src/deltix/util/jdbc/SystemSQLException.java b/src/deltix/util/jdbc/SystemSQLException.java new file mode 100644 index 00000000..37b52abc --- /dev/null +++ b/src/deltix/util/jdbc/SystemSQLException.java @@ -0,0 +1,21 @@ +package deltix.util.jdbc; + +import java.sql.SQLException; + +/** + * Unchecked exception, used to wrap the checked java.sql.SQLException + * occurring because of system problems. + */ +public class SystemSQLException extends RuntimeException { + public SystemSQLException (String msg, SQLException sx) { + super (msg, sx); + } + + public SystemSQLException (SQLException sx) { + super ("System IO error: " + sx, sx); + } + + public SystemSQLException (String msg) { + super (msg); + } +} diff --git a/src/deltix/util/time/AbsoluteDate.java b/src/deltix/util/time/AbsoluteDate.java index c99d600d..95711fcd 100644 --- a/src/deltix/util/time/AbsoluteDate.java +++ b/src/deltix/util/time/AbsoluteDate.java @@ -14,6 +14,9 @@ public class AbsoluteDate implements Comparable { private byte mMonth; // 1-based! private byte mDay; // 1-based! + public AbsoluteDate () { + } + public AbsoluteDate (int year, int month, int day) { set (year, month, day); } From b44733b84cbd4390c9fa92ddee5a0534c7501ab5 Mon Sep 17 00:00:00 2001 From: gene Date: Mon, 13 Nov 2006 18:19:20 +0000 Subject: [PATCH 0028/2572] --- src/deltix/util/time/AbsoluteDate.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/deltix/util/time/AbsoluteDate.java b/src/deltix/util/time/AbsoluteDate.java index 95711fcd..3707d3f6 100644 --- a/src/deltix/util/time/AbsoluteDate.java +++ b/src/deltix/util/time/AbsoluteDate.java @@ -15,6 +15,11 @@ public class AbsoluteDate implements Comparable { private byte mDay; // 1-based! public AbsoluteDate () { + mMonth = 0; + } + + public AbsoluteDate (AbsoluteDate copy) { + set (copy); } public AbsoluteDate (int year, int month, int day) { @@ -33,6 +38,20 @@ public AbsoluteDate (String s) { set (s); } + public boolean isInitialized () { + return (mMonth != 0); + } + + public void setUninitialized () { + mMonth = 0; + } + + public void set (AbsoluteDate copy) { + mYear = copy.mYear; + mMonth = copy.mMonth; + mDay = copy.mDay; + } + public void set (int year, int month, int day) { if (year < 0 || year > Short.MAX_VALUE) throw new IllegalArgumentException ("Illegal year value: " + year); From 9505606b72d9d96d3eac8bdf26cb7466e654e642 Mon Sep 17 00:00:00 2001 From: gene Date: Tue, 14 Nov 2006 18:46:30 +0000 Subject: [PATCH 0029/2572] --- src/deltix/util/jdbc/JDBCUtils.java | 37 ++++++++++++++++++- .../jdbc/MultipleRowsReturnedException.java | 12 ++++++ .../util/jdbc/NoRowsReturnedException.java | 12 ++++++ src/deltix/util/time/AbsoluteDate.java | 3 ++ 4 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 src/deltix/util/jdbc/MultipleRowsReturnedException.java create mode 100644 src/deltix/util/jdbc/NoRowsReturnedException.java diff --git a/src/deltix/util/jdbc/JDBCUtils.java b/src/deltix/util/jdbc/JDBCUtils.java index 0aaac6cc..5bd5b355 100644 --- a/src/deltix/util/jdbc/JDBCUtils.java +++ b/src/deltix/util/jdbc/JDBCUtils.java @@ -40,12 +40,12 @@ public static int queryInt (PreparedStatement ps) throws SQLExcept try { if (!rs.next ()) - throw new SQLException ("No rows returned"); + throw new NoRowsReturnedException (); int ret = rs.getInt (1); if (rs.next ()) - throw new SQLException ("Multiple rows returned"); + throw new MultipleRowsReturnedException (); return (ret); } finally { @@ -68,6 +68,39 @@ public static int queryInt (Connection conn, String query, Object } } + public static String queryString (PreparedStatement ps) throws SQLException { + ResultSet rs = ps.executeQuery (); + + try { + if (!rs.next ()) + throw new NoRowsReturnedException (); + + String ret = rs.getString (1); + + if (rs.next ()) + throw new MultipleRowsReturnedException (); + + return (ret); + } finally { + close (rs); + } + } + + public static String queryString (Connection conn, String query, Object ... params) + throws SQLException + { + PreparedStatement ps = conn.prepareStatement (query); + + try { + for (int ii = 0; ii < params.length; ii++) + ps.setObject (ii + 1, params [ii]); + + return (queryString (ps)); + } finally { + close (ps); + } + } + public static List queryStrings (PreparedStatement ps) throws SQLException { diff --git a/src/deltix/util/jdbc/MultipleRowsReturnedException.java b/src/deltix/util/jdbc/MultipleRowsReturnedException.java new file mode 100644 index 00000000..be1961ce --- /dev/null +++ b/src/deltix/util/jdbc/MultipleRowsReturnedException.java @@ -0,0 +1,12 @@ +package deltix.util.jdbc; + +import java.sql.SQLException; + +/** + * + */ +public class MultipleRowsReturnedException extends SQLException { + public MultipleRowsReturnedException () { + super ("Query returned more than one row"); + } +} diff --git a/src/deltix/util/jdbc/NoRowsReturnedException.java b/src/deltix/util/jdbc/NoRowsReturnedException.java new file mode 100644 index 00000000..58b7047f --- /dev/null +++ b/src/deltix/util/jdbc/NoRowsReturnedException.java @@ -0,0 +1,12 @@ +package deltix.util.jdbc; + +import java.sql.SQLException; + +/** + * + */ +public class NoRowsReturnedException extends SQLException { + public NoRowsReturnedException () { + super ("Query returned 0 rows"); + } +} diff --git a/src/deltix/util/time/AbsoluteDate.java b/src/deltix/util/time/AbsoluteDate.java index 3707d3f6..2486f907 100644 --- a/src/deltix/util/time/AbsoluteDate.java +++ b/src/deltix/util/time/AbsoluteDate.java @@ -7,6 +7,9 @@ * A bean holding an absolute (time- and time zone-unrelated) date. */ public class AbsoluteDate implements Comparable { + public static final AbsoluteDate MIN_VALUE = new AbsoluteDate (0, 1, 1); + public static final AbsoluteDate MAX_VALUE = new AbsoluteDate (Short.MAX_VALUE, 12, 31); + static final long serialVersionUID = 1L; private static final short EXTERNAL_VERSION = 1; From 4c6649f17ee64ad894aadb47ace1b8c7e2de7f2b Mon Sep 17 00:00:00 2001 From: gene Date: Wed, 15 Nov 2006 21:55:29 +0000 Subject: [PATCH 0030/2572] --- src/deltix/util/Util.java | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/deltix/util/Util.java b/src/deltix/util/Util.java index 59f51e83..b52d9568 100644 --- a/src/deltix/util/Util.java +++ b/src/deltix/util/Util.java @@ -17,6 +17,26 @@ public class Util { public static final String LOGGER_NAME = "deltix.util"; public static final Logger LOGGER = Logger.getLogger (LOGGER_NAME); + public static > T max (T a, T b) { + if (a == null) + return (b); + + if (b == null) + return (a); + + return (a.compareTo (b) > 0 ? a : b); + } + + public static > T min (T a, T b) { + if (a == null) + return (b); + + if (b == null) + return (a); + + return (a.compareTo (b) < 0 ? a : b); + } + public static void writeNullableString (String s, ObjectOutput os) throws IOException { From 68ebd6d32899594d43e1539c51dbbda0d916938f Mon Sep 17 00:00:00 2001 From: gene Date: Thu, 16 Nov 2006 23:29:06 +0000 Subject: [PATCH 0031/2572] --- src/deltix/util/time/AbsoluteDate.java | 42 ++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/src/deltix/util/time/AbsoluteDate.java b/src/deltix/util/time/AbsoluteDate.java index 2486f907..8386268d 100644 --- a/src/deltix/util/time/AbsoluteDate.java +++ b/src/deltix/util/time/AbsoluteDate.java @@ -41,6 +41,48 @@ public AbsoluteDate (String s) { set (s); } + /** + * Returns whether the year is a leap year according to the Gregorian calendar + */ + public static boolean isLeapYear (int year) { + if (year % 400 == 0) + return (true); + + if (year % 100 == 0) + return (false); + + return (year % 4 == 0); + } + + private static final int[] DAYS_IN_MONTH = { 0, 31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; + + public int getNumberOfDaysInMonth () { + if (mMonth == 2) + return (isLeapYear (mYear) ? 29 : 28); + else + return (DAYS_IN_MONTH [mMonth]); + } + + /** + * Increments the date by 1 day, according to the Gregorian calendar. + * @return this + */ + public AbsoluteDate inc () { + mDay++; + + if (mDay > getNumberOfDaysInMonth ()) { + mDay = 1; + mMonth++; + } + + if (mMonth == 13) { + mMonth = 1; + mYear++; + } + + return (this); + } + public boolean isInitialized () { return (mMonth != 0); } From 9a050da77acea2f1af16165e70918a1cb69e84be Mon Sep 17 00:00:00 2001 From: gene Date: Fri, 17 Nov 2006 21:13:35 +0000 Subject: [PATCH 0032/2572] State Street work. --- src/deltix/util/ConsoleExceptionHandler.java | 24 ++++++++++++++++++++ src/deltix/util/ExceptionHandler.java | 8 +++++++ src/deltix/util/swing/VerticalForm.java | 9 +++++++- 3 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 src/deltix/util/ConsoleExceptionHandler.java create mode 100644 src/deltix/util/ExceptionHandler.java diff --git a/src/deltix/util/ConsoleExceptionHandler.java b/src/deltix/util/ConsoleExceptionHandler.java new file mode 100644 index 00000000..21670307 --- /dev/null +++ b/src/deltix/util/ConsoleExceptionHandler.java @@ -0,0 +1,24 @@ +package deltix.util; + +import java.io.*; + +/** + * Prints stack trace to specified stream + */ +public class ConsoleExceptionHandler implements ExceptionHandler { + private PrintStream mOut; + + public ConsoleExceptionHandler (PrintStream out) { + mOut = out; + } + + public void handle (Throwable x) { + x.printStackTrace (System.err); + } + + /** + * Prints to System.err + */ + public static final ConsoleExceptionHandler STDERR_HANDLER = + new ConsoleExceptionHandler (System.err); +} diff --git a/src/deltix/util/ExceptionHandler.java b/src/deltix/util/ExceptionHandler.java new file mode 100644 index 00000000..9ae70f1d --- /dev/null +++ b/src/deltix/util/ExceptionHandler.java @@ -0,0 +1,8 @@ +package deltix.util; + +/** + * Abstract exception handler. + */ +public interface ExceptionHandler { + public void handle (Throwable x); +} diff --git a/src/deltix/util/swing/VerticalForm.java b/src/deltix/util/swing/VerticalForm.java index 088f35d8..c7ea3cf4 100644 --- a/src/deltix/util/swing/VerticalForm.java +++ b/src/deltix/util/swing/VerticalForm.java @@ -91,6 +91,9 @@ public void addRow (JComponent comp, boolean disableWithForm) { add (comp, mC); mC.gridy++; + + if (disableWithForm) + enableComponentRec (isEnabled (), comp); } public void addLine () { @@ -128,8 +131,11 @@ public void addField (JLabel jl, JComponent comp, boolean disableWithFor add (comp, mC); mC.gridy++; + + if (disableWithForm) + enableComponentRec (isEnabled (), comp); } - + /* public void setEnabled (boolean flag) { super.setEnabled (flag); @@ -142,4 +148,5 @@ public void setEnabled (boolean flag) { c.setEnabled (flag); } } + */ } From 92368b3dc2fe292a4d07037d0803ad61033fc7c2 Mon Sep 17 00:00:00 2001 From: gene Date: Tue, 21 Nov 2006 20:53:57 +0000 Subject: [PATCH 0033/2572] --- src/deltix/util/io/AbstractDataStore.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/deltix/util/io/AbstractDataStore.java b/src/deltix/util/io/AbstractDataStore.java index 01b3bf33..fe349c42 100644 --- a/src/deltix/util/io/AbstractDataStore.java +++ b/src/deltix/util/io/AbstractDataStore.java @@ -22,6 +22,11 @@ public interface AbstractDataStore { */ public boolean isOpen (); + /** + * Determines whether the store is open as read-only. + */ + public boolean isReadOnly (); + /** * Open the data store. */ From 377f8ff3f18aaf8f89fb73f98dfb0749d90afd22 Mon Sep 17 00:00:00 2001 From: jacob Date: Tue, 21 Nov 2006 23:10:54 +0000 Subject: [PATCH 0034/2572] * Generified Primitive Collections with support for Java Generics * Cleaned up Preprocessing Code to be more readable * Cleaned up ant buildfile to be more readable * Added build.cmd to DELTIX_HOME\bin for command-line build support --- src/deltix/util/collections/ArrayList.vtl | 315 ++++++++++-------- src/deltix/util/collections/Arrays.java | 51 +++ .../util/collections/PrimitiveComparator.vtl | 14 +- .../util/collections/PrimitiveEnumeration.vtl | 4 +- 4 files changed, 240 insertions(+), 144 deletions(-) create mode 100644 src/deltix/util/collections/Arrays.java diff --git a/src/deltix/util/collections/ArrayList.vtl b/src/deltix/util/collections/ArrayList.vtl index d3dddf17..00b38e84 100644 --- a/src/deltix/util/collections/ArrayList.vtl +++ b/src/deltix/util/collections/ArrayList.vtl @@ -1,16 +1,30 @@ package deltix.util.collections.generated; -import java.util.*; +import java.util.AbstractList; +import java.util.List; +import java.util.Collection; +import java.util.Iterator; +#if($name == "Object") +import java.util.Enumeration; +#end + +import deltix.util.collections.Arrays; import deltix.util.memory.*; /** - * Resizable array of primitive ${prim}s. Much more efficient than - * keeping a java.util.ArrayList of ${wrap}. + * Resizable array of primitive ${type}s. Much more efficient than + * keeping a java.util.ArrayList of ${type_Object}. */ -public final class ${wrap}ArrayList - extends AbstractList - implements List, Cloneable, java.io.Serializable, MemorySizeEstimator + +#if($name == "Object") +public final class ${name}ArrayList<${type}> +#else +public final class ${name}ArrayList +#end + extends AbstractList<${type_Object}> + implements List<${type_Object}>, Cloneable, java.io.Serializable, MemorySizeEstimator + { static final long serialVersionUID = 1L; @@ -20,7 +34,7 @@ public final class ${wrap}ArrayList * * @serial */ - private ${prim} elementData[]; + private ${type} elementData[]; /** * The size of the ArrayList (the number of elements it contains). @@ -40,18 +54,22 @@ public final class ${wrap}ArrayList * @exception IllegalArgumentException if the specified initial capacity * is negative */ - public ${wrap}ArrayList(int initialCapacity) { + public ${name}ArrayList(int initialCapacity) { super(); if (initialCapacity < 0) throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); - this.elementData = new ${prim} [initialCapacity]; +#if( $name == "Object" ) + this.elementData = Arrays.initializeArray(initialCapacity); +#else + this.elementData = new ${type} [initialCapacity]; +#end } /** * Constructs an empty list. */ - public ${wrap}ArrayList() { + public ${name}ArrayList() { this(10); } @@ -63,27 +81,29 @@ public final class ${wrap}ArrayList * * @param c the collection whose elements are to be placed into this list. */ - public ${wrap}ArrayList(Collection c) { + public ${name}ArrayList(Collection c) { size = c.size (); - elementData = new ${prim} [(size*110) / 100]; +#if( $name == "Object" ) + this.elementData = Arrays.initializeArray(size); +#else + elementData = new ${type} [(size*110) / 100]; +#end // Allow 10% room for growth - Iterator iter = c.iterator (); + Iterator iter = c.iterator (); int idx = 0; while (iter.hasNext ()) - elementData [idx] = -#if( $wrap == "Object" ) - iter.next (); -#else - ((${wrap}) iter.next ()).${prim}Value (); -#end + elementData [idx++] = iter.next (); } - public ${wrap}ArrayList (${prim} [] arr) { + public ${name}ArrayList (${type} [] arr) { size = arr.length; - elementData = new ${prim} [(size*110) / 100]; - for (int idx = 0; idx < size; idx++) - elementData[idx] = arr[idx]; +#if( $name == "Object" ) + elementData = Arrays.initializeArray((size*110) / 100); +#else + elementData = new ${type} [(size*110) / 100]; +#end + Arrays.safeArrayCopy(arr, 0, elementData, 0, size); } /** @@ -95,9 +115,13 @@ public final class ${wrap}ArrayList modCount++; int oldCapacity = elementData.length; if (size < oldCapacity) { - ${prim} oldData [] = elementData; - elementData = new ${prim} [size]; - System.arraycopy (oldData, 0, elementData, 0, size); + ${type} oldData [] = elementData; +#if( $name == "Object" ) + elementData = Arrays.initializeArray(size); +#else + elementData = new ${type} [size]; +#end + Arrays.safeArrayCopy (oldData, 0, elementData, 0, size); } } @@ -112,12 +136,16 @@ public final class ${wrap}ArrayList modCount++; int oldCapacity = elementData.length; if (minCapacity > oldCapacity) { - ${prim} oldData [] = elementData; + ${type} oldData [] = elementData; int newCapacity = (oldCapacity * 3)/2 + 1; if (newCapacity < minCapacity) newCapacity = minCapacity; - elementData = new ${prim} [newCapacity]; - System.arraycopy (oldData, 0, elementData, 0, size); +#if( $name == "Object" ) + elementData = Arrays.initializeArray(newCapacity); +#else + elementData = new ${type} [newCapacity]; +#end + Arrays.safeArrayCopy (oldData, 0, elementData, 0, size); } } @@ -140,7 +168,16 @@ public final class ${wrap}ArrayList return size == 0; } -#if( $wrap == "Object" ) + /** + * Returns true if this list contains the specified element. + * + * @param elem element whose presence in this List is to be tested. + */ + public boolean contains (Object elem) { + return indexOf (elem) >= 0; + } + +#if( $name == "Object" ) /** * Returns an array containing all of the elements in this list in the * correct order. The runtime type of the returned array is that of the @@ -158,17 +195,13 @@ public final class ${wrap}ArrayList * same runtime type is allocated for this purpose. * @return an array containing the elements of the list. * @throws ArrayStoreException if the runtime type of a is not a supertype - * of ${wrap}. + * of ${type_Object}. */ - public Object [] toArray(Object a[]) { + public T [] toArray(T a[]) { if (a.length < size) - a = (Object[]) - java.lang.reflect.Array.newInstance ( - a.getClass ().getComponentType (), - size - ); + a = Arrays.instantiate(size); - System.arraycopy (elementData, 0, a, 0, size); + Arrays.safeArrayCopy (elementData, 0, a, 0, size); if (a.length > size) a [size] = null; @@ -184,8 +217,8 @@ public final class ${wrap}ArrayList * @throws IndexOutOfBoundsException if index is out of range (index * < 0 || index >= size()). */ - public Object get (int index) { - return (get${wrap} (index)); + public ${type} get (int index) { + return (get${name} (index)); } #else @@ -197,8 +230,8 @@ public final class ${wrap}ArrayList * @throws IndexOutOfBoundsException if index is out of range (index * < 0 || index >= size()). */ - public Object get (int index) { - return new ${wrap} (get${wrap} (index)); + public ${type_Object} get (int index) { + return get${name} (index); } /** @@ -218,14 +251,17 @@ public final class ${wrap}ArrayList * same runtime type is allocated for this purpose. * @return an array containing the elements of the list. * @throws ArrayStoreException if the runtime type of a is not a supertype - * of ${wrap}. + * of ${type_Object}. */ - public Object [] toArray(Object a[]) { + @SuppressWarnings("unchecked") + public T [] toArray(T a[]) { if (a.length < size) - a = new ${wrap} [size]; + a = Arrays.initializeArray(size); - for (int ii = 0; ii < size; ii++) - a [ii] = new ${wrap} (elementData [ii]); + for (int i = 0; i < size; i++) + { + a[i] = (T) new ${type_Object}(elementData[i]); + } if (a.length > size) a [size] = null; @@ -238,7 +274,7 @@ public final class ${wrap}ArrayList * * @param elem element whose presence in this List is to be tested. */ - public boolean contains (Object elem) { + public boolean contains (${type} elem) { return indexOf (elem) >= 0; } @@ -251,19 +287,19 @@ public final class ${wrap}ArrayList * list; returns -1 if the object is not found. */ public int indexOf(Object elem) { - return (indexOf (((${wrap}) elem).${prim}Value ())); + return (indexOf (((${type_Object}) elem).${type}Value ())); } /** - * Returns the index of the last occurrence of the specified ${prim} in + * Returns the index of the last occurrence of the specified ${type} in * this list. * * @param elem the desired element. - * @return the index of the last occurrence of the specified ${prim} in + * @return the index of the last occurrence of the specified ${type} in * this list; returns -1 if the object is not found. */ public int lastIndexOf (Object elem) { - return (lastIndexOf (((${wrap}) elem).${prim}Value ())); + return (lastIndexOf (((${type_Object}) elem).${type}Value ())); } /** @@ -276,8 +312,8 @@ public final class ${wrap}ArrayList * @throws IndexOutOfBoundsException if index out of range * (index < 0 || index >= size()). */ - public Object set (int index, Object element) { - return (new ${wrap} (set (index, ((${wrap}) element).${prim}Value ()))); + public ${type_Object} set (int index, ${type_Object} element) { + return set(index, element.${type}Value()); } /** @@ -286,8 +322,8 @@ public final class ${wrap}ArrayList * @param o element to be appended to this list. * @return true (as per the general contract of Collection.add). */ - public boolean add (Object o) { - return (add (((${wrap}) o).${prim}Value ())); + public boolean add (${type_Object} o) { + return (add (o.${type}Value ())); } /** @@ -300,19 +336,12 @@ public final class ${wrap}ArrayList * @throws IndexOutOfBoundsException if index is out of range * (index < 0 || index > size()). */ - public void add (int index, Object element) { - add (index, ((${wrap}) element).${prim}Value ()); + public void add (int index, ${type_Object} element) { + add (index, element.${type}Value ()); } #end - /** - * Returns true if this list contains the specified element. - * - * @param elem element whose presence in this List is to be tested. - */ - public boolean contains (${prim} elem) { - return indexOf (elem) >= 0; - } + /** * Searches for the first occurence of the given argument, testing @@ -322,7 +351,11 @@ public final class ${wrap}ArrayList * @return the index of the first occurrence of the argument in this * list; returns -1 if the object is not found. */ - public int indexOf (${prim} elem) { +#if ($name == "Object") + public int indexOf (Object elem) { +#else + public int indexOf (${type} elem) { +#end for (int i = 0; i < size; i++) if (elem == elementData[i]) return i; @@ -330,14 +363,18 @@ public final class ${wrap}ArrayList } /** - * Returns the index of the last occurrence of the specified ${prim} in + * Returns the index of the last occurrence of the specified ${type} in * this list. * * @param elem the desired element. - * @return the index of the last occurrence of the specified ${prim} in + * @return the index of the last occurrence of the specified ${type} in * this list; returns -1 if the object is not found. */ - public int lastIndexOf (${prim} elem) { +#if ($name == "Object") + public int lastIndexOf (Object elem) { +#else + public int lastIndexOf (${type} elem) { +#end for (int i = size-1; i >= 0; i--) if (elem == elementData [i]) return i; @@ -345,15 +382,19 @@ public final class ${wrap}ArrayList } /** - * Returns a copy of this ${wrap}ArrayList instance. + * Returns a copy of this ${name}ArrayList instance. * - * @return a clone of this ${wrap}ArrayList instance. + * @return a clone of this ${name}ArrayList instance. */ public Object clone () { try { - ${wrap}ArrayList v = (${wrap}ArrayList) super.clone(); - v.elementData = new ${prim} [size]; - System.arraycopy (elementData, 0, v.elementData, 0, size); + ${name}ArrayList v = (${name}ArrayList) super.clone(); +#if( ${name} == "Object" ) + v.elementData = Arrays.initializeArray(size); +#else + v.elementData = new ${type} [size]; +#end + Arrays.safeArrayCopy (elementData, 0, v.elementData, 0, size); v.modCount = 0; return v; } catch (CloneNotSupportedException e) { @@ -375,15 +416,19 @@ public final class ${wrap}ArrayList } /** - * Returns a ${prim} array containing all of the elements in this list + * Returns a ${type} array containing all of the elements in this list * in the correct order. * * @return an array containing all of the elements in this list * in the correct order. */ - public ${prim} [] to${wrap}Array () { - ${prim} [] ret = new ${prim} [size]; - System.arraycopy (elementData, 0, ret, 0, size); + public ${type} [] to${name_abbr}Array () { +#if($name == "Object") + ${type} [] ret = Arrays.initializeArray(size); +#else + ${type} [] ret = new ${type} [size]; +#end + Arrays.safeArrayCopy (elementData, 0, ret, 0, size); return (ret); } @@ -398,7 +443,7 @@ public final class ${wrap}ArrayList * @throws IndexOutOfBoundsException if index is out of range (index * < 0 || index >= size()). */ - public ${prim} get${wrap} (int index) { + public ${type} get${name} (int index) { RangeCheck(index); return elementData[index]; } @@ -409,7 +454,7 @@ public final class ${wrap}ArrayList * @param index index of element to return. * @return the element at the specified position in this list. */ - public ${prim} get${wrap}NoRangeCheck (int index) { + public ${type} get${name}NoRangeCheck (int index) { return elementData [index]; } @@ -423,9 +468,9 @@ public final class ${wrap}ArrayList * @throws IndexOutOfBoundsException if index out of range * (index < 0 || index >= size()). */ - public ${prim} set (int index, ${prim} element) { + public ${type} set (int index, ${type} element) { RangeCheck(index); - ${prim} oldValue = elementData[index]; + ${type} oldValue = elementData[index]; elementData[index] = element; return oldValue; } @@ -436,7 +481,7 @@ public final class ${wrap}ArrayList * @param d element to be appended to this list. * @return true (as per the general contract of Collection.add). */ - public boolean add (${prim} d) { + public boolean add (${type} d) { ensureCapacity(size + 1); // Increments modCount!! elementData[size++] = d; return true; @@ -452,13 +497,13 @@ public final class ${wrap}ArrayList * @throws IndexOutOfBoundsException if index is out of range * (index < 0 || index > size()). */ - public void add (int index, ${prim} element) { + public void add (int index, ${type} element) { if (index > size || index < 0) throw new IndexOutOfBoundsException( "Index: "+index+", Size: "+size); ensureCapacity (size+1); // Increments modCount!! - System.arraycopy(elementData, index, elementData, index + 1, + Arrays.safeArrayCopy(elementData, index, elementData, index + 1, size - index); elementData[index] = element; size++; @@ -474,12 +519,8 @@ public final class ${wrap}ArrayList * @throws IndexOutOfBoundsException if index out of range (index * < 0 || index >= size()). */ - public Object remove (int index) { -#if( $wrap == "Object" ) - return (removeObject (index)); -#else - return (new ${wrap} (remove${wrap} (index))); -#end + public ${type_Object} remove (int index) { + return (remove${name} (index)); } /** @@ -492,15 +533,15 @@ public final class ${wrap}ArrayList * @throws IndexOutOfBoundsException if index out of range (index * < 0 || index >= size()). */ - public ${prim} remove${wrap} (int index) { + public ${type} remove${name} (int index) { RangeCheck(index); modCount++; - ${prim} oldValue = elementData[index]; + ${type} oldValue = elementData[index]; int numMoved = size - index - 1; if (numMoved > 0) - System.arraycopy(elementData, index+1, elementData, index, + Arrays.safeArrayCopy(elementData, index+1, elementData, index, numMoved); size--; @@ -529,18 +570,18 @@ public final class ${wrap}ArrayList * @throws IndexOutOfBoundsException if index out of range (index * < 0 || index > size()). */ - public boolean addAll (Collection c) { + public boolean addAll (Collection c) { modCount++; int numNew = c.size(); ensureCapacity(size + numNew); - Iterator e = c.iterator(); + Iterator iter = c.iterator (); for (int i=0; i(index * < 0 || index > size()). */ - public boolean addAll(int index, Collection c) { + public boolean addAll (Collection c, int index) { if (index > size || index < 0) throw new IndexOutOfBoundsException( "Index: "+index+", Size: "+size); @@ -570,17 +611,12 @@ public final class ${wrap}ArrayList int numMoved = size - index; if (numMoved > 0) - System.arraycopy(elementData, index, elementData, index + numNew, + Arrays.safeArrayCopy(elementData, index, elementData, index + numNew, numMoved); - Iterator e = c.iterator(); + Iterator iter = c.iterator (); for (int i=0; iArrayList instance from a stream (that is, * deserialize it). */ + @SuppressWarnings("unchecked") private synchronized void readObject (java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { // Read in array length and allocate array size = s.readInt(); - elementData = new ${prim} [size]; +#if( $name == "Object" ) + elementData = Arrays.initializeArray(size); +#else + elementData = new ${type} [size]; +#end // Read in all elements in the proper order. for (int i=0; i { + private int mIndex = 0; public ElemEnumeration () { } - public boolean hasMoreElements () { + public boolean hasMoreElements () { return (mIndex < size); } - public Object nextElement () { + public ${type} nextElement () { return (elementData [mIndex++]); } } - public Enumeration elements () { + public Enumeration elements () { return (new ElemEnumeration ()); } #else - private class ElemEnumeration implements ${wrap}Enumeration { - private int mIndex = 0; + private class ElemEnumeration implements ${name}Enumeration { + private int mIndex = 0; public ElemEnumeration () { } - public boolean hasMoreElements () { + public boolean hasMoreElements () { return (mIndex < size); } - public Object nextElement () { - return (new ${wrap} (next${abbr}Element ())); + public ${type_Object} nextElement () { + return (new ${type_Object} (next${name_abbr}Element ())); } - public ${prim} next${abbr}Element () { + public ${type} next${name_abbr}Element () { return (elementData [mIndex++]); } } - public ${wrap}Enumeration ${prim}Elements () { + public ${name}Enumeration ${type}Elements () { return (new ElemEnumeration ()); } #end diff --git a/src/deltix/util/collections/Arrays.java b/src/deltix/util/collections/Arrays.java new file mode 100644 index 00000000..fb102868 --- /dev/null +++ b/src/deltix/util/collections/Arrays.java @@ -0,0 +1,51 @@ +package deltix.util.collections; + +/** + * @author Jacob Alber + */ +public class Arrays { + public static Generic[] asArray(Generic... array) { + return array; + } + + @SuppressWarnings("unchecked") + public static Generic[] initializeArray(int size) { + return (Generic[]) new Object[size]; + } + + public static void safeArrayCopy(Generic[] src, int srcPos, Generic[] dest, int destPos, int length) { + System.arraycopy(src, srcPos, dest, destPos, length); + } + + public static void safeArrayCopy(int[] src, int srcPos, int[] dest, int destPos, int length) { + System.arraycopy(src, srcPos, dest, destPos, length); + } + + public static void safeArrayCopy(byte[] src, int srcPos, byte[] dest, int destPos, int length) { + System.arraycopy(src, srcPos, dest, destPos, length); + } + + public static void safeArrayCopy(short[] src, int srcPos, short[] dest, int destPos, int length) { + System.arraycopy(src, srcPos, dest, destPos, length); + } + + public static void safeArrayCopy(long[] src, int srcPos, long[] dest, int destPos, int length) { + System.arraycopy(src, srcPos, dest, destPos, length); + } + + public static void safeArrayCopy(double[] src, int srcPos, double[] dest, int destPos, int length) { + System.arraycopy(src, srcPos, dest, destPos, length); + } + + public static void safeArrayCopy(float[] src, int srcPos, float[] dest, int destPos, int length) { + System.arraycopy(src, srcPos, dest, destPos, length); + } + + public static void safeArrayCopy(char[] src, int srcPos, char[] dest, int destPos, int length) { + System.arraycopy(src, srcPos, dest, destPos, length); + } + + public static void safeArrayCopy(boolean[] src, int srcPos, boolean[] dest, int destPos, int length) { + System.arraycopy(src, srcPos, dest, destPos, length); + } +} diff --git a/src/deltix/util/collections/PrimitiveComparator.vtl b/src/deltix/util/collections/PrimitiveComparator.vtl index 14cef7bd..823e9cd2 100644 --- a/src/deltix/util/collections/PrimitiveComparator.vtl +++ b/src/deltix/util/collections/PrimitiveComparator.vtl @@ -4,20 +4,20 @@ import deltix.util.memory.*; import deltix.util.collections.*; /** - * Compares keys as ${prim}s. + * Compares keys as ${type}s. */ -public final class ${wrap}Comparator implements ByteArrayComparator { +public final class ${name}Comparator implements ByteArrayComparator { private int mOrder; - private ${wrap}Comparator (int order) { + private ${name}Comparator (int order) { mOrder = order; } public int compare (byte [] key1, int offset1, byte [] key2, int offset2, int keySize) { assert (keySize == MemorySizeEstimator.${size}); - ${prim} f1 = DataExchangeUtils.read${abbr} (key1, offset1); - ${prim} f2 = DataExchangeUtils.read${abbr} (key2, offset2); + ${type} f1 = DataExchangeUtils.read${name_abbr} (key1, offset1); + ${type} f2 = DataExchangeUtils.read${name_abbr} (key2, offset2); if (f1 == f2) return (0); @@ -27,7 +27,7 @@ public final class ${wrap}Comparator implements ByteArrayComparator { return (-mOrder); } - public static final ${wrap}Comparator ASCENDING = new ${wrap}Comparator (1); + public static final ${name}Comparator ASCENDING = new ${name}Comparator (1); - public static final ${wrap}Comparator DESCENDING = new ${wrap}Comparator (-1); + public static final ${name}Comparator DESCENDING = new ${name}Comparator (-1); } diff --git a/src/deltix/util/collections/PrimitiveEnumeration.vtl b/src/deltix/util/collections/PrimitiveEnumeration.vtl index 4ae7cacf..0d0221cc 100644 --- a/src/deltix/util/collections/PrimitiveEnumeration.vtl +++ b/src/deltix/util/collections/PrimitiveEnumeration.vtl @@ -2,6 +2,6 @@ package deltix.util.collections.generated; import java.util.Enumeration; -public interface ${wrap}Enumeration extends Enumeration { - public ${prim} next${abbr}Element (); +public interface ${name}Enumeration extends Enumeration<$type_Object> { + public ${type} next${name_abbr}Element (); } From d0377f683b82ea5d3e08fbbc08feabf09cd7acb9 Mon Sep 17 00:00:00 2001 From: jacob Date: Tue, 21 Nov 2006 23:33:12 +0000 Subject: [PATCH 0035/2572] * Generified Primitive Collections with support for Java Generics * Cleaned up Preprocessing Code to be more readable * Cleaned up ant buildfile to be more readable * Added build.cmd to DELTIX_HOME\bin for command-line build support --- src/deltix/util/collections/ArrayList.vtl | 24 +++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/deltix/util/collections/ArrayList.vtl b/src/deltix/util/collections/ArrayList.vtl index 00b38e84..c233ed8a 100644 --- a/src/deltix/util/collections/ArrayList.vtl +++ b/src/deltix/util/collections/ArrayList.vtl @@ -60,7 +60,7 @@ public final class ${name}ArrayList throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); #if( $name == "Object" ) - this.elementData = Arrays.initializeArray(initialCapacity); + this.elementData = Arrays.<${type}>initializeArray(initialCapacity); #else this.elementData = new ${type} [initialCapacity]; #end @@ -84,7 +84,7 @@ public final class ${name}ArrayList public ${name}ArrayList(Collection c) { size = c.size (); #if( $name == "Object" ) - this.elementData = Arrays.initializeArray(size); + this.elementData = Arrays.<${type}>initializeArray(size); #else elementData = new ${type} [(size*110) / 100]; #end @@ -99,7 +99,7 @@ public final class ${name}ArrayList public ${name}ArrayList (${type} [] arr) { size = arr.length; #if( $name == "Object" ) - elementData = Arrays.initializeArray((size*110) / 100); + elementData = Arrays.<${type}>initializeArray((size*110) / 100); #else elementData = new ${type} [(size*110) / 100]; #end @@ -117,7 +117,7 @@ public final class ${name}ArrayList if (size < oldCapacity) { ${type} oldData [] = elementData; #if( $name == "Object" ) - elementData = Arrays.initializeArray(size); + elementData = Arrays.<${type}>initializeArray(size); #else elementData = new ${type} [size]; #end @@ -141,7 +141,7 @@ public final class ${name}ArrayList if (newCapacity < minCapacity) newCapacity = minCapacity; #if( $name == "Object" ) - elementData = Arrays.initializeArray(newCapacity); + elementData = Arrays.<${type}>initializeArray(newCapacity); #else elementData = new ${type} [newCapacity]; #end @@ -199,7 +199,7 @@ public final class ${name}ArrayList */ public T [] toArray(T a[]) { if (a.length < size) - a = Arrays.instantiate(size); + a = Arrays.initializeArray(size); Arrays.safeArrayCopy (elementData, 0, a, 0, size); @@ -256,7 +256,7 @@ public final class ${name}ArrayList @SuppressWarnings("unchecked") public T [] toArray(T a[]) { if (a.length < size) - a = Arrays.initializeArray(size); + a = Arrays.initializeArray(size); for (int i = 0; i < size; i++) { @@ -390,7 +390,7 @@ public final class ${name}ArrayList try { ${name}ArrayList v = (${name}ArrayList) super.clone(); #if( ${name} == "Object" ) - v.elementData = Arrays.initializeArray(size); + v.elementData = Arrays.<${type}>initializeArray(size); #else v.elementData = new ${type} [size]; #end @@ -424,7 +424,7 @@ public final class ${name}ArrayList */ public ${type} [] to${name_abbr}Array () { #if($name == "Object") - ${type} [] ret = Arrays.initializeArray(size); + ${type} [] ret = Arrays.<${type}>initializeArray(size); #else ${type} [] ret = new ${type} [size]; #end @@ -681,7 +681,7 @@ public final class ${name}ArrayList // Read in array length and allocate array size = s.readInt(); #if( $name == "Object" ) - elementData = Arrays.initializeArray(size); + elementData = Arrays.<${type}>initializeArray(size); #else elementData = new ${type} [size]; #end @@ -703,8 +703,8 @@ public final class ${name}ArrayList return (false); return (java.util.Arrays.equals ( - to${name}Array (), - ((${name}ArrayList) otherObj).to${name}Array () + to${name_abbr}Array (), + ((${name}ArrayList) otherObj).to${name_abbr}Array () ) ); From 6b9c5c23ee10b64ca78d38caa3984fe1d545989a Mon Sep 17 00:00:00 2001 From: jacob Date: Tue, 21 Nov 2006 23:48:15 +0000 Subject: [PATCH 0036/2572] * Generified Primitive Collections with support for Java Generics * Cleaned up Preprocessing Code to be more readable * Cleaned up ant buildfile to be more readable * Added build.cmd to DELTIX_HOME\bin for command-line build support --- src/deltix/util/collections/ArrayList.vtl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/deltix/util/collections/ArrayList.vtl b/src/deltix/util/collections/ArrayList.vtl index c233ed8a..19fcb6a9 100644 --- a/src/deltix/util/collections/ArrayList.vtl +++ b/src/deltix/util/collections/ArrayList.vtl @@ -386,6 +386,7 @@ public final class ${name}ArrayList * * @return a clone of this ${name}ArrayList instance. */ + @SuppressWarnings("unchecked") public Object clone () { try { ${name}ArrayList v = (${name}ArrayList) super.clone(); From 4348e2bc175eebd4488eb0745c9733923bd921b2 Mon Sep 17 00:00:00 2001 From: gene Date: Sat, 2 Dec 2006 03:19:56 +0000 Subject: [PATCH 0037/2572] --- src/deltix/util/jdbc/JDBCUtils.java | 5 ++++- src/deltix/util/jdbc/NullValueException.java | 12 ++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 src/deltix/util/jdbc/NullValueException.java diff --git a/src/deltix/util/jdbc/JDBCUtils.java b/src/deltix/util/jdbc/JDBCUtils.java index 5bd5b355..9d898ebb 100644 --- a/src/deltix/util/jdbc/JDBCUtils.java +++ b/src/deltix/util/jdbc/JDBCUtils.java @@ -41,9 +41,12 @@ public static int queryInt (PreparedStatement ps) throws SQLExcept try { if (!rs.next ()) throw new NoRowsReturnedException (); - + int ret = rs.getInt (1); + if (rs.wasNull ()) + throw new NullValueException (); + if (rs.next ()) throw new MultipleRowsReturnedException (); diff --git a/src/deltix/util/jdbc/NullValueException.java b/src/deltix/util/jdbc/NullValueException.java new file mode 100644 index 00000000..1fd56696 --- /dev/null +++ b/src/deltix/util/jdbc/NullValueException.java @@ -0,0 +1,12 @@ +package deltix.util.jdbc; + +import java.sql.SQLException; + +/** + * + */ +public class NullValueException extends SQLException { + public NullValueException () { + super ("Query returned null"); + } +} From 9972955beb07ea166968a587723f0ce922915857 Mon Sep 17 00:00:00 2001 From: gene Date: Wed, 6 Dec 2006 02:01:18 +0000 Subject: [PATCH 0038/2572] working shadow updater --- src/deltix/util/jdbc/JDBCUtils.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/deltix/util/jdbc/JDBCUtils.java b/src/deltix/util/jdbc/JDBCUtils.java index 9d898ebb..84f96b57 100644 --- a/src/deltix/util/jdbc/JDBCUtils.java +++ b/src/deltix/util/jdbc/JDBCUtils.java @@ -35,6 +35,18 @@ public static void updateDouble (ResultSet rs, int idx, double v) rs.updateDouble (idx, v); } + /** + * Converts null to SQL NULL + */ + public static void setString (PreparedStatement ps, int idx, String v) + throws SQLException + { + if (v == null) + ps.setNull (idx, Types.VARCHAR); + else + ps.setString (idx, v); + } + public static int queryInt (PreparedStatement ps) throws SQLException { ResultSet rs = ps.executeQuery (); From d86f5e360842ad4f201a64f326b994c157bad038 Mon Sep 17 00:00:00 2001 From: gene Date: Mon, 11 Dec 2006 18:16:28 +0000 Subject: [PATCH 0039/2572] --- src/deltix/util/net/TCPLogger.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/deltix/util/net/TCPLogger.java b/src/deltix/util/net/TCPLogger.java index 9eab3d53..34d2ca93 100644 --- a/src/deltix/util/net/TCPLogger.java +++ b/src/deltix/util/net/TCPLogger.java @@ -47,6 +47,11 @@ public void run () { } public static void main (String [] args) throws Exception { + if (args.length == 0) { + System.out.println ("tcplog "); + return; + } + String delegateHost = args [0]; int localPort = Integer.parseInt (args [1]); int delegatePort = Integer.parseInt (args [2]); From cd69f2748efc0d71c467b799e293a10b5b8cde6c Mon Sep 17 00:00:00 2001 From: gene Date: Wed, 13 Dec 2006 17:38:27 +0000 Subject: [PATCH 0040/2572] Unfinished - incremental attribute loading --- src/deltix/util/jdbc/LoadCSV.java | 169 ++++++++++++++++++++++++++++++ 1 file changed, 169 insertions(+) create mode 100644 src/deltix/util/jdbc/LoadCSV.java diff --git a/src/deltix/util/jdbc/LoadCSV.java b/src/deltix/util/jdbc/LoadCSV.java new file mode 100644 index 00000000..450f6be6 --- /dev/null +++ b/src/deltix/util/jdbc/LoadCSV.java @@ -0,0 +1,169 @@ +package deltix.util.jdbc; + +import java.io.*; +import java.sql.*; + +import au.com.bytecode.opencsv.CSVReader; +import deltix.custom.statestreet.fxa.utils.Common; +import deltix.util.Util; + +/** + * + */ +public class LoadCSV { + private int mBatchSize = 1000; + private boolean mAutoCommit = true; + private Connection mOutputConnection; + + public void setAutoCommit (boolean flag) { + mAutoCommit = flag; + } + + public void setBatchSize (int size) { + mBatchSize = size; + } + + public void setOutputConnection (Connection outConn) { + mOutputConnection = outConn; + } + + public void load (File f) throws IOException, SQLException { + String tableName = f.getName (); + int dot = tableName.indexOf ('.'); + + if (dot >= 0) + tableName = tableName.substring (0, dot); + + FileReader rd = new FileReader (f); + + try { + load (tableName, rd); + } finally { + Util.close (rd); + } + } + + public void load ( + String tableName, + Reader rd + ) + throws IOException, SQLException + { + CSVReader csv = new CSVReader (rd); + String [] headers = csv.readNext (); + + if (headers == null) + throw new EOFException ("No headers in CSV file"); + + StringBuilder createSql = new StringBuilder (); + StringBuilder insertSql = new StringBuilder (); + + createSql.append ("CREATE TABLE \""); + createSql.append (tableName); + createSql.append ("\" ("); + + insertSql.append ("INSERT INTO \""); + insertSql.append (tableName); + insertSql.append ("\" ("); + + for (int ii = 0; ii < headers.length; ii++) { + String col = headers [ii]; + + if (ii > 0) { + createSql.append (", "); + insertSql.append (","); + } + + createSql.append ("\""); + createSql.append (col); + createSql.append ("\" VARCHAR2 (2000)"); + + insertSql.append ("\""); + insertSql.append (col); + insertSql.append ("\""); + } + + createSql.append (")"); + + insertSql.append (") VALUES ("); + + for (int ii = 0; ii < headers.length; ii++) { + if (ii > 0) + insertSql.append (","); + + insertSql.append ("?"); + } + + insertSql.append (")"); + + JDBCUtils.exec (mOutputConnection, createSql.toString ()); + + PreparedStatement ps = + mOutputConnection.prepareStatement (insertSql.toString ()); + + try { + int batchCount = 0; + String [] line; + + while ((line = csv.readNext ()) != null) { + for (int col = 0; col < headers.length; col++) + ps.setString (col + 1, line [col]); + + ps.addBatch (); + batchCount++; + + if (batchCount == mBatchSize) { + ps.executeBatch (); + batchCount = 0; + + if (mAutoCommit) + mOutputConnection.commit (); + } + } + + if (batchCount != 0) { + ps.executeBatch (); + + if (mAutoCommit) + mOutputConnection.commit (); + } + } finally { + JDBCUtils.close (ps); + } + } + + public static void main (String [] args) throws Exception { + if (args.length < 6) { + System.out.println ( + "Usage: csvload ..." + ); + return; + } + + Connection outConn = null; + + try { + outConn = + ORACLE.openThinConnection ( + args [0], + Integer.parseInt (args [1]), + args [2], + args [3], + args [4] + ); + + LoadCSV loader = new LoadCSV (); + + loader.setOutputConnection (outConn); + + for (int ii = 5; ii < args.length; ii++) + loader.load (new File (args [ii])); + + outConn.close (); + + } finally { + JDBCUtils.close (outConn); + + } + } +} From 32dc897d3c25c4e4ad7004fa8594cf68d9467836 Mon Sep 17 00:00:00 2001 From: gene Date: Mon, 18 Dec 2006 18:04:58 +0000 Subject: [PATCH 0041/2572] --- .../custom/statestreet/fxa/load/MDDump.java | 1 + .../jdbc}/AccessConnectionFactory.java | 5 +- src/deltix/util/jdbc/LoadMDB.java | 166 ++++++++++++++++++ 3 files changed, 170 insertions(+), 2 deletions(-) rename src/deltix/{custom/statestreet/fxa/utils => util/jdbc}/AccessConnectionFactory.java (78%) create mode 100644 src/deltix/util/jdbc/LoadMDB.java diff --git a/src/deltix/custom/statestreet/fxa/load/MDDump.java b/src/deltix/custom/statestreet/fxa/load/MDDump.java index ace4e91d..9a9ec23d 100644 --- a/src/deltix/custom/statestreet/fxa/load/MDDump.java +++ b/src/deltix/custom/statestreet/fxa/load/MDDump.java @@ -1,5 +1,6 @@ package deltix.custom.statestreet.fxa.load; +import deltix.util.jdbc.AccessConnectionFactory; import java.io.*; import java.sql.*; diff --git a/src/deltix/custom/statestreet/fxa/utils/AccessConnectionFactory.java b/src/deltix/util/jdbc/AccessConnectionFactory.java similarity index 78% rename from src/deltix/custom/statestreet/fxa/utils/AccessConnectionFactory.java rename to src/deltix/util/jdbc/AccessConnectionFactory.java index b6be06ae..fe38f830 100644 --- a/src/deltix/custom/statestreet/fxa/utils/AccessConnectionFactory.java +++ b/src/deltix/util/jdbc/AccessConnectionFactory.java @@ -1,5 +1,6 @@ -package deltix.custom.statestreet.fxa.utils; +package deltix.util.jdbc; +import deltix.util.Util; import java.sql.*; import java.io.*; import java.util.logging.*; @@ -12,7 +13,7 @@ public class AccessConnectionFactory { try { Class.forName ("sun.jdbc.odbc.JdbcOdbcDriver"); } catch (Throwable x) { - Common.LOGGER.log (Level.SEVERE, "Failed to load the ODBC/JDBC driver", x); + Util.LOGGER.log (Level.SEVERE, "Failed to load the ODBC/JDBC driver", x); System.exit (1); } } diff --git a/src/deltix/util/jdbc/LoadMDB.java b/src/deltix/util/jdbc/LoadMDB.java new file mode 100644 index 00000000..9ac1f8e4 --- /dev/null +++ b/src/deltix/util/jdbc/LoadMDB.java @@ -0,0 +1,166 @@ +package deltix.util.jdbc; + +import java.io.*; +import java.sql.*; + +import deltix.custom.statestreet.fxa.utils.Common; +import deltix.util.Util; + +/** + * + */ +public class LoadMDB { + private int mBatchSize = 1000; + private boolean mAutoCommit = true; + private Connection mOutputConnection; + private Connection mInputConnection; + + public void setAutoCommit (boolean flag) { + mAutoCommit = flag; + } + + public void setBatchSize (int size) { + mBatchSize = size; + } + + public void setOutputConnection (Connection outConn) { + mOutputConnection = outConn; + } + + public void setInputConnection (Connection outConn) { + mInputConnection = outConn; + } + + public void loadTable ( + String tableName + ) + throws SQLException + { + Statement stmt = mInputConnection.createStatement (); + ResultSet rs = stmt.executeQuery ("SELECT * FROM [" + tableName + "]"); + ResultSetMetaData md = rs.getMetaData (); + + StringBuilder createSql = new StringBuilder (); + StringBuilder insertSql = new StringBuilder (); + + createSql.append ("CREATE TABLE \""); + createSql.append (tableName); + createSql.append ("\" ("); + + insertSql.append ("INSERT INTO \""); + insertSql.append (tableName); + insertSql.append ("\" ("); + + for (int ii = 1; ii <= md.getColumnCount (); ii++) { + String col = md.getColumnName (ii); + String typename = md.getColumnTypeName (ii); + int prec = md.getPrecision (ii); + String cname = md.getColumnClassName (ii); + + System.out.println (col + ", " + typename + ", " + prec + ", " + cname); + /* + if (ii > 0) { + createSql.append (", "); + insertSql.append (","); + } + + createSql.append ("\""); + createSql.append (col); + createSql.append ("\" VARCHAR2 (2000)"); + + insertSql.append ("\""); + insertSql.append (col); + insertSql.append ("\""); + */ + } + + createSql.append (")"); + + insertSql.append (") VALUES ("); + + for (int ii = 1; ii <= md.getColumnCount (); ii++) { + if (ii > 0) + insertSql.append (","); + + insertSql.append ("?"); + } + + insertSql.append (")"); + + /* + JDBCUtils.exec (mOutputConnection, createSql.toString ()); + + PreparedStatement ps = + mOutputConnection.prepareStatement (insertSql.toString ()); + + try { + int batchCount = 0; + String [] line; + + while ((line = csv.readNext ()) != null) { + for (int col = 0; col < headers.length; col++) + ps.setString (col + 1, line [col]); + + ps.addBatch (); + batchCount++; + + if (batchCount == mBatchSize) { + ps.executeBatch (); + batchCount = 0; + + if (mAutoCommit) + mOutputConnection.commit (); + } + } + + if (batchCount != 0) { + ps.executeBatch (); + + if (mAutoCommit) + mOutputConnection.commit (); + } + } finally { + JDBCUtils.close (ps); + } + */ + } + + public static void main (String [] args) throws Exception { + if (args.length < 6) { + System.out.println ( + "Usage: mdbload ..." + ); + return; + } + + Connection outConn = null; + Connection inConn = null; + + try { + outConn = + ORACLE.openThinConnection ( + args [0], + Integer.parseInt (args [1]), + args [2], + args [3], + args [4] + ); + + inConn = AccessConnectionFactory.open (new File (args [5])); + + LoadMDB loader = new LoadMDB (); + + loader.setOutputConnection (outConn); + loader.setInputConnection (inConn); + + for (int ii = 6; ii < args.length; ii++) + loader.loadTable (args [ii]); + + outConn.close (); + inConn.close (); + } finally { + JDBCUtils.close (outConn); + JDBCUtils.close (inConn); + } + } +} From abb021280d6264161426879ddb73f7ede96aa972 Mon Sep 17 00:00:00 2001 From: gene Date: Tue, 19 Dec 2006 16:58:33 +0000 Subject: [PATCH 0042/2572] --- src/deltix/util/jdbc/LoadMDB.java | 150 ++++++++++++++++++------------ 1 file changed, 90 insertions(+), 60 deletions(-) diff --git a/src/deltix/util/jdbc/LoadMDB.java b/src/deltix/util/jdbc/LoadMDB.java index 9ac1f8e4..a8c49461 100644 --- a/src/deltix/util/jdbc/LoadMDB.java +++ b/src/deltix/util/jdbc/LoadMDB.java @@ -36,70 +36,101 @@ public void loadTable ( ) throws SQLException { - Statement stmt = mInputConnection.createStatement (); - ResultSet rs = stmt.executeQuery ("SELECT * FROM [" + tableName + "]"); - ResultSetMetaData md = rs.getMetaData (); - - StringBuilder createSql = new StringBuilder (); - StringBuilder insertSql = new StringBuilder (); - - createSql.append ("CREATE TABLE \""); - createSql.append (tableName); - createSql.append ("\" ("); - - insertSql.append ("INSERT INTO \""); - insertSql.append (tableName); - insertSql.append ("\" ("); - - for (int ii = 1; ii <= md.getColumnCount (); ii++) { - String col = md.getColumnName (ii); - String typename = md.getColumnTypeName (ii); - int prec = md.getPrecision (ii); - String cname = md.getColumnClassName (ii); - - System.out.println (col + ", " + typename + ", " + prec + ", " + cname); - /* - if (ii > 0) { - createSql.append (", "); - insertSql.append (","); - } - - createSql.append ("\""); - createSql.append (col); - createSql.append ("\" VARCHAR2 (2000)"); - - insertSql.append ("\""); - insertSql.append (col); - insertSql.append ("\""); - */ - } - - createSql.append (")"); - - insertSql.append (") VALUES ("); - - for (int ii = 1; ii <= md.getColumnCount (); ii++) { - if (ii > 0) - insertSql.append (","); - - insertSql.append ("?"); - } - - insertSql.append (")"); - - /* - JDBCUtils.exec (mOutputConnection, createSql.toString ()); - - PreparedStatement ps = - mOutputConnection.prepareStatement (insertSql.toString ()); + Statement stmt = null; + PreparedStatement ps = null; try { + stmt = mInputConnection.createStatement (); + ResultSet rs = stmt.executeQuery ("SELECT * FROM [" + tableName + "]"); + ResultSetMetaData md = rs.getMetaData (); + int numColumns = md.getColumnCount (); + boolean [] okObjectTrf = new boolean [numColumns + 1]; + StringBuilder createSql = new StringBuilder (); + StringBuilder insertSql = new StringBuilder (); + + createSql.append ("CREATE TABLE \""); + createSql.append (tableName); + createSql.append ("\" ("); + + insertSql.append ("INSERT INTO \""); + insertSql.append (tableName); + insertSql.append ("\" ("); + + for (int ii = 1; ii <= numColumns; ii++) { + String col = md.getColumnName (ii); + int prec = md.getPrecision (ii); + String cname = md.getColumnClassName (ii); + + //System.out.println (col + ", " + typename + ", " + prec + ", " + cname); + + if (ii > 0) { + createSql.append (", "); + insertSql.append (","); + } + + createSql.append ("\""); + createSql.append (col); + createSql.append ("\" "); + + + + if (cname.equals ("java.lang.String")) { + createSql.append ("VARCHAR (" + prec + ")"); + okObjectTrf [ii] = true; + } + else if (cname.equals ("java.lang.Float") || cname.equals ("java.lang.Double")) { + createSql.append ("FLOAT"); + okObjectTrf [ii] = true; + } + else if (cname.equals ("java.sql.Timestamp")) { + createSql.append ("VARCHAR (32)"); // do not mess with time conversion now + okObjectTrf [ii] = false; + } + else { + System.out.println ("Defaulting " + col + " type for class " + cname); + createSql.append ("VARCHAR (2000)"); + okObjectTrf [ii] = false; + } + + insertSql.append ("\""); + insertSql.append (col); + insertSql.append ("\""); + } + + createSql.append (")"); + + insertSql.append (") VALUES ("); + + for (int ii = 1; ii <= numColumns; ii++) { + if (ii > 0) + insertSql.append (","); + + insertSql.append ("?"); + } + + insertSql.append (")"); + + String createSqlStr = createSql.toString (); + + System.out.println (createSqlStr); + + JDBCUtils.exec (mOutputConnection, createSqlStr); + + ps = mOutputConnection.prepareStatement (insertSql.toString ()); + int batchCount = 0; String [] line; - while ((line = csv.readNext ()) != null) { - for (int col = 0; col < headers.length; col++) - ps.setString (col + 1, line [col]); + while (rs.next ()) { + for (int ii = 1; ii < numColumns; ii++) { + String cname = md.getColumnClassName (ii); + Object val = rs.getObject (ii); + + if (val == null || okObjectTrf [ii]) + ps.setObject (ii, val); + else + ps.setString (ii, val.toString ()); + } ps.addBatch (); batchCount++; @@ -122,7 +153,6 @@ public void loadTable ( } finally { JDBCUtils.close (ps); } - */ } public static void main (String [] args) throws Exception { From 47204f9997741fe1110128009d113daa683e368d Mon Sep 17 00:00:00 2001 From: gene Date: Tue, 19 Dec 2006 17:21:28 +0000 Subject: [PATCH 0043/2572] --- src/deltix/util/jdbc/LoadMDB.java | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/deltix/util/jdbc/LoadMDB.java b/src/deltix/util/jdbc/LoadMDB.java index a8c49461..7997d2cc 100644 --- a/src/deltix/util/jdbc/LoadMDB.java +++ b/src/deltix/util/jdbc/LoadMDB.java @@ -44,6 +44,9 @@ public void loadTable ( ResultSet rs = stmt.executeQuery ("SELECT * FROM [" + tableName + "]"); ResultSetMetaData md = rs.getMetaData (); int numColumns = md.getColumnCount (); + + System.out.println (numColumns + " Columns"); + boolean [] okObjectTrf = new boolean [numColumns + 1]; StringBuilder createSql = new StringBuilder (); StringBuilder insertSql = new StringBuilder (); @@ -63,7 +66,7 @@ public void loadTable ( //System.out.println (col + ", " + typename + ", " + prec + ", " + cname); - if (ii > 0) { + if (ii > 1) { createSql.append (", "); insertSql.append (","); } @@ -71,9 +74,7 @@ public void loadTable ( createSql.append ("\""); createSql.append (col); createSql.append ("\" "); - - - + if (cname.equals ("java.lang.String")) { createSql.append ("VARCHAR (" + prec + ")"); okObjectTrf [ii] = true; @@ -114,6 +115,12 @@ else if (cname.equals ("java.sql.Timestamp")) { System.out.println (createSqlStr); + try { + JDBCUtils.exec (mOutputConnection, "DROP TABLE \"" + tableName + "\" CASCADE CONSTRAINTS"); + } catch (SQLException x) { + // ignore + } + JDBCUtils.exec (mOutputConnection, createSqlStr); ps = mOutputConnection.prepareStatement (insertSql.toString ()); @@ -122,11 +129,13 @@ else if (cname.equals ("java.sql.Timestamp")) { String [] line; while (rs.next ()) { - for (int ii = 1; ii < numColumns; ii++) { + for (int ii = 1; ii <= numColumns; ii++) { String cname = md.getColumnClassName (ii); Object val = rs.getObject (ii); - if (val == null || okObjectTrf [ii]) + if (val == null) + ps.setNull (ii, okObjectTrf [ii] ? md.getColumnType (ii) : Types.VARCHAR); + else if (okObjectTrf [ii]) ps.setObject (ii, val); else ps.setString (ii, val.toString ()); From a544c881ebfc4ad95174e9e5e806bf583d740e23 Mon Sep 17 00:00:00 2001 From: gene Date: Thu, 21 Dec 2006 17:42:02 +0000 Subject: [PATCH 0044/2572] --- src/deltix/util/jdbc/LoadMDB.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/deltix/util/jdbc/LoadMDB.java b/src/deltix/util/jdbc/LoadMDB.java index 7997d2cc..0c4334f1 100644 --- a/src/deltix/util/jdbc/LoadMDB.java +++ b/src/deltix/util/jdbc/LoadMDB.java @@ -103,7 +103,7 @@ else if (cname.equals ("java.sql.Timestamp")) { insertSql.append (") VALUES ("); for (int ii = 1; ii <= numColumns; ii++) { - if (ii > 0) + if (ii > 1) insertSql.append (","); insertSql.append ("?"); @@ -113,8 +113,6 @@ else if (cname.equals ("java.sql.Timestamp")) { String createSqlStr = createSql.toString (); - System.out.println (createSqlStr); - try { JDBCUtils.exec (mOutputConnection, "DROP TABLE \"" + tableName + "\" CASCADE CONSTRAINTS"); } catch (SQLException x) { @@ -123,6 +121,8 @@ else if (cname.equals ("java.sql.Timestamp")) { JDBCUtils.exec (mOutputConnection, createSqlStr); + System.out.println (insertSql.toString ()); + ps = mOutputConnection.prepareStatement (insertSql.toString ()); int batchCount = 0; From 58033dd463d2e4f4cd2248bb7ea02e7680925b55 Mon Sep 17 00:00:00 2001 From: gene Date: Tue, 2 Jan 2007 22:19:21 +0000 Subject: [PATCH 0045/2572] --- src/deltix/util/xml/XSLT.java | 40 +++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 src/deltix/util/xml/XSLT.java diff --git a/src/deltix/util/xml/XSLT.java b/src/deltix/util/xml/XSLT.java new file mode 100644 index 00000000..bd1fd52d --- /dev/null +++ b/src/deltix/util/xml/XSLT.java @@ -0,0 +1,40 @@ +package deltix.util.xml; + +import java.io.*; + +/** + * + */ +public class XSLT { + + /** + * Accept two command line arguments: the name of an XML file, and + * the name of an XSLT stylesheet. The result of the transformation + * is written to stdout. + */ + public static void main(String[] args) throws Exception { + if (args.length != 2) { + System.err.println ("Usage: xslt "); + System.exit(1); + } + + File xmlFile = new File(args[0]); + File xsltFile = new File(args[1]); + + javax.xml.transform.Source xmlSource = + new javax.xml.transform.stream.StreamSource(xmlFile); + javax.xml.transform.Source xsltSource = + new javax.xml.transform.stream.StreamSource(xsltFile); + javax.xml.transform.Result result = + new javax.xml.transform.stream.StreamResult(System.out); + + // create an instance of TransformerFactory + javax.xml.transform.TransformerFactory transFact = + javax.xml.transform.TransformerFactory.newInstance( ); + + javax.xml.transform.Transformer trans = + transFact.newTransformer(xsltSource); + + trans.transform(xmlSource, result); + } +} From fdbde6bc783cba362b65f1e8a871736fceb55e65 Mon Sep 17 00:00:00 2001 From: gene Date: Wed, 3 Jan 2007 21:03:24 +0000 Subject: [PATCH 0046/2572] --- src/deltix/util/codec/Base64Decoder.java | 141 ++++++++++++++ src/deltix/util/codec/Base64Encoder.java | 87 +++++++++ src/deltix/util/codec/BinCharEncoder.java | 32 ++++ src/deltix/util/codec/CharBinDecoder.java | 39 ++++ src/deltix/util/codec/HexBinCharEncoder.java | 185 +++++++++++++++++++ src/deltix/util/codec/HexCharBinDecoder.java | 51 +++++ 6 files changed, 535 insertions(+) create mode 100644 src/deltix/util/codec/Base64Decoder.java create mode 100644 src/deltix/util/codec/Base64Encoder.java create mode 100644 src/deltix/util/codec/BinCharEncoder.java create mode 100644 src/deltix/util/codec/CharBinDecoder.java create mode 100644 src/deltix/util/codec/HexBinCharEncoder.java create mode 100644 src/deltix/util/codec/HexCharBinDecoder.java diff --git a/src/deltix/util/codec/Base64Decoder.java b/src/deltix/util/codec/Base64Decoder.java new file mode 100644 index 00000000..ff51cc6a --- /dev/null +++ b/src/deltix/util/codec/Base64Decoder.java @@ -0,0 +1,141 @@ +package deltix.util.codec; + +import java.io.*; + +/** + * See RFC1521. + */ +public class Base64Decoder extends CharBinDecoder { + private int spill = 0; + private int mPos = 0; + + public Base64Decoder (OutputStream os) { + super (os); + } + + private void output (int byt) throws IOException { + mOutputStream.write (byt); + } + + private void decode6 (int sixBit) throws IOException { + switch (mPos) { + case 0: + spill = sixBit << 2; + mPos = 1; + break; + + case 1: + output (spill | (sixBit >> 4)); + spill = (sixBit & 0xF) << 4; + mPos = 2; + break; + + case 2: + output (spill | (sixBit >> 2)); + spill = (sixBit & 0x3) << 6; + mPos = 3; + break; + + case 3: + output (spill | sixBit); + spill = 0; + mPos = 0; + break; + + case 4: + throw new CharConversionException ( + "Index characters after the padding (=) are illegal." + ); + + default: + throw new RuntimeException ("Illegal state"); + } + } + + private void pad () throws IOException { + switch (mPos) { + case 0: + throw new CharConversionException ( + "Padding (=) in 1st position is illegal." + ); + + case 1: + throw new CharConversionException ( + "Padding (=) in 2nd position is illegal." + ); + + case 2: + if (spill != 0) + throw new CharConversionException ( + "Padding (=) in 3rd position is illegal after non-0 bits (" + + (spill >> 4) + ")." + ); + + mPos = 3; + break; + + case 3: + if (spill != 0) + throw new CharConversionException ( + "Padding (=) in 3rd position is illegal after non-0 bits (" + + (spill >> 6) + ")." + ); + + mPos = 4; + break; + + default: + throw new RuntimeException ("Illegal state"); + } + } + + private void decode (char ch) throws IOException { + int diff = ch - 'A'; + + if (diff >= 0 && diff <= 25) { + decode6 (diff); + return; + } + + diff = ch - 'a'; + + if (diff >= 0 && diff <= 25) { + decode6 (diff + 26); + return; + } + + diff = ch - '0'; + + if (diff >= 0 && diff <= 9) { + decode6 (diff + 52); + return; + } + + switch (ch) { + case '+': decode6 (62); return; + case '/': decode6 (63); return; + case '=': pad (); return; + default: /*skip*/ return; + } + } + + public void write (char cbuf [], int off, int len) throws IOException { + for (int ii = 0; ii < len; ii++) + decode (cbuf [off + ii]); + } + + public static void main (String [] args) throws Exception { + Base64Decoder dec = new Base64Decoder (System.out); + + for (;;) { + int ch = System.in.read (); + + if (ch < 0) + break; + + dec.write (ch); + } + + dec.flush (); + } +} diff --git a/src/deltix/util/codec/Base64Encoder.java b/src/deltix/util/codec/Base64Encoder.java new file mode 100644 index 00000000..cc254b7e --- /dev/null +++ b/src/deltix/util/codec/Base64Encoder.java @@ -0,0 +1,87 @@ +package deltix.util.codec; + +import java.io.*; + +public class Base64Encoder extends BinCharEncoder { + private final static char DICTIONARY [] = { + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', + 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', + 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', + 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', + 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', + 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', + 'w', 'x', 'y', 'z', '0', '1', '2', '3', + '4', '5', '6', '7', '8', '9', '+', '/' + }; + + private int mByte1; + private int mByte2; + private int mNumBytes = 0; + + public Base64Encoder (Writer wr) { + super (wr); + } + + private void writeCode (int code) throws IOException { + mWriter.write (DICTIONARY [code]); + } + + public void write (int byt) throws IOException { + byt = byt & 0xFF; + + switch (mNumBytes) { + case 0: + mByte1 = byt; + mNumBytes = 1; + break; + + case 1: + mByte2 = byt; + mNumBytes = 2; + break; + + case 2: + writeCode (mByte1 >> 2); + writeCode (((mByte1 & 0x3) << 4) | (mByte2 >> 4)); + writeCode (((mByte2 & 0xf) << 2) | (byt >> 6)); + writeCode (byt & 0x3f); + mNumBytes = 0; + break; + + default: + throw new RuntimeException (); + } + } + + public void flush () throws IOException { + switch (mNumBytes) { + case 0: + break; + + case 1: + writeCode (mByte1 >> 2); + writeCode ((mByte1 & 0x3) << 4); + mWriter.write ("=="); + break; + + case 2: + writeCode (mByte1 >> 2); + writeCode (((mByte1 & 0x3) << 4) | (mByte2 >> 4)); + writeCode ((mByte2 & 0xf) << 2); + mWriter.write ("="); + break; + + default: + throw new RuntimeException (); + } + + super.flush (); + } + + public static void main (String [] args) throws Exception { + OutputStreamWriter wr = new OutputStreamWriter (System.out); + Base64Encoder b64enc = new Base64Encoder (wr); + deltix.util.io.StreamPump.pump (System.in, b64enc); + b64enc.flush (); + } +} \ No newline at end of file diff --git a/src/deltix/util/codec/BinCharEncoder.java b/src/deltix/util/codec/BinCharEncoder.java new file mode 100644 index 00000000..e3a21e78 --- /dev/null +++ b/src/deltix/util/codec/BinCharEncoder.java @@ -0,0 +1,32 @@ +package deltix.util.codec; + +import java.io.*; + +public abstract class BinCharEncoder extends OutputStream { + protected Writer mWriter; + + protected BinCharEncoder (Writer wr) { + mWriter = wr; + } + + /* + public void write (int b) throws IOException { + } + + if necessary: + + public void flush() throws IOException { + super.flush (); + ... + } + */ + + public void close () throws IOException { + flush (); + mWriter.close (); + } + + public void flush () throws IOException { + mWriter.flush (); + } +} diff --git a/src/deltix/util/codec/CharBinDecoder.java b/src/deltix/util/codec/CharBinDecoder.java new file mode 100644 index 00000000..8d1dbd03 --- /dev/null +++ b/src/deltix/util/codec/CharBinDecoder.java @@ -0,0 +1,39 @@ +package deltix.util.codec; + +import java.io.*; + +public abstract class CharBinDecoder extends Writer { + protected OutputStream mOutputStream; + + protected CharBinDecoder (OutputStream os) { + mOutputStream = os; + } + + /* + optional: + + public void write(int c) throws IOException { + } + + mandatory: + + public void write (char cbuf [], int off, int len) throws IOException { + } + + if necessary: + + public void flush() throws IOException { + super.flush (); + ... + } + */ + + public void close() throws IOException { + flush (); + mOutputStream.close (); + } + + public void flush () throws IOException { + mOutputStream.flush (); + } +} diff --git a/src/deltix/util/codec/HexBinCharEncoder.java b/src/deltix/util/codec/HexBinCharEncoder.java new file mode 100644 index 00000000..ad2b5941 --- /dev/null +++ b/src/deltix/util/codec/HexBinCharEncoder.java @@ -0,0 +1,185 @@ +package deltix.util.codec; + +import java.io.*; + +import deltix.util.*; + +public class HexBinCharEncoder extends BinCharEncoder { + private static final char [] UPPER_CASE_VOCABULARY = { + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' + }; + + private static final char [] LOWER_CASE_VOCABULARY = { + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' + }; + + private char [] mVocabulary; + private boolean mInsertSpace; + private int mNumPerLine; + private String mPrefix; + private String mPostfix; + private int mNumInThisLine = 0; + + /** + * @param wr The Writer to write to + * @param insertSpace Whether to insert spaces bertween each byte + * @param upperCase Whether to use upper-case letters + * @param numPerLine If > 0, a line separator will be inserted + * after this many bytes. + * @param prefix The characters to write at the beginning + * of each line + * @param postfix The characters to write at the end + * of each line + */ + public HexBinCharEncoder ( + Writer wr, + boolean insertSpace, + boolean upperCase, + int numPerLine, + String prefix, + String postfix + ) + { + super (wr); + mVocabulary = + upperCase ? UPPER_CASE_VOCABULARY : LOWER_CASE_VOCABULARY; + + mNumPerLine = numPerLine > 0 ? numPerLine : -1; + mInsertSpace = insertSpace; + mPrefix = prefix; + mPostfix = postfix; + } + + /** + * @param wr The Writer to write to + * @param insertSpace Whether to insert spaces bertween each byte + * @param upperCase Whether to use upper-case letters + * @param numPerLine If > 0, a line separator will be inserted + * after this many bytes. + */ + public HexBinCharEncoder ( + Writer wr, + boolean insertSpace, + boolean upperCase, + int numPerLine + ) + { + this (wr, insertSpace, upperCase, numPerLine, "", ""); + } + + /** + * Constructs a HexBinCharEncoder that writes upper-case letters + * in a single line + * + * @param wr The Writer to write to + * @param insertSpace Whether to insert spaces bertween each byte + */ + public HexBinCharEncoder ( + Writer wr, + boolean insertSpace + ) + { + this (wr, insertSpace, true, 0); + } + + /** + * Constructs a HexBinCharEncoder that writes upper-case letters + * separated by spaces in a single line + * + * @param wr The Writer to write to + */ + public HexBinCharEncoder (Writer wr) { + this (wr, true, true, 0); + } + + public void write (int b) throws IOException { + if (mNumPerLine > 0) { + if (mNumInThisLine == 0) { + mWriter.write (mPrefix); + } + else if (mNumInThisLine == mNumPerLine) { + mWriter.write (mPostfix); + mWriter.write ('\n'); + mNumInThisLine = 0; + mWriter.write (mPrefix); + } + } + + if (mInsertSpace && mNumInThisLine > 0) { + mWriter.write (' '); + } + + mWriter.write (mVocabulary [(b >>> 4) & 0xF]); + mWriter.write (mVocabulary [b & 0xF]); + + if (mInsertSpace || mNumPerLine > 0) + mNumInThisLine++; + } + + /** + * Convenience method to encode a single array of bytes. + * + * @param bytes Bytes to encode + * @param insertSpace Whether to insert spaces bertween each byte + * @param upperCase Whether to use upper-case letters + * @param numPerLine If > 0, a line separator will be inserted + * after this many bytes. + * @return The encoded string. + */ + public static String encode ( + byte [] bytes, + boolean insertSpace, + boolean upperCase, + int numPerLine + ) + { + try { + StringWriter swr = new StringWriter (); + + HexBinCharEncoder enc = + new HexBinCharEncoder ( + swr, + insertSpace, + upperCase, + numPerLine + ); + + enc.write (bytes); + + return (swr.toString ()); + } catch (IOException iox) { + // IO Exception should not be thrown when + // writing to a StringWriter () + throw new RuntimeException (iox); + } + } + + public static void main (String [] args) throws Exception { + byte [] b = { + (byte) 0, (byte) 1, (byte) 2, (byte) 3, (byte) 4, + (byte) 5, (byte) 6, (byte) 7, (byte) 100, (byte) 101, + (byte) 102, (byte) 103, (byte) 104, (byte) 200, + (byte) 201, (byte) 202, (byte) 203, (byte) 204, (byte) 205 + }; + + Writer wr = new OutputStreamWriter (System.out); + + new HexBinCharEncoder (wr, true, true, 4).write (b); + + wr.flush (); + + System.out.println (); + + new HexBinCharEncoder (wr, false, false, 4).write (b); + + wr.flush (); + + System.out.println (); + + new HexBinCharEncoder (wr).write (b); + wr.flush (); + + } +} diff --git a/src/deltix/util/codec/HexCharBinDecoder.java b/src/deltix/util/codec/HexCharBinDecoder.java new file mode 100644 index 00000000..c1ea082e --- /dev/null +++ b/src/deltix/util/codec/HexCharBinDecoder.java @@ -0,0 +1,51 @@ +package deltix.util.codec; + +import java.io.*; + +public class HexCharBinDecoder extends CharBinDecoder { + int mUpper4Bits; + boolean mUpperBitsSet = false; + + public HexCharBinDecoder (OutputStream os) { + super (os); + } + + private void writeDigit (int n) throws IOException { + if (mUpperBitsSet) { + mOutputStream.write ((mUpper4Bits << 4) + n); + mUpperBitsSet = false; + } + else { + mUpper4Bits = n; + mUpperBitsSet = true; + } + } + + public void write (int c) throws IOException { + if (c >= '0' && c <= '9') + writeDigit (c - '0'); + else if (c >= 'a' && c <= 'f') + writeDigit (c - ('a' - 10)); + else if (c >= 'A' && c <= 'F') + writeDigit (c - ('A' - 10)); + } + + public void write (char cbuf [], int off, int len) throws IOException { + int limit = off + len; + + for (int ii = off; ii < limit; ii++) + write (cbuf [ii]); + } + + public static byte [] decode (String s) { + try { + ByteArrayOutputStream baos = new ByteArrayOutputStream (); + new HexCharBinDecoder (baos).write (s); + return (baos.toByteArray ()); + } catch (IOException iox) { + // IO Exception should not be thrown when + // writing to a ByteArrayOutputStream () + throw new RuntimeException (); + } + } +} From 7174b1a13f550991f883876a4dc10ec02eef5f0b Mon Sep 17 00:00:00 2001 From: gene Date: Tue, 23 Jan 2007 21:53:47 +0000 Subject: [PATCH 0047/2572] --- src/deltix/qsrv/pub/QDate.java | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 src/deltix/qsrv/pub/QDate.java diff --git a/src/deltix/qsrv/pub/QDate.java b/src/deltix/qsrv/pub/QDate.java new file mode 100644 index 00000000..d9b7728f --- /dev/null +++ b/src/deltix/qsrv/pub/QDate.java @@ -0,0 +1,21 @@ +package deltix.qsrv.pub; + +/** + * A simple record containing a year, a month and a day of month. + */ +public class QDate { + /** + * The year + */ + public int year; + + /** + * The month, 1 - 12 + */ + public int month; + + /** + * The day of month, 1 - 31 + */ + public int day; +} From f0d5eba9ab19962e62e57b7d776049c26b4be1da Mon Sep 17 00:00:00 2001 From: gene Date: Wed, 24 Jan 2007 16:58:17 +0000 Subject: [PATCH 0048/2572] --- src/deltix/util/jdbc/MSSQLServer.java | 67 +++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 src/deltix/util/jdbc/MSSQLServer.java diff --git a/src/deltix/util/jdbc/MSSQLServer.java b/src/deltix/util/jdbc/MSSQLServer.java new file mode 100644 index 00000000..c6e46527 --- /dev/null +++ b/src/deltix/util/jdbc/MSSQLServer.java @@ -0,0 +1,67 @@ +package deltix.util.jdbc; + +import deltix.util.Util; +import java.util.logging.*; +import java.sql.*; + +/** + * + */ +public class MSSQLServer { + public static void loadMSDriver () throws ClassNotFoundException { + Class.forName ("com.microsoft.jdbc.sqlserver.SQLServerDriver"); + } + + public static Connection openMSConnection ( + String host, + int port, + String dbname, + String user, + String password + ) + throws SQLException + { + try { + loadMSDriver (); + } catch (ClassNotFoundException cnfx) { + Util.LOGGER.log (Level.SEVERE, "Failed to load the MS SQL Server driver", cnfx); + } + + return ( + DriverManager.getConnection ( + "jdbc:microsoft:sqlserver://" + host + ":" + port + ";DatabaseName=" + dbname + + ";SelectMethod=cursor", + user, + password + ) + ); + } + + public static void loadInetDriver () throws ClassNotFoundException { + Class.forName ("com.inet.tds.TdsDriver"); + } + + public static Connection openInetConnection ( + String host, + int port, + String dbname, + String user, + String password + ) + throws SQLException + { + try { + loadInetDriver (); + } catch (ClassNotFoundException cnfx) { + Util.LOGGER.log (Level.SEVERE, "Failed to load the Inet SQL Server driver", cnfx); + } + + return ( + DriverManager.getConnection ( + "jdbc:inetdae7:" + host + ":" + port + "?database=" + dbname, + user, + password + ) + ); + } +} From 35399d634c1f992f825cd7cecdc48de81a86e8d3 Mon Sep 17 00:00:00 2001 From: gene Date: Wed, 24 Jan 2007 20:59:27 +0000 Subject: [PATCH 0049/2572] --- src/deltix/util/jdbc/MSSQLServer.java | 29 +++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/deltix/util/jdbc/MSSQLServer.java b/src/deltix/util/jdbc/MSSQLServer.java index c6e46527..ca815766 100644 --- a/src/deltix/util/jdbc/MSSQLServer.java +++ b/src/deltix/util/jdbc/MSSQLServer.java @@ -8,6 +8,35 @@ * */ public class MSSQLServer { + public static void loadMS2005Driver () throws ClassNotFoundException { + Class.forName ("com.microsoft.sqlserver.jdbc.SQLServerDriver"); + } + + public static Connection openMS2005Connection ( + String host, + int port, + String dbname, + String user, + String password + ) + throws SQLException + { + try { + loadMSDriver (); + } catch (ClassNotFoundException cnfx) { + Util.LOGGER.log (Level.SEVERE, "Failed to load the MS SQL Server driver", cnfx); + } + + return ( + DriverManager.getConnection ( + "jdbc:microsoft:sqlserver://" + host + ":" + port + ";DatabaseName=" + dbname + + ";SelectMethod=cursor", + user, + password + ) + ); + } + public static void loadMSDriver () throws ClassNotFoundException { Class.forName ("com.microsoft.jdbc.sqlserver.SQLServerDriver"); } From 6c993705edf3b4cae3d1c1c37948c57ca1700d2c Mon Sep 17 00:00:00 2001 From: gene Date: Thu, 25 Jan 2007 18:37:38 +0000 Subject: [PATCH 0050/2572] --- src/deltix/qsrv/pub/AbstractCursor.java | 31 +++++++++++++++++++ .../pub/{QDate.java => AbstractDate.java} | 8 ++--- 2 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 src/deltix/qsrv/pub/AbstractCursor.java rename src/deltix/qsrv/pub/{QDate.java => AbstractDate.java} (58%) diff --git a/src/deltix/qsrv/pub/AbstractCursor.java b/src/deltix/qsrv/pub/AbstractCursor.java new file mode 100644 index 00000000..ad781c47 --- /dev/null +++ b/src/deltix/qsrv/pub/AbstractCursor.java @@ -0,0 +1,31 @@ +package deltix.qsrv.pub; + +/** + * An abstract cursor for iterating over arbitrary sequences of data. + * Usage: + *
try {
+ *     while (cursor.next ()) {        
+ *         ... cursor.get??? () ...
+ *    }
+ *} finally {
+ *    cursor.close ();
+ *}
+ * 
+ * All implementations of this interface are designed to be used from a single + * thread and must be externally protected against concurrent calls. + */ +public interface AbstractCursor { + /** + * Moves on to the next data element. + * + * @return false if at the end of the cursor. + */ + public boolean next (); + + /** + * Closes the cursor and releases any associated resources. This method is + * guaranteed not to throw exceptions; therefore, it is safe to use in a + * finally clause directly. + */ + public void close (); +} diff --git a/src/deltix/qsrv/pub/QDate.java b/src/deltix/qsrv/pub/AbstractDate.java similarity index 58% rename from src/deltix/qsrv/pub/QDate.java rename to src/deltix/qsrv/pub/AbstractDate.java index d9b7728f..ece68114 100644 --- a/src/deltix/qsrv/pub/QDate.java +++ b/src/deltix/qsrv/pub/AbstractDate.java @@ -3,19 +3,19 @@ /** * A simple record containing a year, a month and a day of month. */ -public class QDate { +public interface AbstractDate { /** * The year */ - public int year; + public int getYear (); /** * The month, 1 - 12 */ - public int month; + public int getMonth (); /** * The day of month, 1 - 31 */ - public int day; + public int getDay (); } From 01c1957f303f76a3ee70cd399492747a3f602adf Mon Sep 17 00:00:00 2001 From: gene Date: Mon, 29 Jan 2007 19:30:48 +0000 Subject: [PATCH 0051/2572] --- src/deltix/util/Disposable.java | 11 +++ .../concurrent}/AbstractCursor.java | 20 ++--- .../util/concurrent/AsynchronousCursor.java | 14 +++ .../concurrent/AsynchronousDataSource.java | 35 ++++++++ .../AsynchronousDisposableDataSource.java | 11 +++ .../concurrent/DataSourceDemultiplexer.java | 89 +++++++++++++++++++ .../DisposableDataSourceDemultiplexer.java | 26 ++++++ .../util/concurrent/NotifyingRunnable.java | 16 ++++ src/deltix/util/swing/NonEmptyTextField.java | 8 +- 9 files changed, 215 insertions(+), 15 deletions(-) create mode 100644 src/deltix/util/Disposable.java rename src/deltix/{qsrv/pub => util/concurrent}/AbstractCursor.java (52%) create mode 100644 src/deltix/util/concurrent/AsynchronousCursor.java create mode 100644 src/deltix/util/concurrent/AsynchronousDataSource.java create mode 100644 src/deltix/util/concurrent/AsynchronousDisposableDataSource.java create mode 100644 src/deltix/util/concurrent/DataSourceDemultiplexer.java create mode 100644 src/deltix/util/concurrent/DisposableDataSourceDemultiplexer.java create mode 100644 src/deltix/util/concurrent/NotifyingRunnable.java diff --git a/src/deltix/util/Disposable.java b/src/deltix/util/Disposable.java new file mode 100644 index 00000000..8e7d3961 --- /dev/null +++ b/src/deltix/util/Disposable.java @@ -0,0 +1,11 @@ +package deltix.util; + +/** + * Something that can be closed. Analogous to the dot Net IDisposable concept. + */ +public interface Disposable { + /** + * Closes associated resources. + */ + public void close (); +} diff --git a/src/deltix/qsrv/pub/AbstractCursor.java b/src/deltix/util/concurrent/AbstractCursor.java similarity index 52% rename from src/deltix/qsrv/pub/AbstractCursor.java rename to src/deltix/util/concurrent/AbstractCursor.java index ad781c47..e446e9d3 100644 --- a/src/deltix/qsrv/pub/AbstractCursor.java +++ b/src/deltix/util/concurrent/AbstractCursor.java @@ -1,4 +1,6 @@ -package deltix.qsrv.pub; +package deltix.util.concurrent; + +import deltix.util.Disposable; /** * An abstract cursor for iterating over arbitrary sequences of data. @@ -14,18 +16,14 @@ * All implementations of this interface are designed to be used from a single * thread and must be externally protected against concurrent calls. */ -public interface AbstractCursor { +public interface AbstractCursor extends Disposable { /** - * Moves on to the next data element. + * Moves on to the next data element. This method blocks until + * the next element becomes available, or until the cursor is + * determined to be at the end of the sequence. * * @return false if at the end of the cursor. */ - public boolean next (); - - /** - * Closes the cursor and releases any associated resources. This method is - * guaranteed not to throw exceptions; therefore, it is safe to use in a - * finally clause directly. - */ - public void close (); + public boolean next () + throws InterruptedException; } diff --git a/src/deltix/util/concurrent/AsynchronousCursor.java b/src/deltix/util/concurrent/AsynchronousCursor.java new file mode 100644 index 00000000..b3e3b504 --- /dev/null +++ b/src/deltix/util/concurrent/AsynchronousCursor.java @@ -0,0 +1,14 @@ +package deltix.util.concurrent; + + +/** + * A cursor supporting asynchronous data transfer. Note that + * the concept of "data being available" supported by AsynchronousDataSource + * means that a subsequent call to {@link AbstractCursor#next} will not block. + * It does not mean that a subsequent call to {@link AbstractCursor#next} will + * retrn true. + */ +public interface AsynchronousCursor + extends AbstractCursor, AsynchronousDisposableDataSource +{ +} diff --git a/src/deltix/util/concurrent/AsynchronousDataSource.java b/src/deltix/util/concurrent/AsynchronousDataSource.java new file mode 100644 index 00000000..a0de7e60 --- /dev/null +++ b/src/deltix/util/concurrent/AsynchronousDataSource.java @@ -0,0 +1,35 @@ +package deltix.util.concurrent; + +/** + * An abstract source of data. + */ +public interface AsynchronousDataSource { + /** + * Performs a non-blocking check for data availability. + * + * @param timeout Maximum time to wait until data is available, + * in milliseconds. The value of 0 causes a non-blocking + * check to be performed. + * @return True if data is available, false if timeout has expired. + */ + public boolean isDataAvailable (long timeout) + throws InterruptedException; + + /** + * Performs a non-blocking check for data availability. + * + * @return True if data is available, false if not. + */ + public boolean isDataAvailable (); + + /** + * Adds Runnable to be notified of data availability + */ + public void addNotificationListener (Runnable l); + + /** + * Removes a Runnable previously registered with {@link #addNotificationListener} + */ + public void removeNotificationListener (Runnable l); + +} diff --git a/src/deltix/util/concurrent/AsynchronousDisposableDataSource.java b/src/deltix/util/concurrent/AsynchronousDisposableDataSource.java new file mode 100644 index 00000000..d4eaafa7 --- /dev/null +++ b/src/deltix/util/concurrent/AsynchronousDisposableDataSource.java @@ -0,0 +1,11 @@ +package deltix.util.concurrent; + +import deltix.util.Disposable; + +/** + * + */ +public interface AsynchronousDisposableDataSource + extends Disposable, AsynchronousDataSource +{ +} diff --git a/src/deltix/util/concurrent/DataSourceDemultiplexer.java b/src/deltix/util/concurrent/DataSourceDemultiplexer.java new file mode 100644 index 00000000..dc41534a --- /dev/null +++ b/src/deltix/util/concurrent/DataSourceDemultiplexer.java @@ -0,0 +1,89 @@ +package deltix.util.concurrent; + +import java.util.*; +import java.util.logging.*; + +import deltix.util.Util; + +/** + * Allows a single thread to receive data from multiple + * data sources. Note that the public methods of this class are NOT designed to + * be called concurrently, although the object itself is designed to manage + * concurrent processes. + */ +public class DataSourceDemultiplexer { + private Runnable mLock = + new NotifyingRunnable (); + + private Set mDataSources = + new HashSet (); + + public DataSourceDemultiplexer () { + } + + public void add (T ds) { + if (mDataSources.add (ds)) + ds.addNotificationListener (mLock); + } + + public void remove (T ds) { + if (mDataSources.remove (ds)) + ds.removeNotificationListener (mLock); + } + + /** + * Returns a read-only set of registered data sources + */ + public Set dataSources () { + return (Collections.unmodifiableSet (mDataSources)); + } + + public int getNumDataSources () { + return (mDataSources.size ()); + } + /** + * If one of registered data sources has data available, return it. + * Otherwise, return null. + */ + public T getSourceWithAvailableDataNoBlocking () { + for (T ds : mDataSources) + if (ds.isDataAvailable ()) + return (ds); + + return (null); + } + + public T getSourceWithAvailableData (long timeout) + throws InterruptedException + { + boolean firstTime = true; + long limit = 0; + long waitTimeout; + + synchronized (mLock) { + for (;;) { + T ds = getSourceWithAvailableDataNoBlocking (); + + if (ds != null) + return (ds); + + if (firstTime) { + if (timeout <= 0) + return (null); + + limit = System.currentTimeMillis () + timeout; + waitTimeout = timeout; + firstTime = false; + } + else { + waitTimeout = limit - System.currentTimeMillis (); + + if (waitTimeout <= 0) + return (null); + } + + mLock.wait (waitTimeout); + } + } + } +} diff --git a/src/deltix/util/concurrent/DisposableDataSourceDemultiplexer.java b/src/deltix/util/concurrent/DisposableDataSourceDemultiplexer.java new file mode 100644 index 00000000..657aba9c --- /dev/null +++ b/src/deltix/util/concurrent/DisposableDataSourceDemultiplexer.java @@ -0,0 +1,26 @@ +package deltix.util.concurrent; + +import java.util.logging.Level; + +import deltix.util.*; + +/** + * + */ +public class DisposableDataSourceDemultiplexer + extends DataSourceDemultiplexer + implements Disposable +{ + /** + * Closes all registered disposable data sources. All exceptions are logged + * to {@link Util#LOGGER} and ignored. + */ + public void close () { + for (T ds : dataSources ()) + try { + ds.close (); + } catch (Throwable x) { + Util.LOGGER.log (Level.SEVERE, "close () threw a " + x, x); + } + } +} diff --git a/src/deltix/util/concurrent/NotifyingRunnable.java b/src/deltix/util/concurrent/NotifyingRunnable.java new file mode 100644 index 00000000..bacf8d45 --- /dev/null +++ b/src/deltix/util/concurrent/NotifyingRunnable.java @@ -0,0 +1,16 @@ +package deltix.util.concurrent; + +/** + * A Runnable that calls notify () from its run () method. + */ +public class NotifyingRunnable implements Runnable { + /** + * Code: + *
public synchronized void run () {
+     *    notify ();
+     *}
+ */ + public synchronized void run () { + notify (); + } +} diff --git a/src/deltix/util/swing/NonEmptyTextField.java b/src/deltix/util/swing/NonEmptyTextField.java index 89a13af1..3889dae9 100644 --- a/src/deltix/util/swing/NonEmptyTextField.java +++ b/src/deltix/util/swing/NonEmptyTextField.java @@ -16,7 +16,7 @@ public class NonEmptyTextField extends ParsingTextField { /** * Constructs a NonEmptyTextField with the specified value and size. * - * @trim Whether to automatically trim the value. + * @param trim Whether to automatically trim the value. */ public NonEmptyTextField (String value, int columns, boolean trim) { super (value, columns); @@ -26,7 +26,7 @@ public NonEmptyTextField (String value, int columns, boolean trim) { /** * Constructs a NonEmptyTextField with the specified value. * - * @trim Whether to automatically trim the value. + * @param trim Whether to automatically trim the value. */ public NonEmptyTextField (String value, boolean trim) { super (value); @@ -36,7 +36,7 @@ public NonEmptyTextField (String value, boolean trim) { /** * Constructs a NonEmptyTextField with the specified size. * - * @trim Whether to automatically trim the value. + * @param trim Whether to automatically trim the value. */ public NonEmptyTextField (int columns, boolean trim) { super (columns); @@ -46,7 +46,7 @@ public NonEmptyTextField (int columns, boolean trim) { /** * Constructs a NonEmptyTextField. * - * @trim Whether to automatically trim the value. + * @param trim Whether to automatically trim the value. */ public NonEmptyTextField (boolean trim) { super (); From dfd6170496ff3a668ca1c16f0a3e232af60516cc Mon Sep 17 00:00:00 2001 From: gene Date: Tue, 30 Jan 2007 23:52:15 +0000 Subject: [PATCH 0052/2572] JAXB 2.0 is here --- ...plexer.java => DataSourceMultiplexer.java} | 4 ++-- ...a => DisposableDataSourceMultiplexer.java} | 4 ++-- .../xml/AbortingValidationEventHandler.java | 19 +++++++++++++++++++ 3 files changed, 23 insertions(+), 4 deletions(-) rename src/deltix/util/concurrent/{DataSourceDemultiplexer.java => DataSourceMultiplexer.java} (92%) rename src/deltix/util/concurrent/{DisposableDataSourceDemultiplexer.java => DisposableDataSourceMultiplexer.java} (76%) create mode 100644 src/deltix/util/xml/AbortingValidationEventHandler.java diff --git a/src/deltix/util/concurrent/DataSourceDemultiplexer.java b/src/deltix/util/concurrent/DataSourceMultiplexer.java similarity index 92% rename from src/deltix/util/concurrent/DataSourceDemultiplexer.java rename to src/deltix/util/concurrent/DataSourceMultiplexer.java index dc41534a..f1f1f835 100644 --- a/src/deltix/util/concurrent/DataSourceDemultiplexer.java +++ b/src/deltix/util/concurrent/DataSourceMultiplexer.java @@ -11,14 +11,14 @@ * be called concurrently, although the object itself is designed to manage * concurrent processes. */ -public class DataSourceDemultiplexer { +public class DataSourceMultiplexer { private Runnable mLock = new NotifyingRunnable (); private Set mDataSources = new HashSet (); - public DataSourceDemultiplexer () { + public DataSourceMultiplexer () { } public void add (T ds) { diff --git a/src/deltix/util/concurrent/DisposableDataSourceDemultiplexer.java b/src/deltix/util/concurrent/DisposableDataSourceMultiplexer.java similarity index 76% rename from src/deltix/util/concurrent/DisposableDataSourceDemultiplexer.java rename to src/deltix/util/concurrent/DisposableDataSourceMultiplexer.java index 657aba9c..38b4a104 100644 --- a/src/deltix/util/concurrent/DisposableDataSourceDemultiplexer.java +++ b/src/deltix/util/concurrent/DisposableDataSourceMultiplexer.java @@ -7,8 +7,8 @@ /** * */ -public class DisposableDataSourceDemultiplexer - extends DataSourceDemultiplexer +public class DisposableDataSourceMultiplexer + extends DataSourceMultiplexer implements Disposable { /** diff --git a/src/deltix/util/xml/AbortingValidationEventHandler.java b/src/deltix/util/xml/AbortingValidationEventHandler.java new file mode 100644 index 00000000..f71527fd --- /dev/null +++ b/src/deltix/util/xml/AbortingValidationEventHandler.java @@ -0,0 +1,19 @@ +package deltix.util.xml; + +import javax.xml.bind.*; + +/** + * Causes the Unmarshaller to throw an exception when it runs into + * trouble. + */ +public class AbortingValidationEventHandler implements ValidationEventHandler { + private AbortingValidationEventHandler () { + } + + public boolean handleEvent (ValidationEvent event) { + return (false); + } + + public static final ValidationEventHandler INSTANCE = + new AbortingValidationEventHandler (); +} From bb09f793c16772f427aa26079d424af719cce157 Mon Sep 17 00:00:00 2001 From: gene Date: Wed, 31 Jan 2007 23:15:07 +0000 Subject: [PATCH 0053/2572] --- src/deltix/util/time/AbsoluteDate.java | 12 +++++++----- src/deltix/{qsrv/pub => util/time}/AbstractDate.java | 2 +- 2 files changed, 8 insertions(+), 6 deletions(-) rename src/deltix/{qsrv/pub => util/time}/AbstractDate.java (88%) diff --git a/src/deltix/util/time/AbsoluteDate.java b/src/deltix/util/time/AbsoluteDate.java index 8386268d..1cd70ca5 100644 --- a/src/deltix/util/time/AbsoluteDate.java +++ b/src/deltix/util/time/AbsoluteDate.java @@ -6,7 +6,7 @@ /** * A bean holding an absolute (time- and time zone-unrelated) date. */ -public class AbsoluteDate implements Comparable { +public class AbsoluteDate implements AbstractDate, Comparable { public static final AbsoluteDate MIN_VALUE = new AbsoluteDate (0, 1, 1); public static final AbsoluteDate MAX_VALUE = new AbsoluteDate (Short.MAX_VALUE, 12, 31); @@ -132,9 +132,11 @@ public void set (String s) { StringTokenizer stk = new StringTokenizer (s, "-"); if (stk.countTokens () == 3) { - mYear = Short.parseShort (stk.nextToken ()); - mMonth = Byte.parseByte (stk.nextToken ()); - mDay = Byte.parseByte (stk.nextToken ()); + set ( + Short.parseShort (stk.nextToken ()), + Byte.parseByte (stk.nextToken ()), + Byte.parseByte (stk.nextToken ()) + ); } else throw new NumberFormatException ("Illegal AbsoluteDate: " + s); @@ -183,7 +185,7 @@ public boolean equals (Object other) { ); } - public int compareTo (AbsoluteDate o) { + public int compareTo (AbstractDate o) { int dif; dif = mYear - o.getYear (); diff --git a/src/deltix/qsrv/pub/AbstractDate.java b/src/deltix/util/time/AbstractDate.java similarity index 88% rename from src/deltix/qsrv/pub/AbstractDate.java rename to src/deltix/util/time/AbstractDate.java index ece68114..c34f039e 100644 --- a/src/deltix/qsrv/pub/AbstractDate.java +++ b/src/deltix/util/time/AbstractDate.java @@ -1,4 +1,4 @@ -package deltix.qsrv.pub; +package deltix.util.time; /** * A simple record containing a year, a month and a day of month. From 940aaa46e817169e0f4f1963b68936c47f2cf903 Mon Sep 17 00:00:00 2001 From: gene Date: Sat, 3 Feb 2007 17:13:12 +0000 Subject: [PATCH 0054/2572] --- src/deltix/util/GUID.java | 72 +++++++++++++++ .../concurrent/NotifyingAtomicInteger.java | 87 +++++++++++++++++++ 2 files changed, 159 insertions(+) create mode 100644 src/deltix/util/GUID.java create mode 100644 src/deltix/util/concurrent/NotifyingAtomicInteger.java diff --git a/src/deltix/util/GUID.java b/src/deltix/util/GUID.java new file mode 100644 index 00000000..6414f87e --- /dev/null +++ b/src/deltix/util/GUID.java @@ -0,0 +1,72 @@ +package deltix.util; + +import java.io.*; +import java.net.*; + +/** + * Globally unique identifier generator, based on the fact that on any system at any + * given time the same port cannot be bound to multiple sockets. Therefore, + * the port number of a socket combined with the local system time is unique + * within the host system. We add the IP address of the system to this and get + * an identifier that is globally unique, unless the clock is set back, or + * the system's IP address is non-unique within the scope of interest. + */ +public abstract class GUID { + /** + * Creates a string consisting of digits and underscore characters, suitable for + * use in language identifiers. This method does not throw checked exceptons. + */ + public static String createNoX () { + try { + return (create ()); + } catch (InterruptedException ix) { + throw new RuntimeException ("Unexpected " + ix, ix); + } catch (IOException iox) { + throw new RuntimeException ("Unexpected " + iox, iox); + } + } + /** + * Creates a string consisting of digits and underscore characters, suitable for + * use in language identifiers. + */ + public static String create () throws IOException, InterruptedException { + ServerSocket socket = new ServerSocket (); + InetAddress addr = InetAddress.getLocalHost (); + int port; + long time; + + try { + socket.bind (null); + // + // Sleep for 2 ticks to prevent the (extremely unlikely) situation + // where somebody else owned the port for a fraction of the previous tick. + // + Thread.sleep (2); + + // Get a time at which we definitely owned the socket ... + time = System.currentTimeMillis () - 1; + port = socket.getLocalPort (); + } finally { + socket.close (); + } + + StringBuilder s = new StringBuilder (); + + byte [] addressBytes = addr.getAddress (); + + for (byte b : addressBytes) { + s.append (((int) b) & 0xFF); + s.append ('_'); + } + + s.append (port); + s.append ('_'); + s.append (time - 1170522000000L); + + return (s.toString ()); + } + + public static void main (String [] args) throws Exception { + System.out.println (create ()); + } +} diff --git a/src/deltix/util/concurrent/NotifyingAtomicInteger.java b/src/deltix/util/concurrent/NotifyingAtomicInteger.java new file mode 100644 index 00000000..cd015623 --- /dev/null +++ b/src/deltix/util/concurrent/NotifyingAtomicInteger.java @@ -0,0 +1,87 @@ +package deltix.util.concurrent; + +import java.util.concurrent.atomic.AtomicInteger; + +/** + * A synchronized counter, which notifies subclasses when the value changes. + */ +public abstract class NotifyingAtomicInteger { + private int mValue; + + public NotifyingAtomicInteger (int initialValue) { + mValue = initialValue; + } + + /** + * Start as 0 + */ + public NotifyingAtomicInteger () { + this (0); + } + + public final int addAndGet (int n) { + int oldValue, newValue; + + synchronized (this) { + oldValue = mValue; + newValue = mValue = (mValue + n); + syncValueChanged (oldValue, newValue); + } + + valueChanged (oldValue, newValue); + + return (newValue); + } + + public final synchronized int getAndAdd (int n) { + int oldValue, newValue; + + synchronized (this) { + oldValue = mValue; + newValue = mValue = (mValue + n); + syncValueChanged (oldValue, newValue); + } + + valueChanged (oldValue, newValue); + + return (oldValue); + } + + /** + * Same as addAndGet (1) + */ + public final int incrementAndGet () { + return (addAndGet (1)); + } + + /** + * Same as addAndGet (-1) + */ + public final int decrementAndGet () { + return (addAndGet (-1)); + } + + /** + * Same as getAndAdd (1) + */ + public final int getAndIncrement () { + return (getAndAdd (1)); + } + + /** + * Same as getAndAdd (-1) + */ + public final int getAndDecrement () { + return (getAndAdd (-1)); + } + + public final synchronized int get () { + return (mValue); + } + + public void valueChanged (int oldValue, int newValue) { + } + + public void syncValueChanged (int oldValue, int newValue) { + } +} From c5727545c9882738f01c687e0392aa519e7385d3 Mon Sep 17 00:00:00 2001 From: gene Date: Sun, 4 Feb 2007 01:51:33 +0000 Subject: [PATCH 0055/2572] --- src/deltix/util/GUID.java | 25 ++++++++------ src/deltix/util/lang/AbstractClassLoader.java | 19 +++++++++++ .../util/lang/FileSystemClassLoader.java | 33 +++++++++++++++++++ .../util/lang/SingleByteArrayClassLoader.java | 21 ++++++++++++ 4 files changed, 88 insertions(+), 10 deletions(-) create mode 100644 src/deltix/util/lang/AbstractClassLoader.java create mode 100644 src/deltix/util/lang/FileSystemClassLoader.java create mode 100644 src/deltix/util/lang/SingleByteArrayClassLoader.java diff --git a/src/deltix/util/GUID.java b/src/deltix/util/GUID.java index 6414f87e..46a69a67 100644 --- a/src/deltix/util/GUID.java +++ b/src/deltix/util/GUID.java @@ -16,22 +16,24 @@ public abstract class GUID { * Creates a string consisting of digits and underscore characters, suitable for * use in language identifiers. This method does not throw checked exceptons. */ - public static String createNoX () { + public static String createNoX (boolean includeIPAddress) { try { - return (create ()); + return (create (includeIPAddress)); } catch (InterruptedException ix) { throw new RuntimeException ("Unexpected " + ix, ix); } catch (IOException iox) { throw new RuntimeException ("Unexpected " + iox, iox); } } + /** * Creates a string consisting of digits and underscore characters, suitable for * use in language identifiers. */ - public static String create () throws IOException, InterruptedException { + public static String create (boolean includeIPAddress) + throws IOException, InterruptedException + { ServerSocket socket = new ServerSocket (); - InetAddress addr = InetAddress.getLocalHost (); int port; long time; @@ -52,11 +54,14 @@ public static String create () throws IOException, InterruptedException { StringBuilder s = new StringBuilder (); - byte [] addressBytes = addr.getAddress (); - - for (byte b : addressBytes) { - s.append (((int) b) & 0xFF); - s.append ('_'); + if (includeIPAddress) { + InetAddress addr = InetAddress.getLocalHost (); + byte [] addressBytes = addr.getAddress (); + + for (byte b : addressBytes) { + s.append (((int) b) & 0xFF); + s.append ('_'); + } } s.append (port); @@ -67,6 +72,6 @@ public static String create () throws IOException, InterruptedException { } public static void main (String [] args) throws Exception { - System.out.println (create ()); + System.out.println (create (true)); } } diff --git a/src/deltix/util/lang/AbstractClassLoader.java b/src/deltix/util/lang/AbstractClassLoader.java new file mode 100644 index 00000000..2b78ee5a --- /dev/null +++ b/src/deltix/util/lang/AbstractClassLoader.java @@ -0,0 +1,19 @@ +package deltix.util.lang; + +import java.io.*; + +/** + * Trivial utility class which adapts the ClassLoader base class to + * the simple paradigm of byte [] loadClassBytes (String name) + */ +public abstract class AbstractClassLoader extends ClassLoader { + protected abstract byte [] loadClassBytes (String name) + throws ClassNotFoundException; + + protected Class findClass (String name) + throws ClassNotFoundException + { + byte [] b = loadClassBytes (name); + return (defineClass (name, b, 0, b.length)); + } +} diff --git a/src/deltix/util/lang/FileSystemClassLoader.java b/src/deltix/util/lang/FileSystemClassLoader.java new file mode 100644 index 00000000..dc2c4972 --- /dev/null +++ b/src/deltix/util/lang/FileSystemClassLoader.java @@ -0,0 +1,33 @@ +package deltix.util.lang; + +import deltix.util.io.IOUtil; +import java.io.*; + +/** + * UNTESTED + */ +public class FileSystemClassLoader extends AbstractClassLoader { + private File mClassDir; + + public FileSystemClassLoader (File rootDir) { + mClassDir = rootDir; + } + + protected byte [] loadClassBytes (String name) + throws ClassNotFoundException + { + File classFile = new File (mClassDir, name.replace (".", "/") + ".class"); + + if (!classFile.exists ()) + throw new ClassNotFoundException ("File for class " + name + " not found in " + mClassDir); + + try { + return (IOUtil.readBytes (classFile)); + } catch (IOException iox) { + throw new ClassNotFoundException ( + "Failed to read file: " + classFile + " due to: " + iox, + iox + ); + } + } +} diff --git a/src/deltix/util/lang/SingleByteArrayClassLoader.java b/src/deltix/util/lang/SingleByteArrayClassLoader.java new file mode 100644 index 00000000..99d69efa --- /dev/null +++ b/src/deltix/util/lang/SingleByteArrayClassLoader.java @@ -0,0 +1,21 @@ +package deltix.util.lang; + +/** + * Loads a single specified class from the supplied byte array. + */ +public class SingleByteArrayClassLoader extends AbstractClassLoader { + private String mClassName; + private byte [] mBytes; + + public SingleByteArrayClassLoader (String className, byte [] bytes) { + mClassName = className; + mBytes = bytes; + } + + protected byte [] loadClassBytes (String name) throws ClassNotFoundException { + if (!name.equals (mClassName)) + throw new ClassNotFoundException (name); + + return (mBytes); + } +} From 70cd82e716aebbb8f8e25ad98bacdeed3ed17f14 Mon Sep 17 00:00:00 2001 From: gene Date: Sun, 4 Feb 2007 18:57:36 +0000 Subject: [PATCH 0056/2572] --- src/deltix/util/io/IOUtil.java | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/deltix/util/io/IOUtil.java b/src/deltix/util/io/IOUtil.java index dce36052..e7700ec3 100644 --- a/src/deltix/util/io/IOUtil.java +++ b/src/deltix/util/io/IOUtil.java @@ -317,10 +317,20 @@ public static String readFromReader (Reader r) public static void writeTextFile (String filepath, String content) throws IOException { - FileWriter fw = new FileWriter (filepath); + writeTextFile (new File (filepath), content); + } + + public static void writeTextFile (File f, String content) + throws IOException + { + FileWriter fw = new FileWriter (f); - fw.write(content); - fw.close (); + try { + fw.write (content); + fw.close (); + } finally { + Util.close (fw); + } } public static void writeBytes ( From 19625efee8a84d255edc56a3f36ad656011f5f21 Mon Sep 17 00:00:00 2001 From: gene Date: Tue, 6 Feb 2007 18:26:51 +0000 Subject: [PATCH 0057/2572] --- src/deltix/util/io/IOUtil.java | 57 ++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/src/deltix/util/io/IOUtil.java b/src/deltix/util/io/IOUtil.java index e7700ec3..f30d47bd 100644 --- a/src/deltix/util/io/IOUtil.java +++ b/src/deltix/util/io/IOUtil.java @@ -864,4 +864,61 @@ public boolean accept(File pathname) return pathname.isFile (); } } + + /** + * Writes any CharSequence to DataOutput in a way identical to + * DataOutputStream.writeUTF, which is groundlessly defined too narrowly + * by forcing the argument to be a String. + */ + public static int writeUTF (CharSequence str, DataOutput out) throws IOException { + int strlen = str.length(); + int utflen = 0; + int c, count = 0; + + /* use charAt instead of copying String to char array */ + for (int i = 0; i < strlen; i++) { + c = str.charAt(i); + if ((c >= 0x0001) && (c <= 0x007F)) { + utflen++; + } else if (c > 0x07FF) { + utflen += 3; + } else { + utflen += 2; + } + } + + if (utflen > 65535) + throw new UTFDataFormatException( + "encoded string too long: " + utflen + " bytes"); + + out.writeByte ((utflen >>> 8) & 0xFF); + out.writeByte ((utflen >>> 0) & 0xFF); + + + int i=0; + for (i=0; i= 0x0001) && (c <= 0x007F))) break; + out.writeByte (c); + } + + for (;i < strlen; i++){ + c = str.charAt(i); + + if ((c >= 0x0001) && (c <= 0x007F)) + out.writeByte (c); + else if (c > 0x07FF) { + out.writeByte (0xE0 | ((c >> 12) & 0x0F)); + out.writeByte (0x80 | ((c >> 6) & 0x3F)); + out.writeByte (0x80 | ((c >> 0) & 0x3F)); + } + else { + out.writeByte (0xC0 | ((c >> 6) & 0x1F)); + out.writeByte (0x80 | ((c >> 0) & 0x3F)); + } + } + + return utflen + 2; + } + } From e8dc6fc036e7eccae3cf872fb9f11d161808cb79 Mon Sep 17 00:00:00 2001 From: gene Date: Tue, 6 Feb 2007 19:45:39 +0000 Subject: [PATCH 0058/2572] --- src/deltix/util/swing/AbstractApp.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/deltix/util/swing/AbstractApp.java b/src/deltix/util/swing/AbstractApp.java index 12d51b2f..52f26eb5 100644 --- a/src/deltix/util/swing/AbstractApp.java +++ b/src/deltix/util/swing/AbstractApp.java @@ -28,6 +28,22 @@ public void windowClosing (WindowEvent e) { protected void windowClosing (WindowEvent e) { } + /** + * Ask the user if he wants to exit, and call System.exit (0) if so. + */ + public void confirmSystemExit (String title, String msg) { + int ret = + JOptionPane.showConfirmDialog ( + this, + msg, + title, + JOptionPane.YES_NO_OPTION + ); + + if (ret == JOptionPane.YES_OPTION) + System.exit (0); + } + public void handle (Throwable x) { handle (x, Level.SEVERE); } From aa6f9ae55a90b60d5f7bb26ef5c6208ff016e149 Mon Sep 17 00:00:00 2001 From: gene Date: Tue, 6 Feb 2007 23:23:46 +0000 Subject: [PATCH 0059/2572] --- src/deltix/qsrv/ui/query/addSelector.gif | Bin 0 -> 951 bytes src/deltix/qsrv/ui/util/Icons.java | 30 +++++++++++++++++++++++ src/deltix/qsrv/ui/util/boolean.gif | Bin 0 -> 565 bytes src/deltix/qsrv/ui/util/number.gif | Bin 0 -> 1006 bytes src/deltix/qsrv/ui/util/text.gif | Bin 0 -> 962 bytes 5 files changed, 30 insertions(+) create mode 100644 src/deltix/qsrv/ui/query/addSelector.gif create mode 100644 src/deltix/qsrv/ui/util/Icons.java create mode 100644 src/deltix/qsrv/ui/util/boolean.gif create mode 100644 src/deltix/qsrv/ui/util/number.gif create mode 100644 src/deltix/qsrv/ui/util/text.gif diff --git a/src/deltix/qsrv/ui/query/addSelector.gif b/src/deltix/qsrv/ui/query/addSelector.gif new file mode 100644 index 0000000000000000000000000000000000000000..3181d6ec1f02c16f6a0d8ca84d0cfcde0d95c5ec GIT binary patch literal 951 zcmYjQZAepL6h6DHyCsSs3D~#QK{jNK^m#kq;=k@H}y0>^PZ}A`{sT>e>btWT!_lMQzdwAb$Z9AeD40w zfk5Dx&6Q$q7kWm|Hg@&C|IS_Nh%Io8eDPV@UdnPCZghGJ8oPcitYlqvJr+mi14_G} z0WWIz9|nf;1Yp6nXyo-_Ecllh;Lxr^CA9z?XzhB~gq9BLhvr*(!bAMfCB&yqLOli0 zx7fPfFfPJa+Jcc+?q)%W{RZcaeBOq5v`G!x zwfLBXg=x%dFs4LZ7sAz!n67FEKN~q23^N$3MjVa1i24DGqx2VpS6oC?R{$-M3VIsI602=)EWd3Wo7o;cIkMP^8^GiVvO0-vd6Wo8%ebT`L z344}cX3z;#NW9j#?BECd~xzma8d`vOBH&zz=eo3(TZ+N+qTm( zt>EG6s8Gdzg;rGiCM-f@W?DSdW=Twfp;tfa>7(fr_EP6aoJbs-Tvj>ezTa<)t5wPU zoUIn*_FZoH##uwCD3gw>uu_j`XQA*S<+ZgbCdtquQ_s{$B~Mg|!*18W(})iiHubWS T0z*b_e(@Q~x+Psgiy`$N1OYd4 literal 0 HcmV?d00001 diff --git a/src/deltix/qsrv/ui/util/Icons.java b/src/deltix/qsrv/ui/util/Icons.java new file mode 100644 index 00000000..9c599876 --- /dev/null +++ b/src/deltix/qsrv/ui/util/Icons.java @@ -0,0 +1,30 @@ +package deltix.qsrv.ui.util; + +import deltix.util.swing.SwingUtil; +import javax.swing.Icon; + +/** + * + */ +public class Icons { + public static final Icon BOOLEAN = + SwingUtil.loadIcon ("deltix/qsrv/ui/util/boolean.gif"); + + public static final Icon DATE = + SwingUtil.loadIcon ("deltix/qsrv/ui/util/date.gif"); + + public static final Icon NUMBER = + SwingUtil.loadIcon ("deltix/qsrv/ui/util/number.gif"); + + public static final Icon TEXT = + SwingUtil.loadIcon ("deltix/qsrv/ui/util/text.gif"); + + public static final Icon FOLDER = + SwingUtil.loadIcon ("deltix/qsrv/ui/util/folder.gif"); + + public static final Icon DB = + SwingUtil.loadIcon ("deltix/qsrv/ui/util/db.gif"); + + public static final Icon NEW = + SwingUtil.loadIcon ("deltix/qsrv/ui/util/new.gif"); +} diff --git a/src/deltix/qsrv/ui/util/boolean.gif b/src/deltix/qsrv/ui/util/boolean.gif new file mode 100644 index 0000000000000000000000000000000000000000..4325bba854f2686b6c2cd908f176e6bcca4690ae GIT binary patch literal 565 zcmZ?wbhEHb6krfwc*el+|NsB5U%$S8|9|PWb8}W5`~La=lx2I@?z^^j*STx=-!I*C z%+fd8E4F&dqGMYR-+{#&&s~4M_w>E3hp%0`{y!?W$1AnPDYCd{-TR=-7N^2v zhOukUo&W#-{r5TB-e0@@e9F3OPPxaDE2jiio}07o*qm+OkDb5gmAkgMYww&@d(U0I z*R$$-^`xaOtDalNE?s;0yI0{cMb9Zth3BG5*S1VMS3K*vSLr#+(ClNEpL^Bbdw&0a zRAJA(=kJpzeeYTJJh=;K_*Ton?5MVD3_}wr{$ybUxm*WCfZ~LKeNqEMQ*%pe6Q3|U zJ2Mvx3mY4ME1$Kfq!^F5Ik%2btFS2JqQ#6H^IF&?mn>#iYvmAI&C1Gb(aOxTnu&>7 zu$4=E$!;qy`6hh>1{TM~yG2A)I2q&=n>4u>ZQd=z%PAq%%%;S_u~$K>UqYF;nO{J_ pMpji@m($K(qpexb($>_;;ftVEqVqAf#@4hW3mP{pT;RZ94FF+?tpWf5 literal 0 HcmV?d00001 diff --git a/src/deltix/qsrv/ui/util/number.gif b/src/deltix/qsrv/ui/util/number.gif new file mode 100644 index 0000000000000000000000000000000000000000..7b0b222be25d57c77f65444ba3afdf2ac55975ae GIT binary patch literal 1006 zcmXAoL5LP~5XGMu;i2M-cJD5X7n8_~1%ei|=_IufOc#qtyaY~Ghe*Pd4xJQXgf0t) zR0KnxRM-#%d0B*|n-wH;kT58TAR?3Xt6u*v|A*m!dc1kRH~aL-M<01;8RHBFm+R%ySPy!81kaJ0xAO#eGh>4^KMImaU zDN1pOn|O*-0um;X5|o0JNu?B}A#Ktr&EZaH!W43D6Q)Q7RiI)jsX|q#nrf<29qOi@ z>ePUSX`}|Vpk-RAMQv!Cc4~8MtTbgRIbR*-NC#cuVlL@ISGbyMy3!r)=AQ2KfQNac z2fg5BUg_)eBXE#TKn%2xF z=T(9cIa)Q!L@`Q^1`P02qvoJBAkmGUBiRus!x%YI7|XMamBaBc$~JZm^&v_cnd7&# zao7Jhuwy>wH}Tk(Z}88??Bn0A?Rw|#OZPAQa&&c%^50FEY(4*x+;?;F;?1KkJ~51J zTY7x${XM5|A6`E7rLSIip&mZ>_s?gpKXqoOAN%&!$_Kkv7d9W6{q^+W%g1M1U)lWX z?>+UME4Pn)_wN3X{TB{xTl)Um%E7(U8=o&f_v15X`N{P8m)D^*s#V)8oziyg96gK6wArdCcP<{QnF{ zfDk|ok`O`xHE2Q!2i)KZCjtmVB!VcQ43#LNfi`raIg~&H6XYZb6QqD55HXPyp(sR6 zG({;6aT8B*NF#!6GBlGExiM>^;N7jsD$y2905)0OUUH}`a>2RzIp zJ?I55^GYvz!`r;mnY7LgH*LX<^i z6r&Ms(HYG_CTPJ7azX?vWPv3pv63udDN3z0OIeO`E6;LPpu#G$f>o%ps;pu)s;xS! zIcOKHm_<(5VU29C1ufQ+Eo?=rwPq{Z(QfV8&JJ`~M|Q9aUDlOd>_)eBXE#TKn%2xF zrz*jS9IYBFpjOAIz%HenzWg9z(`Vb|J%<+5U z>CAsOuy2~vO)Sq{!L66iXTSa7=X0B8w|)N3SLlMe|_{iR{7xK+>swKcYfoS zOD}%?ZU)vMLzdhTrXYaw|i%TyTv3z>v(qbRGbLP+Q z*RCB|J-2V?qbv7r9DVJJh1**nEnm2Qb^nW7Z{d^Ur)D2-S*g44o?oxCH{W}E^8?>- fXRqzteCou7lWTwce);e9`_~UHyt#YVJU;vv(d5aB literal 0 HcmV?d00001 From d13ab413123acac54489562b0e3907a9618ccfff Mon Sep 17 00:00:00 2001 From: gene Date: Wed, 7 Feb 2007 20:24:22 +0000 Subject: [PATCH 0060/2572] --- src/deltix/util/io/IOUtil.java | 76 ++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/src/deltix/util/io/IOUtil.java b/src/deltix/util/io/IOUtil.java index f30d47bd..60df31aa 100644 --- a/src/deltix/util/io/IOUtil.java +++ b/src/deltix/util/io/IOUtil.java @@ -921,4 +921,80 @@ else if (c > 0x07FF) { return utflen + 2; } + /** + * Reads (appends) a UTF string to a StringBuilder, without clearing it first. + */ + public final static void readUTF(DataInput in, StringBuilder sb) throws IOException { + int utflen = in.readUnsignedShort(); + + if (utflen == 0) + return; + + int c = -2; + int char2, char3; + int count = 0; + + for (;;) { + c = in.readByte (); + if (c > 127) + break; + + count++; + sb.append ((char) c); + + if (count >= utflen) + return; + } + // If we are here, we have broken out of the previous loop and there is an + // unhandled escape character in variable c. + for (;;) { + switch (c >> 4) { + case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: + /* 0xxxxxxx*/ + count++; + sb.append ((char)c); + break; + + case 12: case 13: + /* 110x xxxx 10xx xxxx*/ + count += 2; + if (count > utflen) + throw new UTFDataFormatException( + "malformed input: partial character at end"); + char2 = in.readByte (); + if ((char2 & 0xC0) != 0x80) + throw new UTFDataFormatException( + "malformed input around byte " + count); + sb.append ((char)(((c & 0x1F) << 6) | + (char2 & 0x3F))); + break; + + case 14: + /* 1110 xxxx 10xx xxxx 10xx xxxx */ + count += 3; + if (count > utflen) + throw new UTFDataFormatException( + "malformed input: partial character at end"); + char2 = in.readByte (); + char3 = in.readByte (); + if (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80)) + throw new UTFDataFormatException( + "malformed input around byte " + (count-1)); + sb.append ((char)(((c & 0x0F) << 12) | + ((char2 & 0x3F) << 6) | + ((char3 & 0x3F) << 0))); + break; + + default: + /* 10xx xxxx, 1111 xxxx */ + throw new UTFDataFormatException( + "malformed input around byte " + count); + } + + if (count >= utflen) + break; + + c = in.readByte (); + } + } } From 35ab1e6339ea6bdb904a2ac6f6566970286d2a03 Mon Sep 17 00:00:00 2001 From: gene Date: Thu, 8 Feb 2007 19:36:30 +0000 Subject: [PATCH 0061/2572] --- src/deltix/qsrv/ui/util/Icons.java | 6 ++++++ .../{query/addSelector.gif => util/plus.gif} | Bin src/deltix/qsrv/ui/util/trash.gif | Bin 0 -> 217 bytes src/deltix/util/swing/StandardAction.java | 20 ++++++++++++------ src/deltix/util/swing/SwingUtil.java | 8 +++++++ src/deltix/util/swing/VerticalForm.java | 3 ++- 6 files changed, 30 insertions(+), 7 deletions(-) rename src/deltix/qsrv/ui/{query/addSelector.gif => util/plus.gif} (100%) create mode 100644 src/deltix/qsrv/ui/util/trash.gif diff --git a/src/deltix/qsrv/ui/util/Icons.java b/src/deltix/qsrv/ui/util/Icons.java index 9c599876..9ad1e079 100644 --- a/src/deltix/qsrv/ui/util/Icons.java +++ b/src/deltix/qsrv/ui/util/Icons.java @@ -27,4 +27,10 @@ public class Icons { public static final Icon NEW = SwingUtil.loadIcon ("deltix/qsrv/ui/util/new.gif"); + + public static final Icon TRASH = + SwingUtil.loadIcon ("deltix/qsrv/ui/util/trash.gif"); + + public static final Icon PLUS = + SwingUtil.loadIcon ("deltix/qsrv/ui/util/plus.gif"); } diff --git a/src/deltix/qsrv/ui/query/addSelector.gif b/src/deltix/qsrv/ui/util/plus.gif similarity index 100% rename from src/deltix/qsrv/ui/query/addSelector.gif rename to src/deltix/qsrv/ui/util/plus.gif diff --git a/src/deltix/qsrv/ui/util/trash.gif b/src/deltix/qsrv/ui/util/trash.gif new file mode 100644 index 0000000000000000000000000000000000000000..2b5ea4178b7edb1affc367adc5bb5a1b03c3d3c9 GIT binary patch literal 217 zcmZ?wbhEHb6krfwI3mF?b<*4edrr=oxn$|WwYiz)E0=9rw|e`&UB`ECKfHbOfu4?O z&Go%gCd`{NV_9{1>x`)ji}Pz2&0Dj1{q6;GS1wUK%U7T7#f7mwq5>M;}DtSxyVI| z=jb6u#gHhSuBV&c#;se?J *
  • Figures out the package name of the specified class. - *
  • Loads the icon image from this package's resource path, - * where the icon name is same as the nameKey argument; - * extension imageType. *
  • The action name is retrieved from the resource bundle * called actions, under the same package, under the key of * nameKey. *
  • The tooltip text is retrieved from the resource bundle * called actions, under the same package, under the key of * nameKey.tt. + *
  • Loads the icon image from this package's resource path, + * where the icon name is same as the nameKey argument; + * extension imageType, unless the actions + * resource bundle contains a key called nameKey.tt, + * in which case the value of that key is used as the icon resource path. * * * @param nameKey Used to look up the action properties. @@ -57,11 +59,17 @@ public StandardAction (Class forClass, String nameKey, String imageType) { putValue (SHORT_DESCRIPTION, rb.getString (nameKey + ".tt")); + String imageResourcePath = null; + + try { + imageResourcePath = rb.getString (nameKey + ".img"); + } catch (MissingResourceException x) { + imageResourcePath = packPath + "/" + nameKey + "." + imageType; + } + putValue ( SMALL_ICON, - SwingUtil.loadIcon ( - packPath + "/" + nameKey + "." + imageType - ) + SwingUtil.loadIcon (imageResourcePath) ); // kbd accelerator (hot key) diff --git a/src/deltix/util/swing/SwingUtil.java b/src/deltix/util/swing/SwingUtil.java index cc0ff1f4..a1cb4ee3 100644 --- a/src/deltix/util/swing/SwingUtil.java +++ b/src/deltix/util/swing/SwingUtil.java @@ -198,4 +198,12 @@ public static void setWindowsLookAndFeel () { } catch (Throwable e) { } } + + public static JButton newZeroMarginButton (Action action) { + JButton btn = new JButton (action); + + btn.setMargin (new Insets (0, 0, 0, 0)); + + return (btn); + } } diff --git a/src/deltix/util/swing/VerticalForm.java b/src/deltix/util/swing/VerticalForm.java index c7ea3cf4..a27c3f10 100644 --- a/src/deltix/util/swing/VerticalForm.java +++ b/src/deltix/util/swing/VerticalForm.java @@ -57,7 +57,8 @@ public void addSpring (double weighty) { private void setWeightAndFill (JComponent comp) { if (comp instanceof JTextArea || - comp instanceof JScrollPane) + comp instanceof JScrollPane || + comp instanceof JTabbedPane) { mC.weightx = 1; mC.weighty = 1; From 812afa8e16fc26dc2b6f94751e1a5ac5d9de7342 Mon Sep 17 00:00:00 2001 From: gene Date: Fri, 9 Feb 2007 15:28:03 +0000 Subject: [PATCH 0062/2572] selectEntities works --- src/deltix/util/Util.java | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/deltix/util/Util.java b/src/deltix/util/Util.java index b52d9568..8b5b9d46 100644 --- a/src/deltix/util/Util.java +++ b/src/deltix/util/Util.java @@ -17,6 +17,43 @@ public class Util { public static final String LOGGER_NAME = "deltix.util"; public static final Logger LOGGER = Logger.getLogger (LOGGER_NAME); + /** + * Compare two CharSequences. A null argument is always less than a non-null argument + * and is equal to another null argument. + * + * @param fast When true, use a fast algorithm, which makes a + * char sequence greater than another if it is longer. + * When false, performs lexicographic comparison. + */ + public static int compare (CharSequence s1, CharSequence s2, boolean fast) { + if (s1 == null) + if (s2 == null) + return (0); + else + return (-1); + else if (s2 == null) + return (1); + else { + int len1 = s1.length (); + int len2 = s2.length (); + int diff = len1 - len2; + + if (fast && diff != 0) + return (diff); + + int minLength = diff > 0 ? len2 : len1; + + for (int ii = 0; ii < minLength; ii++) { + int cdiff = s1.charAt (ii) - s2.charAt (ii); + + if (cdiff != 0) + return (cdiff); + } + + return (diff); + } + } + public static > T max (T a, T b) { if (a == null) return (b); From 05556d0f0c8b50b718ae2e53e97ef12b338e6076 Mon Sep 17 00:00:00 2001 From: gene Date: Fri, 9 Feb 2007 21:31:38 +0000 Subject: [PATCH 0063/2572] --- src/deltix/util/lang/FileSystemClassLoader.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/deltix/util/lang/FileSystemClassLoader.java b/src/deltix/util/lang/FileSystemClassLoader.java index dc2c4972..2345cae8 100644 --- a/src/deltix/util/lang/FileSystemClassLoader.java +++ b/src/deltix/util/lang/FileSystemClassLoader.java @@ -16,6 +16,8 @@ public FileSystemClassLoader (File rootDir) { protected byte [] loadClassBytes (String name) throws ClassNotFoundException { + System.out.println ("loadClassBytes " + name); + File classFile = new File (mClassDir, name.replace (".", "/") + ".class"); if (!classFile.exists ()) From 8703854b7689f1bfa31406c4eb89ae49cc7a4ebd Mon Sep 17 00:00:00 2001 From: gene Date: Sat, 10 Feb 2007 15:36:41 +0000 Subject: [PATCH 0064/2572] --- src/deltix/util/Util.java | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/deltix/util/Util.java b/src/deltix/util/Util.java index 8b5b9d46..63f16196 100644 --- a/src/deltix/util/Util.java +++ b/src/deltix/util/Util.java @@ -17,6 +17,35 @@ public class Util { public static final String LOGGER_NAME = "deltix.util"; public static final Logger LOGGER = Logger.getLogger (LOGGER_NAME); + /** + * Returns the sign of a - b + */ + public static int compare (long a, long b) { + long diff = a - b; + + if (diff < 0) + return (-1); + + if (diff > 0) + return (1); + + return (0); + } + + /** + * Returns the sign of a - b + */ + public static int compare (double a, double b) { + double diff = a - b; + + if (diff < 0) + return (-1); + + if (diff > 0) + return (1); + + return (0); + } /** * Compare two CharSequences. A null argument is always less than a non-null argument * and is equal to another null argument. From a9bd5c0013148e6a52d68d7ef99c55bcf2da2671 Mon Sep 17 00:00:00 2001 From: gene Date: Thu, 15 Feb 2007 13:42:17 +0000 Subject: [PATCH 0065/2572] --- src/deltix/util/jdbc/Script.java | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/deltix/util/jdbc/Script.java b/src/deltix/util/jdbc/Script.java index bd132eb1..4cad98b1 100644 --- a/src/deltix/util/jdbc/Script.java +++ b/src/deltix/util/jdbc/Script.java @@ -17,6 +17,7 @@ public class Script { private static final int OUTSIDE = 1; private static final int PLSQL = 2; private static final int DDL = 3; + private static final int COMMENT = 4; private List mStatements = new ArrayList (); @@ -61,7 +62,25 @@ public void read (Reader rd) throws IOException { if (test.startsWith ("--")) continue; - if (state == OUTSIDE) { + if (state == OUTSIDE && test.startsWith ("/*")) + state = COMMENT; + + if (state == COMMENT) { + int end = test.indexOf ("*/"); + + if (end != -1) { + state = OUTSIDE; + + test = test.substring (end + 2).trim (); + + if (test.length () == 0) + continue; + } + else + continue; + } + + if (state == OUTSIDE) { // // Test for exit statement. // From 3cd9baceb0549254737c106b2a5a99fbbbed9014 Mon Sep 17 00:00:00 2001 From: gene Date: Mon, 19 Feb 2007 22:30:38 +0000 Subject: [PATCH 0066/2572] --- .../concurrent/AsynchronousDataSource.java | 31 +++++++++---------- .../concurrent/DataSourceMultiplexer.java | 8 ++--- 2 files changed, 18 insertions(+), 21 deletions(-) diff --git a/src/deltix/util/concurrent/AsynchronousDataSource.java b/src/deltix/util/concurrent/AsynchronousDataSource.java index a0de7e60..d0077d0a 100644 --- a/src/deltix/util/concurrent/AsynchronousDataSource.java +++ b/src/deltix/util/concurrent/AsynchronousDataSource.java @@ -1,7 +1,9 @@ package deltix.util.concurrent; /** - * An abstract source of data. + * An abstract source of data, allowing a single consumer to + * perform work while the data is not available, or to multiplex + * multiple data sources. */ public interface AsynchronousDataSource { /** @@ -10,26 +12,23 @@ public interface AsynchronousDataSource { * @param timeout Maximum time to wait until data is available, * in milliseconds. The value of 0 causes a non-blocking * check to be performed. + * @param listener If specified, and if this method returned false, then + * the listener will be notified (once) when data becomes available. + * Implementations of this class only support + * a single listener. * @return True if data is available, false if timeout has expired. */ - public boolean isDataAvailable (long timeout) + public boolean isDataAvailable (long timeout, Runnable listener) throws InterruptedException; /** - * Performs a non-blocking check for data availability. + * Performs a non-blocking check for data availability. * - * @return True if data is available, false if not. - */ - public boolean isDataAvailable (); - - /** - * Adds Runnable to be notified of data availability + * @param listener If specified, and if this method returned false, then + * the listener will be notified (once) when data becomes available. + * Implementations of this class only support + * a single listener. + * @return If data is available. */ - public void addNotificationListener (Runnable l); - - /** - * Removes a Runnable previously registered with {@link #addNotificationListener} - */ - public void removeNotificationListener (Runnable l); - + public boolean isDataAvailable (Runnable listener); } diff --git a/src/deltix/util/concurrent/DataSourceMultiplexer.java b/src/deltix/util/concurrent/DataSourceMultiplexer.java index f1f1f835..fd40b133 100644 --- a/src/deltix/util/concurrent/DataSourceMultiplexer.java +++ b/src/deltix/util/concurrent/DataSourceMultiplexer.java @@ -22,13 +22,11 @@ public DataSourceMultiplexer () { } public void add (T ds) { - if (mDataSources.add (ds)) - ds.addNotificationListener (mLock); + mDataSources.add (ds); } public void remove (T ds) { - if (mDataSources.remove (ds)) - ds.removeNotificationListener (mLock); + mDataSources.remove (ds); } /** @@ -47,7 +45,7 @@ public int getNumDataSources () { */ public T getSourceWithAvailableDataNoBlocking () { for (T ds : mDataSources) - if (ds.isDataAvailable ()) + if (ds.isDataAvailable (mLock)) return (ds); return (null); From 3cdb7eba51b72da8715d7ea0cd83a205dc53b889 Mon Sep 17 00:00:00 2001 From: gene Date: Tue, 20 Feb 2007 21:45:03 +0000 Subject: [PATCH 0067/2572] --- src/deltix/util/Util.java | 48 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/src/deltix/util/Util.java b/src/deltix/util/Util.java index 63f16196..1ec615d2 100644 --- a/src/deltix/util/Util.java +++ b/src/deltix/util/Util.java @@ -967,6 +967,54 @@ public static int indexOf (Object [] array, Object elem) { return (-1); } + /** + * Find the index of the minimum element. Returns -1 if array is empty. + */ + public static int indexOfMinMax (T [] array, Comparator comp, int order) { + int len = arraylen (array); + + if (len == 0) + return (-1); + + int idx = 0; + T minmax = array [0]; + + for (int ii = 1; ii < len; ii++) { + T cur = array [ii]; + + if (comp.compare (cur, minmax) * order > 0) { + minmax = cur; + idx = ii; + } + } + + return (idx); + } + + /** + * Find the index of the minimum element. Returns -1 if array is empty. + */ + public static > int indexOfMinMax (T [] array, int order) { + int len = arraylen (array); + + if (len == 0) + return (-1); + + int idx = 0; + T minmax = array [0]; + + for (int ii = 1; ii < len; ii++) { + T cur = array [ii]; + + if (cur.compareTo (minmax) * order > 0) { + minmax = cur; + idx = ii; + } + } + + return (idx); + } + public static void format ( StringBuffer out, Object obj, From 408801486e517eee0f8db5addcc7b1cea27f1834 Mon Sep 17 00:00:00 2001 From: gene Date: Thu, 22 Feb 2007 19:59:37 +0000 Subject: [PATCH 0068/2572] --- .../util/collections/ArrayIterator.java | 27 +++++++++ src/deltix/util/collections/Sets.java | 26 +++++++++ .../util/collections/SingleElementSet.java | 58 +++++++++++++++++++ 3 files changed, 111 insertions(+) create mode 100644 src/deltix/util/collections/ArrayIterator.java create mode 100644 src/deltix/util/collections/Sets.java create mode 100644 src/deltix/util/collections/SingleElementSet.java diff --git a/src/deltix/util/collections/ArrayIterator.java b/src/deltix/util/collections/ArrayIterator.java new file mode 100644 index 00000000..0876f815 --- /dev/null +++ b/src/deltix/util/collections/ArrayIterator.java @@ -0,0 +1,27 @@ +package deltix.util.collections; + +import java.util.*; + +/** + * + */ +public class ArrayIterator implements Iterator { + private T [] mArray; + private int mIdx = 0; + + public ArrayIterator (T ... array) { + mArray = array; + } + + public void remove () { + throw new UnsupportedOperationException (); + } + + public T next () { + return (mArray [mIdx++]); + } + + public boolean hasNext () { + return (mIdx < mArray.length); + } +} diff --git a/src/deltix/util/collections/Sets.java b/src/deltix/util/collections/Sets.java new file mode 100644 index 00000000..1479d82e --- /dev/null +++ b/src/deltix/util/collections/Sets.java @@ -0,0 +1,26 @@ +package deltix.util.collections; + +import java.util.*; + +/** + * + */ +public class Sets { + public static int getUnionSize (Set a, Set b) { + int sizeA = a.size (); + int sizeB = b.size (); + + if (sizeA < sizeB) { + for (Object p : a) + if (b.contains (p)) + sizeB--; + } + else { + for (Object p : b) + if (a.contains (p)) + sizeA--; + } + + return (sizeA + sizeB); + } +} diff --git a/src/deltix/util/collections/SingleElementSet.java b/src/deltix/util/collections/SingleElementSet.java new file mode 100644 index 00000000..759edf2f --- /dev/null +++ b/src/deltix/util/collections/SingleElementSet.java @@ -0,0 +1,58 @@ +package deltix.util.collections; + +import java.util.*; + +/** + * A read-only set consisting of a single fixed element. + */ +public class SingleElementSet + extends AbstractSet + implements Set +{ + private T mElement; + + public SingleElementSet (T elem) { + mElement = elem; + } + + public boolean contains (Object o) { + return (mElement.equals (o)); + } + + public int size () { + return (1); + } + + public boolean isEmpty () { + return (false); + } + + @SuppressWarnings ("unchecked") + public Iterator iterator () { + return (new ArrayIterator (mElement)); + } + + public boolean remove (Object o) { + throw new UnsupportedOperationException (); + } + + public boolean addAll (Collection c) { + throw new UnsupportedOperationException (); + } + + public boolean removeAll (Collection c) { + throw new UnsupportedOperationException (); + } + + public boolean retainAll (Collection c) { + throw new UnsupportedOperationException (); + } + + public boolean add (T o) { + throw new UnsupportedOperationException (); + } + + public void clear () { + throw new UnsupportedOperationException (); + } +} From c87ad521e3877a206c7c5b4b685820fc6f71a049 Mon Sep 17 00:00:00 2001 From: gene Date: Fri, 23 Feb 2007 15:26:59 +0000 Subject: [PATCH 0069/2572] --- src/deltix/util/lang/AbstractClassLoader.java | 2 +- src/deltix/util/lang/FileSystemClassLoader.java | 13 ++++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/deltix/util/lang/AbstractClassLoader.java b/src/deltix/util/lang/AbstractClassLoader.java index 2b78ee5a..b80638f6 100644 --- a/src/deltix/util/lang/AbstractClassLoader.java +++ b/src/deltix/util/lang/AbstractClassLoader.java @@ -9,7 +9,7 @@ public abstract class AbstractClassLoader extends ClassLoader { protected abstract byte [] loadClassBytes (String name) throws ClassNotFoundException; - + protected Class findClass (String name) throws ClassNotFoundException { diff --git a/src/deltix/util/lang/FileSystemClassLoader.java b/src/deltix/util/lang/FileSystemClassLoader.java index 2345cae8..9c5ae4bd 100644 --- a/src/deltix/util/lang/FileSystemClassLoader.java +++ b/src/deltix/util/lang/FileSystemClassLoader.java @@ -1,8 +1,9 @@ package deltix.util.lang; -import deltix.util.io.IOUtil; import java.io.*; +import deltix.util.io.IOUtil; + /** * UNTESTED */ @@ -13,11 +14,17 @@ public FileSystemClassLoader (File rootDir) { mClassDir = rootDir; } + public InputStream getResourceAsStream (String name) { + try { + return (new FileInputStream (new File (mClassDir, name))); + } catch (IOException iox) { + return (null); + } + } + protected byte [] loadClassBytes (String name) throws ClassNotFoundException { - System.out.println ("loadClassBytes " + name); - File classFile = new File (mClassDir, name.replace (".", "/") + ".class"); if (!classFile.exists ()) From 569323a2a6a0d4f7b1ae7bcd8671882154581c7f Mon Sep 17 00:00:00 2001 From: kpaharelau Date: Tue, 27 Feb 2007 13:24:00 +0000 Subject: [PATCH 0070/2572] Support for a drag-ndrop was added. --- .../qsrv/ui/util/LocalObjectTransferable.java | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 src/deltix/qsrv/ui/util/LocalObjectTransferable.java diff --git a/src/deltix/qsrv/ui/util/LocalObjectTransferable.java b/src/deltix/qsrv/ui/util/LocalObjectTransferable.java new file mode 100644 index 00000000..98eeedc4 --- /dev/null +++ b/src/deltix/qsrv/ui/util/LocalObjectTransferable.java @@ -0,0 +1,63 @@ +package deltix.qsrv.ui.util; + +import java.awt.datatransfer.UnsupportedFlavorException; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.io.IOException; +import java.io.Serializable; + +/** + * Created by IntelliJ IDEA. + * User: PaharelauK + * Date: Feb 27, 2007 + * Time: 11:30:34 AM + * To change this template use File | Settings | File Templates. + */ +public class LocalObjectTransferable implements Transferable, Serializable { + + private T object; + private DataFlavor dataFlavor; + + public LocalObjectTransferable(T object) { + this(object, (Class)object.getClass()); + } + + public LocalObjectTransferable(T object, Class clazz) { + this.object = object; + dataFlavor = getLocalObjectFlavor(clazz); + } + + public DataFlavor[] getTransferDataFlavors() { + return new DataFlavor[] {dataFlavor}; + } + + public boolean isDataFlavorSupported(DataFlavor flavor) { + return dataFlavor.equals(flavor); + } + + public Object getTransferData(DataFlavor flavor) + throws UnsupportedFlavorException, IOException { + if ( dataFlavor.equals(flavor) ) { + return object; + } + throw new UnsupportedFlavorException(flavor); + } + + public T getObject() { + return object; + } + + public static DataFlavor getLocalObjectFlavor(Class clazz) { + try { + return new DataFlavor(DataFlavor.javaJVMLocalObjectMimeType + ";class="+clazz.getName()); + } + catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + } + + + + +} + From d3edc58ebc8e8efc233a68af30545ed21c639e98 Mon Sep 17 00:00:00 2001 From: kpaharelau Date: Tue, 27 Feb 2007 14:23:17 +0000 Subject: [PATCH 0071/2572] Support for a drag-n-drop and tooltip was added. --- .../ui/util/DefaultDragGestureRecognizer.java | 86 +++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 src/deltix/qsrv/ui/util/DefaultDragGestureRecognizer.java diff --git a/src/deltix/qsrv/ui/util/DefaultDragGestureRecognizer.java b/src/deltix/qsrv/ui/util/DefaultDragGestureRecognizer.java new file mode 100644 index 00000000..10f5e97f --- /dev/null +++ b/src/deltix/qsrv/ui/util/DefaultDragGestureRecognizer.java @@ -0,0 +1,86 @@ +package deltix.qsrv.ui.util; + +import sun.awt.dnd.SunDragSourceContextPeer; + +import javax.swing.JComponent; +import javax.swing.TransferHandler; +import java.awt.dnd.DragSource; +import java.awt.event.InputEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseMotionListener; + +/** + * Created by IntelliJ IDEA. + * User: PaharelauK + * Date: Feb 27, 2007 + * Time: 4:15:06 PM + * To change this template use File | Settings | File Templates. + */ +public class DefaultDragGestureRecognizer extends MouseAdapter implements MouseMotionListener { + + private MouseEvent firstMouseEvent = null; + + private static int getMotionThreshold() { + return DragSource.getDragThreshold(); + } + + public void mousePressed(MouseEvent e) { + firstMouseEvent = e; + e.consume(); + } + + public void mouseReleased(MouseEvent e) { + firstMouseEvent = null; + } + + public void mouseDragged(MouseEvent e) { + if (firstMouseEvent != null) { + e.consume(); + + int action = mapDragOperationFromModifiers(e); + + if (action == TransferHandler.NONE) { + return; + } + + int dx = Math.abs(e.getX() - firstMouseEvent.getX()); + int dy = Math.abs(e.getY() - firstMouseEvent.getY()); + if ((dx > getMotionThreshold()) || (dy > getMotionThreshold())) { + // start transfer... shouldn't be a click at this point + JComponent c = getComponent(e); + TransferHandler th = c.getTransferHandler(); + th.exportAsDrag(c, firstMouseEvent, action); + firstMouseEvent = null; + } + } + } + + public void mouseMoved(MouseEvent e) { + } + + + /** + * from javax.swing.plaf.basic.BasicDragGestureRecognizer + */ + protected int mapDragOperationFromModifiers(MouseEvent e) { + int mods = e.getModifiersEx(); + + if ((mods & InputEvent.BUTTON1_DOWN_MASK) != InputEvent.BUTTON1_DOWN_MASK) { + return TransferHandler.NONE; + } + + JComponent c = getComponent(e); + TransferHandler th = c.getTransferHandler(); + return SunDragSourceContextPeer.convertModifiersToDropAction(mods, th.getSourceActions(c)); + } + + protected JComponent getComponent(MouseEvent e) { + Object src = e.getSource(); + if (src instanceof JComponent) { + JComponent c = (JComponent) src; + return c; + } + return null; + } +} From 19b3e04b72b88f70c3908e153d07aae3a3fbff75 Mon Sep 17 00:00:00 2001 From: gene Date: Tue, 27 Feb 2007 15:12:32 +0000 Subject: [PATCH 0072/2572] --- src/deltix/qsrv/ui/util/LocalObjectTransferable.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/deltix/qsrv/ui/util/LocalObjectTransferable.java b/src/deltix/qsrv/ui/util/LocalObjectTransferable.java index 98eeedc4..6de8c19a 100644 --- a/src/deltix/qsrv/ui/util/LocalObjectTransferable.java +++ b/src/deltix/qsrv/ui/util/LocalObjectTransferable.java @@ -18,6 +18,7 @@ public class LocalObjectTransferable implements Transferable, Serializable { private T object; private DataFlavor dataFlavor; + @SuppressWarnings ("unchecked") public LocalObjectTransferable(T object) { this(object, (Class)object.getClass()); } From 33eb0f3d5f517ecec037fc2bc7299563c8a77a73 Mon Sep 17 00:00:00 2001 From: kpaharelau Date: Tue, 27 Feb 2007 15:54:56 +0000 Subject: [PATCH 0073/2572] Popup menu was added. --- src/deltix/qsrv/ui/util/DefaultDragGestureRecognizer.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/deltix/qsrv/ui/util/DefaultDragGestureRecognizer.java b/src/deltix/qsrv/ui/util/DefaultDragGestureRecognizer.java index 10f5e97f..85a7ed16 100644 --- a/src/deltix/qsrv/ui/util/DefaultDragGestureRecognizer.java +++ b/src/deltix/qsrv/ui/util/DefaultDragGestureRecognizer.java @@ -60,9 +60,7 @@ public void mouseMoved(MouseEvent e) { } - /** - * from javax.swing.plaf.basic.BasicDragGestureRecognizer - */ + //from javax.swing.plaf.basic.BasicDragGestureRecognizer protected int mapDragOperationFromModifiers(MouseEvent e) { int mods = e.getModifiersEx(); @@ -78,8 +76,7 @@ protected int mapDragOperationFromModifiers(MouseEvent e) { protected JComponent getComponent(MouseEvent e) { Object src = e.getSource(); if (src instanceof JComponent) { - JComponent c = (JComponent) src; - return c; + return (JComponent) src; } return null; } From 055a5c891fdc789722307ab2f7ff9d452c283ccb Mon Sep 17 00:00:00 2001 From: gene Date: Fri, 9 Mar 2007 17:32:20 +0000 Subject: [PATCH 0074/2572] --- src/deltix/util/Util.java | 25 ++++ .../util/collections/CharSequenceKey.java | 64 ++++++++++ .../util/concurrent/AbstractCursor.java | 18 ++- .../concurrent/AsynchronousDataSource.java | 16 +-- .../concurrent/DataSourceMultiplexer.java | 118 ++++++++++++++++-- 5 files changed, 221 insertions(+), 20 deletions(-) create mode 100644 src/deltix/util/collections/CharSequenceKey.java diff --git a/src/deltix/util/Util.java b/src/deltix/util/Util.java index 1ec615d2..5a5fc9b5 100644 --- a/src/deltix/util/Util.java +++ b/src/deltix/util/Util.java @@ -46,6 +46,14 @@ public static int compare (double a, double b) { return (0); } + + /** + * Compare two CharSequences for equality. A null equals null. + */ + public static boolean equals (CharSequence s1, CharSequence s2) { + return (compare (s1, s2, true) == 0); + } + /** * Compare two CharSequences. A null argument is always less than a non-null argument * and is equal to another null argument. @@ -62,6 +70,8 @@ public static int compare (CharSequence s1, CharSequence s2, boolean f return (-1); else if (s2 == null) return (1); + else if (s1 == s2) + return (0); else { int len1 = s1.length (); int len2 = s2.length (); @@ -1057,4 +1067,19 @@ public static void format ( out.append (" "); } } + + /** + * Replicates the String.hasCode () logic for arbitrary CharSequence instances + */ + public static int hashCode (CharSequence cs) { + int len = cs.length (); + int hc = 0; + + for (int i = 0; i < len; i++) + hc = 31 * hc + cs.charAt (i); + + return (hc); + } + + } diff --git a/src/deltix/util/collections/CharSequenceKey.java b/src/deltix/util/collections/CharSequenceKey.java new file mode 100644 index 00000000..8ef9f8d5 --- /dev/null +++ b/src/deltix/util/collections/CharSequenceKey.java @@ -0,0 +1,64 @@ +package deltix.util.collections; + +import deltix.util.Util; + +/** + * Provides implementation-independent equals/hashCode implementation + * for comparing instances of CharSequence interface purely based on their + * character content. Therefore, equal CharSequences are guaranteed to be equal. + * If an instance of CharSequenceKey is added to a Map, the caller is responsible + * for keeping the charSequence object immutable. + */ +public class CharSequenceKey + implements CharSequence, Comparable +{ + public CharSequence charSequence; + + public CharSequenceKey (CharSequence cs) { + charSequence = cs; + } + + public CharSequenceKey () { + charSequence = null; + } + + /** + * Converts the nested charSequence to String. This action clones the string content + * of a string buffer, preventing it from changing. + */ + public void fix () { + charSequence = charSequence.toString (); + } + + public boolean equals (Object other) { + return ( + this == other || + other instanceof CharSequenceKey && + Util.equals (charSequence, ((CharSequenceKey) other).charSequence) + ); + } + + public int hashCode () { + return (Util.hashCode (charSequence)); + } + + public String toString () { + return (charSequence.toString ()); + } + + public int compareTo (CharSequence o) { + return (Util.compare (charSequence, o, false)); + } + + public char charAt (int index) { + return (charSequence.charAt (index)); + } + + public CharSequence subSequence (int start, int end) { + return (charSequence.subSequence (start, end)); + } + + public int length () { + return (charSequence.length ()); + } +} diff --git a/src/deltix/util/concurrent/AbstractCursor.java b/src/deltix/util/concurrent/AbstractCursor.java index e446e9d3..65d7bd44 100644 --- a/src/deltix/util/concurrent/AbstractCursor.java +++ b/src/deltix/util/concurrent/AbstractCursor.java @@ -20,10 +20,26 @@ public interface AbstractCursor extends Disposable { /** * Moves on to the next data element. This method blocks until * the next element becomes available, or until the cursor is - * determined to be at the end of the sequence. + * determined to be at the end of the sequence. this method is illegal to + * call if isAtEnd () returns true. * * @return false if at the end of the cursor. */ public boolean next () throws InterruptedException; + + /** + * Returns true if next () has not yet been called + * This method is legal to call any number of times at any + * point in the cursor's lifecycle. + */ + public boolean isAtBeginning (); + + /** + * Returns true if the last call to next () returned false. + * Returns false if next () has not been called yet. + * This method is legal to call any number of times at any + * point in the cursor's lifecycle. + */ + public boolean isAtEnd (); } diff --git a/src/deltix/util/concurrent/AsynchronousDataSource.java b/src/deltix/util/concurrent/AsynchronousDataSource.java index d0077d0a..af995f40 100644 --- a/src/deltix/util/concurrent/AsynchronousDataSource.java +++ b/src/deltix/util/concurrent/AsynchronousDataSource.java @@ -6,29 +6,25 @@ * multiple data sources. */ public interface AsynchronousDataSource { + public void addAvailabilityListener (Runnable listener); + + public void removeAvailabilityListener (Runnable listener); + /** * Performs a non-blocking check for data availability. * * @param timeout Maximum time to wait until data is available, * in milliseconds. The value of 0 causes a non-blocking * check to be performed. - * @param listener If specified, and if this method returned false, then - * the listener will be notified (once) when data becomes available. - * Implementations of this class only support - * a single listener. * @return True if data is available, false if timeout has expired. */ - public boolean isDataAvailable (long timeout, Runnable listener) + public boolean isDataAvailable (long timeout) throws InterruptedException; /** * Performs a non-blocking check for data availability. * - * @param listener If specified, and if this method returned false, then - * the listener will be notified (once) when data becomes available. - * Implementations of this class only support - * a single listener. * @return If data is available. */ - public boolean isDataAvailable (Runnable listener); + public boolean isDataAvailable (); } diff --git a/src/deltix/util/concurrent/DataSourceMultiplexer.java b/src/deltix/util/concurrent/DataSourceMultiplexer.java index fd40b133..56dc662f 100644 --- a/src/deltix/util/concurrent/DataSourceMultiplexer.java +++ b/src/deltix/util/concurrent/DataSourceMultiplexer.java @@ -9,24 +9,38 @@ * Allows a single thread to receive data from multiple * data sources. Note that the public methods of this class are NOT designed to * be called concurrently, although the object itself is designed to manage - * concurrent processes. + * concurrent processes. TODO: fix synchronization */ -public class DataSourceMultiplexer { +public class DataSourceMultiplexer + implements AsynchronousDataSource +{ private Runnable mLock = - new NotifyingRunnable (); + new Runnable () { + public void run () { + synchronized (this) { + notify (); + } + + fireDataAvailable (); + } + }; private Set mDataSources = new HashSet (); + private Set mListeners = new HashSet (); + public DataSourceMultiplexer () { } public void add (T ds) { mDataSources.add (ds); + ds.addAvailabilityListener (mLock); } public void remove (T ds) { mDataSources.remove (ds); + ds.removeAvailabilityListener (mLock); } /** @@ -39,22 +53,81 @@ public Set dataSources () { public int getNumDataSources () { return (mDataSources.size ()); } + /** * If one of registered data sources has data available, return it. * Otherwise, return null. */ public T getSourceWithAvailableDataNoBlocking () { - for (T ds : mDataSources) - if (ds.isDataAvailable (mLock)) - return (ds); + synchronized (mLock) { + for (T ds : mDataSources) + if (ds.isDataAvailable ()) + return (ds); + } return (null); } + public static boolean isDataAvailableInAll (AsynchronousDataSource ... dss) { + for (AsynchronousDataSource ds : dss) + if (!ds.isDataAvailable ()) + return (false); + + return (true); + } + + public static boolean isDataAvailableInAny (AsynchronousDataSource ... dss) { + for (AsynchronousDataSource ds : dss) + if (ds.isDataAvailable ()) + return (true); + + return (false); + } + + public static boolean isDataAvailableInAll (long timeout, AsynchronousDataSource ... dss) + throws InterruptedException + { + boolean firstTime = true; + long limit = 0; + NotifyingRunnable lock = new NotifyingRunnable (); + + synchronized (lock) { + try { + for (AsynchronousDataSource ds : dss) + ds.addAvailabilityListener (lock); + + for (;;) { + if (isDataAvailableInAll (dss)) + return (true); + + long waitTimeout; + + if (limit == 0) { + if (timeout <= 0) + return (false); + + limit = System.currentTimeMillis () + timeout; + waitTimeout = timeout; + } + else { + waitTimeout = limit - System.currentTimeMillis (); + + if (waitTimeout <= 0) + return (false); + } + + lock.wait (waitTimeout); + } + } finally { + for (AsynchronousDataSource ds : dss) + ds.removeAvailabilityListener (lock); + } + } + } + public T getSourceWithAvailableData (long timeout) throws InterruptedException { - boolean firstTime = true; long limit = 0; long waitTimeout; @@ -65,13 +138,12 @@ public T getSourceWithAvailableData (long timeout) if (ds != null) return (ds); - if (firstTime) { + if (limit == 0) { if (timeout <= 0) return (null); limit = System.currentTimeMillis () + timeout; waitTimeout = timeout; - firstTime = false; } else { waitTimeout = limit - System.currentTimeMillis (); @@ -84,4 +156,32 @@ public T getSourceWithAvailableData (long timeout) } } } + + protected void fireDataAvailable () { + if (mListeners != null) + for (Runnable l : mListeners) + l.run (); + } + + public void removeAvailabilityListener (Runnable listener) { + synchronized (mListeners) { + mListeners.remove (listener); + } + } + + public void addAvailabilityListener (Runnable listener) { + synchronized (mListeners) { + mListeners.add (listener); + } + } + + public boolean isDataAvailable (long timeout) + throws InterruptedException + { + return (getSourceWithAvailableData (timeout) != null); + } + + public boolean isDataAvailable () { + return (getSourceWithAvailableDataNoBlocking () != null); + } } From 3a7ac859f9fcd4138fe75368ba8061ad9785c138 Mon Sep 17 00:00:00 2001 From: gene Date: Mon, 12 Mar 2007 15:49:12 +0000 Subject: [PATCH 0075/2572] --- .../concurrent/AlwaysAvailableDataSource.java | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 src/deltix/util/concurrent/AlwaysAvailableDataSource.java diff --git a/src/deltix/util/concurrent/AlwaysAvailableDataSource.java b/src/deltix/util/concurrent/AlwaysAvailableDataSource.java new file mode 100644 index 00000000..2d8252b1 --- /dev/null +++ b/src/deltix/util/concurrent/AlwaysAvailableDataSource.java @@ -0,0 +1,35 @@ +package deltix.util.concurrent; + +/** + * An implementation of AsynchronousDataSource, which always has the data available. + * Convenient base class for implementing "always ready" AsynchronousDataSource instances. + */ +public class AlwaysAvailableDataSource implements AsynchronousDataSource { + /** + * Immediately returns true. + */ + public boolean isDataAvailable (long timeout) + throws InterruptedException + { + return (true); + } + + /** + * Immediately returns true. + */ + public boolean isDataAvailable () { + return (true); + } + + /** + * Does nothing. + */ + public void removeAvailabilityListener (Runnable listener) { + } + + /** + * Does nothing. + */ + public void addAvailabilityListener (Runnable listener) { + } +} From 12b63987f582105f91e6a43d147bd6df78735953 Mon Sep 17 00:00:00 2001 From: kpaharelau Date: Tue, 13 Mar 2007 13:36:41 +0000 Subject: [PATCH 0076/2572] --- .../qsrv/ui/util/LocalObjectTransferable.java | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/deltix/qsrv/ui/util/LocalObjectTransferable.java b/src/deltix/qsrv/ui/util/LocalObjectTransferable.java index 6de8c19a..2853dba6 100644 --- a/src/deltix/qsrv/ui/util/LocalObjectTransferable.java +++ b/src/deltix/qsrv/ui/util/LocalObjectTransferable.java @@ -3,6 +3,8 @@ import java.awt.datatransfer.UnsupportedFlavorException; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; +import java.awt.datatransfer.ClipboardOwner; +import java.awt.datatransfer.Clipboard; import java.io.IOException; import java.io.Serializable; @@ -11,9 +13,8 @@ * User: PaharelauK * Date: Feb 27, 2007 * Time: 11:30:34 AM - * To change this template use File | Settings | File Templates. */ -public class LocalObjectTransferable implements Transferable, Serializable { +public class LocalObjectTransferable implements Transferable, ClipboardOwner, Serializable { private T object; private DataFlavor dataFlavor; @@ -55,10 +56,12 @@ public static DataFlavor getLocalObjectFlavor(Class clazz) { catch (ClassNotFoundException e) { throw new RuntimeException(e); } - } - - - + } + // This method is called when this object is no longer + // the owner of the item on the system clipboard. + public void lostOwnership(Clipboard clipboard, Transferable contents) { + //to do nothing + } } From 9855048f342d84e36dc2a39632de835b347c0f56 Mon Sep 17 00:00:00 2001 From: gene Date: Thu, 15 Mar 2007 21:49:50 +0000 Subject: [PATCH 0077/2572] --- src/deltix/util/concurrent/AbstractCursor.java | 3 +-- .../util/concurrent/DataSourceMultiplexer.java | 15 +++++++++++++++ .../concurrent/UncheckedInterruptedException.java | 10 ++++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 src/deltix/util/concurrent/UncheckedInterruptedException.java diff --git a/src/deltix/util/concurrent/AbstractCursor.java b/src/deltix/util/concurrent/AbstractCursor.java index 65d7bd44..1632e158 100644 --- a/src/deltix/util/concurrent/AbstractCursor.java +++ b/src/deltix/util/concurrent/AbstractCursor.java @@ -25,8 +25,7 @@ public interface AbstractCursor extends Disposable { * * @return false if at the end of the cursor. */ - public boolean next () - throws InterruptedException; + public boolean next (); /** * Returns true if next () has not yet been called diff --git a/src/deltix/util/concurrent/DataSourceMultiplexer.java b/src/deltix/util/concurrent/DataSourceMultiplexer.java index 56dc662f..df4b5d1b 100644 --- a/src/deltix/util/concurrent/DataSourceMultiplexer.java +++ b/src/deltix/util/concurrent/DataSourceMultiplexer.java @@ -125,6 +125,21 @@ public static boolean isDataAvailableInAll (long timeout, AsynchronousData } } + public T getSourceWithAvailableData () + throws InterruptedException + { + synchronized (mLock) { + for (;;) { + T ds = getSourceWithAvailableDataNoBlocking (); + + if (ds != null) + return (ds); + + mLock.wait (); + } + } + } + public T getSourceWithAvailableData (long timeout) throws InterruptedException { diff --git a/src/deltix/util/concurrent/UncheckedInterruptedException.java b/src/deltix/util/concurrent/UncheckedInterruptedException.java new file mode 100644 index 00000000..1497eee7 --- /dev/null +++ b/src/deltix/util/concurrent/UncheckedInterruptedException.java @@ -0,0 +1,10 @@ +package deltix.util.concurrent; + +/** + * + */ +public class UncheckedInterruptedException extends RuntimeException { + public UncheckedInterruptedException (InterruptedException ix) { + super (ix); + } +} From fd10f21ea18b4cd0bfc9865ecc08c9d57d55072b Mon Sep 17 00:00:00 2001 From: kpaharelau Date: Mon, 19 Mar 2007 13:15:09 +0000 Subject: [PATCH 0078/2572] New SS functionality. --- src/deltix/util/swing/SwingUtil.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/deltix/util/swing/SwingUtil.java b/src/deltix/util/swing/SwingUtil.java index a1cb4ee3..6cf539e3 100644 --- a/src/deltix/util/swing/SwingUtil.java +++ b/src/deltix/util/swing/SwingUtil.java @@ -1,6 +1,9 @@ package deltix.util.swing; import java.awt.*; +import java.awt.event.KeyEvent; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; import java.io.*; import java.util.*; import java.util.logging.*; @@ -206,4 +209,18 @@ public static JButton newZeroMarginButton (Action action) { return (btn); } + + public static void setEscapeHandler(JDialog dlg, Action escapeAction) { + KeyStroke escape = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0, false); + dlg.getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(escape, "ESCAPE"); + dlg.getRootPane().getActionMap().put("ESCAPE", escapeAction); + } + + public static void setEscapeHandler(JDialog dialog, final ActionListener escapeAction) { + setEscapeHandler(dialog, new AbstractAction() { + public void actionPerformed(ActionEvent e) { + escapeAction.actionPerformed(e); + } + }); + } } From 2b0e6e3cc9590ac93e5fae927ed7bae6af149219 Mon Sep 17 00:00:00 2001 From: gene Date: Wed, 21 Mar 2007 14:05:27 +0000 Subject: [PATCH 0079/2572] --- src/deltix/util/jdbc/JDBCUtils.java | 37 ++- .../jdbc/{LoadMDB.java => MDB2ORACLE.java} | 6 +- src/deltix/util/jdbc/ORACLE2MDB.java | 261 ++++++++++++++++++ src/deltix/util/jdbc/ui.properties | 3 + .../util/progress/MsgProgressIndicator.java | 8 + .../util/progress/ProgressRunnable.java | 9 + .../util/progress/TaskCompletionAdapter.java | 15 + .../util/progress/TaskCompletionListener.java | 10 + src/deltix/util/swing/FileField.java | 5 +- src/deltix/util/swing/StandardAction.java | 21 +- src/deltix/util/swing/SwingUtil.java | 32 ++- 11 files changed, 366 insertions(+), 41 deletions(-) rename src/deltix/util/jdbc/{LoadMDB.java => MDB2ORACLE.java} (94%) create mode 100644 src/deltix/util/jdbc/ORACLE2MDB.java create mode 100644 src/deltix/util/jdbc/ui.properties create mode 100644 src/deltix/util/progress/MsgProgressIndicator.java create mode 100644 src/deltix/util/progress/ProgressRunnable.java create mode 100644 src/deltix/util/progress/TaskCompletionAdapter.java create mode 100644 src/deltix/util/progress/TaskCompletionListener.java diff --git a/src/deltix/util/jdbc/JDBCUtils.java b/src/deltix/util/jdbc/JDBCUtils.java index 84f96b57..cd2c0dfa 100644 --- a/src/deltix/util/jdbc/JDBCUtils.java +++ b/src/deltix/util/jdbc/JDBCUtils.java @@ -11,6 +11,9 @@ * */ public class JDBCUtils { + static ResourceBundle RB = + ResourceBundle.getBundle ("deltix.util.jdbc.ui"); + /** * Converts NaN to NULL */ @@ -68,15 +71,30 @@ public static int queryInt (PreparedStatement ps) throws SQLExcept } } - public static int queryInt (Connection conn, String query, Object ... params) + public static PreparedStatement prepareStatement (Connection conn, String query, Object ... params) throws SQLException { PreparedStatement ps = conn.prepareStatement (query); - + boolean ok = false; + try { for (int ii = 0; ii < params.length; ii++) ps.setObject (ii + 1, params [ii]); + ok = true; + return (ps); + } finally { + if (!ok) + close (ps); + } + } + + public static int queryInt (Connection conn, String query, Object ... params) + throws SQLException + { + PreparedStatement ps = prepareStatement (conn, query, params); + + try { return (queryInt (ps)); } finally { close (ps); @@ -104,12 +122,9 @@ public static String queryString (PreparedStatement ps) throws SQLExc public static String queryString (Connection conn, String query, Object ... params) throws SQLException { - PreparedStatement ps = conn.prepareStatement (query); + PreparedStatement ps = prepareStatement (conn, query, params); try { - for (int ii = 0; ii < params.length; ii++) - ps.setObject (ii + 1, params [ii]); - return (queryString (ps)); } finally { close (ps); @@ -134,12 +149,9 @@ public static List queryStrings (PreparedStatement ps) public static List queryStrings (Connection conn, String query, Object ... params) throws SQLException { - PreparedStatement ps = conn.prepareStatement (query); + PreparedStatement ps = prepareStatement (conn, query, params); try { - for (int ii = 0; ii < params.length; ii++) - ps.setObject (ii + 1, params [ii]); - return (queryStrings (ps)); } finally { close (ps); @@ -221,12 +233,9 @@ public static void exec (Connection conn, String sql) public static void exec (Connection conn, String sql, Object ... params) throws SQLException { - PreparedStatement ps = conn.prepareStatement (sql); + PreparedStatement ps = prepareStatement (conn, sql, params); try { - for (int ii = 0; ii < params.length; ii++) - ps.setObject (ii + 1, params [ii]); - ps.execute (); ps.close (); ps = null; diff --git a/src/deltix/util/jdbc/LoadMDB.java b/src/deltix/util/jdbc/MDB2ORACLE.java similarity index 94% rename from src/deltix/util/jdbc/LoadMDB.java rename to src/deltix/util/jdbc/MDB2ORACLE.java index 0c4334f1..6ad019eb 100644 --- a/src/deltix/util/jdbc/LoadMDB.java +++ b/src/deltix/util/jdbc/MDB2ORACLE.java @@ -9,7 +9,7 @@ /** * */ -public class LoadMDB { +public class MDB2ORACLE { private int mBatchSize = 1000; private boolean mAutoCommit = true; private Connection mOutputConnection; @@ -167,7 +167,7 @@ else if (okObjectTrf [ii]) public static void main (String [] args) throws Exception { if (args.length < 6) { System.out.println ( - "Usage: mdbload
  • ..." + "Usage: mdb2oracle
    ..." ); return; } @@ -187,7 +187,7 @@ public static void main (String [] args) throws Exception { inConn = AccessConnectionFactory.open (new File (args [5])); - LoadMDB loader = new LoadMDB (); + MDB2ORACLE loader = new MDB2ORACLE (); loader.setOutputConnection (outConn); loader.setInputConnection (inConn); diff --git a/src/deltix/util/jdbc/ORACLE2MDB.java b/src/deltix/util/jdbc/ORACLE2MDB.java new file mode 100644 index 00000000..7550eaaa --- /dev/null +++ b/src/deltix/util/jdbc/ORACLE2MDB.java @@ -0,0 +1,261 @@ +package deltix.util.jdbc; + +import java.io.*; +import java.sql.*; +import java.util.*; + +import deltix.util.progress.MsgProgressIndicator; +import static deltix.util.jdbc.JDBCUtils.RB; + +/** + * + */ +public class ORACLE2MDB { + private int mBatchSize = 1000; + private Connection mOutputConnection; + private Connection mInputConnection; + + public void setBatchSize (int size) { + mBatchSize = size; + } + + public void setOutputConnection (Connection outConn) { + mOutputConnection = outConn; + } + + public void setInputConnection (Connection outConn) { + mInputConnection = outConn; + } + + public void loadTable ( + String tableName + ) + throws SQLException, InterruptedException + { + loadTable (tableName, null, null); + } + + public void loadTable ( + String tableName, + MsgProgressIndicator progress, + String condition, + Object ... params + ) + throws SQLException, InterruptedException + { + if (Thread.interrupted ()) + throw new InterruptedException (); + + PreparedStatement sourceStmt = null; + PreparedStatement destStmt = null; + String addSql = + condition == null ? "" : " WHERE " + condition; + + try { + if (progress != null) { + progress.setTotalWork (Double.NaN); + + progress.message ( + String.format (RB.getString ("countingRecords"), tableName) + ); + + progress.setTotalWork ( + JDBCUtils.queryInt ( + mInputConnection, + "SELECT COUNT (*) FROM \"" + tableName + "\"" + addSql, + params + ) + ); + } + + sourceStmt = + JDBCUtils.prepareStatement ( + mInputConnection, + "SELECT * FROM \"" + tableName + "\"" + addSql, + params + ); + + ResultSet rs = sourceStmt.executeQuery (); + ResultSetMetaData md = rs.getMetaData (); + int numColumns = md.getColumnCount (); + + boolean [] okObjectTrf = new boolean [numColumns + 1]; + StringBuilder createSql = new StringBuilder (); + StringBuilder insertSql = new StringBuilder (); + + createSql.append ("CREATE TABLE \""); + createSql.append (tableName); + createSql.append ("\" ("); + + insertSql.append ("INSERT INTO \""); + insertSql.append (tableName); + insertSql.append ("\" ("); + + for (int ii = 1; ii <= numColumns; ii++) { + String col = md.getColumnName (ii); + int prec = md.getPrecision (ii); + String cname = md.getColumnClassName (ii); + + //System.out.println (col + " (" + prec + "): " + cname); + + if (ii > 1) { + createSql.append (", "); + insertSql.append (","); + } + + createSql.append ("\""); + createSql.append (col); + createSql.append ("\" "); + + if (cname.equals ("java.lang.String")) { + createSql.append ("VARCHAR (" + prec + ")"); + okObjectTrf [ii] = true; + } + else if (cname.equals ("java.lang.Float") || cname.equals ("java.lang.Double")) { + createSql.append ("FLOAT"); + okObjectTrf [ii] = true; + } + else if (cname.equals ("java.math.BigDecimal")) { + createSql.append ("FLOAT"); + okObjectTrf [ii] = true; + } + else if (cname.equals ("java.sql.Timestamp")) { + createSql.append ("VARCHAR (32)"); // do not mess with time conversion now + okObjectTrf [ii] = false; + } + else { + //System.out.println ("Defaulting " + col + " type for class " + cname); + createSql.append ("VARCHAR (255)"); + okObjectTrf [ii] = false; + } + + insertSql.append ("\""); + insertSql.append (col); + insertSql.append ("\""); + } + + createSql.append (")"); + + insertSql.append (") VALUES ("); + + for (int ii = 1; ii <= numColumns; ii++) { + if (ii > 1) + insertSql.append (","); + + insertSql.append ("?"); + } + + insertSql.append (")"); + + String createSqlStr = createSql.toString (); + + if (progress != null) + progress.message ( + String.format (RB.getString ("rebuildingTable"), tableName) + ); + + if (Thread.interrupted ()) + throw new InterruptedException (); + + try { + JDBCUtils.exec (mOutputConnection, "DROP TABLE [" + tableName + "]"); + } catch (SQLException x) { + // ignore + } + + if (Thread.interrupted ()) + throw new InterruptedException (); + + JDBCUtils.exec (mOutputConnection, createSqlStr); + + //System.out.println (insertSql.toString ()); + + if (progress != null) + progress.message ( + String.format (RB.getString ("exportingTable"), tableName) + ); + + destStmt = mOutputConnection.prepareStatement (insertSql.toString ()); + + int batchCount = 0; + String [] line; + + while (rs.next ()) { + if (Thread.interrupted ()) + throw new InterruptedException (); + + for (int ii = 1; ii <= numColumns; ii++) { + String cname = md.getColumnClassName (ii); + Object val = rs.getObject (ii); + + if (val == null) + destStmt.setNull (ii, okObjectTrf [ii] ? md.getColumnType (ii) : Types.VARCHAR); + else if (okObjectTrf [ii]) + destStmt.setObject (ii, val); + else + destStmt.setString (ii, val.toString ()); + } + + destStmt.addBatch (); + batchCount++; + + if (progress != null) + progress.incrementWorkDone (1); + + if (batchCount == mBatchSize) { + destStmt.executeBatch (); + batchCount = 0; + } + } + + if (Thread.interrupted ()) + throw new InterruptedException (); + + if (batchCount != 0) { + destStmt.executeBatch (); + } + } finally { + JDBCUtils.close (destStmt); + JDBCUtils.close (sourceStmt); + } + } + + public static void main (String [] args) throws Exception { + if (args.length < 6) { + System.out.println ( + "Usage: oracle2mdb
    ..." + ); + return; + } + + Connection outConn = null; + Connection inConn = null; + + try { + inConn = + ORACLE.openThinConnection ( + args [0], + Integer.parseInt (args [1]), + args [2], + args [3], + args [4] + ); + + outConn = AccessConnectionFactory.open (new File (args [5])); + + ORACLE2MDB loader = new ORACLE2MDB (); + + loader.setOutputConnection (outConn); + loader.setInputConnection (inConn); + + for (int ii = 6; ii < args.length; ii++) + loader.loadTable (args [ii]); + + outConn.close (); + inConn.close (); + } finally { + JDBCUtils.close (outConn); + JDBCUtils.close (inConn); + } + } +} diff --git a/src/deltix/util/jdbc/ui.properties b/src/deltix/util/jdbc/ui.properties new file mode 100644 index 00000000..c156f583 --- /dev/null +++ b/src/deltix/util/jdbc/ui.properties @@ -0,0 +1,3 @@ +countingRecords Counting records in table %s ... +rebuildingTable Rebuilding table %s ... +exportingTable Exporting table %s ... diff --git a/src/deltix/util/progress/MsgProgressIndicator.java b/src/deltix/util/progress/MsgProgressIndicator.java new file mode 100644 index 00000000..7cc03514 --- /dev/null +++ b/src/deltix/util/progress/MsgProgressIndicator.java @@ -0,0 +1,8 @@ +package deltix.util.progress; + +/** + * + */ +public interface MsgProgressIndicator extends ProgressIndicator { + public void message (String text); +} diff --git a/src/deltix/util/progress/ProgressRunnable.java b/src/deltix/util/progress/ProgressRunnable.java new file mode 100644 index 00000000..31cd3618 --- /dev/null +++ b/src/deltix/util/progress/ProgressRunnable.java @@ -0,0 +1,9 @@ +package deltix.util.progress; + +/** + * + */ +public interface ProgressRunnable { + public void run (MsgProgressIndicator progress) + throws InterruptedException; +} diff --git a/src/deltix/util/progress/TaskCompletionAdapter.java b/src/deltix/util/progress/TaskCompletionAdapter.java new file mode 100644 index 00000000..9d3ee743 --- /dev/null +++ b/src/deltix/util/progress/TaskCompletionAdapter.java @@ -0,0 +1,15 @@ +package deltix.util.progress; + +/** + * + */ +public class TaskCompletionAdapter implements TaskCompletionListener { + public void taskCompleted (ProgressRunnable task) { + } + + public void taskFailed (ProgressRunnable task, Throwable x) { + } + + public void taskWasInterrupted (ProgressRunnable task, InterruptedException x) { + } +} diff --git a/src/deltix/util/progress/TaskCompletionListener.java b/src/deltix/util/progress/TaskCompletionListener.java new file mode 100644 index 00000000..0fe120a7 --- /dev/null +++ b/src/deltix/util/progress/TaskCompletionListener.java @@ -0,0 +1,10 @@ +package deltix.util.progress; + +/** + * + */ +public interface TaskCompletionListener { + public void taskCompleted (ProgressRunnable task); + public void taskFailed (ProgressRunnable task, Throwable x); + public void taskWasInterrupted (ProgressRunnable task, InterruptedException x); +} diff --git a/src/deltix/util/swing/FileField.java b/src/deltix/util/swing/FileField.java index 78023fed..ff4b65db 100644 --- a/src/deltix/util/swing/FileField.java +++ b/src/deltix/util/swing/FileField.java @@ -7,6 +7,8 @@ import java.awt.event.*; import javax.swing.*; +import static deltix.util.swing.SwingUtil.RB; + /** * A combination of text field and a button. The button opens * a file selector. User can see and type in the path into @@ -21,9 +23,6 @@ public class FileField extends JPanel { public static final int VALID_ALLOW_NULL = 0x100; - private static final ResourceBundle RB = - ResourceBundle.getBundle ("deltix.util.swing.ui"); - private JFileChooser mFileChooser = new JFileChooser (); private NonEmptyTextField mPathField = new NonEmptyTextField (true); private JButton mDialogButton = new JButton ("..."); diff --git a/src/deltix/util/swing/StandardAction.java b/src/deltix/util/swing/StandardAction.java index a3e7ad13..39915ae2 100644 --- a/src/deltix/util/swing/StandardAction.java +++ b/src/deltix/util/swing/StandardAction.java @@ -1,10 +1,10 @@ package deltix.util.swing; -import javax.swing.AbstractAction; -import java.util.ResourceBundle; -import java.util.MissingResourceException; -import javax.swing.KeyStroke; +import javax.swing.*; +import java.util.*; +import java.util.logging.Level; +import deltix.util.Util; /** * Base class for Action implementations. Action properties @@ -49,7 +49,8 @@ public StandardAction (Class forClass, String nameKey, String imageType) { String packName = className.substring (0, dot); String packPath = packName.replace ('.', '/'); - ResourceBundle rb = ResourceBundle.getBundle (packPath + "/actions"); + String packFull = packPath + ".actions"; + ResourceBundle rb = ResourceBundle.getBundle (packFull); try { putValue (NAME, rb.getString (nameKey)); @@ -57,7 +58,15 @@ public StandardAction (Class forClass, String nameKey, String imageType) { // Ignore the name } - putValue (SHORT_DESCRIPTION, rb.getString (nameKey + ".tt")); + try { + putValue (SHORT_DESCRIPTION, rb.getString (nameKey + ".tt")); + } catch (MissingResourceException mrx) { + Util.LOGGER.log ( + Level.WARNING, + "Missing tooltip for " + nameKey + " in " + packFull, + mrx + ); + } String imageResourcePath = null; diff --git a/src/deltix/util/swing/SwingUtil.java b/src/deltix/util/swing/SwingUtil.java index 6cf539e3..23c4f256 100644 --- a/src/deltix/util/swing/SwingUtil.java +++ b/src/deltix/util/swing/SwingUtil.java @@ -16,6 +16,8 @@ * Colleciton of static utilities */ public abstract class SwingUtil { + static final ResourceBundle RB = ResourceBundle.getBundle ("deltix/util/swing/ui"); + public static final String ERROR_TITLE = ResourceBundle.getBundle ("deltix/util/swing/exceptions").getString ("errorTitle"); @@ -45,21 +47,21 @@ public static Image loadImage (String relPath) { InputStream is = Util.class.getClassLoader ().getResourceAsStream (relPath); - if (is == null) - return (null); - - try { - return (loadImage (is)); - } catch (Throwable x) { - Util.LOGGER.log ( - Level.WARNING, - "Failed to read image from relative path " + relPath, - x - ); - return (null); - } finally { - Util.close (is); - } + if (is == null) + return (null); + + try { + return (loadImage (is)); + } catch (Throwable x) { + Util.LOGGER.log ( + Level.WARNING, + "Failed to read image from relative path " + relPath, + x + ); + return (null); + } finally { + Util.close (is); + } } public static Image loadImage (File file) throws IOException { From 6e164a8322563cc1940dfe7a6a29ad4dfa4c935b Mon Sep 17 00:00:00 2001 From: gene Date: Wed, 21 Mar 2007 14:52:26 +0000 Subject: [PATCH 0080/2572] --- src/deltix/util/swing/SwingUtil.java | 33 ++++++++++++- src/deltix/util/swing/VerticalForm.java | 4 +- src/deltix/util/swing/treeedit/Test.java | 6 --- .../util/swing/treeedit/TreeEditorNode.java | 14 +++++- .../util/swing/treeedit/TreeEditorPanel.java | 46 +++++++++++-------- 5 files changed, 73 insertions(+), 30 deletions(-) diff --git a/src/deltix/util/swing/SwingUtil.java b/src/deltix/util/swing/SwingUtil.java index 23c4f256..fa8a9d2d 100644 --- a/src/deltix/util/swing/SwingUtil.java +++ b/src/deltix/util/swing/SwingUtil.java @@ -15,7 +15,12 @@ /** * Colleciton of static utilities */ -public abstract class SwingUtil { +public abstract class SwingUtil { + /** + * Marks components that call setDeepEnabled from their own setEnabled method + */ + public interface DeepEnabler { }; + static final ResourceBundle RB = ResourceBundle.getBundle ("deltix/util/swing/ui"); public static final String ERROR_TITLE = @@ -225,4 +230,30 @@ public void actionPerformed(ActionEvent e) { } }); } + + public static void setChildrenDeepEnabled (Container c, boolean b) { + Component [] comps = c.getComponents(); + + if (comps != null) + for (Component comp : comps) + setDeepEnabled (comp, b); + } + + public static void setDeepEnabled (Component c, boolean b) { + if (c instanceof DeepEnabler) { + c.setEnabled (b); + return; + } + + if ((c instanceof JLabel || + c instanceof JToolBar || + c instanceof JTabbedPane || + c instanceof JScrollBar)) + c.setEnabled (true); + else + c.setEnabled (b); + + if (c instanceof Container) + setChildrenDeepEnabled ((Container) c, b); + } } diff --git a/src/deltix/util/swing/VerticalForm.java b/src/deltix/util/swing/VerticalForm.java index a27c3f10..b8cfa4d7 100644 --- a/src/deltix/util/swing/VerticalForm.java +++ b/src/deltix/util/swing/VerticalForm.java @@ -94,7 +94,7 @@ public void addRow (JComponent comp, boolean disableWithForm) { mC.gridy++; if (disableWithForm) - enableComponentRec (isEnabled (), comp); + SwingUtil.setDeepEnabled (comp, isEnabled ()); } public void addLine () { @@ -134,7 +134,7 @@ public void addField (JLabel jl, JComponent comp, boolean disableWithFor mC.gridy++; if (disableWithForm) - enableComponentRec (isEnabled (), comp); + SwingUtil.setDeepEnabled (comp, isEnabled ()); } /* public void setEnabled (boolean flag) { diff --git a/src/deltix/util/swing/treeedit/Test.java b/src/deltix/util/swing/treeedit/Test.java index b8068605..41bf4e13 100644 --- a/src/deltix/util/swing/treeedit/Test.java +++ b/src/deltix/util/swing/treeedit/Test.java @@ -1,9 +1,3 @@ -/* - * Test.java - * - * Created on July 13, 2004, 11:07 AM - */ - package deltix.util.swing.treeedit; import java.util.*; diff --git a/src/deltix/util/swing/treeedit/TreeEditorNode.java b/src/deltix/util/swing/treeedit/TreeEditorNode.java index ad135898..44e9df66 100644 --- a/src/deltix/util/swing/treeedit/TreeEditorNode.java +++ b/src/deltix/util/swing/treeedit/TreeEditorNode.java @@ -17,6 +17,8 @@ public interface Filter { } private NodeAdapter mCallback; + private JScrollPane mScroller = null; + private VerticalForm mForm = null; // For the default implementation of getUI void setCallback (NodeAdapter a) { mCallback = a; @@ -133,10 +135,20 @@ public boolean isEditable () { public void configureForm (VerticalForm form) { } + public JComponent getUI () { + if (mForm == null) { + mForm = new VerticalForm (); + mScroller = new JScrollPane (mForm); + } + + configureForm (mForm); + return (mScroller); + } + /** * Called after the form becomes editable. */ - public void beginEdit (VerticalForm form) { + public void beginEdit () { } /** diff --git a/src/deltix/util/swing/treeedit/TreeEditorPanel.java b/src/deltix/util/swing/treeedit/TreeEditorPanel.java index be7b4eea..0d63d9bf 100644 --- a/src/deltix/util/swing/treeedit/TreeEditorPanel.java +++ b/src/deltix/util/swing/treeedit/TreeEditorPanel.java @@ -32,7 +32,7 @@ public class TreeEditorPanel extends JSplitPane { private JLabel mStockHeader = new JLabel (" "); private JPanel mFormPanel = new JPanel (new BorderLayout ()); private JPanel mBottom = new JPanel (new FlowLayout ()); - private VerticalForm mForm; + private JComponent mCurrentForm = null; private JComponent mFormHeader = null; private TreeEditorNode mSelectedNode; private TreeEditorNode mEditedNode; @@ -76,10 +76,6 @@ public void valueChanged (TreeSelectionEvent e) { setLeftComponent (new JScrollPane (mTree)); - mForm = new VerticalForm (); - JScrollPane scroller = new JScrollPane (mForm); - - mFormPanel.add (scroller, BorderLayout.CENTER); mFormPanel.add (mBottom, BorderLayout.SOUTH); setRightComponent (mFormPanel); @@ -87,6 +83,16 @@ public void valueChanged (TreeSelectionEvent e) { EDIT_ACTION.setEnabled (false); } + private void setFormComponent (JComponent form) { + if (mCurrentForm != null) + mFormPanel.remove (mCurrentForm); + + mCurrentForm = form; + + if (mCurrentForm != null) + mFormPanel.add (form, BorderLayout.CENTER); + } + DefaultTreeModel getTreeModel () { return (mTreeModel); } @@ -126,34 +132,31 @@ public void save () { public void cancel () { if (mCreationMode) mEditedNode.creationCanceled (); - - mForm.removeAll (); - mEditedNode.configureForm (mForm); - mForm.revalidate (); - setEditing (null); - - if (mCreationMode) - setFormFromNode (mSelectedNode); + + setEditing (null); + setFormFromNode (mSelectedNode); } public void edit () { mCreationMode = false; setEditing (mSelectedNode); - mSelectedNode.beginEdit (mForm); + mSelectedNode.beginEdit (); } public void editInCreationMode (TreeEditorNode node) { mCreationMode = true; setFormFromNode (node); setEditing (node); - node.beginEdit (mForm); + node.beginEdit (); } private void setEditing (TreeEditorNode node) { mEditedNode = node; mTree.setBackground (node == null ? mEnabledColor : mDisabledColor); mTree.setEnabled (node == null); - mForm.setEnabled (node != null); + + if (mCurrentForm != null) + SwingUtil.setDeepEnabled (mCurrentForm, node != null); mBottom.removeAll (); @@ -197,11 +200,11 @@ private void setFormHeader (TreeEditorNode userNode) { } private void setFormFromNode (TreeEditorNode userNode) { - mForm.removeAll (); - - if (userNode != null) { + if (userNode == null) + setFormComponent (null); + else { setFormHeader (userNode); - userNode.configureForm (mForm); + setFormComponent (userNode.getUI ()); } mFormPanel.revalidate (); @@ -219,6 +222,9 @@ private void selectionChanged (TreePath newPath) { } setFormFromNode (mSelectedNode); + + if (mCurrentForm != null) + SwingUtil.setDeepEnabled (mCurrentForm, false); } private void popup (int x, int y) { From 4782f8b108ca10fd9b837e998c641717e893cfdf Mon Sep 17 00:00:00 2001 From: kpaharelau Date: Thu, 22 Mar 2007 07:24:54 +0000 Subject: [PATCH 0081/2572] New SS functionality. --- .../{qsrv/ui/util => util/swing}/LocalObjectTransferable.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename src/deltix/{qsrv/ui/util => util/swing}/LocalObjectTransferable.java (94%) diff --git a/src/deltix/qsrv/ui/util/LocalObjectTransferable.java b/src/deltix/util/swing/LocalObjectTransferable.java similarity index 94% rename from src/deltix/qsrv/ui/util/LocalObjectTransferable.java rename to src/deltix/util/swing/LocalObjectTransferable.java index 2853dba6..89c3d647 100644 --- a/src/deltix/qsrv/ui/util/LocalObjectTransferable.java +++ b/src/deltix/util/swing/LocalObjectTransferable.java @@ -1,4 +1,4 @@ -package deltix.qsrv.ui.util; +package deltix.util.swing; import java.awt.datatransfer.UnsupportedFlavorException; import java.awt.datatransfer.DataFlavor; From 02f1f94e24e227d35371b90239bfa43a4d9cc05a Mon Sep 17 00:00:00 2001 From: gene Date: Tue, 27 Mar 2007 21:59:40 +0000 Subject: [PATCH 0082/2572] --- .../statestreet/fxa/load => util/jdbc}/ColumnMap.java | 2 +- .../fxa/load => util/jdbc}/DataTransformer.java | 3 +-- .../statestreet/fxa/load => util/jdbc}/FieldTrf.java | 2 +- .../fxa/load => util/jdbc}/IdentityFieldTrf.java | 2 +- src/deltix/util/jdbc/LoadCSV.java | 1 - src/deltix/util/jdbc/MDB2ORACLE.java | 3 --- .../{custom/statestreet/fxa/load => util/jdbc}/MDDump.java | 7 ++----- .../fxa/load => util/jdbc}/OneToOneFieldTrf.java | 2 +- .../statestreet/fxa/load => util/jdbc}/StringFieldTrf.java | 2 +- .../fxa/load => util/jdbc}/SubStringFieldTrf.java | 2 +- .../fxa/load => util/jdbc}/UpperCaseStringFieldTrf.java | 2 +- .../fxa/load => util/jdbc}/ZeroOrMoreToOneFieldTrf.java | 2 +- 12 files changed, 11 insertions(+), 19 deletions(-) rename src/deltix/{custom/statestreet/fxa/load => util/jdbc}/ColumnMap.java (91%) rename src/deltix/{custom/statestreet/fxa/load => util/jdbc}/DataTransformer.java (96%) rename src/deltix/{custom/statestreet/fxa/load => util/jdbc}/FieldTrf.java (89%) rename src/deltix/{custom/statestreet/fxa/load => util/jdbc}/IdentityFieldTrf.java (84%) rename src/deltix/{custom/statestreet/fxa/load => util/jdbc}/MDDump.java (83%) rename src/deltix/{custom/statestreet/fxa/load => util/jdbc}/OneToOneFieldTrf.java (92%) rename src/deltix/{custom/statestreet/fxa/load => util/jdbc}/StringFieldTrf.java (86%) rename src/deltix/{custom/statestreet/fxa/load => util/jdbc}/SubStringFieldTrf.java (90%) rename src/deltix/{custom/statestreet/fxa/load => util/jdbc}/UpperCaseStringFieldTrf.java (85%) rename src/deltix/{custom/statestreet/fxa/load => util/jdbc}/ZeroOrMoreToOneFieldTrf.java (90%) diff --git a/src/deltix/custom/statestreet/fxa/load/ColumnMap.java b/src/deltix/util/jdbc/ColumnMap.java similarity index 91% rename from src/deltix/custom/statestreet/fxa/load/ColumnMap.java rename to src/deltix/util/jdbc/ColumnMap.java index ec459184..40756979 100644 --- a/src/deltix/custom/statestreet/fxa/load/ColumnMap.java +++ b/src/deltix/util/jdbc/ColumnMap.java @@ -1,4 +1,4 @@ -package deltix.custom.statestreet.fxa.load; +package deltix.util.jdbc; import java.sql.*; import java.util.*; diff --git a/src/deltix/custom/statestreet/fxa/load/DataTransformer.java b/src/deltix/util/jdbc/DataTransformer.java similarity index 96% rename from src/deltix/custom/statestreet/fxa/load/DataTransformer.java rename to src/deltix/util/jdbc/DataTransformer.java index d4091fcd..30eb6bfa 100644 --- a/src/deltix/custom/statestreet/fxa/load/DataTransformer.java +++ b/src/deltix/util/jdbc/DataTransformer.java @@ -1,6 +1,5 @@ -package deltix.custom.statestreet.fxa.load; +package deltix.util.jdbc; -import deltix.util.jdbc.JDBCUtils; import java.sql.*; /** diff --git a/src/deltix/custom/statestreet/fxa/load/FieldTrf.java b/src/deltix/util/jdbc/FieldTrf.java similarity index 89% rename from src/deltix/custom/statestreet/fxa/load/FieldTrf.java rename to src/deltix/util/jdbc/FieldTrf.java index 1a61147a..d2d2f5d2 100644 --- a/src/deltix/custom/statestreet/fxa/load/FieldTrf.java +++ b/src/deltix/util/jdbc/FieldTrf.java @@ -1,4 +1,4 @@ -package deltix.custom.statestreet.fxa.load; +package deltix.util.jdbc; import java.sql.*; diff --git a/src/deltix/custom/statestreet/fxa/load/IdentityFieldTrf.java b/src/deltix/util/jdbc/IdentityFieldTrf.java similarity index 84% rename from src/deltix/custom/statestreet/fxa/load/IdentityFieldTrf.java rename to src/deltix/util/jdbc/IdentityFieldTrf.java index 600d4e61..99cf5720 100644 --- a/src/deltix/custom/statestreet/fxa/load/IdentityFieldTrf.java +++ b/src/deltix/util/jdbc/IdentityFieldTrf.java @@ -1,4 +1,4 @@ -package deltix.custom.statestreet.fxa.load; +package deltix.util.jdbc; import java.sql.*; diff --git a/src/deltix/util/jdbc/LoadCSV.java b/src/deltix/util/jdbc/LoadCSV.java index 450f6be6..292d5a4c 100644 --- a/src/deltix/util/jdbc/LoadCSV.java +++ b/src/deltix/util/jdbc/LoadCSV.java @@ -4,7 +4,6 @@ import java.sql.*; import au.com.bytecode.opencsv.CSVReader; -import deltix.custom.statestreet.fxa.utils.Common; import deltix.util.Util; /** diff --git a/src/deltix/util/jdbc/MDB2ORACLE.java b/src/deltix/util/jdbc/MDB2ORACLE.java index 6ad019eb..2b7b29a1 100644 --- a/src/deltix/util/jdbc/MDB2ORACLE.java +++ b/src/deltix/util/jdbc/MDB2ORACLE.java @@ -3,9 +3,6 @@ import java.io.*; import java.sql.*; -import deltix.custom.statestreet.fxa.utils.Common; -import deltix.util.Util; - /** * */ diff --git a/src/deltix/custom/statestreet/fxa/load/MDDump.java b/src/deltix/util/jdbc/MDDump.java similarity index 83% rename from src/deltix/custom/statestreet/fxa/load/MDDump.java rename to src/deltix/util/jdbc/MDDump.java index 9a9ec23d..39311c85 100644 --- a/src/deltix/custom/statestreet/fxa/load/MDDump.java +++ b/src/deltix/util/jdbc/MDDump.java @@ -1,13 +1,10 @@ -package deltix.custom.statestreet.fxa.load; +package deltix.util.jdbc; -import deltix.util.jdbc.AccessConnectionFactory; import java.io.*; import java.sql.*; -import deltix.custom.statestreet.fxa.utils.*; - /** - * Usage: java deltix.custom.statestreet.fxa.load.MDDump <mdb file> <table name> + * Usage: deltix.util.jdbc.MDDump <mdb file> <table name> */ public class MDDump { public static void main (String [] args) throws Exception { diff --git a/src/deltix/custom/statestreet/fxa/load/OneToOneFieldTrf.java b/src/deltix/util/jdbc/OneToOneFieldTrf.java similarity index 92% rename from src/deltix/custom/statestreet/fxa/load/OneToOneFieldTrf.java rename to src/deltix/util/jdbc/OneToOneFieldTrf.java index de4cf7f6..a728c833 100644 --- a/src/deltix/custom/statestreet/fxa/load/OneToOneFieldTrf.java +++ b/src/deltix/util/jdbc/OneToOneFieldTrf.java @@ -1,4 +1,4 @@ -package deltix.custom.statestreet.fxa.load; +package deltix.util.jdbc; import java.sql.*; diff --git a/src/deltix/custom/statestreet/fxa/load/StringFieldTrf.java b/src/deltix/util/jdbc/StringFieldTrf.java similarity index 86% rename from src/deltix/custom/statestreet/fxa/load/StringFieldTrf.java rename to src/deltix/util/jdbc/StringFieldTrf.java index 633ed8dd..686ad6ce 100644 --- a/src/deltix/custom/statestreet/fxa/load/StringFieldTrf.java +++ b/src/deltix/util/jdbc/StringFieldTrf.java @@ -1,4 +1,4 @@ -package deltix.custom.statestreet.fxa.load; +package deltix.util.jdbc; /** * diff --git a/src/deltix/custom/statestreet/fxa/load/SubStringFieldTrf.java b/src/deltix/util/jdbc/SubStringFieldTrf.java similarity index 90% rename from src/deltix/custom/statestreet/fxa/load/SubStringFieldTrf.java rename to src/deltix/util/jdbc/SubStringFieldTrf.java index a19bc257..193c3b32 100644 --- a/src/deltix/custom/statestreet/fxa/load/SubStringFieldTrf.java +++ b/src/deltix/util/jdbc/SubStringFieldTrf.java @@ -1,4 +1,4 @@ -package deltix.custom.statestreet.fxa.load; +package deltix.util.jdbc; /** * diff --git a/src/deltix/custom/statestreet/fxa/load/UpperCaseStringFieldTrf.java b/src/deltix/util/jdbc/UpperCaseStringFieldTrf.java similarity index 85% rename from src/deltix/custom/statestreet/fxa/load/UpperCaseStringFieldTrf.java rename to src/deltix/util/jdbc/UpperCaseStringFieldTrf.java index abdba8d6..322f2c94 100644 --- a/src/deltix/custom/statestreet/fxa/load/UpperCaseStringFieldTrf.java +++ b/src/deltix/util/jdbc/UpperCaseStringFieldTrf.java @@ -1,4 +1,4 @@ -package deltix.custom.statestreet.fxa.load; +package deltix.util.jdbc; /** * diff --git a/src/deltix/custom/statestreet/fxa/load/ZeroOrMoreToOneFieldTrf.java b/src/deltix/util/jdbc/ZeroOrMoreToOneFieldTrf.java similarity index 90% rename from src/deltix/custom/statestreet/fxa/load/ZeroOrMoreToOneFieldTrf.java rename to src/deltix/util/jdbc/ZeroOrMoreToOneFieldTrf.java index 56d59ba2..16dcd66f 100644 --- a/src/deltix/custom/statestreet/fxa/load/ZeroOrMoreToOneFieldTrf.java +++ b/src/deltix/util/jdbc/ZeroOrMoreToOneFieldTrf.java @@ -1,4 +1,4 @@ -package deltix.custom.statestreet.fxa.load; +package deltix.util.jdbc; import java.sql.*; From e891e7fc819e4251ceee0236d0528cb1db1a7592 Mon Sep 17 00:00:00 2001 From: gene Date: Fri, 30 Mar 2007 15:17:32 +0000 Subject: [PATCH 0083/2572] --- src/deltix/util/jdbc/MDB2ORACLE.java | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/src/deltix/util/jdbc/MDB2ORACLE.java b/src/deltix/util/jdbc/MDB2ORACLE.java index 2b7b29a1..201fd124 100644 --- a/src/deltix/util/jdbc/MDB2ORACLE.java +++ b/src/deltix/util/jdbc/MDB2ORACLE.java @@ -32,13 +32,22 @@ public void loadTable ( String tableName ) throws SQLException + { + loadTable (tableName, tableName); + } + + public void loadTable ( + String accessName, + String oracleName + ) + throws SQLException { Statement stmt = null; PreparedStatement ps = null; try { stmt = mInputConnection.createStatement (); - ResultSet rs = stmt.executeQuery ("SELECT * FROM [" + tableName + "]"); + ResultSet rs = stmt.executeQuery ("SELECT * FROM [" + accessName + "]"); ResultSetMetaData md = rs.getMetaData (); int numColumns = md.getColumnCount (); @@ -49,11 +58,11 @@ public void loadTable ( StringBuilder insertSql = new StringBuilder (); createSql.append ("CREATE TABLE \""); - createSql.append (tableName); + createSql.append (oracleName); createSql.append ("\" ("); insertSql.append ("INSERT INTO \""); - insertSql.append (tableName); + insertSql.append (oracleName); insertSql.append ("\" ("); for (int ii = 1; ii <= numColumns; ii++) { @@ -111,7 +120,7 @@ else if (cname.equals ("java.sql.Timestamp")) { String createSqlStr = createSql.toString (); try { - JDBCUtils.exec (mOutputConnection, "DROP TABLE \"" + tableName + "\" CASCADE CONSTRAINTS"); + JDBCUtils.exec (mOutputConnection, "DROP TABLE \"" + oracleName + "\" CASCADE CONSTRAINTS"); } catch (SQLException x) { // ignore } @@ -189,8 +198,14 @@ public static void main (String [] args) throws Exception { loader.setOutputConnection (outConn); loader.setInputConnection (inConn); - for (int ii = 6; ii < args.length; ii++) - loader.loadTable (args [ii]); + for (int ii = 6; ii < args.length; ii++) { + String arg = args [ii]; + int idx = arg.indexOf (':'); + String accessName = idx == -1 ? arg : arg.substring (0, idx); + String oracleName = idx == -1 ? arg : arg.substring (idx + 1); + + loader.loadTable (accessName, oracleName); + } outConn.close (); inConn.close (); From 92d3b86e6698ff09fd9dcffbc31ff5ab490cc4c8 Mon Sep 17 00:00:00 2001 From: gene Date: Tue, 3 Apr 2007 14:50:36 +0000 Subject: [PATCH 0084/2572] Fixed a cursor leak --- src/deltix/util/jdbc/DataTransformer.java | 26 ++++++++++++++++++----- src/deltix/util/jdbc/JDBCUtils.java | 9 ++++++++ 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/src/deltix/util/jdbc/DataTransformer.java b/src/deltix/util/jdbc/DataTransformer.java index 30eb6bfa..cab59a0f 100644 --- a/src/deltix/util/jdbc/DataTransformer.java +++ b/src/deltix/util/jdbc/DataTransformer.java @@ -1,9 +1,10 @@ package deltix.util.jdbc; +import deltix.util.progress.*; import java.sql.*; /** - * + * Caller must eventually call {@link #close} to free resources. */ public class DataTransformer { private Connection mOutputConnection; @@ -15,6 +16,7 @@ public class DataTransformer { private int mBufferCount; private PreparedStatement mStatement; private int mNumProcessed; + private ProgressIndicator mProgress = null; public static FieldTrf [] buildDirectMapping (ResultSetMetaData md) throws SQLException @@ -203,6 +205,21 @@ public DataTransformer ( mStatement = mOutputConnection.prepareStatement (sql.toString ()); } + public void setProgressIndicator (ProgressIndicator p) { + mProgress = p; + } + + public void close () throws SQLException { + if (mStatement != null) { + mStatement.close (); + mStatement = null; + } + mProgress = null; + mOutputConnection = null; + mBuffer = null; + mFieldTrfs = null; + } + private void flush () throws SQLException { @@ -223,8 +240,9 @@ private void flush () mStatement.executeBatch (); mBufferCount = 0; - - System.out.print (" " + mNumProcessed + " processed \r"); + + if (mProgress != null) + mProgress.incrementWorkDone (numInBatch); } public void transformAll (ResultSet in) @@ -254,7 +272,5 @@ public void transformAll (ResultSet in) if (mBufferCount != 0) flush (); - - System.out.println (); } } diff --git a/src/deltix/util/jdbc/JDBCUtils.java b/src/deltix/util/jdbc/JDBCUtils.java index cd2c0dfa..e3ab6178 100644 --- a/src/deltix/util/jdbc/JDBCUtils.java +++ b/src/deltix/util/jdbc/JDBCUtils.java @@ -194,6 +194,15 @@ public static void close (ResultSet rs) { } } + public static void close (DataTransformer xf) { + if (xf != null) + try { + xf.close (); + } catch (Throwable x) { + Util.LOGGER.log (Level.SEVERE, "Error while closing a DataTransformer", x); + } + } + public static void truncateTable (Connection conn, String tname) throws SQLException { From 74c13091e4ca1ad497ca15e181ba9531aac0968c Mon Sep 17 00:00:00 2001 From: gene Date: Thu, 5 Apr 2007 13:58:41 +0000 Subject: [PATCH 0085/2572] --- .../util/cmdline/DefaultApplication.java | 39 ++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/src/deltix/util/cmdline/DefaultApplication.java b/src/deltix/util/cmdline/DefaultApplication.java index 21d039e0..81eaaf12 100644 --- a/src/deltix/util/cmdline/DefaultApplication.java +++ b/src/deltix/util/cmdline/DefaultApplication.java @@ -1,7 +1,12 @@ package deltix.util.cmdline; -import deltix.util.Util; +import deltix.util.io.StreamPump; +import deltix.util.io.SystemIOException; import java.util.*; +import java.io.*; + +import deltix.util.Util; +import deltix.util.io.IOUtil; import org.xml.sax.SAXParseException; /** @@ -36,6 +41,10 @@ protected DefaultApplication (String [] args) { for (int ii = 0; ii < mArgs.length; ii++) mMap.put (mArgs [ii], ii); + if (isArgSpecified ("-?") || isArgSpecified ("-help")) { + printUsageAndExit (); + } + mDebugMode = getArgValue ("-debug"); mVerbose = isArgSpecified ("-verbose"); } @@ -280,4 +289,32 @@ protected void start () { System.exit (1); } } + + public void printUsageAndExit () { + try { + printUsage (); + } catch (Throwable x) { + x.printStackTrace (); + } + + System.exit (0); + } + + public void printUsage () + throws IOException, InterruptedException + { + Class myClass = getClass (); + String path = myClass.getName ().replace ('.', '/') + "-usage.txt"; + + InputStream is = myClass.getClassLoader ().getResourceAsStream (path); + + if (is == null) + throw new FileNotFoundException ("Cannot open resource " + path); + + try { + StreamPump.pump (is, System.out); + } finally { + Util.close (is); + } + } } From 1a57920807e79683991b56b7b9d798f9da060b59 Mon Sep 17 00:00:00 2001 From: gene Date: Thu, 5 Apr 2007 18:00:50 +0000 Subject: [PATCH 0086/2572] --- src/deltix/util/xml/JAXBPool.java | 52 +++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 src/deltix/util/xml/JAXBPool.java diff --git a/src/deltix/util/xml/JAXBPool.java b/src/deltix/util/xml/JAXBPool.java new file mode 100644 index 00000000..23bc5e09 --- /dev/null +++ b/src/deltix/util/xml/JAXBPool.java @@ -0,0 +1,52 @@ +package deltix.util.xml; + +import java.util.*; +import javax.xml.bind.*; + +/** + * + */ +public class JAXBPool { + private JAXBContext mContext; + private Stack mFreeMarshallers = new Stack (); + private Stack mFreeUnmarshallers = new Stack (); + private ValidationEventHandler mEventHandler = null; + + public JAXBPool (JAXBContext context) { + mContext = context; + } + + public void setEventHandler (ValidationEventHandler handler) { + mEventHandler = handler; + } + + public Marshaller checkOutMarshaller () + throws JAXBException + { + try { + return (mFreeMarshallers.pop ()); + } catch (EmptyStackException x) { + return (mContext.createMarshaller ()); + } + } + + public void checkInMarshaller (Marshaller m) { + mFreeMarshallers.push (m); + } + + public Unmarshaller checkOutUnmarshaller () + throws JAXBException + { + try { + return (mFreeUnmarshallers.pop ()); + } catch (EmptyStackException x) { + Unmarshaller u = mContext.createUnmarshaller (); + u.setEventHandler (mEventHandler); + return (u); + } + } + + public void checkInUnmarshaller (Unmarshaller u) { + mFreeUnmarshallers.push (u); + } +} From 9b37df6bfa4062858332510b9cc9d1c5e7ecbaa6 Mon Sep 17 00:00:00 2001 From: gene Date: Thu, 5 Apr 2007 22:13:49 +0000 Subject: [PATCH 0087/2572] --- src/deltix/util/Util.java | 2 +- src/deltix/util/swing/SimpleAction.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/deltix/util/Util.java b/src/deltix/util/Util.java index 5a5fc9b5..73278930 100644 --- a/src/deltix/util/Util.java +++ b/src/deltix/util/Util.java @@ -156,7 +156,7 @@ public static Object callStaticMethod ( InvocationTargetException, IllegalAccessException { - Class c = Class.forName (className); + Class c = Class.forName (className); Class [] paramTypes = new Class [args.length]; for (int ii = 0; ii < args.length; ii++) paramTypes [ii] = args [ii].getClass (); diff --git a/src/deltix/util/swing/SimpleAction.java b/src/deltix/util/swing/SimpleAction.java index 9b4622f5..18d993d6 100644 --- a/src/deltix/util/swing/SimpleAction.java +++ b/src/deltix/util/swing/SimpleAction.java @@ -36,7 +36,7 @@ public SimpleAction (Object delegate, String nameKey, String imageType) { super (delegate.getClass (), nameKey, imageType); mObject = delegate; - Class c = mObject.getClass (); + Class c = mObject.getClass (); while (c != Object.class) { try { @@ -68,7 +68,7 @@ public SimpleAction (Object delegate, String nameKey, String imageType) { * * @exception RuntimeException If such a method was not found. */ - public SimpleAction (Class delegateClass, Object delegate, String nameKey, String imageType) { + public SimpleAction (Class delegateClass, Object delegate, String nameKey, String imageType) { super (delegateClass, nameKey, imageType); mObject = delegate; From 00f670c8bfa9e2094afacc872104c607edcf94a8 Mon Sep 17 00:00:00 2001 From: gene Date: Wed, 11 Apr 2007 01:13:13 +0000 Subject: [PATCH 0088/2572] --- .../util/csvx/BooleanColumnDescriptor.java | 21 ++++ src/deltix/util/csvx/CSVXReader.java | 68 +++++++++++ src/deltix/util/csvx/ColumnDescriptor.java | 115 ++++++++++++++++++ .../util/csvx/DateColumnDescriptor.java | 46 +++++++ .../util/csvx/StringColumnDescriptor.java | 10 ++ 5 files changed, 260 insertions(+) create mode 100644 src/deltix/util/csvx/BooleanColumnDescriptor.java create mode 100644 src/deltix/util/csvx/CSVXReader.java create mode 100644 src/deltix/util/csvx/ColumnDescriptor.java create mode 100644 src/deltix/util/csvx/DateColumnDescriptor.java create mode 100644 src/deltix/util/csvx/StringColumnDescriptor.java diff --git a/src/deltix/util/csvx/BooleanColumnDescriptor.java b/src/deltix/util/csvx/BooleanColumnDescriptor.java new file mode 100644 index 00000000..3b266e74 --- /dev/null +++ b/src/deltix/util/csvx/BooleanColumnDescriptor.java @@ -0,0 +1,21 @@ +package deltix.util.csvx; + +import java.util.regex.*; + +/** + * + */ +public class BooleanColumnDescriptor extends ColumnDescriptor { + static final Pattern DEFAULT_TRUE_PATTERN = + Pattern.compile ("y|Y|true|TRUE"); + + private Pattern mCompiledTruePattern = DEFAULT_TRUE_PATTERN; + + public void setTruePattern (String pattern) { + mCompiledTruePattern = Pattern.compile (pattern); + } + + protected Object parseValue (String cell) { + return (mCompiledTruePattern.matcher (cell).matches ()); + } +} diff --git a/src/deltix/util/csvx/CSVXReader.java b/src/deltix/util/csvx/CSVXReader.java new file mode 100644 index 00000000..944e1929 --- /dev/null +++ b/src/deltix/util/csvx/CSVXReader.java @@ -0,0 +1,68 @@ +package deltix.util.csvx; + +import au.com.bytecode.opencsv.*; +import java.util.*; +import javax.xml.bind.annotation.*; +import java.io.*; +import java.util.logging.*; + +import deltix.qsrv.provider.pub.*; +import deltix.qsrv.qql.comp.*; +import deltix.util.Util; +import deltix.qsrv.pub.*; +import deltix.qsrv.qql.runtime.*; +import deltix.qsrv.impl.util.*; + +/** + * + */ +public class CSVXReader { + private String mDiagPrefix; + private String [] mHeaders; + private CSVReader mCSVReader; + private int mLine; + private String [] mCSVRecord = null; + + public CSVXReader () { + } + + public void open (Reader rd, String diagPrefix) + throws IOException + { + mDiagPrefix = diagPrefix; + mCSVReader = new CSVReader (rd); + + mHeaders = mCSVReader.readNext (); + + if (mHeaders == null) + throw new EOFException (mDiagPrefix + "File is empty"); + + mLine = 1; + } + + public String [] getHeaders () { + return (mHeaders); + } + + public int getLine () { + return (mLine); + } + + public boolean next () throws IOException { + mCSVRecord = mCSVReader.readNext (); + mLine++; + + return (mCSVRecord != null); + } + + public Object getValue (ColumnDescriptor cd) { + return (cd.getValue (mCSVRecord)); + } + + public void setIndexFromHeaders (ColumnDescriptor cd) { + if (!cd.findIndexFromHeaders (mHeaders)) + throw new RuntimeException ( + mDiagPrefix + "1: Header '" + cd.getHeader () + "' was not found" + ); + } +} diff --git a/src/deltix/util/csvx/ColumnDescriptor.java b/src/deltix/util/csvx/ColumnDescriptor.java new file mode 100644 index 00000000..855e0030 --- /dev/null +++ b/src/deltix/util/csvx/ColumnDescriptor.java @@ -0,0 +1,115 @@ +package deltix.util.csvx; + +import deltix.util.Util; +import java.util.regex.*; + +/** + * + */ +public abstract class ColumnDescriptor { + private String mHeader; + private boolean mTrim = true; + private Object mEmptyCellObject = null; + private int mIdxInCSV = -1; + private Pattern [] mCompiledOutOfBandPatterns = null; + private Object [] mOutOfBandValues = null; + + public final void setHeader (String header) { + if (header == null) + throw new IllegalArgumentException ("header == null"); + + mHeader = header; + } + + public final String getHeader () { + return (mHeader); + } + + public final int getCSVIdx () { + return (mIdxInCSV); + } + + public final void setTrimWhiteSpace (boolean flag) { + mTrim = flag; + } + + public final boolean getTrimWhiteSpace () { + return (mTrim); + } + + public final void setEmptyCellObject (Object obj) { + mEmptyCellObject = obj; + } + + public final Object getEmptyCellObject () { + return (mEmptyCellObject); + } + + public final void setOutOfBandPatterns ( + String [] patterns, + Object [] values + ) + { + int num = patterns.length; + + if (values.length != num) + throw new IllegalArgumentException ( + "patterns.length == " + num + + " != values.length == " + values.length + ); + + mCompiledOutOfBandPatterns = new Pattern [num]; + + for (int ii = 0; ii < num; ii++) + mCompiledOutOfBandPatterns [ii] = Pattern.compile (patterns [ii]); + + mOutOfBandValues = values; + } + + protected abstract Object parseValue (String cell); + + public final Object getValue (String cell) { + if (cell == null) + return (mEmptyCellObject); + + if (mTrim) + cell = cell.trim (); + + if (cell.length () == 0) + return (mEmptyCellObject); + + if (mCompiledOutOfBandPatterns != null) { + for (int ii = 0; ii < mCompiledOutOfBandPatterns.length; ii++) + if (mCompiledOutOfBandPatterns [ii].matcher (cell).matches ()) + return (mOutOfBandValues [ii]); + } + + return (parseValue (cell)); + } + + public final Object getValue (String [] line) { + if (line.length <= mIdxInCSV) + return (null); + + return (getValue (line [mIdxInCSV])); + } + + protected static int parseInt (String s, int startIncl, int endIncl) { + int ret = 0; + + for (int ii = startIncl; ii <= endIncl; ii++) + ret = ret * 10 + (s.charAt (ii) - '0'); + + return (ret); + } + + public final void setIndexInCSV (int csvIdx) { + mIdxInCSV = csvIdx; + } + + public final boolean findIndexFromHeaders (String [] headers) { + mIdxInCSV = Util.indexOf (headers, mHeader); + + return (mIdxInCSV >= 0); + } +} diff --git a/src/deltix/util/csvx/DateColumnDescriptor.java b/src/deltix/util/csvx/DateColumnDescriptor.java new file mode 100644 index 00000000..e8def455 --- /dev/null +++ b/src/deltix/util/csvx/DateColumnDescriptor.java @@ -0,0 +1,46 @@ +package deltix.util.csvx; + +import java.text.*; +import java.util.*; + +/** + * + */ +public class DateColumnDescriptor extends ColumnDescriptor { + private DateFormat mFormat; + + public DateColumnDescriptor () { + setFormat ("yyyy-MM-dd"); + setTimeZone ("GMT"); + } + + public void setFormat (String format) { + setFormat (new SimpleDateFormat (format)); + } + + public void setFormat (DateFormat format) { + mFormat = format; + } + + public void setTimeZone (TimeZone timeZone) { + mFormat.setTimeZone (timeZone); + } + + public void setTimeZone (String timeZone) { + setTimeZone (TimeZone.getTimeZone (timeZone)); + } + + protected Object parseValue (String cell) { + return (getDate (cell)); + } + + public Date getDate (String s) { + try { + synchronized (mFormat) { + return (mFormat.parse (s)); + } + } catch (ParseException px) { + throw new NumberFormatException ("Illegal date: '" + s + "': " + px.toString ()); + } + } +} diff --git a/src/deltix/util/csvx/StringColumnDescriptor.java b/src/deltix/util/csvx/StringColumnDescriptor.java new file mode 100644 index 00000000..41249e94 --- /dev/null +++ b/src/deltix/util/csvx/StringColumnDescriptor.java @@ -0,0 +1,10 @@ +package deltix.util.csvx; + +/** + * + */ +public class StringColumnDescriptor extends ColumnDescriptor { + public Object parseValue (String s) { + return (s.intern ()); + } +} From 13182a2925ba9f87a936e5ef31dedc926d07391b Mon Sep 17 00:00:00 2001 From: gene Date: Wed, 11 Apr 2007 22:44:09 +0000 Subject: [PATCH 0089/2572] --- .../util/cmdline/DefaultApplication.java | 71 ++++++++++--------- 1 file changed, 37 insertions(+), 34 deletions(-) diff --git a/src/deltix/util/cmdline/DefaultApplication.java b/src/deltix/util/cmdline/DefaultApplication.java index 81eaaf12..84deef8f 100644 --- a/src/deltix/util/cmdline/DefaultApplication.java +++ b/src/deltix/util/cmdline/DefaultApplication.java @@ -32,48 +32,51 @@ public abstract class DefaultApplication { private String [] mArgs; private Map mMap = new HashMap (); - private String mDebugMode; - private boolean mVerbose; protected DefaultApplication (String [] args) { - mArgs = args; + ArrayList expArgs = new ArrayList (); + + for (int ii = 0; ii < args.length; ii++) { + String arg = args [ii]; + String fpath = arg.substring (1); + + if (arg.startsWith ("@")) { + String line; + + try { + line = IOUtil.readTextFile (fpath); + } catch (Exception x) { + throw new RuntimeException ("Cannot read file: " + fpath); + } + + StringTokenizer stk = new StringTokenizer (line); + + while (stk.hasMoreTokens ()) + expArgs.add (stk.nextToken ()); + } + else + expArgs.add (arg); + } + + mArgs = expArgs.toArray (new String [expArgs.size ()]); for (int ii = 0; ii < mArgs.length; ii++) mMap.put (mArgs [ii], ii); + if (isArgSpecified ("-showargs")) { + for (int ii = 0; ii < mArgs.length; ii++) { + if (ii > 0) + System.out.print (" "); + + System.out.print (mArgs [ii]); + } + + System.out.println (); + } + if (isArgSpecified ("-?") || isArgSpecified ("-help")) { printUsageAndExit (); } - - mDebugMode = getArgValue ("-debug"); - mVerbose = isArgSpecified ("-verbose"); - } - - /** - * Returns whether the application should give verbose - * information about the progress. This is controlled by - * passing the -verbose argument on the command - * line. - */ - public boolean isVerboseMode () { - return (mVerbose); - } - - /** - * Returns whether the application should give debug - * information about the specified area. This is controlled by - * passing the -debug <value> arguments on - * the command line. The <value> is checked for containing - * the string passed as parameter to this method. - * - * @param mode The symbolic name of a debuggable functional area. - * @return If the -debug <value> - * command argument sequence was - * specified, and the <value> argument - * contains the specified symbolic name. - */ - public boolean isDebugMode (String mode) { - return (mDebugMode != null && mDebugMode.indexOf (mode) != -1); } /** @@ -273,7 +276,7 @@ public static void printException ( * trace, the stack trace is printed out. */ public void handleException (Throwable x) { - printException (x, isDebugMode ("trace")); + printException (x, isArgSpecified ("-trace")); } /** From 4c1e752a57568b4b004f779bfb2690c900f380a4 Mon Sep 17 00:00:00 2001 From: gene Date: Fri, 27 Apr 2007 13:42:41 +0000 Subject: [PATCH 0090/2572] --- src/deltix/util/Util.java | 2 +- .../util/io/FileModificationTracker.java | 80 +++++++++++++++++++ 2 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 src/deltix/util/io/FileModificationTracker.java diff --git a/src/deltix/util/Util.java b/src/deltix/util/Util.java index 73278930..10af3a98 100644 --- a/src/deltix/util/Util.java +++ b/src/deltix/util/Util.java @@ -16,7 +16,7 @@ public class Util { public static final String LOGGER_NAME = "deltix.util"; public static final Logger LOGGER = Logger.getLogger (LOGGER_NAME); - + public static final Timer GLOBAL_TIMER = new Timer ("Global Timer", true); /** * Returns the sign of a - b */ diff --git a/src/deltix/util/io/FileModificationTracker.java b/src/deltix/util/io/FileModificationTracker.java new file mode 100644 index 00000000..c2df5e79 --- /dev/null +++ b/src/deltix/util/io/FileModificationTracker.java @@ -0,0 +1,80 @@ +package deltix.util.io; + +import java.io.*; +import java.util.logging.*; +import java.util.*; + +import deltix.util.Util; + +/** + * + */ +public class FileModificationTracker { + private File mFile; + private Runnable mAction = null; + private TimerTask mTask = null; + private long mLastModTimeWhenExisted = 0; + + public FileModificationTracker (File f) { + mFile = f; + mLastModTimeWhenExisted = f.lastModified (); + } + + public FileModificationTracker (File f, Runnable action) { + this (f); + setAction (action); + } + + public final void setAction (Runnable action) { + mAction = action; + } + + /** + * Override this method, or call {@link #setAction}. + * Default implementation runs the Runnable supplied to the {@link #setAction} call. + */ + public void fileWasModified (File f) { + if (mAction != null) + mAction.run (); + } + + public final void checkModified () { + long t = mFile.lastModified (); + + if (t != 0 && t != mLastModTimeWhenExisted) { + fileWasModified (mFile); + mLastModTimeWhenExisted = t; + } + } + + public final void checkModifiedLogExceptions () { + try { + checkModified (); + } catch (Throwable x) { + Util.LOGGER.log (Level.SEVERE, "Uncaught: " + x, x); + } + } + + public final TimerTask createTimerTask () { + return ( + new TimerTask () { + public void run () { + checkModifiedLogExceptions (); + } + } + ); + } + + public final void schedulePeriodicCheck (long delay, long period) { + cancelPeriodicCheck (); + mTask = createTimerTask (); + Util.GLOBAL_TIMER.schedule (mTask, delay, period); + } + + public final void cancelPeriodicCheck () { + if (mTask != null) { + mTask.cancel (); + mTask = null; + } + } +} From 6dd40b71fb6bf7ca135b6e6a12d0228f1957b4ab Mon Sep 17 00:00:00 2001 From: gene Date: Fri, 27 Apr 2007 22:06:49 +0000 Subject: [PATCH 0091/2572] --- .../util/cmdline/DefaultApplication.java | 39 ++++++++++--------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/src/deltix/util/cmdline/DefaultApplication.java b/src/deltix/util/cmdline/DefaultApplication.java index 84deef8f..d761a331 100644 --- a/src/deltix/util/cmdline/DefaultApplication.java +++ b/src/deltix/util/cmdline/DefaultApplication.java @@ -36,27 +36,28 @@ public abstract class DefaultApplication { protected DefaultApplication (String [] args) { ArrayList expArgs = new ArrayList (); - for (int ii = 0; ii < args.length; ii++) { - String arg = args [ii]; - String fpath = arg.substring (1); - - if (arg.startsWith ("@")) { - String line; - - try { - line = IOUtil.readTextFile (fpath); - } catch (Exception x) { - throw new RuntimeException ("Cannot read file: " + fpath); + if (args != null) + for (int ii = 0; ii < args.length; ii++) { + String arg = args [ii]; + String fpath = arg.substring (1); + + if (arg.startsWith ("@")) { + String line; + + try { + line = IOUtil.readTextFile (fpath); + } catch (Exception x) { + throw new RuntimeException ("Cannot read file: " + fpath); + } + + StringTokenizer stk = new StringTokenizer (line); + + while (stk.hasMoreTokens ()) + expArgs.add (stk.nextToken ()); } - - StringTokenizer stk = new StringTokenizer (line); - - while (stk.hasMoreTokens ()) - expArgs.add (stk.nextToken ()); + else + expArgs.add (arg); } - else - expArgs.add (arg); - } mArgs = expArgs.toArray (new String [expArgs.size ()]); From 267e3f967009f7bff7d0da8ae36fa3fc569591e6 Mon Sep 17 00:00:00 2001 From: gene Date: Thu, 3 May 2007 19:52:02 +0000 Subject: [PATCH 0092/2572] --- src/deltix/util/cmdline/DefaultApplication.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/deltix/util/cmdline/DefaultApplication.java b/src/deltix/util/cmdline/DefaultApplication.java index d761a331..c6e16234 100644 --- a/src/deltix/util/cmdline/DefaultApplication.java +++ b/src/deltix/util/cmdline/DefaultApplication.java @@ -64,6 +64,9 @@ protected DefaultApplication (String [] args) { for (int ii = 0; ii < mArgs.length; ii++) mMap.put (mArgs [ii], ii); + // + // Do some default argument processing + // if (isArgSpecified ("-showargs")) { for (int ii = 0; ii < mArgs.length; ii++) { if (ii > 0) @@ -77,7 +80,7 @@ protected DefaultApplication (String [] args) { if (isArgSpecified ("-?") || isArgSpecified ("-help")) { printUsageAndExit (); - } + } } /** From 431f7174d4e435bb85b5ae8294c91a83fedfb1af Mon Sep 17 00:00:00 2001 From: gene Date: Tue, 8 May 2007 17:24:55 +0000 Subject: [PATCH 0093/2572] Assert !isAtEnd() in all AbstractCursor.next methods SQLProvider work --- .../concurrent/DataSourceMultiplexer.java | 12 +++- src/deltix/util/jdbc/JDBCUtils.java | 63 +++++++++++++++++++ 2 files changed, 73 insertions(+), 2 deletions(-) diff --git a/src/deltix/util/concurrent/DataSourceMultiplexer.java b/src/deltix/util/concurrent/DataSourceMultiplexer.java index df4b5d1b..ba3367fc 100644 --- a/src/deltix/util/concurrent/DataSourceMultiplexer.java +++ b/src/deltix/util/concurrent/DataSourceMultiplexer.java @@ -34,12 +34,20 @@ public DataSourceMultiplexer () { } public void add (T ds) { - mDataSources.add (ds); + boolean ok = mDataSources.add (ds); + + if (!ok) + throw new RuntimeException ("Failed to add " + ds); + ds.addAvailabilityListener (mLock); } public void remove (T ds) { - mDataSources.remove (ds); + boolean ok = mDataSources.remove (ds); + + if (!ok) + throw new RuntimeException ("Failed to remove " + ds); + ds.removeAvailabilityListener (mLock); } diff --git a/src/deltix/util/jdbc/JDBCUtils.java b/src/deltix/util/jdbc/JDBCUtils.java index e3ab6178..cc52353d 100644 --- a/src/deltix/util/jdbc/JDBCUtils.java +++ b/src/deltix/util/jdbc/JDBCUtils.java @@ -71,6 +71,27 @@ public static int queryInt (PreparedStatement ps) throws SQLExcept } } + public static long queryLong (PreparedStatement ps) throws SQLException { + ResultSet rs = ps.executeQuery (); + + try { + if (!rs.next ()) + throw new NoRowsReturnedException (); + + long ret = rs.getLong (1); + + if (rs.wasNull ()) + throw new NullValueException (); + + if (rs.next ()) + throw new MultipleRowsReturnedException (); + + return (ret); + } finally { + close (rs); + } + } + public static PreparedStatement prepareStatement (Connection conn, String query, Object ... params) throws SQLException { @@ -101,6 +122,18 @@ public static int queryInt (Connection conn, String query, Object } } + public static long queryLong (Connection conn, String query, Object ... params) + throws SQLException + { + PreparedStatement ps = prepareStatement (conn, query, params); + + try { + return (queryLong (ps)); + } finally { + close (ps); + } + } + public static String queryString (PreparedStatement ps) throws SQLException { ResultSet rs = ps.executeQuery (); @@ -131,6 +164,36 @@ public static String queryString (Connection conn, String query, Obje } } + public static Object queryObject (PreparedStatement ps) throws SQLException { + ResultSet rs = ps.executeQuery (); + + try { + if (!rs.next ()) + throw new NoRowsReturnedException (); + + Object ret = rs.getObject (1); + + if (rs.next ()) + throw new MultipleRowsReturnedException (); + + return (ret); + } finally { + close (rs); + } + } + + public static Object queryObject (Connection conn, String query, Object ... params) + throws SQLException + { + PreparedStatement ps = prepareStatement (conn, query, params); + + try { + return (queryObject (ps)); + } finally { + close (ps); + } + } + public static List queryStrings (PreparedStatement ps) throws SQLException { From deeafd219b42a740b32ee7d26f64b2f9e7fcbcae Mon Sep 17 00:00:00 2001 From: gene Date: Tue, 8 May 2007 20:14:24 +0000 Subject: [PATCH 0094/2572] Cleaned up memory leak detection SQL adapter functional on ORACLE --- .../memory/DisposableResourceTracker.java | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 src/deltix/util/memory/DisposableResourceTracker.java diff --git a/src/deltix/util/memory/DisposableResourceTracker.java b/src/deltix/util/memory/DisposableResourceTracker.java new file mode 100644 index 00000000..cf398391 --- /dev/null +++ b/src/deltix/util/memory/DisposableResourceTracker.java @@ -0,0 +1,74 @@ +package deltix.util.memory; + +import java.io.*; +import java.util.*; +import java.util.logging.*; + +import deltix.util.*; + +/** + * + */ +public class DisposableResourceTracker implements Disposable { + private static HashSet mOpenResources = + new HashSet (); + + private Disposable mResource; + private Throwable mCreationStackTrace; + + public DisposableResourceTracker () { + this (null); + } + + public DisposableResourceTracker (Disposable id) { + mResource = id; + + if (id == null) + id = this; + + mCreationStackTrace = new Throwable (id + " allocated below"); + + synchronized (mOpenResources) { + mOpenResources.add (this); + } + } + + public static void dumpOpenResources (PrintStream ps) { + synchronized (mOpenResources) { + for (DisposableResourceTracker dtt : mOpenResources) + dtt.dump (ps); + } + } + + public void dump (PrintStream ps) { + mCreationStackTrace.printStackTrace (ps); + } + + public void close () { + synchronized (mOpenResources) { + mOpenResources.remove (this); + } + + mCreationStackTrace = null; + } + + protected void finalize () + throws Throwable + { + if (mCreationStackTrace != null) { + Util.LOGGER.log ( + Level.SEVERE, + mCreationStackTrace.getMessage () + " was never closed", + mCreationStackTrace + ); + + close (); + } + + super.finalize (); + + mResource.close (); + } + + +} From 28294753c6edf2d6416ff68b66f950dc488e1251 Mon Sep 17 00:00:00 2001 From: gene Date: Thu, 17 May 2007 17:13:54 +0000 Subject: [PATCH 0095/2572] --- src/deltix/util/xml/HTML.java | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 src/deltix/util/xml/HTML.java diff --git a/src/deltix/util/xml/HTML.java b/src/deltix/util/xml/HTML.java new file mode 100644 index 00000000..77ac0a1d --- /dev/null +++ b/src/deltix/util/xml/HTML.java @@ -0,0 +1,33 @@ +package deltix.util.xml; + +import java.util.*; +import java.io.*; +import javax.xml.bind.*; +import javax.xml.bind.annotation.*; +import org.w3c.dom.Element; + +/** + * A bean holding Locale/CultureInfo information + */ +@XmlRootElement (name = "html", namespace="http://www.w3.org/1999/xhtml") +public class HTML { + @XmlAnyElement + private List mContent; + + public HTML () { } // Make JAXB happy + + public String toString () { + StringWriter swr = new StringWriter (); + + try { + JAXBContext ctxt = JAXBContext.newInstance (HTML.class); + Marshaller m = ctxt.createMarshaller (); + m.setProperty (Marshaller.JAXB_FRAGMENT, Boolean.TRUE); + m.setProperty (Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.FALSE); + m.marshal (this, swr); + } catch (JAXBException x) { + x.printStackTrace (); + } + return (swr.toString ()); + } +} From 5f483d7aa4b77bcff569ffac907a8106be3ceb6b Mon Sep 17 00:00:00 2001 From: gene Date: Thu, 17 May 2007 22:55:08 +0000 Subject: [PATCH 0096/2572] --- .../concurrent/EmptyAsynchronousCursor.java | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 src/deltix/util/concurrent/EmptyAsynchronousCursor.java diff --git a/src/deltix/util/concurrent/EmptyAsynchronousCursor.java b/src/deltix/util/concurrent/EmptyAsynchronousCursor.java new file mode 100644 index 00000000..2e1575fb --- /dev/null +++ b/src/deltix/util/concurrent/EmptyAsynchronousCursor.java @@ -0,0 +1,54 @@ +package deltix.util.concurrent; + +import deltix.util.memory.*; + +/** + * An AsynchronousCursor that returns no frames. + */ +public class EmptyAsynchronousCursor + implements AsynchronousCursor +{ + private DisposableResourceTracker mTracker; + private boolean mNextWasCalled = false; + + public EmptyAsynchronousCursor () { + mTracker = new DisposableResourceTracker (this); + } + + public void close () { + if (mTracker != null) { + mTracker.close (); + mTracker = null; + } + } + + public void removeAvailabilityListener (Runnable listener) { + } + + public void addAvailabilityListener (Runnable listener) { + } + + public boolean isDataAvailable (long timeout) throws InterruptedException { + return (true); + } + + public boolean next () { + if (isAtEnd ()) + throw new IllegalStateException ("Cursor is at end"); + + mNextWasCalled = true; + return (false); + } + + public boolean isAtBeginning () { + return (!mNextWasCalled); + } + + public boolean isAtEnd () { + return (mNextWasCalled); + } + + public boolean isDataAvailable () { + return (true); + } +} From 739c8177e97b3337f2ac965b16b519e3b71b5a84 Mon Sep 17 00:00:00 2001 From: gene Date: Fri, 18 May 2007 21:53:27 +0000 Subject: [PATCH 0097/2572] --- src/deltix/util/cmdline/DefaultApplication.java | 2 +- src/deltix/util/io/ByteArrayOutputStreamEx.java | 4 ++++ src/deltix/util/io/NullOutputStream.java | 7 ++++--- .../{SystemIOException.java => UncheckedIOException.java} | 8 ++++---- 4 files changed, 13 insertions(+), 8 deletions(-) rename src/deltix/util/io/{SystemIOException.java => UncheckedIOException.java} (55%) diff --git a/src/deltix/util/cmdline/DefaultApplication.java b/src/deltix/util/cmdline/DefaultApplication.java index c6e16234..16e1668c 100644 --- a/src/deltix/util/cmdline/DefaultApplication.java +++ b/src/deltix/util/cmdline/DefaultApplication.java @@ -1,7 +1,7 @@ package deltix.util.cmdline; import deltix.util.io.StreamPump; -import deltix.util.io.SystemIOException; +import deltix.util.io.UncheckedIOException; import java.util.*; import java.io.*; diff --git a/src/deltix/util/io/ByteArrayOutputStreamEx.java b/src/deltix/util/io/ByteArrayOutputStreamEx.java index de91b0e0..6b591283 100644 --- a/src/deltix/util/io/ByteArrayOutputStreamEx.java +++ b/src/deltix/util/io/ByteArrayOutputStreamEx.java @@ -41,4 +41,8 @@ public void reset (int position) { count = position; } + + public InputStream openInput () { + return (new ByteArrayInputStreamEx (buf, 0, count)); + } } diff --git a/src/deltix/util/io/NullOutputStream.java b/src/deltix/util/io/NullOutputStream.java index be9acadc..be2cccf3 100644 --- a/src/deltix/util/io/NullOutputStream.java +++ b/src/deltix/util/io/NullOutputStream.java @@ -4,11 +4,10 @@ /** * Null output. - * - * Example of use: code that uses Java serialization only to traverse object graph. */ public class NullOutputStream extends OutputStream { - + private NullOutputStream () { } + public void write(int b) {} public void write(byte b[]) {} @@ -18,4 +17,6 @@ public void write(byte b[], int off, int len) {} public void flush() {} public void close() {} + + public static final OutputStream INSTANCE = new NullOutputStream (); } diff --git a/src/deltix/util/io/SystemIOException.java b/src/deltix/util/io/UncheckedIOException.java similarity index 55% rename from src/deltix/util/io/SystemIOException.java rename to src/deltix/util/io/UncheckedIOException.java index 701fe752..3f6c48eb 100644 --- a/src/deltix/util/io/SystemIOException.java +++ b/src/deltix/util/io/UncheckedIOException.java @@ -6,16 +6,16 @@ * Unchecked exception, used to wrap the checked java.io.IOException * occurring because of system problems. */ -public class SystemIOException extends RuntimeException { - public SystemIOException (String msg, IOException iox) { +public class UncheckedIOException extends RuntimeException { + public UncheckedIOException (String msg, Exception iox) { super (msg, iox); } - public SystemIOException (IOException iox) { + public UncheckedIOException (Exception iox) { super ("System IO error: " + iox, iox); } - public SystemIOException (String msg) { + public UncheckedIOException (String msg) { super (msg); } } From d6aa5afe2783a0fe16b9c76a743adc7b9c50803f Mon Sep 17 00:00:00 2001 From: gene Date: Sun, 20 May 2007 20:07:53 +0000 Subject: [PATCH 0098/2572] --- src/deltix/util/io/FileOpSynchronizer.java | 106 +++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 src/deltix/util/io/FileOpSynchronizer.java diff --git a/src/deltix/util/io/FileOpSynchronizer.java b/src/deltix/util/io/FileOpSynchronizer.java new file mode 100644 index 00000000..ab89ba85 --- /dev/null +++ b/src/deltix/util/io/FileOpSynchronizer.java @@ -0,0 +1,106 @@ +package deltix.util.io; + +import java.io.*; +import java.nio.channels.*; + +import deltix.util.*; +import deltix.util.collections.generated.*; + +/** + * A globally synchronized file operation. + */ +public abstract class FileOpSynchronizer { + public interface Operation { + public void perform ( + File f, + RandomAccessFile raf + ) + throws IOException, InterruptedException; + } + + private static final int NO_LOCK = 0; + private static final int EXCLUSIVE_LOCK = -1; + + /** + * Maps file path to whether the number of shared locks + */ + private static ObjectToIntegerHashMap mLocks = + new ObjectToIntegerHashMap (); + + public static void perform ( + File f, + Operation op, + boolean readOnly + ) + throws IOException, InterruptedException + { + String globalPath = f.getCanonicalPath (); + RandomAccessFile raf = null; + FileLock flock = null; + boolean gotLocalLock = false; + + try { + synchronized (mLocks) { + int lockCount; + + for (;;) { + lockCount = mLocks.get (globalPath, NO_LOCK); + + if (lockCount == NO_LOCK) + break; + + if (readOnly && lockCount != EXCLUSIVE_LOCK) + break; + + mLocks.wait (); + } + + if (readOnly) + lockCount++; + else + lockCount = EXCLUSIVE_LOCK; + + mLocks.put (globalPath, lockCount); + gotLocalLock = true; + } + + raf = new RandomAccessFile (f, readOnly ? "r" : "rw"); + + flock = raf.getChannel ().lock (0, Long.MAX_VALUE, readOnly); + + op.perform (f, raf); + } finally { + // MUST release in reverse order + + if (flock != null) + flock.release (); + + Util.close (raf); + + if (gotLocalLock) { + try { + synchronized (mLocks) { + if (readOnly) { + int lockCount = mLocks.get (globalPath); + + lockCount--; + + if (lockCount == 0) { + mLocks.remove (globalPath); + mLocks.notifyAll (); + } + else + mLocks.put (globalPath, lockCount); + } + else { + mLocks.remove (globalPath); + mLocks.notifyAll (); + } + } + } catch (ObjectToIntegerHashMap.KeyNotFoundException x) { + throw new RuntimeException ("Lock record is gone", x); + } + } + } + } +} From 761e864d47edbc3615848a019a5ecdca5b165adf Mon Sep 17 00:00:00 2001 From: gene Date: Tue, 22 May 2007 23:20:33 +0000 Subject: [PATCH 0099/2572] --- .../util/collections/IndexedArrayList.java | 204 ++++++++++++++++++ 1 file changed, 204 insertions(+) create mode 100644 src/deltix/util/collections/IndexedArrayList.java diff --git a/src/deltix/util/collections/IndexedArrayList.java b/src/deltix/util/collections/IndexedArrayList.java new file mode 100644 index 00000000..f4ab0b87 --- /dev/null +++ b/src/deltix/util/collections/IndexedArrayList.java @@ -0,0 +1,204 @@ +package deltix.util.collections; + +import java.util.*; + +import deltix.util.collections.generated.*; + +/** + * + */ +public class IndexedArrayList implements List { + private ObjectToIntegerHashMap mElemToIdxMap; + private List mElemList; + + public static IndexedArrayList wrapIfNecessary (List in) { + if (in == null) + return (null); + + if (in instanceof IndexedArrayList) + return ((IndexedArrayList ) in); + + return (new IndexedArrayList (in)); + } + + public IndexedArrayList () { + this (32); + } + + public IndexedArrayList (int capacity) { + mElemToIdxMap = new ObjectToIntegerHashMap (capacity); + mElemList = new ObjectArrayList (capacity); + } + + public IndexedArrayList (List list) { + int num = list.size (); + + mElemList = list; + mElemToIdxMap = new ObjectToIntegerHashMap (num); + + for (int ii = 0; ii < num; ii++) + map (list.get (ii), ii); + } + + public IndexedArrayList (Collection list) { + this (new ObjectArrayList (list)); + } + + private void map (E e, int idx) { + if (e == null) + throw new IllegalArgumentException ("Cannot add null"); + + if (!mElemToIdxMap.put (e, idx)) + throw new IllegalArgumentException ( + "Duplicate element: " + e + " at index " + idx + ); + } + + public boolean remove (Object o) { + try { + mElemList.remove (mElemToIdxMap.remove (o)); + return (true); + } catch (ObjectToIntegerHashMap.KeyNotFoundException x) { + return (false); + } + } + + public boolean contains (Object o) { + return (mElemToIdxMap.containsKey (o)); + } + + public int indexOf (Object o) { + return (mElemToIdxMap.get (o, -1)); + } + + public int lastIndexOf (Object o) { + return (indexOf (o)); + } + + private void unmap (E e) { + try { + mElemToIdxMap.remove (e); + } catch (ObjectToIntegerHashMap.KeyNotFoundException x) { + throw new RuntimeException ("unexpected: " + x, x); + } + } + + public E remove (int index) { + throw new UnsupportedOperationException ("Removal is not supported"); + } + + public ListIterator listIterator (int index) { + return (mElemList.listIterator ()); + } + + public E get (int index) { + return (mElemList.get (index)); + } + + public T [] toArray (T [] a) { + return (mElemList.toArray (a)); + } + + public boolean addAll (Collection c) { + for (E e : c) + add (e); + + return (!c.isEmpty ()); + } + + public E set (int index, E element) { + int existIdx = mElemToIdxMap.get (element, -1); + + if (existIdx == index) + return (element); + + if (existIdx >= 0) + throw new IllegalArgumentException ( + "Element " + element + " being set at index " + index + + " already exists at index " + existIdx + ); + + E prev = mElemList.get (index); + + unmap (prev); + mElemList.set (index, element); + map (element, index); + return (prev); + } + + public void add (int index, E element) { + if (index != size ()) + throw new UnsupportedOperationException ("Insertion is not supported"); + + add (element); + } + + public boolean addAll (int index, Collection c) { + if (index != size ()) + throw new UnsupportedOperationException ("Insertion is not supported"); + + return (addAll (c)); + } + + public boolean retainAll (Collection c) { + throw new UnsupportedOperationException ("Removal is not supported"); + } + + public boolean removeAll (Collection c) { + throw new UnsupportedOperationException ("Removal is not supported"); + } + + public boolean containsAll (Collection c) { + for (Object e : c) + if (!mElemToIdxMap.containsKey (e)) + return (false); + + return (true); + } + + public Object [] toArray () { + return (mElemList.toArray ()); + } + + public List subList (int fromIndex, int toIndex) { + return (mElemList.subList (fromIndex, toIndex)); + } + + public int size () { + return (mElemList.size ()); + } + + public boolean add (E o) { + if (o == null) + throw new IllegalArgumentException ("null element"); + + int existIdx = mElemToIdxMap.get (o, -1); + + if (existIdx >= 0) + throw new IllegalArgumentException ( + "Element " + o + + " already exists at index " + existIdx + ); + + map (o, mElemList.size ()); + mElemList.add (o); + return (true); + } + + public void clear () { + mElemList.clear (); + mElemToIdxMap.clear (); + } + + public boolean isEmpty () { + return (mElemList.isEmpty ()); + } + + public Iterator iterator () { + return (mElemList.iterator ()); + } + + public ListIterator listIterator () { + return (mElemList.listIterator ()); + } +} From 911f1c39b713bc89292e7f343bef7c5ff95a1935 Mon Sep 17 00:00:00 2001 From: gene Date: Wed, 23 May 2007 16:58:02 +0000 Subject: [PATCH 0100/2572] --- .../util/collections/IndexedArrayList.java | 112 +++++++++++------- 1 file changed, 69 insertions(+), 43 deletions(-) diff --git a/src/deltix/util/collections/IndexedArrayList.java b/src/deltix/util/collections/IndexedArrayList.java index f4ab0b87..2efda028 100644 --- a/src/deltix/util/collections/IndexedArrayList.java +++ b/src/deltix/util/collections/IndexedArrayList.java @@ -5,7 +5,17 @@ import deltix.util.collections.generated.*; /** - * + *

    A special implementation of List which provides very fast indexOf and + * contains operations.

    + *

    Notes: + *

      + *
    • Null elements can be added, but are not indexed, + * therefore indexOf (null) is not allowed. + *
    • Duplicate elements are not allowed. Therefore, indexOf () + * and lastIndexOf () always return identical results. + *
    • Removal of elements is not allowed. + *
    • Insertion into the middle is not allowed. + *

    */ public class IndexedArrayList implements List { private ObjectToIntegerHashMap mElemToIdxMap; @@ -45,46 +55,57 @@ public IndexedArrayList (Collection list) { } private void map (E e, int idx) { - if (e == null) - throw new IllegalArgumentException ("Cannot add null"); - if (!mElemToIdxMap.put (e, idx)) throw new IllegalArgumentException ( "Duplicate element: " + e + " at index " + idx ); } - public boolean remove (Object o) { + private void unmap (E e) { try { - mElemList.remove (mElemToIdxMap.remove (o)); - return (true); + mElemToIdxMap.remove (e); } catch (ObjectToIntegerHashMap.KeyNotFoundException x) { - return (false); + throw new RuntimeException ("unexpected: " + x, x); } } + + public boolean remove (Object o) { + throw new UnsupportedOperationException ("Removal is not supported"); + } public boolean contains (Object o) { + if (o == null) + throw new UnsupportedOperationException ("contains (null)"); + return (mElemToIdxMap.containsKey (o)); } public int indexOf (Object o) { + if (o == null) + throw new UnsupportedOperationException ("indexOf (null)"); + return (mElemToIdxMap.get (o, -1)); } public int lastIndexOf (Object o) { - return (indexOf (o)); + if (o == null) + throw new UnsupportedOperationException ("lastIndexOf (null)"); + + return (mElemToIdxMap.get (o, -1)); } - private void unmap (E e) { - try { - mElemToIdxMap.remove (e); - } catch (ObjectToIntegerHashMap.KeyNotFoundException x) { - throw new RuntimeException ("unexpected: " + x, x); - } - } - public E remove (int index) { - throw new UnsupportedOperationException ("Removal is not supported"); + if (index != size () - 1) + throw new UnsupportedOperationException ( + "Removal from the middle is not supported" + ); + + E e = mElemList.remove (index); + + if (e != null) + unmap (e); + + return (e); } public ListIterator listIterator (int index) { @@ -107,22 +128,27 @@ public boolean addAll (Collection c) { } public E set (int index, E element) { - int existIdx = mElemToIdxMap.get (element, -1); - - if (existIdx == index) - return (element); + if (element != null) { + int existIdx = mElemToIdxMap.get (element, -1); + + // Still call set () to ensure correct identities + if (existIdx == index) + return (mElemList.set (index, element)); + + if (existIdx >= 0) + throw new IllegalArgumentException ( + "Element " + element + " being set at index " + index + + " already exists at index " + existIdx + ); + + map (element, index); + } - if (existIdx >= 0) - throw new IllegalArgumentException ( - "Element " + element + " being set at index " + index + - " already exists at index " + existIdx - ); + E prev = mElemList.set (index, element); - E prev = mElemList.get (index); + if (prev != null) + unmap (prev); - unmap (prev); - mElemList.set (index, element); - map (element, index); return (prev); } @@ -169,18 +195,18 @@ public int size () { } public boolean add (E o) { - if (o == null) - throw new IllegalArgumentException ("null element"); - - int existIdx = mElemToIdxMap.get (o, -1); - - if (existIdx >= 0) - throw new IllegalArgumentException ( - "Element " + o + - " already exists at index " + existIdx - ); - - map (o, mElemList.size ()); + if (o != null) { + int existIdx = mElemToIdxMap.get (o, -1); + + if (existIdx >= 0) + throw new IllegalArgumentException ( + "Element " + o + + " already exists at index " + existIdx + ); + + map (o, mElemList.size ()); + } + mElemList.add (o); return (true); } From f31a160cf0a9998ab752a469ed32c21da1062b64 Mon Sep 17 00:00:00 2001 From: gene Date: Fri, 25 May 2007 00:45:13 +0000 Subject: [PATCH 0101/2572] --- src/deltix/util/Util.java | 102 +++++++++----------------------------- 1 file changed, 23 insertions(+), 79 deletions(-) diff --git a/src/deltix/util/Util.java b/src/deltix/util/Util.java index 10af3a98..8b9cd264 100644 --- a/src/deltix/util/Util.java +++ b/src/deltix/util/Util.java @@ -540,95 +540,39 @@ public static int arrayHashCode (Object [] arr) { return (ret); } - - /** - * Method identical to "obj1.equals(obj2)", it also handles null values. - */ - public static boolean xequals(Object obj1, Object obj2) - { - return obj1 == obj2 || // shortcut - ((obj1 != null) ? (obj2 != null) && obj1.equals (obj2) : obj2 == null); + + public static boolean eq (Object o1, Object o2) { + if (o1 == null) + return (o2 == null); + else if (o2 == null) + return (false); + else + return (o1.equals (o2)); } - - /** - * Method identical to "obj1.compareTo(obj2)==0", it also handles null values. - */ - public static boolean xcompare(Comparable obj1, T obj2) - { - return obj1 == obj2 || // shortcut - (obj1 != null ? obj1.compareTo (obj2)==0 : obj2 == null); + + public static > int xcompare (T o1, T o2) { + if (o1 == null) + if (o2 == null) + return (0); + else + return (-1); + else if (o2 == null) + return (1); + else + return (o1.compareTo (o2)); } - + /** - * Identical to equals() but handles Number.equals() problem: - * - * ( new Integer (1).equals (new Long (1)) != true ) - * - * This method allows to compare different Number types by actual value. + * Method identical to "obj1.equals(obj2)", it also handles null values. */ - public static boolean xequals2(Object o1, Object o2) + public static boolean xequals(Object obj1, Object obj2) { - if (o1 == o2) - return true; - - if (o1 == null || o2 == null) - return o1 == o2; - - if (o1 instanceof Number && o2 instanceof Number) { - Class c1 = o1.getClass (); - Class c2 = o2.getClass (); - - if (c1 == c2) - return o1.equals (o2); - - if (c1 != Double.class && c1 != Float.class && c2 != Double.class && c2 != Float.class) { - return ((Number) o1).longValue () == ((Number) o2).longValue (); - } else { - return ((Number) o1).doubleValue () == ((Number) o2).doubleValue (); - } - } else { - return o1.equals (o2); - } + return (obj1 == obj2 || obj1 != null && obj2 != null && obj1.equals (obj2)); } public static final double SMALL_NUMBER = 0.0000000000000001; - /** - * Identical to equals() but handles Number.equals() problem: - * - * ( new Integer (1).equals (new Long (1)) != true ) - * - * This method allows to compare different Number types by actual value. - */ - public static boolean equalsEpsilon(Object o1, Object o2) - { - if (o1 == o2) { - return true; - } - - if (o1 == null || o2 == null) { - return o1 == o2; - } - - if (o1 instanceof Number && o2 instanceof Number) { - Class c1 = o1.getClass (); - Class c2 = o2.getClass (); - - if (c1 == c2) { - return o1.equals (o2); - } - - if (c1 != Double.class && c1 != Float.class && c2 != Double.class && c2 != Float.class) { - return ((Number) o1).longValue () == ((Number) o2).longValue (); - } else { - return Math.abs (((Number) o1).doubleValue () - ((Number) o2).doubleValue ()) < SMALL_NUMBER; - } - } else { - return o1.equals (o2); - } - } - /** * Given a Class object, attempts to find its .class location [returns null * if no such definition can be found]. Use for testing/debugging only. From cee5edcd198c0a52f6fc94088e423e525bfd5c19 Mon Sep 17 00:00:00 2001 From: gene Date: Tue, 29 May 2007 16:11:39 +0000 Subject: [PATCH 0102/2572] Added substr () --- src/deltix/util/Util.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/deltix/util/Util.java b/src/deltix/util/Util.java index 8b9cd264..a57c2abc 100644 --- a/src/deltix/util/Util.java +++ b/src/deltix/util/Util.java @@ -1024,6 +1024,4 @@ public static int hashCode (CharSequence cs) { return (hc); } - - } From 6927e1d101f87c84bd0c8d3db823373d15ba1fb6 Mon Sep 17 00:00:00 2001 From: gene Date: Fri, 8 Jun 2007 13:04:35 +0000 Subject: [PATCH 0103/2572] --- src/deltix/util/io/AbstractDataStore.java | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/deltix/util/io/AbstractDataStore.java b/src/deltix/util/io/AbstractDataStore.java index fe349c42..53ded801 100644 --- a/src/deltix/util/io/AbstractDataStore.java +++ b/src/deltix/util/io/AbstractDataStore.java @@ -1,11 +1,12 @@ package deltix.util.io; +import deltix.util.Disposable; import java.io.*; /** * A persistent object used to store structured data of some sort. */ -public interface AbstractDataStore { +public interface AbstractDataStore extends Disposable { /** * Create a new object on disk and format internally. The data store is * left open for read-write at the end of this method. @@ -31,10 +32,4 @@ public interface AbstractDataStore { * Open the data store. */ public void open (boolean readOnly); - - /** - * Close the data store and release all resources, such as caches and - * file descriptors. - */ - public void close (); } From cdf0ca0e9557b186d00067f632a09ccf0d65e96e Mon Sep 17 00:00:00 2001 From: gene Date: Fri, 8 Jun 2007 21:00:36 +0000 Subject: [PATCH 0104/2572] --- .../util/io/ByteCountingOutputStream.java | 8 ++ .../RandomAccessFileToInputStreamAdapter.java | 78 +++++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 src/deltix/util/io/RandomAccessFileToInputStreamAdapter.java diff --git a/src/deltix/util/io/ByteCountingOutputStream.java b/src/deltix/util/io/ByteCountingOutputStream.java index 73ff5cd2..ae6d1d18 100644 --- a/src/deltix/util/io/ByteCountingOutputStream.java +++ b/src/deltix/util/io/ByteCountingOutputStream.java @@ -12,6 +12,14 @@ public ByteCountingOutputStream (OutputStream os) { super (os); } + public void reset () { + mNumBytesWritten = 0; + } + + public void setNumBytesWritten (long n) { + mNumBytesWritten = n; + } + public long getNumBytesWritten () { return (mNumBytesWritten); } diff --git a/src/deltix/util/io/RandomAccessFileToInputStreamAdapter.java b/src/deltix/util/io/RandomAccessFileToInputStreamAdapter.java new file mode 100644 index 00000000..58c8793e --- /dev/null +++ b/src/deltix/util/io/RandomAccessFileToInputStreamAdapter.java @@ -0,0 +1,78 @@ +package deltix.util.io; + +import java.io.*; + +/** + * Adapts java.io.RandomAccessFile to java.io.InputStream interface. + * Useful for buffering data being read from RandomAccessFiles. + * Override close () if necessary, default implementation does nothing! + */ +public class RandomAccessFileToInputStreamAdapter extends InputStream { + private final RandomAccessFile mIn; + private long mMark = -1; + + public RandomAccessFileToInputStreamAdapter (RandomAccessFile in) { + mIn = in; + } + + protected RandomAccessFile randomAccessFile () { + return (mIn); + } + + public int read (byte [] b, int off, int len) + throws IOException + { + return (mIn.read (b, off, len)); + } + + public int read (byte [] b) + throws IOException + { + return (mIn.read (b)); + } + + public int read () throws IOException { + return (mIn.read ()); + } + + public void mark (int readlimit) { + super.mark(readlimit); + } + + public int available () throws IOException { + long n = mIn.length () - mIn.getFilePointer (); + + if (n > Integer.MAX_VALUE) + return (Integer.MAX_VALUE); + + return ((int) n); + } + + public void reset () throws IOException { + if (mMark < 0) + throw new IOException ("mark () has not been called"); + + mIn.seek (mMark); + } + + public boolean markSupported () { + return (true); + } + + public long skip (long n) throws IOException { + if (n <= 0) + return (0); + + long curPos = mIn.getFilePointer (); + long limit = mIn.length (); + long newPos = curPos + n; + + if (newPos > limit) { + n = limit - curPos; + newPos = limit; + } + + mIn.seek (newPos); + return (n); + } +} From 8ea603266176ca3cf4bfa30c662c7cb21d73d646 Mon Sep 17 00:00:00 2001 From: gene Date: Mon, 11 Jun 2007 17:30:55 +0000 Subject: [PATCH 0105/2572] --- src/deltix/util/Util.java | 4 +- src/deltix/util/io/DataOutputStreamEx.java | 12 ++++ src/deltix/util/io/RandomAccessFileStore.java | 69 +++++++++++++++++++ 3 files changed, 83 insertions(+), 2 deletions(-) create mode 100644 src/deltix/util/io/DataOutputStreamEx.java create mode 100644 src/deltix/util/io/RandomAccessFileStore.java diff --git a/src/deltix/util/Util.java b/src/deltix/util/Util.java index a57c2abc..a84fab50 100644 --- a/src/deltix/util/Util.java +++ b/src/deltix/util/Util.java @@ -113,7 +113,7 @@ public static > T min (T a, T b) { return (a.compareTo (b) < 0 ? a : b); } - public static void writeNullableString (String s, ObjectOutput os) + public static void writeNullableString (String s, DataOutput os) throws IOException { os.writeBoolean (s == null); @@ -122,7 +122,7 @@ public static void writeNullableString (String s, ObjectOutput os) os.writeUTF (s); } - public static String readNullableString (ObjectInput is) + public static String readNullableString (DataInput is) throws IOException { if (is.readBoolean ()) diff --git a/src/deltix/util/io/DataOutputStreamEx.java b/src/deltix/util/io/DataOutputStreamEx.java new file mode 100644 index 00000000..176b5312 --- /dev/null +++ b/src/deltix/util/io/DataOutputStreamEx.java @@ -0,0 +1,12 @@ +package deltix.util.io; + +import java.io.*; + +/** + * + */ +public class DataOutputStreamEx extends DataOutputStream { + public DataOutputStreamEx (OutputStream out) { + super (out); + } +} diff --git a/src/deltix/util/io/RandomAccessFileStore.java b/src/deltix/util/io/RandomAccessFileStore.java new file mode 100644 index 00000000..0554c874 --- /dev/null +++ b/src/deltix/util/io/RandomAccessFileStore.java @@ -0,0 +1,69 @@ +package deltix.util.io; + +import java.io.*; + +/** + * + */ +public class RandomAccessFileStore implements AbstractDataStore { + protected final File file; + protected RandomAccessFile raf; + private boolean mIsReadOnly; + + public RandomAccessFileStore (File f) { + file = f; + } + + protected void force (boolean metaData) throws IOException { + raf.getChannel ().force (metaData); + } + + public void open (boolean readOnly) { + mIsReadOnly = readOnly; + + try { + raf = new RandomAccessFile (file, readOnly ? "r" : "rw"); + } catch (IOException iox) { + throw new UncheckedIOException (iox); + } + } + + public boolean isReadOnly () { + return (mIsReadOnly); + } + + public boolean isOpen () { + return (raf != null); + } + + public void format () { + mIsReadOnly = false; + + try { + raf = new RandomAccessFile (file, "rw"); + } catch (IOException iox) { + throw new UncheckedIOException (iox); + } + } + + public void delete () { + close (); + + if (!file.delete ()) + throw new UncheckedIOException ("Failed to delete " + file.getPath ()); + } + + public void close () { + if (raf != null) { + try { + raf.close (); + } catch (IOException iox) { + throw new UncheckedIOException (iox); + } + + raf = null; + } + } + + +} From 41c9f838b0291a3cb9f3aac77cef23e3479dfc1a Mon Sep 17 00:00:00 2001 From: gene Date: Tue, 12 Jun 2007 22:00:00 +0000 Subject: [PATCH 0106/2572] --- src/deltix/util/csvx/CSVXReader.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/deltix/util/csvx/CSVXReader.java b/src/deltix/util/csvx/CSVXReader.java index 944e1929..edb41640 100644 --- a/src/deltix/util/csvx/CSVXReader.java +++ b/src/deltix/util/csvx/CSVXReader.java @@ -59,10 +59,11 @@ public Object getValue (ColumnDescriptor cd) { return (cd.getValue (mCSVRecord)); } - public void setIndexFromHeaders (ColumnDescriptor cd) { - if (!cd.findIndexFromHeaders (mHeaders)) - throw new RuntimeException ( - mDiagPrefix + "1: Header '" + cd.getHeader () + "' was not found" - ); + public void setIndexFromHeaders (ColumnDescriptor ... cds) { + for (ColumnDescriptor cd : cds) + if (!cd.findIndexFromHeaders (mHeaders)) + throw new RuntimeException ( + mDiagPrefix + "1: Header '" + cd.getHeader () + "' was not found" + ); } } From 37a6f2ecb91e8547cfc32bcec0a492b5e9adfd4e Mon Sep 17 00:00:00 2001 From: gene Date: Wed, 13 Jun 2007 16:32:02 +0000 Subject: [PATCH 0107/2572] --- src/deltix/util/cmdline/AbstractShell.java | 127 ++++++++++++++++++ .../util/cmdline/DefaultApplication.java | 8 +- src/deltix/util/io/Dump.java | 21 +++ 3 files changed, 155 insertions(+), 1 deletion(-) create mode 100644 src/deltix/util/cmdline/AbstractShell.java create mode 100644 src/deltix/util/io/Dump.java diff --git a/src/deltix/util/cmdline/AbstractShell.java b/src/deltix/util/cmdline/AbstractShell.java new file mode 100644 index 00000000..1c3eaa56 --- /dev/null +++ b/src/deltix/util/cmdline/AbstractShell.java @@ -0,0 +1,127 @@ +package deltix.util.cmdline; + +import java.io.*; + +/** + * + */ +public abstract class AbstractShell extends DefaultApplication { + protected AbstractShell (String [] args) { + super (args); + } + + protected boolean doSet (String option, String value) throws Exception { + return (false); + } + + protected boolean doCommand (String key, String args) throws Exception { + if (key.equalsIgnoreCase ("help") || key.equalsIgnoreCase ("?")) { + printUsage (System.err); + return (true); + } + + if (key.equalsIgnoreCase ("set")) { + set (key, args); + return (true); + } + + return (false); + } + + protected void set (String option, String value) { + try { + if (!doSet (option, value)) { + System.err.println ("set " + option + ": unrecognized option."); + printUsage (System.err); + } + } catch (Throwable x) { + printException (x, true); + } + } + + protected final void runCommand (String key, String args) { + key = key.trim (); + + try { + if (!doCommand (key, args)) { + System.err.println (key + ": unrecognized command."); + printUsage (System.err); + } + } catch (Throwable x) { + printException (x, true); + } + } + + protected void run () throws Throwable { + String [] args = getArgs (); + + for (int ii = 0; ii < args.length; ) { + String arg = args [ii++]; + + if (arg.startsWith ("-") || arg.startsWith("/")) { + String option = arg.substring (1).toLowerCase (); + + if (option.equals ("do")) { + String key = args [ii++]; + String cmdArgs; + + if (ii == args.length) + cmdArgs = null; + else { + StringBuilder sb = new StringBuilder (args [ii++]); + + while (ii < args.length) { + sb.append (" "); + sb.append (args [ii++]); + } + + cmdArgs = sb.toString (); + } + + runCommand (key, cmdArgs); + return; + } + else + doSet (option, args [ii++]); + } + } + + LineNumberReader rd = + new LineNumberReader (new InputStreamReader (System.in)); + + for (;;) { + System.err.print ("==> "); + System.err.flush (); + + String line = rd.readLine (); + + if (line == null) + break; + + line = line.trim (); + + int len = line.length (); + + if (len == 0) + continue; + + int ws = 0; + + while (ws < len) { + if (Character.isWhitespace (line.charAt (ws))) + break; + + ws++; + } + + String key = line.substring (0, ws); + + if (key.equalsIgnoreCase ("quit") || key.equalsIgnoreCase ("exit")) + break; + + String cmdargs = ws < len ? line.substring (ws + 1).trim () : null; + + runCommand (key, cmdargs); + } + } +} diff --git a/src/deltix/util/cmdline/DefaultApplication.java b/src/deltix/util/cmdline/DefaultApplication.java index 16e1668c..5793066c 100644 --- a/src/deltix/util/cmdline/DefaultApplication.java +++ b/src/deltix/util/cmdline/DefaultApplication.java @@ -309,6 +309,12 @@ public void printUsageAndExit () { public void printUsage () throws IOException, InterruptedException + { + printUsage (System.out); + } + + public void printUsage (OutputStream os) + throws IOException, InterruptedException { Class myClass = getClass (); String path = myClass.getName ().replace ('.', '/') + "-usage.txt"; @@ -319,7 +325,7 @@ public void printUsage () throw new FileNotFoundException ("Cannot open resource " + path); try { - StreamPump.pump (is, System.out); + StreamPump.pump (is, os); } finally { Util.close (is); } diff --git a/src/deltix/util/io/Dump.java b/src/deltix/util/io/Dump.java new file mode 100644 index 00000000..8849b5c7 --- /dev/null +++ b/src/deltix/util/io/Dump.java @@ -0,0 +1,21 @@ +package deltix.util.io; + +/** + * + */ +public class Dump { + + public static void dump (byte [] bytes, int offset, int length) { + for (int ii = 0; ii < length; ii++) { + if ((ii & 15) == 0) + System.out.printf ("%04X: ", ii); + + System.out.printf ("%02X ", bytes [ii]); + + if ((ii & 15) == 15) + System.out.println (); + } + + System.out.println (); + } +} From d968c998b7cb08c50dc611b520f9f2368707ecf1 Mon Sep 17 00:00:00 2001 From: gene Date: Sat, 23 Jun 2007 13:21:31 +0000 Subject: [PATCH 0108/2572] --- src/deltix/util/memory/DataExchangeUtils.java | 70 ++++++---- src/deltix/util/memory/MemoryDataInput.java | 99 ++++++++++++++ src/deltix/util/memory/MemoryDataOutput.java | 126 ++++++++++++++++++ 3 files changed, 268 insertions(+), 27 deletions(-) create mode 100644 src/deltix/util/memory/MemoryDataInput.java create mode 100644 src/deltix/util/memory/MemoryDataOutput.java diff --git a/src/deltix/util/memory/DataExchangeUtils.java b/src/deltix/util/memory/DataExchangeUtils.java index 78195cd6..50975247 100644 --- a/src/deltix/util/memory/DataExchangeUtils.java +++ b/src/deltix/util/memory/DataExchangeUtils.java @@ -5,11 +5,11 @@ * in precisely the same format as DataInput/DataOutput. */ public class DataExchangeUtils { - private static int b (byte [] bytes, int offset) { + public static int readByte (byte [] bytes, int offset) { return (((int) bytes [offset]) & 0xFF); } - private static void b (byte [] bytes, int offset, int byt) { + public static void writeByte (byte [] bytes, int offset, int byt) { bytes [offset] = (byte) (byt & 0xFF); } @@ -23,59 +23,66 @@ private static long lb (byte [] bytes, int offset) { public static short readShort (byte [] bytes, int offset) { return ((short) - (b (bytes, offset) << 8 | - b (bytes, offset + 1)) + (readByte (bytes, offset) << 8 | + readByte (bytes, offset + 1)) ); } public static int readUnsignedShort (byte [] bytes, int offset) { return ( - (b (bytes, offset) << 8 | - b (bytes, offset + 1)) + (readByte (bytes, offset) << 8 | + readByte (bytes, offset + 1)) ); } public static void writeShort (byte [] bytes, int offset, short s) { - b (bytes, offset, s >>> 8); - b (bytes, offset + 1, s); + writeByte (bytes, offset, s >>> 8); + writeByte (bytes, offset + 1, s); } public static void writeUnsignedShort (byte [] bytes, int offset, int s) { - b (bytes, offset, s >>> 8); - b (bytes, offset + 1, s); + writeByte (bytes, offset, s >>> 8); + writeByte (bytes, offset + 1, s); } public static char readChar (byte [] bytes, int offset) { return ((char) - (b (bytes, offset) << 8 | - b (bytes, offset + 1)) + (readByte (bytes, offset) << 8 | + readByte (bytes, offset + 1)) ); } public static void writeChar (byte [] bytes, int offset, char s) { - b (bytes, offset, s >>> 8); - b (bytes, offset + 1, s); + writeByte (bytes, offset, s >>> 8); + writeByte (bytes, offset + 1, s); } public static int readInt (byte [] bytes, int offset) { return ( - b (bytes, offset) << 24 | - b (bytes, offset + 1) << 16 | - b (bytes, offset + 2) << 8 | - b (bytes, offset + 3) + readByte (bytes, offset) << 24 | + readByte (bytes, offset + 1) << 16 | + readByte (bytes, offset + 2) << 8 | + readByte (bytes, offset + 3) ); } public static int readIntInvertBytes (byte [] bytes, int offset) { return ( - b (bytes, offset) | - b (bytes, offset + 1) << 8 | - b (bytes, offset + 2) << 16 | - b (bytes, offset + 3) << 24 + readByte (bytes, offset) | + readByte (bytes, offset + 1) << 8 | + readByte (bytes, offset + 2) << 16 | + readByte (bytes, offset + 3) << 24 ); } public static void writeInt (byte [] bytes, int offset, int i) { + writeByte (bytes, offset, i >>> 24); + writeByte (bytes, offset + 1, i >>> 16); + writeByte (bytes, offset + 2, i >>> 8); + writeByte (bytes, offset + 3, i); + } + + public static void writeUnsignedInt (byte [] bytes, int offset, long i) { b (bytes, offset, i >>> 24); b (bytes, offset + 1, i >>> 16); b (bytes, offset + 2, i >>> 8); @@ -83,10 +90,10 @@ public static void writeInt (byte [] bytes, int offset, int i) { } public static void writeIntInvertBytes (byte [] bytes, int offset, int i) { - b (bytes, offset, i); - b (bytes, offset + 1, i >>> 8); - b (bytes, offset + 2, i >>> 16); - b (bytes, offset + 3, i >>> 24); + writeByte (bytes, offset, i); + writeByte (bytes, offset + 1, i >>> 8); + writeByte (bytes, offset + 2, i >>> 16); + writeByte (bytes, offset + 3, i >>> 24); } public static float readFloat (byte [] bytes, int offset) { @@ -110,6 +117,15 @@ public static long readLong (byte [] bytes, int offset) { ); } + public static long readUnsignedInt (byte [] bytes, int offset) { + return ( + lb (bytes, offset + 4) << 24 | + lb (bytes, offset + 5) << 16 | + lb (bytes, offset + 6) << 8 | + lb (bytes, offset + 7) + ); + } + public static void writeLong (byte [] bytes, int offset, long l) { b (bytes, offset, l >>> 56); b (bytes, offset + 1, l >>> 48); @@ -126,7 +142,7 @@ public static double readDouble (byte [] bytes, int offset) { } public static void writeDouble (byte [] bytes, int offset, double d) { - writeLong (bytes, offset, Double.doubleToLongBits (d)); + writeLong (bytes, offset, Double.doubleToLongBits (d)); } } diff --git a/src/deltix/util/memory/MemoryDataInput.java b/src/deltix/util/memory/MemoryDataInput.java new file mode 100644 index 00000000..96317428 --- /dev/null +++ b/src/deltix/util/memory/MemoryDataInput.java @@ -0,0 +1,99 @@ +package deltix.util.memory; + +import deltix.util.collections.generated.ByteArrayList; + +/** + * Equivalent of DataInputStream wrapped around + * ByteArrayInputStream optimized for extreme performance. This class uses + * no virtual method calls and presents a non-virtual public final API. + */ +public class MemoryDataInput { + private byte [] mBuffer; + private int mPos; + private int mLimit; + + public final void setBytes (ByteArrayList buffer) { + mBuffer = buffer.getInternalBuffer (); + mLimit = buffer.size (); + mPos = 0; + } + + public final void setBytes (byte [] buffer, int offset, int length) { + mBuffer = buffer; + mLimit = offset + length; + mPos = offset; + } + + public final void readFully (byte[] b, int off, int len) { + System.arraycopy (mBuffer, mPos, b, off, len); + mPos += len; + } + + public final void readFully (byte[] b) { + readFully (b, 0, b.length); + } + + public final void skipBytes (int n) { + mPos += n; + } + + public final int readUnsignedShort () { + int ret = DataExchangeUtils.readUnsignedShort (mBuffer, mPos); + mPos += 2; + return (ret); + } + + public final long readUnsignedInt () { + long ret = DataExchangeUtils.readUnsignedInt (mBuffer, mPos); + mPos += 4; + return (ret); + } + + public final int readUnsignedByte () { + throw new RuntimeException (); + } + + public final boolean readBoolean () { + return (readByte () != 0); + } + + public final byte readByte () { + throw new RuntimeException (); + } + + public final char readChar () { + throw new RuntimeException (); + } + + public final double readDouble () { + throw new RuntimeException (); + } + + public final float readFloat () { + throw new RuntimeException (); + } + + public final int readInt () { + throw new RuntimeException (); + } + + public final long readLong () { + throw new RuntimeException (); + } + + public final long readPackedLong () { + throw new RuntimeException (); + } + + public final short readShort () { + throw new RuntimeException (); + } + + public final String readString () { + throw new RuntimeException (); + } + + public final String readUTF () { + throw new RuntimeException (); + } +} diff --git a/src/deltix/util/memory/MemoryDataOutput.java b/src/deltix/util/memory/MemoryDataOutput.java new file mode 100644 index 00000000..fe50a730 --- /dev/null +++ b/src/deltix/util/memory/MemoryDataOutput.java @@ -0,0 +1,126 @@ +package deltix.util.memory; + +/** + * Equivalent of DataOutputStream wrapped around + * ByteArrayOutputStream optimized for extreme performance. This class uses + * no virtual method calls and presents a non-virtual public final API. + */ +public class MemoryDataOutput { + private byte [] mBuffer; + private int mPos = 0; + + public MemoryDataOutput () { + this (4096); + } + + public MemoryDataOutput (int capacity) { + mBuffer = new byte [capacity]; + } + + private final void makeRoom (int space) { + int requiredSize = mPos + space; + int currentSize = mBuffer.length; + + if (currentSize < requiredSize) { + do { + currentSize = currentSize << 1; + } while (currentSize < requiredSize); + + byte [] newBuffer = new byte [currentSize]; + System.arraycopy (mBuffer, 0, newBuffer, 0, mPos); + mBuffer = newBuffer; + } + } + + public final void reset () { + mPos = 0; + } + + public final byte [] getBuffer () { + return (mBuffer); + } + + public final int getSize () { + return (mPos); + } + + public final void writeString (String str) { + boolean isNotNull = str != null; + writeBoolean (isNotNull); + if (isNotNull) + writeUTF (str); + } + + public final void writeUTF (String str) { + throw new RuntimeException (); + } + + public final void write (byte[] b, int off, int len) { + makeRoom (len); + System.arraycopy (b, off, mBuffer, mPos, len); + mPos += len; + } + + public final void write (byte[] b) { + write (b, 0, b.length); + } + + public final void writeByte (byte v) { + makeRoom (1); + mBuffer [mPos] = v; + mPos++; + } + + public final void writeChar (char v) { + makeRoom (2); + DataExchangeUtils.writeChar (mBuffer, mPos, v); + mPos += 2; + } + + public final void writeInt (int v) { + makeRoom (4); + DataExchangeUtils.writeInt (mBuffer, mPos, v); + mPos += 4; + } + + public final void writeShort (short v) { + makeRoom (2); + DataExchangeUtils.writeShort (mBuffer, mPos, v); + mPos += 2; + } + + public final void writeUnsignedShort (int v) { + makeRoom (2); + DataExchangeUtils.writeUnsignedShort (mBuffer, mPos, v); + mPos += 2; + } + + public final void writeBoolean (boolean v) { + makeRoom (1); + mBuffer [mPos] = v ? (byte) 1 : 0; + mPos += 1; + } + + public final void writeLong (long v) { + makeRoom (8); + DataExchangeUtils.writeLong (mBuffer, mPos, v); + mPos += 8; + } + + public final void writePackedLong (long v) { + makeRoom (8); + throw new RuntimeException (); + } + + public final void writeDouble (double v) { + makeRoom (8); + DataExchangeUtils.writeDouble (mBuffer, mPos, v); + mPos += 8; + } + + public final void writeFloat (float v) { + makeRoom (4); + DataExchangeUtils.writeFloat (mBuffer, mPos, v); + mPos += 4; + } +} From 8bf5c560244261eb8fa7ae143beaaff547f292f6 Mon Sep 17 00:00:00 2001 From: gene Date: Sun, 24 Jun 2007 15:31:39 +0000 Subject: [PATCH 0109/2572] --- src/deltix/util/io/IOUtil.java | 57 ---------- src/deltix/util/memory/MemoryDataInput.java | 110 ++++++++++++++++--- src/deltix/util/memory/MemoryDataOutput.java | 87 +++++++++++++-- 3 files changed, 171 insertions(+), 83 deletions(-) diff --git a/src/deltix/util/io/IOUtil.java b/src/deltix/util/io/IOUtil.java index 60df31aa..2fe46a90 100644 --- a/src/deltix/util/io/IOUtil.java +++ b/src/deltix/util/io/IOUtil.java @@ -800,63 +800,6 @@ public static long getFreeDiskSpaceOn(File filesys) return (value); } - /** - * Method attempts to obtian exclusive lock on given file. - * Can be used e.g. to prevent two instances of application from running at the same time. - * Example: - *
    -     * FileLock lock = null;
    -     * try {
    -     *    lock = IOUtil.lock ("fleet.client.lock", true);
    -     *    runApplication (...);
    -     * } finally {
    -     *       IOUtil.unlock (lock);
    -     * }
    -     * 
    - * - * - * - * @param fileLockName - name of the log file to be created in user home directory - * @param exitProcessOnFail - specify true to exit the process on lock failure or any other error - * @return non-null FileLock if given file can be locked - */ - public static final FileLock lock (String fileLockName, boolean exitProcessOnFail) { - - File lockFile = new File (System.getProperty ("user.home"), fileLockName); - FileLock result = null; - try { - result = new RandomAccessFile (lockFile, "rw").getChannel().tryLock(); - } catch (IOException xcp) { - xcp.printStackTrace(); - } - - if (result == null) { - System.err.println("Looks like application is already running (cannot create file lock " + - lockFile.getAbsolutePath() + ")"); - - if (exitProcessOnFail) - System.exit (1); - } - - - return result; - } - - /** - * @param lock - lock obtained by lock() - */ - public static final void unlock (FileLock lock) { - if (lock != null) { - try { - lock.release (); - } catch (IOException ignore) { - ignore.printStackTrace(); - } - } - } - - - public static final class FileOnlyFilter implements FileFilter { public boolean accept(File pathname) diff --git a/src/deltix/util/memory/MemoryDataInput.java b/src/deltix/util/memory/MemoryDataInput.java index 96317428..7e5e7dd6 100644 --- a/src/deltix/util/memory/MemoryDataInput.java +++ b/src/deltix/util/memory/MemoryDataInput.java @@ -12,16 +12,22 @@ public class MemoryDataInput { private int mPos; private int mLimit; + public final void setBytes (byte [] buffer, int offset, int length) { + mBuffer = buffer; + mLimit = offset + length; + mPos = offset; + } + public final void setBytes (ByteArrayList buffer) { mBuffer = buffer.getInternalBuffer (); mLimit = buffer.size (); mPos = 0; } - public final void setBytes (byte [] buffer, int offset, int length) { - mBuffer = buffer; - mLimit = offset + length; - mPos = offset; + public final void setBytes (MemoryDataOutput out) { + mBuffer = out.getBuffer (); + mLimit = out.getSize (); + mPos = 0; } public final void readFully (byte[] b, int off, int len) { @@ -50,43 +56,117 @@ public final long readUnsignedInt () { } public final int readUnsignedByte () { - throw new RuntimeException (); + return (mBuffer [mPos++] & 0xFF); } public final boolean readBoolean () { - return (readByte () != 0); + return (mBuffer [mPos++] != 0); } public final byte readByte () { - throw new RuntimeException (); + return (mBuffer [mPos++]); } public final char readChar () { - throw new RuntimeException (); + char ret = DataExchangeUtils.readChar (mBuffer, mPos); + mPos += 2; + return (ret); } public final double readDouble () { - throw new RuntimeException (); + double ret = DataExchangeUtils.readDouble (mBuffer, mPos); + mPos += 8; + return (ret); } public final float readFloat () { - throw new RuntimeException (); + float ret = DataExchangeUtils.readFloat (mBuffer, mPos); + mPos += 4; + return (ret); } public final int readInt () { - throw new RuntimeException (); + int ret = DataExchangeUtils.readInt (mBuffer, mPos); + mPos += 4; + return (ret); } public final long readLong () { - throw new RuntimeException (); + long ret = DataExchangeUtils.readLong (mBuffer, mPos); + mPos += 8; + return (ret); } - public final long readPackedLong () { - throw new RuntimeException (); + private final long readLongByte () { + return (((long) mBuffer [mPos++]) & 0xFFL); + } + + public final long readPackedUnsignedLong () { + int head = mBuffer [mPos++]; + long ret = head & 0x1F; + int numAddlBytes = (head >>> 5) & 0x7; + + switch (numAddlBytes) { + case 7: + ret |= readLongByte () << 5; + ret |= readLongByte () << 13; + ret |= readLongByte () << 21; + ret |= readLongByte () << 29; + ret |= readLongByte () << 37; + ret |= readLongByte () << 45; + ret |= readLongByte () << 53; + break; + + case 6: + ret |= readLongByte () << 5; + ret |= readLongByte () << 13; + ret |= readLongByte () << 21; + ret |= readLongByte () << 29; + ret |= readLongByte () << 37; + ret |= readLongByte () << 45; + break; + + case 5: + ret |= readLongByte () << 5; + ret |= readLongByte () << 13; + ret |= readLongByte () << 21; + ret |= readLongByte () << 29; + ret |= readLongByte () << 37; + break; + + case 4: + ret |= readLongByte () << 5; + ret |= readLongByte () << 13; + ret |= readLongByte () << 21; + ret |= readLongByte () << 29; + break; + + case 3: + ret |= readLongByte () << 5; + ret |= readLongByte () << 13; + ret |= readLongByte () << 21; + break; + + case 2: + ret |= readLongByte () << 5; + ret |= readLongByte () << 13; + break; + + case 1: + ret |= readLongByte () << 5; + break; + + case 0: + break; + } + + return (ret); } public final short readShort () { - throw new RuntimeException (); + short ret = DataExchangeUtils.readShort (mBuffer, mPos); + mPos += 2; + return (ret); } public final String readString () { diff --git a/src/deltix/util/memory/MemoryDataOutput.java b/src/deltix/util/memory/MemoryDataOutput.java index fe50a730..a765d335 100644 --- a/src/deltix/util/memory/MemoryDataOutput.java +++ b/src/deltix/util/memory/MemoryDataOutput.java @@ -44,15 +44,59 @@ public final int getSize () { return (mPos); } - public final void writeString (String str) { - boolean isNotNull = str != null; - writeBoolean (isNotNull); - if (isNotNull) - writeUTF (str); - } + public final void writeString (CharSequence str) { + if (str == null) { + writeUnsignedShort (0xFFFF); + return; + } + + int strlen = str.length(); + int utflen = 0; + int c, count = 0; + + /* use charAt instead of copying String to char array */ + for (int i = 0; i < strlen; i++) { + c = str.charAt(i); + if ((c >= 0x0001) && (c <= 0x007F)) + utflen++; + else if (c > 0x07FF) + utflen += 3; + else + utflen += 2; + } + + if (utflen >= 0xFFFF) + throw new RuntimeException ("Encoded string too long: " + utflen + " bytes"); - public final void writeUTF (String str) { - throw new RuntimeException (); + makeRoom (utflen + 2); + writeUnsignedShort (utflen); + + int i=0; + + for (i=0; i= 0x0001) && (c <= 0x007F))) + break; + + mBuffer [mPos++] = (byte) c; + } + + for (; i < strlen; i++) { + c = str.charAt(i); + + if ((c >= 0x0001) && (c <= 0x007F)) + mBuffer [mPos++] = (byte) c; + else if (c > 0x07FF) { + mBuffer [mPos++] = (byte) (0xE0 | ((c >> 12) & 0x0F)); + mBuffer [mPos++] = (byte) (0x80 | ((c >> 6) & 0x3F)); + mBuffer [mPos++] = (byte) (0x80 | ((c >> 0) & 0x3F)); + } + else { + mBuffer [mPos++] = (byte) (0xC0 | ((c >> 6) & 0x1F)); + mBuffer [mPos++] = (byte) (0x80 | ((c >> 0) & 0x3F)); + } + } } public final void write (byte[] b, int off, int len) { @@ -71,6 +115,12 @@ public final void writeByte (byte v) { mPos++; } + public final void writeUnsignedByte (int v) { + makeRoom (1); + mBuffer [mPos] = (byte) v; + mPos++; + } + public final void writeChar (char v) { makeRoom (2); DataExchangeUtils.writeChar (mBuffer, mPos, v); @@ -107,9 +157,24 @@ public final void writeLong (long v) { mPos += 8; } - public final void writePackedLong (long v) { - makeRoom (8); - throw new RuntimeException (); + public final void writePackedUnsignedLong (long v) { + if ((v & 0xE000000000000000L) != 0) + throw new IllegalArgumentException ("High 3 bits must be 0; v=" + v); + + makeRoom (8); + + int pos = mPos++; + int addlPos = mPos; + int low5bits = ((int) v) & 0x1F; + + v = v >>> 5; + + while (v != 0) { + mBuffer [mPos++] = (byte) (v & 0xFF); + v = v >>> 8; + } + + mBuffer [pos] = (byte) (low5bits | ((mPos - addlPos) << 5)); } public final void writeDouble (double v) { From 7a68f81568c1e7e63d51849672e141007a7a74ae Mon Sep 17 00:00:00 2001 From: gene Date: Mon, 25 Jun 2007 22:14:18 +0000 Subject: [PATCH 0110/2572] --- src/deltix/util/memory/MemoryDataInput.java | 26 +++++++++++++++++---- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/src/deltix/util/memory/MemoryDataInput.java b/src/deltix/util/memory/MemoryDataInput.java index 7e5e7dd6..65d5fd13 100644 --- a/src/deltix/util/memory/MemoryDataInput.java +++ b/src/deltix/util/memory/MemoryDataInput.java @@ -1,6 +1,7 @@ package deltix.util.memory; import deltix.util.collections.generated.ByteArrayList; +import java.io.UnsupportedEncodingException; /** * Equivalent of DataInputStream wrapped around @@ -170,10 +171,25 @@ public final short readShort () { } public final String readString () { - throw new RuntimeException (); - } - - public final String readUTF () { - throw new RuntimeException (); + int utflen = readUnsignedShort (); + + if (utflen == 0xFFFF) + return (null); + + if (utflen == 0) + return (""); + + String s; + + try { + s = new String (mBuffer, mPos, utflen, "UTF-8"); + } catch (UnsupportedEncodingException x) { + throw new RuntimeException ("UTF-8 unsupported???", x); + } + + mPos += utflen; + + return (s); } + } From 9d07a929465d3c116899b8a77446d891b7974cbc Mon Sep 17 00:00:00 2001 From: gene Date: Mon, 25 Jun 2007 22:31:36 +0000 Subject: [PATCH 0111/2572] --- src/deltix/util/io/RandomAccessFileStore.java | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/deltix/util/io/RandomAccessFileStore.java b/src/deltix/util/io/RandomAccessFileStore.java index 0554c874..8518db07 100644 --- a/src/deltix/util/io/RandomAccessFileStore.java +++ b/src/deltix/util/io/RandomAccessFileStore.java @@ -9,6 +9,7 @@ public class RandomAccessFileStore implements AbstractDataStore { protected final File file; protected RandomAccessFile raf; private boolean mIsReadOnly; + private long mMinSize = 0; public RandomAccessFileStore (File f) { file = f; @@ -18,11 +19,30 @@ protected void force (boolean metaData) throws IOException { raf.getChannel ().force (metaData); } + private void setMinimumSizeNOW () throws IOException { + if (mMinSize > 0 && mMinSize > raf.length ()) + raf.setLength (mMinSize); + } + + public void setMinimumSize (long size) { + mMinSize = size; + + if (isOpen ()) { + try { + setMinimumSizeNOW (); + } catch (IOException iox) { + throw new UncheckedIOException (iox); + } + } + } + public void open (boolean readOnly) { mIsReadOnly = readOnly; try { raf = new RandomAccessFile (file, readOnly ? "r" : "rw"); + + setMinimumSizeNOW (); } catch (IOException iox) { throw new UncheckedIOException (iox); } @@ -41,9 +61,11 @@ public void format () { try { raf = new RandomAccessFile (file, "rw"); + + setMinimumSizeNOW (); } catch (IOException iox) { throw new UncheckedIOException (iox); - } + } } public void delete () { From f7167cc11e991cec6822ed90ebf0b454f288ade9 Mon Sep 17 00:00:00 2001 From: gene Date: Tue, 26 Jun 2007 18:45:39 +0000 Subject: [PATCH 0112/2572] --- src/deltix/util/cmdline/AbstractShell.java | 64 ++++++++++++++------- src/deltix/util/memory/MemoryDataInput.java | 30 ++++++++++ 2 files changed, 73 insertions(+), 21 deletions(-) diff --git a/src/deltix/util/cmdline/AbstractShell.java b/src/deltix/util/cmdline/AbstractShell.java index 1c3eaa56..fbc500f9 100644 --- a/src/deltix/util/cmdline/AbstractShell.java +++ b/src/deltix/util/cmdline/AbstractShell.java @@ -21,7 +21,16 @@ protected boolean doCommand (String key, String args) throws Exception { } if (key.equalsIgnoreCase ("set")) { - set (key, args); + int argLength = args.length (); + int delim = 0; + + while (delim < argLength && !Character.isWhitespace (args.charAt (delim))) + delim++; + + String option = args.substring (0, delim); + String value = args.substring (delim).trim (); + + set (option, value); return (true); } @@ -54,32 +63,49 @@ protected final void runCommand (String key, String args) { protected void run () throws Throwable { String [] args = getArgs (); + boolean exitWhenDone = false; for (int ii = 0; ii < args.length; ) { String arg = args [ii++]; - if (arg.startsWith ("-") || arg.startsWith("/")) { + if (arg.startsWith ("-") || arg.startsWith ("/")) { String option = arg.substring (1).toLowerCase (); - if (option.equals ("do")) { + if (option.equals ("exec")) { String key = args [ii++]; String cmdArgs; - - if (ii == args.length) - cmdArgs = null; - else { - StringBuilder sb = new StringBuilder (args [ii++]); - - while (ii < args.length) { - sb.append (" "); - sb.append (args [ii++]); + + StringBuilder sb = new StringBuilder (); + + for (;; ii++) { + if (ii == args.length) + break; + + arg = args [ii]; + + if (arg.startsWith ("-") || arg.startsWith ("/")) { + option = arg.substring (1).toLowerCase (); + + if (option.equals ("exec")) + break; + + if (option.equals ("exit")) { + exitWhenDone = true; + break; + } } - cmdArgs = sb.toString (); + if (sb.length () > 0) + sb.append (" "); + + sb.append (arg); } - + + cmdArgs = sb.toString (); runCommand (key, cmdArgs); - return; + + if (exitWhenDone) + return; } else doSet (option, args [ii++]); @@ -107,19 +133,15 @@ protected void run () throws Throwable { int ws = 0; - while (ws < len) { - if (Character.isWhitespace (line.charAt (ws))) - break; - + while (ws < len && !Character.isWhitespace (line.charAt (ws))) ws++; - } String key = line.substring (0, ws); if (key.equalsIgnoreCase ("quit") || key.equalsIgnoreCase ("exit")) break; - String cmdargs = ws < len ? line.substring (ws + 1).trim () : null; + String cmdargs = line.substring (ws + 1).trim (); runCommand (key, cmdargs); } diff --git a/src/deltix/util/memory/MemoryDataInput.java b/src/deltix/util/memory/MemoryDataInput.java index 65d5fd13..987d4311 100644 --- a/src/deltix/util/memory/MemoryDataInput.java +++ b/src/deltix/util/memory/MemoryDataInput.java @@ -13,6 +13,24 @@ public class MemoryDataInput { private int mPos; private int mLimit; + public MemoryDataInput () { + mBuffer = null; + mLimit = 0; + mPos = 0; + } + + public MemoryDataInput (byte [] buffer, int offset, int length) { + setBytes (buffer, offset, length); + } + + public MemoryDataInput (ByteArrayList list) { + setBytes (list); + } + + public MemoryDataInput (MemoryDataOutput mout) { + setBytes (mout); + } + public final void setBytes (byte [] buffer, int offset, int length) { mBuffer = buffer; mLimit = offset + length; @@ -31,6 +49,18 @@ public final void setBytes (MemoryDataOutput out) { mPos = 0; } + public final byte [] getBytes () { + return (mBuffer); + } + + public final int getPosition () { + return (mPos); + } + + public final int getLimit () { + return (mLimit); + } + public final void readFully (byte[] b, int off, int len) { System.arraycopy (mBuffer, mPos, b, off, len); mPos += len; From bd1627f74ce7bce153e7fdeb9ce93cc0405f460a Mon Sep 17 00:00:00 2001 From: gene Date: Wed, 27 Jun 2007 17:34:04 +0000 Subject: [PATCH 0113/2572] --- src/deltix/util/cmdline/AbstractShell.java | 2 +- src/deltix/util/cmdline/DefaultApplication.java | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/deltix/util/cmdline/AbstractShell.java b/src/deltix/util/cmdline/AbstractShell.java index fbc500f9..ed560a25 100644 --- a/src/deltix/util/cmdline/AbstractShell.java +++ b/src/deltix/util/cmdline/AbstractShell.java @@ -141,7 +141,7 @@ protected void run () throws Throwable { if (key.equalsIgnoreCase ("quit") || key.equalsIgnoreCase ("exit")) break; - String cmdargs = line.substring (ws + 1).trim (); + String cmdargs = line.substring (ws).trim (); runCommand (key, cmdargs); } diff --git a/src/deltix/util/cmdline/DefaultApplication.java b/src/deltix/util/cmdline/DefaultApplication.java index 5793066c..631df256 100644 --- a/src/deltix/util/cmdline/DefaultApplication.java +++ b/src/deltix/util/cmdline/DefaultApplication.java @@ -276,11 +276,10 @@ public static void printException ( * Prints out a standardized diagnostic line. Handles * known wrapper exceptions intelligently, such as, * for example, prints out the line number and position - * if a SAXParseException is thrown. If the debug mode includes - * trace, the stack trace is printed out. + * if a SAXParseException is thrown. */ public void handleException (Throwable x) { - printException (x, isArgSpecified ("-trace")); + printException (x, true); } /** From f8b9cb5162c9acb8409323e702fc633742b47deb Mon Sep 17 00:00:00 2001 From: gene Date: Fri, 29 Jun 2007 17:22:15 +0000 Subject: [PATCH 0114/2572] --- src/deltix/util/Util.java | 36 +-------------------------- src/deltix/util/lang/StringUtils.java | 18 ++++++++++++++ 2 files changed, 19 insertions(+), 35 deletions(-) diff --git a/src/deltix/util/Util.java b/src/deltix/util/Util.java index a84fab50..a5448785 100644 --- a/src/deltix/util/Util.java +++ b/src/deltix/util/Util.java @@ -274,29 +274,6 @@ public static void close (RandomAccessFile wr) { } } - /** - * Closes a Writer without throwing an exception. Checks for null. - */ - public static void delete (Writer wr) { - if (wr != null) - try { - wr.close (); - } catch (Exception x) { - handleException (x); - } - } - - /** - * Deletes a File. If fails, logs an error message. - */ - public static void delete (File f) { - if (f != null && !f.delete ()) - LOGGER.log ( - Level.SEVERE, - "Failed to delete file " + f - ); - } - /** * Closes a Writer without throwing an exception. Checks for null. */ @@ -541,15 +518,6 @@ public static int arrayHashCode (Object [] arr) { return (ret); } - public static boolean eq (Object o1, Object o2) { - if (o1 == null) - return (o2 == null); - else if (o2 == null) - return (false); - else - return (o1.equals (o2)); - } - public static > int xcompare (T o1, T o2) { if (o1 == null) if (o2 == null) @@ -571,8 +539,6 @@ public static boolean xequals(Object obj1, Object obj2) return (obj1 == obj2 || obj1 != null && obj2 != null && obj1.equals (obj2)); } - public static final double SMALL_NUMBER = 0.0000000000000001; - /** * Given a Class object, attempts to find its .class location [returns null * if no such definition can be found]. Use for testing/debugging only. @@ -1013,7 +979,7 @@ public static void format ( } /** - * Replicates the String.hasCode () logic for arbitrary CharSequence instances + * Replicates the String.hashCode () logic for arbitrary CharSequence instances */ public static int hashCode (CharSequence cs) { int len = cs.length (); diff --git a/src/deltix/util/lang/StringUtils.java b/src/deltix/util/lang/StringUtils.java index 33fd4100..247b97b2 100644 --- a/src/deltix/util/lang/StringUtils.java +++ b/src/deltix/util/lang/StringUtils.java @@ -106,6 +106,24 @@ private static boolean replace ( return (true); } + public static int parseDecimalDigit (CharSequence s, int idx) { + int d = s.charAt (idx) - '0'; + + if (d < 0 || d > 9) + throw new NumberFormatException (s.toString ()); + + return (d); + } + + public static int parseUnsignedDecimalInt (CharSequence s, int idx, int len) { + int d = 0; + + for (int ii = 0; ii < len; ii++) + d = d * 10 + parseDecimalDigit (s, idx + ii); + + return (d); + } + public static int parseDecimalInt (byte [] bytes, int offset, int len) { skipSpace: while (len > 0) switch (bytes [offset]) { From c053ecb3e99cde3ddb498d8c81ffa1083cc0fd9f Mon Sep 17 00:00:00 2001 From: gene Date: Sat, 30 Jun 2007 13:39:23 +0000 Subject: [PATCH 0115/2572] --- src/deltix/util/memory/MemoryDataInput.java | 110 ++++++++++++++++++-- 1 file changed, 99 insertions(+), 11 deletions(-) diff --git a/src/deltix/util/memory/MemoryDataInput.java b/src/deltix/util/memory/MemoryDataInput.java index 987d4311..11046c0a 100644 --- a/src/deltix/util/memory/MemoryDataInput.java +++ b/src/deltix/util/memory/MemoryDataInput.java @@ -1,6 +1,7 @@ package deltix.util.memory; import deltix.util.collections.generated.ByteArrayList; +import deltix.util.io.UncheckedIOException; import java.io.UnsupportedEncodingException; /** @@ -12,7 +13,8 @@ public class MemoryDataInput { private byte [] mBuffer; private int mPos; private int mLimit; - + private StringBuilder mStringBuilder; + public MemoryDataInput () { mBuffer = null; mLimit = 0; @@ -200,26 +202,112 @@ public final short readShort () { return (ret); } - public final String readString () { + public final String readString () { + CharSequence sb = readCharSequence (); + + return (sb == null ? null : sb.toString ()); + } + + /** + * Uses an internal buffer. The returned value is valid until the next call to + * this method. Returns null if the string value is null. + */ + public final CharSequence readCharSequence () { + if (mStringBuilder == null) + mStringBuilder = new StringBuilder (); + + return (readStringBuilder (mStringBuilder)); + } + + /** + * Returns null if the string value is null. + */ + public final StringBuilder readStringBuilder (StringBuilder sb) { int utflen = readUnsignedShort (); if (utflen == 0xFFFF) return (null); + sb.setLength (0); + if (utflen == 0) - return (""); + return (sb); - String s; + int c = -2; + int char2, char3; + int count = 0; - try { - s = new String (mBuffer, mPos, utflen, "UTF-8"); - } catch (UnsupportedEncodingException x) { - throw new RuntimeException ("UTF-8 unsupported???", x); + for (;;) { + c = readByte (); + if (c > 127) + break; + + count++; + sb.append ((char) c); + + if (count >= utflen) + return (sb); } + // If we are here, we have broken out of the previous loop and there is an + // unhandled escape character in variable c. + for (;;) { + switch (c >> 4) { + case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: + /* 0xxxxxxx*/ + count++; + sb.append ((char)c); + break; + + case 12: case 13: + /* 110x xxxx 10xx xxxx*/ + count += 2; + + if (count > utflen) + throw new UncheckedIOException ( + "malformed input: partial character at end" + ); + + char2 = readByte (); + + if ((char2 & 0xC0) != 0x80) + throw new UncheckedIOException ( + "malformed input around byte " + count + ); + + sb.append ((char)(((c & 0x1F) << 6) | (char2 & 0x3F))); + break; + + case 14: + /* 1110 xxxx 10xx xxxx 10xx xxxx */ + count += 3; + if (count > utflen) + throw new UncheckedIOException ( + "malformed input: partial character at end" + ); + char2 = readByte (); + char3 = readByte (); + if (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80)) + throw new UncheckedIOException( + "malformed input around byte " + (count-1)); + sb.append ((char)(((c & 0x0F) << 12) | + ((char2 & 0x3F) << 6) | + ((char3 & 0x3F) << 0))); + break; + + default: + /* 10xx xxxx, 1111 xxxx */ + throw new UncheckedIOException ( + "malformed input around byte " + count + ); + } + + if (count >= utflen) + break; + + c = readByte (); + } - mPos += utflen; - - return (s); + return (sb); } } From a1e6c37449620db8a2ca5e016fe572f3be9382ca Mon Sep 17 00:00:00 2001 From: gene Date: Sun, 1 Jul 2007 13:02:34 +0000 Subject: [PATCH 0116/2572] --- src/deltix/util/io/IOUtil.java | 65 ++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/src/deltix/util/io/IOUtil.java b/src/deltix/util/io/IOUtil.java index 2fe46a90..2b7174f8 100644 --- a/src/deltix/util/io/IOUtil.java +++ b/src/deltix/util/io/IOUtil.java @@ -246,6 +246,18 @@ public static String readTextFromClassPath (String relPath) } } + public static String [] readLinesFromClassPath (String relPath) + throws IOException, InterruptedException + { + InputStream is = openResourceAsStream (relPath); + + try { + return (readLinesFromReader (new InputStreamReader (is))); + } finally { + Util.close (is); + } + } + public static String readTextFile (String filepath) throws IOException, InterruptedException { @@ -272,6 +284,32 @@ public static String readTextFile (File f) } } + public static String [] readLinesFromTextFile (String filepath) + throws IOException, InterruptedException + { + FileReader fr = null; + + try { + fr = new FileReader (filepath); + return (readLinesFromReader (fr)); + } finally { + Util.close (fr); + } + } + + public static String [] readLinesFromTextFile (File f) + throws IOException, InterruptedException + { + FileReader fr = null; + + try { + fr = new FileReader (f); + return (readLinesFromReader (fr)); + } finally { + Util.close (fr); + } + } + /** */ public static String readFromStream (InputStream is, String encoding) @@ -314,6 +352,33 @@ public static String readFromReader (Reader r) return (fileContents.toString ()); } + public static String [] readLinesFromReader (Reader r) + throws IOException, InterruptedException + { + BufferedReader brd; + + if (r instanceof BufferedReader) + brd = (BufferedReader) r; + else + brd = new BufferedReader (r); + + ArrayList lines = new ArrayList (); + + for (;;) { + String line = brd.readLine (); + + if (line == null) + break; + + if (Thread.interrupted ()) + throw new InterruptedException (); + + lines.add (line); + } + + return (lines.toArray (new String [lines.size ()])); + } + public static void writeTextFile (String filepath, String content) throws IOException { From 47acb154ac8bd662beaf6abd05cd1b802aaca0fb Mon Sep 17 00:00:00 2001 From: gene Date: Wed, 18 Jul 2007 20:07:09 +0000 Subject: [PATCH 0117/2572] --- .../util/cmdline/AbstractShell-usage.txt | 6 +++++ .../util/cmdline/DefaultApplication-usage.txt | 5 ++++ .../util/cmdline/DefaultApplication.java | 24 +++++++++++-------- 3 files changed, 25 insertions(+), 10 deletions(-) create mode 100644 src/deltix/util/cmdline/AbstractShell-usage.txt create mode 100644 src/deltix/util/cmdline/DefaultApplication-usage.txt diff --git a/src/deltix/util/cmdline/AbstractShell-usage.txt b/src/deltix/util/cmdline/AbstractShell-usage.txt new file mode 100644 index 00000000..120eca10 --- /dev/null +++ b/src/deltix/util/cmdline/AbstractShell-usage.txt @@ -0,0 +1,6 @@ +Shell Command-Line Options: + +-set
    0ST!LAY1^YtWav=)NArNdfq?M;>p8&;3?Ml1!+u@? zWwbYSl&Y3-#6czvIU7n;J;a`oEW`v75g*cw?4vp+^^4v@S`)3f#N!)(wU+^;Piz>uf2>7_Bgd;O2;G zFC7WWUu?$Jox^oCa5^e1j1k*Z>}aWRE*(Z-wav~~xXLNVR~c5J)jeyEF+8J)F% z3=c}D1Zkb74!5d_sHcB@;gi+jD}wfxQUvcs9#q?&htkmk zQx9E~_|7t3-vL0cUCC$dT zgo6A8l)fR!QvC?-ldB-uBx;DI?wO2M$)pfDXYRYgQ-1TvDp+Q(3K1Igz@%xuaTDdn ze}-82hO9ERfkB$i*V6rIbaqIQYvFZ3Was?+R@cZxiLTh-)oMd(d{J z&cn=GaRtw_QWRm%O9ykIc5mM9KmYvyX3nqE&a+wKo>1J)W0i~bMTe^5JV6hC1w)YWIGPyCLN(`U1f z{8kb)ccAp>Hl57sttw^)^OdJ3Z!eOo$Aln){&)U2jJT`MaG&}e`>$^_{e}31$lgSN zP!FAZPt6|oe31S4o+#&MH%<>}sQttqx6^A4%K^U2XQ4l#kNoJ1>!-jVJnZGLGS{~x z-;ZX(XJpn_CD_pp49-aJ#Vb7MPx#OL-42!?N$a=x=+F6UeTcfnYd9f65FHkUDvK3S zUU(jzP{%Aw{zbu9pQGWaQ81m%I4U*3GTdT$m`bKmUP5jBk*v#`ZvD*TV(&br|@9VeKw=5 zZ=8?(;!SNiw~ooPQ&EVbuE5>LAP;bPE%K?t-`dg&5yUh-86``Z`3u**#CrtLT*Bn` z0=_bSWYg-cfP0NR+lJS2Y?Hy@G0kP~YF>3I<38ZNu!f0;&6887OMhiT=>*`)e1?a5 zY|#}xc4C}xcawntd(Wb*&}B`VULSmGm)zhrlr>8tlp7zH(Xi91kPSI1?h zGBTWOV>>dfCBxs7uHMdUB;A~8>FY0g(;A%b<0fe%xehdU+#1zFMh>?ok;(&2tf#$O zye&rPJk#prk4sC7$+6{L=5uWP>?TuMYRB8BqgbkE#-#J3VvUo|4}Agt%MFagp8TmV z;hnZqie7(!=2l@@wJ?=5xk+hBMTIj?F2+CaY*;&wH5Z=SGSODMz}j)8=k}iFGgc+E z!whPVij}3i>kH{#Cu|e!7?h4!aVZER%u8{P=ZcQjI_=J8N>o_3R{x!DI0tu|h`K^g z-z40~bqzZiq2gM}nN|R3yWd4UmQ;tKTQ={{SIcI`k2#wp@FjV-#lg z)oGAy>WX3{FcOhpRC1`KW2pQ-)SSAMIATt*k4-gftLb64x~Vdls4!V^PV(q?^h|b$ z=0NoTvEDeBVmRCm%Fa$WvJ`bxq=KuY7Ecb?^B7*AKlE724BZ4Q(gc%cb!9e~w$xS8 zk~zwZGdj{A%bGBl6G4xP$ibmA$`6_O@}p0TU8X!+86{HI^b>>BSE__yr=+S^Agov! zHBz>Om65e%>~lGGQ`#YH$ngC6ko_d{n?PZYxT2woY@e+}n#-w}raV@1-B!n!M74EV z%@21|b_tV1t{nx~XL?ZMojeu4=|b7dx}+14b;vp<59_rf@=BHFTW69)mfI287?L)y3GAcALjGbqAF z8oT+4p(7y&gW?4Tcn9QOk3->eWffp^>q-c&(;Ie+6Fnu7BV){LmVw8Pi_=Nxd^8P-Ms^dC}bOmovPyi5$Gd@puu6~>N=fyloi@Y`&6k$l#EVusw=Mw zQSRZ_XWVBX)uiNa3)hW%GTM2y-ktJQrG0>T3SyLvzAAIQV|YY{Sy}TpByoa4)Y{AO z8nD{!mR{*c+0G{$a(u;f1Zg=`!g`9eY_{#QW6e2mplzwQ`;fH`z^KKeDIr)zsHd&Q zw;0`>($91~QhghCDSM}^3T$GkY`w%!mF}-?Y=^1YE~u;i^5=AdN?ED#>W9Hi zvHo$@Xu;PTH)mnOqoSC``hfkjig`bCI>-Im(BQH<@aBvwZpHeOG_L!h=d;MZ+Fke! ze8ul+)zFL!T_sJrR)1mHofUt)tjY&Gs07!2`aV@BA5O`&MxkIpElU&!1Pu_d8fH1^ zzz3ZNY*{m-T74s^;dYu8YMNM+!}(-GG}Z0E>80~l1bf?_?+aYeeSpc*l6{jRChFjW^$uf(+eK2Kk^;WWO6 z3YnjXdDY=q+lPfl@=;k)RnzJYSqRY}bgl)CHX!50!?v2xk)98x~sMYUPc|7$} zTky*;uv&pwFldXLjsbu^FmCMLJ6_{=JJ}5Jv9tXByx=FL-fpmdAL5dAmCV5=cQ>j4TJ;c&M1tT_53@-=W5lK8C_&Tt`z z7_acF^S~F2*exB-Xd_192%%4wckbRcdi#s&wQnL`D&3?Z_!FQ9xHsxIW;OdljlN-* z<)Zs9_&rpY7cjBA%E?5sbAD0X+5kdbb+`9O)6!lICoj+*fAs@am>63RyxtIfa|p0I z*3Vyf$Bjrx9iJ4m!#lWC6Mw2x=hAKH^Q0ZZ?pCIDWIwMCZ;rvc4#Syz2!|ciRSoP( zVdxK>6^Ab*#^?cy2@&i{?J{kFSGdq^rfnBr5ImSY&4C?It4|aWcAK*7ZXqu^Bin}{ zUIQOct2^7xe?WcE9O4|+$HJz9Ak&I)DTSCs2};w~nI|JyaNTOChT&8Cxio%V5cq}m zvBY`9`>7Yd7Az@V-z!(AUG4)l|7E&oxB+Mbx5B%Iz@q|Yv9GOt&_bb4@vmXv|31Y7 zt&EMZa%Ak<$>&MO5$N^R=NOP6K;E!k8uoQH#l%PV^un)P`8qvL_Vzeq6bmil5nunU(#894 z!ap%*M<4lRvQnM3VI63HcHX@ry+H zB1$(BB-%pRI88M}q?=zu33a}-Q(m}-fZd>U0>od&NvpQzyJM9&v{)(~QV`^KY{8Y1 zvAw#ox}=j)zM&mbV4-(%(;!I>K!6d=I48GyD9%G00mX+z8H6`6TZ4fta4nbjQyLo# ze(?VR6aVEBzija{aQ~fUzN7>KB1qh$$4%^JhX6qOs2nx(lQXAtr|S@a31KWFhMT~1 zV@a|Ea{~a zpO{cHj}KKqGskfQrQjA=Gmy7uJnCLjMV!KWp1>JX2cSCRroa^kPH$ClB}y3;J~hW! z!6zS{{sYjaBLzTH2gCEdLo?Dx?J`5W0OgTsC)Fsc@EZpmTx`y z?UPQ(EGs~|(pxEf@&|00EdM>eYXNG$6@{{gSE#(T-HZI{66T|eFOf2&6|mg|)HsO$ zX>sh#9rRoN+N8X9J91>lE?6q|+oqfegFsg0K+BWUK$7Lj^?qftlnF)#ULT8|*I;5S zzoiTI23;g}KG-COeixma0R7bL5#p-^0>uSl0M7l0DX_X*eXic-!@Zm{oXictH zi6+b*S&`|JY%djO$}D6an5oOAmIo7i$<~%XJ)WA$Hu8oge>-%sqlH@=mT1}`XJRQG z3>1quc3cn`HSrQ9owU(vpLi!(YfCXGEuMCq%Ve9E-sQ?)!U$qODb>hxn9o zb*r@k&rCTS(e#9i5cuW|F0xA7Ga#WYXx3oaIOaH5l+Goyuug=HrlfMpvG21QAv=nS zKXWLrNhSt}8P>5!KNtA`?3svV4sh=ow<^|}@*$NY8cLhotf5nBY-PpL$;3pSLaGFV zYX#jOPVGvD$(!ys87uoV5vO58(h;pR%$Ll1mQLgCSCKg8yiGKP_GbENF)k&<47O?f zPm*Gal#bDObL_ff!(l&J`xCR--m)l!j7pe!^W8~g2hVFYp=m$>VX$JUIdvwcr5xQ9 zgN2mKiA@6PD+L&)Y5glXmzOAICpOx_7S=bRFRaqWb@^5 z7`r8zf(HI|RqQ&6OeUne zPhN|a5Yb5;#`twffJXax951TRt+8#`?L=Y>2!;g`mMxtJS*R_} zjC2^%iz6h8$($?d5OV7W!p~ipElH4ojRWV*Ei-~lhyoBF0Ng7x{n*a57Y74@sL|wA zu)l4VD)vp48)&@z+5K_Axp*%}hBZWW?1o6&t0l1zLy(?W(pg;nBTtC!yXcU;$C(Lg z)mR35=A@r`URITWWr@_0WBjK$jtltkqAVFj(!x<4oNR_FL=7Vl`@2A^c#BN5^7MIT z^GC-zYVl@C0f2P6sTlWB?nOg2#Nii$dbt;j8#Svd*!%nE~JjI>(?I5SX7;{^0cwd z;hpmyHQqQc*en$8ZT43s&VaJcS$f7skz*~mm4`J8z=O!J)z4JR`Rd0^nU=2eukzu` zb*zk{#IB14rci@p!t!se<2LSmrS@~Xv_b+|qda64hl|kaAG!3UeB^m916zrCO`67X z*`TGR-9ahiTQKsv7v+0P+3kD-I;o)XJ0({)*TzB#T5b~?6NiedDcpgIGLJFK6P-&+#3mviKZj ztLo0>!y~EYm=_u#$k$bR2j^WdrniS($BVC5)(R82lA`hj4M3$bwhA@3)lpIlBKosi zQ`V8v9bGz=9gA8)AT&+woiN6JPfN8u_OHwv!2Kf(*wbaE@GcqK-mxq9M!!~iwe1p1 z_fqMSV`bYU2P>A!=0+N+!AH7v4zS%6Y`?D!c=8Ge2Cnf#| z0_})We{y?{DKDmmsqIC3=ybe}U7f}DDTH{&lW7!QEw+f2vlU(`_$zLnmA|_D>fEg> ziztFMU0@)kmL2o5cMa(lFxjnyk$m{&UpSL;jzLaKag_#lC$8(|xQ(c~d+5WJ=_T&( zAYn|(d6M*Yc_}Cc@R6iyic6vZl}pOLGR2c`2mVoI9eml5ftT`fnF4~=i|52`$-gs$ z4p3+qp-PDNB4x1yIyEQa&7}>acj!?WGty%r6W#N#YlD^=TLq)C2gZRfB0`pX?aRV72nbC8hs@J^v#CM%_^}K zI%FngM^}aSLY@a{SNy+3@Toukj&<)^seI9H2XALsHjv9<0^hU`nGEZPhM{@x&QkDoevT70g& zroAVP?Vq2qZQ2daJ4WJbYzb2m&thEG+4DWPtXZt`4MgU3*;IOIKTG0~cJ-_@NIZzS|;L1VnE zlkQ!$^-V$yRbf%hOe*4@Ba}7~p7R$Ack>ol;~w5faWXCe?YXEWffJ1ElJWG+=xp)4 zOC^#j#mur}B;)fOPQc=d|2E`pEGIugh^_Qnvp~}KJH<08Sb{x_ryUOSa{XuCmt643 zGt)2H>jL+Em#OphEt;W3bw^QJ;Ry=cng-Td%GgC8D43Xm67c8WD;JJW;FyscpeIhW zonG^~vno~qJGI!u8w(4@>-qz<3%55+t5M0yJ#j4?aXGPFeu&3=Tc6_ zMV>N72A(p+lZ?8gDC4BIfD9`$WFH--KQH=NGg!?z(f9L>PKfp2*~$W%TV9_pwE z+?N+1u;rC1Lyi?#Q&zuE_%N*&#A8?m>6KBfY5)gBR^}sCo8>GrE2+^^Edkd&dspmL= zUgA{hBUc-~sL+7^BFF!ce-MXekTVd;T~dT^KWbLy6*Ob;W^oBUYC=u+%qgyClQTI-1a6~_Hf%&HGuE?g zv3#gKhAN-RL-FI$0AiXYBWM7dxdH}wdzRs`VSsx|iO!>8V_0|N`u}mPb%f)UjQP8@ zf1+YTEk14VV0`{_NTAHh4h9RfGFpUD*3;z_XKmV|68!w&Hb(@i)0f&68bs^NZ<>sV z{!?Yss#0asm8+&)HtCay29ura9y2qyo0?_BeJIJ$k$#65lYkf}D6*gS`%4=Tx(#%( zZ9eRW;6r72D+w7NBkta(3-*`El5H-*bt;a%7ZCl)W;`s>tSBdlDOSdQlc-*Soo~`} zmxi=qwkaENQ)*M@XCM0Em!>awS(4y3awAbl^TiZc{B{k_ z(B|usRgo6r(mz4Kj@AiIXcGL5V(zCew>Y^H7_YEcoiCOBS7lV&>CNf$ zO)_<#2}-5Z>nwuhUT0?Hb7pq`$!nL*8vf2Tr{|VL$p>D`LEbkp!I||zxUjJDhN?n~ zW9*d1IIXa=ZN{}lxz#;Nwf{Nv`7XyxO`c0ER@O%|)+<~!_cc5hE|e?)GoO_~RcZGX zB>Y0a z*V3=GdN7YaNPR)H?-t?xuGG5sS<4ZcK<)L`N9$tDDZPCWw~ml)=!E$Q1TiD`j0cDi z*62!%YwZS~Uix+KwWk|^7)*pYA`u_jqZ*-!f5d%Wh{wwWU3LP}*TMrleiR%)TnN2e zF*~1(>Te8&Mv(SA&;(r&JD>2iNZU_9nVq3S=qG>FKe4R&>1W4xT0%_csQvQsH>5q2 zbOTbXEXY4&bwg6{`!?`rV`kk}e7*XEpTsby0V4c$y!>HX1J_xA=3u)SEw)Cd119Pw z2iw7v9$(GfXkzElf7c{PufnHpg-JB^Omx=GCFzwzmfOsB)r(}t%(MaS@0Xg z|CH*?6)Eu*PM8E3a~~!N!$J0VZHR}!PwNGl6o5cG=aL`+Z{VXyE#%Mh91t&~xsJ}? zbs2%Dbf*vNc7ort!ZYUFYz*_VXUU(i1o)CV&b*fS=VCT-*ZL1SRDN56=6vW}szT!p zry#}?2!f}?GjAY+r}%=W2&MgBkec`f)vwGHK9SyUa%m(i=bC?on(=nLrB3;;qo-bgJ3&KKnBd}|ZjJ^&bk{NI)z-(T@j5qit;e{^55GlkQ8T+S4&cCHaUCW|eoeYVJM%L$|GS2ZUVQ)c5SRlBq7jxp?_)|3qmBZ-_P}=bs3E z;ZX!_$tl~bkgTlD4Y^^_t0OSql`x&nwEd~0giQ~#WbVJHQwA{^j4N4B4v~VKH06i( zbUsT{?VRFHQ`1#EU`@Zi`Ty@G+rKdV^L%I^AS#TX=SM<=ldv<1_#<6_@J3$7{N|7K zxqIb_g%b@VgxmpB#gGV<5yxHk>jmiuC4}NU=tqll7Ug10UyO4mv00l-Ym{-DcaCpN z+T?&bmCm?wzV4jse17R}Z=jJ1xvk;fIo*2h`t-Se?;1|{_IP0g${0XH<+lG9KItB& ztxJ`XLdj8(FYX_418@YZx!F(h?U20Et=eO48IJM#bg%MXE-Q^yM|JPy>5v=5z7Ykp zQ&hP0+paVu-y-tpQlYa;7++V}h;gHE7wF~wbWZ{8)Eb2D5bO0)sT_J&rWw`%Lnv3L zZrz9pLFw3zK`1R9gitYNAnYbPyd!Moxfo8wk14&`S7-%D19~}8WA^*0`21taUoiNp z_mJI%ddX3}B?sAf%J$}8BJp#QSaR<7@1eU0_`4|(a^geu;v=)~_Q&IA)jnRz{c9w& zu9C->KU;*qeEVbU%3sjBs&=@2z15Haa)ZyeAgv$rgE2QosQkThs2|dUK)!VH4HY#_ zofZ2x`T((Q!0u+}CT@t=Go16&6C`L`^eOp+y|i3p@Ozap3*#D*{E{h|VsdtE@Pqo= zZ%EYGe{QgiuC6YPX0OVv6z>q++~D;yhYh)4B7^G%VWmyN`UX0mv3@m^IC+iX)#iOC z62mbVqrX1ICt@Yj5qa4P$qO8>fqjO!{&@^S-%I5X7I&#tRdP&1|erJwb1>|63xRIrpTbNOpJhb?7={$}3qLM!LmkN7mG3TR+y)mq%J~HKwrcC7ACXYns!iXeC6WwM;4>W0GwM;EFR-F{3A0a8;K9 z4y>99;hO1~Ln5^dZOkMWFmwM7RgRuOgCK}^0N1-5InAfCs=?lik+jxpmJBAkO4}SN zvoVPho9JU>WJiU2pP>B}h>8RjC399JMiu2AhNrf^gX+Jj0rxe>9+JiA!h*UuK4L?W z;VPQ+Nj|mlNf&h41mOFcbo5zm&b+5}Q;ug7iQXWacwkoTh;x?6Jyp1WJEm~M_RJNt zfFQc~V7(oSHmdEcNUU!au0rhjfentK!kHVX56Rw|A7ZAPbjsmx{{CsHV2;fze|2u~ z_U<#*mmfdXOF}UJKD~5#8cdUxT$IcCKGs)wx5W$hR~}&yH*4k)Gpl-wR4+g42h2B` z`q6HetVW6vqb^5Gzw5m*k?9$6<*%txfCSw1;N@JzciLsMMYvBJ>r%QTri1E2;lMjR zdK*v^-iTU5aS@HJvG*J8CYvf`onKjU1|G|Do^?89MEs@DpBEMdl5o~MhWtLcMG+`l zGtAcHUD;|>ib+z$a*8Bptnoo_%MPM376m#g6os;|KSa5qR5HpDgW>A=VOVvE0NITF zuDNaI*SQo~_1Ts<-b71K)H-QobO|3HF^gid-XyFN zGhwkw;}I41fhk0;be8=*$czm{UXwt}!zL7T*mZUf zqq)|x2Jc2u?TMMER6=ahgZ#i^Kn19ZIJqcA(ON~Jm0^{7N!Vk)>JHPLy_F1w0eXhK z!;;Z5EYP6*+SIv}`&)0QzSfgd_b~ zZXK~>3aL)I`#DD5#dI8*;iy0t!o_;;Luq>!u5{Tu!zyZu_MoAWWHnCz=t$ zh6p^Z*;0c;*TJHB+zNYn`3+9doih)Xa2&eINZLmaFHVu7Dpid~V3*ex7T3ujF(|6> zc6WmA2JS^mt6p)2npNXwfQiRv)y(;p@NvHPYM>53xlv6qgU$=DoY|tgmY?B@>db?% z?&~gP-zj&tnXXT7vQyo$dGfVCI70HPk1M+pDcNui)zMCnSx+Bqy_1^U-4-V!{pgiR z14|{I4t$8_97fEkBZWkcAL4b)F_@lj2D)V`Gk$ySKC3P{PD#zRYf^SZ*6GqREgNcs zS1R75{uE7rOvBxxx&eGB{z&4ruc0$xyl@^$3t&7^yNx$=+lW`tjdmQ*P1{)XMS$pj zxX-ok9wf#9?=j;J0CTK^sPYN90IeU&w0}f}J$%%4KE_<|nVM;CoVwSRq|T!3EO|ZP z<-cAXQ}ehnA|YZ_Vhagwb#itkxNFxEL^ZQt*(~PHDp|)!xXdos3w3Koug<|I%h7dC zea}JHEx4%GxL%=~?_lJe;#k0~#P74T9)btr17!>Z!3nMb?Ard4Y{8#et=PbySWR&N zP?+h-LKEUMXxEUFz;ddC{DDLMjj%=$(u%g;lhpFJ;)p|V^ayf=#Y#|Ap@xT!~JA%)=xaMqqZINekRMz#by~mdJV-Q#;Jbyvc|C>LtWo z>~e><&uky#Q^OxhpCl(+Sm+C> zAn6X`08UhpHH9GfHscbT1*8yE+kB+j?&wv~vOCfX=#GWS3dMRW=dbL^@#?9}3#z71 z;QAKQ@%+WXiaOLOeUNV(SQfB8Ol_vWGOrhHPAiMXtG7v4_3bg$37*$weMhj(#g zQp_#Z*Pj&U>3z++Lr~fd(M;(ew3yc2=u)H%0Q;hAg$oSbl^Oo93bLC>r)s7ufKA;)JI)bVOQ+zKW~y`lMS~xeV=zK7iVuQ z!s-LtglAah75(3d7`&RP3X?p_PWp;&YpZAfB8|lkE;V&rixdjhFhgg zMLpQ0>UQ}n*cq%{8T4J5)JtMxQ{=@ZZwaoOL|G2r-+1?_A-(~V)e)Fd^4i&Ac! zu60h!>b%tv%E$M1dC6arP_w@?pCs_f=7@YtA7ouLQV>R&NPnlns$1w`k8bwq&^_DG zJ>OBn##&&KO6xQ5$JmbTDqcAvc32{v4}SkYA&a18o}1b~>TrdGO9D24mK>HK%9m)I z&eEe|B}G%Sr532xs^+E2{J?m5m@*^*l$>!8R5e|@v4-`BS|^F6<=imegBUAszasTW zK>KLxq+6HM(Zs|xKff=qdSAJ}!o;Y1{tjifL?|VszOJbDOW1GGT7unH|5%{T-<}Gh zismwXQczN`30iMYZ-P_+y|vM5yP}6VLD}hK*ZCahVEeNb4px@&+6v7nCzL1jK%$`J-^74!`FrTl(&NlD@>$h~=>ke9ehT&srF8HY|ru=Ya*uhPM3lC0vVOri@n+VGz{j^Qe~y zJwOyB=}@eTL*H7}oTqeZ2jwD3u_8~>;v>kP)C&+S$J!$cg z3^t#vW}w*$tLFuB5XjyS!MGasS{S0)d{gkm{R|Dah({g7u;@$J6a%3AXr>4V(>R3V z6HsQwndd-Y(Dn7SVkt)TsX3w{NL29sD0xV5`&jUr6664y#t$t0J}D>kSD*f#K>~55 z;9Y?MDY0C_eJ|h|smnn`BCtfNp{}qo5>o`ht>=A6XcS~mr1NLp)hU!(-b!kasPwsk z5M^JS3pc;RoL~VVG*5lD7o%d(koc-0_5 z?)`hoynt1`%(j-@x?LAJo$cXm?J*>Kpr&(NuzBT4W=6Q-y$-!Z*U=#ls2a7Kes@%= z^Q;SLNG?*Cou?|iczs7Mbf|9&bL6>E<-6In$p`)9UG?7OWPt&A_rFE(|}E0Sd1 zQW`2ef9dJ91e0;?tK77s@r4D43OlQ-XG>SZde*Kr`F3@4A7upzo0&TL{Zk0NPpwE-^;nRG4-R zqWGI2K{B=ywmuiMwE%o{j37qhz7RoN!B3h}P?2fGiBwz#E*6O~A{90sLg-%p)`>HtCF|P^9~-tkIfK?vaNMVIdR$LWTwZhPzZxwsyTptNBmvD6i2FkZG+tGxc_8u*=j%^~D^ceb&**G0Qekp}5@=_j}? z565jn;eFWFSHsBz33{n%mA&1V&S%HbSI*t6a<55y#bzAAzJU;^#}P&TE3Ft(Z$)r@ zH)q)+;w=(@CiNLuEL5{^{^w%epGCz24HFu@ml5{XQwLNqudPww zM)NlQ>>XOh&hy<@r=#(3X4s2rLMk-c0E5dBBkm|Jng-TTx6ItV(g>3p7J0KM=XzaM z_=PK5Uu76hnz1%K`aE^+CNa;E@(gz9`wg4hD<2QQG?B^A>^c62)3zW3_Y_{}Dx{a2 zd&30d+^Mzb`C-hXopu9!_R=kv9Mz(@>}YyFnCG(v_HzkCCUHnYS5`J{scQ|v3W&L=7v9FS<%h(q{^n()mQJZ0_8y~{#iRcA0Le7z9m z&hUzopN&@KNN<5Bcnuzt15D1XFC0E8wgVS0)|Z!d*lIKY-?o$PpOHmO&OF0_J1Ni~ znf~{|HqWmmuFq!U)IfBvEzQC#RitJ-V!dF)Xjk{=2ON1ey2Pdz1vtbS zhif2gIb1W{beSO6ZnU;?*)|IzbQ-_S++piKaIOcuOD7R_o@s&7i}$~|Hkd|~bR5N- zwCpXnY902)c^XSYXvszp0*+1eBZlpOho1}Ejy#&xT|6pG5-jl|aUw9u2+8)&DbEcP zx@%Ukf1wMmk1#Olcnoek&L8UbZ$Jj_v#Of1VJd2~7(41Dz=Cw43zxR^F)SpnD_Ah) zVzB|dV!Z|=>GC6JpSNS~reC+(u0PAjp4GtJycUyj=bU0ahvQz?L8IgE2HDi4gxUmE^qLf`pR!#HlqxxUILKWr{Lb zzyqF0xa!i(@Yzgi5b&z#`W3|<=x<4+@e|IlILJ1Uf(J!KeC|rv1JaFf#zc5w!f`-Z zEMss3;yz+k?g@pr*jsBJKvdFn<@pq-786*?W*NTr_pc)7Xp*3V`xcD6Yf)CKcuVg; zqT3~wj=@mI8q~?)1)r|k~ET;Xq z$H)?9V{sG0oZ)|hPX9BbCt{4({Xv2q*u^98GeX`#15PZIhx{iX?pG)wocpIvMNBzP zTjOZ%z4H^Mh`%~wp-c(q=tI3a8*dog>{&aIpG4j=FX zAATvfHaOf2q()rPY|<|J+*>C-u%!cOACe0Q3m++lk$itVW0-{qtZODG6Zq7p-1NX8WhC&?PgGpxR1ofSt^(Y6Q0 zEN1FL!-={qDkX+iNKZ@MxMj9*i!?{YI9lux{p21(3YUf^63khr5Ttl(ziY8r7aY^b zGO%2TF#!%t3NvFKT5i4K;=!9r8Z(m3$!bBPm6jO`lA-6OUG)N4E8^^sZRT1@bCp*# zk{lb5YxNPW`BiAJv?=Tl8>LN+h3P>Kn+s%{BeqDhh?@&p2}p{kK#`1M4U1sH*m$XN zzcHJj(7KHgECC)CO{br}zqIA6m4@pvS@&qpF8Z?3 zjVf#MVx)xReC(ThKxSxS&~PWJS5+4Xbr&*6Re){85dtY1YZR7=tPK@tbDmm=4JdGl zrg}8b9C@5&W36Pw-si2Dlz=(X9Lewbu}Q9q7roERu$!732lY+0gzTo3oeOfIz@6vZ zvH%SQr?oY#dD2Kr7X7tXV0FzU5FB_~pK5B5;`ErBJtSRR2AYC>rtJT21}GQwN+(z3 zTl%fi>y6v~()i1X&42f&NDWX{7#=s>x8-`tjhw~alDh`lG^m$YNfO`5qE^VgxD47&a0 zZp!>Ygx+9tA}-M%81<}#w)OGpo3x3^bD1I)m}7v*@;}YBdAnDyd8I= zlijoxCo1<`^(NH0yztYq+dZRsq4mI!4BOl+>SkOz5wuN5Ym;-Z?!1KBr%Ms%bpU4} zMbKd(%gYLW7>oY7MqJj^khm&Rq?3ic`tueRytWF$%n|;*mA$Efm#4Ge_0gQFDx^ec z&^UzfPO()5$p*g@atmR`my#>nv0U%(+XJ@WDB}H1^b1<73c6%|Pi{Zo=VaO+f^3ad zJIO%Py}4@m4v`{x#NH8F`igNAX#?m@vW3QYgx5Ee8u{DMtp~VrZv|D|MfpC;%FDbVmI&%Lh({4dW{>xO=NtT_)D)lVt1>ZhaJ|(4%&S?qnbObN12)zfU*fldsT;42I#IlS3`7YW_(=@V=?gzvTG2JG`@6(IJL<=j_l*Q zh3LV?YCNC@?IT=|wShB-!RVWmdUahxemF5*+2)g?RI1$zqE}59S3n=NE4x#qqik0Q zjz^&QdkmaN2J}Mvdd+juk?+bse9f0Mo3mrb`-AwrgQK*KNwiVin|P^rX{R<*XT|8>3l55AeK)tV)L zj>e!r5H9)y-y{iii===eB^|r}A|#o;X?6_bnqM>q!;|UTi{1LAa;Hq_ZxWep+Y^{~!+IVuCZhMnYiwY)Qxb35&OME+ zF2eF?tNvEe^vMP?FR1WCPN(Qvz?mfUVgz!x4e7ReQB4Jzz?fN2#!ViI7YTD-Y2<2` zbjdQs^|B&En5S}pQl_;_ zniwK$foC&zd~7r78RoDL)Han92X8)FGFpqq9IaeN;sTZv+W7jP!XXMF(sgq&!_QA7 zkOKJF$MO*v;HzEovn049XyEX}&eU$`5A2OCWX=fW_PAb;aQxs7@^YXgFi2w{amh1k z7U_R;uf0YNOi91ruKH8fAo2u}$PxE5GqhsXs~)EzRy;K;KvEw%B=E?(F*v~dLmcnS zPj|~tx3fSjz>lq3@+D9x`38$`NJ6Kd`Wu0yu`$?LD}u&-aEl`zW+?LEPZN`Z1mgE&#>9fQ4(k7HCR$EKzLdn1@uoZ@_=h8tp%{eqdgsuUkH+tcAGulJwLwb*7>J9@W}5FNMVt{6KmV% z9h<7u+7X#`Nu4XJNpcI^br<66_@A^{AxyRNv!2bxL_*WRqPnEgN*dG%p~bypk0eBa zP&dtn$t34!T*A{hAqkzZ{i5A`;=*rni8D?R25++yux;Q-Z*UB+oVTbCxJTMF@Bfw1 z@ZZEUt+l61egOd$g8%_>{LjR{lED*XmJt)E(_sLvGBSpfBFCcFP;cjfd5MeA_@usrckF&>l-M&6PKVf%%>vaHvEQc~jdD6ufz6eAy3Z+YDr`WK{kNk%`j06>u9YYLuev+Q(Ue za!M6k5)Rrme^X&V(bZ|YAG-fn? z0`$I0{0&%5H1_%ai-2-03i|Q_+0w{HQ`izJM@eVEIha3*PUB=k<12I$Ik?(A7(vX~ zC(aY4T9=$$Rq_F6i7;kzVr?+>7)MU?+m}ql;OT$aasFG%2tiisgtkFVU@YVYv?2Rn zi2uDL2Nj3K{8?YKA2_7^pOY-l96|zz6AGY4hEiMs1sED?>)&acwFG+Q`1u^Whj$9s88;ItlSB!o8ZK`ero_7UBaw2q8>4!a<4_RF z3s=s=5V!^!kt=3A5P+3d)*8Uj|a3U9BECemRv<6L6>)j3qX5~q;6PM&JZxycS)xeLZ;2Q zT&*;@Wy8T{t<_WBNS7Q|g|}B9u);fl93J$#`#)JLK>vL%cd|WY{huf*tb`hCkspIP z)=zdUJghWR+L3=AD_NBUEGjTuRkH;xi{$)*{^*~wFbir|Kd3YmQ+v};k?(-(>O(KR za~K+ddsWcFu>n<7wzX7F0xKnL$Za_$Zff<40R zZ}EX;B1hP-!eXl@qyToDRm0!OQTbyG@w3h@ovNc1M?R!_WD*2MD2aE;hL+x2NYGE& zri|Lt7^alEOi6|sQRriuJW2nol_*y-iWO93w3Mn$3KSI{h}he$PasH?Cjp@S>Jq%F zTpOip>3PhNA;f7uhXP?KsGTU&YsJMW;x2tfo?=a?Rh4L%#h#TKU`kdRI5Ze<)vD!b zpqwatP|YA~#fF-J5y-nWTt>mG%jXHrvyMNie=?>yG#D9Z4BPe@4zdW`b|e`l%VyQ+ z8p=hHgMmyYHC75J8W{=Cd;p#;c*Pg zXAVI3`MVx}%SMJFDz}z&OIK_%p|3e$gn2ED7?+|TpfE(Er%*?oKcMy`V$Sq*D^kAv@lt>lqqZ-c6a8qnvCh}iq=-HUKEl8DIhD*~9_gJ*&FLIA(rJM-IZa7#r0$hVogU>lc z-s)H#|CK_MaLgJ4mayF+4(ZM)pu9`UMLgC|qH)Za^JaNM z+J^(pd7Q9G&?vjq5UM}a=%W?dJRP3Ddtl^qcw6{idawTw=)iE1eD?>eZ6SaXSPMk~ zh+gNl=e@IgVUuG^=|aE#ZhCZ z(0%>BcZQbxqOjT9YCCw-pb>>g9d?hluGXJ3yL_%D4?eH|T>~9BXbHmZLvu0A3RYw? zB=j8&_9psUOo%wJhFifpuI^{!4dMs`J`ml;+uF&1Vb4I;mo`lzQpP>g3=9VyqB3{y z@{5k4lhd?ZB}r}3)ugp*_C(Ki?qLb9uwX}%%s#-TH8$8Bt+K7wz;Op*LeztI3nuvF z>Y{T9;=tzFI{$$4`efE|3VIEiEn)VJ%f^MDqfu5Q%@tqq9c3ib=^mi8G)?IMlr94F zSG+9a#X;mQj+^i2d|M9FqCZnIX%p>{QnR;BPPTk>bseK5CI0a$vS+R4)*2}VpI4o& zZ^g%YF=bi&lM6S(pWCv?wOx;7)ZHg`9NVgQW;A5S=(#!LXQ}mY-Lk81O{Fv_ z#uU~3H9x+T8Ll;RotFPuX2gjM*o&g_oF$*=2)89sejq3l5=;p94$U`npljih(lwUY zU2gIsBI@gU?XY}g*)idW=>BF^#x5i{jYwrn z#^ncE=TuyTz~@(*EK@=4PZBuB5CzFH5`X84P#L<83}noqjgYVx`$SprHyHRaixxaF^D8y;BzV{R%!kjQuhJ;t z5?ng{2|n61#Ac&r;gQmhw=CwP^FH3qL(I+qXoiRbq$nwua>FNww8q0bsF85!S7qn` zs$Fg+z6KGwCREwn%J#BSbCXa=k7%@=d8AX z*efc;*0o_Pk!vaM4T|n%OYbsSHOPGzZGz6ny>Pz=U@X0(eX`YM@GMP_f(N!&_XhQ2 z$E<%hs9YHxi^G%oP#?4T4TDvDwh5!IQ328e#+8sERpvS)k%N^O^QkIXxB4U-7%|}e zHZF0|vdor4#0pXW7-g!Njh4dgC!mJ`{@nb(Q5PYM7(<)QtO{%_p}op%qO=seSc)A2EgG>n`7xpf zvD=%4YT%hSfWgNrm&6ywu$EhxP5jn$Oc%ytBX~x}F?xKXoUItM>MS4EP%E$i%`6K` z^xO4qu9s_vDJ%@HYPQU7=_)$6`lVEsO&aYLsu>REsJbI8REE^;mE5C7%2+O)t5E41 zL;6}Pk#2wL`VZ3@A}(?WnKx8TnAKaDkZdX}BhqOJE6O=hDkU#$Oc<z(un_xFsoJDP=cyYmacEL(Filu(T+N!ZO+t_g)Wnmf=2@6Iy?&NSkP;1E5}68)(n#s)aq zhZ3*i<_2U$TQgLo?NDQahZFI}!EmyK5j@l;AiJtD)X}&PmL^pIxKVzYRr?~`%8EsB z8^MB6(7wWJ=Z0+rQ=CUSR2LGXw`rZDaq$B40muOkKvF>_+DWA^XLze|e- zSElLdHiE-9S;Jq8zO?prnsZ~bY|G73bhszDYAvH=*hPJ3u;xkP@{|b&6 zGd7aSawAFT-&iP_I#H%NGj(b}jgZOUb|Ra9h|d$uMFA6-x=I6~J{}))3T|+epN%)J z6Hq@O^_@^Gr@`Rs7aR<-Lp-?@60(bQ{*$554;3AQIgqaiz`$@u-?W(#Y@5%epRobo z6m(;XlDpGgM7_QU?=MbXHHetuu$@6@8PDzSK*sl!=X(bF4Z-G~hiNrT=CH?oLILAu z(XqZ`+clRPa>`h|mlqu%co8>*rDt-3w?z%hPn=VcRvyChgmbQ`;S)9V4%?MnGw
    &>Ic)jug0qN_5helZnL_>n|b&+eyj;bwEt`ubf>o zIKCk{fW?Nn7!JH2Sc#Zi}0LB-oZ`6ZRZGT~{qlKsd35l}sfZxmdbQy81@sP=p)U{^cMu zm8mk8Gt6fB?KpUMUybEQy79oHGSaDLXMDaLvjct%9V`fiQwo+#}ZN|7HoNoeRhf;7P zfK(fP3OC+-**=3BK>E_Y4l)Kv>*c1lS7AnZsjyrsfq@_=L{_%pzX*k4{eOM1{3)r z9@>0=r>)l6K8>FUq^(B)^<#&ny70jnP*m{E5>#=*vh+F>lXlrp5g6Ph`Qw_)E-FNY zUjlwqW^gcpXf(B^zogRRa7Ss`upPpx-2DIg`U;@9nk8J^6Wrb1-GaM?;2PXDxGwI# z!QI^n4ncwicY?bG_n>dXz3<-3|Ek`p+N!g=-*orPj_jQ2{@U?6C$M#rP+dqe`70mh z+8;u*TlJO>sjZzJIZd*> zNLh8Bq)l=P!2Wb&O}8Q9%gFK4d8V0(XbO&2$NUIEzmxD>eJB=ElV;nFURN|@B?@u1 z!)jU;i7X}kG#mB2xArfOaCUmv+U2y4qSh-2JpzyHB5h!R5RuHviX4F&@h`JJLpB-K{SrbkO~K#cD-Pb_Z~Jpw|I{X>@NM!ZLXw9fNvF7>ByLCgkW)(A|#^PREt9v zdCFp5eAU>sNW4zU`*#=Hq>kLi`y)!?7Fcx@R)rQoN6Uf2EH4^PUU0D6xI1(#|w19ujz6q&Ywi4*&gb#yTSJT;!4O zA-XTJ3PAYbhJL6EQN$At3HpZuT}eU3B{6 zC|t^vQD1;^Ii(9SI@Eqo&|H**TGOSHv}fq|2*89^Ltt9ipxjoWyCk!e-RX}jiP`Uj zFOKmVPl08OU%fskKl8NEZ{E^OY%a!}CZAcewoLX~XbE|w#UwN(H|SpoR^lv2R>ve+ z&_)+H9elV#O3yech7H3ghefa80!mFPGW;&ot(i{uq&>xHncz(OxzfS0iE|FNB`Qs& z9RfIos435fcg{j%={HM2A?aw_CkpFZnY3Gj@8A2=7`oqEh3ai7r~r zE<%k-P&C%)8ScLBxO)Ai_X?*asPs3<)i@-+o6rvTwTg(!ulnu7e9p(bM4hm+d3pwdc=b1-%2nON?V-`ai-cAsR;qd z!>hJgIz7(+NgzIgv$3Nft-3hb2EWRgmN$d;^?~lb6d}qCYwR%hm#9En=vcg~RrL7j z?_A!{l8I9}JM6LvaNMk=_0loMpO`>3A@R#v`o{#H(UM7atwZ=E&xoDnkf#>!?U`XI z3tHzP84Ye$Ku{5KVKU0WPt!}h7;gbUeO~A;EJc#xb#X0xLAm2AH0Xo2hG<`yvRfK);!m)dc`UJ@%v^3=B#6n8*=j9E6?6o5N zJIK~}fD-p5@qzj?{YpRa^f7P3Gunfobd8-!uf~D(-Kq@mz|j+;Ln_XOtw@BuH!GNl zD-*_2W&igT#Q}lXm{2fg%Y;>V+O>$CU7m()_4IVkbWUK$TxjMK_?#!&ck4gAo-l&Q ziI@B}KUih13EbF_C%vHVH|Dwk-zDq_rIHkPJ}VOo!lvI+vq~xpX2(}@{pj#}hWBLk z=W}8u!>vwiAuX~2gR@z0#g`?Jg=Auc)`iW~+D0;RWY%2X>oOuvc%n>)Zp&>6sZ|KT z?`X*BY|q^k|F)!dOnZURLM$qazWA)(O3%tY$iN5b$nwT*l)k zk%t)Wxx#&;E$Teo8D!c8KlBt;+J6FCV zdzb3pGrY|FQ3VKLG1D3?*noP`tECrpJ6ea#{R$~-&2rMfE?QD`#d8a zS_6rBuoOxYC(;L2PsDak>F=4HV)o<$YsHpeZPcs}{6ROjGk}QMiEEmk6**25v9GXo z@1TA0ls;KHB26s7G{1c4h^*yYFX^W!0b2U6BJYR7{n7PJ^%WPAM7#T=bq~+sFlo~X zySOT8cXR}OUnRrqO2 z{mP$;%!#4^YoZ#Q=;eKm2eI&FHVyO(V&am$1+Py|do9!=)JMA~`X~IGT`3{(dmcJK zv`c~KX>TJ0_VB(?7dh;5@Ob6{Cwvkf&hnWz5w8&?LmR7=L!m+unMdw0tvn5>To0Myp?Ev9qvWY z!!_*6tWPn7-dlfLc_LA;Dn& z>cwesCQiuUkrNH1c?BWD`0`N=i-vCUFx>1*slT9(`eb#ESM(>i)V*rq7CrrC(L~#4 z^lS32=kkD+SHXTtPX!YQlvc_R=piPnSEL9>z}kUa|n-!u+d=wa{)= zIh3UN=*DOOd0bM>D4B~34}BYb0)5>gB^exKW6>T|-1+qqBxpC*t6-K+O@HQ%VR`2! z`OWV=OI{S-YW<$xf>BNC<%RgKK5FR0JJI0p|9^$nm6PW2Qmx zdAAc#JY|XMNyfv;z zytgAn`ND15@y%~3-A{}Y>fdb$%O#!NVs}S$^tIO<%H41`<*A%+WK)ytASflHyA~_j zk6c`IoEXO{5QYgs|6oOM>13E24s7-7b|gLwqQJ)@3a_udARlODw64f)B#_&-H(XA2 z1BS8m`8NM_}=#%4zty@CA3c$c%-P*bg*C{Qu(iX0N=1NgnEagf*E|-g_ z(@cSFG`^!?)vDnyD;v~VMl?lwp1?J_W@v7DcPuf4F(c`ouU(CKOl#IW?@bf4d7XE1 z0IHZj>PM$3zOCJpgwUmQ^TO97j2SC-JGo1O&c*b*A`yHCy7w2;Wt(AUtt4CX6#@H= zohE;nH*V3MbJk;z0);k2V@{tgl+W1Op2poJx+U7_YJ5ris=mgD{pPw}fXr_#TjzWX zPM(M6DwxHM!J7v*5|L;Bm^CBwgshf!SLxPac(i>~>sf=EF-k03M_Wa0zJa{4@{gfx zj3FqRg?1PnJ`{ma7`7z2D#B*=@dvbScCcA+%q&_m7Te%VmrUC;pGguP>1euK**CrvEb7TK8MeqGy z+|^CVL;iBEUj|9vpegT`k#;l2W%Wx?ZY~iQ48i@&M&X4%As*t8&GSDSMG-bFA1p*np5n~X_4Rhy%#DEIx9TysH zD@tt3r0J&vflW#Bhg5~WPThcRhj_DAWALXuOkO2o*GlJlEtM{eFS-eC@I+ICxZI2C zbi5`GeN|)UFMeaII;nvqSUSY@{p_{X9T`$nrQC3dz6q{VN~>SQ-3v%)dQ^gM3%h$B zrffEREKhR&oO%Yx)wIG}5~nrvE3(+akj*oKDVzlG28Eb^vO*BHsU=Cpu{gjf|~0@M&Dr zb#@w*U4HCy%Hr$8#wbA-poEd-6DZ8FxRcEq8KgCDcc+aM%Gmf0ptLP;_al%|#44Ham<2N3xSYYpK$_Jr=8PmnEg6@@Wc8;p9 zBhfV*U{-B?kDp$w>~#19_+w4Igeg}_yS*>HOaPzbBqnt6Dk_?U&<Doo_=C@KH+VTTn1!(aZRbq!?-m-x9by0cp`${VAl_M38d>A zh`$W%a-PJw(^`g6hA)$1gsWAkqj+!BP+Que&V>1ZZmmO^~qaB_aYrd7I*GTU^P zqxsPgVN)cSb|Mf##UWI~5GmSV<~M9e@dnF>LrN{)#todR;HcQ?TXfQA{39GwA9%ZB zX1ZQYrL}7R7fb$-0nv+>f2{jJF#c3v%zzHKc>UpkJ@{)lj$|X;tsuyW>L)y~#s(AU z5RL{M@gf9#n*NCLtf&K504@vtgWt$Bhp_<~wZ@%Rjp-AOro`mu+#h%}@IaVzOmDC? zNOR|psg93(QL&q1JSQ>;7;@=7EL++2Uaq&^=5Fr$8xmU~bp zjF!h2bk>qum(!}LV439S;5gP1X>iWA53tPswt21&rqpMwjl5-Kbx*i2>zU|*zSO~| zk2qJ=9|Hc!o~r-iE5oJQ$&4VltQXSw!&-%vN-f{OtWiB84rwZ?h*pw~85;pXE1KsX zhv$7LVDrihnK4#I!Gi)xp*4xsv{&9ft*i=Onyq26-3OCap~v%Ax;Aj_XMB6b4jJzB z$8Wmrx>I{c9=Ke8){~+Mlyq^4e0W#tsEcJq<*-d>J3DOAvCrbbk$#(BY-ILEYV~b+ zV(-XBF$W^~Ymc#p;ra{@(gEqJQ)1ZC!Lx|q0lpc)b+K|kDKsipN(1d4BqDZaUeiFs zk;!=T#nvKw>w&Mr=9Gy+a?K-z>G_K;?FNky-cpnjfM`zBc_bH=gQPaj@nnwPv(m+~ zq?99k^rgC7g6Pr&qqA)v(VY`r3AM;Bt~@?qy;k8zxG2d|*-$Hss1I%IP4b+?sX*>O zfEgaLocCk2RANd8anjWlv|3ItHl@;C5Yc7ixgA1w?HMBcNn@$n>28fh${O^Grz%KU zhnV`K?L61d8izg9A`;k7J39MW<`ny)!9o zBy=Kdv+yE;&Hu@g``0-FnAwim4swnl0jBqGf+B`Nt`X0TO^nB6g}N9bG}yU}KO?Z) zKbAwWl3M;KfC;o0b%PdmyHwm`O6q}#8ikO!IXZmgr_zTe0`vTb zn5NwP6j71L6uqo?E0bwINq%(|1{Ar&6}m?a&XMMQMtwNSub!Y=Bc&mi)^5X0OEzx=TZ|8)U&4lZ(3>&b;{0UozUnb%R`lwhjwYA+PQ7tuq z6qi!_(d#a5^t*9XyyTr9iSaLnRyfSOah=V@`ajXo<6o^O1VEP5BAYxKC-?t(AN{Mb zo0mB8&8*Dqd#k*+{CnQ!EmK0z4+BDwcPy()Ip`rs?EWaANXl*H zBu85RlD3*3`DDF{IejaoRJB3FGP>P$?gHdnTDaMAIhc|VOXr}h&I6{nNI`zz`Vu!e>=9v3nO=? z{z!M1+xM0e=wu|aAG(VPIyU8SsHnmz^D1`dTPBvn<##QtsMK^ zY?XFe5HR|))QYJLXG9=V*Wg!6OxVaIZ5qqKOG=+J$JsKAV0b4-WljW@*4)f53^7rt zylRaN5oQY~>V=bc6=o_s-Tj$hf$!rA8PnvnyJ2N5HEiSvn<8cSRg z;5Tx0$3!27*u~21kId0#)NslPex8!NACnG~Pk~l&A3rlIi`?V<4S%j6>iIK6L(W`P z4%^zkzHcXkDo7Nl08i>u9dyHYN?_b*d7l2s_0AbGF>Zx!C93yo?C6&}l{CK*^L`@O z3YGWaPqXNo8f|K6AqvXWSk7Fcf3s1G{_e)+^GCF=a%$6a z{n0%IrHFZfKw@V$_47DWjS{$%a@Q6sxqT}>hk~+Xgf!{O3XPZp^dv6m@M~4Yk zaRX)L_N}>8OfF5fp!V3X$GcCyj_-ZMsKUzw^~)aw4#%ra@?n1G{4-B#Oc6hRuZyi zNNlmVg;R(JWd0rpWHrKwos37>zQccKtxg%uGyUMuh}-T#JrTG7J*}-8&WbV7sN~Bs zct4t#G@PcaN$edRXmeRk`N1Bqu`F`m4eAF8oDFhX0a827{sOi$4b6z^*20#DBEyDz zE{i^$vV$Bk@|lJeH9%Y{4vP>OK2SIKjI`?4{_{P_d?;51;O`wN#h(vRq(6K8IQ&>l zPTCXNplRLkb6a%a)`WwMz8W3DY`d^3)&?7G!X!Ldf25G#o3BymQOhWZOE}Z8$!>{O zKWum>1!G6n5#mLGB-NIer7tNRWAxy_aQlHwueNFs&o#)=b!Y6m`boQ6=2#GG&mK69 zw=4TL;bSFWO{5ekH0s8-?Zq1Yz!IrfQ;W~M>DwNJq)#Q2FW{H~{!4npFp4y!crsGz zjP-dSg>sW82E{(%4&D8$D^brtW;Lk@c+4iwx^yh6L=XH=gte2g0;NqE*$e{j1X1q* z^&mw+EBOtz^H{J`lw4Tjs-{~-seaw(Q1Sr5&|hMr7b(#vp0MHG_nqkrE?n8G$L+0oF6CznKQq7Y z*>65ue^`0Q{JAeiz)P_&k%XCSUP)*&(M#cz;o_Qsq4>o-jgv|M3(C9}HWrjGU`mpJ zjl4$%kUcV8pc#j|H#99T8n!=h4rPfrkIK+6b_bPR_(S9f)jNQnOvJY3Iejn#^N8&p zR#fxaQl1B)CsT@GfNvSH6Ww;?7H5MZ;{j~Jo#lwaP-zwVMn+&~=TM;&8qx=9NoAgN z<=cD9?4eqAqV@<26Bp3$&|B_{z$cwoQf&7LP#a2dR9M|{rI|8@+K~PpJ}}Re-FM~Y z&&kz>O2zGcD<*&TjpY*(rM|2FBW7MuaEyf*UmLgho_6sipm%I(KUMBDl4o|A8Q})Y z^CjVP^5!lMroVg+&L-&SlDN3Z8QcWL};OSEG1o6(uN= zJ_ldIUnyF0g@)+5t^^K6GT!uBcP*}qP43~79t7r^2(-k22n*PX7)LwQiQT%Xw13; ztSl#PWvdC%4O^mBZqmI9{Q>o~=ecjkDj?WP`iEh~Bc`eAGUI{y?&Nrr#%F=H2+Hfb zy1ZEDuvkn!nHVLk(>dU6D9|TSc)}9kP@D`vPifi!W8h_+tF`jCNe)RT8}`=@65}vG zKdJy`Rz;3(g8&WWid4=Ol_{(>=JxY`{3jB9={)lD9^~~CjS=%q3_?#aZ$DIAQu0UEaxwvktIaEda9}mH?B- z?~>d20&j%jR`l6hw)Wrm>i()L?<*UnFVbITjowUCD|b|;#TUJOqKXktqWu{`igb(B zE80jbYzHK*GgG6<7O`yZ)L5E3F7{q30B+QM>m60F!~cZ*p8NzcaEj2wgeQiy?88N) z-n%mGqbvz2B|1vAE&C>yDVuqKlro@hC;1VRIZanJ62D5pZn%Xpgr%vR?K?R$ZbFiU zh>eS|v)|49QxN4GqazO8B-`4oVv8H{G#-g*I2EuhPxPC)Q@XOQIau#yXUOVG@iwF6 z{%BNtA`Vr|R!@$drq@l3?|57!o97QR?HjRPl1~?0)gpcH?+|gOYr^pH#x?-$A(T;4 zA{Bq0Z^8`AlCjuFZdQdu?PwtfF(wwFgiDh8 z;_pBR8C=Tu_0+amiHPYKpUYtgjG8jB0A&c9g~-ny2ELy%i)B(NTHmw6_>>GK7L5ncp($aLrl`WX)5fi9WZO+QM?pu>Mw| zGc-_NLTj8|iW3r7+=7SF0`(6%y&=>EwtA1m6#JDp-3{{FE-W^QwR;G9mf?*E9E+m{ zS_cpUY*o-TFnsOm931N{q~9erE=UIo>%)nZ3!@;S#-WAVe&t$dQqY{9HJSfqQwGQt z%6;h>YY0p#z0onhFMP=t%A0m_Glrw8>2@sod@|fJF1Xh+p5=A(e0^%q3|8RyxnFA} zGtW$4632-E7Z(l7lwn;POs;wCJUoTLsRC{R@D7(vop%nVX3SBgALc_MYnVbzMifdT z&jmpf?)~xUwWo84A%nSgqH5nKw{q<=-B}f_dUciPl?*$JCbjY^EnHD%(0@2))(R!h z-p^7zyDMC}W>)DUKhxUqdT|XGtY&1>T%;J)hR}Ydntp4o)NW1Tj!wuKM$w-zWsg~ zI&BwOL8Sx6j+e*^NVgW{sLR!of+Xb+4nRU)lcn>hSL8p~^NHBZjdGrM zw@8VNW*TxoDWQbMW}(vb8AcJ}>#9?;oZ;xz_xUuJmi;U`ZCa3uHAJ^TW;Z551?c~c zK8@5J_&AbGWMP`V#Scva0|VWeAt`FT@KrU@&z=lt1}+6EtdTI6Y{Oc&*<5jYpcVgdufbuF&H`% z%u%!E1;y#nuNq!U3b07K(1GXrIDjLExGaCM!{-Hs#HNp)i`LH7X)vG7MKLoz)fXi& zT6^6QtXe|zuti+=Oz62^34YkvI+`R@AH&?fw zv1Z(sC&l{VeSlzQETyCF7xqyf_w2=Kqi8)bVjWRGy#ZJg{36aCgzLs^z3u;A681 zT#e)neKt+jjO+}7mq)W@P0ItsBZD82gg_DceBG8Y!uy0mq1EcqEKn&u<0QrCnxp>R zp%*KYg%x`Wp_f(ekloyQXi_eUY0G%eOV`m`w=Z<2I?mPnfY&>VLHTfi@?2M6I77dW z_7Ii8&z;Gfl&BZ6S)!TcI$P$0x55*5!Xxq9`G64<(INmA^xUNl6dK3&deG^yfXbMt zvi3KR_p>4`2BK5fvML8UHvtRRp*K5@0!3O%oGrW=vR9jMZ|hebrzJ+9XdVS%KoW0> zi)~>n&uRnd+PNVUUJl!d>0g0jL@@PJ4^>Y?hM=Kh11?1}-&BYLiY ztx|@W^KNj^a_z_5a?kj%h13_4!g9V&II(18ofYBejCeG$H5Zu9J?DUP&B5HNxNWuK zsimMEP49y?o6`M#m2K#R8vRp1R;1j8>cP&;`SB?ygl*M9e%^)&3cru#%prUhzisie zv(d|5&=qRDx`XkWPX#;fqEl0n>}Ze?wF1-t=v+5C3W#1FNBI`H5(_$jBEgfBHNTkq zy%Q3$c1_=lpvu0{6`CZQKrfs~3x^_R2UFAlt&Q*WkWZQ{S8(p|ZVO*DFC^nupTM{9 z>0xZ1%^H9|2WzvGAT+BWsMtkVVd!e*g%>kSE%wc5uL*bOby(6_MMy8F-M+xczT(X0$jU)07L49% za!5ACrTtK9*w?_DAM(IJTrW=gfc>^Vv{xvw{iRO}1jX0?>)iYO0s$aXb^P^#oLQ@> zp>6I(zQMNu?c9$hv?S89VFlsvwW#Pw;j2Z*MMzq%Lnldh)m=mBuwLg7;Z*(gfUoDH zu9c$JRy@wD>9?I8r%U#$R|DhBYhW1XBV8!F?{KUpYjcbz{X!_erSK)GrP(MCM8v3t z_%j|18l;mZWeXWh0Dju77~zyk4|vWBRB5l`D}SS9({{A(`GAt8`an|x9Xe$$eVPe1 z<#Ge5#1~!XH?aD&TA^#* zpdnaiB~r?thj)HEtl=fjn@CzXkAsr*`{7StLTk|S3m9(5jcG5ch)Q_fHFMdh@Zv5p zWm9YLLeZ!G&ZR4>ImA*s&Xrj^8A4eSe-j9$+A8C~4Uf+;rW-nKG4{NjNZX~ef<)6k zC}msuP*ibd(g3}^(Hh5I%hpd7j99(y%-?W`Zob2(;VgZ@>o&X#vA{FC&+KLs6b+Qz z#1hncrwcFFX1JJYVyTVtxf$w3{`~-4B_!RTigbLo1*8N1)<-9a3-M4PQb|XHVh8_} z8}QZ}RBaot^V5~qB*8$|+)VN@onKBnS)^6pIz_#PnNR`DD4sd9mfqRVVqH?KBLi_e zTPZu}gO@TGe=yWNs3;od?C?-Otx^<;Ch#|l5mA3BA6#de93~6(+O{kuB+H5p`(7X) zW%DKXjPRc9iHT+5@Xs~7twFI?0*zwmXu{WYbrw!enA9SR1>kZTDm@R_Yx7 zaSK^NJeuNzABYN2CrNuMO=2^9Y-}XesmN{j}nAP70P{BYlZ@QZ1)+1;ELST#_+cRI=_Q4F^>9l3A{qPVj)PyP3}= zvRNYOu256^kuI?_c9k9th3DuOh8L#Z-ckqmX78$=9Gg}bD=tb%{z|i13?=v3qQQ?t zm5yya!IV!VC4;WGY_a5k7e+6|nFm1!P&zTlO&6eB4!;ni(qQAGc6an;=mBk`#C_3*Uc!~bEm zNZnN@&&*Ei!ktZUU#m2SJh&mIUUPyqjGfQUShX)NhLWLNbFwyqGbH%qPPBO^Z6m|R zpB;5hX?CPrM7eMLNbJ;G0s_Q%DXV~E+4qaz`c%f^NMD%EOE-xiaj1GV`1#lLSDJSS z-?=i_%;Um%bUd#|GrI>bFKX79c2&n#BK9>}C$t`=!s{S(`~vBJZO`Y=}kO-XJ|HnJkyB{AnQW5j`0|(wBHr zNrbT^>4E_{dX%Kkj8(K2X{RLQNFwKnf|Klr2Yf#GCBh#xO!lJh!ha?{iE|1k`G_46vcZ0IE2L(h@pu&c1S@?6Q*~3DUn&FB z7{;S>IK}Ad9O-WdHNV8U)hs;6OtM4a^LdOOm2a4!iuQsYD3*l+UkAO}A%S&pXa9Ek z-6wx{0km~g15na>! z$ctc{F)Ryrhy5hQ%9@Avj7T%jg4TZ|(_M*544_^H0K&YI*Qln64tWib zX_NEh*83S`EG$aD>!LIyyFU~mQOSNt{WIslnxmB`b6toDRoFSA+EvwZzH~plPzwH4 zImlQvIOj4}1NF#v^!u>*PvgdBaYT9*+;c@h1ir-&HJaxRyh z_v+WBtRTj@`?NwH8e=_nq;fX%m3>@~j<(~mbBvbk8o`wYdqddzI_Qzi-jULXch-*6 zuJa%M5ot(Zja54enhlmfvjO+N$uEcicJq_Ud^q+hXVBtE`1YoLBuJ(lne8*V(k&>^z?26NH|JB zZrnQfsxGSuP0N%9hB$Vy_G!*VeoP{PB9`N7c}J7)G)APN`@T&g>{Y1%nT`EB?K?OG ze6CzDNY9e;SHO-{wJodS02v=b&jO*q1FudtWnF_w6B5Dv3@>ykx*7z?ew7B6@+iEQ zg)#|2NOw5FKdc)N497H`$LhdyBvL4P2!5dtKHOQ3-2G-Cn&1=hkXNCt`}zyJfec6% zEh|)~d@oX}*|-0X!_&CIt0W+?l{A39G0e7dZ31~G-+Adns;D&Fq=jf1>eLU=AkUkC|ig2l09=+p1RF$E1cUL(o}~*J+E>?&^vV0Pqas5JnCOf3&~AiP9Yd zPB@-;E9${Z=s^fgC=ue`cde^s8n$~;jHJDC>JTy;^7|ZUSUoB+Y~=ou-zKhMhablHZCxXdSt z!#~KR@JMeGy~mBKp8&n_n6_DrQpNAPXt%3AB5o_J2k z!_6WZ)&P&bfocF;QzGJMMNT@6A%Cn=IVIO|O|Cl*}dP53O=m8&OfmK7?6m#q_AP*T>xUJ>d5RfY@80ZKS z^d1}n0}KNU3=R$q!5egRkMxuM-QSzJNB?Uf5I_|u|C1B&1Ul6Ry#WKw!mk%-gZV#K z8tC5si#dqi>%YSOSpxBY@L*t_|1M$v#n8mY^#5D%ucZmY2;c{xtU6c>|5UN~911=F z2L|>P1fzMQf&d%{j(`bVpCBdqYs=n|rc)URumpOMy#dl90CTyqfbW^#1ARx3Ucp9p zmh}6e)duf9=#=*j7#$JV{gDQEH}@}~@xn=(BM69s1O~?b1}KE~s-9?+0sgOgD-sZQ zFi>P169OC;B!LXLq=*A7n?i#7`{k`?MHg^m7z+XsA5;jGpBokz$oy|pOgu-{5;r^fIJN48~J_Sji1xf$Q zu>If5fc91TM{qo#_wc{Wv= z)2nL0C=4hQ6XC1+{}9=OD*U#xm3sdMQ@sNJ$vggE!KwzY!1W1OVAKThD|jn-;xiEl zK>&J@{}&0mV=)GjPO|F#^@#cV`Trd|px@_zu2|!Ljh%mw1Y;Y^H>2Ti;r~)d|Fe^I z8UxQ$X@NKyNWky&NF;y3uf)9|RkR={g||I2*9-(E2f6~#-gJY%h29XU{*Q5BV2PHX zLIgmWX`EN-Zz%iT0Ils`r8CX4{tNiOOlxm|xL<(&(_F8hH>_rFK+sMgX?(!W*?(2) zFK3oFh#m_O^t7Ar4G_WwNVzBt_qP&%IkbSCQ&Ao`CLZx}D$2x9aDfysapztCPaz6m&Z z16)XWm6|t8^9uayq4>96kDwon_YLqq4H&&B^$Pm0%i=%nAI*4`HsXZ`T$}k}b}2LZ`|ssFCb>p>aFzFW}TBJc(%QvRy`-5m9+ z#Qz>g{1Yfv1k-wVyW=HWxfJ*zTfc-gwSK!}2V*;Sc ztALu5^$pPFJE-pny@HTmdNn{RC>V$g Date: Thu, 20 Sep 2018 16:28:53 +0300 Subject: [PATCH 2096/2572] [SKIP CI] gradle update --- .gitlab-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d6b5f590..8872d49c 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -39,7 +39,7 @@ cache: "Build: Java 8": stage: build - image: packages.deltixhub.com:443/gitlabci.docker/oracle-jdk-8-gradle-3.3:latest + image: packages.deltixhub.com:443/gitlabci.docker/oracle-jdk-8-gradle-4.10.1:latest script: - git checkout origin/pipeline-$CI_PIPELINE_ID~1 || true - ./gradlew build test --no-daemon @@ -72,7 +72,7 @@ cache: "Publish: Java 8": stage: publish - image: packages.deltixhub.com:443/gitlabci.docker/oracle-jdk-8-gradle-3.3:latest + image: packages.deltixhub.com:443/gitlabci.docker/oracle-jdk-8-gradle-4.10.1:latest script: - git checkout origin/pipeline-$CI_PIPELINE_ID~1 - ./gradlew publish From 87a59b4a0f1ef491eeae36a976699a5ae6406e52 Mon Sep 17 00:00:00 2001 From: Alex Karpovich Date: Fri, 21 Sep 2018 16:33:43 +0300 Subject: [PATCH 2097/2572] [*] plugins --- build.gradle | 2 -- 1 file changed, 2 deletions(-) diff --git a/build.gradle b/build.gradle index 511ddb81..4ba8fb6f 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,4 @@ plugins { - id 'idea' - // Supports functionality similar to Maven BOM. // Helps to avoid re-declaring dependency version in each subproject. // See https://github.com/spring-gradle-plugins/dependency-management-plugin From a54b42ab59f56265255f9bdb13634f23e0292433 Mon Sep 17 00:00:00 2001 From: Andy Malakov Date: Fri, 21 Sep 2018 12:35:47 -0400 Subject: [PATCH 2098/2572] ProGet credentials --- gradle/Deltix.gradle | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/gradle/Deltix.gradle b/gradle/Deltix.gradle index 8e98b236..586e06fe 100644 --- a/gradle/Deltix.gradle +++ b/gradle/Deltix.gradle @@ -1,8 +1,15 @@ +// Developers: please put credentials into ~/.gradle/gradle.properties +// CI Build robots get these credentials from CI Environment Variables +gradle.beforeProject { + if (findProperty('DELTIX_PROGET_USER') == null && System.getenv('DELTIX_PROGET_USER') == null) + ant.fail('ERROR: Credentials to access packages.deltixhub.com repo are NOT defined!\nSee https://gitlab.deltixhub.com/Deltix/Common/MultilingualPackage/wikis/ProGetCredentials') +} + repositories.ext.mavenDeltix = { name -> repositories.maven { credentials { - username "Builder" - password "FPubKkK172yBz9oAKZFk" + username findProperty('DELTIX_PROGET_USER') ?: System.getenv('DELTIX_PROGET_USER') ?: "FakeProGetUser" + password findProperty('DELTIX_PROGET_PASS') ?: System.getenv('DELTIX_PROGET_PASS') ?: "FakeProGetPass" } authentication { digest(BasicAuthentication) @@ -14,8 +21,8 @@ repositories.ext.mavenDeltix = { name -> project.buildscript.repositories.ext.mavenDeltix = { name -> project.buildscript.repositories.maven { credentials { - username "Builder" - password "FPubKkK172yBz9oAKZFk" + username findProperty('DELTIX_PROGET_USER') ?: System.getenv('DELTIX_PROGET_USER') ?: "FakeProGetUser" + password findProperty('DELTIX_PROGET_PASS') ?: System.getenv('DELTIX_PROGET_PASS') ?: "FakeProGetPass" } authentication { digest(BasicAuthentication) @@ -23,4 +30,3 @@ project.buildscript.repositories.ext.mavenDeltix = { name -> url "https://packages.deltixhub.com/maven2/" + name } } - From 3b021bfbe814aa2cdc5e52b58bbb7b34013438b4 Mon Sep 17 00:00:00 2001 From: Alex Karpovich Date: Tue, 2 Oct 2018 15:02:50 +0300 Subject: [PATCH 2099/2572] [*] currencies: allow > 1000 --- util/src/main/java/deltix/util/currency/CurrencyCodeList.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/src/main/java/deltix/util/currency/CurrencyCodeList.java b/util/src/main/java/deltix/util/currency/CurrencyCodeList.java index 83f280fe..8b31b644 100644 --- a/util/src/main/java/deltix/util/currency/CurrencyCodeList.java +++ b/util/src/main/java/deltix/util/currency/CurrencyCodeList.java @@ -23,7 +23,7 @@ @Depends("deltix/util/currency/CurrencyCodes.xml") @ThreadSafe public class CurrencyCodeList { - private static final int amount = 1000; + private static final int amount = 10000; private static final CurrencyInfo[] numericIndex = new CurrencyInfo[amount]; private static final ThreeLetterToObjectMapQuick symbolicIndex = new ThreeLetterToObjectMapQuick<>(amount); From ddc59a3f4a2ece82e4fe6ee784eb55f0ceba6ed2 Mon Sep 17 00:00:00 2001 From: Alex Karpovich Date: Tue, 2 Oct 2018 16:13:54 +0300 Subject: [PATCH 2100/2572] [*] fix CI --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index d5203e62..f47ed622 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ #Wed Sep 19 18:08:57 MSK 2018 -version=5.2.31-SNAPSHOT +version=5.2.32-SNAPSHOT deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java From 875bcf8df54048735dbbe5585c51b453a11e7000 Mon Sep 17 00:00:00 2001 From: Robot Date: Tue, 2 Oct 2018 16:14:34 +0300 Subject: [PATCH 2101/2572] [Skip CI] Generate release version --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index f47ed622..bc32ea47 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ -#Wed Sep 19 18:08:57 MSK 2018 -version=5.2.32-SNAPSHOT +#Tue Oct 02 16:14:34 MSK 2018 +version=5.2.32 deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java From 0f4553bfcf55864923d7b9cc6ab51774b07f5408 Mon Sep 17 00:00:00 2001 From: Robot Date: Tue, 2 Oct 2018 16:14:40 +0300 Subject: [PATCH 2102/2572] [Skip CI] Generate next development version --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index bc32ea47..b97b4cb1 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ -#Tue Oct 02 16:14:34 MSK 2018 -version=5.2.32 +#Tue Oct 02 16:14:40 MSK 2018 +version=5.2.33-SNAPSHOT deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java From f67bfbbf73368290d2e10c7a3dfd9535ecee4027 Mon Sep 17 00:00:00 2001 From: Andy Malakov Date: Tue, 23 Oct 2018 21:30:04 -0400 Subject: [PATCH 2103/2572] Newer version of gflog (.15) --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 4ba8fb6f..6107538e 100644 --- a/build.gradle +++ b/build.gradle @@ -48,7 +48,7 @@ configure(leafProjects) { // dependency 'org.mockito:mockito-core:1.10.19' - dependencySet (group: 'deltix', version: '2.0.8') { + dependencySet (group: 'deltix', version: '2.0.15') { entry 'deltix-gflog-api' entry 'deltix-gflog-core' entry 'deltix-gflog-jul' From f559545ad91278b6ac48e75dcdf0c3b8584bd4d8 Mon Sep 17 00:00:00 2001 From: Andy Malakov Date: Wed, 24 Oct 2018 13:11:16 -0400 Subject: [PATCH 2104/2572] Reverted Reconnectable back to JUL logger on Nick's request (used in legacy trading connectrors) --- gradle.properties | 2 +- .../qsrv/hf/spi/conn/ReconnectableImpl.java | 67 +++++++++++++------ 2 files changed, 49 insertions(+), 20 deletions(-) diff --git a/gradle.properties b/gradle.properties index b97b4cb1..467aecfc 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ #Tue Oct 02 16:14:40 MSK 2018 -version=5.2.33-SNAPSHOT +version=5.2.34-GFLOG deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java diff --git a/util/src/main/java/deltix/qsrv/hf/spi/conn/ReconnectableImpl.java b/util/src/main/java/deltix/qsrv/hf/spi/conn/ReconnectableImpl.java index b0e326aa..5e639dac 100644 --- a/util/src/main/java/deltix/qsrv/hf/spi/conn/ReconnectableImpl.java +++ b/util/src/main/java/deltix/qsrv/hf/spi/conn/ReconnectableImpl.java @@ -3,19 +3,23 @@ import deltix.gflog.Log; import deltix.gflog.LogFactory; import deltix.gflog.LogLevel; +import deltix.util.lang.Util; import deltix.util.log.LazyLogger; import deltix.util.time.GlobalTimer; import deltix.util.time.TimerRunner; import net.jcip.annotations.GuardedBy; import java.util.TimerTask; +import java.util.logging.Level; +import java.util.logging.Logger; /** * Helps implement the {@link deltix.qsrv.hf.spi.conn.Disconnectable} interface, including reconnect * capability. */ public class ReconnectableImpl extends DisconnectableEventHandler { - protected static final Log DEFAULT_LOG = LogFactory.getLog(ReconnectableImpl.class); +// protected static final Log DEFAULT_LOG = LogFactory.getLog(ReconnectableImpl.class); + protected static final Logger DEFAULT_LOG = Logger.getLogger(ReconnectableImpl.class.getName()); public interface Reconnector { /** @@ -96,12 +100,11 @@ public long nextInterval ( private volatile long initialReconnectInterval = 5000; private volatile ReconnectIntervalAdjuster adjuster = null; - private volatile Log logger = DEFAULT_LOG; - private volatile LogLevel logLevel = LogLevel.TRACE; + private volatile Logger logger = DEFAULT_LOG; +// private volatile LogLevel logLevel = LogLevel.TRACE; + private volatile Level logLevel = Level.FINE; private volatile String logprefix; - private volatile LazyLogger lazyLogger = null; - @GuardedBy ("this") private Reconnector reconnector = null; @@ -164,25 +167,25 @@ public synchronized int getNumReconnectAttempts () { return numReconnectAttempts; } - public LogLevel getLogLevel () { + public Level getLogLevel () { return logLevel; } - public void setLogLevel (LogLevel logLevel) { + public void setLogLevel (Level logLevel) { this.logLevel = logLevel; } - public Log getLogger () { + public Logger getLogger () { return logger; } - public void setLogger (Log logger) { + public void setLogger (Logger logger) { this.logger = logger; } - public void setLazyLogger(LazyLogger lazyLogger) { - this.lazyLogger = lazyLogger; - } +// public void setLazyLogger(LazyLogger lazyLogger) { +// this.lazyLogger = lazyLogger; +// } public void setLogPrefix(String logprefix) { this.logprefix = logprefix; @@ -197,7 +200,8 @@ public void connected () { lastExceptionAsString = null; } - logger.log (logLevel, "[%s] Connected").with(logprefix); + //logger.log (logLevel, "[%s] Connected").with(logprefix); + log ("[{0}] Connected", logprefix); onReconnected(); } @@ -208,11 +212,32 @@ public void disconnected () { timeDisconnected = System.currentTimeMillis (); } - logger.log(logLevel, "[%s] Disconnected").with(logprefix); + //logger.log(logLevel, "[%s] Disconnected").with(logprefix); + log("[{0}] Disconnected", logprefix); onDisconnected(); } + private void log(String msg, Object ... params) { + Logger lg = logger; + if (lg != null && lg.isLoggable(logLevel)) + lg.log (logLevel, msg, params); + } + + private void log(String msg, Object param) { + Logger lg = logger; + + if (lg != null && lg.isLoggable(logLevel)) + lg.log (logLevel, msg, param); + } + + private void log(String msg, Throwable x) { + Logger lg = logger; + + if (lg != null && lg.isLoggable(logLevel)) + lg.log (logLevel, msg, x); + } + public synchronized boolean isConnected () { return (isConnected); } @@ -233,9 +258,11 @@ private synchronized void tryReconnect () throws Exception { } catch (Throwable x) { String check = x.toString (); if (check.equals (lastExceptionAsString)) { - logger.log (logLevel, "[%s] Reconnect failed due to: %s").with(logprefix).with(lastExceptionAsString); + //logger.log (logLevel, "[%s] Reconnect failed due to: %s").with(logprefix).with(lastExceptionAsString); + log ("[{0}] Reconnect failed due to: {1}", logprefix, lastExceptionAsString); } else { - logger.log (logLevel, "[%s] Reconnect failed: %s").with(logprefix).with(x); + //logger.log (logLevel, "[%s] Reconnect failed: %s").with(logprefix).with(x); + log ("[" + logprefix + "] Reconnect failed", x); lastExceptionAsString = check; } @@ -270,14 +297,16 @@ public void runInternal () { try { tryReconnect (); } catch (Throwable x) { - logger.error("[%s] Unexpected: %s").with(logprefix ).with(x); + //logger.error("[%s] Unexpected: %s").with(logprefix ).with(x); + logger.log (Level.SEVERE, "[" + logprefix + "] Unexpected", x); } } }; GlobalTimer.INSTANCE.schedule (reconnectTask, currentReconnectInterval); - logger.log(logLevel, "[%s] Next reconnect in %s").with(logprefix).with(currentReconnectInterval); + //logger.log(logLevel, "[%s] Next reconnect in %s").with(logprefix).with(currentReconnectInterval); + log("[{0}] Next reconnect in {1}", logprefix, currentReconnectInterval); } public synchronized void scheduleReconnect () { @@ -299,7 +328,7 @@ public synchronized void cancelReconnect () { private static String getDefaultPrefix(Class current) { StackTraceElement[] elems = Thread.currentThread().getStackTrace(); - if (elems == null || elems.length <= 1) + if (elems.length <= 1) return current.getSimpleName(); String currentClassName = current.getName(); From 9aebacf325fdf333d88b3622ccadce620665524a Mon Sep 17 00:00:00 2001 From: Andy Malakov Date: Wed, 24 Oct 2018 17:04:20 -0400 Subject: [PATCH 2105/2572] Marked as deprecated --- util/src/main/java/deltix/util/log/LazyLogger.java | 1 + 1 file changed, 1 insertion(+) diff --git a/util/src/main/java/deltix/util/log/LazyLogger.java b/util/src/main/java/deltix/util/log/LazyLogger.java index 9035a7a3..46411d61 100644 --- a/util/src/main/java/deltix/util/log/LazyLogger.java +++ b/util/src/main/java/deltix/util/log/LazyLogger.java @@ -9,6 +9,7 @@ /** * Logger uses lazy initialization on first log() in background thread. */ +@Deprecated public class LazyLogger { private final ArrayDeque buffer = new ArrayDeque(20); From c0dbcf30ba7ecbadf3ef931d6b873873a20fb895 Mon Sep 17 00:00:00 2001 From: Alex Karpovich Date: Tue, 30 Oct 2018 18:55:03 +0300 Subject: [PATCH 2106/2572] [*] version --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 825c0900..0dd7897a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ #Tue Oct 02 16:14:40 MSK 2018 -version=5.2.35-SNAPSHOT +version=5.2.36-SNAPSHOT deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java From 782e9f409ce8e92b46384353a83ff9165f37c90b Mon Sep 17 00:00:00 2001 From: Robot Date: Tue, 30 Oct 2018 18:55:29 +0300 Subject: [PATCH 2107/2572] [Skip CI] Generate release version --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 0dd7897a..4a3dc67e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ -#Tue Oct 02 16:14:40 MSK 2018 -version=5.2.36-SNAPSHOT +#Tue Oct 30 18:55:29 MSK 2018 +version=5.2.36 deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java From a38111dc77f7d794f1d36eae06a7f5e2569aa1ca Mon Sep 17 00:00:00 2001 From: Robot Date: Tue, 30 Oct 2018 18:55:36 +0300 Subject: [PATCH 2108/2572] [Skip CI] Generate next development version --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 4a3dc67e..98802d03 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ -#Tue Oct 30 18:55:29 MSK 2018 -version=5.2.36 +#Tue Oct 30 18:55:36 MSK 2018 +version=5.2.37-SNAPSHOT deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java From c1d417eee0c00f044f395c306b6e62c94b56d256 Mon Sep 17 00:00:00 2001 From: Artyom Korzun Date: Mon, 19 Nov 2018 13:23:25 +0300 Subject: [PATCH 2109/2572] 1. Added a copy constructor to primitive lists which takes the interface of a list 2. Added hashCode, equals, copy methods to CollectionUtil --- .../util/collections/CollectionUtil.java | 375 ++++++++++++++++-- collections/src/main/templates/ArrayList.vpp | 27 +- .../util/collections/Test_CollectionUtil.java | 58 +++ 3 files changed, 419 insertions(+), 41 deletions(-) create mode 100644 collections/src/test/java/deltix/util/collections/Test_CollectionUtil.java diff --git a/collections/src/main/java/deltix/util/collections/CollectionUtil.java b/collections/src/main/java/deltix/util/collections/CollectionUtil.java index 181fb67e..74e62227 100644 --- a/collections/src/main/java/deltix/util/collections/CollectionUtil.java +++ b/collections/src/main/java/deltix/util/collections/CollectionUtil.java @@ -1,74 +1,70 @@ package deltix.util.collections; -import java.lang.reflect.Array; -import java.util.ArrayList; -import java.util.Collection; -import java.util.EnumSet; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - +import deltix.util.collections.generated.*; import deltix.util.lang.Filter; import deltix.util.lang.StringUtils; import deltix.util.lang.Transformer; import deltix.util.lang.Util; +import java.lang.reflect.Array; +import java.util.*; +import java.util.function.Function; + public class CollectionUtil { - public static void remove (Collection collection, - Filter filter) { - ArrayList r = new ArrayList (); + public static void remove(Collection collection, + Filter filter) { + ArrayList r = new ArrayList(); for (T o : collection) { - if (filter.accept (o)) - r.add (o); + if (filter.accept(o)) + r.add(o); } for (T o : r) { - collection.remove (o); + collection.remove(o); } } - public static String toString (Collection collection, String separator) { - return toString (collection, "", "", separator); + public static String toString(Collection collection, String separator) { + return toString(collection, "", "", separator); } - public static String toString (Collection collection, String head, String tail, String separator) { - if (collection == null || collection.isEmpty ()) + public static String toString(Collection collection, String head, String tail, String separator) { + if (collection == null || collection.isEmpty()) return head + tail; - StringBuilder builder = new StringBuilder (128); - builder.append (head); + StringBuilder builder = new StringBuilder(128); + builder.append(head); for (Object value : collection) - builder.append (value).append (separator); - builder.setLength (builder.length () - separator.length ()); - builder.append (tail); + builder.append(value).append(separator); + builder.setLength(builder.length() - separator.length()); + builder.append(tail); return builder.toString(); } - public static > EnumSet toEnumSet (Class elementType, - String... elements) throws IllegalArgumentException { + public static > EnumSet toEnumSet(Class elementType, + String... elements) throws IllegalArgumentException { if (elements == null || elements.length <= 0) - return EnumSet.noneOf (elementType); + return EnumSet.noneOf(elementType); - EnumSet result = EnumSet.noneOf (elementType); + EnumSet result = EnumSet.noneOf(elementType); for (String element : elements) { - String elementStr = StringUtils.trim (element); + String elementStr = StringUtils.trim(element); if (elementStr != null) - result.add (Enum.valueOf (elementType, elementStr)); + result.add(Enum.valueOf(elementType, elementStr)); } return result; } @SuppressWarnings("unchecked") - public static T[] remove (T[] elementData, T element, Class clazz) { + public static T[] remove(T[] elementData, T element, Class clazz) { for (int index = 0; index < elementData.length; index++) - if (Util.xequals (element, elementData[index])) { + if (Util.xequals(element, elementData[index])) { int numMoved = elementData.length - index - 1; if (numMoved >= 0) { - T[] result = (T[]) Array.newInstance (clazz, elementData.length - 1); - System.arraycopy (elementData, 0, result, 0, index); - System.arraycopy (elementData, index + 1, result, index, numMoved); + T[] result = (T[]) Array.newInstance(clazz, elementData.length - 1); + System.arraycopy(elementData, 0, result, 0, index); + System.arraycopy(elementData, index + 1, result, index, numMoved); return result; } } @@ -100,4 +96,313 @@ private static Object toArray(Collection values, Class componentType) { Array.set(array, count++, value); return array; } + + // region hashCode + + public static int hashCode(final ObjectList list) { + int hash = 0; + + if (list != null) { + for (int i = 0, size = list.size(); i < size; i++) { + final Object object = list.getObjectNoRangeCheck(i); + hash = 31 * hash + Objects.hashCode(object); + } + } + + return hash; + } + + public static int hashCode(final LongList list) { + int hash = 0; + + if (list != null) { + for (int i = 0, size = list.size(); i < size; i++) { + final long value = list.getLongNoRangeCheck(i); + hash = 31 * hash + Long.hashCode(value); + } + } + + return hash; + } + + public static int hashCode(final IntegerList list) { + int hash = 0; + + if (list != null) { + for (int i = 0, size = list.size(); i < size; i++) { + final int value = list.getIntegerNoRangeCheck(i); + hash = 31 * hash + Integer.hashCode(value); + } + } + + return hash; + } + + public static int hashCode(final ShortList list) { + int hash = 0; + + if (list != null) { + for (int i = 0, size = list.size(); i < size; i++) { + final short value = list.getShortNoRangeCheck(i); + hash = 31 * hash + Short.hashCode(value); + } + } + + return hash; + } + + public static int hashCode(final ByteList list) { + int hash = 0; + + if (list != null) { + for (int i = 0, size = list.size(); i < size; i++) { + final byte value = list.getByteNoRangeCheck(i); + hash = 31 * hash + Byte.hashCode(value); + } + } + + return hash; + } + + public static int hashCode(final CharacterList list) { + int hash = 0; + + if (list != null) { + for (int i = 0, size = list.size(); i < size; i++) { + final char value = list.getCharacterNoRangeCheck(i); + hash = 31 * hash + Character.hashCode(value); + } + } + + return hash; + } + + public static int hashCode(final BooleanList list) { + int hash = 0; + + if (list != null) { + for (int i = 0, size = list.size(); i < size; i++) { + final boolean value = list.getBooleanNoRangeCheck(i); + hash = 31 * hash + Boolean.hashCode(value); + } + } + + return hash; + } + + // endregion + + // region equals + + public static boolean equals(final ObjectList lhs, final ObjectList rhs) { + if (lhs == rhs) { + return true; + } + + if (lhs == null || rhs == null) { + return false; + } + + final int size = lhs.size(); + if (size != rhs.size()) { + return false; + } + + for (int i = 0; i < size; i++) { + if (!Objects.equals(lhs.getObjectNoRangeCheck(i), rhs.getObjectNoRangeCheck(i))) { + return false; + } + } + + return true; + } + + public static boolean equals(final LongList lhs, final LongList rhs) { + if (lhs == rhs) { + return true; + } + + if (lhs == null || rhs == null) { + return false; + } + + final int size = lhs.size(); + if (size != rhs.size()) { + return false; + } + + for (int i = 0; i < size; i++) { + if (lhs.getLongNoRangeCheck(i) != rhs.getLongNoRangeCheck(i)) { + return false; + } + } + + return true; + } + + public static boolean equals(final IntegerList lhs, final IntegerList rhs) { + if (lhs == rhs) { + return true; + } + + if (lhs == null || rhs == null) { + return false; + } + + final int size = lhs.size(); + if (size != rhs.size()) { + return false; + } + + for (int i = 0; i < size; i++) { + if (lhs.getIntegerNoRangeCheck(i) != rhs.getIntegerNoRangeCheck(i)) { + return false; + } + } + + return true; + } + + public static boolean equals(final ShortList lhs, final ShortList rhs) { + if (lhs == rhs) { + return true; + } + + if (lhs == null || rhs == null) { + return false; + } + + final int size = lhs.size(); + if (size != rhs.size()) { + return false; + } + + for (int i = 0; i < size; i++) { + if (lhs.getShortNoRangeCheck(i) != rhs.getShortNoRangeCheck(i)) { + return false; + } + } + + return true; + } + + public static boolean equals(final ByteList lhs, final ByteList rhs) { + if (lhs == rhs) { + return true; + } + + if (lhs == null || rhs == null) { + return false; + } + + final int size = lhs.size(); + if (size != rhs.size()) { + return false; + } + + for (int i = 0; i < size; i++) { + if (lhs.getByteNoRangeCheck(i) != rhs.getByteNoRangeCheck(i)) { + return false; + } + } + + return true; + } + + public static boolean equals(final CharacterList lhs, final CharacterList rhs) { + if (lhs == rhs) { + return true; + } + + if (lhs == null || rhs == null) { + return false; + } + + final int size = lhs.size(); + if (size != rhs.size()) { + return false; + } + + for (int i = 0; i < size; i++) { + if (lhs.getCharacterNoRangeCheck(i) != rhs.getCharacterNoRangeCheck(i)) { + return false; + } + } + + return true; + } + + public static boolean equals(final BooleanArrayList lhs, final BooleanArrayList rhs) { + if (lhs == rhs) { + return true; + } + + if (lhs == null || rhs == null) { + return false; + } + + final int size = lhs.size(); + if (size != rhs.size()) { + return false; + } + + for (int i = 0; i < size; i++) { + if (lhs.getBooleanNoRangeCheck(i) != rhs.getBooleanNoRangeCheck(i)) { + return false; + } + } + + return true; + } + + // endregion + + // region copy + + @SuppressWarnings("unchecked") + public static ObjectArrayList copy(final ObjectList list, + final Function elementCopyFunction) { + if (list == null) { + return null; + } + + final int size = list.size(); + final ObjectArrayList copy = new ObjectArrayList<>(size); + + for (int i = 0; i < size; i++) { + final T element = list.getObjectNoRangeCheck(i); + final T elementCopy = elementCopyFunction.apply(element); + + copy.add(elementCopy); + } + + return copy; + } + + public static LongArrayList copy(final LongList list) { + return (list == null) ? null : new LongArrayList(list); + } + + public static IntegerArrayList copy(final IntegerList list) { + return (list == null) ? null : new IntegerArrayList(list); + } + + public static ShortArrayList copy(final ShortList list) { + return (list == null) ? null : new ShortArrayList(list); + } + + public static ByteArrayList copy(final ByteList list) { + return (list == null) ? null : new ByteArrayList(list); + } + + public static CharacterArrayList copy(final CharacterList list) { + return (list == null) ? null : new CharacterArrayList(list); + } + + public static BooleanArrayList copy(final BooleanList list) { + return (list == null) ? null : new BooleanArrayList(list); + } + + // endregion + } diff --git a/collections/src/main/templates/ArrayList.vpp b/collections/src/main/templates/ArrayList.vpp index a4984dd0..36e7daf5 100644 --- a/collections/src/main/templates/ArrayList.vpp +++ b/collections/src/main/templates/ArrayList.vpp @@ -91,17 +91,32 @@ public final class ${name}ArrayList extends AbstractList<${type_Object}> impleme this(10); } +#if($name == "Long" || $name == "Integer" || $name == "Short" || $name == "Byte" || $name == "Character" || $name == "Boolean") + /** + * Constructs a list containing the elements of the specified + * list, in the order they are returned by the collection's + * iterator. The ArrayList instance has an initial capacity of + * the same size of the specified collection. + * + * @param list the list whose elements are to be placed into this list. + */ + public ${name}ArrayList(${name}List list) { + elementData = list.to${name_abbr}Array(); + size = elementData.length; + } +#end + /** * Constructs a list containing the elements of the specified * collection, in the order they are returned by the collection's * iterator. The ArrayList instance has an initial capacity of - * 110% the size of the specified collection. + * the same size of the specified collection. * * @param c the collection whose elements are to be placed into this list. */ public ${name}ArrayList(Collection c) { size = c.size (); - elementData = new ${actualType} [(size * 110) / 100]; // allow 10% room for growth + elementData = new ${actualType} [size]; Iterator iter = c.iterator (); int idx = 0; @@ -113,18 +128,18 @@ public final class ${name}ArrayList extends AbstractList<${type_Object}> impleme public ${name}ArrayList (${type} [] arr) { size = arr.length; #if($name == "Object") - elementData = Arrays.copyOf(arr, (size * 110) / 100, Object[].class); // intrinsic doesn't zero memory + elementData = Arrays.copyOf(arr, size, Object[].class); // intrinsic doesn't zero memory #else - elementData = Arrays.copyOf(arr, (size * 110) / 100); // intrinsic doesn't zero memory + elementData = Arrays.copyOf(arr, size); // intrinsic doesn't zero memory #end } public ${name}ArrayList (${type} [] arr, int offset, int length) { size = length; #if($name == "Object") - elementData = Arrays.copyOfRange(arr, offset, offset + ((length * 110) / 100), Object[].class); // intrinsic doesn't zero memory + elementData = Arrays.copyOfRange(arr, offset, offset + length, Object[].class); // intrinsic doesn't zero memory #else - elementData = Arrays.copyOfRange(arr, offset, offset + ((length * 110) / 100)); // intrinsic doesn't zero memory + elementData = Arrays.copyOfRange(arr, offset, offset + length); // intrinsic doesn't zero memory #end } diff --git a/collections/src/test/java/deltix/util/collections/Test_CollectionUtil.java b/collections/src/test/java/deltix/util/collections/Test_CollectionUtil.java new file mode 100644 index 00000000..649018e6 --- /dev/null +++ b/collections/src/test/java/deltix/util/collections/Test_CollectionUtil.java @@ -0,0 +1,58 @@ +package deltix.util.collections; + +import deltix.util.collections.generated.LongArrayList; +import deltix.util.collections.generated.LongList; +import org.junit.Assert; +import org.junit.Test; + +import java.util.concurrent.ThreadLocalRandom; + + +public class Test_CollectionUtil { + + @Test + public void testHashCode() { + for (int i = 0; i < 1000; i++) { + final long v1 = randomLong(); + final long v2 = randomLong(); + + Assert.assertEquals(CollectionUtil.hashCode(list(v1, v2)), CollectionUtil.hashCode(list(v1, v2))); + } + + Assert.assertNotEquals(CollectionUtil.hashCode(list(1)), CollectionUtil.hashCode(list(2))); + } + + @Test + public void testEquals() { + for (int i = 0; i < 1000; i++) { + final long v1 = randomLong(); + final long v2 = randomLong(); + + Assert.assertTrue(CollectionUtil.equals(list(v1, v2), list(v1, v2))); + Assert.assertFalse(CollectionUtil.equals(list(v1), list(v1, v2))); + } + } + + @Test + public void testCopy() { + for (int i = 0; i < 1000; i++) { + final LongArrayList list = new LongArrayList(i); + + for (int j = 0; j < i; j++) { + list.add(randomLong()); + } + + final LongArrayList copy = CollectionUtil.copy(list); + Assert.assertTrue(CollectionUtil.equals(list, copy)); + } + } + + private static LongList list(long... values) { + return new LongArrayList(values); + } + + private static long randomLong() { + return ThreadLocalRandom.current().nextLong(); + } + +} From 8ffc705936ad73af9d4a8013a33667d2d546cbbb Mon Sep 17 00:00:00 2001 From: Robot Date: Mon, 19 Nov 2018 13:27:41 +0300 Subject: [PATCH 2110/2572] [Skip CI] Generate release version --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 98802d03..0b0c8e62 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ -#Tue Oct 30 18:55:36 MSK 2018 -version=5.2.37-SNAPSHOT +#Mon Nov 19 13:27:41 MSK 2018 +version=5.2.37 deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java From 4a48dd3113bf0ceb6a1f025700bf6e2e443fd5e4 Mon Sep 17 00:00:00 2001 From: Robot Date: Mon, 19 Nov 2018 13:27:47 +0300 Subject: [PATCH 2111/2572] [Skip CI] Generate next development version --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 0b0c8e62..a95bc47a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ -#Mon Nov 19 13:27:41 MSK 2018 -version=5.2.37 +#Mon Nov 19 13:27:47 MSK 2018 +version=5.2.38-SNAPSHOT deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java From 277902039f1e5a8df4f77661de20e26474bc6684 Mon Sep 17 00:00:00 2001 From: Artyom Korzun Date: Thu, 22 Nov 2018 13:51:12 +0300 Subject: [PATCH 2112/2572] 1. Added a copy constructor to primitive lists which takes the implementation of a list 2. Updated gflog from 2.0.15 to 2.0.22 --- build.gradle | 2 +- collections/src/main/templates/ArrayList.vpp | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 6107538e..2572ad94 100644 --- a/build.gradle +++ b/build.gradle @@ -48,7 +48,7 @@ configure(leafProjects) { // dependency 'org.mockito:mockito-core:1.10.19' - dependencySet (group: 'deltix', version: '2.0.15') { + dependencySet (group: 'deltix', version: '2.0.22') { entry 'deltix-gflog-api' entry 'deltix-gflog-core' entry 'deltix-gflog-jul' diff --git a/collections/src/main/templates/ArrayList.vpp b/collections/src/main/templates/ArrayList.vpp index 36e7daf5..1adfbdf8 100644 --- a/collections/src/main/templates/ArrayList.vpp +++ b/collections/src/main/templates/ArrayList.vpp @@ -92,6 +92,19 @@ public final class ${name}ArrayList extends AbstractList<${type_Object}> impleme } #if($name == "Long" || $name == "Integer" || $name == "Short" || $name == "Byte" || $name == "Character" || $name == "Boolean") + /** + * Constructs a list containing the elements of the specified + * list, in the order they are returned by the collection's + * iterator. The ArrayList instance has an initial capacity of + * the same size of the specified collection. + * + * @param list the list whose elements are to be placed into this list. + */ + public ${name}ArrayList(${name}ArrayList list) { + elementData = list.to${name_abbr}Array(); + size = elementData.length; + } + /** * Constructs a list containing the elements of the specified * list, in the order they are returned by the collection's From ab921246b182cc324d277a9358251ca8aa5fff9a Mon Sep 17 00:00:00 2001 From: Robot Date: Thu, 22 Nov 2018 13:51:57 +0300 Subject: [PATCH 2113/2572] [Skip CI] Generate release version --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index a95bc47a..ab2e513d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ -#Mon Nov 19 13:27:47 MSK 2018 -version=5.2.38-SNAPSHOT +#Thu Nov 22 13:51:56 MSK 2018 +version=5.2.38 deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java From f46d05ea89333f37e2c28be82f0abc997e3ea115 Mon Sep 17 00:00:00 2001 From: Robot Date: Thu, 22 Nov 2018 13:52:03 +0300 Subject: [PATCH 2114/2572] [Skip CI] Generate next development version --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index ab2e513d..3e68cc04 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ -#Thu Nov 22 13:51:56 MSK 2018 -version=5.2.38 +#Thu Nov 22 13:52:03 MSK 2018 +version=5.2.39-SNAPSHOT deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java From 4300fde68f64efdf05aec9c7b35ba359fef57d15 Mon Sep 17 00:00:00 2001 From: Alex Karpovich Date: Fri, 23 Nov 2018 16:52:48 +0300 Subject: [PATCH 2115/2572] [*] compilation under bootJar --- .../java/deltix/util/lang/JarEntryObject.java | 103 ++++++++++++++++++ .../java/deltix/util/lang/JarScanner.java | 90 +++++++++++++++ .../deltix/util/lang/JavaCompilerHelper.java | 26 +++++ 3 files changed, 219 insertions(+) create mode 100644 util/src/main/java/deltix/util/lang/JarEntryObject.java create mode 100644 util/src/main/java/deltix/util/lang/JarScanner.java diff --git a/util/src/main/java/deltix/util/lang/JarEntryObject.java b/util/src/main/java/deltix/util/lang/JarEntryObject.java new file mode 100644 index 00000000..01609313 --- /dev/null +++ b/util/src/main/java/deltix/util/lang/JarEntryObject.java @@ -0,0 +1,103 @@ +package deltix.util.lang; + +import javax.lang.model.element.Modifier; +import javax.lang.model.element.NestingKind; +import javax.tools.JavaFileObject; +import java.io.*; +import java.net.URI; +import java.net.URL; + +/** + * @author atamur + * @since 15-Oct-2009 + */ +class JarEntryObject implements JavaFileObject { + private final String binaryName; + private final URI uri; + private final String name; + + public JarEntryObject(String binaryName, URI uri) { + this.uri = uri; + this.binaryName = binaryName; + this.name = uri.getPath() == null ? uri.getSchemeSpecificPart() : uri.getPath(); // for FS based URI the path is not null, for JAR URI the scheme specific part is not null + } + + @Override + public URI toUri() { + return uri; + } + + @Override + public InputStream openInputStream() throws IOException { + return uri.toURL().openStream(); // easy way to handle any URI! + } + + @Override + public OutputStream openOutputStream() throws IOException { + throw new UnsupportedOperationException(); + } + + @Override + public String getName() { + return name; + } + + @Override + public Reader openReader(boolean ignoreEncodingErrors) throws IOException { + throw new UnsupportedOperationException(); + } + + @Override + public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException { + throw new UnsupportedOperationException(); + } + + @Override + public Writer openWriter() throws IOException { + throw new UnsupportedOperationException(); + } + + @Override + public long getLastModified() { + return 0; + } + + @Override + public boolean delete() { + throw new UnsupportedOperationException(); + } + + @Override + public Kind getKind() { + return Kind.CLASS; + } + + @Override // copied from SimpleJavaFileManager + public boolean isNameCompatible(String simpleName, Kind kind) { + String baseName = simpleName + kind.extension; + return kind.equals(getKind()) + && (baseName.equals(getName()) + || getName().endsWith("/" + baseName)); + } + + @Override + public NestingKind getNestingKind() { + throw new UnsupportedOperationException(); + } + + @Override + public Modifier getAccessLevel() { + throw new UnsupportedOperationException(); + } + + public String binaryName() { + return binaryName; + } + + @Override + public String toString() { + return "CustomJavaFileObject{" + + "uri=" + uri + + '}'; + } +} \ No newline at end of file diff --git a/util/src/main/java/deltix/util/lang/JarScanner.java b/util/src/main/java/deltix/util/lang/JarScanner.java new file mode 100644 index 00000000..84f26a11 --- /dev/null +++ b/util/src/main/java/deltix/util/lang/JarScanner.java @@ -0,0 +1,90 @@ +package deltix.util.lang; + +import javax.tools.JavaFileObject; +import java.io.File; +import java.io.IOException; +import java.net.JarURLConnection; +import java.net.URI; +import java.net.URL; +import java.util.*; +import java.util.jar.JarEntry; + +class JarScanner { + private static final String CLASS_FILE_EXTENSION = ".class"; + + public static List list(ClassLoader loader, String packageName) throws IOException { + String javaPackageName = packageName.replaceAll("\\.", "/"); + + List result = new ArrayList<>(); + + Enumeration urlEnumeration = loader.getResources(javaPackageName); + while (urlEnumeration.hasMoreElements()) { + URL packageFolderURL = urlEnumeration.nextElement(); + result.addAll(listUnder(packageName, packageFolderURL)); + } + + return result; + } + + private static Collection listUnder(String packageName, URL packageFolderURL) { + String protocol = packageFolderURL.getProtocol(); + + if ("jar".equals(protocol)) { + return processJar(packageFolderURL); + } +// else if ("file".equals(protocol)) { +// File file = new File(packageFolderURL.getFile()); +// if (file.isDirectory()) +// return processDir(packageName, file); +// } + + return Collections.emptyList(); + } + + private static List processJar(URL packageFolderURL) { + List result = new ArrayList(); + try { + String[] uris = packageFolderURL.toExternalForm().split("!"); + String jarUri = uris[0]; + String secondUri = uris[1]; + JarURLConnection jarConn = (JarURLConnection) packageFolderURL.openConnection(); + String rootEntryName = jarConn.getEntryName(); + int rootEnd = rootEntryName.length()+1; + + if (!secondUri.endsWith("jar")) + return result; + + Enumeration entryEnum = jarConn.getJarFile().entries(); + while (entryEnum.hasMoreElements()) { + JarEntry jarEntry = entryEnum.nextElement(); + String name = jarEntry.getName(); + if (name.startsWith(rootEntryName) && name.indexOf('/', rootEnd) == -1 && name.endsWith(CLASS_FILE_EXTENSION)) { + URI uri = URI.create(jarUri + "!" + secondUri + "!/" + name); + String binaryName = name.replaceAll("/", "."); + binaryName = binaryName.replaceAll(CLASS_FILE_EXTENSION + "$", ""); + result.add(new JarEntryObject(binaryName, uri)); + } + } + } catch (Exception e) { + throw new RuntimeException("Wasn't able to open " + packageFolderURL + " as a jar file", e); + } + return result; + } + +// private static List processDir(String packageName, File directory) { +// List result = new ArrayList(); +// File[] files = directory.listFiles(); +// +// for (int i = 0; files != null && i < files.length; i++) { +// File file = files[i]; +// +// if (file.isFile() && file.getName().endsWith(CLASS_FILE_EXTENSION)) { +// String binaryName = packageName.length() != 0 ? packageName + "." + file.getName() : file.getName(); +// binaryName = binaryName.replaceAll(CLASS_FILE_EXTENSION + "$", ""); +// result.add(new JarEntryObject(binaryName, file.toURI())); +// } +// } +// +// return result; +// } +} \ No newline at end of file diff --git a/util/src/main/java/deltix/util/lang/JavaCompilerHelper.java b/util/src/main/java/deltix/util/lang/JavaCompilerHelper.java index ada3f18b..638878f2 100644 --- a/util/src/main/java/deltix/util/lang/JavaCompilerHelper.java +++ b/util/src/main/java/deltix/util/lang/JavaCompilerHelper.java @@ -189,6 +189,32 @@ public JavaFileObject getJavaFileForOutput(Location location, String name, JavaF public ClassLoader getClassLoader(Location location) { return xcl; } + + @Override + public String inferBinaryName(Location location, JavaFileObject file) { + if (file instanceof JarEntryObject) { + return ((JarEntryObject) file).binaryName(); + } else { + return fileManager.inferBinaryName(location, file); + } + } + + @Override + public Iterable list(Location location, String packageName, Set kinds, boolean recurse) throws IOException { + if (location == StandardLocation.PLATFORM_CLASS_PATH) { + return fileManager.list(location, packageName, kinds, recurse); + } else if (location == StandardLocation.CLASS_PATH && kinds.contains(JavaFileObject.Kind.CLASS)) { + Iterable list = fileManager.list(location, packageName, kinds, recurse); + + List objects = JarScanner.list(xcl, packageName); + for (JavaFileObject object : list) + objects.add(object); + + return objects; + } + + return super.list(location, packageName, kinds, recurse); + } } From 998bf72360b0e6170c133803d057d8cb90b2f95b Mon Sep 17 00:00:00 2001 From: Robot Date: Fri, 23 Nov 2018 16:53:26 +0300 Subject: [PATCH 2116/2572] [Skip CI] Generate release version --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 3e68cc04..c51f4931 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ -#Thu Nov 22 13:52:03 MSK 2018 -version=5.2.39-SNAPSHOT +#Fri Nov 23 16:53:25 MSK 2018 +version=5.2.39 deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java From 2ae0573279f79db5c8d79452b02c5eaa473f8cc5 Mon Sep 17 00:00:00 2001 From: Robot Date: Fri, 23 Nov 2018 16:53:32 +0300 Subject: [PATCH 2117/2572] [Skip CI] Generate next development version --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index c51f4931..da650401 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ -#Fri Nov 23 16:53:25 MSK 2018 -version=5.2.39 +#Fri Nov 23 16:53:31 MSK 2018 +version=5.2.40-SNAPSHOT deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java From c41d8746386183b441f7bd8021af83dd4cd3457c Mon Sep 17 00:00:00 2001 From: Alex Karpovich Date: Thu, 13 Dec 2018 23:07:51 +0300 Subject: [PATCH 2118/2572] [*] currencies update --- .../deltix/util/currency/CurrencyCodes.xml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/util/src/main/resources/deltix/util/currency/CurrencyCodes.xml b/util/src/main/resources/deltix/util/currency/CurrencyCodes.xml index a595389e..1b9daa62 100644 --- a/util/src/main/resources/deltix/util/currency/CurrencyCodes.xml +++ b/util/src/main/resources/deltix/util/currency/CurrencyCodes.xml @@ -1580,7 +1580,19 @@ Verge XVG XVG - + + + 902 + USD Coin + USDC + USDC + + + 903 + Paxos + PAX + PAX + \ No newline at end of file From d4eab7a78db037debbd10c6dfd9aa80827fdc31b Mon Sep 17 00:00:00 2001 From: Robot Date: Thu, 13 Dec 2018 23:08:44 +0300 Subject: [PATCH 2119/2572] [Skip CI] Generate release version --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index da650401..3af5fd65 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ -#Fri Nov 23 16:53:31 MSK 2018 -version=5.2.40-SNAPSHOT +#Thu Dec 13 23:08:43 MSK 2018 +version=5.2.40 deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java From 84474a31f530403f88660e3d201bcf0d974e9687 Mon Sep 17 00:00:00 2001 From: Robot Date: Thu, 13 Dec 2018 23:08:50 +0300 Subject: [PATCH 2120/2572] [Skip CI] Generate next development version --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 3af5fd65..cb40763f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ -#Thu Dec 13 23:08:43 MSK 2018 -version=5.2.40 +#Thu Dec 13 23:08:50 MSK 2018 +version=5.2.41-SNAPSHOT deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java From f710b43c2bb2b91157f3c805ffb3b873831f97ef Mon Sep 17 00:00:00 2001 From: Artyom Korzun Date: Thu, 20 Dec 2018 12:44:41 +0300 Subject: [PATCH 2121/2572] added two more useful methods hashCode and equals, which take an element function as parameter, to CollectionUtil --- .../util/collections/CollectionUtil.java | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/collections/src/main/java/deltix/util/collections/CollectionUtil.java b/collections/src/main/java/deltix/util/collections/CollectionUtil.java index 74e62227..c9c7595f 100644 --- a/collections/src/main/java/deltix/util/collections/CollectionUtil.java +++ b/collections/src/main/java/deltix/util/collections/CollectionUtil.java @@ -8,7 +8,9 @@ import java.lang.reflect.Array; import java.util.*; +import java.util.function.BiPredicate; import java.util.function.Function; +import java.util.function.ToIntFunction; public class CollectionUtil { @@ -99,6 +101,20 @@ private static Object toArray(Collection values, Class componentType) { // region hashCode + public static int hashCode(final ObjectList list, + final ToIntFunction elementHashFunction) { + int hash = 0; + + if (list != null) { + for (int i = 0, size = list.size(); i < size; i++) { + final T object = list.getObjectNoRangeCheck(i); + hash = 31 * hash + elementHashFunction.applyAsInt(object); + } + } + + return hash; + } + public static int hashCode(final ObjectList list) { int hash = 0; @@ -194,6 +210,31 @@ public static int hashCode(final BooleanList list) { // region equals + public static boolean equals(final ObjectList lhs, + final ObjectList rhs, + final BiPredicate elementEqualsFunction) { + if (lhs == rhs) { + return true; + } + + if (lhs == null || rhs == null) { + return false; + } + + final int size = lhs.size(); + if (size != rhs.size()) { + return false; + } + + for (int i = 0; i < size; i++) { + if (!elementEqualsFunction.test(lhs.getObjectNoRangeCheck(i), rhs.getObjectNoRangeCheck(i))) { + return false; + } + } + + return true; + } + public static boolean equals(final ObjectList lhs, final ObjectList rhs) { if (lhs == rhs) { return true; From e4b1512c6e24fac06f3a4c198998445697dc10e8 Mon Sep 17 00:00:00 2001 From: Robot Date: Thu, 20 Dec 2018 12:45:15 +0300 Subject: [PATCH 2122/2572] [Skip CI] Generate release version --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index cb40763f..4f774d9f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ -#Thu Dec 13 23:08:50 MSK 2018 -version=5.2.41-SNAPSHOT +#Thu Dec 20 12:45:15 MSK 2018 +version=5.2.41 deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java From 3fb59af237590337a70feccf0f11a50d4270a721 Mon Sep 17 00:00:00 2001 From: Robot Date: Thu, 20 Dec 2018 12:45:22 +0300 Subject: [PATCH 2123/2572] [Skip CI] Generate next development version --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 4f774d9f..99af6e35 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ -#Thu Dec 20 12:45:15 MSK 2018 -version=5.2.41 +#Thu Dec 20 12:45:21 MSK 2018 +version=5.2.42-SNAPSHOT deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java From d821c28659d7553c4c265edd99d7447d7153313a Mon Sep 17 00:00:00 2001 From: Aliaksei Vavilau Date: Thu, 7 Feb 2019 04:02:37 +0300 Subject: [PATCH 2124/2572] [SKIP-CI] Add Poolable Object List. --- .../util/collections/PoolableObjectList.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 collections/src/main/java/deltix/util/collections/PoolableObjectList.java diff --git a/collections/src/main/java/deltix/util/collections/PoolableObjectList.java b/collections/src/main/java/deltix/util/collections/PoolableObjectList.java new file mode 100644 index 00000000..1d51608b --- /dev/null +++ b/collections/src/main/java/deltix/util/collections/PoolableObjectList.java @@ -0,0 +1,16 @@ +package deltix; + +import deltix.util.collections.generated.ObjectList; + +public interface PoolableObjectList extends ObjectList { + + int capacity(); + + void clear(); + + void hintCapacity(int capacity, Class type); + + void setSize(int count, Class type); + + Q append(Class type); +} From 087ac5622465a38ffe8ccb6cabd755a8697b9a04 Mon Sep 17 00:00:00 2001 From: Robot Date: Thu, 7 Feb 2019 04:03:41 +0300 Subject: [PATCH 2125/2572] [Skip CI] Generate release version --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 99af6e35..94910a91 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ -#Thu Dec 20 12:45:21 MSK 2018 -version=5.2.42-SNAPSHOT +#Thu Feb 07 04:03:41 MSK 2019 +version=5.2.42 deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java From 93df5831a4bdca1e0925de2fa1e6ca22ebd09cd1 Mon Sep 17 00:00:00 2001 From: Robot Date: Thu, 7 Feb 2019 04:03:48 +0300 Subject: [PATCH 2126/2572] [Skip CI] Generate next development version --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 94910a91..967c830c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ -#Thu Feb 07 04:03:41 MSK 2019 -version=5.2.42 +#Thu Feb 07 04:03:48 MSK 2019 +version=5.2.43-SNAPSHOT deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java From bcd0e785fe5695e7233004cded9e4afca84448e9 Mon Sep 17 00:00:00 2001 From: Aliaksei Vavilau Date: Fri, 8 Feb 2019 04:39:58 +0300 Subject: [PATCH 2127/2572] [SKIP-CI] Fix PoolableObjectList package. --- .../main/java/deltix/util/collections/PoolableObjectList.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collections/src/main/java/deltix/util/collections/PoolableObjectList.java b/collections/src/main/java/deltix/util/collections/PoolableObjectList.java index 1d51608b..c56e41a9 100644 --- a/collections/src/main/java/deltix/util/collections/PoolableObjectList.java +++ b/collections/src/main/java/deltix/util/collections/PoolableObjectList.java @@ -1,4 +1,4 @@ -package deltix; +package deltix.util.collections; import deltix.util.collections.generated.ObjectList; From 38c80922e937e9ac5a0f39e1fb523397555d53d1 Mon Sep 17 00:00:00 2001 From: Robot Date: Fri, 8 Feb 2019 04:41:33 +0300 Subject: [PATCH 2128/2572] [Skip CI] Generate release version --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 967c830c..32ff34d6 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ -#Thu Feb 07 04:03:48 MSK 2019 -version=5.2.43-SNAPSHOT +#Fri Feb 08 04:41:33 MSK 2019 +version=5.2.43 deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java From db08d130a6314a1aacc91730056b580b869199bc Mon Sep 17 00:00:00 2001 From: Robot Date: Fri, 8 Feb 2019 04:41:39 +0300 Subject: [PATCH 2129/2572] [Skip CI] Generate next development version --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 32ff34d6..b3e72e73 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ -#Fri Feb 08 04:41:33 MSK 2019 -version=5.2.43 +#Fri Feb 08 04:41:39 MSK 2019 +version=5.2.44-SNAPSHOT deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java From 314e7825afc05b878db530b3035ffe959fc2a426 Mon Sep 17 00:00:00 2001 From: Alex Karpovich Date: Wed, 20 Mar 2019 13:28:39 +0300 Subject: [PATCH 2130/2572] [*] additional method. --- lang/src/main/java/deltix/util/memory/MemoryDataOutput.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lang/src/main/java/deltix/util/memory/MemoryDataOutput.java b/lang/src/main/java/deltix/util/memory/MemoryDataOutput.java index 9f9bee86..4b1492b4 100644 --- a/lang/src/main/java/deltix/util/memory/MemoryDataOutput.java +++ b/lang/src/main/java/deltix/util/memory/MemoryDataOutput.java @@ -285,6 +285,10 @@ public void writeLong (long v) { mPos += 8; } + public void writeLong (Decimal64 v) { + writeDecimal64(v); + } + public void writeLongInverted (long v) { makeRoom (8); DataExchangeUtils.writeLongInvertBytes (mBuffer, mPos, v); From 91ce401972b92bf4b0c46de6e93c33fc72ea2402 Mon Sep 17 00:00:00 2001 From: Robot Date: Wed, 20 Mar 2019 10:30:29 +0000 Subject: [PATCH 2131/2572] [Skip CI] Generate release version --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index b3e72e73..b60bde7d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ -#Fri Feb 08 04:41:39 MSK 2019 -version=5.2.44-SNAPSHOT +#Wed Mar 20 10:30:29 UTC 2019 +version=5.2.44 deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java From 469e6f602b85f55db33f2118b984d135fa63a7eb Mon Sep 17 00:00:00 2001 From: Robot Date: Wed, 20 Mar 2019 10:30:41 +0000 Subject: [PATCH 2132/2572] [Skip CI] Generate next development version --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index b60bde7d..812bca8d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ -#Wed Mar 20 10:30:29 UTC 2019 -version=5.2.44 +#Wed Mar 20 10:30:41 UTC 2019 +version=5.2.45-SNAPSHOT deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java From 54db8981cdb601f44c770bb7d4cbfdbdbd67c534 Mon Sep 17 00:00:00 2001 From: Alex Karpovich Date: Thu, 11 Apr 2019 17:11:03 +0300 Subject: [PATCH 2133/2572] [*] dependencies --- util/build.gradle | 10 +- .../java/deltix/util/io/FileUploadBean.java | 198 ------------------ 2 files changed, 4 insertions(+), 204 deletions(-) delete mode 100644 util/src/main/java/deltix/util/io/FileUploadBean.java diff --git a/util/build.gradle b/util/build.gradle index 52f9a353..ea287d7a 100644 --- a/util/build.gradle +++ b/util/build.gradle @@ -10,18 +10,16 @@ dependencies { compile 'deltix:deltix-thread-affinity' - compile 'commons-lang:commons-lang', - 'org.apache.commons:commons-compress:1.7', - 'javax.servlet:javax.servlet-api:3.1.0' + compile 'commons-lang:commons-lang' + compile 'org.apache.commons:commons-compress:1.7' + //compile 'javax.servlet:javax.servlet-api:3.1.0' compileOnly 'com.google.code.findbugs:jsr305' - // compile('com.sun.xml.bind:jaxb-xjc:2.2.11') // 2.2.11 has only bug fixes compared 2.2.8-b130911.1802 (which used by Java 8) - compile('org.glassfish.jaxb:jaxb-runtime:2.2.11') // Glassfish replaces JAXB RI + compile 'org.glassfish.jaxb:jaxb-runtime:2.2.11' // Glassfish replaces JAXB RI //compile('javax.xml:jsr173:1.0'){ transitive = false } - compile('net.java.dev.jna:jna:3.4.0'){ transitive = false } compile('net.java.dev.jna:platform:3.4.0'){ transitive = false } compile('org.apache.bcel:bcel:6.0'){ transitive = false } diff --git a/util/src/main/java/deltix/util/io/FileUploadBean.java b/util/src/main/java/deltix/util/io/FileUploadBean.java deleted file mode 100644 index 4fc47adf..00000000 --- a/util/src/main/java/deltix/util/io/FileUploadBean.java +++ /dev/null @@ -1,198 +0,0 @@ -package deltix.util.io; - -import deltix.gflog.Log; -import deltix.gflog.LogFactory; - -import javax.servlet.ServletInputStream; -import javax.servlet.http.HttpServletRequest; -import java.io.BufferedWriter; -import java.io.FileWriter; -import java.io.IOException; -import java.io.PrintWriter; -import java.util.Dictionary; -import java.util.Hashtable; - -public class FileUploadBean { - private static final Log LOG = LogFactory.getLog(FileUploadBean.class); - - private String _savePath, _filepath, _filename, _contentType; - private Dictionary _fields; - - public String getFilename () { - return _filename; - } - - public String getFilepath () { - return _filepath; - } - - public void setSavePath (final String savePath) { - this._savePath = savePath; - } - - public String getContentType () { - return _contentType; - } - - public String getFieldValue (final String fieldName) { - if (_fields == null || fieldName == null) - return null; - return _fields.get (fieldName); - } - - private void setFilename (final String s) { - if (s == null) - return; - - int pos = s.indexOf ("filename=\""); - if (pos != -1) { - _filepath = s.substring (pos + 10, - s.length () - 1); - // Windows browsers include the full path on the client - // But Linux/Unix and Mac browsers only send the filename - // test if this is from a Windows browser - pos = _filepath.lastIndexOf ("\\"); - if (pos != -1) - _filename = _filepath.substring (pos + 1); - else - _filename = _filepath; - } - } - - private void setContentType (final String s) { - if (s == null) - return; - - final int pos = s.indexOf (": "); - if (pos != -1) - _contentType = s.substring (pos + 2, - s.length ()); - } - - public void doUpload (final HttpServletRequest request) throws IOException { - final ServletInputStream in = request.getInputStream (); - - final byte[] line = new byte[128]; - int i = in.readLine (line, - 0, - 128); - if (i < 3) - return; - final int boundaryLength = i - 2; - - final String boundary = new String (line, - 0, - boundaryLength); // -2 discards the - // newline - // character - _fields = new Hashtable (); - - while (i != -1) { - String newLine = new String (line, - 0, - i); - if (newLine.startsWith ("Content-Disposition: form-data; name=\"")) { - if (newLine.indexOf ("filename=\"") != -1) { - setFilename (new String (line, - 0, - i - 2)); - if (_filename == null) - return; - // this is the file content - i = in.readLine (line, - 0, - 128); - setContentType (new String (line, - 0, - i - 2)); - i = in.readLine (line, - 0, - 128); - // blank line - i = in.readLine (line, - 0, - 128); - newLine = new String (line, - 0, - i); - final PrintWriter pw = new PrintWriter (new BufferedWriter (new - FileWriter ((_savePath == null - ? "" - : _savePath) + - _filename))); - while (i != -1 && !newLine.startsWith (boundary)) { - // the problem is the last line of the file content - // contains the new line character. - // So, we need to check if the current line is - // the last line. - i = in.readLine (line, - 0, - 128); - // +4 is eof - if ((i == boundaryLength + 2 || i == boundaryLength + 4) && - (new String (line, - 0, - i).startsWith (boundary))) - pw.print (newLine.substring (0, - newLine.length () - 2)); - else - pw.print (newLine); - newLine = new String (line, - 0, - i); - - } - pw.close (); - - } else { - // this is a field - // get the field name - final int pos = newLine.indexOf ("name=\""); - final String fieldName = newLine.substring (pos + 6, - newLine.length () - 3); - // System.out.println("fieldName:" + fieldName); - // blank line - i = in.readLine (line, - 0, - 128); - i = in.readLine (line, - 0, - 128); - newLine = new String (line, - 0, - i); - final StringBuffer fieldValue = new StringBuffer (128); - while (i != -1 && !newLine.startsWith (boundary)) { - // The last line of the field - // contains the new line character. - // So, we need to check if the current line is - // the last line. - i = in.readLine (line, - 0, - 128); - // +4 is eof - if ((i == boundaryLength + 2 || i == boundaryLength + 4) - && - (new String (line, - 0, - i).startsWith (boundary))) - fieldValue.append (newLine.substring (0, - newLine.length () - 2)); - else - fieldValue.append (newLine); - newLine = new String (line, - 0, - i); - } - LOG.info( "%s<->%s").with(fieldName).with(fieldValue); - _fields.put (fieldName, - fieldValue.toString ()); - } - } - i = in.readLine (line, - 0, - 128); - - } // end while - } -} From 685a2de62e21bdbed80d03df535ab340bee281ef Mon Sep 17 00:00:00 2001 From: Robot Date: Thu, 11 Apr 2019 14:11:23 +0000 Subject: [PATCH 2134/2572] [Skip CI] Generate release version --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 812bca8d..c59a8b36 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ -#Wed Mar 20 10:30:41 UTC 2019 -version=5.2.45-SNAPSHOT +#Thu Apr 11 14:11:23 UTC 2019 +version=5.2.45 deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java From ba5004b9ef3877286adfda04426a979813807a2a Mon Sep 17 00:00:00 2001 From: Robot Date: Thu, 11 Apr 2019 14:11:32 +0000 Subject: [PATCH 2135/2572] [Skip CI] Generate next development version --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index c59a8b36..3e08c7db 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ -#Thu Apr 11 14:11:23 UTC 2019 -version=5.2.45 +#Thu Apr 11 14:11:32 UTC 2019 +version=5.2.46-SNAPSHOT deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java From 35b8f03d471dff1aaaf5249ab7efce9e92fdee2f Mon Sep 17 00:00:00 2001 From: Artyom Korzun Date: Mon, 22 Apr 2019 12:05:30 +0300 Subject: [PATCH 2136/2572] added check for nullness to CollectionUtil.copy(list, copyFunction) --- .../src/main/java/deltix/util/collections/CollectionUtil.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collections/src/main/java/deltix/util/collections/CollectionUtil.java b/collections/src/main/java/deltix/util/collections/CollectionUtil.java index c9c7595f..f4ec1511 100644 --- a/collections/src/main/java/deltix/util/collections/CollectionUtil.java +++ b/collections/src/main/java/deltix/util/collections/CollectionUtil.java @@ -412,7 +412,7 @@ public static ObjectArrayList copy(final ObjectList list, for (int i = 0; i < size; i++) { final T element = list.getObjectNoRangeCheck(i); - final T elementCopy = elementCopyFunction.apply(element); + final T elementCopy = (element == null) ? null : elementCopyFunction.apply(element); copy.add(elementCopy); } From 6a1961e02145829d3e1b76e2940dfae5d423794f Mon Sep 17 00:00:00 2001 From: Robot Date: Mon, 22 Apr 2019 09:05:55 +0000 Subject: [PATCH 2137/2572] [Skip CI] Generate release version --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 3e08c7db..3aff71e9 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ -#Thu Apr 11 14:11:32 UTC 2019 -version=5.2.46-SNAPSHOT +#Mon Apr 22 09:05:54 UTC 2019 +version=5.2.46 deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java From 1ae37915465735724461b2fb5abe8f11608c753c Mon Sep 17 00:00:00 2001 From: Robot Date: Mon, 22 Apr 2019 09:06:11 +0000 Subject: [PATCH 2138/2572] [Skip CI] Generate next development version --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 3aff71e9..e06e8381 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ -#Mon Apr 22 09:05:54 UTC 2019 -version=5.2.46 +#Mon Apr 22 09:06:11 UTC 2019 +version=5.2.47-SNAPSHOT deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java From 1436700d79f135a762ae865f24cbad670c683430 Mon Sep 17 00:00:00 2001 From: Alex Karpovich Date: Fri, 10 May 2019 14:51:40 +0300 Subject: [PATCH 2139/2572] [*] CurrencyCodes --- .../deltix/util/currency/CurrencyCodes.xml | 7211 +++++++++++++---- 1 file changed, 5614 insertions(+), 1597 deletions(-) diff --git a/util/src/main/resources/deltix/util/currency/CurrencyCodes.xml b/util/src/main/resources/deltix/util/currency/CurrencyCodes.xml index 1b9daa62..e2757de2 100644 --- a/util/src/main/resources/deltix/util/currency/CurrencyCodes.xml +++ b/util/src/main/resources/deltix/util/currency/CurrencyCodes.xml @@ -1,1598 +1,5615 @@ - - - - - 20 - ADP - ADP - ADP - - - 784 - UNITED ARAB EMIRATES - UAE Dirham - AED - د.Ø¥.†- - - 971 - AFGHANISTAN - Afghani - AFN - AFN - - - 8 - ALBANIA - Lek - ALL - Lek - - - 51 - ARMENIA - Armenian Dram - AMD - Õ¤Ö€. - - - 532 - NETHERLANDS ANTILLES - Netherlands Antillian Guikder - ANG - ANG - - - 973 - ANGOLA - Kwanza - AOA - AOA - - - 32 - ARGENTINA - Argentine Peso - ARS - $ - - - 40 - ATS - ATS - ATS - - - 36 - Australian Dollar - AUD - $ - - - 533 - ARUBA - Aruban Guilder - AWG - AWG - - - 31 - AZERBAIJAN - Azerbaijanian Manat - AZM - ман. - - - 977 - BOSNIA & HERZEGOVINA - Convertible Marks - BAM - KM - - - 52 - BARBADOS - Barbados Dollar - BBD - BBD - - - 50 - BANGLADESH - Taka - BDT - à§³ - - - 56 - BEF - BEF - BEF - - - 975 - BULGARIA - Bulgarian Lev - BGN - BGN - - - 48 - BAHRAIN - Bahraini Dinar - BHD - د.ب.†- - - 108 - BURUNDI - Burundi Franc - BIF - BIF - - - 60 - BERMUDA - Bermudian Dollar (customarily known as Bermuda Dollar) - BMD - BMD - - - 96 - BRUNEI DARUSSALAM - Brunei Dollar - BND - $ - - - 68 - BOLIVIA - Boliviano - BOB - $b - - - 984 - BOLIVIA - Mvdol - BOV - BOV - - - 986 - BRAZIL - Brazilian Real - BRL - R$ - - - 44 - BAHAMAS - Bahamian Dollar - BSD - BSD - - - 64 - BHUTAN - Ngultrum - BTN - BTN - - - 72 - BOTSWANA - Pula - BWP - BWP - - - 974 - BELARUS - Belarussian Ruble - BYR - BYR - - - 84 - BELIZE - Belize Dollar - BZD - BZ$ - - - 124 - CANADA - Canadian Dollar - CAD - $ - - - 976 - CONGO, THE DEMOCRATIC REPUBLIC OF - Franc Congolais - CDF - CDF - - - 947 - SWITZERLAND - WIR Euro - CHE - CHE - - - 756 - Swiss Franc - CHF - fr. - - - 948 - SWITZERLAND - WIR Franc - CHW - CHW - - - 990 - CHILE - UnNumericCodeades de formento - CLF - CLF - - - 152 - CHILE - Chilean Peso - CLP - $ - - - 156 - CHINA - Yuan Renminbi - CNY - Â¥ - - - 170 - COLOMBIA - Colombian Peso - COP - $ - - - 970 - COLOMBIA - UnNumericCodead de Valor Real - COU - COU - - - 188 - COSTA RICA - Costa Rican Colon - CRC - â‚¡ - - - 891 - SERBIA AND MONTENEGRO - Serbian Dinar - CSD - Дин. - - - 192 - CUBA - Cuban Peso - CUP - CUP - - - 132 - CAPE VERDE - Cape Verde Escudo - CVE - CVE - - - 196 - CYPRUS - Cyprus Pound - CYP - CYP - - - 203 - CZECH REPUBLIC - Czech Koruna - CZK - - - - 276 - DEM - DEM - DEM - - - 262 - DJIBOUTI - Djibouti Franc - DJF - DJF - - - 208 - Danish Krone - DKK - kr. - - - 214 - DOMINICAN REPUBLIC - Dominican Peso - DOP - RD$ - - - 12 - ALGERIA - Algerian Dinar - DZD - DZD - - - 233 - ESTONIA - Kroon - EEK - kr - - - 818 - EGYPT - Egyptian Pound - EGP - ج.Ù….†- - - 232 - ERITREA - Nakfa - ERN - ERN - - - 724 - ESP - ESP - ESP - - - 230 - ETHIOPIA - Ethiopian Birr - ETB - ETB - - - 978 - Euro - EUR - € - - - 246 - FIM - FIM - FIM - - - 242 - FIJI - Fiji Dollar - FJD - FJD - - - 238 - FALKLAND ISLANDS (MALVINAS) - Falkland Islands Pound - FKP - FKP - - - 250 - FRF - FRF - FRF - FRF - - - 826 - UNITED KINGDOM - Pound Sterling - GBP - £ - - - 981 - GEORGIA - Lari - GEL - Lari - - - 288 - GHANA - Cedi - GHC - GHC - - - 292 - GIBRALTAR - Gibraltar Pound - GIP - GIP - - - 270 - GAMBIA - Dalasi - GMD - GMD - - - 324 - GUINEA - Guinea Franc - GNF - GNF - - - 300 - GRD - GRD - GRD - - - 320 - GUATEMALA - Quetzal - GTQ - Q - - - 624 - GUINEA-BISSAU - Guinea-Bissau Peso - GWP - GWP - - - 328 - GUYANA - Guyana Dollar - GYD - GYD - - - 344 - HONG KONG - Hong Kong Dollar - HKD - HK$ - - - 340 - HONDURAS - Lempira - HNL - L. - - - 191 - CROATIA - Croatian Kuna - HRK - kn - - - 332 - HAITI - Gourde - HTG - HTG - - - 348 - HUNGARY - Forint - HUF - Ft - - - 360 - INDONESIA - Rupiah - IDR - Rp - - - 372 - IEP - IEP - IEP - - - 376 - ISRAEL - New Israeli Sheqel - ILS - ₪ - - - 356 - Indian Rupee - INR - Rs. - - - 368 - IRAQ - Iraqi Dinar - IQD - د.ع.†- - - 364 - IRAN (ISLAMIC REPUBLIC OF) - Iranian Rial - IRR - ريال - - - 352 - ICELAND - Iceland Krona - ISK - kr. - - - 380 - ITL - ITL - ITL - - - 388 - JAMAICA - Jamaican Dollar - JMD - J$ - - - 400 - JORDAN - Jordanian Dinar - JOD - د.ا.†- - - 392 - JAPAN - Yen - JPY - Â¥ - - - 404 - KENYA - Kenyan Shilling - KES - S - - - 417 - KYRGYZSTAN - Som - KGS - Ñом - - - 116 - CAMBODIA - Riel - KHR - ៛ - - - 174 - COMOROS - Comoro Franc - KMF - KMF - - - 408 - KOREA, DEMOCRATIC PEOPLE''S REPUBLIC OF - North Korean Won - KPW - KPW - - - 410 - KOREA, DEMOCRATIC PEOPLE''S REPUBLIC OF - Won - KRW - â‚© - - - 414 - KUWAIT - Kuwaiti Dinar - KWD - د.Ùƒ.†- - - 136 - CAYMAN ISLANDS - Cayman Islands Dollar - KYD - KYD - - - 398 - KAZAKHSTAN - Tenge - KZT - Т - - - 418 - LAO PEOPLE''S DEMOCRATIC REPUBLIC - Kip - LAK - LAK - - - 422 - LEBANON - Lebanese Pound - LBP - Ù„.Ù„.†- - - 144 - SRI LANKA - Sri Lanka Rupee - LKR - රු. - - - 430 - LIBERIA - Liberian Dollar - LRD - LRD - - - 426 - LESOTHO - Loti - LSL - LSL - - - 440 - LITHUANIA - Lithuanian Litas - LTL - Lt - - - 442 - LUF - LUF - LUF - - - 428 - LATVIA - Latvian Lats - LVL - Ls - - - 434 - LIBYAN ARAB JAMAHIRIYA - Libyan Dinar - LYD - د.Ù„.†- - - 504 - Moroccan Dirham - MAD - د.Ù….†- - - 498 - MOLDOVA, REPUBLIC OF - Moldovan Leu - MDL - MDL - - - 969 - MADAGASCAR - Malagascy Ariary - MGA - MGA - - - 807 - MACEDONIA, THE FORMER YUGOSLAV REPUBLIC OF - Denar - MKD - ден. - - - 104 - MYANMAR - Kyat - MMK - MMK - - - 496 - MONGOLIA - Tugrik - MNT - â‚® - - - 446 - MACAO - Pataca - MOP - MOP - - - 478 - MAURITANIA - Ouguiya - MRO - MRO - - - 470 - MALTA - Maltese Lira - MTL - Lm - - - 480 - MAURITIUS - Mauritius Rupee - MUR - MUR - - - 462 - MALDIVES - Rufiyaa - MVR - Þƒ. - - - 454 - MALAWI - Kwacha - MWK - MWK - - - 484 - MEXICO - Mexican Peso - MXN - $ - - - 979 - MEXICO - Mexican UnNumericCodead de Inversion (UNumericCode) - MXV - MXV - - - 458 - MALAYSIA - Malaysian Ringgit - MYR - RM - - - 943 - MOZAMBIQUE - Merical - MZN - MZN - - - 516 - NAMIBIA - Namibian Dollar - NAD - NAD - - - 566 - NIGERIA - Naira - NGN - NGN - - - 558 - NICARAGUA - Cordoba Oro - NIO - N - - - 528 - NLG - NLG - NLG - - - 578 - Norwegian Krone - NOK - kr - - - 524 - NEPAL - Nepalese Rupee - NPR - रॠ- - - 554 - New Zealand Dollar - NZD - $ - - - 512 - OMAN - Rial Omani - OMR - ر.ع.†- - - 590 - PANAMA - Balboa - PAB - B/. - - - 604 - PERU - Nuevo Sol - PEN - S/. - - - 598 - PAPUA NEW GUINEA - Kina - PGK - PGK - - - 608 - PHILIPPINES - Philippine Peso - PHP - PhP - - - 586 - PAKISTAN - Pakistan Rupee - PKR - Rs - - - 985 - POLAND - Zloty - PLN - zÅ‚ - - - 620 - PTE - PTE - PTE - - - 600 - PARAGUAY - Guarani - PYG - Gs - - - 634 - QATAR - Qatari Rial - QAR - ر.Ù‚.†- - - 642 - ROMANIA - Old Leu - ROL - lei - - - 946 - ROMANIA - New Leu - RON - RON - - - 643 - RUSSIAN FEDERATION - Russian Ruble - RUB - RUB - - - 646 - RWANDA - Rwanda Franc - RWF - RWF - - - 682 - SAUDI ARABIA - Saudi Riyal - SAR - ر.س.†- - - 90 - SOLOMON ISLANDS - Solomon Islands Dollar - SBD - SBD - - - 690 - SEYCHELLES - Seychelles Rupee - SCR - SCR - - - 736 - SUDAN - Sudanese Dinar - SDD - SDD - - - 752 - SWEDEN - Swedish Krona - SEK - kr - - - 702 - SINGAPORE - Singapore Dollar - SGD - $ - - - 654 - SAINT HELENA - Saint Helena Pound - SHP - SHP - - - 705 - SLOVENIA - Tolar - SIT - SIT - - - 703 - SLOVAKIA - Slovak Koruna - SKK - Sk - - - 694 - SIERRA LEONE - Leone - SLL - SLL - - - 706 - SOMALIA - Somali Shilling - SOS - SOS - - - 968 - SURINAME - Surinam Dollar - SRD - SRD - - - 678 - S?O TOME AND PRINCIPE - Dobra - STD - STD - - - 222 - EL SALVADOR - El Salvador Colon - SVC - SVC - - - 760 - SYRIAN ARAB REPUBLIC - Syrian Pound - SYP - Ù„.س.†- - - 748 - SWAZILAND - Lilangeni - SZL - SZL - - - 764 - THAILAND - Baht - THB - ฿ - - - 972 - TAJIKISTAN - Somoni - TJS - TJS - - - 795 - TURKMENISTAN - Manat - TMM - m. - - - 788 - TUNISIA - Tunisian Dinar - TND - د.ت.†- - - 776 - TONGA - Pa''anga - TOP - TOP - - - 949 - TURKEY - New Turkish Lira - TRY - YTL - - - 792 - TURKEY - Old Turkish Lira - TRL - ₤ - - - 780 - TRINNumericCodeAD AND TOBAGO - TrinNumericCodead and Tobago Dollar - TTD - TT$ - - - 901 - TAIWAN, PROVINCE OF CHINA - New Taiwan Dollar - TWD - NT$ - - - 834 - TANZANIA, UNITED REPUBLIC OF - Tanzanian Shilling - TZS - TZS - - - 980 - UKRAINE - Hryvnia - UAH - грн. - - - 800 - UGANDA - Uganda Shilling - UGX - UGX - - - 840 - US Dollar - USD - $ - - - 997 - UNITED STATES - (Next day) - USN - USN - - - 998 - UNITED STATES - (Same day) - USS - USS - - - 858 - URUGUAY - Peso Uruguayo - UYU - $U - - - 860 - UZBEKISTAN - Uzbekistan Sum - UZS - Ñўм - - - 862 - VENEZUELA - Bolivar - VEB - Bs - - - 704 - VIET NAM - Dong - VND - â‚« - - - 548 - VANUATU - Vatu - VUV - VUV - - - 882 - SAMOA - Tala - WST - WST - - - 950 - CFA Franc BEAC - XAF - XAF - - - 961 - Silver - XAG - XAG - - - 959 - Gold - XAU - XAU - - - 955 - Bond Markets Units European Composite Unit (EURCO) - XBA - XBA - - - 956 - European Monetary Unit (E.M.U.-6) - XBB - XBB - - - 957 - European Unit of Account 9(E.U.A.-9) - XBC - XBC - - - 958 - European Unit of Account 17(E.U.A.-17) - XBD - XBD - - - 951 - East Caribbean Dollar - XCD - XCD - - - 960 - INTERNATIONAL MONETARY FUND (I.M.F) - SDR - XDR - XDR - - - 952 - CFA Franc BCEAO - XOF - XOF - - - 964 - Palladium - XPD - XPD - - - 953 - CFP Franc - XPF - XPF - - - 962 - Platinum - XPT - XPT - - - 963 - AlphabeticCodes specifically reserved for testing purposes - XTS - XTS - - - 999 - The AlphabeticCodes assigned for transactions where no Name is involved are: - XXX - XXX - - - 886 - YEMEN - Yemeni Rial - YER - ر.ÙŠ.†- - - 710 - Rand - ZAR - R - - - 894 - ZAMBIA - Kwacha - ZMK - ZMK - - - 716 - ZIMBABWE - Zimbabwe Dollar - ZWD - Z$ - - - - - 777 - CHINA - Yuan Renminbi - CNH - Â¥ - - - - 641 - Litecoin - LTC - LTC - - - 741 - Bitcoin - XBT - XBT - - - 841 - Ethereum - ETH - ETH - - - - 301 - Ripple - XRP - XRP - - - 302 - Metaverse ETP - ETP - ETP - - - 303 - Bitcoin Cash - BCH - BCH - - - 304 - OmiseGO - OMG - OMG - - - 305 - NEO - NEO - NEO - - - 306 - Iota - IOT - IOT - - - 307 - DigitalCash - DSH - DSH - - - 308 - Zcash - ZEC - ZEC - - - 309 - Monero - XMR - XMR - - - 310 - Ethereum Classic - ETC - ETC - - - 311 - EOS - EOS - EOS - - - 312 - Aventus - AVT - AVT - - - 313 - Qtum - QTM - QTM - - - 314 - Santiment - SAN - SAN - - - 315 - Eidoo - EDO - EDO - - - 316 - Bitcoin Gold - BTG - BTG - - - 317 - Streamr - DAT - DAT - - - 318 - QASH - QSH - QSH - - - 319 - YOYOW - YYW - YYW - - - 321 - Tether - THR - THR - - - 322 - Cardano - ADA - ADA - - - - 323 - Binance Coin - BNB - BNB - - - 325 - Bread - BRD - BRD - - - 326 - Gifto - GTO - GTO - - - 327 - Iconomi - ICN - ICN - - - 329 - Icon - ICX - ICX - - - 330 - Lisk - LSK - LSK - - - 331 - Nano - NAN - NAN - - - 333 - Salt - SLT - SLT - - - 334 - Stratis - STR - STR - - - 335 - Tron - TRX - TRX - - - 336 - Wings - WNG - WNG - - - 337 - Stellar Lumens - XLM - XLM - - - 338 - Verge - XVG - XVG - - - 902 - USD Coin - USDC - USDC - - - 903 - Paxos - PAX - PAX - - - + + + + + 1301 + Ripple + XRP + XRP + + + 1302 + Metaverse ETP + ETP + ETP + + + 1303 + Bitcoin Cash + BCH + BCH + + + 1304 + OmiseGO + OMG + OMG + + + 1305 + Neo + NEO + NEO + + + 1306 + Iota + MIOTA + IOT + + + 1307 + DigitalCash + DASH + DSH + + + 1308 + Zcash + ZEC + ZEC + + + 1309 + Monero + XMR + XMR + + + 1310 + Ethereum Classic + ETC + ETC + + + 1311 + EOS + EOS + EOS + + + 1312 + Aventus + AVT + AVT + + + 1313 + Qtum + QTUM + QTM + + + 1314 + Santiment + SAN + SAN + + + 1315 + Eidoo + EDO + EDO + + + 1316 + Bitcoin Gold + BTG + BTG + + + 1317 + Streamr + DATA + DAT + + + 1318 + QASH + QASH + QSH + + + 1319 + YOYOW + YOYOW + YYW + + + 1321 + Tether + USDT + THR + + + 1322 + Cardano + ADA + ADA + + + 1323 + Binance Coin + BNB + BNB + + + 1325 + Bread + BRD + BRD + + + 1326 + Gifto + GTO + GTO + + + 1327 + Iconomi + ICN + ICN + + + 1329 + Icon + ICX + ICX + + + 1330 + Lisk + LSK + LSK + + + 1331 + Nano + NANO + NAN + + + 1333 + Salt + SALT + SLT + + + 1334 + Stratis + STRAT + STR + + + 1335 + Tron + TRX + TRX + + + 1336 + Wings + WINGS + WNG + + + 1337 + Stellar Lumens + XLM + XLM + + + 1338 + Verge + XVG + XVG + + + 1641 + Litecoin + LTC + LTC + + + 1741 + Bitcoin + BTC + XBT + + + 1841 + Ethereum + ETH + ETH + + + 8 + ALBANIA + Lek + ALL + Lek + + + 12 + ALGERIA + Algerian Dinar + DZD + DZD + + + 20 + ADP + ADP + ADP + + + 31 + AZERBAIJAN + Azerbaijanian Manat + AZM + ман. + + + 32 + ARGENTINA + Argentine Peso + ARS + $ + + + 36 + Australian Dollar + AUD + $ + + + 40 + ATS + ATS + ATS + + + 44 + BAHAMAS + Bahamian Dollar + BSD + BSD + + + 48 + BAHRAIN + Bahraini Dinar + BHD + د.ب.†+ + + 50 + BANGLADESH + Taka + BDT + à§³ + + + 51 + ARMENIA + Armenian Dram + AMD + Õ¤Ö€. + + + 52 + BARBADOS + Barbados Dollar + BBD + BBD + + + 56 + BEF + BEF + BEF + + + 60 + BERMUDA + Bermudian Dollar (customarily known as Bermuda Dol + BMD + BMD + + + 64 + BHUTAN + Ngultrum + BTN + BTN + + + 68 + BOLIVIA + Boliviano + BOB + $b + + + 72 + BOTSWANA + Pula + BWP + BWP + + + 84 + BELIZE + Belize Dollar + BZD + BZ$ + + + 90 + SOLOMON ISLANDS + Solomon Islands Dollar + SBD + SBD + + + 96 + BRUNEI DARUSSALAM + Brunei Dollar + BND + $ + + + 104 + MYANMAR + Kyat + MMK + MMK + + + 108 + BURUNDI + Burundi Franc + BIF + BIF + + + 116 + CAMBODIA + Riel + KHR + ៛ + + + 124 + CANADA + Canadian Dollar + CAD + $ + + + 132 + CAPE VERDE + Cape Verde Escudo + CVE + CVE + + + 136 + CAYMAN ISLANDS + Cayman Islands Dollar + KYD + KYD + + + 144 + SRI LANKA + Sri Lanka Rupee + LKR + රු. + + + 152 + CHILE + Chilean Peso + CLP + $ + + + 156 + CHINA + Yuan Renminbi + CNY + Â¥ + + + 170 + COLOMBIA + Colombian Peso + COP + $ + + + 174 + COMOROS + Comoro Franc + KMF + KMF + + + 188 + COSTA RICA + Costa Rican Colon + CRC + â‚¡ + + + 191 + CROATIA + Croatian Kuna + HRK + kn + + + 192 + CUBA + Cuban Peso + CUP + CUP + + + 196 + CYPRUS + Cyprus Pound + CYP + CYP + + + 203 + CZECH REPUBLIC + Czech Koruna + CZK + + + + 208 + Danish Krone + DKK + kr. + + + 214 + DOMINICAN REPUBLIC + Dominican Peso + DOP + RD$ + + + 222 + EL SALVADOR + El Salvador Colon + SVC + SVC + + + 230 + ETHIOPIA + Ethiopian Birr + ETB + ETB + + + 232 + ERITREA + Nakfa + ERN + ERN + + + 233 + ESTONIA + Kroon + EEK + kr + + + 238 + FALKLAND ISLANDS (MALVINAS) + Falkland Islands Pound + FKP + FKP + + + 242 + FIJI + Fiji Dollar + FJD + FJD + + + 246 + FIM + FIM + FIM + + + 250 + FRF + FRF + FRF + FRF + + + 262 + DJIBOUTI + Djibouti Franc + DJF + DJF + + + 270 + GAMBIA + Dalasi + GMD + GMD + + + 276 + DEM + DEM + DEM + + + 288 + GHANA + Cedi + GHC + GHC + + + 292 + GIBRALTAR + Gibraltar Pound + GIP + GIP + + + 300 + GRD + GRD + GRD + + + 320 + GUATEMALA + Quetzal + GTQ + Q + + + 324 + GUINEA + Guinea Franc + GNF + GNF + + + 328 + GUYANA + Guyana Dollar + GYD + GYD + + + 332 + HAITI + Gourde + HTG + HTG + + + 340 + HONDURAS + Lempira + HNL + L. + + + 344 + HONG KONG + Hong Kong Dollar + HKD + HK$ + + + 348 + HUNGARY + Forint + HUF + Ft + + + 352 + ICELAND + Iceland Krona + ISK + kr. + + + 356 + Indian Rupee + INR + Rs. + + + 360 + INDONESIA + Rupiah + IDR + Rp + + + 364 + IRAN (ISLAMIC REPUBLIC OF) + Iranian Rial + IRR + ريال + + + 368 + IRAQ + Iraqi Dinar + IQD + د.ع.†+ + + 372 + IEP + IEP + IEP + + + 376 + ISRAEL + New Israeli Sheqel + ILS + ₪ + + + 380 + ITL + ITL + ITL + + + 388 + JAMAICA + Jamaican Dollar + JMD + J$ + + + 392 + JAPAN + Yen + JPY + Â¥ + + + 398 + KAZAKHSTAN + Tenge + KZT + Т + + + 400 + JORDAN + Jordanian Dinar + JOD + د.ا.†+ + + 404 + KENYA + Kenyan Shilling + KES + S + + + 408 + KOREA, DEMOCRATIC PEOPLE''S REPUBLIC OF + North Korean Won + KPW + KPW + + + 410 + KOREA, DEMOCRATIC PEOPLE''S REPUBLIC OF + Won + KRW + â‚© + + + 414 + KUWAIT + Kuwaiti Dinar + KWD + د.Ùƒ.†+ + + 417 + KYRGYZSTAN + Som + KGS + Ñом + + + 418 + LAO PEOPLE''S DEMOCRATIC REPUBLIC + Kip + LAK + LAK + + + 422 + LEBANON + Lebanese Pound + LBP + Ù„.Ù„.†+ + + 426 + LESOTHO + Loti + LSL + LSL + + + 428 + LATVIA + Latvian Lats + LVL + Ls + + + 430 + LIBERIA + Liberian Dollar + LRD + LRD + + + 434 + LIBYAN ARAB JAMAHIRIYA + Libyan Dinar + LYD + د.Ù„.†+ + + 440 + LITHUANIA + Lithuanian Litas + LTL + Lt + + + 442 + LUF + LUF + LUF + + + 446 + MACAO + Pataca + MOP + MOP + + + 454 + MALAWI + Kwacha + MWK + MWK + + + 458 + MALAYSIA + Malaysian Ringgit + MYR + RM + + + 462 + MALDIVES + Rufiyaa + MVR + Þƒ. + + + 470 + MALTA + Maltese Lira + ^MTL + Lm + + + 478 + MAURITANIA + Ouguiya + MRO + MRO + + + 480 + MAURITIUS + Mauritius Rupee + MUR + MUR + + + 484 + MEXICO + Mexican Peso + MXN + $ + + + 496 + MONGOLIA + Tugrik + MNT + â‚® + + + 498 + MOLDOVA, REPUBLIC OF + Moldovan Leu + MDL + MDL + + + 504 + Moroccan Dirham + MAD + د.Ù….†+ + + 512 + OMAN + Rial Omani + OMR + ر.ع.†+ + + 516 + NAMIBIA + Namibian Dollar + NAD + NAD + + + 524 + NEPAL + Nepalese Rupee + NPR + रॠ+ + + 528 + NLG + NLG + NLG + + + 532 + NETHERLANDS ANTILLES + Netherlands Antillian Guikder + ANG + ANG + + + 533 + ARUBA + Aruban Guilder + AWG + AWG + + + 548 + VANUATU + Vatu + VUV + VUV + + + 554 + New Zealand Dollar + NZD + $ + + + 558 + NICARAGUA + Cordoba Oro + NIO + N + + + 566 + NIGERIA + Naira + NGN + NGN + + + 578 + Norwegian Krone + NOK + kr + + + 586 + PAKISTAN + Pakistan Rupee + PKR + Rs + + + 590 + PANAMA + Balboa + PAB + B/. + + + 598 + PAPUA NEW GUINEA + Kina + PGK + PGK + + + 600 + PARAGUAY + Guarani + PYG + Gs + + + 604 + PERU + Nuevo Sol + PEN + S/. + + + 608 + PHILIPPINES + Philippine Peso + PHP + PhP + + + 620 + PTE + PTE + PTE + + + 624 + GUINEA-BISSAU + Guinea-Bissau Peso + GWP + GWP + + + 634 + QATAR + Qatari Rial + QAR + ر.Ù‚.†+ + + 642 + ROMANIA + Old Leu + ROL + lei + + + 643 + RUSSIAN FEDERATION + Russian Ruble + RUB + RUB + + + 646 + RWANDA + Rwanda Franc + RWF + RWF + + + 654 + SAINT HELENA + Saint Helena Pound + SHP + SHP + + + 678 + S?O TOME AND PRINCIPE + Dobra + STD + STD + + + 682 + SAUDI ARABIA + Saudi Riyal + SAR + ر.س.†+ + + 690 + SEYCHELLES + Seychelles Rupee + SCR + SCR + + + 694 + SIERRA LEONE + Leone + SLL + SLL + + + 702 + SINGAPORE + Singapore Dollar + SGD + $ + + + 703 + SLOVAKIA + Slovak Koruna + SKK + Sk + + + 704 + VIET NAM + Dong + VND + â‚« + + + 705 + SLOVENIA + Tolar + SIT + SIT + + + 706 + SOMALIA + Somali Shilling + SOS + SOS + + + 710 + Rand + ZAR + R + + + 716 + ZIMBABWE + Zimbabwe Dollar + ZWD + Z$ + + + 724 + ESP + ESP + ESP + + + 736 + SUDAN + Sudanese Dinar + SDD + SDD + + + 748 + SWAZILAND + Lilangeni + SZL + SZL + + + 752 + SWEDEN + Swedish Krona + SEK + kr + + + 756 + Swiss Franc + CHF + fr. + + + 760 + SYRIAN ARAB REPUBLIC + Syrian Pound + SYP + Ù„.س.†+ + + 764 + THAILAND + Baht + THB + ฿ + + + 776 + TONGA + Pa''anga + TOP + TOP + + + 777 + CHINA + Yuan Renminbi + CNH + Â¥ + + + 780 + TRINNumericCodeAD AND TOBAGO + TrinNumericCodead and Tobago Dollar + TTD + TT$ + + + 784 + UNITED ARAB EMIRATES + UAE Dirham + AED + د.Ø¥.†+ + + 788 + TUNISIA + Tunisian Dinar + TND + د.ت.†+ + + 792 + TURKEY + Old Turkish Lira + TRL + ₤ + + + 795 + TURKMENISTAN + Manat + TMM + m. + + + 800 + UGANDA + Uganda Shilling + UGX + UGX + + + 807 + MACEDONIA, THE FORMER YUGOSLAV REPUBLIC OF + Denar + MKD + ден. + + + 818 + EGYPT + Egyptian Pound + EGP + ج.Ù….†+ + + 826 + UNITED KINGDOM + Pound Sterling + GBP + £ + + + 834 + TANZANIA, UNITED REPUBLIC OF + Tanzanian Shilling + TZS + TZS + + + 840 + US Dollar + USD + $ + + + 858 + URUGUAY + Peso Uruguayo + UYU + $U + + + 860 + UZBEKISTAN + Uzbekistan Sum + UZS + Ñўм + + + 862 + VENEZUELA + Bolivar + VEB + Bs + + + 882 + SAMOA + Tala + WST + WST + + + 886 + YEMEN + Yemeni Rial + YER + ر.ÙŠ.†+ + + 891 + SERBIA AND MONTENEGRO + Serbian Dinar + CSD + Дин. + + + 894 + ZAMBIA + Kwacha + ZMK + ZMK + + + 901 + TAIWAN, PROVINCE OF CHINA + New Taiwan Dollar + TWD + NT$ + + + 943 + MOZAMBIQUE + Merical + MZN + MZN + + + 946 + ROMANIA + New Leu + RON + RON + + + 947 + SWITZERLAND + WIR Euro + CHE + CHE + + + 948 + SWITZERLAND + WIR Franc + CHW + CHW + + + 949 + TURKEY + New Turkish Lira + TRY + YTL + + + 950 + CFA Franc BEAC + XAF + XAF + + + 951 + East Caribbean Dollar + XCD + XCD + + + 952 + CFA Franc BCEAO + XOF + XOF + + + 953 + CFP Franc + XPF + XPF + + + 955 + Bond Markets Units European Composite Unit (EURCO) + XBA + XBA + + + 956 + European Monetary Unit (E.M.U.-6) + XBB + XBB + + + 957 + European Unit of Account 9(E.U.A.-9) + XBC + XBC + + + 958 + European Unit of Account 17(E.U.A.-17) + XBD + XBD + + + 959 + Gold + XAU + XAU + + + 960 + INTERNATIONAL MONETARY FUND (I.M.F) + SDR + XDR + XDR + + + 961 + Silver + XAG + XAG + + + 962 + Platinum + XPT + XPT + + + 963 + AlphabeticCodes specifically reserved for testing + XTS + XTS + + + 964 + Palladium + XPD + XPD + + + 968 + SURINAME + Surinam Dollar + SRD + SRD + + + 969 + MADAGASCAR + Malagascy Ariary + MGA + MGA + + + 970 + COLOMBIA + UnNumericCodead de Valor Real + COU + COU + + + 971 + AFGHANISTAN + Afghani + AFN + AFN + + + 972 + TAJIKISTAN + Somoni + TJS + TJS + + + 973 + ANGOLA + Kwanza + AOA + AOA + + + 974 + BELARUS + Belarussian Ruble + BYR + BYR + + + 975 + BULGARIA + Bulgarian Lev + BGN + BGN + + + 976 + CONGO, THE DEMOCRATIC REPUBLIC OF + Franc Congolais + CDF + CDF + + + 977 + BOSNIA & HERZEGOVINA + Convertible Marks + BAM + KM + + + 978 + Euro + EUR + € + + + 979 + MEXICO + Mexican UnNumericCodead de Inversion (UNumericCode + MXV + MXV + + + 980 + UKRAINE + Hryvnia + UAH + грн. + + + 981 + GEORGIA + Lari + GEL + Lari + + + 984 + BOLIVIA + Mvdol + BOV + BOV + + + 985 + POLAND + Zloty + PLN + zÅ‚ + + + 986 + BRAZIL + Brazilian Real + BRL + R$ + + + 990 + CHILE + UnNumericCodeades de formento + CLF + CLF + + + 997 + UNITED STATES + (Next day) + USN + USN + + + 998 + UNITED STATES + (Same day) + USS + USS + + + 999 + + XXX + XXX + + + 1339 + Ark + ARK + ARK + + + 1341 + Komodo + KMD + KMD + + + 1342 + Power Ledger + POWR + PWR + + + 1343 + AdEx + ADX + ADX + + + 1345 + Aeternity + AE + AE + + + 1346 + Aion + AION + AIO + + + 1347 + Ambrosus + AMB + AMB + + + 1349 + AppCoins + APPC + APP + + + 1350 + Aeron + ARN + ARN + + + 1351 + AirSwap + AST + AST + + + 1353 + Basic Attention Token + BAT + BAT + + + 1354 + Bitcoin Diamond + BCD + BCD + + + 1355 + BlockMason Credit Protocol + BCPT + BCP + + + 1357 + Bluzelle + BLZ + BLZ + + + 1358 + Bancor + BNT + BNT + + + 1359 + ETHOS + ETHOS + BQX + + + 1361 + BitShares + BTS + BTS + + + 1362 + Blox + CDT + CDT + + + 1363 + ChatCoin + CHAT + CHT + + + 1365 + CyberMiles + CMT + CMT + + + 1366 + Cindicator + CND + CND + + + 1367 + Centra + CTR + CTR + + + 1369 + DigixDAO + DGD + DGD + + + 1370 + Agrello + DLT + DLT + + + 1371 + district0x + DNT + DNT + + + 1373 + aelf + ELF + ELF + + + 1374 + Enigma + ENG + ENG + + + 1375 + Enjin Coin + ENJ + ENJ + + + 1377 + Everex + EVX + EVX + + + 1378 + Etherparty + FUEL + FUE + + + 1379 + FunFair + FUN + FUN + + + 1381 + Gas + GAS + GAS + + + 1382 + Genesis Vision + GVT + GVT + + + 1383 + GXChain + GXS + GXS + + + 1384 + Hshare + HSR + HSR + + + 1385 + Insolar + INS + INS + + + 1386 + IOStoken + IOST + IOS + + + 1387 + Kyber Network + KNC + KNC + + + 1389 + Lendingblock + LND + LND + + + 1390 + ChainLink + LINK + LNK + + + 1391 + Loopring + LRC + LRC + + + 1393 + Lunyr + LUN + LUN + + + 1394 + Decentraland + MANA + MAN + + + 1395 + Crypto.com + MCO + MCO + + + 1396 + Moeda Loyalty Points + MDA + MDA + + + 1397 + Modum + MOD + MOD + + + 1399 + Monetha + MTH + MTH + + + 1401 + Metal + MTL + MET + + + 1402 + NavCoin + NAV + NAV + + + 1403 + Nucleus Vision + NCASH + NCH + + + 1405 + Neblio + NEBL + NEB + + + 1406 + Nuls + NULS + NUL + + + 1407 + OpenANX + OAX + OAX + + + 1409 + Ontology + ONT + ONT + + + 1411 + Simple Token + OST + OST + + + 1412 + PIVX + PIVX + PIV + + + 1413 + POA Network + POA + POA + + + 1415 + Po.et + POE + POE + + + 1416 + Populous + PPT + PPT + + + 1419 + QLINK + QLC + QLC + + + 1420 + Quantstamp + QSP + QSP + + + 1421 + Ripio Credit Network + RCN + RCN + + + 1423 + Raiden Network Token + RDN + RDN + + + 1424 + Request Network + REQ + REQ + + + 1425 + iExec RLC + RLC + RLC + + + 1427 + Red Pulse + PHX + RPX + + + 1429 + SingularDTV + SNGLS + SNG + + + 1431 + SONM + SNM + SNM + + + 1432 + Status + SNT + SNT + + + 1433 + Steem + STEEM + STM + + + 1435 + Storj + STORJ + STJ + + + 1436 + Storm + STORM + SRM + + + 1437 + Substratum + SUB + SUB + + + 1438 + Syscoin + SYS + SYS + + + 1439 + Time New Bank + TNB + TNB + + + 1441 + Tierion + TNT + TNT + + + 1443 + Triggers + TRIG + TRI + + + 1444 + VeChain + VET + VEN + + + 1445 + Viacoin + VIA + VIA + + + 1447 + Viberate + VIB + VIB + + + 1448 + VIBE + VIBE + VBE + + + 1449 + WaBi + WABI + WAB + + + 1450 + Wanchain + WAN + WAN + + + 1451 + Waves + WAVES + WVS + + + 1452 + WePower + WPR + WPR + + + 1453 + Waltonchain + WTC + WTC + + + 1455 + NEM + XEM + XEM + + + 1456 + ZCoin + XZC + XZC + + + 1457 + Zilliqa + ZIL + ZIL + + + 1459 + 0x Protocol + ZRX + ZRX + + + 1000 + HyperCash + HC + HC + + + 1001 + GoChain + GO + GO + + + 1002 + Paxos Standard Token + PAX + PAX + + + 1003 + Ravencoin + RVN + RVN + + + 1004 + Decred + DCR + DCR + + + 1005 + Mithril + MITH + MITH + + + 1006 + USD Coin + USDC + USDC + + + 1007 + Bitcoin SV + BSV + BSV + + + 1008 + Tezos + XTZ + XTZ + + + 1009 + Maker + MKR + MKR + + + 1010 + Dogecoin + DOGE + DOGE + + + 1011 + Bytecoin + BCN + BCN + + + 1012 + TrueUSD + TUSD + TUSD + + + 1013 + DigiByte + DGB + DGB + + + 1014 + Siacoin + SC + SC + + + 1015 + Bytom + BTM + BTM + + + 1016 + Pundi X + NPXS + NPXS + + + 1017 + Augur + REP + REP + + + 1018 + MaidSafeCoin + MAID + MAID + + + 1019 + Golem + GNT + GNT + + + 1020 + Electroneum + ETN + ETN + + + 1021 + Holo + HOT + HOT + + + 1022 + Cryptonex + CNX + CNX + + + 1023 + Factom + FCT + FCT + + + 1024 + Dai + DAI + DAI + + + 1025 + KuCoin Shares + KCS + KCS + + + 1026 + Worldwide Asset Exchange + WAX + WAX + + + 1027 + Ardor + ARDR + ARDR + + + 1028 + Huobi Token + HT + HT + + + 1029 + MOAC + MOAC + MOAC + + + 1030 + Revain + R + R + + + 1031 + MonaCoin + MONA + MONA + + + 1032 + Nexo + NEXO + NEXO + + + 1033 + ODEM + ODE + ODE + + + 1034 + Insight Chain + INB + INB + + + 1035 + ReddCoin + RDD + RDD + + + 1036 + Mixin + XIN + XIN + + + 1037 + Dentacoin + DCN + DCN + + + 1038 + Horizen + ZEN + ZEN + + + 1039 + Polymath + POLY + POLY + + + 1040 + Nasdacoin + NSD + NSD + + + 1041 + SIRIN LABS Token + SRN + SRN + + + 1042 + Digitex Futures + DGTX + DGTX + + + 1043 + Dropil + DROP + DROP + + + 1044 + Nxt + NXT + NXT + + + 1045 + MobileGo + MGO + MGO + + + 1046 + BOScoin + BOS + BOS + + + 1047 + TenX + PAY + PAY + + + 1048 + Theta Token + THETA + THETA + + + 1049 + Nebulas + NAS + NAS + + + 1050 + QuarkChain + QKC + QKC + + + 1051 + Loom Network + LOOM + LOOM + + + 1052 + Veritaseum + VERI + VERI + + + 1053 + Elastos + ELA + ELA + + + 1054 + WaykiChain + WICC + WICC + + + 1055 + ETERNAL TOKEN + XET + XET + + + 1056 + Dragonchain + DRGN + DRGN + + + 1057 + ProximaX + XPX + XPX + + + 1058 + Bitcoin Private + BTCP + BTCP + + + 1059 + Gemini Dollar + GUSD + GUSD + + + 1060 + Linkey + LKY + LKY + + + 1061 + BHPCash + BHPC + BHPC + + + 1062 + Smartlands + SLT + SLT + + + 1063 + Nectar + NEC + NEC + + + 1064 + Civic + CVC + CVC + + + 1065 + Odyssey + OCN + OCN + + + 1066 + Endor Protocol + EDR + EDR + + + 1067 + Bibox Token + BIX + BIX + + + 1068 + ARBITRAGE + ARB + ARB + + + 1069 + Optimal Shelf... + OSA + OSA + + + 1070 + Dent + DENT + DENT + + + 1071 + Groestlcoin + GRS + GRS + + + 1072 + Byteball Bytes + GBYTE + GBYTE + + + 1073 + RChain + RHOC + RHOC + + + 1074 + THEKEY + TKY + TKY + + + 1075 + Centrality + CENNZ + CENNZ + + + 1076 + Peercoin + PPC + PPC + + + 1077 + Emercoin + EMC + EMC + + + 1078 + ETH Lend + LEND + LEND + + + 1079 + Cloak Coin + CLOAK + CLOAK + + + 1080 + SKY + SKY + SKY + + + 1081 + IOTX + IOTX + IOTX + + + 1082 + AGI + AGI + AGI + + + 1083 + Nexus + NXS + NXS + + + 1084 + Key Coin + KEY + KEY + + + 1085 + Mainframe + MFT + MFT + + + 1086 + DOCK + DOCK + DOCK + + + 1087 + Bit Connect + BCC + BCC + + + 1088 + VEN + VEN + VEN + + + 1089 + Red Pulse + RPX + RPX + + + 1090 + REN + REN + REN + + + 1091 + Ethos + BQX + BQX + + + 1092 + BnkToTheFuture + BFT + BFT + + + 1093 + FSN + FSN + FSN + + + 1094 + Matrix + MAN + MAN + + + 1095 + Gnosis + GNO + GNO + + + 1096 + Melon + MLN + MLN + + + 1097 + Namecoin + NMC + NMC + + + 1098 + Vertcoin + VTC + VTC + + + 1099 + Burst + BURST + BURST + + + 1830 + Steem Dollars + STEEMD + SBD + + + 1332 + BitTorrent + BTT + BTT + + + 1831 + Clams + CLAM + CLAM + + + 1832 + FOAM + FOAM + FOAM + + + 1833 + GameCredits + GAME + GAME + + + 1835 + LBRY Credits + LBC + LBC + + + 1836 + Numeraire + NMR + NMR + + + 1837 + Pascal Coin + PASC + PASC + + + 1838 + Counterparty + XCP + XCP + + + 1839 + Primecoin + XPM + XPM + + + 1829 + StableUSD + USDS + USDS + + + 1823 + STASIS EURS + EURS + EURS + + + 1824 + UTRUST + UTK + UTK + + + 1825 + Cortex + CTXC + CTXC + + + 1827 + Project Pai + PAI + PAI + + + 1828 + SmartMesh + SMT + SMT + + + 1794 + Grin + GRIN + GRIN + + + 1796 + Unikoin Gold + UKG + UKG + + + 1797 + Genaro Network + GNX + GNX + + + 1798 + Penta + PNT + PNT + + + 1799 + Content Neutrality Network + CNN + CNN + + + 1801 + Cred + LBA + LBA + + + 1802 + Blocktix + TIX + TIX + + + 1803 + Lympo + LYM + LYM + + + 1804 + All Sports + SOC + SOC + + + 1805 + Jibrel Network + JNT + JNT + + + 1806 + DATA + DTA + DTA + + + 1808 + Achain + ACT + ACT + + + 1809 + TokenCard + TKN + TKN + + + 1810 + Propy + PRO + PRO + + + 1811 + DigitalNote + XDN + XDN + + + 1812 + Crypterium + CRPT + CRPT + + + 1813 + Aragon + ANT + ANT + + + 1814 + BLOCKv + VEE + VEE + + + 1815 + Blocknet + BLOCK + BLOCK + + + 1816 + PumaPay + PMA + PMA + + + 1817 + Ignis + IGNIS + IGNIS + + + 1819 + Edgeless + EDG + EDG + + + 1821 + Ontology Gas + ONG + ONG + + + 1822 + Fetch.AI + FET + FET + + + 1793 + HUSD Solution + HUSD + HUSD + + + 1632 + Ink Protocol + XNK + XNK + + + 1633 + Crowd Machine + CMCT + CMCT + + + 1636 + Nexium + NXC + NXC + + + 1637 + SIBCoin + SIB + SIB + + + 1638 + Swarm City + SWT + SWT + + + 1639 + Patientory + PTOY + PTOY + + + 1640 + BANKEX + BKX + BKX + + + 1644 + Matchpool + GUP + GUP + + + 1645 + Humaniq + HMQ + HMQ + + + 1647 + HyperSpace + AMP + AMP + + + 1648 + DECENT + DCT + DCT + + + 1649 + SpaceChain + SPC + SPC + + + 1650 + NAGA + NGC + NGC + + + 1651 + NoLimitCoin + NLC2 + NLC2 + + + 1652 + Aeon + AEON + AEON + + + 1653 + OriginTrail + TRAC + TRAC + + + 1655 + eBoost + EBST + EBST + + + 1656 + CannabisCoin + CANN + CANN + + + 1657 + Breakout + BRK + BRK + + + 1658 + Sequence + SEQ + SEQ + + + 1659 + TransferCoin + TX + TX + + + 1660 + Memetic / PepeCoin + MEME + MEME + + + 1661 + DopeCoin + DOPE + DOPE + + + 1662 + Internet of People + IOP + IOP + + + 1663 + VeriumReserve + VRM + VRM + + + 1664 + PinkCoin + PINK + PINK + + + 1665 + Syndicate + SYNX + SYNX + + + 1666 + 2GIVE + 2GIVE + 2GIVE + + + 1667 + ExclusiveCoin + EXCL + EXCL + + + 1668 + Dynamic + DYN + DYN + + + 1669 + ArtByte + ABY + ABY + + + 1670 + FoldingCoin + FLDC + FLDC + + + 1671 + Kore + KORE + KORE + + + 1672 + GeoCoin + GEO + GEO + + + 1673 + Expanse + EXP + EXP + + + 1674 + OKCash + OK + OK + + + 1675 + Musicoin + MUSIC + MUSIC + + + 1676 + Golos + GOLOS + GOLOS + + + 1677 + Blockparty (BOXX Token) + BOXX + BOXX + + + 1679 + Curecoin + CURE + CURE + + + 1680 + SolarCoin + SLR + SLR + + + 1681 + Bloom + BLT + BLT + + + 1683 + Decision Token + HST + HST + + + 1684 + Haven Protocol + XHV + XHV + + + 1685 + GridCoin + GRC + GRC + + + 1686 + MonetaryUnit + MUE + MUE + + + 1687 + Myriad + XMY + XMY + + + 1688 + Diamond + DMD + DMD + + + 1689 + I/O Coin + IOC + IOC + + + 1691 + Bean Cash + BITB + BITB + + + 1692 + Crown + CRW + CRW + + + 1693 + Radium + RADS + RADS + + + 1695 + VeriCoin + VRC + VRC + + + 1696 + Incent + INCNT + INCNT + + + 1697 + RevolutionVR + RVR + RVR + + + 1698 + XEL + XEL + XEL + + + 1699 + UpToken + UP + UP + + + 1700 + ION + ION + ION + + + 1701 + BitTube + TUBE + TUBE + + + 1707 + HempCoin + THC + THC + + + 1708 + Feathercoin + FTC + FTC + + + 1709 + Shift + SHIFT + SHIFT + + + 1711 + adToken + ADT + ADT + + + 1712 + PotCoin + POT + POT + + + 1713 + BlackCoin + BLK + BLK + + + 1714 + Sentinel Protocol + UPP + UPP + + + 1715 + Mercury + MER + MER + + + 1717 + Mobius + MOBI + MOBI + + + 1718 + ZClassic + ZCL + ZCL + + + 1719 + CashBet Coin + CBC + CBC + + + 1720 + Metronome + MET + MET + + + 1721 + VITE + VITE + VITE + + + 1722 + Hydro + HYDRO + HYDRO + + + 1723 + BitBay + BAY + BAY + + + 1725 + IHT Real Estate Protocol + IHT + IHT + + + 1726 + Refereum + RFR + RFR + + + 1727 + Ubiq + UBQ + UBQ + + + 1728 + FLO + FLO + FLO + + + 1729 + WhiteCoin + XWC + XWC + + + 1730 + Moss Coin + MOC + MOC + + + 1731 + NKN + NKN + NKN + + + 1732 + Quant + QNT + QNT + + + 1733 + Crypto.com Chain + CRO + CRO + + + 1734 + Particl + PART + PART + + + 1735 + Quantum Resistant Ledger + QRL + QRL + + + 1737 + DMarket + DMT + DMT + + + 1738 + SaluS + SLS + SLS + + + 1739 + MediBloc [ERC20] + MEDX + MEDX + + + 1740 + Einsteinium + EMC2 + EMC2 + + + 1742 + AidCoin + AID + AID + + + 1743 + Auctus + AUC + AUC + + + 1744 + Banyan Network + BBN + BBN + + + 1745 + Bitcoin Interest + BCI + BCI + + + 1746 + CommerceBlock + CBT + CBT + + + 1747 + Callisto Network + CLO + CLO + + + 1749 + Digix Gold Token + DGX + DGX + + + 1750 + Dether + DTH + DTH + + + 1751 + Essentia + ESS + ESS + + + 1753 + ParkinGo + GOT + GOT + + + 1754 + Internet Node Token + INT + INT + + + 1755 + On.Live + ONL + ONL + + + 1757 + Kleros + PNK + PNK + + + 1758 + RIF Token + RIF + RIF + + + 1759 + Rate3 + RTE + RTE + + + 1761 + Consensus + SEN + SEN + + + 1762 + Vetri + VLD + VLD + + + 1763 + WOLLO + WLO + WLO + + + 1765 + Xriba + XRA + XRA + + + 1766 + 0Chain + ZCN + ZCN + + + 1767 + Recovery Right Tokens + RRT + RRT + + + 1768 + Credits + CS + CS + + + 1769 + DADI + DADI + DADI + + + 1770 + Tether Euro + EURT + EURt + + + 1771 + Everipedia + IQ + IQ + + + 1772 + Medicalchain + MTN + MTN + + + 1773 + Autonio + ANIO + NIO + + + 1774 + Omni + OMNI + OMNI + + + 1775 + ORS Group + ORSG + ORS + + + 1778 + Blockpass + PASS + PASS + + + 1779 + RSK Smart Bitcoin + RBTC + RBTC + + + 1781 + SEER + SEER + SEER + + + 1782 + SpankChain + SPANK + SPANK + + + 1783 + Universa + UTNP + UTNP + + + 1785 + V Systems + VSYS + VSYS + + + 1786 + V Yggdrash + YEED + YEED + + + 1787 + Hydro Protocol + HOTP + HOT + + + 1789 + ContentBox + BOX + BOX + + + 1790 + Atonomi + ATMI + ATMI + + + 1791 + The Abyss + ABYSS + ABYSS + + + 1630 + Atlas Protocol + ATP + ATP + + + 1631 + 1BG + 1BG + 1BG + + + 1626 + Time Space Chain + TSC + TSC + + + 1627 + Berith + BRT + BRT + + + 1628 + BitMart Token + BMX + BMX + + + 1629 + Bitcoin HD + XHD + BHD + + + 1625 + WoChain + WOC + WOC + + + 1623 + Celer Network + CELR + CELR + + + 1622 + Ether Kingdoms Token + IMP + IMP + + + 1621 + Maecenas + ART + ART + + + 1619 + Veriblock + VBK + VBK + + + 1618 + PlayChip + PLA + PLA + + + 1617 + Orbs + ORBS + ORBS + + + 1614 + TTC Protocol + TTC + TTC + + + 1615 + Foresting + PTON + PTON + + + 1616 + PCHAIN + PI + PI + + + 1612 + Ankr + ANKR + ANKR + + + 1613 + Aergo + AERGO + AERGO + + + 1610 + Metadium + META + META + + + 1611 + GoldCoin + GLC + GLC + + + 1605 + PAL Network + PAL + PAL + + + 1606 + Solve.Care + SOLVE + SOLVE + + + 1607 + BTU Protocol + BTU + BTU + + + 1609 + Spendcoin + SPND + SPND + + + 1602 + Sphere + SPHR + SPHR + + + 1603 + Serve + SERV + SERV + + + 1597 + Circuits of Value + COVAL + COVAL + + + 1599 + Breakout Stake + BRX + BRX + + + 1601 + Bitswift + BITS + BITS + + + 1596 + Golos Gold + GBG + GBG + + + 1594 + EverGreenCoin + EGC + EGC + + + 1595 + Databits + DTB + DTB + + + 1587 + Qwark + QWARK + QWARK + + + 1588 + NeosCoin + NEOS + NEOS + + + 1589 + NuBits + NBT + NBT + + + 1591 + More Coin + MORE + MORE + + + 1592 + Hxro + HXRO + HXRO + + + 1593 + Gambit + GAM + GAM + + + 1584 + Stealth + XST + XST + + + 1585 + Tokes + TKS + TKS + + + 1582 + Gulden + CNLG + NLG + + + 1583 + BitSend + CBSD + BSD + + + 1581 + HunterCoin + HUC + HUC + + + 1580 + Livepeer + LPT + LPT + + + 1579 + BORA + BORA + BORA + + + 1577 + STACS + STACS + STACS + + + 1576 + HOT Token + HOTT + HOT + + + 1575 + DreamTeam + DREAM + DREAM + + + 1574 + TOP + TOPN + TOP + + + 1568 + Machine Xchange Coin + MXC + MXC + + + 1569 + COVA + COVA + COVA + + + 1570 + Lambda + LAMB + LAMB + + + 1571 + Content Value Network + CVNT + CVNT + + + 1572 + Ruff + RUFF + RUFF + + + 1573 + LinkEye + LET + LET + + + 1563 + Davinci Coin + DAC + DAC + + + 1564 + Tripio + TRIO + TRIO + + + 1565 + InvestDigital + IDT + IDT + + + 1567 + Huobi Pool Token + HPT + HPT + + + 1556 + ThingsOperatingSystem + TOS + TOS + + + 1557 + Globalvillage Ecosystem + GVE + GVE + + + 1559 + NeuroChain + NCC + NCC + + + 1560 + Kcash + KCASH + KCASH + + + 1561 + CVCoin + CVN + CVN + + + 1562 + BitCapitalVendor + BCV + BCV + + + 1551 + Yuan Chain Coin + YCC + YCC + + + 1552 + BitUP Token + BUT + BUT + + + 1553 + Smartshare + SSP + SSP + + + 1555 + MyToken + MT + MT + + + 1546 + DATx + DATX + DATX + + + 1547 + Themis + GET + GET + + + 1549 + GET Protocol + GETP + GET + + + 1550 + U Network + UUU + UUU + + + 1540 + XMax + XMX + XMX + + + 1541 + YouLive Coin + UC + UC + + + 1542 + Acute Angle Cloud + AAC + AAC + + + 1543 + Seele + SEELE + SEELE + + + 1544 + UnlimitedIP + UIP + UIP + + + 1545 + Litex + LXT + LXT + + + 1537 + FansTime + FTI + FTI + + + 1538 + Global Social Chain + GSC + GSC + + + 1539 + Promotion Coin + PC + PC + + + 1531 + EDUCare + EKT + EKT + + + 1534 + BeeKan + BKBT + BKBT + + + 1535 + FairGame + FAIR + FAIR + + + 1536 + Game.com + GTC + GTC + + + 1527 + Intelligent Investment Chain + IIC + IIC + + + 1529 + ShineChain + SHE + SHE + + + 1530 + MEX + MEX + MEX + + + 1522 + QunQun + QUN + QUN + + + 1523 + EduCoin + EDU + EDU + + + 1525 + BitcoinX + BCX + BCX + + + 1526 + HitChain + HIT + HIT + + + 1520 + SunContract + SNC + SNC + + + 1521 + STK + STK + STK + + + 1517 + YEE + YEE + YEE + + + 1518 + EchoLink + EKO + EKO + + + 1519 + DeepBrain Chain + DBC + DBC + + + 1513 + Zilla + ZLA + ZLA + + + 1514 + Arcblock + ABT + ABT + + + 1515 + Matryx + MTX + MTX + + + 1511 + BitKan + KAN + KAN + + + 1506 + TopChain + TOPC + TOPC + + + 1507 + CoinMeet + MEET + MEET + + + 1508 + SwftCoin + SWFTC + SWFTC + + + 1509 + MediShares + MDS + MDS + + + 1510 + IoT Chain + ITC + ITC + + + 1501 + Engine + EGCC + EGCC + + + 1502 + AI Doctor + AIDOC + AIDOC + + + 1503 + Super Bitcoin + SBTC + SBTC + + + 1505 + Bitcoin File + BIFI + BIFI + + + 1500 + IRIS Network + IRIS + IRIS + + + 1494 + Musk + MUSK + MUSK + + + 1495 + Portal + PORTAL + PORTAL + + + 1497 + RCCC + RCCC + RCCC + + + 1499 + Datum + DAT + DAT + + + 1492 + ZJLT Distributed Factoring Network + ZJLT + ZJLT + + + 1493 + Block 18 + 18C + 18C + + + 1491 + MARK.SPACE + MRK + MRK + + + 1490 + AdHive + ADH + ADH + + + 1479 + FLIP + FLP + FLP + + + 1489 + Dragon Coins + DRG + DRG + + + 1481 + FarmaTrust + FTT + FTT + + + 1482 + LikeCoin + LIKE + LIKE + + + 1483 + Morpheus Labs + MITX + MITX + + + 1485 + Stox + STX + STX + + + 1486 + ZPER + ZPR + ZPR + + + 1487 + FintruX Network + FTX + FTX + + + 1488 + Plus-Coin + NPLC + NPLC + + + 1477 + Huobi 10 Index + HB10 + HB10 + + + 1476 + Obsidian + ODN + ODN + + + 1472 + Pitch + PITCH + PITCH + + + 1473 + Purple Butterfly Trading + PBTT + PBTT + + + 1474 + Patron + PAT + PAT + + + 1475 + Opus + OPT + OPT + + + 1463 + ProCurrency + PROC + PROC + + + 1464 + Presearch + PRE + PRE + + + 1465 + Paymon + PMNT + PMNT + + + 1466 + Pluton + PLU + PLU + + + 1467 + Pillar + PLR + PLR + + + 1468 + Polybius + PLBT + PLBT + + + 1469 + Playkey + PKT + PKT + + + 1471 + Lampix + PIX + PIX + + + 1460 + Quanta Utility Token + QNTU + QNTU + + + 1461 + PlayGame + PXG + PXG + + + 1842 + imbrex + REX + REX + + + 1843 + BitRent + RNTB + RNTB + + + 1844 + Robotina + ROX + ROX + + + 1845 + Rivetz + RVT + RVT + + + 1846 + Sociall + SCL + SCL + + + 1847 + Sentinel + SENT + SENT + + + 1848 + ShipChain + SHIP + SHIP + + + 1849 + Signal Token + SIG + SIG + + + 1850 + SilkChain + SILK + SILK + + + 1851 + Slate + SLX + SLX + + + 1852 + SmartCash + SMART + SMART + + + 1853 + Snowball + SNBL + SNBL + + + 1854 + SPINDLE + SPD + SPD + + + 1855 + SportyCo + SPF + SPF + + + 1856 + Starbase + STAR + STAR + + + 1857 + Storiqa + STQ + STQ + + + 1859 + Sunchain + SUNC + SUNC + + + 1861 + Suretly + SUR + SUR + + + 1863 + savedroid + SVD + SVD + + + 1864 + Swarm + SWM + SWM + + + 1865 + TaaS + TAAS + TAAS + + + 1866 + Lamden + TAU + TAU + + + 1867 + TrueDeck + TDP + TDP + + + 1868 + TokenDesk + TDS + TDS + + + 1869 + Telcoin + TEL + TEL + + + 1870 + Chronobank + TIME + TIME + + + 1871 + Tradcoin + TRAD + TRAD + + + 1872 + WeTrust + TRST + TRST + + + 1873 + TrueChain + TRUE + TRUE + + + 1874 + Useless Ethereum Token + UET + UET + + + 1875 + Usechain Token + USE + USE + + + 1876 + United Traders Token + UTT + UTT + + + 1877 + VeriME + VME + VME + + + 1878 + Provoco Token + VOCO + VOCO + + + 1879 + Wiki Token + WIKI + WIKI + + + 1880 + CrowdWiz + WIZ + WIZ + + + 1881 + Xaurum + XAUR + XAUR + + + 1883 + BlitzPredict + XBP + XBP + + + 1884 + Monero Classic + XMC + XMC + + + 1885 + Exchange Union + XUC + XUC + + + 1887 + Zap + ZAP + ZAP + + + 1888 + Zeepin + ZPT + ZPT + + + 1889 + ZrCoin + ZRC + ZRC + + + 1890 + Zeusshield + ZSC + ZSC + + + 2000 + ATLANT Token + ATL + ATL + + + 2001 + BANCA + BANCA + BANCA + + + 2002 + Berry + BERRY + BERRY + + + 2003 + BetterBetting + BETR + BETR + + + 2004 + BitClave + CAT + CAT + + + 2005 + Bitcore + BTX + BTX + + + 2006 + BitDegree + BDG + BDG + + + 2007 + BitDice + CSNO + CSNO + + + 2008 + Black Moon + BMC + BMC + + + 2009 + BlockMesh + BMH + BMH + + + 2010 + Cashaa + CAS + CAS + + + 2011 + CoinPoker + CHP + CHP + + + 2012 + COPYTRACK + CPY + CPY + + + 2013 + Covesting + COV + COV + + + 2014 + Crypto20 + C20 + C20 + + + 2015 + Cryptopay + CPAY + CPAY + + + 2016 + CUBE + AUTO + AUTO + + + 2017 + Curriculum Vitae + CVH + CVH + + + 2018 + CyberVeinToken + CVT + CVT + + + 2019 + DAO Casino + BET + BET + + + 2020 + DecentBet + DBET + DBET + + + 2021 + DIMCOIN + DIM + DIM + + + 2022 + Etheroll + DICE + DICE + + + 2023 + First Blood + 1ST + 1ST + + + 2024 + Fortuna + FOTA + FOTA + + + 2025 + GoByte + GBX + GBX + + + 2026 + Happycoin + HPC + HPC + + + 2027 + Hive Project + HVN + HVN + + + 2028 + indaHash + IDH + IDH + + + 2029 + InsurChain + INSUR + INSUR + + + 2030 + InsurePal + IPL + IPL + + + 2031 + iXledger + IXT + IXT + + + 2032 + KickCoin + KICK + KICK + + + 2033 + KIN + KIN + KIN + + + 2034 + LAToken + LA + LA + + + 2035 + Life + LIFE + LIFE + + + 2036 + LockTrip + LOC + LOC + + + 2037 + MeshBox + MESH + MESH + + + 2038 + Micro Money + AMM + AMM + + + 2039 + Mybit + MYB + MYB + + + 2040 + Nectar + NCT + NCT + + + 2041 + Neumark + NEU + NEU + + + 2042 + NOAHCOIN + NOAH + NOAH + + + 2043 + SwissBorg + CHSB + CHSB + + + 2044 + Alphacat + ACAT + ACAT + + + 2045 + Freyr Chain + FREC + FREC + + + 2046 + Consentium + CSM + CSM + + + 2047 + Nanjcoin + NANJ + NANJ + + + 2048 + NeuroToken + NTK + NTK + + + 2049 + FuzeX + FXT + FXT + + + 2050 + Chainium + CHX + CHX + + + 2051 + FriendZ Coin + FDZ + FDZ + + + 2052 + Cryptaur + CPT + CPT + + + 2053 + HTMLCOIN + HTML + HTML + + + 2054 + Banker Token + BNK + BNK + + + 2055 + KaratBank Coin + KBC + KBC + + + 2056 + Ink + INK + INK + + + 2057 + Colu Local Network + CLN + CLN + + + 2058 + LitecoinCash + LCC + LCC + + + 2059 + ElectrifyAsia + ELEC + ELEC + + + 2060 + BitRewards + BIT + BIT + + + 2061 + CosmoCoin + COSM + COSM + + + 2062 + Kind Ads + KIND + KIND + + + 2063 + Inmediate + DIT + DIT + + + 2064 + CyClean + CCL + CCL + + + 2065 + Nimiq + NIM + NIM + + + 2066 + AML Bitcoin + ABTC + ABTC + + + 2067 + EcosBall + ABA + ABA + + + 2068 + Messe + MESSE + MESSE + + + 2069 + AXpire + AXPR + AXPR + + + 2070 + Constellation + DAG + DAG + + + 2071 + Acorn Collective Token + OAK + OAK + + + 2072 + Marginless + MRS + MRS + + + 2073 + Dynamic Trading Rights + DTR + DTR + + + 1892 + BOX Token + BOXT + BOX + + + 1893 + Bitcoinus + BITSS + BITS + + + 1895 + 1World + 1WO + 1WO + + + 1896 + AMLT + AMLT + AMLT + + + 1897 + Biotron + BTRN + BTRN + + + 1898 + CanYaCoin + CAN + CAN + + + 1899 + XAYA + CHI + CHI + + + 1900 + DACSEE + DACS + DACS + + + 1902 + Earth Token + EARTH + EARTH + + + 1903 + EZToken + EZT + EZT + + + 1904 + Flixxo + FLIXX + FLIXX + + + 1905 + DAOstack + GEN + GEN + + + 1906 + GazeCoin + GZE + GZE + + + 1907 + Invictus Hyperion Fund + IHF + IHF + + + 1908 + IP Exchange + IPSX + IPSX + + + 1909 + Kryll + KRL + KRL + + + 1910 + LALA World + LALA + LALA + + + 1911 + SalPay + SAL + SAL + + + 1912 + Signals Network + SGN + SGN + + + 1913 + SIX + SIX + SIX + + + 1914 + SnipCoin + SNIP + SNIP + + + 1915 + SophiaTX + SPHTX + SPHTX + + + 1916 + Thrive Token + THRT + THRT + + + 1917 + TokenPay + TPAY + TPAY + + + 1918 + Unibright + UBT + UBT + + + 1919 + Proxeus + XES + XES + + + 1920 + Zebi + ZCO + ZCO + + + 1921 + Bryllite + BRC + BRC + + + 1922 + FidentiaX + FDX + FDX + + + 1923 + Global Awards Token + GAT + GAT + + + 1924 + onG.social + ONGS + ONG + + + 1925 + StarterCoin + STAC + STAC + + + 1926 + Teleport + TPT + TPT + + + 1927 + TaTaTu + TTU + TTU + + + 1928 + WCoin + WIN + WIN + + + 1929 + bitJob + STU + STU + + + 1930 + Cosmos + ATOM + ATOM + + + 1931 + XND + XND + XND + + + 1932 + SCRL + SCRL + SCR + + + 1933 + UGAS + UGAS + UGAS + + + 1934 + Matic Network + MATIC + MATIC + + + 1935 + Wrapped Bitcoin + WBTC + WBTC + + + 1936 + CryptoFranc + XCHF + XCHF + + + 1937 + Function X + FX + FX + + + 1938 + Ocean + OCEAN + OCEAN + + + 1939 + XYO + XYO + XYO + + + 1940 + Wibson + WIB + WIB + + + 1941 + Blue Whale Token + BWX + BWX + + + 1942 + Newton Project + NEW + NEW + + + 1944 + ThunderCore + TT + TT + + \ No newline at end of file From 145bcf0d3790c96e6652c62ab0daa379a2e9556a Mon Sep 17 00:00:00 2001 From: Robot Date: Fri, 10 May 2019 14:52:28 +0300 Subject: [PATCH 2140/2572] [Skip CI] Generate release version --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index e06e8381..bbd41762 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ -#Mon Apr 22 09:06:11 UTC 2019 -version=5.2.47-SNAPSHOT +#Fri May 10 14:52:28 MSK 2019 +version=5.2.47 deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java From b5c62d0350663734df2767d6451ae9a7353ea754 Mon Sep 17 00:00:00 2001 From: Robot Date: Fri, 10 May 2019 14:52:35 +0300 Subject: [PATCH 2141/2572] [Skip CI] Generate next development version --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index bbd41762..868bc422 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ -#Fri May 10 14:52:28 MSK 2019 -version=5.2.47 +#Fri May 10 14:52:34 MSK 2019 +version=5.2.48-SNAPSHOT deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java From fd5693200856a8963cf4a777eac803df05011628 Mon Sep 17 00:00:00 2001 From: Artyom Korzun Date: Mon, 3 Jun 2019 11:09:15 +0300 Subject: [PATCH 2142/2572] added a method to FixedSizeCharSeqToObjectMap::putAndGetIfEmpty --- .../FixedSizeCharSeqToObjectMap.java | 34 ++++++++++++++++--- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/collections/src/main/java/deltix/util/collections/FixedSizeCharSeqToObjectMap.java b/collections/src/main/java/deltix/util/collections/FixedSizeCharSeqToObjectMap.java index 67d4874f..50ba222d 100644 --- a/collections/src/main/java/deltix/util/collections/FixedSizeCharSeqToObjectMap.java +++ b/collections/src/main/java/deltix/util/collections/FixedSizeCharSeqToObjectMap.java @@ -1,7 +1,5 @@ package deltix.util.collections; -import deltix.util.collections.generated.CharacterHashMapBase; - import java.util.Arrays; import java.util.Iterator; @@ -26,7 +24,11 @@ public V get(CharSequence key) { return map.get(key); } - public V putIfEmpty(CharSequence key, V value) { + public boolean putIfEmpty(CharSequence key, V value) { + return map.putIfEmpty(key, value); + } + + public V putAndGetIfEmpty(CharSequence key, V value) { return map.putAndGetIfEmpty(key, value); } @@ -41,7 +43,7 @@ Iterator iterator() { /// Hides access to Map itself to avoid accidental access to base class functionality like .remove(). - private static class LimitedCharSeq2ObjectHashMap extends CharSequenceToObjectMapQuick { + private static class LimitedCharSeq2ObjectHashMap extends CharSequenceToObjectMapQuick { private final OnDeleteCallback itemDeleteCallback; private final CircularBufferOfInt insertionPoints; private Object [] values; @@ -66,6 +68,7 @@ public V get (CharSequence key) { * @param value The value * @return Element that remains in the map. Never null. */ + @Override @SuppressWarnings("unchecked") public V putAndGetIfEmpty (CharSequence key, V value) { int hidx = hashIndex (key); @@ -89,6 +92,29 @@ public V putAndGetIfEmpty (CharSequence key, V value) { return value; } + @Override + public boolean putIfEmpty(final CharSequence key, final V value) { + int hidx = hashIndex (key); + int idx = find (hidx, key); + + if (idx != NULL) { + return false; + } + + if (freeHead == NULL) { + idx = insertionPoints.tail(); // no more free capacity => evict the oldest entry + assert idx != CircularBufferOfInt.EMPTY; + free (idx); + } + + idx = allocEntry (hidx); + + values [idx] = value; + keys [idx] = key; + insertionPoints.add(idx); + return true; + } + @SuppressWarnings("unchecked") @Override protected void free(int idx) { From 7632dac9ff39b4562692b057d21cedb2eb560349 Mon Sep 17 00:00:00 2001 From: Artyom Korzun Date: Mon, 3 Jun 2019 11:13:14 +0300 Subject: [PATCH 2143/2572] fixed tests --- .../collections/Test_FixedSizeCharSeqToOrderHashMap.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/collections/src/test/java/deltix/util/collections/Test_FixedSizeCharSeqToOrderHashMap.java b/collections/src/test/java/deltix/util/collections/Test_FixedSizeCharSeqToOrderHashMap.java index 2a606b96..9fa33648 100644 --- a/collections/src/test/java/deltix/util/collections/Test_FixedSizeCharSeqToOrderHashMap.java +++ b/collections/src/test/java/deltix/util/collections/Test_FixedSizeCharSeqToOrderHashMap.java @@ -53,7 +53,7 @@ public void testSingleElement() { public void testPutIfEmpty() { map.putIfEmpty("1", 11L); assertEquals(new Long(11), get(1)); - Long result = map.putIfEmpty("1", 111L); // shouldn't affect map + Long result = map.putAndGetIfEmpty("1", 111L); // shouldn't affect map assertEquals(new Long(11), result); assertEquals(new Long(11), get(1)); @@ -163,13 +163,13 @@ private void insert(int key, Long value) { } private void insert(CharSequence key, Long value) { - Long newItem = map.putIfEmpty(key, value); + Long newItem = map.putAndGetIfEmpty(key, value); assertSame(newItem, value); } private void override(CharSequence key, Long value) { - Long newItem = map.putIfEmpty(key, value); + Long newItem = map.putAndGetIfEmpty(key, value); assertNotSame(newItem, value); } From c9ecb2f90b9fa488e1200e96e02c73255087f596 Mon Sep 17 00:00:00 2001 From: Artyom Korzun Date: Mon, 3 Jun 2019 11:17:36 +0300 Subject: [PATCH 2144/2572] fixed CI to use remote temp branch --- .gitlab-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 8872d49c..f9203c45 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -58,9 +58,9 @@ cache: - git config user.name "Robot" - git config user.email "" - git remote set-url --push origin "${CI_PUSH_REPO}" - - git checkout pipeline-$CI_PIPELINE_ID~1 + - git checkout origin/pipeline-$CI_PIPELINE_ID~1 - ./gradlew pushVersion --no-daemon - - git checkout pipeline-$CI_PIPELINE_ID + - git checkout origin/pipeline-$CI_PIPELINE_ID - git push origin origin/pipeline-$CI_PIPELINE_ID:${CI_BUILD_REF_NAME} tags: - Linux From 5095c0331ec7fb6afa4393f92920776f96815403 Mon Sep 17 00:00:00 2001 From: Robot Date: Mon, 3 Jun 2019 11:18:10 +0300 Subject: [PATCH 2145/2572] [Skip CI] Generate release version --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 868bc422..163d2a61 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ -#Fri May 10 14:52:34 MSK 2019 -version=5.2.48-SNAPSHOT +#Mon Jun 03 11:18:09 MSK 2019 +version=5.2.48 deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java From f6f802693882dd88c8bf68e11fe9443ac6e22205 Mon Sep 17 00:00:00 2001 From: Robot Date: Mon, 3 Jun 2019 11:18:16 +0300 Subject: [PATCH 2146/2572] [Skip CI] Generate next development version --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 163d2a61..83955d25 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ -#Mon Jun 03 11:18:09 MSK 2019 -version=5.2.48 +#Mon Jun 03 11:18:16 MSK 2019 +version=5.2.49-SNAPSHOT deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java From b0c01e2380bc651818c344f5ac1551d59dd0fcf7 Mon Sep 17 00:00:00 2001 From: Aliaksei Vavilau Date: Tue, 4 Jun 2019 03:36:24 +0300 Subject: [PATCH 2147/2572] Add support for HdDateTime and HdTimeSpan. Correct serialization/deserialization --- collections/build.gradle | 18 ++++--- collections/src/main/templates/ArrayList.vpp | 50 +++++++++++++++---- collections/src/main/templates/List.vpp | 4 ++ .../main/templates/PrimitiveComparator.vpp | 12 +++++ .../src/main/templates/PrimitiveEntry.vpp | 10 +++- .../main/templates/PrimitiveEnumeration.vpp | 4 ++ .../main/templates/PrimitiveHashMapBase.vpp | 6 ++- .../src/main/templates/PrimitiveHashSet.vpp | 16 +++++- .../templates/PrimitiveToPrimitiveHashMap.vpp | 4 ++ gradle.properties | 2 + lang/build.gradle | 3 +- .../deltix/util/memory/DataExchangeUtils.java | 12 ++++- 12 files changed, 119 insertions(+), 22 deletions(-) diff --git a/collections/build.gradle b/collections/build.gradle index 0328994b..bd6d781e 100644 --- a/collections/build.gradle +++ b/collections/build.gradle @@ -40,49 +40,53 @@ ext { types.Object = [ name : 'Object', 'name_abbr' : 'Object', type : 'Object', 'type_Object' : 'ObjectType', size : 'SIZE_OF_POINTER' ] types.Decimal = [ name : 'Decimal', 'name_abbr' : 'Decimal', type : 'Decimal64', 'type_Object' : 'Decimal64', size : 'SIZE_OF_POINTER' ] + + types.HdDateTime = [ name : 'HdDateTime', 'name_abbr' : 'HdDateTime', type : 'HdDateTime', 'type_Object' : 'HdDateTime', size : 'SIZE_OF_POINTER' ] + + types.HdTimeSpan = [ name : 'HdTimeSpan', 'name_abbr' : 'HdTimeSpan', type : 'HdTimeSpan', 'type_Object' : 'HdTimeSpan', size : 'SIZE_OF_POINTER' ] } velocity { entry { from = "$srcDir/PrimitiveEntry.vpp" to = "$dstDir/@{name}Entry.java" - contexts = [ types.char, types.byte, types.short, types.int, types.long, types.float, types.double, types.boolean, types.Decimal ] + contexts = [ types.char, types.byte, types.short, types.int, types.long, types.float, types.double, types.boolean, types.Decimal, types.HdDateTime, types.HdTimeSpan] } enumeration { from = "$srcDir/PrimitiveEnumeration.vpp" to = "$dstDir/@{name}Enumeration.java" - contexts = [ types.char, types.byte, types.short, types.int, types.long, types.float, types.double, types.boolean, types.Decimal ] + contexts = [ types.char, types.byte, types.short, types.int, types.long, types.float, types.double, types.boolean, types.Decimal, types.HdDateTime, types.HdTimeSpan] } list { from = "$srcDir/List.vpp" to = "$dstDir/@{name}List.java" - contexts = [ types.char, types.byte, types.short, types.int, types.long, types.float, types.double, types.boolean, types.Object, types.Decimal ] + contexts = [ types.char, types.byte, types.short, types.int, types.long, types.float, types.double, types.boolean, types.Object, types.Decimal, types.HdDateTime, types.HdTimeSpan] } arrayList { from = "$srcDir/ArrayList.vpp" to = "$dstDir/@{name}ArrayList.java" - contexts = [ types.char, types.byte, types.short, types.int, types.long, types.float, types.double, types.boolean, types.Object, types.Decimal ] + contexts = [ types.char, types.byte, types.short, types.int, types.long, types.float, types.double, types.boolean, types.Object, types.Decimal, types.HdDateTime, types.HdTimeSpan] } comparator { from = "$srcDir/PrimitiveComparator.vpp" to = "$dstDir/@{name}Comparator.java" - contexts = [ types.char, types.short, types.int, types.long, types.float, types.double, types.Decimal ] + contexts = [ types.char, types.short, types.int, types.long, types.float, types.double, types.Decimal, types.HdDateTime, types.HdTimeSpan] } hashSet { from = "$srcDir/PrimitiveHashSet.vpp" to = "$dstDir/@{name}HashSet.java" - contexts = [ types.char, types.short, types.int, types.long, types.float, types.double, types.Object, types.Decimal ] + contexts = [ types.char, types.short, types.int, types.long, types.float, types.double, types.Object, types.Decimal, types.HdDateTime, types.HdTimeSpan] } hashMapBase { from = "$srcDir/PrimitiveHashMapBase.vpp" to = "$dstDir/@{name}HashMapBase.java" - contexts = [ types.char, types.short, types.int, types.long, types.float, types.double, types.Object, types.Decimal ] + contexts = [ types.char, types.short, types.int, types.long, types.float, types.double, types.Object, types.Decimal, types.HdDateTime, types.HdTimeSpan] } } diff --git a/collections/src/main/templates/ArrayList.vpp b/collections/src/main/templates/ArrayList.vpp index 1adfbdf8..684bb7c8 100644 --- a/collections/src/main/templates/ArrayList.vpp +++ b/collections/src/main/templates/ArrayList.vpp @@ -8,7 +8,7 @@ import java.util.AbstractList; import java.util.Collection; import java.util.Arrays; import java.lang.reflect.Array; -#if($name == "Object" || $name == "Decimal") +#if($name == "Object" || $name == "Decimal" || $name == 'HdDateTime' || $name == 'HdTimeSpan') import deltix.util.lang.Util; import java.util.Enumeration; import java.util.Comparator; @@ -22,6 +22,10 @@ import deltix.util.collections.ICapacity; #if( $name == "Decimal" ) import deltix.dfp.Decimal64; +#elseif( $name == "HdDateTime" ) +import deltix.hddatetime.HdDateTime; +#elseif( $name == "HdTimeSpan" ) +import deltix.hddatetime.HdTimeSpan; #end #if( $name == "Object" ) @@ -240,7 +244,7 @@ public final class ${name}ArrayList extends AbstractList<${type_Object}> impleme return indexOf (elem) >= 0; } -#if( $name == "Object" || $name == "Decimal") +#if( $name == "Object" || $name == "Decimal" || $name == "HdDateTime" || $name == "HdTimeSpan") /** *

    Returns an array containing all of the elements in this list in the * correct order. The runtime type of the returned array is that of the @@ -263,7 +267,7 @@ public final class ${name}ArrayList extends AbstractList<${type_Object}> impleme @SuppressWarnings("unchecked") public T[] toArray(T[] a) { if (a.length < size) { -#if($name == "Decimal") +#if($name == "Decimal" || $name == "HdDateTime" || $name == "HdTimeSpan") return (T[]) Arrays.copyOf(elementData, size); #else return (T[]) Arrays.copyOf(elementData, size, a.getClass()); @@ -417,7 +421,7 @@ public final class ${name}ArrayList extends AbstractList<${type_Object}> impleme } #end -#if ($name == "Decimal") +#if ($name == "Decimal" || $name == "HdDateTime" || $name == "HdTimeSpan") /** * Returns true if this list contains the specified element. * @@ -446,6 +450,16 @@ public final class ${name}ArrayList extends AbstractList<${type_Object}> impleme for (int i = 0; i < size; i++) if (Util.xequals (elem, elementData[i])) return i; +#elseif ($name == "HdDateTime") + public int indexOf (HdDateTime elem) { + for (int i = 0; i < size; i++) + if (Util.xequals (elem, elementData[i])) + return i; +#elseif ($name == "HdTimeSpan") + public int indexOf (HdTimeSpan elem) { + for (int i = 0; i < size; i++) + if (Util.xequals (elem, elementData[i])) + return i; #else public int indexOf (${type} elem) { for (int i = 0; i < size; i++) @@ -473,6 +487,16 @@ public final class ${name}ArrayList extends AbstractList<${type_Object}> impleme for (int i = size-1; i >= 0; i--) if (Util.xequals (elem, elementData [i])) return i; +#elseif ($name == "HdDateTime") + public int lastIndexOf (HdDateTime elem) { + for (int i = size-1; i >= 0; i--) + if (Util.xequals (elem, elementData [i])) + return i; +#elseif ($name == "HdTimeSpan") + public int lastIndexOf (HdTimeSpan elem) { + for (int i = size-1; i >= 0; i--) + if (Util.xequals (elem, elementData [i])) + return i; #else public int lastIndexOf (${type} elem) { for (int i = size-1; i >= 0; i--) @@ -671,7 +695,7 @@ public final class ${name}ArrayList extends AbstractList<${type_Object}> impleme Iterator iter = c.iterator (); for (int i=0; i impleme return numNew != 0; } - #if($name != "Object" || $name == "Decimal") + #if($name != "Object" || $name == "Decimal" || $name == 'HdDateTime' || $name == 'HdTimeSpan') /** * Appends all of the elements in the specified array to the end of @@ -845,7 +869,11 @@ public final class ${name}ArrayList extends AbstractList<${type_Object}> impleme // Write out all elements in the proper order. for (int i=0; i impleme // Read in all elements in the proper order. for (int i=0; i impleme return (buf.toString ()); } -#if( $name == "Object" || $name == "Decimal" ) +#if( $name == "Object" || $name == "Decimal" || $name == 'HdDateTime' || $name == 'HdTimeSpan') private class ElemEnumeration implements Enumeration<$type> { private int mIndex = 0; diff --git a/collections/src/main/templates/List.vpp b/collections/src/main/templates/List.vpp index d14713bb..aebbbd73 100644 --- a/collections/src/main/templates/List.vpp +++ b/collections/src/main/templates/List.vpp @@ -12,6 +12,10 @@ package deltix.util.collections.generated; #if( $name == "Decimal" ) import deltix.dfp.Decimal64; +#elseif( $name == "HdDateTime" ) +import deltix.hddatetime.HdDateTime; +#elseif( $name == "HdTimeSpan" ) +import deltix.hddatetime.HdTimeSpan; #end /** diff --git a/collections/src/main/templates/PrimitiveComparator.vpp b/collections/src/main/templates/PrimitiveComparator.vpp index e1b2e5ae..41b8b35b 100644 --- a/collections/src/main/templates/PrimitiveComparator.vpp +++ b/collections/src/main/templates/PrimitiveComparator.vpp @@ -5,6 +5,10 @@ import deltix.util.collections.*; #if( $name == "Decimal" ) import deltix.dfp.Decimal64; +#elseif( $name == "HdDateTime" ) +import deltix.hddatetime.HdDateTime; +#elseif( $name == "HdTimeSpan" ) +import deltix.hddatetime.HdTimeSpan; #end /** @@ -30,6 +34,14 @@ public final class ${name}Comparator implements ByteArrayComparator { return (mOrder); else return (-mOrder); +#elseif( $name == "HdDateTime" || $name == "HdTimeSpan") + int c = ${name_abbr}.compare(f1, f2); + if (c == 0) + return (0); + else if (c > 0) + return (mOrder); + else + return (-mOrder); #else if (f1 == f2) return (0); diff --git a/collections/src/main/templates/PrimitiveEntry.vpp b/collections/src/main/templates/PrimitiveEntry.vpp index f44e2631..eae09099 100644 --- a/collections/src/main/templates/PrimitiveEntry.vpp +++ b/collections/src/main/templates/PrimitiveEntry.vpp @@ -4,10 +4,18 @@ import deltix.util.collections.KeyEntry; #if( $name == "Decimal" ) import deltix.dfp.Decimal64; +public interface ${name}Entry extends KeyEntry<${type}> { +#elseif( $name == "HdDateTime" ) +import deltix.hddatetime.HdDateTime; public interface ${name}Entry extends KeyEntry<${type}> { -#else + +#elseif( $name == "HdTimeSpan" ) +import deltix.hddatetime.HdTimeSpan; +public interface ${name}Entry extends KeyEntry<${type}> { + +#else public interface ${name}Entry extends KeyEntry<${name}> { #end diff --git a/collections/src/main/templates/PrimitiveEnumeration.vpp b/collections/src/main/templates/PrimitiveEnumeration.vpp index 83968d7b..a9db6d39 100644 --- a/collections/src/main/templates/PrimitiveEnumeration.vpp +++ b/collections/src/main/templates/PrimitiveEnumeration.vpp @@ -3,6 +3,10 @@ package deltix.util.collections.generated; import deltix.util.collections.ElementsEnumeration; #if( $name == "Decimal" ) import deltix.dfp.Decimal64; +#elseif( $name == "HdDateTime" ) +import deltix.hddatetime.HdDateTime; +#elseif( $name == "HdTimeSpan" ) +import deltix.hddatetime.HdTimeSpan; #end public interface ${name}Enumeration extends ElementsEnumeration<$type_Object> { diff --git a/collections/src/main/templates/PrimitiveHashMapBase.vpp b/collections/src/main/templates/PrimitiveHashMapBase.vpp index f1752d91..4658a2a8 100644 --- a/collections/src/main/templates/PrimitiveHashMapBase.vpp +++ b/collections/src/main/templates/PrimitiveHashMapBase.vpp @@ -12,6 +12,10 @@ import deltix.util.collections.hash.*; import java.util.*; #if( $name == "Decimal" ) import deltix.dfp.Decimal64; +#elseif( $name == "HdDateTime" ) +import deltix.hddatetime.HdDateTime; +#elseif( $name == "HdTimeSpan" ) +import deltix.hddatetime.HdTimeSpan; #end /** * Base class for ${name} to anything hash maps. @@ -194,7 +198,7 @@ protected final class KeyEnumeration implements ${name}Enumeration { return (ret); } -#if($name == "Decimal") +#if($name == "Decimal" || $name == "HdDateTime" || $name == "HdTimeSpan") @Override public ${type} nextElement () { return (next${name_abbr}Element ()); diff --git a/collections/src/main/templates/PrimitiveHashSet.vpp b/collections/src/main/templates/PrimitiveHashSet.vpp index e2b6bd4e..9139dc4d 100644 --- a/collections/src/main/templates/PrimitiveHashSet.vpp +++ b/collections/src/main/templates/PrimitiveHashSet.vpp @@ -13,6 +13,10 @@ import java.io.*; import java.util.*; #if( $name == "Decimal" ) import deltix.dfp.Decimal64; +#elseif( $name == "HdDateTime" ) +import deltix.hddatetime.HdDateTime; +#elseif( $name == "HdTimeSpan" ) +import deltix.hddatetime.HdTimeSpan; #end @SuppressWarnings ("unchecked") @@ -127,7 +131,11 @@ public class ${name}HashSet$!{key_param} extends ${name}HashMapBase$!{key_param} if (isFilled (ii)) { numWritten++; #if( $name == "Decimal") - out.writeLong (keys [ii].toLong()); + out.writeLong (Decimal64.toUnderlying(keys [ii])); +#elseif( $name == "HdDateTime") + out.writeLong (HdDateTime.toUnderlying(keys [ii])); +#elseif( $name == "HdTimeSpan") + out.writeLong (HdTimeSpan.toUnderlying(keys [ii])); #else out.write${name_abbr} (keys [ii]); #end @@ -152,7 +160,11 @@ public class ${name}HashSet$!{key_param} extends ${name}HashMapBase$!{key_param} for (int ii = 0; ii < inCount; ii++) { #if( $name == "Decimal") - ${key_type} key = Decimal64.fromLong(in.readLong ()); + ${key_type} key = Decimal64.fromUnderlying(in.readLong ()); +#elseif( $name == "HdDateTime") + ${key_type} key = HdDateTime.fromUnderlying(in.readLong ()); +#elseif( $name == "HdTimeSpan") + ${key_type} key = HdTimeSpan.fromUnderlying(in.readLong ()); #else ${key_type} key = $!{key_cast}in.read${name_abbr} (); #end diff --git a/collections/src/main/templates/PrimitiveToPrimitiveHashMap.vpp b/collections/src/main/templates/PrimitiveToPrimitiveHashMap.vpp index 292e8d5d..ae6d54b3 100644 --- a/collections/src/main/templates/PrimitiveToPrimitiveHashMap.vpp +++ b/collections/src/main/templates/PrimitiveToPrimitiveHashMap.vpp @@ -20,6 +20,10 @@ import java.io.*; import java.util.*; #if( $name == "Decimal" ) import deltix.dfp.Decimal64; +#elseif( $name == "HdDateTime" ) +import deltix.hddatetime.HdDateTime; +#elseif( $name == "HdTimeSpan" ) +import deltix.hddatetime.HdTimeSpan; #end #if( $second_name == "Object" ) import java.util.function.Consumer; diff --git a/gradle.properties b/gradle.properties index 83955d25..e0c5636e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,5 @@ #Mon Jun 03 11:18:16 MSK 2019 version=5.2.49-SNAPSHOT deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java +dfpVersion=0.10.7 +hdTimeVersion=0.2.4 \ No newline at end of file diff --git a/lang/build.gradle b/lang/build.gradle index dc3585e1..0ca85f82 100644 --- a/lang/build.gradle +++ b/lang/build.gradle @@ -5,7 +5,8 @@ plugins { description = 'QuantServer commons-lang set of utilities' dependencies { - compile group: 'deltix', name: 'deltix-dfp', version: '0.6.7' + compile group: 'deltix', name: 'deltix-dfp', version: dfpVersion + compile group: 'deltix', name: 'hd-date-time', version: hdTimeVersion compile 'deltix:deltix-gflog-api' } diff --git a/lang/src/main/java/deltix/util/memory/DataExchangeUtils.java b/lang/src/main/java/deltix/util/memory/DataExchangeUtils.java index 0996cfdc..754f0e2e 100644 --- a/lang/src/main/java/deltix/util/memory/DataExchangeUtils.java +++ b/lang/src/main/java/deltix/util/memory/DataExchangeUtils.java @@ -2,6 +2,8 @@ import deltix.dfp.Decimal64; +import deltix.hddatetime.HdDateTime; +import deltix.hddatetime.HdTimeSpan; /** * Reads/writes primitive values from/to an array of bytes, @@ -370,6 +372,14 @@ public static void writeDoubleInvertBytes (byte [] bytes, int offset, double } public static Decimal64 readDecimal (byte [] bytes, int offset) { - return Decimal64.fromLong(readLong(bytes, offset)); + return Decimal64.fromUnderlying(readLong(bytes, offset)); + } + + public static HdDateTime readHdDateTime (byte [] bytes, int offset) { + return HdDateTime.fromUnderlying(readLong(bytes, offset)); + } + + public static HdTimeSpan readHdTimeSpan (byte [] bytes, int offset) { + return HdTimeSpan.fromUnderlying(readLong(bytes, offset)); } } From 8e3d768a4ae028f12ce455a5103f06ab89fbde09 Mon Sep 17 00:00:00 2001 From: Robot Date: Tue, 4 Jun 2019 04:23:30 +0300 Subject: [PATCH 2148/2572] [Skip CI] Generate release version --- gradle.properties | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gradle.properties b/gradle.properties index e0c5636e..7264b7cf 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ -#Mon Jun 03 11:18:16 MSK 2019 -version=5.2.49-SNAPSHOT -deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java +#Tue Jun 04 04:23:30 MSK 2019 dfpVersion=0.10.7 -hdTimeVersion=0.2.4 \ No newline at end of file +version=5.2.49 +deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java +hdTimeVersion=0.2.4 From 05a2ae383942a8bd3b07978211570a4e37be3e33 Mon Sep 17 00:00:00 2001 From: Robot Date: Tue, 4 Jun 2019 04:23:37 +0300 Subject: [PATCH 2149/2572] [Skip CI] Generate next development version --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 7264b7cf..6d190c13 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ -#Tue Jun 04 04:23:30 MSK 2019 +#Tue Jun 04 04:23:37 MSK 2019 dfpVersion=0.10.7 -version=5.2.49 +version=5.2.50-SNAPSHOT deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java hdTimeVersion=0.2.4 From 3a20fb826c287f230f58c39b0e89f9eaeb5d6a43 Mon Sep 17 00:00:00 2001 From: Alex Karpovich Date: Tue, 18 Jun 2019 17:23:32 +0300 Subject: [PATCH 2150/2572] [*] download CurrencyCodes.xml from server --- util/build.gradle | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/util/build.gradle b/util/build.gradle index ea287d7a..7a712adf 100644 --- a/util/build.gradle +++ b/util/build.gradle @@ -24,3 +24,10 @@ dependencies { compile('net.java.dev.jna:platform:3.4.0'){ transitive = false } compile('org.apache.bcel:bcel:6.0'){ transitive = false } } + +task downloadCodes(type: Download) { + src 'http://sm.deltixuat.com:5552/api/v1/currencyinfo/xml' + dest new File(buildDir, 'resources/main/deltix/util/currency/CurrencyCodes.xml') +} + +build.dependsOn(downloadCodes) \ No newline at end of file From c3b08a669b30fed5f5d8147a82de8108c6a75158 Mon Sep 17 00:00:00 2001 From: Alex Karpovich Date: Tue, 18 Jun 2019 17:28:36 +0300 Subject: [PATCH 2151/2572] [*] plug-in --- build.gradle | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index 2572ad94..f232de65 100644 --- a/build.gradle +++ b/build.gradle @@ -3,6 +3,7 @@ plugins { // Helps to avoid re-declaring dependency version in each subproject. // See https://github.com/spring-gradle-plugins/dependency-management-plugin id "io.spring.dependency-management" version "1.0.5.RELEASE" + id "de.undercouch.download" version "3.4.3" } // To update Gradle wrapper use: @@ -230,11 +231,8 @@ configure(leafProjects) { def testTasks = ext.leafProjects*.test - - task generateTestReport(type: TestReport) { group 'verification' reportOn testTasks destinationDir = file("$rootDir/build/reports/junit/html/all_reports_merged") // TODO: Pick better name for merged report } -task allJunitTests(dependsOn: generateTestReport) From 9077b3edd0fdd2e37117cf41bd9a8e690e1c8083 Mon Sep 17 00:00:00 2001 From: Robot Date: Tue, 18 Jun 2019 17:29:34 +0300 Subject: [PATCH 2152/2572] [Skip CI] Generate release version --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 6d190c13..a1c25acd 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ -#Tue Jun 04 04:23:37 MSK 2019 +#Tue Jun 18 17:29:33 MSK 2019 dfpVersion=0.10.7 -version=5.2.50-SNAPSHOT +version=5.2.50 deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java hdTimeVersion=0.2.4 From aec6799b633a39b95d0b49e1be7bde2b09041011 Mon Sep 17 00:00:00 2001 From: Robot Date: Tue, 18 Jun 2019 17:29:40 +0300 Subject: [PATCH 2153/2572] [Skip CI] Generate next development version --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index a1c25acd..58a20c04 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ -#Tue Jun 18 17:29:33 MSK 2019 +#Tue Jun 18 17:29:40 MSK 2019 dfpVersion=0.10.7 -version=5.2.50 +version=5.2.51-SNAPSHOT deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java hdTimeVersion=0.2.4 From 8a2c746f3f905654eb115009bfede5d38b94221c Mon Sep 17 00:00:00 2001 From: YarmalkevichD Date: Thu, 20 Jun 2019 17:42:15 +0300 Subject: [PATCH 2154/2572] [+] added LegacyNumericCode to CurrencyCodeList --- .../util/currency/CurrencyCodeList.java | 354 +++++++++--------- 1 file changed, 184 insertions(+), 170 deletions(-) diff --git a/util/src/main/java/deltix/util/currency/CurrencyCodeList.java b/util/src/main/java/deltix/util/currency/CurrencyCodeList.java index c0d20e76..e0fb8248 100644 --- a/util/src/main/java/deltix/util/currency/CurrencyCodeList.java +++ b/util/src/main/java/deltix/util/currency/CurrencyCodeList.java @@ -1,170 +1,184 @@ -package deltix.util.currency; - -import deltix.util.io.BasicIOUtil; -import deltix.util.lang.Depends; -import deltix.util.lang.StringUtils; -import deltix.util.lang.Util; -import deltix.util.text.CharSequenceParser; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.xml.sax.SAXException; - -import javax.annotation.concurrent.ThreadSafe; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; - -@Depends("deltix/util/currency/CurrencyCodes.xml") -@ThreadSafe -public class CurrencyCodeList { - private static final int amount = 10000; - private static final CurrencyInfo[] numericIndex = new CurrencyInfo[amount]; - private static final ThreeLetterToObjectMapQuick symbolicIndex = new ThreeLetterToObjectMapQuick<>(amount); - - static { - read (); - } - - private static void read () { - InputStream is = null; - try { - String alternativeLocation = System.getProperty("deltix.qsrv.currency.codes"); - if (StringUtils.isEmpty(alternativeLocation)) - is = BasicIOUtil.openResourceAsStream ("deltix/util/currency/CurrencyCodes.xml"); - else - is = new FileInputStream(alternativeLocation); - read(is); - } catch (final Throwable x) { - Util.logException("Can not create currency code list", x); - } finally { - Util.close (is); - } - } - - private static void read(InputStream is) throws ParserConfigurationException, SAXException, IOException { - final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance (); - final DocumentBuilder db = dbf.newDocumentBuilder (); - final Document doc = db.parse (is); - doc.getDocumentElement ().normalize (); - - final NodeList nodeLst = doc.getElementsByTagName ("Currency"); - - for (int s = 0; s < nodeLst.getLength (); s++) { - - final Node node = nodeLst.item (s); - - if (node.getNodeType () == Node.ELEMENT_NODE) { - final Element element = (Element) node; - - final CurrencyInfo info = new CurrencyInfo(getText (element, - "AlphabeticCode"), - CharSequenceParser.parseShort (getText (element, - "NumericCode")), - getText (element, - "Name"), - getText (element, - "Country")); - numericIndex[info.numericCode] = info; - symbolicIndex.put (info.symbolicCode, info); - } - - } - } - - private static String getText (final Element element, - final String tag) { - NodeList fstNm; - try { - final NodeList nodes = element.getElementsByTagName (tag); - if (nodes.getLength() == 0) - return null; - - final Element fstNmElmnt = (Element) nodes.item (0); - fstNm = fstNmElmnt.getChildNodes (); - - return (fstNm.item(0)).getNodeValue(); - } catch (final Throwable x) { - return null; - } - - } - - public static CurrencyInfo[] getCodes () { - CurrencyInfo[] result = new CurrencyInfo[symbolicIndex.size()]; - if (symbolicIndex.size() > 0) - symbolicIndex.valuesToArray(result); - return result; - } - - public static String numericToSymbolic (final int code) { - final CurrencyInfo info = getInfoByNumeric (code); - - return (info == null ? null : info.symbolicCode); - } - - public static int symbolicToNumeric (String code, final int notFoundValue) { - final CurrencyInfo info = getInfoBySymbolic (code); - return (info == null ? notFoundValue : info.numericCode); - } - - public static short symbolicToNumeric (CharSequence code, final short notFoundValue) { - final CurrencyInfo info = getInfoBySymbolic (code); - return (info == null ? notFoundValue : info.numericCode); - } - - public static short symbolicToNumeric (CharSequence code, int start, int end, final short notFoundValue) { - final CurrencyInfo info = getInfoBySymbolic (code, start, end); - return (info == null ? notFoundValue : info.numericCode); - } - - public static CurrencyInfo getInfoByNumeric (final int code) { - return (code >= 0 && code < amount ? numericIndex[code] : null); - } - - public static CurrencyInfo getInfoBySymbolic (CharSequence code) { - return getInfoBySymbolic(code, 0, code.length()); - } - - public static CurrencyInfo getInfoBySymbolic (CharSequence code, int start, int end) { - return symbolicIndex.get(code, start, end, null); - } - - public static CurrencyInfo getInfoBySymbolic (String code) { - return getInfoBySymbolic((CharSequence) code); - } - - public static class CurrencyInfo implements Comparable { - public final String symbolicCode; - public final short numericCode; - public final String description; - public final String location; - - private CurrencyInfo (final String code, - final short numeric, - final String currency, - final String location) { - super (); - this.symbolicCode = code; - this.numericCode = numeric; - this.description = currency; - this.location = location; - } - - @Override - public String toString () { - return numericCode + " (" + symbolicCode + ")"; - } - - @Override - public int compareTo (final CurrencyInfo o) { - return Util.compare (symbolicCode, - o == null ? null : o.symbolicCode, - true); - } - } -} +package deltix.util.currency; + +import deltix.util.io.BasicIOUtil; +import deltix.util.lang.Depends; +import deltix.util.lang.StringUtils; +import deltix.util.lang.Util; +import deltix.util.text.CharSequenceParser; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +import javax.annotation.concurrent.ThreadSafe; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; + +@Depends("deltix/util/currency/CurrencyCodes.xml") +@ThreadSafe +public class CurrencyCodeList { + private static final int amount = 10000; + private static final CurrencyInfo[] numericIndex = new CurrencyInfo[amount]; + private static final ThreeLetterToObjectMapQuick symbolicIndex = new ThreeLetterToObjectMapQuick<>(amount); + + static { + read (); + } + + private static void read () { + InputStream is = null; + try { + String alternativeLocation = System.getProperty("deltix.qsrv.currency.codes"); + if (StringUtils.isEmpty(alternativeLocation)) + is = BasicIOUtil.openResourceAsStream ("deltix/util/currency/CurrencyCodes.xml"); + else + is = new FileInputStream(alternativeLocation); + read(is); + } catch (final Throwable x) { + Util.logException("Can not create currency code list", x); + } finally { + Util.close (is); + } + } + + private static void read(InputStream is) throws ParserConfigurationException, SAXException, IOException { + final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance (); + final DocumentBuilder db = dbf.newDocumentBuilder (); + final Document doc = db.parse (is); + doc.getDocumentElement ().normalize (); + + final NodeList nodeLst = doc.getElementsByTagName ("Currency"); + + for (int s = 0; s < nodeLst.getLength (); s++) { + + final Node node = nodeLst.item (s); + + if (node.getNodeType () == Node.ELEMENT_NODE) { + final Element element = (Element) node; + + String legacyNumericCode = getText (element, "LegacyNumericCode"); + final CurrencyInfo info = new CurrencyInfo(getText (element, + "AlphabeticCode"), + CharSequenceParser.parseShort (getText (element, + "NumericCode")), + getText (element, + "Name"), + getText (element, + "Country"), + legacyNumericCode == null ? Short.MIN_VALUE: + CharSequenceParser.parseShort (legacyNumericCode)); + numericIndex[info.numericCode] = info; + if (info.legacyNumericCode != Short.MIN_VALUE) { + if (numericIndex[info.legacyNumericCode] != null) { + System.out.printf("ERROR while loading CurrencyCodes.xml. Codes are equal in currencies %s and %s\n", + numericIndex[info.legacyNumericCode], info); + System.out.printf("Writing currency %s\n", info); + } + numericIndex[info.legacyNumericCode] = info; + } + symbolicIndex.put (info.symbolicCode, info); + } + + } + } + + private static String getText (final Element element, + final String tag) { + NodeList fstNm; + try { + final NodeList nodes = element.getElementsByTagName (tag); + if (nodes.getLength() == 0) + return null; + + final Element fstNmElmnt = (Element) nodes.item (0); + fstNm = fstNmElmnt.getChildNodes (); + + return (fstNm.item(0)).getNodeValue(); + } catch (final Throwable x) { + return null; + } + + } + + public static CurrencyInfo[] getCodes () { + CurrencyInfo[] result = new CurrencyInfo[symbolicIndex.size()]; + if (symbolicIndex.size() > 0) + symbolicIndex.valuesToArray(result); + return result; + } + + public static String numericToSymbolic (final int code) { + final CurrencyInfo info = getInfoByNumeric (code); + + return (info == null ? null : info.symbolicCode); + } + + public static int symbolicToNumeric (String code, final int notFoundValue) { + final CurrencyInfo info = getInfoBySymbolic (code); + return (info == null ? notFoundValue : info.numericCode); + } + + public static short symbolicToNumeric (CharSequence code, final short notFoundValue) { + final CurrencyInfo info = getInfoBySymbolic (code); + return (info == null ? notFoundValue : info.numericCode); + } + + public static short symbolicToNumeric (CharSequence code, int start, int end, final short notFoundValue) { + final CurrencyInfo info = getInfoBySymbolic (code, start, end); + return (info == null ? notFoundValue : info.numericCode); + } + + public static CurrencyInfo getInfoByNumeric (final int code) { + return (code >= 0 && code < amount ? numericIndex[code] : null); + } + + public static CurrencyInfo getInfoBySymbolic (CharSequence code) { + return getInfoBySymbolic(code, 0, code.length()); + } + + public static CurrencyInfo getInfoBySymbolic (CharSequence code, int start, int end) { + return symbolicIndex.get(code, start, end, null); + } + + public static CurrencyInfo getInfoBySymbolic (String code) { + return getInfoBySymbolic((CharSequence) code); + } + + public static class CurrencyInfo implements Comparable { + public final String symbolicCode; + public final short numericCode; + public final String description; + public final String location; + public final short legacyNumericCode; + + private CurrencyInfo (final String code, + final short numeric, + final String currency, + final String location, + final short legacyNumericCode) { + super (); + this.symbolicCode = code; + this.numericCode = numeric; + this.description = currency; + this.location = location; + this.legacyNumericCode = legacyNumericCode; + } + + @Override + public String toString () { + return numericCode + " (" + symbolicCode + ")"; + } + + @Override + public int compareTo (final CurrencyInfo o) { + return Util.compare (symbolicCode, + o == null ? null : o.symbolicCode, + true); + } + } +} From 339d80e195feaa1df35389158a3e446604f1765d Mon Sep 17 00:00:00 2001 From: Robot Date: Thu, 20 Jun 2019 14:43:00 +0000 Subject: [PATCH 2155/2572] [Skip CI] Generate release version --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 58a20c04..c33a3a55 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ -#Tue Jun 18 17:29:40 MSK 2019 +#Thu Jun 20 14:43:00 UTC 2019 dfpVersion=0.10.7 -version=5.2.51-SNAPSHOT +version=5.2.51 deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java hdTimeVersion=0.2.4 From 6f4a9882b027fda07223b92e020c27c16347e29c Mon Sep 17 00:00:00 2001 From: Robot Date: Thu, 20 Jun 2019 14:43:08 +0000 Subject: [PATCH 2156/2572] [Skip CI] Generate next development version --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index c33a3a55..c01c14de 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ -#Thu Jun 20 14:43:00 UTC 2019 +#Thu Jun 20 14:43:08 UTC 2019 dfpVersion=0.10.7 -version=5.2.51 +version=5.2.52-SNAPSHOT deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java hdTimeVersion=0.2.4 From ecbf5132aad0ec1375e485a197bb48e3fa1cfdc3 Mon Sep 17 00:00:00 2001 From: Alex Karpovich Date: Thu, 20 Jun 2019 18:07:30 +0300 Subject: [PATCH 2157/2572] [*] new currency codes --- util/build.gradle | 2 +- .../deltix/util/currency/CurrencyCodes.xml | 369 +++++++++++++++++- 2 files changed, 369 insertions(+), 2 deletions(-) diff --git a/util/build.gradle b/util/build.gradle index 7a712adf..0f60ee32 100644 --- a/util/build.gradle +++ b/util/build.gradle @@ -27,7 +27,7 @@ dependencies { task downloadCodes(type: Download) { src 'http://sm.deltixuat.com:5552/api/v1/currencyinfo/xml' - dest new File(buildDir, 'resources/main/deltix/util/currency/CurrencyCodes.xml') + dest new File(projectDir, 'src/main/resources/deltix/util/currency/CurrencyCodes.xml') } build.dependsOn(downloadCodes) \ No newline at end of file diff --git a/util/src/main/resources/deltix/util/currency/CurrencyCodes.xml b/util/src/main/resources/deltix/util/currency/CurrencyCodes.xml index e2757de2..8a8fccd9 100644 --- a/util/src/main/resources/deltix/util/currency/CurrencyCodes.xml +++ b/util/src/main/resources/deltix/util/currency/CurrencyCodes.xml @@ -6,222 +6,259 @@ Ripple XRP XRP + 301 1302 Metaverse ETP ETP ETP + 302 1303 Bitcoin Cash BCH BCH + 303 1304 OmiseGO OMG OMG + 304 1305 Neo NEO NEO + 305 1306 Iota MIOTA IOT + 306 1307 DigitalCash DASH DSH + 307 1308 Zcash ZEC ZEC + 308 1309 Monero XMR XMR + 309 1310 Ethereum Classic ETC ETC + 310 1311 EOS EOS EOS + 311 1312 Aventus AVT AVT + 312 1313 Qtum QTUM QTM + 313 1314 Santiment SAN SAN + 314 1315 Eidoo EDO EDO + 315 1316 Bitcoin Gold BTG BTG + 316 1317 Streamr DATA DAT + 317 1318 QASH QASH QSH + 318 1319 YOYOW YOYOW YYW + 319 1321 Tether USDT THR + 321 1322 Cardano ADA ADA + 322 1323 Binance Coin BNB BNB + 323 1325 Bread BRD BRD + 325 1326 Gifto GTO GTO + 326 1327 Iconomi ICN ICN + 327 1329 Icon ICX ICX + 329 1330 Lisk LSK LSK + 330 1331 Nano NANO NAN + 331 1333 Salt SALT SLT + 333 1334 Stratis STRAT STR + 334 1335 Tron TRX TRX + 335 1336 Wings WINGS WNG + 336 1337 Stellar Lumens XLM XLM + 337 1338 Verge XVG XVG + 338 1641 Litecoin LTC LTC + 641 1741 Bitcoin BTC XBT + 741 1841 Ethereum ETH ETH + 841 8 @@ -2607,7 +2644,7 @@ 1082 - AGI + SingularityNET AGI AGI @@ -5611,5 +5648,335 @@ TT TT + + 1945 + OKB + OKB + OKB + + + 1954 + YOU COIN + YOU + YOU + + + 1965 + Asch + XAS + XAS + + + 1966 + Egretia + EGT + EGT + + + 1967 + High Performance Blockchain + HPB + HPB + + + 1982 + Measurable Data Token + MDT + MDT + + + 1983 + ugChain + UGC + UGC + + + 1987 + Delphy + DPY + DPY + + + 1988 + SelfSell + SSC + SSC + + + 1989 + Primas + PST + PST + + + 1991 + Zipper + ZIP + ZIP + + + 1992 + CIChain + CIC + CIC + + + 1993 + Chronologic + DAY + DAY + + + 1994 + Daneel + DAN + DAN + + + 1995 + DomRaider Token + DRT + DRT + + + 1996 + Indorse Token + IND + IND + + + 2074 + Helbiz Token + HBZ + HBZ + + + 2075 + Morpheus Network + MORPH + MORPH + + + 2076 + Synthetix + SNX + SNX + + + 2077 + Synthetix sUSD + SUSD + SUSD + + + 2078 + LEO Token + LEO + LEO + + + 2079 + Vodi X + VDX + VDX + + + 2080 + Reserve Rights Token + RSR + RSR + + + 1100 + Red Pulse Phoenix Binance + PHB + PHB + + + 1101 + Theta Fuel + TFUEL + TFUEL + + + 1102 + ZBToken + ZB + ZB + + + 1103 + Upfiring + UFR + UFR + + + 1129 + Cai Token + CAI + CAI + + + 1105 + WinToken + WINT + WINT + + + 1106 + Origin Sport + ORS + ORS + + + 1107 + HYCON + HYC + HYC + + + 1130 + Airbloc + ABL + ABL + + + 1109 + Blockcloud + BLOC + BLOC + + + 1110 + ACE (TokenStars) + ACE + ACE + + + 1111 + Molecular Future + MOF + MOF + + + 1112 + TokenClub + TCT + TCT + + + 1113 + StarChain + STC + STC + + + 1114 + LightChain + LIGHT + LIGHT + + + 1115 + OFCOIN + OF + OF + + + 1131 + Hi Mutual Society + HMC + HMC + + + 1117 + Beauty Chain + BEC + BEC + + + 1118 + Merculet + MVP + MVP + + + 1119 + SDChain + SDA + SDA + + + 1120 + ProChain + PRA + PRA + + + 1121 + OneRoot Network + RNT + RNT + + + 1122 + RealChain + RCT + RCT + + + 1123 + RefToken + REF + REF + + + 1133 + Ubique Chain Of Things + UCT + UCT + + + 1125 + United Bitcoin + UBTC + UBTC + + + 1126 + Show + SHOW + SHOW + + + 1127 + Olympus Labs + MOT + MOT + + + 1128 + IPChain + IPC + IPC + + + 1134 + Origo + OGO + OGO + + + 1135 + Harmony + ONE + ONE + + + 1137 + USDK + USDK + USDK + \ No newline at end of file From ea108bd824865e485f6ffd922e92c8e59ffb0dd3 Mon Sep 17 00:00:00 2001 From: Robot Date: Thu, 20 Jun 2019 15:08:12 +0000 Subject: [PATCH 2158/2572] [Skip CI] Generate release version --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index c01c14de..acca7b01 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ -#Thu Jun 20 14:43:08 UTC 2019 +#Thu Jun 20 15:08:12 UTC 2019 dfpVersion=0.10.7 -version=5.2.52-SNAPSHOT +version=5.2.52 deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java hdTimeVersion=0.2.4 From 2a5bd789a6e8fde0170284b8ec8389e03ff0976e Mon Sep 17 00:00:00 2001 From: Robot Date: Thu, 20 Jun 2019 15:08:20 +0000 Subject: [PATCH 2159/2572] [Skip CI] Generate next development version --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index acca7b01..49987d93 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ -#Thu Jun 20 15:08:12 UTC 2019 +#Thu Jun 20 15:08:20 UTC 2019 dfpVersion=0.10.7 -version=5.2.52 +version=5.2.53-SNAPSHOT deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java hdTimeVersion=0.2.4 From b0c357eb71dad2d7a5b10c41923a27e8951bc039 Mon Sep 17 00:00:00 2001 From: Alex Karpovich Date: Mon, 8 Jul 2019 20:34:18 +0300 Subject: [PATCH 2160/2572] [-] fix compiled class loader for plugins --- .../util/lang/ClassLoaderJavaFileManager.java | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/util/src/main/java/deltix/util/lang/ClassLoaderJavaFileManager.java b/util/src/main/java/deltix/util/lang/ClassLoaderJavaFileManager.java index 907db162..1eaa1599 100644 --- a/util/src/main/java/deltix/util/lang/ClassLoaderJavaFileManager.java +++ b/util/src/main/java/deltix/util/lang/ClassLoaderJavaFileManager.java @@ -27,23 +27,27 @@ public Iterable list ( ) throws IOException { + ArrayList ret = new ArrayList (); + // first of all try listClasses Collection > clist = listClasses.listClassesForPackage (packageName); if (clist == null || clist.isEmpty()) { // try one-level recursion here final ClassLoader parent = ((ClassLoader) listClasses).getParent(); - if (parent != null && parent instanceof ClassDirectory) + if (parent instanceof ClassDirectory) { clist = ((ClassDirectory) parent).listClassesForPackage(packageName); + } + } - if (clist == null || clist.isEmpty()) - return super.list(location, packageName, kinds, recurse); + if (clist != null) { + for (Class cls : clist) + ret.add(new ClassBasedJavaFileObject(cls)); } - ArrayList ret = new ArrayList (); - - for (Class cls : clist) - ret.add (new ClassBasedJavaFileObject (cls)); + Iterable list = super.list(location, packageName, kinds, recurse); + for (JavaFileObject javaFileObject : list) + ret.add (javaFileObject); return (ret); } From e19c5362d1bc126ff7874d271ce0b50cd33110f2 Mon Sep 17 00:00:00 2001 From: Robot Date: Mon, 8 Jul 2019 20:35:03 +0300 Subject: [PATCH 2161/2572] [Skip CI] Generate release version --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 49987d93..df78f819 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ -#Thu Jun 20 15:08:20 UTC 2019 +#Mon Jul 08 20:35:03 MSK 2019 dfpVersion=0.10.7 -version=5.2.53-SNAPSHOT +version=5.2.53 deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java hdTimeVersion=0.2.4 From 8a6e846fad6cdc00e2a05273b6ccd08bd65c62ba Mon Sep 17 00:00:00 2001 From: Robot Date: Mon, 8 Jul 2019 20:35:10 +0300 Subject: [PATCH 2162/2572] [Skip CI] Generate next development version --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index df78f819..b1d62794 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ -#Mon Jul 08 20:35:03 MSK 2019 +#Mon Jul 08 20:35:10 MSK 2019 dfpVersion=0.10.7 -version=5.2.53 +version=5.2.54-SNAPSHOT deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java hdTimeVersion=0.2.4 From 884ed90100ee313c76583b2a5904ccf85dcc8112 Mon Sep 17 00:00:00 2001 From: Alex Karpovich Date: Fri, 2 Aug 2019 11:11:46 +0300 Subject: [PATCH 2163/2572] [*] move SemanticVersion --- .../java/deltix/util/io/SemanticVersion.java | 461 ++++++++++++++++++ .../deltix/util/io/Test_SemanticVersion.java | 47 ++ 2 files changed, 508 insertions(+) create mode 100644 util/src/main/java/deltix/util/io/SemanticVersion.java create mode 100644 util/src/test/java/deltix/util/io/Test_SemanticVersion.java diff --git a/util/src/main/java/deltix/util/io/SemanticVersion.java b/util/src/main/java/deltix/util/io/SemanticVersion.java new file mode 100644 index 00000000..37a92999 --- /dev/null +++ b/util/src/main/java/deltix/util/io/SemanticVersion.java @@ -0,0 +1,461 @@ +// Code source of this file: +// http://grepcode.com/file/repo1.maven.org/maven2/ +// org.apache.maven/maven-artifact/3.1.1/ +// org/apache/maven/artifact/versioning/ComparableVersion.java/ +// +// Modifications made on top of the source: +// 1. Changed +// package org.apache.maven.artifact.versioning; +// to +// package org.apache.hadoop.util; +// to package deltix.tools +// 2. Removed author tags to clear hadoop author tag warning +// author Kenney Westerhof +// author Herve Boutemy +// 3. Added ability to match artifact name and version +// 4. BigDecimal removed +// +package deltix.util.io; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.util.*; + +/** + * Generic implementation of version comparison. + *

    Features:

    + *
      + *
    • mixing of '-' (dash) and '.' (dot) separators,
    • + *
    • transition between characters and digits also constitutes a separator: + * 1.0alpha1 => [1, 0, alpha, 1]
    • + *
    • unlimited number of version components,
    • + *
    • version components in the text can be digits or strings,
    • + *
    • strings are checked for well-known qualifiers and the qualifier ordering is used for version ordering. + * Well-known qualifiers (case insensitive) are:
        + *
      • alpha or a
      • + *
      • beta or b
      • + *
      • milestone or m
      • + *
      • rc or cr
      • + *
      • snapshot
      • + *
      • (the empty string) or ga or final
      • + *
      • sp
      • + *
      + * Unknown qualifiers are considered after known qualifiers, with lexical order (always case insensitive), + *
    • + *
    • a dash usually precedes a qualifier, and is always less important than something preceded with a dot.
    • + *
    + * + * @see "Versioning" on Maven Wiki + * @see Semantic Versioning + * + */ +public class SemanticVersion implements Comparable { + private final String value; + private final String description; + private String id; + + private String name; // name without version component + + private String canonical; + + private ListItem items; + + private interface Item { + int INTEGER_ITEM = 0; + int STRING_ITEM = 1; + int LIST_ITEM = 2; + + int compareTo(Item item); + + int getType(); + + boolean isNull(); + } + + /** + * Represents a numeric item in the version item list. + */ + private static class IntegerItem implements Item { + static final IntegerItem ZERO = new IntegerItem(); + + private static final int NULL_VALUE = 0; + private final long value; + + private IntegerItem() { + this.value = NULL_VALUE; + } + + IntegerItem(String str) { + this.value = Long.parseLong(str); + } + + public int getType() { + return INTEGER_ITEM; + } + + public boolean isNull() { + return NULL_VALUE == value; + } + + public int compareTo(Item item) { + if (item == null) + return NULL_VALUE == value ? 0 : 1; // 1.0 == 1, 1.1 > 1 + + switch (item.getType()) { + case INTEGER_ITEM: + return Long.compare(value, ((IntegerItem) item).value); + + case STRING_ITEM: + return 1; // 1.1 > 1-sp + + case LIST_ITEM: + return 1; // 1.1 > 1-1 + + default: + throw new RuntimeException("invalid item: " + item.getClass()); + } + } + + public String toString() { + return String.valueOf(value); + } + } + + /** + * Represents a string in the version item list, usually a qualifier. + */ + private static class StringItem implements Item { + + private static final String[] QUALIFIERS = {"alpha", "beta", "milestone", "rc", "snapshot", "", "sp"}; + private static final List _QUALIFIERS = Arrays.asList(QUALIFIERS); + private static final Properties ALIASES = new Properties(); + + static { + ALIASES.put("ga", ""); + ALIASES.put("final", ""); + ALIASES.put("cr", "rc"); + } + + /** + * A comparable value for the empty-string qualifier. This one is used to determine if a given qualifier makes + * the version older than one without a qualifier, or more recent. + */ + private static final String RELEASE_VERSION_INDEX = String.valueOf(_QUALIFIERS.indexOf("")); + + private String value; + + StringItem(String value, boolean followedByDigit) { + if (followedByDigit && value.length() == 1) { + // a1 = alpha-1, b1 = beta-1, m1 = milestone-1 + switch (value.charAt(0)) { + case 'a': + value = "alpha"; + break; + case 'b': + value = "beta"; + break; + case 'm': + value = "milestone"; + break; + } + } + this.value = ALIASES.getProperty(value, value); + } + + public int getType() { + return STRING_ITEM; + } + + public boolean isNull() { + return (comparableQualifier(value).compareTo(RELEASE_VERSION_INDEX) == 0); + } + + /** + * Returns a comparable value for a qualifier. + *

    + * This method takes into account the ordering of known qualifiers then unknown qualifiers with lexical ordering. + *

    + * just returning an Integer with the index here is faster, but requires a lot of if/then/else to check for -1 + * or QUALIFIERS.size and then resort to lexical ordering. Most comparisons are decided by the first character, + * so this is still fast. If more characters are needed then it requires a lexical sort anyway. + * + * @param qualifier qualifier + * @return an equivalent value that can be used with lexical comparison + */ + static String comparableQualifier(String qualifier) { + int i = _QUALIFIERS.indexOf(qualifier); + + return i == -1 ? (_QUALIFIERS.size() + "-" + qualifier) : String.valueOf(i); + } + + public int compareTo(Item item) { + if (item == null) { + // 1-rc < 1, 1-ga > 1 + return comparableQualifier(value).compareTo(RELEASE_VERSION_INDEX); + } + switch (item.getType()) { + case INTEGER_ITEM: + return -1; // 1.any < 1.1 ? + + case STRING_ITEM: + return comparableQualifier(value).compareTo(comparableQualifier(((StringItem) item).value)); + + case LIST_ITEM: + return -1; // 1.any < 1-1 + + default: + throw new RuntimeException("invalid item: " + item.getClass()); + } + } + + public String toString() { + return value; + } + } + + /** + * Represents a version list item. This class is used both for the global item list and for sub-lists (which start + * with '-(number)' in the version specification). + */ + private static class ListItem extends ArrayList implements Item { + + @Override + public int getType() { + return LIST_ITEM; + } + + @Override + public boolean isNull() { + return (size() == 0); + } + + void normalize() { + for (ListIterator iterator = listIterator(size()); iterator.hasPrevious(); ) { + Item item = iterator.previous(); + if (item.isNull()) { + iterator.remove(); // remove null trailing items: 0, "", empty list + } else { + break; + } + } + } + + @Override + public int compareTo(Item item) { + if (item == null) { + if (size() == 0) { + return 0; // 1-0 = 1- (normalize) = 1 + } + Item first = get(0); + return first.compareTo(null); + } + switch (item.getType()) { + case INTEGER_ITEM: + return -1; // 1-1 < 1.0.x + + case STRING_ITEM: + return 1; // 1-1 > 1-sp + + case LIST_ITEM: + Iterator left = iterator(); + Iterator right = ((ListItem) item).iterator(); + + while (left.hasNext() || right.hasNext()) { + Item l = left.hasNext() ? left.next() : null; + Item r = right.hasNext() ? right.next() : null; + + // if this is shorter, then invert the compare and mul with -1 + int result = l == null ? -1 * r.compareTo(l) : l.compareTo(r); + + if (result != 0) { + return result; + } + } + + return 0; + + default: + throw new RuntimeException("invalid item: " + item.getClass()); + } + } + + public String toString() { + StringBuilder buffer = new StringBuilder("("); + for (Iterator iter = iterator(); iter.hasNext(); ) { + buffer.append(iter.next()); + if (iter.hasNext()) { + buffer.append(','); + } + } + buffer.append(')'); + return buffer.toString(); + } + } + + public SemanticVersion(String version) { + this(version, null); + } + + public SemanticVersion(String version, String description) { + this.value = version; + this.description = description; + parse(version); + } + + private void parse(String version) { + items = new ListItem(); + version = version.toLowerCase(Locale.ENGLISH); + + StringBuilder idBuilder = new StringBuilder(); + + String[] parts = version.split("[\\-+ ]"); + + for (int i = 0; i < parts.length; i++) { + String part = parts[i]; + + if (part.length() > 0) { + if (Character.isDigit(part.charAt(0))) { + parseInternal(part); + } else + items.add(new StringItem(part, false)); + + if (part.contains(".") && Character.isDigit(part.charAt(0))) { + if (id == null) + id = idBuilder.toString(); + + if (name == null) { + if (i > 0) { + String previous = parts[i - 1]; + name = version.substring(0, version.indexOf(previous) + previous.length()); + } else { + name = ""; + } + } + } else { + if (idBuilder.length() > 0) + idBuilder.append(";"); + idBuilder.append(part); + } + } + } + + if (id == null) + id = idBuilder.toString(); + + if (name == null) + name = version; + } + + private void parseInternal(String version) { + + ListItem list = items; + Stack stack = new Stack<>(); + stack.push(list); + + boolean isDigit = false; + int startIndex = 0; + + for (int i = 0; i < version.length(); i++) { + char c = version.charAt(i); + + if (c == '.') { + if (i == startIndex) + list.add(IntegerItem.ZERO); + else + list.add(parseItem(isDigit, version.substring(startIndex, i))); + + startIndex = i + 1; + } + else if (Character.isDigit(c)) { + // digits can start after separators only + + if (!isDigit && i > startIndex) { + list.add(new StringItem(version.substring(startIndex, i), true)); + startIndex = i; + } + isDigit = true; + } else { + if (isDigit && i > startIndex) { + list.add(parseItem(true, version.substring(startIndex, i))); + startIndex = i; + } + + isDigit = false; + } + } + + if (version.length() > startIndex) + list.add(parseItem(isDigit, version.substring(startIndex))); + + while (!stack.isEmpty()) { + list = (ListItem) stack.pop(); + list.normalize(); + } + + canonical = items.toString(); + } + + private static Item parseItem(boolean isDigit, String buf) { + return isDigit ? new IntegerItem(buf) : new StringItem(buf, false); + } + + public int compareTo(SemanticVersion v) { + if (v != null) + return items.compareTo(v.items); + + return -1; + } + + /** + * Returns original version string + */ + public String getVersion() { + return value; + } + + /** + * Returns semicolon separated parts of the name component + * for the input commons-lang3-3.4 returns commons;lang3 + */ + public String getId() { + return id; + } + + public String getName() { + return name; + } + + @Override + public String toString() { + return Arrays.toString(items.toArray(new Object[items.size()])); + } + + public String getDescription() { + return description; + } + + public boolean equals(Object o) { + return (o instanceof SemanticVersion) && canonical.equals(((SemanticVersion) o).canonical); + } + + public int hashCode() { + return canonical.hashCode(); + } +} diff --git a/util/src/test/java/deltix/util/io/Test_SemanticVersion.java b/util/src/test/java/deltix/util/io/Test_SemanticVersion.java new file mode 100644 index 00000000..115a7403 --- /dev/null +++ b/util/src/test/java/deltix/util/io/Test_SemanticVersion.java @@ -0,0 +1,47 @@ +package deltix.util.io; + +import org.junit.Assert; +import org.junit.Test; + +/** + * Created by Alex Karpovich on 9/21/2018. + */ +public class Test_SemanticVersion { + + @Test + public void test() { + SemanticVersion v = new SemanticVersion("tools", ""); + Assert.assertEquals("tools", v.getId()); + Assert.assertEquals("[tools]", v.toString()); + Assert.assertEquals("tools", v.getName()); + + v = new SemanticVersion("taglibs-standard-impl-1.0.5", ""); + Assert.assertEquals("taglibs;standard;impl", v.getId()); + Assert.assertEquals("taglibs-standard-impl", v.getName()); + + v = new SemanticVersion("taglibs1 standard impl 1.2.5", ""); + Assert.assertEquals("taglibs1;standard;impl", v.getId()); + Assert.assertEquals("taglibs1 standard impl", v.getName()); + + v = new SemanticVersion("taglibs-standard3-impl-1.2.5-SNApSHOT", ""); + Assert.assertEquals("taglibs;standard3;impl", v.getId()); + Assert.assertEquals("taglibs-standard3-impl", v.getName()); + + v = new SemanticVersion("taglibs5-standard-1.0.0-alpha+001", ""); + Assert.assertEquals("taglibs5;standard", v.getId()); + Assert.assertEquals("taglibs5-standard", v.getName()); + + v = new SemanticVersion("taglibs5-standard-1-0-1.2.5-alpha+001", ""); + Assert.assertEquals("taglibs5;standard;1;0", v.getId()); + Assert.assertEquals("taglibs5-standard-1-0", v.getName()); + Assert.assertEquals("[taglibs5, standard, 1, 1, 2, 5, alpha, 1]", v.toString()); + + v = new SemanticVersion("test-me-1.0.0-x.7.z.92", ""); + Assert.assertEquals("test;me", v.getId()); + Assert.assertEquals("test-me", v.getName()); + Assert.assertEquals("[test, me, 1, x.7.z.92]", v.toString()); + + v = new SemanticVersion("objecttrading.data-22.80-SNAPSHOT+190722113743.46c7154.jar", ""); + Assert.assertEquals("objecttrading.data", v.getId()); + } +} From cf2f14a9f7d1b3af2ea8fb5263a60d2a41ef367d Mon Sep 17 00:00:00 2001 From: Robot Date: Fri, 2 Aug 2019 11:12:33 +0300 Subject: [PATCH 2164/2572] [Skip CI] Generate release version --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index b1d62794..e56d773f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ -#Mon Jul 08 20:35:10 MSK 2019 +#Fri Aug 02 11:12:33 MSK 2019 dfpVersion=0.10.7 -version=5.2.54-SNAPSHOT +version=5.2.54 deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java hdTimeVersion=0.2.4 From 58586c933750c5ae8b40745b0deb12307f6db3d8 Mon Sep 17 00:00:00 2001 From: Robot Date: Fri, 2 Aug 2019 11:12:39 +0300 Subject: [PATCH 2165/2572] [Skip CI] Generate next development version --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index e56d773f..61b76ede 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ -#Fri Aug 02 11:12:33 MSK 2019 +#Fri Aug 02 11:12:39 MSK 2019 dfpVersion=0.10.7 -version=5.2.54 +version=5.2.55-SNAPSHOT deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java hdTimeVersion=0.2.4 From 4efdc5c1bf22dcea5d7d6faf8eb71cb3e1b84bc4 Mon Sep 17 00:00:00 2001 From: Artyom Korzun Date: Tue, 6 Aug 2019 17:18:46 +0300 Subject: [PATCH 2166/2572] removed incrementing modCount from set (index, value) method in Lists --- collections/src/main/templates/ArrayList.vpp | 1 - 1 file changed, 1 deletion(-) diff --git a/collections/src/main/templates/ArrayList.vpp b/collections/src/main/templates/ArrayList.vpp index 684bb7c8..63a5995d 100644 --- a/collections/src/main/templates/ArrayList.vpp +++ b/collections/src/main/templates/ArrayList.vpp @@ -589,7 +589,6 @@ public final class ${name}ArrayList extends AbstractList<${type_Object}> impleme rangeCheck(index); ${type} oldValue = (${type}) elementData[index]; elementData[index] = element; - modCount++; return oldValue; } From 51885f3046a2a0c43f7bd3d366a82503d4d35cd9 Mon Sep 17 00:00:00 2001 From: Robot Date: Tue, 6 Aug 2019 17:19:33 +0300 Subject: [PATCH 2167/2572] [Skip CI] Generate release version --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 61b76ede..00909566 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ -#Fri Aug 02 11:12:39 MSK 2019 +#Tue Aug 06 17:19:32 MSK 2019 dfpVersion=0.10.7 -version=5.2.55-SNAPSHOT +version=5.2.55 deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java hdTimeVersion=0.2.4 From d4f045772273f2d30547887626f34045fca0f14b Mon Sep 17 00:00:00 2001 From: Robot Date: Tue, 6 Aug 2019 17:19:39 +0300 Subject: [PATCH 2168/2572] [Skip CI] Generate next development version --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 00909566..6e6c482a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ -#Tue Aug 06 17:19:32 MSK 2019 +#Tue Aug 06 17:19:39 MSK 2019 dfpVersion=0.10.7 -version=5.2.55 +version=5.2.56-SNAPSHOT deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java hdTimeVersion=0.2.4 From 480b3bd41792aa5a544daf98ef4773abf089ae85 Mon Sep 17 00:00:00 2001 From: Alex Karpovich Date: Tue, 15 Oct 2019 11:33:39 +0300 Subject: [PATCH 2169/2572] [*] redundant libraries --- util/build.gradle | 4 +- .../deltix/util/currency/CurrencyCodes.xml | 5983 +---------------- 2 files changed, 3 insertions(+), 5984 deletions(-) diff --git a/util/build.gradle b/util/build.gradle index 0f60ee32..d6a4ea8c 100644 --- a/util/build.gradle +++ b/util/build.gradle @@ -20,8 +20,8 @@ dependencies { compile 'org.glassfish.jaxb:jaxb-runtime:2.2.11' // Glassfish replaces JAXB RI //compile('javax.xml:jsr173:1.0'){ transitive = false } - compile('net.java.dev.jna:jna:3.4.0'){ transitive = false } - compile('net.java.dev.jna:platform:3.4.0'){ transitive = false } +// compile('net.java.dev.jna:jna:4.2.1'){ transitive = false } +// compile('net.java.dev.jna:jna-platform:4.2.1'){ transitive = false } compile('org.apache.bcel:bcel:6.0'){ transitive = false } } diff --git a/util/src/main/resources/deltix/util/currency/CurrencyCodes.xml b/util/src/main/resources/deltix/util/currency/CurrencyCodes.xml index 8a8fccd9..ab7a6538 100644 --- a/util/src/main/resources/deltix/util/currency/CurrencyCodes.xml +++ b/util/src/main/resources/deltix/util/currency/CurrencyCodes.xml @@ -1,5982 +1 @@ - - - - - 1301 - Ripple - XRP - XRP - 301 - - - 1302 - Metaverse ETP - ETP - ETP - 302 - - - 1303 - Bitcoin Cash - BCH - BCH - 303 - - - 1304 - OmiseGO - OMG - OMG - 304 - - - 1305 - Neo - NEO - NEO - 305 - - - 1306 - Iota - MIOTA - IOT - 306 - - - 1307 - DigitalCash - DASH - DSH - 307 - - - 1308 - Zcash - ZEC - ZEC - 308 - - - 1309 - Monero - XMR - XMR - 309 - - - 1310 - Ethereum Classic - ETC - ETC - 310 - - - 1311 - EOS - EOS - EOS - 311 - - - 1312 - Aventus - AVT - AVT - 312 - - - 1313 - Qtum - QTUM - QTM - 313 - - - 1314 - Santiment - SAN - SAN - 314 - - - 1315 - Eidoo - EDO - EDO - 315 - - - 1316 - Bitcoin Gold - BTG - BTG - 316 - - - 1317 - Streamr - DATA - DAT - 317 - - - 1318 - QASH - QASH - QSH - 318 - - - 1319 - YOYOW - YOYOW - YYW - 319 - - - 1321 - Tether - USDT - THR - 321 - - - 1322 - Cardano - ADA - ADA - 322 - - - 1323 - Binance Coin - BNB - BNB - 323 - - - 1325 - Bread - BRD - BRD - 325 - - - 1326 - Gifto - GTO - GTO - 326 - - - 1327 - Iconomi - ICN - ICN - 327 - - - 1329 - Icon - ICX - ICX - 329 - - - 1330 - Lisk - LSK - LSK - 330 - - - 1331 - Nano - NANO - NAN - 331 - - - 1333 - Salt - SALT - SLT - 333 - - - 1334 - Stratis - STRAT - STR - 334 - - - 1335 - Tron - TRX - TRX - 335 - - - 1336 - Wings - WINGS - WNG - 336 - - - 1337 - Stellar Lumens - XLM - XLM - 337 - - - 1338 - Verge - XVG - XVG - 338 - - - 1641 - Litecoin - LTC - LTC - 641 - - - 1741 - Bitcoin - BTC - XBT - 741 - - - 1841 - Ethereum - ETH - ETH - 841 - - - 8 - ALBANIA - Lek - ALL - Lek - - - 12 - ALGERIA - Algerian Dinar - DZD - DZD - - - 20 - ADP - ADP - ADP - - - 31 - AZERBAIJAN - Azerbaijanian Manat - AZM - ман. - - - 32 - ARGENTINA - Argentine Peso - ARS - $ - - - 36 - Australian Dollar - AUD - $ - - - 40 - ATS - ATS - ATS - - - 44 - BAHAMAS - Bahamian Dollar - BSD - BSD - - - 48 - BAHRAIN - Bahraini Dinar - BHD - د.ب.†- - - 50 - BANGLADESH - Taka - BDT - à§³ - - - 51 - ARMENIA - Armenian Dram - AMD - Õ¤Ö€. - - - 52 - BARBADOS - Barbados Dollar - BBD - BBD - - - 56 - BEF - BEF - BEF - - - 60 - BERMUDA - Bermudian Dollar (customarily known as Bermuda Dol - BMD - BMD - - - 64 - BHUTAN - Ngultrum - BTN - BTN - - - 68 - BOLIVIA - Boliviano - BOB - $b - - - 72 - BOTSWANA - Pula - BWP - BWP - - - 84 - BELIZE - Belize Dollar - BZD - BZ$ - - - 90 - SOLOMON ISLANDS - Solomon Islands Dollar - SBD - SBD - - - 96 - BRUNEI DARUSSALAM - Brunei Dollar - BND - $ - - - 104 - MYANMAR - Kyat - MMK - MMK - - - 108 - BURUNDI - Burundi Franc - BIF - BIF - - - 116 - CAMBODIA - Riel - KHR - ៛ - - - 124 - CANADA - Canadian Dollar - CAD - $ - - - 132 - CAPE VERDE - Cape Verde Escudo - CVE - CVE - - - 136 - CAYMAN ISLANDS - Cayman Islands Dollar - KYD - KYD - - - 144 - SRI LANKA - Sri Lanka Rupee - LKR - රු. - - - 152 - CHILE - Chilean Peso - CLP - $ - - - 156 - CHINA - Yuan Renminbi - CNY - Â¥ - - - 170 - COLOMBIA - Colombian Peso - COP - $ - - - 174 - COMOROS - Comoro Franc - KMF - KMF - - - 188 - COSTA RICA - Costa Rican Colon - CRC - â‚¡ - - - 191 - CROATIA - Croatian Kuna - HRK - kn - - - 192 - CUBA - Cuban Peso - CUP - CUP - - - 196 - CYPRUS - Cyprus Pound - CYP - CYP - - - 203 - CZECH REPUBLIC - Czech Koruna - CZK - - - - 208 - Danish Krone - DKK - kr. - - - 214 - DOMINICAN REPUBLIC - Dominican Peso - DOP - RD$ - - - 222 - EL SALVADOR - El Salvador Colon - SVC - SVC - - - 230 - ETHIOPIA - Ethiopian Birr - ETB - ETB - - - 232 - ERITREA - Nakfa - ERN - ERN - - - 233 - ESTONIA - Kroon - EEK - kr - - - 238 - FALKLAND ISLANDS (MALVINAS) - Falkland Islands Pound - FKP - FKP - - - 242 - FIJI - Fiji Dollar - FJD - FJD - - - 246 - FIM - FIM - FIM - - - 250 - FRF - FRF - FRF - FRF - - - 262 - DJIBOUTI - Djibouti Franc - DJF - DJF - - - 270 - GAMBIA - Dalasi - GMD - GMD - - - 276 - DEM - DEM - DEM - - - 288 - GHANA - Cedi - GHC - GHC - - - 292 - GIBRALTAR - Gibraltar Pound - GIP - GIP - - - 300 - GRD - GRD - GRD - - - 320 - GUATEMALA - Quetzal - GTQ - Q - - - 324 - GUINEA - Guinea Franc - GNF - GNF - - - 328 - GUYANA - Guyana Dollar - GYD - GYD - - - 332 - HAITI - Gourde - HTG - HTG - - - 340 - HONDURAS - Lempira - HNL - L. - - - 344 - HONG KONG - Hong Kong Dollar - HKD - HK$ - - - 348 - HUNGARY - Forint - HUF - Ft - - - 352 - ICELAND - Iceland Krona - ISK - kr. - - - 356 - Indian Rupee - INR - Rs. - - - 360 - INDONESIA - Rupiah - IDR - Rp - - - 364 - IRAN (ISLAMIC REPUBLIC OF) - Iranian Rial - IRR - ريال - - - 368 - IRAQ - Iraqi Dinar - IQD - د.ع.†- - - 372 - IEP - IEP - IEP - - - 376 - ISRAEL - New Israeli Sheqel - ILS - ₪ - - - 380 - ITL - ITL - ITL - - - 388 - JAMAICA - Jamaican Dollar - JMD - J$ - - - 392 - JAPAN - Yen - JPY - Â¥ - - - 398 - KAZAKHSTAN - Tenge - KZT - Т - - - 400 - JORDAN - Jordanian Dinar - JOD - د.ا.†- - - 404 - KENYA - Kenyan Shilling - KES - S - - - 408 - KOREA, DEMOCRATIC PEOPLE''S REPUBLIC OF - North Korean Won - KPW - KPW - - - 410 - KOREA, DEMOCRATIC PEOPLE''S REPUBLIC OF - Won - KRW - â‚© - - - 414 - KUWAIT - Kuwaiti Dinar - KWD - د.Ùƒ.†- - - 417 - KYRGYZSTAN - Som - KGS - Ñом - - - 418 - LAO PEOPLE''S DEMOCRATIC REPUBLIC - Kip - LAK - LAK - - - 422 - LEBANON - Lebanese Pound - LBP - Ù„.Ù„.†- - - 426 - LESOTHO - Loti - LSL - LSL - - - 428 - LATVIA - Latvian Lats - LVL - Ls - - - 430 - LIBERIA - Liberian Dollar - LRD - LRD - - - 434 - LIBYAN ARAB JAMAHIRIYA - Libyan Dinar - LYD - د.Ù„.†- - - 440 - LITHUANIA - Lithuanian Litas - LTL - Lt - - - 442 - LUF - LUF - LUF - - - 446 - MACAO - Pataca - MOP - MOP - - - 454 - MALAWI - Kwacha - MWK - MWK - - - 458 - MALAYSIA - Malaysian Ringgit - MYR - RM - - - 462 - MALDIVES - Rufiyaa - MVR - Þƒ. - - - 470 - MALTA - Maltese Lira - ^MTL - Lm - - - 478 - MAURITANIA - Ouguiya - MRO - MRO - - - 480 - MAURITIUS - Mauritius Rupee - MUR - MUR - - - 484 - MEXICO - Mexican Peso - MXN - $ - - - 496 - MONGOLIA - Tugrik - MNT - â‚® - - - 498 - MOLDOVA, REPUBLIC OF - Moldovan Leu - MDL - MDL - - - 504 - Moroccan Dirham - MAD - د.Ù….†- - - 512 - OMAN - Rial Omani - OMR - ر.ع.†- - - 516 - NAMIBIA - Namibian Dollar - NAD - NAD - - - 524 - NEPAL - Nepalese Rupee - NPR - रॠ- - - 528 - NLG - NLG - NLG - - - 532 - NETHERLANDS ANTILLES - Netherlands Antillian Guikder - ANG - ANG - - - 533 - ARUBA - Aruban Guilder - AWG - AWG - - - 548 - VANUATU - Vatu - VUV - VUV - - - 554 - New Zealand Dollar - NZD - $ - - - 558 - NICARAGUA - Cordoba Oro - NIO - N - - - 566 - NIGERIA - Naira - NGN - NGN - - - 578 - Norwegian Krone - NOK - kr - - - 586 - PAKISTAN - Pakistan Rupee - PKR - Rs - - - 590 - PANAMA - Balboa - PAB - B/. - - - 598 - PAPUA NEW GUINEA - Kina - PGK - PGK - - - 600 - PARAGUAY - Guarani - PYG - Gs - - - 604 - PERU - Nuevo Sol - PEN - S/. - - - 608 - PHILIPPINES - Philippine Peso - PHP - PhP - - - 620 - PTE - PTE - PTE - - - 624 - GUINEA-BISSAU - Guinea-Bissau Peso - GWP - GWP - - - 634 - QATAR - Qatari Rial - QAR - ر.Ù‚.†- - - 642 - ROMANIA - Old Leu - ROL - lei - - - 643 - RUSSIAN FEDERATION - Russian Ruble - RUB - RUB - - - 646 - RWANDA - Rwanda Franc - RWF - RWF - - - 654 - SAINT HELENA - Saint Helena Pound - SHP - SHP - - - 678 - S?O TOME AND PRINCIPE - Dobra - STD - STD - - - 682 - SAUDI ARABIA - Saudi Riyal - SAR - ر.س.†- - - 690 - SEYCHELLES - Seychelles Rupee - SCR - SCR - - - 694 - SIERRA LEONE - Leone - SLL - SLL - - - 702 - SINGAPORE - Singapore Dollar - SGD - $ - - - 703 - SLOVAKIA - Slovak Koruna - SKK - Sk - - - 704 - VIET NAM - Dong - VND - â‚« - - - 705 - SLOVENIA - Tolar - SIT - SIT - - - 706 - SOMALIA - Somali Shilling - SOS - SOS - - - 710 - Rand - ZAR - R - - - 716 - ZIMBABWE - Zimbabwe Dollar - ZWD - Z$ - - - 724 - ESP - ESP - ESP - - - 736 - SUDAN - Sudanese Dinar - SDD - SDD - - - 748 - SWAZILAND - Lilangeni - SZL - SZL - - - 752 - SWEDEN - Swedish Krona - SEK - kr - - - 756 - Swiss Franc - CHF - fr. - - - 760 - SYRIAN ARAB REPUBLIC - Syrian Pound - SYP - Ù„.س.†- - - 764 - THAILAND - Baht - THB - ฿ - - - 776 - TONGA - Pa''anga - TOP - TOP - - - 777 - CHINA - Yuan Renminbi - CNH - Â¥ - - - 780 - TRINNumericCodeAD AND TOBAGO - TrinNumericCodead and Tobago Dollar - TTD - TT$ - - - 784 - UNITED ARAB EMIRATES - UAE Dirham - AED - د.Ø¥.†- - - 788 - TUNISIA - Tunisian Dinar - TND - د.ت.†- - - 792 - TURKEY - Old Turkish Lira - TRL - ₤ - - - 795 - TURKMENISTAN - Manat - TMM - m. - - - 800 - UGANDA - Uganda Shilling - UGX - UGX - - - 807 - MACEDONIA, THE FORMER YUGOSLAV REPUBLIC OF - Denar - MKD - ден. - - - 818 - EGYPT - Egyptian Pound - EGP - ج.Ù….†- - - 826 - UNITED KINGDOM - Pound Sterling - GBP - £ - - - 834 - TANZANIA, UNITED REPUBLIC OF - Tanzanian Shilling - TZS - TZS - - - 840 - US Dollar - USD - $ - - - 858 - URUGUAY - Peso Uruguayo - UYU - $U - - - 860 - UZBEKISTAN - Uzbekistan Sum - UZS - Ñўм - - - 862 - VENEZUELA - Bolivar - VEB - Bs - - - 882 - SAMOA - Tala - WST - WST - - - 886 - YEMEN - Yemeni Rial - YER - ر.ÙŠ.†- - - 891 - SERBIA AND MONTENEGRO - Serbian Dinar - CSD - Дин. - - - 894 - ZAMBIA - Kwacha - ZMK - ZMK - - - 901 - TAIWAN, PROVINCE OF CHINA - New Taiwan Dollar - TWD - NT$ - - - 943 - MOZAMBIQUE - Merical - MZN - MZN - - - 946 - ROMANIA - New Leu - RON - RON - - - 947 - SWITZERLAND - WIR Euro - CHE - CHE - - - 948 - SWITZERLAND - WIR Franc - CHW - CHW - - - 949 - TURKEY - New Turkish Lira - TRY - YTL - - - 950 - CFA Franc BEAC - XAF - XAF - - - 951 - East Caribbean Dollar - XCD - XCD - - - 952 - CFA Franc BCEAO - XOF - XOF - - - 953 - CFP Franc - XPF - XPF - - - 955 - Bond Markets Units European Composite Unit (EURCO) - XBA - XBA - - - 956 - European Monetary Unit (E.M.U.-6) - XBB - XBB - - - 957 - European Unit of Account 9(E.U.A.-9) - XBC - XBC - - - 958 - European Unit of Account 17(E.U.A.-17) - XBD - XBD - - - 959 - Gold - XAU - XAU - - - 960 - INTERNATIONAL MONETARY FUND (I.M.F) - SDR - XDR - XDR - - - 961 - Silver - XAG - XAG - - - 962 - Platinum - XPT - XPT - - - 963 - AlphabeticCodes specifically reserved for testing - XTS - XTS - - - 964 - Palladium - XPD - XPD - - - 968 - SURINAME - Surinam Dollar - SRD - SRD - - - 969 - MADAGASCAR - Malagascy Ariary - MGA - MGA - - - 970 - COLOMBIA - UnNumericCodead de Valor Real - COU - COU - - - 971 - AFGHANISTAN - Afghani - AFN - AFN - - - 972 - TAJIKISTAN - Somoni - TJS - TJS - - - 973 - ANGOLA - Kwanza - AOA - AOA - - - 974 - BELARUS - Belarussian Ruble - BYR - BYR - - - 975 - BULGARIA - Bulgarian Lev - BGN - BGN - - - 976 - CONGO, THE DEMOCRATIC REPUBLIC OF - Franc Congolais - CDF - CDF - - - 977 - BOSNIA & HERZEGOVINA - Convertible Marks - BAM - KM - - - 978 - Euro - EUR - € - - - 979 - MEXICO - Mexican UnNumericCodead de Inversion (UNumericCode - MXV - MXV - - - 980 - UKRAINE - Hryvnia - UAH - грн. - - - 981 - GEORGIA - Lari - GEL - Lari - - - 984 - BOLIVIA - Mvdol - BOV - BOV - - - 985 - POLAND - Zloty - PLN - zÅ‚ - - - 986 - BRAZIL - Brazilian Real - BRL - R$ - - - 990 - CHILE - UnNumericCodeades de formento - CLF - CLF - - - 997 - UNITED STATES - (Next day) - USN - USN - - - 998 - UNITED STATES - (Same day) - USS - USS - - - 999 - - XXX - XXX - - - 1339 - Ark - ARK - ARK - - - 1341 - Komodo - KMD - KMD - - - 1342 - Power Ledger - POWR - PWR - - - 1343 - AdEx - ADX - ADX - - - 1345 - Aeternity - AE - AE - - - 1346 - Aion - AION - AIO - - - 1347 - Ambrosus - AMB - AMB - - - 1349 - AppCoins - APPC - APP - - - 1350 - Aeron - ARN - ARN - - - 1351 - AirSwap - AST - AST - - - 1353 - Basic Attention Token - BAT - BAT - - - 1354 - Bitcoin Diamond - BCD - BCD - - - 1355 - BlockMason Credit Protocol - BCPT - BCP - - - 1357 - Bluzelle - BLZ - BLZ - - - 1358 - Bancor - BNT - BNT - - - 1359 - ETHOS - ETHOS - BQX - - - 1361 - BitShares - BTS - BTS - - - 1362 - Blox - CDT - CDT - - - 1363 - ChatCoin - CHAT - CHT - - - 1365 - CyberMiles - CMT - CMT - - - 1366 - Cindicator - CND - CND - - - 1367 - Centra - CTR - CTR - - - 1369 - DigixDAO - DGD - DGD - - - 1370 - Agrello - DLT - DLT - - - 1371 - district0x - DNT - DNT - - - 1373 - aelf - ELF - ELF - - - 1374 - Enigma - ENG - ENG - - - 1375 - Enjin Coin - ENJ - ENJ - - - 1377 - Everex - EVX - EVX - - - 1378 - Etherparty - FUEL - FUE - - - 1379 - FunFair - FUN - FUN - - - 1381 - Gas - GAS - GAS - - - 1382 - Genesis Vision - GVT - GVT - - - 1383 - GXChain - GXS - GXS - - - 1384 - Hshare - HSR - HSR - - - 1385 - Insolar - INS - INS - - - 1386 - IOStoken - IOST - IOS - - - 1387 - Kyber Network - KNC - KNC - - - 1389 - Lendingblock - LND - LND - - - 1390 - ChainLink - LINK - LNK - - - 1391 - Loopring - LRC - LRC - - - 1393 - Lunyr - LUN - LUN - - - 1394 - Decentraland - MANA - MAN - - - 1395 - Crypto.com - MCO - MCO - - - 1396 - Moeda Loyalty Points - MDA - MDA - - - 1397 - Modum - MOD - MOD - - - 1399 - Monetha - MTH - MTH - - - 1401 - Metal - MTL - MET - - - 1402 - NavCoin - NAV - NAV - - - 1403 - Nucleus Vision - NCASH - NCH - - - 1405 - Neblio - NEBL - NEB - - - 1406 - Nuls - NULS - NUL - - - 1407 - OpenANX - OAX - OAX - - - 1409 - Ontology - ONT - ONT - - - 1411 - Simple Token - OST - OST - - - 1412 - PIVX - PIVX - PIV - - - 1413 - POA Network - POA - POA - - - 1415 - Po.et - POE - POE - - - 1416 - Populous - PPT - PPT - - - 1419 - QLINK - QLC - QLC - - - 1420 - Quantstamp - QSP - QSP - - - 1421 - Ripio Credit Network - RCN - RCN - - - 1423 - Raiden Network Token - RDN - RDN - - - 1424 - Request Network - REQ - REQ - - - 1425 - iExec RLC - RLC - RLC - - - 1427 - Red Pulse - PHX - RPX - - - 1429 - SingularDTV - SNGLS - SNG - - - 1431 - SONM - SNM - SNM - - - 1432 - Status - SNT - SNT - - - 1433 - Steem - STEEM - STM - - - 1435 - Storj - STORJ - STJ - - - 1436 - Storm - STORM - SRM - - - 1437 - Substratum - SUB - SUB - - - 1438 - Syscoin - SYS - SYS - - - 1439 - Time New Bank - TNB - TNB - - - 1441 - Tierion - TNT - TNT - - - 1443 - Triggers - TRIG - TRI - - - 1444 - VeChain - VET - VEN - - - 1445 - Viacoin - VIA - VIA - - - 1447 - Viberate - VIB - VIB - - - 1448 - VIBE - VIBE - VBE - - - 1449 - WaBi - WABI - WAB - - - 1450 - Wanchain - WAN - WAN - - - 1451 - Waves - WAVES - WVS - - - 1452 - WePower - WPR - WPR - - - 1453 - Waltonchain - WTC - WTC - - - 1455 - NEM - XEM - XEM - - - 1456 - ZCoin - XZC - XZC - - - 1457 - Zilliqa - ZIL - ZIL - - - 1459 - 0x Protocol - ZRX - ZRX - - - 1000 - HyperCash - HC - HC - - - 1001 - GoChain - GO - GO - - - 1002 - Paxos Standard Token - PAX - PAX - - - 1003 - Ravencoin - RVN - RVN - - - 1004 - Decred - DCR - DCR - - - 1005 - Mithril - MITH - MITH - - - 1006 - USD Coin - USDC - USDC - - - 1007 - Bitcoin SV - BSV - BSV - - - 1008 - Tezos - XTZ - XTZ - - - 1009 - Maker - MKR - MKR - - - 1010 - Dogecoin - DOGE - DOGE - - - 1011 - Bytecoin - BCN - BCN - - - 1012 - TrueUSD - TUSD - TUSD - - - 1013 - DigiByte - DGB - DGB - - - 1014 - Siacoin - SC - SC - - - 1015 - Bytom - BTM - BTM - - - 1016 - Pundi X - NPXS - NPXS - - - 1017 - Augur - REP - REP - - - 1018 - MaidSafeCoin - MAID - MAID - - - 1019 - Golem - GNT - GNT - - - 1020 - Electroneum - ETN - ETN - - - 1021 - Holo - HOT - HOT - - - 1022 - Cryptonex - CNX - CNX - - - 1023 - Factom - FCT - FCT - - - 1024 - Dai - DAI - DAI - - - 1025 - KuCoin Shares - KCS - KCS - - - 1026 - Worldwide Asset Exchange - WAX - WAX - - - 1027 - Ardor - ARDR - ARDR - - - 1028 - Huobi Token - HT - HT - - - 1029 - MOAC - MOAC - MOAC - - - 1030 - Revain - R - R - - - 1031 - MonaCoin - MONA - MONA - - - 1032 - Nexo - NEXO - NEXO - - - 1033 - ODEM - ODE - ODE - - - 1034 - Insight Chain - INB - INB - - - 1035 - ReddCoin - RDD - RDD - - - 1036 - Mixin - XIN - XIN - - - 1037 - Dentacoin - DCN - DCN - - - 1038 - Horizen - ZEN - ZEN - - - 1039 - Polymath - POLY - POLY - - - 1040 - Nasdacoin - NSD - NSD - - - 1041 - SIRIN LABS Token - SRN - SRN - - - 1042 - Digitex Futures - DGTX - DGTX - - - 1043 - Dropil - DROP - DROP - - - 1044 - Nxt - NXT - NXT - - - 1045 - MobileGo - MGO - MGO - - - 1046 - BOScoin - BOS - BOS - - - 1047 - TenX - PAY - PAY - - - 1048 - Theta Token - THETA - THETA - - - 1049 - Nebulas - NAS - NAS - - - 1050 - QuarkChain - QKC - QKC - - - 1051 - Loom Network - LOOM - LOOM - - - 1052 - Veritaseum - VERI - VERI - - - 1053 - Elastos - ELA - ELA - - - 1054 - WaykiChain - WICC - WICC - - - 1055 - ETERNAL TOKEN - XET - XET - - - 1056 - Dragonchain - DRGN - DRGN - - - 1057 - ProximaX - XPX - XPX - - - 1058 - Bitcoin Private - BTCP - BTCP - - - 1059 - Gemini Dollar - GUSD - GUSD - - - 1060 - Linkey - LKY - LKY - - - 1061 - BHPCash - BHPC - BHPC - - - 1062 - Smartlands - SLT - SLT - - - 1063 - Nectar - NEC - NEC - - - 1064 - Civic - CVC - CVC - - - 1065 - Odyssey - OCN - OCN - - - 1066 - Endor Protocol - EDR - EDR - - - 1067 - Bibox Token - BIX - BIX - - - 1068 - ARBITRAGE - ARB - ARB - - - 1069 - Optimal Shelf... - OSA - OSA - - - 1070 - Dent - DENT - DENT - - - 1071 - Groestlcoin - GRS - GRS - - - 1072 - Byteball Bytes - GBYTE - GBYTE - - - 1073 - RChain - RHOC - RHOC - - - 1074 - THEKEY - TKY - TKY - - - 1075 - Centrality - CENNZ - CENNZ - - - 1076 - Peercoin - PPC - PPC - - - 1077 - Emercoin - EMC - EMC - - - 1078 - ETH Lend - LEND - LEND - - - 1079 - Cloak Coin - CLOAK - CLOAK - - - 1080 - SKY - SKY - SKY - - - 1081 - IOTX - IOTX - IOTX - - - 1082 - SingularityNET - AGI - AGI - - - 1083 - Nexus - NXS - NXS - - - 1084 - Key Coin - KEY - KEY - - - 1085 - Mainframe - MFT - MFT - - - 1086 - DOCK - DOCK - DOCK - - - 1087 - Bit Connect - BCC - BCC - - - 1088 - VEN - VEN - VEN - - - 1089 - Red Pulse - RPX - RPX - - - 1090 - REN - REN - REN - - - 1091 - Ethos - BQX - BQX - - - 1092 - BnkToTheFuture - BFT - BFT - - - 1093 - FSN - FSN - FSN - - - 1094 - Matrix - MAN - MAN - - - 1095 - Gnosis - GNO - GNO - - - 1096 - Melon - MLN - MLN - - - 1097 - Namecoin - NMC - NMC - - - 1098 - Vertcoin - VTC - VTC - - - 1099 - Burst - BURST - BURST - - - 1830 - Steem Dollars - STEEMD - SBD - - - 1332 - BitTorrent - BTT - BTT - - - 1831 - Clams - CLAM - CLAM - - - 1832 - FOAM - FOAM - FOAM - - - 1833 - GameCredits - GAME - GAME - - - 1835 - LBRY Credits - LBC - LBC - - - 1836 - Numeraire - NMR - NMR - - - 1837 - Pascal Coin - PASC - PASC - - - 1838 - Counterparty - XCP - XCP - - - 1839 - Primecoin - XPM - XPM - - - 1829 - StableUSD - USDS - USDS - - - 1823 - STASIS EURS - EURS - EURS - - - 1824 - UTRUST - UTK - UTK - - - 1825 - Cortex - CTXC - CTXC - - - 1827 - Project Pai - PAI - PAI - - - 1828 - SmartMesh - SMT - SMT - - - 1794 - Grin - GRIN - GRIN - - - 1796 - Unikoin Gold - UKG - UKG - - - 1797 - Genaro Network - GNX - GNX - - - 1798 - Penta - PNT - PNT - - - 1799 - Content Neutrality Network - CNN - CNN - - - 1801 - Cred - LBA - LBA - - - 1802 - Blocktix - TIX - TIX - - - 1803 - Lympo - LYM - LYM - - - 1804 - All Sports - SOC - SOC - - - 1805 - Jibrel Network - JNT - JNT - - - 1806 - DATA - DTA - DTA - - - 1808 - Achain - ACT - ACT - - - 1809 - TokenCard - TKN - TKN - - - 1810 - Propy - PRO - PRO - - - 1811 - DigitalNote - XDN - XDN - - - 1812 - Crypterium - CRPT - CRPT - - - 1813 - Aragon - ANT - ANT - - - 1814 - BLOCKv - VEE - VEE - - - 1815 - Blocknet - BLOCK - BLOCK - - - 1816 - PumaPay - PMA - PMA - - - 1817 - Ignis - IGNIS - IGNIS - - - 1819 - Edgeless - EDG - EDG - - - 1821 - Ontology Gas - ONG - ONG - - - 1822 - Fetch.AI - FET - FET - - - 1793 - HUSD Solution - HUSD - HUSD - - - 1632 - Ink Protocol - XNK - XNK - - - 1633 - Crowd Machine - CMCT - CMCT - - - 1636 - Nexium - NXC - NXC - - - 1637 - SIBCoin - SIB - SIB - - - 1638 - Swarm City - SWT - SWT - - - 1639 - Patientory - PTOY - PTOY - - - 1640 - BANKEX - BKX - BKX - - - 1644 - Matchpool - GUP - GUP - - - 1645 - Humaniq - HMQ - HMQ - - - 1647 - HyperSpace - AMP - AMP - - - 1648 - DECENT - DCT - DCT - - - 1649 - SpaceChain - SPC - SPC - - - 1650 - NAGA - NGC - NGC - - - 1651 - NoLimitCoin - NLC2 - NLC2 - - - 1652 - Aeon - AEON - AEON - - - 1653 - OriginTrail - TRAC - TRAC - - - 1655 - eBoost - EBST - EBST - - - 1656 - CannabisCoin - CANN - CANN - - - 1657 - Breakout - BRK - BRK - - - 1658 - Sequence - SEQ - SEQ - - - 1659 - TransferCoin - TX - TX - - - 1660 - Memetic / PepeCoin - MEME - MEME - - - 1661 - DopeCoin - DOPE - DOPE - - - 1662 - Internet of People - IOP - IOP - - - 1663 - VeriumReserve - VRM - VRM - - - 1664 - PinkCoin - PINK - PINK - - - 1665 - Syndicate - SYNX - SYNX - - - 1666 - 2GIVE - 2GIVE - 2GIVE - - - 1667 - ExclusiveCoin - EXCL - EXCL - - - 1668 - Dynamic - DYN - DYN - - - 1669 - ArtByte - ABY - ABY - - - 1670 - FoldingCoin - FLDC - FLDC - - - 1671 - Kore - KORE - KORE - - - 1672 - GeoCoin - GEO - GEO - - - 1673 - Expanse - EXP - EXP - - - 1674 - OKCash - OK - OK - - - 1675 - Musicoin - MUSIC - MUSIC - - - 1676 - Golos - GOLOS - GOLOS - - - 1677 - Blockparty (BOXX Token) - BOXX - BOXX - - - 1679 - Curecoin - CURE - CURE - - - 1680 - SolarCoin - SLR - SLR - - - 1681 - Bloom - BLT - BLT - - - 1683 - Decision Token - HST - HST - - - 1684 - Haven Protocol - XHV - XHV - - - 1685 - GridCoin - GRC - GRC - - - 1686 - MonetaryUnit - MUE - MUE - - - 1687 - Myriad - XMY - XMY - - - 1688 - Diamond - DMD - DMD - - - 1689 - I/O Coin - IOC - IOC - - - 1691 - Bean Cash - BITB - BITB - - - 1692 - Crown - CRW - CRW - - - 1693 - Radium - RADS - RADS - - - 1695 - VeriCoin - VRC - VRC - - - 1696 - Incent - INCNT - INCNT - - - 1697 - RevolutionVR - RVR - RVR - - - 1698 - XEL - XEL - XEL - - - 1699 - UpToken - UP - UP - - - 1700 - ION - ION - ION - - - 1701 - BitTube - TUBE - TUBE - - - 1707 - HempCoin - THC - THC - - - 1708 - Feathercoin - FTC - FTC - - - 1709 - Shift - SHIFT - SHIFT - - - 1711 - adToken - ADT - ADT - - - 1712 - PotCoin - POT - POT - - - 1713 - BlackCoin - BLK - BLK - - - 1714 - Sentinel Protocol - UPP - UPP - - - 1715 - Mercury - MER - MER - - - 1717 - Mobius - MOBI - MOBI - - - 1718 - ZClassic - ZCL - ZCL - - - 1719 - CashBet Coin - CBC - CBC - - - 1720 - Metronome - MET - MET - - - 1721 - VITE - VITE - VITE - - - 1722 - Hydro - HYDRO - HYDRO - - - 1723 - BitBay - BAY - BAY - - - 1725 - IHT Real Estate Protocol - IHT - IHT - - - 1726 - Refereum - RFR - RFR - - - 1727 - Ubiq - UBQ - UBQ - - - 1728 - FLO - FLO - FLO - - - 1729 - WhiteCoin - XWC - XWC - - - 1730 - Moss Coin - MOC - MOC - - - 1731 - NKN - NKN - NKN - - - 1732 - Quant - QNT - QNT - - - 1733 - Crypto.com Chain - CRO - CRO - - - 1734 - Particl - PART - PART - - - 1735 - Quantum Resistant Ledger - QRL - QRL - - - 1737 - DMarket - DMT - DMT - - - 1738 - SaluS - SLS - SLS - - - 1739 - MediBloc [ERC20] - MEDX - MEDX - - - 1740 - Einsteinium - EMC2 - EMC2 - - - 1742 - AidCoin - AID - AID - - - 1743 - Auctus - AUC - AUC - - - 1744 - Banyan Network - BBN - BBN - - - 1745 - Bitcoin Interest - BCI - BCI - - - 1746 - CommerceBlock - CBT - CBT - - - 1747 - Callisto Network - CLO - CLO - - - 1749 - Digix Gold Token - DGX - DGX - - - 1750 - Dether - DTH - DTH - - - 1751 - Essentia - ESS - ESS - - - 1753 - ParkinGo - GOT - GOT - - - 1754 - Internet Node Token - INT - INT - - - 1755 - On.Live - ONL - ONL - - - 1757 - Kleros - PNK - PNK - - - 1758 - RIF Token - RIF - RIF - - - 1759 - Rate3 - RTE - RTE - - - 1761 - Consensus - SEN - SEN - - - 1762 - Vetri - VLD - VLD - - - 1763 - WOLLO - WLO - WLO - - - 1765 - Xriba - XRA - XRA - - - 1766 - 0Chain - ZCN - ZCN - - - 1767 - Recovery Right Tokens - RRT - RRT - - - 1768 - Credits - CS - CS - - - 1769 - DADI - DADI - DADI - - - 1770 - Tether Euro - EURT - EURt - - - 1771 - Everipedia - IQ - IQ - - - 1772 - Medicalchain - MTN - MTN - - - 1773 - Autonio - ANIO - NIO - - - 1774 - Omni - OMNI - OMNI - - - 1775 - ORS Group - ORSG - ORS - - - 1778 - Blockpass - PASS - PASS - - - 1779 - RSK Smart Bitcoin - RBTC - RBTC - - - 1781 - SEER - SEER - SEER - - - 1782 - SpankChain - SPANK - SPANK - - - 1783 - Universa - UTNP - UTNP - - - 1785 - V Systems - VSYS - VSYS - - - 1786 - V Yggdrash - YEED - YEED - - - 1787 - Hydro Protocol - HOTP - HOT - - - 1789 - ContentBox - BOX - BOX - - - 1790 - Atonomi - ATMI - ATMI - - - 1791 - The Abyss - ABYSS - ABYSS - - - 1630 - Atlas Protocol - ATP - ATP - - - 1631 - 1BG - 1BG - 1BG - - - 1626 - Time Space Chain - TSC - TSC - - - 1627 - Berith - BRT - BRT - - - 1628 - BitMart Token - BMX - BMX - - - 1629 - Bitcoin HD - XHD - BHD - - - 1625 - WoChain - WOC - WOC - - - 1623 - Celer Network - CELR - CELR - - - 1622 - Ether Kingdoms Token - IMP - IMP - - - 1621 - Maecenas - ART - ART - - - 1619 - Veriblock - VBK - VBK - - - 1618 - PlayChip - PLA - PLA - - - 1617 - Orbs - ORBS - ORBS - - - 1614 - TTC Protocol - TTC - TTC - - - 1615 - Foresting - PTON - PTON - - - 1616 - PCHAIN - PI - PI - - - 1612 - Ankr - ANKR - ANKR - - - 1613 - Aergo - AERGO - AERGO - - - 1610 - Metadium - META - META - - - 1611 - GoldCoin - GLC - GLC - - - 1605 - PAL Network - PAL - PAL - - - 1606 - Solve.Care - SOLVE - SOLVE - - - 1607 - BTU Protocol - BTU - BTU - - - 1609 - Spendcoin - SPND - SPND - - - 1602 - Sphere - SPHR - SPHR - - - 1603 - Serve - SERV - SERV - - - 1597 - Circuits of Value - COVAL - COVAL - - - 1599 - Breakout Stake - BRX - BRX - - - 1601 - Bitswift - BITS - BITS - - - 1596 - Golos Gold - GBG - GBG - - - 1594 - EverGreenCoin - EGC - EGC - - - 1595 - Databits - DTB - DTB - - - 1587 - Qwark - QWARK - QWARK - - - 1588 - NeosCoin - NEOS - NEOS - - - 1589 - NuBits - NBT - NBT - - - 1591 - More Coin - MORE - MORE - - - 1592 - Hxro - HXRO - HXRO - - - 1593 - Gambit - GAM - GAM - - - 1584 - Stealth - XST - XST - - - 1585 - Tokes - TKS - TKS - - - 1582 - Gulden - CNLG - NLG - - - 1583 - BitSend - CBSD - BSD - - - 1581 - HunterCoin - HUC - HUC - - - 1580 - Livepeer - LPT - LPT - - - 1579 - BORA - BORA - BORA - - - 1577 - STACS - STACS - STACS - - - 1576 - HOT Token - HOTT - HOT - - - 1575 - DreamTeam - DREAM - DREAM - - - 1574 - TOP - TOPN - TOP - - - 1568 - Machine Xchange Coin - MXC - MXC - - - 1569 - COVA - COVA - COVA - - - 1570 - Lambda - LAMB - LAMB - - - 1571 - Content Value Network - CVNT - CVNT - - - 1572 - Ruff - RUFF - RUFF - - - 1573 - LinkEye - LET - LET - - - 1563 - Davinci Coin - DAC - DAC - - - 1564 - Tripio - TRIO - TRIO - - - 1565 - InvestDigital - IDT - IDT - - - 1567 - Huobi Pool Token - HPT - HPT - - - 1556 - ThingsOperatingSystem - TOS - TOS - - - 1557 - Globalvillage Ecosystem - GVE - GVE - - - 1559 - NeuroChain - NCC - NCC - - - 1560 - Kcash - KCASH - KCASH - - - 1561 - CVCoin - CVN - CVN - - - 1562 - BitCapitalVendor - BCV - BCV - - - 1551 - Yuan Chain Coin - YCC - YCC - - - 1552 - BitUP Token - BUT - BUT - - - 1553 - Smartshare - SSP - SSP - - - 1555 - MyToken - MT - MT - - - 1546 - DATx - DATX - DATX - - - 1547 - Themis - GET - GET - - - 1549 - GET Protocol - GETP - GET - - - 1550 - U Network - UUU - UUU - - - 1540 - XMax - XMX - XMX - - - 1541 - YouLive Coin - UC - UC - - - 1542 - Acute Angle Cloud - AAC - AAC - - - 1543 - Seele - SEELE - SEELE - - - 1544 - UnlimitedIP - UIP - UIP - - - 1545 - Litex - LXT - LXT - - - 1537 - FansTime - FTI - FTI - - - 1538 - Global Social Chain - GSC - GSC - - - 1539 - Promotion Coin - PC - PC - - - 1531 - EDUCare - EKT - EKT - - - 1534 - BeeKan - BKBT - BKBT - - - 1535 - FairGame - FAIR - FAIR - - - 1536 - Game.com - GTC - GTC - - - 1527 - Intelligent Investment Chain - IIC - IIC - - - 1529 - ShineChain - SHE - SHE - - - 1530 - MEX - MEX - MEX - - - 1522 - QunQun - QUN - QUN - - - 1523 - EduCoin - EDU - EDU - - - 1525 - BitcoinX - BCX - BCX - - - 1526 - HitChain - HIT - HIT - - - 1520 - SunContract - SNC - SNC - - - 1521 - STK - STK - STK - - - 1517 - YEE - YEE - YEE - - - 1518 - EchoLink - EKO - EKO - - - 1519 - DeepBrain Chain - DBC - DBC - - - 1513 - Zilla - ZLA - ZLA - - - 1514 - Arcblock - ABT - ABT - - - 1515 - Matryx - MTX - MTX - - - 1511 - BitKan - KAN - KAN - - - 1506 - TopChain - TOPC - TOPC - - - 1507 - CoinMeet - MEET - MEET - - - 1508 - SwftCoin - SWFTC - SWFTC - - - 1509 - MediShares - MDS - MDS - - - 1510 - IoT Chain - ITC - ITC - - - 1501 - Engine - EGCC - EGCC - - - 1502 - AI Doctor - AIDOC - AIDOC - - - 1503 - Super Bitcoin - SBTC - SBTC - - - 1505 - Bitcoin File - BIFI - BIFI - - - 1500 - IRIS Network - IRIS - IRIS - - - 1494 - Musk - MUSK - MUSK - - - 1495 - Portal - PORTAL - PORTAL - - - 1497 - RCCC - RCCC - RCCC - - - 1499 - Datum - DAT - DAT - - - 1492 - ZJLT Distributed Factoring Network - ZJLT - ZJLT - - - 1493 - Block 18 - 18C - 18C - - - 1491 - MARK.SPACE - MRK - MRK - - - 1490 - AdHive - ADH - ADH - - - 1479 - FLIP - FLP - FLP - - - 1489 - Dragon Coins - DRG - DRG - - - 1481 - FarmaTrust - FTT - FTT - - - 1482 - LikeCoin - LIKE - LIKE - - - 1483 - Morpheus Labs - MITX - MITX - - - 1485 - Stox - STX - STX - - - 1486 - ZPER - ZPR - ZPR - - - 1487 - FintruX Network - FTX - FTX - - - 1488 - Plus-Coin - NPLC - NPLC - - - 1477 - Huobi 10 Index - HB10 - HB10 - - - 1476 - Obsidian - ODN - ODN - - - 1472 - Pitch - PITCH - PITCH - - - 1473 - Purple Butterfly Trading - PBTT - PBTT - - - 1474 - Patron - PAT - PAT - - - 1475 - Opus - OPT - OPT - - - 1463 - ProCurrency - PROC - PROC - - - 1464 - Presearch - PRE - PRE - - - 1465 - Paymon - PMNT - PMNT - - - 1466 - Pluton - PLU - PLU - - - 1467 - Pillar - PLR - PLR - - - 1468 - Polybius - PLBT - PLBT - - - 1469 - Playkey - PKT - PKT - - - 1471 - Lampix - PIX - PIX - - - 1460 - Quanta Utility Token - QNTU - QNTU - - - 1461 - PlayGame - PXG - PXG - - - 1842 - imbrex - REX - REX - - - 1843 - BitRent - RNTB - RNTB - - - 1844 - Robotina - ROX - ROX - - - 1845 - Rivetz - RVT - RVT - - - 1846 - Sociall - SCL - SCL - - - 1847 - Sentinel - SENT - SENT - - - 1848 - ShipChain - SHIP - SHIP - - - 1849 - Signal Token - SIG - SIG - - - 1850 - SilkChain - SILK - SILK - - - 1851 - Slate - SLX - SLX - - - 1852 - SmartCash - SMART - SMART - - - 1853 - Snowball - SNBL - SNBL - - - 1854 - SPINDLE - SPD - SPD - - - 1855 - SportyCo - SPF - SPF - - - 1856 - Starbase - STAR - STAR - - - 1857 - Storiqa - STQ - STQ - - - 1859 - Sunchain - SUNC - SUNC - - - 1861 - Suretly - SUR - SUR - - - 1863 - savedroid - SVD - SVD - - - 1864 - Swarm - SWM - SWM - - - 1865 - TaaS - TAAS - TAAS - - - 1866 - Lamden - TAU - TAU - - - 1867 - TrueDeck - TDP - TDP - - - 1868 - TokenDesk - TDS - TDS - - - 1869 - Telcoin - TEL - TEL - - - 1870 - Chronobank - TIME - TIME - - - 1871 - Tradcoin - TRAD - TRAD - - - 1872 - WeTrust - TRST - TRST - - - 1873 - TrueChain - TRUE - TRUE - - - 1874 - Useless Ethereum Token - UET - UET - - - 1875 - Usechain Token - USE - USE - - - 1876 - United Traders Token - UTT - UTT - - - 1877 - VeriME - VME - VME - - - 1878 - Provoco Token - VOCO - VOCO - - - 1879 - Wiki Token - WIKI - WIKI - - - 1880 - CrowdWiz - WIZ - WIZ - - - 1881 - Xaurum - XAUR - XAUR - - - 1883 - BlitzPredict - XBP - XBP - - - 1884 - Monero Classic - XMC - XMC - - - 1885 - Exchange Union - XUC - XUC - - - 1887 - Zap - ZAP - ZAP - - - 1888 - Zeepin - ZPT - ZPT - - - 1889 - ZrCoin - ZRC - ZRC - - - 1890 - Zeusshield - ZSC - ZSC - - - 2000 - ATLANT Token - ATL - ATL - - - 2001 - BANCA - BANCA - BANCA - - - 2002 - Berry - BERRY - BERRY - - - 2003 - BetterBetting - BETR - BETR - - - 2004 - BitClave - CAT - CAT - - - 2005 - Bitcore - BTX - BTX - - - 2006 - BitDegree - BDG - BDG - - - 2007 - BitDice - CSNO - CSNO - - - 2008 - Black Moon - BMC - BMC - - - 2009 - BlockMesh - BMH - BMH - - - 2010 - Cashaa - CAS - CAS - - - 2011 - CoinPoker - CHP - CHP - - - 2012 - COPYTRACK - CPY - CPY - - - 2013 - Covesting - COV - COV - - - 2014 - Crypto20 - C20 - C20 - - - 2015 - Cryptopay - CPAY - CPAY - - - 2016 - CUBE - AUTO - AUTO - - - 2017 - Curriculum Vitae - CVH - CVH - - - 2018 - CyberVeinToken - CVT - CVT - - - 2019 - DAO Casino - BET - BET - - - 2020 - DecentBet - DBET - DBET - - - 2021 - DIMCOIN - DIM - DIM - - - 2022 - Etheroll - DICE - DICE - - - 2023 - First Blood - 1ST - 1ST - - - 2024 - Fortuna - FOTA - FOTA - - - 2025 - GoByte - GBX - GBX - - - 2026 - Happycoin - HPC - HPC - - - 2027 - Hive Project - HVN - HVN - - - 2028 - indaHash - IDH - IDH - - - 2029 - InsurChain - INSUR - INSUR - - - 2030 - InsurePal - IPL - IPL - - - 2031 - iXledger - IXT - IXT - - - 2032 - KickCoin - KICK - KICK - - - 2033 - KIN - KIN - KIN - - - 2034 - LAToken - LA - LA - - - 2035 - Life - LIFE - LIFE - - - 2036 - LockTrip - LOC - LOC - - - 2037 - MeshBox - MESH - MESH - - - 2038 - Micro Money - AMM - AMM - - - 2039 - Mybit - MYB - MYB - - - 2040 - Nectar - NCT - NCT - - - 2041 - Neumark - NEU - NEU - - - 2042 - NOAHCOIN - NOAH - NOAH - - - 2043 - SwissBorg - CHSB - CHSB - - - 2044 - Alphacat - ACAT - ACAT - - - 2045 - Freyr Chain - FREC - FREC - - - 2046 - Consentium - CSM - CSM - - - 2047 - Nanjcoin - NANJ - NANJ - - - 2048 - NeuroToken - NTK - NTK - - - 2049 - FuzeX - FXT - FXT - - - 2050 - Chainium - CHX - CHX - - - 2051 - FriendZ Coin - FDZ - FDZ - - - 2052 - Cryptaur - CPT - CPT - - - 2053 - HTMLCOIN - HTML - HTML - - - 2054 - Banker Token - BNK - BNK - - - 2055 - KaratBank Coin - KBC - KBC - - - 2056 - Ink - INK - INK - - - 2057 - Colu Local Network - CLN - CLN - - - 2058 - LitecoinCash - LCC - LCC - - - 2059 - ElectrifyAsia - ELEC - ELEC - - - 2060 - BitRewards - BIT - BIT - - - 2061 - CosmoCoin - COSM - COSM - - - 2062 - Kind Ads - KIND - KIND - - - 2063 - Inmediate - DIT - DIT - - - 2064 - CyClean - CCL - CCL - - - 2065 - Nimiq - NIM - NIM - - - 2066 - AML Bitcoin - ABTC - ABTC - - - 2067 - EcosBall - ABA - ABA - - - 2068 - Messe - MESSE - MESSE - - - 2069 - AXpire - AXPR - AXPR - - - 2070 - Constellation - DAG - DAG - - - 2071 - Acorn Collective Token - OAK - OAK - - - 2072 - Marginless - MRS - MRS - - - 2073 - Dynamic Trading Rights - DTR - DTR - - - 1892 - BOX Token - BOXT - BOX - - - 1893 - Bitcoinus - BITSS - BITS - - - 1895 - 1World - 1WO - 1WO - - - 1896 - AMLT - AMLT - AMLT - - - 1897 - Biotron - BTRN - BTRN - - - 1898 - CanYaCoin - CAN - CAN - - - 1899 - XAYA - CHI - CHI - - - 1900 - DACSEE - DACS - DACS - - - 1902 - Earth Token - EARTH - EARTH - - - 1903 - EZToken - EZT - EZT - - - 1904 - Flixxo - FLIXX - FLIXX - - - 1905 - DAOstack - GEN - GEN - - - 1906 - GazeCoin - GZE - GZE - - - 1907 - Invictus Hyperion Fund - IHF - IHF - - - 1908 - IP Exchange - IPSX - IPSX - - - 1909 - Kryll - KRL - KRL - - - 1910 - LALA World - LALA - LALA - - - 1911 - SalPay - SAL - SAL - - - 1912 - Signals Network - SGN - SGN - - - 1913 - SIX - SIX - SIX - - - 1914 - SnipCoin - SNIP - SNIP - - - 1915 - SophiaTX - SPHTX - SPHTX - - - 1916 - Thrive Token - THRT - THRT - - - 1917 - TokenPay - TPAY - TPAY - - - 1918 - Unibright - UBT - UBT - - - 1919 - Proxeus - XES - XES - - - 1920 - Zebi - ZCO - ZCO - - - 1921 - Bryllite - BRC - BRC - - - 1922 - FidentiaX - FDX - FDX - - - 1923 - Global Awards Token - GAT - GAT - - - 1924 - onG.social - ONGS - ONG - - - 1925 - StarterCoin - STAC - STAC - - - 1926 - Teleport - TPT - TPT - - - 1927 - TaTaTu - TTU - TTU - - - 1928 - WCoin - WIN - WIN - - - 1929 - bitJob - STU - STU - - - 1930 - Cosmos - ATOM - ATOM - - - 1931 - XND - XND - XND - - - 1932 - SCRL - SCRL - SCR - - - 1933 - UGAS - UGAS - UGAS - - - 1934 - Matic Network - MATIC - MATIC - - - 1935 - Wrapped Bitcoin - WBTC - WBTC - - - 1936 - CryptoFranc - XCHF - XCHF - - - 1937 - Function X - FX - FX - - - 1938 - Ocean - OCEAN - OCEAN - - - 1939 - XYO - XYO - XYO - - - 1940 - Wibson - WIB - WIB - - - 1941 - Blue Whale Token - BWX - BWX - - - 1942 - Newton Project - NEW - NEW - - - 1944 - ThunderCore - TT - TT - - - 1945 - OKB - OKB - OKB - - - 1954 - YOU COIN - YOU - YOU - - - 1965 - Asch - XAS - XAS - - - 1966 - Egretia - EGT - EGT - - - 1967 - High Performance Blockchain - HPB - HPB - - - 1982 - Measurable Data Token - MDT - MDT - - - 1983 - ugChain - UGC - UGC - - - 1987 - Delphy - DPY - DPY - - - 1988 - SelfSell - SSC - SSC - - - 1989 - Primas - PST - PST - - - 1991 - Zipper - ZIP - ZIP - - - 1992 - CIChain - CIC - CIC - - - 1993 - Chronologic - DAY - DAY - - - 1994 - Daneel - DAN - DAN - - - 1995 - DomRaider Token - DRT - DRT - - - 1996 - Indorse Token - IND - IND - - - 2074 - Helbiz Token - HBZ - HBZ - - - 2075 - Morpheus Network - MORPH - MORPH - - - 2076 - Synthetix - SNX - SNX - - - 2077 - Synthetix sUSD - SUSD - SUSD - - - 2078 - LEO Token - LEO - LEO - - - 2079 - Vodi X - VDX - VDX - - - 2080 - Reserve Rights Token - RSR - RSR - - - 1100 - Red Pulse Phoenix Binance - PHB - PHB - - - 1101 - Theta Fuel - TFUEL - TFUEL - - - 1102 - ZBToken - ZB - ZB - - - 1103 - Upfiring - UFR - UFR - - - 1129 - Cai Token - CAI - CAI - - - 1105 - WinToken - WINT - WINT - - - 1106 - Origin Sport - ORS - ORS - - - 1107 - HYCON - HYC - HYC - - - 1130 - Airbloc - ABL - ABL - - - 1109 - Blockcloud - BLOC - BLOC - - - 1110 - ACE (TokenStars) - ACE - ACE - - - 1111 - Molecular Future - MOF - MOF - - - 1112 - TokenClub - TCT - TCT - - - 1113 - StarChain - STC - STC - - - 1114 - LightChain - LIGHT - LIGHT - - - 1115 - OFCOIN - OF - OF - - - 1131 - Hi Mutual Society - HMC - HMC - - - 1117 - Beauty Chain - BEC - BEC - - - 1118 - Merculet - MVP - MVP - - - 1119 - SDChain - SDA - SDA - - - 1120 - ProChain - PRA - PRA - - - 1121 - OneRoot Network - RNT - RNT - - - 1122 - RealChain - RCT - RCT - - - 1123 - RefToken - REF - REF - - - 1133 - Ubique Chain Of Things - UCT - UCT - - - 1125 - United Bitcoin - UBTC - UBTC - - - 1126 - Show - SHOW - SHOW - - - 1127 - Olympus Labs - MOT - MOT - - - 1128 - IPChain - IPC - IPC - - - 1134 - Origo - OGO - OGO - - - 1135 - Harmony - ONE - ONE - - - 1137 - USDK - USDK - USDK - - - \ No newline at end of file +1301RippleXRPXRP1302Metaverse ETPETPETP1303Bitcoin CashBCHBCH1304OmiseGOOMGOMG1305NeoNEONEO1306IotaMIOTAIOT1307DigitalCashDASHDSH1308ZcashZECZEC1309MoneroXMRXMR1310Ethereum ClassicETCETC1311EOSEOSEOS1312AventusAVTAVT1313QtumQTUMQTM1314SantimentSANSAN1315EidooEDOEDO1316Bitcoin GoldBTGBTG1317StreamrDATADAT1318QASHQASHQSH1319YOYOWYOYOWYYW1321TetherUSDTTHR1322CardanoADAADA1323Binance CoinBNBBNB1325BreadBRDBRD1326GiftoGTOGTO1327IconomiICNICN1329IconICXICX1330LiskLSKLSK1331NanoNANONAN1333SaltSALTSLT1334StratisSTRATSTR1335TronTRXTRX1336WingsWINGSWNG1337Stellar LumensXLMXLM1338VergeXVGXVG1641LitecoinLTCLTC1741BitcoinBTCXBT1841EthereumETHETH8ALBANIALekALLLek12ALGERIAAlgerian DinarDZDDZD20ADPADPADP31AZERBAIJANAzerbaijanian ManatAZMман.32ARGENTINAArgentine PesoARS$36Australian DollarAUD$40ATSATSATS44BAHAMASBahamian DollarBSDBSD48BAHRAINBahraini DinarBHDد.ب.â€50BANGLADESHTakaBDTà§³51ARMENIAArmenian DramAMDÕ¤Ö€.52BARBADOSBarbados DollarBBDBBD56BEFBEFBEF60BERMUDABermudian Dollar (customarily known as Bermuda DolBMDBMD64BHUTANNgultrumBTNBTN68BOLIVIABolivianoBOB$b72BOTSWANAPulaBWPBWP84BELIZEBelize DollarBZDBZ$90SOLOMON ISLANDSSolomon Islands DollarSBDSBD96BRUNEI DARUSSALAMBrunei DollarBND$104MYANMARKyatMMKMMK108BURUNDIBurundi FrancBIFBIF116CAMBODIARielKHR៛124CANADACanadian DollarCAD$132CAPE VERDECape Verde EscudoCVECVE136CAYMAN ISLANDSCayman Islands DollarKYDKYD144SRI LANKASri Lanka RupeeLKRරු.152CHILEChilean PesoCLP$156CHINAYuan RenminbiCNYÂ¥170COLOMBIAColombian PesoCOP$174COMOROSComoro FrancKMFKMF188COSTA RICACosta Rican ColonCRCâ‚¡191CROATIACroatian KunaHRKkn192CUBACuban PesoCUPCUP196CYPRUSCyprus PoundCYPCYP203CZECH REPUBLICCzech KorunaCZK208Danish KroneDKKkr.214DOMINICAN REPUBLICDominican PesoDOPRD$222EL SALVADOREl Salvador ColonSVCSVC230ETHIOPIAEthiopian BirrETBETB232ERITREANakfaERNERN233ESTONIAKroonEEKkr238FALKLAND ISLANDS (MALVINAS)Falkland Islands PoundFKPFKP242FIJIFiji DollarFJDFJD246FIMFIMFIM250FRFFRFFRFFRF262DJIBOUTIDjibouti FrancDJFDJF270GAMBIADalasiGMDGMD276DEMDEMDEM288GHANACediGHCGHC292GIBRALTARGibraltar PoundGIPGIP300GRDGRDGRD320GUATEMALAQuetzalGTQQ324GUINEAGuinea FrancGNFGNF328GUYANAGuyana DollarGYDGYD332HAITIGourdeHTGHTG340HONDURASLempiraHNLL.344HONG KONGHong Kong DollarHKDHK$348HUNGARYForintHUFFt352ICELANDIceland KronaISKkr.356Indian RupeeINRRs.360INDONESIARupiahIDRRp364IRAN (ISLAMIC REPUBLIC OF)Iranian RialIRRريال368IRAQIraqi DinarIQDد.ع.â€372IEPIEPIEP376ISRAELNew Israeli SheqelILS₪380ITLITLITL388JAMAICAJamaican DollarJMDJ$392JAPANYenJPYÂ¥398KAZAKHSTANTengeKZTТ400JORDANJordanian DinarJODد.ا.â€404KENYAKenyan ShillingKESS408KOREA, DEMOCRATIC PEOPLE''S REPUBLIC OFNorth Korean WonKPWKPW410KOREA, DEMOCRATIC PEOPLE''S REPUBLIC OFWonKRWâ‚©414KUWAITKuwaiti DinarKWDد.Ùƒ.â€417KYRGYZSTANSomKGSÑом418LAO PEOPLE''S DEMOCRATIC REPUBLICKipLAKLAK422LEBANONLebanese PoundLBPÙ„.Ù„.â€426LESOTHOLotiLSLLSL428LATVIALatvian LatsLVLLs430LIBERIALiberian DollarLRDLRD434LIBYAN ARAB JAMAHIRIYALibyan DinarLYDد.Ù„.â€440LITHUANIALithuanian LitasLTLLt442LUFLUFLUF446MACAOPatacaMOPMOP454MALAWIKwachaMWKMWK458MALAYSIAMalaysian RinggitMYRRM462MALDIVESRufiyaaMVRÞƒ.470MALTAMaltese Lira^MTLLm478MAURITANIAOuguiyaMROMRO480MAURITIUSMauritius RupeeMURMUR484MEXICOMexican PesoMXN$496MONGOLIATugrikMNTâ‚®498MOLDOVA, REPUBLIC OFMoldovan LeuMDLMDL504Moroccan DirhamMADد.Ù….â€512OMANRial OmaniOMRر.ع.â€516NAMIBIANamibian DollarNADNAD524NEPALNepalese RupeeNPRरà¥528NLGNLGNLG532NETHERLANDS ANTILLESNetherlands Antillian GuikderANGANG533ARUBAAruban GuilderAWGAWG548VANUATUVatuVUVVUV554New Zealand DollarNZD$558NICARAGUACordoba OroNION566NIGERIANairaNGNNGN578Norwegian KroneNOKkr586PAKISTANPakistan RupeePKRRs590PANAMABalboaPABB/.598PAPUA NEW GUINEAKinaPGKPGK600PARAGUAYGuaraniPYGGs604PERUNuevo SolPENS/.608PHILIPPINESPhilippine PesoPHPPhP620PTEPTEPTE624GUINEA-BISSAUGuinea-Bissau PesoGWPGWP634QATARQatari RialQARر.Ù‚.â€642ROMANIAOld LeuROLlei643RUSSIAN FEDERATIONRussian RubleRUBRUB646RWANDARwanda FrancRWFRWF654SAINT HELENASaint Helena PoundSHPSHP678S?O TOME AND PRINCIPEDobraSTDSTD682SAUDI ARABIASaudi RiyalSARر.س.â€690SEYCHELLESSeychelles RupeeSCRSCR694SIERRA LEONELeoneSLLSLL702SINGAPORESingapore DollarSGD$703SLOVAKIASlovak KorunaSKKSk704VIET NAMDongVNDâ‚«705SLOVENIATolarSITSIT706SOMALIASomali ShillingSOSSOS710RandZARR716ZIMBABWEZimbabwe DollarZWDZ$724ESPESPESP736SUDANSudanese DinarSDDSDD748SWAZILANDLilangeniSZLSZL752SWEDENSwedish KronaSEKkr756Swiss FrancCHFfr.760SYRIAN ARAB REPUBLICSyrian PoundSYPÙ„.س.â€764THAILANDBahtTHB฿776TONGAPa''angaTOPTOP777CHINAYuan RenminbiCNHÂ¥780TRINNumericCodeAD AND TOBAGOTrinNumericCodead and Tobago DollarTTDTT$784UNITED ARAB EMIRATESUAE DirhamAEDد.Ø¥.â€788TUNISIATunisian DinarTNDد.ت.â€792TURKEYOld Turkish LiraTRL₤795TURKMENISTANManatTMMm.800UGANDAUganda ShillingUGXUGX807MACEDONIA, THE FORMER YUGOSLAV REPUBLIC OFDenarMKDден.818EGYPTEgyptian PoundEGPج.Ù….â€826UNITED KINGDOMPound SterlingGBP£834TANZANIA, UNITED REPUBLIC OFTanzanian ShillingTZSTZS840US DollarUSD$858URUGUAYPeso UruguayoUYU$U860UZBEKISTANUzbekistan SumUZSÑўм862VENEZUELABolivarVEBBs882SAMOATalaWSTWST886YEMENYemeni RialYERر.ÙŠ.â€891SERBIA AND MONTENEGROSerbian DinarCSDДин.894ZAMBIAKwachaZMKZMK901TAIWAN, PROVINCE OF CHINANew Taiwan DollarTWDNT$943MOZAMBIQUEMericalMZNMZN946ROMANIANew LeuRONRON947SWITZERLANDWIR EuroCHECHE948SWITZERLANDWIR FrancCHWCHW949TURKEYNew Turkish LiraTRYYTL950CFA Franc BEACXAFXAF951East Caribbean DollarXCDXCD952CFA Franc BCEAOXOFXOF953CFP FrancXPFXPF955Bond Markets Units European Composite Unit (EURCO)XBAXBA956European Monetary Unit (E.M.U.-6)XBBXBB957European Unit of Account 9(E.U.A.-9)XBCXBC958European Unit of Account 17(E.U.A.-17)XBDXBD959GoldXAUXAU960INTERNATIONAL MONETARY FUND (I.M.F)SDRXDRXDR961SilverXAGXAG962PlatinumXPTXPT963AlphabeticCodes specifically reserved for testingXTSXTS964PalladiumXPDXPD968SURINAMESurinam DollarSRDSRD969MADAGASCARMalagascy AriaryMGAMGA970COLOMBIAUnNumericCodead de Valor RealCOUCOU971AFGHANISTANAfghaniAFNAFN972TAJIKISTANSomoniTJSTJS973ANGOLAKwanzaAOAAOA974BELARUSBelarussian RubleBYRBYR975BULGARIABulgarian LevBGNBGN976CONGO, THE DEMOCRATIC REPUBLIC OFFranc CongolaisCDFCDF977BOSNIA & HERZEGOVINAConvertible MarksBAMKM978EuroEUR€979MEXICOMexican UnNumericCodead de Inversion (UNumericCodeMXVMXV980UKRAINEHryvniaUAHгрн.981GEORGIALariGELLari984BOLIVIAMvdolBOVBOV985POLANDZlotyPLNzÅ‚986BRAZILBrazilian RealBRLR$990CHILEUnNumericCodeades de formentoCLFCLF997UNITED STATES(Next day)USNUSN998UNITED STATES(Same day)USSUSS999XXXXXX1339ArkARKARK1341KomodoKMDKMD1342Power LedgerPOWRPWR1343AdExADXADX1345AeternityAEAE1346AionAIONAIO1347AmbrosusAMBAMB1349AppCoinsAPPCAPP1350AeronARNARN1351AirSwapASTAST1353Basic Attention TokenBATBAT1354Bitcoin DiamondBCDBCD1355BlockMason Credit ProtocolBCPTBCP1357BluzelleBLZBLZ1358BancorBNTBNT1359ETHOSETHOSBQX1361BitSharesBTSBTS1362BloxCDTCDT1363ChatCoinCHATCHT1365CyberMilesCMTCMT1366CindicatorCNDCND1367CentraCTRCTR1369DigixDAODGDDGD1370AgrelloDLTDLT1371district0xDNTDNT1373aelfELFELF1374EnigmaENGENG1375Enjin CoinENJENJ1377EverexEVXEVX1378EtherpartyFUELFUE1379FunFairFUNFUN1381GasGASGAS1382Genesis VisionGVTGVT1383GXChainGXSGXS1384HshareHSRHSR1385InsolarINSINS1386IOStokenIOSTIOS1387Kyber NetworkKNCKNC1389LendingblockLNDLND1390ChainLinkLINKLNK1391LoopringLRCLRC1393LunyrLUNLUN1394DecentralandMANAMAN1395Crypto.comMCOMCO1396Moeda Loyalty PointsMDAMDA1397ModumMODMOD1399MonethaMTHMTH1401MetalMTLMET1402NavCoinNAVNAV1403Nucleus VisionNCASHNCH1405NeblioNEBLNEB1406NulsNULSNUL1407OpenANXOAXOAX1409OntologyONTONT1411Simple TokenOSTOST1412PIVXPIVXPIV1413POA NetworkPOAPOA1415Po.etPOEPOE1416PopulousPPTPPT1419QLINKQLCQLC1420QuantstampQSPQSP1421Ripio Credit NetworkRCNRCN1423Raiden Network TokenRDNRDN1424Request NetworkREQREQ1425iExec RLCRLCRLC1427Red PulsePHXRPX1429SingularDTVSNGLSSNG1431SONMSNMSNM1432StatusSNTSNT1433SteemSTEEMSTM1435StorjSTORJSTJ1436StormSTORMSRM1437SubstratumSUBSUB1438SyscoinSYSSYS1439Time New BankTNBTNB1441TierionTNTTNT1443TriggersTRIGTRI1444VeChainVETVEN1445ViacoinVIAVIA1447ViberateVIBVIB1448VIBEVIBEVBE1449WaBiWABIWAB1450WanchainWANWAN1451WavesWAVESWVS1452WePowerWPRWPR1453WaltonchainWTCWTC1455NEMXEMXEM1456ZCoinXZCXZC1457ZilliqaZILZIL14590x ProtocolZRXZRX1000HyperCashHCHC1001GoChainGOGO1002Paxos Standard TokenPAXPAX1003RavencoinRVNRVN1004DecredDCRDCR1005MithrilMITHMITH1006USD CoinUSDCUSDC1007Bitcoin SVBSVBSV1008TezosXTZXTZ1009MakerMKRMKR1010DogecoinDOGEDOGE1011BytecoinBCNBCN1012TrueUSDTUSDTUSD1013DigiByteDGBDGB1014SiacoinSCSC1015BytomBTMBTM1016Pundi XNPXSNPXS1017AugurREPREP1018MaidSafeCoinMAIDMAID1019GolemGNTGNT1020ElectroneumETNETN1021HoloHOTHOT1022CryptonexCNXCNX1023FactomFCTFCT1024DaiDAIDAI1025KuCoin SharesKCSKCS1026Worldwide Asset ExchangeWAXWAX1027ArdorARDRARDR1028Huobi TokenHTHT1029MOACMOACMOAC1030RevainRR1031MonaCoinMONAMONA1032NexoNEXONEXO1033ODEMODEODE1034Insight ChainINBINB1035ReddCoinRDDRDD1036MixinXINXIN1037DentacoinDCNDCN1038HorizenZENZEN1039PolymathPOLYPOLY1040NasdacoinNSDNSD1041SIRIN LABS TokenSRNSRN1042Digitex FuturesDGTXDGTX1043DropilDROPDROP1044NxtNXTNXT1045MobileGoMGOMGO1046BOScoinBOSBOS1047TenXPAYPAY1048Theta TokenTHETATHETA1049NebulasNASNAS1050QuarkChainQKCQKC1051Loom NetworkLOOMLOOM1052VeritaseumVERIVERI1053ElastosELAELA1054WaykiChainWICCWICC1055ETERNAL TOKENXETXET1056DragonchainDRGNDRGN1057ProximaXXPXXPX1058Bitcoin PrivateBTCPBTCP1059Gemini DollarGUSDGUSD1060LinkeyLKYLKY1061BHPCashBHPCBHPC1062SmartlandsSLTSLT1063NectarNECNEC1064CivicCVCCVC1065OdysseyOCNOCN1066Endor ProtocolEDREDR1067Bibox TokenBIXBIX1068ARBITRAGEARBARB1069Optimal Shelf...OSAOSA1070DentDENTDENT1071GroestlcoinGRSGRS1072Byteball BytesGBYTEGBYTE1073RChainRHOCRHOC1074THEKEYTKYTKY1075CentralityCENNZCENNZ1076PeercoinPPCPPC1077EmercoinEMCEMC1078ETH LendLENDLEND1079Cloak CoinCLOAKCLOAK1080SKYSKYSKY1081IOTXIOTXIOTX1082SingularityNETAGIAGI1083NexusNXSNXS1084Key CoinKEYKEY1085MainframeMFTMFT1086DOCKDOCKDOCK1087Bit ConnectBCCBCC1088VENVENVEN1089Red PulseRPXRPX1090RENRENREN1091EthosBQXBQX1092BnkToTheFutureBFTBFT1093FSNFSNFSN1094MatrixMANMAN1095GnosisGNOGNO1096MelonMLNMLN1097NamecoinNMCNMC1098VertcoinVTCVTC1099BurstBURSTBURST1830Steem DollarsSTEEMDSBD1332BitTorrentBTTBTT1831ClamsCLAMCLAM1832FOAMFOAMFOAM1833GameCreditsGAMEGAME1835LBRY CreditsLBCLBC1836NumeraireNMRNMR1837Pascal CoinPASCPASC1838CounterpartyXCPXCP1839PrimecoinXPMXPM1829StableUSDUSDSUSDS1823STASIS EURSEURSEURS1824UTRUSTUTKUTK1825CortexCTXCCTXC1827Project PaiPAIPAI1828SmartMeshSMTSMT1794GrinGRINGRIN1796Unikoin GoldUKGUKG1797Genaro NetworkGNXGNX1798PentaPNTPNT1799Content Neutrality NetworkCNNCNN1801CredLBALBA1802BlocktixTIXTIX1803LympoLYMLYM1804All SportsSOCSOC1805Jibrel NetworkJNTJNT1806DATADTADTA1808AchainACTACT1809TokenCardTKNTKN1810PropyPROPRO1811DigitalNoteXDNXDN1812CrypteriumCRPTCRPT1813AragonANTANT1814BLOCKvVEEVEE1815BlocknetBLOCKBLOCK1816PumaPayPMAPMA1817IgnisIGNISIGNIS1819EdgelessEDGEDG1821Ontology GasONGONG1822Fetch.AIFETFET1793HUSD SolutionHUSDHUSD1632Ink ProtocolXNKXNK1633Crowd MachineCMCTCMCT1636NexiumNXCNXC1637SIBCoinSIBSIB1638Swarm CitySWTSWT1639PatientoryPTOYPTOY1640BANKEXBKXBKX1644MatchpoolGUPGUP1645HumaniqHMQHMQ1647HyperSpaceAMPAMP1648DECENTDCTDCT1649SpaceChainSPCSPC1650NAGANGCNGC1651NoLimitCoinNLC2NLC21652AeonAEONAEON1653OriginTrailTRACTRAC1655eBoostEBSTEBST1656CannabisCoinCANNCANN1657BreakoutBRKBRK1658SequenceSEQSEQ1659TransferCoinTXTX1660Memetic / PepeCoinMEMEMEME1661DopeCoinDOPEDOPE1662Internet of PeopleIOPIOP1663VeriumReserveVRMVRM1664PinkCoinPINKPINK1665SyndicateSYNXSYNX16662GIVE2GIVE2GIVE1667ExclusiveCoinEXCLEXCL1668DynamicDYNDYN1669ArtByteABYABY1670FoldingCoinFLDCFLDC1671KoreKOREKORE1672GeoCoinGEOGEO1673ExpanseEXPEXP1674OKCashOKOK1675MusicoinMUSICMUSIC1676GolosGOLOSGOLOS1677Blockparty (BOXX Token)BOXXBOXX1679CurecoinCURECURE1680SolarCoinSLRSLR1681BloomBLTBLT1683Decision TokenHSTHST1684Haven ProtocolXHVXHV1685GridCoinGRCGRC1686MonetaryUnitMUEMUE1687MyriadXMYXMY1688DiamondDMDDMD1689I/O CoinIOCIOC1691Bean CashBITBBITB1692CrownCRWCRW1693RadiumRADSRADS1695VeriCoinVRCVRC1696IncentINCNTINCNT1697RevolutionVRRVRRVR1698XELXELXEL1699UpTokenUPUP1700IONIONION1701BitTubeTUBETUBE1707HempCoinTHCTHC1708FeathercoinFTCFTC1709ShiftSHIFTSHIFT1711adTokenADTADT1712PotCoinPOTPOT1713BlackCoinBLKBLK1714Sentinel ProtocolUPPUPP1715MercuryMERMER1717MobiusMOBIMOBI1718ZClassicZCLZCL1719CashBet CoinCBCCBC1720MetronomeMETMET1721VITEVITEVITE1722HydroHYDROHYDRO1723BitBayBAYBAY1725IHT Real Estate ProtocolIHTIHT1726RefereumRFRRFR1727UbiqUBQUBQ1728FLOFLOFLO1729WhiteCoinXWCXWC1730Moss CoinMOCMOC1731NKNNKNNKN1732QuantQNTQNT1733Crypto.com ChainCROCRO1734ParticlPARTPART1735Quantum Resistant LedgerQRLQRL1737DMarketDMTDMT1738SaluSSLSSLS1739MediBloc [ERC20]MEDXMEDX1740EinsteiniumEMC2EMC21742AidCoinAIDAID1743AuctusAUCAUC1744Banyan NetworkBBNBBN1745Bitcoin InterestBCIBCI1746CommerceBlockCBTCBT1747Callisto NetworkCLOCLO1749Digix Gold TokenDGXDGX1750DetherDTHDTH1751EssentiaESSESS1753ParkinGoGOTGOT1754Internet Node TokenINTINT1755On.LiveONLONL1757KlerosPNKPNK1758RIF TokenRIFRIF1759Rate3RTERTE1761ConsensusSENSEN1762VetriVLDVLD1763WOLLOWLOWLO1765XribaXRAXRA17660ChainZCNZCN1767Recovery Right TokensRRTRRT1768CreditsCSCS1769DADIDADIDADI1770Tether EuroEURTEURt1771EveripediaIQIQ1772MedicalchainMTNMTN1773AutonioANIONIO1774OmniOMNIOMNI1775ORS GroupORSGORS1778BlockpassPASSPASS1779RSK Smart BitcoinRBTCRBTC1781SEERSEERSEER1782SpankChainSPANKSPANK1783UniversaUTNPUTNP1785V SystemsVSYSVSYS1786V YggdrashYEEDYEED1787Hydro ProtocolHOTPHOT1789ContentBoxBOXBOX1790AtonomiATMIATMI1791The AbyssABYSSABYSS1630Atlas ProtocolATPATP16311BG1BG1BG1626Time Space ChainTSCTSC1627BerithBRTBRT1628BitMart TokenBMXBMX1629Bitcoin HDXHDBHD1625WoChainWOCWOC1623Celer NetworkCELRCELR1622Ether Kingdoms TokenIMPIMP1621MaecenasARTART1619VeriblockVBKVBK1618PlayChipPLAPLA1617OrbsORBSORBS1614TTC ProtocolTTCTTC1615ForestingPTONPTON1616PCHAINPIPI1612AnkrANKRANKR1613AergoAERGOAERGO1610MetadiumMETAMETA1611GoldCoinGLCGLC1605PAL NetworkPALPAL1606Solve.CareSOLVESOLVE1607BTU ProtocolBTUBTU1609SpendcoinSPNDSPND1602SphereSPHRSPHR1603ServeSERVSERV1597Circuits of ValueCOVALCOVAL1599Breakout StakeBRXBRX1601BitswiftBITSBITS1596Golos GoldGBGGBG1594EverGreenCoinEGCEGC1595DatabitsDTBDTB1587QwarkQWARKQWARK1588NeosCoinNEOSNEOS1589NuBitsNBTNBT1591More CoinMOREMORE1592HxroHXROHXRO1593GambitGAMGAM1584StealthXSTXST1585TokesTKSTKS1582GuldenCNLGNLG1583BitSendCBSDBSD1581HunterCoinHUCHUC1580LivepeerLPTLPT1579BORABORABORA1577STACSSTACSSTACS1576HOT TokenHOTTHOT1575DreamTeamDREAMDREAM1574TOPTOPNTOP1568Machine Xchange CoinMXCMXC1569COVACOVACOVA1570LambdaLAMBLAMB1571Content Value NetworkCVNTCVNT1572RuffRUFFRUFF1573LinkEyeLETLET1563Davinci CoinDACDAC1564TripioTRIOTRIO1565InvestDigitalIDTIDT1567Huobi Pool TokenHPTHPT1556ThingsOperatingSystemTOSTOS1557Globalvillage EcosystemGVEGVE1559NeuroChainNCCNCC1560KcashKCASHKCASH1561CVCoinCVNCVN1562BitCapitalVendorBCVBCV1551Yuan Chain CoinYCCYCC1552BitUP TokenBUTBUT1553SmartshareSSPSSP1555MyTokenMTMT1546DATxDATXDATX1547ThemisGETGET1549GET ProtocolGETPGET1550U NetworkUUUUUU1540XMaxXMXXMX1541YouLive CoinUCUC1542Acute Angle CloudAACAAC1543SeeleSEELESEELE1544UnlimitedIPUIPUIP1545LitexLXTLXT1537FansTimeFTIFTI1538Global Social ChainGSCGSC1539Promotion CoinPCPC1531EDUCareEKTEKT1534BeeKanBKBTBKBT1535FairGameFAIRFAIR1536Game.comGTCGTC1527Intelligent Investment ChainIICIIC1529ShineChainSHESHE1530MEXMEXMEX1522QunQunQUNQUN1523EduCoinEDUEDU1525BitcoinXBCXBCX1526HitChainHITHIT1520SunContractSNCSNC1521STKSTKSTK1517YEEYEEYEE1518EchoLinkEKOEKO1519DeepBrain ChainDBCDBC1513ZillaZLAZLA1514ArcblockABTABT1515MatryxMTXMTX1511BitKanKANKAN1506TopChainTOPCTOPC1507CoinMeetMEETMEET1508SwftCoinSWFTCSWFTC1509MediSharesMDSMDS1510IoT ChainITCITC1501EngineEGCCEGCC1502AI DoctorAIDOCAIDOC1503Super BitcoinSBTCSBTC1505Bitcoin FileBIFIBIFI1500IRIS NetworkIRISIRIS1494MuskMUSKMUSK1495PortalPORTALPORTAL1497RCCCRCCCRCCC1499DatumDATDAT1492ZJLT Distributed Factoring NetworkZJLTZJLT1493Block 1818C18C1491MARK.SPACEMRKMRK1490AdHiveADHADH1479FLIPFLPFLP1489Dragon CoinsDRGDRG1481FarmaTrustFTTFTT1482LikeCoinLIKELIKE1483Morpheus LabsMITXMITX1485StoxSTXSTX1486ZPERZPRZPR1487FintruX NetworkFTXFTX1488Plus-CoinNPLCNPLC1477Huobi 10 IndexHB10HB101476ObsidianODNODN1472PitchPITCHPITCH1473Purple Butterfly TradingPBTTPBTT1474PatronPATPAT1475OpusOPTOPT1463ProCurrencyPROCPROC1464PresearchPREPRE1465PaymonPMNTPMNT1466PlutonPLUPLU1467PillarPLRPLR1468PolybiusPLBTPLBT1469PlaykeyPKTPKT1471LampixPIXPIX1460Quanta Utility TokenQNTUQNTU1461PlayGamePXGPXG1842imbrexREXREX1843BitRentRNTBRNTB1844RobotinaROXROX1845RivetzRVTRVT1846SociallSCLSCL1847SentinelSENTSENT1848ShipChainSHIPSHIP1849Signal TokenSIGSIG1850SilkChainSILKSILK1851SlateSLXSLX1852SmartCashSMARTSMART1853SnowballSNBLSNBL1854SPINDLESPDSPD1855SportyCoSPFSPF1856StarbaseSTARSTAR1857StoriqaSTQSTQ1859SunchainSUNCSUNC1861SuretlySURSUR1863savedroidSVDSVD1864SwarmSWMSWM1865TaaSTAASTAAS1866LamdenTAUTAU1867TrueDeckTDPTDP1868TokenDeskTDSTDS1869TelcoinTELTEL1870ChronobankTIMETIME1871TradcoinTRADTRAD1872WeTrustTRSTTRST1873TrueChainTRUETRUE1874Useless Ethereum TokenUETUET1875Usechain TokenUSEUSE1876United Traders TokenUTTUTT1877VeriMEVMEVME1878Provoco TokenVOCOVOCO1879Wiki TokenWIKIWIKI1880CrowdWizWIZWIZ1881XaurumXAURXAUR1883BlitzPredictXBPXBP1884Monero ClassicXMCXMC1885Exchange UnionXUCXUC1887ZapZAPZAP1888ZeepinZPTZPT1889ZrCoinZRCZRC1890ZeusshieldZSCZSC2000ATLANT TokenATLATL2001BANCABANCABANCA2002BerryBERRYBERRY2003BetterBettingBETRBETR2004BitClaveCATCAT2005BitcoreBTXBTX2006BitDegreeBDGBDG2007BitDiceCSNOCSNO2008Black MoonBMCBMC2009BlockMeshBMHBMH2010CashaaCASCAS2011CoinPokerCHPCHP2012COPYTRACKCPYCPY2013CovestingCOVCOV2014Crypto20C20C202015CryptopayCPAYCPAY2016CUBEAUTOAUTO2017Curriculum VitaeCVHCVH2018CyberVeinTokenCVTCVT2019DAO CasinoBETBET2020DecentBetDBETDBET2021DIMCOINDIMDIM2022EtherollDICEDICE2023First Blood1ST1ST2024FortunaFOTAFOTA2025GoByteGBXGBX2026HappycoinHPCHPC2027Hive ProjectHVNHVN2028indaHashIDHIDH2029InsurChainINSURINSUR2030InsurePalIPLIPL2031iXledgerIXTIXT2032KickCoinKICKKICK2033KINKINKIN2034LATokenLALA2035LifeLIFELIFE2036LockTripLOCLOC2037MeshBoxMESHMESH2038Micro MoneyAMMAMM2039MybitMYBMYB2040NectarNCTNCT2041NeumarkNEUNEU2042NOAHCOINNOAHNOAH2043SwissBorgCHSBCHSB2044AlphacatACATACAT2045Freyr ChainFRECFREC2046ConsentiumCSMCSM2047NanjcoinNANJNANJ2048NeuroTokenNTKNTK2049FuzeXFXTFXT2050ChainiumCHXCHX2051FriendZ CoinFDZFDZ2052CryptaurCPTCPT2053HTMLCOINHTMLHTML2054Banker TokenBNKBNK2055KaratBank CoinKBCKBC2056InkINKINK2057Colu Local NetworkCLNCLN2058LitecoinCashLCCLCC2059ElectrifyAsiaELECELEC2060BitRewardsBITBIT2061CosmoCoinCOSMCOSM2062Kind AdsKINDKIND2063InmediateDITDIT2064CyCleanCCLCCL2065NimiqNIMNIM2066AML BitcoinABTCABTC2067EcosBallABAABA2068MesseMESSEMESSE2069AXpireAXPRAXPR2070ConstellationDAGDAG2071Acorn Collective TokenOAKOAK2072MarginlessMRSMRS2073Dynamic Trading RightsDTRDTR1892BOX TokenBOXTBOX1893BitcoinusBITSSBITS18951World1WO1WO1896AMLTAMLTAMLT1897BiotronBTRNBTRN1898CanYaCoinCANCAN1899XAYACHICHI1900DACSEEDACSDACS1902Earth TokenEARTHEARTH1903EZTokenEZTEZT1904FlixxoFLIXXFLIXX1905DAOstackGENGEN1906GazeCoinGZEGZE1907Invictus Hyperion FundIHFIHF1908IP ExchangeIPSXIPSX1909KryllKRLKRL1910LALA WorldLALALALA1911SalPaySALSAL1912Signals NetworkSGNSGN1913SIXSIXSIX1914SnipCoinSNIPSNIP1915SophiaTXSPHTXSPHTX1916Thrive TokenTHRTTHRT1917TokenPayTPAYTPAY1918UnibrightUBTUBT1919ProxeusXESXES1920ZebiZCOZCO1921BrylliteBRCBRC1922FidentiaXFDXFDX1923Global Awards TokenGATGAT1924onG.socialONGSONG1925StarterCoinSTACSTAC1926TeleportTPTTPT1927TaTaTuTTUTTU1928WCoinWINWIN1929bitJobSTUSTU1930CosmosATOMATOM1931XNDXNDXND1932SCRLSCRLSCR1933UGASUGASUGAS1934Matic NetworkMATICMATIC1935Wrapped BitcoinWBTCWBTC1936CryptoFrancXCHFXCHF1937Function XFXFX1938OceanOCEANOCEAN1939XYOXYOXYO1940WibsonWIBWIB1941Blue Whale TokenBWXBWX1942Newton ProjectNEWNEW1944ThunderCoreTTTT1945OKBOKBOKB1954YOU COINYOUYOU1965AschXASXAS1966EgretiaEGTEGT1967High Performance BlockchainHPBHPB1982Measurable Data TokenMDTMDT1983ugChainUGCUGC1987DelphyDPYDPY1988SelfSellSSCSSC1989PrimasPSTPST1991ZipperZIPZIP1992CIChainCICCIC1993ChronologicDAYDAY1994DaneelDANDAN1995DomRaider TokenDRTDRT1996Indorse TokenINDIND2074Helbiz TokenHBZHBZ2075Morpheus NetworkMORPHMORPH2076SynthetixSNXSNX2077Synthetix sUSDSUSDSUSD2078LEO TokenLEOLEO2079Vodi XVDXVDX2080Reserve Rights TokenRSRRSR1100Red Pulse Phoenix BinancePHBPHB1101Theta FuelTFUELTFUEL1102ZBTokenZBZB1103UpfiringUFRUFR1129Cai TokenCAICAI1105WinTokenWINTWINT1106Origin SportORSORS1107HYCONHYCHYC1130AirblocABLABL1109BlockcloudBLOCBLOC1110ACE (TokenStars)ACEACE1111Molecular FutureMOFMOF1112TokenClubTCTTCT1113StarChainSTCSTC1114LightChainLIGHTLIGHT1115OFCOINOFOF1131Hi Mutual SocietyHMCHMC1117Beauty ChainBECBEC1118MerculetMVPMVP1119SDChainSDASDA1120ProChainPRAPRA1121OneRoot NetworkRNTRNT1122RealChainRCTRCT1123RefTokenREFREF1133Ubique Chain Of ThingsUCTUCT1125United BitcoinUBTCUBTC1126ShowSHOWSHOW1127Olympus LabsMOTMOT1128IPChainIPCIPC1134OrigoOGOOGO1135HarmonyONEONE1137USDKUSDKUSDK2081BeaxyBXYBXY2082FantomFTMFTM2083AlgorandALGOALGO2084V-IDVIDTVIDT2085VideoCoinVIDVID2086EnergiNRGNRG2087Dusk NetworkDUSKDUSK2088WINkWINKWINK2089WirexWXTWXT2090Bitcoin BEP2BTCBBTCB2091StableUSD BEP2USDSBUSDSB2092ElrondERDERD2093Binance GBP Stable CoinBGBPBGBP2094ContentosCOSCOS2095TrueUSD BEP2TUSDBTUSDB2096Cocos-BCXCOCOSCOCOS2097TomoChainTOMOTOMO2098PerlinPERLPERL2099ChilizCHZCHZ2100AmpleforthAMPLAMPL2101GateChainTokenGTGT2102UltraUOSUOS2103rrbRRBRRB2104Dragon TokenDTDT2105BeamBEAMBEAM2106Tether CNHCNHTCNHT2107AlliveALVALV2108VNT ChainVNTVNT2109En-Tan-MoETMETM2110EminerEMEM2111EchoinECEC2112PledgecampPLGPLG2113X-Power ChainXPOXPO2114FTX TokenFTTXFTTX2115AkropolisAKROAKRO2116Skrumble NetworkSKMSKM2117PivotPVTPVT2118Crypto Neo-value Neural SystemCNNSCNNS2119BHEX TokenBHTBHT2120CarryCRECRE2121ARPA ChainARPAARPA2122VidyCoinVIDYVIDY2123Force ProtocolFORFOR2124RedFOX LabsRFOXRFOX2125CelsiusCELCEL2126AnchorANCTANCT2127Standard Tokenization ProtocolSTPTSTPT2128Contents ProtocolCPTLCPTL2129PrometeusPROMPROM2130FlexacoinFXCFXC2131SPIN ProtocolSPINSPIN2132ChromiaCHRCHR2133PixelPXLPXL2134HedgeTradeHEDGHEDG2135Morpheus.NetworkMRPHMRPH2136Hedera HashgraphHBARHBAR2137Band ProtocolBANDBAND2138Bitpanda Ecosystem TokenBESTBEST2139PantosPANPAN2140Binance USDBUSDBUSD \ No newline at end of file From 822570f0237f00de1294dc1ceff2268d8d142f7a Mon Sep 17 00:00:00 2001 From: Robot Date: Tue, 15 Oct 2019 08:33:58 +0000 Subject: [PATCH 2170/2572] [Skip CI] Generate release version --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 6e6c482a..21f7321c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ -#Tue Aug 06 17:19:39 MSK 2019 +#Tue Oct 15 08:33:58 UTC 2019 dfpVersion=0.10.7 -version=5.2.56-SNAPSHOT +version=5.2.56 deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java hdTimeVersion=0.2.4 From f90d36e0e08414e96a3f1b15b23f3ecfac71c22d Mon Sep 17 00:00:00 2001 From: Robot Date: Tue, 15 Oct 2019 08:34:05 +0000 Subject: [PATCH 2171/2572] [Skip CI] Generate next development version --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 21f7321c..8dfd896f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ -#Tue Oct 15 08:33:58 UTC 2019 +#Tue Oct 15 08:34:05 UTC 2019 dfpVersion=0.10.7 -version=5.2.56 +version=5.2.57-SNAPSHOT deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java hdTimeVersion=0.2.4 From 66d85d8690e5a184d74dd7d490973ae3bd0e7cae Mon Sep 17 00:00:00 2001 From: Alex Karpovich Date: Wed, 30 Oct 2019 13:44:02 +0300 Subject: [PATCH 2172/2572] [*] JAVA 11 --- .gitlab-ci.yml | 2 +- build.gradle | 9 +++++++-- gradle.properties | 4 ++-- gradle/wrapper/gradle-wrapper.jar | Bin 56177 -> 55616 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 18 +++++++++++++++++- gradlew.bat | 18 +++++++++++++++++- gui/build.gradle | 11 ----------- .../deltix/util/swing/StandardAction.java | 2 +- .../deltix/util/swing/tree/BaseTreeNode.java | 2 +- .../util/swing/treeedit/TreeEditorPanel.java | 2 +- lang/build.gradle | 8 ++++---- util/build.gradle | 13 ++++++++----- .../deltix/util/cmdline/AbstractShell.java | 5 +++++ .../util/io/ByteCountingOutputStream.java | 15 ++++++++------- .../deltix/util/lang/MemoryPreferences.java | 3 ++- .../deltix/util/net/SSLContextProvider.java | 5 ++++- .../main/java/deltix/util/os/WindowsOS.java | 1 - .../text/table/AlignedNoWhitespacesTable.java | 2 +- .../java/deltix/util/time/TimeDomain.java | 3 --- .../deltix/util/currency/CurrencyCodes.xml | 2 +- 21 files changed, 81 insertions(+), 46 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f9203c45..356bd323 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -39,7 +39,7 @@ cache: "Build: Java 8": stage: build - image: packages.deltixhub.com:443/gitlabci.docker/oracle-jdk-8-gradle-4.10.1:latest + image: packages.deltixhub.com:443/gitlabci.docker/openjdk-jdk-11-gradle-5.2.1:latest script: - git checkout origin/pipeline-$CI_PIPELINE_ID~1 || true - ./gradlew build test --no-daemon diff --git a/build.gradle b/build.gradle index f232de65..47ab4c88 100644 --- a/build.gradle +++ b/build.gradle @@ -35,8 +35,13 @@ configure(leafProjects) { apply plugin: 'io.spring.dependency-management' compileJava.options.encoding = 'UTF-8' - sourceCompatibility = 1.8 - targetCompatibility = 1.8 + compileJava.options.compilerArgs += '--add-exports=java.base/sun.nio.ch=ALL-UNNAMED' + compileJava.options.compilerArgs += '--add-exports=java.base/sun.nio=ALL-UNNAMED' + + //--add-exports //=(,)* + + sourceCompatibility = 11 + targetCompatibility = 11 // Defines versions of dependencies to be used by subprojects // https://github.com/spring-gradle-plugins/dependency-management-plugin#dependency-management-dsl diff --git a/gradle.properties b/gradle.properties index 8dfd896f..ec1d0a46 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ #Tue Oct 15 08:34:05 UTC 2019 dfpVersion=0.10.7 -version=5.2.57-SNAPSHOT +version=5.4.1-SNAPSHOT deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java -hdTimeVersion=0.2.4 +hdTimeVersion=0.2.4 \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 13536770052936a92b204cc34e72284a03a6903c..5c2d1cf016b3885f6930543d57b744ea8c220a1a 100644 GIT binary patch delta 47360 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 delta 47987 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 PKYfr|!6OI@2KN5|iDBJb diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 5c1b6c95..44e7c4d1 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-5.2.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index cccdd3d5..b0d6d0ab 100755 --- a/gradlew +++ b/gradlew @@ -1,5 +1,21 @@ #!/usr/bin/env sh +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + ############################################################################## ## ## Gradle start up script for UN*X @@ -28,7 +44,7 @@ APP_NAME="Gradle" APP_BASE_NAME=`basename "$0"` # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" diff --git a/gradlew.bat b/gradlew.bat index f9553162..9991c503 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,3 +1,19 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem http://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + @if "%DEBUG%" == "" @echo off @rem ########################################################################## @rem @@ -14,7 +30,7 @@ set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome diff --git a/gui/build.gradle b/gui/build.gradle index 6179c06d..60e321e7 100644 --- a/gui/build.gradle +++ b/gui/build.gradle @@ -13,21 +13,10 @@ dependencies { exclude module: 'commons-logging' } -// compile files('../../../lib/jgoodies/binding.jar'), -// files('../../../lib/jgoodies/forms.jar'), //have dependency to jgoodies-common.jar -// files('../../../lib/jgoodies/jgoodies-common.jar'), -// files('../../../lib/jgoodies/looks.jar'), //unused(?) -// files('../../../lib/jgoodies/validation.jar'), -// files('../../../lib/swingx/filters.jar'), //unused(?) //dependency at swingx.jar -// files('../../../lib/swingx/jxlayer.jar'), //unused(?) -// files('../../../lib/swingx/swingx.jar') - compile('org.swinglabs:swingx:1.6') // have filters.jar v:2.0.235 in dependencies compile('com.jgoodies:jgoodies-forms:1.6.0') // have jgoodies-common.jar v:1.4.0 in dependencies compile('com.jgoodies:jgoodies-looks:2.5.2') compile('com.jgoodies:jgoodies-binding:2.7.0'){ transitive = false } compile('com.jgoodies:jgoodies-validation:2.4.2'){ transitive = false } compile('org.swinglabs:jxlayer:3.0.4'){ transitive = false } - - } diff --git a/gui/src/main/java/deltix/util/swing/StandardAction.java b/gui/src/main/java/deltix/util/swing/StandardAction.java index a7160473..338718b9 100644 --- a/gui/src/main/java/deltix/util/swing/StandardAction.java +++ b/gui/src/main/java/deltix/util/swing/StandardAction.java @@ -51,7 +51,7 @@ public StandardAction (Class forClass, String nameKey) { setUpAction (this, forClass, nameKey); } - public static final String [] IMAGE_EXTENSIONS = { "gif", "jpg", "png" }; + static final String [] IMAGE_EXTENSIONS = { "gif", "jpg", "png" }; private final String key; diff --git a/gui/src/main/java/deltix/util/swing/tree/BaseTreeNode.java b/gui/src/main/java/deltix/util/swing/tree/BaseTreeNode.java index a499b8e0..f467f1c8 100644 --- a/gui/src/main/java/deltix/util/swing/tree/BaseTreeNode.java +++ b/gui/src/main/java/deltix/util/swing/tree/BaseTreeNode.java @@ -168,7 +168,7 @@ public int getIndex(TreeNode treeNode) { @Override @SuppressWarnings("unchecked") - public Enumeration children() { + public Enumeration children() { updateChildren(); return (new ArrayEnumeration(mChildNodes.toArray())); } diff --git a/gui/src/main/java/deltix/util/swing/treeedit/TreeEditorPanel.java b/gui/src/main/java/deltix/util/swing/treeedit/TreeEditorPanel.java index e1908601..2d451275 100644 --- a/gui/src/main/java/deltix/util/swing/treeedit/TreeEditorPanel.java +++ b/gui/src/main/java/deltix/util/swing/treeedit/TreeEditorPanel.java @@ -338,7 +338,7 @@ protected void fireEditingChanged (boolean edit) { //////////////////HELPER CLASSES/////////////////////////// - protected class TreeEditorTransferHandler extends TransferHandler { + protected static class TreeEditorTransferHandler extends TransferHandler { public boolean canImport(JComponent comp, DataFlavor[] transferFlavors) { return false; diff --git a/lang/build.gradle b/lang/build.gradle index 0ca85f82..50ac100d 100644 --- a/lang/build.gradle +++ b/lang/build.gradle @@ -1,5 +1,5 @@ plugins { - id "me.champeau.gradle.jmh" version "0.3.1" + id 'me.champeau.gradle.jmh' version '0.4.5' apply false } description = 'QuantServer commons-lang set of utilities' @@ -10,6 +10,6 @@ dependencies { compile 'deltix:deltix-gflog-api' } -jmh { - jmhVersion = '1.19' -} \ No newline at end of file +//jmh { +// jmhVersion = '1.19' +//} \ No newline at end of file diff --git a/util/build.gradle b/util/build.gradle index d6a4ea8c..58aa2a9d 100644 --- a/util/build.gradle +++ b/util/build.gradle @@ -12,21 +12,24 @@ dependencies { compile 'commons-lang:commons-lang' compile 'org.apache.commons:commons-compress:1.7' - //compile 'javax.servlet:javax.servlet-api:3.1.0' compileOnly 'com.google.code.findbugs:jsr305' + compile 'javax.xml.bind:jaxb-api:2.2.8' + compile 'com.sun.xml.bind:jaxb-impl:2.3.0' + compile 'com.sun.xml.bind:jaxb-core:2.3.0' + // compile('com.sun.xml.bind:jaxb-xjc:2.2.11') // 2.2.11 has only bug fixes compared 2.2.8-b130911.1802 (which used by Java 8) - compile 'org.glassfish.jaxb:jaxb-runtime:2.2.11' // Glassfish replaces JAXB RI + //compile 'org.glassfish.jaxb:jaxb-runtime:2.2.11' // Glassfish replaces JAXB RI //compile('javax.xml:jsr173:1.0'){ transitive = false } -// compile('net.java.dev.jna:jna:4.2.1'){ transitive = false } -// compile('net.java.dev.jna:jna-platform:4.2.1'){ transitive = false } + compile('net.java.dev.jna:jna:5.4.0'){ transitive = false } + compile('net.java.dev.jna:jna-platform:5.4.0'){ transitive = false } compile('org.apache.bcel:bcel:6.0'){ transitive = false } } task downloadCodes(type: Download) { - src 'http://sm.deltixuat.com:5552/api/v1/currencyinfo/xml' + src 'https://smi.deltixhub.com/api/v1/currencyinfo/xml' dest new File(projectDir, 'src/main/resources/deltix/util/currency/CurrencyCodes.xml') } diff --git a/util/src/main/java/deltix/util/cmdline/AbstractShell.java b/util/src/main/java/deltix/util/cmdline/AbstractShell.java index 2776581d..a8908150 100644 --- a/util/src/main/java/deltix/util/cmdline/AbstractShell.java +++ b/util/src/main/java/deltix/util/cmdline/AbstractShell.java @@ -68,6 +68,11 @@ protected boolean doCommand (String key, String args) throws Exception { return (true); } + if (key.equalsIgnoreCase ("quit")) { + System.exit(errorCode); + return (true); + } + if (key.equalsIgnoreCase ("set")) { if (args == null) doSet (); diff --git a/util/src/main/java/deltix/util/io/ByteCountingOutputStream.java b/util/src/main/java/deltix/util/io/ByteCountingOutputStream.java index 1d1e395f..de65da23 100644 --- a/util/src/main/java/deltix/util/io/ByteCountingOutputStream.java +++ b/util/src/main/java/deltix/util/io/ByteCountingOutputStream.java @@ -1,41 +1,42 @@ package deltix.util.io; import java.io.*; +import java.util.concurrent.atomic.AtomicLong; /** * Counts bytes that pass through. */ public class ByteCountingOutputStream extends FilterOutputStream { - private volatile long mNumBytesWritten = 0; + private final AtomicLong mNumBytesWritten = new AtomicLong(); public ByteCountingOutputStream (OutputStream os) { super (os); } public void reset () { - mNumBytesWritten = 0; + mNumBytesWritten.set(0); } public void setNumBytesWritten (long n) { - mNumBytesWritten = n; + mNumBytesWritten.set(n); } public long getNumBytesWritten () { - return (mNumBytesWritten); + return (mNumBytesWritten.longValue()); } public void write (byte [] b) throws IOException { out.write (b); - mNumBytesWritten += b.length; + mNumBytesWritten.addAndGet(b.length); } public void write (byte [] b, int off, int len) throws IOException { out.write (b, off, len); - mNumBytesWritten += len; + mNumBytesWritten.addAndGet(len); } public void write (int b) throws IOException { - mNumBytesWritten++; out.write (b); + mNumBytesWritten.incrementAndGet(); } } diff --git a/util/src/main/java/deltix/util/lang/MemoryPreferences.java b/util/src/main/java/deltix/util/lang/MemoryPreferences.java index 44aadf8a..e87989ab 100644 --- a/util/src/main/java/deltix/util/lang/MemoryPreferences.java +++ b/util/src/main/java/deltix/util/lang/MemoryPreferences.java @@ -10,7 +10,8 @@ * @see java.util.prefs.Preferences */ public final class MemoryPreferences extends AbstractPreferences { - public final class Factory implements PreferencesFactory { + + public static class Factory implements PreferencesFactory { private MemoryPreferences sys = new MemoryPreferences (false); private MemoryPreferences user = new MemoryPreferences (true); diff --git a/util/src/main/java/deltix/util/net/SSLContextProvider.java b/util/src/main/java/deltix/util/net/SSLContextProvider.java index 9030b655..c2589c5a 100644 --- a/util/src/main/java/deltix/util/net/SSLContextProvider.java +++ b/util/src/main/java/deltix/util/net/SSLContextProvider.java @@ -79,7 +79,10 @@ private static TrustManager[] getTrustManagers(boolean trustAl if (!trustAll) { KeyStore keystore = KeyStore.getInstance(KEYSTORE_FORMAT); - keystore.load(new FileInputStream(keystoreFile), keystorePass != null ? keystorePass.toCharArray() : null); + try (FileInputStream stream = new FileInputStream(keystoreFile)) { + keystore.load(stream, keystorePass != null ? keystorePass.toCharArray() : null); + } + //create and init trust manager factory TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); trustManagerFactory.init(keystore); diff --git a/util/src/main/java/deltix/util/os/WindowsOS.java b/util/src/main/java/deltix/util/os/WindowsOS.java index 97f1d829..fa38b871 100644 --- a/util/src/main/java/deltix/util/os/WindowsOS.java +++ b/util/src/main/java/deltix/util/os/WindowsOS.java @@ -4,7 +4,6 @@ import deltix.util.lang.Util; import deltix.util.lang.StringUtils; -import com.sun.jna.*; import com.sun.jna.platform.win32.*; import java.io.*; diff --git a/util/src/main/java/deltix/util/text/table/AlignedNoWhitespacesTable.java b/util/src/main/java/deltix/util/text/table/AlignedNoWhitespacesTable.java index c587b78b..7d3aae08 100644 --- a/util/src/main/java/deltix/util/text/table/AlignedNoWhitespacesTable.java +++ b/util/src/main/java/deltix/util/text/table/AlignedNoWhitespacesTable.java @@ -167,7 +167,7 @@ public void remove() { }; } - private class ANWColumn implements Column { + private static class ANWColumn implements Column { private final int index; private final String name; private final int nameStart; diff --git a/util/src/main/java/deltix/util/time/TimeDomain.java b/util/src/main/java/deltix/util/time/TimeDomain.java index d3b8c512..562ae407 100644 --- a/util/src/main/java/deltix/util/time/TimeDomain.java +++ b/util/src/main/java/deltix/util/time/TimeDomain.java @@ -237,9 +237,6 @@ public long c2g (long t) { if (t < 0) return (openTimes.getLong (0) + t); - - if (n == 0) - return (NOT_FOUND); int pos = Arrays.binarySearch (cumTimes.getInternalBuffer (), 0, n, t + 1); diff --git a/util/src/main/resources/deltix/util/currency/CurrencyCodes.xml b/util/src/main/resources/deltix/util/currency/CurrencyCodes.xml index ab7a6538..1fc1b2b1 100644 --- a/util/src/main/resources/deltix/util/currency/CurrencyCodes.xml +++ b/util/src/main/resources/deltix/util/currency/CurrencyCodes.xml @@ -1 +1 @@ -1301RippleXRPXRP1302Metaverse ETPETPETP1303Bitcoin CashBCHBCH1304OmiseGOOMGOMG1305NeoNEONEO1306IotaMIOTAIOT1307DigitalCashDASHDSH1308ZcashZECZEC1309MoneroXMRXMR1310Ethereum ClassicETCETC1311EOSEOSEOS1312AventusAVTAVT1313QtumQTUMQTM1314SantimentSANSAN1315EidooEDOEDO1316Bitcoin GoldBTGBTG1317StreamrDATADAT1318QASHQASHQSH1319YOYOWYOYOWYYW1321TetherUSDTTHR1322CardanoADAADA1323Binance CoinBNBBNB1325BreadBRDBRD1326GiftoGTOGTO1327IconomiICNICN1329IconICXICX1330LiskLSKLSK1331NanoNANONAN1333SaltSALTSLT1334StratisSTRATSTR1335TronTRXTRX1336WingsWINGSWNG1337Stellar LumensXLMXLM1338VergeXVGXVG1641LitecoinLTCLTC1741BitcoinBTCXBT1841EthereumETHETH8ALBANIALekALLLek12ALGERIAAlgerian DinarDZDDZD20ADPADPADP31AZERBAIJANAzerbaijanian ManatAZMман.32ARGENTINAArgentine PesoARS$36Australian DollarAUD$40ATSATSATS44BAHAMASBahamian DollarBSDBSD48BAHRAINBahraini DinarBHDد.ب.â€50BANGLADESHTakaBDTà§³51ARMENIAArmenian DramAMDÕ¤Ö€.52BARBADOSBarbados DollarBBDBBD56BEFBEFBEF60BERMUDABermudian Dollar (customarily known as Bermuda DolBMDBMD64BHUTANNgultrumBTNBTN68BOLIVIABolivianoBOB$b72BOTSWANAPulaBWPBWP84BELIZEBelize DollarBZDBZ$90SOLOMON ISLANDSSolomon Islands DollarSBDSBD96BRUNEI DARUSSALAMBrunei DollarBND$104MYANMARKyatMMKMMK108BURUNDIBurundi FrancBIFBIF116CAMBODIARielKHR៛124CANADACanadian DollarCAD$132CAPE VERDECape Verde EscudoCVECVE136CAYMAN ISLANDSCayman Islands DollarKYDKYD144SRI LANKASri Lanka RupeeLKRරු.152CHILEChilean PesoCLP$156CHINAYuan RenminbiCNYÂ¥170COLOMBIAColombian PesoCOP$174COMOROSComoro FrancKMFKMF188COSTA RICACosta Rican ColonCRCâ‚¡191CROATIACroatian KunaHRKkn192CUBACuban PesoCUPCUP196CYPRUSCyprus PoundCYPCYP203CZECH REPUBLICCzech KorunaCZK208Danish KroneDKKkr.214DOMINICAN REPUBLICDominican PesoDOPRD$222EL SALVADOREl Salvador ColonSVCSVC230ETHIOPIAEthiopian BirrETBETB232ERITREANakfaERNERN233ESTONIAKroonEEKkr238FALKLAND ISLANDS (MALVINAS)Falkland Islands PoundFKPFKP242FIJIFiji DollarFJDFJD246FIMFIMFIM250FRFFRFFRFFRF262DJIBOUTIDjibouti FrancDJFDJF270GAMBIADalasiGMDGMD276DEMDEMDEM288GHANACediGHCGHC292GIBRALTARGibraltar PoundGIPGIP300GRDGRDGRD320GUATEMALAQuetzalGTQQ324GUINEAGuinea FrancGNFGNF328GUYANAGuyana DollarGYDGYD332HAITIGourdeHTGHTG340HONDURASLempiraHNLL.344HONG KONGHong Kong DollarHKDHK$348HUNGARYForintHUFFt352ICELANDIceland KronaISKkr.356Indian RupeeINRRs.360INDONESIARupiahIDRRp364IRAN (ISLAMIC REPUBLIC OF)Iranian RialIRRريال368IRAQIraqi DinarIQDد.ع.â€372IEPIEPIEP376ISRAELNew Israeli SheqelILS₪380ITLITLITL388JAMAICAJamaican DollarJMDJ$392JAPANYenJPYÂ¥398KAZAKHSTANTengeKZTТ400JORDANJordanian DinarJODد.ا.â€404KENYAKenyan ShillingKESS408KOREA, DEMOCRATIC PEOPLE''S REPUBLIC OFNorth Korean WonKPWKPW410KOREA, DEMOCRATIC PEOPLE''S REPUBLIC OFWonKRWâ‚©414KUWAITKuwaiti DinarKWDد.Ùƒ.â€417KYRGYZSTANSomKGSÑом418LAO PEOPLE''S DEMOCRATIC REPUBLICKipLAKLAK422LEBANONLebanese PoundLBPÙ„.Ù„.â€426LESOTHOLotiLSLLSL428LATVIALatvian LatsLVLLs430LIBERIALiberian DollarLRDLRD434LIBYAN ARAB JAMAHIRIYALibyan DinarLYDد.Ù„.â€440LITHUANIALithuanian LitasLTLLt442LUFLUFLUF446MACAOPatacaMOPMOP454MALAWIKwachaMWKMWK458MALAYSIAMalaysian RinggitMYRRM462MALDIVESRufiyaaMVRÞƒ.470MALTAMaltese Lira^MTLLm478MAURITANIAOuguiyaMROMRO480MAURITIUSMauritius RupeeMURMUR484MEXICOMexican PesoMXN$496MONGOLIATugrikMNTâ‚®498MOLDOVA, REPUBLIC OFMoldovan LeuMDLMDL504Moroccan DirhamMADد.Ù….â€512OMANRial OmaniOMRر.ع.â€516NAMIBIANamibian DollarNADNAD524NEPALNepalese RupeeNPRरà¥528NLGNLGNLG532NETHERLANDS ANTILLESNetherlands Antillian GuikderANGANG533ARUBAAruban GuilderAWGAWG548VANUATUVatuVUVVUV554New Zealand DollarNZD$558NICARAGUACordoba OroNION566NIGERIANairaNGNNGN578Norwegian KroneNOKkr586PAKISTANPakistan RupeePKRRs590PANAMABalboaPABB/.598PAPUA NEW GUINEAKinaPGKPGK600PARAGUAYGuaraniPYGGs604PERUNuevo SolPENS/.608PHILIPPINESPhilippine PesoPHPPhP620PTEPTEPTE624GUINEA-BISSAUGuinea-Bissau PesoGWPGWP634QATARQatari RialQARر.Ù‚.â€642ROMANIAOld LeuROLlei643RUSSIAN FEDERATIONRussian RubleRUBRUB646RWANDARwanda FrancRWFRWF654SAINT HELENASaint Helena PoundSHPSHP678S?O TOME AND PRINCIPEDobraSTDSTD682SAUDI ARABIASaudi RiyalSARر.س.â€690SEYCHELLESSeychelles RupeeSCRSCR694SIERRA LEONELeoneSLLSLL702SINGAPORESingapore DollarSGD$703SLOVAKIASlovak KorunaSKKSk704VIET NAMDongVNDâ‚«705SLOVENIATolarSITSIT706SOMALIASomali ShillingSOSSOS710RandZARR716ZIMBABWEZimbabwe DollarZWDZ$724ESPESPESP736SUDANSudanese DinarSDDSDD748SWAZILANDLilangeniSZLSZL752SWEDENSwedish KronaSEKkr756Swiss FrancCHFfr.760SYRIAN ARAB REPUBLICSyrian PoundSYPÙ„.س.â€764THAILANDBahtTHB฿776TONGAPa''angaTOPTOP777CHINAYuan RenminbiCNHÂ¥780TRINNumericCodeAD AND TOBAGOTrinNumericCodead and Tobago DollarTTDTT$784UNITED ARAB EMIRATESUAE DirhamAEDد.Ø¥.â€788TUNISIATunisian DinarTNDد.ت.â€792TURKEYOld Turkish LiraTRL₤795TURKMENISTANManatTMMm.800UGANDAUganda ShillingUGXUGX807MACEDONIA, THE FORMER YUGOSLAV REPUBLIC OFDenarMKDден.818EGYPTEgyptian PoundEGPج.Ù….â€826UNITED KINGDOMPound SterlingGBP£834TANZANIA, UNITED REPUBLIC OFTanzanian ShillingTZSTZS840US DollarUSD$858URUGUAYPeso UruguayoUYU$U860UZBEKISTANUzbekistan SumUZSÑўм862VENEZUELABolivarVEBBs882SAMOATalaWSTWST886YEMENYemeni RialYERر.ÙŠ.â€891SERBIA AND MONTENEGROSerbian DinarCSDДин.894ZAMBIAKwachaZMKZMK901TAIWAN, PROVINCE OF CHINANew Taiwan DollarTWDNT$943MOZAMBIQUEMericalMZNMZN946ROMANIANew LeuRONRON947SWITZERLANDWIR EuroCHECHE948SWITZERLANDWIR FrancCHWCHW949TURKEYNew Turkish LiraTRYYTL950CFA Franc BEACXAFXAF951East Caribbean DollarXCDXCD952CFA Franc BCEAOXOFXOF953CFP FrancXPFXPF955Bond Markets Units European Composite Unit (EURCO)XBAXBA956European Monetary Unit (E.M.U.-6)XBBXBB957European Unit of Account 9(E.U.A.-9)XBCXBC958European Unit of Account 17(E.U.A.-17)XBDXBD959GoldXAUXAU960INTERNATIONAL MONETARY FUND (I.M.F)SDRXDRXDR961SilverXAGXAG962PlatinumXPTXPT963AlphabeticCodes specifically reserved for testingXTSXTS964PalladiumXPDXPD968SURINAMESurinam DollarSRDSRD969MADAGASCARMalagascy AriaryMGAMGA970COLOMBIAUnNumericCodead de Valor RealCOUCOU971AFGHANISTANAfghaniAFNAFN972TAJIKISTANSomoniTJSTJS973ANGOLAKwanzaAOAAOA974BELARUSBelarussian RubleBYRBYR975BULGARIABulgarian LevBGNBGN976CONGO, THE DEMOCRATIC REPUBLIC OFFranc CongolaisCDFCDF977BOSNIA & HERZEGOVINAConvertible MarksBAMKM978EuroEUR€979MEXICOMexican UnNumericCodead de Inversion (UNumericCodeMXVMXV980UKRAINEHryvniaUAHгрн.981GEORGIALariGELLari984BOLIVIAMvdolBOVBOV985POLANDZlotyPLNzÅ‚986BRAZILBrazilian RealBRLR$990CHILEUnNumericCodeades de formentoCLFCLF997UNITED STATES(Next day)USNUSN998UNITED STATES(Same day)USSUSS999XXXXXX1339ArkARKARK1341KomodoKMDKMD1342Power LedgerPOWRPWR1343AdExADXADX1345AeternityAEAE1346AionAIONAIO1347AmbrosusAMBAMB1349AppCoinsAPPCAPP1350AeronARNARN1351AirSwapASTAST1353Basic Attention TokenBATBAT1354Bitcoin DiamondBCDBCD1355BlockMason Credit ProtocolBCPTBCP1357BluzelleBLZBLZ1358BancorBNTBNT1359ETHOSETHOSBQX1361BitSharesBTSBTS1362BloxCDTCDT1363ChatCoinCHATCHT1365CyberMilesCMTCMT1366CindicatorCNDCND1367CentraCTRCTR1369DigixDAODGDDGD1370AgrelloDLTDLT1371district0xDNTDNT1373aelfELFELF1374EnigmaENGENG1375Enjin CoinENJENJ1377EverexEVXEVX1378EtherpartyFUELFUE1379FunFairFUNFUN1381GasGASGAS1382Genesis VisionGVTGVT1383GXChainGXSGXS1384HshareHSRHSR1385InsolarINSINS1386IOStokenIOSTIOS1387Kyber NetworkKNCKNC1389LendingblockLNDLND1390ChainLinkLINKLNK1391LoopringLRCLRC1393LunyrLUNLUN1394DecentralandMANAMAN1395Crypto.comMCOMCO1396Moeda Loyalty PointsMDAMDA1397ModumMODMOD1399MonethaMTHMTH1401MetalMTLMET1402NavCoinNAVNAV1403Nucleus VisionNCASHNCH1405NeblioNEBLNEB1406NulsNULSNUL1407OpenANXOAXOAX1409OntologyONTONT1411Simple TokenOSTOST1412PIVXPIVXPIV1413POA NetworkPOAPOA1415Po.etPOEPOE1416PopulousPPTPPT1419QLINKQLCQLC1420QuantstampQSPQSP1421Ripio Credit NetworkRCNRCN1423Raiden Network TokenRDNRDN1424Request NetworkREQREQ1425iExec RLCRLCRLC1427Red PulsePHXRPX1429SingularDTVSNGLSSNG1431SONMSNMSNM1432StatusSNTSNT1433SteemSTEEMSTM1435StorjSTORJSTJ1436StormSTORMSRM1437SubstratumSUBSUB1438SyscoinSYSSYS1439Time New BankTNBTNB1441TierionTNTTNT1443TriggersTRIGTRI1444VeChainVETVEN1445ViacoinVIAVIA1447ViberateVIBVIB1448VIBEVIBEVBE1449WaBiWABIWAB1450WanchainWANWAN1451WavesWAVESWVS1452WePowerWPRWPR1453WaltonchainWTCWTC1455NEMXEMXEM1456ZCoinXZCXZC1457ZilliqaZILZIL14590x ProtocolZRXZRX1000HyperCashHCHC1001GoChainGOGO1002Paxos Standard TokenPAXPAX1003RavencoinRVNRVN1004DecredDCRDCR1005MithrilMITHMITH1006USD CoinUSDCUSDC1007Bitcoin SVBSVBSV1008TezosXTZXTZ1009MakerMKRMKR1010DogecoinDOGEDOGE1011BytecoinBCNBCN1012TrueUSDTUSDTUSD1013DigiByteDGBDGB1014SiacoinSCSC1015BytomBTMBTM1016Pundi XNPXSNPXS1017AugurREPREP1018MaidSafeCoinMAIDMAID1019GolemGNTGNT1020ElectroneumETNETN1021HoloHOTHOT1022CryptonexCNXCNX1023FactomFCTFCT1024DaiDAIDAI1025KuCoin SharesKCSKCS1026Worldwide Asset ExchangeWAXWAX1027ArdorARDRARDR1028Huobi TokenHTHT1029MOACMOACMOAC1030RevainRR1031MonaCoinMONAMONA1032NexoNEXONEXO1033ODEMODEODE1034Insight ChainINBINB1035ReddCoinRDDRDD1036MixinXINXIN1037DentacoinDCNDCN1038HorizenZENZEN1039PolymathPOLYPOLY1040NasdacoinNSDNSD1041SIRIN LABS TokenSRNSRN1042Digitex FuturesDGTXDGTX1043DropilDROPDROP1044NxtNXTNXT1045MobileGoMGOMGO1046BOScoinBOSBOS1047TenXPAYPAY1048Theta TokenTHETATHETA1049NebulasNASNAS1050QuarkChainQKCQKC1051Loom NetworkLOOMLOOM1052VeritaseumVERIVERI1053ElastosELAELA1054WaykiChainWICCWICC1055ETERNAL TOKENXETXET1056DragonchainDRGNDRGN1057ProximaXXPXXPX1058Bitcoin PrivateBTCPBTCP1059Gemini DollarGUSDGUSD1060LinkeyLKYLKY1061BHPCashBHPCBHPC1062SmartlandsSLTSLT1063NectarNECNEC1064CivicCVCCVC1065OdysseyOCNOCN1066Endor ProtocolEDREDR1067Bibox TokenBIXBIX1068ARBITRAGEARBARB1069Optimal Shelf...OSAOSA1070DentDENTDENT1071GroestlcoinGRSGRS1072Byteball BytesGBYTEGBYTE1073RChainRHOCRHOC1074THEKEYTKYTKY1075CentralityCENNZCENNZ1076PeercoinPPCPPC1077EmercoinEMCEMC1078ETH LendLENDLEND1079Cloak CoinCLOAKCLOAK1080SKYSKYSKY1081IOTXIOTXIOTX1082SingularityNETAGIAGI1083NexusNXSNXS1084Key CoinKEYKEY1085MainframeMFTMFT1086DOCKDOCKDOCK1087Bit ConnectBCCBCC1088VENVENVEN1089Red PulseRPXRPX1090RENRENREN1091EthosBQXBQX1092BnkToTheFutureBFTBFT1093FSNFSNFSN1094MatrixMANMAN1095GnosisGNOGNO1096MelonMLNMLN1097NamecoinNMCNMC1098VertcoinVTCVTC1099BurstBURSTBURST1830Steem DollarsSTEEMDSBD1332BitTorrentBTTBTT1831ClamsCLAMCLAM1832FOAMFOAMFOAM1833GameCreditsGAMEGAME1835LBRY CreditsLBCLBC1836NumeraireNMRNMR1837Pascal CoinPASCPASC1838CounterpartyXCPXCP1839PrimecoinXPMXPM1829StableUSDUSDSUSDS1823STASIS EURSEURSEURS1824UTRUSTUTKUTK1825CortexCTXCCTXC1827Project PaiPAIPAI1828SmartMeshSMTSMT1794GrinGRINGRIN1796Unikoin GoldUKGUKG1797Genaro NetworkGNXGNX1798PentaPNTPNT1799Content Neutrality NetworkCNNCNN1801CredLBALBA1802BlocktixTIXTIX1803LympoLYMLYM1804All SportsSOCSOC1805Jibrel NetworkJNTJNT1806DATADTADTA1808AchainACTACT1809TokenCardTKNTKN1810PropyPROPRO1811DigitalNoteXDNXDN1812CrypteriumCRPTCRPT1813AragonANTANT1814BLOCKvVEEVEE1815BlocknetBLOCKBLOCK1816PumaPayPMAPMA1817IgnisIGNISIGNIS1819EdgelessEDGEDG1821Ontology GasONGONG1822Fetch.AIFETFET1793HUSD SolutionHUSDHUSD1632Ink ProtocolXNKXNK1633Crowd MachineCMCTCMCT1636NexiumNXCNXC1637SIBCoinSIBSIB1638Swarm CitySWTSWT1639PatientoryPTOYPTOY1640BANKEXBKXBKX1644MatchpoolGUPGUP1645HumaniqHMQHMQ1647HyperSpaceAMPAMP1648DECENTDCTDCT1649SpaceChainSPCSPC1650NAGANGCNGC1651NoLimitCoinNLC2NLC21652AeonAEONAEON1653OriginTrailTRACTRAC1655eBoostEBSTEBST1656CannabisCoinCANNCANN1657BreakoutBRKBRK1658SequenceSEQSEQ1659TransferCoinTXTX1660Memetic / PepeCoinMEMEMEME1661DopeCoinDOPEDOPE1662Internet of PeopleIOPIOP1663VeriumReserveVRMVRM1664PinkCoinPINKPINK1665SyndicateSYNXSYNX16662GIVE2GIVE2GIVE1667ExclusiveCoinEXCLEXCL1668DynamicDYNDYN1669ArtByteABYABY1670FoldingCoinFLDCFLDC1671KoreKOREKORE1672GeoCoinGEOGEO1673ExpanseEXPEXP1674OKCashOKOK1675MusicoinMUSICMUSIC1676GolosGOLOSGOLOS1677Blockparty (BOXX Token)BOXXBOXX1679CurecoinCURECURE1680SolarCoinSLRSLR1681BloomBLTBLT1683Decision TokenHSTHST1684Haven ProtocolXHVXHV1685GridCoinGRCGRC1686MonetaryUnitMUEMUE1687MyriadXMYXMY1688DiamondDMDDMD1689I/O CoinIOCIOC1691Bean CashBITBBITB1692CrownCRWCRW1693RadiumRADSRADS1695VeriCoinVRCVRC1696IncentINCNTINCNT1697RevolutionVRRVRRVR1698XELXELXEL1699UpTokenUPUP1700IONIONION1701BitTubeTUBETUBE1707HempCoinTHCTHC1708FeathercoinFTCFTC1709ShiftSHIFTSHIFT1711adTokenADTADT1712PotCoinPOTPOT1713BlackCoinBLKBLK1714Sentinel ProtocolUPPUPP1715MercuryMERMER1717MobiusMOBIMOBI1718ZClassicZCLZCL1719CashBet CoinCBCCBC1720MetronomeMETMET1721VITEVITEVITE1722HydroHYDROHYDRO1723BitBayBAYBAY1725IHT Real Estate ProtocolIHTIHT1726RefereumRFRRFR1727UbiqUBQUBQ1728FLOFLOFLO1729WhiteCoinXWCXWC1730Moss CoinMOCMOC1731NKNNKNNKN1732QuantQNTQNT1733Crypto.com ChainCROCRO1734ParticlPARTPART1735Quantum Resistant LedgerQRLQRL1737DMarketDMTDMT1738SaluSSLSSLS1739MediBloc [ERC20]MEDXMEDX1740EinsteiniumEMC2EMC21742AidCoinAIDAID1743AuctusAUCAUC1744Banyan NetworkBBNBBN1745Bitcoin InterestBCIBCI1746CommerceBlockCBTCBT1747Callisto NetworkCLOCLO1749Digix Gold TokenDGXDGX1750DetherDTHDTH1751EssentiaESSESS1753ParkinGoGOTGOT1754Internet Node TokenINTINT1755On.LiveONLONL1757KlerosPNKPNK1758RIF TokenRIFRIF1759Rate3RTERTE1761ConsensusSENSEN1762VetriVLDVLD1763WOLLOWLOWLO1765XribaXRAXRA17660ChainZCNZCN1767Recovery Right TokensRRTRRT1768CreditsCSCS1769DADIDADIDADI1770Tether EuroEURTEURt1771EveripediaIQIQ1772MedicalchainMTNMTN1773AutonioANIONIO1774OmniOMNIOMNI1775ORS GroupORSGORS1778BlockpassPASSPASS1779RSK Smart BitcoinRBTCRBTC1781SEERSEERSEER1782SpankChainSPANKSPANK1783UniversaUTNPUTNP1785V SystemsVSYSVSYS1786V YggdrashYEEDYEED1787Hydro ProtocolHOTPHOT1789ContentBoxBOXBOX1790AtonomiATMIATMI1791The AbyssABYSSABYSS1630Atlas ProtocolATPATP16311BG1BG1BG1626Time Space ChainTSCTSC1627BerithBRTBRT1628BitMart TokenBMXBMX1629Bitcoin HDXHDBHD1625WoChainWOCWOC1623Celer NetworkCELRCELR1622Ether Kingdoms TokenIMPIMP1621MaecenasARTART1619VeriblockVBKVBK1618PlayChipPLAPLA1617OrbsORBSORBS1614TTC ProtocolTTCTTC1615ForestingPTONPTON1616PCHAINPIPI1612AnkrANKRANKR1613AergoAERGOAERGO1610MetadiumMETAMETA1611GoldCoinGLCGLC1605PAL NetworkPALPAL1606Solve.CareSOLVESOLVE1607BTU ProtocolBTUBTU1609SpendcoinSPNDSPND1602SphereSPHRSPHR1603ServeSERVSERV1597Circuits of ValueCOVALCOVAL1599Breakout StakeBRXBRX1601BitswiftBITSBITS1596Golos GoldGBGGBG1594EverGreenCoinEGCEGC1595DatabitsDTBDTB1587QwarkQWARKQWARK1588NeosCoinNEOSNEOS1589NuBitsNBTNBT1591More CoinMOREMORE1592HxroHXROHXRO1593GambitGAMGAM1584StealthXSTXST1585TokesTKSTKS1582GuldenCNLGNLG1583BitSendCBSDBSD1581HunterCoinHUCHUC1580LivepeerLPTLPT1579BORABORABORA1577STACSSTACSSTACS1576HOT TokenHOTTHOT1575DreamTeamDREAMDREAM1574TOPTOPNTOP1568Machine Xchange CoinMXCMXC1569COVACOVACOVA1570LambdaLAMBLAMB1571Content Value NetworkCVNTCVNT1572RuffRUFFRUFF1573LinkEyeLETLET1563Davinci CoinDACDAC1564TripioTRIOTRIO1565InvestDigitalIDTIDT1567Huobi Pool TokenHPTHPT1556ThingsOperatingSystemTOSTOS1557Globalvillage EcosystemGVEGVE1559NeuroChainNCCNCC1560KcashKCASHKCASH1561CVCoinCVNCVN1562BitCapitalVendorBCVBCV1551Yuan Chain CoinYCCYCC1552BitUP TokenBUTBUT1553SmartshareSSPSSP1555MyTokenMTMT1546DATxDATXDATX1547ThemisGETGET1549GET ProtocolGETPGET1550U NetworkUUUUUU1540XMaxXMXXMX1541YouLive CoinUCUC1542Acute Angle CloudAACAAC1543SeeleSEELESEELE1544UnlimitedIPUIPUIP1545LitexLXTLXT1537FansTimeFTIFTI1538Global Social ChainGSCGSC1539Promotion CoinPCPC1531EDUCareEKTEKT1534BeeKanBKBTBKBT1535FairGameFAIRFAIR1536Game.comGTCGTC1527Intelligent Investment ChainIICIIC1529ShineChainSHESHE1530MEXMEXMEX1522QunQunQUNQUN1523EduCoinEDUEDU1525BitcoinXBCXBCX1526HitChainHITHIT1520SunContractSNCSNC1521STKSTKSTK1517YEEYEEYEE1518EchoLinkEKOEKO1519DeepBrain ChainDBCDBC1513ZillaZLAZLA1514ArcblockABTABT1515MatryxMTXMTX1511BitKanKANKAN1506TopChainTOPCTOPC1507CoinMeetMEETMEET1508SwftCoinSWFTCSWFTC1509MediSharesMDSMDS1510IoT ChainITCITC1501EngineEGCCEGCC1502AI DoctorAIDOCAIDOC1503Super BitcoinSBTCSBTC1505Bitcoin FileBIFIBIFI1500IRIS NetworkIRISIRIS1494MuskMUSKMUSK1495PortalPORTALPORTAL1497RCCCRCCCRCCC1499DatumDATDAT1492ZJLT Distributed Factoring NetworkZJLTZJLT1493Block 1818C18C1491MARK.SPACEMRKMRK1490AdHiveADHADH1479FLIPFLPFLP1489Dragon CoinsDRGDRG1481FarmaTrustFTTFTT1482LikeCoinLIKELIKE1483Morpheus LabsMITXMITX1485StoxSTXSTX1486ZPERZPRZPR1487FintruX NetworkFTXFTX1488Plus-CoinNPLCNPLC1477Huobi 10 IndexHB10HB101476ObsidianODNODN1472PitchPITCHPITCH1473Purple Butterfly TradingPBTTPBTT1474PatronPATPAT1475OpusOPTOPT1463ProCurrencyPROCPROC1464PresearchPREPRE1465PaymonPMNTPMNT1466PlutonPLUPLU1467PillarPLRPLR1468PolybiusPLBTPLBT1469PlaykeyPKTPKT1471LampixPIXPIX1460Quanta Utility TokenQNTUQNTU1461PlayGamePXGPXG1842imbrexREXREX1843BitRentRNTBRNTB1844RobotinaROXROX1845RivetzRVTRVT1846SociallSCLSCL1847SentinelSENTSENT1848ShipChainSHIPSHIP1849Signal TokenSIGSIG1850SilkChainSILKSILK1851SlateSLXSLX1852SmartCashSMARTSMART1853SnowballSNBLSNBL1854SPINDLESPDSPD1855SportyCoSPFSPF1856StarbaseSTARSTAR1857StoriqaSTQSTQ1859SunchainSUNCSUNC1861SuretlySURSUR1863savedroidSVDSVD1864SwarmSWMSWM1865TaaSTAASTAAS1866LamdenTAUTAU1867TrueDeckTDPTDP1868TokenDeskTDSTDS1869TelcoinTELTEL1870ChronobankTIMETIME1871TradcoinTRADTRAD1872WeTrustTRSTTRST1873TrueChainTRUETRUE1874Useless Ethereum TokenUETUET1875Usechain TokenUSEUSE1876United Traders TokenUTTUTT1877VeriMEVMEVME1878Provoco TokenVOCOVOCO1879Wiki TokenWIKIWIKI1880CrowdWizWIZWIZ1881XaurumXAURXAUR1883BlitzPredictXBPXBP1884Monero ClassicXMCXMC1885Exchange UnionXUCXUC1887ZapZAPZAP1888ZeepinZPTZPT1889ZrCoinZRCZRC1890ZeusshieldZSCZSC2000ATLANT TokenATLATL2001BANCABANCABANCA2002BerryBERRYBERRY2003BetterBettingBETRBETR2004BitClaveCATCAT2005BitcoreBTXBTX2006BitDegreeBDGBDG2007BitDiceCSNOCSNO2008Black MoonBMCBMC2009BlockMeshBMHBMH2010CashaaCASCAS2011CoinPokerCHPCHP2012COPYTRACKCPYCPY2013CovestingCOVCOV2014Crypto20C20C202015CryptopayCPAYCPAY2016CUBEAUTOAUTO2017Curriculum VitaeCVHCVH2018CyberVeinTokenCVTCVT2019DAO CasinoBETBET2020DecentBetDBETDBET2021DIMCOINDIMDIM2022EtherollDICEDICE2023First Blood1ST1ST2024FortunaFOTAFOTA2025GoByteGBXGBX2026HappycoinHPCHPC2027Hive ProjectHVNHVN2028indaHashIDHIDH2029InsurChainINSURINSUR2030InsurePalIPLIPL2031iXledgerIXTIXT2032KickCoinKICKKICK2033KINKINKIN2034LATokenLALA2035LifeLIFELIFE2036LockTripLOCLOC2037MeshBoxMESHMESH2038Micro MoneyAMMAMM2039MybitMYBMYB2040NectarNCTNCT2041NeumarkNEUNEU2042NOAHCOINNOAHNOAH2043SwissBorgCHSBCHSB2044AlphacatACATACAT2045Freyr ChainFRECFREC2046ConsentiumCSMCSM2047NanjcoinNANJNANJ2048NeuroTokenNTKNTK2049FuzeXFXTFXT2050ChainiumCHXCHX2051FriendZ CoinFDZFDZ2052CryptaurCPTCPT2053HTMLCOINHTMLHTML2054Banker TokenBNKBNK2055KaratBank CoinKBCKBC2056InkINKINK2057Colu Local NetworkCLNCLN2058LitecoinCashLCCLCC2059ElectrifyAsiaELECELEC2060BitRewardsBITBIT2061CosmoCoinCOSMCOSM2062Kind AdsKINDKIND2063InmediateDITDIT2064CyCleanCCLCCL2065NimiqNIMNIM2066AML BitcoinABTCABTC2067EcosBallABAABA2068MesseMESSEMESSE2069AXpireAXPRAXPR2070ConstellationDAGDAG2071Acorn Collective TokenOAKOAK2072MarginlessMRSMRS2073Dynamic Trading RightsDTRDTR1892BOX TokenBOXTBOX1893BitcoinusBITSSBITS18951World1WO1WO1896AMLTAMLTAMLT1897BiotronBTRNBTRN1898CanYaCoinCANCAN1899XAYACHICHI1900DACSEEDACSDACS1902Earth TokenEARTHEARTH1903EZTokenEZTEZT1904FlixxoFLIXXFLIXX1905DAOstackGENGEN1906GazeCoinGZEGZE1907Invictus Hyperion FundIHFIHF1908IP ExchangeIPSXIPSX1909KryllKRLKRL1910LALA WorldLALALALA1911SalPaySALSAL1912Signals NetworkSGNSGN1913SIXSIXSIX1914SnipCoinSNIPSNIP1915SophiaTXSPHTXSPHTX1916Thrive TokenTHRTTHRT1917TokenPayTPAYTPAY1918UnibrightUBTUBT1919ProxeusXESXES1920ZebiZCOZCO1921BrylliteBRCBRC1922FidentiaXFDXFDX1923Global Awards TokenGATGAT1924onG.socialONGSONG1925StarterCoinSTACSTAC1926TeleportTPTTPT1927TaTaTuTTUTTU1928WCoinWINWIN1929bitJobSTUSTU1930CosmosATOMATOM1931XNDXNDXND1932SCRLSCRLSCR1933UGASUGASUGAS1934Matic NetworkMATICMATIC1935Wrapped BitcoinWBTCWBTC1936CryptoFrancXCHFXCHF1937Function XFXFX1938OceanOCEANOCEAN1939XYOXYOXYO1940WibsonWIBWIB1941Blue Whale TokenBWXBWX1942Newton ProjectNEWNEW1944ThunderCoreTTTT1945OKBOKBOKB1954YOU COINYOUYOU1965AschXASXAS1966EgretiaEGTEGT1967High Performance BlockchainHPBHPB1982Measurable Data TokenMDTMDT1983ugChainUGCUGC1987DelphyDPYDPY1988SelfSellSSCSSC1989PrimasPSTPST1991ZipperZIPZIP1992CIChainCICCIC1993ChronologicDAYDAY1994DaneelDANDAN1995DomRaider TokenDRTDRT1996Indorse TokenINDIND2074Helbiz TokenHBZHBZ2075Morpheus NetworkMORPHMORPH2076SynthetixSNXSNX2077Synthetix sUSDSUSDSUSD2078LEO TokenLEOLEO2079Vodi XVDXVDX2080Reserve Rights TokenRSRRSR1100Red Pulse Phoenix BinancePHBPHB1101Theta FuelTFUELTFUEL1102ZBTokenZBZB1103UpfiringUFRUFR1129Cai TokenCAICAI1105WinTokenWINTWINT1106Origin SportORSORS1107HYCONHYCHYC1130AirblocABLABL1109BlockcloudBLOCBLOC1110ACE (TokenStars)ACEACE1111Molecular FutureMOFMOF1112TokenClubTCTTCT1113StarChainSTCSTC1114LightChainLIGHTLIGHT1115OFCOINOFOF1131Hi Mutual SocietyHMCHMC1117Beauty ChainBECBEC1118MerculetMVPMVP1119SDChainSDASDA1120ProChainPRAPRA1121OneRoot NetworkRNTRNT1122RealChainRCTRCT1123RefTokenREFREF1133Ubique Chain Of ThingsUCTUCT1125United BitcoinUBTCUBTC1126ShowSHOWSHOW1127Olympus LabsMOTMOT1128IPChainIPCIPC1134OrigoOGOOGO1135HarmonyONEONE1137USDKUSDKUSDK2081BeaxyBXYBXY2082FantomFTMFTM2083AlgorandALGOALGO2084V-IDVIDTVIDT2085VideoCoinVIDVID2086EnergiNRGNRG2087Dusk NetworkDUSKDUSK2088WINkWINKWINK2089WirexWXTWXT2090Bitcoin BEP2BTCBBTCB2091StableUSD BEP2USDSBUSDSB2092ElrondERDERD2093Binance GBP Stable CoinBGBPBGBP2094ContentosCOSCOS2095TrueUSD BEP2TUSDBTUSDB2096Cocos-BCXCOCOSCOCOS2097TomoChainTOMOTOMO2098PerlinPERLPERL2099ChilizCHZCHZ2100AmpleforthAMPLAMPL2101GateChainTokenGTGT2102UltraUOSUOS2103rrbRRBRRB2104Dragon TokenDTDT2105BeamBEAMBEAM2106Tether CNHCNHTCNHT2107AlliveALVALV2108VNT ChainVNTVNT2109En-Tan-MoETMETM2110EminerEMEM2111EchoinECEC2112PledgecampPLGPLG2113X-Power ChainXPOXPO2114FTX TokenFTTXFTTX2115AkropolisAKROAKRO2116Skrumble NetworkSKMSKM2117PivotPVTPVT2118Crypto Neo-value Neural SystemCNNSCNNS2119BHEX TokenBHTBHT2120CarryCRECRE2121ARPA ChainARPAARPA2122VidyCoinVIDYVIDY2123Force ProtocolFORFOR2124RedFOX LabsRFOXRFOX2125CelsiusCELCEL2126AnchorANCTANCT2127Standard Tokenization ProtocolSTPTSTPT2128Contents ProtocolCPTLCPTL2129PrometeusPROMPROM2130FlexacoinFXCFXC2131SPIN ProtocolSPINSPIN2132ChromiaCHRCHR2133PixelPXLPXL2134HedgeTradeHEDGHEDG2135Morpheus.NetworkMRPHMRPH2136Hedera HashgraphHBARHBAR2137Band ProtocolBANDBAND2138Bitpanda Ecosystem TokenBESTBEST2139PantosPANPAN2140Binance USDBUSDBUSD \ No newline at end of file +1301RippleXRPXRP1323Binance CoinBNBBNB1325BreadBRDBRD1326GiftoGTOGTO1327IconomiICNICN1329IconICXICX1330LiskLSKLSK1331NanoNANONAN1333SaltSALTSLT1335TronTRXTRX1336WingsWINGSWNG1337Stellar LumensXLMXLM1338VergeXVGXVG1641LitecoinLTCLTC1741BitcoinBTCXBT1841EthereumETHETH1322CardanoADAADA1321TetherUSDTTHR1334StratisSTRATSTR1318QASHQASHQSH1319YOYOWYOYOWYYW1302Metaverse ETPETPETP1303Bitcoin CashBCHBCH1304OmiseGOOMGOMG1305NeoNEONEO1307DigitalCashDASHDSH1308ZcashZECZEC1309MoneroXMRXMR1306IotaMIOTAIOT1311EOSEOSEOS1312AventusAVTAVT1313QtumQTUMQTM1314SantimentSANSAN1315EidooEDOEDO1316Bitcoin GoldBTGBTG1310Ethereum ClassicETCETC1317StreamrDATADAT706SOMALIASomali ShillingSOSSOS756Swiss FrancCHFfr.752SWEDENSwedish KronaSEKkr748SWAZILANDLilangeniSZLSZL710RandZARR724ESPESPESP716ZIMBABWEZimbabwe DollarZWDZ$760SYRIAN ARAB REPUBLICSyrian PoundSYPÙ„.س.â€736SUDANSudanese DinarSDDSDD764THAILANDBahtTHB฿807MACEDONIA, THE FORMER YUGOSLAV REPUBLIC OFDenarMKDден.780TRINNumericCodeAD AND TOBAGOTrinNumericCodead and Tobago DollarTTDTT$784UNITED ARAB EMIRATESUAE DirhamAEDد.Ø¥.â€788TUNISIATunisian DinarTNDد.ت.â€792TURKEYOld Turkish LiraTRL₤777CHINAYuan RenminbiCNHÂ¥795TURKMENISTANManatTMMm.800UGANDAUganda ShillingUGXUGX818EGYPTEgyptian PoundEGPج.Ù….â€826UNITED KINGDOMPound SterlingGBP£705SLOVENIATolarSITSIT776TONGAPa''angaTOPTOP704VIET NAMDongVNDâ‚«590PANAMABalboaPABB/.702SINGAPORESingapore DollarSGD$548VANUATUVatuVUVVUV558NICARAGUACordoba OroNION566NIGERIANairaNGNNGN578Norwegian KroneNOKkr586PAKISTANPakistan RupeePKRRs834TANZANIA, UNITED REPUBLIC OFTanzanian ShillingTZSTZS598PAPUA NEW GUINEAKinaPGKPGK600PARAGUAYGuaraniPYGGs604PERUNuevo SolPENS/.608PHILIPPINESPhilippine PesoPHPPhP620PTEPTEPTE624GUINEA-BISSAUGuinea-Bissau PesoGWPGWP634QATARQatari RialQARر.Ù‚.â€642ROMANIAOld LeuROLlei643RUSSIAN FEDERATIONRussian RubleRUBRUB646RWANDARwanda FrancRWFRWF654SAINT HELENASaint Helena PoundSHPSHP678S?O TOME AND PRINCIPEDobraSTDSTD682SAUDI ARABIASaudi RiyalSARر.س.â€690SEYCHELLESSeychelles RupeeSCRSCR694SIERRA LEONELeoneSLLSLL703SLOVAKIASlovak KorunaSKKSk840US DollarUSD$955Bond Markets Units European Composite Unit (EURCO)XBAXBA860UZBEKISTANUzbekistan SumUZSÑўм968SURINAMESurinam DollarSRDSRD969MADAGASCARMalagascy AriaryMGAMGA970COLOMBIAUnNumericCodead de Valor RealCOUCOU971AFGHANISTANAfghaniAFNAFN972TAJIKISTANSomoniTJSTJS973ANGOLAKwanzaAOAAOA974BELARUSBelarussian RubleBYRBYR975BULGARIABulgarian LevBGNBGN976CONGO, THE DEMOCRATIC REPUBLIC OFFranc CongolaisCDFCDF977BOSNIA & HERZEGOVINAConvertible MarksBAMKM978EuroEUR€979MEXICOMexican UnNumericCodead de Inversion (UNumericCodeMXVMXV980UKRAINEHryvniaUAHгрн.981GEORGIALariGELLari984BOLIVIAMvdolBOVBOV985POLANDZlotyPLNzÅ‚986BRAZILBrazilian RealBRLR$990CHILEUnNumericCodeades de formentoCLFCLF997UNITED STATES(Next day)USNUSN998UNITED STATES(Same day)USSUSS999XXXXXX964PalladiumXPDXPD858URUGUAYPeso UruguayoUYU$U963AlphabeticCodes specifically reserved for testingXTSXTS961SilverXAGXAG862VENEZUELABolivarVEBBs882SAMOATalaWSTWST886YEMENYemeni RialYERر.ÙŠ.â€891SERBIA AND MONTENEGROSerbian DinarCSDДин.894ZAMBIAKwachaZMKZMK901TAIWAN, PROVINCE OF CHINANew Taiwan DollarTWDNT$943MOZAMBIQUEMericalMZNMZN946ROMANIANew LeuRONRON947SWITZERLANDWIR EuroCHECHE948SWITZERLANDWIR FrancCHWCHW949TURKEYNew Turkish LiraTRYYTL950CFA Franc BEACXAFXAF951East Caribbean DollarXCDXCD952CFA Franc BCEAOXOFXOF953CFP FrancXPFXPF533ARUBAAruban GuilderAWGAWG956European Monetary Unit (E.M.U.-6)XBBXBB957European Unit of Account 9(E.U.A.-9)XBCXBC958European Unit of Account 17(E.U.A.-17)XBDXBD959GoldXAUXAU960INTERNATIONAL MONETARY FUND (I.M.F)SDRXDRXDR962PlatinumXPTXPT532NETHERLANDS ANTILLESNetherlands Antillian GuikderANGANG554New Zealand DollarNZD$524NEPALNepalese RupeeNPRरà¥144SRI LANKASri Lanka RupeeLKRරු.528NLGNLGNLG156CHINAYuan RenminbiCNYÂ¥170COLOMBIAColombian PesoCOP$174COMOROSComoro FrancKMFKMF188COSTA RICACosta Rican ColonCRCâ‚¡191CROATIACroatian KunaHRKkn192CUBACuban PesoCUPCUP196CYPRUSCyprus PoundCYPCYP203CZECH REPUBLICCzech KorunaCZK208Danish KroneDKKkr.214DOMINICAN REPUBLICDominican PesoDOPRD$222EL SALVADOREl Salvador ColonSVCSVC230ETHIOPIAEthiopian BirrETBETB232ERITREANakfaERNERN233ESTONIAKroonEEKkr238FALKLAND ISLANDS (MALVINAS)Falkland Islands PoundFKPFKP242FIJIFiji DollarFJDFJD246FIMFIMFIM250FRFFRFFRFFRF262DJIBOUTIDjibouti FrancDJFDJF136CAYMAN ISLANDSCayman Islands DollarKYDKYD132CAPE VERDECape Verde EscudoCVECVE124CANADACanadian DollarCAD$116CAMBODIARielKHR៛8ALBANIALekALLLek12ALGERIAAlgerian DinarDZDDZD20ADPADPADP31AZERBAIJANAzerbaijanian ManatAZMман.32ARGENTINAArgentine PesoARS$36Australian DollarAUD$40ATSATSATS44BAHAMASBahamian DollarBSDBSD48BAHRAINBahraini DinarBHDد.ب.â€50BANGLADESHTakaBDTà§³270GAMBIADalasiGMDGMD51ARMENIAArmenian DramAMDÕ¤Ö€.56BEFBEFBEF60BERMUDABermudian Dollar (customarily known as Bermuda DolBMDBMD64BHUTANNgultrumBTNBTN68BOLIVIABolivianoBOB$b72BOTSWANAPulaBWPBWP84BELIZEBelize DollarBZDBZ$90SOLOMON ISLANDSSolomon Islands DollarSBDSBD96BRUNEI DARUSSALAMBrunei DollarBND$104MYANMARKyatMMKMMK108BURUNDIBurundi FrancBIFBIF52BARBADOSBarbados DollarBBDBBD276DEMDEMDEM152CHILEChilean PesoCLP$292GIBRALTARGibraltar PoundGIPGIP418LAO PEOPLE''S DEMOCRATIC REPUBLICKipLAKLAK422LEBANONLebanese PoundLBPÙ„.Ù„.â€426LESOTHOLotiLSLLSL428LATVIALatvian LatsLVLLs430LIBERIALiberian DollarLRDLRD434LIBYAN ARAB JAMAHIRIYALibyan DinarLYDد.Ù„.â€440LITHUANIALithuanian LitasLTLLt442LUFLUFLUF446MACAOPatacaMOPMOP454MALAWIKwachaMWKMWK458MALAYSIAMalaysian RinggitMYRRM462MALDIVESRufiyaaMVRÞƒ.470MALTAMaltese Lira^MTLLm478MAURITANIAOuguiyaMROMRO480MAURITIUSMauritius RupeeMURMUR484MEXICOMexican PesoMXN$496MONGOLIATugrikMNTâ‚®498MOLDOVA, REPUBLIC OFMoldovan LeuMDLMDL504Moroccan DirhamMADد.Ù….â€288GHANACediGHCGHC516NAMIBIANamibian DollarNADNAD417KYRGYZSTANSomKGSÑом414KUWAITKuwaiti DinarKWDد.Ùƒ.â€512OMANRial OmaniOMRر.ع.â€408KOREA, DEMOCRATIC PEOPLE''S REPUBLIC OFNorth Korean WonKPWKPW410KOREA, DEMOCRATIC PEOPLE''S REPUBLIC OFWonKRWâ‚©300GRDGRDGRD324GUINEAGuinea FrancGNFGNF328GUYANAGuyana DollarGYDGYD332HAITIGourdeHTGHTG340HONDURASLempiraHNLL.344HONG KONGHong Kong DollarHKDHK$348HUNGARYForintHUFFt352ICELANDIceland KronaISKkr.356Indian RupeeINRRs.320GUATEMALAQuetzalGTQQ364IRAN (ISLAMIC REPUBLIC OF)Iranian RialIRRريال368IRAQIraqi DinarIQDد.ع.â€372IEPIEPIEP376ISRAELNew Israeli SheqelILS₪380ITLITLITL388JAMAICAJamaican DollarJMDJ$392JAPANYenJPYÂ¥398KAZAKHSTANTengeKZTТ404KENYAKenyan ShillingKESS400JORDANJordanian DinarJODد.ا.â€360INDONESIARupiahIDRRp1416PopulousPPTPPT1419QLINKQLCQLC1420QuantstampQSPQSP1425iExec RLCRLCRLC1423Raiden Network TokenRDNRDN1424Request NetworkREQREQ1427Red PulsePHXRPX1421Ripio Credit NetworkRCNRCN1415Po.etPOEPOE1407OpenANXOAXOAX1412PIVXPIVXPIV1411Simple TokenOSTOST1409OntologyONTONT1406NulsNULSNUL1405NeblioNEBLNEB1403Nucleus VisionNCASHNCH1402NavCoinNAVNAV1429SingularDTVSNGLSSNG1401MetalMTLMET1413POA NetworkPOAPOA1431SONMSNMSNM1447ViberateVIBVIB1433SteemSTEEMSTM1399MonethaMTHMTH14590x ProtocolZRXZRX1457ZilliqaZILZIL1456ZCoinXZCXZC1455NEMXEMXEM1453WaltonchainWTCWTC1452WePowerWPRWPR1451WavesWAVESWVS1450WanchainWANWAN1432StatusSNTSNT1449WaBiWABIWAB1445ViacoinVIAVIA1444VeChainVETVEN1443TriggersTRIGTRI1441TierionTNTTNT1439Time New BankTNBTNB1438SyscoinSYSSYS1437SubstratumSUBSUB1436StormSTORMSRM1435StorjSTORJSTJ1448VIBEVIBEVBE1397ModumMODMOD1378EtherpartyFUELFUE1395Crypto.comMCOMCO1365CyberMilesCMTCMT1363ChatCoinCHATCHT1362BloxCDTCDT1361BitSharesBTSBTS1358BancorBNTBNT1357BluzelleBLZBLZ1355BlockMason Credit ProtocolBCPTBCP1354Bitcoin DiamondBCDBCD1353Basic Attention TokenBATBAT1351AirSwapASTAST1350AeronARNARN1349AppCoinsAPPCAPP1347AmbrosusAMBAMB1346AionAIONAIO1345AeternityAEAE1343AdExADXADX1342Power LedgerPOWRPWR1341KomodoKMDKMD1339ArkARKARK1366CindicatorCNDCND1367CentraCTRCTR1359ETHOSETHOSBQX1370AgrelloDLTDLT1394DecentralandMANAMAN1393LunyrLUNLUN1391LoopringLRCLRC1369DigixDAODGDDGD1389LendingblockLNDLND1387Kyber NetworkKNCKNC1386IOStokenIOSTIOS1385InsolarINSINS1384HshareHSRHSR1383GXChainGXSGXS1390ChainLinkLINKLNK1381GasGASGAS1379FunFairFUNFUN1396Moeda Loyalty PointsMDAMDA1377EverexEVXEVX1375Enjin CoinENJENJ1374EnigmaENGENG1373aelfELFELF1371district0xDNTDNT1382Genesis VisionGVTGVT1000HyperCashHCHC1007Bitcoin SVBSVBSV1006USD CoinUSDCUSDC1005MithrilMITHMITH1002Paxos Standard TokenPAXPAX1003RavencoinRVNRVN1001GoChainGOGO1004DecredDCRDCR1016Pundi XNPXSNPXS1021HoloHOTHOT1020ElectroneumETNETN1019GolemGNTGNT1018MaidSafeCoinMAIDMAID1015BytomBTMBTM1017AugurREPREP1013DigiByteDGBDGB1012TrueUSDTUSDTUSD1014SiacoinSCSC1011BytecoinBCNBCN1010DogecoinDOGEDOGE1009MakerMKRMKR1008TezosXTZXTZ1036MixinXINXIN1037DentacoinDCNDCN1038HorizenZENZEN1039PolymathPOLYPOLY1042Digitex FuturesDGTXDGTX1041SIRIN LABS TokenSRNSRN1035ReddCoinRDDRDD1043DropilDROPDROP1040NasdacoinNSDNSD1033ODEMODEODE1034Insight ChainINBINB1031MonaCoinMONAMONA1032NexoNEXONEXO1023FactomFCTFCT1024DaiDAIDAI1025KuCoin SharesKCSKCS1026Worldwide Asset ExchangeWAXWAX1022CryptonexCNXCNX1028Huobi TokenHTHT1029MOACMOACMOAC1030RevainRR1027ArdorARDRARDR1044NxtNXTNXT1045MobileGoMGOMGO1046BOScoinBOSBOS1057ProximaXXPXXPX1063NectarNECNEC1062SmartlandsSLTSLT1061BHPCashBHPCBHPC1060LinkeyLKYLKY1059Gemini DollarGUSDGUSD1058Bitcoin PrivateBTCPBTCP1056DragonchainDRGNDRGN1047TenXPAYPAY1054WaykiChainWICCWICC1053ElastosELAELA1052VeritaseumVERIVERI1051Loom NetworkLOOMLOOM1050QuarkChainQKCQKC1049NebulasNASNAS1048Theta TokenTHETATHETA1055ETERNAL TOKENXETXET1077EmercoinEMCEMC1076PeercoinPPCPPC1075CentralityCENNZCENNZ1074THEKEYTKYTKY1073RChainRHOCRHOC1072Byteball BytesGBYTEGBYTE1071GroestlcoinGRSGRS1067Bibox TokenBIXBIX1069Optimal Shelf...OSAOSA1068ARBITRAGEARBARB1066Endor ProtocolEDREDR1065OdysseyOCNOCN1064CivicCVCCVC1070DentDENTDENT1078ETH LendLENDLEND1079Cloak CoinCLOAKCLOAK1080SKYSKYSKY1081IOTXIOTXIOTX1082SingularityNETAGIAGI1083NexusNXSNXS1084Key CoinKEYKEY1085MainframeMFTMFT1086DOCKDOCKDOCK1087Bit ConnectBCCBCC1088VENVENVEN1089Red PulseRPXRPX1090RENRENREN1091EthosBQXBQX1092BnkToTheFutureBFTBFT1093FSNFSNFSN1094MatrixMANMAN1095GnosisGNOGNO1096MelonMLNMLN1097NamecoinNMCNMC1098VertcoinVTCVTC1099BurstBURSTBURST1830Steem DollarsSTEEMDSBD1332BitTorrentBTTBTT1839PrimecoinXPMXPM1838CounterpartyXCPXCP1837Pascal CoinPASCPASC1836NumeraireNMRNMR1833GameCreditsGAMEGAME1832FOAMFOAMFOAM1831ClamsCLAMCLAM1835LBRY CreditsLBCLBC1829StableUSDUSDSUSDS1823STASIS EURSEURSEURS1824UTRUSTUTKUTK1825CortexCTXCCTXC1827Project PaiPAIPAI1828SmartMeshSMTSMT1810PropyPROPRO1811DigitalNoteXDNXDN1812CrypteriumCRPTCRPT1813AragonANTANT1814BLOCKvVEEVEE1821Ontology GasONGONG1816PumaPayPMAPMA1817IgnisIGNISIGNIS1819EdgelessEDGEDG1822Fetch.AIFETFET1815BlocknetBLOCKBLOCK1809TokenCardTKNTKN1806DATADTADTA1797Genaro NetworkGNXGNX1805Jibrel NetworkJNTJNT1804All SportsSOCSOC1803LympoLYMLYM1802BlocktixTIXTIX1801CredLBALBA1799Content Neutrality NetworkCNNCNN1798PentaPNTPNT1808AchainACTACT1796Unikoin GoldUKGUKG1794GrinGRINGRIN1793HUSD SolutionHUSDHUSD1738SaluSSLSSLS1750DetherDTHDTH1735Quantum Resistant LedgerQRLQRL1739MediBloc [ERC20]MEDXMEDX1737DMarketDMTDMT1740EinsteiniumEMC2EMC21747Callisto NetworkCLOCLO1743AuctusAUCAUC1744Banyan NetworkBBNBBN1745Bitcoin InterestBCIBCI1746CommerceBlockCBTCBT1734ParticlPARTPART1749Digix Gold TokenDGXDGX1742AidCoinAIDAID1733Crypto.com ChainCROCRO1727UbiqUBQUBQ1731NKNNKNNKN1730Moss CoinMOCMOC1729WhiteCoinXWCXWC1728FLOFLOFLO1726RefereumRFRRFR1725IHT Real Estate ProtocolIHTIHT1723BitBayBAYBAY1722HydroHYDROHYDRO1721VITEVITEVITE1720MetronomeMETMET1719CashBet CoinCBCCBC1718ZClassicZCLZCL1717MobiusMOBIMOBI1732QuantQNTQNT1751EssentiaESSESS1790AtonomiATMIATMI1754Internet Node TokenINTINT1791The AbyssABYSSABYSS1715MercuryMERMER1789ContentBoxBOXBOX1787Hydro ProtocolHOTPHOT1786V YggdrashYEEDYEED1785V SystemsVSYSVSYS1783UniversaUTNPUTNP1782SpankChainSPANKSPANK1781SEERSEERSEER1779RSK Smart BitcoinRBTCRBTC1778BlockpassPASSPASS1775ORS GroupORSGORS1774OmniOMNIOMNI1773AutonioANIONIO1772MedicalchainMTNMTN1771EveripediaIQIQ1770Tether EuroEURTEURt1769DADIDADIDADI1768CreditsCSCS1767Recovery Right TokensRRTRRT17660ChainZCNZCN1765XribaXRAXRA1763WOLLOWLOWLO1762VetriVLDVLD1761ConsensusSENSEN1759Rate3RTERTE1758RIF TokenRIFRIF1757KlerosPNKPNK1755On.LiveONLONL1753ParkinGoGOTGOT1714Sentinel ProtocolUPPUPP1653OriginTrailTRACTRAC1712PotCoinPOTPOT1668DynamicDYNDYN1667ExclusiveCoinEXCLEXCL16662GIVE2GIVE2GIVE1665SyndicateSYNXSYNX1664PinkCoinPINKPINK1663VeriumReserveVRMVRM1662Internet of PeopleIOPIOP1661DopeCoinDOPEDOPE1660Memetic / PepeCoinMEMEMEME1659TransferCoinTXTX1658SequenceSEQSEQ1657BreakoutBRKBRK1656CannabisCoinCANNCANN1655eBoostEBSTEBST1713BlackCoinBLKBLK1652AeonAEONAEON1651NoLimitCoinNLC2NLC21650NAGANGCNGC1648DECENTDCTDCT1647HyperSpaceAMPAMP1645HumaniqHMQHMQ1644MatchpoolGUPGUP1640BANKEXBKXBKX1639PatientoryPTOYPTOY1638Swarm CitySWTSWT1637SIBCoinSIBSIB1636NexiumNXCNXC1633Crowd MachineCMCTCMCT1632Ink ProtocolXNKXNK1669ArtByteABYABY1670FoldingCoinFLDCFLDC1649SpaceChainSPCSPC1672GeoCoinGEOGEO1711adTokenADTADT1709ShiftSHIFTSHIFT1708FeathercoinFTCFTC1707HempCoinTHCTHC1701BitTubeTUBETUBE1700IONIONION1699UpTokenUPUP1698XELXELXEL1697RevolutionVRRVRRVR1696IncentINCNTINCNT1695VeriCoinVRCVRC1671KoreKOREKORE1693RadiumRADSRADS1692CrownCRWCRW1691Bean CashBITBBITB1680SolarCoinSLRSLR1688DiamondDMDDMD1687MyriadXMYXMY1686MonetaryUnitMUEMUE1685GridCoinGRCGRC1684Haven ProtocolXHVXHV1683Decision TokenHSTHST1681BloomBLTBLT1689I/O CoinIOCIOC1679CurecoinCURECURE1677Blockparty (BOXX Token)BOXXBOXX1676GolosGOLOSGOLOS1675MusicoinMUSICMUSIC1674OKCashOKOK1673ExpanseEXPEXP16311BG1BG1BG1630Atlas ProtocolATPATP1628BitMart TokenBMXBMX1629Bitcoin HDXHDBHD1626Time Space ChainTSCTSC1627BerithBRTBRT1625WoChainWOCWOC1623Celer NetworkCELRCELR1622Ether Kingdoms TokenIMPIMP1621MaecenasARTART1619VeriblockVBKVBK1618PlayChipPLAPLA1617OrbsORBSORBS1614TTC ProtocolTTCTTC1615ForestingPTONPTON1616PCHAINPIPI1612AnkrANKRANKR1613AergoAERGOAERGO1611GoldCoinGLCGLC1610MetadiumMETAMETA1609SpendcoinSPNDSPND1607BTU ProtocolBTUBTU1605PAL NetworkPALPAL1606Solve.CareSOLVESOLVE1602SphereSPHRSPHR1603ServeSERVSERV1597Circuits of ValueCOVALCOVAL1599Breakout StakeBRXBRX1601BitswiftBITSBITS1596Golos GoldGBGGBG1595DatabitsDTBDTB1594EverGreenCoinEGCEGC1587QwarkQWARKQWARK1588NeosCoinNEOSNEOS1589NuBitsNBTNBT1591More CoinMOREMORE1592HxroHXROHXRO1593GambitGAMGAM1584StealthXSTXST1585TokesTKSTKS1582GuldenCNLGNLG1583BitSendCBSDBSD1581HunterCoinHUCHUC1580LivepeerLPTLPT1579BORABORABORA1577STACSSTACSSTACS1576HOT TokenHOTTHOT1575DreamTeamDREAMDREAM1574TOPTOPNTOP1568Machine Xchange CoinMXCMXC1569COVACOVACOVA1570LambdaLAMBLAMB1571Content Value NetworkCVNTCVNT1572RuffRUFFRUFF1573LinkEyeLETLET1567Huobi Pool TokenHPTHPT1565InvestDigitalIDTIDT1564TripioTRIOTRIO1563Davinci CoinDACDAC1556ThingsOperatingSystemTOSTOS1557Globalvillage EcosystemGVEGVE1559NeuroChainNCCNCC1560KcashKCASHKCASH1561CVCoinCVNCVN1562BitCapitalVendorBCVBCV1551Yuan Chain CoinYCCYCC1552BitUP TokenBUTBUT1553SmartshareSSPSSP1555MyTokenMTMT1550U NetworkUUUUUU1549GET ProtocolGETPGET1546DATxDATXDATX1547ThemisGETGET1540XMaxXMXXMX1541YouLive CoinUCUC1542Acute Angle CloudAACAAC1543SeeleSEELESEELE1544UnlimitedIPUIPUIP1545LitexLXTLXT1537FansTimeFTIFTI1538Global Social ChainGSCGSC1539Promotion CoinPCPC1534BeeKanBKBTBKBT1536Game.comGTCGTC1531EDUCareEKTEKT1535FairGameFAIRFAIR1527Intelligent Investment ChainIICIIC1529ShineChainSHESHE1530MEXMEXMEX1525BitcoinXBCXBCX1522QunQunQUNQUN1523EduCoinEDUEDU1526HitChainHITHIT1521STKSTKSTK1520SunContractSNCSNC1519DeepBrain ChainDBCDBC1517YEEYEEYEE1518EchoLinkEKOEKO1513ZillaZLAZLA1514ArcblockABTABT1515MatryxMTXMTX1511BitKanKANKAN1506TopChainTOPCTOPC1507CoinMeetMEETMEET1508SwftCoinSWFTCSWFTC1509MediSharesMDSMDS1510IoT ChainITCITC1503Super BitcoinSBTCSBTC1505Bitcoin FileBIFIBIFI1502AI DoctorAIDOCAIDOC1501EngineEGCCEGCC1500IRIS NetworkIRISIRIS1499DatumDATDAT1497RCCCRCCCRCCC1495PortalPORTALPORTAL1494MuskMUSKMUSK1493Block 1818C18C1492ZJLT Distributed Factoring NetworkZJLTZJLT1491MARK.SPACEMRKMRK1490AdHiveADHADH1479FLIPFLPFLP1489Dragon CoinsDRGDRG1481FarmaTrustFTTFTT1482LikeCoinLIKELIKE1483Morpheus LabsMITXMITX1485StoxSTXSTX1486ZPERZPRZPR1487FintruX NetworkFTXFTX1488Plus-CoinNPLCNPLC1477Huobi 10 IndexHB10HB101476ObsidianODNODN1472PitchPITCHPITCH1473Purple Butterfly TradingPBTTPBTT1475OpusOPTOPT1474PatronPATPAT1471LampixPIXPIX1469PlaykeyPKTPKT1468PolybiusPLBTPLBT1467PillarPLRPLR1466PlutonPLUPLU1465PaymonPMNTPMNT1464PresearchPREPRE1463ProCurrencyPROCPROC1843BitRentRNTBRNTB1842imbrexREXREX1844RobotinaROXROX1461PlayGamePXGPXG1460Quanta Utility TokenQNTUQNTU1847SentinelSENTSENT1848ShipChainSHIPSHIP1845RivetzRVTRVT1846SociallSCLSCL1849Signal TokenSIGSIG1850SilkChainSILKSILK1851SlateSLXSLX1852SmartCashSMARTSMART1853SnowballSNBLSNBL1854SPINDLESPDSPD1855SportyCoSPFSPF1856StarbaseSTARSTAR1857StoriqaSTQSTQ1859SunchainSUNCSUNC1861SuretlySURSUR1867TrueDeckTDPTDP1866LamdenTAUTAU1863savedroidSVDSVD1864SwarmSWMSWM1865TaaSTAASTAAS1873TrueChainTRUETRUE1868TokenDeskTDSTDS1869TelcoinTELTEL1870ChronobankTIMETIME1871TradcoinTRADTRAD1872WeTrustTRSTTRST1876United Traders TokenUTTUTT1878Provoco TokenVOCOVOCO1874Useless Ethereum TokenUETUET1875Usechain TokenUSEUSE1877VeriMEVMEVME1879Wiki TokenWIKIWIKI1880CrowdWizWIZWIZ1881XaurumXAURXAUR1883BlitzPredictXBPXBP1884Monero ClassicXMCXMC1885Exchange UnionXUCXUC1887ZapZAPZAP1888ZeepinZPTZPT1889ZrCoinZRCZRC1890ZeusshieldZSCZSC2000ATLANT TokenATLATL2003BetterBettingBETRBETR2002BerryBERRYBERRY2001BANCABANCABANCA2004BitClaveCATCAT2005BitcoreBTXBTX2006BitDegreeBDGBDG2007BitDiceCSNOCSNO2008Black MoonBMCBMC2009BlockMeshBMHBMH2010CashaaCASCAS2011CoinPokerCHPCHP2014Crypto20C20C202012COPYTRACKCPYCPY2013CovestingCOVCOV2017Curriculum VitaeCVHCVH2015CryptopayCPAYCPAY2016CUBEAUTOAUTO2018CyberVeinTokenCVTCVT2019DAO CasinoBETBET2020DecentBetDBETDBET2021DIMCOINDIMDIM2022EtherollDICEDICE2023First Blood1ST1ST2024FortunaFOTAFOTA2025GoByteGBXGBX2026HappycoinHPCHPC2027Hive ProjectHVNHVN2031iXledgerIXTIXT2030InsurePalIPLIPL2028indaHashIDHIDH2029InsurChainINSURINSUR2032KickCoinKICKKICK2033KINKINKIN2034LATokenLALA2035LifeLIFELIFE2036LockTripLOCLOC2037MeshBoxMESHMESH2038Micro MoneyAMMAMM2039MybitMYBMYB2040NectarNCTNCT2041NeumarkNEUNEU2045Freyr ChainFRECFREC2043SwissBorgCHSBCHSB2042NOAHCOINNOAHNOAH2044AlphacatACATACAT2046ConsentiumCSMCSM2047NanjcoinNANJNANJ2048NeuroTokenNTKNTK2049FuzeXFXTFXT2050ChainiumCHXCHX2051FriendZ CoinFDZFDZ2056InkINKINK2054Banker TokenBNKBNK2055KaratBank CoinKBCKBC2052CryptaurCPTCPT2053HTMLCOINHTMLHTML2057Colu Local NetworkCLNCLN2058LitecoinCashLCCLCC2059ElectrifyAsiaELECELEC2060BitRewardsBITBIT2061CosmoCoinCOSMCOSM2062Kind AdsKINDKIND2063InmediateDITDIT2064CyCleanCCLCCL2065NimiqNIMNIM2067EcosBallABAABA2066AML BitcoinABTCABTC2068MesseMESSEMESSE2072MarginlessMRSMRS2071Acorn Collective TokenOAKOAK2069AXpireAXPRAXPR2070ConstellationDAGDAG2073Dynamic Trading RightsDTRDTR1892BOX TokenBOXTBOX1893BitcoinusBITSSBITS18951World1WO1WO1896AMLTAMLTAMLT1897BiotronBTRNBTRN1898CanYaCoinCANCAN1899XAYACHICHI1900DACSEEDACSDACS1908IP ExchangeIPSXIPSX1907Invictus Hyperion FundIHFIHF1906GazeCoinGZEGZE1903EZTokenEZTEZT1904FlixxoFLIXXFLIXX1902Earth TokenEARTHEARTH1905DAOstackGENGEN1909KryllKRLKRL1910LALA WorldLALALALA1911SalPaySALSAL1912Signals NetworkSGNSGN1917TokenPayTPAYTPAY1919ProxeusXESXES1916Thrive TokenTHRTTHRT1918UnibrightUBTUBT1914SnipCoinSNIPSNIP1915SophiaTXSPHTXSPHTX1913SIXSIXSIX1920ZebiZCOZCO1921BrylliteBRCBRC1922FidentiaXFDXFDX1923Global Awards TokenGATGAT1924onG.socialONGSONG1925StarterCoinSTACSTAC1929bitJobSTUSTU1928WCoinWINWIN1930CosmosATOMATOM1926TeleportTPTTPT1927TaTaTuTTUTTU1931XNDXNDXND1932SCRLSCRLSCR1933UGASUGASUGAS1934Matic NetworkMATICMATIC1935Wrapped BitcoinWBTCWBTC1936CryptoFrancXCHFXCHF1937Function XFXFX1938OceanOCEANOCEAN1939XYOXYOXYO1940WibsonWIBWIB1941Blue Whale TokenBWXBWX1942Newton ProjectNEWNEW1944ThunderCoreTTTT1945OKBOKBOKB1954YOU COINYOUYOU1965AschXASXAS1966EgretiaEGTEGT1967High Performance BlockchainHPBHPB1982Measurable Data TokenMDTMDT1983ugChainUGCUGC1987DelphyDPYDPY1988SelfSellSSCSSC1989PrimasPSTPST1991ZipperZIPZIP1992CIChainCICCIC1993ChronologicDAYDAY1994DaneelDANDAN1995DomRaider TokenDRTDRT1996Indorse TokenINDIND2074Helbiz TokenHBZHBZ2075Morpheus NetworkMORPHMORPH2076SynthetixSNXSNX2077Synthetix sUSDSUSDSUSD2078LEO TokenLEOLEO2079Vodi XVDXVDX2080Reserve Rights TokenRSRRSR1100Red Pulse Phoenix BinancePHBPHB1101Theta FuelTFUELTFUEL1102ZBTokenZBZB1103UpfiringUFRUFR1129Cai TokenCAICAI1105WinTokenWINTWINT1106Origin SportORSORS1107HYCONHYCHYC1130AirblocABLABL1109BlockcloudBLOCBLOC1110ACE (TokenStars)ACEACE1111Molecular FutureMOFMOF1112TokenClubTCTTCT1113StarChainSTCSTC1114LightChainLIGHTLIGHT1115OFCOINOFOF1131Hi Mutual SocietyHMCHMC1117Beauty ChainBECBEC1118MerculetMVPMVP1119SDChainSDASDA1120ProChainPRAPRA1121OneRoot NetworkRNTRNT1122RealChainRCTRCT1123RefTokenREFREF1133Ubique Chain Of ThingsUCTUCT1125United BitcoinUBTCUBTC1126ShowSHOWSHOW1127Olympus LabsMOTMOT1128IPChainIPCIPC1134OrigoOGOOGO1135HarmonyONEONE1137USDKUSDKUSDK2081BeaxyBXYBXY2082FantomFTMFTM2083AlgorandALGOALGO2084V-IDVIDTVIDT2085VideoCoinVIDVID2086EnergiNRGNRG2087Dusk NetworkDUSKDUSK2088WINkWINKWINK2089WirexWXTWXT2090Bitcoin BEP2BTCBBTCB2091StableUSD BEP2USDSBUSDSB2092ElrondERDERD2093Binance GBP Stable CoinBGBPBGBP2094ContentosCOSCOS2095TrueUSD BEP2TUSDBTUSDB2096Cocos-BCXCOCOSCOCOS2097TomoChainTOMOTOMO2098PerlinPERLPERL2099ChilizCHZCHZ2100AmpleforthAMPLAMPL2101GateChainTokenGTGT2102UltraUOSUOS2103rrbRRBRRB2104Dragon TokenDTDT2105BeamBEAMBEAM2106Tether CNHCNHTCNHT2107AlliveALVALV2108VNT ChainVNTVNT2109En-Tan-MoETMETM2110EminerEMEM2111EchoinECEC2112PledgecampPLGPLG2113X-Power ChainXPOXPO2114FTX TokenFTTXFTTX2115AkropolisAKROAKRO2116Skrumble NetworkSKMSKM2118Crypto Neo-value Neural SystemCNNSCNNS2117PivotPVTPVT2119BHEX TokenBHTBHT2120CarryCRECRE2121ARPA ChainARPAARPA2123Force ProtocolFORFOR2122VidyCoinVIDYVIDY2124RedFOX LabsRFOXRFOX2125CelsiusCELCEL2126AnchorANCTANCT2127Standard Tokenization ProtocolSTPTSTPT2128Contents ProtocolCPTLCPTL2129PrometeusPROMPROM2130FlexacoinFXCFXC2131SPIN ProtocolSPINSPIN2132ChromiaCHRCHR2133PixelPXLPXL2134HedgeTradeHEDGHEDG2135Morpheus.NetworkMRPHMRPH2136Hedera HashgraphHBARHBAR2137Band ProtocolBANDBAND2138Bitpanda Ecosystem TokenBESTBEST2139PantosPANPAN2140Binance USDBUSDBUSD2141Infinitus TokenINFINF \ No newline at end of file From ee512454e57077ed8c7b6d31b6b68a62c4d0b26c Mon Sep 17 00:00:00 2001 From: Alex Karpovich Date: Wed, 30 Oct 2019 15:01:23 +0300 Subject: [PATCH 2173/2572] [-] CI fix --- .gitlab-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 356bd323..2af616f2 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -39,7 +39,7 @@ cache: "Build: Java 8": stage: build - image: packages.deltixhub.com:443/gitlabci.docker/openjdk-jdk-11-gradle-5.2.1:latest + image: packages.deltixhub.com:443/gitlabci.docker/openjdk-11-gradle-5.2.1:latest script: - git checkout origin/pipeline-$CI_PIPELINE_ID~1 || true - ./gradlew build test --no-daemon @@ -72,7 +72,7 @@ cache: "Publish: Java 8": stage: publish - image: packages.deltixhub.com:443/gitlabci.docker/oracle-jdk-8-gradle-4.10.1:latest + image: packages.deltixhub.com:443/gitlabci.docker/openjdk-11-gradle-5.2.1:latest script: - git checkout origin/pipeline-$CI_PIPELINE_ID~1 - ./gradlew publish From d72ddd2f9143b5fe45079df6e2198de549524cc5 Mon Sep 17 00:00:00 2001 From: Robot Date: Wed, 30 Oct 2019 12:02:09 +0000 Subject: [PATCH 2174/2572] [Skip CI] Generate release version --- gradle.properties | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gradle.properties b/gradle.properties index ec1d0a46..ca42596a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ -#Tue Oct 15 08:34:05 UTC 2019 +#Wed Oct 30 12:02:09 UTC 2019 dfpVersion=0.10.7 -version=5.4.1-SNAPSHOT +version=5.4.1 deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java -hdTimeVersion=0.2.4 \ No newline at end of file +hdTimeVersion=0.2.4 From 7167e702987f3b78448d07539bd30b7de7d87c19 Mon Sep 17 00:00:00 2001 From: Robot Date: Wed, 30 Oct 2019 12:02:18 +0000 Subject: [PATCH 2175/2572] [Skip CI] Generate next development version --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index ca42596a..76e8e188 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ -#Wed Oct 30 12:02:09 UTC 2019 +#Wed Oct 30 12:02:17 UTC 2019 dfpVersion=0.10.7 -version=5.4.1 +version=5.4.2-SNAPSHOT deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java hdTimeVersion=0.2.4 From 89774c879d1f6c9b2efb840232a8366e7ddaa104 Mon Sep 17 00:00:00 2001 From: Alex Karpovich Date: Wed, 30 Oct 2019 16:12:26 +0300 Subject: [PATCH 2176/2572] [*] jna version change --- util/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/util/build.gradle b/util/build.gradle index 58aa2a9d..2314e306 100644 --- a/util/build.gradle +++ b/util/build.gradle @@ -23,8 +23,8 @@ dependencies { //compile 'org.glassfish.jaxb:jaxb-runtime:2.2.11' // Glassfish replaces JAXB RI //compile('javax.xml:jsr173:1.0'){ transitive = false } - compile('net.java.dev.jna:jna:5.4.0'){ transitive = false } - compile('net.java.dev.jna:jna-platform:5.4.0'){ transitive = false } + compile('net.java.dev.jna:jna:4.2.1'){ transitive = false } + compile('net.java.dev.jna:jna-platform:4.2.1'){ transitive = false } compile('org.apache.bcel:bcel:6.0'){ transitive = false } } From 1135ca42d9bfa34ca5c52d4bdecf7f2f4b31b547 Mon Sep 17 00:00:00 2001 From: Robot Date: Wed, 30 Oct 2019 13:13:18 +0000 Subject: [PATCH 2177/2572] [Skip CI] Generate release version --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 76e8e188..b5b9dd68 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ -#Wed Oct 30 12:02:17 UTC 2019 +#Wed Oct 30 13:13:18 UTC 2019 dfpVersion=0.10.7 -version=5.4.2-SNAPSHOT +version=5.4.2 deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java hdTimeVersion=0.2.4 From 5a8eea4a21a3a9bb8ef0203c554bcd416831862b Mon Sep 17 00:00:00 2001 From: Robot Date: Wed, 30 Oct 2019 13:13:27 +0000 Subject: [PATCH 2178/2572] [Skip CI] Generate next development version --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index b5b9dd68..cd5818ba 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ -#Wed Oct 30 13:13:18 UTC 2019 +#Wed Oct 30 13:13:27 UTC 2019 dfpVersion=0.10.7 -version=5.4.2 +version=5.4.3-SNAPSHOT deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java hdTimeVersion=0.2.4 From eb1771a674fe7f243b9ef0a005a18d66991090f5 Mon Sep 17 00:00:00 2001 From: Andy Malakov Date: Wed, 30 Oct 2019 15:19:12 -0400 Subject: [PATCH 2179/2572] removed :443 from docker image urls --- .gitlab-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f9203c45..cfaa2997 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -39,7 +39,7 @@ cache: "Build: Java 8": stage: build - image: packages.deltixhub.com:443/gitlabci.docker/oracle-jdk-8-gradle-4.10.1:latest + image: packages.deltixhub.com/gitlabci.docker/oracle-jdk-8-gradle-4.10.1:latest script: - git checkout origin/pipeline-$CI_PIPELINE_ID~1 || true - ./gradlew build test --no-daemon @@ -72,7 +72,7 @@ cache: "Publish: Java 8": stage: publish - image: packages.deltixhub.com:443/gitlabci.docker/oracle-jdk-8-gradle-4.10.1:latest + image: packages.deltixhub.com/gitlabci.docker/oracle-jdk-8-gradle-4.10.1:latest script: - git checkout origin/pipeline-$CI_PIPELINE_ID~1 - ./gradlew publish From 58388a2d63640af073c2a1cb95cf6e8bca77e54b Mon Sep 17 00:00:00 2001 From: Andy Malakov Date: Wed, 30 Oct 2019 19:50:55 -0400 Subject: [PATCH 2180/2572] Updated velocity plugin in preparation for check-dependency plugin use (which also use velocity of higher version) --- collections/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/collections/build.gradle b/collections/build.gradle index bd6d781e..6183a02d 100644 --- a/collections/build.gradle +++ b/collections/build.gradle @@ -3,7 +3,7 @@ description = 'QuantServer commons-collections set of utilities' // This repository provides velocity plugin buildscript { dependencies { - classpath group: 'deltix.gradle.plugins', name: 'velocity', version: '1.0.0' + classpath group: 'deltix.gradle.plugins', name: 'velocity', version: '1.2.1' } } apply plugin: 'velocity' From 9c839df39e90713614339dbd0deba5906555cb1c Mon Sep 17 00:00:00 2001 From: Andy Malakov Date: Wed, 30 Oct 2019 19:52:31 -0400 Subject: [PATCH 2181/2572] Added dependency check plugin (will be used by scheduled pipeline) --- .gitlab-ci.yml | 36 +++++++++++++++++++++++++++ build.gradle | 21 ++++++++++++++++ dependency-check-suppression-file.xml | 9 +++++++ 3 files changed, 66 insertions(+) create mode 100644 dependency-check-suppression-file.xml diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index cfaa2997..df64ea5a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,6 +1,7 @@ stages: - prepare - build + - test - release - publish - clean-up @@ -51,6 +52,41 @@ cache: except: - tags +#"Test": +# image: packages.deltixhub.com/gitlabci.docker/oracle-jdk-8-gradle-4.10.1:latest +# stage: test +# script: +# - ./gradlew check --parallel +# cache: +# key: "$CACHE_KEY" +# paths: +# - .gradle/wrapper +# - .gradle/caches +# - ember/monitor/frontend/node_modules +# - ember/monitor/frontend/.gradle +# policy: pull-push +# except: +# - /^release-.*$/ +# tags: +# - Linux +# - DockerExecutor +# - Natick + + +dependency-check: + stage: test + image: packages.deltixhub.com/gitlabci.docker/oracle-jdk-8-gradle-4.10.1:latest + only: + - schedules + script: + - ./gradlew :dependencyCheckAggregate + artifacts: + name: "${CI_JOB_ID}_${CI_JOB_NAME}" + when: always + expire_in: 30 day + paths: + - build/reports/dependency-check-report.html + "Release": stage: release script: diff --git a/build.gradle b/build.gradle index f232de65..db67e9fe 100644 --- a/build.gradle +++ b/build.gradle @@ -1,3 +1,12 @@ +buildscript { + repositories { + mavenCentral() + } + dependencies { + classpath 'org.owasp:dependency-check-gradle:5.2.2' + } +} + plugins { // Supports functionality similar to Maven BOM. // Helps to avoid re-declaring dependency version in each subproject. @@ -227,6 +236,18 @@ configure(leafProjects) { setIncludeCategories categories.split(',').collect { "deltix.util.CommonsJUnitCategories\$${it}".toString() } as Set } } + + // See http://jeremylong.github.io/DependencyCheck/dependency-check-gradle + apply plugin: 'org.owasp.dependencycheck' + + dependencyCheck { + // skipProjects = nonJavaProjects + failBuildOnCVSS = 7 + suppressionFile = file("$rootDir/dependency-check-suppression-file.xml") + analyzers { + assemblyEnabled = false + } + } } def testTasks = ext.leafProjects*.test diff --git a/dependency-check-suppression-file.xml b/dependency-check-suppression-file.xml new file mode 100644 index 00000000..20665c3b --- /dev/null +++ b/dependency-check-suppression-file.xml @@ -0,0 +1,9 @@ + + + + + 7 + + \ No newline at end of file From 3fe7a71fb42f1cbe41a0d1c9ee458ba33e152d39 Mon Sep 17 00:00:00 2001 From: Robot Date: Wed, 30 Oct 2019 23:53:01 +0000 Subject: [PATCH 2182/2572] [Skip CI] Generate release version --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 8dfd896f..baaddca0 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ -#Tue Oct 15 08:34:05 UTC 2019 +#Wed Oct 30 23:53:01 UTC 2019 dfpVersion=0.10.7 -version=5.2.57-SNAPSHOT +version=5.2.57 deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java hdTimeVersion=0.2.4 From 5b40df211f63dab7ac1e80596a5134792e169643 Mon Sep 17 00:00:00 2001 From: Robot Date: Wed, 30 Oct 2019 23:53:09 +0000 Subject: [PATCH 2183/2572] [Skip CI] Generate next development version --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index baaddca0..2fd43b5e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ -#Wed Oct 30 23:53:01 UTC 2019 +#Wed Oct 30 23:53:09 UTC 2019 dfpVersion=0.10.7 -version=5.2.57 +version=5.2.58-SNAPSHOT deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java hdTimeVersion=0.2.4 From a8ea72b1016e23f77971a6b88d95ce030e22ce12 Mon Sep 17 00:00:00 2001 From: Andy Malakov Date: Thu, 31 Oct 2019 08:34:58 -0400 Subject: [PATCH 2184/2572] Added dependency check plugin (will be used by scheduled pipeline) --- build.gradle | 3 +++ 1 file changed, 3 insertions(+) diff --git a/build.gradle b/build.gradle index db67e9fe..3c38ab57 100644 --- a/build.gradle +++ b/build.gradle @@ -237,6 +237,9 @@ configure(leafProjects) { } } +} + +allProjects { // See http://jeremylong.github.io/DependencyCheck/dependency-check-gradle apply plugin: 'org.owasp.dependencycheck' From 8e1283b4db07f12ef2bf66db7663e2e8e06c2bc4 Mon Sep 17 00:00:00 2001 From: Andy Malakov Date: Thu, 31 Oct 2019 08:38:44 -0400 Subject: [PATCH 2185/2572] Added dependency check plugin (will be used by scheduled pipeline) --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 3c38ab57..8548590c 100644 --- a/build.gradle +++ b/build.gradle @@ -239,7 +239,7 @@ configure(leafProjects) { } -allProjects { +allprojects { // See http://jeremylong.github.io/DependencyCheck/dependency-check-gradle apply plugin: 'org.owasp.dependencycheck' From 7895d6abc91bc5b1af0515dad210a1584922261b Mon Sep 17 00:00:00 2001 From: Andy Malakov Date: Thu, 31 Oct 2019 08:39:35 -0400 Subject: [PATCH 2186/2572] Added dependency check plugin (will be used by scheduled pipeline) --- .gitlab-ci.yml | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index df64ea5a..0757d70c 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -52,27 +52,6 @@ cache: except: - tags -#"Test": -# image: packages.deltixhub.com/gitlabci.docker/oracle-jdk-8-gradle-4.10.1:latest -# stage: test -# script: -# - ./gradlew check --parallel -# cache: -# key: "$CACHE_KEY" -# paths: -# - .gradle/wrapper -# - .gradle/caches -# - ember/monitor/frontend/node_modules -# - ember/monitor/frontend/.gradle -# policy: pull-push -# except: -# - /^release-.*$/ -# tags: -# - Linux -# - DockerExecutor -# - Natick - - dependency-check: stage: test image: packages.deltixhub.com/gitlabci.docker/oracle-jdk-8-gradle-4.10.1:latest From 772baf72398eb9640c89f20f24989835dedb3463 Mon Sep 17 00:00:00 2001 From: Robot Date: Thu, 31 Oct 2019 12:39:58 +0000 Subject: [PATCH 2187/2572] [Skip CI] Generate release version --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 2fd43b5e..6eea7d93 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ -#Wed Oct 30 23:53:09 UTC 2019 +#Thu Oct 31 12:39:58 UTC 2019 dfpVersion=0.10.7 -version=5.2.58-SNAPSHOT +version=5.2.58 deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java hdTimeVersion=0.2.4 From efdd892ca51b52319985e86d1063684b65e1b28f Mon Sep 17 00:00:00 2001 From: Robot Date: Thu, 31 Oct 2019 12:40:06 +0000 Subject: [PATCH 2188/2572] [Skip CI] Generate next development version --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 6eea7d93..42e35952 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ -#Thu Oct 31 12:39:58 UTC 2019 +#Thu Oct 31 12:40:05 UTC 2019 dfpVersion=0.10.7 -version=5.2.58 +version=5.2.59-SNAPSHOT deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java hdTimeVersion=0.2.4 From c565cb851b5d60f177a0c1cdeb0a360cc05ea6e0 Mon Sep 17 00:00:00 2001 From: Robot Date: Thu, 31 Oct 2019 12:46:33 +0000 Subject: [PATCH 2189/2572] [Skip CI] Generate release version --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 42e35952..383568b8 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ -#Thu Oct 31 12:40:05 UTC 2019 +#Thu Oct 31 12:46:33 UTC 2019 dfpVersion=0.10.7 -version=5.2.59-SNAPSHOT +version=5.2.59 deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java hdTimeVersion=0.2.4 From 5a97ebc8df6115cb16b735d43f994637da4fa6b5 Mon Sep 17 00:00:00 2001 From: Robot Date: Thu, 31 Oct 2019 12:46:41 +0000 Subject: [PATCH 2190/2572] [Skip CI] Generate next development version --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 383568b8..e44cb910 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ -#Thu Oct 31 12:46:33 UTC 2019 +#Thu Oct 31 12:46:41 UTC 2019 dfpVersion=0.10.7 -version=5.2.59 +version=5.2.60-SNAPSHOT deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java hdTimeVersion=0.2.4 From 4789195d9fe04cf3119354486fefddfe17b5636b Mon Sep 17 00:00:00 2001 From: Andy Malakov Date: Thu, 31 Oct 2019 11:56:29 -0400 Subject: [PATCH 2191/2572] Spotbug findings https://gitlab.deltixhub.com/Deltix/QuantServer/QuantServer/issues/62 --- .../main/java/deltix/util/io/BasicIOUtil.java | 224 +++++++++--------- util/src/main/java/deltix/util/io/IOUtil.java | 112 ++++----- 2 files changed, 171 insertions(+), 165 deletions(-) diff --git a/util/src/main/java/deltix/util/io/BasicIOUtil.java b/util/src/main/java/deltix/util/io/BasicIOUtil.java index 29d40095..b4d7f74f 100644 --- a/util/src/main/java/deltix/util/io/BasicIOUtil.java +++ b/util/src/main/java/deltix/util/io/BasicIOUtil.java @@ -1569,20 +1569,21 @@ else if (c > 0x07FF) { * Reads (appends) a UTF string to an Appendable (such as StringBuidler), * without clearing it first. */ + @Deprecated // buggy public final static void readUTF(DataInput in, Appendable sb) throws IOException { int utflen = in.readUnsignedShort(); if (utflen == 0) return; - int c = -2; + int c; int char2, char3; int count = 0; for (;;) { - c = in.readByte (); - if (c > 127) - break; + c = in.readByte (); //NB: result in range [-128, 127] -- Andy + //if (c > 127) + // break; count++; sb.append ((char) c); @@ -1590,77 +1591,79 @@ public final static void readUTF(DataInput in, Appendable sb) throws IOException if (count >= utflen) return; } - // If we are here, we have broken out of the previous loop and there is an - // unhandled escape character in variable c. - for (;;) { - switch (c >> 4) { - case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: - /* 0xxxxxxx*/ - count++; - sb.append ((char)c); - break; - - case 12: case 13: - /* 110x xxxx 10xx xxxx*/ - count += 2; - if (count > utflen) - throw new UTFDataFormatException( - "malformed input: partial character at end"); - char2 = in.readByte (); - if ((char2 & 0xC0) != 0x80) - throw new UTFDataFormatException( - "malformed input around byte " + count); - sb.append ((char)(((c & 0x1F) << 6) | - (char2 & 0x3F))); - break; - - case 14: - /* 1110 xxxx 10xx xxxx 10xx xxxx */ - count += 3; - if (count > utflen) - throw new UTFDataFormatException( - "malformed input: partial character at end"); - char2 = in.readByte (); - char3 = in.readByte (); - if (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80)) - throw new UTFDataFormatException( - "malformed input around byte " + (count-1)); - sb.append ((char)(((c & 0x0F) << 12) | - ((char2 & 0x3F) << 6) | - ((char3 & 0x3F) << 0))); - break; - - default: - /* 10xx xxxx, 1111 xxxx */ - throw new UTFDataFormatException( - "malformed input around byte " + count); - } - - if (count >= utflen) - break; - - c = in.readByte (); - } +// de-facto unreachable -- Andy +// // If we are here, we have broken out of the previous loop and there is an +// // unhandled escape character in variable c. +// for (;;) { +// switch (c >> 4) { +// case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: +// /* 0xxxxxxx*/ +// count++; +// sb.append ((char)c); +// break; +// +// case 12: case 13: +// /* 110x xxxx 10xx xxxx*/ +// count += 2; +// if (count > utflen) +// throw new UTFDataFormatException( +// "malformed input: partial character at end"); +// char2 = in.readByte (); +// if ((char2 & 0xC0) != 0x80) +// throw new UTFDataFormatException( +// "malformed input around byte " + count); +// sb.append ((char)(((c & 0x1F) << 6) | +// (char2 & 0x3F))); +// break; +// +// case 14: +// /* 1110 xxxx 10xx xxxx 10xx xxxx */ +// count += 3; +// if (count > utflen) +// throw new UTFDataFormatException( +// "malformed input: partial character at end"); +// char2 = in.readByte (); +// char3 = in.readByte (); +// if (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80)) +// throw new UTFDataFormatException( +// "malformed input around byte " + (count-1)); +// sb.append ((char)(((c & 0x0F) << 12) | +// ((char2 & 0x3F) << 6) | +// ((char3 & 0x3F) << 0))); +// break; +// +// default: +// /* 10xx xxxx, 1111 xxxx */ +// throw new UTFDataFormatException( +// "malformed input around byte " + count); +// } +// +// if (count >= utflen) +// break; +// +// c = in.readByte (); +// } } /** * Reads (appends) a UTF string to an Appendable (such as StringBuidler), * without clearing it first. */ + @Deprecated // buggy public final static void readUTF(ByteBuffer in, Appendable sb) throws BufferUnderflowException, IOException { int utflen = 0xFFFF & in.getShort(); if (utflen == 0) return; - int c = -2; + int c; int char2, char3; int count = 0; for (;;) { - c = in.get (); - if (c > 127) - break; + c = in.get (); //NB: result in range [-128, 127] -- Andy +// if (c > 127) +// break; count++; sb.append ((char) c); @@ -1668,57 +1671,58 @@ public final static void readUTF(ByteBuffer in, Appendable sb) throws BufferUnde if (count >= utflen) return; } - // If we are here, we have broken out of the previous loop and there is an - // unhandled escape character in variable c. - for (;;) { - switch (c >> 4) { - case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: - /* 0xxxxxxx*/ - count++; - sb.append ((char)c); - break; - - case 12: case 13: - /* 110x xxxx 10xx xxxx*/ - count += 2; - if (count > utflen) - throw new UTFDataFormatException( - "malformed input: partial character at end"); - char2 = in.get (); - if ((char2 & 0xC0) != 0x80) - throw new UTFDataFormatException( - "malformed input around byte " + count); - sb.append ((char)(((c & 0x1F) << 6) | - (char2 & 0x3F))); - break; - - case 14: - /* 1110 xxxx 10xx xxxx 10xx xxxx */ - count += 3; - if (count > utflen) - throw new UTFDataFormatException( - "malformed input: partial character at end"); - char2 = in.get (); - char3 = in.get (); - if (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80)) - throw new UTFDataFormatException( - "malformed input around byte " + (count-1)); - sb.append ((char)(((c & 0x0F) << 12) | - ((char2 & 0x3F) << 6) | - ((char3 & 0x3F) << 0))); - break; - - default: - /* 10xx xxxx, 1111 xxxx */ - throw new UTFDataFormatException( - "malformed input around byte " + count); - } - - if (count >= utflen) - break; - - c = in.get (); - } +// de-facto unreachable -- Andy +// // If we are here, we have broken out of the previous loop and there is an +// // unhandled escape character in variable c. +// for (;;) { +// switch (c >> 4) { +// case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: +// /* 0xxxxxxx*/ +// count++; +// sb.append ((char)c); +// break; +// +// case 12: case 13: +// /* 110x xxxx 10xx xxxx*/ +// count += 2; +// if (count > utflen) +// throw new UTFDataFormatException( +// "malformed input: partial character at end"); +// char2 = in.get (); +// if ((char2 & 0xC0) != 0x80) +// throw new UTFDataFormatException( +// "malformed input around byte " + count); +// sb.append ((char)(((c & 0x1F) << 6) | +// (char2 & 0x3F))); +// break; +// +// case 14: +// /* 1110 xxxx 10xx xxxx 10xx xxxx */ +// count += 3; +// if (count > utflen) +// throw new UTFDataFormatException( +// "malformed input: partial character at end"); +// char2 = in.get (); +// char3 = in.get (); +// if (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80)) +// throw new UTFDataFormatException( +// "malformed input around byte " + (count-1)); +// sb.append ((char)(((c & 0x0F) << 12) | +// ((char2 & 0x3F) << 6) | +// ((char3 & 0x3F) << 0))); +// break; +// +// default: +// /* 10xx xxxx, 1111 xxxx */ +// throw new UTFDataFormatException( +// "malformed input around byte " + count); +// } +// +// if (count >= utflen) +// break; +// +// c = in.get (); +// } } public static long addFileToZip (File f, ZipOutputStream zos, String path) diff --git a/util/src/main/java/deltix/util/io/IOUtil.java b/util/src/main/java/deltix/util/io/IOUtil.java index 28b6ff48..e6f8ccd1 100644 --- a/util/src/main/java/deltix/util/io/IOUtil.java +++ b/util/src/main/java/deltix/util/io/IOUtil.java @@ -97,20 +97,21 @@ else if (c > 0x07FF) { * Reads (appends) a UTF string to an Appendable (such as StringBuidler), * without clearing it first. */ + @Deprecated // buggy public final static void readUTF(MemoryDataInput in, Appendable sb) throws IOException { int utflen = in.readUnsignedShort(); if (utflen == 0) return; - int c = -2; + int c; int char2, char3; int count = 0; for (;;) { - c = in.readByte (); - if (c > 127) - break; + c = in.readByte (); //NB: result in range [-128, 127] -- Andy +// if (c > 127) +// break; count++; sb.append ((char) c); @@ -118,57 +119,58 @@ public final static void readUTF(MemoryDataInput in, Appendable sb) throws IOExc if (count >= utflen) return; } - // If we are here, we have broken out of the previous loop and there is an - // unhandled escape character in variable c. - for (;;) { - switch (c >> 4) { - case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: - /* 0xxxxxxx*/ - count++; - sb.append ((char)c); - break; - - case 12: case 13: - /* 110x xxxx 10xx xxxx*/ - count += 2; - if (count > utflen) - throw new UTFDataFormatException( - "malformed input: partial character at end"); - char2 = in.readByte (); - if ((char2 & 0xC0) != 0x80) - throw new UTFDataFormatException( - "malformed input around byte " + count); - sb.append ((char)(((c & 0x1F) << 6) | - (char2 & 0x3F))); - break; - - case 14: - /* 1110 xxxx 10xx xxxx 10xx xxxx */ - count += 3; - if (count > utflen) - throw new UTFDataFormatException( - "malformed input: partial character at end"); - char2 = in.readByte (); - char3 = in.readByte (); - if (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80)) - throw new UTFDataFormatException( - "malformed input around byte " + (count-1)); - sb.append ((char)(((c & 0x0F) << 12) | - ((char2 & 0x3F) << 6) | - ((char3 & 0x3F) << 0))); - break; - - default: - /* 10xx xxxx, 1111 xxxx */ - throw new UTFDataFormatException( - "malformed input around byte " + count); - } - - if (count >= utflen) - break; - - c = in.readByte (); - } +// de-facto unreachable -- Andy +// // If we are here, we have broken out of the previous loop and there is an +// // unhandled escape character in variable c. +// for (;;) { +// switch (c >> 4) { +// case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: +// /* 0xxxxxxx*/ +// count++; +// sb.append ((char)c); +// break; +// +// case 12: case 13: +// /* 110x xxxx 10xx xxxx*/ +// count += 2; +// if (count > utflen) +// throw new UTFDataFormatException( +// "malformed input: partial character at end"); +// char2 = in.readByte (); +// if ((char2 & 0xC0) != 0x80) +// throw new UTFDataFormatException( +// "malformed input around byte " + count); +// sb.append ((char)(((c & 0x1F) << 6) | +// (char2 & 0x3F))); +// break; +// +// case 14: +// /* 1110 xxxx 10xx xxxx 10xx xxxx */ +// count += 3; +// if (count > utflen) +// throw new UTFDataFormatException( +// "malformed input: partial character at end"); +// char2 = in.readByte (); +// char3 = in.readByte (); +// if (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80)) +// throw new UTFDataFormatException( +// "malformed input around byte " + (count-1)); +// sb.append ((char)(((c & 0x0F) << 12) | +// ((char2 & 0x3F) << 6) | +// ((char3 & 0x3F) << 0))); +// break; +// +// default: +// /* 10xx xxxx, 1111 xxxx */ +// throw new UTFDataFormatException( +// "malformed input around byte " + count); +// } +// +// if (count >= utflen) +// break; +// +// c = in.readByte (); +// } } private static final byte [] header = { From d55cbc2501d72e3ee2068e616b935093b8dd082d Mon Sep 17 00:00:00 2001 From: Andy Malakov Date: Thu, 31 Oct 2019 12:01:04 -0400 Subject: [PATCH 2192/2572] Fixed most spotbug findings --- build.gradle | 6 +++- .../util/collections/ReusableObjectPool.java | 2 +- .../util/swing/table/RadioCellRenderer.java | 6 +--- lang/src/main/java/deltix/util/lang/Util.java | 36 +++++++++++-------- .../deltix/util/memory/MemoryDataInput.java | 12 +++---- .../deltix/util/log/gf/LoggerFactory.java | 3 ++ util/build.gradle | 2 -- .../src/main/java/deltix/util/vfs/VFiles.java | 20 +++++------ util/src/main/java/java_cup/lalr_item.java | 3 ++ .../src/main/java/java_cup/reduce_action.java | 5 ++- util/src/main/java/java_cup/shift_action.java | 5 ++- 11 files changed, 56 insertions(+), 44 deletions(-) diff --git a/build.gradle b/build.gradle index 8548590c..e157514b 100644 --- a/build.gradle +++ b/build.gradle @@ -54,7 +54,8 @@ configure(leafProjects) { dependency 'deltix:deltix-thread-affinity:1.0.2' dependency 'commons-lang:commons-lang:2.6' dependency 'javax.mail:mail:1.4.7' - dependency 'com.google.code.findbugs:jsr305:3.0.1' + dependency 'com.google.code.findbugs:jsr305:3.0.2' + dependency 'com.google.code.findbugs:annotations:3.0.1' // dependency 'org.mockito:mockito-core:1.10.19' @@ -86,6 +87,9 @@ configure(leafProjects) { } dependencies { + compileOnly 'com.google.code.findbugs:jsr305' + compileOnly 'com.google.code.findbugs:annotations' + testCompile 'junit:junit:4.12' //'org.mockito:mockito-core:1.10.19' } diff --git a/collections/src/main/java/deltix/util/collections/ReusableObjectPool.java b/collections/src/main/java/deltix/util/collections/ReusableObjectPool.java index ba28222d..c9b7aced 100644 --- a/collections/src/main/java/deltix/util/collections/ReusableObjectPool.java +++ b/collections/src/main/java/deltix/util/collections/ReusableObjectPool.java @@ -88,7 +88,7 @@ public synchronized void close() { @Override protected T createItem() { - return pool.createItem(); + return pool.createItem(); //TODO: NPE? } } } diff --git a/gui/src/main/java/deltix/util/swing/table/RadioCellRenderer.java b/gui/src/main/java/deltix/util/swing/table/RadioCellRenderer.java index 24dbc767..de4fccbe 100644 --- a/gui/src/main/java/deltix/util/swing/table/RadioCellRenderer.java +++ b/gui/src/main/java/deltix/util/swing/table/RadioCellRenderer.java @@ -53,11 +53,7 @@ public Component getTableCellRendererComponent ( JTable table, this.setBackground ( background ); } - if (value == null) { - this.setSelected ( false ); - } - Boolean ValueAsBoolean = (Boolean) value; - this.setSelected ( ValueAsBoolean.booleanValue ( ) ); + this.setSelected(value != null && (Boolean) value); this.setHorizontalAlignment ( SwingConstants.CENTER ); return this; diff --git a/lang/src/main/java/deltix/util/lang/Util.java b/lang/src/main/java/deltix/util/lang/Util.java index 1cd98263..5edb062e 100644 --- a/lang/src/main/java/deltix/util/lang/Util.java +++ b/lang/src/main/java/deltix/util/lang/Util.java @@ -521,30 +521,36 @@ public static Object newInstanceNoX ( public static Runnable methodRunnable (final Object obj, String methodName) { Method m = null; - - for (Class cls = obj.getClass (); cls != null; cls = cls.getSuperclass ()) { + + Class cls = obj.getClass (); + while (true) { try { m = cls.getDeclaredMethod (methodName); break; } catch (NoSuchMethodException x) { + cls = cls.getSuperclass (); + if (cls == null) + throw new RuntimeException(x); // continue } } - - m.setAccessible (true); - - final Method fm = m; - + + assert m != null; + + m.setAccessible(true); + + final Method fm = m; + return ( - new Runnable () { - public void run () { - try { - fm.invoke (obj); - } catch (IllegalArgumentException | InvocationTargetException | IllegalAccessException x) { - throw new RuntimeException (x); + new Runnable() { + public void run() { + try { + fm.invoke(obj); + } catch (IllegalArgumentException | InvocationTargetException | IllegalAccessException x) { + throw new RuntimeException(x); + } } - } - } + } ); } diff --git a/lang/src/main/java/deltix/util/memory/MemoryDataInput.java b/lang/src/main/java/deltix/util/memory/MemoryDataInput.java index 94e1b586..f0cb138a 100644 --- a/lang/src/main/java/deltix/util/memory/MemoryDataInput.java +++ b/lang/src/main/java/deltix/util/memory/MemoryDataInput.java @@ -42,12 +42,7 @@ public MemoryDataInput (MemoryDataOutput mout) { } public void setBytes (byte [] buffer, int offset, int length) { - assert - (buffer == null ? - length == 0 : - offset + length <= buffer.length) : - "Insufficient buffer length " + buffer.length + "; offset: " + - offset + "; length: " + length; + assert (buffer == null ? length == 0 : offset + length <= buffer.length) : "Insufficient buffer length offset: " + offset + "; length: " + length; mBuffer = buffer; mLimit = offset + length; @@ -391,6 +386,7 @@ public void skipCharSequence () { /** * Returns false if the string value is null. */ + @Deprecated // buggy public StringBuilder appendToStringBuilder (StringBuilder sb) { int utflen = readUnsignedShort (); @@ -400,13 +396,13 @@ public StringBuilder appendToStringBuilder (StringBuilder sb) { if (utflen == 0) return (sb); - int c = -2; + int c; int char2, char3; int count = 0; for (;;) { c = readByte (); - if (c > 127 || c < 0) + if (c < 0) //WAS: if (c > 127 || c < 0) break; count++; diff --git a/log/src/main/java/deltix/util/log/gf/LoggerFactory.java b/log/src/main/java/deltix/util/log/gf/LoggerFactory.java index ed2a15cd..5ad1c1a9 100644 --- a/log/src/main/java/deltix/util/log/gf/LoggerFactory.java +++ b/log/src/main/java/deltix/util/log/gf/LoggerFactory.java @@ -1,6 +1,7 @@ package deltix.util.log.gf; import deltix.gflog.dcl.DclBridgeFactory; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -15,6 +16,8 @@ public abstract class LoggerFactory { protected LoggerFactory() { } + + @SuppressFBWarnings(value = "JLM_JSR166_UTILCONCURRENT_MONITORENTER", justification = "OK here") private Logger getLog(String name) { Logger logger = loggers.get(name); diff --git a/util/build.gradle b/util/build.gradle index d6a4ea8c..42984c33 100644 --- a/util/build.gradle +++ b/util/build.gradle @@ -14,8 +14,6 @@ dependencies { compile 'org.apache.commons:commons-compress:1.7' //compile 'javax.servlet:javax.servlet-api:3.1.0' - compileOnly 'com.google.code.findbugs:jsr305' - // compile('com.sun.xml.bind:jaxb-xjc:2.2.11') // 2.2.11 has only bug fixes compared 2.2.8-b130911.1802 (which used by Java 8) compile 'org.glassfish.jaxb:jaxb-runtime:2.2.11' // Glassfish replaces JAXB RI //compile('javax.xml:jsr173:1.0'){ transitive = false } diff --git a/util/src/main/java/deltix/util/vfs/VFiles.java b/util/src/main/java/deltix/util/vfs/VFiles.java index 94148daf..c675ba5d 100644 --- a/util/src/main/java/deltix/util/vfs/VFiles.java +++ b/util/src/main/java/deltix/util/vfs/VFiles.java @@ -10,16 +10,16 @@ public class VFiles { - public static long copyFile(VFile from, VFile to) throws IOException, InterruptedException { - InputStream in = null; - OutputStream out = null; - try { - return StreamPump.pump(in, out); - } finally { - Util.close(in); - Util.close(out); - } - } +// public static long copyFile(VFile from, VFile to) throws IOException, InterruptedException { +// InputStream in = null; +// OutputStream out = null; +// try { +// return StreamPump.pump(in, out); +// } finally { +// Util.close(in); +// Util.close(out); +// } +// } public static URL appendRelativePath(URL root, String relativePath) throws MalformedURLException { relativePath = relativePath.trim(); diff --git a/util/src/main/java/java_cup/lalr_item.java b/util/src/main/java/java_cup/lalr_item.java index d4b250b0..4f0afc10 100644 --- a/util/src/main/java/java_cup/lalr_item.java +++ b/util/src/main/java/java_cup/lalr_item.java @@ -1,5 +1,7 @@ package java_cup; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; + import java.util.Stack; import java.util.Enumeration; @@ -275,6 +277,7 @@ public boolean equals(lalr_item other) /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Generic equality comparison. */ + @SuppressFBWarnings(value = "EQ_OVERRIDING_EQUALS_NOT_SYMMETRIC", justification = "Not touching Java_cup - third-party source") public boolean equals(Object other) { if (!(other instanceof lalr_item)) diff --git a/util/src/main/java/java_cup/reduce_action.java b/util/src/main/java/java_cup/reduce_action.java index e8f4c84a..bd59a67c 100644 --- a/util/src/main/java/java_cup/reduce_action.java +++ b/util/src/main/java/java_cup/reduce_action.java @@ -1,7 +1,9 @@ package java_cup; -/** This class represents a reduce action within the parse table. +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; + +/** This class represents a reduce action within the parse table. * The action simply stores the production that it reduces with and * responds to queries about its type. * @@ -55,6 +57,7 @@ public boolean equals(reduce_action other) /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Generic equality test. */ + @SuppressFBWarnings(value = "EQ_OVERRIDING_EQUALS_NOT_SYMMETRIC", justification = "Not touching Java_cup - third-party source") public boolean equals(Object other) { if (other instanceof reduce_action) diff --git a/util/src/main/java/java_cup/shift_action.java b/util/src/main/java/java_cup/shift_action.java index 33fc17a6..8ad68569 100644 --- a/util/src/main/java/java_cup/shift_action.java +++ b/util/src/main/java/java_cup/shift_action.java @@ -1,7 +1,9 @@ package java_cup; -/** This class represents a shift action within the parse table. +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; + +/** This class represents a shift action within the parse table. * The action simply stores the state that it shifts to and responds * to queries about its type. * @@ -55,6 +57,7 @@ public boolean equals(shift_action other) /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Generic equality test. */ + @SuppressFBWarnings(value = "EQ_OVERRIDING_EQUALS_NOT_SYMMETRIC", justification = "Not touching Java_cup - third-party source") public boolean equals(Object other) { if (other instanceof shift_action) From 3866dfd273cd5e854bfaf5c597f28a24a414f41e Mon Sep 17 00:00:00 2001 From: Robot Date: Thu, 31 Oct 2019 16:01:38 +0000 Subject: [PATCH 2193/2572] [Skip CI] Generate release version --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index e44cb910..247819a9 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ -#Thu Oct 31 12:46:41 UTC 2019 +#Thu Oct 31 16:01:38 UTC 2019 dfpVersion=0.10.7 -version=5.2.60-SNAPSHOT +version=5.2.60 deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java hdTimeVersion=0.2.4 From 34c03e79734a9d28298036f9683f50dfb5c92876 Mon Sep 17 00:00:00 2001 From: Robot Date: Thu, 31 Oct 2019 16:01:46 +0000 Subject: [PATCH 2194/2572] [Skip CI] Generate next development version --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 247819a9..7f806145 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ -#Thu Oct 31 16:01:38 UTC 2019 +#Thu Oct 31 16:01:46 UTC 2019 dfpVersion=0.10.7 -version=5.2.60 +version=5.2.61-SNAPSHOT deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java hdTimeVersion=0.2.4 From 56d86edaa0f6de69c2eff47fb9eae88d04d8d5b1 Mon Sep 17 00:00:00 2001 From: Robot Date: Sun, 3 Nov 2019 04:19:31 +0000 Subject: [PATCH 2195/2572] [Skip CI] Generate release version --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 7f806145..629da43e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ -#Thu Oct 31 16:01:46 UTC 2019 +#Sun Nov 03 04:19:31 UTC 2019 dfpVersion=0.10.7 -version=5.2.61-SNAPSHOT +version=5.2.61 deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java hdTimeVersion=0.2.4 From 5f01100e002d05425cd39e92b9148bf3bb8d89c7 Mon Sep 17 00:00:00 2001 From: Robot Date: Sun, 3 Nov 2019 04:19:39 +0000 Subject: [PATCH 2196/2572] [Skip CI] Generate next development version --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 629da43e..13c3d9a2 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ -#Sun Nov 03 04:19:31 UTC 2019 +#Sun Nov 03 04:19:39 UTC 2019 dfpVersion=0.10.7 -version=5.2.61 +version=5.2.62-SNAPSHOT deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java hdTimeVersion=0.2.4 From 232825dba916fc743e9f7b31da7fd6037d1139e1 Mon Sep 17 00:00:00 2001 From: YarmalkevichD Date: Tue, 5 Nov 2019 11:10:03 +0300 Subject: [PATCH 2197/2572] [*] deprecate method with missing in java-11 platform-dependent packages --- gui/src/main/java/deltix/util/swing/SwingUtil.java | 12 +++++++++++- .../main/java/deltix/util/swing/gridpanel/Test.java | 2 +- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/gui/src/main/java/deltix/util/swing/SwingUtil.java b/gui/src/main/java/deltix/util/swing/SwingUtil.java index bec29b06..c5c25204 100644 --- a/gui/src/main/java/deltix/util/swing/SwingUtil.java +++ b/gui/src/main/java/deltix/util/swing/SwingUtil.java @@ -261,11 +261,21 @@ public void run () { ); } + @Deprecated public static void setWindowsLookAndFeel () { try { UIManager.setLookAndFeel ("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); + } catch (ClassNotFoundException exc) { + setSystemLookAndFeel(); } catch (Throwable e) { - } + } + } + + public static void setSystemLookAndFeel () { + try { + UIManager.setLookAndFeel (UIManager.getSystemLookAndFeelClassName()); + } catch (Throwable ignored) { + } } public static JButton newZeroMarginButton (Action action) { diff --git a/gui/src/main/java/deltix/util/swing/gridpanel/Test.java b/gui/src/main/java/deltix/util/swing/gridpanel/Test.java index 73cdaeb2..bfef0496 100644 --- a/gui/src/main/java/deltix/util/swing/gridpanel/Test.java +++ b/gui/src/main/java/deltix/util/swing/gridpanel/Test.java @@ -11,7 +11,7 @@ */ public class Test { public static void main (String [] args) throws Exception { - SwingUtil.setWindowsLookAndFeel (); + SwingUtil.setSystemLookAndFeel() ; SwingAbstractApp app = new SwingAbstractApp (); From 0926cec217ef6405f2b2a58b38db8e7aac129f2b Mon Sep 17 00:00:00 2001 From: Alex Karpovich Date: Tue, 5 Nov 2019 11:36:28 +0300 Subject: [PATCH 2198/2572] [*] new version --- .gitignore | 10 +++++++++- gradle.properties | 4 ++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index f1f4e26a..a35dc0c2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,12 @@ .idea/ .gradle/ *.iml -build \ No newline at end of file +*.iws +*.ipr +build + +# compiled output +/dist +/tmp +/**/out +/**/build \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index cd5818ba..5d68578b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ #Wed Oct 30 13:13:27 UTC 2019 dfpVersion=0.10.7 -version=5.4.3-SNAPSHOT +version=5.4.4-SNAPSHOT deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java -hdTimeVersion=0.2.4 +hdTimeVersion=0.2.4 \ No newline at end of file From 4886d6581f39a35e40adcd45ed27f427ff593c3a Mon Sep 17 00:00:00 2001 From: Robot Date: Tue, 5 Nov 2019 08:36:52 +0000 Subject: [PATCH 2199/2572] [Skip CI] Generate release version --- gradle.properties | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gradle.properties b/gradle.properties index 5d68578b..758b83a6 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ -#Wed Oct 30 13:13:27 UTC 2019 +#Tue Nov 05 08:36:52 UTC 2019 dfpVersion=0.10.7 -version=5.4.4-SNAPSHOT +version=5.4.4 deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java -hdTimeVersion=0.2.4 \ No newline at end of file +hdTimeVersion=0.2.4 From 9f638c427e63ae7290331d2825b827fe891bfb6f Mon Sep 17 00:00:00 2001 From: Robot Date: Tue, 5 Nov 2019 08:37:01 +0000 Subject: [PATCH 2200/2572] [Skip CI] Generate next development version --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 758b83a6..b82f7360 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ -#Tue Nov 05 08:36:52 UTC 2019 +#Tue Nov 05 08:37:01 UTC 2019 dfpVersion=0.10.7 -version=5.4.4 +version=5.4.5-SNAPSHOT deltixFeedUrl=https\://packages.deltixhub.com/maven2/Deltix.Java hdTimeVersion=0.2.4 From 607ceaa71996343e3a37d433ba9971c566f256e4 Mon Sep 17 00:00:00 2001 From: Alexei Osipov Date: Wed, 6 Nov 2019 23:48:29 +0300 Subject: [PATCH 2201/2572] Cleanup for SpotBugs --- .../util/currency/CurrencyCodeList.java | 2 ++ .../main/java/deltix/util/io/BasicIOUtil.java | 3 ++ util/src/main/java/deltix/util/io/IOUtil.java | 5 +++- .../java/deltix/util/io/SemanticVersion.java | 2 ++ .../java/deltix/util/jdbc/MDB2ORACLE.java | 2 +- .../deltix/util/net/SSLContextProvider.java | 30 ++++++++++++------- .../deltix/util/net/timer/TimerClient.java | 5 +++- .../main/java/deltix/util/os/Executor.java | 2 ++ .../main/java/deltix/util/os/WindowsOS.java | 14 +++++---- .../deltix/util/currency/CurrencyCodes.xml | 2 +- 10 files changed, 47 insertions(+), 20 deletions(-) diff --git a/util/src/main/java/deltix/util/currency/CurrencyCodeList.java b/util/src/main/java/deltix/util/currency/CurrencyCodeList.java index e0fb8248..c131f44b 100644 --- a/util/src/main/java/deltix/util/currency/CurrencyCodeList.java +++ b/util/src/main/java/deltix/util/currency/CurrencyCodeList.java @@ -12,6 +12,7 @@ import org.xml.sax.SAXException; import javax.annotation.concurrent.ThreadSafe; +import javax.xml.XMLConstants; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; @@ -48,6 +49,7 @@ private static void read () { private static void read(InputStream is) throws ParserConfigurationException, SAXException, IOException { final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance (); + dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); final DocumentBuilder db = dbf.newDocumentBuilder (); final Document doc = db.parse (is); doc.getDocumentElement ().normalize (); diff --git a/util/src/main/java/deltix/util/io/BasicIOUtil.java b/util/src/main/java/deltix/util/io/BasicIOUtil.java index b4d7f74f..2f9bae67 100644 --- a/util/src/main/java/deltix/util/io/BasicIOUtil.java +++ b/util/src/main/java/deltix/util/io/BasicIOUtil.java @@ -10,6 +10,8 @@ import deltix.util.lang.Util; import deltix.util.text.ShellPatternCSMatcher; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; + import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; @@ -258,6 +260,7 @@ public static String getNameNoExt (File f) { * * @throws CloneNotSupportedException - thrown when the afore-mentioned cloning algorithm fails */ + @SuppressFBWarnings("OBJECT_DESERIALIZATION") public static Object clone(Serializable object) throws CloneNotSupportedException { diff --git a/util/src/main/java/deltix/util/io/IOUtil.java b/util/src/main/java/deltix/util/io/IOUtil.java index e6f8ccd1..d33d33de 100644 --- a/util/src/main/java/deltix/util/io/IOUtil.java +++ b/util/src/main/java/deltix/util/io/IOUtil.java @@ -171,7 +171,9 @@ public final static void readUTF(MemoryDataInput in, Appendable sb) throws IOExc // // c = in.readByte (); // } - } + } + + // TODO: Move ecnryption-related code to a separate class private static final byte [] header = { (byte) 0xcc, (byte) 0xdd, (byte) 0x21, (byte) 0x3c, @@ -181,6 +183,7 @@ public final static void readUTF(MemoryDataInput in, Appendable sb) throws IOExc private static final PBEParameterSpec pars = new PBEParameterSpec (header, header.length); private static final String csname = "UTF-8"; + // TODO: Switch to a better cipher (with HMAC) private static final String algon = "PBEWithMD5AndDES"; private static final SecretKeyFactory skf; diff --git a/util/src/main/java/deltix/util/io/SemanticVersion.java b/util/src/main/java/deltix/util/io/SemanticVersion.java index 37a92999..2ebc373b 100644 --- a/util/src/main/java/deltix/util/io/SemanticVersion.java +++ b/util/src/main/java/deltix/util/io/SemanticVersion.java @@ -174,6 +174,8 @@ private static class StringItem implements Item { case 'm': value = "milestone"; break; + default: + // ignore } } this.value = ALIASES.getProperty(value, value); diff --git a/util/src/main/java/deltix/util/jdbc/MDB2ORACLE.java b/util/src/main/java/deltix/util/jdbc/MDB2ORACLE.java index 201fd124..582283ba 100644 --- a/util/src/main/java/deltix/util/jdbc/MDB2ORACLE.java +++ b/util/src/main/java/deltix/util/jdbc/MDB2ORACLE.java @@ -124,7 +124,7 @@ else if (cname.equals ("java.sql.Timestamp")) { } catch (SQLException x) { // ignore } - + JDBCUtils.exec (mOutputConnection, createSqlStr); System.out.println (insertSql.toString ()); diff --git a/util/src/main/java/deltix/util/net/SSLContextProvider.java b/util/src/main/java/deltix/util/net/SSLContextProvider.java index 9030b655..eb2869fc 100644 --- a/util/src/main/java/deltix/util/net/SSLContextProvider.java +++ b/util/src/main/java/deltix/util/net/SSLContextProvider.java @@ -1,6 +1,8 @@ package deltix.util.net; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; + import javax.net.ssl.*; import java.io.FileInputStream; import java.io.IOException; @@ -89,21 +91,27 @@ private static TrustManager[] getTrustManagers(boolean trustAl } else { //trust all connections trustManagers = new TrustManager[] { - new X509TrustManager() { - public X509Certificate[] getAcceptedIssuers() { - return null; - } - - @Override - public void checkClientTrusted(X509Certificate[] certs, String authType) { } - - @Override - public void checkServerTrusted(X509Certificate[] certs, String authType) { } - } + new TrustAllX509TrustManager() }; } return trustManagers; } + + /** + * This trust manager accepts all certificates as valid. + */ + @SuppressFBWarnings(value = "WEAK_TRUST_MANAGER", justification = "Intended behavior") + private static class TrustAllX509TrustManager implements X509TrustManager { + public X509Certificate[] getAcceptedIssuers() { + return null; + } + + @Override + public void checkClientTrusted(X509Certificate[] certs, String authType) { } + + @Override + public void checkServerTrusted(X509Certificate[] certs, String authType) { } + } } diff --git a/util/src/main/java/deltix/util/net/timer/TimerClient.java b/util/src/main/java/deltix/util/net/timer/TimerClient.java index 3cf424c4..5e92174d 100644 --- a/util/src/main/java/deltix/util/net/timer/TimerClient.java +++ b/util/src/main/java/deltix/util/net/timer/TimerClient.java @@ -3,6 +3,8 @@ import deltix.util.io.*; import deltix.util.lang.*; import deltix.util.memory.*; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; + import java.io.*; import java.net.*; @@ -36,7 +38,8 @@ public TimerClient (String host, int port) { public long nanoTime () { return (System.nanoTime () + correction); } - + + @SuppressFBWarnings("UNENCRYPTED_SOCKET") @Override public void run () { try { diff --git a/util/src/main/java/deltix/util/os/Executor.java b/util/src/main/java/deltix/util/os/Executor.java index 26621eda..25f16eaa 100644 --- a/util/src/main/java/deltix/util/os/Executor.java +++ b/util/src/main/java/deltix/util/os/Executor.java @@ -4,6 +4,7 @@ import deltix.gflog.LogFactory; import deltix.util.lang.Util; import deltix.util.lang.StringUtils; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import java.io.*; @@ -25,6 +26,7 @@ static class StreamGrabber extends Thread { this.out = out; } + @SuppressFBWarnings("DM_DEFAULT_ENCODING") // This code reads data from command line that usually uses system wide default charset public void run() { BufferedReader reader = null; try { diff --git a/util/src/main/java/deltix/util/os/WindowsOS.java b/util/src/main/java/deltix/util/os/WindowsOS.java index 97f1d829..48d3cbea 100644 --- a/util/src/main/java/deltix/util/os/WindowsOS.java +++ b/util/src/main/java/deltix/util/os/WindowsOS.java @@ -4,8 +4,8 @@ import deltix.util.lang.Util; import deltix.util.lang.StringUtils; -import com.sun.jna.*; import com.sun.jna.platform.win32.*; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import java.io.*; import java.lang.reflect.InvocationTargetException; @@ -157,6 +157,7 @@ public static void createShortcut ( createShortcut (target, location.getAbsolutePath (), icon.getAbsolutePath ()); } + @SuppressFBWarnings("COMMAND_INJECTION") public static void createShortcut ( File target, String location, @@ -191,9 +192,9 @@ public static void createShortcut ( + "For Each objItem in colItems\n" + " Wscript.Echo objItem.Caption & \":\" & objItem.InterfaceType & \":\" & objItem.SerialNumber\n" + "Next\n"; - + @SuppressFBWarnings("COMMAND_INJECTION") public static String getHardDiskSerial () { - String result = ""; + StringBuilder result = new StringBuilder(); try { File file = File.createTempFile ("getHardDiskSerial", ".vbs"); @@ -207,13 +208,13 @@ public static String getHardDiskSerial () { BufferedReader input = new BufferedReader (new InputStreamReader (p.getInputStream ())); String line; while ((line = input.readLine ()) != null) { - result += "%" + line; + result.append("%").append(line); } input.close (); } catch (Exception e) { e.printStackTrace (); } - return result.trim (); + return result.toString().trim (); } // static String GET_SERIAL_NUMBERS = "Set fso = CreateObject(\"Scripting.FileSystemObject\")\n" @@ -256,6 +257,7 @@ public static String getSystemSerial() { return number; } + @SuppressFBWarnings("COMMAND_INJECTION") public static String getDiskSerialNumber (String drive) { String result = ""; try { @@ -284,6 +286,7 @@ public static String getDiskSerialNumber (String drive) { return result.length() > 0 ? String.format ("%08X", Integer.valueOf (result)) : result; } + @SuppressFBWarnings("COMMAND_INJECTION") public static String getMBSerialNumber() { String result = ""; try { @@ -316,6 +319,7 @@ public static String getMBSerialNumber() { return result.trim (); } + @SuppressFBWarnings("COMMAND_INJECTION") public static String getSystemUUID() { String result = ""; try { diff --git a/util/src/main/resources/deltix/util/currency/CurrencyCodes.xml b/util/src/main/resources/deltix/util/currency/CurrencyCodes.xml index ab7a6538..d4e71dbe 100644 --- a/util/src/main/resources/deltix/util/currency/CurrencyCodes.xml +++ b/util/src/main/resources/deltix/util/currency/CurrencyCodes.xml @@ -1 +1 @@ -1301RippleXRPXRP1302Metaverse ETPETPETP1303Bitcoin CashBCHBCH1304OmiseGOOMGOMG1305NeoNEONEO1306IotaMIOTAIOT1307DigitalCashDASHDSH1308ZcashZECZEC1309MoneroXMRXMR1310Ethereum ClassicETCETC1311EOSEOSEOS1312AventusAVTAVT1313QtumQTUMQTM1314SantimentSANSAN1315EidooEDOEDO1316Bitcoin GoldBTGBTG1317StreamrDATADAT1318QASHQASHQSH1319YOYOWYOYOWYYW1321TetherUSDTTHR1322CardanoADAADA1323Binance CoinBNBBNB1325BreadBRDBRD1326GiftoGTOGTO1327IconomiICNICN1329IconICXICX1330LiskLSKLSK1331NanoNANONAN1333SaltSALTSLT1334StratisSTRATSTR1335TronTRXTRX1336WingsWINGSWNG1337Stellar LumensXLMXLM1338VergeXVGXVG1641LitecoinLTCLTC1741BitcoinBTCXBT1841EthereumETHETH8ALBANIALekALLLek12ALGERIAAlgerian DinarDZDDZD20ADPADPADP31AZERBAIJANAzerbaijanian ManatAZMман.32ARGENTINAArgentine PesoARS$36Australian DollarAUD$40ATSATSATS44BAHAMASBahamian DollarBSDBSD48BAHRAINBahraini DinarBHDد.ب.â€50BANGLADESHTakaBDTà§³51ARMENIAArmenian DramAMDÕ¤Ö€.52BARBADOSBarbados DollarBBDBBD56BEFBEFBEF60BERMUDABermudian Dollar (customarily known as Bermuda DolBMDBMD64BHUTANNgultrumBTNBTN68BOLIVIABolivianoBOB$b72BOTSWANAPulaBWPBWP84BELIZEBelize DollarBZDBZ$90SOLOMON ISLANDSSolomon Islands DollarSBDSBD96BRUNEI DARUSSALAMBrunei DollarBND$104MYANMARKyatMMKMMK108BURUNDIBurundi FrancBIFBIF116CAMBODIARielKHR៛124CANADACanadian DollarCAD$132CAPE VERDECape Verde EscudoCVECVE136CAYMAN ISLANDSCayman Islands DollarKYDKYD144SRI LANKASri Lanka RupeeLKRරු.152CHILEChilean PesoCLP$156CHINAYuan RenminbiCNYÂ¥170COLOMBIAColombian PesoCOP$174COMOROSComoro FrancKMFKMF188COSTA RICACosta Rican ColonCRCâ‚¡191CROATIACroatian KunaHRKkn192CUBACuban PesoCUPCUP196CYPRUSCyprus PoundCYPCYP203CZECH REPUBLICCzech KorunaCZK208Danish KroneDKKkr.214DOMINICAN REPUBLICDominican PesoDOPRD$222EL SALVADOREl Salvador ColonSVCSVC230ETHIOPIAEthiopian BirrETBETB232ERITREANakfaERNERN233ESTONIAKroonEEKkr238FALKLAND ISLANDS (MALVINAS)Falkland Islands PoundFKPFKP242FIJIFiji DollarFJDFJD246FIMFIMFIM250FRFFRFFRFFRF262DJIBOUTIDjibouti FrancDJFDJF270GAMBIADalasiGMDGMD276DEMDEMDEM288GHANACediGHCGHC292GIBRALTARGibraltar PoundGIPGIP300GRDGRDGRD320GUATEMALAQuetzalGTQQ324GUINEAGuinea FrancGNFGNF328GUYANAGuyana DollarGYDGYD332HAITIGourdeHTGHTG340HONDURASLempiraHNLL.344HONG KONGHong Kong DollarHKDHK$348HUNGARYForintHUFFt352ICELANDIceland KronaISKkr.356Indian RupeeINRRs.360INDONESIARupiahIDRRp364IRAN (ISLAMIC REPUBLIC OF)Iranian RialIRRريال368IRAQIraqi DinarIQDد.ع.â€372IEPIEPIEP376ISRAELNew Israeli SheqelILS₪380ITLITLITL388JAMAICAJamaican DollarJMDJ$392JAPANYenJPYÂ¥398KAZAKHSTANTengeKZTТ400JORDANJordanian DinarJODد.ا.â€404KENYAKenyan ShillingKESS408KOREA, DEMOCRATIC PEOPLE''S REPUBLIC OFNorth Korean WonKPWKPW410KOREA, DEMOCRATIC PEOPLE''S REPUBLIC OFWonKRWâ‚©414KUWAITKuwaiti DinarKWDد.Ùƒ.â€417KYRGYZSTANSomKGSÑом418LAO PEOPLE''S DEMOCRATIC REPUBLICKipLAKLAK422LEBANONLebanese PoundLBPÙ„.Ù„.â€426LESOTHOLotiLSLLSL428LATVIALatvian LatsLVLLs430LIBERIALiberian DollarLRDLRD434LIBYAN ARAB JAMAHIRIYALibyan DinarLYDد.Ù„.â€440LITHUANIALithuanian LitasLTLLt442LUFLUFLUF446MACAOPatacaMOPMOP454MALAWIKwachaMWKMWK458MALAYSIAMalaysian RinggitMYRRM462MALDIVESRufiyaaMVRÞƒ.470MALTAMaltese Lira^MTLLm478MAURITANIAOuguiyaMROMRO480MAURITIUSMauritius RupeeMURMUR484MEXICOMexican PesoMXN$496MONGOLIATugrikMNTâ‚®498MOLDOVA, REPUBLIC OFMoldovan LeuMDLMDL504Moroccan DirhamMADد.Ù….â€512OMANRial OmaniOMRر.ع.â€516NAMIBIANamibian DollarNADNAD524NEPALNepalese RupeeNPRरà¥528NLGNLGNLG532NETHERLANDS ANTILLESNetherlands Antillian GuikderANGANG533ARUBAAruban GuilderAWGAWG548VANUATUVatuVUVVUV554New Zealand DollarNZD$558NICARAGUACordoba OroNION566NIGERIANairaNGNNGN578Norwegian KroneNOKkr586PAKISTANPakistan RupeePKRRs590PANAMABalboaPABB/.598PAPUA NEW GUINEAKinaPGKPGK600PARAGUAYGuaraniPYGGs604PERUNuevo SolPENS/.608PHILIPPINESPhilippine PesoPHPPhP620PTEPTEPTE624GUINEA-BISSAUGuinea-Bissau PesoGWPGWP634QATARQatari RialQARر.Ù‚.â€642ROMANIAOld LeuROLlei643RUSSIAN FEDERATIONRussian RubleRUBRUB646RWANDARwanda FrancRWFRWF654SAINT HELENASaint Helena PoundSHPSHP678S?O TOME AND PRINCIPEDobraSTDSTD682SAUDI ARABIASaudi RiyalSARر.س.â€690SEYCHELLESSeychelles RupeeSCRSCR694SIERRA LEONELeoneSLLSLL702SINGAPORESingapore DollarSGD$703SLOVAKIASlovak KorunaSKKSk704VIET NAMDongVNDâ‚«705SLOVENIATolarSITSIT706SOMALIASomali ShillingSOSSOS710RandZARR716ZIMBABWEZimbabwe DollarZWDZ$724ESPESPESP736SUDANSudanese DinarSDDSDD748SWAZILANDLilangeniSZLSZL752SWEDENSwedish KronaSEKkr756Swiss FrancCHFfr.760SYRIAN ARAB REPUBLICSyrian PoundSYPÙ„.س.â€764THAILANDBahtTHB฿776TONGAPa''angaTOPTOP777CHINAYuan RenminbiCNHÂ¥780TRINNumericCodeAD AND TOBAGOTrinNumericCodead and Tobago DollarTTDTT$784UNITED ARAB EMIRATESUAE DirhamAEDد.Ø¥.â€788TUNISIATunisian DinarTNDد.ت.â€792TURKEYOld Turkish LiraTRL₤795TURKMENISTANManatTMMm.800UGANDAUganda ShillingUGXUGX807MACEDONIA, THE FORMER YUGOSLAV REPUBLIC OFDenarMKDден.818EGYPTEgyptian PoundEGPج.Ù….â€826UNITED KINGDOMPound SterlingGBP£834TANZANIA, UNITED REPUBLIC OFTanzanian ShillingTZSTZS840US DollarUSD$858URUGUAYPeso UruguayoUYU$U860UZBEKISTANUzbekistan SumUZSÑўм862VENEZUELABolivarVEBBs882SAMOATalaWSTWST886YEMENYemeni RialYERر.ÙŠ.â€891SERBIA AND MONTENEGROSerbian DinarCSDДин.894ZAMBIAKwachaZMKZMK901TAIWAN, PROVINCE OF CHINANew Taiwan DollarTWDNT$943MOZAMBIQUEMericalMZNMZN946ROMANIANew LeuRONRON947SWITZERLANDWIR EuroCHECHE948SWITZERLANDWIR FrancCHWCHW949TURKEYNew Turkish LiraTRYYTL950CFA Franc BEACXAFXAF951East Caribbean DollarXCDXCD952CFA Franc BCEAOXOFXOF953CFP FrancXPFXPF955Bond Markets Units European Composite Unit (EURCO)XBAXBA956European Monetary Unit (E.M.U.-6)XBBXBB957European Unit of Account 9(E.U.A.-9)XBCXBC958European Unit of Account 17(E.U.A.-17)XBDXBD959GoldXAUXAU960INTERNATIONAL MONETARY FUND (I.M.F)SDRXDRXDR961SilverXAGXAG962PlatinumXPTXPT963AlphabeticCodes specifically reserved for testingXTSXTS964PalladiumXPDXPD968SURINAMESurinam DollarSRDSRD969MADAGASCARMalagascy AriaryMGAMGA970COLOMBIAUnNumericCodead de Valor RealCOUCOU971AFGHANISTANAfghaniAFNAFN972TAJIKISTANSomoniTJSTJS973ANGOLAKwanzaAOAAOA974BELARUSBelarussian RubleBYRBYR975BULGARIABulgarian LevBGNBGN976CONGO, THE DEMOCRATIC REPUBLIC OFFranc CongolaisCDFCDF977BOSNIA & HERZEGOVINAConvertible MarksBAMKM978EuroEUR€979MEXICOMexican UnNumericCodead de Inversion (UNumericCodeMXVMXV980UKRAINEHryvniaUAHгрн.981GEORGIALariGELLari984BOLIVIAMvdolBOVBOV985POLANDZlotyPLNzÅ‚986BRAZILBrazilian RealBRLR$990CHILEUnNumericCodeades de formentoCLFCLF997UNITED STATES(Next day)USNUSN998UNITED STATES(Same day)USSUSS999XXXXXX1339ArkARKARK1341KomodoKMDKMD1342Power LedgerPOWRPWR1343AdExADXADX1345AeternityAEAE1346AionAIONAIO1347AmbrosusAMBAMB1349AppCoinsAPPCAPP1350AeronARNARN1351AirSwapASTAST1353Basic Attention TokenBATBAT1354Bitcoin DiamondBCDBCD1355BlockMason Credit ProtocolBCPTBCP1357BluzelleBLZBLZ1358BancorBNTBNT1359ETHOSETHOSBQX1361BitSharesBTSBTS1362BloxCDTCDT1363ChatCoinCHATCHT1365CyberMilesCMTCMT1366CindicatorCNDCND1367CentraCTRCTR1369DigixDAODGDDGD1370AgrelloDLTDLT1371district0xDNTDNT1373aelfELFELF1374EnigmaENGENG1375Enjin CoinENJENJ1377EverexEVXEVX1378EtherpartyFUELFUE1379FunFairFUNFUN1381GasGASGAS1382Genesis VisionGVTGVT1383GXChainGXSGXS1384HshareHSRHSR1385InsolarINSINS1386IOStokenIOSTIOS1387Kyber NetworkKNCKNC1389LendingblockLNDLND1390ChainLinkLINKLNK1391LoopringLRCLRC1393LunyrLUNLUN1394DecentralandMANAMAN1395Crypto.comMCOMCO1396Moeda Loyalty PointsMDAMDA1397ModumMODMOD1399MonethaMTHMTH1401MetalMTLMET1402NavCoinNAVNAV1403Nucleus VisionNCASHNCH1405NeblioNEBLNEB1406NulsNULSNUL1407OpenANXOAXOAX1409OntologyONTONT1411Simple TokenOSTOST1412PIVXPIVXPIV1413POA NetworkPOAPOA1415Po.etPOEPOE1416PopulousPPTPPT1419QLINKQLCQLC1420QuantstampQSPQSP1421Ripio Credit NetworkRCNRCN1423Raiden Network TokenRDNRDN1424Request NetworkREQREQ1425iExec RLCRLCRLC1427Red PulsePHXRPX1429SingularDTVSNGLSSNG1431SONMSNMSNM1432StatusSNTSNT1433SteemSTEEMSTM1435StorjSTORJSTJ1436StormSTORMSRM1437SubstratumSUBSUB1438SyscoinSYSSYS1439Time New BankTNBTNB1441TierionTNTTNT1443TriggersTRIGTRI1444VeChainVETVEN1445ViacoinVIAVIA1447ViberateVIBVIB1448VIBEVIBEVBE1449WaBiWABIWAB1450WanchainWANWAN1451WavesWAVESWVS1452WePowerWPRWPR1453WaltonchainWTCWTC1455NEMXEMXEM1456ZCoinXZCXZC1457ZilliqaZILZIL14590x ProtocolZRXZRX1000HyperCashHCHC1001GoChainGOGO1002Paxos Standard TokenPAXPAX1003RavencoinRVNRVN1004DecredDCRDCR1005MithrilMITHMITH1006USD CoinUSDCUSDC1007Bitcoin SVBSVBSV1008TezosXTZXTZ1009MakerMKRMKR1010DogecoinDOGEDOGE1011BytecoinBCNBCN1012TrueUSDTUSDTUSD1013DigiByteDGBDGB1014SiacoinSCSC1015BytomBTMBTM1016Pundi XNPXSNPXS1017AugurREPREP1018MaidSafeCoinMAIDMAID1019GolemGNTGNT1020ElectroneumETNETN1021HoloHOTHOT1022CryptonexCNXCNX1023FactomFCTFCT1024DaiDAIDAI1025KuCoin SharesKCSKCS1026Worldwide Asset ExchangeWAXWAX1027ArdorARDRARDR1028Huobi TokenHTHT1029MOACMOACMOAC1030RevainRR1031MonaCoinMONAMONA1032NexoNEXONEXO1033ODEMODEODE1034Insight ChainINBINB1035ReddCoinRDDRDD1036MixinXINXIN1037DentacoinDCNDCN1038HorizenZENZEN1039PolymathPOLYPOLY1040NasdacoinNSDNSD1041SIRIN LABS TokenSRNSRN1042Digitex FuturesDGTXDGTX1043DropilDROPDROP1044NxtNXTNXT1045MobileGoMGOMGO1046BOScoinBOSBOS1047TenXPAYPAY1048Theta TokenTHETATHETA1049NebulasNASNAS1050QuarkChainQKCQKC1051Loom NetworkLOOMLOOM1052VeritaseumVERIVERI1053ElastosELAELA1054WaykiChainWICCWICC1055ETERNAL TOKENXETXET1056DragonchainDRGNDRGN1057ProximaXXPXXPX1058Bitcoin PrivateBTCPBTCP1059Gemini DollarGUSDGUSD1060LinkeyLKYLKY1061BHPCashBHPCBHPC1062SmartlandsSLTSLT1063NectarNECNEC1064CivicCVCCVC1065OdysseyOCNOCN1066Endor ProtocolEDREDR1067Bibox TokenBIXBIX1068ARBITRAGEARBARB1069Optimal Shelf...OSAOSA1070DentDENTDENT1071GroestlcoinGRSGRS1072Byteball BytesGBYTEGBYTE1073RChainRHOCRHOC1074THEKEYTKYTKY1075CentralityCENNZCENNZ1076PeercoinPPCPPC1077EmercoinEMCEMC1078ETH LendLENDLEND1079Cloak CoinCLOAKCLOAK1080SKYSKYSKY1081IOTXIOTXIOTX1082SingularityNETAGIAGI1083NexusNXSNXS1084Key CoinKEYKEY1085MainframeMFTMFT1086DOCKDOCKDOCK1087Bit ConnectBCCBCC1088VENVENVEN1089Red PulseRPXRPX1090RENRENREN1091EthosBQXBQX1092BnkToTheFutureBFTBFT1093FSNFSNFSN1094MatrixMANMAN1095GnosisGNOGNO1096MelonMLNMLN1097NamecoinNMCNMC1098VertcoinVTCVTC1099BurstBURSTBURST1830Steem DollarsSTEEMDSBD1332BitTorrentBTTBTT1831ClamsCLAMCLAM1832FOAMFOAMFOAM1833GameCreditsGAMEGAME1835LBRY CreditsLBCLBC1836NumeraireNMRNMR1837Pascal CoinPASCPASC1838CounterpartyXCPXCP1839PrimecoinXPMXPM1829StableUSDUSDSUSDS1823STASIS EURSEURSEURS1824UTRUSTUTKUTK1825CortexCTXCCTXC1827Project PaiPAIPAI1828SmartMeshSMTSMT1794GrinGRINGRIN1796Unikoin GoldUKGUKG1797Genaro NetworkGNXGNX1798PentaPNTPNT1799Content Neutrality NetworkCNNCNN1801CredLBALBA1802BlocktixTIXTIX1803LympoLYMLYM1804All SportsSOCSOC1805Jibrel NetworkJNTJNT1806DATADTADTA1808AchainACTACT1809TokenCardTKNTKN1810PropyPROPRO1811DigitalNoteXDNXDN1812CrypteriumCRPTCRPT1813AragonANTANT1814BLOCKvVEEVEE1815BlocknetBLOCKBLOCK1816PumaPayPMAPMA1817IgnisIGNISIGNIS1819EdgelessEDGEDG1821Ontology GasONGONG1822Fetch.AIFETFET1793HUSD SolutionHUSDHUSD1632Ink ProtocolXNKXNK1633Crowd MachineCMCTCMCT1636NexiumNXCNXC1637SIBCoinSIBSIB1638Swarm CitySWTSWT1639PatientoryPTOYPTOY1640BANKEXBKXBKX1644MatchpoolGUPGUP1645HumaniqHMQHMQ1647HyperSpaceAMPAMP1648DECENTDCTDCT1649SpaceChainSPCSPC1650NAGANGCNGC1651NoLimitCoinNLC2NLC21652AeonAEONAEON1653OriginTrailTRACTRAC1655eBoostEBSTEBST1656CannabisCoinCANNCANN1657BreakoutBRKBRK1658SequenceSEQSEQ1659TransferCoinTXTX1660Memetic / PepeCoinMEMEMEME1661DopeCoinDOPEDOPE1662Internet of PeopleIOPIOP1663VeriumReserveVRMVRM1664PinkCoinPINKPINK1665SyndicateSYNXSYNX16662GIVE2GIVE2GIVE1667ExclusiveCoinEXCLEXCL1668DynamicDYNDYN1669ArtByteABYABY1670FoldingCoinFLDCFLDC1671KoreKOREKORE1672GeoCoinGEOGEO1673ExpanseEXPEXP1674OKCashOKOK1675MusicoinMUSICMUSIC1676GolosGOLOSGOLOS1677Blockparty (BOXX Token)BOXXBOXX1679CurecoinCURECURE1680SolarCoinSLRSLR1681BloomBLTBLT1683Decision TokenHSTHST1684Haven ProtocolXHVXHV1685GridCoinGRCGRC1686MonetaryUnitMUEMUE1687MyriadXMYXMY1688DiamondDMDDMD1689I/O CoinIOCIOC1691Bean CashBITBBITB1692CrownCRWCRW1693RadiumRADSRADS1695VeriCoinVRCVRC1696IncentINCNTINCNT1697RevolutionVRRVRRVR1698XELXELXEL1699UpTokenUPUP1700IONIONION1701BitTubeTUBETUBE1707HempCoinTHCTHC1708FeathercoinFTCFTC1709ShiftSHIFTSHIFT1711adTokenADTADT1712PotCoinPOTPOT1713BlackCoinBLKBLK1714Sentinel ProtocolUPPUPP1715MercuryMERMER1717MobiusMOBIMOBI1718ZClassicZCLZCL1719CashBet CoinCBCCBC1720MetronomeMETMET1721VITEVITEVITE1722HydroHYDROHYDRO1723BitBayBAYBAY1725IHT Real Estate ProtocolIHTIHT1726RefereumRFRRFR1727UbiqUBQUBQ1728FLOFLOFLO1729WhiteCoinXWCXWC1730Moss CoinMOCMOC1731NKNNKNNKN1732QuantQNTQNT1733Crypto.com ChainCROCRO1734ParticlPARTPART1735Quantum Resistant LedgerQRLQRL1737DMarketDMTDMT1738SaluSSLSSLS1739MediBloc [ERC20]MEDXMEDX1740EinsteiniumEMC2EMC21742AidCoinAIDAID1743AuctusAUCAUC1744Banyan NetworkBBNBBN1745Bitcoin InterestBCIBCI1746CommerceBlockCBTCBT1747Callisto NetworkCLOCLO1749Digix Gold TokenDGXDGX1750DetherDTHDTH1751EssentiaESSESS1753ParkinGoGOTGOT1754Internet Node TokenINTINT1755On.LiveONLONL1757KlerosPNKPNK1758RIF TokenRIFRIF1759Rate3RTERTE1761ConsensusSENSEN1762VetriVLDVLD1763WOLLOWLOWLO1765XribaXRAXRA17660ChainZCNZCN1767Recovery Right TokensRRTRRT1768CreditsCSCS1769DADIDADIDADI1770Tether EuroEURTEURt1771EveripediaIQIQ1772MedicalchainMTNMTN1773AutonioANIONIO1774OmniOMNIOMNI1775ORS GroupORSGORS1778BlockpassPASSPASS1779RSK Smart BitcoinRBTCRBTC1781SEERSEERSEER1782SpankChainSPANKSPANK1783UniversaUTNPUTNP1785V SystemsVSYSVSYS1786V YggdrashYEEDYEED1787Hydro ProtocolHOTPHOT1789ContentBoxBOXBOX1790AtonomiATMIATMI1791The AbyssABYSSABYSS1630Atlas ProtocolATPATP16311BG1BG1BG1626Time Space ChainTSCTSC1627BerithBRTBRT1628BitMart TokenBMXBMX1629Bitcoin HDXHDBHD1625WoChainWOCWOC1623Celer NetworkCELRCELR1622Ether Kingdoms TokenIMPIMP1621MaecenasARTART1619VeriblockVBKVBK1618PlayChipPLAPLA1617OrbsORBSORBS1614TTC ProtocolTTCTTC1615ForestingPTONPTON1616PCHAINPIPI1612AnkrANKRANKR1613AergoAERGOAERGO1610MetadiumMETAMETA1611GoldCoinGLCGLC1605PAL NetworkPALPAL1606Solve.CareSOLVESOLVE1607BTU ProtocolBTUBTU1609SpendcoinSPNDSPND1602SphereSPHRSPHR1603ServeSERVSERV1597Circuits of ValueCOVALCOVAL1599Breakout StakeBRXBRX1601BitswiftBITSBITS1596Golos GoldGBGGBG1594EverGreenCoinEGCEGC1595DatabitsDTBDTB1587QwarkQWARKQWARK1588NeosCoinNEOSNEOS1589NuBitsNBTNBT1591More CoinMOREMORE1592HxroHXROHXRO1593GambitGAMGAM1584StealthXSTXST1585TokesTKSTKS1582GuldenCNLGNLG1583BitSendCBSDBSD1581HunterCoinHUCHUC1580LivepeerLPTLPT1579BORABORABORA1577STACSSTACSSTACS1576HOT TokenHOTTHOT1575DreamTeamDREAMDREAM1574TOPTOPNTOP1568Machine Xchange CoinMXCMXC1569COVACOVACOVA1570LambdaLAMBLAMB1571Content Value NetworkCVNTCVNT1572RuffRUFFRUFF1573LinkEyeLETLET1563Davinci CoinDACDAC1564TripioTRIOTRIO1565InvestDigitalIDTIDT1567Huobi Pool TokenHPTHPT1556ThingsOperatingSystemTOSTOS1557Globalvillage EcosystemGVEGVE1559NeuroChainNCCNCC1560KcashKCASHKCASH1561CVCoinCVNCVN1562BitCapitalVendorBCVBCV1551Yuan Chain CoinYCCYCC1552BitUP TokenBUTBUT1553SmartshareSSPSSP1555MyTokenMTMT1546DATxDATXDATX1547ThemisGETGET1549GET ProtocolGETPGET1550U NetworkUUUUUU1540XMaxXMXXMX1541YouLive CoinUCUC1542Acute Angle CloudAACAAC1543SeeleSEELESEELE1544UnlimitedIPUIPUIP1545LitexLXTLXT1537FansTimeFTIFTI1538Global Social ChainGSCGSC1539Promotion CoinPCPC1531EDUCareEKTEKT1534BeeKanBKBTBKBT1535FairGameFAIRFAIR1536Game.comGTCGTC1527Intelligent Investment ChainIICIIC1529ShineChainSHESHE1530MEXMEXMEX1522QunQunQUNQUN1523EduCoinEDUEDU1525BitcoinXBCXBCX1526HitChainHITHIT1520SunContractSNCSNC1521STKSTKSTK1517YEEYEEYEE1518EchoLinkEKOEKO1519DeepBrain ChainDBCDBC1513ZillaZLAZLA1514ArcblockABTABT1515MatryxMTXMTX1511BitKanKANKAN1506TopChainTOPCTOPC1507CoinMeetMEETMEET1508SwftCoinSWFTCSWFTC1509MediSharesMDSMDS1510IoT ChainITCITC1501EngineEGCCEGCC1502AI DoctorAIDOCAIDOC1503Super BitcoinSBTCSBTC1505Bitcoin FileBIFIBIFI1500IRIS NetworkIRISIRIS1494MuskMUSKMUSK1495PortalPORTALPORTAL1497RCCCRCCCRCCC1499DatumDATDAT1492ZJLT Distributed Factoring NetworkZJLTZJLT1493Block 1818C18C1491MARK.SPACEMRKMRK1490AdHiveADHADH1479FLIPFLPFLP1489Dragon CoinsDRGDRG1481FarmaTrustFTTFTT1482LikeCoinLIKELIKE1483Morpheus LabsMITXMITX1485StoxSTXSTX1486ZPERZPRZPR1487FintruX NetworkFTXFTX1488Plus-CoinNPLCNPLC1477Huobi 10 IndexHB10HB101476ObsidianODNODN1472PitchPITCHPITCH1473Purple Butterfly TradingPBTTPBTT1474PatronPATPAT1475OpusOPTOPT1463ProCurrencyPROCPROC1464PresearchPREPRE1465PaymonPMNTPMNT1466PlutonPLUPLU1467PillarPLRPLR1468PolybiusPLBTPLBT1469PlaykeyPKTPKT1471LampixPIXPIX1460Quanta Utility TokenQNTUQNTU1461PlayGamePXGPXG1842imbrexREXREX1843BitRentRNTBRNTB1844RobotinaROXROX1845RivetzRVTRVT1846SociallSCLSCL1847SentinelSENTSENT1848ShipChainSHIPSHIP1849Signal TokenSIGSIG1850SilkChainSILKSILK1851SlateSLXSLX1852SmartCashSMARTSMART1853SnowballSNBLSNBL1854SPINDLESPDSPD1855SportyCoSPFSPF1856StarbaseSTARSTAR1857StoriqaSTQSTQ1859SunchainSUNCSUNC1861SuretlySURSUR1863savedroidSVDSVD1864SwarmSWMSWM1865TaaSTAASTAAS1866LamdenTAUTAU1867TrueDeckTDPTDP1868TokenDeskTDSTDS1869TelcoinTELTEL1870ChronobankTIMETIME1871TradcoinTRADTRAD1872WeTrustTRSTTRST1873TrueChainTRUETRUE1874Useless Ethereum TokenUETUET1875Usechain TokenUSEUSE1876United Traders TokenUTTUTT1877VeriMEVMEVME1878Provoco TokenVOCOVOCO1879Wiki TokenWIKIWIKI1880CrowdWizWIZWIZ1881XaurumXAURXAUR1883BlitzPredictXBPXBP1884Monero ClassicXMCXMC1885Exchange UnionXUCXUC1887ZapZAPZAP1888ZeepinZPTZPT1889ZrCoinZRCZRC1890ZeusshieldZSCZSC2000ATLANT TokenATLATL2001BANCABANCABANCA2002BerryBERRYBERRY2003BetterBettingBETRBETR2004BitClaveCATCAT2005BitcoreBTXBTX2006BitDegreeBDGBDG2007BitDiceCSNOCSNO2008Black MoonBMCBMC2009BlockMeshBMHBMH2010CashaaCASCAS2011CoinPokerCHPCHP2012COPYTRACKCPYCPY2013CovestingCOVCOV2014Crypto20C20C202015CryptopayCPAYCPAY2016CUBEAUTOAUTO2017Curriculum VitaeCVHCVH2018CyberVeinTokenCVTCVT2019DAO CasinoBETBET2020DecentBetDBETDBET2021DIMCOINDIMDIM2022EtherollDICEDICE2023First Blood1ST1ST2024FortunaFOTAFOTA2025GoByteGBXGBX2026HappycoinHPCHPC2027Hive ProjectHVNHVN2028indaHashIDHIDH2029InsurChainINSURINSUR2030InsurePalIPLIPL2031iXledgerIXTIXT2032KickCoinKICKKICK2033KINKINKIN2034LATokenLALA2035LifeLIFELIFE2036LockTripLOCLOC2037MeshBoxMESHMESH2038Micro MoneyAMMAMM2039MybitMYBMYB2040NectarNCTNCT2041NeumarkNEUNEU2042NOAHCOINNOAHNOAH2043SwissBorgCHSBCHSB2044AlphacatACATACAT2045Freyr ChainFRECFREC2046ConsentiumCSMCSM2047NanjcoinNANJNANJ2048NeuroTokenNTKNTK2049FuzeXFXTFXT2050ChainiumCHXCHX2051FriendZ CoinFDZFDZ2052CryptaurCPTCPT2053HTMLCOINHTMLHTML2054Banker TokenBNKBNK2055KaratBank CoinKBCKBC2056InkINKINK2057Colu Local NetworkCLNCLN2058LitecoinCashLCCLCC2059ElectrifyAsiaELECELEC2060BitRewardsBITBIT2061CosmoCoinCOSMCOSM2062Kind AdsKINDKIND2063InmediateDITDIT2064CyCleanCCLCCL2065NimiqNIMNIM2066AML BitcoinABTCABTC2067EcosBallABAABA2068MesseMESSEMESSE2069AXpireAXPRAXPR2070ConstellationDAGDAG2071Acorn Collective TokenOAKOAK2072MarginlessMRSMRS2073Dynamic Trading RightsDTRDTR1892BOX TokenBOXTBOX1893BitcoinusBITSSBITS18951World1WO1WO1896AMLTAMLTAMLT1897BiotronBTRNBTRN1898CanYaCoinCANCAN1899XAYACHICHI1900DACSEEDACSDACS1902Earth TokenEARTHEARTH1903EZTokenEZTEZT1904FlixxoFLIXXFLIXX1905DAOstackGENGEN1906GazeCoinGZEGZE1907Invictus Hyperion FundIHFIHF1908IP ExchangeIPSXIPSX1909KryllKRLKRL1910LALA WorldLALALALA1911SalPaySALSAL1912Signals NetworkSGNSGN1913SIXSIXSIX1914SnipCoinSNIPSNIP1915SophiaTXSPHTXSPHTX1916Thrive TokenTHRTTHRT1917TokenPayTPAYTPAY1918UnibrightUBTUBT1919ProxeusXESXES1920ZebiZCOZCO1921BrylliteBRCBRC1922FidentiaXFDXFDX1923Global Awards TokenGATGAT1924onG.socialONGSONG1925StarterCoinSTACSTAC1926TeleportTPTTPT1927TaTaTuTTUTTU1928WCoinWINWIN1929bitJobSTUSTU1930CosmosATOMATOM1931XNDXNDXND1932SCRLSCRLSCR1933UGASUGASUGAS1934Matic NetworkMATICMATIC1935Wrapped BitcoinWBTCWBTC1936CryptoFrancXCHFXCHF1937Function XFXFX1938OceanOCEANOCEAN1939XYOXYOXYO1940WibsonWIBWIB1941Blue Whale TokenBWXBWX1942Newton ProjectNEWNEW1944ThunderCoreTTTT1945OKBOKBOKB1954YOU COINYOUYOU1965AschXASXAS1966EgretiaEGTEGT1967High Performance BlockchainHPBHPB1982Measurable Data TokenMDTMDT1983ugChainUGCUGC1987DelphyDPYDPY1988SelfSellSSCSSC1989PrimasPSTPST1991ZipperZIPZIP1992CIChainCICCIC1993ChronologicDAYDAY1994DaneelDANDAN1995DomRaider TokenDRTDRT1996Indorse TokenINDIND2074Helbiz TokenHBZHBZ2075Morpheus NetworkMORPHMORPH2076SynthetixSNXSNX2077Synthetix sUSDSUSDSUSD2078LEO TokenLEOLEO2079Vodi XVDXVDX2080Reserve Rights TokenRSRRSR1100Red Pulse Phoenix BinancePHBPHB1101Theta FuelTFUELTFUEL1102ZBTokenZBZB1103UpfiringUFRUFR1129Cai TokenCAICAI1105WinTokenWINTWINT1106Origin SportORSORS1107HYCONHYCHYC1130AirblocABLABL1109BlockcloudBLOCBLOC1110ACE (TokenStars)ACEACE1111Molecular FutureMOFMOF1112TokenClubTCTTCT1113StarChainSTCSTC1114LightChainLIGHTLIGHT1115OFCOINOFOF1131Hi Mutual SocietyHMCHMC1117Beauty ChainBECBEC1118MerculetMVPMVP1119SDChainSDASDA1120ProChainPRAPRA1121OneRoot NetworkRNTRNT1122RealChainRCTRCT1123RefTokenREFREF1133Ubique Chain Of ThingsUCTUCT1125United BitcoinUBTCUBTC1126ShowSHOWSHOW1127Olympus LabsMOTMOT1128IPChainIPCIPC1134OrigoOGOOGO1135HarmonyONEONE1137USDKUSDKUSDK2081BeaxyBXYBXY2082FantomFTMFTM2083AlgorandALGOALGO2084V-IDVIDTVIDT2085VideoCoinVIDVID2086EnergiNRGNRG2087Dusk NetworkDUSKDUSK2088WINkWINKWINK2089WirexWXTWXT2090Bitcoin BEP2BTCBBTCB2091StableUSD BEP2USDSBUSDSB2092ElrondERDERD2093Binance GBP Stable CoinBGBPBGBP2094ContentosCOSCOS2095TrueUSD BEP2TUSDBTUSDB2096Cocos-BCXCOCOSCOCOS2097TomoChainTOMOTOMO2098PerlinPERLPERL2099ChilizCHZCHZ2100AmpleforthAMPLAMPL2101GateChainTokenGTGT2102UltraUOSUOS2103rrbRRBRRB2104Dragon TokenDTDT2105BeamBEAMBEAM2106Tether CNHCNHTCNHT2107AlliveALVALV2108VNT ChainVNTVNT2109En-Tan-MoETMETM2110EminerEMEM2111EchoinECEC2112PledgecampPLGPLG2113X-Power ChainXPOXPO2114FTX TokenFTTXFTTX2115AkropolisAKROAKRO2116Skrumble NetworkSKMSKM2117PivotPVTPVT2118Crypto Neo-value Neural SystemCNNSCNNS2119BHEX TokenBHTBHT2120CarryCRECRE2121ARPA ChainARPAARPA2122VidyCoinVIDYVIDY2123Force ProtocolFORFOR2124RedFOX LabsRFOXRFOX2125CelsiusCELCEL2126AnchorANCTANCT2127Standard Tokenization ProtocolSTPTSTPT2128Contents ProtocolCPTLCPTL2129PrometeusPROMPROM2130FlexacoinFXCFXC2131SPIN ProtocolSPINSPIN2132ChromiaCHRCHR2133PixelPXLPXL2134HedgeTradeHEDGHEDG2135Morpheus.NetworkMRPHMRPH2136Hedera HashgraphHBARHBAR2137Band ProtocolBANDBAND2138Bitpanda Ecosystem TokenBESTBEST2139PantosPANPAN2140Binance USDBUSDBUSD \ No newline at end of file +1301RippleXRPXRP1302Metaverse ETPETPETP1303Bitcoin CashBCHBCH1304OmiseGOOMGOMG1305NeoNEONEO1306IotaMIOTAIOT1307DigitalCashDASHDSH1308ZcashZECZEC1309MoneroXMRXMR1310Ethereum ClassicETCETC1311EOSEOSEOS1312AventusAVTAVT1313QtumQTUMQTM1314SantimentSANSAN1315EidooEDOEDO1316Bitcoin GoldBTGBTG1317StreamrDATADAT1318QASHQASHQSH1319YOYOWYOYOWYYW1321TetherUSDTTHR1322CardanoADAADA1323Binance CoinBNBBNB1325BreadBRDBRD1326GiftoGTOGTO1327IconomiICNICN1329IconICXICX1330LiskLSKLSK1331NanoNANONAN1333SaltSALTSLT1334StratisSTRATSTR1335TronTRXTRX1336WingsWINGSWNG1337Stellar LumensXLMXLM1338VergeXVGXVG1641LitecoinLTCLTC1741BitcoinBTCXBT1841EthereumETHETH8ALBANIALekALLLek12ALGERIAAlgerian DinarDZDDZD20ADPADPADP31AZERBAIJANAzerbaijanian ManatAZMман.32ARGENTINAArgentine PesoARS$36Australian DollarAUD$40ATSATSATS44BAHAMASBahamian DollarBSDBSD48BAHRAINBahraini DinarBHDد.ب.â€50BANGLADESHTakaBDTà§³51ARMENIAArmenian DramAMDÕ¤Ö€.52BARBADOSBarbados DollarBBDBBD56BEFBEFBEF60BERMUDABermudian Dollar (customarily known as Bermuda DolBMDBMD64BHUTANNgultrumBTNBTN68BOLIVIABolivianoBOB$b72BOTSWANAPulaBWPBWP84BELIZEBelize DollarBZDBZ$90SOLOMON ISLANDSSolomon Islands DollarSBDSBD96BRUNEI DARUSSALAMBrunei DollarBND$104MYANMARKyatMMKMMK108BURUNDIBurundi FrancBIFBIF116CAMBODIARielKHR៛124CANADACanadian DollarCAD$132CAPE VERDECape Verde EscudoCVECVE136CAYMAN ISLANDSCayman Islands DollarKYDKYD144SRI LANKASri Lanka RupeeLKRරු.152CHILEChilean PesoCLP$156CHINAYuan RenminbiCNYÂ¥170COLOMBIAColombian PesoCOP$174COMOROSComoro FrancKMFKMF188COSTA RICACosta Rican ColonCRCâ‚¡191CROATIACroatian KunaHRKkn192CUBACuban PesoCUPCUP196CYPRUSCyprus PoundCYPCYP203CZECH REPUBLICCzech KorunaCZK208Danish KroneDKKkr.214DOMINICAN REPUBLICDominican PesoDOPRD$222EL SALVADOREl Salvador ColonSVCSVC230ETHIOPIAEthiopian BirrETBETB232ERITREANakfaERNERN233ESTONIAKroonEEKkr238FALKLAND ISLANDS (MALVINAS)Falkland Islands PoundFKPFKP242FIJIFiji DollarFJDFJD246FIMFIMFIM250FRFFRFFRFFRF262DJIBOUTIDjibouti FrancDJFDJF270GAMBIADalasiGMDGMD276DEMDEMDEM288GHANACediGHCGHC292GIBRALTARGibraltar PoundGIPGIP300GRDGRDGRD320GUATEMALAQuetzalGTQQ324GUINEAGuinea FrancGNFGNF328GUYANAGuyana DollarGYDGYD332HAITIGourdeHTGHTG340HONDURASLempiraHNLL.344HONG KONGHong Kong DollarHKDHK$348HUNGARYForintHUFFt352ICELANDIceland KronaISKkr.356Indian RupeeINRRs.360INDONESIARupiahIDRRp364IRAN (ISLAMIC REPUBLIC OF)Iranian RialIRRريال368IRAQIraqi DinarIQDد.ع.â€372IEPIEPIEP376ISRAELNew Israeli SheqelILS₪380ITLITLITL388JAMAICAJamaican DollarJMDJ$392JAPANYenJPYÂ¥398KAZAKHSTANTengeKZTТ400JORDANJordanian DinarJODد.ا.â€404KENYAKenyan ShillingKESS408KOREA, DEMOCRATIC PEOPLE''S REPUBLIC OFNorth Korean WonKPWKPW410KOREA, DEMOCRATIC PEOPLE''S REPUBLIC OFWonKRWâ‚©414KUWAITKuwaiti DinarKWDد.Ùƒ.â€417KYRGYZSTANSomKGSÑом418LAO PEOPLE''S DEMOCRATIC REPUBLICKipLAKLAK422LEBANONLebanese PoundLBPÙ„.Ù„.â€426LESOTHOLotiLSLLSL428LATVIALatvian LatsLVLLs430LIBERIALiberian DollarLRDLRD434LIBYAN ARAB JAMAHIRIYALibyan DinarLYDد.Ù„.â€440LITHUANIALithuanian LitasLTLLt442LUFLUFLUF446MACAOPatacaMOPMOP454MALAWIKwachaMWKMWK458MALAYSIAMalaysian RinggitMYRRM462MALDIVESRufiyaaMVRÞƒ.470MALTAMaltese Lira^MTLLm478MAURITANIAOuguiyaMROMRO480MAURITIUSMauritius RupeeMURMUR484MEXICOMexican PesoMXN$496MONGOLIATugrikMNTâ‚®498MOLDOVA, REPUBLIC OFMoldovan LeuMDLMDL504Moroccan DirhamMADد.Ù….â€512OMANRial OmaniOMRر.ع.â€516NAMIBIANamibian DollarNADNAD524NEPALNepalese RupeeNPRरà¥528NLGNLGNLG532NETHERLANDS ANTILLESNetherlands Antillian GuikderANGANG533ARUBAAruban GuilderAWGAWG548VANUATUVatuVUVVUV554New Zealand DollarNZD$558NICARAGUACordoba OroNION566NIGERIANairaNGNNGN578Norwegian KroneNOKkr586PAKISTANPakistan RupeePKRRs590PANAMABalboaPABB/.598PAPUA NEW GUINEAKinaPGKPGK600PARAGUAYGuaraniPYGGs604PERUNuevo SolPENS/.608PHILIPPINESPhilippine PesoPHPPhP620PTEPTEPTE624GUINEA-BISSAUGuinea-Bissau PesoGWPGWP634QATARQatari RialQARر.Ù‚.â€642ROMANIAOld LeuROLlei643RUSSIAN FEDERATIONRussian RubleRUBRUB646RWANDARwanda FrancRWFRWF654SAINT HELENASaint Helena PoundSHPSHP678S?O TOME AND PRINCIPEDobraSTDSTD682SAUDI ARABIASaudi RiyalSARر.س.â€690SEYCHELLESSeychelles RupeeSCRSCR694SIERRA LEONELeoneSLLSLL702SINGAPORESingapore DollarSGD$703SLOVAKIASlovak KorunaSKKSk704VIET NAMDongVNDâ‚«705SLOVENIATolarSITSIT706SOMALIASomali ShillingSOSSOS710RandZARR716ZIMBABWEZimbabwe DollarZWDZ$724ESPESPESP736SUDANSudanese DinarSDDSDD748SWAZILANDLilangeniSZLSZL752SWEDENSwedish KronaSEKkr756Swiss FrancCHFfr.760SYRIAN ARAB REPUBLICSyrian PoundSYPÙ„.س.â€764THAILANDBahtTHB฿776TONGAPa''angaTOPTOP777CHINAYuan RenminbiCNHÂ¥780TRINNumericCodeAD AND TOBAGOTrinNumericCodead and Tobago DollarTTDTT$784UNITED ARAB EMIRATESUAE DirhamAEDد.Ø¥.â€788TUNISIATunisian DinarTNDد.ت.â€792TURKEYOld Turkish LiraTRL₤795TURKMENISTANManatTMMm.800UGANDAUganda ShillingUGXUGX807MACEDONIA, THE FORMER YUGOSLAV REPUBLIC OFDenarMKDден.818EGYPTEgyptian PoundEGPج.Ù….â€826UNITED KINGDOMPound SterlingGBP£834TANZANIA, UNITED REPUBLIC OFTanzanian ShillingTZSTZS840US DollarUSD$858URUGUAYPeso UruguayoUYU$U860UZBEKISTANUzbekistan SumUZSÑўм862VENEZUELABolivarVEBBs882SAMOATalaWSTWST886YEMENYemeni RialYERر.ÙŠ.â€891SERBIA AND MONTENEGROSerbian DinarCSDДин.894ZAMBIAKwachaZMKZMK901TAIWAN, PROVINCE OF CHINANew Taiwan DollarTWDNT$943MOZAMBIQUEMericalMZNMZN946ROMANIANew LeuRONRON947SWITZERLANDWIR EuroCHECHE948SWITZERLANDWIR FrancCHWCHW949TURKEYNew Turkish LiraTRYYTL950CFA Franc BEACXAFXAF951East Caribbean DollarXCDXCD952CFA Franc BCEAOXOFXOF953CFP FrancXPFXPF955Bond Markets Units European Composite Unit (EURCO)XBAXBA956European Monetary Unit (E.M.U.-6)XBBXBB957European Unit of Account 9(E.U.A.-9)XBCXBC958European Unit of Account 17(E.U.A.-17)XBDXBD959GoldXAUXAU960INTERNATIONAL MONETARY FUND (I.M.F)SDRXDRXDR961SilverXAGXAG962PlatinumXPTXPT963AlphabeticCodes specifically reserved for testingXTSXTS964PalladiumXPDXPD968SURINAMESurinam DollarSRDSRD969MADAGASCARMalagascy AriaryMGAMGA970COLOMBIAUnNumericCodead de Valor RealCOUCOU971AFGHANISTANAfghaniAFNAFN972TAJIKISTANSomoniTJSTJS973ANGOLAKwanzaAOAAOA974BELARUSBelarussian RubleBYRBYR975BULGARIABulgarian LevBGNBGN976CONGO, THE DEMOCRATIC REPUBLIC OFFranc CongolaisCDFCDF977BOSNIA & HERZEGOVINAConvertible MarksBAMKM978EuroEUR€979MEXICOMexican UnNumericCodead de Inversion (UNumericCodeMXVMXV980UKRAINEHryvniaUAHгрн.981GEORGIALariGELLari984BOLIVIAMvdolBOVBOV985POLANDZlotyPLNzÅ‚986BRAZILBrazilian RealBRLR$990CHILEUnNumericCodeades de formentoCLFCLF997UNITED STATES(Next day)USNUSN998UNITED STATES(Same day)USSUSS999XXXXXX1339ArkARKARK1341KomodoKMDKMD1342Power LedgerPOWRPWR1343AdExADXADX1345AeternityAEAE1346AionAIONAIO1347AmbrosusAMBAMB1349AppCoinsAPPCAPP1350AeronARNARN1351AirSwapASTAST1353Basic Attention TokenBATBAT1354Bitcoin DiamondBCDBCD1355BlockMason Credit ProtocolBCPTBCP1357BluzelleBLZBLZ1358BancorBNTBNT1359ETHOSETHOSBQX1361BitSharesBTSBTS1362BloxCDTCDT1363ChatCoinCHATCHT1365CyberMilesCMTCMT1366CindicatorCNDCND1367CentraCTRCTR1369DigixDAODGDDGD1370AgrelloDLTDLT1371district0xDNTDNT1373aelfELFELF1374EnigmaENGENG1375Enjin CoinENJENJ1377EverexEVXEVX1378EtherpartyFUELFUE1379FunFairFUNFUN1381GasGASGAS1382Genesis VisionGVTGVT1383GXChainGXSGXS1384HshareHSRHSR1385InsolarINSINS1386IOStokenIOSTIOS1387Kyber NetworkKNCKNC1389LendingblockLNDLND1390ChainLinkLINKLNK1391LoopringLRCLRC1393LunyrLUNLUN1394DecentralandMANAMAN1395Crypto.comMCOMCO1396Moeda Loyalty PointsMDAMDA1397ModumMODMOD1399MonethaMTHMTH1401MetalMTLMET1402NavCoinNAVNAV1403Nucleus VisionNCASHNCH1405NeblioNEBLNEB1406NulsNULSNUL1407OpenANXOAXOAX1409OntologyONTONT1411Simple TokenOSTOST1412PIVXPIVXPIV1413POA NetworkPOAPOA1415Po.etPOEPOE1416PopulousPPTPPT1419QLINKQLCQLC1420QuantstampQSPQSP1421Ripio Credit NetworkRCNRCN1423Raiden Network TokenRDNRDN1424Request NetworkREQREQ1425iExec RLCRLCRLC1427Red PulsePHXRPX1429SingularDTVSNGLSSNG1431SONMSNMSNM1432StatusSNTSNT1433SteemSTEEMSTM1435StorjSTORJSTJ1436StormSTORMSRM1437SubstratumSUBSUB1438SyscoinSYSSYS1439Time New BankTNBTNB1441TierionTNTTNT1443TriggersTRIGTRI1444VeChainVETVEN1445ViacoinVIAVIA1447ViberateVIBVIB1448VIBEVIBEVBE1449WaBiWABIWAB1450WanchainWANWAN1451WavesWAVESWVS1452WePowerWPRWPR1453WaltonchainWTCWTC1455NEMXEMXEM1456ZCoinXZCXZC1457ZilliqaZILZIL14590x ProtocolZRXZRX1000HyperCashHCHC1001GoChainGOGO1002Paxos Standard TokenPAXPAX1003RavencoinRVNRVN1004DecredDCRDCR1005MithrilMITHMITH1006USD CoinUSDCUSDC1007Bitcoin SVBSVBSV1008TezosXTZXTZ1009MakerMKRMKR1010DogecoinDOGEDOGE1011BytecoinBCNBCN1012TrueUSDTUSDTUSD1013DigiByteDGBDGB1014SiacoinSCSC1015BytomBTMBTM1016Pundi XNPXSNPXS1017AugurREPREP1018MaidSafeCoinMAIDMAID1019GolemGNTGNT1020ElectroneumETNETN1021HoloHOTHOT1022CryptonexCNXCNX1023FactomFCTFCT1024DaiDAIDAI1025KuCoin SharesKCSKCS1026Worldwide Asset ExchangeWAXWAX1027ArdorARDRARDR1028Huobi TokenHTHT1029MOACMOACMOAC1030RevainRR1031MonaCoinMONAMONA1032NexoNEXONEXO1033ODEMODEODE1034Insight ChainINBINB1035ReddCoinRDDRDD1036MixinXINXIN1037DentacoinDCNDCN1038HorizenZENZEN1039PolymathPOLYPOLY1040NasdacoinNSDNSD1041SIRIN LABS TokenSRNSRN1042Digitex FuturesDGTXDGTX1043DropilDROPDROP1044NxtNXTNXT1045MobileGoMGOMGO1046BOScoinBOSBOS1047TenXPAYPAY1048Theta TokenTHETATHETA1049NebulasNASNAS1050QuarkChainQKCQKC1051Loom NetworkLOOMLOOM1052VeritaseumVERIVERI1053ElastosELAELA1054WaykiChainWICCWICC1055ETERNAL TOKENXETXET1056DragonchainDRGNDRGN1057ProximaXXPXXPX1058Bitcoin PrivateBTCPBTCP1059Gemini DollarGUSDGUSD1060LinkeyLKYLKY1061BHPCashBHPCBHPC1062SmartlandsSLTSLT1063NectarNECNEC1064CivicCVCCVC1065OdysseyOCNOCN1066Endor ProtocolEDREDR1067Bibox TokenBIXBIX1068ARBITRAGEARBARB1069Optimal Shelf...OSAOSA1070DentDENTDENT1071GroestlcoinGRSGRS1072Byteball BytesGBYTEGBYTE1073RChainRHOCRHOC1074THEKEYTKYTKY1075CentralityCENNZCENNZ1076PeercoinPPCPPC1077EmercoinEMCEMC1078ETH LendLENDLEND1079Cloak CoinCLOAKCLOAK1080SKYSKYSKY1081IOTXIOTXIOTX1082SingularityNETAGIAGI1083NexusNXSNXS1084Key CoinKEYKEY1085MainframeMFTMFT1086DOCKDOCKDOCK1087Bit ConnectBCCBCC1088VENVENVEN1089Red PulseRPXRPX1090RENRENREN1091EthosBQXBQX1092BnkToTheFutureBFTBFT1093FSNFSNFSN1094MatrixMANMAN1095GnosisGNOGNO1096MelonMLNMLN1097NamecoinNMCNMC1098VertcoinVTCVTC1099BurstBURSTBURST1830Steem DollarsSTEEMDSBD1332BitTorrentBTTBTT1831ClamsCLAMCLAM1832FOAMFOAMFOAM1833GameCreditsGAMEGAME1835LBRY CreditsLBCLBC1836NumeraireNMRNMR1837Pascal CoinPASCPASC1838CounterpartyXCPXCP1839PrimecoinXPMXPM1829StableUSDUSDSUSDS1823STASIS EURSEURSEURS1824UTRUSTUTKUTK1825CortexCTXCCTXC1827Project PaiPAIPAI1828SmartMeshSMTSMT1794GrinGRINGRIN1796Unikoin GoldUKGUKG1797Genaro NetworkGNXGNX1798PentaPNTPNT1799Content Neutrality NetworkCNNCNN1801CredLBALBA1802BlocktixTIXTIX1803LympoLYMLYM1804All SportsSOCSOC1805Jibrel NetworkJNTJNT1806DATADTADTA1808AchainACTACT1809TokenCardTKNTKN1810PropyPROPRO1811DigitalNoteXDNXDN1812CrypteriumCRPTCRPT1813AragonANTANT1814BLOCKvVEEVEE1815BlocknetBLOCKBLOCK1816PumaPayPMAPMA1817IgnisIGNISIGNIS1819EdgelessEDGEDG1821Ontology GasONGONG1822Fetch.AIFETFET1793HUSD SolutionHUSDHUSD1632Ink ProtocolXNKXNK1633Crowd MachineCMCTCMCT1636NexiumNXCNXC1637SIBCoinSIBSIB1638Swarm CitySWTSWT1639PatientoryPTOYPTOY1640BANKEXBKXBKX1644MatchpoolGUPGUP1645HumaniqHMQHMQ1647HyperSpaceAMPAMP1648DECENTDCTDCT1649SpaceChainSPCSPC1650NAGANGCNGC1651NoLimitCoinNLC2NLC21652AeonAEONAEON1653OriginTrailTRACTRAC1655eBoostEBSTEBST1656CannabisCoinCANNCANN1657BreakoutBRKBRK1658SequenceSEQSEQ1659TransferCoinTXTX1660Memetic / PepeCoinMEMEMEME1661DopeCoinDOPEDOPE1662Internet of PeopleIOPIOP1663VeriumReserveVRMVRM1664PinkCoinPINKPINK1665SyndicateSYNXSYNX16662GIVE2GIVE2GIVE1667ExclusiveCoinEXCLEXCL1668DynamicDYNDYN1669ArtByteABYABY1670FoldingCoinFLDCFLDC1671KoreKOREKORE1672GeoCoinGEOGEO1673ExpanseEXPEXP1674OKCashOKOK1675MusicoinMUSICMUSIC1676GolosGOLOSGOLOS1677Blockparty (BOXX Token)BOXXBOXX1679CurecoinCURECURE1680SolarCoinSLRSLR1681BloomBLTBLT1683Decision TokenHSTHST1684Haven ProtocolXHVXHV1685GridCoinGRCGRC1686MonetaryUnitMUEMUE1687MyriadXMYXMY1688DiamondDMDDMD1689I/O CoinIOCIOC1691Bean CashBITBBITB1692CrownCRWCRW1693RadiumRADSRADS1695VeriCoinVRCVRC1696IncentINCNTINCNT1697RevolutionVRRVRRVR1698XELXELXEL1699UpTokenUPUP1700IONIONION1701BitTubeTUBETUBE1707HempCoinTHCTHC1708FeathercoinFTCFTC1709ShiftSHIFTSHIFT1711adTokenADTADT1712PotCoinPOTPOT1713BlackCoinBLKBLK1714Sentinel ProtocolUPPUPP1715MercuryMERMER1717MobiusMOBIMOBI1718ZClassicZCLZCL1719CashBet CoinCBCCBC1720MetronomeMETMET1721VITEVITEVITE1722HydroHYDROHYDRO1723BitBayBAYBAY1725IHT Real Estate ProtocolIHTIHT1726RefereumRFRRFR1727UbiqUBQUBQ1728FLOFLOFLO1729WhiteCoinXWCXWC1730Moss CoinMOCMOC1731NKNNKNNKN1732QuantQNTQNT1733Crypto.com ChainCROCRO1734ParticlPARTPART1735Quantum Resistant LedgerQRLQRL1737DMarketDMTDMT1738SaluSSLSSLS1739MediBloc [ERC20]MEDXMEDX1740EinsteiniumEMC2EMC21742AidCoinAIDAID1743AuctusAUCAUC1744Banyan NetworkBBNBBN1745Bitcoin InterestBCIBCI1746CommerceBlockCBTCBT1747Callisto NetworkCLOCLO1749Digix Gold TokenDGXDGX1750DetherDTHDTH1751EssentiaESSESS1753ParkinGoGOTGOT1754Internet Node TokenINTINT1755On.LiveONLONL1757KlerosPNKPNK1758RIF TokenRIFRIF1759Rate3RTERTE1761ConsensusSENSEN1762VetriVLDVLD1763WOLLOWLOWLO1765XribaXRAXRA17660ChainZCNZCN1767Recovery Right TokensRRTRRT1768CreditsCSCS1769DADIDADIDADI1770Tether EuroEURTEURt1771EveripediaIQIQ1772MedicalchainMTNMTN1773AutonioANIONIO1774OmniOMNIOMNI1775ORS GroupORSGORS1778BlockpassPASSPASS1779RSK Smart BitcoinRBTCRBTC1781SEERSEERSEER1782SpankChainSPANKSPANK1783UniversaUTNPUTNP1785V SystemsVSYSVSYS1786V YggdrashYEEDYEED1787Hydro ProtocolHOTPHOT1789ContentBoxBOXBOX1790AtonomiATMIATMI1791The AbyssABYSSABYSS1630Atlas ProtocolATPATP16311BG1BG1BG1626Time Space ChainTSCTSC1627BerithBRTBRT1628BitMart TokenBMXBMX1629Bitcoin HDXHDBHD1625WoChainWOCWOC1623Celer NetworkCELRCELR1622Ether Kingdoms TokenIMPIMP1621MaecenasARTART1619VeriblockVBKVBK1618PlayChipPLAPLA1617OrbsORBSORBS1614TTC ProtocolTTCTTC1615ForestingPTONPTON1616PCHAINPIPI1612AnkrANKRANKR1613AergoAERGOAERGO1610MetadiumMETAMETA1611GoldCoinGLCGLC1605PAL NetworkPALPAL1606Solve.CareSOLVESOLVE1607BTU ProtocolBTUBTU1609SpendcoinSPNDSPND1602SphereSPHRSPHR1603ServeSERVSERV1597Circuits of ValueCOVALCOVAL1599Breakout StakeBRXBRX1601BitswiftBITSBITS1596Golos GoldGBGGBG1594EverGreenCoinEGCEGC1595DatabitsDTBDTB1587QwarkQWARKQWARK1588NeosCoinNEOSNEOS1589NuBitsNBTNBT1591More CoinMOREMORE1592HxroHXROHXRO1593GambitGAMGAM1584StealthXSTXST1585TokesTKSTKS1582GuldenCNLGNLG1583BitSendCBSDBSD1581HunterCoinHUCHUC1580LivepeerLPTLPT1579BORABORABORA1577STACSSTACSSTACS1576HOT TokenHOTTHOT1575DreamTeamDREAMDREAM1574TOPTOPNTOP1568Machine Xchange CoinMXCMXC1569COVACOVACOVA1570LambdaLAMBLAMB1571Content Value NetworkCVNTCVNT1572RuffRUFFRUFF1573LinkEyeLETLET1563Davinci CoinDACDAC1564TripioTRIOTRIO1565InvestDigitalIDTIDT1567Huobi Pool TokenHPTHPT1556ThingsOperatingSystemTOSTOS1557Globalvillage EcosystemGVEGVE1559NeuroChainNCCNCC1560KcashKCASHKCASH1561CVCoinCVNCVN1562BitCapitalVendorBCVBCV1551Yuan Chain CoinYCCYCC1552BitUP TokenBUTBUT1553SmartshareSSPSSP1555MyTokenMTMT1546DATxDATXDATX1547ThemisGETGET1549GET ProtocolGETPGET1550U NetworkUUUUUU1540XMaxXMXXMX1541YouLive CoinUCUC1542Acute Angle CloudAACAAC1543SeeleSEELESEELE1544UnlimitedIPUIPUIP1545LitexLXTLXT1537FansTimeFTIFTI1538Global Social ChainGSCGSC1539Promotion CoinPCPC1531EDUCareEKTEKT1534BeeKanBKBTBKBT1535FairGameFAIRFAIR1536Game.comGTCGTC1527Intelligent Investment ChainIICIIC1529ShineChainSHESHE1530MEXMEXMEX1522QunQunQUNQUN1523EduCoinEDUEDU1525BitcoinXBCXBCX1526HitChainHITHIT1520SunContractSNCSNC1521STKSTKSTK1517YEEYEEYEE1518EchoLinkEKOEKO1519DeepBrain ChainDBCDBC1513ZillaZLAZLA1514ArcblockABTABT1515MatryxMTXMTX1511BitKanKANKAN1506TopChainTOPCTOPC1507CoinMeetMEETMEET1508SwftCoinSWFTCSWFTC1509MediSharesMDSMDS1510IoT ChainITCITC1501EngineEGCCEGCC1502AI DoctorAIDOCAIDOC1503Super BitcoinSBTCSBTC1505Bitcoin FileBIFIBIFI1500IRIS NetworkIRISIRIS1494MuskMUSKMUSK1495PortalPORTALPORTAL1497RCCCRCCCRCCC1499DatumDATDAT1492ZJLT Distributed Factoring NetworkZJLTZJLT1493Block 1818C18C1491MARK.SPACEMRKMRK1490AdHiveADHADH1479FLIPFLPFLP1489Dragon CoinsDRGDRG1481FarmaTrustFTTFTT1482LikeCoinLIKELIKE1483Morpheus LabsMITXMITX1485StoxSTXSTX1486ZPERZPRZPR1487FintruX NetworkFTXFTX1488Plus-CoinNPLCNPLC1477Huobi 10 IndexHB10HB101476ObsidianODNODN1472PitchPITCHPITCH1473Purple Butterfly TradingPBTTPBTT1474PatronPATPAT1475OpusOPTOPT1463ProCurrencyPROCPROC1464PresearchPREPRE1465PaymonPMNTPMNT1466PlutonPLUPLU1467PillarPLRPLR1468PolybiusPLBTPLBT1469PlaykeyPKTPKT1471LampixPIXPIX1460Quanta Utility TokenQNTUQNTU1461PlayGamePXGPXG1842imbrexREXREX1843BitRentRNTBRNTB1844RobotinaROXROX1845RivetzRVTRVT1846SociallSCLSCL1847SentinelSENTSENT1848ShipChainSHIPSHIP1849Signal TokenSIGSIG1850SilkChainSILKSILK1851SlateSLXSLX1852SmartCashSMARTSMART1853SnowballSNBLSNBL1854SPINDLESPDSPD1855SportyCoSPFSPF1856StarbaseSTARSTAR1857StoriqaSTQSTQ1859SunchainSUNCSUNC1861SuretlySURSUR1863savedroidSVDSVD1864SwarmSWMSWM1865TaaSTAASTAAS1866LamdenTAUTAU1867TrueDeckTDPTDP1868TokenDeskTDSTDS1869TelcoinTELTEL1870ChronobankTIMETIME1871TradcoinTRADTRAD1872WeTrustTRSTTRST1873TrueChainTRUETRUE1874Useless Ethereum TokenUETUET1875Usechain TokenUSEUSE1876United Traders TokenUTTUTT1877VeriMEVMEVME1878Provoco TokenVOCOVOCO1879Wiki TokenWIKIWIKI1880CrowdWizWIZWIZ1881XaurumXAURXAUR1883BlitzPredictXBPXBP1884Monero ClassicXMCXMC1885Exchange UnionXUCXUC1887ZapZAPZAP1888ZeepinZPTZPT1889ZrCoinZRCZRC1890ZeusshieldZSCZSC2000ATLANT TokenATLATL2001BANCABANCABANCA2002BerryBERRYBERRY2003BetterBettingBETRBETR2004BitClaveCATCAT2005BitcoreBTXBTX2006BitDegreeBDGBDG2007BitDiceCSNOCSNO2008Black MoonBMCBMC2009BlockMeshBMHBMH2010CashaaCASCAS2011CoinPokerCHPCHP2012COPYTRACKCPYCPY2013CovestingCOVCOV2014Crypto20C20C202015CryptopayCPAYCPAY2016CUBEAUTOAUTO2017Curriculum VitaeCVHCVH2018CyberVeinTokenCVTCVT2019DAO CasinoBETBET2020DecentBetDBETDBET2021DIMCOINDIMDIM2022EtherollDICEDICE2023First Blood1ST1ST2024FortunaFOTAFOTA2025GoByteGBXGBX2026HappycoinHPCHPC2027Hive ProjectHVNHVN2028indaHashIDHIDH2029InsurChainINSURINSUR2030InsurePalIPLIPL2031iXledgerIXTIXT2032KickCoinKICKKICK2033KINKINKIN2034LATokenLALA2035LifeLIFELIFE2036LockTripLOCLOC2037MeshBoxMESHMESH2038Micro MoneyAMMAMM2039MybitMYBMYB2040NectarNCTNCT2041NeumarkNEUNEU2042NOAHCOINNOAHNOAH2043SwissBorgCHSBCHSB2044AlphacatACATACAT2045Freyr ChainFRECFREC2046ConsentiumCSMCSM2047NanjcoinNANJNANJ2048NeuroTokenNTKNTK2049FuzeXFXTFXT2050ChainiumCHXCHX2051FriendZ CoinFDZFDZ2052CryptaurCPTCPT2053HTMLCOINHTMLHTML2054Banker TokenBNKBNK2055KaratBank CoinKBCKBC2056InkINKINK2057Colu Local NetworkCLNCLN2058LitecoinCashLCCLCC2059ElectrifyAsiaELECELEC2060BitRewardsBITBIT2061CosmoCoinCOSMCOSM2062Kind AdsKINDKIND2063InmediateDITDIT2064CyCleanCCLCCL2065NimiqNIMNIM2066AML BitcoinABTCABTC2067EcosBallABAABA2068MesseMESSEMESSE2069AXpireAXPRAXPR2070ConstellationDAGDAG2071Acorn Collective TokenOAKOAK2072MarginlessMRSMRS2073Dynamic Trading RightsDTRDTR1892BOX TokenBOXTBOX1893BitcoinusBITSSBITS18951World1WO1WO1896AMLTAMLTAMLT1897BiotronBTRNBTRN1898CanYaCoinCANCAN1899XAYACHICHI1900DACSEEDACSDACS1902Earth TokenEARTHEARTH1903EZTokenEZTEZT1904FlixxoFLIXXFLIXX1905DAOstackGENGEN1906GazeCoinGZEGZE1907Invictus Hyperion FundIHFIHF1908IP ExchangeIPSXIPSX1909KryllKRLKRL1910LALA WorldLALALALA1911SalPaySALSAL1912Signals NetworkSGNSGN1913SIXSIXSIX1914SnipCoinSNIPSNIP1915SophiaTXSPHTXSPHTX1916Thrive TokenTHRTTHRT1917TokenPayTPAYTPAY1918UnibrightUBTUBT1919ProxeusXESXES1920ZebiZCOZCO1921BrylliteBRCBRC1922FidentiaXFDXFDX1923Global Awards TokenGATGAT1924onG.socialONGSONG1925StarterCoinSTACSTAC1926TeleportTPTTPT1927TaTaTuTTUTTU1928WCoinWINWIN1929bitJobSTUSTU1930CosmosATOMATOM1931XNDXNDXND1932SCRLSCRLSCR1933UGASUGASUGAS1934Matic NetworkMATICMATIC1935Wrapped BitcoinWBTCWBTC1936CryptoFrancXCHFXCHF1937Function XFXFX1938OceanOCEANOCEAN1939XYOXYOXYO1940WibsonWIBWIB1941Blue Whale TokenBWXBWX1942Newton ProjectNEWNEW1944ThunderCoreTTTT1945OKBOKBOKB1954YOU COINYOUYOU1965AschXASXAS1966EgretiaEGTEGT1967High Performance BlockchainHPBHPB1982Measurable Data TokenMDTMDT1983ugChainUGCUGC1987DelphyDPYDPY1988SelfSellSSCSSC1989PrimasPSTPST1991ZipperZIPZIP1992CIChainCICCIC1993ChronologicDAYDAY1994DaneelDANDAN1995DomRaider TokenDRTDRT1996Indorse TokenINDIND2074Helbiz TokenHBZHBZ2075Morpheus NetworkMORPHMORPH2076SynthetixSNXSNX2077Synthetix sUSDSUSDSUSD2078LEO TokenLEOLEO2079Vodi XVDXVDX2080Reserve Rights TokenRSRRSR1100Red Pulse Phoenix BinancePHBPHB1101Theta FuelTFUELTFUEL1102ZBTokenZBZB1103UpfiringUFRUFR1129Cai TokenCAICAI1105WinTokenWINTWINT1106Origin SportORSORS1107HYCONHYCHYC1130AirblocABLABL1109BlockcloudBLOCBLOC1110ACE (TokenStars)ACEACE1111Molecular FutureMOFMOF1112TokenClubTCTTCT1113StarChainSTCSTC1114LightChainLIGHTLIGHT1115OFCOINOFOF1131Hi Mutual SocietyHMCHMC1117Beauty ChainBECBEC1118MerculetMVPMVP1119SDChainSDASDA1120ProChainPRAPRA1121OneRoot NetworkRNTRNT1122RealChainRCTRCT1123RefTokenREFREF1133Ubique Chain Of ThingsUCTUCT1125United BitcoinUBTCUBTC1126ShowSHOWSHOW1127Olympus LabsMOTMOT1128IPChainIPCIPC1134OrigoOGOOGO1135HarmonyONEONE1137USDKUSDKUSDK2081BeaxyBXYBXY2082FantomFTMFTM2083AlgorandALGOALGO2084V-IDVIDTVIDT2085VideoCoinVIDVID2086EnergiNRGNRG2087Dusk NetworkDUSKDUSK2088WINkWINKWINK2089WirexWXTWXT2090Bitcoin BEP2BTCBBTCB2091StableUSD BEP2USDSBUSDSB2092ElrondERDERD2093Binance GBP Stable CoinBGBPBGBP2094ContentosCOSCOS2095TrueUSD BEP2TUSDBTUSDB2096Cocos-BCXCOCOSCOCOS2097TomoChainTOMOTOMO2098PerlinPERLPERL2099ChilizCHZCHZ2100AmpleforthAMPLAMPL2101GateChainTokenGTGT2102UltraUOSUOS2103rrbRRBRRB2104Dragon TokenDTDT2105BeamBEAMBEAM2106Tether CNHCNHTCNHT2107AlliveALVALV2108VNT ChainVNTVNT2109En-Tan-MoETMETM2110EminerEMEM2111EchoinECEC2112PledgecampPLGPLG2113X-Power ChainXPOXPO2114FTX TokenFTTXFTTX2115AkropolisAKROAKRO2116Skrumble NetworkSKMSKM2117PivotPVTPVT2118Crypto Neo-value Neural SystemCNNSCNNS2119BHEX TokenBHTBHT2120CarryCRECRE2121ARPA ChainARPAARPA2122VidyCoinVIDYVIDY2123Force ProtocolFORFOR2124RedFOX LabsRFOXRFOX2125CelsiusCELCEL2126AnchorANCTANCT2127Standard Tokenization ProtocolSTPTSTPT2128Contents ProtocolCPTLCPTL2129PrometeusPROMPROM2130FlexacoinFXCFXC2131SPIN ProtocolSPINSPIN2132ChromiaCHRCHR2133PixelPXLPXL2134HedgeTradeHEDGHEDG2135Morpheus.NetworkMRPHMRPH2136Hedera HashgraphHBARHBAR2137Band ProtocolBANDBAND2138Bitpanda Ecosystem TokenBESTBEST2139PantosPANPAN2140Binance USDBUSDBUSD2141Infinitus TokenINFINF2142PAX GoldPAXGPAXG \ No newline at end of file From d6b43709c61c084d45b1d96c9d80a152d1f4256c Mon Sep 17 00:00:00 2001 From: Alexei Osipov Date: Thu, 7 Nov 2019 00:27:26 +0300 Subject: [PATCH 2202/2572] Move executable tools into a separate module --- settings.gradle | 2 +- tools/build.gradle | 5 + .../java/deltix/util/csvx/CSVFilter-usage.txt | 46 +- .../main/java/deltix/util/csvx/CSVFilter.java | 226 ++++---- .../main/java/deltix/util/jdbc/JSQLPlus.java | 146 ++--- .../main/java/deltix/util/jdbc/LoadCSV.java | 312 +++++------ .../java/deltix/util/jdbc/MDB2ORACLE.java | 434 +++++++-------- .../main/java/deltix/util/jdbc/MDDump.java | 82 +-- .../java/deltix/util/jdbc/ORACLE2MDB.java | 522 +++++++++--------- .../util/os/DotNetFrameworkVersionTester.java | 210 +++---- .../src/main/java/deltix/util/xml/XSLT.java | 80 +-- 11 files changed, 1035 insertions(+), 1030 deletions(-) create mode 100644 tools/build.gradle rename {util => tools}/src/main/java/deltix/util/csvx/CSVFilter-usage.txt (97%) rename {util => tools}/src/main/java/deltix/util/csvx/CSVFilter.java (97%) rename {util => tools}/src/main/java/deltix/util/jdbc/JSQLPlus.java (96%) rename {util => tools}/src/main/java/deltix/util/jdbc/LoadCSV.java (96%) rename {util => tools}/src/main/java/deltix/util/jdbc/MDB2ORACLE.java (97%) rename {util => tools}/src/main/java/deltix/util/jdbc/MDDump.java (97%) rename {util => tools}/src/main/java/deltix/util/jdbc/ORACLE2MDB.java (97%) rename {util => tools}/src/main/java/deltix/util/os/DotNetFrameworkVersionTester.java (96%) rename {util => tools}/src/main/java/deltix/util/xml/XSLT.java (96%) diff --git a/settings.gradle b/settings.gradle index fd24247b..4c8daf3a 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,3 +1,3 @@ //rootProject.name = 'commons' -include ':lang', ':collections', ':util', ':log', ':gui' \ No newline at end of file +include ':lang', ':collections', ':util', ':log', ':gui', ':tools' \ No newline at end of file diff --git a/tools/build.gradle b/tools/build.gradle new file mode 100644 index 00000000..e7b0f5b9 --- /dev/null +++ b/tools/build.gradle @@ -0,0 +1,5 @@ +description = 'QuantServer general purpose utilities' + +dependencies { + compile project(':util') +} diff --git a/util/src/main/java/deltix/util/csvx/CSVFilter-usage.txt b/tools/src/main/java/deltix/util/csvx/CSVFilter-usage.txt similarity index 97% rename from util/src/main/java/deltix/util/csvx/CSVFilter-usage.txt rename to tools/src/main/java/deltix/util/csvx/CSVFilter-usage.txt index 4cd0d5a4..b9c7e442 100644 --- a/util/src/main/java/deltix/util/csvx/CSVFilter-usage.txt +++ b/tools/src/main/java/deltix/util/csvx/CSVFilter-usage.txt @@ -1,23 +1,23 @@ -Usage: csv