package mediawiki.info.wikibase;
import java.util.ArrayList;
import java.util.Arrays;
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 mediawiki.JSONizable;
import mediawiki.MediaWikiUtil;
import mediawiki.XMLRepresented;
import mediawiki.info.HasProperty;
import javat.xml.Element;
public class Statement implements XMLRepresented, JSONizable, HasProperty {
private String id;
private ArrayList<Reference> references = new ArrayList<>();
private Claim claim;
private ArrayList<Qualifier> qualifiers = new ArrayList<>();
private Rank rank = Rank.NORMAL;
public Statement(String id) {
setID(id);
}
public Statement(Claim c) {
setClaim(c);
}
public Statement(Property p, Snak s) {
this(new Claim(p,s));
}
public Statement(Property p, Snak s, Reference...refs) {
this(p,s);
references.addAll(Arrays.asList(refs));
}
public Statement(Element e) throws Exception {
references = new ArrayList<>();
convert(e);
}
public String getID() {
return id;
}
public void setID(String id) {
this.id = id;
}
public void addReference(Reference r){
references.add(r);
}
public boolean hasReferences(){
return ! references.isEmpty();
}
public boolean hasReference(Property p){
if(! hasReferences())
return false;
for(Reference r : references)
for(Claim c : r)
if(c.getProperty().equals(p))
return true;
return false;
}
public boolean hasReference(Claim cl){
if(! hasReferences())
return false;
for(Reference r : references)
for(Claim c : r)
if(c.equals(cl))
return true;
return false;
}
public void addQualifier(Qualifier q){
qualifiers.add(q);
}
public boolean hasQualifiers(){
return ! qualifiers.isEmpty();
}
public boolean hasQualifier(Property p){
if(! hasQualifiers())
return false;
for(Qualifier r : qualifiers)
if(r.getProperty().equals(p))
return true;
return false;
}
public void convert(Element element) throws Exception { // ab claim
setID(element.getAttribute("id").getValue());
setRank(Rank.valueOf(element.getAttribute("rank").getValue().toUpperCase()));
if(element.getChildren("references").size() > 0){
for(Element e : element.getChildren("references").get(0).getChildren("reference")){
addReference(new Reference(e));
}
}
if(element.getChildren("qualifiers").size() > 0){
for(Element e : element.getChildren("qualifiers").get(0).getChildren("property")){
for(Element e2 : e.getChildren("qualifiers")){
addQualifier(new Qualifier(e2));
}
}
}
setClaim(new Claim(element.getChildren("mainsnak").get(0)));
}
public Claim getClaim() {
return claim;
}
public void setClaim(Claim snak) {
this.claim = snak;
}
public Rank getRank() {
return rank;
}
public void setRank(Rank rank) {
this.rank = rank;
}
@Override
public JSONObject toJSONObject() throws JSONException {
JSONObject o = new JSONObject();
if(getID() != null)
o.put("id", getID());
o.put("mainsnak", getClaim().toJSONObject());
o.put("type", "statement");
o.put("rank", getRank().name().toLowerCase());
if(references.size() > 0) {
JSONArray ref = new JSONArray();
for(Reference r : references)
ref.put(r.toJSONObject());
o.put("references", ref);
}
if(qualifiers.size() > 0) {
Map<Property, List<Qualifier>> m = MediaWikiUtil.groupByProperty(qualifiers);
JSONObject snaks = new JSONObject();
for(Entry<Property, List<Qualifier>> e : m.entrySet()){
JSONArray p = new JSONArray();
for(Qualifier c : e.getValue())
p.put(c.toJSONObject());
snaks.put("P"+e.getKey().getID(), p);
}
o.put("qualifiers", snaks);
JSONArray order = new JSONArray();
for(Property p : MediaWikiUtil.listByProperty(qualifiers))
order.put("P"+p.getID());
o.put("qualifiers-order", order);
}
return o;
}
@Override
public boolean equals(Object obj) {
if(obj == null)
return false;
if(!(obj instanceof Statement))
return false;
Statement s = (Statement) obj;
if(getID() != null && ! s.getID().equals(getID()))
return false;
if(! references.equals(s.references))
return false;
if(! qualifiers.equals(s.qualifiers))
return false;
if(! claim.equals(s.claim))
return false;
if(! rank.equals(s.rank))
return false;
return true;
}
@Override
public Property getProperty() {
return getClaim().getProperty();
}
}