--- /dev/null
+/**\r
+ * \r
+ */\r
+package uk.ac.vamsas.client.picking;\r
+\r
+import uk.ac.vamsas.objects.core.Input;\r
+import uk.ac.vamsas.objects.core.Pos;\r
+import uk.ac.vamsas.objects.core.RangeType;\r
+import uk.ac.vamsas.objects.core.Seg;\r
+\r
+/**\r
+ * Send and receive details about vamsas object selections and selection ranges\r
+ * defined on one or more objects.\r
+ * \r
+ * @author J.B. Procter\r
+ * \r
+ */\r
+public class SelectionMessage extends Message {\r
+ private String selectionID;\r
+\r
+ private String[] vorbaIDs;\r
+\r
+ RangeType ranges;\r
+\r
+ private boolean none=false;\r
+ /**\r
+ * parse a message payload as a selection message\r
+ * \r
+ * @param str\r
+ */\r
+ public SelectionMessage(String str) {\r
+ message = str;\r
+ // Parse message into ...\r
+ String[] elements = str.split("\t");\r
+ String positions[] = null, segs[] = null;\r
+ for (int i = 0; i < elements.length; i++) {\r
+ if (elements[i].startsWith("selectionID="))\r
+ selectionID = elements[i].substring(12);\r
+ if (elements[i].startsWith("vorbaIDs="))\r
+ vorbaIDs = elements[i].substring(9).split("\\|");\r
+ if (elements[i].startsWith("positions=")) {\r
+ positions = elements[i].substring(10).split(",");\r
+ }\r
+ if (elements[i].startsWith("ranges=")) {\r
+ segs = elements[i].substring(7).split(",");\r
+ }\r
+ if (elements[i].equals("none"))\r
+ {\r
+ none=true;\r
+ }\r
+ }\r
+ if (none)\r
+ {\r
+ ranges = null;\r
+ vorbaIDs = null;\r
+ }\r
+ if (positions != null) {\r
+ ranges = new Input();\r
+ for (int i = 0; i < positions.length; i++) {\r
+ Pos p = new Pos();\r
+ try {\r
+ p.setI(Integer.parseInt(positions[i]));\r
+ ranges.addPos(p);\r
+ } catch (Exception e) {\r
+ // invalid message - ignore element\r
+ }\r
+ }\r
+ } else if (segs != null) {\r
+ ranges = new Input();\r
+ for (int i = 0; i < segs.length; i += 2) {\r
+ Seg s = new Seg();\r
+ s.setInclusive(segs[i].startsWith("["));\r
+ try {\r
+ s.setStart(Integer.parseInt(segs[i].substring(1)));\r
+ s.setEnd(Integer.parseInt(segs[i + 1]));\r
+ ranges.addSeg(s);\r
+ } catch (Exception e) {\r
+ // invalid message - again ignore element\r
+ }\r
+ }\r
+ }\r
+\r
+ }\r
+\r
+ /**\r
+ * create a new selection message\r
+ * \r
+ * @param selectionID -\r
+ * (may be null) optional handle (or ID) to refer to selection by\r
+ * @param vorbaIDs -\r
+ * one or more objects to be selected, or null for the empty selection\r
+ * @param ranges\r
+ * optional rangetype specifying positions or intervals over\r
+ * object(s) coordinate system.\r
+ */\r
+ public SelectionMessage(String selectionID, String[] vorbaIDs,\r
+ RangeType ranges) {\r
+ this(selectionID,vorbaIDs,ranges,false);\r
+ }\r
+ public SelectionMessage(String selectionID, String[] vorbaIDs, RangeType ranges, boolean none)\r
+ {\r
+ super();\r
+ this.selectionID = selectionID;\r
+ if (selectionID != null && selectionID.indexOf("\t") > -1) {\r
+ throw new Error(\r
+ "VAMSAS Selection Messages are not allowed to have Tab Characters in their selection ID");\r
+ }\r
+ this.vorbaIDs = vorbaIDs;\r
+ this.ranges = ranges;\r
+ this.none=none;\r
+ StringBuffer message = new StringBuffer();\r
+ message.append("SELECTION\t");\r
+ if (selectionID != null) {\r
+ message.append("selectionID=" + selectionID);\r
+ message.append("\t");\r
+ }\r
+ message.append("vorbaIDs=");\r
+ for (int ids = 0; ids < vorbaIDs.length; ids++) {\r
+ if (ids > 0) {\r
+ message.append("|");\r
+ }\r
+ if (vorbaIDs[ids] == null) {\r
+ throw new Error("null vorbaID in SelectionMessage ID vector.(" + ids\r
+ + ")");\r
+ }\r
+ if (vorbaIDs[ids].indexOf("\t") > -1) {\r
+ throw new Error(\r
+ "Invalid vorbaID string in SelectionMessage ID vector. ("\r
+ + vorbaIDs[ids] + ")");\r
+ }\r
+ message.append(vorbaIDs[ids]);\r
+ }\r
+ if (none) {\r
+ // must have only IDs for the selection or the selection scope - no range\r
+ if (ranges!=null)\r
+ {\r
+ throw new Error("Empty selection cannot specify a range.");\r
+ }\r
+ if ((selectionID==null || selectionID.length()==0) && (vorbaIDs==null || vorbaIDs.length==0))\r
+ {\r
+ throw new Error("Empty selection must have at least a selection ID or at least one vorbaID indicating selection scope.");\r
+ }\r
+ message.append("none");\r
+ return;\r
+ } \r
+ // Verify that the range has at least one valid vorbaID for it to be defined on.\r
+ if (vorbaIDs==null || vorbaIDs.length==0)\r
+ {\r
+ throw new Error("You must specify at least one vorbaID for the selection.");\r
+ }\r
+ if (ranges != null) {\r
+ if (ranges.getPosCount() > 0) {\r
+ message.append("\tpositions=");\r
+ Pos[] pos = ranges.getPos();\r
+ for (int p = 0; p < pos.length; p++) {\r
+ if (p > 0) {\r
+ message.append(",");\r
+ }\r
+ message.append(pos[p].getI());\r
+ }\r
+ } else if (ranges.getSegCount() > 0) {\r
+ message.append("\tranges=");\r
+ Seg[] rng = ranges.getSeg();\r
+ for (int p = 0; p < rng.length; p++) {\r
+ boolean inc = rng[p].getInclusive();\r
+ if (p > 0) {\r
+ message.append(",");\r
+ }\r
+ if (inc) {\r
+ message.append("[");\r
+ } else {\r
+ message.append("(");\r
+ }\r
+ message.append(rng[p].getStart());\r
+ message.append(",");\r
+ message.append(rng[p].getEnd());\r
+ }\r
+ }\r
+ }\r
+ message.append("\n");\r
+ this.message = message.toString();\r
+ }\r
+\r
+ /**\r
+ * @return the selectionID\r
+ */\r
+ public String getSelectionID() {\r
+ return selectionID;\r
+ }\r
+\r
+ /**\r
+ * @return the vorbaIDs\r
+ */\r
+ public String[] getVorbaIDs() {\r
+ return vorbaIDs;\r
+ }\r
+\r
+ /**\r
+ * @return the ranges\r
+ */\r
+ public RangeType getRanges() {\r
+ return ranges;\r
+ }\r
+\r
+ /**\r
+ * @return the none\r
+ */\r
+ public boolean isNone() {\r
+ return none;\r
+ }\r
+}\r
\r
import java.util.logging.*;\r
\r
+import uk.ac.vamsas.objects.core.Input;\r
+import uk.ac.vamsas.objects.core.Pos;\r
+import uk.ac.vamsas.objects.core.Seg;\r
+\r
/**\r
* Simple example of a (runnable) class that shows how to use the picking API.\r
+ * use this to test new messages. Bear in mind that any active pick server only\r
+ * relays messages that could be parsed at compile time - that means that you\r
+ * must make sure that you close all currently running vamsas pick servers and\r
+ * start a new one which copes with the new message in order to be able to\r
+ * receive any of the new message classes.\r
*/\r
-public class TestApp implements IMessageHandler\r
-{\r
- public static void main(String[] args)\r
- throws Exception\r
- {\r
- TestApp app = new TestApp();\r
- }\r
- \r
- public TestApp()\r
- {\r
- IPickManager manager = new SocketManager();\r
- manager.registerMessageHandler(this);\r
- \r
- while (true)\r
- { \r
- try { Thread.sleep((int) (Math.random()*5000)); }\r
- catch (InterruptedException e) {}\r
- \r
- int rnd = (int) (Math.random()*100);\r
- CustomMessage msg = new CustomMessage("" + rnd);\r
- \r
-// manager.sendMessage(msg);\r
-\r
- MouseOverMessage mom = new MouseOverMessage("wibble", 10);\r
- manager.sendMessage(mom);\r
- }\r
- }\r
- \r
- public void handleMessage(Message message)\r
- {\r
- System.out.println("Handler received " + message.getRawMessage());\r
- }\r
+public class TestApp implements IMessageHandler {\r
+ public static void main(String[] args) throws Exception {\r
+ TestApp app = new TestApp();\r
+ }\r
+\r
+ public TestApp() {\r
+ IPickManager manager = new SocketManager();\r
+ manager.registerMessageHandler(this);\r
+ while (true) {\r
+ try {\r
+ Thread.sleep((int) (Math.random() * 5000));\r
+ } catch (InterruptedException e) {\r
+ }\r
+\r
+ int rnd = (int) (Math.random() * 100);\r
+ CustomMessage msg = new CustomMessage("" + rnd);\r
+\r
+ manager.sendMessage(msg);\r
+\r
+ try {\r
+ Thread.sleep((int) (Math.random() * 5000));\r
+ } catch (InterruptedException e) {\r
+ }\r
+\r
+ MouseOverMessage mom = new MouseOverMessage("wibble", 10);\r
+ manager.sendMessage(mom);\r
+\r
+ try {\r
+ Thread.sleep((int) (Math.random() * 5000));\r
+ } catch (InterruptedException e) {\r
+ }\r
+\r
+ try {\r
+ Input range = new Input();\r
+ for (int in = 0, inL = (2 + ((int) (Math.random() * 10f))); in < inL; in++) {\r
+ if ((inL % 2) == 1) {\r
+ Seg sg = new Seg();\r
+ sg.setStart((int) (Math.random() * 1000f));\r
+ sg.setEnd((int) (Math.random() * 1000f));\r
+ sg.setInclusive((((int) (Math.random() * 10f)) % 2) == 0);\r
+ range.addSeg(sg);\r
+ } else {\r
+ Pos p = new Pos();\r
+ p.setI((int) (Math.random() * 1000f));\r
+ range.addPos(p);\r
+ }\r
+ }\r
+ String[] ids = new String[(int) (Math.random() * 10)];\r
+ for (int id = 0; id < ids.length; id++) {\r
+ ids[id] = "object" + id;\r
+ }\r
+ \r
+ SelectionMessage sel = new SelectionMessage("mysel", ids, (ids.length>0) ? range : null,(ids.length==0) ? true : false);\r
+ sel.validate();\r
+ manager.sendMessage(sel);\r
+ } catch (Exception e) {\r
+ System.err.println("Failed to construct and send selection message.");\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+ }\r
+\r
+ public void handleMessage(Message message) {\r
+ System.out.println("Handler received " + message.getRawMessage());\r
+ if (message instanceof MouseOverMessage) {\r
+ MouseOverMessage mm = (MouseOverMessage) message;\r
+ System.out.println("MouseOver : " + mm.getPosition() + " on id "\r
+ + mm.getVorbaID());\r
+ }\r
+ if (message instanceof SelectionMessage) {\r
+ SelectionMessage sm = (SelectionMessage) message;\r
+\r
+ System.out.println("Selection "\r
+ + ((sm.getSelectionID() == null) ? "on " : "'" + sm.getSelectionID()\r
+ + "' on ")\r
+ + sm.getVorbaIDs().length\r
+ + ((sm.getRanges() == null) ? "." : " over "\r
+ + ((sm.getRanges().getPosCount() > 0) ? ""\r
+ + sm.getRanges().getPosCount() + " positions" : ""\r
+ + sm.getRanges().getSegCount() + "intervals.")));\r
+ }\r
+ }\r
}
\ No newline at end of file