From 1e940bf58bbd9f228ff991b5ee6e5b38c36a78fe Mon Sep 17 00:00:00 2001 From: jprocter Date: Wed, 12 Nov 2008 15:58:18 +0000 Subject: [PATCH] new Selection message. This still needs work! git-svn-id: https://svn.lifesci.dundee.ac.uk/svn/repository/trunk@492 be28352e-c001-0410-b1a7-c7978e42abec --- src/uk/ac/vamsas/client/picking/PickEndPoint.java | 7 +- .../ac/vamsas/client/picking/SelectionMessage.java | 211 ++++++++++++++++++++ src/uk/ac/vamsas/client/picking/TestApp.java | 123 +++++++++--- 3 files changed, 307 insertions(+), 34 deletions(-) create mode 100644 src/uk/ac/vamsas/client/picking/SelectionMessage.java diff --git a/src/uk/ac/vamsas/client/picking/PickEndPoint.java b/src/uk/ac/vamsas/client/picking/PickEndPoint.java index b5b0a9a..beb0e46 100644 --- a/src/uk/ac/vamsas/client/picking/PickEndPoint.java +++ b/src/uk/ac/vamsas/client/picking/PickEndPoint.java @@ -60,7 +60,7 @@ class PickEndPoint extends Thread { String str = message.getRawMessage(); - //logger.info("CLIENT: send " + str + " to " + rPort); + // System.err.println("CLIENT: send " + str + " to " + rPort); os.write(str); // We use a newline to terminate the message @@ -128,13 +128,16 @@ class PickEndPoint extends Thread { try { + // System.err.println("Received Message\n*\n"+str+"*"); if (str==null || str.length()==1) return null; if (str.startsWith("CUSTOM")) return new CustomMessage(str.substring(6)); - if (str.startsWith("MOUSEOVER")) return new MouseOverMessage(str); + if (str.startsWith("SELECTION")) + return new SelectionMessage(str); + } catch (Exception e) { diff --git a/src/uk/ac/vamsas/client/picking/SelectionMessage.java b/src/uk/ac/vamsas/client/picking/SelectionMessage.java new file mode 100644 index 0000000..d611437 --- /dev/null +++ b/src/uk/ac/vamsas/client/picking/SelectionMessage.java @@ -0,0 +1,211 @@ +/** + * + */ +package uk.ac.vamsas.client.picking; + +import uk.ac.vamsas.objects.core.Input; +import uk.ac.vamsas.objects.core.Pos; +import uk.ac.vamsas.objects.core.RangeType; +import uk.ac.vamsas.objects.core.Seg; + +/** + * Send and receive details about vamsas object selections and selection ranges + * defined on one or more objects. + * + * @author J.B. Procter + * + */ +public class SelectionMessage extends Message { + private String selectionID; + + private String[] vorbaIDs; + + RangeType ranges; + + private boolean none=false; + /** + * parse a message payload as a selection message + * + * @param str + */ + public SelectionMessage(String str) { + message = str; + // Parse message into ... + String[] elements = str.split("\t"); + String positions[] = null, segs[] = null; + for (int i = 0; i < elements.length; i++) { + if (elements[i].startsWith("selectionID=")) + selectionID = elements[i].substring(12); + if (elements[i].startsWith("vorbaIDs=")) + vorbaIDs = elements[i].substring(9).split("\\|"); + if (elements[i].startsWith("positions=")) { + positions = elements[i].substring(10).split(","); + } + if (elements[i].startsWith("ranges=")) { + segs = elements[i].substring(7).split(","); + } + if (elements[i].equals("none")) + { + none=true; + } + } + if (none) + { + ranges = null; + vorbaIDs = null; + } + if (positions != null) { + ranges = new Input(); + for (int i = 0; i < positions.length; i++) { + Pos p = new Pos(); + try { + p.setI(Integer.parseInt(positions[i])); + ranges.addPos(p); + } catch (Exception e) { + // invalid message - ignore element + } + } + } else if (segs != null) { + ranges = new Input(); + for (int i = 0; i < segs.length; i += 2) { + Seg s = new Seg(); + s.setInclusive(segs[i].startsWith("[")); + try { + s.setStart(Integer.parseInt(segs[i].substring(1))); + s.setEnd(Integer.parseInt(segs[i + 1])); + ranges.addSeg(s); + } catch (Exception e) { + // invalid message - again ignore element + } + } + } + + } + + /** + * create a new selection message + * + * @param selectionID - + * (may be null) optional handle (or ID) to refer to selection by + * @param vorbaIDs - + * one or more objects to be selected, or null for the empty selection + * @param ranges + * optional rangetype specifying positions or intervals over + * object(s) coordinate system. + */ + public SelectionMessage(String selectionID, String[] vorbaIDs, + RangeType ranges) { + this(selectionID,vorbaIDs,ranges,false); + } + public SelectionMessage(String selectionID, String[] vorbaIDs, RangeType ranges, boolean none) + { + super(); + this.selectionID = selectionID; + if (selectionID != null && selectionID.indexOf("\t") > -1) { + throw new Error( + "VAMSAS Selection Messages are not allowed to have Tab Characters in their selection ID"); + } + this.vorbaIDs = vorbaIDs; + this.ranges = ranges; + this.none=none; + StringBuffer message = new StringBuffer(); + message.append("SELECTION\t"); + if (selectionID != null) { + message.append("selectionID=" + selectionID); + message.append("\t"); + } + message.append("vorbaIDs="); + for (int ids = 0; ids < vorbaIDs.length; ids++) { + if (ids > 0) { + message.append("|"); + } + if (vorbaIDs[ids] == null) { + throw new Error("null vorbaID in SelectionMessage ID vector.(" + ids + + ")"); + } + if (vorbaIDs[ids].indexOf("\t") > -1) { + throw new Error( + "Invalid vorbaID string in SelectionMessage ID vector. (" + + vorbaIDs[ids] + ")"); + } + message.append(vorbaIDs[ids]); + } + if (none) { + // must have only IDs for the selection or the selection scope - no range + if (ranges!=null) + { + throw new Error("Empty selection cannot specify a range."); + } + if ((selectionID==null || selectionID.length()==0) && (vorbaIDs==null || vorbaIDs.length==0)) + { + throw new Error("Empty selection must have at least a selection ID or at least one vorbaID indicating selection scope."); + } + message.append("none"); + return; + } + // Verify that the range has at least one valid vorbaID for it to be defined on. + if (vorbaIDs==null || vorbaIDs.length==0) + { + throw new Error("You must specify at least one vorbaID for the selection."); + } + if (ranges != null) { + if (ranges.getPosCount() > 0) { + message.append("\tpositions="); + Pos[] pos = ranges.getPos(); + for (int p = 0; p < pos.length; p++) { + if (p > 0) { + message.append(","); + } + message.append(pos[p].getI()); + } + } else if (ranges.getSegCount() > 0) { + message.append("\tranges="); + Seg[] rng = ranges.getSeg(); + for (int p = 0; p < rng.length; p++) { + boolean inc = rng[p].getInclusive(); + if (p > 0) { + message.append(","); + } + if (inc) { + message.append("["); + } else { + message.append("("); + } + message.append(rng[p].getStart()); + message.append(","); + message.append(rng[p].getEnd()); + } + } + } + message.append("\n"); + this.message = message.toString(); + } + + /** + * @return the selectionID + */ + public String getSelectionID() { + return selectionID; + } + + /** + * @return the vorbaIDs + */ + public String[] getVorbaIDs() { + return vorbaIDs; + } + + /** + * @return the ranges + */ + public RangeType getRanges() { + return ranges; + } + + /** + * @return the none + */ + public boolean isNone() { + return none; + } +} diff --git a/src/uk/ac/vamsas/client/picking/TestApp.java b/src/uk/ac/vamsas/client/picking/TestApp.java index d7f3d35..bb27811 100644 --- a/src/uk/ac/vamsas/client/picking/TestApp.java +++ b/src/uk/ac/vamsas/client/picking/TestApp.java @@ -2,39 +2,98 @@ package uk.ac.vamsas.client.picking; import java.util.logging.*; +import uk.ac.vamsas.objects.core.Input; +import uk.ac.vamsas.objects.core.Pos; +import uk.ac.vamsas.objects.core.Seg; + /** * Simple example of a (runnable) class that shows how to use the picking API. + * use this to test new messages. Bear in mind that any active pick server only + * relays messages that could be parsed at compile time - that means that you + * must make sure that you close all currently running vamsas pick servers and + * start a new one which copes with the new message in order to be able to + * receive any of the new message classes. */ -public class TestApp implements IMessageHandler -{ - public static void main(String[] args) - throws Exception - { - TestApp app = new TestApp(); - } - - public TestApp() - { - IPickManager manager = new SocketManager(); - manager.registerMessageHandler(this); - - while (true) - { - try { Thread.sleep((int) (Math.random()*5000)); } - catch (InterruptedException e) {} - - int rnd = (int) (Math.random()*100); - CustomMessage msg = new CustomMessage("" + rnd); - -// manager.sendMessage(msg); - - MouseOverMessage mom = new MouseOverMessage("wibble", 10); - manager.sendMessage(mom); - } - } - - public void handleMessage(Message message) - { - System.out.println("Handler received " + message.getRawMessage()); - } +public class TestApp implements IMessageHandler { + public static void main(String[] args) throws Exception { + TestApp app = new TestApp(); + } + + public TestApp() { + IPickManager manager = new SocketManager(); + manager.registerMessageHandler(this); + while (true) { + try { + Thread.sleep((int) (Math.random() * 5000)); + } catch (InterruptedException e) { + } + + int rnd = (int) (Math.random() * 100); + CustomMessage msg = new CustomMessage("" + rnd); + + manager.sendMessage(msg); + + try { + Thread.sleep((int) (Math.random() * 5000)); + } catch (InterruptedException e) { + } + + MouseOverMessage mom = new MouseOverMessage("wibble", 10); + manager.sendMessage(mom); + + try { + Thread.sleep((int) (Math.random() * 5000)); + } catch (InterruptedException e) { + } + + try { + Input range = new Input(); + for (int in = 0, inL = (2 + ((int) (Math.random() * 10f))); in < inL; in++) { + if ((inL % 2) == 1) { + Seg sg = new Seg(); + sg.setStart((int) (Math.random() * 1000f)); + sg.setEnd((int) (Math.random() * 1000f)); + sg.setInclusive((((int) (Math.random() * 10f)) % 2) == 0); + range.addSeg(sg); + } else { + Pos p = new Pos(); + p.setI((int) (Math.random() * 1000f)); + range.addPos(p); + } + } + String[] ids = new String[(int) (Math.random() * 10)]; + for (int id = 0; id < ids.length; id++) { + ids[id] = "object" + id; + } + + SelectionMessage sel = new SelectionMessage("mysel", ids, (ids.length>0) ? range : null,(ids.length==0) ? true : false); + sel.validate(); + manager.sendMessage(sel); + } catch (Exception e) { + System.err.println("Failed to construct and send selection message."); + e.printStackTrace(); + } + } + } + + public void handleMessage(Message message) { + System.out.println("Handler received " + message.getRawMessage()); + if (message instanceof MouseOverMessage) { + MouseOverMessage mm = (MouseOverMessage) message; + System.out.println("MouseOver : " + mm.getPosition() + " on id " + + mm.getVorbaID()); + } + if (message instanceof SelectionMessage) { + SelectionMessage sm = (SelectionMessage) message; + + System.out.println("Selection " + + ((sm.getSelectionID() == null) ? "on " : "'" + sm.getSelectionID() + + "' on ") + + sm.getVorbaIDs().length + + ((sm.getRanges() == null) ? "." : " over " + + ((sm.getRanges().getPosCount() > 0) ? "" + + sm.getRanges().getPosCount() + " positions" : "" + + sm.getRanges().getSegCount() + "intervals."))); + } + } } \ No newline at end of file -- 1.7.10.2