Changeset 84


Ignore:
Timestamp:
06/22/13 21:51:33 (12 years ago)
Author:
psniegowski
Message:

HIGHLIGHTS:

  • simplification of entities management model
  • cleanup around params (improve hierarchy)
  • migrate from JUnit to TestNG
  • introduce FEST to automatically test GUI
  • improve slider control
  • loosen synchronization between gui tree and backend representation
  • and many other bug fixes

NOTICE:

  • a great many of lines is changed only because of substituting spaces with tabs

CHANGELOG (oldest changes at the bottom):

Some cleaning after fix found.

Fix bug with tree.

More changes with TreeNodes?.

Finally fix issue with tree.

Improve gui tree management.

Decouple update of values from fetch request in gui.

Minor changes.

Minor changes.

Minor change.

Change Path construction wording.

More fixes to SliderControl?.

Fix SliderControl?.

Fix SliderControl?.

Minor improvement.

Several changes.

Make NumberParam? a generic class.

Add robot to the gui test.

Setup common testing logging configuration.

Remove Parameters class.

Remove entityOwner from Parameters.

Move name out from Parameters class.

Move configuration to after the construction.

Simplify observers and endpoints.

Remove superfluous configureEntity overrides.

Add dependency on fest-swing-testng.

Use FEST for final print test.

Use FEST for more concise and readable assertions.

Divide test of F0Parser into multiple methods.

Migrate to TestNG

Minor change.

Change convention from LOGGER to log.

Fix reporting of errors during controls filling.

Bound maximal height of SliderControl?.

Minor improvements.

Improve tooltips for controls.

Also use Delimeted in more places.

Move static control utilities to Gui.

Rename package gui.components to controls.

Some cleaning in controls.

Improve Param classes placing.

Move ValueParam?, PrimitiveParam? and CompositeParam? one package up.

Improve ParamBuilder?.

Move getDef to ValueParam? and PrimitiveParam?.

Move getMax and getDef to ValueParam?.

Move getMin to ValueParam?.

Upgrade to laters apache commons versions.

Use filterInstanceof extensively.

Add instanceof filters.

Make ValueParam? in many places of Param.

Place assertions about ValueParam?.

Add ValueParam?

Rename ValueParam? to PrimitiveParam?

Minor changes.

Several improvements to params types.

Add NumberParam?.

Add TextControl? component.

Add .swp files to .gitignore

Greatly improved slider component.

Some improvements.

Make Param.reassign return also a state.

Add IterableIterator?.

Several changes.

  • Move util classes to better packages.
  • Remove warnings from eclim.

Several improvements.

Fix bug with BooleanParam?.

Some experiments with visualization.

Another fix to panel management.

Improve panel management.

Some refactorization around panels.

Add root class for panel.

Location:
java/main
Files:
62 added
22 deleted
110 edited

Legend:

Unmodified
Added
Removed
  • java/main

    • Property svn:ignore set to
      target
  • java/main/pom.xml

    r78 r84  
    11<?xml version="1.0" encoding="UTF-8"?>
    22<project xmlns="http://maven.apache.org/POM/4.0.0"
    3          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    5     <modelVersion>4.0.0</modelVersion>
     3                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     4                xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     5        <modelVersion>4.0.0</modelVersion>
    66
    7     <groupId>framsticks</groupId>
    8     <artifactId>framsticks</artifactId>
    9     <version>1.0</version>
     7        <groupId>framsticks</groupId>
     8        <artifactId>framsticks</artifactId>
     9        <version>1.0</version>
    1010
    1111        <repositories>
     
    1818                <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    1919        </properties>
    20         <build>
    21                 <plugins>
    22                         <plugin>
    23                                 <groupId>org.apache.maven.plugins</groupId>
    24                                 <artifactId>maven-compiler-plugin</artifactId>
    25                                 <version>3.0</version>
    26                                 <configuration>
    27                                         <source>1.6</source>
    28                                         <target>1.6</target>
    29                                 </configuration>
    30                         </plugin>
    31                 </plugins>
    32         </build>
    33 
    3420        <dependencies>
    3521                <dependency>
     
    4228                        <groupId>commons-configuration</groupId>
    4329                        <artifactId>commons-configuration</artifactId>
    44                         <version>1.7</version>
     30                        <version>1.9</version>
     31                        <scope>compile</scope>
     32                </dependency>
     33                <dependency>
     34                        <groupId>commons-collections</groupId>
     35                        <artifactId>commons-collections</artifactId>
     36                        <version>3.2.1</version>
    4537                        <scope>compile</scope>
    4638                </dependency>
     
    6153                </dependency>
    6254
    63         <dependency>
    64             <groupId>junit</groupId>
    65             <artifactId>junit</artifactId>
    66             <version>4.8.1</version>
    67             <scope>test</scope>
    68         </dependency>
    69                 <!--dependency>
     55                <dependency>
     56                        <groupId>org.testng</groupId>
     57                        <artifactId>testng</artifactId>
     58                        <version>6.1.1</version>
     59                        <scope>test</scope>
    7060                </dependency>
    7161                <dependency>
    72                 </dependency-->
     62                        <groupId>org.easytesting</groupId>
     63                        <artifactId>fest-assert</artifactId>
     64                        <version>1.4</version>
     65                </dependency>
     66                <dependency>
     67                        <groupId>org.easytesting</groupId>
     68                        <artifactId>fest-swing-testng</artifactId>
     69                        <version>1.2.1</version>
     70                </dependency>
     71
     72                <!-- <dependency> -->
     73                <!--    <groupId>junit</groupId> -->
     74                <!--    <artifactId>junit</artifactId> -->
     75                <!--    <version>4.8.1</version> -->
     76                <!--    <scope>test</scope> -->
     77                <!-- </dependency> -->
     78
     79                <!--dependency>
     80                  </dependency>
     81                  <dependency>
     82                  </dependency-->
    7383        </dependencies>
     84        <build>
     85                <plugins>
     86                        <plugin>
     87                                <groupId>org.apache.maven.plugins</groupId>
     88                                <artifactId>maven-compiler-plugin</artifactId>
     89                                <version>3.0</version>
     90                                <configuration>
     91                                        <source>1.6</source>
     92                                        <target>1.6</target>
     93                                </configuration>
     94                        </plugin>
     95
     96                        <plugin>
     97                                <groupId>org.codehaus.mojo</groupId>
     98                                <artifactId>exec-maven-plugin</artifactId>
     99                                <version>1.2.1</version>
     100                                <executions>
     101                                        <execution>
     102                                                <goals>
     103                                                        <goal>exec</goal>
     104                                                </goals>
     105                                        </execution>
     106                                </executions>
     107                                <configuration>
     108                                        <executable>java</executable>
     109                                        <!-- optional -->
     110                                        <workingDirectory>/home/psniegowski/mgr/framsticks</workingDirectory>
     111                                        <arguments>
     112                                                <!-- <argument>-ea</argument> -->
     113                                                <argument>-Xdebug</argument>
     114                                                <argument>-Xrunjdwp:transport=dt_socket,address=4711,server=y,suspend=n</argument>
     115                                                <argument>-classpath</argument>
     116                                                <classpath />
     117                                                <argument>com.framsticks.core.Program</argument>
     118                                        </arguments>
     119                                </configuration>
     120                        </plugin>
     121
     122                </plugins>
     123        </build>
     124
    74125</project>
  • java/main/src/main/java/com/framsticks/communication/ClientConnection.java

    r77 r84  
    88import com.framsticks.params.ListSource;
    99import com.framsticks.util.*;
     10import com.framsticks.util.dispatching.AtOnceDispatcher;
     11import com.framsticks.util.dispatching.Dispatcher;
     12import com.framsticks.util.dispatching.Dispatching;
     13import com.framsticks.util.lang.Pair;
     14import com.framsticks.util.lang.Strings;
    1015import org.apache.log4j.Logger;
    1116
    12 import java.io.BufferedReader;
    1317import java.io.IOException;
    14 import java.io.InputStreamReader;
    15 import java.io.PrintWriter;
    1618import java.net.Socket;
    1719import java.net.SocketException;
     
    2527public class ClientConnection extends Connection {
    2628
    27     private final static Logger LOGGER = Logger.getLogger(ClientConnection.class);
    28 
    29     protected final Map<String, Subscription> subscriptions = new HashMap<String, Subscription>();
    30 
    31     public String getAddress() {
    32         return address;
    33     }
    34 
    35     public void connect(StateFunctor connectedFunctor) {
    36         try {
    37             LOGGER.info("connecting to " + address);
    38 
    39             socket = new Socket(hostName, port);
    40 
    41             socket.setSoTimeout(500);
    42 
    43             LOGGER.info("connected to " + hostName + ":" + port);
    44             connected = true;
    45 
    46             runThreads();
    47 
    48             connectedFunctor.call(null);
    49         } catch (SocketException e) {
    50             LOGGER.error("failed to connect: " + e);
    51             connectedFunctor.call(e);
    52         } catch (IOException e) {
    53             LOGGER.error("buffer creation failure");
    54             connectedFunctor.call(e);
    55             close();
    56         }
    57     }
    58 
    59     private static abstract class InboundMessage {
    60         protected String currentFilePath;
    61         protected List<String> currentFileContent;
    62         protected final List<File> files = new ArrayList<File>();
    63 
    64         public abstract void eof();
    65 
    66         protected void initCurrentFile(String path) {
    67             currentFileContent = new LinkedList<String>();
    68             currentFilePath = path;
    69         }
    70         protected void finishCurrentFile() {
    71             if (currentFileContent == null) {
    72                 return;
    73             }
    74             files.add(new File(currentFilePath, new ListSource(currentFileContent)));
    75             currentFilePath = null;
    76             currentFileContent= null;
    77         }
    78 
    79         public abstract void startFile(String path);
    80 
    81         public void addLine(String line) {
    82             assert line != null;
    83             assert currentFileContent != null;
    84             currentFileContent.add(line.substring(0, line.length() - 1));
    85         }
    86 
    87         public List<File> getFiles() {
    88             return files;
    89         }
    90     }
    91 
    92     private static class EventFire extends InboundMessage {
    93         public final Subscription subscription;
    94 
    95         private EventFire(Subscription subscription) {
    96             this.subscription = subscription;
    97         }
    98 
    99         public void startFile(String path) {
    100             assert path == null;
    101             initCurrentFile(null);
    102         }
    103 
    104         @Override
    105         public void eof() {
    106             finishCurrentFile();
    107             Dispatching.invokeLaterOrNow(subscription.getDispatcher(), new Runnable() {
    108                 @Override
    109                 public void run() {
    110                     subscription.getEventCallback().call(getFiles());
    111                 }
    112             });
    113         }
    114     }
    115 
    116     private static class SentQuery extends InboundMessage {
    117         Request request;
    118         ResponseCallback callback;
    119         Dispatcher dispatcher;
    120 
    121         public void startFile(String path) {
    122             finishCurrentFile();
    123             if (path == null) {
    124                 assert request instanceof ApplicationRequest;
    125                 path = ((ApplicationRequest)request).getPath();
    126             }
    127             initCurrentFile(path);
    128         }
    129 
    130         public void eof() {
    131             finishCurrentFile();
    132             //no-operation
    133         }
    134 
    135         @Override
    136         public String toString() {
    137             return request.toString();
    138         }
    139     }
    140     private Map<Integer, SentQuery> queryMap = new HashMap<Integer, SentQuery>();
    141 
    142 
    143     protected final String address;
    144     protected final String hostName;
    145     protected final int port;
    146 
    147     private static Pattern addressPattern = Pattern.compile("^([^:]*)(:([0-9]+))?$");
    148 
    149     public ClientConnection(String address) {
    150         assert address != null;
    151         this.address = address;
    152         Matcher matcher = addressPattern.matcher(address);
    153         if (!matcher.matches()) {
    154             LOGGER.fatal("invalid address: " + address);
    155             hostName = null;
    156             port = 0;
    157             return;
    158         }
    159         hostName = matcher.group(1);
    160         port = matcher.group(3) != null ? Integer.parseInt(matcher.group(3)) : 9009;
    161     }
    162 
    163     private SentQuery currentlySentQuery;
    164 
    165     public void send(Request request, ResponseCallback callback) {
    166         send(request, AtOnceDispatcher.instance, callback);
    167     }
    168 
    169     public void send(Request request, Dispatcher dispatcher, ResponseCallback callback) {
    170 
    171         if (!isConnected()) {
    172             LOGGER.fatal("not connected");
    173             return;
    174         }
    175         final SentQuery sentQuery = new SentQuery();
    176         sentQuery.request = request;
    177         sentQuery.callback = callback;
    178         sentQuery.dispatcher = dispatcher;
    179 
    180         senderThread.invokeLater(new Runnable(){
    181             @Override
    182             public void run() {
    183                 synchronized (ClientConnection.this) {
    184 
    185                     while (!(requestIdEnabled || currentlySentQuery == null)) {
    186                         try {
    187                             ClientConnection.this.wait();
    188                         } catch (InterruptedException ignored) {
    189                             break;
    190                         }
    191                     }
    192                 }
    193                 Integer id = stashQuery(sentQuery);
    194                 String command = sentQuery.request.getCommand();
    195                 StringBuilder message = new StringBuilder();
    196                 message.append(command);
    197                 if (id != null) {
    198                     message.append(" ").append(id);
    199                 }
    200                 sentQuery.request.construct(message);
    201                 String out = message.toString();
    202 
    203                 output.println(out);
    204                 LOGGER.debug("sending query: " + out);
    205 
    206             }
    207         });
    208         /*
    209         synchronized (this) {
    210             LOGGER.debug("queueing query: " + query);
    211             queryQueue.offer(sentQuery);
    212             notifyAll();
    213         }
    214         */
    215     }
    216 
    217 
    218     @Override
    219     public String toString() {
    220         return address;
    221     }
    222 
    223     public void subscribe(final String path, final SubscriptionCallback callback) {
    224         send(new RegistrationRequest().setPath(path), new ResponseCallback() {
    225             @Override
    226             public void process(Response response) {
    227                 if (!response.getOk()) {
    228                     LOGGER.error("failed to register on event: " + path);
    229                     callback.subscribed(null);
    230                     return;
    231                 }
    232                 assert response.getFiles().isEmpty();
    233                 Subscription subscription = new Subscription(ClientConnection.this, path, response.getComment());
    234                 LOGGER.debug("registered on event: " + subscription);
    235                 synchronized (subscriptions) {
    236                     subscriptions.put(subscription.getRegisteredPath(), subscription);
    237                 }
    238                 subscription.setEventCallback(callback.subscribed(subscription));
    239                 if (subscription.getEventCallback() == null) {
    240                     LOGGER.info("subscription for " + path + " aborted");
    241                     subscription.unsubscribe(new LoggingStateCallback(LOGGER, "abort subscription"));
    242                 }
    243             }
    244         });
    245     }
    246 
    247     public void negotiateProtocolVersion(StateFunctor stateFunctor) {
    248         protocolVersion = -1;
    249         sendQueryVersion(1, stateFunctor);
    250     }
    251 
    252     public void sendQueryVersion(final int version, final StateFunctor stateFunctor) {
    253         send(new VersionRequest().version(version), new StateCallback() {
    254             @Override
    255             public void call(Exception e) {
    256                 if (e != null) {
    257                     LOGGER.fatal("failed to upgrade protocol to version: " + version);
    258                     return;
    259                 }
    260                 protocolVersion = version;
    261                 if (version < 4) {
    262                     /** it is an implicit loop here*/
    263                     sendQueryVersion(version + 1, stateFunctor);
    264                     return;
    265                 }
    266                 send(new UseRequest().feature("request_id"), new StateCallback() {
    267                     @Override
    268                     public void call(Exception e) {
    269                         requestIdEnabled = e == null;
    270                         /*
    271                         synchronized (ClientConnection.this) {
    272                             ClientConnection.this.notifyAll();
    273                         }
    274                         */
    275                         if (!requestIdEnabled) {
    276                             LOGGER.fatal("protocol negotiation failed");
    277                             stateFunctor.call(new Exception("protocol negotiation failed", e));
    278                             return;
    279                         }
    280                         stateFunctor.call(null);
    281                     }
    282                 });
    283 
    284             }
    285         });
    286     }
    287 
    288 
    289     private synchronized SentQuery fetchQuery(Integer id, boolean remove) {
    290         if (id == null) {
    291             if (requestIdEnabled) {
    292                 return null;
    293             }
    294             SentQuery result = currentlySentQuery;
    295             if (remove) {
    296                 currentlySentQuery = null;
    297                 notifyAll();
    298             }
    299             return result;
    300         }
    301         if (queryMap.containsKey(id)) {
    302             SentQuery result = queryMap.get(id);
    303             if (remove) {
    304                 queryMap.remove(id);
    305             }
    306             return result;
    307         }
    308         return null;
    309     }
    310 
    311     private int nextQueryId = 0;
    312 
    313     private Integer stashQuery(SentQuery sentQuery) {
    314         if (!requestIdEnabled) {
    315             currentlySentQuery = sentQuery;
    316             return null;
    317         }
    318         queryMap.put(nextQueryId, sentQuery);
    319         return nextQueryId++;
    320     }
    321 
    322     protected void processMessage(InboundMessage inboundMessage) throws Exception {
    323         if (inboundMessage == null) {
    324             LOGGER.error("failed to use any inbound message");
    325             return;
    326         }
    327 
    328         String line;
    329         while (!(line = getLine()).startsWith("eof")) {
    330             inboundMessage.addLine(line);
    331         }
    332         inboundMessage.eof();
    333     }
    334 
    335     protected void processEvent(String rest) throws Exception {
    336         Matcher matcher = eventPattern.matcher(rest);
    337         if (!matcher.matches()) {
    338             LOGGER.error("invalid event line: " + rest);
    339             return;
    340         }
    341         Subscription subscription = subscriptions.get(matcher.group(1));
    342         if (subscription == null) {
    343             LOGGER.error("non subscribed event: " + matcher.group(1));
    344             return;
    345         }
    346         EventFire event = new EventFire(subscription);
    347         event.startFile(null);
    348         processMessage(event);
    349     }
    350 
    351 
    352     protected void processMessageStartingWith(String line) throws Exception {
    353         Pair<String, String> command = Strings.splitIntoPair(line, ' ', "\n");
    354         if (command.first.equals("event")) {
    355             processEvent(command.second);
    356             return;
    357         }
    358         Pair<Integer, String> rest = parseRest(command.second);
    359 
    360         if (command.first.equals("file")) {
    361             SentQuery sentQuery = fetchQuery(rest.first, false);
    362             sentQuery.startFile(rest.second);
    363             processMessage(sentQuery);
    364             return;
    365         }
    366 
    367         SentQuery sentQuery = fetchQuery(rest.first, true);
    368         if (sentQuery == null) {
    369             return;
    370         }
    371         LOGGER.debug("parsing response for request " + sentQuery);
    372 
    373         final Response response = new Response(command.first.equals("ok"), rest.second, sentQuery.getFiles());
    374         final ResponseCallback callback = sentQuery.callback;
    375 
    376         Dispatching.invokeLaterOrNow(sentQuery.dispatcher, new Runnable() {
    377             @Override
    378             public void run() {
    379                 callback.process(response);
    380             }
    381         });
    382     }
    383 
    384     @Override
    385     protected void receiverThreadRoutine() throws Exception {
    386         while (connected) {
    387             processMessageStartingWith(getLine());
    388         }
    389     }
     29        private final static Logger log = Logger.getLogger(ClientConnection.class);
     30
     31        protected final Map<String, Subscription> subscriptions = new HashMap<String, Subscription>();
     32
     33        public String getAddress() {
     34                return address;
     35        }
     36
     37        public void connect(StateFunctor connectedFunctor) {
     38                try {
     39                        log.info("connecting to " + address);
     40
     41                        socket = new Socket(hostName, port);
     42
     43                        socket.setSoTimeout(500);
     44
     45                        log.info("connected to " + hostName + ":" + port);
     46                        connected = true;
     47
     48                        runThreads();
     49
     50                        connectedFunctor.call(null);
     51                } catch (SocketException e) {
     52                        log.error("failed to connect: " + e);
     53                        connectedFunctor.call(e);
     54                } catch (IOException e) {
     55                        log.error("buffer creation failure");
     56                        connectedFunctor.call(e);
     57                        close();
     58                }
     59        }
     60
     61        private static abstract class InboundMessage {
     62                protected String currentFilePath;
     63                protected List<String> currentFileContent;
     64                protected final List<File> files = new ArrayList<File>();
     65
     66                public abstract void eof();
     67
     68                protected void initCurrentFile(String path) {
     69                        currentFileContent = new LinkedList<String>();
     70                        currentFilePath = path;
     71                }
     72                protected void finishCurrentFile() {
     73                        if (currentFileContent == null) {
     74                                return;
     75                        }
     76                        files.add(new File(currentFilePath, new ListSource(currentFileContent)));
     77                        currentFilePath = null;
     78                        currentFileContent= null;
     79                }
     80
     81                public abstract void startFile(String path);
     82
     83                public void addLine(String line) {
     84                        assert line != null;
     85                        assert currentFileContent != null;
     86                        currentFileContent.add(line.substring(0, line.length() - 1));
     87                }
     88
     89                public List<File> getFiles() {
     90                        return files;
     91                }
     92        }
     93
     94        private static class EventFire extends InboundMessage {
     95                public final Subscription subscription;
     96
     97                private EventFire(Subscription subscription) {
     98                        this.subscription = subscription;
     99                }
     100
     101                public void startFile(String path) {
     102                        assert path == null;
     103                        initCurrentFile(null);
     104                }
     105
     106                @Override
     107                public void eof() {
     108                        finishCurrentFile();
     109                        Dispatching.invokeLaterOrNow(subscription.getDispatcher(), new Runnable() {
     110                                @Override
     111                                public void run() {
     112                                        subscription.getEventCallback().call(getFiles());
     113                                }
     114                        });
     115                }
     116        }
     117
     118        private static class SentQuery extends InboundMessage {
     119                Request request;
     120                ResponseCallback callback;
     121                Dispatcher dispatcher;
     122
     123                public void startFile(String path) {
     124                        finishCurrentFile();
     125                        if (path == null) {
     126                                assert request instanceof ApplicationRequest;
     127                                path = ((ApplicationRequest)request).getPath();
     128                        }
     129                        initCurrentFile(path);
     130                }
     131
     132                public void eof() {
     133                        finishCurrentFile();
     134                        //no-operation
     135                }
     136
     137                @Override
     138                public String toString() {
     139                        return request.toString();
     140                }
     141        }
     142        private Map<Integer, SentQuery> queryMap = new HashMap<Integer, SentQuery>();
     143
     144
     145        protected final String address;
     146        protected final String hostName;
     147        protected final int port;
     148
     149        private static Pattern addressPattern = Pattern.compile("^([^:]*)(:([0-9]+))?$");
     150
     151        public ClientConnection(String address) {
     152                assert address != null;
     153                this.address = address;
     154                Matcher matcher = addressPattern.matcher(address);
     155                if (!matcher.matches()) {
     156                        log.fatal("invalid address: " + address);
     157                        hostName = null;
     158                        port = 0;
     159                        return;
     160                }
     161                hostName = matcher.group(1);
     162                port = matcher.group(3) != null ? Integer.parseInt(matcher.group(3)) : 9009;
     163        }
     164
     165        private SentQuery currentlySentQuery;
     166
     167        public void send(Request request, ResponseCallback callback) {
     168                send(request, AtOnceDispatcher.instance, callback);
     169        }
     170
     171        public void send(Request request, Dispatcher dispatcher, ResponseCallback callback) {
     172
     173                if (!isConnected()) {
     174                        log.fatal("not connected");
     175                        return;
     176                }
     177                final SentQuery sentQuery = new SentQuery();
     178                sentQuery.request = request;
     179                sentQuery.callback = callback;
     180                sentQuery.dispatcher = dispatcher;
     181
     182                senderThread.invokeLater(new Runnable(){
     183                        @Override
     184                        public void run() {
     185                                synchronized (ClientConnection.this) {
     186
     187                                        while (!(requestIdEnabled || currentlySentQuery == null)) {
     188                                                try {
     189                                                        ClientConnection.this.wait();
     190                                                } catch (InterruptedException ignored) {
     191                                                        break;
     192                                                }
     193                                        }
     194                                }
     195                                Integer id = stashQuery(sentQuery);
     196                                String command = sentQuery.request.getCommand();
     197                                StringBuilder message = new StringBuilder();
     198                                message.append(command);
     199                                if (id != null) {
     200                                        message.append(" ").append(id);
     201                                }
     202                                sentQuery.request.construct(message);
     203                                String out = message.toString();
     204
     205                                output.println(out);
     206                                log.debug("sending query: " + out);
     207
     208                        }
     209                });
     210                /*
     211                synchronized (this) {
     212                        log.debug("queueing query: " + query);
     213                        queryQueue.offer(sentQuery);
     214                        notifyAll();
     215                }
     216                */
     217        }
     218
     219
     220        @Override
     221        public String toString() {
     222                return address;
     223        }
     224
     225        public void subscribe(final String path, final SubscriptionCallback callback) {
     226                send(new RegistrationRequest().setPath(path), new ResponseCallback() {
     227                        @Override
     228                        public void process(Response response) {
     229                                if (!response.getOk()) {
     230                                        log.error("failed to register on event: " + path);
     231                                        callback.subscribed(null);
     232                                        return;
     233                                }
     234                                assert response.getFiles().isEmpty();
     235                                Subscription subscription = new Subscription(ClientConnection.this, path, response.getComment());
     236                                log.debug("registered on event: " + subscription);
     237                                synchronized (subscriptions) {
     238                                        subscriptions.put(subscription.getRegisteredPath(), subscription);
     239                                }
     240                                subscription.setEventCallback(callback.subscribed(subscription));
     241                                if (subscription.getEventCallback() == null) {
     242                                        log.info("subscription for " + path + " aborted");
     243                                        subscription.unsubscribe(new LoggingStateCallback(log, "abort subscription"));
     244                                }
     245                        }
     246                });
     247        }
     248
     249        public void negotiateProtocolVersion(StateFunctor stateFunctor) {
     250                protocolVersion = -1;
     251                sendQueryVersion(1, stateFunctor);
     252        }
     253
     254        public void sendQueryVersion(final int version, final StateFunctor stateFunctor) {
     255                send(new VersionRequest().version(version), new StateCallback() {
     256                        @Override
     257                        public void call(Exception e) {
     258                                if (e != null) {
     259                                        log.fatal("failed to upgrade protocol to version: " + version);
     260                                        return;
     261                                }
     262                                protocolVersion = version;
     263                                if (version < 4) {
     264                                        /** it is an implicit loop here*/
     265                                        sendQueryVersion(version + 1, stateFunctor);
     266                                        return;
     267                                }
     268                                send(new UseRequest().feature("request_id"), new StateCallback() {
     269                                        @Override
     270                                        public void call(Exception e) {
     271                                                requestIdEnabled = e == null;
     272                                                /*
     273                                                synchronized (ClientConnection.this) {
     274                                                        ClientConnection.this.notifyAll();
     275                                                }
     276                                                */
     277                                                if (!requestIdEnabled) {
     278                                                        log.fatal("protocol negotiation failed");
     279                                                        stateFunctor.call(new Exception("protocol negotiation failed", e));
     280                                                        return;
     281                                                }
     282                                                stateFunctor.call(null);
     283                                        }
     284                                });
     285
     286                        }
     287                });
     288        }
     289
     290
     291        private synchronized SentQuery fetchQuery(Integer id, boolean remove) {
     292                if (id == null) {
     293                        if (requestIdEnabled) {
     294                                return null;
     295                        }
     296                        SentQuery result = currentlySentQuery;
     297                        if (remove) {
     298                                currentlySentQuery = null;
     299                                notifyAll();
     300                        }
     301                        return result;
     302                }
     303                if (queryMap.containsKey(id)) {
     304                        SentQuery result = queryMap.get(id);
     305                        if (remove) {
     306                                queryMap.remove(id);
     307                        }
     308                        return result;
     309                }
     310                return null;
     311        }
     312
     313        private int nextQueryId = 0;
     314
     315        private Integer stashQuery(SentQuery sentQuery) {
     316                if (!requestIdEnabled) {
     317                        currentlySentQuery = sentQuery;
     318                        return null;
     319                }
     320                queryMap.put(nextQueryId, sentQuery);
     321                return nextQueryId++;
     322        }
     323
     324        protected void processMessage(InboundMessage inboundMessage) throws Exception {
     325                if (inboundMessage == null) {
     326                        log.error("failed to use any inbound message");
     327                        return;
     328                }
     329
     330                String line;
     331                while (!(line = getLine()).startsWith("eof")) {
     332                        // log.debug("line: " + line);
     333                        inboundMessage.addLine(line);
     334                }
     335                inboundMessage.eof();
     336        }
     337
     338        protected void processEvent(String rest) throws Exception {
     339                Matcher matcher = eventPattern.matcher(rest);
     340                if (!matcher.matches()) {
     341                        log.error("invalid event line: " + rest);
     342                        return;
     343                }
     344                Subscription subscription = subscriptions.get(matcher.group(1));
     345                if (subscription == null) {
     346                        log.error("non subscribed event: " + matcher.group(1));
     347                        return;
     348                }
     349                EventFire event = new EventFire(subscription);
     350                event.startFile(null);
     351                processMessage(event);
     352        }
     353
     354
     355        protected void processMessageStartingWith(String line) throws Exception {
     356                Pair<String, String> command = Strings.splitIntoPair(line, ' ', "\n");
     357                if (command.first.equals("event")) {
     358                        processEvent(command.second);
     359                        return;
     360                }
     361                Pair<Integer, String> rest = parseRest(command.second);
     362
     363                if (command.first.equals("file")) {
     364                        SentQuery sentQuery = fetchQuery(rest.first, false);
     365                        sentQuery.startFile(rest.second);
     366                        processMessage(sentQuery);
     367                        return;
     368                }
     369
     370                SentQuery sentQuery = fetchQuery(rest.first, true);
     371                if (sentQuery == null) {
     372                        return;
     373                }
     374                log.debug("parsing response for request " + sentQuery);
     375
     376                final Response response = new Response(command.first.equals("ok"), rest.second, sentQuery.getFiles());
     377                final ResponseCallback callback = sentQuery.callback;
     378
     379                Dispatching.invokeLaterOrNow(sentQuery.dispatcher, new Runnable() {
     380                        @Override
     381                        public void run() {
     382                                callback.process(response);
     383                        }
     384                });
     385        }
     386
     387        @Override
     388        protected void receiverThreadRoutine() throws Exception {
     389                while (connected) {
     390                        processMessageStartingWith(getLine());
     391                }
     392        }
    390393
    391394}
  • java/main/src/main/java/com/framsticks/communication/Connection.java

    r77 r84  
    11package com.framsticks.communication;
    22
    3 import com.framsticks.util.Pair;
     3import com.framsticks.util.lang.Pair;
    44import org.apache.log4j.Logger;
    55import java.io.BufferedReader;
     
    1515public abstract class Connection {
    1616
    17         protected final static Logger LOGGER = Logger.getLogger(Connection.class);
     17        protected final static Logger log = Logger.getLogger(Connection.class);
    1818
    1919        protected PrintWriter output = null;
     
    2828        protected int protocolVersion = -1;
    2929
    30         protected final com.framsticks.util.Thread senderThread = new com.framsticks.util.Thread();
     30        protected final com.framsticks.util.dispatching.Thread senderThread = new com.framsticks.util.dispatching.Thread();
    3131        protected Thread receiverThread;
    3232
     
    4040                        connected = false;
    4141
    42             senderThread.interrupt();
    43             senderThread.join();
     42                        senderThread.interrupt();
     43                        senderThread.join();
    4444                        if (receiverThread != null) {
    4545                                receiverThread.interrupt();
     
    6464                        }
    6565
    66                         LOGGER.info("connection closed");
     66                        log.info("connection closed");
    6767                } catch (Exception e) {
    68                         LOGGER.error(e);
     68                        log.error(e);
    6969                }
    7070
     
    7777
    7878
    79     protected final Pair<Integer, String> parseRest(String rest) {
    80         Matcher matcher = (requestIdEnabled ? requestIdEnabledPattern : requestIDisabledPattern).matcher(rest);
    81         if (!matcher.matches()) {
    82             LOGGER.fatal("unmatched first line of input: " + rest);
    83             return null;
    84         }
    85         return new Pair<Integer, String>(requestIdEnabled ? Integer.parseInt(matcher.group(1)) : null, matcher.group(requestIdEnabled ? 2 : 1));
    86     }
     79        protected final Pair<Integer, String> parseRest(String rest) {
     80                Matcher matcher = (requestIdEnabled ? requestIdEnabledPattern : requestIDisabledPattern).matcher(rest);
     81                if (!matcher.matches()) {
     82                        log.fatal("unmatched first line of input: " + rest);
     83                        return null;
     84                }
     85                return new Pair<Integer, String>(requestIdEnabled ? Integer.parseInt(matcher.group(1)) : null, matcher.group(requestIdEnabled ? 2 : 1));
     86        }
    8787
    88     static final int BUFFER_LENGTH = 1024;
     88        static final int BUFFER_LENGTH = 1024;
    8989
    90     int readChars = 0;
    91     int iterator = 0;
    92     int bufferStart = 0;
    93     char[] readBuffer = new char[BUFFER_LENGTH];
     90        int readChars = 0;
     91        int iterator = 0;
     92        int bufferStart = 0;
     93        char[] readBuffer = new char[BUFFER_LENGTH];
    9494
    95     protected String getLine() throws Exception {
    96         StringBuilder lineBuffer = new StringBuilder();
    97         while (!Thread.interrupted()) {
    98             while (iterator < readChars) {
    99                 if (readBuffer[iterator] != '\n') {
    100                     ++iterator;
    101                     continue;
    102                 }
    103                 lineBuffer.append(readBuffer, bufferStart, iterator - bufferStart + 1);
    104                 ++iterator;
    105                 bufferStart = iterator;
    106                 return lineBuffer.toString();
    107             }
    108             lineBuffer.append(readBuffer, bufferStart, readChars - bufferStart);
     95        protected String getLine() throws Exception {
     96                StringBuilder lineBuffer = new StringBuilder();
     97                while (!Thread.interrupted()) {
     98                        while (iterator < readChars) {
     99                                if (readBuffer[iterator] != '\n') {
     100                                        ++iterator;
     101                                        continue;
     102                                }
     103                                lineBuffer.append(readBuffer, bufferStart, iterator - bufferStart + 1);
     104                                ++iterator;
     105                                bufferStart = iterator;
     106                                return lineBuffer.toString();
     107                        }
     108                        lineBuffer.append(readBuffer, bufferStart, readChars - bufferStart);
    109109
    110             readChars = 0;
    111             while (readChars == 0) {
    112                 try {
    113                     readChars = input.read(readBuffer);
    114                 } catch (SocketTimeoutException ignored) {
    115                     //timeout - continue
    116                 }
    117             }
    118             iterator = 0;
    119             bufferStart = 0;
    120         }
    121         throw new InterruptedException();
    122     }
     110                        readChars = 0;
     111                        while (readChars == 0) {
     112                                try {
     113                                        readChars = input.read(readBuffer);
     114                                } catch (SocketTimeoutException ignored) {
     115                                        //timeout - continue
     116                                }
     117                        }
     118                        iterator = 0;
     119                        bufferStart = 0;
     120                }
     121                throw new InterruptedException();
     122        }
    123123
    124     protected abstract void receiverThreadRoutine() throws Exception;
     124        protected abstract void receiverThreadRoutine() throws Exception;
    125125
    126     protected void runThreads() {
    127         try {
    128             output = new PrintWriter(socket.getOutputStream(), true);
    129             input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    130         } catch (IOException e) {
    131             LOGGER.error("buffer creation failure");
    132             close();
    133             return;
    134         }
     126        protected void runThreads() {
     127                try {
     128                        output = new PrintWriter(socket.getOutputStream(), true);
     129                        input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
     130                } catch (IOException e) {
     131                        log.error("buffer creation failure");
     132                        close();
     133                        return;
     134                }
    135135
    136         senderThread.setName(this + "-sender");
    137         receiverThread = new Thread(new Runnable() {
    138             @Override
    139             public void run() {
    140                 try {
    141                     receiverThreadRoutine();
    142                 } catch (InterruptedException ignored) {
    143                     LOGGER.debug("receiver thread interrupted");
    144                 } catch (Exception e) {
    145                     LOGGER.error("error: " + e);
    146                     close();
    147                 }
    148             }
    149         });
    150         receiverThread.setName(this + "-receiver");
     136                senderThread.setName(this + "-sender");
     137                receiverThread = new Thread(new Runnable() {
     138                        @Override
     139                        public void run() {
     140                                try {
     141                                        receiverThreadRoutine();
     142                                } catch (InterruptedException ignored) {
     143                                        log.debug("receiver thread interrupted");
     144                                } catch (Exception e) {
     145                                        log.error("error: " + e);
     146                                        close();
     147                                }
     148                        }
     149                });
     150                receiverThread.setName(this + "-receiver");
    151151
    152         senderThread.start();
    153         receiverThread.start();
    154     }
     152                senderThread.start();
     153                receiverThread.start();
     154        }
    155155
    156156
  • java/main/src/main/java/com/framsticks/communication/EventCallback.java

    r77 r84  
    11package com.framsticks.communication;
    2 
    3 import com.framsticks.params.SourceInterface;
    42
    53import java.util.List;
  • java/main/src/main/java/com/framsticks/communication/Request.java

    r77 r84  
    22
    33import com.framsticks.communication.queries.*;
    4 
    5 import java.util.Collection;
    6 import java.util.regex.Matcher;
    7 import java.util.regex.Pattern;
    84
    95/**
     
    128public abstract class Request {
    139
    14     public static void quoteValue(StringBuilder builder, String value) {
     10        public static void quoteValue(StringBuilder builder, String value) {
    1511                String quote = ((value.indexOf(' ') > 0) || (value.length() == 0) ? "\"" : "");
    1612                builder.append(quote).append(value).append(quote);
     
    1915        public abstract String getCommand();
    2016
    21     protected abstract StringBuilder construct(StringBuilder buffer);
     17        protected abstract StringBuilder construct(StringBuilder buffer);
    2218        //private static Pattern queryPattern = Pattern.compile("^(\\S+)\\s+(\\S+)(?:\\s+(\\S+))?$");
    2319
     
    3531                        return new CallRequest();
    3632                }
    37         if (type.equals("reg")) {
    38             return new RegistrationRequest();
    39         }
    40         if (type.equals("use")) {
    41             return new UseRequest();
    42         }
    43         if (type.equals("version")) {
    44             return new VersionRequest();
    45         }
    46         return null;
     33                if (type.equals("reg")) {
     34                        return new RegistrationRequest();
     35                }
     36                if (type.equals("use")) {
     37                        return new UseRequest();
     38                }
     39                if (type.equals("version")) {
     40                        return new VersionRequest();
     41                }
     42                return null;
    4743        }
    4844
    49     public abstract void parseRest(String rest);
     45        public abstract void parseRest(String rest);
    5046
    51     @Override
    52     public String toString() {
    53         return construct(new StringBuilder().append(getCommand())).toString();
    54     }
     47        @Override
     48        public String toString() {
     49                return construct(new StringBuilder().append(getCommand())).toString();
     50        }
    5551}
  • java/main/src/main/java/com/framsticks/communication/ResponseCallback.java

    r77 r84  
    11package com.framsticks.communication;
    2 
    3 import com.framsticks.params.SourceInterface;
    4 
    5 import java.util.List;
    62
    73/**
  • java/main/src/main/java/com/framsticks/communication/ServerConnection.java

    r77 r84  
    33import com.framsticks.communication.queries.*;
    44import com.framsticks.params.SourceInterface;
    5 import com.framsticks.util.Pair;
    6 import com.framsticks.util.Strings;
     5import com.framsticks.util.lang.Pair;
     6import com.framsticks.util.lang.Strings;
    77import org.apache.log4j.Logger;
    88
    9 import java.io.BufferedReader;
    10 import java.io.IOException;
    11 import java.io.InputStreamReader;
    12 import java.io.PrintWriter;
    139import java.net.Socket;
    1410
     
    1814public class ServerConnection extends Connection {
    1915
    20     private final static Logger LOGGER = Logger.getLogger(ServerConnection.class);
     16        private final static Logger log = Logger.getLogger(ServerConnection.class);
    2117
    22     RequestHandler requestHandler;
     18        RequestHandler requestHandler;
    2319
    24     public ServerConnection(Socket socket, RequestHandler requestHandler) {
    25         this.socket = socket;
    26         this.requestHandler = requestHandler;
    27         connected = true;
     20        public ServerConnection(Socket socket, RequestHandler requestHandler) {
     21                this.socket = socket;
     22                this.requestHandler = requestHandler;
     23                connected = true;
    2824
    29     }
     25        }
    3026
    31     public void start() {
     27        public void start() {
    3228
    3329
    34         runThreads();
    35     }
     30                runThreads();
     31        }
    3632
    37     @Override
    38     public String toString() {
    39         return socket.getInetAddress().getHostAddress();
    40     }
     33        @Override
     34        public String toString() {
     35                return socket.getInetAddress().getHostAddress();
     36        }
    4137
    42     @Override
    43     protected void receiverThreadRoutine() throws Exception {
    44         while (connected) {
    45             processNextRequest();
    46         }
    47     }
     38        @Override
     39        protected void receiverThreadRoutine() throws Exception {
     40                while (connected) {
     41                        processNextRequest();
     42                }
     43        }
    4844
    49     protected void handleRequest(Request request, ResponseCallback responseCallback) {
    50         if (request instanceof ApplicationRequest) {
    51             requestHandler.handle((ApplicationRequest)request, responseCallback);
    52             return;
    53         }
    54         if (request instanceof ProtocolRequest) {
    55             if (request instanceof VersionRequest) {
    56                 responseCallback.process(new Response(true, null, null));
    57                 return;
    58             }
    59             if (request instanceof UseRequest) {
    60                 String feature = ((UseRequest)request).getFeature();
    61                 if (feature.equals("request_id")) {
    62                     requestIdEnabled = true;
    63                     responseCallback.process(new Response(true, null, null));
    64                     return;
    65                 }
    66                 responseCallback.process(new Response(false, "\"unknown feature: " + feature + "\"", null));
    67                 return;
    68             }
     45        protected void handleRequest(Request request, ResponseCallback responseCallback) {
     46                if (request instanceof ApplicationRequest) {
     47                        requestHandler.handle((ApplicationRequest)request, responseCallback);
     48                        return;
     49                }
     50                if (request instanceof ProtocolRequest) {
     51                        if (request instanceof VersionRequest) {
     52                                responseCallback.process(new Response(true, null, null));
     53                                return;
     54                        }
     55                        if (request instanceof UseRequest) {
     56                                String feature = ((UseRequest)request).getFeature();
     57                                if (feature.equals("request_id")) {
     58                                        requestIdEnabled = true;
     59                                        responseCallback.process(new Response(true, null, null));
     60                                        return;
     61                                }
     62                                responseCallback.process(new Response(false, "\"unknown feature: " + feature + "\"", null));
     63                                return;
     64                        }
    6965
    70         }
    71         LOGGER.error("unhandled request: " + request);
    72         responseCallback.process(new Response(false, "unhandled", null));
    73     }
     66                }
     67                log.error("unhandled request: " + request);
     68                responseCallback.process(new Response(false, "unhandled", null));
     69        }
    7470
    75     protected final void respond(final Response response, final Integer id) {
    76         senderThread.invokeLater(new Runnable() {
    77             @Override
    78             public void run() {
    79                 String outId = id != null ? " " + id : "";
    80                 if (response.getFiles() != null) {
    81                     for (File f : response.getFiles()) {
    82                         output.print("file" + outId/* + " " + f.getPath()*/ + "\n");
    83                         SourceInterface content = f.getContent();
    84                         String line;
    85                         while ((line = content.readLine()) != null) {
    86                             output.print(line);
    87                             output.print('\n');
    88                         }
    89                         output.print("eof\n");
    90                     }
    91                 }
    92                 output.print(response.getOk() ? "ok" : "error");
    93                 output.print(outId);
    94                 if (Strings.notEmpty(response.getComment())) {
    95                     output.print(' ');
    96                     output.print(response.getComment());
    97                 }
    98                 output.print('\n');
    99                 output.flush();
    100             }
    101         });
     71        protected final void respond(final Response response, final Integer id) {
     72                senderThread.invokeLater(new Runnable() {
     73                        @Override
     74                        public void run() {
     75                                String outId = id != null ? " " + id : "";
     76                                if (response.getFiles() != null) {
     77                                        for (File f : response.getFiles()) {
     78                                                output.print("file" + outId/* + " " + f.getPath()*/ + "\n");
     79                                                SourceInterface content = f.getContent();
     80                                                String line;
     81                                                while ((line = content.readLine()) != null) {
     82                                                        output.print(line);
     83                                                        output.print('\n');
     84                                                }
     85                                                output.print("eof\n");
     86                                        }
     87                                }
     88                                output.print(response.getOk() ? "ok" : "error");
     89                                output.print(outId);
     90                                if (Strings.notEmpty(response.getComment())) {
     91                                        output.print(' ');
     92                                        output.print(response.getComment());
     93                                }
     94                                output.print('\n');
     95                                output.flush();
     96                        }
     97                });
    10298
    103     }
     99        }
    104100
    105     protected void processNextRequest() throws Exception {
    106         String line = getLine();
    107         Pair<String, String> command = Strings.splitIntoPair(line, ' ', "\n");
    108         final Pair<Integer, String> rest = parseRest(command.second);
    109         if (rest == null) {
    110             respond(new Response(false, "\"invalid input\"", null), null);
    111             return;
    112         }
     101        protected void processNextRequest() throws Exception {
     102                String line = getLine();
     103                Pair<String, String> command = Strings.splitIntoPair(line, ' ', "\n");
     104                final Pair<Integer, String> rest = parseRest(command.second);
     105                if (rest == null) {
     106                        respond(new Response(false, "\"invalid input\"", null), null);
     107                        return;
     108                }
    113109
    114         final Request request = Request.createRequestByTypeString(command.first);
    115         if (request == null) {
    116             respond(new Response(false, "\"invalid input\"", null), null);
    117             return;
    118         }
    119         request.parseRest(rest.second);
    120         if (LOGGER.isTraceEnabled()) {
    121             LOGGER.trace("read request: " + request);
    122         }
     110                final Request request = Request.createRequestByTypeString(command.first);
     111                if (request == null) {
     112                        respond(new Response(false, "\"invalid input\"", null), null);
     113                        return;
     114                }
     115                request.parseRest(rest.second);
     116                if (log.isTraceEnabled()) {
     117                        log.trace("read request: " + request);
     118                }
    123119
    124         handleRequest(request, new ResponseCallback() {
    125             @Override
    126             public void process(Response response) {
    127                 respond(response, rest.first);
    128             }
    129         });
    130     }
     120                handleRequest(request, new ResponseCallback() {
     121                        @Override
     122                        public void process(Response response) {
     123                                respond(response, rest.first);
     124                        }
     125                });
     126        }
    131127}
  • java/main/src/main/java/com/framsticks/communication/Subscription.java

    r77 r84  
    22
    33import com.framsticks.communication.queries.RegistrationRequest;
    4 import com.framsticks.util.AtOnceDispatcher;
    5 import com.framsticks.util.Dispatcher;
     4import com.framsticks.util.dispatching.AtOnceDispatcher;
     5import com.framsticks.util.dispatching.Dispatcher;
    66import com.framsticks.util.StateFunctor;
    77import org.apache.log4j.Logger;
     
    1313public class Subscription {
    1414
    15     private final static Logger LOGGER = Logger.getLogger(Subscription.class);
     15    private final static Logger log = Logger.getLogger(Subscription.class);
    1616
    1717    private final ClientConnection connection;
     
    5151            public void process(Response response) {
    5252                if (!response.getOk()) {
    53                     LOGGER.error("failed to unsunscribe " + this + ": " + response.getComment());
     53                    log.error("failed to unsunscribe " + this + ": " + response.getComment());
    5454                    stateFunctor.call(new Exception(response.getComment()));
    5555                    return;
    5656                }
    5757                assert response.hasFiles();
    58                 LOGGER.debug("unsunscribed " + this);
     58                log.debug("unsunscribed " + this);
    5959                stateFunctor.call(null);
    6060            }
  • java/main/src/main/java/com/framsticks/communication/queries/ApplicationRequest.java

    r77 r84  
    22
    33import com.framsticks.communication.Request;
     4import com.framsticks.util.lang.Delimeted;
    45
    56import java.util.Collection;
     
    1011public abstract class ApplicationRequest extends Request {
    1112
    12     protected String path;
    13     protected String fields;
     13        protected String path;
     14        protected String fields;
    1415
    15     public ApplicationRequest setPath(String path) {
    16         assert path != null;
    17         this.path = path;
    18         return this;
    19     }
     16        public ApplicationRequest setPath(String path) {
     17                assert path != null;
     18                this.path = path;
     19                return this;
     20        }
    2021
    21     public ApplicationRequest setField(String field) {
    22         this.fields = field;
    23         return this;
    24     }
     22        public ApplicationRequest setField(String field) {
     23                this.fields = field;
     24                return this;
     25        }
    2526
    26     public ApplicationRequest setFields(Collection<String> fields) {
    27         StringBuilder fieldString = new StringBuilder();
    28         boolean notFirst = false;
    29         for (String field : fields) {
    30             if (notFirst) {
    31                 fieldString.append(",");
    32 
    33             } else {
    34                 notFirst = true;
    35             }
    36             fieldString.append(field);
    37         }
    38         return setField(fieldString.toString());
    39     }
     27        public ApplicationRequest setFields(Collection<String> fields) {
     28                Delimeted d = new Delimeted(",", "");
     29                for (String f : fields) {
     30                        d.append(f);
     31                }
     32                return setField(d.build());
     33        }
    4034
    4135
    42     public String getPath() {
    43         return path;
    44     }
     36        public String getPath() {
     37                return path;
     38        }
    4539
    46     @Override
    47     protected StringBuilder construct(StringBuilder buffer) {
    48         buffer.append(' ').append(path);
    49         if (fields != null) {
    50             buffer.append(' ').append(fields);
    51         }
    52         return buffer;
    53     }
     40        @Override
     41        protected StringBuilder construct(StringBuilder buffer) {
     42                buffer.append(' ').append(path);
     43                if (fields != null) {
     44                        buffer.append(' ').append(fields);
     45                }
     46                return buffer;
     47        }
    5448
    55     @Override
    56     public void parseRest(String rest) {
    57         path = rest;
    58     }
     49        @Override
     50        public void parseRest(String rest) {
     51                path = rest;
     52        }
    5953
    6054}
  • java/main/src/main/java/com/framsticks/communication/queries/CallRequest.java

    r77 r84  
    99 */
    1010public class CallRequest extends ApplicationRequest {
     11
    1112        protected String arguments;
    1213        protected String method;
    13 
    1414
    1515        public CallRequest setArguments(String arguments) {
     
    2121                StringBuilder buffer = new StringBuilder();
    2222                for (String a : arguments) {
    23                         String arg = a.trim();
    2423                        buffer.append(" ");
    25                         Request.quoteValue(buffer, arg);
     24                        Request.quoteValue(buffer, a.trim());
    2625                }
    2726                return this.setArguments(buffer.toString());
     
    4241                        buffer.append(arguments);
    4342                }
    44         return buffer;
     43                return buffer;
    4544        }
    4645
  • java/main/src/main/java/com/framsticks/communication/queries/GetRequest.java

    r77 r84  
    11package com.framsticks.communication.queries;
    2 
    3 import com.framsticks.communication.Request;
    42
    53/**
  • java/main/src/main/java/com/framsticks/communication/queries/InfoRequest.java

    r77 r84  
    11package com.framsticks.communication.queries;
    2 
    3 import com.framsticks.communication.Request;
    42
    53/**
  • java/main/src/main/java/com/framsticks/communication/queries/RegistrationRequest.java

    r77 r84  
    11package com.framsticks.communication.queries;
    2 
    3 import com.framsticks.communication.Request;
    42
    53/**
     
    1715        }
    1816
    19     @Override
     17        @Override
    2018        protected StringBuilder construct(StringBuilder buffer) {
    21         super.construct(buffer);
     19                super.construct(buffer);
    2220                if (!register) {
    2321                        buffer.append(" remove");
    2422                }
    25         return buffer;
     23                return buffer;
    2624        }
    2725
  • java/main/src/main/java/com/framsticks/communication/queries/SetRequest.java

    r77 r84  
    11package com.framsticks.communication.queries;
    2 
    3 import com.framsticks.communication.Request;
    42
    53/**
     
    2321                        buffer.append(" \"").append(value).append("\"");
    2422                }
    25         return buffer;
     23                return buffer;
    2624        }
    2725        @Override
  • java/main/src/main/java/com/framsticks/communication/queries/UseRequest.java

    r77 r84  
    11package com.framsticks.communication.queries;
    2 
    3 import com.framsticks.communication.Request;
    42
    53/**
     
    1412        }
    1513
    16     @Override
     14        @Override
    1715        public String getCommand() {
    1816                return "use";
    1917        }
    2018
    21     @Override
     19        @Override
    2220        protected StringBuilder construct(StringBuilder buffer) {
    2321                return buffer.append(' ').append(feature);
    2422        }
    2523
    26     @Override
    27     public void parseRest(String rest) {
    28         feature = rest;
    29     }
     24        @Override
     25        public void parseRest(String rest) {
     26                feature = rest;
     27        }
    3028
    31     public final String getFeature() {
    32         return feature;
    33     }
     29        public final String getFeature() {
     30                return feature;
     31        }
    3432}
  • java/main/src/main/java/com/framsticks/communication/queries/VersionRequest.java

    r77 r84  
    11package com.framsticks.communication.queries;
    22
    3 import com.framsticks.communication.Request;
    4 import com.framsticks.util.Numbers;
    5 import com.sun.j3d.loaders.ParsingErrorException;
     3import com.framsticks.util.lang.Numbers;
    64
    75/**
     
    1917        }
    2018
    21     @Override
     19        @Override
    2220        public String getCommand() {
    2321                return "version";
    2422        }
    2523
    26     @Override
    27     public void parseRest(String rest) {
    28         version = Numbers.parse(rest, Integer.class);
    29     }
     24        @Override
     25        public void parseRest(String rest) {
     26                version = Numbers.parse(rest, Integer.class);
     27        }
    3028
    31     @Override
    32     protected StringBuilder construct(StringBuilder buffer) {
     29        @Override
     30        protected StringBuilder construct(StringBuilder buffer) {
    3331                return buffer.append(' ').append(version);
    3432        }
  • java/main/src/main/java/com/framsticks/communication/util/LoggingStateCallback.java

    r77 r84  
    33import com.framsticks.communication.StateCallback;
    44import org.apache.log4j.Logger;
    5 import org.apache.log4j.Priority;
    65
    76/**
  • java/main/src/main/java/com/framsticks/core/Entity.java

    r78 r84  
    11package com.framsticks.core;
    22
    3 import com.framsticks.util.*;
    4 import com.framsticks.util.Thread;
     3import com.framsticks.params.FramsClass;
     4import com.framsticks.util.dispatching.Thread;
     5import com.framsticks.util.dispatching.Dispatcher;
     6
     7import org.apache.commons.configuration.Configuration;
    58import org.apache.log4j.Logger;
    69
     
    811 * @author Piotr Sniegowski
    912 */
    10 public abstract class Entity extends Parameters implements Dispatcher {
     13public abstract class Entity implements Dispatcher {
    1114
    12     private final static Logger LOGGER = Logger.getLogger(Entity.class.getName());
     15        private final static Logger log = Logger.getLogger(Entity.class.getName());
    1316
    14     public Entity(Parameters parameters) {
    15         super(parameters);
    16         if (dispatcher == null) {
    17             dispatcher = new Thread(name);
    18         }
    19     }
     17        protected String name = "entity";
     18        protected EntityOwner owner;
     19        protected Dispatcher dispatcher;
    2020
    21     @Override
    22     public final boolean isActive() {
    23         return dispatcher.isActive();
    24     }
     21        public Entity() {
     22        }
    2523
    26     @Override
    27     public final void invokeLater(Runnable runnable) {
    28         dispatcher.invokeLater(runnable);
    29     }
     24        public final String getName() {
     25                return name;
     26        }
    3027
    31     protected void run() {
    32         assert isActive();
    33         LOGGER.info("running: " + this);
    34     }
     28        /**
     29         * @param name the name to set
     30         */
     31        public final void setName(String name) {
     32                this.name = name;
     33                if (dispatcher instanceof Thread) {
     34                        ((Thread) dispatcher).setName(name);
     35                }
     36        }
    3537
    36     public final void configurePublic() throws Exception {
    37         configure();
    38     }
     38        /**
     39         * @return the owner
     40         */
     41        public EntityOwner getOwner() {
     42                return owner;
     43        }
    3944
    40     protected void configure() throws Exception {
     45        /**
     46         * @param owner the owner to set
     47         */
     48        public void setOwner(EntityOwner owner) {
     49                this.owner = owner;
     50        }
    4151
    42     }
     52        @Override
     53        public final boolean isActive() {
     54                return dispatcher == null || dispatcher.isActive();
     55        }
    4356
    44     public Dispatcher getDispatcher() {
    45         return dispatcher;
    46     }
     57        @Override
     58        public final void invokeLater(Runnable runnable) {
     59                assert dispatcher != null;
     60                dispatcher.invokeLater(runnable);
     61        }
    4762
    48     public final void start() {
    49         invokeLater(new Runnable() {
    50             @Override
    51             public void run() {
    52                 Entity.this.run();
    53             }
    54         });
    55     }
     63        public Dispatcher createDefaultDispatcher() {
     64                return new Thread(name);
     65        }
     66
     67        protected void run() {
     68                assert isActive();
     69                log.info("running: " + this);
     70        }
     71
     72
     73        public void configure(Configuration config) {
     74        }
     75
     76        public Dispatcher getDispatcher() {
     77                return dispatcher;
     78        }
     79
     80        /**
     81         * @param dispatcher the dispatcher to set
     82         */
     83        public void setDispatcher(Dispatcher dispatcher) {
     84                this.dispatcher = dispatcher;
     85        }
     86
     87        public final void start() {
     88                if (dispatcher == null) {
     89                        log.debug("no dispatcher set for " + this + ", creating default one");
     90                        setDispatcher(createDefaultDispatcher());
     91                }
     92                invokeLater(new Runnable() {
     93                        @Override
     94                        public void run() {
     95                                Entity.this.run();
     96                        }
     97                });
     98        }
    5699
    57100        public final void done() {
    58                 LOGGER.info("stopping entity");
     101                log.info("stopping entity");
    59102                if (owner != null) {
    60103                        owner.onDone();
     
    62105        }
    63106
    64 
     107        public static void constructFramsClass(FramsClass.Constructor constructor) {
     108                constructor.method("getName");
     109        }
    65110}
  • java/main/src/main/java/com/framsticks/core/Instance.java

    r78 r84  
    33import com.framsticks.communication.*;
    44import com.framsticks.params.*;
    5 import com.framsticks.params.types.CompositeParam;
    65import com.framsticks.params.types.ObjectParam;
    76import com.framsticks.parsers.Loaders;
     
    98import com.framsticks.util.*;
    109import com.framsticks.util.UnsupportedOperationException;
     10import com.framsticks.util.dispatching.Dispatching;
     11import com.framsticks.util.dispatching.Future;
     12import com.framsticks.util.lang.Casting;
    1113import org.apache.log4j.Logger;
    1214
     
    1820public abstract class Instance extends Entity {
    1921
    20         private static final Logger LOGGER = Logger.getLogger(Instance.class.getName());
    21 
    22 
    23     protected Node root;
    24 
    25     public Set<InstanceListener> listeners = new HashSet<InstanceListener>();
    26 
    27     public Instance(Parameters parameters) {
    28         super(parameters);
    29         root = new Node((CompositeParam)new ParamBuilder().setName("Instance").setId(name).setType("o").build(), null);
    30         }
    31 
    32     @Override
    33     protected void run() {
    34         super.run();
     22        private static final Logger log = Logger.getLogger(Instance.class.getName());
     23
     24
     25        protected Node root;
     26
     27        public Set<InstanceListener> listeners = new HashSet<InstanceListener>();
     28
     29        public Instance() {
     30        }
     31
     32        @Override
     33        protected void run() {
     34                super.run();
     35                root = new Node((CompositeParam)new ParamBuilder().setName("Instance").setId(name).setType("o").build(), null);
    3536                com.framsticks.model.Package.register(registry);
    36     }
    37 
    38     @Override
    39     protected void configure() throws Exception {
    40         super.configure();
    41     }
    42 
    43     protected void fetchInfo(Path path, Future<FramsClass> future) {
     37        }
     38
     39        protected void fetchInfo(Path path, Future<FramsClass> future) {
    4440                future.result(null, new UnsupportedOperationException());
    4541        }
     
    6157        }
    6258
    63     public void fetchValue(Path path, Param param, StateFunctor stateFunctor) {
     59        public void fetchValue(Path path, Param param, StateFunctor stateFunctor) {
    6460                stateFunctor.call(null);
    6561        }
    6662
    67     public void fetchValues(Path path, StateFunctor stateFunctor) {
     63        public void fetchValues(Path path, StateFunctor stateFunctor) {
    6864                stateFunctor.call(null);
    6965        }
    7066
    71     protected void tryRegisterOnChangeEvents(Path path) {
     67        protected void tryRegisterOnChangeEvents(Path path) {
    7268
    7369        }
     
    8379        }
    8480
    85     protected void fireRun(Exception e) {
    86         for (InstanceListener l : this.listeners) {
    87             l.onRun(e);
    88         }
    89     }
    90 
    91     protected void fireStop(Exception e) {
    92         for (InstanceListener l : this.listeners) {
    93             l.onStop(e);
    94         }
    95     }
    96 
    97     public void addListener(final InstanceListener listener) {
    98         assert Dispatching.isThreadSafe();
    99         Dispatching.invokeLaterOrNow(this, new Runnable() {
    100             @Override
    101             public void run() {
    102                 listeners.add(listener);
    103             }
    104         });
    105     }
    106 
    107     public void removeListener(final InstanceListener listener) {
    108         assert Dispatching.isThreadSafe();
    109         Dispatching.invokeLaterOrNow(this, new Runnable() {
    110             @Override
    111             public void run() {
    112                 listeners.remove(listener);
    113             }
    114         });
    115     }
    116 
    117 
    118     protected void fireListChange(Path path, ListChange change) {
    119         assert isActive();
    120         for (InstanceListener l : this.listeners) {
     81        protected void fireRun(Exception e) {
     82                for (InstanceListener l : this.listeners) {
     83                        l.onRun(e);
     84                }
     85        }
     86
     87        protected void fireStop(Exception e) {
     88                for (InstanceListener l : this.listeners) {
     89                        l.onStop(e);
     90                }
     91        }
     92
     93        public void addListener(final InstanceListener listener) {
     94                assert Dispatching.isThreadSafe();
     95                Dispatching.invokeLaterOrNow(this, new Runnable() {
     96                        @Override
     97                        public void run() {
     98                                listeners.add(listener);
     99                        }
     100                });
     101        }
     102
     103        public void removeListener(final InstanceListener listener) {
     104                assert Dispatching.isThreadSafe();
     105                Dispatching.invokeLaterOrNow(this, new Runnable() {
     106                        @Override
     107                        public void run() {
     108                                listeners.remove(listener);
     109                        }
     110                });
     111        }
     112
     113
     114        protected void fireListChange(Path path, ListChange change) {
     115                assert isActive();
     116                for (InstanceListener l : this.listeners) {
    121117                        l.onListChange(path, change);
    122118                }
    123119        }
    124120
    125 
    126     public final FramsClass getInfoFromCache(Path path) {
    127         return getInfoFromCache(path.getTop().getParam().getContainedTypeName());
    128     }
    129 
    130 
    131     public FramsClass getInfoFromCache(String id) {
    132         assert isActive();
     121        protected void fireFetch(Path path) {
     122                assert isActive();
     123                for (InstanceListener l : this.listeners) {
     124                        l.onFetch(path);
     125                }
     126        }
     127
     128
     129        public final FramsClass getInfoFromCache(Path path) {
     130                return getInfoFromCache(path.getTop().getParam().getContainedTypeName());
     131        }
     132
     133
     134        public FramsClass getInfoFromCache(String id) {
     135                assert isActive();
    133136                return registry.getInfoFromCache(id);
    134137        }
     
    137140
    138141        public AccessInterface createAccess(String name) {
    139         assert isActive();
    140         if (name == null) {
     142                assert isActive();
     143                return registry.createAccess(name);
     144        }
     145
     146
     147        // TODO: make ValueParam
     148        public <T> T get(Node node, Param childParam, Class<T> type) {
     149                return bindAccess(node).get((ValueParam) childParam, type);
     150        }
     151
     152        public void findInfo(final Path path, final Future<FramsClass> future) {
     153                assert isActive();
     154                final String name = path.getTop().getParam().getContainedTypeName();
     155                final FramsClass framsClass = getInfoFromCache(name);
     156                if (framsClass != null) {
     157                        log.trace("info for " + name + " found in cache");
     158                        future.result(framsClass, null);
     159                        return;
     160                }
     161                fetchInfo(path, future);
     162        }
     163
     164        public final AccessInterface bindAccess(Node node) {
     165                assert node.getObject() != null;
     166                AccessInterface access = registry.prepareAccess(node.getParam());
     167                if (access == null) {
     168                        log.error("missing access for: " + node.getParam());
    141169                        return null;
    142170                }
    143                 FramsClass framsClass = getInfoFromCache(name);
    144                 if (framsClass == null) {
    145                         return null;
    146                 }
    147 
    148                 return registry.createAccess(name, framsClass);
    149         }
    150 
    151         public static AccessInterface wrapAccessWithListIfNeeded(CompositeParam param, AccessInterface access) {
    152         if (access == null) {
    153                         return null;
    154                 }
    155         return param.prepareAccessInterface(access);
    156         }
    157 
    158     public AccessInterface prepareAccess(CompositeParam param) {
    159         return wrapAccessWithListIfNeeded(param, createAccess(param.getContainedTypeName()));
    160     }
    161 
    162     public <T> T get(Node node, Param childParam, Class<T> type) {
    163         return bindAccess(node).get(childParam, type);
    164     }
    165 
    166     public void findInfo(final Path path, final Future<FramsClass> future) {
    167         assert isActive();
    168         final String name = path.getTop().getParam().getContainedTypeName();
    169         final FramsClass framsClass = getInfoFromCache(name);
    170         if (framsClass != null) {
    171             LOGGER.trace("info for " + name + " found in cache");
    172             future.result(framsClass, null);
    173             return;
    174         }
    175         fetchInfo(path, future);
    176     }
    177 
    178     public final AccessInterface bindAccess(Node node) {
    179         assert node.getObject() != null;
    180         AccessInterface access = prepareAccess(node.getParam());
    181         if (access == null) {
    182                         LOGGER.error("missing access for: " + node.getParam());
    183             return null;
    184         }
    185         access.select(node.getObject());
    186         return access;
    187     }
    188 
    189     public final <T> T getParam(Path path, String id, Class<T> type) {
    190         return Casting.tryCast(type, prepareAccess(path.getTop().getParam()).getParam(id));
    191     }
    192 
    193     public final AccessInterface bindAccess(Path path) {
    194         assert path.isResolved();
    195         return bindAccess(path.getTop());
    196     }
    197 
    198     public void resolve(final String targetPath, final Future<Path> future) {
    199         assert isActive();
    200         final Path path = new Path(this, targetPath);
    201         resolve(path, new Future<Path>() {
    202             @Override
    203             public void result(Path result, Exception e) {
    204                 assert isActive();
    205                 if (e != null) {
    206                     future.result(path, e);
    207                     return;
    208                 }
    209                 if (path.isResolved(targetPath)) {
    210                     future.result(path, null);
    211                     return;
    212                 }
    213                 if (path.isResolved()) {
    214                     future.result(path, new Exception("testing"));
    215                     return;
    216                 }
    217                 resolve(targetPath, future);
    218             }
    219         });
    220     }
    221 
    222     public void resolveAndFetch(final String targetPath, final Future<Path> future) {
    223         assert isActive();
    224         resolve(targetPath, new Future<Path>() {
    225             @Override
    226             public void result(final Path path, Exception e) {
    227                 if (e != null) {
    228                     future.result(path, e);
    229                     return;
    230                 }
    231                 assert path.isResolved(targetPath);
    232                 fetchValues(path, new StateFunctor() {
    233                     @Override
    234                     public void call(Exception e) {
    235                         future.result(path, e);
    236                     }
    237                 });
    238             }
    239         });
    240     }
    241 
    242     public Path createIfNeeded(String path) {
    243         Path p;
    244         while (!(p = new Path(this, path)).isResolved(path)) {
    245             create(p);
    246         }
    247         return p;
    248     }
    249 
    250     public Path create(Path path) {
    251         assert isActive();
    252         assert !path.isResolved();
    253         Path resolved = path.findResolution();
    254         if (!resolved.isResolved()) {
    255             LOGGER.debug("creating: " + path);
    256             AccessInterface access = prepareAccess(path.getTop().getParam());
    257             assert access != null;
    258             Object child = access.createAccessee();
    259             assert child != null;
    260             if (path.size() == 1) {
    261                 root = new Node(root.getParam(), child);
    262             } else {
    263                 bindAccess(path.getUnder()).set(path.getTop().getParam(), child);
    264             }
    265             resolved = path.appendResolution(child);
    266         }
    267         tryRegisterOnChangeEvents(resolved);
    268         return resolved;
    269     }
    270 
    271 
    272 
    273 
    274     public FramsClass processFetchedInfo(File file) {
    275         assert isActive();
    276         FramsClass framsClass = Loaders.loadFramsClass(file.getContent());
    277         if ("/".equals(file.getPath())) {
    278             if (root.getParam().getContainedTypeName() == null) {
    279                 root = new Node((CompositeParam)new ParamBuilder().setName("Instance").setId(name).setType("o " + framsClass.getId()).build(), root.getObject());
    280             }
    281         }
    282         registry.putInfoIntoCache(framsClass);
    283         return framsClass;
    284     }
    285 
    286     public void processFetchedValues(Path path, List<File> files) {
    287         assert isActive();
    288         assert files.size() == 1;
    289         assert path.isTheSame(files.get(0).getPath());
    290         Node node = path.getTop();
    291         MultiParamLoader loader = new MultiParamLoader();
    292         loader.setNewSource(files.get(0).getContent());
    293         loader.addBreakCondition(MultiParamLoader.Status.AfterObject);
    294 
    295         try {
    296             if (node.getParam() instanceof ObjectParam) {
    297                 loader.addAccessInterface(bindAccess(node));
    298                 loader.go();
    299     //            for (NodeListener l : listeners) {
    300     //                l.onChange(this);
    301     //            }
    302                 return;
    303             }
    304 
    305             ListAccess listAccess = ((ListAccess)bindAccess(node));
    306             assert listAccess != null;
    307             listAccess.clearValues();
    308 
    309             AccessInterface elementAccess = listAccess.getElementAccess();
    310             loader.addAccessInterface(elementAccess);
    311             MultiParamLoader.Status status;
    312             while ((status = loader.go()) != MultiParamLoader.Status.Finished) {
    313                 if (status == MultiParamLoader.Status.AfterObject) {
    314                     AccessInterface accessInterface = loader.getLastAccessInterface();
    315 
    316                     String id = listAccess.computeIdentifierFor(accessInterface.getSelected());
    317                     Param param = new ParamBuilder().setType("o " + accessInterface.getId()).setId(id).build();
    318                     Object child = accessInterface.getSelected();
    319                     accessInterface.select(null);
    320                     assert child != null;
    321                     bindAccess(node).set(param, child);
    322                 }
    323             }
    324     //        for (NodeListener l : listeners) {
    325     //            l.onChange(this);
    326     //        }
    327         } catch (Exception e) {
    328             LOGGER.error("exception occurred while loading: " + e);
    329         }
    330 
    331     }
    332 
    333     public static Iterator<String> splitPath(String path) {
    334         List<String> list = new LinkedList<String>();
    335         for (String s : path.split("/")) {
    336             if (!s.isEmpty()) {
    337                 list.add(s);
    338             }
    339         }
    340         return list.iterator();
    341     }
     171                access.select(node.getObject());
     172                return access;
     173        }
     174
     175        public final <T> T getParam(Path path, String id, Class<T> type) {
     176                return Casting.tryCast(type, registry.prepareAccess(path.getTop().getParam()).getParam(id));
     177        }
     178
     179        public final AccessInterface bindAccess(Path path) {
     180                assert path.isResolved();
     181                return bindAccess(path.getTop());
     182        }
     183
     184        public void resolve(final String targetPath, final Future<Path> future) {
     185                assert isActive();
     186                final Path path = getPath(targetPath);
     187                resolve(path, new Future<Path>() {
     188                        @Override
     189                        public void result(Path result, Exception e) {
     190                                assert isActive();
     191                                if (e != null) {
     192                                        future.result(path, e);
     193                                        return;
     194                                }
     195                                if (path.isResolved(targetPath)) {
     196                                        future.result(path, null);
     197                                        return;
     198                                }
     199                                if (path.isResolved()) {
     200                                        future.result(path, new Exception("testing"));
     201                                        return;
     202                                }
     203                                resolve(targetPath, future);
     204                        }
     205                });
     206        }
     207
     208        public void resolveAndFetch(final String targetPath, final Future<Path> future) {
     209                assert isActive();
     210                resolve(targetPath, new Future<Path>() {
     211                        @Override
     212                        public void result(final Path path, Exception e) {
     213                                if (e != null) {
     214                                        future.result(path, e);
     215                                        return;
     216                                }
     217                                assert path.isResolved(targetPath);
     218                                fetchValues(path, new StateFunctor() {
     219                                        @Override
     220                                        public void call(Exception e) {
     221                                                future.result(path, e);
     222                                        }
     223                                });
     224                        }
     225                });
     226        }
     227
     228        public Path createIfNeeded(String path) {
     229                Path p;
     230                while (!(p = getPath(path)).isResolved(path)) {
     231                        create(p);
     232                }
     233                return p;
     234        }
     235
     236        public Path createIfNeeded(Path path) {
     237                assert isActive();
     238                if (path.isResolved()) {
     239                        return path;
     240                }
     241                return create(path);
     242        }
     243
     244        public Path create(Path path) {
     245                assert isActive();
     246                assert !path.isResolved();
     247                Path resolved = path.tryFindResolution();
     248                if (!resolved.isResolved()) {
     249                        log.debug("creating: " + path);
     250                        AccessInterface access = registry.prepareAccess(path.getTop().getParam());
     251                        assert access != null;
     252                        Object child = access.createAccessee();
     253                        assert child != null;
     254                        if (path.size() == 1) {
     255                                root = new Node(root.getParam(), child);
     256                        } else {
     257                                bindAccess(path.getUnder()).set(path.getTop().getParam(), child);
     258                        }
     259                        resolved = path.appendResolution(child);
     260                }
     261                tryRegisterOnChangeEvents(resolved);
     262                return resolved;
     263        }
     264
     265
     266
     267
     268        public FramsClass processFetchedInfo(File file) {
     269                assert isActive();
     270                FramsClass framsClass = Loaders.loadFramsClass(file.getContent());
     271                if ("/".equals(file.getPath())) {
     272                        if (root.getParam().getContainedTypeName() == null) {
     273                                root = new Node((CompositeParam)new ParamBuilder().setName("Instance").setId(name).setType("o " + framsClass.getId()).build(), root.getObject());
     274                        }
     275                }
     276                registry.putInfoIntoCache(framsClass);
     277                return framsClass;
     278        }
     279
     280        public void processFetchedValues(Path path, List<File> files) {
     281                assert isActive();
     282                assert files.size() == 1;
     283                assert path.isTheSame(files.get(0).getPath());
     284                Node node = path.getTop();
     285                MultiParamLoader loader = new MultiParamLoader();
     286                loader.setNewSource(files.get(0).getContent());
     287                loader.addBreakCondition(MultiParamLoader.Status.AfterObject);
     288
     289                try {
     290                        if (node.getParam() instanceof ObjectParam) {
     291                                loader.addAccessInterface(bindAccess(node));
     292                                loader.go();
     293                                fireFetch(path);
     294        //            for (NodeListener l : listeners) {
     295        //                l.onChange(this);
     296        //            }
     297                                return;
     298                        }
     299
     300                        ListAccess listAccess = ((ListAccess)bindAccess(node));
     301                        assert listAccess != null;
     302                        listAccess.clearValues();
     303
     304                        AccessInterface elementAccess = listAccess.getElementAccess();
     305                        loader.addAccessInterface(elementAccess);
     306                        MultiParamLoader.Status status;
     307                        while ((status = loader.go()) != MultiParamLoader.Status.Finished) {
     308                                if (status == MultiParamLoader.Status.AfterObject) {
     309                                        AccessInterface accessInterface = loader.getLastAccessInterface();
     310
     311                                        String id = listAccess.computeIdentifierFor(accessInterface.getSelected());
     312                                        Param param = new ParamBuilder().setType("o " + accessInterface.getId()).setId(id).build();
     313                                        Object child = accessInterface.getSelected();
     314                                        accessInterface.select(null);
     315                                        assert child != null;
     316                                        bindAccess(node).set((ValueParam) param, child);
     317                                }
     318                        }
     319
     320                        fireFetch(path);
     321        //        for (NodeListener l : listeners) {
     322        //            l.onChange(this);
     323        //        }
     324                } catch (Exception e) {
     325                        log.error("exception occurred while loading: " + e);
     326                }
     327
     328        }
     329
     330        public static Iterator<String> splitPath(String path) {
     331                List<String> list = new LinkedList<String>();
     332                for (String s : path.split("/")) {
     333                        if (!s.isEmpty()) {
     334                                list.add(s);
     335                        }
     336                }
     337                return list.iterator();
     338        }
    342339
    343340        public Registry getRegistry() {
    344341                return registry;
    345342        }
     343
     344        public Path getPath(String textual) {
     345                return new Path(this, textual);
     346        }
     347
     348        public Path getRootPath() {
     349                return getPath("/");
     350        }
    346351}
    347352
  • java/main/src/main/java/com/framsticks/core/InstanceListener.java

    r77 r84  
    55 */
    66public interface InstanceListener {
    7     public void onListChange(Path path, ListChange change);
    8     public void onRun(Exception e);
    9     public void onStop(Exception e);
     7        public void onListChange(Path path, ListChange change);
     8        public void onFetch(Path path);
     9        public void onRun(Exception e);
     10        public void onStop(Exception e);
    1011}
  • java/main/src/main/java/com/framsticks/core/ListChange.java

    r77 r84  
    22
    33import com.framsticks.params.FramsClass;
    4 import com.framsticks.params.ListSource;
    54import com.framsticks.params.ParamBuilder;
    65import com.framsticks.params.types.DecimalParam;
    76import com.framsticks.params.types.EnumParam;
    87import com.framsticks.params.types.StringParam;
    9 import com.framsticks.util.Strings;
     8import com.framsticks.util.lang.Strings;
    109
    11 import java.util.ArrayList;
    1210import java.util.Arrays;
    1311
     
    1715public class ListChange {
    1816
    19     public Action getAction() {
    20         return action;
    21     }
     17        public Action getAction() {
     18                return action;
     19        }
    2220
    23     public Integer getPosition() {
    24         return position;
    25     }
     21        public Integer getPosition() {
     22                return position;
     23        }
    2624
    27     public String getIdentifier() {
    28         return identifier;
    29     }
     25        public String getIdentifier() {
     26                return identifier;
     27        }
    3028
    31     public static enum Action {
    32         Add,
    33         Remove,
    34         Modify
    35     }
     29        public static enum Action {
     30                Add,
     31                Remove,
     32                Modify
     33        }
    3634
    37     private Action action;
    38     private Integer position;
    39     private String identifier;
     35        private Action action;
     36        private Integer position;
     37        private String identifier;
    4038
    41     public Integer getType() { return action.ordinal(); }
    42     public void setType(Integer type) { action = Action.values()[type]; }
     39        public Integer getType() { return action.ordinal(); }
     40        public void setType(Integer type) { action = Action.values()[type]; }
    4341
    4442        public Integer getPos() { return position; }
     
    4846        public void setId(String id) { identifier = id; }
    4947
    50     public String getBestIdentifier() {
    51         if (Strings.notEmpty(identifier)) {
    52             return identifier;
    53         }
    54         return position.toString();
    55     }
     48        public String getBestIdentifier() {
     49                if (Strings.notEmpty(identifier)) {
     50                        return identifier;
     51                }
     52                return position.toString();
     53        }
    5654
    57     public static FramsClass getFramsClass() {
     55        public static FramsClass getFramsClass() {
     56                return new FramsClass("ListChange", "ListChange", null)
     57                                .append(new ParamBuilder().setId("type").setName("type").setType(new EnumParam(Arrays.asList("Add", "Remove", "Modify"))).build())
     58                                .append(new ParamBuilder().setId("id").setName("identifier").setType(StringParam.class).build())
     59                                .append(new ParamBuilder().setId("pos").setName("position").setType(DecimalParam.class).build());
     60        }
    5861
    59         ArrayList<String> actions = new ArrayList<String>();
    60         actions.add("Add");
    61         actions.add("Remove");
    62         actions.add("Modify");
    63         return new FramsClass("ListChange", "ListChange", null)
    64                 .append(new ParamBuilder().setId("type").setName("type").setType(new EnumParam(actions)).build())
    65                 .append(new ParamBuilder().setId("id").setName("identifier").setType(StringParam.class).build())
    66                 .append(new ParamBuilder().setId("pos").setName("position").setType(DecimalParam.class).build());
    67     }
    68 
    69     @Override
    70     public String toString() {
    71         return action + " " + identifier + " " + position;
    72     }
     62        @Override
     63        public String toString() {
     64                return action + " " + identifier + " " + position;
     65        }
    7366}
  • java/main/src/main/java/com/framsticks/core/LocalInstance.java

    r78 r84  
    22
    33import com.framsticks.hosting.InstanceClient;
    4 import com.framsticks.params.AccessInterface;
    5 import com.framsticks.params.Param;
    6 import com.framsticks.util.*;
    7 import com.framsticks.util.Thread;
     4import com.framsticks.util.dispatching.Thread;
     5
     6import org.apache.commons.configuration.Configuration;
    87import org.apache.log4j.Logger;
    98
     
    2120public abstract class LocalInstance extends Instance {
    2221
    23     private static final Logger LOGGER = Logger.getLogger(LocalInstance.class.getName());
     22        private static final Logger log = Logger.getLogger(LocalInstance.class.getName());
    2423
    25     public LocalInstance(Parameters parameters) {
    26         super(parameters);
     24        public LocalInstance() {
    2725
    28         Integer accept = config.getInteger("accept", null);
    29         if (accept != null) {
    30             try {
    31                 acceptSocket = new ServerSocket();
    32                 acceptSocket.setReuseAddress(true);
    33                 acceptThread = new Thread(name + "-accept");
    34                 tryBind(accept);
    35             } catch (IOException e) {
    36                 LOGGER.fatal("failed to create accept socket: " + e);
    37             }
    38         }
    39     }
     26        }
    4027
    41     @Override
    42     protected void run() {
    43         super.run();
    44     }
     28        @Override
     29        public void configure(Configuration config) {
     30                Integer accept = config.getInteger("accept", null);
     31                if (accept != null) {
     32                        try {
     33                                acceptSocket = new ServerSocket();
     34                                acceptSocket.setReuseAddress(true);
     35                                acceptThread = new Thread(name + "-accept");
     36                                tryBind(accept);
     37                        } catch (IOException e) {
     38                                log.fatal("failed to create accept socket: " + e);
     39                        }
     40                }
     41        }
    4542
    46     @Override
    47     protected void configure() throws Exception {
    48         super.configure();
    49     }
     43        protected final Set<InstanceClient> clients = new HashSet<InstanceClient>();
     44        ServerSocket acceptSocket;
     45        Thread acceptThread;
    5046
    51     protected final Set<InstanceClient> clients = new HashSet<InstanceClient>();
    52     ServerSocket acceptSocket;
    53     Thread acceptThread;
     47        protected void acceptNext() {
     48                acceptThread.invokeLater(new Runnable() {
     49                        @Override
     50                        public void run() {
     51                                try {
     52                                        final Socket socket = acceptSocket.accept();
     53                                        assert socket != null;
     54                                        log.debug("accepted socket: " + socket.getInetAddress().getHostAddress());
     55                                        invokeLater(new Runnable() {
     56                                                @Override
     57                                                public void run() {
     58                                                        InstanceClient client = new InstanceClient(LocalInstance.this, socket);
     59                                                        clients.add(client);
     60                                                        log.info("client connected: " + client);
     61                                                }
     62                                        });
     63                                } catch (IOException e) {
     64                                        log.error("failed to accept socket: " + e);
     65                                }
     66                                acceptNext();
     67                        }
     68                });
     69        }
    5470
    55     protected void acceptNext() {
    56         acceptThread.invokeLater(new Runnable() {
    57             @Override
    58             public void run() {
    59                 try {
    60                     final Socket socket = acceptSocket.accept();
    61                     assert socket != null;
    62                     LOGGER.debug("accepted socket: " + socket.getInetAddress().getHostAddress());
    63                     invokeLater(new Runnable() {
    64                         @Override
    65                         public void run() {
    66                             InstanceClient client = new InstanceClient(LocalInstance.this, socket);
    67                             clients.add(client);
    68                             LOGGER.info("client connected: " + client);
    69                         }
    70                     });
    71                 } catch (IOException e) {
    72                     LOGGER.error("failed to accept socket: " + e);
    73                 }
    74                 acceptNext();
    75             }
    76         });
    77     }
    78 
    79     public void tryBind(final Integer accept) {
    80         acceptThread.invokeLater(new Runnable() {
    81             @Override
    82             public void run() {
    83                 try {
    84                     acceptSocket.bind(new InetSocketAddress(accept));
    85                     LOGGER.debug("started accepting on port " + accept);
    86                     acceptNext();
    87                 } catch (IOException e) {
    88                     LOGGER.fatal("failed to accept on port " + accept + ": " + e);
    89                 }
    90                 try {
    91                     java.lang.Thread.sleep(1000);
    92                 } catch (InterruptedException ignored) {
    93                 }
    94                 tryBind(accept);
    95             }
    96         });
    97     }
     71        public void tryBind(final Integer accept) {
     72                acceptThread.invokeLater(new Runnable() {
     73                        @Override
     74                        public void run() {
     75                                try {
     76                                        acceptSocket.bind(new InetSocketAddress(accept));
     77                                        log.debug("started accepting on port " + accept);
     78                                        acceptNext();
     79                                } catch (IOException e) {
     80                                        log.fatal("failed to accept on port " + accept + ": " + e);
     81                                }
     82                                try {
     83                                        java.lang.Thread.sleep(1000);
     84                                } catch (InterruptedException ignored) {
     85                                }
     86                                tryBind(accept);
     87                        }
     88                });
     89        }
    9890
    9991}
  • java/main/src/main/java/com/framsticks/core/Node.java

    r77 r84  
    11package com.framsticks.core;
    22
    3 import com.framsticks.params.types.CompositeParam;
    4 
    5 import java.util.HashMap;
    6 import java.util.Map;
     3import com.framsticks.params.CompositeParam;
    74
    85/**
  • java/main/src/main/java/com/framsticks/core/Path.java

    r77 r84  
    22
    33import com.framsticks.params.AccessInterface;
     4import com.framsticks.params.CompositeParam;
    45import com.framsticks.params.Param;
    5 import com.framsticks.params.types.CompositeParam;
    6 import com.framsticks.util.Dispatching;
    7 import org.apache.log4j.Logger;
    8 
     6import com.framsticks.util.dispatching.Dispatching;
    97import java.util.Iterator;
    108import java.util.LinkedList;
     9import java.util.List;
     10
     11import org.apache.commons.collections.ListUtils;
    1112
    1213/**
     
    1415 */
    1516public class Path {
    16     private final static Logger LOGGER = Logger.getLogger(Path.class.getName());
    17 
    18     final LinkedList<Node> nodes = new LinkedList<Node>();
    19     String textual;
    20     Instance instance;
    21 
    22     protected Object getKnownChild(AccessInterface access, CompositeParam param) {
    23         Object child = access.get(param, Object.class);
    24         if (child == null) {
    25             return null;
    26         }
    27         return (instance.prepareAccess(param) != null) ? child : null;
    28     }
    29 
    30     public Path(Instance instance, String textual) {
    31         assert instance.isActive();
    32         this.instance = instance;
    33         StringBuilder b = new StringBuilder();
    34         nodes.add(instance.root);
    35         Node current = instance.root;
    36         Iterator<String> i = Instance.splitPath(textual);
    37         while (i.hasNext() && current.getObject() != null) {
    38             AccessInterface access = instance.prepareAccess(current.getParam());
    39             if (access == null) {
    40                 break;
    41             }
    42             String e = i.next();
    43             Param p = access.getParam(e);
    44             if (!(p instanceof CompositeParam)) {
    45                 //entries.add(new Entry());
    46                 break;
    47             }
    48             CompositeParam c = (CompositeParam)p;
    49             b.append("/").append(e);
    50             access.select(current.getObject());
    51             current = new Node(c, getKnownChild(access, c));
    52             nodes.add(current);
    53         }
    54         this.textual = (size() == 1) ? "/" : b.toString();
    55     }
    56 
    57     protected Path() {
    58 
    59     }
    60 
    61     public Path appendNode(Node node) {
    62         assert isResolved();
    63         Path result = new Path();
    64         result.textual = textual + ((size() == 1) ? "" : "/") + node.getParam().getId();
    65         result.instance = instance;
    66         result.nodes.addAll(nodes);
    67         result.nodes.add(node);
    68         return result;
    69     }
    70 
    71     public Path appendParam(CompositeParam param) {
    72         assert isResolved();
    73         return appendNode(new Node(param, null));
    74     }
    75 
    76     public Path appendResolution(Object object) {
    77         assert !isResolved();
    78         Path result = new Path();
    79         result.textual = textual;
    80         result.instance = instance;
    81         result.nodes.addAll(nodes);
    82         result.nodes.add(new Node(result.nodes.pollLast().getParam(), object));
    83         return result;
    84     }
    85 
    86     public final Object getTopObject() {
    87         return getTop().getObject();
    88     }
    89 
    90     public final Node getTop() {
    91         return nodes.getLast();
    92     }
    93 
    94     public final Node getUnder() {
    95         assert nodes.size() >= 2;
    96         return nodes.get(nodes.size() - 2);
    97     }
    98 
    99     public final String getTextual() {
    100         return textual;
    101     }
    102 
    103     public String toString() {
    104         return instance + textual + (!isResolved() ? "!" : "");
    105     }
    106 
    107     public final int size() {
    108         assert Dispatching.isThreadSafe();
    109         return nodes.size();
    110     }
    111 
    112     public final boolean isResolved() {
    113         assert Dispatching.isThreadSafe();
    114         return getTop().getObject() != null;
    115     }
    116 
    117     public final boolean isResolved(String textual) {
    118         assert Dispatching.isThreadSafe();
    119         return isTheSame(textual) && isResolved();
    120     }
    121 
    122     public final boolean isTheSame(String textual) {
    123         assert Dispatching.isThreadSafe();
    124         return this.textual.equals(textual);
    125     }
    126 
    127     public final Instance getInstance() {
    128         assert Dispatching.isThreadSafe();
    129         return instance;
    130     }
    131 
    132     public Path findResolution() {
    133         assert instance.isActive();
    134         assert !isResolved();
    135         if (size() == 1) {
     17        // private final static Logger log = Logger.getLogger(Path.class.getName());
     18
     19        final LinkedList<Node> nodes = new LinkedList<Node>();
     20        String textual;
     21        Instance instance;
     22
     23        protected Object getKnownChild(AccessInterface access, CompositeParam param) {
     24                Object child = access.get(param, Object.class);
     25                if (child == null) {
     26                        return null;
     27                }
     28                return (instance.registry.prepareAccess(param) != null) ? child : null;
     29        }
     30
     31        // public Path constructPath(Instance instance, String textual) {
     32        //      assert instance.isActive();
     33
     34        // }
     35
     36        Path(Instance instance, String textual) {
     37                assert instance.isActive();
     38                this.instance = instance;
     39
     40                nodes.add(instance.root);
     41                Node current = instance.root;
     42
     43                StringBuilder b = new StringBuilder();
     44                Iterator<String> i = Instance.splitPath(textual);
     45                while (i.hasNext() && current.getObject() != null) {
     46                        AccessInterface access = instance.registry.prepareAccess(current.getParam());
     47                        if (access == null) {
     48                                break;
     49                        }
     50                        String e = i.next();
     51                        Param p = access.getParam(e);
     52                        if (!(p instanceof CompositeParam)) {
     53                                //entries.add(new Entry());
     54                                break;
     55                        }
     56                        CompositeParam c = (CompositeParam)p;
     57                        b.append("/").append(e);
     58                        access.select(current.getObject());
     59                        current = new Node(c, getKnownChild(access, c));
     60                        nodes.add(current);
     61                }
     62                this.textual = (size() == 1) ? "/" : b.toString();
     63        }
     64
     65        public Path(Instance instance, List<Node> nodes, Node node) {
     66                this.instance = instance;
     67                StringBuilder b = new StringBuilder();
     68                boolean add = false;
     69                for (Node n : nodes) {
     70                        this.nodes.add(n);
     71                        if (add) {
     72                                b.append("/").append(n.getParam().getId());
     73                        }
     74                        add = true;
     75                        if (n == node) {
     76                                break;
     77                        }
     78                }
     79                this.textual = (size() == 1) ? "/" : b.toString();
     80        }
     81
     82        protected Path() {
     83
     84        }
     85
     86        public Path appendNode(Node node) {
     87                assert isResolved();
     88                Path result = new Path();
     89                result.textual = textual + ((size() == 1) ? "" : "/") + node.getParam().getId();
     90                result.instance = instance;
     91                result.nodes.addAll(nodes);
     92                result.nodes.add(node);
     93                return result;
     94        }
     95
     96        public Path appendParam(CompositeParam param) {
     97                assert isResolved();
     98                return appendNode(new Node(param, null));
     99        }
     100
     101        public Path appendResolution(Object object) {
     102                assert !isResolved();
     103                Path result = new Path();
     104                result.textual = textual;
     105                result.instance = instance;
     106                result.nodes.addAll(nodes);
     107                result.nodes.add(new Node(result.nodes.pollLast().getParam(), object));
     108                return result;
     109        }
     110
     111        public final Object getTopObject() {
     112                return getTop().getObject();
     113        }
     114
     115        public final Node getTop() {
     116                return nodes.getLast();
     117        }
     118
     119        public final Node getUnder() {
     120                assert nodes.size() >= 2;
     121                return nodes.get(nodes.size() - 2);
     122        }
     123
     124        public final String getTextual() {
     125                return textual;
     126        }
     127
     128        public String toString() {
     129                return instance + textual + (!isResolved() ? "!" : "");
     130        }
     131
     132        public final int size() {
     133                assert Dispatching.isThreadSafe();
     134                return nodes.size();
     135        }
     136
     137        public final boolean isResolved() {
     138                assert Dispatching.isThreadSafe();
     139                return getTop().getObject() != null;
     140        }
     141
     142        public final boolean isResolved(String textual) {
     143                assert Dispatching.isThreadSafe();
     144                return isTheSame(textual) && isResolved();
     145        }
     146
     147        public final boolean isTheSame(String textual) {
     148                assert Dispatching.isThreadSafe();
     149                return this.textual.equals(textual);
     150        }
     151
     152        public final Instance getInstance() {
     153                assert Dispatching.isThreadSafe();
     154                return instance;
     155        }
     156
     157
     158        /** Attach resolution at end, if available.
     159         *
     160         * @return Modified path, if resolution was available, this otherwise.
     161         */
     162        public Path tryFindResolution() {
     163                assert instance.isActive();
     164                assert !isResolved();
     165                if (size() == 1) {
    136166                        return new Path(instance, "/");//appendResolution(instance.root.object);
    137         }
    138         Object child = getKnownChild(instance.bindAccess(getUnder()), getTop().getParam());
    139         if (child == null) {
    140             return this;
    141         }
    142         return appendResolution(child);
    143     }
    144 
    145     public boolean matches(Path p) {
    146         assert Dispatching.isThreadSafe();
    147         assert instance == p.instance;
    148         Iterator<Node> a = nodes.iterator();
    149         Iterator<Node> b = p.nodes.iterator();
    150         while (a.hasNext() && b.hasNext()) {
    151             Node an = a.next();
    152             Node bn = b.next();
    153             if (an.object != bn.object) {
    154                 return false;
    155             }
    156         }
    157         return a.hasNext() == b.hasNext();
    158     }
    159 
    160     public String getLastElement() {
    161         return getTop().getParam().getId();
    162     }
    163 
    164     public final boolean isOwner(Instance instance) {
    165         return this.instance == instance;
    166     }
     167                }
     168                Object child = getKnownChild(instance.bindAccess(getUnder()), getTop().getParam());
     169                if (child == null) {
     170                        return this;
     171                }
     172                return appendResolution(child);
     173        }
     174
     175        public boolean matches(Path p) {
     176                assert Dispatching.isThreadSafe();
     177                assert instance == p.instance;
     178                Iterator<Node> a = nodes.iterator();
     179                Iterator<Node> b = p.nodes.iterator();
     180                while (a.hasNext() && b.hasNext()) {
     181                        Node an = a.next();
     182                        Node bn = b.next();
     183                        if (an.object != bn.object) {
     184                                return false;
     185                        }
     186                }
     187                return a.hasNext() == b.hasNext();
     188        }
     189
     190        public String getLastElement() {
     191                return getTop().getParam().getId();
     192        }
     193
     194        public final boolean isOwner(Instance instance) {
     195                return this.instance == instance;
     196        }
     197
     198        @SuppressWarnings("unchecked")
     199        public
     200        List<Node> getNodes() {
     201                return ListUtils.unmodifiableList(nodes);
     202        }
    167203}
    168204
  • java/main/src/main/java/com/framsticks/core/Program.java

    r78 r84  
    11package com.framsticks.core;
    22
    3 import com.framsticks.util.Pair;
    4 import com.framsticks.util.Strings;
     3import com.framsticks.util.lang.IterableIterator;
     4import com.framsticks.util.lang.Pair;
     5import com.framsticks.util.lang.Strings;
    56import org.apache.commons.configuration.*;
    67import org.apache.log4j.Logger;
    78import org.apache.log4j.PropertyConfigurator;
    8 //import sun.misc.Signal;
    9 //import sun.misc.SignalHandler;
    109
    1110import java.lang.reflect.Constructor;
     
    1514 * @author Piotr Sniegowski
    1615 */
    17 public class Program extends com.framsticks.util.Thread {
     16public class Program extends com.framsticks.util.dispatching.Thread {
    1817
    19     private final static Logger LOGGER = Logger.getLogger(Program.class.getName());
     18        private final static Logger log = Logger.getLogger(Program.class.getName());
    2019
    21 /*
    22     protected SignalHandler signalHandler = new SignalHandler() {
    23         @Override
    24         public void handle(Signal signal) {
    25             LOGGER.info("caught " + signal);
    26             Runtime.getRuntime().exit(0);
    27         }
    28     };
    29 */
     20        protected Entity entity;
    3021
    31     protected Entity entity;
     22        Configuration config;
    3223
    33     Configuration config;
     24        public Program(String name) {
     25                super(name, java.lang.Thread.currentThread());
     26        }
    3427
     28        public static Entity configureEntity(Configuration config) {
     29                String typeName = config.getString("class");
     30                log.info("configuring instance " + typeName);
     31                try {
     32                        Class<?> type = Class.forName(typeName);
     33                        Constructor<?> constructor = type.getConstructor();
     34                        Entity entity = (Entity) constructor.newInstance();
     35                        return entity;
     36                } catch (Exception e) {
     37                        log.error("failed to instantiate: " + e);
     38                }
     39                return null;
     40        }
    3541
    36     public Program(String name) {
    37         super(name, java.lang.Thread.currentThread());
    38 //        Signal.handle(new Signal("INT"), signalHandler);
    39 //        Signal.handle(new Signal("TERM"), signalHandler);
    40     }
     42        protected static void resolve(Configuration config, String prefix) {
     43                for (String p : new IterableIterator<String>(prefix == null ? config.getKeys() : config.getKeys(prefix))) {
     44                        if (p.endsWith(".mount")) {
     45                                String source = config.getString(p);
     46                                log.info("mounting " + source + " at " + p);
     47                                config.clearProperty(p);
     48                                Configuration mount = config.subset(source);
     49                                for (String mk : new IterableIterator<String>(mount.getKeys())) {
     50                                        config.addProperty(p.substring(0, p.length() - 6) + "." + mk, mount.getProperty(mk));
     51                                }
     52                        }
     53                }
     54        }
    4155
    42     public static Entity configureEntity(Parameters parameters) {
    43         String typeName = parameters.getConfig().getString("class");
    44         LOGGER.info("configuring instance " + typeName);
    45         try {
    46             Class type = Class.forName(typeName);
    47             Constructor constructor = type.getConstructor(Parameters.class);
    48             return (Entity) constructor.newInstance(parameters);
    49         } catch (Exception e) {
    50             LOGGER.error("failed to instantiate: " + e);
    51         }
    52         return null;
    53     }
    54 
    55     protected static void resolve(Configuration config, String prefix) {
    56 
    57         Iterator i = prefix == null ? config.getKeys() : config.getKeys(prefix);
    58         while (i.hasNext()) {
    59             String p = (String) i.next();
    60             if (p.endsWith(".mount")) {
    61                 String source = config.getString(p);
    62                 LOGGER.info("mounting " + source + " at " + p);
    63                 config.clearProperty(p);
    64                 Configuration mount = config.subset(source);
    65                 Iterator mi = mount.getKeys();
    66                 while (mi.hasNext()) {
    67                     String mk = (String) mi.next();
    68                     config.addProperty(p.substring(0, p.length() - 6) + "." + mk, mount.getProperty(mk));
    69                 }
    70             }
    71         }
    72     }
    73 
    74     public void run(String[] args) {
     56        public void run(String[] args) {
    7557
    7658                PropertyConfigurator.configure(getClass().getResource("/configs/log4j.properties"));
    77                 LOGGER.debug("started in " + System.getProperty("user.dir"));
    78         try {
     59                log.debug("started in " + System.getProperty("user.dir"));
     60                try {
    7961                        config = new PropertiesConfiguration(getClass().getResource("/configs/framsticks.properties"));
    8062
    81             for (String a : args) {
    82                 Pair<String, String> p = Strings.splitIntoPair(a, '=', "true");
    83                 config.setProperty(p.first, p.second);
    84             }
     63                        for (String a : args) {
     64                                Pair<String, String> p = Strings.splitIntoPair(a, '=', "true");
     65                                config.setProperty(p.first, p.second);
     66                        }
    8567
    86             resolve(config, null);
     68                        resolve(config, null);
    8769
    88             Iterator i = config.getKeys();
    89             while (i.hasNext()) {
    90                 String p = (String) i.next();
    91                 LOGGER.debug(p + " = " + config.getProperty(p));
    92             }
     70                        Iterator<?> i = config.getKeys();
     71                        while (i.hasNext()) {
     72                                String p = (String) i.next();
     73                                log.debug(p + " = " + config.getProperty(p));
     74                        }
    9375
    94         } catch (ConfigurationException e) {
    95             System.err.print("failed to parse configuration:" + e);
    96             return;
    97         }
     76                } catch (ConfigurationException e) {
     77                        System.err.print("failed to parse configuration:" + e);
     78                        return;
     79                }
     80                Configuration entityConfig = config.subset("com.framsticks.entity");
    9881
    99         entity = configureEntity(new Parameters(config.subset("com.framsticks.entity"), "main", null, new EntityOwner() {
     82                entity = configureEntity(entityConfig);
     83                entity.setOwner(new EntityOwner() {
    10084                        @Override
    10185                        public void onDone() {
    102                                 LOGGER.info("exiting");
     86                                log.info("exiting");
    10387                                Runtime.getRuntime().exit(0);
    10488                        }
    105                 }));
     89                });
     90                entity.setName("main");
    10691                try {
    107                 entity.configurePublic();
     92                        entity.configure(entityConfig);
    10893                } catch (Exception e) {
    109                         LOGGER.fatal("exception caught during configuration: " + e);
     94                        log.fatal("exception caught during configuration: " + e);
    11095                }
    111         LOGGER.info("all entities were configured");
    112         entity.start();
    113     }
     96                log.info("all entities were configured");
     97                entity.start();
     98        }
    11499
    115     public static void main(final String[] args) {
    116         final Program program = new Program("program");
    117         program.invokeLater(new Runnable() {
    118             @Override
    119             public void run() {
    120                 program.run(args);
    121             }
    122         });
    123         program.routine();
    124     }
     100        public static void main(final String[] args) {
     101
     102                final Program program = new Program("program");
     103                program.invokeLater(new Runnable() {
     104                        @Override
     105                        public void run() {
     106                                program.run(args);
     107                        }
     108                });
     109                program.routine();
     110        }
    125111
    126112}
  • java/main/src/main/java/com/framsticks/diagnostics/Diagnostics.java

    r78 r84  
    11package com.framsticks.diagnostics;
    22
    3 import com.framsticks.core.Parameters;
     3import org.apache.commons.configuration.Configuration;
     4
    45import com.framsticks.observers.Endpoint;
    56import com.framsticks.observers.Observer;
     
    1011public class Diagnostics extends Observer {
    1112
    12     final Integer dumpsInterval;
    13     final String dumpsPath;
    14     final String dumpsFormat;
     13        Integer dumpsInterval;
     14        String dumpsPath;
     15        String dumpsFormat;
    1516
    1617
    17     public Diagnostics(Parameters parameters) {
    18         super(parameters);
    19         dumpsInterval = config.getInteger("dumps.interval", null);
    20         dumpsPath = config.getString("dumps.path", null);
    21         dumpsFormat = config.getString("dumps.format", null);
    22     }
     18        public Diagnostics() {
     19        }
    2320
    24     @Override
    25     protected void configure() throws Exception {
    26 
    27         super.configure();
    28     }
     21        @Override
     22        public void configure(Configuration config) {
     23                super.configure(config);
     24                dumpsInterval = config.getInteger("dumps.interval", null);
     25                dumpsPath = config.getString("dumps.path", null);
     26                dumpsFormat = config.getString("dumps.format", null);
     27        }
    2928
    3029
    31     @Override
    32     protected Endpoint createEndpoint() {
    33         return new DiagnosticsEndpoint();
    34     }
     30        @Override
     31        protected Endpoint createEndpoint() {
     32                return new DiagnosticsEndpoint();
     33        }
    3534
    3635
  • java/main/src/main/java/com/framsticks/diagnostics/DiagnosticsEndpoint.java

    r77 r84  
    11package com.framsticks.diagnostics;
    22
    3 import com.framsticks.core.Path;
     3import com.framsticks.dumping.PrintWriterSink;
    44import com.framsticks.dumping.SaveStream;
    55import com.framsticks.observers.Endpoint;
    6 import com.framsticks.dumping.PrintStreamSink;
    76import com.framsticks.remote.RecursiveFetcher;
    87import com.framsticks.util.Logging;
     
    1312import java.io.File;
    1413import java.io.IOException;
    15 import java.io.PrintStream;
     14import java.io.PrintWriter;
    1615import java.text.SimpleDateFormat;
    1716import java.util.Date;
     
    2221public class DiagnosticsEndpoint extends Endpoint {
    2322
    24     private final static Logger LOGGER = Logger.getLogger(DiagnosticsEndpoint.class.getName());
     23        private final static Logger log = Logger.getLogger(DiagnosticsEndpoint.class.getName());
    2524
    2625
    27     public DiagnosticsEndpoint() {
    28         super();
    29     }
     26        public DiagnosticsEndpoint() {
     27                super();
     28        }
    3029
    31     @Override
    32     public Diagnostics getObserver() {
    33         return (Diagnostics)observer;
    34     }
     30        @Override
     31        public Diagnostics getObserver() {
     32                return (Diagnostics)observer;
     33        }
    3534
    3635
    37     @Override
    38     protected void configure() {
    39         super.configure();
     36        @Override
     37        public void start() {
     38                super.start();
    4039
    41         if (getObserver().dumpsInterval != null) {
    42             new PeriodicTask(instance, getObserver().dumpsInterval * 1000) {
    43                 @Override
    44                 public void run() {
     40                if (getObserver().dumpsInterval != null) {
     41                        new PeriodicTask(instance, getObserver().dumpsInterval * 1000) {
     42                                @Override
     43                                public void run() {
    4544
    46                     LOGGER.info("starting periodic dump");
    47                     new RecursiveFetcher(instance, new Path(instance, "/"), new StateFunctor() {
    48                         @Override
    49                         public void call(Exception e) {
    50                             if (Logging.log(LOGGER, "recursively fetch", instance, e)) {
    51                                 again();
    52                                 return;
    53                             }
    54                             LOGGER.info("instance resolved, saving");
    55                             try {
    56                                 final String fileName = getObserver().dumpsPath + "/" + instance + "_" + new SimpleDateFormat(getObserver().dumpsFormat).format(new Date()) + ".param";
    57                                 File file = new File(fileName);
    58                                 new SaveStream(new PrintStreamSink(new PrintStream(file)), instance, new Path(instance, "/"), new StateFunctor() {
    59                                     @Override
    60                                     public void call(Exception e) {
    61                                         Logging.log(LOGGER, "periodic dump in " + fileName + " of", DiagnosticsEndpoint.this.instance, e);
    62                                         again();
    63                                     }
    64                                 });
    65                             } catch (IOException ex) {
    66                                 LOGGER.info("failed to initiate dump: " + ex);
    67                                 again();
    68                             }
     45                                        log.info("starting periodic dump");
     46                                        new RecursiveFetcher(instance, instance.getRootPath(), new StateFunctor() {
     47                                                @Override
     48                                                public void call(Exception e) {
     49                                                        if (Logging.log(log, "recursively fetch", instance, e)) {
     50                                                                again();
     51                                                                return;
     52                                                        }
     53                                                        log.info("instance resolved, saving");
     54                                                        try {
     55                                                                final String fileName = getObserver().dumpsPath + "/" + instance + "_" + new SimpleDateFormat(getObserver().dumpsFormat).format(new Date()) + ".param";
     56                                                                File file = new File(fileName);
     57                                                                new SaveStream(new PrintWriterSink(new PrintWriter(file)), instance, instance.getRootPath(), new StateFunctor() {
     58                                                                        @Override
     59                                                                        public void call(Exception e) {
     60                                                                                Logging.log(log, "periodic dump in " + fileName + " of", DiagnosticsEndpoint.this.instance, e);
     61                                                                                again();
     62                                                                        }
     63                                                                });
     64                                                        } catch (IOException ex) {
     65                                                                log.info("failed to initiate dump: " + ex);
     66                                                                again();
     67                                                        }
    6968
    70                         }
    71                     });
     69                                                }
     70                                        });
    7271
    7372
    74                 }
    75             };
    76         }
    77     }
     73                                }
     74                        };
     75                }
     76        }
    7877
    79     /*
    80     @Override
    81     public void onChange(Path path) {
    82         super.onChange(path);    //To change body of overridden methods use File | Settings | File Templates.
    83     }
    84     */
     78        /*
     79        @Override
     80        public void onChange(Path path) {
     81                super.onChange(path);    //To change body of overridden methods use File | Settings | File Templates.
     82        }
     83        */
    8584}
  • java/main/src/main/java/com/framsticks/dumping/FileInstance.java

    r78 r84  
    22
    33import com.framsticks.core.LocalInstance;
    4 import com.framsticks.core.Parameters;
    54import com.framsticks.core.Path;
    6 import com.framsticks.params.FramsClass;
    75import com.framsticks.core.Instance;
    8 import com.framsticks.util.*;
    9 import com.framsticks.util.UnsupportedOperationException;
     6import com.framsticks.util.dispatching.Future;
     7
     8import org.apache.commons.configuration.Configuration;
    109import org.apache.log4j.Logger;
    1110
     
    2019public class FileInstance extends LocalInstance {
    2120
    22     private static final Logger LOGGER = Logger.getLogger(Instance.class.getName());
    23     protected final File file;
     21        private static final Logger log = Logger.getLogger(Instance.class.getName());
     22        protected File file;
    2423
    25     public FileInstance(Parameters parameters) {
    26         super(parameters);
    27         file = new File(config.getString("filename"));
    28     }
     24        public FileInstance() {
     25        }
    2926
    30     @Override
    31     public void run() {
    32         assert isActive();
    33         super.run();
    34         try {
    35             FileReader fileReader = new FileReader(file);
    36             LoadStream stream = new LoadStream(new Path(this, "/"), new BufferedReader(fileReader), this, new Future<Path>() {
    37                 @Override
    38                 public void result(Path result, Exception e) {
    39                     if (e != null) {
    40                         LOGGER.error("failed to load file instance " + FileInstance.this + ": " + e);
    41                         fireRun(e);
    42                         return;
    43                     }
    44                     LOGGER.info("loaded file instance " + FileInstance.this);
    45                     fireRun(null);
    46                 }
    47             });
    48             stream.load();
    49         } catch (IOException e) {
    50             LOGGER.error("io failure: " + e);
    51             fireRun(e);
    52         }
    53     }
     27        @Override
     28        public void configure(Configuration config) {
     29                super.configure(config);
     30                file = new File(config.getString("filename"));
     31        }
    5432
    55     @Override
    56     public String toString() {
    57         return "file@" + file.getName();
    58     }
     33        @Override
     34        public void run() {
     35                assert isActive();
     36                super.run();
     37                try {
     38                        FileReader fileReader = new FileReader(file);
     39                        LoadStream stream = new LoadStream(this.getRootPath(), new BufferedReader(fileReader), this, new Future<Path>() {
     40                                @Override
     41                                public void result(Path result, Exception e) {
     42                                        if (e != null) {
     43                                                log.error("failed to load file instance " + FileInstance.this + ": " + e);
     44                                                fireRun(e);
     45                                                return;
     46                                        }
     47                                        log.info("loaded file instance " + FileInstance.this);
     48                                        fireRun(null);
     49                                }
     50                        });
     51                        stream.load();
     52                } catch (IOException e) {
     53                        log.error("io failure: " + e);
     54                        fireRun(e);
     55                }
     56        }
     57
     58        @Override
     59        public String toString() {
     60                return "file@" + file.getName();
     61        }
    5962
    6063
  • java/main/src/main/java/com/framsticks/dumping/LoadStream.java

    r77 r84  
    66import com.framsticks.core.Instance;
    77import com.framsticks.util.*;
     8import com.framsticks.util.dispatching.Future;
     9import com.framsticks.util.lang.Pair;
     10import com.framsticks.util.lang.Strings;
    811import org.apache.log4j.Logger;
    912
     
    1821public class LoadStream {
    1922
    20     private final static Logger LOGGER = Logger.getLogger(LoadStream.class.getName());
     23        private final static Logger log = Logger.getLogger(LoadStream.class.getName());
    2124
    22     protected final Instance instance;
    23     protected final Path mountPath;
    24     protected final BufferedReader stream;
    25     protected final Future<Path> future;
    26     protected final Stopwatch stopwatch = new Stopwatch();
     25        protected final Instance instance;
     26        protected final Path mountPath;
     27        protected final BufferedReader stream;
     28        protected final Future<Path> future;
     29        protected final Stopwatch stopwatch = new Stopwatch();
    2730
    2831
    29     public LoadStream(Path mountPath, BufferedReader stream, Instance instance, Future<Path> future) {
    30         this.instance = instance;
    31         this.mountPath = mountPath;
    32         this.stream = stream;
    33         this.future = future;
    34     }
     32        public LoadStream(Path mountPath, BufferedReader stream, Instance instance, Future<Path> future) {
     33                this.instance = instance;
     34                this.mountPath = mountPath;
     35                this.stream = stream;
     36                this.future = future;
     37        }
    3538
    36     public void load() {
    37         try {
    38             String line;
    39             Pair<String, String> query = null;
    40             List<File> files = null;
    41             List<String> content = null;
    42             //File file;
    43             while ((line = stream.readLine()) != null) {
    44                 if (query == null) {
    45                     query = Strings.splitIntoPair(line, ' ', "\n");
    46                     files = new LinkedList<File>();
    47                     LOGGER.trace("loading " + line);
    48                     continue;
    49                 }
    50                 if (content == null) {
    51                     if (line.equals("file")) {
    52                         content = new LinkedList<String>();
    53                         continue;
    54                     }
    55                     if (line.equals("ok")) {
    56                         if (query.first.equals("get")) {
    57                             Path path = instance.createIfNeeded(query.second);
    58                             instance.processFetchedValues(path, files);
    59                         } else if (query.first.equals("info")) {
    60                             assert files.size() == 1;
    61                             instance.processFetchedInfo(files.get(0));
    62                         } else {
    63                             assert false;
    64                         }
    65                         query = null;
    66                         files = null;
    67                         continue;
    68                     }
    69                     assert false;
    70                     continue;
    71                 }
    72                 if (line.equals("eof")) {
    73                     files.add(new File(query.second, new ListSource(content)));
    74                     content = null;
    75                     continue;
    76                 }
    77                 content.add(line);
    78             }
    79         } catch (IOException e) {
    80             LOGGER.error("failed to load: " + e);
    81             future.result(null, e);
    82             return;
    83         }
    84         LOGGER.info("loaded in: " + stopwatch);
    85         future.result(new Path(instance, mountPath.getTextual()), null);
    86     }
     39        public void load() {
     40                try {
     41                        String line;
     42                        Pair<String, String> query = null;
     43                        List<File> files = null;
     44                        List<String> content = null;
     45                        //File file;
     46                        while ((line = stream.readLine()) != null) {
     47                                if (query == null) {
     48                                        query = Strings.splitIntoPair(line, ' ', "\n");
     49                                        files = new LinkedList<File>();
     50                                        log.trace("loading " + line);
     51                                        continue;
     52                                }
     53                                if (content == null) {
     54                                        if (line.equals("file")) {
     55                                                content = new LinkedList<String>();
     56                                                continue;
     57                                        }
     58                                        if (line.equals("ok")) {
     59                                                if (query.first.equals("get")) {
     60                                                        Path path = instance.createIfNeeded(query.second);
     61                                                        instance.processFetchedValues(path, files);
     62                                                } else if (query.first.equals("info")) {
     63                                                        assert files.size() == 1;
     64                                                        instance.processFetchedInfo(files.get(0));
     65                                                } else {
     66                                                        assert false;
     67                                                }
     68                                                query = null;
     69                                                files = null;
     70                                                continue;
     71                                        }
     72                                        assert false;
     73                                        continue;
     74                                }
     75                                if (line.equals("eof")) {
     76                                        files.add(new File(query.second, new ListSource(content)));
     77                                        content = null;
     78                                        continue;
     79                                }
     80                                content.add(line);
     81                        }
     82                } catch (IOException e) {
     83                        log.error("failed to load: " + e);
     84                        future.result(null, e);
     85                        return;
     86                }
     87                log.info("loaded in: " + stopwatch);
     88                future.result(instance.getPath(mountPath.getTextual()), null);
     89        }
    8790
    8891
  • java/main/src/main/java/com/framsticks/dumping/SaveStream.java

    r78 r84  
    44import com.framsticks.core.Path;
    55import com.framsticks.params.AccessInterface;
     6import com.framsticks.params.CompositeParam;
    67import com.framsticks.params.FramsClass;
    78import com.framsticks.params.ListAccess;
    8 import com.framsticks.params.Param;
    9 import com.framsticks.params.types.CompositeParam;
    109import com.framsticks.params.SinkInterface;
    1110import com.framsticks.parsers.Savers;
    1211import com.framsticks.core.Instance;
    1312import com.framsticks.util.*;
     13import com.framsticks.util.dispatching.Dispatching;
    1414import org.apache.log4j.Logger;
    1515
    1616import java.util.HashSet;
    1717import java.util.Set;
     18import static com.framsticks.util.lang.Containers.filterInstanceof;
    1819
    1920/**
     
    2223public class SaveStream {
    2324
    24     private final static Logger LOGGER = Logger.getLogger(SaveStream.class.getName());
     25        private final static Logger log = Logger.getLogger(SaveStream.class.getName());
    2526
    26     protected final SinkInterface sink;
    27     protected final Instance instance;
    28     protected final StateFunctor stateFunctor;
    29     protected final Stopwatch stopwatch = new Stopwatch();
    30     protected final Set<FramsClass> storedInfo = new HashSet<FramsClass>();
     27        protected final SinkInterface sink;
     28        protected final Instance instance;
     29        protected final StateFunctor stateFunctor;
     30        protected final Stopwatch stopwatch = new Stopwatch();
     31        protected final Set<FramsClass> storedInfo = new HashSet<FramsClass>();
    3132
    32     private int dispatched = 0;
     33        private int dispatched = 0;
    3334
    34     public SaveStream(SinkInterface sink, Instance instance, Path root, StateFunctor stateFunctor) {
    35         assert Dispatching.isThreadSafe();
    36         this.sink = sink;
    37         this.instance = instance;
    38         this.stateFunctor = stateFunctor;
     35        public SaveStream(SinkInterface sink, Instance instance, Path root, StateFunctor stateFunctor) {
     36                assert Dispatching.isThreadSafe();
     37                this.sink = sink;
     38                this.instance = instance;
     39                this.stateFunctor = stateFunctor;
    3940                dispatchWrite(root);
    40     }
     41        }
    4142
    4243        protected void dispatchWrite(final Path path) {
     
    5051        }
    5152
    52     protected void finished() {
    53         assert instance.isActive();
    54         LOGGER.info("stored in " + stopwatch);
    55         stateFunctor.call(null);
    56     }
     53        protected void finished() {
     54                assert instance.isActive();
     55                log.info("stored in " + stopwatch);
     56                stateFunctor.call(null);
     57        }
    5758
    58     public void write(final Path path) {
    59         assert instance.isActive();
    60         if (!path.isResolved()) {
    61             LOGGER.debug("path " + path + " is not resolved - skipping");
    62         } else {
    63             AccessInterface access = instance.bindAccess(path);
     59        public void write(final Path path) {
     60                assert instance.isActive();
     61                if (!path.isResolved()) {
     62                        log.debug("path " + path + " is not resolved - skipping");
     63                } else {
     64                        AccessInterface access = instance.bindAccess(path);
    6465                        assert access != null;
    65             FramsClass framsClass = access.getFramsClass();
    66             assert framsClass != null;
    67             if (!storedInfo.contains(framsClass)) {
    68                 storedInfo.add(framsClass);
    69                 sink.print("info ").print(path.getTextual()).breakLine();
    70                 sink.print("file").breakLine();
    71                 Savers.saveFramsClass(sink, framsClass);
    72                 sink.print("eof").breakLine();
    73                 sink.print("ok").breakLine();
    74             }
    75             if (!(access instanceof ListAccess)) {
    76                 sink.print("get ").print(path.getTextual()).breakLine();
    77                 sink.print("file").breakLine();
    78                 //stream.print("#" + access.getSelected().getClass().getCanonicalName() + "\n");
    79                 access.save(sink);
    80                 sink.print("eof").breakLine();
    81                 sink.print("ok").breakLine();
    82             }
    83             for (Param p : access.getParams()) {
    84                 if (p instanceof CompositeParam) {
    85                     CompositeParam childParam = (CompositeParam)p;
    86                     final Path childPath = path.appendNode(new Node(childParam, access.get(childParam, Object.class)));
    87                     if (childPath.isResolved() && instance.getInfoFromCache(childPath) != null) {
    88                                                 dispatchWrite(childPath);
    89                     }
    90                 }
    91             }
    92         }
    93         --dispatched;
    94         if (dispatched == 0) {
    95             finished();
    96         }
    97     }
     66                        FramsClass framsClass = access.getFramsClass();
     67                        assert framsClass != null;
     68                        if (!storedInfo.contains(framsClass)) {
     69                                storedInfo.add(framsClass);
     70                                sink.print("info ").print(path.getTextual()).breakLine();
     71                                sink.print("file").breakLine();
     72                                Savers.saveFramsClass(sink, framsClass);
     73                                sink.print("eof").breakLine();
     74                                sink.print("ok").breakLine();
     75                        }
     76                        if (!(access instanceof ListAccess)) {
     77                                sink.print("get ").print(path.getTextual()).breakLine();
     78                                sink.print("file").breakLine();
     79                                //stream.print("#" + access.getSelected().getClass().getCanonicalName() + "\n");
     80                                access.save(sink);
     81                                sink.print("eof").breakLine();
     82                                sink.print("ok").breakLine();
     83                        }
     84                        for (CompositeParam p : filterInstanceof(access.getParams(), CompositeParam.class)) {
     85                                final Path childPath = path.appendNode(new Node(p, access.get(p, Object.class)));
     86                                if (childPath.isResolved() && instance.getInfoFromCache(childPath) != null) {
     87                                        dispatchWrite(childPath);
     88                                }
     89                        }
     90                }
     91                --dispatched;
     92                if (dispatched == 0) {
     93                        finished();
     94                }
     95        }
    9896}
  • java/main/src/main/java/com/framsticks/examples/GenotypeBrowser.java

    r79 r84  
    33import com.framsticks.core.Instance;
    44import com.framsticks.core.Node;
    5 import com.framsticks.core.Parameters;
    6 import com.framsticks.core.Path;
     5import com.framsticks.dumping.PrintWriterSink;
    76import com.framsticks.model.*;
    87import com.framsticks.model.Package;
    98import com.framsticks.params.*;
    10 import com.framsticks.params.types.CompositeParam;
    119import com.framsticks.parsers.F0Parser;
     10import com.framsticks.parsers.F0Writer;
    1211import com.framsticks.parsers.Schema;
     12
     13import org.apache.commons.configuration.Configuration;
    1314import org.apache.log4j.Logger;
    1415
     16import java.io.PrintWriter;
     17import java.io.StringWriter;
    1518import java.util.List;
    1619
     
    2023public class GenotypeBrowser extends Instance {
    2124
    22         private static final Logger LOGGER = Logger.getLogger(Instance.class.getName());
     25        private static final Logger log = Logger
     26                        .getLogger(Instance.class.getName());
    2327        protected Schema schema;
    2428
    25 
    26         public GenotypeBrowser(Parameters parameters) {
    27                 super(parameters);
    28                 LOGGER.info("model builder created");
     29        public GenotypeBrowser() {
     30                log.info("model builder created");
    2931        }
    3032
    3133        @Override
    32         protected void configure() throws Exception {
    33                 super.configure();
    34                 schema = new Schema(Schema.getDefaultDefinitionAsStream());
     34        public void configure(Configuration config) {
     35                super.configure(config);
     36                try {
     37                        schema = new Schema(Schema.getDefaultDefinitionAsStream());
     38                } catch (Exception e) {
     39                        log.error("failed to load schema: " + e);
     40                }
    3541                this.registry = schema.getRegistry();
    3642                Package.register(this.getRegistry());
     
    3844                registry.putInfoIntoCache(new FramsClass("ModelBuilderRoot", "ModelBuilderRoot", null)
    3945                                .append(new ParamBuilder().setType("o Model").setId("model").setName("model").build())
     46                                .append(new ParamBuilder().setType("s 1").setId("genotype").setName("genotype").build())
    4047                );
    4148                root = new Node((CompositeParam)new ParamBuilder().setType("o ModelBuilderRoot").setId(name).setName("Instance").build(), PropertiesAccess.createPropertiesMap());
     
    5158                        Model model = Model.build(objects);
    5259
    53                         AccessInterface rootAccess = bindAccess(new Path(this, "/"));
     60                        AccessInterface rootAccess = bindAccess(this.getRootPath());
    5461
    5562                        rootAccess.set("model", model);
    5663
     64                        StringWriter w = new StringWriter();
     65                        new F0Writer(schema, model, new PrintWriterSink(new PrintWriter(w))).write();
     66                        rootAccess.set("genotype", w.getBuffer().toString());
     67
    5768                } catch (Exception e) {
    58                         LOGGER.error("exception caught: " + e);
     69                        log.error("exception caught: " + e);
    5970                }
    6071                //done();
  • java/main/src/main/java/com/framsticks/gui/Browser.java

    r78 r84  
    44import com.framsticks.observers.Endpoint;
    55import com.framsticks.observers.Observer;
    6 import com.framsticks.util.Dispatcher;
     6import com.framsticks.util.Logging;
     7import com.framsticks.util.dispatching.Dispatcher;
     8import com.framsticks.util.dispatching.Future;
     9
     10import org.apache.commons.configuration.Configuration;
     11import org.apache.commons.lang.ArrayUtils;
    712import org.apache.log4j.Logger;
    813
    914import javax.swing.*;
     15
     16import java.awt.Dimension;
     17import java.util.ArrayList;
    1018import java.util.HashSet;
     19import java.util.List;
    1120import java.util.Set;
    1221
     
    1625public class Browser extends Observer implements Dispatcher {
    1726
    18     private static final Logger LOGGER = Logger.getLogger(Browser.class.getName());
    19 
    20     protected final Set<Frame> frames = new HashSet<Frame>();
    21     protected MainFrame mainFrame;
    22 
    23     public void addFrame(Frame frame) {
    24         frames.add(frame);
    25     }
    26 
    27         public Browser(Parameters parameters) {
    28         super(parameters);
    29         dispatcher = SwingDispatcher.instance;
    30         invokeLater(new Runnable() {
    31             @Override
    32             public void run() {
    33                 assert isActive();
    34 
    35             }
    36         });
     27        private static final Logger log = Logger.getLogger(Browser.class.getName());
     28
     29        protected final Set<Frame> frames = new HashSet<Frame>();
     30        protected MainFrame mainFrame;
     31        public List<PanelProvider> panelProviders = new ArrayList<PanelProvider>();
     32        protected Dimension defaultFrameDimension;
     33
     34        public void addFrame(Frame frame) {
     35                frames.add(frame);
     36        }
     37
     38        public Browser() {
     39                JPopupMenu.setDefaultLightWeightPopupEnabled(false);
     40                addPanelProvider(new StandardPanelProvider());
     41        }
     42
     43        @Override
     44        public void configure(Configuration config) {
     45                super.configure(config);
     46
     47                defaultFrameDimension = new Dimension(config.getInteger("size.width", 1000), config.getInteger("size.height", 500));
     48
     49                for (String name : config.getStringArray("panel_providers")) {
     50                        try {
     51                                Class<?> c = Class.forName(name);
     52                                if (ArrayUtils.indexOf(c.getInterfaces(), PanelProvider.class) == -1) {
     53                                        continue;
     54                                }
     55                                PanelProvider p = (PanelProvider)c.newInstance();
     56                                addPanelProvider(p);
     57                        } catch (Exception e) {
     58                                log.error("failed to load PanelProvider " + name + ": " + e);
     59                        }
     60                }
     61
     62                // for (final String path : config.getStringArray("resolve_paths")) {
     63                //      invokeLater()
     64                //      autoResolvePath(path, new Future<Path>() {
     65                //              @Override
     66                //              public void result(Path p, Exception e) {
     67                //                      Logging.log(log, "auto resolve path", path, e);
     68                //              }
     69                //      });
     70                // }
     71        }
     72
     73        public void addPanelProvider(PanelProvider panelProvider) {
     74                log.debug("added panel provider of type: " + panelProvider.getClass().getCanonicalName());
     75                panelProviders.add(panelProvider);
     76        }
     77
     78        public void autoResolvePath(final String path, final Future<Path> future) {
     79                final Instance i = endpoints.get("localhost").getInstance();
     80                i.invokeLater(new Runnable() {
     81                        @Override
     82                        public void run() {
     83                                i.resolveAndFetch(path, new Future<Path>() {
     84                                        @Override
     85                                        public void result(final Path p, Exception e) {
     86                                                Logging.log(log, "auto resolve path", path, e);
     87                                                if (future != null) {
     88                                                        future.result(p, e);
     89                                                }
     90                                                if (e == null) {
     91                                                        mainFrame.invokeLater(new Runnable() {
     92                                                                @Override
     93                                                                public void run() {
     94                                                                        mainFrame.goTo(p);
     95                                                                }
     96                                                        });
     97                                                }
     98                                        }
     99                                });
     100                        }
     101                });
    37102        }
    38103
    39104        public void clear() {
    40         assert isActive();
    41         for (Frame f : frames) {
    42             f.clear();
    43         }
    44         }
    45 
    46     @Override
    47     protected void configure() throws Exception {
    48         super.configure();
    49     }
    50 
    51 
    52     @Override
    53     public void run() {
    54         super.run();
    55 
    56         try {
    57             UIManager.setLookAndFeel("com.sun.java.swing.plaf.gtk.GTKLookAndFeel");
    58         } catch (Exception ex) {
    59             LOGGER.warn("failed loading Look&Feel: ", ex);
    60         }
    61         javax.swing.JFrame.setDefaultLookAndFeelDecorated(true);
    62 
    63         mainFrame = new MainFrame(Browser.this);
    64         addFrame(mainFrame);
    65 
    66         for (Frame f : frames) {
    67             f.configure();
    68         }
    69 
    70         for (final Endpoint e : getEndpoints().values()) {
    71             e.invokeLater(new Runnable() {
    72                 @Override
    73                 public void run() {
    74                     final Path p = new Path(e.getInstance(), "/");
    75                     invokeLater(new Runnable() {
    76                         @Override
    77                         public void run() {
    78                             mainFrame.addRootPath((BrowserEndpoint) e, p);
    79                         }
    80                     });
    81                 }
    82             });
    83 
    84         }
    85 
    86         for (Frame f : frames) {
    87             f.setVisible(true);
    88         }
    89     }
    90 
    91     public void createTreeNodeForChild(final Path path) {
    92         assert !isActive();
    93         //assert instance.isActive();
     105                assert isActive();
     106                for (Frame f : frames) {
     107                        f.clear();
     108                }
     109        }
     110
     111        @Override
     112        public void run() {
     113                super.run();
     114
     115                assert isActive();
     116
     117                try {
     118                        boolean found = false;
     119                        // for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
     120                        //      log.info("look and feel available: " + info.getName());
     121                        //      if ("Nimbus".equals(info.getName())) {
     122                        //              UIManager.setLookAndFeel(info.getClassName());
     123                        //              found = true;
     124                        //              break;
     125                        //      }
     126                        // }
     127                        if (!found) {
     128                                UIManager.setLookAndFeel("com.sun.java.swing.plaf.gtk.GTKLookAndFeel");
     129                        }
     130                } catch (Exception ex) {
     131                        log.warn("failed loading Look&Feel: ", ex);
     132                }
     133
     134                javax.swing.JFrame.setDefaultLookAndFeelDecorated(true);
     135
     136                mainFrame = new MainFrame(Browser.this);
     137                addFrame(mainFrame);
     138
     139                for (Frame f : frames) {
     140                        f.configure();
     141                }
     142
     143                for (final Endpoint e : getEndpoints().values()) {
     144                        e.invokeLater(new Runnable() {
     145                                @Override
     146                                public void run() {
     147                                        final Path p = e.getInstance().getRootPath();
     148                                        invokeLater(new Runnable() {
     149                                                @Override
     150                                                public void run() {
     151                                                        mainFrame.addRootPath((BrowserEndpoint) e, p);
     152                                                }
     153                                        });
     154                                }
     155                        });
     156                }
     157
     158                for (Frame f : frames) {
     159                        f.setVisible(true);
     160                }
     161
     162                // autoResolvePath("/simulator/genepools/groups/0", null);
     163                // autoResolvePath("/", null);
     164        }
     165
     166        public void createTreeNodeForChild(final Path path) {
     167                assert !isActive();
     168                //assert instance.isActive();
    94169
    95170
    96171/*
    97         final TreeNode parentTreeNode = (TreeNode) child.getParent().getUserObject();
    98         if (parentTreeNode == null) {
    99             Dispatching.invokeDispatch(this, manager, new Runnable() {
    100                 @Override
    101                 public void run() {
    102                     createTreeNodeForChild(child);
    103                 }
    104             });
    105             return;
    106         }
    107         LOGGER.debug(child.getClass().getSimpleName() + " created: " + child);
    108 
    109 
    110         invokeLater(new Runnable() {
    111             @Override
    112             public void run() {
    113                 parentTreeNode.getOrCreateChildTreeNodeFor(child);
    114             }
    115         });
     172                final TreeNode parentTreeNode = (TreeNode) child.getParent().getUserObject();
     173                if (parentTreeNode == null) {
     174                        Dispatching.invokeDispatch(this, manager, new Runnable() {
     175                                @Override
     176                                public void run() {
     177                                        createTreeNodeForChild(child);
     178                                }
     179                        });
     180                        return;
     181                }
     182                log.debug(child.getClass().getSimpleName() + " created: " + child);
     183
     184
     185                invokeLater(new Runnable() {
     186                        @Override
     187                        public void run() {
     188                                parentTreeNode.getOrCreateChildTreeNodeFor(child);
     189                        }
     190                });
    116191*/
    117192        }
    118193
    119194
    120     @Override
    121     protected Endpoint createEndpoint() {
    122         return new BrowserEndpoint();
    123     }
     195        @Override
     196        protected Endpoint createEndpoint() {
     197                return new BrowserEndpoint();
     198        }
     199
     200        @Override
     201        public Dispatcher createDefaultDispatcher() {
     202                return SwingDispatcher.instance;
     203        }
     204
     205        /**
     206         * @return the mainFrame
     207         */
     208        public MainFrame getMainFrame() {
     209                return mainFrame;
     210        }
    124211
    125212}
  • java/main/src/main/java/com/framsticks/gui/BrowserEndpoint.java

    r77 r84  
    99
    1010    public BrowserEndpoint() {
     11       
    1112    }
    1213
  • java/main/src/main/java/com/framsticks/gui/EndpointAtFrame.java

    r77 r84  
    11package com.framsticks.gui;
    22
    3 import java.util.HashMap;
    4 import java.util.Map;
     3import org.apache.log4j.Logger;
     4
     5import com.framsticks.core.Instance;
     6import com.framsticks.core.InstanceListener;
     7import com.framsticks.core.ListChange;
     8import com.framsticks.core.Node;
     9import com.framsticks.core.Path;
     10import com.framsticks.params.CompositeParam;
     11import com.framsticks.params.FramsClass;
     12
     13import java.util.*;
     14
     15import javax.swing.tree.TreePath;
    516
    617/**
    718 * @author Piotr Sniegowski
    819 */
    9 public class EndpointAtFrame {
    10     protected final BrowserEndpoint endpoint;
    11     protected final Frame frame;
    12     protected final Map<String, Panel> knownPanels = new HashMap<String, Panel>();
     20public class EndpointAtFrame implements InstanceListener {
    1321
    14     public EndpointAtFrame(BrowserEndpoint endpoint, Frame frame) {
    15         this.endpoint = endpoint;
    16         this.frame = frame;
    17     }
     22        private static final Logger log = Logger.getLogger(EndpointAtFrame.class);
    1823
     24        protected final BrowserEndpoint endpoint;
     25        protected final Frame frame;
     26        protected final Instance instance;
     27        protected final Map<String, Panel> knownPanels = new HashMap<String, Panel>();
     28        protected TreeNode rootTreeNode;
    1929
    20     public BrowserEndpoint getEndpoint() {
    21         return endpoint;
    22     }
     30        public EndpointAtFrame(BrowserEndpoint endpoint, Frame frame) {
     31                this.endpoint = endpoint;
     32                this.frame = frame;
     33                this.instance = endpoint.getInstance();
     34        }
    2335
    24     public Frame getFrame() {
    25         return frame;
    26     }
     36        public BrowserEndpoint getEndpoint() {
     37                return endpoint;
     38        }
    2739
    28     public void registerPanel(Panel panel) {
    29         assert frame.isActive();
    30         knownPanels.put(panel.getClassName(), panel);
    31         frame.cardPanel.add(panel, panel.getFullName());
    32     }
     40        public Frame getFrame() {
     41                return frame;
     42        }
    3343
    34     public Panel findPanel(String className) {
    35         assert frame.isActive();
    36         return (knownPanels.containsKey(className) ? knownPanels.get(className) : null);
    37     }
     44        public void registerPanel(Panel panel) {
     45        }
    3846
    39     public final String getName() {
    40         return endpoint.getName();
    41     }
     47        public Panel findPanel(String accessId) {
     48                assert frame.isActive();
     49                return (knownPanels.containsKey(accessId) ? knownPanels.get(accessId) : null);
     50        }
     51
     52        public final String getName() {
     53                return endpoint.getName();
     54        }
     55
     56        public Panel preparePanel(CompositeParam param, FramsClass framsClass) {
     57                assert frame.isActive();
     58                Panel panel = preparePanelImpl(param, framsClass);
     59                assert panel != null;
     60                String accessId = param.computeAccessId();
     61                panel.uniqueName = accessId + "@" + endpoint.getName();
     62                knownPanels.put(accessId, panel);
     63                frame.cardPanel.add(panel, panel.uniqueName);
     64                log.debug("prepared panel for " + panel);
     65                return panel;
     66        }
     67
     68        protected Panel preparePanelImpl(CompositeParam param, FramsClass framsClass) {
     69                assert frame.isActive();
     70                List<Panel> panels = new ArrayList<Panel>();
     71
     72                Panel.Parameters parameters = new Panel.Parameters(this, param,
     73                                framsClass);
     74                for (PanelProvider pp : frame.browser.panelProviders) {
     75                        Panel p = pp.providePanel(parameters);
     76                        if (p != null) {
     77                                panels.add(p);
     78                        }
     79                }
     80
     81                if (panels.isEmpty()) {
     82                        return new EmptyPanel(parameters);
     83                }
     84                if (panels.size() == 1) {
     85                        return panels.get(0);
     86                }
     87                return new MultiPanel(parameters, panels);
     88
     89        }
     90
     91        @Override
     92        public void onListChange(Path path, ListChange change) {
     93
     94        }
     95
     96        public TreePath getTreePath(Path path, boolean create) {
     97                assert frame.isActive();
     98                TreeNode t = rootTreeNode;
     99                TreePath result = new TreePath(frame.rootNode).pathByAddingChild(rootTreeNode);
     100                List<Node> nodes = path.getNodes();
     101                Iterator<Node> i = nodes.iterator();
     102                i.next();
     103                // Node first = i.next();
     104
     105                // if (!t.path.isResolved()) {
     106                //      t.path = new Path(path.getInstance(), nodes, first);
     107                // }
     108                while (i.hasNext()) {
     109                        Node n = i.next();
     110                        TreeNode r = null;
     111                        for (TreeNode c : t.childrenIterable()) {
     112                                if (c.paramId.equals(n.getParam().getId())) {
     113                                        r = c;
     114                                        break;
     115                                }
     116                        }
     117                        if (r == null) {
     118                                log.debug("missing " + n.getParam().getId() + " in " + t);
     119                                if (!create) {
     120                                        return result;
     121                                }
     122                                Path p = new Path(path.getInstance(), nodes, n);
     123                                log.debug("forced resolution: creating treenode for " + p);
     124                                TreeNode childNode = new TreeNode(EndpointAtFrame.this, p);
     125
     126                                frame.addNode(childNode, t);
     127                                // frame.treeModel.reload();
     128                                // t.add(childNode);
     129                                // frame.treeModel.nodeStructureChanged(t);
     130
     131                                r = childNode;
     132                        } else {
     133                                // if (!r.path.isResolved()) {
     134                                //      r.path = new Path(path.getInstance(), nodes, n);
     135                                // }
     136                        }
     137                        result = result.pathByAddingChild(r);
     138                        t = r;
     139                }
     140                return result;
     141        }
     142
     143        @Override
     144        public void onFetch(final Path path) {
     145                assert instance.isActive();
     146                log.trace("fetched " + path);
     147
     148                frame.invokeLater(new Runnable() {
     149                        @Override
     150                        public void run() {
     151
     152                                TreePath treePath = getTreePath(path, true);
     153                                assert treePath.getPathCount() == path.size() + 1;
     154
     155                                final TreeNode result = (TreeNode) treePath.getLastPathComponent();
     156                                // log.trace("found " + result + " == " + path);
     157                                instance.invokeLater(new Runnable() {
     158                                        @Override
     159                                        public void run() {
     160                                                result.reactForFetchResult(path, null);
     161                                        }
     162                                });
     163                        }
     164                });
     165        }
     166
     167        @Override
     168        public void onRun(Exception e) {
     169
     170        }
     171
     172        @Override
     173        public void onStop(Exception e) {
     174
     175        }
    42176}
  • java/main/src/main/java/com/framsticks/gui/Frame.java

    r78 r84  
    11package com.framsticks.gui;
    22
    3 import com.framsticks.core.Node;
     3import com.framsticks.core.Instance;
    44import com.framsticks.core.Path;
    55import com.framsticks.gui.view.*;
    66import com.framsticks.gui.view.TreeCellRenderer;
    7 import com.framsticks.util.Dispatcher;
     7import com.framsticks.util.dispatching.Dispatcher;
     8import com.framsticks.util.swing.KeyboardModifier;
    89import org.apache.log4j.Logger;
    910
    1011import javax.swing.*;
     12import javax.swing.event.TreeModelEvent;
     13import javax.swing.event.TreeModelListener;
    1114import javax.swing.event.TreeSelectionEvent;
    1215import javax.swing.event.TreeSelectionListener;
    1316import javax.swing.tree.*;
     17
    1418import java.awt.*;
    1519import java.awt.datatransfer.StringSelection;
    16 import java.awt.event.ActionEvent;
    17 import java.awt.event.MouseAdapter;
    18 import java.awt.event.MouseEvent;
     20import java.awt.event.*;
    1921import java.util.HashMap;
    2022import java.util.Map;
     
    2325 * @author Piotr Sniegowski
    2426 */
     27@SuppressWarnings("serial")
    2528public class Frame extends JFrame implements Dispatcher {
    2629
    27     private static final Logger LOGGER = Logger.getLogger(Frame.class.getName());
    28 
    29     protected final Browser browser;
    30 
    31     protected final Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
    32 
    33 
    34     final protected CardLayout cardPanelLayout = new CardLayout();
    35     protected final JPanel cardPanel = new JPanel();
    36 
    37     protected JScrollPane treeScrollPane;
    38     protected JTree tree;
    39     protected DefaultTreeModel treeModel;
    40     protected javax.swing.tree.MutableTreeNode rootNode;
    41     //final Instance instance;
    42     protected JPanel treePanel;
    43     protected  JPopupMenu treePopupMenu;
    44     protected JMenuItem treePopupMenuHeader;
    45 
    46     TreeNode currentlyPoppedTreeNode;
    47     protected JLabel statusBar;
    48     protected JPanel mainPanel;
    49     protected JPanel leftPanel;
    50     protected JPanel normalWorkPanel;
    51     protected CardLayout mainPanelLayout;
    52 
    53     protected final Map<BrowserEndpoint, EndpointAtFrame> endpoints = new HashMap<BrowserEndpoint, EndpointAtFrame>();
    54 
    55     public Frame(String title, Browser browser) {
     30        private static final Logger log = Logger.getLogger(Frame.class.getName());
     31
     32        protected final Browser browser;
     33
     34        protected final Dimension screenDimension = Toolkit.getDefaultToolkit()
     35                        .getScreenSize();
     36
     37        final protected CardLayout cardPanelLayout = new CardLayout();
     38        protected final JPanel cardPanel = new JPanel();
     39
     40        protected JScrollPane treeScrollPane;
     41        protected JTree tree;
     42        protected DefaultTreeModel treeModel;
     43        protected javax.swing.tree.MutableTreeNode rootNode;
     44        //final Instance instance;
     45        protected JPanel treePanel;
     46        protected JPopupMenu treePopupMenu;
     47        protected JMenuItem treePopupMenuHeader;
     48
     49        TreeNode currentlyPoppedTreeNode;
     50        protected JLabel statusBar;
     51        protected JPanel mainPanel;
     52        protected JPanel leftPanel;
     53        protected JPanel normalWorkPanel;
     54        protected CardLayout mainPanelLayout;
     55
     56        protected JMenuBar menuBar;
     57        protected JMenu fileMenu;
     58        protected JMenu editMenu;
     59        protected JMenu viewMenu;
     60        protected JMenu windowMenu;
     61        protected JMenu helpMenu;
     62
     63        protected final Map<BrowserEndpoint, EndpointAtFrame> endpoints = new HashMap<BrowserEndpoint, EndpointAtFrame>();
     64        protected final Map<Instance, EndpointAtFrame> endpointsByInstance = new HashMap<Instance, EndpointAtFrame>();
     65
     66        public Frame(String title, Browser browser) {
    5667                super(title);
    57         this.browser = browser;
    58     }
    59 
    60     public void configure() {
    61 
    62         Container contentPane = this.getContentPane();
    63         contentPane.setLayout(new BorderLayout());
    64 
    65         treePopupMenu = new JPopupMenu("title");
    66         treePopupMenu.setName("popup");
    67         treePopupMenuHeader = new JMenuItem();
    68         treePopupMenuHeader.setForeground(Color.BLUE);
    69         treePopupMenu.add(treePopupMenuHeader);
    70         treePopupMenu.addSeparator();
    71         //TODO: add to favourites
    72         //TODO: remove from favourites
    73         //TODO: open in new window as root
    74         //TODO: refresh
    75         //TODO: open in console
    76 
    77         treePopupMenu.add(new JMenuItem("Refresh"));
    78         treePopupMenu.add(new JMenuItem("Open in new frame as root"));
    79                 addNodeActionToTreePopupMenu("Copy path to clipboard", new NodeAction() {
    80                         @Override
    81                         public void actionPerformed(TreeNode treeNode) {
    82                                 Path path = treeNode.getInstancePath();
    83                                 StringSelection selection = new StringSelection(path.toString());
    84                                 getToolkit().getSystemClipboard().setContents(selection, selection);
    85                         }
    86                 });
    87         //this.add(createMenuItem("Add to favourites", null));
    88         //this.add(createMenuItem("Remove from favourites", null));
    89 
    90         treePanel = new JPanel();
    91         treePanel.setLayout(new BorderLayout());
    92 
    93         treeModel = new DefaultTreeModel(null);
    94 
    95         tree = new JTree(treeModel);
    96         tree.setRootVisible(false);
    97         ToolTipManager.sharedInstance().registerComponent(tree);
    98 
    99         tree.addTreeSelectionListener(new TreeSelectionListener() {
    100             @Override
    101             public void valueChanged(TreeSelectionEvent e) {
    102                 chooseTreeNode(e.getNewLeadSelectionPath());
    103             }
    104         });
    105 
    106         tree.setExpandsSelectedPaths(true);
    107         tree.setEditable(false);
    108         tree.setDoubleBuffered(true);
    109         tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
    110         tree.setShowsRootHandles(true);
    111         tree.setRowHeight(26);
    112         tree.setDoubleBuffered(true);
    113         tree.addMouseListener(new MouseAdapter() {
    114             @Override
    115             public void mousePressed(MouseEvent e) {
    116                 assert isActive();
    117                 showPopup(e);
    118             }
    119 
    120             @Override
    121             public void mouseReleased(MouseEvent e) {
    122                 assert isActive();
    123                 showPopup(e);
    124             }
    125         });
    126         tree.setCellRenderer(new TreeCellRenderer());
    127 
    128         treeScrollPane = new JScrollPane(tree);
    129         treeScrollPane.setBorder(BorderFactory.createEmptyBorder());
    130 
    131         treePanel.add(treeScrollPane);
    132 
    133         rootNode = new DefaultMutableTreeNode();
    134         treeModel.setRoot(rootNode);
    135 
    136         normalWorkPanel = new JPanel();
    137         normalWorkPanel.setLayout(new BorderLayout());
    138 
    139         mainPanel = new JPanel();
    140         mainPanelLayout = new CardLayout();
    141         mainPanel.setLayout(mainPanelLayout);
    142         mainPanel.add(normalWorkPanel, "browser");
    143 
    144         contentPane.add(createMenu(), BorderLayout.NORTH);
    145         contentPane.add(mainPanel, BorderLayout.CENTER);
    146         contentPane.add(statusBar, BorderLayout.SOUTH);
    147 
    148         leftPanel = new JPanel();
    149         leftPanel.setLayout(new BorderLayout());
    150         JPanel leftTopPanel = createLeftTopPanel();
    151         if (leftTopPanel != null) {
    152             leftPanel.add(leftTopPanel, BorderLayout.PAGE_START);
    153         }
    154         leftPanel.add(treePanel, BorderLayout.CENTER);
    155         leftPanel.setBackground(Color.WHITE);
    156         leftPanel.setForeground(Color.WHITE);
    157 
    158         JSplitPane split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, leftPanel, cardPanel);
    159         split.setPreferredSize(new Dimension(this.browser.getConfig().getInteger("size.width", 1000), this.browser.getConfig().getInteger("size.height", 500)));
    160         split.setMaximumSize(screenDimension);
    161         split.setOneTouchExpandable(true);
    162         split.setDividerLocation(250);
    163         split.setDividerSize(5);
    164 
    165         normalWorkPanel.add(split);
    166 
    167         //this.setVisible(true);
    168         mainPanelLayout.show(mainPanel, "browser");
    169 
    170         cardPanel.setLayout(cardPanelLayout);
     68                /** this is done to remove the current value label from above the slider,
     69                 * because it cannot put to work properly with floating-point value sliders,
     70                 * nor it can be removed in normal way through JSlider methods  */
     71                UIManager.put("Slider.paintValue", false);
     72                this.browser = browser;
     73                log.debug("creating " + this);
     74        }
     75
     76        public void configure() {
     77
     78                Container contentPane = this.getContentPane();
     79                contentPane.setLayout(new BorderLayout());
     80
     81                treePopupMenu = new JPopupMenu("title");
     82                treePopupMenu.setName("popup");
     83                treePopupMenuHeader = new JMenuItem();
     84                treePopupMenuHeader.setForeground(Color.BLUE);
     85                treePopupMenu.add(treePopupMenuHeader);
     86                treePopupMenu.addSeparator();
     87                //TODO: add to favourites
     88                //TODO: remove from favourites
     89                //TODO: open in new window as root
     90                //TODO: refresh
     91                //TODO: open in console
     92
     93                treePopupMenu.add(new JMenuItem("Refresh"));
     94                treePopupMenu.add(new JMenuItem("Open in new frame as root"));
     95                addNodeActionToTreePopupMenu("Copy path to clipboard",
     96                                new NodeAction() {
     97                                        @Override
     98                                        public void actionPerformed(TreeNode treeNode) {
     99                                                Path path = treeNode.getInstancePath();
     100                                                StringSelection selection = new StringSelection(path
     101                                                                .toString());
     102                                                getToolkit().getSystemClipboard().setContents(
     103                                                                selection, selection);
     104                                        }
     105                                });
     106                //this.add(createMenuItem("Add to favourites", null));
     107                //this.add(createMenuItem("Remove from favourites", null));
     108
     109                treePanel = new JPanel();
     110                treePanel.setLayout(new BorderLayout());
     111
     112                treeModel = new DefaultTreeModel(null);
     113                treeModel.addTreeModelListener(new TreeModelListener() {
     114
     115                        @Override
     116                        public void treeNodesChanged(TreeModelEvent arg0) {
     117                                log.trace("treeNodesChanged: " + arg0);
     118                        }
     119
     120                        @Override
     121                        public void treeNodesInserted(TreeModelEvent arg0) {
     122                                // log.trace("treeNodesInserted: " + arg0);
     123                        }
     124
     125                        @Override
     126                        public void treeNodesRemoved(TreeModelEvent arg0) {
     127                                log.trace("treeNodesRemoved: " + arg0);
     128                        }
     129
     130                        @Override
     131                        public void treeStructureChanged(TreeModelEvent arg0) {
     132                                log.trace("treeStructureChanged: " + arg0);
     133                        }
     134                });
     135
     136                tree = new JTree(treeModel);
     137                tree.setName("tree");
     138                tree.setRootVisible(false);
     139                tree.setExpandsSelectedPaths(true);
     140                tree.setSelectionModel(new DefaultTreeSelectionModel());
     141                ToolTipManager.sharedInstance().registerComponent(tree);
     142
     143                tree.addTreeSelectionListener(new TreeSelectionListener() {
     144                        @Override
     145                        public void valueChanged(TreeSelectionEvent e) {
     146                                chooseTreeNode(e.getNewLeadSelectionPath());
     147                        }
     148                });
     149
     150                tree.setExpandsSelectedPaths(true);
     151                tree.setEditable(false);
     152                tree.setDoubleBuffered(true);
     153                tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
     154                tree.setShowsRootHandles(true);
     155                tree.setRowHeight(26);
     156                tree.setDoubleBuffered(true);
     157                tree.addMouseListener(new MouseAdapter() {
     158                        @Override
     159                        public void mousePressed(MouseEvent e) {
     160                                assert isActive();
     161                                showPopup(e);
     162                        }
     163
     164                        @Override
     165                        public void mouseReleased(MouseEvent e) {
     166                                assert isActive();
     167                                showPopup(e);
     168                        }
     169                });
     170
     171                new KeyboardModifier(tree, JComponent.WHEN_FOCUSED)
     172                        .join(KeyStroke.getKeyStroke('h'), KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0))
     173                        .join(KeyStroke.getKeyStroke('j'), KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0))
     174                        .join(KeyStroke.getKeyStroke('k'), KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0))
     175                        .join(KeyStroke.getKeyStroke('l'), KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0))
     176                        ;
     177
     178                tree.setCellRenderer(new TreeCellRenderer());
     179
     180                treeScrollPane = new JScrollPane(tree);
     181                treeScrollPane.setBorder(BorderFactory.createEmptyBorder());
     182
     183                treePanel.add(treeScrollPane);
     184
     185                rootNode = new DefaultMutableTreeNode();
     186                rootNode.setUserObject("root");
     187                treeModel.setRoot(rootNode);
     188
     189                normalWorkPanel = new JPanel();
     190                normalWorkPanel.setLayout(new BorderLayout());
     191                normalWorkPanel.setName("browser");
     192
     193                mainPanel = new JPanel();
     194                mainPanel.setName("main");
     195                mainPanelLayout = new CardLayout();
     196                mainPanel.setLayout(mainPanelLayout);
     197                mainPanel.add(normalWorkPanel, "browser");
     198
     199                menuBar = new JMenuBar();
     200
     201                fileMenu = menuBar.add(new JMenu("File"));
     202                editMenu = menuBar.add(new JMenu("Edit"));
     203                viewMenu = menuBar.add(new JMenu("View"));
     204                windowMenu = menuBar.add(new JMenu("Window"));
     205                helpMenu = menuBar.add(new JMenu("Help"));
     206
     207                contentPane.add(menuBar, BorderLayout.NORTH);
     208                contentPane.add(mainPanel, BorderLayout.CENTER);
     209                contentPane.add(statusBar, BorderLayout.SOUTH);
     210
     211                leftPanel = new JPanel();
     212                leftPanel.setLayout(new BorderLayout());
     213                //leftPanel.add(new ViewerTest(), BorderLayout.PAGE_START);
     214//        JPanel leftTopPanel = createLeftTopPanel();
     215//        if (leftTopPanel != null) {
     216//            leftPanel.add(leftTopPanel, BorderLayout.PAGE_START);
     217//        }
     218                leftPanel.add(treePanel, BorderLayout.CENTER);
     219                leftPanel.setBackground(Color.WHITE);
     220                leftPanel.setForeground(Color.WHITE);
     221
     222                cardPanel.setName("card");
     223                JSplitPane split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, leftPanel, cardPanel);
     224                split.setPreferredSize(browser.defaultFrameDimension);
     225                split.setMaximumSize(screenDimension);
     226                split.setOneTouchExpandable(true);
     227                split.setDividerLocation(250);
     228                split.setDividerSize(5);
     229                split.setName("split");
     230
     231                normalWorkPanel.add(split);
     232
     233                //this.setVisible(true);
     234                mainPanelLayout.show(mainPanel, "browser");
     235
     236                cardPanel.setLayout(cardPanelLayout);
    171237
    172238                this.pack();
    173239                tree.requestFocusInWindow();
    174240
    175     }
    176 
    177     protected JMenuBar createMenu() {
    178         return new JMenuBar();
    179     }
    180 
    181     protected JPanel createLeftTopPanel() {
    182         return null;
    183     }
    184 
    185     public void repaintTree() {
    186         //LOGGER.debug("repainting");
    187         //tree.repaint();
    188     }
    189 
    190     public EndpointAtFrame getOrCreateEndpointAtFrame(BrowserEndpoint endpoint) {
    191         assert isActive();
    192         if (endpoints.containsKey(endpoint)) {
    193             return endpoints.get(endpoint);
    194         }
    195         EndpointAtFrame e = new EndpointAtFrame(endpoint, this);
    196         endpoints.put(endpoint, e);
    197         return e;
    198     }
    199 
    200     public void addRootPath(BrowserEndpoint endpoint, Path path) {
    201         assert isActive();
    202         TreeNode node = new TreeNode(this, getOrCreateEndpointAtFrame(endpoint), path);
    203         treeModel.insertNodeInto(node, rootNode, rootNode.getChildCount());
    204         tree.expandPath(new TreePath(rootNode));
    205     }
    206 
    207     @Override
    208     public boolean isActive() {
    209         return SwingDispatcher.instance.isActive();
    210     }
    211 
    212     @Override
    213     public void invokeLater(Runnable runnable) {
    214         SwingDispatcher.instance.invokeLater(runnable);
    215     }
    216 
    217     public Action addActionToTreePopupMenu(Action action) {
    218         assert isActive();
    219         treePopupMenu.add(action);
    220         return action;
    221     }
    222 
    223     public Action addNodeActionToTreePopupMenu(String title, final NodeAction nodeAction) {
    224         assert isActive();
    225         return addActionToTreePopupMenu(new AbstractAction(title) {
    226             @Override
    227             public void actionPerformed(ActionEvent e) {
    228                 TreeNode treeNode = getCurrentlyPoppedTreeNode();
    229                 if (treeNode == null) {
    230                     return;
    231                 }
    232                 nodeAction.actionPerformed(treeNode);
    233             }
    234         });
    235     }
    236 
    237 
    238     public void showPanel(Panel panel) {
    239         assert isActive();
    240         assert panel != null;
    241         cardPanelLayout.show(cardPanel, panel.getFullName());
    242     }
    243 
    244     private void showPopup(MouseEvent e) {
    245         assert isActive();
    246         if (!e.isPopupTrigger()) {
    247             return;
    248         }
    249         currentlyPoppedTreeNode = findTreeNodeByTreePath(tree.getPathForLocation(e.getX(), e.getY()));
    250         if (currentlyPoppedTreeNode == null) {
    251             return;
    252         }
    253         treePopupMenu.show(e.getComponent(), e.getX(), e.getY());
    254         //currentlyPoppedPanel.getNode().getFramsClass().getName()
    255         //treePopupMenuHeader.setText(currentlyPoppedTreeNode.getNode().getPath());
    256     }
    257 
    258     public TreeNode getCurrentlyPoppedTreeNode() {
    259         assert isActive();
    260         return currentlyPoppedTreeNode;
    261     }
    262 
    263 
    264     public void clear() {
    265         treeModel.setRoot(null);
    266         cardPanel.removeAll();
    267         cardPanel.updateUI();
    268         tree.setEnabled(false);
    269     }
    270 
    271 
    272     public void markNodeChanged(MutableTreeNode treeNode, TreePath path) {
    273         assert isActive();
    274         treeModel.nodeStructureChanged(treeNode);
    275         tree.setSelectionPath(path);
    276         tree.repaint();
    277     }
    278 
    279     public TreePath startChange() {
    280         return tree.getSelectionPath();
    281     }
    282 
    283 
    284     public void selectTreeNode(final TreeNode treeNode) {
    285         assert isActive();
     241                log.debug("frame configured");
     242
     243        }
     244
     245        protected JPanel createLeftTopPanel() {
     246                return null;
     247        }
     248
     249        public void addRootPath(BrowserEndpoint endpoint, Path path) {
     250                assert isActive();
     251                assert !endpoints.containsKey(endpoint);
     252
     253                EndpointAtFrame e = new EndpointAtFrame(endpoint, this);
     254                endpoint.getInstance().addListener(e);
     255                endpoints.put(endpoint, e);
     256                endpointsByInstance.put(endpoint.getInstance(), e);
     257                TreeNode node = new TreeNode(e, path);
     258                e.rootTreeNode = node;
     259                treeModel.insertNodeInto(node, rootNode, rootNode.getChildCount());
     260                tree.expandPath(new TreePath(rootNode));
     261        }
     262
     263        @Override
     264        public boolean isActive() {
     265                return SwingDispatcher.instance.isActive();
     266        }
     267
     268        @Override
     269        public void invokeLater(Runnable runnable) {
     270                SwingDispatcher.instance.invokeLater(runnable);
     271        }
     272
     273        public Action addActionToTreePopupMenu(Action action) {
     274                assert isActive();
     275                treePopupMenu.add(action);
     276                return action;
     277        }
     278
     279        public Action addNodeActionToTreePopupMenu(String title, final NodeAction nodeAction) {
     280                assert isActive();
     281                return addActionToTreePopupMenu(new AbstractAction(title) {
     282                        @Override
     283                        public void actionPerformed(ActionEvent e) {
     284                                TreeNode treeNode = getCurrentlyPoppedTreeNode();
     285                                if (treeNode == null) {
     286                                        return;
     287                                }
     288                                nodeAction.actionPerformed(treeNode);
     289                        }
     290                });
     291        }
     292
     293        public void showPanel(Panel panel) {
     294                assert isActive();
     295                assert panel != null;
     296                cardPanelLayout.show(cardPanel, panel.getUniqueName());
     297        }
     298
     299
     300        private void showPopup(MouseEvent e) {
     301                assert isActive();
     302                if (!e.isPopupTrigger()) {
     303                        return;
     304                }
     305                currentlyPoppedTreeNode = findTreeNodeByTreePath(tree.getPathForLocation(e.getX(), e.getY()));
     306                if (currentlyPoppedTreeNode == null) {
     307                        return;
     308                }
     309                treePopupMenu.show(e.getComponent(), e.getX(), e.getY());
     310                //currentlyPoppedPanel.getNode().getFramsClass().getName()
     311                //treePopupMenuHeader.setText(currentlyPoppedTreeNode.getNode().getPath());
     312        }
     313
     314        public TreeNode getCurrentlyPoppedTreeNode() {
     315                assert isActive();
     316                return currentlyPoppedTreeNode;
     317        }
     318
     319
     320        public void clear() {
     321                treeModel.setRoot(null);
     322                cardPanel.removeAll();
     323                cardPanel.updateUI();
     324                tree.setEnabled(false);
     325        }
     326
     327        public Runnable startChange(final DefaultMutableTreeNode node) {
     328                assert isActive();
     329                final TreePath selection = tree.getSelectionPath();
     330                return new Runnable() {
     331                        @Override
     332                        public void run() {
     333                                assert isActive();
     334                                treeModel.nodeChanged(node);
     335                                tree.setSelectionPath(selection);
     336                        }
     337                };
     338        }
     339
     340        public void selectTreeNode(final TreeNode treeNode) {
     341                assert isActive();
    286342/*              final Panel panel = treeNode.getOrCreatePanel();
    287343                if (panel == null) {
     
    291347                treeNode.updateData();
    292348                showPanel(panel);*/
    293     }
    294 
    295     public TreeNode findTreeNodeByTreePath(TreePath treePath) {
    296         assert isActive();
    297         if (treePath == null) {
    298             return null;
    299         }
    300         if (!(treePath.getLastPathComponent() instanceof TreeNode)) {
    301             return null;
    302         }
    303         return (TreeNode)treePath.getLastPathComponent();
    304     }
    305 
    306 
    307 
    308     public void chooseTreeNode(TreePath treePath) {
    309         assert isActive();
    310         final TreeNode treeNode = findTreeNodeByTreePath(treePath);
    311         if (treeNode == null) {
    312             return;
    313         }
    314         treeNode.select();
    315     }
    316 
     349        }
     350
     351        public TreeNode findTreeNodeByTreePath(TreePath treePath) {
     352                assert isActive();
     353                if (treePath == null) {
     354                        return null;
     355                }
     356                if (!(treePath.getLastPathComponent() instanceof TreeNode)) {
     357                        return null;
     358                }
     359                return (TreeNode)treePath.getLastPathComponent();
     360        }
     361
     362        public void chooseTreeNode(TreePath treePath) {
     363                assert isActive();
     364                final TreeNode treeNode = findTreeNodeByTreePath(treePath);
     365                if (treeNode == null) {
     366                        return;
     367                }
     368                treeNode.select();
     369        }
     370
     371        public void goTo(Path path) {
     372                assert isActive();
     373                final TreePath treePath = endpointsByInstance.get(path.getInstance()).getTreePath(path, false);
     374                log.info("go to path: " + path + "(" + treePath + ")");
     375                invokeLater(new Runnable() {
     376                        @Override
     377                        public void run() {
     378                                tree.setSelectionPath(treePath);
     379                                tree.makeVisible(treePath);
     380                                assert tree.isVisible(treePath);
     381                        }
     382
     383                });
     384        }
     385
     386
     387        public void addNode(TreeNode child, DefaultMutableTreeNode parent) {
     388                assert isActive();
     389                Runnable r = startChange(parent);
     390                treeModel.insertNodeInto(child, parent, parent.getChildCount());
     391                r.run();
     392        }
     393
     394        @Override
     395        public String toString() {
     396                return getTitle() + "@" + browser.getName();
     397        }
    317398
    318399}
  • java/main/src/main/java/com/framsticks/gui/ImageProvider.java

    r77 r84  
    77
    88import javax.swing.*;
    9 import java.net.URL;
    109import java.util.HashMap;
    1110import java.util.LinkedHashMap;
     
    1615public class ImageProvider {
    1716
    18     private final static Logger LOGGER = Logger.getLogger(ImageProvider.class.getName());
     17    private final static Logger log = Logger.getLogger(ImageProvider.class.getName());
    1918
    2019
     
    8786            return icon;
    8887                } catch (Exception ignored) {
    89             LOGGER.error("failed to read icon: " + resourceName);
     88            log.error("failed to read icon: " + resourceName);
    9089                }
    9190                return null;
  • java/main/src/main/java/com/framsticks/gui/ListPanel.java

    r77 r84  
    1212 */
    1313@SuppressWarnings("serial")
    14 public class ListPanel extends Panel {
     14public class ListPanel extends ModifiablePanel {
    1515
    16         private static final Logger LOGGER = Logger.getLogger(ListPanel.class.getName());
     16        private static final Logger log = Logger.getLogger(ListPanel.class.getName());
    1717
    1818        final protected TableModel tableModel = new TableModel();
    1919        final protected JTable table = new JTable(tableModel);
    2020
    21         public ListPanel(EndpointAtFrame endpoint) {
    22                 super(endpoint, "list");
     21        public ListPanel(Parameters parameters) {
     22                super(parameters);
    2323
    2424                table.getTableHeader().setReorderingAllowed(false);
     
    2929                contentPanel.add(table);
    3030
    31         /*
     31                log.debug("created");
     32
     33                /*
    3234                AccessInterface elementAccess = ((ListAccess)access).getElementAccess();
    3335                if (elementAccess == null) {
    34                         LOGGER.error("no type class");
     36                        log.error("no type class");
    3537                        return;
    3638                }
     
    5052                }
    5153                tableModel.addRow(list.toArray());
    52         */
     54                */
    5355                /*
    5456                JMenuBar menuBar = new JMenuBar();
     
    105107
    106108        @Override
    107         public void refreshComponents(AccessInterface access) {
     109        public void pullValuesFromLocalToUser(AccessInterface access) {
    108110
    109111        }
     112
     113        @Override
     114        public String getTitle() {
     115                return "List";
     116        }
    110117}
  • java/main/src/main/java/com/framsticks/gui/MainFrame.java

    r77 r84  
    11package com.framsticks.gui;
    22
    3 import com.framsticks.gui.components.Control;
    4 import com.framsticks.gui.view.*;
    53import com.framsticks.gui.windows.console.ConsoleFrame;
     4import com.framsticks.util.swing.MenuConstructor;
    65import org.apache.log4j.Logger;
    76
     
    1110import java.awt.event.ActionEvent;
    1211import java.awt.event.ActionListener;
     12import java.awt.event.KeyEvent;
    1313import java.awt.event.WindowAdapter;
    1414import java.awt.event.WindowEvent;
     
    1717 * Application Main Frame.
    1818 */
     19@SuppressWarnings("serial")
    1920public class MainFrame extends Frame {
    2021
    21         private final static Logger LOGGER = Logger.getLogger(MainFrame.class.getName());
     22        private final static Logger log = Logger.getLogger(MainFrame.class.getName());
    2223
    2324        JButton start, stop, step;
     
    2829        public MainFrame(final Browser browser) {
    2930                super("Framsticks Network Client", browser);
    30                 LOGGER.debug("creating main frame");
     31                log.debug("creating main frame");
    3132
    3233                statusBar = new JLabel("not connected");
    33 
    34 
    35         }
     34        }
     35
    3636
    3737        @Override
    3838        public void configure() {
    3939                super.configure();
     40
     41                new MenuConstructor(fileMenu)
     42                        .add(null, new AbstractAction("Console") {
     43                                @Override
     44                                public void actionPerformed(ActionEvent actionEvent) {
     45                                        showConsoleFrame();
     46                                }
     47                        })
     48                        .add(KeyStroke.getKeyStroke(KeyEvent.VK_G, ActionEvent.CTRL_MASK), new AbstractAction("Goto") {
     49                                @Override
     50                                public void actionPerformed(ActionEvent actionEvent) {
     51                                        browser.autoResolvePath("/simulator/genepools/groups/0", null);
     52                                        // browser.autoResolvePath("/simulator/populations/groups/0", null;
     53                                        // browser.autoResolvePath("/simulator/genepools/groups/0/genotypes", null);
     54                                        // browser.autoResolvePath("/simulator/populations/groups", null);
     55                                }
     56                        })
     57                        .add(null, new AbstractAction("Disconnect") {
     58                                @Override
     59                                public void actionPerformed(ActionEvent actionEvent) {
     60                                        disconnect();
     61                                }
     62                        })
     63                        .add(null, new AbstractAction("Quit") {
     64                                @Override
     65                                public void actionPerformed(ActionEvent actionEvent) {
     66                                }
     67                        })
     68                        ;
     69
    4070                setFrameProperties();
    4171        }
    4272
    43         private void onConnectionEstablished() {
    44         assert isActive();
    45 
    46         addNodeActionToTreePopupMenu("Open in console", new NodeAction() {
    47             @Override
    48             public void actionPerformed(TreeNode treeNode) {
    49                 assert isActive();
    50                 //showConsoleFrame().setCommandLine("info " + treeNode.getNode().getPath());
    51             }
    52         });
    53 
    54 
    55 
    56 /*
    57         browser.addNodeActionToTreePopupMenu("Resolve recursively", new NodeAction() {
    58             @Override
    59             public void actionPerformed(TreeNode treeNode) {
    60                 final Child child = treeNode.getChild();
    61                 //server.invokeLater(new Runnable() {
    62                     @Override
    63                     public void run() {
    64                         resolveRecursively(child);
    65                     }
    66                 });
    67             }
    68         });
    69 */
    70 
    71         addNodeActionToTreePopupMenu("Store in file", new NodeAction() {
    72             @Override
    73             public void actionPerformed(final TreeNode treeNode) {
    74 
    75 /*
    76                 final Node node = treeNode.getNode();
    77                 server.invokeLater(new Runnable() {
    78                     @Override
    79                     public void run() {
    80                         try {
    81                             LOGGER.info("storing");
    82                             //File file = new File();
    83                             PrintStream file = new PrintStream("/home/piotr/Desktop/test.param");
    84                             StoreStream stream = new StoreStream(file, server.getManager());
    85                             stream.store(node);
    86 
    87                         } catch (FileNotFoundException e) {
    88                             e.printStackTrace();
    89                         }
    90                     }
    91                 });
    92 */
    93             }
    94         });
    95 
    96 /*
    97         arguments.forEach("resolve", new UnaryFunctor<Boolean, String>() {
    98             @Override
    99             public Boolean call(final String s) {
    100                 server.getManager().resolvePath(s, new StateFunctor() {
    101                     @Override
    102                     public void call(Exception e) {
    103                         if (e != null) {
    104                             LOGGER.error("failed to resolve: " + s);
    105                             return;
    106                         }
    107                         LOGGER.info("succeeded to resolve: " + s);
    108 
    109                     }
    110                 });
    111                 return true;
    112             }
    113         });
    114 */
    115 
    116         /*
    117         arguments.forEach("console", new UnaryFunctor<Boolean, String>() {
     73        // private void onConnectionEstablished() {
     74                // assert isActive();
     75
     76                // addNodeActionToTreePopupMenu("Open in console", new NodeAction() {
     77                        // @Override
     78                        // public void actionPerformed(TreeNode treeNode) {
     79                                // assert isActive();
     80                        // }
     81                // });
     82
     83
     84
     85
     86        //      // browser.addNodeActionToTreePopupMenu("Resolve recursively", new NodeAction() {
     87        //      //      @Override
     88        //      //      public void actionPerformed(TreeNode treeNode) {
     89        //      //              final Child child = treeNode.getChild();
     90        //      //              //server.invokeLater(new Runnable() {
     91        //              //              @Override
     92        //              //              public void run() {
     93        //              //                      resolveRecursively(child);
     94        //              //              }
     95        //              //      });
     96        //      // }
     97        //      // });
     98
     99
     100                // // addNodeActionToTreePopupMenu("Store in file", new NodeAction() {
     101                // //     @Override
     102                // //     public void actionPerformed(final TreeNode treeNode) {
     103                // //         // final Node node = treeNode.getNode();
     104                // //         // server.invokeLater(new Runnable() {
     105                // //         //     @Override
     106                // //         //     public void run() {
     107                // //         //         try {
     108                // //         //             log.info("storing");
     109                // //         //             //File file = new File();
     110                // //         //             StoreStream stream = new StoreStream(file, server.getManager());
     111                // //         //             stream.store(node);
     112                // //         //         } catch (FileNotFoundException e) {
     113                // //         //             e.printStackTrace();
     114                // //         //         }
     115                // //         //     }
     116                // //         // });
     117                // //     }
     118                // // });
     119
     120
     121        //      // arguments.forEach("resolve", new UnaryFunctor<Boolean, String>() {
     122        //      //      @Override
     123        //      //      public Boolean call(final String s) {
     124        //      //              server.getManager().resolvePath(s, new StateFunctor() {
     125        //      //                      @Override
     126        //      //                      public void call(Exception e) {
     127        //      //                              if (e != null) {
     128        //      //                                      log.error("failed to resolve: " + s);
     129        //      //                                      return;
     130        //      //                              }
     131        //      //                              log.info("succeeded to resolve: " + s);
     132        //      //                      }
     133        //      //              });
     134        //      //              return true;
     135        //      //      }
     136        //      // });
     137
     138
     139        //      // arguments.forEach("console", new UnaryFunctor<Boolean, String>() {
     140        //      //      @Override
     141        //      //      public Boolean call(String s) {
     142        //      //              showConsoleFrame().setCommandLine(s);
     143        //      //              return true;
     144        //      //      }
     145        //      // });
     146        // }
     147
     148        public void setSimulationRunning(final boolean run) {
     149                assert isActive();
     150                /*
     151                remoteInstance.invokeLater(new Runnable() {
    118152                        @Override
    119                         public Boolean call(String s) {
    120                                 showConsoleFrame().setCommandLine(s);
    121                                 return true;
     153                        public void run() {
     154                                remoteInstance.setRunning(run);
    122155                        }
    123156                });
     
    125158        }
    126159
    127         public void setSimulationRunning(final boolean run) {
    128         assert isActive();
    129         /*
    130         remoteInstance.invokeLater(new Runnable() {
    131             @Override
    132             public void run() {
    133                 remoteInstance.setRunning(run);
    134             }
    135         });
    136         */
    137         }
    138 
    139160        /**
    140161         * Creates panel with start, step, stop buttons.
    141162         */
    142     @Override
     163        @Override
    143164        protected JPanel createLeftTopPanel() {
    144         assert isActive();
    145         Dimension buttonDimension = new Dimension(45, 45);
     165                assert isActive();
     166                Dimension buttonDimension = new Dimension(45, 45);
    146167
    147168                JPanel panel = new JPanel();
     
    161182
    162183                step = new JButton(ImageProvider.loadImage(ImageProvider.SIM_STEP));
    163         /*
     184                /*
    164185                step.addActionListener(new ActionListener() {
    165186
     
    212233         */
    213234        private void setFrameProperties() {
    214         assert isActive();
    215         setMinimumSize(this.getPreferredSize());
     235                assert isActive();
     236                setMinimumSize(this.getPreferredSize());
    216237                setSize(this.getPreferredSize());
    217238                setMaximumSize(screenDimension);
     
    224245                addWindowListener(new WindowAdapter() {
    225246                        public void windowClosing(WindowEvent e) {
    226                 assert isActive();
    227                 /*
    228                 if (connection != null) {
     247                                assert isActive();
     248                                /*
     249                                if (connection != null) {
    229250                                        connection.close();
    230251                                }
     
    237258
    238259        public ConsoleFrame showConsoleFrame() {
    239         assert isActive();
    240         /*
    241         ConsoleFrame consoleFrame = new ConsoleFrame(connection);
     260                assert isActive();
     261                /*
     262                ConsoleFrame consoleFrame = new ConsoleFrame(connection);
    242263                consoleFrame.show(MainFrame.this);
    243264                return consoleFrame;
    244265                */
    245         return null;
    246         }
    247 
    248         /**
    249          * Creates menu bar.
    250          *
    251          * @return JMenuBar Menu bar.
    252          */
    253     @Override
    254         protected JMenuBar createMenu() {
    255         assert isActive();
    256         final JMenuBar menuBar = new JMenuBar();
    257                 final JMenu menu = new JMenu("Main");
    258 
    259                 final JMenuItem consoleItem = new JMenuItem("Console");
    260                 consoleItem.addActionListener(new ActionListener() {
    261 
    262                         public void actionPerformed(ActionEvent e) {
    263                                 showConsoleFrame();
    264                         }
    265 
    266                 });
    267 
    268         /*
    269                 final JMenuItem serverLogItem = new JMenuItem("Sever Log");
    270                 serverLogItem.addActionListener(new ActionListener() {
    271 
    272                         public void actionPerformed(ActionEvent e) {
    273                                 serverLogFrame.show(MainFrame.this);
    274                         }
    275 
    276                 });
    277                 */
    278 
    279                 final JMenuItem disconnectItem = new JMenuItem("Disconnect");
    280                 disconnectItem.addActionListener(new ActionListener() {
    281 
    282                         public void actionPerformed(ActionEvent e) {
    283                                 disconnect();
    284                         }
    285                 });
    286 
    287                 /** @todo do something proper with UI on close */
    288                 menu.add(consoleItem);
    289                 //menu.add(serverLogItem);
    290                 menu.add(disconnectItem);
    291                 menuBar.add(menu);
    292                 return menuBar;
     266                return null;
    293267        }
    294268
     
    297271         */
    298272        private void disconnect() {
    299         assert isActive();
    300         //remoteInstance.disconnect();
     273                assert isActive();
     274                //remoteInstance.disconnect();
    301275                browser.clear();
    302276                onWindowClosing();
     
    308282         */
    309283        private void onWindowClosing() {
    310         assert isActive();
     284                assert isActive();
    311285
    312286        }
    313287
    314288        public void setRunningButtons(boolean running) {
    315         assert isActive();
    316         step.setEnabled(!running);
     289                assert isActive();
     290                step.setEnabled(!running);
    317291                stop.setEnabled(running);
    318292                start.setEnabled(!running);
  • java/main/src/main/java/com/framsticks/gui/ObjectPanel.java

    r77 r84  
    11package com.framsticks.gui;
    22
    3 import com.framsticks.gui.components.Control;
    4 import com.framsticks.gui.components.ValueControl;
    5 import com.framsticks.gui.components.ValueControlListener;
     3import com.framsticks.gui.controls.Control;
     4import com.framsticks.gui.controls.ValueControl;
     5import com.framsticks.gui.controls.ValueControlListener;
    66import com.framsticks.params.AccessInterface;
    7 import com.framsticks.params.types.CompositeParam;
    87import com.framsticks.params.Param;
    9 import com.framsticks.util.Strings;
     8import com.framsticks.params.ValueParam;
     9
    1010import org.apache.log4j.Logger;
    1111
    1212import javax.swing.*;
    13 import java.awt.*;
    1413import java.util.Collection;
    1514import java.util.HashMap;
    1615import java.util.Map;
    17 import java.util.List;
     16import static com.framsticks.util.lang.Containers.filterInstanceof;
    1817
    1918@SuppressWarnings("serial")
    20 public class ObjectPanel extends com.framsticks.gui.Panel {
     19public class ObjectPanel extends ModifiablePanel {
    2120
    22         private static final Logger LOGGER = Logger.getLogger(ObjectPanel.class.getName());
     21        private static final Logger log = Logger.getLogger(ObjectPanel.class.getName());
    2322
    2423        final protected Map<Param, Control> components = new HashMap<Param, Control>();
    25         final protected Map<Param, ValueControl> valueComponents = new HashMap<Param, ValueControl>();
     24        final protected Map<ValueParam, ValueControl> valueControls = new HashMap<ValueParam, ValueControl>();
    2625
    27         public static void fillWithComponents(JPanel panel, Collection<Param> params, Map<Param, Control> components) {
    28                 for (Param param : params) {
    29                         if (param.isUserHidden()) {
    30                                 continue;
    31                         }
    32                         assert !(param instanceof CompositeParam);
    33                         Control control = Control.createSuitable(param);
    34                         if (control != null) {
    35                                 LOGGER.debug("add component for " + param);
    36                                 JPanel line = new JPanel();
    37                                 line.setLayout(new BoxLayout(line, BoxLayout.LINE_AXIS));
    38                                 line.setAlignmentX(LEFT_ALIGNMENT);
    39                                 JLabel label = new JLabel(Strings.notEmpty(param.getName()) ? param.getName() : "? (" + param.getId() + ")");
    40                                 label.setToolTipText(label.getText());
    41                                 label.setHorizontalAlignment(JLabel.RIGHT);
    42                                 Dimension labelSize = new Dimension(150, 30);
    43                                 label.setMaximumSize(labelSize);
    44                                 label.setMinimumSize(labelSize);
    45                                 label.setPreferredSize(labelSize);
    46                                 line.add(label);
    47                                 line.add(Box.createRigidArea(new Dimension(8, 0)));
    48                                 line.add(control);
    49                                 line.revalidate();
    50                                 panel.add(line);
    51                                 panel.add(Box.createRigidArea(new Dimension(0, 8)));
    52                                 //component.setAlignmentX(LEFT_ALIGNMENT);
    53                                 components.put(param, control);
    54                                 continue;
    55                         }
    56                         LOGGER.error("component for param " + param + " of type " + param.getClass().getSimpleName() + " was not added");
    57                 }
     26        public ObjectPanel(Panel.Parameters parameters, Collection<Param> params) {
     27                super(parameters);
    5828
    59         }
     29                Gui.fillWithControls(contentPanel, params, components);
    6030
    61         public ObjectPanel(EndpointAtFrame endpoint, String className, List<Param> params) {
    62                 super(endpoint, className);
    63 
    64                 fillWithComponents(contentPanel, params, components);
    65 
    66                 for (Map.Entry<Param, Control> e : components.entrySet()) {
    67                         Control control = e.getValue();
    68                         Param param = e.getKey();
    69                         if (control instanceof ValueControl) {
    70                                 final ValueControl valueComponent = (ValueControl) control;
    71                                 valueComponents.put(param, valueComponent);
    72                                 valueComponent.setListener(new ValueControlListener() {
    73                                         @Override
    74                                         public boolean onChange(Object newValue) {
    75                                                 if (currentTreeNode == null) {
    76                                                         return true;
    77                                                 }
    78                                                 boolean result = currentTreeNode.changeValue(valueComponent, newValue);
    79                                                 refreshControlButtons();
    80                                                 return result;
     31                for (final ValueControl c : filterInstanceof(components.values(), ValueControl.class)) {
     32                        valueControls.put(c.getParam(), c);
     33                        c.setListener(new ValueControlListener() {
     34                                @Override
     35                                public boolean onChange(Object newValue) {
     36                                        if (currentTreeNode == null) {
     37                                                return true;
    8138                                        }
    82                                 });
    83                         }
     39                                        boolean result = currentTreeNode.changeValue(c, newValue);
     40                                        refreshControlButtons();
     41                                        return result;
     42                                }
     43                        });
    8444                }
    8545                contentPanel.add(Box.createVerticalGlue());
     
    9151                assert frame.isActive();
    9252                assert currentTreeNode != null;
    93                 currentTreeNode.applyChanges();
     53                currentTreeNode.pushLocalChanges();
    9454        }
    9555
    9656        protected void refreshControlButtons() {
    9757                assert frame.isActive();
    98                 applyButton.setEnabled(currentTreeNode.changedValues != null);
     58                applyButton.setEnabled(currentTreeNode.localChanges != null);
     59        }
     60
     61        protected static void fillControlsWithValues(Map<ValueControl, Object> map) {
    9962        }
    10063
    10164        @Override
    102         public void refreshComponents(AccessInterface access) {
    103         assert currentTreeNode.path.getInstance().isActive();
    104         assert currentTreeNode != null;
    105         LOGGER.debug("refreshing components");
     65        public void pullValuesFromLocalToUser(AccessInterface access) {
     66                assert currentTreeNode != null;
     67                assert currentTreeNode.path.getInstance().isActive();
     68                log.debug("refreshing components");
    10669
    107         final Map<ValueControl, Object> values = new HashMap<ValueControl, Object>();
    108         for (ValueControl vc : valueComponents.values()) {
    109             Object value = access.get(vc.getParam().getId(), Object.class);
    110             values.put(vc, value);
    111         }
     70                final Map<ValueControl, Object> values = new HashMap<ValueControl, Object>();
     71                for (Map.Entry<ValueParam, ValueControl> e : valueControls.entrySet()) {
     72                        values.put(e.getValue(), access.get(e.getKey().getId(), Object.class));
     73                }
    11274
    113         frame.invokeLater(new Runnable() {
    114             @Override
    115             public void run() {
    116                 for (Map.Entry<ValueControl, Object> e : values.entrySet()) {
    117                     e.getKey().setValue(e.getValue());
    118                 }
    119                                 if (currentTreeNode.changedValues != null) {
    120                                         for (Map.Entry<ValueControl, Object> e : currentTreeNode.changedValues.entrySet()) {
    121                                                 e.getKey().setValue(e.getValue());
     75                frame.invokeLater(new Runnable() {
     76                        @Override
     77                        public void run() {
     78                                if (currentTreeNode.localChanges != null) {
     79                                        for (Map.Entry<ValueControl, Object> e : currentTreeNode.localChanges.entrySet()) {
     80                                                values.put(e.getKey(), e.getValue());
    12281                                        }
    12382                                }
     83                                for (Map.Entry<ValueControl, Object> e : values.entrySet()) {
     84                                        e.getKey().pushValueToUserInterface(e.getValue());
     85                                }
    12486                                refreshControlButtons();
    125                 ObjectPanel.this.revalidate();
    126             }
    127         });
     87                                ObjectPanel.this.revalidate();
     88                        }
     89                });
    12890
    12991        }
    13092
     93        @Override
     94        public String getTitle() {
     95                return "Properties";
     96        }
    13197
    13298
    133 /*      public void updateValue() {
    134                 //assert panel.getFrame().isActive();
     99        // public void updateValue() {
     100        //      //assert panel.getFrame().isActive();
    135101
    136         final Node n = panel.getCurrentNode();
    137         panel.getBrowser().getManager().invokeLater(new Runnable() {
    138             @Override
    139             public void run() {
    140                 Object v = n.getAccess().get(param, Object.class);
    141                 if (v == null) {
    142                     v = param.getDef(Object.class);
    143                 }
    144                 final Object fv = v;
    145                 panel.getBrowser().invokeLater(new Runnable() {
    146                     @Override
    147                     public void run() {
    148                         setValueImpl(fv);
    149                     }
    150                 });
    151             }
    152         });
    153         }*/
     102        //      final Node n = panel.getCurrentNode();
     103        //      panel.getBrowser().getManager().invokeLater(new Runnable() {
     104        //              @Override
     105        //              public void run() {
     106        //                      Object v = n.getAccess().get(param, Object.class);
     107        //                      if (v == null) {
     108        //                              v = param.getDef(Object.class);
     109        //                      }
     110        //                      final Object fv = v;
     111        //                      panel.getBrowser().invokeLater(new Runnable() {
     112        //                              @Override
     113        //                              public void run() {
     114        //                                      setValueImpl(fv);
     115        //                              }
     116        //                      });
     117        //              }
     118        //      });
     119        // }
    154120
    155121}
  • java/main/src/main/java/com/framsticks/gui/Panel.java

    r77 r84  
    22
    33import com.framsticks.params.AccessInterface;
    4 import org.apache.log4j.Logger;
     4import com.framsticks.params.CompositeParam;
     5import com.framsticks.params.FramsClass;
     6// import org.apache.log4j.Logger;
    57
    68import javax.swing.*;
    7 import java.awt.*;
    8 import java.awt.event.ActionEvent;
    9 import java.awt.event.ActionListener;
    109
    1110/**
    12  * @author Piotr Sniegowski
     11 * Author: Piotr Śniegowski
    1312 */
     13@SuppressWarnings("serial")
    1414public abstract class Panel extends JPanel {
    1515
    16         private static final Logger LOGGER = Logger.getLogger(Panel.class.getName());
     16        public static class Parameters {
     17                public final EndpointAtFrame endpoint;
     18                public final CompositeParam param;
     19                public final FramsClass framsClass;
    1720
    18         /**
    19          * Pane to which components will be added.
    20          */
    21         protected JPanel contentPanel;
     21                public Parameters(EndpointAtFrame endpoint, CompositeParam param, FramsClass framsClass) {
     22                        this.endpoint = endpoint;
     23                        this.param = param;
     24                        this.framsClass = framsClass;
     25                }
     26        }
     27
     28        // private static final Logger log = Logger.getLogger(Panel.class.getName());
    2229
    2330        protected TreeNode currentTreeNode;
    24     protected EndpointAtFrame endpoint;
    25     protected final Frame frame;
     31        protected final EndpointAtFrame endpoint;
     32        protected final Frame frame;
    2633        protected final String className;
    27         final protected JLabel label;
    28         final protected JButton applyButton;
     34        protected final FramsClass framsClass;
     35        protected final CompositeParam param;
     36        protected String uniqueName = "?";
    2937
    30         public Panel(EndpointAtFrame endpoint, String className) {
    31         this.endpoint = endpoint;
    32                 this.frame = endpoint.getFrame();
    33                 this.className = className;
    34                 LOGGER.debug("create panel for type: " + className);
    35 
    36         endpoint.registerPanel(this);
    37 
    38                 contentPanel = new JPanel();
    39                 contentPanel.setLayout(new BoxLayout(contentPanel, BoxLayout.PAGE_AXIS));
    40                 JScrollPane scroll = new JScrollPane(contentPanel);
    41                 //scroll.setBorder(BorderFactory.createEtchedBorder());
    42 
    43                 JPanel pageEndPanel = new JPanel();
    44                 pageEndPanel.setLayout(new BoxLayout(pageEndPanel, BoxLayout.X_AXIS));
    45                 pageEndPanel.add(Box.createHorizontalGlue());
    46 
    47                 applyButton = new JButton("Apply");
    48                 applyButton.addActionListener(new ActionListener() {
    49                         public void actionPerformed(ActionEvent e) {
    50                                 applyChanges();
    51                         }
    52                 });
    53                 pageEndPanel.add(applyButton);
    54 
    55                 pageEndPanel.add(Box.createHorizontalStrut(10));
    56                 pageEndPanel.setPreferredSize(new Dimension(0, 30));
    57 
    58                 label = new JLabel();
    59                 JPanel centerPanel = new JPanel();
    60                 centerPanel.setLayout(new BorderLayout());
    61                 centerPanel.add(Box.createHorizontalStrut(10), BorderLayout.LINE_START);
    62                 centerPanel.add(Box.createHorizontalStrut(10), BorderLayout.LINE_END);
    63                 centerPanel.add(label, BorderLayout.PAGE_START);
    64                 centerPanel.add(scroll, BorderLayout.CENTER);
    65                 centerPanel.add(pageEndPanel, BorderLayout.PAGE_END);
    66 
    67                 this.setLayout(new BorderLayout());
    68                 this.add(centerPanel, BorderLayout.CENTER);
    69 
    70 
     38        public Panel(Parameters parameters) {
     39                this.endpoint = parameters.endpoint;
     40                this.frame = parameters.endpoint.getFrame();
     41                this.framsClass = parameters.framsClass;
     42                this.param = parameters.param;
     43                this.className = parameters.param.getContainedTypeName();
     44                this.setName(parameters.param.getFramsTypeName());
    7145        }
    7246
    73         public void setCurrentTreeNode(TreeNode node) {
    74                 currentTreeNode = node;
    75                 //label.setText(node.getNode().getPath());
    76                 //this.revalidate();
     47        public void setCurrentTreeNode(TreeNode currentTreeNode) {
     48                this.currentTreeNode = currentTreeNode;
    7749        }
    7850
     
    8153        }
    8254
    83         protected abstract void applyChanges();
    84         public abstract void refreshComponents(AccessInterface access);
     55        public final Frame getFrame() {
     56                return frame;
     57        }
     58
     59        public final EndpointAtFrame getEndpointAtFrame() {
     60                return endpoint;
     61        }
     62
     63
     64        public final String getClassName() {
     65                return className;
     66        }
     67
     68        public abstract void pullValuesFromLocalToUser(AccessInterface access);
    8569
    8670        @Override
    8771        public String toString() {
    88                 return currentTreeNode == null ? "?" : currentTreeNode.toString();
     72                return uniqueName;
    8973        }
    9074
    91     public final Frame getFrame() {
    92         return frame;
    93     }
     75        public final String getUniqueName() {
     76                return uniqueName;
     77        }
    9478
    95 
    96     public final String getClassName() {
    97         return className;
    98     }
    99 
    100     public final String getFullName() {
    101         return className + "@" + endpoint.getName();
    102     }
    103 
     79        public abstract String getTitle();
    10480}
  • java/main/src/main/java/com/framsticks/gui/SwingDispatcher.java

    r77 r84  
    11package com.framsticks.gui;
    22
    3 import com.framsticks.util.Dispatcher;
    4 import com.framsticks.util.Task;
     3import com.framsticks.util.dispatching.Dispatcher;
     4import com.framsticks.util.dispatching.Task;
    55
    66import javax.swing.*;
    7 import java.awt.*;
    87
    98/**
     
    1211public class SwingDispatcher implements Dispatcher {
    1312
    14     public static final SwingDispatcher instance = new SwingDispatcher();
     13        public static final SwingDispatcher instance = new SwingDispatcher();
    1514
    16     public SwingDispatcher() {
    17         invokeLater(new Runnable() {
    18             @Override
    19             public void run() {
    20                 Thread.currentThread().setName("gui");
    21             }
    22         });
    23     }
     15        public SwingDispatcher() {
     16                invokeLater(new Runnable() {
     17                        @Override
     18                        public void run() {
     19                                Thread.currentThread().setName("gui");
     20                        }
     21                });
     22        }
    2423
    25     @Override
    26     public final boolean isActive() {
    27         return SwingUtilities.isEventDispatchThread();
    28     }
     24        @Override
     25        public final boolean isActive() {
     26                return SwingUtilities.isEventDispatchThread();
     27        }
    2928
    30     @Override
    31     public final void invokeLater(Runnable runnable) {
    32         assert !(runnable instanceof Task);
    33         SwingUtilities.invokeLater(runnable);
    34     }
     29        @Override
     30        public final void invokeLater(Runnable runnable) {
     31                assert !(runnable instanceof Task);
     32                SwingUtilities.invokeLater(runnable);
     33        }
    3534
    3635}
  • java/main/src/main/java/com/framsticks/gui/TreeNode.java

    r78 r84  
    55import com.framsticks.core.ListChange;
    66import com.framsticks.core.Path;
    7 import com.framsticks.gui.components.ValueControl;
     7import com.framsticks.gui.controls.ValueControl;
    88import com.framsticks.gui.view.TreeCellRenderer;
    99import com.framsticks.params.AccessInterface;
    10 import com.framsticks.params.Param;
     10import com.framsticks.params.CompositeParam;
     11import com.framsticks.params.FramsClass;
    1112import com.framsticks.params.types.*;
    1213import com.framsticks.remote.*;
    13 import com.framsticks.util.Casting;
    14 import com.framsticks.util.Future;
     14import com.framsticks.util.lang.Casting;
     15import com.framsticks.util.swing.TooltipConstructor;
     16import com.framsticks.util.dispatching.Future;
    1517import com.framsticks.util.Logging;
    1618import com.framsticks.util.StateFunctor;
     
    1820
    1921import javax.swing.tree.DefaultMutableTreeNode;
    20 import javax.swing.tree.TreePath;
    2122import java.util.HashMap;
    2223import java.util.LinkedList;
    2324import java.util.List;
    2425import java.util.Map;
     26import static com.framsticks.util.lang.Containers.filterInstanceof;
     27import com.framsticks.util.swing.TreeNodeUtils;
    2528
    2629/**
    2730 * @author Piotr Sniegowski
    2831 */
     32@SuppressWarnings("serial")
    2933public class TreeNode extends DefaultMutableTreeNode implements NodeListener {
    3034
    31         private static final Logger LOGGER = Logger.getLogger(TreeNode.class.getName());
     35        private static final Logger log = Logger.getLogger(TreeNode.class.getName());
    3236
    3337        Panel panel;
    3438
    3539        final protected Frame frame;
    36     final protected EndpointAtFrame endpoint;
    37 
    38     final protected Map<EventParam, Subscription> userSubscriptions = new HashMap<EventParam, Subscription>();
    39         protected Map<ValueControl, Object> changedValues = null;
    40     protected String tooltip;
    41     protected String name;
    42     protected String iconName;
    43     protected Path path;
    44 
    45 
    46     public TreeNode(Frame frame, EndpointAtFrame endpoint, final Path path) {
    47         assert frame.isActive();
    48         this.frame = frame;
    49                 LOGGER.debug("creating treenode for: " + path);
    50         this.path = path;
    51         this.endpoint = endpoint;
    52 
    53         name = path.getTop().getParam().getId();
    54         iconName = TreeCellRenderer.findIconName(name, path.getTextual());
    55         tooltip = "?";
    56         path.getInstance().invokeLater(new Runnable() {
    57             @Override
    58             public void run() {
    59                 updateDescriptions(path);
    60             }
    61         });
    62         }
    63 
    64     public void fetch(final Path p) {
    65         assert p.getInstance().isActive();
    66         LOGGER.debug("fetching: " + p);
    67         p.getInstance().fetchValues(p, new StateFunctor() {
    68             @Override
    69             public void call(Exception e) {
    70                 assert p.getInstance().isActive();
    71                 if (Logging.log(LOGGER, "fetch", TreeNode.this, e)) {
    72                     frame.invokeLater(new Runnable() {
    73                         @Override
    74                         public void run() {
    75                             LOGGER.debug("removing node from tree: " + p);
    76                             TreeNode.this.removeFromParent();
    77                             frame.repaintTree();
    78                         }
    79                     });
    80                     return;
    81                 }
    82                 updateChildren(p);
    83                 frame.invokeLater(new Runnable() {
    84                     @Override
    85                     public void run() {
    86                         //TODO maybe this should be called from some better place
    87                         useOrCreatePanel();
    88                     }
    89                 });
    90 
    91             }
    92         });
    93     }
    94 
    95     protected void postUpdatePath(final Path newPath) {
    96         assert !frame.isActive();
    97         /** TODO those two actions could be merged into single closure */
    98         frame.invokeLater(new Runnable() {
    99             @Override
    100             public void run() {
    101                 updatePath(newPath);
    102             }
    103         });
    104         updateDescriptions(newPath);
    105     }
    106 
    107     protected void updatePath(Path newPath) {
    108         assert frame.isActive();
    109         if (!path.isResolved()) {
    110             path = newPath;
    111                         LOGGER.debug("updated treenode's path: " + path);
    112             return;
    113         }
    114         if (path.matches(newPath)) {
    115             return;
    116         }
    117         this.removeAllChildren();
    118     }
    119 
    120     /** Update children, by removing non existing and adding new ones.
    121      */
    122     protected void updateChildren(final Path p) {
    123         assert p.getInstance().isActive();
    124         LOGGER.debug("updating children of " + this);
    125         AccessInterface access = p.getInstance().bindAccess(p.getTop());
     40        final protected EndpointAtFrame endpoint;
     41
     42        final protected Map<EventParam, Subscription> userSubscriptions = new HashMap<EventParam, Subscription>();
     43        protected Map<ValueControl, Object> localChanges = null;
     44        protected String tooltip;
     45        protected String name;
     46        protected final String paramId;
     47        protected String iconName;
     48        protected Path path;
     49
     50        public TreeNode(EndpointAtFrame endpoint, final Path path) {
     51                this.frame = endpoint.getFrame();
     52                assert frame.isActive();
     53                this.paramId = path.getLastElement();
     54                this.name = this.paramId;
     55                log.debug("creating treenode " + name + ": " + path);
     56                this.path = path;
     57                this.endpoint = endpoint;
     58
     59                iconName = TreeCellRenderer.findIconName(name, path.getTextual());
     60                tooltip = "?";
     61                path.getInstance().invokeLater(new Runnable() {
     62                        @Override
     63                        public void run() {
     64                                updateDescriptions(path);
     65                        }
     66                });
     67        }
     68
     69        public void fetch(final Path p) {
     70                assert p.getInstance().isActive();
     71                log.debug("fetching: " + p);
     72                p.getInstance().fetchValues(p, new StateFunctor() {
     73                        @Override
     74                        public void call(Exception e) {
     75                                //TODO removing should stay here
     76                                // reactForFetchResult(p, e);
     77                        }
     78                });
     79        }
     80
     81        protected void reactForFetchResult(final Path p, Exception e) {
     82                assert p.getInstance().isActive();
     83                if (Logging.log(log, "fetch", TreeNode.this, e)) {
     84                        frame.invokeLater(new Runnable() {
     85                                @Override
     86                                public void run() {
     87                                        log.debug("removing node from tree: " + p);
     88                                        frame.treeModel.removeNodeFromParent(TreeNode.this);
     89                                }
     90                        });
     91                        return;
     92                }
     93                updateChildren(p);
     94                frame.invokeLater(new Runnable() {
     95                        @Override
     96                        public void run() {
     97                                //TODO maybe this should be called from some better place
     98                                useOrCreatePanel();
     99                        }
     100                });
     101        }
     102
     103        protected void postUpdatePath(final Path newPath) {
     104                assert !frame.isActive();
     105                /** TODO those two actions could be merged into single closure */
     106                frame.invokeLater(new Runnable() {
     107                        @Override
     108                        public void run() {
     109                                updatePath(newPath);
     110                        }
     111                });
     112                updateDescriptions(newPath);
     113        }
     114
     115        protected void updatePath(Path newPath) {
     116                assert frame.isActive();
     117                if (!path.isResolved()) {
     118                        path = newPath;
     119                        log.debug("updated treenode's path: " + path);
     120                        return;
     121                }
     122                if (path.matches(newPath)) {
     123                        return;
     124                }
     125                log.debug("removing all children due to path update");
     126                this.removeAllChildren();
     127                frame.treeModel.nodeStructureChanged(this);
     128        }
     129
     130        public Iterable<TreeNode> childrenIterable() {
     131                return filterInstanceof(TreeNodeUtils.children(TreeNode.this, frame.treeModel), TreeNode.class);
     132        }
     133
     134        /** Update children, by removing non existing and adding new ones.
     135         */
     136        protected void updateChildren(final Path p) {
     137                assert p.getInstance().isActive();
     138                log.debug("updating children of " + this);
     139                AccessInterface access = p.getInstance().bindAccess(p.getTop());
    126140                if (access == null) {
    127141                        return;
    128142                }
    129         final List<Path> childrenPaths = new LinkedList<Path>();
    130         /**Prepare path for each child.*/
    131         for (Param param : access.getParams()) {
    132             if (!(param instanceof CompositeParam)) {
    133                 continue;
    134             }
    135             Path childPath = p.appendParam((CompositeParam)param);
    136             childrenPaths.add(childPath);
    137         }
    138         /**If some child were found, update in frame context.*/
    139         if (childrenPaths.size() > 0) {
    140             frame.invokeLater(new Runnable() {
    141                 @Override
    142                 public void run() {
    143                     TreePath treePath = frame.startChange();
    144                     updatePath(p);
    145                     Map<String, TreeNode> current = new HashMap<String, TreeNode>();
    146                     for (int c = 0; c < TreeNode.this.getChildCount(); ++c) {
    147                         TreeNode n = (TreeNode)TreeNode.this.getChildAt(c);
    148                         current.put(n.path.getLastElement(), n);
    149                     }
    150                     for (final Path childPath : childrenPaths) {
    151                         String e = childPath.getLastElement();
    152                         if (current.containsKey(e)) {
    153                             /*
    154                             final TreeNode n = current.get(e);
    155                             childPath.getInstance().invokeLater(new Runnable() {
    156                                 @Override
    157                                 public void run() {
    158                                     n.updateChildren(childPath);
    159                                 }
    160                             });
    161                             */
    162                             current.remove(e);
    163                             continue;
    164                         }
    165                         TreeNode childNode = new TreeNode(frame, endpoint, childPath);
    166                         TreeNode.this.add(childNode);
    167                     }
    168                     for (TreeNode n : current.values()) {
    169                         TreeNode.this.remove(n);
    170                     }
    171                     frame.markNodeChanged(TreeNode.this, treePath);
    172                     frame.repaintTree();
    173                     LOGGER.debug("updated children of " + TreeNode.this);
    174                 }
    175             });
    176         } else {
    177             LOGGER.debug("no children in " + TreeNode.this);
    178         }
    179     }
    180 
    181     public void select() {
    182         final Path p = path;
    183 
    184         p.getInstance().invokeLater(new Runnable() {
    185             @Override
    186             public void run() {
    187                 final Path updated = (p.isResolved()) ? p : p.findResolution();
    188                 if (updated.isResolved()) {
    189                     Logging.log(LOGGER, "update", updated, null);
    190                     fetch(updated);
    191                     postUpdatePath(updated);
    192                     return;
    193                 }
    194                 p.getInstance().resolve(updated, new Future<Path>() {
    195                     @Override
    196                     public void result(final Path result, Exception e) {
    197                         if (Logging.log(LOGGER, "resolve and select", TreeNode.this, e)) {
    198                             return;
    199                         }
    200 
    201                         fetch(result);
    202                         postUpdatePath(result);
    203                     }
    204                 });
    205             }
    206         });
    207 
    208     }
    209 
    210     @Override
    211     public String toString() {
    212         return path.toString();
    213     }
     143                final List<Path> childrenPaths = new LinkedList<Path>();
     144                /**Prepare path for each child.*/
     145                for (CompositeParam param : filterInstanceof(access.getParams(), CompositeParam.class)) {
     146                        childrenPaths.add(p.appendParam(param).tryFindResolution());
     147                }
     148
     149                /**If some child were found, update in frame context.*/
     150                if (childrenPaths.size() > 0) {
     151                        frame.invokeLater(new Runnable() {
     152                                @Override
     153                                public void run() {
     154                                        // TreePath treePath = frame.startChange();
     155                                        updatePath(p);
     156                                        Map<String, TreeNode> current = new HashMap<String, TreeNode>();
     157                                        for (TreeNode n : childrenIterable()) {
     158                                                current.put(n.path.getLastElement(), n);
     159                                        }
     160                                        assert current.size() == TreeNode.this.getChildCount();
     161                                        assert TreeNode.this.getChildCount() == frame.treeModel.getChildCount(TreeNode.this);
     162                                        log.trace("current " + TreeNode.this.getChildCount() + " children: " + current.values());
     163                                        for (Path childPath : childrenPaths) {
     164                                                String e = childPath.getLastElement();
     165                                                if (current.containsKey(e)) {
     166                                                        current.remove(e);
     167                                                        continue;
     168                                                }
     169                                                log.debug("update: treenode for " + p);
     170                                                TreeNode childNode = new TreeNode(endpoint, childPath);
     171
     172                                                frame.addNode(childNode, TreeNode.this);
     173                                        }
     174                                        for (TreeNode n : current.values()) {
     175                                                frame.treeModel.removeNodeFromParent(n);
     176                                        }
     177                                        log.debug("updated children of " + TreeNode.this + ": " + TreeNode.this.getChildCount());
     178                                }
     179                        });
     180                } else {
     181                        log.debug("no children in " + TreeNode.this);
     182                }
     183        }
     184
     185        public void select() {
     186                final Path p = path;
     187
     188                p.getInstance().invokeLater(new Runnable() {
     189                        @Override
     190                        public void run() {
     191                                final Path updated = (p.isResolved()) ? p : p.tryFindResolution();
     192                                if (updated.isResolved()) {
     193                                        Logging.log(log, "update", updated, null);
     194                                        fetch(updated);
     195                                        postUpdatePath(updated);
     196                                        return;
     197                                }
     198                                p.getInstance().resolve(updated, new Future<Path>() {
     199                                        @Override
     200                                        public void result(final Path result, Exception e) {
     201                                                if (Logging.log(log, "resolve and select", TreeNode.this, e)) {
     202                                                        return;
     203                                                }
     204
     205                                                fetch(result);
     206                                                postUpdatePath(result);
     207                                        }
     208                                });
     209                        }
     210                });
     211
     212        }
     213
     214        @Override
     215        public String toString() {
     216                return path.toString();
     217        }
    214218
    215219        public final Panel getPanel() {
    216         assert frame.isActive();
     220                assert frame.isActive();
    217221                return panel;
    218222        }
    219223
    220     protected void updateDescriptions(final Path p) {
    221         assert p.getInstance().isActive();
    222         if (!p.isResolved()) {
    223             return;
    224         }
    225         AccessInterface access = p.getInstance().bindAccess(p);
     224        protected void updateDescriptions(Path p) {
     225                assert p.getInstance().isActive();
     226
     227                if (!p.isResolved()) {
     228                        return;
     229                }
     230                AccessInterface access = p.getInstance().bindAccess(p);
    226231                if (access == null) {
    227232                        return;
    228233                }
    229         StringBuilder t = new StringBuilder();
    230         /** html formatting is used here, since tooltips in swing do not support simple \n line breaks */
    231         t.append("<html>");
    232         t.append("frams: ").append(access.getId()).append("<br/>");
    233         t.append("java: ").append(p.getTopObject().getClass().getCanonicalName()).append("<br/>");
    234         t.append("access: ").append(access.getClass().getSimpleName());
    235         t.append("</html>");
    236         final String tooltip = t.toString();
    237 
    238         StringParam nameParam = Casting.tryCast(StringParam.class, access.getParam("name"));
    239         final String name = (nameParam != null ? access.get(nameParam, String.class) : path.getTop().getParam().getId());
    240 
    241         frame.invokeLater(new Runnable() {
    242             @Override
    243             public void run() {
    244 
    245                 TreeNode.this.tooltip = tooltip;
    246                 TreeNode.this.name = name;
    247             }
    248         });
    249     }
     234
     235                final String tooltip = new TooltipConstructor()
     236                        .append("frams", access.getId())
     237                        .append("java", p.getTopObject().getClass().getCanonicalName())
     238                        .append("access", access.getClass().getSimpleName())
     239                        .append("name", name)
     240                        .append("id", paramId)
     241                        .append("object", Integer.toHexString(System.identityHashCode(this)))
     242                        .build()
     243                        ;
     244
     245                StringParam nameParam = Casting.tryCast(StringParam.class, access.getParam("name"));
     246                final String name = (nameParam != null ? access.get(nameParam, String.class) : path.getTop().getParam().getId());
     247
     248                frame.invokeLater(new Runnable() {
     249                        @Override
     250                        public void run() {
     251                                TreeNode.this.tooltip = tooltip;
     252                                TreeNode.this.name = name;
     253
     254                                log.debug("updated descriptions for " + path + ": " + name);
     255                        }
     256                });
     257        }
    250258
    251259/*
    252260        public void updateData() {
    253         assert browser.isActive();
     261                assert browser.isActive();
    254262                final Node node = getNode();
    255         browser.manager.invokeLater(new Runnable() {
    256             @Override
    257             public void run() {
    258                 node.fetchValues(new StateFunctor() {
    259                     @Override
    260                     public void call(Exception e) {
    261                         if (e != null) {
    262                             return;
    263                         }
    264                         browser.invokeLater(new Runnable() {
    265                             @Override
    266                             public void run() {
    267                                 assert browser.isActive();
    268                                 if (panel.getCurrentTreeNode() == TreeNode.this) {
    269                                     panel.refreshComponents();
    270                                 }
    271 
    272                                 browser.tree.repaint();
    273                                 panel.refreshComponents();
    274                             }
    275                         });
    276                     }
    277                 });
    278             }
    279         });
     263                browser.manager.invokeLater(new Runnable() {
     264                        @Override
     265                        public void run() {
     266                                node.fetchValues(new StateFunctor() {
     267                                        @Override
     268                                        public void call(Exception e) {
     269                                                if (e != null) {
     270                                                        return;
     271                                                }
     272                                                browser.invokeLater(new Runnable() {
     273                                                        @Override
     274                                                        public void run() {
     275                                                                assert browser.isActive();
     276                                                                if (panel.getCurrentTreeNode() == TreeNode.this) {
     277                                                                        panel.refreshComponents();
     278                                                                }
     279
     280                                                                browser.tree.repaint();
     281                                                                panel.refreshComponents();
     282                                                        }
     283                                                });
     284                                        }
     285                                });
     286                        }
     287                });
    280288        }
    281289*/
    282290
    283     public void showPanel() {
    284         assert frame.isActive();
    285         assert panel != null;
    286         frame.showPanel(panel);
    287     }
    288 
    289     public void fillPanelWithValues() {
    290         assert frame.isActive();
    291         final Path p = path;
    292         assert p.isResolved();
    293         assert panel != null;
    294         panel.setCurrentTreeNode(this);
    295         p.getInstance().invokeLater(new Runnable() {
    296             @Override
    297             public void run() {
    298                 AccessInterface access = p.getInstance().bindAccess(p);
    299                 panel.refreshComponents(access);
    300 
    301                 frame.invokeLater(new Runnable() {
    302                     @Override
    303                     public void run() {
    304                         showPanel();
    305                     }
    306                 });
    307             }
    308         });
    309 
    310     }
     291        public void showPanel() {
     292                assert frame.isActive();
     293                assert panel != null;
     294                frame.showPanel(panel);
     295        }
     296
     297        public void fillPanelWithValues() {
     298                assert frame.isActive();
     299                if (panel == null) {
     300                        return;
     301                }
     302                final Path p = path;
     303                assert p.isResolved();
     304                panel.setCurrentTreeNode(this);
     305                p.getInstance().invokeLater(new Runnable() {
     306                        @Override
     307                        public void run() {
     308                                AccessInterface access = p.getInstance().bindAccess(p);
     309                                panel.pullValuesFromLocalToUser(access);
     310
     311                                frame.invokeLater(new Runnable() {
     312                                        @Override
     313                                        public void run() {
     314                                                showPanel();
     315                                        }
     316                                });
     317                        }
     318                });
     319
     320        }
    311321
    312322        public void useOrCreatePanel() {
    313         assert frame.isActive();
     323                assert frame.isActive();
    314324                if (panel != null) {
    315             LOGGER.trace("panel is already attached: " + path);
    316             fillPanelWithValues();
    317                         return;
    318                 }
    319         if (!path.isResolved()) {
    320             LOGGER.trace("path is not resolved: " + path);
    321             return;
    322         }
    323 
    324         CompositeParam param = path.getTop().getParam();
    325         panel = endpoint.findPanel(param.computeAccessId());
    326         if (panel != null) {
    327             LOGGER.debug("found prepared panel for: " + path);
    328             fillPanelWithValues();
    329             return;
    330         }
    331         final Path p = path;
    332         LOGGER.debug("preparing panel: " + p);
    333         p.getInstance().invokeLater(new Runnable() {
    334             @Override
    335             public void run() {
    336                 assert p.getInstance().isActive();
    337                 final CompositeParam param = p.getTop().getParam();
    338                 if (param instanceof ObjectParam) {
    339                     AccessInterface access = p.getInstance().prepareAccess(param);
    340                     final List<Param> params = new LinkedList<Param>();
    341                     for (Param p : access.getParams()) {
    342                         if (p instanceof CompositeParam) {
    343                             continue;
    344                         }
    345                         params.add(p);
    346                     }
    347                     frame.invokeLater(new Runnable() {
    348                         @Override
    349                         public void run() {
    350                             panel = new ObjectPanel(endpoint, param.getContainedTypeName(), params);
    351                             fillPanelWithValues();
    352                         }
    353                     });
    354                     return;
    355                 }
    356                 if (param instanceof ListParam) {
    357                                         frame.invokeLater(new Runnable() {
    358                                                 @Override
    359                                                 public void run() {
    360                                                         panel = new ListPanel(endpoint);
    361                                                         fillPanelWithValues();
     325                        log.trace("panel is already attached: " + path);
     326                        fillPanelWithValues();
     327                        return;
     328                }
     329                if (!path.isResolved()) {
     330                        log.trace("path is not resolved: " + path);
     331                        return;
     332                }
     333
     334                CompositeParam param = path.getTop().getParam();
     335                panel = endpoint.findPanel(param.computeAccessId());
     336                if (panel != null) {
     337                        log.debug("found prepared panel for: " + path);
     338                        fillPanelWithValues();
     339                        return;
     340                }
     341                final Path p = path;
     342                log.debug("preparing panel: " + p);
     343                p.getInstance().invokeLater(new Runnable() {
     344                        @Override
     345                        public void run() {
     346                                assert p.getInstance().isActive();
     347                                final CompositeParam param = p.getTop().getParam();
     348                                final FramsClass framsClass = p.getInstance().getInfoFromCache(param.getContainedTypeName());
     349                                frame.invokeLater(new Runnable() {
     350                                        @Override
     351                                        public void run() {
     352                                                panel = endpoint.preparePanel(param, framsClass);
     353                                                fillPanelWithValues();
     354                                        }
     355                                });
     356                        }
     357                });
     358        }
     359
     360        public String getTooltip() {
     361                assert frame.isActive();
     362                return tooltip;
     363        }
     364
     365
     366
     367
     368        /*public void subscribe(final EventParam eventParam) {
     369                assert browser.isActive();
     370                if (hasSubscribed(eventParam)) {
     371                        log.error(eventParam + " is already subscribed for " + this);
     372                        return;
     373                }
     374                Node node = getNode();
     375                node.getConnection().subscribe(node.getPath() + "/" + eventParam.getId(), new SubscriptionCallback() {
     376                        @Override
     377                        public EventCallback subscribed(final Subscription subscription) {
     378                                if (subscription == null) {
     379                                        log.error("subscription failed");
     380                                        return null;
     381                                }
     382                                if (hasSubscribed(eventParam)) {
     383                                        //abort subscription
     384                                        return null;
     385                                }
     386                                userSubscriptions.put(eventParam, subscription);
     387                                log.debug("subscription succeeded: " + subscription);
     388                                subscription.setDispatcher(browser);
     389                                return new EventCallback() {
     390                                        @Override
     391                                        public void call(SourceInterface content) {
     392                                                assert browser.isActive();
     393                                                log.info("event " + subscription + " occurred");
     394                                        }
     395                                };
     396                        }
     397                });
     398
     399        }*/
     400
     401        public boolean hasSubscribed(EventParam param) {
     402                assert frame.isActive();
     403                return userSubscriptions.containsKey(param);
     404        }
     405
     406        public void unsubscribe(EventParam eventParam) {
     407                assert frame.isActive();
     408                if (!hasSubscribed(eventParam)) {
     409                        log.error("could not unsubscribe from " + eventParam);
     410                        return;
     411                }
     412                userSubscriptions.get(eventParam).unsubscribe(new LoggingStateCallback(log, "unsubscribed " + eventParam));
     413                userSubscriptions.remove(eventParam);
     414        }
     415
     416/*
     417
     418        @Override
     419        public void onChildChange(final Child child, ListChange.Action action) {
     420                assert browser.manager.isActive();
     421
     422                switch (action) {
     423                        case Remove: {
     424                                Dispatching.invokeDispatch(browser, browser.manager, new Runnable() {
     425                                        @Override
     426                                        public void run() {
     427                                                assert browser.manager.isActive();
     428                                                final TreeNode treeNode = (TreeNode) child.getUserObject();
     429                                                if (treeNode == null) {
     430                                                        log.error("child " + child + " had no tree node attached");
     431                                                        return;
    362432                                                }
    363                                         });
    364                                         return;
    365                     //return panel = new ListPanel(browser, access);
    366                 }
    367                 assert false;
    368             }
    369         });
    370         }
    371 
    372     public String getTooltip() {
    373         assert frame.isActive();
    374         return tooltip;
    375     }
    376 
    377 
    378 
    379 
    380     /*public void subscribe(final EventParam eventParam) {
    381         assert browser.isActive();
    382         if (hasSubscribed(eventParam)) {
    383             LOGGER.error(eventParam + " is already subscribed for " + this);
    384             return;
    385         }
    386         Node node = getNode();
    387         node.getConnection().subscribe(node.getPath() + "/" + eventParam.getId(), new SubscriptionCallback() {
    388             @Override
    389             public EventCallback subscribed(final Subscription subscription) {
    390                 if (subscription == null) {
    391                     LOGGER.error("subscription failed");
    392                     return null;
    393                 }
    394                 if (hasSubscribed(eventParam)) {
    395                     //abort subscription
    396                     return null;
    397                 }
    398                 userSubscriptions.put(eventParam, subscription);
    399                 LOGGER.debug("subscription succeeded: " + subscription);
    400                 subscription.setDispatcher(browser);
    401                 return new EventCallback() {
    402                     @Override
    403                     public void call(SourceInterface content) {
    404                         assert browser.isActive();
    405                         LOGGER.info("event " + subscription + " occurred");
    406                     }
    407                 };
    408             }
    409         });
    410 
    411     }*/
    412 
    413     public boolean hasSubscribed(EventParam param) {
    414         assert frame.isActive();
    415         return userSubscriptions.containsKey(param);
    416     }
    417 
    418     public void unsubscribe(EventParam eventParam) {
    419         assert frame.isActive();
    420         if (!hasSubscribed(eventParam)) {
    421             LOGGER.error("could not unsubscribe from " + eventParam);
    422             return;
    423         }
    424         userSubscriptions.get(eventParam).unsubscribe(new LoggingStateCallback(LOGGER, "unsubscribed " + eventParam));
    425         userSubscriptions.remove(eventParam);
    426     }
    427 
    428 /*
    429 
    430     @Override
    431     public void onChildChange(final Child child, ListChange.Action action) {
    432         assert browser.manager.isActive();
    433 
    434         switch (action) {
    435             case Remove: {
    436                 Dispatching.invokeDispatch(browser, browser.manager, new Runnable() {
    437                     @Override
    438                     public void run() {
    439                         assert browser.manager.isActive();
    440                         final TreeNode treeNode = (TreeNode) child.getUserObject();
    441                         if (treeNode == null) {
    442                             LOGGER.error("child " + child + " had no tree node attached");
    443                             return;
    444                         }
    445                         browser.invokeLater(new Runnable() {
    446                             @Override
    447                             public void run() {
    448                                 assert browser.isActive();
    449                                 TreePath path = browser.startChange();
    450                                 //assert treeNode.getParent() == TreeNode.this;
    451                                 if (treeNode.getParent() != null) {
    452                                     browser.treeModel.removeNodeFromParent(treeNode);
    453                                 }
    454                                 //remove(treeNode);
    455                                 browser.markNodeChanged(TreeNode.this, path);
    456                             }
    457                         });
    458                     }
    459                 });
    460                 break;
    461             }
    462         }
    463 
    464     }
     433                                                browser.invokeLater(new Runnable() {
     434                                                        @Override
     435                                                        public void run() {
     436                                                                assert browser.isActive();
     437                                                                TreePath path = browser.startChange();
     438                                                                //assert treeNode.getParent() == TreeNode.this;
     439                                                                if (treeNode.getParent() != null) {
     440                                                                        browser.treeModel.removeNodeFromParent(treeNode);
     441                                                                }
     442                                                                //remove(treeNode);
     443                                                                browser.markNodeChanged(TreeNode.this, path);
     444                                                        }
     445                                                });
     446                                        }
     447                                });
     448                                break;
     449                        }
     450                }
     451
     452        }
    465453*/
    466454
    467     public String getName() {
    468         return name;
    469     }
    470 
    471     public String getIconName() {
    472         return iconName;
    473     }
    474 
    475     @Override
    476     public void onUpgrade(Path path) {
    477     }
    478 
    479     @Override
    480     public void onChange(Path path) {
    481     }
    482 
    483     @Override
    484     public void onChildChange(Path path, ListChange.Action action) {
    485     }
    486 
    487     public final Frame getFrame() {
    488         return frame;
    489     }
     455        public String getName() {
     456                return name;
     457        }
     458
     459        public String getIconName() {
     460                return iconName;
     461        }
     462
     463        @Override
     464        public void onUpgrade(Path path) {
     465        }
     466
     467        @Override
     468        public void onChange(Path path) {
     469        }
     470
     471        @Override
     472        public void onChildChange(Path path, ListChange.Action action) {
     473        }
     474
     475        public final Frame getFrame() {
     476                return frame;
     477        }
    490478
    491479        public boolean changeValue(ValueControl component, Object newValue) {
    492                 LOGGER.debug("changing value of " + component + " to '" + newValue + "'");
    493 
    494                 if (changedValues == null) {
    495                         changedValues = new HashMap<ValueControl, Object>();
    496                 }
    497                 changedValues.put(component, newValue);
     480                log.debug("changing value of " + component + " to '" + newValue + "'");
     481
     482                if (localChanges == null) {
     483                        localChanges = new HashMap<ValueControl, Object>();
     484                }
     485                localChanges.put(component, newValue);
    498486
    499487                return true;
     
    505493        }
    506494
    507         public void applyChanges() {
    508                 assert frame.isActive();
    509                 if (changedValues == null) {
    510                         return;
    511                 }
    512                 final Map<ValueControl, Object> changes = changedValues;
    513                 changedValues = null;
     495        public void pushLocalChanges() {
     496                assert frame.isActive();
     497                if (localChanges == null) {
     498                        return;
     499                }
     500                final Map<ValueControl, Object> changes = localChanges;
     501                localChanges = null;
    514502                endpoint.getEndpoint().invokeLater(new Runnable() {
    515503                        @Override
     
    525513                                                                return;
    526514                                                        }
    527                                                         LOGGER.debug("applied changes for: " + p);
     515                                                        log.debug("applied changes for: " + p);
    528516                                                        frame.invokeLater(new Runnable() {
    529517                                                                @Override
  • java/main/src/main/java/com/framsticks/gui/view/ColumnMenuItem.java

    r77 r84  
    4646                this.addItemListener(new ItemListener() {
    4747                        public void itemStateChanged(ItemEvent e) {
    48                                 if (e.getStateChange() == e.SELECTED) {
     48                                if (e.getStateChange() == ItemEvent.SELECTED) {
    4949                                        columnManager.addColumn(ColumnMenuItem.this.columnName,
    5050                                                        ColumnMenuItem.this.columnId,
  • java/main/src/main/java/com/framsticks/gui/view/TreeCellRenderer.java

    r77 r84  
    66import javax.swing.*;
    77import javax.swing.tree.DefaultTreeCellRenderer;
     8
     9import org.apache.log4j.Logger;
     10
    811import java.awt.*;
    912
     
    1316@SuppressWarnings("serial")
    1417public class TreeCellRenderer extends DefaultTreeCellRenderer {
     18        private static final Logger log =
     19                Logger.getLogger(TreeCellRenderer.class);
    1520
    16     public TreeCellRenderer() {
    17         setOpenIcon(null);
    18         setClosedIcon(null);
    19         setLeafIcon(null);
    20     }
     21
     22        public TreeCellRenderer() {
     23                setOpenIcon(null);
     24                setClosedIcon(null);
     25                setLeafIcon(null);
     26        }
    2127
    2228        @Override
    2329        public Component getTreeCellRendererComponent(JTree tree, Object value,
    24                                                       boolean sel, boolean expanded, boolean leaf, int row,
    25                                                       boolean hasFocus) {
     30                        boolean sel, boolean expanded, boolean leaf, int row,
     31                        boolean hasFocus) {
    2632
    2733                //super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf,
     
    3137                }
    3238                if (!(value instanceof TreeNode)) {
    33             setIcon(ImageProvider.loadImage(ImageProvider.SERVER));
    34             setText("framsticks");
     39                        setIcon(ImageProvider.loadImage(ImageProvider.SERVER));
     40                        setText("framsticks");
    3541                        return this;
    3642                }
    3743                TreeNode treeNode = (TreeNode)value;
    38         assert treeNode.getFrame().isActive();
    39         setToolTipText(treeNode.getTooltip());
    40         setIcon(ImageProvider.loadImage(treeNode.getIconName()));
    41         setText(treeNode.getName());
     44                assert treeNode.getFrame().isActive();
     45                setToolTipText(treeNode.getTooltip());
     46                setIcon(ImageProvider.loadImage(treeNode.getIconName()));
     47                setText(treeNode.getName());
    4248                return this;
    4349        }
    4450
    4551        public static String findIconName(String nodeName, String path) {
    46         if (path == null || nodeName == null) {
    47             return null;
    48         }
    49         if (path.equals("/")) {
     52                if (nodeName == null || path == null) {
     53                        log.warn("given invalid parameters: " + nodeName + " " + path);
     54                        // return null;
     55                        return ImageProvider.SERVER;
     56                }
     57                if (path.equals("/")) {
    5058                        return ImageProvider.SERVER;
    5159                }
     
    133141                return ImageProvider.SERVER;
    134142        }
    135        
    136        
     143
     144
    137145}
  • java/main/src/main/java/com/framsticks/gui/windows/ServerLogFrame.java

    r77 r84  
    22
    33import com.framsticks.gui.ImageProvider;
    4 import com.framsticks.gui.components.Control;
    54import org.apache.log4j.Logger;
    65
  • java/main/src/main/java/com/framsticks/gui/windows/console/ConsoleFrame.java

    r77 r84  
    33import com.framsticks.communication.*;
    44import com.framsticks.gui.ImageProvider;
    5 import com.framsticks.util.Pair;
    6 import com.framsticks.util.Strings;
     5import com.framsticks.util.lang.Pair;
     6import com.framsticks.util.lang.Strings;
    77import org.apache.log4j.Logger;
    88
     
    1919public class ConsoleFrame extends JFrame {
    2020
    21         private static final Logger LOGGER = Logger.getLogger(ConsoleFrame.class.getName());
    22 
    23         /**
    24     * Painter coloring manager responses before display.
    25     */
    26     private final ConsolePainter consolePainter;
    27 
    28     /**
    29     * Text field for typing commands.
    30     */
    31     private final JTextField commandLine;
    32         /**
    33     * Reference to connection.
    34     */
    35     protected final ClientConnection connection;
     21        private static final Logger log = Logger.getLogger(ConsoleFrame.class.getName());
     22
     23        /**
     24        * Painter coloring manager responses before display.
     25        */
     26        private final ConsolePainter consolePainter;
     27
     28        /**
     29        * Text field for typing commands.
     30        */
     31        private final JTextField commandLine;
     32        /**
     33        * Reference to connection.
     34        */
     35        protected final ClientConnection connection;
    3636
    3737        /**
     
    5252
    5353        /**
    54     * Default constructor creates frame with console.
    55     */
    56     @SuppressWarnings("unchecked")
    57     public ConsoleFrame(ClientConnection connection) {
    58             this.connection = connection;
    59         this.setTitle("Console");
    60         this.setLayout(new BorderLayout());
    61         this.setSize(new Dimension(440, 400));
    62         this.setMinimumSize(new Dimension(440, 400));
    63         this.setIconImage(ImageProvider.loadImage(ImageProvider.LOGO).getImage());
    64         JFrame.setDefaultLookAndFeelDecorated(true);
    65 
    66             JTextPane text = new JTextPane();
    67         consolePainter = new ConsolePainter(text);
    68 
    69         text.setEditable(false);
    70         final JScrollPane scrollText = new JScrollPane(text);
    71         scrollText.setBorder(BorderFactory.createEtchedBorder());
    72 
    73         JPanel scrollPanel = new JPanel();
    74         scrollPanel.setLayout(new BorderLayout());
    75         scrollPanel.add(scrollText, BorderLayout.CENTER);
    76         scrollPanel.setBorder(BorderFactory.createEmptyBorder(7, 7, 7, 7));
    77 
    78         commandLine = new JTextField();
    79 
    80         commandLine.addKeyListener(new KeyListener() {
    81                 @Override
    82                 public void keyTyped(KeyEvent e) {
    83 
    84                 }
    85 
    86                 @Override
    87                 public void keyPressed(KeyEvent e) {
    88                         onKeyPressed(e.getKeyCode());
    89                 }
    90 
    91                 @Override
    92                 public void keyReleased(KeyEvent e) {
    93                 }
    94         });
    95 
    96         commandLine.setFocusTraversalKeys(
    97                         KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
    98                         Collections.EMPTY_SET);
    99 
    100         this.addWindowListener(new WindowAdapter() {
    101             public void windowActivated(WindowEvent e) {
    102                 commandLine.requestFocusInWindow();
    103             }
    104         });
    105 
    106             JButton sendButton = new JButton("Send");
    107         sendButton.addActionListener(new ActionListener() {
    108 
    109                 public void actionPerformed(final ActionEvent e) {
    110                         buttonSendAction();
    111                 }
    112 
    113         });
    114 
    115         final Box cmdBox = new Box(BoxLayout.LINE_AXIS);
    116         cmdBox.add(commandLine);
    117         cmdBox.add(Box.createHorizontalStrut(10));
    118         cmdBox.add(sendButton);
    119         cmdBox.setBorder(BorderFactory.createEmptyBorder(0, 7, 7, 7));
    120 
    121         this.getContentPane().add(scrollPanel, BorderLayout.CENTER);
    122         this.getContentPane().add(cmdBox, BorderLayout.PAGE_END);
    123         this.setVisible(false);
    124 
    125     }
     54        * Default constructor creates frame with console.
     55        */
     56        @SuppressWarnings("unchecked")
     57        public ConsoleFrame(ClientConnection connection) {
     58                this.connection = connection;
     59                this.setTitle("Console");
     60                this.setLayout(new BorderLayout());
     61                this.setSize(new Dimension(440, 400));
     62                this.setMinimumSize(new Dimension(440, 400));
     63                this.setIconImage(ImageProvider.loadImage(ImageProvider.LOGO).getImage());
     64                JFrame.setDefaultLookAndFeelDecorated(true);
     65
     66                JTextPane text = new JTextPane();
     67                consolePainter = new ConsolePainter(text);
     68
     69                text.setEditable(false);
     70                final JScrollPane scrollText = new JScrollPane(text);
     71                scrollText.setBorder(BorderFactory.createEtchedBorder());
     72
     73                JPanel scrollPanel = new JPanel();
     74                scrollPanel.setLayout(new BorderLayout());
     75                scrollPanel.add(scrollText, BorderLayout.CENTER);
     76                scrollPanel.setBorder(BorderFactory.createEmptyBorder(7, 7, 7, 7));
     77
     78                commandLine = new JTextField();
     79
     80                commandLine.addKeyListener(new KeyListener() {
     81                        @Override
     82                        public void keyTyped(KeyEvent e) {
     83
     84                        }
     85
     86                        @Override
     87                        public void keyPressed(KeyEvent e) {
     88                                onKeyPressed(e.getKeyCode());
     89                        }
     90
     91                        @Override
     92                        public void keyReleased(KeyEvent e) {
     93                        }
     94                });
     95
     96                commandLine.setFocusTraversalKeys(
     97                                KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
     98                                Collections.EMPTY_SET);
     99
     100                this.addWindowListener(new WindowAdapter() {
     101                        public void windowActivated(WindowEvent e) {
     102                                commandLine.requestFocusInWindow();
     103                        }
     104                });
     105
     106                JButton sendButton = new JButton("Send");
     107                sendButton.addActionListener(new ActionListener() {
     108
     109                        public void actionPerformed(final ActionEvent e) {
     110                                buttonSendAction();
     111                        }
     112
     113                });
     114
     115                final Box cmdBox = new Box(BoxLayout.LINE_AXIS);
     116                cmdBox.add(commandLine);
     117                cmdBox.add(Box.createHorizontalStrut(10));
     118                cmdBox.add(sendButton);
     119                cmdBox.setBorder(BorderFactory.createEmptyBorder(0, 7, 7, 7));
     120
     121                this.getContentPane().add(scrollPanel, BorderLayout.CENTER);
     122                this.getContentPane().add(cmdBox, BorderLayout.PAGE_END);
     123                this.setVisible(false);
     124
     125        }
    126126
    127127        public void setCommandLine(String command) {
     
    130130
    131131
    132     /**
    133     * Shows console frame, sets location relative to parent.
    134     *
    135     * @param parent Frame relative to which console window will be localized.
    136     */
    137     public void show(JFrame parent) {
    138         final Point parentLocation = parent.getLocation();
    139         final Point location = new Point(parentLocation.x + 20, parentLocation.y + 20);
    140         this.setLocation(location);
    141         this.setVisible(true);
    142     }
    143 
    144     /**
    145     * Adds query to console window.
    146     *
    147     * @param line Line of string query.
    148     */
    149     private void addQuery(String line) {
    150         consolePainter.userMsg(line + "\n");
    151     }
    152 
    153 
    154     /**
    155     * Sends message to manager and adds message to console frame.
    156     */
    157     public void buttonSendAction() {
    158         if (!connection.isConnected()) {
    159             JOptionPane.showMessageDialog(this, "missing connection to manager");
    160             return;
    161         }
    162         String commandText = commandLine.getText();
    163             Pair<String, String> command = Strings.splitIntoPair(commandText, ' ', "\n");
    164         Request request = Request.createRequestByTypeString(command.first);
    165         if (request == null) {
    166             LOGGER.warn("not a valid request: " + commandText);
    167             return;
    168         }
    169         request.parseRest(command.second);
    170 
    171             addQuery(commandText);
    172             addSentMessage(commandText);
    173             commandLine.setText("");
    174         connection.send(request, new ResponseCallback() {
    175             @Override
    176             public void process(Response response) {
    177                 for (File f : response.getFiles()) {
    178                     consolePainter.paintMessage(f);
    179                 }
    180             }
    181         });
    182     }
     132        /**
     133        * Shows console frame, sets location relative to parent.
     134        *
     135        * @param parent Frame relative to which console window will be localized.
     136        */
     137        public void show(JFrame parent) {
     138                final Point parentLocation = parent.getLocation();
     139                final Point location = new Point(parentLocation.x + 20, parentLocation.y + 20);
     140                this.setLocation(location);
     141                this.setVisible(true);
     142        }
     143
     144        /**
     145        * Adds query to console window.
     146        *
     147        * @param line Line of string query.
     148        */
     149        private void addQuery(String line) {
     150                consolePainter.userMsg(line + "\n");
     151        }
     152
     153
     154        /**
     155        * Sends message to manager and adds message to console frame.
     156        */
     157        public void buttonSendAction() {
     158                if (!connection.isConnected()) {
     159                        JOptionPane.showMessageDialog(this, "missing connection to manager");
     160                        return;
     161                }
     162                String commandText = commandLine.getText();
     163                Pair<String, String> command = Strings.splitIntoPair(commandText, ' ', "\n");
     164                Request request = Request.createRequestByTypeString(command.first);
     165                if (request == null) {
     166                        log.warn("not a valid request: " + commandText);
     167                        return;
     168                }
     169                request.parseRest(command.second);
     170
     171                addQuery(commandText);
     172                addSentMessage(commandText);
     173                commandLine.setText("");
     174                connection.send(request, new ResponseCallback() {
     175                        @Override
     176                        public void process(Response response) {
     177                                for (File f : response.getFiles()) {
     178                                        consolePainter.paintMessage(f);
     179                                }
     180                        }
     181                });
     182        }
    183183
    184184        private void onKeyPressed(int keyCode) {
  • java/main/src/main/java/com/framsticks/gui/windows/console/ConsolePainter.java

    r77 r84  
    22
    33import com.framsticks.communication.File;
    4 import com.framsticks.params.SourceInterface;
    5 import org.apache.log4j.Logger;
     4// import org.apache.log4j.Logger;
    65
    76import java.awt.Color;
     
    1615 */
    1716public class ConsolePainter {
    18         private static final Logger LOGGER = Logger.getLogger(ConsolePainter.class.getName());
     17        // private static final Logger log = Logger.getLogger(ConsolePainter.class.getName());
    1918
    2019        private Document doc;
    2120        private JTextPane textPane;
    22         private Color c1 = new Color(192, 0, 0);
    23         private Color c2 = new Color(84, 141, 212);
    24         private Color c3 = new Color(118, 146, 60);
    25         private Color c4 = new Color(0, 0, 128);
     21        // private Color c1 = new Color(192, 0, 0);
     22        // private Color c2 = new Color(84, 141, 212);
     23        // private Color c3 = new Color(118, 146, 60);
     24        // private Color c4 = new Color(0, 0, 128);
    2625        private SimpleLinePainter linePainter1;
    2726        private SimpleLinePainter linePainter2;
    2827        private final SimpleAttributeSet set = new SimpleAttributeSet();
    2928
    30        
     29
    3130        /**
    3231         * Constructor sets reference to pane with text.
     
    4746
    4847                String line;
    49                 Boolean boldNextId = false;
    50                 Boolean doNotPaint = false;
     48                // Boolean boldNextId = false;
     49                // Boolean doNotPaint = false;
    5150
    5251                while ((line = file.getContent().readLine()) != null) {
     
    113112
    114113                scrollDown();
    115                
     114
    116115        }
    117116
     
    166165         * @return First word in text line (with space char).
    167166         */
    168         private String firstWord(String line) {
    169                 String result;
    170                 int spaceIndex = line.indexOf(' ');
    171 
    172                 if (spaceIndex == -1) {
    173                         result = line;
    174                 } else {
    175                         result = line.substring(0, spaceIndex + 1);
    176                 }
    177 
    178                 return result;
    179         }
     167        // private String firstWord(String line) {
     168        //      String result;
     169        //      int spaceIndex = line.indexOf(' ');
     170
     171        //      if (spaceIndex == -1) {
     172        //              result = line;
     173        //      } else {
     174        //              result = line.substring(0, spaceIndex + 1);
     175        //      }
     176
     177        //      return result;
     178        // }
    180179
    181180        /**
  • java/main/src/main/java/com/framsticks/hosting/InstanceClient.java

    r77 r84  
    99import com.framsticks.parsers.Savers;
    1010import com.framsticks.core.LocalInstance;
    11 import com.framsticks.util.Future;
     11import com.framsticks.util.dispatching.Future;
    1212
    1313import java.net.Socket;
     
    2121public class InstanceClient implements RequestHandler {
    2222
    23     protected final LocalInstance instance;
    24     protected final ServerConnection connection;
     23        protected final LocalInstance instance;
     24        protected final ServerConnection connection;
    2525
    26     public InstanceClient(LocalInstance instance, Socket socket) {
    27         this.instance = instance;
    28         connection = new ServerConnection(socket, this);
    29         connection.start();
    30     }
     26        public InstanceClient(LocalInstance instance, Socket socket) {
     27                this.instance = instance;
     28                connection = new ServerConnection(socket, this);
     29                connection.start();
     30        }
    3131
    32     @Override
    33     public String toString() {
    34         return instance + "|" + connection.toString();
    35     }
     32        @Override
     33        public String toString() {
     34                return instance + "|" + connection.toString();
     35        }
    3636
    3737
    38     @Override
    39     public void handle(final ApplicationRequest request, final ResponseCallback responseCallback) {
    40         instance.invokeLater(new Runnable() {
    41             @Override
    42             public void run() {
    43                 final Path path = new Path(instance, request.getPath());
    44                 if (!path.isResolved(request.getPath())) {
    45                     responseCallback.process(new Response(false, "\"invalid path\"", null));
    46                     return;
    47                 }
    48                 if (request instanceof GetRequest) {
    49                     instance.findInfo(path, new Future<FramsClass>() {
    50                         @Override
    51                         public void result(FramsClass result, Exception e) {
    52                             if (result == null) {
    53                                 responseCallback.process(new Response(false, "\"failed to find info for access bind\"", null));
    54                                 return;
    55                             }
    56                             List<File> files = new LinkedList<File>();
    57                             AccessInterface access = instance.bindAccess(path);
     38        @Override
     39        public void handle(final ApplicationRequest request, final ResponseCallback responseCallback) {
     40                instance.invokeLater(new Runnable() {
     41                        @Override
     42                        public void run() {
     43                                final Path path = instance.getPath(request.getPath());
     44                                if (!path.isResolved(request.getPath())) {
     45                                        responseCallback.process(new Response(false, "\"invalid path\"", null));
     46                                        return;
     47                                }
     48                                if (request instanceof GetRequest) {
     49                                        instance.findInfo(path, new Future<FramsClass>() {
     50                                                @Override
     51                                                public void result(FramsClass result, Exception e) {
     52                                                        if (result == null) {
     53                                                                responseCallback.process(new Response(false, "\"failed to find info for access bind\"", null));
     54                                                                return;
     55                                                        }
     56                                                        List<File> files = new LinkedList<File>();
     57                                                        AccessInterface access = instance.bindAccess(path);
    5858
    59                             if (access == null) {
     59                                                        if (access == null) {
    6060
    61                                 responseCallback.process(new Response(false, "\"failed to bind access\"", null));
    62                                 return;
    63                             }
    64                             ListSink sink = new ListSink();
    65                             access.save(sink);
    66                             files.add(new File(path.getTextual(), new ListSource(sink.getOut())));
    67                             responseCallback.process(new Response(true, "", files));
    68                         }
    69                     });
    70                     return;
    71                 }
    72                 if (request instanceof InfoRequest) {
    73                     instance.findInfo(path, new Future<FramsClass>() {
    74                         @Override
    75                         public void result(FramsClass result, Exception e) {
    76                             if (result == null) {
    77                                 responseCallback.process(new Response(false, "\"info not found\"", null));
    78                                 return;
    79                             }
    80                             ListSink sink = new ListSink();
    81                             Savers.saveFramsClass(sink, result);
    82                             List<File> files = new ArrayList<File>();
    83                             files.add(new File(path.getTextual(), new ListSource(sink.getOut())));
    84                             responseCallback.process(new Response(true, null, files));
    85                         }
    86                     });
    87                     return;
    88                 }
    89                 responseCallback.process(new Response(false, "invalid", null));
    90             }
    91         });
     61                                                                responseCallback.process(new Response(false, "\"failed to bind access\"", null));
     62                                                                return;
     63                                                        }
     64                                                        ListSink sink = new ListSink();
     65                                                        access.save(sink);
     66                                                        files.add(new File(path.getTextual(), new ListSource(sink.getOut())));
     67                                                        responseCallback.process(new Response(true, "", files));
     68                                                }
     69                                        });
     70                                        return;
     71                                }
     72                                if (request instanceof InfoRequest) {
     73                                        instance.findInfo(path, new Future<FramsClass>() {
     74                                                @Override
     75                                                public void result(FramsClass result, Exception e) {
     76                                                        if (result == null) {
     77                                                                responseCallback.process(new Response(false, "\"info not found\"", null));
     78                                                                return;
     79                                                        }
     80                                                        ListSink sink = new ListSink();
     81                                                        Savers.saveFramsClass(sink, result);
     82                                                        List<File> files = new ArrayList<File>();
     83                                                        files.add(new File(path.getTextual(), new ListSource(sink.getOut())));
     84                                                        responseCallback.process(new Response(true, null, files));
     85                                                }
     86                                        });
     87                                        return;
     88                                }
     89                                responseCallback.process(new Response(false, "invalid", null));
     90                        }
     91                });
    9292
    93     }
     93        }
    9494}
  • java/main/src/main/java/com/framsticks/hosting/ServerInstance.java

    r78 r84  
    22
    33import com.framsticks.core.*;
     4import com.framsticks.params.CompositeParam;
    45import com.framsticks.params.FramsClass;
    56import com.framsticks.params.ParamBuilder;
    6 import com.framsticks.params.types.CompositeParam;
    77import com.framsticks.core.LocalInstance;
    8 import com.framsticks.util.Future;
     8import com.framsticks.util.dispatching.Future;
     9
     10import org.apache.commons.configuration.Configuration;
    911import org.apache.log4j.Logger;
    1012
     
    1416public class ServerInstance extends LocalInstance {
    1517
    16     private final static Logger LOGGER = Logger.getLogger(ServerInstance.class.getName());
     18        private final static Logger log = Logger.getLogger(ServerInstance.class.getName());
    1719
    18     Entity hosted;
     20        Entity hosted;
    1921
    20     public ServerInstance(Parameters parameters) {
    21         super(parameters);
    22     }
     22        public ServerInstance() {
     23        }
    2324
    24     @Override
    25     protected void run() {
    26         super.run();
    27         assert hosted != null;
    28         hosted.start();
    29     }
     25        @Override
     26        protected void run() {
     27                super.run();
     28                assert hosted != null;
     29                hosted.start();
     30        }
    3031
    31     @Override
    32     protected void configure() throws Exception {
    33         super.configure();
     32        @Override
     33        public void configure(Configuration config) {
     34                super.configure(config);
    3435
    35         Parameters p = new Parameters(config.subset("hosted.entity"), "hosted", this, null);
    36         hosted = Program.configureEntity(p);
    37         if (hosted == null) {
    38             LOGGER.fatal("failed to create hosted entity");
    39             return;
    40         }
    41         hosted.configurePublic();
    42         root = new Node((CompositeParam)new ParamBuilder().setName("root").setId("root").setType("o" + hosted.getClass().getCanonicalName()).build(), hosted);
    43     }
     36                Configuration hostedConfig = config.subset("hosted.entity");
     37                hosted = Program.configureEntity(hostedConfig);
     38                if (hosted == null) {
     39                        log.fatal("failed to create hosted entity");
     40                        return;
     41                }
     42                hosted.setName("hosted");
     43                hosted.configure(hostedConfig);
     44                root = new Node((CompositeParam)new ParamBuilder().setName("root").setId("root").setType("o" + hosted.getClass().getCanonicalName()).build(), hosted);
     45        }
    4446
    45     @Override
    46     public FramsClass getInfoFromCache(String id) {
    47         assert isActive();
    48         if (id == null) {
    49             return null;
    50         }
     47        @Override
     48        public FramsClass getInfoFromCache(String id) {
     49                assert isActive();
     50                if (id == null) {
     51                        return null;
     52                }
    5153                FramsClass cached = registry.getInfoFromCache(id);
    52         if (cached != null) {
     54                if (cached != null) {
    5355                        return cached;
    54         }
    55         try {
    56             Class nativeClass = Class.forName(id);
    57             FramsClass framsClass = new FramsClass.Constructor(nativeClass, id).getResult();
     56                }
     57                try {
     58                        Class<?> nativeClass = Class.forName(id);
     59                        FramsClass framsClass = new FramsClass.Constructor(nativeClass, id).getResult();
    5860
    59             registry.registerReflectedClass(null, id, nativeClass);
    60             registry.putInfoIntoCache(framsClass);
    61             return framsClass;
    62         } catch (ClassNotFoundException ignored) {
    63         }
     61                        registry.registerReflectedClass(null, id, nativeClass);
     62                        registry.putInfoIntoCache(framsClass);
     63                        return framsClass;
     64                } catch (ClassNotFoundException ignored) {
     65                }
    6466
    65         return null;
    66     }
     67                return null;
     68        }
    6769
    68     @Override
    69     protected void fetchInfo(Path path, Future<FramsClass> future) {
    70         assert isActive();
     70        @Override
     71        protected void fetchInfo(Path path, Future<FramsClass> future) {
     72                assert isActive();
    7173
    72         FramsClass framsClass = getInfoFromCache(path.getTop().getObject().getClass().getCanonicalName());
    73         if (framsClass == null) {
    74             LOGGER.error("failed to create frams class for: " + path.getTop().getObject().getClass());
    75             future.result(null, new Exception());
    76             return;
    77         }
    78         future.result(framsClass, null);
     74                FramsClass framsClass = getInfoFromCache(path.getTop().getObject().getClass().getCanonicalName());
     75                if (framsClass == null) {
     76                        log.error("failed to create frams class for: " + path.getTop().getObject().getClass());
     77                        future.result(null, new Exception());
     78                        return;
     79                }
     80                future.result(framsClass, null);
    7981
    80     }
     82        }
    8183
    82     @Override
    83     protected void tryRegisterOnChangeEvents(Path path) {
    84     }
     84        @Override
     85        protected void tryRegisterOnChangeEvents(Path path) {
     86        }
    8587
    8688}
  • java/main/src/main/java/com/framsticks/leftovers/FavouritesXMLFactory.java

    r77 r84  
    2929        /**
    3030         * Writes favourites nodes and fields list to XML file.
    31          * 
     31         *
    3232         * @param path
    3333         *            Path of XML file.
     
    8989        /**
    9090         * Reads user favourites nodes and fields from XML file.
    91          * 
     91         *
    9292         * @param filePath
    9393         *            PAth to XML file.
     
    117117                                                if (itemDetails.item(0).getNodeName().equals(pathMark)
    118118                                                                && itemDetails.item(1).getNodeName().equals(nameMark)
    119                                                                 && (itemDetails.item(2).getNodeName().equals(fieldMark) 
     119                                                                && (itemDetails.item(2).getNodeName().equals(fieldMark)
    120120                                                                                || itemDetails.item(2).getNodeName().equals(typeMark))) {
    121121                                                        path = itemDetails.item(0).getTextContent();
     
    128128                                                        }else{
    129129                                                                try {
    130                                                                         int nodeTypeId = Integer.parseInt(itemDetails.item(2).getTextContent());
     130                                                                        // int nodeTypeId = Integer.parseInt(itemDetails.item(2).getTextContent());
    131131                                                                        userNode = new UserFavourite(path, name, null);
    132132                                                                        result.put(path, userNode);
     
    147147        /**
    148148         * Writes column configuration to XML file.
    149          * 
     149         *
    150150         * @param path
    151151         *            Path to XML file.
     
    206206        /**
    207207         * Reads column configuration from XML file.
    208          * 
     208         *
    209209         * @param path
    210210         *            Path to XML file.
  • java/main/src/main/java/com/framsticks/leftovers/f0/NeuroClass.java

    r77 r84  
    44
    55import com.framsticks.params.FramsClass;
     6import com.framsticks.params.Param;
    67
    78/**
     
    1415        */
    1516
    16         /** The symbol glymph. */
     17        /**
     18         * The symbol glymph.
     19         */
    1720        private int[] symbolGlymph;
    18        
    19         /** The pref inputs. */
     21
     22        /**
     23         * The pref inputs.
     24         */
    2025        private int prefInputs;
    21        
    22         /** The pref output. */
     26
     27        /**
     28         * The pref output.
     29         */
    2330        private int prefOutput;
    24        
    25         /** The pref location. */
     31
     32        /**
     33         * The pref location.
     34         */
    2635        private int prefLocation;
    27        
    28         /** The param entry list. */
     36
     37        /**
     38         * The param entry list.
     39         */
    2940        private FramsClass framsClass;
    30        
    31         /** The visual hints. */
     41
     42        /**
     43         * The visual hints.
     44         */
    3245        private int visualHints;
    3346
     
    5366         * Instantiates a new neuro class.
    5467         *
    55          * @param framsClass the param entry list
    56          * @param prefInputs the pref inputs
    57          * @param prefOutput the pref output
     68         * @param framsClass   the param entry list
     69         * @param prefInputs   the pref inputs
     70         * @param prefOutput   the pref output
    5871         * @param prefLocation the pref location
    59          * @param visualHints the visual hints
     72         * @param visualHints  the visual hints
    6073         * @param symbolGlymph the symbol glymph
    6174         */
    6275        public NeuroClass(FramsClass framsClass, int prefInputs,
    63                         int prefOutput, int prefLocation, int visualHints,
    64                         int[] symbolGlymph) {
     76                                          int prefOutput, int prefLocation, int visualHints,
     77                                          int[] symbolGlymph) {
    6578                super();
    6679                this.framsClass = framsClass;
     
    113126         *
    114127         * @return 0 if the object doesn't need any assignment to the body element.
    115          * 1 = it likes to be attached to the Part ( @see
    116          * Neuro::attachToPart() )
    117          * 2 = the object prefers to have the Joint ( @see
    118          * Neuro::attachToJoint() )
     128         *         1 = it likes to be attached to the Part ( @see
     129         *         Neuro::attachToPart() )
     130         *         2 = the object prefers to have the Joint ( @see
     131         *         Neuro::attachToJoint() )
    119132         */
    120133        int getPreferredLocation() {
     
    170183        public String toString() {
    171184                StringBuilder sb = new StringBuilder();
    172                 sb.append("NeuroClass [getId=" + framsClass.getId() + ", getName="
    173                                 + framsClass.getName() + ", description="
    174                                 + framsClass.getDescription() + ", groups#="
    175                                 + framsClass.getGroupCount() + ", prefInputs=" + prefInputs
    176                                 + ", prefOutput=" + prefOutput + ", prefLocation="
    177                                 + prefLocation + ", visualHints=" + visualHints
    178                                 + ", symbolGlymph=" + Arrays.toString(symbolGlymph)
    179                                 + ", paramList={");
     185                sb.append("NeuroClass [getId=").append(framsClass.getId())
     186                                .append(", getName=").append(framsClass.getName())
     187                                .append(", description=").append(framsClass.getDescription())
     188                                .append(", groups#=").append(framsClass.getGroupCount())
     189                                .append(", prefInputs=").append(prefInputs)
     190                                .append(", prefOutput=").append(prefOutput)
     191                                .append(", prefLocation=").append(prefLocation)
     192                                .append(", visualHints=").append(visualHints)
     193                                .append(", symbolGlymph=").append(Arrays.toString(symbolGlymph));
     194
     195                sb.append(", paramList={");
    180196                for (int i = 0; i < framsClass.getParamCount(); i++) {
    181197                        sb.append("\n");
    182                         sb.append(framsClass.getParamEntry(i).toString());
     198                        sb.append(framsClass.getParamEntry(i, Param.class).toString());
    183199                }
    184200                sb.append("\n}]");
  • java/main/src/main/java/com/framsticks/model/BaseJoint.java

    r78 r84  
    11package com.framsticks.model;
    22
    3 import com.framsticks.util.Point3d;
     3import com.framsticks.util.math.Point3d;
    44
    55/**
  • java/main/src/main/java/com/framsticks/model/BasePart.java

    r79 r84  
    11package com.framsticks.model;
    22
    3 import com.framsticks.util.Orientation;
    4 import com.framsticks.util.Point3d;
     3import com.framsticks.util.math.Orientation;
     4import com.framsticks.util.math.Point3d;
    55
    66/**
  • java/main/src/main/java/com/framsticks/model/Creature.java

    r79 r84  
    22
    33import com.framsticks.params.FramsClass;
    4 import com.framsticks.util.Orientation;
    5 import com.framsticks.util.Point3d;
     4import com.framsticks.util.math.Point3d;
    65
    76import java.util.ArrayList;
  • java/main/src/main/java/com/framsticks/model/Genotype.java

    r79 r84  
    22
    33
    4 import org.apache.log4j.Logger;
     4// import org.apache.log4j.Logger;
    55
    66public class Genotype extends Model {
    7         private final static Logger LOGGER = Logger.getLogger(Genotype.class);
     7        // private final static Logger log = Logger.getLogger(Genotype.class);
    88
    99        public String name;
  • java/main/src/main/java/com/framsticks/model/Joint.java

    r78 r84  
    11package com.framsticks.model;
    2 
    3 import com.framsticks.util.Point3d;
    42
    53/**
  • java/main/src/main/java/com/framsticks/model/MechJoint.java

    r78 r84  
    11package com.framsticks.model;
    2 
    3 import com.framsticks.util.Point3d;
    42
    53/**
  • java/main/src/main/java/com/framsticks/model/MechPart.java

    r79 r84  
    11package com.framsticks.model;
    22
    3 import com.framsticks.util.Orientation;
    4 import com.framsticks.util.Point3d;
     3import com.framsticks.util.math.Point3d;
    54
    65/*
  • java/main/src/main/java/com/framsticks/model/Model.java

    r79 r84  
    11package com.framsticks.model;
    22
    3 import com.framsticks.util.Casting;
    4 import com.framsticks.util.Containers;
    5 import com.framsticks.util.Orientation;
     3import com.framsticks.util.lang.Casting;
     4import com.framsticks.util.lang.Containers;
     5import com.framsticks.util.lang.IterableIterator;
     6import com.framsticks.util.math.Orientation;
    67import org.apache.log4j.Logger;
    78
     
    1516public class Model {
    1617
    17         private final static Logger LOGGER = Logger.getLogger(Model.class);
     18        private final static Logger log = Logger.getLogger(Model.class);
    1819
    1920        public Double startingEnergy;
     
    5354                Model f0Genotype = Casting.tryCast(Model.class, i.next());
    5455                if (f0Genotype == null) {
    55                         LOGGER.fatal("first object is not a Model");
     56                        log.fatal("first object is not a Model");
    5657                        return null;
    5758                }
    58                 while (i.hasNext()) {
    59                         Object object = i.next();
     59                for (Object object : new IterableIterator<Object>(i)) {
    6060                        if (object instanceof Joint) {
    6161                                f0Genotype.joints.add((Joint)object);
     
    7070                                continue;
    7171                        }
    72                         LOGGER.error("invalid class: " + object.getClass().getCanonicalName());
     72                        log.error("invalid class: " + object.getClass().getCanonicalName());
    7373                }
    7474
  • java/main/src/main/java/com/framsticks/model/Neuro.java

    r78 r84  
    11package com.framsticks.model;
    22
    3 import com.framsticks.util.Point3d;
     3import com.framsticks.util.math.Point3d;
    44
    55/**
  • java/main/src/main/java/com/framsticks/model/Package.java

    r79 r84  
    11package com.framsticks.model;
    22
    3 import com.framsticks.params.FramsClass;
    43import com.framsticks.params.Registry;
    5 import com.framsticks.util.Orientation;
    6 import com.framsticks.util.Point3d;
    74
    85/**
  • java/main/src/main/java/com/framsticks/model/Part.java

    r79 r84  
    22
    33
    4 import com.framsticks.util.Point3d;
     4import com.framsticks.util.math.Point3d;
    55
    66/**
  • java/main/src/main/java/com/framsticks/observers/Endpoint.java

    r77 r84  
    55import com.framsticks.core.Path;
    66import com.framsticks.params.FramsClass;
    7 import com.framsticks.portals.PortalEndpoint;
    87import com.framsticks.core.ListChange;
    9 import com.framsticks.util.Dispatcher;
     8import com.framsticks.util.dispatching.Dispatcher;
    109import org.apache.log4j.Logger;
    1110
     
    1413 */
    1514public class Endpoint implements Dispatcher, InstanceListener {
    16     private final static Logger LOGGER = Logger.getLogger(PortalEndpoint.class.getName());
     15        private final static Logger log = Logger.getLogger(Endpoint.class.getName());
    1716
    18     protected Instance instance;
    19     protected Observer observer;
    20     protected String name;
     17        protected Instance instance;
     18        protected Observer observer;
     19        protected String name;
    2120
    22     public Endpoint() {
    23     }
     21        public Endpoint() {
     22        }
    2423
    25     public final void configurePublic(Observer observer, Instance instance, String name) {
    26         assert instance != null;
    27         this.name = name;
    28         this.observer = observer;
    29         this.instance = instance;
    30         instance.addListener(this);
    31         configure();
    32     }
     24        public final void configurePublic(Observer observer, Instance instance, String name) {
     25                assert instance != null;
     26                this.name = name;
     27                this.observer = observer;
     28                this.instance = instance;
     29                instance.addListener(this);
     30        }
    3331
    34     protected void configure() {
     32        public void start() {
     33                instance.start();
     34        }
    3535
    36     }
     36        @Override
     37        public void onListChange(Path path, ListChange change) {
     38                log.info("change " + change + " in " + path);
     39        }
    3740
    38     @Override
    39     public void onListChange(Path path, ListChange change) {
    40         LOGGER.info("change " + change + " in " + path);
    41     }
     41        @Override
     42        public void onRun(Exception e) {
     43        }
    4244
    43     @Override
    44     public void onRun(Exception e) {
    45     }
     45        @Override
     46        public void onStop(Exception e) {
     47        }
    4648
    47     @Override
    48     public void onStop(Exception e) {
    49     }
     49        @Override
     50        public void onFetch(Path path) {
     51                log.trace("fetched " + path);
     52        }
    5053
    51     @Override
    52     public String toString() {
    53         return instance.toString();
    54     }
     54        @Override
     55        public String toString() {
     56                return instance.toString();
     57        }
    5558
    56     public final Instance getInstance() {
    57         return instance;
    58     }
     59        public final Instance getInstance() {
     60                return instance;
     61        }
    5962
    60     @Override
    61     public final boolean isActive() {
    62         return instance.isActive();
    63     }
     63        @Override
     64        public final boolean isActive() {
     65                return instance.isActive();
     66        }
    6467
    65     @Override
    66     public final void invokeLater(Runnable runnable) {
    67         instance.invokeLater(runnable);
    68     }
     68        @Override
     69        public final void invokeLater(Runnable runnable) {
     70                instance.invokeLater(runnable);
     71        }
    6972
    70     public Observer getObserver() {
    71         return observer;
    72     }
     73        public Observer getObserver() {
     74                return observer;
     75        }
    7376
    74     public final String getName() {
    75         return name;
    76     }
     77        public final String getName() {
     78                return name;
     79        }
    7780
    78     public static void constructFramsClass(FramsClass.Constructor constructor) {
    79         constructor.method("getName").method("getInstance");
    80     }
     81        public static void constructFramsClass(FramsClass.Constructor constructor) {
     82                constructor.method("getName").method("getInstance");
     83        }
     84
    8185}
  • java/main/src/main/java/com/framsticks/observers/Observer.java

    r78 r84  
    33import com.framsticks.core.Entity;
    44import com.framsticks.core.Instance;
    5 import com.framsticks.core.Parameters;
    65import com.framsticks.core.Program;
    76import com.framsticks.params.FramsClass;
    8 import com.framsticks.util.Casting;
     7import com.framsticks.util.lang.Casting;
    98import org.apache.commons.configuration.Configuration;
    109import org.apache.log4j.Logger;
     
    1716public abstract class Observer extends Entity {
    1817
    19     private final static Logger LOGGER = Logger.getLogger(Observer.class.getName());
     18        private final static Logger log = Logger.getLogger(Observer.class.getName());
    2019
    21     public Observer(Parameters parameters) {
    22         super(parameters);
    23     }
     20        public Observer() {
     21        }
    2422
    25     protected final Map<String, Endpoint> endpoints = new HashMap<String, Endpoint>();
     23        protected final Map<String, Endpoint> endpoints = new HashMap<String, Endpoint>();
    2624
    27     protected Endpoint createEndpoint() {
    28         return new Endpoint();
    29     }
     25        protected Endpoint createEndpoint() {
     26                return new Endpoint();
     27        }
    3028
    31     @Override
    32     protected void configure() throws Exception {
    33         super.configure();
    34         for (String name : config.getStringArray("endpoints")) {
    35             if (getEndpoints().containsKey(name)) {
    36                 LOGGER.fatal("observer already contains endpoint named: " + name);
    37                 continue;
    38             }
    39             Configuration c = config.subset("endpoints." + name);
    40             Parameters p = new Parameters(c.subset("entity"), name, null, null);
    41             Entity e = Program.configureEntity(p);
    42             Instance i = Casting.tryCast(Instance.class, e);
    43             if (i == null) {
    44                 LOGGER.error("failed to create instance: " + p);
    45                 continue;
    46             }
    47             i.configurePublic();
    48             Endpoint endpoint = createEndpoint();
    49             endpoint.configurePublic(this, i, name);
    50             getEndpoints().put(name, endpoint);
    51             LOGGER.info("instance " + i + " was added to " + Observer.this);
    52         }
    53     }
     29        @Override
     30        public void configure(Configuration config) {
     31                super.configure(config);
     32                for (String n : config.getStringArray("endpoints")) {
     33                        if (getEndpoints().containsKey(n)) {
     34                                log.fatal("observer already contains endpoint named: " + n);
     35                                continue;
     36                        }
     37                        Configuration instanceConfig = config.subset("endpoints." + n).subset("entity");
     38                        Instance i = Casting.tryCast(Instance.class, Program.configureEntity(instanceConfig));
     39                        if (i == null) {
     40                                log.error("failed to create instance: ");
     41                                continue;
     42                        }
     43                        i.setName(n);
     44                        i.configure(instanceConfig);
     45                        addEndpointForInstance(i);
     46                }
     47        }
    5448
    55     @Override
    56     protected void run() {
    57         super.run();
    58         for (Endpoint e : getEndpoints().values()) {
    59             e.getInstance().start();
    60         }
    61     }
     49        public Endpoint addEndpointForInstance(Instance instance) {
     50                Endpoint endpoint = createEndpoint();
     51                endpoint.configurePublic(this, instance, instance.getName());
     52                getEndpoints().put(instance.getName(), endpoint);
     53                log.info("instance " + instance + " was added to " + this + " as " + instance.getName());
     54                return endpoint;
     55        };
     56
     57        @Override
     58        protected void run() {
     59                super.run();
     60                for (Endpoint e : getEndpoints().values()) {
     61                        e.start();
     62                }
     63        }
    6264
    6365
    64     public Map<String, Endpoint> getEndpoints() {
    65         return endpoints;
    66     }
     66        public Map<String, Endpoint> getEndpoints() {
     67                return endpoints;
     68        }
    6769
    68     public static void constructFramsClass(FramsClass.Constructor constructor) {
    69         constructor.method("getEndpoints");
    70     }
     70        public static void constructFramsClass(FramsClass.Constructor constructor) {
     71                constructor.method("getEndpoints");
     72        }
    7173
    7274
  • java/main/src/main/java/com/framsticks/params/AccessInterface.java

    r78 r84  
    22
    33import java.util.Collection;
    4 import java.util.List;
    54
    65
     
    98 * framsticks. In descriptions of methods names "property" and "parameter" are
    109 * synonyms.
    11  * 
     10 *
    1211 * @author Jarek Szymczak <name.surname@gmail.com> (please replace name and
    1312 *         surname with my personal data)
     
    2019
    2120        String getId();
    22 
    23 
    24     /*
    25         String getName();
    26 
    27     * This method provides more verbose (but not strict) names of classes.
    28      *
    29      * e.g. for a list it will return l Type, and if name of FramsClass missing,
    30      * it's id will be used
    31      *
    32     String getNiceName();
    33     */
    3421
    3522        Param getGroupMember(int gi, int n);
     
    4431        <T> T get(String id, Class<T> type);
    4532
    46         <T> T get(Param param, Class<T> type);
     33        <T> T get(ValueParam param, Class<T> type);
    4734
    4835        <T> int set(int i, T value);
     
    5037        <T> int set(String id, T value);
    5138
    52         <T> int set(Param param, T value);
     39        <T> int set(ValueParam param, T value);
    5340
    5441        void setDefault(boolean numericOnly);
     
    7158
    7259        /**
    73          * Return as a single line String.
    74          *
    75          * @param omitDefaultValues
    76          *            the omit default values
    77          * @return the string
    78          */
    79         String save2(boolean omitDefaultValues);
    80 
    81         /**
    8260         * Removes all the properties values.
    8361         */
    8462        void clearValues();
    8563
    86         void select(Object object);
     64        AccessInterface select(Object object);
    8765
    8866        Object getSelected();
     
    9068        AccessInterface cloneAccess();
    9169
    92     Object createAccessee();
     70        Object createAccessee();
    9371
    94     Collection<Param> getParams();
     72        Collection<Param> getParams();
    9573
    96     FramsClass getFramsClass();
     74        FramsClass getFramsClass();
    9775
    9876
  • java/main/src/main/java/com/framsticks/params/ArrayListAccess.java

    r77 r84  
    11package com.framsticks.params;
    22
    3 import com.framsticks.util.Numbers;
     3import com.framsticks.util.lang.Numbers;
    44
    55import java.util.ArrayList;
     
    1313public class ArrayListAccess extends ListAccess {
    1414
    15     List list;
     15        List<Object> list;
    1616
     17        public ArrayListAccess(AccessInterface elementAccess) {
     18                super(elementAccess);
     19        }
    1720
    18     public ArrayListAccess(AccessInterface elementAccess) {
    19         super(elementAccess);
    20     }
     21        @Override
     22        public ArrayListAccess cloneAccess() {
     23                return new ArrayListAccess(elementAccess.cloneAccess());
     24        }
    2125
    22     @Override
    23     public ArrayListAccess cloneAccess() {
    24         return new ArrayListAccess(elementAccess.cloneAccess());
    25     }
     26        @Override
     27        public List<?> createAccessee() {
     28                return new ArrayList<Object>();
     29        }
    2630
    27     @Override
    28     public List createAccessee() {
    29         return new ArrayList();
    30     }
     31        @Override
     32        public Param getParam(int i) {
     33                return new ParamBuilder().setId(Integer.toString(i)).setName(elementAccess.getId()).setType("o " + elementAccess.getId()).build();
     34        }
    3135
    32     @Override
    33     public Param getParam(int i) {
    34         return new ParamBuilder().setId(Integer.toString(i)).setName(elementAccess.getId()).setType("o " + elementAccess.getId()).build();
    35     }
     36        @Override
     37        public Param getParam(String id) {
     38                Integer i = Numbers.parse(id, Integer.class);
     39                return (i == null ? null : getParam(i));
     40        }
    3641
    37     @Override
    38     public Param getParam(String id) {
    39         Integer i = Numbers.parse(id, Integer.class);
    40         return (i == null ? null : getParam(i));
    41     }
     42        @Override
     43        public String getId() {
     44                return "l " + elementAccess.getId();
     45        }
    4246
    43     @Override
    44     public String getId() {
    45         return "l " + elementAccess.getId();
    46     }
     47        @Override
     48        public int getParamCount() {
     49                return list.size();
     50        }
    4751
    48     @Override
    49     public int getParamCount() {
    50         return list.size();
    51     }
     52        @Override
     53        public <T> T get(int i, Class<T> type) {
     54                if (i < list.size()) {
     55                        return type.cast(list.get(i));
     56                }
     57                return null;
     58        }
    5259
    53     @Override
    54     public <T> T get(int i, Class<T> type) {
    55         if (i < list.size()) {
    56             return type.cast(list.get(i));
    57         }
    58         return null;
    59     }
     60        @Override
     61        public <T> T get(String id, Class<T> type) {
     62                return get(Integer.parseInt(id), type);
     63        }
    6064
    61     @Override
    62     public <T> T get(String id, Class<T> type) {
    63         return get(Integer.parseInt(id), type);
    64     }
     65        @Override
     66        public <T> T get(ValueParam param, Class<T> type) {
     67                return get(param.getId(), type);
     68        }
    6569
    66     @Override
    67     public <T> T get(Param param, Class<T> type) {
    68         return get(param.getId(), type);
    69     }
     70        @Override
     71        public <T> int set(int i, T value) {
     72                while (i >= list.size()) {
     73                        list.add(null);
     74                }
     75                list.set(i, value);
     76                return 0;
     77        }
    7078
    71     @Override
    72     public <T> int set(int i, T value) {
    73         while (i >= list.size()) {
    74             list.add(null);
    75         }
    76         list.set(i, value);
    77         return 0;
    78     }
     79        @Override
     80        public <T> int set(String id, T value) {
     81                return set(Integer.parseInt(id), value);
     82        }
    7983
    80     @Override
    81     public <T> int set(String id, T value) {
    82         return set(Integer.parseInt(id), value);
    83     }
     84        @Override
     85        public <T> int set(ValueParam param, T value) {
     86                return set(param.getId(), value);
     87        }
    8488
    85     @Override
    86     public <T> int set(Param param, T value) {
    87         return set(param.getId(), value);
    88     }
     89        @Override
     90        public void clearValues() {
     91                list.clear();
     92        }
    8993
    90     @Override
    91     public void clearValues() {
    92         list.clear();
    93     }
     94        /** covariant */
     95        @Override
     96        public List<Object> getSelected() {
     97                return list;
     98        }
    9499
    95     /** covariant */
    96     @Override
    97     public List getSelected() {
    98         return list;
    99     }
     100        @SuppressWarnings("unchecked")
     101        @Override
     102        public ArrayListAccess select(Object object) {
     103                list = (List<Object>) object;
     104                return this;
     105        }
    100106
    101     @Override
    102     public void select(Object object) {
    103         list = (List)object;
    104     }
     107        @Override
     108        public String computeIdentifierFor(Object selected) {
     109                return Integer.toString(list.size());
     110        }
    105111
    106     @Override
    107     public String computeIdentifierFor(Object selected) {
    108         return Integer.toString(list.size());
    109     }
    110 
    111     @Override
    112     public Collection<Param> getParams() {
    113         List<Param> result = new LinkedList<Param>();
    114         if (list == null) {
    115             return result;
    116         }
    117         for (int i = 0; i < list.size(); ++i) {
    118             result.add(getParam(i));
    119         }
    120         return result;
    121     }
     112        @Override
     113        public Collection<Param> getParams() {
     114                List<Param> result = new LinkedList<Param>();
     115                if (list == null) {
     116                        return result;
     117                }
     118                for (int i = 0; i < list.size(); ++i) {
     119                        result.add(getParam(i));
     120                }
     121                return result;
     122        }
    122123
    123124
  • java/main/src/main/java/com/framsticks/params/CastFailure.java

    r77 r84  
    55 */
    66public class CastFailure extends Exception {
     7
     8        /**
     9         *
     10         */
     11        private static final long serialVersionUID = 2117813329617553801L;
     12
    713}
  • java/main/src/main/java/com/framsticks/params/Flags.java

    r77 r84  
    33import java.lang.reflect.Field;
    44import org.apache.log4j.Logger;
     5
     6import com.framsticks.util.lang.Delimeted;
    57
    68/**
     
    911 *
    1012 * Based on c++ defines located in: cpp/gdk/param.h
    11  * 
     13 *
    1214 * @author Jarek Szymczak <name.surname@gmail.com>
    1315 * (please replace name and surname with my personal data)
     
    1719public final class Flags {
    1820
    19         private final static Logger logger = Logger.getLogger(Flags.class.getName());
    20 
     21        private final static Logger log = Logger.getLogger(Flags.class.getName());
    2122
    2223        public static final int READONLY = 1;
     
    4849        public static final int PSET_HITMAX = 8;
    4950
     51        public static String write(int flags, String empty) {
     52                Delimeted d = new Delimeted("+", empty);
     53                try {
     54                        for (Field f : Flags.class.getDeclaredFields()) {
     55                                if (f.getType() != int.class) {
     56                                        continue;
     57                                }
     58                                if ((flags & f.getInt(null)) != 0) {
     59                                        d.append(f.getName());
     60                                }
     61                        }
     62                } catch (IllegalArgumentException e) {
     63                        e.printStackTrace();
     64                } catch (IllegalAccessException e) {
     65                        e.printStackTrace();
     66                }
     67                return d.build();
     68        }
     69
    5070        public static Integer read(String flags) {
    5171                Integer allFlags = 0;
     
    5979                                        allFlags |= Integer.parseInt(field.get(null).toString());
    6080                                } catch (SecurityException e) {
    61                                         logger.warn("security exception was thrown while trying to read flag ("
    62                                                         + flag + ")");
     81                                        log.warn("security exception was thrown while trying to read flag (" + flag + ")");
    6382                                } catch (NoSuchFieldException e) {
    64                                         logger.warn("selected flag is not known (" + flag + ")");
     83                                        log.warn("selected flag is not known (" + flag + ")");
    6584                                } catch (IllegalArgumentException e) {
    66                                         logger.warn("selected flag is not known (" + flag + ")");
     85                                        log.warn("selected flag is not known (" + flag + ")");
    6786                                } catch (IllegalAccessException e) {
    68                                         logger.warn("selected flag is not known (" + flag + ")");
     87                                        log.warn("selected flag is not known (" + flag + ")");
    6988                                }
    7089                        }
  • java/main/src/main/java/com/framsticks/params/FramsClass.java

    r78 r84  
    11package com.framsticks.params;
    22
    3 import com.framsticks.params.types.CompositeParam;
    4 import com.framsticks.params.types.DecimalParam;
    5 import com.framsticks.params.types.FloatParam;
    63import com.framsticks.params.types.StringParam;
    74import com.framsticks.parsers.FileSource;
    85import com.framsticks.parsers.Loaders;
    9 import com.framsticks.util.Casting;
     6import com.framsticks.util.lang.Casting;
     7
    108import org.apache.log4j.Logger;
    119
    12 import javax.lang.model.element.TypeElement;
    1310import java.io.InputStream;
    1411import java.lang.reflect.*;
    1512import java.util.*;
    16 import java.util.List;
    1713
    1814/**
     
    3026public final class FramsClass {
    3127
    32     private final static Logger LOGGER = Logger.getLogger(FramsClass.class.getName());
    33 
    34     /**
    35       * The Class which represents group.
    36       */
     28        private final static Logger log = Logger.getLogger(FramsClass.class.getName());
     29
     30        /**
     31          * The Class which represents group.
     32          */
    3733
    3834        /** The offset of the parameter (applied for newly added parameter). */
     
    7571        /**
    7672         * Adds new param entry.
    77          * 
     73         *
    7874         * @param param
    7975         *            the new param entry
     
    113109        /**
    114110         * Gets the group member.
    115          * 
     111         *
    116112         * @param gi
    117113         *            the offset of group
     
    123119                if (gi < 0 || pi < 0 || gi >= groups.size()) {
    124120                        return null;
    125         }
     121                }
    126122                Group group = groups.get(gi);
    127123                return (group != null ? group.getProperty(pi) : null);
     
    130126        /**
    131127         * Gets the group getName.
    132          * 
     128         *
    133129         * @param gi
    134130         *            the offset of group
     
    149145        }
    150146
    151     public String getNiceName() {
    152         return name != null ? name : id;
    153     }
     147        public String getNiceName() {
     148                return name != null ? name : id;
     149        }
    154150
    155151        /**
    156152         * Gets the param entry.
    157          * 
     153         *
    158154         * @param i
    159155         *            the offset of parameter
    160156         * @return the param entry
    161157         */
    162         public Param getParamEntry(int i) {
     158        public <T extends Param> T getParamEntry(int i, Class<T> type) {
    163159                if (i < 0 || i >= paramList.size()) {
    164160                        return null;
    165161                }
    166                 return paramList.get(i);
     162                return Casting.tryCast(type, paramList.get(i));
    167163        }
    168164
    169165        /**
    170166         * Gets the param entry.
    171          * 
     167         *
    172168         * @param id
    173169         *            the getId of parameter
    174170         * @return the param entry
    175171         */
    176         public Param getParamEntry(String id) {
    177                 return paramEntryMap.get(id);
     172        public <T extends Param> T getParamEntry(String id, Class<T> type) {
     173                return Casting.tryCast(type, paramEntryMap.get(id));
    178174        }
    179175
     
    206202        }
    207203
    208     public static String getParamTypeForNativeType(Type type) {
    209         if (type instanceof ParameterizedType) {
    210             ParameterizedType p = (ParameterizedType) type;
    211             Type rawType = p.getRawType();
    212             if (rawType.equals(Map.class)) {
    213                 Type containedType = p.getActualTypeArguments()[1];
    214                 //TODO uid should be passed along during construction
    215                 if (containedType instanceof Class) {
    216                     return "l " + ((Class) containedType).getCanonicalName() + " name";
    217                 }
    218             }
     204        public static String getParamTypeForNativeType(Type type) {
     205                if (type instanceof ParameterizedType) {
     206                        ParameterizedType p = (ParameterizedType) type;
     207                        Type rawType = p.getRawType();
     208                        if (rawType.equals(Map.class)) {
     209                                Type containedType = p.getActualTypeArguments()[1];
     210                                //TODO uid should be passed along during construction
     211                                if (containedType instanceof Class) {
     212                                        return "l " + ((Class<?>) containedType).getCanonicalName() + " name";
     213                                }
     214                        }
    219215                        if (rawType.equals(List.class)) {
    220216                                Type containedType = p.getActualTypeArguments()[0];
    221217                                if (containedType instanceof Class) {
    222                                         return "l " + ((Class) containedType).getCanonicalName();
    223                                 }
    224                         }
    225             return null;
    226         }
    227 
    228         if (type.equals(Integer.class)) {
    229             return "d";
    230         }
    231         if (type.equals(String.class)) {
    232             return "s";
    233         }
    234         if (type.equals(Double.class)) {
    235             return "f";
    236         }
    237         if (type instanceof Class) {
    238             return "o " + ((Class) type).getCanonicalName();
    239         }
    240         return null;
    241     }
    242 
    243     public static final String GENERATE_HELP_PREFIX = "automatically generated from: ";
     218                                        return "l " + ((Class<?>) containedType).getCanonicalName();
     219                                }
     220                        }
     221                        return null;
     222                }
     223
     224                if (type.equals(Integer.class)) {
     225                        return "d";
     226                }
     227                if (type.equals(String.class)) {
     228                        return "s";
     229                }
     230                if (type.equals(Double.class)) {
     231                        return "f";
     232                }
     233                if (type instanceof Class) {
     234                        return "o " + ((Class<?>) type).getCanonicalName();
     235                }
     236                return null;
     237        }
     238
     239        public static final String GENERATE_HELP_PREFIX = "automatically generated from: ";
    244240
    245241        public static FramsClass readFromStream(InputStream stream) {
     
    248244
    249245        public static class Constructor {
    250         protected final FramsClass result;
    251         protected Class currentClass;
    252         public Constructor(Class src, String name) {
    253             result = new FramsClass(name, name, GENERATE_HELP_PREFIX + src.toString());
    254             currentClass = src;
    255             while (currentClass != null) {
    256                 try {
    257                     currentClass.getMethod("constructFramsClass", Constructor.class).invoke(null, this);
    258                 } catch (Exception ignored) {
    259                 }
    260                 currentClass = currentClass.getSuperclass();
    261             }
     246                protected final FramsClass result;
     247                protected Class<?> currentClass;
     248
     249                public Constructor(Class<?> src, String name) {
     250                        result = new FramsClass(name, name, GENERATE_HELP_PREFIX + src.toString());
    262251                        currentClass = src;
    263         }
    264 
    265         public final FramsClass getResult() {
    266             return result;
    267         }
     252                        while (currentClass != null) {
     253                                try {
     254                                        currentClass.getMethod("constructFramsClass", Constructor.class).invoke(null, this);
     255                                } catch (Exception ignored) {
     256                                }
     257                                currentClass = currentClass.getSuperclass();
     258                        }
     259                        currentClass = src;
     260                }
     261
     262                public final FramsClass getResult() {
     263                        return result;
     264                }
    268265
    269266                public Constructor allFields() {
     
    274271                }
    275272
    276         public Constructor method(String name, Class<?> ... arguments) {
    277             try {
    278                 Method method = currentClass.getMethod(name, arguments);
    279                 if (!Modifier.isPublic(method.getModifiers())) {
    280                     return this;
    281                 }
    282                 String returnParamClass = getParamTypeForNativeType(method.getGenericReturnType());
    283                 if (returnParamClass == null) {
    284                     return this;
    285                 }
    286                 Class[] args = method.getParameterTypes();
    287                 if (args.length == 0) {
    288                     if (method.getName().startsWith("get")) {
    289                         String fieldName = method.getName().substring(3, 4).toLowerCase() + method.getName().substring(4);
    290                         Param param = new ParamBuilder().setType(returnParamClass).setName(fieldName).setId(fieldName).setHelp(GENERATE_HELP_PREFIX + method.toString()).build();
    291                         assert param != null;
    292                         result.append(param);
    293                         return this;
    294                     }
    295                     return this;
    296                 }
    297                 return this;
    298             } catch (NoSuchMethodException e) {
    299                 LOGGER.fatal("method " + name + " was not found in " + currentClass.toString());
    300             }
    301             return this;
    302         }
    303         public Constructor field(String name) {
    304             try {
    305                 Field field = currentClass.getField(name);
    306                 if (!Modifier.isPublic(field.getModifiers())) {
    307                     return this;
    308                 }
    309                 String paramClass = getParamTypeForNativeType(field.getGenericType());
    310                 if (paramClass == null) {
    311                     return this;
    312                 }
    313                 Param param = new ParamBuilder().setType(paramClass).setName(field.getName()).setId(field.getName()).setHelp(GENERATE_HELP_PREFIX + field.toString()).build();
    314                 assert param != null;
    315                 result.append(param);
    316                 return this;
    317             } catch (NoSuchFieldException e) {
    318                 LOGGER.fatal("field " + name + " was not found in " + currentClass.toString());
    319             }
    320             return this;
    321         }
    322     }
     273                public Constructor method(String name, Class<?> ... arguments) {
     274                        try {
     275                                Method method = currentClass.getMethod(name, arguments);
     276                                if (!Modifier.isPublic(method.getModifiers())) {
     277                                        return this;
     278                                }
     279                                String returnParamClass = getParamTypeForNativeType(method.getGenericReturnType());
     280                                if (returnParamClass == null) {
     281                                        return this;
     282                                }
     283                                Class<?>[] args = method.getParameterTypes();
     284                                if (args.length == 0) {
     285                                        if (method.getName().startsWith("get")) {
     286                                                String fieldName = method.getName().substring(3, 4).toLowerCase() + method.getName().substring(4);
     287                                                Param param = new ParamBuilder().setType(returnParamClass).setName(fieldName).setId(fieldName).setHelp(GENERATE_HELP_PREFIX + method.toString()).build();
     288                                                assert param != null;
     289                                                result.append(param);
     290                                                return this;
     291                                        }
     292                                        return this;
     293                                }
     294                                return this;
     295                        } catch (NoSuchMethodException e) {
     296                                log.fatal("method " + name + " was not found in " + currentClass.toString());
     297                        }
     298                        return this;
     299                }
     300                public Constructor field(String name) {
     301                        try {
     302                                Field field = currentClass.getField(name);
     303                                if (!Modifier.isPublic(field.getModifiers())) {
     304                                        return this;
     305                                }
     306                                String paramClass = getParamTypeForNativeType(field.getGenericType());
     307                                if (paramClass == null) {
     308                                        return this;
     309                                }
     310                                Param param = new ParamBuilder().setType(paramClass).setName(field.getName()).setId(field.getName()).setHelp(GENERATE_HELP_PREFIX + field.toString()).build();
     311                                assert param != null;
     312                                result.append(param);
     313                                return this;
     314                        } catch (NoSuchFieldException e) {
     315                                log.fatal("field " + name + " was not found in " + currentClass.toString());
     316                        }
     317                        return this;
     318                }
     319        }
    323320}
  • java/main/src/main/java/com/framsticks/params/ListAccess.java

    r78 r84  
    11package com.framsticks.params;
    22
    3 import com.framsticks.core.Node;
    4 import com.framsticks.core.Path;
    5 import com.framsticks.params.types.CompositeParam;
    63
    7 import java.util.List;
     4
     5import static com.framsticks.util.lang.Containers.filterInstanceof;
    86
    97/**
     
    1816        }
    1917
    20     @Override
     18        @Override
    2119        public Param getGroupMember(int gi, int n) {
    2220                return null;
     
    5250
    5351        @Override
    54     public void save(SinkInterface sink) {
    55         for (Param p : getParams()) {
    56             assert p instanceof CompositeParam;
    57             CompositeParam childParam = (CompositeParam)p;
    58             Object child = get(childParam, Object.class);
    59             //this is probably an assertion
    60             assert child != null;
    61             elementAccess.select(child);
    62             elementAccess.save(sink);
    63         }
    64     }
     52        public void save(SinkInterface sink) {
     53                for (CompositeParam p : filterInstanceof(getParams(), CompositeParam.class)) {
     54                        Object child = get(p, Object.class);
     55                        //this is probably an assertion
     56                        assert child != null;
     57                        elementAccess.select(child);
     58                        elementAccess.save(sink);
     59                }
     60        }
    6561
    6662        @Override
    6763        public void load(SourceInterface stream) throws Exception {
    68         }
    69 
    70         @Override
    71         public String save2(boolean omitDefaultValues) {
    72                 return null;
    7364        }
    7465
     
    7768        }
    7869
    79     public abstract String computeIdentifierFor(Object selected);
     70        public abstract String computeIdentifierFor(Object selected);
    8071
    81     @Override
    82     public final FramsClass getFramsClass() {
    83         return elementAccess.getFramsClass();
    84     }
     72        @Override
     73        public final FramsClass getFramsClass() {
     74                return elementAccess.getFramsClass();
     75        }
    8576
    8677}
  • java/main/src/main/java/com/framsticks/params/ListSink.java

    r77 r84  
    88 */
    99public class ListSink implements SinkInterface {
    10     protected final List<String> out;
    11     protected StringBuilder lineBuilder = new StringBuilder();
     10        protected final List<String> out;
     11        protected StringBuilder lineBuilder = new StringBuilder();
    1212
    13     public ListSink(List<String> out) {
    14         this.out = out;
    15     }
     13        public ListSink(List<String> out) {
     14                this.out = out;
     15        }
    1616
    17     public ListSink() {
    18         this.out = new LinkedList<String>();
    19     }
     17        public ListSink() {
     18                this.out = new LinkedList<String>();
     19        }
    2020
    21     public final List<String> getOut() {
    22         return out;
    23     }
     21        public final List<String> getOut() {
     22                return out;
     23        }
    2424
    2525
    26     @Override
    27     public SinkInterface print(String str) {
    28         lineBuilder.append(str);
    29         return this;
    30     }
     26        @Override
     27        public SinkInterface print(String str) {
     28                lineBuilder.append(str);
     29                return this;
     30        }
    3131
    32     @Override
    33     public SinkInterface print(Object obj) {
    34         lineBuilder.append(obj);
    35         return this;
    36     }
     32        @Override
     33        public SinkInterface print(Object obj) {
     34                lineBuilder.append(obj);
     35                return this;
     36        }
    3737
    38     @Override
    39     public void breakLine() {
    40         out.add(lineBuilder.toString());
    41         lineBuilder = new StringBuilder();
    42     }
     38        @Override
     39        public void breakLine() {
     40                out.add(lineBuilder.toString());
     41                lineBuilder = new StringBuilder();
     42        }
    4343
    44     @Override
    45     public void close() {
    46     }
     44        @Override
     45        public void close() {
     46        }
    4747}
  • java/main/src/main/java/com/framsticks/params/ListSource.java

    r77 r84  
    77
    88        private Iterator<String> iterator = null;
    9     private final List<String> source;
     9    //private final List<String> source;
    1010
    1111        public ListSource(List<String> source) {
    12         this.source = source;
     12        //this.source = source;
    1313        iterator = source.iterator();
    1414        }
  • java/main/src/main/java/com/framsticks/params/Param.java

    r78 r84  
    33import com.framsticks.params.types.DecimalParam;
    44import com.framsticks.params.types.StringParam;
    5 
    6 import java.util.HashMap;
    7 import java.util.Map;
    85
    96/**
     
    4239        protected Integer extra;
    4340
    44         /** The minimum allowed value of parameter. */
    45         protected Object min;
    46 
    47         /** The maximum allowed value of parameter. */
    48         protected Object max;
    49 
    50         /** The default value of parameter. */
    51         protected Object def;
    52 
    53 
    54 
    55         /**
    56          * The defaults used for Integer, Double and String classes, if the default
    57          * value of parameter is not explicitly given.
    58          */
    59         @SuppressWarnings("rawtypes")
    60         private Map<Class, Object> defaults = new HashMap<Class, Object>();
    61         // static initialization of defaults
    62         {
    63                 defaults.put(String.class, "");
    64                 defaults.put(Integer.class, 0);
    65                 defaults.put(Double.class, 0.0);
    66         }
    6741
    6842        public Param() {
     
    9468        }
    9569
    96     public abstract String getType();
     70        public abstract String getFramsTypeName();
    9771
    9872
     
    10175        }
    10276
    103 
    104     private <T> T tryCastAndReturn(Object value, Class<T> type) {
    105         if (value == null)
    106             return null;
    107         try {
    108             return type.cast(value);
    109         } catch (ClassCastException e) {
    110             throw new ClassCastException("property \"" + name
    111                     + "\" type is \"" + value.getClass().getName()
    112                     + "\", not \"" + type.getName() + "\"");
    113         }
    114     }
    115         /**
    116          * Gets the minimum value of parameter.
    117          *
    118          * @param <T> the generic getType which must be correctly specified by user
    119          * @param type the getType of variable, can be checked by
    120          * @return the minimum allowed value of parameter
    121          * @throws ClassCastException the class cast exception, thrown when given getType is incorrect
    122          */
    123         public <T> T getMin(Class<T> type) {
    124                 return tryCastAndReturn(min, type);
    125         }
    126 
    127         /**
    128          * Gets the maximum value of parameter.
    129          *
    130          * @param <T> the generic getType which must be correctly specified by user
    131          * @param type the getType of variable, can be checked by {@link #getStorageType()}
    132          * @return the maximum allowed value of parameter
    133          * @throws ClassCastException the class cast exception, thrown when given getType is incorrect
    134          */
    135         public <T> T getMax(Class<T> type) {
    136                 return tryCastAndReturn(max, type);
    137         }
    138 
    139         /**
    140          * Gets the default value of parameter.
    141          *
    142          * @param <T> the generic getType which must be correctly specified by user
    143          * @param type the getType of variable, can be checked by {@link #getStorageType()}
    144          * @return the default value of parameter
    145          * @throws ClassCastException the class cast exception, thrown when given getType is incorrect
    146          */
    147         public <T> T getDef(Class<T> type) throws ClassCastException {
    148                 return tryCastAndReturn(def, type);
    149         }
    15077
    15178        public Integer getExtra() {
     
    16693        }
    16794
    168         public boolean isEmptyAvailable() {
    169                 return false;
    170         }
    171 
    172         public abstract Class getStorageType();
     95        public abstract Class<?> getStorageType();
    17396
    17497        public boolean hasFlag(int flag) {
     
    17699        }
    177100
    178         public Object reassign(Object newValue, Object oldValue) throws CastFailure {
    179         if (newValue == null) {
    180             if (isEmptyAvailable()) {
    181                 return null;
    182             }
    183             throw new CastFailure();
    184         }
    185         try {
    186             return getStorageType().cast(newValue);
    187         } catch (ClassCastException ignored) {
    188             throw new CastFailure();
    189         }
    190     }
    191 
    192101        public boolean isUserHidden() {
    193102                return (flags & Flags.USERHIDDEN) != 0;
    194103        }
    195104
    196     public static FramsClass getFramsClass() {
    197         return new FramsClass("prop", "prop", null)
    198                 .append(new ParamBuilder().setId("name").setName("Name").setType(StringParam.class).build())
    199                 .append(new ParamBuilder().setId("id").setName("Id").setType(StringParam.class).build())
    200                 .append(new ParamBuilder().setId("type").setName("Type").setType(StringParam.class).build())
    201                 .append(new ParamBuilder().setId("help").setName("Help").setType(StringParam.class).build())
    202                 .append(new ParamBuilder().setId("flags").setName("Flags").setType(DecimalParam.class).build());
    203     }
     105        public static FramsClass getFramsClass() {
     106                return new FramsClass("prop", "prop", null)
     107                                .append(new ParamBuilder().setId("name").setName("Name").setType(StringParam.class).build())
     108                                .append(new ParamBuilder().setId("id").setName("Id").setType(StringParam.class).build())
     109                                .append(new ParamBuilder().setId("type").setName("Type").setType(StringParam.class).build())
     110                                .append(new ParamBuilder().setId("help").setName("Help").setType(StringParam.class).build())
     111                                .append(new ParamBuilder().setId("flags").setName("Flags").setType(DecimalParam.class).build());
     112        }
    204113
    205114}
  • java/main/src/main/java/com/framsticks/params/ParamBuilder.java

    r77 r84  
    22
    33import com.framsticks.params.types.*;
     4import com.framsticks.util.lang.Numbers;
     5
    46import org.apache.log4j.Logger;
    57
     
    911/**
    1012 * The class ParamBuilder helps building Param objects.
    11  * 
     13 *
    1214 * @author Mateusz Jarus <name.surname@gmail.com> (please replace name and
    1315 *         surname with my personal data)
     
    1719
    1820public class ParamBuilder {
    19         private final static Logger LOGGER = Logger.getLogger(ParamBuilder.class.getName());
     21        private final static Logger log = Logger.getLogger(ParamBuilder.class.getName());
    2022
    2123        private static final String ID_FIELD = "id";
     
    4850
    4951        /** The getType of parameter. */
    50         @SuppressWarnings("rawtypes")
    51         private Class paramType;
     52        private Class<? extends Param> paramType;
    5253
    5354        private Param param;
     55        private PrimitiveParam primitiveParam;
    5456
    5557        /**
    5658         * Build Param based on provided data.
    57          * 
     59         *
    5860         * @return Param object
    5961         * @throws Exception
     
    6163         */
    6264        public Param build()  {
    63         assert param != null;
     65                assert param != null;
    6466                param.id = id;
    6567                param.name = name;
     
    6870                param.flags = flags;
    6971                param.internalId = internalId;
    70 
    7172                return param;
    7273        }
     
    7778        }
    7879
     80        protected <T extends Param> ParamBuilder internalSetType(Class<? extends Param> type, T param) {
     81                this.paramType = type;
     82                this.param = param;
     83                if (param instanceof PrimitiveParam) {
     84                        primitiveParam = (PrimitiveParam) param;
     85                }
     86                return this;
     87        }
     88
    7989        public <T extends Param> ParamBuilder setType(Class<T> type) {
    80                 this.paramType = type;
    8190                try {
    82                         this.param = (Param)paramType.newInstance();
     91                        return internalSetType(type, type.newInstance());
    8392                } catch (InstantiationException e) {
    8493                        e.printStackTrace();
     
    8998        }
    9099
    91         public <T extends Param> ParamBuilder setType(T type) {
    92                 this.paramType = type.getClass();
    93                 this.param = type;
    94                 return this;
     100        public <T extends Param> ParamBuilder setType(T param) {
     101                return internalSetType(param.getClass(), param);
    95102        }
    96103
     
    116123        }
    117124
     125        protected <T extends Number> void parseMinMaxDefNumber(Class<T> type, String second, String third) {
     126                if (primitiveParam == null) {
     127                        log.warn("param is not a primitive param");
     128                        return;
     129                }
     130                if (second != null) {
     131                        this.primitiveParam.min = Numbers.parse(second, type);
     132                        if (this.primitiveParam.min == null) {
     133                                log.warn("value of min attribute was invalid");
     134                        }
     135                }
     136                if (third != null) {
     137                        this.primitiveParam.max = Numbers.parse(third, type);
     138                        if (this.primitiveParam.max == null) {
     139                                log.warn("value of min attribute was invalid");
     140                        }
     141                }
     142        }
     143
    118144        public ParamBuilder setType(String type) {
    119145
    120                 LOGGER.trace("parsing type: " + type);
     146                log.trace("parsing type: " + type);
    121147
    122148                String[] typeSplitted = type.split(" ");
     
    136162                                        procedureParam.parseSignature(signature);
    137163                                } catch (Exception e) {
    138                                         LOGGER.error("invalid procedure signature '" + signature + "': " + e);
     164                                        log.error("invalid procedure signature '" + signature + "': " + e);
    139165                                }
    140166                                setType(procedureParam);
     
    148174                                } else {
    149175                                        if (first.length() >= 2) {
    150                                                 switch (first.charAt(1)) {
     176                                switch (first.charAt(1)) {
    151177                                                        case 'b': {
    152178                                                                setType(BinaryParam.class);
     
    159185                                                }
    160186                                        }
    161                     if ("0".equals(second) && "1".equals(third)) {
    162                         setType(BooleanParam.class);
    163                     }
     187                                        if ("0".equals(second) && "1".equals(third)) {
     188                                                setType(BooleanParam.class);
     189                                        }
    164190                                        if (param == null) {
    165191                                                setType(DecimalParam.class);
     
    167193                                }
    168194                                if (this.param instanceof DecimalParam) {
    169                                         try {
    170                                                 if (second != null) {
    171                                                         this.param.min = Integer.parseInt(second);
    172                                                 }
    173 
    174                                                 if (third != null) {
    175                                                         this.param.max = Integer.parseInt(third);
    176                                                 }
    177                                         } catch (NumberFormatException e) {
    178                                                 LOGGER.warn("value of min or max attribute should be an Integer");
    179                                         }
     195                                        parseMinMaxDefNumber(Integer.class, second, third);
    180196                                }
    181197                                break;
     
    183199                        case 'f': {
    184200                                setType(FloatParam.class);
    185                                 try {
    186                                         if (second != null) {
    187                                                 this.param.min = Double.parseDouble(second);
    188                                         }
    189 
    190                                         if (third != null) {
    191                                                 this.param.max = Double.parseDouble(third);
    192                                         }
    193                                 } catch (NumberFormatException ex) {
    194                                         LOGGER.warn("Value of min or max attribute should be Double");
    195                                 }
     201                                parseMinMaxDefNumber(Double.class, second, third);
    196202                                break;
    197203                        }
     
    202208                        case 's': {
    203209                                setType(StringParam.class);
    204                                 this.param.min = second;
    205                                 this.param.max = third;
     210                                setMin(second);
     211                                setMax(third);
    206212                                break;
    207213                        }
     
    211217                        }
    212218                        case 'l': {
    213 
    214219                                setType(third != null ? new UniqueListParam(second, third) : new ArrayListParam(second));
    215220                                break;
     
    225230        }
    226231
     232        /**
     233         * @return the paramType
     234         */
     235        public Class<? extends Param> getParamType() {
     236                return paramType;
     237        }
     238
    227239        public <T> ParamBuilder setMin(T min) {
    228                 this.param.min = min;
     240                if (primitiveParam != null) {
     241                        this.primitiveParam.min = min;
     242                }
    229243                return this;
    230244        }
    231245
    232246        public <T> ParamBuilder setMax(T max) {
    233                 this.param.max = max;
     247                if (primitiveParam != null) {
     248                        this.primitiveParam.max = max;
     249                }
    234250                return this;
    235251        }
    236252
    237253        public <T> ParamBuilder setDef(T def) {
    238                 this.param.def = def;
    239                 return this;
     254                if (def != null && primitiveParam != null) {
     255                        this.primitiveParam.def = def;
     256                }
     257                return this;
     258        }
     259
     260        public Class<?> getStorageType() {
     261                assert param != null;
     262                return param.getStorageType();
    240263        }
    241264
     
    244267
    245268                if (paramEntryValues.length == 0) {
    246                         LOGGER.warn("field empty or wrong format (" + line
     269                        log.warn("field empty or wrong format (" + line
    247270                                        + ") - omitting");
    248271                        return null;
     
    263286                        /** everything is ok, parameters have just finished*/
    264287                } catch (NumberFormatException ex) {
    265                         LOGGER.warn("wrong format of entry: " + line
     288                        log.warn("wrong format of entry: " + line
    266289                                        + ", omitting");
    267290                        return null;
  • java/main/src/main/java/com/framsticks/params/PropertiesAccess.java

    r78 r84  
    11package com.framsticks.params;
    22
    3 import java.util.ArrayList;
    43import java.util.HashMap;
    5 import java.util.List;
    64import java.util.Map;
     5
    76
    87/**
    98 * The Class PropertiesAccess.
    10  * 
     9 *
    1110 * @author Jarek Szymczak <name.surname@gmail.com> (please replace name and
    1211 *         surname with my personal data)
     
    1817        public Map<String, Object> properties;
    1918
    20     @Override
     19        @Override
    2120        public Map<String, Object> createAccessee() {
    2221                return PropertiesAccess.createPropertiesMap();
     
    3332        @Override
    3433        public void clearValues() {
    35         assert properties != null;
    36         properties.clear();
     34                assert properties != null;
     35                properties.clear();
    3736        }
    3837
    3938        @Override
    40         public <T> T get(Param param, Class<T> type) {
    41         assert properties != null;
    42         assert param != null;
     39        public <T> T get(ValueParam param, Class<T> type) {
     40                assert properties != null;
     41                assert param != null;
    4342                Object object = null;
    4443                try {
     
    5453        }
    5554
    56         protected <T> void internalSet(Param param, T value) {
     55        @Override
     56        protected <T> void internalSet(ValueParam param, T value) {
    5757                properties.put(param.getId(), value);
    5858        }
     
    6363         * correct exceptions might occurred while getting / setting the parameters
    6464         * values
    65          * 
     65         *
    6666         * @param object
    6767         *            the properties with parameters values
    6868         */
     69        @SuppressWarnings("unchecked")
    6970        @Override
    70         public void select(Object object) {
     71        public PropertiesAccess select(Object object) {
    7172                this.properties = (Map<String, Object>)object;
     73                return this;
    7274        }
    7375
     
    8183        public PropertiesAccess cloneAccess() {
    8284                return new PropertiesAccess(framsClass);
    83                 //properties = createProperties();
    84                 //return access;
    8585        }
    8686
  • java/main/src/main/java/com/framsticks/params/ReflectionAccess.java

    r78 r84  
    44import java.lang.reflect.InvocationTargetException;
    55import java.lang.reflect.Modifier;
    6 import java.lang.reflect.Type;
    7 import java.util.List;
    86
    9 import com.framsticks.params.types.ListParam;
    107import org.apache.log4j.Logger;
     8
     9import com.framsticks.util.lang.Containers;
    1110
    1211
    1312/**
    1413 * The Class ReflectionAccess. Stores data in provided object using reflection.
    15  * 
     14 *
    1615 * @author Mateusz Jarus <name.surname@gmail.com> (please replace name and
    1716 *         surname with my personal data)
     
    2019 */
    2120public class ReflectionAccess extends SimpleAbstractAccess {
    22         private final static Logger LOGGER = Logger.getLogger(ReflectionAccess.class
    23                         .getName());
     21        private final static Logger log = Logger.getLogger(ReflectionAccess.class.getName());
    2422
    25 
    26     protected final Class reflectedClass;
     23        protected final Class<?> reflectedClass;
    2724        private Object object;
    2825
    29         public ReflectionAccess(Class reflectedClass, FramsClass framsClass) {
    30         this.reflectedClass = reflectedClass;
     26        public ReflectionAccess(Class<?> reflectedClass, FramsClass framsClass) {
     27                this.reflectedClass = reflectedClass;
    3128                setFramsClass(framsClass);
    3229        }
     
    3734
    3835        @Override
    39         public <T> T get(Param param, Class<T> type) {
     36        public <T> T get(ValueParam param, Class<T> type) {
    4037                if (object == null) {
    4138                        return null;
     
    5451                        } catch (InvocationTargetException e) {
    5552                                //e.printStackTrace();
    56             }
     53                        }
    5754
    5855                } catch (IllegalAccessException ex) {
    59                         LOGGER.warn("illegal access error occurred while trying to access returnedObject");
     56                        log.warn("illegal access error occurred while trying to access returnedObject");
    6057                        ex.printStackTrace();
    61         } catch (ClassCastException ignored) {
     58                } catch (ClassCastException ignored) {
    6259
    63         }
     60                }
    6461                return null;
    6562        }
    6663
    6764        @Override
    68         protected <T> void internalSet(Param param, T value) {
     65        protected <T> void internalSet(ValueParam param, T value) {
    6966                setValue(param, value);
    7067        }
    7168
    72         private <T> void setValue(Param param, T value) {
     69        private <T> void setValue(ValueParam param, T value) {
    7370                if (object == null) {
    7471                        return;
    75         }
     72                }
    7673                try {
    7774                        String id = param.getId();
    7875                        try {
    7976                                Field f = reflectedClass.getField(id);
    80                                 Class t = f.getType();
     77                                Class<?> t = f.getType();
    8178                                if (Modifier.isFinal(f.getModifiers())) {
    8279                                        return;
     
    111108
    112109                try {
    113                         for (Param p : framsClass.getParamEntries()) {
     110                        for (ValueParam p : Containers.filterInstanceof(framsClass.getParamEntries(), ValueParam.class)) {
    114111                                setValue(p, p.getDef(Object.class));
    115112                        }
     
    121118        /**
    122119         * Sets the new object to operate on.
    123          * 
     120         *
    124121         * @param object
    125122         *            new object to operate on
    126123         */
    127124        @Override
    128         public void select(Object object) {
     125        public ReflectionAccess select(Object object) {
    129126                assert object == null || reflectedClass.isInstance(object);
    130127                this.object = object;
     128                return this;
    131129        }
    132130
     
    159157        }
    160158
    161     @Override
    162     public Object createAccessee() {
    163         try {
    164             return reflectedClass.newInstance();
    165         } catch (InstantiationException e) {
    166             e.printStackTrace();
    167         } catch (IllegalAccessException e) {
    168             e.printStackTrace();
    169         }
    170         LOGGER.fatal("failed to create reflected object of class " + reflectedClass.getCanonicalName() + " for frams type " + framsClass.getId());
    171         return null;
    172     }
     159        @Override
     160        public Object createAccessee() {
     161                try {
     162                        return reflectedClass.newInstance();
     163                } catch (InstantiationException e) {
     164                        e.printStackTrace();
     165                } catch (IllegalAccessException e) {
     166                        e.printStackTrace();
     167                }
     168                log.fatal("failed to create reflected object of class " + reflectedClass.getCanonicalName() + " for frams type " + framsClass.getId());
     169                return null;
     170        }
    173171}
  • java/main/src/main/java/com/framsticks/params/Registry.java

    r78 r84  
    1010 */
    1111public class Registry {
    12         private static final Logger LOGGER = Logger.getLogger(Registry.class.getName());
     12        private static final Logger log = Logger.getLogger(Registry.class.getName());
    1313
    14         protected final Map<String, Class> reflectedClasses = new HashMap<String, Class>();
     14        protected final Map<String, Class<?>> reflectedClasses = new HashMap<String, Class<?>>();
    1515        protected final Map<String, String> invertedReflectedClasses = new HashMap<String, String>();
    1616        protected final Map<String, FramsClass> infoCache = new HashMap<String, FramsClass>();
     
    2020                        registerReflectedClass(name, id, Class.forName(className));
    2121                } catch (ClassNotFoundException e) {
    22                         LOGGER.fatal("class not found during registration: " + e);
     22                        log.fatal("class not found during registration: " + e);
    2323                }
    2424        }
    2525
    26         public void registerReflectedClass(String name, String id, Class reflectedClass) {
     26        public void registerReflectedClass(String name, String id,
     27                        Class<?> reflectedClass) {
    2728                if (name != null) {
    2829                        reflectedClasses.put(name, reflectedClass);
     
    4344        public void putInfoIntoCache(FramsClass framsClass) {
    4445                if (infoCache.containsKey(framsClass.getId())) {
    45                         LOGGER.info("already cached " + framsClass);
     46                        log.info("already cached " + framsClass);
    4647                        return;
    4748                }
    48                 LOGGER.debug("caching info for " + framsClass);
     49                log.debug("caching info for " + framsClass);
    4950                infoCache.put(framsClass.getId(), framsClass);
    5051                infoCache.put(framsClass.getName(), framsClass);
     
    6364                return null;
    6465        }
     66
     67        public static AccessInterface wrapAccessWithListIfNeeded(CompositeParam param, AccessInterface access) {
     68        if (access == null) {
     69                        return null;
     70                }
     71        return param.prepareAccessInterface(access);
     72        }
     73
     74    public AccessInterface prepareAccess(CompositeParam param) {
     75        return wrapAccessWithListIfNeeded(param, createAccess(param.getContainedTypeName()));
     76    }
     77
     78        public AccessInterface createAccess(String name) {
     79                if (name == null) {
     80                        return null;
     81                }
     82                FramsClass framsClass = getInfoFromCache(name);
     83                if (framsClass == null) {
     84                        return null;
     85                }
     86
     87                return createAccess(name, framsClass);
     88        }
     89
    6590}
  • java/main/src/main/java/com/framsticks/params/SimpleAbstractAccess.java

    r78 r84  
    22
    33import java.io.IOException;
    4 import java.text.DecimalFormat;
    5 import java.text.DecimalFormatSymbols;
    6 import java.util.ArrayList;
    74import java.util.Collection;
    8 import java.util.List;
    9 
    10 import com.framsticks.params.types.*;
     5
     6import static com.framsticks.util.lang.Containers.filterInstanceof;
     7
    118import org.apache.log4j.Logger;
    12 import java.util.Locale;
    139
    1410/**
     
    2622public abstract class SimpleAbstractAccess implements AccessInterface {
    2723
    28         private final static Logger LOGGER = Logger.getLogger(SimpleAbstractAccess.class.getName());
    29 
    30 
    31 
    32     @Override
     24        private final static Logger log = Logger.getLogger(SimpleAbstractAccess.class.getName());
     25
     26        @Override
    3327        public final FramsClass getFramsClass() {
    3428                return framsClass;
     
    3832                this.framsClass = framsClass;
    3933        }
    40     /**
     34        /**
    4135         * Simple String key, value class.
    4236         */
     
    6458        }
    6559
    66     @Override
     60        @Override
    6761        public int getParamCount() {
    6862                return framsClass.getParamCount();
     
    7165        @Override
    7266        public Param getParam(int i) {
    73                 return framsClass.getParamEntry(i);
     67                return framsClass.getParamEntry(i, Param.class);
    7468        }
    7569
    7670        @Override
    7771        public Param getParam(String id) {
    78                 return framsClass.getParamEntry(id);
    79         }
    80 
     72                return framsClass.getParamEntry(id, Param.class);
     73        }
    8174
    8275        @Override
     
    8780        @Override
    8881        public <T> T get(int i, Class<T> type) {
    89                 return get(getParam(i), type);
     82                Param p = getParam(i);
     83                assert p instanceof ValueParam;
     84                return get((ValueParam) p, type);
    9085        }
    9186
    9287        @Override
    9388        public <T> T get(String id, Class<T> type) {
    94                 return get(getParam(id), type);
    95         }
    96 
     89                Param p = getParam(id);
     90                assert p instanceof ValueParam;
     91                return get((ValueParam) p, type);
     92        }
    9793
    9894        @Override
    9995        public <T> int set(String id, T value) {
    100                 return set(getParam(id), value);
     96                Param p = getParam(id);
     97                assert p instanceof ValueParam;
     98                return set((ValueParam) p, value);
    10199        }
    102100
    103101        @Override
    104102        public <T> int set(int i, T value) {
    105                 return set(getParam(i), value);
    106         }
    107 
    108         @SuppressWarnings("unchecked")
    109         @Override
    110         public <T> int set(Param param, T value) {
     103                Param p = getParam(i);
     104                assert p instanceof ValueParam;
     105                return set((ValueParam) p, value);
     106        }
     107
     108        @Override
     109        public <T> int set(ValueParam param, T value) {
    111110                int flags = 0;
     111
    112112                //String id = param.getEffectiveId();
    113113                try {
    114             Object oldValue = get(param, param.getStorageType());
    115             Object casted = param.reassign(value, oldValue);
    116             if (casted != oldValue) {
    117                 internalSet(param, casted);
    118             }
    119         } catch (CastFailure e) {
    120             LOGGER.error("casting failure while set: ", e);
    121 
    122         }
    123         return flags;
    124     }
    125 
    126 
    127 
     114                        Object oldValue = get(param, param.getStorageType());
     115                        ReassignResult<?> result = param.reassign(value, oldValue);
     116                        Object casted = result.getValue();
     117                        if (casted != oldValue) {
     118                                internalSet(param, casted);
     119                        }
     120                        flags = result.getFlags();
     121                } catch (CastFailure e) {
     122                        log.error("casting failure while set: ", e);
     123                }
     124                return flags;
     125        }
    128126
    129127        @Override
    130128        public void setDefault(boolean numericOnly) {
    131                 for (int i = 0; i < framsClass.getParamCount(); i++)
     129                for (int i = 0; i < framsClass.getParamCount(); i++) {
    132130                        setDefault(i, numericOnly);
     131                }
    133132        }
    134133
    135134        @Override
    136135        public void setDefault(int i, boolean numericOnly) {
    137                 Param entry = framsClass.getParamEntry(i);
     136                ValueParam entry = framsClass.getParamEntry(i, ValueParam.class);
    138137                if ((entry != null)     && (!numericOnly || entry.isNumeric())) {
    139138                        set(i, entry.getDef(entry.getStorageType()));
     
    148147        }
    149148
    150         @SuppressWarnings("unchecked")
    151149        @Override
    152150        public void setMin(int i) {
    153                 Param entry = framsClass.getParamEntry(i);
     151                PrimitiveParam entry = framsClass.getParamEntry(i, PrimitiveParam.class);
     152                if (entry == null) {
     153                        return;
     154                }
    154155                Object min = entry.getMin(entry.getStorageType());
    155156                if (min != null) {
     
    165166        }
    166167
    167         @SuppressWarnings("unchecked")
    168168        @Override
    169169        public void setMax(int i) {
    170                 Param entry = framsClass.getParamEntry(i);
     170                PrimitiveParam entry = framsClass.getParamEntry(i, PrimitiveParam.class);
     171                if (entry == null) {
     172                        return;
     173                }
    171174                Object max = entry.getMax(entry.getStorageType());
    172175                if (max != null) {
     
    191194        @Override
    192195        public void save(SinkInterface sink) {
    193         assert framsClass != null;
    194         sink.print(framsClass.getId()).print(":").breakLine();
    195         for (Param p : framsClass.getParamEntries()) {
    196             if (p instanceof ValueParam) {
    197                 Object value = get(p, Object.class);
    198                 if (value == null) {
    199                     continue;
    200                 }
    201                 sink.print(p.getId()).print(":");
    202                 ((ValueParam)p).save(sink, value);
    203                 sink.breakLine();
    204 
    205 
    206                 //continue;
    207             }
    208             /*
    209             if (p instanceof CompositeParam) {
    210                 if (!(p instanceof ListParam)) {
    211                     continue;
    212                 }
    213                 Collection c = get(p, Collection.class);
    214                 if (c != null) {
    215                     save(stream, p, c.size());
    216                 }
    217             }
    218             */
    219 
    220         }
    221         sink.breakLine();
    222         }
    223 
    224         @Override
    225         public String save2(boolean omitDefaultValues) {
    226                 StringBuilder stringBuilder = new StringBuilder();
    227                 DecimalFormat df = new DecimalFormat("#.###", new DecimalFormatSymbols(
    228                                 Locale.ENGLISH));
    229                 boolean canOmitName = false;
    230                 int n = 0;
    231                 for (int i = 0; i < framsClass.getParamCount(); i++) {
    232                         Object value = this.get(i, Object.class);
    233                         Object def = framsClass.getParamEntry(i).getDef(Object.class);
    234                         if (value != null && (!omitDefaultValues || !value.equals(def))) {
    235                                 if ((n != i && !canOmitName)
    236                                                 || (getParam(i).getFlags() & Flags.CANOMITNAME) == 0) {
    237                                         stringBuilder.append(getParam(i).getId());
    238                                         stringBuilder.append("=");
     196                assert framsClass != null;
     197                sink.print(framsClass.getId()).print(":").breakLine();
     198                for (PrimitiveParam p : filterInstanceof(framsClass.getParamEntries(), PrimitiveParam.class)) {
     199                        Object value = get(p, Object.class);
     200                        if (value == null) {
     201                                continue;
     202                        }
     203                        sink.print(p.getId()).print(":");
     204                        p.save(sink, value);
     205                        sink.breakLine();
     206                }
     207                sink.breakLine();
     208        }
     209
     210        private Entry readEntry(SourceInterface source)
     211                        throws IOException {
     212
     213                String line;
     214                String key = null;
     215                StringBuilder value = null;
     216                while ((line = source.readLine()) != null)
     217                {
     218                        if (key == null) {
     219                                int colonIndex = line.indexOf(':');
     220                                if (colonIndex == -1) {
     221                                        return null;
    239222                                }
    240                                 n++;
    241                                 canOmitName = true;
    242                                 if (this.get(i, Object.class) instanceof String) {
    243                                         String valueString = this.get(i, String.class);
    244                                         valueString = valueString.replaceAll("\\\"", "\\\\\"");
    245                                         valueString = valueString.contains(",") ? "\""
    246                                                         + valueString + "\"" : valueString;
    247                                         // if ("".equals(valueString.trim()))
    248                                         // value = "\"\"";
    249                                         stringBuilder.append(valueString);
    250                                 } else if (this.get(i, Object.class) instanceof Double) {
    251                                         stringBuilder.append(df.format(this.get(i, Double.class)));
    252                                 } else
    253                                         stringBuilder.append(this.get(i, Object.class));
    254                                 stringBuilder.append(", ");
     223                                key = line.substring(0, colonIndex);
     224                                String inlineValue = line.substring(colonIndex + 1);
     225
     226
     227                                if (!inlineValue.startsWith("~")) {
     228                                        return new Entry(key, inlineValue);
     229                                }
     230                                value = new StringBuilder();
     231                                value.append(inlineValue.substring(1));
     232                                continue;
     233                        }
     234                        if (value.length() != 0) {
     235                                value.append(System.getProperty("line.separator"));
     236                        }
     237                        if (line.contains("~")) {
     238                                value.append(line.substring(0, line.indexOf("~")));
     239                                return new Entry(key, value.toString());
     240                        }
     241                        value.append(line);
     242                        /*
     243                        if (line.contains("~")) {
     244                                String lastLine = line.substring(0, line.indexOf("~"));
     245                                if (lastLine.length() > 0) {
     246                                        appendToValue(value, lastLine);
     247                                }
     248                                return new Entry(key, value.toString());
     249                        }
     250                        appendToValue(value, line);
     251                        */
     252                }
     253                return null;
     254        }
     255
     256        @Override
     257        public void load(SourceInterface source) throws Exception {
     258                //TODO not clearing values, because get from manager gives only fields, not children
     259                //this.clearValues();
     260
     261                Entry entry;
     262                while ((entry = readEntry(source)) != null) {
     263                        Param param = getParam(entry.key);
     264                        if (param == null) {
     265                                continue;
     266                        }
     267                        if (!(param instanceof ValueParam)) {
     268                                log.warn("param " + param + " is not a ValueParam");
     269                                continue;
     270                        }
     271                        if ((param.getFlags() & Flags.DONTLOAD) != 0) {
     272                                log.debug("DontLoad flag was set - not loading...");
    255273                        } else {
    256                                 canOmitName = false;
    257                         }
    258                 }
    259 
    260                 String params = "";
    261                 if (stringBuilder.length() > 1)
    262                         params = stringBuilder.substring(0, stringBuilder.length() - 2);
    263 
    264                 return getId() + ":" + params;
    265         }
    266 
    267     /*
    268     private static void appendToValue(StringBuilder value, String line) {
    269 
    270         if (value.length() != 0) {
    271             value.append(System.getProperty("line.separator"));
    272         }
    273         value.append(line);
    274     }
    275     */
    276 
    277     private Entry readEntry(SourceInterface source)
    278             throws IOException {
    279 
    280         String line;
    281         String key = null;
    282         StringBuilder value = null;
    283         while ((line = source.readLine()) != null)
    284         {
    285             if (key == null) {
    286                 int colonIndex = line.indexOf(':');
    287                 if (colonIndex == -1) {
    288                     return null;
    289                 }
    290                 key = line.substring(0, colonIndex);
    291                 String inlineValue = line.substring(colonIndex + 1);
    292 
    293 
    294                 if (!inlineValue.startsWith("~")) {
    295                     return new Entry(key, inlineValue);
    296                 }
    297                 value = new StringBuilder();
    298                 value.append(inlineValue.substring(1));
    299                 continue;
    300             }
    301             if (value.length() != 0) {
    302                 value.append(System.getProperty("line.separator"));
    303             }
    304             if (line.contains("~")) {
    305                 value.append(line.substring(0, line.indexOf("~")));
    306                 return new Entry(key, value.toString());
    307             }
    308             value.append(line);
    309             /*
    310             if (line.contains("~")) {
    311                 String lastLine = line.substring(0, line.indexOf("~"));
    312                 if (lastLine.length() > 0) {
    313                     appendToValue(value, lastLine);
    314                 }
    315                 return new Entry(key, value.toString());
    316             }
    317             appendToValue(value, line);
    318             */
    319         }
    320         return null;
    321     }
    322 
    323     @Override
    324     public void load(SourceInterface source) throws Exception {
    325         //TODO not clearing values, because get from manager gives only fields, not children
    326         //this.clearValues();
    327 
    328         Entry entry;
    329         while ((entry = readEntry(source)) != null) {
    330             Param param = getParam(entry.key);
    331             if (param == null) {
    332                 continue;
    333             }
    334             if ((param.getFlags() & Flags.DONTLOAD) != 0) {
    335                 LOGGER.debug("DontLoad flag was set - not loading...");
    336             } else {
    337                 int retFlags = this.set(param, entry.value);
    338                 if ((retFlags & (Flags.PSET_HITMIN | Flags.PSET_HITMAX)) != 0) {
    339                     String which = ((retFlags & Flags.PSET_HITMIN) != 0) ? "small"
    340                             : "big";
    341                     LOGGER.warn("value of key '" + entry.key
    342                             + "' was too " + which + ", adjusted");
    343                 }
    344             }
    345         }
    346     }
    347 
    348 
    349 
    350         protected abstract <T> void internalSet(Param param, T value);
    351 
    352     @Override
    353     public Collection<Param> getParams() {
    354         return framsClass.getParamEntries();
    355     }
    356 
    357     /*
     274                                int retFlags = this.set((ValueParam) param, entry.value);
     275                                if ((retFlags & (Flags.PSET_HITMIN | Flags.PSET_HITMAX)) != 0) {
     276                                        String which = ((retFlags & Flags.PSET_HITMIN) != 0) ? "small" : "big";
     277                                        log.warn("value of key '" + entry.key + "' was too " + which + ", adjusted");
     278                                }
     279                        }
     280                }
     281        }
     282
     283        protected abstract <T> void internalSet(ValueParam param, T value);
     284
     285        @Override
     286        public Collection<Param> getParams() {
     287                return framsClass.getParamEntries();
     288        }
     289
     290        /*
    358291        protected <T extends Comparable<T>> int setAndCut(Param param, Object value, Class<T> type) {
    359292                int flags = 0;
  • java/main/src/main/java/com/framsticks/params/UniqueListAccess.java

    r77 r84  
    11package com.framsticks.params;
    22
    3 import com.framsticks.util.Casting;
    4 import com.framsticks.util.Numbers;
     3import com.framsticks.util.lang.Casting;
     4import com.framsticks.util.lang.Numbers;
    55import org.apache.log4j.Logger;
    66
     
    1212public class UniqueListAccess extends ListAccess {
    1313
    14     private static final Logger LOGGER = Logger.getLogger(UniqueListAccess.class.getName());
     14        private static final Logger log = Logger.getLogger(UniqueListAccess.class.getName());
    1515
    16     Map<String, Object> map;
     16        Map<String, Object> map;
    1717
    18     final String uidName;
     18        final String uidName;
    1919
    20     public UniqueListAccess(AccessInterface elementAccess, String uidName) {
    21         super(elementAccess);
    22         this.uidName = uidName;
    23     }
     20        public UniqueListAccess(AccessInterface elementAccess, String uidName) {
     21                super(elementAccess);
     22                this.uidName = uidName;
     23        }
    2424
    25     @Override
    26     public Map<String, Object> createAccessee() {
    27         return new HashMap<String, Object>();
    28     }
     25        @Override
     26        public Map<String, Object> createAccessee() {
     27                return new HashMap<String, Object>();
     28        }
    2929
    30     @Override
    31     public Param getParam(int i) {
    32         LOGGER.error("accesing unique list through index");
    33         assert false;
    34         return null;
    35         //LOGGER.error("accesing unique list through index");
    36         //return null;
    37         //return new ParamBuilder().setId(Integer.toString(i)).setName(elementAccess.getId()).setType("o " + elementAccess.getId()).build();
    38     }
     30        @Override
     31        public Param getParam(int i) {
     32                log.error("accesing unique list through index");
     33                assert false;
     34                return null;
     35                //log.error("accesing unique list through index");
     36                //return null;
     37                //return new ParamBuilder().setId(Integer.toString(i)).setName(elementAccess.getId()).setType("o " + elementAccess.getId()).build();
     38        }
    3939
    40     @Override
    41     public Param getParam(String id) {
    42         Integer i = Numbers.parse(id, Integer.class);
    43         if (i != null) {
    44             return getParam(i);
    45         }
    46         return new ParamBuilder().setId(id).setName(elementAccess.getId()).setType("o " + elementAccess.getId()).build();
    47     }
     40        @Override
     41        public Param getParam(String id) {
     42                Integer i = Numbers.parse(id, Integer.class);
     43                if (i != null) {
     44                        return getParam(i);
     45                }
     46                return new ParamBuilder().setId(id).setName(elementAccess.getId()).setType("o " + elementAccess.getId()).build();
     47        }
    4848
    49     @Override
    50     public String getId() {
    51         return "l " + elementAccess.getId() + " " + uidName;
    52     }
     49        @Override
     50        public String getId() {
     51                return "l " + elementAccess.getId() + " " + uidName;
     52        }
    5353
    54     @Override
    55     public int getParamCount() {
    56         return map.size();
    57     }
     54        @Override
     55        public int getParamCount() {
     56                return map.size();
     57        }
    5858
    59     @Override
    60     public <T> T get(int i, Class<T> type) {
    61         LOGGER.error("accesing unique list through index");
    62         assert false;
    63         return null;
    64         //Object[] values = map.values().toArray();
    65         //return Casting.tryCast(i < values.length ? values[i] : null, type);
    66     }
     59        @Override
     60        public <T> T get(int i, Class<T> type) {
     61                log.error("accesing unique list through index");
     62                assert false;
     63                return null;
     64                //Object[] values = map.values().toArray();
     65                //return Casting.tryCast(i < values.length ? values[i] : null, type);
     66        }
    6767
    68     @Override
    69     public <T> T get(String id, Class<T> type) {
    70         Integer i = Numbers.parse(id, Integer.class);
    71         if (i != null) {
    72             return get(i, type);
    73         }
    74         return Casting.tryCast(type, map.containsKey(id) ? map.get(id) : null);
    75     }
     68        @Override
     69        public <T> T get(String id, Class<T> type) {
     70                Integer i = Numbers.parse(id, Integer.class);
     71                if (i != null) {
     72                        return get(i, type);
     73                }
     74                return Casting.tryCast(type, map.containsKey(id) ? map.get(id) : null);
     75        }
    7676
    77     @Override
    78     public <T> T get(Param param, Class<T> type) {
    79         return get(param.getId(), type);
    80     }
     77        @Override
     78        public <T> T get(ValueParam param, Class<T> type) {
     79                return get(param.getId(), type);
     80        }
    8181
    82     public String getUidOf(Object value) {
    83         Object tmp = elementAccess.getSelected();
    84         elementAccess.select(value);
    85         String uid = elementAccess.get(uidName, String.class);
    86         elementAccess.select(tmp);
    87         if (uid == null) {
    88             return null;
    89         }
    90         return uid;
    91     }
     82        public String getUidOf(Object value) {
     83                Object tmp = elementAccess.getSelected();
     84                elementAccess.select(value);
     85                String uid = elementAccess.get(uidName, String.class);
     86                elementAccess.select(tmp);
     87                if (uid == null) {
     88                        return null;
     89                }
     90                return uid;
     91        }
    9292
    93     protected int setByUid(Object object, String uid) {
    94         if (uid == null) {
    95             uid = getUidOf(object);
    96             if (uid == null) {
    97                 LOGGER.error("failed to set - missing uid");
    98                 return 0;
    99             }
    100         }
    101         if (object == null) {
    102             map.remove(uid);
    103         } else {
    104             map.put(uid, object);
    105         }
    106         return 0;
    107     }
     93        protected int setByUid(Object object, String uid) {
     94                if (uid == null) {
     95                        uid = getUidOf(object);
     96                        if (uid == null) {
     97                                log.error("failed to set - missing uid");
     98                                return 0;
     99                        }
     100                }
     101                if (object == null) {
     102                        map.remove(uid);
     103                } else {
     104                        map.put(uid, object);
     105                }
     106                return 0;
     107        }
    108108
    109     @Override
    110     public <T> int set(int i, T value) {
    111         LOGGER.error("accesing unique list through index");
    112         //return setByUid(value, null);
    113         return 0;
    114     }
     109        @Override
     110        public <T> int set(int i, T value) {
     111                log.error("accesing unique list through index");
     112                //return setByUid(value, null);
     113                return 0;
     114        }
    115115
    116     @Override
    117     public <T> int set(String id, T value) {
    118         Integer i = Numbers.parse(id, Integer.class);
    119         if (i != null) {
    120             return set(i, value);
    121         }
    122         if (value == null) {
    123             return setByUid(null, id);
    124         }
    125         String uid = getUidOf(value);
    126         if (uid != null && id != null) {
    127             if (!id.equals(uid)) {
    128                 LOGGER.error("uid mismatch with set key");
    129                 return 0;
    130             }
    131             setByUid(value, uid);
    132             return 0;
    133         }
    134         if (uid != null) {
    135             setByUid(value, uid);
    136             return 0;
    137         }
    138         if (id != null) {
    139             setByUid(value, id);
    140             return 0;
    141         }
    142         LOGGER.error("missing both uid and id - failed to set");
    143         return 0;
    144     }
     116        @Override
     117        public <T> int set(String id, T value) {
     118                Integer i = Numbers.parse(id, Integer.class);
     119                if (i != null) {
     120                        return set(i, value);
     121                }
     122                if (value == null) {
     123                        return setByUid(null, id);
     124                }
     125                String uid = getUidOf(value);
     126                if (uid != null && id != null) {
     127                        if (!id.equals(uid)) {
     128                                log.error("uid mismatch with set key");
     129                                return 0;
     130                        }
     131                        setByUid(value, uid);
     132                        return 0;
     133                }
     134                if (uid != null) {
     135                        setByUid(value, uid);
     136                        return 0;
     137                }
     138                if (id != null) {
     139                        setByUid(value, id);
     140                        return 0;
     141                }
     142                log.error("missing both uid and id - failed to set");
     143                return 0;
     144        }
    145145
    146     @Override
    147     public <T> int set(Param param, T value) {
    148         return set(param.getId(), value);
    149     }
     146        @Override
     147        public <T> int set(ValueParam param, T value) {
     148                return set(param.getId(), value);
     149        }
    150150
    151     @Override
    152     public void clearValues() {
    153         map.clear();
    154     }
     151        @Override
     152        public void clearValues() {
     153                map.clear();
     154        }
    155155
    156     @Override
    157     public void select(Object object) {
    158         map = (Map<String, Object>)object;
    159     }
     156        @SuppressWarnings("unchecked")
     157        @Override
     158        public UniqueListAccess select(Object object) {
     159                assert (object instanceof Map);
     160                map = (Map<String, Object>) object;
     161                return this;
     162        }
    160163
    161     @Override
    162     public Object getSelected() {
    163         return map;
    164     }
     164        @Override
     165        public Object getSelected() {
     166                return map;
     167        }
    165168
    166     @Override
    167     public UniqueListAccess cloneAccess() {
    168         return new UniqueListAccess(elementAccess.cloneAccess(), uidName);
    169     }
     169        @Override
     170        public UniqueListAccess cloneAccess() {
     171                return new UniqueListAccess(elementAccess.cloneAccess(), uidName);
     172        }
    170173
    171     @Override
    172     public String computeIdentifierFor(Object selected) {
    173         String uid = getUidOf(selected);
    174         if (uid == null) {
    175             LOGGER.error("missing uid field");
    176             return null;
    177         }
    178         return uid;
    179     }
     174        @Override
     175        public String computeIdentifierFor(Object selected) {
     176                String uid = getUidOf(selected);
     177                if (uid == null) {
     178                        log.error("missing uid field");
     179                        return null;
     180                }
     181                return uid;
     182        }
    180183
    181     @Override
    182     public Collection<Param> getParams() {
    183         List<Param> result = new LinkedList<Param>();
    184         if (map == null) {
    185             return result;
    186         }
    187         for (String k : map.keySet()) {
    188             result.add(getParam(k));
    189         }
    190         return result;
    191     }
     184        @Override
     185        public Collection<Param> getParams() {
     186                List<Param> result = new LinkedList<Param>();
     187                if (map == null) {
     188                        return result;
     189                }
     190                for (String k : map.keySet()) {
     191                        result.add(getParam(k));
     192                }
     193                return result;
     194        }
    192195}
  • java/main/src/main/java/com/framsticks/params/Util.java

    r78 r84  
    44import java.util.List;
    55
     6import static com.framsticks.util.lang.Containers.filterInstanceof;
     7
    68/**
    79 * @author Piotr Sniegowski
    810 */
    911public abstract class Util {
    10     public static String readSourceToString(SourceInterface source) {
    11         StringBuilder result = new StringBuilder();
    12         String line;
    13         while ((line = source.readLine()) != null) {
    14             result.append(line).append(" ");
    15         }
    16         source.close();
    17         return result.toString();
    18     }
     12
     13        public static String readSourceToString(SourceInterface source) {
     14                StringBuilder result = new StringBuilder();
     15                String line;
     16                while ((line = source.readLine()) != null) {
     17                        result.append(line).append(" ");
     18                }
     19                source.close();
     20                return result.toString();
     21        }
     22
    1923        public static List<Object> stripAccessInterface(List<AccessInterface> accesses) {
    2024                List<Object> result = new ArrayList<Object>();
     
    2428                return result;
    2529        }
     30
    2631        public static int copyParams(AccessInterface to, AccessInterface from) {
    2732                int copied = 0;
    28                 for (Param f : from.getParams()) {
     33                for (ValueParam f : filterInstanceof(from.getParams(), ValueParam.class)) {
    2934                        Param t = from.getParam(f.getId());
    30                         if (t == null) {
     35                        if (!(t instanceof ValueParam)) {
    3136                                continue;
    3237                        }
     
    3439                                continue;
    3540                        }
    36                         to.set(t, from.get(f, Object.class));
     41                        to.set((ValueParam) t, from.get(f, Object.class));
    3742                        ++copied;
    3843                }
  • java/main/src/main/java/com/framsticks/params/types/ArrayListParam.java

    r77 r84  
    44import com.framsticks.params.ArrayListAccess;
    55import com.framsticks.params.CastFailure;
    6 import com.framsticks.util.Casting;
    7 import com.framsticks.util.Containers;
    8 import com.framsticks.util.Numbers;
     6import com.framsticks.params.ReassignResult;
     7import com.framsticks.util.lang.Casting;
     8import com.framsticks.util.lang.Containers;
     9import com.framsticks.util.lang.Numbers;
    910
    1011import java.util.ArrayList;
     
    1617public class ArrayListParam extends ListParam {
    1718
    18     public ArrayListParam(String containedTypeName) {
    19         super(containedTypeName);
    20     }
     19        public ArrayListParam(String containedTypeName) {
     20                super(containedTypeName);
     21        }
    2122
    2223
    23     @Override
    24     public Class getStorageType() {
    25         return List.class;
    26     }
     24        @Override
     25        public Class<?> getStorageType() {
     26                return List.class;
     27        }
    2728
    28     @Override
    29     public AccessInterface prepareAccessInterface(AccessInterface access) {
    30         return new ArrayListAccess(access);
    31     }
     29        @Override
     30        public AccessInterface prepareAccessInterface(AccessInterface access) {
     31                return new ArrayListAccess(access);
     32        }
    3233
    33     @Override
    34     public String computeAccessId() {
    35         return "l " + containedTypeName;
    36     }
     34        @Override
     35        public String computeAccessId() {
     36                return "l " + containedTypeName;
     37        }
    3738
    38     @Override
    39     public Object reassign(Object newValue, Object oldValue) throws CastFailure {
    40         if (newValue == null) {
    41             throw new CastFailure();
    42         }
    43         Integer size = Numbers.cast(newValue, Integer.class);
    44         if (size != null) {
    45             //return oldValue;
    46             List list;
    47             if (oldValue == null) {
    48                 list = new ArrayList();
    49             } else {
    50                 list = Casting.tryCast(List.class, oldValue);
    51                 if (list == null) {
    52                     throw new CastFailure();
    53                 }
    54             }
    55             Containers.resizeList(list, size);
    56             return list;
    57         }
    58         if (oldValue != null) {
    59             return oldValue;
    60         }
    61         return newValue;
    62     }
     39        @Override
     40        public ReassignResult<List<?>> reassign(Object newValue, Object oldValue) throws CastFailure {
     41                if (newValue == null) {
     42                        throw new CastFailure();
     43                }
     44                Integer size = Numbers.cast(newValue, Integer.class);
     45                if (size != null) {
     46                        //return oldValue;
     47                        List<?> list;
     48                        if (oldValue == null) {
     49                                list = new ArrayList<Object>();
     50                        } else {
     51                                list = Casting.tryCast(List.class, oldValue);
     52                                if (list == null) {
     53                                        throw new CastFailure();
     54                                }
     55                        }
     56                        Containers.resizeList(list, size);
     57                        return new ReassignResult<List<?>>(list);
     58                }
     59                if (oldValue != null) {
     60                        return new ReassignResult<List<?>>(Casting.throwCast(List.class, oldValue));
     61                }
     62                return new ReassignResult<List<?>>(Casting.throwCast(List.class, newValue));
     63        }
    6364
    64     @Override
    65     public String getType() {
    66         return "l " + getContainedTypeName();
    67     }
     65        @Override
     66        public String getFramsTypeName() {
     67                return "l " + getContainedTypeName();
     68        }
    6869}
  • java/main/src/main/java/com/framsticks/params/types/BinaryParam.java

    r77 r84  
    22
    33import com.framsticks.params.CastFailure;
    4 import com.framsticks.util.Numbers;
     4import com.framsticks.params.PrimitiveParam;
     5import com.framsticks.params.ReassignResult;
     6import com.framsticks.util.lang.Numbers;
    57
    68/**
    79 * @author Piotr Sniegowski
    810 */
    9 public class BinaryParam extends ValueParam {
     11public class BinaryParam extends PrimitiveParam {
     12
    1013        @Override
    11         public Class getStorageType() {
     14        public Class<?> getStorageType() {
    1215                return Integer.class;
    1316        }
    1417
    15     @Override
    16     public String getType() {
    17         return "db";
    18     }
     18        @Override
     19        public String getFramsTypeName() {
     20                return "db";
     21        }
    1922
    20     @Override
    21     public Object reassign(Object newValue, Object oldValue) throws CastFailure {
    22         if (newValue instanceof String) {
    23             Integer v = Numbers.parse((String) newValue, Integer.class);
    24             if (v != null) {
    25                 return v;
    26             }
    27             throw new CastFailure();
    28         }
    29         return super.reassign(newValue, oldValue);
    30     }
     23        @Override
     24        public ReassignResult<?> reassign(Object newValue, Object oldValue) throws CastFailure {
     25                if (newValue instanceof String) {
     26                        Integer v = Numbers.parse((String) newValue, Integer.class);
     27                        if (v != null) {
     28                                return ReassignResult.create(v);
     29                        }
     30                        throw new CastFailure();
     31                }
     32                if (newValue instanceof Integer) {
     33                        return ReassignResult.create((Integer) newValue);
     34                }
     35                throw new CastFailure();
     36        }
    3137
    3238}
  • java/main/src/main/java/com/framsticks/params/types/BooleanParam.java

    r77 r84  
    22
    33import com.framsticks.params.CastFailure;
     4import com.framsticks.params.PrimitiveParam;
     5import com.framsticks.params.ReassignResult;
    46import com.framsticks.params.SinkInterface;
     7import com.framsticks.util.lang.Numbers;
    58
    69/**
    710 * @author Piotr Sniegowski
    811 */
    9 public class BooleanParam extends DecimalParam {
    10     @Override
    11     public Class getStorageType() {
    12         return Boolean.class;
    13     }
     12public class BooleanParam extends PrimitiveParam {
    1413
    15     @Override
    16     public Object reassign(Object newValue, Object oldValue) throws CastFailure {
     14        public BooleanParam() {
     15                def = false;
     16        }
     17
     18        @Override
     19        public Class<?> getStorageType() {
     20                return Boolean.class;
     21        }
     22
     23        @Override
     24        public ReassignResult<Boolean> reassign(Object newValue, Object oldValue) throws CastFailure {
    1725                if (newValue instanceof Boolean) {
    18                         return newValue;
     26                        return ReassignResult.create((Boolean) newValue);
    1927                }
    20         Object casted = super.reassign(newValue, oldValue);
    21         if (casted instanceof Integer) {
    22             Integer i = (Integer)casted;
    23             if (i == 0) return false;
    24             if (i == 1) return true;
    25             throw new CastFailure();
    26         }
    27         /*
    28         if (newValue instanceof String) {
    29             if (newValue.equals("true")) return true;
    30             if (newValue.equals("false")) return false;
    31             throw new CastFailure();
    32         }
    33         */
    34         throw new CastFailure();
    35     }
     28                if (newValue instanceof Integer) {
     29                        return ReassignResult.create(((Integer) newValue) != 0);
     30                }
     31                if (newValue instanceof String) {
     32                        if ("true".equals(newValue)) {
     33                                return ReassignResult.create(true);
     34                        }
     35                        if ("false".equals(newValue)) {
     36                                return ReassignResult.create(false);
     37                        }
     38                        Integer i = Numbers.cast(newValue, Integer.class);
     39                        if (i != null) {
     40                                return ReassignResult.create(i != 0);
     41                        }
     42                        throw new CastFailure();
     43                }
     44                throw new CastFailure();
     45        }
    3646
    37     @Override
    38     public String getType() {
    39         return "d 0 1";
    40     }
     47        @Override
     48        public String getFramsTypeName() {
     49                return "d 0 1";
     50        }
    4151
    42     @Override
    43     public void save(SinkInterface sink, Object value) {
    44         assert value instanceof Boolean;
    45         sink.print(((Boolean)value) ? "1" : "0");
    46     }
     52        @Override
     53        public void save(SinkInterface sink, Object value) {
     54                assert value instanceof Boolean;
     55                sink.print(((Boolean)value) ? "1" : "0");
     56        }
    4757}
  • java/main/src/main/java/com/framsticks/params/types/ColorParam.java

    r77 r84  
    11package com.framsticks.params.types;
     2
     3import com.framsticks.params.CastFailure;
     4import com.framsticks.params.PrimitiveParam;
     5import com.framsticks.params.ReassignResult;
    26
    37/**
    48 * @author Piotr Sniegowski
    59 */
    6 public class ColorParam extends ValueParam {
     10public class ColorParam extends PrimitiveParam {
    711
    812        @Override
    9         public Class getStorageType() {
    10                 return Void.class;
     13        public Class<?> getStorageType() {
     14                return Object.class;
    1115        }
    1216
    13     @Override
    14     public String getType() {
    15         return "dc";
    16     }
     17        @Override
     18        public String getFramsTypeName() {
     19                return "dc";
     20        }
    1721
     22        public ReassignResult<Object> reassign(Object newValue, Object oldValue) throws CastFailure {
     23                return ReassignResult.create(newValue);
     24        }
    1825
    1926
  • java/main/src/main/java/com/framsticks/params/types/DecimalParam.java

    r77 r84  
    22
    33import com.framsticks.params.CastFailure;
    4 import com.framsticks.util.Numbers;
     4import com.framsticks.params.ReassignResult;
    55
    66/**
    77 * @author Piotr Sniegowski
    88 */
    9 public class DecimalParam extends ValueParam {
     9public class DecimalParam extends NumberParam<Integer> {
    1010
    11         @Override
    12         public boolean isNumeric() {
    13                 return true;
     11        public DecimalParam() {
     12                def = 0;
    1413        }
    1514
    1615        @Override
    17         public Class getStorageType() {
     16        public Class<?> getStorageType() {
    1817                return Integer.class;
    1918        }
    2019
     20        @Override
     21        public ReassignResult<Integer> reassign(Object newValue, Object oldValue) throws CastFailure {
     22                return reassignNumber(newValue, oldValue, Integer.class);
     23        }
    2124
    22 
    23     @Override
    24     public Object reassign(Object newValue, Object oldValue) throws CastFailure {
    25         if (newValue instanceof String) {
    26             Integer v = Numbers.parse((String)newValue, Integer.class);
    27             if (v != null) {
    28                 return v;
    29             }
    30             throw new CastFailure();
    31         }
    32         return super.reassign(newValue, oldValue);
    33     }
    34 
    35     @Override
    36     public String getType() {
    37         return "d";
    38     }
     25        @Override
     26        public String getFramsTypeName() {
     27                return "d";
     28        }
    3929
    4030
  • java/main/src/main/java/com/framsticks/params/types/EnumParam.java

    r77 r84  
    11package com.framsticks.params.types;
    22
    3 import java.util.ArrayList;
    43import java.util.List;
    54
     
    98public class EnumParam extends DecimalParam {
    109
    11         ArrayList<String> enums;
     10        List<String> enums;
    1211
    1312        /**
     
    1615         * @param enums
    1716         */
    18         public EnumParam(ArrayList<String> enums) {
     17        public EnumParam(List<String> enums) {
    1918                assert(enums != null);
    2019                this.enums = enums;
  • java/main/src/main/java/com/framsticks/params/types/EventParam.java

    r77 r84  
    77 */
    88public class EventParam extends Param {
     9
    910        @Override
    10         public Class getStorageType() {
     11        public Class<?> getStorageType() {
    1112                return Void.class;
    1213        }
    1314
    14     @Override
    15     public String getType() {
    16         return "e";
    17     }
    18 
    19 
    20 
     15        @Override
     16        public String getFramsTypeName() {
     17                return "e";
     18        }
    2119}
  • java/main/src/main/java/com/framsticks/params/types/FloatParam.java

    r77 r84  
    22
    33import com.framsticks.params.CastFailure;
    4 import com.framsticks.util.Numbers;
     4import com.framsticks.params.ReassignResult;
    55
    66/**
    77 * @author Piotr Sniegowski
    88 */
    9 public class FloatParam extends ValueParam {
     9public class FloatParam extends NumberParam<Double> {
     10
     11        public FloatParam() {
     12                def = 0.0;
     13        }
     14
    1015        @Override
    11         public boolean isNumeric() {
    12                 return true;
    13         }
    14         @Override
    15         public Class getStorageType() {
     16        public Class<?> getStorageType() {
    1617                return Double.class;
    1718        }
    1819
    1920        @Override
    20     public Object reassign(Object newValue, Object oldValue) throws CastFailure {
    21         if (newValue instanceof String) {
    22                     Double v = Numbers.parse((String)newValue, Double.class);
    23             if (v != null) {
    24                 return v;
    25             }
    26             throw new CastFailure();
    27         }
    28         return super.reassign(newValue, oldValue);
     21        public ReassignResult<Double> reassign(Object newValue, Object oldValue) throws CastFailure {
     22                return reassignNumber(newValue, oldValue, Double.class);
    2923        }
    3024
    31     @Override
    32     public String getType() {
    33         return "f";
    34     }
     25        @Override
     26        public String getFramsTypeName() {
     27                return "f";
     28        }
    3529
    3630
  • java/main/src/main/java/com/framsticks/params/types/ListParam.java

    r77 r84  
    11package com.framsticks.params.types;
    22
    3 import com.framsticks.params.CastFailure;
    4 import com.framsticks.util.Casting;
    5 import com.framsticks.util.Containers;
    6 import com.framsticks.util.Numbers;
    7 
    8 import java.util.List;
     3import com.framsticks.params.CompositeParam;
    94
    105/**
     
    1712        }
    1813
    19 
    20 
    21 
    22 
    23 
    2414}
  • java/main/src/main/java/com/framsticks/params/types/ObjectParam.java

    r77 r84  
    33import com.framsticks.params.AccessInterface;
    44import com.framsticks.params.CastFailure;
     5import com.framsticks.params.CompositeParam;
     6import com.framsticks.params.ReassignResult;
    57
    68/**
     
    1315        }
    1416
    15     @Override
    16     public String computeAccessId() {
    17         return containedTypeName;
    18     }
     17        @Override
     18        public String computeAccessId() {
     19                return containedTypeName;
     20        }
    1921
    20     @Override
    21         public Class getStorageType() {
     22        @Override
     23        public Class<?> getStorageType() {
    2224                return Object.class;
    2325        }
    2426
    2527        @Override
    26         public boolean isEmptyAvailable() {
    27                 return true;
     28        public ReassignResult<Object> reassign(Object newValue, Object oldValue) throws CastFailure {
     29                return ReassignResult.create(newValue);
    2830        }
    2931
    3032        @Override
    31         public Object reassign(Object newValue, Object oldValue) throws CastFailure {
    32                 return newValue;
     33        public AccessInterface prepareAccessInterface(AccessInterface access) {
     34                return access;
    3335        }
    3436
    35     @Override
    36     public AccessInterface prepareAccessInterface(AccessInterface access) {
    37         return access;
    38     }
    39 
    40     @Override
    41     public String getType() {
    42         return "o " + containedTypeName;
    43     }
    44 
    45 
    46 
     37        @Override
     38        public String getFramsTypeName() {
     39                return "o " + containedTypeName;
     40        }
    4741
    4842}
  • java/main/src/main/java/com/framsticks/params/types/ProcedureParam.java

    r77 r84  
    11package com.framsticks.params.types;
    22
    3 import com.framsticks.params.CastFailure;
    4 import com.framsticks.params.FramsClass;
    53import com.framsticks.params.Param;
    64import com.framsticks.params.ParamBuilder;
    7 import com.framsticks.util.Strings;
     5import com.framsticks.util.lang.Strings;
    86
    97import java.util.ArrayList;
     
    5856
    5957        @Override
    60         public Class getStorageType() {
     58        public Class<?> getStorageType() {
    6159                return Void.class;
    6260        }
     
    7068        }
    7169
    72     @Override
    73     public Object reassign(Object newValue, Object oldValue) throws CastFailure {
    74         throw new CastFailure();
    75     }
    76 
    77     @Override
    78     public String getType() {
    79         return "p";
    80     }
     70        @Override
     71        public String getFramsTypeName() {
     72                return "p";
     73        }
    8174
    8275}
  • java/main/src/main/java/com/framsticks/params/types/StringParam.java

    r77 r84  
    22
    33import com.framsticks.params.CastFailure;
     4import com.framsticks.params.PrimitiveParam;
     5import com.framsticks.params.ReassignResult;
    46import com.framsticks.params.SinkInterface;
    57
     
    79 * @author Piotr Sniegowski
    810 */
    9 public class StringParam extends ValueParam {
     11public class StringParam extends PrimitiveParam {
    1012        @Override
    11         public Class getStorageType() {
     13        public Class<?> getStorageType() {
    1214                return String.class;
    1315        }
    1416
    1517        @Override
    16         public boolean isEmptyAvailable() {
    17                 return true;
     18        public ReassignResult<String> reassign(Object newValue, Object oldValue) throws CastFailure {
     19                if (newValue == null) {
     20                        return new ReassignResult<String>(null);
     21                }
     22                if (newValue instanceof String) {
     23                        return ReassignResult.create((String) newValue);
     24                }
     25                return ReassignResult.create(newValue.toString());
     26                // return super.reassign(newValue, oldValue);
    1827        }
    1928
    20     @Override
    21     public Object reassign(Object newValue, Object oldValue) throws CastFailure {
    22         if (newValue instanceof String) {
    23             return (String)newValue;
    24         }
    25         return super.reassign(newValue, oldValue);
    26     }
     29        @Override
     30        public String getFramsTypeName() {
     31                return "s";
     32        }
    2733
    28     @Override
    29     public String getType() {
    30         return "s";
    31     }
     34        private static final String SEPARATOR = System.getProperty("line.separator");
    3235
    33     private static final String SEPARATOR = System.getProperty("line.separator");
    34 
    35     @Override
    36     public void save(SinkInterface sink, Object value) {
    37         assert value instanceof String;
    38         String s = (String)value;
    39         sink.print((s.contains(SEPARATOR) ? (s = "~" + SEPARATOR + s + "~") : s));
    40     }
     36        @Override
     37        public void save(SinkInterface sink, Object value) {
     38                assert value instanceof String;
     39                String s = (String)value;
     40                sink.print((s.contains(SEPARATOR) ? (s = "~" + SEPARATOR + s + "~") : s));
     41        }
    4142}
  • java/main/src/main/java/com/framsticks/params/types/UniqueListParam.java

    r77 r84  
    33import com.framsticks.params.AccessInterface;
    44import com.framsticks.params.CastFailure;
     5import com.framsticks.params.ReassignResult;
    56import com.framsticks.params.UniqueListAccess;
    6 import com.framsticks.util.Numbers;
     7import com.framsticks.util.lang.Numbers;
    78
    89import java.util.HashMap;
    9 import java.util.List;
    1010import java.util.Map;
    1111
     
    1515public class UniqueListParam extends ListParam {
    1616
    17     final String uidName;
     17        final String uidName;
    1818
    19     public UniqueListParam(String containedTypeName, String uidName) {
    20         super(containedTypeName);
    21         this.uidName = uidName;
    22     }
     19        public UniqueListParam(String containedTypeName, String uidName) {
     20                super(containedTypeName);
     21                this.uidName = uidName;
     22        }
    2323
    24     @Override
    25     public String computeAccessId() {
    26         return "l " + containedTypeName + " " + uidName;
    27     }
     24        @Override
     25        public String computeAccessId() {
     26                return "l " + containedTypeName + " " + uidName;
     27        }
    2828
    2929
    30     @Override
    31     public Class getStorageType() {
    32         return Map.class;
    33     }
     30        @Override
     31        public Class<?> getStorageType() {
     32                return Map.class;
     33        }
    3434
    35     @Override
    36     public AccessInterface prepareAccessInterface(AccessInterface access) {
    37         return new UniqueListAccess(access, uidName);
    38     }
     35        @Override
     36        public AccessInterface prepareAccessInterface(AccessInterface access) {
     37                return new UniqueListAccess(access, uidName);
     38        }
    3939
     40        @Override
     41        public ReassignResult<? extends Map<?,?>> reassign(Object newValue, Object oldValue) throws CastFailure {
     42                if (newValue instanceof Map) {
     43                        return new ReassignResult<Map<?,?>>((Map<?,?>) newValue);
     44                }
     45                Integer size = Numbers.cast(newValue, Integer.class);
     46                if (size != null) {
     47                        //return oldValue;
     48                        /*
     49                        the integer value should be ignored, because this may cause, that object is created before
     50                        information about it's elements is available, which would break resolution flow
     51                        */
     52                        if (oldValue != null) {
     53                                return new ReassignResult<Map<?,?>>((Map<?,?>) oldValue);
     54                        }
     55                        return ReassignResult.create(new HashMap<Object, Object>());
     56                }
    4057
    41     @Override
    42     public Object reassign(Object newValue, Object oldValue) throws CastFailure {
    43         if (newValue instanceof Map) {
    44             return newValue;
    45         }
    46         Integer size = Numbers.cast(newValue, Integer.class);
    47         if (size != null) {
    48             //return oldValue;
    49             /*
    50             the integer value should be ignored, because this may cause, that object is created before
    51             information about it's elements is available, which would break resolution flow
    52             */
    53             if (oldValue != null) {
    54                 return oldValue;
    55             }
    56             return new HashMap();
    57         }
     58                throw new CastFailure();
     59        }
    5860
    59         throw new CastFailure();
    60     }
    61 
    62     @Override
    63     public String getType() {
    64         return "l " + containedTypeName + " " + uidName;
    65     }
     61        @Override
     62        public String getFramsTypeName() {
     63                return "l " + containedTypeName + " " + uidName;
     64        }
    6665
    6766
  • java/main/src/main/java/com/framsticks/params/types/UniversalParam.java

    r77 r84  
    22
    33import com.framsticks.params.CastFailure;
    4 import com.framsticks.util.Numbers;
     4import com.framsticks.params.PrimitiveParam;
     5import com.framsticks.params.ReassignResult;
    56
    67/**
    78 * @author Piotr Sniegowski
    89 */
    9 public class UniversalParam extends ValueParam {
     10public class UniversalParam extends PrimitiveParam {
    1011        @Override
    11         public Class getStorageType() {
     12        public Class<?> getStorageType() {
    1213                return Object.class;
    1314        }
    1415
    1516        @Override
    16         public boolean isEmptyAvailable() {
    17                 return true;
     17        public String getFramsTypeName() {
     18                return "x";
    1819        }
    1920
    20     @Override
    21     public String getType() {
    22         return "x";
    23     }
    24 
     21        @Override
     22        public ReassignResult<Object> reassign(Object newValue, Object oldValue) throws CastFailure {
     23                return ReassignResult.create(newValue);
     24        }
    2525
    2626}
  • java/main/src/main/java/com/framsticks/parsers/F0Parser.java

    r79 r84  
    77import java.text.ParseException;
    88import java.util.ArrayList;
     9import java.util.Collection;
    910import java.util.List;
    1011
     
    1415import com.framsticks.params.Flags;
    1516import com.framsticks.params.Param;
    16 import com.framsticks.util.Exceptions;
    17 import com.framsticks.util.Pair;
    18 import com.framsticks.util.Strings;
     17import com.framsticks.params.PrimitiveParam;
     18import com.framsticks.util.lang.Containers;
     19import com.framsticks.util.lang.Exceptions;
     20import com.framsticks.util.lang.Pair;
     21import com.framsticks.util.lang.Strings;
    1922import org.apache.log4j.Logger;
    2023
     
    2730public class F0Parser {
    2831
    29         private final static Logger LOGGER = Logger.getLogger(F0Parser.class);
     32        private final static Logger log = Logger.getLogger(F0Parser.class);
    3033
    3134        /** The schema proper for f0 representation. */
     
    7174         * fields (bigger than maximum or smaller than minimum values) are
    7275         * communicated by warnings and set to minimum / maximum value.
    73          * 
     76         *
    7477         * @return the list
    7578         * @throws IOException
     
    9194                                if (lineNumber == 1) {
    9295                                        if (!"//0".equals(line)) {
    93                                                 LOGGER.warn("stream should begin with \"//0\" in the first line");
     96                                                log.warn("stream should begin with \"//0\" in the first line");
    9497                                        } else {
    9598                                                continue;
     
    122125
    123126        private static void warn(int lineNumber, String message, Exception e) {
    124                 LOGGER.warn("in line " + lineNumber + " the following error occurred (" + message + "): " + e + "\n" + Exceptions.printStackTrace(e));
     127                log.warn("in line " + lineNumber + " the following error occurred (" + message + "): " + e + "\n" + Exceptions.printStackTrace(e));
    125128        }
    126129
     
    175178                List<Exception> exceptions = new ArrayList<Exception>();
    176179
    177                 Param[] params = access.getParams().toArray(new Param[] {null});
     180                Collection<Param> paramsC = access.getParams();
     181                Param[] params = paramsC.toArray(new Param[] {null});
    178182                if (params.length == 0) {
    179183                        return exceptions;
    180184                }
    181                 for (Param p : params) {
     185                for (PrimitiveParam p : Containers.filterInstanceof(paramsC, PrimitiveParam.class)) {
    182186                        Object def = p.getDef(Object.class);
    183187                        if (def != null) {
     
    210214                                        currentParam = params[nextParamNumber];
    211215                                }
    212 
    213216                                if (currentParam != null) {
    214217                                        if (pair.value != null) {
    215                                                 int setFlag = access.set(currentParam, pair.value);
     218                                                PrimitiveParam vp = (PrimitiveParam) currentParam;
     219                                                int setFlag = access.set(vp, pair.value);
    216220                                                if ((setFlag & Flags.PSET_HITMIN) != 0) {
    217                                                         exceptions.add(createBoundaryHitException(access, currentParam, pair.value, Flags.PSET_HITMIN));
     221                                                        exceptions.add(createBoundaryHitException(access, vp, pair.value, Flags.PSET_HITMIN));
    218222                                                }
    219223
    220224                                                if ((setFlag & Flags.PSET_HITMAX) != 0) {
    221                                                         exceptions.add(createBoundaryHitException(access, currentParam, pair.value, Flags.PSET_HITMAX));
     225                                                        exceptions.add(createBoundaryHitException(access, vp, pair.value, Flags.PSET_HITMAX));
    222226                                                }
    223227
     
    243247        }
    244248
    245         private static Exception createBoundaryHitException(AccessInterface access, Param param, String value, int flag) {
     249        private static Exception createBoundaryHitException(AccessInterface access, PrimitiveParam param, String value, int flag) {
    246250                boolean minimum = (flag & Flags.PSET_HITMIN) != 0;
    247251                String boundary = (minimum ? param.getMin(Object.class) : param.getMax(Object.class)).toString();
  • java/main/src/main/java/com/framsticks/parsers/Loaders.java

    r77 r84  
    99public class Loaders {
    1010
    11         private static final Logger LOGGER = Logger.getLogger(Loaders.class.getName());
     11        private static final Logger log = Logger.getLogger(Loaders.class.getName());
    1212
    1313        public static FramsClass loadFramsClass(SourceInterface source) {
     
    1515                loader.setNewSource(source);
    1616
    17         FramsClass result = new FramsClass();
     17                FramsClass result = new FramsClass();
    1818
    19         AccessInterface framsClassAccess = new ReflectionAccess(FramsClass.class, FramsClass.getFramsClass());
    20         AccessInterface paramBuilderAccess = new ReflectionAccess(ParamBuilder.class, ParamBuilder.getFramsClass());
    21         framsClassAccess.select(result);
     19                AccessInterface framsClassAccess = new ReflectionAccess(FramsClass.class, FramsClass.getFramsClass());
     20                AccessInterface paramBuilderAccess = new ReflectionAccess(ParamBuilder.class, ParamBuilder.getFramsClass());
     21                framsClassAccess.select(result);
    2222                loader.addAccessInterface(framsClassAccess);
    2323                loader.addAccessInterface(paramBuilderAccess);
     
    3131
    3232                                        Object object = loader.returnObject();
    33                     if (object instanceof FramsClass) {
    34                         continue;
    35                     }
    36                     if (object instanceof ParamBuilder) {
    37                         result.append(((ParamBuilder) object).build());
     33                                        if (object instanceof FramsClass) {
     34                                                continue;
     35                                        }
     36                                        if (object instanceof ParamBuilder) {
     37                                                result.append(((ParamBuilder) object).build());
    3838                                        }
    3939                                }
     
    4141                        return result;
    4242                } catch (Exception e) {
    43                         LOGGER.error("an error occurred while loading class description: " + e + " before " + source.readLine());
     43                        log.error("an error occurred while loading class description: " + e + " before " + source.readLine());
    4444                        e.printStackTrace();
    4545                }
  • java/main/src/main/java/com/framsticks/parsers/Savers.java

    r77 r84  
    88 */
    99public class Savers {
    10     public static void saveFramsClass(SinkInterface sink, FramsClass framsClass) {
     10        public static void saveFramsClass(SinkInterface sink, FramsClass framsClass) {
    1111
    12         AccessInterface framsClassAccess = new ReflectionAccess(FramsClass.class, FramsClass.getFramsClass());
    13         AccessInterface paramAccess = new ReflectionAccess(Param.class, Param.getFramsClass());
    14         framsClassAccess.select(framsClass);
    15         framsClassAccess.save(sink);
    16         for (Param p : framsClass.getParamEntries()) {
    17             paramAccess.select(p);
    18             paramAccess.save(sink);
    19         }
    20     }
     12                AccessInterface framsClassAccess = new ReflectionAccess(FramsClass.class, FramsClass.getFramsClass());
     13                AccessInterface paramAccess = new ReflectionAccess(Param.class, Param.getFramsClass());
     14                framsClassAccess.select(framsClass);
     15                framsClassAccess.save(sink);
     16                for (Param p : framsClass.getParamEntries()) {
     17                        paramAccess.select(p);
     18                        paramAccess.save(sink);
     19                }
     20        }
    2121
    2222}
  • java/main/src/main/java/com/framsticks/parsers/Schema.java

    r78 r84  
    11package com.framsticks.parsers;
    22
    3 import java.io.File;
    4 import java.io.FileInputStream;
    53import java.io.IOException;
    64import java.io.InputStream;
     
    86import java.util.HashMap;
    97import java.util.Map;
    10 import java.util.Map.Entry;
    118
    129import com.framsticks.params.*;
    13 import com.framsticks.params.types.DecimalParam;
    14 import com.framsticks.params.types.FloatParam;
    15 import com.framsticks.params.types.StringParam;
     10import com.framsticks.util.lang.Numbers;
    1611import org.apache.log4j.Logger;
    1712
     
    224219        }
    225220
     221        private static <T extends Number> T extractAttribute(NamedNodeMap attributes, String name, Class<T> type) {
     222                String value = getAttribute(attributes, name);
     223                if (value == null) {
     224                        return null;
     225                }
     226                return Numbers.parse(value, type);
     227        }
    226228        /**
    227229         * It analyses the single property within the class
     
    265267                }
    266268
    267                 Map<String, String> minMaxDef = new HashMap<String, String>();
    268 
    269                 for (String key : new String[] { "MIN", "MAX", "DEF" }) {
    270                         String value = getAttribute(attributes, key);
    271                         if (value != null && !value.trim().equals(""))
    272                                 minMaxDef.put(key, value);
    273                 }
    274 
    275269                ParamBuilder builder = new ParamBuilder();
    276270                builder.setId(id).setName(name).setHelp(description).setGroup(group).setFlags(flags);
    277271
     272                builder.setType(type);
     273
    278274                if ("d".equals(type)) {
    279 
    280                         Map<String, Integer> minMaxDefInt = new HashMap<String, Integer>();
    281                         for (Entry<String, String> entry : minMaxDef.entrySet()) {
    282                                 try {
    283                                         minMaxDefInt.put(entry.getKey(),
    284                                                         Integer.parseInt(entry.getValue()));
    285                                 } catch (NumberFormatException e) {
    286                                         logger.warn(entry.getKey() + " attribute in property \""
    287                                                         + id + "\" getId in class \"" + classId
    288                                                         + "\" should be an integer value");
    289                                 }
    290                         }
    291 
    292                         builder.setType(DecimalParam.class);
    293                         builder.setMin(minMaxDefInt.get("MIN"));
    294                         builder.setMax(minMaxDefInt.get("MAX"));
    295                         builder.setDef(minMaxDefInt.get("DEF"));
    296 
     275                        builder.setMin(extractAttribute(attributes, "MIN", Integer.class));
     276                        builder.setMax(extractAttribute(attributes, "MAX", Integer.class));
     277                        builder.setDef(extractAttribute(attributes, "DEF", Integer.class));
    297278                } else if ("f".equals(type)) {
    298 
    299                         Map<String, Double> minMaxDefDouble = new HashMap<String, Double>();
    300                         for (Entry<String, String> entry : minMaxDef.entrySet()) {
    301                                 try {
    302                                         minMaxDefDouble.put(entry.getKey(),
    303                                                         Double.parseDouble(entry.getValue()));
    304                                 } catch (NumberFormatException e) {
    305                                         logger.warn(entry.getKey() + " attribute in property \""
    306                                                         + id + "\" getId in class \"" + classId
    307                                                         + "\" should be a double value");
    308                                 }
    309                         }
    310                         builder.setType(FloatParam.class);
    311                         builder.setMin(minMaxDefDouble.get("MIN"));
    312                         builder.setMax(minMaxDefDouble.get("MAX"));
    313                         builder.setDef(minMaxDefDouble.get("DEF"));
    314 
    315 
     279                        builder.setMin(extractAttribute(attributes, "MIN", Double.class));
     280                        builder.setMax(extractAttribute(attributes, "MAX", Double.class));
     281                        builder.setDef(extractAttribute(attributes, "DEF", Double.class));
    316282                } else if ("s".equals(type)) {
    317                         builder.setType(StringParam.class);
    318                         builder.setDef(minMaxDef.get("DEF"));
     283                        builder.setMin(extractAttribute(attributes, "MIN", Integer.class));
     284                        builder.setMax(extractAttribute(attributes, "MAX", Integer.class));
     285                        builder.setDef(extractAttribute(attributes, "DEF", Integer.class));
     286                        builder.setDef(getAttribute(attributes, "DEF"));
    319287                } else {
    320288                        builder.setType(type);
  • java/main/src/main/java/com/framsticks/portals/Portal.java

    r78 r84  
    11package com.framsticks.portals;
    22
    3 import com.framsticks.core.Parameters;
    43import com.framsticks.observers.Observer;
    54import com.framsticks.params.FramsClass;
     
    1312public class Portal extends Observer {
    1413
    15     private final static Logger LOGGER = Logger.getLogger(Portal.class.getName());
     14        private final static Logger log = Logger.getLogger(Portal.class.getName());
    1615
    17     public Integer counter = 0;
     16        public Integer counter = 0;
    1817
    19     public Portal(Parameters parameters) {
    20         super(parameters);
    21     }
     18        public Portal() {
     19        }
    2220
    23     @Override
    24     public void run() {
    25         super.run();
    26         new PeriodicTask(this, 1000) {
     21        @Override
     22        public void run() {
     23                super.run();
     24                new PeriodicTask(this, 1000) {
    2725
    28             @Override
    29             public void run() {
    30                 ++counter;
    31                 LOGGER.debug("counter is now: " + counter);
    32                 again();
    33             }
    34         };
    35     }
     26                        @Override
     27                        public void run() {
     28                                ++counter;
     29                                log.debug("counter is now: " + counter);
     30                                again();
     31                        }
     32                };
     33        }
    3634
    37     @Override
    38     protected void configure() throws Exception {
    39         super.configure();
    40     }
     35        @Override
     36        protected PortalEndpoint createEndpoint() {
     37                return new PortalEndpoint();
     38        }
    4139
     40        public Double getCounterSquared() {
     41                return (double)(counter * counter);
     42        }
    4243
    43     @Override
    44     protected PortalEndpoint createEndpoint() {
    45         return new PortalEndpoint();
    46     }
    47 
    48     public Double getCounterSquared() {
    49         return (double)(counter * counter);
    50     }
    51 
    52     public static void constructFramsClass(FramsClass.Constructor constructor) {
    53         constructor.method("getCounterSquared").field("counter");
    54     }
     44        public static void constructFramsClass(FramsClass.Constructor constructor) {
     45                constructor.method("getCounterSquared").field("counter");
     46        }
    5547}
  • java/main/src/main/java/com/framsticks/portals/PortalEndpoint.java

    r77 r84  
    33import com.framsticks.core.Path;
    44import com.framsticks.observers.Endpoint;
    5 import com.framsticks.util.Dispatching;
    6 import com.framsticks.util.Future;
     5import com.framsticks.util.dispatching.Dispatching;
     6import com.framsticks.util.dispatching.Future;
    77import com.framsticks.util.Logging;
    88import org.apache.log4j.Logger;
     
    1313public class PortalEndpoint extends Endpoint {
    1414
    15         private final static Logger LOGGER = Logger.getLogger(PortalEndpoint.class.getName());
     15        private final static Logger log = Logger.getLogger(PortalEndpoint.class.getName());
    1616
    1717        public PortalEndpoint() {
     
    3939                    @Override
    4040                    public void result(Path result, Exception e) {
    41                         Logging.log(LOGGER, "resolve", path, e);
     41                        Logging.log(log, "resolve", path, e);
    4242                    }
    4343                });
     
    5757            @Override
    5858            public void run() {
    59                 LOGGER.debug("change at " + path);
     59                log.debug("change at " + path);
    6060            }
    6161        });
  • java/main/src/main/java/com/framsticks/remote/RecursiveFetcher.java

    r77 r84  
    44import com.framsticks.core.Path;
    55import com.framsticks.params.AccessInterface;
     6import com.framsticks.params.CompositeParam;
    67import com.framsticks.params.FramsClass;
    7 import com.framsticks.params.Param;
    8 import com.framsticks.params.types.CompositeParam;
    98import com.framsticks.core.Instance;
    10 import com.framsticks.util.Future;
     9import com.framsticks.util.dispatching.Future;
    1110import com.framsticks.util.StateFunctor;
    1211import com.framsticks.util.Stopwatch;
    1312import org.apache.log4j.Logger;
     13import static com.framsticks.util.lang.Containers.filterInstanceof;
    1414
    1515/**
     
    1818public class RecursiveFetcher {
    1919
    20     private final static Logger LOGGER = Logger.getLogger(RecursiveFetcher.class.getName());
     20        private final static Logger log = Logger.getLogger(RecursiveFetcher.class.getName());
    2121
    22     protected final Instance instance;
    23     protected final StateFunctor stateFunctor;
    24     protected int dispatched;
    25     protected final Stopwatch stopwatch = new Stopwatch();
     22        protected final Instance instance;
     23        protected final StateFunctor stateFunctor;
     24        protected int dispatched;
     25        protected final Stopwatch stopwatch = new Stopwatch();
    2626
    27     public RecursiveFetcher(Instance instance, final Path path, StateFunctor stateFunctor) {
    28         this.instance = instance;
    29         this.stateFunctor = stateFunctor;
    30         dispatched = 1;
    31         process(path);
    32     }
     27        public RecursiveFetcher(Instance instance, final Path path, StateFunctor stateFunctor) {
     28                this.instance = instance;
     29                this.stateFunctor = stateFunctor;
     30                dispatched = 1;
     31                process(path);
     32        }
    3333
    34     protected void finished() {
    35         assert instance.isActive();
    36         LOGGER.info("recursively fetched in " + stopwatch);
    37         stateFunctor.call(null);
    38     }
     34        protected void finished() {
     35                assert instance.isActive();
     36                log.info("recursively fetched in " + stopwatch);
     37                stateFunctor.call(null);
     38        }
    3939
    40     protected void process(final Path path) {
    41         assert instance.isActive();
    42         if (path == null || !path.isResolved()) {
    43             LOGGER.warn("path " + path + " is not resolved - skipping");
    44         } else {
    45             AccessInterface access = instance.bindAccess(path);
    46             FramsClass framsClass = access.getFramsClass();
    47             assert framsClass != null;
    48             for (Param p : access.getParams()) {
    49                 if (p instanceof CompositeParam) {
    50                     CompositeParam childParam = (CompositeParam)p;
    51                     Object child = access.get(childParam, Object.class);
    52                     final Path childPath = path.appendNode(new Node(childParam, child));
    53                     if (childPath.isResolved() && instance.getInfoFromCache(childPath) != null) {
    54                         ++dispatched;
    55                         instance.invokeLater(new Runnable() {
    56                             @Override
    57                             public void run() {
    58                                 fetch(childPath);
    59                             }
    60                         });
    61                         continue;
    62                     }
    63                     ++dispatched;
    64                     instance.resolve(childPath, new Future<Path>() {
    65                         @Override
    66                         public void result(Path result, Exception e) {
    67                             assert instance.isActive();
    68                             if (e != null) {
    69                                 LOGGER.error(e);
    70                                 return;
    71                             }
    72                             fetch(result);
    73                         }
    74                     });
    75                 }
    76             }
    77         }
    78         --dispatched;
    79         if (dispatched == 0) {
    80             finished();
    81         }
    82     }
     40        protected void process(final Path path) {
     41                assert instance.isActive();
     42                if (path == null || !path.isResolved()) {
     43                        log.warn("path " + path + " is not resolved - skipping");
     44                } else {
     45                        AccessInterface access = instance.bindAccess(path);
     46                        FramsClass framsClass = access.getFramsClass();
     47                        assert framsClass != null;
     48                        for (CompositeParam p : filterInstanceof(access.getParams(), CompositeParam.class)) {
     49                                Object child = access.get(p, Object.class);
     50                                final Path childPath = path.appendNode(new Node(p, child));
     51                                if (childPath.isResolved() && instance.getInfoFromCache(childPath) != null) {
     52                                        ++dispatched;
     53                                        instance.invokeLater(new Runnable() {
     54                                                @Override
     55                                                public void run() {
     56                                                        fetch(childPath);
     57                                                }
     58                                        });
     59                                        continue;
     60                                }
     61                                ++dispatched;
     62                                instance.resolve(childPath, new Future<Path>() {
     63                                        @Override
     64                                        public void result(Path result, Exception e) {
     65                                                assert instance.isActive();
     66                                                if (e != null) {
     67                                                        log.error(e);
     68                                                        return;
     69                                                }
     70                                                fetch(result);
     71                                        }
     72                                });
     73                        }
     74                }
     75                --dispatched;
     76                if (dispatched == 0) {
     77                        finished();
     78                }
     79        }
    8380
    84     protected void fetch(final Path path) {
    85         instance.fetchValues(path, new StateFunctor() {
    86             @Override
    87             public void call(Exception e) {
    88                 if (e != null) {
    89                     LOGGER.error("failed to fetch values for " + path + ": " + e);
    90                     process(null);
    91                     return;
    92                 }
    93                 process(path);
    94             }
    95         });
    96     }
     81        protected void fetch(final Path path) {
     82                instance.fetchValues(path, new StateFunctor() {
     83                        @Override
     84                        public void call(Exception e) {
     85                                if (e != null) {
     86                                        log.error("failed to fetch values for " + path + ": " + e);
     87                                        process(null);
     88                                        return;
     89                                }
     90                                process(path);
     91                        }
     92                });
     93        }
    9794
    9895}
  • java/main/src/main/java/com/framsticks/remote/RemoteInstance.java

    r77 r84  
    77import com.framsticks.communication.util.LoggingSubscriptionCallback;
    88import com.framsticks.core.ListChange;
    9 import com.framsticks.core.Parameters;
    109import com.framsticks.core.Path;
    1110import com.framsticks.params.*;
    12 import com.framsticks.params.types.CompositeParam;
    1311import com.framsticks.params.types.EventParam;
    1412import com.framsticks.parsers.MultiParamLoader;
    1513import com.framsticks.core.Instance;
    1614import com.framsticks.util.*;
     15import com.framsticks.util.dispatching.Dispatching;
     16import com.framsticks.util.dispatching.Future;
     17import com.framsticks.util.lang.Casting;
     18import com.framsticks.util.lang.Pair;
     19
     20import org.apache.commons.configuration.Configuration;
    1721import org.apache.log4j.Logger;
    1822
     
    2428public class RemoteInstance extends Instance {
    2529
    26         private final static Logger LOGGER = Logger.getLogger(RemoteInstance.class.getName());
    27 
    28     protected Path simulator;
    29     protected final ClientConnection connection;
    30 
    31     protected final Set<Pair<Path, Subscription>> subscriptions = new HashSet<Pair<Path, Subscription>>();
    32 
    33     public Pair<Path, Subscription> getSubscription(Path path) {
    34         for (Pair<Path, Subscription> s : subscriptions) {
    35             if (s.first.matches(path)) {
    36                 return s;
    37             }
    38         }
    39         return null;
    40     }
    41 
    42     @Override
    43     public void run() {
    44         assert isActive();
    45         super.run();
    46         connection.connect(new StateFunctor() {
     30        private final static Logger log = Logger.getLogger(RemoteInstance.class.getName());
     31
     32        protected Path simulator;
     33        protected ClientConnection connection;
     34
     35        protected final Set<Pair<Path, Subscription>> subscriptions = new HashSet<Pair<Path, Subscription>>();
     36
     37        public Pair<Path, Subscription> getSubscription(Path path) {
     38                for (Pair<Path, Subscription> s : subscriptions) {
     39                        if (s.first.matches(path)) {
     40                                return s;
     41                        }
     42                }
     43                return null;
     44        }
     45
     46        @Override
     47        public void run() {
     48                assert isActive();
     49                super.run();
     50                connection.connect(new StateFunctor() {
    4751                        @Override
    4852                        public void call(Exception e) {
    49                 if (e != null) {
    50                     fireRun(e);
    51                     return;
    52                 }
     53                                if (e != null) {
     54                                        fireRun(e);
     55                                        return;
     56                                }
    5357                                connection.negotiateProtocolVersion(new StateFunctor() {
    5458                                        @Override
    5559                                        public void call(Exception e) {
    5660                                                if (e != null) {
    57                                                         LOGGER.fatal("unsupported protocol version!\n minimal version is: "
     61                                                        log.fatal("unsupported protocol version!\n minimal version is: "
    5862                                                                        + "nmanager protocol is: "
    5963                                                                        + connection.getProtocolVersion());
    6064                                                        connection.close();
    61                             fireRun(e);
     65                                                        fireRun(e);
    6266                                                        return;
    6367                                                }
    6468
    65                         invokeLater(new Runnable() {
    66                             @Override
    67                             public void run() {
    68                                 resolveAndFetch("/simulator", new Future<Path>() {
    69                                     @Override
    70                                     public void result(Path path, Exception e) {
    71                                         if (e != null) {
    72                                             LOGGER.fatal("failed to resolve simulator node");
    73                                             fireRun(e);
    74                                             return;
    75                                         }
    76                                         assert isActive();
    77                                         simulator = path;
    78                                         fireRun(null);
    79                                         LOGGER.info("resolved simulator node");
    80 
    81                                         EventParam param = getParam(simulator, "running_changed", EventParam.class);
    82                                         assert param != null;
    83                                         connection.subscribe(simulator.getTextual() + "/" + param.getId(), new LoggingSubscriptionCallback(LOGGER, "server running state change", new EventCallback() {
    84                                             @Override
    85                                             public void call(List<File> files) {
    86                                                 invokeLater(new Runnable() {
    87                                                     @Override
    88                                                     public void run() {
    89                                                         updateSimulationRunning();
    90                                                     }
    91                                                 });
    92                                             }
    93                                         }));
    94                                         new PeriodicTask(RemoteInstance.this, 1000) {
    95                                             @Override
    96                                             public void run() {
    97                                                 updateSimulationRunning();
    98                                                 again();
    99                                             }
    100                                         };
    101                                     }
    102                                 });
    103                             }
    104                         });
     69                                                invokeLater(new Runnable() {
     70                                                        @Override
     71                                                        public void run() {
     72                                                                resolveAndFetch("/simulator", new Future<Path>() {
     73                                                                        @Override
     74                                                                        public void result(Path path, Exception e) {
     75                                                                                if (e != null) {
     76                                                                                        log.fatal("failed to resolve simulator node");
     77                                                                                        fireRun(e);
     78                                                                                        return;
     79                                                                                }
     80                                                                                assert isActive();
     81                                                                                simulator = path;
     82                                                                                fireRun(null);
     83                                                                                log.info("resolved simulator node");
     84
     85                                                                                EventParam param = getParam(simulator, "running_changed", EventParam.class);
     86                                                                                assert param != null;
     87                                                                                connection.subscribe(simulator.getTextual() + "/" + param.getId(), new LoggingSubscriptionCallback(log, "server running state change", new EventCallback() {
     88                                                                                        @Override
     89                                                                                        public void call(List<File> files) {
     90                                                                                                invokeLater(new Runnable() {
     91                                                                                                        @Override
     92                                                                                                        public void run() {
     93                                                                                                                updateSimulationRunning();
     94                                                                                                        }
     95                                                                                                });
     96                                                                                        }
     97                                                                                }));
     98                                                                                new PeriodicTask(RemoteInstance.this, 1000) {
     99                                                                                        @Override
     100                                                                                        public void run() {
     101                                                                                                updateSimulationRunning();
     102                                                                                                again();
     103                                                                                        }
     104                                                                                };
     105                                                                        }
     106                                                                });
     107                                                        }
     108                                                });
    105109                                        }
    106110                                });
     
    109113        }
    110114
    111         public RemoteInstance(Parameters parameters) {
    112         super(parameters);
    113         connection = new ClientConnection(config.getString("address"));
    114     }
     115        public RemoteInstance() {
     116        }
     117
     118
     119        @Override
     120        public void configure(Configuration config) {
     121                super.configure(config);
     122                connection = new ClientConnection(config.getString("address"));
     123        }
     124
     125
     126        public void setConnection(ClientConnection connection) {
     127                this.connection = connection;
     128        }
    115129
    116130        @Override
    117131        public String toString() {
    118         assert Dispatching.isThreadSafe();
     132                assert Dispatching.isThreadSafe();
    119133                return getConnection().getAddress();
    120134        }
    121135
    122136        public void setRunning(final boolean running) {
    123         assert isActive();
    124         //simulator.call(simulator.getParam(running ? "start" : "stop", ProcedureParam.class), new LoggingStateCallback(LOGGER, (running ? "starting" : "stopping") + " server"));
     137                assert isActive();
     138                //simulator.call(simulator.getParam(running ? "start" : "stop", ProcedureParam.class), new LoggingStateCallback(log, (running ? "starting" : "stopping") + " server"));
    125139        }
    126140
     
    128142
    129143        protected void updateSimulationRunning() {
    130         assert isActive();
    131         /*
    132         fetchValue(simulator, getParam(simulator, "running", Param.class), new StateFunctor() {
    133             @Override
    134             public void call(Exception e) {
    135                 if (e != null) {
    136                     LOGGER.fatal("failed to query simulator running status: " + e);
    137                     return;
    138                 }
    139 
    140                 invokeLater(new Runnable() {
    141                     @Override
    142                     public void run() {
    143                         boolean value = bindAccess(simulator).get("running", Boolean.class);
    144                         LOGGER.trace("server running: " + value);
    145                         simulationRunningListeners.call(value);
    146                     }
    147                 });
    148 
    149             }
    150         });
    151         */
     144                assert isActive();
     145                /*
     146                fetchValue(simulator, getParam(simulator, "running", Param.class), new StateFunctor() {
     147                        @Override
     148                        public void call(Exception e) {
     149                                if (e != null) {
     150                                        log.fatal("failed to query simulator running status: " + e);
     151                                        return;
     152                                }
     153
     154                                invokeLater(new Runnable() {
     155                                        @Override
     156                                        public void run() {
     157                                                boolean value = bindAccess(simulator).get("running", Boolean.class);
     158                                                log.trace("server running: " + value);
     159                                                simulationRunningListeners.call(value);
     160                                        }
     161                                });
     162
     163                        }
     164                });
     165                */
    152166        }
    153167
    154168        public void addRunningStateListener(UnaryFunctor<Boolean, Boolean> listener) {
    155         assert isActive();
    156         simulationRunningListeners.add(listener);
     169                assert isActive();
     170                simulationRunningListeners.add(listener);
    157171        }
    158172
    159173        public void disconnect() {
    160         assert isActive();
    161         if (connection.isConnected()) {
     174                assert isActive();
     175                if (connection.isConnected()) {
    162176                        connection.close();
    163177                }
    164178        }
    165179
    166     public final ClientConnection getConnection() {
    167         return connection;
    168     }
    169 
    170     @Override
    171     public void fetchValue(final Path path, final Param param, final StateFunctor stateFunctor) {
    172         assert isActive();
    173         assert param != null;
    174         assert path.isResolved();
    175         connection.send(new GetRequest().setField(param.getId()).setPath(path.getTextual()), this, new ResponseCallback() {
    176             @Override
    177             public void process(Response response) {
    178                 assert isActive();
    179                 if (!response.getOk()) {
    180                     stateFunctor.call(new Exception(response.getComment()));
    181                     return;
    182                 }
    183                 try {
    184                     processFetchedValues(path, response.getFiles());
    185                     stateFunctor.call(null);
    186                 } catch (Exception ex) {
    187                     stateFunctor.call(ex);
    188                 }
    189             }
    190         });
    191     }
    192 
    193     protected final Map<String, Set<Future<FramsClass>>> infoRequests = new HashMap<String, Set<Future<FramsClass>>>();
    194 
    195     protected void finishInfoRequest(String id, FramsClass result, Exception e) {
    196         assert isActive();
    197         Set<Future<FramsClass>> futures = infoRequests.get(id);
    198         infoRequests.remove(id);
    199         for (Future<FramsClass> f : futures) {
    200             f.result(result, e);
    201         }
    202     }
    203 
    204     @Override
    205     protected void fetchInfo(final Path path, final Future<FramsClass> future) {
    206 
    207         final String name = path.getTop().getParam().getContainedTypeName();
    208 
    209         if (infoRequests.containsKey(name)) {
    210             infoRequests.get(name).add(future);
    211             return;
    212         }
    213 
    214         LOGGER.debug("issuing info request for " + name);
    215         Set<Future<FramsClass>> futures = new HashSet<Future<FramsClass>>();
    216         futures.add(future);
    217         infoRequests.put(name, futures);
    218 
    219         //TODO: if the info is in the cache, then don't communicate
    220         connection.send(new InfoRequest().setPath(path.getTextual()), this, new ResponseCallback() {
    221             @Override
    222             public void process(Response response) {
    223                 assert isActive();
    224                 if (!response.getOk()) {
    225                     finishInfoRequest(name, null, new Exception(response.getComment()));
    226                     return;
    227                 }
    228 
    229                 assert response.getFiles().size() == 1;
    230                 assert path.isTheSame(response.getFiles().get(0).getPath());
    231                 FramsClass framsClass = processFetchedInfo(response.getFiles().get(0));
    232 
    233                 if (framsClass == null) {
    234                     LOGGER.fatal("could not read class info");
    235                     finishInfoRequest(name, null, new Exception("could not read class info"));
    236                     return;
    237                 }
    238                 CompositeParam thisParam = path.getTop().getParam();
    239                 if (!thisParam.isMatchingContainedName(framsClass.getId())) {
    240                     String mismatch = "class name mismatch: param=" + thisParam.getContainedTypeName() + " differs from fetched=" + framsClass.getId();
    241                     LOGGER.error(mismatch);
    242                     finishInfoRequest(name, null, new Exception(mismatch));
    243                     return;
    244                 }
    245                 finishInfoRequest(name, framsClass, null);
    246             }
    247         });
    248     }
    249 
    250     @Override
    251     public void fetchValues(final Path path, final StateFunctor stateFunctor) {
    252         assert isActive();
    253         assert path.getTop().getObject() != null;
    254 
    255         LOGGER.trace("fetching values for " + path);
    256         connection.send(new GetRequest().setPath(path.getTextual()), this, new ResponseCallback() {
    257             @Override
    258             public void process(Response response) {
    259                 assert isActive();
    260                 if (!response.getOk()) {
    261                     stateFunctor.call(new Exception(response.getComment()));
    262                     return;
    263                 }
    264                 try {
    265                     processFetchedValues(path, response.getFiles());
    266                     stateFunctor.call(null);
    267                 } catch (Exception ex) {
    268                     LOGGER.error("an exception occurred while loading: " + ex);
    269                     ex.printStackTrace();
    270                     stateFunctor.call(ex);
    271                 }
    272             }
    273         });
    274     }
    275 
    276     @Override
    277     public void resolve(final Path path, final Future<Path> future) {
    278         assert isActive();
    279         if (path.getTop().getObject() != null) {
    280             if (getInfoFromCache(path) != null) {
    281                 future.result(path, null);
    282                 return;
    283             }
    284             findInfo(path, new Future<FramsClass>() {
    285                 @Override
    286                 public void result(FramsClass result, Exception e) {
    287                     if (e != null) {
    288                         future.result(null, e);
    289                         return;
    290                     }
    291                     future.result(path, null);
    292                 }
    293             });
    294             return;
    295         }
    296         findInfo(path, new Future<FramsClass>() {
    297             @Override
    298             public void result(FramsClass result, Exception e) {
    299                 assert isActive();
    300                 if (e != null) {
    301                     future.result(null, e);
    302                     return;
    303                 }
    304                 assert path.getTop().getParam().isMatchingContainedName(result.getId());
    305                 Path p = (path.getTop().getParam().getContainedTypeName() != null ? path : new Path(path.getInstance(), path.getTextual()));
    306                 future.result(create(p), null);
    307             }
    308         });
    309     }
    310 
    311     @Override
    312     protected void tryRegisterOnChangeEvents(final Path path) {
    313         assert isActive();
    314         AccessInterface access = bindAccess(path);
    315         if (!(access instanceof ListAccess)) {
    316             return;
    317         }
    318 
    319 
    320         assert path.size() >= 2;
    321         FramsClass underFramsClass = getInfoFromCache(path.getUnder().getParam().getContainedTypeName());
    322 
    323         EventParam changedEvent = Casting.tryCast(EventParam.class, underFramsClass.getParamEntry(path.getTop().getParam().getId() + "_changed"));
    324         if (changedEvent == null) {
    325             return;
    326         }
    327 
    328         if (getSubscription(path) != null) {
    329             return;
    330         }
    331 
    332         final Pair<Path, Subscription> temporary = new Pair<Path, Subscription>(path, null);
    333         subscriptions.add(temporary);
    334 
    335         connection.subscribe(path.getTextual() + "_changed", new SubscriptionCallback() {
    336             @Override
    337             public EventCallback subscribed(final Subscription subscription) {
    338                 if (subscription == null) {
    339                     LOGGER.error("failed to subscribe for change event for " + path);
    340                     return null;
    341                 }
    342                 LOGGER.debug("subscribed for change event for " + path);
    343                 subscription.setDispatcher(RemoteInstance.this);
    344                 RemoteInstance.this.invokeLater(new Runnable() {
    345                     @Override
    346                     public void run() {
    347                         subscriptions.remove(temporary);
    348                         subscriptions.add(new Pair<Path, Subscription>(path, subscription));
    349                     }
    350                 });
    351                 return new EventCallback() {
    352                     @Override
    353                     public void call(List<File> files) {
    354                         assert isActive();
    355                         assert files.size() == 1;
    356                         MultiParamLoader loader = new MultiParamLoader();
    357                         loader.setNewSource(files.get(0).getContent());
    358                         loader.addBreakCondition(MultiParamLoader.Status.AfterObject);
    359                         ReflectionAccess access = new ReflectionAccess(ListChange.class, ListChange.getFramsClass());
    360                         loader.addAccessInterface(access);
    361                         MultiParamLoader.Status status;
    362                         try {
    363                             while ((status = loader.go()) != MultiParamLoader.Status.Finished) {
    364                                 if (status == MultiParamLoader.Status.AfterObject) {
    365                                     AccessInterface accessInterface = loader.getLastAccessInterface();
    366                                     reactToChange(path, (ListChange) accessInterface.getSelected());
    367                                 }
    368                             }
    369                         } catch (Exception e) {
    370                             e.printStackTrace();
    371                         }
    372                     }
    373                 };
    374             }
    375         });
    376     }
    377 
    378 
    379     protected void reactToChange(final Path path, final ListChange listChange) {
    380         assert isActive();
    381         LOGGER.debug("reacting to change " + listChange + " in " + path);
     180        public final ClientConnection getConnection() {
     181                return connection;
     182        }
     183
     184        @Override
     185        public void fetchValue(final Path path, final Param param, final StateFunctor stateFunctor) {
     186                assert isActive();
     187                assert param != null;
     188                assert path.isResolved();
     189                connection.send(new GetRequest().setField(param.getId()).setPath(path.getTextual()), this, new ResponseCallback() {
     190                        @Override
     191                        public void process(Response response) {
     192                                assert isActive();
     193                                if (!response.getOk()) {
     194                                        stateFunctor.call(new Exception(response.getComment()));
     195                                        return;
     196                                }
     197                                try {
     198                                        processFetchedValues(path, response.getFiles());
     199                                        stateFunctor.call(null);
     200                                } catch (Exception ex) {
     201                                        stateFunctor.call(ex);
     202                                }
     203                        }
     204                });
     205        }
     206
     207        protected final Map<String, Set<Future<FramsClass>>> infoRequests = new HashMap<String, Set<Future<FramsClass>>>();
     208
     209        protected void finishInfoRequest(String id, FramsClass result, Exception e) {
     210                assert isActive();
     211                Set<Future<FramsClass>> futures = infoRequests.get(id);
     212                infoRequests.remove(id);
     213                for (Future<FramsClass> f : futures) {
     214                        f.result(result, e);
     215                }
     216        }
     217
     218        @Override
     219        protected void fetchInfo(final Path path, final Future<FramsClass> future) {
     220
     221                final String name = path.getTop().getParam().getContainedTypeName();
     222
     223                if (infoRequests.containsKey(name)) {
     224                        infoRequests.get(name).add(future);
     225                        return;
     226                }
     227
     228                log.debug("issuing info request for " + name);
     229                Set<Future<FramsClass>> futures = new HashSet<Future<FramsClass>>();
     230                futures.add(future);
     231                infoRequests.put(name, futures);
     232
     233                //TODO: if the info is in the cache, then don't communicate
     234                connection.send(new InfoRequest().setPath(path.getTextual()), this, new ResponseCallback() {
     235                        @Override
     236                        public void process(Response response) {
     237                                assert isActive();
     238                                if (!response.getOk()) {
     239                                        finishInfoRequest(name, null, new Exception(response.getComment()));
     240                                        return;
     241                                }
     242
     243                                assert response.getFiles().size() == 1;
     244                                assert path.isTheSame(response.getFiles().get(0).getPath());
     245                                FramsClass framsClass = processFetchedInfo(response.getFiles().get(0));
     246
     247                                if (framsClass == null) {
     248                                        log.fatal("could not read class info");
     249                                        finishInfoRequest(name, null, new Exception("could not read class info"));
     250                                        return;
     251                                }
     252                                CompositeParam thisParam = path.getTop().getParam();
     253                                if (!thisParam.isMatchingContainedName(framsClass.getId())) {
     254                                        String mismatch = "class name mismatch: param=" + thisParam.getContainedTypeName() + " differs from fetched=" + framsClass.getId();
     255                                        log.error(mismatch);
     256                                        finishInfoRequest(name, null, new Exception(mismatch));
     257                                        return;
     258                                }
     259                                finishInfoRequest(name, framsClass, null);
     260                        }
     261                });
     262        }
     263
     264        @Override
     265        public void fetchValues(final Path path, final StateFunctor stateFunctor) {
     266                assert isActive();
     267                assert path.getTop().getObject() != null;
     268
     269                log.trace("fetching values for " + path);
     270                connection.send(new GetRequest().setPath(path.getTextual()), this, new ResponseCallback() {
     271                        @Override
     272                        public void process(Response response) {
     273                                assert isActive();
     274                                if (!response.getOk()) {
     275                                        stateFunctor.call(new Exception(response.getComment()));
     276                                        return;
     277                                }
     278                                try {
     279                                        processFetchedValues(path, response.getFiles());
     280                                        stateFunctor.call(null);
     281                                } catch (Exception ex) {
     282                                        log.error("an exception occurred while loading: " + ex);
     283                                        ex.printStackTrace();
     284                                        stateFunctor.call(ex);
     285                                }
     286                        }
     287                });
     288        }
     289
     290        @Override
     291        public void resolve(final Path path, final Future<Path> future) {
     292                assert isActive();
     293                if (path.getTop().getObject() != null) {
     294                        if (getInfoFromCache(path) != null) {
     295                                future.result(path, null);
     296                                return;
     297                        }
     298                        findInfo(path, new Future<FramsClass>() {
     299                                @Override
     300                                public void result(FramsClass result, Exception e) {
     301                                        if (e != null) {
     302                                                future.result(null, e);
     303                                                return;
     304                                        }
     305                                        future.result(path, null);
     306                                }
     307                        });
     308                        return;
     309                }
     310                findInfo(path, new Future<FramsClass>() {
     311                        @Override
     312                        public void result(FramsClass result, Exception e) {
     313                                assert isActive();
     314                                if (e != null) {
     315                                        future.result(null, e);
     316                                        return;
     317                                }
     318                                assert path.getTop().getParam().isMatchingContainedName(result.getId());
     319                                Path p = (path.getTop().getParam().getContainedTypeName() != null ? path : path.tryFindResolution());
     320                                future.result(createIfNeeded(p), null);
     321                        }
     322                });
     323        }
     324
     325        @Override
     326        protected void tryRegisterOnChangeEvents(final Path path) {
     327                assert isActive();
     328                AccessInterface access = bindAccess(path);
     329                if (!(access instanceof ListAccess)) {
     330                        return;
     331                }
     332
     333
     334                assert path.size() >= 2;
     335                FramsClass underFramsClass = getInfoFromCache(path.getUnder().getParam().getContainedTypeName());
     336
     337                EventParam changedEvent = underFramsClass.getParamEntry(path.getTop().getParam().getId() + "_changed", EventParam.class);
     338                if (changedEvent == null) {
     339                        return;
     340                }
     341
     342                if (getSubscription(path) != null) {
     343                        return;
     344                }
     345
     346                final Pair<Path, Subscription> temporary = new Pair<Path, Subscription>(path, null);
     347                subscriptions.add(temporary);
     348
     349                connection.subscribe(path.getTextual() + "_changed", new SubscriptionCallback() {
     350                        @Override
     351                        public EventCallback subscribed(final Subscription subscription) {
     352                                if (subscription == null) {
     353                                        log.error("failed to subscribe for change event for " + path);
     354                                        return null;
     355                                }
     356                                log.debug("subscribed for change event for " + path);
     357                                subscription.setDispatcher(RemoteInstance.this);
     358                                RemoteInstance.this.invokeLater(new Runnable() {
     359                                        @Override
     360                                        public void run() {
     361                                                subscriptions.remove(temporary);
     362                                                subscriptions.add(new Pair<Path, Subscription>(path, subscription));
     363                                        }
     364                                });
     365                                return new EventCallback() {
     366                                        @Override
     367                                        public void call(List<File> files) {
     368                                                assert isActive();
     369                                                assert files.size() == 1;
     370                                                MultiParamLoader loader = new MultiParamLoader();
     371                                                loader.setNewSource(files.get(0).getContent());
     372                                                loader.addBreakCondition(MultiParamLoader.Status.AfterObject);
     373                                                ReflectionAccess access = new ReflectionAccess(ListChange.class, ListChange.getFramsClass());
     374                                                loader.addAccessInterface(access);
     375                                                MultiParamLoader.Status status;
     376                                                try {
     377                                                        while ((status = loader.go()) != MultiParamLoader.Status.Finished) {
     378                                                                if (status == MultiParamLoader.Status.AfterObject) {
     379                                                                        AccessInterface accessInterface = loader.getLastAccessInterface();
     380                                                                        reactToChange(path, (ListChange) accessInterface.getSelected());
     381                                                                }
     382                                                        }
     383                                                } catch (Exception e) {
     384                                                        e.printStackTrace();
     385                                                }
     386                                        }
     387                                };
     388                        }
     389                });
     390        }
     391
     392
     393        protected void reactToChange(final Path path, final ListChange listChange) {
     394                assert isActive();
     395                log.debug("reacting to change " + listChange + " in " + path);
    382396                AccessInterface access = bindAccess(path);
    383397                assert access != null;
     
    389403                                public void result(Path result, Exception e) {
    390404                                        if (e != null) {
    391                                                 LOGGER.error("failed to modify " + p + ": " + e);
     405                                                log.error("failed to modify " + p + ": " + e);
    392406                                                return;
    393407                                        }
     
    399413
    400414
    401         CompositeParam childParam = Casting.tryCast(CompositeParam.class, access.getParam(listChange.getBestIdentifier()));
    402         assert childParam != null;
    403         switch (listChange.getAction()) {
    404             case Add: {
    405                 final String p = path.getTextual() + "/" + childParam.getId();
    406                 resolveAndFetch(p, new Future<Path>() {
    407                     @Override
    408                     public void result(Path result, Exception e) {
    409                         if (e != null) {
    410                             LOGGER.error("failed to add " + p + ": " + e);
    411                             return;
    412                         }
    413                         LOGGER.debug("added: " + result);
    414                         fireListChange(path, listChange);
    415                     }
    416                 });
    417                 break;
    418             }
    419             case Remove: {
    420                 access.set(childParam, null);
    421                 fireListChange(path, listChange);
    422                 break;
    423             }
    424             case Modify: {
    425                 final String p = path.getTextual() + "/" + childParam.getId();
    426                 resolveAndFetch(p, new Future<Path>() {
    427                     @Override
    428                     public void result(Path result, Exception e) {
    429                         if (e != null) {
    430                             LOGGER.error("failed to modify " + p + ": " + e);
    431                             return;
    432                         }
    433                         fireListChange(path, listChange);
    434                     }
    435                 });
    436                 break;
    437             }
    438         }
    439     }
    440 
     415                CompositeParam childParam = Casting.tryCast(CompositeParam.class, access.getParam(listChange.getBestIdentifier()));
     416                assert childParam != null;
     417                switch (listChange.getAction()) {
     418                        case Add: {
     419                                final String p = path.getTextual() + "/" + childParam.getId();
     420                                resolveAndFetch(p, new Future<Path>() {
     421                                        @Override
     422                                        public void result(Path result, Exception e) {
     423                                                if (e != null) {
     424                                                        log.error("failed to add " + p + ": " + e);
     425                                                        return;
     426                                                }
     427                                                log.debug("added: " + result);
     428                                                fireListChange(path, listChange);
     429                                        }
     430                                });
     431                                break;
     432                        }
     433                        case Remove: {
     434                                access.set(childParam, null);
     435                                fireListChange(path, listChange);
     436                                break;
     437                        }
     438                        case Modify: {
     439                                final String p = path.getTextual() + "/" + childParam.getId();
     440                                resolveAndFetch(p, new Future<Path>() {
     441                                        @Override
     442                                        public void result(Path result, Exception e) {
     443                                                if (e != null) {
     444                                                        log.error("failed to modify " + p + ": " + e);
     445                                                        return;
     446                                                }
     447                                                fireListChange(path, listChange);
     448                                        }
     449                                });
     450                                break;
     451                        }
     452                }
     453        }
     454
     455        //TODO ValueParam
    441456        @Override
    442457        public void storeValue(final Path path, final Param param, final Object value, final StateFunctor stateFunctor) {
    443458                assert isActive();
    444459
    445                 LOGGER.trace("storing value " + param + " for " + path);
     460                log.trace("storing value " + param + " for " + path);
    446461                connection.send(new SetRequest().value(value.toString()).setField(param.getId()).setPath(path.getTextual()), this, new StateCallback() {
    447462                        @Override
    448463                        public void call(Exception e) {
    449464                                if (e == null) {
    450                                         bindAccess(path).set(param, value);
     465                                        bindAccess(path).set((ValueParam) param, value);
    451466                                }
    452467                                stateFunctor.call(e);
  • java/main/src/main/java/com/framsticks/util/PeriodicTask.java

    r77 r84  
    11package com.framsticks.util;
     2
     3import com.framsticks.util.dispatching.Dispatcher;
     4import com.framsticks.util.dispatching.Task;
    25
    36/**
  • java/main/src/main/java/com/framsticks/util/UnsupportedOperationException.java

    r77 r84  
    66public class UnsupportedOperationException extends Exception {
    77
     8        /**
     9         *
     10         */
     11        private static final long serialVersionUID = -8006030446614381094L;
     12
    813}
  • java/main/src/main/java/com/framsticks/visualization/Viewer.java

    r78 r84  
    11package com.framsticks.visualization;
    22
    3 import com.framsticks.model.World;
    43import com.sun.j3d.loaders.IncorrectFormatException;
    54import com.sun.j3d.loaders.ParsingErrorException;
     
    1312import javax.media.j3d.*;
    1413import javax.swing.*;
    15 import javax.swing.text.StyledDocument;
    1614import javax.vecmath.Color3f;
    1715import javax.vecmath.Point3d;
    1816import javax.vecmath.Vector3f;
    1917import java.awt.*;
    20 import java.awt.event.ActionEvent;
    21 import java.awt.event.ActionListener;
    22 import java.io.FileNotFoundException;
     18import java.io.*;
    2319
    24 import org.apache.log4j.Logger;
     20// import org.apache.log4j.Logger;
    2521
    2622public class Viewer {
    2723
    28     private static Logger LOGGER = Logger.getLogger(Viewer.class);
     24    // private static Logger log = Logger.getLogger(Viewer.class);
    2925
    3026    Canvas3D canvas3d;
    3127    SimpleUniverse universe;
    3228
    33     World world;
    34     private JMenuBar menuBar;
    35 
    36         private JScrollPane scrollPane;
    37     private boolean scrollLock = false;
    38 
    39         private JCheckBoxMenuItem loggingItem;
    40     private JCheckBoxMenuItem autorefreshItem;
    41 
    42     public Viewer(JMenuBar menuBar) {
     29    public Viewer() {
    4330        super();
    44         this.menuBar = menuBar;
    45         loggingItem = new JCheckBoxMenuItem("Logging");
    46         loggingItem.setSelected(true);
    4731
    4832        init();
     
    6650        objScale.addChild(objTrans);
    6751
    68         String filename = "/static/shared/res/obj/cylinder.obj";
     52        String filename = "/visualization/models/cylinder.obj";
    6953        int flags = ObjectFile.RESIZE;
    7054        flags |= ObjectFile.TRIANGULATE;
     
    7559        Scene s = null;
    7660        try {
    77             s = f.load(this.getClass().getResource(filename).getFile());
     61                        InputStream is = this.getClass().getResourceAsStream(filename);
     62            s = f.load(new InputStreamReader(is));
    7863        } catch (FileNotFoundException e) {
    7964            System.err.println(e);
     
    8974        objTrans.addChild(s.getSceneGroup());
    9075
    91         BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0),
    92                 100.0);
     76        BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0);
    9377
    9478        Color3f bgColor = new Color3f(0.05f, 0.05f, 0.5f);
     
    10589        textPane.setEditable(false);
    10690
    107             StyledDocument styledDocument = textPane.getStyledDocument();
    108 
    109         scrollPane = new JScrollPane(textPane);
    110         //scrollPane.
    111         //scrollPane
    112         //              .setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
    113 
    114         // paneScrollPane.setMinimumSize(new Dimension(400, 300));
    115 
    116         createMenuBar();
    117 
    118         GraphicsConfiguration config = SimpleUniverse
    119                 .getPreferredConfiguration();
     91        GraphicsConfiguration config = SimpleUniverse.getPreferredConfiguration();
    12092
    12193        // Create a Canvas3D using the preferred configuration
     
    12496        // Create simple universe with view branch
    12597        universe = new SimpleUniverse(canvas3d);
    126         BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0),
    127                 100.0);
     98        BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0);
    12899
    129100        // add mouse behaviours to the ViewingPlatform
     
    173144        // behaviour.addListener(canvas3d);
    174145        // behaviour.initialize();
    175         behaviour.setSchedulingBounds(new BoundingSphere(new Point3d(0.0, 0.0,
    176                 0.0), 100.0));
     146        behaviour.setSchedulingBounds(new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0));
    177147        transformGroup.addChild(content);
    178148        // transformGroup.addChild(behaviour);
     
    180150
    181151        universe.addBranchGraph(scene);
    182 
    183 
    184     }
    185 
    186     private void createMenuBar() {
    187 
    188         JMenu serverItem = new JMenu("Manager");
    189         menuBar.add(serverItem);
    190 
    191         JMenuItem testModeItem = new JMenuItem("Test mode");
    192         serverItem.add(testModeItem);
    193 
    194             JMenuItem connectItem = new JMenuItem("Connect");
    195         serverItem.add(connectItem);
    196 
    197         JMenu simulationItem = new JMenu("Simulation");
    198         menuBar.add(simulationItem);
    199 
    200             //TODO: move init to main window
    201         JMenuItem initItem = new JMenuItem("Init");
    202         simulationItem.add(initItem);
    203         initItem.addActionListener(new ActionListener() {
    204             public void actionPerformed(ActionEvent event) {
    205             }
    206         });
    207 
    208         JMenuItem refreshCreaturesItem = new JMenuItem("Refresh creatures");
    209         simulationItem.add(refreshCreaturesItem);
    210         refreshCreaturesItem.addActionListener(new ActionListener() {
    211             public void actionPerformed(ActionEvent event) {
    212 
    213             }
    214         });
    215 
    216         JMenuItem refreshWorldItem = new JMenuItem("Refresh world");
    217         simulationItem.add(refreshWorldItem);
    218         refreshWorldItem.addActionListener(new ActionListener() {
    219             public void actionPerformed(ActionEvent event) {
    220                 refreshWorld();
    221             }
    222         });
    223 
    224             JMenu styleMenu = new JMenu("Style");
    225         menuBar.add(styleMenu);
    226 
    227             JMenu viewMenu = new JMenu("View");
    228         menuBar.add(viewMenu);
    229         rebuildViewMenu(null);
    230 
    231         JMenu optionsMenu = new JMenu("Options");
    232         menuBar.add(optionsMenu);
    233 
    234         autorefreshItem = new JCheckBoxMenuItem("Autorefresh");
    235         autorefreshItem.addActionListener(new ActionListener() {
    236             public void actionPerformed(ActionEvent e) {
    237                 if (autorefreshItem.isSelected()) {
    238 
    239                 }
    240             }
    241         });
    242         optionsMenu.add(autorefreshItem);
    243 
    244         optionsMenu.add(loggingItem);
    245 
    246     }
    247 
    248     public void refreshWorld() {
    249 
    250 
    251     }
    252 
    253     public void rebuildViewMenu(Object creatures) {
    254 
     152                canvas3d.startRenderer();
     153                Dimension d = new Dimension(500, 500);
     154                canvas3d.setMinimumSize(d);
     155                canvas3d.setSize(d);
    255156    }
    256157
     
    259160    }
    260161
    261     public Component getControlComponent() {
    262         return scrollPane;
    263     }
    264162
    265163}
  • java/main/src/main/resources/configs/framsticks.properties

    r78 r84  
    22com.framsticks.entities.browser.size.width=1500
    33com.framsticks.entities.browser.size.height=800
    4 com.framsticks.entities.browser.endpoints=localhost,dump,genotype_browser
     4# com.framsticks.entities.browser.endpoints=localhost,dump,genotype_browser
     5com.framsticks.entities.browser.endpoints=localhost
    56com.framsticks.entities.browser.endpoints.dump.entity.class=com.framsticks.dumping.FileInstance
    67com.framsticks.entities.browser.endpoints.dump.entity.filename=dumps/localhost:9009__.param
     
    89com.framsticks.entities.browser.endpoints.remote_portal.entity.mount=com.framsticks.entities.remote_portal
    910com.framsticks.entities.browser.endpoints.genotype_browser.entity.mount=com.framsticks.entities.genotype_browser
     11com.framsticks.entities.browser.panel_providers=com.framsticks.visualization.SingleViewPanelProvider
     12com.framsticks.entities.browser.resolve_paths=/simulator
    1013
    1114com.framsticks.entities.diagnostics.class=com.framsticks.diagnostics.Diagnostics
  • java/main/src/main/resources/configs/log4j.properties

    r78 r84  
    2929
    3030log4j.logger.com.framsticks=INFO
     31# log4j.logger.com.framsticks.gui.controls.SliderControl=TRACE
     32# log4j.logger.com.framsticks.gui.EndpointAtFrame=DEBUG
     33# log4j.logger.com.framsticks.gui.TreeNode=DEBUG
     34# log4j.logger.com.framsticks.gui.Frame=TRACE
     35# log4j.logger.com.framsticks.gui.Browser=DEBUG
     36
     37#log4j.logger.com.framsticks.gui.Frame=DEBUG
     38#log4j.logger.com.framsticks.gui.Browser=DEBUG
     39#log4j.logger.com.framsticks.gui.EndpointAtFrame=DEBUG
    3140#log4j.logger.com.framsticks.remote.RemoteInstance=DEBUG
    3241#log4j.logger.com.framsticks.gui.TreeNode=DEBUG
  • java/main/src/test/java/com/framsticks/parsers/F0ParserTest.java

    r79 r84  
    11package com.framsticks.parsers;
    22
     3import org.testng.annotations.*;
    34import com.framsticks.model.*;
    45import com.framsticks.model.Package;
    56import com.framsticks.params.*;
    67import com.framsticks.params.types.FloatParam;
    7 import com.framsticks.util.Point3d;
    8 import org.apache.log4j.PropertyConfigurator;
    9 import org.junit.Test;
     8import com.framsticks.test.TestConfiguration;
     9import com.framsticks.util.math.Point3d;
    1010
     11import java.io.IOException;
     12import java.text.ParseException;
    1113import java.util.List;
    12 
    13 import static org.junit.Assert.*;
     14import static org.fest.assertions.Assertions.*;
     15import static org.fest.assertions.Delta.*;
    1416
    1517/**
    1618 * Author: Piotr Śniegowski
    1719 */
    18 public class F0ParserTest {
     20public class F0ParserTest extends TestConfiguration {
     21
     22        private Schema schema;
     23        private List<AccessInterface> accesses;
     24        private List<Object> objects;
     25        private Model model;
     26
     27        @BeforeClass
     28        public void setUp() throws Exception {
     29                schema = new Schema(Schema.getDefaultDefinitionAsStream());
     30                Package.register(schema.getRegistry());
     31        }
    1932
    2033        @Test
    21         public void testParser() throws Exception {
    22                 PropertyConfigurator.configure(getClass().getResource("/log4j.properties"));
    23                 //testing schema
    24                 Schema schema = new Schema(Schema.getDefaultDefinitionAsStream());
     34        public void primitiveParam() {
     35                FramsClass joint = schema.getRegistry().getInfoFromCache("j");
     36                PrimitiveParam dx = joint.getParamEntry("dx", PrimitiveParam.class);
     37                assertThat(dx).isInstanceOf(FloatParam.class);
     38                assertThat(schema.getNeuroClasses().size()).isEqualTo(21);
     39                assertThat(dx.getName()).isEqualTo("delta.x");
     40                assertThat(dx.getMin(Double.class)).isEqualTo(-2.0, delta(0.0));
     41        }
    2542
    26                 {
    27                         FramsClass joint = schema.getRegistry().getInfoFromCache("j");
    28                         Param dx = joint.getParamEntry("dx");
    29                         assertEquals(FloatParam.class, dx.getClass());
    30                         assertEquals(21, schema.getNeuroClasses().size());
    31                         assertEquals("delta.x", dx.getName());
    32                         assertEquals(-2.0, dx.getMin(Double.class), 0.0);
    33                 }
     43        @Test
     44        public void readF0() throws IOException, ParseException {
     45                accesses = new F0Parser(schema, F0ParserTest.class.getResourceAsStream("/parsers/f0_example.txt")).parse();
    3446
    35                 Package.register(schema.getRegistry());
    36                 //testing parser
    37                 List<AccessInterface> accesses = new F0Parser(schema, F0ParserTest.class.getResourceAsStream("/parsers/f0_example.txt")).parse();
     47                assertThat(accesses.size()).isEqualTo(12);
     48                assertThat(accesses.get(0).getSelected()).isInstanceOf(Model.class);
     49                assertThat(accesses.get(5).get("i", String.class)).isEqualTo("1,2,3,\"dsadsa,,,,");
     50                assertThat(accesses.get(7).get("d", String.class)).isEqualTo("|:p=0.25,r=1");
     51                assertThat(accesses.get(10).get("d", String.class)).isEqualTo("@:p=0.25");
     52        }
    3853
    39                 {
    40                         assertEquals(12, accesses.size());
    41                         assertTrue(accesses.get(0).getSelected() instanceof Model);
    42                         assertEquals("1,2,3,\"dsadsa,,,,", accesses.get(5).get("i", String.class));
    43                         assertEquals("|:p=0.25,r=1", accesses.get(7).get("d", String.class));
    44                         assertEquals("@:p=0.25", accesses.get(10).get("d", String.class));
    45                 }
     54        @Test(dependsOnMethods = {"readF0"})
     55        public void stripAccessInterface() {
     56                objects = Util.stripAccessInterface(accesses);
    4657
    47                 List<Object> objects = Util.stripAccessInterface(accesses);
    48                 {
    49                         assertEquals(Part.class, objects.get(1).getClass());
    50                         assertEquals(Joint.class, objects.get(4).getClass());
    51                         assertEquals(NeuroDef.class, objects.get(6).getClass());
    52                 }
     58                assertThat(objects.get(1)).isInstanceOf(Part.class);
     59                assertThat(objects.get(4)).isInstanceOf(Joint.class);
     60                assertThat(objects.get(6)).isInstanceOf(NeuroDef.class);
     61        }
    5362
    54                 Model model = Model.build(objects);
    55                 {
    56                         assertEquals(3, model.getParts().size());
    57                         assertEquals(6, model.getNeuroDefs().size());
    58                         assertEquals(2, model.getJoints().size());
     63        @Test(dependsOnMethods = {"stripAccessInterface"})
     64        public void buildModel() {
     65                model = Model.build(objects);
    5966
    60                         assertEquals(new Integer(0), model.getJoints().get(0).part1);
    61                         assertEquals(new Integer(1), model.getJoints().get(0).part2);
    62                         assertEquals(new Integer(1), model.getNeuroDefs().get(0).part);
    63                         assertEquals(new Integer(-1), model.getNeuroDefs().get(0).joint);
    64                         assertEquals("|:p=0.25,r=1", model.getNeuroDefs().get(1).details);
    65                         assertEquals("N", model.getNeuroDefs().get(3).details);
    66                         assertEquals(new Integer(-1), model.getNeuroDefs().get(4).part);
     67                assertThat(model.getParts().size()).isEqualTo(3);
     68                assertThat(model.getNeuroDefs().size()).isEqualTo(6);
     69                assertThat(model.getJoints().size()).isEqualTo(2);
    6770
    68                         assertEquals(2.0, model.getParts().get(1).getPosition().x, 0.0);
    69                         assertTrue(model.getParts().get(2).getPosition().sub(new Point3d(2.27236, -0.0792596, -0.958924)).length() < 0.0001);
    70                         assertTrue(model.getParts().get(2).getOrientation().y.sub(new Point3d(0.870277, -0.404792, 0.280644)).length() < 0.0001);
    71                 }
     71                assertThat(model.getJoints().get(0).part1).isEqualTo(0);
     72                assertThat(model.getJoints().get(0).part2).isEqualTo(1);
     73                assertThat(model.getNeuroDefs().get(0).part).isEqualTo(1);
     74                assertThat(model.getNeuroDefs().get(0).joint).isEqualTo(-1);
     75                assertThat(model.getNeuroDefs().get(1).details).isEqualTo("|:p=0.25,r=1");
     76                assertThat(model.getNeuroDefs().get(3).details).isEqualTo("N");
     77                assertThat(model.getNeuroDefs().get(4).part).isEqualTo(-1);
    7278
     79                assertThat(model.getParts().get(1).getPosition().x).isEqualTo(2.0, delta(0.0));
     80                assertThat(model.getParts().get(2).getPosition().sub(new Point3d(2.27236, -0.0792596, -0.958924)).length()).isLessThan(0.0001);
     81                assertThat(model.getParts().get(2).getOrientation().y.sub(new Point3d(0.870277, -0.404792, 0.280644)).length()).isLessThan(0.0001);
     82        }
     83
     84        @Test(dependsOnMethods = {"buildModel"})
     85        public void print() throws Exception {
     86                ListSink sink = new ListSink();
     87                new F0Writer(schema, model, sink).write();
     88
     89                assertThat(sink.getOut()).containsExactly(
     90                        "p:",
     91                        "p:2.0,i=,Vstyle=",
     92                        "p:2.272364001928095,-0.07925961087140347,-0.9589242746631385,i=bla",
     93                        "j:0,1,dx=2.0",
     94                        "j:1,2,rx=8.0,5.0,6.0,dx=1.0,i=\"1,2,3,\\\"dsadsa,,,,\"",
     95                        "n:p=1",
     96                        "n:j=0,d=\"|:p=0.25,r=1\"",
     97                        "n:j=0,d=G",
     98                        "n:p=1",
     99                        "n:j=0,d=@:p=0.25",
     100                        "n:p=1,d=Nu",
     101                        "m:"
     102                );
    73103
    74104        }
  • java/main/src/test/resources/log4j.properties

    r78 r84  
    2727
    2828log4j.logger.com.framsticks=INFO
     29# log4j.logger.com.framsticks.gui.controls.SliderControl=TRACE
     30# log4j.logger.com.framsticks.communication.ClientConnection=DEBUG
Note: See TracChangeset for help on using the changeset viewer.