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

org.firebirdsql.encodings.EncodingFactory Maven / Gradle / Ivy

There is a newer version: 4.0.10.java7
Show newest version
/*
 * Firebird Open Source JavaEE Connector - JDBC Driver
 *
 * Distributable under LGPL license.
 * You may obtain a copy of the License at http://www.gnu.org/copyleft/lgpl.html
 *
 * This program 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
 * LGPL License for more details.
 *
 * This file was created by members of the firebird development team.
 * All individual contributions remain the Copyright (C) of those
 * individuals.  Contributors to this file are either listed here or
 * can be obtained from a source control history command.
 *
 * All rights reserved.
 */
package org.firebirdsql.encodings;

import org.firebirdsql.gds.ISCConstants;
import org.firebirdsql.logging.Logger;
import org.firebirdsql.logging.LoggerFactory;

import java.nio.charset.Charset;
import java.nio.charset.IllegalCharsetNameException;
import java.nio.charset.UnsupportedCharsetException;
import java.sql.SQLException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import static org.firebirdsql.gds.ISCConstants.CS_dynamic;

/**
 * Factory for {@link EncodingDefinition} and {@link Encoding}.
 *
 * @author Mark Rotteveel
 */
public final class EncodingFactory implements IEncodingFactory {

    private static final Logger log = LoggerFactory.getLogger(EncodingFactory.class);

    private static final Charset DEFAULT_CHARSET = Charset.defaultCharset();
    private static final int MAX_NORMAL_CHARSET_ID = 255;
    private static final Comparator ENCODING_SET_COMPARATOR = new Comparator() {
        @Override
        public int compare(final EncodingSet o1, final EncodingSet o2) {
            return o1.getPreferenceWeight() - o2.getPreferenceWeight();
        }
    };

    public static final String ENCODING_NAME_NONE = "NONE";
    public static final String ENCODING_NAME_OCTETS = "OCTETS";

    /**
     * Holder class to ensure static fields of EncodingFactory are properly initialized before the default instance can
     * be loaded/created
     */
    private static class DefaultEncodingFactory {
        private static final EncodingFactory ROOT_ENCODING_FACTORY;
        private static final IEncodingFactory PLATFORM_DEFAULT_INSTANCE;
        static {
            ROOT_ENCODING_FACTORY = createInstance();
            PLATFORM_DEFAULT_INSTANCE = ROOT_ENCODING_FACTORY
                    .withDefaultEncodingDefinition();
        }
    }

    // Linked HashMap because we need to preserve insertion order for the lazy initialization;
    // Initial capacity of 128 should prevent resizing during loading (if only DefaultEncodingSet is present)
    private final Map firebirdEncodingToDefinition = new LinkedHashMap<>(128);
    private final EncodingDefinition[] firebirdCharacterSetIdToDefinition =
            new EncodingDefinition[MAX_NORMAL_CHARSET_ID + 1];
    private final Map javaCharsetToDefinition = new ConcurrentHashMap<>();
    private final Map javaAliasesToDefinition = new ConcurrentHashMap<>();
    private final Encoding defaultEncoding;
    private final EncodingDefinition defaultEncodingDefinition;
    private final ConcurrentMap translations = new ConcurrentHashMap<>();

    /**
     * Initializes EncodingFactory by processing the encodingSets using the provided iterator.
     *
     * @param encodingSets
     *         Iterator of {@link EncodingSet} instances
     */
    private EncodingFactory(Iterator encodingSets) {
        while (encodingSets.hasNext()) {
            processEncodingSet(encodingSets.next());
        }
        // Ensure CS_dynamic to be null
        firebirdCharacterSetIdToDefinition[CS_dynamic] = null;
        final EncodingDefinition candidateDefinition = getEncodingDefinitionByCharset(DEFAULT_CHARSET);

        if (candidateDefinition != null && !candidateDefinition.isInformationOnly()) {
            defaultEncoding = candidateDefinition.getEncoding();
            defaultEncodingDefinition = candidateDefinition;
        } else {
            defaultEncoding = new EncodingGeneric(DEFAULT_CHARSET);
            defaultEncodingDefinition =
                    new DefaultEncodingDefinition(ENCODING_NAME_NONE, DEFAULT_CHARSET, 1, ISCConstants.CS_NONE, false);
        }
    }

