Der Aufstieg

Da wir stets bemüht sind, den Nuxeo Server besser, moderner und effizienter zu machen, haben wir unsere Aufmerksamkeit auf den Aufstieg der Programmiersprache Kotlin gelenkt.

Nuxeo KotlinKotlin ist eine statisch typisierte Programmiersprache, die auf der Java Virtual Machine läuft und in den JavaScript-Quellcode von JetBrains übersetzt werden kann. Es ist eine leistungsstarke, objektorientierte Sprache und eine "bessere Programmiersprache" als Java, und ist dabei dennoch vollständig mit Java-Code kompatibel, wodurch Unternehmen schrittweise von Java zu Kotlin migrieren können.

Mit der Ankündigung von Google, dass alle Android-Apps nun auch mit Kotlin geschrieben werden können, ist diese Sprache nun in die erste Reihe vorgerückt.

Heute freuen wir uns, Ihnen mitteilen zu können, dass Sie Ihre Nuxeo-Bundles jetzt mit Kotlin programmieren können.

Kotlin und Java

Kotlin ist vollständig mit Java-Code kompatibel und beide können in einem Bundle übersetzt werden und gemeinsam verwendet werden!

So funktioniert es

Projektstruktur

Wie jede Maven-Projektstruktur sieht das Kotlin-Bundle wie ein Nuxeo Java-Bundle aus, außer dass Sie hier einen neuen Ordner namens ‚kotlin' anstelle von ‚java' für den Kotlin-Code nutzen:

├── pom.xml
└── src
    ├── main
    │   ├── kotlin
    │   │   └── org
    │   │       └── nuxeo
    │   │           └── sample
    │   └── resources
    │       ├── META-INF
    │       └── OSGI-INF
    └── test
        └── org
            └── nuxeo
                └── kotlin
                    └── sample

Natürlich können Sie Java und Kotlin im selben Bundle mischen.

├── pom.xml
└── src
    ├── main
    │   ├── kotlin
    │   │   └── org
    │   │       └── nuxeo
    │   │           └── sample
    |   |__ java
    |   |   |__ org......
    │   └── resources

Das erste Kotlin-Bundle

Um dies zu ermöglichen und um Ihnen den Start Ihres Projektes zu erleichtern, haben wir bereits eine spezifische Vorlage mit Nuxeo CLI erstellt. Erstellen wir ein neues Bundle mit einem Paket und einer Beispieloperation.

# Ensure to have the latest version
nuxeo update

# You can create an empty bundle using
# nuxeo bootstrap kotlin-module
# But, following this blog, we are going to create a more complete example
mkdir kotlin-sample && cd $_
nuxeo bootstrap kotlin-operation package

Sie können wie folgt antworten, oder seien Sie kreativ:

     info You'll be prompted for generation of:
     info   kotlin-sample-kotlin: kotlin-module, kotlin-operation
     info   kotlin-sample-package: 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: 9.1
? Project Group id: org.nuxeo.sample
? Project Artifact id: kotlin-sample-parent
? Project Version: 1.0-SNAPSHOT
? Project Description:

   create Generate Module: kotlin-sample-kotlin

   create Generating Kotlin module
     info   Parameters: Nuxeo version, Project group, Project artifact, Project version, Project description
? Project Group id: org.nuxeo.sample
? Project Artifact id: kotlin-sample-kotlin
? Project version: 1.0-SNAPSHOT
? Project description:

   create Generating Kotlin operation
     info   Parameters: Operation class name, Operation label
? Operation class name: SampleOperation
? Operation label: My Kotlin Operation

   create Generate Module: kotlin-sample-package

   create Generating Package
     info   Parameters: Package artifact, Package version, Package name, Company name
? Package Artifact id: kotlin-sample-package
? Package Version: 1.0-SNAPSHOT
? Package name: kotlin-sample
? Company name:

Die erste Kotlin-Operation

Hier ist die erstellte Kotlin-basierte Operation, die annäherungsweise das selbe Verhalten zeigt wie eine Java-Operation:

package org.nuxeo.sample

