blob: a97ac0e7609a7b0c9784bc33acd8f60ca4d63ea8 [file] [log] [blame]
/*
* 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.feature;
import java.util.Collection;
import org.opengis.util.GenericName;
// Branch-dependent imports
import java.util.Objects;
/**
* An association implementation which delegate its work to the parent feature.
* This class is used for default implementation of {@link AbstractFeature#getProperty(String)}.
*
* <p><strong>This implementation is inefficient!</strong>
* This class is for making easier to begin with a custom {@link AbstractFeature} implementation,
* but developers are encouraged to provide their own {@link AbstractFeature#getProperty(String)}
* implementation.
*
* @author Martin Desruisseaux (Geomatys)
* @version 0.8
* @since 0.8
* @module
*/
class AssociationView extends AbstractAssociation {
/**
* For cross-version compatibility.
*/
private static final long serialVersionUID = -148100967531766909L;
/**
* The feature from which to read and where to write the attribute or association value.
*/
final AbstractFeature feature;
/**
* The string representation of the property name. This is the value to be given in calls to
* {@code Feature.getPropertyValue(String)} and {@code Feature.setPropertyValue(String, Object)}.
*/
final String name;
/**
* Creates a new association which will delegate its work to the given feature.
*/
private AssociationView(final AbstractFeature feature, final DefaultAssociationRole role) {
super(role);
this.feature = feature;
this.name = role.getName().toString();
}
/**
* Creates a new association which will delegate its work to the given feature.
*
* @param feature the feature from which to read and where to write the association value.
* @param role the role of this association. Must be one of the properties listed in the
* {@link #feature} (this is not verified by this constructor).
*/
static AbstractAssociation create(final AbstractFeature feature, final DefaultAssociationRole role) {
if (isSingleton(role.getMaximumOccurs())) {
return new Singleton(feature, role);
} else {
return new AssociationView(feature, role);
}
}
/**
* Returns the name of the role specified at construction time.
*/
@Override
public final GenericName getName() {
return role.getName();
}
@Override
public AbstractFeature getValue() {
return (AbstractFeature) PropertyView.getValue(feature, name);
}
@Override
public void setValue(final AbstractFeature value) {
PropertyView.setValue(feature, name, value);
}
@Override
public Collection<AbstractFeature> getValues() {
return PropertyView.getValues(feature, name, AbstractFeature.class);
}
@Override
public final void setValues(final Collection<? extends AbstractFeature> values) {
PropertyView.setValues(feature, name, values);
}
/**
* Specialization of {@code AssociationView} when the amount of values can be only zero or one.
* This implementation takes shortcuts for the {@code getValue()} and {@code getValues()} methods.
* This specialization is provided because it is the most common case.
*/
private static final class Singleton extends AssociationView {
/**
* For cross-version compatibility.
*/
private static final long serialVersionUID = 2574475751526292380L;
/**
* Creates a new association which will delegate its work to the given feature.
*/
Singleton(final AbstractFeature feature, final DefaultAssociationRole role) {
super(feature, role);
}
/**
* Returns the single value, or {@code null} if none.
*/
@Override
public AbstractFeature getValue() {
return (AbstractFeature) this.feature.getPropertyValue(this.name);
}
/**
* Sets the value of this association. This method assumes that the
* {@code Feature.setPropertyValue(String, Object)} implementation
* will verify the argument type.
*/
@Override
public void setValue(final AbstractFeature value) {
this.feature.setPropertyValue(this.name, value);
}
/**
* Wraps the property value in a set.
*/
@Override
public Collection<AbstractFeature> getValues() {
return PropertyView.singletonOrEmpty(getValue());
}
}
@Override
public final int hashCode() {
return PropertyView.hashCode(feature, name);
}
@Override
public final boolean equals(final Object obj) {
if (obj == this) {
return true;
}
if (obj != null && obj.getClass() == getClass()) {
final AssociationView that = (AssociationView) obj;
return feature == that.feature && Objects.equals(name, that.name);
}
return false;
}
@Override
public final String toString() {
return PropertyView.toString(getClass(), AbstractFeature.class, getName(), getValues());
}
}