Top Banner
Salvatore Incandela Everything is content Spring JCR (JSR170) Spring Framework Meeting 31 Ottobre 2009
32

Spring Jcr Extension

Jun 19, 2015

Download

Technology

Everything si content. La produzione frenetica di contenuti a cui siamo abituati ci impone di utilizzare strumenti, semantiche, metadati sempre più avanzati. Tutti i CR implementati in java aderiscono alla specifica JSR170 per standardizzare accesso ai dati e rappresentazione del dato, tuttavia la specifica in se stessa non è sufficiente a ridurre i costi di implementazione di integrazioni.
Spring JCR Extension si pone come obbiettivo quello di applicare l'approccio JDBC Template al mondo dei CR.
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Spring Jcr Extension

Salvatore Incandela

Everything is contentSpring JCR (JSR170)

Spring Framework Meeting 31 Ottobre 2009

Page 2: Spring Jcr Extension

Agenda

• Introduzione ai Content Repository.• Java Content Repository API.• Repository Model.• Esempio pratico.• Vantaggi Spring JCR.• Links.

Page 3: Spring Jcr Extension

Caratteristiche di File system e database

●Versioning●Controllo accessi●Classifcazione contenuti●Monitoraggio eventi●Ricerche testuali

Introduzine ai content repository

Page 4: Spring Jcr Extension

Con API proprietarie

Java Content Repository API

Page 5: Spring Jcr Extension

Con JCR

Java Content Repository API

Page 6: Spring Jcr Extension

Why JCR 170?

Più di 800 vendor sul mercatoStandard API

Riduzione costi

API semplici

Swappability

Java Content Repository API

Page 7: Spring Jcr Extension

•Level 1• Traversing tree • Getting value of properties • Namespace remapping

(transient) • Export to XML • Query by Xpath

Java Content Repository API

Page 8: Spring Jcr Extension

• Level 2• Adding, removing items • Writing to properties • Persistent namespace changes • Import from XML • Assigning node types to nodes

Java Content Repository API

Page 9: Spring Jcr Extension

•Transactions (JTA) •Versioning •Observation (events) •Locking •SQL syntax for queries

Java Content Repository API

Page 10: Spring Jcr Extension

Java Content Repository API

Page 11: Spring Jcr Extension

Il content model è costituito da più workspace, ognuno di essi contiene un albero composto da più item (nodi o property).

Nodo : one parent more childProperty: one parent no child

Repository model

Page 12: Spring Jcr Extension

Percorso xpathAbsolute : /a/b/c Relative: ../../b/c

UUID

Navigazione dell'albero

Repository model

Page 13: Spring Jcr Extension

●Ogni nodo ha un primary type● jcr:primaryType

●Più mixing types, opzionali contenuti nella proprietà jcr:mixingTypes

● mix:versionable● mix:lockable● mix:referencable

●Possono avere fratelli uguali● /nodo/nodofglio[2]

Nodo

Repository model

Page 14: Spring Jcr Extension

Un content repository deve supportare il tipo nt:base Può inoltre supportare dei tipi opzionali

–nt:unstructured –nt:hierarchyNode (sottotipi: nt:fle,nt:folder) –nt:resource –nt:version, nt:versionHistory –nt:query

Tipi di nodo

Repository model

Page 15: Spring Jcr Extension

Un content repository deve supportare il tipo nt:base Può inoltre supportare dei tipi opzionali

–nt:unstructured –nt:hierarchyNode (sottotipi: nt:fle,nt:folder) –nt:resource –nt:version, nt:versionHistory –nt:query

Tipi di nodo

Repository model

Page 16: Spring Jcr Extension

Tipi di nodo

NodeTypeName nt:file Supertypes nt:hierarchyNode IsMixin false HasOrderableChildNodes false PrimaryItemName jcr:content ChildNodeDefinition Name jcr:content RequiredPrimaryTypes [nt:base] DefaultPrimaryType null AutoCreatefalse Mandatory true OnParentVersion COPY Protected false SameNameSiblings false

NodeTypeName mix:lockable Supertypes [] IsMixin true HasOrderableChildNodes false PrimaryItemName null PropertyDefinition Name jcr:lockOwner RequiredType STRING ValueConstraints [] DefaultValues null AutoCreated false Mandatory false OnParentVersion IGNORE Protected true Multiple false PropertyDefinition Name jcr:lockIsDeep RequiredType BOOLEAN ValueConstraints [] DefaultValues null AutoCreatefalse Mandatory false OnParentVersion IGNORE Protectedtrue Multiple false

Repository model

Page 17: Spring Jcr Extension

Proprietà

– LONG, DATE, STRING, DOUBLE, BOOLEAN – PATH: percorso nel workspace – REFERENCE: contiene l'UUID del nodo (mix:referenceable)– NAME: nome del tipo di nodo

