All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.obolibrary.oboformat.model.Frame Maven / Gradle / Ivy

Go to download

A java library for converting obo format documents to OWL, and for converting (a subset of) OWL to obo format. This version has been slightly modified to be included directly in the OWL API. The upstream code for this module and its authors can be found at https://code.google.com/p/oboformat/.

There is a newer version: 5.5.1
Show newest version
package org.obolibrary.oboformat.model;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.obolibrary.obo2owl.OboInOwlCardinalityTools;
import org.obolibrary.oboformat.parser.OBOFormatConstants.OboFormatTag;

/** The Class Frame. */
public class Frame {

    /** The Enum FrameType. */
    public enum FrameType {
        /** HEADER. */
        HEADER, /** TERM. */
        TERM, /** TYPEDEF. */
        TYPEDEF, /** INSTANCE. */
        INSTANCE, /** ANNOTATION. */
        ANNOTATION
    }

    /** The clauses. */
    protected Collection clauses;
    /** The id. */
    protected String id;
    /** The type. */
    protected FrameType type;

    /** Instantiates a new frame. */
    public Frame() {
        init();
    }

    /**
     * Instantiates a new frame.
     * 
     * @param type
     *        the type
     */
    public Frame(FrameType type) {
        init();
        this.type = type;
    }

    /** Init clauses. */
    protected final void init() {
        clauses = new ArrayList<>();
    }

    /**
     * freezing a frame signals that a frame has become quiescent, and that data structures can be adjusted to
     * increase performance or reduce memory consumption. If a frozen frame is subsequently modified it will be thawed
     * as necessary.
     */
    public void freeze() {
        if (clauses.isEmpty()) {
            clauses = Collections.emptyList();
            return;
        }

        for (Clause clause : clauses) {
            clause.freeze();
        }

        if (clauses.size() == 1) {
            clauses = Collections.singletonList(clauses.iterator().next());
            return;
        }

        if (clauses instanceof ArrayList) {
            ArrayList arrayList = (ArrayList) clauses;
            arrayList.trimToSize();
        }

    }

    /**
     * @return the type
     */
    public FrameType getType() {
        return type;
    }

    /**
     * @param type
     *        the new type
     */
    public void setType(FrameType type) {
        this.type = type;
    }

    /**
     * @return the id
     */
    public String getId() {
        return id;
    }

    /**
     * @param id
     *        the new id
     */
    public void setId(String id) {
        this.id = id;
    }

    /**
     * @return the clauses
     */
    public Collection getClauses() {
        return clauses;
    }

    /**
     * @param tag
     *        the tag
     * @return the clauses for tag
     */
    @Nonnull
    public Collection getClauses(String tag) {
        Collection cls = new ArrayList<>();
        for (Clause cl : clauses) {
            if (cl.getTag().equals(tag)) {
                cls.add(cl);
            }
        }
        return cls;
    }

    /**
     * @param tag
     *        the tag
     * @return the clauses for tag
     */
    @Nonnull
    public Collection getClauses(@Nonnull OboFormatTag tag) {
        return getClauses(tag.getTag());
    }

    /**
     * @param tag
     *        the tag
     * @return null if no value set, otherwise first value
     */
    @Nullable
    public Clause getClause(String tag) {
        for (Clause cl : clauses) {
            if (cl.getTag().equals(tag)) {
                return cl;
            }
            // TODO - throw exception if more than one clause of this type?
        }
        return null;
    }

    /**
     * @param tag
     *        the tag
     * @return the clause for tag
     */
    @Nullable
    public Clause getClause(@Nonnull OboFormatTag tag) {
        return getClause(tag.getTag());
    }

    /**
     * @param clauses
     *        the new clauses
     */
    public void setClauses(Collection clauses) {
        this.clauses = clauses;
    }

    /**
     * @param cl
     *        the clause
     */
    public void addClause(Clause cl) {
        if (!(clauses instanceof ArrayList)) {
            Collection tmp  = new ArrayList<>(clauses.size()+1);
            tmp.addAll(clauses);
            clauses = tmp;
        }
        clauses.add(cl);
    }

    @Override
    public String toString() {
        StringBuffer sb = new StringBuffer();
        sb.append("Frame(");
        sb.append(id);
        sb.append(' ');
        for (Clause cl : clauses) {
            sb.append(cl);
        }
        sb.append(')');
        String string = sb.toString();
        assert string != null;
        return string;
    }

    /**
     * @param tag
     *        the tag
     * @return the tag value for tag
     */
    @Nullable
    public Object getTagValue(String tag) {
        Clause clause = getClause(tag);
        if (clause == null) {
            return null;
        }
        return clause.getValue();
    }

    /**
     * @param tag
     *        the tag
     * @return the tag value for tag
     */
    @Nullable
    public Object getTagValue(@Nonnull OboFormatTag tag) {
        return getTagValue(tag.getTag());
    }

    /**
     * @param 
     *        the generic type
     * @param tag
     *        the tag
     * @param cls
     *        the cls
     * @return the tag value for tag and class
     */
    @SuppressWarnings("null")
    @Nullable
    public  T getTagValue(String tag, @Nonnull Class cls) {
        if (getClause(tag) == null) {
            return null;
        }
        Object value = getClause(tag).getValue();
        if (value != null && value.getClass().isAssignableFrom(cls)) {
            return cls.cast(value);
        }
        return null;
    }

    /**
     * @param 
     *        the generic type
     * @param tag
     *        the tag
     * @param cls
     *        the cls
     * @return the tag value for tag and class
     */
    @Nullable
    public  T getTagValue(@Nonnull OboFormatTag tag, @Nonnull Class cls) {
        return getTagValue(tag.getTag(), cls);
    }

