| /* |
| * 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.storage; |
| |
| import java.util.Optional; |
| import java.util.OptionalLong; |
| import org.opengis.util.GenericName; |
| import org.opengis.metadata.Metadata; |
| import org.apache.sis.storage.event.StoreListeners; |
| import org.apache.sis.storage.base.MetadataBuilder; |
| |
| // Specific to the main branch: |
| import org.apache.sis.feature.DefaultFeatureType; |
| |
| |
| /** |
| * Default implementations of several methods for classes that want to implement the {@link FeatureSet} interface. |
| * Subclasses should override the following methods: |
| * |
| * <ul> |
| * <li>{@link #getType()} (mandatory)</li> |
| * <li>{@link #features(boolean parallel)} (mandatory)</li> |
| * <li>{@link #getFeatureCount()} (recommended)</li> |
| * <li>{@link #getEnvelope()} (recommended)</li> |
| * <li>{@link #createMetadata()} (optional)</li> |
| * </ul> |
| * |
| * <h2>Thread safety</h2> |
| * Default methods of this abstract class are thread-safe. |
| * Synchronization, when needed, uses {@link #getSynchronizationLock()}. |
| * |
| * @author Johann Sorel (Geomatys) |
| * @author Martin Desruisseaux (Geomatys) |
| * @version 1.4 |
| * @since 1.2 |
| */ |
| public abstract class AbstractFeatureSet extends AbstractResource implements FeatureSet { |
| /** |
| * Creates a new resource, potentially as a child of another resource. |
| * The parent resource is typically, but not necessarily, an {@link Aggregate}. |
| * |
| * @param parent the parent resource, or {@code null} if none. |
| * |
| * @since 1.4 |
| */ |
| protected AbstractFeatureSet(final Resource parent) { |
| super(parent); |
| } |
| |
| /** |
| * Creates a new resource which can send notifications to the given set of listeners. |
| * If {@code hidden} is {@code false} (the recommended value), then this resource will have its own set of |
| * listeners with this resource declared as the {@linkplain StoreListeners#getSource() source of events}. |
| * It will be possible to add and remove listeners independently from the set of parent listeners. |
| * Conversely if {@code hidden} is {@code true}, then the given listeners will be used directly |
| * and this resource will not appear as the source of any event. |
| * |
| * <p>In any cases, the listeners of all parents (ultimately the data store that created this resource) |
| * will always be notified, either directly if {@code hidden} is {@code true} |
| * or indirectly if {@code hidden} is {@code false}.</p> |
| * |
| * @param parentListeners listeners of the parent resource, or {@code null} if none. |
| * This is usually the listeners of the {@link DataStore} that created this resource. |
| * @param hidden {@code false} if this resource shall use its own {@link StoreListeners} |
| * with the specified parent, or {@code true} for using {@code parentListeners} directly. |
| */ |
| protected AbstractFeatureSet(final StoreListeners parentListeners, final boolean hidden) { |
| super(parentListeners, hidden); |
| } |
| |
| /** |
| * Returns the feature type name as the identifier for this resource. |
| * Subclasses should override if they can provide a more specific identifier. |
| * |
| * @return the resource identifier inferred from feature type. |
| * @throws DataStoreException if an error occurred while fetching the identifier. |
| * |
| * @see DataStore#getIdentifier() |
| */ |
| @Override |
| public Optional<GenericName> getIdentifier() throws DataStoreException { |
| final DefaultFeatureType type = getType(); |
| return (type != null) ? Optional.of(type.getName()) : Optional.empty(); |
| } |
| |
| /** |
| * Returns an estimation of the number of features in this set, or empty if unknown. |
| * The default implementation returns an empty value. |
| * |
| * @return estimation of the number of features. |
| */ |
| public OptionalLong getFeatureCount() { |
| return OptionalLong.empty(); |
| } |
| |
| /** |
| * Invoked in a synchronized block the first time that {@code getMetadata()} is invoked. |
| * The default implementation populates metadata based on information provided by |
| * {@link #getIdentifier() getIdentifier()}, |
| * {@link #getEnvelope() getEnvelope()}, |
| * {@link #getType() getType()} and |
| * {@link #getFeatureCount() getFeatureCount()}. |
| * Subclasses should override if they can provide more information. |
| * The default value can be completed by casting to {@link org.apache.sis.metadata.iso.DefaultMetadata}. |
| * |
| * @return the newly created metadata, or {@code null} if unknown. |
| * @throws DataStoreException if an error occurred while reading metadata from this resource. |
| */ |
| @Override |
| protected Metadata createMetadata() throws DataStoreException { |
| final MetadataBuilder builder = new MetadataBuilder(); |
| builder.addDefaultMetadata(this, listeners); |
| return builder.build(); |
| } |
| } |