Recorrido por el Content Repository API para Java (JCR), analizando JackRabbit
Transcript of Recorrido por el Content Repository API para Java (JCR), analizando JackRabbit
Presentador Edwin Guilbert Recorrido por el Content Repository API para Java (JCR),
analizando JackRabbit.20 de Mayo, 2015
JCR
¿QUÉ ES JCR?!
Content Repository API para Java: !
CMS Java Standard: JSR-170, JSR-283 Object database para guardar, buscar y obtener datos jerárquicos Java Package: javax.jcr
NODE TYPES!
Define los nodos hijo y sus propiedades. Sirve de modelo de contenidos para aplicaciones:
!
Primary type: Estructura del nodo. Propiedades, hijos, herencia !
Mixin: Capacidad con propiedades o nodos hijos
Primary: Product<nodeTypes xmlns:rep="internal" xmlns:nt="http://www.jcp.org/jcr/nt/1.0" xmlns:mix="http://www.jcp.org/jcr/mix/1.0" xmlns:mgnl="http://www.magnolia.info/jcr/mgnl" xmlns:jcr="http://www.jcp.org/jcr/1.0"> <!-- custom node types --> <nodeType name="mgnl:product" isMixin="false" hasOrderableChildNodes="true" primaryItemName=""> <supertypes> <supertype>mgnl:content</supertype> </supertypes> </nodeType> </nodeTypes>
Primary: Content <nodeType name="mgnl:contentNode" isMixin="false" hasOrderableChildNodes="true" primaryItemName=""> <supertypes> <supertype>nt:hierarchyNode</supertype> <supertype>mix:referenceable</supertype> <supertype>mgnl:created</supertype> <supertype>mgnl:activatable</supertype> <supertype>mgnl:lastModified</supertype> <supertype>mgnl:renderable</supertype> </supertypes> <childNodeDefinition name="*" defaultPrimaryType="" autoCreated="false" mandatory="false" onParentVersion="COPY" protected="false" sameNameSiblings="false"> <requiredPrimaryTypes> <requiredPrimaryType>nt:base</requiredPrimaryType> </requiredPrimaryTypes> </childNodeDefinition> <propertyDefinition name="*" requiredType="undefined" autoCreated="false" mandatory="false" onParentVersion="COPY" protected="false" multiple="false"/> <propertyDefinition name="*" requiredType="undefined" autoCreated="false" mandatory="false" onParentVersion="COPY" protected="false" multiple="true"/> </nodeType>
Mixin: Created <nodeType name="mgnl:created" isMixin=“true"> !
<supertypes> <supertype>nt:base</supertype> </supertypes> !
<propertyDefinition name="mgnl:created" requiredType="Date" autoCreated="false" mandatory="false" onParentVersion="COPY" protected="false" multiple=“false"/> !
<propertyDefinition name="mgnl:createdBy" requiredType="String" autoCreated="false" mandatory="false" onParentVersion="COPY" protected="false" multiple=“false"/> !
</nodeType>
BENEFICIOS DE JCREstructura Jerárquica Observación Búsqueda Versionado Exportar Importar Ordenamiento Seguridad
ESTRUCTURA JERÁRQUICALos datos en JCR consisten en un árbol de nodos con propiedades asociadas:
!
Los datos se almacenan en propiedades Strings o datos binarios Un nodo puede tener uno o mas NodeTypes asociados Propiedad especial que permite referenciar nodos entre sí Herencia/Integridad referencial JCR+API
REPOSITORIO Y WORKSPACES!
!
Carpetas comparables con nodos !
Ficheros comparables con propiedades !
Navegación por path: /A/B/property
OBSERVACIÓN!
Permite a las aplicaciones recibir notificaciones sobre cambios en un workspace: !
Modelo de eventos Tipos de evento: Agregar, remover, persistir Propiedades de evento: Path, identificador, usuario, fecha
ObservationManager:addEventListener !
ObservationUtil.registerDeferredChangeListener( RepositoryConstants.CONFIG, SERVER_FILTERS, filtersEventListener, 1000, 5000); !
!
ObservationManager observationManager = getObservationManager(workspace); !
observationManager.addEventListener(listener, eventTypesMask, observationPath, includeSubnodes, null, nodeTypes, false);
EventListener por Workspace !public class CommandEventListener implements EventListener { ! public void onEvent(EventIterator events) { ! while (events.hasNext()) { ! event = events.nextEvent(); ! path = getPath(event); ! Context executionCtx = this.createContext(); ! executionCtx.put(Context.ATTRIBUTE_PATH, path); ! getCommand().execute(executionCtx); } } }
BÚSQUEDA!
JSR-283 establece que se debe soportar una forma estandarizada de SQL: !
Abstract Query Model Lenguajes: JCR-SQL2 y JCR-JQOM Semántica: Selectores, Joins, Constraints, Orderings, Query results JCR Query Cheat Sheet
VERSIONADOEl versionado permite al usuario guardar y restaurar el estado de un nodo y su sub-árbol: !
Version <mix:versionable> subtipo de <mix:referenceable> Checkin, checkout y checkpoint VersionHistory / VersionStorage Base version Frozen nodes
protected Version createVersion(Node node, Rule rule, String userName) throws UnsupportedRepositoryOperationException, RepositoryException { !
node.addMixin(“mix:versionable"); node.addMixin.save(); !
// add version Version newVersion = node.checkin(); node.checkout(); !
} !
BaseVersionManager: createVersion
public synchronized void restore(final Node node, Version version, boolean removeExisting) throws VersionException, UnsupportedRepositoryOperationException, RepositoryException { !
!
node.restore(unwrappedVersion, removeExisting); !
node.checkout(); !
!
}
BaseVersionManager: restore
IMPORTAR / EXPORTARJCR provee serialización convirtiendo a XML el contenido del workspace sin pérdida de información:
!
XML refleja estructura jerárquica de JCR Namespace: sv: http://www.jcp.org/jcr/sv/1.0 Nodos se convierten en <sv:node> Propiedades se convierten en <sv:property> Nombres se convierten en atributo sv:name=“”
!
!
!
Session session = ws.getSession(); !
!
session.importXML(basepath, xmlStream, importMode); !
!
session.exportSystemView(basepath, outputStream, false, false);
DataTransporter: import export
ORDENAMIENTO!
JCR permite que los nodos tengan un ordenamiento dentro del árbol jerárquico:
!
Propiedades no son ordenables <nodeType name="mgnl:content" hasOrderableChildNodes=“true"> Node.getNodes() siempre tiene un orden El nodo padre ordena a sus hijos
!
!
!
public static void orderBefore(Node node, String siblingName) throws RepositoryException { !
node.getParent().orderBefore(node.getName(), siblingName); !
} !
!
!
NodeUtil: orderBefore
SEGURIDAD!
JCR permite la gestión de control de acceso en el repositorio: !
AccessControlManager Privilegios que un usuario tiene sobre un nodo jcr:read Obtener un nodo y sus propiedades jcr:write Modificar propiedades, agregar/eliminar nodos
public void addPermission(final Role role, final String workspace, final String path, final long permission) { !
Node roleNode = session.getNodeByIdentifier(role.getId()); Node aclNode = getAclNode(roleNode, workspace); if (!existsPermission(aclNode, path, permission)) { String nodeName = Path.getUniqueLabel(session, aclNode.getPath(), "0"); Node node = aclNode.addNode(nodeName, NodeTypes.ContentNode.NAME); node.setProperty("path", path); node.setProperty("permissions", permission); session.save(); } !
}
MgnlRoleManager: addPermission