/*******************************************************************************
* Copyright (c) 2014, 2015 IBM Corporation and others
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Apache License,
* Version 2.0 (the "License�); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Contributors:
* IBM Corporation - initial API and implementation
********************************************************************************/
package org.cloudfoundry.ide.eclipse.server.ui;
import java.util.regex.Pattern;
import org.cloudfoundry.ide.eclipse.server.core.AbstractAppStateTracker;
import org.cloudfoundry.ide.eclipse.server.core.ICloudFoundryApplicationModule;
import org.cloudfoundry.ide.eclipse.server.core.internal.CloudFoundryServer;
import org.cloudfoundry.ide.eclipse.server.core.internal.client.CloudFoundryApplicationModule;
import org.cloudfoundry.ide.eclipse.server.ui.internal.Logger;
import org.cloudfoundry.ide.eclipse.server.ui.internal.console.ConsoleManagerRegistry;
import org.eclipse.ui.console.IPatternMatchListener;
import org.eclipse.ui.console.MessageConsole;
import org.eclipse.ui.console.PatternMatchEvent;
import org.eclipse.ui.console.TextConsole;
import org.eclipse.wst.server.core.IModule;
import org.eclipse.wst.server.core.IServer;
/**
* A general implementation class of the org.cloudfoundry.ide.eclipse.server.core.internal.AbstractAppStateTracker
* that provides easy implementation to track console output to decide whether the app is started or not. In
* most of the cases, the adopter only need to implement the getAppStartedPattern() method. In more complex cases,
* the adopter can override the createPatternMatchListener() to provide their own pattern match listener.
*
* @author Elson Yuen
*/
public abstract class AbstractConsoleMonitorAppStateTracker extends AbstractAppStateTracker {
private ConsolePatternMatchListener consoleMonitor;
/**
* Tracks text appended to the console and notifies listeners in terms of whole
* lines.
*/
public class ConsolePatternMatchListener implements IPatternMatchListener {
private String appName;
private int appState = IServer.STATE_STARTING;
public ConsolePatternMatchListener(String curAppName) {
appName = curAppName;
}
/* (non-Javadoc)
* @see org.eclipse.ui.console.IPatternMatchListenerDelegate#connect(org.eclipse.ui.console.TextConsole)
*/
public void connect(TextConsole console) {
// Do nothing
}
/* (non-Javadoc)
* @see org.eclipse.ui.console.IPatternMatchListener#disconnect()
*/
public synchronized void disconnect() {
// Do nothing
}
/* (non-Javadoc)
* @see org.eclipse.ui.console.IPatternMatchListener#matchFound(org.eclipse.ui.console.PatternMatchEvent)
*/
public void matchFound(PatternMatchEvent event) {
if (Logger.INFO) {
Logger.println(Logger.INFO_LEVEL, this, "matchFound", "Application start detected: " + appName); //$NON-NLS-1$ //$NON-NLS-2$
}
appState = IServer.STATE_STARTED;
}
/* (non-Javadoc)
* @see org.eclipse.ui.console.IPatternMatchListener#getPattern()
*/
public String getPattern() {
return getAppStartedPattern();
}
/* (non-Javadoc)
* @see org.eclipse.ui.console.IPatternMatchListener#getCompilerFlags()
*/
public int getCompilerFlags() {
return Pattern.CASE_INSENSITIVE;
}
/* (non-Javadoc)
* @see org.eclipse.ui.console.IPatternMatchListener#getLineQualifier()
*/
public String getLineQualifier() {
return "\\n|\\r"; //$NON-NLS-1$
}
protected int getApplicationState() {
return appState;
}
}
protected ConsolePatternMatchListener createPatternMatchListener(ICloudFoundryApplicationModule appModule) {
return new ConsolePatternMatchListener(((IModule)appModule).getName());
}
/**
* Find the message console that corresponds to the server and a given module. If there are multiple instances
* of the application, only the first one will get returned.
* @param server the server for that console
* @param appModule the app for that console
* @return the message console. Null if no corresponding console is found.
*/
protected MessageConsole findCloudFoundryConsole(IServer server, CloudFoundryApplicationModule appModule) {
CloudFoundryServer cfServer = (CloudFoundryServer)server.getAdapter(CloudFoundryServer.class);
return ConsoleManagerRegistry.getConsoleManager(cfServer).findCloudFoundryConsole(server, appModule);
}
@Override
public int getApplicationState(ICloudFoundryApplicationModule appModule) {
if (Logger.DETAILS) {
Logger.println(Logger.DETAILS_LEVEL, this, "getApplicationState", "Waiting for app to start: " + ((IModule)appModule).getName() + ", state=" + consoleMonitor.getApplicationState()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
return consoleMonitor.getApplicationState();
}
/**
* Get the regex pattern that defines that pattern string that matches console messages on each line to
* decide if the application is started.
* @return regex pattern for the match pattern.
*/
protected abstract String getAppStartedPattern();
@Override
public void startTracking(CloudFoundryApplicationModule appModule) {
if (server == null || appModule == null) {
return;
}
MessageConsole console = findCloudFoundryConsole(server, appModule);
if (console != null) {
if (Logger.INFO) {
Logger.println(Logger.INFO_LEVEL, this, "isApplicationStarted", "Start app state tracking: " + ((IModule)appModule).getName()); //$NON-NLS-1$ //$NON-NLS-2$
}
consoleMonitor = createPatternMatchListener(appModule);
console.addPatternMatchListener(consoleMonitor);
}
}
@Override
public void stopTracking(CloudFoundryApplicationModule appModule) {
if (server == null || consoleMonitor == null || appModule == null) {
return;
}
if (Logger.INFO) {
Logger.println(Logger.INFO_LEVEL, this, "stopTracking", "Stop app state tracking: " + ((IModule)appModule).getName()); //$NON-NLS-1$ //$NON-NLS-2$
}
MessageConsole console = findCloudFoundryConsole(server, appModule);
if (console != null) {
console.removePatternMatchListener(consoleMonitor);
}
}
}