/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */
package org.apache.sis.xml;

import java.net.URI;
import java.util.Locale;
import java.util.Objects;
import java.io.Serializable;
import javax.xml.bind.annotation.XmlEnum;
import javax.xml.bind.annotation.XmlEnumValue;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlSchemaType;
import org.opengis.util.InternationalString;
import org.apache.sis.util.Classes;
import org.apache.sis.util.logging.Logging;
import org.apache.sis.util.resources.Errors;
import org.apache.sis.internal.system.Loggers;

import static java.util.logging.Logger.getLogger;


/**
 * The XML attributes defined by OGC in the
 * <a href="http://schemas.opengis.net/xlink/1.0.0/xlinks.xsd">xlink</a> schema.
 *
 * The allowed combinations of any one attribute depend on the value of the special
 * {@link #getType() type} attribute. Following is a summary of the element types
 * (columns) on which the global attributes (rows) are allowed, with an indication
 * of whether a value is required (R) or optional (O)
 * (Source: <a href="http://www.w3.org/TR/xlink/">W3C</a>):
 *
 * <table class="sis">
 * <caption>XLink attribute usage patterns</caption>
 * <tr>
 *   <th> </th>
 *   <th style="width: 14%">{@link XLink.Type#SIMPLE simple}</th>
 *   <th style="width: 14%">{@link XLink.Type#EXTENDED extended}</th>
 *   <th style="width: 14%">{@link XLink.Type#LOCATOR locator}</th>
 *   <th style="width: 14%">{@link XLink.Type#ARC arc}</th>
 *   <th style="width: 14%">{@link XLink.Type#RESOURCE resource}</th>
 *   <th style="width: 14%">{@link XLink.Type#TITLE title}</th>
 * </tr>
 *   <tr style="text-align:center"><td style="text-align:left"><b>{@link #getType() type}</b></td>       <td>R</td><td>R</td><td>R</td><td>R</td><td>R</td><td>R</td></tr>
 *   <tr style="text-align:center"><td style="text-align:left"><b>{@link #getHRef() href}</b></td>       <td>O</td><td> </td><td>R</td><td> </td><td> </td><td> </td></tr>
 *   <tr style="text-align:center"><td style="text-align:left"><b>{@link #getRole() role}</b></td>       <td>O</td><td>O</td><td>O</td><td> </td><td>O</td><td> </td></tr>
 *   <tr style="text-align:center"><td style="text-align:left"><b>{@link #getArcRole() arcrole}</b></td> <td>O</td><td> </td><td> </td><td>O</td><td> </td><td> </td></tr>
 *   <tr style="text-align:center"><td style="text-align:left"><b>{@link #getTitle() title}</b></td>     <td>O</td><td>O</td><td>O</td><td>O</td><td>O</td><td> </td></tr>
 *   <tr style="text-align:center"><td style="text-align:left"><b>{@link #getShow() show}</b></td>       <td>O</td><td> </td><td> </td><td>O</td><td> </td><td> </td></tr>
 *   <tr style="text-align:center"><td style="text-align:left"><b>{@link #getActuate() actuate}</b></td> <td>O</td><td> </td><td> </td><td>O</td><td> </td><td> </td></tr>
 *   <tr style="text-align:center"><td style="text-align:left"><b>{@link #getLabel() label}</b></td>     <td> </td><td> </td><td>O</td><td> </td><td>O</td><td> </td></tr>
 *   <tr style="text-align:center"><td style="text-align:left"><b>{@link #getFrom() from}</b></td>       <td> </td><td> </td><td> </td><td>O</td><td> </td><td> </td></tr>
 *   <tr style="text-align:center"><td style="text-align:left"><b>{@link #getTo() to}</b></td>           <td> </td><td> </td><td> </td><td>O</td><td> </td><td> </td></tr>
 * </table>
 *
 * When {@code xlink} attributes are found at unmarshalling time instead of an object definition,
 * those attributes are given to the {@link ReferenceResolver#resolve(MarshalContext, Class, XLink)}
 * method. Users can override that method in order to fetch an instance in some catalog for the given
 * {@code xlink} values.
 *
 * @author  Guilhem Legal (Geomatys)
 * @author  Martin Desruisseaux (Geomatys)
 * @version 0.3
 *
 * @see <a href="http://www.w3.org/TR/xlink/">XML Linking Language</a>
 * @see <a href="http://schemas.opengis.net/xlink/1.0.0/xlinks.xsd">OGC schema</a>
 *
 * @since 0.3
 * @module
 */
@XmlTransient
public class XLink implements Serializable {
    /**
     * For cross-version compatibility.
     */
    private static final long serialVersionUID = 4046720871882443681L;

    /**
     * The type of link. If {@code null}, then the type will be inferred by {@link #getType()}.
     *
     * @see #getType()
     */
    private Type type;

    /**
     * A URN to an external resources, or to an other part of a XML document, or an identifier.
     *
     * @see #getHRef()
     * @category locator
     */
    private URI href;

    /**
     * A URI reference for some description of the arc role.
     *
     * @see #getRole()
     * @category semantic
     */
    private URI role;

    /**
     * A URI reference for some description of the arc role.
     *
     * @see #getArcRole()
     * @category semantic
     */
    private URI arcrole;

    /**
     * Just as with resources, this is simply a human-readable string with a short description
     * for the arc.
     *
     * @see #getTitle()
     * @category semantic
     */
    private InternationalString title;

    /**
     * Communicates the desired presentation of the ending resource on traversal
     * from the starting resource.
     *
     * @see #getShow()
     * @category behavior
     */
    private Show show;

    /**
     * Communicates the desired timing of traversal from the starting resource to the ending resource.
     *
     * @see #getActuate()
     * @category behavior
     */
    private Actuate actuate;

    /**
     * Identifies the target of a {@code from} or {@code to} attribute.
     *
     * @see #getLabel()
     * @category traversal
     */
    private String label;

    /**
     * The starting resource. The value must correspond to the same value for some
     * {@code label} attribute.
     *
     * @see #getFrom()
     * @category traversal
     */
    private String from;

    /**
     * The ending resource. The value must correspond to the same value for some
     * {@code label} attribute.
     *
     * @see #getTo()
     * @category traversal
     */
    private String to;

    /**
     * The cached hash code value, computed only if this {@code XLink} is unmodifiable. Otherwise,
     * this field is left to zero. This field is computed when the {@link #freeze()} method has
     * been invoked.
     */
    private int hashCode;

    /**
     * Creates a new link. The initial value of all attributes is {@code null}.
     */
    public XLink() {
    }

    /**
     * Creates a new link as a copy of the given link.
     *
     * @param link The link to copy, or {@code null} if none.
     */
    public XLink(final XLink link) {
        if (link != null) {
            type    = link.type;
            href    = link.href;
            role    = link.role;
            arcrole = link.arcrole;
            title   = link.title;
            show    = link.show;
            actuate = link.actuate;
            label   = link.label;
            from    = link.from;
            to      = link.to;
        }
    }

    /**
     * The type of a {@code xlink}. This type can be determined from the set of non-null
     * attribute values in a {@link XLink} instance.
     *
     * @author  Martin Desruisseaux (Geomatys)
     * @version 0.3
     * @since   0.3
     * @module
     *
     * @see XLink#getType()
     */
    @XmlEnum
    public enum Type {
        /**
         * A simple link. Allows the {@link XLink#getHRef() href}, {@link XLink#getRole() role},
         * {@link XLink#getArcRole() arcrole}, {@link #getTitle() title}, {@link XLink#getShow()
         * show} and {@link XLink#getActuate() actuate} attributes, all of them being optional.
         */
        @XmlEnumValue("simple")
        SIMPLE(0x1 | 0x2 | 0x4 | 0x8 | 0x10 | 0x20 | 0x40, 0x1),

        /**
         * An extended, possibly multi-resource, link. Allows the {@link XLink#getRole() role}
         * and {@link #getTitle() title} attributes, all of them being optional.
         */
        @XmlEnumValue("extended")
        EXTENDED(0x1 | 0x4 | 0x10, 0x1),

        /**
         * A pointer to an external resource. Allows the {@link XLink#getHRef() href},
         * {@link XLink#getRole() role}, {@link #getTitle() title} and {@link XLink#getLabel()
         * label} attributes, where {@code href} is mandatory and all other are optional.
         */
        @XmlEnumValue("locator")
        LOCATOR(0x1 | 0x2 | 0x4 | 0x10 | 0x80, 0x1 | 0x2),

