package org.springframework.roo.addon.suite;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.felix.bundlerepository.Repository;
import org.apache.felix.bundlerepository.RepositoryAdmin;
import org.apache.felix.bundlerepository.Resource;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Service;
import org.apache.felix.service.command.CommandProcessor;
import org.apache.felix.service.command.CommandSession;
import org.apache.felix.service.command.Converter;
import org.osgi.framework.BundleContext;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;
import org.osgi.service.component.ComponentContext;
import org.osgi.service.subsystem.Subsystem;
import org.springframework.roo.shell.Completion;
import org.springframework.roo.support.logging.HandlerUtils;
/**
*
* AddonSuiteOperations implementation that manage Roo Addon Suite on Spring Roo
* Shell
*
* @author Juan Carlos GarcĂa
* @since 2.0.0
*/
@Component
@Service
public class AddonSuiteOperationsImpl implements AddonSuiteOperations {
private BundleContext context;
private static final Logger LOGGER = HandlerUtils.getLogger(AddonSuiteOperationsImpl.class);
private CommandProcessor commandProcessor;
private RepositoryAdmin repositoryAdmin;
protected void activate(final ComponentContext cContext) {
context = cContext.getBundleContext();
}
@Override
public void installRooAddonSuiteByName(ObrAddonSuiteSymbolicName suiteSymbolicName)
throws Exception {
perform("subsystem:deploy " + suiteSymbolicName.getKey());
}
@Override
public void installRooAddonSuiteByUrl(String url) throws Exception {
perform("subsystem:install " + url);
}
@Override
public void startRooAddonSuite(AddonSuiteSymbolicName symbolicName) {
LOGGER
.log(Level.INFO, String.format("Starting '%s' Roo Addon Suite...", symbolicName.getKey()));
Subsystem subsystem = getSubsystemByName(symbolicName);
if (subsystem != null) {
subsystem.start();
LOGGER.log(Level.INFO, String.format("'%s' Roo Addon Suite started!", symbolicName.getKey()));
} else {
LOGGER.warning(String.format("Cannot start Subsystem '%s'", symbolicName.getKey()));
}
}
@Override
public void stopRooAddonSuite(AddonSuiteSymbolicName symbolicName) {
LOGGER
.log(Level.INFO, String.format("Stopping '%s' Roo Addon Suite...", symbolicName.getKey()));
Subsystem subsystem = getSubsystemByName(symbolicName);
if (subsystem != null) {
subsystem.stop();
LOGGER.log(Level.INFO, String.format("'%s' Roo Addon Suite stopped!", symbolicName.getKey()));
} else {
LOGGER.warning(String.format("Cannot stop Subsystem '%s'", symbolicName.getKey()));
}
}
@Override
public void uninstallRooAddonSuite(AddonSuiteSymbolicName symbolicName) {
LOGGER.log(Level.INFO,
String.format("Uninstalling '%s' Roo Addon Suite...", symbolicName.getKey()));
Subsystem subsystem = getSubsystemByName(symbolicName);
if (subsystem != null) {
subsystem.uninstall();
LOGGER.log(Level.INFO,
String.format("'%s' Roo Addon Suite uninstalled!", symbolicName.getKey()));
} else {
LOGGER.warning(String.format("Cannot uninstall Subsystem '%s'", symbolicName.getKey()));
}
}
@Override
public void listAllInstalledSubsystems() {
LOGGER.log(Level.INFO, "Getting all 'Roo Addon Suites' installed on Spring Roo Shell... ");
LOGGER.log(Level.INFO, " ");
// Get all Services implement Subsystem interface
try {
ServiceReference<?>[] references =
context.getAllServiceReferences(Subsystem.class.getName(), null);
for (ServiceReference<?> ref : references) {
Subsystem subsystem = (Subsystem) context.getService(ref);
LOGGER.log(Level.INFO, " " + subsystem.getSymbolicName());
}
LOGGER.log(Level.INFO, " ");
LOGGER.log(Level.INFO, String.format(
"%s Roo Addon Suites were found at your Spring Roo installation", references.length));
} catch (InvalidSyntaxException e) {
LOGGER.warning("Cannot load Subsystem on AddonSuiteOperationsImpl.");
}
}
@Override
public void listAllSubsystemsOnRepository(ObrRepositorySymbolicName obrRepository) {
LOGGER.log(Level.INFO, "Getting all 'Roo Addon Suites' located on '" + obrRepository.getKey()
+ "' repository... ");
LOGGER.log(Level.INFO, " ");
int repos = 0;
// Getting all repositories
Repository[] repositories = getRepositoryAdmin().listRepositories();
for (Repository repo : repositories) {
if (repo.getURI().equals(obrRepository.getKey())) {
// Getting all resources from repository
Resource[] repositoryResource = repo.getResources();
for (Resource resource : repositoryResource) {
// If current resource ends with .esa, means that is a ROO Addon Suite
if (resource.getURI().endsWith(".esa")) {
LOGGER.log(Level.INFO, " " + resource.getSymbolicName());
repos++;
}
}
}
}
LOGGER.log(Level.INFO, " ");
LOGGER.log(
Level.INFO,
String.format("%s Roo Addon Suites were found on '%s' repository", repos,
obrRepository.getKey()));
}
/**
* Method to obtain installed subsystem by name
*
* @param symbolicName
* @return
*/
private Subsystem getSubsystemByName(AddonSuiteSymbolicName symbolicName) {
// Get all Services implement Subsystem interface
try {
ServiceReference<?>[] references =
context.getAllServiceReferences(Subsystem.class.getName(), null);
for (ServiceReference<?> ref : references) {
Subsystem subsystem = (Subsystem) context.getService(ref);
if (subsystem.getSymbolicName().equals(symbolicName.getKey())) {
return subsystem;
}
}
return null;
} catch (InvalidSyntaxException e) {
LOGGER.warning("Cannot load Subsystem on AddonSuiteOperationsImpl.");
return null;
}
}
private void perform(final String commandLine) throws Exception {
if ("shutdown".equals(commandLine)) {
context.getBundle(0).stop();
return;
}
ByteArrayOutputStream sysOut = new ByteArrayOutputStream();
ByteArrayOutputStream sysErr = new ByteArrayOutputStream();
final PrintStream printStreamOut = new PrintStream(sysOut);
final PrintStream printErrOut = new PrintStream(sysErr);
try {
final CommandSession commandSession =
getCommandProcessor().createSession(System.in, printStreamOut, printErrOut);
Object result = commandSession.execute(commandLine);
if (result != null) {
printStreamOut.println(commandSession.format(result, Converter.INSPECT));
}
if (sysOut.size() > 0) {
LOGGER.log(Level.INFO, new String(sysOut.toByteArray()));
}
if (sysErr.size() > 0) {
LOGGER.log(Level.SEVERE, new String(sysErr.toByteArray()));
}
} catch (Throwable ex) {
LOGGER.log(Level.SEVERE, ex.getMessage(), ex);
} finally {
printStreamOut.close();
printErrOut.close();
}
}
/**
* Method to get CommandProcessor Service implementation
*
* @return
*/
public CommandProcessor getCommandProcessor() {
if (commandProcessor == null) {
// Get all Services implement CommandProcessor interface
try {
ServiceReference<?>[] references =
context.getAllServiceReferences(CommandProcessor.class.getName(), null);
for (ServiceReference<?> ref : references) {
commandProcessor = (CommandProcessor) context.getService(ref);
return commandProcessor;
}
return null;
} catch (InvalidSyntaxException e) {
LOGGER.warning("Cannot load CommandProcessor on AddonSuiteOperationsImpl.");
return null;
}
} else {
return commandProcessor;
}
}
/**
* Method to get RepositoryAdmin Service implementation
*
* @return
*/
public RepositoryAdmin getRepositoryAdmin() {
if (repositoryAdmin == null) {
// Get all Services implement RepositoryAdmin interface
try {
ServiceReference<?>[] references =
context.getAllServiceReferences(RepositoryAdmin.class.getName(), null);
for (ServiceReference<?> ref : references) {
repositoryAdmin = (RepositoryAdmin) context.getService(ref);
return repositoryAdmin;
}
return null;
} catch (InvalidSyntaxException e) {
LOGGER.warning("Cannot load RepositoryAdmin on AddonSuiteOperationsImpl.");
return null;
}
} else {
return repositoryAdmin;
}
}
}