All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.geotoolkit.referencing.crs.UnprefixedMap Maven / Gradle / Ivy

Go to download

Implementations of Coordinate Reference Systems (CRS), conversion and transformation services derived from ISO 19111.

There is a newer version: 3.20-geoapi-3.0
Show newest version
/*
 *    Geotoolkit.org - An Open Source Java GIS Toolkit
 *    http://www.geotoolkit.org
 *
 *    (C) 2004-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.referencing.crs;

import java.util.Map;
import org.opengis.referencing.IdentifiedObject;
import org.geotoolkit.util.collection.DerivedMap;


/**
 * A map without the {@code "conversion."} prefix in front of property keys. This
 * implementation performs a special processing for the {@linkplain #prefix}.name
 * key: if it doesn't exists, then the plain {@code name} key is used. In other words,
 * this map inherits the {@code "name"} property from the {@linkplain #base} map.
 *
 * @author Martin Desruisseaux (IRD)
 * @version 3.00
 *
 * @since 2.0
 * @module
 */
final class UnprefixedMap extends DerivedMap {
    /**
     * For cross-version compatibility.
     */
    private static final long serialVersionUID = -5603681431606877770L;

    /**
     * The prefix to remove for this map.
     */
    private final String prefix;

    /**
     * {@code true} if the {@linkplain #prefix}.name property exists
     * in the {@linkplain #base base} map. This class will inherit the name and alias
     * from the {@linkplain #base base} map only if this field is set to {@code false}.
     */
    private final boolean hasName, hasAlias;

    /**
     * Creates a new unprefixed map from the specified base map and prefix.
     *
     * @param base   The base map.
     * @param prefix The prefix to remove from the keys in the base map.
     */
    @SuppressWarnings({"unchecked","rawtypes"}) // Okay because values are Object.
    public UnprefixedMap(final Map base, final String prefix) {
        super((Map) base, String.class);
        this.prefix = prefix.trim();
        final String  nameKey = this.prefix + IdentifiedObject. NAME_KEY;
        final String aliasKey = this.prefix + IdentifiedObject.ALIAS_KEY;
        boolean hasName  = false;
        boolean hasAlias = false;
        for (final Object value : base.keySet()) {
            final String candidate = value.toString().trim();
            if (keyMatches(nameKey, candidate)) {
                hasName = true;
                if (hasAlias) break;
            } else
            if (keyMatches(aliasKey, candidate)) {
                hasAlias = true;
                if (hasName) break;
            }
        }
        this.hasName  = hasName;
        this.hasAlias = hasAlias;
    }

    /**
     * Removes the prefix from the specified key. If the key doesn't begins with
     * the prefix, then this method returns {@code null}.
     *
     * @param  key A key from the {@linkplain #base} map.
     * @return The key that this view should contains instead of {@code key}, or {@code null}.
     */
    @Override
    protected String baseToDerived(final String key) {
        final int length = prefix.length();
        final String textualKey = key.trim();
        if (textualKey.regionMatches(true, 0, prefix, 0, length)) {
            return textualKey.substring(length).trim();
        }
        if (isPlainKey(textualKey)) {
            return textualKey;
        }
        return null;
    }

    /**
     * Adds the prefix to the specified key.
     *
     * @param  key A key in this map.
     * @return The key stored in the {@linkplain #base} map.
     */
    @Override
    protected String derivedToBase(final String key) {
        final String textualKey = key.trim();
        if (isPlainKey(textualKey)) {
            return textualKey;
        }
        return prefix + textualKey;
    }

    /**
     * Returns {@code true} if the specified candidate is {@code "name"}
     * or {@code "alias"} without prefix. Key starting with {@code "name_"}
     * or {@code "alias_"} are accepted as well.
     */
    private boolean isPlainKey(final String key) {
        return (!hasName  && keyMatches(IdentifiedObject.NAME_KEY,  key)) ||
               (!hasAlias && keyMatches(IdentifiedObject.ALIAS_KEY, key));
    }

    /**
     * Returns {@code true} if the specified candidate matched
     * the specified key name.
     */
    private static boolean keyMatches(final String key, final String candidate) {
        final int length = key.length();
        return candidate.regionMatches(true, 0, key, 0, length) &&
               (candidate.length() == length || candidate.charAt(length) == '_');
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy