Do you remember those days when you'd create a new Java Nuxeo Operation in your bundle and the whole process of creating it seemed a little too much? Indeed, there was a lot going on: checking if you had the right Maven dependencies, and trying to find another Operation somewhere to get the right Java Annotations for parameters and run method before you finally did a "nice" copy paste!
You must have also put in effort in creating a Nuxeo Package to simplify your application deployment inside your Nuxeo Platform, creating a Java Listener or a Nuxeo Service, trying to figure out what event name exists, how to define your Service (which class? which XML?), or making sure you added your component to the
Well, that time is now over! (You didn't see that coming, eh!)
Now you'll even be able to use your beloved IDE (as it's a headless tool.). Let’s take a look at this new easier process!
Setting up Your Environment
It's based on a great tool, Yeoman. Yeoman helps you kickstart new projects, prescribing best practices and tools to help you stay productive.
With a correct Node installation, the simplest way is to install the module in your global registry:
npm install -g yo generator-nuxeo
yo is working well:
You must find the
nuxeo generator in the output list.
Available Generators: nuxeo
That’s it! We are all set to save a lot of time now.
We will take the most common use case: Creating a new Operation and bundle it in a Nuxeo Package.
mkdir sample-project && cd sample-project yo nuxeo operation package
Let's talk a little bit about what is requested while generating:
invoke Requirements: multi-module, single-module, operation, package info You'll be prompted for generation of: multi-module, single-module, operation, package
Other modules may be needed. In our example, we are starting from an empty project and we need to bootstrap a Maven multi-module, then create a
-core module where we'll have the sources of our Operation. Finally, we need a
-package module for our Nuxeo Package.
create Generating Multi module (Your project parent POM) info Parameters: Use a parent artifact, Parent group, Parent artifact, Parent version, Import nuxeo in the `dependency management`, Nuxeo version, Project group, Project artifact, Project version, Project description ? Use a parent artifact (for instance your company's BOM or the org.nuxeo.ecm.distribution:nuxeo-distribution POM)? Yes ? Parent Group id: org.nuxeo.ecm.distribution ? Parent Artifact id: nuxeo-distribution ? Parent Version: 7.10 ? Project group id: com.bigcorp.sample ? Project Artifact id: sample-project-parent ? Project version: 1.0-SNAPSHOT ? Project description: my sample
Sometimes you'll need to use a BOM; aka your enterprise
pom with your dependency management. The other option is to use the
nuxeo-distribution artifact as module parent, but in case you don't want to do that, you can import your dependency management in the pom.
create Generating Single module info Parameters: Nuxeo version, Project group, Project artifact, Project version, Project description ? Nuxeo Version: 7.10 (LTS 2015) ? Project Group id: com.bigcorp.sample ? Project Artifact id: sample-project-core ? Project version: 1.0-SNAPSHOT ? Project description: create Generating Operation info Parameters: Operation class name, Operation label ? Operation class name: MyOperation ? Operation label: My Cool Operation create Generating Package info Parameters: Package artifact, Package name, Company name ? Package Artifact id: sample-project-package ? Package name: sample app ? Company name: bigcorp
You can do the same for the others generators.
create Configuration: multi info Maven dependency: org.nuxeo.ecm.automation:nuxeo-automation-core info Maven dependency: org.nuxeo.ecm.automation:nuxeo-automation-test:::test create pom.xml create sample-project-core/src/main/resources/META-INF/MANIFEST.MF create sample-project-core/pom.xml create sample-project-core/src/main/java/com/bigcorp/sample/package-info.java create sample-project-core/src/test/resources/log4j.xml create sample-project-core/src/main/java/com/bigcorp/sample/MyOperation.java create sample-project-core/src/test/java/com/bigcorp/sample/TestMyOperation.java create sample-project-core/src/main/resources/OSGI-INF/my-operation-operation-contrib.xml create sample-project-marketplace/pom.xml create sample-project-marketplace/src/main/assemble/assembly.xml create sample-project-marketplace/src/main/resources/install/templates/sample-project/nuxeo.defaults create sample-project-marketplace/src/main/resources/install.xml create sample-project-marketplace/src/main/resources/package.xml info You can start editing code or you can continue with calling another generator (yo nuxeo <generator>..)
Voilà! All the files are created. You can ask Maven to
package everything, or you can open the project and start coding! Note that we added a unit test for Operation, Service, and Event Listener (you're welcome!). And please, instead of removing the test files, make them work! ;)
Under the Hood
You already know that our generator is built on top of Yeoman but we tweaked it a little bit because all our generators are pulled from another repository generator-nuxeo-meta to give us a meta-model that represents what is created and move all the generation logic to the engine. The goal of this repository is to handle all generated templates; like the
pom.xml of your modules, Java classes, Package assembly file, and so on.
If we look closer at how it works, each generator has a
descriptor.js file. This file describes what must be requested of the user and what must be created, using a clear and simple JSON format.
The descriptor file is composed of different definitions. You can check out the README for the description.
params: It defines which parameters will be prompted to the user. It is handled with Inquirer.js; and we added some sugar coating! For instance, a
storeparameter will not be asked twice during a generation process even if it is required by several generators.
templatesfolder: After having the user's inputs, the content of the
templatesfolder is rendered. We decided to use the more natural way to template a file to a specific path: by using just the path.
contributions: It’s a templating system for contributions but with a
destentry for the filenames. It renders the file in the
OSGI-INFfolder, which is then added to the
test-java: It’s a templating system for Java classes, which also uses a
destentry, and expects to have a user's input
package. It renders the file in the corresponding package.
dependencies: List of Maven GAV (group, artifact, version) of the dependencies. The format is:
With those entries, you should be able to understand and create your own generator, and/or contribute with an awesome Pull Request!
The next steps are:
- Bringing Nuxeo Studio and the Generator to work together allowing you to create constant class, based on what is defined on Studio side
- New generators to bootstrap Polymer / Angular app to be deployed in your Nuxeo Platform
- Bug fixing