com.bigdata.btree.keys.DefaultKeyBuilderFactory Maven / Gradle / Ivy
/*
Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016. All rights reserved.
Contact:
SYSTAP, LLC DBA Blazegraph
2501 Calvert ST NW #106
Washington, DC 20008
[email protected]
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
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
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* Created on Jul 3, 2008
*/
package com.bigdata.btree.keys;
import java.io.Serializable;
import java.util.Locale;
import java.util.Properties;
import org.apache.log4j.Logger;
import com.bigdata.btree.keys.KeyBuilder.Options;
/**
* Default factory for Unicode {@link IKeyBuilder}s. This does NOT generate
* thread-local instances. The factory serializes all properties that were
* required to generate a configuration so that the same configuration may be
* materialized on another JVM or host by de-serializing an instance of this
* factory.
*
* @see ThreadLocalKeyBuilderFactory
*
* @author Bryan Thompson
* @version $Id$
*/
public class DefaultKeyBuilderFactory implements IKeyBuilderFactory, Serializable {
protected static final transient Logger log = Logger.getLogger(DefaultKeyBuilderFactory.class);
// protected static final transient boolean INFO = log.isInfoEnabled();
//
// protected static final transient boolean log.isDebugEnabled() = log.isDebugEnabled();
/**
*
*/
private static final long serialVersionUID = -3285057306742134508L;
// private final transient boolean icu_avail;
/**
* The initial buffer capacity (grows as needed).
*/
private final int initialCapacity;
/**
* The selected collator.
*/
private final CollatorEnum collator;
/**
* The selected {@link Locale}.
*/
private final Locale locale;
/**
* The selected collator strength (MAY be null
, which means
* no override).
*/
private final Object strength;
/**
* The selected decomposition mode (MAY be null
, which means
* no override).
*/
private final DecompositionEnum decompositionMode;
/**
* The initial buffer capacity (the actual capacity grows as needed at
* runtime).
*/
public final int getInitialCapacity() {
return initialCapacity;
}
/**
* The selected collator.
*/
public final CollatorEnum getCollator() {
return collator;
}
/**
* The selected {@link Locale}.
*/
public final Locale getLocale() {
return locale;
}
/**
* The selected collator strength.
*
* @return Either a {@link StrengthEnum}, an {@link Integer}, or
* null
(which means no override).
*/
public final Object getStrength() {
return strength;
}
/**
* The selected decomposition mode (MAY be null
, which means
* no override).
*/
public final DecompositionEnum getDecompositionMode() {
return decompositionMode;
}
/**
* Representation includes all aspects of the {@link Serializable} state.
*/
@Override
public String toString() {
StringBuilder sb = new StringBuilder(getClass().getName());
sb.append("{ initialCapacity=" + initialCapacity);
sb.append(", collator=" + collator);
sb.append(", locale=" + locale);
sb.append(", strength=" + strength);
sb.append(", decomposition=" + decompositionMode);
sb.append("}");
return sb.toString();
}
/**
* Return the property if found in properties. If properties
* is null
or if the value is not found in properties,
* then return the property if found using
* {@link System#getProperty(String)}.
*
* @param properties
* The properties.
* @param key
* The key.
*
* @return The value -or- null
if no value was found.
*/
static private String getProperty(final Properties properties,
final String key) {
return getProperty(properties, key, null);
}
/**
* Return the property if found in properties. If properties
* is null
or if the value is not found in properties,
* then return the property if found using
* {@link System#getProperty(String)}.
*
* @param properties
* The properties.
* @param key
* The name of the desired property.
* @param def
* The default (MAY be null
).
*
* @return The value -or- def if no value was found.
*/
static private String getProperty(final Properties properties,
final String key, final String def) {
String val = null;
if (properties != null) {
val = properties.getProperty(key);//, def);
}
if (val == null) {
val = System.getProperty(key, def);
}
if(log.isDebugEnabled()) {
log.debug("name=" + key + ",val=" + val);
}
return val;
}
/**
* Create a factory for {@link IKeyBuilder} instances configured according
* to the specified properties. Any properties NOT explicitly given
* will be defaulted from {@link System#getProperties()}. The pre-defined
* properties {@link Options#USER_LANGUAGE}, {@link Options#USER_COUNTRY},
* and {@link Options#USER_VARIANT} MAY be overridden. The factory will
* support Unicode unless {@link CollatorEnum#ASCII} is explicitly specified
* for the {@link Options#COLLATOR} property.
*
* @param properties
* The properties to be used (optional). When null
* the {@link System#getProperties() System properties} are used.
*
* @see Options
*
* @throws UnsupportedOperationException
*
* The ICU library was required but was not located. Make sure
* that the ICU JAR is on the classpath. See
* {@link Options#COLLATOR}.
*
*
* Note: If you are trying to use ICU4JNI then that has to be
* locatable as a native library. How you do this is different
* for Windows and Un*x.
*
*/
public DefaultKeyBuilderFactory(final Properties properties) {
// default capacity : @todo config by property.
this.initialCapacity = 0;
final boolean icu_avail = isICUAvailable();
if(log.isInfoEnabled()) {
log.info("ICU library is" + (icu_avail ? "" : " not") + " available.");
}
{
/*
* Figure out which collator to use.
*/
collator = CollatorEnum.valueOf(getProperty(properties,
Options.COLLATOR, CollatorEnum.ICU.toString()));
// true iff the collator was _explicitly_ specified.
final boolean explicitCollatorChoice = getProperty(properties,
Options.COLLATOR) != null;
if (!explicitCollatorChoice) {
/*
* Choice was made by default rather than explicitly specified
* by a property.
*/
if (log.isInfoEnabled()) {
log.info("Defaulting: " + Options.COLLATOR + "="
+ collator);
}
}
}
{
/*
* Figure out what Locale to use.
*/
final String language = getProperty(properties, Options.USER_LANGUAGE);
final String country = getProperty(properties, Options.USER_COUNTRY);
final String variant = getProperty(properties, Options.USER_VARIANT);
if (language == null) {
locale = Locale.getDefault();
} else {
if (country == null) {
locale = new Locale(language);
} else if (variant == null) {
locale = new Locale(language, country);
} else {
locale = new Locale(language, country, variant);
}
}
if (log.isInfoEnabled()) {
log.info("Using default locale: " + locale.getDisplayName());
}
}
{
/*
* Figure out the collator strength.
*/
Object tmpStrength = null;
final String val = getProperty(properties, Options.STRENGTH);
if (val != null) {
try {
tmpStrength = StrengthEnum.valueOf(val);
} catch (RuntimeException ex) {
tmpStrength = Integer.parseInt(val);
}
}
if (log.isInfoEnabled())
log.info(Options.STRENGTH + "=" + tmpStrength);
/*
* Note: MAY be null (when null, does not override the collator's
* default).
*/
this.strength = tmpStrength;
}
{
/*
* Figure out the decomposition mode.
*/
DecompositionEnum mode = null;
if (getProperty(properties, Options.DECOMPOSITION) != null) {
mode = DecompositionEnum.valueOf(getProperty(properties,
Options.DECOMPOSITION));
if (log.isInfoEnabled())
log.info(Options.DECOMPOSITION + "=" + mode);
}
/*
* Note: MAY be null (when null, does not override the collator's
* default).
*/
this.decompositionMode = mode;
}
if(log.isInfoEnabled()) {
log.info(toString());
}
}
@Override
public IKeyBuilder getKeyBuilder() {
if(log.isDebugEnabled()) {
log.debug(toString());
}
return KeyBuilder.newInstance(initialCapacity, collator, locale,
strength, decompositionMode);
}
@Override
public IKeyBuilder getPrimaryKeyBuilder() {
if(log.isDebugEnabled()) {
log.debug(toString());
}
return KeyBuilder.newInstance(initialCapacity, collator, locale,
StrengthEnum.Primary, decompositionMode);
}
/**
* Text of the exception thrown when the ICU library is required but is not
* available.
*/
final public static String ICU_NOT_AVAILABLE = "The ICU library is not available.";
/**
* Figures out whether or not the ICU library is available.
*
* @return true
iff the ICU library is available.
*/
public static boolean isICUAvailable() {
boolean icu_avail;
try {
Class.forName("com.ibm.icu.text.RuleBasedCollator");
icu_avail = true;
} catch(Throwable t) {
log.warn("ICU library is not available");
icu_avail = false;
}
return icu_avail;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy