package com.cyc.tool.kbtaxonomy.builder;
/*
* #%L
* KBTaxonomyGeneral
* %%
* Copyright (C) 2015 Cycorp, Inc
* %%
* 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.
* #L%
*/
import com.cyc.library.json.JSONBuilder;
import static com.cyc.tool.kbtaxonomy.builder.KBConcept.addToLists;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.SocketException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* <p>
* NonCycConcept is a type of KBConcept that is not in OpenCyc.
*
*/
public class NonCycConcept extends KBConcept {
/**
* Map from Integer to NonCycConcept to track teamIDs
*/
static protected final Map<Integer, NonCycConcept> teamIDsToConcepts = new HashMap<>();
List<String> nonCycConceptWNIDs;
List<Integer> nonCycTeamNumericID;
Float weight = null;
/**
* NonCycConcept constructor
*
* @param conceptCycL
* @param nonCycTeamConceptID
* @param conceptName
* @param conceptUri
* @param nonCycConceptWNIDs
*/
public NonCycConcept(String conceptCycL, List<Integer> nonCycTeamConceptID, String conceptName, String conceptUri, List<String> nonCycConceptWNIDs) {
super(conceptCycL, conceptUri);
nonCycTeamNumericID = nonCycTeamConceptID;
this.nonCycConceptWNIDs = nonCycConceptWNIDs;
this.nlNames = new HashSet<>();
this.nlNames.add(conceptName);
setExpanded();
// this.setSelected( (Math.random()>0.5));
}
/**
* Factory method to create a new NonCycConcept object
*
* @param kbTaxonomyCycConceptTerm
* @param nonCycTeamConceptID
* @param conceptName
* @param conceptUri
* @param nonCycConceptWNIDs
* @return a NonCycConcept
*/
public static NonCycConcept create(String kbTaxonomyCycConceptTerm, List<Integer> nonCycTeamConceptID, String conceptName, String conceptUri, List<String> nonCycConceptWNIDs) {
if (haveConcept(kbTaxonomyCycConceptTerm)) {
return (NonCycConcept) getConcept(kbTaxonomyCycConceptTerm);
}
assert (kbTaxonomyCycConceptTerm.startsWith("NonCycConcept")) :
"Attempt to create NonCyc Concept for non-NonCyc term " + kbTaxonomyCycConceptTerm;
NonCycConcept created = new NonCycConcept(kbTaxonomyCycConceptTerm, nonCycTeamConceptID, conceptName, conceptUri, nonCycConceptWNIDs);
addToLists(created);
for (Integer id : nonCycTeamConceptID) {
teamIDsToConcepts.put(id, created);
}
// teamIDsToConcepts.put(nonCycTeamConceptID, created);
return created;
}
/**
* Factory method to create a new NonCycConcept object
*
* @param kbTaxonomyCycConceptTerm
* @param nonCycTeamConceptID
* @param conceptName
* @param conceptUri
* @return a NonCycConcept
*/
public static NonCycConcept create(String kbTaxonomyCycConceptTerm, List<Integer> nonCycTeamConceptID, String conceptName, String conceptUri) {
if (haveConcept(kbTaxonomyCycConceptTerm)) {
return (NonCycConcept) getConcept(kbTaxonomyCycConceptTerm);
}
assert (kbTaxonomyCycConceptTerm.startsWith("NonCycConcept")) :
"Attempt to create NonCyc Concept for non-NonCyc term " + kbTaxonomyCycConceptTerm;
NonCycConcept created = new NonCycConcept(kbTaxonomyCycConceptTerm, nonCycTeamConceptID, conceptName, conceptUri, new ArrayList<>());
addToLists(created);
nonCycTeamConceptID.forEach(id -> {
teamIDsToConcepts.put(id, created);
});
// teamIDsToConcepts.put(nonCycTeamConceptID, created);
return created;
}
/**
* Returns a NonCycConcept based on its index
*
* @param index
* @return a NonCycConcept
*/
public static NonCycConcept getByIndex(int index) {
KBConcept fetched = allConceptTable.get(index);
if (fetched instanceof NonCycConcept) {
return (NonCycConcept) fetched;
} else {
throw new RuntimeException("Tried to fetch concept " + index + " -> "
+ fetched + " as " + NonCycConcept.class.getCanonicalName() + " when it isn't");
// return null;
}
}
/**
* Returns a NonCycConcept based on its teamID
*
* @param teamID
* @return a NonCycConcept
*/
public static NonCycConcept getFromID(int teamID) {
return teamIDsToConcepts.get(teamID);
}
/**
* Returns a NonCycConcept based on its teamID, name, and conceptUri
*
* @param teamID
* @param name
* @param conceptUri
* @return a NonCycConcept
*/
public static NonCycConcept getFromIDNameOpt(int teamID, String name, String conceptUri) {
if (!teamIDsToConcepts.containsKey(teamID)) {
System.out.println("FAKING " + teamID + "-" + name);
List<Integer> teamIDs = new ArrayList<>();
teamIDs.add(teamID);
NonCycConcept ret = create("NonCycConcept-Fake" + teamID + "-" + name, teamIDs, name, conceptUri);
ret.setSelected();
return ret;
}
return getFromID(teamID);
}
/**
*
* @param concepts NonCycConcepts to check for more details
* @return HTML to display information about a NonCycConept in the graph
*/
public static String generateHtmlForConcept(Set<NonCycConcept> concepts) {
String html = "";
Set<String> conceptNames = new HashSet<>();
Set<String> imageLinks = new HashSet<>();
for (NonCycConcept c : concepts) {
conceptNames.add(c.getName());
Set<String> pics = new HashSet<>();
if (c.getNonCycConceptWNIDs() != null) {
pics = c.selectPicsForConcept(c.getNonCycConceptWNIDs());
}
imageLinks.addAll(pics);
}
// String constantName = getName();
// Set<String> pics = selectPicsForConcept(getNonCycConceptWNIDs());
html += "<h1>" + conceptNames.toString().replaceFirst("\\[", "").replaceFirst("\\]", "") + "</h1>\n\n";
// TEST
// html += "<img src=\"http://www.sci-spot.com/truck/elocker/drain.jpg\" height=\"60\" width=\"60\">";
// html += "\n";
if (imageLinks.isEmpty()) {
html += "No additional information available";
} else {
Set<String> picLinks = new HashSet<>();
for (String p : imageLinks) {
try {
URL imageLinkUrl = new URL(p);
URLConnection con = imageLinkUrl.openConnection();
InputStream is = con.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
while (picLinks.size() < 3) {
String picUrlString = br.readLine();
try {
URL picUrl = new URL(picUrlString);
HttpURLConnection huc = (HttpURLConnection) picUrl.openConnection();
huc.setRequestMethod("GET");
huc.connect();
if (huc.getResponseCode() == 200) {
picLinks.add(picUrlString);
}
} catch (MalformedURLException | SocketException ex) {
Logger.getLogger(NonCycConcept.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(NonCycConcept.class.getName()).log(Level.SEVERE, null, ex);
}
}
} catch (MalformedURLException ex) {
Logger.getLogger(NonCycConcept.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(NonCycConcept.class.getName()).log(Level.SEVERE, null, ex);
}
}
// html += "Sample images:";
// html += "<ul>\n";
for (String p : picLinks) {
html += "<img src=\"" + p + "\" height=\"90\" width=\"90\"> ";
}
html += "</ul>\n";
}
return html;
}
@Override
public final String getName() {
if (getNlNames().isEmpty()) {
return "Au#:" + getConceptCycL();
} else if (getNlNames().size() == 1) {
return String.join("", getNlNames());
} else {
StringBuilder allNames = new StringBuilder();
return ("Au:[" + String.join("/", getNlNames()) + "]");
}
}
/**
*
* @return nonCycConceptWNIDs
*/
public List<String> getNonCycConceptWNIDs() {
return nonCycConceptWNIDs;
}
/**
*
* @return nonCycTeamNumericID
*/
public List<Integer> getNonCycTeamNumericID() {
return nonCycTeamNumericID;
}
/**
*
* @return weight
*/
public float getWeight() {
if (weight == null) {
return 0;
}
return weight;
}
/**
* Setter for weight field
*
* @param mWeight
*/
public void setWeight(float mWeight) {
this.weight = mWeight;
}
/**
*
* @return true if weight is not null
*/
public boolean hasWeight() {
return weight != null;
}
@Deprecated
@Override
public String toD3JSON(int depth, KBConcept.GraphDirection dir) {
return toD3JSON(depth, 100, dir);
}
@Override
public String toD3JSON(int depth, int depthLimit, KBConcept.GraphDirection direction) {
switch (direction) {
case down:
return toD3JSONDown(depth, depthLimit);
case up:
return toD3JSONUp(depth, depthLimit);
default:
return "";
}
}
@Override
public String toD3JSON(int depth) {
List<String> fields = new ArrayList<>();
fields.add(JSONBuilder.fieldStringValuePair("type", "nonCycTeamConcept"));
//if (nonCycTeamNumericID >=0 ){
// fields.add(JSONBuilder.fieldValuePair("nonCycTeamConceptID", nonCycTeamNumericID));
// }
// fields.add(JSONBuilder.fieldStringValuePair("kbTaxonomyCycConceptTerm", conceptCycL));
if (getNlNames().size() == 1) {
fields.add(JSONBuilder.fieldStringValuePair(
"name", (new ArrayList<>(getNlNames())).get(0)));
} else {
System.out.println("*** Problem: NonCyc Concepts should have one NL .. "
+ getNlNames() + "was found for " + this);
}
return JSONBuilder.object(fields);
}
@Override
public String toD3JSONNoRecursion(NonTaxonomicLink forLink) { //NB Forced to be a part for now
List<String> fields = new ArrayList<>();
System.out.println(this + "A " + forLink.getLinkTypeName() + " -- " + forLink.getLinkColour());
fields.add(JSONBuilder.fieldStringValuePair("linkType", forLink.getLinkTypeName()));
fields.add(JSONBuilder.fieldStringValuePair("linkColour", forLink.getLinkColour()));
if (getNlNames().size() == 1) {
fields.add(JSONBuilder.fieldStringValuePair(
"name", (new ArrayList<>(getNlNames())).get(0)));
} else {
System.out.println("*** Problem: NonCyc Concepts should have one NL .. "
+ getNlNames() + "was found for " + this);
}
fields.add(JSONBuilder.fieldStringValuePair("type", "nonCycTeamConcept"));
fields.add(JSONBuilder.fieldValuePair("activeconcept", this.isSelected()));
fields.add(JSONBuilder.fieldStringValuePair("displayedConceptID", getRef()));
// fields.add(JSONBuilder.fieldStringValuePair("nonCycTeamConceptID", Integer.toString(getNonCycTeamNumericID())));
if (nonCycTeamNumericID != null) {
fields.add(JSONBuilder.fieldValuePair("nonCycTeamConceptID", nonCycTeamNumericID.toString()));
}
// fields.add(JSONBuilder.fieldValuePair("nonCycConceptWNID", JSONBuilder.arrayOfString(getNonCycConceptWNIDs())));
if (nonCycConceptWNIDs != null) {
fields.add(JSONBuilder.fieldValuePair("nonCycConceptWNID", JSONBuilder.arrayOfString(nonCycConceptWNIDs)));
}
return JSONBuilder.object(fields);
}
@Override
public String toJSON(int depth, KBConcept.GraphDirection dir) {
return toJSON(depth);
}
public String toJSON(int depth) {
return toJSONNoRecursion();
}
@Override
public String toJSONNoRecursion() {
List<String> fields = new ArrayList<>();
fields.add(JSONBuilder.fieldValuePair("printSequence", printNumber++));
fields.add(JSONBuilder.fieldStringValuePair("type", "nonCycTeamConcept"));
// if (nonCycTeamNumericID >= 0) {
// fields.add(JSONBuilder.fieldValuePair("nonCycTeamConceptID", nonCycTeamNumericID));
// }
if (nonCycTeamNumericID != null) {
fields.add(JSONBuilder.fieldValuePair("nonCycTeamConceptID", nonCycTeamNumericID.toString()));
}
if (nonCycConceptWNIDs != null) {
fields.add(JSONBuilder.fieldValuePair("nonCycConceptWNID", JSONBuilder.arrayOfString(nonCycConceptWNIDs)));
}
// fields.add(JSONBuilder.fieldValuePair("nonCycConceptWNID", JSONBuilder.arrayOfString(getNonCycConceptWNIDs())));
fields.add(JSONBuilder.fieldStringValuePair("kbTaxonomyCycConceptTerm", getConceptCycL()));
if (getNlNames().size() == 1) {
fields.add(JSONBuilder.fieldStringValuePair(
"conceptName", (new ArrayList<>(getNlNames())).get(0)));
} else {
System.out.println("*** Problem: NonCyc Concepts should have one NL .. "
+ getNlNames() + "was found for " + this);
}
return JSONBuilder.object(fields);
}
@Override
public String toString() {
return "NonCyc " + super.toString() + " NumericID:" + nonCycTeamNumericID;
}
@Override
protected Set<KBLink> getChildSpecLinks() {
return childSpecLinks;
}
@Override
public Set<KBConcept> getChildren() {
return children;
}
@Override
protected Set<NonTaxonomicLink> getNonTaxonomicLinks() {
return nonTaxonomicLinks;
}
@Override
protected Set<TaxonomicLink> getParentlinks() {
return parentLinks;
}
@Override
protected Set<KBConcept> getParents() {
return parents;
}
@Override
final protected void setChildren() {
if (!isExpanded()) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}
@Override
protected void setChildrenLinks() {
if (!isExpanded()) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}
@Override
protected final void setParentLinks() {
if (!isExpanded()) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}
@Override
protected final void setParents() {
if (!isExpanded()) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}
private Set<String> selectPicsForConcept(List<String> nonCycConceptWNIDs) {
Set<String> picUrls = new HashSet<>();
for (String w : nonCycConceptWNIDs) {
picUrls.add("http://www.image-net.org/api/text/imagenet.synset.geturls?wnid=" + w);
}
return picUrls;
}
private String toD3JSONDown(int depth, int depthLimit) {
List<String> fields = new ArrayList<>();
fields.add(JSONBuilder.fieldStringValuePair("type", "nonCycTeamConcept"));
fields.add(JSONBuilder.fieldValuePair("activeconcept", this.isSelected()));
fields.add(JSONBuilder.fieldStringValuePair("displayedConceptID", getRef()));
// fields.add(JSONBuilder.fieldStringValuePair("nonCycTeamConceptID", Integer.toString(getNonCycTeamNumericID())));
if (nonCycTeamNumericID != null) {
fields.add(JSONBuilder.fieldValuePair("nonCycTeamConceptID", nonCycTeamNumericID.toString()));
}
// fields.add(JSONBuilder.fieldValuePair("nonCycConceptWNID", JSONBuilder.arrayOfString(getNonCycConceptWNIDs())));
if (nonCycConceptWNIDs != null) {
fields.add(JSONBuilder.fieldValuePair("nonCycConceptWNID", JSONBuilder.arrayOfString(nonCycConceptWNIDs)));
}
//if (nonCycTeamNumericID >=0 ){
// fields.add(JSONBuilder.fieldValuePair("nonCycTeamConceptID", nonCycTeamNumericID));
// }
// fields.add(JSONBuilder.fieldStringValuePair("kbTaxonomyCycConceptTerm", conceptCycL));
if (getNlNames().size() == 1) {
fields.add(JSONBuilder.fieldStringValuePair(
"name", (new ArrayList<>(getNlNames())).get(0)));
} else {
System.out.println("*** Problem: NonCyc Concepts should have one NL .. "
+ getNlNames() + "was found for " + this);
}
return JSONBuilder.object(fields);
}
private String toD3JSONUp(int depth, int depthLimit) {
List<String> fields = new ArrayList<>();
//System.out.println("NonCyc UP:"+this);
fields.add(JSONBuilder.fieldStringValuePair("type", "nonCycTeamConcept"));
fields.add(JSONBuilder.fieldValuePair("activeconcept", this.isSelected()));
fields.add(JSONBuilder.fieldValuePair("isParent", true));
fields.add(JSONBuilder.fieldStringValuePair("displayedConceptID", getRef()));
// fields.add(JSONBuilder.fieldStringValuePair("nonCycTeamConceptID", Integer.toString(getNonCycTeamNumericID())));
if (nonCycTeamNumericID != null) {
fields.add(JSONBuilder.fieldValuePair("nonCycTeamConceptID", nonCycTeamNumericID.toString()));
}
// fields.add(JSONBuilder.fieldValuePair("nonCycConceptWNID", JSONBuilder.arrayOfString(getNonCycConceptWNIDs())));
if (nonCycConceptWNIDs != null) {
fields.add(JSONBuilder.fieldValuePair("nonCycConceptWNID", JSONBuilder.arrayOfString(nonCycConceptWNIDs)));
}
//if (nonCycTeamNumericID >=0 ){
// fields.add(JSONBuilder.fieldValuePair("nonCycTeamConceptID", nonCycTeamNumericID));
// }
// fields.add(JSONBuilder.fieldStringValuePair("kbTaxonomyCycConceptTerm", conceptCycL));
if (getNlNames().size() == 1) {
fields.add(JSONBuilder.fieldStringValuePair(
"name", (new ArrayList<>(getNlNames())).get(0)));
} else {
System.out.println("*** Problem: NonCyc Concepts should have one NL .. "
+ getNlNames() + "was found for " + this);
}
if (!getParentlinks().isEmpty() && (depth < depthLimit)) {
List<String> parentJSON = new ArrayList<>();
for (TaxonomicLink p : getParentlinks()) {
parentJSON.add(p.getTo().toD3JSON(depth + 1, depthLimit, KBConcept.GraphDirection.up));
}
fields.add(JSONBuilder.fieldValuePair("children",
JSONBuilder.array(parentJSON)));
}
return JSONBuilder.object(fields);
}
}