/*
* Geotoolkit - An Open Source Java GIS Toolkit
* http://www.geotoolkit.org
*
* (C) 2008, Open Source Geospatial Foundation (OSGeo)
* (C) 2009, Geomatys
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
package org.geotoolkit.temporal.object;
import java.util.Map;
import java.util.Objects;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import org.apache.sis.util.ArgumentChecks;
import org.apache.sis.util.ComparisonMode;
import org.opengis.temporal.Duration;
import org.opengis.temporal.Instant;
import org.opengis.temporal.Period;
import org.opengis.temporal.RelativePosition;
/**
* A one-dimensional geometric primitive that represent extent in time.
*
* @author Mehdi Sidhoum (Geomatys)
* @author Remi Marechal (Geomatys)
* @module
* @version 4.0
* @since 4.0
*/
@XmlType(name = "TimePeriod_Type", propOrder = {
"beginning",
"ending",
"duration"
})
@XmlRootElement(name = "TimePeriod")
public class DefaultPeriod extends DefaultTemporalGeometricPrimitive implements Period {
/**
* This is the {@link Instant} at which this Period starts.
*/
private Instant begining;
/**
* This is the {@link Instant} at which this Period ends.
*/
private Instant ending;
/**
* Empty constructor only use for XML binding.
*/
private DefaultPeriod() {
}
/**
* Creates a default {@link Period} implementation from the given properties and {@link Instant}.
* The properties given in argument follow the same rules than for the
* {@linkplain DefaultTemporalGeometricPrimitive#DefaultTemporalGeometricPrimitive(java.util.Map) ) super-class constructor}.
*
* <table class="referencingTemporal">
* <caption>Recognized properties (non exhaustive list)</caption>
* <tr>
* <th>Property name</th>
* <th>Value type</th>
* <th>Returned by</th>
* </tr>
* <tr>
* <th colspan="3" class="hsep">Defined in parent class (reminder)</th>
* </tr>
* <tr>
* <td>{@value org.opengis.referencing.IdentifiedObject#NAME_KEY}</td>
* <td>{@link Identifier} or {@link String}</td>
* <td>{@link #getName()}</td>
* </tr>
* <tr>
* <td>{@value org.opengis.referencing.IdentifiedObject#IDENTIFIERS_KEY}</td>
* <td>{@link Identifier} (optionally as array)</td>
* <td>{@link #getIdentifiers()}</td>
* </tr>
* </table>
*
* @param properties The properties to be given to this object.
* @param begining begin instant of the period.
* @param ending end instant of the period.
* @throws IllegalArgumentException
*/
public DefaultPeriod(final Map<String , ?> properties, final Instant begining, final Instant ending) {
super(properties);
ArgumentChecks.ensureNonNull("begining", begining);
ArgumentChecks.ensureNonNull("ending", ending);
//-- begining must be before or equals ending
if (begining != null &&
(RelativePosition.BEFORE.equals(begining.relativePosition(ending)) ||
RelativePosition.EQUALS.equals(begining.relativePosition(ending)))) {
this.begining = begining;
this.ending = ending;
}
}
/**
* Constructs a new instance initialized with the values from the specified metadata object.
* This is a <cite>shallow</cite> copy constructor, since the other metadata contained in the
* given object are not recursively copied.
*
* @param object The Instant to copy values from, or {@code null} if none.
*
* @see #castOrCopy(Period)
*/
private DefaultPeriod(final Period object) {
super(object);
if (object != null) {
begining = object.getBeginning();
ending = object.getEnding();
if (object instanceof DefaultPeriod) {
//--- voir pour get duration
}
}
}
/**
* Returns a Geotk implementation with the values of the given arbitrary implementation.
* This method performs the first applicable action in the following choices:
*
* <ul>
* <li>If the given object is {@code null}, then this method returns {@code null}.</li>
* <li>Otherwise if the given object is already an instance of
* {@code DefaultPeriod}, then it is returned unchanged.</li>
* <li>Otherwise a new {@code DefaultPeriod} instance is created using the
* {@linkplain #DefaultPeriod(Period) copy constructor}
* and returned. Note that this is a <cite>shallow</cite> copy operation, since the other
* metadata contained in the given object are not recursively copied.</li>
* </ul>
*
* @param object The object to get as a Geotk implementation, or {@code null} if none.
* @return A Geotk implementation containing the values of the given object (may be the
* given object itself), or {@code null} if the argument was null.
*/
public static DefaultPeriod castOrCopy(final Period object) {
if (object == null || object instanceof DefaultPeriod) {
return (DefaultPeriod) object;
}
return new DefaultPeriod(object);
}
/**
* Returns {@link Period} to the {@link Instant} at which it starts.
*
* @return {@link Period} to the {@link Instant} at which it starts.
*/
@Override
@XmlElement(name = "begin", required = true)
public Instant getBeginning() {
return begining;
}
/**
* Set {@link Period} to the {@link Instant} at which it starts.
*
* @param begining start {@link Instant} of the {@link Period}.
*/
public void setBegining(final Instant begining) {
this.begining = begining;
}
/**
* Returns {@link Period} to the {@link Instant} at which it ends.
*
* @return {@link Period} to the {@link Instant} at which it ends.
*/
@Override
@XmlElement(name = "end", required = true)
public Instant getEnding() {
return ending;
}
/**
* Duration only use for XML binding.
*
* @return {@link String} which represent duration for XML binding format.
*/
@XmlElement(name = "duration")
private String getDuration() {
Duration dur = super.length();
if (dur != null && (dur instanceof DefaultDuration)) {
final DefaultPeriodDuration defPerDur = (dur instanceof DefaultPeriodDuration) ? (DefaultPeriodDuration) dur : new DefaultPeriodDuration(((DefaultDuration)dur).getTimeInMillis());
return defPerDur.toString();
}
return null;
}
/**
* Set {@link Period} to the {@link Instant} at which it ends.
*
* @param ending ending {@link Instant} of the {@link Period}.
*/
public void setEnding(final Instant ending) {
this.ending = ending;
}
/**
* Verify if this entry is identical to the specified object.
*/
@Override
public boolean equals(final Object object, ComparisonMode comp) {
if (object == this) {
return true;
}
if (object instanceof DefaultPeriod) {
final DefaultPeriod that = (DefaultPeriod) object;
return Objects.equals(this.begining, that.begining) &&
Objects.equals(this.ending, that.ending);
}
return false;
}
/**
* {@inheritDoc }
*/
@Override
protected long computeHashCode() {
int hash = 5;
hash = 37 * hash + (this.begining != null ? this.begining.hashCode() : 0);
hash = 37 * hash + (this.ending != null ? this.ending.hashCode() : 0);
return hash;
}
/**
* {@inheritDoc }
*/
@Override
public String toString() {
StringBuilder s = new StringBuilder("Period:").append('\n');
if (begining != null) {
s.append("begin:").append(begining).append('\n');
}
if (ending != null) {
s.append("end:").append(ending).append('\n');
}
return s.toString();
}
}