Package org.jboss.as.cli.operation

Source Code of org.jboss.as.cli.operation.OperationRequestCompleter

/*
* JBoss, Home of Professional Open Source.
* Copyright 2011, Red Hat, Inc., and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* 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 org.jboss.as.cli.operation;

import java.util.Collections;
import java.util.List;
import java.util.Set;

import org.jboss.as.cli.CommandContext;
import org.jboss.as.cli.CommandLineCompleter;
import org.jboss.as.cli.EscapeSelector;
import org.jboss.as.cli.Util;
import org.jboss.as.cli.operation.impl.DefaultOperationCallbackHandler;
import org.jboss.as.cli.operation.impl.DefaultOperationRequestAddress;

import jline.Completor;

/**
*
* @author Alexey Loubyansky
*/
public class OperationRequestCompleter implements CommandLineCompleter, Completor {

    public static final OperationRequestCompleter INSTANCE = new OperationRequestCompleter(null);

    public static final EscapeSelector ESCAPE_SELECTOR = new EscapeSelector() {
        @Override
        public boolean isEscape(char ch) {
            return ch == ':' || ch == '/' || ch == '=' || ch == ' ' || ch == '"' || ch == '\\';
        }
    };

    private final CommandContext ctx;

    public OperationRequestCompleter(CommandContext ctx) {
        this.ctx = ctx;
    }

    /* (non-Javadoc)
     * @see jline.Completor#complete(java.lang.String, int, java.util.List)
     */
    @SuppressWarnings({ "rawtypes", "unchecked" } )
    @Override
    public int complete(String buffer, int cursor, List candidates) {
        return complete(ctx, buffer, cursor, candidates);
    }

    @Override
    public int complete(CommandContext ctx, final String buffer, int cursor, List<String> candidates) {
        int firstCharIndex = 0;
        while(firstCharIndex < buffer.length()) {
            if(!Character.isWhitespace(buffer.charAt(firstCharIndex))) {
                break;
            }
            ++firstCharIndex;
        }

        // if it ends on .. then the completion shouldn't happen
        // since the node is selected and it doesn't end on a separator
        if(buffer.endsWith("..")) {
            return 0;
        }

        DefaultOperationCallbackHandler handler = new DefaultOperationCallbackHandler(new DefaultOperationRequestAddress(ctx.getPrefix()));

        try {
            ctx.getOperationRequestParser().parse(buffer, handler);
        } catch (OperationFormatException e1) {
            return -1;
        }

        if(handler.isRequestComplete()) {
            return -1;
        }

        if(handler.hasProperties() || handler.endsOnPropertyListStart()) {

            if(handler.endsOnPropertyValueSeparator()) {
                // no value completion
                return -1;
            }

            OperationCandidatesProvider provider = ctx.getOperationCandidatesProvider();

            List<String> propertyNames = provider.getPropertyNames(handler.getOperationName(), handler.getAddress());
            if(propertyNames.isEmpty()) {
                if(handler.endsOnPropertyListStart()) {
                    candidates.add(")");
                    return buffer.length();
                }
                return -1;
            }

            if(handler.endsOnPropertyListStart()) {
                if(propertyNames.size() == 1) {
                    candidates.add(propertyNames.get(0) + '=');
                } else {
                    candidates.addAll(propertyNames);
                    Collections.sort(candidates);
                }
                //return handler.getLastSeparatorIndex() + 1;
                return buffer.length();
            }

            Set<String> specifiedNames = handler.getPropertyNames();

            String chunk = null;
            for(String specifiedName : specifiedNames) {
                String value = handler.getPropertyValue(specifiedName);
                if(value == null) {
                    chunk = specifiedName;
                } else {
                    propertyNames.remove(specifiedName);
                }
            }

            if(chunk == null) {
                if(handler.endsOnPropertySeparator()) {
                    if(propertyNames.size() == 1) {
                        candidates.add(propertyNames.get(0) + '=');
                    } else {
                        candidates.addAll(propertyNames);
                        Collections.sort(candidates);
                    }
                } else if(propertyNames.isEmpty()) {
                    candidates.add(")");
                }
                return buffer.length();
                //return handler.getLastSeparatorIndex() + 1;
            }

            for(String candidate : propertyNames) {
                if(candidate.startsWith(chunk)) {
                    candidates.add(candidate);
                }
            }

            if(candidates.size() == 1) {
                candidates.set(0, (String)candidates.get(0) + '=');
            } else {
                Collections.sort(candidates);
            }
            return handler.getLastSeparatorIndex() + 1;
        }

        if(handler.hasOperationName() || handler.endsOnAddressOperationNameSeparator()) {

            if(handler.getAddress().endsOnType()) {
                return -1;
            }
            OperationCandidatesProvider provider = ctx.getOperationCandidatesProvider();
            final List<String> names = provider.getOperationNames(handler.getAddress());
            if(names.isEmpty()) {
                return -1;
            }

            final String chunk = handler.getOperationName();
            if(chunk == null) {
                candidates.addAll(names);
            } else {
                for (String name : names) {
                    if (chunk == null || name.startsWith(chunk)) {
                        candidates.add(name);
                    }
                }
            }

            Collections.sort(candidates);
            return handler.getLastSeparatorIndex() + 1;
        }

        final OperationRequestAddress address = handler.getAddress();

        final String chunk;
        if (address.isEmpty() || handler.endsOnNodeSeparator()
                || handler.endsOnNodeTypeNameSeparator()
                || address.equals(ctx.getPrefix())
                // TODO this is not nice
                || buffer.endsWith("..")) {
            chunk = null;
        } else if (address.endsOnType()) {
            chunk = address.getNodeType();
            address.toParentNode();
        } else {
            chunk = address.toNodeType();
        }

        OperationCandidatesProvider provider = ctx.getOperationCandidatesProvider();
        final List<String> names;
        if(address.endsOnType()) {
            names = provider.getNodeNames(address);
        } else {
            names = provider.getNodeTypes(address);
        }

        if(names.isEmpty()) {
            return -1;
        }

        if(chunk == null) {
            candidates.addAll(names);
        } else {
            for (String name : names) {
                if (chunk == null || name.startsWith(chunk)) {
                    candidates.add(name);
                }
            }
        }

        if(candidates.size() == 1) {
            if(address.endsOnType()) {
                candidates.set(0, Util.escapeString(candidates.get(0), ESCAPE_SELECTOR));
            } else {
                String onlyType = (String) candidates.get(0);
                address.toNodeType(onlyType);
                List<String> childNames = provider.getNodeNames(address);
                if (!childNames.isEmpty()) {
                    onlyType = Util.escapeString(onlyType, ESCAPE_SELECTOR);
                    candidates.clear();
                    if(childNames.size() == 1) {
                        candidates.add(onlyType  + '=' + Util.escapeString(childNames.get(0), ESCAPE_SELECTOR));
                    } else {
                        Util.sortAndEscape(childNames, ESCAPE_SELECTOR);
                        for (String name : childNames) {
                            candidates.add(onlyType + '=' + name);
                        }
                    }
                }
            }
        } else {
            Util.sortAndEscape(candidates, ESCAPE_SELECTOR);
        }

        return handler.getLastSeparatorIndex() + 1;
    }
}
TOP

Related Classes of org.jboss.as.cli.operation.OperationRequestCompleter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.