com.celements.iterator.XObjectIterator.java Source code

Java tutorial

Introduction

Here is the source code for com.celements.iterator.XObjectIterator.java

Source

/*
 * 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.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.xwiki.model.reference.DocumentReference;

import com.celements.web.service.IWebUtilsService;
import com.xpn.xwiki.XWiki;
import com.xpn.xwiki.XWikiContext;
import com.xpn.xwiki.XWikiException;
import com.xpn.xwiki.doc.XWikiDocument;
import com.xpn.xwiki.objects.BaseObject;
import com.xpn.xwiki.objects.BaseProperty;
import com.xpn.xwiki.web.Utils;

/**
 * Iterator class
 * @author Philipp Buser
 *
 */
public class XObjectIterator implements Iterator<BaseObject>, Iterable<BaseObject> {

    private static Log mLogger = LogFactory.getFactory().getInstance(XObjectIterator.class);

    private List<String> _docList;
    private String _xwikiClassName;
    private XWikiContext _context;
    private XWiki _xwiki;
    private Iterator<BaseObject> _objectIterator;
    private Iterator<String> _docIterator;
    private XWikiDocument _currentDoc;
    private BaseObject _nextObject;
    private String _key;
    private Object _value;

    IWebUtilsService webUtilsService;

    /**
     * Constructor
     * @param XWiki context
     */
    public XObjectIterator(XWikiContext context) {
        _context = context;
        _xwiki = _context.getWiki();
    }

    /**
     * Checks if iterator has a next object
     */
    public boolean hasNext() {
        while ((_nextObject == null) && (getDocIterator().hasNext() || getObjectIterator().hasNext())) {
            if (getObjectIterator().hasNext()) {
                _nextObject = getObjectIterator().next();
                if (_key != null && _value != null) {
                    if (!isValidObject()) {
                        _nextObject = null;
                    }
                }
            } else {
                moveToNextDoc();
            }
        }
        return (_nextObject != null);
    }

    boolean isValidObject() {
        return ((_nextObject != null) && (_value.equals(getValue())));
    }

    private Object getValue() {
        try {
            if (_nextObject.get(_key) != null) {
                return ((BaseProperty) _nextObject.get(_key)).getValue();
            }
        } catch (XWikiException exp) {
            mLogger.warn("Failed to get a propery with key [" + _key + "]", exp);
        }
        return null;
    }

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

    /**
     * Moves to the next document
     */
    void moveToNextDoc() {
        try {
            String nextFN = getDocIterator().next();
            DocumentReference nextDocRef = Utils.getComponent(IWebUtilsService.class)
                    .resolveDocumentReference(nextFN);
            _currentDoc = _xwiki.getDocument(nextDocRef, _context);
            _objectIterator = null;
        } catch (XWikiException exp) {
            // If getDocument failed, getDocIterator still moved on by one document in list.
            // Yet, _objectIterator is not reset and hasNext is still false.
            // Hence the while loop in 'next' moves on to the next document in list.
            mLogger.error("Failed to get next xwiki document.", exp);
        }
    }

    /**
     * Gets the object iterator
     * @return XObjectIterator
     */
    Iterator<BaseObject> getObjectIterator() {
        if (_objectIterator == null) {
            _objectIterator = getObjectsForCurrentDoc().iterator();
        }
        return _objectIterator;
    }

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

    /**
     * Get the objects for the current document
     * @return
     */
    List<BaseObject> getObjectsForCurrentDoc() {
        if (_xwikiClassName == null) {
            throw new IllegalStateException("Classname cannot be null");
        }
        if (getCurrentDoc() == null) {
            return Collections.emptyList();
        }
        List<BaseObject> objs = getCurrentDoc()
                .getXObjects(getWebUtilsService().resolveDocumentReference(_xwikiClassName));
        if (objs != null) {
            return objs;
        } else {
            return Collections.emptyList();
        }
    }

    /**
     * Gets the current document
     * @return current document
     */
    XWikiDocument getCurrentDoc() {
        return _currentDoc;
    }

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

    /**
     * FOR TESTS ONLY!!!
     * @param nextObject
     */
    void inject_NextObject(BaseObject nextObject) {
        _nextObject = nextObject;
    }

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

    /**
     * Set the document list
     * @param document list
     */
    public void setDocList(List<String> docList) {
        _objectIterator = null;
        _docIterator = null;
        _nextObject = 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);
    }

    /**
     * Sets the class name
     * @param class name
     */
    public void setClassName(String className) {
        _xwikiClassName = className;
    }

    /**
     * Gets the class name
     * @return class name
     */
    public String getClassName() {
        return _xwikiClassName;
    }

    /**
     * Sets the filter
     * @param filter
     */
    public void setFilter(String key, Object value) {
        _key = key;
        _value = value;
    }

    String getFilterKey() {
        return _key;
    }

    Object getFilterValue() {
        return _value;
    }

    public Iterator<BaseObject> iterator() {
        return this;
    }

    IWebUtilsService getWebUtilsService() {
        if (webUtilsService != null) {
            return webUtilsService;
        }
        return Utils.getComponent(IWebUtilsService.class);
    }

}