Author: ruschein
Date: 2010-12-29 10:30:09 -0800 (Wed, 29 Dec 2010)
New Revision: 23275
Modified:
core3/table-browser-impl/trunk/src/main/java/org/cytoscape/browser/internal/BrowserTableModel.java
Log:
Added support for list editing.
Modified:
core3/table-browser-impl/trunk/src/main/java/org/cytoscape/browser/internal/BrowserTableModel.java
===================================================================
---
core3/table-browser-impl/trunk/src/main/java/org/cytoscape/browser/internal/BrowserTableModel.java
2010-12-29 04:21:58 UTC (rev 23274)
+++
core3/table-browser-impl/trunk/src/main/java/org/cytoscape/browser/internal/BrowserTableModel.java
2010-12-29 18:30:09 UTC (rev 23275)
@@ -1,6 +1,9 @@
package org.cytoscape.browser.internal;
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -27,6 +30,7 @@
public class BrowserTableModel extends AbstractTableModel
implements ColumnCreatedListener, ColumnDeletedListener,
RowCreatedMicroListener
{
+ private static final int EOF = -1;
private final JTable table;
private final CyEventHelper eventHelper;
private final CyTable attrs;
@@ -349,11 +353,306 @@
return null;
}
- private Object parseList(final String text, final Class elementType,
final StringBuilder errorMessage) {
- errorMessage.append("parseList() has not yet been
implemented!");
- return null;
+ enum ListParserState {
+ OPENING_BRACE_EXPECTED, COMMA_OR_CLOSING_BRACE_EXPECTED,
+ ITEM_OR_CLOSING_BRACE_EXPECTED, ITEM_EXPECTED,
END_OF_INPUT_EXPECTED
+ };
+
+ @SuppressWarnings (value={"unchecked", "fallthrough"})
+ static List parseList(final String text, final Class<?>
listElementType, final StringBuilder errorMessage) {
+ final List newList = new ArrayList();
+ final StringReader reader = new StringReader(text);
+
+ ListParserState state = ListParserState.OPENING_BRACE_EXPECTED;
+ for (;;) {
+ int ch = EOF;
+ try {
+ reader.mark(0);
+ ch = reader.read();
+System.err.println("************** at the top of the for-loop, ch="+(char)ch);
+ } catch (final IOException e) {
+ throw new IllegalStateException("We should
*never* get here!");
+ }
+
+ if (ch == '\n' || ch == '\t' || ch == ' ')
+ continue;
+
+ switch (state) {
+ case OPENING_BRACE_EXPECTED:
+ if (ch == '[') {
+ state =
ListParserState.ITEM_OR_CLOSING_BRACE_EXPECTED;
+ break;
+ } else {
+ errorMessage.append("List must start
with '['!");
+ return null;
+ }
+ case ITEM_OR_CLOSING_BRACE_EXPECTED:
+ if (ch == ']') {
+ state =
ListParserState.END_OF_INPUT_EXPECTED;
+ break;
+ }
+ case ITEM_EXPECTED:
+ if (ch == EOF) {
+ errorMessage.append("Premature end of
list!");
+ return null;
+ }
+ try {
+ reader.reset();
+ } catch (final IOException e) {
+ throw new IllegalStateException("We
should *never* get here!");
+ }
+
+ final Object item = getListItem(reader,
listElementType, errorMessage);
+ if (item == null)
+ return null;
+ newList.add(item);
+
+ state =
ListParserState.COMMA_OR_CLOSING_BRACE_EXPECTED;
+ break;
+ case COMMA_OR_CLOSING_BRACE_EXPECTED:
+ if (ch == ']') {
+ state =
ListParserState.END_OF_INPUT_EXPECTED;
+ break;
+ } else if (ch == ',') {
+ state = ListParserState.ITEM_EXPECTED;
+ break;
+ } else {
+ errorMessage.append("Unexpected
character(s) in list detected!");
+ return null;
+ }
+ case END_OF_INPUT_EXPECTED:
+ if (ch != EOF) {
+ errorMessage.append("Unexpected garbage
after end of list!");
+ return null;
+ }
+
+ return newList;
+ }
+ }
}
+ private static Object getListItem(final StringReader reader, final
Class<?> listElementType,
+ final StringBuilder errorMessage)
+ {
+ if (listElementType == Double.class)
+ return getDouble(reader, errorMessage);
+ else if (listElementType == String.class)
+ return getString(reader, errorMessage);
+ else if (listElementType == Integer.class || listElementType ==
Long.class) {
+ // Process optional leading sign:
+ int ch = EOF;
+ try {
+ reader.mark(0);
+ ch = reader.read();
+ } catch (final IOException e) {
+ throw new IllegalStateException("We should
*never* get here!");
+ }
+ final StringBuilder builder = new StringBuilder();
+ if (ch == '-')
+ builder.append((char)ch);
+ else if (ch == '+')
+ /* Intentionally empty! */;
+ else {
+ try {
+ reader.reset();
+ } catch (final IOException e) {
+ throw new IllegalStateException("We
should *never* get here!");
+ }
+ }
+
+ grabAsciiDigits(reader, builder);
+ try {
+ if (listElementType == Integer.class)
+ return
Integer.valueOf(builder.toString());
+ else
+ return Long.valueOf(builder.toString());
+ } catch (final NumberFormatException e) {
+ errorMessage.append("Found invalid integer or
long integer list item!");
+ return null;
+ }
+ } else if (listElementType == Boolean.class) {
+ final StringBuilder builder = new StringBuilder();
+ grabAsciiLetters(reader, builder);
+ final String boolValueCandidate = builder.toString();
+ if (boolValueCandidate.equalsIgnoreCase("true"))
+ return Boolean.valueOf(true);
+ else if (boolValueCandidate.equalsIgnoreCase("false"))
+ return Boolean.valueOf(false);
+ else {
+ errorMessage.append("\"" + boolValueCandidate
+ + "\" is not a valid
boolean list item!");
+ return null;
+ }
+ } else
+ throw new IllegalStateException("unknown list element
type: "
+ +
listElementType.getName() + "!");
+ }
+
+ private static Double getDouble(final StringReader reader, final
StringBuilder errorMessage) {
+ try {
+ reader.mark(0);
+ int ch = reader.read();
+ if (ch == EOF) {
+ errorMessage.append("Unexpected end of input
while trying to read a floating point number!");
+ return null;
+ }
+
+ final StringBuilder builder = new StringBuilder();
+
+ // Process optional leading sign:
+ if (ch == '-' || ch == '+')
+ builder.append((char)ch);
+ else
+ reader.reset();
+
+ int savedLength = builder.length();
+ grabAsciiDigits(reader, builder);
+ final boolean needAfterDecimalPointDigits =
builder.length() == savedLength;
+
+ // Process optional decimal point followed by zero or
more digits:
+ reader.mark(0);
+ ch = reader.read();
+ if (ch != '.') {
+ if (needAfterDecimalPointDigits) {
+ errorMessage.append("Bad or missing
floating point list item!");
+ return null;
+ }
+ reader.reset();
+ } else {
+ builder.append('.');
+ savedLength = builder.length();
+ grabAsciiDigits(reader, builder);
+ if (needAfterDecimalPointDigits && savedLength
== builder.length()) {
+ errorMessage.append("Bad or missing
floating point list item!");
+ return null;
+ }
+ }
+
+ // Process optional exponent:
+ reader.mark(0);
+ ch = reader.read();
+ if (ch != 'e' && ch != 'E')
+ reader.reset();
+ else {
+ builder.append('e');
+
+ // Process optional sign:
+ reader.mark(0);
+ ch = reader.read();
+ if (ch != '+' && ch != '-')
+ reader.reset();
+ else
+ builder.append((char)ch);
+
+ savedLength = builder.length();
+ grabAsciiDigits(reader, builder);
+ if (builder.length() == savedLength) {
+ errorMessage.append("Invalid
exponent!");
+ return null;
+ }
+ }
+
+ try {
+ return Double.valueOf(builder.toString());
+ } catch (Exception e) {
+ errorMessage.append("Malformed number!");
+ return null;
+ }
+ } catch (final IOException e) {
+ throw new IllegalStateException("This should *never*
happen!");
+ }
+ }
+
+ private static void grabAsciiDigits(final StringReader reader, final
StringBuilder builder) {
+ try {
+ for (;;) {
+ reader.mark(0);
+ final int ch = reader.read();
+ if (ch == EOF || (char)ch < '0' || (char)ch >
'9') {
+ reader.reset();
+ return;
+ }
+
+ builder.append((char)ch);
+ }
+ } catch (final IOException e) {
+ throw new IllegalStateException("This should *never*
happen!");
+ }
+ }
+
+ private static String getString(final StringReader reader, final
StringBuilder errorMessage) {
+ try {
+ if (reader.read() != '"') {
+ errorMessage.append("Strings must start with a
double quote symbol!");
+ return null;
+ }
+
+ final StringBuilder builder = new StringBuilder();
+
+ int ch = reader.read();
+ boolean escaped = false;
+ while (escaped || ch != '"') {
+ if (ch == EOF) {
+ errorMessage.append("Unterminated
string list item!");
+ return null;
+ }
+
+ if (escaped) {
+ switch (ch) {
+ case 'n':
+ builder.append('\n');
+ break;
+ case 't':
+ builder.append('\t');
+ break;
+ case 'r':
+ builder.append('\r');
+ break;
+ case 'f':
+ builder.append('\f');
+ break;
+ case 'b':
+ builder.append('\b');
+ break;
+ default:
+ builder.append((char)ch);
+ }
+ escaped = false;
+ } else if (ch == '\\')
+ escaped = true;
+ else
+ builder.append((char)ch);
+
+ ch = reader.read();
+ }
+
+ return builder.toString();
+ } catch (final IOException e) {
+ throw new IllegalStateException("This should *never*
happen!");
+ }
+ }
+
+ private static void grabAsciiLetters(final StringReader reader, final
StringBuilder builder)
+ {
+ try {
+ for (;;) {
+ reader.mark(0);
+ final int ch = reader.read();
+ if (ch == EOF
+ || (((char)ch < 'a' || (char)ch > 'z')
+ && ((char)ch < 'A' || (char)ch > 'Z')))
+ {
+ reader.reset();
+ return;
+ }
+
+ builder.append((char)ch);
+ }
+ } catch (final IOException e) {
+ throw new IllegalStateException("This should *never*
happen!");
+ }
+ }
+
public void cleanup() {
eventHelper.removeMicroListener(this,
RowCreatedMicroListener.class, attrs);
for (final RowSetMicroListenerProxy proxy :
rowToListenerProxyMap.values())
--
You received this message because you are subscribed to the Google Groups
"cytoscape-cvs" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/cytoscape-cvs?hl=en.