/* TMeaning.java - SQL operations with the table 'meaning' in Wiktionary * parsed database. * * Copyright (c) 2009-2011 Andrew Krizhanovsky <andrew.krizhanovsky at gmail.com> * Distributed under EPL/LGPL/GPL/AL/BSD multi-license. */ package wikokit.base.wikt.sql; //import wikipedia.language.Encodings; //import wikipedia.sql.PageTableBase; import wikokit.base.wikipedia.sql.Connect; import java.sql.*; import wikokit.base.wikt.constant.Relation; import java.util.List; import java.util.ArrayList; import java.util.Map; import java.util.HashMap; import wikokit.base.wikt.sql.quote.TQuote; /** An operations with the table 'meaning' in MySQL wiktionary_parsed database. * * @see wikt.word.WPOS */ public class TMeaning { /** Unique identifier in the table 'meaning'. */ private int id; /** Link to the table 'lang_pos', which defines language and POS. * If lang_pos != null, then lang_pos_id is not used; lazy DB access. */ private TLangPOS lang_pos; // int lang_pos_id; /** Link to the table 'lang_pos', which defines language and POS. * If lang_pos != null, then lang_pos_id is not used. */ private int lang_pos_id; /** Meaning (sense) number. */ private int meaning_n; /** Wikified text describing this meaning. * If wiki_text != null, then wiki_text_id is not used; lazy DB access. */ private TWikiText wiki_text; // int wiki_text_id /** ID of wikified text in a table 'wiki_text. * If wiki_text != null, then wiki_text_id is not used; lazy DB access. */ private int wiki_text_id; /** Quotations illustrate the meaning. */ private TQuote[] quotation; /** Semantic relations: synonymy, antonymy, etc. * The map from semantic relation (e.g. synonymy) to array of WRelation * (one WRelation contains a list of synonyms for one meaning). */ private Map<Relation, TRelation[]> relation; /** Translation */ private TTranslation translation; private final static Map<Relation, TRelation[]> NULL_MAP_RELATION_TRELATION_ARRAY = new HashMap<Relation, TRelation[]>(); private final static TMeaning[] NULL_TMEANING_ARRAY = new TMeaning[0]; //private final static TRelation[] NULL_TRELATION_ARRAY = new TRelation[0]; /** Constructor. * @param _id * @param _lang_pos * @param _lang_pos_id * @param _meaning_n * @param _wiki_text * TLangPOS _lang_pos or int _lang_pos_id should be valid, * if lang_pos != null, then _lang_pos_id is not used. */ public TMeaning(int _id,TLangPOS _lang_pos,int _lang_pos_id, int _meaning_n, TWikiText _wiki_text,int _wiki_text_id) { id = _id; lang_pos = _lang_pos; lang_pos_id = _lang_pos_id; meaning_n = _meaning_n; wiki_text = _wiki_text; wiki_text_id= _wiki_text_id; relation = NULL_MAP_RELATION_TRELATION_ARRAY; } /** Gets unique ID from database */ public int getID() { return id; } /** Gets meaning (sense) number from database */ public int getMeaningNumber() { return meaning_n; } /** Gets language and POS ID (for this meaning) from the database' table 'lang_pos'. */ public TLangPOS getLangPOS(Connect connect) { if(null != lang_pos) return lang_pos; lang_pos = TLangPOS.getByID(connect, lang_pos_id); // lazy DB access return lang_pos; } /** Gets text object describing this meaning (without wikification) */ public TWikiText getWikiText() { return wiki_text; } /** Gets text describing this meaning (without wikification) or empty String "". */ public String getWikiTextString() { if(null == wiki_text) return ""; return wiki_text.getText(); } /** Gets relation map */ public Map<Relation, TRelation[]> getRelation() { return relation; } /** Inserts record into the table 'meaning'.<br><br> * INSERT INTO meaning (lang_pos_id,meaning_n,wiki_text_id) VALUES (1,2,3); * @param lang_pos ID of language and POS of wiki page which will be added * @param meaning_n meaning (sense) number * @param wiki_text wikified text (definitions), it could be null (since an article can contain synonyms without a definition of meaning) * @return inserted record, or null if insertion failed */ public static TMeaning insert (Connect connect,TLangPOS lang_pos, int meaning_n, TWikiText wiki_text) { if(null == lang_pos) { System.out.println("Error (wikt_parsed TMeaning.insert()):: null argument lang_pos"); return null; } StringBuilder str_sql = new StringBuilder(); TMeaning meaning = null; int wiki_text_id = 0; try { Statement s = connect.conn.createStatement (); try { if(null != wiki_text) str_sql.append("INSERT INTO meaning (lang_pos_id,meaning_n,wiki_text_id) VALUES ("); else str_sql.append("INSERT INTO meaning (lang_pos_id,meaning_n) VALUES ("); str_sql.append(lang_pos.getID()); str_sql.append(","); str_sql.append(meaning_n); if(null != wiki_text) { str_sql.append(","); str_sql.append(wiki_text.getID()); wiki_text_id = wiki_text.getID(); } str_sql.append(")"); s.executeUpdate (str_sql.toString()); } finally { s.close(); } try { s = connect.conn.createStatement (); ResultSet rs = s.executeQuery ("SELECT LAST_INSERT_ID() as id"); try { if (rs.next ()) { meaning = new TMeaning(rs.getInt("id"), lang_pos, lang_pos.getID(), meaning_n, wiki_text, wiki_text_id); //System.out.println("TMeaning.insert()):: wiki_text='" + wiki_text.getText() + "'; meaning_n=" + meaning_n); } } finally { rs.close(); } } finally { s.close(); } }catch(SQLException ex) { System.out.println("SQLException (wikt_parsed TMeaning.java insert()):: sql='" + str_sql.toString() + "' " + ex.getMessage()); } return meaning; } /** Selects rows from the table 'meaning' by the lang_pos_id. * SELECT id,meaning_n,wiki_text_id FROM meaning WHERE lang_pos_id=1; * @return empty array if data is absent */ public static TMeaning[] get (Connect connect,TLangPOS lang_pos) { if(null == lang_pos) { System.out.println("Error (wikt_parsed TMeaning.get()):: null argument lang_pos"); return null; } StringBuilder str_sql = new StringBuilder(); List<TMeaning> list_meaning = null; try { Statement s = connect.conn.createStatement (); try { str_sql.append("SELECT id,meaning_n,wiki_text_id FROM meaning WHERE lang_pos_id="); str_sql.append(lang_pos.getID()); //str_sql.append(" ORDER BY id"); ResultSet rs = s.executeQuery (str_sql.toString()); try { while (rs.next ()) { int id = rs.getInt("id"); int meaning_n = rs.getInt("meaning_n"); int wiki_text_id = rs.getInt("wiki_text_id"); TWikiText wiki_text = wiki_text_id < 1 ? null : TWikiText.getByID(connect, wiki_text_id); if(null == list_meaning) list_meaning = new ArrayList<TMeaning>(); list_meaning.add(new TMeaning(id, lang_pos, lang_pos.getID(), meaning_n, wiki_text, wiki_text_id)); } } finally { rs.close(); } } finally { s.close(); } } catch(SQLException ex) { System.out.println("SQLException (TMeaning.get()):: sql='" + str_sql.toString() + "' " + ex.getMessage()); } if(null == list_meaning) return NULL_TMEANING_ARRAY; return ((TMeaning[])list_meaning.toArray(NULL_TMEANING_ARRAY)); } /** Filters the array 'rels' of semantic relations only for one kind of * semantic relations (e.g. synonyms) defined by the variable 'r_type'. * @param rels array of relations * @param r_type the relation type we are interested in, e.g. synonymy * @return an empty array if relations are absent */ private void addOneKindOfRelation (Relation r_type, TRelation[] rels) { // 1. counts number of relations of this type int c = 0; for(TRelation r : rels) { if(r.getRelationType() == r_type) c ++; } if(0 == c) return; // 2. gets these relations TRelation[] result = new TRelation[c]; c = 0; for(TRelation r : rels) { if(r.getRelationType() == r_type) result [c ++] = r; } if(0 == relation.size()) relation = new HashMap<Relation, TRelation[]>(); relation.put(r_type, result); //System.out.println("r_type="+r_type.toString()+"; +1 where TRelation[] result.size="+result.length); } /** Fills the relations field. */ public void fillRelation (Connect connect) { TRelation[] rels = TRelation.get(connect, this); // let's convert the flat array: TRelation[] rels // into the map: Map<Relation, TRelation[]> relation; addOneKindOfRelation (Relation.synonymy, rels); addOneKindOfRelation (Relation.antonymy, rels); addOneKindOfRelation (Relation.hypernymy, rels); addOneKindOfRelation (Relation.hyponymy, rels); addOneKindOfRelation (Relation.holonymy, rels); addOneKindOfRelation (Relation.meronymy, rels); } /** Fills the translation field. * * Selects rows from the table 'translation' by the meaning_id, * fills (recursively) all fields translation_entry. */ public void fillTranslation (Connect connect) { translation = TTranslation.getByMeaning(connect, this); if(null == translation) return; translation.getRecursive(connect); } /** Selects rows from the table 'meaning' by the lang_pos_id. * fills (recursively) relations. * * @return empty array if data is absent */ public static TMeaning[] getRecursive (Connect connect,TLangPOS lang_pos) { TMeaning[] mm = TMeaning.get(connect, lang_pos); for(TMeaning m : mm) { m.fillRelation(connect); m.fillTranslation(connect); } return mm; } /** Selects rows from the table 'meaning' by ID<br><br> * SELECT lang_pos_id,meaning_n,wiki_text_id FROM meaning WHERE id=1; * @return empty array if data is absent */ public static TMeaning getByID (Connect connect,int id) { StringBuilder str_sql = new StringBuilder(); TMeaning meaning = null; try { Statement s = connect.conn.createStatement (); try { str_sql.append("SELECT lang_pos_id,meaning_n,wiki_text_id FROM meaning WHERE id="); str_sql.append(id); ResultSet rs = s.executeQuery (str_sql.toString()); try { if (rs.next ()) { TLangPOS lang_pos = TLangPOS.getByID(connect, rs.getInt("lang_pos_id")); int meaning_n = rs.getInt("meaning_n"); int wiki_text_id = rs.getInt("wiki_text_id"); TWikiText wiki_text = wiki_text_id < 1 ? null : TWikiText.getByID(connect, wiki_text_id); if(null != lang_pos) { meaning = new TMeaning(id, lang_pos, lang_pos.getID(), meaning_n, wiki_text, wiki_text_id); } } } finally { rs.close(); } } finally { s.close(); } } catch(SQLException ex) { System.out.println("SQLException (TMeaning.getByID()):: sql='" + str_sql.toString() + "' " + ex.getMessage()); } return meaning; } /** Deletes row from the table 'meaning' by a value of ID.<br> * DELETE FROM meaning WHERE id=1; * @param id unique ID in the table `meaning` */ public static void delete (Connect connect,TMeaning meaning) { if(null == meaning) { System.out.println("Error (wikt_parsed TMeaning.delete()):: null argument meaning"); return; } StringBuilder str_sql = new StringBuilder(); try { Statement s = connect.conn.createStatement (); try { str_sql.append("DELETE FROM meaning WHERE id="); str_sql.append(meaning.getID()); s.execute (str_sql.toString()); //System.out.println("TMeaning.delete()):: wiki_text='" + meaning.getWikiText().getText() + // "'; meaning_n=" + meaning.getMeaningNumber()); } finally { s.close(); } } catch(SQLException ex) { System.out.println("SQLException (TMeaning.delete()):: sql='" + str_sql.toString() + "' " + ex.getMessage()); } } /** Checks whether the article 'page_title' has at least one translatio * into the destination (target) language from the array 'trans_lang'. * The fields 'lang_pos', 'lang_pos.translation' are scanned here. */ public boolean hasTranslation(TLang trans_lang[]) { if(null == translation) return false; TTranslationEntry[] trans_entries = translation.getTranslationEntry(); for(TTranslationEntry entry: trans_entries) { for(TLang lang : trans_lang) { if(lang == entry.getLang()) return true; } } return false; } }