tag:blogger.com,1999:blog-67795290144564979142024-03-13T14:21:53.773-07:00Alfresco tips & tutorialsPatriciahttp://www.blogger.com/profile/08618980369195930324noreply@blogger.comBlogger10125tag:blogger.com,1999:blog-6779529014456497914.post-22727846115078391652011-08-29T04:55:00.000-07:002011-10-06T03:33:58.148-07:00Alfresco - Combinando WebScripts con Acciones (parte 3)<div class="separator" style="clear: both; text-align: center;">
</div>
Y por ultimo, os dejo unas capturas de los pasos realizados...<br />
<br />
1. Creamos un contenido de tipo Documento<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://img706.imageshack.us/img706/2346/cap4z.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="180" src="http://img706.imageshack.us/img706/2346/cap4z.jpg" width="640" /></a></div>
<br />
<br />
2. Le asociamos uno o varios documentos<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://img812.imageshack.us/img812/2233/cap1l.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="http://img812.imageshack.us/img812/2233/cap1l.jpg" width="640" /></a></div>
<br />
<br />
<br />
<br />
3. Una vez tenemos los documentos asociados, nos sale la opción para poder verlos<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://img845.imageshack.us/img845/6394/cap3k.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="208" src="http://img845.imageshack.us/img845/6394/cap3k.jpg" width="640" /></a></div>
<br />
<br />
4. Hacemos click y nos muestra una nueva pantalla con la lista de asociados<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://img808.imageshack.us/img808/5458/cap2tb.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="124" src="http://img808.imageshack.us/img808/5458/cap2tb.jpg" width="640" /></a></div>
<br />
Y esto ha sido todo por esta vez... espero que os resulte útil!Patriciahttp://www.blogger.com/profile/08618980369195930324noreply@blogger.com0tag:blogger.com,1999:blog-6779529014456497914.post-47551021350185076482011-08-29T04:41:00.000-07:002011-08-29T02:40:41.486-07:00Alfresco - Combinando WebScripts con Acciones (parte 2)<script src="http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js" type="'text/javascript'">
</script>
<script src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushXml.js" type="'text/javascript'">
</script>
<script type="'text/javascript'">
</script>
Ya tenemos creado el webscript, el siguiente paso será crear la acción que lo ejecutará. Además, vamos a necesitar una pantalla de diálogo donde se mostrarán los documentos asociados.<br />
<br />
Para empezar modificaremos el fichero <b>web-client-config-custom.xml: </b><br />
<br />
Primero mostramos las asociaciones en las propiedades del documento. <br />
<br />
<pre class="xml" name="code"> <config condition="custom:documento" evaluator="node-type">
<property-sheet>
<separator component-generator="HeaderSeparatorGenerator" display-label="Documentos Asociados" name="separador">
<show-association name="custom:docsAsociados">
</show-association></separator></property-sheet>
</config>
<config condition="Content Wizards" evaluator="string-compare">
<content-types>
<type name="custom:documento">
</type></content-types>
</config>
<config condition="Action Wizards" evaluator="string-compare">
<specialise-types>
<type name="custom:documento">
</type></specialise-types>
</config>
</pre>
<br />
Definimos la acción:<br />
<br />
<pre class="xml" name="code"> <config>
<actions>
<action id="ver_documentos_asociados">
<label>Ver Docs asociados</label>
<evaluator>es.pruebas.evaluator.DocumentosAsociadosEvaluator</evaluator>
<img />/images/icons/search.gif
<action-listener>#{VerDocsAsociadosDialog.setupAction}<action-listener>
<action>dialog:verDocsAsociadosDialog</action>
<params>
<param name="webscript-url" />
/sample/docsAsociados
<param name="title" />
Mostrar documentos asociados
<param name="nodeRef" />
#{actionContext.nodeRef}
</params>
</action-listener></action-listener></action>
<action-group id="document_browse_menu">
<action idref="ver_documentos_asociados">
</action></action-group>
<action-group id="document_browse">
<action idref="ver_documentos_asociados">
</action></action-group>
<action-group id="doc_details_actions">
<action idref="ver_documentos_asociados">
</action></action-group>
</actions>
</config>
</pre>
<br />
las funciones de las distintas etiquetas son:<br />
<br />
<span style="color: #6aa84f;"><evaluator></span><span style="color: #38761d;"> </span>define una clase Evaluator que controla cuando mostrar la acción<br />
<span style="color: #6aa84f;"><image></span> icono que se mostrará para la acción<br />
<span style="color: #6aa84f;"><span style="color: #38761d;"><action-listener>, <action></span> </span>definimos que es lo que se ejecutará<br />
<span style="color: #6aa84f;"><params> </span>parámetros que necesitamos en nuestra acción (en nuestro caso la clase diálogo)<br />
<br />
Definimos el diálogo:<br />
<br />
<pre class="xml" name="code"> <config>
<dialogs>
<dialog icon="/images/icons/search_results_large.gif" managed-bean="VerDocsAsociadosDialog" name="verDocsAsociadosDialog" page="/jsp/extension/verDocsAsociados.jsp">
</dialog>
</dialogs>
</config>
</pre>
<br />
<br />
Y por último, registramos el diálogo en <b>alfresco\WEB-INF\faces-config-custom.xml</b><br />
<br />
<pre class="xml" name="code"> <faces-config>
<managed-bean>
<managed-bean-name>VerDocsAsociadosDialog</managed-bean-name>
<managed-bean-class>es.pruebas.dialogs.VerDocsAsociadosDialog</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
</faces-config>
</pre>
<br />
<br />
Las dos clases que hemos utilizado son:<br />
<br />
<b>VerDocsAsociadosDialog.java</b><br />
<br />
<pre class="java" name="code"> public class VerDocsAsociadosDialog extends BaseDialogBean {
/**
*
*/
private static final long serialVersionUID = -653745991045332155L;
private String url;
private String title;
private String webscriptUrl;
private static Log log = LogFactory.getLog(VerDocsAsociadosDialog.class);
@Override
protected String finishImpl(FacesContext arg0, String arg1) throws Throwable {
throw new UnsupportedOperationException("Not supported yet.");
}
public void setupAction(ActionEvent event) {
UIActionLink link = (UIActionLink) event.getComponent();
Map<string, string=""> params = link.getParameterMap();
NodeRef nodo = new NodeRef(params.get("nodeRef"));
String url2 = params.get("webscript-url");
String title2 = params.get("title");
if (!"".equals(url2)) {
this.url = url2 + "?q="+ nodo.toString();
this.title = title2;
}
}
@Override
public String getContainerTitle(){
return this.title;
}
@Override
public String getCancelButtonLabel(){
return "Cerrar";
}
@Override
public String cancel() {
return getDefaultCancelOutcome();
}
public String getWebscriptUrl() {
return "/wcservice" + url;
}
}
</string,></pre>
<span style="color: #6aa84f; font-size: x-small;"> </span><b>DocumentosAsociadosEvaluator.java</b><br />
<br />
<pre class="java" name="code"> public class DocumentosAsociadosEvaluator implements ActionEvaluator{
private static Log log = LogFactory.getLog(DocumentosAsociadosEvaluator.class);
public static final QName ASOCIACION_DOC = QName.createQName("custom.model", "docsAsociados");
public boolean evaluate(Node node) {
NodeRef ref = new NodeRef(Repository.getStoreRef(), node.getId());
FacesContext context = FacesContext.getCurrentInstance();
NodeService nodeSvc = Repository.getServiceRegistry(context).getNodeService();
boolean result = false;
List asocs = (List)node.getAssociations().get(ASOCIACION_DOC);
if(asocs != null && asocs.size() > 0) {
return true;
}
return result;
}
public boolean evaluate(Object arg0) {
throw new UnsupportedOperationException("Not supported yet.");
}
}
</pre>
<span style="color: #6aa84f; font-size: x-small;"><br /></span><br />
y la jsp que mostrará los resultados <b>verDocsAsociados.jsp</b><br />
<div style="color: #38761d;">
<br /></div>
<pre class="html" name="code"> <%@ taglib uri="/WEB-INF/repo.tld" prefix="r" >
<script type="text/javascript">
window.onload = hideFinish;
function hideFinish() {
var finishButton = document.getElementById("dialog:finish-button");
finishButton.style.display = "none";
}
</script>
<r:webscript scripturl="#{DialogManager.bean.webscriptUrl}"></r:webscript>
</pre>
Patriciahttp://www.blogger.com/profile/08618980369195930324noreply@blogger.com0tag:blogger.com,1999:blog-6779529014456497914.post-86643388042185643412011-08-29T04:33:00.000-07:002011-08-29T02:40:21.172-07:00Alfresco - Combinando WebScripts con Acciones (parte 1)Hola de nuevo!
<br />Tenia un poco olvidado el blog y he decidido retomarlo con este tutorial. La idea es combinar diferentes aspectos de Alfresco, como son las acciones, dialogos, webscripts, evaluadores...
<br />Vamos a empezar creando un webscript muy sencillo, su función será mostrarnos los documentos que tiene asociados un documento en concreto. Para ello, primero debemos definir nuestro <b>customModel.xml:</b>
<pre class="xml" name="code">
<model name="custom:customModel" xmlns="http://www.alfresco.org/model/dictionary/1.0">
<description>Custom Model</description>
<author></author>
<version>1.0</version>
<imports>
<import prefix="d" uri="http://www.alfresco.org/model/dictionary/1.0">
<import prefix="cm" uri="http://www.alfresco.org/model/content/1.0">
</import></import>
</imports>
<namespaces>
<namespace prefix="custom" uri="custom.model"></namespace>
</namespaces>
<types>
<type name="custom:documento">
<title>Documento</title>
<parent>cm:content</parent>
<associations>
<association name="custom:docsAsociados">
<title>Documentos Asociados</title>
<source>
<mandatory>false</mandatory>
<many>true</many>
</source>
<target>
<class>cm:content</class>
<mandatory>false</mandatory>
<many>true</many>
</target>
</association>
</associations>
</type>
</types>
</model>
</pre><b>
</b>
Un webscript se puede componer de varios ficheros:
<ul><li>Documento descriptivo</li><li>Script de control (opcional)</li><li>Una o varias plantillas</li><li>Documento de configuración (opcional)</li><li>Fichero de propiedades (opcional)</li></ul>
<br />En nuestro caso, crearemos tres ficheros en la ruta:
<pre>/Company Home/Data Dictionary/Web Scripts/org/alfresco/sample</pre>
<br /><b>1.</b> <b>docsAsociados.get.desc.xml (documento descriptivo):</b>
<pre class="xml" name="code">
<webscript>
<shortname>Documentos Asociados</shortname>
<url>/sample/docsAsociados?q={searchTerm}</url>
<format default="html">extension</format>
<authentication>user</authentication>
<transaction>required</transaction>
</webscript>
</pre>
<b>2. docsAsociados.get.html.ftl (plantilla de salida)</b>
<div style="color: #6aa84f;">
</div><div style="color: #38761d;"><pre class="html" name="code">
<html>
<body>
<br>
<table>
<tr><td colspan="2"><b><u>Documentos Asociados</u></b></td></tr>
<tr></tr>
<tr></tr>
<tr style='background-color: #C6D8EB'>
<td></td>
<td align="center"><b>Nombre<b></td>
</tr>
<tr>
<#list resultset as node>
<td align="center"><img src="${url.context}${node.icon16}"/></td>
<td align="center"><a href="/alfresco${node.url}" target="_blank">${node.name}</a></td>
<td></td>
<#if node.assocs["custom:docsAsociados"]?exists>
<#list node.assocs["custom:docsAsociados"] as doc>
<td><a href="/alfresco${doc.url}" target="_blank">Documento</a></td>
<td></td>
<td align="center">${doc.name}</td>
<td></td>
</#list>
</#if>
<tr><td colspan="6">--------------------------------------------------------------------------------------</td></tr>
</#list>
</tr>
</table>
</body>
</html>
</pre></div>
<b>3. docsAsociados.get.js (script de control)</b>
<div style="color: #6aa84f;">
</div><pre class="js" name="code">
if (args.q == undefined || args.q.length == 0){
status.code = 400;
status.message = "Search term has not been provided.";
status.redirect = true;
} else{
var node = search.findNode(args.q);
var asociaciones = node.assocs["custom:docsAsociados"];
model.resultset = asociaciones;
}</pre>
Para información más completa y detallada acerca de los webscripts, <a href="http://wiki.alfresco.com/wiki/Web_Scripts#How_Do_I_Create_a_Web_Script.3F">aquí </a>encontrareis todo lo necesario.Patriciahttp://www.blogger.com/profile/08618980369195930324noreply@blogger.com1tag:blogger.com,1999:blog-6779529014456497914.post-3763625993536699432011-03-30T01:29:00.000-07:002011-08-29T02:42:25.987-07:00Alfresco - Creando un workflow desde cero (parte 3)<div style="font-family: Georgia,"Times New Roman",serif;">En esta tercera y ultima parte explicaré como adaptar nuestro proceso para introducirlo en Alfresco.</div><div style="font-family: Georgia,"Times New Roman",serif;"><br />
</div><div style="font-family: Georgia,"Times New Roman",serif;">Para ello necesitaremos los siguientes ficheros:</div><div style="font-family: Georgia,"Times New Roman",serif;"><br />
</div><div style="font-family: Georgia,"Times New Roman",serif;"><span style="font-size: 11pt; line-height: 115%;"><b>../</b></span><span style="font-size: 11pt; line-height: 115%;"><b>tomcat/shared/classes/alfresco/extension/workflows</b></span></div><div style="font-family: Georgia,"Times New Roman",serif;"><br />
</div><div style="font-family: Georgia,"Times New Roman",serif;"><span style="font-size: xx-small;">- processdefinition.xml </span></div><div style="font-family: Georgia,"Times New Roman",serif;"><br />
</div><div style="font-family: Georgia,"Times New Roman",serif;"><span style="font-size: 11pt; line-height: 115%;"><b>../</b></span><span style="font-size: 11pt; line-height: 115%;"><b>tomcat/shared/classes/alfresco/extension</b></span> </div><div style="font-family: Georgia,"Times New Roman",serif;"><br />
</div><div style="font-family: Georgia,"Times New Roman",serif;"><span style="font-size: xx-small;">- </span><span style="font-size: xx-small; line-height: 115%;">customWorkflowModel.xml </span></div><div style="font-family: Georgia,"Times New Roman",serif;"><span style="font-size: xx-small; line-height: 115%;">- </span><span style="font-size: xx-small;">custom-workflow-context.xml</span></div><div style="font-family: Georgia,"Times New Roman",serif;"><span style="font-size: xx-small;">- </span><span style="font-size: xx-small; line-height: 115%;">custom-workflow-messages.properties+</span></div><div style="font-family: Georgia,"Times New Roman",serif;"><span style="font-size: xx-small; line-height: 115%;"> </span></div><div style="font-family: Georgia,"Times New Roman",serif;"><span style="font-size: 11pt; line-height: 115%;">También podemos echar un vistazo a varios ejemplos en ../alfresco/WEB-INF/classes/alfresco/workflow</span><div><br />
</div><div><span style="font-size: 11pt; line-height: 115%;">El modelo de contenido que he definido es el siguiente:</span></div><div><span style="font-size: 11pt; line-height: 115%;"> </span></div><div><span style="font-size: 11pt; line-height: 115%;"> <pre name="code" class="xml"><?xml version="1.0" encoding="UTF-8"?>
<model name="mwf:customworkflowmodel" xmlns="http://www.alfresco.org/model/dictionary/1.0">
<imports>
<import uri="http://www.alfresco.org/model/dictionary/1.0" prefix="d"/>
<import uri="http://www.alfresco.org/model/bpm/1.0" prefix="bpm"/>
<import uri="http://www.alfresco.org/model/workflow/1.0" prefix="wf"/>
</imports>
<namespaces>
<namespace uri="extension.misWorkflows" prefix="mwf"/>
</namespaces>
<types>
<type name="mwf:submitApproveContent">
<parent>bpm:startTask</parent>
<mandatory-aspects>
<aspect>bpm:assignee</aspect>
</mandatory-aspects>
</type>
<type name="mwf:reviewContent">
<parent>bpm:workflowTask</parent>
<overrides>
<property name="bpm:packageItemActionGroup">
<default>edit_package_item_actions</default>
</property>
</overrides>
<mandatory-aspects>
<aspect>mwf:motivos</aspect>
</mandatory-aspects>
</type>
<type name="mwf:approvedContent">
<parent>bpm:workflowTask</parent>
<mandatory-aspects>
<aspect>bpm:assignee</aspect>
</mandatory-aspects>
</type>
<type name="mwf:rejectedContent">
<parent>bpm:workflowTask</parent>
<mandatory-aspects>
<aspect>bpm:assignee</aspect>
<aspect>mwf:motivos</aspect>
</mandatory-aspects>
</type>
</types>
<aspects>
<aspect name="mwf:motivos">
<properties>
<property name="mwf:motivoRechazo">
<title>Motivo Rechazo</title>
<type>d:text</type>
<mandatory>false</mandatory>
</property>
</properties>
</aspect>
</aspects>
</model>
</pre></span></div><div><span style="font-size: 11pt; line-height: 115%;"> </span></div><div><div><span style="font-size: 11pt; line-height: 115%;">Hemos definido un tipo para cada uno de los <u>task-node</u> de nuestro workflow que heredan las propiedades de <b>bpm:</b></span><span style="font-size: 11pt; line-height: 115%;"><b>workflowTask</b>.</span></div><div><span style="font-size: 11pt; line-height: 115%;">El estado inicial<b> </b></span><b><span style="font-size: 11pt; line-height: 115%;">mwf:submitApproveContent </span></b><span style="font-size: 11pt; line-height: 115%;">ser</span><span style="font-size: 11pt; line-height: 115%;">á</span><b><span style="font-size: 11pt; line-height: 115%;"> </span></b><span style="font-size: 11pt; line-height: 115%;">de tipo <b>bpm:startTask</b> que llevará las propiedades descripción, prioridad y fecha de vencimiento. </span></div><div><span style="font-size: 11pt; line-height: 115%;">Además, hemos creado un aspecto que tendrá como propiedad un motivo de rechazo.</span></div><div><span style="font-size: 11pt; line-height: 115%;"><br />
</span></div><div><b>custom-workflow-context.xml</b></div><span style="font-size: 11pt; line-height: 115%;"> </span></div><span style="font-size: xx-small; line-height: 115%;"> </span></div><div style="font-family: Georgia,"Times New Roman",serif;"><span style="font-size: small;"><span style="line-height: 115%;"> <pre name="code" class="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="myworkflows.workflowBootstrap" parent="workflowDeployer">
<property name="workflowDefinitions">
<list>
<props>
<prop key="engineId">jbpm</prop>
<prop key="location">alfresco/extension/workflows/processdefinition.xml</prop>
<prop key="mimetype">text/xml</prop>
<prop key="redeploy">true</prop>
</props>
</list>
</property>
<property name="models">
<list>
<value>alfresco/extension/customWorkflowModel.xml</value>
</list>
</property>
<property name="labels">
<list>
<value>alfresco/extension/custom-workflow-messages</value>
</list>
</property>
</bean>
</beans>
</pre></span></span></div><div style="font-family: Georgia,"Times New Roman",serif;"><span style="font-size: xx-small; line-height: 115%;"><span style="font-size: small;"> </span></span></div><div style="font-family: Georgia,"Times New Roman",serif;"><b><span style="font-size: 11pt; line-height: 115%;">custom-workflow-messages.properties</span></b></div><div style="font-family: Georgia,"Times New Roman",serif;"><b><span style="font-size: 11pt; line-height: 115%;"> </span></b></div><div style="font-family: Georgia,"Times New Roman",serif;"><span style="font-size: 11pt; line-height: 115%;"> <pre name="code" class="java">#Workflow
mwf_approveContent.workflow.title=Aprobar Contenido
mwf_approveContent.workflow.description=Proceso para aprobar contenido
#Review & Approve Task Definitions
mwf_customworkflowmodel.type.mwf_submitApproveContent.title=Iniciar aprobaci\u00f3n de contenido
mwf_customworkflowmodel.type.mwf_submitApproveContent.description=Enviar documentos para su revisi\u00f3n y aprobaci\u00f3n
mwf_customworkflowmodel.type.mwf_reviewContent.title=Revisar contenido
mwf_customworkflowmodel.type.mwf_reviewContent.description=Revisar documentos para aprobarlos o rechazarlos
mwf_customworkflowmodel.type.mwf_approvedContent.title=Contenido Aprobado
mwf_customworkflowmodel.type.mwf_approvedContent.description=Contenido Aprobado
mwf_customworkflowmodel.type.mwf_rejectedContent.title=Contenido Rechazado
mwf_customworkflowmodel.type.mwf_rejectedContent.description=Contenido Rechazado
</pre></span></div><div style="font-family: Georgia,"Times New Roman",serif;"><b><span style="font-size: 11pt; line-height: 115%;"> </span></b></div><div style="font-family: Georgia,"Times New Roman",serif;"><span style="font-size: 11pt; line-height: 115%;"> Y finalmente, hemos modificado <b>processdefinition.xml </b></span></div><div style="font-family: Georgia,"Times New Roman",serif;"><span style="font-size: 11pt; line-height: 115%;"><b> </b></span></div><div style="font-family: Georgia,"Times New Roman",serif;"><span style="font-size: 11pt; line-height: 115%;"> <pre name="code" class="xml"><?xml version="1.0" encoding="UTF-8"?>
<process-definition xmlns="urn:jbpm.org:jpdl-3.2" name="mwf:approveContent">
<swimlane name="initiator"/>
<start-state name="start">
<task name="mwf:submitApproveContent" swimlane="initiator"/>
<transition to="review"></transition>
</start-state>
<swimlane name="assignee">
<assignment class="org.alfresco.repo.workflow.jbpm.AlfrescoAssignment">
<actor>#{bpm_assignee}</actor>
</assignment>
</swimlane>
<task-node name="review">
<task name="mwf:reviewContent" swimlane="assignee"/>
<transition to="reject" name="reject">
<action class="org.alfresco.repo.workflow.jbpm.AlfrescoJavaScript">
<script>
var mail = actions.create("mail");
mail.parameters.to = initiator.properties.email;
mail.parameters.subject = "xxx ha rechazado el documento " + bpm_workflowDescription;
mail.parameters.from = "admin@alfresco.org";
mail.parameters.text = "It's done";
mail.execute(bpm_package);
</script>
</action>
</transition>
<transition to="approve" name="approve"/>
</task-node>
<task-node name="approve">
<task name="mwf:approvedContent" swimlane="initiator"/>
<transition to="end">
</transition>
</task-node>
<task-node name="reject">
<task name="mwf:rejectedContent" swimlane="initiator"/>
<transition to="end"/>
</task-node>
<end-state name="end"></end-state>
</process-definition>
</pre></span></div><div style="font-family: Georgia,"Times New Roman",serif;"><span style="font-size: 11pt; line-height: 115%;"><br />
</span></div><div style="font-family: Georgia,"Times New Roman",serif;"><span style="font-size: 11pt; line-height: 115%;"></span><span style="font-size: 11pt; line-height: 115%;">Los cambios realizados en la definición son:<br />
<br />
Se han modificado los nombres de las tareas añadiendole la extensión de nuestro modelo de contenido (<b>mwf</b>) .<br />
<br />
Se han añadido los elementos <b>swimlane </b>que se utilizan para asignar las tareas a un usuario o grupo de usuarios de Alfresco.<br />
<br />
El rol <b>initiatior </b>será el encargado de iniciar y finalizar el flujo, siempre debe aparecer. <br />
<br />
El rol <b>assignee </b>será el usuario encargado de realizar la tarea de aprobar/rechazar contenido. En mi caso es un único usuario, tal y como viene indicado por la etiqueta <b><actor></b>, pero también puede ser un grupo de usuarios, que podriamos definirlo utilizando la etiqueta <b><pooledactors>.</b><br />
<br />
También se ha añadido un script sencillo que enviará un email a la persona que inició el flujo en caso de que el usuario haya rechazado el contenido.<br />
<br />
Para que las propiedades se visualicen en nuestro web-client, tendremos que modificar el fichero <b>web-client-config-custom.xml</b> y añadir lo siguiente:</span><b><span style="font-size: 11pt; line-height: 115%;"></span></b></div><div style="font-family: Georgia,"Times New Roman",serif;"><b><span style="font-size: 11pt; line-height: 115%;"><br />
</span></b></div><div style="font-family: Georgia,"Times New Roman",serif;"><span style="font-size: 11pt; line-height: 115%;"> <pre name="code" class="xml"><config evaluator="node-type" condition="mwf:submitApproveContent" replace="true">
<property-sheet>
...
</property-sheet>
</config>
<config evaluator="node-type" condition="mwf:reviewContent" replace="true">
<property-sheet>
....
</property-sheet>
</config>
<config evaluator="node-type" condition="mwf:rejectedContent" replace="true">
<property-sheet>
...
</property-sheet>
</config>
<config evaluator="node-type" condition="mwf:approvedContent" replace="true">
<property-sheet>
...
</property-sheet>
</config>
</pre></span></div><div style="font-family: Georgia,"Times New Roman",serif;"><span style="font-size: 11pt; line-height: 115%;"><br />
</span></div><div style="font-family: Georgia,"Times New Roman",serif;"><span style="font-size: 11pt; line-height: 115%;">Una vez tengamos todo, reiniciamos el servidor de Alfresco y ya tendremos nuestro workflow disponible!!!<br />
<br />
</span></div>Patriciahttp://www.blogger.com/profile/08618980369195930324noreply@blogger.com18tag:blogger.com,1999:blog-6779529014456497914.post-238621886953275772011-03-30T01:15:00.000-07:002011-08-29T02:45:05.991-07:00Alfresco - Creando un workflow desde cero (parte 2)Vamos a empezar creando un workflow sencillo en Eclipse que consistirá en:
- Usuario A solicita la revisión de un documento a Usuario B.
- Usuario B aprueba/rechaza el documento.
- Usuario A es informado de la tarea realizada.
Debemos copiar la libreria<b> activation.jar </b>en el directorio lib de la instalación de jBPM y a continuación crearemos un proyecto <b>"Process Project":</b>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxNYtzsmErWrsYpZa95suK7D-9CS3kM_FZogA5IP4XLN1sH9C0p8GcdxvfQbCaZpekETx_CIEKt0tSwdy8oT6SobCZhdtcjUssuxhiPZb59ZDRexGRckIrGcd1G3cosXTgHqfDlM6D-3c/s1600/work1.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="298" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxNYtzsmErWrsYpZa95suK7D-9CS3kM_FZogA5IP4XLN1sH9C0p8GcdxvfQbCaZpekETx_CIEKt0tSwdy8oT6SobCZhdtcjUssuxhiPZb59ZDRexGRckIrGcd1G3cosXTgHqfDlM6D-3c/s400/work1.JPG" width="400" /></a></div>
Y dentro de nuestro proyecto, un <b>"Process Definition"</b>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj51jK9zX2ZgQIggNT7H94Vprk-4ikbEcAMBxJxw-D8BRhwlH1Mtc9zmd3IF24MX_9bYSh6-aDUzKqdk9_G9SHliBzxjfqId1HXe4qNSNFxdGygHBc-jg_MJRreYu5mBFijq8BFlk5NCRk/s1600/work2.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="300" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj51jK9zX2ZgQIggNT7H94Vprk-4ikbEcAMBxJxw-D8BRhwlH1Mtc9zmd3IF24MX_9bYSh6-aDUzKqdk9_G9SHliBzxjfqId1HXe4qNSNFxdGygHBc-jg_MJRreYu5mBFijq8BFlk5NCRk/s400/work2.JPG" width="400" /></a></div>
El diagrama podriamos dibujarlo de la siguiente manera:
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgL25TtX90yTsVzQNDEZLY2hvbRTnWBxAZ6RTMGuOntanae4PJTjcSfV0ceat8YWQjA2dH0amkvcmBgGoraUvToZrPZMontgS8jB_yfQzR6yaj6NBaszg84Y2DAkioZ6Hzh_xSve__rTQw/s1600/workflow.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="322" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgL25TtX90yTsVzQNDEZLY2hvbRTnWBxAZ6RTMGuOntanae4PJTjcSfV0ceat8YWQjA2dH0amkvcmBgGoraUvToZrPZMontgS8jB_yfQzR6yaj6NBaszg84Y2DAkioZ6Hzh_xSve__rTQw/s400/workflow.JPG" width="400" /></a></div>
El fichero <b>processdefinition.xml</b> equivalente sería:
<br />
<pre class="xml" name="code"><process-definition name="approveContent" xmlns="urn:jbpm.org:jpdl-3.2">
<start-state name="start">
<transition to="review"></transition>
</start-state>
<task-node name="review">
<transition name="approve" to="approved"></transition>
<transition name="reject" to="rejected"></transition>
</task-node>
<task-node name="approved">
<transition to="end"></transition>
</task-node>
<task-node name="rejected">
<transition to="end"></transition>
</task-node>
<end-state name="end"></end-state>
</process-definition>
</pre>
<span style="color: #6aa84f;"><span style="color: black;">En un workflow siempre debemos tener los estados que definen el inicio <b>(start-state)</b> y fin <b>(end-state)</b> de nuestro proceso.</span> </span>Patriciahttp://www.blogger.com/profile/08618980369195930324noreply@blogger.com1tag:blogger.com,1999:blog-6779529014456497914.post-48186821322421995672011-03-30T01:10:00.000-07:002011-08-29T02:43:31.487-07:00Alfresco - Creando un workflow desde cero (parte 1)<div style="font-family: Georgia,"Times New Roman",serif;">Hola!</div><div style="font-family: Georgia,"Times New Roman",serif;"><br />
</div><div style="font-family: Georgia,"Times New Roman",serif;">He empezado esta semana a trabajar con workflows y me he llevado una sorpresa... parecen "divertidos" y al menos es diferente a lo que he estado haciendo hasta ahora!</div><div style="font-family: Georgia,"Times New Roman",serif;"><br />
</div><div style="font-family: Georgia,"Times New Roman",serif;">He tenido que recopilar información de varios sitios distintos como la wikipedia o los foros... y finalmente he entendido su funcionamiento.</div><div style="font-family: Georgia,"Times New Roman",serif;"><br />
</div><div style="font-family: Georgia,"Times New Roman",serif;">Me ha parecido buena idea crear este tutorial, desde la instalación de jbpm hasta la integración en Alfresco de un proceso sencillo. Creo que resultará util a gente que no haya hecho nunca un workflow en Alfresco...</div><div style="font-family: Georgia,"Times New Roman",serif;"><br />
Voy a dedicar esta primera parte del tutorial a la <b>instalación </b>y <b>configuración </b>de jBPM.<br />
<br />
</div><div style="font-family: Georgia,"Times New Roman",serif;">He decidido instalar la versión que recomiendan en la <a href="http://wiki.alfresco.com/wiki/WorkflowAdministration#Installing_JBoss_jBPM_Process_Designer">wiki</a>, la <b>jbpm-jpdl-3.2.6.SP1</b> (a lo mejor hay alguna más nueva pero a mi con esta me funciona bien).</div><div style="font-family: Georgia,"Times New Roman",serif;"><br />
</div><div style="font-family: Georgia,"Times New Roman",serif;">Para instalar ejecutamos: </div><div style="font-family: Georgia,"Times New Roman",serif;"><br />
</div><div style="color: #38761d; font-family: Georgia,"Times New Roman",serif;"><b><span style="font-size: 11pt;">java –jar jbpm-installer-3.2.6.jar </span></b></div><div style="font-family: Georgia,"Times New Roman",serif;"><br />
</div><div style="font-family: Georgia,"Times New Roman",serif;"><span style="font-size: 11pt;">(Si durante la instalación nos pide directorio de instalación de JBOSS y no tenemos, introducimos C:/tmp)</span></div><div style="font-family: Georgia,"Times New Roman",serif;"><br />
</div><div style="font-family: Georgia,"Times New Roman",serif;"><span style="font-size: 11pt;">Una vez hecho esto, podemos instalar<b> </b></span><span style="font-size: 11pt;"><b>jBPM process designer</b> en nuestro Eclipse (en mi caso Helios).</span></div><div style="font-family: Georgia,"Times New Roman",serif;"><span style="font-size: 11pt;"><br />
</span></div><div class="separator" style="clear: both; font-family: Georgia,"Times New Roman",serif; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1lcipNsBbxWVZoQCfQhuaH0Z9tx9mfaFDwvn2oF_sb871TYoZj-xywPUNsLWZXNR-_5q4rSUC2Tu3MkwVjw37PiYT1IKkhuz_FiH9tfI-p6apO9hiPBwPnmlX2xfQ6OrT-rsUInyyOYU/s1600/instal1.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="298" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1lcipNsBbxWVZoQCfQhuaH0Z9tx9mfaFDwvn2oF_sb871TYoZj-xywPUNsLWZXNR-_5q4rSUC2Tu3MkwVjw37PiYT1IKkhuz_FiH9tfI-p6apO9hiPBwPnmlX2xfQ6OrT-rsUInyyOYU/s400/instal1.JPG" width="400" /></a></div><div style="font-family: Georgia,"Times New Roman",serif;"><span style="font-size: 11pt;"><br />
</span></div><div style="font-family: Georgia,"Times New Roman",serif;"><span style="font-size: 11pt;"> </span></div><div style="font-family: Georgia,"Times New Roman",serif;"></div><div style="font-family: Georgia,"Times New Roman",serif;"></div><div style="font-family: Georgia,"Times New Roman",serif;"><br />
</div><div style="font-family: Georgia,"Times New Roman",serif;">En la siguiente ventana añadiremos un archivo local, seleccionaremos el fichero<b> jbpm-jpdl-designer-site.zip </b>que se encuentra en la carpeta <b>designer </b>de la instalación de jbpm.</div><div style="font-family: Georgia,"Times New Roman",serif;"><br />
</div><div class="separator" style="clear: both; font-family: Georgia,"Times New Roman",serif; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg40fDyeXLHV4eIQdOHQ5QRM1-e6Dt0tVPSW7P1rbBeXxrRdfz6SW10cangLASCiLck37Gxw3iEXZDHtkTBL5T2Us9eKiqpIk20HjzqKjVP9JK8nIE9qy26ysrkH2BE1YxzXL4uM2N7QGQ/s1600/instal2.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="300" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg40fDyeXLHV4eIQdOHQ5QRM1-e6Dt0tVPSW7P1rbBeXxrRdfz6SW10cangLASCiLck37Gxw3iEXZDHtkTBL5T2Us9eKiqpIk20HjzqKjVP9JK8nIE9qy26ysrkH2BE1YxzXL4uM2N7QGQ/s400/instal2.JPG" width="400" /></a></div><div style="font-family: Georgia,"Times New Roman",serif;"><br />
</div><div style="font-family: Georgia,"Times New Roman",serif;"><br />
</div><div style="font-family: Georgia,"Times New Roman",serif;"></div><div style="font-family: Georgia,"Times New Roman",serif;"><br />
</div><div style="font-family: Georgia,"Times New Roman",serif;">En el menú <b>window/preferences</b>, en la sección <b>JBoss jBPM/</b><b>Runtime Location</b>, añadiremos la ruta de la instalación de jbpm.</div><div class="separator" style="clear: both; font-family: Georgia,"Times New Roman",serif; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqOSl1Bnq_Y_hnqfG85x-NqM-7cptACMDL2NvvZQ6I0Qs5P8aSASLa0QxUmV3nJOEdwSz7IAJeTybjzOpOURdqWhkNkUgWcdkiuKiEPqgpDxvd6wtIE8vs7Yv98OCEouVgo_AhEjU2B5Q/s1600/work3.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><br />
</a></div><div class="separator" style="clear: both; font-family: Georgia,"Times New Roman",serif; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_CxUskPAxL0jFfOFiRC607QHR_Sp7eUcoCpHx4L0_8fNlo5-bnWSbSXUoOf8YRYIZGRBTsQxvaM59xahss2ixu70FohhToYiffEjLg1DCWqSS5Qcq-jCRoYZz_iv1EnZKIIK0wxll6a4/s1600/instal3.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="298" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_CxUskPAxL0jFfOFiRC607QHR_Sp7eUcoCpHx4L0_8fNlo5-bnWSbSXUoOf8YRYIZGRBTsQxvaM59xahss2ixu70FohhToYiffEjLg1DCWqSS5Qcq-jCRoYZz_iv1EnZKIIK0wxll6a4/s400/instal3.JPG" width="400" /></a></div><div style="font-family: Georgia,"Times New Roman",serif;"> </div><div style="font-family: Georgia,"Times New Roman",serif;"><br />
</div><div style="font-family: Georgia,"Times New Roman",serif;"><br />
</div><div style="font-family: Georgia,"Times New Roman",serif;">Para desplegar los procesos en Alfresco podremos hacerlo bien de forma manual, o bien desde el Eclipse, configurando los siguientes parámetros en la seccion "<b>Server Deployment</b>".</div><div style="font-family: Georgia,"Times New Roman",serif;"><br />
</div><div class="separator" style="clear: both; font-family: Georgia,"Times New Roman",serif; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEib-bGWlPwblhf1radNP3TTzZAqC-Wm-f-HuX_bSCCg_Tu0Kqhs15u9gEuN1Ip_pV7-pLvTz1APCqpjsE5N8_TQRHEdeillMS9HtYY1818K6Np5G7a0cGB-l2Ri6yAGBI36JLqcZkp3IWU/s1600/deploy.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="346" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEib-bGWlPwblhf1radNP3TTzZAqC-Wm-f-HuX_bSCCg_Tu0Kqhs15u9gEuN1Ip_pV7-pLvTz1APCqpjsE5N8_TQRHEdeillMS9HtYY1818K6Np5G7a0cGB-l2Ri6yAGBI36JLqcZkp3IWU/s400/deploy.JPG" width="400" /></a></div><div style="font-family: Georgia,"Times New Roman",serif;"><br />
</div><div style="font-family: Georgia,"Times New Roman",serif;"><br />
</div><div style="font-family: Georgia,"Times New Roman",serif;"><br />
</div><div style="font-family: Georgia,"Times New Roman",serif;"><br />
</div><div style="font-family: Georgia,"Times New Roman",serif;"><br />
</div><div style="font-family: Georgia,"Times New Roman",serif;"><br />
</div><div style="font-family: Georgia,"Times New Roman",serif;"><br />
</div><div style="font-family: Georgia,"Times New Roman",serif;"><br />
</div><div style="font-family: Georgia,"Times New Roman",serif;"><br />
</div><div class="separator" style="clear: both; font-family: Georgia,"Times New Roman",serif; text-align: center;"></div>Patriciahttp://www.blogger.com/profile/08618980369195930324noreply@blogger.com0tag:blogger.com,1999:blog-6779529014456497914.post-40829265294458007032011-03-09T07:14:00.000-08:002011-03-09T07:19:20.231-08:00Alfresco WebServices - Manipulando contenido<div style="text-align: justify;">Cuando queramos hacer una apliación a medida en <b>Java </b>y trabajar con el repositorio de Alfresco, podremos usar, entre otras cosas, los <b>webservices</b>. Para ello, una de las librerias que necesitaremos es <b>alfresco-web-service-client.jar</b>, donde podemos encontrar los siguientes servicios:</div><br /><div style="color: rgb(56, 118, 29);font-family:Verdana,sans-serif;"><span style="font-size:x-small;"><b>AuthenticationService</b></span></div><div style="color: rgb(56, 118, 29);font-family:Verdana,sans-serif;"><span style="font-size:x-small;"><b>RepositoryService</b></span></div><div style="color: rgb(56, 118, 29);font-family:Verdana,sans-serif;"><span style="font-size:x-small;"><b>ContentService</b></span></div><div style="color: rgb(56, 118, 29);font-family:Verdana,sans-serif;"><span style="font-size:x-small;"><b>AuthoringService</b></span></div><div style="color: rgb(56, 118, 29);font-family:Verdana,sans-serif;"><span style="font-size:x-small;"><b>ClassificationService</b></span></div><div style="color: rgb(56, 118, 29);font-family:Verdana,sans-serif;"><span style="font-size:x-small;"><b>ActionService</b></span></div><div style="color: rgb(56, 118, 29);font-family:Verdana,sans-serif;"><span style="font-size:x-small;"><b>AccessControlService</b></span></div><div style="color: rgb(56, 118, 29);font-family:Verdana,sans-serif;"><span style="font-size:x-small;"><b>AdministrationService</b></span></div><span style=";font-family:Verdana,sans-serif;font-size:x-small;" ><b style="color: rgb(56, 118, 29);">DictionaryService</b></span><br /><br />Hoy me voy a centrar en la manipulación de contenido, veremos como crearlo, modificar propiedades, crear aspectos, crear asociaciones...<br /><br />Lo primero que tenemos que hacer es autenticarnos en Alfresco:<br /> <span style=";font-family:Verdana,sans-serif;font-size:x-small;" ><b><span style="color: rgb(56, 118, 29);"> </span></b></span><br /><span style=";font-family:Verdana,sans-serif;font-size:x-small;" ><b><span style="color: rgb(56, 118, 29);">AuthenticationUtils.startSession(USERNAME, PASSWORD);</span></b></span><br /><br /><div style="text-align: justify;">Aprovecho esto para explicar brevemente como crear un pdf con <a href="http://es.wikipedia.org/wiki/JasperReports">jasperreports</a> que posteriormente utilizaremos para crear nuestro nodo en el repositorio. Con la herramienta <a href="http://jasperforge.org/projects/ireport">iReport</a> podemos crear una plantilla para pdfs que nos generará dos ficheros, un *.jasper y otro *.jrxml, ambos ficheros deben estar dentro de nuestro proyecto. (prometo crear un post explicando esta herramienta más extensamente :-))</div> <br />Para generar el pdf podriamos implementar el siguiente método:<br /><br /><span style=";font-family:Verdana,sans-serif;font-size:x-small;" > </span><b><span style=";font-family:Verdana,sans-serif;font-size:x-small;" ><span style="color: rgb(56, 118, 29);">public static byte[] obtenerPdf(String rutaReport) {</span> <span style="color: rgb(56, 118, 29);"> byte[] pdf = null;</span> <span style="color: rgb(56, 118, 29);"> </span> <span style="color: rgb(56, 118, 29);"> try {</span> <span style="color: rgb(56, 118, 29);"> //en ruta report se encuentran los ficheros necesarios que hemos mencionado anteriormente</span> <span style="color: rgb(56, 118, 29);"> JasperReport jasperReport = (JasperReport) JRLoader.loadObject(new URL(rutaReport));</span> <span style="color: rgb(56, 118, 29);"> </span> <span style="color: rgb(56, 118, 29);"> //el método fillReport nos da la posibilidad de añadir parámetros pero en este caso no es necesario</span> <span style="color: rgb(56, 118, 29);"> JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, null);</span> <span style="color: rgb(56, 118, 29);"> ByteArrayOutputStream pdfOutput = new ByteArrayOutputStream();</span> <span style="color: rgb(56, 118, 29);"> JRPdfExporter exporter = new JRPdfExporter();</span> <span style="color: rgb(56, 118, 29);"> exporter.setParameter(JRPdfExporterParameter.METADATA_AUTHOR, "autor");</span> <span style="color: rgb(56, 118, 29);"> exporter.setParameter(JRPdfExporterParameter.METADATA_CREATOR, "creador"); </span> <span style="color: rgb(56, 118, 29);"> exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint); </span> <span style="color: rgb(56, 118, 29);"> exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, pdfOutput);</span> <span style="color: rgb(56, 118, 29);"> exporter.exportReport();</span> <span style="color: rgb(56, 118, 29);"> pdf = pdfOutput.toByteArray();</span> <span style="color: rgb(56, 118, 29);"> </span> <span style="color: rgb(56, 118, 29);"> } catch (MalformedURLException e) {</span> <span style="color: rgb(56, 118, 29);"> // TODO Auto-generated catch block</span> <span style="color: rgb(56, 118, 29);"> e.printStackTrace();</span> <span style="color: rgb(56, 118, 29);"> } catch (JRException e) {</span> <span style="color: rgb(56, 118, 29);"> // TODO Auto-generated catch block</span> <span style="color: rgb(56, 118, 29);"> e.printStackTrace();</span> <span style="color: rgb(56, 118, 29);"> } </span> <span style="color: rgb(56, 118, 29);"> return pdf; </span> <span style="color: rgb(56, 118, 29);"> }</span></span><span style="font-size:x-small;"><br /> </span></b><br /> <br />Comenzaremos ahora a crear nuestro contenido, para lo que necesitaremos los siguientes servicios:<br /> <br /><span style=";font-family:Verdana,sans-serif;font-size:x-small;" ><b style="color: rgb(56, 118, 29);">RepositoryServiceSoapBindingStub repositoryService = WebServiceFactory.getRepositoryService();<br />ContentServiceSoapBindingStub contentService = WebServiceFactory.getContentService();</b></span><br /><br />Primero tenemos que decidir donde lo vamos a guardar, podemos hacerlo bien en <b>companyHome</b>:<br /><br /><div style="color: rgb(56, 118, 29);font-family:Verdana,sans-serif;"><span style="font-size:x-small;"><b>Store storeRef = new Store(Constants.WORKSPACE_STORE, "SpacesStore"); </b></span></div><span style="font-size:x-small;"><b style="color: rgb(56, 118, 29); font-family: Verdana,sans-serif;">ParentReference companyHomeParent = new ParentReference(storeRef, null, "/app:company_home", Constants.ASSOC_CONTAINS, "nombrePdf"); </b></span><br /><br />o bien podemos indicarle el path de un espacio concreto donde lo queramos almacenar:<br /><br /><div style="color: rgb(56, 118, 29);font-family:Verdana,sans-serif;"><span style="font-size:x-small;"><b>String pathEncoded = "/app:company_home"+"/cm:"+ISO9075.encode("Mis documentos");</b></span></div><div style="color: rgb(56, 118, 29);font-family:Verdana,sans-serif;"><span style="font-size:x-small;"><b>Store storeRef = new Store(Constants.WORKSPACE_STORE, "SpacesStore"); </b></span></div><span style="font-size:x-small;"><b style="font-family:Verdana,sans-serif;"><span style="color: rgb(56, 118, 29);">ParentReference parentReference = new ParentReference(storeRef, null,pathEncoded, Constants.ASSOC_CONTAINS, "nombrePdf");</span></b></span><br /> <br /> <br />Le indicamos de que tipo será el contenido<br /><br /><span style=";font-family:Verdana,sans-serif;font-size:x-small;" ><b><span style="color: rgb(56, 118, 29);">ContentFormat contentFormat = new ContentFormat("application/pdf", "UTF-8");</span></b></span><br /> <br />modificamos sus propiedades, en este caso el nombre y la descripción:<br /><br /><span style=";font-family:Verdana,sans-serif;font-size:x-small;" ><b><span style="color: rgb(56, 118, 29);">NamedValue[] propiedades = new NamedValue[2];</span> <span style="color: rgb(56, 118, 29);">propiedades[0] = Utils.createNamedValue(Constants.PROP_NAME, "nombrePdf");</span> <span style="color: rgb(56, 118, 29);">propiedades[1] = Utils.createNamedValue(Constants.PROP_DESCRIPTION, "descripción del nuevo nodo");</span></b></span><br /> <br />y finalmente creamos el contenido:<br /><br /><span style=";font-family:Verdana,sans-serif;font-size:x-small;" ><b><span style="color: rgb(56, 118, 29);">CMLCreate create = new CMLCreate("1", parentReference, null, null, null, Constants.TYPE_CONTENT, propiedades); </span> <span style="color: rgb(56, 118, 29);">CML cml = new CML();</span> <span style="color: rgb(56, 118, 29);">cml.setCreate(new CMLCreate[]{create});</span> <span style="color: rgb(56, 118, 29);">UpdateResult[] result = repositoryService.update(cml);</span></b></span><br /> <br /><span style=";font-family:Verdana,sans-serif;font-size:x-small;" ><b><span style="color: rgb(56, 118, 29);">Reference newContentNode = result[0].getDestination();</span> <span style="color: rgb(56, 118, 29);">byte contentString[] = obtenerPdf(ruta);</span> <span style="color: rgb(56, 118, 29);">//Modificamos el contenido de nuestro nuevo nodo con el pdf que hemos obtenido</span> <span style="color: rgb(56, 118, 29);">contentService.write(newContentNode, Constants.PROP_CONTENT, contentString, contentFormat);</span></b></span><br /><br />Ya tenemos creado nuestro nodo (<b>newContentNode</b>) y ahora podemos actualizar sus propiedades<br /><br /><span style=";font-family:Verdana,sans-serif;font-size:x-small;" ><b><span style="color: rgb(56, 118, 29);">CMLUpdate update = new CMLUpdate();</span> <span style="color: rgb(56, 118, 29);">NamedValue[] props = new NamedValue[1]; </span> <span style="color: rgb(56, 118, 29);">props[0] = Utils.createNamedValue(Constants.PROP_DESCRIPTION, "esta es una modificación del nodo"); </span> <span style="color: rgb(56, 118, 29);">update.setProperty(props);</span> <span style="color: rgb(56, 118, 29);">update.setWhere(new Predicate(new Reference[]{newContentNode}, storeRef, null));</span></b></span><br /><span style=";font-family:Verdana,sans-serif;font-size:x-small;" ><b style="color: rgb(56, 118, 29);">cml.setUpdate(new CMLUpdate[]{update});</b></span><br /><span style=";font-family:Verdana,sans-serif;font-size:x-small;" ><b><span style="color: rgb(56, 118, 29);">repositoryService.update(cml);</span></b></span><br /><br />y añadirle aspectos y asociaciones<br /><br /><span style="font-size:x-small;"><b style="color: rgb(56, 118, 29); font-family: Verdana,sans-serif;">CMLAddAspect addAspect = new CMLAddAspect(); <br />addAspect.setAspect(Constants.ASPECT_VERSIONABLE);</b></span><br /><div style="color: rgb(56, 118, 29);font-family:Verdana,sans-serif;"><span style="font-size:x-small;"><b>addAspect.setWhere(new Predicate(new Reference[]{newContentNode}, storeRef, null));</b></span></div><span style="font-size:x-small;"><b style="color: rgb(56, 118, 29); font-family: Verdana,sans-serif;">cml.setAddAspect(new CMLAddAspect[]{addAspect});</b></span><br /> <br /><b><span style="color: rgb(56, 118, 29);font-family:Verdana,sans-serif;font-size:x-small;" >CMLCreateAssociation createAssoc = new CMLCreateAssociation();<br />createAssoc.setAssociation(Constants.ASSOC_CHILDREN);<br />createAssoc.setFrom(Predicate)//Nodo hijo que hayamos creado o que ya exista en Alfresco<br />createAssoc.setTo(new Predicate(new Reference[]{newContentNode}, storeRef, null))//Nodo padre</span></b><br /><span style=";font-family:Verdana,sans-serif;font-size:x-small;" ><b style="color: rgb(56, 118, 29);">cml.setCreateAssociation(new </b><b style="color: rgb(56, 118, 29);"><span style="color: rgb(56, 118, 29);font-family:Verdana,sans-serif;" >CMLCreateAssociation[]{</span></b><b style="color: rgb(56, 118, 29);"><span style="color: rgb(56, 118, 29);font-family:Verdana,sans-serif;" >createAssoc</span></b><b style="color: rgb(56, 118, 29);"><span style="color: rgb(56, 118, 29);font-family:Verdana,sans-serif;" >}</span>);</b></span><br /><br /><span style=";font-family:Verdana,sans-serif;font-size:x-small;" ><b><span style="color: rgb(56, 118, 29);">repositoryService.update(cml);</span></b></span> <br /><br />También podemos mover nuestro nodo a otro espacio<br /><br /><span style=";font-family:Verdana,sans-serif;font-size:x-small;" ><b style="color: rgb(56, 118, 29);">CMLMove move = new CMLMove(); </b></span><br /><span style=";font-family:Verdana,sans-serif;font-size:x-small;" ><b style="color: rgb(56, 118, 29);">//carpeta destino</b></span><br /><span style=";font-family:Verdana,sans-serif;font-size:x-small;" ><b style="color: rgb(56, 118, 29);">move.setTo(companyHomeParent); </b></span><br /><span style=";font-family:Verdana,sans-serif;font-size:x-small;" ><b style="color: rgb(56, 118, 29);">//nodo que vamos a mover</b></span><br /><span style=";font-family:Verdana,sans-serif;font-size:x-small;" ><b style="color: rgb(56, 118, 29);">move.setWhere(new Predicate(new Reference[]{newContentNode}, storeRef, null));</b></span><br /><span style=";font-family:Verdana,sans-serif;font-size:x-small;" ><b style="color: rgb(56, 118, 29);">cml.setMove(new CMLMove[]{move});</b></span><br /><span style=";font-family:Verdana,sans-serif;font-size:x-small;" ><b><span style="color: rgb(56, 118, 29);">repositoryService.update(cml);</span></b></span><br /><span style=";font-family:Verdana,sans-serif;font-size:x-small;" ><b><span style="color: rgb(56, 118, 29);"> </span></b></span><br />o bien borrarlo:<br /><br /><span style=";font-family:Verdana,sans-serif;font-size:x-small;" ><b style="color: rgb(56, 118, 29);">CMLDelete delete = new CMLDelete(new Predicate(new Reference[]{newContentNode}, storeRef, null));<br />cml.setDelete(new CMLDelete[]{delete});</b></span><br /><span style=";font-family:Verdana,sans-serif;font-size:x-small;" ><b><span style="color: rgb(56, 118, 29);">repositoryService.update(cml);</span></b></span><br /><br />Una vez hayamos terminado, no nos olvidemos nunca de finalizar la sesión:<br /><br /><span style="color: rgb(56, 118, 29);font-family:Verdana,sans-serif;font-size:x-small;" ><b> AuthenticationUtils.endSession();</b></span><br /><br /><span style="color: rgb(56, 118, 29);font-family:Verdana,sans-serif;font-size:x-small;" ><b> </b></span>Patriciahttp://www.blogger.com/profile/08618980369195930324noreply@blogger.com7tag:blogger.com,1999:blog-6779529014456497914.post-45419338384202571122011-03-07T04:25:00.000-08:002011-03-09T00:05:25.478-08:00Rechazo de emails con envío masivoHola,<br />
<br />
Voy a comentar un problema que tuvimos con el envío de correos (inbound) al servidor...<br />
<br />
<u><b>Configuración de servidor:</b></u><br />
<br />
<i>Windows Server 2008<br />
Alfresco 3.1.1<br />
Lotus Notes<br />
SQLServer</i><br />
<br />
<u><b>Situación:</b></u><br />
<br />
de 3 a 5 usuarios enviando varios correos de forma simultánea al servidor<br />
<br />
<u><b>Resultado:</b></u><br />
<br />
<span style="color: #38761d; font-size: x-small;">15:21:37,884 ERROR [org.alfresco.email.server.impl.subetha.SubethaEmailServer] Email message processing failed<br />
org.alfresco.error.AlfrescoRuntimeException: Email message processing failed<br />
at org.alfresco.email.server.EmailServiceImpl.processMessage(EmailServiceImpl.java:235)<br />
at org.alfresco.email.server.EmailServiceImpl.importMessage(EmailServiceImpl.java:147)<br />
at es.sic.utils.CustomEmailServiceImpl_.importMessage(CustomEmailServiceImpl_.java:17)<br />
at org.alfresco.email.server.impl.subetha.SubethaEmailServer$Handler.processDelivery(SubethaEmailServer.java:177)<br />
at org.alfresco.email.server.impl.subetha.SubethaEmailServer$Handler.data(SubethaEmailServer.java:132)<br />
at org.subethamail.smtp.command.DataCommand.execute(DataCommand.java:56)<br />
at org.subethamail.smtp.server.CommandHandler.handleCommand(CommandHandler.java:58)<br />
at org.subethamail.smtp.server.ConnectionHandler.run(ConnectionHandler.java:113)<br />
Caused by: org.alfresco.error.AlfrescoRuntimeException: IOException while attempting to detect charset encoding.<br />
at org.alfresco.encoding.AbstractCharactersetFinder.detectCharset(AbstractCharactersetFinder.java:102)<br />
at org.alfresco.repo.content.encoding.ContentCharsetFinder.getCharset(ContentCharsetFinder.java:100)<br />
at org.alfresco.email.server.handler.AbstractEmailMessageHandler.writeContent(AbstractEmailMessageHandler.java:220)<br />
at org.alfresco.email.server.handler.FolderEmailMessageHandler.addAlfrescoContent(FolderEmailMessageHandler.java:134)<br />
at org.alfresco.email.server.handler.FolderEmailMessageHandler.processMessage(FolderEmailMessageHandler.java:80)<br />
at org.alfresco.email.server.EmailServiceImpl$3.execute(EmailServiceImpl.java:207)<br />
at org.alfresco.repo.transaction.RetryingTransactionHelper.doInTransaction(RetryingTransactionHelper.java:322)<br />
at org.alfresco.repo.transaction.RetryingTransactionHelper.doInTransaction(RetryingTransactionHelper.java:248)<br />
at org.alfresco.email.server.EmailServiceImpl$4.doWork(EmailServiceImpl.java:215)<br />
at org.alfresco.repo.security.authentication.AuthenticationUtil.runAs(AuthenticationUtil.java:497)<br />
at org.alfresco.email.server.EmailServiceImpl.processMessage(EmailServiceImpl.java:218)<br />
... 7 more<br />
Caused by: java.io.IOException: Stream closed<br />
at java.io.PushbackInputStream.ensureOpen(PushbackInputStream.java:57)<br />
at java.io.PushbackInputStream.read(PushbackInputStream.java:118)<br />
at com.sun.mail.util.QPDecoderStream.read(QPDecoderStream.java:55)<br />
at com.sun.mail.util.QPDecoderStream.read(QPDecoderStream.java:134)<br />
at java.io.BufferedInputStream.fill(BufferedInputStream.java:218)<br />
at java.io.BufferedInputStream.read1(BufferedInputStream.java:258)<br />
at java.io.BufferedInputStream.read(BufferedInputStream.java:317)<br />
at java.io.FilterInputStream.read(FilterInputStream.java:90)<br />
at org.alfresco.encoding.AbstractCharactersetFinder.detectCharset(AbstractCharactersetFinder.java:88)<br />
... 17 more</span><br />
<br />
<br />
Al principio pensamos que era un problema de configuración de Lotus Notes y que venia con un charset que Alfresco no reconocía, pero descubrimos que no, por lo que añadimos estas dos lineas en el fichero <b>custom-email-server.properties</b><br />
<br />
<code style="color: #38761d;">email.server.connections.max=5</code><br />
<br />
Con este cambio conseguimos mejorar el resultado, pero seguíamos teniendo rechazos cuando llegaban correos con muchos adjuntos, por lo que teníamos que encolar los correos y mandarlos con un retardo de por lo menos 10 segundos. <br />
Al final decidimos hacer nuestra propia clase, que extiende de la clase de Alfresco que trata los emails (<b>EmailServiceImpl</b>) y sincroniza el método que los procesa. De momento, no hemos tenido ningún problema.<br />
<br />
<br />
<b><span style="color: #38761d; font-size: x-small;">public class CustomEmailServiceImpl_ extends EmailServiceImpl{ <br />
/**<br />
* {@inheritDoc}<br />
*/<br />
@Override<br />
public void importMessage(EmailMessage message)<br />
{<br />
synchronized (this) {<br />
super.importMessage(message);<br />
}<br />
}<br />
/**<br />
* {@inheritDoc}<br />
*/<br />
@Override<br />
public void importMessage(NodeRef nodeRef, EmailMessage message)<br />
{<br />
synchronized (this) {<br />
super.importMessage(nodeRef, message);<br />
}<br />
}<br />
<br />
}</span></b>Patriciahttp://www.blogger.com/profile/08618980369195930324noreply@blogger.com0tag:blogger.com,1999:blog-6779529014456497914.post-42374388548581096652011-03-07T02:39:00.000-08:002011-03-13T00:54:57.865-08:00Alfresco 3.4 + CentoOS + OracleHemos optado esta vez por instalar la nueva versión de Alfresco en un CentOS.<br /><br />Para la instalación, hemos utilizado el installer de Linux de 64 bits y Oracle 10g.<br /><br />Hemos puesto el driver de oracle <b>ojdbc14.jar</b> en <b>.../tomcat/lib</b><br />Hemos utilizado el siguiente script para la creación del tablespace y el usuario de la base de datos de Oracle<br /><br /><b><span style="color: rgb(56, 118, 29);font-size:x-small;" > CREATE TABLESPACE <span style="color: rgb(204, 0, 0);">TABLESPACE</span><br />DATAFILE<br /> 'C:\oracle\datafiles\<span style="color: rgb(204, 0, 0);">TABLESPACE</span>.DBF' SIZE 1024 M<br />AUTOEXTEND ON NEXT 100 M MAXSIZE UNLIMITED;<br /><br />CREATE USER "<span style="color: rgb(204, 0, 0);">USERNAME</span>" IDENTIFIED BY "<span style="color: rgb(204, 0, 0);">PASSWORD</span>"<br /><br /> DEFAULT TABLESPACE <span style="color: rgb(204, 0, 0);">TABLESPACE</span><br /> TEMPORARY TABLESPACE TEMP<br /> QUOTA UNLIMITED ON </span></b><b><span style="color: rgb(56, 118, 29);font-size:x-small;" ><span style="color: rgb(204, 0, 0);">TABLESPACE</span></span></b><b><span style="color: rgb(56, 118, 29);font-size:x-small;" >;<br /><br />GRANT "CONNECT" TO "<span style="color: rgb(204, 0, 0);">USERNAME</span>";<br />GRANT "DBA" TO "</span></b><b><span style="color: rgb(56, 118, 29);font-size:x-small;" ><span style="color: rgb(204, 0, 0);">USERNAME</span></span></b><b><span style="color: rgb(56, 118, 29);font-size:x-small;" >";<br />ALTER USER "</span></b><b><span style="color: rgb(56, 118, 29);font-size:x-small;" ><span style="color: rgb(204, 0, 0);">USERNAME</span></span></b><b><span style="color: rgb(56, 118, 29);font-size:x-small;" >" DEFAULT ROLE "CONNECT";</span></b><br /><br />Y hemos configurado el <b>alfresco-global.properties</b> de la siguiente manera:<br /><br /><b style="color: rgb(56, 118, 29);"><span style="font-size:x-small;">db.driver=oracle.jdbc.OracleDriver</span></b><br /><div style="color: rgb(56, 118, 29);"><b><span style="font-size:x-small;">db.name=<span style="color: rgb(204, 0, 0);">TABLESPACE</span></span></b></div><div style="color: rgb(56, 118, 29);"><b><span style="font-size:x-small;">db.username=</span></b><b style="color: rgb(204, 0, 0);"><span style="font-size:x-small;">USERNAME</span></b></div><div style="color: rgb(56, 118, 29);"><b><span style="font-size:x-small;">db.password=<span style="color: rgb(204, 0, 0);">PASSWORD</span></span></b></div><div style="color: rgb(56, 118, 29);"><b><span style="font-size:x-small;">db.host=<span style="color: rgb(204, 0, 0);">HOST</span></span></b><br /><b><span style="font-size:x-small;">db.port=1521</span></b></div><div style="color: rgb(56, 118, 29);"><b><span style="font-size:x-small;">db.url=jdbc:oracle:thin:@host:1521:<span style="color: rgb(204, 0, 0);">SID</span></span></b></div><b style="color: rgb(56, 118, 29);"><span style="font-size:x-small;">db.pool.validate.query=SELECT 1 FROM DUAL</span></b><br /><br /><br />También hemos tenido que añadir ésta linea porque teniamos varios esquemas, aunque no siempre es necesario:<br /><br /><span style="color: rgb(56, 118, 29);font-size:x-small;" ><b>hibernate.default_schema=<span style="color: rgb(204, 0, 0);">SCHEMA_NAME</span></b></span><br /><br />Para arrancar y parar el serivdor, situarnos en la ruta de la instalación y ejecutar los siguientes comandos:<br /><br /><span style="color: rgb(56, 118, 29);font-size:x-small;" ><b>sh alfresco.sh start</b></span><br /><span style="color: rgb(56, 118, 29);font-size:x-small;" ><b>sh alfresco.sh stop </b></span><br /><br />Salu2!Patriciahttp://www.blogger.com/profile/08618980369195930324noreply@blogger.com0tag:blogger.com,1999:blog-6779529014456497914.post-30886213185524006002011-03-07T02:13:00.000-08:002011-03-09T07:20:50.431-08:00Hola!!<br /><br />Muy buenas a todos,<br /><br />Me llamo Patricia y trabajo como desarrolladora. Llevo más de un año trabajando con <a href="http://www.alfresco.com/es/">Alfresco</a> y después de muchos quebraderos de cabeza me he decidido a escribir este blog para contar mis penurias con este gestor documental...<br /><br />Os iré contando todos los problemas con los que me he encontrado y las soluciones que he utilizado para solventarlos... y si me animo pues seguro que escribiré alguna cosa más!<br />Espero de verdad, que le sirva a alguien como ayuda :)<br /><br />Gracias a Cristina por animarme a escribir!!<br /><br />Salu2 a todos!Patriciahttp://www.blogger.com/profile/08618980369195930324noreply@blogger.com1