diff --git a/META-INF/MANIFEST.MF b/META-INF/MANIFEST.MF index e3b70f5..928f7e9 100644 --- a/META-INF/MANIFEST.MF +++ b/META-INF/MANIFEST.MF @@ -5,5 +5,7 @@ Bundle-SymbolicName: vaadin-eclipse-plugin;singleton:=true Bundle-Version: 1.0.0.qualifier Bundle-Vendor: Vaadin Require-Bundle: org.eclipse.ui +Bundle-Activator: com.vaadin.plugin.Activator +Import-Package: javax.servlet,javax.servlet.http,org.osgi.service.http,org.osgi.framework Automatic-Module-Name: vaadin.eclipse.plugin Bundle-RequiredExecutionEnvironment: JavaSE-21 diff --git a/README.md b/README.md index 362e39d..a4a7b48 100644 --- a/README.md +++ b/README.md @@ -1 +1,8 @@ # eclipse-plugin + +This repository contains a minimal Eclipse plug-in example for Vaadin. +At workbench startup the plug-in is activated via an `org.eclipse.ui.startup` extension. The `BundleActivator` registers a servlet using the OSGi `HttpService`. The servlet exposes a unique `/api/{serviceName}` endpoint on the container's HTTP server, and the full endpoint URL is stored in the `vaadin.copilot.endpoint` system property. + +## License + +This project is licensed under the Apache License 2.0. See the [LICENSE](LICENSE) file for details. diff --git a/plugin.xml b/plugin.xml index d85dcef..d845d6a 100644 --- a/plugin.xml +++ b/plugin.xml @@ -57,6 +57,11 @@ - + + + + + diff --git a/src/com/vaadin/plugin/Activator.java b/src/com/vaadin/plugin/Activator.java new file mode 100644 index 0000000..f5165ad --- /dev/null +++ b/src/com/vaadin/plugin/Activator.java @@ -0,0 +1,27 @@ +package com.vaadin.plugin; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; + +/** + * Bundle activator that starts the REST service when the plug-in is + * activated and stops it on shutdown. + */ +public class Activator implements BundleActivator { + private CopilotRestService restService; + + @Override + public void start(BundleContext context) throws Exception { + restService = new CopilotRestService(); + restService.start(context); + System.setProperty("vaadin.copilot.endpoint", restService.getEndpoint()); + } + + @Override + public void stop(BundleContext context) throws Exception { + if (restService != null) { + restService.stop(context); + restService = null; + } + } +} diff --git a/src/com/vaadin/plugin/CopilotRestService.java b/src/com/vaadin/plugin/CopilotRestService.java new file mode 100644 index 0000000..14ea271 --- /dev/null +++ b/src/com/vaadin/plugin/CopilotRestService.java @@ -0,0 +1,53 @@ +package com.vaadin.plugin; + +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceReference; +import org.osgi.service.http.HttpService; +import org.osgi.service.http.NamespaceException; +import javax.servlet.ServletException; +import java.io.IOException; +import java.util.UUID; + +/** + * Registers a simple servlet for Vaadin Copilot integration using the OSGi + * {@link HttpService}. The servlet is bound to a unique "/api/{serviceName}" + * alias and the full endpoint URL can be retrieved via {@link #getEndpoint()}. + */ +public class CopilotRestService { + private HttpService httpService; + private ServiceReference serviceRef; + private String serviceName; + private String endpoint; + + public void start(BundleContext context) throws ServletException, NamespaceException { + serviceName = "copilot-" + UUID.randomUUID(); + serviceRef = context.getServiceReference(HttpService.class); + if (serviceRef == null) { + throw new IllegalStateException("HttpService not available"); + } + httpService = context.getService(serviceRef); + String alias = "/api/" + serviceName; + httpService.registerServlet(alias, new CopilotServlet(), null, null); + String port = context.getProperty("org.osgi.service.http.port"); + if (port == null) { + port = "8080"; + } + endpoint = "http://localhost:" + port + alias; + System.out.println("Copilot REST service registered at " + endpoint); + } + + public void stop(BundleContext context) { + if (httpService != null) { + String alias = "/api/" + serviceName; + httpService.unregister(alias); + context.ungetService(serviceRef); + httpService = null; + serviceRef = null; + } + } + + public String getEndpoint() { + return endpoint; + } + +} diff --git a/src/com/vaadin/plugin/CopilotServlet.java b/src/com/vaadin/plugin/CopilotServlet.java new file mode 100644 index 0000000..126b8c7 --- /dev/null +++ b/src/com/vaadin/plugin/CopilotServlet.java @@ -0,0 +1,21 @@ +package com.vaadin.plugin; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.stream.Collectors; + +/** + * Simple servlet used by {@link CopilotRestService} to receive Copilot requests. + */ +public class CopilotServlet extends HttpServlet { + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + String body = req.getReader().lines().collect(Collectors.joining(System.lineSeparator())); + System.out.println("Received Copilot request: " + body); + resp.setStatus(HttpServletResponse.SC_OK); + resp.getWriter().write("OK"); + } +} diff --git a/src/com/vaadin/plugin/EarlyStartup.java b/src/com/vaadin/plugin/EarlyStartup.java new file mode 100644 index 0000000..cab972f --- /dev/null +++ b/src/com/vaadin/plugin/EarlyStartup.java @@ -0,0 +1,16 @@ +package com.vaadin.plugin; + +import org.eclipse.ui.IStartup; + + +/** + * Starts the REST service when the workbench starts. The service is registered + * using the OSGi {@code HttpService} and stopped when the bundle shuts down. + */ +public class EarlyStartup implements IStartup { + + @Override + public void earlyStartup() { + // Trigger plug-in activation so the BundleActivator runs + } +}