    @Override
    public Encoding getDefaultEncoding() {
        return defaultEncoding;
    }

    /**
     * @return The default encoding of the platform.
     */
    public static Encoding getPlatformEncoding() {
        return getRootEncodingFactory().getDefaultEncoding();
    }

    @Override
    public EncodingDefinition getDefaultEncodingDefinition() {
        return defaultEncodingDefinition;
    }

    @Override
    public EncodingDefinition getEncodingDefinitionByFirebirdName(final String firebirdEncodingName) {
        return firebirdEncodingName != null ? firebirdEncodingToDefinition.get(firebirdEncodingName.toLowerCase()) : null;
    }

    /**
     * Gets an {@link org.firebirdsql.encodings.Encoding} for the specified Firebird encoding. If there is no known
     * encoding for this name, or the loaded EncodingDefinition is information-only, then the fallbackEncoding.
     *
     * @param firebirdEncodingName
     *         The Firebird encoding name (case insensitive)
     * @param fallbackEncoding
     *         The Encoding to use as fallback if no encoding is found (usually the connection encoding). If
     *         null, the defaultEncoding for the JVM is used.
     * @return Encoding instance (never null)
     */
    public Encoding getEncodingForFirebirdName(final String firebirdEncodingName, final Encoding fallbackEncoding) {
        return returnEncodingOrFallback(getEncodingDefinitionByFirebirdName(firebirdEncodingName), fallbackEncoding);
    }

    @Override
    public Encoding getEncodingForFirebirdName(final String firebirdEncodingName) {
        return getEncodingForFirebirdName(firebirdEncodingName, null);
    }

    @Override
    public EncodingDefinition getEncodingDefinitionByCharacterSetId(final int firebirdCharacterSetId) {
        return firebirdCharacterSetIdToDefinition[firebirdCharacterSetId & 0xFF];
    }

    /**
     * Gets an {@link org.firebirdsql.encodings.Encoding} for the specified Firebird character set id. If there is no
     * known encoding for this character set id (or if it is 127, see {@link #getEncodingDefinitionByCharacterSetId(int)}),
     * or the loaded EncodingDefinition is information-only, then the fallbackEncoding will be used.
     *
     * @param firebirdCharacterSetId
     *         The Firebird character set id
     * @param fallbackEncoding
     *         The Encoding to use as fallback if no encoding is found (usually the connection encoding). If
     *         null, the defaultEncoding for the JVM is used.
     * @return Encoding instance (never null)
     */
    public Encoding getEncodingForCharacterSetId(final int firebirdCharacterSetId, final Encoding fallbackEncoding) {
        return returnEncodingOrFallback(getEncodingDefinitionByCharacterSetId(firebirdCharacterSetId), fallbackEncoding);
    }

    @Override
    public Encoding getEncodingForCharacterSetId(final int firebirdCharacterSetId) {
        return getEncodingForCharacterSetId(firebirdCharacterSetId, null);
    }

    @Override
    public EncodingDefinition getEncodingDefinitionByCharset(final Charset charset) {
        EncodingDefinition encodingDefinition = javaCharsetToDefinition.get(charset);
        if (encodingDefinition != null) {
            return encodingDefinition;
        }
        return findAndMapEncodingDefinition(charset);
    }

    private EncodingDefinition findAndMapEncodingDefinition(final Charset charset) {
        final Set potentialNames = toLowerCaseAliasSet(charset);
        for (EncodingDefinition encodingDefinition : firebirdEncodingToDefinition.values()) {
            String javaEncodingName = encodingDefinition.getJavaEncodingName();
            if (javaEncodingName != null && !encodingDefinition.isFirebirdOnly()
                    && potentialNames.contains(javaEncodingName.toLowerCase())) {
                registerJavaMappingForEncodingDefinition(encodingDefinition);
                return encodingDefinition;
            }
        }
        return null;
    }

    @Override
    public Encoding getEncodingForCharset(final Charset charset, final Encoding fallbackEncoding) {
        return returnEncodingOrFallback(getEncodingDefinitionByCharset(charset), fallbackEncoding);
    }

    @Override
    public Encoding getEncodingForCharset(final Charset charset) {
        return getEncodingForCharset(charset, null);
    }

    @Override
    public Encoding getOrCreateEncodingForCharset(final Charset charset) {
        return getEncodingForCharset(charset, new EncodingGeneric(charset));
    }

