blob: 19d2b5e7515f0ccbb1d099ab3338632866cd2a87 [file] [log] [blame]
/**
* Copyright (c) 2011, 2015 - Lunifera GmbH (Gross Enzersdorf, Austria), Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Florian Pirchner - Initial implementation
*/
package org.eclipse.osbp.ecview.vaadin.ide.preview;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import javax.servlet.ServletException;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.osbp.ecview.vaadin.ide.preview.jetty.PreviewJettyManager;
import org.eclipse.osbp.ecview.vaadin.ide.preview.parts.IDEPreviewHandler;
import org.eclipse.osbp.ecview.vaadin.ide.preview.web.EcviewPreviewVaadinServlet;
import org.eclipse.osbp.ecview.vaadin.ide.preview.web.ResourceProvider;
import org.eclipse.osbp.xtext.builder.ui.access.IXtextUtilService;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.eclipse.xtext.ui.shared.SharedStateModule;
import org.eclipse.xtext.util.Modules2;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleEvent;
import org.osgi.framework.BundleException;
import org.osgi.framework.BundleListener;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;
import org.osgi.service.http.HttpService;
import org.osgi.service.http.NamespaceException;
import org.osgi.util.tracker.ServiceTracker;
import org.osgi.util.tracker.ServiceTrackerCustomizer;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.Module;
import com.google.inject.Provider;
/**
* Activator is used by OSGi framework to notify about the start and stop of the
* bundle. The activator will look for the HttpService and registers the vaadin
* servlet at it.
*/
public class PreviewActivator extends AbstractUIPlugin implements
BundleListener {
final String PROPERTY_PREFIX = "org.eclipse.equinox.http.jetty."; //$NON-NLS-1$
public static final String BUNDLE_ID = "org.eclipse.osbp.ecview.vaadin.ide.preview";
/**
* name="http.port" type="Integer" (default: 0 -- first available port)
*/
public static final String PROP_HTTP_PORT = "http.port"; //$NON-NLS-1$
/**
* name="other.info" type="String"
*/
public static final String PROP_OTHER_INFO = "other.info"; //$NON-NLS-1$
public static final String PROP_MOBILEPREVIEW = "mobilepreview";
private static BundleContext context;
private static PreviewActivator plugin;
static BundleContext getContext() {
return context;
}
private Provider<IWorkspace> workspaceProvider;
// track the XtextUtilService
private ServiceTracker<IXtextUtilService, IXtextUtilService> xtextUtilServiceTracker;
// used to register servlets
private ResourceProvider resourceProvider;
// xtext and vaadin preview
private IXtextUtilService xtextUtilService;
private Injector injector;
// http services
private ServiceTracker<HttpService, HttpService> ideTracker;
// data exchange handler
private IDEPreviewHandler idePreviewHandler;
public void start(BundleContext bundleContext) throws Exception {
super.start(bundleContext);
PreviewActivator.context = bundleContext;
plugin = this;
idePreviewHandler = new IDEPreviewHandler();
// // Starts the jetty server
// startJetty();
startJetty(bundleContext);
resourceProvider = new ResourceProvider();
handleStartedBundles(context);
Module mergedModule = Modules2.mixin(new SharedStateModule(),
new IdeUiModule());
injector = Guice.createInjector(mergedModule);
workspaceProvider = injector.getProvider(IWorkspace.class);
// register this instance as a bundle listener to an reference to all
// vaadin bundles. Used to find the static resources.
bundleContext.addBundleListener(this);
xtextUtilServiceTracker = new ServiceTracker<IXtextUtilService, IXtextUtilService>(
bundleContext, IXtextUtilService.class, null);
xtextUtilServiceTracker.open();
xtextUtilService = xtextUtilServiceTracker.waitForService(5000);
registerIDEPreview(bundleContext);
}
public IWorkspace getWorkspace() {
return workspaceProvider.get();
}
/**
* Registers the ide preview.
*
* @param bundleContext
* @throws InvalidSyntaxException
* @throws InterruptedException
*/
protected void registerIDEPreview(final BundleContext bundleContext)
throws InvalidSyntaxException, InterruptedException {
// Start a HttpService-Tracker to get an instance of HttpService
String filter = String.format("(&(objectClass=%s)(%s=%s))",
HttpService.class.getName(),
PreviewJettyManager.PROP_OTHER_INFO,
PreviewJettyManager.PROP_IDEPREVIEW);
ideTracker = new ServiceTracker<HttpService, HttpService>(
bundleContext, bundleContext.createFilter(filter),
new ServiceTrackerCustomizer<HttpService, HttpService>() {
@Override
public HttpService addingService(
ServiceReference<HttpService> reference) {
HttpService ideService = bundleContext
.getService(reference);
try {
// register the servlet at the http service
ideService.registerServlet("/",
new EcviewPreviewVaadinServlet(), null,
resourceProvider);
} catch (ServletException e) {
e.printStackTrace();
} catch (NamespaceException e) {
e.printStackTrace();
}
return ideService;
}
@Override
public void modifiedService(
ServiceReference<HttpService> reference,
HttpService service) {
}
@Override
public void removedService(
ServiceReference<HttpService> reference,
HttpService service) {
}
});
ideTracker.open();
}
/**
* Start the jetty server.
*
* @param bundleContext
* @throws InterruptedException
* @throws IOException
*/
protected void startJetty(BundleContext bundleContext)
throws InterruptedException, IOException {
}
public void stop(BundleContext bundleContext) throws Exception {
resourceProvider = null;
idePreviewHandler.dispose();
idePreviewHandler = null;
ideTracker.close();
PreviewActivator.context = null;
plugin = null;
super.stop(bundleContext);
}
/**
* Tries to find proper started bundles and adds them to resource provider.
* Since bundle changed listener will not find them.
*
* @param context
*/
protected void handleStartedBundles(BundleContext context) {
for (Bundle bundle : context.getBundles()) {
String name = bundle.getSymbolicName();
if (name.startsWith("com.vaadin") || name.contains("widgetset")) {
resourceProvider.add(bundle);
} else if (bundle.getState() == Bundle.RESOLVED
&& name.equals("org.eclipse.equinox.http.jetty")) {
try {
bundle.start();
} catch (BundleException e) {
}
}
}
}
@Override
public void bundleChanged(BundleEvent event) {
// tracks the starting and stopping of vaadin bundles. If a bundle is a
// vaadin bundle it will be added to the resource provider for lookups.
String name = event.getBundle().getSymbolicName();
if (name.startsWith("com.vaadin") || name.contains("widgetset")) {
if (event.getType() != BundleEvent.STOPPED) {
resourceProvider.add(event.getBundle());
} else if (event.getType() == BundleEvent.STOPPED) {
resourceProvider.remove(event.getBundle());
}
}
}
/**
* Returns the handler for ide.
*
* @return
*/
public static IDEPreviewHandler getIDEPreviewHandler() {
return plugin.idePreviewHandler;
}
public static PreviewActivator getDefault() {
return plugin;
}
public IXtextUtilService getXtextUtilService() {
return xtextUtilService;
}
public Injector getInjector() {
return injector;
}
/**
* Tries to find the resource traversing all projects contained in the
* workspace.
*
* @param uri
* @return
*/
public URL findResource(String uri) {
IWorkspace ws = workspaceProvider.get();
for (IProject project : ws.getRoot().getProjects()) {
IResource resource = project.findMember(uri);
if (resource != null) {
try {
return resource.getLocationURI().toURL();
} catch (MalformedURLException e) {
}
}
}
return null;
}
// public void setSynchronizer(
// ECViewVaadinSynchronizer ecViewVaadinSynchronizer) {
// idePreviewHandler.setSynchronizer(ecViewVaadinSynchronizer);
// mobilePreviewHandler.setSynchronizer(ecViewVaadinSynchronizer);
// }
}