    /**
     * @param tag
     *        the tag
     * @return the tag values for tag
     */
    @Nonnull
    public Collection getTagValues(@Nonnull OboFormatTag tag) {
        return getTagValues(tag.getTag());
    }

    /**
     * @param tag
     *        the tag
     * @return the tag values for tag
     */
    @Nonnull
    public Collection getTagValues(String tag) {
        Collection vals = new ArrayList<>();
        for (Clause c : getClauses(tag)) {
            vals.add(c.getValue());
        }
        return vals;
    }

    /**
     * @param 
     *        the generic type
     * @param tag
     *        the tag
     * @param cls
     *        the cls
     * @return the tag values for tag and class
     */
    @Nonnull
    public  Collection getTagValues(@Nonnull OboFormatTag tag, @Nonnull Class cls) {
        return getTagValues(tag.getTag(), cls);
    }

    /**
     * @param 
     *        the generic type
     * @param tag
     *        the tag
     * @param cls
     *        the cls
     * @return the tag values for tag and class
     */
    @Nonnull
    public  Collection getTagValues(String tag, @Nonnull Class cls) {
        Collection vals = new ArrayList<>();
        for (Clause c : getClauses(tag)) {
            vals.add(c.getValue(cls));
        }
        return vals;
    }

    /**
     * @param tag
     *        the tag
     * @return the tag xrefs for tg
     */
    @SuppressWarnings("null")
    @Nonnull
    public Collection getTagXrefs(String tag) {
        Collection xrefs = new ArrayList<>();
        for (Object ob : getClause(tag).getValues()) {
            if (ob instanceof Xref) {
                xrefs.add((Xref) ob);
            }
        }
        return xrefs;
    }

    /**
     * @return the tags
     */
    @Nonnull
    public Set getTags() {
        Set tags = new HashSet<>();
        for (Clause cl : getClauses()) {
            tags.add(cl.getTag());
        }
        return tags;
    }

    /**
     * @param extFrame
     *        the external frame
     * @throws FrameMergeException
     *         the frame merge exception
     */
    public void merge(@Nonnull Frame extFrame) throws FrameMergeException {
        if (this == extFrame) {
            return;
        }
        if (!extFrame.getId().equals(getId())) {
            throw new FrameMergeException("ids do not match");
        }
        if (!extFrame.getType().equals(getType())) {
            throw new FrameMergeException("frame types do not match");
        }
        for (Clause c : extFrame.getClauses()) {
            addClause(c);
        }
        // note we do not perform a document structure check at this point
    }

    /**
     * Check this frame for violations, i.e. cardinality constraint violations.
     * 
     * @throws FrameStructureException
     *         the frame structure exception
     * @see OboInOwlCardinalityTools for equivalent checks in OWL
     */
    @SuppressWarnings("null")
    public void check() throws FrameStructureException {
        if (FrameType.HEADER.equals(type)) {
            checkMaxOneCardinality(OboFormatTag.TAG_ONTOLOGY, OboFormatTag.TAG_FORMAT_VERSION, OboFormatTag.TAG_DATE,
                OboFormatTag.TAG_DEFAULT_NAMESPACE, OboFormatTag.TAG_SAVED_BY, OboFormatTag.TAG_AUTO_GENERATED_BY);
        }
        if (FrameType.TYPEDEF.equals(type)) {
            checkMaxOneCardinality(OboFormatTag.TAG_DOMAIN, OboFormatTag.TAG_RANGE, OboFormatTag.TAG_IS_METADATA_TAG,
                OboFormatTag.TAG_IS_CLASS_LEVEL_TAG);
        }
        if (!FrameType.HEADER.equals(getType())) {
            if (getClauses(OboFormatTag.TAG_ID).size() != 1) {
                throw new FrameStructureException(this, "cardinality of id field must be 1");
            }
            if (getClause(OboFormatTag.TAG_ID).getValue() == null) {
                throw new FrameStructureException(this, "id field must not be null");
            }
            if (getId() == null) {
                throw new FrameStructureException(this, "id field must be set");
            }
        }
        Collection iClauses = getClauses(OboFormatTag.TAG_INTERSECTION_OF);
        if (iClauses.size() == 1) {
            throw new FrameStructureException(this, "single intersection_of tags are not allowed");
        }
        checkMaxOneCardinality(OboFormatTag.TAG_IS_ANONYMOUS, OboFormatTag.TAG_NAME,
            // OboFormatTag.TAG_NAMESPACE,
            OboFormatTag.TAG_DEF, OboFormatTag.TAG_COMMENT, OboFormatTag.TAG_IS_ANTI_SYMMETRIC,
            OboFormatTag.TAG_IS_CYCLIC, OboFormatTag.TAG_IS_REFLEXIVE, OboFormatTag.TAG_IS_SYMMETRIC,
            OboFormatTag.TAG_IS_TRANSITIVE, OboFormatTag.TAG_IS_FUNCTIONAL, OboFormatTag.TAG_IS_INVERSE_FUNCTIONAL,
            OboFormatTag.TAG_IS_OBSELETE, OboFormatTag.TAG_CREATED_BY, OboFormatTag.TAG_CREATION_DATE);
    }

    /**
     * Check max one cardinality.
     * 
     * @param tags
     *        the tags
     * @throws FrameStructureException
     *         frame structure exception
     */
    private void checkMaxOneCardinality(@Nonnull OboFormatTag... tags) throws FrameStructureException {
        for (OboFormatTag tag : tags) {
            if (getClauses(tag).size() > 1) {
                throw new FrameStructureException(this, "multiple " + tag.getTag() + " tags not allowed.");
            }
        }
    }
}