diff --git a/config/alfresco/bootstrap-context.xml b/config/alfresco/bootstrap-context.xml index 62ceb6681b..b3a27f81c1 100644 --- a/config/alfresco/bootstrap-context.xml +++ b/config/alfresco/bootstrap-context.xml @@ -36,6 +36,7 @@ classpath:alfresco/dbscripts/create/2.1/${db.script.dialect}/AlfrescoPostCreate-2.1-FKIndexes.sql + classpath:alfresco/dbscripts/create/1.4/${db.script.dialect}/post-create-indexes-02.sql diff --git a/config/alfresco/dbscripts/upgrade/2.1/org.hibernate.dialect.AlfrescoSQLServerDialect/AlfrescoSchemaUpdate-2.1-JBPMProcessKey.sql b/config/alfresco/dbscripts/upgrade/2.1/org.hibernate.dialect.AlfrescoSQLServerDialect/AlfrescoSchemaUpdate-2.1-JBPMProcessKey.sql new file mode 100644 index 0000000000..9d2b1d1a39 --- /dev/null +++ b/config/alfresco/dbscripts/upgrade/2.1/org.hibernate.dialect.AlfrescoSQLServerDialect/AlfrescoSchemaUpdate-2.1-JBPMProcessKey.sql @@ -0,0 +1,22 @@ +-- +-- Title: Jbpm 3.2 Process Instance Key +-- Database: SQL Server +-- Since: V2.1 Schema 63 +-- Author: David Caruana +-- +-- Please contact support@alfresco.com if you need assistance with the upgrade. +-- + +UPDATE JBPM_PROCESSINSTANCE SET KEY_ = STR(ID_) WHERE KEY_ IS NULL; + +-- +-- Record script finish +-- +DELETE FROM alf_applied_patch WHERE id = 'patch.db-V2.1-JBPMProcessKey'; +INSERT INTO alf_applied_patch + (id, description, fixes_from_schema, fixes_to_schema, applied_to_schema, target_schema, applied_on_date, applied_to_server, was_executed, succeeded, report) + VALUES + ( + 'patch.db-V2.1-JBPMProcessKey', 'Manually executed script upgrade V2.1: JBPM 3.2 Process Instance Key', + 0, 62, -1, 63, null, 'UNKOWN', 1, 1, 'Script completed' + ); \ No newline at end of file diff --git a/config/alfresco/model/dataTypeAnalyzers_fi.properties b/config/alfresco/model/dataTypeAnalyzers_fi.properties new file mode 100644 index 0000000000..6320710a65 --- /dev/null +++ b/config/alfresco/model/dataTypeAnalyzers_fi.properties @@ -0,0 +1,4 @@ +# Data Type Index Analyzers + +d_dictionary.datatype.d_text.analyzer=org.alfresco.repo.search.impl.lucene.analysis.FinnishSnowballAnalyser +d_dictionary.datatype.d_content.analyzer=org.alfresco.repo.search.impl.lucene.analysis.FinnishSnowballAnalyser diff --git a/source/java/org/alfresco/repo/domain/hibernate/Node.hbm.xml b/source/java/org/alfresco/repo/domain/hibernate/Node.hbm.xml index df78c655c1..c707a0987a 100644 --- a/source/java/org/alfresco/repo/domain/hibernate/Node.hbm.xml +++ b/source/java/org/alfresco/repo/domain/hibernate/Node.hbm.xml @@ -254,20 +254,13 @@ select status from - org.alfresco.repo.domain.hibernate.NodeStatusImpl as status - join status.node as node + org.alfresco.repo.domain.hibernate.NodeStatusImpl as status, + org.alfresco.repo.domain.hibernate.ChildAssocImpl as assoc + join assoc.child as child where - node.id in - ( - select - child.id - from - org.alfresco.repo.domain.hibernate.ChildAssocImpl as assoc - join assoc.child as child - where - assoc.parent.id = :parentId and - assoc.isPrimary = true - ) + assoc.parent.id = :parentId and + assoc.isPrimary = true and + status.node.id = child.id diff --git a/source/java/org/alfresco/repo/node/index/IndexTransactionTrackerTest.java b/source/java/org/alfresco/repo/node/index/IndexTransactionTrackerTest.java index d83de501bc..1c34f22be6 100644 --- a/source/java/org/alfresco/repo/node/index/IndexTransactionTrackerTest.java +++ b/source/java/org/alfresco/repo/node/index/IndexTransactionTrackerTest.java @@ -66,7 +66,7 @@ public class IndexTransactionTrackerTest extends TestCase searchService = serviceRegistry.getSearchService(); nodeService = serviceRegistry.getNodeService(); fileFolderService = serviceRegistry.getFileFolderService(); - authenticationComponent = (AuthenticationComponent) ctx.getBean("authenticationComponentImpl"); + authenticationComponent = (AuthenticationComponent) ctx.getBean("authenticationComponent"); contentStore = (ContentStore) ctx.getBean("fileContentStore"); ftsIndexer = (FullTextSearchIndexer) ctx.getBean("LuceneFullTextSearchIndexer"); @@ -108,7 +108,7 @@ public class IndexTransactionTrackerTest extends TestCase return childAssocRef; } }; - ChildAssociationRef childAssocRef = transactionService.getRetryingTransactionHelper().doInTransaction(createNodeWork, true); + ChildAssociationRef childAssocRef = transactionService.getRetryingTransactionHelper().doInTransaction(createNodeWork, false); } public void testSetup() throws Exception diff --git a/source/java/org/alfresco/repo/node/integrity/IntegrityChecker.java b/source/java/org/alfresco/repo/node/integrity/IntegrityChecker.java index 8e8247be50..7a29071bea 100644 --- a/source/java/org/alfresco/repo/node/integrity/IntegrityChecker.java +++ b/source/java/org/alfresco/repo/node/integrity/IntegrityChecker.java @@ -623,7 +623,7 @@ public class IntegrityChecker if (failOnViolation && !warnOnly) { logger.error(sb.toString()); - throw new IntegrityException(failures); + throw new IntegrityException(sb.toString(), failures); } else { diff --git a/source/java/org/alfresco/repo/node/integrity/IntegrityException.java b/source/java/org/alfresco/repo/node/integrity/IntegrityException.java index d36121ca7b..89c1be5380 100644 --- a/source/java/org/alfresco/repo/node/integrity/IntegrityException.java +++ b/source/java/org/alfresco/repo/node/integrity/IntegrityException.java @@ -45,6 +45,12 @@ public class IntegrityException extends AlfrescoRuntimeException this.records = records; } + public IntegrityException(String msg, List records) + { + super(msg); + this.records = records; + } + /** * @return Returns a list of all the integrity violations */ diff --git a/source/java/org/alfresco/repo/search/impl/lucene/ADMLuceneIndexerImpl.java b/source/java/org/alfresco/repo/search/impl/lucene/ADMLuceneIndexerImpl.java index 8b833219d3..b17d537707 100644 --- a/source/java/org/alfresco/repo/search/impl/lucene/ADMLuceneIndexerImpl.java +++ b/source/java/org/alfresco/repo/search/impl/lucene/ADMLuceneIndexerImpl.java @@ -31,8 +31,11 @@ import java.io.Reader; import java.io.Serializable; import java.io.StringReader; import java.io.UnsupportedEncodingException; +import java.text.ParseException; +import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collection; +import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; @@ -46,6 +49,7 @@ import org.alfresco.model.ContentModel; import org.alfresco.repo.content.MimetypeMap; import org.alfresco.repo.content.transform.ContentTransformer; import org.alfresco.repo.search.IndexerException; +import org.alfresco.repo.search.impl.lucene.analysis.DateTimeAnalyser; import org.alfresco.repo.search.impl.lucene.fts.FTSIndexerAware; import org.alfresco.repo.search.impl.lucene.fts.FullTextSearchIndexer; import org.alfresco.repo.tenant.TenantService; @@ -69,10 +73,12 @@ import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter; import org.alfresco.service.cmr.repository.datatype.TypeConversionException; import org.alfresco.service.namespace.QName; +import org.alfresco.util.CachingDateFormat; import org.alfresco.util.EqualsHelper; import org.alfresco.util.ISO9075; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.lucene.analysis.Token; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; import org.apache.lucene.index.IndexReader; @@ -93,7 +99,7 @@ import org.apache.lucene.search.BooleanClause.Occur; */ public class ADMLuceneIndexerImpl extends AbstractLuceneIndexerImpl implements ADMLuceneIndexer { - static Log s_logger = LogFactory.getLog(ADMLuceneIndexerImpl.class); + static Log s_logger = LogFactory.getLog(ADMLuceneIndexerImpl.class); /** * The node service we use to get information about nodes @@ -133,16 +139,6 @@ public class ADMLuceneIndexerImpl extends AbstractLuceneIndexerImpl imp super(); } - /** - * IOC setting of the dictionary service - * - * @param dictionaryService - */ - public void setDictionaryService(DictionaryService dictionaryService) - { - super.setDictionaryService(dictionaryService); - } - /** * IOC setting of the node service * @@ -722,6 +718,7 @@ public class ADMLuceneIndexerImpl extends AbstractLuceneIndexerImpl imp boolean isContent = false; boolean isMultiLingual = false; boolean isText = false; + boolean isDateTime = false; PropertyDefinition propertyDef = getDictionaryService().getProperty(propertyName); if (propertyDef != null) @@ -733,6 +730,12 @@ public class ADMLuceneIndexerImpl extends AbstractLuceneIndexerImpl imp isContent = propertyDef.getDataType().getName().equals(DataTypeDefinition.CONTENT); isMultiLingual = propertyDef.getDataType().getName().equals(DataTypeDefinition.MLTEXT); isText = propertyDef.getDataType().getName().equals(DataTypeDefinition.TEXT); + if (propertyDef.getDataType().getName().equals(DataTypeDefinition.DATETIME)) + { + DataTypeDefinition dataType = propertyDef.getDataType(); + String analyserClassName = dataType.getAnalyserClassName(); + isDateTime = analyserClassName.equals(DateTimeAnalyser.class.getCanonicalName()); + } } if (value == null) { @@ -843,10 +846,8 @@ public class ADMLuceneIndexerImpl extends AbstractLuceneIndexerImpl imp // Check that the reader is a view onto something concrete if (!reader.exists()) { - throw new ContentIOException( - "The transformation did not write any content, yet: \n" + - " transformer: " + transformer + "\n" + - " temp writer: " + writer); + throw new ContentIOException("The transformation did not write any content, yet: \n" + + " transformer: " + transformer + "\n" + " temp writer: " + writer); } } catch (ContentIOException e) @@ -977,6 +978,24 @@ public class ADMLuceneIndexerImpl extends AbstractLuceneIndexerImpl imp doc.add(new Field(attributeName, strValue, fieldStore, fieldIndex, Field.TermVector.NO)); } } + else if (isDateTime) + { + doc.add(new Field(attributeName, strValue, fieldStore, fieldIndex, Field.TermVector.NO)); + + SimpleDateFormat df = CachingDateFormat.getDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", true); + + Date date; + try + { + date = df.parse(strValue); + doc.add(new Field(attributeName + ".sort", df.format(date), Field.Store.NO, Field.Index.NO_NORMS, Field.TermVector.NO)); + } + catch (ParseException e) + { + // ignore for ordering + } + + } else { doc.add(new Field(attributeName, strValue, fieldStore, fieldIndex, Field.TermVector.NO)); diff --git a/source/java/org/alfresco/repo/search/impl/lucene/ADMLuceneSearcherImpl.java b/source/java/org/alfresco/repo/search/impl/lucene/ADMLuceneSearcherImpl.java index 55f364686b..ec2da9a7e6 100644 --- a/source/java/org/alfresco/repo/search/impl/lucene/ADMLuceneSearcherImpl.java +++ b/source/java/org/alfresco/repo/search/impl/lucene/ADMLuceneSearcherImpl.java @@ -41,7 +41,10 @@ import org.alfresco.repo.search.SearcherException; import org.alfresco.repo.search.impl.NodeSearcher; import org.alfresco.repo.search.impl.lucene.QueryParser.Operator; import org.alfresco.repo.tenant.TenantService; +import org.alfresco.repo.search.impl.lucene.analysis.DateTimeAnalyser; +import org.alfresco.service.cmr.dictionary.DataTypeDefinition; import org.alfresco.service.cmr.dictionary.DictionaryService; +import org.alfresco.service.cmr.dictionary.PropertyDefinition; import org.alfresco.service.cmr.repository.InvalidNodeRefException; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; @@ -80,7 +83,7 @@ import com.werken.saxpath.XPathReader; */ public class ADMLuceneSearcherImpl extends AbstractLuceneBase implements LuceneSearcher { - static Log s_logger = LogFactory.getLog(ADMLuceneSearcherImpl.class); + static Log s_logger = LogFactory.getLog(ADMLuceneSearcherImpl.class); /** * Default field name @@ -93,8 +96,6 @@ public class ADMLuceneSearcherImpl extends AbstractLuceneBase implements LuceneS private TenantService tenantService; - private DictionaryService dictionaryService; - private QueryRegisterComponent queryRegister; private LuceneIndexer indexer; @@ -161,10 +162,6 @@ public class ADMLuceneSearcherImpl extends AbstractLuceneBase implements LuceneS this.tenantService = tenantService; } - public void setDictionaryService(DictionaryService dictionaryService) - { - this.dictionaryService = dictionaryService; - } /** * Set the query register @@ -249,10 +246,10 @@ public class ADMLuceneSearcherImpl extends AbstractLuceneBase implements LuceneS Query query = LuceneQueryParser.parse( parameterisedQueryString, DEFAULT_FIELD, new LuceneAnalyser( - dictionaryService, + getDictionaryService(), searchParameters.getMlAnalaysisMode() == null ? getLuceneConfig().getDefaultMLSearchAnalysisMode() : searchParameters.getMlAnalaysisMode()), namespacePrefixResolver, - dictionaryService, + getDictionaryService(), tenantService, defaultOperator, searchParameters, @@ -279,9 +276,26 @@ public class ADMLuceneSearcherImpl extends AbstractLuceneBase implements LuceneS switch (sd.getSortType()) { case FIELD: - if (fieldHasTerm(searcher.getReader(), sd.getField())) + String field = sd.getField(); + if(field.startsWith("@")) { - fields[index++] = new SortField(sd.getField(), !sd.isAscending()); + field = expandAttributeFieldName(field); + PropertyDefinition propertyDef = getDictionaryService().getProperty(QName.createQName(field.substring(1))); + + if (propertyDef.getDataType().getName().equals(DataTypeDefinition.DATETIME)) + { + DataTypeDefinition dataType = propertyDef.getDataType(); + String analyserClassName = dataType.getAnalyserClassName(); + if(analyserClassName.equals(DateTimeAnalyser.class.getCanonicalName())) + { + field = field + ".sort"; + } + } + + } + if (fieldHasTerm(searcher.getReader(), field)) + { + fields[index++] = new SortField(field, !sd.isAscending()); } else { @@ -329,7 +343,7 @@ public class ADMLuceneSearcherImpl extends AbstractLuceneBase implements LuceneS XPathReader reader = new XPathReader(); LuceneXPathHandler handler = new LuceneXPathHandler(); handler.setNamespacePrefixResolver(namespacePrefixResolver); - handler.setDictionaryService(dictionaryService); + handler.setDictionaryService(getDictionaryService()); // TODO: Handler should have the query parameters to use in // building its lucene query // At the moment xpath style parameters in the PATH @@ -569,7 +583,7 @@ public class ADMLuceneSearcherImpl extends AbstractLuceneBase implements LuceneS public List selectNodes(NodeRef contextNodeRef, String xpath, QueryParameterDefinition[] parameters, NamespacePrefixResolver namespacePrefixResolver, boolean followAllParentLinks, String language) throws InvalidNodeRefException, XPathException { - NodeSearcher nodeSearcher = new NodeSearcher(nodeService, dictionaryService, this); + NodeSearcher nodeSearcher = new NodeSearcher(nodeService, getDictionaryService(), this); contextNodeRef = tenantService.getName(contextNodeRef); @@ -582,7 +596,7 @@ public class ADMLuceneSearcherImpl extends AbstractLuceneBase implements LuceneS public List selectProperties(NodeRef contextNodeRef, String xpath, QueryParameterDefinition[] parameters, NamespacePrefixResolver namespacePrefixResolver, boolean followAllParentLinks, String language) throws InvalidNodeRefException, XPathException { - NodeSearcher nodeSearcher = new NodeSearcher(nodeService, dictionaryService, this); + NodeSearcher nodeSearcher = new NodeSearcher(nodeService, getDictionaryService(), this); return nodeSearcher.selectProperties(contextNodeRef, xpath, parameters, namespacePrefixResolver, followAllParentLinks, language); } @@ -715,4 +729,25 @@ public class ADMLuceneSearcherImpl extends AbstractLuceneBase implements LuceneS { return selectProperties(contextNodeRef, xpath, parameters, namespacePrefixResolver, followAllParentLinks, SearchService.LANGUAGE_XPATH); } + + private String expandAttributeFieldName(String field) + { + String fieldName = 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 + fieldName = "@{" + namespacePrefixResolver.getNamespaceURI("") + "}" + field.substring(1); + } + else + { + // find the prefix + fieldName = "@{" + namespacePrefixResolver.getNamespaceURI(field.substring(1, colonPosition)) + "}" + field.substring(colonPosition + 1); + } + } + return fieldName; + } } diff --git a/source/java/org/alfresco/repo/search/impl/lucene/ADMLuceneTest.java b/source/java/org/alfresco/repo/search/impl/lucene/ADMLuceneTest.java index 397189cd85..2d984fd1da 100644 --- a/source/java/org/alfresco/repo/search/impl/lucene/ADMLuceneTest.java +++ b/source/java/org/alfresco/repo/search/impl/lucene/ADMLuceneTest.java @@ -15,11 +15,11 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * As a special exception to the terms and conditions of version 2.0 of - * the GPL, you may redistribute this Program in connection with Free/Libre - * and Open Source Software ("FLOSS") applications as described in Alfresco's - * FLOSS exception. You should have recieved a copy of the text describing - * the FLOSS exception, and it is also available here: + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: * http://www.alfresco.com/legal/licensing */ package org.alfresco.repo.search.impl.lucene; @@ -31,6 +31,7 @@ import java.io.InputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; +import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; @@ -67,6 +68,7 @@ import org.alfresco.repo.security.authentication.AuthenticationComponent; import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.tenant.TenantService; import org.alfresco.repo.transaction.RetryingTransactionHelper; +import org.alfresco.repo.transaction.TransactionResourceInterceptor; import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback; import org.alfresco.service.ServiceRegistry; import org.alfresco.service.cmr.dictionary.DataTypeDefinition; @@ -201,7 +203,7 @@ public class ADMLuceneTest extends TestCase private Date testDate; /** - * + * */ public ADMLuceneTest() { @@ -398,7 +400,7 @@ public class ADMLuceneTest extends TestCase writer.putContent("The quick brown fox jumped over the lazy dog and ate the Alfresco Tutorial, in pdf format, along with the following stop words; a an and are" + " as at be but by for if in into is it no not of on or such that the their then there these they this to was will with: " + " and random charcters \u00E0\u00EA\u00EE\u00F0\u00F1\u00F6\u00FB\u00FF"); - //System.out.println("Size is " + writer.getSize()); + // System.out.println("Size is " + writer.getSize()); nodeService.addChild(rootNodeRef, n8, ContentModel.ASSOC_CHILDREN, QName.createQName("{namespace}eight-0")); nodeService.addChild(n1, n8, ASSOC_TYPE_QNAME, QName.createQName("{namespace}eight-1")); @@ -1191,6 +1193,7 @@ public class ADMLuceneTest extends TestCase { public Object execute() throws Throwable { + SessionSizeResourceManager.setDisableInTransaction(); for (int i = 0; i < 20; i++) { HashSet refs = new HashSet(); @@ -1575,6 +1578,47 @@ public class ADMLuceneTest extends TestCase date = currentBun; } results.close(); + + SearchParameters sp_7 = new SearchParameters(); + sp_7.addStore(rootNodeRef.getStoreRef()); + sp_7.setLanguage(SearchService.LANGUAGE_LUCENE); + sp_7.setQuery("PATH:\"//.\""); + sp_7.addSort("@" + ContentModel.PROP_MODIFIED, true); + results = searcher.query(sp_7); + + date = null; + for (ResultSetRow row : results) + { + Date currentBun = DefaultTypeConverter.INSTANCE.convert(Date.class, nodeService.getProperty(row.getNodeRef(), ContentModel.PROP_MODIFIED)); + // System.out.println(currentBun); + if (date != null) + { + assertTrue(date.compareTo(currentBun) <= 0); + } + date = currentBun; + } + results.close(); + + SearchParameters sp_8 = new SearchParameters(); + sp_8.addStore(rootNodeRef.getStoreRef()); + sp_8.setLanguage(SearchService.LANGUAGE_LUCENE); + sp_8.setQuery("PATH:\"//.\""); + sp_8.addSort("@" + ContentModel.PROP_MODIFIED, false); + results = searcher.query(sp_8); + + date = null; + for (ResultSetRow row : results) + { + Date currentBun = DefaultTypeConverter.INSTANCE.convert(Date.class, nodeService.getProperty(row.getNodeRef(), ContentModel.PROP_MODIFIED)); + // System.out.println(currentBun); + if ((date != null) && (currentBun != null)) + { + assertTrue(date.compareTo(currentBun) >= 0); + } + date = currentBun; + } + results.close(); + // sort by double @@ -2481,23 +2525,25 @@ public class ADMLuceneTest extends TestCase results.close(); // Dates - + PropertyDefinition propertyDef = dictionaryService.getProperty(QName.createQName(TEST_NAMESPACE, "datetime-ista")); DataTypeDefinition dataType = propertyDef.getDataType(); String analyserClassName = dataType.getAnalyserClassName(); boolean usesDateTimeAnalyser = analyserClassName.equals(DateTimeAnalyser.class.getCanonicalName()); - + Date date = new Date(); - String sDate = CachingDateFormat.getDateFormat().format(date); + SimpleDateFormat df = CachingDateFormat.getDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", true); + String sDate = df.format(date); results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" + escapeQName(QName.createQName(TEST_NAMESPACE, "date-ista")) + ":\"" + sDate + "\"", null, null); assertEquals(1, results.length()); results.close(); results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" + escapeQName(QName.createQName(TEST_NAMESPACE, "datetime-ista")) + ":\"" + sDate + "\"", null, null); - assertEquals(usesDateTimeAnalyser ? 0 : 1 , results.length()); + assertEquals(usesDateTimeAnalyser ? 0 : 1, results.length()); results.close(); - - sDate = CachingDateFormat.getDateFormat().format(testDate); + + sDate = df.format(testDate); + results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" + escapeQName(QName.createQName(TEST_NAMESPACE, "date-ista")) + ":\"" + sDate + "\"", null, null); assertEquals(1, results.length()); results.close(); @@ -2505,7 +2551,63 @@ public class ADMLuceneTest extends TestCase results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" + escapeQName(QName.createQName(TEST_NAMESPACE, "datetime-ista")) + ":\"" + sDate + "\"", null, null); assertEquals(1, results.length()); results.close(); - + + // Date ranges + // Test date collapses but date time does not + + sDate = df.format(date); + results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" + escapeQName(QName.createQName(TEST_NAMESPACE, "date-ista")) + ":[" + sDate + " TO " + sDate + "]", + null, null); + assertEquals(1, results.length()); + results.close(); + + sDate = CachingDateFormat.getDateFormat().format(date); + results = searcher.query(rootNodeRef.getStoreRef(), "lucene", + "\\@" + escapeQName(QName.createQName(TEST_NAMESPACE, "datetime-ista")) + ":[" + sDate + " TO " + sDate + "]", null, null); + assertEquals(usesDateTimeAnalyser ? 0 : 1, results.length(), results.length()); + results.close(); + + if (usesDateTimeAnalyser) + { + sDate = df.format(testDate); + // System.out.println("SD = " + sDate); + + for (long i : new long[] { 333, 20000, 20 * 60 * 1000, 8 * 60 * 60 * 1000, 10 * 24 * 60 * 60 * 1000, 4 * 30 * 24 * 60 * 60 * 1000, 10 * 12 * 30 * 24 * 60 * 60 * 1000 }) + { + String startDate = df.format(new Date(testDate.getTime() - i)); + // System.out.println("\tStart = " + startDate); + + + String endDate = df.format(new Date(testDate.getTime() + i)); + // System.out.println("\tEnd = " + endDate); + + results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" + + escapeQName(QName.createQName(TEST_NAMESPACE, "datetime-ista")) + ":[" + startDate + " TO " + endDate + "]", null, null); + assertEquals(1, results.length()); + results.close(); + + results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" + + escapeQName(QName.createQName(TEST_NAMESPACE, "datetime-ista")) + ":[" + sDate + " TO " + endDate + "]", null, null); + assertEquals(1, results.length()); + results.close(); + + results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" + + escapeQName(QName.createQName(TEST_NAMESPACE, "datetime-ista")) + ":[" + startDate + " TO " + sDate + "]", null, null); + assertEquals(1, results.length()); + results.close(); + + results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" + + escapeQName(QName.createQName(TEST_NAMESPACE, "datetime-ista")) + ":{" + sDate + " TO " + endDate + "}", null, null); + assertEquals(0, results.length()); + results.close(); + + results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" + + escapeQName(QName.createQName(TEST_NAMESPACE, "datetime-ista")) + ":{" + startDate + " TO " + sDate + "}", null, null); + assertEquals(0, results.length()); + results.close(); + } + } + results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "\\@" + escapeQName(QName.createQName(TEST_NAMESPACE, "boolean-ista")) + ":\"true\"", null, null); assertEquals(1, results.length()); results.close(); @@ -2549,48 +2651,59 @@ public class ADMLuceneTest extends TestCase results.close(); // proximity searches - + results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "TEXT:\"Tutorial Alfresco\"~0", null, null); assertEquals(0, results.length()); results.close(); - + results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "TEXT:\"Tutorial Alfresco\"~1", null, null); assertEquals(0, results.length()); results.close(); - + results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "TEXT:\"Tutorial Alfresco\"~2", null, null); assertEquals(1, results.length()); results.close(); - + results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "TEXT:\"Tutorial Alfresco\"~3", null, null); assertEquals(1, results.length()); results.close(); - - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "@" + LuceneQueryParser.escape(ContentModel.PROP_DESCRIPTION.toString())+":\"Alfresco Tutorial\"", null, null); + + results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "@" + LuceneQueryParser.escape(ContentModel.PROP_DESCRIPTION.toString()) + ":\"Alfresco Tutorial\"", null, + null); + assertEquals(1, results.length()); results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "@" + LuceneQueryParser.escape(ContentModel.PROP_DESCRIPTION.toString())+":\"Tutorial Alfresco\"", null, null); + + results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "@" + LuceneQueryParser.escape(ContentModel.PROP_DESCRIPTION.toString()) + ":\"Tutorial Alfresco\"", null, + null); + assertEquals(0, results.length()); results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "@" + LuceneQueryParser.escape(ContentModel.PROP_DESCRIPTION.toString())+":\"Tutorial Alfresco\"~0", null, null); + + results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "@" + LuceneQueryParser.escape(ContentModel.PROP_DESCRIPTION.toString()) + ":\"Tutorial Alfresco\"~0", null, + null); + assertEquals(0, results.length()); results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "@" + LuceneQueryParser.escape(ContentModel.PROP_DESCRIPTION.toString())+":\"Tutorial Alfresco\"~1", null, null); + + results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "@" + LuceneQueryParser.escape(ContentModel.PROP_DESCRIPTION.toString()) + ":\"Tutorial Alfresco\"~1", null, + null); + assertEquals(0, results.length()); results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "@" + LuceneQueryParser.escape(ContentModel.PROP_DESCRIPTION.toString())+":\"Tutorial Alfresco\"~2", null, null); + + results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "@" + LuceneQueryParser.escape(ContentModel.PROP_DESCRIPTION.toString()) + ":\"Tutorial Alfresco\"~2", null, + null); + assertEquals(1, results.length()); results.close(); - - results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "@" + LuceneQueryParser.escape(ContentModel.PROP_DESCRIPTION.toString())+":\"Tutorial Alfresco\"~3", null, null); + + results = searcher.query(rootNodeRef.getStoreRef(), "lucene", "@" + LuceneQueryParser.escape(ContentModel.PROP_DESCRIPTION.toString()) + ":\"Tutorial Alfresco\"~3", null, + null); + assertEquals(1, results.length()); results.close(); - + // multi ml text QName multimlQName = QName.createQName(TEST_NAMESPACE, "mltext-many-ista"); @@ -3221,7 +3334,7 @@ public class ADMLuceneTest extends TestCase sp = new SearchParameters(); sp.addStore(rootNodeRef.getStoreRef()); sp.setLanguage("lucene"); - sp.setQuery("@" + LuceneQueryParser.escape(ContentModel.PROP_DESCRIPTION.toString()) +":\"alfres??\""); + sp.setQuery("@" + LuceneQueryParser.escape(ContentModel.PROP_DESCRIPTION.toString()) + ":\"alfres??\""); results = searcher.query(sp); assertEquals(1, results.length()); results.close(); @@ -5425,7 +5538,7 @@ public class ADMLuceneTest extends TestCase { /** - * + * */ private static final long serialVersionUID = -6729690518573349055L; diff --git a/source/java/org/alfresco/repo/search/impl/lucene/AVMLuceneIndexerImpl.java b/source/java/org/alfresco/repo/search/impl/lucene/AVMLuceneIndexerImpl.java index 0d92230ba5..5b68e53fbe 100644 --- a/source/java/org/alfresco/repo/search/impl/lucene/AVMLuceneIndexerImpl.java +++ b/source/java/org/alfresco/repo/search/impl/lucene/AVMLuceneIndexerImpl.java @@ -31,6 +31,8 @@ import java.io.Reader; import java.io.Serializable; import java.io.StringReader; import java.io.UnsupportedEncodingException; +import java.text.ParseException; +import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; @@ -52,6 +54,7 @@ import org.alfresco.repo.content.transform.ContentTransformer; import org.alfresco.repo.domain.PropertyValue; import org.alfresco.repo.search.IndexMode; import org.alfresco.repo.search.Indexer; +import org.alfresco.repo.search.impl.lucene.analysis.DateTimeAnalyser; import org.alfresco.repo.search.impl.lucene.fts.FTSIndexerAware; import org.alfresco.repo.search.impl.lucene.fts.FullTextSearchIndexer; import org.alfresco.repo.transaction.AlfrescoTransactionSupport; @@ -74,6 +77,7 @@ import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter; import org.alfresco.service.cmr.repository.datatype.TypeConversionException; import org.alfresco.service.namespace.QName; +import org.alfresco.util.CachingDateFormat; import org.alfresco.util.EqualsHelper; import org.alfresco.util.GUID; import org.alfresco.util.ISO9075; @@ -104,7 +108,7 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl impl private static String SNAP_SHOT_ID = "SnapShot"; - static Log s_logger = LogFactory.getLog(AVMLuceneIndexerImpl.class); + static Log s_logger = LogFactory.getLog(AVMLuceneIndexerImpl.class); private AVMService avmService; @@ -649,6 +653,7 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl impl boolean isContent = false; boolean isMultiLingual = false; boolean isText = false; + boolean isDateTime = false; PropertyDefinition propertyDef = getDictionaryService().getProperty(propertyName); if (propertyDef != null) @@ -660,6 +665,12 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl impl isContent = propertyDef.getDataType().getName().equals(DataTypeDefinition.CONTENT); isMultiLingual = propertyDef.getDataType().getName().equals(DataTypeDefinition.MLTEXT); isText = propertyDef.getDataType().getName().equals(DataTypeDefinition.TEXT); + if (propertyDef.getDataType().getName().equals(DataTypeDefinition.DATETIME)) + { + DataTypeDefinition dataType = propertyDef.getDataType(); + String analyserClassName = dataType.getAnalyserClassName(); + isDateTime = analyserClassName.equals(DateTimeAnalyser.class.getCanonicalName()); + } } if (value == null) { @@ -896,6 +907,24 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl impl doc.add(new Field(attributeName, strValue, fieldStore, fieldIndex, Field.TermVector.NO)); } } + else if (isDateTime) + { + + doc.add(new Field(attributeName, strValue, fieldStore, fieldIndex, Field.TermVector.NO)); + + SimpleDateFormat df = CachingDateFormat.getDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", true); + + Date date; + try + { + date = df.parse(strValue); + doc.add(new Field(attributeName + ".sort", df.format(date), Field.Store.NO, Field.Index.NO_NORMS, Field.TermVector.NO)); + } + catch (ParseException e) + { + // ignore for ordering + } + } else { doc.add(new Field(attributeName, strValue, fieldStore, fieldIndex, Field.TermVector.NO)); @@ -1546,12 +1575,11 @@ public class AVMLuceneIndexerImpl extends AbstractLuceneIndexerImpl impl } } - public boolean hasIndexBeenCreated(String store) { return hasIndexBeenCreatedimpl(store, IndexChannel.MAIN) || hasIndexBeenCreatedimpl(store, IndexChannel.DELTA); } - + public boolean hasIndexBeenCreatedimpl(String store, IndexChannel channel) { IndexReader reader = null; 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 792fcbe577..6e9462db95 100644 --- a/source/java/org/alfresco/repo/search/impl/lucene/LuceneQueryParser.java +++ b/source/java/org/alfresco/repo/search/impl/lucene/LuceneQueryParser.java @@ -26,10 +26,13 @@ package org.alfresco.repo.search.impl.lucene; import java.io.IOException; import java.io.StringReader; +import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Calendar; import java.util.Collection; import java.util.Collections; import java.util.Comparator; +import java.util.Date; import java.util.HashSet; import java.util.Iterator; import java.util.List; @@ -40,6 +43,7 @@ import java.util.Vector; import org.alfresco.i18n.I18NUtil; import org.alfresco.repo.search.MLAnalysisMode; import org.alfresco.repo.search.SearcherException; +import org.alfresco.repo.search.impl.lucene.analysis.DateTimeAnalyser; import org.alfresco.repo.search.impl.lucene.analysis.MLTokenDuplicator; import org.alfresco.repo.search.impl.lucene.analysis.VerbatimAnalyser; import org.alfresco.repo.search.impl.lucene.query.PathQuery; @@ -54,6 +58,7 @@ import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.cmr.search.SearchParameters; import org.alfresco.service.namespace.NamespacePrefixResolver; import org.alfresco.service.namespace.QName; +import org.alfresco.util.CachingDateFormat; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.lucene.analysis.Analyzer; @@ -77,7 +82,7 @@ import com.werken.saxpath.XPathReader; public class LuceneQueryParser extends QueryParser { - private static Log s_logger = LogFactory.getLog(LuceneQueryParser.class); + private static Log s_logger = LogFactory.getLog(LuceneQueryParser.class); private NamespacePrefixResolver namespacePrefixResolver; @@ -1120,6 +1125,52 @@ public class LuceneQueryParser extends QueryParser if (field.startsWith("@")) { String fieldName = expandAttributeFieldName(field); + + QName propertyQName = QName.createQName(fieldName.substring(1)); + PropertyDefinition propertyDef = dictionaryService.getProperty(propertyQName); + if (propertyDef != null) + { + if (propertyDef.getDataType().getName().equals(DataTypeDefinition.DATETIME)) + { + DataTypeDefinition dataType = propertyDef.getDataType(); + String analyserClassName = dataType.getAnalyserClassName(); + boolean usesDateTimeAnalyser = analyserClassName.equals(DateTimeAnalyser.class.getCanonicalName()); + // Expand query for internal date time format + + if (usesDateTimeAnalyser) + { + Calendar start = Calendar.getInstance(); + Calendar end = Calendar.getInstance(); + SimpleDateFormat df = CachingDateFormat.getDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", true); + try + { + Date date = df.parse(part1); + start.setTime(date); + } + catch (java.text.ParseException e) + { + return new TermQuery(new Term("NO_TOKENS", "__")); + } + try + { + Date date = df.parse(part2); + end.setTime(date); + } + catch (java.text.ParseException e) + { + return new TermQuery(new Term("NO_TOKENS", "__")); + } + + // Build a composite query for all the bits + return buildDateTimeRange(field, start, end, inclusive); + } + else + { + return new RangeQuery(new Term(fieldName, getToken(fieldName, part1)), new Term(fieldName, getToken(fieldName, part2)), inclusive); + } + } + } + return new RangeQuery(new Term(fieldName, getToken(fieldName, part1)), new Term(fieldName, getToken(fieldName, part2)), inclusive); } @@ -1127,7 +1178,601 @@ public class LuceneQueryParser extends QueryParser { return super.getRangeQuery(field, part1, part2, inclusive); } + } + private Query buildDateTimeRange(String field, Calendar start, Calendar end, boolean inclusive) throws ParseException + { + BooleanQuery query = new BooleanQuery(); + Query part; + if (start.get(Calendar.YEAR) == end.get(Calendar.YEAR)) + { + part = new TermQuery(new Term(field, "YE" + start.get(Calendar.YEAR))); + query.add(part, Occur.MUST); + if (start.get(Calendar.MONTH) == end.get(Calendar.MONTH)) + { + part = new TermQuery(new Term(field, build2SF("MO", start.get(Calendar.MONTH)))); + query.add(part, Occur.MUST); + if (start.get(Calendar.DAY_OF_MONTH) == end.get(Calendar.DAY_OF_MONTH)) + { + part = new TermQuery(new Term(field, build2SF("DA", start.get(Calendar.DAY_OF_MONTH)))); + query.add(part, Occur.MUST); + if (start.get(Calendar.HOUR_OF_DAY) == end.get(Calendar.HOUR_OF_DAY)) + { + part = new TermQuery(new Term(field, build2SF("HO", start.get(Calendar.HOUR_OF_DAY)))); + query.add(part, Occur.MUST); + if (start.get(Calendar.MINUTE) == end.get(Calendar.MINUTE)) + { + part = new TermQuery(new Term(field, build2SF("MI", start.get(Calendar.MINUTE)))); + query.add(part, Occur.MUST); + if (start.get(Calendar.SECOND) == end.get(Calendar.SECOND)) + { + part = new TermQuery(new Term(field, build2SF("SE", start.get(Calendar.SECOND)))); + query.add(part, Occur.MUST); + if (start.get(Calendar.MILLISECOND) == end.get(Calendar.MILLISECOND)) + { + if (inclusive) + { + part = new TermQuery(new Term(field, build3SF("MS", start.get(Calendar.MILLISECOND)))); + query.add(part, Occur.MUST); + } + else + { + return new TermQuery(new Term("NO_TOKENS", "__")); + } + } + else + { + // only ms + part = new RangeQuery(new Term(field, build3SF("MS", start.get(Calendar.MILLISECOND))), new Term(field, build3SF("MS", end + .get(Calendar.MILLISECOND))), inclusive); + query.add(part, Occur.MUST); + } + } + else + { + // s + ms + + BooleanQuery subQuery = new BooleanQuery(); + Query subPart; + + subPart = buildStart(field, start, inclusive, Calendar.SECOND, Calendar.MILLISECOND); + if (subPart != null) + { + subQuery.add(subPart, Occur.SHOULD); + } + + if ((end.get(Calendar.SECOND) - start.get(Calendar.SECOND)) > 1) + { + subPart = new RangeQuery(new Term(field, build2SF("SE", start.get(Calendar.SECOND))), + new Term(field, build2SF("SE", end.get(Calendar.SECOND))), false); + subQuery.add(subPart, Occur.SHOULD); + } + + subPart = buildEnd(field, end, inclusive, Calendar.SECOND, Calendar.MILLISECOND); + if (subPart != null) + { + subQuery.add(subPart, Occur.SHOULD); + } + + if (subQuery.clauses().size() > 0) + { + query.add(subQuery, Occur.MUST); + } + + } + } + else + { + // min + s + ms + + BooleanQuery subQuery = new BooleanQuery(); + Query subPart; + + for (int i : new int[] { Calendar.MILLISECOND, Calendar.SECOND }) + { + subPart = buildStart(field, start, inclusive, Calendar.MINUTE, i); + if (subPart != null) + { + subQuery.add(subPart, Occur.SHOULD); + } + } + + if ((end.get(Calendar.MINUTE) - start.get(Calendar.MINUTE)) > 1) + { + subPart = new RangeQuery(new Term(field, build2SF("MI", start.get(Calendar.MINUTE))), new Term(field, build2SF("MI", end.get(Calendar.MINUTE))), + false); + subQuery.add(subPart, Occur.SHOULD); + } + + for (int i : new int[] { Calendar.SECOND, Calendar.MILLISECOND }) + { + subPart = buildEnd(field, end, inclusive, Calendar.MINUTE, i); + if (subPart != null) + { + subQuery.add(subPart, Occur.SHOULD); + } + } + + if (subQuery.clauses().size() > 0) + { + query.add(subQuery, Occur.MUST); + } + } + } + else + { + // hr + min + s + ms + + BooleanQuery subQuery = new BooleanQuery(); + Query subPart; + + for (int i : new int[] { Calendar.MILLISECOND, Calendar.SECOND, Calendar.MINUTE }) + { + subPart = buildStart(field, start, inclusive, Calendar.HOUR_OF_DAY, i); + if (subPart != null) + { + subQuery.add(subPart, Occur.SHOULD); + } + } + + if ((end.get(Calendar.HOUR_OF_DAY) - start.get(Calendar.HOUR_OF_DAY)) > 1) + { + subPart = new RangeQuery(new Term(field, build2SF("HO", start.get(Calendar.HOUR_OF_DAY))), new Term(field, + build2SF("HO", end.get(Calendar.HOUR_OF_DAY))), false); + subQuery.add(subPart, Occur.SHOULD); + } + + for (int i : new int[] { Calendar.MINUTE, Calendar.SECOND, Calendar.MILLISECOND }) + { + subPart = buildEnd(field, end, inclusive, Calendar.HOUR_OF_DAY, i); + if (subPart != null) + { + subQuery.add(subPart, Occur.SHOULD); + } + } + + if (subQuery.clauses().size() > 0) + { + query.add(subQuery, Occur.MUST); + } + } + } + else + { + // day + hr + min + s + ms + + BooleanQuery subQuery = new BooleanQuery(); + Query subPart; + + for (int i : new int[] { Calendar.MILLISECOND, Calendar.SECOND, Calendar.MINUTE, Calendar.HOUR_OF_DAY }) + { + subPart = buildStart(field, start, inclusive, Calendar.DAY_OF_MONTH, i); + if (subPart != null) + { + subQuery.add(subPart, Occur.SHOULD); + } + } + + if ((end.get(Calendar.DAY_OF_MONTH) - start.get(Calendar.DAY_OF_MONTH)) > 1) + { + subPart = new RangeQuery(new Term(field, build2SF("DA", start.get(Calendar.DAY_OF_MONTH))), + new Term(field, build2SF("DA", end.get(Calendar.DAY_OF_MONTH))), false); + subQuery.add(subPart, Occur.SHOULD); + } + + for (int i : new int[] { Calendar.HOUR_OF_DAY, Calendar.MINUTE, Calendar.SECOND, Calendar.MILLISECOND }) + { + subPart = buildEnd(field, end, inclusive, Calendar.DAY_OF_MONTH, i); + if (subPart != null) + { + subQuery.add(subPart, Occur.SHOULD); + } + } + + if (subQuery.clauses().size() > 0) + { + query.add(subQuery, Occur.MUST); + } + + } + } + else + { + // month + day + hr + min + s + ms + + BooleanQuery subQuery = new BooleanQuery(); + Query subPart; + + for (int i : new int[] { Calendar.MILLISECOND, Calendar.SECOND, Calendar.MINUTE, Calendar.HOUR_OF_DAY, Calendar.DAY_OF_MONTH }) + { + subPart = buildStart(field, start, inclusive, Calendar.MONTH, i); + if (subPart != null) + { + subQuery.add(subPart, Occur.SHOULD); + } + } + + if ((end.get(Calendar.MONTH) - start.get(Calendar.MONTH)) > 1) + { + subPart = new RangeQuery(new Term(field, build2SF("MO", start.get(Calendar.MONTH))), new Term(field, build2SF("MO", end.get(Calendar.MONTH))), false); + subQuery.add(subPart, Occur.SHOULD); + } + + for (int i : new int[] { Calendar.DAY_OF_MONTH, Calendar.HOUR_OF_DAY, Calendar.MINUTE, Calendar.SECOND, Calendar.MILLISECOND }) + { + subPart = buildEnd(field, end, inclusive, Calendar.MONTH, i); + if (subPart != null) + { + subQuery.add(subPart, Occur.SHOULD); + } + } + + if (subQuery.clauses().size() > 0) + { + query.add(subQuery, Occur.MUST); + } + } + } + else + { + // year + month + day + hr + min + s + ms + + BooleanQuery subQuery = new BooleanQuery(); + Query subPart; + + for (int i : new int[] { Calendar.MILLISECOND, Calendar.SECOND, Calendar.MINUTE, Calendar.HOUR_OF_DAY, Calendar.DAY_OF_MONTH, Calendar.MONTH }) + { + subPart = buildStart(field, start, inclusive, Calendar.YEAR, i); + if (subPart != null) + { + subQuery.add(subPart, Occur.SHOULD); + } + } + + if ((end.get(Calendar.YEAR) - start.get(Calendar.YEAR)) > 1) + { + subPart = new RangeQuery(new Term(field, "YE" + start.get(Calendar.YEAR)), new Term(field, "YE" + end.get(Calendar.YEAR)), false); + subQuery.add(subPart, Occur.SHOULD); + } + + for (int i : new int[] { Calendar.MONTH, Calendar.DAY_OF_MONTH, Calendar.HOUR_OF_DAY, Calendar.MINUTE, Calendar.SECOND, Calendar.MILLISECOND }) + { + subPart = buildEnd(field, end, inclusive, Calendar.YEAR, i); + if (subPart != null) + { + subQuery.add(subPart, Occur.SHOULD); + } + } + + if (subQuery.clauses().size() > 0) + { + query.add(subQuery, Occur.MUST); + } + } + return query; + } + + private Query buildStart(String field, Calendar cal, boolean inclusive, int startField, int padField) + { + BooleanQuery range = new BooleanQuery(); + // only ms difference + Query part; + + int ms = cal.get(Calendar.MILLISECOND) + (inclusive ? 0 : 1); + + switch (startField) + { + case Calendar.YEAR: + part = new TermQuery(new Term(field, "YE" + cal.get(Calendar.YEAR))); + range.add(part, Occur.MUST); + case Calendar.MONTH: + if ((cal.get(Calendar.MONTH) == 0) + && (cal.get(Calendar.DAY_OF_MONTH) == 1) && (cal.get(Calendar.HOUR_OF_DAY) == 0) && (cal.get(Calendar.MINUTE) == 0) && (cal.get(Calendar.SECOND) == 0) + && (ms == 0)) + { + if (padField == Calendar.DAY_OF_MONTH) + { + break; + } + else + { + return null; + } + } + else if (padField == Calendar.MONTH) + { + part = new RangeQuery(new Term(field, build2SF("MO", (cal.get(Calendar.MONTH) + 1))), new Term(field, "MO11"), true); + range.add(part, Occur.MUST); + break; + } + else + { + part = new TermQuery(new Term(field, build2SF("MO", cal.get(Calendar.MONTH)))); + range.add(part, Occur.MUST); + } + case Calendar.DAY_OF_MONTH: + if ((cal.get(Calendar.DAY_OF_MONTH) == 1) && (cal.get(Calendar.HOUR_OF_DAY) == 0) && (cal.get(Calendar.MINUTE) == 0) && (cal.get(Calendar.SECOND) == 0) && (ms == 0)) + { + if (padField == Calendar.HOUR_OF_DAY) + { + break; + } + else + { + return null; + } + } + else if (padField == Calendar.DAY_OF_MONTH) + { + part = new RangeQuery(new Term(field, build2SF("DA", (cal.get(Calendar.DAY_OF_MONTH) + 1))), new Term(field, "DA31"), true); + range.add(part, Occur.MUST); + break; + } + else + { + part = new TermQuery(new Term(field, build2SF("DA", cal.get(Calendar.DAY_OF_MONTH)))); + range.add(part, Occur.MUST); + } + case Calendar.HOUR_OF_DAY: + if ((cal.get(Calendar.HOUR_OF_DAY) == 0) && (cal.get(Calendar.MINUTE) == 0) && (cal.get(Calendar.SECOND) == 0) && (ms == 0)) + { + if (padField == Calendar.MINUTE) + { + break; + } + else + { + return null; + } + } + else if (padField == Calendar.HOUR_OF_DAY) + { + part = new RangeQuery(new Term(field, build2SF("HO", (cal.get(Calendar.HOUR_OF_DAY) + 1))), new Term(field, "HO23"), true); + range.add(part, Occur.MUST); + break; + } + else + { + part = new TermQuery(new Term(field, build2SF("HO", cal.get(Calendar.HOUR_OF_DAY)))); + range.add(part, Occur.MUST); + } + case Calendar.MINUTE: + if ((cal.get(Calendar.MINUTE) == 0) && (cal.get(Calendar.SECOND) == 0) && (ms == 0)) + { + if (padField == Calendar.SECOND) + { + break; + } + else + { + return null; + } + } + else if (padField == Calendar.MINUTE) + { + part = new RangeQuery(new Term(field, build2SF("MI", (cal.get(Calendar.MINUTE) + 1))), new Term(field, "MI59"), true); + range.add(part, Occur.MUST); + break; + } + else + { + part = new TermQuery(new Term(field, build2SF("MI", cal.get(Calendar.MINUTE)))); + range.add(part, Occur.MUST); + } + case Calendar.SECOND: + if ((cal.get(Calendar.SECOND) == 0) && (ms == 0)) + { + if (padField == Calendar.MILLISECOND) + { + break; + } + else + { + return null; + } + } + else if (padField == Calendar.SECOND) + { + part = new RangeQuery(new Term(field, build2SF("SE", (cal.get(Calendar.SECOND) + 1))), new Term(field, "SE59"), true); + range.add(part, Occur.MUST); + break; + } + else + { + part = new TermQuery(new Term(field, build2SF("SE", cal.get(Calendar.SECOND)))); + range.add(part, Occur.MUST); + } + default: + if ((ms > 0) && (ms < 999)) + { + part = new RangeQuery(new Term(field, build3SF("MS", ms)), new Term(field, "MS999"), true); + range.add(part, Occur.MUST); + } + else if (ms == 1000) + { + // exclude + range.add(new TermQuery(new Term("NO_TOKENS", "__")), Occur.MUST); + } + } + + if (range.clauses().size() > 0) + { + return range; + } + else + { + return null; + } + } + + private Query buildEnd(String field, Calendar cal, boolean inclusive, int startField, int padField) + { + BooleanQuery range = new BooleanQuery(); + // only ms difference + Query part; + + int ms = cal.get(Calendar.MILLISECOND) - (inclusive ? 0 : 1); + + switch (startField) + { + case Calendar.YEAR: + part = new TermQuery(new Term(field, "YE" + cal.get(Calendar.YEAR))); + range.add(part, Occur.MUST); + case Calendar.MONTH: + if ((cal.get(Calendar.MONTH) == 0) + && (cal.get(Calendar.DAY_OF_MONTH) == 1) && (cal.get(Calendar.HOUR_OF_DAY) == 0) && (cal.get(Calendar.MINUTE) == 0) && (cal.get(Calendar.SECOND) == 0) + && (ms == 0)) + { + if (padField == Calendar.MONTH) + { + return null; + } + } + + if (padField == Calendar.MONTH) + { + part = new RangeQuery(new Term(field, "MO00"), new Term(field, build2SF("MO", (cal.get(Calendar.MONTH) - 1))), true); + range.add(part, Occur.MUST); + break; + } + else + { + part = new TermQuery(new Term(field, build2SF("MO", cal.get(Calendar.MONTH)))); + range.add(part, Occur.MUST); + } + case Calendar.DAY_OF_MONTH: + if ((cal.get(Calendar.DAY_OF_MONTH) == 1) && (cal.get(Calendar.HOUR_OF_DAY) == 0) && (cal.get(Calendar.MINUTE) == 0) && (cal.get(Calendar.SECOND) == 0) + && (ms == 0)) + { + if (padField == Calendar.DAY_OF_MONTH) + { + return null; + } + } + + if (padField == Calendar.DAY_OF_MONTH) + { + part = new RangeQuery(new Term(field, "DA00"), new Term(field, build2SF("DA", (cal.get(Calendar.DAY_OF_MONTH) - 1))), true); + range.add(part, Occur.MUST); + break; + } + else + { + part = new TermQuery(new Term(field, build2SF("DA", cal.get(Calendar.DAY_OF_MONTH)))); + range.add(part, Occur.MUST); + } + case Calendar.HOUR_OF_DAY: + if ((cal.get(Calendar.HOUR_OF_DAY) == 0) && (cal.get(Calendar.MINUTE) == 0) && (cal.get(Calendar.SECOND) == 0) + && (ms == 0)) + { + if (padField == Calendar.HOUR_OF_DAY) + { + return null; + } + } + + if (padField == Calendar.HOUR_OF_DAY) + { + part = new RangeQuery(new Term(field, "HO00"), new Term(field, build2SF("HO", (cal.get(Calendar.HOUR_OF_DAY) - 1))), true); + range.add(part, Occur.MUST); + break; + } + else + { + part = new TermQuery(new Term(field, build2SF("HO", cal.get(Calendar.HOUR_OF_DAY)))); + range.add(part, Occur.MUST); + } + case Calendar.MINUTE: + if ((cal.get(Calendar.MINUTE) == 0) && (cal.get(Calendar.SECOND) == 0) + && (ms == 0)) + { + if (padField == Calendar.MINUTE) + { + return null; + } + } + + if (padField == Calendar.MINUTE) + { + part = new RangeQuery(new Term(field, "MI00"), new Term(field, build2SF("MI", (cal.get(Calendar.MINUTE) - 1))), true); + range.add(part, Occur.MUST); + break; + } + else + { + part = new TermQuery(new Term(field, build2SF("MI", cal.get(Calendar.MINUTE)))); + range.add(part, Occur.MUST); + } + case Calendar.SECOND: + if ((cal.get(Calendar.SECOND) == 0) + && (ms == 0)) + { + if (padField == Calendar.SECOND) + { + return null; + } + } + + if (padField == Calendar.SECOND) + { + part = new RangeQuery(new Term(field, "SE00"), new Term(field, build2SF("SE", (cal.get(Calendar.SECOND) - 1))), true); + range.add(part, Occur.MUST); + break; + } + else + { + part = new TermQuery(new Term(field, build2SF("SE", cal.get(Calendar.SECOND)))); + range.add(part, Occur.MUST); + } + default: + if ((ms >= 0) && (ms < 999)) + { + part = new RangeQuery(new Term(field, "MS000"), new Term(field, build3SF("MS", ms)), true); + range.add(part, Occur.MUST); + } + else if (ms == -1) + { + // exclude + range.add(new TermQuery(new Term("NO_TOKENS", "__")), Occur.MUST); + } + } + + if (range.clauses().size() > 0) + { + return range; + } + else + { + return null; + } + } + + private String build2SF(String prefix, int value) + { + if (value < 10) + { + return prefix + "0" + value; + } + else + { + return prefix + value; + } + } + + private String build3SF(String prefix, int value) + { + if (value < 10) + { + return prefix + "00" + value; + } + else if (value < 100) + { + return prefix + "0" + value; + } + else + { + return prefix + value; + } } private String expandAttributeFieldName(String field) @@ -1558,4 +2203,33 @@ public class LuceneQueryParser extends QueryParser } } + public static void main(String[] args) throws ParseException + { + Query query; + + Calendar start = Calendar.getInstance(); + Calendar end = Calendar.getInstance(); + SimpleDateFormat df = CachingDateFormat.getDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", false); + try + { + Date date = df.parse("2007-10-15T11:21:03.312"); + start.setTime(date); + } + catch (java.text.ParseException e) + { + query = new TermQuery(new Term("NO_TOKENS", "__")); + } + try + { + Date date = df.parse("2007-10-15T11:21:03.645"); + end.setTime(date); + } + catch (java.text.ParseException e) + { + query = new TermQuery(new Term("NO_TOKENS", "__")); + } + LuceneQueryParser lqp = new LuceneQueryParser(null, null); + query = lqp.buildDateTimeRange("TEST", start, end, true); + System.out.println("Query is " + query); + } } diff --git a/source/java/org/alfresco/repo/search/impl/lucene/analysis/AnalysisException.java b/source/java/org/alfresco/repo/search/impl/lucene/analysis/AnalysisException.java index 1c30fd3a28..d0d0d702f5 100644 --- a/source/java/org/alfresco/repo/search/impl/lucene/analysis/AnalysisException.java +++ b/source/java/org/alfresco/repo/search/impl/lucene/analysis/AnalysisException.java @@ -1,3 +1,27 @@ +/* + * Copyright (C) 2005-2007 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * 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 General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" + */ package org.alfresco.repo.search.impl.lucene.analysis; import org.alfresco.error.AlfrescoRuntimeException; diff --git a/source/java/org/alfresco/repo/search/impl/lucene/analysis/DanishSnowballAnalyser.java b/source/java/org/alfresco/repo/search/impl/lucene/analysis/DanishSnowballAnalyser.java index e28a27f606..4c98e17f14 100644 --- a/source/java/org/alfresco/repo/search/impl/lucene/analysis/DanishSnowballAnalyser.java +++ b/source/java/org/alfresco/repo/search/impl/lucene/analysis/DanishSnowballAnalyser.java @@ -1,3 +1,27 @@ +/* + * Copyright (C) 2005-2007 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * 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 General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" + */ package org.alfresco.repo.search.impl.lucene.analysis; import org.apache.lucene.analysis.snowball.SnowballAnalyzer; diff --git a/source/java/org/alfresco/repo/search/impl/lucene/analysis/DateTimeTokenFilter.java b/source/java/org/alfresco/repo/search/impl/lucene/analysis/DateTimeTokenFilter.java index 77ed11443c..f7dbef5a40 100644 --- a/source/java/org/alfresco/repo/search/impl/lucene/analysis/DateTimeTokenFilter.java +++ b/source/java/org/alfresco/repo/search/impl/lucene/analysis/DateTimeTokenFilter.java @@ -28,7 +28,10 @@ import java.io.IOException; import java.io.Reader; import java.text.ParseException; import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; import java.util.Date; +import java.util.Iterator; import org.alfresco.util.CachingDateFormat; import org.apache.lucene.analysis.Token; @@ -41,7 +44,9 @@ import org.apache.lucene.analysis.WhitespaceTokenizer; public class DateTimeTokenFilter extends Tokenizer { Tokenizer baseTokeniser; - + + Iterator tokenIterator = null; + public DateTimeTokenFilter(Reader in) { super(in); @@ -50,10 +55,26 @@ public class DateTimeTokenFilter extends Tokenizer public Token next() throws IOException { - SimpleDateFormat df = CachingDateFormat.getDateFormat(); - SimpleDateFormat dof = CachingDateFormat.getDateFormat(); + if (tokenIterator == null) + { + buildIterator(); + } + if (tokenIterator.hasNext()) + { + return tokenIterator.next(); + } + else + { + return null; + } + } + + public void buildIterator() throws IOException + { + SimpleDateFormat df = CachingDateFormat.getDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", true); Token candidate; - while((candidate = baseTokeniser.next()) != null) + ArrayList tokens = new ArrayList(); + while ((candidate = baseTokeniser.next()) != null) { Date date; try @@ -62,13 +83,99 @@ public class DateTimeTokenFilter extends Tokenizer } catch (ParseException e) { - continue; + continue; } - String valueString = dof.format(date); - Token integerToken = new Token(valueString, candidate.startOffset(), candidate.startOffset(), - candidate.type()); - return integerToken; + + Calendar cal = Calendar.getInstance(); + cal.setTime(date); + + Token token; + + // four digits + token = new Token("YE" + cal.get(Calendar.YEAR), candidate.startOffset(), candidate.startOffset(), candidate.type()); + tokens.add(token); + + // 2 digits + int month = cal.get(Calendar.MONTH); + if (month < 10) + { + token = new Token("MO0" + month, candidate.startOffset(), candidate.startOffset(), candidate.type()); + tokens.add(token); + } + else + { + token = new Token("MO" + month, candidate.startOffset(), candidate.startOffset(), candidate.type()); + tokens.add(token); + } + + int day = cal.get(Calendar.DAY_OF_MONTH); + if (day < 10) + { + token = new Token("DA0" + day, candidate.startOffset(), candidate.startOffset(), candidate.type()); + tokens.add(token); + } + else + { + token = new Token("DA" + day, candidate.startOffset(), candidate.startOffset(), candidate.type()); + tokens.add(token); + } + + int hour = cal.get(Calendar.HOUR_OF_DAY); + if (hour < 10) + { + token = new Token("HO0" + hour, candidate.startOffset(), candidate.startOffset(), candidate.type()); + tokens.add(token); + } + else + { + token = new Token("HO" + hour, candidate.startOffset(), candidate.startOffset(), candidate.type()); + tokens.add(token); + } + + int minute = cal.get(Calendar.MINUTE); + if (minute < 10) + { + token = new Token("MI0" + minute, candidate.startOffset(), candidate.startOffset(), candidate.type()); + tokens.add(token); + } + else + { + token = new Token("MI" + minute, candidate.startOffset(), candidate.startOffset(), candidate.type()); + tokens.add(token); + } + + int second = cal.get(Calendar.SECOND); + if (second < 10) + { + token = new Token("SE0" + second, candidate.startOffset(), candidate.startOffset(), candidate.type()); + tokens.add(token); + } + else + { + token = new Token("SE" + second, candidate.startOffset(), candidate.startOffset(), candidate.type()); + tokens.add(token); + } + + int millis = cal.get(Calendar.MILLISECOND); + if (millis < 10) + { + token = new Token("MS00" + millis, candidate.startOffset(), candidate.startOffset(), candidate.type()); + tokens.add(token); + } + else if (millis < 100) + { + token = new Token("MS0" + millis, candidate.startOffset(), candidate.startOffset(), candidate.type()); + tokens.add(token); + } + else + { + token = new Token("MS" + millis, candidate.startOffset(), candidate.startOffset(), candidate.type()); + tokens.add(token); + } + + break; } - return null; + + tokenIterator = tokens.iterator(); } } \ No newline at end of file diff --git a/source/java/org/alfresco/repo/search/impl/lucene/analysis/DutchSnowballAnalyser.java b/source/java/org/alfresco/repo/search/impl/lucene/analysis/DutchSnowballAnalyser.java index 63a66a0fe0..eb23606b58 100644 --- a/source/java/org/alfresco/repo/search/impl/lucene/analysis/DutchSnowballAnalyser.java +++ b/source/java/org/alfresco/repo/search/impl/lucene/analysis/DutchSnowballAnalyser.java @@ -1,3 +1,27 @@ +/* + * Copyright (C) 2005-2007 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * 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 General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" + */ package org.alfresco.repo.search.impl.lucene.analysis; import org.apache.lucene.analysis.snowball.SnowballAnalyzer; @@ -7,6 +31,6 @@ public class DutchSnowballAnalyser extends SnowballAnalyzer public DutchSnowballAnalyser() { - super("Danish"); + super("Dutch"); } } diff --git a/source/java/org/alfresco/repo/search/impl/lucene/analysis/EnglishSnowballAnalyser.java b/source/java/org/alfresco/repo/search/impl/lucene/analysis/EnglishSnowballAnalyser.java index 8b0b130436..8d5733aa2a 100644 --- a/source/java/org/alfresco/repo/search/impl/lucene/analysis/EnglishSnowballAnalyser.java +++ b/source/java/org/alfresco/repo/search/impl/lucene/analysis/EnglishSnowballAnalyser.java @@ -1,3 +1,27 @@ +/* + * Copyright (C) 2005-2007 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * 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 General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" + */ package org.alfresco.repo.search.impl.lucene.analysis; import org.apache.lucene.analysis.snowball.SnowballAnalyzer; @@ -7,6 +31,6 @@ public class EnglishSnowballAnalyser extends SnowballAnalyzer public EnglishSnowballAnalyser() { - super("Danish"); + super("English"); } } diff --git a/source/java/org/alfresco/repo/search/impl/lucene/analysis/FinnishSnowballAnalyser.java b/source/java/org/alfresco/repo/search/impl/lucene/analysis/FinnishSnowballAnalyser.java new file mode 100644 index 0000000000..eec5f5e598 --- /dev/null +++ b/source/java/org/alfresco/repo/search/impl/lucene/analysis/FinnishSnowballAnalyser.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2005-2007 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * 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 General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" + */ +package org.alfresco.repo.search.impl.lucene.analysis; + +import org.apache.lucene.analysis.snowball.SnowballAnalyzer; + +public class FinnishSnowballAnalyser extends SnowballAnalyzer +{ + + public FinnishSnowballAnalyser() + { + super("Finnish"); + } +} diff --git a/source/java/org/alfresco/repo/search/impl/lucene/analysis/FrenchSnowballAnalyser.java b/source/java/org/alfresco/repo/search/impl/lucene/analysis/FrenchSnowballAnalyser.java index 654b57f83a..59e82f1c60 100644 --- a/source/java/org/alfresco/repo/search/impl/lucene/analysis/FrenchSnowballAnalyser.java +++ b/source/java/org/alfresco/repo/search/impl/lucene/analysis/FrenchSnowballAnalyser.java @@ -1,3 +1,27 @@ +/* + * Copyright (C) 2005-2007 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * 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 General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" + */ package org.alfresco.repo.search.impl.lucene.analysis; import org.apache.lucene.analysis.snowball.SnowballAnalyzer; @@ -7,6 +31,6 @@ public class FrenchSnowballAnalyser extends SnowballAnalyzer public FrenchSnowballAnalyser() { - super("Danish"); + super("French"); } } diff --git a/source/java/org/alfresco/repo/search/impl/lucene/analysis/German2SnowballAnalyser.java b/source/java/org/alfresco/repo/search/impl/lucene/analysis/German2SnowballAnalyser.java index ab29ceaebc..e829dcd8cb 100644 --- a/source/java/org/alfresco/repo/search/impl/lucene/analysis/German2SnowballAnalyser.java +++ b/source/java/org/alfresco/repo/search/impl/lucene/analysis/German2SnowballAnalyser.java @@ -1,3 +1,27 @@ +/* + * Copyright (C) 2005-2007 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * 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 General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" + */ package org.alfresco.repo.search.impl.lucene.analysis; import org.apache.lucene.analysis.snowball.SnowballAnalyzer; @@ -7,6 +31,6 @@ public class German2SnowballAnalyser extends SnowballAnalyzer public German2SnowballAnalyser() { - super("Danish"); + super("German2"); } } diff --git a/source/java/org/alfresco/repo/search/impl/lucene/analysis/GermanSnowballAnalyser.java b/source/java/org/alfresco/repo/search/impl/lucene/analysis/GermanSnowballAnalyser.java index 8be89305ed..39b969611f 100644 --- a/source/java/org/alfresco/repo/search/impl/lucene/analysis/GermanSnowballAnalyser.java +++ b/source/java/org/alfresco/repo/search/impl/lucene/analysis/GermanSnowballAnalyser.java @@ -1,3 +1,27 @@ +/* + * Copyright (C) 2005-2007 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * 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 General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" + */ package org.alfresco.repo.search.impl.lucene.analysis; import org.apache.lucene.analysis.snowball.SnowballAnalyzer; @@ -7,6 +31,6 @@ public class GermanSnowballAnalyser extends SnowballAnalyzer public GermanSnowballAnalyser() { - super("Danish"); + super("German"); } } diff --git a/source/java/org/alfresco/repo/search/impl/lucene/analysis/ItalianSnowballAnalyser.java b/source/java/org/alfresco/repo/search/impl/lucene/analysis/ItalianSnowballAnalyser.java index a29e223cf9..537e764233 100644 --- a/source/java/org/alfresco/repo/search/impl/lucene/analysis/ItalianSnowballAnalyser.java +++ b/source/java/org/alfresco/repo/search/impl/lucene/analysis/ItalianSnowballAnalyser.java @@ -1,3 +1,27 @@ +/* + * Copyright (C) 2005-2007 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * 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 General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" + */ package org.alfresco.repo.search.impl.lucene.analysis; import org.apache.lucene.analysis.snowball.SnowballAnalyzer; @@ -7,6 +31,6 @@ public class ItalianSnowballAnalyser extends SnowballAnalyzer public ItalianSnowballAnalyser() { - super("Danish"); + super("Italian"); } } diff --git a/source/java/org/alfresco/repo/search/impl/lucene/analysis/KPSnowballAnalyser.java b/source/java/org/alfresco/repo/search/impl/lucene/analysis/KPSnowballAnalyser.java index cbf92af45f..1ccb65f0f7 100644 --- a/source/java/org/alfresco/repo/search/impl/lucene/analysis/KPSnowballAnalyser.java +++ b/source/java/org/alfresco/repo/search/impl/lucene/analysis/KPSnowballAnalyser.java @@ -1,3 +1,27 @@ +/* + * Copyright (C) 2005-2007 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * 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 General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" + */ package org.alfresco.repo.search.impl.lucene.analysis; import org.apache.lucene.analysis.snowball.SnowballAnalyzer; @@ -7,6 +31,6 @@ public class KPSnowballAnalyser extends SnowballAnalyzer public KPSnowballAnalyser() { - super("Danish"); + super("Kp"); } } diff --git a/source/java/org/alfresco/repo/search/impl/lucene/analysis/LovinsSnowballAnalyser.java b/source/java/org/alfresco/repo/search/impl/lucene/analysis/LovinsSnowballAnalyser.java index a7ea3c701d..70e4c93a4a 100644 --- a/source/java/org/alfresco/repo/search/impl/lucene/analysis/LovinsSnowballAnalyser.java +++ b/source/java/org/alfresco/repo/search/impl/lucene/analysis/LovinsSnowballAnalyser.java @@ -1,3 +1,27 @@ +/* + * Copyright (C) 2005-2007 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * 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 General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" + */ package org.alfresco.repo.search.impl.lucene.analysis; import org.apache.lucene.analysis.snowball.SnowballAnalyzer; @@ -7,6 +31,6 @@ public class LovinsSnowballAnalyser extends SnowballAnalyzer public LovinsSnowballAnalyser() { - super("Danish"); + super("Lovins"); } } diff --git a/source/java/org/alfresco/repo/search/impl/lucene/analysis/LowerCaseVerbatimAnalyser.java b/source/java/org/alfresco/repo/search/impl/lucene/analysis/LowerCaseVerbatimAnalyser.java index c15b62f670..a461ac4f1e 100644 --- a/source/java/org/alfresco/repo/search/impl/lucene/analysis/LowerCaseVerbatimAnalyser.java +++ b/source/java/org/alfresco/repo/search/impl/lucene/analysis/LowerCaseVerbatimAnalyser.java @@ -1,3 +1,27 @@ +/* + * Copyright (C) 2005-2007 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * 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 General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" + */ package org.alfresco.repo.search.impl.lucene.analysis; public class LowerCaseVerbatimAnalyser extends VerbatimAnalyser diff --git a/source/java/org/alfresco/repo/search/impl/lucene/analysis/MLAnalayser.java b/source/java/org/alfresco/repo/search/impl/lucene/analysis/MLAnalayser.java index a7aec2f5dc..a80330f596 100644 --- a/source/java/org/alfresco/repo/search/impl/lucene/analysis/MLAnalayser.java +++ b/source/java/org/alfresco/repo/search/impl/lucene/analysis/MLAnalayser.java @@ -1,3 +1,27 @@ +/* + * Copyright (C) 2005-2007 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * 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 General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" + */ package org.alfresco.repo.search.impl.lucene.analysis; import java.io.BufferedReader; diff --git a/source/java/org/alfresco/repo/search/impl/lucene/analysis/MLTokenDuplicator.java b/source/java/org/alfresco/repo/search/impl/lucene/analysis/MLTokenDuplicator.java index 8bcf61f26f..78bb998cd6 100644 --- a/source/java/org/alfresco/repo/search/impl/lucene/analysis/MLTokenDuplicator.java +++ b/source/java/org/alfresco/repo/search/impl/lucene/analysis/MLTokenDuplicator.java @@ -1,3 +1,27 @@ +/* + * Copyright (C) 2005-2007 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * 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 General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" + */ package org.alfresco.repo.search.impl.lucene.analysis; import java.io.IOException; diff --git a/source/java/org/alfresco/repo/search/impl/lucene/analysis/NorwegianSnowballAnalyser.java b/source/java/org/alfresco/repo/search/impl/lucene/analysis/NorwegianSnowballAnalyser.java index a2078a3866..6bbdc88e48 100644 --- a/source/java/org/alfresco/repo/search/impl/lucene/analysis/NorwegianSnowballAnalyser.java +++ b/source/java/org/alfresco/repo/search/impl/lucene/analysis/NorwegianSnowballAnalyser.java @@ -1,3 +1,27 @@ +/* + * Copyright (C) 2005-2007 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * 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 General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" + */ package org.alfresco.repo.search.impl.lucene.analysis; import org.apache.lucene.analysis.snowball.SnowballAnalyzer; @@ -7,6 +31,6 @@ public class NorwegianSnowballAnalyser extends SnowballAnalyzer public NorwegianSnowballAnalyser() { - super("Danish"); + super("Norwegian"); } } diff --git a/source/java/org/alfresco/repo/search/impl/lucene/analysis/PorterSnowballAnalyser.java b/source/java/org/alfresco/repo/search/impl/lucene/analysis/PorterSnowballAnalyser.java index 636ffd79e3..b72108f40b 100644 --- a/source/java/org/alfresco/repo/search/impl/lucene/analysis/PorterSnowballAnalyser.java +++ b/source/java/org/alfresco/repo/search/impl/lucene/analysis/PorterSnowballAnalyser.java @@ -1,3 +1,27 @@ +/* + * Copyright (C) 2005-2007 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * 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 General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" + */ package org.alfresco.repo.search.impl.lucene.analysis; import org.apache.lucene.analysis.snowball.SnowballAnalyzer; @@ -7,6 +31,6 @@ public class PorterSnowballAnalyser extends SnowballAnalyzer public PorterSnowballAnalyser() { - super("Danish"); + super("Porter"); } } diff --git a/source/java/org/alfresco/repo/search/impl/lucene/analysis/PortugueseSnowballAnalyser.java b/source/java/org/alfresco/repo/search/impl/lucene/analysis/PortugueseSnowballAnalyser.java index 4faf802004..e69930cd7b 100644 --- a/source/java/org/alfresco/repo/search/impl/lucene/analysis/PortugueseSnowballAnalyser.java +++ b/source/java/org/alfresco/repo/search/impl/lucene/analysis/PortugueseSnowballAnalyser.java @@ -1,3 +1,27 @@ +/* + * Copyright (C) 2005-2007 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * 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 General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" + */ package org.alfresco.repo.search.impl.lucene.analysis; import org.apache.lucene.analysis.snowball.SnowballAnalyzer; @@ -7,6 +31,6 @@ public class PortugueseSnowballAnalyser extends SnowballAnalyzer public PortugueseSnowballAnalyser() { - super("Danish"); + super("Portuguese"); } } diff --git a/source/java/org/alfresco/repo/search/impl/lucene/analysis/RussianSnowballAnalyser.java b/source/java/org/alfresco/repo/search/impl/lucene/analysis/RussianSnowballAnalyser.java index 9c43c381a3..86729a44be 100644 --- a/source/java/org/alfresco/repo/search/impl/lucene/analysis/RussianSnowballAnalyser.java +++ b/source/java/org/alfresco/repo/search/impl/lucene/analysis/RussianSnowballAnalyser.java @@ -1,3 +1,27 @@ +/* + * Copyright (C) 2005-2007 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * 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 General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" + */ package org.alfresco.repo.search.impl.lucene.analysis; import org.apache.lucene.analysis.snowball.SnowballAnalyzer; @@ -7,6 +31,6 @@ public class RussianSnowballAnalyser extends SnowballAnalyzer public RussianSnowballAnalyser() { - super("Danish"); + super("Russian"); } } diff --git a/source/java/org/alfresco/repo/search/impl/lucene/analysis/SpanishSnowballAnalyser.java b/source/java/org/alfresco/repo/search/impl/lucene/analysis/SpanishSnowballAnalyser.java index 5036390ef5..8d6b03baf6 100644 --- a/source/java/org/alfresco/repo/search/impl/lucene/analysis/SpanishSnowballAnalyser.java +++ b/source/java/org/alfresco/repo/search/impl/lucene/analysis/SpanishSnowballAnalyser.java @@ -1,3 +1,27 @@ +/* + * Copyright (C) 2005-2007 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * 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 General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" + */ package org.alfresco.repo.search.impl.lucene.analysis; import org.apache.lucene.analysis.snowball.SnowballAnalyzer; @@ -7,6 +31,6 @@ public class SpanishSnowballAnalyser extends SnowballAnalyzer public SpanishSnowballAnalyser() { - super("Danish"); + super("Spanish"); } } diff --git a/source/java/org/alfresco/repo/search/impl/lucene/analysis/SwedishSnowballAnalyser.java b/source/java/org/alfresco/repo/search/impl/lucene/analysis/SwedishSnowballAnalyser.java index aeff418000..2985f2cd80 100644 --- a/source/java/org/alfresco/repo/search/impl/lucene/analysis/SwedishSnowballAnalyser.java +++ b/source/java/org/alfresco/repo/search/impl/lucene/analysis/SwedishSnowballAnalyser.java @@ -1,3 +1,27 @@ +/* + * Copyright (C) 2005-2007 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * 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 General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" + */ package org.alfresco.repo.search.impl.lucene.analysis; import org.apache.lucene.analysis.snowball.SnowballAnalyzer; @@ -7,6 +31,6 @@ public class SwedishSnowballAnalyser extends SnowballAnalyzer public SwedishSnowballAnalyser() { - super("Danish"); + super("Swedish"); } } diff --git a/source/java/org/alfresco/repo/search/impl/lucene/analysis/VerbatimAnalyser.java b/source/java/org/alfresco/repo/search/impl/lucene/analysis/VerbatimAnalyser.java index d39fec920f..1ae841caa0 100644 --- a/source/java/org/alfresco/repo/search/impl/lucene/analysis/VerbatimAnalyser.java +++ b/source/java/org/alfresco/repo/search/impl/lucene/analysis/VerbatimAnalyser.java @@ -1,3 +1,27 @@ +/* + * Copyright (C) 2005-2007 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * 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 General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" + */ package org.alfresco.repo.search.impl.lucene.analysis; import java.io.Reader; diff --git a/source/java/org/alfresco/repo/search/impl/lucene/analysis/VerbatimTokenFilter.java b/source/java/org/alfresco/repo/search/impl/lucene/analysis/VerbatimTokenFilter.java index 579a98bf3b..7afc3664a4 100644 --- a/source/java/org/alfresco/repo/search/impl/lucene/analysis/VerbatimTokenFilter.java +++ b/source/java/org/alfresco/repo/search/impl/lucene/analysis/VerbatimTokenFilter.java @@ -1,3 +1,27 @@ +/* + * Copyright (C) 2005-2007 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * 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 General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" + */ package org.alfresco.repo.search.impl.lucene.analysis; import java.io.IOException; diff --git a/source/java/org/alfresco/repo/transaction/RetryingTransactionHelper.java b/source/java/org/alfresco/repo/transaction/RetryingTransactionHelper.java index bba661fd67..b72f8186fd 100644 --- a/source/java/org/alfresco/repo/transaction/RetryingTransactionHelper.java +++ b/source/java/org/alfresco/repo/transaction/RetryingTransactionHelper.java @@ -38,6 +38,7 @@ import org.alfresco.repo.security.permissions.AccessDeniedException; import org.alfresco.service.transaction.TransactionService; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.hibernate.ObjectNotFoundException; import org.hibernate.StaleObjectStateException; import org.hibernate.StaleStateException; import org.hibernate.exception.ConstraintViolationException; @@ -73,7 +74,8 @@ public class RetryingTransactionHelper BatchUpdateException.class, ConstraintViolationException.class, DataIntegrityViolationException.class, - StaleStateException.class + StaleStateException.class, + ObjectNotFoundException.class }; } @@ -398,6 +400,15 @@ public class RetryingTransactionHelper return null; } } + else if (retryCause instanceof ObjectNotFoundException) + { + // This is (I'm almost certain) an optimistic locking failure in disguise. + if (retryCause.getMessage().contains("No row")) + { + return retryCause; + } + return null; + } else { return retryCause;