/******************************************************************************* * Copyright (c) 2012 VMware, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * VMware, Inc. - initial API and implementation *******************************************************************************/ package org.springframework.roo.shell.eclipse; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.lang.reflect.Method; import java.net.URL; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Collection; import java.util.Date; import java.util.List; import java.util.logging.Level; 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.Service; import org.osgi.framework.ServiceReference; import org.osgi.service.component.ComponentContext; import org.springframework.roo.file.monitor.event.FileEvent; import org.springframework.roo.file.monitor.event.FileEventListener; import org.springframework.roo.file.monitor.event.FileOperation; import org.springframework.roo.process.manager.ActiveProcessManager; import org.springframework.roo.process.manager.ProcessManager; import org.springframework.roo.shell.AbstractShell; import org.springframework.roo.shell.CommandMarker; import org.springframework.roo.shell.ExecutionStrategy; import org.springframework.roo.shell.Parser; import org.springframework.roo.shell.Shell; import org.springframework.roo.shell.event.ShellStatus.Status; import org.springframework.roo.support.osgi.OSGiUtils; import org.springframework.roo.support.util.ReflectionUtils; /** * Eclipse-based {@link Shell} implementation. * @author Christian Dupuis */ @Component(immediate = true) @Service public class EclipseShell extends AbstractShell implements CommandMarker, Shell, FileEventListener { private static final Logger logger = Logger.getLogger(EclipseShell.class.getName()); private ComponentContext context; private boolean developmentMode = false; private DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); @Reference private ExecutionStrategy executionStrategy; private FileWriter fileLog; @Reference private Parser parser; private ProcessManager processManager = null; private String projectLocation; private Object projectRefresher; private String rooHome; private TextHandler handler; public Integer complete(String command, Integer pos, List<String> completions) { if (getParser() != null) { try { ActiveProcessManager.setActiveProcessManager(processManager); return getParser().complete(command, pos, completions); } finally { ActiveProcessManager.clearActiveProcessManager(); } } return 0; } public void close() { if (fileLog != null) { try { fileLog.write("// Spring Roo " + versionInfo() + " log closed at " + df.format(new Date()) + "\n"); fileLog.flush(); fileLog.close(); fileLog = null; } catch (IOException e) { } } Logger mainLogger = Logger.getLogger(""); mainLogger.removeHandler(handler); } @Override public boolean executeCommand(String line) { try { ActiveProcessManager.setActiveProcessManager(processManager); boolean status = super.executeCommand(line); logger.info(getShellPrompt()); return status; } finally { ActiveProcessManager.clearActiveProcessManager(); } } public void init(Object appender, int identity, Object projectRefresher, Object runTestsCommand, Object deployCommand, Object uiCommands, String rooHome, String projectLocation) { try { ServiceReference ref = context.getBundleContext().getServiceReference( "org.springframework.roo.process.manager.ProcessManager"); processManager = (ProcessManager) context.getBundleContext().getService(ref); ActiveProcessManager.setActiveProcessManager(processManager); completionKeys = "CTRL+SPACE"; shellPrompt = "roo> "; // this.reflectiveCommands = runTestsCommand; // this.deployCommand = deployCommand; // this.uiCommands = uiCommands; this.rooHome = rooHome; this.projectLocation = projectLocation; this.projectRefresher = projectRefresher; setPromptPath(null); handler = new TextHandler(appender, identity); Logger mainLogger = Logger.getLogger(""); mainLogger.addHandler(handler); openFileLogIfPossible(); logger.info(version(null)); logger.info("Welcome to Spring Roo. For assistance press " + completionKeys + " or type \"hint\" then hit ENTER."); logger.info(getShellPrompt()); setShellStatus(Status.STARTED); } finally { ActiveProcessManager.clearActiveProcessManager(); } } public boolean isDevelopmentMode() { return developmentMode; } public void onFileEvent(FileEvent fileEvent) { try { Method method = ReflectionUtils.findMethod(projectRefresher.getClass(), "refresh", new Class[] { File.class, Boolean.class }); method.invoke(projectRefresher, fileEvent.getFileDetails().getFile(), fileEvent.getOperation() == FileOperation.CREATED); } catch (Throwable e) { } } public void promptLoop() { } public void setDevelopmentMode(boolean developmentMode) { this.developmentMode = developmentMode; } private void openFileLogIfPossible() { try { fileLog = new FileWriter(new File(this.projectLocation, "log.roo"), true); // first write, so let's record the date and time of the first user // command fileLog.write("// Spring Roo " + versionInfo() + " log opened at " + df.format(new Date()) + "\n"); fileLog.flush(); } catch (IOException ignoreIt) { } } protected void activate(ComponentContext context) { this.context = context; } protected void deactivate(ComponentContext context) { close(); this.context = null; } @Override protected boolean executeScriptLine(String line) { if (line != null && line.startsWith("project")) { return true; } return super.executeScriptLine(line); } @Override protected Collection<URL> findResources(String path) { return OSGiUtils.findEntriesByPath(context.getBundleContext(), OSGiUtils.ROOT_PATH + path); } @Override protected ExecutionStrategy getExecutionStrategy() { return executionStrategy; } @Override protected String getHomeAsString() { return this.rooHome; } @Override protected Parser getParser() { return parser; } @Override protected void logCommandToOutput(String processedLine) { if (fileLog == null) { openFileLogIfPossible(); if (fileLog == null) { // still failing, so give up return; } } try { fileLog.write(processedLine + "\n"); // unix line endings only from // Roo fileLog.flush(); // so tail -f will show it's working if (getExitShellRequest() != null) { // shutting down, so close our file (we can always reopen it // later if needed) fileLog.write("// Spring Roo " + versionInfo() + " log closed at " + df.format(new Date()) + "\n"); fileLog.flush(); fileLog.close(); fileLog = null; } } catch (IOException ignoreIt) { } } @Override public void flash(Level level, String message, String slot) { // TODO CD: add implementation here } }