001/*
002 * (C) Copyright 2006-2010 Nuxeo SAS (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 *     bstefanescu
016 */
017package org.nuxeo.shell.automation;
018
019import java.util.Collections;
020import java.util.List;
021
022import jline.Completor;
023
024import org.nuxeo.ecm.automation.client.model.Document;
025import org.nuxeo.ecm.automation.client.model.Documents;
026import org.nuxeo.shell.Shell;
027import org.nuxeo.shell.ShellException;
028import org.nuxeo.shell.utils.Path;
029
030/**
031 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
032 */
033public class DocRefCompletor implements Completor {
034
035    protected RemoteContext ctx;
036
037    public DocRefCompletor() {
038        this(Shell.get().getContextObject(RemoteContext.class));
039    }
040
041    public DocRefCompletor(RemoteContext ctx) {
042        this.ctx = ctx;
043    }
044
045    protected Document fetchDocument(String path) {
046        try {
047            return ctx.resolveDocument(path);
048        } catch (Exception e) {
049            return null;
050        }
051    }
052
053    @SuppressWarnings({ "rawtypes", "unchecked" })
054    public int complete(String buffer, int cursor, List clist) {
055        Document cdoc = ctx.getDocument();
056        String prefix = "";
057        if (buffer != null) {
058            if (buffer.endsWith("/")) {
059                Path path = new Path(buffer).removeTrailingSeparator();
060                prefix = buffer;
061                buffer = "";
062                cdoc = fetchDocument(path.toString());
063            } else if (buffer.indexOf('/') != -1) {
064                Path path = new Path(buffer);
065                buffer = path.lastSegment();
066                prefix = path.getParent().toString();
067                cdoc = fetchDocument(prefix);
068                prefix += '/';
069            }
070        }
071        if (cdoc == null) {
072            return -1;
073        }
074        try {
075            Documents docs = ctx.getDocumentService().getChildren(cdoc);
076            for (Document doc : docs) {
077                String name = new Path(doc.getPath()).lastSegment();
078                if (buffer == null) {
079                    clist.add(name);
080                } else if (name.startsWith(buffer)) {
081                    clist.add(prefix + name);
082                }
083            }
084            Collections.sort(clist);
085            if (clist.size() == 1) { // TODO add trailing / only if folderish
086                clist.set(0, ((String) clist.get(0)) + '/');
087            }
088            return clist.isEmpty() ? -1 : 0;
089        } catch (Exception e) {
090            throw new ShellException("Failed to gather children for " + buffer, e);
091        }
092    }
093}