[exo-jcr-commits] exo-jcr SVN: r198 - in jcr/trunk/component/core: src/main/java/org/exoplatform/services/jcr/config and 6 other directories.
do-not-reply at jboss.org
do-not-reply at jboss.org
Fri Oct 2 11:41:15 EDT 2009
Author: skabashnyuk
Date: 2009-10-02 11:41:14 -0400 (Fri, 02 Oct 2009)
New Revision: 198
Added:
jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/IndexException.java
jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/RepositoryIndexSearcherHolder.java
jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/LuceneVirtualTableResolver.java
jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/NodeTypeVirtualTableResolver.java
jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/VirtualTableResolver.java
jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/indexing-configuration-1.1.dtd
jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/indexing-configuration-1.2.dtd
Modified:
jcr/trunk/component/core/pom.xml
jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/config/QueryHandlerEntryWrapper.java
jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/core/nodetype/NodeTypeDataManager.java
jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/RepositoryContainer.java
jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/NamespaceRegistryImpl.java
jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/nodetype/NodeTypeDataManagerImpl.java
jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/nodetype/VolatileNodeTypeDataManager.java
jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/ErrorLog.java
jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/QueryHandlerContext.java
jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SearchIndexConfigurationHelper.java
jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SearchManager.java
jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SystemSearchManager.java
jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/IndexingConfigurationEntityResolver.java
jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/IndexingConfigurationImpl.java
jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/LuceneQueryBuilder.java
jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/QueryImpl.java
jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/SearchIndex.java
jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/indexing-configuration-1.0.dtd
Log:
EXOJCR-161 : indexer configuration update
Modified: jcr/trunk/component/core/pom.xml
===================================================================
--- jcr/trunk/component/core/pom.xml 2009-10-02 15:39:44 UTC (rev 197)
+++ jcr/trunk/component/core/pom.xml 2009-10-02 15:41:14 UTC (rev 198)
@@ -112,6 +112,12 @@
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
+ <exclusions>
+ <exclusion>
+ <groupId>xerces</groupId>
+ <artifactId>xercesImpl</artifactId>
+ </exclusion>
+ </exclusions>
</dependency>
<!-- JOTM comes from exo.kernel.component.common -->
@@ -129,7 +135,8 @@
<artifactId>log4j</artifactId>
</exclusion>
</exclusions>
- </dependency -->
+ </dependency
+-->
<dependency>
<groupId>javax.resource</groupId>
@@ -205,7 +212,8 @@
<artifactId>mysql-connector-java</artifactId>
<version>5.0.5</version>
<scope>test</scope>
- </dependency -->
+ </dependency
+-->
<!-- For PostgresSQL support -->
<!-- dependency>
@@ -213,7 +221,8 @@
<artifactId>postgresql</artifactId>
<version>8.2-504.jdbc3</version>
<scope>compile</scope>
- </dependency -->
+ </dependency
+-->
<!-- For Oracle 10g support (local-jcr repository) -->
<!-- dependency>
@@ -227,7 +236,8 @@
<artifactId>orai18n</artifactId>
<version>14</version>
<scope>compile</scope>
- </dependency -->
+ </dependency
+-->
<!-- For IBM DB2 support (local-jcr repository) -->
<!-- dependency>
@@ -241,7 +251,8 @@
<artifactId>db2jcc_license_cu</artifactId>
<version>9.1</version>
<scope>compile</scope>
- </dependency -->
+ </dependency
+-->
<!-- For MS SQL 7/2000/2005 and Sybase ASE/Anywhere support (jTDS driver) -->
<!-- dependency>
@@ -249,7 +260,8 @@
<artifactId>jtds</artifactId>
<version>1.2</version>
<scope>compile</scope>
- </dependency -->
+ </dependency
+-->
<!-- For MS SQL 2005 support (Microsoft JDBC driver) (local-jcr repository) -->
<!-- dependency>
@@ -257,7 +269,8 @@
<artifactId>sqljdbc</artifactId>
<version>9.0</version>
<scope>compile</scope>
- </dependency -->
+ </dependency
+-->
<!-- For Sybase ASE/Anywhere support (jConnect driver) (local-jcr repository) -->
<!-- dependency>
@@ -265,7 +278,8 @@
<artifactId>jconn3</artifactId>
<version>6.05</version>
<scope>compile</scope>
- </dependency -->
+ </dependency
+-->
<!-- For Apache Derby support (aka JavaDB) -->
<!-- dependency>
@@ -273,7 +287,8 @@
<artifactId>derby</artifactId>
<version>10.2.2.0</version>
<scope>compile</scope>
- </dependency -->
+ </dependency
+-->
<!-- Ingres Database (local repository) -->
<!-- dependency>
@@ -281,7 +296,8 @@
<artifactId>iijdbc</artifactId>
<version>9.2</version>
<scope>test</scope>
- </dependency -->
+ </dependency
+-->
<!-- H2 Database -->
<!--dependency>
@@ -289,7 +305,8 @@
<artifactId>h2</artifactId>
<version>1.0.74</version>
<scope>compile</scope>
- </dependency -->
+ </dependency
+-->
<!-- ======================================================================= -->
</dependencies>
@@ -428,8 +445,14 @@
<exclude>**/TestAggregateRules.java</exclude>
<exclude>**/IndexingAggregateTest.java</exclude>
<exclude>**/IndexingRuleTest.java</exclude>
+ <exclude>**/TestExcelFileSearch.java</exclude>
+ <exclude>**/TestRewriteNode.java</exclude>
+ <exclude>**/TestArabicSearch.java</exclude>
+ <exclude>**/TestDateSearch.java</exclude>
+ <exclude>**/TestBinarySearch.java</exclude>
+
<exclude>**/TestImport.java</exclude>
<exclude>**/TestRollbackBigFiles.java</exclude>
<exclude>**/TestErrorMultithreading.java</exclude>
@@ -486,7 +509,8 @@
<include>org/exoplatform/services/jcr/integration/PrepareTestRepository.java</include>
</includes>
</configuration>
- </execution -->
+ </execution
+-->
<execution>
<id>execution4 - pause 10 sec</id>
<phase>test</phase>
Modified: jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/config/QueryHandlerEntryWrapper.java
===================================================================
--- jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/config/QueryHandlerEntryWrapper.java 2009-10-02 15:39:44 UTC (rev 197)
+++ jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/config/QueryHandlerEntryWrapper.java 2009-10-02 15:41:14 UTC (rev 198)
@@ -22,7 +22,6 @@
import org.exoplatform.container.configuration.ConfigurationManager;
import org.exoplatform.services.jcr.datamodel.IllegalNameException;
import org.exoplatform.services.jcr.impl.Constants;
-import org.exoplatform.services.jcr.impl.core.query.ErrorLog;
import org.exoplatform.services.jcr.impl.core.query.QueryHandler;
import org.exoplatform.services.jcr.impl.core.query.QueryHandlerContext;
import org.exoplatform.services.jcr.impl.core.query.QueryImpl;
@@ -58,641 +57,624 @@
* @version $Id: QueryHandlerEntry.java 14931 2008-05-29 15:02:08Z ksm $
*/
-public class QueryHandlerEntryWrapper implements QueryHandlerParams
-{
+public class QueryHandlerEntryWrapper implements QueryHandlerParams {
- /**
- * The default value for property {@link #extractorBackLog}.
- */
- public static final int DEFAULT_EXTRACTOR_BACKLOG = 100;
+ /**
+ * The default value for property {@link #extractorBackLog}.
+ */
+ public static final int DEFAULT_EXTRACTOR_BACKLOG = 100;
- /**
- * The default value for property {@link #extractorPoolSize}.
- */
- public static final int DEFAULT_EXTRACTOR_POOLSIZE = 0;
+ /**
+ * The default value for property {@link #extractorPoolSize}.
+ */
+ public static final int DEFAULT_EXTRACTOR_POOLSIZE = 0;
- /**
- * The default timeout in milliseconds which is granted to the text extraction process until
- * fulltext indexing is deferred to a background thread.
- */
- public static final int DEFAULT_EXTRACTOR_TIMEOUT = 100;
+ /**
+ * The default timeout in milliseconds which is granted to the text
+ * extraction process until fulltext indexing is deferred to a background
+ * thread.
+ */
+ public static final int DEFAULT_EXTRACTOR_TIMEOUT = 100;
- /**
- * the default value for property {@link #maxFieldLength}.
- */
- public static final int DEFAULT_MAX_FIELD_LENGTH = 10000;
+ /**
+ * the default value for property {@link #maxFieldLength}.
+ */
+ public static final int DEFAULT_MAX_FIELD_LENGTH = 10000;
- /**
- * The default value for property {@link #maxMergeDocs}.
- */
- public static final int DEFAULT_MAX_MERGE_DOCS = Integer.MAX_VALUE;
+ /**
+ * The default value for property {@link #maxMergeDocs}.
+ */
+ public static final int DEFAULT_MAX_MERGE_DOCS = Integer.MAX_VALUE;
- /**
- * the default value for property {@link #mergeFactor}.
- */
- public static final int DEFAULT_MERGE_FACTOR = 10;
+ /**
+ * the default value for property {@link #mergeFactor}.
+ */
+ public static final int DEFAULT_MERGE_FACTOR = 10;
- /**
- * The default value for property {@link #minMergeDocs}.
- */
- public static final int DEFAULT_MIN_MERGE_DOCS = 100;
+ /**
+ * The default value for property {@link #minMergeDocs}.
+ */
+ public static final int DEFAULT_MIN_MERGE_DOCS = 100;
- /**
- * Name of the file to persist search internal namespace mappings.
- */
- public static final String NS_MAPPING_FILE = "ns_mappings.properties"; // TODO
+ /**
+ * Name of the file to persist search internal namespace mappings.
+ */
+ public static final String NS_MAPPING_FILE = "ns_mappings.properties"; // TODO
- /**
- * The excerpt provider class. Implements {@link ExcerptProvider}.
- */
- private static final String DEDAULT_EXCERPTPROVIDER_CLASS = DefaultHTMLExcerpt.class.getName();
+ /**
+ * The excerpt provider class. Implements {@link ExcerptProvider}.
+ */
+ private static final String DEDAULT_EXCERPTPROVIDER_CLASS = DefaultHTMLExcerpt.class
+ .getName();
- private static final String DEDAULT_INDEXINGCONFIGURATIONCLASS = IndexingConfigurationImpl.class.getName();
+ private static final String DEDAULT_INDEXINGCONFIGURATIONCLASS = IndexingConfigurationImpl.class
+ .getName();
- private static final boolean DEFAULT_AUTOREPAIR = true;
+ private static final boolean DEFAULT_AUTOREPAIR = true;
- private static final int DEFAULT_BUFFER_SIZE = 10;
+ private static final int DEFAULT_BUFFER_SIZE = 10;
- private static final int DEFAULT_CACHE_SIZE = 1000;
+ private static final int DEFAULT_CACHE_SIZE = 1000;
- private final static boolean DEFAULT_CONSISTENCYCHECKENABLED = false;
+ private final static boolean DEFAULT_CONSISTENCYCHECKENABLED = false;
- private final static boolean DEFAULT_DOCUMENTORDER = true;
+ private final static boolean DEFAULT_DOCUMENTORDER = true;
- private final static boolean DEFAULT_FORCECONSISTENCYCHECK = false;
+ private final static boolean DEFAULT_FORCECONSISTENCYCHECK = false;
- /**
- * Name of the default query implementation class.
- */
- private static final String DEFAULT_QUERY_HANDLER_CLASS = SearchIndex.class.getName();
+ /**
+ * Name of the default query implementation class.
+ */
+ private static final String DEFAULT_QUERY_HANDLER_CLASS = SearchIndex.class
+ .getName();
- /**
- * Name of the default query implementation class.
- */
- private static final String DEFAULT_QUERY_IMPL_CLASS = QueryImpl.class.getName();
+ /**
+ * Name of the default query implementation class.
+ */
+ private static final String DEFAULT_QUERY_IMPL_CLASS = QueryImpl.class
+ .getName();
- /**
- * The number of documents that are pre fetched when a query is executed. <p/> Default value is:
- * {@link Integer#MAX_VALUE}.
- */
- private final static int DEFAULT_RESULTFETCHSIZE = Integer.MAX_VALUE;
+ /**
+ * The number of documents that are pre fetched when a query is executed.
+ * <p/>
+ * Default value is: {@link Integer#MAX_VALUE}.
+ */
+ private final static int DEFAULT_RESULTFETCHSIZE = Integer.MAX_VALUE;
- private final static boolean DEFAULT_SUPPORTHIGHLIGHTING = false;
+ private final static boolean DEFAULT_SUPPORTHIGHLIGHTING = false;
- private final static boolean DEFAULT_USECOMPOUNDFILE = false;
+ private final static boolean DEFAULT_USECOMPOUNDFILE = false;
- private final static int DEFAULT_VOLATILEIDLETIME = 3;
+ private final static int DEFAULT_VOLATILEIDLETIME = 3;
- //since https://jira.jboss.org/jira/browse/EXOJCR-17
+ // since https://jira.jboss.org/jira/browse/EXOJCR-17
- public static final boolean DEFAULT_UPGRADE_INDEX = false;
+ public static final boolean DEFAULT_UPGRADE_INDEX = false;
- private QueryHandlerEntry queryHandlerEntry;
+ private QueryHandlerEntry queryHandlerEntry;
- public QueryHandlerEntry getQueryHandlerEntry()
- {
- return queryHandlerEntry;
- }
+ public QueryHandlerEntry getQueryHandlerEntry() {
+ return queryHandlerEntry;
+ }
- private static void initDefaults(QueryHandlerEntry entry)
- {
- entry.putBooleanParameter(PARAM_AUTO_REPAIR, DEFAULT_AUTOREPAIR);
- entry.putIntegerParameter(PARAM_BUFFER_SIZE, DEFAULT_BUFFER_SIZE);
- entry.putIntegerParameter(PARAM_CACHE_SIZE, DEFAULT_CACHE_SIZE);
- entry.putBooleanParameter(PARAM_DOCUMENT_ORDER, DEFAULT_DOCUMENTORDER);
- entry.putParameterValue(PARAM_EXCERPTPROVIDER_CLASS, DEDAULT_EXCERPTPROVIDER_CLASS);
- entry.putParameterValue(PARAM_EXCLUDED_NODE_IDENTIFERS, null);
- entry.putIntegerParameter(PARAM_EXTRACTOR_BACKLOG, DEFAULT_EXTRACTOR_BACKLOG);
- entry.putIntegerParameter(PARAM_EXTRACTOR_POOLSIZE, DEFAULT_EXTRACTOR_POOLSIZE);
- entry.putIntegerParameter(PARAM_EXTRACTOR_TIMEOUT, DEFAULT_EXTRACTOR_TIMEOUT);
- }
+ private static void initDefaults(QueryHandlerEntry entry) {
+ entry.putBooleanParameter(PARAM_AUTO_REPAIR, DEFAULT_AUTOREPAIR);
+ entry.putIntegerParameter(PARAM_BUFFER_SIZE, DEFAULT_BUFFER_SIZE);
+ entry.putIntegerParameter(PARAM_CACHE_SIZE, DEFAULT_CACHE_SIZE);
+ entry.putBooleanParameter(PARAM_DOCUMENT_ORDER, DEFAULT_DOCUMENTORDER);
+ entry.putParameterValue(PARAM_EXCERPTPROVIDER_CLASS,
+ DEDAULT_EXCERPTPROVIDER_CLASS);
+ entry.putParameterValue(PARAM_EXCLUDED_NODE_IDENTIFERS, null);
+ entry.putIntegerParameter(PARAM_EXTRACTOR_BACKLOG,
+ DEFAULT_EXTRACTOR_BACKLOG);
+ entry.putIntegerParameter(PARAM_EXTRACTOR_POOLSIZE,
+ DEFAULT_EXTRACTOR_POOLSIZE);
+ entry.putIntegerParameter(PARAM_EXTRACTOR_TIMEOUT,
+ DEFAULT_EXTRACTOR_TIMEOUT);
+ }
- public String getType()
- {
- return queryHandlerEntry.getType();
- }
+ public String getType() {
+ return queryHandlerEntry.getType();
+ }
- public static QueryHandlerEntry queryHandlerEntryFactory()
- {
- QueryHandlerEntry entry = new QueryHandlerEntry();
- initDefaults(entry);
- return entry;
- }
+ public static QueryHandlerEntry queryHandlerEntryFactory() {
+ QueryHandlerEntry entry = new QueryHandlerEntry();
+ initDefaults(entry);
+ return entry;
+ }
- /** The logger instance for this class */
- private static final Log log = ExoLogger.getLogger(QueryHandlerEntry.class);
+ /** The logger instance for this class */
+ private static final Log log = ExoLogger.getLogger(QueryHandlerEntry.class);
- //public QueryHandlerEntry queryHandler;
+ // public QueryHandlerEntry queryHandler;
- public Integer volatileIdleTime;
+ public Integer volatileIdleTime;
- /**
- * The analyzer we use for indexing.
- */
- private JcrStandartAnalyzer analyzer;
+ /**
+ * The analyzer we use for indexing.
+ */
+ private JcrStandartAnalyzer analyzer;
- private String queryHandlerClass = DEFAULT_QUERY_HANDLER_CLASS;
+ private String queryHandlerClass = DEFAULT_QUERY_HANDLER_CLASS;
- public QueryHandlerEntryWrapper(QueryHandlerEntry queryHandlerEntry)
- {
- this.queryHandlerEntry = queryHandlerEntry;
- this.analyzer = new JcrStandartAnalyzer();
- initDefaults(queryHandlerEntry);
- }
+ public QueryHandlerEntryWrapper(QueryHandlerEntry queryHandlerEntry) {
+ this.queryHandlerEntry = queryHandlerEntry;
+ this.analyzer = new JcrStandartAnalyzer();
+ initDefaults(queryHandlerEntry);
+ }
- public QueryHandlerEntryWrapper(String type, List params, QueryHandlerEntry queryHandlerEntry)
- {
- this.queryHandlerEntry = queryHandlerEntry;
- queryHandlerEntry.setType(type);
- queryHandlerEntry.setParameters(params);
- this.analyzer = new JcrStandartAnalyzer();
- initDefaults(queryHandlerEntry);
- }
+ public QueryHandlerEntryWrapper(String type, List params,
+ QueryHandlerEntry queryHandlerEntry) {
+ this.queryHandlerEntry = queryHandlerEntry;
+ queryHandlerEntry.setType(type);
+ queryHandlerEntry.setParameters(params);
+ this.analyzer = new JcrStandartAnalyzer();
+ initDefaults(queryHandlerEntry);
+ }
- /**
- * Creates an excerpt provider for the given <code>query</code>.
- *
- * @param query the query.
- * @return an excerpt provider for the given <code>query</code>.
- * @throws IOException if the provider cannot be created.
- */
- public ExcerptProvider createExcerptProvider(Query query) throws IOException
- {
- ExcerptProvider ep;
- try
- {
- Class excerptProviderClass = Class.forName(getExcerptProviderClass(), true, this.getClass().getClassLoader());
- ep = (ExcerptProvider)excerptProviderClass.newInstance();
- }
- catch (Exception e)
- {
- IOException ex = new IOException();
- ex.initCause(e);
- throw ex;
- }
+ /**
+ * Creates an excerpt provider for the given <code>query</code>.
+ *
+ * @param query
+ * the query.
+ * @return an excerpt provider for the given <code>query</code>.
+ * @throws IOException
+ * if the provider cannot be created.
+ */
+ public ExcerptProvider createExcerptProvider(Query query)
+ throws IOException {
+ ExcerptProvider ep;
+ try {
+ Class excerptProviderClass = Class.forName(
+ getExcerptProviderClass(), true, this.getClass()
+ .getClassLoader());
+ ep = (ExcerptProvider) excerptProviderClass.newInstance();
+ } catch (Exception e) {
+ IOException ex = new IOException();
+ ex.initCause(e);
+ throw ex;
+ }
- return ep;
- }
+ return ep;
+ }
- /**
- * @param namespaceMappings The namespace mappings
- * @return the fulltext indexing configuration or <code>null</code> if there is no configuration.
- */
- public IndexingConfiguration createIndexingConfiguration(NamespaceMappings namespaceMappings,
- QueryHandlerContext context, ConfigurationManager cfm) throws IOException, RepositoryConfigurationException
- {
- Element docElement = getIndexingConfigurationDOM(cfm);
- if (docElement == null)
- {
- return null;
- }
- IndexingConfiguration idxCfg = null;
- try
- {
- Class indexingConfigurationClass =
- Class.forName(getIndexingConfigurationClass(), true, this.getClass().getClassLoader());
- idxCfg = (IndexingConfiguration)indexingConfigurationClass.newInstance();
- idxCfg.init(docElement, context, namespaceMappings);
- }
- catch (InstantiationException e)
- {
- log.warn("Exception initializing indexing configuration from: " + getIndexingConfigurationPath(), e);
- }
- catch (IllegalAccessException e)
- {
- log.warn("Exception initializing indexing configuration from: " + getIndexingConfigurationPath(), e);
- }
- catch (RepositoryException e)
- {
- log.warn("Exception initializing indexing configuration from: " + getIndexingConfigurationPath(), e);
- }
- catch (IllegalNameException e)
- {
- log.warn("Exception initializing indexing configuration from: " + getIndexingConfigurationPath(), e);
- }
- catch (Exception e)
- {
- log.warn("Exception initializing indexing configuration from: " + getIndexingConfigurationPath(), e);
- }
- return idxCfg;
- }
+ /**
+ * @param namespaceMappings
+ * The namespace mappings
+ * @return the fulltext indexing configuration or <code>null</code> if there
+ * is no configuration.
+ */
+ public IndexingConfiguration createIndexingConfiguration(
+ NamespaceMappings namespaceMappings, QueryHandlerContext context,
+ ConfigurationManager cfm) throws IOException,
+ RepositoryConfigurationException {
+ Element docElement = getIndexingConfigurationDOM(cfm);
+ if (docElement == null) {
+ return null;
+ }
+ IndexingConfiguration idxCfg = null;
+ try {
+ Class indexingConfigurationClass = Class.forName(
+ getIndexingConfigurationClass(), true, this.getClass()
+ .getClassLoader());
+ idxCfg = (IndexingConfiguration) indexingConfigurationClass
+ .newInstance();
+ idxCfg.init(docElement, context, namespaceMappings);
+ } catch (InstantiationException e) {
+ log.warn("Exception initializing indexing configuration from: "
+ + getIndexingConfigurationPath(), e);
+ } catch (IllegalAccessException e) {
+ log.warn("Exception initializing indexing configuration from: "
+ + getIndexingConfigurationPath(), e);
+ } catch (RepositoryException e) {
+ log.warn("Exception initializing indexing configuration from: "
+ + getIndexingConfigurationPath(), e);
+ } catch (IllegalNameException e) {
+ log.warn("Exception initializing indexing configuration from: "
+ + getIndexingConfigurationPath(), e);
+ } catch (Exception e) {
+ log.warn("Exception initializing indexing configuration from: "
+ + getIndexingConfigurationPath(), e);
+ }
+ return idxCfg;
+ }
- /**
- * Creates a spell checker for this query handler.
- *
- * @return the spell checker or <code>null</code> if none is configured or an error occurs.
- */
- public SpellChecker createSpellChecker(QueryHandler handler)
- {
- SpellChecker spCheck = null;
- if (getSpellCheckerClass() != null)
- {
- try
- {
- Class spellCheckerClass = Class.forName(getSpellCheckerClass(), true, this.getClass().getClassLoader());
- spCheck = (SpellChecker)spellCheckerClass.newInstance();
- spCheck.init(handler);
- }
- catch (Exception e)
- {
- log.warn("Exception initializing spell checker: " + getSpellCheckerClass(), e);
- }
- }
- return spCheck;
- }
+ /**
+ * Creates a spell checker for this query handler.
+ *
+ * @return the spell checker or <code>null</code> if none is configured or
+ * an error occurs.
+ */
+ public SpellChecker createSpellChecker(QueryHandler handler) {
+ SpellChecker spCheck = null;
+ if (getSpellCheckerClass() != null) {
+ try {
+ Class spellCheckerClass = Class.forName(getSpellCheckerClass(),
+ true, this.getClass().getClassLoader());
+ spCheck = (SpellChecker) spellCheckerClass.newInstance();
+ spCheck.init(handler);
+ } catch (Exception e) {
+ log.warn("Exception initializing spell checker: "
+ + getSpellCheckerClass(), e);
+ }
+ }
+ return spCheck;
+ }
- /**
- * @param cfm
- * @return the configured synonym provider or <code>null</code> if none is configured or an error
- * occurs.
- */
- public SynonymProvider createSynonymProvider(ConfigurationManager cfm)
- {
- SynonymProvider sp = null;
- if (getSynonymProviderClass() != null)
- {
- try
- {
- Class synonymProviderClass =
- Class.forName(getSynonymProviderClass(), true, this.getClass().getClassLoader());
- sp = (SynonymProvider)synonymProviderClass.newInstance();
+ /**
+ * @param cfm
+ * @return the configured synonym provider or <code>null</code> if none is
+ * configured or an error occurs.
+ */
+ public SynonymProvider createSynonymProvider(ConfigurationManager cfm) {
+ SynonymProvider sp = null;
+ if (getSynonymProviderClass() != null) {
+ try {
+ Class synonymProviderClass = Class.forName(
+ getSynonymProviderClass(), true, this.getClass()
+ .getClassLoader());
+ sp = (SynonymProvider) synonymProviderClass.newInstance();
- sp.initialize(createSynonymProviderConfigResource(cfm));
- }
- catch (Exception e)
- {
- log.warn("Exception initializing synonym provider: " + getSynonymProviderClass(), e);
- sp = null;
- }
- }
- return sp;
- }
+ sp.initialize(createSynonymProviderConfigResource(cfm));
+ } catch (Exception e) {
+ log.warn("Exception initializing synonym provider: "
+ + getSynonymProviderClass(), e);
+ sp = null;
+ }
+ }
+ return sp;
+ }
- public JcrStandartAnalyzer getAnalyzer()
- {
- return analyzer;
- }
+ public JcrStandartAnalyzer getAnalyzer() {
+ return analyzer;
+ }
- private String getParameterString(String name)
- {
- return queryHandlerEntry.getParameterValue(name, null);
- }
+ private String getParameterString(String name) {
+ return queryHandlerEntry.getParameterValue(name, null);
+ }
- private Integer getParameterIntegerInitialized(String name)
- {
- String value = queryHandlerEntry.getParameterValue(name, null);
- return StringNumberParser.parseInt(value);
- }
+ private Integer getParameterIntegerInitialized(String name) {
+ String value = queryHandlerEntry.getParameterValue(name, null);
+ return StringNumberParser.parseInt(value);
+ }
- private Boolean getParameterBooleanInitialized(String name)
- {
- String value = queryHandlerEntry.getParameterValue(name, "false");
- return Boolean.parseBoolean(value);
- }
+ private Boolean getParameterBooleanInitialized(String name) {
+ String value = queryHandlerEntry.getParameterValue(name, "false");
+ return Boolean.parseBoolean(value);
+ }
- /**
- * If set <code>true</code> errors detected by the consistency check are repaired. If
- * <code>false</code> the errors are only reported in the log. <p/> Default value is:
- * <code>true</code>.
- * @throws RepositoryConfigurationException
- */
- public boolean getAutoRepair() throws RepositoryConfigurationException
- {
- return getParameterBooleanInitialized(PARAM_AUTO_REPAIR);
- }
+ /**
+ * If set <code>true</code> errors detected by the consistency check are
+ * repaired. If <code>false</code> the errors are only reported in the log.
+ * <p/>
+ * Default value is: <code>true</code>.
+ *
+ * @throws RepositoryConfigurationException
+ */
+ public boolean getAutoRepair() throws RepositoryConfigurationException {
+ return getParameterBooleanInitialized(PARAM_AUTO_REPAIR);
+ }
- /**
- * Number of documents that are buffered before they are added to the index.
- * @throws RepositoryConfigurationException
- */
- public int getBufferSize()
- {
- return getParameterIntegerInitialized(PARAM_BUFFER_SIZE);
- }
+ /**
+ * Number of documents that are buffered before they are added to the index.
+ *
+ * @throws RepositoryConfigurationException
+ */
+ public int getBufferSize() {
+ return getParameterIntegerInitialized(PARAM_BUFFER_SIZE);
+ }
- public int getCacheSize()
- {
- return getParameterIntegerInitialized(PARAM_CACHE_SIZE);
- }
+ public int getCacheSize() {
+ return getParameterIntegerInitialized(PARAM_CACHE_SIZE);
+ }
- /**
- * Flag indicating whether document order is enable as the default ordering.
- */
- public boolean getDocumentOrder()
- {
- return getParameterBooleanInitialized(PARAM_DOCUMENT_ORDER);
- }
+ /**
+ * Flag indicating whether document order is enable as the default ordering.
+ */
+ public boolean getDocumentOrder() {
+ return getParameterBooleanInitialized(PARAM_DOCUMENT_ORDER);
+ }
- /**
- * @return the class name of the excerpt provider implementation.
- */
- public String getExcerptProviderClass()
- {
- return getParameterString(PARAM_EXCERPTPROVIDER_CLASS);
- }
+ /**
+ * @return the class name of the excerpt provider implementation.
+ */
+ public String getExcerptProviderClass() {
+ return getParameterString(PARAM_EXCERPTPROVIDER_CLASS);
+ }
- public String getExcludedNodeIdentifers()
- {
- return getParameterString(PARAM_EXCLUDED_NODE_IDENTIFERS);
- }
+ public String getExcludedNodeIdentifers() {
+ return getParameterString(PARAM_EXCLUDED_NODE_IDENTIFERS);
+ }
- /**
- * @return the size of the extractor queue back log.
- */
- public int getExtractorBackLogSize()
- {
- return getParameterIntegerInitialized(PARAM_EXTRACTOR_BACKLOG);
- }
+ /**
+ * @return the size of the extractor queue back log.
+ */
+ public int getExtractorBackLogSize() {
+ return getParameterIntegerInitialized(PARAM_EXTRACTOR_BACKLOG);
+ }
- /**
- * @return the size of the thread pool which is used to run the text extractors when binary
- * content is indexed.
- */
- public int getExtractorPoolSize()
- {
- return getParameterIntegerInitialized(PARAM_EXTRACTOR_POOLSIZE);
- }
+ /**
+ * @return the size of the thread pool which is used to run the text
+ * extractors when binary content is indexed.
+ */
+ public int getExtractorPoolSize() {
+ return getParameterIntegerInitialized(PARAM_EXTRACTOR_POOLSIZE);
+ }
- /**
- * @return the extractor timeout in milliseconds.
- */
- public long getExtractorTimeout()
- {
- return getParameterIntegerInitialized(PARAM_EXTRACTOR_TIMEOUT);
- }
+ /**
+ * @return the extractor timeout in milliseconds.
+ */
+ public long getExtractorTimeout() {
+ return getParameterIntegerInitialized(PARAM_EXTRACTOR_TIMEOUT);
+ }
- /**
- * Returns the location of the search index. Returns <code>null</code> if not set.
- *
- * @return the location of the search index.
- * @throws RepositoryConfigurationException
- */
- public String getIndexDir() throws RepositoryConfigurationException
- {
+ /**
+ * Returns the location of the search index. Returns <code>null</code> if
+ * not set.
+ *
+ * @return the location of the search index.
+ * @throws RepositoryConfigurationException
+ */
+ public String getIndexDir() throws RepositoryConfigurationException {
- String indexDir;
- try
- {
- indexDir = queryHandlerEntry.getParameterValue(PARAM_INDEX_DIR);
- }
- catch (RepositoryConfigurationException e)
- {
- indexDir = queryHandlerEntry.getParameterValue(OLD_PARAM_INDEX_DIR);
- }
+ String indexDir;
+ try {
+ indexDir = queryHandlerEntry.getParameterValue(PARAM_INDEX_DIR);
+ } catch (RepositoryConfigurationException e) {
+ indexDir = queryHandlerEntry.getParameterValue(OLD_PARAM_INDEX_DIR);
+ }
- indexDir = indexDir.replace("${java.io.tmpdir}", System.getProperty("java.io.tmpdir"));
+ indexDir = indexDir.replace("${java.io.tmpdir}", System
+ .getProperty("java.io.tmpdir"));
- return indexDir;
- }
+ return indexDir;
+ }
- /**
- * @return the class name of the indexing configuration implementation.
- */
- public String getIndexingConfigurationClass()
- {
- return queryHandlerEntry
- .getParameterValue(PARAM_INDEXING_CONFIGURATION_CLASS, DEDAULT_INDEXINGCONFIGURATIONCLASS);
- }
+ /**
+ * @return the class name of the indexing configuration implementation.
+ */
+ public String getIndexingConfigurationClass() {
+ return queryHandlerEntry.getParameterValue(
+ PARAM_INDEXING_CONFIGURATION_CLASS,
+ DEDAULT_INDEXINGCONFIGURATIONCLASS);
+ }
- /**
- * @return the path to the indexing configuration file.
- */
- public String getIndexingConfigurationPath()
- {
- return queryHandlerEntry.getParameterValue(PARAM_INDEXING_CONFIGURATION_PATH, null);
- }
+ /**
+ * @return the path to the indexing configuration file.
+ */
+ public String getIndexingConfigurationPath() {
+ return queryHandlerEntry.getParameterValue(
+ PARAM_INDEXING_CONFIGURATION_PATH, null);
+ }
- public int getMaxFieldLength()
- {
- return queryHandlerEntry.getParameterInteger(PARAM_MAX_FIELD_LENGTH, DEFAULT_MAX_FIELD_LENGTH);
- }
+ public int getMaxFieldLength() {
+ return queryHandlerEntry.getParameterInteger(PARAM_MAX_FIELD_LENGTH,
+ DEFAULT_MAX_FIELD_LENGTH);
+ }
- /**
- * Returns the current value for maxMergeDocs.
- *
- * @return the current value for maxMergeDocs.
- */
- public int getMaxMergeDocs()
- {
- return queryHandlerEntry.getParameterInteger(PARAM_MAX_MERGE_DOCS, DEFAULT_MAX_MERGE_DOCS);
- }
+ /**
+ * Returns the current value for maxMergeDocs.
+ *
+ * @return the current value for maxMergeDocs.
+ */
+ public int getMaxMergeDocs() {
+ return queryHandlerEntry.getParameterInteger(PARAM_MAX_MERGE_DOCS,
+ DEFAULT_MAX_MERGE_DOCS);
+ }
- /**
- * Returns the current value for the merge factor.
- *
- * @return the current value for the merge factor.
- */
- public int getMergeFactor()
- {
- return queryHandlerEntry.getParameterInteger(PARAM_MERGE_FACTOR, DEFAULT_MERGE_FACTOR);
- }
+ /**
+ * Returns the current value for the merge factor.
+ *
+ * @return the current value for the merge factor.
+ */
+ public int getMergeFactor() {
+ return queryHandlerEntry.getParameterInteger(PARAM_MERGE_FACTOR,
+ DEFAULT_MERGE_FACTOR);
+ }
- /**
- * Returns the current value for minMergeDocs.
- *
- * @return the current value for minMergeDocs.
- */
- public int getMinMergeDocs()
- {
- return queryHandlerEntry.getParameterInteger(PARAM_MIN_MERGE_DOCS, DEFAULT_MIN_MERGE_DOCS);
- }
+ /**
+ * Returns the current value for minMergeDocs.
+ *
+ * @return the current value for minMergeDocs.
+ */
+ public int getMinMergeDocs() {
+ return queryHandlerEntry.getParameterInteger(PARAM_MIN_MERGE_DOCS,
+ DEFAULT_MIN_MERGE_DOCS);
+ }
- public String getQueryClass()
- {
- return queryHandlerEntry.getParameterValue(PARAM_QUERY_CLASS, DEFAULT_QUERY_IMPL_CLASS);
- }
+ public String getQueryClass() {
+ return queryHandlerEntry.getParameterValue(PARAM_QUERY_CLASS,
+ DEFAULT_QUERY_IMPL_CLASS);
+ }
- /**
- * @return the number of results the query handler will fetch initially when a query is executed.
- */
- public int getResultFetchSize()
- {
- return queryHandlerEntry.getParameterInteger(PARAM_RESULT_FETCH_SIZE, DEFAULT_RESULTFETCHSIZE);
- }
+ /**
+ * @return the number of results the query handler will fetch initially when
+ * a query is executed.
+ */
+ public int getResultFetchSize() {
+ return queryHandlerEntry.getParameterInteger(PARAM_RESULT_FETCH_SIZE,
+ DEFAULT_RESULTFETCHSIZE);
+ }
- public String getRootNodeIdentifer()
- {
- return queryHandlerEntry.getParameterValue(PARAM_ROOT_NODE_ID, Constants.ROOT_UUID);
- }
+ public String getRootNodeIdentifer() {
+ return queryHandlerEntry.getParameterValue(PARAM_ROOT_NODE_ID,
+ Constants.ROOT_UUID);
+ }
- /**
- * Get spell checker class.
- *
- * @return the class name of the spell checker implementation or <code>null</code> if none is set.
- */
- public String getSpellCheckerClass()
- {
- return queryHandlerEntry.getParameterValue(PARAM_SPELLCHECKER_CLASS, null);
- }
+ /**
+ * Get spell checker class.
+ *
+ * @return the class name of the spell checker implementation or
+ * <code>null</code> if none is set.
+ */
+ public String getSpellCheckerClass() {
+ return queryHandlerEntry.getParameterValue(PARAM_SPELLCHECKER_CLASS,
+ null);
+ }
- /**
- * Get support highlighting.
- *
- * @return <code>true</code> if highlighting support is enabled.
- */
- public boolean getSupportHighlighting()
- {
- return queryHandlerEntry.getParameterBoolean(PARAM_SUPPORT_HIGHLIGHTING, DEFAULT_SUPPORTHIGHLIGHTING);
- }
+ /**
+ * Get support highlighting.
+ *
+ * @return <code>true</code> if highlighting support is enabled.
+ */
+ public boolean getSupportHighlighting() {
+ return queryHandlerEntry.getParameterBoolean(
+ PARAM_SUPPORT_HIGHLIGHTING, DEFAULT_SUPPORTHIGHLIGHTING);
+ }
- /**
- * Get synonym provider class.
- *
- * @return the class name of the synonym provider implementation or <code>null</code> if none is
- * set.
- */
- public String getSynonymProviderClass()
- {
- return queryHandlerEntry.getParameterValue(PARAM_SYNONYMPROVIDER_CLASS, null);
- }
+ /**
+ * Get synonym provider class.
+ *
+ * @return the class name of the synonym provider implementation or
+ * <code>null</code> if none is set.
+ */
+ public String getSynonymProviderClass() {
+ return queryHandlerEntry.getParameterValue(PARAM_SYNONYMPROVIDER_CLASS,
+ null);
+ }
- /**
- * Get synonym provider configuration path.
- *
- * @return the configuration path for the synonym provider. If none is set this method returns
- * <code>null</code>.
- */
- public String getSynonymProviderConfigPath()
- {
- return queryHandlerEntry.getParameterValue(PARAM_SYNONYMPROVIDER_CONFIG_PATH, null);
- }
+ /**
+ * Get synonym provider configuration path.
+ *
+ * @return the configuration path for the synonym provider. If none is set
+ * this method returns <code>null</code>.
+ */
+ public String getSynonymProviderConfigPath() {
+ return queryHandlerEntry.getParameterValue(
+ PARAM_SYNONYMPROVIDER_CONFIG_PATH, null);
+ }
- /**
- * Returns the current value for useCompoundFile.
- *
- * @return the current value for useCompoundFile.
- */
- public boolean getUseCompoundFile()
- {
- return queryHandlerEntry.getParameterBoolean(PARAM_USE_COMPOUNDFILE, DEFAULT_USECOMPOUNDFILE);
- }
+ /**
+ * Returns the current value for useCompoundFile.
+ *
+ * @return the current value for useCompoundFile.
+ */
+ public boolean getUseCompoundFile() {
+ return queryHandlerEntry.getParameterBoolean(PARAM_USE_COMPOUNDFILE,
+ DEFAULT_USECOMPOUNDFILE);
+ }
- /**
- * Returns the current value for volatileIdleTime.
- *
- * @return the current value for volatileIdleTime.
- */
- public int getVolatileIdleTime()
- {
- if (volatileIdleTime == null)
- volatileIdleTime = queryHandlerEntry.getParameterInteger(PARAM_VOLATILE_IDLE_TIME, DEFAULT_VOLATILEIDLETIME);
+ /**
+ * Returns the current value for volatileIdleTime.
+ *
+ * @return the current value for volatileIdleTime.
+ */
+ public int getVolatileIdleTime() {
+ if (volatileIdleTime == null)
+ volatileIdleTime = queryHandlerEntry.getParameterInteger(
+ PARAM_VOLATILE_IDLE_TIME, DEFAULT_VOLATILEIDLETIME);
- return volatileIdleTime;
- }
+ return volatileIdleTime;
+ }
- /**
- * If set <code>true</code> the index is checked for consistency depending on the
- * {@link #forceConsistencyCheck} parameter. If set to <code>false</code>, no consistency check is
- * performed, even if the redo log had been applied on startup. <p/> Default value is:
- * <code>false</code>.
- *
- * @return boolean
- */
- public boolean isConsistencyCheckEnabled()
- {
- return queryHandlerEntry.getParameterBoolean(PARAM_CONSISTENCY_CHECK_ENABLED, DEFAULT_CONSISTENCYCHECKENABLED);
- }
+ /**
+ * If set <code>true</code> the index is checked for consistency depending
+ * on the {@link #forceConsistencyCheck} parameter. If set to
+ * <code>false</code>, no consistency check is performed, even if the redo
+ * log had been applied on startup.
+ * <p/>
+ * Default value is: <code>false</code>.
+ *
+ * @return boolean
+ */
+ public boolean isConsistencyCheckEnabled() {
+ return queryHandlerEntry.getParameterBoolean(
+ PARAM_CONSISTENCY_CHECK_ENABLED,
+ DEFAULT_CONSISTENCYCHECKENABLED);
+ }
- public boolean isForceConsistencyCheck()
- {
- return queryHandlerEntry.getParameterBoolean(PARAM_FORCE_CONSISTENCYCHECK, DEFAULT_FORCECONSISTENCYCHECK);
- }
+ public boolean isForceConsistencyCheck() {
+ return queryHandlerEntry.getParameterBoolean(
+ PARAM_FORCE_CONSISTENCYCHECK, DEFAULT_FORCECONSISTENCYCHECK);
+ }
- /**
- *
- * @return true if index upgrade allowed.
- */
- public boolean isUpgradeIndex()
- {
- Boolean updateIndex = queryHandlerEntry.getParameterBoolean(PARAM_UPGRADE_INDEX, null);
- if (updateIndex == null || !updateIndex)
- {
- updateIndex = Boolean.valueOf(System.getProperty(PARAM_UPGRADE_INDEX));
- }
- return updateIndex;
- }
+ /**
+ *
+ * @return true if index upgrade allowed.
+ */
+ public boolean isUpgradeIndex() {
+ Boolean updateIndex = queryHandlerEntry.getParameterBoolean(
+ PARAM_UPGRADE_INDEX, null);
+ if (updateIndex == null || !updateIndex) {
+ updateIndex = Boolean.valueOf(System
+ .getProperty(PARAM_UPGRADE_INDEX));
+ }
+ return updateIndex;
+ }
- /**
- * Creates a file system resource to the synonym provider configuration.
- *
- * @param cfm
- * @return a file system resource or <code>null</code> if no path was configured.
- * @throws Exception
- */
- protected InputStream createSynonymProviderConfigResource(ConfigurationManager cfm) throws Exception
- {
- if (getSynonymProviderConfigPath() != null)
- {
- return cfm.getInputStream(getSynonymProviderConfigPath());
- }
- return null;
- }
+ /**
+ * Creates a file system resource to the synonym provider configuration.
+ *
+ * @param cfm
+ * @return a file system resource or <code>null</code> if no path was
+ * configured.
+ * @throws Exception
+ */
+ protected InputStream createSynonymProviderConfigResource(
+ ConfigurationManager cfm) throws Exception {
+ if (getSynonymProviderConfigPath() != null) {
+ return cfm.getInputStream(getSynonymProviderConfigPath());
+ }
+ return null;
+ }
- /**
- * Returns the document element of the indexing configuration or <code>null</code> if there is no
- * indexing configuration.
- *
- * @return the indexing configuration or <code>null</code> if there is none.
- * @throws IOException
- * @throws RepositoryConfigurationException
- */
- protected Element getIndexingConfigurationDOM(ConfigurationManager cfm) throws IOException,
- RepositoryConfigurationException
- {
- String indexingConfigPath = getIndexingConfigurationPath();
- Element indexingConfiguration = null;
- if (indexingConfigPath != null)
- {
+ /**
+ * Returns the document element of the indexing configuration or
+ * <code>null</code> if there is no indexing configuration.
+ *
+ * @return the indexing configuration or <code>null</code> if there is none.
+ * @throws IOException
+ * @throws RepositoryConfigurationException
+ */
+ protected Element getIndexingConfigurationDOM(ConfigurationManager cfm)
+ throws IOException, RepositoryConfigurationException {
+ String indexingConfigPath = getIndexingConfigurationPath();
+ Element indexingConfiguration = null;
+ if (indexingConfigPath != null) {
- InputStream is;
- try
- {
- is = cfm.getInputStream(indexingConfigPath);
- }
- catch (Exception e1)
- {
- throw new IOException(e1.getLocalizedMessage());
- }
+ InputStream is;
+ try {
+ is = cfm.getInputStream(indexingConfigPath);
+ } catch (Exception e1) {
+ throw new IOException(e1.getLocalizedMessage());
+ }
- if (is == null)
- throw new IOException("Resource does not exist: " + indexingConfigPath);
+ if (is == null)
+ throw new IOException("Resource does not exist: "
+ + indexingConfigPath);
- DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
- try
- {
- DocumentBuilder builder = factory.newDocumentBuilder();
- builder.setEntityResolver(new IndexingConfigurationEntityResolver());
- indexingConfiguration = builder.parse(is).getDocumentElement();
- }
- catch (ParserConfigurationException e)
- {
- throw new RepositoryConfigurationException(e.getLocalizedMessage(), e);
- }
- catch (SAXException e)
- {
- throw new RepositoryConfigurationException(e.getLocalizedMessage(), e);
- }
- }
+ DocumentBuilderFactory factory = DocumentBuilderFactory
+ .newInstance();
+ try {
+ DocumentBuilder builder = factory.newDocumentBuilder();
+ builder
+ .setEntityResolver(new IndexingConfigurationEntityResolver());
+ indexingConfiguration = builder.parse(is).getDocumentElement();
+ } catch (ParserConfigurationException e) {
+ throw new RepositoryConfigurationException(e
+ .getLocalizedMessage(), e);
+ } catch (SAXException e) {
+ throw new RepositoryConfigurationException(e
+ .getLocalizedMessage(), e);
+ }
+ }
- return indexingConfiguration;
- }
+ return indexingConfiguration;
+ }
- /**
- * Return ErrorLog file size in Kb String representation.
- *
- * @return int size in Kb
- */
- public int getErrorLogSize()
- {
- String size = queryHandlerEntry.getParameterValue(PARAM_ERRORLOG_SIZE, null);
- if ((size == null) || (size.equals("")))
- {
- return ErrorLog.DEFAULT_FILE_SIZE;
- }
- else
- {
- return new Integer(size);
- }
- }
+ /**
+ * Return ErrorLog file size in Kb String representation.
+ *
+ * @return int size in Kb
+ */
+ public int getErrorLogSize() {
+ String size = queryHandlerEntry.getParameterValue(PARAM_ERRORLOG_SIZE,
+ null);
+ if ((size == null) || (size.equals(""))) {
+ return SearchIndex.DEFAULT_ERRORLOG_FILE_SIZE;
+ } else {
+ return new Integer(size);
+ }
+ }
}
Modified: jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/core/nodetype/NodeTypeDataManager.java
===================================================================
--- jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/core/nodetype/NodeTypeDataManager.java 2009-10-02 15:39:44 UTC (rev 197)
+++ jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/core/nodetype/NodeTypeDataManager.java 2009-10-02 15:41:14 UTC (rev 198)
@@ -23,7 +23,6 @@
import org.exoplatform.services.jcr.dataflow.PlainChangesLog;
import org.exoplatform.services.jcr.datamodel.InternalQName;
import org.exoplatform.services.jcr.datamodel.NodeData;
-import org.exoplatform.services.jcr.impl.core.query.QueryHandler;
import java.io.InputStream;
import java.util.List;
@@ -51,7 +50,7 @@
*/
public Set<InternalQName> getSupertypes(final InternalQName nodeTypeName);
- void addQueryHandler(QueryHandler queryHandler);
+ //void addQueryHandler(QueryHandler queryHandler);
/**
* @param nodeName
Modified: jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/RepositoryContainer.java
===================================================================
--- jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/RepositoryContainer.java 2009-10-02 15:39:44 UTC (rev 197)
+++ jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/RepositoryContainer.java 2009-10-02 15:41:14 UTC (rev 198)
@@ -31,7 +31,6 @@
import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
import org.exoplatform.services.jcr.config.RepositoryEntry;
import org.exoplatform.services.jcr.config.WorkspaceEntry;
-import org.exoplatform.services.jcr.core.ManageableRepository;
import org.exoplatform.services.jcr.core.nodetype.ExtendedNodeTypeManager;
import org.exoplatform.services.jcr.core.nodetype.NodeTypeDataManager;
import org.exoplatform.services.jcr.impl.core.LocationFactory;
@@ -49,6 +48,7 @@
import org.exoplatform.services.jcr.impl.core.nodetype.NodeTypeManagerImpl;
import org.exoplatform.services.jcr.impl.core.observation.ObservationManagerRegistry;
import org.exoplatform.services.jcr.impl.core.query.QueryManagerFactory;
+import org.exoplatform.services.jcr.impl.core.query.RepositoryIndexSearcherHolder;
import org.exoplatform.services.jcr.impl.core.query.SearchManager;
import org.exoplatform.services.jcr.impl.core.query.SystemSearchManager;
import org.exoplatform.services.jcr.impl.core.query.SystemSearchManagerHolder;
@@ -449,28 +449,28 @@
WorkspaceContainer workspaceContainer = getWorkspaceContainer(ws.getName());
SearchManager searchManager =
(SearchManager)workspaceContainer.getComponentInstanceOfType(SearchManager.class);
- if (searchManager != null)
- {
- typeManager.addQueryHandler(searchManager.getHandler());
- namespaceRegistry.addQueryHandler(searchManager.getHandler());
- }
- else
- {
- log.warn("Search manager not configured for " + ws.getName());
- }
+ // if (searchManager != null)
+ // {
+ // typeManager.addQueryHandler(searchManager.getHandler());
+ // namespaceRegistry.addQueryHandler(searchManager.getHandler());
+ // }
+ // else
+ // {
+ // log.warn("Search manager not configured for " + ws.getName());
+ // }
}
SystemSearchManagerHolder searchManager =
(SystemSearchManagerHolder)this.getComponentInstanceOfType(SystemSearchManagerHolder.class);
- if (searchManager != null)
- {
- typeManager.addQueryHandler(searchManager.get().getHandler());
- namespaceRegistry.addQueryHandler(searchManager.get().getHandler());
- }
- else
- {
- log.warn("System search manager not configured ");
- }
+ // if (searchManager != null)
+ // {
+ // typeManager.addQueryHandler(searchManager.get().getHandler());
+ // namespaceRegistry.addQueryHandler(searchManager.get().getHandler());
+ // }
+ // else
+ // {
+ // log.warn("System search manager not configured ");
+ // }
}
@@ -603,6 +603,8 @@
registerComponentImplementation(IdGenerator.class);
+ registerComponentImplementation(RepositoryIndexSearcherHolder.class);
+
registerComponentImplementation(NamespaceDataPersister.class);
registerComponentImplementation(NamespaceRegistryImpl.class);
Modified: jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/NamespaceRegistryImpl.java
===================================================================
--- jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/NamespaceRegistryImpl.java 2009-10-02 15:39:44 UTC (rev 197)
+++ jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/NamespaceRegistryImpl.java 2009-10-02 15:41:14 UTC (rev 198)
@@ -18,42 +18,21 @@
*/
package org.exoplatform.services.jcr.impl.core;
-import org.apache.lucene.index.Term;
-import org.apache.lucene.search.BooleanQuery;
-import org.apache.lucene.search.Query;
-import org.apache.lucene.search.WildcardQuery;
-import org.apache.lucene.search.BooleanClause.Occur;
import org.exoplatform.services.jcr.dataflow.DataManager;
-import org.exoplatform.services.jcr.datamodel.InternalQName;
import org.exoplatform.services.jcr.datamodel.ItemData;
-import org.exoplatform.services.jcr.datamodel.NodeData;
-import org.exoplatform.services.jcr.datamodel.PropertyData;
-import org.exoplatform.services.jcr.datamodel.QPath;
-import org.exoplatform.services.jcr.datamodel.ValueData;
-import org.exoplatform.services.jcr.impl.core.query.QueryHandler;
-import org.exoplatform.services.jcr.impl.core.query.lucene.FieldNames;
-import org.exoplatform.services.jcr.impl.core.query.lucene.QueryHits;
-import org.exoplatform.services.jcr.impl.core.query.lucene.ScoreNode;
-import org.exoplatform.services.jcr.impl.core.value.NameValue;
-import org.exoplatform.services.jcr.impl.core.value.PathValue;
-import org.exoplatform.services.jcr.impl.core.value.ValueFactoryImpl;
-import org.exoplatform.services.jcr.impl.dataflow.AbstractValueData;
+import org.exoplatform.services.jcr.impl.core.query.RepositoryIndexSearcherHolder;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.jcr.NamespaceException;
import javax.jcr.PathNotFoundException;
-import javax.jcr.PropertyType;
import javax.jcr.RepositoryException;
-import javax.jcr.Value;
/**
* Created by The eXo Platform SAS.
@@ -115,8 +94,10 @@
private Map<String, String> prefixes;
- private HashSet<QueryHandler> queryHandlers;
+ // private HashSet<QueryHandler> queryHandlers;
+ private final RepositoryIndexSearcherHolder indexSearcherHolder;
+
// private final NodeTypeDataManager nodeTypeDataManager;
/**
@@ -126,18 +107,20 @@
{
this.namespaces = DEF_NAMESPACES;
this.prefixes = DEF_PREFIXES;
- this.queryHandlers = new HashSet<QueryHandler>();
+ this.indexSearcherHolder = new RepositoryIndexSearcherHolder();
+ // this.queryHandlers = new HashSet<QueryHandler>();
// this.nodeTypeDataManager = null;
}
- public NamespaceRegistryImpl(NamespaceDataPersister persister)
+ public NamespaceRegistryImpl(NamespaceDataPersister persister, RepositoryIndexSearcherHolder indexSearcherHolder)
{
+ this.indexSearcherHolder = indexSearcherHolder;
// this.nodeTypeDataManager = nodeTypeDataManager;
this.namespaces = new HashMap<String, String>(DEF_NAMESPACES);
this.prefixes = new HashMap<String, String>(DEF_PREFIXES);
this.persister = persister;
- this.queryHandlers = new HashSet<QueryHandler>();
+ // this.queryHandlers = new HashSet<QueryHandler>();
}
/**
@@ -340,10 +323,10 @@
}
}
- public void addQueryHandler(QueryHandler queryHandler)
- {
- queryHandlers.add(queryHandler);
- }
+ // public void addQueryHandler(QueryHandler queryHandler)
+ // {
+ // queryHandlers.add(queryHandler);
+ // }
/**
* Return
@@ -356,118 +339,118 @@
public Set<String> getNodes(String prefix) throws RepositoryException
{
- LocationFactory locationFactory = new LocationFactory(this);
- ValueFactoryImpl valueFactory = new ValueFactoryImpl(locationFactory);
+ // LocationFactory locationFactory = new LocationFactory(this);
+ // ValueFactoryImpl valueFactory = new ValueFactoryImpl(locationFactory);
+ //
+ // BooleanQuery query = new BooleanQuery();
+ // // query.add(new MatchAllDocsQuery(), Occur.MUST);
+ // // name of the node
+ // query.add(new WildcardQuery(new Term(FieldNames.LABEL, prefix + ":*")), Occur.SHOULD);
+ // // name of the property
+ // query.add(new WildcardQuery(new Term(FieldNames.PROPERTIES_SET, prefix + ":*")), Occur.SHOULD);
+ //
+ // Set<String> result = getNodes(query);
+ //
+ // // value of the property
+ // Set<String> propSet = getNodes(new WildcardQuery(new Term(FieldNames.PROPERTIES, "*" + prefix + ":*")));
+ // // Manually check property values;
+ // for (String uuid : propSet)
+ // {
+ // if (isPrefixMatch(valueFactory, uuid, prefix))
+ // result.add(uuid);
+ // }
- BooleanQuery query = new BooleanQuery();
- // query.add(new MatchAllDocsQuery(), Occur.MUST);
- // name of the node
- query.add(new WildcardQuery(new Term(FieldNames.LABEL, prefix + ":*")), Occur.SHOULD);
- // name of the property
- query.add(new WildcardQuery(new Term(FieldNames.PROPERTIES_SET, prefix + ":*")), Occur.SHOULD);
-
- Set<String> result = getNodes(query);
-
- // value of the property
- Set<String> propSet = getNodes(new WildcardQuery(new Term(FieldNames.PROPERTIES, "*" + prefix + ":*")));
- // Manually check property values;
- for (String uuid : propSet)
- {
- if (isPrefixMatch(valueFactory, uuid, prefix))
- result.add(uuid);
- }
-
- return result;
+ return indexSearcherHolder.getNodesByUri(prefix);
}
- /**
- * @param valueFactory
- * @param dm
- * @param uuid
- * @param prefix
- * @throws RepositoryException
- */
- private boolean isPrefixMatch(ValueFactoryImpl valueFactory, String uuid, String prefix) throws RepositoryException
- {
- DataManager dm = persister.getDataManager();
- ItemData node = dm.getItemData(uuid);
- if (node != null && node.isNode())
- {
- List<PropertyData> props = dm.getChildPropertiesData((NodeData)node);
- for (PropertyData propertyData : props)
- {
- if (propertyData.getType() == PropertyType.PATH || propertyData.getType() == PropertyType.NAME)
- {
- for (ValueData vdata : propertyData.getValues())
- {
- Value val =
- valueFactory.loadValue(((AbstractValueData)vdata).createTransientCopy(), propertyData.getType());
- if (propertyData.getType() == PropertyType.PATH)
- {
- if (isPrefixMatch(((PathValue)val).getQPath(), prefix))
- return true;
- }
- else if (propertyData.getType() == PropertyType.NAME)
- {
- if (isPrefixMatch(((NameValue)val).getQName(), prefix))
- return true;
- }
- }
- }
- }
- }
- return false;
- }
+ // /**
+ // * @param valueFactory
+ // * @param dm
+ // * @param uuid
+ // * @param prefix
+ // * @throws RepositoryException
+ // */
+ // private boolean isPrefixMatch(ValueFactoryImpl valueFactory, String uuid, String prefix) throws RepositoryException
+ // {
+ // DataManager dm = persister.getDataManager();
+ // ItemData node = dm.getItemData(uuid);
+ // if (node != null && node.isNode())
+ // {
+ // List<PropertyData> props = dm.getChildPropertiesData((NodeData)node);
+ // for (PropertyData propertyData : props)
+ // {
+ // if (propertyData.getType() == PropertyType.PATH || propertyData.getType() == PropertyType.NAME)
+ // {
+ // for (ValueData vdata : propertyData.getValues())
+ // {
+ // Value val =
+ // valueFactory.loadValue(((AbstractValueData)vdata).createTransientCopy(), propertyData.getType());
+ // if (propertyData.getType() == PropertyType.PATH)
+ // {
+ // if (isPrefixMatch(((PathValue)val).getQPath(), prefix))
+ // return true;
+ // }
+ // else if (propertyData.getType() == PropertyType.NAME)
+ // {
+ // if (isPrefixMatch(((NameValue)val).getQName(), prefix))
+ // return true;
+ // }
+ // }
+ // }
+ // }
+ // }
+ // return false;
+ // }
+ //
+ // private boolean isPrefixMatch(QPath value, String prefix) throws NamespaceException
+ // {
+ // for (int i = 0; i < value.getEntries().length; i++)
+ // {
+ // if (isPrefixMatch(value.getEntries()[i], prefix))
+ // return true;
+ // }
+ // return false;
+ // }
+ //
+ // private boolean isPrefixMatch(InternalQName value, String prefix) throws NamespaceException
+ // {
+ // return (value.getNamespace().equals(getURI(prefix)));
+ // }
- private boolean isPrefixMatch(QPath value, String prefix) throws NamespaceException
- {
- for (int i = 0; i < value.getEntries().length; i++)
- {
- if (isPrefixMatch(value.getEntries()[i], prefix))
- return true;
- }
- return false;
- }
+ // /**
+ // * @param query
+ // * @return
+ // * @throws RepositoryException
+ // */
+ // private Set<String> getNodes(Query query) throws RepositoryException
+ // {
+ // Set<String> result = new HashSet<String>();
+ //
+ // Iterator<QueryHandler> it = queryHandlers.iterator();
+ // try
+ // {
+ // while (it.hasNext())
+ // {
+ // QueryHandler queryHandler = it.next();
+ // QueryHits hits = queryHandler.executeQuery(query);
+ //
+ // ScoreNode sn;
+ //
+ // while ((sn = hits.nextScoreNode()) != null)
+ // {
+ // result.add(sn.getNodeId());
+ // }
+ // // for (int i = 0; i < hits.getSize(); i++)
+ // // {
+ // // result.add(hits.getFieldContent(i, FieldNames.UUID));
+ // // }
+ // }
+ // }
+ // catch (IOException e)
+ // {
+ // throw new RepositoryException(e.getLocalizedMessage(), e);
+ // }
+ // return result;
+ // }
- private boolean isPrefixMatch(InternalQName value, String prefix) throws NamespaceException
- {
- return (value.getNamespace().equals(getURI(prefix)));
- }
-
- /**
- * @param query
- * @return
- * @throws RepositoryException
- */
- private Set<String> getNodes(Query query) throws RepositoryException
- {
- Set<String> result = new HashSet<String>();
-
- Iterator<QueryHandler> it = queryHandlers.iterator();
- try
- {
- while (it.hasNext())
- {
- QueryHandler queryHandler = it.next();
- QueryHits hits = queryHandler.executeQuery(query);
-
- ScoreNode sn;
-
- while ((sn = hits.nextScoreNode()) != null)
- {
- result.add(sn.getNodeId());
- }
- // for (int i = 0; i < hits.getSize(); i++)
- // {
- // result.add(hits.getFieldContent(i, FieldNames.UUID));
- // }
- }
- }
- catch (IOException e)
- {
- throw new RepositoryException(e.getLocalizedMessage(), e);
- }
- return result;
- }
-
}
Modified: jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/nodetype/NodeTypeDataManagerImpl.java
===================================================================
--- jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/nodetype/NodeTypeDataManagerImpl.java 2009-10-02 15:39:44 UTC (rev 197)
+++ jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/nodetype/NodeTypeDataManagerImpl.java 2009-10-02 15:41:14 UTC (rev 198)
@@ -51,10 +51,8 @@
import org.exoplatform.services.jcr.impl.core.LocationFactory;
import org.exoplatform.services.jcr.impl.core.nodetype.registration.NodeDefinitionComparator;
import org.exoplatform.services.jcr.impl.core.nodetype.registration.PropertyDefinitionComparator;
-import org.exoplatform.services.jcr.impl.core.query.QueryHandler;
+import org.exoplatform.services.jcr.impl.core.query.RepositoryIndexSearcherHolder;
import org.exoplatform.services.jcr.impl.core.query.lucene.FieldNames;
-import org.exoplatform.services.jcr.impl.core.query.lucene.QueryHits;
-import org.exoplatform.services.jcr.impl.core.query.lucene.ScoreNode;
import org.exoplatform.services.jcr.impl.core.value.BaseValue;
import org.exoplatform.services.jcr.impl.core.value.ValueFactoryImpl;
import org.exoplatform.services.jcr.impl.dataflow.TransientNodeData;
@@ -78,7 +76,6 @@
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -129,12 +126,15 @@
*/
private final Map<NodeTypeManagerListener, NodeTypeManagerListener> listeners;
- protected HashSet<QueryHandler> queryHandlers;
+ // protected HashSet<QueryHandler> queryHandlers;
private final ValueFactoryImpl valueFactory;
+ protected final RepositoryIndexSearcherHolder indexSearcherHolder;
+
public NodeTypeDataManagerImpl(RepositoryEntry config, LocationFactory locationFactory,
- NamespaceRegistry namespaceRegistry, NodeTypeDataPersister persister) throws RepositoryException
+ NamespaceRegistry namespaceRegistry, NodeTypeDataPersister persister,
+ RepositoryIndexSearcherHolder indexSearcherHolder) throws RepositoryException
{
this.namespaceRegistry = namespaceRegistry;
@@ -142,6 +142,7 @@
this.persister = persister;
this.locationFactory = locationFactory;
+ this.indexSearcherHolder = indexSearcherHolder;
this.valueFactory = new ValueFactoryImpl(locationFactory);
this.accessControlPolicy = config.getAccessControl();
@@ -151,7 +152,7 @@
this.listeners = Collections.synchronizedMap(new WeakHashMap<NodeTypeManagerListener, NodeTypeManagerListener>());
this.buildInNodeTypesNames = new HashSet<InternalQName>();
initDefault();
- this.queryHandlers = new HashSet<QueryHandler>();
+ //this.queryHandlers = new HashSet<QueryHandler>();
}
/**
@@ -162,7 +163,8 @@
* @throws RepositoryException
*/
public NodeTypeDataManagerImpl(String accessControlPolicy, LocationFactory locationFactory,
- NamespaceRegistry namespaceRegistry, NodeTypeDataPersister persister) throws RepositoryException
+ NamespaceRegistry namespaceRegistry, NodeTypeDataPersister persister,
+ RepositoryIndexSearcherHolder indexSearcherHolder) throws RepositoryException
{
this.namespaceRegistry = namespaceRegistry;
@@ -170,6 +172,7 @@
this.persister = persister;
this.locationFactory = locationFactory;
+ this.indexSearcherHolder = indexSearcherHolder;
this.valueFactory = new ValueFactoryImpl(locationFactory);
this.accessControlPolicy = accessControlPolicy;
@@ -178,7 +181,7 @@
this.defsHolder = new ItemDefinitionDataHolder();
this.listeners = Collections.synchronizedMap(new WeakHashMap<NodeTypeManagerListener, NodeTypeManagerListener>());
this.buildInNodeTypesNames = new HashSet<InternalQName>();
- this.queryHandlers = new HashSet<QueryHandler>();
+ //this.queryHandlers = new HashSet<QueryHandler>();
}
/**
@@ -195,10 +198,11 @@
}
}
- public void addQueryHandler(QueryHandler queryHandler)
- {
- queryHandlers.add(queryHandler);
- }
+ //
+ // public void addQueryHandler(QueryHandler queryHandler)
+ // {
+ // queryHandlers.add(queryHandler);
+ // }
/**
* {@inheritDoc}
@@ -393,7 +397,7 @@
*/
public Set<String> getNodes(InternalQName nodeType) throws RepositoryException
{
- return getNodes(nodeType, new InternalQName[0], new InternalQName[0]);
+ return indexSearcherHolder.getNodesByNodeType(nodeType);
}
/**
@@ -407,56 +411,47 @@
public Set<String> getNodes(InternalQName nodeType, InternalQName[] includeProperties,
InternalQName[] excludeProperties) throws RepositoryException
{
- Query query = getQuery(nodeType);
- if (includeProperties.length > 0)
- {
- BooleanQuery tmp = new BooleanQuery();
- for (int i = 0; i < includeProperties.length; i++)
- {
+ return new HashSet<String>();
- String field = locationFactory.createJCRName(includeProperties[i]).getAsString();
- tmp.add(new TermQuery(new Term(FieldNames.PROPERTIES_SET, field)), Occur.MUST);
- }
- tmp.add(query, Occur.MUST);
- query = tmp;
- }
-
- if (excludeProperties.length > 0)
- {
- BooleanQuery tmp = new BooleanQuery();
- for (int i = 0; i < excludeProperties.length; i++)
- {
-
- String field = locationFactory.createJCRName(excludeProperties[i]).getAsString();
- tmp.add(new TermQuery(new Term(FieldNames.PROPERTIES_SET, field)), Occur.MUST_NOT);
- }
- tmp.add(query, Occur.MUST);
- query = tmp;
- }
-
- Iterator<QueryHandler> it = queryHandlers.iterator();
- Set<String> result = new HashSet<String>();
-
- try
- {
- while (it.hasNext())
- {
- QueryHandler queryHandler = it.next();
- QueryHits hits = queryHandler.executeQuery(query);
-
- ScoreNode sn;
-
- while ((sn = hits.nextScoreNode()) != null)
- {
- result.add(sn.getNodeId());
- }
- }
- }
- catch (IOException e)
- {
- throw new RepositoryException(e.getLocalizedMessage(), e);
- }
- return result;
+ // Query query = getQuery(nodeType);
+ // if (includeProperties.length > 0)
+ // {
+ // BooleanQuery tmp = new BooleanQuery();
+ // for (int i = 0; i < includeProperties.length; i++)
+ // {
+ //
+ // String field = locationFactory.createJCRName(includeProperties[i]).getAsString();
+ // tmp.add(new TermQuery(new Term(FieldNames.PROPERTIES_SET, field)), Occur.MUST);
+ // }
+ // tmp.add(query, Occur.MUST);
+ // query = tmp;
+ // }
+ //
+ // if (excludeProperties.length > 0)
+ // {
+ // BooleanQuery tmp = new BooleanQuery();
+ // for (int i = 0; i < excludeProperties.length; i++)
+ // {
+ //
+ // String field = locationFactory.createJCRName(excludeProperties[i]).getAsString();
+ // tmp.add(new TermQuery(new Term(FieldNames.PROPERTIES_SET, field)), Occur.MUST_NOT);
+ // }
+ // tmp.add(query, Occur.MUST);
+ // query = tmp;
+ // }
+ //
+ // Iterator<QueryHandler> it = queryHandlers.iterator();
+ // Set<String> result = new HashSet<String>();
+ //
+ // try
+ // {
+ // indexSearcherHolder.getNodesByNodeType()
+ // }
+ // catch (IOException e)
+ // {
+ // throw new RepositoryException(e.getLocalizedMessage(), e);
+ // }
+ // return result;
}
/**
@@ -486,11 +481,11 @@
return propertyDefinitions;
}
- // TODO make me private
- public Set<QueryHandler> getQueryHandlers()
- {
- return queryHandlers;
- }
+ // // TODO make me private
+ // public Set<QueryHandler> getQueryHandlers()
+ // {
+ // return queryHandlers;
+ // }
/**
* @param nodeTypeName
Modified: jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/nodetype/VolatileNodeTypeDataManager.java
===================================================================
--- jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/nodetype/VolatileNodeTypeDataManager.java 2009-10-02 15:39:44 UTC (rev 197)
+++ jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/nodetype/VolatileNodeTypeDataManager.java 2009-10-02 15:41:14 UTC (rev 198)
@@ -20,13 +20,11 @@
import org.exoplatform.services.jcr.core.nodetype.NodeTypeData;
import org.exoplatform.services.jcr.datamodel.InternalQName;
-import org.exoplatform.services.jcr.impl.core.query.QueryHandler;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import java.util.Collection;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.Map;
import javax.jcr.RepositoryException;
@@ -43,9 +41,10 @@
public VolatileNodeTypeDataManager(NodeTypeDataManagerImpl nodeTypeDataManagerImpl) throws RepositoryException
{
super(nodeTypeDataManagerImpl.accessControlPolicy, nodeTypeDataManagerImpl.locationFactory,
- nodeTypeDataManagerImpl.namespaceRegistry, nodeTypeDataManagerImpl.persister);
+ nodeTypeDataManagerImpl.namespaceRegistry, nodeTypeDataManagerImpl.persister,
+ nodeTypeDataManagerImpl.indexSearcherHolder);
this.superNodeTypeDataManager = nodeTypeDataManagerImpl;
- this.queryHandlers = new HashSet<QueryHandler>(nodeTypeDataManagerImpl.queryHandlers);
+ //this.queryHandlers = new HashSet<QueryHandler>(nodeTypeDataManagerImpl.queryHandlers);
registerVolatileNodeTypes(superNodeTypeDataManager.getAllNodeTypes());
}
Modified: jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/ErrorLog.java
===================================================================
--- jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/ErrorLog.java 2009-10-02 15:39:44 UTC (rev 197)
+++ jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/ErrorLog.java 2009-10-02 15:41:14 UTC (rev 198)
@@ -17,6 +17,9 @@
package org.exoplatform.services.jcr.impl.core.query;
+import org.exoplatform.services.log.ExoLogger;
+import org.exoplatform.services.log.Log;
+
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
@@ -31,253 +34,204 @@
import java.util.List;
import java.util.Set;
-import org.exoplatform.services.log.Log;
-
-import org.exoplatform.services.log.ExoLogger;
-
/**
- * All changes that must be in index but interrupted by IOException are here. Created by The eXo
- * Platform SAS Author : Sergey Karpenko <sergey.karpenko at exoplatform.com.ua>
+ * All changes that must be in index but interrupted by IOException are here.
+ * Created by The eXo Platform SAS Author : Sergey Karpenko
+ * <sergey.karpenko at exoplatform.com.ua>
*
* @version $Id: $
*/
-public class ErrorLog
-{
- public static final int DEFAULT_FILE_SIZE = 50; // Kb
+public class ErrorLog {
- /**
- * Logger instance for this class
- */
- private static final Log LOG = ExoLogger.getLogger(ErrorLog.class);
+ /**
+ * Logger instance for this class
+ */
+ private static final Log LOG = ExoLogger.getLogger(ErrorLog.class);
- /**
- * REMOVE term.
- */
- public static final String REMOVE = "rem";
+ /**
+ * REMOVE term.
+ */
+ public static final String REMOVE = "rem";
- /**
- * ADD term.
- */
- public static final String ADD = "add";
+ /**
+ * ADD term.
+ */
+ public static final String ADD = "add";
- /**
- * The log file
- */
- private final File logFile;
+ /**
+ * The log file
+ */
+ private final File logFile;
- /**
- * Writer to the log file
- */
- private FileChannel out;
+ /**
+ * Writer to the log file
+ */
+ private FileChannel out;
- /**
- * File size in Kb. Used on create and clear(truncate) methods.
- */
- private int fileSize = DEFAULT_FILE_SIZE; // Kb
+ /**
+ * File size in Kb. Used on create and clear(truncate) methods.
+ */
+ private int fileSize = 0; // Kb
- /**
- * ErrorLog constructor.
- *
- * @param file
- * @throws IOException
- */
- public ErrorLog(File file) throws IOException
- {
- logFile = file;
- openFile(file);
- }
+ /**
+ * ErrorLog constructor.
+ *
+ * @param file
+ * @param errorLogSize
+ * @throws IOException
+ */
+ public ErrorLog(File file, int errorLogSize) throws IOException {
+ fileSize = errorLogSize;
+ logFile = file;
+ openFile(file);
+ }
- /**
- * ErrorLog constructor.
- *
- * @param file
- * @param errorLogSize
- * @throws IOException
- */
- public ErrorLog(File file, int errorLogSize) throws IOException
- {
- fileSize = errorLogSize;
- logFile = file;
- openFile(file);
- }
+ /**
+ * openFile.
+ *
+ * @param log
+ * @throws IOException
+ */
+ private void openFile(File log) throws IOException {
+ // set file size;
+ if (!log.exists()) {
+ log.getParentFile().mkdirs();
+ log.createNewFile();
- /**
- * openFile.
- *
- * @param log
- * @throws IOException
- */
- private void openFile(File log) throws IOException
- {
- // set file size;
- if (!log.exists())
- {
- log.getParentFile().mkdirs();
- log.createNewFile();
+ out = new FileOutputStream(log).getChannel();
+ out.position(1024 * fileSize - 1);
+ out.write(ByteBuffer.wrap(new byte[] { 0 }));
+ out.position(0);
+ out.force(false);
+ } else {
+ out = new FileOutputStream(log, true).getChannel();
+ }
+ }
- out = new FileOutputStream(log).getChannel();
- out.position(1024 * fileSize - 1);
- out.write(ByteBuffer.wrap(new byte[]{0}));
- out.position(0);
- out.force(false);
- }
- else
- {
- out = new FileOutputStream(log, true).getChannel();
- }
- }
+ /**
+ * Appends an action to the log.
+ *
+ * @param action
+ * the action to append.
+ * @throws IOException
+ * if the node cannot be written to the redo log.
+ */
+ public void append(String action, String uuid) throws IOException {
+ initOut();
+ out.write(ByteBuffer.wrap((action + " " + uuid + "\n").getBytes()));
+ }
- /**
- * Appends an action to the log.
- *
- * @param action
- * the action to append.
- * @throws IOException
- * if the node cannot be written to the redo log.
- */
- public void append(String action, String uuid) throws IOException
- {
- initOut();
- out.write(ByteBuffer.wrap((action + " " + uuid + "\n").getBytes()));
- }
+ /**
+ * Flushes all pending writes to the underlying file.
+ *
+ * @throws IOException
+ * if an error occurs while writing.
+ */
+ public void flush() throws IOException {
+ if (out != null) {
+ out.force(false);
+ }
+ }
- /**
- * Flushes all pending writes to the underlying file.
- *
- * @throws IOException
- * if an error occurs while writing.
- */
- public void flush() throws IOException
- {
- if (out != null)
- {
- out.force(false);
- }
- }
+ /**
+ * Clears the redo log.
+ *
+ * @throws IOException
+ * if the redo log cannot be cleared.
+ */
+ public void clear() throws IOException {
+ if (out != null) {
+ out.truncate(0);
+ out.close();
+ out = new FileOutputStream(logFile).getChannel();
+ out.position(1024 * fileSize - 1);
+ out.write(ByteBuffer.wrap(new byte[] { 0 }));
+ out.position(0);
+ out.force(false);
+ }
+ }
- /**
- * Clears the redo log.
- *
- * @throws IOException
- * if the redo log cannot be cleared.
- */
- public void clear() throws IOException
- {
- if (out != null)
- {
- out.truncate(0);
- out.close();
- out = new FileOutputStream(logFile).getChannel();
- out.position(1024 * fileSize - 1);
- out.write(ByteBuffer.wrap(new byte[]{0}));
- out.position(0);
- out.force(false);
- }
- }
+ /**
+ * Initializes the {@link #out} stream if it is not yet set.
+ *
+ * @throws IOException
+ * if an error occurs while creating the output stream.
+ */
+ private void initOut() throws IOException {
+ if (out == null) {
+ FileOutputStream os = new FileOutputStream(logFile, false);
+ out = os.getChannel();
+ }
+ }
- /**
- * Initializes the {@link #out} stream if it is not yet set.
- *
- * @throws IOException
- * if an error occurs while creating the output stream.
- */
- private void initOut() throws IOException
- {
- if (out == null)
- {
- FileOutputStream os = new FileOutputStream(logFile, false);
- out = os.getChannel();
- }
- }
+ /**
+ * Reads the log file .
+ *
+ * @throws IOException
+ * if an error occurs while reading from the log file.
+ */
+ public List<String> readList() throws IOException {
+ InputStream in = new FileInputStream(logFile);
+ try {
+ List<String> list = new ArrayList<String>();
+ BufferedReader reader = new BufferedReader(
+ new InputStreamReader(in));
+ String line;
+ while ((line = reader.readLine()) != null) {
+ if (!line.matches("\\x00++")) {
+ list.add(line);
+ }
+ }
+ return list;
- /**
- * Reads the log file .
- *
- * @throws IOException
- * if an error occurs while reading from the log file.
- */
- public List<String> readList() throws IOException
- {
- InputStream in = new FileInputStream(logFile);
- try
- {
- List<String> list = new ArrayList<String>();
- BufferedReader reader = new BufferedReader(new InputStreamReader(in));
- String line;
- while ((line = reader.readLine()) != null)
- {
- if (!line.matches("\\x00++"))
- {
- list.add(line);
- }
- }
- return list;
+ } finally {
+ if (in != null) {
+ try {
+ in.close();
+ } catch (IOException e) {
+ LOG.warn("Exception while closing error log: "
+ + e.toString());
+ }
+ }
+ }
+ }
- }
- finally
- {
- if (in != null)
- {
- try
- {
- in.close();
- }
- catch (IOException e)
- {
- LOG.warn("Exception while closing error log: " + e.toString());
- }
- }
- }
- }
+ public void readChanges(Set<String> rem, Set<String> add)
+ throws IOException {
+ List<String> list = readList();
- public void readChanges(Set<String> rem, Set<String> add) throws IOException
- {
- List<String> list = readList();
+ Iterator<String> it = list.iterator();
+ while (it.hasNext()) {
+ String[] str = it.next().split(" ");
+ if (str.length == 2) {
+ if (str[0].equals(ADD)) {
+ add.add(str[1]);
+ } else if (str[0].equals(REMOVE)) {
+ rem.add(str[1]);
+ }
+ }
+ }
+ }
- Iterator<String> it = list.iterator();
- while (it.hasNext())
- {
- String[] str = it.next().split(" ");
- if (str.length == 2)
- {
- if (str[0].equals(ADD))
- {
- add.add(str[1]);
- }
- else if (str[0].equals(REMOVE))
- {
- rem.add(str[1]);
- }
- }
- }
- }
+ public void writeChanges(Set<String> removed, Set<String> added)
+ throws IOException {
+ try {
+ if (!removed.isEmpty()) {
+ Iterator<String> rem = removed.iterator();
+ while (rem.hasNext()) {
+ append(ErrorLog.REMOVE, rem.next());
+ }
+ }
+ if (!added.isEmpty()) {
+ Iterator<String> add = added.iterator();
+ while (add.hasNext()) {
+ append(ErrorLog.ADD, add.next());
+ }
+ }
+ } finally {
+ flush();
+ }
+ }
- public void writeChanges(Set<String> removed, Set<String> added) throws IOException
- {
- try
- {
- if (!removed.isEmpty())
- {
- Iterator<String> rem = removed.iterator();
- while (rem.hasNext())
- {
- append(ErrorLog.REMOVE, rem.next());
- }
- }
- if (!added.isEmpty())
- {
- Iterator<String> add = added.iterator();
- while (add.hasNext())
- {
- append(ErrorLog.ADD, add.next());
- }
- }
- }
- finally
- {
- flush();
- }
- }
-
}
Added: jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/IndexException.java
===================================================================
--- jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/IndexException.java (rev 0)
+++ jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/IndexException.java 2009-10-02 15:41:14 UTC (rev 198)
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.exoplatform.services.jcr.impl.core.query;
+
+import org.exoplatform.services.log.ExoLogger;
+import org.exoplatform.services.log.Log;
+
+import javax.jcr.RepositoryException;
+
+/**
+ * Created by The eXo Platform SAS.
+ *
+ * @author <a href="mailto:Sergey.Kabashnyuk at gmail.com">Sergey Kabashnyuk</a>
+ * @version $Id: $
+ */
+public class IndexException extends RepositoryException
+{
+ /**
+ *
+ */
+ private static final long serialVersionUID = 2247843831064852072L;
+
+ /**
+ * Class logger.
+ */
+ private static final Log LOG = ExoLogger.getLogger(IndexException.class);
+
+ /**
+ *
+ */
+ public IndexException()
+ {
+ super();
+ }
+
+ /**
+ * @param message
+ * @param cause
+ */
+ public IndexException(String message, Throwable cause)
+ {
+ super(message, cause);
+ }
+
+ /**
+ * @param message
+ */
+ public IndexException(String message)
+ {
+ super(message);
+ }
+
+ /**
+ * @param cause
+ */
+ public IndexException(Throwable cause)
+ {
+ super(cause);
+ }
+}
Property changes on: jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/IndexException.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified: jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/QueryHandlerContext.java
===================================================================
--- jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/QueryHandlerContext.java 2009-10-02 15:39:44 UTC (rev 197)
+++ jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/QueryHandlerContext.java 2009-10-02 15:41:14 UTC (rev 198)
@@ -21,6 +21,7 @@
import org.exoplatform.services.jcr.dataflow.ItemDataConsumer;
import org.exoplatform.services.jcr.impl.core.NamespaceRegistryImpl;
import org.exoplatform.services.jcr.impl.core.nodetype.NodeTypeDataManagerImpl;
+import org.exoplatform.services.jcr.impl.core.query.lucene.LuceneVirtualTableResolver;
/**
* Acts as an argument for the {@link QueryHandler} to keep the interface
@@ -68,6 +69,8 @@
private final boolean createInitialIndex;
+ private final LuceneVirtualTableResolver virtualTableResolver;
+
/**
* Creates a new context instance.
*
@@ -86,6 +89,7 @@
* @param parentHandler
* the parent query handler or <code>null</code> it there is no
* parent handler.
+ * @param virtualTableResolver
* @param excludedNodeId
* id of the node that should be excluded from indexing. Any
* descendant of that node is also excluded from indexing.
@@ -94,7 +98,8 @@
IndexingTree indexingTree, NodeTypeDataManager nodeTypeDataManager,
NamespaceRegistryImpl nsRegistry, QueryHandler parentHandler,
String indexDirectory, DocumentReaderService extractor,
- boolean createInitialIndex) {
+ boolean createInitialIndex,
+ LuceneVirtualTableResolver virtualTableResolver) {
this.stateMgr = stateMgr;
this.indexingTree = indexingTree;
this.nodeTypeDataManager = nodeTypeDataManager;
@@ -102,6 +107,7 @@
this.indexDirectory = indexDirectory;
this.extractor = extractor;
this.createInitialIndex = createInitialIndex;
+ this.virtualTableResolver = virtualTableResolver;
this.propRegistry = new PropertyTypeRegistry(nodeTypeDataManager);
this.parentHandler = parentHandler;
((NodeTypeDataManagerImpl) this.nodeTypeDataManager)
@@ -109,6 +115,13 @@
}
/**
+ * @return the virtualTableResolver
+ */
+ public LuceneVirtualTableResolver getVirtualTableResolver() {
+ return virtualTableResolver;
+ }
+
+ /**
* @return the createInitialIndex
*/
public boolean isCreateInitialIndex() {
Added: jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/RepositoryIndexSearcherHolder.java
===================================================================
--- jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/RepositoryIndexSearcherHolder.java (rev 0)
+++ jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/RepositoryIndexSearcherHolder.java 2009-10-02 15:41:14 UTC (rev 198)
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.exoplatform.services.jcr.impl.core.query;
+
+import org.exoplatform.services.jcr.datamodel.InternalQName;
+import org.exoplatform.services.log.ExoLogger;
+import org.exoplatform.services.log.Log;
+import org.picocontainer.Startable;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.jcr.RepositoryException;
+
+/**
+ * Created by The eXo Platform SAS.
+ *
+ * @author <a href="mailto:Sergey.Kabashnyuk at gmail.com">Sergey Kabashnyuk</a>
+ * @version $Id: $
+ */
+public class RepositoryIndexSearcherHolder implements Startable {
+ private final List<SearchManager> indexSearchers;
+
+ /**
+ * Class logger.
+ */
+ private final Log log = ExoLogger
+ .getLogger(RepositoryIndexSearcherHolder.class);
+
+ /**
+ * @param indexSearchers
+ */
+ public RepositoryIndexSearcherHolder() {
+ super();
+ this.indexSearchers = new ArrayList<SearchManager>();
+ }
+
+ /**
+ * @return the indexSearchers
+ */
+ public void addIndexSearcher(final SearchManager indexSearcher) {
+ this.indexSearchers.add(indexSearcher);
+ }
+
+ /**
+ * @return
+ * @throws IndexException
+ */
+ public Set<String> getFieldNames() throws IndexException {
+ final Set<String> fildsSet = new HashSet<String>();
+
+ for (final SearchManager queryHandler : this.indexSearchers) {
+
+ fildsSet.addAll(queryHandler.getFieldNames());
+ }
+ return fildsSet;
+ }
+
+ public Set<String> getNodesByNodeType(final InternalQName nodeType)
+ throws RepositoryException {
+ final Set<String> result = new HashSet<String>();
+ for (final SearchManager indexingService : this.indexSearchers) {
+ result.addAll(indexingService.getNodesByNodeType(nodeType));
+ }
+
+ return result;
+ }
+
+ /**
+ * @param uri
+ * @return
+ * @throws RepositoryException
+ */
+ public Set<String> getNodesByUri(final String uri)
+ throws RepositoryException {
+ final Set<String> result = new HashSet<String>();
+ for (final SearchManager indexingService : this.indexSearchers) {
+ result.addAll(indexingService.getNodesByUri(uri));
+ }
+
+ return result;
+ }
+
+ /**
+ * @return the indexSearchers
+ */
+ public void removeIndexSearcher(final SearchManager indexSearcher) {
+ this.indexSearchers.remove(indexSearcher);
+ }
+
+ public void start() {
+ }
+
+ public void stop() {
+ this.indexSearchers.clear();
+ }
+}
Property changes on: jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/RepositoryIndexSearcherHolder.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified: jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SearchIndexConfigurationHelper.java
===================================================================
--- jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SearchIndexConfigurationHelper.java 2009-10-02 15:39:44 UTC (rev 197)
+++ jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SearchIndexConfigurationHelper.java 2009-10-02 15:41:14 UTC (rev 198)
@@ -19,7 +19,9 @@
package org.exoplatform.services.jcr.impl.core.query;
import org.exoplatform.services.jcr.config.QueryHandlerEntry;
+import org.exoplatform.services.jcr.config.QueryHandlerParams;
import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
+import org.exoplatform.services.jcr.config.SimpleParameterEntry;
import org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex;
import java.io.IOException;
@@ -42,9 +44,93 @@
this.searchIndex = searchIndex;
}
+ /**
+ * Initialize parameters
+ *
+ * @param queryHandlerEntry
+ * @throws IOException
+ * @throws RepositoryConfigurationException
+ */
public void init(QueryHandlerEntry queryHandlerEntry) throws IOException,
RepositoryConfigurationException {
// Path will be set using queryHandelContext
+ for (SimpleParameterEntry parameter : queryHandlerEntry.getParameters()) {
+ setParam(parameter.getName(), parameter.getValue());
+ }
+
}
+
+ /**
+ * @param name
+ * @param value
+ */
+ private void setParam(String name, String value) {
+
+ if (QueryHandlerParams.PARAM_AUTO_REPAIR.equals(name))
+ searchIndex.setAutoRepair(Boolean.parseBoolean(value));
+ else if (QueryHandlerParams.PARAM_BUFFER_SIZE.equals(name))
+ searchIndex.setBufferSize(Integer.parseInt(value));
+ else if (QueryHandlerParams.PARAM_CACHE_SIZE.equals(name))
+ searchIndex.setCacheSize(Integer.parseInt(value));
+ else if (QueryHandlerParams.PARAM_CONSISTENCY_CHECK_ENABLED
+ .equals(name))
+ searchIndex.setEnableConsistencyCheck(Boolean.parseBoolean(value));
+ else if (QueryHandlerParams.PARAM_DOCUMENT_ORDER.equals(name))
+ searchIndex.setRespectDocumentOrder(Boolean.parseBoolean(value));
+ else if (QueryHandlerParams.PARAM_EXCERPTPROVIDER_CLASS.equals(name))
+ searchIndex.setExcerptProviderClass(value);
+ // else if
+ // (QueryHandlerParams.PARAM_EXCLUDED_NODE_IDENTIFERS.equals(name))
+ // searchIndex.setE
+ else if (QueryHandlerParams.PARAM_EXTRACTOR_BACKLOG.equals(name))
+ searchIndex.setExtractorBackLogSize(Integer.parseInt(value));
+ else if (QueryHandlerParams.PARAM_EXTRACTOR_POOLSIZE.equals(name))
+ searchIndex.setExtractorPoolSize(Integer.parseInt(value));
+ else if (QueryHandlerParams.PARAM_EXTRACTOR_TIMEOUT.equals(name))
+ searchIndex.setExtractorTimeout(Long.parseLong(value));
+ else if (QueryHandlerParams.PARAM_FORCE_CONSISTENCYCHECK.equals(name))
+ searchIndex.setForceConsistencyCheck(Boolean.parseBoolean(value));
+ else if (QueryHandlerParams.PARAM_ERRORLOG_SIZE.equals(name))
+ searchIndex.setErrorLogfileSize(Integer.parseInt(value));
+ // else if (QueryHandlerParams.PARAM_INDEX_DIR.equals(name))
+ // searchIndex.setBufferSize(0);
+ // else if (OLD_PARAM_INDEX_DIR
+ else if (QueryHandlerParams.PARAM_INDEXING_CONFIGURATION_PATH
+ .equals(name))
+ searchIndex.setIndexingConfiguration(value);
+ else if (QueryHandlerParams.PARAM_INDEXING_CONFIGURATION_CLASS
+ .equals(name))
+ searchIndex.setIndexingConfigurationClass(value);
+ else if (QueryHandlerParams.PARAM_MAX_FIELD_LENGTH.equals(name))
+ searchIndex.setMaxFieldLength(Integer.parseInt(value));
+ else if (QueryHandlerParams.PARAM_MAX_MERGE_DOCS.equals(name))
+ searchIndex.setMaxMergeDocs(Integer.parseInt(value));
+ else if (QueryHandlerParams.PARAM_MERGE_FACTOR.equals(name))
+ searchIndex.setMergeFactor(Integer.parseInt(value));
+ else if (QueryHandlerParams.PARAM_MIN_MERGE_DOCS.equals(name))
+ searchIndex.setMinMergeDocs(Integer.parseInt(value));
+ else if (QueryHandlerParams.PARAM_QUERY_CLASS.equals(name))
+ searchIndex.setQueryClass(value);
+ else if (QueryHandlerParams.PARAM_RESULT_FETCH_SIZE.equals(name))
+ searchIndex.setResultFetchSize(Integer.parseInt(value));
+ // else if (QueryHandlerParams.PARAM_ROOT_NODE_ID.equals(name))
+ // searchIndex.setBufferSize(0);
+ else if (QueryHandlerParams.PARAM_SPELLCHECKER_CLASS.equals(name))
+ searchIndex.setSpellCheckerClass(value);
+ else if (QueryHandlerParams.PARAM_SUPPORT_HIGHLIGHTING.equals(name))
+ searchIndex.setSupportHighlighting(Boolean.parseBoolean(value));
+ else if (QueryHandlerParams.PARAM_SYNONYMPROVIDER_CLASS.equals(name))
+ searchIndex.setSynonymProviderClass(value);
+ else if (QueryHandlerParams.PARAM_SYNONYMPROVIDER_CONFIG_PATH
+ .equals(name))
+ searchIndex.setSynonymProviderConfigPath(value);
+ else if (QueryHandlerParams.PARAM_USE_COMPOUNDFILE.equals(name))
+ searchIndex.setUseCompoundFile(Boolean.parseBoolean(value));
+ else if (QueryHandlerParams.PARAM_VOLATILE_IDLE_TIME.equals(name))
+ searchIndex.setVolatileIdleTime(Integer.parseInt(value));
+ // else if (QueryHandlerParams.PARAM_UPGRADE_INDEX.equals(name))
+ // searchIndex.i
+
+ }
}
Modified: jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SearchManager.java
===================================================================
--- jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SearchManager.java 2009-10-02 15:39:44 UTC (rev 197)
+++ jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SearchManager.java 2009-10-02 15:41:14 UTC (rev 198)
@@ -16,6 +16,11 @@
*/
package org.exoplatform.services.jcr.impl.core.query;
+import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.search.BooleanQuery;
+import org.apache.lucene.search.WildcardQuery;
+import org.apache.lucene.search.BooleanClause.Occur;
import org.exoplatform.container.configuration.ConfigurationManager;
import org.exoplatform.services.document.DocumentReaderService;
import org.exoplatform.services.jcr.config.QueryHandlerEntry;
@@ -26,13 +31,26 @@
import org.exoplatform.services.jcr.dataflow.ItemState;
import org.exoplatform.services.jcr.dataflow.ItemStateChangesLog;
import org.exoplatform.services.jcr.dataflow.persistent.MandatoryItemsPersistenceListener;
+import org.exoplatform.services.jcr.datamodel.InternalQName;
import org.exoplatform.services.jcr.datamodel.ItemData;
import org.exoplatform.services.jcr.datamodel.NodeData;
+import org.exoplatform.services.jcr.datamodel.PropertyData;
import org.exoplatform.services.jcr.datamodel.QPath;
+import org.exoplatform.services.jcr.datamodel.ValueData;
import org.exoplatform.services.jcr.impl.Constants;
+import org.exoplatform.services.jcr.impl.core.LocationFactory;
import org.exoplatform.services.jcr.impl.core.NamespaceRegistryImpl;
import org.exoplatform.services.jcr.impl.core.SessionDataManager;
import org.exoplatform.services.jcr.impl.core.SessionImpl;
+import org.exoplatform.services.jcr.impl.core.query.lucene.FieldNames;
+import org.exoplatform.services.jcr.impl.core.query.lucene.LuceneVirtualTableResolver;
+import org.exoplatform.services.jcr.impl.core.query.lucene.QueryHits;
+import org.exoplatform.services.jcr.impl.core.query.lucene.ScoreNode;
+import org.exoplatform.services.jcr.impl.core.query.lucene.SearchIndex;
+import org.exoplatform.services.jcr.impl.core.value.NameValue;
+import org.exoplatform.services.jcr.impl.core.value.PathValue;
+import org.exoplatform.services.jcr.impl.core.value.ValueFactoryImpl;
+import org.exoplatform.services.jcr.impl.dataflow.AbstractValueData;
import org.exoplatform.services.jcr.impl.dataflow.persistent.WorkspacePersistentDataManager;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
@@ -42,6 +60,7 @@
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -52,7 +71,9 @@
import java.util.StringTokenizer;
import javax.jcr.Node;
+import javax.jcr.PropertyType;
import javax.jcr.RepositoryException;
+import javax.jcr.Value;
import javax.jcr.query.InvalidQueryException;
import javax.jcr.query.Query;
@@ -108,6 +129,8 @@
private final ConfigurationManager cfm;
+ protected LuceneVirtualTableResolver virtualTableResolver;
+
/**
* Creates a new <code>SearchManager</code>.
*
@@ -134,17 +157,19 @@
public SearchManager(QueryHandlerEntry config, NamespaceRegistryImpl nsReg,
NodeTypeDataManager ntReg, WorkspacePersistentDataManager itemMgr,
SystemSearchManagerHolder parentSearchManager,
- DocumentReaderService extractor, ConfigurationManager cfm)
+ DocumentReaderService extractor, ConfigurationManager cfm,
+ final RepositoryIndexSearcherHolder indexSearcherHolder)
throws RepositoryException, RepositoryConfigurationException {
this.extractor = extractor;
-
+ indexSearcherHolder.addIndexSearcher(this);
this.config = new QueryHandlerEntryWrapper(config);
this.nodeTypeDataManager = ntReg;
this.nsReg = nsReg;
this.itemMgr = itemMgr;
this.cfm = cfm;
-
+ this.virtualTableResolver = new LuceneVirtualTableResolver(
+ nodeTypeDataManager, nsReg);
this.parentSearchManager = parentSearchManager != null ? parentSearchManager
.get()
: null;
@@ -465,7 +490,7 @@
QueryHandlerContext context = new QueryHandlerContext(itemMgr,
indexingTree, nodeTypeDataManager, nsReg, parentHandler, config
- .getIndexDir(), extractor, true);
+ .getIndexDir(), extractor, true, virtualTableResolver);
return context;
}
@@ -543,4 +568,178 @@
}
}
+ /**
+ * {@inheritDoc}
+ */
+ public Set<String> getFieldNames() throws IndexException {
+ final Set<String> fildsSet = new HashSet<String>();
+ if (handler instanceof SearchIndex) {
+ IndexReader reader = null;
+ try {
+ reader = ((SearchIndex) handler).getIndexReader();
+ final Collection fields = reader
+ .getFieldNames(IndexReader.FieldOption.ALL);
+ for (final Object field : fields) {
+ fildsSet.add((String) field);
+ }
+ } catch (IOException e) {
+ throw new IndexException(e.getLocalizedMessage(), e);
+ } finally {
+ try {
+ if (reader != null)
+ reader.close();
+ } catch (IOException e) {
+ throw new IndexException(e.getLocalizedMessage(), e);
+ }
+ }
+
+ }
+ return fildsSet;
+ }
+
+ public Set<String> getNodesByNodeType(final InternalQName nodeType)
+ throws RepositoryException {
+
+ return getNodes(virtualTableResolver.resolve(nodeType, true));
+ }
+
+ /**
+ * Return set of uuid of nodes. Contains in names prefixes maped to the
+ * given uri
+ *
+ * @param prefix
+ * @return
+ * @throws RepositoryException
+ */
+ public Set<String> getNodesByUri(final String uri)
+ throws RepositoryException {
+ Set<String> result;
+ final int defaultClauseCount = BooleanQuery.getMaxClauseCount();
+ try {
+
+ // final LocationFactory locationFactory = new
+ // LocationFactory(this);
+ final ValueFactoryImpl valueFactory = new ValueFactoryImpl(
+ new LocationFactory(nsReg));
+ BooleanQuery.setMaxClauseCount(Integer.MAX_VALUE);
+ BooleanQuery query = new BooleanQuery();
+
+ final String prefix = nsReg.getNamespacePrefixByURI(uri);
+ query.add(new WildcardQuery(new Term(FieldNames.LABEL, prefix
+ + ":*")), Occur.SHOULD);
+ // name of the property
+ query.add(new WildcardQuery(new Term(FieldNames.PROPERTIES_SET,
+ prefix + ":*")), Occur.SHOULD);
+
+ result = getNodes(query);
+
+ // value of the property
+
+ try {
+ final Set<String> props = getFieldNames();
+
+ query = new BooleanQuery();
+ for (final String fieldName : props) {
+ if (!FieldNames.PROPERTIES_SET.equals(fieldName)) {
+ query.add(new WildcardQuery(new Term(fieldName, "*"
+ + prefix + ":*")), Occur.SHOULD);
+ }
+ }
+ } catch (final IndexException e) {
+ throw new RepositoryException(e.getLocalizedMessage(), e);
+ }
+
+ final Set<String> propSet = getNodes(query);
+ // Manually check property values;
+ for (final String uuid : propSet) {
+ if (isPrefixMatch(valueFactory, uuid, prefix)) {
+ result.add(uuid);
+ }
+ }
+ } finally {
+ BooleanQuery.setMaxClauseCount(defaultClauseCount);
+ }
+
+ return result;
+ }
+
+ private boolean isPrefixMatch(final InternalQName value, final String prefix)
+ throws RepositoryException {
+ return value.getNamespace().equals(
+ nsReg.getNamespaceURIByPrefix(prefix));
+ }
+
+ private boolean isPrefixMatch(final QPath value, final String prefix)
+ throws RepositoryException {
+ for (int i = 0; i < value.getEntries().length; i++) {
+ if (isPrefixMatch(value.getEntries()[i], prefix)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * @param valueFactory
+ * @param dm
+ * @param uuid
+ * @param prefix
+ * @throws RepositoryException
+ */
+ private boolean isPrefixMatch(final ValueFactoryImpl valueFactory,
+ final String uuid, final String prefix) throws RepositoryException {
+
+ final ItemData node = itemMgr.getItemData(uuid);
+ if (node != null && node.isNode()) {
+ final List<PropertyData> props = itemMgr
+ .getChildPropertiesData((NodeData) node);
+ for (final PropertyData propertyData : props) {
+ if (propertyData.getType() == PropertyType.PATH
+ || propertyData.getType() == PropertyType.NAME) {
+ for (final ValueData vdata : propertyData.getValues()) {
+ final Value val = valueFactory.loadValue(
+ ((AbstractValueData) vdata)
+ .createTransientCopy(), propertyData
+ .getType());
+ if (propertyData.getType() == PropertyType.PATH) {
+ if (isPrefixMatch(((PathValue) val).getQPath(),
+ prefix)) {
+ return true;
+ }
+ } else if (propertyData.getType() == PropertyType.NAME) {
+ if (isPrefixMatch(((NameValue) val).getQName(),
+ prefix)) {
+ return true;
+ }
+ }
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * @param query
+ * @return
+ * @throws RepositoryException
+ */
+ private Set<String> getNodes(final org.apache.lucene.search.Query query)
+ throws RepositoryException {
+ Set<String> result = new HashSet<String>();
+ try {
+ QueryHits hits = handler.executeQuery(query);
+
+ ScoreNode sn;
+
+ while ((sn = hits.nextScoreNode()) != null) {
+ // Node node = session.getNodeById(sn.getNodeId());
+ result.add(sn.getNodeId());
+ }
+ } catch (IOException e) {
+ throw new RepositoryException(e.getLocalizedMessage(), e);
+ }
+ return result;
+ }
+
}
Modified: jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SystemSearchManager.java
===================================================================
--- jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SystemSearchManager.java 2009-10-02 15:39:44 UTC (rev 197)
+++ jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/SystemSearchManager.java 2009-10-02 15:41:14 UTC (rev 198)
@@ -64,9 +64,11 @@
public SystemSearchManager(QueryHandlerEntry config,
NamespaceRegistryImpl nsReg, NodeTypeDataManager ntReg,
WorkspacePersistentDataManager itemMgr,
- DocumentReaderService service, ConfigurationManager cfm)
+ DocumentReaderService service, ConfigurationManager cfm,
+ RepositoryIndexSearcherHolder indexSearcherHolder)
throws RepositoryException, RepositoryConfigurationException {
- super(config, nsReg, ntReg, itemMgr, null, service, cfm);
+ super(config, nsReg, ntReg, itemMgr, null, service, cfm,
+ indexSearcherHolder);
}
@Override
@@ -124,7 +126,7 @@
.getIndexDir()
+ "_" + INDEX_DIR_SUFFIX, extractor, changesLogBuffer
.size() > 0
- && !isStarted);
+ && !isStarted, virtualTableResolver);
return context;
}
}
Modified: jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/IndexingConfigurationEntityResolver.java
===================================================================
--- jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/IndexingConfigurationEntityResolver.java 2009-10-02 15:39:44 UTC (rev 197)
+++ jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/IndexingConfigurationEntityResolver.java 2009-10-02 15:41:14 UTC (rev 198)
@@ -16,16 +16,16 @@
*/
package org.exoplatform.services.jcr.impl.core.query.lucene;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
-import org.xml.sax.EntityResolver;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-
/**
* <code>IndexingConfigurationEntityResolver</code> implements an entity
* resolver for the indexing configuration DTD.
@@ -35,34 +35,37 @@
/**
* Maps system ids to DTD resource names.
*/
- private static final Map SYSTEM_IDS;
+ private static final Map<String, String> SYSTEM_IDS;
static {
- Map systemIds = new HashMap();
- systemIds.put(
- "http://jackrabbit.apache.org/dtd/indexing-configuration-1.0.dtd",
- "indexing-configuration-1.0.dtd");
- systemIds.put(
- "http://jackrabbit.apache.org/dtd/indexing-configuration-1.1.dtd",
- "indexing-configuration-1.1.dtd");
- systemIds.put(
- "http://jackrabbit.apache.org/dtd/indexing-configuration-1.2.dtd",
- "indexing-configuration-1.2.dtd");
- SYSTEM_IDS = Collections.unmodifiableMap(systemIds);
+ Map<String, String> systemIds = new HashMap<String, String>();
+ systemIds
+ .put(
+ "http://www.exoplatform.org/dtd/indexing-configuration-1.0.dtd",
+ "indexing-configuration-1.0.dtd");
+ systemIds
+ .put(
+ "http://www.exoplatform.org/dtd/indexing-configuration-1.1.dtd",
+ "indexing-configuration-1.1.dtd");
+ systemIds
+ .put(
+ "http://www.exoplatform.org/dtd/indexing-configuration-1.2.dtd",
+ "indexing-configuration-1.2.dtd");
+ SYSTEM_IDS = Collections.unmodifiableMap(systemIds);
}
/**
* {@inheritDoc}
*/
public InputSource resolveEntity(String publicId, String systemId)
- throws SAXException, IOException {
- String resourceName = (String) SYSTEM_IDS.get(systemId);
- if (resourceName != null) {
- InputStream in = getClass().getResourceAsStream(resourceName);
- if (in != null) {
- return new InputSource(in);
- }
- }
- return null;
+ throws SAXException, IOException {
+ String resourceName = SYSTEM_IDS.get(systemId);
+ if (resourceName != null) {
+ InputStream in = getClass().getResourceAsStream(resourceName);
+ if (in != null) {
+ return new InputSource(in);
+ }
+ }
+ return null;
}
}
Modified: jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/IndexingConfigurationImpl.java
===================================================================
--- jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/IndexingConfigurationImpl.java 2009-10-02 15:39:44 UTC (rev 197)
+++ jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/IndexingConfigurationImpl.java 2009-10-02 15:41:14 UTC (rev 198)
@@ -16,22 +16,6 @@
*/
package org.exoplatform.services.jcr.impl.core.query.lucene;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.NoSuchElementException;
-import java.util.Properties;
-
-import javax.jcr.NamespaceException;
-import javax.jcr.PropertyType;
-import javax.jcr.RepositoryException;
-
-import org.apache.commons.collections.iterators.AbstractIteratorDecorator;
import org.apache.lucene.analysis.Analyzer;
import org.exoplatform.services.jcr.core.NamespaceAccessor;
import org.exoplatform.services.jcr.core.nodetype.NodeTypeData;
@@ -49,7 +33,6 @@
import org.exoplatform.services.jcr.impl.core.query.AdditionalNamespaceResolver;
import org.exoplatform.services.jcr.impl.core.query.QueryHandlerContext;
import org.exoplatform.services.jcr.impl.core.query.misc.Pattern;
-
import org.exoplatform.services.jcr.impl.util.ISO9075;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -60,1088 +43,1038 @@
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+
/**
* <code>IndexingConfigurationImpl</code> implements a concrete indexing
* configuration.
*/
-public class IndexingConfigurationImpl implements IndexingConfiguration
-{
+public class IndexingConfigurationImpl implements IndexingConfiguration {
- /**
- * The logger instance for this class
- */
- private static final Logger log = LoggerFactory.getLogger(IndexingConfigurationImpl.class);
+ /**
+ * The logger instance for this class
+ */
+ private static final Logger log = LoggerFactory
+ .getLogger(IndexingConfigurationImpl.class);
- /**
- * The path factory instance.
- */
- //private static final PathFactory PATH_FACTORY = PathFactoryImpl.getInstance();
- /**
- * A namespace resolver for parsing QNames in the configuration.
- */
- private LocationFactory resolver;
+ /**
+ * The path factory instance.
+ */
+ // private static final PathFactory PATH_FACTORY =
+ // PathFactoryImpl.getInstance();
+ /**
+ * A namespace resolver for parsing QNames in the configuration.
+ */
+ private LocationFactory resolver;
- /**
- * The item state manager to retrieve additional item states.
- */
- private ItemDataConsumer ism;
+ /**
+ * The item state manager to retrieve additional item states.
+ */
+ private ItemDataConsumer ism;
- /**
- * A hierarchy resolver for the item state manager.
- */
- // private HierarchyManager hmgr;
- /**
- * The {@link IndexingRule}s inside this configuration.
- */
- private Map configElements = new HashMap();
+ /**
+ * A hierarchy resolver for the item state manager.
+ */
+ // private HierarchyManager hmgr;
+ /**
+ * The {@link IndexingRule}s inside this configuration.
+ */
+ private Map<InternalQName, List<IndexingRule>> configElements = new HashMap<InternalQName, List<IndexingRule>>();
- /**
- * The indexing aggregates inside this configuration.
- */
- private AggregateRule[] aggregateRules;
+ /**
+ * The indexing aggregates inside this configuration.
+ */
+ private AggregateRule[] aggregateRules;
- /**
- * The configured analyzers for indexing properties.
- */
- private Map analyzers = new HashMap();
+ /**
+ * The configured analyzers for indexing properties.
+ */
+ private Map<String, Analyzer> analyzers = new HashMap<String, Analyzer>();
- /**
- * {@inheritDoc}
- */
- public void init(Element config, QueryHandlerContext context, NamespaceMappings nsMappings) throws Exception
- {
- ism = context.getItemStateManager();
+ /**
+ * {@inheritDoc}
+ */
+ public void init(Element config, QueryHandlerContext context,
+ NamespaceMappings nsMappings) throws Exception {
+ ism = context.getItemStateManager();
- NamespaceAccessor nsResolver = new AdditionalNamespaceResolver(getNamespaces(config));
- resolver = new LocationFactory(nsResolver);//new ParsingNameResolver(NameFactoryImpl.getInstance(), nsResolver);
+ NamespaceAccessor nsResolver = new AdditionalNamespaceResolver(
+ getNamespaces(config));
+ resolver = new LocationFactory(nsResolver);// new
+ // ParsingNameResolver(NameFactoryImpl.getInstance(),
+ // nsResolver);
- NodeTypeDataManager ntReg = context.getNodeTypeDataManager();
- List<NodeTypeData> ntNames = ntReg.getAllNodeTypes();
- List idxAggregates = new ArrayList();
- NodeList indexingConfigs = config.getChildNodes();
- for (int i = 0; i < indexingConfigs.getLength(); i++)
- {
- Node configNode = indexingConfigs.item(i);
- if (configNode.getNodeName().equals("index-rule"))
- {
- IndexingRule element = new IndexingRule(configNode);
- // register under node type and all its sub types
- log.debug("Found rule '{}' for NodeType '{}'", element, element.getNodeTypeName());
- for (NodeTypeData nodeTypeData : ntNames)
- {
+ NodeTypeDataManager ntReg = context.getNodeTypeDataManager();
+ List<NodeTypeData> ntNames = ntReg.getAllNodeTypes();
+ List<AggregateRuleImpl> idxAggregates = new ArrayList<AggregateRuleImpl>();
+ NodeList indexingConfigs = config.getChildNodes();
+ for (int i = 0; i < indexingConfigs.getLength(); i++) {
+ Node configNode = indexingConfigs.item(i);
+ if (configNode.getNodeName().equals("index-rule")) {
+ IndexingRule element = new IndexingRule(configNode);
+ // register under node type and all its sub types
+ log.debug("Found rule '{}' for NodeType '{}'", element, element
+ .getNodeTypeName());
+ for (NodeTypeData nodeTypeData : ntNames) {
- if (ntReg.isNodeType(element.getNodeTypeName(), nodeTypeData.getName()))
- {
- List perNtConfig = (List)configElements.get(nodeTypeData);
- if (perNtConfig == null)
- {
- perNtConfig = new ArrayList();
- configElements.put(nodeTypeData, perNtConfig);
- }
- log.debug("Registering it for name '{}'", nodeTypeData);
- perNtConfig.add(new IndexingRule(element, nodeTypeData.getName()));
- }
- }
- }
- else if (configNode.getNodeName().equals("aggregate"))
- {
- idxAggregates.add(new AggregateRuleImpl(configNode, resolver, ism));
- }
- else if (configNode.getNodeName().equals("analyzers"))
- {
- NodeList childNodes = configNode.getChildNodes();
- for (int j = 0; j < childNodes.getLength(); j++)
- {
- Node analyzerNode = childNodes.item(j);
- if (analyzerNode.getNodeName().equals("analyzer"))
- {
- String analyzerClassName = analyzerNode.getAttributes().getNamedItem("class").getNodeValue();
- try
- {
- Class clazz = Class.forName(analyzerClassName);
- if (clazz == JcrStandartAnalyzer.class)
- {
- log.warn("Not allowed to configure " + JcrStandartAnalyzer.class.getName()
- + " for a property. " + "Using default analyzer for that property.");
- }
- else if (Analyzer.class.isAssignableFrom(clazz))
- {
- Analyzer analyzer = (Analyzer)clazz.newInstance();
- NodeList propertyChildNodes = analyzerNode.getChildNodes();
- for (int k = 0; k < propertyChildNodes.getLength(); k++)
- {
- Node propertyNode = propertyChildNodes.item(k);
- if (propertyNode.getNodeName().equals("property"))
- {
- // get property name
- InternalQName propName =
- resolver.parseJCRName(getTextContent(propertyNode)).getInternalName();
- String fieldName = nsMappings.translateName(propName);
- // set analyzer for the fulltext property fieldname
- int idx = fieldName.indexOf(':');
- fieldName =
- fieldName.substring(0, idx + 1) + FieldNames.FULLTEXT_PREFIX
- + fieldName.substring(idx + 1);
- Object prevAnalyzer = analyzers.put(fieldName, analyzer);
- if (prevAnalyzer != null)
- {
- log.warn("Property " + propName.getName()
- + " has been configured for multiple analyzers. "
- + " Last configured analyzer is used");
- }
- }
- }
- }
- else
- {
- log.warn("org.apache.lucene.analysis.Analyzer is not a superclass of " + analyzerClassName
- + ". Ignoring this configure analyzer");
- }
- }
- catch (ClassNotFoundException e)
- {
- log.warn("Analyzer class not found: " + analyzerClassName, e);
- }
- }
- }
- }
+ if (ntReg.isNodeType(element.getNodeTypeName(),
+ nodeTypeData.getName())) {
+ List<IndexingRule> perNtConfig = configElements
+ .get(nodeTypeData);
+ if (perNtConfig == null) {
+ perNtConfig = new ArrayList<IndexingRule>();
+ configElements.put(nodeTypeData.getName(),
+ perNtConfig);
+ }
+ log.debug("Registering it for name '{}'", nodeTypeData);
+ perNtConfig.add(new IndexingRule(element, nodeTypeData
+ .getName()));
+ }
+ }
+ } else if (configNode.getNodeName().equals("aggregate")) {
+ idxAggregates.add(new AggregateRuleImpl(configNode, resolver,
+ ism));
+ } else if (configNode.getNodeName().equals("analyzers")) {
+ NodeList childNodes = configNode.getChildNodes();
+ for (int j = 0; j < childNodes.getLength(); j++) {
+ Node analyzerNode = childNodes.item(j);
+ if (analyzerNode.getNodeName().equals("analyzer")) {
+ String analyzerClassName = analyzerNode.getAttributes()
+ .getNamedItem("class").getNodeValue();
+ try {
+ Class clazz = Class.forName(analyzerClassName);
+ if (clazz == JcrStandartAnalyzer.class) {
+ log
+ .warn("Not allowed to configure "
+ + JcrStandartAnalyzer.class
+ .getName()
+ + " for a property. "
+ + "Using default analyzer for that property.");
+ } else if (Analyzer.class.isAssignableFrom(clazz)) {
+ Analyzer analyzer = (Analyzer) clazz
+ .newInstance();
+ NodeList propertyChildNodes = analyzerNode
+ .getChildNodes();
+ for (int k = 0; k < propertyChildNodes
+ .getLength(); k++) {
+ Node propertyNode = propertyChildNodes
+ .item(k);
+ if (propertyNode.getNodeName().equals(
+ "property")) {
+ // get property name
+ InternalQName propName = resolver
+ .parseJCRName(
+ getTextContent(propertyNode))
+ .getInternalName();
+ String fieldName = nsMappings
+ .translateName(propName);
+ // set analyzer for the fulltext
+ // property fieldname
+ int idx = fieldName.indexOf(':');
+ fieldName = fieldName.substring(0,
+ idx + 1)
+ + FieldNames.FULLTEXT_PREFIX
+ + fieldName.substring(idx + 1);
+ Object prevAnalyzer = analyzers.put(
+ fieldName, analyzer);
+ if (prevAnalyzer != null) {
+ log
+ .warn("Property "
+ + propName
+ .getName()
+ + " has been configured for multiple analyzers. "
+ + " Last configured analyzer is used");
+ }
+ }
+ }
+ } else {
+ log
+ .warn("org.apache.lucene.analysis.Analyzer is not a superclass of "
+ + analyzerClassName
+ + ". Ignoring this configure analyzer");
+ }
+ } catch (ClassNotFoundException e) {
+ log.warn("Analyzer class not found: "
+ + analyzerClassName, e);
+ }
+ }
+ }
+ }
- }
- aggregateRules = (AggregateRule[])idxAggregates.toArray(new AggregateRule[idxAggregates.size()]);
- }
+ }
+ aggregateRules = idxAggregates.toArray(new AggregateRule[idxAggregates
+ .size()]);
+ }
- /**
- * Returns the configured indexing aggregate rules or <code>null</code> if
- * none exist.
- *
- * @return the configured rules or <code>null</code> if none exist.
- */
- public AggregateRule[] getAggregateRules()
- {
- return aggregateRules;
- }
+ /**
+ * Returns the configured indexing aggregate rules or <code>null</code> if
+ * none exist.
+ *
+ * @return the configured rules or <code>null</code> if none exist.
+ */
+ public AggregateRule[] getAggregateRules() {
+ return aggregateRules;
+ }
- /**
- * Returns <code>true</code> if the property with the given name is fulltext
- * indexed according to this configuration.
- *
- * @param state the node state.
- * @param propertyName the name of a property.
- * @return <code>true</code> if the property is fulltext indexed;
- * <code>false</code> otherwise.
- */
- public boolean isIndexed(NodeData state, InternalQName propertyName)
- {
- IndexingRule rule = getApplicableIndexingRule(state);
- if (rule != null)
- {
- return rule.isIndexed(propertyName);
- }
- // none of the configs matches -> index property
- return true;
- }
+ /**
+ * Returns <code>true</code> if the property with the given name is fulltext
+ * indexed according to this configuration.
+ *
+ * @param state
+ * the node state.
+ * @param propertyName
+ * the name of a property.
+ * @return <code>true</code> if the property is fulltext indexed;
+ * <code>false</code> otherwise.
+ */
+ public boolean isIndexed(NodeData state, InternalQName propertyName) {
+ IndexingRule rule = getApplicableIndexingRule(state);
+ if (rule != null) {
+ return rule.isIndexed(propertyName);
+ }
+ // none of the configs matches -> index property
+ return true;
+ }
- /**
- * Returns the boost value for the given property name. If there is no
- * configuration entry for the property name the {@link #DEFAULT_BOOST} is
- * returned.
- *
- * @param state the node state.
- * @param propertyName the name of a property.
- * @return the boost value for the property.
- */
- public float getPropertyBoost(NodeData state, InternalQName propertyName)
- {
- IndexingRule rule = getApplicableIndexingRule(state);
- if (rule != null)
- {
- return rule.getBoost(propertyName);
- }
- return DEFAULT_BOOST;
- }
+ /**
+ * Returns the boost value for the given property name. If there is no
+ * configuration entry for the property name the {@link #DEFAULT_BOOST} is
+ * returned.
+ *
+ * @param state
+ * the node state.
+ * @param propertyName
+ * the name of a property.
+ * @return the boost value for the property.
+ */
+ public float getPropertyBoost(NodeData state, InternalQName propertyName) {
+ IndexingRule rule = getApplicableIndexingRule(state);
+ if (rule != null) {
+ return rule.getBoost(propertyName);
+ }
+ return DEFAULT_BOOST;
+ }
- /**
- * Returns the boost for the node scope fulltext index field.
- *
- * @param state the node state.
- * @return the boost for the node scope fulltext index field.
- */
- public float getNodeBoost(NodeData state)
- {
- IndexingRule rule = getApplicableIndexingRule(state);
- if (rule != null)
- {
- return rule.getNodeBoost();
- }
- return DEFAULT_BOOST;
- }
+ /**
+ * Returns the boost for the node scope fulltext index field.
+ *
+ * @param state
+ * the node state.
+ * @return the boost for the node scope fulltext index field.
+ */
+ public float getNodeBoost(NodeData state) {
+ IndexingRule rule = getApplicableIndexingRule(state);
+ if (rule != null) {
+ return rule.getNodeBoost();
+ }
+ return DEFAULT_BOOST;
+ }
- /**
- * Returns <code>true</code> if the property with the given name should be
- * included in the node scope fulltext index. If there is not configuration
- * entry for that propery <code>false</code> is returned.
- *
- * @param state the node state.
- * @param propertyName the name of a property.
- * @return <code>true</code> if the property should be included in the node
- * scope fulltext index.
- */
- public boolean isIncludedInNodeScopeIndex(NodeData state, InternalQName propertyName)
- {
- IndexingRule rule = getApplicableIndexingRule(state);
- if (rule != null)
- {
- return rule.isIncludedInNodeScopeIndex(propertyName);
- }
- // none of the config elements matched -> default is to include
- return true;
- }
+ /**
+ * Returns <code>true</code> if the property with the given name should be
+ * included in the node scope fulltext index. If there is not configuration
+ * entry for that propery <code>false</code> is returned.
+ *
+ * @param state
+ * the node state.
+ * @param propertyName
+ * the name of a property.
+ * @return <code>true</code> if the property should be included in the node
+ * scope fulltext index.
+ */
+ public boolean isIncludedInNodeScopeIndex(NodeData state,
+ InternalQName propertyName) {
+ IndexingRule rule = getApplicableIndexingRule(state);
+ if (rule != null) {
+ return rule.isIncludedInNodeScopeIndex(propertyName);
+ }
+ // none of the config elements matched -> default is to include
+ return true;
+ }
- /**
- * Returns <code>true</code> if the content of the property with the given
- * name should show up in an excerpt. If there is no configuration entry for
- * that property <code>true</code> is returned.
- *
- * @param state the node state.
- * @param propertyName the name of a property.
- * @return <code>true</code> if the content of the property should be
- * included in an excerpt; <code>false</code> otherwise.
- */
- public boolean useInExcerpt(NodeData state, InternalQName propertyName)
- {
- IndexingRule rule = getApplicableIndexingRule(state);
- if (rule != null)
- {
- return rule.useInExcerpt(propertyName);
- }
- // none of the config elements matched -> default is to include
- return true;
- }
+ /**
+ * Returns <code>true</code> if the content of the property with the given
+ * name should show up in an excerpt. If there is no configuration entry for
+ * that property <code>true</code> is returned.
+ *
+ * @param state
+ * the node state.
+ * @param propertyName
+ * the name of a property.
+ * @return <code>true</code> if the content of the property should be
+ * included in an excerpt; <code>false</code> otherwise.
+ */
+ public boolean useInExcerpt(NodeData state, InternalQName propertyName) {
+ IndexingRule rule = getApplicableIndexingRule(state);
+ if (rule != null) {
+ return rule.useInExcerpt(propertyName);
+ }
+ // none of the config elements matched -> default is to include
+ return true;
+ }
- /**
- * Returns the analyzer configured for the property with this fieldName
- * (the string representation ,JCR-style name, of the given <code>InternalQName</code>
- * prefixed with <code>FieldNames.FULLTEXT_PREFIX</code>)),
- * and <code>null</code> if none is configured, or the configured analyzer
- * cannot be found. If <code>null</code> is returned, the default Analyzer
- * is used.
- *
- * @param fieldName the string representation ,JCR-style name, of the given <code>InternalQName</code>
- * prefixed with <code>FieldNames.FULLTEXT_PREFIX</code>))
- * @return the <code>analyzer</code> to use for indexing this property
- */
- public Analyzer getPropertyAnalyzer(String fieldName)
- {
- if (analyzers.containsKey(fieldName))
- {
- return (Analyzer)analyzers.get(fieldName);
- }
- return null;
- }
+ /**
+ * Returns the analyzer configured for the property with this fieldName (the
+ * string representation ,JCR-style name, of the given
+ * <code>InternalQName</code> prefixed with
+ * <code>FieldNames.FULLTEXT_PREFIX</code>)), and <code>null</code> if none
+ * is configured, or the configured analyzer cannot be found. If
+ * <code>null</code> is returned, the default Analyzer is used.
+ *
+ * @param fieldName
+ * the string representation ,JCR-style name, of the given
+ * <code>InternalQName</code> prefixed with
+ * <code>FieldNames.FULLTEXT_PREFIX</code>))
+ * @return the <code>analyzer</code> to use for indexing this property
+ */
+ public Analyzer getPropertyAnalyzer(String fieldName) {
+ if (analyzers.containsKey(fieldName)) {
+ return analyzers.get(fieldName);
+ }
+ return null;
+ }
- //---------------------------------< internal >-----------------------------
+ // ---------------------------------< internal
+ // >-----------------------------
- /**
- * Returns the first indexing rule that applies to the given node
- * <code>state</code>.
- *
- * @param state a node state.
- * @return the indexing rule or <code>null</code> if none applies.
- */
- private IndexingRule getApplicableIndexingRule(NodeData state)
- {
- List rules = null;
- List r = (List)configElements.get(state.getPrimaryTypeName());
- if (r != null)
- {
- rules = new ArrayList();
- rules.addAll(r);
- }
+ /**
+ * Returns the first indexing rule that applies to the given node
+ * <code>state</code>.
+ *
+ * @param state
+ * a node state.
+ * @return the indexing rule or <code>null</code> if none applies.
+ */
+ private IndexingRule getApplicableIndexingRule(NodeData state) {
+ List<IndexingRule> rules = null;
+ List<IndexingRule> r = configElements.get(state.getPrimaryTypeName());
+ if (r != null) {
+ rules = new ArrayList<IndexingRule>();
+ rules.addAll(r);
+ }
- Iterator it = Arrays.asList(state.getMixinTypeNames()).iterator();
- while (it.hasNext())
- {
- r = (List)configElements.get(it.next());
- if (r != null)
- {
- if (rules == null)
- {
- rules = new ArrayList();
- }
- rules.addAll(r);
- }
- }
+ InternalQName[] mixTypes = state.getMixinTypeNames();
+ for (InternalQName mixType : mixTypes) {
+ r = configElements.get(mixType);
+ if (r != null) {
+ if (rules == null) {
+ rules = new ArrayList<IndexingRule>();
+ }
+ rules.addAll(r);
+ }
+ }
- if (rules != null)
- {
- it = rules.iterator();
- while (it.hasNext())
- {
- IndexingRule ir = (IndexingRule)it.next();
- if (ir.appliesTo(state))
- {
- return ir;
- }
- }
- }
+ if (rules != null) {
+ for (IndexingRule ir : rules) {
+ if (ir.appliesTo(state)) {
+ return ir;
+ }
+ }
+ }
- // no applicable rule
- return null;
- }
+ // no applicable rule
+ return null;
+ }
- /**
- * Returns the namespaces declared on the <code>node</code>.
- *
- * @param node a DOM node.
- * @return the namespaces
- */
- private Properties getNamespaces(Node node)
- {
- Properties namespaces = new Properties();
- NamedNodeMap attributes = node.getAttributes();
- for (int i = 0; i < attributes.getLength(); i++)
- {
- Attr attribute = (Attr)attributes.item(i);
- if (attribute.getName().startsWith("xmlns:"))
- {
- namespaces.setProperty(attribute.getName().substring(6), attribute.getValue());
- }
- }
- return namespaces;
- }
+ /**
+ * Returns the namespaces declared on the <code>node</code>.
+ *
+ * @param node
+ * a DOM node.
+ * @return the namespaces
+ */
+ private Properties getNamespaces(Node node) {
+ Properties namespaces = new Properties();
+ NamedNodeMap attributes = node.getAttributes();
+ for (int i = 0; i < attributes.getLength(); i++) {
+ Attr attribute = (Attr) attributes.item(i);
+ if (attribute.getName().startsWith("xmlns:")) {
+ namespaces.setProperty(attribute.getName().substring(6),
+ attribute.getValue());
+ }
+ }
+ return namespaces;
+ }
- /**
- * Creates property configurations defined in the <code>config</code>.
- *
- * @param config the fulltext indexing configuration.
- * @param propConfigs will be filled with exact <code>InternalQName</code> to
- * <code>PropertyConfig</code> mappings.
- * @param namePatterns will be filled with <code>NamePattern</code>s.
- * @throws IllegalNameException if the node type name contains illegal
- * characters.
- * @throws RepositoryException
- */
- private void createPropertyConfigs(Node config, Map propConfigs, List namePatterns) throws IllegalNameException,
- RepositoryException
- {
- NodeList childNodes = config.getChildNodes();
- for (int i = 0; i < childNodes.getLength(); i++)
- {
- Node n = childNodes.item(i);
- if (n.getNodeName().equals("property"))
- {
- NamedNodeMap attributes = n.getAttributes();
- // get boost value
- float boost = 1.0f;
- Node boostAttr = attributes.getNamedItem("boost");
- if (boostAttr != null)
- {
- try
- {
- boost = Float.parseFloat(boostAttr.getNodeValue());
- }
- catch (NumberFormatException e)
- {
- // use default
- }
- }
+ /**
+ * Creates property configurations defined in the <code>config</code>.
+ *
+ * @param config
+ * the fulltext indexing configuration.
+ * @param propConfigs
+ * will be filled with exact <code>InternalQName</code> to
+ * <code>PropertyConfig</code> mappings.
+ * @param namePatterns
+ * will be filled with <code>NamePattern</code>s.
+ * @throws IllegalNameException
+ * if the node type name contains illegal characters.
+ * @throws RepositoryException
+ */
+ private void createPropertyConfigs(Node config,
+ Map<InternalQName, PropertyConfig> propConfigs,
+ List<NamePattern> namePatterns) throws IllegalNameException,
+ RepositoryException {
+ NodeList childNodes = config.getChildNodes();
+ for (int i = 0; i < childNodes.getLength(); i++) {
+ Node n = childNodes.item(i);
+ if (n.getNodeName().equals("property")) {
+ NamedNodeMap attributes = n.getAttributes();
+ // get boost value
+ float boost = 1.0f;
+ Node boostAttr = attributes.getNamedItem("boost");
+ if (boostAttr != null) {
+ try {
+ boost = Float.parseFloat(boostAttr.getNodeValue());
+ } catch (NumberFormatException e) {
+ // use default
+ }
+ }
- // get nodeScopeIndex flag
- boolean nodeScopeIndex = true;
- Node nsIndex = attributes.getNamedItem("nodeScopeIndex");
- if (nsIndex != null)
- {
- nodeScopeIndex = Boolean.valueOf(nsIndex.getNodeValue()).booleanValue();
- }
+ // get nodeScopeIndex flag
+ boolean nodeScopeIndex = true;
+ Node nsIndex = attributes.getNamedItem("nodeScopeIndex");
+ if (nsIndex != null) {
+ nodeScopeIndex = Boolean.valueOf(nsIndex.getNodeValue())
+ .booleanValue();
+ }
- // get isRegexp flag
- boolean isRegexp = false;
- Node regexp = attributes.getNamedItem("isRegexp");
- if (regexp != null)
- {
- isRegexp = Boolean.valueOf(regexp.getNodeValue()).booleanValue();
- }
+ // get isRegexp flag
+ boolean isRegexp = false;
+ Node regexp = attributes.getNamedItem("isRegexp");
+ if (regexp != null) {
+ isRegexp = Boolean.valueOf(regexp.getNodeValue())
+ .booleanValue();
+ }
- // get useInExcerpt flag
- boolean useInExcerpt = true;
- Node excerpt = attributes.getNamedItem("useInExcerpt");
- if (excerpt != null)
- {
- useInExcerpt = Boolean.valueOf(excerpt.getNodeValue()).booleanValue();
- }
+ // get useInExcerpt flag
+ boolean useInExcerpt = true;
+ Node excerpt = attributes.getNamedItem("useInExcerpt");
+ if (excerpt != null) {
+ useInExcerpt = Boolean.valueOf(excerpt.getNodeValue())
+ .booleanValue();
+ }
- PropertyConfig pc = new PropertyConfig(boost, nodeScopeIndex, useInExcerpt);
+ PropertyConfig pc = new PropertyConfig(boost, nodeScopeIndex,
+ useInExcerpt);
- if (isRegexp)
- {
- namePatterns.add(new NamePattern(getTextContent(n), pc, resolver));
- }
- else
- {
- InternalQName propName = resolver.parseJCRName(getTextContent(n)).getInternalName();
- propConfigs.put(propName, pc);
- }
- }
- }
- }
+ if (isRegexp) {
+ namePatterns.add(new NamePattern(getTextContent(n), pc,
+ resolver));
+ } else {
+ InternalQName propName = resolver.parseJCRName(
+ getTextContent(n)).getInternalName();
+ propConfigs.put(propName, pc);
+ }
+ }
+ }
+ }
- /**
- * Gets the condition expression from the configuration.
- *
- * @param config the config node.
- * @return the condition expression or <code>null</code> if there is no
- * condition set on the <code>config</code>.
- * @throws MalformedPathException if the condition string is malformed.
- * @throws IllegalNameException if a name contains illegal characters.
- * @throws RepositoryException
- */
- private PathExpression getCondition(Node config) throws IllegalNameException, RepositoryException
- {
- Node conditionAttr = config.getAttributes().getNamedItem("condition");
- if (conditionAttr == null)
- {
- return null;
- }
- String conditionString = conditionAttr.getNodeValue();
- int idx;
- int axis;
- InternalQName elementTest = null;
- InternalQName nameTest = null;
- InternalQName propertyName;
- String propertyValue;
+ /**
+ * Gets the condition expression from the configuration.
+ *
+ * @param config
+ * the config node.
+ * @return the condition expression or <code>null</code> if there is no
+ * condition set on the <code>config</code>.
+ * @throws MalformedPathException
+ * if the condition string is malformed.
+ * @throws IllegalNameException
+ * if a name contains illegal characters.
+ * @throws RepositoryException
+ */
+ private PathExpression getCondition(Node config)
+ throws IllegalNameException, RepositoryException {
+ Node conditionAttr = config.getAttributes().getNamedItem("condition");
+ if (conditionAttr == null) {
+ return null;
+ }
+ String conditionString = conditionAttr.getNodeValue();
+ int idx;
+ int axis;
+ InternalQName elementTest = null;
+ InternalQName nameTest = null;
+ InternalQName propertyName;
+ String propertyValue;
- // parse axis
- if (conditionString.startsWith("ancestor::"))
- {
- axis = PathExpression.ANCESTOR;
- idx = "ancestor::".length();
- }
- else if (conditionString.startsWith("parent::"))
- {
- axis = PathExpression.PARENT;
- idx = "parent::".length();
- }
- else if (conditionString.startsWith("@"))
- {
- axis = PathExpression.SELF;
- idx = "@".length();
- }
- else
- {
- axis = PathExpression.CHILD;
- idx = 0;
- }
+ // parse axis
+ if (conditionString.startsWith("ancestor::")) {
+ axis = PathExpression.ANCESTOR;
+ idx = "ancestor::".length();
+ } else if (conditionString.startsWith("parent::")) {
+ axis = PathExpression.PARENT;
+ idx = "parent::".length();
+ } else if (conditionString.startsWith("@")) {
+ axis = PathExpression.SELF;
+ idx = "@".length();
+ } else {
+ axis = PathExpression.CHILD;
+ idx = 0;
+ }
- try
- {
- if (conditionString.startsWith("element(", idx))
- {
- int colon = conditionString.indexOf(',', idx + "element(".length());
- String name = conditionString.substring(idx + "element(".length(), colon).trim();
- if (!name.equals("*"))
- {
- nameTest = resolver.parseJCRName(ISO9075.decode(name)).getInternalName();
- }
- idx = conditionString.indexOf(")/@", colon);
- String type = conditionString.substring(colon + 1, idx).trim();
- elementTest = resolver.parseJCRName(ISO9075.decode(type)).getInternalName();
- idx += ")/@".length();
- }
- else
- {
- if (axis == PathExpression.ANCESTOR || axis == PathExpression.CHILD || axis == PathExpression.PARENT)
- {
- // simple name test
- String name = conditionString.substring(idx, conditionString.indexOf('/', idx));
- if (!name.equals("*"))
- {
- nameTest = resolver.parseJCRName(ISO9075.decode(name)).getInternalName();
- }
- idx += name.length() + "/@".length();
- }
- }
+ try {
+ if (conditionString.startsWith("element(", idx)) {
+ int colon = conditionString.indexOf(',', idx
+ + "element(".length());
+ String name = conditionString.substring(
+ idx + "element(".length(), colon).trim();
+ if (!name.equals("*")) {
+ nameTest = resolver.parseJCRName(ISO9075.decode(name))
+ .getInternalName();
+ }
+ idx = conditionString.indexOf(")/@", colon);
+ String type = conditionString.substring(colon + 1, idx).trim();
+ elementTest = resolver.parseJCRName(ISO9075.decode(type))
+ .getInternalName();
+ idx += ")/@".length();
+ } else {
+ if (axis == PathExpression.ANCESTOR
+ || axis == PathExpression.CHILD
+ || axis == PathExpression.PARENT) {
+ // simple name test
+ String name = conditionString.substring(idx,
+ conditionString.indexOf('/', idx));
+ if (!name.equals("*")) {
+ nameTest = resolver.parseJCRName(ISO9075.decode(name))
+ .getInternalName();
+ }
+ idx += name.length() + "/@".length();
+ }
+ }
- // parse property name
- int eq = conditionString.indexOf('=', idx);
- String name = conditionString.substring(idx, eq).trim();
- propertyName = resolver.parseJCRName(ISO9075.decode(name)).getInternalName();
+ // parse property name
+ int eq = conditionString.indexOf('=', idx);
+ String name = conditionString.substring(idx, eq).trim();
+ propertyName = resolver.parseJCRName(ISO9075.decode(name))
+ .getInternalName();
- // parse string value
- int quote = conditionString.indexOf('\'', eq) + 1;
- propertyValue = conditionString.substring(quote, conditionString.indexOf('\'', quote));
- }
- catch (IndexOutOfBoundsException e)
- {
- throw new RepositoryException(conditionString);
- }
+ // parse string value
+ int quote = conditionString.indexOf('\'', eq) + 1;
+ propertyValue = conditionString.substring(quote, conditionString
+ .indexOf('\'', quote));
+ } catch (IndexOutOfBoundsException e) {
+ throw new RepositoryException(conditionString);
+ }
- return new PathExpression(axis, elementTest, nameTest, propertyName, propertyValue);
- }
+ return new PathExpression(axis, elementTest, nameTest, propertyName,
+ propertyValue);
+ }
- /**
- * @param node a node.
- * @return the text content of the <code>node</code>.
- */
- private static String getTextContent(Node node)
- {
- StringBuffer content = new StringBuffer();
- NodeList nodes = node.getChildNodes();
- for (int i = 0; i < nodes.getLength(); i++)
- {
- Node n = nodes.item(i);
- if (n.getNodeType() == Node.TEXT_NODE)
- {
- content.append(((CharacterData)n).getData());
- }
- }
- return content.toString();
- }
+ /**
+ * @param node
+ * a node.
+ * @return the text content of the <code>node</code>.
+ */
+ private static String getTextContent(Node node) {
+ StringBuffer content = new StringBuffer();
+ NodeList nodes = node.getChildNodes();
+ for (int i = 0; i < nodes.getLength(); i++) {
+ Node n = nodes.item(i);
+ if (n.getNodeType() == Node.TEXT_NODE) {
+ content.append(((CharacterData) n).getData());
+ }
+ }
+ return content.toString();
+ }
- /**
- * A property name pattern.
- */
- private static final class NamePattern
- {
+ /**
+ * A property name pattern.
+ */
+ private static final class NamePattern {
- /**
- * The pattern to match.
- */
- private final Pattern pattern;
+ /**
+ * The pattern to match.
+ */
+ private final Pattern pattern;
- /**
- * The associated configuration.
- */
- private final PropertyConfig config;
+ /**
+ * The associated configuration.
+ */
+ private final PropertyConfig config;
- /**
- * Creates a new name pattern.
- *
- * @param pattern the pattern as read from the configuration file.
- * @param config the associated configuration.
- * @param resolver a namespace resolver for parsing name from the
- * configuration.
- * @throws IllegalNameException if the prefix of the name pattern is
- * illegal.
- * @throws RepositoryException
- */
- private NamePattern(String pattern, PropertyConfig config, LocationFactory resolver) throws IllegalNameException,
- RepositoryException
- {
- String uri = Constants.NS_DEFAULT_URI;
- String localPattern = pattern;
- int idx = pattern.indexOf(':');
- if (idx != -1)
- {
- // use a dummy local name to get namespace uri
- uri = resolver.parseJCRName(pattern.substring(0, idx) + ":a").getNamespace();
- localPattern = pattern.substring(idx + 1);
- }
- this.pattern = Pattern.name(uri, localPattern);
- this.config = config;
- }
+ /**
+ * Creates a new name pattern.
+ *
+ * @param pattern
+ * the pattern as read from the configuration file.
+ * @param config
+ * the associated configuration.
+ * @param resolver
+ * a namespace resolver for parsing name from the
+ * configuration.
+ * @throws IllegalNameException
+ * if the prefix of the name pattern is illegal.
+ * @throws RepositoryException
+ */
+ private NamePattern(String pattern, PropertyConfig config,
+ LocationFactory resolver) throws IllegalNameException,
+ RepositoryException {
+ String uri = Constants.NS_DEFAULT_URI;
+ String localPattern = pattern;
+ int idx = pattern.indexOf(':');
+ if (idx != -1) {
+ // use a dummy local name to get namespace uri
+ uri = resolver.parseJCRName(pattern.substring(0, idx) + ":a")
+ .getNamespace();
+ localPattern = pattern.substring(idx + 1);
+ }
+ this.pattern = Pattern.name(uri, localPattern);
+ this.config = config;
+ }
- /**
- * @param path the path to match.
- * @return <code>true</code> if <code>path</code> matches this name
- * pattern; <code>false</code> otherwise.
- */
- boolean matches(QPath path)
- {
- return pattern.match(path).isFullMatch();
- }
+ /**
+ * @param path
+ * the path to match.
+ * @return <code>true</code> if <code>path</code> matches this name
+ * pattern; <code>false</code> otherwise.
+ */
+ boolean matches(QPath path) {
+ return pattern.match(path).isFullMatch();
+ }
- /**
- * @return the property configuration for this name pattern.
- */
- PropertyConfig getConfig()
- {
- return config;
- }
- }
+ /**
+ * @return the property configuration for this name pattern.
+ */
+ PropertyConfig getConfig() {
+ return config;
+ }
+ }
- private class IndexingRule
- {
+ private class IndexingRule {
- /**
- * The node type of this fulltext indexing rule.
- */
- private final InternalQName nodeTypeName;
+ /**
+ * The node type of this fulltext indexing rule.
+ */
+ private final InternalQName nodeTypeName;
- /**
- * Map of {@link PropertyConfig}. Key=InternalQName of property.
- */
- private final Map propConfigs;
+ /**
+ * Map of {@link PropertyConfig}. Key=InternalQName of property.
+ */
+ private final Map<InternalQName, PropertyConfig> propConfigs;
- /**
- * List of {@link NamePattern}s.
- */
- private final List namePatterns;
+ /**
+ * List of {@link NamePattern}s.
+ */
+ private final List<NamePattern> namePatterns;
- /**
- * An expression based on a relative path.
- */
- private final PathExpression condition;
+ /**
+ * An expression based on a relative path.
+ */
+ private final PathExpression condition;
- /**
- * The boost value for this config element.
- */
- private final float boost;
+ /**
+ * The boost value for this config element.
+ */
+ private final float boost;
- /**
- * Creates a new indexing rule base on an existing one, but for a
- * different node type name.
- *
- * @param original the existing rule.
- * @param nodeTypeName the node type name for the rule.
- */
- IndexingRule(IndexingRule original, InternalQName nodeTypeName)
- {
- this.nodeTypeName = nodeTypeName;
- this.propConfigs = original.propConfigs;
- this.namePatterns = original.namePatterns;
- this.condition = original.condition;
- this.boost = original.boost;
- }
+ /**
+ * Creates a new indexing rule base on an existing one, but for a
+ * different node type name.
+ *
+ * @param original
+ * the existing rule.
+ * @param nodeTypeName
+ * the node type name for the rule.
+ */
+ IndexingRule(IndexingRule original, InternalQName nodeTypeName) {
+ this.nodeTypeName = nodeTypeName;
+ this.propConfigs = original.propConfigs;
+ this.namePatterns = original.namePatterns;
+ this.condition = original.condition;
+ this.boost = original.boost;
+ }
- /**
- *
- * @param config the configuration for this rule.
- * @throws MalformedPathException if the condition expression is malformed.
- * @throws IllegalNameException if a name contains illegal characters.
- * @throws RepositoryException
- */
- IndexingRule(Node config) throws IllegalNameException, RepositoryException
- {
- this.nodeTypeName = getNodeTypeName(config);
- this.condition = getCondition(config);
- this.boost = getNodeBoost(config);
- this.propConfigs = new HashMap();
- this.namePatterns = new ArrayList();
- createPropertyConfigs(config, propConfigs, namePatterns);
- }
+ /**
+ *
+ * @param config
+ * the configuration for this rule.
+ * @throws MalformedPathException
+ * if the condition expression is malformed.
+ * @throws IllegalNameException
+ * if a name contains illegal characters.
+ * @throws RepositoryException
+ */
+ IndexingRule(Node config) throws IllegalNameException,
+ RepositoryException {
+ this.nodeTypeName = getNodeTypeName(config);
+ this.condition = getCondition(config);
+ this.boost = getNodeBoost(config);
+ this.propConfigs = new HashMap<InternalQName, PropertyConfig>();
+ this.namePatterns = new ArrayList<NamePattern>();
+ createPropertyConfigs(config, propConfigs, namePatterns);
+ }
- /**
- * Returns the name of the node type where this rule applies to.
- *
- * @return name of the node type.
- */
- public InternalQName getNodeTypeName()
- {
- return nodeTypeName;
- }
+ /**
+ * Returns the name of the node type where this rule applies to.
+ *
+ * @return name of the node type.
+ */
+ public InternalQName getNodeTypeName() {
+ return nodeTypeName;
+ }
- /**
- * @return the value for the node boost.
- */
- public float getNodeBoost()
- {
- return boost;
- }
+ /**
+ * @return the value for the node boost.
+ */
+ public float getNodeBoost() {
+ return boost;
+ }
- /**
- * Returns <code>true</code> if the property with the given name is
- * indexed according to this rule.
- *
- * @param propertyName the name of a property.
- * @return <code>true</code> if the property is indexed;
- * <code>false</code> otherwise.
- */
- public boolean isIndexed(InternalQName propertyName)
- {
- return getConfig(propertyName) != null;
- }
+ /**
+ * Returns <code>true</code> if the property with the given name is
+ * indexed according to this rule.
+ *
+ * @param propertyName
+ * the name of a property.
+ * @return <code>true</code> if the property is indexed;
+ * <code>false</code> otherwise.
+ */
+ public boolean isIndexed(InternalQName propertyName) {
+ return getConfig(propertyName) != null;
+ }
- /**
- * Returns the boost value for the given property name. If there is no
- * configuration entry for the property name the default boost value is
- * returned.
- *
- * @param propertyName the name of a property.
- * @return the boost value for the property.
- */
- public float getBoost(InternalQName propertyName)
- {
- PropertyConfig config = getConfig(propertyName);
- if (config != null)
- {
- return config.boost;
- }
- else
- {
- return DEFAULT_BOOST;
- }
- }
+ /**
+ * Returns the boost value for the given property name. If there is no
+ * configuration entry for the property name the default boost value is
+ * returned.
+ *
+ * @param propertyName
+ * the name of a property.
+ * @return the boost value for the property.
+ */
+ public float getBoost(InternalQName propertyName) {
+ PropertyConfig config = getConfig(propertyName);
+ if (config != null) {
+ return config.boost;
+ } else {
+ return DEFAULT_BOOST;
+ }
+ }
- /**
- * Returns <code>true</code> if the property with the given name should
- * be included in the node scope fulltext index. If there is no
- * configuration entry for that propery <code>false</code> is returned.
- *
- * @param propertyName the name of a property.
- * @return <code>true</code> if the property should be included in the
- * node scope fulltext index.
- */
- public boolean isIncludedInNodeScopeIndex(InternalQName propertyName)
- {
- PropertyConfig config = getConfig(propertyName);
- if (config != null)
- {
- return config.nodeScopeIndex;
- }
- else
- {
- return false;
- }
- }
+ /**
+ * Returns <code>true</code> if the property with the given name should
+ * be included in the node scope fulltext index. If there is no
+ * configuration entry for that propery <code>false</code> is returned.
+ *
+ * @param propertyName
+ * the name of a property.
+ * @return <code>true</code> if the property should be included in the
+ * node scope fulltext index.
+ */
+ public boolean isIncludedInNodeScopeIndex(InternalQName propertyName) {
+ PropertyConfig config = getConfig(propertyName);
+ if (config != null) {
+ return config.nodeScopeIndex;
+ } else {
+ return false;
+ }
+ }
- /**
- * Returns <code>true</code> if the content of the property with the
- * given name should show up in an excerpt. If there is no configuration
- * entry for that property <code>true</code> is returned.
- *
- * @param propertyName the name of a property.
- * @return <code>true</code> if the content of the property should be
- * included in an excerpt; <code>false</code> otherwise.
- */
- public boolean useInExcerpt(InternalQName propertyName)
- {
- PropertyConfig config = getConfig(propertyName);
- if (config != null)
- {
- return config.useInExcerpt;
- }
- else
- {
- return true;
- }
- }
+ /**
+ * Returns <code>true</code> if the content of the property with the
+ * given name should show up in an excerpt. If there is no configuration
+ * entry for that property <code>true</code> is returned.
+ *
+ * @param propertyName
+ * the name of a property.
+ * @return <code>true</code> if the content of the property should be
+ * included in an excerpt; <code>false</code> otherwise.
+ */
+ public boolean useInExcerpt(InternalQName propertyName) {
+ PropertyConfig config = getConfig(propertyName);
+ if (config != null) {
+ return config.useInExcerpt;
+ } else {
+ return true;
+ }
+ }
- /**
- * Returns <code>true</code> if this rule applies to the given node
- * <code>state</code>.
- *
- * @param state the state to check.
- * @return <code>true</code> the rule applies to the given node;
- * <code>false</code> otherwise.
- */
- public boolean appliesTo(NodeData state)
- {
- if (!nodeTypeName.equals(state.getPrimaryTypeName()))
- {
- return false;
- }
- if (condition == null)
- {
- return true;
- }
- else
- {
- return condition.evaluate(state);
- }
- }
+ /**
+ * Returns <code>true</code> if this rule applies to the given node
+ * <code>state</code>.
+ *
+ * @param state
+ * the state to check.
+ * @return <code>true</code> the rule applies to the given node;
+ * <code>false</code> otherwise.
+ */
+ public boolean appliesTo(NodeData state) {
+ if (!nodeTypeName.equals(state.getPrimaryTypeName())) {
+ return false;
+ }
+ if (condition == null) {
+ return true;
+ } else {
+ return condition.evaluate(state);
+ }
+ }
- //-------------------------< internal >---------------------------------
+ // -------------------------< internal
+ // >---------------------------------
- /**
- * @param propertyName name of a property.
- * @return the property configuration or <code>null</code> if this
- * indexing rule does not contain a configuration for the given
- * property.
- */
- private PropertyConfig getConfig(InternalQName propertyName)
- {
- PropertyConfig config = (PropertyConfig)propConfigs.get(propertyName);
- if (config != null)
- {
- return config;
- }
- else if (namePatterns.size() > 0)
- {
- QPath path = new QPath(new QPathEntry[]{new QPathEntry(propertyName, 1)});
- // check patterns
- for (Iterator it = namePatterns.iterator(); it.hasNext();)
- {
- NamePattern np = (NamePattern)it.next();
- if (np.matches(path))
- {
- return np.getConfig();
- }
- }
- }
- return null;
- }
+ /**
+ * @param propertyName
+ * name of a property.
+ * @return the property configuration or <code>null</code> if this
+ * indexing rule does not contain a configuration for the given
+ * property.
+ */
+ private PropertyConfig getConfig(InternalQName propertyName) {
+ PropertyConfig config = propConfigs.get(propertyName);
+ if (config != null) {
+ return config;
+ } else if (namePatterns.size() > 0) {
+ QPath path = new QPath(new QPathEntry[] { new QPathEntry(
+ propertyName, 1) });
+ // check patterns
+ for (Iterator<NamePattern> it = namePatterns.iterator(); it
+ .hasNext();) {
+ NamePattern np = it.next();
+ if (np.matches(path)) {
+ return np.getConfig();
+ }
+ }
+ }
+ return null;
+ }
- /**
- * Reads the node type of the root node of the indexing rule.
- *
- * @param config the configuration.
- * @return the name of the node type.
- * @throws IllegalNameException if the node type name contains illegal
- * characters.
- * @throws RepositoryException
- */
- private InternalQName getNodeTypeName(Node config) throws IllegalNameException, RepositoryException
- {
- String ntString = config.getAttributes().getNamedItem("nodeType").getNodeValue();
- return resolver.parseJCRName(ntString).getInternalName();
- }
+ /**
+ * Reads the node type of the root node of the indexing rule.
+ *
+ * @param config
+ * the configuration.
+ * @return the name of the node type.
+ * @throws IllegalNameException
+ * if the node type name contains illegal characters.
+ * @throws RepositoryException
+ */
+ private InternalQName getNodeTypeName(Node config)
+ throws IllegalNameException, RepositoryException {
+ String ntString = config.getAttributes().getNamedItem("nodeType")
+ .getNodeValue();
+ return resolver.parseJCRName(ntString).getInternalName();
+ }
- /**
- * Returns the node boost from the <code>config</code>.
- *
- * @param config the configuration.
- * @return the configured node boost or the default boost if none is
- * configured.
- */
- private float getNodeBoost(Node config)
- {
- Node boost = config.getAttributes().getNamedItem("boost");
- if (boost != null)
- {
- try
- {
- return Float.parseFloat(boost.getNodeValue());
- }
- catch (NumberFormatException e)
- {
- // return default boost
- }
- }
- return DEFAULT_BOOST;
- }
- }
+ /**
+ * Returns the node boost from the <code>config</code>.
+ *
+ * @param config
+ * the configuration.
+ * @return the configured node boost or the default boost if none is
+ * configured.
+ */
+ private float getNodeBoost(Node config) {
+ Node boost = config.getAttributes().getNamedItem("boost");
+ if (boost != null) {
+ try {
+ return Float.parseFloat(boost.getNodeValue());
+ } catch (NumberFormatException e) {
+ // return default boost
+ }
+ }
+ return DEFAULT_BOOST;
+ }
+ }
- /**
- * Simple class that holds boost and nodeScopeIndex flag.
- */
- private class PropertyConfig
- {
+ /**
+ * Simple class that holds boost and nodeScopeIndex flag.
+ */
+ private class PropertyConfig {
- /**
- * The boost value for a property.
- */
- final float boost;
+ /**
+ * The boost value for a property.
+ */
+ final float boost;
- /**
- * Flag that indicates whether a property is included in the node
- * scope fulltext index of its parent.
- */
- final boolean nodeScopeIndex;
+ /**
+ * Flag that indicates whether a property is included in the node scope
+ * fulltext index of its parent.
+ */
+ final boolean nodeScopeIndex;
- /**
- * Flag that indicates whether the content of a property should be used
- * to create an excerpt.
- */
- final boolean useInExcerpt;
+ /**
+ * Flag that indicates whether the content of a property should be used
+ * to create an excerpt.
+ */
+ final boolean useInExcerpt;
- PropertyConfig(float boost, boolean nodeScopeIndex, boolean useInExcerpt)
- {
- this.boost = boost;
- this.nodeScopeIndex = nodeScopeIndex;
- this.useInExcerpt = useInExcerpt;
- }
- }
+ PropertyConfig(float boost, boolean nodeScopeIndex, boolean useInExcerpt) {
+ this.boost = boost;
+ this.nodeScopeIndex = nodeScopeIndex;
+ this.useInExcerpt = useInExcerpt;
+ }
+ }
- private class PathExpression
- {
+ private class PathExpression {
- static final int SELF = 0;
+ static final int SELF = 0;
- static final int CHILD = 1;
+ static final int CHILD = 1;
- static final int ANCESTOR = 2;
+ static final int ANCESTOR = 2;
- static final int PARENT = 3;
+ static final int PARENT = 3;
- private final int axis;
+ private final int axis;
- private final InternalQName elementTest;
+ private final InternalQName elementTest;
- private final InternalQName nameTest;
+ private final InternalQName nameTest;
- private final InternalQName propertyName;
+ private final InternalQName propertyName;
- private final String propertyValue;
+ private final String propertyValue;
- PathExpression(int axis, InternalQName elementTest, InternalQName nameTest, InternalQName propertyName,
- String propertyValue)
- {
- this.axis = axis;
- this.elementTest = elementTest;
- this.nameTest = nameTest;
- this.propertyName = propertyName;
- this.propertyValue = propertyValue;
- }
+ PathExpression(int axis, InternalQName elementTest,
+ InternalQName nameTest, InternalQName propertyName,
+ String propertyValue) {
+ this.axis = axis;
+ this.elementTest = elementTest;
+ this.nameTest = nameTest;
+ this.propertyName = propertyName;
+ this.propertyValue = propertyValue;
+ }
- /**
- * Evaluates this expression and returns <code>true</code> if the
- * condition matches using <code>state</code> as the context node
- * state.
- *
- * @param context the context from where the expression should be
- * evaluated.
- * @return expression result.
- */
- boolean evaluate(final NodeData context)
- {
- // get iterator along specified axis
- Iterator nodeStates;
- if (axis == SELF)
- {
- nodeStates = Collections.singletonList(context).iterator();
- }
- else if (axis == CHILD)
- {
- List<NodeData> childs;
- try
- {
- childs = ism.getChildNodesData(context);
- nodeStates = childs.iterator();
- }
- catch (RepositoryException e)
- {
- nodeStates = Collections.<NodeData> emptyList().iterator();
- }
- }
- else if (axis == ANCESTOR)
- {
- try
- {
- nodeStates = new Iterator()
- {
+ /**
+ * Evaluates this expression and returns <code>true</code> if the
+ * condition matches using <code>state</code> as the context node state.
+ *
+ * @param context
+ * the context from where the expression should be evaluated.
+ * @return expression result.
+ */
+ boolean evaluate(final NodeData context) {
+ // get iterator along specified axis
+ Iterator nodeStates;
+ if (axis == SELF) {
+ nodeStates = Collections.singletonList(context).iterator();
+ } else if (axis == CHILD) {
+ List<NodeData> childs;
+ try {
+ childs = ism.getChildNodesData(context);
+ nodeStates = childs.iterator();
+ } catch (RepositoryException e) {
+ nodeStates = Collections.<NodeData> emptyList().iterator();
+ }
+ } else if (axis == ANCESTOR) {
+ try {
+ nodeStates = new Iterator() {
- private NodeData next = (NodeData)ism.getItemData(context.getParentIdentifier());
+ private NodeData next = (NodeData) ism
+ .getItemData(context.getParentIdentifier());
- public void remove()
- {
- throw new UnsupportedOperationException();
- }
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
- public boolean hasNext()
- {
- return next != null;
- }
+ public boolean hasNext() {
+ return next != null;
+ }
- public Object next()
- {
- NodeData tmp = next;
- try
- {
- if (next.getParentIdentifier() != null)
- {
- next = (NodeData)ism.getItemData(next.getParentIdentifier());
- }
- else
- {
- next = null;
- }
- }
- catch (RepositoryException e)
- {
- next = null;
- }
- return tmp;
- }
- };
- }
- catch (RepositoryException e)
- {
- nodeStates = Collections.EMPTY_LIST.iterator();
- }
- }
- else if (axis == PARENT)
- {
- try
- {
- if (context.getParentIdentifier() != null)
- {
- NodeData state = (NodeData)ism.getItemData(context.getParentIdentifier());
- nodeStates = Collections.singletonList(state).iterator();
- }
- else
- {
- nodeStates = Collections.EMPTY_LIST.iterator();
- }
- }
- catch (RepositoryException e)
- {
- nodeStates = Collections.EMPTY_LIST.iterator();
- }
- }
- else
- {
- // unsupported axis
- nodeStates = Collections.EMPTY_LIST.iterator();
- }
+ public Object next() {
+ NodeData tmp = next;
+ try {
+ if (next.getParentIdentifier() != null) {
+ next = (NodeData) ism.getItemData(next
+ .getParentIdentifier());
+ } else {
+ next = null;
+ }
+ } catch (RepositoryException e) {
+ next = null;
+ }
+ return tmp;
+ }
+ };
+ } catch (RepositoryException e) {
+ nodeStates = Collections.EMPTY_LIST.iterator();
+ }
+ } else if (axis == PARENT) {
+ try {
+ if (context.getParentIdentifier() != null) {
+ NodeData state = (NodeData) ism.getItemData(context
+ .getParentIdentifier());
+ nodeStates = Collections.singletonList(state)
+ .iterator();
+ } else {
+ nodeStates = Collections.EMPTY_LIST.iterator();
+ }
+ } catch (RepositoryException e) {
+ nodeStates = Collections.EMPTY_LIST.iterator();
+ }
+ } else {
+ // unsupported axis
+ nodeStates = Collections.EMPTY_LIST.iterator();
+ }
- // check node type, name and property value for each
- while (nodeStates.hasNext())
- {
- try
- {
- NodeData current = (NodeData)nodeStates.next();
- if ((elementTest != null) && !current.getPrimaryTypeName().equals(elementTest))
- {
- continue;
- }
- if ((nameTest != null) && !current.getQPath().getName().equals(nameTest))
- {
- continue;
- }
+ // check node type, name and property value for each
+ while (nodeStates.hasNext()) {
+ try {
+ NodeData current = (NodeData) nodeStates.next();
+ if ((elementTest != null)
+ && !current.getPrimaryTypeName()
+ .equals(elementTest)) {
+ continue;
+ }
+ if ((nameTest != null)
+ && !current.getQPath().getName().equals(nameTest)) {
+ continue;
+ }
- List<PropertyData> childProps = ism.getChildPropertiesData(current);
+ List<PropertyData> childProps = ism
+ .getChildPropertiesData(current);
- PropertyData propState = null;
- for (PropertyData propertyData : childProps)
- {
- if (propertyData.getQPath().getName().equals(propertyName))
- {
- propState = propertyData;
- break;
- }
+ PropertyData propState = null;
+ for (PropertyData propertyData : childProps) {
+ if (propertyData.getQPath().getName().equals(
+ propertyName)) {
+ propState = propertyData;
+ break;
+ }
- }
- if (propState == null)
- {
- continue;
- }
+ }
+ if (propState == null) {
+ continue;
+ }
- List<ValueData> values = propState.getValues();
+ List<ValueData> values = propState.getValues();
- // if (values.get(i).toString().equals(propertyValue)) {
- // return true;
- // }
+ // if (values.get(i).toString().equals(propertyValue)) {
+ // return true;
+ // }
- if (propState.getType() == PropertyType.BINARY)
- {
- // skip binary values
- continue;
- }
+ if (propState.getType() == PropertyType.BINARY) {
+ // skip binary values
+ continue;
+ }
- try
- {
- for (int i = 0; i < values.size(); i++)
- {
- byte[] bytes = values.get(i).getAsByteArray();
- String val = new String(bytes, Constants.DEFAULT_ENCODING);
- if (val.equals(propertyValue))
- {
- return true;
- }
- }
- }
- catch (IOException e)
- {
- log.error(e.getLocalizedMessage());
- }
+ try {
+ for (int i = 0; i < values.size(); i++) {
+ byte[] bytes = values.get(i).getAsByteArray();
+ String val = new String(bytes,
+ Constants.DEFAULT_ENCODING);
+ if (val.equals(propertyValue)) {
+ return true;
+ }
+ }
+ } catch (IOException e) {
+ log.error(e.getLocalizedMessage());
+ }
- }
- catch (RepositoryException e)
- {
- log.error(e.getLocalizedMessage());
- }
- }
- return false;
- }
- }
+ } catch (RepositoryException e) {
+ log.error(e.getLocalizedMessage());
+ }
+ }
+ return false;
+ }
+ }
}
Modified: jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/LuceneQueryBuilder.java
===================================================================
--- jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/LuceneQueryBuilder.java 2009-10-02 15:39:44 UTC (rev 197)
+++ jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/LuceneQueryBuilder.java 2009-10-02 15:41:14 UTC (rev 198)
@@ -16,21 +16,6 @@
*/
package org.exoplatform.services.jcr.impl.core.query.lucene;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Calendar;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-
-import javax.jcr.NamespaceException;
-import javax.jcr.PropertyType;
-import javax.jcr.RepositoryException;
-import javax.jcr.nodetype.NodeType;
-import javax.jcr.nodetype.NodeTypeIterator;
-import javax.jcr.nodetype.NodeTypeManager;
-import javax.jcr.query.InvalidQueryException;
-
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryParser.ParseException;
@@ -39,7 +24,6 @@
import org.apache.lucene.search.Query;
import org.apache.lucene.search.BooleanClause.Occur;
import org.exoplatform.commons.utils.ISO8601;
-import org.exoplatform.services.jcr.core.nodetype.NodeTypeData;
import org.exoplatform.services.jcr.core.nodetype.NodeTypeDataManager;
import org.exoplatform.services.jcr.dataflow.ItemDataConsumer;
import org.exoplatform.services.jcr.datamodel.IllegalNameException;
@@ -51,7 +35,6 @@
import org.exoplatform.services.jcr.datamodel.QPathEntry;
import org.exoplatform.services.jcr.impl.Constants;
import org.exoplatform.services.jcr.impl.core.LocationFactory;
-import org.exoplatform.services.jcr.impl.core.RepositoryImpl;
import org.exoplatform.services.jcr.impl.core.SessionImpl;
import org.exoplatform.services.jcr.impl.core.query.AndQueryNode;
import org.exoplatform.services.jcr.impl.core.query.DefaultQueryNodeVisitor;
@@ -70,1221 +53,1151 @@
import org.exoplatform.services.jcr.impl.core.query.QueryNodeVisitor;
import org.exoplatform.services.jcr.impl.core.query.QueryRootNode;
import org.exoplatform.services.jcr.impl.core.query.RelationQueryNode;
-import org.exoplatform.services.jcr.impl.core.query.SearchManager;
import org.exoplatform.services.jcr.impl.core.query.TextsearchQueryNode;
-
import org.exoplatform.services.jcr.impl.util.ISO9075;
import org.exoplatform.services.jcr.impl.xml.XMLChar;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.jcr.NamespaceException;
+import javax.jcr.PropertyType;
+import javax.jcr.RepositoryException;
+import javax.jcr.query.InvalidQueryException;
+
/**
- * Implements a query builder that takes an abstract query tree and creates
- * a lucene {@link org.apache.lucene.search.Query} tree that can be executed
- * on an index.
- * todo introduce a node type hierarchy for efficient translation of NodeTypeQueryNode
+ * Implements a query builder that takes an abstract query tree and creates a
+ * lucene {@link org.apache.lucene.search.Query} tree that can be executed on an
+ * index. todo introduce a node type hierarchy for efficient translation of
+ * NodeTypeQueryNode
*/
-public class LuceneQueryBuilder implements QueryNodeVisitor
-{
- /**
- * Namespace URI for xpath functions
- */
- private static final String NS_FN_PREFIX = "fn";
+public class LuceneQueryBuilder implements QueryNodeVisitor {
+ /**
+ * Namespace URI for xpath functions
+ */
+ private static final String NS_FN_PREFIX = "fn";
- public static final String NS_FN_URI = "http://www.w3.org/2005/xpath-functions";
+ public static final String NS_FN_URI = "http://www.w3.org/2005/xpath-functions";
- /**
- * Deprecated namespace URI for xpath functions
- */
- private static final String NS_FN_OLD_PREFIX = "fn_old";
+ /**
+ * Deprecated namespace URI for xpath functions
+ */
+ private static final String NS_FN_OLD_PREFIX = "fn_old";
- public static final String NS_FN_OLD_URI = "http://www.w3.org/2004/10/xpath-functions";
+ public static final String NS_FN_OLD_URI = "http://www.w3.org/2004/10/xpath-functions";
- /**
- * Namespace URI for XML schema
- */
- private static final String NS_XS_PREFIX = "xs";
+ /**
+ * Namespace URI for XML schema
+ */
+ private static final String NS_XS_PREFIX = "xs";
- public static final String NS_XS_URI = "http://www.w3.org/2001/XMLSchema";
+ public static final String NS_XS_URI = "http://www.w3.org/2001/XMLSchema";
- /**
- * Logger for this class
- */
- private static final Logger log = LoggerFactory.getLogger(LuceneQueryBuilder.class);
+ /**
+ * Logger for this class
+ */
+ private static final Logger log = LoggerFactory
+ .getLogger(LuceneQueryBuilder.class);
- /**
- * Root node of the abstract query tree
- */
- private final QueryRootNode root;
+ /**
+ * Root node of the abstract query tree
+ */
+ private final QueryRootNode root;
- /**
- * Session of the user executing this query
- */
- private final SessionImpl session;
+ /**
+ * Session of the user executing this query
+ */
+ private final SessionImpl session;
- /**
- * The shared item state manager of the workspace.
- */
- private final ItemDataConsumer sharedItemMgr;
+ /**
+ * The shared item state manager of the workspace.
+ */
+ private final ItemDataConsumer sharedItemMgr;
- // /**
- // * A hierarchy manager based on {@link #sharedItemMgr} to resolve paths.
- // */
- // private final HierarchyManager hmgr;
+ // /**
+ // * A hierarchy manager based on {@link #sharedItemMgr} to resolve paths.
+ // */
+ // private final HierarchyManager hmgr;
- /**
- * Namespace mappings to internal prefixes
- */
- private final NamespaceMappings nsMappings;
+ /**
+ * Namespace mappings to internal prefixes
+ */
+ private final NamespaceMappings nsMappings;
- /**
- * Name and Path resolver
- */
- private final LocationFactory resolver;
+ /**
+ * Name and Path resolver
+ */
+ private final LocationFactory resolver;
- /**
- * The analyzer instance to use for contains function query parsing
- */
- private final Analyzer analyzer;
+ /**
+ * The analyzer instance to use for contains function query parsing
+ */
+ private final Analyzer analyzer;
- /**
- * The property type registry.
- */
- private final PropertyTypeRegistry propRegistry;
+ /**
+ * The property type registry.
+ */
+ private final PropertyTypeRegistry propRegistry;
- /**
- * The synonym provider or <code>null</code> if none is configured.
- */
- private final SynonymProvider synonymProvider;
+ /**
+ * The synonym provider or <code>null</code> if none is configured.
+ */
+ private final SynonymProvider synonymProvider;
- /**
- * Wether the index format is new or old.
- */
- private final IndexFormatVersion indexFormatVersion;
+ /**
+ * Wether the index format is new or old.
+ */
+ private final IndexFormatVersion indexFormatVersion;
- /**
- * Exceptions thrown during tree translation
- */
- private final List exceptions = new ArrayList();
+ /**
+ * Exceptions thrown during tree translation
+ */
+ private final List exceptions = new ArrayList();
- private final NodeTypeDataManager nodeTypeDataManager;
+ private final NodeTypeDataManager nodeTypeDataManager;
- /**
- * Creates a new <code>LuceneQueryBuilder</code> instance.
- *
- * @param root the root node of the abstract query tree.
- * @param session of the user executing this query.
- * @param sharedItemMgr the shared item state manager of the
- * workspace.
- * @param hmgr a hierarchy manager based on sharedItemMgr.
- * @param nsMappings namespace resolver for internal prefixes.
- * @param analyzer for parsing the query statement of the contains
- * function.
- * @param propReg the property type registry.
- * @param synonymProvider the synonym provider or <code>null</code> if
- * node is configured.
- * @param indexFormatVersion the index format version for the lucene query.
- * @throws RepositoryException
- */
- private LuceneQueryBuilder(QueryRootNode root, SessionImpl session, ItemDataConsumer sharedItemMgr,
- //HierarchyManager hmgr,
- NamespaceMappings nsMappings, Analyzer analyzer, PropertyTypeRegistry propReg, SynonymProvider synonymProvider,
- IndexFormatVersion indexFormatVersion) throws RepositoryException
- {
- this.root = root;
- this.session = session;
- this.sharedItemMgr = sharedItemMgr;
- //this.hmgr = hmgr;
- this.nsMappings = nsMappings;
- this.analyzer = analyzer;
- this.propRegistry = propReg;
- this.synonymProvider = synonymProvider;
- this.indexFormatVersion = indexFormatVersion;
- this.nodeTypeDataManager = session.getWorkspace().getNodeTypesHolder();
- this.resolver = new LocationFactory(nsMappings);
- }
+ private final VirtualTableResolver<Query> virtualTableResolver;
- /**
- * Creates a lucene {@link org.apache.lucene.search.Query} tree from an
- * abstract query tree.
- *
- * @param root the root node of the abstract query tree.
- * @param session of the user executing the query.
- * @param sharedItemMgr the shared item state manager of the workspace.
- * @param nsMappings namespace resolver for internal prefixes.
- * @param analyzer for parsing the query statement of the contains
- * function.
- * @param propReg the property type registry to lookup type
- * information.
- * @param synonymProvider the synonym provider or <code>null</code> if node
- * is configured.
- * @param indexFormatVersion the index format version to be used
- * @return the lucene query tree.
- * @throws RepositoryException if an error occurs during the translation.
- */
- public static Query createQuery(QueryRootNode root, SessionImpl session, ItemDataConsumer sharedItemMgr,
- NamespaceMappings nsMappings, Analyzer analyzer, PropertyTypeRegistry propReg, SynonymProvider synonymProvider,
- IndexFormatVersion indexFormatVersion) throws RepositoryException
- {
+ /**
+ * Creates a new <code>LuceneQueryBuilder</code> instance.
+ *
+ * @param root
+ * the root node of the abstract query tree.
+ * @param session
+ * of the user executing this query.
+ * @param sharedItemMgr
+ * the shared item state manager of the workspace.
+ * @param hmgr
+ * a hierarchy manager based on sharedItemMgr.
+ * @param nsMappings
+ * namespace resolver for internal prefixes.
+ * @param analyzer
+ * for parsing the query statement of the contains function.
+ * @param propReg
+ * the property type registry.
+ * @param synonymProvider
+ * the synonym provider or <code>null</code> if node is
+ * configured.
+ * @param indexFormatVersion
+ * the index format version for the lucene query.
+ * @param virtualTableResolver
+ * @throws RepositoryException
+ */
+ private LuceneQueryBuilder(
+ QueryRootNode root,
+ SessionImpl session,
+ ItemDataConsumer sharedItemMgr,
+ // HierarchyManager hmgr,
+ NamespaceMappings nsMappings, Analyzer analyzer,
+ PropertyTypeRegistry propReg, SynonymProvider synonymProvider,
+ IndexFormatVersion indexFormatVersion,
+ VirtualTableResolver<Query> virtualTableResolver)
+ throws RepositoryException {
+ this.root = root;
+ this.session = session;
+ this.sharedItemMgr = sharedItemMgr;
+ // this.hmgr = hmgr;
+ this.nsMappings = nsMappings;
+ this.analyzer = analyzer;
+ this.propRegistry = propReg;
+ this.synonymProvider = synonymProvider;
+ this.indexFormatVersion = indexFormatVersion;
+ this.virtualTableResolver = virtualTableResolver;
+ this.nodeTypeDataManager = session.getWorkspace().getNodeTypesHolder();
+ this.resolver = new LocationFactory(nsMappings);
+ }
- LuceneQueryBuilder builder =
- new LuceneQueryBuilder(root, session, sharedItemMgr, nsMappings, analyzer, propReg, synonymProvider,
- indexFormatVersion);
+ /**
+ * Creates a lucene {@link org.apache.lucene.search.Query} tree from an
+ * abstract query tree.
+ *
+ * @param root
+ * the root node of the abstract query tree.
+ * @param session
+ * of the user executing the query.
+ * @param sharedItemMgr
+ * the shared item state manager of the workspace.
+ * @param nsMappings
+ * namespace resolver for internal prefixes.
+ * @param analyzer
+ * for parsing the query statement of the contains function.
+ * @param propReg
+ * the property type registry to lookup type information.
+ * @param synonymProvider
+ * the synonym provider or <code>null</code> if node is
+ * configured.
+ * @param indexFormatVersion
+ * the index format version to be used
+ * @return the lucene query tree.
+ * @throws RepositoryException
+ * if an error occurs during the translation.
+ */
+ public static Query createQuery(QueryRootNode root, SessionImpl session,
+ ItemDataConsumer sharedItemMgr, NamespaceMappings nsMappings,
+ Analyzer analyzer, PropertyTypeRegistry propReg,
+ SynonymProvider synonymProvider,
+ IndexFormatVersion indexFormatVersion,
+ VirtualTableResolver<Query> virtualTableResolver)
+ throws RepositoryException {
- Query q = builder.createLuceneQuery();
- if (builder.exceptions.size() > 0)
- {
- StringBuffer msg = new StringBuffer();
- for (Iterator it = builder.exceptions.iterator(); it.hasNext();)
- {
- msg.append(it.next().toString()).append('\n');
- }
- throw new RepositoryException("Exception building query: " + msg.toString());
- }
- return q;
- }
+ LuceneQueryBuilder builder = new LuceneQueryBuilder(root, session,
+ sharedItemMgr, nsMappings, analyzer, propReg, synonymProvider,
+ indexFormatVersion, virtualTableResolver);
- /**
- * Starts the tree traversal and returns the lucene
- * {@link org.apache.lucene.search.Query}.
- *
- * @return the lucene <code>Query</code>.
- * @throws RepositoryException
- */
- private Query createLuceneQuery() throws RepositoryException
- {
- return (Query)root.accept(this, null);
- }
+ Query q = builder.createLuceneQuery();
+ if (builder.exceptions.size() > 0) {
+ StringBuffer msg = new StringBuffer();
+ for (Iterator it = builder.exceptions.iterator(); it.hasNext();) {
+ msg.append(it.next().toString()).append('\n');
+ }
+ throw new RepositoryException("Exception building query: "
+ + msg.toString());
+ }
+ return q;
+ }
- //---------------------< QueryNodeVisitor interface >-----------------------
+ /**
+ * Starts the tree traversal and returns the lucene
+ * {@link org.apache.lucene.search.Query}.
+ *
+ * @return the lucene <code>Query</code>.
+ * @throws RepositoryException
+ */
+ private Query createLuceneQuery() throws RepositoryException {
+ return (Query) root.accept(this, null);
+ }
- public Object visit(QueryRootNode node, Object data) throws RepositoryException
- {
- BooleanQuery root = new BooleanQuery();
+ // ---------------------< QueryNodeVisitor interface
+ // >-----------------------
- Query wrapped = root;
- if (node.getLocationNode() != null)
- {
- wrapped = (Query)node.getLocationNode().accept(this, root);
- }
+ public Object visit(QueryRootNode node, Object data)
+ throws RepositoryException {
+ BooleanQuery root = new BooleanQuery();
- return wrapped;
- }
+ Query wrapped = root;
+ if (node.getLocationNode() != null) {
+ wrapped = (Query) node.getLocationNode().accept(this, root);
+ }
- public Object visit(OrQueryNode node, Object data) throws RepositoryException
- {
- BooleanQuery orQuery = new BooleanQuery();
- Object[] result = node.acceptOperands(this, null);
- for (int i = 0; i < result.length; i++)
- {
- Query operand = (Query)result[i];
- orQuery.add(operand, Occur.SHOULD);
- }
- return orQuery;
- }
+ return wrapped;
+ }
- public Object visit(AndQueryNode node, Object data) throws RepositoryException
- {
- Object[] result = node.acceptOperands(this, null);
- if (result.length == 0)
- {
- return null;
- }
- BooleanQuery andQuery = new BooleanQuery();
- for (int i = 0; i < result.length; i++)
- {
- Query operand = (Query)result[i];
- andQuery.add(operand, Occur.MUST);
- }
- return andQuery;
- }
+ public Object visit(OrQueryNode node, Object data)
+ throws RepositoryException {
+ BooleanQuery orQuery = new BooleanQuery();
+ Object[] result = node.acceptOperands(this, null);
+ for (int i = 0; i < result.length; i++) {
+ Query operand = (Query) result[i];
+ orQuery.add(operand, Occur.SHOULD);
+ }
+ return orQuery;
+ }
- public Object visit(NotQueryNode node, Object data) throws RepositoryException
- {
- Object[] result = node.acceptOperands(this, null);
- if (result.length == 0)
- {
- return data;
- }
- // join the results
- BooleanQuery b = new BooleanQuery();
- for (int i = 0; i < result.length; i++)
- {
- b.add((Query)result[i], Occur.SHOULD);
- }
- // negate
- return new NotQuery(b);
- }
+ public Object visit(AndQueryNode node, Object data)
+ throws RepositoryException {
+ Object[] result = node.acceptOperands(this, null);
+ if (result.length == 0) {
+ return null;
+ }
+ BooleanQuery andQuery = new BooleanQuery();
+ for (int i = 0; i < result.length; i++) {
+ Query operand = (Query) result[i];
+ andQuery.add(operand, Occur.MUST);
+ }
+ return andQuery;
+ }
- public Object visit(ExactQueryNode node, Object data)
- {
- String field = "";
- String value = "";
- try
- {
- field = resolver.createJCRName(node.getPropertyName()).getAsString();
- value = resolver.createJCRName(node.getValue()).getAsString();
- }
- catch (RepositoryException e)
- {
- // will never happen, prefixes are created when unknown
- }
- return new JackrabbitTermQuery(new Term(FieldNames.PROPERTIES, FieldNames.createNamedValue(field, value)));
- }
+ public Object visit(NotQueryNode node, Object data)
+ throws RepositoryException {
+ Object[] result = node.acceptOperands(this, null);
+ if (result.length == 0) {
+ return data;
+ }
+ // join the results
+ BooleanQuery b = new BooleanQuery();
+ for (int i = 0; i < result.length; i++) {
+ b.add((Query) result[i], Occur.SHOULD);
+ }
+ // negate
+ return new NotQuery(b);
+ }
- public Object visit(NodeTypeQueryNode node, Object data)
- {
+ public Object visit(ExactQueryNode node, Object data) {
+ String field = "";
+ String value = "";
+ try {
+ field = resolver.createJCRName(node.getPropertyName())
+ .getAsString();
+ value = resolver.createJCRName(node.getValue()).getAsString();
+ } catch (RepositoryException e) {
+ // will never happen, prefixes are created when unknown
+ }
+ return new JackrabbitTermQuery(new Term(FieldNames.PROPERTIES,
+ FieldNames.createNamedValue(field, value)));
+ }
- List terms = new ArrayList();
- try
- {
- String mixinTypesField = resolver.createJCRName(Constants.JCR_MIXINTYPES).getAsString();
- String primaryTypeField = resolver.createJCRName(Constants.JCR_PRIMARYTYPE).getAsString();
+ public Object visit(NodeTypeQueryNode node, Object data) {
- NodeTypeData base = nodeTypeDataManager.findNodeType(node.getValue());
+ try {
+ return virtualTableResolver.resolve(node.getValue(), true);
+ } catch (InvalidQueryException e1) {
+ exceptions.add(e1);
+ } catch (RepositoryException e1) {
+ exceptions.add(e1);
+ }
+ return new BooleanQuery();
+ // // (result)
+ // List terms = new ArrayList();
+ // try {
+ // String mixinTypesField = resolver.createJCRName(
+ // Constants.JCR_MIXINTYPES).getAsString();
+ // String primaryTypeField = resolver.createJCRName(
+ // Constants.JCR_PRIMARYTYPE).getAsString();
+ //
+ // NodeTypeData base = nodeTypeDataManager.findNodeType(node
+ // .getValue());
+ //
+ // if (base.isMixin()) {
+ // // search for nodes where jcr:mixinTypes is set to this mixin
+ // Term t = new Term(FieldNames.PROPERTIES, FieldNames
+ // .createNamedValue(mixinTypesField, resolver
+ // .createJCRName(node.getValue()).getAsString()));
+ // terms.add(t);
+ // } else {
+ // // search for nodes where jcr:primaryType is set to this type
+ // Term t = new Term(FieldNames.PROPERTIES, FieldNames
+ // .createNamedValue(primaryTypeField, resolver
+ // .createJCRName(node.getValue()).getAsString()));
+ // terms.add(t);
+ // }
+ //
+ // // now search for all node types that are derived from base
+ // Collection<NodeTypeData> allTypes = nodeTypeDataManager
+ // .getAllNodeTypes();
+ // for (NodeTypeData nodeTypeData : allTypes) {
+ // InternalQName[] superTypes = nodeTypeData
+ // .getDeclaredSupertypeNames();
+ // if (Arrays.asList(superTypes).contains(base.getName())) {
+ // String ntName = nsMappings.translateName(nodeTypeData
+ // .getName());
+ // Term t;
+ // if (nodeTypeData.isMixin()) {
+ // // search on jcr:mixinTypes
+ // t = new Term(FieldNames.PROPERTIES, FieldNames
+ // .createNamedValue(mixinTypesField, ntName));
+ // } else {
+ // // search on jcr:primaryType
+ // t = new Term(FieldNames.PROPERTIES, FieldNames
+ // .createNamedValue(primaryTypeField, ntName));
+ // }
+ // terms.add(t);
+ // }
+ // }
+ // } catch (IllegalNameException e) {
+ // exceptions.add(e);
+ // } catch (RepositoryException e) {
+ // exceptions.add(e);
+ // }
+ // if (terms.size() == 0) {
+ // // exception occured
+ // return new BooleanQuery();
+ // } else if (terms.size() == 1) {
+ // return new JackrabbitTermQuery((Term) terms.get(0));
+ // } else {
+ // BooleanQuery b = new BooleanQuery();
+ // for (Iterator it = terms.iterator(); it.hasNext();) {
+ // b.add(new JackrabbitTermQuery((Term) it.next()), Occur.SHOULD);
+ // }
+ // return b;
+ // }
+ }
- if (base.isMixin())
- {
- // search for nodes where jcr:mixinTypes is set to this mixin
- Term t =
- new Term(FieldNames.PROPERTIES, FieldNames.createNamedValue(mixinTypesField, resolver.createJCRName(
- node.getValue()).getAsString()));
- terms.add(t);
- }
- else
- {
- // search for nodes where jcr:primaryType is set to this type
- Term t =
- new Term(FieldNames.PROPERTIES, FieldNames.createNamedValue(primaryTypeField, resolver.createJCRName(
- node.getValue()).getAsString()));
- terms.add(t);
- }
+ public Object visit(TextsearchQueryNode node, Object data) {
+ try {
+ QPath relPath = node.getRelativePath();
+ String fieldname;
+ if (relPath == null || !node.getReferencesProperty()) {
+ // fulltext on node
+ fieldname = FieldNames.FULLTEXT;
+ } else {
+ // final path element is a property name
- // now search for all node types that are derived from base
- Collection<NodeTypeData> allTypes = nodeTypeDataManager.getAllNodeTypes();
- for (NodeTypeData nodeTypeData : allTypes)
- {
- InternalQName[] superTypes = nodeTypeData.getDeclaredSupertypeNames();
- if (Arrays.asList(superTypes).contains(base.getName()))
- {
- String ntName = nsMappings.translateName(nodeTypeData.getName());
- Term t;
- if (nodeTypeData.isMixin())
- {
- // search on jcr:mixinTypes
- t = new Term(FieldNames.PROPERTIES, FieldNames.createNamedValue(mixinTypesField, ntName));
- }
- else
- {
- // search on jcr:primaryType
- t = new Term(FieldNames.PROPERTIES, FieldNames.createNamedValue(primaryTypeField, ntName));
- }
- terms.add(t);
- }
- }
- }
- catch (IllegalNameException e)
- {
- exceptions.add(e);
- }
- catch (RepositoryException e)
- {
- exceptions.add(e);
- }
- if (terms.size() == 0)
- {
- // exception occured
- return new BooleanQuery();
- }
- else if (terms.size() == 1)
- {
- return new JackrabbitTermQuery((Term)terms.get(0));
- }
- else
- {
- BooleanQuery b = new BooleanQuery();
- for (Iterator it = terms.iterator(); it.hasNext();)
- {
- b.add(new JackrabbitTermQuery((Term)it.next()), Occur.SHOULD);
- }
- return b;
- }
- }
+ fieldname = resolver.createJCRName(relPath.getName())
+ .getAsString();
+ int idx = fieldname.indexOf(':');
+ fieldname = fieldname.substring(0, idx + 1)
+ + FieldNames.FULLTEXT_PREFIX
+ + fieldname.substring(idx + 1);
- public Object visit(TextsearchQueryNode node, Object data)
- {
- try
- {
- QPath relPath = node.getRelativePath();
- String fieldname;
- if (relPath == null || !node.getReferencesProperty())
- {
- // fulltext on node
- fieldname = FieldNames.FULLTEXT;
- }
- else
- {
- // final path element is a property name
+ }
+ QueryParser parser = new JackrabbitQueryParser(fieldname, analyzer,
+ synonymProvider);
+ Query context = parser.parse(node.getQuery());
+ if (relPath != null
+ && (!node.getReferencesProperty() || relPath.getEntries().length > 1)) {
+ // text search on some child axis
+ QPathEntry[] elements = relPath.getEntries();
+ for (int i = elements.length - 1; i >= 0; i--) {
+ QPathEntry name = null;
+ if (!elements[i].equals(RelationQueryNode.STAR_NAME_TEST)) {
+ name = elements[i];
+ }
+ // join text search with name test
+ // if path references property that's elements.length - 2
+ // if path references node that's elements.length - 1
+ if (name != null
+ && ((node.getReferencesProperty() && i == elements.length - 2) || (!node
+ .getReferencesProperty() && i == elements.length - 1))) {
+ Query q = new NameQuery(name, indexFormatVersion,
+ nsMappings);
+ BooleanQuery and = new BooleanQuery();
+ and.add(q, Occur.MUST);
+ and.add(context, Occur.MUST);
+ context = and;
+ } else if ((node.getReferencesProperty() && i < elements.length - 2)
+ || (!node.getReferencesProperty() && i < elements.length - 1)) {
+ // otherwise do a parent axis step
+ context = new ParentAxisQuery(context, name,
+ indexFormatVersion, nsMappings);
+ }
+ }
+ // finally select parent
+ context = new ParentAxisQuery(context, null,
+ indexFormatVersion, nsMappings);
+ }
+ return context;
+ } catch (NamespaceException e) {
+ exceptions.add(e);
+ } catch (ParseException e) {
+ exceptions.add(e);
+ } catch (RepositoryException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return null;
+ }
- fieldname = resolver.createJCRName(relPath.getName()).getAsString();
- int idx = fieldname.indexOf(':');
- fieldname = fieldname.substring(0, idx + 1)
- + FieldNames.FULLTEXT_PREFIX + fieldname.substring(idx + 1);
-
- }
- QueryParser parser = new JackrabbitQueryParser(fieldname, analyzer, synonymProvider);
- Query context = parser.parse(node.getQuery());
- if (relPath != null && (!node.getReferencesProperty() || relPath.getEntries().length > 1))
- {
- // text search on some child axis
- QPathEntry[] elements = relPath.getEntries();
- for (int i = elements.length - 1; i >= 0; i--)
- {
- QPathEntry name = null;
- if (!elements[i].equals(RelationQueryNode.STAR_NAME_TEST))
- {
- name = elements[i];
- }
- // join text search with name test
- // if path references property that's elements.length - 2
- // if path references node that's elements.length - 1
- if (name != null
- && ((node.getReferencesProperty() && i == elements.length - 2) || (!node.getReferencesProperty() && i == elements.length - 1)))
- {
- Query q = new NameQuery(name, indexFormatVersion, nsMappings);
- BooleanQuery and = new BooleanQuery();
- and.add(q, Occur.MUST);
- and.add(context, Occur.MUST);
- context = and;
- }
- else if ((node.getReferencesProperty() && i < elements.length - 2)
- || (!node.getReferencesProperty() && i < elements.length - 1))
- {
- // otherwise do a parent axis step
- context = new ParentAxisQuery(context, name, indexFormatVersion, nsMappings);
- }
- }
- // finally select parent
- context = new ParentAxisQuery(context, null, indexFormatVersion, nsMappings);
- }
- return context;
- }
- catch (NamespaceException e)
- {
- exceptions.add(e);
- }
- catch (ParseException e)
- {
- exceptions.add(e);
- }
- catch (RepositoryException e)
- {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- return null;
- }
+ public Object visit(PathQueryNode node, Object data)
+ throws RepositoryException {
+ Query context = null;
+ LocationStepQueryNode[] steps = node.getPathSteps();
+ if (steps.length > 0) {
+ if (node.isAbsolute() && !steps[0].getIncludeDescendants()) {
+ // eat up first step
+ InternalQName nameTest = steps[0].getNameTest();
+ if (nameTest == null) {
+ // this is equivalent to the root node
+ context = new JackrabbitTermQuery(new Term(FieldNames.UUID,
+ Constants.ROOT_UUID));
+ } else if (nameTest.getName().length() == 0) {
+ // root node
+ context = new JackrabbitTermQuery(new Term(FieldNames.UUID,
+ Constants.ROOT_UUID));
+ } else {
+ // then this is a node != the root node
+ // will never match anything!
+ BooleanQuery and = new BooleanQuery();
+ and.add(new JackrabbitTermQuery(new Term(FieldNames.UUID,
+ Constants.ROOT_UUID)), Occur.MUST);
+ and.add(new NameQuery(nameTest, indexFormatVersion,
+ nsMappings), Occur.MUST);
+ context = and;
+ }
+ LocationStepQueryNode[] tmp = new LocationStepQueryNode[steps.length - 1];
+ System.arraycopy(steps, 1, tmp, 0, steps.length - 1);
+ steps = tmp;
+ } else {
+ // path is 1) relative or 2) descendant-or-self
+ // use root node as context
+ context = new JackrabbitTermQuery(new Term(FieldNames.UUID,
+ Constants.ROOT_UUID));
+ }
+ } else {
+ exceptions.add(new InvalidQueryException(
+ "Number of location steps must be > 0"));
+ }
+ // loop over steps
+ for (int i = 0; i < steps.length; i++) {
+ context = (Query) steps[i].accept(this, context);
+ }
+ if (data instanceof BooleanQuery) {
+ BooleanQuery constraint = (BooleanQuery) data;
+ if (constraint.getClauses().length > 0) {
+ constraint.add(context, Occur.MUST);
+ context = constraint;
+ }
+ }
+ return context;
+ }
- public Object visit(PathQueryNode node, Object data) throws RepositoryException
- {
- Query context = null;
- LocationStepQueryNode[] steps = node.getPathSteps();
- if (steps.length > 0)
- {
- if (node.isAbsolute() && !steps[0].getIncludeDescendants())
- {
- // eat up first step
- InternalQName nameTest = steps[0].getNameTest();
- if (nameTest == null)
- {
- // this is equivalent to the root node
- context = new JackrabbitTermQuery(new Term(FieldNames.UUID, Constants.ROOT_UUID));
- }
- else if (nameTest.getName().length() == 0)
- {
- // root node
- context = new JackrabbitTermQuery(new Term(FieldNames.UUID, Constants.ROOT_UUID));
- }
- else
- {
- // then this is a node != the root node
- // will never match anything!
- BooleanQuery and = new BooleanQuery();
- and.add(new JackrabbitTermQuery(new Term(FieldNames.UUID, Constants.ROOT_UUID)), Occur.MUST);
- and.add(new NameQuery(nameTest, indexFormatVersion, nsMappings), Occur.MUST);
- context = and;
- }
- LocationStepQueryNode[] tmp = new LocationStepQueryNode[steps.length - 1];
- System.arraycopy(steps, 1, tmp, 0, steps.length - 1);
- steps = tmp;
- }
- else
- {
- // path is 1) relative or 2) descendant-or-self
- // use root node as context
- context = new JackrabbitTermQuery(new Term(FieldNames.UUID, Constants.ROOT_UUID));
- }
- }
- else
- {
- exceptions.add(new InvalidQueryException("Number of location steps must be > 0"));
- }
- // loop over steps
- for (int i = 0; i < steps.length; i++)
- {
- context = (Query)steps[i].accept(this, context);
- }
- if (data instanceof BooleanQuery)
- {
- BooleanQuery constraint = (BooleanQuery)data;
- if (constraint.getClauses().length > 0)
- {
- constraint.add(context, Occur.MUST);
- context = constraint;
- }
- }
- return context;
- }
+ public Object visit(LocationStepQueryNode node, Object data)
+ throws RepositoryException {
+ Query context = (Query) data;
+ BooleanQuery andQuery = new BooleanQuery();
- public Object visit(LocationStepQueryNode node, Object data) throws RepositoryException
- {
- Query context = (Query)data;
- BooleanQuery andQuery = new BooleanQuery();
+ if (context == null) {
+ exceptions.add(new IllegalArgumentException("Unsupported query"));
+ }
- if (context == null)
- {
- exceptions.add(new IllegalArgumentException("Unsupported query"));
- }
+ // predicate on step?
+ Object[] predicates = node.acceptOperands(this, data);
+ for (int i = 0; i < predicates.length; i++) {
+ andQuery.add((Query) predicates[i], Occur.MUST);
+ }
- // predicate on step?
- Object[] predicates = node.acceptOperands(this, data);
- for (int i = 0; i < predicates.length; i++)
- {
- andQuery.add((Query)predicates[i], Occur.MUST);
- }
+ // check for position predicate
+ QueryNode[] pred = node.getPredicates();
+ for (int i = 0; i < pred.length; i++) {
+ if (pred[i].getType() == QueryNode.TYPE_RELATION) {
+ RelationQueryNode pos = (RelationQueryNode) pred[i];
+ if (pos.getValueType() == QueryConstants.TYPE_POSITION) {
+ node.setIndex(pos.getPositionValue());
+ }
+ }
+ }
- // check for position predicate
- QueryNode[] pred = node.getPredicates();
- for (int i = 0; i < pred.length; i++)
- {
- if (pred[i].getType() == QueryNode.TYPE_RELATION)
- {
- RelationQueryNode pos = (RelationQueryNode)pred[i];
- if (pos.getValueType() == QueryConstants.TYPE_POSITION)
- {
- node.setIndex(pos.getPositionValue());
- }
- }
- }
+ NameQuery nameTest = null;
+ if (node.getNameTest() != null) {
+ nameTest = new NameQuery(node.getNameTest(), indexFormatVersion,
+ nsMappings);
+ }
- NameQuery nameTest = null;
- if (node.getNameTest() != null)
- {
- nameTest = new NameQuery(node.getNameTest(), indexFormatVersion, nsMappings);
- }
+ if (node.getIncludeDescendants()) {
+ if (nameTest != null) {
+ andQuery.add(new DescendantSelfAxisQuery(context, nameTest,
+ false), Occur.MUST);
+ } else {
+ // descendant-or-self with nametest=*
+ if (predicates.length > 0) {
+ // if we have a predicate attached, the condition acts as
+ // the sub query.
- if (node.getIncludeDescendants())
- {
- if (nameTest != null)
- {
- andQuery.add(new DescendantSelfAxisQuery(context, nameTest, false), Occur.MUST);
- }
- else
- {
- // descendant-or-self with nametest=*
- if (predicates.length > 0)
- {
- // if we have a predicate attached, the condition acts as
- // the sub query.
+ // only use descendant axis if path is not //*
+ // otherwise the query for the predicate can be used itself
+ PathQueryNode pathNode = (PathQueryNode) node.getParent();
+ if (pathNode.getPathSteps()[0] != node) {
+ Query subQuery = new DescendantSelfAxisQuery(context,
+ andQuery, false);
+ andQuery = new BooleanQuery();
+ andQuery.add(subQuery, Occur.MUST);
+ }
+ } else {
+ // todo this will traverse the whole index, optimize!
+ // only use descendant axis if path is not //*
+ PathQueryNode pathNode = (PathQueryNode) node.getParent();
+ if (pathNode.getPathSteps()[0] != node) {
+ if (node.getIndex() == LocationStepQueryNode.NONE) {
+ context = new DescendantSelfAxisQuery(context,
+ false);
+ andQuery.add(context, Occur.MUST);
+ } else {
+ context = new DescendantSelfAxisQuery(context, true);
+ andQuery
+ .add(new ChildAxisQuery(sharedItemMgr,
+ context, null, node.getIndex(),
+ indexFormatVersion, nsMappings),
+ Occur.MUST);
+ }
+ } else {
+ andQuery.add(new MatchAllDocsQuery(), Occur.MUST);
+ }
+ }
+ }
+ } else {
+ // name test
+ if (nameTest != null) {
+ andQuery.add(new ChildAxisQuery(sharedItemMgr, context,
+ nameTest.getName(), node.getIndex(),
+ indexFormatVersion, nsMappings), Occur.MUST);
+ } else {
+ // select child nodes
+ andQuery.add(new ChildAxisQuery(sharedItemMgr, context, null,
+ node.getIndex(), indexFormatVersion, nsMappings),
+ Occur.MUST);
+ }
+ }
- // only use descendant axis if path is not //*
- // otherwise the query for the predicate can be used itself
- PathQueryNode pathNode = (PathQueryNode)node.getParent();
- if (pathNode.getPathSteps()[0] != node)
- {
- Query subQuery = new DescendantSelfAxisQuery(context, andQuery, false);
- andQuery = new BooleanQuery();
- andQuery.add(subQuery, Occur.MUST);
- }
- }
- else
- {
- // todo this will traverse the whole index, optimize!
- // only use descendant axis if path is not //*
- PathQueryNode pathNode = (PathQueryNode)node.getParent();
- if (pathNode.getPathSteps()[0] != node)
- {
- if (node.getIndex() == LocationStepQueryNode.NONE)
- {
- context = new DescendantSelfAxisQuery(context, false);
- andQuery.add(context, Occur.MUST);
- }
- else
- {
- context = new DescendantSelfAxisQuery(context, true);
- andQuery.add(new ChildAxisQuery(sharedItemMgr, context, null, node.getIndex(), indexFormatVersion,
- nsMappings), Occur.MUST);
- }
- }
- else
- {
- andQuery.add(new MatchAllDocsQuery(), Occur.MUST);
- }
- }
- }
- }
- else
- {
- // name test
- if (nameTest != null)
- {
- andQuery.add(new ChildAxisQuery(sharedItemMgr, context, nameTest.getName(), node.getIndex(),
- indexFormatVersion, nsMappings), Occur.MUST);
- }
- else
- {
- // select child nodes
- andQuery.add(new ChildAxisQuery(sharedItemMgr, context, null, node.getIndex(), indexFormatVersion,
- nsMappings), Occur.MUST);
- }
- }
+ return andQuery;
+ }
- return andQuery;
- }
+ public Object visit(DerefQueryNode node, Object data)
+ throws RepositoryException {
+ Query context = (Query) data;
+ if (context == null) {
+ exceptions.add(new IllegalArgumentException("Unsupported query"));
+ }
- public Object visit(DerefQueryNode node, Object data) throws RepositoryException
- {
- Query context = (Query)data;
- if (context == null)
- {
- exceptions.add(new IllegalArgumentException("Unsupported query"));
- }
+ try {
+ String refProperty = resolver.createJCRName(node.getRefProperty())
+ .getAsString();
- try
- {
- String refProperty = resolver.createJCRName(node.getRefProperty()).getAsString();
+ if (node.getIncludeDescendants()) {
+ Query refPropQuery = Util.createMatchAllQuery(refProperty,
+ indexFormatVersion);
+ context = new DescendantSelfAxisQuery(context, refPropQuery,
+ false);
+ }
- if (node.getIncludeDescendants())
- {
- Query refPropQuery = Util.createMatchAllQuery(refProperty, indexFormatVersion);
- context = new DescendantSelfAxisQuery(context, refPropQuery, false);
- }
+ context = new DerefQuery(context, refProperty, node.getNameTest(),
+ indexFormatVersion, nsMappings);
- context = new DerefQuery(context, refProperty, node.getNameTest(), indexFormatVersion, nsMappings);
+ // attach predicates
+ Object[] predicates = node.acceptOperands(this, data);
+ if (predicates.length > 0) {
+ BooleanQuery andQuery = new BooleanQuery();
+ for (int i = 0; i < predicates.length; i++) {
+ andQuery.add((Query) predicates[i], Occur.MUST);
+ }
+ andQuery.add(context, Occur.MUST);
+ context = andQuery;
+ }
- // attach predicates
- Object[] predicates = node.acceptOperands(this, data);
- if (predicates.length > 0)
- {
- BooleanQuery andQuery = new BooleanQuery();
- for (int i = 0; i < predicates.length; i++)
- {
- andQuery.add((Query)predicates[i], Occur.MUST);
- }
- andQuery.add(context, Occur.MUST);
- context = andQuery;
- }
+ } catch (NamespaceException e) {
+ // should never happen
+ exceptions.add(e);
+ }
- }
- catch (NamespaceException e)
- {
- // should never happen
- exceptions.add(e);
- }
+ return context;
+ }
- return context;
- }
+ public Object visit(RelationQueryNode node, Object data)
+ throws RepositoryException {
+ Query query;
+ String[] stringValues = new String[1];
+ switch (node.getValueType()) {
+ case 0:
+ // not set: either IS NULL or IS NOT NULL
+ break;
+ case QueryConstants.TYPE_DATE:
+ stringValues[0] = DateField.dateToString(node.getDateValue());
+ break;
+ case QueryConstants.TYPE_DOUBLE:
+ stringValues[0] = DoubleField.doubleToString(node.getDoubleValue());
+ break;
+ case QueryConstants.TYPE_LONG:
+ stringValues[0] = LongField.longToString(node.getLongValue());
+ break;
+ case QueryConstants.TYPE_STRING:
+ if (node.getOperation() == QueryConstants.OPERATION_EQ_GENERAL
+ || node.getOperation() == QueryConstants.OPERATION_EQ_VALUE
+ || node.getOperation() == QueryConstants.OPERATION_NE_GENERAL
+ || node.getOperation() == QueryConstants.OPERATION_NE_VALUE) {
+ // only use coercing on non-range operations
+ InternalQName propertyName = node.getRelativePath().getName();
+ stringValues = getStringValues(propertyName, node
+ .getStringValue());
+ } else {
+ stringValues[0] = node.getStringValue();
+ }
+ break;
+ case QueryConstants.TYPE_POSITION:
+ // ignore position. is handled in the location step
+ return null;
+ default:
+ throw new IllegalArgumentException("Unknown relation type: "
+ + node.getValueType());
+ }
- public Object visit(RelationQueryNode node, Object data) throws RepositoryException
- {
- Query query;
- String[] stringValues = new String[1];
- switch (node.getValueType())
- {
- case 0 :
- // not set: either IS NULL or IS NOT NULL
- break;
- case QueryConstants.TYPE_DATE :
- stringValues[0] = DateField.dateToString(node.getDateValue());
- break;
- case QueryConstants.TYPE_DOUBLE :
- stringValues[0] = DoubleField.doubleToString(node.getDoubleValue());
- break;
- case QueryConstants.TYPE_LONG :
- stringValues[0] = LongField.longToString(node.getLongValue());
- break;
- case QueryConstants.TYPE_STRING :
- if (node.getOperation() == QueryConstants.OPERATION_EQ_GENERAL
- || node.getOperation() == QueryConstants.OPERATION_EQ_VALUE
- || node.getOperation() == QueryConstants.OPERATION_NE_GENERAL
- || node.getOperation() == QueryConstants.OPERATION_NE_VALUE)
- {
- // only use coercing on non-range operations
- InternalQName propertyName = node.getRelativePath().getName();
- stringValues = getStringValues(propertyName, node.getStringValue());
- }
- else
- {
- stringValues[0] = node.getStringValue();
- }
- break;
- case QueryConstants.TYPE_POSITION :
- // ignore position. is handled in the location step
- return null;
- default :
- throw new IllegalArgumentException("Unknown relation type: " + node.getValueType());
- }
+ if (node.getRelativePath() == null
+ && node.getOperation() != QueryConstants.OPERATION_SIMILAR
+ && node.getOperation() != QueryConstants.OPERATION_SPELLCHECK) {
+ exceptions.add(new InvalidQueryException(
+ "@* not supported in predicate"));
+ return data;
+ }
- if (node.getRelativePath() == null && node.getOperation() != QueryConstants.OPERATION_SIMILAR
- && node.getOperation() != QueryConstants.OPERATION_SPELLCHECK)
- {
- exceptions.add(new InvalidQueryException("@* not supported in predicate"));
- return data;
- }
+ // get property transformation
+ final int[] transform = new int[] { TransformConstants.TRANSFORM_NONE };
+ node.acceptOperands(new DefaultQueryNodeVisitor() {
+ public Object visit(PropertyFunctionQueryNode node, Object data) {
+ if (node.getFunctionName().equals(
+ PropertyFunctionQueryNode.LOWER_CASE)) {
+ transform[0] = TransformConstants.TRANSFORM_LOWER_CASE;
+ } else if (node.getFunctionName().equals(
+ PropertyFunctionQueryNode.UPPER_CASE)) {
+ transform[0] = TransformConstants.TRANSFORM_UPPER_CASE;
+ }
+ return data;
+ }
+ }, null);
- // get property transformation
- final int[] transform = new int[]{TransformConstants.TRANSFORM_NONE};
- node.acceptOperands(new DefaultQueryNodeVisitor()
- {
- public Object visit(PropertyFunctionQueryNode node, Object data)
- {
- if (node.getFunctionName().equals(PropertyFunctionQueryNode.LOWER_CASE))
- {
- transform[0] = TransformConstants.TRANSFORM_LOWER_CASE;
- }
- else if (node.getFunctionName().equals(PropertyFunctionQueryNode.UPPER_CASE))
- {
- transform[0] = TransformConstants.TRANSFORM_UPPER_CASE;
- }
- return data;
- }
- }, null);
+ QPath relPath = node.getRelativePath();
+ if (node.getOperation() == QueryConstants.OPERATION_SIMILAR) {
+ // this is a bit ugly:
+ // add the name of a dummy property because relPath actually
+ // references a property. whereas the relPath of the similar
+ // operation references a node
+ relPath = QPath.makeChildPath(relPath, Constants.JCR_PRIMARYTYPE);
+ }
+ String field = "";
+ try {
+ field = resolver.createJCRName(relPath.getName()).getAsString();
+ } catch (NamespaceException e) {
+ // should never happen
+ exceptions.add(e);
+ }
- QPath relPath = node.getRelativePath();
- if (node.getOperation() == QueryConstants.OPERATION_SIMILAR)
- {
- // this is a bit ugly:
- // add the name of a dummy property because relPath actually
- // references a property. whereas the relPath of the similar
- // operation references a node
- relPath = QPath.makeChildPath(relPath, Constants.JCR_PRIMARYTYPE);
- }
- String field = "";
- try
- {
- field = resolver.createJCRName(relPath.getName()).getAsString();
- }
- catch (NamespaceException e)
- {
- // should never happen
- exceptions.add(e);
- }
+ // support for fn:name()
+ InternalQName propName = relPath.getName();
+ if (propName.getNamespace().equals(NS_FN_URI)
+ && propName.getName().equals("name()")) {
+ if (node.getValueType() != QueryConstants.TYPE_STRING) {
+ exceptions.add(new InvalidQueryException("Name function can "
+ + "only be used in conjunction with a string literal"));
+ return data;
+ }
+ if (node.getOperation() != QueryConstants.OPERATION_EQ_VALUE
+ && node.getOperation() != QueryConstants.OPERATION_EQ_GENERAL) {
+ exceptions
+ .add(new InvalidQueryException(
+ "Name function can "
+ + "only be used in conjunction with an equals operator"));
+ return data;
+ }
+ // check if string literal is a valid XML Name
+ if (XMLChar.isValidName(node.getStringValue())) {
+ // parse string literal as JCR Name
+ try {
+ InternalQName n = session
+ .getLocationFactory()
+ .parseJCRName(ISO9075.decode(node.getStringValue()))
+ .getInternalName();
+ query = new NameQuery(n, indexFormatVersion, nsMappings);
+ } catch (RepositoryException e) {
+ exceptions.add(e);
+ return data;
+ }
+ } else {
+ // will never match -> create dummy query
+ query = new BooleanQuery();
+ }
+ } else {
+ switch (node.getOperation()) {
+ case QueryConstants.OPERATION_EQ_VALUE: // =
+ case QueryConstants.OPERATION_EQ_GENERAL:
+ BooleanQuery or = new BooleanQuery();
+ for (int i = 0; i < stringValues.length; i++) {
+ Term t = new Term(FieldNames.PROPERTIES, FieldNames
+ .createNamedValue(field, stringValues[i]));
+ Query q;
+ if (transform[0] == TransformConstants.TRANSFORM_UPPER_CASE) {
+ q = new CaseTermQuery.Upper(t);
+ } else if (transform[0] == TransformConstants.TRANSFORM_LOWER_CASE) {
+ q = new CaseTermQuery.Lower(t);
+ } else {
+ q = new JackrabbitTermQuery(t);
+ }
+ or.add(q, Occur.SHOULD);
+ }
+ query = or;
+ if (node.getOperation() == QueryConstants.OPERATION_EQ_VALUE) {
+ query = createSingleValueConstraint(or, field);
+ }
+ break;
+ case QueryConstants.OPERATION_GE_VALUE: // >=
+ case QueryConstants.OPERATION_GE_GENERAL:
+ or = new BooleanQuery();
+ for (int i = 0; i < stringValues.length; i++) {
+ Term lower = new Term(FieldNames.PROPERTIES, FieldNames
+ .createNamedValue(field, stringValues[i]));
+ Term upper = new Term(FieldNames.PROPERTIES, FieldNames
+ .createNamedValue(field, "\uFFFF"));
+ or.add(new RangeQuery(lower, upper, true, transform[0]),
+ Occur.SHOULD);
+ }
+ query = or;
+ if (node.getOperation() == QueryConstants.OPERATION_GE_VALUE) {
+ query = createSingleValueConstraint(or, field);
+ }
+ break;
+ case QueryConstants.OPERATION_GT_VALUE: // >
+ case QueryConstants.OPERATION_GT_GENERAL:
+ or = new BooleanQuery();
+ for (int i = 0; i < stringValues.length; i++) {
+ Term lower = new Term(FieldNames.PROPERTIES, FieldNames
+ .createNamedValue(field, stringValues[i]));
+ Term upper = new Term(FieldNames.PROPERTIES, FieldNames
+ .createNamedValue(field, "\uFFFF"));
+ or.add(new RangeQuery(lower, upper, false, transform[0]),
+ Occur.SHOULD);
+ }
+ query = or;
+ if (node.getOperation() == QueryConstants.OPERATION_GT_VALUE) {
+ query = createSingleValueConstraint(or, field);
+ }
+ break;
+ case QueryConstants.OPERATION_LE_VALUE: // <=
+ case QueryConstants.OPERATION_LE_GENERAL: // <=
+ or = new BooleanQuery();
+ for (int i = 0; i < stringValues.length; i++) {
+ Term lower = new Term(FieldNames.PROPERTIES, FieldNames
+ .createNamedValue(field, ""));
+ Term upper = new Term(FieldNames.PROPERTIES, FieldNames
+ .createNamedValue(field, stringValues[i]));
+ or.add(new RangeQuery(lower, upper, true, transform[0]),
+ Occur.SHOULD);
+ }
+ query = or;
+ if (node.getOperation() == QueryConstants.OPERATION_LE_VALUE) {
+ query = createSingleValueConstraint(query, field);
+ }
+ break;
+ case QueryConstants.OPERATION_LIKE: // LIKE
+ // the like operation always has one string value.
+ // no coercing, see above
+ if (stringValues[0].equals("%")) {
+ query = Util.createMatchAllQuery(field, indexFormatVersion);
+ } else {
+ query = new WildcardQuery(FieldNames.PROPERTIES, field,
+ stringValues[0], transform[0]);
+ }
+ break;
+ case QueryConstants.OPERATION_LT_VALUE: // <
+ case QueryConstants.OPERATION_LT_GENERAL:
+ or = new BooleanQuery();
+ for (int i = 0; i < stringValues.length; i++) {
+ Term lower = new Term(FieldNames.PROPERTIES, FieldNames
+ .createNamedValue(field, ""));
+ Term upper = new Term(FieldNames.PROPERTIES, FieldNames
+ .createNamedValue(field, stringValues[i]));
+ or.add(new RangeQuery(lower, upper, false, transform[0]),
+ Occur.SHOULD);
+ }
+ query = or;
+ if (node.getOperation() == QueryConstants.OPERATION_LT_VALUE) {
+ query = createSingleValueConstraint(or, field);
+ }
+ break;
+ case QueryConstants.OPERATION_NE_VALUE: // !=
+ // match nodes with property 'field' that includes svp and mvp
+ BooleanQuery notQuery = new BooleanQuery();
+ notQuery.add(Util
+ .createMatchAllQuery(field, indexFormatVersion),
+ Occur.SHOULD);
+ // exclude all nodes where 'field' has the term in question
+ for (int i = 0; i < stringValues.length; i++) {
+ Term t = new Term(FieldNames.PROPERTIES, FieldNames
+ .createNamedValue(field, stringValues[i]));
+ Query q;
+ if (transform[0] == TransformConstants.TRANSFORM_UPPER_CASE) {
+ q = new CaseTermQuery.Upper(t);
+ } else if (transform[0] == TransformConstants.TRANSFORM_LOWER_CASE) {
+ q = new CaseTermQuery.Lower(t);
+ } else {
+ q = new JackrabbitTermQuery(t);
+ }
+ notQuery.add(q, Occur.MUST_NOT);
+ }
+ // and exclude all nodes where 'field' is multi valued
+ notQuery.add(new JackrabbitTermQuery(new Term(FieldNames.MVP,
+ field)), Occur.MUST_NOT);
+ query = notQuery;
+ break;
+ case QueryConstants.OPERATION_NE_GENERAL: // !=
+ // that's:
+ // all nodes with property 'field'
+ // minus the nodes that have a single property 'field' that is
+ // not equal to term in question
+ // minus the nodes that have a multi-valued property 'field' and
+ // all values are equal to term in question
+ notQuery = new BooleanQuery();
+ notQuery.add(Util
+ .createMatchAllQuery(field, indexFormatVersion),
+ Occur.SHOULD);
+ for (int i = 0; i < stringValues.length; i++) {
+ // exclude the nodes that have the term and are single
+ // valued
+ Term t = new Term(FieldNames.PROPERTIES, FieldNames
+ .createNamedValue(field, stringValues[i]));
+ Query svp = new NotQuery(new JackrabbitTermQuery(new Term(
+ FieldNames.MVP, field)));
+ BooleanQuery and = new BooleanQuery();
+ Query q;
+ if (transform[0] == TransformConstants.TRANSFORM_UPPER_CASE) {
+ q = new CaseTermQuery.Upper(t);
+ } else if (transform[0] == TransformConstants.TRANSFORM_LOWER_CASE) {
+ q = new CaseTermQuery.Lower(t);
+ } else {
+ q = new JackrabbitTermQuery(t);
+ }
+ and.add(q, Occur.MUST);
+ and.add(svp, Occur.MUST);
+ notQuery.add(and, Occur.MUST_NOT);
+ }
+ // todo above also excludes multi-valued properties that contain
+ // multiple instances of only stringValues. e.g. text={foo, foo}
+ query = notQuery;
+ break;
+ case QueryConstants.OPERATION_NULL:
+ query = new NotQuery(Util.createMatchAllQuery(field,
+ indexFormatVersion));
+ break;
+ case QueryConstants.OPERATION_SIMILAR:
+ String uuid = "x";
+ try {
+ // throw new UnsupportedOperationException();
+ QPath path = resolver.parseJCRPath(node.getStringValue())
+ .getInternalPath();
+ NodeData parent = (NodeData) sharedItemMgr
+ .getItemData(Constants.ROOT_UUID);
- // support for fn:name()
- InternalQName propName = relPath.getName();
- if (propName.getNamespace().equals(NS_FN_URI) && propName.getName().equals("name()"))
- {
- if (node.getValueType() != QueryConstants.TYPE_STRING)
- {
- exceptions.add(new InvalidQueryException("Name function can "
- + "only be used in conjunction with a string literal"));
- return data;
- }
- if (node.getOperation() != QueryConstants.OPERATION_EQ_VALUE
- && node.getOperation() != QueryConstants.OPERATION_EQ_GENERAL)
- {
- exceptions.add(new InvalidQueryException("Name function can "
- + "only be used in conjunction with an equals operator"));
- return data;
- }
- // check if string literal is a valid XML Name
- if (XMLChar.isValidName(node.getStringValue()))
- {
- // parse string literal as JCR Name
- try
- {
- InternalQName n =
- session.getLocationFactory().parseJCRName(ISO9075.decode(node.getStringValue())).getInternalName();
- query = new NameQuery(n, indexFormatVersion, nsMappings);
- }
- catch (RepositoryException e)
- {
- exceptions.add(e);
- return data;
- }
- }
- else
- {
- // will never match -> create dummy query
- query = new BooleanQuery();
- }
- }
- else
- {
- switch (node.getOperation())
- {
- case QueryConstants.OPERATION_EQ_VALUE : // =
- case QueryConstants.OPERATION_EQ_GENERAL :
- BooleanQuery or = new BooleanQuery();
- for (int i = 0; i < stringValues.length; i++)
- {
- Term t = new Term(FieldNames.PROPERTIES, FieldNames.createNamedValue(field, stringValues[i]));
- Query q;
- if (transform[0] == TransformConstants.TRANSFORM_UPPER_CASE)
- {
- q = new CaseTermQuery.Upper(t);
- }
- else if (transform[0] == TransformConstants.TRANSFORM_LOWER_CASE)
- {
- q = new CaseTermQuery.Lower(t);
- }
- else
- {
- q = new JackrabbitTermQuery(t);
- }
- or.add(q, Occur.SHOULD);
- }
- query = or;
- if (node.getOperation() == QueryConstants.OPERATION_EQ_VALUE)
- {
- query = createSingleValueConstraint(or, field);
- }
- break;
- case QueryConstants.OPERATION_GE_VALUE : // >=
- case QueryConstants.OPERATION_GE_GENERAL :
- or = new BooleanQuery();
- for (int i = 0; i < stringValues.length; i++)
- {
- Term lower = new Term(FieldNames.PROPERTIES, FieldNames.createNamedValue(field, stringValues[i]));
- Term upper = new Term(FieldNames.PROPERTIES, FieldNames.createNamedValue(field, "\uFFFF"));
- or.add(new RangeQuery(lower, upper, true, transform[0]), Occur.SHOULD);
- }
- query = or;
- if (node.getOperation() == QueryConstants.OPERATION_GE_VALUE)
- {
- query = createSingleValueConstraint(or, field);
- }
- break;
- case QueryConstants.OPERATION_GT_VALUE : // >
- case QueryConstants.OPERATION_GT_GENERAL :
- or = new BooleanQuery();
- for (int i = 0; i < stringValues.length; i++)
- {
- Term lower = new Term(FieldNames.PROPERTIES, FieldNames.createNamedValue(field, stringValues[i]));
- Term upper = new Term(FieldNames.PROPERTIES, FieldNames.createNamedValue(field, "\uFFFF"));
- or.add(new RangeQuery(lower, upper, false, transform[0]), Occur.SHOULD);
- }
- query = or;
- if (node.getOperation() == QueryConstants.OPERATION_GT_VALUE)
- {
- query = createSingleValueConstraint(or, field);
- }
- break;
- case QueryConstants.OPERATION_LE_VALUE : // <=
- case QueryConstants.OPERATION_LE_GENERAL : // <=
- or = new BooleanQuery();
- for (int i = 0; i < stringValues.length; i++)
- {
- Term lower = new Term(FieldNames.PROPERTIES, FieldNames.createNamedValue(field, ""));
- Term upper = new Term(FieldNames.PROPERTIES, FieldNames.createNamedValue(field, stringValues[i]));
- or.add(new RangeQuery(lower, upper, true, transform[0]), Occur.SHOULD);
- }
- query = or;
- if (node.getOperation() == QueryConstants.OPERATION_LE_VALUE)
- {
- query = createSingleValueConstraint(query, field);
- }
- break;
- case QueryConstants.OPERATION_LIKE : // LIKE
- // the like operation always has one string value.
- // no coercing, see above
- if (stringValues[0].equals("%"))
- {
- query = Util.createMatchAllQuery(field, indexFormatVersion);
- }
- else
- {
- query = new WildcardQuery(FieldNames.PROPERTIES, field, stringValues[0], transform[0]);
- }
- break;
- case QueryConstants.OPERATION_LT_VALUE : // <
- case QueryConstants.OPERATION_LT_GENERAL :
- or = new BooleanQuery();
- for (int i = 0; i < stringValues.length; i++)
- {
- Term lower = new Term(FieldNames.PROPERTIES, FieldNames.createNamedValue(field, ""));
- Term upper = new Term(FieldNames.PROPERTIES, FieldNames.createNamedValue(field, stringValues[i]));
- or.add(new RangeQuery(lower, upper, false, transform[0]), Occur.SHOULD);
- }
- query = or;
- if (node.getOperation() == QueryConstants.OPERATION_LT_VALUE)
- {
- query = createSingleValueConstraint(or, field);
- }
- break;
- case QueryConstants.OPERATION_NE_VALUE : // !=
- // match nodes with property 'field' that includes svp and mvp
- BooleanQuery notQuery = new BooleanQuery();
- notQuery.add(Util.createMatchAllQuery(field, indexFormatVersion), Occur.SHOULD);
- // exclude all nodes where 'field' has the term in question
- for (int i = 0; i < stringValues.length; i++)
- {
- Term t = new Term(FieldNames.PROPERTIES, FieldNames.createNamedValue(field, stringValues[i]));
- Query q;
- if (transform[0] == TransformConstants.TRANSFORM_UPPER_CASE)
- {
- q = new CaseTermQuery.Upper(t);
- }
- else if (transform[0] == TransformConstants.TRANSFORM_LOWER_CASE)
- {
- q = new CaseTermQuery.Lower(t);
- }
- else
- {
- q = new JackrabbitTermQuery(t);
- }
- notQuery.add(q, Occur.MUST_NOT);
- }
- // and exclude all nodes where 'field' is multi valued
- notQuery.add(new JackrabbitTermQuery(new Term(FieldNames.MVP, field)), Occur.MUST_NOT);
- query = notQuery;
- break;
- case QueryConstants.OPERATION_NE_GENERAL : // !=
- // that's:
- // all nodes with property 'field'
- // minus the nodes that have a single property 'field' that is
- // not equal to term in question
- // minus the nodes that have a multi-valued property 'field' and
- // all values are equal to term in question
- notQuery = new BooleanQuery();
- notQuery.add(Util.createMatchAllQuery(field, indexFormatVersion), Occur.SHOULD);
- for (int i = 0; i < stringValues.length; i++)
- {
- // exclude the nodes that have the term and are single valued
- Term t = new Term(FieldNames.PROPERTIES, FieldNames.createNamedValue(field, stringValues[i]));
- Query svp = new NotQuery(new JackrabbitTermQuery(new Term(FieldNames.MVP, field)));
- BooleanQuery and = new BooleanQuery();
- Query q;
- if (transform[0] == TransformConstants.TRANSFORM_UPPER_CASE)
- {
- q = new CaseTermQuery.Upper(t);
- }
- else if (transform[0] == TransformConstants.TRANSFORM_LOWER_CASE)
- {
- q = new CaseTermQuery.Lower(t);
- }
- else
- {
- q = new JackrabbitTermQuery(t);
- }
- and.add(q, Occur.MUST);
- and.add(svp, Occur.MUST);
- notQuery.add(and, Occur.MUST_NOT);
- }
- // todo above also excludes multi-valued properties that contain
- // multiple instances of only stringValues. e.g. text={foo, foo}
- query = notQuery;
- break;
- case QueryConstants.OPERATION_NULL :
- query = new NotQuery(Util.createMatchAllQuery(field, indexFormatVersion));
- break;
- case QueryConstants.OPERATION_SIMILAR :
- String uuid = "x";
- try
- {
- // throw new UnsupportedOperationException();
- QPath path = resolver.parseJCRPath(node.getStringValue()).getInternalPath();
- NodeData parent = (NodeData)sharedItemMgr.getItemData(Constants.ROOT_UUID);
+ if (path.equals(Constants.ROOT_PATH)) {
+ uuid = Constants.ROOT_UUID;
+ } else {
+ QPathEntry[] relPathEntries = path.getRelPath(path
+ .getDepth());
+ ItemData item = parent;
+ for (int i = 0; i < relPathEntries.length; i++) {
+ item = sharedItemMgr.getItemData(parent,
+ relPathEntries[i]);
- if (path.equals(Constants.ROOT_PATH))
- {
- uuid = Constants.ROOT_UUID;
- }
- else
- {
- QPathEntry[] relPathEntries = path.getRelPath(path.getDepth());
- ItemData item = parent;
- for (int i = 0; i < relPathEntries.length; i++)
- {
- item = sharedItemMgr.getItemData(parent, relPathEntries[i]);
+ if (item == null)
+ break;
- if (item == null)
- break;
+ if (item.isNode())
+ parent = (NodeData) item;
+ else if (i < relPathEntries.length - 1)
+ throw new IllegalPathException(
+ "Path can not contains a property as the intermediate element");
+ }
+ uuid = item.getIdentifier();
+ }
- if (item.isNode())
- parent = (NodeData)item;
- else if (i < relPathEntries.length - 1)
- throw new IllegalPathException(
- "Path can not contains a property as the intermediate element");
- }
- uuid = item.getIdentifier();
- }
+ } catch (RepositoryException e) {
+ exceptions.add(e);
+ }
+ query = new SimilarityQuery(uuid, analyzer);
+ break;
+ case QueryConstants.OPERATION_NOT_NULL:
+ query = Util.createMatchAllQuery(field, indexFormatVersion);
+ break;
+ case QueryConstants.OPERATION_SPELLCHECK:
+ query = Util.createMatchAllQuery(field, indexFormatVersion);
+ break;
+ default:
+ throw new IllegalArgumentException(
+ "Unknown relation operation: " + node.getOperation());
+ }
+ }
- }
- catch (RepositoryException e)
- {
- exceptions.add(e);
- }
- query = new SimilarityQuery(uuid, analyzer);
- break;
- case QueryConstants.OPERATION_NOT_NULL :
- query = Util.createMatchAllQuery(field, indexFormatVersion);
- break;
- case QueryConstants.OPERATION_SPELLCHECK :
- query = Util.createMatchAllQuery(field, indexFormatVersion);
- break;
- default :
- throw new IllegalArgumentException("Unknown relation operation: " + node.getOperation());
- }
- }
+ if (relPath.getEntries().length > 1) {
+ // child axis in relation
+ QPathEntry[] elements = relPath.getEntries();
+ // elements.length - 1 = property name
+ // elements.length - 2 = last child axis name test
+ for (int i = elements.length - 2; i >= 0; i--) {
+ QPathEntry name = null;
+ if (!elements[i].equals(RelationQueryNode.STAR_NAME_TEST)) {
+ name = elements[i];
+ }
+ if (i == elements.length - 2) {
+ // join name test with property query if there is one
+ if (name != null) {
+ Query nameTest = new NameQuery(name,
+ indexFormatVersion, nsMappings);
+ BooleanQuery and = new BooleanQuery();
+ and.add(query, Occur.MUST);
+ and.add(nameTest, Occur.MUST);
+ query = and;
+ } else {
+ // otherwise the query can be used as is
+ }
+ } else {
+ query = new ParentAxisQuery(query, name,
+ indexFormatVersion, nsMappings);
+ }
+ }
+ // finally select the parent of the selected nodes
+ query = new ParentAxisQuery(query, null, indexFormatVersion,
+ nsMappings);
+ }
- if (relPath.getEntries().length > 1)
- {
- // child axis in relation
- QPathEntry[] elements = relPath.getEntries();
- // elements.length - 1 = property name
- // elements.length - 2 = last child axis name test
- for (int i = elements.length - 2; i >= 0; i--)
- {
- QPathEntry name = null;
- if (!elements[i].equals(RelationQueryNode.STAR_NAME_TEST))
- {
- name = elements[i];
- }
- if (i == elements.length - 2)
- {
- // join name test with property query if there is one
- if (name != null)
- {
- Query nameTest = new NameQuery(name, indexFormatVersion, nsMappings);
- BooleanQuery and = new BooleanQuery();
- and.add(query, Occur.MUST);
- and.add(nameTest, Occur.MUST);
- query = and;
- }
- else
- {
- // otherwise the query can be used as is
- }
- }
- else
- {
- query = new ParentAxisQuery(query, name, indexFormatVersion, nsMappings);
- }
- }
- // finally select the parent of the selected nodes
- query = new ParentAxisQuery(query, null, indexFormatVersion, nsMappings);
- }
+ return query;
+ }
- return query;
- }
+ public Object visit(OrderQueryNode node, Object data) {
+ return data;
+ }
- public Object visit(OrderQueryNode node, Object data)
- {
- return data;
- }
+ public Object visit(PropertyFunctionQueryNode node, Object data) {
+ return data;
+ }
- public Object visit(PropertyFunctionQueryNode node, Object data)
- {
- return data;
- }
+ // ---------------------------< internal
+ // >-----------------------------------
- //---------------------------< internal >-----------------------------------
+ /**
+ * Wraps a constraint query around <code>q</code> that limits the nodes to
+ * those where <code>propName</code> is the name of a single value property
+ * on the node instance.
+ *
+ * @param q
+ * the query to wrap.
+ * @param propName
+ * the name of a property that only has one value.
+ * @return the wrapped query <code>q</code>.
+ */
+ private Query createSingleValueConstraint(Query q, String propName) {
+ // get nodes with multi-values in propName
+ Query mvp = new JackrabbitTermQuery(new Term(FieldNames.MVP, propName));
+ // now negate, that gives the nodes that have propName as single
+ // values but also all others
+ Query svp = new NotQuery(mvp);
+ // now join the two, which will result in those nodes where propName
+ // only contains a single value. This works because q already restricts
+ // the result to those nodes that have a property propName
+ BooleanQuery and = new BooleanQuery();
+ and.add(q, Occur.MUST);
+ and.add(svp, Occur.MUST);
+ return and;
+ }
- /**
- * Wraps a constraint query around <code>q</code> that limits the nodes to
- * those where <code>propName</code> is the name of a single value property
- * on the node instance.
- *
- * @param q the query to wrap.
- * @param propName the name of a property that only has one value.
- * @return the wrapped query <code>q</code>.
- */
- private Query createSingleValueConstraint(Query q, String propName)
- {
- // get nodes with multi-values in propName
- Query mvp = new JackrabbitTermQuery(new Term(FieldNames.MVP, propName));
- // now negate, that gives the nodes that have propName as single
- // values but also all others
- Query svp = new NotQuery(mvp);
- // now join the two, which will result in those nodes where propName
- // only contains a single value. This works because q already restricts
- // the result to those nodes that have a property propName
- BooleanQuery and = new BooleanQuery();
- and.add(q, Occur.MUST);
- and.add(svp, Occur.MUST);
- return and;
- }
+ /**
+ * Returns an array of String values to be used as a term to lookup the
+ * search index for a String <code>literal</code> of a certain property
+ * name. This method will lookup the <code>propertyName</code> in the node
+ * type registry trying to find out the {@link javax.jcr.PropertyType}s. If
+ * no property type is found looking up node type information, this method
+ * will guess the property type.
+ *
+ * @param propertyName
+ * the name of the property in the relation.
+ * @param literal
+ * the String literal in the relation.
+ * @return the String values to use as term for the query.
+ */
+ private String[] getStringValues(InternalQName propertyName, String literal) {
+ PropertyTypeRegistry.TypeMapping[] types = propRegistry
+ .getPropertyTypes(propertyName);
+ List<String> values = new ArrayList<String>();
+ for (int i = 0; i < types.length; i++) {
+ switch (types[i].type) {
+ case PropertyType.NAME:
+ // try to translate name
+ try {
+ InternalQName n = session.getLocationFactory()
+ .parseJCRName(literal).getInternalName();
+ values.add(nsMappings.translateName(n));
+ log.debug("Coerced " + literal + " into NAME.");
+ } catch (RepositoryException e) {
+ log.warn("Unable to coerce '" + literal + "' into a NAME: "
+ + e.toString());
+ } catch (IllegalNameException e) {
+ log.warn("Unable to coerce '" + literal + "' into a NAME: "
+ + e.toString());
+ }
+ break;
+ case PropertyType.PATH:
+ // try to translate path
+ try {
+ QPath p = session.getLocationFactory()
+ .parseJCRPath(literal).getInternalPath();
+ values.add(resolver.createJCRPath(p).getAsString(true));
+ log.debug("Coerced " + literal + " into PATH.");
+ } catch (RepositoryException e) {
+ log.warn("Unable to coerce '" + literal + "' into a PATH: "
+ + e.toString());
+ }
+ break;
+ case PropertyType.DATE:
+ // try to parse date
+ Calendar c = ISO8601.parse(literal);
+ if (c != null) {
+ values.add(DateField.timeToString(c.getTimeInMillis()));
+ log.debug("Coerced " + literal + " into DATE.");
+ } else {
+ log.warn("Unable to coerce '" + literal + "' into a DATE.");
+ }
+ break;
+ case PropertyType.DOUBLE:
+ // try to parse double
+ try {
+ double d = Double.parseDouble(literal);
+ values.add(DoubleField.doubleToString(d));
+ log.debug("Coerced " + literal + " into DOUBLE.");
+ } catch (NumberFormatException e) {
+ log.warn("Unable to coerce '" + literal
+ + "' into a DOUBLE: " + e.toString());
+ }
+ break;
+ case PropertyType.LONG:
+ // try to parse long
+ try {
+ long l = Long.parseLong(literal);
+ values.add(LongField.longToString(l));
+ log.debug("Coerced " + literal + " into LONG.");
+ } catch (NumberFormatException e) {
+ log.warn("Unable to coerce '" + literal + "' into a LONG: "
+ + e.toString());
+ }
+ break;
+ case PropertyType.STRING:
+ values.add(literal);
+ log.debug("Using literal " + literal + " as is.");
+ break;
+ }
+ }
+ if (values.size() == 0) {
+ // use literal as is then try to guess other types
+ values.add(literal);
- /**
- * Returns an array of String values to be used as a term to lookup the search index
- * for a String <code>literal</code> of a certain property name. This method
- * will lookup the <code>propertyName</code> in the node type registry
- * trying to find out the {@link javax.jcr.PropertyType}s.
- * If no property type is found looking up node type information, this
- * method will guess the property type.
- *
- * @param propertyName the name of the property in the relation.
- * @param literal the String literal in the relation.
- * @return the String values to use as term for the query.
- */
- private String[] getStringValues(InternalQName propertyName, String literal)
- {
- PropertyTypeRegistry.TypeMapping[] types = propRegistry.getPropertyTypes(propertyName);
- List<String> values = new ArrayList<String>();
- for (int i = 0; i < types.length; i++)
- {
- switch (types[i].type)
- {
- case PropertyType.NAME :
- // try to translate name
- try
- {
- InternalQName n = session.getLocationFactory().parseJCRName(literal).getInternalName();
- values.add(nsMappings.translateName(n));
- log.debug("Coerced " + literal + " into NAME.");
- }
- catch (RepositoryException e)
- {
- log.warn("Unable to coerce '" + literal + "' into a NAME: " + e.toString());
- }
- catch (IllegalNameException e)
- {
- log.warn("Unable to coerce '" + literal + "' into a NAME: " + e.toString());
- }
- break;
- case PropertyType.PATH :
- // try to translate path
- try
- {
- QPath p = session.getLocationFactory().parseJCRPath(literal).getInternalPath();
- values.add(resolver.createJCRPath(p).getAsString(true));
- log.debug("Coerced " + literal + " into PATH.");
- }
- catch (RepositoryException e)
- {
- log.warn("Unable to coerce '" + literal + "' into a PATH: " + e.toString());
- }
- break;
- case PropertyType.DATE :
- // try to parse date
- Calendar c = ISO8601.parse(literal);
- if (c != null)
- {
- values.add(DateField.timeToString(c.getTimeInMillis()));
- log.debug("Coerced " + literal + " into DATE.");
- }
- else
- {
- log.warn("Unable to coerce '" + literal + "' into a DATE.");
- }
- break;
- case PropertyType.DOUBLE :
- // try to parse double
- try
- {
- double d = Double.parseDouble(literal);
- values.add(DoubleField.doubleToString(d));
- log.debug("Coerced " + literal + " into DOUBLE.");
- }
- catch (NumberFormatException e)
- {
- log.warn("Unable to coerce '" + literal + "' into a DOUBLE: " + e.toString());
- }
- break;
- case PropertyType.LONG :
- // try to parse long
- try
- {
- long l = Long.parseLong(literal);
- values.add(LongField.longToString(l));
- log.debug("Coerced " + literal + " into LONG.");
- }
- catch (NumberFormatException e)
- {
- log.warn("Unable to coerce '" + literal + "' into a LONG: " + e.toString());
- }
- break;
- case PropertyType.STRING :
- values.add(literal);
- log.debug("Using literal " + literal + " as is.");
- break;
- }
- }
- if (values.size() == 0)
- {
- // use literal as is then try to guess other types
- values.add(literal);
-
- // try to guess property type
- if (literal.indexOf('/') > -1)
- {
- // might be a path
- try
- {
- QPath p = session.getLocationFactory().parseJCRPath(literal).getInternalPath();
- values.add(resolver.createJCRPath(p).getAsString(true));
- log.debug("Coerced " + literal + " into PATH.");
- }
- catch (Exception e)
- {
- // not a path
- }
- }
- if (XMLChar.isValidName(literal))
- {
- // might be a name
- try
- {
- InternalQName n = session.getLocationFactory().parseJCRName(literal).getInternalName();
- values.add(nsMappings.translateName(n));
- log.debug("Coerced " + literal + " into NAME.");
- }
- catch (Exception e)
- {
- // not a name
- }
- }
- if (literal.indexOf(':') > -1)
- {
- // is it a date?
- Calendar c = ISO8601.parse(literal);
- if (c != null)
- {
- values.add(DateField.timeToString(c.getTimeInMillis()));
- log.debug("Coerced " + literal + " into DATE.");
- }
- }
- else
- {
- // long or double are possible at this point
- try
- {
- values.add(LongField.longToString(Long.parseLong(literal)));
- log.debug("Coerced " + literal + " into LONG.");
- }
- catch (NumberFormatException e)
- {
- // not a long
- // try double
- try
- {
- values.add(DoubleField.doubleToString(Double.parseDouble(literal)));
- log.debug("Coerced " + literal + " into DOUBLE.");
- }
- catch (NumberFormatException e1)
- {
- // not a double
- }
- }
- }
- }
- // if still no values use literal as is
- if (values.size() == 0)
- {
- values.add(literal);
- log.debug("Using literal " + literal + " as is.");
- }
- return (String[])values.toArray(new String[values.size()]);
- }
+ // try to guess property type
+ if (literal.indexOf('/') > -1) {
+ // might be a path
+ try {
+ QPath p = session.getLocationFactory()
+ .parseJCRPath(literal).getInternalPath();
+ values.add(resolver.createJCRPath(p).getAsString(true));
+ log.debug("Coerced " + literal + " into PATH.");
+ } catch (Exception e) {
+ // not a path
+ }
+ }
+ if (XMLChar.isValidName(literal)) {
+ // might be a name
+ try {
+ InternalQName n = session.getLocationFactory()
+ .parseJCRName(literal).getInternalName();
+ values.add(nsMappings.translateName(n));
+ log.debug("Coerced " + literal + " into NAME.");
+ } catch (Exception e) {
+ // not a name
+ }
+ }
+ if (literal.indexOf(':') > -1) {
+ // is it a date?
+ Calendar c = ISO8601.parse(literal);
+ if (c != null) {
+ values.add(DateField.timeToString(c.getTimeInMillis()));
+ log.debug("Coerced " + literal + " into DATE.");
+ }
+ } else {
+ // long or double are possible at this point
+ try {
+ values.add(LongField.longToString(Long.parseLong(literal)));
+ log.debug("Coerced " + literal + " into LONG.");
+ } catch (NumberFormatException e) {
+ // not a long
+ // try double
+ try {
+ values.add(DoubleField.doubleToString(Double
+ .parseDouble(literal)));
+ log.debug("Coerced " + literal + " into DOUBLE.");
+ } catch (NumberFormatException e1) {
+ // not a double
+ }
+ }
+ }
+ }
+ // if still no values use literal as is
+ if (values.size() == 0) {
+ values.add(literal);
+ log.debug("Using literal " + literal + " as is.");
+ }
+ return (String[]) values.toArray(new String[values.size()]);
+ }
}
Added: jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/LuceneVirtualTableResolver.java
===================================================================
--- jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/LuceneVirtualTableResolver.java (rev 0)
+++ jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/LuceneVirtualTableResolver.java 2009-10-02 15:41:14 UTC (rev 198)
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.exoplatform.services.jcr.impl.core.query.lucene;
+
+import org.apache.lucene.index.Term;
+import org.apache.lucene.search.BooleanQuery;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.BooleanClause.Occur;
+import org.exoplatform.services.jcr.core.NamespaceAccessor;
+import org.exoplatform.services.jcr.core.nodetype.NodeTypeDataManager;
+import org.exoplatform.services.jcr.datamodel.InternalQName;
+import org.exoplatform.services.jcr.impl.Constants;
+import org.exoplatform.services.jcr.impl.core.LocationFactory;
+import org.exoplatform.services.log.ExoLogger;
+import org.exoplatform.services.log.Log;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.nodetype.NoSuchNodeTypeException;
+import javax.jcr.query.InvalidQueryException;
+
+/**
+ * @author <a href="mailto:Sergey.Kabashnyuk at gmail.com">Sergey Kabashnyuk</a>
+ * @version $Id: exo-jboss-codetemplates.xml 34027 2009-07-15 23:26:43Z
+ * aheritier $
+ */
+public class LuceneVirtualTableResolver extends
+ NodeTypeVirtualTableResolver<Query> {
+
+ private final LocationFactory locationFactory;
+
+ /**
+ * Class logger.
+ */
+ private final Log log = ExoLogger
+ .getLogger(LuceneVirtualTableResolver.class);
+
+ private final String mixinTypesField;
+
+ private final String primaryTypeField;
+
+ /**
+ * @param nodeTypeDataManager
+ * @throws RepositoryException
+ */
+ public LuceneVirtualTableResolver(
+ final NodeTypeDataManager nodeTypeDataManager,
+ final NamespaceAccessor namespaceAccessor)
+ throws RepositoryException {
+ super(nodeTypeDataManager);
+
+ locationFactory = new LocationFactory(namespaceAccessor);
+ mixinTypesField = locationFactory.createJCRName(
+ Constants.JCR_MIXINTYPES).getAsString();
+ primaryTypeField = locationFactory.createJCRName(
+ Constants.JCR_PRIMARYTYPE).getAsString();
+
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Query resolve(final InternalQName tableName,
+ final boolean includeInheritedTables) throws InvalidQueryException,
+ RepositoryException {
+
+ final List<Term> terms = new ArrayList<Term>();
+
+ Query query = null;
+ try {
+ final String nodeTypeStringName = locationFactory.createJCRName(
+ tableName).getAsString();
+
+ if (isMixin(tableName)) {
+ // search for nodes where jcr:mixinTypes is set to this mixin
+ Term t = new Term(FieldNames.PROPERTIES, FieldNames
+ .createNamedValue(mixinTypesField, nodeTypeStringName));
+ terms.add(t);
+
+ } else {
+ // search for nodes where jcr:primaryType is set to this type
+
+ Term t = new Term(FieldNames.PROPERTIES, FieldNames
+ .createNamedValue(primaryTypeField, nodeTypeStringName));
+ terms.add(t);
+ }
+ if (includeInheritedTables) {
+ // now search for all node types that are derived from base
+ final Set<InternalQName> allTypes = getSubTypes(tableName);
+ for (final InternalQName descendantNt : allTypes) {
+ final String ntName = locationFactory.createJCRName(
+ descendantNt).getAsString();
+
+ Term t;
+ if (isMixin(descendantNt)) {
+ // search on jcr:mixinTypes
+ t = new Term(FieldNames.PROPERTIES, FieldNames
+ .createNamedValue(mixinTypesField, ntName));
+ } else {
+ // search on jcr:primaryType
+ t = new Term(FieldNames.PROPERTIES, FieldNames
+ .createNamedValue(primaryTypeField, ntName));
+ }
+ terms.add(t);
+ }
+ }
+ } catch (final NoSuchNodeTypeException e) {
+ throw new InvalidQueryException(e.getMessage(), e);
+ }
+
+ if (terms.size() == 0) {
+ // exception occured
+ query = new BooleanQuery();
+
+ } else if (terms.size() == 1) {
+ query = new JackrabbitTermQuery(terms.get(0));
+
+ } else {
+ final BooleanQuery b = new BooleanQuery();
+ for (final Object element : terms) {
+ // b.add(new TermQuery((Term) element), Occur.SHOULD);
+ b.add(new JackrabbitTermQuery((Term) element), Occur.SHOULD);
+ }
+ query = b;
+ }
+
+ return query;
+ }
+}
Property changes on: jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/LuceneVirtualTableResolver.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/NodeTypeVirtualTableResolver.java
===================================================================
--- jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/NodeTypeVirtualTableResolver.java (rev 0)
+++ jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/NodeTypeVirtualTableResolver.java 2009-10-02 15:41:14 UTC (rev 198)
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.exoplatform.services.jcr.impl.core.query.lucene;
+
+import org.exoplatform.services.jcr.core.nodetype.NodeTypeData;
+import org.exoplatform.services.jcr.core.nodetype.NodeTypeDataManager;
+import org.exoplatform.services.jcr.datamodel.InternalQName;
+
+import java.util.Set;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.nodetype.NoSuchNodeTypeException;
+
+/**
+ * @author <a href="mailto:Sergey.Kabashnyuk at gmail.com">Sergey Kabashnyuk</a>
+ * @version $Id: exo-jboss-codetemplates.xml 34027 2009-07-15 23:26:43Z
+ * aheritier $
+ */
+public abstract class NodeTypeVirtualTableResolver<Q> implements
+ VirtualTableResolver<Q> {
+ private final NodeTypeDataManager nodeTypeDataManager;
+
+ /**
+ * @param nodeTypeDataManager
+ */
+ public NodeTypeVirtualTableResolver(
+ final NodeTypeDataManager nodeTypeDataManager) {
+ super();
+ this.nodeTypeDataManager = nodeTypeDataManager;
+ }
+
+ /**
+ * @param nodeTypeName
+ * name.
+ * @return Returns all subtypes of node type <code>nodeTypeName</code> in
+ * the node type inheritance hierarchy.
+ * @throws RepositoryException
+ */
+ protected Set<InternalQName> getSubTypes(final InternalQName nodeTypeName)
+ throws RepositoryException {
+ return this.nodeTypeDataManager.getSubtypes(nodeTypeName);
+ }
+
+ /**
+ * @param nodeTypeName
+ * name.
+ * @return true if node type with name <code>nodeTypeName</code> is mixin.
+ * @throws RepositoryException
+ */
+ protected boolean isMixin(final InternalQName nodeTypeName)
+ throws RepositoryException {
+ final NodeTypeData nodeType = this.nodeTypeDataManager
+ .findNodeType(nodeTypeName);
+ if (nodeType == null) {
+ throw new NoSuchNodeTypeException("Node type "
+ + nodeTypeName.getAsString() + " not found");
+ }
+ return nodeType.isMixin();
+ }
+}
Property changes on: jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/NodeTypeVirtualTableResolver.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified: jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/QueryImpl.java
===================================================================
--- jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/QueryImpl.java 2009-10-02 15:39:44 UTC (rev 197)
+++ jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/QueryImpl.java 2009-10-02 15:41:14 UTC (rev 198)
@@ -16,15 +16,6 @@
*/
package org.exoplatform.services.jcr.impl.core.query.lucene;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import javax.jcr.RepositoryException;
-import javax.jcr.nodetype.PropertyDefinition;
-import javax.jcr.query.InvalidQueryException;
-import javax.jcr.query.QueryResult;
-
import org.apache.lucene.search.Query;
import org.exoplatform.services.jcr.core.nodetype.NodeTypeData;
import org.exoplatform.services.jcr.core.nodetype.PropertyDefinitionData;
@@ -33,8 +24,6 @@
import org.exoplatform.services.jcr.impl.Constants;
import org.exoplatform.services.jcr.impl.core.SessionDataManager;
import org.exoplatform.services.jcr.impl.core.SessionImpl;
-import org.exoplatform.services.jcr.impl.core.nodetype.NodeTypeImpl;
-import org.exoplatform.services.jcr.impl.core.nodetype.PropertyDefinitionImpl;
import org.exoplatform.services.jcr.impl.core.query.AndQueryNode;
import org.exoplatform.services.jcr.impl.core.query.DefaultQueryNodeVisitor;
import org.exoplatform.services.jcr.impl.core.query.LocationStepQueryNode;
@@ -44,10 +33,17 @@
import org.exoplatform.services.jcr.impl.core.query.QueryNodeFactory;
import org.exoplatform.services.jcr.impl.core.query.QueryParser;
import org.exoplatform.services.jcr.impl.core.query.QueryRootNode;
-
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.query.InvalidQueryException;
+import javax.jcr.query.QueryResult;
+
/**
* Implements the {@link org.apache.jackrabbit.core.query.ExecutableQuery}
* interface.
@@ -62,7 +58,8 @@
/**
* The default selector name 's'.
*/
- public static final InternalQName DEFAULT_SELECTOR_NAME = new InternalQName(Constants.NS_DEFAULT_URI,"s");
+ public static final InternalQName DEFAULT_SELECTOR_NAME = new InternalQName(
+ Constants.NS_DEFAULT_URI, "s");
/**
* The root node of the query tree
@@ -71,135 +68,149 @@
/**
* Creates a new query instance from a query string.
- *
- * @param session the session of the user executing this query.
- * @param itemMgr the item manager of the session executing this query.
- * @param index the search index.
- * @param propReg the property type registry.
- * @param statement the query statement.
- * @param language the syntax of the query statement.
- * @param factory the query node factory.
- * @throws InvalidQueryException if the query statement is invalid according
- * to the specified <code>language</code>.
+ *
+ * @param session
+ * the session of the user executing this query.
+ * @param itemMgr
+ * the item manager of the session executing this query.
+ * @param index
+ * the search index.
+ * @param propReg
+ * the property type registry.
+ * @param statement
+ * the query statement.
+ * @param language
+ * the syntax of the query statement.
+ * @param factory
+ * the query node factory.
+ * @throws InvalidQueryException
+ * if the query statement is invalid according to the specified
+ * <code>language</code>.
*/
- public QueryImpl(SessionImpl session,
- SessionDataManager itemMgr,
- SearchIndex index,
- PropertyTypeRegistry propReg,
- String statement,
- String language,
- QueryNodeFactory factory) throws InvalidQueryException {
- super(session, itemMgr, index, propReg);
- // parse query according to language
- // build query tree using the passed factory
- //this.root = QueryParser.parse(statement, language, session, factory);
- this.root = QueryParser.parse(statement, language, session.getLocationFactory(), factory);
+ public QueryImpl(SessionImpl session, SessionDataManager itemMgr,
+ SearchIndex index, PropertyTypeRegistry propReg, String statement,
+ String language, QueryNodeFactory factory)
+ throws InvalidQueryException {
+ super(session, itemMgr, index, propReg);
+ // parse query according to language
+ // build query tree using the passed factory
+ // this.root = QueryParser.parse(statement, language, session, factory);
+ this.root = QueryParser.parse(statement, language, session
+ .getLocationFactory(), factory);
}
/**
* Executes this query and returns a <code>{@link QueryResult}</code>.
- *
- * @param offset the offset in the total result set
- * @param limit the maximum result size
+ *
+ * @param offset
+ * the offset in the total result set
+ * @param limit
+ * the maximum result size
* @return a <code>QueryResult</code>
- * @throws RepositoryException if an error occurs
+ * @throws RepositoryException
+ * if an error occurs
*/
- public QueryResult execute(long offset, long limit) throws RepositoryException {
- if (log.isDebugEnabled()) {
- log.debug("Executing query: \n" + root.dump());
- }
+ public QueryResult execute(long offset, long limit)
+ throws RepositoryException {
+ if (log.isDebugEnabled()) {
+ log.debug("Executing query: \n" + root.dump());
+ }
- // build lucene query
- Query query = LuceneQueryBuilder.createQuery(root, session,
- index.getContext().getItemStateManager(),
- index.getNamespaceMappings(), index.getTextAnalyzer(),
- propReg, index.getSynonymProvider(),
- index.getIndexFormatVersion());
+ // build lucene query
+ Query query = LuceneQueryBuilder.createQuery(root, session, index
+ .getContext().getItemStateManager(), index
+ .getNamespaceMappings(), index.getTextAnalyzer(), propReg,
+ index.getSynonymProvider(), index.getIndexFormatVersion(),
+ index.getContext().getVirtualTableResolver());
- OrderQueryNode orderNode = root.getOrderNode();
+ OrderQueryNode orderNode = root.getOrderNode();
- OrderQueryNode.OrderSpec[] orderSpecs;
- if (orderNode != null) {
- orderSpecs = orderNode.getOrderSpecs();
- } else {
- orderSpecs = new OrderQueryNode.OrderSpec[0];
- }
- QPath[] orderProperties = new QPath[orderSpecs.length];
- boolean[] ascSpecs = new boolean[orderSpecs.length];
- for (int i = 0; i < orderSpecs.length; i++) {
- orderProperties[i] = orderSpecs[i].getPropertyPath();
- ascSpecs[i] = orderSpecs[i].isAscending();
- }
+ OrderQueryNode.OrderSpec[] orderSpecs;
+ if (orderNode != null) {
+ orderSpecs = orderNode.getOrderSpecs();
+ } else {
+ orderSpecs = new OrderQueryNode.OrderSpec[0];
+ }
+ QPath[] orderProperties = new QPath[orderSpecs.length];
+ boolean[] ascSpecs = new boolean[orderSpecs.length];
+ for (int i = 0; i < orderSpecs.length; i++) {
+ orderProperties[i] = orderSpecs[i].getPropertyPath();
+ ascSpecs[i] = orderSpecs[i].isAscending();
+ }
- return new SingleColumnQueryResult(index, itemMgr,
- session, session.getAccessManager(),
- this, query, new SpellSuggestion(index.getSpellChecker(), root),
- getSelectProperties(), orderProperties, ascSpecs,
- getRespectDocumentOrder(), offset, limit);
+ return new SingleColumnQueryResult(index, itemMgr, session, session
+ .getAccessManager(), this, query, new SpellSuggestion(index
+ .getSpellChecker(), root), getSelectProperties(),
+ orderProperties, ascSpecs, getRespectDocumentOrder(), offset,
+ limit);
}
/**
* Returns the select properties for this query.
- *
+ *
* @return array of select property names.
- * @throws RepositoryException if an error occurs.
+ * @throws RepositoryException
+ * if an error occurs.
*/
protected InternalQName[] getSelectProperties() throws RepositoryException {
- // get select properties
- List selectProps = new ArrayList();
- selectProps.addAll(Arrays.asList(root.getSelectProperties()));
- if (selectProps.size() == 0) {
- // use node type constraint
- LocationStepQueryNode[] steps = root.getLocationNode().getPathSteps();
- final InternalQName[] ntName = new InternalQName[1];
- steps[steps.length - 1].acceptOperands(new DefaultQueryNodeVisitor() {
+ // get select properties
+ List selectProps = new ArrayList();
+ selectProps.addAll(Arrays.asList(root.getSelectProperties()));
+ if (selectProps.size() == 0) {
+ // use node type constraint
+ LocationStepQueryNode[] steps = root.getLocationNode()
+ .getPathSteps();
+ final InternalQName[] ntName = new InternalQName[1];
+ steps[steps.length - 1].acceptOperands(
+ new DefaultQueryNodeVisitor() {
- public Object visit(AndQueryNode node, Object data) throws RepositoryException {
- return node.acceptOperands(this, data);
- }
+ public Object visit(AndQueryNode node, Object data)
+ throws RepositoryException {
+ return node.acceptOperands(this, data);
+ }
- public Object visit(NodeTypeQueryNode node, Object data) {
- ntName[0] = node.getValue();
- return data;
- }
- }, null);
- if (ntName[0] == null) {
- ntName[0] = Constants.NT_BASE;
- }
- NodeTypeData nt = session.getWorkspace().getNodeTypesHolder().findNodeType(ntName[0]);
- PropertyDefinitionData[] propDefs = nt.getDeclaredPropertyDefinitions();
-
- for (int i = 0; i < propDefs.length; i++) {
- PropertyDefinitionData propDef = propDefs[i];
- if (!propDef.isResidualSet() && !propDef.isMultiple())
- {
- selectProps.add(propDef.getName());
- }
- }
- }
+ public Object visit(NodeTypeQueryNode node, Object data) {
+ ntName[0] = node.getValue();
+ return data;
+ }
+ }, null);
+ if (ntName[0] == null) {
+ ntName[0] = Constants.NT_BASE;
+ }
+ NodeTypeData nt = session.getWorkspace().getNodeTypesHolder()
+ .findNodeType(ntName[0]);
+ PropertyDefinitionData[] propDefs = nt
+ .getDeclaredPropertyDefinitions();
- // add jcr:path and jcr:score if not selected already
- if (!selectProps.contains(Constants.JCR_PATH))
- {
- selectProps.add(Constants.JCR_PATH);
- }
- if (!selectProps.contains(Constants.JCR_SCORE))
- {
- selectProps.add(Constants.JCR_SCORE);
- }
+ for (int i = 0; i < propDefs.length; i++) {
+ PropertyDefinitionData propDef = propDefs[i];
+ if (!propDef.isResidualSet() && !propDef.isMultiple()) {
+ selectProps.add(propDef.getName());
+ }
+ }
+ }
- return (InternalQName[])selectProps.toArray(new InternalQName[selectProps.size()]);
+ // add jcr:path and jcr:score if not selected already
+ if (!selectProps.contains(Constants.JCR_PATH)) {
+ selectProps.add(Constants.JCR_PATH);
+ }
+ if (!selectProps.contains(Constants.JCR_SCORE)) {
+ selectProps.add(Constants.JCR_SCORE);
+ }
+
+ return (InternalQName[]) selectProps
+ .toArray(new InternalQName[selectProps.size()]);
}
/**
* Returns <code>true</code> if this query node needs items under
* /jcr:system to be queried.
- *
+ *
* @return <code>true</code> if this query node needs content under
* /jcr:system to be queried; <code>false</code> otherwise.
*/
public boolean needsSystemTree() {
- return this.root.needsSystemTree();
+ return this.root.needsSystemTree();
}
}
Modified: jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/SearchIndex.java
===================================================================
--- jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/SearchIndex.java 2009-10-02 15:39:44 UTC (rev 197)
+++ jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/SearchIndex.java 2009-10-02 15:41:14 UTC (rev 198)
@@ -87,24 +87,6 @@
*/
public class SearchIndex extends AbstractQueryHandler {
- // public static final List VALID_SYSTEM_INDEX_NODE_TYPE_NAMES
- // = Collections.unmodifiableList(Arrays.asList(new Name[]{
- // NameConstants.NT_CHILDNODEDEFINITION,
- // NameConstants.NT_FROZENNODE,
- // NameConstants.NT_NODETYPE,
- // NameConstants.NT_PROPERTYDEFINITION,
- // NameConstants.NT_VERSION,
- // NameConstants.NT_VERSIONEDCHILD,
- // NameConstants.NT_VERSIONHISTORY,
- // NameConstants.NT_VERSIONLABELS,
- // NameConstants.REP_NODETYPES,
- // NameConstants.REP_SYSTEM,
- // NameConstants.REP_VERSIONSTORAGE,
- // // Supertypes
- // NameConstants.NT_BASE,
- // NameConstants.MIX_REFERENCEABLE
- // }));
-
private static final DefaultQueryNodeFactory DEFAULT_QUERY_NODE_FACTORY = new DefaultQueryNodeFactory();
/** The logger instance for this class */
@@ -162,32 +144,10 @@
*/
public static final int DEFAULT_TERM_INFOS_INDEX_DIVISOR = 1;
- // /**
- // * The path factory.
- // */
- // protected static final PathFactory PATH_FACTORY =
- // PathFactoryImpl.getInstance();
- //
- // /**
- // * The path of the root node.
- // */
- // private static final Path ROOT_PATH;
- //
- // /**
- // * The path <code>/jcr:system</code>.
- // */
- // private static final Path JCR_SYSTEM_PATH;
- //
- // static {
- // ROOT_PATH = PATH_FACTORY.create(NameConstants.ROOT);
- // try {
- // JCR_SYSTEM_PATH = PATH_FACTORY.create(ROOT_PATH,
- // NameConstants.JCR_SYSTEM, false);
- // } catch (RepositoryException e) {
- // // should never happen, path is always valid
- // throw new InternalError(e.getMessage());
- // }
- // }
+ /**
+ * Default name of the error log file
+ */
+ private static final String ERROR_LOG = "error.log";
/**
* The actual index
@@ -199,19 +159,6 @@
*/
private JcrStandartAnalyzer analyzer;
- // /**
- // * List of text extractor and text filter class names. The configured
- // * classes will be instantiated and used to extract text content from
- // * binary properties.
- // */
- // private String textFilterClasses =
- // DefaultTextExtractor.class.getName();
- //
- // /**
- // * Text extractor for extracting text content of binary properties.
- // */
- // private TextExtractor extractor;
-
/**
* The namespace mappings used internally.
*/
@@ -380,8 +327,6 @@
*/
private SynonymProvider synProvider;
- // private File indexDirectory;
-
/**
* The configuration path for the synonym provider.
*/
@@ -451,15 +396,14 @@
*/
private boolean closed = false;
- // private QueryHandlerContext context;
-
/**
* Text extractor for extracting text content of binary properties.
*/
private DocumentReaderService extractor;
- // private final QueryHandlerEntryWrapper queryHandlerConfig;
+ public static final int DEFAULT_ERRORLOG_FILE_SIZE = 50; // Kb
+ private int errorLogfileSize = DEFAULT_ERRORLOG_FILE_SIZE;
/**
* The ErrorLog of this <code>MultiIndex</code>. All changes that must be in
* index but interrupted by IOException are here.
@@ -601,9 +545,30 @@
+ "storage for optimal performance.", new Integer(
getIndexFormatVersion().getVersion()));
}
+
+ File file = new File(indexDirectory, ERROR_LOG);
+ errorLog = new ErrorLog(file, errorLogfileSize);
+ // reprocess any notfinished notifies;
+ recoverErrorLog(errorLog);
+
}
/**
+ * @return the errorLogfileSize
+ */
+ public int getErrorLogfileSize() {
+ return errorLogfileSize;
+ }
+
+ /**
+ * @param errorLogfileSize
+ * the errorLogfileSize to set
+ */
+ public void setErrorLogfileSize(int errorLogfileSize) {
+ this.errorLogfileSize = errorLogfileSize;
+ }
+
+ /**
* Adds the <code>node</code> to the search index.
*
* @param node
@@ -1308,34 +1273,39 @@
* @return the indexing configuration or <code>null</code> if there is none.
*/
protected Element getIndexingConfigurationDOM() {
- if (indexingConfiguration != null) {
- return indexingConfiguration;
+ if (indexingConfiguration == null) {
+ if (indexingConfigPath != null) {
+
+ // File config = new File(indexingConfigPath);
+
+ InputStream is = SearchIndex.class
+ .getResourceAsStream(indexingConfigPath);
+ if (is == null) {
+ try {
+ is = cfm.getInputStream(indexingConfigPath);
+ } catch (Exception e1) {
+ log.warn("Unable to load configuration "
+ + indexingConfigPath);
+ }
+ }
+
+ try {
+ DocumentBuilderFactory factory = DocumentBuilderFactory
+ .newInstance();
+ DocumentBuilder builder = factory.newDocumentBuilder();
+ builder
+ .setEntityResolver(new IndexingConfigurationEntityResolver());
+ indexingConfiguration = builder.parse(is)
+ .getDocumentElement();
+ } catch (ParserConfigurationException e) {
+ log.warn("Unable to create XML parser", e);
+ } catch (IOException e) {
+ log.warn("Exception parsing " + indexingConfigPath, e);
+ } catch (SAXException e) {
+ log.warn("Exception parsing " + indexingConfigPath, e);
+ }
+ }
}
- if (indexingConfigPath == null) {
- return null;
- }
- File config = new File(indexingConfigPath);
- if (!config.exists()) {
- log.warn("File does not exist: " + indexingConfigPath);
- return null;
- } else if (!config.canRead()) {
- log.warn("Cannot read file: " + indexingConfigPath);
- return null;
- }
- try {
- DocumentBuilderFactory factory = DocumentBuilderFactory
- .newInstance();
- DocumentBuilder builder = factory.newDocumentBuilder();
- builder
- .setEntityResolver(new IndexingConfigurationEntityResolver());
- indexingConfiguration = builder.parse(config).getDocumentElement();
- } catch (ParserConfigurationException e) {
- log.warn("Unable to create XML parser", e);
- } catch (IOException e) {
- log.warn("Exception parsing " + indexingConfigPath, e);
- } catch (SAXException e) {
- log.warn("Exception parsing " + indexingConfigPath, e);
- }
return indexingConfiguration;
}
@@ -2384,6 +2354,72 @@
errorLog.writeChanges(removed, added);
}
+ private void recoverErrorLog(ErrorLog errlog) throws IOException,
+ RepositoryException {
+ final Set<String> rem = new HashSet<String>();
+ final Set<String> add = new HashSet<String>();
+
+ errlog.readChanges(rem, add);
+
+ // check is any notifies in log
+ if (rem.isEmpty() && add.isEmpty()) {
+ // there is no sense to continue
+ return;
+ }
+
+ Iterator<String> removedStates = rem.iterator();
+
+ // make a new iterator;
+ Iterator<NodeData> addedStates = new Iterator<NodeData>() {
+ private final Iterator<String> iter = add.iterator();
+
+ public boolean hasNext() {
+ return iter.hasNext();
+ }
+
+ public NodeData next() {
+ String id;
+ // we have to iterrate through items till will meet ones
+ // existing in
+ // workspace
+ while (iter.hasNext()) {
+ id = iter.next();
+
+ try {
+ ItemData item = getContext().getItemStateManager()
+ .getItemData(id);
+ if (item != null) {
+ if (item.isNode()) {
+ return (NodeData) item; // return node here
+ } else
+ log
+ .warn("Node expected but property found with id "
+ + id
+ + ". Skipping "
+ + item.getQPath().getAsString());
+ } else {
+ log.warn("Unable to recovery node index " + id
+ + ". Node not found.");
+ }
+ } catch (RepositoryException e) {
+ log.error("ErrorLog recovery error. Item id " + id
+ + ". " + e, e);
+ }
+ }
+
+ return null;
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ };
+
+ updateNodes(removedStates, addedStates);
+
+ errlog.clear();
+ }
+
/**
* @see org.exoplatform.services.jcr.impl.core.query.QueryHandler#executeQuery(org.apache.lucene.search.Query,
* boolean, org.exoplatform.services.jcr.datamodel.InternalQName[],
@@ -2398,4 +2434,5 @@
return new LuceneQueryHits(reader, searcher, query);
}
+
}
Added: jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/VirtualTableResolver.java
===================================================================
--- jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/VirtualTableResolver.java (rev 0)
+++ jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/VirtualTableResolver.java 2009-10-02 15:41:14 UTC (rev 198)
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2009 eXo Platform SAS.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.exoplatform.services.jcr.impl.core.query.lucene;
+
+import org.exoplatform.services.jcr.datamodel.InternalQName;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.query.InvalidQueryException;
+
+/**
+ * @author <a href="mailto:Sergey.Kabashnyuk at gmail.com">Sergey Kabashnyuk</a>
+ * @version $Id: exo-jboss-codetemplates.xml 34027 2009-07-15 23:26:43Z
+ * aheritier $
+ */
+public interface VirtualTableResolver<Q>
+{
+ /**
+ * Construct <Q>query for given table.
+ *
+ * @param tableName - name of the virtual table.
+ * @param includeInheritedTables - include inherited tables to the result.
+ * @return query.
+ */
+ Q resolve(InternalQName tableName, boolean includeInheritedTables) throws InvalidQueryException, RepositoryException;
+
+}
Property changes on: jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/VirtualTableResolver.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified: jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/indexing-configuration-1.0.dtd
===================================================================
--- jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/indexing-configuration-1.0.dtd 2009-10-02 15:39:44 UTC (rev 197)
+++ jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/indexing-configuration-1.0.dtd 2009-10-02 15:41:14 UTC (rev 198)
@@ -16,7 +16,7 @@
-->
<!--
The configuration element configures the indexing behaviour of the lucene
- backed query handler in Jackrabbit. It allows you to define indexing
+ backed query handler . It allows you to define indexing
aggregates and configure which properties of a node are indexed.
This element must contain all the namespace declarations that are used
throughout this configuration.
Added: jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/indexing-configuration-1.1.dtd
===================================================================
--- jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/indexing-configuration-1.1.dtd (rev 0)
+++ jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/indexing-configuration-1.1.dtd 2009-10-02 15:41:14 UTC (rev 198)
@@ -0,0 +1,84 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!--
+ The configuration element configures the indexing behaviour of the lucene
+ backed query handler . It allows you to define indexing
+ aggregates and configure which properties of a node are indexed.
+ This element must contain all the namespace declarations that are used
+ throughout this configuration.
+-->
+<!ELEMENT configuration (aggregate*,index-rule*)>
+
+<!--
+ Each aggregate element defines an indexing aggregate based on the name of a
+ primary node type.
+-->
+<!ELEMENT aggregate (include*)>
+<!ATTLIST aggregate primaryType CDATA #REQUIRED>
+
+<!--
+ An include element contains a relative path pattern using either an exact
+ node name or *. Nodes that match the path pattern against the root of an
+ indexing aggregate are included in the aggregated node index. An include
+ element may optionally specify a primary node type name that needs to match
+ for the included node.
+-->
+<!ELEMENT include (#PCDATA)>
+<!ATTLIST include primaryType CDATA #IMPLIED>
+
+<!--
+ An index-rule element defines which properties of a node should be indexed.
+ When a node is indexed the list of index-rules is check for a matching
+ node type and whether the condition is true. If a match is found the
+ property is looked up.
+ The index-rule element also contains a boost value for the entire node
+ being indexed. A value higher than 1.0 will boost the score value for a node
+ that matched this index-rule.
+-->
+<!ELEMENT index-rule (property*)>
+<!ATTLIST index-rule nodeType CDATA #REQUIRED
+ condition CDATA #IMPLIED
+ boost CDATA "1.0">
+
+<!--
+ A property element defines the boost value for a matching property and a
+ flag that indicates whether the value of a string property should also be
+ included in the node scope fulltext index. Both boost and nodeScopeIndex
+ attributes only affect string properties and are ignored if the property
+ is not of type string. If isRegexp is set to true the name of the property
+ is interpreted as a regular expression to match properties on a node. Please
+ note that you may only use a regular expression for the local part of a
+ property name. The attribute useInExcerpt controls whether the contents
+ of the property is used to construct an excerpt. The default value for this
+ attribute is true.
+-->
+<!ELEMENT property (#PCDATA)>
+<!ATTLIST property boost CDATA "1.0"
+ nodeScopeIndex CDATA "true"
+ isRegexp CDATA "false"
+ useInExcerpt CDATA "true">
+
+<!--
+ An analyzer element with property elements in it defines which analyzer is to
+ be used for indexing and parsing the full text of this property. If the analyzer
+ class can not be found, the default analyzer is used. The node scope is always
+ indexed with the default analyzer, so might return different results for search
+ queries in some rare cases.
+-->
+<!ELEMENT analyzers (analyzer*)>
+<!ELEMENT analyzer (property*)>
+<!ATTLIST analyzer class CDATA #REQUIRED>
Property changes on: jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/indexing-configuration-1.1.dtd
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/indexing-configuration-1.2.dtd
===================================================================
--- jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/indexing-configuration-1.2.dtd (rev 0)
+++ jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/indexing-configuration-1.2.dtd 2009-10-02 15:41:14 UTC (rev 198)
@@ -0,0 +1,93 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!--
+ The configuration element configures the indexing behaviour of the lucene
+ backed query handler. It allows you to define indexing
+ aggregates and configure which properties of a node are indexed.
+ This element must contain all the namespace declarations that are used
+ throughout this configuration.
+-->
+<!ELEMENT configuration (aggregate*,index-rule*)>
+
+<!--
+ Each aggregate element defines an indexing aggregate based on the name of a
+ primary node type.
+-->
+<!ELEMENT aggregate (include*,include-property)>
+<!ATTLIST aggregate primaryType CDATA #REQUIRED>
+
+<!--
+ An include element contains a relative path pattern using either an exact
+ node name or *. Nodes that match the path pattern against the root of an
+ indexing aggregate are included in the aggregated node index. An include
+ element may optionally specify a primary node type name that needs to match
+ for the included node.
+-->
+<!ELEMENT include (#PCDATA)>
+<!ATTLIST include primaryType CDATA #IMPLIED>
+
+<!--
+ An include-property element contains a relative path to a property. Properties
+ that match the path against the root of an indexing aggregate are included
+ in the aggregated node index. Aggregated properties may be used to speed
+ up sorting of query results when the order by clause references a property
+ with a relative path.
+-->
+<!ELEMENT include-property (#PCDATA)>
+
+<!--
+ An index-rule element defines which properties of a node should be indexed.
+ When a node is indexed the list of index-rules is check for a matching
+ node type and whether the condition is true. If a match is found the
+ property is looked up.
+ The index-rule element also contains a boost value for the entire node
+ being indexed. A value higher than 1.0 will boost the score value for a node
+ that matched this index-rule.
+-->
+<!ELEMENT index-rule (property*)>
+<!ATTLIST index-rule nodeType CDATA #REQUIRED
+ condition CDATA #IMPLIED
+ boost CDATA "1.0">
+
+<!--
+ A property element defines the boost value for a matching property and a
+ flag that indicates whether the value of a string property should also be
+ included in the node scope fulltext index. Both boost and nodeScopeIndex
+ attributes only affect string properties and are ignored if the property
+ is not of type string. If isRegexp is set to true the name of the property
+ is interpreted as a regular expression to match properties on a node. Please
+ note that you may only use a regular expression for the local part of a
+ property name. The attribute useInExcerpt controls whether the contents
+ of the property is used to construct an excerpt. The default value for this
+ attribute is true.
+-->
+<!ELEMENT property (#PCDATA)>
+<!ATTLIST property boost CDATA "1.0"
+ nodeScopeIndex CDATA "true"
+ isRegexp CDATA "false"
+ useInExcerpt CDATA "true">
+
+<!--
+ An analyzer element with property elements in it defines which analyzer is to
+ be used for indexing and parsing the full text of this property. If the analyzer
+ class can not be found, the default analyzer is used. The node scope is always
+ indexed with the default analyzer, so might return different results for search
+ queries in some rare cases.
+-->
+<!ELEMENT analyzers (analyzer*)>
+<!ELEMENT analyzer (property*)>
+<!ATTLIST analyzer class CDATA #REQUIRED>
Property changes on: jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/indexing-configuration-1.2.dtd
___________________________________________________________________
Name: svn:mime-type
+ text/plain
More information about the exo-jcr-commits
mailing list