/**
*
*/
package outputter.search;
import java.util.ArrayList;
import java.util.Hashtable;
import org.apache.log4j.Logger;
import org.jdom.Element;
import outputter.Utilities;
import outputter.XML2EQ;
import outputter.data.CompositeEntity;
import outputter.data.Entity;
import outputter.data.EntityProposals;
import outputter.data.FormalRelation;
import outputter.data.REntity;
import outputter.data.SimpleEntity;
import outputter.knowledge.Dictionary;
/**
* @author Hong Cui
* = EntitySearcher2
*/
public class EntityEntityLocatorStrategy implements SearchStrategy {
ArrayList<EntityProposals> entities;
private String elocatorphrase;
private String entityphrase;
private Element root;
private String structid;
private String prep;
private String originalentityphrase;
private static final Logger LOGGER = Logger.getLogger(EntityEntityLocatorStrategy.class);
//search results:
private ArrayList<EntityProposals> entitylps;
private ArrayList<EntityProposals> sentityps;
private static Hashtable<String, ArrayList<EntityProposals>> cache = new Hashtable<String, ArrayList<EntityProposals>>();
private static ArrayList<String> nomatchcache = new ArrayList<String>();
/**
*
*/
public EntityEntityLocatorStrategy(Element root, String structid,
String entityphrase, String elocatorphrase,
String originalentityphrase, String prep) {
this.elocatorphrase = elocatorphrase;
this.entityphrase = entityphrase;
this.root = root;
this.structid = structid;
this.prep = prep;
this.originalentityphrase = originalentityphrase;
LOGGER.debug("EntityEntityLocatorStrategy: search '"+entityphrase+"[orig="+originalentityphrase+"]'");
}
/* anterior margin of maxilla => anterior margin^part_of(maxilla)): entity = anterior margin, locator = maxilla
*/
@Override
public void handle() {
//search cache
if(EntityEntityLocatorStrategy.nomatchcache.contains(entityphrase+"+"+elocatorphrase)){
entities = null;
return;
}
if(EntityEntityLocatorStrategy.cache.get(entityphrase+"+"+elocatorphrase)!=null){
entities = EntityEntityLocatorStrategy.cache.get(entityphrase+"+"+elocatorphrase);
return;
}
//search entity and entity locator separately
String[] entitylocators = null;
if(elocatorphrase.length()>0) entitylocators = elocatorphrase.split("\\s*,\\s*");
//SimpleEntity entityl = new SimpleEntity();
//entityl.setString(elocatorphrase);
//ArrayList<EntityProposals> entitylps = new ArrayList<EntityProposals>();
//entitylp.setPhrase(elocatorphrase);
if(entitylocators!=null) {
//SimpleEntity result = (SimpleEntity) new TermSearcher().searchTerm(elocatorphrase, "entity");
ArrayList<EntityProposals> result = new EntitySearcherOriginal().searchEntity(root, structid, elocatorphrase, "", originalentityphrase, prep); //advanced search
if(result!=null){
entitylps = result;
LOGGER.debug("EEL...searched locator '"+elocatorphrase+"[orig="+originalentityphrase+"]':");
for(EntityProposals ep: result){
LOGGER.debug("....."+ep.toString());
}
}else{ //entity locator not matched
LOGGER.debug("EEL...no results from searching '"+elocatorphrase+"[orig="+originalentityphrase+"]':");
//TODO
}
}
//SimpleEntity sentity = (SimpleEntity)new TermSearcher().searchTerm(entityphrase, "entity");
sentityps = new EntitySearcherOriginal().searchEntity(root, structid, entityphrase, "", originalentityphrase, prep); //advanced search
if(sentityps!=null && entitylps!=null){//if entity matches
//entity
for(EntityProposals entitylp: entitylps){
if(entitylp.getPhrase().length()>0){
//LOGGER.debug("entity locator phrase is not empty, constructing composite entity...");
for(Entity entityl: entitylp.getProposals()){
//relation & entity locator
FormalRelation rel = Dictionary.partof;
rel.setConfidenceScore((float)1.0);
REntity rentity = new REntity(rel, entityl);
boolean confirmed = false;
EntityProposals confirmedcentityp = null;
EntityProposals centityp = null;
LOGGER.debug("EEL searched entity'"+entityphrase+"[orig="+originalentityphrase+"]':");
for(EntityProposals sentityp: sentityps){
LOGGER.debug("....."+sentityp.toString());
for(Entity sentity: sentityp.getProposals()){
SimpleEntity bspo = null;
//sentityps could be a spatial entity, so the final E need to be composed using the spatial convention of SpatialModifiedEntity.
if(sentity instanceof CompositeEntity && sentity.getPrimaryEntityID().contains("BSPO:")){
bspo = ((CompositeEntity)sentity).getTheSimpleEntity();
sentity = ((CompositeEntity)sentity).getEntityLocator().getEntity();
}
if(bspo!=null){//composition with a spatial entity
CompositeEntity ce = new CompositeEntity();
ce.addEntity(bspo);
ce.addEntity(rentity);
rentity = new REntity(rel, ce);
}
//check elk: can sentity be part of entityl? 'intermedium (fore)' is part of 'manus'
//if true for any proposal, return it
//otherwise, return all
if(XML2EQ.elk.isPartOf(sentity.getClassIRI(),entityl.getClassIRI()) || XML2EQ.elk.isSubclassOfWithPart(entityl.getClassIRI(),sentity.getClassIRI())){
confirmed = true;
}
//composite entity
CompositeEntity centity = new CompositeEntity();
centity.addEntity(sentity);
centity.addEntity(rentity);
centity.setString(this.originalentityphrase);
//EntityProposals entities = new EntityProposals();
//entities.setPhrase(sentityp.getPhrase());
//EntityProposals centityp = new EntityProposals();
//centityp.setPhrase(sentityp.getPhrase());
if(confirmed){
if(confirmedcentityp==null) confirmedcentityp = new EntityProposals();
confirmedcentityp.setPhrase(this.originalentityphrase);
//confirmedcentityp.add(centity); //no explicit composition needed
confirmedcentityp.add(sentity);
sentity.setConfidenceScore(1f);
confirmed = false;
LOGGER.debug("...confirmed:"+confirmedcentityp);
}else{
if(centityp==null) centityp = new EntityProposals();
centityp.setPhrase(this.originalentityphrase);
centityp.add(centity);
}
}
}
if(confirmedcentityp!=null){
entities = new ArrayList<EntityProposals>();
Utilities.addEntityProposals(entities, confirmedcentityp);
//LOGGER.debug("..composite entityproposals ="+confirmedcentityp.toString());
}
else if(centityp!=null){
entities = new ArrayList<EntityProposals>();
Utilities.addEntityProposals(entities, centityp);
//LOGGER.debug("..composite entityproposals ="+centityp.toString());
}
}
//caching
if(entities==null) EntityEntityLocatorStrategy.nomatchcache.add(entityphrase+"+"+elocatorphrase);
else EntityEntityLocatorStrategy.cache.put(entityphrase+"+"+elocatorphrase, entities);
if(entities!=null){
LOGGER.debug("EEL: results:");
for(EntityProposals ep: entities){
LOGGER.debug(".."+ep.toString());
}
return;
}
}else{
//LOGGER.debug("entity locator phrase is empty, saving simple entity as EntityProposals...");
//EntityProposals entities = new EntityProposals();
//entities = new EntityProposals();
//entities.setPhrase(sentityp.getPhrase());
//entities.add(sentityp.getProposals());
for(EntityProposals ep: sentityps){
ep.setPhrase(this.originalentityphrase+"["+ep.getPhrase()+"]");
if(entities==null) entities = new ArrayList<EntityProposals>();
Utilities.addEntityProposals(entities, ep);
//LOGGER.debug("..entityproposals ="+ep.toString());
}
//caching
if(entities==null) EntityEntityLocatorStrategy.nomatchcache.add(entityphrase+"+"+elocatorphrase);
else EntityEntityLocatorStrategy.cache.put(entityphrase+"+"+elocatorphrase, entities);
if(entities!=null){
LOGGER.debug("EEL: results:");
for(EntityProposals ep: entities){
LOGGER.debug(".."+ep.toString());
}
return;
}
}
}
}else{
LOGGER.debug("EntityEntityLocatorStrategy: no results for '"+entityphrase+"[orig="+originalentityphrase+"]':");
}
}
/**
* search result for entity (partial)
* @return
*/
public ArrayList<EntityProposals> getEntityResult() {
return this.sentityps;
}
/**
* search result for entity locator (partial)
* @return
*/
public ArrayList<EntityProposals> getEntityLocatorResult() {
return this.entitylps;
}
/**
* composite entities with entity and locator
* @return
*/
public ArrayList<EntityProposals> getEntities() {
return entities;
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}