Java tutorial
/* * Zettelkasten - nach Luhmann ** Copyright (C) 2001-2014 by Daniel Ldecke (http://www.danielluedecke.de) * * Homepage: http://zettelkasten.danielluedecke.de * * * This program 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 3 of * the License, or (at your option) any later version. * * This program 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 this program; * if not, see <http://www.gnu.org/licenses/>. * * * Dieses Programm ist freie Software. Sie knnen es unter den Bedingungen der GNU * General Public License, wie von der Free Software Foundation verffentlicht, weitergeben * und/oder modifizieren, entweder gem Version 3 der Lizenz oder (wenn Sie mchten) * jeder spteren Version. * * Die Verffentlichung dieses Programms erfolgt in der Hoffnung, da es Ihnen von Nutzen sein * wird, aber OHNE IRGENDEINE GARANTIE, sogar ohne die implizite Garantie der MARKTREIFE oder * der VERWENDBARKEIT FR EINEN BESTIMMTEN ZWECK. Details finden Sie in der * GNU General Public License. * * Sie sollten ein Exemplar der GNU General Public License zusammen mit diesem Programm * erhalten haben. Falls nicht, siehe <http://www.gnu.org/licenses/>. */ package de.danielluedecke.zettelkasten.database; import de.danielluedecke.zettelkasten.util.Constants; import java.util.Iterator; import java.util.List; import java.util.logging.Level; import org.jdom2.Document; import org.jdom2.Element; import org.jdom2.IllegalAddException; import org.jdom2.IllegalDataException; /** * * @author danielludecke */ public class AutoKorrektur { /** * XML document that holds the data for auto-correction. Each element "entry" * has an attribute named "id" that contains the wrong, mispelled word. the * entry's text is the correct writing of the word. */ private Document autokorrektur; /** * XML document that is used as backup */ private Document backupdoc = null; /** * This class stores the information about the automatic correction (spelling) when * the user makes input for new entries. */ public AutoKorrektur() { clear(); } /** * Clears the XML document and creates a dummy-backup of the document, in case the original * XML-document contains data. */ public final void clear() { // check whether backup document exists, whether autokorrektur-document exists and whether // the autokorrektur-document has any data. only in this case we create a backup if (autokorrektur != null && autokorrektur.getRootElement().getContentSize() > 0) { // create new backup doc backupdoc = new Document(new Element("backup_autokorrektur")); // copy content backupdoc.getRootElement().addContent(autokorrektur.getRootElement().cloneContent()); } autokorrektur = new Document(new Element("autokorrektur")); } /** * This method checks whether the XML document is ok or corrupted. in case there have been * jdom-errors when adding new elements, the XML document {@link #autokorrektur} might * be empty, while the backup-document {@link #backupdoc} has data. In this case, * {@code false} is returned. If the XML-document is ok, {@code true} is returned. * @return {@code true} if the main XML-document is ok, {@code false}if it might be corrupted. * <br><br> * You can use {@link #restoreDocument() restoreDocument()} to restore a corrupted document. */ public boolean isDocumentOK() { // check whether we have any XML-document at all. proceed only, if we have no document // of if the XML-document does not contain data if ((null == autokorrektur) || (autokorrektur.getRootElement().getContentSize() < 1)) { // now check whether we have a backup of the XML document, which has content if ((backupdoc != null) && (backupdoc.getRootElement().getContentSize() > 0)) { // if so, the backup contains data that the main document does not has // so, we assume the document is *not* ok return false; } } // else everything is fine return true; } /** * In case we have a corrupted XML document with a backup document that has data * (see {@link #isDocumentOK() isDocumentOK()}), we can restore the backupped data * with this method.<br><br> * So, this method copies back the content of the {@link #backupdoc} to the * original XML document {@link #autokorrektur}. */ public void restoreDocument() { // check whether we have a backup document that also contains data if ((backupdoc != null) && (backupdoc.getRootElement().getContentSize() > 0)) { // if we have it, create new main XML document autokorrektur = new Document(new Element("autokorrektur")); // and copy the content of the backup document to it autokorrektur.getRootElement().addContent(backupdoc.getRootElement().cloneContent()); } } /** * Sets the document, e.g. after loading the settings * @param d (the document with the auto-correction-data) */ public void setDocument(Document d) { autokorrektur = d; } /** * Gets the xml-document that contains the auto-correction-data * @return the xml-document with the auto-correction-data */ public Document getDocument() { return autokorrektur; } /** * Returns the amount of elements * @return Returns the amount of elements as integer value */ public int getCount() { return autokorrektur.getRootElement().getContentSize(); } /** * Checks whether the value passed by the parameter "e" already exists in the * data. Therefore, each element's id-attribute is compared to the parameter "e". * @param e the string we want to look for if it exists * @return {@code true} if we found it, false if it doesn't exist */ public boolean exists(String e) { // get all elements List<Element> all = autokorrektur.getRootElement().getChildren(); // create an iterator Iterator<Element> i = all.iterator(); // go through list while (i.hasNext()) { // get element Element el = i.next(); // get attribute String att = el.getAttributeValue("id"); // if the element's id equals the requestes string "e", return true // i.e. the string e already exists as element if (att != null && att.equalsIgnoreCase(e)) { return true; } } // nothing found... return false; } /** * Adds a new pair of false/correct words to the document * * @param falsch the wrong or mispelled word * @param richtig the correct writing * @return {@code true} if element was successfully addes, {@code false} if "falsch" already existed or * one of the parameters were invalid */ public boolean addElement(String falsch, String richtig) { // check for minimum length if (null == falsch || falsch.length() < 2 || null == richtig || richtig.length() < 2) { return false; } // check for existence if (exists(falsch)) { return false; } // if it doesn't already exist, create new element Element e = new Element(Daten.ELEMENT_ENTRY); try { // set id-attribute e.setAttribute("id", falsch); // set content e.setText(richtig); // and add it to the document autokorrektur.getRootElement().addContent(e); } catch (IllegalAddException ex) { Constants.zknlogger.log(Level.SEVERE, ex.getLocalizedMessage()); return false; } catch (IllegalDataException ex) { Constants.zknlogger.log(Level.SEVERE, ex.getLocalizedMessage()); return false; } // return success return true; } /** * Gets a String-pair of auto-correct data, i.e. a string array with 2 fields. first * field contains the wrong/mispelled writing, the second field holds the correct * version of the word * @param nr the position of the element we want to retrieve * @return a string array containing the wrong and right spelling */ public String[] getElement(int nr) { // get all elements List<Element> all = autokorrektur.getRootElement().getChildren(); // get the requested element Element el = all.get(nr); // new string array String[] retval = null; // if we found an element, return its content if (el != null) { retval = new String[2]; retval[0] = el.getAttributeValue("id"); retval[1] = el.getText(); } return retval; } /** * * @param wrong * @return the correct spelling of the word {@code wrong} or {@code null}, if no spellcorrection was found */ public String getCorrectSpelling(String wrong) { // get all elements List<Element> all = autokorrektur.getRootElement().getChildren(); // create an iterator Iterator<Element> i = all.iterator(); // go through list while (i.hasNext()) { // get element Element el = i.next(); // get attribute value String att = el.getAttributeValue("id"); // check for existing attribute if (null == att) { return null; } // get spell-check-word String correct = att.toLowerCase(); // get lower-case word of mistyped wrong word... String retval = wrong.toLowerCase(); // if the element's id equals the requestes string "e", return true // i.e. the string e already exists as element if (correct.equalsIgnoreCase(wrong)) { // now that we found the correct word, we want to see whether // the word starts with an upper case letter - and if so, convert // the first letter of the return value to upper case as well String firstLetter = wrong.substring(0, 1); String firstBigLetter = wrong.substring(0, 1).toUpperCase(); // get return value retval = el.getText(); // if both matches, we have upper case initial letter // convert first letter to uppercase if (firstLetter.equals(firstBigLetter)) { retval = retval.substring(0, 1).toUpperCase() + retval.substring(1); } return retval; } // when the misspelled phrase starts with an asterisk, we know that we should check the // end of or in between the typed word "wrong". if (correct.startsWith("*")) { // first we remove the asterisk correct = correct.substring(1); // if the misspelled phrase also ends with an asterisk, we have to check // for the phrase in between - that means, "wrong" is not allowed to end or start // with "correct" if (correct.endsWith(("*"))) { // remove trailing asterisk correct = correct.substring(0, correct.length() - 1); // if the mistyped word "wrong" does not start and end with "correct", we know // that we have a correction in between if (retval.contains(correct)) { // return correct word for wrong spelling return correctWithCase(retval, correct, el.getText(), wrong); } } // if the mistyped word "wrong" does not end with "correct", we know // that else if (retval.endsWith(correct) && retval.contains(correct)) { // return correct word for wrong spelling return correctWithCase(retval, correct, el.getText(), wrong); } } else if (correct.endsWith("*")) { // get lower-case word of mistyped wrong word... retval = wrong.toLowerCase(); // if the mistyped word "wrong" does not end with "correct", we know // that we have the correction at thr word beginning if (retval.startsWith(correct) && retval.contains(correct)) { // return correct word for wrong spelling return correctWithCase(retval, correct, el.getText(), wrong); } } } // return null, no correct word found return null; } private String correctWithCase(String retval, String correct, String newtext, String wrong) { retval = retval.replace(correct, newtext); // now that we found the correct word, we want to see whether // the word starts with an upper case letter - and if so, convert // the first letter of the return value to upper case as well String firstLetter = wrong.substring(0, 1); String firstBigLetter = wrong.substring(0, 1).toUpperCase(); // if both matches, we have upper case initial letter // convert first letter to uppercase if (firstLetter.equals(firstBigLetter)) { retval = retval.substring(0, 1).toUpperCase() + retval.substring(1); } return retval; } }