Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

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.

share|improve this question
add comment

1 Answer

up vote 3 down vote accepted

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);
  }

}
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.