8

How would you implement an extendable web application? What I'm thinking about is a web application similar to Jenkins or Hudson which provides plug-in support. While it's obvious to me how plug-ins can be located and loaded, I don't know how they can be integrated within the overall architecture. I'm especially uncertain about the following points.

How can a plug-in change the view, e.g. add input elements to a form?

My first idea would be that a plug-in can register partials / fragments for a certain form.

Example: Newsletter plug-in which registers a typical newsletter checkbox fragment which will be rendered in the user registration view.

How can a plug-in react to incoming requests?

Again, a direct approach would be to provide listeners for certain requests or actions, e.g. POST request to /user.

How could a plug-in persist data?

I'm assuming this is a situation where NoSQL data storage solutions would be superior to relational databases.

I would appreciate any comments, ideas and experiences (maybe there is even a design pattern) that you have regarding extendable web applications.

asked Oct 21, 2011 at 9:28

1 Answer 1

3

Your question contains almost all the answers. You're right in the ballpark: it's all plug-ins and their extension points to set the context and make them do the things you want. There are numerou ways to design plug-in systems. For starters:

http://people.clarkson.edu/~dhou/courses/EE564-s07/plugin.pdf

http://blogs.atlassian.com/developer/2011/03/plugin_architecture_episode_i.html

Here is a trivial example to illustrate how a rudimentary plugin-aware system would work:

public interface Plugin {
 void setEntityManager(EntityManager manager); // this is very course grained and liberal! A plugin would have access to whatever Entity Manager the container gives it. A plugin would then have a carte blanche to do whatever it needs: create, drop, insert, select, delete.
 View renderView(ViewContext context); // a plugin would render or return a view (whatever it is, could be a string in the simplest case) based on the context that the container passed to the plugin
 Action readEvent(Event event); // a plugin performs some Action based on an event as notified by a container
}
public class PluginContainer {
 private List<Plugin> plugins = new ArrayList<Plugin>();
 public void registerPlugins() {
 // loop through plugin descriptors obtained by your preferred mechanism
 // like introspecting libraries (JARs) in a configurable location
 // for each descriptor, load a Plugin dynamically and "register" it with a container
 Plugin p = ClassLoader.getSystemClassLoader().loadClass("com.my.PluginA").newInstance(); 
 p.setEntityManager(entityManager);
 plugins.add(p);
 }
 public void readEvent(AppEvent appEvent) {
 Event e = this.constructPluginSpecificEventFromAppEvent(); // optional
 for (Plugin p : this.plugins) {
 p.readEvent(e); // disregarding Action here
 }
 }
}
public class Application {
 private PluginContainer pContainer;
 private void buttonClicked(AppEvent appEvent) {
 this.showCoolDialog("Thank you for clicking a button!");
 // now let my plugins handle this
 // they can do whatever they want for this event
 // since they have access to EntityManager, they can work with a persistence storage as well
 this.pcContainer.readEvent(appEvent);
 }
}
answered Oct 22, 2011 at 19:46

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.