9 Replies Latest reply on Mar 22, 2013 9:47 AM by charles SALMON

    Extending the "rest" command (RestPlugin) for a javascript plugin

    charles SALMON Newbie

      Hello all,

       

      I am currently developping a plugin for the Qooxdoo javascript framework (qooxdoo.org) and I'd like to extend the "rest" command to generates some qooxdoo-javascript files to ease the uses of the created REST-endpoints.

       

      To summarize, when running

      [as7forge] as7forge $ qooxdoo setup

      ...

      ***SUCCESS*** Installed [QooxdooFacet] successfully.

      [as7forge] as7forge $ rest endpoint-from-entity com.sample.model.Customer.java

      ...

       

      I'd like having an extra javascript file created, and, if possible, having the option "--contentType" forced to the value "application/json".

       

      Can I create a QooxdooRestPlugin that inherits from the forge one, using the same @Alias name ?

      Or, if not working, what is the best strategy to implement my functionality ?

       

      Thanks a lot,

      Charles.

        • 1. Re: Extending the "rest" command (RestPlugin) for a javascript plugin
          Ivan St. Ivanov Novice

          Hey Charles,

           

          I was waiting for the Forge big guns to answer, but, anyway, here are my 5 cents ;-)

           

          By default you can have dependencies to the following Forge projects: org.jboss.forge.javaee.api, org.jboss.forge.maven.api, org.jboss.forge.scaffold.api and org.jboss.forge.shell.api. Yes, you can add whatever you like in your pom, but I am not sure how you can tell Weld to put it in your classloader at runtime. Probably there are some ways, but I don't know them. The RestPlugin is in the java ee impl module. So somebody that knows better how Forge integrates and works with JBoss Modules should tell you how you should add the appropriate dependency.

           

          As for reusing functionality in Forge plugins. I think that the way to reuse something in Forge 1 is to put that into a facet and not extending a plugin. Unfortunately it's not postulated anywhere and the Rest plugin has the functionality that you need inside the plugin and not as part of any facet.

           

          If I were you, I would:

           

          1) Check whether it is at all possible to have additional Forge dependencies added to your plugin

          2) Refactor the RestPlugin and move the endpoint-from-entity business logic in one of the existing or in a new facet and try to contribute it back to forge core.

          3) Import the facet in your plugin (project.getFacet(<the-facet-from-point-two>.class)) and call the method that generates entities

           

          Cheers,

          Ivan

          • 2. Re: Extending the "rest" command (RestPlugin) for a javascript plugin
            George Gastaldi Master

            Hi Charles,

             

            One option would be to create a plugin that listens for the CommandExecuted event and test if it the plugin executed was the REST plugin with the command endpoint-from-entity to create your javascript file.

             

            Starting in Forge 1.2.3.Final (to be released April 15th, 2013), you can also listen for PreCommandExecution events and veto them if needed.

             

            You could also create another plugin (with a different alias) that invokes the rest plugin and do  the stuff you need. This encapsulates the REST plugin execution and allows you to add any other actions you desire.

             

            Best Regards,

             

            George Gastaldi

            • 3. Re: Extending the "rest" command (RestPlugin) for a javascript plugin
              charles SALMON Newbie

              Excellent !

               

              I was thinking of using the CommandExecuted event, but as there is no documentation on it (except an example in the video), I was not sure if it was possible.

              So, for any command executed from a plugin, there is an event that is fired automatically, is it right ?

               

              I will try it as soon as I will have some time. and give you a feedback as soon as it works.

               

              Thanks a lot,

              Charles.

              • 4. Re: Extending the "rest" command (RestPlugin) for a javascript plugin
                George Gastaldi Master

                Hi Charles,

                 

                Correct, we may need to better document this behavior. Check the test cases for the time being.

                 

                Best Regards,

                 

                George Gastaldi

                • 5. Re: Extending the "rest" command (RestPlugin) for a javascript plugin
                  charles SALMON Newbie

                  OK, I am able to catch the end of the command execution:

                   

                  void postRestCommand(@Observes final CommandExecuted event) {
                            if (     "rest".equals(event.getCommand().getParent().getName())
                                      && "endpoint-from-entity".equals(event.getCommand().getName())
                                      && event.getStatus() == Status.SUCCESS) 
                            {
                                           // Successfully ran command: rest endpoint-from-entity ...
                                           // Get back args
                                           String contentType =  (String)event.getParameters()[1];

                   

                   

                  1- Looks like the event.getStatus() is always SUCCESS, even when an error has occured when running the rest command.

                  The code in the RestPlugin is as follow:

                       
                   if (javaTargets.isEmpty())
                        {
                           ShellMessages.error(out, "Must specify a domain @Entity on which to operate.");
                           return;
                        }
                  
                  

                  Is it a bug or is there something to do on my side ?

                   

                  2- What is the best way to get back the resolved options values ?

                  I am using event.getParamaters(), but, in the case where the only unordered option is given (JavaResource[]), I got event.getParamaters()[2] being an array of String, not Resource.

                  Example:

                  [as7forge] as7forge $ rest endpoint-from-entity com.sample.model.Customer.java
                  ***SUCCESS*** Generated REST endpoint for [com.sample.model.Customer]
                  ***INFO*** PARAMETERS
                  ***INFO*** org.jboss.forge.shell.util.PipeOutImpl@129ec2b
                  ***INFO*** application/xml
                  ***INFO*** [Ljava.lang.String;@12424eb
                  
                  

                   

                  Plugin command definition:

                  @Command(value = "endpoint-from-entity", help = "Creates a REST endpoint from an existing domain @Entity object")
                     public void endpointFromEntity(
                              final PipeOut out,
                              @Option(name = "contentType", defaultValue = MediaType.APPLICATION_XML, completer = ContentTypeCompleter.class) String contentType,
                              @Option(required = false) JavaResource[] targets)
                              throws FileNotFoundException
                     {
                  

                   

                   

                   

                  Moreover, the RestPlugin is doing a smart JavaResource(s) resolution to create Endpoints only on Entities of interest.

                  Is there a way to attach the resolved JavaResources to the event, so I will be able to know which resources have been treated, to treat them in my turn for generating my javascript files.

                  Or, am I obliged to copy/paste the JavaResources resolution used in the RestPlugin plugin ?

                   

                  Thanks, Charles

                  • 6. Re: Extending the "rest" command (RestPlugin) for a javascript plugin
                    George Gastaldi Master

                    Hi Charles,

                     

                    The first one seems an easy issue to solve. We'll fix it for 1.2.3.Final.

                    The second one we may need to think a little better.

                     

                    Best Regards,

                     

                    George Gastaldi

                    • 7. Re: Extending the "rest" command (RestPlugin) for a javascript plugin
                      Lincoln Baxter III Master

                      Hey Charles,

                       

                      Actually the CommandExecuted event just passes the unconverted parameter values. It might make sense to provide a map,  even with the converted values, but this of course would be an API change and your plugin would not be compatible with previous versions of forge. Additionally, we could fire a RestResourcesGenerated event to contain exactly the information you need, but this again would be an API change. I think of the two, adding a new event is the right choice.

                       

                      George is fixing the bug you reported in #1 as we speak.

                      • 8. Re: Extending the "rest" command (RestPlugin) for a javascript plugin
                        George Gastaldi Master

                        Charles,

                         

                        The first issue is fixed and scheduled for 1.2.3.Final: https://issues.jboss.org/browse/FORGE-830

                         

                        You may want to file an issue or even better, contribute to us implementing this specific event in the RestPlugin ?

                        We'll be glad to help you out on any issues you may find.

                        Besides this forum, you can meet us in irc.freenode.net @ #forge channel or even the forge-dev mailing list.