All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.jsoar.debugger.PartialMatchesView Maven / Gradle / Ivy
/*
* Copyright (c) 2008 Dave Ray
*
* Created on Oct 23, 2008
*/
package org.jsoar.debugger;
import java.awt.BorderLayout;
import java.awt.Color;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import org.jsoar.debugger.selection.SelectionListener;
import org.jsoar.debugger.selection.SelectionManager;
import org.jsoar.debugger.syntax.Highlighter;
import org.jsoar.kernel.Production;
import org.jsoar.kernel.ProductionManager;
import org.jsoar.kernel.rete.PartialMatches;
import org.jsoar.kernel.rete.PartialMatches.Entry;
import org.jsoar.runtime.CompletionHandler;
import org.jsoar.runtime.ThreadedAgent;
import org.jsoar.util.adaptables.Adaptables;
/**
* @author ray
*/
public class PartialMatchesView extends AbstractAdaptableView implements SelectionListener, Refreshable
{
private final ThreadedAgent agent;
private final SelectionManager selectionManager;
private final Highlighter highlighter;
private JTextPane textArea = new JTextPane();
public PartialMatchesView(JSoarDebugger debugger)
{
super("partialmatches", "Partial Matches");
this.highlighter = Highlighter.getInstance(debugger);
this.agent = debugger.getAgent();
this.selectionManager = debugger.getSelectionManager();
JPanel p = new JPanel(new BorderLayout());
this.textArea.setEditable(false);
this.textArea.setContentType("text/html");
p.add(new JScrollPane(textArea), BorderLayout.CENTER);
getContentPane().add(p);
this.selectionManager.addListener(this);
selectionChanged(selectionManager);
}
/* (non-Javadoc)
* @see org.jsoar.debugger.selection.SelectionListener#selectionChanged(org.jsoar.debugger.selection.SelectionManager)
*/
@Override
public void selectionChanged(SelectionManager manager)
{
getMatchOutput(new ArrayList(manager.getSelection()));
}
/* (non-Javadoc)
* @see org.jsoar.debugger.Refreshable#refresh(boolean)
*/
@Override
public void refresh(boolean afterInitSoar)
{
getMatchOutput(new ArrayList(selectionManager.getSelection()));
}
/* (non-Javadoc)
* @see org.jsoar.debugger.AbstractAdaptableView#getShortcutKey()
*/
@Override
public String getShortcutKey()
{
return "ctrl M";
}
private void getMatchOutput(final List selection)
{
Color background = highlighter.getPatterns().getBackground();
Callable matchCall = () -> safeGetMatchOutput(selection, background);
CompletionHandler finish = result ->
{
if(result != null && result.length() != 0)
{
textArea.setText(result);
textArea.setCaretPosition(0);
}
};
agent.execute(matchCall, SwingCompletionHandler.newInstance(finish));
}
private Production getProduction(ProductionManager pm, Object o)
{
Production p = Adaptables.adapt(o, Production.class);
if(p != null)
{
return p;
}
return pm.getProduction(o.toString());
}
private String safeGetMatchOutput(List selection, Color background)
{
final StringBuilder b = new StringBuilder();
b.append("");
b.append("");
int count = 0;
for(Object o : selection)
{
final Production p = getProduction(agent.getProductions(), o);
if(p != null)
{
b.append("" + escape(p.getName()) + " ");
final PartialMatches pm = p.getPartialMatches();
final List entries = pm.getEntries();
if(entries.size() > 0)
{
formatEntries(b, entries, 0);
b.append(" ");
final Entry lastEntry = entries.get(entries.size() - 1);
final int total = lastEntry.matches;
b.append(String.format("%d complete match%s. ",
total > 0 ? "green" : "red",
total,
total != 1 ? "es" : ""));
}
else
{
b.append("No match info available ");
}
count++;
}
b.append(" ");
}
b.append("");
return count != 0 ? b.toString() : null;
}
private String escape(String s)
{
return s.replace("&", "&").replace("<", "<");
}
private void spaces(StringBuilder b, int level)
{
for(int i = 0; i < level; i++)
{
b.append(" ");
}
}
private void formatPositiveEntry(StringBuilder b, Entry e, Entry previous)
{
printEntryLeader(b, e, previous);
b.append("");
b.append("" + e.matches + " ");
b.append(escape(String.format("%s", e.condition)));
b.append(" ");
}
private void formatNegativeEntry(final StringBuilder b, Entry e, int level, Entry previous)
{
printEntryLeader(b, e, previous);
// how about ¬ ??
b.append("-{ ");
formatEntries(b, e.negatedSubConditions, level+1);
spaces(b, level);
b.append(" ");
b.append(String.format("} %d ", e.matches > 0 ? "green" : "red", e.matches));
}
private void printEntryLeader(StringBuilder b, Entry e, Entry previous)
{
final boolean firstNonMatch = e.matches == 0 && (previous == null || previous.matches > 0);
if(firstNonMatch)
{
b.append("" + escape(">> ") + " ");
}
else
{
b.append(" ");
}
}
private void formatEntries(final StringBuilder b, final List entries, int level)
{
b.append("");
Entry previous = null;
int processed = 0;
for(Entry e : entries)
{
spaces(b, level);
if(e.negatedSubConditions == null)
{
formatPositiveEntry(b, e, previous);
}
else
{
formatNegativeEntry(b, e, level, previous);
}
b.append(" ");
previous = e;
processed++;
// Only print up to the first non-match.
// TODO: make this configurable
if(e.matches == 0)
{
break;
}
}
if(processed != entries.size())
{
final int remaining = entries.size() - processed;
b.append(String.format(" ... %d more condition%s ... ", remaining, (remaining != 1 ? "s": "")));
}
b.append(" ");
}
}