Modified: jakarta/slide/trunk/src/stores/org/apache/slide/index/lucene/expressions/AbstractLuceneExpression.java URL: http://svn.apache.org/viewcvs/jakarta/slide/trunk/src/stores/org/apache/slide/index/lucene/expressions/AbstractLuceneExpression.java?rev=356261&r1=356260&r2=356261&view=diff ============================================================================== --- jakarta/slide/trunk/src/stores/org/apache/slide/index/lucene/expressions/AbstractLuceneExpression.java (original) +++ jakarta/slide/trunk/src/stores/org/apache/slide/index/lucene/expressions/AbstractLuceneExpression.java Mon Dec 12 06:36:39 2005 @@ -22,7 +22,12 @@ */ package org.apache.slide.index.lucene.expressions; +import org.apache.slide.index.lucene.LuceneOrderBy; +import org.apache.slide.index.lucene.LuceneBasicResultSetImpl; + import java.io.IOException; +import java.io.StringReader; +import java.util.Iterator; import java.util.List; import java.util.StringTokenizer; @@ -34,8 +39,14 @@ import org.apache.lucene.search.Query; import org.apache.lucene.search.RangeQuery; import org.apache.lucene.search.TermQuery; +import org.apache.lucene.search.Sort; +import org.apache.lucene.search.SortField; + +import org.apache.slide.search.CompareHint; import org.apache.slide.common.SlideException; +import org.apache.slide.common.SlideTokenWrapper; import org.apache.slide.content.NodeProperty; +import org.apache.slide.content.NodeRevisionDescriptor; import org.apache.slide.index.lucene.Index; import org.apache.slide.index.lucene.LuceneExpressionFactory; import org.apache.slide.search.BadQueryException; @@ -50,224 +61,331 @@ import org.apache.slide.search.basic.IBasicExpressionFactory; import org.apache.slide.search.basic.IBasicQuery; import org.apache.slide.search.basic.IBasicResultSet; +import org.apache.slide.search.basic.OrderBy; +import org.apache.slide.security.AccessDeniedException; +import org.apache.slide.store.BindingStore; import org.apache.slide.structure.ObjectNode; import org.apache.slide.structure.SubjectNode; +import org.apache.slide.util.Configuration; import org.apache.slide.util.logger.Logger; import org.apache.slide.content.NodeRevisionNumber; import org.jdom.Element; - +import org.jdom.JDOMException; +import org.jdom.Namespace; +import org.jdom.input.SAXBuilder; /** * */ -public abstract class AbstractLuceneExpression implements IBasicExpression -{ +public abstract class AbstractLuceneExpression implements IBasicExpression { + + static final String LOG_CHANNEL = "org.apache.slide.index.lucene.expressions"; + + protected LuceneExpressionFactory factory; + + protected Index index; - static final String LOG_CHANNEL = "org.apache.slide.index.lucene.expressions"; - - protected LuceneExpressionFactory factory; - protected Index index; - private IBasicResultSet resultSet = null; - - private Query query; - - public AbstractLuceneExpression(Index index) { - this.index = index; - } - - protected final void setQuery(Query query) { - this.query = query; - } - protected final Query getQuery() { - return this.query; - } - - public IBasicExpressionFactory getFactory() - { - return factory; - } - - public void setFactory(IBasicExpressionFactory factory) - { - this.factory = (LuceneExpressionFactory)factory; - } - - public IBasicResultSet execute() throws SearchException - { - if (this.resultSet != null) { - return this.resultSet; - } - - Query luceneQuery = this.getQuery(); - - IBasicQuery q = factory.getQuery(); - String scope = q.getSearchToken().getSlideContext().getSlidePath( - q.getScope().getHref()); - if (scope.endsWith("/") && scope.length() > 1) { - scope = scope.substring(0, scope.length()-1); - } - - // add a scope restriction, this allows negated queries too - BooleanQuery booleanQuery = new BooleanQuery(); - booleanQuery.add(luceneQuery, true, false); - booleanQuery.add(new TermQuery(new Term(Index.SCOPE_FIELD_NAME, scope)), - true, false); - - // add depth restriction - switch (q.getScope().getDepth() ) { - case QueryScope.DEPTH_INFINITY: - break; - case QueryScope.DEPTH_0: - booleanQuery.add(new TermQuery(new Term(Index.DEPTH_FIELD_NAME, - index.getConfiguration().intToIndexString(getDepth(scope)))), - true, false); - break; - case QueryScope.DEPTH_1: - default: - booleanQuery.add(new RangeQuery( - new Term(Index.DEPTH_FIELD_NAME, - index.getConfiguration().intToIndexString(getDepth(scope))), - new Term(Index.DEPTH_FIELD_NAME, - index.getConfiguration().intToIndexString(getDepth(scope)+q.getScope().getDepth())), - true), - true, false); - - - } - luceneQuery = booleanQuery; - - IndexSearcher searcher = null; - try { - if (index.getLogger().isEnabled(LOG_CHANNEL, Logger.DEBUG)) { - index.getLogger().log("start query execution: " + - luceneQuery.toString(), LOG_CHANNEL, Logger.DEBUG); - } - long start = System.currentTimeMillis(); - - searcher = this.index.getSearcher(); - Hits hits = searcher.search(luceneQuery); - - if (index.getLogger().isEnabled(LOG_CHANNEL, Logger.DEBUG)) { - index.getLogger().log("finished: " + hits.length() + " hits (" + - (System.currentTimeMillis() - start) + "ms)" , LOG_CHANNEL, Logger.DEBUG); - } - - IBasicResultSet result = new BasicResultSetImpl(false); - - for (int i = 0, l = hits.length(); i < l; i++) { - Document doc = hits.doc(i); - String uri = doc.get(Index.URI_FIELD_NAME); - String number = doc.get(Index.REVISION_FIELD_NAME); - NodeRevisionNumber nodeNumber = new NodeRevisionNumber(number); - RequestedResource resource = createResource(uri, nodeNumber); - result.add(resource); - } - - this.resultSet = result; - return result; - } catch (InvalidScopeException e) { - throw e; - } catch (SearchException e) { - throw e; - } catch (IOException e) { - throw new SearchException(e); - } finally { - if (searcher != null) { - try { - searcher.close(); - } catch (IOException e1) { - // ignore - } - } - } - } - - private int getDepth(String path) { - StringTokenizer tokenizer = new StringTokenizer(path, "/"); - return tokenizer.countTokens(); - } - - protected Query negateQuery(Query query) { - BooleanQuery booleanQuery = new BooleanQuery(); - booleanQuery.add( - allQuery(), - true, false); - booleanQuery.add( - query, - false, true); - return booleanQuery; - } - - protected Query allQuery() { - return new TermQuery(new Term(Index.SCOPE_FIELD_NAME, "/")); - } - - protected RequestedResource createResource(String uri, NodeRevisionNumber nodeNumber) throws SearchException - { - ObjectNode node = new SubjectNode(uri); // this will return the root - // folder - RequestedResource resource = null; - IBasicQuery query = factory.getQuery(); - - try { - resource = new ComparableResourceImpl(node, query.getSearchToken(), - query.getScope(), factory.getPropertyProvider(), nodeNumber); - } catch (SlideException e) { - throw new SearchException(e); - } - return resource; - } - - protected static Element getFirstElement(Element node) - { - List children = node.getChildren(); - - for (int i = 0; i < children.size(); i++) { - if (children.get(i) instanceof Element) { - return (Element)children.get(i); - } - } - return null; - } - - /** - * Returns the first <code>D:prop</code> element. - * @param operator - * @return Element - * @throws BadQueryException if element not found - */ - public static Element getPropertyElement(Element operator) throws BadQueryException - { - Element prop = operator.getChild("prop", - NodeProperty.NamespaceCache.DEFAULT_NAMESPACE); - if (prop == null) throw new InvalidQueryException("Missing prop element"); - - prop = getFirstElement(prop); - if (prop == null) throw new InvalidQueryException("Empty prop element given"); - return prop; - } - /** - * Retruns the first <code>D:literal</code> element. - * @param operator - * @return - * @throws BadQueryException if element not found - */ - protected Element getLiteralElement(Element operator) throws BadQueryException - { - Element literal = operator.getChild("literal", - NodeProperty.NamespaceCache.DEFAULT_NAMESPACE); - if (literal == null) throw new InvalidQueryException("Missing literal element"); - return literal; - } - - protected Element getLiteral2Element(Element operator) throws BadQueryException - { - List children = operator.getChildren("literal", - NodeProperty.NamespaceCache.DEFAULT_NAMESPACE); - if (children.size() > 1) { - return (Element)children.get(1); - } else { - throw new InvalidQueryException("Missing second literal element"); - } - } + private IBasicResultSet resultSet = null; + + private Query query; + + private SAXBuilder saxBuilder = new SAXBuilder(); + + public AbstractLuceneExpression(Index index) { + this.index = index; + } + + protected final void setQuery(Query query) { + this.query = query; + } + + protected final Query getQuery() { + return this.query; + } + + public IBasicExpressionFactory getFactory() { + return factory; + } + + public void setFactory(IBasicExpressionFactory factory) { + this.factory = (LuceneExpressionFactory) factory; + } + + public IBasicResultSet execute() throws SearchException { + return this.execute(null, -1); + } + + public IBasicResultSet execute(OrderBy orderBy) throws SearchException { + return this.execute(orderBy, -1); + } + + public IBasicResultSet execute(OrderBy orderBy, int limit) + throws SearchException { + if (this.resultSet != null) { + return this.resultSet; + } + + Query luceneQuery = this.getQuery(); + + IBasicQuery q = factory.getQuery(); + String scope = q.getSearchToken().getSlideContext().getSlidePath( + q.getScope().getHref()); + if (scope.endsWith("/") && scope.length() > 1) { + scope = scope.substring(0, scope.length() - 1); + } + + // add a scope restriction, this allows negated queries too + BooleanQuery booleanQuery = new BooleanQuery(); + + if (luceneQuery != null) + booleanQuery.add(luceneQuery, true, false); + + booleanQuery.add( + new TermQuery(new Term(Index.SCOPE_FIELD_NAME, scope)), true, + false); + + int queryScopeHrefDepth = getDepth(scope); + + // add depth restriction + switch (q.getScope().getDepth()) { + case QueryScope.DEPTH_INFINITY: + break; + case QueryScope.DEPTH_0: + booleanQuery.add( + new TermQuery(new Term(Index.DEPTH_FIELD_NAME, index + .getConfiguration().intToIndexString( + getDepth(scope)))), true, false); + break; + case QueryScope.DEPTH_1: + default: + booleanQuery + .add( + new RangeQuery( + new Term(Index.DEPTH_FIELD_NAME, index + .getConfiguration() + .intToIndexString(getDepth(scope))), + new Term( + Index.DEPTH_FIELD_NAME, + index + .getConfiguration() + .intToIndexString( + getDepth(scope) + + q + .getScope() + .getDepth())), + true), true, false); + + } + + luceneQuery = booleanQuery; + + Sort sorter = null; + if (orderBy != null && orderBy instanceof LuceneOrderBy) { + sorter = ((LuceneOrderBy) orderBy).getSorter(); + + if (index.getLogger().isEnabled(LOG_CHANNEL, Logger.DEBUG)) { + index.getLogger().log( + " Gotten a sorter! from LuceneOrderBy " + sorter, + LOG_CHANNEL, Logger.DEBUG); + } + } + + IndexSearcher searcher = null; + try { + if (index.getLogger().isEnabled(LOG_CHANNEL, Logger.DEBUG)) { + index.getLogger().log( + "start query execution: " + luceneQuery.toString(), + LOG_CHANNEL, Logger.DEBUG); + } + long start = System.currentTimeMillis(); + + searcher = this.index.getSearcher(); + Hits hits = null; + + if (sorter != null) { + hits = searcher.search(luceneQuery, sorter); + + if (index.getLogger().isEnabled(LOG_CHANNEL, Logger.DEBUG)) { + index.getLogger().log(" Query uses sorter! " + sorter, + LOG_CHANNEL, Logger.DEBUG); + } + } else + hits = searcher.search(luceneQuery); + + if (index.getLogger().isEnabled(LOG_CHANNEL, Logger.DEBUG)) { + index.getLogger().log( + "finished: " + hits.length() + " hits (" + + (System.currentTimeMillis() - start) + "ms)", + LOG_CHANNEL, Logger.DEBUG); + } + + IBasicResultSet result = new LuceneBasicResultSetImpl(false); + + int counter = 0; + for (int i = 0, l = hits.length(); (i < l) + && (limit < 0 || counter < limit); i++) { + Document doc = hits.doc(i); + String uri = doc.get(Index.URI_FIELD_NAME); + String number = doc.get(Index.REVISION_FIELD_NAME); + NodeRevisionNumber nodeNumber = new NodeRevisionNumber(number); + RequestedResource resource = null; + + // TODO: This is just a quick hack to enable DASL with binding store + // Please replace with something less evel! + // At least the INDEXED_BINDING_URI_IDENTIFIER prefix should be added at indexing time + if (Configuration.useGlobalBinding()) { + resource = createResource(BindingStore.INDEXED_BINDING_URI_IDENTIFIER + uri, nodeNumber); + if (resource != null) { + try { + NodeProperty parentProperty = resource.getProperty( + "parent-set", + NodeProperty.DEFAULT_NAMESPACE); + String parentValue = "<parents>"+parentProperty.getValue()+"</parents>"; + // Get bindings for resource + org.jdom.Document parentDocument = saxBuilder.build(new StringReader((String)parentValue)); + List parents = parentDocument.getRootElement().getChildren(); + for ( Iterator parentIterator = parents.iterator(); parentIterator.hasNext(); ) { + Element parent = (Element)parentIterator.next(); + String href = parent.getChild("href", Namespace.getNamespace("DAV:")).getText(); + String segment = parent.getChild("segment", Namespace.getNamespace("DAV:")).getText(); + RequestedResource binding = (RequestedResource)resource.clone(); + binding.setUri(href+"/"+segment); + result.add(binding); + counter++; + } + } catch (SlideException e) { + throw new SearchException("Property 'parent-set' must be present when using binding enabled search", e); + } catch (JDOMException e) { + throw new SearchException("Malformed 'parent-set' property value", e); + } + } + } else { + resource = createResource(uri, nodeNumber); + if (resource != null) { + result.add(resource); + counter++; + } + } + } + this.resultSet = result; + return result; + } catch (InvalidScopeException e) { + throw e; + } catch (SearchException e) { + throw e; + } catch (IOException e) { + throw new SearchException(e); + } finally { + if (searcher != null) { + try { + searcher.close(); + } catch (IOException e1) { + // ignore + } + } + } + } + + private int getDepth(String path) { + StringTokenizer tokenizer = new StringTokenizer(path, "/"); + return tokenizer.countTokens(); + } + + protected Query negateQuery(Query query) { + BooleanQuery booleanQuery = new BooleanQuery(); + booleanQuery.add(allQuery(), true, false); + booleanQuery.add(query, false, true); + return booleanQuery; + } + + protected Query allQuery() { + return new TermQuery(new Term(Index.SCOPE_FIELD_NAME, "/")); + } + + protected RequestedResource createResource(String uri, + NodeRevisionNumber nodeNumber) throws SearchException { + ObjectNode node = new SubjectNode(uri); // this will return the root + // folder + RequestedResource resource = null; + IBasicQuery query = factory.getQuery(); + + SlideTokenWrapper token = new SlideTokenWrapper(query.getSearchToken() + .getSlideToken()); + token.setForceLock(false); + + try { + // resource = new ComparableResourceImpl(node, + // query.getSearchToken(), + // query.getScope(), factory.getPropertyProvider()); + + resource = new ComparableResourceImpl(node, query.getSearchToken(), + query.getScope(), factory.getPropertyProvider(), nodeNumber); + } catch (AccessDeniedException e) { + // ignore, just not visible due to permissions + resource = null; + } catch (SlideException e) { + throw new SearchException(e); + } + return resource; + } + + protected static Element getFirstElement(Element node) { + List children = node.getChildren(); + + for (int i = 0; i < children.size(); i++) { + if (children.get(i) instanceof Element) { + return (Element) children.get(i); + } + } + return null; + } + + /** + * Returns the first <code>D:prop</code> element. + * + * @param operator + * @return Element + * @throws BadQueryException + * if element not found + */ + public static Element getPropertyElement(Element operator) + throws BadQueryException { + Element prop = operator.getChild("prop", + NodeProperty.NamespaceCache.DEFAULT_NAMESPACE); + if (prop == null) + throw new InvalidQueryException("Missing prop element"); + + prop = getFirstElement(prop); + if (prop == null) + throw new InvalidQueryException("Empty prop element given"); + return prop; + } + + /** + * Retruns the first <code>D:literal</code> element. + * + * @param operator + * @return + * @throws BadQueryException + * if element not found + */ + protected Element getLiteralElement(Element operator) + throws BadQueryException { + Element literal = operator.getChild("literal", + NodeProperty.NamespaceCache.DEFAULT_NAMESPACE); + if (literal == null) + throw new InvalidQueryException("Missing literal element"); + return literal; + } + + protected Element getLiteral2Element(Element operator) + throws BadQueryException { + List children = operator.getChildren("literal", + NodeProperty.NamespaceCache.DEFAULT_NAMESPACE); + if (children.size() > 1) { + return (Element) children.get(1); + } else { + throw new InvalidQueryException("Missing second literal element"); + } + } }
Modified: jakarta/slide/trunk/src/stores/org/apache/slide/index/lucene/expressions/LikeExpression.java URL: http://svn.apache.org/viewcvs/jakarta/slide/trunk/src/stores/org/apache/slide/index/lucene/expressions/LikeExpression.java?rev=356261&r1=356260&r2=356261&view=diff ============================================================================== --- jakarta/slide/trunk/src/stores/org/apache/slide/index/lucene/expressions/LikeExpression.java (original) +++ jakarta/slide/trunk/src/stores/org/apache/slide/index/lucene/expressions/LikeExpression.java Mon Dec 12 06:36:39 2005 @@ -99,10 +99,4 @@ return result.toString(); } - - public static void main(String[] a) { - System.out.println("abc".indexOf("c")); - System.out.println("abc".substring(0, "abc".length()-1)); - } - } --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]