Java tutorial
/** * Constellio, Open Source Enterprise Search * Copyright (C) 2010 DocuLibre inc. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU * Lesser General Public License, as published by the Free Software Foundation. * * 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. * * You should have received a copy of the GNU Lesser General Public License * along with this distribution; if not, write to: * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA */ package com.doculibre.constellio.lucene.impl; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Locale; import org.apache.commons.lang.StringUtils; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.document.StringField; import org.apache.lucene.index.DirectoryReader; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriterConfig; import org.apache.lucene.index.Term; import org.apache.lucene.store.Directory; import org.apache.lucene.store.FSDirectory; import org.apache.lucene.util.Version; import com.doculibre.constellio.entities.I18NLabel; import com.doculibre.constellio.entities.skos.SkosConcept; import com.doculibre.constellio.entities.skos.SkosConceptAltLabel; import com.doculibre.constellio.entities.skos.Thesaurus; import com.doculibre.constellio.lucene.BaseLuceneIndexHelper; import com.doculibre.constellio.services.SkosServices; import com.doculibre.constellio.utils.ConstellioSpringUtils; @SuppressWarnings("serial") public class SkosIndexHelperImpl extends BaseLuceneIndexHelper<SkosConcept> implements SkosIndexHelper { private static final String ID = "id"; private static final String THESAURUS_ID = "thesaurus_id"; private static final String PREF_LABEL = "prefLabel"; private static final String ALT_LABEL = "altLabel"; public SkosIndexHelperImpl() { super("skos"); } @Override protected Field[] createIndexFields() { List<Field> fields = new ArrayList<Field>(); fields.add(new StringField(ID, "", Field.Store.YES)); fields.add(new StringField(THESAURUS_ID, "", Field.Store.YES)); Field prefLabelField = createDefaultIndexField(PREF_LABEL); prefLabelField.setBoost(4.0F); fields.add(prefLabelField); fields.add(createDefaultIndexField(ALT_LABEL)); for (Locale locale : ConstellioSpringUtils.getSupportedLocales()) { String suffix = "_" + locale.getLanguage(); Field prefLabelLocaleField = createDefaultIndexField(PREF_LABEL + suffix); prefLabelLocaleField.setBoost(4.0F); fields.add(prefLabelLocaleField); fields.add(createDefaultIndexField(ALT_LABEL + suffix)); } return fields.toArray(new Field[0]); } @Override protected String[] createSearchFields(Field[] indexFields) { List<String> fieldNames = new ArrayList<String>(); fieldNames.add(PREF_LABEL); fieldNames.add(ALT_LABEL); for (Locale locale : ConstellioSpringUtils.getSupportedLocales()) { String suffix = "_" + locale.getLanguage(); fieldNames.add(PREF_LABEL + suffix); fieldNames.add(ALT_LABEL + suffix); } return fieldNames.toArray(new String[0]); } @Override protected List<SkosConcept> getAll() { List<SkosConcept> skosConcepts = new ArrayList<SkosConcept>(); SkosServices skosServices = ConstellioSpringUtils.getSkosServices(); for (Thesaurus thesaurus : skosServices.list()) { for (SkosConcept topConcept : thesaurus.getTopConcepts()) { addConceptAndSubConcepts(topConcept, skosConcepts); } } return skosConcepts; } private void addConceptAndSubConcepts(SkosConcept skosConcept, List<SkosConcept> skosConcepts) { skosConcepts.add(skosConcept); for (SkosConcept narrower : skosConcept.getNarrower()) { // recursive call addConceptAndSubConcepts(narrower, skosConcepts); } } @Override protected String getUniqueIndexFieldName() { return ID; } @Override protected String getUniqueIndexFieldValue(SkosConcept object) { return object.getId().toString(); } @Override protected void populateIndexField(SkosConcept skosConcept, Field indexField, Document doc) { String indexFieldName = indexField.name(); List<Locale> supportedLocales = ConstellioSpringUtils.getSupportedLocales(); if (indexFieldName.equals(ID)) { indexField.setStringValue(skosConcept.getId().toString()); } else if (indexFieldName.equals(THESAURUS_ID)) { indexField.setStringValue(skosConcept.getThesaurus().getId().toString()); } else if (indexFieldName.equals(PREF_LABEL)) { boolean first = true; for (I18NLabel prefLabel : skosConcept.getPrefLabels()) { for (Locale locale : prefLabel.getValues().keySet()) { if (supportedLocales.contains(locale)) { if (first) { indexField.setStringValue(prefLabel.getValue(locale)); first = false; } else { Field extraField = createDefaultIndexField(PREF_LABEL); extraField.setStringValue(prefLabel.getValue(locale)); doc.add(extraField); } } } } } else if (indexFieldName.equals(ALT_LABEL)) { boolean first = true; for (SkosConceptAltLabel altLabel : skosConcept.getAltLabels()) { Locale locale = altLabel.getLocale(); if (supportedLocales.contains(locale)) { for (String altLabelValue : skosConcept.getAltLabels(locale)) { if (first) { indexField.setStringValue(altLabelValue); first = false; } else { Field extraField = createDefaultIndexField(ALT_LABEL); extraField.setStringValue(altLabelValue); doc.add(extraField); } } } } } else if (indexFieldName.startsWith(PREF_LABEL)) { if (indexFieldName.indexOf("_") != -1) { String language = StringUtils.substringAfter(indexFieldName, "_"); Locale locale = new Locale(language); String prefLabel = skosConcept.getPrefLabel(locale); if (StringUtils.isNotBlank(prefLabel)) { indexField.setStringValue(prefLabel); } } } else if (indexFieldName.startsWith(ALT_LABEL)) { String language = StringUtils.substringAfter(indexFieldName, "_"); Locale locale = new Locale(language); String prefLabel = skosConcept.getPrefLabel(locale); if (StringUtils.isNotBlank(prefLabel)) { boolean first = true; for (String altLabelValue : skosConcept.getAltLabels(locale)) { if (first) { indexField.setStringValue(altLabelValue); first = false; } else { Field extraField = createDefaultIndexField(indexFieldName); extraField.setStringValue(altLabelValue); doc.add(extraField); } } } } } @Override protected SkosConcept toObject(int docId, Document doc) { Long id = new Long(doc.getField(ID).stringValue()); SkosServices skosServices = ConstellioSpringUtils.getSkosServices(); return skosServices.getSkosConcept(id); } @Override public void add(Thesaurus thesaurus) { delete(thesaurus); try { Directory directory = FSDirectory.open(getIndexDir()); Analyzer analyzer = getAnalyzerProvider().getAnalyzer(Locale.FRENCH); IndexWriter indexWriter = new IndexWriter(directory, new IndexWriterConfig(Version.LUCENE_44, analyzer)); List<SkosConcept> skosConcepts = new ArrayList<SkosConcept>(); for (SkosConcept topConcept : thesaurus.getTopConcepts()) { addConceptAndSubConcepts(topConcept, skosConcepts); } for (SkosConcept skosConcept : skosConcepts) { add(skosConcept, indexWriter); } // indexWriter.optimize(); indexWriter.close(); directory.close(); } catch (IOException e) { throw new RuntimeException(e); } } @Override public void delete(Thesaurus thesaurus) { try { Directory directory = FSDirectory.open(getIndexDir()); if (DirectoryReader.indexExists(directory)) { Analyzer analyzer = getAnalyzerProvider().getAnalyzer(Locale.FRENCH); IndexWriter indexWriter = new IndexWriter(directory, new IndexWriterConfig(Version.LUCENE_44, analyzer)); Term term = new Term(THESAURUS_ID, thesaurus.getId().toString()); indexWriter.deleteDocuments(term); indexWriter.close(); } directory.close(); } catch (IOException e) { throw new RuntimeException(e); } } @Override public List<SkosConcept> searchAltLabel(String input, Thesaurus thesaurus, Locale locale) { input = adjustInputWildcard(input); StringBuffer luceneQuery = new StringBuffer(); luceneQuery.append(THESAURUS_ID + ":" + thesaurus.getId()); luceneQuery.append(" AND "); if (locale != null) { String suffix = "_" + locale.getLanguage(); luceneQuery.append(ALT_LABEL + suffix + ":" + input); } else { luceneQuery.append(ALT_LABEL + ":" + input); } return super.search(luceneQuery.toString()); } @Override public List<SkosConcept> searchPrefLabel(String input, Thesaurus thesaurus, Locale locale) { input = adjustInputWildcard(input); StringBuffer luceneQuery = new StringBuffer(); luceneQuery.append(THESAURUS_ID + ":" + thesaurus.getId()); luceneQuery.append(" AND "); if (locale != null) { String suffix = "_" + locale.getLanguage(); luceneQuery.append(PREF_LABEL + suffix + ":" + input); } else { luceneQuery.append(PREF_LABEL + ":" + input); } return super.search(luceneQuery.toString()); } @Override public List<SkosConcept> searchAllLabels(String input, Thesaurus thesaurus, Locale locale) { input = adjustInputWildcard(input); String adjustedInput = getAndQuery(input); StringBuffer luceneQuery = new StringBuffer(); luceneQuery.append(THESAURUS_ID + ":" + thesaurus.getId()); luceneQuery.append(" AND "); if (locale != null) { String suffix = "_" + locale.getLanguage(); luceneQuery.append("("); luceneQuery.append(PREF_LABEL + suffix + ":"); luceneQuery.append("("); luceneQuery.append(adjustedInput); luceneQuery.append(")"); luceneQuery.append(" OR "); luceneQuery.append(ALT_LABEL + suffix + ":"); luceneQuery.append("("); luceneQuery.append(adjustedInput); luceneQuery.append(")"); luceneQuery.append(")"); } else { luceneQuery.append("("); luceneQuery.append(PREF_LABEL + ":"); luceneQuery.append("("); luceneQuery.append(adjustedInput); luceneQuery.append(")"); luceneQuery.append(" OR "); luceneQuery.append(ALT_LABEL + ":"); luceneQuery.append("("); luceneQuery.append(adjustedInput); luceneQuery.append(")"); luceneQuery.append(")"); } return super.search(luceneQuery.toString()); } private String adjustInputWildcard(String input) { String result; if (input.endsWith("*")) { // String beforeWildCard = StringUtils.substringBefore(input, "*"); // result = analyze(beforeWildCard); result = input; } else { result = "\"" + input + "\""; } return result; } public static void main(String[] args) { SkosIndexHelperImpl indexHelper = new SkosIndexHelperImpl(); indexHelper.rebuild(); } }