/******************************************************************************* * Copyright 2007, 2009 Jorge Villalon (jorge.villalon@uai.cl) * * 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 tml.vectorspace.operations; import java.util.ArrayList; import java.util.Date; import java.util.List; import org.apache.log4j.Logger; import tml.corpus.Corpus; import tml.storage.Repository; import tml.vectorspace.operations.results.AbstractResult; import Jama.Matrix; import javax.swing.event.EventListenerList; /** * Abstract class for all operations, it contains the common attributes and the * start() and end() methods. * * @author Jorge Villalon * * @param <E> * The class for the result of the particular operation */ public abstract class AbstractOperation<E> implements Operation<E> { protected static Logger logger = Logger.getLogger(AbstractOperation.class); protected long timeElapsed = 0; protected Date executionDate; protected int maxResults = -1; protected ArrayList<E> results = new ArrayList<E>(); protected Corpus corpus = null; protected String name; protected double summaryResult = -1; protected Corpus backgroundKnowledge = null; protected Repository repository = null; protected boolean requiresSemanticSpace = true; protected EventListenerList listeners = null; /** * @return the repository */ public Repository getRepository() { return repository; } @Override public void addOperationListener(OperationListener listener) { this.listeners.add(OperationListener.class, listener); } @Override public void removeOperationListener(OperationListener listener) { this.listeners.remove(OperationListener.class, listener); } protected void operationPerformed(OperationEvent evt) { OperationListener[] list = this.listeners.getListeners(OperationListener.class); for (OperationListener listener : list) { listener.operationAction(evt); } } /** * Constructs a default operation with no {@link Corpus} attached to it */ public AbstractOperation() { this(null); } /** * Creates a new instance with a corpus ready * @param corpus the corpus to process */ public AbstractOperation(Corpus corpus) { this.setCorpus(corpus); this.name = this.getClass().getSimpleName(); this.listeners = new EventListenerList(); } protected void end() { this.timeElapsed = System.currentTimeMillis() - this.timeElapsed; String message = "Operation " + this.name + " finished,"; if (this.results != null) { message += " " + this.results.size() + " results obtained"; } message += " in " + this.timeElapsed + " ms."; logger.info(message); } @Override public Corpus getCorpus() { return corpus; } @Override public int getMaxResults() { return maxResults; } @Override public String getName() { return name; } protected Object[][] getObjectArrayFromMatrix(Matrix m) { Object[][] data = new Object[m.getRowDimension()][m.getColumnDimension()]; for (int i = 0; i < m.getRowDimension(); i++) { for (int j = 0; j < m.getColumnDimension(); j++) { data[i][j] = m.get(i, j); } } return data; } /** * @return the corpus used as background knowledge */ @Override public Corpus getBackgroundKnowledgeCorpus() { return backgroundKnowledge; } @Override public List<E> getResults() { return this.results; } /** * @return results are presented as a set of lines separated by commas */ @Override public String getResultsCSVString() { return getResultsString("", "", "", "\n", ","); } @Override public int getResultsNumber() { return this.results.size(); } /** * @param start * @param end * @param startLine * @param endLine * @param separator * @return a String containing the representation of the results */ public String getResultsString(String start, String end, String startLine, String endLine, String separator) { StringBuffer buff = new StringBuffer(); Object[][] data = this.getResultsTable(); Object[] headers = this.getResultsTableHeader(); if (data == null || headers == null) { return "Operation doesn't implement results as output."; } buff.append(start); int columns = headers.length; int rows = data.length; buff.append(startLine); for (int j = 0; j < columns; j++) { if (j == columns - 1) { buff.append(this.getResultsTableHeader()[j]); } else { buff.append(this.getResultsTableHeader()[j] + separator); } } buff.append(endLine); for (int i = 0; i < rows; i++) { buff.append(startLine); for (int j = 0; j < columns; j++) { if (j == columns - 1) { buff.append(data[i][j]); } else { buff.append(data[i][j] + separator); } } buff.append(endLine); } buff.append(end); return buff.toString(); } @Override public long getTimeElapsed() { return this.timeElapsed; } /** * Print results on the console */ public void printResults() { printResults("", "", "", "\n", "|"); } private void printResults(String start, String end, String startLine, String endLine, String separator) { System.out.print(getResultsString(start, end, startLine, endLine, separator)); } /** * Prints the results on the console using a comma as separator */ @Override public void printResultsCSV() { printResults("", "", "", "\n", ","); } /** * Prints the results on the console a'la Matlab */ @Override public void printResultsMatlab() { printResults("[", "]", "", ";", " "); } @Override public void setCorpus(Corpus corpus) { this.corpus = corpus; if (corpus != null) { this.repository = this.corpus.getRepository(); } } /** * Sets the maximum results the operation will return */ @Override public void setMaxResults(int maxResults) { this.maxResults = maxResults; } /** * @param backgroundKnowledgeCorpus the corpus that will be used as background knowledge */ @Override public void setBackgroundKnowledgeCorpus(Corpus backgroundKnowledgeCorpus) { this.backgroundKnowledge = backgroundKnowledgeCorpus; } @Override public void start() throws Exception { logger.info("Operation " + this.name + " started"); this.executionDate = new Date(); this.timeElapsed = System.currentTimeMillis(); if (backgroundKnowledge != null) { try { if (!backgroundKnowledge.getSemanticSpace().isCalculated()) { backgroundKnowledge.getSemanticSpace().calculate(); } Corpus projectedCorpus = backgroundKnowledge.projectCorpus(this.corpus); this.corpus = projectedCorpus; } catch (Exception e) { logger.error(e); return; } } else { if (requiresSemanticSpace && !this.corpus.getSemanticSpace().isCalculated()) { try { this.corpus.getSemanticSpace().calculate(); } catch (Exception e) { e.printStackTrace(); this.corpus = null; } } } } @Override public String toString() { return this.getName() + " " + this.corpus.getName(); } @Override public Object[][] getResultsTable() { if (this.results == null || this.results.size() == 0) { return null; } E e = this.results.get(0); Object[][] data = new Object[this.results.size()][e.getClass().getDeclaredFields().length]; int resultNumber = 0; for (E r : this.results) { AbstractResult result = (AbstractResult) r; try { data[resultNumber] = result.getValues(); } catch (Exception e1) { logger.error(e1); continue; } resultNumber++; } return data; } @Override public String[][] getResultsStringTable() { Object[][] resultsTable = getResultsTable(); Object[] resultsHeaders = getResultsTableHeader(); String[][] output = new String[resultsTable.length+1][resultsTable[0].length]; for(int j=0;j<resultsTable[0].length;j++) output[0][j] = resultsHeaders[j].toString(); for(int i=0;i<resultsTable.length;i++) for(int j=0;j<resultsTable[0].length;j++) output[i+1][j] = resultsTable[i][j].toString(); return output; } @Override public Object[] getResultsTableHeader() { if (this.results == null || this.results.size() == 0) { return null; } AbstractResult result = (AbstractResult) this.results.get(0); return result.getHeaders(); } @Override public String getResultsXML() { return getResultsString("<?xml version=\"1.0\"?><results>", "</results>", "<result>", "</result>", "#"); } }