cancel
Showing results for 
Search instead for 
Did you mean: 

Desplegar una acción en Alfresco

peli
Champ in-the-making
Champ in-the-making

Buenos días,

llevo unas semanas trabajando con Alfresco. Estoy intentando implementar una acción Java para llamarla desde una regla que ejecuta un script cuando se modifica un documento concreto del share. Estoy muy confusa sobre cúal es el procedimiento a seguir para poder llamar a esta acción desde un script. He creado un proyecto Maven, que genera la jerarquía de directorios por defecto. Una vez implementada la acción, ¿Cómo se hace el despliegue de la acción en Alfresco? y ¿Que directorios de /tomcat se utilizan?

Gracias.

17 REPLIES 17

angelborroy
Community Manager Community Manager
Community Manager

Te recomiendo que leas la serie de tutoriales de Jeff Potts sobre desarrollo en Alfresco: About the Alfresco Developer Tutorial Series | ECM Architect 

En concreto, para esta tarea debes prestar atención a:

Getting Started with the Alfresco Maven SDK | ECMArchitect | Alfresco Developer Tutorials 

Creating Custom Actions in Alfresco | ECMArchitect | Alfresco Developer Tutorials 

Hyland Developer Evangelist

peli
Champ in-the-making
Champ in-the-making

Una vez leída la serie de tutoriales concluyo que, para crear una acción que implemente una nueva funcionalidad en Alfresco, primero creo un proyecto Maven; desarrollo la clase en cuestión que extienda de ActionExecuterAbstractBase y registro ésta a través de un bean ubicado en el directorio src\main\resources\alfresco\module\*-repo\context\service-context.xml del proyecto creado; por último ejecutar ./run.sh para crear el AMP y desplegarlo en Alfresco a través del servidor Tomcat embebido. ¿Es éste el proceso correcto?

Y si es así, accediendo a http:\\localhost:8080/share ya se podría llamar a esta acción desde un script? Mi intención es crear una script que invoque la acción, por lo que no necesitaría mostrarla en la interfaz de usuario de share y por tanto no necesitaría crear un artefacto para hacer visible la acción en el share. ¿Es acertada esta suposición?

La acción que quiero implementar es para trabajar con documentos binarios. Se ejecuta un script que invoca la acción pasando unos valores por parámetros, la acción accede al documento binario y lo rellena con los parámetros que recibe para devolver el documento binario rellenado.

Muchas gracias.

angelborroy
Community Manager Community Manager
Community Manager

El planteamiento tiene buena pinta.

Mediante JavaScript deberías poder invocar la acción utilizando el nombre que le pongas al bean de Spring sin más desarrollos que el propio AMP del repo.

Hyland Developer Evangelist

peli
Champ in-the-making
Champ in-the-making

La semana pasada estuve probando a desplegar un AMP de la forma descrita anteriormente. Creé un proyecto Maven con una clase que simplemente tenía un System.out.println() para escribir en el log de Alfresco. Una vez generado el AMP, lo ubiqué en el directorio alfresco\amps e instalé el AMP con el comando java -jar alfrescp-mmt.jar install amps/*-repo.amp tomcat/webapps/alfresco.war. Sin errores hasta el momento.

Accedo a mi localhost:8080/share y creo un script js ubicado en Diccionario de datos/Script, que se ejecuta con una regla y el cual invoca al método de la clase utilizando <valuedelbean>.<nombredelmétodo>;. Al ejecutarse la regla salta un error diciendo que <valuedelbean> no está definido.

He estado buscando y parece que la definición del bean debe ir en el directorio del proyecto src/main/amp/config/alfresco/module/repo-amp/context/service-context.xml y yo lo tengo en src\main\resources\alfresco\module\*-repo\context\service-context.xml, ya que en la distribución de mi proyecto no existe ese directorio.

Puede estar ahí la causa de que no reconozca el bean?

Gracias

cristinamr
World-Class Innovator
World-Class Innovator

Dos cosas: ¿Qué versión de SDK usas para tu proyecto? Lo puedes ver en el pom.xml del amp que estés compilando.

Yo con una 2.1.1 lo tengo aquí:

¿Puedes pasarnos una captura de la estructura de tu proyecto? 

Coméntanos y te intentamos echar una mano.

Cris.

--
VenziaIT: helping companies since 2005! Our ECM products: AQuA & Seidoc

peli
Champ in-the-making
Champ in-the-making

Pues estoy usando la versión del SDK 3.0.1, y la estructura del proyecto es esta:

Puede que influya que para generar el proyecto haya elegido el artefacto 4. alfresco-platform-jar-archetype? Ya que sólamente incluye como opciones las versiones 3.0.0 y 3.0.1...

De todas formas, según el tutorial  Getting Started with the Alfresco Maven SDK | ECMArchitect | Alfresco Developer Tutorials, comenta que el directorio src/main/resources/alfresco/module/*-repo es dónde deben ir las declaraciones de los beans y todo lo referente a los AMP...

Muchas gracias!

cristinamr
World-Class Innovator
World-Class Innovator

Mira, en un proyecto que tengo 3.0.0 tengo la siguiente distribución:

Y dentro del proyecto de Alfresco:

Echa un vistazo a tu estructura y mira a ver si lo tienes en la ruta src/main/resources/alfresco/module/nombre_proyecto/context

Cuéntanos.

Cris.

--
VenziaIT: helping companies since 2005! Our ECM products: AQuA & Seidoc

peli
Champ in-the-making
Champ in-the-making

Si, es exactamente en serc/main/resources/alfresco/module/*-repo/context/service-context.xml donde he definido el bean:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
          http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">


    <bean id="myAlfrescoCustom" class="com.alf.ActionDemo"  parent="baseJavaScriptExtension">
        <property name="extensionName"   value="mycustom" />
    </bean>
</beans>

La clase ActionDemo:

public class ActionAlfrescoDemo extends BaseProcessorExtension {
 
 public void writeToCatalina(String text) {
  System.out.println("Message from Alfresco websript: " + text);
 }

El Script JS en Alfresco:

mycustom.writeToCatalina("Ei! ");

Eso es todo lo que tengo... el módulo AMP está instalado en alfresco.war, comprobado con java -jar bin/alfresco-mmt.jar list y cuándo se acciona la regla que ejecuta el script sale el siguiente log:

2018-03-06 10:52:41,542 ERROR [org.springframework.extensions.webscripts.AbstractRuntime] [http-apr-8080-exec-10] Exception from executeScript: 02060021 Failed to execute script 'workspace://*/*': 02060020 ReferenceError: "mycustom" is not defined.

[...]

Ais, si ya estoy dándole mil vueltas a esto... cuándo se consiga solventar este asunto y tenga que ponerme a implementar la tarea de generación de documentos, me caigo muerta

cristinamr
World-Class Innovator
World-Class Innovator

Creo que te faltan los getters y setter del objeto.

Vamos a hacer una cosa, te voy a pasar un ejemplo que funciona y revisas el código ¿vale?

EJEMPLO (sacado del libro Alfresco developers, es para versiones antiguas pero para este tipo de conceptos/ejemplos va bien):

clase java (en la ruta src/java/com/someco/jscript/Ratings.java😞

package com.someco.jscript;
import org.alfresco.repo.jscript.ScriptNode;
import org.alfresco.repo.jscript.ValueConverter;
import org.alfresco.repo.processor.BaseProcessorExtension;
import org.alfresco.service.cmr.repository.NodeRef;
import com.someco.service.RatingService;
public class Ratings extends BaseProcessorExtension {
private RatingService ratingService;
private final ValueConverter valueConverter = new ValueConverter();
public void rate(ScriptNode scriptNode, int rating, String user) {
ratingService.rate((NodeRef)valueConverter.convertValueForRepo(scriptNode), rating, user);
}
public void deleteRatings(ScriptNode scriptNode) {
ratingService.deleteRatings((NodeRef)valueConverter.convertValueForRepo(scriptNode));
}
public Object getRatingData(ScriptNode scriptNode) {
return ratingService.getRatingData((NodeRef)valueConverter.convertValueForRepo(scriptNode));
}
public int getUserRating(ScriptNode scriptNode, String user) {
return ratingService.getUserRating((NodeRef)valueConverter.convertValueForRepo(scriptNode), user);
}
public boolean hasRatings(ScriptNode scriptNode) {
return ratingService.hasRatings((NodeRef)valueConverter.convertValueForRepo(scriptNode));
}
public void setRatingService(RatingService ratingService) {
this.ratingService = ratingService;
}
}

Otro java más con el servicio customizado (ruta src/java/com/someco/service/RatingService.java)

package com.someco.service;
import org.alfresco.service.cmr.repository.NodeRef;
public interface RatingService {
public void rate(NodeRef nodeRef, int rating, String user);
public void deleteRatings(NodeRef nodeRef);
public RatingData getRatingData(NodeRef nodeRef);
public int getUserRating(NodeRef nodeRef, String user);
public boolean hasRatings(NodeRef nodeRef);
public interface RatingData {
public int getCount();
public double getRating();
public int getTotal();
}
}

contexto con el bean (en la ruta config/alfresco/extension/someco-services-context.xml)

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>
<beans>
....
<bean id="ratingScript" parent="baseJavaScriptExtension" class="com.someco.jscript.Ratings">
<property name="extensionName">
<value>ratings</value>
</property>
<property name="ratingService">
<ref bean="RatingService" />
</property>
</bean>
</beans>

Y  javascript (en la ruta src/scripts/addTestRating.js😞

// randomly pick a num b/w 1 and 5 inclusive
var ratingValue = Math.floor(Math.random()*5) + 1;
// use the rating service instead
/*
// add the aspect to this document if it needs it
if (document.hasAspect("sc:rateable")) {
logger.log("Document already as aspect");
} else {
logger.log("Adding rateable aspect");
document.addAspect("sc:rateable");
}
var props = new Array(2);
props["sc:rating"] = ratingValue;
props["sc:rater"] = person.properties.userName;
// create a new ratings node and set its properties
var ratingsNode = document.createNode("rating" + new Date().getTime(), "sc:rating", props, "sc:ratings");
ratingsNode.save();
*/
ratings.rate(document, ratingValue, person.properties.userName);
logger.log("Ratings node saved.");

Prueba y nos dices. Si consigues sacar este ejemplo, el tuyo lo verás con más claridad y podrás corregirlo. El caso es no quedarte estancada y ver si un ejemplo probado te sale para ir aprendiendo con la práctica.

Coméntanos,

Cris.

--
VenziaIT: helping companies since 2005! Our ECM products: AQuA & Seidoc