001/*
002 * Copyright (c) 2013 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the Eclipse Public License v1.0
006 * which accompanies this distribution, and is available at
007 * http://www.eclipse.org/legal/epl-v10.html
008 *
009 * Contributors:
010 *     Florent Guillaume
011 */
012package org.nuxeo.ecm.core.api.impl;
013
014import java.util.ArrayList;
015import java.util.Iterator;
016import java.util.List;
017import java.util.NoSuchElementException;
018
019import org.apache.commons.logging.Log;
020import org.apache.commons.logging.LogFactory;
021import org.nuxeo.ecm.core.api.CoreSession;
022import org.nuxeo.ecm.core.api.DocumentModel;
023import org.nuxeo.ecm.core.api.DocumentModelIterator;
024import org.nuxeo.ecm.core.api.DocumentRef;
025import org.nuxeo.ecm.core.api.Filter;
026import org.nuxeo.ecm.core.api.IdRef;
027
028/**
029 * Iterator over the children of a folder.
030 */
031public class DocumentModelChildrenIterator implements DocumentModelIterator {
032
033    private static final Log log = LogFactory.getLog(DocumentModelChildrenIterator.class);
034
035    private CoreSession session;
036
037    private String type;
038
039    private Filter filter;
040
041    private Iterator<String> it;
042
043    private DocumentModel next;
044
045    public DocumentModelChildrenIterator(CoreSession session, DocumentRef parentRef, String type, Filter filter)
046            {
047        this.session = session;
048        this.type = type;
049        this.filter = filter;
050
051        // fetch all the children ids now
052        List<DocumentRef> refs = session.getChildrenRefs(parentRef, null);
053        List<String> ids = new ArrayList<String>(refs.size());
054        for (DocumentRef ref : refs) {
055            ids.add(ref.toString()); // always an IdRef
056        }
057        it = ids.iterator();
058    }
059
060    @Override
061    public boolean hasNext() {
062        if (next != null) {
063            return true;
064        }
065        // this could be optimized to retrieve batches of documents instead of
066        // one at a time; this would need to call SQLSession.getDocumentsById
067        // through a new CoreSession API (or improve getDocuments)
068        for (;;) {
069            if (!it.hasNext()) {
070                return false;
071            }
072            String id = it.next();
073            DocumentModel doc;
074            doc = session.getDocument(new IdRef(id));
075            if (accept(doc)) {
076                next = doc;
077                return true;
078            }
079            // continue
080        }
081    }
082
083    private boolean accept(DocumentModel doc) {
084        if (type != null && !type.equals(doc.getType())) {
085            return false;
086        }
087        if (filter != null && !filter.accept(doc)) {
088            return false;
089        }
090        return true;
091    }
092
093    @Override
094    public DocumentModel next() {
095        if (!hasNext()) {
096            throw new NoSuchElementException();
097        }
098        DocumentModel res = next;
099        next = null;
100        return res;
101    }
102
103    @Override
104    public void remove() {
105        throw new UnsupportedOperationException();
106    }
107
108    @Override
109    public Iterator<DocumentModel> iterator() {
110        return this;
111    }
112
113    @Override
114    public long size() {
115        return UNKNOWN_SIZE;
116    }
117
118}