- Timestamp:
- 06/22/13 21:51:33 (10 years ago)
- Location:
- java/main
- Files:
-
- 62 added
- 22 deleted
- 110 edited
Legend:
- Unmodified
- Added
- Removed
-
java/main
-
Property
svn:ignore
set to
target
-
Property
svn:ignore
set to
-
java/main/pom.xml
r78 r84 1 1 <?xml version="1.0" encoding="UTF-8"?> 2 2 <project xmlns="http://maven.apache.org/POM/4.0.0" 3 4 5 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> 6 6 7 8 9 7 <groupId>framsticks</groupId> 8 <artifactId>framsticks</artifactId> 9 <version>1.0</version> 10 10 11 11 <repositories> … … 18 18 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 19 19 </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 34 20 <dependencies> 35 21 <dependency> … … 42 28 <groupId>commons-configuration</groupId> 43 29 <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> 45 37 <scope>compile</scope> 46 38 </dependency> … … 61 53 </dependency> 62 54 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> 70 60 </dependency> 71 61 <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--> 73 83 </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 74 125 </project> -
java/main/src/main/java/com/framsticks/communication/ClientConnection.java
r77 r84 8 8 import com.framsticks.params.ListSource; 9 9 import com.framsticks.util.*; 10 import com.framsticks.util.dispatching.AtOnceDispatcher; 11 import com.framsticks.util.dispatching.Dispatcher; 12 import com.framsticks.util.dispatching.Dispatching; 13 import com.framsticks.util.lang.Pair; 14 import com.framsticks.util.lang.Strings; 10 15 import org.apache.log4j.Logger; 11 16 12 import java.io.BufferedReader;13 17 import java.io.IOException; 14 import java.io.InputStreamReader;15 import java.io.PrintWriter;16 18 import java.net.Socket; 17 19 import java.net.SocketException; … … 25 27 public class ClientConnection extends Connection { 26 28 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 } 390 393 391 394 } -
java/main/src/main/java/com/framsticks/communication/Connection.java
r77 r84 1 1 package com.framsticks.communication; 2 2 3 import com.framsticks.util. Pair;3 import com.framsticks.util.lang.Pair; 4 4 import org.apache.log4j.Logger; 5 5 import java.io.BufferedReader; … … 15 15 public abstract class Connection { 16 16 17 protected final static Logger LOGGER= Logger.getLogger(Connection.class);17 protected final static Logger log = Logger.getLogger(Connection.class); 18 18 19 19 protected PrintWriter output = null; … … 28 28 protected int protocolVersion = -1; 29 29 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(); 31 31 protected Thread receiverThread; 32 32 … … 40 40 connected = false; 41 41 42 43 42 senderThread.interrupt(); 43 senderThread.join(); 44 44 if (receiverThread != null) { 45 45 receiverThread.interrupt(); … … 64 64 } 65 65 66 LOGGER.info("connection closed");66 log.info("connection closed"); 67 67 } catch (Exception e) { 68 LOGGER.error(e);68 log.error(e); 69 69 } 70 70 … … 77 77 78 78 79 80 81 82 LOGGER.fatal("unmatched first line of input: " + rest);83 84 85 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 } 87 87 88 88 static final int BUFFER_LENGTH = 1024; 89 89 90 91 92 93 90 int readChars = 0; 91 int iterator = 0; 92 int bufferStart = 0; 93 char[] readBuffer = new char[BUFFER_LENGTH]; 94 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 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); 109 109 110 111 112 113 114 115 116 117 118 119 120 121 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 } 123 123 124 124 protected abstract void receiverThreadRoutine() throws Exception; 125 125 126 127 128 129 130 131 LOGGER.error("buffer creation failure");132 133 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 } 135 135 136 137 138 139 140 141 142 143 LOGGER.debug("receiver thread interrupted");144 145 LOGGER.error("error: " + e);146 147 148 149 150 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"); 151 151 152 153 154 152 senderThread.start(); 153 receiverThread.start(); 154 } 155 155 156 156 -
java/main/src/main/java/com/framsticks/communication/EventCallback.java
r77 r84 1 1 package com.framsticks.communication; 2 3 import com.framsticks.params.SourceInterface;4 2 5 3 import java.util.List; -
java/main/src/main/java/com/framsticks/communication/Request.java
r77 r84 2 2 3 3 import com.framsticks.communication.queries.*; 4 5 import java.util.Collection;6 import java.util.regex.Matcher;7 import java.util.regex.Pattern;8 4 9 5 /** … … 12 8 public abstract class Request { 13 9 14 10 public static void quoteValue(StringBuilder builder, String value) { 15 11 String quote = ((value.indexOf(' ') > 0) || (value.length() == 0) ? "\"" : ""); 16 12 builder.append(quote).append(value).append(quote); … … 19 15 public abstract String getCommand(); 20 16 21 17 protected abstract StringBuilder construct(StringBuilder buffer); 22 18 //private static Pattern queryPattern = Pattern.compile("^(\\S+)\\s+(\\S+)(?:\\s+(\\S+))?$"); 23 19 … … 35 31 return new CallRequest(); 36 32 } 37 38 39 40 41 42 43 44 45 46 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; 47 43 } 48 44 49 45 public abstract void parseRest(String rest); 50 46 51 52 53 54 47 @Override 48 public String toString() { 49 return construct(new StringBuilder().append(getCommand())).toString(); 50 } 55 51 } -
java/main/src/main/java/com/framsticks/communication/ResponseCallback.java
r77 r84 1 1 package com.framsticks.communication; 2 3 import com.framsticks.params.SourceInterface;4 5 import java.util.List;6 2 7 3 /** -
java/main/src/main/java/com/framsticks/communication/ServerConnection.java
r77 r84 3 3 import com.framsticks.communication.queries.*; 4 4 import com.framsticks.params.SourceInterface; 5 import com.framsticks.util. Pair;6 import com.framsticks.util. Strings;5 import com.framsticks.util.lang.Pair; 6 import com.framsticks.util.lang.Strings; 7 7 import org.apache.log4j.Logger; 8 8 9 import java.io.BufferedReader;10 import java.io.IOException;11 import java.io.InputStreamReader;12 import java.io.PrintWriter;13 9 import java.net.Socket; 14 10 … … 18 14 public class ServerConnection extends Connection { 19 15 20 private final static Logger LOGGER= Logger.getLogger(ServerConnection.class);16 private final static Logger log = Logger.getLogger(ServerConnection.class); 21 17 22 18 RequestHandler requestHandler; 23 19 24 25 26 27 20 public ServerConnection(Socket socket, RequestHandler requestHandler) { 21 this.socket = socket; 22 this.requestHandler = requestHandler; 23 connected = true; 28 24 29 25 } 30 26 31 27 public void start() { 32 28 33 29 34 35 30 runThreads(); 31 } 36 32 37 38 39 40 33 @Override 34 public String toString() { 35 return socket.getInetAddress().getHostAddress(); 36 } 41 37 42 43 44 45 46 47 38 @Override 39 protected void receiverThreadRoutine() throws Exception { 40 while (connected) { 41 processNextRequest(); 42 } 43 } 48 44 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 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 } 69 65 70 71 LOGGER.error("unhandled request: " + request);72 73 66 } 67 log.error("unhandled request: " + request); 68 responseCallback.process(new Response(false, "unhandled", null)); 69 } 74 70 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 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 }); 102 98 103 99 } 104 100 105 106 107 108 109 110 111 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 } 113 109 114 115 116 117 118 119 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 } 123 119 124 125 126 127 128 129 130 120 handleRequest(request, new ResponseCallback() { 121 @Override 122 public void process(Response response) { 123 respond(response, rest.first); 124 } 125 }); 126 } 131 127 } -
java/main/src/main/java/com/framsticks/communication/Subscription.java
r77 r84 2 2 3 3 import com.framsticks.communication.queries.RegistrationRequest; 4 import com.framsticks.util. AtOnceDispatcher;5 import com.framsticks.util. Dispatcher;4 import com.framsticks.util.dispatching.AtOnceDispatcher; 5 import com.framsticks.util.dispatching.Dispatcher; 6 6 import com.framsticks.util.StateFunctor; 7 7 import org.apache.log4j.Logger; … … 13 13 public class Subscription { 14 14 15 private final static Logger LOGGER= Logger.getLogger(Subscription.class);15 private final static Logger log = Logger.getLogger(Subscription.class); 16 16 17 17 private final ClientConnection connection; … … 51 51 public void process(Response response) { 52 52 if (!response.getOk()) { 53 LOGGER.error("failed to unsunscribe " + this + ": " + response.getComment());53 log.error("failed to unsunscribe " + this + ": " + response.getComment()); 54 54 stateFunctor.call(new Exception(response.getComment())); 55 55 return; 56 56 } 57 57 assert response.hasFiles(); 58 LOGGER.debug("unsunscribed " + this);58 log.debug("unsunscribed " + this); 59 59 stateFunctor.call(null); 60 60 } -
java/main/src/main/java/com/framsticks/communication/queries/ApplicationRequest.java
r77 r84 2 2 3 3 import com.framsticks.communication.Request; 4 import com.framsticks.util.lang.Delimeted; 4 5 5 6 import java.util.Collection; … … 10 11 public abstract class ApplicationRequest extends Request { 11 12 12 13 13 protected String path; 14 protected String fields; 14 15 15 16 17 18 19 16 public ApplicationRequest setPath(String path) { 17 assert path != null; 18 this.path = path; 19 return this; 20 } 20 21 21 22 23 24 22 public ApplicationRequest setField(String field) { 23 this.fields = field; 24 return this; 25 } 25 26 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 } 40 34 41 35 42 43 44 36 public String getPath() { 37 return path; 38 } 45 39 46 47 48 49 50 51 52 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 } 54 48 55 56 57 58 49 @Override 50 public void parseRest(String rest) { 51 path = rest; 52 } 59 53 60 54 } -
java/main/src/main/java/com/framsticks/communication/queries/CallRequest.java
r77 r84 9 9 */ 10 10 public class CallRequest extends ApplicationRequest { 11 11 12 protected String arguments; 12 13 protected String method; 13 14 14 15 15 public CallRequest setArguments(String arguments) { … … 21 21 StringBuilder buffer = new StringBuilder(); 22 22 for (String a : arguments) { 23 String arg = a.trim();24 23 buffer.append(" "); 25 Request.quoteValue(buffer, a rg);24 Request.quoteValue(buffer, a.trim()); 26 25 } 27 26 return this.setArguments(buffer.toString()); … … 42 41 buffer.append(arguments); 43 42 } 44 43 return buffer; 45 44 } 46 45 -
java/main/src/main/java/com/framsticks/communication/queries/GetRequest.java
r77 r84 1 1 package com.framsticks.communication.queries; 2 3 import com.framsticks.communication.Request;4 2 5 3 /** -
java/main/src/main/java/com/framsticks/communication/queries/InfoRequest.java
r77 r84 1 1 package com.framsticks.communication.queries; 2 3 import com.framsticks.communication.Request;4 2 5 3 /** -
java/main/src/main/java/com/framsticks/communication/queries/RegistrationRequest.java
r77 r84 1 1 package com.framsticks.communication.queries; 2 3 import com.framsticks.communication.Request;4 2 5 3 /** … … 17 15 } 18 16 19 17 @Override 20 18 protected StringBuilder construct(StringBuilder buffer) { 21 19 super.construct(buffer); 22 20 if (!register) { 23 21 buffer.append(" remove"); 24 22 } 25 23 return buffer; 26 24 } 27 25 -
java/main/src/main/java/com/framsticks/communication/queries/SetRequest.java
r77 r84 1 1 package com.framsticks.communication.queries; 2 3 import com.framsticks.communication.Request;4 2 5 3 /** … … 23 21 buffer.append(" \"").append(value).append("\""); 24 22 } 25 23 return buffer; 26 24 } 27 25 @Override -
java/main/src/main/java/com/framsticks/communication/queries/UseRequest.java
r77 r84 1 1 package com.framsticks.communication.queries; 2 3 import com.framsticks.communication.Request;4 2 5 3 /** … … 14 12 } 15 13 16 14 @Override 17 15 public String getCommand() { 18 16 return "use"; 19 17 } 20 18 21 19 @Override 22 20 protected StringBuilder construct(StringBuilder buffer) { 23 21 return buffer.append(' ').append(feature); 24 22 } 25 23 26 27 28 29 24 @Override 25 public void parseRest(String rest) { 26 feature = rest; 27 } 30 28 31 32 33 29 public final String getFeature() { 30 return feature; 31 } 34 32 } -
java/main/src/main/java/com/framsticks/communication/queries/VersionRequest.java
r77 r84 1 1 package com.framsticks.communication.queries; 2 2 3 import com.framsticks.communication.Request; 4 import com.framsticks.util.Numbers; 5 import com.sun.j3d.loaders.ParsingErrorException; 3 import com.framsticks.util.lang.Numbers; 6 4 7 5 /** … … 19 17 } 20 18 21 19 @Override 22 20 public String getCommand() { 23 21 return "version"; 24 22 } 25 23 26 27 28 29 24 @Override 25 public void parseRest(String rest) { 26 version = Numbers.parse(rest, Integer.class); 27 } 30 28 31 32 29 @Override 30 protected StringBuilder construct(StringBuilder buffer) { 33 31 return buffer.append(' ').append(version); 34 32 } -
java/main/src/main/java/com/framsticks/communication/util/LoggingStateCallback.java
r77 r84 3 3 import com.framsticks.communication.StateCallback; 4 4 import org.apache.log4j.Logger; 5 import org.apache.log4j.Priority;6 5 7 6 /** -
java/main/src/main/java/com/framsticks/core/Entity.java
r78 r84 1 1 package com.framsticks.core; 2 2 3 import com.framsticks.util.*; 4 import com.framsticks.util.Thread; 3 import com.framsticks.params.FramsClass; 4 import com.framsticks.util.dispatching.Thread; 5 import com.framsticks.util.dispatching.Dispatcher; 6 7 import org.apache.commons.configuration.Configuration; 5 8 import org.apache.log4j.Logger; 6 9 … … 8 11 * @author Piotr Sniegowski 9 12 */ 10 public abstract class Entity extends Parametersimplements Dispatcher {13 public abstract class Entity implements Dispatcher { 11 14 12 private final static Logger LOGGER= Logger.getLogger(Entity.class.getName());15 private final static Logger log = Logger.getLogger(Entity.class.getName()); 13 16 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; 20 20 21 @Override 22 public final boolean isActive() { 23 return dispatcher.isActive(); 24 } 21 public Entity() { 22 } 25 23 26 @Override 27 public final void invokeLater(Runnable runnable) { 28 dispatcher.invokeLater(runnable); 29 } 24 public final String getName() { 25 return name; 26 } 30 27 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 } 35 37 36 public final void configurePublic() throws Exception { 37 configure(); 38 } 38 /** 39 * @return the owner 40 */ 41 public EntityOwner getOwner() { 42 return owner; 43 } 39 44 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 } 41 51 42 } 52 @Override 53 public final boolean isActive() { 54 return dispatcher == null || dispatcher.isActive(); 55 } 43 56 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 } 47 62 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 } 56 99 57 100 public final void done() { 58 LOGGER.info("stopping entity");101 log.info("stopping entity"); 59 102 if (owner != null) { 60 103 owner.onDone(); … … 62 105 } 63 106 64 107 public static void constructFramsClass(FramsClass.Constructor constructor) { 108 constructor.method("getName"); 109 } 65 110 } -
java/main/src/main/java/com/framsticks/core/Instance.java
r78 r84 3 3 import com.framsticks.communication.*; 4 4 import com.framsticks.params.*; 5 import com.framsticks.params.types.CompositeParam;6 5 import com.framsticks.params.types.ObjectParam; 7 6 import com.framsticks.parsers.Loaders; … … 9 8 import com.framsticks.util.*; 10 9 import com.framsticks.util.UnsupportedOperationException; 10 import com.framsticks.util.dispatching.Dispatching; 11 import com.framsticks.util.dispatching.Future; 12 import com.framsticks.util.lang.Casting; 11 13 import org.apache.log4j.Logger; 12 14 … … 18 20 public abstract class Instance extends Entity { 19 21 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); 35 36 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) { 44 40 future.result(null, new UnsupportedOperationException()); 45 41 } … … 61 57 } 62 58 63 59 public void fetchValue(Path path, Param param, StateFunctor stateFunctor) { 64 60 stateFunctor.call(null); 65 61 } 66 62 67 63 public void fetchValues(Path path, StateFunctor stateFunctor) { 68 64 stateFunctor.call(null); 69 65 } 70 66 71 67 protected void tryRegisterOnChangeEvents(Path path) { 72 68 73 69 } … … 83 79 } 84 80 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 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) { 121 117 l.onListChange(path, change); 122 118 } 123 119 } 124 120 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(); 133 136 return registry.getInfoFromCache(id); 134 137 } … … 137 140 138 141 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()); 141 169 return null; 142 170 } 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 } 342 339 343 340 public Registry getRegistry() { 344 341 return registry; 345 342 } 343 344 public Path getPath(String textual) { 345 return new Path(this, textual); 346 } 347 348 public Path getRootPath() { 349 return getPath("/"); 350 } 346 351 } 347 352 -
java/main/src/main/java/com/framsticks/core/InstanceListener.java
r77 r84 5 5 */ 6 6 public 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); 10 11 } -
java/main/src/main/java/com/framsticks/core/ListChange.java
r77 r84 2 2 3 3 import com.framsticks.params.FramsClass; 4 import com.framsticks.params.ListSource;5 4 import com.framsticks.params.ParamBuilder; 6 5 import com.framsticks.params.types.DecimalParam; 7 6 import com.framsticks.params.types.EnumParam; 8 7 import com.framsticks.params.types.StringParam; 9 import com.framsticks.util. Strings;8 import com.framsticks.util.lang.Strings; 10 9 11 import java.util.ArrayList;12 10 import java.util.Arrays; 13 11 … … 17 15 public class ListChange { 18 16 19 20 21 17 public Action getAction() { 18 return action; 19 } 22 20 23 24 25 21 public Integer getPosition() { 22 return position; 23 } 26 24 27 28 29 25 public String getIdentifier() { 26 return identifier; 27 } 30 28 31 32 33 34 35 29 public static enum Action { 30 Add, 31 Remove, 32 Modify 33 } 36 34 37 38 39 35 private Action action; 36 private Integer position; 37 private String identifier; 40 38 41 42 39 public Integer getType() { return action.ordinal(); } 40 public void setType(Integer type) { action = Action.values()[type]; } 43 41 44 42 public Integer getPos() { return position; } … … 48 46 public void setId(String id) { identifier = id; } 49 47 50 51 52 53 54 55 48 public String getBestIdentifier() { 49 if (Strings.notEmpty(identifier)) { 50 return identifier; 51 } 52 return position.toString(); 53 } 56 54 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 } 58 61 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 } 73 66 } -
java/main/src/main/java/com/framsticks/core/LocalInstance.java
r78 r84 2 2 3 3 import 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; 4 import com.framsticks.util.dispatching.Thread; 5 6 import org.apache.commons.configuration.Configuration; 8 7 import org.apache.log4j.Logger; 9 8 … … 21 20 public abstract class LocalInstance extends Instance { 22 21 23 private static final Logger LOGGER= Logger.getLogger(LocalInstance.class.getName());22 private static final Logger log = Logger.getLogger(LocalInstance.class.getName()); 24 23 25 public LocalInstance(Parameters parameters) { 26 super(parameters); 24 public LocalInstance() { 27 25 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 } 40 27 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 } 45 42 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; 50 46 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 } 54 70 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 } 98 90 99 91 } -
java/main/src/main/java/com/framsticks/core/Node.java
r77 r84 1 1 package com.framsticks.core; 2 2 3 import com.framsticks.params.types.CompositeParam; 4 5 import java.util.HashMap; 6 import java.util.Map; 3 import com.framsticks.params.CompositeParam; 7 4 8 5 /** -
java/main/src/main/java/com/framsticks/core/Path.java
r77 r84 2 2 3 3 import com.framsticks.params.AccessInterface; 4 import com.framsticks.params.CompositeParam; 4 5 import com.framsticks.params.Param; 5 import com.framsticks.params.types.CompositeParam; 6 import com.framsticks.util.Dispatching; 7 import org.apache.log4j.Logger; 8 6 import com.framsticks.util.dispatching.Dispatching; 9 7 import java.util.Iterator; 10 8 import java.util.LinkedList; 9 import java.util.List; 10 11 import org.apache.commons.collections.ListUtils; 11 12 12 13 /** … … 14 15 */ 15 16 public 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) { 136 166 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 } 167 203 } 168 204 -
java/main/src/main/java/com/framsticks/core/Program.java
r78 r84 1 1 package com.framsticks.core; 2 2 3 import com.framsticks.util.Pair; 4 import com.framsticks.util.Strings; 3 import com.framsticks.util.lang.IterableIterator; 4 import com.framsticks.util.lang.Pair; 5 import com.framsticks.util.lang.Strings; 5 6 import org.apache.commons.configuration.*; 6 7 import org.apache.log4j.Logger; 7 8 import org.apache.log4j.PropertyConfigurator; 8 //import sun.misc.Signal;9 //import sun.misc.SignalHandler;10 9 11 10 import java.lang.reflect.Constructor; … … 15 14 * @author Piotr Sniegowski 16 15 */ 17 public class Program extends com.framsticks.util. Thread {16 public class Program extends com.framsticks.util.dispatching.Thread { 18 17 19 private final static Logger LOGGER= Logger.getLogger(Program.class.getName());18 private final static Logger log = Logger.getLogger(Program.class.getName()); 20 19 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; 30 21 31 protected Entity entity;22 Configuration config; 32 23 33 Configuration config; 24 public Program(String name) { 25 super(name, java.lang.Thread.currentThread()); 26 } 34 27 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 } 35 41 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 } 41 55 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) { 75 57 76 58 PropertyConfigurator.configure(getClass().getResource("/configs/log4j.properties")); 77 LOGGER.debug("started in " + System.getProperty("user.dir"));78 59 log.debug("started in " + System.getProperty("user.dir")); 60 try { 79 61 config = new PropertiesConfiguration(getClass().getResource("/configs/framsticks.properties")); 80 62 81 82 83 84 63 for (String a : args) { 64 Pair<String, String> p = Strings.splitIntoPair(a, '=', "true"); 65 config.setProperty(p.first, p.second); 66 } 85 67 86 68 resolve(config, null); 87 69 88 Iteratori = config.getKeys();89 90 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 } 93 75 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"); 98 81 99 entity = configureEntity(new Parameters(config.subset("com.framsticks.entity"), "main", null, new EntityOwner() { 82 entity = configureEntity(entityConfig); 83 entity.setOwner(new EntityOwner() { 100 84 @Override 101 85 public void onDone() { 102 LOGGER.info("exiting");86 log.info("exiting"); 103 87 Runtime.getRuntime().exit(0); 104 88 } 105 })); 89 }); 90 entity.setName("main"); 106 91 try { 107 entity.configurePublic();92 entity.configure(entityConfig); 108 93 } catch (Exception e) { 109 LOGGER.fatal("exception caught during configuration: " + e);94 log.fatal("exception caught during configuration: " + e); 110 95 } 111 LOGGER.info("all entities were configured");112 113 96 log.info("all entities were configured"); 97 entity.start(); 98 } 114 99 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 } 125 111 126 112 } -
java/main/src/main/java/com/framsticks/diagnostics/Diagnostics.java
r78 r84 1 1 package com.framsticks.diagnostics; 2 2 3 import com.framsticks.core.Parameters; 3 import org.apache.commons.configuration.Configuration; 4 4 5 import com.framsticks.observers.Endpoint; 5 6 import com.framsticks.observers.Observer; … … 10 11 public class Diagnostics extends Observer { 11 12 12 finalInteger dumpsInterval;13 finalString dumpsPath;14 finalString dumpsFormat;13 Integer dumpsInterval; 14 String dumpsPath; 15 String dumpsFormat; 15 16 16 17 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 } 23 20 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 } 29 28 30 29 31 32 33 34 30 @Override 31 protected Endpoint createEndpoint() { 32 return new DiagnosticsEndpoint(); 33 } 35 34 36 35 -
java/main/src/main/java/com/framsticks/diagnostics/DiagnosticsEndpoint.java
r77 r84 1 1 package com.framsticks.diagnostics; 2 2 3 import com.framsticks. core.Path;3 import com.framsticks.dumping.PrintWriterSink; 4 4 import com.framsticks.dumping.SaveStream; 5 5 import com.framsticks.observers.Endpoint; 6 import com.framsticks.dumping.PrintStreamSink;7 6 import com.framsticks.remote.RecursiveFetcher; 8 7 import com.framsticks.util.Logging; … … 13 12 import java.io.File; 14 13 import java.io.IOException; 15 import java.io.Print Stream;14 import java.io.PrintWriter; 16 15 import java.text.SimpleDateFormat; 17 16 import java.util.Date; … … 22 21 public class DiagnosticsEndpoint extends Endpoint { 23 22 24 private final static Logger LOGGER= Logger.getLogger(DiagnosticsEndpoint.class.getName());23 private final static Logger log = Logger.getLogger(DiagnosticsEndpoint.class.getName()); 25 24 26 25 27 28 29 26 public DiagnosticsEndpoint() { 27 super(); 28 } 30 29 31 32 33 34 30 @Override 31 public Diagnostics getObserver() { 32 return (Diagnostics)observer; 33 } 35 34 36 35 37 38 protected void configure() {39 super.configure();36 @Override 37 public void start() { 38 super.start(); 40 39 41 42 43 44 40 if (getObserver().dumpsInterval != null) { 41 new PeriodicTask(instance, getObserver().dumpsInterval * 1000) { 42 @Override 43 public void run() { 45 44 46 LOGGER.info("starting periodic dump");47 new RecursiveFetcher(instance, new Path(instance, "/"), new StateFunctor() {48 49 50 if (Logging.log(LOGGER, "recursively fetch", instance, e)) {51 52 53 54 LOGGER.info("instance resolved, saving");55 56 57 58 new SaveStream(new PrintStreamSink(new PrintStream(file)), instance, new Path(instance, "/"), new StateFunctor() {59 60 61 Logging.log(LOGGER, "periodic dump in " + fileName + " of", DiagnosticsEndpoint.this.instance, e);62 63 64 65 66 LOGGER.info("failed to initiate dump: " + ex);67 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 } 69 68 70 71 69 } 70 }); 72 71 73 72 74 75 76 77 73 } 74 }; 75 } 76 } 78 77 79 80 81 82 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 */ 85 84 } -
java/main/src/main/java/com/framsticks/dumping/FileInstance.java
r78 r84 2 2 3 3 import com.framsticks.core.LocalInstance; 4 import com.framsticks.core.Parameters;5 4 import com.framsticks.core.Path; 6 import com.framsticks.params.FramsClass;7 5 import com.framsticks.core.Instance; 8 import com.framsticks.util.*; 9 import com.framsticks.util.UnsupportedOperationException; 6 import com.framsticks.util.dispatching.Future; 7 8 import org.apache.commons.configuration.Configuration; 10 9 import org.apache.log4j.Logger; 11 10 … … 20 19 public class FileInstance extends LocalInstance { 21 20 22 private static final Logger LOGGER= Logger.getLogger(Instance.class.getName());23 protected finalFile file;21 private static final Logger log = Logger.getLogger(Instance.class.getName()); 22 protected File file; 24 23 25 public FileInstance(Parameters parameters) { 26 super(parameters); 27 file = new File(config.getString("filename")); 28 } 24 public FileInstance() { 25 } 29 26 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 } 54 32 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 } 59 62 60 63 -
java/main/src/main/java/com/framsticks/dumping/LoadStream.java
r77 r84 6 6 import com.framsticks.core.Instance; 7 7 import com.framsticks.util.*; 8 import com.framsticks.util.dispatching.Future; 9 import com.framsticks.util.lang.Pair; 10 import com.framsticks.util.lang.Strings; 8 11 import org.apache.log4j.Logger; 9 12 … … 18 21 public class LoadStream { 19 22 20 private final static Logger LOGGER= Logger.getLogger(LoadStream.class.getName());23 private final static Logger log = Logger.getLogger(LoadStream.class.getName()); 21 24 22 23 24 25 26 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(); 27 30 28 31 29 30 31 32 33 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 } 35 38 36 37 38 39 40 41 42 43 44 45 46 47 LOGGER.trace("loading " + line);48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 LOGGER.error("failed to load: " + e);81 82 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 } 87 90 88 91 -
java/main/src/main/java/com/framsticks/dumping/SaveStream.java
r78 r84 4 4 import com.framsticks.core.Path; 5 5 import com.framsticks.params.AccessInterface; 6 import com.framsticks.params.CompositeParam; 6 7 import com.framsticks.params.FramsClass; 7 8 import com.framsticks.params.ListAccess; 8 import com.framsticks.params.Param;9 import com.framsticks.params.types.CompositeParam;10 9 import com.framsticks.params.SinkInterface; 11 10 import com.framsticks.parsers.Savers; 12 11 import com.framsticks.core.Instance; 13 12 import com.framsticks.util.*; 13 import com.framsticks.util.dispatching.Dispatching; 14 14 import org.apache.log4j.Logger; 15 15 16 16 import java.util.HashSet; 17 17 import java.util.Set; 18 import static com.framsticks.util.lang.Containers.filterInstanceof; 18 19 19 20 /** … … 22 23 public class SaveStream { 23 24 24 private final static Logger LOGGER= Logger.getLogger(SaveStream.class.getName());25 private final static Logger log = Logger.getLogger(SaveStream.class.getName()); 25 26 26 27 28 29 30 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>(); 31 32 32 33 private int dispatched = 0; 33 34 34 35 36 37 38 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; 39 40 dispatchWrite(root); 40 41 } 41 42 42 43 protected void dispatchWrite(final Path path) { … … 50 51 } 51 52 52 53 54 LOGGER.info("stored in " + stopwatch);55 56 53 protected void finished() { 54 assert instance.isActive(); 55 log.info("stored in " + stopwatch); 56 stateFunctor.call(null); 57 } 57 58 58 59 60 61 LOGGER.debug("path " + path + " is not resolved - skipping");62 63 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); 64 65 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 } 98 96 } -
java/main/src/main/java/com/framsticks/examples/GenotypeBrowser.java
r79 r84 3 3 import com.framsticks.core.Instance; 4 4 import com.framsticks.core.Node; 5 import com.framsticks.core.Parameters; 6 import com.framsticks.core.Path; 5 import com.framsticks.dumping.PrintWriterSink; 7 6 import com.framsticks.model.*; 8 7 import com.framsticks.model.Package; 9 8 import com.framsticks.params.*; 10 import com.framsticks.params.types.CompositeParam;11 9 import com.framsticks.parsers.F0Parser; 10 import com.framsticks.parsers.F0Writer; 12 11 import com.framsticks.parsers.Schema; 12 13 import org.apache.commons.configuration.Configuration; 13 14 import org.apache.log4j.Logger; 14 15 16 import java.io.PrintWriter; 17 import java.io.StringWriter; 15 18 import java.util.List; 16 19 … … 20 23 public class GenotypeBrowser extends Instance { 21 24 22 private static final Logger LOGGER = Logger.getLogger(Instance.class.getName()); 25 private static final Logger log = Logger 26 .getLogger(Instance.class.getName()); 23 27 protected Schema schema; 24 28 25 26 public GenotypeBrowser(Parameters parameters) { 27 super(parameters); 28 LOGGER.info("model builder created"); 29 public GenotypeBrowser() { 30 log.info("model builder created"); 29 31 } 30 32 31 33 @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 } 35 41 this.registry = schema.getRegistry(); 36 42 Package.register(this.getRegistry()); … … 38 44 registry.putInfoIntoCache(new FramsClass("ModelBuilderRoot", "ModelBuilderRoot", null) 39 45 .append(new ParamBuilder().setType("o Model").setId("model").setName("model").build()) 46 .append(new ParamBuilder().setType("s 1").setId("genotype").setName("genotype").build()) 40 47 ); 41 48 root = new Node((CompositeParam)new ParamBuilder().setType("o ModelBuilderRoot").setId(name).setName("Instance").build(), PropertiesAccess.createPropertiesMap()); … … 51 58 Model model = Model.build(objects); 52 59 53 AccessInterface rootAccess = bindAccess( new Path(this, "/"));60 AccessInterface rootAccess = bindAccess(this.getRootPath()); 54 61 55 62 rootAccess.set("model", model); 56 63 64 StringWriter w = new StringWriter(); 65 new F0Writer(schema, model, new PrintWriterSink(new PrintWriter(w))).write(); 66 rootAccess.set("genotype", w.getBuffer().toString()); 67 57 68 } catch (Exception e) { 58 LOGGER.error("exception caught: " + e);69 log.error("exception caught: " + e); 59 70 } 60 71 //done(); -
java/main/src/main/java/com/framsticks/gui/Browser.java
r78 r84 4 4 import com.framsticks.observers.Endpoint; 5 5 import com.framsticks.observers.Observer; 6 import com.framsticks.util.Dispatcher; 6 import com.framsticks.util.Logging; 7 import com.framsticks.util.dispatching.Dispatcher; 8 import com.framsticks.util.dispatching.Future; 9 10 import org.apache.commons.configuration.Configuration; 11 import org.apache.commons.lang.ArrayUtils; 7 12 import org.apache.log4j.Logger; 8 13 9 14 import javax.swing.*; 15 16 import java.awt.Dimension; 17 import java.util.ArrayList; 10 18 import java.util.HashSet; 19 import java.util.List; 11 20 import java.util.Set; 12 21 … … 16 25 public class Browser extends Observer implements Dispatcher { 17 26 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 }); 37 102 } 38 103 39 104 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(); 94 169 95 170 96 171 /* 97 98 99 100 101 102 103 104 105 106 107 LOGGER.debug(child.getClass().getSimpleName() + " created: " + child);108 109 110 111 112 113 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 }); 116 191 */ 117 192 } 118 193 119 194 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 } 124 211 125 212 } -
java/main/src/main/java/com/framsticks/gui/BrowserEndpoint.java
r77 r84 9 9 10 10 public BrowserEndpoint() { 11 11 12 } 12 13 -
java/main/src/main/java/com/framsticks/gui/EndpointAtFrame.java
r77 r84 1 1 package com.framsticks.gui; 2 2 3 import java.util.HashMap; 4 import java.util.Map; 3 import org.apache.log4j.Logger; 4 5 import com.framsticks.core.Instance; 6 import com.framsticks.core.InstanceListener; 7 import com.framsticks.core.ListChange; 8 import com.framsticks.core.Node; 9 import com.framsticks.core.Path; 10 import com.framsticks.params.CompositeParam; 11 import com.framsticks.params.FramsClass; 12 13 import java.util.*; 14 15 import javax.swing.tree.TreePath; 5 16 6 17 /** 7 18 * @author Piotr Sniegowski 8 19 */ 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>(); 20 public class EndpointAtFrame implements InstanceListener { 13 21 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); 18 23 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; 19 29 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 } 23 35 24 public Frame getFrame() {25 return frame;26 36 public BrowserEndpoint getEndpoint() { 37 return endpoint; 38 } 27 39 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 } 33 43 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 } 38 46 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 } 42 176 } -
java/main/src/main/java/com/framsticks/gui/Frame.java
r78 r84 1 1 package com.framsticks.gui; 2 2 3 import com.framsticks.core. Node;3 import com.framsticks.core.Instance; 4 4 import com.framsticks.core.Path; 5 5 import com.framsticks.gui.view.*; 6 6 import com.framsticks.gui.view.TreeCellRenderer; 7 import com.framsticks.util.Dispatcher; 7 import com.framsticks.util.dispatching.Dispatcher; 8 import com.framsticks.util.swing.KeyboardModifier; 8 9 import org.apache.log4j.Logger; 9 10 10 11 import javax.swing.*; 12 import javax.swing.event.TreeModelEvent; 13 import javax.swing.event.TreeModelListener; 11 14 import javax.swing.event.TreeSelectionEvent; 12 15 import javax.swing.event.TreeSelectionListener; 13 16 import javax.swing.tree.*; 17 14 18 import java.awt.*; 15 19 import java.awt.datatransfer.StringSelection; 16 import java.awt.event.ActionEvent; 17 import java.awt.event.MouseAdapter; 18 import java.awt.event.MouseEvent; 20 import java.awt.event.*; 19 21 import java.util.HashMap; 20 22 import java.util.Map; … … 23 25 * @author Piotr Sniegowski 24 26 */ 27 @SuppressWarnings("serial") 25 28 public class Frame extends JFrame implements Dispatcher { 26 29 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) { 56 67 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