You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by re...@apache.org on 2012/02/10 15:08:00 UTC

svn commit: r1242775 - in /jackrabbit/trunk/jackrabbit-core/src: main/java/org/apache/jackrabbit/core/persistence/bundle/ main/java/org/apache/jackrabbit/core/persistence/check/ test/java/org/apache/jackrabbit/core/

Author: reschke
Date: Fri Feb 10 14:08:00 2012
New Revision: 1242775

URL: http://svn.apache.org/viewvc?rev=1242775&view=rev
Log:
JCR-3233: Provide callback for consistency checker (work-in-progress)

Added:
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/check/ConsistencyCheckListener.java   (with props)
Modified:
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/AbstractBundlePersistenceManager.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/ConsistencyCheckerImpl.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/check/ConsistencyChecker.java
    jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/TestHelper.java

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/AbstractBundlePersistenceManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/AbstractBundlePersistenceManager.java?rev=1242775&r1=1242774&r2=1242775&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/AbstractBundlePersistenceManager.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/AbstractBundlePersistenceManager.java Fri Feb 10 14:08:00 2012
@@ -41,6 +41,7 @@ import org.apache.jackrabbit.core.persis
 import org.apache.jackrabbit.core.persistence.IterablePersistenceManager;
 import org.apache.jackrabbit.core.persistence.PMContext;
 import org.apache.jackrabbit.core.persistence.PersistenceManager;
+import org.apache.jackrabbit.core.persistence.check.ConsistencyCheckListener;
 import org.apache.jackrabbit.core.persistence.check.ConsistencyChecker;
 import org.apache.jackrabbit.core.persistence.check.ConsistencyReport;
 import org.apache.jackrabbit.core.persistence.util.BLOBStore;