        /**
         * An internal resource. Allows the {@link XLink#getRole() role},  {@link #getTitle() title}
         * and {@link #getLabel() label} attributes, all of them being optional.
         */
        @XmlEnumValue("resource")
        RESOURCE(0x1 | 0x4 | 0x10 | 0x80, 0x1),

        /**
         * A traversal rule between resources. Allows the {@link XLink#getArcRole() arcrole},
         * {@link #getTitle() title}, {@link XLink#getShow() show}, {@link XLink#getActuate()
         * actuate} {@link #getFrom() from} and {@link #getTo() to} attributes, all of them
         * being optional.
         */
        @XmlEnumValue("arc")
        ARC(0x1 | 0x8 | 0x10 | 0x20 | 0x40 | 0x100 | 0x200, 0x1),

        /**
         * A descriptive title for another linking element.
         */
        @XmlEnumValue("title")
        TITLE(0x1, 0x1),

        /**
         * A special value for computing the type automatically from the {@link XLink} attributes.
         * After a call to {@code XLink.setType(AUTO)}, any call to {@code XLink.getType()} will
         * infer the type from the non-null attributes as according the table documented in the
         * {@link XLink} javadoc.
         */
        AUTO(-1, 0);

        /**
         * A bitmask which specified the non-null fields expected for a given type.
         * The bit values are:
         *
         * <ul>
         *   <li>{@code type}:     0x1</li>
         *   <li>{@code href}:     0x2</li>
         *   <li>{@code role}:     0x4</li>
         *   <li>{@code arcrole}:  0x8</li>
         *   <li>{@code title}:   0x10</li>
         *   <li>{@code show}:    0x20</li>
         *   <li>{@code actuate}: 0x40</li>
         *   <li>{@code label}:   0x80</li>
         *   <li>{@code from}:   0x100</li>
         *   <li>{@code to}:     0x200</li>
         * </ul>
         */
        final int fieldMask, mandatory;

        /**
         * Creates a new type which allows the fields specified by the given mask.
         */
        private Type(final int mask, final int mandatory) {
            this.fieldMask = mask;
            this.mandatory = mandatory;
        }

        /**
         * Returns the attribute name for this type.
         */
        final String identifier() {
            return name().toLowerCase(Locale.ROOT);
        }
    }

    /**
     * Returns a mask of fields for which a non-null value has been defined.
     * The bit values are defined in the {@link XLink.Type#fieldMask} javadoc.
     */
    private int fieldMask() {
        int mask = 0;
        if (type    != null) mask |= 0x1;
        if (href    != null) mask |= 0x2;
        if (role    != null) mask |= 0x4;
        if (arcrole != null) mask |= 0x8;
        if (title   != null) mask |= 0x10;
        if (show    != null) mask |= 0x20;
        if (actuate != null) mask |= 0x40;
        if (label   != null) mask |= 0x80;
        if (from    != null) mask |= 0x100;
        if (to      != null) mask |= 0x200;
        return mask;
    }

    /**
     * Returns the type of link. May have one of the following values:
     *
     * <ul>
     *   <li><b>simple:</b>   a simple link</li>
     *   <li><b>extended:</b> an extended, possibly multi-resource, link</li>
     *   <li><b>locator:</b>  a pointer to an external resource</li>
     *   <li><b>resource:</b> an internal resource</li>
     *   <li><b>arc:</b>      a traversal rule between resources</li>
     *   <li><b>title:</b>    a descriptive title for another linking element</li>
     * </ul>
     *
     * The default value is {@code null}. If the {@link #setType(XLink.Type)} method has been
     * invoked with the {@link org.apache.sis.xml.XLink.Type#AUTO AUTO} enum, then this method
     * will infer a type from the attributes having a non-null value.
     *
     * @return the type of link, or {@code null}.
     */
    @XmlAttribute(name = "type", namespace = Namespaces.XLINK, required = true)
    public Type getType() {
        if (type != Type.AUTO) {
            return type;
        }
        Type best = null;
        int min = Integer.SIZE;
        final int defined = fieldMask();
        final int undefined = ~(defined | 0x1);
        for (final Type candidate : Type.values()) {
            final int forbidden = ~candidate.fieldMask;
            if (forbidden == 0) {
                continue;                   // Skip the AUTO enum.
            }
            // Test if this XLink instance defines only values allowed by the candidate type.
            if ((defined & forbidden) != 0) {
                continue;
            }
            // Test if this XLink instance defines all mandatory fields.
            if ((undefined & candidate.mandatory) != 0) {
                continue;
            }
            // Select the type requerying the smallest amount of fields.
            final int n = Integer.bitCount(undefined & candidate.fieldMask);
            if (n < min) {
                min = n;
                best = candidate;
            }
        }
        return best;                        // May still null.
    }

