Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
Implementations of metadata derived from ISO 19115. This module provides both an implementation
of the metadata interfaces defined in GeoAPI, and a framework for handling those metadata through
Java reflection.
/*
* Geotoolkit.org - An Open Source Java GIS Toolkit
* http://www.geotoolkit.org
*
* (C) 2007-2011, Open Source Geospatial Foundation (OSGeo)
* (C) 2009-2011, 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.metadata;
import java.util.Map;
import java.util.Set;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Collection;
import java.util.Locale;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.text.DateFormat;
import java.text.NumberFormat;
import java.text.ParseException;
import javax.swing.tree.TreeNode;
import org.opengis.util.CodeList;
import org.opengis.util.InternationalString;
import org.geotoolkit.util.Strings;
import org.geotoolkit.util.converter.Classes;
import org.geotoolkit.util.converter.Numbers;
import org.geotoolkit.gui.swing.tree.NamedTreeNode;
import org.geotoolkit.gui.swing.tree.MutableTreeNode;
import org.geotoolkit.gui.swing.tree.DefaultMutableTreeNode;
import org.geotoolkit.gui.swing.tree.Trees;
import org.geotoolkit.internal.CodeLists;
import org.geotoolkit.resources.Vocabulary;
import org.geotoolkit.resources.Errors;
import static org.geotoolkit.metadata.AbstractMetadata.LOGGER;
/**
* Represents the metadata property as a tree made from {@linkplain TreeNode tree nodes}.
* Note that while {@link TreeNode} is defined in the {@link javax.swing.tree} package,
* it can be seen as a data structure independent of Swing.
*
* This class is called {@code PropertyTree} because it may implements
* {@link javax.swing.tree.TreeModel} in some future Geotk implementation.
*
* @author Martin Desruisseaux (Geomatys)
* @version 3.02
*
* @since 2.4
* @module
*
* @todo It may make sense to refactor this class as a subclass of {@link java.text.Format}
* and make it public.
*/
final class PropertyTree {
/**
* The default number of significant digits (may or may not be fraction digits).
*/
private static final int PRECISION = 12;
/**
* The expected standard implemented by the metadata.
*/
private final MetadataStandard standard;
/**
* The locale to use for {@linkplain Date date}, {@linkplain Number number}
* and {@linkplain InternationalString international string} formatting.
*/
private final Locale locale;
/**
* The object to use for formatting numbers.
* Will be created only when first needed.
*/
private transient NumberFormat numberFormat;
/**
* The object to use for formatting dates.
* Will be created only when first needed.
*/
private transient DateFormat dateFormat;
/**
* Creates a new tree builder using the default locale.
*
* @param standard The expected standard implemented by the metadata.
*/
public PropertyTree(final MetadataStandard standard) {
this(standard, Locale.getDefault());
}
/**
* Creates a new tree builder.
*
* @param standard The expected standard implemented by the metadata.
* @param locale The locale to use for {@linkplain Date date}, {@linkplain Number number}
* and {@linkplain InternationalString international string} formatting.
*/
public PropertyTree(final MetadataStandard standard, final Locale locale) {
this.standard = standard;
this.locale = locale;
}
// ---------------------- PARSING -------------------------------------------------------------
/**
* Fetches values from every nodes of the given tree except the root, and puts them in
* the given metadata object. The value of the root node is ignored (it is typically
* just the name of the metadata class).
*
* If the given metadata object already contains property values, then the parsing will be
* merged with the existing values: attributes not defined in the tree will be left unchanged,
* and collections will be augmented with new entries without change in the previously existing
* entries.
*
* @param node The node from which to fetch the values.
* @param metadata The metadata where to store the values.
* @throws ParseException If a value can not be stored in the given metadata object.
*/
final void parse(final TreeNode node, final Object metadata) throws ParseException {
final Class> type = metadata.getClass();
final PropertyAccessor accessor = standard.getAccessorOptional(type);
if (accessor == null) {
throw new ParseException(Errors.format(Errors.Keys.UNKNOWN_TYPE_$1, type), 0);
}
final int duplicated = parse(node, type, metadata, null, accessor);
if (duplicated != 0) {
final LogRecord record = Errors.getResources(locale).getLogRecord(
Level.WARNING, Errors.Keys.DUPLICATED_VALUES_COUNT_$1, duplicated);
record.setSourceClassName("AbstractMetadata"); // This is the public API.
record.setSourceMethodName("parse");
record.setLoggerName(LOGGER.getName());
LOGGER.log(record);
}
}
/**
* Fetches values from every nodes of the given tree except the root, and puts them in
* the given metadata object. This method invokes itself recursively.
*
* @param node The node from which to fetch the values.
* @param type The implementation class of the given {@code metadata}.
* @param metadata The metadata where to store the values, or {@code null} if it should
* be created from the given {@code type} when first needed.
* @param addTo If non-null, then metadata objects (including the one provided to this
* method) are added to this collection after they have been parsed.
* @param accessor The object to use for writing in the metadata object.
* @return The number of duplicated elements, for logging purpose.
* @throws ParseException If a value can not be stored in the given metadata object.
*/
private int parse(final TreeNode node, final Class extends T> type, T metadata,
final Collection super T> addTo, final PropertyAccessor accessor) throws ParseException
{
int duplicated = 0;
final Set done = new HashSet();
final int childCount = node.getChildCount();
for (int i=0; i childType = accessor.type(index, TypeValuePolicy.ELEMENT_TYPE);
if (childType == null) {
// The type of the parameter is unknown (actually the message is a bit
// misleading since it doesn't said that only the type is unknown).
throw new ParseException(Errors.format(Errors.Keys.UNKNOWN_PARAMETER_$1, name), 0);
}
childType = standard.getImplementation(childType);
/*
* If the type is an other metadata implementation, invokes this method
* recursively for every childs of the metadata object we just found.
*/
Object value;
final PropertyAccessor ca = standard.getAccessorOptional(childType);
if (ca != null) {
value = accessor.get(index, metadata);
if (value instanceof Collection>) {
@SuppressWarnings("unchecked") // We will rely on CheckedCollection checks.
final Collection