    @Override
    public EncodingDefinition getEncodingDefinitionByCharsetAlias(final String charsetAlias) {
        if (charsetAlias == null) {
            return null;
        }
        EncodingDefinition encodingDefinition = javaAliasesToDefinition.get(charsetAlias.toLowerCase());
        if (encodingDefinition != null) {
            return encodingDefinition;
        }
        return resolveEncodingDefinitionByCharset(charsetAlias);
    }

    /**
     * Gets an {@link org.firebirdsql.encodings.Encoding} for the specified Java character set name or alias. If there
     * is no known encoding for this name, or the loaded EncodingDefinition is information-only, then the
     * fallbackEncoding will be used.
     *
     * @param charsetAlias
     *         The Java character set name or alias
     * @param fallbackEncoding
     *         The Encoding to use as fallback if no encoding is found (usually the connection encoding). If
     *         null, the defaultEncoding for the JVM is used.
     * @return Encoding instance (never null)
     */
    public Encoding getEncodingForCharsetAlias(final String charsetAlias, final Encoding fallbackEncoding) {
        return returnEncodingOrFallback(getEncodingDefinitionByCharsetAlias(charsetAlias), fallbackEncoding);
    }

    @Override
    public Encoding getEncodingForCharsetAlias(final String charsetAlias) {
        return getEncodingForCharsetAlias(charsetAlias, null);
    }

    @Override
    public CharacterTranslator getCharacterTranslator(String mappingPath) throws SQLException {
        if (mappingPath == null) return null;
        CharacterTranslator translator = translations.get(mappingPath);
        if (translator != null) {
            return translator;
        }

        translator = CharacterTranslator.create(mappingPath);
        translations.putIfAbsent(mappingPath, translator);

        return translations.get(mappingPath);
    }

    @Override
    public EncodingDefinition getEncodingDefinition(final String firebirdEncodingName, final String javaCharsetAlias) {
        try {
            EncodingDefinition encodingDefinition = null;
            Charset charset = null;
            // TODO Consider returning getDefaultEncodingDefinition() if both firebirdEncodingName and javaCharsetAlias are NULL
            if (firebirdEncodingName != null) {
                encodingDefinition = getEncodingDefinitionByFirebirdName(firebirdEncodingName);
                if (javaCharsetAlias != null) {
                    charset = Charset.forName(javaCharsetAlias);
                } else if (encodingDefinition != null) {
                    charset = encodingDefinition.getJavaCharset();
                }
            } else if (javaCharsetAlias != null) {
                encodingDefinition = getEncodingDefinitionByCharsetAlias(javaCharsetAlias);
                if (encodingDefinition != null) {
                    charset = encodingDefinition.getJavaCharset();
                }
            }

            if (encodingDefinition == null) {
                // TODO Consider throwing exception if no EncodingDefinition is found
                return null;
            } else if (!encodingDefinition.isInformationOnly()
                    && (charset == null || encodingDefinition.getJavaCharset().equals(charset))) {
                // Normal encoding definition
                return encodingDefinition;
            } else if (charset != null) {
                /* Construct non-standard combination of Firebird encoding + Java character set
                 * This allows for special purpose combinations like Firebird ISO8859_3 with Java ISO-8859-1
                 * But is mostly intended for using Firebird NONE with a specific java character set
                 */
                return new DefaultEncodingDefinition(encodingDefinition.getFirebirdEncodingName(), charset, encodingDefinition.getMaxBytesPerChar(),
                        encodingDefinition.getFirebirdCharacterSetId(), false);
            } else if (ENCODING_NAME_NONE.equalsIgnoreCase(firebirdEncodingName)) {
                encodingDefinition = getDefaultEncodingDefinition();
                return new DefaultEncodingDefinition(ENCODING_NAME_NONE, encodingDefinition.getJavaCharset(), 1, ISCConstants.CS_NONE, false);
            }
            // TODO Consider throwing exception if no EncodingDefinition is found
            return null;
        } catch (Exception e) {
            log.debug(String.format("Exception looking up encoding definition for firebirdEncodingName %s, javaCharsetAlias %s", firebirdEncodingName, javaCharsetAlias), e);
            return null;
        }
    }

