org.wikidata.wdtk.datamodel.json.jackson.JacksonTermedStatementDocument.java Source code

Java tutorial

Introduction

Here is the source code for org.wikidata.wdtk.datamodel.json.jackson.JacksonTermedStatementDocument.java

Source

package org.wikidata.wdtk.datamodel.json.jackson;

/*
 * #%L
 * Wikidata Toolkit Data Model
 * %%
 * Copyright (C) 2014 Wikidata Toolkit Developers
 * %%
 * 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 java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.wikidata.wdtk.datamodel.interfaces.EntityIdValue;
import org.wikidata.wdtk.datamodel.interfaces.MonolingualTextValue;
import org.wikidata.wdtk.datamodel.interfaces.Statement;
import org.wikidata.wdtk.datamodel.interfaces.StatementDocument;
import org.wikidata.wdtk.datamodel.interfaces.StatementGroup;
import org.wikidata.wdtk.datamodel.interfaces.TermedDocument;
import org.wikidata.wdtk.util.NestedIterator;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonSubTypes.Type;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;

/**
 * Abstract Jackson implementation of {@link TermedDocument}. Like all Jackson
 * objects, it is not technically immutable, but it is strongly recommended to
 * treat it as such in all contexts: the setters are for Jackson; never call
 * them in your code.
 *
 * @author Fredo Erxleben
 *
 */
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
@JsonSubTypes({ @Type(value = JacksonItemDocument.class, name = JacksonTermedStatementDocument.JSON_TYPE_ITEM),
        @Type(value = JacksonPropertyDocument.class, name = JacksonTermedStatementDocument.JSON_TYPE_PROPERTY) })
public abstract class JacksonTermedStatementDocument implements TermedDocument, StatementDocument {

    /**
     * String used to refer to items in JSON.
     */
    public static final String JSON_TYPE_ITEM = "item";
    /**
     * String used to refer to properties in JSON.
     */
    public static final String JSON_TYPE_PROPERTY = "property";

    @JsonDeserialize(using = AliasesDeserializer.class)
    protected Map<String, List<JacksonMonolingualTextValue>> aliases = new HashMap<>();
    protected Map<String, JacksonMonolingualTextValue> labels = new HashMap<>();
    protected Map<String, JacksonMonolingualTextValue> descriptions = new HashMap<>();

    /**
     * This is what is called <i>claim</i> in the JSON model. It corresponds to
     * the statement group in the WDTK model.
     */
    private Map<String, List<JacksonStatement>> claims = new HashMap<>();

    /**
     * Statement groups. This member is initialized when statements are
     * accessed.
     */
    private List<StatementGroup> statementGroups = null;

    /**
     * The id of the entity that the document refers to. This is not mapped to
     * JSON directly by Jackson but split into two fields, "type" and "id". The
     * type field is ignored during deserialization since the type is clear for
     * a concrete document. For serialization, the type is hard-coded.
     * <p>
     * The site IRI, which would also be required to create a complete
     * {@link EntityIdValue}, is not encoded in JSON. It needs to be injected
     * from the outside (if not, we default to Wikidata).
     */
    protected String entityId = "";

    /**
     * The site IRI that this document refers to, or null if not specified. In
     * the latter case, we assume Wikidata as the default.
     *
     * @see EntityIdValue#getSiteIri()
     */
    @JsonIgnore
    protected String siteIri = null;

    /**
     * Constructor. Creates an empty object that can be populated during JSON
     * deserialization. Should only be used by Jackson for this very purpose.
     */
    public JacksonTermedStatementDocument() {
    }

    /**
     * Sets the aliases to the given value. Only for use by Jackson during
     * deserialization.
     *
     * @param aliases
     *            new value
     */
    public void setAliases(Map<String, List<JacksonMonolingualTextValue>> aliases) {
        this.aliases = aliases;
    }

