/** * Copyright (c) Codice Foundation * <p/> * This 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 any later version. * <p/> * 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 * Lesser General Public License for more details. A copy of the GNU Lesser General Public License * is distributed along with this program and can be found at * <http://www.gnu.org/licenses/lgpl.html>. */ package org.codice.solr.query; import java.io.IOException; import java.util.HashMap; import java.util.Map; import org.apache.commons.lang.StringUtils; import org.apache.solr.client.solrj.SolrServer; import org.apache.solr.client.solrj.SolrServerException; import org.apache.solr.client.solrj.request.LukeRequest; import org.apache.solr.client.solrj.response.LukeResponse; import org.apache.solr.client.solrj.response.LukeResponse.FieldInfo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class SchemaFieldResolver { public static final String OBJECT_SUFFIX = "_obj"; public static final String LONG_SUFFIX = "_lng"; public static final String INTEGER_SUFFIX = "_int"; public static final String SHORT_SUFFIX = "_shr"; public static final String FLOAT_SUFFIX = "_flt"; public static final String DOUBLE_SUFFIX = "_dbl"; public static final String BOOLEAN_SUFFIX = "_bln"; public static final String GEO_SUFFIX = "_geo"; public static final String TEXT_SUFFIX = "_txt"; public static final String XML_SUFFIX = "_xml"; public static final String DATE_SUFFIX = "_tdt"; public static final String BINARY_SUFFIX = "_bin"; public static final String[] FORMAT_SUFFIXES = new String[] {OBJECT_SUFFIX, LONG_SUFFIX, INTEGER_SUFFIX, SHORT_SUFFIX, FLOAT_SUFFIX, DOUBLE_SUFFIX, BOOLEAN_SUFFIX, GEO_SUFFIX, TEXT_SUFFIX, XML_SUFFIX, DATE_SUFFIX, BINARY_SUFFIX}; public static final String TOKENIZED = "_tokenized"; public static final String HAS_CASE = "_has_case"; public static final String TEXT_PATH = "_tpt"; public static final String INDEXED = "_index"; public static final String METACARD_TYPE_FIELD_NAME = "metacard_type_name" + TEXT_SUFFIX; public static final String METACARD_TYPE_OBJECT_FIELD_NAME = "metacard_type" + OBJECT_SUFFIX; private static final Logger LOGGER = LoggerFactory.getLogger(SchemaFieldResolver.class); private static final Map<String, AttributeFormat> SUFFIX_TO_FORMAT_MAP = new HashMap<String, AttributeFormat>(); private static final Map<AttributeFormat, String> FORMAT_TO_SUFFIX_MAP = new HashMap<AttributeFormat, String>(); static { SUFFIX_TO_FORMAT_MAP.put(GEO_SUFFIX, AttributeFormat.GEOMETRY); SUFFIX_TO_FORMAT_MAP.put(DATE_SUFFIX, AttributeFormat.DATE); SUFFIX_TO_FORMAT_MAP.put(BINARY_SUFFIX, AttributeFormat.BINARY); SUFFIX_TO_FORMAT_MAP.put(XML_SUFFIX, AttributeFormat.XML); SUFFIX_TO_FORMAT_MAP.put(TEXT_SUFFIX, AttributeFormat.STRING); SUFFIX_TO_FORMAT_MAP.put(BOOLEAN_SUFFIX, AttributeFormat.BOOLEAN); SUFFIX_TO_FORMAT_MAP.put(DOUBLE_SUFFIX, AttributeFormat.DOUBLE); SUFFIX_TO_FORMAT_MAP.put(FLOAT_SUFFIX, AttributeFormat.FLOAT); SUFFIX_TO_FORMAT_MAP.put(INTEGER_SUFFIX, AttributeFormat.INTEGER); SUFFIX_TO_FORMAT_MAP.put(LONG_SUFFIX, AttributeFormat.LONG); SUFFIX_TO_FORMAT_MAP.put(SHORT_SUFFIX, AttributeFormat.SHORT); SUFFIX_TO_FORMAT_MAP.put(OBJECT_SUFFIX, AttributeFormat.OBJECT); FORMAT_TO_SUFFIX_MAP.put(AttributeFormat.GEOMETRY, GEO_SUFFIX); FORMAT_TO_SUFFIX_MAP.put(AttributeFormat.DATE, DATE_SUFFIX); FORMAT_TO_SUFFIX_MAP.put(AttributeFormat.BINARY, BINARY_SUFFIX); FORMAT_TO_SUFFIX_MAP.put(AttributeFormat.XML, XML_SUFFIX); FORMAT_TO_SUFFIX_MAP.put(AttributeFormat.STRING, TEXT_SUFFIX); FORMAT_TO_SUFFIX_MAP.put(AttributeFormat.BOOLEAN, BOOLEAN_SUFFIX); FORMAT_TO_SUFFIX_MAP.put(AttributeFormat.DOUBLE, DOUBLE_SUFFIX); FORMAT_TO_SUFFIX_MAP.put(AttributeFormat.FLOAT, FLOAT_SUFFIX); FORMAT_TO_SUFFIX_MAP.put(AttributeFormat.INTEGER, INTEGER_SUFFIX); FORMAT_TO_SUFFIX_MAP.put(AttributeFormat.LONG, LONG_SUFFIX); FORMAT_TO_SUFFIX_MAP.put(AttributeFormat.SHORT, SHORT_SUFFIX); FORMAT_TO_SUFFIX_MAP.put(AttributeFormat.OBJECT, OBJECT_SUFFIX); } private SolrServer solrServer; public SchemaFieldResolver(SolrServer solrServer) { this.solrServer = solrServer; } public AttributeFormat getFormat(String suffix) { return SUFFIX_TO_FORMAT_MAP.get(suffix); } public String getFieldSuffix(AttributeFormat attributeFormat) { return FORMAT_TO_SUFFIX_MAP.get(attributeFormat); } public SchemaField getSchemaField(String propertyName, boolean isSearchedAsExactValue) { SchemaField schemaField = null; LukeRequest luke = new LukeRequest(); LukeResponse rsp; try { rsp = luke.process(solrServer); Map<String, FieldInfo> fieldsInfo = rsp.getFieldInfo(); if (fieldsInfo != null && !fieldsInfo.isEmpty()) { LOGGER.info("got fieldsInfo for {} fields", fieldsInfo.size()); for (Map.Entry<String, FieldInfo> entry : fieldsInfo.entrySet()) { // See if any fieldName startsWith(propertyName) // if it does, then see if remainder of fieldName matches any expected suffix // if suffix matches, then get type of field and cache it if (entry.getKey().startsWith(propertyName) && StringUtils .endsWithAny(entry.getKey(), FORMAT_SUFFIXES)) { String fieldType = entry.getValue().getType(); int index = StringUtils.lastIndexOfAny(entry.getKey(), FORMAT_SUFFIXES); String suffix = entry.getKey().substring(index); if (!isSearchedAsExactValue) { suffix = getSpecialIndexSuffix(suffix); fieldType += suffix; } LOGGER.info("field {} has type {}", entry.getKey(), fieldType); schemaField = new SchemaField(entry.getKey(), fieldType); schemaField.setSuffix(suffix); return schemaField; } } } else { LOGGER.info("fieldsInfo from LukeRequest are either null or empty"); } } catch (SolrServerException e) { LOGGER.info("SolrServerException while processing LukeRequest", e); } catch (IOException e) { LOGGER.info("IOException while processing LukeRequest", e); } LOGGER.info("Did not find SchemaField for property {}", propertyName); return schemaField; } private String getSpecialIndexSuffix(String suffix) { if (suffix.equalsIgnoreCase(TEXT_SUFFIX)) { return SchemaFieldResolver.TOKENIZED; } else if (suffix.equalsIgnoreCase(GEO_SUFFIX)) { return SchemaFieldResolver.INDEXED; } else if (suffix.equalsIgnoreCase(XML_SUFFIX)) { return SchemaFieldResolver.TEXT_PATH; } return ""; } }