Details

    • Type: Improvement Improvement
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Not a Problem
    • Affects Version/s: None
    • Fix Version/s: None
    • Component/s: core
    • Labels:
      None

      Description

      Add module support to Click core. Some code has been committed here:

      http://click.svn.sourceforge.net/viewvc/click/trunk/sandbox/sabob/plugin/

      Note that with the recent work done on CLK-343 the module code wont compile anymore.

      A related issue is: CLK-328

        Activity

        Hide
        Ahmed Mohombe added a comment -

        > Add plugin support to Click core. Some code has been committed here:
        >
        > http://click.svn.sourceforge.net/viewvc/click/trunk/sandbox/sabob/plugin/
        >
        > Note that with the recent work done on CLK-343 the plugin code wont compile anymore.
        >
        > A related issue is: CLK-328
        IMHO we should not call this functionality "plug-in" but "module".

        When I think of plug-ins I think of something that can't work on their own.
        As I described in the JIRA issue, however the "module" if dropped in an empty
        webapplication would just work, so IMHO it's more a "module", and it also
        fits better with the Cayenne modularity concepts.

        Ahmed.

        -------------------------------------------------------------------------
        Check out the new SourceForge.net Marketplace.
        It's the best place to buy or sell services for
        just about anything Open Source.
        http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace
        _______________________________________________
        Click-development mailing list
        Click-development@lists.sourceforge.net
        https://lists.sourceforge.net/lists/listinfo/click-development

        Show
        Ahmed Mohombe added a comment - > Add plugin support to Click core. Some code has been committed here: > > http://click.svn.sourceforge.net/viewvc/click/trunk/sandbox/sabob/plugin/ > > Note that with the recent work done on CLK-343 the plugin code wont compile anymore. > > A related issue is: CLK-328 IMHO we should not call this functionality "plug-in" but "module". When I think of plug-ins I think of something that can't work on their own. As I described in the JIRA issue, however the "module" if dropped in an empty webapplication would just work, so IMHO it's more a "module", and it also fits better with the Cayenne modularity concepts. Ahmed. ------------------------------------------------------------------------- Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace _______________________________________________ Click-development mailing list Click-development@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/click-development
        Hide
        Michael Hall added a comment -

        Suppose you have a plugin/module who's initialization is dependent on another plugin/module already being initialized. From a quick look at the code it seems the initialization order is not guaranteed, correct?

        Here's my suggestion, create a PluginClickApp.initPlugin(String PluginName) that keeps track of which plugins have already been loaded. That way if plugin A depends on plugin B, you can do this:

        class A extends ClickPlugin {

        public onInit()

        { PluginClickApp.loadPlugin("B"); // Do A's initialization }

        If B has already been initialized, then loadPlugin quickly returns, otherwise it calls B.onInit(), adds B to the list of loaded plugins, then returns.

        Show
        Michael Hall added a comment - Suppose you have a plugin/module who's initialization is dependent on another plugin/module already being initialized. From a quick look at the code it seems the initialization order is not guaranteed, correct? Here's my suggestion, create a PluginClickApp.initPlugin(String PluginName) that keeps track of which plugins have already been loaded. That way if plugin A depends on plugin B, you can do this: class A extends ClickPlugin { public onInit() { PluginClickApp.loadPlugin("B"); // Do A's initialization } If B has already been initialized, then loadPlugin quickly returns, otherwise it calls B.onInit(), adds B to the list of loaded plugins, then returns.
        Hide
        Michael Hall added a comment -

        Also, how about a PluginNotFound exception, so that if we try to load B in A.onInit, but we haven't added plugin B to our webapp, A can do something else instead of just failing outright.

        This is very important to what I wanted to do with Click, so that I can say "If this plugin exists, let's use it, but it isn't necessary". That is why I say pass the plugin name, instead of the class, so you don't even need B's class files in your classpath at runtime or compile time.

        Show
        Michael Hall added a comment - Also, how about a PluginNotFound exception, so that if we try to load B in A.onInit, but we haven't added plugin B to our webapp, A can do something else instead of just failing outright. This is very important to what I wanted to do with Click, so that I can say "If this plugin exists, let's use it, but it isn't necessary". That is why I say pass the plugin name, instead of the class, so you don't even need B's class files in your classpath at runtime or compile time.
        Hide
        Bob Schellink added a comment -

        >it seems the initialization order is not guaranteed, correct?

        Correct order is not guaranteed.

        Your idea of doing PluginClickApp.loadPlugin sounds good. Dependencies would be easy to manage that way.

        Can expose a method:
        onInit(PluginClickApp clickapp) throws PluginNotFoundException;

        So one can do:
        public void onInit(PluginClickApp clickApp) throws PluginNotFoundException {
        try

        { clickApp.loadPlugin("B"); } catch (...) {}
        }

        or provide a way to query if a certain plugin is available instead of throwing the exception:

        public void onInit(PluginClickApp clickApp) {
        if ( clickApp.pluginExists("B") ) { clickApp.loadPlugin("B"); }

        }

        Thanks for the feedback.

        Show
        Bob Schellink added a comment - >it seems the initialization order is not guaranteed, correct? Correct order is not guaranteed. Your idea of doing PluginClickApp.loadPlugin sounds good. Dependencies would be easy to manage that way. Can expose a method: onInit(PluginClickApp clickapp) throws PluginNotFoundException; So one can do: public void onInit(PluginClickApp clickApp) throws PluginNotFoundException { try { clickApp.loadPlugin("B"); } catch (...) {} } or provide a way to query if a certain plugin is available instead of throwing the exception: public void onInit(PluginClickApp clickApp) { if ( clickApp.pluginExists("B") ) { clickApp.loadPlugin("B"); } } Thanks for the feedback.
        Hide
        Bob Schellink added a comment -

        Been wondering about the support for the optional "root" directory.

        It makes things difficult for both the module author and implementation.

        How about we make the "root" mandatory or just default it to the module "name".

        Some advantages:

        • The module developer then knows the path to resources eg: <link href=''$context / mymodule / myscript.js' />
        • The URL's are predictable eg: / mycontext / mymodule / edit-customer.htm
        • It is easy to cleanup after a module by just deleting to "root" directory. If the module's resources are interspersed with the rest of the app it would be difficult to upgrade the module.

        I believe this is how struts modules works as well : http://www.onjava.com/pub/a/onjava/2002/10/30/jakarta.html?page=2

        Is this reasonable? Perhaps we can make it "optional" after 1.5?

        Show
        Bob Schellink added a comment - Been wondering about the support for the optional "root" directory. It makes things difficult for both the module author and implementation. How about we make the "root" mandatory or just default it to the module "name". Some advantages: The module developer then knows the path to resources eg: <link href=''$context / mymodule / myscript.js' /> The URL's are predictable eg: / mycontext / mymodule / edit-customer.htm It is easy to cleanup after a module by just deleting to "root" directory. If the module's resources are interspersed with the rest of the app it would be difficult to upgrade the module. I believe this is how struts modules works as well : http://www.onjava.com/pub/a/onjava/2002/10/30/jakarta.html?page=2 Is this reasonable? Perhaps we can make it "optional" after 1.5?
        Hide
        Ricardo R. Lecheta added a comment -

        >>How about we make the "root" mandatory or just default it to the module "name".

        default to the module "name" makes sense to me.

        Show
        Ricardo R. Lecheta added a comment - >>How about we make the "root" mandatory or just default it to the module "name". default to the module "name" makes sense to me.
        Hide
        Joseph Schmidt added a comment -

        Any news on this "module support"?
        I know that it is partially implemented, but can we please have a "full" module support for Click 2.2.0?

        I believe this would be the most important feature regarding high productivity for Click: to be able to reuse not just components, but "modules" - i.e. pages+templates+logic as standalone modules parts.

        Now that I have made several small projects with Click (with older versions), I see that there's allot of common functionality that I rather not maintain/upgrade in every project, but have it as modules, some of them would be even suitable as open source, e.g.:

        • registration
        • authentication
        • acl
        • dashboard
        • recent activity/audit
        • tags
        • license management
        • etc.

        I believe this could be more like the Django plugins, where the developer only configures/enumerates them, and the application just has them, except that in Click the modules work in standalone mode too if provided a border template.

        Thank you,
        Joseph.

        Show
        Joseph Schmidt added a comment - Any news on this "module support"? I know that it is partially implemented, but can we please have a "full" module support for Click 2.2.0? I believe this would be the most important feature regarding high productivity for Click: to be able to reuse not just components, but "modules" - i.e. pages+templates+logic as standalone modules parts. Now that I have made several small projects with Click (with older versions), I see that there's allot of common functionality that I rather not maintain/upgrade in every project, but have it as modules, some of them would be even suitable as open source, e.g.: registration authentication acl dashboard recent activity/audit tags license management etc. I believe this could be more like the Django plugins, where the developer only configures/enumerates them, and the application just has them, except that in Click the modules work in standalone mode too if provided a border template. Thank you, Joseph.
        Hide
        Andrei Ionescu added a comment -

        > can we please have a "full" module support for Click 2.2.0?
        ++

        >some of them would be even suitable as open source, e.g.:
        >- registration
        >- authentication
        >- acl
        >- dashboard
        >- recent activity/audit
        >- tags
        >- license management
        Maybe these should be each separate issues, since it's just too much "code" for an issue to implement all?

        "Full module" support in Click would be the killer feature indeed .
        With the help of the above modules, a new Click application could be ~40% ready in a few minutes

        Show
        Andrei Ionescu added a comment - > can we please have a "full" module support for Click 2.2.0? ++ >some of them would be even suitable as open source, e.g.: >- registration >- authentication >- acl >- dashboard >- recent activity/audit >- tags >- license management Maybe these should be each separate issues, since it's just too much "code" for an issue to implement all? "Full module" support in Click would be the killer feature indeed . With the help of the above modules, a new Click application could be ~40% ready in a few minutes
        Hide
        Malcolm Edgar added a comment -

        I can understand how we could have JARs which contain their own Page classes and Velocity templates, HTML resources and have page mapping configuration defined in some resource file (XML or properties file).

        However I have difficulty seeing how how you can reuse large sections blocks of UI functionality across multiple applications given the dependencies Click pages have on services, dao, entities, etc. (unless the underlying code is reused for all the potential applications).

        regards Malcolm Edgar

        Show
        Malcolm Edgar added a comment - I can understand how we could have JARs which contain their own Page classes and Velocity templates, HTML resources and have page mapping configuration defined in some resource file (XML or properties file). However I have difficulty seeing how how you can reuse large sections blocks of UI functionality across multiple applications given the dependencies Click pages have on services, dao, entities, etc. (unless the underlying code is reused for all the potential applications). regards Malcolm Edgar
        Hide
        Andrei Ionescu added a comment - - edited

        >However I have difficulty seeing how how you can reuse large sections blocks of UI functionality across multiple applications given the dependencies
        > Click pages have on services, dao, entities, etc. (unless the underlying code is reused for all the potential applications).
        There are a few ways - many users already use them like that:

        • Pages(Click or not) access only the Services and Entities (maybe helpers too) - not the DAO (in fact there's no need for it most of the time).
        • Services expose only interfaces to the Pages
        • Services have the implementation for the desired back-end (so the DAO is usually merged here too - like the click-examples)
        • Entities may also expose only interfaces (this would have the advantage of being able to easier interchange Cayenne, OODBs or whatever backend)

        For Cayenne, there are Datamaps, so basically each "standalone" unit should have it's one Datamap. I was told that this should work
        with Cayenne, only it's not yet supported in the Modeler (and a cayenne.xml is still needed yet - but there's a JIRA item for this).
        (What I haven't understood yet is how the automatic but optional reversed relationships across Datamaps should work)
        For OODBs there's no problem: the separation is done using different Java packages per module.

        Well, I'm just a newbie, but at most this is how I understood from a (Click) JUG presentation that modularity should work.

        Show
        Andrei Ionescu added a comment - - edited >However I have difficulty seeing how how you can reuse large sections blocks of UI functionality across multiple applications given the dependencies > Click pages have on services, dao, entities, etc. (unless the underlying code is reused for all the potential applications). There are a few ways - many users already use them like that: Pages(Click or not) access only the Services and Entities (maybe helpers too) - not the DAO (in fact there's no need for it most of the time). Services expose only interfaces to the Pages Services have the implementation for the desired back-end (so the DAO is usually merged here too - like the click-examples) Entities may also expose only interfaces (this would have the advantage of being able to easier interchange Cayenne, OODBs or whatever backend) For Cayenne, there are Datamaps, so basically each "standalone" unit should have it's one Datamap. I was told that this should work with Cayenne, only it's not yet supported in the Modeler (and a cayenne.xml is still needed yet - but there's a JIRA item for this). (What I haven't understood yet is how the automatic but optional reversed relationships across Datamaps should work) For OODBs there's no problem: the separation is done using different Java packages per module. Well, I'm just a newbie, but at most this is how I understood from a (Click) JUG presentation that modularity should work.
        Hide
        Md. Jahid Shohel added a comment -

        Anyone working with this task? I would like to work/investigate with this task.

        Show
        Md. Jahid Shohel added a comment - Anyone working with this task? I would like to work/investigate with this task.
        Hide
        Md. Jahid Shohel added a comment -

        Couple of questions pooped up while I was looking into the old implementation[1] of module support for click. I will point out those questions and would like to have thoughts from everyone -

        1) Since each module is doing to be stand alone and independently pluggable, does that mean that each module will have their own configurations. By configurations I mean automapping, autobinding, etc (but not log service, config service,etc). If any configuration is not mentioned on module, then it will use base application's configuration (here by base application I mean the web application).

        2) If each module can have their own configuration(mentioned on on #1 above), then should we impose for each module to have "click-module.xml" to be in their class path (inside META-INF)?

        3) Who will load the modules? Potential candidates are ClickServlet or any config service. I think it should be ClickServlet. So that we do not depend on different config services. Because config services can change, but ClickServlet will not change.

        4) What will be the loading sequence? I mean load all modules first, then base application(by base application I mean, the main application as it is today, which is a war and contains web.xml)? Or other way around. Also what is the reason of loading sequence?

        [1] http://click.svn.sourceforge.net/viewvc/click/trunk/sandbox/sabob/plugin/

        Show
        Md. Jahid Shohel added a comment - Couple of questions pooped up while I was looking into the old implementation [1] of module support for click. I will point out those questions and would like to have thoughts from everyone - 1) Since each module is doing to be stand alone and independently pluggable, does that mean that each module will have their own configurations. By configurations I mean automapping, autobinding, etc (but not log service, config service,etc). If any configuration is not mentioned on module, then it will use base application's configuration (here by base application I mean the web application). 2) If each module can have their own configuration(mentioned on on #1 above), then should we impose for each module to have "click-module.xml" to be in their class path (inside META-INF)? 3) Who will load the modules? Potential candidates are ClickServlet or any config service. I think it should be ClickServlet. So that we do not depend on different config services. Because config services can change, but ClickServlet will not change. 4) What will be the loading sequence? I mean load all modules first, then base application(by base application I mean, the main application as it is today, which is a war and contains web.xml)? Or other way around. Also what is the reason of loading sequence? [1] http://click.svn.sourceforge.net/viewvc/click/trunk/sandbox/sabob/plugin/
        Hide
        Bob Schellink added a comment -

        I've commented on this before on the mailing list but will repeat it here:

        "Since this issue was opened there were a couple of new features added making it largely redundant. These
        features include:

        • multi page support
        • auto deployment of resources under META-INF/resources

        With these two features one can package up pages/templates/resources into jars and use them in the
        main war."

        Before doing any work we need to understand what are the requirements that are not met already and why it cannot be solved by existing technology.

        Show
        Bob Schellink added a comment - I've commented on this before on the mailing list but will repeat it here: "Since this issue was opened there were a couple of new features added making it largely redundant. These features include: multi page support auto deployment of resources under META-INF/resources With these two features one can package up pages/templates/resources into jars and use them in the main war." Before doing any work we need to understand what are the requirements that are not met already and why it cannot be solved by existing technology.
        Hide
        Md. Jahid Shohel added a comment -

        I already read that post, and that's how I thought too, that's why I did not mention them on my earlier post. The requirements I see, and the possibility of solving those with existing system are mentioned below-

        Requirements -

        1) Click should have modularity support. Where developers can write their own click modules and use the same module on different applications.
        2) Each module should be self contained with all its resources.
        3) Each module should have a way to mention its own configurations. If any specific configuration is not specified, then it will use the application's configuration. This will give the module to run with its configurations isolated.
        4) A module need to be self contained, so that it should be possible just to plug in a module without require to modify it before plugging it in.

        What we can/can't solve with existing technology (according to requirements sequence)-

        1) Current click release does not support modularity at all. So may be we have to start it from scratch. As per the last solution, we can have a ModuleService which is responsible for loading all modules. And main application (ClickServlet or any config service) can trigger the ModuleService to load modules. That way we can keep loading modules separate.

        2) For resources, It should work exactly as bob mentioned on earlier post (see above). The only thing I will suggest is, the module should have a scope to mention its own configuration with it.

        3) There are several way to let the module has its own configuration with it. Right now we xml approach, and we can share a huge amount of code from xmlconfigservice (will require refactor xmlconfigservice and separate common logics to share). Using properties or annotations are other alternatives. In the old solution, it was done by letting user implement/extend a interface/class and return their own configurations. We can still use that, but this might encourage some user to hard code their configurations inside the class.

        Show
        Md. Jahid Shohel added a comment - I already read that post, and that's how I thought too, that's why I did not mention them on my earlier post. The requirements I see, and the possibility of solving those with existing system are mentioned below- Requirements - 1) Click should have modularity support. Where developers can write their own click modules and use the same module on different applications. 2) Each module should be self contained with all its resources. 3) Each module should have a way to mention its own configurations. If any specific configuration is not specified, then it will use the application's configuration. This will give the module to run with its configurations isolated. 4) A module need to be self contained, so that it should be possible just to plug in a module without require to modify it before plugging it in. What we can/can't solve with existing technology (according to requirements sequence)- 1) Current click release does not support modularity at all. So may be we have to start it from scratch. As per the last solution, we can have a ModuleService which is responsible for loading all modules. And main application (ClickServlet or any config service) can trigger the ModuleService to load modules. That way we can keep loading modules separate. 2) For resources, It should work exactly as bob mentioned on earlier post (see above). The only thing I will suggest is, the module should have a scope to mention its own configuration with it. 3) There are several way to let the module has its own configuration with it. Right now we xml approach, and we can share a huge amount of code from xmlconfigservice (will require refactor xmlconfigservice and separate common logics to share). Using properties or annotations are other alternatives. In the old solution, it was done by letting user implement/extend a interface/class and return their own configurations. We can still use that, but this might encourage some user to hard code their configurations inside the class.
        Hide
        Bob Schellink added a comment - - edited

        > 1) Click should have modularity support. Where developers can write their own click modules and use the same module on different applications.

        Are you saying you want to build a full blown stand-alone application which can then be dropped into another Click application? There are many question that pop into my head at this stage:

        • How do you expect the module to become aware of the main application BorderPage?
        • How will the module plug into the main application menu system?
        • How will the module third-party jar dependencies and configurations be handled?
        • What about the module's DataSource?
        • What about the entities of the module and how will the main application ORM filter influence the module ORM settings? By this I mean the Open Session In View Filter which is the most common for web apps.

        I also think we need to differentiate between modules and the way to manage a big project. One can certainly break a big app into smaller modules (Eclipse subprojects), but they are still part of the same application and are tested as a whole. However creating stand-alone application modules which are dropped into a main application is not a simple task.

        Show
        Bob Schellink added a comment - - edited > 1) Click should have modularity support. Where developers can write their own click modules and use the same module on different applications. Are you saying you want to build a full blown stand-alone application which can then be dropped into another Click application? There are many question that pop into my head at this stage: How do you expect the module to become aware of the main application BorderPage? How will the module plug into the main application menu system? How will the module third-party jar dependencies and configurations be handled? What about the module's DataSource? What about the entities of the module and how will the main application ORM filter influence the module ORM settings? By this I mean the Open Session In View Filter which is the most common for web apps. I also think we need to differentiate between modules and the way to manage a big project. One can certainly break a big app into smaller modules (Eclipse subprojects), but they are still part of the same application and are tested as a whole. However creating stand-alone application modules which are dropped into a main application is not a simple task.
        Hide
        Md. Jahid Shohel added a comment -

        Before I comment, I must mention that, I am just saying what I think (which is more like discussing).

        >- How do you expect the module to become aware of the main application BorderPage?

        If module1 contains the border page, and module2 contains the body page. Then module1 should depend on module2. That should work right? At least I don't see any reason of not working, or may be I am missing something.

        >- How will the module plug into the main application menu system?

        I do not have clear answer for that, because this includes fine grained modularity. By that I mean, module1 is the host of main menu, and module2 want to contribute a menu item on the main menu. But still We can have modularity, where module1 has the base page, and module2 has the body pages. So module2 depends on module1.

        >- How will the module third-party jar dependencies and configurations be handled?

        I am a maven user, I don't see any problem with this. Because when my war is built, all my dependent jars, and their dependency, and their dependency...... all are packed into the war's WEB-INF/lib. That does not mean everyone have to use maven, but they can solve it the way maven does that.

        >- What about the module's DataSource?

        Say module1 loads the data source. then the specification of module1 can be, that it puts the data source into the session with some special key. Then all other modules (who will use the datasource of module1) can follow the specification of module1, and use the same key to fetch the datasource from the session.

        The other way is, giving a way so that modules can query for other modules, and can get a hold of the module. That way, all other modules can get hold of module1, and ask for data source/any other object/services.

        >- What about the entities of the module and how will the main application ORM filter influence the module ORM settings? By this I mean the Open Session In View Filter which is the most common for web apps.

        Yes this is a problem. I don't have clear answer for this, but some ORM can give a specific answer.

        >One can certainly break a big app into smaller modules (Eclipse subprojects), but they are still part of the same application and are tested as a whole.

        Will that be modularity/plugin? It sounds like more package separation, but not modularity. Some example or detail description will clear the confusion.

        Show
        Md. Jahid Shohel added a comment - Before I comment, I must mention that, I am just saying what I think (which is more like discussing). >- How do you expect the module to become aware of the main application BorderPage? If module1 contains the border page, and module2 contains the body page. Then module1 should depend on module2. That should work right? At least I don't see any reason of not working, or may be I am missing something. >- How will the module plug into the main application menu system? I do not have clear answer for that, because this includes fine grained modularity. By that I mean, module1 is the host of main menu, and module2 want to contribute a menu item on the main menu. But still We can have modularity, where module1 has the base page, and module2 has the body pages. So module2 depends on module1. >- How will the module third-party jar dependencies and configurations be handled? I am a maven user, I don't see any problem with this. Because when my war is built, all my dependent jars, and their dependency, and their dependency...... all are packed into the war's WEB-INF/lib. That does not mean everyone have to use maven, but they can solve it the way maven does that. >- What about the module's DataSource? Say module1 loads the data source. then the specification of module1 can be, that it puts the data source into the session with some special key. Then all other modules (who will use the datasource of module1) can follow the specification of module1, and use the same key to fetch the datasource from the session. The other way is, giving a way so that modules can query for other modules, and can get a hold of the module. That way, all other modules can get hold of module1, and ask for data source/any other object/services. >- What about the entities of the module and how will the main application ORM filter influence the module ORM settings? By this I mean the Open Session In View Filter which is the most common for web apps. Yes this is a problem. I don't have clear answer for this, but some ORM can give a specific answer. >One can certainly break a big app into smaller modules (Eclipse subprojects), but they are still part of the same application and are tested as a whole. Will that be modularity/plugin? It sounds like more package separation, but not modularity. Some example or detail description will clear the confusion.
        Hide
        Md. Jahid Shohel added a comment - - edited

        >>- How will the module plug into the main application menu system?

        >I do not have clear answer for that, because this includes fine grained modularity. By that I mean, module1 is the host of main menu, and module2 want to contribute a menu item on the main menu. But still We can have modularity, where module1 has the base page, and module2 has the body pages. So module2 depends on module1.

        I was actually thinking about this issue, and was wondering, whether we can solve the issue this way-

        Module1(the module that host's menu):

        Declares an interface like -

        interface MenuContributor

        { public MenuItem contributMenuItem(); }

        class MenuItem

        { private String menuLabel; //this can be a listener, or a page instance to forward when the menu is clicked //then user does not have to implement listener private MenuClickListener; ///constructor and getters setters just like POJO }

        Module2 (the module which contributes to menu):

        class HelpPageMenuContributor implements MenuContributor {
        public MenuItem contributeMenuIItem()

        { return new MenuItem("Help", new HelpMenuClickListenerImpl()); }

        }

        class HelpMenuClickListenerImpl implements MenuClickListener {
        public void onMenuClick(String menuLabel, Context context)

        { context.setForward(new HelpPage()); }

        }

        Now, how module1 can find all MenuContributor is a separate issues. And can be solved several ways -

        1) Module1 an put an instance of a class, with specific name (which is part of the access specification of module1). Other modules can take that instance and register their menu contributor like -

        menuRegister.registerMenuContributor(new HelpPageMenuContributor());

        2) Using spring, this is much easier. module2 can make HelpPageMenuContributor a bean on this local context (i mean child context, bundled in the same jar) file. And module1 can take all beans which implements MenuContributor interface. And local contexts can be then imported into parent context. Where parent context resides inside /WEB-INF/applicationContext.xml

        3) Follow the same way as #1 mentioned above, and module1 can implement a ServletContextAttributeListener and listen to the attribute changes to update the menu. Where as module2 is the potential candidate to update the attribute with new menu item.

        All these are just thoughts. And I believe, we can solve other issues as well. But if Click can have droppable jar modularity then it will be awesome. We might not be able to bring in everything all at once, but we can bring in things incrementally.

        Show
        Md. Jahid Shohel added a comment - - edited >>- How will the module plug into the main application menu system? >I do not have clear answer for that, because this includes fine grained modularity. By that I mean, module1 is the host of main menu, and module2 want to contribute a menu item on the main menu. But still We can have modularity, where module1 has the base page, and module2 has the body pages. So module2 depends on module1. I was actually thinking about this issue, and was wondering, whether we can solve the issue this way- Module1(the module that host's menu): Declares an interface like - interface MenuContributor { public MenuItem contributMenuItem(); } class MenuItem { private String menuLabel; //this can be a listener, or a page instance to forward when the menu is clicked //then user does not have to implement listener private MenuClickListener; ///constructor and getters setters just like POJO } Module2 (the module which contributes to menu): class HelpPageMenuContributor implements MenuContributor { public MenuItem contributeMenuIItem() { return new MenuItem("Help", new HelpMenuClickListenerImpl()); } } class HelpMenuClickListenerImpl implements MenuClickListener { public void onMenuClick(String menuLabel, Context context) { context.setForward(new HelpPage()); } } Now, how module1 can find all MenuContributor is a separate issues. And can be solved several ways - 1) Module1 an put an instance of a class, with specific name (which is part of the access specification of module1). Other modules can take that instance and register their menu contributor like - menuRegister.registerMenuContributor(new HelpPageMenuContributor()); 2) Using spring, this is much easier. module2 can make HelpPageMenuContributor a bean on this local context (i mean child context, bundled in the same jar) file. And module1 can take all beans which implements MenuContributor interface. And local contexts can be then imported into parent context. Where parent context resides inside /WEB-INF/applicationContext.xml 3) Follow the same way as #1 mentioned above, and module1 can implement a ServletContextAttributeListener and listen to the attribute changes to update the menu. Where as module2 is the potential candidate to update the attribute with new menu item. All these are just thoughts. And I believe, we can solve other issues as well. But if Click can have droppable jar modularity then it will be awesome. We might not be able to bring in everything all at once, but we can bring in things incrementally.
        Hide
        Md. Jahid Shohel added a comment -

        >- What about the entities of the module and how will the main application ORM filter influence the module ORM settings? By this I mean the Open Session In View Filter which is the most common for web apps.

        >>Yes this is a problem. I don't have clear answer for this, but some ORM can give a specific answer.

        I don't see how that is Click's problem though? How this problem is solved for enterprise applications which supports modularity? If there is a way to solve this for enterprise applications with modularity, then the same way it can be solved for Click applications.

        Show
        Md. Jahid Shohel added a comment - >- What about the entities of the module and how will the main application ORM filter influence the module ORM settings? By this I mean the Open Session In View Filter which is the most common for web apps. >>Yes this is a problem. I don't have clear answer for this, but some ORM can give a specific answer. I don't see how that is Click's problem though? How this problem is solved for enterprise applications which supports modularity? If there is a way to solve this for enterprise applications with modularity, then the same way it can be solved for Click applications.
        Hide
        Md. Jahid Shohel added a comment -

        >I also think we need to differentiate between modules and the way to manage a big project. One can certainly >break a big app into smaller modules (Eclipse subprojects), but they are still part of the same application and >are tested as a whole. However creating stand-alone application modules which are dropped into a main >application is not a simple task.

        So, should we finalize the definition of modularity that we are talking here? Like jar level modularity (where the dependency is only on jar, but there will be no source code copy), or just a separate package, which can be copied over and over on different projects? For the 2nd case, we should not use the word "modularity" though.

        Show
        Md. Jahid Shohel added a comment - >I also think we need to differentiate between modules and the way to manage a big project. One can certainly >break a big app into smaller modules (Eclipse subprojects), but they are still part of the same application and >are tested as a whole. However creating stand-alone application modules which are dropped into a main >application is not a simple task. So, should we finalize the definition of modularity that we are talking here? Like jar level modularity (where the dependency is only on jar, but there will be no source code copy), or just a separate package, which can be copied over and over on different projects? For the 2nd case, we should not use the word "modularity" though.
        Hide
        Bob Schellink added a comment -

        > So, should we finalize the definition of modularity that we are talking here?

        I don't know anymore. I think this question just solidifies that we are not trying to solve real world problems here, and are instead speculating and theorizing about problems that could fit into the modularity concept. Unfortunately this leads to bloatware eg. features added to the framework that nobody uses or that is too hard to use.

        Regardless here is what is already possible with the framework today:

        • split a large project into multiple pieces (modules) and assemble all the parts when building the final product (this is normally achieved with ANT, no need for "modularity")
        • split a large UI into "reusable" pieces that can be reused. This is already possible through multi package[1] support:

        click.xml:
        <pages package="com.mycorp.mod1">
        <pages package="com.mycorp.mod2">

        Granted this does not provide drop-in "module" support. Instead its a one-liner, so its pretty close. It also doesn't address multiple configurations, however multiple configurations won't work anyway eg: mod1 depends on Velocity and mod2 depends on Freemarker. Click only supports one Template Engine at a time.

        [1]: http://click.apache.org/docs/user-guide/html/ch04s02.html#application-multiple-packages

        Show
        Bob Schellink added a comment - > So, should we finalize the definition of modularity that we are talking here? I don't know anymore. I think this question just solidifies that we are not trying to solve real world problems here, and are instead speculating and theorizing about problems that could fit into the modularity concept. Unfortunately this leads to bloatware eg. features added to the framework that nobody uses or that is too hard to use. Regardless here is what is already possible with the framework today: split a large project into multiple pieces (modules) and assemble all the parts when building the final product (this is normally achieved with ANT, no need for "modularity") split a large UI into "reusable" pieces that can be reused. This is already possible through multi package [1] support: click.xml: <pages package="com.mycorp.mod1"> <pages package="com.mycorp.mod2"> Granted this does not provide drop-in "module" support. Instead its a one-liner, so its pretty close. It also doesn't address multiple configurations, however multiple configurations won't work anyway eg: mod1 depends on Velocity and mod2 depends on Freemarker. Click only supports one Template Engine at a time. [1] : http://click.apache.org/docs/user-guide/html/ch04s02.html#application-multiple-packages
        Hide
        Md. Jahid Shohel added a comment -

        So, we were sort of talking about making reusable packages (but not modules). If so, then is there anything else that need to be done? Because as Bob showed above, this functionality is already there.

        Show
        Md. Jahid Shohel added a comment - So, we were sort of talking about making reusable packages (but not modules). If so, then is there anything else that need to be done? Because as Bob showed above, this functionality is already there.
        Hide
        Bob Schellink added a comment -

        As mentioned above, one difficulty with building modular Click pages is how the modules would plug into the main application's BorderPage. One solution would be to not have a BorderPage at all. The primary use case for a BorderPage is to set a common template for all Pages. Using a PageInterceptor, one could also set the template and eliminate the BorderPage.

        Show
        Bob Schellink added a comment - As mentioned above, one difficulty with building modular Click pages is how the modules would plug into the main application's BorderPage. One solution would be to not have a BorderPage at all. The primary use case for a BorderPage is to set a common template for all Pages. Using a PageInterceptor, one could also set the template and eliminate the BorderPage.

          People

          • Assignee:
            Unassigned
            Reporter:
            Bob Schellink
          • Votes:
            6 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development