Files
secondo/Javagui/viewer/CStreamViewer.java

1259 lines
39 KiB
Java
Raw Permalink Normal View History

2026-01-23 17:03:45 +08:00
package viewer;
import java.awt.GridLayout;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.ConnectException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Iterator;
import javax.swing.BoxLayout;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSlider;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import gui.SecondoObject;
import tools.Reporter;
import sj.lang.MyDataInputStream;
import sj.lang.MyDataOutputStream;
/**
* This class provides a viewer for the CStreamAlgebra to display tuplestreams
*/
public class CStreamViewer extends SecondoViewer {
private TupleStreamReceiver tsr;
private HashMap<String, LinkedHashSet<String>> tuplemap;
private ArrayList<String> attributes, allAttributes, opList, containerAttrs;
private String tupledescription, unknownAttr, unknownOp;
private String hostname;
private int tupleport, streamport, numOfTuples;
private boolean connect = false;
private int idxHelper;
private boolean cutAllowed = false;
private JTextField filterField, numOfTypes, hostnameField, tupleportField, streamportField;;
private JTextArea tupletextarea;
private JSlider slider;
private JLabel sliderlabel;
private JButton confirmBtn, showBtn;
private final String TUPLE_TYPE_PROTOCOL_MSG = "RequestDone()";
private final String TUPLE_STREAM_PROTOCOL_MSG = "StreamDone()";
/** The constructor which layouts the viewer */
public CStreamViewer(){
setLayout(new BorderLayout());
/* north */
JPanel filterpanel = new JPanel();
filterpanel.setLayout(new BoxLayout(filterpanel, BoxLayout.LINE_AXIS));
JLabel filterlabel = new JLabel("Filter : ");
filterField = new JTextField();
filterpanel.add(filterlabel);
filterpanel.add(filterField);
/* center */
JPanel textpanel = new JPanel();
textpanel.setLayout(new BorderLayout());
tupletextarea = new JTextArea();
tupletextarea.setEditable(false);
textpanel.add(new JScrollPane(tupletextarea), BorderLayout.CENTER);
/* west */
JPanel westpanel = new JPanel();
westpanel.setLayout(new GridLayout(2,0));
JPanel configpanel = new JPanel();
configpanel.setLayout(new BoxLayout(configpanel, BoxLayout.PAGE_AXIS));
JLabel numOfTypesLabel = new JLabel("Number of Tupletypes");
numOfTypes = new JTextField();
JLabel hostlabel = new JLabel("Hostname");
hostnameField = new JTextField();
JLabel tuplelabel = new JLabel("Port for Tupletypes");
tupleportField = new JTextField();
JLabel streamlabel = new JLabel("Port for Tuplestream");
streamportField = new JTextField();
confirmBtn = new JButton();
confirmBtn.setText("receive tupletypes");
configpanel.add(numOfTypesLabel);
configpanel.add(numOfTypes);
configpanel.add(hostlabel);
configpanel.add(hostnameField);
configpanel.add(tuplelabel);
configpanel.add(tupleportField);
configpanel.add(streamlabel);
configpanel.add(streamportField);
configpanel.add(confirmBtn);
JPanel sliderpanel = new JPanel();
sliderpanel.setLayout(new BoxLayout(sliderpanel, BoxLayout.PAGE_AXIS));
sliderlabel = new JLabel("show 5 Tuples");
slider = new JSlider(JSlider.HORIZONTAL, 1, 30, 5);
showBtn = new JButton();
showBtn.setText("receive tuplestream");
sliderpanel.add(slider);
sliderpanel.add(sliderlabel);
sliderpanel.add(showBtn);
westpanel.add(configpanel);
westpanel.add(sliderpanel);
add(filterpanel, BorderLayout.NORTH);
add(textpanel, BorderLayout.CENTER);
add(westpanel, BorderLayout.WEST);
tsr = new TupleStreamReceiver();
tuplemap = new HashMap<String, LinkedHashSet<String>>();
attributes = new ArrayList<String>();
allAttributes = new ArrayList<String>();
opList = new ArrayList<String>();
containerAttrs = new ArrayList<String>();
tupledescription = new String();
fillOpList();
confirmBtn.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent action) {
showTupleTypes();
}
});
slider.addChangeListener(new ChangeListener(){
@Override
public void stateChanged(ChangeEvent c) {
sliderlabel.setText("show "+slider.getValue()+" Tuples");
}
});
showBtn.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent action) {
if( !connect ){
showTuples();
} else {
tsr.stopThread();
}
}
});
}
/** This function is not needed in this viewer */
public boolean addObject(SecondoObject o){
return false;
}
/** This function is not needed in this viewer */
public boolean isDisplayed(SecondoObject o){
return false;
}
/** This function is not needed in this viewer */
public void removeObject(SecondoObject o){ }
/** This function is not needed in this viewer */
public void removeAll(){ }
/** This function is not needed in this viewer */
public boolean canDisplay(SecondoObject o){
return false;
}
/** Returns the name of this viewer */
public String getName(){
return "CStreamViewer";
}
/** This function is not needed in this viewer */
public boolean selectObject(SecondoObject O){
return false;
}
/** Fills the operatorlist with available operators for the filter */
private void fillOpList(){
opList.add("+");
opList.add("-");
opList.add("*");
opList.add("/");
opList.add("<");
opList.add("<=");
opList.add("=");
opList.add(">=");
opList.add(">");
opList.add("#");
opList.add("startsWith");
opList.add("contains");
opList.add("count");
opList.add("mod");
opList.add("div");
}
/** Checks the userinputs for the serverconnections */
private boolean checkEntries(){
boolean tpOK = false;
boolean spOK = false;
boolean ntOK = false;
try {
tupleport = Integer.parseInt(tupleportField.getText());
tpOK = true;
} catch ( NumberFormatException tp ) {
Reporter.showInfo("Invalid entry for the tupleport.\nPlease select a number between 0 and 65535.");
}
try {
streamport = Integer.parseInt(streamportField.getText());
spOK = true;
} catch ( NumberFormatException sp ) {
Reporter.showInfo("Invalid entry for the streamport.\nPlease select a number between 0 and 65535.");
}
try {
numOfTuples = Integer.parseInt(numOfTypes.getText());
ntOK = true;
} catch ( NumberFormatException np ) {
Reporter.showInfo("Invalid entry for number of tupletypes.\nPlease select a number greater than zero.");
}
if(!tpOK || !spOK || !ntOK ){
return false;
}
hostname = hostnameField.getText();
if ( hostname.isEmpty() || tupleport < 0 || tupleport > 65535 ||
streamport < 0 || streamport > 65535 || numOfTuples < 1){
hostnameField.setText("127.0.0.1");
tupleportField.setText("1024");
streamportField.setText("1024");
numOfTypes.setText("1");
Reporter.showInfo("One or more entries are invalid (out of bounds)");
return false;
} else {
return true;
}
}
/** This function starts the serverconnection to get the
* tupletypes from the server which provides tupletypes
*/
private void showTupleTypes(){
tuplemap.clear();
if ( !checkEntries() ){
return;
}
String tupletypes = new String();
TupleTypeReceiver ttr = new TupleTypeReceiver();
ttr.startThread();
/* Wait one second, to receive a tupledescription from the
* server before the thread will be killed */
int loop = 10;
while( !ttr.canInterrupt() && loop > 0){
try {
Thread.sleep(100);
loop--;
} catch ( InterruptedException ie ){
Reporter.debug(ie);
}
}
tupletypes = ttr.getTupleTypes();
ttr.stopThread();
if ( tupletypes.equals("()RequestDone()") ){
Reporter.showInfo("An empty tupledescription received! Abort.");
return;
} else if ( tupletypes.equals("") ){
Reporter.showInfo("no tupledescription received.");
return;
}
tupletypes = tupletypes.replace(") (",")("); //
splitList(tupletypes);
if ( !tuplemap.isEmpty() ){
new TupleDialog();
if ( tupledescription.equals("()") || tupledescription.equals("") ){
Reporter.showInfo("An empty or no description was choosed. Abort.");
return;
}
if( !attributes.isEmpty() ){
buildProjectTupleDescription();
for(int i = 0; i < containerAttrs.size(); i++){
eraseEmptyContainers();
}
}
}
}
/** An algorithm to extract tupletypes and their attributes */
private void splitList(String tupletypes){
if ( tupletypes.isEmpty() ){
return;
}
if ( tupletypes.indexOf(TUPLE_TYPE_PROTOCOL_MSG) != -1 ){
tupletypes = tupletypes.replace(TUPLE_TYPE_PROTOCOL_MSG,"");
} else {
Reporter.showInfo("Protocol error : No "+TUPLE_TYPE_PROTOCOL_MSG+" received.");
return;
}
ArrayList<String> tupledescrs = new ArrayList<String>();
int bracketcounter = 0;
int idxOld = 0;
for(int i = 0; i < tupletypes.length(); i++){
if ( tupletypes.charAt(i) == '(' ){
bracketcounter++;
} else if ( tupletypes.charAt(i) == ')' ){
bracketcounter--;
if ( bracketcounter == 0 ){
String sub = tupletypes.substring(idxOld, i + 1);
idxOld = i + 1;
tupledescrs.add(sub);
}
}
}
tuplemap = getTupleTypes(tupledescrs);
}
/** Extracts all tupletypes and attributes */
private HashMap<String, LinkedHashSet<String>> getTupleTypes(final ArrayList<String> tupletypes){
HashMap<String, LinkedHashSet<String>> map = new HashMap<String, LinkedHashSet<String>>();
for(int i = 0; i < tupletypes.size(); i++){
LinkedHashSet<String> attrs = getAttributes(tupletypes.get(i));
String temp = tupletypes.get(i);
map.put(temp, attrs);
}
return map;
}
/** Extracts all attributes from a giving tupledescription */
private LinkedHashSet<String> getAttributes(String tupledesc){
LinkedHashSet<String> attrs = new LinkedHashSet<String>();
int begin= -1;
int end = 0;
while(begin != end){
begin = end;
begin = getStartIndex(tupledesc, end);
end = getEndIndex(tupledesc, begin);
if ( end == tupledesc.length() || begin == end ){
break;
}
String sub = tupledesc.substring(begin - 1, end + 1);
if( !(sub.contains("record") || sub.contains("vector")) ){
attrs.add(sub);
} else {
int blank = 0;
for(int i = 1; i < sub.length(); i++){
if(sub.charAt(i) == ' '){
blank = i;
break;
}
}
sub = sub.substring(1, blank);
containerAttrs.add("("+sub+")");
containerAttrs.add("("+sub+" )");
containerAttrs.add("("+sub+" )");
}
}
return attrs;
}
/** Finds the startindex where an attributes begins */
private int getStartIndex(String tupledesc, int end){
int start = end;
for(int i = end; i < tupledesc.length(); i++){
if ( Character.isUpperCase(tupledesc.charAt(i)) ){
start = i;
break;
}
}
return start;
}
/** Finds the endindex where the attributes ends or a container begins */
private int getEndIndex(String tupledesc, int start){
int end = start;
for(int i = start; i < tupledesc.length(); i++){
if ( tupledesc.charAt(i) == '(' ){
return i + "vector".length();
} else if ( tupledesc.charAt(i) == ')' ){
end = i;
break;
} else if ( i == tupledesc.length() - 1 ){
return tupledesc.length();
}
}
return end;
}
/** This function builds a projected tupledescription with the
* choosen attributes from the tupledialog
*/
private void buildProjectTupleDescription(){
for(int i = 0; i < attributes.size(); i++){
tupledescription = tupledescription.replace(attributes.get(i), "");
}
}
/** deletes an empty vector or record */
private void eraseEmptyContainers(){
tupledescription = tupledescription.replace(" ()","");
tupledescription = tupledescription.replace("()","");
tupledescription = tupledescription.replace("(vector)","");
tupledescription = tupledescription.replace("(record)","");
tupledescription = tupledescription.replace("(vector )","");
tupledescription = tupledescription.replace("(record )","");
for(int i = 0; i < containerAttrs.size(); i++){
tupledescription = tupledescription.replace(containerAttrs.get(i),"");
}
}
/** This function starts the serverconnection to get the
* tuplestreams from the server which distributes a tuplestream
*/
private void showTuples(){
if ( !checkEntries() ){
return;
}
String filter = checkFilterContent();
if ( filter.equals("error") ){
Reporter.showInfo("Invalid entry for the filtercondition\ne.g. '.No >= 5'\ne.g. 'fun(t : tuple([No : int])) attr(t,No) >= 5'.");
return;
} else if ( filter.equals("errAttr") ){
Reporter.showInfo("Unknown attribute for the filter :'"+unknownAttr+"'");
return;
} else if ( filter.equals("errOp") ){
Reporter.showInfo("Unknown operator for the filter :'"+unknownOp+"'");
return;
}
tsr = new TupleStreamReceiver();
tsr.setFilter(filter);
tsr.startThread();
}
/** Checks the filterinput */
private String checkFilterContent(){
if ( filterField.getText().isEmpty() ){
return new String("()");
} else {
return buildOpTreeString();
}
}
/** This function builds an 'operatortreestring' */
private String buildOpTreeString(){
String fkt = filterField.getText();
if ( fkt.length() < 3){
return new String("error");
}
if(fkt.startsWith(".")){
try {
return shortForm(fkt);
} catch ( StringIndexOutOfBoundsException se ){
return new String("error");
}
} else if (fkt.startsWith("fun")){
try {
return longForm(fkt);
} catch ( StringIndexOutOfBoundsException se ){
return new String("error");
}
} else {
return new String("error");
}
}
private boolean examineAttributeFromFilter(String filterattr){
for(int i = 0; i < allAttributes.size(); i++){
if(allAttributes.get(i).contains(filterattr)){
return true;
}
}
unknownAttr = filterattr;
return false;
}
private boolean examineOperatorFromFilter(String filterop){
for(int i = 0; i < opList.size(); i++){
if(filterop.equals(opList.get(i)) ){
return true;
}
}
unknownOp = filterop;
return false;
}
/** Creates an operatortree from a longform */
private String longForm(String funtxt) throws StringIndexOutOfBoundsException {
String filterattr = new String();
String filterop = new String();
String filterval = new String();
funtxt = funtxt.trim();
int idx = funtxt.indexOf("attr");
funtxt = funtxt.substring(idx, funtxt.length());
idx = funtxt.indexOf(",");
funtxt = funtxt.substring(idx + 1, funtxt.length());
idx = funtxt.indexOf(")");
filterattr = funtxt.substring(0, idx);
if ( !examineAttributeFromFilter(filterattr) ){
return new String("errAttr");
}
funtxt = funtxt.substring(idx + 1, funtxt.length());
funtxt = funtxt.trim();
idx = funtxt.indexOf(" ");
filterop = funtxt.substring(0, idx);
if ( !examineOperatorFromFilter(filterop) ){
return new String("errOp");
}
funtxt = funtxt.substring(idx + 1, funtxt.length());
/* One more condition */
if ( funtxt.contains(" ")){
String filterattr2 = new String();
String filterop2 = new String();
String filterval2 = new String();
String con = new String();
if ( funtxt.contains(" and ")){
con = "and";
} else if ( funtxt.contains(" or ")){
con = "or";;
}
idx = funtxt.indexOf(" ");
filterval = funtxt.substring(0, idx);
funtxt = funtxt.substring(idx + 1, funtxt.length());
idx = funtxt.indexOf("attr");
funtxt = funtxt.substring(idx, funtxt.length());
idx = funtxt.indexOf(",");
funtxt = funtxt.substring(idx + 1, funtxt.length());
idx = funtxt.indexOf(")");
filterattr2 = funtxt.substring(0, idx);
if ( !examineAttributeFromFilter(filterattr2) ){
return new String("errAttr");
}
funtxt = funtxt.substring(idx + 1, funtxt.length());
funtxt = funtxt.trim();
idx = funtxt.indexOf(" ");
filterop2 = funtxt.substring(0, idx);
if ( !examineOperatorFromFilter(filterop2) ){
return new String("errOp");
}
funtxt = funtxt.substring(idx + 1, funtxt.length());
filterval2 = funtxt.substring(0, funtxt.length() - 1);
return "(fun(t(tuple"+tupledescription+"))("+con+"("+filterop+"(attr t "+filterattr+")"+filterval+")("+filterop2+"(attr t "+filterattr2+")"+filterval2+")))";
} else {
/* no second condition */
filterval = funtxt.substring(0, funtxt.length());
return "(fun(t(tuple"+tupledescription+"))("+filterop+"(attr t "+filterattr+")"+filterval+"))";
}
}
/** Creates an operatortree from a shortform */
private String shortForm(String funtxt) throws StringIndexOutOfBoundsException {
String filterattr = new String();
String filterop = new String();
String filterval = new String();
String con = new String();
boolean two = false;
funtxt = funtxt.trim();
funtxt = funtxt.replace("(","");
funtxt = funtxt.replace(")","");
/* examine, if there is a second filtercondition */
if ( funtxt.contains(" and ")){
con = "and";
two = true;
} else if ( funtxt.contains(" or ")){
con = "or";
two = true;
}
funtxt = funtxt.substring(1, funtxt.length());
int pos = 0;
for(int i = 0; i < funtxt.length(); i++){
if(funtxt.charAt(i) == ' '){
pos = i;
break;
}
}
filterattr = funtxt.substring(0, pos);
if ( !examineAttributeFromFilter(filterattr) ){
return new String("errAttr");
}
funtxt = funtxt.substring(pos + 1, funtxt.length());
for(int i = 0; i < funtxt.length(); i++){
if(funtxt.charAt(i) == ' '){
pos = i;
break;
}
}
filterop = funtxt.substring(0, pos);
if ( !examineOperatorFromFilter(filterop) ){
return new String("errOp");
}
funtxt = funtxt.substring(pos + 1, funtxt.length());
if (!two){
filterval = funtxt;
String opTree = "(fun(t(tuple"+tupledescription+"))("+filterop+"(attr t "+filterattr+")"+filterval+"))";
return opTree;
}
for(int i = 0; i < funtxt.length(); i++){
if(funtxt.charAt(i) == ' '){
pos = i;
break;
}
}
filterval = funtxt.substring(0, pos);
funtxt = funtxt.substring(pos + 1, funtxt.length());
String filterval2 = new String();
String filterop2 = new String();
String filterattr2 = new String();
for(int i = funtxt.length() - 1; i > 0; i--){
if(funtxt.charAt(i) == ' ' ){
pos = i;
break;
}
}
filterval2 = funtxt.substring(pos + 1, funtxt.length());
funtxt = funtxt.substring(0, pos);
for(int i = funtxt.length() - 1; i > 0; i--){
if(funtxt.charAt(i) == ' ' ){
pos = i;
break;
}
}
filterop2 = funtxt.substring(pos + 1, funtxt.length());
if ( !examineOperatorFromFilter(filterop2) ){
return new String("errOp");
}
funtxt = funtxt.substring(0, pos);
for(int i = funtxt.length() - 1; i > 0; i--){
if(funtxt.charAt(i) == '.' ){
pos = i;
break;
}
}
filterattr2 = funtxt.substring(pos + 1,funtxt.length());
if ( !examineAttributeFromFilter(filterattr2) ){
return new String("errAttr");
}
String opTree = "(fun(t(tuple"+tupledescription+"))("+con+"("+filterop+"(attr t "+filterattr+")"+filterval+")("+filterop2+"(attr t "+filterattr2+")"+filterval2+")))";
return opTree;
}
/** Updates the textarea which shows the tuplestream */
private void updateTupleTextArea(final String text){
tupletextarea.insert(text, 0);
}
/**
* A helperclass to choose tupletypes and optional attributes from this tupletype
*/
private class TupleDialog extends JDialog {
private DefaultListModel<String> tupletypelistmodel, attributelistmodel;
private JList<String> tupletypelist, attributelist;
private JButton ok;
private ArrayList<Integer> negativeIndices;
/** The constructor */
private TupleDialog(){
setModal(true);
setLayout(new GridLayout(2,0));
negativeIndices = new ArrayList<Integer>();
JPanel typepanel = new JPanel();
typepanel.setLayout(new BoxLayout(typepanel, BoxLayout.PAGE_AXIS));
JLabel typelabel = new JLabel("Available Tupletypes");
tupletypelistmodel = new DefaultListModel<String>();
tupletypelist = new JList<String>(tupletypelistmodel);
tupletypelist.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
tupletypelist.setSelectedIndex(0);
tupletypelist.setVisibleRowCount(10);
typepanel.add(typelabel);
typepanel.add(new JScrollPane(tupletypelist));
JPanel attrpanel = new JPanel();
attrpanel.setLayout(new BoxLayout(attrpanel, BoxLayout.PAGE_AXIS));
JLabel attrlabel = new JLabel("choose Attributes");
attributelistmodel = new DefaultListModel<String>();
attributelist = new JList<String>(attributelistmodel);
attributelist.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
attributelist.setSelectedIndex(0);
attributelist.setVisibleRowCount(10);
ok = new JButton("confirm");
ok.setEnabled(false);
attrpanel.add(attrlabel);
attrpanel.add(new JScrollPane(attributelist));
attrpanel.add(ok);
add(typepanel, BorderLayout.WEST);
add(attrpanel, BorderLayout.CENTER);
tupletypelist.addListSelectionListener(new ListSelectionListener(){
@Override
public void valueChanged(ListSelectionEvent l) {
if ( l.getValueIsAdjusting() ){
if ( tupletypelist.isSelectionEmpty() ){
ok.setEnabled(false);
} else {
ok.setEnabled(true);
}
final String tupledesc = tupletypelist.getSelectedValue();
addAttributesInList(tupledesc);
}
}
});
attributelist.addListSelectionListener(new ListSelectionListener(){
@Override
public void valueChanged(ListSelectionEvent l) {
if ( l.getValueIsAdjusting() ){
negativeIndices.clear();
for(int i = 0; i < attributelistmodel.getSize(); i++){
if(!attributelist.isSelectedIndex(i)){
negativeIndices.add(i);
}
}
}
}
});
ok.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent action) {
collectAttributes();
if ( collectTupleDescription() ){
clearEntries();
dispose();
}
}
});
addTupleTypesInList();
setSize(640, 480);
setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
setVisible(true);
}
/** Adds all tupletypes in the upper list */
private void addTupleTypesInList(){
for(Iterator<String> it = tuplemap.keySet().iterator(); it.hasNext();){
String type = it.next();
tupletypelistmodel.addElement(type);
}
}
/** Adds all attributes from the choosen tupletype in the lower list */
private void addAttributesInList(String tupledesc){
allAttributes.clear();
attributelistmodel.clear();
for(Iterator<String> at = tuplemap.get(tupledesc).iterator(); at.hasNext();){
String attr = at.next();
attributelistmodel.addElement(attr);
allAttributes.add(attr);
}
}
/** Saves the choosen tupletype from the upper list */
private boolean collectTupleDescription(){
tupledescription = tupletypelistmodel.getElementAt(tupletypelist.getSelectedIndex());
if( tupledescription.equals("()") ){
Reporter.showInfo("An empty tupledescription was choosed");
return false;
}
return true;
}
/** Saves all choosen attributes from the lower list, if no attributes is selected
* the original tupledescription will be choosen
*/
private void collectAttributes(){
attributes.clear();
if(negativeIndices.isEmpty()){
return;
}
for(int i = 0; i < negativeIndices.size(); i++){
attributes.add(attributelistmodel.getElementAt(negativeIndices.get(i)));
}
}
/** Clears all entries from the tuplemap and the two list */
private void clearEntries(){
tuplemap.clear();
tupletypelistmodel.clear();
attributelistmodel.clear();
}
}
/**
* A helperclass to receive the tupletypes from the server
*/
private class TupleTypeReceiver extends Thread {
private String tupletypes;
private boolean allowInterrupt;
private Socket socket;
private MyDataInputStream input;
private MyDataOutputStream output;
private BufferedInputStream reader;
private BufferedOutputStream writer;
/** The constructor */
private TupleTypeReceiver(){
tupletypes = new String();
allowInterrupt = false;
}
/** Starts the thread from outside */
public void startThread(){
start();
}
/** Interrupts the thread from outside */
public void stopThread(){
try {
writer.close();
reader.close();
output.close();
input.close();
socket.close();
} catch ( Exception e ){
Reporter.debug(e);
} finally {
interrupt();
}
}
/** Serverconnection */
@Override
public void run(){
try {
socket = new Socket(hostname, tupleport);
} catch ( ConnectException ce ){
allowInterrupt = true;
return;
} catch ( UnknownHostException uhe ){
allowInterrupt = true;
return;
} catch ( IOException ioe ) {
allowInterrupt = true;
return;
}
try {
reader = new BufferedInputStream(socket.getInputStream());
writer = new BufferedOutputStream(socket.getOutputStream());
input = new MyDataInputStream(reader);
output = new MyDataOutputStream(writer);
output.writeString("RequestTupleTypes("+numOfTuples+")\n");
output.flush();
String line = null;
while( (line = input.readLine()) != null){
tupletypes += line;
}
allowInterrupt = true;
} catch ( IOException ioe ){
Reporter.debug(ioe);
allowInterrupt = true;
}
}
/** Get the tupletypes */
public String getTupleTypes(){
return tupletypes;
}
public boolean canInterrupt(){
return allowInterrupt;
}
}
/**
* A helperclass to receive and display a tuplestream from the server
*/
private class TupleStreamReceiver extends Thread {
private Socket socket;
private MyDataInputStream input;
private MyDataOutputStream output;
private BufferedInputStream reader;
private BufferedOutputStream writer;
private String filter;
/** The constructor */
private TupleStreamReceiver(){
filter = new String();
}
public void setFilter(String filter){
this.filter = filter;
}
/** Starts the thread from outside */
public void startThread(){
tupletextarea.setText("");
start();
}
/** Interrupts the thread from outside */
public void stopThread(){
try {
writer.close();
reader.close();
output.close();
input.close();
socket.close();
} catch ( Exception e ){
Reporter.debug(e);
} finally {
interrupt();
connect = false;
showBtn.setText("receive tuplestream");
showBtn.setEnabled(true);
slider.setEnabled(true);
confirmBtn.setEnabled(true);
}
}
/** Serverconnection */
@Override
public void run(){
try {
socket = new Socket(hostname, streamport);
} catch ( ConnectException ce ){
Reporter.showInfo("Could not connect to\nServer '"+hostname+"'\nPort '"+streamport+"'");
interrupt();
return;
} catch ( UnknownHostException uhe ){
interrupt();
return;
} catch ( IOException ioe ) {
interrupt();
return;
}
try {
reader = new BufferedInputStream(socket.getInputStream());
writer = new BufferedOutputStream(socket.getOutputStream());
input = new MyDataInputStream(reader);
output = new MyDataOutputStream(writer);
connect = true;
showBtn.setText("stop tuplestream");
slider.setEnabled(false);
confirmBtn.setEnabled(false);
tupledescription = tupledescription.replace(")(",") ("); //
output.writeString("RequestStream("+tupledescription+","+filter+",false)\n");
output.flush();
String in = input.readLine();
if ( in.equals("ConfirmStream(OK)") ){
ArrayList<String> lastXTuples = new ArrayList<String>();
while ( !isInterrupted() ) {
in = input.readLine();
if ( in.equals(TUPLE_STREAM_PROTOCOL_MSG) ) {
stopThread();
return;
} else {
String extract = in.substring("TupleMessage".length(), in.length());
extract = formatter(extract);
showlastXTuples(lastXTuples, extract);
}
}
} else {
Reporter.showInfo("Protocol error : "+in);
}
} catch ( IOException ioe ){
Reporter.debug(ioe);
} finally {
stopThread();
}
}
/** shows the last X tuples, where X is the slidervalue */
private void showlastXTuples(ArrayList<String> last, String tuple){
if ( last.size() < slider.getValue() ){
last.add(tuple);
} else {
last.remove(0);
last.add(tuple);
}
tupletextarea.setText("");
for(int i = 0; i < last.size(); i++){
updateTupleTextArea(last.get(i)+"\n");
}
}
/** this function formattes the received tuples for
* the tupletextarea */
private String formatter(String tuplevalues){
StringBuilder sb = new StringBuilder();
sb.append(tuplevalues.substring(0, 1));
sb.append("\n\t");
tuplevalues = tuplevalues.substring(1, tuplevalues.length() - 1);
int start = -1;
int end = 0;
while(start != end){
start = end;
for(int i = start; i < tuplevalues.length(); i++){
if(Character.isDigit(tuplevalues.charAt(i))){
String number = numberOrBoolFormatter(tuplevalues, i);
if(number.isEmpty()){
return new String();
} else {
end = i + number.length() - 2;
sb.append(number+"\n\t");
break;
}
} else if (Character.isLetter(tuplevalues.charAt(i)) ){
String bool = numberOrBoolFormatter(tuplevalues, i);
if(bool.isEmpty()){
return new String();
} else if (bool.contains("true") || bool.contains("TRUE") ||
bool.contains("false") || bool.contains("FALSE") ){
end = i + bool.length() - 2;
sb.append(bool+"\n\t");
break;
}
} else if (tuplevalues.charAt(i) == '\"' ){
String s = stringFormatter(tuplevalues, i);
if(s.isEmpty()){
return new String();
} else {
end = i + s.length() - 2;
sb.append(s+"\n\t");
break;
}
} else if (tuplevalues.charAt(i) == '\'' ){
String t = textFormatter(tuplevalues, i);
if(t.isEmpty()){
return new String();
} else {
end = i + t.length() - 2;
sb.append(t+"\n\t");
break;
}
} else if (tuplevalues.charAt(i) == '(' ){
String nf = nestedFormatter(tuplevalues, i);
if(nf.isEmpty()){
return new String();
} else {
end = i + nf.length() - 2;
sb.append(nf+"\n\t");
break;
}
}
}
}
sb.deleteCharAt(sb.length() - 1);
sb.append(")");
return sb.toString();
}
private String stringFormatter(String tuplevalues, int start){
/* search for a string */
int end = 0;
for(int i = start + 1; i < tuplevalues.length(); i++){
if(tuplevalues.charAt(i) == '\"' ){
end = i + 1;
break;
} else if (i == tuplevalues.length() - 1){
end = i + 1;
break;
}
}
try {
String word = tuplevalues.substring(start, end);
word = word.replace(word, "("+word+")");
return word;
} catch ( StringIndexOutOfBoundsException e ){
return new String();
}
}
private String textFormatter(String tuplevalues, int start){
/* search for a text */
int end = 0;
for(int i = start + 1; i < tuplevalues.length(); i++){
if(tuplevalues.charAt(i) == '\'' ){
end = i + 1;
break;
} else if (i == tuplevalues.length() - 1){
end = i + 1;
break;
}
}
try {
String word = tuplevalues.substring(start, end);
word = word.replace(word, "("+word+")");
return word;
} catch ( StringIndexOutOfBoundsException e ){
return new String();
}
}
private String numberOrBoolFormatter(String tuplevalues, int start){
/* search for a numeric */
int end = 0;
for(int i = start; i < tuplevalues.length(); i++){
if(tuplevalues.charAt(i) == ' ' ){
end = i;
break;
} else if (i == tuplevalues.length() - 1){
end = i + 1;
break;
}
}
try {
String word = tuplevalues.substring(start, end);
word = word.replace(word, "("+word+")");
return word;
} catch ( StringIndexOutOfBoundsException e ){
return new String();
}
}
private String nestedFormatter(String tuplevalues, int start){
/* search for a nested form (vector or record) */
int end = 0;
int brackets = 1;
for(int i = start + 1; i < tuplevalues.length(); i++){
if( tuplevalues.charAt(i) == '(' ){
brackets++;
} else if( tuplevalues.charAt(i) == ')' ){
brackets--;
if( brackets == 0){
end = i + 1;
break;
} else {
continue;
}
} else if ( i == tuplevalues.length() - 1){
end = i + 1;
break;
}
}
try {
String word = tuplevalues.substring(start, end);
word = word.replace(word, "("+word+")");
return word;
} catch ( StringIndexOutOfBoundsException e ){
return new String();
}
}
}
}