/*
* This file is part of Caliph & Emir.
*
* Caliph & Emir 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 2 of the License, or
* (at your option) any later version.
*
* Caliph & Emir 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 Caliph & Emir; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Copyright statement:
* --------------------
* (c) 2002-2005 by Mathias Lux (mathias@juggle.at)
* http://www.juggle.at, http://caliph-emir.sourceforge.net
*/
package at.lux.fotoretrieval;
import org.jdom.Element;
import org.jdom.Namespace;
import javax.xml.transform.Transformer;
import java.text.DecimalFormat;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
/**
* ResultListEntry
*
* @author Mathias Lux, mathias@juggle.at
*/
public class ResultListEntry implements Comparable {
private double relevance;
private Element documentRoot;
private String filePath = null;
private String thumbPath = null;
private String descriptionPath = null;
private String HTMLSummary = null;
private static DecimalFormat df = ((DecimalFormat) DecimalFormat.getInstance());
private int quality = -1;
private String semanticDescriptionString;
private String creatorName;
private String freeTextDescription;
private String creationTime;
private String imageFilePath;
private String imageSize;
public ResultListEntry(double relevance, Element documentRoot, String descriptionPath) {
this.relevance = relevance;
this.documentRoot = documentRoot;
this.descriptionPath = descriptionPath;
df.setMaximumFractionDigits(2);
List results = RetrievalToolkit.xpathQuery(documentRoot, "//MediaProfile[@master='true']/MediaInstance/MediaLocator/MediaUri", null);
if (results.size() > 0) {
filePath = ((Element) results.get(0)).getTextTrim();
if (results.size() > 1) {
thumbPath = ((Element) results.get(1)).getTextTrim();
}
}
// /Mpeg7/Description/MultimediaContent/Image/MediaInformation/MediaProfile/MediaFormat/VisualCoding/Frame
results = RetrievalToolkit.xpathQuery(documentRoot, "//MediaProfile/MediaFormat/VisualCoding/Frame[number(@height) < 121 and number(@width) < 121]", null);
if (results.size() > 0) {
Element frame = ((Element) results.get(0));
Element profile = (Element) frame.getParent().getParent().getParent();
Namespace mpeg7 = profile.getNamespace();
Element uri = profile.getChild("MediaInstance", mpeg7).getChild("MediaLocator", mpeg7).getChild("MediaUri", mpeg7);
thumbPath = uri.getTextTrim();
}
// quality
results = RetrievalToolkit.xpathQuery(documentRoot, "//QualityRating[@type='subjective']/RatingValue", null);
if (results.size() > 0) {
quality = Integer.parseInt(((Element) results.get(0)).getTextTrim());
} else {
quality = -1;
}
// creating the summary:
// HTMLSummary = getSummary();
extractSummary();
this.documentRoot = null;
}
public ResultListEntry(double relevance, String thumbPath, String filePath, String creatorName, String freeTextDescription, String creationTime, String imageFilePath, String imageSize) {
this.relevance = relevance;
this.thumbPath = thumbPath;
this.filePath = filePath;
this.descriptionPath = null;
this.creatorName = creatorName;
this.freeTextDescription = freeTextDescription;
this.creationTime = creationTime;
this.imageFilePath = imageFilePath;
this.imageSize = imageSize;
}
public double getRelevance() {
return relevance;
}
public int getQuality() {
return quality;
}
public String getFilePath() {
return filePath;
}
public String getThumbPath() {
return thumbPath;
}
public void setThumbPath(String thumbPath) {
this.thumbPath = thumbPath;
}
/**
* Gets path to MPEG-7 file
*
* @return Path to MPEG-7 file
*/
public String getDescriptionPath() {
return descriptionPath;
}
/**
* Summary of result
*
* @return Summary of result based on HTML 3.2
*/
public String getHTMLSummary() {
return HTMLSummary;
}
public String getSemanticDescriptionString() {
return semanticDescriptionString;
}
public String getCreatorName() {
return creatorName;
}
public String getFreeTextDescription() {
return freeTextDescription;
}
public String getCreationTime() {
return creationTime;
}
public String getImageFilePath() {
return imageFilePath;
}
public String getImageSize() {
return imageSize;
}
private void extractSummary() {
creatorName = "";
List l = RetrievalToolkit.xpathQuery(documentRoot, "//CreationInformation/Creation/Creator/Agent/Name", documentRoot.getNamespace());
if (l.size() > 0) {
Element name = (Element) l.get(0);
creatorName += name.getChildTextTrim("FamilyName", name.getNamespace());
creatorName += ", ";
creatorName += name.getChildTextTrim("GivenName", name.getNamespace());
}
creatorName += " with " + getValueOfPath("//CreationInformation/Creation/CreationTool/Tool/Name");
creationTime = getValueOfPath("//CreationInformation/Creation/CreationCoordinates/Date/TimePoint");
// so we can build up some description on our own.
LinkedList<String> agents = new LinkedList<String>();
LinkedList<String> events = new LinkedList<String>();
LinkedList<String> times = new LinkedList<String>();
LinkedList<String> places = new LinkedList<String>();
Namespace xsi = Namespace.getNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");
l = RetrievalToolkit.xpathQuery(documentRoot, "//SemanticBase", documentRoot.getNamespace());
for (Object aL : l) {
Element elem = (Element) aL;
String label;
label = elem.getChild("Label", elem.getNamespace()).getChildText("Name", elem.getNamespace()).trim();
if (elem.getAttribute("type", xsi).getValue().startsWith("AgentObjectType")) {
agents.add(label);
} else if (elem.getAttribute("type", xsi).getValue().startsWith("EventType")) {
events.add(label);
} else if (elem.getAttribute("type", xsi).getValue().startsWith("SemanticTimeType")) {
times.add(label);
} else if (elem.getAttribute("type", xsi).getValue().startsWith("SemanticPlaceType")) {
places.add(label);
}
}
semanticDescriptionString = appendAll(agents) + ((appendAll(agents).contains(",")) ? " are at " : " is at ") + appendAll(places) + " for " + appendAll(events) + " in " + appendAll(times);
// fre text annotation:
String valueOfPath = getValueOfPath("//TextAnnotation/FreeTextAnnotation");
freeTextDescription = valueOfPath;
valueOfPath = getValueOfPath("//MediaInformation/MediaProfile/MediaInstance/MediaLocator/MediaUri");
imageFilePath = valueOfPath.substring(valueOfPath.lastIndexOf('/') + 1);
l = RetrievalToolkit.xpathQuery(documentRoot, "//MediaInformation/MediaProfile/MediaFormat/VisualCoding/Frame", documentRoot.getNamespace());
if (l.size() > 0) {
Element frame = (Element) l.get(0);
imageSize = frame.getAttribute("width").getValue() + " x " + frame.getAttribute("height").getValue() + " pixels ";
}
}
private String getValueOfPath(String path) {
String result = null;
List l = RetrievalToolkit.xpathQuery(documentRoot, path, documentRoot.getNamespace());
if (l.size() > 0) {
Element name = (Element) l.get(0);
result = name.getTextTrim();
}
return result;
}
private String appendAll(List<String> input) {
StringBuilder sb = new StringBuilder(input.size() * 32);
for (Iterator<String> iterator = input.iterator(); iterator.hasNext();) {
sb.append(iterator.next());
if (iterator.hasNext()) sb.append(", ");
}
return sb.toString();
}
public int compareTo(Object o) {
ResultListEntry r = (ResultListEntry) o;
return (int) Math.signum(r.getRelevance() - relevance);
}
}