/* Copyright (2007-2012) Schibsted ASA * This file is part of Possom. * * Possom 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, either version 3 of the License, or * (at your option) any later version. * * Possom 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. * * You should have received a copy of the GNU Lesser General Public License * along with Possom. If not, see <http://www.gnu.org/licenses/>. */ package no.sesat.search.query.transform; import no.schibstedsok.newsadmin.service.NewsCaseFacade; import no.sesat.search.query.Clause; import org.apache.log4j.Logger; import javax.naming.InitialContext; import javax.naming.NamingException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Properties; import java.util.TimeZone; /** * Checks if the query should be transformed from a ejb lookup on the queryParameter. Transformation will replace * the whole query. * <p/> * <b>Note:</b> This queryTransformer ignores all earlier transforms on the query. All transforms to the resulting * query should be done after this. */ public final class NewsCaseQueryTransformer extends AbstractQueryTransformer { private final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); private final static Logger LOG = Logger.getLogger(NewsCaseQueryTransformer.class); private NewsQueryTransformerDataAccess dataAccess = new NewsQueryTransformerDataAccess(); private final NewsCaseQueryTransformerConfig config; /** * @param config */ public NewsCaseQueryTransformer(final QueryTransformerConfig config) { this.config = (NewsCaseQueryTransformerConfig) config; sdf.setTimeZone(TimeZone.getTimeZone(this.config.getTimeZone())); } /** * @param clause */ public void visitImpl(final Clause clause) { dataAccess.setProperties(getContext().getDataModel().getSite().getSiteConfiguration().getProperties()); String queryString; if (config.getQueryParameter() == null) { queryString = getTransformedTermsQuery(); } else { queryString = (String) getContext().getDataModel().getJunkYard().getValue(config.getQueryParameter()); } LOG.debug("Original query is: '" + queryString + "'"); if (queryString != null && queryString.length() > 0) { String transformedQuery = dataAccess.getQuery(queryString, config.getQueryType(),config.getAggregatorId()); if (transformedQuery == null) { transformedQuery = defaultTransform(queryString); } for (Clause keyClause : getContext().getTransformedTerms().keySet()) { getContext().getTransformedTerms().put(keyClause, ""); } if (config.isUnclusteredDelay()) { transformedQuery = addUnclusteredDelayFilter(transformedQuery); } LOG.debug("New query is: '" + transformedQuery + "'"); if (transformedQuery.length() > 0) { getContext().getDataModel().getJunkYard().setValue(config.getQueryType(), transformedQuery); getContext().getTransformedTerms().put(getContext().getQuery().getFirstLeafClause(), transformedQuery); } } } private String addUnclusteredDelayFilter(String transformedQuery) { if (transformedQuery != null && transformedQuery.length() > 0) { Calendar cal = Calendar.getInstance(TimeZone.getTimeZone(config.getTimeZone())); cal.add(Calendar.MINUTE, -config.getUnclusteredDelayInMinutes()); StringBuilder sb = new StringBuilder(transformedQuery); sb.insert(0, "and("); sb.append(",cluster:range(1,max) or processingtime:range(min,"); sb.append(sdf.format(cal.getTime())); sb.append("))"); return sb.toString(); } else { return transformedQuery; } } private String getTransformedTermsQuery() { StringBuilder query = new StringBuilder(); for (Clause keyClause : getContext().getTransformedTerms().keySet()) { query.append(getContext().getTransformedTerms().get(keyClause)); } return query.toString(); } private String defaultTransform(String queryString) { if (config.getTypeConversions() != null) { String type = (String) getContext().getDataModel().getJunkYard().getValue(config.getTypeParameter()); if (type == null) { type = config.getDefaultType(); } if (type != null) { String[] conversion = config.getTypeConversions().get(type); if (conversion != null) { return conversion[0] + queryString + conversion[1]; } } } return '"' + queryString + '"'; } /** * */ public static class NewsQueryTransformerDataAccess { private Properties properties; private static final String NEWSADMIN_JNDINAME = "newsadmin.jndiname"; /** * @param properties */ public void setProperties(Properties properties) { this.properties = properties; } /** * @return */ public NewsCaseFacade lookupDataService() { InitialContext ic = null; try { String serviceJndi = properties.getProperty(NEWSADMIN_JNDINAME); ic = new InitialContext(properties); return (NewsCaseFacade) ic.lookup(serviceJndi); } catch (NamingException e) { LOG.error("Could not lookup remote EJB.", e); } finally { if (ic != null) { try { ic.close(); } catch (NamingException e) { // Ignoring } } } return null; } /** * @param newsCaseName * @param queryType * @return */ public String getQuery(String newsCaseName, String queryType, int aggrId) { try { LOG.debug("Looking up query for: " + newsCaseName); final NewsCaseFacade newsCaseFacade = lookupDataService(); if (newsCaseFacade != null) { String newsQuery = newsCaseFacade.searchForQuery(newsCaseName, queryType, aggrId); if (newsQuery != null) { return newsQuery; } } } catch (RuntimeException e) { LOG.error("Could not lookup query for: " + newsCaseName, e); } return null; } } }