    /**
     * Sets the type of link. Any value different than {@link org.apache.sis.xml.XLink.Type#AUTO
     * Type.AUTO} (including {@code null}) will overwrite the value inferred automatically by
     * {@link #getType()}. A {@code AUTO} value will enable automatic type detection.
     *
     * @param  type  the new type of link, or {@code null} if none.
     */
    public void setType(final Type type) {
        canWrite(0x1, "type", "type"); // We want a non-null value in all cases.
        if (type != null && (fieldMask() & ~type.fieldMask) != 0) {
            throw new IllegalStateException(Errors.format(Errors.Keys.InconsistentAttribute_2, "type", type.identifier()));
        }
        this.type = type;
    }

    /**
     * Checks if the given attribute can be set.
     *
     * @param  field  the attribute code, as documented in {@link XLink.Type#fieldMask}.
     * @throws UnsupportedOperationException if this {@code xlink} is unmodifiable.
     * @throws IllegalStateException if the given field can not be set for this kind of {@code xlink}.
     */
    private void canWrite(final int field, final String name, final Object value) throws IllegalStateException {
        if (hashCode != 0) {
            throw new UnsupportedOperationException(Errors.format(Errors.Keys.UnmodifiableObject_1, "XLink"));
        }
        final Type type = this.type;
        if (type != null) {
            if (value != null) {
                if ((type.fieldMask & field) == 0) {
                    throw new IllegalStateException(Errors.format(
                            Errors.Keys.ForbiddenAttribute_2, name, type.identifier()));
                }
            } else {
                if ((type.mandatory & field) != 0) {
                    throw new IllegalStateException(Errors.format(
                            Errors.Keys.MandatoryAttribute_2, name, type.identifier()));
                }
            }
        }
    }

    /**
     * Returns a URN to an external resources, or to an other part of a XML document, or an identifier.
     *
     * @return a URN to a resources, or {@code null} if none.
     *
     * @category locator
     */
    @XmlSchemaType(name = "anyURI")
    @XmlAttribute(name = "href", namespace = Namespaces.XLINK)
    public URI getHRef() {
        return href;
    }

    /**
     * Sets the URN to a resources.
     *
     * @param  href  a URN to a resources, or {@code null} if none.
     * @throws UnsupportedOperationException if this {@code xlink} is unmodifiable.
     * @throws IllegalStateException if the link type {@linkplain #setType has been explicitly set}.
     *         and that type does not allow the {@code "href"} attribute.
     *
     * @category locator
     */
    public void setHRef(final URI href) throws IllegalStateException {
        canWrite(0x2, "href", href);
        this.href = href;
    }

    /**
     * Returns a URI reference for some description of the arc role.
     *
     * @return a URI reference for some description of the arc role, or {@code null} if none.
     *
     * @category semantic
     */
    @XmlSchemaType(name = "anyURI")
    @XmlAttribute(name = "role", namespace = Namespaces.XLINK)
    public URI getRole() {
        return role;
    }

    /**
     * Sets the URI reference for some description of the arc role.
     *
     * @param  role  a URI reference for some description of the arc role, or {@code null} if none.
     * @throws UnsupportedOperationException if this {@code xlink} is unmodifiable.
     * @throws IllegalStateException if the link type {@linkplain #setType has been explicitly set}.
     *         and that type does not allow the {@code "role"} attribute.
     *
     * @category semantic
     */
    public void setRole(final URI role) throws IllegalStateException {
        canWrite(0x4, "role", role);
        this.role = role;
    }

