/*******************************************************************************
* Copyright (c) 2005, 2007 IBM Corporation and others.
* 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
*
*******************************************************************************/
package com.aptana.interactive_console.console.ui;
import java.lang.ref.WeakReference;
import java.util.List;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.debug.ui.console.IConsoleLineTracker;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.text.ITextHover;
import org.eclipse.jface.text.contentassist.ContentAssistant;
import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
import org.eclipse.jface.text.quickassist.IQuickAssistProcessor;
import org.eclipse.jface.text.quickassist.QuickAssistAssistant;
import org.eclipse.jface.text.source.SourceViewerConfiguration;
import org.eclipse.swt.graphics.Color;
import org.eclipse.ui.console.IConsoleDocumentPartitioner;
import org.eclipse.ui.console.IConsoleView;
import org.eclipse.ui.console.TextConsole;
import org.eclipse.ui.part.IPageBookViewPage;
import com.aptana.interactive_console.console.IScriptConsoleInterpreter;
import com.aptana.interactive_console.console.InterpreterResponse;
import com.aptana.interactive_console.console.ScriptConsoleHistory;
import com.aptana.interactive_console.console.ScriptConsolePrompt;
import com.aptana.interactive_console.console.ui.internal.ICommandHandler;
import com.aptana.interactive_console.console.ui.internal.IHandleScriptAutoEditStrategy;
import com.aptana.interactive_console.console.ui.internal.ScriptConsolePage;
import com.aptana.interactive_console.console.ui.internal.ScriptConsoleSession;
import com.aptana.interactive_console.console.ui.internal.ScriptConsoleViewer;
import com.aptana.interactive_console.console.ui.internal.actions.AbstractHandleBackspaceAction;
import com.aptana.shared_core.callbacks.ICallback;
import com.aptana.shared_core.structure.Tuple;
import com.aptana.shared_core.utils.Reflection;
public abstract class ScriptConsole extends TextConsole implements ICommandHandler {
protected ScriptConsolePage page;
protected ScriptConsolePartitioner partitioner;
protected IScriptConsoleInterpreter interpreter;
protected ScriptConsoleSession session;
protected ListenerList consoleListeners;
protected ScriptConsolePrompt prompt;
protected ScriptConsoleHistory history;
private WeakReference<ScriptConsoleViewer> viewer;
protected IConsoleDocumentPartitioner getPartitioner() {
return partitioner;
}
public ScriptConsole(String consoleName, String consoleType, IScriptConsoleInterpreter interpreterArg) {
super(consoleName, consoleType, null, true);
this.interpreter = interpreterArg;
this.consoleListeners = new ListenerList(ListenerList.IDENTITY);
this.prompt = createConsolePrompt();
this.history = new ScriptConsoleHistory();
this.session = new ScriptConsoleSession();
addListener(this.session);
partitioner = new ScriptConsolePartitioner();
getDocument().setDocumentPartitioner(partitioner);
partitioner.connect(getDocument());
}
/**
* @return the assistant that should handle content assist requests (code completion)
*/
protected abstract IContentAssistProcessor createConsoleCompletionProcessor(ContentAssistant pyContentAssistant);
/**
* @return the assistant that should handle quick assist requests (quick fixes)
*/
protected abstract IQuickAssistProcessor createConsoleQuickAssistProcessor(QuickAssistAssistant quickAssist);
/**
* @return the text hover to be used in the console.
*/
protected abstract ITextHover createHover();
/**
* @return the console prompt that should be used.
*/
protected abstract ScriptConsolePrompt createConsolePrompt();
public IScriptConsoleSession getSession() {
return session;
}
public void addListener(IScriptConsoleListener listener) {
consoleListeners.add(listener);
}
public void removeListener(IScriptConsoleListener listener) {
consoleListeners.remove(listener);
}
protected void setInterpreter(IScriptConsoleInterpreter interpreter) {
this.interpreter = interpreter;
}
public ScriptConsolePrompt getPrompt() {
return prompt;
}
public ScriptConsoleHistory getHistory() {
return history;
}
/**
* Creates the actual page to be shown to the user.
*/
@Override
public IPageBookViewPage createPage(IConsoleView view) {
page = new ScriptConsolePage(this, view, createSourceViewerConfiguration());
return page;
}
protected abstract SourceViewerConfiguration createSourceViewerConfiguration();
/**
* Clears the console
*/
public void clearConsole() {
page.clearConsolePage();
}
/**
* Handles some command that the user entered
*
* @param userInput that's the command to be evaluated by the user.
*/
public void handleCommand(String userInput, final ICallback<Object, InterpreterResponse> onResponseReceived,
final ICallback<Object, Tuple<String, String>> onContentsReceived) {
final Object[] listeners = consoleListeners.getListeners();
//notify about the user request
for (Object listener : listeners) {
((IScriptConsoleListener) listener).userRequest(userInput, prompt);
}
//executes the user input in the interpreter
interpreter.exec(userInput, new ICallback<Object, InterpreterResponse>() {
public Object call(final InterpreterResponse response) {
//sets the new mode
prompt.setMode(!response.more);
prompt.setNeedInput(response.need_input);
//notify about the console answer
for (Object listener : listeners) {
((IScriptConsoleListener) listener).interpreterResponse(response, prompt);
}
onResponseReceived.call(response);
return null;
}
}, onContentsReceived);
}
/**
* Finishes the interpreter (and stops the communication)
*/
public void terminate() {
try {
interpreter.close();
} catch (Exception e) {
}
interpreter = null;
}
public void setViewer(ScriptConsoleViewer scriptConsoleViewer) {
this.viewer = new WeakReference<ScriptConsoleViewer>(scriptConsoleViewer);
}
public ScriptConsoleViewer getViewer() {
if (this.viewer != null) {
return this.viewer.get();
}
return null;
}
/**
* Must be overridden to create a style provider for the console (configures colors)
* @return a style provider.
*/
public abstract IConsoleStyleProvider createStyleProvider();
/**
* @return a list of trackers that'll identify links in the console.
*/
public abstract List<IConsoleLineTracker> getLineTrackers();
/**
* @return the commands that should be initially set in the prompt.
*/
public abstract String getInitialCommands();
/**
* Used for backward compatibility because the setBackground/getBackground is not available for eclipse 3.2
*/
private Color fPydevConsoleBackground;
/**
* Used for backward compatibility because the setBackground/getBackground is not available for eclipse 3.2
*/
public Color getPydevConsoleBackground() {
try {
Color ret = (Color) Reflection.invoke(this, "getBackground");
return ret;
} catch (Throwable e) {
//not available in eclipse 3.2
return fPydevConsoleBackground;
}
}
/**
* Used for backward compatibility because the setBackground/getBackground is not available for eclipse 3.2
*/
public void setPydevConsoleBackground(Color color) {
try {
Reflection.invoke(this, "setBackground", color);
} catch (Throwable e) {
//not available in eclipse 3.2
fPydevConsoleBackground = color;
}
}
public Object getInterpreterInfo() {
return this.interpreter.getInterpreterInfo();
}
/**
* @return
*/
public abstract boolean getFocusOnStart();
/**
* Enable/Disable linking of the debug console with the suspended frame.
*/
public void linkWithDebugSelection(boolean isLinkedWithDebug) {
this.interpreter.linkWithDebugSelection(isLinkedWithDebug);
}
public abstract AbstractHandleBackspaceAction getBackspaceAction();
public abstract void createActions(IToolBarManager toolbarManager);
public abstract IHandleScriptAutoEditStrategy getAutoEditStrategy();
}