| /* |
| * 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()); |
| } |
| } |