    /**
     * Returns a URI reference for some description of the arc role.
     *
     * @return a URI reference for some description of the arc role, or {@code null} if none.
     *
     * @category semantic
     */
    @XmlSchemaType(name = "anyURI")
    @XmlAttribute(name = "arcrole", namespace = Namespaces.XLINK)
    public URI getArcRole() {
        return arcrole;
    }

    /**
     * Sets a URI reference for some description of the arc role.
     *
     * @param  arcrole  a URI reference for some description of the arc role, or {@code null} if none.
     * @throws UnsupportedOperationException if this {@code xlink} is unmodifiable.
     * @throws IllegalStateException if the link type {@linkplain #setType has been explicitly set}.
     *         and that type does not allow the {@code "arcrole"} attribute.
     *
     * @category semantic
     */
    public void setArcRole(final URI arcrole) throws IllegalStateException {
        canWrite(0x8, "arcrole", arcrole);
        this.arcrole = arcrole;
    }

    /**
     * Returns a human-readable string with a short description for the arc.
     *
     * @return a human-readable string with a short description for the arc, or {@code null} if none.
     *
     * @category semantic
     */
    @XmlAttribute(name = "title", namespace = Namespaces.XLINK)
    public InternationalString getTitle() {
        return title;
    }

    /**
     * Sets a human-readable string with a short description for the arc.
     *
     * @param  title  a human-readable string with a short description for the arc, or {@code null} if none.
     * @throws UnsupportedOperationException if this {@code xlink} is unmodifiable.
     * @throws IllegalStateException if the link type {@linkplain #setType has been explicitly set}.
     *         and that type does not allow the {@code "title"} attribute.
     *
     * @category semantic
     */
    public void setTitle(final InternationalString title) throws IllegalStateException {
        canWrite(0x10, "title", title);
        this.title = title;
    }

    /**
     * Communicates the desired presentation of the ending resource on traversal
     * from the starting resource.
     *
     * @author  Martin Desruisseaux (Geomatys)
     * @version 0.3
     * @since   0.3
     * @module
     *
     * @see XLink#getShow()
     */
    @XmlEnum
    public enum Show {
        /**
         * Load ending resource in a new window, frame, pane, or other presentation context.
         */
        @XmlEnumValue("new") NEW,

        /**
         * Load the resource in the same window, frame, pane, or other presentation context.
         */
        @XmlEnumValue("replace") REPLACE,

        /**
         * Load ending resource in place of the presentation of the starting resource.
         */
        @XmlEnumValue("embed") EMBED,

        /**
         * Behavior is unconstrained; examine other markup in the link for hints.
         */
        @XmlEnumValue("other") OTHER,

        /**
         * Behavior is unconstrained.
         */
        @XmlEnumValue("none") NONE
    }

    /**
     * Returns the desired presentation of the ending resource on traversal
     * from the starting resource. It's value should be treated as follows:
     *
     * <ul>
     *   <li><b>new:</b>     load ending resource in a new window, frame, pane, or other presentation context</li>
     *   <li><b>replace:</b> load the resource in the same window, frame, pane, or other presentation context</li>
     *   <li><b>embed:</b>   load ending resource in place of the presentation of the starting resource</li>
     *   <li><b>other:</b>   behavior is unconstrained; examine other markup in the link for hints</li>
     *   <li><b>none:</b>    behavior is unconstrained</li>
     * </ul>
     *
     * @return the desired presentation of the ending resource, or {@code null} if unspecified.
     *
     * @category behavior
     */
    @XmlAttribute(name = "show", namespace = Namespaces.XLINK)
    public Show getShow() {
        return show;
    }

    /**
     * Sets the desired presentation of the ending resource on traversal from the starting resource.
     *
     * @param  show  the desired presentation of the ending resource, or {@code null} if unspecified.
     * @throws UnsupportedOperationException if this {@code xlink} is unmodifiable.
     * @throws IllegalStateException if the link type {@linkplain #setType has been explicitly set}.
     *         and that type does not allow the {@code "show"} attribute.
     *
     * @category behavior
     */
    public void setShow(final Show show) throws IllegalStateException {
        canWrite(0x20, "show", show);
        this.show = show;
    }

