/******************************************************************************* * Copyright 2016 * Ubiquitous Knowledge Processing (UKP) Lab * Technische Universität Darmstadt * * 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. ******************************************************************************/ package de.tudarmstadt.ukp.lmf.api; import java.io.FileNotFoundException; import java.sql.SQLException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.hibernate.Query; import org.hibernate.SQLQuery; import org.hibernate.Session; import org.hibernate.SessionFactory; import de.tudarmstadt.ukp.lmf.model.core.LexicalResource; import de.tudarmstadt.ukp.lmf.model.core.Lexicon; import de.tudarmstadt.ukp.lmf.model.core.Sense; import de.tudarmstadt.ukp.lmf.model.multilingual.SenseAxis; import de.tudarmstadt.ukp.lmf.transform.DBConfig; /** * This class represents an extension of the {@link Uby} class and offers additional methods for * quick searching of different UBY-LMF elements in a database containing a {@link LexicalResource}. * <p> * For performance reasons, the methods offered by this class do not return fully initialized * Uby-LMF class instances. * * @since 0.1.0 * * @author Silvana Hartmann * @author Zijad Maksuti */ public class UbyQuickAPI extends Uby { /** * Using this constructor, you have to call setDbConfig before using any method. * * @deprecated use {@link #UbyQuickAPI(DBConfig)} instead */ @Deprecated public UbyQuickAPI() { // TO-DO nothing } /** * Constructor for a {@link UbyQuickAPI} instance used for searching of different elements in a * database containing UBY-LMF {@link LexicalResource}. * * The connection to the database is specified using a {@link DBConfig} instance. * * @param dbConfig * configuration of the database containing UBY-LMF lexical resource. * @throws UbyInvalidArgumentException * if the specified dbConfig is null * * @since 0.1.0 */ public UbyQuickAPI(DBConfig dbConfig) throws IllegalArgumentException { super(dbConfig); } /** * * @param config * database's configuration * @param useHibernate * false for direct access; true connect via Hibernate * @deprecated use {@link #UbyQuickAPI(DBConfig)} instead */ @Deprecated public UbyQuickAPI(DBConfig config, boolean useHibernate,boolean useTempTables) throws ClassNotFoundException, SQLException, FileNotFoundException{ setDBConfig(config,useHibernate,useTempTables); } /** * * @param session * Session of hibernate connection. In case you don't run query * directly * @deprecated use {@link #UbyQuickAPI(DBConfig)} instead */ @Deprecated public UbyQuickAPI(Session session) { this.session = session; } /** * @deprecated use {@link #UbyQuickAPI(DBConfig)} instead */ @Deprecated public UbyQuickAPI(SessionFactory sf){ sessionFactory=sf; session=sessionFactory.openSession(); } /** * @param config * Database's Configuration * @param useHibernate * true if you want to connect to database via Hibernate; false for direct access * @deprecated use {@link #UbyQuickAPI(DBConfig)} instead */ @Deprecated public void setDBConfig(DBConfig config, boolean useHibernate, boolean useTemporaryTables) throws ClassNotFoundException, SQLException, FileNotFoundException { this.dbConfig = config; if(useHibernate){ setDbConfig(config); }/*else{ this.useTemporaryTables=useTemporaryTables; mysql=new MySQLConnect(config,this.useTemporaryTables); }*/ } /** * This method fetches a {@link List} of light {@link Lexicon} instances containing only * the name and the id.<p> * * The method is meant for fast fetching of lexicons. In order to get complete * Lexicon instances use {@link #getLexicons()} instead. * * @return a list of all lexicons contained in the database. The returned lexicons are light * and consist only of an id and a name. If the accessed database does not contain any lexicons, * this method returns an empty list. * * @since 0.2.0 * * @see Lexicon#getName() * @see Lexicon#getId() * */ public List<Lexicon> lightLexicons(){ List<Lexicon>lexicons=new ArrayList<Lexicon>(); String sql="Select lexiconId,lexiconName from Lexicon"; SQLQuery query = session.createSQLQuery(sql); Iterator<?> iter = query.list().iterator(); while (iter.hasNext()) { Object[] row = (Object[]) iter.next(); Lexicon lexicon=new Lexicon(); lexicon.setId((String)row[0]); lexicon.setName((String)row[1]); lexicons.add(lexicon); } return lexicons; } /** * This method fetches a {@link List} of all identifiers of {@link Sense} * instances which are aligned by a {@link SenseAxis} with the specified * sense. * <p> * * The method is meant for fast fetching of alignments. For retrieving of * complete alignments use {@link #getSenseAxesBySense(Sense)} instead. * * @param sense * all returned identifiers must belong to senses which are * aligned to it * * @return a list of identifiers of all senses which are aligned with the * specified sense by a sense axis.<br> * If the specified sense is not contained in any alignment or the * specified sense is null, this method returns an empty list. * * @since 0.2.0 * */ public List<String> alignedSenseIDs(Sense sense) { List<String> list = new ArrayList<String>(); String id = sense.getId(); if (id != null && !id.equals("")) { // Select senseOneId, senseTwoId from SenseAxis where // senseOneId='WN_Sense_100' or senseTwoId='WN_Sense_100' String sql = "Select senseOneId, senseTwoId from SenseAxis where senseOneId='" + id + "' or senseTwoId='" + id + "'"; // use Hibernate query SQLQuery query = session.createSQLQuery(sql); @SuppressWarnings("rawtypes") Iterator iter = query.list().iterator(); while (iter.hasNext()) { Object[] row = (Object[]) iter.next(); String sense1 = (String) row[0]; String sense2 = (String) row[1]; if (sense1.matches(id)) { list.add(sense2); } else { list.add(sense1); } } } return list; } /** * This method fetches a {@link List} of all identifiers of {@link Sense} * instances which are aligned by a {@link SenseAxis} with the sense * specified by its identifier. * <p> * * The method is meant for fast fetching of alignments. For retrieving of * complete alignments use {@link #getSenseAxesBySense(Sense)} instead. * * @param senseId * all returned identifiers must belong to senses which are * aligned to the sense represented by the id * * @return a list of identifiers of all senses which are aligned with the * specified sense by a sense axis.<br> * If the sense specified by its identifier is not contained in any * alignment or the specified id is null, this method returns an * empty list. * * @since 0.2.0 * */ public List<String> alignedSenseIDs(String senseId) { List<String> list = new ArrayList<String>(); if (senseId != null && !senseId.equals("")) { // Select senseOneId, senseTwoId from SenseAxis where // senseOneId='WN_Sense_100' or senseTwoId='WN_Sense_100' String sql = "Select senseOneId, senseTwoId from SenseAxis where senseOneId='" + senseId + "' or senseTwoId='" + senseId + "'"; @SuppressWarnings("rawtypes") List query = session.createSQLQuery(sql).list(); @SuppressWarnings("rawtypes") Iterator iter = query.iterator(); while (iter.hasNext()) { Object[] row = (Object[]) iter.next(); String sense1 = (String) row[0]; String sense2 = (String) row[1]; if (sense1.matches(senseId)) { list.add(sense2); } else { list.add(sense1); } } } return list; } /** * Consumes a {@link List} of {@link Sense} instances and returns a List of * all {@link SenseAxis} instances aligning senses from the consumed list. * In particular, every returned sense axis aligns two senses from the * consumed list.<br> * The returned sense axes are not fully initialized and contain only references * to senses which they bind. * * @param listSense * A list of senses for which the sense alignments should be * returned. * <br> * Note that sense instances contained in the list must not be * fully initialized. It sufficient to provide a list of senses * where each sense only has its unique identifier set. * * @return a list of sense alignments available from the input list. * <p> * If no sense alignments are available, this method returns an * empty list. * * @since 0.2.0 * * @see #lightSenseAxesBySenseIDs(List) * */ public List<SenseAxis> lightSenseAxes(List<Sense> listSense) { String list = ""; List<SenseAxis> senseAxes = new ArrayList<SenseAxis>(); for (Sense sense : listSense) { list += "'" + sense.getId() + "',"; } if (list.endsWith(",")) { list = list.substring(0, list.length() - 1); } String sql = "Select senseOneId,senseTwoId from SenseAxis where senseOneId in (" + list + ") and senseTwoId in (" + list + ")"; Query query = session.createSQLQuery(sql); Iterator<?> iter = query.list().iterator(); while (iter.hasNext()) { Object[] rows = (Object[]) iter.next(); SenseAxis sa = new SenseAxis(); Sense sense1 = getSenseFromList(listSense, (String) rows[0]); Sense sense2 = getSenseFromList(listSense, (String) rows[1]); sa.setSenseOne(sense1); sa.setSenseTwo(sense2); senseAxes.add(sa); } return senseAxes; } /** * Consumes a {@link List} of unique identifiers of {@link Sense} instances * and returns a List of all {@link SenseAxis} instances aligning senses * which identifiers are in the consumed list. In particular, every returned * sense axis aligns two senses which unique identifiers are in the consumed * list. * <br> * The returned sense axes are not fully initialized and contain only references * to senses which they bind. * * @param listSenseId * A list of sense identifiers for which the sense alignments * should be returned. * * @return a list of sense alignments available from the input list. * <p> * If no sense alignments are available, this method returns an * empty list. * * @since 0.2.0 * * @see #getSenseAxes() * @see #lightSenseAxes(List) */ public List<SenseAxis> lightSenseAxesBySenseIDs(List<String> listSenseId) { String list = ""; List<SenseAxis> senseAxes = new ArrayList<SenseAxis>(); for (String senseId : listSenseId) { list += "'" + senseId + "',"; } if (list.endsWith(",")) { list = list.substring(0, list.length() - 1); } String sql = "Select senseOneId,senseTwoId from SenseAxis where senseOneId in (" + list + ") and senseTwoId in (" + list + ")"; Query query = session.createSQLQuery(sql); Iterator<?> iter = query.list().iterator(); while (iter.hasNext()) { Object[] rows = (Object[]) iter.next(); SenseAxis sa = new SenseAxis(); Sense sense1 = new Sense(); Sense sense2 = new Sense(); sense1.setId((String) rows[0]); sense2.setId((String) rows[1]); sa.setSenseOne(sense1); sa.setSenseTwo(sense2); senseAxes.add(sa); } return senseAxes; } /** * Consumes a {@link List} of {@link Sense} instances and a {@link String} * representing the unique identifier of a sense. It returns the sense from * the consumed list which unique identifier is equal to the consumed * identifier. * * @param senses * a list of sense to be searched in * * @param senseId * the unique identifier of the searched sense * * @return the sense in the consumed list which unique identifier matches * the consumed unique identifier or null if the list does not * contain such sense */ // TODO not neccessary? protected Sense getSenseFromList(List<Sense> senses, String senseId) { Sense sense = null; for (Sense s : senses) { if (s.getId().equals(senseId)) { sense = s; break; } } return sense; } }