From 6bb6d88371e8c21e7e34270a5fd42b1288280937 Mon Sep 17 00:00:00 2001 From: 7u83 <7u83@mail.ru> Date: Tue, 4 Dec 2018 01:36:00 +0100 Subject: [PATCH] Creates assets in world from JSON --- .../gui/AssetEditor/AssetListPanel.java | 2 +- src/opensesim/gui/Globals.java | 16 ++-- src/opensesim/gui/SeSimApplication.java | 3 +- src/opensesim/gui/util/Json.java | 16 +++- .../sesim/Assets/CryptoCurrency.java | 8 ++ src/opensesim/sesim/Assets/CurrencyAsset.java | 8 ++ src/opensesim/sesim/Assets/FurtureAsset.java | 9 +++ src/opensesim/sesim/Assets/StockAssett.java | 8 ++ src/opensesim/sesim/Assets/WarrentAsset.java | 8 ++ src/opensesim/world/AbstractAsset.java | 80 +++++++++---------- src/opensesim/world/Exchange.java | 9 +-- src/opensesim/world/Order.java | 18 ++--- src/opensesim/world/World.java | 53 ++++++++---- .../util/idgenerator/IDGeneratorTest.java | 23 +++--- test/opensesim/world/ExchangeTest.java | 64 +++++++++++++++ 15 files changed, 234 insertions(+), 91 deletions(-) create mode 100644 test/opensesim/world/ExchangeTest.java diff --git a/src/opensesim/gui/AssetEditor/AssetListPanel.java b/src/opensesim/gui/AssetEditor/AssetListPanel.java index b36526c..1d3c8ba 100644 --- a/src/opensesim/gui/AssetEditor/AssetListPanel.java +++ b/src/opensesim/gui/AssetEditor/AssetListPanel.java @@ -92,7 +92,7 @@ public class AssetListPanel extends javax.swing.JPanel implements GuiSelectionLi String type_name; try { - type_name=a.getConstructor().newInstance().getTypeName(); + type_name=a.getConstructor(World.class,JSONObject.class).newInstance(null,null).getTypeName(); } catch (NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) { Logger.getLogger(AssetListPanel.class.getName()).log(Level.SEVERE, null, ex); diff --git a/src/opensesim/gui/Globals.java b/src/opensesim/gui/Globals.java index 4a4782a..ef20e74 100644 --- a/src/opensesim/gui/Globals.java +++ b/src/opensesim/gui/Globals.java @@ -445,13 +445,7 @@ public class Globals { } - public static JSONObject getWorld(){ - JSONObject world = new JSONObject(); - world.put(PrefKeys.ASSETS, getAssets()); - world.put(PrefKeys.EXCHANGES, getExchanges()); - return world; - } - + public static void clearAll() { putStrategies(new JSONObject()); putTraders(new JSONArray()); @@ -466,5 +460,13 @@ public class Globals { loadString(s); } + + + public static JSONObject getWorld(){ + JSONObject cfg = new JSONObject(); + cfg.put(World.JKEYS.ASSETS, getAssets()); + cfg.put(World.JKEYS.EXCHANGES, getExchanges()); + return cfg; + } } diff --git a/src/opensesim/gui/SeSimApplication.java b/src/opensesim/gui/SeSimApplication.java index 5735660..0a5d00c 100644 --- a/src/opensesim/gui/SeSimApplication.java +++ b/src/opensesim/gui/SeSimApplication.java @@ -69,6 +69,7 @@ import opensesim.old_sesim.Exchange; import opensesim.old_sesim.Scheduler; import opensesim.util.XClassLoader; +import opensesim.world.World; /** * @@ -598,7 +599,7 @@ public class SeSimApplication extends javax.swing.JFrame { void startSim() { - // World = new World(); + World world = new World(Globals.getWorld()); diff --git a/src/opensesim/gui/util/Json.java b/src/opensesim/gui/util/Json.java index d5c75aa..9132487 100644 --- a/src/opensesim/gui/util/Json.java +++ b/src/opensesim/gui/util/Json.java @@ -129,16 +129,30 @@ public class Json { } Class cls = f.getType(); + String name = null == imp.value() ? f.getName() : imp.value(); + + // JTextField if (JTextField.class.isAssignableFrom(cls)) { try { JTextField tf = (JTextField) f.get(o); - String name = null == imp.value() ? f.getName() : imp.value(); + tf.setText(jo.optString(name)); } catch (IllegalArgumentException | IllegalAccessException ex1) { Logger.getLogger(Json.class.getName()).log(Level.SEVERE, null, ex1); } continue; } + + // String + if (String.class.isAssignableFrom(cls)) { + try { + f.set(o, jo.optString(name)); + } catch (IllegalArgumentException | IllegalAccessException ex1) { + Logger.getLogger(Json.class.getName()).log(Level.SEVERE, null, ex1); + } + continue; + } + } Method[] methods = o.getClass().getMethods(); diff --git a/src/opensesim/sesim/Assets/CryptoCurrency.java b/src/opensesim/sesim/Assets/CryptoCurrency.java index 5f56baf..6b6d774 100644 --- a/src/opensesim/sesim/Assets/CryptoCurrency.java +++ b/src/opensesim/sesim/Assets/CryptoCurrency.java @@ -26,6 +26,8 @@ package opensesim.sesim.Assets; import opensesim.world.AbstractAsset; +import opensesim.world.World; +import org.json.JSONObject; /** * @@ -33,6 +35,12 @@ import opensesim.world.AbstractAsset; */ public class CryptoCurrency extends AbstractAsset{ + public CryptoCurrency(World world, JSONObject cfg) { + super(world, cfg); + } + + + @Override public String getTypeName() { return "Crypto Currency"; diff --git a/src/opensesim/sesim/Assets/CurrencyAsset.java b/src/opensesim/sesim/Assets/CurrencyAsset.java index 065ea10..c81994f 100644 --- a/src/opensesim/sesim/Assets/CurrencyAsset.java +++ b/src/opensesim/sesim/Assets/CurrencyAsset.java @@ -26,6 +26,8 @@ package opensesim.sesim.Assets; import opensesim.world.AbstractAsset; +import opensesim.world.World; +import org.json.JSONObject; /** * @@ -33,6 +35,12 @@ import opensesim.world.AbstractAsset; */ public class CurrencyAsset extends AbstractAsset { + public CurrencyAsset(World world, JSONObject cfg) { + super(world, cfg); + } + + + @Override public String getTypeName() { return "Currency"; diff --git a/src/opensesim/sesim/Assets/FurtureAsset.java b/src/opensesim/sesim/Assets/FurtureAsset.java index 3ce56a8..e9100f4 100644 --- a/src/opensesim/sesim/Assets/FurtureAsset.java +++ b/src/opensesim/sesim/Assets/FurtureAsset.java @@ -27,12 +27,21 @@ package opensesim.sesim.Assets; import javax.swing.JPanel; import opensesim.world.AbstractAsset; +import opensesim.world.World; +import org.json.JSONObject; /** * * @author 7u83 <7u83@mail.ru> */ public class FurtureAsset extends AbstractAsset{ + + public FurtureAsset(World world, JSONObject cfg) { + super(world, cfg); + } + + + @Override public String getTypeName(){ return "Future"; diff --git a/src/opensesim/sesim/Assets/StockAssett.java b/src/opensesim/sesim/Assets/StockAssett.java index 87bdff8..813cca0 100644 --- a/src/opensesim/sesim/Assets/StockAssett.java +++ b/src/opensesim/sesim/Assets/StockAssett.java @@ -26,6 +26,8 @@ package opensesim.sesim.Assets; import opensesim.world.AbstractAsset; +import opensesim.world.World; +import org.json.JSONObject; /** * @@ -33,6 +35,12 @@ import opensesim.world.AbstractAsset; */ public class StockAssett extends AbstractAsset{ + public StockAssett(World world, JSONObject cfg) { + super(world, cfg); + } + + + @Override public String getTypeName() { return "Stock"; diff --git a/src/opensesim/sesim/Assets/WarrentAsset.java b/src/opensesim/sesim/Assets/WarrentAsset.java index 0acea40..874d6e5 100644 --- a/src/opensesim/sesim/Assets/WarrentAsset.java +++ b/src/opensesim/sesim/Assets/WarrentAsset.java @@ -26,12 +26,20 @@ package opensesim.sesim.Assets; import opensesim.world.AbstractAsset; +import opensesim.world.World; +import org.json.JSONObject; /** * * @author 7u83 <7u83@mail.ru> */ public class WarrentAsset extends AbstractAsset{ + + public WarrentAsset(World world, JSONObject cfg) { + super(world, cfg); + } + + @Override public String getTypeName(){ return "Warrent"; diff --git a/src/opensesim/world/AbstractAsset.java b/src/opensesim/world/AbstractAsset.java index 1dba758..fb7eb62 100644 --- a/src/opensesim/world/AbstractAsset.java +++ b/src/opensesim/world/AbstractAsset.java @@ -25,10 +25,11 @@ */ package opensesim.world; - import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.JPanel; +import opensesim.gui.util.Json; +import opensesim.gui.util.Json.Import; import opensesim.sesim.interfaces.Configurable; import opensesim.util.idgenerator.Id; @@ -39,9 +40,11 @@ import org.json.JSONObject; * * @author 7u83 <7u83@mail.ru> */ -public abstract class AbstractAsset implements Configurable { +public abstract class AbstractAsset { + + World world; + - private Id id; private String symbol; private String name; private String description; @@ -49,18 +52,22 @@ public abstract class AbstractAsset implements Configurable { /** * Constructor + * @param world + * @param cfg */ - protected AbstractAsset() { - id = null; + public AbstractAsset(World world, JSONObject cfg) { + if (world == null) + return; + symbol = cfg.getString("symbol"); + name = cfg.getString("name"); + decimals = cfg.optInt("decimals",0); + + this.world = world; } + + public abstract String getTypeName(); - - - - public void setDecimals(int decimals) { - this.decimals = decimals; - } public int getDecimals() { return decimals; @@ -70,10 +77,6 @@ public abstract class AbstractAsset implements Configurable { this.description = description; } - public Id getID() { - return id; - } - public String getSymbol() { return symbol; } @@ -82,25 +85,20 @@ public abstract class AbstractAsset implements Configurable { return name; } - public void setName(String name) { - this.name = name; - } - public String getDescription() { return description; } - - public boolean isCurrency(){ - return false; - } - public boolean isAsset(){ - return false; - } - - - public static final String JSON_ID ="id"; - public static final String JSON_CLASS = "class"; + public boolean isCurrency() { + return false; + } + + public boolean isAsset() { + return false; + } + + public static final String JSON_ID = "id"; + public static final String JSON_CLASS = "class"; public static final String JSON_SYMBOL = "symbol"; public static final String JSON_NAME = "name"; public static final String JSON_DESCRIPTION = "description"; @@ -118,9 +116,10 @@ public abstract class AbstractAsset implements Configurable { } - public static AbstractAsset create(World world, Class cls, String symbol) throws Exception { + /* public static AbstractAsset create(World world, Class cls, String symbol) throws Exception { AbstractAsset a = cls.newInstance(); - + + if (world.assetsBySymbol.get(symbol) != null) { throw new java.lang.Exception("Can't create asset. Symbol '" + symbol + "' is already in use."); } @@ -129,13 +128,13 @@ public abstract class AbstractAsset implements Configurable { a.symbol=symbol; - world.assetsById.put(a.id, a); + world.assetsById.add(a); world.assetsBySymbol.put(a.getSymbol(), a); return a; } - - public static AbstractAsset create(World world, JSONObject cfg){ + */ + /* public static AbstractAsset create(World world, JSONObject cfg){ AbstractAsset a; String class_name; Class cls; @@ -160,9 +159,8 @@ public abstract class AbstractAsset implements Configurable { } return null; } - - @Override - public JSONObject getConfig() { + */ + /* public JSONObject getConfig() { JSONObject cfg = new JSONObject(); cfg.put(AbstractAsset.JSON_ID,id.toString()); cfg.put(AbstractAsset.JSON_CLASS, this.getClass().getName()); @@ -173,15 +171,15 @@ public abstract class AbstractAsset implements Configurable { return cfg; } - @Override + public void putConfig(JSONObject cfg) { symbol = cfg.optString(AbstractAsset.JSON_SYMBOL); decimals = cfg.optInt(AbstractAsset.JSON_DECIMALS, AbstractAsset.DECIMALS_DEFAULT); name = cfg.optString(AbstractAsset.JSON_NAME, ""); description = cfg.optString(AbstractAsset.JSON_DESCRIPTION); } - - public JPanel getEditGui(){ + */ + public JPanel getEditGui() { return null; } } diff --git a/src/opensesim/world/Exchange.java b/src/opensesim/world/Exchange.java index 14ea13d..ad63c68 100644 --- a/src/opensesim/world/Exchange.java +++ b/src/opensesim/world/Exchange.java @@ -51,16 +51,15 @@ public class Exchange implements Configurable{ //private final HashMap asset_pairs; - private final HashMap asset_pairs; + private final HashMap asset_pairs = new HashMap<>(); Exchange(World world, String symbol) { - asset_pairs = new HashMap<>(); + this.world = world; this.symbol=symbol; } - - private void reset() { - asset_pairs.clear(); + + Exchange(World world, JSONObject cfg){ } public String getName() { diff --git a/src/opensesim/world/Order.java b/src/opensesim/world/Order.java index 0ca3b1a..b681700 100644 --- a/src/opensesim/world/Order.java +++ b/src/opensesim/world/Order.java @@ -31,14 +31,12 @@ import opensesim.sesim.AssetPair; import opensesim.util.idgenerator.IDGenerator; import opensesim.util.idgenerator.Id; - /** * * @author 7u83 <7u83@mail.ru> */ public class Order implements Comparable { - - + @Override public int compareTo(Order o) { { @@ -99,7 +97,7 @@ public class Order implements Comparable { Order(World world, Account account, AssetPair pair, Type type, double volume, double limit) { - + this.account = account; this.type = type; this.limit = limit; @@ -108,10 +106,10 @@ public class Order implements Comparable { this.created = 0; this.status = OrderStatus.OPEN; this.cost = 0; - // id = Order.idGenerator.getNext(); - this.world=world; - // id = world. - id = null; + // id = Order.idGenerator.getNext(); + this.world = world; + // id = world. + id = world.orderIdGenerator.getNext(); } public Id getID() { @@ -168,8 +166,8 @@ public class Order implements Comparable { * @return Stock symbol */ public String getStockSymbol() { - // return stock.getSymbol(); - return null; + // return stock.getSymbol(); + return null; } } diff --git a/src/opensesim/world/World.java b/src/opensesim/world/World.java index 56a9f3c..b6f7066 100644 --- a/src/opensesim/world/World.java +++ b/src/opensesim/world/World.java @@ -25,35 +25,35 @@ */ package opensesim.world; +import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; +import java.util.logging.Level; +import java.util.logging.Logger; import opensesim.sesim.AssetPair; -import opensesim.sesim.interfaces.Configurable; import opensesim.util.idgenerator.IDGenerator; -import opensesim.util.idgenerator.Id; import opensesim.util.SeSimException; -import org.json.JSONArray; import org.json.JSONObject; /** * * @author 7u83 <7u83@mail.ru> */ -public class World implements Configurable { +public class World { public static final class JKEYS { - public static final String ASSETS = "assets"; + + public static final String ASSETS = "assets"; public static final String EXCHANGES = "exchanges"; } - HashMap assetsById = new HashMap<>(); + HashSet assetsById = new HashSet<>(); HashMap assetsBySymbol = new HashMap<>(); IDGenerator assetIdGenerator = new IDGenerator(); IDGenerator orderIdGenerator = new IDGenerator(); - HashSet assetPairs = new HashSet<>(); @@ -62,14 +62,37 @@ public class World implements Configurable { /** * Create a World object. * - * @param world + * @param cfg */ - public World(JSONObject world) { + public World(JSONObject cfg) { + // Read assets + JSONObject jassets = cfg.getJSONObject(World.JKEYS.ASSETS); + for (String symbol : jassets.keySet()) { + AbstractAsset a = createAsset(jassets.getJSONObject(symbol)); + assetsById.add(a); + assetsBySymbol.put(symbol, a); + } + } + + private AbstractAsset createAsset(JSONObject cfg) { + AbstractAsset a; + String class_name; + Class cls; + + class_name = cfg.getString("type"); + try { + cls = (Class) Class.forName(class_name); + a = cls.getConstructor(World.class,JSONObject.class).newInstance(this,cfg); + } catch (ClassNotFoundException | NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) { + Logger.getLogger(World.class.getName()).log(Level.SEVERE, null, ex); + return null; + } + return a; } public Collection getAssetCollection() { - return Collections.unmodifiableCollection(assetsById.values()); + return Collections.unmodifiableCollection(assetsById); } public Collection getAssetPairsCollection() { @@ -99,7 +122,7 @@ public class World implements Configurable { static final String JSON_ASSET = "asset"; static final String JSON_EXCHANGES = "exchanges"; - @Override + /* public JSONObject getConfig() { JSONObject cfg = new JSONObject(); @@ -132,12 +155,12 @@ public class World implements Configurable { AbstractAsset.create(this, acfg); } } - - public AbstractAsset createAsset(Class cls, String symbol) throws Exception { + */ + /* public AbstractAsset createAsset(Class cls, String symbol) throws Exception { return AbstractAsset.create(this, cls, symbol); } - - /* + */ + /* static public JSONArray toJson() { JSONArray all = new JSONArray(); diff --git a/test/opensesim/util/idgenerator/IDGeneratorTest.java b/test/opensesim/util/idgenerator/IDGeneratorTest.java index 93a871c..122a3c9 100644 --- a/test/opensesim/util/idgenerator/IDGeneratorTest.java +++ b/test/opensesim/util/idgenerator/IDGeneratorTest.java @@ -37,22 +37,22 @@ import static org.junit.Assert.*; * @author 7u83 <7u83@mail.ru> */ public class IDGeneratorTest { - + public IDGeneratorTest() { } - + @BeforeClass public static void setUpClass() { } - + @AfterClass public static void tearDownClass() { } - + @Before public void setUp() { } - + @After public void tearDown() { } @@ -66,7 +66,7 @@ public class IDGeneratorTest { IDGenerator instance = new IDGenerator(); instance.reset(); // TODO review the generated test code and remove the default call to fail. - // fail("The test case is a prototype."); + // fail("The test case is a prototype."); } /** @@ -76,12 +76,15 @@ public class IDGeneratorTest { public void testGetNext() { System.out.println("getNext"); IDGenerator instance = new IDGenerator(7L); - + Id expResult = new Id(7L); Id result = instance.getNext(); assertEquals(expResult, result); - // TODO review the generated test code and remove the default call to fail. - // fail("The test case is a prototype."); - } + + result = instance.getNext(); + expResult = new Id(8L); + assertEquals(expResult, result); + } + } diff --git a/test/opensesim/world/ExchangeTest.java b/test/opensesim/world/ExchangeTest.java new file mode 100644 index 0000000..1f573ec --- /dev/null +++ b/test/opensesim/world/ExchangeTest.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2018, 7u83 <7u83@mail.ru> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +package opensesim.world; + +import java.util.Collection; +import opensesim.sesim.AssetPair; +import org.json.JSONObject; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import static org.junit.Assert.*; + +/** + * + * @author 7u83 <7u83@mail.ru> + */ +public class ExchangeTest { + + public ExchangeTest() { + } + + @BeforeClass + public static void setUpClass() { + } + + @AfterClass + public static void tearDownClass() { + } + + @Before + public void setUp() { + } + + @After + public void tearDown() { + } + + +}