001 // This file is part of the Attempto Java Packages. 002 // Copyright 2008-2009, Attempto Group, University of Zurich (see http://attempto.ifi.uzh.ch). 003 // 004 // The Attempto Java Packages is free software: you can redistribute it and/or modify it under the 005 // terms of the GNU Lesser General Public License as published by the Free Software Foundation, 006 // either version 3 of the License, or (at your option) any later version. 007 // 008 // The Attempto Java Packages is distributed in the hope that it will be useful, but WITHOUT ANY 009 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 010 // PURPOSE. See the GNU Lesser General Public License for more details. 011 // 012 // You should have received a copy of the GNU Lesser General Public License along with the Attempto 013 // Java Packages. If not, see http://www.gnu.org/licenses/. 014 015 package ch.uzh.ifi.attempto.acewiki.gui.editor; 016 017 import java.util.ArrayList; 018 import java.util.List; 019 020 import nextapp.echo2.app.event.ActionEvent; 021 import nextapp.echo2.app.event.ActionListener; 022 import ch.uzh.ifi.attempto.acewiki.Task; 023 import ch.uzh.ifi.attempto.acewiki.Wiki; 024 import ch.uzh.ifi.attempto.acewiki.core.ontology.OntologyElement; 025 import ch.uzh.ifi.attempto.acewiki.core.ontology.Sentence; 026 import ch.uzh.ifi.attempto.acewiki.core.ontology.Statement; 027 import ch.uzh.ifi.attempto.acewiki.gui.page.ArticlePage; 028 import ch.uzh.ifi.attempto.echocomp.MessageWindow; 029 import ch.uzh.ifi.attempto.preditor.PreditorWindow; 030 import ch.uzh.ifi.attempto.preditor.text.TextContainer; 031 import ch.uzh.ifi.attempto.preditor.text.TextElement; 032 033 /** 034 * This class manages the predictive editor. It creates the editor window and handles its 035 * responses. 036 * 037 * @author Tobias Kuhn 038 */ 039 public class SentenceEditorHandler implements ActionListener { 040 041 private static final long serialVersionUID = -2083910385095284075L; 042 043 private PreditorWindow editorWindow; 044 private MessageWindow messageWindow; 045 private ArticlePage page; 046 private Wiki wiki; 047 private boolean edit; 048 private Statement statement; 049 private List<Sentence> newSentences = new ArrayList<Sentence>(); 050 private int checked = 0; 051 052 private SentenceEditorHandler(Statement statement, ArticlePage page, boolean edit) { 053 this.page = page; 054 this.wiki = page.getWiki(); 055 this.edit = edit; 056 this.statement = statement; 057 AceWikiMenuCreator menuCreator = new AceWikiMenuCreator(wiki, page.getOntologyElement(), this); 058 editorWindow = new PreditorWindow("Sentence Editor", wiki.getGrammar(), menuCreator); 059 editorWindow.setLogger(wiki.getLogger()); 060 editorWindow.addActionListener(this); 061 editorWindow.setContextChecker(Sentence.contextChecker); 062 063 if (edit) { 064 String t = ((Sentence) statement).getPrettyText(); 065 // remove the last element (i.e. the period '.' or question mark '?'): 066 editorWindow.addText(t.substring(0, t.length()-1) + " "); 067 } 068 } 069 070 /** 071 * Generates a new preditive editor (short "preditor") window to create a new sentence. 072 * 073 * @param followingStatement The statement in front of which the new sentences should be added, 074 * or null if the sentences should be added to the end of the article. 075 * @param page The host page into which the sentence should be added. 076 * @return A new preditor window. 077 */ 078 public static PreditorWindow generatePreditorAddWindow(Statement followingStatement, ArticlePage page) { 079 SentenceEditorHandler h = new SentenceEditorHandler(followingStatement, page, false); 080 return h.getPreditorWindow(); 081 } 082 083 /** 084 * Generates a new preditive editor (short "preditor") window to create a new sentence. 085 * 086 * @param sentence The sentence that should be edited. 087 * @param page The host page which contains the sentence to be edited. 088 * @return A new preditor window. 089 */ 090 public static PreditorWindow generatePreditorEditWindow(Sentence sentence, ArticlePage page) { 091 SentenceEditorHandler h = new SentenceEditorHandler(sentence, page, true); 092 return h.getPreditorWindow(); 093 } 094 095 private PreditorWindow getPreditorWindow() { 096 return editorWindow; 097 } 098 099 public void actionPerformed(ActionEvent e) { 100 if (e.getSource() == editorWindow && e.getActionCommand().equals("OK")) { 101 TextContainer textContainer = editorWindow.getTextContainer(); 102 103 ArrayList<TextElement> finalElements = editorWindow.getPossibleNextTokens(".", "?"); 104 if (!finalElements.isEmpty()) textContainer.addElement(finalElements.get(0)); 105 106 ArrayList<TextElement> l = textContainer.getTextElements(); 107 if (l.isEmpty() || l.get(l.size() - 1).getText().matches("[.?]")) { 108 newSentences = Sentence.generateSentences(textContainer, page.getOntologyElement()); 109 checkSentence(); 110 } else { 111 wiki.log("edit", "error: unfinished sentences"); 112 MessageWindow mw = new MessageWindow("Error", "There are unfinished sentences.", editorWindow, "OK"); 113 page.getWiki().showWindow(mw); 114 } 115 } else if (e.getSource() == editorWindow && e.getActionCommand().equals("Cancel")) { 116 editorWindow.setVisible(false); 117 editorWindow.dispose(); 118 } else if (e.getSource() == messageWindow && e.getActionCommand().equals("a ...")) { 119 checked++; 120 checkSentence(); 121 } else if (e.getSource() == messageWindow && e.getActionCommand().equals("every ...")) { 122 String text = newSentences.get(checked).getText(); 123 text = text.replaceFirst("^(A|a)n? ", "Every "); 124 newSentences.remove(checked); 125 newSentences.add(checked, new Sentence(text, page.getOntologyElement())); 126 checked++; 127 checkSentence(); 128 } else if (e.getSource() == messageWindow && e.getActionCommand().equals("Close")) { 129 checked = 0; 130 } else if (e.getSource() instanceof TextElement) { 131 editorWindow.addTextElement((TextElement) e.getSource()); 132 } 133 } 134 135 private void checkSentence() { 136 if (checked >= newSentences.size()) { 137 assertSentences(); 138 } else { 139 List<TextElement> t = newSentences.get(checked).getTextElements(); 140 String t0 = t.get(0).getText(); 141 String t1 = t.get(1).getText(); 142 String l = t.get(t.size()-1).getText(); 143 if (t0.matches("(A|a)n?") && !t1.matches(".* of") && l.equals(".")) { 144 String s = t.get(1).getText(); 145 messageWindow = new MessageWindow( 146 "Warning", 147 "Your sentence \"a " + s + " ...\" is interpreted as \"there is a " + s + " that ...\". " + 148 "Do you want to say \"every " + s + " ...\"?", 149 editorWindow, 150 this, 151 "a ...", "every ..." 152 ); 153 wiki.showWindow(messageWindow); 154 } else { 155 checked++; 156 checkSentence(); 157 } 158 } 159 } 160 161 private void assertSentences() { 162 final TextContainer textContainer = editorWindow.getTextContainer(); 163 final OntologyElement el = page.getOntologyElement(); 164 165 Task task = new Task() { 166 167 int success; 168 169 public void run() { 170 if (edit) { 171 wiki.log("edit", "sentence updated: " + textContainer.getText()); 172 success = el.edit(statement, new ArrayList<Statement>(newSentences)); 173 } else { 174 wiki.log("edit", "sentence created: " + textContainer.getText()); 175 success = el.add(statement, new ArrayList<Statement>(newSentences)); 176 } 177 } 178 179 public void updateGUI() { 180 page.update(); 181 if (success == 1) { 182 wiki.showWindow( 183 new MessageWindow( 184 "Conflict", 185 "A sentence is in conflict with the current knowledge. For that reason, " + 186 "it cannot be added to the knowledge base.", 187 "OK" 188 ) 189 ); 190 } else if (success == 2) { 191 wiki.showWindow( 192 new MessageWindow( 193 "Error", 194 "A sentence could not be added to the knowledge base because the knowledge " + 195 "base got too complex.", 196 "OK" 197 ) 198 ); 199 } 200 if (page != null) { 201 page.update(); 202 page.getWiki().update(); 203 } 204 } 205 206 }; 207 208 if (edit) { 209 wiki.enqueueAsyncTask("Updating", "The knowledge base is being updated...", task); 210 } else { 211 wiki.enqueueAsyncTask("Updating", "The sentence is being added to the knowledge base...", task); 212 } 213 214 editorWindow.setVisible(false); 215 } 216 217 }