package mediawiki.info.wikibase;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import javat.xml.Element;
import mediawiki.JSONizable;
import mediawiki.MediaWikiUtil;
import mediawiki.XMLRepresented;
import mediawiki.info.Language;
import mediawiki.info.Project;
public class Entity implements XMLRepresented, JSONizable {
private Integer lastRevID = null;
private String id = null;
private ArrayList<Statement> statements = new ArrayList<>();
private TranslatedContent<String> labels = new TranslatedContent<>();
private TranslatedContent<String> descriptions = new TranslatedContent<>();
private TranslatedContent<ArrayList<String>> aliases = new TranslatedContent<>();
private ArrayList<Sitelink> sitelinks = new ArrayList<>();
public Entity() {
}
public Entity(Element e) throws Exception {
this();
convert(e);
}
@Override
public void convert(Element element) throws Exception {
if(element.getAttribute("missing") != null)
throw new NullPointerException("entity "+element.getAttribute("id").getValue()+" is missing");
setLastRevID(Integer.parseInt(element.getAttribute("lastrevid").getValue()));
setID(element.getAttribute("id").getValue());
if(element.getChildren("labels").size() == 1){
Element ls = element.getChildren("labels").get(0);
for(Element label : ls.getChildren("label")) {
labels.put(new Language(label.getAttribute("language").getValue()), label.getAttribute("value").getValue());
}
}
if(element.getChildren("descriptions").size() == 1){
Element ls = element.getChildren("descriptions").get(0);
for(Element label : ls.getChildren("description")) {
descriptions.put(new Language(label.getAttribute("language").getValue()), label.getAttribute("value").getValue());
}
}
if(element.getChildren("aliases").size() == 1){
Element as = element.getChildren("aliases").get(0);
for(Element lang : as.getChildren("language")){
ArrayList<String> ls = new ArrayList<>();
for(Element a : lang.getChildren("alias")) {
ls.add(a.getAttribute("value").getValue());
}
aliases.put(new Language(lang.getAttribute("id").getValue()), ls);
}
}
if(element.getChildren("claims").size() == 1){
Element c = element.getChildren("claims").get(0);
for(Element p : c.getChildren("property")){
for(Element s : p.getChildren("claim")) {
statements.add(new Statement(s));
}
}
}
if(element.getChildren("sitelinks").size() == 1){
Element s = element.getChildren("sitelinks").get(0);
for(Element sitelink : s.getChildren("sitelink")) {
sitelinks.add(new Sitelink(sitelink));
}
}
}
public Integer getLastRevID() {
return lastRevID;
}
public void setLastRevID(int lastRevID) {
this.lastRevID = lastRevID;
}
public String getID() {
return id;
}
public void setID(String id) {
this.id = id;
}
@Override
public JSONObject toJSONObject() throws JSONException {
JSONObject o = new JSONObject();
{
JSONObject l = new JSONObject();
for(Entry<Language, String> e : labels){
JSONObject a = new JSONObject();
a.put("language", e.getKey().getName());
a.put("value", e.getValue());
l.put(e.getKey().getName(), a);
}
o.put("labels", l);
}
{
JSONObject l = new JSONObject();
for(Entry<Language, ArrayList<String>> e : aliases){
JSONArray a = new JSONArray();
for(String al : e.getValue()) {
JSONObject a2 = new JSONObject();
a2.put("language", e.getKey().getName());
a2.put("value", al);
a.put(a2);
}
l.put(e.getKey().getName(), a);
}
o.put("aliases", l);
}
{
JSONObject l = new JSONObject();
for(Entry<Language, String> e : descriptions){
JSONObject a = new JSONObject();
a.put("language", e.getKey().getName());
a.put("value", e.getValue());
l.put(e.getKey().getName(), a);
}
o.put("descriptions", l);
}
{
Map<Property, List<Statement>> m = MediaWikiUtil.groupByProperty(statements);
JSONObject claims = new JSONObject();
for(Entry<Property, List<Statement>> e : m.entrySet()){
JSONArray p = new JSONArray();
for(Statement c : e.getValue())
p.put(c.toJSONObject());
claims.put("P"+e.getKey().getID(), p);
}
o.put("claims", claims);
}
{
JSONObject l = new JSONObject();
for(Sitelink s : sitelinks){
JSONObject a = new JSONObject();
a.put("site", s.getProject().getSite());
a.put("title", s.getTitle());
a.put("badges", new JSONArray(s.getBadges()));
l.put(s.getProject().getSite(), a);
}
o.put("sitelinks", l);
}
return o;
}
public boolean hasStatement(Property p){
for(Statement s : statements)
if(s.getClaim().getProperty().equals(p))
return true;
return false;
}
public boolean hasStatement(Statement s){
for(Statement ss : statements)
if(ss.equals(s))
return true;
return false;
}
public void addStatement(Statement s){
statements.add(s);
}
public void addStatement(Property p, Snak s) {
addStatement(new Statement(p,s));
}
public List<Statement> getStatements(Property p) {
ArrayList<Statement> s = new ArrayList<>();
for(Statement st : statements)
if(st.getClaim().getProperty().equals(p))
s.add(st);
return s;
}
public void putLabel(Language l, String s){
labels.put(l, s);
}
public boolean hasLabel(Language l){
return labels.containsKey(l);
}
public String getLabel(Language l){
return labels.get(l);
}
public void putDescription(Language l, String s){
descriptions.put(l, s);
}
public boolean hasDescription(Language l){
return descriptions.containsKey(l);
}
public String getDescription(Language l){
return descriptions.get(l);
}
public void addAlias(Language l, String a) {
if(! aliases.containsKey(l))
aliases.put(l, new ArrayList<String>());
aliases.get(l).add(a);
}
public boolean hasAlias(Language l){
return aliases.containsKey(l);
}
public boolean hasAlias(Language l, String a) {
if(! hasAlias(l))
return false;
return getAliases(l).contains(a);
}
public List<String> getAliases(Language l){
return aliases.get(l);
}
public boolean hasSitelink(Project p) {
for(Sitelink s: sitelinks)
if(s.getProject().equals(p))
return true;
return false;
}
public void addSitelink(Sitelink s){
if(hasSitelink(s.getProject()))
throw new IllegalArgumentException("this entity has already a sitelink for "+s.getProject().getSite());
sitelinks.add(s);
}
public void putSitelink(Sitelink s){
for(int i = 0; i < sitelinks.size(); i++){
if(sitelinks.get(i).getProject().equals(s.getProject())){
sitelinks.set(i, s);
return;
}
}
sitelinks.add(s);
}
public void addSitelink(Project p, String t) {
addSitelink(new Sitelink(p,t));
}
}