    /**
     * Communicates the desired timing of traversal from the starting resource to the ending
     * resource.
     *
     * @author  Martin Desruisseaux (Geomatys)
     * @version 0.3
     * @since   0.3
     * @module
     *
     * @see XLink#getActuate()
     */
    @XmlEnum
    public enum Actuate {
        /**
         * Traverse to the ending resource immediately on loading the starting resource.
         */
        @XmlEnumValue("onLoad") ON_LOAD,

        /**
         * Traverse from the starting resource to the ending resource only on a post-loading event
         * triggered for this purpose.
         */
        @XmlEnumValue("onRequest") ON_REQUEST,

        /**
         * Behavior is unconstrained; examine other markup in link for hints.
         */
        @XmlEnumValue("other") OTHER,

        /**
         * Behavior is unconstrained.
         */
        @XmlEnumValue("none") NONE
    }

    /**
     * Returns the desired timing of traversal from the starting resource to the ending
     * resource. It's value should be treated as follows:
     *
     * <ul>
     *   <li><b>onLoad:</b>    traverse to the ending resource immediately on loading the starting resource</li>
     *   <li><b>onRequest:</b> traverse from the starting resource to the ending resource only on a post-loading event triggered for this purpose</li>
     *   <li><b>other:</b>     behavior is unconstrained; examine other markup in link for hints</li>
     *   <li><b>none:</b>      behavior is unconstrained</li>
     * </ul>
     *
     * @return the desired timing of traversal from the starting resource to the ending resource,
     *         or {@code null} if unspecified.
     *
     * @category behavior
     */
    @XmlAttribute(name = "actuate", namespace = Namespaces.XLINK)
    public Actuate getActuate() {
        return actuate;
    }

    /**
     * Sets the desired timing of traversal from the starting resource to the ending resource.
     *
     * @param  actuate  the desired timing of traversal from the starting resource to the ending resource,
     *                  or {@code null} if unspecified.
     * @throws UnsupportedOperationException if this {@code xlink} is unmodifiable.
     * @throws IllegalStateException if the link type {@linkplain #setType has been explicitly set}.
     *         and that type does not allow the {@code "actuate"} attribute.
     *
     * @category behavior
     */
    public void setActuate(final Actuate actuate) throws IllegalStateException {
        canWrite(0x40, "actuate", actuate);
        this.actuate = actuate;
    }

    /**
     * Returns an identification of the target of a {@code from} or {@code to} attribute.
     *
     * @return an identification of the target of a {@code from} or {@code to} attribute, or {@code null}.
     *
     * @category traversal
     */
    public String getLabel() {
        return label;
    }

    /**
     * Sets an identification of the target of a {@code from} or {@code to} attribute.
     *
     * @param  label  an identification of the target of a {@code from} or {@code to} attribute, or {@code null}.
     * @throws UnsupportedOperationException if this {@code xlink} is unmodifiable.
     * @throws IllegalStateException if the link type {@linkplain #setType has been explicitly set}.
     *         and that type does not allow the {@code "label"} attribute.
     *
     * @category traversal
     */
    public void setLabel(final String label) throws IllegalStateException {
        canWrite(0x80, "label", label);
        this.label = label;
    }

    /**
     * Returns the starting resource. The value must correspond to the same value for some
     * {@code label} attribute.
     *
     * @return the starting resource, or {@code null}.
     *
     * @category traversal
     */
    public String getFrom() {
        return from;
    }

    /**
     * Sets the starting resource. The value must correspond to the same value for some
     * {@code label} attribute.
     *
     * @param  from  the starting resource, or {@code null}.
     * @throws UnsupportedOperationException if this {@code xlink} is unmodifiable.
     * @throws IllegalStateException if the link type {@linkplain #setType has been explicitly set}.
     *         and that type does not allow the {@code "from"} attribute.
     *
     * @category traversal
     */
    public void setFrom(final String from) throws IllegalStateException {
        canWrite(0x100, "from", from);
        this.from = from;
    }

    /**
     * Returns the ending resource. The value must correspond to the same value for some
     * {@code label} attribute.
     *
     * @return the ending resource, or {@code null}.
     *
     * @category traversal
     */
    public String getTo() {
        return to;
    }

