What’s next for e4
Tom Schindl <tom.schindl@bestsolution.at> Twitter: @tomsontom Website: http://www.bestsolution.at
Whats next for e4 Tom Schindl <tom.schindl@bestsolution.at> - - PowerPoint PPT Presentation
Whats next for e4 Tom Schindl <tom.schindl@bestsolution.at> Twitter: @tomsontom Website: http://www.bestsolution.at About Tom CTO BestSolution.at Systemhaus GmbH Eclipse Committer e4 Platform EMF Project lead
Tom Schindl <tom.schindl@bestsolution.at> Twitter: @tomsontom Website: http://www.bestsolution.at
(c) BestSolution.at - Licensed under Creative Commons Attribution-NonCommerical-ShareAlike 3.0
About Tom
e4 spec’ed world
Application Model
The Brain
(OSGi) Service Components & DI-Container
Nervous system
UI (SWT/FX/…)
Sense organ
combat world
Application Model
The (split) Brain Nervous system
UI (SWT/ FX/…)
Sense organ
$n - Registries Legacy Compat- Layer DI & Service
How OSGi spec’ed the world
Service-API
(requires NOTHING)
Service-Impl 1
(requires Equinox, …)
Service-Impl $N
(requires Felix, …)
Consumer
(requires Service-API)
How e4 core implemented it
Service-API
(requires Equinox)
Service-Impl 1 Consumer
(requires Service-API & transitive Equinox)
Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-SymbolicName: org.eclipse.e4.core.di … Import-Package: javax.annotation, javax.inject;version=„1.0.0"
Wanna see an example
Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-SymbolicName: org.eclipse.e4.core.di … Import-Package: javax.annotation, javax.inject;version=„1.0.0"
Wanna see an example
Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-SymbolicName: org.eclipse.e4.core.di … Import-Package: javax.annotation, javax.inject;version="1.0.0",
Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-SymbolicName: org.eclipse.e4.core.di … Import-Package: javax.annotation, javax.inject;version=„1.0.0"
Wanna see an example
Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-SymbolicName: org.eclipse.e4.core.di … Import-Package: javax.annotation, javax.inject;version="1.0.0",
ONLY NEEDED BY IMPL
Ideal OSGi App world
Ideal OSGi App world
A-API-Bundle
(requires NOTHING)
Ideal OSGi App world
A-API-Bundle
(requires NOTHING)
A Impl-Bundle
(requires NOTHING)
Ideal OSGi App world
A-API-Bundle
(requires NOTHING)
A Impl-Bundle
(requires NOTHING)
B Impl-Bundle
(requires Comp A-API-Bundle)
Ideal OSGi App world
A-API-Bundle
(requires NOTHING)
A Impl-Bundle
(requires NOTHING)
B Impl-Bundle
(requires Comp A-API-Bundle) public interface A { }
Ideal OSGi App world
A-API-Bundle
(requires NOTHING)
A Impl-Bundle
(requires NOTHING)
B Impl-Bundle
(requires Comp A-API-Bundle) public interface A { } @Component public class ImplA implements A { }
Ideal OSGi App world
A-API-Bundle
(requires NOTHING)
A Impl-Bundle
(requires NOTHING)
B Impl-Bundle
(requires Comp A-API-Bundle) public interface A { } @Component public class ImplA implements A { } @Component public class ImplB { @Reference(cardinality= ReferenceCardinality.MANDATORY) public void setCompA(A a) {} public void unsetCompA(A a) {} }
e4 OSGi usage
A Impl-Bundle
(requires NOTHING)
B Impl-Bundle
(requires Comp A-API-Bundle)
A-API-Bundle
(requires NOTHING)
e4 OSGi usage
A Impl-Bundle
(requires NOTHING)
B Impl-Bundle
(requires Comp A-API-Bundle)
A-API-Bundle
(requires NOTHING) public interface A { } @Component public class ImplA implements A { }
e4 OSGi usage
A Impl-Bundle
(requires NOTHING)
B Impl-Bundle
(requires Comp A-API-Bundle)
A-API-Bundle
(requires NOTHING) public interface A { } @Component public class ImplA implements A { } public class ImplB { @Inject public void setCompA(A a) {} }
e4 OSGi usage
IEclipseContext serviceContext = … B a = ContextInjectionFactory.make(B.class, serviceContext);
e4 OSGi usage
Bundle bundle = FrameworkUtil.getBundle(BlaBla.class) BundleContext btx = bundle.getBundleContext(); IEclipseContext serviceContext = EclipseContextFactory.getServiceContext(btx); B a = ContextInjectionFactory.make(B.class, serviceContext);
e4 OSGi API useage
e4 OSGi API useage
Pattern 1 - Debug/Log
import org.eclipse.osgi.framework.log.FrameworkLog; import org.eclipse.osgi.framework.log.FrameworkLogEntry; FrameworkLog log = … FrameworkLogEntry logEntry = new FrameworkLogEntry("org.eclipse.core.e4.di", FrameworkLogEntry.ERROR, 0, "I’m an error", 0, e, null);
e4 OSGi API useage
Pattern 1 - Debug/Log
import org.eclipse.osgi.framework.log.FrameworkLog; import org.eclipse.osgi.framework.log.FrameworkLogEntry; FrameworkLog log = … FrameworkLogEntry logEntry = new FrameworkLogEntry("org.eclipse.core.e4.di", FrameworkLogEntry.ERROR, 0, "I’m an error", 0, e, null);
Pattern 2 - Accessing OSGi-Service
BundleContext bundleContext = FrameworkUtil.getBundle(BlaBla.class).getBundleContext(); ServiceReference<ComponentA> serviceReference = bundleContext.getServiceReference(GreetService.class); if( serviceReference != null ) { bundleContext.getService(serviceReference).greet("Hello Tom"); }
Logging the efxclipse way
Access Patterns
Logging the efxclipse way
Access Patterns
public class ComponentEarly2000 { private static Logger logger = LoggerCreator.createLogger(getClass()); }
Logging the efxclipse way
Access Patterns
public class OSGiComponent2016 { private Logger logger; @Reference(cardinality=ReferenceCardinality.MANDATORY) public void setLoggerFactory(LoggerFactory f) { f.createLogger(getClass().getName()); } } public class ComponentEarly2000 { private static Logger logger = LoggerCreator.createLogger(getClass()); }
Logging the efxclipse way
Access Patterns
public class DiComponent2016 { @Inject @Log private Logger logger; } public class OSGiComponent2016 { private Logger logger; @Reference(cardinality=ReferenceCardinality.MANDATORY) public void setLoggerFactory(LoggerFactory f) { f.createLogger(getClass().getName()); } } public class ComponentEarly2000 { private static Logger logger = LoggerCreator.createLogger(getClass()); }
Logging the efxclipse way
private void processJPAResultList(List<Person> list) {// slf4j/log4j/efxclipse for( int i = 0; i < list.size(); i++ ) { Person p = list.get(i); logger.debug("Processing " + p.getName() + " - " + p.getAddress().getStreet()); } }
Logging the efxclipse way
private void processJPAResultList(List<Person> list) {// slf4j/log4j/efxclipse for( int i = 0; i < list.size(); i++ ) { Person p = list.get(i); logger.debug("Processing " + p.getName() + " - " + p.getAddress().getStreet()); } }
BAD IDEA
Logging the efxclipse way
private void processJPAResultList(List<Person> list) {// slf4j/log4j/efxclipse for( int i = 0; i < list.size(); i++ ) { Person p = list.get(i); logger.debug("Processing " + p.getName() + " - " + p.getAddress().getStreet()); } } private void processJPAResultList(List<Person> list) {// slf4j/log4j/efxclipse for( int i = 0; i < list.size(); i++ ) { Person p = list.get(i); if( logger.isEnabled(Level.DEBUG) ) { logger.debug("Processing " + p.getName() + " - " + p.getAddress().getStreet()); } } }
Logging the efxclipse way
private void processJPAResultList(List<Person> list) {// slf4j/log4j/efxclipse for( int i = 0; i < list.size(); i++ ) { Person p = list.get(i); logger.debug("Processing " + p.getName() + " - " + p.getAddress().getStreet()); } } private void processJPAResultList(List<Person> list) {// log4j-2.x/efxclipse for( int i = 0; i < list.size(); i++ ) { Person p = list.get(i); // Logger#debug(Supplier<String>): void logger.debug(() -> "Processing " + p.getName() + " - " + p.getAddress().getStreet()); } } private void processJPAResultList(List<Person> list) {// slf4j/log4j/efxclipse for( int i = 0; i < list.size(); i++ ) { Person p = list.get(i); if( logger.isEnabled(Level.DEBUG) ) { logger.debug("Processing " + p.getName() + " - " + p.getAddress().getStreet()); } } }
Logging the efxclipse way
private void processJPAResultList(List<Person> list) {// slf4j/log4j/efxclipse for( int i = 0; i < list.size(); i++ ) { Person p = list.get(i); logger.debug("Processing " + p.getName() + " - " + p.getAddress().getStreet()); } } private void processJPAResultList(List<Person> list) {// log4j-2.x/efxclipse for( int i = 0; i < list.size(); i++ ) { Person p = list.get(i); // Logger#debug(Supplier<String>): void logger.debug(() -> "Processing " + p.getName() + " - " + p.getAddress().getStreet()); } } private void processJPAResultList(List<Person> list) {// slf4j/log4j/efxclipse for( int i = 0; i < list.size(); i++ ) { Person p = list.get(i); if( logger.isEnabled(Level.DEBUG) ) { logger.debug("Processing " + p.getName() + " - " + p.getAddress().getStreet()); } } } private void processJPAResultList(List<Person> list) {// efxclipse for( int i = 0; i < list.size(); i++ ) { // Logger#<T>debug(T value Function<T,String>): T logger.debug(list.get(i), (p)
} }
Logging the efxclipse way
private void processJPAResultList(List<Person> list) {// slf4j/log4j/efxclipse for( int i = 0; i < list.size(); i++ ) { Person p = list.get(i); logger.debug("Processing " + p.getName() + " - " + p.getAddress().getStreet()); } } private void processJPAResultList(List<Person> list) {// log4j-2.x/efxclipse for( int i = 0; i < list.size(); i++ ) { Person p = list.get(i); // Logger#debug(Supplier<String>): void logger.debug(() -> "Processing " + p.getName() + " - " + p.getAddress().getStreet()); } } private void processJPAResultList(List<Person> list) {// slf4j/log4j/efxclipse for( int i = 0; i < list.size(); i++ ) { Person p = list.get(i); if( logger.isEnabled(Level.DEBUG) ) { logger.debug("Processing " + p.getName() + " - " + p.getAddress().getStreet()); } } } private void processJPAResultList(List<Person> list) {// efxclipse for( int i = 0; i < list.size(); i++ ) { // Logger#<T>debug(T value Function<T,String>): T logger.debug(list.get(i), (p)
} }
BAD IDEA
Logging the efxclipse way
private void processJPAResultList(List<Person> list) {// log4j-2.x/efxclipse for( int i = 0; i < list.size(); i++ ) { Person p = list.get(i); logger.debug(() -> "Processing " + p.getName() + " - " + p.getAddress().getStreet()); } }
Logging the efxclipse way
private void processJPAResultList(List<Person> list) {// log4j-2.x/efxclipse for( int i = 0; i < list.size(); i++ ) { Person p = list.get(i); logger.debug(() -> "Processing " + p.getName() + " - " + p.getAddress().getStreet()); } } static class Supplier1234 implements Supplier<String> { private Person p; Supplier1234(Person p) { this.p = p; } public void String get() { return "Processing " + p.getName() + " - " + p.getAddress().getStreet()); } } private void processJPAResultList(List<Person> list) {// log4j-2.x/efxclipse for( int i = 0; i < list.size(); i++ ) { Person p = list.get(i); logger.debug(new Supplier(p)); } }
Logging the efxclipse way
private void processJPAResultList(List<Person> list) {// efxclipse for( int i = 0; i < list.size(); i++ ) { logger.debug(list.get(i), (p)
} }
Logging the efxclipse way
private void processJPAResultList(List<Person> list) {// efxclipse for( int i = 0; i < list.size(); i++ ) { logger.debug(list.get(i), (p)
} } static class Function1234 implements Function<Person,String> { public void String apply(Person p) { return "Processing " + p.getName() + " - " + p.getAddress().getStreet()); } } private static Function1234 INSTANCE = new Function1234(); private void processJPAResultList(List<Person> list) {// efxclipse for( int i = 0; i < list.size(); i++ ) { logger.debug(list.get(i), INSTANCE); } list.stream() .map( p -> logger.debug(list.get(i), INSTANCE) ) .filter(…) }
Servicelookup the efx way
Servicelookup the efx way
e4 built-in - single value
Servicelookup the efx way
e4 built-in - single value
public class DiComponent { @Inject GreetService greetService; }
Servicelookup the efx way
e4 built-in - single value
public class DiComponent { @Inject GreetService greetService; }
NO e4 built-in - multi value
Servicelookup the efx way
e4 built-in - single value
public class DiComponent { @Inject List<GreetService> greetService; } public class DiComponent { @Inject GreetService greetService; }
NO e4 built-in - multi value
Servicelookup the efx way
e4 built-in - single value
public class DiComponent { @Inject List<GreetService> greetService; } public class DiComponent { @Inject GreetService greetService; } public class DiComponent { @Inject @Service GreetService greetService; }
NO e4 built-in - multi value
Servicelookup the efx way
e4 built-in - single value
public class DiComponent { @Inject List<GreetService> greetService; } public class DiComponent { @Inject GreetService greetService; } public class DiComponent { @Inject @Service GreetService greetService; }
NO e4 built-in - multi value
public class DiComponent { @Inject @Service List<GreetService> greetService; }
Servicelookup the efx way
Servicelookup the efx way
e4 static lookup single value
Servicelookup the efx way
e4 static lookup single value
public class Component { public void m(IEclipseContext c) { A g = c.get(A.class); } }
Servicelookup the efx way
e4 static lookup single value
public class Component { public void m(IEclipseContext c) { A g = c.get(A.class); } }
NO e4 static lookup multi value
Servicelookup the efx way
e4 static lookup single value
public class Component { public void m(IEclipseContext c) { A g = c.get(A.class); } }
NO e4 static lookup multi value
public class Component { public void m(IEclipseContext c) { List<A> s = c.get(/*NO EXPRESSION*/); } }
Servicelookup the efx way
e4 static lookup single value
public class Component { public void m(IEclipseContext c) { A g = c.get(A.class); } }
NO e4 static lookup multi value
public class Component { public void m(IEclipseContext c) { List<A> s = c.get(/*NO EXPRESSION*/); } } import static o.e.f.c.ServiceUtils.*; public class Component { public void m() { Optional<A> g = getService(A.class); } }
Servicelookup the efx way
e4 static lookup single value
public class Component { public void m(IEclipseContext c) { A g = c.get(A.class); } }
NO e4 static lookup multi value
public class Component { public void m(IEclipseContext c) { List<A> s = c.get(/*NO EXPRESSION*/); } } import static o.e.f.c.ServiceUtils.*; public class Component { public void m() { Optional<A> g = getService(A.class); } } import static o.e.f.c.ServiceUtils.*; public class Component { public void m() { List<A> g = getServiceList(A.class); } }
IEclipseContext
retrieving & publishing to information in e4
IEclipseContext
retrieving & publishing to information in e4 EclipseContext@1
IEclipseContext
retrieving & publishing to information in e4 EclipseContext@2 EclipseContext@1
IEclipseContext
retrieving & publishing to information in e4 EclipseContext@2 EclipseContext@1
my.Person: Person@1 MWindow: MWindowImpl@1 …
IEclipseContext
retrieving & publishing to information in e4 EclipseContext@2 EclipseContext@1
my.Person: Person@1 MWindow: MWindowImpl@1 … MPart: MPartImpl@1 …
IEclipseContext
retrieving & publishing to information in e4
public class A { @Inject Person p; }
EclipseContext@2 EclipseContext@1
my.Person: Person@1 MWindow: MWindowImpl@1 … MPart: MPartImpl@1 …
IEclipseContext
retrieving & publishing to information in e4
public class A { @Inject Person p; } public class B { @Inject private IEclipseContext c; public void m() { c.getParent().set(Person.class,p); } }
EclipseContext@2 EclipseContext@1
my.Person: Person@1 MWindow: MWindowImpl@1 … MPart: MPartImpl@1 …
IEclipseContext
retrieving & publishing to information in e4
public class A { @Inject Person p; } public class B { @Inject private IEclipseContext c; public void m() { c.getParent().set(Person.class,p); } }
EclipseContext@2 EclipseContext@1
my.Person: Person@1 MWindow: MWindowImpl@1 … MPart: MPartImpl@1 …
IEclipseContext
retrieving & publishing to information in e4
public class A { @Inject Person p; } public class B { @Inject private IEclipseContext c; public void m() { c.getParent().set(Person.class,p); } }
EclipseContext@2 EclipseContext@1
my.Person: Person@1 MWindow: MWindowImpl@1 … MPart: MPartImpl@1 …
IEclipseContext
retrieving & publishing to information in efxclipse
public class A { @Inject Person p; } public class B { @Inject @ContextValue("my.Person") private Consumer<Person> c; public void m() { c.accept(p); } }
EclipseContext@2 EclipseContext@1
my.Person: Person@1 MWindow: MWindowImpl@1 … MPart: MPartImpl@1 …
Success story
Source: http://modernisierung.site/summary/
e4 editor story
e4 editor story
efxclipse-editor story
efxclipse-editor story
Eclipse 4 Application Platform
efxclipse-editor story
Eclipse 4 Application Platform Core-API
(eg resource-abstraction, auto-complete,…)
efxclipse-editor story
Eclipse 4 Application Platform Core-API
(eg resource-abstraction, auto-complete,…)
Presentation API
efxclipse-editor story
Eclipse 4 Application Platform Core-API
(eg resource-abstraction, auto-complete,…)
Core-EFS
(use IProject, IFile,..)
Core-NIO
(use java.nio.file.Path, …)
Presentation API
efxclipse-editor story
Eclipse 4 Application Platform Core-API
(eg resource-abstraction, auto-complete,…)
Core-EFS
(use IProject, IFile,..)
Core-NIO
(use java.nio.file.Path, …)
Presentation API JavaFX SWT*
* does not exist
(at least not for e4 on JavaFX)
Platform of the future
Platform of the future
JVM
Platform of the future
JVM OSGi
Platform of the future
JVM efx-core Eclipse 4 App Platform OSGi
Platform of the future
JVM efx-core Eclipse 4 App Platform OSGi efx-platform
Platform of the future
JVM efx-core Eclipse 4 App Platform OSGi efx-platform
Platform of the future
JVM efx-core Eclipse 4 App Platform efx-platform