
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.List;
import java.util.StringTokenizer;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextArea;
import javax.swing.JTabbedPane;
import javax.swing.SwingUtilities;
import javax.swing.text.BadLocationException;

import com.xerox.amazonws.simpledb.Domain;
import com.xerox.amazonws.simpledb.Item;
import com.xerox.amazonws.simpledb.SDBException;
import com.xerox.amazonws.simpledb.SelectResult;
import com.xerox.amazonws.simpledb.SimpleDB;

public class QueryTool extends JPanel implements ActionListener {
	private JFrame parent;
	private JTextArea querySpace;
	private JTabbedPane results;
	private Domain dom;

	public QueryTool(JFrame parent, String accessId, String secretKey, String domain) {
		this.parent = parent;
		layoutGUI();
		SimpleDB sdb = new SimpleDB(accessId, secretKey);
		try {
			dom = sdb.getDomain(domain);
		} catch (SDBException ex) {
			System.err.println("Could not create domain object: "+ex.getMessage());
			System.exit(-1);
		}
	}

	private void layoutGUI() {
		setLayout(new GridBagLayout());

		JButton runQuery = new JButton("run");
		runQuery.addActionListener(this);
		GridBagConstraints gbc = new GridBagConstraints();
		gbc.gridwidth = GridBagConstraints.REMAINDER;
		add(runQuery, gbc);

		querySpace = new JTextArea();

		results = new JTabbedPane();

		JSplitPane split = new JSplitPane(JSplitPane.VERTICAL_SPLIT, querySpace, results);
		querySpace.setMinimumSize(new Dimension(100, 100));

		gbc = new GridBagConstraints();
		gbc.gridwidth = GridBagConstraints.REMAINDER;
		gbc.weightx = 1.0;
		gbc.weighty = 1.0;
		gbc.fill = GridBagConstraints.BOTH;
		add(split, gbc);
	}

	public void actionPerformed(ActionEvent evt) {
		try {
			int lineNum = querySpace.getLineOfOffset(querySpace.getCaretPosition())+1;
			StringTokenizer st = new StringTokenizer(querySpace.getText(), "\n", true);
			int lineCount = 0;
			String val = "";
			while (st.hasMoreTokens()) {
				String tok = st.nextToken();
				if (tok.equals("\n")) {
					lineCount++;
				}
				else {
					val = tok;
				}
				if (lineCount == lineNum) break;
			}
			final String query = val;
			final JTextArea resultSpace = new JTextArea();
			JScrollPane sp = new JScrollPane(resultSpace);
			results.add("query", sp);
			results.setSelectedComponent(sp);
			new Thread(new Runnable() {
				public void run() {
					StringBuilder resText = new StringBuilder();
					try {
						int itemCount = 0;
						long start = System.currentTimeMillis();
						String nextToken = null;
						do {
							SelectResult sr = dom.selectItems(query, nextToken);
							List<Item> items = sr.getItems();
							for (Item item : items) {
								resText.append("Item : "+item.getIdentifier()+"\n");
								for (String key : item.getAttributes().keySet()) {
									String value = item.getAttributes().get(key);
									resText.append("  "+key+" = "+value+"\n");
								}
								itemCount++;
								if (itemCount > 1000) {
									resText.append("\nquery terminated. max results hit\n");
									break;
								}
							}
							nextToken = sr.getNextToken();
							resText.append("Box Usage :"+sr.getBoxUsage()+"\n");
							updateResults(resultSpace, resText.toString());
							if (itemCount > 1000) {
								nextToken = null;
							}
						} while (nextToken != null && !nextToken.trim().equals(""));
						long end = System.currentTimeMillis();
						resText.append("Time : "+((int)(end-start)/1000.0)+"\n");
						resText.append("Number of items returned : "+itemCount+"\n");
					} catch (SDBException ex) {
						resText.append(ex.getMessage());
					}
					updateResults(resultSpace, resText.toString());
				}
			}).start();
		} catch (BadLocationException ex) {
		}
	}

	void updateResults(final JTextArea area, final String data) {
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				area.setText(data);
			}
		});
	}

	public static void main(String [] args) {
		final JFrame frame = new JFrame("SimpleDB Query Tool");
		final QueryTool controls = new QueryTool(frame, args[0], args[1], args[2]);
		Dimension size = controls.getPreferredSize();
		frame.setSize(600, 600);
		frame.addWindowListener(new WindowAdapter() {
				public void windowClosing(WindowEvent event) {
					System.exit(0);
				}
			});
		frame.setContentPane(controls);
		frame.setVisible(true);
	}
}

@@ -250,19 +250,68 @@
 va.util.
-Lis
+Iterator;%0Aimport java.util.List;%0Aimport java.util.Se
 t;%0Aimpor
@@ -3199,20 +3199,26 @@
 %09%09%09%09
+Set%3C
 String
+%3E
  value
+s
  = i
@@ -3247,16 +3247,95 @@
 t(key);%0A
+%09%09%09%09%09%09%09%09%09Iterator iter = values.iterator();%0A%09%09%09%09%09%09%09%09%09while (iter.hasNext()) %7B%0A%09
 %09%09%09%09%09%09%09%09
@@ -3369,20 +3369,37 @@
 = %22+
-value+%22%5Cn%22);
+iter.next()+%22%5Cn%22);%0A%09%09%09%09%09%09%09%09%09%7D
 %0A%09%09%09

tweak to show multi-value attrs