Return-Path: Delivered-To: apmail-jackrabbit-commits-archive@www.apache.org Received: (qmail 61147 invoked from network); 8 Jan 2008 20:41:17 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 8 Jan 2008 20:41:17 -0000 Received: (qmail 90076 invoked by uid 500); 8 Jan 2008 20:41:07 -0000 Delivered-To: apmail-jackrabbit-commits-archive@jackrabbit.apache.org Received: (qmail 89989 invoked by uid 500); 8 Jan 2008 20:41:06 -0000 Mailing-List: contact commits-help@jackrabbit.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@jackrabbit.apache.org Delivered-To: mailing list commits@jackrabbit.apache.org Received: (qmail 89980 invoked by uid 99); 8 Jan 2008 20:41:06 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 08 Jan 2008 12:41:06 -0800 X-ASF-Spam-Status: No, hits=-100.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.3] (HELO eris.apache.org) (140.211.11.3) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 08 Jan 2008 20:41:00 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 47AE81A985B; Tue, 8 Jan 2008 12:40:50 -0800 (PST) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r610137 - in /jackrabbit/trunk/jackrabbit-jcr-commons: ./ src/main/java/org/apache/jackrabbit/commons/packaging/ src/main/java/org/apache/jackrabbit/commons/predicate/ src/main/java/org/apache/jackrabbit/commons/visitor/ Date: Tue, 08 Jan 2008 20:40:47 -0000 To: commits@jackrabbit.apache.org From: jukka@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20080108204050.47AE81A985B@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: jukka Date: Tue Jan 8 12:40:45 2008 New Revision: 610137 URL: http://svn.apache.org/viewvc?rev=610137&view=rev Log: JCR-1259: Utility code for filtering and packaging trees - Patch by Carsten Ziegeler Added: jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/packaging/ jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/packaging/ContentPackage.java jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/packaging/ContentPackageExporter.java jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/packaging/FilterContentPackage.java jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/predicate/ jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/predicate/DeclaringTypePredicate.java jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/predicate/DepthPredicate.java jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/predicate/IsMandatoryPredicate.java jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/predicate/IsNodePredicate.java jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/predicate/NamePredicate.java jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/predicate/NodeTypePredicate.java jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/predicate/NtFilePredicate.java jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/predicate/PathPredicate.java jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/visitor/ jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/visitor/FilteringItemVisitor.java Modified: jackrabbit/trunk/jackrabbit-jcr-commons/pom.xml Modified: jackrabbit/trunk/jackrabbit-jcr-commons/pom.xml URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr-commons/pom.xml?rev=610137&r1=610136&r2=610137&view=diff ============================================================================== --- jackrabbit/trunk/jackrabbit-jcr-commons/pom.xml (original) +++ jackrabbit/trunk/jackrabbit-jcr-commons/pom.xml Tue Jan 8 12:40:45 2008 @@ -51,6 +51,10 @@ jcr + commons-collections + commons-collections + + org.slf4j slf4j-api Added: jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/packaging/ContentPackage.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/packaging/ContentPackage.java?rev=610137&view=auto ============================================================================== --- jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/packaging/ContentPackage.java (added) +++ jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/packaging/ContentPackage.java Tue Jan 8 12:40:45 2008 @@ -0,0 +1,27 @@ +/* + * 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. + */ +package org.apache.jackrabbit.commons.packaging; + +import java.util.Iterator; + +import javax.jcr.RepositoryException; +import javax.jcr.Session; + +public interface ContentPackage { + + Iterator getItems(Session session) throws RepositoryException; +} Added: jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/packaging/ContentPackageExporter.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/packaging/ContentPackageExporter.java?rev=610137&view=auto ============================================================================== --- jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/packaging/ContentPackageExporter.java (added) +++ jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/packaging/ContentPackageExporter.java Tue Jan 8 12:40:45 2008 @@ -0,0 +1,27 @@ +/* + * 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. + */ +package org.apache.jackrabbit.commons.packaging; + +import java.io.OutputStream; + +import javax.jcr.RepositoryException; + +public interface ContentPackageExporter { + + void export(ContentPackage description, OutputStream out) + throws RepositoryException; +} Added: jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/packaging/FilterContentPackage.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/packaging/FilterContentPackage.java?rev=610137&view=auto ============================================================================== --- jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/packaging/FilterContentPackage.java (added) +++ jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/packaging/FilterContentPackage.java Tue Jan 8 12:40:45 2008 @@ -0,0 +1,206 @@ +/* + * 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. + */ +package org.apache.jackrabbit.commons.packaging; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.NoSuchElementException; + +import javax.jcr.Item; +import javax.jcr.Node; +import javax.jcr.NodeIterator; +import javax.jcr.PropertyIterator; +import javax.jcr.RepositoryException; +import javax.jcr.Session; + +import org.apache.commons.collections.Predicate; + + +public class FilterContentPackage implements ContentPackage { + + protected final List content = new ArrayList(); + + protected boolean includeProperties = false; + + public void addContent(String path, Predicate filterList) { + this.content.add(new Content(new String[] {path}, filterList)); + } + + public void addContent(String[] paths, Predicate filterList) { + this.content.add(new Content(paths, filterList)); + } + + /** + * @see org.apache.jackrabbit.commons.packaging.ContentPackage#getItems(javax.jcr.Session) + */ + public Iterator getItems(Session session) + throws RepositoryException { + return new FilteringIterator(session, new ArrayList(this.content), this.includeProperties); + } + + protected static class Content { + protected final String[] paths; + protected final Predicate filterList; + + public Content(String[] paths, Predicate filterList) { + this.paths = paths; + this.filterList = filterList; + } + } + + public static class FilteringIterator implements Iterator { + + /** The content we will iterate over. */ + protected final List content; + + /** + * Filter that defines which items are included + */ + protected Predicate includeFilter; + + protected int contentIndex, pathIndex; + + protected Item nextItem; + + protected Node lastNode; + + protected final Session session; + + protected final List nodeIteratorStack = new ArrayList(); + + protected final boolean includeProperties; + + protected PropertyIterator propertyIterator; + + /** + * Creates a new tree walker that uses the given filter as include and + * traversal filter. + * + * @param session The session. + * @param contentList The list of content objects. + * @param includeProperties Should properties be included. + */ + public FilteringIterator(final Session session, + final List contentList, + final boolean includeProperties) { + this.content = contentList; + this.session = session; + this.includeProperties = includeProperties; + } + + /** + * @see java.util.Iterator#hasNext() + */ + public boolean hasNext() { + if ( this.nextItem != null ) { + return true; + } + try { + return this.checkForNextNode(); + } catch (RepositoryException e) { + // if any error occurs, we stop iterating + return false; + } + } + + protected boolean checkForNextNode() throws RepositoryException { + if ( this.propertyIterator != null ) { + if ( this.propertyIterator.hasNext() ) { + this.nextItem = this.propertyIterator.nextProperty(); + return true; + } + this.propertyIterator = null; + } else if ( this.includeProperties && this.lastNode != null ) { + if ( this.lastNode.hasProperties() ) { + this.propertyIterator = this.lastNode.getProperties(); + this.propertyIterator.hasNext(); + this.nextItem = this.propertyIterator.nextProperty(); + return true; + } + } + if ( this.lastNode != null ) { + + if ( this.lastNode.hasNodes() ) { + final NodeIterator iter = this.lastNode.getNodes(); + this.nodeIteratorStack.add(iter); + } + while ( this.nodeIteratorStack.size() > 0 ) { + final NodeIterator iter = (NodeIterator)this.nodeIteratorStack.get(this.nodeIteratorStack.size() - 1); + if ( iter.hasNext() ) { + do { + final Node contextNode = iter.nextNode(); + if ( this.includeFilter.evaluate(contextNode) ) { + this.lastNode = contextNode; + this.nextItem = contextNode; + return true; + } + } while ( iter.hasNext() ); + } + this.nodeIteratorStack.remove(iter); + } + this.pathIndex++; + this.lastNode = null; + } + while ( this.contentIndex < this.content.size() ) { + final Content content = (Content)this.content.get(this.contentIndex); + this.includeFilter = content.filterList; + while ( this.pathIndex < content.paths.length ) { + final String path = content.paths[this.pathIndex]; + this.pathIndex++; + final Node contextNode = (Node)this.session.getItem(path); + if ( this.includeFilter.evaluate(contextNode) ) { + this.lastNode = contextNode; + this.nextItem = contextNode; + return true; + } + } + this.contentIndex++; + this.pathIndex = 0; + } + + return false; + } + + /** + * @see java.util.Iterator#next() + */ + public Object next() { + if ( this.hasNext() ) { + final Item result = nextItem; + this.nextItem = null; + return result; + } + throw new NoSuchElementException("No more elements available"); + } + + /** + * @see java.util.Iterator#remove() + */ + public void remove() { + throw new UnsupportedOperationException("Remove is not supported."); + } + } + + public boolean isIncludeProperties() { + return includeProperties; + } + + public void setIncludeProperties(boolean includeProperties) { + this.includeProperties = includeProperties; + } +} Added: jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/predicate/DeclaringTypePredicate.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/predicate/DeclaringTypePredicate.java?rev=610137&view=auto ============================================================================== --- jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/predicate/DeclaringTypePredicate.java (added) +++ jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/predicate/DeclaringTypePredicate.java Tue Jan 8 12:40:45 2008 @@ -0,0 +1,75 @@ +/* + * 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. + */ +package org.apache.jackrabbit.commons.predicate; + +import javax.jcr.Item; +import javax.jcr.Node; +import javax.jcr.Property; +import javax.jcr.RepositoryException; + +/** + * Filter that checks the declared type of an item + * + */ +public class DeclaringTypePredicate extends DepthPredicate { + + /** + * The nodetype to check + */ + protected final String nodeType; + + /** + * indicates if only props should be checked + */ + protected final boolean propsOnly; + + /** + * Creates a new filter for the given nodetype and flags. + * @param nodeType the nodetype name to check + * @param propsOnly if true only properties are checked + * @param minDepth the minimal depth + * @param maxDepth the maximal depth + */ + public DeclaringTypePredicate(String nodeType, boolean propsOnly, + int minDepth, int maxDepth) { + super(minDepth, maxDepth); + this.nodeType = nodeType; + this.propsOnly = propsOnly; + } + + /** + * Creates a new filter for the given nodetype and flags + * @param nodeType the nodetype name to check + * @param propsOnly if true only properties are checked + */ + public DeclaringTypePredicate(String nodeType, boolean propsOnly) { + this(nodeType, propsOnly, 0, Integer.MAX_VALUE); + } + + /** + * Matches if the declaring nodetype of the item is equal to the one + * specified in this filter. If the item is a node and propsOnly + * flag is true it returns false. + * @see org.apache.jackrabbit.commons.predicate.DepthPredicate#matches(javax.jcr.Item) + */ + protected boolean matches(Item item) throws RepositoryException { + if (item.isNode()) { + return !propsOnly && ((Node) item).getDefinition().getDeclaringNodeType().getName().equals(nodeType); + } + return ((Property) item).getDefinition().getDeclaringNodeType().getName().equals(nodeType); + } +} \ No newline at end of file Added: jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/predicate/DepthPredicate.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/predicate/DepthPredicate.java?rev=610137&view=auto ============================================================================== --- jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/predicate/DepthPredicate.java (added) +++ jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/predicate/DepthPredicate.java Tue Jan 8 12:40:45 2008 @@ -0,0 +1,79 @@ +/* + * 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. + */ +package org.apache.jackrabbit.commons.predicate; + +import javax.jcr.Item; +import javax.jcr.RepositoryException; + +import org.apache.commons.collections.Predicate; + +/** + * Implements a filter that filters item according to their (passed) depth. + * + */ +public class DepthPredicate implements Predicate { + + /** + * The minimal depth + */ + protected final int minDepth; + + /** + * The maximal depth + */ + protected final int maxDepth; + + /** + * Creates a new depth filter for the given depths. + * @param minDepth the minimal depth + * @param maxDepth the maximal depth + */ + public DepthPredicate(int minDepth, int maxDepth) { + this.minDepth = minDepth; + this.maxDepth = maxDepth; + } + + /** + * Matches if the given depth is greater or equal the minimum depth and + * less or equal the maximum depth and if the call to {@link #matches(Item)} + * returns true. + * @see org.apache.commons.collections.Predicate#evaluate(java.lang.Object) + */ + public boolean evaluate(Object item) { + if ( item instanceof Item ) { + try { + final int depth = ((Item)item).getDepth(); + return depth >= minDepth && depth <= maxDepth && matches((Item)item); + } catch (RepositoryException re) { + return false; + } + } + return false; + } + + /** + * Returns true. Subclasses can override to implement something + * useful that is dependant of the depth. + * + * @param item the item to match + * @return true if the item matches; false otherwise. + * @throws RepositoryException if an error occurs. + */ + protected boolean matches(Item item) throws RepositoryException { + return true; + } +} \ No newline at end of file Added: jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/predicate/IsMandatoryPredicate.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/predicate/IsMandatoryPredicate.java?rev=610137&view=auto ============================================================================== --- jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/predicate/IsMandatoryPredicate.java (added) +++ jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/predicate/IsMandatoryPredicate.java Tue Jan 8 12:40:45 2008 @@ -0,0 +1,54 @@ +/* + * 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. + */ +package org.apache.jackrabbit.commons.predicate; + +import javax.jcr.Item; +import javax.jcr.Node; +import javax.jcr.Property; +import javax.jcr.RepositoryException; + +/** + * IsMandatoryFilter... + * + */ +public class IsMandatoryPredicate extends DepthPredicate { + + protected final boolean isMandatory; + + public IsMandatoryPredicate() { + this(true); + } + + public IsMandatoryPredicate(boolean isMandatory, int minDepth, int maxDepth) { + super(minDepth, maxDepth); + this.isMandatory = isMandatory; + } + + public IsMandatoryPredicate(boolean isMandatory) { + this(isMandatory, 0, Integer.MAX_VALUE); + } + + /** + * @see org.apache.jackrabbit.commons.predicate.DepthPredicate#matches(javax.jcr.Item) + */ + protected boolean matches(Item item) throws RepositoryException { + if (item.isNode()) { + return ((Node) item).getDefinition().isMandatory() == isMandatory; + } + return ((Property) item).getDefinition().isMandatory() == isMandatory; + } +} \ No newline at end of file Added: jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/predicate/IsNodePredicate.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/predicate/IsNodePredicate.java?rev=610137&view=auto ============================================================================== --- jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/predicate/IsNodePredicate.java (added) +++ jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/predicate/IsNodePredicate.java Tue Jan 8 12:40:45 2008 @@ -0,0 +1,72 @@ +/* + * 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. + */ +package org.apache.jackrabbit.commons.predicate; + +import javax.jcr.Item; +import javax.jcr.RepositoryException; + +/** + * Item filter that checks if an item is a node. + * + */ +public class IsNodePredicate extends DepthPredicate { + + /** + * Polarity of this filter + */ + protected final boolean isNode; + + /** + * Default constructor. + */ + public IsNodePredicate() { + this(true); + } + + /** + * Creates a new node item filter. + * + * @param polarity the polarity of this filter. if true it matches + * nodes, if false it matches properties. + * @param minDepth the minimum depth + * @param maxDepth the maximum depth + * + * @see DepthPredicate + */ + public IsNodePredicate(boolean polarity, int minDepth, int maxDepth) { + super(minDepth, maxDepth); + isNode = polarity; + } + + /** + * Creates a new node item filter + * @param polarity the polarity of this filter. if true it matches + * nodes, if false it matches properties. + */ + public IsNodePredicate(boolean polarity) { + this(polarity, 0, Integer.MAX_VALUE); + } + + /** + * Returns true if the item is a node and the polarity is + * positive (true). + * @see org.apache.jackrabbit.commons.predicate.DepthPredicate#matches(javax.jcr.Item) + */ + protected boolean matches(Item item) throws RepositoryException { + return item.isNode() == isNode; + } +} \ No newline at end of file Added: jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/predicate/NamePredicate.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/predicate/NamePredicate.java?rev=610137&view=auto ============================================================================== --- jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/predicate/NamePredicate.java (added) +++ jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/predicate/NamePredicate.java Tue Jan 8 12:40:45 2008 @@ -0,0 +1,60 @@ +/* + * 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. + */ +package org.apache.jackrabbit.commons.predicate; + +import javax.jcr.Item; +import javax.jcr.RepositoryException; + +/** + * Filters items according to their names. + * + */ +public class NamePredicate extends DepthPredicate { + + /** + * The name to filter on + */ + protected final String name; + + /** + * Creates a new name filter with the given name and depths + * @param name the name to filter on + * @param minDepth the minimal depth + * @param maxDepth the maximal depth + */ + public NamePredicate(String name, int minDepth, int maxDepth) { + super(minDepth, maxDepth); + this.name = name; + } + + /** + * Creates a new name filter with the given name. + * @param name the name to filter on + */ + public NamePredicate(String name) { + this(name, 0, Integer.MAX_VALUE); + } + + /** + * Returns true if the name of the given item is equal to + * the configured name. + * @see org.apache.jackrabbit.commons.predicate.DepthPredicate#matches(javax.jcr.Item) + */ + protected boolean matches(Item item) throws RepositoryException { + return item.getName().equals(name); + } +} \ No newline at end of file Added: jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/predicate/NodeTypePredicate.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/predicate/NodeTypePredicate.java?rev=610137&view=auto ============================================================================== --- jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/predicate/NodeTypePredicate.java (added) +++ jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/predicate/NodeTypePredicate.java Tue Jan 8 12:40:45 2008 @@ -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. + */ +package org.apache.jackrabbit.commons.predicate; + +import javax.jcr.Item; +import javax.jcr.Node; +import javax.jcr.RepositoryException; + +/** + * Filters on the node type of a node. + * + */ +public class NodeTypePredicate extends DepthPredicate { + + /** + * the nodetype to filter on + */ + protected final String nodeType; + + /** + * indicates if supertypes should be respected + */ + protected final boolean respectSupertype; + + /** + * Creates a new node type filter. + * @param nodeType the node type to filter on + * @param respectSupertype indicates if supertype should be respected + * @param minDepth the minimal depth + * @param maxDepth the maximal depth + */ + public NodeTypePredicate(String nodeType, boolean respectSupertype, + int minDepth, int maxDepth) { + super(minDepth, maxDepth); + this.nodeType = nodeType; + this.respectSupertype = respectSupertype; + } + + /** + * Creates a new node type filter. + * @param nodeType the node type to filter on + * @param respectSupertype indicates if supertype should be respected + */ + public NodeTypePredicate(String nodeType, boolean respectSupertype) { + this(nodeType, respectSupertype, 0, Integer.MAX_VALUE); + } + + /** + * Returns true if the item is a node and if the configured + * nodetype is equal to the primary type of the node. if supertypes are + * respected it also returns true if the items nodetype + * extends from the configured node type (Node.isNodeType() check). + * @see org.apache.jackrabbit.commons.predicate.DepthPredicate#matches(javax.jcr.Item) + */ + protected boolean matches(Item item) throws RepositoryException { + if (item.isNode()) { + if (respectSupertype) { + try { + return ((Node) item).isNodeType(nodeType); + } catch (RepositoryException e) { + // ignore + return false; + } + } + return ((Node) item).getPrimaryNodeType().getName().equals(nodeType); + } + return false; + + } +} \ No newline at end of file Added: jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/predicate/NtFilePredicate.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/predicate/NtFilePredicate.java?rev=610137&view=auto ============================================================================== --- jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/predicate/NtFilePredicate.java (added) +++ jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/predicate/NtFilePredicate.java Tue Jan 8 12:40:45 2008 @@ -0,0 +1,118 @@ +/* + * 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. + */ +package org.apache.jackrabbit.commons.predicate; + +import javax.jcr.Item; +import javax.jcr.Property; +import javax.jcr.RepositoryException; + +import org.apache.commons.collections.Predicate; + +/** + * The nt file item filter matches all properties that are defined my the + * nt:file or nt:resource nodetype. the later only, if the respective nodes + * name is 'jcr:content'. + * + * Additionally the properties 'jcr:encoding' can be configured to be excluded. + * + */ +public class NtFilePredicate implements Predicate { + + public static final String NT_FILE = "nt:file"; + public static final String NT_HIERARCHYNODE = "nt:hierarchyNode"; + public static final String NT_RESOURCE = "nt:resource"; + public static final String JCR_CONTENT = "jcr:content"; + public static final String JCR_ENCODING = "jcr:encoding"; + public static final String JCR_MIMETYPE = "jcr:mimeType"; + public static final String JCR_PRIMARY_TYPE = "jcr:primaryType"; + + /** + * indicates if the jcr:encoding property is to be excluded from this filter. + */ + protected final boolean ignoreEncoding; + + /** + * indicates if the jcr:mimeType property is to be excluded from this filter. + */ + protected final boolean ignoreMimeType; + + public NtFilePredicate() { + this(false, false); + } + + public NtFilePredicate(boolean ignoreEncoding, boolean ignoreMimeType) { + this.ignoreEncoding = ignoreEncoding; + this.ignoreMimeType = ignoreMimeType; + } + + /** + * Returns the ignore encoding flag. + * @return the ignore encoding flag. + */ + public boolean isIgnoreEncoding() { + return ignoreEncoding; + } + + /** + * Returns the ignore mime type flag. + * @return the ignore mime type flag. + */ + public boolean isIgnoreMimeType() { + return ignoreMimeType; + } + + /** + * @return true if the item is a nt:file or nt:resource property + * @see org.apache.commons.collections.Predicate#evaluate(java.lang.Object) + */ + public boolean evaluate(Object item) { + if ( item instanceof Item ) { + if (!((Item)item).isNode()) { + try { + Property prop = (Property) item; + String dnt = prop.getDefinition().getDeclaringNodeType().getName(); + // exclude all nt:file props + if (dnt.equals(NT_FILE) || dnt.equals(NT_HIERARCHYNODE)) { + return true; + } + if (ignoreEncoding && prop.getName().equals(JCR_ENCODING)) { + return false; + } + if (ignoreMimeType && prop.getName().equals(JCR_MIMETYPE)) { + return false; + } + // exclude nt:resource props, if parent is 'jcr:content' + if (prop.getParent().getName().equals(JCR_CONTENT)) { + if (dnt.equals(NT_RESOURCE)) { + return true; + } + // exclude primary type if nt:resource + /* + if (prop.getName().equals(JCR_PRIMARY_TYPE) + && prop.getValue().getString().equals(NT_RESOURCE)) { + return true; + } + */ + } + } catch (RepositoryException re) { + return false; + } + } + } + return false; + } +} \ No newline at end of file Added: jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/predicate/PathPredicate.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/predicate/PathPredicate.java?rev=610137&view=auto ============================================================================== --- jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/predicate/PathPredicate.java (added) +++ jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/predicate/PathPredicate.java Tue Jan 8 12:40:45 2008 @@ -0,0 +1,79 @@ +/* + * 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. + */ +package org.apache.jackrabbit.commons.predicate; + +import java.util.regex.Pattern; + +import javax.jcr.Item; +import javax.jcr.RepositoryException; + +import org.apache.commons.collections.Predicate; + +/** + * The path filter provides hierarchical filtering. + * + */ +public class PathPredicate implements Predicate { + + /** + * the internal regex pattern + */ + protected final Pattern regex; + + /** + * Creates a new default path filter + * + * | Pattern | Matches + * | /foo | exactly "/foo" + * | /foo.* | all paths starting with "foo." + * | foo.* | all files starting with "foo." + * | /foo/* | all direct children of /foo + * | /foo/** | all children of /foo + * + * @param pattern the pattern + */ + public PathPredicate(String pattern) { + String suffix = ""; + String prefix = ""; + if (pattern.endsWith("/**")) { + suffix = "/.*"; + pattern = pattern.substring(0, pattern.length() - 3); + } else if (pattern.endsWith("*")) { + suffix = "[^/]*$"; + pattern = pattern.substring(0, pattern.length() - 1); + } + if (pattern.charAt(0) != '/') { + prefix = "^.*/"; + } + pattern = prefix + pattern.replaceAll("\\.", "\\\\.") + suffix; + regex = Pattern.compile(pattern); + } + + /** + * @see org.apache.commons.collections.Predicate#evaluate(java.lang.Object) + */ + public boolean evaluate(Object item) { + if ( item instanceof Item ) { + try { + return regex.matcher(((Item)item).getPath()).matches(); + } catch (RepositoryException re) { + return false; + } + } + return false; + } +} \ No newline at end of file Added: jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/visitor/FilteringItemVisitor.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/visitor/FilteringItemVisitor.java?rev=610137&view=auto ============================================================================== --- jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/visitor/FilteringItemVisitor.java (added) +++ jackrabbit/trunk/jackrabbit-jcr-commons/src/main/java/org/apache/jackrabbit/commons/visitor/FilteringItemVisitor.java Tue Jan 8 12:40:45 2008 @@ -0,0 +1,238 @@ +/* + * 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. + */ +package org.apache.jackrabbit.commons.visitor; + +import java.util.LinkedList; + +import javax.jcr.Item; +import javax.jcr.ItemVisitor; +import javax.jcr.Node; +import javax.jcr.NodeIterator; +import javax.jcr.Property; +import javax.jcr.PropertyIterator; +import javax.jcr.RepositoryException; + +import org.apache.commons.collections.Predicate; +import org.apache.commons.collections.functors.TruePredicate; + +public abstract class FilteringItemVisitor implements ItemVisitor { + + /** + * Predicate that defines which items are included. + */ + protected Predicate includePredicate = TruePredicate.INSTANCE; + + /** + * Predicate that defines which items are traversed. + */ + protected Predicate traversalPredicate = TruePredicate.INSTANCE; + + /** + * Do we want to walk all properties of nodes? + * The default is false. + */ + protected boolean walkProperties = false; + + /** + * indicates if traversal should be done in a breadth-first + * manner rather than depth-first (which is the default) + */ + protected boolean breadthFirst = false; + + /** + * the 0-based level up to which the hierarchy should be traversed + * (if it's -1, the hierarchy will be traversed until there are no + * more children of the current item) + */ + protected int maxLevel = -1; + + /** + * queues used to implement breadth-first traversal + */ + protected LinkedList currentQueue; + protected LinkedList nextQueue; + + /** + * used to track hierarchy level of item currently being processed + */ + protected int currentLevel; + + public void setMaxLevel(final int ml) { + this.maxLevel = ml; + } + + public void setBreadthFirst(final boolean flag) { + if ( this.breadthFirst != flag ) { + this.breadthFirst = flag; + if (breadthFirst) { + this.currentQueue = new LinkedList(); + this.nextQueue = new LinkedList(); + } else { + this.currentQueue = null; + this.nextQueue = null; + } + + } + } + public void setWalkProperties(final boolean flag) { + this.walkProperties = flag; + } + + public void setIncludePredicate(final Predicate ip) { + this.includePredicate = ip; + } + + public void setTraversalPredicate(final Predicate tp) { + this.traversalPredicate = tp; + } + + /** + * Implement this method to add behaviour performed before a + * Property is visited. + * + * @param property the Property that is accepting this visitor. + * @param level hierarchy level of this property (the root node starts at level 0) + * @throws RepositoryException if an error occurrs + */ + protected abstract void entering(Property property, int level) + throws RepositoryException; + + /** + * Implement this method to add behaviour performed before a + * Node is visited. + * + * @param node the Node that is accepting this visitor. + * @param level hierarchy level of this node (the root node starts at level 0) + * @throws RepositoryException if an error occurrs + */ + protected abstract void entering(Node node, int level) + throws RepositoryException; + + /** + * Implement this method to add behaviour performed after a + * Property is visited. + * + * @param property the Property that is accepting this visitor. + * @param level hierarchy level of this property (the root node starts at level 0) + * @throws RepositoryException if an error occurrs + */ + protected abstract void leaving(Property property, int level) + throws RepositoryException; + + /** + * Implement this method to add behaviour performed after a + * Node is visited. + * + * @param node the Node that is accepting this visitor. + * @param level hierarchy level of this node (the root node starts at level 0) + * @throws RepositoryException if an error occurrs + */ + protected abstract void leaving(Node node, int level) + throws RepositoryException; + + /** + * Called when the Visitor is passed to a Property. + *

+ * It calls TraversingItemVisitor.entering(Property, int) followed by + * TraversingItemVisitor.leaving(Property, int). Implement these abstract methods to + * specify behaviour on 'arrival at' and 'after leaving' the Property. + *

+ *

+ * If this method throws, the visiting process is aborted. + * + * @param property the Property that is accepting this visitor. + * @throws RepositoryException if an error occurrs + */ + public void visit(Property property) throws RepositoryException { + if ( this.walkProperties && this.includePredicate.evaluate(property) ) { + entering(property, currentLevel); + leaving(property, currentLevel); + } + } + + /** + * Called when the Visitor is passed to a Node. + *

+ * It calls TraversingItemVisitor.entering(Node, int) followed by + * TraversingItemVisitor.leaving(Node, int). Implement these abstract methods to + * specify behaviour on 'arrival at' and 'after leaving' the Node. + *

+ * If this method throws, the visiting process is aborted. + * + * @param node the Node that is accepting this visitor. + * @throws RepositoryException if an error occurrs + */ + public void visit(Node node) + throws RepositoryException { + if ( this.traversalPredicate.evaluate(node) ) { + if ( this.includePredicate == this.traversalPredicate || this.includePredicate.evaluate(node) ) { + try { + if (!breadthFirst) { + // depth-first traversal + entering(node, currentLevel); + if (maxLevel == -1 || currentLevel < maxLevel) { + currentLevel++; + if ( this.walkProperties ) { + PropertyIterator propIter = node.getProperties(); + while (propIter.hasNext()) { + propIter.nextProperty().accept(this); + } + } + NodeIterator nodeIter = node.getNodes(); + while (nodeIter.hasNext()) { + nodeIter.nextNode().accept(this); + } + currentLevel--; + } + leaving(node, currentLevel); + } else { + // breadth-first traversal + entering(node, currentLevel); + leaving(node, currentLevel); + + if (maxLevel == -1 || currentLevel < maxLevel) { + if ( this.walkProperties ) { + PropertyIterator propIter = node.getProperties(); + while (propIter.hasNext()) { + nextQueue.addLast(propIter.nextProperty()); + } + } + NodeIterator nodeIter = node.getNodes(); + while (nodeIter.hasNext()) { + nextQueue.addLast(nodeIter.nextNode()); + } + } + + while (!currentQueue.isEmpty() || !nextQueue.isEmpty()) { + if (currentQueue.isEmpty()) { + currentLevel++; + currentQueue = nextQueue; + nextQueue = new LinkedList(); + } + Item e = (Item) currentQueue.removeFirst(); + e.accept(this); + } + currentLevel = 0; + } + } catch (RepositoryException re) { + currentLevel = 0; + throw re; + } + } + } + } +}