    /**
     * Sets the ending resource. The value must correspond to the same value for some
     * {@code label} attribute.
     *
     * @param  to  the ending resource, or {@code null}.
     * @throws UnsupportedOperationException if this {@code xlink} is unmodifiable.
     * @throws IllegalStateException if the link type {@linkplain #setType has been explicitly set}.
     *         and that type does not allow the {@code "to"} attribute.
     *
     * @category traversal
     */
    public void setTo(final String to) throws IllegalStateException {
        canWrite(0x200, "to", to);
        this.to = to;
    }

    /**
     * Marks this {@code xlink} as unmodifiable. After this method call, any call to a setter
     * method will throw an {@link UnsupportedOperationException}.
     *
     * <p>After the first call to this method, any subsequent calls have no effect.</p>
     */
    public void freeze() {
        if (hashCode == 0) {
            hashCode = hash();
        }
    }

    /**
     * Compares this {@code XLink} with the given object for equality.
     *
     * @param  object  the object to compare with this XLink.
     */
    @Override
    public boolean equals(final Object object) {
        if (object == this) {
            return true;
        }
        if (object != null && object.getClass() == getClass()) {
            final XLink that = (XLink) object;
            final int h0 = hashCode;
            if (h0 != 0) {
                final int h1 = that.hashCode;
                if (h1 != 0 && h0 != h1) {
                    return false;                   // Slight optimization using the pre-computed hash code values.
                }
            }
            return Objects.equals(this.type,    that.type)    &&
                   Objects.equals(this.href,    that.href)    &&
                   Objects.equals(this.role,    that.role)    &&
                   Objects.equals(this.arcrole, that.arcrole) &&
                   Objects.equals(this.title,   that.title)   &&
                   Objects.equals(this.show,    that.show)    &&
                   Objects.equals(this.actuate, that.actuate) &&
                   Objects.equals(this.label,   that.label)   &&
                   Objects.equals(this.from,    that.from)    &&
                   Objects.equals(this.to,      that.to);
        }
        return false;
    }

    /**
     * Returns a hash code value for this XLink.
     */
    @Override
    public int hashCode() {
        int hash = hashCode;
        if (hash == 0) {
            hash = hash();
            // Do not save the hash code value, since it may change.
        }
        return hash;
    }

    /**
     * Computes the hash code now. This method is guaranteed to return a value different
     * than zero, in order to allow us to use 0 as a sentinel value for modifiable xlink.
     */
    private int hash() {
        int hash = Objects.hash(href, role, arcrole, title, show, actuate, label, from, to, type) ^ (int) serialVersionUID;
        if (hash == 0) {
            hash = -1;
        }
        return hash;
    }

    /**
     * Returns a string representation of this object. The default implementation returns the
     * simple class name followed by non-null attributes, as in the example below:
     *
     * {@preformat text
     *     XLink[type="locator", href="urn:ogc:def:method:EPSG::4326"]
     * }
     */
    @Override
    public String toString() {
        final StringBuilder buffer = new StringBuilder(64);
        buffer.append(Classes.getShortClassName(this)).append('[');
        append(buffer, "type",    getType());
        append(buffer, "href",    getHRef());
        append(buffer, "role",    getRole());
        append(buffer, "arcrole", getArcRole());
        append(buffer, "title",   getTitle());
        append(buffer, "show",    getShow());
        append(buffer, "actuate", getActuate());
        append(buffer, "label",   getLabel());
        append(buffer, "from",    getFrom());
        append(buffer, "to",      getTo());
        return buffer.append(']').toString();
    }

    /**
     * Appends the given attribute in the given buffer if the attribute value is not null.
     * If the given value is an attribute, the XML name will be used rather than the Java
     * field name.
     */
    private static void append(final StringBuilder buffer, final String label, Object value) {
        if (value != null) {
            if (buffer.charAt(buffer.length() - 1) != '[') {
                buffer.append(", ");
            }
            if (value instanceof Enum<?>) try {
                final XmlEnumValue xml = value.getClass().getField(((Enum<?>) value).name()).getAnnotation(XmlEnumValue.class);
                if (xml != null) {
                    value = xml.value();
                }
            } catch (NoSuchFieldException e) {
                // Should never happen with Enums. But if it happen anyway, this is not a fatal error.
                Logging.unexpectedException(getLogger(Loggers.XML), XLink.class, "toString", e);
            }
            buffer.append(label).append("=\"").append(value).append('"');
        }
    }
}
