it.pronetics.madstore.repository.jcr.impl.AbstractJcrRepository.java Source code

Java tutorial

Introduction

Here is the source code for it.pronetics.madstore.repository.jcr.impl.AbstractJcrRepository.java

Source

/**
 * Copyright 2008 - 2009 Pro-Netics S.P.A.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */
package it.pronetics.madstore.repository.jcr.impl;

import it.pronetics.madstore.common.AtomConstants;
import it.pronetics.madstore.common.dom.DomHelper;
import it.pronetics.madstore.repository.index.IndexManager;
import it.pronetics.madstore.repository.jcr.xml.JcrContentHandlerFactory;
import it.pronetics.madstore.repository.support.AtomRepositoryException;
import it.pronetics.madstore.repository.util.PagingList;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import javax.jcr.ImportUUIDBehavior;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.query.Query;
import javax.jcr.query.QueryManager;
import javax.jcr.query.QueryResult;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.antlr.stringtemplate.StringTemplate;
import org.antlr.stringtemplate.StringTemplateGroup;
import org.springframework.extensions.jcr.JcrTemplate;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.ContentHandler;

/**
 * Base abstract class for repositories implementations.
 * <br/>
 * This class contains methods to read and write content from the repository, defining its inner structure.
 * 
 * @author Salvatore Incandela
 * @author Sergio Bossa
 */
public abstract class AbstractJcrRepository {

    private static final String TEMPLATES_CLASSPATH_FOLDER = "templates/";
    private static final String GET_ENTRY_NODE_PATH_TEMPLATE = TEMPLATES_CLASSPATH_FOLDER + "getEntryNode";
    private static final String GET_COLLECTION_NODE_PATH_TEMPLATE = TEMPLATES_CLASSPATH_FOLDER
            + "getCollectionNode";
    private static final String GET_ENTRY_NODES_QUERY_TEMPLATE = TEMPLATES_CLASSPATH_FOLDER + "getEntryNodes";
    private static final String GET_COLLECTION_NODES_QUERY_TEMPLATE = TEMPLATES_CLASSPATH_FOLDER
            + "getCollectionNodes";
    private static final String COLLECTION_TEMPLATE_PARAMETER = "collection";
    private static final String ENTRY_TEMPLATE_PARAMETER = "entry";
    private static final StringTemplateGroup PATH_GROUP = new StringTemplateGroup("pathGroup");
    private static final StringTemplateGroup QUERY_GROUP = new StringTemplateGroup("queryGroup");
    private static final String MADSTORE_NAMESPACE = "mds:";
    private static final String APP_COLLECTION = "app:collection";
    private static final String ATOM_ENTRY = "atom:entry";
    private static final String JCR_LAST_MODIFIED = "jcr:lastModified";
    private static final String MIX_REFERENCEABLE = "mix:referenceable";
    private static final String COLLECTION_REF = "collectionRef";
    protected JcrTemplate jcrTemplate;
    protected JcrContentHandlerFactory jcrContentHandlerFactory;
    protected IndexManager indexManager;

    public void setJcrTemplate(JcrTemplate jcrTemplate) {
        this.jcrTemplate = jcrTemplate;
    }

    public void setJcrContentHandlerFactory(JcrContentHandlerFactory jcrContentHandlerFactory) {
        this.jcrContentHandlerFactory = jcrContentHandlerFactory;
    }

    public void setIndexManager(IndexManager indexManager) {
        this.indexManager = indexManager;
    }

    public IndexManager getIndexManager() {
        return indexManager;
    }

    protected final void importNodeFromDomCollection(String collectionKey, Element collectionElement,
            Session session) {
        try {
            InputStream collectionStream = DomHelper.getStreamFromDomElement(collectionElement);
            Node root = session.getRootNode();
            Node collectionContainerNode = root.addNode(MADSTORE_NAMESPACE + collectionKey);
            session.importXML(collectionContainerNode.getPath(), collectionStream,
                    ImportUUIDBehavior.IMPORT_UUID_COLLISION_THROW);
            Node collectionNode = collectionContainerNode.getNode(APP_COLLECTION);
            postProcessCollectionImport(collectionElement, collectionContainerNode, collectionNode);
        } catch (Exception ex) {
            throw new AtomRepositoryException(ex.getMessage(), ex);
        }
    }

    protected final void importNodeFromDomEntry(String collectionKey, String entryKey, Element entryElement,
            Session session) {
        try {
            InputStream entryStream = DomHelper.getStreamFromDomElement(entryElement);
            Node root = session.getRootNode();
            Node collectionContainerNode = root.getNode(MADSTORE_NAMESPACE + collectionKey);
            Node entryContainerNode = collectionContainerNode.addNode(MADSTORE_NAMESPACE + entryKey);
            session.importXML(entryContainerNode.getPath(), entryStream,
                    ImportUUIDBehavior.IMPORT_UUID_COLLISION_THROW);
            Node entryNode = entryContainerNode.getNode(ATOM_ENTRY);
            postProcessEntryImport(entryElement, collectionContainerNode, entryContainerNode, entryNode);
        } catch (Exception ex) {
            throw new AtomRepositoryException(ex.getMessage(), ex);
        }
    }

