What is Scala?
Scala is a multi-paradigm language that integrates features of functional languages and object-oriented, unlike Java is an imperative language (except in version 8, Oracle has included some functional language features such as lambda functions).
It is therefore a good idea to use Scala and Java Alfresco since, in this way, we can have both –functional and imperative– paradigms to our service.
Version of Alfresco
The test was carried out on Alfresco 5.0.c and has been used maven with the archetype of creating AMP modules, version 2.2.0 of the SDK.
Installing components in Eclipse
The following components are recommended to use Scala in Eclipse IDE:
– Install from Marketplace: Scala IDE 4.2.x (recommended)
– Install from “Install new software” (optional):
Name: Maven for Scala
URL: http://alchim31.free.fr/m2e-scala/update-site/
Create project Alfresco AMP module (SDK 2.2.0)
mvn archetype:generate -Dfilter=org.alfresco: [INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building Maven Stub Project (No POM) 1 [INFO] ------------------------------------------------------------------------ [INFO] [INFO] >>> maven-archetype-plugin:2.2:generate (default-cli) > generate-sources @ standalone-pom >>> [INFO] [INFO] <<< maven-archetype-plugin:2.2:generate (default-cli) < generate-sources @ standalone-pom <<< [INFO] [INFO] --- maven-archetype-plugin:2.2:generate (default-cli) @ standalone-pom -- - [INFO] Generating project in Interactive mode [INFO] No archetype defined. Using maven-archetype-quickstart (org.apache.maven. archetypes:maven-archetype-quickstart:1.0) Choose archetype: 1: remote -> org.alfresco.maven.archetype:alfresco-allinone-archetype (Sample mu lti-module project for All-in-One development on the Alfresco plaftorm. Includes modules for: Repository WAR overlay, Repository AMP, Share WAR overlay, Solr co nfiguration, and embedded Tomcat runner) 2: remote -> org.alfresco.maven.archetype:alfresco-amp-archetype (Sample project with full support for lifecycle and rapid development of Repository AMPs (Alfre sco Module Packages)) 3: remote -> org.alfresco.maven.archetype:share-amp-archetype (Share project wit h full support for lifecycle and rapid development of AMPs (Alfresco Module Packages)) Choose a number or apply filter (format: [groupId:]artifactId, case sensitive co ntains): : 2 Choose org.alfresco.maven.archetype:alfresco-amp-archetype version: 1: 2.0.0-beta-1 2: 2.0.0-beta-2 3: 2.0.0-beta-3 4: 2.0.0-beta-4 5: 2.0.0 6: 2.1.0 7: 2.1.1 8: 2.2.0 Choose a number: 8: 8 Downloading: https://repo.maven.apache.org/maven2/org/alfresco/maven/archetype/a lfresco-amp-archetype/2.2.0/alfresco-amp-archetype-2.2.0.jar Downloaded: https://repo.maven.apache.org/maven2/org/alfresco/maven/archetype/al fresco-amp-archetype/2.2.0/alfresco-amp-archetype-2.2.0.jar (26 KB at 16.2 KB/se c) Downloading: https://repo.maven.apache.org/maven2/org/alfresco/maven/archetype/a lfresco-amp-archetype/2.2.0/alfresco-amp-archetype-2.2.0.pom Downloaded: https://repo.maven.apache.org/maven2/org/alfresco/maven/archetype/al fresco-amp-archetype/2.2.0/alfresco-amp-archetype-2.2.0.pom (3 KB at 16.3 KB/sec ) Define value for property 'groupId': : com.fegor.alfresco.scala Define value for property 'artifactId': : AlfScala [INFO] Using property: version = 1.0-SNAPSHOT Define value for property 'package': com.fegor.alfresco.scala: : Confirm properties configuration: groupId: com.fegor.alfresco.scala artifactId: AlfScala version: 1.0-SNAPSHOT package: com.fegor.alfresco.scala Y: :
Create folders to work with Scala
Create directories to work with Scala within the project:
src/main/scala src/test/scala
Modify pom.xml to integrate compilation Scala
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.fegorsoft.alfresco.scala</groupId> <artifactId>AlfScala</artifactId> <version>1.0-SNAPSHOT</version> <name>AlfScala Repository AMP project</name> <packaging>amp</packaging> <description>Manages the lifecycle of the AlfScala Repository AMP (Alfresco Module Package)</description> <parent> <groupId>org.alfresco.maven</groupId> <artifactId>alfresco-sdk-parent</artifactId> <version>2.2.0</version> </parent> <repositories> <repository> <id>artima</id> <name>Artima Maven Repository</name> <url>http://repo.artima.com/releases</url> </repository> </repositories> <!-- SDK properties have sensible defaults in the SDK parent, but you can override the properties below to use another version. For more available properties see the alfresco-sdk-parent POM. --> <properties> <!-- The following are default values for data location and Alfresco Community version. Uncomment if you need to change (Note. current default version for Enterprise edition is 5.1) <alfresco.version>5.1.e</alfresco.version> <alfresco.data.location>/absolute/path/to/alf_data_dev</alfresco.data.location> --> <!-- This control the root logging level for all apps uncomment and change, defaults to WARN <app.log.root.level>WARN</app.log.root.level> --> <!-- Set the enviroment to use, this controls which properties will be picked in src/test/properties for embedded run, defaults to the 'local' environment. See SDK Parent POM for more info. <env>local</env> --> <recompileMode>incremental</recompileMode> <fsc>false</fsc> </properties> <!-- Here we realize the connection with the Alfresco selected platform (e.g.version and edition) --> <dependencyManagement> <dependencies> <!-- Setup what versions of the different Alfresco artifacts that will be used (depends on alfresco.version), so we don't have to specify version in any of the dependency definitions in our POM. For more info see: http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Importing_Dependencies --> <dependency> <groupId>${alfresco.groupId}</groupId> <artifactId>alfresco-platform-distribution</artifactId> <version>${alfresco.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <!-- Following dependencies are needed for compiling Java code in src/main/java; <scope>provided</scope> is inherited for each of the following; for more info, please refer to alfresco-platform-distribution POM --> <dependency> <groupId>${alfresco.groupId}</groupId> <artifactId>alfresco-repository</artifactId> </dependency> <!-- If we are running tests then make the H2 Scripts available Note. tests are skipped when you are running -Pamp-to-war --> <dependency> <groupId>${alfresco.groupId}</groupId> <artifactId>alfresco-repository</artifactId> <version>${alfresco.version}</version> <classifier>h2scripts</classifier> <scope>test</scope> <exclusions> <exclusion> <groupId>*</groupId> <artifactId>*</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.scala-lang</groupId> <artifactId>scala-compiler</artifactId> <version>2.11.8</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.scala-lang</groupId> <artifactId>scala-library</artifactId> <version>2.11.8</version> </dependency> <dependency> <groupId>com.typesafe.scala-logging</groupId> <artifactId>scala-logging-slf4j_2.11</artifactId> <version>2.1.2</version> </dependency> <dependency> <groupId>org.scala-lang.modules</groupId> <artifactId>scala-xml_2.11</artifactId> <version>1.0.3</version> </dependency> <dependency> <groupId>org.scalactic</groupId> <artifactId>scalactic_2.11</artifactId> <version>3.0.0-M15</version> </dependency> <dependency> <groupId>org.scalatest</groupId> <artifactId>scalatest_2.11</artifactId> <version>3.0.0-M15</version> <scope>test</scope> </dependency> <!-- <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> --> </dependencies> <profiles> <!-- Brings in the extra Enterprise specific repository classes, if the 'enterprise' profile has been activated, needs to be activated manually. --> <profile> <id>enterprise</id> <dependencies> <dependency> <groupId>${alfresco.groupId}</groupId> <artifactId>alfresco-enterprise-repository</artifactId> <version>${alfresco.version}</version> <scope>provided</scope> </dependency> </dependencies> </profile> </profiles> <build> <pluginManagement> <plugins> <plugin> <groupId>net.alchim31.maven</groupId> <artifactId>scala-maven-plugin</artifactId> <version>3.2.1</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>2.0.2</version> </plugin> </plugins> </pluginManagement> <plugins> <plugin> <inherited>true</inherited> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.7</source> <target>1.7</target> </configuration> </plugin> <plugin> <groupId>org.scala-tools</groupId> <artifactId>maven-scala-plugin</artifactId> <version>2.15.2</version> <executions> <!-- Run scala compiler in the process-resources phase, so that dependencies on scala classes can be resolved later in the (Java) compile phase --> <execution> <id>scala-compile-first</id> <phase>process-resources</phase> <goals> <goal>compile</goal> </goals> </execution> <!-- Run scala compiler in the process-test-resources phase, so that dependencies on scala classes can be resolved later in the (Java) test-compile phase --> <execution> <id>scala-test-compile</id> <phase>process-test-resources</phase> <goals> <goal>testCompile</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>build-helper-maven-plugin</artifactId> <executions> <!-- Add src/main/scala to source path of Eclipse --> <execution> <id>add-source</id> <phase>generate-sources</phase> <goals> <goal>add-source</goal> </goals> <configuration> <sources> <source>src/main/scala</source> </sources> </configuration> </execution> <!-- Add src/test/scala to test source path of Eclipse --> <execution> <id>add-test-source</id> <phase>generate-test-sources</phase> <goals> <goal>add-test-source</goal> </goals> <configuration> <sources> <source>src/test/scala</source> </sources> </configuration> </execution> </executions> </plugin> <!-- to generate Eclipse artifacts for projects mixing Scala and Java --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-eclipse-plugin</artifactId> <version>2.8</version> <configuration> <downloadSources>true</downloadSources> <downloadJavadocs>true</downloadJavadocs> <projectnatures> <projectnature>org.scala-ide.sdt.core.scalanature</projectnature> <projectnature>org.eclipse.jdt.core.javanature</projectnature> </projectnatures> <buildcommands> <buildcommand>org.scala-ide.sdt.core.scalabuilder</buildcommand> </buildcommands> <classpathContainers> <classpathContainer>org.scala-ide.sdt.launching.SCALA_CONTAINER</classpathContainer> <classpathContainer>org.eclipse.jdt.launching.JRE_CONTAINER</classpathContainer> </classpathContainers> <excludes> <!-- in Eclipse, use scala-library, scala-compiler from the SCALA_CONTAINER rather than POM <dependency> --> <exclude>org.scala-lang:scala-library</exclude> <exclude>org.scala-lang:scala-compiler</exclude> </excludes> <sourceIncludes> <sourceInclude>**/*.scala</sourceInclude> <sourceInclude>**/*.java</sourceInclude> </sourceIncludes> </configuration> </plugin> <!-- When run tests in the test phase, include .java and .scala source files --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <configuration> <includes> <include>**/*.java</include> <include>**/*.scala</include> </includes> </configuration> </plugin> </plugins> </build> </project>
Create a unit test
In this case a unit test is created to retrieve the content is inside ‘Company Home’.
package com.fegor.alfresco.scala.test /* * @author Fernando González (fegor at fegor dot com) * */ import org.scalatest.junit.AssertionsForJUnit import org.slf4j.LoggerFactory import com.typesafe.scalalogging.slf4j.Logger import org.junit.Assert._ import org.junit.{ Test, Before } import org.junit.runner.RunWith import com.tradeshift.test.remote.{ Remote, RemoteTestRunner } import org.springframework.test.context.ContextConfiguration import org.springframework.test.context.junit4.SpringJUnit4ClassRunner import org.springframework.context.ApplicationContext import org.springframework.beans.factory.annotation.{ Autowired, Qualifier } import org.alfresco.util.ApplicationContextHelper import org.alfresco.model.ContentModel import org.alfresco.service.cmr.repository.{ StoreRef, NodeService } import org.alfresco.service.cmr.search.{ SearchService, ResultSet } import org.alfresco.repo.security.authentication.AuthenticationUtil /** Test Alfresco in Scala * * @constructor create tests for Alfresco with Scala */ @RunWith(classOf[RemoteTestRunner]) @Remote(runnerClass = classOf[SpringJUnit4ClassRunner]) @ContextConfiguration(Array("classpath:alfresco/application-context.xml")) class RepositoryTest extends AssertionsForJUnit { val logger = Logger(LoggerFactory.getLogger(classOf[RepositoryTest])) val storeRef: StoreRef = new StoreRef(StoreRef.PROTOCOL_WORKSPACE, "SpacesStore") val ctx: ApplicationContext = ApplicationContextHelper.getApplicationContext val nodeService: NodeService = ctx.getBean("NodeService").asInstanceOf[NodeService] var searchService: SearchService = ctx.getBean("SearchService").asInstanceOf[SearchService] /* Initialize */ @Before def initialize() { AuthenticationUtil.setFullyAuthenticatedUser("admin") } /* Alfresco repository test */ @Test def testRepositoryList() { val rs: ResultSet = searchService.query(storeRef, SearchService.LANGUAGE_LUCENE, "PATH:\"/app:company_home/*\"") assert(rs.length() > 0) logger.info((for (i <- 0 until rs.length()) yield nodeService.getProperty(rs.getNodeRef(i), ContentModel.PROP_NAME)) mkString ",") rs.close() } }
Enable debugging classes log4j.properties
log4j.logger.com.fegor.alfresco.scala.test.RepositoryTest=DEBUG
Results ejecutción test
2016-03-30 21:23:09,884 INFO [extensions.webscripts.ScriptProcessorRegistry] [main] Registered script processor javascript for extension js 2016-03-30 21:23:10,165 INFO [scala.test.RepositoryTest] [main] Guest Home,User Homes,Shared,Imap Attachments,IMAP Home,Sites,Data Dictionary Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 41.923 sec - in com.fegor.alfresco.scala.test.RepositoryTest
Reference Websites
http://scala-ide.org/docs/tutorials/m2eclipse/index.html
http://www.scalatest.org/getting_started_with_junit_4_in_scala
http://ted-gao.blogspot.com.es/2011/09/mixing-scala-and-java-in-project.html
https://en.wikipedia.org/wiki/Scala_(programming_language)
https://es.wikipedia.org/wiki/Scala_(lenguaje_de_programaci%C3%B3n)