/****************************************************************************** * * Copyright 2014 Paphus Solutions Inc. * * Licensed under the Eclipse Public License, Version 1.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.eclipse.org/legal/epl-v10.html * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ******************************************************************************/ package org.botlibre.client.gui; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.swing.AbstractAction; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JRadioButton; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JTree; import javax.swing.KeyStroke; import javax.swing.border.LineBorder; import javax.swing.event.TreeModelListener; import javax.swing.text.Keymap; import javax.swing.tree.TreeModel; import javax.swing.tree.TreePath; import org.botlibre.api.knowledge.Network; import org.botlibre.api.knowledge.Relationship; import org.botlibre.api.knowledge.Vertex; import org.botlibre.knowledge.Primitive; import org.botlibre.sense.context.Context; import org.botlibre.sense.context.Selector; public class ContextPanel extends ChildPanel { private static final long serialVersionUID = 1L; protected JTree treePane; protected JLabel selectedLabel; protected JTextArea selectedPane; protected JLabel relationshipLabel; protected JTextArea relationshipPane; protected JLabel filterLabel; protected JTextArea filterPane; protected JScrollPane scrollPane; protected JButton selectButton; protected JButton relationshipButton; protected JButton associateButton; protected JButton instantiateButton; protected JButton refreshButton; protected JButton deleteButton; protected JButton referencesButton; protected JRadioButton shortTermButton; protected JRadioButton longTermButton; protected Vertex selection; protected Vertex relationship; public class SelectAction implements ActionListener { public void actionPerformed(ActionEvent event) { if (treePane.getSelectionPath() == null) { return; } Object selected = treePane.getSelectionPath().getLastPathComponent(); if (selected instanceof Relationship) { selection = ((Relationship)selected).getTarget(); } else if (selected instanceof Vertex) { selection = (Vertex)selected; } if (selection != null) { selectedPane.setText(selection.toString()); getBot().awareness().getSense(Context.class.getName()).input(selection); } } } public class RelationshipAction implements ActionListener { public void actionPerformed(ActionEvent event) { if (treePane.getSelectionPath() == null) { return; } Object selected = treePane.getSelectionPath().getLastPathComponent(); if (selected instanceof Relationship) { relationship = ((Relationship)selected).getTarget(); } else if (selected instanceof Vertex) { relationship = (Vertex)selected; } if (relationship != null) { relationshipPane.setText(relationship.toString()); } } } public class DeleteAction implements ActionListener { public void actionPerformed(ActionEvent event) { if (treePane.getSelectionPath() == null) { return; } Object selected = treePane.getSelectionPath().getLastPathComponent(); if (selected instanceof Relationship) { Relationship relationship = (Relationship)selected; relationship.getSource().internalRemoveRelationship(relationship); } else if (selected instanceof Vertex) { Vertex vertex = (Vertex)selected; getSelectedNetwork().removeVertexAndReferences(vertex); } getBot().memory().save(); } } /** * Create a new vertex that is an instance of the current selection. */ public class InstantiateAction implements ActionListener { public void actionPerformed(ActionEvent event) { if (treePane.getSelectionPath() == null) { return; } Object selected = treePane.getSelectionPath().getLastPathComponent(); Vertex classification = null; if (selected instanceof Relationship) { classification = ((Relationship)selected).getTarget(); } else if (selected instanceof Vertex) { classification = (Vertex)selected; } if (classification != null) { Network network = getBot().memory().getShortTermMemory(); Vertex instance = network.createVertex(); Vertex instantiationType = network.createVertex(Primitive.INSTANTIATION); classification = network.createVertex(classification); instance.addRelationship(instantiationType, classification); selection = instance; selectedPane.setText(selection.toString()); getBot().memory().save(); getBot().awareness().getSense(Context.class.getName()).input(selection); } } } /** * Associate the selected vertex with the selected relationship, with the current selection as target. */ public class AssociateAction implements ActionListener { public void actionPerformed(ActionEvent event) { Object selected = treePane.getSelectionPath().getLastPathComponent(); Vertex target = null; if (selected instanceof Relationship) { target = ((Relationship)selected).getTarget(); } else if (selected instanceof Vertex) { target = (Vertex)selected; } if ((target != null) && (relationship != null) && (selection != null)) { Network network = getBot().memory().getShortTermMemory(); Vertex source = network.createVertex(selection); Vertex relationshipType = network.createVertex(relationship); target = network.createVertex(target); source.addRelationship(relationshipType, target); getBot().memory().save(); } } } public class RefreshAction extends AbstractAction implements ActionListener { private static final long serialVersionUID = 1L; public void actionPerformed(ActionEvent event) { getSelectedNetwork().clear(); resetState(); } } public class ReferencesAction extends AbstractAction implements ActionListener { private static final long serialVersionUID = 1L; public void actionPerformed(ActionEvent event) { if (treePane.getSelectionPath() == null) { return; } Object selected = treePane.getSelectionPath().getLastPathComponent(); if (!(selected instanceof Vertex)) { return; } long id = ((Vertex)selected).getId(); filterPane.setText("jpql: Select v from Vertex v join v.allRelationships r where r.target.id = " + id); resetState(); } } public class ShortTermAction implements ActionListener { public void actionPerformed(ActionEvent event) { shortTermButton.setSelected(true); longTermButton.setSelected(false); resetState(); } } public class LongTermAction implements ActionListener { public void actionPerformed(ActionEvent event) { longTermButton.setSelected(true); shortTermButton.setSelected(false); resetState(); } } public ContextPanel(BotPanel BotPanel) { super(BotPanel); } public Network getSelectedNetwork() { if (this.longTermButton.isSelected()) { return getBot().memory().getLongTermMemory(); } else { return getBot().memory().getShortTermMemory(); } } public void resetState() { TreeModel model = new TreeModel() { /** Stores list of root vertices. */ List<Vertex> vertices; /** Stores list of relationships per vertex. */ Map<Vertex, List<Relationship>> relationships = new HashMap<Vertex, List<Relationship>>(); @SuppressWarnings("unchecked") List<Vertex> getVertices() { if (this.vertices == null) { this.vertices = new ArrayList<Vertex>(); List<Vertex> result = null; String filter = filterPane.getText().trim(); if ((filter.length() > 5) && (filter.substring(0, 5).equals("jpql:"))) { result = getSelectedNetwork().findAllQuery(filter.substring(5, filter.length())); } else if (filter.length() > 0) { result = getSelectedNetwork().findAllLike(filter); } else { result = getSelectedNetwork().findAll(); } this.vertices.addAll(result); } return this.vertices; } List<Relationship> getRelationships(Vertex vertex) { List<Relationship> parentRelationships = this.relationships.get(vertex); if (parentRelationships == null) { parentRelationships = new ArrayList<Relationship>(); Iterator<Relationship> iterator = vertex.orderedAllRelationships(); while (iterator.hasNext()) { parentRelationships.add(iterator.next()); } this.relationships.put(vertex, parentRelationships); } return parentRelationships; } public Object getRoot() { return getBot().memory(); } public Object getChild(Object parent, int index) { Object child = null; if (parent == getBot().memory()) { child = getVertices().get(index); } else if (parent instanceof Relationship) { if (index == 0) { child = ((Relationship)parent).getType(); } else if (index == 1) { child = ((Relationship)parent).getTarget(); } else { child = ((Relationship)parent).getMeta(); } } else if (parent instanceof Vertex) { child = getRelationships((Vertex)parent).get(index); } return child; } public int getChildCount(Object parent) { int count = 0; if (parent == getBot().memory()) { count = getVertices().size(); } else if (parent instanceof Relationship) { if (((Relationship)parent).getMeta() != null) { count = 3; } else { count = 2; } } else if (parent instanceof Vertex) { count = getRelationships((Vertex)parent).size(); } return count; } public boolean isLeaf(Object node) { return false; } public void valueForPathChanged(TreePath path, Object newValue) { } public int getIndexOfChild(Object parent, Object child) { int index = -1; if (parent == getBot().memory()) { index = getVertices().indexOf(child); } else if (parent instanceof Relationship) { if (child == ((Relationship)parent).getType()) { index = 0; } else if (child == ((Relationship)parent).getTarget()) { index = 1; } else { index = 2; } } else if (parent instanceof Vertex) { index = getRelationships((Vertex)parent).indexOf(child); } return index; } public void addTreeModelListener(TreeModelListener l) { } public void removeTreeModelListener(TreeModelListener l) { } }; this.treePane.setModel(model); } public void initKeyMap(JTextArea text) { Keymap keyMap = JTextArea.addKeymap("EnterSubmit", text.getKeymap()); KeyStroke key = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0); keyMap.addActionForKeyStroke(key, new RefreshAction()); text.setKeymap(keyMap); } protected void buildContent() { setLayout(new GridBagLayout()); this.treePane = new JTree(); this.scrollPane = new JScrollPane(this.treePane, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); this.selectedPane = new JTextArea(); this.selectedPane.setEditable(false); this.selectedPane.setBorder(LineBorder.createGrayLineBorder()); this.selectedLabel = new JLabel(); this.selectedLabel.setText("Selection:"); this.relationshipPane = new JTextArea(); this.relationshipPane.setEditable(false); this.relationshipPane.setBorder(LineBorder.createGrayLineBorder()); this.relationshipLabel = new JLabel(); this.relationshipLabel.setText("Relationship:"); this.filterPane = new JTextArea(); initKeyMap(this.filterPane); this.filterPane.setBorder(LineBorder.createGrayLineBorder()); this.filterLabel = new JLabel(); this.filterLabel.setText("Filter:"); this.selectButton = new JButton("Select"); this.selectButton.addActionListener(new SelectAction()); this.relationshipButton = new JButton("Relationship"); this.relationshipButton.addActionListener(new RelationshipAction()); this.associateButton = new JButton("Associate"); this.associateButton.addActionListener(new AssociateAction()); this.instantiateButton = new JButton("Instantiate"); this.instantiateButton.addActionListener(new InstantiateAction()); this.refreshButton = new JButton("Refresh"); this.refreshButton.addActionListener(new RefreshAction()); this.referencesButton = new JButton("References"); this.referencesButton.addActionListener(new ReferencesAction()); this.deleteButton = new JButton("Delete"); this.deleteButton.addActionListener(new DeleteAction()); this.shortTermButton = new JRadioButton("Short Term"); this.shortTermButton.addActionListener(new ShortTermAction()); this.shortTermButton.setSelected(true); this.longTermButton = new JRadioButton("Long Term"); this.longTermButton.addActionListener(new LongTermAction()); add(this.scrollPane, new GridBagConstraints(0,0,2,10, 1.0,1.0, GridBagConstraints.CENTER,GridBagConstraints.BOTH, new Insets(4,4,4,4), 0,0)); add(this.selectedLabel, new GridBagConstraints(0,11,1,1, 0,0, GridBagConstraints.WEST,GridBagConstraints.NONE, new Insets(4,4,4,4), 0,0)); add(this.selectedPane, new GridBagConstraints(1,11,1,1, 1.0,0, GridBagConstraints.CENTER,GridBagConstraints.BOTH, new Insets(4,4,4,4), 0,0)); add(this.relationshipLabel, new GridBagConstraints(0,12,1,1, 0,0, GridBagConstraints.WEST,GridBagConstraints.NONE, new Insets(4,4,4,4), 0,0)); add(this.relationshipPane, new GridBagConstraints(1,12,1,1, 1.0,0, GridBagConstraints.CENTER,GridBagConstraints.BOTH, new Insets(4,4,4,4), 0,0)); add(this.filterLabel, new GridBagConstraints(0,13,1,1, 0,0, GridBagConstraints.WEST,GridBagConstraints.NONE, new Insets(4,4,4,4), 0,0)); add(this.filterPane, new GridBagConstraints(1,13,1,1, 1.0,0, GridBagConstraints.CENTER,GridBagConstraints.BOTH, new Insets(4,4,4,4), 0,0)); add(this.shortTermButton, new GridBagConstraints(2,0,1,1, 0.0,0.0, GridBagConstraints.CENTER,GridBagConstraints.BOTH, new Insets(4,4,4,4), 0,0)); add(this.longTermButton, new GridBagConstraints(2,1,1,1, 0.0,0.0, GridBagConstraints.CENTER,GridBagConstraints.BOTH, new Insets(4,4,4,4), 0,0)); add(this.refreshButton, new GridBagConstraints(2,2,1,1, 0.0,0.0, GridBagConstraints.CENTER,GridBagConstraints.BOTH, new Insets(4,4,4,4), 0,0)); add(this.referencesButton, new GridBagConstraints(2,3,1,1, 0.0,0.0, GridBagConstraints.CENTER,GridBagConstraints.BOTH, new Insets(4,4,4,4), 0,0)); add(this.selectButton, new GridBagConstraints(2,4,1,1, 0.0,0.0, GridBagConstraints.CENTER,GridBagConstraints.BOTH, new Insets(4,4,4,4), 0,0)); add(this.relationshipButton, new GridBagConstraints(2,5,1,1, 0.0,0.0, GridBagConstraints.CENTER,GridBagConstraints.BOTH, new Insets(4,4,4,4), 0,0)); add(this.associateButton, new GridBagConstraints(2,6,1,1, 0.0,0.0, GridBagConstraints.CENTER,GridBagConstraints.BOTH, new Insets(4,4,4,4), 0,0)); add(this.instantiateButton, new GridBagConstraints(2,7,1,1, 0.0,0.0, GridBagConstraints.CENTER,GridBagConstraints.BOTH, new Insets(4,4,4,4), 0,0)); add(this.deleteButton, new GridBagConstraints(2,8,1,1, 0.0,0.0, GridBagConstraints.CENTER,GridBagConstraints.BOTH, new Insets(4,4,4,4), 0,0)); resetBotInstance(); } /** * Reset any state specific to the Bot instance when changed. */ public void resetBotInstance() { Context sense = (Context)getBot().awareness().getSense(Context.class.getName()); sense.setSelector(new Selector() { public Object getSelection() { return selection; } public void setSelection(Object selection) { } }); resetState(); } }