Basándonos en este artículo
del blog de Alfresco relativo a propiedades dinámicas en tipos de
contenido, hemos desarrollado un sencillo componente para utilizar
y gestionar listas dinámicas en uno de nuestros modelos de
contenido utilizados en zylk.net.
En nuestro caso, tenemos un modelo de contenido para
gestionar incidencias o tickets, con un tipo base bug:incidencia,
del cual tenemos el siguiente extracto:
<type name="bug:incidencia">
ref="bug:AsignarIssue" />
ref="bug:EstadosIssue" />
ref="bug:PrioridadesIssue" />
Para las tres propiedades anteriores se utilizan un
conjunto de constrains que se definen de manera dinamica a
continuación, a partir de una query de lucene sobre el
repositorio. Es decir, gestionamos las propiedades en el
repositorio (y no en un archivo xml del modelo), y las consumimos
mediante querys de lucene.
Para asignar incidencia a usuario (person):
type="zylk.net.constraints.SearchBasedListConstraint" >
Para
definir los estados de la incidencia (categorías):
<constraint name="bug:EstadosIssue"
type="zylk.net.constraints.SearchBasedListConstraint" >
Para establecer la prioridad de la incidencia (folders):
type="zylk.net.constraints.SearchBasedListConstraint" >
El caso de uso es el siguiente:
-
Tenemos un tipo de contenido con una propiedad
definida que es variable
bug:EstadosIssue
y necesita de una administración propia, porque
el administrador requiere añadir nuevos valores a esa
constraint con cierta frecuencia. Esta problemática se puede
gestionar con categorias en Alfresco (pero solo el
administrador puede acceder a través de las interfaces de
Alfresco Explorer y Share). -
Tenemos un tipo de contenido con una propiedad
definida que es variable
bug:PrioridadesIssue
y necesita de una administración propia y donde
no sólo por los administradores sino un grupo de usuarios va a
añadir valores con cierta frecuencia. Esta problemática se
puede gestionar con una estructura de carpetas virtual creada
por ejemplo en Data Dictionary (con permisos de edicion para
el conjunto de usuarios editores)
La clase que implementará la
carga de valores extiende de
ListOfValuesConstraint (ver
wiki
)
public class SearchBasedListConstraint extends ListOfValuesConstraint implements Serializable
haremos uso del ServiceRegistry para poder llamar a
los servicios que necesitamos (SearchService, NodeService…)
private static ServiceRegistry registry; public ServiceRegistry getServiceRegistry() { return registry; } public void setServiceRegistry(ServiceRegistry registry) { SearchBasedListConstraint.registry = registry; }
tendremos
un método que realizará una búsqueda Lucene con una query que
pasaremos como parámetro desde el modelo de contenido.
protected List<String> getResults() { getServiceRegistry().getAuthenticationService().authenticate("admin", "admin".toCharArray()); List<String> allowedValues = new ArrayList<String>(); for (ResultSetRow row : resultSet) { if(nodeSvc.getType(row.getNodeRef()).equals(ContentModel.TYPE_PERSON)){ allowedValues.add((String)nodeSvc.getProperty(row.getNodeRef(), ContentModel.PROP_FIRSTNAME) + " " + (String)nodeSvc.getProperty(row.getNodeRef(), ContentModel.PROP_LASTNAME)); }else{ allowedValues.add((String)nodeSvc.getProperty(row.getNodeRef(), ContentModel.PROP_NAME)); } } if (allowedValues.size() == 0) allowedValues.add(""); return allowedValues; }
también es necesario sobreescribir el método
getAllowedValues para que cargue los valores obtenidos en la búsqueda:
@Override public List<String> getAllowedValues() { List<String> allowedValues = getResults(); super.setAllowedValues(allowedValues); return allowedValues; }
y por último, tendremos que tener definido el bean en
el contexto:
PS: Para
desplegar la clase java hemos creado un jar y lo hemos copiado en
$ALF_HOME$/tomcat/webapps/alfresco/WEB-INF/lib.
Ejemplos:
Constraint
para usuarios:
Constraint
de categorías:
Constraint
de carpetas: