1d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann/*******************************************************************************
2d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann * Copyright (c) 2009, 2017 Mountainminds GmbH & Co. KG and Contributors
3d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann * All rights reserved. This program and the accompanying materials
4d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann * are made available under the terms of the Eclipse Public License v1.0
5d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann * which accompanies this distribution, and is available at
6d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann * http://www.eclipse.org/legal/epl-v10.html
7d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann *
8d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann * Contributors:
9d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann *    Marc R. Hoffmann - initial API and implementation
10d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann *
11d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann *******************************************************************************/
12d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmannpackage org.jacoco.cli.internal;
13d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann
14d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmannimport java.util.AbstractList;
15d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann
16d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmannimport org.jacoco.cli.internal.commands.AllCommands;
17d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmannimport org.kohsuke.args4j.CmdLineException;
18d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmannimport org.kohsuke.args4j.CmdLineParser;
19d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmannimport org.kohsuke.args4j.OptionDef;
20d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmannimport org.kohsuke.args4j.spi.Messages;
21d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmannimport org.kohsuke.args4j.spi.OptionHandler;
22d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmannimport org.kohsuke.args4j.spi.Parameters;
23d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmannimport org.kohsuke.args4j.spi.Setter;
24d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann
25d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann/**
26d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann * {@link OptionHandler} which uses {@link CommandParser} internally to provide
27d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann * help context also for sub-commands.
28d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann */
29d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmannpublic class CommandHandler extends OptionHandler<Command> {
30d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann
31d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann	/**
32d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann	 * This constructor is required by the args4j framework.
33d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann	 *
34d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann	 * @param parser
35d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann	 * @param option
36d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann	 * @param setter
37d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann	 */
38d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann	public CommandHandler(final CmdLineParser parser, final OptionDef option,
39d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann			final Setter<Object> setter) {
40d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann		super(parser,
41d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann				new OptionDef(AllCommands.names(), "<command>",
42d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann						option.required(), option.help(), option.hidden(),
43d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann						CommandHandler.class, option.isMultiValued()) {
44d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann				}, setter);
45d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann	}
46d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann
47d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann	@Override
48d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann	public int parseArguments(final Parameters params) throws CmdLineException {
49d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann		final String subCmd = params.getParameter(0);
50d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann
51d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann		for (final Command c : AllCommands.get()) {
52d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann			if (c.name().equals(subCmd)) {
53d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann				parseSubArguments(c, params);
54d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann				setter.addValue(c);
55d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann				return params.size(); // consume all the remaining tokens
56d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann			}
57d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann		}
58d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann
59d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann		throw new CmdLineException(owner,
60d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann				Messages.ILLEGAL_OPERAND.format(option.toString(), subCmd));
61d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann	}
62d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann
63d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann	private void parseSubArguments(final Command c, final Parameters params)
64d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann			throws CmdLineException {
65d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann		final CmdLineParser p = new CommandParser(c);
66d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann		p.parseArgument(new AbstractList<String>() {
67d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann			@Override
68d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann			public String get(final int index) {
69d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann				try {
70d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann					return params.getParameter(index + 1);
71d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann				} catch (final CmdLineException e) {
72d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann					// invalid index was accessed.
73d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann					throw new IndexOutOfBoundsException();
74d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann				}
75d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann			}
76d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann
77d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann			@Override
78d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann			public int size() {
79d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann				return params.size() - 1;
80d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann			}
81d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann		});
82d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann	}
83d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann
84d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann	@Override
85d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann	public String getDefaultMetaVariable() {
86d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann		return "<command>";
87d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann	}
88d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann
89d850ed49b22d2a0c84a3b317acec8df7e7159016Marc R. Hoffmann}
90