    @Override
    public Map<String, List<MonolingualTextValue>> getAliases() {
        // because of the typing provided by the interface one has to
        // re-create the map anew, simple casting is not possible
        Map<String, List<MonolingualTextValue>> returnMap = new HashMap<>();

        for (Entry<String, List<JacksonMonolingualTextValue>> entry : this.aliases.entrySet()) {
            returnMap.put(entry.getKey(), Collections.<MonolingualTextValue>unmodifiableList(entry.getValue()));
        }

        return Collections.unmodifiableMap(returnMap);
    }

    /**
     * Sets the descriptions to the given value. Only for use by Jackson during
     * deserialization.
     *
     * @param descriptions
     *            new value
     */
    public void setDescriptions(Map<String, JacksonMonolingualTextValue> descriptions) {
        this.descriptions = descriptions;
    }

    @Override
    public Map<String, MonolingualTextValue> getDescriptions() {
        return Collections.<String, MonolingualTextValue>unmodifiableMap(this.descriptions);
    }

    /**
     * Sets the labels to the given value. Only for use by Jackson during
     * deserialization.
     *
     * @param labels
     *            new value
     */
    public void setLabels(Map<String, JacksonMonolingualTextValue> labels) {
        this.labels = labels;
    }

    @Override
    public Map<String, MonolingualTextValue> getLabels() {
        return Collections.<String, MonolingualTextValue>unmodifiableMap(this.labels);
    }

    /**
     * Sets the string id of the entity that this document refers to. Only for
     * use by Jackson during deserialization.
     *
     * @param id
     *            new value
     */
    @JsonProperty("id")
    public void setJsonId(String id) {
        this.entityId = id;
    }

    /**
     * Returns the string id of the entity that this document refers to. Only
     * for use by Jackson during serialization.
     *
     * @return string id
     */
    @JsonProperty("id")
    public String getJsonId() {
        return this.entityId;
    }

    /**
     * Sets the site iri to the given value. This can be used to inject
     * information about the site the object belongs to after the object is
     * constructed. This is needed since this information is not part of the
     * JSON serialization.
     *
     * @see EntityIdValue#getSiteIri()
     * @param siteIri
     *            the site IRI
     */
    @JsonIgnore
    public void setSiteIri(String siteIri) {
        this.siteIri = siteIri;

        EntityIdValue subject = this.getEntityId();

        for (Entry<String, List<JacksonStatement>> entry : this.claims.entrySet()) {
            for (JacksonStatement statement : entry.getValue()) {
                statement.setSubject(subject);
            }
        }
    }

    @JsonIgnore
    public String getSiteIri() {
        return this.siteIri;
    }

    @JsonIgnore
    @Override
    public List<StatementGroup> getStatementGroups() {
        if (this.statementGroups == null) {
            this.statementGroups = new ArrayList<>(this.claims.size());
            for (List<JacksonStatement> statements : this.claims.values()) {
                this.statementGroups.add(new StatementGroupFromJson(statements));
            }
        }
        return this.statementGroups;
    }

    /**
     * Sets the "claims" to the given value. Only for use by Jackson during
     * deserialization.
     * <p>
     * The name refers to the JSON model, where claims are similar to statement
     * groups. This should not be confused with claims as used in the WDTK data
     * model. This will probably only be used by the Jacksons' ObjectMapper.
     *
     * @param claims
     */
    @JsonProperty("claims")
    public void setJsonClaims(Map<String, List<JacksonStatement>> claims) {
        this.claims = claims;
        this.statementGroups = null; // clear cache
    }

    /**
     * Returns the "claims". Only used by Jackson.
     * <p>
     * JSON "claims" correspond to statement groups in the WDTK model. You
     * should use {@link JacksonItemDocument#getStatementGroups()} to obtain
     * this data.
     *
     * @return map of statement groups
     */
    @JsonProperty("claims")
    public Map<String, List<JacksonStatement>> getJsonClaims() {
        return this.claims;
    }

    @Override
    @JsonIgnore
    public Iterator<Statement> getAllStatements() {
        return new NestedIterator<>(this.getStatementGroups());
    }

}