You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by ju...@apache.org on 2009/11/25 15:04:50 UTC
svn commit: r884108 [3/10] - in /jackrabbit/sandbox/JCR-1456: ./
jackrabbit-api/
jackrabbit-api/src/main/java/org/apache/jackrabbit/api/security/
jackrabbit-api/src/main/java/org/apache/jackrabbit/api/security/user/
jackrabbit-core/ jackrabbit-core/src...
Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/JackrabbitIndexSearcher.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/JackrabbitIndexSearcher.java?rev=884108&r1=884107&r2=884108&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/JackrabbitIndexSearcher.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/JackrabbitIndexSearcher.java Wed Nov 25 14:04:38 2009
@@ -16,16 +16,17 @@
*/
package org.apache.jackrabbit.core.query.lucene;
-import org.apache.lucene.search.IndexSearcher;
-import org.apache.lucene.search.Query;
-import org.apache.lucene.search.Sort;
-import org.apache.lucene.index.IndexReader;
-import org.apache.jackrabbit.core.query.lucene.constraint.EvaluationContext;
+import java.io.IOException;
+
import org.apache.jackrabbit.core.SessionImpl;
+import org.apache.jackrabbit.core.query.lucene.constraint.EvaluationContext;
import org.apache.jackrabbit.core.state.ItemStateManager;
import org.apache.jackrabbit.spi.Name;
-
-import java.io.IOException;
+import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.Sort;
/**
* <code>JackrabbitIndexSearcher</code> implements an index searcher with
@@ -112,6 +113,19 @@
return hits;
}
+ //---------------------------< IndexSearcher >------------------------------
+
+ @Override
+ public int docFreq(Term term) throws IOException {
+ // provide a fixed document frequency for fields that are not fulltext
+ // indexed. correct frequency is only useful for fulltext queries.
+ if (FieldNames.isFulltextField(term.field())) {
+ return super.docFreq(term);
+ } else {
+ return 1;
+ }
+ }
+
//------------------------< EvaluationContext >-----------------------------
/**
Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/JackrabbitParser.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/JackrabbitParser.java?rev=884108&r1=884107&r2=884108&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/JackrabbitParser.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/JackrabbitParser.java Wed Nov 25 14:04:38 2009
@@ -26,11 +26,12 @@
import org.apache.tika.exception.TikaException;
import org.apache.tika.metadata.Metadata;
import org.apache.tika.parser.AutoDetectParser;
+import org.apache.tika.parser.ParseContext;
import org.apache.tika.parser.Parser;
import org.apache.tika.parser.html.HtmlParser;
import org.apache.tika.parser.image.ImageParser;
import org.apache.tika.parser.microsoft.OfficeParser;
-import org.apache.tika.parser.opendocument.OpenOfficeParser;
+import org.apache.tika.parser.odf.OpenDocumentParser;
import org.apache.tika.parser.pdf.PDFParser;
import org.apache.tika.parser.rtf.RTFParser;
import org.apache.tika.parser.txt.TXTParser;
@@ -136,7 +137,7 @@
parsers.put("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", parser);
} else if (name.equals(
"org.apache.jackrabbit.extractor.OpenOfficeTextExtractor")) {
- Parser parser = new OpenOfficeParser();
+ Parser parser = new OpenDocumentParser();
parsers.put("application/vnd.oasis.opendocument.database", parser);
parsers.put("application/vnd.oasis.opendocument.formula", parser);
parsers.put("application/vnd.oasis.opendocument.graphics", parser);
@@ -181,10 +182,17 @@
* Delegates the call to the configured {@link AutoDetectParser}.
*/
public void parse(
- InputStream stream, ContentHandler handler, Metadata metadata)
+ InputStream stream, ContentHandler handler,
+ Metadata metadata, ParseContext context)
throws IOException, SAXException, TikaException {
waitIfBlocked();
- parser.parse(stream, handler, metadata);
+ parser.parse(stream, handler, metadata, context);
+ }
+
+ public void parse(
+ InputStream stream, ContentHandler handler, Metadata metadata)
+ throws IOException, SAXException, TikaException {
+ parser.parse(stream, handler, metadata, new ParseContext());
}
/**
Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/LuceneQueryBuilder.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/LuceneQueryBuilder.java?rev=884108&r1=884107&r2=884108&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/LuceneQueryBuilder.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/LuceneQueryBuilder.java Wed Nov 25 14:04:38 2009
@@ -452,6 +452,17 @@
and.add(new NameQuery(nameTest, indexFormatVersion, nsMappings), Occur.MUST);
context = and;
}
+ // apply predicates
+ Object[] predicates = steps[0].acceptOperands(this, context);
+ BooleanQuery andQuery = new BooleanQuery();
+ for (Object predicate : predicates) {
+ andQuery.add((Query) predicate, Occur.MUST);
+ }
+ if (andQuery.clauses().size() > 0) {
+ andQuery.add(context, Occur.MUST);
+ context = andQuery;
+ }
+
LocationStepQueryNode[] tmp = new LocationStepQueryNode[steps.length - 1];
System.arraycopy(steps, 1, tmp, 0, steps.length - 1);
steps = tmp;
Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/LuceneQueryHits.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/LuceneQueryHits.java?rev=884108&r1=884107&r2=884108&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/LuceneQueryHits.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/LuceneQueryHits.java Wed Nov 25 14:04:38 2009
@@ -57,7 +57,8 @@
return null;
}
int doc = scorer.doc();
- NodeId id = new NodeId(reader.document(doc).get(FieldNames.UUID));
+ NodeId id = new NodeId(reader.document(
+ doc, FieldSelectors.UUID).get(FieldNames.UUID));
return new ScoreNode(id, scorer.score(), doc);
}
Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiIndex.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiIndex.java?rev=884108&r1=884107&r2=884108&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiIndex.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiIndex.java Wed Nov 25 14:04:38 2009
@@ -16,40 +16,41 @@
*/
package org.apache.jackrabbit.core.query.lucene;
+import java.io.IOException;
+import java.text.DateFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Collection;
+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;
+
+import javax.jcr.RepositoryException;
+
import org.apache.jackrabbit.core.id.NodeId;
import org.apache.jackrabbit.core.query.lucene.directory.DirectoryManager;
+import org.apache.jackrabbit.core.state.ChildNodeEntry;
import org.apache.jackrabbit.core.state.ItemStateException;
import org.apache.jackrabbit.core.state.ItemStateManager;
import org.apache.jackrabbit.core.state.NoSuchItemStateException;
import org.apache.jackrabbit.core.state.NodeState;
-import org.apache.jackrabbit.core.state.ChildNodeEntry;
-import org.apache.jackrabbit.util.Timer;
import org.apache.jackrabbit.spi.Path;
import org.apache.jackrabbit.spi.PathFactory;
-import org.apache.jackrabbit.spi.commons.name.PathFactoryImpl;
-import org.apache.jackrabbit.spi.commons.conversion.PathResolver;
import org.apache.jackrabbit.spi.commons.conversion.DefaultNamePathResolver;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.apache.jackrabbit.spi.commons.conversion.PathResolver;
+import org.apache.jackrabbit.spi.commons.name.PathFactoryImpl;
+import org.apache.jackrabbit.util.Timer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.store.Directory;
-
-import javax.jcr.RepositoryException;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Arrays;
-import java.util.Set;
-import java.util.HashSet;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Calendar;
-import java.text.DateFormat;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* A <code>MultiIndex</code> consists of a {@link VolatileIndex} and multiple
@@ -255,7 +256,7 @@
this.redoLog = redoLogFactory.createRedoLog(this);
// initialize IndexMerger
- merger = new IndexMerger(this, handler.getIndexMergerPoolSize());
+ merger = new IndexMerger(this, handler.getContext().getExecutor());
merger.setMaxMergeDocs(handler.getMaxMergeDocs());
merger.setMergeFactor(handler.getMergeFactor());
merger.setMinMergeDocs(handler.getMinMergeDocs());
Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/PersistentIndex.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/PersistentIndex.java?rev=884108&r1=884107&r2=884108&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/PersistentIndex.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/PersistentIndex.java Wed Nov 25 14:04:38 2009
@@ -16,17 +16,17 @@
*/
package org.apache.jackrabbit.core.query.lucene;
+import java.io.IOException;
+
+import org.apache.jackrabbit.core.query.lucene.directory.DirectoryManager;
import org.apache.lucene.analysis.Analyzer;
+import org.apache.lucene.index.IndexDeletionPolicy;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
-import org.apache.lucene.index.IndexDeletionPolicy;
+import org.apache.lucene.search.Similarity;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.IndexInput;
import org.apache.lucene.store.IndexOutput;
-import org.apache.lucene.search.Similarity;
-import org.apache.jackrabbit.core.query.lucene.directory.DirectoryManager;
-
-import java.io.IOException;
/**
* Implements a lucene index which is based on a
@@ -79,7 +79,7 @@
this.indexDelPolicy = new IndexDeletionPolicyImpl(this,
generationMaxAge * 1000);
if (isExisting()) {
- IndexMigration.migrate(this, directoryManager);
+ IndexMigration.migrate(this, directoryManager, '\uFFFF');
}
}
Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/QueryResultImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/QueryResultImpl.java?rev=884108&r1=884107&r2=884108&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/QueryResultImpl.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/QueryResultImpl.java Wed Nov 25 14:04:38 2009
@@ -290,9 +290,11 @@
MultiColumnQueryHits result = null;
try {
long time = System.currentTimeMillis();
+ long r1 = IOCounters.getReads();
result = executeQuery(maxResultSize);
- log.debug("query executed in {} ms",
- System.currentTimeMillis() - time);
+ long r2 = IOCounters.getReads();
+ log.debug("query executed in {} ms ({})",
+ System.currentTimeMillis() - time, r2 - r1);
// set selector names
selectorNames = result.getSelectorNames();
@@ -306,8 +308,9 @@
time = System.currentTimeMillis();
collectScoreNodes(result, resultNodes, maxResultSize);
- log.debug("retrieved ScoreNodes in {} ms",
- System.currentTimeMillis() - time);
+ long r3 = IOCounters.getReads();
+ log.debug("retrieved ScoreNodes in {} ms ({})",
+ System.currentTimeMillis() - time, r3 - r2);
// update numResults
numResults = result.getSize();
Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/RangeQuery.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/RangeQuery.java?rev=884108&r1=884107&r2=884108&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/RangeQuery.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/RangeQuery.java Wed Nov 25 14:04:38 2009
@@ -16,32 +16,42 @@
*/
package org.apache.jackrabbit.core.query.lucene;
-import org.apache.lucene.search.Query;
-import org.apache.lucene.search.Weight;
-import org.apache.lucene.search.Searcher;
-import org.apache.lucene.search.Scorer;
-import org.apache.lucene.search.Explanation;
-import org.apache.lucene.search.Similarity;
-import org.apache.lucene.search.ConstantScoreRangeQuery;
-import org.apache.lucene.index.Term;
-import org.apache.lucene.index.IndexReader;
-import org.apache.lucene.index.TermEnum;
-import org.apache.lucene.index.TermDocs;
-
import java.io.IOException;
-import java.util.BitSet;
-import java.util.Map;
-import java.util.List;
import java.util.ArrayList;
+import java.util.BitSet;
import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
import java.util.Set;
+import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.index.TermDocs;
+import org.apache.lucene.index.TermEnum;
+import org.apache.lucene.search.BooleanQuery;
+import org.apache.lucene.search.Explanation;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.Scorer;
+import org.apache.lucene.search.Searcher;
+import org.apache.lucene.search.Similarity;
+import org.apache.lucene.search.Weight;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
/**
- * Implements a lucene range query.
+ * Implements a variant of the lucene class {@link org.apache.lucene.search.RangeQuery}.
+ * This class does not rewrite to basic {@link org.apache.lucene.search.TermQuery}
+ * but will calculate the matching documents itself. That way a
+ * <code>TooManyClauses</code> can be avoided.
*/
public class RangeQuery extends Query implements Transformable {
/**
+ * Logger instance for this class.
+ */
+ private static final Logger log = LoggerFactory.getLogger(RangeQuery.class);
+
+ /**
* The lower term. May be <code>null</code> if <code>upperTerm</code> is not
* <code>null</code>.
*/
@@ -65,6 +75,12 @@
private int transform = TRANSFORM_NONE;
/**
+ * The rewritten range query or <code>null</code> if the range spans more
+ * than {@link org.apache.lucene.search.BooleanQuery#maxClauseCount} terms.
+ */
+ private Query stdRangeQuery;
+
+ /**
* Creates a new RangeQuery. The lower or the upper term may be
* <code>null</code>, but not both!
*
@@ -113,8 +129,9 @@
}
/**
- * Rewrites this query into a {@link ConstantScoreRangeQuery} if
- * {@link #transform} is {@link #TRANSFORM_NONE}.
+ * Tries to rewrite this query into a standard lucene RangeQuery.
+ * This rewrite might fail with a TooManyClauses exception. If that
+ * happens, we use our own implementation.
*
* @param reader the index reader.
* @return the rewritten query or this query if rewriting is not possible.
@@ -122,9 +139,16 @@
*/
public Query rewrite(IndexReader reader) throws IOException {
if (transform == TRANSFORM_NONE) {
- return new ConstantScoreRangeQuery(lowerTerm.field(),
- lowerTerm.text(), upperTerm.text(), inclusive,
- inclusive).rewrite(reader);
+ Query stdRangeQueryImpl
+ = new org.apache.lucene.search.RangeQuery(lowerTerm, upperTerm, inclusive);
+ try {
+ stdRangeQuery = stdRangeQueryImpl.rewrite(reader);
+ return stdRangeQuery;
+ } catch (BooleanQuery.TooManyClauses e) {
+ log.debug("Too many terms to enumerate, using custom RangeQuery");
+ // failed, use own implementation
+ return this;
+ }
} else {
// always use our implementation when we need to transform the
// term enum
@@ -169,7 +193,9 @@
* {@inheritDoc}
*/
public void extractTerms(Set terms) {
- // cannot extract terms
+ if (stdRangeQuery != null) {
+ stdRangeQuery.extractTerms(terms);
+ }
}
/**
Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SearchIndex.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SearchIndex.java?rev=884108&r1=884107&r2=884108&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SearchIndex.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SearchIndex.java Wed Nov 25 14:04:38 2009
@@ -170,11 +170,6 @@
public static final int DEFAULT_TERM_INFOS_INDEX_DIVISOR = 1;
/**
- * The default value for {@link #indexMergerPoolSize}.
- */
- public static final int DEFAULT_INDEX_MERGER_POOL_SIZE = 2;
-
- /**
* The path factory.
*/
protected static final PathFactory PATH_FACTORY = PathFactoryImpl.getInstance();
@@ -447,11 +442,6 @@
private boolean initializeHierarchyCache = true;
/**
- * The number of worker threads for merging index segments.
- */
- private int indexMergerPoolSize = DEFAULT_INDEX_MERGER_POOL_SIZE;
-
- /**
* The name of the redo log factory class implementation.
*/
private String redoLogFactoryClass = DefaultRedoLogFactory.class.getName();
@@ -1103,7 +1093,7 @@
indexer.setIndexingConfiguration(indexingConfig);
indexer.setIndexFormatVersion(indexFormatVersion);
Document doc = indexer.createDoc();
- mergeAggregatedNodeIndexes(node, doc);
+ mergeAggregatedNodeIndexes(node, doc, indexFormatVersion);
return doc;
}
@@ -1321,8 +1311,11 @@
*
* @param state the node state on which <code>doc</code> was created.
* @param doc the lucene document with index fields from <code>state</code>.
+ * @param ifv the current index format version.
*/
- protected void mergeAggregatedNodeIndexes(NodeState state, Document doc) {
+ protected void mergeAggregatedNodeIndexes(NodeState state,
+ Document doc,
+ IndexFormatVersion ifv) {
if (indexingConfig != null) {
AggregateRule[] aggregateRules = indexingConfig.getAggregateRules();
if (aggregateRules == null) {
@@ -1337,7 +1330,7 @@
if (aggregates != null) {
ruleMatched = true;
for (NodeState aggregate : aggregates) {
- Document aDoc = createDocument(aggregate, getNamespaceMappings(), index.getIndexFormatVersion());
+ Document aDoc = createDocument(aggregate, getNamespaceMappings(), ifv);
// transfer fields to doc if there are any
Fieldable[] fulltextFields = aDoc.getFieldables(FieldNames.FULLTEXT);
if (fulltextFields != null) {
@@ -1355,7 +1348,7 @@
for (PropertyState propState : propStates) {
String namePrefix = FieldNames.createNamedValue(getNamespaceMappings().translateName(propState.getName()), "");
NodeState parent = (NodeState) ism.getItemState(propState.getParentId());
- Document aDoc = createDocument(parent, getNamespaceMappings(), getIndex().getIndexFormatVersion());
+ Document aDoc = createDocument(parent, getNamespaceMappings(), ifv);
try {
// find the right fields to transfer
Fieldable[] fields = aDoc.getFieldables(FieldNames.PROPERTIES);
@@ -2224,26 +2217,6 @@
}
/**
- * @return the current size of the index merger pool.
- */
- public int getIndexMergerPoolSize() {
- return indexMergerPoolSize;
- }
-
- /**
- * Sets a new value for the index merger pool size.
- *
- * @param indexMergerPoolSize the number of worker threads.
- * @throws IllegalArgumentException if the size is less than or equal 0.
- */
- public void setIndexMergerPoolSize(int indexMergerPoolSize) {
- if (indexMergerPoolSize <= 0) {
- throw new IllegalArgumentException("must be greater than 0");
- }
- this.indexMergerPoolSize = indexMergerPoolSize;
- }
-
- /**
* @return the maximum age in seconds for outdated generations of
* {@link IndexInfos}.
*/
Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SortedLuceneQueryHits.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SortedLuceneQueryHits.java?rev=884108&r1=884107&r2=884108&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SortedLuceneQueryHits.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SortedLuceneQueryHits.java Wed Nov 25 14:04:38 2009
@@ -16,18 +16,18 @@
*/
package org.apache.jackrabbit.core.query.lucene;
-import org.apache.lucene.search.Sort;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.jackrabbit.core.id.NodeId;
+import org.apache.lucene.index.IndexReader;
import org.apache.lucene.search.Query;
-import org.apache.lucene.search.TopFieldDocCollector;
import org.apache.lucene.search.ScoreDoc;
-import org.apache.lucene.index.IndexReader;
-import org.apache.jackrabbit.core.id.NodeId;
-import org.slf4j.LoggerFactory;
+import org.apache.lucene.search.Sort;
+import org.apache.lucene.search.TopFieldDocCollector;
import org.slf4j.Logger;
-
-import java.io.IOException;
-import java.util.List;
-import java.util.ArrayList;
+import org.slf4j.LoggerFactory;
/**
* Wraps a lucene query result and adds a close method that allows to release
@@ -77,9 +77,9 @@
private int hitIndex = -1;
/**
- * The score nodes.
+ * The score docs.
*/
- private final List<ScoreNode> scoreNodes = new ArrayList<ScoreNode>();
+ private final List<ScoreDoc> scoreDocs = new ArrayList<ScoreDoc>();
/**
* The total number of hits.
@@ -130,12 +130,16 @@
if (++hitIndex >= size) {
// no more score nodes
return null;
- } else if (hitIndex >= scoreNodes.size()) {
+ } else if (hitIndex >= scoreDocs.size()) {
// refill at least numHits or twice hitIndex
this.numHits = Math.max(this.numHits, hitIndex * 2);
getHits();
}
- return scoreNodes.get(hitIndex);
+ ScoreDoc doc = scoreDocs.get(hitIndex);
+ String uuid = reader.document(doc.doc,
+ FieldSelectors.UUID).get(FieldNames.UUID);
+ NodeId id = new NodeId(uuid);
+ return new ScoreNode(id, doc.score, doc.doc);
}
/**
@@ -155,12 +159,10 @@
searcher.search(query, collector);
this.size = collector.getTotalHits();
ScoreDoc[] docs = collector.topDocs().scoreDocs;
- for (int i = scoreNodes.size(); i < docs.length; i++) {
- String uuid = reader.document(docs[i].doc).get(FieldNames.UUID);
- NodeId id = new NodeId(uuid);
- scoreNodes.add(new ScoreNode(id, docs[i].score, docs[i].doc));
+ for (int i = scoreDocs.size(); i < docs.length; i++) {
+ scoreDocs.add(docs[i]);
}
- log.debug("getHits() {}/{}", scoreNodes.size(), numHits);
+ log.debug("getHits() {}/{}", scoreDocs.size(), numHits);
// double hits for next round
numHits *= 2;
}
Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/directory/FSDirectoryManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/directory/FSDirectoryManager.java?rev=884108&r1=884107&r2=884108&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/directory/FSDirectoryManager.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/directory/FSDirectoryManager.java Wed Nov 25 14:04:38 2009
@@ -16,18 +16,19 @@
*/
package org.apache.jackrabbit.core.query.lucene.directory;
+import java.io.File;
+import java.io.FileFilter;
+import java.io.IOException;
+
+import org.apache.jackrabbit.core.query.lucene.IOCounters;
+import org.apache.jackrabbit.core.query.lucene.SearchIndex;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
-import org.apache.lucene.store.NativeFSLockFactory;
-import org.apache.lucene.store.IndexOutput;
import org.apache.lucene.store.IndexInput;
+import org.apache.lucene.store.IndexOutput;
import org.apache.lucene.store.Lock;
import org.apache.lucene.store.LockFactory;
-import org.apache.jackrabbit.core.query.lucene.SearchIndex;
-
-import java.io.IOException;
-import java.io.File;
-import java.io.FileFilter;
+import org.apache.lucene.store.NativeFSLockFactory;
/**
* <code>FSDirectoryManager</code> implements a directory manager for
@@ -185,7 +186,8 @@
}
public IndexInput openInput(String name) throws IOException {
- return directory.openInput(name);
+ IndexInput in = directory.openInput(name);
+ return new IndexInputLogWrapper(in);
}
public void close() throws IOException {
@@ -194,7 +196,8 @@
public IndexInput openInput(String name, int bufferSize)
throws IOException {
- return directory.openInput(name, bufferSize);
+ IndexInput in = directory.openInput(name, bufferSize);
+ return new IndexInputLogWrapper(in);
}
public Lock makeLock(String name) {
@@ -221,4 +224,49 @@
return this.getClass().getName() + "@" + directory;
}
}
+
+ /**
+ * Implements an index input wrapper that logs the number of time bytes
+ * are read from storage.
+ */
+ private static final class IndexInputLogWrapper extends IndexInput {
+
+ private IndexInput in;
+
+ IndexInputLogWrapper(IndexInput in) {
+ this.in = in;
+ }
+
+ public byte readByte() throws IOException {
+ return in.readByte();
+ }
+
+ public void readBytes(byte[] b, int offset, int len) throws IOException {
+ IOCounters.incrRead();
+ in.readBytes(b, offset, len);
+ }
+
+ public void close() throws IOException {
+ in.close();
+ }
+
+ public long getFilePointer() {
+ return in.getFilePointer();
+ }
+
+ public void seek(long pos) throws IOException {
+ in.seek(pos);
+ }
+
+ public long length() {
+ return in.length();
+ }
+
+ @Override
+ public Object clone() {
+ IndexInputLogWrapper clone = (IndexInputLogWrapper) super.clone();
+ clone.in = (IndexInput) in.clone();
+ return clone;
+ }
+ }
}
Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/retention/RetentionRegistryImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/retention/RetentionRegistryImpl.java?rev=884108&r1=884107&r2=884108&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/retention/RetentionRegistryImpl.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/retention/RetentionRegistryImpl.java Wed Nov 25 14:04:38 2009
@@ -82,13 +82,14 @@
// start listening to added/changed or removed holds and retention policies.
Workspace wsp = session.getWorkspace();
- // register eventlistener to be informed about new/removed holds and retention plcs.
+ // register event listener to be informed about new/removed holds and
+ // retention policies.
int types = Event.PROPERTY_ADDED | Event.PROPERTY_REMOVED | Event.PROPERTY_CHANGED;
String[] ntFilter = new String[] {session.getJCRName(RetentionManagerImpl.REP_RETENTION_MANAGEABLE)};
wsp.getObservationManager().addEventListener(this, types, "/", true, null, ntFilter, false);
// populate the retentionMap and the holdMap with the effective
- // holds and retention plcs present within the content.
+ // holds and retention policies present within the content.
try {
readRetentionFile();
} catch (FileSystemException e) {
@@ -253,7 +254,7 @@
return true;
} else if (checkParent && !nodePath.denotesRoot() &&
element.hasPath(nodePath.getAncestor(1))) {
- // hold present on the parent node whithout checking for being
+ // hold present on the parent node without checking for being
// a deep hold.
// this required for removal of a node that can be inhibited
// by a hold on the node itself, by a hold on the parent or
Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/JackrabbitSecurityManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/JackrabbitSecurityManager.java?rev=884108&r1=884107&r2=884108&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/JackrabbitSecurityManager.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/JackrabbitSecurityManager.java Wed Nov 25 14:04:38 2009
@@ -52,11 +52,12 @@
*
* @param creds
* @param subject
+ * @param workspaceName The name of the workspace to login.
* @return A new <code>AuthContext</code> for the given <code>creds</code>
* and <code>subject</code>.
* @throws RepositoryException
*/
- AuthContext getAuthContext(Credentials creds, Subject subject) throws RepositoryException;
+ AuthContext getAuthContext(Credentials creds, Subject subject, String workspaceName) throws RepositoryException;
/**
* Retrieve the <code>AccessManager</code> for the given <code>session</code>.
@@ -95,8 +96,9 @@
* the specified subject.
*
* @param subject
+ * @param workspaceName
* @return userID to be displayed upon {@link Session#getUserID()}.
* @throws RepositoryException
*/
- String getUserID(Subject subject) throws RepositoryException;
+ String getUserID(Subject subject, String workspaceName) throws RepositoryException;
}
Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/SimpleJBossAccessManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/SimpleJBossAccessManager.java?rev=884108&r1=884107&r2=884108&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/SimpleJBossAccessManager.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/SimpleJBossAccessManager.java Wed Nov 25 14:04:38 2009
@@ -109,7 +109,7 @@
public boolean isGranted(ItemId id, int permissions) throws RepositoryException {
// system has always all permissions
- // anonymous has only READ premissions
+ // anonymous has only READ permissions
return system || (anonymous && ((permissions & (WRITE | REMOVE)) == 0));
}
@@ -131,7 +131,7 @@
private boolean internalIsGranted(int permissions) {
/* system has always all permissions,
- anonymous has only READ premissions */
+ anonymous has only READ permissions */
return system || (anonymous && Permission.READ == permissions);
}
}
Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/AbstractLoginModule.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/AbstractLoginModule.java?rev=884108&r1=884107&r2=884108&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/AbstractLoginModule.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/AbstractLoginModule.java Wed Nov 25 14:04:38 2009
@@ -86,7 +86,7 @@
* credentials should be taken as is and the user requesting access
* has already been authenticated outside of this LoginModule.
*
- * @see #getTrustedCredentialsAttributeName()
+ * @see #getPreAuthAttributeName()
*/
private String preAuthAttributeName;
@@ -247,7 +247,7 @@
* If the option is missing, the system default prinvipal provider will
* be used.<p/>
*
- * <b>3) Verfication</b><br>
+ * <b>3) Verification</b><br>
* There are four cases, how the User-ID can be verfied:
* The login is anonymous, preauthenticated or the login is the result of
* an impersonation request (see {@link javax.jcr.Session#impersonate(Credentials)}
@@ -410,8 +410,8 @@
* @see javax.security.auth.spi.LoginModule#logout()
*/
public boolean logout() throws LoginException {
- Set thisPrincipals = subject.getPrincipals();
- Set thisCredentials = subject.getPublicCredentials(SimpleCredentials.class);
+ Set<Principal> thisPrincipals = subject.getPrincipals();
+ Set<SimpleCredentials> thisCredentials = subject.getPublicCredentials(SimpleCredentials.class);
if (thisPrincipals == null || thisCredentials == null
|| thisPrincipals.isEmpty() || thisCredentials.isEmpty()) {
return false;
@@ -758,7 +758,7 @@
* <p>
* This base class implementation returns <code>true</code> if the
* <code>creds</code> object is a SimpleCredentials instance and the
- * configured {@link #getTrustedCredentialsAttributeName() trusted
+ * configured {@link #getPreAuthAttributeName() trusted
* credentials property} is set to a non-<code>null</code> value in the
* credentials attributes.
* <p>
Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/AuthContextProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/AuthContextProvider.java?rev=884108&r1=884107&r2=884108&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/AuthContextProvider.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/AuthContextProvider.java Wed Nov 25 14:04:38 2009
@@ -32,18 +32,11 @@
import java.util.Properties;
/**
- * A AuthContextProvider selects how the current request for login is handled.
- * It selects the mechanism and set-up according configuration.<br>
- * The handler selects if the JAAS-configuration
- * {@link javax.security.auth.login.Configuration} is taken or the fall-back as
- * configured via {@link org.apache.jackrabbit.core.config.RepositoryConfig}.<p>
- * This implementaion selects JAAS under the following condition:
- * <ul>
- * <li>a JAAS Login-{@link javax.security.auth.login.Configuration} is available
- * <li>the configuration contains the configured application name
- * </ul>
- * If the conditions are not met <b>AND</b> a LoginModule is configured in
- * {@link org.apache.jackrabbit.core.config.RepositoryConfig}, that one is taken.
+ * <code>AuthContextProvider</code> defines how the current request for login is
+ * handled. By default the {@link org.apache.jackrabbit.core.config.RepositoryConfig
+ * local repository configuration} takes precedence over JAAS configuration.
+ * If no local configuration is present a JAAS configuration must be provided
+ * otherwise {@link #getAuthContext} fails with <code>RepositoryException</code>.
*/
public class AuthContextProvider {
Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/CryptedSimpleCredentials.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/CryptedSimpleCredentials.java?rev=884108&r1=884107&r2=884108&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/CryptedSimpleCredentials.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authentication/CryptedSimpleCredentials.java Wed Nov 25 14:04:38 2009
@@ -113,9 +113,8 @@
}
/**
- * Compair this instance with an instance of SimpleCredentials.
- * If one the other Credentials' Password is plain-text treies to encode
- * it with the current Digest.
+ * Compares this instance with the given <code>SimpleCredentials</code> and
+ * returns <code>true</code> if both match.
*
* @param credentials
* @return true if {@link SimpleCredentials#getUserID() UserID} and
@@ -126,7 +125,7 @@
public boolean matches(SimpleCredentials credentials)
throws NoSuchAlgorithmException, UnsupportedEncodingException {
- if (getUserID().matches(credentials.getUserID())) {
+ if (getUserID().equalsIgnoreCase(credentials.getUserID())) {
String toMatch = new String(credentials.getPassword());
String algr = getAlgorithm(toMatch);
@@ -148,7 +147,7 @@
private static String crypt(String pwd, String algorithm)
throws NoSuchAlgorithmException, UnsupportedEncodingException {
- StringBuffer password = new StringBuffer();
+ StringBuilder password = new StringBuilder();
password.append("{").append(algorithm).append("}");
password.append(Text.digest(algorithm, pwd.getBytes("UTF-8")));
return password.toString();
Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AbstractACLTemplate.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AbstractACLTemplate.java?rev=884108&r1=884107&r2=884108&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AbstractACLTemplate.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AbstractACLTemplate.java Wed Nov 25 14:04:38 2009
@@ -19,14 +19,19 @@
import java.security.Principal;
import java.util.Collections;
import java.util.Map;
+import java.util.List;
import javax.jcr.RepositoryException;
import javax.jcr.Value;
import javax.jcr.ValueFactory;
+import javax.jcr.UnsupportedRepositoryOperationException;
import javax.jcr.security.AccessControlException;
import javax.jcr.security.Privilege;
+import javax.jcr.security.AccessControlEntry;
import org.apache.jackrabbit.api.security.JackrabbitAccessControlList;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* <code>AbstractACLTemplate</code>...
@@ -34,6 +39,8 @@
public abstract class AbstractACLTemplate implements JackrabbitAccessControlList,
AccessControlConstants {
+ private static Logger log = LoggerFactory.getLogger(AbstractACLTemplate.class);
+
/**
* Path of the node this ACL template has been created for.
*/
@@ -65,6 +72,17 @@
boolean isAllow,
Map<String, Value> restrictions) throws AccessControlException;
+ /**
+ * Return the list of entries, if they are held in a orderable list.
+ *
+ * @return the list of entries.
+ * @throws UnsupportedRepositoryOperationException If the implementation
+ * does not held the entries in a list.
+ * @throws RepositoryException
+ * @see #orderBefore(AccessControlEntry, AccessControlEntry)
+ */
+ protected abstract List<? extends AccessControlEntry> getEntries() throws UnsupportedRepositoryOperationException, RepositoryException;
+
//--------------------------------------< JackrabbitAccessControlPolicy >---
/**
* @see org.apache.jackrabbit.api.security.JackrabbitAccessControlPolicy#getPath()
@@ -82,6 +100,34 @@
return addEntry(principal, privileges, isAllow, Collections.<String, Value>emptyMap());
}
+ /**
+ *
+ * @param srcEntry The access control entry to be moved within the list.
+ * @param destEntry The entry before which the <code>srcEntry</code> will be moved.
+ * @throws AccessControlException
+ * @throws UnsupportedRepositoryOperationException
+ * @throws RepositoryException
+ */
+ public void orderBefore(AccessControlEntry srcEntry, AccessControlEntry destEntry) throws AccessControlException, UnsupportedRepositoryOperationException, RepositoryException {
+ if (srcEntry.equals(destEntry)) {
+ log.debug("srcEntry equals destEntry -> no reordering required.");
+ return;
+ }
+
+ List entries = getEntries();
+ int index = (destEntry == null) ? entries.size()-1 : entries.indexOf(destEntry);
+ if (index < 0) {
+ throw new AccessControlException("destEntry not contained in this AccessControlList");
+ } else {
+ if (entries.remove(srcEntry)) {
+ // re-insert the srcEntry at the new position.
+ entries.add(index, srcEntry);
+ } else {
+ // src entry not contained in this list.
+ throw new AccessControlException("srcEntry not contained in this AccessControlList");
+ }
+ }
+ }
//--------------------------------------------------< AccessControlList >---
/**
Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AccessControlProviderFactoryImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AccessControlProviderFactoryImpl.java?rev=884108&r1=884107&r2=884108&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AccessControlProviderFactoryImpl.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/AccessControlProviderFactoryImpl.java Wed Nov 25 14:04:38 2009
@@ -74,7 +74,7 @@
Map props;
if (config != null && config.getAccessControlProviderConfig() != null) {
BeanConfig bc = config.getAccessControlProviderConfig();
- prov = (AccessControlProvider) bc.newInstance();
+ prov = bc.newInstance(AccessControlProvider.class);
props = bc.getParameters();
} else {
log.debug("No ac-provider configuration for workspace " + workspaceName + " -> using defaults.");
@@ -87,7 +87,7 @@
prov = new ACLProvider();
}
log.debug("Default provider for workspace " + workspaceName + " = " + prov.getClass().getName());
- props = Collections.EMPTY_MAP;
+ props = Collections.emptyMap();
}
prov.init(systemSession, props);
Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/UnmodifiableAccessControlList.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/UnmodifiableAccessControlList.java?rev=884108&r1=884107&r2=884108&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/UnmodifiableAccessControlList.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/UnmodifiableAccessControlList.java Wed Nov 25 14:04:38 2009
@@ -130,12 +130,16 @@
return accessControlEntries.length;
}
- public boolean addEntry(Principal principal, Privilege[] privileges, boolean isAllow) throws AccessControlException, RepositoryException {
- throw new AccessControlException("Unmodifiable ACL. Use AccessControlManager#getApplicablePolicies in order to obtain an modifiable ACL.");
+ public boolean addEntry(Principal principal, Privilege[] privileges, boolean isAllow) throws AccessControlException {
+ throw new AccessControlException("Unmodifiable ACL. Use AccessControlManager#getPolicy or #getApplicablePolicies in order to obtain an modifiable ACL.");
}
- public boolean addEntry(Principal principal, Privilege[] privileges, boolean isAllow, Map<String, Value> restrictions) throws AccessControlException, RepositoryException {
- throw new AccessControlException("Unmodifiable ACL. Use AccessControlManager#getApplicablePolicies in order to obtain an modifiable ACL.");
+ public boolean addEntry(Principal principal, Privilege[] privileges, boolean isAllow, Map<String, Value> restrictions) throws AccessControlException {
+ throw new AccessControlException("Unmodifiable ACL. Use AccessControlManager#getPolicy or #getApplicablePolicies in order to obtain an modifiable ACL.");
+ }
+
+ public void orderBefore(AccessControlEntry srcEntry, AccessControlEntry destEntry) throws AccessControlException {
+ throw new AccessControlException("Unmodifiable ACL. Use AccessControlManager#getPolicy or #getApplicablePolicy in order to obtain a modifiable ACL.");
}
public String getPath() {
Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/WorkspaceAccessManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/WorkspaceAccessManager.java?rev=884108&r1=884107&r2=884108&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/WorkspaceAccessManager.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/WorkspaceAccessManager.java Wed Nov 25 14:04:38 2009
@@ -31,10 +31,10 @@
/**
* Initialize this <code>WorkspaceAccessManager</code>.
*
- * @param securitySession The security session.
+ * @param systemSession Session used to initialize this instance.
* @throws RepositoryException if an error occurs.
*/
- void init(Session securitySession) throws RepositoryException;
+ void init(Session systemSession) throws RepositoryException;
/**
* Dispose this <code>WorkspaceAccessManager</code> and its resources.
Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/ACLProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/ACLProvider.java?rev=884108&r1=884107&r2=884108&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/ACLProvider.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/ACLProvider.java Wed Nov 25 14:04:38 2009
@@ -17,14 +17,15 @@
package org.apache.jackrabbit.core.security.authorization.acl;
import java.security.Principal;
+import java.security.acl.Group;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
-import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.Iterator;
import javax.jcr.ItemNotFoundException;
import javax.jcr.NodeIterator;
@@ -33,8 +34,6 @@
import javax.jcr.Value;
import javax.jcr.observation.Event;
import javax.jcr.observation.EventIterator;
-import javax.jcr.query.Query;
-import javax.jcr.query.QueryManager;
import javax.jcr.security.AccessControlEntry;
import javax.jcr.security.AccessControlList;
import javax.jcr.security.AccessControlManager;
@@ -53,15 +52,14 @@
import org.apache.jackrabbit.core.security.authorization.AbstractCompiledPermissions;
import org.apache.jackrabbit.core.security.authorization.AccessControlConstants;
import org.apache.jackrabbit.core.security.authorization.AccessControlEditor;
-import org.apache.jackrabbit.core.security.authorization.AccessControlEntryIterator;
import org.apache.jackrabbit.core.security.authorization.CompiledPermissions;
import org.apache.jackrabbit.core.security.authorization.Permission;
import org.apache.jackrabbit.core.security.authorization.PrivilegeRegistry;
import org.apache.jackrabbit.core.security.authorization.UnmodifiableAccessControlList;
-import org.apache.jackrabbit.core.security.principal.PrincipalImpl;
import org.apache.jackrabbit.spi.Path;
import org.apache.jackrabbit.spi.commons.name.PathFactoryImpl;
import org.apache.jackrabbit.util.Text;
+import org.apache.commons.collections.iterators.IteratorChain;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -103,15 +101,9 @@
*/
private NodeId rootNodeId;
- /**
- * Flag indicating whether or not this provider should be create the default
- * ACLs upon initialization.
- */
- private boolean initializedWithDefaults;
-
//-------------------------------------------------< AccessControlUtils >---
/**
- * @see AbstractAccessControlProvider#isAcItem(Path)
+ * @see org.apache.jackrabbit.core.security.authorization.AccessControlUtils#isAcItem(Path)
*/
public boolean isAcItem(Path absPath) throws RepositoryException {
Path.Element[] elems = absPath.getElements();
@@ -125,7 +117,7 @@
/**
* Test if the given node is itself a rep:ACL or a rep:ACE node.
- * @see AbstractAccessControlProvider#isAcItem(ItemImpl)
+ * @see org.apache.jackrabbit.core.security.authorization.AccessControlUtils#isAcItem(ItemImpl)
*/
public boolean isAcItem(ItemImpl item) throws RepositoryException {
NodeImpl n = ((item.isNode()) ? (NodeImpl) item : (NodeImpl) item.getParent());
@@ -136,6 +128,7 @@
/**
* @see org.apache.jackrabbit.core.security.authorization.AccessControlProvider#init(Session, Map)
*/
+ @Override
public void init(Session systemSession, Map configuration) throws RepositoryException {
super.init(systemSession, configuration);
@@ -144,7 +137,8 @@
NodeImpl root = (NodeImpl) session.getRootNode();
rootNodeId = root.getNodeId();
systemEditor = new ACLEditor(systemSession, this);
- initializedWithDefaults = !configuration.containsKey(PARAM_OMIT_DEFAULT_PERMISSIONS);
+ // TODO: replace by configurable default policy (see JCR-2331)
+ boolean initializedWithDefaults = !configuration.containsKey(PARAM_OMIT_DEFAULT_PERMISSIONS);
if (initializedWithDefaults && !isAccessControlled(root)) {
initRootACL(session, systemEditor);
}
@@ -208,8 +202,21 @@
}
}
- //------------------------------------------------------------< private >---
+ //----------------------------------------------------------< protected >---
+ /**
+ * Retrieve an iterator of <code>AccessControlEntry</code> to be evaluated
+ * upon {@link AbstractCompiledPermissions#buildResult}.
+ *
+ * @param node Target node.
+ * @param principalNames List of principal names.
+ * @return an iterator of <code>AccessControlEntry</code>.
+ * @throws RepositoryException If an error occurs.
+ */
+ protected Iterator<AccessControlEntry> retrieveResultEntries(NodeImpl node, List<String> principalNames) throws RepositoryException {
+ return new Entries(node, principalNames).iterator();
+ }
+ //------------------------------------------------------------< private >---
/**
* Returns the given <code>targetNode</code> unless the node itself stores
* access control information in which case it's nearest non-ac-parent is
@@ -280,27 +287,25 @@
PrincipalManager pMgr = session.getPrincipalManager();
AccessControlManager acMgr = session.getAccessControlManager();
- log.debug("... Privilege.ALL for administrators.");
- Principal administrators;
String pName = SecurityConstants.ADMINISTRATORS_NAME;
if (pMgr.hasPrincipal(pName)) {
- administrators = pMgr.getPrincipal(pName);
+ Principal administrators = pMgr.getPrincipal(pName);
+ log.debug("... Privilege.ALL for administrators.");
+ Privilege[] privs = new Privilege[]{acMgr.privilegeFromName(Privilege.JCR_ALL)};
+ acl.addAccessControlEntry(administrators, privs);
} else {
- log.warn("Administrators principal group is missing.");
- administrators = new PrincipalImpl(pName);
+ log.info("Administrators principal group is missing -> omitting initialization of default permissions.");
}
- Privilege[] privs = new Privilege[]{acMgr.privilegeFromName(Privilege.JCR_ALL)};
- acl.addAccessControlEntry(administrators, privs);
Principal everyone = pMgr.getEveryone();
log.debug("... Privilege.READ for everyone.");
- privs = new Privilege[]{acMgr.privilegeFromName(Privilege.JCR_READ)};
+ Privilege[] privs = new Privilege[]{acMgr.privilegeFromName(Privilege.JCR_READ)};
acl.addAccessControlEntry(everyone, privs);
editor.setPolicy(rootPath, acl);
session.save();
} else {
- log.warn("No applicable ACL available for the root node -> skip initialization of the root node's ACL.");
+ log.info("No applicable ACL available for the root node -> skip initialization of the root node's ACL.");
}
} catch (RepositoryException e) {
log.error("Failed to set-up minimal access control for root node of workspace " + session.getWorkspace().getName());
@@ -331,13 +336,6 @@
private class AclPermissions extends AbstractCompiledPermissions implements SynchronousEventListener {
private final List<String> principalNames;
- private final String jcrReadPrivilegeName;
-
- /**
- * flag indicating that there is not 'deny READ'.
- * -> simplify {@link #grants(Path, int)} in case of permissions == READ
- */
- private boolean readAllowed;
private AclPermissions(Set<Principal> principals) throws RepositoryException {
this(principals, true);
@@ -348,17 +346,9 @@
for (Principal princ : principals) {
principalNames.add(princ.getName());
}
- jcrReadPrivilegeName = session.getAccessControlManager().privilegeFromName(Privilege.JCR_READ).getName();
if (listenToEvents) {
/*
- Determine if there is any 'denyRead' entry (since the default
- is that everyone can READ everywhere -> makes evaluation for
- the most common check (can-read) easy.
- */
- readAllowed = isReadAllowed(principalNames);
-
- /*
Make sure this AclPermission recalculates the permissions if
any ACL concerning it is modified. interesting events are:
- new ACE-entry for any of the principals (NODE_ADDED)
@@ -376,56 +366,11 @@
}
}
- /**
- * If this provider defines read-permission for everyone (defined upon
- * init with default values), search if there is any ACE that defines
- * permissions for any of the principals AND denies-READ. Otherwise
- * this shortcut is not possible.
- *
- * @param principalnames names of the principals
- * @return true if read is allowed everywhere.
- */
- private boolean isReadAllowed(Collection<String> principalnames) {
- boolean isReadAllowed = false;
- if (initializedWithDefaults) {
- try {
- QueryManager qm = session.getWorkspace().getQueryManager();
- StringBuffer stmt = new StringBuffer("/jcr:root");
- stmt.append("//element(*,");
- stmt.append(resolver.getJCRName(NT_REP_DENY_ACE));
- stmt.append(")[(");
-
- // where the rep:principalName property exactly matches any of
- // the given principalsNames
- int i = 0;
- for (String principalname : principalnames) {
- stmt.append("@").append(resolver.getJCRName(P_PRINCIPAL_NAME)).append(" eq ");
- stmt.append("'").append(principalname).append("'");
- if (++i < principalnames.size()) {
- stmt.append(" or ");
- }
- }
- // AND rep:privileges contains the READ privilege
- stmt.append(") and @");
- stmt.append(resolver.getJCRName(P_PRIVILEGES));
- stmt.append(" = '").append(jcrReadPrivilegeName).append("']");
-
- Query q = qm.createQuery(stmt.toString(), Query.XPATH);
-
- NodeIterator it = q.execute().getNodes();
- isReadAllowed = !it.hasNext();
- } catch (RepositoryException e) {
- log.error(e.toString());
- // unable to determine... -> no shortcut upon grants
- }
- }
- return isReadAllowed;
- }
-
//------------------------------------< AbstractCompiledPermissions >---
/**
* @see AbstractCompiledPermissions#buildResult(Path)
*/
+ @Override
protected Result buildResult(Path absPath) throws RepositoryException {
boolean existingNode = false;
NodeImpl node = null;
@@ -456,14 +401,14 @@
// retrieve all ACEs at path or at the direct ancestor of path that
// apply for the principal names.
- AccessControlEntryIterator entries = new Entries(getNode(node), principalNames).iterator();
+ Iterator<AccessControlEntry> entries = retrieveResultEntries(getNode(node), principalNames);
// build a list of ACEs that are defined locally at the node
- List localACEs;
+ List<AccessControlEntry> localACEs;
if (existingNode && isAccessControlled(node)) {
NodeImpl aclNode = node.getNode(N_POLICY);
localACEs = Arrays.asList(systemEditor.getACL(aclNode).getAccessControlEntries());
} else {
- localACEs = Collections.EMPTY_LIST;
+ localACEs = Collections.emptyList();
}
/*
Calculate privileges and permissions:
@@ -520,22 +465,6 @@
super.close();
}
- /**
- *
- * @param absPath absolute path
- * @param permissions permission bits
- * @return <code>true</code> if the permissions are granted
- * @throws RepositoryException
- * @see CompiledPermissions#grants(Path, int)
- */
- public boolean grants(Path absPath, int permissions) throws RepositoryException {
- if (permissions == Permission.READ && readAllowed && !isAcItem(absPath)) {
- return true;
- } else {
- return super.grants(absPath, permissions);
- }
- }
-
//--------------------------------------------------< EventListener >---
/**
* @see javax.jcr.observation.EventListener#onEvent(EventIterator)
@@ -556,16 +485,6 @@
NodeImpl n = (NodeImpl) session.getNode(path);
if (n.isNodeType(NT_REP_ACE) &&
principalNames.contains(n.getProperty(P_PRINCIPAL_NAME).getString())) {
- // and reset the readAllowed flag, if the new
- // ACE denies READ.
- if (readAllowed && n.isNodeType(NT_REP_DENY_ACE)) {
- Value[] vs = n.getProperty(P_PRIVILEGES).getValues();
- for (Value v : vs) {
- if (jcrReadPrivilegeName.equals(v.getString())) {
- readAllowed = false;
- }
- }
- }
clearCache = true;
}
break;
@@ -573,7 +492,6 @@
case Event.NODE_REMOVED:
// can't find out if the removed ACL/ACE node was
// relevant for the principals
- readAllowed = isReadAllowed(principalNames);
clearCache = true;
break;
case Event.PROPERTY_ADDED:
@@ -594,7 +512,6 @@
}
if (principalName != null &&
principalNames.contains(principalName)) {
- readAllowed = isReadAllowed(principalNames);
clearCache = true;
}
}
@@ -624,13 +541,12 @@
*/
private class Entries {
- private final Map<String, List<AccessControlEntry>> principalNamesToEntries;
+ private final Collection<String> principalNames;
+ private final List<AccessControlEntry> userAces = new ArrayList();
+ private final List<AccessControlEntry> groupAces = new ArrayList();
private Entries(NodeImpl node, Collection<String> principalNames) throws RepositoryException {
- principalNamesToEntries = new LinkedHashMap<String, List<AccessControlEntry>>();
- for (String name : principalNames) {
- principalNamesToEntries.put(name, new ArrayList<AccessControlEntry>());
- }
+ this.principalNames = principalNames;
collectEntries(node);
}
@@ -640,22 +556,80 @@
if (isAccessControlled(node)) {
// build acl for the access controlled node
NodeImpl aclNode = node.getNode(N_POLICY);
- ACLTemplate.collectEntries(aclNode, principalNamesToEntries);
+ //collectEntries(aclNode, principalNamesToEntries);
+ collectEntriesFromAcl(aclNode);
}
- // then, recursively look for access controlled parents up the hierarchy.
+ // recursively look for access controlled parents up the hierarchy.
if (!rootNodeId.equals(node.getId())) {
NodeImpl parentNode = (NodeImpl) node.getParent();
collectEntries(parentNode);
}
}
- private AccessControlEntryIterator iterator() {
- List<AccessControlEntry> entries = new ArrayList<AccessControlEntry>();
- for (List<AccessControlEntry> list: principalNamesToEntries.values()) {
- entries.addAll(list);
+ /**
+ * Separately collect the entries defined for the user and group
+ * principals.
+ *
+ * @param aclNode acl node
+ * @throws RepositoryException if an error occurs
+ */
+ private void collectEntriesFromAcl(NodeImpl aclNode) throws RepositoryException {
+ SessionImpl sImpl = (SessionImpl) aclNode.getSession();
+ PrincipalManager principalMgr = sImpl.getPrincipalManager();
+ AccessControlManager acMgr = sImpl.getAccessControlManager();
+
+ // first collect aces present on the given aclNode.
+ List<AccessControlEntry> gaces = new ArrayList<AccessControlEntry>();
+ List<AccessControlEntry> uaces = new ArrayList<AccessControlEntry>();
+
+ NodeIterator itr = aclNode.getNodes();
+ while (itr.hasNext()) {
+ NodeImpl aceNode = (NodeImpl) itr.nextNode();
+ String principalName = aceNode.getProperty(AccessControlConstants.P_PRINCIPAL_NAME).getString();
+ // only process aceNode if 'principalName' is contained in the given set
+ if (principalNames.contains(principalName)) {
+ Principal princ = principalMgr.getPrincipal(principalName);
+ if (princ == null) {
+ log.warn("Principal with name " + principalName + " unknown to PrincipalManager -> Ignored from AC evaluation.");
+ continue;
+ }
+
+ Value[] privValues = aceNode.getProperty(AccessControlConstants.P_PRIVILEGES).getValues();
+ Privilege[] privs = new Privilege[privValues.length];
+ for (int i = 0; i < privValues.length; i++) {
+ privs[i] = acMgr.privilegeFromName(privValues[i].getString());
+ }
+ // create a new ACEImpl (omitting validation check)
+ AccessControlEntry ace = new ACLTemplate.Entry(
+ princ,
+ privs,
+ aceNode.isNodeType(AccessControlConstants.NT_REP_GRANT_ACE),
+ sImpl.getValueFactory());
+ // add it to the proper list (e.g. separated by principals)
+ /**
+ * NOTE: access control entries must be collected in reverse
+ * order in order to assert proper evaluation.
+ */
+ if (princ instanceof Group) {
+ gaces.add(0, ace);
+ } else {
+ uaces.add(0, ace);
+ }
+ }
+ }
+
+ // add the lists of aces to the overall lists that contain the entries
+ // throughout the hierarchy.
+ if (!gaces.isEmpty()) {
+ groupAces.addAll(gaces);
+ }
+ if (!uaces.isEmpty()) {
+ userAces.addAll(uaces);
}
- return new AccessControlEntryIterator(entries);
}
- }
+ private Iterator<AccessControlEntry> iterator() {
+ return new IteratorChain(userAces.iterator(), groupAces.iterator());
+ }
+ }
}
Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/ACLTemplate.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/ACLTemplate.java?rev=884108&r1=884107&r2=884108&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/ACLTemplate.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/acl/ACLTemplate.java Wed Nov 25 14:04:38 2009
@@ -19,7 +19,6 @@
import java.security.Principal;
import java.util.ArrayList;
import java.util.Collections;
-import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@@ -48,9 +47,11 @@
import org.slf4j.LoggerFactory;
/**
- * Implementation of the {@link org.apache.jackrabbit.api.security.JackrabbitAccessControlList} interface that
- * is detached from the effective access control content. Consequently, any
- * modifications applied to this ACL only take effect, if the policy gets
+ * Implementation of the
+ * {@link org.apache.jackrabbit.api.security.JackrabbitAccessControlList}
+ * interface that is detached from the effective access control content.
+ * Consequently, any modifications applied to this ACL only take effect, if
+ * the policy gets
* {@link javax.jcr.security.AccessControlManager#setPolicy(String, javax.jcr.security.AccessControlPolicy) reapplied}
* to the <code>AccessControlManager</code> and the changes are saved.
*/
@@ -59,11 +60,10 @@
private static final Logger log = LoggerFactory.getLogger(ACLTemplate.class);
/**
- * Map containing the entries of this ACL Template using the principal
- * name as key. The value represents a List containing maximal one grant
- * and one deny ACE per principal.
+ * List containing the entries of this ACL Template with maximal one
+ * grant and one deny ACE per principal.
*/
- private final Map<String, List<Entry>> entries = new LinkedHashMap<String, List<Entry>>();
+ private final List<Entry> entries = new ArrayList<Entry>();
/**
* The principal manager used for validation checks
@@ -140,102 +140,54 @@
}
}
- /**
- * Separately collect the entries defined for the principals with the
- * specified names and return a map consisting of principal name key
- * and a list of ACEs as value.
- *
- * @param aclNode acl node
- * @param princToEntries Map of key = principalName and value = ArrayList
- * to be filled with ACEs matching the principal names.
- * @throws RepositoryException if an error occurs
- */
- static void collectEntries(NodeImpl aclNode, Map<String, List<AccessControlEntry>> princToEntries)
- throws RepositoryException {
- SessionImpl sImpl = (SessionImpl) aclNode.getSession();
- PrincipalManager principalMgr = sImpl.getPrincipalManager();
- AccessControlManager acMgr = sImpl.getAccessControlManager();
-
- NodeIterator itr = aclNode.getNodes();
- while (itr.hasNext()) {
- NodeImpl aceNode = (NodeImpl) itr.nextNode();
- String principalName = aceNode.getProperty(AccessControlConstants.P_PRINCIPAL_NAME).getString();
- // only process aceNode if 'principalName' is contained in the given set
- if (princToEntries.containsKey(principalName)) {
- Principal princ = principalMgr.getPrincipal(principalName);
- if (princ == null) {
- log.warn("Principal with name " + principalName + " unknown to PrincipalManager.");
- princ = new PrincipalImpl(principalName);
- }
-
- Value[] privValues = aceNode.getProperty(AccessControlConstants.P_PRIVILEGES).getValues();
- Privilege[] privs = new Privilege[privValues.length];
- for (int i = 0; i < privValues.length; i++) {
- privs[i] = acMgr.privilegeFromName(privValues[i].getString());
- }
- // create a new ACEImpl (omitting validation check)
- Entry ace = new Entry(
- princ,
- privs,
- aceNode.isNodeType(AccessControlConstants.NT_REP_GRANT_ACE),
- sImpl.getValueFactory());
- // add it to the proper list (e.g. separated by principals)
- princToEntries.get(principalName).add(ace);
- }
- }
- }
-
- private List<? extends AccessControlEntry> internalGetEntries() {
- List<Entry> l = new ArrayList<Entry>();
- for (List<Entry> o : entries.values()) {
- l.addAll(o);
- }
- return l;
- }
-
private List<Entry> internalGetEntries(Principal principal) {
String principalName = principal.getName();
- if (entries.containsKey(principalName)) {
- return entries.get(principalName);
- } else {
- return new ArrayList<Entry>(2);
+ List entriesPerPrincipal = new ArrayList(2);
+ for (Entry entry : entries) {
+ if (principalName.equals(entry.getPrincipal().getName())) {
+ entriesPerPrincipal.add(entry);
+ }
}
+ return entriesPerPrincipal;
}
private synchronized boolean internalAdd(Entry entry) throws AccessControlException {
Principal principal = entry.getPrincipal();
- List<Entry> l = internalGetEntries(principal);
- if (l.isEmpty()) {
- // simple case: just add the new entry
- l.add(entry);
- entries.put(principal.getName(), l);
+ List<Entry> entriesPerPrincipal = internalGetEntries(principal);
+ if (entriesPerPrincipal.isEmpty()) {
+ // simple case: just add the new entry at the end of the list.
+ entries.add(entry);
return true;
} else {
- if (l.contains(entry)) {
+ if (entriesPerPrincipal.contains(entry)) {
// the same entry is already contained -> no modification
return false;
}
// check if need to adjust existing entries
+ int updateIndex = -1;
Entry complementEntry = null;
- Entry[] entries = l.toArray(new Entry[l.size()]);
- for (int i = 0; i < entries.length; i++) {
- if (entry.isAllow() == entries[i].isAllow()) {
- int existingPrivs = entries[i].getPrivilegeBits();
+
+ for (Entry e : entriesPerPrincipal) {
+ if (entry.isAllow() == e.isAllow()) {
+ int existingPrivs = e.getPrivilegeBits();
if ((existingPrivs | ~entry.getPrivilegeBits()) == -1) {
// all privileges to be granted/denied are already present
// in the existing entry -> not modified
return false;
}
+ // remember the index of the existing entry to be updated later on.
+ updateIndex = entries.indexOf(e);
+
// remove the existing entry and create a new that includes
// both the new privileges and the existing ones.
- l.remove(i);
- int mergedBits = entries[i].getPrivilegeBits() | entry.getPrivilegeBits();
+ entries.remove(e);
+ int mergedBits = e.getPrivilegeBits() | entry.getPrivilegeBits();
Privilege[] mergedPrivs = privilegeRegistry.getPrivileges(mergedBits);
// omit validation check.
entry = new Entry(entry.getPrincipal(), mergedPrivs, entry.isAllow(), valueFactory);
} else {
- complementEntry = entries[i];
+ complementEntry = e;
}
}
@@ -243,22 +195,34 @@
// grant/deny the same privileges -> remove privileges that are now
// denied/granted.
if (complementEntry != null) {
+
int complPrivs = complementEntry.getPrivilegeBits();
int resultPrivs = Permission.diff(complPrivs, entry.getPrivilegeBits());
+
if (resultPrivs == PrivilegeRegistry.NO_PRIVILEGE) {
- l.remove(complementEntry);
+ // remove the complement entry as the new entry covers
+ // all privileges granted by the existing entry.
+ entries.remove(complementEntry);
+ updateIndex--;
+
} else if (resultPrivs != complPrivs) {
- l.remove(complementEntry);
- // omit validation check
+ // replace the existing entry having the privileges adjusted
+ int index = entries.indexOf(complementEntry);
+ entries.remove(complementEntry);
Entry tmpl = new Entry(entry.getPrincipal(),
privilegeRegistry.getPrivileges(resultPrivs),
!entry.isAllow(), valueFactory);
- l.add(tmpl);
+ entries.add(index, tmpl);
} /* else: does not need to be modified.*/
}
- // finally add the new entry at the end.
- l.add(entry);
+ // finally update the existing entry or add the new entry passed
+ // to this method at the end.
+ if (updateIndex < 0) {
+ entries.add(entry);
+ } else {
+ entries.add(updateIndex, entry);
+ }
return true;
}
}
@@ -281,12 +245,19 @@
}
}
+ /**
+ * @see org.apache.jackrabbit.core.security.authorization.AbstractACLTemplate#getEntries()
+ */
+ protected List<? extends AccessControlEntry> getEntries() {
+ return entries;
+ }
+
//--------------------------------------------------< AccessControlList >---
/**
* @see javax.jcr.security.AccessControlList#getAccessControlEntries()
*/
public AccessControlEntry[] getAccessControlEntries() throws RepositoryException {
- List<? extends AccessControlEntry> l = internalGetEntries();
+ List<? extends AccessControlEntry> l = getEntries();
return l.toArray(new AccessControlEntry[l.size()]);
}
@@ -298,11 +269,8 @@
if (!(ace instanceof Entry)) {
throw new AccessControlException("Invalid AccessControlEntry implementation " + ace.getClass().getName() + ".");
}
- List l = internalGetEntries(ace.getPrincipal());
- if (l.remove(ace)) {
- if (l.isEmpty()) {
- entries.remove(ace.getPrincipal().getName());
- }
+ if (entries.contains(ace)) {
+ entries.remove(ace);
} else {
throw new AccessControlException("AccessControlEntry " + ace + " cannot be removed from ACL defined at " + getPath());
}
@@ -339,7 +307,7 @@
* @see org.apache.jackrabbit.api.security.JackrabbitAccessControlList#size()
*/
public int size() {
- return internalGetEntries().size();
+ return getEntries().size();
}
/**
Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/combined/CombinedProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/combined/CombinedProvider.java?rev=884108&r1=884107&r2=884108&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/combined/CombinedProvider.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/combined/CombinedProvider.java Wed Nov 25 14:04:38 2009
@@ -81,6 +81,7 @@
/**
* @see AccessControlProvider#close()
*/
+ @Override
public void close() {
for (AccessControlProvider provider : providers) {
provider.close();
@@ -91,6 +92,7 @@
/**
* @see AccessControlProvider#init(javax.jcr.Session, java.util.Map)
*/
+ @Override
public void init(Session systemSession, Map configuration) throws RepositoryException {
super.init(systemSession, configuration);
@@ -207,6 +209,7 @@
/**
* @see AbstractCompiledPermissions#buildResult(Path)
*/
+ @Override
protected Result buildResult(Path absPath) throws RepositoryException {
Result res = null;
for (AbstractCompiledPermissions acp : cPermissions) {
@@ -219,6 +222,7 @@
/**
* @see AbstractCompiledPermissions#getResult(Path)
*/
+ @Override
public Result getResult(Path absPath) throws RepositoryException {
// TODO: missing caching
return buildResult(absPath);
@@ -228,10 +232,11 @@
/**
* @see CompiledPermissions#close()
*/
+ @Override
public synchronized void close() {
// close all c-permissions retained in the list and clear the list.
- for (Iterator it = cPermissions.iterator(); it.hasNext();) {
- CompiledPermissions cp = (CompiledPermissions) it.next();
+ for (Iterator<AbstractCompiledPermissions> it = cPermissions.iterator(); it.hasNext();) {
+ CompiledPermissions cp = it.next();
cp.close();
it.remove();
}
Modified: jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/principalbased/ACLProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/principalbased/ACLProvider.java?rev=884108&r1=884107&r2=884108&view=diff
==============================================================================
--- jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/principalbased/ACLProvider.java (original)
+++ jackrabbit/sandbox/JCR-1456/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/security/authorization/principalbased/ACLProvider.java Wed Nov 25 14:04:38 2009
@@ -99,6 +99,7 @@
/**
* @see org.apache.jackrabbit.core.security.authorization.AccessControlProvider#init(javax.jcr.Session, java.util.Map)
*/
+ @Override
public void init(Session systemSession, Map configuration) throws RepositoryException {
super.init(systemSession, configuration);
@@ -113,6 +114,7 @@
}
editor = new ACLEditor(session, resolver.getQPath(acRoot.getPath()));
+ // TODO: replace by configurable default policy (see JCR-2331)
if (!configuration.containsKey(PARAM_OMIT_DEFAULT_PERMISSIONS)) {
try {
log.debug("Install initial permissions: ...");
@@ -126,15 +128,14 @@
AccessControlManager acMgr = session.getAccessControlManager();
// initial default permissions for the administrators group
- Principal administrators;
String pName = SecurityConstants.ADMINISTRATORS_NAME;
if (pMgr.hasPrincipal(pName)) {
- administrators = pMgr.getPrincipal(pName);
+ Principal administrators = pMgr.getPrincipal(pName);
installDefaultPermissions(administrators,
new Privilege[] {acMgr.privilegeFromName(Privilege.JCR_ALL)},
restrictions, editor);
} else {
- log.warn("Administrators principal group is missing -> Not adding default permissions.");
+ log.info("Administrators principal group is missing -> Not adding default permissions.");
}
// initialize default permissions for the everyone group
@@ -276,6 +277,7 @@
/**
* @see AbstractCompiledPermissions#buildResult(Path)
*/
+ @Override
protected synchronized Result buildResult(Path absPath) throws RepositoryException {
if (!absPath.isAbsolute()) {
throw new RepositoryException("Absolute path expected.");
@@ -355,6 +357,7 @@
/**
* @see CompiledPermissions#close()
*/
+ @Override
public void close() {
try {
observationMgr.removeEventListener(this);