Files
secondo/Javagui/viewer/NestedRelationViewer.java

305 lines
9.4 KiB
Java
Raw Permalink Normal View History

2026-01-23 17:03:45 +08:00
//This file is part of SECONDO.
//Copyright (C) 2004, University in Hagen, Department of Computer Science,
//Database Systems for New Applications.
//SECONDO is free software; you can redistribute it and/or modify
//it under the terms of the GNU General Public License as published by
//the Free Software Foundation; either version 2 of the License, or
//(at your option) any later version.
//SECONDO is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//GNU General Public License for more details.
//You should have received a copy of the GNU General Public License
//along with SECONDO; if not, write to the Free Software
//Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package viewer;
import javax.swing.*;
import java.util.Vector;
import java.awt.*;
import java.awt.event.*;
import java.security.spec.EllipticCurve;
import gui.SecondoObject;
import sj.lang.*;
/* this viewer shows nested relations and attribute relations */
public class NestedRelationViewer extends StandardViewer {
private static final int INDENT_BY = 4;
private JScrollPane ScrollPane = new JScrollPane();
private JTextArea TextArea = new JTextArea();
private JComboBox ComboBox = new JComboBox();
private Vector ItemObjects = new Vector(10, 5);
private MenuVector menuVector = new MenuVector();
private SecondoObject CurrentObject = null;
/* create a new StandardViewer */
public NestedRelationViewer() {
add(BorderLayout.NORTH, ComboBox);
add(BorderLayout.CENTER, ScrollPane);
ScrollPane.setViewportView(TextArea);
Font font = TextArea.getFont(); // Keep text size at default value
TextArea.setFont(new Font("monospaced", Font.PLAIN, font.getSize()));
JMenu StdMenu = new JMenu("NestedRelation-Viewer");
JMenuItem MI_Remove = StdMenu.add("Discard current view");
JMenuItem MI_RemoveAll = StdMenu.add("Discard all views");
menuVector.addMenu(StdMenu);
MI_Remove.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (CurrentObject != null) {
SecondoObject selectedObject = CurrentObject;
if (ItemObjects.remove(CurrentObject)) {
ComboBox.removeItem(CurrentObject.getName());
CurrentObject = null;
int index = ComboBox.getSelectedIndex(); // the new current object
if (index >= 0) {
CurrentObject = (SecondoObject) ItemObjects.get(index);
showObject();
}
}
if (VC != null)
VC.removeObject(selectedObject); // inform the ViewerControl
}
}
});
MI_RemoveAll.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
ItemObjects.removeAllElements();
ComboBox.removeAllItems();
CurrentObject = null;
if (VC != null)
VC.removeObject(null);
showObject();
}
});
ComboBox.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
showObject();
if (VC != null) {
int index = ComboBox.getSelectedIndex();
if (index >= 0) {
try {
CurrentObject = (SecondoObject) ItemObjects.get(index);
VC.selectObject(NestedRelationViewer.this, CurrentObject);
} catch (Exception e) {
}
}
}
}
});
}
/* adds a new Object to this Viewer and display it */
public boolean addObject(SecondoObject o) {
if (isDisplayed(o))
selectObject(o);
else {
ItemObjects.add(o);
ComboBox.addItem(o.getName());
try {
ComboBox.setSelectedIndex(ComboBox.getItemCount() - 1); // make the new object to active object
showObject();
} catch (Exception e) {
}
}
return true;
}
/* returns true if o a SecondoObject in this viewer */
public boolean isDisplayed(SecondoObject o) {
return ItemObjects.indexOf(o) >= 0;
}
/** remove o from this Viewer */
public void removeObject(SecondoObject o) {
if (ItemObjects.remove(o))
ComboBox.removeItem(o.getName());
}
/** remove all containing objects */
public void removeAll() {
ItemObjects.removeAllElements();
ComboBox.removeAllItems();
CurrentObject = null;
if (VC != null)
VC.removeObject(null);
showObject();
}
/* returns allways true (this viewer can display all SecondoObjects) */
public boolean canDisplay(SecondoObject o) {
boolean result = false;
ListExpr type = o.toListExpr().first();
try {
String shortType = getShortType(type);
result = (shortType.equals("arel2") || shortType.equals("nrel2"));
}
catch(Exception e)
{
JOptionPane.showMessageDialog(this, e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
}
return result;
}
/* returns the Menuextension of this viewer */
public MenuVector getMenuVector() {
return menuVector;
}
/* returns Standard */
public String getName() {
return "NestedRelation";
}
/* select O */
public boolean selectObject(SecondoObject O) {
int i = ItemObjects.indexOf(O);
if (i >= 0) {
ComboBox.setSelectedIndex(i);
showObject();
return true;
} else //object not found
return false;
}
private void showObject() {
TextArea.setText("");
int index = ComboBox.getSelectedIndex();
if (index >= 0) {
try {
CurrentObject = (SecondoObject) ItemObjects.get(index);
ListExpr type = CurrentObject.toListExpr().first();
ListExpr value = CurrentObject.toListExpr().second();
String relation = DisplayRelation(type, value);
TextArea.setText(relation);
} catch (Exception e) {
TextArea.setText(e.getMessage());
}
}
}
private static final int getBaseIndentation(ListExpr type) {
int result = 0;
String attrName;
String shortType;
while (!type.isEmpty()) {
ListExpr current = type.first();
attrName = current.first().symbolValue();
shortType = getShortType(current.second());
result = (attrName.length() > result) ? attrName.length() : result;
if ((shortType == "arel2") || (shortType == "nrel2")) {
int len = getBaseIndentation(current.second().second().second()) - 4;
result = (len > result) ? len : result;
}
type = type.rest();
}
return result;
}
private static final String getShortType(ListExpr attrType) {
String result = "";
if (!attrType.isEmpty()) {
if (attrType.isAtom()) {
if (attrType.atomType() == ListExpr.SYMBOL_ATOM) {
result = attrType.symbolValue();
}
} else {
attrType = attrType.first();
if (attrType.isAtom()) {
if (attrType.atomType() == ListExpr.SYMBOL_ATOM) {
result = attrType.symbolValue();
}
}
}
}
return result;
}
private static String DisplayRelation(ListExpr type, ListExpr value) {
StringBuilder output = new StringBuilder(type.writeListExprToString());
output.append("\n\n ======= \n\n");
DisplayRelation(type, value, 0, output);
return output.toString();
}
private static void DisplayRelation(ListExpr type, ListExpr value, int indentation, StringBuilder output) {
ListExpr attrDescs = type.second().second();
if (indentation == 0) {
indentation = getBaseIndentation(attrDescs);
}
if (!value.isAtom()) {
output.append('\n');
while (!value.isEmpty()) {
ListExpr currentTuple = value.first();
try {
DisplayTuple(attrDescs, currentTuple, indentation, output);
} catch(Exception e)
{
output.append("<<< Broken tuple >>>\n");
}
value = value.rest();
}
} else {
value.writeListExprToString();
}
}
private static void DisplayTuple(ListExpr attrDescs, ListExpr value,
int indentation, StringBuilder output) {
while (!attrDescs.isEmpty())
{
ListExpr currentAttrDesc = attrDescs.first();
ListExpr currentValue = value.first();
String attrName = currentAttrDesc.first().symbolValue();
ListExpr currentAttrType = currentAttrDesc.second();
String attrShortType = getShortType(currentAttrType);
for(int i = 0; i < indentation - attrName.length(); i++) {
output.append(' ');
}
output.append(attrName);
output.append(" : ");
if (attrShortType.equals("arel2") || attrShortType.equals("nrel2"))
{
DisplayRelation(currentAttrType, currentValue,
indentation + INDENT_BY, output);
}
else
{
try
{
String attrValue = currentValue.writeListExprToString();
if (attrValue.length()>=1 && attrValue.startsWith("\n"))
{
attrValue = attrValue.substring(1);
}
output.append(attrValue);
}
catch(Exception e)
{
output.append("<<< Broken attribute value >>>");
}
}
output.append("\n");
attrDescs = attrDescs.rest();
value = value.rest();
}
//Print an empty line after each tuple to group attributes of one tuple
//together visually
output.append("\n");
}
}