/**
* Copyright (c) 2013-2016 Angelo ZERR and Genuitec LLC.
* 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:
* Piotr Tomiak <piotr@genuitec.com> - initial API and implementation
*/
package tern.eclipse.ide.internal.ui;
import java.io.IOException;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.text.IDocument;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PlatformUI;
import tern.ITernFile;
import tern.ITernProject;
import tern.TernResourcesManager;
import tern.eclipse.ide.core.resources.TernDocumentFile;
import tern.eclipse.ide.internal.ui.util.AllInOneWorkbenchListener;
import tern.eclipse.ide.ui.TernUIPlugin;
/**
* This class is responsible for tracking currently activated editors and
* triggering synchronization of files to Tern Server. Following rules are
* applied:
* <ul>
* <li>if JS or HTML file is opened, ensureSynch is called</li>
* <li>if JS editor looses focus, it's contents are uploaded to tern server</li>
* <li>if HTML editor looses focus, it is removed from the server on the next
* synchronization</li>
* </ul>
*/
public class EditorActivationTracker extends AllInOneWorkbenchListener {
private static final EditorActivationTracker INSTANCE = new EditorActivationTracker();
public static EditorActivationTracker getInstance() {
return INSTANCE;
}
private EditorActivationTracker() {
initialize();
// initialize sync if needed
Display.getDefault().asyncExec(new Runnable() {
@Override
public void run() {
IWorkbench bench = PlatformUI.getWorkbench();
if (bench.getWorkbenchWindowCount() > 0) {
partActivated(bench.getActiveWorkbenchWindow()
.getActivePage().getActivePart());
}
}
});
}
@Override
public void partActivated(IWorkbenchPart part) {
IFile file = getFile(part);
if (file != null
&& (TernResourcesManager.isHTMLFile(file) || TernResourcesManager
.isJSFile(file))) {
// Ensure that everything is synchronized when JS or HTML file is
// opened
final ITernProject project = TernResourcesManager
.getTernProject(file.getProject());
if (project != null) {
new Job("Synchronizing script resources with Tern server...") {
@Override
protected IStatus run(IProgressMonitor monitor) {
monitor.beginTask("", -1); //$NON-NLS-1$
project.getFileSynchronizer().ensureSynchronized();
return Status.OK_STATUS;
}
}.schedule();
}
}
}
@Override
public void partDeactivated(IWorkbenchPart part) {
IFile file = getFile(part);
boolean isHtml = false;
if (file != null
&& (TernResourcesManager.isJSFile(file) || (isHtml = TernResourcesManager
.isHTMLFile(file)))) {
final ITernProject project = TernResourcesManager
.getTernProject(file.getProject());
if (project != null) {
if (isHtml) {
// Remove HTML file contents from the server next time
// content assist is invoked
project.getFileSynchronizer().refresh(file);
return;
}
IDocument document = (IDocument) part
.getAdapter(IDocument.class);
if (document != null) {
// Synchronize file with the server, when user moves to the
// other editor without saving content. This allows Tern
// server to calculate completion proposals based on unsaved
// content.
final ITernFile tf = new TernDocumentFile(file, document);
new Job("Synchronizing sources with Tern server") {
@Override
protected IStatus run(IProgressMonitor monitor) {
try {
project.getFileSynchronizer().synchronizeFile(
tf);
} catch (IOException e) {
TernUIPlugin
.getDefault()
.getLog()
.log(new Status(IStatus.ERROR,
TernUIPlugin.PLUGIN_ID, e
.getMessage(), e));
}
return Status.OK_STATUS;
}
}.schedule();
}
}
}
}
private IFile getFile(IWorkbenchPart part) {
if (part instanceof IEditorPart) {
IEditorInput input = ((IEditorPart) part).getEditorInput();
if (input instanceof IFileEditorInput) {
return ((IFileEditorInput) input).getFile();
}
}
return null;
}
}