import org.nuxeo.ecm.automation.core.Constants
import org.nuxeo.ecm.automation.core.annotations.Context
import org.nuxeo.ecm.automation.core.annotations.Operation
import org.nuxeo.ecm.automation.core.annotations.OperationMethod
import org.nuxeo.ecm.automation.core.annotations.Param
import org.nuxeo.ecm.core.api.CoreSession
import org.nuxeo.ecm.core.api.DocumentModel
import org.nuxeo.ecm.core.api.PathRef

@Operation(id = "Document.SampleOperation", category = Constants.CAT_DOCUMENT, label="My Kotlin Operation", description="Describe here what your operation does.")
open class SampleOperation {

    @Context
    protected lateinit var session: CoreSession

    @Param(name = "path", required = false)
    protected var path: String? = null

    @OperationMethod
    fun run(): DocumentModel {
        return when {
            path.isNullOrBlank() -> session.rootDocument
            else -> session.getDocument(PathRef(path))
        }
    }
}

Natürlich wird diese Operation wie jedes andere Nuxeo-Bundle zum MANIFEST beitragen und darin erwähnt.

Maven Build-Plugin

Sie werden feststellen, dass wir das Kotlin Maven Build-Plugin hinzugefügt haben, um wie folgt korrekt zu übersetzen:

<plugin>
  <artifactId>kotlin-maven-plugin</artifactId>
  <groupId>org.jetbrains.kotlin</groupId>
  <version>${kotlin.version}</version>
  <executions>
    <execution>
      <id>compile</id>
      <goals>
        <goal>compile</goal>
      </goals>
    </execution>
    <execution>
      <id>test-compile</id>
      <goals>
        <goal>test-compile</goal>
      </goals>
    </execution>
  </executions>
</plugin>

Bereitstellung

Wie jedes andere Nuxeo-Bundle können Sie Ihr Projekt durch Ausführung von ‚mvn package' erstellen und das Bundle in Ihrem ‚$NUXEO_HOME/nxserver/bundles'-Ordner ablegen.

Bevor Sie jedoch den Nuxeo Server starten, vergessen Sie bitte nicht die dazugehörige JetBrains Kotlin Runtime-Bibliothek in ‚NUXEO_HOME/nxserver/lib' festzulegen.

Das Beste: dies wird mit dem Nuxeo Package, das wir gerade erstellt haben, automatisch ausgeführt. Sie müssen Ihr Paket also nur noch bereitstellen.

# Build the whole bundle
cd $PROJECT_ROOT && mvn package

# Ensure your server is stopped
$NUXEO_HOME/bin/nuxeoctl stop

# Install your bundle
$NUXEO_HOME/bin/nuxeoctl mp-install $PROJECT_ROOT/kotlin-sample-package/target/kotlin-sample-package-*.zip

# Start your server
$NUXEO_HOME/bin/nuxeoctl start

Als nächstes definieren wir die Operation und rufen sie mithilfe von ‚curl' ab:

# Get Operation Documentation
curl -u Administrator:Administrator http://localhost:8080/nuxeo/site/automation/Document.SampleOperation

# Execute the Operation
curl -H 'Content-Type:application/json+nxrequest' -X POST -d '{"params":{},"context":{}}' -u Administrator:Administrator http://localhost:8080/nuxeo/api/v1/automation/Document.SampleOperation

Fantastische Ergebnisse!

Debugging

Fügen Sie irgendwo in Ihrer Operation einen "breakpoint" ein und nutzen Sie Ihre IDE Remote Debugging-Funktion, um die Verbindung mit Nuxeo herzustellen (Port 8787). Sie können alle Schritte in Kotlin und in Java ausführen.

Debug

Tests

Der Einsatz von Kotlin für eine schnellere Programmierung bewahrt Sie nicht davor, diese zu testen. Das ist leider die Wahrheit.

Wie Sie in der ‚TestSampleOperation'-Datei sehen, können Sie dafür unser Test Framework nutzen:

@RunWith(FeaturesRunner::class)
@Features(AutomationFeature::class)
@Deploy("org.nuxeo.sample.kotlin-sample-kotlin")
open class TestSampleOperation {

    @Inject
    protected lateinit var session: CoreSession

    ...
}

Probieren Sie es aus. Wir wünschen Ihnen viel Spaß mit dieser modernen und eleganten Programmiersprache.