    protected final Element exportNodeToDom(String path, Session session) {
        try {
            Document exportedDocument = getDomDocument();
            ContentHandler atomContentHandler = jcrContentHandlerFactory.makeExportContentHandler(exportedDocument);
            session.exportDocumentView(path, atomContentHandler, false, false);
            return exportedDocument.getDocumentElement();
        } catch (Exception ex) {
            throw new AtomRepositoryException(ex.getMessage(), ex);
        }
    }

    protected final void postProcessCollectionImport(Element collectionElement, Node collectionContainerNode,
            Node collectionNode) {
        try {
            collectionContainerNode.addMixin(MIX_REFERENCEABLE);
        } catch (Exception ex) {
            throw new AtomRepositoryException(ex.getMessage(), ex);
        }
    }

    protected final void postProcessEntryImport(Element entryElement, Node collectionContainerNode,
            Node entryContainerNode, Node entryNode) {
        try {
            entryContainerNode.addMixin(MIX_REFERENCEABLE);
            entryContainerNode.setProperty(COLLECTION_REF, collectionContainerNode);
            org.w3c.dom.NodeList nodes = entryElement.getElementsByTagNameNS(AtomConstants.ATOM_NS,
                    AtomConstants.ATOM_ENTRY_UPDATED);
            if (nodes.getLength() == 1) {
                org.w3c.dom.Node updated = nodes.item(0);
                entryNode.setProperty(JCR_LAST_MODIFIED, updated.getTextContent());
            }
        } catch (Exception ex) {
            throw new AtomRepositoryException(ex.getMessage(), ex);
        }
    }

    protected final Node getCollectionNode(String collectionKey, Session session) throws RepositoryException {
        StringTemplate pathTemplate = PATH_GROUP.getInstanceOf(GET_COLLECTION_NODE_PATH_TEMPLATE);
        pathTemplate.setAttribute(COLLECTION_TEMPLATE_PARAMETER, collectionKey);
        String path = pathTemplate.toString();
        Node root = session.getRootNode();
        if (root.hasNode(path)) {
            return root.getNode(path);
        } else {
            return null;
        }
    }

    protected final Node getEntryNode(String collectionKey, String entryKey, Session session)
            throws RepositoryException {
        StringTemplate pathTemplate = PATH_GROUP.getInstanceOf(GET_ENTRY_NODE_PATH_TEMPLATE);
        pathTemplate.setAttribute(COLLECTION_TEMPLATE_PARAMETER, collectionKey);
        pathTemplate.setAttribute(ENTRY_TEMPLATE_PARAMETER, entryKey);
        String path = pathTemplate.toString();
        Node root = session.getRootNode();
        if (root.hasNode(path)) {
            return root.getNode(path);
        } else {
            return null;
        }
    }

    protected final List<Node> getCollectionNodes(Session session) throws RepositoryException {
        StringTemplate queryTemplate = QUERY_GROUP.getInstanceOf(GET_COLLECTION_NODES_QUERY_TEMPLATE);
        QueryManager queryManager = session.getWorkspace().getQueryManager();
        Query query = queryManager.createQuery(queryTemplate.toString(), Query.XPATH);
        QueryResult queryResult = query.execute();
        List<Node> elements = new ArrayList<Node>();
        NodeIterator nodeIterator = queryResult.getNodes();
        while (nodeIterator.hasNext()) {
            elements.add(nodeIterator.nextNode());
        }
        return elements;
    }

    protected final PagingList<Node> getEntryNodes(String collectionKey, int offset, int max, Session session)
            throws RepositoryException {
        if (offset < 0 || max < 0) {
            throw new IllegalArgumentException("Parameters offset and max cannot be negative!");
        }
        StringTemplate queryTemplate = QUERY_GROUP.getInstanceOf(GET_ENTRY_NODES_QUERY_TEMPLATE);
        queryTemplate.setAttribute(COLLECTION_TEMPLATE_PARAMETER, collectionKey);
        QueryManager queryManager = session.getWorkspace().getQueryManager();
        Query query = queryManager.createQuery(queryTemplate.toString(), Query.XPATH);
        QueryResult queryResult = query.execute();
        NodeIterator nodeIterator = queryResult.getNodes();
        int total = (int) nodeIterator.getSize();
        PagingList<Node> elements = new PagingList<Node>(new ArrayList<Node>(), offset, max, total);
        if (nodeIterator.getSize() > offset) {
            nodeIterator.skip(offset);
            while (nodeIterator.hasNext()) {
                if (max > 0 && !((nodeIterator.getPosition() - offset + 1) <= max)) {
                    break;
                }
                elements.add(nodeIterator.nextNode());
            }
        }
        return elements;
    }

    private Document getDomDocument() throws Exception {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setNamespaceAware(true);
        DocumentBuilder builder = factory.newDocumentBuilder();
        return builder.newDocument();
    }
}