Skip to content
2 changes: 2 additions & 0 deletions META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -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
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -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.
7 changes: 6 additions & 1 deletion plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@
</command>
</toolbar>
</menuContribution>
</extension>
</extension>

<extension
point="org.eclipse.ui.startup">
<startup class="com.vaadin.plugin.EarlyStartup"/>
</extension>

</plugin>
27 changes: 27 additions & 0 deletions src/com/vaadin/plugin/Activator.java
Original file line number Diff line number Diff line change
@@ -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;
}
}
}
53 changes: 53 additions & 0 deletions src/com/vaadin/plugin/CopilotRestService.java
Original file line number Diff line number Diff line change
@@ -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<HttpService> 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;
}

}
21 changes: 21 additions & 0 deletions src/com/vaadin/plugin/CopilotServlet.java
Original file line number Diff line number Diff line change
@@ -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");
}
}
16 changes: 16 additions & 0 deletions src/com/vaadin/plugin/EarlyStartup.java
Original file line number Diff line number Diff line change
@@ -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
}
}