Impostare un valore null ad una property equivale ad eliminarla

Repository model

Page 18: Spring Jcr Extension

Namespace

Il nome di una property come in xml può essere preceduto da un prefsso (namespace):

●jcr (eg. jcr:primaryNode)●nt – per i tipi di nodi (es. nt:version) ●mix – per i mixing types (es. mix:versionable) ●xml – per la compatibilità con xml

Repository model

Page 19: Spring Jcr Extension

Eseguire una query Workspace workspace = session.getWorkspace(); Node node = session.getRootNode(); workspace.getNamespaceRegistry().registerNamespace("pnx", "http://pronetics.jcrexample/1.0"); QueryManager queryManager = workspace.getQueryManager(); Query query = queryManager.createQuery("//pnx:rubrica/pnx:contact[@pnx:name='christian')]", Query.XPATH); QueryResult queryResult = query.execute(); NodeIterator nodeIterator = queryResult.getNodes();

Esportare File file = new File("backup.xml"); FileOutputStream fileOutputStream = new FileOutputStream(file); session.exportSystemView("/pnx:rubrica", fileOutputStream, false, false);

Importare File file = new File("backup.xml"); FileInputStream fileInputStream = new FileInputStream(file); session.importXML("/", fileInputStream, ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW);

Esempi

Page 20: Spring Jcr Extension

Considerato l'albero in fgura

Esempio pratico

Page 21: Spring Jcr Extension

Autenticazione al repository

Traversal access di una property

Esempio pratico

//Get repositoryRepository repository = (Repository) ctx.lookup("myrepo");//Get CredentialsCredentials credentials = new SimpleCredentials("MyName", "MyPassword".toCharArray());//Get SessionSession mySession = repository.login(credentials, "MyWorkSpace");

Node root = mySession.getRootNode();Node myNode = root.getNode("a/e");//mySession.getNodeByUUID("123456789")Property property = myNode.getProperty("k");Value value = property.getValue();double myDouble = value.getDouble();

Page 22: Spring Jcr Extension

Proviamo a creare un nodo

Per eliminare una property

Esempio pratico

Session mySession; Node root = mySession.getRootNode(); Node myNode = root.getNode("a/e"); myNode.addNode("Y"); session.save();

Session mySession; Node root = mySession.getRootNode(); Node myNode = root.getNode("a/e"); myNode.setProperty("p", (Value) null); session.save();

Page 23: Spring Jcr Extension

Inserimento e stampa property

Repository r = new TransientRepository(); Session session = r.login(new SimpleCredentials("pippo", "pluto".toCharArray())); try { Workspace workspace = session.getWorkspace(); Node node = session.getRootNode(); workspace.getNamespaceRegistry().registerNamespace("pnx", "http://pronetics.jcrexample/1.0");

Node rubrica = node.addNode("pnx:rubrica"); Node contact = rubrica.addNode("pnx:contact"); contact.setProperty("pnx:name", "christian"); contact.setProperty("pnx:tel", "000000"); contact.setProperty("pnx:category", new String[] { "professional", "metal" }); // IMPORTANTE session.save();

rubrica = node.getNode("pnx:rubrica"); node.getProperty("pnxs:rubrica/pnx:contact[1]/pnx:name");

NodeIterator nodeIterator = node.getNodes(); while (nodeIterator.hasNext()) { Node cnt = nodeIterator.nextNode(); PropertyIterator propertyIterator = cnt.getProperties(); while (propertyIterator.hasNext()) { Property property = propertyIterator.nextProperty(); LOG.info("Property name: {} property value: {}", property.getName(), property.getValue()); } }

} finally { session.logout(); }

Esempio pratico

Page 24: Spring Jcr Extension

L'interfaccia SessionFactory descrive come ottenere una session, agisce come wrapper del javax.jcr.Repository. Per ottenere una sessionFactory abbiamo bisogno del repository bean e delle credenziali:

<bean id="jcrSessionFactory" class="org.springframework.extensions.jcr.JcrSessionFactory"> <property name="repository" ref="repository"/> <property name="credentials"> <bean class="javax.jcr.SimpleCredentials"> <constructor-arg index="0" value="bogus"/> <constructor-arg index="1" value="pass"/> </bean> </property> </bean>

JcrSessionFactory permette inoltre la registrazione di namespaces, agiungere listener per ulteriori informazioni fare riferimento ai javadoc.

Session Factory

Page 25: Spring Jcr Extension

Per effettuare la registrazione di namespaces custom basta semplicemente passarli come property, la key rappresenta il prefsso e il valore rappresenta il namespace:

<bean id="sessionFactory" class="org.springframework.extensions.jcr.JcrSessionFactory"> ... <property name="namespaces"> <props> <prop key="foo">http://bar.com/jcr</prop> <prop key="hocus">http://pocus.com/jcr</prop> </props> </property></bean>

