![JAR search and dependency download from the Maven repository](/logo.png)
it.unibz.inf.ontop.protege.utils.QueryPainter Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ontop-protege Show documentation
Show all versions of ontop-protege Show documentation
Ontop OBDA plugin for protégé
package it.unibz.inf.ontop.protege.utils;
/*
* #%L
* ontop-protege4
* %%
* Copyright (C) 2009 - 2013 KRDB Research Centre. Free University of Bozen Bolzano.
* %%
* Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
*
* 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.
* #L%
*/
import it.unibz.inf.ontop.io.PrefixManager;
import it.unibz.inf.ontop.io.TargetQueryVocabularyValidator;
import it.unibz.inf.ontop.model.*;
import it.unibz.inf.ontop.parser.TargetQueryParserException;
import it.unibz.inf.ontop.parser.TurtleOBDASyntaxParser;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.LinkedList;
import java.util.List;
import java.util.Vector;
public class QueryPainter {
private final OBDAModel apic;
private SimpleAttributeSet black;
private SimpleAttributeSet brackets;
private SimpleAttributeSet dataProp;
private SimpleAttributeSet objectProp;
private SimpleAttributeSet annotProp;
private SimpleAttributeSet clazz;
private SimpleAttributeSet individual;
private Style invalidQuery;
private Border defaultBorder;
private Border outerBorder;
private Border stateBorder;
private Border errorBorder;
private Timer timer;
private TargetQueryParserException parsingException;
private TargetQueryVocabularyValidator validator;
private boolean invalid = false;
private static final Color INVALID = Color.RED;
private static final int DEFAULT_TOOL_TIP_INITIAL_DELAY = ToolTipManager.sharedInstance().getInitialDelay();
private static final int DEFAULT_TOOL_TIP_DISMISS_DELAY = ToolTipManager.sharedInstance().getDismissDelay();
private static final int ERROR_TOOL_TIP_INITIAL_DELAY = 100;
private static final int ERROR_TOOL_TIP_DISMISS_DELAY = 9000;
private Font plainFont;
private Style plainStyle;
private Style boldStyle;
private Style nonBoldStyle;
private Style foreground;
private Style fontSizeStyle;
private StyledDocument doc = null;
private JTextPane parent = null;
private Vector tasks = new Vector();
private List validatorListeners = new LinkedList();
private TurtleOBDASyntaxParser textParser;
public QueryPainter(OBDAModel apic, JTextPane parent, TargetQueryVocabularyValidator validator) {
this.apic = apic;
this.parent = parent;
this.validator = validator;
this.doc = parent.getStyledDocument();
this.parent = parent;
this.textParser = new TurtleOBDASyntaxParser(apic.getPrefixManager());
prepareStyles();
prepareTextPane();
prepareTimer();
prepareBorder();
}
private void prepareBorder() {
outerBorder = null;
defaultBorder = BorderFactory.createMatteBorder(1, 1, 1, 1, Color.LIGHT_GRAY);
errorBorder = BorderFactory.createMatteBorder(2, 2, 2, 2, Color.RED);
setStateBorder(defaultBorder);
}
private void prepareTimer() {
timer = new Timer(200, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
handleTimer();
}
});
}
public void addValidatorListener(ValidatorListener listener) {
validatorListeners.add(listener);
}
public void removeValidatorListener(ValidatorListener listener) {
validatorListeners.remove(listener);
}
private void fireValidationOcurred() {
for (ValidatorListener listener : validatorListeners) {
listener.validated(!invalid);
}
}
public interface ValidatorListener {
/**
* Called when the validator has just validated. Takes as input the
* result of the validation.
*/
public void validated(boolean result);
}
private void handleDocumentUpdated() {
timer.restart();
clearError();
}
private void handleTimer() {
timer.stop();
checkExpression();
if (!invalid) {
try {
recolorQuery();
} catch (Exception e) {
}
}
}
/***
* Checks if the query is valid. If so, notifies listeners that the query
* has been validated.
*
* @throws Exception
*/
private void validate() throws Exception {
final String text = parent.getText().trim();
if (text.isEmpty() || text.length() == 1) {
String msg = String.format("Empty query");
invalid = true;
throw new Exception(msg);
}
List query = textParser.parse(text);
if (query == null) {
invalid = true;
throw parsingException;
}
if (!validator.validate(query)) {
List invalidPredicates = validator.getInvalidPredicates();
String invalidList = "";
for (String predicate : invalidPredicates) {
invalidList += "- " + predicate + "\n";
}
String msg = String.format("ERROR: The below list of predicates is unknown by the ontology: \n %s", invalidList);
invalid = true;
throw new Exception(msg);
}
invalid = false;
}
protected void checkExpression() {
try {
// Parse the text in the editor. If no parse
// exception is thrown, clear the error, otherwise
// set the error
validate();
invalid = false;
setError(null);
} catch (Exception e) {
invalid = true;
setError(e);
} finally {
fireValidationOcurred();
}
}
private void setError(Exception e) {
if (e != null) {
ToolTipManager.sharedInstance().setInitialDelay(ERROR_TOOL_TIP_INITIAL_DELAY);
ToolTipManager.sharedInstance().setDismissDelay(ERROR_TOOL_TIP_DISMISS_DELAY);
if (e instanceof IllegalArgumentException) {
parent.setToolTipText("Syntax error");
}
else {
Throwable cause = e.getCause();
String errorstring = null;
if(cause!=null) {
errorstring = cause.getMessage();
}
else {
errorstring = e.getMessage();
}
if(errorstring != null) {
int index = errorstring.indexOf("Location: line");
if (index != -1) {
String location = errorstring.substring(index + 15);
int prefixlines = apic.getPrefixManager().getPrefixMap().keySet().size();
String[] coordinates = location.split(":");
int errorline = Integer.valueOf(coordinates[0]) - prefixlines;
int errorcol = Integer.valueOf(coordinates[1]);
errorstring = errorstring.replace(errorstring.substring(index), "Location: line " + errorline + " column " + errorcol);
}
parent.setToolTipText(getHTMLErrorMessage(errorstring));
}
}
setStateBorder(errorBorder);
} else {
clearError();
}
}
private static String getHTMLErrorMessage(String msg) {
if (msg != null) {
String html = "";
msg = msg.replace("\n", "
");
msg = msg.replace("\t", " ");
html += msg;
html += "";
return html;
}
return null;
}
private void clearError() {
parent.setToolTipText(null);
setStateBorder(defaultBorder);
ToolTipManager.sharedInstance().setInitialDelay(DEFAULT_TOOL_TIP_INITIAL_DELAY);
ToolTipManager.sharedInstance().setDismissDelay(DEFAULT_TOOL_TIP_DISMISS_DELAY);
}
public void setStateBorder(Border border) {
stateBorder = border;
this.parent.setBorder(BorderFactory.createCompoundBorder(outerBorder, stateBorder));
}
private void prepareStyles() {
StyledDocument doc = parent.getStyledDocument();
plainStyle = doc.addStyle("PLAIN_STYLE", null);
StyleConstants.setItalic(plainStyle, false);
boldStyle = doc.addStyle("BOLD_STYLE", null);
StyleConstants.setBold(boldStyle, true);
nonBoldStyle = doc.addStyle("NON_BOLD_STYLE", null);
StyleConstants.setBold(nonBoldStyle, false);
fontSizeStyle = doc.addStyle("FONT_SIZE", null);
StyleConstants.setFontSize(fontSizeStyle, 40);
invalidQuery = doc.addStyle("INVALID_STYLE", null);
StyleConstants.setForeground(invalidQuery, INVALID);
foreground = doc.addStyle("FOREGROUND", null);
StyleConstants.setForeground(foreground, Color.black);
black = new SimpleAttributeSet();
black.addAttribute(StyleConstants.CharacterConstants.Foreground, Color.black);
brackets = new SimpleAttributeSet();
brackets.addAttribute(StyleConstants.CharacterConstants.Foreground, Color.BLACK);
annotProp = new SimpleAttributeSet();
Color c_dp = new Color(109, 159, 162);
annotProp.addAttribute(StyleConstants.CharacterConstants.Foreground, c_dp);
annotProp.addAttribute(StyleConstants.CharacterConstants.Bold, true);
dataProp = new SimpleAttributeSet();
Color c_ap = new Color(41, 167, 121);
dataProp.addAttribute(StyleConstants.CharacterConstants.Foreground, c_ap);
dataProp.addAttribute(StyleConstants.CharacterConstants.Bold, true);
objectProp = new SimpleAttributeSet();
Color c_op = new Color(41, 119, 167);
objectProp.addAttribute(StyleConstants.CharacterConstants.Foreground, c_op);
objectProp.addAttribute(StyleConstants.CharacterConstants.Bold, true);
clazz = new SimpleAttributeSet();
Color c_clazz = new Color(199, 155, 41);
clazz.addAttribute(StyleConstants.CharacterConstants.Foreground, c_clazz);
clazz.addAttribute(StyleConstants.CharacterConstants.Bold, true);
individual = new SimpleAttributeSet();
Color c_individual = new Color(83, 24, 82);
individual.addAttribute(StyleConstants.CharacterConstants.Foreground, c_individual);
individual.addAttribute(StyleConstants.CharacterConstants.Bold, true);
}
private void resetStyles() {
setupFont();
StyleConstants.setFontSize(fontSizeStyle, getFontSize());
StyleConstants.setFontFamily(fontSizeStyle, plainFont.getFamily());
StyleConstants.setForeground(fontSizeStyle, Color.black);
fontSizeStyle.addAttribute(StyleConstants.CharacterConstants.Foreground, Color.black);
doc.setParagraphAttributes(0, doc.getLength(), fontSizeStyle, true);
}
private void prepareTextPane() {
resetStyles();
parent.setBorder(null);
parent.getStyledDocument().addDocumentListener(
new DocumentListener() {
@Override public void insertUpdate(DocumentEvent e) { handleDocumentUpdated(); }
@Override public void removeUpdate(DocumentEvent e) { handleDocumentUpdated(); }
@Override public void changedUpdate(DocumentEvent e) { /* NO-OP */ }
}
);
}
private void setupFont() {
plainFont = new Font("Lucida Grande", Font.PLAIN, 14);
parent.setFont(plainFont);
}
private int getFontSize() {
return 14;
}
/***
* Performs coloring of the textpane. This method needs to be rewriten.
*
* @throws Exception
*/
public void recolorQuery() throws Exception {
PrefixManager man = apic.getPrefixManager();
String input = doc.getText(0, doc.getLength());
List current_query = parse(input);
if (current_query == null) {
JOptionPane.showMessageDialog(null, "An error occured while parsing the mappings. For more info, see the logs.");
throw new Exception("Unable to parse the query: " + input + ", " + parsingException);
}
input = doc.getText(0, doc.getLength());
resetStyles();
int pos = input.indexOf("(", 0);
while (pos != -1) {
doc.setCharacterAttributes(pos, 1, brackets, false);
pos = input.indexOf("(", pos + 1);
}
pos = input.indexOf(")", 0);
while (pos != -1) {
doc.setCharacterAttributes(pos, 1, brackets, false);
pos = input.indexOf(")", pos + 1);
}
pos = input.indexOf(".", 0);
while (pos != -1) {
doc.setCharacterAttributes(pos, 1, black, false);
pos = input.indexOf(".", pos + 1);
}
pos = input.indexOf(",", 0);
while (pos != -1) {
doc.setCharacterAttributes(pos, 1, black, false);
pos = input.indexOf(",", pos + 1);
}
pos = input.indexOf(":", 0);
while (pos != -1) {
doc.setCharacterAttributes(pos, 1, black, false);
pos = input.indexOf(":", pos + 1);
}
for (Function atom : current_query) {
Predicate predicate = atom.getFunctionSymbol();
String predicateName = man.getShortForm(atom.getFunctionSymbol().toString());
if (validator.isClass(predicate)) {
ColorTask task = new ColorTask(predicateName, clazz);
tasks.add(task);
} else if (validator.isObjectProperty(predicate)) {
ColorTask task = new ColorTask(predicateName, objectProp);
tasks.add(task);
} else if (validator.isDataProperty(predicate)) {
ColorTask task = new ColorTask(predicateName, dataProp);
tasks.add(task);
} else if (validator.isAnnotationProperty(predicate)) {
ColorTask task = new ColorTask(predicateName, annotProp);
tasks.add(task);
}
Term term1 = null;
Term term2 = null;
term1 = atom.getTerm(0);
if (atom.getArity() == 2) {
term2 = atom.getTerm(1);
}
if (term1 instanceof URIConstant) {
String rendered = man.getShortForm(((URIConstant) term1).getURI().toString());
ColorTask task = new ColorTask(rendered, individual);
tasks.add(task);
}
if (term2 instanceof URIConstant) {
String rendered = man.getShortForm(((URIConstant) term2).getURI().toString());
ColorTask task = new ColorTask(rendered, individual);
tasks.add(task);
}
}
ColorTask[] taskArray = order(tasks);
for (int i = 0; i < taskArray.length; i++) {
if (taskArray[i].text != null) {
int index = input.indexOf(taskArray[i].text, 0);
while (index != -1) {
doc.setCharacterAttributes(index, taskArray[i].text.length(), taskArray[i].set, true);
index = input.indexOf(taskArray[i].text, index + 1);
}
}
}
tasks.clear();
}
private List parse(String query) {
try {
return textParser.parse(query);
} catch (TargetQueryParserException e) {
parsingException = e;
return null;
} catch (Exception e) {
return null;
}
}
private ColorTask[] order(Vector v) {
ColorTask[] s = new ColorTask[v.size()];
ColorTask[] result = v.toArray(s);
for (int i = 1; i < result.length; i++) {
int j = i;
ColorTask str = result[i];
int B = result[i].text.length();
while ((j > 0) && (result[j - 1].text != null) && (result[j - 1].text.length() > B)) {
result[j] = result[j - 1];
j--;
}
result[j] = str;
}
return result;
}
public boolean isValidQuery() {
return !invalid;
}
class ColorTask {
public String text = null;
public SimpleAttributeSet set = null;
public ColorTask(String s, SimpleAttributeSet sas) {
text = s;
set = sas;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy