AEM listen to bundle registration - aem

I know I can use a JCR EventListener to check things like changes on nodes. I also know OSGi bundles implement a ServiceListener interface which let them know when a bundle is registered or stopped.
I think I'm somewhat close but I can't seem to connect the dots. How in AEM can I deploy a bundle that can listen to other bundles ServiceEvent changes?

Yes, you are right. You can listen to OSGi events, using Felix EventAdmin.
There you can find specification but in a couple of words:
First you need to implement interface EventHandler
Register your handler for events with topic org/osgi/framework/BundleEvent/STARTED
In documentation they do not use annotations, but if you use maven scr plugin in you project - you can do it with annotations. Your code could look like:
#Component
#Service(value = EventHandler.class)
#Property(name = EventConstants.EVENT_TOPIC, value = { ReplicationAction.EVENT_TOPIC })
public class YourEventHandler implements EventHandler {
#Override
public void handleEvent(Event event) {
// do smth with event
}
}

What is your use case? do you need a BundleTracker or a ServiceTracker.
As may be the case you may need to extend BundleTracker/ServiceTracker and handle your logic in addingxxxxxx/ modifiedxxxxxx/ removedxxxxxx methods.
Some examples you can check AEM commons code and Tracker

Related

How do Service / SourceProviders work in Eclipse 4 RCP 2.0?

I've been busily getting with the future and migrating an old eclipse 3.7 application over to Eclipse 4 and whilst I'm happy with the application model for porting all the views I have a number of source providers that I am unsure about porting wise. I've been using a few tutorials on Eclipse 4 including this Tutorial from good old Lars but none seem to cover this particular element.
For a small amount of Context my existing application has a few classes extending AbstractSourceProvider that are registered in the org.eclipse.ui.services extension point. My views register themselves as listeners to these services using the ISourceProviderService.getSourceProvider(key) function from the workbench and update themselves if that source fires a sourced changed event. I also have a few providers that reference each other some times too so I'm wondering if this will still work with injection.
What sort of model is used in Eclipse 4?, should I just use the same old extension point? Can these extension point services be injected in to the views in the new cool anotationy way?
What gives?
You can create a service in a number of ways:
Create an instance of your service class and put it in the IEclipseContext. This is often done in an 'Addon':
public class MyAddon
{
#PostConstruct
void postConstruct(IEclipseContext context)
{
MyService myService = ContextInjectionFactory.make(MyService.class, context);
context.put(MyService.class, myService);
}
}
The 'Addon' is declared in the application.e4xmi file.
You could also create the service like this in the LifeCycle class for the RCP.
An OSGi service will automatically be added to the Eclipse context.
You can use a Context Function which uses an OSGi service but doesn't create the actual service until it is needed.
In all cases you reference the service by injection:
#Inject
MyService myService;
Note that injection is only done on objects created by Eclipse from objects described in the application.e4xmi. It is possible to do injection on other objects using ContextInjectionFactory.

Enabling EJB Injection into Vaadin 7 UI via Usage of Vaadin-CDI-Integration Addon

I wasn't able to successfully integrate the official Vaadin-CDI-Integration-Addon, since after finishing the official integration instructions, the following Exception was thrown in case I reloaded the already published URL localhost:8080/App/?restartApplication.
javax.servlet.ServletException: com.vaadin.server.ServiceException:
java.lang.IllegalStateException: UI id has already been defined
The following little workaround is a tested, working solution, which completes the official instructions.
You have to work off the following steps to successfully integrate the official CDI-Integration-Addon into your Vaadin project.
Do exactly as stated in the official how-to.
Remove the ?restartApplication parameter from the URL. This avoids the Exception.
Inject the EJB as shown in the listing below.
Keep in mind to restart your application manually if necessary!
#CDIUI
public class ExampleCDIUI extends UI {
#Inject
MyLocalBeanInterface myBean;
#Override
public void init(VaadinRequest request) {
Label label = new Label("Hello Vaadin user");
setContent(label);
// myBean should be accessible now.
}
}
That's it. I hope this helps :-)

How to include 3rd party JavaScript libraries in a reusable gwt library/widget?

I'm trying to get my feet wet with GWT to see if migrating will work out. I usually try the more difficult parts first to make sure I can finish the project. The most difficult part of my project(s) is referencing 3rd party JS libs. In this example I'm trying to use PubNub as much of our platform uses it.
What I'd like to do is create a reusable object that can be used in other GWT projects in need of PubNub. I've got a simple little test running successfully (ie, I've got the basics of JNSI working), but my question is -> where do I put the reference to the 3rd party script in order to create the library/module properly?
Right now I just put the reference to the external scripts in the HTML page in the project, but I'm pretty sure this is incorrect from a reusability perspective, as this lib would be used in other projects, each of which would have their own base HTML page.
I tried putting the reference in the gwt.xml file, but this seems to lose the references (ie my test project no longer works as it did when the scripts were in the HTML page)
Do you have any tips on how to include 3rd party libraries in a reusable GWT library/widget?
Here you have an example using client bundles and script injector, you can use either synchronous loading or asynchronous.
When using sync the external js content will be embedded in the application, otherwise it will be include in a different fragment which will be got with an ajax request.
You can put your api in any server and load it with the ScriptInjector.
public class Example {
public static interface MyApiJs extends ClientBundle {
MyApiJs INSTANCE = GWT.create(MyApiJs.class);
#Source("my_api.js")
TextResource sync();
#Source("my_api.js") // Should be in the same domain or configure CORS
ExternalTextResource async();
}
public void loadSync() {
String js = MyApiJs.INSTANCE.sync().getText();
ScriptInjector.fromString(js).inject();
}
public void loadAsync() throws ResourceException {
MyApiJs.INSTANCE.async().getText(new ResourceCallback<TextResource>() {
public void onSuccess(TextResource r) {
String js = r.getText();
ScriptInjector.fromString(js).inject();
}
public void onError(ResourceException e) {
}
});
}
public void loadFromExternalUrl() {
ScriptInjector.fromUrl("http://.../my_api.js").inject();
}
}
[EDITED]
A better approach is to use a new feature in gwtquery 1.4.0 named JsniBundle. We introduced this feature during the GWT.create conferences at San Francisco and Frankfurt.
With this approach you can insert any external javascript (placed in your source tree or hosted in an external host) as a JSNI block. It has many benefits:
Take advantage of GWT jsni validators, obfuscators and optimizers.
Get rid of any jsni java method when the application does not use it.
The syntax is actually easy:
public interface JQueryBundle extends JsniBundle {
#LibrarySource("http://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js")
public void initJQuery();
}
JQueryBundle jQuery = GWT.create(JQueryBundle.class);
jQuery.initJQuery();

Create a GWT RPC Service

I’m trying to create a backend for a homepage with GWT. I created a Google Web Application in Eclipse without sample code and now I would like to add the service, but the developer Google guide doesn’t help me. I’m not sure, where to add the interface and how it exactly works.
If I understand the google documentation correctly, I have to add a module and an entry point class, is that correct? It would be great if you could give me some tips and help how to create a rpc service.
If you create a new GWT project in the Eclipse "New Project" wizard, with "Generate project sample code" checked, it will include a fully functioning RPC service with a sample method, which you can then adapt or copy according to your needs.
Out of memory, don't have eclipse in front of me.
First do create a test project with generated testcode, you can delete it afterward.
Yes you will have to add a module.
Create in client the two interfaces for the async calls, inherit it on server side.
Hope I understood your question right.
I'm not sure what would help you the most. Google developer guide was enough for me (at least when I started using it on version 1.6) to create RPC services for my GWT application.
General APP
Module: is the .gwt.xml file. Yes, you'll need it. The GWT compiler will find it automagically and try to compile all the GWT code (the <source> element will tell which subpackage contains Java code that will be converted to JS). It will tell also which class implements the EntryPoint interface. The onModuleLoad will be the code executed when javascript runs in the client page.
RPC
Well, you should first try UI things and only then, when you're confident enough, try the server thing. Anyway the scheme is:
interface MyService extends RemoteService {
List<String> doSomething(String sample, int other);
}
#RemoteServiceRelativePath("../path/to/servlet") // see later
intercace MyServiceAsync {
void doSomething(String sample, int other, AsyncCallback<List<String>> callback);
}
These are the interfaces. Later is the async one. That's what you'll use from client side. Always calling and passing an implementation of AsyncCallback which will receive (sometime later, you don't know when) the result.
First interface is the syncrhonous one. That is what you need to implement on server. You must inherit from RemoteServiceServlet class (it is an implementation of servlet that already does all the values handling), and implement your interface. GWT code does the rest (almost).
public class ServiceImpl extends RemoteServiceServlet implements MyService
{
// implement the method normally
}
From client you'll need to create the service proxy:
private static MyServiceAsync MY_SERVICE = GWT.create(MyService.class);
Yes. I know it's weird how GWT knows MyserviceAsync and MyService work together. Don't worry about that. It works :)
Just use the service like this:
MY_SERVICE.doSomething("value", 111, new AsyncCallback<List<String>>() {
// note that this code executes some time in the future when response from server is back
public void onSuccess(List<String> result) {
Window.alert("Server answered with " + result.size() + " elements!");
}
public void onFailure(Throwable t) {
Window.alert("Server failed: " + t.getMessage());
}
}
Path to server
You'll have to configure your app to make that servlet implementation listen to URL indicated in #RemoteServiceRelativePath. That's the way client knows where to make the request, and the server knows which servlet attends that request. I'd suggest using:
../my-service.gwt as relative path (GWT module gets published in <ROOT>/module_name
and
configuring your web app to use the servlet for /my-service.gwt
But it's entirely upon your preferences :)
Anyway I think Google tutorials are the best. So please copy&paste. Try&modify until you get to understand the whole thing.

How do I run a method before republishing to JBoss?

I'm developing a J2EE web application and I would like to be able to run a method (or function, class, whatever - something) during the "republish" process. It would be nice if I could control when during the republish my function gets called (before, during, after, etc.) but a good first step would be getting something to be called automatically.
As a temporary hack, I was able to add a button to my web app that you click right before you click "republish" in Eclipse.
Implement ServletContextListener to hook on webapp's startup and shutdown.
public class Config implements ServletContextListener {
public void contextInitialized(ServletContextEvent event) {
// Do stuff during startup.
}
public void contextDestroyed(ServletContextEvent event) {
// Do stuff during shutdown.
}
}
To get it to work, just register it in web.xml.
<listener>
<listener-class>com.example.Config</listener-class>
</listener>
I am however only not sure what exactly you mean with during publish. But you could take a look for another listeners available in the Servlet API or maybe a Filter.