package org.springframework.roo.shell.osgi;
import java.util.logging.Logger;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.ReferencePolicy;
import org.apache.felix.scr.annotations.ReferenceStrategy;
import org.apache.felix.scr.annotations.References;
import org.apache.felix.scr.annotations.Service;
import org.osgi.service.component.ComponentContext;
import org.springframework.roo.shell.AbstractShell;
import org.springframework.roo.shell.CliCommand;
import org.springframework.roo.shell.CliOption;
import org.springframework.roo.shell.CommandMarker;
import org.springframework.roo.shell.Converter;
import org.springframework.roo.shell.Parser;
import org.springframework.roo.shell.SimpleParser;
import org.springframework.roo.support.api.AddOnSearch;
/**
* OSGi component launcher for {@link SimpleParser}.
*
* @author Ben Alex
* @since 1.1
*/
@Component
@Service(value = Parser.class)
// Important, as auto-detection includes CommandMarker which is unacceptable as
// we'd have a circular dependency to ourself
@References(value = {
@Reference(name = "converter", strategy = ReferenceStrategy.EVENT, policy = ReferencePolicy.DYNAMIC, referenceInterface = Converter.class, cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE),
@Reference(name = "command", strategy = ReferenceStrategy.EVENT, policy = ReferencePolicy.DYNAMIC, referenceInterface = CommandMarker.class, cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE),
@Reference(name = "addOnSearch", strategy = ReferenceStrategy.EVENT, policy = ReferencePolicy.DYNAMIC, referenceInterface = AddOnSearch.class, cardinality = ReferenceCardinality.OPTIONAL_UNARY) })
public class SimpleParserComponent extends SimpleParser implements
CommandMarker {
private AddOnSearch addOnSearch;
protected void activate(final ComponentContext context) {
bindCommand(this);
}
protected void bindAddOnSearch(final AddOnSearch s) {
addOnSearch = s;
}
protected void bindCommand(final CommandMarker c) {
add(c);
}
protected void bindConverter(final Converter<?> c) {
add(c);
}
@Override
protected void commandNotFound(final Logger logger, final String buffer) {
logger.warning("Command '" + buffer
+ "' not found (for assistance press "
+ AbstractShell.completionKeys
+ " or type \"hint\" then hit ENTER)");
if (addOnSearch == null) {
return;
}
// Decide which command they asked for
String command = buffer.trim();
// Truncate from the first option, if any was given
final int firstDash = buffer.indexOf("--");
if (firstDash > 1) {
command = buffer.substring(0, firstDash - 1).trim();
}
// Do a silent (console message free) lookup of matches
Integer matches = null;
matches = addOnSearch.searchAddOns(false, null, false, 1, 99, false,
false, false, command);
// Render to screen if required
if (matches == null) {
logger.info("Spring Roo automatic add-on discovery service currently unavailable");
}
else if (matches == 0) {
logger.info("addon search --requiresCommand \"" + command
+ "\" found no matches");
}
else if (matches > 0) {
logger.info("Located add-on" + (matches == 1 ? "" : "s")
+ " that may offer this command");
addOnSearch.searchAddOns(true, null, false, 1, 99, false, false,
false, command);
}
}
protected void deactivate(final ComponentContext context) {
unbindCommand(this);
}
@Override
@CliCommand(value = "reference guide", help = "Writes the reference guide XML fragments (in DocBook format) into the current working directory")
public void helpReferenceGuide() {
super.helpReferenceGuide();
}
@Override
@CliCommand(value = "help", help = "Shows system help")
public void obtainHelp(
@CliOption(key = { "", "command" }, optionContext = "availableCommands", help = "Command name to provide help for") final String buffer) {
super.obtainHelp(buffer);
}
protected void unbindAddOnSearch(final AddOnSearch s) {
addOnSearch = null;
}
protected void unbindCommand(final CommandMarker c) {
remove(c);
}
protected void unbindConverter(final Converter<?> c) {
remove(c);
}
}