001: /*
002: * Copyright 2004-2006 the original author or authors.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.compass.core.converter.basic;
018:
019: import java.util.Locale;
020:
021: import org.compass.core.CompassException;
022: import org.compass.core.config.CompassConfigurable;
023: import org.compass.core.config.CompassEnvironment;
024: import org.compass.core.config.CompassSettings;
025: import org.compass.core.util.StringUtils;
026:
027: /**
028: * A base class that can handle {@link ThreadSafeFormat} and provide formatting support.
029: * The format is read from a configuration setting {@link CompassEnvironment.Converter.Format#FORMAT}.
030: * Uses a pool of formatters for better performance, using {@link CompassEnvironment.Converter.Format#MIN_POOL_SIZE},
031: * and {@link CompassEnvironment.Converter.Format#MAX_POOL_SIZE} as configuration settings for the pool size.
032: *
033: * <p>If specific locale is required for the formatted, the {@link CompassEnvironment.Converter.Format#LOCALE} can
034: * be used to specify the required locale.
035: *
036: * <p>Allows to specify the default format if none is provided by overriding {@link #doGetDefaultFormat()}.
037: *
038: * @author kimchy
039: */
040: public abstract class AbstractFormatConverter extends
041: AbstractBasicConverter implements CompassConfigurable,
042: FormatConverter {
043:
044: protected ThreadSafeFormat[] formatters;
045:
046: protected boolean hasFormatter = true;
047:
048: protected Locale locale;
049:
050: public void configure(CompassSettings settings)
051: throws CompassException {
052: String format = settings
053: .getSetting(CompassEnvironment.Converter.Format.FORMAT);
054: if (format == null) {
055: format = doGetDefaultFormat();
056: }
057: String localeSetting = settings
058: .getSetting(CompassEnvironment.Converter.Format.LOCALE);
059: if (localeSetting != null) {
060: locale = new Locale(localeSetting);
061: } else {
062: locale = Locale.getDefault();
063: }
064: if (format == null) {
065: hasFormatter = false;
066: return;
067: }
068: createFormatters(format, settings);
069: }
070:
071: public void setFormat(String format) {
072: createFormatters(format, null);
073: }
074:
075: public FormatConverter copy() {
076: try {
077: AbstractFormatConverter copy = (AbstractFormatConverter) getClass()
078: .newInstance();
079: copy.locale = locale;
080: return copy;
081: } catch (Exception e) {
082: throw new CompassException("Should not happen", e);
083: }
084: }
085:
086: protected abstract ThreadSafeFormat.FormatterFactory doCreateFormatterFactory();
087:
088: protected String doGetDefaultFormat() {
089: return null;
090: }
091:
092: private void createFormatters(String format,
093: CompassSettings settings) {
094: String[] formatStrings = StringUtils
095: .delimitedListToStringArray(format, "||");
096: formatters = new ThreadSafeFormat[formatStrings.length];
097: for (int i = 0; i < formatters.length; i++) {
098: String currentFromat = formatStrings[i];
099: ThreadSafeFormat.FormatterFactory formatterFactory = doCreateFormatterFactory();
100: formatterFactory.configure(currentFromat, locale);
101: int minPoolSize = 4;
102: int maxPoolSize = 20;
103: if (settings != null) {
104: minPoolSize = settings
105: .getSettingAsInt(
106: CompassEnvironment.Converter.Format.MIN_POOL_SIZE,
107: minPoolSize);
108: maxPoolSize = settings
109: .getSettingAsInt(
110: CompassEnvironment.Converter.Format.MAX_POOL_SIZE,
111: maxPoolSize);
112: }
113: formatters[i] = new ThreadSafeFormat(minPoolSize,
114: maxPoolSize, formatterFactory);
115: }
116: }
117:
118: /**
119: * Format based converters should can be used (and should) when using query parser notation.
120: * Returns <code>true</code>.
121: */
122: public boolean canNormalize() {
123: return true;
124: }
125: }
|