Author: nzamosenchuk
Date: 2010-06-15 06:21:46 -0400 (Tue, 15 Jun 2010)
New Revision: 2599
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/ErrorLog.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/ConsistencyCheck.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/FileBasedNamespaceMappings.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/IndexingQueue.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/IndexingQueueStore.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/MultiIndex.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/PersistentIndex.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/SearchIndex.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/Util.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/VolatileIndex.java
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/SecurityHelper.java
Log:
EXOJCR-758: indexer updates
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/ErrorLog.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/ErrorLog.java 2010-06-15
09:58:52 UTC (rev 2598)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/ErrorLog.java 2010-06-15
10:21:46 UTC (rev 2599)
@@ -17,6 +17,7 @@
package org.exoplatform.services.jcr.impl.core.query;
+import org.exoplatform.services.jcr.impl.util.SecurityHelper;
import org.exoplatform.services.jcr.impl.util.io.PrivilegedFileHelper;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
@@ -30,6 +31,7 @@
import java.io.InputStreamReader;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
+import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@@ -96,24 +98,31 @@
* @param log
* @throws IOException
*/
- private void openFile(File log) throws IOException
+ private void openFile(final File log) throws IOException
{
- // set file size;
- if (!log.exists())
+ SecurityHelper.doPriviledgedIOExceptionAction(new
PrivilegedExceptionAction<Object>()
{
- log.getParentFile().mkdirs();
- log.createNewFile();
+ public Object run() throws Exception
+ {
+ // set file size;
+ if (!log.exists())
+ {
+ log.getParentFile().mkdirs();
+ log.createNewFile();
- out = PrivilegedFileHelper.fileOutputStream(log).getChannel();
- out.position(1024 * fileSize - 1);
- out.write(ByteBuffer.wrap(new byte[]{0}));
- out.position(0);
- out.force(false);
- }
- else
- {
- out = PrivilegedFileHelper.fileOutputStream(log, true).getChannel();
- }
+ out = PrivilegedFileHelper.fileOutputStream(log).getChannel();
+ out.position(1024 * fileSize - 1);
+ out.write(ByteBuffer.wrap(new byte[]{0}));
+ out.position(0);
+ out.force(false);
+ }
+ else
+ {
+ out = new FileOutputStream(log, true).getChannel();
+ }
+ return null;
+ }
+ });
}
/**
@@ -124,10 +133,17 @@
* @throws IOException
* if the node cannot be written to the redo log.
*/
- public void append(String action, String uuid) throws IOException
+ public void append(final String action, final String uuid) throws IOException
{
initOut();
- out.write(ByteBuffer.wrap((action + " " + uuid +
"\n").getBytes()));
+ SecurityHelper.doPriviledgedIOExceptionAction(new
PrivilegedExceptionAction<Object>()
+ {
+ public Object run() throws Exception
+ {
+ out.write(ByteBuffer.wrap((action + " " + uuid +
"\n").getBytes()));
+ return null;
+ }
+ });
}
/**
@@ -138,10 +154,17 @@
*/
public void flush() throws IOException
{
- if (out != null)
+ SecurityHelper.doPriviledgedIOExceptionAction(new
PrivilegedExceptionAction<Object>()
{
- out.force(false);
- }
+ public Object run() throws Exception
+ {
+ if (out != null)
+ {
+ out.force(false);
+ }
+ return null;
+ }
+ });
}
/**
@@ -152,16 +175,23 @@
*/
public void clear() throws IOException
{
- if (out != null)
+ SecurityHelper.doPriviledgedIOExceptionAction(new
PrivilegedExceptionAction<Object>()
{
- out.truncate(0);
- out.close();
- out = PrivilegedFileHelper.fileOutputStream(logFile).getChannel();
- out.position(1024 * fileSize - 1);
- out.write(ByteBuffer.wrap(new byte[]{0}));
- out.position(0);
- out.force(false);
- }
+ public Object run() throws Exception
+ {
+ if (out != null)
+ {
+ out.truncate(0);
+ out.close();
+ out = new FileOutputStream(logFile).getChannel();
+ out.position(1024 * fileSize - 1);
+ out.write(ByteBuffer.wrap(new byte[]{0}));
+ out.position(0);
+ out.force(false);
+ }
+ return null;
+ }
+ });
}
/**
@@ -172,11 +202,18 @@
*/
private void initOut() throws IOException
{
- if (out == null)
+ SecurityHelper.doPriviledgedIOExceptionAction(new
PrivilegedExceptionAction<Object>()
{
- FileOutputStream os = PrivilegedFileHelper.fileOutputStream(logFile, false);
- out = os.getChannel();
- }
+ public Object run() throws Exception
+ {
+ if (out == null)
+ {
+ FileOutputStream os = new FileOutputStream(logFile, false);
+ out = os.getChannel();
+ }
+ return null;
+ }
+ });
}
/**
@@ -187,36 +224,42 @@
*/
public List<String> readList() throws IOException
{
- InputStream in = PrivilegedFileHelper.fileInputStream(logFile);
- try
+ return SecurityHelper.doPriviledgedIOExceptionAction(new
PrivilegedExceptionAction<List<String>>()
{
- List<String> list = new ArrayList<String>();
- BufferedReader reader = new BufferedReader(new InputStreamReader(in));
- String line;
- while ((line = reader.readLine()) != null)
+ public List<String> run() throws Exception
{
- if (!line.matches("\\x00++"))
+ InputStream in = new FileInputStream(logFile);
+ try
{
- list.add(line);
- }
- }
- return list;
+ List<String> list = new ArrayList<String>();
+ BufferedReader reader = new BufferedReader(new InputStreamReader(in));
+ String line;
+ while ((line = reader.readLine()) != null)
+ {
+ if (!line.matches("\\x00++"))
+ {
+ list.add(line);
+ }
+ }
+ return list;
- }
- finally
- {
- if (in != null)
- {
- try
- {
- in.close();
}
- catch (IOException e)
+ finally
{
- LOG.warn("Exception while closing error log: " + e.toString());
+ if (in != null)
+ {
+ try
+ {
+ in.close();
+ }
+ catch (IOException e)
+ {
+ LOG.warn("Exception while closing error log: " +
e.toString());
+ }
+ }
}
}
- }
+ });
}
public void readChanges(Set<String> rem, Set<String> add) throws
IOException
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/ConsistencyCheck.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/ConsistencyCheck.java 2010-06-15
09:58:52 UTC (rev 2598)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/ConsistencyCheck.java 2010-06-15
10:21:46 UTC (rev 2599)
@@ -19,10 +19,12 @@
import org.apache.lucene.document.Document;
import org.exoplatform.services.jcr.dataflow.ItemDataConsumer;
import org.exoplatform.services.jcr.datamodel.NodeData;
+import org.exoplatform.services.jcr.impl.util.SecurityHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
+import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
@@ -114,12 +116,20 @@
int notRepairable = 0;
for (Iterator<ConsistencyCheckError> it = errors.iterator(); it.hasNext();)
{
- ConsistencyCheckError error = it.next();
+ final ConsistencyCheckError error = it.next();
try
{
if (error.repairable())
{
- error.repair();
+ SecurityHelper.doPriviledgedIOExceptionAction(new
PrivilegedExceptionAction<Object>()
+ {
+ public Object run() throws Exception
+ {
+ // running in privileged mode
+ error.repair();
+ return null;
+ }
+ });
}
else
{
@@ -170,21 +180,29 @@
Set multipleEntries = new HashSet();
// collect all documents UUIDs
documentUUIDs = new HashSet();
- CachingMultiIndexReader reader = index.getIndexReader();
+ final CachingMultiIndexReader reader = index.getIndexReader();
try
{
for (int i = 0; i < reader.maxDoc(); i++)
{
if (i > 10 && i % (reader.maxDoc() / 5) == 0)
{
- long progress = Math.round((100.0 * (float)i) / ((float)reader.maxDoc() *
2f));
+ long progress = Math.round((100.0 * i) / (reader.maxDoc() * 2f));
log.info("progress: " + progress + "%");
}
if (reader.isDeleted(i))
{
continue;
}
- Document d = reader.document(i, FieldSelectors.UUID);
+ final int currentIndex = i;
+ Document d = SecurityHelper.doPriviledgedIOExceptionAction(new
PrivilegedExceptionAction<Document>()
+ {
+ public Document run() throws Exception
+ {
+ return reader.document(currentIndex, FieldSelectors.UUID);
+ }
+ });
+
String uuid = d.get(FieldNames.UUID);
if (stateMgr.getItemData(uuid) != null)
{
@@ -201,7 +219,14 @@
}
finally
{
- reader.release();
+ SecurityHelper.doPriviledgedIOExceptionAction(new
PrivilegedExceptionAction<Object>()
+ {
+ public Object run() throws Exception
+ {
+ reader.release();
+ return null;
+ }
+ });
}
// create multiple entries errors
@@ -210,22 +235,30 @@
errors.add(new MultipleEntries((String)it.next()));
}
- reader = index.getIndexReader();
+ final CachingMultiIndexReader newReader = index.getIndexReader();
try
{
// run through documents again and check parent
- for (int i = 0; i < reader.maxDoc(); i++)
+ for (int i = 0; i < newReader.maxDoc(); i++)
{
- if (i > 10 && i % (reader.maxDoc() / 5) == 0)
+ if (i > 10 && i % (newReader.maxDoc() / 5) == 0)
{
- long progress = Math.round((100.0 * (float)i) / ((float)reader.maxDoc() *
2f));
+ long progress = Math.round((100.0 * i) / (newReader.maxDoc() * 2f));
log.info("progress: " + (progress + 50) + "%");
}
- if (reader.isDeleted(i))
+ if (newReader.isDeleted(i))
{
continue;
}
- Document d = reader.document(i, FieldSelectors.UUID_AND_PARENT);
+ final int currentIndex = i;
+ Document d = SecurityHelper.doPriviledgedIOExceptionAction(new
PrivilegedExceptionAction<Document>()
+ {
+ public Document run() throws Exception
+ {
+ return newReader.document(currentIndex,
FieldSelectors.UUID_AND_PARENT);
+ }
+ });
+
String uuid = d.get(FieldNames.UUID);
String parentUUIDString = d.get(FieldNames.PARENT);
@@ -248,7 +281,14 @@
}
finally
{
- reader.release();
+ SecurityHelper.doPriviledgedIOExceptionAction(new
PrivilegedExceptionAction<Object>()
+ {
+ public Object run() throws Exception
+ {
+ newReader.release();
+ return null;
+ }
+ });
}
}
@@ -285,6 +325,7 @@
* Returns <code>true</code>.
* @return <code>true</code>.
*/
+ @Override
public boolean repairable()
{
return true;
@@ -294,6 +335,7 @@
* Repairs the missing node by indexing the missing ancestors.
* @throws IOException if an error occurs while repairing.
*/
+ @Override
public void repair() throws IOException
{
String parentId = parentUUID;
@@ -331,6 +373,7 @@
* Not reparable (yet).
* @return <code>false</code>.
*/
+ @Override
public boolean repairable()
{
return false;
@@ -339,6 +382,7 @@
/**
* No operation.
*/
+ @Override
public void repair() throws IOException
{
log.warn("Unknown parent for " + uuid + " cannot be
repaired");
@@ -360,6 +404,7 @@
* Returns <code>true</code>.
* @return <code>true</code>.
*/
+ @Override
public boolean repairable()
{
return true;
@@ -370,6 +415,7 @@
* re-index the node.
* @throws IOException if an error occurs while repairing.
*/
+ @Override
public void repair() throws IOException
{
// first remove all occurrences
@@ -405,6 +451,7 @@
* Returns <code>true</code>.
* @return <code>true</code>.
*/
+ @Override
public boolean repairable()
{
return true;
@@ -414,6 +461,7 @@
* Deletes the nodes from the index.
* @throws IOException if an error occurs while repairing.
*/
+ @Override
public void repair() throws IOException
{
log.info("Removing deleted node from index: " + uuid);
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/FileBasedNamespaceMappings.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/FileBasedNamespaceMappings.java 2010-06-15
09:58:52 UTC (rev 2598)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/FileBasedNamespaceMappings.java 2010-06-15
10:21:46 UTC (rev 2599)
@@ -16,16 +16,17 @@
*/
package org.exoplatform.services.jcr.impl.core.query.lucene;
+import org.exoplatform.services.jcr.impl.util.SecurityHelper;
import org.exoplatform.services.jcr.impl.util.io.PrivilegedFileHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.BufferedOutputStream;
import java.io.File;
-import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.security.PrivilegedExceptionAction;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
@@ -148,33 +149,40 @@
*/
private void load() throws IOException
{
- if (storage.exists())
+ SecurityHelper.doPriviledgedIOExceptionAction(new
PrivilegedExceptionAction<Object>()
{
- InputStream in = PrivilegedFileHelper.fileInputStream(storage);
- try
+ public Object run() throws Exception
{
- Properties props = new Properties();
- log.debug("loading namespace mappings...");
- props.load(in);
+ if (storage.exists())
+ {
+ InputStream in = PrivilegedFileHelper.fileInputStream(storage);
+ try
+ {
+ Properties props = new Properties();
+ log.debug("loading namespace mappings...");
+ props.load(in);
- // read mappings from properties
- Iterator iter = props.keySet().iterator();
- while (iter.hasNext())
- {
- String prefix = (String)iter.next();
- String uri = props.getProperty(prefix);
- log.debug(prefix + " -> " + uri);
- prefixToURI.put(prefix, uri);
- uriToPrefix.put(uri, prefix);
+ // read mappings from properties
+ Iterator iter = props.keySet().iterator();
+ while (iter.hasNext())
+ {
+ String prefix = (String)iter.next();
+ String uri = props.getProperty(prefix);
+ log.debug(prefix + " -> " + uri);
+ prefixToURI.put(prefix, uri);
+ uriToPrefix.put(uri, prefix);
+ }
+ prefixCount = props.size();
+ log.debug("namespace mappings loaded.");
+ }
+ finally
+ {
+ in.close();
+ }
}
- prefixCount = props.size();
- log.debug("namespace mappings loaded.");
+ return null;
}
- finally
- {
- in.close();
- }
- }
+ });
}
/**
@@ -184,28 +192,35 @@
*/
private void store() throws IOException
{
- Properties props = new Properties();
-
- // store mappings in properties
- Iterator iter = prefixToURI.keySet().iterator();
- while (iter.hasNext())
+ SecurityHelper.doPriviledgedIOExceptionAction(new
PrivilegedExceptionAction<Object>()
{
- String prefix = (String)iter.next();
- String uri = (String)prefixToURI.get(prefix);
- props.setProperty(prefix, uri);
- }
+ public Object run() throws Exception
+ {
+ Properties props = new Properties();
- OutputStream out = PrivilegedFileHelper.fileOutputStream(storage);
- try
- {
- out = new BufferedOutputStream(out);
- props.store(out, null);
- }
- finally
- {
- // make sure stream is closed
- out.close();
- }
+ // store mappings in properties
+ Iterator iter = prefixToURI.keySet().iterator();
+ while (iter.hasNext())
+ {
+ String prefix = (String)iter.next();
+ String uri = (String)prefixToURI.get(prefix);
+ props.setProperty(prefix, uri);
+ }
+
+ OutputStream out = PrivilegedFileHelper.fileOutputStream(storage);
+ try
+ {
+ out = new BufferedOutputStream(out);
+ props.store(out, null);
+ }
+ finally
+ {
+ // make sure stream is closed
+ out.close();
+ }
+ return null;
+ }
+ });
}
public String[] getAllNamespacePrefixes() throws RepositoryException
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/IndexingQueue.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/IndexingQueue.java 2010-06-15
09:58:52 UTC (rev 2598)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/IndexingQueue.java 2010-06-15
10:21:46 UTC (rev 2599)
@@ -19,10 +19,12 @@
import org.apache.lucene.document.Document;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.TermDocs;
+import org.exoplatform.services.jcr.impl.util.SecurityHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
+import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
@@ -75,54 +77,62 @@
* @param index the multi index this indexing queue belongs to.
* @throws IOException if an error occurs while reading from the index.
*/
- void initialize(MultiIndex index) throws IOException
+ void initialize(final MultiIndex index) throws IOException
{
- if (initialized)
+ SecurityHelper.doPriviledgedIOExceptionAction(new
PrivilegedExceptionAction<Object>()
{
- throw new IllegalStateException("already initialized");
- }
- // check index for nodes that need to be reindexed
- CachingMultiIndexReader reader = index.getIndexReader();
- try
- {
- TermDocs tDocs = reader.termDocs(new Term(FieldNames.REINDEXING_REQUIRED,
""));
- try
+ public Object run() throws Exception
{
- while (tDocs.next())
+ if (initialized)
{
- queueStore.addUUID(reader.document(tDocs.doc(),
FieldSelectors.UUID).get(FieldNames.UUID));
+ throw new IllegalStateException("already initialized");
}
+ // check index for nodes that need to be reindexed
+ CachingMultiIndexReader reader = index.getIndexReader();
+ try
+ {
+ TermDocs tDocs = reader.termDocs(new Term(FieldNames.REINDEXING_REQUIRED,
""));
+ try
+ {
+ while (tDocs.next())
+ {
+ queueStore.addUUID(reader.document(tDocs.doc(),
FieldSelectors.UUID).get(FieldNames.UUID));
+ }
+ }
+ finally
+ {
+ tDocs.close();
+ }
+ }
+ finally
+ {
+ reader.release();
+ }
+ String[] uuids = queueStore.getPending();
+ for (int i = 0; i < uuids.length; i++)
+ {
+ try
+ {
+ Document doc = index.createDocument(uuids[i]);
+ pendingDocuments.put(uuids[i], doc);
+ log.debug("added node {}. New size of indexing queue: {}",
uuids[i], new Integer(pendingDocuments
+ .size()));
+ }
+ catch (IllegalArgumentException e)
+ {
+ log.warn("Invalid UUID in indexing queue store: " +
uuids[i]);
+ }
+ catch (RepositoryException e)
+ {
+ // node does not exist anymore
+ log.debug("Node with uuid {} does not exist anymore",
uuids[i]);
+ queueStore.removeUUID(uuids[i]);
+ }
+ }
+ initialized = true;
+ return null;
}
- finally
- {
- tDocs.close();
- }
- }
- finally
- {
- reader.release();
- }
- String[] uuids = queueStore.getPending();
- for (int i = 0; i < uuids.length; i++)
- {
- try
- {
- Document doc = index.createDocument(uuids[i]);
- pendingDocuments.put(uuids[i], doc);
- log.debug("added node {}. New size of indexing queue: {}",
uuids[i], new Integer(pendingDocuments.size()));
- }
- catch (IllegalArgumentException e)
- {
- log.warn("Invalid UUID in indexing queue store: " + uuids[i]);
- }
- catch (RepositoryException e)
- {
- // node does not exist anymore
- log.debug("Node with uuid {} does not exist anymore", uuids[i]);
- queueStore.removeUUID(uuids[i]);
- }
- }
- initialized = true;
+ });
}
/**
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/IndexingQueueStore.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/IndexingQueueStore.java 2010-06-15
09:58:52 UTC (rev 2598)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/IndexingQueueStore.java 2010-06-15
10:21:46 UTC (rev 2599)
@@ -18,6 +18,7 @@
import org.apache.lucene.store.Directory;
import org.exoplatform.services.jcr.impl.core.query.lucene.directory.IndexInputStream;
+import org.exoplatform.services.jcr.impl.util.SecurityHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -25,6 +26,8 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedExceptionAction;
import java.util.HashSet;
import java.util.Set;
@@ -118,20 +121,27 @@
*/
public void close()
{
- if (pending.isEmpty())
+ SecurityHelper.doPriviledgedAction(new PrivilegedAction<Object>()
{
- try
+ public Object run()
{
- if (dir.fileExists(INDEXING_QUEUE_FILE))
+ if (pending.isEmpty())
{
- dir.deleteFile(INDEXING_QUEUE_FILE);
+ try
+ {
+ if (dir.fileExists(INDEXING_QUEUE_FILE))
+ {
+ dir.deleteFile(INDEXING_QUEUE_FILE);
+ }
+ }
+ catch (IOException e)
+ {
+ log.warn("unable to delete " + INDEXING_QUEUE_FILE);
+ }
}
+ return null;
}
- catch (IOException e)
- {
- log.warn("unable to delete " + INDEXING_QUEUE_FILE);
- }
- }
+ });
}
//----------------------------< internal >----------------------------------
@@ -144,45 +154,52 @@
*/
private void readStore() throws IOException
{
- if (dir.fileExists(INDEXING_QUEUE_FILE))
+ SecurityHelper.doPriviledgedIOExceptionAction(new
PrivilegedExceptionAction<Object>()
{
- InputStream in = new IndexInputStream(dir.openInput(INDEXING_QUEUE_FILE));
- BufferedReader reader = new BufferedReader(new InputStreamReader(in,
ENCODING));
- try
+ public Object run() throws Exception
{
- String line;
- while ((line = reader.readLine()) != null)
+ if (dir.fileExists(INDEXING_QUEUE_FILE))
{
- int idx = line.indexOf(' ');
- if (idx == -1)
+ InputStream in = new
IndexInputStream(dir.openInput(INDEXING_QUEUE_FILE));
+ BufferedReader reader = new BufferedReader(new InputStreamReader(in,
ENCODING));
+ try
{
- // invalid line
- log.warn("invalid line in {}: {}", INDEXING_QUEUE_FILE,
line);
- }
- else
- {
- String cmd = line.substring(0, idx);
- String uuid = line.substring(idx + 1, line.length());
- if (ADD.equals(cmd))
+ String line;
+ while ((line = reader.readLine()) != null)
{
- pending.add(uuid);
+ int idx = line.indexOf(' ');
+ if (idx == -1)
+ {
+ // invalid line
+ log.warn("invalid line in {}: {}", INDEXING_QUEUE_FILE,
line);
+ }
+ else
+ {
+ String cmd = line.substring(0, idx);
+ String uuid = line.substring(idx + 1, line.length());
+ if (ADD.equals(cmd))
+ {
+ pending.add(uuid);
+ }
+ else if (REMOVE.equals(cmd))
+ {
+ pending.remove(uuid);
+ }
+ else
+ {
+ // invalid line
+ log.warn("invalid line in {}: {}",
INDEXING_QUEUE_FILE, line);
+ }
+ }
}
- else if (REMOVE.equals(cmd))
- {
- pending.remove(uuid);
- }
- else
- {
- // invalid line
- log.warn("invalid line in {}: {}", INDEXING_QUEUE_FILE,
line);
- }
}
+ finally
+ {
+ in.close();
+ }
}
+ return null;
}
- finally
- {
- in.close();
- }
- }
+ });
}
}
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/MultiIndex.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/MultiIndex.java 2010-06-15
09:58:52 UTC (rev 2598)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/MultiIndex.java 2010-06-15
10:21:46 UTC (rev 2599)
@@ -20,8 +20,6 @@
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.store.Directory;
-import org.apache.lucene.store.FSDirectory;
-import org.apache.lucene.store.NativeFSLockFactory;
import org.exoplatform.services.jcr.dataflow.ItemDataConsumer;
import org.exoplatform.services.jcr.datamodel.ItemData;
import org.exoplatform.services.jcr.datamodel.NodeData;
@@ -35,9 +33,9 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
+import java.security.PrivilegedAction;
import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;
import java.util.Arrays;
@@ -245,6 +243,7 @@
this.modeHandler = modeHandler;
this.indexUpdateMonitor = indexUpdateMonitor;
this.directoryManager = handler.getDirectoryManager();
+ // this method is run in privileged mode internally
this.indexDir = directoryManager.getDirectory(".");
this.handler = handler;
this.cache = new DocNumberCache(handler.getCacheSize());
@@ -253,10 +252,13 @@
this.flushTask = null;
this.indexNames = indexInfos;
this.indexNames.setDirectory(indexDir);
+ // this method is run in privileged mode internally
this.indexNames.read();
modeHandler.addIndexerIoModeListener(this);
indexUpdateMonitor.addIndexUpdateMonitorListener(this);
+
+ // this method is run in privileged mode internally
// as of 1.5 deletable file is not used anymore
removeDeletable();
@@ -266,6 +268,7 @@
merger.setMergeFactor(handler.getMergeFactor());
merger.setMinMergeDocs(handler.getMinMergeDocs());
+ // this method is run in privileged mode internally
IndexingQueueStore store = new IndexingQueueStore(indexDir);
// initialize indexing queue
@@ -301,14 +304,21 @@
// set index format version and at the same time
// initialize hierarchy cache if requested.
- CachingMultiIndexReader reader =
getIndexReader(handler.isInitializeHierarchyCache());
+ final CachingMultiIndexReader reader =
getIndexReader(handler.isInitializeHierarchyCache());
try
{
version = IndexFormatVersion.getVersion(reader);
}
finally
{
- reader.release();
+ SecurityHelper.doPriviledgedIOExceptionAction(new
PrivilegedExceptionAction<Object>()
+ {
+ public Object run() throws Exception
+ {
+ reader.release();
+ return null;
+ }
+ });
}
indexingQueue.initialize(this);
if (modeHandler.getMode() == IndexerIoMode.READ_WRITE)
@@ -333,14 +343,21 @@
}
else
{
- CachingMultiIndexReader reader = getIndexReader();
+ final CachingMultiIndexReader reader = getIndexReader();
try
{
return reader.numDocs();
}
finally
{
- reader.release();
+ SecurityHelper.doPriviledgedIOExceptionAction(new
PrivilegedExceptionAction<Object>()
+ {
+ public Object run() throws Exception
+ {
+ reader.release();
+ return null;
+ }
+ });
}
}
}
@@ -418,71 +435,78 @@
* @throws IOException
* if an error occurs while updating the index.
*/
- synchronized void update(Collection remove, Collection add) throws IOException
+ synchronized void update(final Collection remove, final Collection add) throws
IOException
{
- // make sure a reader is available during long updates
- if (add.size() > handler.getBufferSize())
+ SecurityHelper.doPriviledgedIOExceptionAction(new
PrivilegedExceptionAction<Object>()
{
- try
+ public Object run() throws Exception
{
- getIndexReader().release();
- }
- catch (IOException e)
- {
- // do not fail if an exception is thrown here
- log.warn("unable to prepare index reader " + "for queries
during update", e);
- }
- }
-
- synchronized (updateMonitor)
- {
- //updateInProgress = true;
- indexUpdateMonitor.setUpdateInProgress(true, false);
- }
- boolean flush = false;
- try
- {
- long transactionId = nextTransactionId++;
- executeAndLog(new Start(transactionId));
-
- for (Iterator it = remove.iterator(); it.hasNext();)
- {
- executeAndLog(new DeleteNode(transactionId, (String)it.next()));
- }
- for (Iterator it = add.iterator(); it.hasNext();)
- {
- Document doc = (Document)it.next();
- if (doc != null)
+ // make sure a reader is available during long updates
+ if (add.size() > handler.getBufferSize())
{
- executeAndLog(new AddNode(transactionId, doc));
- // commit volatile index if needed
- flush |= checkVolatileCommit();
+ try
+ {
+ getIndexReader().release();
+ }
+ catch (IOException e)
+ {
+ // do not fail if an exception is thrown here
+ log.warn("unable to prepare index reader " + "for
queries during update", e);
+ }
}
- }
- executeAndLog(new Commit(transactionId));
- // flush whole index when volatile index has been commited.
- if (flush)
- {
- // if we are going to flush, need to set persistent update
synchronized (updateMonitor)
{
- indexUpdateMonitor.setUpdateInProgress(true, true);
+ //updateInProgress = true;
+ indexUpdateMonitor.setUpdateInProgress(true, false);
}
- flush();
- }
- }
- finally
- {
- synchronized (updateMonitor)
- {
- //updateInProgress = false;
+ boolean flush = false;
+ try
+ {
+ long transactionId = nextTransactionId++;
+ executeAndLog(new Start(transactionId));
- indexUpdateMonitor.setUpdateInProgress(false, flush);
- updateMonitor.notifyAll();
- releaseMultiReader();
+ for (Iterator it = remove.iterator(); it.hasNext();)
+ {
+ executeAndLog(new DeleteNode(transactionId, (String)it.next()));
+ }
+ for (Iterator it = add.iterator(); it.hasNext();)
+ {
+ Document doc = (Document)it.next();
+ if (doc != null)
+ {
+ executeAndLog(new AddNode(transactionId, doc));
+ // commit volatile index if needed
+ flush |= checkVolatileCommit();
+ }
+ }
+ executeAndLog(new Commit(transactionId));
+
+ // flush whole index when volatile index has been commited.
+ if (flush)
+ {
+ // if we are going to flush, need to set persistent update
+ synchronized (updateMonitor)
+ {
+ indexUpdateMonitor.setUpdateInProgress(true, true);
+ }
+ flush();
+ }
+ }
+ finally
+ {
+ synchronized (updateMonitor)
+ {
+ //updateInProgress = false;
+
+ indexUpdateMonitor.setUpdateInProgress(false, flush);
+ updateMonitor.notifyAll();
+ releaseMultiReader();
+ }
+ }
+ return null;
}
- }
+ });
}
/**
@@ -606,10 +630,17 @@
for (Iterator it = indexReaders.entrySet().iterator(); it.hasNext();)
{
Map.Entry entry = (Map.Entry)it.next();
- ReadOnlyIndexReader reader = (ReadOnlyIndexReader)entry.getKey();
+ final ReadOnlyIndexReader reader = (ReadOnlyIndexReader)entry.getKey();
try
{
- reader.release();
+ SecurityHelper.doPriviledgedIOExceptionAction(new
PrivilegedExceptionAction<Object>()
+ {
+ public Object run() throws Exception
+ {
+ reader.release();
+ return null;
+ }
+ });
}
catch (IOException ex)
{
@@ -727,14 +758,21 @@
* @throws IOException
* if an exception occurs while replacing the indexes.
*/
- void replaceIndexes(String[] obsoleteIndexes, PersistentIndex index, Collection
deleted) throws IOException
+ void replaceIndexes(String[] obsoleteIndexes, final PersistentIndex index, Collection
deleted) throws IOException
{
if (handler.isInitializeHierarchyCache())
{
// force initializing of caches
long time = System.currentTimeMillis();
- index.getReadOnlyIndexReader(true).release();
+ SecurityHelper.doPriviledgedIOExceptionAction(new
PrivilegedExceptionAction<Object>()
+ {
+ public Object run() throws Exception
+ {
+ index.getReadOnlyIndexReader(true).release();
+ return null;
+ }
+ });
time = System.currentTimeMillis() - time;
log.debug("hierarchy cache initialized in {} ms", new Long(time));
}
@@ -1119,17 +1157,24 @@
*/
void releaseMultiReader() throws IOException
{
- if (multiReader != null)
+ SecurityHelper.doPriviledgedIOExceptionAction(new
PrivilegedExceptionAction<Object>()
{
- try
+ public Object run() throws Exception
{
- multiReader.release();
+ if (multiReader != null)
+ {
+ try
+ {
+ multiReader.release();
+ }
+ finally
+ {
+ multiReader = null;
+ }
+ }
+ return null;
}
- finally
- {
- multiReader = null;
- }
- }
+ });
}
// -------------------------< internal
@@ -1161,28 +1206,35 @@
*/
private void scheduleFlushTask()
{
- // cancel task
- if (flushTask != null)
+ SecurityHelper.doPriviledgedAction(new PrivilegedAction<Object>()
{
- flushTask.cancel();
- }
- // clear canceled tasks
- FLUSH_TIMER.purge();
- // new flush task, cause canceled can't be re-used
- flushTask = new TimerTask()
- {
- @Override
- public void run()
+ public Object run()
{
- // check if there are any indexing jobs finished
- checkIndexingQueue();
- // check if volatile index should be flushed
- checkFlush();
+ // cancel task
+ if (flushTask != null)
+ {
+ flushTask.cancel();
+ }
+ // clear canceled tasks
+ FLUSH_TIMER.purge();
+ // new flush task, cause canceled can't be re-used
+ flushTask = new TimerTask()
+ {
+ @Override
+ public void run()
+ {
+ // check if there are any indexing jobs finished
+ checkIndexingQueue();
+ // check if volatile index should be flushed
+ checkFlush();
+ }
+ };
+ FLUSH_TIMER.schedule(flushTask, 0, 1000);
+ lastFlushTime = System.currentTimeMillis();
+ lastFileSystemFlushTime = System.currentTimeMillis();
+ return null;
}
- };
- FLUSH_TIMER.schedule(flushTask, 0, 1000);
- lastFlushTime = System.currentTimeMillis();
- lastFileSystemFlushTime = System.currentTimeMillis();
+ });
}
/**
@@ -1386,18 +1438,25 @@
*/
private void removeDeletable()
{
- String fileName = "deletable";
- try
+ SecurityHelper.doPriviledgedAction(new PrivilegedAction<Object>()
{
- if (indexDir.fileExists(fileName))
+ public Object run()
{
- indexDir.deleteFile(fileName);
+ String fileName = "deletable";
+ try
+ {
+ if (indexDir.fileExists(fileName))
+ {
+ indexDir.deleteFile(fileName);
+ }
+ }
+ catch (IOException e)
+ {
+ log.warn("Unable to remove file 'deletable'.", e);
+ }
+ return null;
}
- }
- catch (IOException e)
- {
- log.warn("Unable to remove file 'deletable'.", e);
- }
+ });
}
/**
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/PersistentIndex.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/PersistentIndex.java 2010-06-15
09:58:52 UTC (rev 2598)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/PersistentIndex.java 2010-06-15
10:21:46 UTC (rev 2599)
@@ -16,8 +16,6 @@
*/
package org.exoplatform.services.jcr.impl.core.query.lucene;
-import java.io.IOException;
-
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
@@ -26,149 +24,187 @@
import org.apache.lucene.store.IndexInput;
import org.apache.lucene.store.IndexOutput;
import org.exoplatform.services.jcr.impl.core.query.lucene.directory.DirectoryManager;
+import org.exoplatform.services.jcr.impl.util.SecurityHelper;
+import java.io.IOException;
+import java.security.PrivilegedExceptionAction;
-
/**
* Implements a lucene index which is based on a
* {@link org.apache.jackrabbit.core.fs.FileSystem}.
*/
-class PersistentIndex extends AbstractIndex {
+class PersistentIndex extends AbstractIndex
+{
- /** The name of this persistent index */
- private final String name;
+ /** The name of this persistent index */
+ private final String name;
- /**
- * If non <code>null</code>, <code>listener</code> needs to
be informed
- * when a document is deleted.
- */
- private IndexListener listener;
+ /**
+ * If non <code>null</code>, <code>listener</code> needs to be
informed
+ * when a document is deleted.
+ */
+ private IndexListener listener;
- /**
- * Creates a new <code>PersistentIndex</code>.
- *
- * @param name the name of this index.
- * @param analyzer the analyzer for text tokenizing.
- * @param similarity the similarity implementation.
- * @param cache the document number cache
- * @param indexingQueue the indexing queue.
- * @param directoryManager the directory manager.
- * @throws IOException if an error occurs while opening / creating the
- * index.
- */
- PersistentIndex(String name, Analyzer analyzer,
- Similarity similarity, DocNumberCache cache,
- IndexingQueue indexingQueue,
- DirectoryManager directoryManager)
- throws IOException {
- super(analyzer, similarity, directoryManager.getDirectory(name),
- cache, indexingQueue);
- this.name = name;
- if (isExisting()) {
- IndexMigration.migrate(this, directoryManager);
- }
- }
+ /**
+ * Creates a new <code>PersistentIndex</code>.
+ *
+ * @param name the name of this index.
+ * @param analyzer the analyzer for text tokenizing.
+ * @param similarity the similarity implementation.
+ * @param cache the document number cache
+ * @param indexingQueue the indexing queue.
+ * @param directoryManager the directory manager.
+ * @throws IOException if an error occurs while opening / creating the
+ * index.
+ */
+ PersistentIndex(String name, Analyzer analyzer, Similarity similarity, DocNumberCache
cache,
+ IndexingQueue indexingQueue, final DirectoryManager directoryManager) throws
IOException
+ {
+ super(analyzer, similarity, directoryManager.getDirectory(name), cache,
indexingQueue);
+ this.name = name;
+ if (isExisting())
+ {
+ SecurityHelper.doPriviledgedIOExceptionAction(new
PrivilegedExceptionAction<Object>()
+ {
+ public Object run() throws Exception
+ {
+ IndexMigration.migrate(PersistentIndex.this, directoryManager);
+ return null;
+ }
+ });
+ }
+ }
- /**
- * @inheritDoc
- */
- int removeDocument(Term idTerm) throws IOException {
- int num = super.removeDocument(idTerm);
- if (num > 0 && listener != null) {
- listener.documentDeleted(idTerm);
- }
- return num;
- }
+ /**
+ * @inheritDoc
+ */
+ @Override
+ int removeDocument(Term idTerm) throws IOException
+ {
+ int num = super.removeDocument(idTerm);
+ if (num > 0 && listener != null)
+ {
+ listener.documentDeleted(idTerm);
+ }
+ return num;
+ }
- /**
- * Merges the provided indexes into this index. After this completes, the
- * index is optimized.
- * <p/>
- * The provided IndexReaders are not closed.
- *
- * @param readers the readers of indexes to add.
- * @throws IOException if an error occurs while adding indexes.
- */
- void addIndexes(IndexReader[] readers) throws IOException {
- getIndexWriter().addIndexes(readers);
- getIndexWriter().optimize();
- }
+ /**
+ * Merges the provided indexes into this index. After this completes, the
+ * index is optimized.
+ * <p/>
+ * The provided IndexReaders are not closed.
+ *
+ * @param readers the readers of indexes to add.
+ * @throws IOException if an error occurs while adding indexes.
+ */
+ void addIndexes(final IndexReader[] readers) throws IOException
+ {
+ SecurityHelper.doPriviledgedIOExceptionAction(new
PrivilegedExceptionAction<Object>()
+ {
+ public Object run() throws Exception
+ {
+ getIndexWriter().addIndexes(readers);
+ getIndexWriter().optimize();
+ return null;
+ }
+ });
+ }
- /**
- * Copies <code>index</code> into this persistent index. This method
should
- * only be called when <code>this</code> index is empty otherwise the
- * behaviour is undefined.
- *
- * @param index the index to copy from.
- * @throws IOException if an error occurs while copying.
- */
- void copyIndex(AbstractIndex index) throws IOException {
- // commit changes to directory on other index.
- index.commit(true);
- // simply copy over the files
- byte[] buffer = new byte[1024];
- Directory dir = index.getDirectory();
- Directory dest = getDirectory();
- String[] files = dir.list();
- for (int i = 0; i < files.length; i++) {
- IndexInput in = dir.openInput(files[i]);
- try {
- IndexOutput out = dest.createOutput(files[i]);
- try {
- long remaining = in.length();
- while (remaining > 0) {
- int num = (int) Math.min(remaining, buffer.length);
+ /**
+ * Copies <code>index</code> into this persistent index. This method
should
+ * only be called when <code>this</code> index is empty otherwise the
+ * behaviour is undefined.
+ *
+ * @param index the index to copy from.
+ * @throws IOException if an error occurs while copying.
+ */
+ void copyIndex(final AbstractIndex index) throws IOException
+ {
+ SecurityHelper.doPriviledgedIOExceptionAction(new
PrivilegedExceptionAction<Object>()
+ {
+ public Object run() throws Exception
+ {
+ // commit changes to directory on other index.
+ index.commit(true);
+ // simply copy over the files
+ byte[] buffer = new byte[1024];
+ Directory dir = index.getDirectory();
+ Directory dest = getDirectory();
+ String[] files = dir.list();
+ for (int i = 0; i < files.length; i++)
+ {
+ IndexInput in = dir.openInput(files[i]);
+ try
+ {
+ IndexOutput out = dest.createOutput(files[i]);
+ try
+ {
+ long remaining = in.length();
+ while (remaining > 0)
+ {
+ int num = (int)Math.min(remaining, buffer.length);
in.readBytes(buffer, 0, num);
out.writeBytes(buffer, num);
remaining -= num;
- }
- } finally {
- out.close();
- }
- } finally {
- in.close();
+ }
+ }
+ finally
+ {
+ out.close();
+ }
+ }
+ finally
+ {
+ in.close();
+ }
}
- }
- }
+ return null;
+ }
+ });
+ }
- /**
- * Returns a <code>ReadOnlyIndexReader</code> and registeres
- * <code>listener</code> to send notifications when documents are deleted
on
- * <code>this</code> index.
- *
- * @param listener the listener to notify when documents are deleted.
- * @return a <code>ReadOnlyIndexReader</code>.
- * @throws IOException if the reader cannot be obtained.
- */
- synchronized ReadOnlyIndexReader getReadOnlyIndexReader(IndexListener listener)
- throws IOException {
- ReadOnlyIndexReader reader = getReadOnlyIndexReader();
- this.listener = listener;
- return reader;
- }
+ /**
+ * Returns a <code>ReadOnlyIndexReader</code> and registeres
+ * <code>listener</code> to send notifications when documents are deleted
on
+ * <code>this</code> index.
+ *
+ * @param listener the listener to notify when documents are deleted.
+ * @return a <code>ReadOnlyIndexReader</code>.
+ * @throws IOException if the reader cannot be obtained.
+ */
+ synchronized ReadOnlyIndexReader getReadOnlyIndexReader(IndexListener listener) throws
IOException
+ {
+ ReadOnlyIndexReader reader = getReadOnlyIndexReader();
+ this.listener = listener;
+ return reader;
+ }
- /**
- * Removes a potentially registered {@link IndexListener}.
- */
- synchronized void resetListener() {
- this.listener = null;
- }
+ /**
+ * Removes a potentially registered {@link IndexListener}.
+ */
+ synchronized void resetListener()
+ {
+ this.listener = null;
+ }
- /**
- * Returns the number of documents in this persistent index.
- *
- * @return the number of documents in this persistent index.
- * @throws IOException if an error occurs while reading from the index.
- */
- int getNumDocuments() throws IOException {
- return getIndexReader().numDocs();
- }
+ /**
+ * Returns the number of documents in this persistent index.
+ *
+ * @return the number of documents in this persistent index.
+ * @throws IOException if an error occurs while reading from the index.
+ */
+ int getNumDocuments() throws IOException
+ {
+ return getIndexReader().numDocs();
+ }
- /**
- * Returns the name of this index.
- * @return the name of this index.
- */
- String getName() {
- return name;
- }
+ /**
+ * Returns the name of this index.
+ * @return the name of this index.
+ */
+ String getName()
+ {
+ return name;
+ }
}
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/SearchIndex.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/SearchIndex.java 2010-06-15
09:58:52 UTC (rev 2598)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/SearchIndex.java 2010-06-15
10:21:46 UTC (rev 2599)
@@ -59,6 +59,7 @@
import org.exoplatform.services.jcr.impl.core.query.SearchIndexConfigurationHelper;
import org.exoplatform.services.jcr.impl.core.query.lucene.directory.DirectoryManager;
import org.exoplatform.services.jcr.impl.core.query.lucene.directory.FSDirectoryManager;
+import org.exoplatform.services.jcr.impl.util.SecurityHelper;
import org.exoplatform.services.jcr.impl.util.io.PrivilegedFileHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -69,6 +70,8 @@
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -129,6 +132,7 @@
* calculated as follows: 2 *
* Runtime.getRuntime().availableProcessors().
*/
+ @Deprecated
public static final int DEFAULT_EXTRACTOR_POOL_SIZE = 0;
/**
@@ -493,18 +497,24 @@
throw new IOException("SearchIndex requires 'path' parameter in
configuration!");
}
- File indexDirectory;
+ final File indexDirectory;
if (path != null)
{
-
indexDirectory = new File(path);
- if (!indexDirectory.exists())
+ SecurityHelper.doPriviledgedRepositoryExceptionAction(new
PrivilegedExceptionAction<Object>()
{
- if (!indexDirectory.mkdirs())
+ public Object run() throws Exception
{
- throw new RepositoryException("fail to create index dir " +
path);
+ if (!indexDirectory.exists())
+ {
+ if (!indexDirectory.mkdirs())
+ {
+ throw new RepositoryException("fail to create index dir "
+ path);
+ }
+ }
+ return null;
}
- }
+ });
}
else
{
@@ -531,9 +541,16 @@
else
{
// read local namespace mappings
- File mapFile = new File(indexDirectory, NS_MAPPING_FILE);
- if (mapFile.exists())
+ final File mapFile = new File(indexDirectory, NS_MAPPING_FILE);
+ boolean fileExists = SecurityHelper.doPriviledgedAction(new
PrivilegedAction<Boolean>()
{
+ public Boolean run()
+ {
+ return mapFile.exists();
+ }
+ });
+ if (fileExists)
+ {
// be backward compatible and use ns_mappings.properties from
// index folder
nsMappings = new FileBasedNamespaceMappings(mapFile);
@@ -1376,8 +1393,15 @@
{
try
{
- spCheck = spellCheckerClass.newInstance();
- spCheck.init(this, spellCheckerMinDistance, spellCheckerMorePopular);
+ spCheck = SecurityHelper.doPriviledgedIOExceptionAction(new
PrivilegedExceptionAction<SpellChecker>()
+ {
+ public SpellChecker run() throws Exception
+ {
+ SpellChecker spCheck = spellCheckerClass.newInstance();
+ spCheck.init(SearchIndex.this, spellCheckerMinDistance,
spellCheckerMorePopular);
+ return spCheck;
+ }
+ });
}
catch (Exception e)
{
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/Util.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/Util.java 2010-06-15
09:58:52 UTC (rev 2598)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/Util.java 2010-06-15
10:21:46 UTC (rev 2599)
@@ -25,11 +25,14 @@
import org.exoplatform.services.jcr.datamodel.QPathEntry;
import org.exoplatform.services.jcr.datamodel.ValueData;
import org.exoplatform.services.jcr.impl.dataflow.ValueDataConvertor;
+import org.exoplatform.services.jcr.impl.util.SecurityHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedExceptionAction;
import java.util.Iterator;
import java.util.regex.Pattern;
@@ -55,28 +58,35 @@
*
* @param old the document to dispose.
*/
- public static void disposeDocument(Document old)
+ public static void disposeDocument(final Document old)
{
- for (Iterator it = old.getFields().iterator(); it.hasNext();)
+ SecurityHelper.doPriviledgedAction(new PrivilegedAction<Object>()
{
- Fieldable f = (Fieldable)it.next();
- try
+ public Object run()
{
- if (f.readerValue() != null)
+ for (Iterator it = old.getFields().iterator(); it.hasNext();)
{
- f.readerValue().close();
+ Fieldable f = (Fieldable)it.next();
+ try
+ {
+ if (f.readerValue() != null)
+ {
+ f.readerValue().close();
+ }
+ else if (f instanceof LazyTextExtractorField)
+ {
+ LazyTextExtractorField field = (LazyTextExtractorField)f;
+ field.dispose();
+ }
+ }
+ catch (IOException ex)
+ {
+ log.warn("Exception while disposing index document: " + ex);
+ }
}
- else if (f instanceof LazyTextExtractorField)
- {
- LazyTextExtractorField field = (LazyTextExtractorField)f;
- field.dispose();
- }
+ return null;
}
- catch (IOException ex)
- {
- log.warn("Exception while disposing index document: " + ex);
- }
- }
+ });
}
/**
@@ -147,16 +157,23 @@
* @throws IOException if an error occurs while closing or releasing the
* index reader.
*/
- public static void closeOrRelease(IndexReader reader) throws IOException
+ public static void closeOrRelease(final IndexReader reader) throws IOException
{
- if (reader instanceof ReleaseableIndexReader)
+ SecurityHelper.doPriviledgedIOExceptionAction(new
PrivilegedExceptionAction<Object>()
{
- ((ReleaseableIndexReader)reader).release();
- }
- else
- {
- reader.close();
- }
+ public Object run() throws Exception
+ {
+ if (reader instanceof ReleaseableIndexReader)
+ {
+ ((ReleaseableIndexReader)reader).release();
+ }
+ else
+ {
+ reader.close();
+ }
+ return null;
+ }
+ });
}
/**
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/VolatileIndex.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/VolatileIndex.java 2010-06-15
09:58:52 UTC (rev 2598)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/core/query/lucene/VolatileIndex.java 2010-06-15
10:21:46 UTC (rev 2599)
@@ -29,147 +29,166 @@
/**
* Implements an in-memory index with a pending buffer.
*/
-class VolatileIndex extends AbstractIndex {
+class VolatileIndex extends AbstractIndex
+{
- /**
- * Default value for {@link #bufferSize}.
- */
- private static final int DEFAULT_BUFFER_SIZE = 10;
+ /**
+ * Default value for {@link #bufferSize}.
+ */
+ private static final int DEFAULT_BUFFER_SIZE = 10;
- /**
- * Map of pending documents to add to the index
- */
- private final Map pending = new LinkedMap();
+ /**
+ * Map of pending documents to add to the index
+ */
+ private final Map pending = new LinkedMap();
- /**
- * Number of documents that are buffered before they are added to the index.
- */
- private int bufferSize = DEFAULT_BUFFER_SIZE;
+ /**
+ * Number of documents that are buffered before they are added to the index.
+ */
+ private int bufferSize = DEFAULT_BUFFER_SIZE;
- /**
- * The number of documents in this index.
- */
- private int numDocs = 0;
+ /**
+ * The number of documents in this index.
+ */
+ private int numDocs = 0;
- /**
- * Creates a new <code>VolatileIndex</code> using an
<code>analyzer</code>.
- *
- * @param analyzer the analyzer to use.
- * @param similarity the similarity implementation.
- * @param indexingQueue the indexing queue.
- * @throws IOException if an error occurs while opening the index.
- */
- VolatileIndex(Analyzer analyzer,
- Similarity similarity,
- IndexingQueue indexingQueue) throws IOException {
- super(analyzer, similarity, new RAMDirectory(), null, indexingQueue);
- }
+ /**
+ * Creates a new <code>VolatileIndex</code> using an
<code>analyzer</code>.
+ *
+ * @param analyzer the analyzer to use.
+ * @param similarity the similarity implementation.
+ * @param indexingQueue the indexing queue.
+ * @throws IOException if an error occurs while opening the index.
+ */
+ VolatileIndex(Analyzer analyzer, Similarity similarity, IndexingQueue indexingQueue)
throws IOException
+ {
+ super(analyzer, similarity, new RAMDirectory(), null, indexingQueue);
+ }
- /**
- * Overwrites the default implementation by adding the documents to a
- * pending list and commits the pending list if needed.
- *
- * @param docs the documents to add to the index.
- * @throws IOException if an error occurs while writing to the index.
- */
- void addDocuments(Document[] docs) throws IOException {
- for (int i = 0; i < docs.length; i++) {
- Document old = (Document) pending.put(docs[i].get(FieldNames.UUID),
docs[i]);
- if (old != null) {
- Util.disposeDocument(old);
- }
- if (pending.size() >= bufferSize) {
- commitPending();
- }
- numDocs++;
- }
- invalidateSharedReader();
- }
+ /**
+ * Overwrites the default implementation by adding the documents to a
+ * pending list and commits the pending list if needed.
+ *
+ * @param docs the documents to add to the index.
+ * @throws IOException if an error occurs while writing to the index.
+ */
+ @Override
+ void addDocuments(Document[] docs) throws IOException
+ {
+ for (int i = 0; i < docs.length; i++)
+ {
+ Document old = (Document)pending.put(docs[i].get(FieldNames.UUID), docs[i]);
+ if (old != null)
+ {
+ Util.disposeDocument(old);
+ }
+ if (pending.size() >= bufferSize)
+ {
+ commitPending();
+ }
+ numDocs++;
+ }
+ invalidateSharedReader();
+ }
- /**
- * Overwrites the default implementation to remove the document from the
- * pending list if it is present or simply calls
<code>super.removeDocument()</code>.
- *
- * @param idTerm the uuid term of the document to remove.
- * @return the number of deleted documents
- * @throws IOException if an error occurs while removing the document from
- * the index.
- */
- int removeDocument(Term idTerm) throws IOException {
- Document doc = (Document) pending.remove(idTerm.text());
- int num;
- if (doc != null) {
- Util.disposeDocument(doc);
- // pending document has been removed
- num = 1;
- } else {
- // remove document from index
- num = super.getIndexReader().deleteDocuments(idTerm);
- }
- numDocs -= num;
- return num;
- }
+ /**
+ * Overwrites the default implementation to remove the document from the
+ * pending list if it is present or simply calls
<code>super.removeDocument()</code>.
+ *
+ * @param idTerm the uuid term of the document to remove.
+ * @return the number of deleted documents
+ * @throws IOException if an error occurs while removing the document from
+ * the index.
+ */
+ @Override
+ int removeDocument(Term idTerm) throws IOException
+ {
+ Document doc = (Document)pending.remove(idTerm.text());
+ int num;
+ if (doc != null)
+ {
+ Util.disposeDocument(doc);
+ // pending document has been removed
+ num = 1;
+ }
+ else
+ {
+ // remove document from index
+ num = super.removeDocument(idTerm);
+ }
+ numDocs -= num;
+ return num;
+ }
- /**
- * Returns the number of valid documents in this index.
- *
- * @return the number of valid documents in this index.
- */
- int getNumDocuments() {
- return numDocs;
- }
+ /**
+ * Returns the number of valid documents in this index.
+ *
+ * @return the number of valid documents in this index.
+ */
+ int getNumDocuments()
+ {
+ return numDocs;
+ }
- /**
- * Overwrites the implementation in {@link AbstractIndex} to trigger
- * commit of pending documents to index.
- * @return the index reader for this index.
- * @throws IOException if an error occurs building a reader.
- */
- protected synchronized CommittableIndexReader getIndexReader() throws IOException {
- commitPending();
- return super.getIndexReader();
- }
+ /**
+ * Overwrites the implementation in {@link AbstractIndex} to trigger
+ * commit of pending documents to index.
+ * @return the index reader for this index.
+ * @throws IOException if an error occurs building a reader.
+ */
+ @Override
+ protected synchronized CommittableIndexReader getIndexReader() throws IOException
+ {
+ commitPending();
+ return super.getIndexReader();
+ }
- /**
- * Overwrites the implementation in {@link AbstractIndex} to commit
- * pending documents.
- * @param optimize if <code>true</code> the index is optimized after the
- * commit.
- */
- protected synchronized void commit(boolean optimize) throws IOException {
- commitPending();
- super.commit(optimize);
- }
+ /**
+ * Overwrites the implementation in {@link AbstractIndex} to commit
+ * pending documents.
+ * @param optimize if <code>true</code> the index is optimized after the
+ * commit.
+ */
+ @Override
+ protected synchronized void commit(boolean optimize) throws IOException
+ {
+ commitPending();
+ super.commit(optimize);
+ }
- /**
- * {@inheritDoc}
- */
- long getRamSizeInBytes() {
- return super.getRamSizeInBytes() + ((RAMDirectory)
getDirectory()).sizeInBytes();
- }
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ long getRamSizeInBytes()
+ {
+ return super.getRamSizeInBytes() + ((RAMDirectory)getDirectory()).sizeInBytes();
+ }
- /**
- * Sets a new buffer size for pending documents to add to the index.
- * Higher values consume more memory, but help to avoid multiple index
- * cycles when a node is changed / saved multiple times.
- *
- * @param size the new buffer size.
- */
- void setBufferSize(int size) {
- bufferSize = size;
- }
+ /**
+ * Sets a new buffer size for pending documents to add to the index.
+ * Higher values consume more memory, but help to avoid multiple index
+ * cycles when a node is changed / saved multiple times.
+ *
+ * @param size the new buffer size.
+ */
+ void setBufferSize(int size)
+ {
+ bufferSize = size;
+ }
- /**
- * Commits pending documents to the index.
- *
- * @throws IOException if committing pending documents fails.
- */
- private void commitPending() throws IOException {
- if (pending.isEmpty()) {
- return;
- }
- super.addDocuments((Document[]) pending.values().toArray(
- new Document[pending.size()]));
- pending.clear();
- }
+ /**
+ * Commits pending documents to the index.
+ *
+ * @throws IOException if committing pending documents fails.
+ */
+ private void commitPending() throws IOException
+ {
+ if (pending.isEmpty())
+ {
+ return;
+ }
+ super.addDocuments((Document[])pending.values().toArray(new
Document[pending.size()]));
+ pending.clear();
+ }
}
Modified:
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/SecurityHelper.java
===================================================================
---
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/SecurityHelper.java 2010-06-15
09:58:52 UTC (rev 2598)
+++
jcr/trunk/exo.jcr.component.core/src/main/java/org/exoplatform/services/jcr/impl/util/SecurityHelper.java 2010-06-15
10:21:46 UTC (rev 2599)
@@ -18,13 +18,14 @@
*/
package org.exoplatform.services.jcr.impl.util;
-import java.io.File;
import java.io.IOException;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
+import javax.jcr.RepositoryException;
+
/**
* Helps running code in privileged
*
@@ -68,33 +69,50 @@
}
/**
- * Launches action in privileged mode. Can throw only runtime exceptions.
+ * Launches action in privileged mode. Can throw only repository exception.
*
* @param <E>
* @param action
* @return
- * @throws IOException
+ * @throws RepositoryException
*/
- public static <E> E doPriviledgedAction(PrivilegedAction<E> action)
+ public static <E> E
doPriviledgedRepositoryExceptionAction(PrivilegedExceptionAction<E> action)
+ throws RepositoryException
{
- return AccessController.doPrivileged(action);
+ try
+ {
+ return AccessController.doPrivileged(action);
+ }
+ catch (PrivilegedActionException pae)
+ {
+ Throwable cause = pae.getCause();
+ if (cause instanceof RepositoryException)
+ {
+ throw (RepositoryException)cause;
+ }
+ else if (cause instanceof RuntimeException)
+ {
+ throw (RuntimeException)cause;
+ }
+ else
+ {
+ throw new RuntimeException(cause);
+ }
+ }
}
+
/**
- * Gets system property in privileged mode
+ * Launches action in privileged mode. Can throw only runtime exceptions.
*
- * @param name
+ * @param <E>
+ * @param action
* @return
+ * @throws IOException
*/
- public static String getSystemProperty(final String name)
+ public static <E> E doPriviledgedAction(PrivilegedAction<E> action)
{
- return SecurityHelper.doPriviledgedAction(new PrivilegedAction<String>()
- {
- public String run()
- {
- return System.getProperty(name);
- }
- });
+ return AccessController.doPrivileged(action);
}
}