@@ -784,7 +785,7 @@ public abstract class AbstractBundlePers
      */
     public void checkConsistency(String[] uuids, boolean recursive, boolean fix) {
         try {
-            ConsistencyCheckerImpl cs = new ConsistencyCheckerImpl(this);
+            ConsistencyCheckerImpl cs = new ConsistencyCheckerImpl(this, null);
             cs.check(uuids, recursive, fix, null);
         } catch (RepositoryException ex) {
             log.error("While running consistency check.", ex);
@@ -794,8 +795,10 @@ public abstract class AbstractBundlePers
     /**
      * {@inheritDoc}
      */
-    public ConsistencyReport check(String[] uuids, boolean recursive, boolean fix, String lostNFoundId) throws RepositoryException {
-        ConsistencyCheckerImpl cs = new ConsistencyCheckerImpl(this);
+    public ConsistencyReport check(String[] uuids, boolean recursive,
+            boolean fix, String lostNFoundId, ConsistencyCheckListener listener)
+            throws RepositoryException {
+        ConsistencyCheckerImpl cs = new ConsistencyCheckerImpl(this, listener);
         return cs.check(uuids, recursive, fix, lostNFoundId);
     }
 

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/ConsistencyCheckerImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/ConsistencyCheckerImpl.java?rev=1242775&r1=1242774&r2=1242775&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/ConsistencyCheckerImpl.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/ConsistencyCheckerImpl.java Fri Feb 10 14:08:00 2012
@@ -26,7 +26,7 @@ import java.util.Set;
 import javax.jcr.RepositoryException;
 
 import org.apache.jackrabbit.core.id.NodeId;
-import org.apache.jackrabbit.core.persistence.check.ConsistencyChecker;
+import org.apache.jackrabbit.core.persistence.check.ConsistencyCheckListener;
 import org.apache.jackrabbit.core.persistence.check.ConsistencyReport;
 import org.apache.jackrabbit.core.persistence.check.ConsistencyReportImpl;
 import org.apache.jackrabbit.core.persistence.check.ReportItem;
@@ -39,35 +39,42 @@ import org.apache.jackrabbit.spi.commons
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class ConsistencyCheckerImpl implements ConsistencyChecker {
+public class ConsistencyCheckerImpl {
 
     /** the default logger */
-    private static Logger log = LoggerFactory.getLogger(ConsistencyCheckerImpl.class);
+    private static Logger log = LoggerFactory
+            .getLogger(ConsistencyCheckerImpl.class);
+
+    private final AbstractBundlePersistenceManager pm;
+
+    private final ConsistencyCheckListener listener;
 
-    private AbstractBundlePersistenceManager pm;
-    
     private static final NameFactory NF = NameFactoryImpl.getInstance();
 
     // process 64K nodes at once
     private static int NODESATONCE = 1024 * 64;
 
-    public ConsistencyCheckerImpl(AbstractBundlePersistenceManager pm) {
+    public ConsistencyCheckerImpl(AbstractBundlePersistenceManager pm,
+            ConsistencyCheckListener listener) {
         this.pm = pm;
+        this.listener = listener;
     }
 
-    public ConsistencyReport check(String[] uuids, boolean recursive, boolean fix, String lostNFoundId)
-            throws RepositoryException {
+    public ConsistencyReport check(String[] uuids, boolean recursive,
+            boolean fix, String lostNFoundId) throws RepositoryException {
         Set<ReportItem> reports = new HashSet<ReportItem>();
 
         long tstart = System.currentTimeMillis();
-        int total = internalCheckConsistency(uuids, recursive, fix, reports, lostNFoundId);
+        int total = internalCheckConsistency(uuids, recursive, fix, reports,
+                lostNFoundId);
         long elapsed = System.currentTimeMillis() - tstart;
 
         return new ConsistencyReportImpl(total, elapsed, reports);
     }
-    
-    private int internalCheckConsistency(String[] uuids, boolean recursive, boolean fix, Set<ReportItem> reports,
-            String lostNFoundId) throws RepositoryException {
+
+    private int internalCheckConsistency(String[] uuids, boolean recursive,
+            boolean fix, Set<ReportItem> reports, String lostNFoundId)
+            throws RepositoryException {
         int count = 0;
         Collection<NodePropBundle> modifications = new ArrayList<NodePropBundle>();
         Set<NodeId> orphaned = new HashSet<NodeId>();
@@ -79,14 +86,17 @@ public class ConsistencyCheckerImpl impl
                 NodeId tmpid = new NodeId(lostNFoundId);
                 NodePropBundle lfBundle = pm.loadBundle(tmpid);
                 if (lfBundle == null) {
-                    log.error("specified 'lost+found' node does not exist");
-                } else if (!NameConstants.NT_UNSTRUCTURED.equals(lfBundle.getNodeTypeName())) {
-                    log.error("specified 'lost+found' node is not of type nt:unstructured");
+                    error(lostNFoundId,
+                            "specified 'lost+found' node does not exist");
+                } else if (!NameConstants.NT_UNSTRUCTURED.equals(lfBundle
+                        .getNodeTypeName())) {
+                    error(lostNFoundId,
+                            "specified 'lost+found' node is not of type nt:unstructured");
                 } else {
                     lostNFound = lfBundle.getId();
                 }
             } catch (Exception ex) {
-                log.error("finding 'lost+found' folder", ex);
+                error(lostNFoundId, "finding 'lost+found' folder", ex);
             }
         }
 
@@ -96,20 +106,24 @@ public class ConsistencyCheckerImpl impl
 
                 while (!allIds.isEmpty()) {
                     NodeId lastId = null;
-                    
+
                     for (NodeId id : allIds) {
                         lastId = id;
                         try {
                             // parse and check bundle
                             NodePropBundle bundle = pm.loadBundle(id);
                             if (bundle == null) {
-                                log.error("No bundle found for id '" + id + "'");
+                                error(id.toString(), "No bundle found for id '"
+                                        + id + "'");
                             } else {
-                                checkBundleConsistency(id, bundle, fix, modifications, lostNFound, orphaned, reports);
+                                checkBundleConsistency(id, bundle, fix,
+                                        modifications, lostNFound, orphaned,
+                                        reports);
 
                                 count++;
-                                if (count % 1000 == 0) {
-                                    log.info(pm + ": checked " + count + " bundles...");
+                                if (count % 1000 == 0 && listener == null) {
+                                    log.info(pm + ": checked " + count
+                                            + " bundles...");
                                 }
                             }
                         } catch (ItemStateException e) {
@@ -118,7 +132,7 @@ public class ConsistencyCheckerImpl impl
                         }
                     }
 
-                    if (! allIds.isEmpty()) {
+                    if (!allIds.isEmpty()) {
                         allIds = pm.getAllNodeIds(lastId, NODESATONCE);
                     }
                 }
@@ -130,9 +144,9 @@ public class ConsistencyCheckerImpl impl
 
             // 1) convert uuid array to modifiable list
             // 2) for each uuid do
-            //     a) load node bundle
-            //     b) check bundle, store any bundle-to-be-modified in collection
-            //     c) if recursive, add child uuids to list of uuids
+            // a) load node bundle
+            // b) check bundle, store any bundle-to-be-modified in collection
+            // c) if recursive, add child uuids to list of uuids
 
             List<NodeId> idList = new ArrayList<NodeId>(uuids.length);
             // convert uuid string array to list of UUID objects
@@ -140,11 +154,14 @@ public class ConsistencyCheckerImpl impl
                 try {
                     idList.add(new NodeId(uuids[i]));
                 } catch (IllegalArgumentException e) {
-                    log.error("Invalid id for consistency check, skipping: '" + uuids[i] + "': " + e);
+                    error(uuids[i],
+                            "Invalid id for consistency check, skipping: '"
+                                    + uuids[i] + "': " + e);
                 }
             }
-            
-            // iterate over UUIDs (including ones that are newly added inside the loop!)
+
+            // iterate over UUIDs (including ones that are newly added inside
+            // the loop!)
             for (int i = 0; i < idList.size(); i++) {
                 NodeId id = idList.get(i);
                 try {
@@ -152,39 +169,48 @@ public class ConsistencyCheckerImpl impl
                     NodePropBundle bundle = pm.loadBundle(id);
 
                     if (bundle == null) {
-                        log.error("No bundle found for id '" + id + "'");
-                    }
-                    else {
-                        checkBundleConsistency(id, bundle, fix, modifications, lostNFound, orphaned, reports);
+                        if (!isVirtualNode(id)) {
+                            error(id.toString(), "No bundle found for id '"
+                                    + id + "'");
+                        }
+                    } else {
+                        checkBundleConsistency(id, bundle, fix, modifications,
+                                lostNFound, orphaned, reports);
 
                         if (recursive) {
-                            for (NodePropBundle.ChildNodeEntry entry : bundle.getChildNodeEntries()) {
+                            for (NodePropBundle.ChildNodeEntry entry : bundle
+                                    .getChildNodeEntries()) {
                                 idList.add(entry.getId());
                             }
                         }
 
                         count++;
-                        if (count % 1000 == 0) {
-                            log.info(pm + ": checked " + count + "/" + idList.size() + " bundles...");
+                        if (count % 1000 == 0 && listener == null) {
+                            log.info(pm + ": checked " + count + "/"
+                                    + idList.size() + " bundles...");
                         }
                     }
                 } catch (ItemStateException e) {
-                    // problem already logged (loadBundle called with logDetailedErrors=true)
+                    // problem already logged (loadBundle called with
+                    // logDetailedErrors=true)
                 }
             }
         }
 
         // repair collected broken bundles
         if (fix && !modifications.isEmpty()) {
-            log.info(pm + ": Fixing " + modifications.size() + " inconsistent bundle(s)...");
+            info(null, pm + ": Fixing " + modifications.size()
+                    + " inconsistent bundle(s)...");
             for (NodePropBundle bundle : modifications) {
                 try {
-                    log.info(pm + ": Fixing bundle '" + bundle.getId() + "'");
+                    info(bundle.getId().toString(), pm + ": Fixing bundle '"
+                            + bundle.getId() + "'");
                     bundle.markOld(); // use UPDATE instead of INSERT
                     pm.storeBundle(bundle);
                     pm.evictBundle(bundle.getId());
                 } catch (ItemStateException e) {
-                    log.error(pm + ": Error storing fixed bundle: " + e);
+                    error(bundle.getId().toString(), pm
+                            + ": Error storing fixed bundle: " + e);
                 }
             }
         }
@@ -194,20 +220,23 @@ public class ConsistencyCheckerImpl impl
             try {
                 NodePropBundle lfBundle = pm.loadBundle(lostNFound);
                 if (lfBundle == null) {
-                    log.error("specified 'lost+found' node does not exist");
-                } else if (!NameConstants.NT_UNSTRUCTURED.equals(lfBundle.getNodeTypeName())) {
-                    log.error("specified 'lost+found' node is not of type nt:unstructered");
+                    error(lostNFoundId, "specified 'lost+found' node does not exist");
+                } else if (!NameConstants.NT_UNSTRUCTURED.equals(lfBundle
+                        .getNodeTypeName())) {
+                    error(lostNFoundId, "specified 'lost+found' node is not of type nt:unstructered");
                 } else {
                     lfBundle.markOld();
                     for (NodeId orphan : orphaned) {
-                        String nodeName = orphan + "-" + System.currentTimeMillis();
-                        lfBundle.addChildNodeEntry(NF.create("", nodeName), orphan);
+                        String nodeName = orphan + "-"
+                                + System.currentTimeMillis();
+                        lfBundle.addChildNodeEntry(NF.create("", nodeName),
+                                orphan);
                     }
                     pm.storeBundle(lfBundle);
                     pm.evictBundle(lfBundle.getId());
                 }
             } catch (Exception ex) {
-                log.error("trying orphan adoption", ex);
+                error(null, "trying orphan adoption", ex);
             }
         }
 
@@ -219,29 +248,37 @@ public class ConsistencyCheckerImpl impl
     /**
      * Checks a single bundle for inconsistencies, ie. inexistent child nodes
      * and inexistent parents.
-     *
-     * @param id node id for the bundle to check
-     * @param bundle the bundle to check
-     * @param fix if <code>true</code>, repair things that can be repaired
-     * @param modifications if <code>fix == true</code>, collect the repaired
-     * {@linkplain NodePropBundle bundles} here
+     * 
+     * @param id
+     *            node id for the bundle to check
+     * @param bundle
+     *            the bundle to check
+     * @param fix
+     *            if <code>true</code>, repair things that can be repaired
+     * @param modifications
+     *            if <code>fix == true</code>, collect the repaired
+     *            {@linkplain NodePropBundle bundles} here
      */
     private void checkBundleConsistency(NodeId id, NodePropBundle bundle,
-                                          boolean fix, Collection<NodePropBundle> modifications,
-                                          NodeId lostNFoundId, Set<NodeId> orphaned, Set<ReportItem> reports) {
-        //log.info(name + ": checking bundle '" + id + "'");
-
-        // skip all system nodes except root node
-        if (id.toString().endsWith("babecafebabe")
-                && !id.toString().equals("cafebabe-cafe-babe-cafe-babecafebabe")) {
+            boolean fix, Collection<NodePropBundle> modifications,
+            NodeId lostNFoundId, Set<NodeId> orphaned, Set<ReportItem> reports) {
+        // log.info(name + ": checking bundle '" + id + "'");
+
+        // skip all virtual nodes
+        if (isVirtualNode(id)) {
             return;
         }
 
+        if (listener != null) {
+            listener.startCheck(id.toString());
+        }
+
         // look at the node's children
         Collection<NodePropBundle.ChildNodeEntry> missingChildren = new ArrayList<NodePropBundle.ChildNodeEntry>();
         for (NodePropBundle.ChildNodeEntry entry : bundle.getChildNodeEntries()) {
 
-            // skip check for system nodes (root, system root, version storage, node types)
+            // skip check for system nodes (root, system root, version storage,
+            // node types)
             if (entry.getId().toString().endsWith("babecafebabe")) {
                 continue;
             }
@@ -251,8 +288,10 @@ public class ConsistencyCheckerImpl impl
                 NodePropBundle child = pm.loadBundle(entry.getId());
                 String message = null;
                 if (child == null) {
-                    message = "NodeState '" + id + "' references inexistent child" + " '"
-                            + entry.getName() + "' with id " + "'" + entry.getId() + "'";
+                    message = "NodeState '" + id
+                            + "' references inexistent child" + " '"
+                            + entry.getName() + "' with id " + "'"
+                            + entry.getId() + "'";
                     log.error(message);
                     missingChildren.add(entry);
                 } else {
@@ -261,7 +300,8 @@ public class ConsistencyCheckerImpl impl
                         message = "ChildNode has invalid parent id: <null>";
                         log.error(message);
                     } else if (!cp.equals(id)) {
-                        message = "ChildNode has invalid parent id: '" + cp + "' (instead of '" + id + "')";
+                        message = "ChildNode has invalid parent id: '" + cp
+                                + "' (instead of '" + id + "')";
                         log.error(message);
                     }
                 }
@@ -269,7 +309,8 @@ public class ConsistencyCheckerImpl impl
                     addMessage(reports, id, message);
                 }
             } catch (ItemStateException e) {
-                // problem already logged (loadBundle called with logDetailedErrors=true)
+                // problem already logged (loadBundle called with
+                // logDetailedErrors=true)
                 addMessage(reports, id, e.getMessage());
             }
         }
@@ -287,9 +328,11 @@ public class ConsistencyCheckerImpl impl
             // skip root nodes (that point to itself)
             if (parentId != null && !id.toString().endsWith("babecafebabe")) {
                 NodePropBundle parentBundle = pm.loadBundle(parentId);
-                
+
                 if (parentBundle == null) {
-                    String message = "NodeState '" + id + "' references inexistent parent id '" + parentId + "'";
+                    String message = "NodeState '" + id
+                            + "' references inexistent parent id '" + parentId
+                            + "'";
                     log.error(message);
                     addMessage(reports, id, message);
                     orphaned.add(id);
@@ -297,19 +340,21 @@ public class ConsistencyCheckerImpl impl
                         bundle.setParentId(lostNFoundId);
                         modifications.add(bundle);
                     }
-                }
-                else {
+                } else {
                     boolean found = false;
 
-                    for (NodePropBundle.ChildNodeEntry entry : parentBundle.getChildNodeEntries()) {
-                        if (entry.getId().equals(id)){
+                    for (NodePropBundle.ChildNodeEntry entry : parentBundle
+                            .getChildNodeEntries()) {
+                        if (entry.getId().equals(id)) {
                             found = true;
                             break;
                         }
                     }
 
                     if (!found) {
-                        String message = "NodeState '" + id + "' is not referenced by its parent node '" + parentId + "'";
+                        String message = "NodeState '" + id
+                                + "' is not referenced by its parent node '"
+                                + parentId + "'";
                         log.error(message);
                         addMessage(reports, id, message);
 
@@ -317,22 +362,77 @@ public class ConsistencyCheckerImpl impl
                         int r = new Random().nextInt();
                         int n = l + r;
                         String nodeName = Integer.toHexString(n);
-                        parentBundle.addChildNodeEntry(NF.create("{}" + nodeName), id);
-                        log.info("NodeState '" + id + "' adds itself to its parent node '" + parentId + "' with a new name '" + nodeName + "'");
+                        parentBundle.addChildNodeEntry(
+                                NF.create("{}" + nodeName), id);
+                        log.info("NodeState '" + id
+                                + "' adds itself to its parent node '"
+                                + parentId + "' with a new name '" + nodeName
+                                + "'");
                         modifications.add(parentBundle);
                     }
                 }
             }
         } catch (ItemStateException e) {
-            String message = "Error reading node '" + parentId + "' (parent of '" + id + "'): " + e;
+            String message = "Error reading node '" + parentId
+                    + "' (parent of '" + id + "'): " + e;
             log.error(message);
             addMessage(reports, id, message);
         }
     }
 
+    /**
+     * @return whether the id is for a virtual node (not needing checking)
+     */
+    private boolean isVirtualNode(NodeId id) {
+        String s = id.toString();
+        if ("cafebabe-cafe-babe-cafe-babecafebabe".equals(s)) {
+            // root node isn't virtual
+            return false;
+        }
+        else {
+            // all other system nodes are
+            return s.endsWith("babecafebabe");
+        }
+    }
+
+
     private void addMessage(Set<ReportItem> reports, NodeId id, String message) {
-        if (reports != null) {
-            reports.add(new ReportItemImpl(id.toString(), message));
+
+        if (reports != null || listener != null) {
+            ReportItem ri = new ReportItemImpl(id.toString(), message);
+
+            if (reports != null) {
+                reports.add(ri);
+            }
+            if (listener != null) {
+                listener.report(ri);
+            }
+        }
+    }
+
+    private void info(String id, String message) {
+        if (this.listener == null) {
+            String idstring = id == null ? "" : ("Node " + id + ": ");
+            log.info(idstring + message);
+        } else {
+            listener.info(id, message);
+        }
+    }
+
+    private void error(String id, String message) {
+        if (this.listener == null) {
+            String idstring = id == null ? "" : ("Node " + id + ": ");
+            log.error(idstring + message);
+        } else {
+            listener.error(id, message);
+        }
+    }
+
+    private void error(String id, String message, Throwable ex) {
+        String idstring = id == null ? "" : ("Node " + id + ": ");
+        log.error(idstring + message, ex);
+        if (listener != null) {
+            listener.error(id, message);
         }
     }
 }

Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/check/ConsistencyCheckListener.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/check/ConsistencyCheckListener.java?rev=1242775&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/check/ConsistencyCheckListener.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/check/ConsistencyCheckListener.java Fri Feb 10 14:08:00 2012
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.core.persistence.check;
+
+public interface ConsistencyCheckListener {
+
+    /**
+     * Called when checking of a node starts
+     * @param id node ID
+     */
+    public void startCheck(String id);
+
+    /**
+     * Called when there's a consistency problem to be reported
+     * @param item problem report
+     */
+    public void report(ReportItem item);
+
+    /**
+     * Called on errors with the check procedure
+     * @param id node id (can be <code>null</code>)
+     * @param message
+     */
+    public void error(String id, String message);
+
+    /**
+     * Called on progress with the check procedure
+     * @param id node id (can be <code>null</code>)
+     * @param message
+     */
+    public void info(String id, String message);
+}

Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/check/ConsistencyCheckListener.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/check/ConsistencyChecker.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/check/ConsistencyChecker.java?rev=1242775&r1=1242774&r2=1242775&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/check/ConsistencyChecker.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/check/ConsistencyChecker.java Fri Feb 10 14:08:00 2012
@@ -49,7 +49,10 @@ public interface ConsistencyChecker {
      *            in which case orphaned nodes will not get moved); this node
      *            should be of a node type that allows adding arbitrary child
      *            nodes
+     * @param listener
+     *            to be called on each node that was checked (may be <code>null</code>)
      */
-    ConsistencyReport check(String[] uuids, boolean recursive, boolean fix, String lostNFoundId)
+    ConsistencyReport check(String[] uuids, boolean recursive, boolean fix,
+            String lostNFoundId, ConsistencyCheckListener listener)
             throws RepositoryException;
 }

Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/TestHelper.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/TestHelper.java?rev=1242775&r1=1242774&r2=1242775&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/TestHelper.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/TestHelper.java Fri Feb 10 14:08:00 2012
@@ -69,7 +69,7 @@ public class TestHelper {
             if (!(pm instanceof ConsistencyChecker)) {
                 throw new NotExecutableException();
             } else {
-                return ((ConsistencyChecker) pm).check(null, true, runFix, lostNFoundId);
+                return ((ConsistencyChecker) pm).check(null, true, runFix, lostNFoundId, null);
             }
         }
     }
@@ -97,7 +97,7 @@ public class TestHelper {
             if (!(pm instanceof ConsistencyChecker)) {
                 throw new NotExecutableException();
             } else {
-                return ((ConsistencyChecker) pm).check(null, true, runFix, lostNFoundId);
+                return ((ConsistencyChecker) pm).check(null, true, runFix, lostNFoundId, null);
             }
         }
     }