/*
* Copyright 2013 Martin Kouba
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.trimou.prettytime.resolver;
import static org.trimou.engine.priority.Priorities.rightAfter;
import java.util.Date;
import java.util.Locale;
import java.util.Set;
import org.ocpsoft.prettytime.PrettyTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.trimou.engine.cache.ComputingCache;
import org.trimou.engine.config.ConfigurationKey;
import org.trimou.engine.config.SimpleConfigurationKey;
import org.trimou.engine.convert.Converter;
import org.trimou.engine.convert.ObjectToDateConverter;
import org.trimou.engine.resolver.ArrayIndexResolver;
import org.trimou.engine.resolver.ResolutionContext;
import org.trimou.engine.resolver.Resolver;
import org.trimou.engine.resolver.TransformResolver;
import org.trimou.engine.validation.Validateable;
import org.trimou.prettytime.DefaultPrettyTimeFactory;
import org.trimou.prettytime.PrettyTimeFactory;
import org.trimou.prettytime.PrettyTimeHelper;
import org.trimou.util.Checker;
import org.trimou.util.ImmutableSet;
/**
* <p>
* The PrettyTime resolver. Developers are encouraged to use
* {@link PrettyTimeHelper} instead of this resolver to avoid the negative
* performance impact during interpolation.
* </p>
*
* <p>
* Use {@link #MATCH_NAME_KEY} configuration property to customize the name to
* match.
* </p>
*
* <p>
* If the configuration property with key {@link #ENABLED_KEY} resolves to
* false, the resolver is marked as invalid.
* </p>
*
* @author Martin Kouba
* @see Resolver
* @see PrettyTimeHelper
*/
public class PrettyTimeResolver extends TransformResolver implements
Validateable {
public static final int PRETTY_TIME_RESOLVER_PRIORITY = rightAfter(ArrayIndexResolver.ARRAY_RESOLVER_PRIORITY);
public static final String COMPUTING_CACHE_CONSUMER_ID = PrettyTimeResolver.class
.getName();
public static final ConfigurationKey MATCH_NAME_KEY = new SimpleConfigurationKey(
PrettyTimeResolver.class.getName() + ".matchName", "prettyTime");
public static final ConfigurationKey ENABLED_KEY = new SimpleConfigurationKey(
PrettyTimeResolver.class.getName() + ".enabled", false);
private static final Logger LOGGER = LoggerFactory
.getLogger(PrettyTimeResolver.class);
private final PrettyTimeFactory factory;
private final Converter<Object, Date> converter;
/**
* Lazy loading cache of PrettyTime instances
*/
private ComputingCache<Locale, PrettyTime> prettyTimeCache;
/**
*
*/
public PrettyTimeResolver() {
this(PRETTY_TIME_RESOLVER_PRIORITY, new DefaultPrettyTimeFactory());
}
/**
*
* @param priority
* @param prettyTimeFactory
*/
public PrettyTimeResolver(int priority, PrettyTimeFactory prettyTimeFactory) {
this(priority, prettyTimeFactory, new ObjectToDateConverter());
}
/**
*
* @param priority
* @param factory
* @param converter
*/
public PrettyTimeResolver(int priority, PrettyTimeFactory factory,
Converter<Object, Date> converter) {
super(priority);
Checker.checkArgumentsNotNull(factory, converter);
this.factory = factory;
this.converter = converter;
}
@Override
public Object transform(Object contextObject, String name,
ResolutionContext context) {
Date value = converter.convert(contextObject);
if (value == null) {
return null;
}
return prettyTimeCache.get(getCurrentLocale()).format(value);
}
@Override
public Set<ConfigurationKey> getConfigurationKeys() {
return ImmutableSet.of(MATCH_NAME_KEY, ENABLED_KEY);
}
@Override
public void init() {
if (!configuration.getBooleanPropertyValue(ENABLED_KEY)) {
return;
}
super.init();
setMatchingNames(configuration.getStringPropertyValue(MATCH_NAME_KEY));
prettyTimeCache = configuration.getComputingCacheFactory().create(
COMPUTING_CACHE_CONSUMER_ID,
factory::createPrettyTime, null, 10L, null);
LOGGER.info("Initialized [matchingName: {}]", matchingName(0));
}
@Override
public boolean isValid() {
return prettyTimeCache != null;
}
}