Modalità di registrazione:●ForceNamespacesRegistration●KeepNewNamespaces●skipExistingNamespaces

Namespace registration

Page 26: Spring Jcr Extension

La registrazione dei listener permette di identifcare il path del nodo ascoltato, o una espressione regolare

<bean id="sessionFactory" class="org.springframework.extensions.jcr.JcrSessionFactory"> ... <property name="eventListeners"> <list> <bean class="org.springframework.extensions.jcr.EventListenerDefinition"> <property name="listener"> <bean class="org.springframework.extensions.examples.jcr.DummyEventListener"/> </property> <property name="absPath" value="/rootNode/someFolder/someLeaf"/> </bean> </list> </property></property>

Event listeners

Page 27: Spring Jcr Extension

La registrazione dei tipi di nodo è tipica del CR che stiamo usando, in questo caso JackRabbit:

<bean id="jackrabbitSessionFactory" class="org.springframework.extensions.jcr.jackrabbit.JackrabbitSessionFactory"> ... <property name="nodeDefinitions"> <list> <value>classpath:/nodeTypes/wikiTypes.cnd</value> <value>classpath:/nodeTypes/clientATypes.cnd</value> </list> </property></bean>

NodeTypeDefinition

Page 28: Spring Jcr Extension

Inserimento e stampa property

//Repository r = new TransientRepository(); //Session session = r.login(new SimpleCredentials("pippo", "pluto".toCharArray())); //try { Workspace workspace = session.getWorkspace(); Node node = session.getRootNode(); //workspace.getNamespaceRegistry().registerNamespace("pnx", "http://pronetics.jcrexample/1.0");

Node rubrica = node.addNode("pnx:rubrica"); Node contact = rubrica.addNode("pnx:contact"); contact.setProperty("pnx:name", "christian"); contact.setProperty("pnx:tel", "000000"); contact.setProperty("pnx:category", new String[] { "professional", "metal" }); // IMPORTANTE session.save();

rubrica = node.getNode("pnx:rubrica"); node.getProperty("pnxs:rubrica/pnx:contact[1]/pnx:name");

NodeIterator nodeIterator = node.getNodes(); while (nodeIterator.hasNext()) { Node cnt = nodeIterator.nextNode(); PropertyIterator propertyIterator = cnt.getProperties(); while (propertyIterator.hasNext()) { Property property = propertyIterator.nextProperty(); LOG.info("Property name: {} property value: {}", property.getName(), property.getValue()); } }

//} finally { // session.logout(); //}

Esempio SpringJcr

Page 29: Spring Jcr Extension

La maggior parte del lavoro con JCR viene svolta dal Jcrtemplate stesso. Il template richiede una sessionFactory e può essere confgurato in modo da creare nuove sessioni on demand o riusarle.

<bean id="jcrTemplate" class="org.springframework.extensions.jcr.JcrTemplate"> <property name="sessionFactory" ref="sessionFactory"/> <property name="allowCreate" value="true"/></bean>

JcrTemplate contiene molte delle funzioni di javax.jcr.Session e javax.jcr.query.Query. Nel caso in cui queste non siano suffcienti interviene JcrCallback che opera direttamente con la sessione. JcrCallback è thread-safe, apre e chiude sessioni.

public void saveSmth() { template.execute(new JcrCallback() {

public Object doInJcr(Session session) throws RepositoryException { Node root = session.getRootNode(); log.info("starting from root node " \+ root); Node sample = root.addNode("sample node"); sample.setProperty("sample property", "bla bla"); log.info("saved property " \+ sample); session.save(); return null; } }); }

JcrTemplate e JcrCallback

Page 30: Spring Jcr Extension

E' possibile utilizzare JcrDaoSupport analogamente a JdbcDaoSupport.

public class ProductDaoImpl extends JcrDaoSupport {

public void saveSmth() throws DataAccessException, MyException {

Session session = getSession(); try { Node root = session.getRootNode(); log.info("starting from root node " + root); Node sample = root.addNode("sample node"); sample.setProperty("sample property", "bla bla"); log.info("saved property " + sample); session.save(); return null; } catch (RepositoryException ex) { throw convertJcrAccessException(ex); } } }

DAO senza callback

Page 31: Spring Jcr Extension

Q/A

Finish

Page 32: Spring Jcr Extension

JSR-170 http://www.jcp.org/en/jsr/detail?id=170

Jackrabbithttp://jackrabbit.apache.org/

Versione html della specifca http://www.day.com/specs/jcr/1.0/

Spring JCRhttp://se-jcr.sourceforge.net/

Link utili

Authorwww.twitter.com/sincandela

salvatoreincandela.blogspot.comwww.linkedin.com/in/salvatoreincandela