/** * Associates the specified value with the specified key in this map. * * @throws IllegalArgumentException if the given key is not the name of a property in the metadata. * @throws ClassCastException if the given value is not of the expected type. * @throws UnmodifiableMetadataException if the property for the given key is read-only. */ @Override public Object put(final String key, final Object value) { final Object old = accessor.set(accessor.indexOf(key, true), metadata, value, RETURN_PREVIOUS); return valuePolicy.isSkipped(old) ? null : old; }
/** * Returns the number of elements in this collection, * ignoring the {@link #isSkipped(Object) skipped} ones. */ @Override public int size() { int count = accessor.count(metadata, parent.table.valuePolicy, PropertyAccessor.COUNT_DEEP); if (titleProperty >= 0 && !isSkipped(valueAt(titleProperty))) count--; return count; }
@Override public Object apply(final CacheKey k, final Object v) { if (v instanceof PropertyAccessor) { return v; } final Class<?> standardImpl = getImplementation(type); final PropertyAccessor accessor; if (SpecialCases.isSpecialCase(type)) { accessor = new SpecialCases(citation, type, k.type, standardImpl); } else { accessor = new PropertyAccessor(citation, type, k.type, standardImpl); } return accessor; } });
/** * Creates a collection to be tested for the given metadata object and value policy. */ private static TreeNodeChildren create(final DefaultCitation citation, final ValueExistencePolicy valuePolicy) { final MetadataStandard standard = MetadataStandard.ISO_19115; final TreeTableView table = new TreeTableView(standard, citation, Citation.class, valuePolicy); final TreeNode node = (TreeNode) table.getRoot(); final PropertyAccessor accessor = standard.getAccessor(new CacheKey(citation.getClass()), true); return new TreeNodeChildren(node, citation, accessor); }
/** * Moves {@link #next} to the first property with a valid value, * starting at the specified index. */ private void move(int index) { final int count = accessor.count(); while (index < count) { if (!valuePolicy.isSkipped(accessor.get(index, metadata))) { next = new Property(index); return; } index++; } next = null; }
/** * Returns a key for use in {@link #getAccessor(CacheKey, boolean)} for the given type. * The type may be an interface (typically a GeoAPI interface) or an implementation class. */ private CacheKey createCacheKey(Class<?> type) { final Class<?> implementation = getImplementation(type); if (implementation != null) { type = implementation; } return new CacheKey(type); }
/** * Returns the value to which the specified key is mapped, or {@code null} * if this map contains no mapping for the key. */ @Override public Object get(final Object key) { if (key instanceof String) { final Object value = accessor.get(accessor.indexOf((String) key, false), metadata); if (!valuePolicy.isSkipped(value)) { return value; } } return null; }
/** * Replaces every properties in the specified metadata by their * {@linkplain ModifiableMetadata#unmodifiable() unmodifiable variant}. * * @throws ClassCastException if the specified implementation class do * not implements a metadata interface of the expected package. * * @see ModifiableMetadata#freeze() */ final void freeze(final Object metadata) throws ClassCastException { getAccessor(new CacheKey(metadata.getClass()), true).freeze(metadata); }
/** * Compares this metadata with the specified object for equality. The default * implementation uses Java reflection. Subclasses may override this method * for better performances, or for comparing "hidden" properties not specified * by the GeoAPI (or other standard) interface. * * @param object the object to compare with this metadata. * @param mode the strictness level of the comparison. * @return {@code true} if the given object is equal to this metadata. */ @Override public boolean equals(final Object object, final ComparisonMode mode) { return getStandard().equals(this, object, mode); }
/** * Returns the information to which the specified key is mapped, * or {@code null} if this map contains no mapping for the key. */ @Override public ExtendedElementInformation get(final Object key) { if (key instanceof String) { return accessor.information(accessor.indexOf((String) key, false)); } return null; }
/** * Returns the interface type declared by the accessor for the given class. */ private Class<?> getAccessor(final Class<?> type, final boolean mandatory) { final PropertyAccessor accessor = standard.getAccessor(new CacheKey(type), mandatory); return (accessor != null) ? accessor.type : null; }
/** * Validates the given newly constructed metadata. The default implementation ensures that * {@link AbstractMetadata#isEmpty()} returns {@code true}. * * @param metadata the metadata to validate. */ protected void validate(final AbstractMetadata metadata) { assertTrue("AbstractMetadata.isEmpty()", metadata.isEmpty()); }
/** * Creates a table to be tested for the given value policy. */ private static TreeTableView create(final ValueExistencePolicy valuePolicy) { return new TreeTableView(MetadataStandard.ISO_19115, TreeNodeTest.metadataWithHierarchy(), Citation.class, valuePolicy); }
@Override protected Object copyRecursively(final Class<?> type, final Object metadata) { if (metadata instanceof ModifiableMetadata) { final ModifiableMetadata.State state = ((ModifiableMetadata) metadata).state(); if (state == ModifiableMetadata.State.FINAL) { return metadata; } } return super.copyRecursively(type, metadata); } };
/** * Returns {@code true} if the given metadata is empty. */ static boolean isEmpty(final Object container) { return (container instanceof AbstractMetadata) && ((AbstractMetadata) container).isEmpty(); }
/** * Returns {@code true} if this map contains a mapping for the specified key. * The default implementation is okay only if all metadata defined by the standard are included * in the map. Subclasses shall override this method if their map contain only a subset of all * possible metadata elements. */ @Override public boolean containsKey(final Object key) { return (key instanceof String) && accessor.indexOf((String) key, false) >= 0; }
/** * Associates the specified value with the specified key in this map. * * @throws IllegalArgumentException if the given key is not the name of a property in the metadata. * @throws ClassCastException if the given value is not of the expected type. * @throws UnmodifiableMetadataException if the property for the given key is read-only. */ @Override public Object put(final String key, final Object value) { final Object old = accessor.set(accessor.indexOf(key, true), metadata, value, RETURN_PREVIOUS); return valuePolicy.isSkipped(old) ? null : old; }
/** * Returns the number of elements in this collection, * ignoring the {@link #isSkipped(Object) skipped} ones. */ @Override public int size() { int count = accessor.count(metadata, parent.table.valuePolicy, PropertyAccessor.COUNT_DEEP); if (titleProperty >= 0 && !isSkipped(valueAt(titleProperty))) count--; return count; }