/*
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package com.celements.iterator;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xwiki.model.reference.DocumentReference;

import com.celements.model.access.IModelAccessFacade;
import com.celements.model.access.exception.DocumentLoadException;
import com.celements.model.access.exception.DocumentNotExistsException;
import com.celements.web.service.IWebUtilsService;
import com.xpn.xwiki.XWikiContext;
import com.xpn.xwiki.doc.XWikiDocument;
import com.xpn.xwiki.web.Utils;

public class DocumentIterator implements Iterator<XWikiDocument>, Iterable<XWikiDocument> {

  private static Logger _LOGGER = LoggerFactory.getLogger(XObjectIterator.class);

  private List<String> _docList;

  private Iterator<String> _docIterator;

  private XWikiDocument _currentDoc;

  /**
   * Constructor
   */
  public DocumentIterator() {
  }

  /**
   * Constructor
   *
   * @param XWiki
   *          context
   * @deprecated instead use DocumentIterator()
   */
  @Deprecated
  public DocumentIterator(XWikiContext context) {
  }

  /**
   * Checks if iterator has a next object
   */
  @Override
  public boolean hasNext() {
    while ((_currentDoc == null) && (getDocIterator().hasNext())) {
      moveToNextDoc();
    }
    return (_currentDoc != null);
  }

  /**
   * Returns the next element in the iteration.
   *
   * @return the next element in the iteration.
   * @exception NoSuchElementException
   *              iteration has no more elements.
   */
  @Override
  public XWikiDocument next() {
    if (hasNext()) {
      XWikiDocument theCurrentDoc = _currentDoc;
      _currentDoc = null;
      return theCurrentDoc;
    }
    throw new NoSuchElementException();
  }

  /**
   * Moves to the next document
   */
  void moveToNextDoc() {
    try {
      String fullname;
      DocumentReference docRef;
      do {
        fullname = getDocIterator().next();
        _LOGGER.debug("moveToNextDoc fullname [{}]", fullname);
        docRef = getWebUtils().resolveDocumentReference(fullname);
      } while (!getModelAccess().exists(docRef) && getDocIterator().hasNext());
      if (getModelAccess().exists(docRef)) {
        _LOGGER.info("moveToNextDoc found next doc [{}]", docRef);
        _currentDoc = getModelAccess().getDocument(docRef);
      } else {
        _LOGGER.info("moveToNextDoc no next doc found.");
        _currentDoc = null;
      }
    } catch (DocumentLoadException | DocumentNotExistsException exp) {
      // If getDocument failed, getDocIterator still moved on by one document in
      // list.
      // Hence the while loop in 'next' moves on to the next document in list.
      _LOGGER.error("Failed to get next xwiki document.", exp);
    }
  }

  /**
   * @return
   */
  Iterator<String> getDocIterator() {
    if (getDocList() == null) {
      throw new IllegalStateException("No doc list set.");
    }
    if (_docIterator == null) {
      _docIterator = getDocList().iterator();
    }
    return _docIterator;
  }

  /**
   * Gets the current document
   *
   * @return current document
   */
  XWikiDocument getCurrentDoc() {
    if ((_currentDoc == null) && (getDocIterator().hasNext())) {
      moveToNextDoc();
    }
    return _currentDoc;
  }

  /**
   * FOR TESTS ONLY!!!
   *
   * @param testCurrentDoc
   */
  void inject_CurrentDoc(XWikiDocument testCurrentDoc) {
    _currentDoc = testCurrentDoc;
  }

  /**
   * Remove is not supported
   *
   * @throws UnsupportedOperationException
   */
  @Override
  public void remove() {
    throw new UnsupportedOperationException();
  }

  /**
   * Set the document list
   *
   * @param document
   *          list
   */
  public void setDocList(List<String> docList) {
    _docIterator = null;
    _docList = docList;
  }

  /**
   * Gets the document list
   *
   * @return document list
   */
  List<String> getDocList() {
    return _docList;
  }

  /**
   * Get a copy of the document list
   *
   * @return document list
   */
  public List<String> getDocListCopy() {
    return new ArrayList<String>(_docList);
  }

  @Override
  public Iterator<XWikiDocument> iterator() {
    return this;
  }

  private IModelAccessFacade getModelAccess() {
    return Utils.getComponent(IModelAccessFacade.class);
  }

  private IWebUtilsService getWebUtils() {
    return Utils.getComponent(IWebUtilsService.class);
  }

}

@@ -1697,14 +1697,15 @@
 ger(
-XObjec
+Documen
 tIte

change logger class to DocumentIterator.class for DocumentIterator