diff --git a/config/alfresco/core-services-context.xml b/config/alfresco/core-services-context.xml
index f14ff527c8..82dd60e136 100644
--- a/config/alfresco/core-services-context.xml
+++ b/config/alfresco/core-services-context.xml
@@ -344,9 +344,6 @@
-
-
-
@@ -368,15 +365,6 @@
${lucene.indexer.batchSize}
-
- ${lucene.indexer.minMergeDocs}
-
-
- ${lucene.indexer.mergeFactor}
-
-
- ${lucene.indexer.maxMergeDocs}
- ${dir.indexes.lock}
@@ -411,11 +399,6 @@
-
-
-
-
-
diff --git a/config/alfresco/extension/new-indexer-context.xml.sample b/config/alfresco/extension/new-indexer-context.xml.sample
index b34616efed..703ada717e 100644
--- a/config/alfresco/extension/new-indexer-context.xml.sample
+++ b/config/alfresco/extension/new-indexer-context.xml.sample
@@ -16,9 +16,6 @@
-
-
-
diff --git a/config/alfresco/extension/old-indexer-context.xml.sample b/config/alfresco/extension/old-indexer-context.xml.sample
deleted file mode 100644
index 9d5a962fb1..0000000000
--- a/config/alfresco/extension/old-indexer-context.xml.sample
+++ /dev/null
@@ -1,101 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ${dir.indexes}
-
-
-
-
-
-
-
-
- ${lucene.maxAtomicTransformationTime}
-
-
- ${lucene.query.maxClauses}
-
-
- ${lucene.indexer.batchSize}
-
-
- ${lucene.indexer.minMergeDocs}
-
-
- ${lucene.indexer.mergeFactor}
-
-
- ${lucene.indexer.maxMergeDocs}
-
-
- ${dir.indexes.lock}
-
-
- ${lucene.indexer.maxFieldLength}
-
-
- ${lucene.write.lock.timeout}
-
-
- ${lucene.commit.lock.timeout}
-
-
- ${lucene.lock.poll.interval}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ${dir.root}/backup-lucene-indexes
-
-
-
-
-
-
- org.alfresco.repo.search.impl.lucene.LuceneIndexerAndSearcherFactory$LuceneIndexBackupJob
-
-
-
-
-
-
\ No newline at end of file
diff --git a/config/alfresco/model/dataTypeAnalyzers_cs.properties b/config/alfresco/model/dataTypeAnalyzers_cs.properties
new file mode 100644
index 0000000000..bd4f99b085
--- /dev/null
+++ b/config/alfresco/model/dataTypeAnalyzers_cs.properties
@@ -0,0 +1,4 @@
+# Data Type Index Analyzers
+
+d_dictionary.datatype.d_text.analyzer=org.apache.lucene.analysis.cz.CzechAnalyzer
+d_dictionary.datatype.d_content.analyzer=org.apache.lucene.analysis.cz.CzechAnalyzer
diff --git a/config/alfresco/model/dataTypeAnalyzers_da.properties b/config/alfresco/model/dataTypeAnalyzers_da.properties
new file mode 100644
index 0000000000..eba2d37c18
--- /dev/null
+++ b/config/alfresco/model/dataTypeAnalyzers_da.properties
@@ -0,0 +1,4 @@
+# Data Type Index Analyzers
+
+d_dictionary.datatype.d_text.analyzer=org.alfresco.repo.search.impl.lucene.analysis.DanishSnowballAnalyser
+d_dictionary.datatype.d_content.analyzer=org.alfresco.repo.search.impl.lucene.analysis.DanishSnowballAnalyser
diff --git a/config/alfresco/model/dataTypeAnalyzers_de.properties b/config/alfresco/model/dataTypeAnalyzers_de.properties
new file mode 100644
index 0000000000..51a0c3dc20
--- /dev/null
+++ b/config/alfresco/model/dataTypeAnalyzers_de.properties
@@ -0,0 +1,4 @@
+# Data Type Index Analyzers
+
+d_dictionary.datatype.d_text.analyzer=org.apache.lucene.analysis.de.GermanAnalyzer
+d_dictionary.datatype.d_content.analyzer=org.apache.lucene.analysis.de.GermanAnalyzer
diff --git a/config/alfresco/model/dataTypeAnalyzers_el.properties b/config/alfresco/model/dataTypeAnalyzers_el.properties
new file mode 100644
index 0000000000..e76fb3c77f
--- /dev/null
+++ b/config/alfresco/model/dataTypeAnalyzers_el.properties
@@ -0,0 +1,4 @@
+# Data Type Index Analyzers
+
+d_dictionary.datatype.d_text.analyzer=org.apache.lucene.analysis.el.GreekAnalyzer
+d_dictionary.datatype.d_content.analyzer=org.apache.lucene.analysis.el.GreekAnalyzer
diff --git a/config/alfresco/model/dataTypeAnalyzers_en.properties b/config/alfresco/model/dataTypeAnalyzers_en.properties
new file mode 100644
index 0000000000..49ce516535
--- /dev/null
+++ b/config/alfresco/model/dataTypeAnalyzers_en.properties
@@ -0,0 +1,4 @@
+# Data Type Index Analyzers
+
+d_dictionary.datatype.d_text.analyzer=org.alfresco.repo.search.impl.lucene.analysis.AlfrescoStandardAnalyser
+d_dictionary.datatype.d_content.analyzer=org.alfresco.repo.search.impl.lucene.analysis.AlfrescoStandardAnalyser
diff --git a/config/alfresco/model/dataTypeAnalyzers_es.properties b/config/alfresco/model/dataTypeAnalyzers_es.properties
new file mode 100644
index 0000000000..a808ef9f11
--- /dev/null
+++ b/config/alfresco/model/dataTypeAnalyzers_es.properties
@@ -0,0 +1,4 @@
+# Data Type Index Analyzers
+
+d_dictionary.datatype.d_text.analyzer=org.alfresco.repo.search.impl.lucene.analysis.SpanishSnowballAnalyser
+d_dictionary.datatype.d_content.analyzer=org.alfresco.repo.search.impl.lucene.analysis.SpanishSnowballAnalyser
diff --git a/config/alfresco/model/dataTypeAnalyzers_fr.properties b/config/alfresco/model/dataTypeAnalyzers_fr.properties
new file mode 100644
index 0000000000..2e73d811fa
--- /dev/null
+++ b/config/alfresco/model/dataTypeAnalyzers_fr.properties
@@ -0,0 +1,4 @@
+# Data Type Index Analyzers
+
+d_dictionary.datatype.d_text.analyzer=org.apache.lucene.analysis.fr.FrenchAnalyzer
+d_dictionary.datatype.d_content.analyzer=org.apache.lucene.analysis.fr.FrenchAnalyzer
diff --git a/config/alfresco/model/dataTypeAnalyzers_it.properties b/config/alfresco/model/dataTypeAnalyzers_it.properties
new file mode 100644
index 0000000000..55f492167d
--- /dev/null
+++ b/config/alfresco/model/dataTypeAnalyzers_it.properties
@@ -0,0 +1,4 @@
+# Data Type Index Analyzers
+
+d_dictionary.datatype.d_text.analyzer=org.alfresco.repo.search.impl.lucene.analysis.ItalianSnowballAnalyser
+d_dictionary.datatype.d_content.analyzer=org.alfresco.repo.search.impl.lucene.analysis.ItalianSnowballAnalyser
diff --git a/config/alfresco/model/dataTypeAnalyzers_ja.properties b/config/alfresco/model/dataTypeAnalyzers_ja.properties
new file mode 100644
index 0000000000..58a04cb7e6
--- /dev/null
+++ b/config/alfresco/model/dataTypeAnalyzers_ja.properties
@@ -0,0 +1,4 @@
+# Data Type Index Analyzers
+
+d_dictionary.datatype.d_text.analyzer=org.apache.lucene.analysis.cjk.CJKAnalyzer
+d_dictionary.datatype.d_content.analyzer=org.apache.lucene.analysis.cjk.CJKAnalyzer
diff --git a/config/alfresco/model/dataTypeAnalyzers_ko.properties b/config/alfresco/model/dataTypeAnalyzers_ko.properties
new file mode 100644
index 0000000000..58a04cb7e6
--- /dev/null
+++ b/config/alfresco/model/dataTypeAnalyzers_ko.properties
@@ -0,0 +1,4 @@
+# Data Type Index Analyzers
+
+d_dictionary.datatype.d_text.analyzer=org.apache.lucene.analysis.cjk.CJKAnalyzer
+d_dictionary.datatype.d_content.analyzer=org.apache.lucene.analysis.cjk.CJKAnalyzer
diff --git a/config/alfresco/model/dataTypeAnalyzers_nl.properties b/config/alfresco/model/dataTypeAnalyzers_nl.properties
new file mode 100644
index 0000000000..f4cfcf826e
--- /dev/null
+++ b/config/alfresco/model/dataTypeAnalyzers_nl.properties
@@ -0,0 +1,4 @@
+# Data Type Index Analyzers
+
+d_dictionary.datatype.d_text.analyzer=org.apache.lucene.analysis.nl.DutchAnalyzer
+d_dictionary.datatype.d_content.analyzer=org.apache.lucene.analysis.nl.DutchAnalyzer
diff --git a/config/alfresco/model/dataTypeAnalyzers_no.properties b/config/alfresco/model/dataTypeAnalyzers_no.properties
new file mode 100644
index 0000000000..386ab258f5
--- /dev/null
+++ b/config/alfresco/model/dataTypeAnalyzers_no.properties
@@ -0,0 +1,4 @@
+# Data Type Index Analyzers
+
+d_dictionary.datatype.d_text.analyzer=org.alfresco.repo.search.impl.lucene.analysis.NorwegianSnowballAnalyser
+d_dictionary.datatype.d_content.analyzer=org.alfresco.repo.search.impl.lucene.analysis.NorwegianSnowballAnalyser
diff --git a/config/alfresco/model/dataTypeAnalyzers_pt.properties b/config/alfresco/model/dataTypeAnalyzers_pt.properties
new file mode 100644
index 0000000000..522bad3dff
--- /dev/null
+++ b/config/alfresco/model/dataTypeAnalyzers_pt.properties
@@ -0,0 +1,4 @@
+# Data Type Index Analyzers
+
+d_dictionary.datatype.d_text.analyzer=org.alfresco.repo.search.impl.lucene.analysis.PortugueseSnowballAnalyser
+d_dictionary.datatype.d_content.analyzer=org.alfresco.repo.search.impl.lucene.analysis.PortugueseSnowballAnalyser
diff --git a/config/alfresco/model/dataTypeAnalyzers_pt_BR.properties b/config/alfresco/model/dataTypeAnalyzers_pt_BR.properties
new file mode 100644
index 0000000000..a792c4bb32
--- /dev/null
+++ b/config/alfresco/model/dataTypeAnalyzers_pt_BR.properties
@@ -0,0 +1,4 @@
+# Data Type Index Analyzers
+
+d_dictionary.datatype.d_text.analyzer=org.apache.lucene.analysis.br.BrazilianAnalyzer
+d_dictionary.datatype.d_content.analyzer=org.apache.lucene.analysis.br.BrazilianAnalyzer
diff --git a/config/alfresco/model/dataTypeAnalyzers_ru.properties b/config/alfresco/model/dataTypeAnalyzers_ru.properties
new file mode 100644
index 0000000000..8a8340215b
--- /dev/null
+++ b/config/alfresco/model/dataTypeAnalyzers_ru.properties
@@ -0,0 +1,4 @@
+# Data Type Index Analyzers
+
+d_dictionary.datatype.d_text.analyzer=org.apache.lucene.analysis.ru.RussianAnalyzer
+d_dictionary.datatype.d_content.analyzer=org.apache.lucene.analysis.ru.RussianAnalyzer
diff --git a/config/alfresco/model/dataTypeAnalyzers_sv.properties b/config/alfresco/model/dataTypeAnalyzers_sv.properties
new file mode 100644
index 0000000000..0bfd347223
--- /dev/null
+++ b/config/alfresco/model/dataTypeAnalyzers_sv.properties
@@ -0,0 +1,4 @@
+# Data Type Index Analyzers
+
+d_dictionary.datatype.d_text.analyzer=org.alfresco.repo.search.impl.lucene.analysis.SwedishSnowballAnalyser
+d_dictionary.datatype.d_content.analyzer=org.alfresco.repo.search.impl.lucene.analysis.SwedishSnowballAnalyser
diff --git a/config/alfresco/model/dataTypeAnalyzers_zh.properties b/config/alfresco/model/dataTypeAnalyzers_zh.properties
new file mode 100644
index 0000000000..7d3b6bfa36
--- /dev/null
+++ b/config/alfresco/model/dataTypeAnalyzers_zh.properties
@@ -0,0 +1,4 @@
+# Data Type Index Analyzers
+
+d_dictionary.datatype.d_text.analyzer=org.apache.lucene.analysis.cn.ChineseAnalyzer
+d_dictionary.datatype.d_content.analyzer=org.apache.lucene.analysis.cn.ChineseAnalyzer
diff --git a/source/java/org/alfresco/repo/dictionary/CompiledModel.java b/source/java/org/alfresco/repo/dictionary/CompiledModel.java
index 382affaeb0..1aa82120e5 100644
--- a/source/java/org/alfresco/repo/dictionary/CompiledModel.java
+++ b/source/java/org/alfresco/repo/dictionary/CompiledModel.java
@@ -316,6 +316,15 @@ import org.apache.commons.logging.LogFactory;
{
return aspects.values();
}
+
+ /**
+ *
+ * @return the compiled properties
+ */
+ public Collection getProperties()
+ {
+ return properties.values();
+ }
/* (non-Javadoc)
diff --git a/source/java/org/alfresco/repo/dictionary/DictionaryComponent.java b/source/java/org/alfresco/repo/dictionary/DictionaryComponent.java
index f9cd844d6c..d551fc9786 100644
--- a/source/java/org/alfresco/repo/dictionary/DictionaryComponent.java
+++ b/source/java/org/alfresco/repo/dictionary/DictionaryComponent.java
@@ -18,6 +18,8 @@ package org.alfresco.repo.dictionary;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
import java.util.Map;
import org.alfresco.service.cmr.dictionary.AspectDefinition;
@@ -285,5 +287,50 @@ public class DictionaryComponent implements DictionaryService
{
return dictionaryDAO.getAssociation(associationName);
}
+
+
+ /*
+ * (non-Javadoc)
+ * @see org.alfresco.service.cmr.dictionary.DictionaryService#getAllProperties(org.alfresco.service.namespace.QName)
+ */
+ public Collection getAllProperties(QName dataType)
+ {
+ Collection aspects = new HashSet(64);
+ for (QName model : getAllModels())
+ {
+ aspects.addAll(getProperties(model, dataType));
+ }
+ return aspects;
+ }
+
+
+ /*
+ * (non-Javadoc)
+ * @see org.alfresco.service.cmr.dictionary.DictionaryService#getAllProperties(org.alfresco.service.namespace.QName, org.alfresco.service.namespace.QName)
+ */
+ public Collection getProperties(QName model, QName dataType)
+ {
+ Collection propDefs = dictionaryDAO.getProperties(model, dataType);
+ HashSet props = new HashSet(propDefs.size());
+ for(PropertyDefinition def : propDefs)
+ {
+ props.add(def.getName());
+ }
+ return props;
+
+ }
+
+
+ public Collection getProperties(QName model)
+ {
+ Collection propDefs = dictionaryDAO.getProperties(model);
+ HashSet props = new HashSet(propDefs.size());
+ for(PropertyDefinition def : propDefs)
+ {
+ props.add(def.getName());
+ }
+ return props;
+ }
+
}
diff --git a/source/java/org/alfresco/repo/dictionary/DictionaryDAO.java b/source/java/org/alfresco/repo/dictionary/DictionaryDAO.java
index bc6abbd819..622103a4b9 100644
--- a/source/java/org/alfresco/repo/dictionary/DictionaryDAO.java
+++ b/source/java/org/alfresco/repo/dictionary/DictionaryDAO.java
@@ -21,6 +21,7 @@ import java.util.Collection;
import org.alfresco.service.cmr.dictionary.AspectDefinition;
import org.alfresco.service.cmr.dictionary.ModelDefinition;
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
+import org.alfresco.service.cmr.dictionary.PropertyDefinition;
import org.alfresco.service.cmr.dictionary.TypeDefinition;
import org.alfresco.service.namespace.QName;
@@ -61,6 +62,14 @@ public interface DictionaryDAO extends ModelQuery
* @return the aspects of the model
*/
public Collection getAspects(QName model);
+
+
+ /**
+ *
+ * @param model the model for which to get properties
+ * @return
+ */
+ public Collection getProperties(QName model);
/**
* Construct an anonymous type that combines a primary type definition and
@@ -87,4 +96,14 @@ public interface DictionaryDAO extends ModelQuery
*/
public void removeModel(QName model);
+ /**
+ * Get all properties for the model and that are of the given data type.
+ * If dataType is null then the all properties will be returned.
+ *
+ * @param modelName
+ * @param dataType
+ * @return
+ */
+ public Collection getProperties(QName modelName, QName dataType);
+
}
diff --git a/source/java/org/alfresco/repo/dictionary/DictionaryDAOImpl.java b/source/java/org/alfresco/repo/dictionary/DictionaryDAOImpl.java
index 50306137e4..af5c23f080 100644
--- a/source/java/org/alfresco/repo/dictionary/DictionaryDAOImpl.java
+++ b/source/java/org/alfresco/repo/dictionary/DictionaryDAOImpl.java
@@ -20,6 +20,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -441,5 +442,33 @@ public class DictionaryDAOImpl implements DictionaryDAO
return new M2AnonymousTypeDefinition(typeDef, aspectDefs);
}
+ /*
+ * (non-Javadoc)
+ * @see org.alfresco.repo.dictionary.DictionaryDAO#getProperties(org.alfresco.service.namespace.QName)
+ */
+ public Collection getProperties(QName modelName)
+ {
+ CompiledModel model = getCompiledModel(modelName);
+ return model.getProperties();
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.alfresco.repo.dictionary.DictionaryDAO#getProperties(org.alfresco.service.namespace.QName, org.alfresco.service.namespace.QName)
+ */
+ public Collection getProperties(QName modelName, QName dataType)
+ {
+ HashSet properties = new HashSet();
+
+ Collection props = getProperties(modelName);
+ for(PropertyDefinition prop : props)
+ {
+ if((dataType == null) || prop.getDataType().getName().equals(dataType))
+ {
+ properties.add(prop);
+ }
+ }
+ return properties;
+ }
}
diff --git a/source/java/org/alfresco/repo/search/MLAnalysisMode.java b/source/java/org/alfresco/repo/search/MLAnalysisMode.java
new file mode 100644
index 0000000000..9aae62f24e
--- /dev/null
+++ b/source/java/org/alfresco/repo/search/MLAnalysisMode.java
@@ -0,0 +1,52 @@
+package org.alfresco.repo.search;
+
+import org.alfresco.error.AlfrescoRuntimeException;
+
+/**
+ * Enum to specify how multi-lingual properties should be treate for indexing and search.
+ *
+ * @author andyh
+ *
+ */
+public enum MLAnalysisMode
+{
+ /**
+ * Only exact locale is used.
+ */
+ LOCALE_ONLY,
+
+ /**
+ * Only the exact locale and no local === all lnaguages
+ */
+ LOCALE_AND_ALL,
+
+ /**
+ * Expand the locale to include all the locales that contain it.
+ * en_GB would be en_GB, en, but not all languages
+ */
+ LOCALE_AND_ALL_CONTAINING_LOCALES,
+
+ /**
+ * Expand the locale to include all the locales that contain it.
+ * en_GB would be en_GB, en, and all.
+ */
+ LOCALE_AND_ALL_CONTAINING_LOCALES_AND_ALL,
+
+ /**
+ * Expand to all the locales that are contained by this.
+ * en would expand to en, en_GB, en_US, ....
+ */
+ LOCAL_AND_ALL_CONTAINED_LOCALES;
+
+ public static MLAnalysisMode getMLAnalysisMode(String mode)
+ {
+ for(MLAnalysisMode test : MLAnalysisMode.values())
+ {
+ if(test.toString().equalsIgnoreCase(mode))
+ {
+ return test;
+ }
+ }
+ throw new AlfrescoRuntimeException("Unknown ML Analysis mode "+mode);
+ }
+}
diff --git a/source/java/org/alfresco/repo/search/impl/lucene/Lockable.java b/source/java/org/alfresco/repo/search/impl/lucene/Lockable.java
deleted file mode 100644
index bd26a963c5..0000000000
--- a/source/java/org/alfresco/repo/search/impl/lucene/Lockable.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2005 Alfresco, Inc.
- *
- * Licensed under the Mozilla Public License version 1.1
- * with a permitted attribution clause. You may obtain a
- * copy of the License at
- *
- * http://www.alfresco.org/legal/license.txt
- *
- * 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.alfresco.repo.search.impl.lucene;
-
-import org.alfresco.repo.search.transaction.LuceneIndexLock;
-
-public interface Lockable
-{
- public void setLuceneIndexLock(LuceneIndexLock luceneIndexLock);
-
- public LuceneIndexLock getLuceneIndexLock();
-
- public void getReadLock();
-
- public void releaseReadLock();
-
- public void getWriteLock();
-
- public void releaseWriteLock();
-}
diff --git a/source/java/org/alfresco/repo/search/impl/lucene/LuceneAnalyser.java b/source/java/org/alfresco/repo/search/impl/lucene/LuceneAnalyser.java
index 593436647a..8aa403d7cd 100644
--- a/source/java/org/alfresco/repo/search/impl/lucene/LuceneAnalyser.java
+++ b/source/java/org/alfresco/repo/search/impl/lucene/LuceneAnalyser.java
@@ -20,6 +20,8 @@ import java.io.Reader;
import java.util.HashMap;
import java.util.Map;
+import org.alfresco.repo.search.MLAnalysisMode;
+import org.alfresco.repo.search.impl.lucene.analysis.MLAnalayser;
import org.alfresco.repo.search.impl.lucene.analysis.PathAnalyser;
import org.alfresco.repo.search.impl.lucene.analysis.VerbatimAnalyser;
import org.alfresco.service.cmr.dictionary.DictionaryService;
@@ -32,44 +34,43 @@ import org.apache.lucene.analysis.WhitespaceAnalyzer;
import org.alfresco.repo.search.impl.lucene.analysis.AlfrescoStandardAnalyser;
/**
- * Analyse properties according to the property definition.
- *
- * The default is to use the standard tokeniser. The tokeniser should not have
- * been called when indexing properties that require no tokenisation. (tokenise
- * should be set to false when adding the field to the document)
+ * Analyse properties according to the property definition. The default is to use the standard tokeniser. The tokeniser should not have been called when indexing properties that
+ * require no tokenisation. (tokenise should be set to false when adding the field to the document)
*
* @author andyh
- *
*/
public class LuceneAnalyser extends Analyzer
{
-
+ // Dictinary service to look up analyser classes by data type and locale.
private DictionaryService dictionaryService;
+ // If all else fails a fall back analyser
private Analyzer defaultAnalyser;
+ // Cached analysers for non ML data types.
private Map analysers = new HashMap();
+ private MLAnalysisMode mlAlaysisMode;
+
/**
* Constructs with a default standard analyser
*
* @param defaultAnalyzer
- * Any fields not specifically defined to use a different
- * analyzer will use the one provided here.
+ * Any fields not specifically defined to use a different analyzer will use the one provided here.
*/
- public LuceneAnalyser(DictionaryService dictionaryService)
+ public LuceneAnalyser(DictionaryService dictionaryService, MLAnalysisMode mlAlaysisMode)
{
this(new AlfrescoStandardAnalyser());
this.dictionaryService = dictionaryService;
+ this.mlAlaysisMode = mlAlaysisMode;
}
/**
* Constructs with default analyzer.
*
* @param defaultAnalyzer
- * Any fields not specifically defined to use a different
- * analyzer will use the one provided here.
+ * Any fields not specifically defined to use a different analyzer will use the one provided here.
*/
public LuceneAnalyser(Analyzer defaultAnalyser)
{
@@ -78,6 +79,23 @@ public class LuceneAnalyser extends Analyzer
public TokenStream tokenStream(String fieldName, Reader reader)
{
+ // Treat multilingual as a special case.
+ // If multilingual then we need to find the correct tokeniser.
+ // This is done dynamically by reading a language code at the start of the reader.
+ if (fieldName.startsWith("@") && !fieldName.endsWith(".mimetype"))
+ {
+ QName propertyQName = QName.createQName(fieldName.substring(1));
+ PropertyDefinition propertyDef = dictionaryService.getProperty(propertyQName);
+ if (propertyDef != null)
+ {
+ if (propertyDef.getDataType().getName().equals(DataTypeDefinition.MLTEXT))
+ {
+ MLAnalayser analyser = new MLAnalayser(dictionaryService);
+ return analyser.tokenStream(fieldName, reader);
+ }
+ }
+ }
+
Analyzer analyser = (Analyzer) analysers.get(fieldName);
if (analyser == null)
{
@@ -86,6 +104,12 @@ public class LuceneAnalyser extends Analyzer
return analyser.tokenStream(fieldName, reader);
}
+ /**
+ * Pick the analyser from the field name
+ *
+ * @param fieldName
+ * @return
+ */
private Analyzer findAnalyser(String fieldName)
{
Analyzer analyser;
@@ -116,24 +140,31 @@ public class LuceneAnalyser extends Analyzer
}
else if (fieldName.startsWith("@"))
{
- QName propertyQName = QName.createQName(fieldName.substring(1));
- PropertyDefinition propertyDef = dictionaryService.getProperty(propertyQName);
- if (propertyDef != null)
+ if (fieldName.endsWith(".mimetype"))
{
- if (propertyDef.isTokenisedInIndex())
- {
- DataTypeDefinition dataType = propertyDef.getDataType();
- analyser = loadAnalyzer(dataType);
- }
- else
- {
- analyser = new VerbatimAnalyser();
- }
+ analyser = new VerbatimAnalyser();
}
else
{
- DataTypeDefinition dataType = dictionaryService.getDataType(DataTypeDefinition.TEXT);
- analyser = loadAnalyzer(dataType);
+ QName propertyQName = QName.createQName(fieldName.substring(1));
+ PropertyDefinition propertyDef = dictionaryService.getProperty(propertyQName);
+ if (propertyDef != null)
+ {
+ if (propertyDef.isTokenisedInIndex())
+ {
+ DataTypeDefinition dataType = propertyDef.getDataType();
+ analyser = loadAnalyzer(dataType);
+ }
+ else
+ {
+ analyser = new VerbatimAnalyser();
+ }
+ }
+ else
+ {
+ DataTypeDefinition dataType = dictionaryService.getDataType(DataTypeDefinition.TEXT);
+ analyser = loadAnalyzer(dataType);
+ }
}
}
else
@@ -144,6 +175,12 @@ public class LuceneAnalyser extends Analyzer
return analyser;
}
+ /**
+ * Find an instantiate an analyser. The shuld all be thread sade as Analyser.tokenStream should be re-entrant.
+ *
+ * @param dataType
+ * @return
+ */
private Analyzer loadAnalyzer(DataTypeDefinition dataType)
{
String analyserClassName = dataType.getAnalyserClassName();
@@ -155,19 +192,40 @@ public class LuceneAnalyser extends Analyzer
}
catch (ClassNotFoundException e)
{
- throw new RuntimeException("Unable to load analyser for property of type " + dataType.getName() + " using "
- + analyserClassName);
+ throw new RuntimeException("Unable to load analyser for property of type "
+ + dataType.getName() + " using " + analyserClassName);
}
catch (InstantiationException e)
{
- throw new RuntimeException("Unable to load analyser for property of type " + dataType.getName() + " using "
- + analyserClassName);
+ throw new RuntimeException("Unable to load analyser for property of type "
+ + dataType.getName() + " using " + analyserClassName);
}
catch (IllegalAccessException e)
{
- throw new RuntimeException("Unable to load analyser for property of type " + dataType.getName() + " using "
- + analyserClassName);
+ throw new RuntimeException("Unable to load analyser for property of type "
+ + dataType.getName() + " using " + analyserClassName);
}
}
+ /**
+ * For multilingual fields we separate the tokens for each instance to break phrase queries spanning different languages etc.
+ */
+ @Override
+ public int getPositionIncrementGap(String fieldName)
+ {
+ if (fieldName.startsWith("@") && !fieldName.endsWith(".mimetype"))
+ {
+ QName propertyQName = QName.createQName(fieldName.substring(1));
+ PropertyDefinition propertyDef = dictionaryService.getProperty(propertyQName);
+ if (propertyDef != null)
+ {
+ if (propertyDef.getDataType().equals(DataTypeDefinition.MLTEXT))
+ {
+ return 1000;
+ }
+ }
+ }
+ return super.getPositionIncrementGap(fieldName);
+ }
+
}
diff --git a/source/java/org/alfresco/repo/search/impl/lucene/LuceneBase2.java b/source/java/org/alfresco/repo/search/impl/lucene/LuceneBase2.java
index 681ce81354..a1096f23fa 100644
--- a/source/java/org/alfresco/repo/search/impl/lucene/LuceneBase2.java
+++ b/source/java/org/alfresco/repo/search/impl/lucene/LuceneBase2.java
@@ -21,6 +21,7 @@ import java.io.IOException;
import java.util.Set;
import org.alfresco.repo.search.IndexerException;
+import org.alfresco.repo.search.MLAnalysisMode;
import org.alfresco.repo.search.impl.lucene.index.IndexInfo;
import org.alfresco.repo.search.impl.lucene.index.TransactionStatus;
import org.alfresco.repo.search.impl.lucene.index.IndexInfo.LockWork;
@@ -86,7 +87,7 @@ public abstract class LuceneBase2
* @param deltaId
* @throws IOException
*/
- protected void initialise(StoreRef store, String deltaId, boolean createMain, boolean createDelta)
+ protected void initialise(StoreRef store, String deltaId)
throws LuceneIndexException
{
this.store = store;
@@ -208,7 +209,7 @@ public abstract class LuceneBase2
*/
protected IndexWriter getDeltaWriter() throws LuceneIndexException, IOException
{
- return indexInfo.getDeltaIndexWriter(deltaId, new LuceneAnalyser(dictionaryService));
+ return indexInfo.getDeltaIndexWriter(deltaId, new LuceneAnalyser(dictionaryService, config.getDefaultMLIndexAnalysisMode()));
}
/**
diff --git a/source/java/org/alfresco/repo/search/impl/lucene/LuceneCategoryTest2.java b/source/java/org/alfresco/repo/search/impl/lucene/LuceneCategoryTest2.java
index 2341ec5820..011d117365 100644
--- a/source/java/org/alfresco/repo/search/impl/lucene/LuceneCategoryTest2.java
+++ b/source/java/org/alfresco/repo/search/impl/lucene/LuceneCategoryTest2.java
@@ -32,10 +32,9 @@ import org.alfresco.repo.dictionary.M2Aspect;
import org.alfresco.repo.dictionary.M2Model;
import org.alfresco.repo.dictionary.M2Property;
import org.alfresco.repo.search.impl.lucene.fts.FullTextSearchIndexer;
-import org.alfresco.repo.search.transaction.LuceneIndexLock;
import org.alfresco.service.ServiceRegistry;
-import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
+import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
@@ -59,7 +58,6 @@ public class LuceneCategoryTest2 extends TestCase
static ApplicationContext ctx = ApplicationContextHelper.getApplicationContext();
NodeService nodeService;
DictionaryService dictionaryService;
- LuceneIndexLock luceneIndexLock;
private NodeRef rootNodeRef;
private NodeRef n1;
private NodeRef n2;
@@ -111,7 +109,6 @@ public class LuceneCategoryTest2 extends TestCase
public void setUp() throws Exception
{
nodeService = (NodeService)ctx.getBean("dbNodeService");
- luceneIndexLock = (LuceneIndexLock)ctx.getBean("luceneIndexLock");
dictionaryService = (DictionaryService)ctx.getBean("dictionaryService");
luceneFTS = (FullTextSearchIndexer) ctx.getBean("LuceneFullTextSearchIndexer");
dictionaryDAO = (DictionaryDAO) ctx.getBean("dictionaryDAO");
diff --git a/source/java/org/alfresco/repo/search/impl/lucene/LuceneConfig.java b/source/java/org/alfresco/repo/search/impl/lucene/LuceneConfig.java
index fee4da57cb..c23f9ae9bb 100644
--- a/source/java/org/alfresco/repo/search/impl/lucene/LuceneConfig.java
+++ b/source/java/org/alfresco/repo/search/impl/lucene/LuceneConfig.java
@@ -16,21 +16,48 @@
*/
package org.alfresco.repo.search.impl.lucene;
+import org.alfresco.repo.search.MLAnalysisMode;
+
public interface LuceneConfig
{
-
+ /**
+ * Set the lock dir - just to make sure - this should no longer be used.
+ *
+ * @param lockDirectory
+ */
+ public void setLockDirectory(String lockDirectory);
+
+ /**
+ * The path to the index location
+ * @return
+ */
public String getIndexRootLocation();
+ /**
+ * The batch size in which to group flushes of the index.
+ *
+ * @return
+ */
public int getIndexerBatchSize();
- public int getIndexerMaxMergeDocs();
-
- public int getIndexerMergeFactor();
-
- public int getIndexerMinMergeDocs();
-
- public String getLockDirectory();
-
+ /**
+ * The maximum numbr of sub-queries the can be generated out of wild card expansion etc
+ * @return
+ */
public int getQueryMaxClauses();
+
+ /**
+ * The default mode for analysing ML text during index.
+ *
+ * @return
+ */
+ public MLAnalysisMode getDefaultMLIndexAnalysisMode();
+
+ /**
+ * The default mode for analysis of ML text during search.
+ *
+ * @return
+ */
+ public MLAnalysisMode getDefaultMLSearchAnalysisMode();
}
diff --git a/source/java/org/alfresco/repo/search/impl/lucene/LuceneIndexer.java b/source/java/org/alfresco/repo/search/impl/lucene/LuceneIndexer.java
deleted file mode 100644
index 68c8763abe..0000000000
--- a/source/java/org/alfresco/repo/search/impl/lucene/LuceneIndexer.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2005 Alfresco, Inc.
- *
- * Licensed under the Mozilla Public License version 1.1
- * with a permitted attribution clause. You may obtain a
- * copy of the License at
- *
- * http://www.alfresco.org/legal/license.txt
- *
- * 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.alfresco.repo.search.impl.lucene;
-
-import java.util.Set;
-
-import org.alfresco.repo.search.Indexer;
-import org.alfresco.repo.search.IndexerSPI;
-import org.alfresco.repo.search.impl.lucene.fts.FTSIndexerAware;
-import org.alfresco.repo.search.impl.lucene.fts.FullTextSearchIndexer;
-import org.alfresco.service.cmr.dictionary.DictionaryService;
-import org.alfresco.service.cmr.repository.NodeRef;
-import org.alfresco.service.cmr.repository.NodeService;
-
-/**
- * @author Andy Hind
- */
-public interface LuceneIndexer extends IndexerSPI, Lockable
-{
-
- public void commit();
- public void rollback();
- public int prepare();
- public boolean isModified();
- public void setNodeService(NodeService nodeService);
- public void setDictionaryService(DictionaryService dictionaryService);
- public void setLuceneFullTextSearchIndexer(FullTextSearchIndexer luceneFullTextSearchIndexer);
-
- public String getDeltaId();
- public void flushPending() throws LuceneIndexException;
- public Set getDeletions();
-}
diff --git a/source/java/org/alfresco/repo/search/impl/lucene/LuceneIndexerAndSearcherFactory2.java b/source/java/org/alfresco/repo/search/impl/lucene/LuceneIndexerAndSearcherFactory2.java
index eeef925e30..da7e98ccee 100644
--- a/source/java/org/alfresco/repo/search/impl/lucene/LuceneIndexerAndSearcherFactory2.java
+++ b/source/java/org/alfresco/repo/search/impl/lucene/LuceneIndexerAndSearcherFactory2.java
@@ -30,11 +30,11 @@ import javax.transaction.xa.Xid;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.repo.search.IndexerException;
+import org.alfresco.repo.search.MLAnalysisMode;
import org.alfresco.repo.search.QueryRegisterComponent;
import org.alfresco.repo.search.SearcherException;
import org.alfresco.repo.search.impl.lucene.fts.FullTextSearchIndexer;
import org.alfresco.repo.search.impl.lucene.index.IndexInfo;
-import org.alfresco.repo.search.transaction.LuceneIndexLock;
import org.alfresco.repo.search.transaction.SimpleTransaction;
import org.alfresco.repo.search.transaction.SimpleTransactionManager;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
@@ -50,7 +50,6 @@ import org.alfresco.util.GUID;
import org.apache.commons.io.FileUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.store.Lock;
import org.quartz.Job;
@@ -59,14 +58,11 @@ import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
/**
- * This class is resource manager LuceneIndexers and LuceneSearchers.
- *
- * It supports two phase commit inside XA transactions and outside transactions it provides thread local transaction support.
- *
- * TODO: Provide pluggable support for a transaction manager TODO: Integrate with Spring transactions
+ * This class is resource manager LuceneIndexers and LuceneSearchers. It supports two phase commit inside XA
+ * transactions and outside transactions it provides thread local transaction support. TODO: Provide pluggable support
+ * for a transaction manager TODO: Integrate with Spring transactions
*
* @author andyh
- *
*/
public class LuceneIndexerAndSearcherFactory2 implements LuceneIndexerAndSearcher, XAResource
@@ -81,16 +77,9 @@ public class LuceneIndexerAndSearcherFactory2 implements LuceneIndexerAndSearche
private int indexerBatchSize;
- private int indexerMinMergeDocs;
-
- private int indexerMergeFactor;
-
- private int indexerMaxMergeDocs;
-
- private String lockDirectory;
-
/**
- * A map of active global transactions . It contains all the indexers a transaction has used, with at most one indexer for each store within a transaction
+ * A map of active global transactions . It contains all the indexers a transaction has used, with at most one
+ * indexer for each store within a transaction
*/
private static Map> activeIndexersInGlobalTx = new HashMap>();
@@ -123,8 +112,6 @@ public class LuceneIndexerAndSearcherFactory2 implements LuceneIndexerAndSearche
private NodeService nodeService;
- private LuceneIndexLock luceneIndexLock;
-
private FullTextSearchIndexer luceneFullTextSearchIndexer;
private String indexRootLocation;
@@ -142,6 +129,12 @@ public class LuceneIndexerAndSearcherFactory2 implements LuceneIndexerAndSearche
private long commitLockTimeout;
+ private String lockDirectory;
+
+ private MLAnalysisMode defaultMLIndexAnalysisMode = MLAnalysisMode.LOCALE_ONLY;
+
+ private MLAnalysisMode defaultMLSearchAnalysisMode = MLAnalysisMode.LOCALE_AND_ALL;
+
/**
* Private constructor for the singleton TODO: FIt in with IOC
*/
@@ -172,11 +165,6 @@ public class LuceneIndexerAndSearcherFactory2 implements LuceneIndexerAndSearche
this.nameSpaceService = nameSpaceService;
}
- public void setLuceneIndexLock(LuceneIndexLock luceneIndexLock)
- {
- this.luceneIndexLock = luceneIndexLock;
- }
-
public void setLuceneFullTextSearchIndexer(FullTextSearchIndexer luceneFullTextSearchIndexer)
{
this.luceneFullTextSearchIndexer = luceneFullTextSearchIndexer;
@@ -193,7 +181,8 @@ public class LuceneIndexerAndSearcherFactory2 implements LuceneIndexerAndSearche
}
/**
- * Set the maximum average transformation time allowed to a transformer in order to have the transformation performed in the current transaction. The default is 20ms.
+ * Set the maximum average transformation time allowed to a transformer in order to have the transformation
+ * performed in the current transaction. The default is 20ms.
*
* @param maxAtomicTransformationTime
* the maximum average time that a text transformation may take in order to be performed atomically.
@@ -796,36 +785,6 @@ public class LuceneIndexerAndSearcherFactory2 implements LuceneIndexerAndSearche
this.indexerBatchSize = indexerBatchSize;
}
- public int getIndexerMaxMergeDocs()
- {
- return indexerMaxMergeDocs;
- }
-
- public void setIndexerMaxMergeDocs(int indexerMaxMergeDocs)
- {
- this.indexerMaxMergeDocs = indexerMaxMergeDocs;
- }
-
- public int getIndexerMergeFactor()
- {
- return indexerMergeFactor;
- }
-
- public void setIndexerMergeFactor(int indexerMergeFactor)
- {
- this.indexerMergeFactor = indexerMergeFactor;
- }
-
- public int getIndexerMinMergeDocs()
- {
- return indexerMinMergeDocs;
- }
-
- public void setIndexerMinMergeDocs(int indexerMinMergeDocs)
- {
- this.indexerMinMergeDocs = indexerMinMergeDocs;
- }
-
public String getLockDirectory()
{
return lockDirectory;
@@ -882,7 +841,7 @@ public class LuceneIndexerAndSearcherFactory2 implements LuceneIndexerAndSearche
{
this.commitLockTimeout = timeout;
}
-
+
public long getCommitLockTimeout()
{
return commitLockTimeout;
@@ -912,7 +871,8 @@ public class LuceneIndexerAndSearcherFactory2 implements LuceneIndexerAndSearche
/**
* This component is able to safely perform backups of the Lucene indexes while the server is running.
*
- * It can be run directly by calling the {@link #backup() } method, but the convenience {@link LuceneIndexBackupJob} can be used to call it as well.
+ * It can be run directly by calling the {@link #backup() } method, but the convenience {@link LuceneIndexBackupJob}
+ * can be used to call it as well.
*
* @author Derek Hulley
*/
@@ -1204,4 +1164,27 @@ public class LuceneIndexerAndSearcherFactory2 implements LuceneIndexerAndSearche
});
}
}
+
+ public MLAnalysisMode getDefaultMLIndexAnalysisMode()
+ {
+ return defaultMLIndexAnalysisMode;
+ }
+
+ public void setDefaultMLIndexAnalysisMode(String mode)
+ {
+ defaultMLIndexAnalysisMode = MLAnalysisMode.getMLAnalysisMode(mode);
+ }
+
+ public MLAnalysisMode getDefaultMLSearchAnalysisMode()
+ {
+ return defaultMLSearchAnalysisMode;
+ }
+
+ public void setDefaultMLSearchAnalysisMode(String mode)
+ {
+ defaultMLSearchAnalysisMode = MLAnalysisMode.getMLAnalysisMode(mode);
+ }
+
+
+
}
diff --git a/source/java/org/alfresco/repo/search/impl/lucene/LuceneIndexerImpl2.java b/source/java/org/alfresco/repo/search/impl/lucene/LuceneIndexerImpl2.java
index a832cc74c6..9ee498b1db 100644
--- a/source/java/org/alfresco/repo/search/impl/lucene/LuceneIndexerImpl2.java
+++ b/source/java/org/alfresco/repo/search/impl/lucene/LuceneIndexerImpl2.java
@@ -30,6 +30,7 @@ import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
+import java.util.Locale;
import java.util.Map;
import java.util.Set;
@@ -55,6 +56,7 @@ import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
+import org.alfresco.service.cmr.repository.MLText;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.Path;
@@ -475,7 +477,7 @@ public class LuceneIndexerImpl2 extends LuceneBase2 implements LuceneIndexer2
}
LuceneIndexerImpl2 indexer = new LuceneIndexerImpl2();
indexer.setLuceneConfig(config);
- indexer.initialise(storeRef, deltaId, false, true);
+ indexer.initialise(storeRef, deltaId);
return indexer;
}
@@ -1443,6 +1445,7 @@ public class LuceneIndexerImpl2 extends LuceneBase2 implements LuceneIndexer2
boolean tokenise = true;
boolean atomic = true;
boolean isContent = false;
+ boolean isMultiLingual = false;
PropertyDefinition propertyDef = getDictionaryService().getProperty(propertyName);
if (propertyDef != null)
@@ -1452,6 +1455,7 @@ public class LuceneIndexerImpl2 extends LuceneBase2 implements LuceneIndexer2
tokenise = propertyDef.isTokenisedInIndex();
atomic = propertyDef.isIndexedAtomically();
isContent = propertyDef.getDataType().getName().equals(DataTypeDefinition.CONTENT);
+ isMultiLingual = propertyDef.getDataType().getName().equals(DataTypeDefinition.MLTEXT);
}
if (value == null)
{
@@ -1621,7 +1625,20 @@ public class LuceneIndexerImpl2 extends LuceneBase2 implements LuceneIndexer2
fieldIndex = Field.Index.NO;
}
- doc.add(new Field(attributeName, strValue, fieldStore, fieldIndex, Field.TermVector.NO));
+ if(isMultiLingual)
+ {
+ MLText mlText = DefaultTypeConverter.INSTANCE.convert(MLText.class, value);
+ for(Locale locale : mlText.getLocales())
+ {
+ String localeString = mlText.getValue(locale);
+ doc.add(new Field(attributeName, "\u0000" + locale.toString() +"\u0000" + localeString, fieldStore, fieldIndex, Field.TermVector.NO));
+ }
+ }
+ else
+ {
+ doc.add(new Field(attributeName, strValue, fieldStore, fieldIndex, Field.TermVector.NO));
+ }
+
}
}
diff --git a/source/java/org/alfresco/repo/search/impl/lucene/LuceneQueryParser.java b/source/java/org/alfresco/repo/search/impl/lucene/LuceneQueryParser.java
index 129c4515b9..eb321ce9bc 100644
--- a/source/java/org/alfresco/repo/search/impl/lucene/LuceneQueryParser.java
+++ b/source/java/org/alfresco/repo/search/impl/lucene/LuceneQueryParser.java
@@ -18,16 +18,18 @@ package org.alfresco.repo.search.impl.lucene;
import java.io.IOException;
import java.io.StringReader;
+import java.util.Collection;
+import java.util.Collections;
import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
+import java.util.List;
+import java.util.Locale;
+import org.alfresco.i18n.I18NUtil;
import org.alfresco.repo.search.SearcherException;
import org.alfresco.repo.search.impl.lucene.query.PathQuery;
import org.alfresco.service.cmr.dictionary.AspectDefinition;
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
import org.alfresco.service.cmr.dictionary.DictionaryService;
-import org.alfresco.service.cmr.dictionary.ModelDefinition;
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
import org.alfresco.service.cmr.dictionary.TypeDefinition;
import org.alfresco.service.namespace.NamespacePrefixResolver;
@@ -53,6 +55,8 @@ public class LuceneQueryParser extends QueryParser
private DictionaryService dictionaryService;
+ private List locales;
+
/**
* Parses a query string, returning a {@link org.apache.lucene.search.Query}.
*
@@ -66,8 +70,8 @@ public class LuceneQueryParser extends QueryParser
* if the parsing fails
*/
static public Query parse(String query, String field, Analyzer analyzer,
- NamespacePrefixResolver namespacePrefixResolver, DictionaryService dictionaryService, Operator defaultOperator)
- throws ParseException
+ NamespacePrefixResolver namespacePrefixResolver, DictionaryService dictionaryService,
+ Operator defaultOperator, List locales) throws ParseException
{
if (s_logger.isDebugEnabled())
{
@@ -77,9 +81,16 @@ public class LuceneQueryParser extends QueryParser
parser.setDefaultOperator(defaultOperator);
parser.setNamespacePrefixResolver(namespacePrefixResolver);
parser.setDictionaryService(dictionaryService);
+ parser.setLocales(locales);
+ // TODO: Apply locale contstraints at the top level if required for the non ML doc types.
return parser.parse(query);
}
+ private void setLocales(List locales)
+ {
+ this.locales = locales;
+ }
+
public void setNamespacePrefixResolver(NamespacePrefixResolver namespacePrefixResolver)
{
this.namespacePrefixResolver = namespacePrefixResolver;
@@ -128,14 +139,14 @@ public class LuceneQueryParser extends QueryParser
pathQuery.setRepeats(true);
return pathQuery;
}
- else if(field.equals("TEXT"))
+ else if (field.equals("TEXT"))
{
- Set contentAttributes = getContentAttributes();
+ Collection contentAttributes = dictionaryService.getAllProperties(DataTypeDefinition.CONTENT);
BooleanQuery query = new BooleanQuery();
- for(QName qname : contentAttributes)
+ for (QName qname : contentAttributes)
{
// The super implementation will create phrase queries etc if required
- Query part = super.getFieldQuery("@"+qname.toString(), queryText);
+ Query part = super.getFieldQuery("@" + qname.toString(), queryText);
query.add(part, Occur.SHOULD);
}
return query;
@@ -173,7 +184,7 @@ public class LuceneQueryParser extends QueryParser
else if (field.equals("TYPE"))
{
TypeDefinition target;
- if(queryText.startsWith("{"))
+ if (queryText.startsWith("{"))
{
target = dictionaryService.getType(QName.createQName(queryText));
}
@@ -183,12 +194,15 @@ public class LuceneQueryParser extends QueryParser
if (colonPosition == -1)
{
// use the default namespace
- target = dictionaryService.getType(QName.createQName(namespacePrefixResolver.getNamespaceURI(""), queryText));
+ target = dictionaryService.getType(QName.createQName(namespacePrefixResolver
+ .getNamespaceURI(""), queryText));
}
else
{
// find the prefix
- target = dictionaryService.getType(QName.createQName(namespacePrefixResolver.getNamespaceURI(queryText.substring(0, colonPosition)), queryText.substring(colonPosition + 1)));
+ target = dictionaryService.getType(QName.createQName(namespacePrefixResolver
+ .getNamespaceURI(queryText.substring(0, colonPosition)), queryText
+ .substring(colonPosition + 1)));
}
}
if (target == null)
@@ -221,7 +235,7 @@ public class LuceneQueryParser extends QueryParser
else if (field.equals("ASPECT"))
{
AspectDefinition target;
- if(queryText.startsWith("{"))
+ if (queryText.startsWith("{"))
{
target = dictionaryService.getAspect(QName.createQName(queryText));
}
@@ -231,15 +245,18 @@ public class LuceneQueryParser extends QueryParser
if (colonPosition == -1)
{
// use the default namespace
- target = dictionaryService.getAspect(QName.createQName(namespacePrefixResolver.getNamespaceURI(""), queryText));
+ target = dictionaryService.getAspect(QName.createQName(namespacePrefixResolver
+ .getNamespaceURI(""), queryText));
}
else
{
// find the prefix
- target = dictionaryService.getAspect(QName.createQName(namespacePrefixResolver.getNamespaceURI(queryText.substring(0, colonPosition)), queryText.substring(colonPosition + 1)));
+ target = dictionaryService.getAspect(QName.createQName(namespacePrefixResolver
+ .getNamespaceURI(queryText.substring(0, colonPosition)), queryText
+ .substring(colonPosition + 1)));
}
}
-
+
QName targetQName = target.getName();
HashSet subclasses = new HashSet();
for (QName classRef : dictionaryService.getAllAspects())
@@ -266,6 +283,7 @@ public class LuceneQueryParser extends QueryParser
}
else if (field.startsWith("@"))
{
+ // Expand prefixes
String expandedFieldName = field;
// Check for any prefixes and expand to the full uri
@@ -276,7 +294,7 @@ public class LuceneQueryParser extends QueryParser
{
// use the default namespace
expandedFieldName = "@{"
- + namespacePrefixResolver.getNamespaceURI("") + "}" + field.substring(1);
+ + namespacePrefixResolver.getNamespaceURI("") + "}" + field.substring(1);
}
else
{
@@ -286,21 +304,46 @@ public class LuceneQueryParser extends QueryParser
+ field.substring(colonPosition + 1);
}
}
-
- if(expandedFieldName.endsWith(".mimetype"))
+
+ // Mime type
+ if (expandedFieldName.endsWith(".mimetype"))
{
- QName propertyQName = QName.createQName(expandedFieldName.substring(1, expandedFieldName.length()-9));
+ QName propertyQName = QName.createQName(expandedFieldName.substring(1,
+ expandedFieldName.length() - 9));
PropertyDefinition propertyDef = dictionaryService.getProperty(propertyQName);
- if((propertyDef != null) && (propertyDef.getDataType().getName().equals(DataTypeDefinition.CONTENT)))
+ if ((propertyDef != null)
+ && (propertyDef.getDataType().getName().equals(DataTypeDefinition.CONTENT)))
{
return super.getFieldQuery(expandedFieldName, queryText);
}
-
+
}
-
+
// Already in expanded form
- return super.getFieldQuery(expandedFieldName, queryText);
-
+
+ // ML
+
+ QName propertyQName = QName.createQName(expandedFieldName.substring(1));
+ PropertyDefinition propertyDef = dictionaryService.getProperty(propertyQName);
+ if ((propertyDef != null) && (propertyDef.getDataType().getName().equals(DataTypeDefinition.MLTEXT)))
+ {
+ // Build a sub query for each locale and or the results together - the analysis will take care of
+ // cross language matching for each entry
+ BooleanQuery booleanQuery = new BooleanQuery();
+ for (Locale locale : (((locales == null) || (locales.size() == 0)) ? Collections
+ .singletonList(I18NUtil.getLocale()) : locales))
+ {
+ StringBuilder builder = new StringBuilder(queryText.length() + 10);
+ builder.append("\u0000").append(locale.toString()).append("\u0000").append(queryText);
+ Query subQuery = super.getFieldQuery(expandedFieldName, builder.toString());
+ booleanQuery.add(subQuery, Occur.SHOULD);
+ }
+ return booleanQuery;
+ }
+ else
+ {
+ return super.getFieldQuery(expandedFieldName, queryText);
+ }
}
else
@@ -315,37 +358,6 @@ public class LuceneQueryParser extends QueryParser
}
- private Set getContentAttributes()
- {
- HashSet contentAttributes = new HashSet();
-
- for(QName type : dictionaryService.getAllTypes())
- {
- Map props = dictionaryService.getType(type).getProperties();
- for(QName prop : props.keySet())
- {
- if(props.get(prop).getDataType().getName().equals(DataTypeDefinition.CONTENT))
- {
- contentAttributes.add(prop);
- }
- }
- }
-
- for(QName aspect : dictionaryService.getAllAspects())
- {
- Map props = dictionaryService.getAspect(aspect).getProperties();
- for(QName prop : props.keySet())
- {
- if(props.get(prop).getDataType().getName().equals(DataTypeDefinition.CONTENT))
- {
- contentAttributes.add(prop);
- }
- }
- }
-
- return contentAttributes;
- }
-
/**
* @exception ParseException
* throw in overridden method to disallow
@@ -415,11 +427,264 @@ public class LuceneQueryParser extends QueryParser
}
+ @Override
+ protected Query getPrefixQuery(String field, String termStr) throws ParseException
+ {
+ if (field.startsWith("@"))
+ {
+ // Expand prefixes
+
+ String expandedFieldName = field;
+ // Check for any prefixes and expand to the full uri
+ if (field.charAt(1) != '{')
+ {
+ int colonPosition = field.indexOf(':');
+ if (colonPosition == -1)
+ {
+ // use the default namespace
+ expandedFieldName = "@{" + namespacePrefixResolver.getNamespaceURI("") + "}" + field.substring(1);
+ }
+ else
+ {
+ // find the prefix
+ expandedFieldName = "@{"
+ + namespacePrefixResolver.getNamespaceURI(field.substring(1, colonPosition)) + "}"
+ + field.substring(colonPosition + 1);
+ }
+ }
+
+ // Mime type
+ if (expandedFieldName.endsWith(".mimetype"))
+ {
+ QName propertyQName = QName.createQName(expandedFieldName.substring(1, expandedFieldName.length() - 9));
+ PropertyDefinition propertyDef = dictionaryService.getProperty(propertyQName);
+ if ((propertyDef != null) && (propertyDef.getDataType().getName().equals(DataTypeDefinition.CONTENT)))
+ {
+ return super.getPrefixQuery(expandedFieldName, termStr);
+ }
+
+ }
+
+ // Already in expanded form
+
+ // ML
+
+ QName propertyQName = QName.createQName(expandedFieldName.substring(1));
+ PropertyDefinition propertyDef = dictionaryService.getProperty(propertyQName);
+ if ((propertyDef != null) && (propertyDef.getDataType().getName().equals(DataTypeDefinition.MLTEXT)))
+ {
+ // Build a sub query for each locale and or the results together - the analysis will take care of
+ // cross language matching for each entry
+ BooleanQuery booleanQuery = new BooleanQuery();
+ for (Locale locale : (((locales == null) || (locales.size() == 0)) ? Collections.singletonList(I18NUtil
+ .getLocale()) : locales))
+ {
+ StringBuilder builder = new StringBuilder(termStr.length() + 10);
+ builder.append("\u0000").append(locale.toString()).append("\u0000").append(termStr);
+ Query subQuery = super.getPrefixQuery(expandedFieldName, builder.toString());
+ booleanQuery.add(subQuery, Occur.SHOULD);
+ }
+ return booleanQuery;
+ }
+ else
+ {
+ return super.getPrefixQuery(expandedFieldName, termStr);
+ }
+
+ }
+
+ else if (field.equals("TEXT"))
+ {
+ Collection contentAttributes = dictionaryService.getAllProperties(DataTypeDefinition.CONTENT);
+ BooleanQuery query = new BooleanQuery();
+ for (QName qname : contentAttributes)
+ {
+ // The super implementation will create phrase queries etc if required
+ Query part = super.getPrefixQuery("@" + qname.toString(), termStr);
+ query.add(part, Occur.SHOULD);
+ }
+ return query;
+
+ }
+ else
+ {
+ return super.getFieldQuery(field, termStr);
+ }
+ }
+
+ @Override
+ protected Query getWildcardQuery(String field, String termStr) throws ParseException
+ {
+ if (field.startsWith("@"))
+ {
+ // Expand prefixes
+
+ String expandedFieldName = field;
+ // Check for any prefixes and expand to the full uri
+ if (field.charAt(1) != '{')
+ {
+ int colonPosition = field.indexOf(':');
+ if (colonPosition == -1)
+ {
+ // use the default namespace
+ expandedFieldName = "@{" + namespacePrefixResolver.getNamespaceURI("") + "}" + field.substring(1);
+ }
+ else
+ {
+ // find the prefix
+ expandedFieldName = "@{"
+ + namespacePrefixResolver.getNamespaceURI(field.substring(1, colonPosition)) + "}"
+ + field.substring(colonPosition + 1);
+ }
+ }
+
+ // Mime type
+ if (expandedFieldName.endsWith(".mimetype"))
+ {
+ QName propertyQName = QName.createQName(expandedFieldName.substring(1, expandedFieldName.length() - 9));
+ PropertyDefinition propertyDef = dictionaryService.getProperty(propertyQName);
+ if ((propertyDef != null) && (propertyDef.getDataType().getName().equals(DataTypeDefinition.CONTENT)))
+ {
+ return super.getWildcardQuery(expandedFieldName, termStr);
+ }
+
+ }
+
+ // Already in expanded form
+
+ // ML
+
+ QName propertyQName = QName.createQName(expandedFieldName.substring(1));
+ PropertyDefinition propertyDef = dictionaryService.getProperty(propertyQName);
+ if ((propertyDef != null) && (propertyDef.getDataType().getName().equals(DataTypeDefinition.MLTEXT)))
+ {
+ // Build a sub query for each locale and or the results together - the analysis will take care of
+ // cross language matching for each entry
+ BooleanQuery booleanQuery = new BooleanQuery();
+ for (Locale locale : (((locales == null) || (locales.size() == 0)) ? Collections.singletonList(I18NUtil
+ .getLocale()) : locales))
+ {
+ StringBuilder builder = new StringBuilder(termStr.length() + 10);
+ builder.append("\u0000").append(locale.toString()).append("\u0000").append(termStr);
+ Query subQuery = super.getWildcardQuery(expandedFieldName, builder.toString());
+ booleanQuery.add(subQuery, Occur.SHOULD);
+ }
+ return booleanQuery;
+ }
+ else
+ {
+ return super.getWildcardQuery(expandedFieldName, termStr);
+ }
+
+ }
+
+ else if (field.equals("TEXT"))
+ {
+ Collection contentAttributes = dictionaryService.getAllProperties(DataTypeDefinition.CONTENT);
+ BooleanQuery query = new BooleanQuery();
+ for (QName qname : contentAttributes)
+ {
+ // The super implementation will create phrase queries etc if required
+ Query part = super.getWildcardQuery("@" + qname.toString(), termStr);
+ query.add(part, Occur.SHOULD);
+ }
+ return query;
+
+ }
+ else
+ {
+ return super.getWildcardQuery(field, termStr);
+ }
+ }
+
+ @Override
+ protected Query getFuzzyQuery(String field, String termStr, float minSimilarity) throws ParseException
+ {
+ if (field.startsWith("@"))
+ {
+ // Expand prefixes
+
+ String expandedFieldName = field;
+ // Check for any prefixes and expand to the full uri
+ if (field.charAt(1) != '{')
+ {
+ int colonPosition = field.indexOf(':');
+ if (colonPosition == -1)
+ {
+ // use the default namespace
+ expandedFieldName = "@{" + namespacePrefixResolver.getNamespaceURI("") + "}" + field.substring(1);
+ }
+ else
+ {
+ // find the prefix
+ expandedFieldName = "@{"
+ + namespacePrefixResolver.getNamespaceURI(field.substring(1, colonPosition)) + "}"
+ + field.substring(colonPosition + 1);
+ }
+ }
+
+ // Mime type
+ if (expandedFieldName.endsWith(".mimetype"))
+ {
+ QName propertyQName = QName.createQName(expandedFieldName.substring(1, expandedFieldName.length() - 9));
+ PropertyDefinition propertyDef = dictionaryService.getProperty(propertyQName);
+ if ((propertyDef != null) && (propertyDef.getDataType().getName().equals(DataTypeDefinition.CONTENT)))
+ {
+ return super.getFuzzyQuery(expandedFieldName, termStr, minSimilarity);
+ }
+
+ }
+
+ // Already in expanded form
+
+ // ML
+
+ QName propertyQName = QName.createQName(expandedFieldName.substring(1));
+ PropertyDefinition propertyDef = dictionaryService.getProperty(propertyQName);
+ if ((propertyDef != null) && (propertyDef.getDataType().getName().equals(DataTypeDefinition.MLTEXT)))
+ {
+ // Build a sub query for each locale and or the results together - the analysis will take care of
+ // cross language matching for each entry
+ BooleanQuery booleanQuery = new BooleanQuery();
+ for (Locale locale : (((locales == null) || (locales.size() == 0)) ? Collections.singletonList(I18NUtil
+ .getLocale()) : locales))
+ {
+ StringBuilder builder = new StringBuilder(termStr.length() + 10);
+ builder.append("\u0000").append(locale.toString()).append("\u0000").append(termStr);
+ Query subQuery = super.getFuzzyQuery(expandedFieldName, builder.toString(), minSimilarity);
+ booleanQuery.add(subQuery, Occur.SHOULD);
+ }
+ return booleanQuery;
+ }
+ else
+ {
+ return super.getFuzzyQuery(expandedFieldName, termStr, minSimilarity);
+ }
+
+ }
+
+ else if (field.equals("TEXT"))
+ {
+ Collection contentAttributes = dictionaryService.getAllProperties(DataTypeDefinition.CONTENT);
+ BooleanQuery query = new BooleanQuery();
+ for (QName qname : contentAttributes)
+ {
+ // The super implementation will create phrase queries etc if required
+ Query part = super.getFuzzyQuery("@" + qname.toString(), termStr, minSimilarity);
+ query.add(part, Occur.SHOULD);
+ }
+ return query;
+
+ }
+ else
+ {
+ return super.getFuzzyQuery(field, termStr, minSimilarity);
+ }
+ }
+
public void setDictionaryService(DictionaryService dictionaryService)
{
this.dictionaryService = dictionaryService;
}
-
-
}
diff --git a/source/java/org/alfresco/repo/search/impl/lucene/LuceneSearcher.java b/source/java/org/alfresco/repo/search/impl/lucene/LuceneSearcher.java
deleted file mode 100644
index 425583e12d..0000000000
--- a/source/java/org/alfresco/repo/search/impl/lucene/LuceneSearcher.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2005 Alfresco, Inc.
- *
- * Licensed under the Mozilla Public License version 1.1
- * with a permitted attribution clause. You may obtain a
- * copy of the License at
- *
- * http://www.alfresco.org/legal/license.txt
- *
- * 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.alfresco.repo.search.impl.lucene;
-
-import org.alfresco.service.cmr.repository.NodeService;
-import org.alfresco.service.cmr.search.SearchService;
-import org.alfresco.service.namespace.NamespacePrefixResolver;
-
-public interface LuceneSearcher extends SearchService, Lockable
-{
- public boolean indexExists();
- public void setNodeService(NodeService nodeService);
- public void setNamespacePrefixResolver(NamespacePrefixResolver namespacePrefixResolver);
-}
diff --git a/source/java/org/alfresco/repo/search/impl/lucene/LuceneSearcherImpl2.java b/source/java/org/alfresco/repo/search/impl/lucene/LuceneSearcherImpl2.java
index db1aba72ad..6941bffed5 100644
--- a/source/java/org/alfresco/repo/search/impl/lucene/LuceneSearcherImpl2.java
+++ b/source/java/org/alfresco/repo/search/impl/lucene/LuceneSearcherImpl2.java
@@ -102,7 +102,7 @@ public class LuceneSearcherImpl2 extends LuceneBase2 implements LuceneSearcher2
searcher.setLuceneConfig(config);
try
{
- searcher.initialise(storeRef, indexer == null ? null : indexer.getDeltaId(), false, false);
+ searcher.initialise(storeRef, indexer == null ? null : indexer.getDeltaId());
searcher.indexer = indexer;
}
catch (LuceneIndexException e)
@@ -215,7 +215,7 @@ public class LuceneSearcherImpl2 extends LuceneBase2 implements LuceneSearcher2
}
Query query = LuceneQueryParser.parse(parameterisedQueryString, DEFAULT_FIELD, new LuceneAnalyser(
- dictionaryService), namespacePrefixResolver, dictionaryService, defaultOperator);
+ dictionaryService, searchParameters.getMlAnalaysisMode() == null ? getLuceneConfig().getDefaultMLSearchAnalysisMode() : searchParameters.getMlAnalaysisMode()), namespacePrefixResolver, dictionaryService, defaultOperator, searchParameters.getLocales());
ClosingIndexSearcher searcher = getSearcher(indexer);
if (searcher == null)
{
diff --git a/source/java/org/alfresco/repo/search/impl/lucene/LuceneTest2.java b/source/java/org/alfresco/repo/search/impl/lucene/LuceneTest2.java
index 148c7f5f30..b2734713f6 100644
--- a/source/java/org/alfresco/repo/search/impl/lucene/LuceneTest2.java
+++ b/source/java/org/alfresco/repo/search/impl/lucene/LuceneTest2.java
@@ -27,6 +27,7 @@ import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.Locale;
import java.util.Map;
import java.util.Random;
@@ -43,11 +44,9 @@ import org.alfresco.repo.dictionary.NamespaceDAOImpl;
import org.alfresco.repo.node.BaseNodeServiceTest;
import org.alfresco.repo.search.QueryParameterDefImpl;
import org.alfresco.repo.search.QueryRegisterComponent;
-import org.alfresco.repo.search.impl.lucene.analysis.NumericEncoder;
import org.alfresco.repo.search.impl.lucene.fts.FullTextSearchIndexer;
import org.alfresco.repo.search.results.ChildAssocRefResultSet;
import org.alfresco.repo.search.results.DetachedResultSet;
-import org.alfresco.repo.search.transaction.LuceneIndexLock;
import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.service.ServiceRegistry;
@@ -57,6 +56,7 @@ import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.ContentData;
import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.ContentWriter;
+import org.alfresco.service.cmr.repository.MLText;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.Path;
@@ -83,7 +83,6 @@ import org.springframework.context.ApplicationContext;
/**
* @author andyh
- *
*/
@SuppressWarnings("unused")
public class LuceneTest2 extends TestCase
@@ -100,11 +99,11 @@ public class LuceneTest2 extends TestCase
QName createdDate = QName.createQName(TEST_NAMESPACE, "createdDate");
QName orderDouble = QName.createQName(TEST_NAMESPACE, "orderDouble");
-
+
QName orderFloat = QName.createQName(TEST_NAMESPACE, "orderFloat");
-
+
QName orderLong = QName.createQName(TEST_NAMESPACE, "orderLong");
-
+
QName orderInt = QName.createQName(TEST_NAMESPACE, "orderInt");
TransactionService transactionService;
@@ -113,8 +112,6 @@ public class LuceneTest2 extends TestCase
DictionaryService dictionaryService;
- LuceneIndexLock luceneIndexLock;
-
private NodeRef rootNodeRef;
private NodeRef n1;
@@ -183,7 +180,6 @@ public class LuceneTest2 extends TestCase
public void setUp() throws Exception
{
nodeService = (NodeService) ctx.getBean("dbNodeService");
- luceneIndexLock = (LuceneIndexLock) ctx.getBean("luceneIndexLock");
dictionaryService = (DictionaryService) ctx.getBean("dictionaryService");
dictionaryDAO = (DictionaryDAO) ctx.getBean("dictionaryDAO");
luceneFTS = (FullTextSearchIndexer) ctx.getBean("LuceneFullTextSearchIndexer");
@@ -193,31 +189,28 @@ public class LuceneTest2 extends TestCase
indexerAndSearcher = (LuceneIndexerAndSearcher) ctx.getBean("luceneIndexerAndSearcherFactory");
transactionService = (TransactionService) ctx.getBean("transactionComponent");
serviceRegistry = (ServiceRegistry) ctx.getBean(ServiceRegistry.SERVICE_REGISTRY);
-
- namespaceDao = (NamespaceDAOImpl) ctx.getBean("namespaceDAO");
-
+
+ namespaceDao = (NamespaceDAOImpl) ctx.getBean("namespaceDAO");
this.authenticationComponent = (AuthenticationComponent) ctx.getBean("authenticationComponent");
-
queryRegisterComponent.loadQueryCollection("testQueryRegister.xml");
- assertEquals(true, ctx.isSingleton("luceneIndexLock"));
assertEquals(true, ctx.isSingleton("LuceneFullTextSearchIndexer"));
testTX = transactionService.getUserTransaction();
testTX.begin();
this.authenticationComponent.setSystemUserAsCurrentUser();
-
+
// load in the test model
ClassLoader cl = BaseNodeServiceTest.class.getClassLoader();
InputStream modelStream = cl.getResourceAsStream("org/alfresco/repo/search/impl/lucene/LuceneTest_model.xml");
assertNotNull(modelStream);
M2Model model = M2Model.createModel(modelStream);
dictionaryDAO.putModel(model);
-
+
namespaceDao.addPrefix("test", TEST_NAMESPACE);
-
+
StoreRef storeRef = nodeService.createStore(StoreRef.PROTOCOL_WORKSPACE, "Test_" + System.currentTimeMillis());
rootNodeRef = nodeService.getRootNode(storeRef);
@@ -276,6 +269,20 @@ public class LuceneTest2 extends TestCase
testProperties.put(QName.createQName(TEST_NAMESPACE, "path-ista"), nodeService.getPath(n3));
testProperties.put(QName.createQName(TEST_NAMESPACE, "null"), null);
testProperties.put(QName.createQName(TEST_NAMESPACE, "list"), new ArrayList());
+ MLText mlText = new MLText();
+ mlText.addValue(Locale.ENGLISH, "banana");
+ mlText.addValue(Locale.FRENCH, "banane");
+ mlText.addValue(Locale.CHINESE, "香蕉");
+ mlText.addValue(new Locale("nl"), "banaan");
+ mlText.addValue(Locale.GERMAN, "banane");
+ mlText.addValue(new Locale("el"), "μπανάνα");
+ mlText.addValue(Locale.ITALIAN, "banana");
+ mlText.addValue(new Locale("ja"), "バナナ");
+ mlText.addValue(new Locale("ko"), "바나나");
+ mlText.addValue(new Locale("pt"), "banana");
+ mlText.addValue(new Locale("ru"), "банан");
+ mlText.addValue(new Locale("es"), "plátano");
+ testProperties.put(QName.createQName(TEST_NAMESPACE, "ml"), mlText);
ArrayList