Index

javalightning

This is an experimental web framework by me, the documentation for my own use.

Hello World

create a bundle with the following Activator for hello world.
public class Activator extends LightningActivator {

	public Activator() {
		// all routes for this bundle are accessible under /hello
		super("hello");
	}

	@Override
	protected void init(BundleContext context) throws Exception {
		addPageService(builder -> {
			// return a simple String result on requests for /hello
			builder.newIdentityRouteGet("", () -> new PageController() {
				@Override
				public void invoke(ResponseBuilder response) throws Exception {
					response.setRenderer(new StringRenderer("hello world! " + new Date()));
				}
			});
			// allow access (true) regardless of context (e.g. ip, sessionId) on all routes
			builder.setSecurity(new PageSecurity((route, ctx) -> true));
		});
	}
}

mapping HTTP requests to controllers

routes

mapping a HTTP method to a relative path under bundle root
builder.newRoute(routeId).map(path, RouteType.GET,     () -> new PageController() { ... });
builder.newRoute(routeId).map(path, RouteType.POST,    () -> new PageController() { ... });
builder.newRoute(routeId).map(path, RouteType.HEAD,    () -> new PageController() { ... });
builder.newRoute(routeId).map(path, RouteType.PUT,     () -> new PageController() { ... });
builder.newRoute(routeId).map(path, RouteType.DELETE,  () -> new PageController() { ... });
builder.newRoute(routeId).map(path, RouteType.TRACE,   () -> new PageController() { ... });
builder.newRoute(routeId).map(path, RouteType.OPTIONS, () -> new PageController() { ... });
builder.newRoute(routeId).map(path, RouteType.CONNECT, () -> new PageController() { ... });
mapping with wildcard in path (run PageController for all pages starting with [bundle-name]/foo/)
builder.newRoute(routeId).mapGet("foo/*", () -> new PageController() {
shorthand: map GET:/[bundle-name]/[path] to controller
builder.newIdentityRouteGet(path, () -> new PageController() { ... }
shorthand: map POST:/[bundle-name] to controller
builder.newIdentityRoutePost(path, () -> new PageController() { ... }
shorthand: map both GET and POST requests to the same controller
builder.newIdentityRouteGetAndPost(path, () -> new PageController() { ... }
associated controller
public class StringRendererController implements PageController {
	@Override
	public void invoke(ResponseBuilder builder) {
		builder.setRenderer(new StringRenderer("Hello world!<br/>" + new Date()));
	}
}

dependency injection

public class BeanController implements PageController {
	
	@Bean
	private HttpServletRequest request;
	@Bean
	private HttpServletResponse response;
	@Bean
	private HttpSession session;
	@Bean
	private RequestContext context;
	@Bean
	private Parameters parameters;
	@Bean
	private BeanInjector injector;
	@Bean
	private ServiceCollection<MyServiceType> osgiService;

	@Override
	public void invoke(ResponseBuilder rb) {
....

basic renderers

render a simple String in the response
new StringRenderer("...")
render a (freemarker) template as response
new TemplateRenderer(template)
create file download response (renderer)
new DownloadRenderer(new File("/path/to/file.txt"))
new DownloadRenderer(new FileDownload("download-name.txt", new File("/path/to/file.txt")))
new InputStreamRenderer(new FileInputStream("/path/to/file.txt"))

redirects

performing an internal redirect from PageController
public void invoke(ResponseBuilder builder) {
	throw new InternalRedirectException(new UrlMapping("internal", "/mvc/prefix/example"));
}
performing an external redirect from PageController
public void invoke(ResponseBuilder builder) {
	throw new ExternalRedirectException(new UrlMapping("github", "http://www.github.com"));
}

template engine (freemarker)

template hello world
public class Activator extends LightningActivator {

	public Activator() {
		super("hello");
	}

	@Override
	protected void init(BundleContext context) throws Exception {
		addTemplateSource();
		addPageService(builder -> {
			builder.newIdentityRouteGet("template", () -> new AbstractTemplateController() {
				@Override
				public void invoke() throws Exception {
					model.put("key", "value");
					// template will be loaded from this bundles classpath /hello/template.ftlh
					setTemplate("/hello/template.ftlh");
				}
			});
			builder.setSecurity(new PageSecurity((route, ctx) -> true));
		});
	}
}
making (freemarker) templates available in the activator
addTemplateSource();
exposing a global variable to all templates
addTemplateSource(new TemplateGlobal() {
	@Override
	public String getName() {
		return "key";
	}

	@Override
	public Object getObject() {
		return "global";
	}
});
referencing the global in the (freemarker) template
${globals.get("date")?time}
referencing a HTTP parameter in the template
${parameter.get('key')}
${parameter.get('key', 'default')}
getting the remote url of a route
${lightning.getRemotePath('service', 'id')}

rules file syntax

blocking (rules processed in order of occurence)

block requests matching a path pattern
block
	pattern=robots.txt
allow all requests
allow

remapping external paths to internal paths

map favicon to /web/favicon.ico internally
map
    path=favicon.ico
    to=/web/favicon.ico
regex search and replace
map
    pattern=/replaceme~
    regex=^/replaceme
    to=/newpath

patterns

specific path
pattern=robots.txt
separate multiple patterns with commas
pattern=*.php, *.gch
block admin and admin/*
pattern=admin~

osgi properties for configuring the framework (defaults after '=')

remote URL (used in redirects)
com.eriklievaart.javalightning.bundle.host=localhost:8000
com.eriklievaart.javalightning.bundle.https=false
a rules file can be used to block urls and to redirect requested paths (e.g. favicon) to different internal paths
com.eriklievaart.javalightning.bundle.rules=[defaults to preset rules]
redirect incoming requests on root to home path
com.eriklievaart.javalightning.bundle.servlet_prefix=
hide stack traces and render a custom error page instead, takes a redirect path (e.g. /oops)
com.eriklievaart.javalightning.bundle.exception.redirect=
specify directory containing freemarker templates (for real time editing during development)
com.eriklievaart.javalightning.freemarker.path=/home/eazy/Development/git/hufront/main/resources
com.eriklievaart.javalightning.freemarker.timeout=60000
email properties
com.eriklievaart.javalightning.email.host=localhost
logging properties
com.eriklievaart.osgi.logging.console=true
com.eriklievaart.osgi.logging.file=
com.eriklievaart.osgi.logging.file.level=TRACE
log to an osgi service
com.eriklievaart.osgi.logging.service=true
com.eriklievaart.osgi.logging.date=
example logging format
com.eriklievaart.osgi.logging.date=yyyy-MM-dd HH:mm:ss

antastic config

src/main/config/antastic.properties

src/main/config/dependencies.txt
javalightning-bundle @local @snapshot
javalightning-email @local @snapshot
javalightning-freemarker @local @snapshot
osgi-status @local @snapshot
osgi-toolkit @local @snapshot
toolkit-ant @local @snapshot
toolkit-bean @local @snapshot
toolkit-convert @local @snapshot
toolkit-io @local @snapshot
toolkit-lang @local @snapshot
toolkit-logging @local @snapshot
toolkit-reflect @local @snapshot
toolkit-vfs @local @snapshot
freemarker org.freemarker 2.3.28
org.apache.felix.http.api org.apache.felix 3.0.0
org.apache.felix.http.jetty org.apache.felix 4.0.6
org.apache.felix.http.servlet-api org.apache.felix 1.1.2