    /**
     * {@inheritDoc}
     * 

* This implementation returns an instance of {@link ConnectionEncodingFactory}. *

*/ @Override public IEncodingFactory withDefaultEncodingDefinition(EncodingDefinition encodingDefinition) { return new ConnectionEncodingFactory(this, encodingDefinition != null && !encodingDefinition.isInformationOnly() ? encodingDefinition : getDefaultEncodingDefinition()); } /** * {@inheritDoc} *

* This implementation returns an instance of {@link ConnectionEncodingFactory}. *

*/ @Override public IEncodingFactory withDefaultEncodingDefinition(Charset charset) { return new ConnectionEncodingFactory(this, getEncodingDefinitionByCharset(charset)); } /** * Returns an {@link org.firebirdsql.encodings.ConnectionEncodingFactory} that uses * {@link #getDefaultEncodingDefinition()} as the default. * * @return IEncodingFactory instance with the specified default. */ public IEncodingFactory withDefaultEncodingDefinition() { return withDefaultEncodingDefinition(getDefaultEncodingDefinition()); } /** * Loads the {@link EncodingSet} instances from the classpath (using {@link ServiceLoader}). * * @see EncodingSet */ @SuppressWarnings("WhileLoopReplaceableByForEach") private static NavigableSet loadEncodingSets() { final TreeSet encodingSets = new TreeSet<>(ENCODING_SET_COMPARATOR); final ServiceLoader encodingSetLoader = ServiceLoader.load(EncodingSet.class, EncodingFactory.class.getClassLoader()); // We can't use foreach here, because the encoding sets are lazily loaded, which might trigger a ServiceConfigurationError Iterator encodingSetIterator = encodingSetLoader.iterator(); // Load the encoding sets and populate the TreeMap while (encodingSetIterator.hasNext()) { try { final EncodingSet encodingSet = encodingSetIterator.next(); encodingSets.add(encodingSet); } catch (Exception | ServiceConfigurationError e) { log.error("Could not load encoding set (skipping): " + e.getMessage(), e); } } return encodingSets; } /** * Loads the {@link EncodingDefinition} instance from a single {@link EncodingSet} instance. * * @param encodingSet * The EncodingSet to process */ private void processEncodingSet(final EncodingSet encodingSet) { if (log.isDebugEnabled()) log.debug(String.format("Processing EncodingSet %s with preference weight %d", encodingSet.getClass().getName(), encodingSet.getPreferenceWeight())); for (EncodingDefinition encodingDefinition : encodingSet.getEncodings()) { processEncodingDefinition(encodingDefinition); } } /** * Maps an {@link EncodingDefinition} instance from the Firebird encoding and Java charset names. This is skipped * if * there already is an instance mapped for the Firebird encoding name. * * @param encodingDefinition * The EncodingDefinition */ private void processEncodingDefinition(final EncodingDefinition encodingDefinition) { final String firebirdEncodingName = encodingDefinition.getFirebirdEncodingName(); final int firebirdCharacterSetId = encodingDefinition.getFirebirdCharacterSetId(); if (firebirdEncodingToDefinition.containsKey(firebirdEncodingName.toLowerCase())) { // We already loaded a definition for this encoding if (log.isDebugEnabled()) log.debug(String.format("Skipped loading encoding definition for Firebird encoding %s, already loaded a definition for that name", firebirdEncodingName)); return; } else if (firebirdCharacterSetId == CS_dynamic) { if (log.isDebugEnabled()) log.debug(String.format("Skipped loading encoding definition for Firebird encoding %s, as it declared itself as the connection character set (FirebirdCharacterSetId 127 or CS_dynamic)", firebirdEncodingName)); return; } else if (firebirdCharacterSetId < 0 || firebirdCharacterSetId > MAX_NORMAL_CHARSET_ID) { log.warn(String.format("Skipped loading encoding definition for Firebird encoding %s, as it declared itself as FirebirdCharacterSetId %d, which is outside the range [0, 255]", firebirdEncodingName, firebirdCharacterSetId)); return; } // Map firebird encoding and character set id to EncodingDefinition firebirdEncodingToDefinition.put(firebirdEncodingName.toLowerCase(), encodingDefinition); // We don't check whether the characterSetId is already mapped, as a characterSetId should map to a single Firebird encoding firebirdCharacterSetIdToDefinition[firebirdCharacterSetId] = encodingDefinition; // We are not mapping to Java charset / aliases here; that is delayed until really needed } private void registerJavaMappingForEncodingDefinition(EncodingDefinition encodingDefinition) { final Charset charset = encodingDefinition.getJavaCharset(); if (encodingDefinition.isInformationOnly() || encodingDefinition.isFirebirdOnly() || charset == null) { return; } final EncodingDefinition currentEncodingDefinition = javaCharsetToDefinition.get(charset); if (currentEncodingDefinition == null) { // Map Java charset to EncodingDefinition javaCharsetToDefinition.put(charset, encodingDefinition); javaAliasesToDefinition.put(charset.name().toLowerCase(), encodingDefinition); for (String charsetAlias : charset.aliases()) { javaAliasesToDefinition.put(charsetAlias.toLowerCase(), encodingDefinition); } } else if (log.isDebugEnabled()) { log.debug(String.format( "Not mapping java charset %s to Firebird encoding %s, already mapped to Firebird encoding %s", charset.name(), encodingDefinition.getEncoding(), currentEncodingDefinition.getFirebirdEncodingName())); } } /** * Returns the {@link Encoding} from the encodingDefinition. If encodingDefinition is null, information-only or * doesn't create an Encoding, it will return the fallbackEncoding. If fallbackEncoding is null, then {@link * #getDefaultEncoding()} is used. * * @param encodingDefinition * EncodingDefinition instance * @param fallbackEncoding * Encoding instance for fallback (default encoding for this VM is used if null) * @return Encoding instance */ private Encoding returnEncodingOrFallback(EncodingDefinition encodingDefinition, Encoding fallbackEncoding) { if (fallbackEncoding == null) { fallbackEncoding = getDefaultEncoding(); } if (encodingDefinition == null || encodingDefinition.isInformationOnly()) { return fallbackEncoding; } Encoding encoding = encodingDefinition.getEncoding(); if (encoding != null) { return encoding; } // We only get here if the EncodingDefinition implementation does not adhere to the contract if (log.isDebugEnabled()) { log.debug(String.format("EncodingDefinition for Firebird encoding %s returned null for getEncoding(), using fallback encoding", encodingDefinition.getFirebirdEncodingName())); } return fallbackEncoding; } /** * Returns the root instance of EncodingFactory. * * @return The root instance of EncodingFactory * @see #createInstance() */ static EncodingFactory getRootEncodingFactory() { return DefaultEncodingFactory.ROOT_ENCODING_FACTORY; } /** * Returns an instance of {@link IEncodingFactory} with the default encoding set to the platform encoding. * * @return Instance of {@link IEncodingFactory}. */ public static IEncodingFactory getPlatformDefault() { return DefaultEncodingFactory.PLATFORM_DEFAULT_INSTANCE; } /** * Returns an {@link org.firebirdsql.encodings.IEncodingFactory} that uses {@code encodingDefinition} as the * default. *

* If {@code encodingDefinition} is {@code null} or an information-only encoding, the implementation will * return the cached instance returned by {@link #getPlatformDefault()}. *

* * @param encodingDefinition * The default encoding to use (or {@code null} to get {@link #getPlatformDefault()} * @return IEncodingFactory instance with the specified default. */ public static IEncodingFactory createInstance(EncodingDefinition encodingDefinition) { if (encodingDefinition == null || encodingDefinition.isInformationOnly()) { return getPlatformDefault(); } return getRootEncodingFactory().withDefaultEncodingDefinition(encodingDefinition); } /** * Returns an {@link IEncodingFactory} that uses an {@link EncodingDefinition} identified * by {@code charSet} as the default. *

* If {@code charset} is {@code null}, the implementation will return the cached instance return by * {@link #getPlatformDefault()}. *

* * @param charset * The default charset to use, or {@code null} for {@link #getPlatformDefault()}. * @return IEncodingFactory instance with the specified default. */ public static IEncodingFactory createInstance(Charset charset) { if (charset == null) { return getPlatformDefault(); } return getRootEncodingFactory().withDefaultEncodingDefinition(charset); } /** * @return A new instance of EncodingFactory */ private static EncodingFactory createInstance() { // Process the encoding sets in descending order NavigableSet encodingSets = loadEncodingSets(); if (encodingSets.isEmpty()) { log.warn("No encoding sets were loaded. Make sure at least one valid /META-INF/services/org.firebirdsql.encodings.EncodingSet " + "exists on the classpath (it is normally part of the jaybird jar-file). Falling back to default definition."); encodingSets.add(new DefaultEncodingSet()); } return new EncodingFactory(encodingSets.descendingIterator()); } /** * Creates a new EncodingFactory based on the supplied encodingSets. The supplied {@link EncodingSet} instances * are processed highest preferenceWeight first. * * @param encodingSets * The EncodingSet definitions to use for the EncodingFactory instance * @return EncodingFactory instance based on the supplied encodingSets. */ public static EncodingFactory createInstance(EncodingSet... encodingSets) { TreeSet sortedEncodingSets = new TreeSet<>(ENCODING_SET_COMPARATOR); // Load the encoding sets and populate the TreeMap Collections.addAll(sortedEncodingSets, encodingSets); // Process the encoding sets in descending order return new EncodingFactory(sortedEncodingSets.descendingIterator()); } /** * Get size of a character for the specified character set. * * @param characterSetId * of the character set. * @return maximum size of the character in bytes or 1 if charset was not * found. * @deprecated Use the information provided by the {@link EncodingDefinition} returned by {@link * #getEncodingDefinitionByCharacterSetId(int)} */ @Deprecated public static int getCharacterSetSize(int characterSetId) { final EncodingDefinition encodingDefinition = getRootEncodingFactory() .getEncodingDefinitionByCharacterSetId(characterSetId); return encodingDefinition != null ? encodingDefinition.getMaxBytesPerChar() : 1; } /** * Gets an {@link Encoding} instance for the supplied java Charset name. * * @param javaCharsetAlias * Java Charset name * @return Instance of {@link Encoding} * @deprecated Use {@link #getEncodingForCharsetAlias(String, Encoding)} */ @Deprecated public static Encoding getEncoding(String javaCharsetAlias) { return getRootEncodingFactory().getEncodingForCharsetAlias(javaCharsetAlias, null); } /** * Gets an {@link Encoding} instance for the supplied java Charset. * * @param charset * Java Charset * @return Instance of {@link Encoding} * @deprecated Use {@link #getEncodingForCharset(java.nio.charset.Charset, Encoding)} or {@link * #getOrCreateEncodingForCharset(java.nio.charset.Charset)} */ @Deprecated public static Encoding getEncoding(Charset charset) { return getRootEncodingFactory().getOrCreateEncodingForCharset(charset); } /** * Gets an {@link Encoding} instance for the supplied java Charset name and * alternative character mapping. * * @param encoding * Java Charset name * @param mappingPath * Resource file with alternative character mapping * @return Instance of {@link Encoding} * @deprecated To be removed in Jaybird 4, use {@link #getEncodingForCharsetAlias(String)} */ @Deprecated @SuppressWarnings("deprecation") public static Encoding getEncoding(String encoding, String mappingPath) throws SQLException { EncodingDefinition encodingDefinition = getRootEncodingFactory().getEncodingDefinitionByCharsetAlias(encoding); // TODO Express this in terms of other methods of this factory? Charset charset = null; if (encodingDefinition != null) { charset = encodingDefinition.getJavaCharset(); } if (charset == null) { charset = DEFAULT_CHARSET; } return getEncoding(charset, mappingPath); } /** * Gets an {@link Encoding} instance for the supplied java Charset and * alternative character mapping. * * @param charset * Java Charset * @param mappingPath * Resource file with alternative character mapping * @return Instance of {@link Encoding} * @deprecated To be removed in Jaybird 4, use {@link #getEncodingForCharset(Charset)} */ @Deprecated @SuppressWarnings("deprecation") public static Encoding getEncoding(Charset charset, String mappingPath) throws SQLException { final Encoding encoding = getEncoding(charset); return mappingPath == null ? encoding : encoding.withTranslation(getTranslator(mappingPath)); } /** * Get Firebird encoding for given Java language encoding. * * @param javaCharsetAlias * Java language encoding. * @return corresponding Firebird encoding or null if none * found. * @deprecated Use {@link #getEncodingDefinitionByCharsetAlias(String)} */ @Deprecated @SuppressWarnings("deprecation") public static String getIscEncoding(String javaCharsetAlias) { final EncodingDefinition encodingDefinition = getRootEncodingFactory() .getEncodingDefinitionByCharsetAlias(javaCharsetAlias); return encodingDefinition != null ? encodingDefinition.getFirebirdEncodingName() : null; } /** * Get Firebird encoding for given Java Charset. * * @param javaCharset * Java Charset * @return corresponding Firebird encoding or null if none * found. * @deprecated Use {@link #getEncodingDefinitionByCharset(java.nio.charset.Charset)} */ @Deprecated public static String getIscEncoding(Charset javaCharset) { final EncodingDefinition encodingDefinition = getRootEncodingFactory() .getEncodingDefinitionByCharset(javaCharset); return encodingDefinition != null ? encodingDefinition.getFirebirdEncodingName() : null; } /** * Get size of a character for the specified Firebird encoding. * * @param iscEncoding * Firebird encoding. * @return maximum size of the character in bytes or 1 if encoding was not * found. * @deprecated Use {@link #getEncodingDefinitionByFirebirdName(String)} and {@link EncodingDefinition#getMaxBytesPerChar()} */ @Deprecated public static int getIscEncodingSize(String iscEncoding) { if (iscEncoding == null) { return 1; } final EncodingDefinition encodingDefinition = getRootEncodingFactory() .getEncodingDefinitionByFirebirdName(iscEncoding); return encodingDefinition != null ? encodingDefinition.getMaxBytesPerChar() : 1; } /** * Get Java language encoding for given Firebird encoding. * * @param iscEncoding * Firebird encoding * @return corresponding Java encoding or null if none found. * Use {@link #getEncodingDefinitionByFirebirdName(String)} and {@link org.firebirdsql.encodings.EncodingDefinition#getJavaEncodingName()} */ @Deprecated public static String getJavaEncoding(String iscEncoding) { if (iscEncoding == null) { return null; } final EncodingDefinition encodingDefinition = getRootEncodingFactory() .getEncodingDefinitionByFirebirdName(iscEncoding); // TODO: Test the claim below // very important for performance // if javaEncoding is the default one, set to null if (encodingDefinition == null || DEFAULT_CHARSET.equals(encodingDefinition.getJavaCharset())) { return null; } return encodingDefinition.getJavaEncodingName(); } /** * Get Java language encoding for a given Java encoding alias. *

* Ensures that naming is consistent even if a different alias was used. *

* * @param javaAlias * Java alias for the encoding * @return Java Charset name * @deprecated Use {@link #getEncodingDefinitionByCharsetAlias(String)} and {@link * EncodingDefinition#getJavaEncodingName()} */ @Deprecated public static String getJavaEncodingForAlias(String javaAlias) { final EncodingDefinition encodingDefinition = getRootEncodingFactory() .getEncodingDefinitionByCharsetAlias(javaAlias); // TODO: Test the claim below // very important for performance // if javaEncoding is the default one, set to null if (encodingDefinition == null || DEFAULT_CHARSET.equals(encodingDefinition.getJavaCharset())) { return null; } return encodingDefinition.getJavaEncodingName(); } /** * Gets the {@link CharacterTranslator} for the specified mappingPath, or null if there is no such * mappingPath * * @param mappingPath * Path of the mapping definition file * @return CharacterTranslator or null * @throws SQLException */ public static CharacterTranslator getTranslator(String mappingPath) throws SQLException { return getRootEncodingFactory().getCharacterTranslator(mappingPath); } /** * Resolves the encoding definition by getting the {@code Charset} of the alias, and then retrieving by charset. *

* This is a fallback mechanism if the character set has not been loaded yet. *

* * @param charsetAlias Java character set alias * @return Encoding definition, or {@code null} if not found */ private EncodingDefinition resolveEncodingDefinitionByCharset(final String charsetAlias) { try { Charset charset = Charset.forName(charsetAlias); return getEncodingDefinitionByCharset(charset); } catch (UnsupportedCharsetException | IllegalCharsetNameException e) { return null; } } /** * Set of the charset name and aliases in lower case. * * @param charset Character set * @return Set of lower case names and aliases */ private static Set toLowerCaseAliasSet(final Charset charset) { final Set aliases = charset.aliases(); final Set potentialNames = new HashSet<>(aliases.size() + 1); potentialNames.add(charset.name().toLowerCase()); for (String alias : aliases) { potentialNames.add(alias.toLowerCase()); } return potentialNames; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy