Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion bundles/org.eclipse.e4.ui.workbench/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,10 @@ Import-Package: com.ibm.icu.text,
jakarta.annotation;version="[2.1.0,3.0.0)",
jakarta.inject;version="[2.0.0,3.0.0)",
org.osgi.service.component.annotations;version="1.2.0";resolution:=optional,
org.osgi.service.event;version="1.3.0"
org.osgi.service.event;version="1.3.0",
org.osgi.service.servlet.context;version="[2.0.0,3.0.0)",
org.osgi.service.servlet.runtime;version="[2.0.0,3.0.0)",
org.osgi.service.servlet.runtime.dto;version="[2.0.0,3.0.0)",
org.osgi.service.servlet.whiteboard;version="[2.0.0,3.0.0)",
org.osgi.service.servlet.whiteboard.annotations;version="[2.0.0,3.0.0)",
org.osgi.service.servlet.whiteboard.propertytypes;version="[2.0.0,3.0.0)"
3 changes: 2 additions & 1 deletion bundles/org.eclipse.rap.rwt.osgi/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ Import-Package: jakarta.servlet;version="[5.0.0,7.0.0)",
org.eclipse.rap.rwt.internal.application;version="[4.8.0,5.0.0)",
org.eclipse.rap.rwt.internal.lifecycle;version="[4.8.0,5.0.0)",
org.eclipse.rap.rwt.service;version="[4.8.0,5.0.0)",
org.eclipse.rap.service.http;version="[4.8.0,5.0.0)",
org.osgi.framework;version="[1.3.0,2.0.0)",
org.osgi.service.log;version="[1.3.0,2.0.0)",
org.osgi.service.servlet.runtime;version="[2.0.0,3.0.0)",
org.osgi.service.servlet.whiteboard;version="[2.0.0,3.0.0)",
org.osgi.util.tracker;version="[1.4.0,2.0.0)"
Bundle-Activator: org.eclipse.rap.rwt.osgi.internal.Activator
Export-Package: org.eclipse.rap.rwt.osgi;version="4.8.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@
package org.eclipse.rap.rwt.osgi;

import org.eclipse.rap.rwt.application.ApplicationConfiguration;
import org.eclipse.rap.service.http.HttpContext;
import org.eclipse.rap.service.http.HttpService;

import org.osgi.service.servlet.runtime.HttpServiceRuntime;

/**
* A launcher for RWT applications in the OSGi environment. An instance of this interface will be
Expand Down Expand Up @@ -45,20 +43,18 @@ public interface ApplicationLauncher {
public static final String PROPERTY_CONTEXT_NAME = "contextName";

/**
* Launches an application with the given configuration at the given HTTPService.
* Launches an application with the given configuration at the given HttpServiceRuntime.
*
* @param configuration the configuration of the application to start
* @param httpService the http service to start the application at
* @param httpContext the http context to use, or <code>null</code> to use the default context
* @param httpService the HttpServiceRuntime
* @param contextName the context name of the application, defines the first URL path segment to
* the application
* @param contextDirectory the name of a directory to store static web resources
* @return a reference to the application started
* @since 4.0
*/
ApplicationReference launch( ApplicationConfiguration configuration,
HttpService httpService,
HttpContext httpContext,
HttpServiceRuntime httpService,
String contextName,
String contextDirectory );

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,17 @@
import org.eclipse.rap.rwt.osgi.ApplicationLauncher;
import org.eclipse.rap.rwt.osgi.ApplicationReference;
import org.eclipse.rap.rwt.osgi.internal.ServiceContainer.ServiceHolder;
import org.eclipse.rap.service.http.HttpContext;
import org.eclipse.rap.service.http.HttpService;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.service.log.LogService;
import org.osgi.service.servlet.runtime.HttpServiceRuntime;


public class ApplicationLauncherImpl implements ApplicationLauncher {

private final Object lock;
private final ServiceContainer<ApplicationConfiguration> configurations;
private final ServiceContainer<HttpService> httpServices;
private final ServiceContainer<HttpServiceRuntime> httpServices;
private final HashSet<ApplicationReferenceImpl> applicationReferences;
private BundleContext bundleContext;

Expand All @@ -42,16 +41,16 @@ public ApplicationLauncherImpl( BundleContext bundleContext ) {
this.bundleContext = bundleContext;
}

public HttpService addHttpService( ServiceReference<HttpService> reference ) {
ServiceHolder<HttpService> httpServiceHolder;
public HttpServiceRuntime addHttpService( ServiceReference<HttpServiceRuntime> reference ) {
ServiceHolder<HttpServiceRuntime> httpServiceHolder;
synchronized( lock ) {
httpServiceHolder = httpServices.add( reference );
launchAtHttpService( httpServiceHolder );
}
return httpServiceHolder.getService();
}

public void removeHttpService( HttpService httpService ) {
public void removeHttpService( HttpServiceRuntime httpService ) {
synchronized( lock ) {
httpServices.remove( httpService );
stopApplicationReferences( httpService );
Expand All @@ -77,28 +76,25 @@ public void removeConfiguration( ApplicationConfiguration configuration ) {

@Override
public ApplicationReference launch( ApplicationConfiguration configuration,
HttpService httpService,
HttpContext httpContext,
HttpServiceRuntime httpService,
String contextName,
String contextDirectory )
{
synchronized( lock ) {
if( isAlive() ) {
return doLaunch( configuration, httpService, httpContext, contextName, contextDirectory );
return doLaunch( configuration, httpService, contextName, contextDirectory );
}
return null;
}
}

private ApplicationReferenceImpl doLaunch( ApplicationConfiguration configuration,
HttpService httpService,
HttpContext httpContext,
HttpServiceRuntime httpService,
String contextName,
String contextDirectory )
{
ApplicationReferenceImpl result = new ApplicationReferenceImpl( configuration,
httpService,
httpContext,
contextName,
contextDirectory,
this );
Expand Down Expand Up @@ -134,7 +130,7 @@ BundleContext getBundleContext() {
return bundleContext;
}

private void launchAtHttpService( ServiceHolder<HttpService> httpServiceHolder ) {
private void launchAtHttpService( ServiceHolder<HttpServiceRuntime> httpServiceHolder ) {
ServiceHolder<ApplicationConfiguration>[] services = configurations.getServices();
for( ServiceHolder<ApplicationConfiguration> configurationHolder : services ) {
if( matches( httpServiceHolder, configurationHolder ) ) {
Expand All @@ -145,23 +141,23 @@ private void launchAtHttpService( ServiceHolder<HttpService> httpServiceHolder )

private void launchWithConfiguration( ServiceHolder<ApplicationConfiguration> configurationHolder )
{
ServiceHolder<HttpService>[] services = httpServices.getServices();
for( ServiceHolder<HttpService> httpServiceHolder : services ) {
ServiceHolder<HttpServiceRuntime>[] services = httpServices.getServices();
for( ServiceHolder<HttpServiceRuntime> httpServiceHolder : services ) {
if( matches( httpServiceHolder, configurationHolder ) ) {
launch( configurationHolder, httpServiceHolder );
}
}
}

private void launch( ServiceHolder<ApplicationConfiguration> configurationHolder,
ServiceHolder<HttpService> httpServiceHolder )
ServiceHolder<HttpServiceRuntime> httpServiceHolder )
{
ApplicationConfiguration configuration = configurationHolder.getService();
HttpService httpService = httpServiceHolder.getService();
HttpServiceRuntime httpService = httpServiceHolder.getService();
String contextName = getContextName( configurationHolder );
String contextLocation = getLocation( contextName, configuration, httpService );
try {
launch( configuration, httpService, null, contextName, contextLocation );
launch( configuration, httpService, contextName, contextLocation );
} catch( RuntimeException rte ) {
logProblem( "Unable to start RWT application.", rte );
}
Expand Down Expand Up @@ -197,10 +193,10 @@ void stopApplicationReference( ApplicationReferenceImpl applicationReference ) {
}
}

private static boolean matches( ServiceHolder<HttpService> httpServiceHolder,
private static boolean matches( ServiceHolder<HttpServiceRuntime> httpServiceHolder,
ServiceHolder<ApplicationConfiguration> configurationHolder )
{
ServiceReference<HttpService> httpServiceRef = httpServiceHolder.getReference();
ServiceReference<HttpServiceRuntime> httpServiceRef = httpServiceHolder.getReference();
ServiceReference<ApplicationConfiguration> configurationRef = configurationHolder.getReference();
return new Matcher( httpServiceRef, configurationRef ).matches();
}
Expand All @@ -219,7 +215,7 @@ private void logProblem( String failureMessage, Throwable failure ) {

String getLocation( String contextName,
ApplicationConfiguration configuration,
HttpService service )
HttpServiceRuntime service )
{
String pathToContext = getContextFileName( contextName, configuration, service );
File dataFile = bundleContext.getDataFile( pathToContext );
Expand All @@ -228,7 +224,7 @@ String getLocation( String contextName,

static String getContextFileName( String name,
ApplicationConfiguration configuration,
HttpService service )
HttpServiceRuntime service )
{
return new StringBuilder()
.append( name == null ? "rwtcontext" : name )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,21 @@
package org.eclipse.rap.rwt.osgi.internal;

import java.util.Collection;
import java.util.Dictionary;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;

import org.eclipse.rap.rwt.application.ApplicationConfiguration;
import org.eclipse.rap.rwt.application.ApplicationRunner;
import org.eclipse.rap.rwt.engine.RWTServlet;
import org.eclipse.rap.rwt.osgi.ApplicationReference;
import org.eclipse.rap.rwt.service.ApplicationContext;
import org.eclipse.rap.service.http.HttpContext;
import org.eclipse.rap.service.http.HttpService;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import org.osgi.framework.*;
import org.osgi.service.servlet.runtime.HttpServiceRuntime;
import org.osgi.service.servlet.whiteboard.HttpWhiteboardConstants;

import jakarta.servlet.Servlet;
import jakarta.servlet.ServletContext;
import jakarta.servlet.http.HttpServlet;

Expand All @@ -34,29 +38,32 @@ class ApplicationReferenceImpl implements ApplicationReference {
static final String RAP_HTTP_CONTEXT_CLASS_NAME = "org.eclipse.rap.ui.internal.RAPHttpContext";

private ApplicationConfiguration configuration;
private HttpService httpService;
private HttpContext httpContext;
private HttpServiceRuntime httpService;
private String contextLocation;
private String contextName;
private ServletContext servletContextWrapper;
private ApplicationRunner applicationRunner;
private ApplicationLauncherImpl applicationLauncher;
private ServiceRegistration<?> serviceRegistration;
private volatile boolean alive;
private BundleContext bundleContext;

// Whiteboard-Registrierungen, damit wir sie beim Stoppen wieder abmelden koennen.
private final Map<String, ServiceRegistration<Servlet>> servletRegistrations = new HashMap<>();
private ServiceRegistration<?> resourceRegistration;

ApplicationReferenceImpl( ApplicationConfiguration configuration,
HttpService httpService,
HttpContext httpContext,
HttpServiceRuntime httpService,
String contextName,
String contextLocation,
ApplicationLauncherImpl applicationLauncher )
{
this.configuration = configuration;
this.httpService = httpService;
this.httpContext = isRAPContext( httpContext ) ? httpContext : wrapHttpContext( httpContext );
this.contextLocation = contextLocation;
this.contextName = contextName;
this.applicationLauncher = applicationLauncher;
this.bundleContext = FrameworkUtil.getBundle( getClass() ).getBundleContext();
}

void start() {
Expand Down Expand Up @@ -154,18 +161,6 @@ private void unregisterServletContextProviderServlet() {
unregisterServlet( SERVLET_CONTEXT_FINDER_ALIAS );
}

private HttpContext wrapHttpContext( HttpContext context ) {
HttpContext wrapped = context != null ? context : httpService.createDefaultHttpContext();
return new HttpContextWrapper( wrapped );
}

private static boolean isRAPContext( HttpContext context ) {
if( context != null ) {
return RAP_HTTP_CONTEXT_CLASS_NAME.equals( context.getClass().getName() );
}
return false;
}

private HttpServlet registerServletContextProviderServlet() {
HttpServlet result = new HttpServlet() {
private static final long serialVersionUID = 1L;
Expand All @@ -186,8 +181,17 @@ private BundleContext getBundleContext() {

private void registerServlet( String alias, HttpServlet servlet ) {
try {
String pattern = getContextSegment() + alias;
HttpServlet wrapper = new CutOffContextPathWrapper( servlet, servletContextWrapper, alias );
httpService.registerServlet( getContextSegment() + alias, wrapper, null, httpContext );
Dictionary<String, Object> properties = new Hashtable<>();
// Muster, unter dem das Servlet erreichbar ist (Whiteboard-Spec).
properties.put( HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, pattern );
// Eindeutiger Name; optional, aber empfohlen.
properties.put( HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_NAME,
"rwt-servlet" + pattern );
ServiceRegistration<Servlet> registration
= bundleContext.registerService( Servlet.class, wrapper, properties );
servletRegistrations.put( pattern, registration );
} catch( RuntimeException rte ) {
throw rte;
} catch( Exception shouldNotHappen ) {
Expand All @@ -197,9 +201,16 @@ private void registerServlet( String alias, HttpServlet servlet ) {

private void registerResourceDirectory() {
String alias = ApplicationRunner.RESOURCES;
String location = contextLocation + "/" + alias;
String prefix = contextLocation + "/" + alias;
String pattern = getContextSegment() + "/" + alias + "/*";
try {
httpService.registerResources( getContextSegment() + "/" + alias, location, httpContext );
Dictionary<String, Object> properties = new Hashtable<>();
// Muster + Prefix fuer eine Whiteboard-Ressourcenregistrierung.
properties.put( HttpWhiteboardConstants.HTTP_WHITEBOARD_RESOURCE_PATTERN, pattern );
properties.put( HttpWhiteboardConstants.HTTP_WHITEBOARD_RESOURCE_PREFIX, prefix );
// Ein beliebiges Marker-Objekt genuegt als Service-Instanz.
resourceRegistration
= bundleContext.registerService( Object.class, new Object(), properties );
} catch( RuntimeException rte ) {
throw rte;
} catch( Exception shouldNotHappen ) {
Expand All @@ -209,8 +220,6 @@ private void registerResourceDirectory() {

private void clearFields() {
applicationRunner = null;
httpService = null;
httpContext = null;
configuration = null;
contextName = null;
contextLocation = null;
Expand All @@ -219,11 +228,27 @@ private void clearFields() {
}

private void unregisterServlet( String alias ) {
httpService.unregister( getContextSegment() + alias );
String pattern = getContextSegment() + alias;
ServiceRegistration<Servlet> registration = servletRegistrations.remove( pattern );
if( registration != null ) {
try {
registration.unregister();
} catch( IllegalStateException alreadyUnregistered ) {
// Registrierung wurde bereits abgemeldet - ignorieren.
}
}
}

private void unregisterResourcesDirectory() {
httpService.unregister( getContextSegment() + "/" + ApplicationRunner.RESOURCES );
if( resourceRegistration != null ) {
try {
resourceRegistration.unregister();
} catch( IllegalStateException alreadyUnregistered ) {
// bereits abgemeldet - ignorieren.
} finally {
resourceRegistration = null;
}
}
}

private void notifyAboutToStop() {
Expand All @@ -249,5 +274,4 @@ private void markAlive() {
private void markNotAlive() {
alive = false;
}

}
}
Loading