public void checkIndex(ItemDataConsumer itemStateManager, boolean isSystem, final InspectionReport report)
      throws RepositoryException, IOException
   {

      // The visitor, that performs item enumeration and checks if all nodes present in 
      // persistent layer are indexed. Also collects the list of all indexed nodes
      // to optimize the process of backward check, when index is traversed to find
      // references to already deleted nodes
      class ItemDataIndexConsistencyVisitor extends ItemDataTraversingVisitor
      {
         private final IndexReader indexReader;

         private final Set<String> indexedNodes = new HashSet<String>();

         /**
          * @param dataManager
          */
         public ItemDataIndexConsistencyVisitor(ItemDataConsumer dataManager, IndexReader indexReader)
         {
            super(dataManager);
            this.indexReader = indexReader;
         }

         /**
          * {@inheritDoc}
          */
         @Override
         protected void entering(PropertyData property, int level) throws RepositoryException
         {
            // ignore properties;
         }

         /**
          * {@inheritDoc}
          */
         @Override
         protected void entering(NodeData node, int level) throws RepositoryException
         {
            // process node uuids one-by-one
            try
            {
               String uuid = node.getIdentifier();
               TermDocs docs = indexReader.termDocs(new Term(FieldNames.UUID, uuid));

               if (docs.next())
               {
                  indexedNodes.add(uuid);
                  docs.doc();
                  if (docs.next())
                  {
                     //multiple entries
                     report.logComment("Multiple entires.");
                     report.logBrokenObjectAndSetInconsistency("ID=" + uuid);
                  }
               }
               else
               {
                  report.logComment("Not indexed.");
                  report.logBrokenObjectAndSetInconsistency("ID=" + uuid);
               }
            }
            catch (IOException e)
            {
               throw new RepositoryException(e.getMessage(), e);
            }
         }

         @Override
         protected void leaving(PropertyData property, int level) throws RepositoryException
         {
            // ignore properties
         }

         @Override
         protected void leaving(NodeData node, int level) throws RepositoryException
         {
            // do nothing
         }

         @Override
         protected void visitChildProperties(NodeData node) throws RepositoryException
         {
            //do nothing
         }

         public Set<String> getIndexedNodes()
         {
            return indexedNodes;
         }
      }

      // check relation Persistent Layer -> Index
      // If current workspace is system, then need to invoke reader correspondent to system index
      ensureFlushed();
      if (isSystem)
      {
         if (getContext().getParentHandler() != null)
         {
            ((SearchIndex)getContext().getParentHandler()).ensureFlushed();
         }
      }
      IndexReader indexReader = getIndexReader(isSystem);
      try
      {
         ItemData root = itemStateManager.getItemData(Constants.ROOT_UUID);
         ItemDataIndexConsistencyVisitor visitor = new ItemDataIndexConsistencyVisitor(itemStateManager, indexReader);
         root.accept(visitor);

         Set<String> documentUUIDs = visitor.getIndexedNodes();

         // check relation Index -> Persistent Layer
         // find document that do not corresponds to real node
         // iterate on documents one-by-one
         for (int i = 0; i < indexReader.maxDoc(); i++)
         {
            if (indexReader.isDeleted(i))
            {
               continue;
            }
            final int currentIndex = i;
            Document d = indexReader.document(currentIndex, FieldSelectors.UUID);
            String uuid = d.get(FieldNames.UUID);
            if (!documentUUIDs.contains(uuid))
            {
               report.logComment("Document corresponds to removed node.");
               report.logBrokenObjectAndSetInconsistency("ID=" + uuid);
            }
         }
      }
      finally
      {
         Util.closeOrRelease(indexReader);
      }
   }
public void checkIndex ( ItemDataConsumer itemStateManager , boolean isSystem , final InspectionReport report ) throws RepositoryException , IOException { class ItemDataIndexConsistencyVisitor extends ItemDataTraversingVisitor { private final IndexReader indexReader ; private final Set < String > indexedNodes = new HashSet < String > ( ) ; public ItemDataIndexConsistencyVisitor ( ItemDataConsumer dataManager , IndexReader indexReader ) { super ( dataManager ) ; this . indexReader = indexReader ; } @ Override protected void entering ( PropertyData property , int level ) throws RepositoryException { } @ Override protected void entering ( NodeData node , int level ) throws RepositoryException { try { String uuid = node . getIdentifier ( ) ; TermDocs docs = indexReader . termDocs ( new Term ( FieldNames . UUID , uuid ) ) ; if ( docs . next ( ) ) { indexedNodes . add ( uuid ) ; docs . doc ( ) ; if ( docs . next ( ) ) { report . logComment ( "Multiple entires." ) ; report . logBrokenObjectAndSetInconsistency ( "ID=" + uuid ) ; } } else { report . logComment ( "Not indexed." ) ; report . logBrokenObjectAndSetInconsistency ( "ID=" + uuid ) ; } } catch ( IOException e ) { throw new RepositoryException ( e . getMessage ( ) , e ) ; } } @ Override protected void leaving ( PropertyData property , int level ) throws RepositoryException { } @ Override protected void leaving ( NodeData node , int level ) throws RepositoryException { } @ Override protected void visitChildProperties ( NodeData node ) throws RepositoryException { } public Set < String > getIndexedNodes ( ) { return indexedNodes ; } } ensureFlushed ( ) ; if ( isSystem ) { if ( getContext ( ) . getParentHandler ( ) != null ) { ( ( SearchIndex ) getContext ( ) . getParentHandler ( ) ) . ensureFlushed ( ) ; } } IndexReader indexReader = getIndexReader ( isSystem ) ; try { ItemData root = itemStateManager . getItemData ( Constants . ROOT_UUID ) ; ItemDataIndexConsistencyVisitor visitor = new ItemDataIndexConsistencyVisitor ( itemStateManager , indexReader ) ; root . accept ( visitor ) ; Set < String > documentUUIDs = visitor . getIndexedNodes ( ) ; for ( int i = 0 ; i < indexReader . maxDoc ( ) ; i ++ ) { if ( indexReader . isDeleted ( i ) ) { continue ; } final int currentIndex = i ; Document d = indexReader . document ( currentIndex , FieldSelectors . UUID ) ; String uuid = d . get ( FieldNames . UUID ) ; if ( ! documentUUIDs . contains ( uuid ) ) { report . logComment ( "Document corresponds to removed node." ) ; report . logBrokenObjectAndSetInconsistency ( "ID=" + uuid ) ; } } } finally { Util . closeOrRelease ( indexReader ) ; } }
{@inheritDoc}