org.xaloon.wicket.component.repository.impl.FileRepositoryImpl.java Source code

Java tutorial

Introduction

Here is the source code for org.xaloon.wicket.component.repository.impl.FileRepositoryImpl.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 org.xaloon.wicket.component.repository.impl;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Map;

import javax.jcr.AccessDeniedException;
import javax.jcr.ImportUUIDBehavior;
import javax.jcr.InvalidSerializedDataException;
import javax.jcr.ItemExistsException;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.PathNotFoundException;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.UnsupportedRepositoryOperationException;
import javax.jcr.ValueFormatException;
import javax.jcr.lock.LockException;
import javax.jcr.nodetype.ConstraintViolationException;
import javax.jcr.nodetype.NoSuchNodeTypeException;
import javax.jcr.query.InvalidQueryException;
import javax.jcr.query.Query;
import javax.jcr.query.QueryManager;
import javax.jcr.query.QueryResult;
import javax.jcr.version.Version;
import javax.jcr.version.VersionException;
import javax.jcr.version.VersionHistory;
import javax.jcr.version.VersionIterator;

import org.apache.jackrabbit.JcrConstants;
import org.apache.jackrabbit.core.SessionImpl;
import org.apache.jackrabbit.core.WorkspaceImpl;
import org.apache.jackrabbit.core.data.GarbageCollector;
import org.apache.jackrabbit.core.state.ItemStateException;
import org.dms.wicket.component.ContentSessionFacade;
import org.dms.wicket.repository.db.model.FileDescription;
import org.dms.wicket.repository.db.model.FileVersion;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.xaloon.wicket.component.exception.FileStorageException;
import org.xaloon.wicket.component.repository.FileRepository;
import org.xaloon.wicket.component.repository.util.RepositoryHelper;

/**
 * http://www.xaloon.org
 * 
 * @author vytautas racelis
 */
@Repository("fileRepository")
public class FileRepositoryImpl implements FileRepository {
    @Autowired
    private ContentSessionFacade contentSessionFacade;

    public FileDescription storeFile(String path, String name, String mimeType, InputStream fileStream)
            throws PathNotFoundException, RepositoryException, Exception {
        FileDescription filedesc = null;
        Session session = contentSessionFacade.getDefaultSession();
        Node rootNode = session.getRootNode();

        Node folder = (rootNode.hasNode(path)) ? rootNode.getNode(path)
                : RepositoryHelper.createFolder(session, path, rootNode);
        Node file = folder.addNode(name, JcrConstants.NT_FILE);
        file.addMixin(JcrConstants.MIX_REFERENCEABLE);
        Node fileContent = file.addNode(JcrConstants.JCR_CONTENT, JcrConstants.NT_RESOURCE);
        fileContent.setProperty(JcrConstants.JCR_MIMETYPE, mimeType);
        final Calendar lastModified = Calendar.getInstance();
        lastModified.setTimeInMillis(System.currentTimeMillis());
        fileContent.setProperty(JcrConstants.JCR_LASTMODIFIED, lastModified);
        fileContent.setProperty(JcrConstants.JCR_DATA, fileStream);
        session.save();
        final String uuid = fileContent.getUUID();

        filedesc = new FileDescription();
        filedesc.setLastModified(lastModified.getTime());
        filedesc.setMimeType(mimeType);
        filedesc.setPath(path);
        filedesc.setName(name);
        filedesc.setUUID(uuid);

        return filedesc;
    }

    public FileDescription storeFileVersion(String path, String name, String mimeType, InputStream fileStream)
            throws NoSuchNodeTypeException, VersionException, ConstraintViolationException, LockException,
            RepositoryException, Exception {
        FileDescription filedesc = null;
        Session session = contentSessionFacade.getDefaultSession();
        Node rootNode = session.getRootNode();

        Node folder = (rootNode.hasNode(path)) ? rootNode.getNode(path)
                : RepositoryHelper.createFolder(session, path, rootNode);
        Node file = folder.addNode(name, JcrConstants.NT_FILE);
        file.addMixin(JcrConstants.MIX_VERSIONABLE);

        Node fileContent = file.addNode(JcrConstants.JCR_CONTENT, JcrConstants.NT_RESOURCE);
        fileContent.setProperty(JcrConstants.JCR_MIMETYPE, mimeType);
        final Calendar lastModified = Calendar.getInstance();
        lastModified.setTimeInMillis(System.currentTimeMillis());
        fileContent.setProperty(JcrConstants.JCR_LASTMODIFIED, lastModified);
        fileContent.setProperty(JcrConstants.JCR_DATA, fileStream);
        session.save();
        final Version version = file.checkin();

        filedesc = new FileDescription();
        filedesc.setLastModified(lastModified.getTime());
        filedesc.setMimeType(mimeType);
        filedesc.setPath(path);
        filedesc.setName(name);
        filedesc.setUUID(fileContent.getUUID());
        filedesc.setFileVersion(version.getName());
        // filedesc.setSize(file.getNode("jcr:content").getProperty("jcr:data").getLength());

        return filedesc;
    }

    public void storeNextVersion(FileDescription latestVersion, InputStream fileStream)
            throws ValueFormatException, VersionException, LockException, ConstraintViolationException,
            PathNotFoundException, RepositoryException {
        final String pathLatestVersion = latestVersion.getFilePath();
        Node rootNode = contentSessionFacade.getDefaultSession().getRootNode();
        if (rootNode.hasNode(pathLatestVersion)) {
            final Node childNode = rootNode.getNode(pathLatestVersion);
            childNode.checkout();
            childNode.getNode(JcrConstants.JCR_CONTENT).setProperty(JcrConstants.JCR_DATA, fileStream);
            final Calendar lastModified = Calendar.getInstance();
            lastModified.setTimeInMillis(System.currentTimeMillis());
            childNode.getNode(JcrConstants.JCR_CONTENT).setProperty(JcrConstants.JCR_LASTMODIFIED, lastModified);
            childNode.save();
            final Version version = childNode.checkin();

            latestVersion.setFileVersion(version.getName());
            latestVersion.setLastModified(lastModified.getTime());
        }
    }

    public void restoreVersion(FileDescription file, String verName) throws RepositoryException

    {
        final String pathLatestVersion = file.getFilePath();
        Node rootNode = contentSessionFacade.getDefaultSession().getRootNode();
        if (rootNode.hasNode(pathLatestVersion)) {
            Node node = rootNode.getNode(pathLatestVersion);
            node.restore(verName, true);
            Version restoreVersion = node.checkin();

            file.setFileVersion(restoreVersion.getName());
            file.setLastModified(restoreVersion.getCreated().getTime());

        }
    }

    public void removeFileVersion(String path, String versionName)
            throws PathNotFoundException, RepositoryException {
        Node rootNode = contentSessionFacade.getDefaultSession().getRootNode();
        Node file = rootNode.getNode(path);
        file.checkout();
        VersionHistory history = file.getVersionHistory();
        history.removeVersion(versionName);
        file.checkin();
    }

    public List<FileVersion> getFileVersions(String path) throws RepositoryException {
        final List<FileVersion> versions = new ArrayList<FileVersion>();
        Node rootNode = contentSessionFacade.getDefaultSession().getRootNode();
        Node file = rootNode.getNode(path);

        VersionHistory history = file.getVersionHistory();
        VersionIterator ite = history.getAllVersions();
        while (ite.hasNext()) {

            Version ver = (Version) ite.next();
            if (!ver.getName().equalsIgnoreCase(JcrConstants.JCR_ROOTVERSION)) {
                versions.add(new FileVersion(ver.getCreated().getTime(), ver.getName()));
            }
        }

        return versions;
    }

    public InputStream retrieveFile(String pathToFile)
            throws PathNotFoundException, ValueFormatException, RepositoryException {
        Node rootNode = contentSessionFacade.getDefaultSession().getRootNode();
        if (rootNode.hasNode(pathToFile)) {
            Node file = rootNode.getNode(pathToFile);
            return file.getNode(JcrConstants.JCR_CONTENT).getProperty(JcrConstants.JCR_DATA).getStream();
        }
        return null;
    }

    public InputStream retrieveFileByUUID(String uuid)
            throws ValueFormatException, PathNotFoundException, RepositoryException {
        if (!org.apache.commons.lang.StringUtils.isEmpty(uuid)) {
            Node fileContent = contentSessionFacade.getDefaultSession().getNodeByUUID(uuid);
            return fileContent.getProperty(JcrConstants.JCR_DATA).getStream();
        }
        return null;
    }

    public InputStream retrieveFile(String path, Map<String, String> attr)
            throws ValueFormatException, PathNotFoundException, RepositoryException {
        Node rootNode = contentSessionFacade.getDefaultSession().getRootNode();
        if (rootNode.hasNode(path)) {
            Node fileContent = rootNode.getNode(path);
            attr.put("mimetype", fileContent.getNode(JcrConstants.JCR_CONTENT)
                    .getProperty(JcrConstants.JCR_MIMETYPE).getString());
            attr.put("filename", RepositoryHelper.getFileName(fileContent.getPath()));

            return fileContent.getNode(JcrConstants.JCR_CONTENT).getProperty(JcrConstants.JCR_DATA).getStream();
        }
        return null;
    }

    public List<FileDescription> searchFiles(String searchPath) throws FileStorageException {
        List<FileDescription> result = new ArrayList<FileDescription>();
        try {
            Session session = contentSessionFacade.getDefaultSession();
            if (!session.getRootNode().hasNode(searchPath)) {
                return result;
            }
            Node node = session.getRootNode().getNode(searchPath);
            NodeIterator ni = node.getNodes();
            while (ni.hasNext()) {
                Node file = ni.nextNode();
                if (isFile(file)) {
                    FileDescription desc = new FileDescription();
                    desc.setPath(file.getPath());
                    desc.setName(file.getName());
                    desc.setLastModified(file.getNode(JcrConstants.JCR_CONTENT)
                            .getProperty(JcrConstants.JCR_LASTMODIFIED).getDate().getTime());
                    desc.setMimeType(file.getNode(JcrConstants.JCR_CONTENT).getProperty(JcrConstants.JCR_MIMETYPE)
                            .getString());
                    desc.setSize(
                            file.getNode(JcrConstants.JCR_CONTENT).getProperty(JcrConstants.JCR_DATA).getLength());
                    result.add(desc);
                }
            }
        } catch (Exception e) {
            throw new FileStorageException("Error while searching files", e);
        }
        return result;
    }

    public List<FileDescription> searchFileByKeyword(String path, String keyword)
            throws InvalidQueryException, RepositoryException {
        List<FileDescription> result = new ArrayList<FileDescription>();

        Session session = contentSessionFacade.getDefaultSession();
        if (!session.getRootNode().hasNode(path)) {
            return result;
        }
        QueryManager qmanager = session.getWorkspace().getQueryManager();
        Query query = qmanager.createQuery("//*[jcr:contains(.,'" + keyword + "')]", Query.XPATH);
        QueryResult qresult = query.execute();

        NodeIterator ni = qresult.getNodes();
        while (ni.hasNext()) {
            Node file = ni.nextNode();
            if (isFile(file)) {
                final FileDescription desc = new FileDescription();
                desc.setPath(file.getPath());
                desc.setName(file.getName());
                desc.setLastModified(file.getNode(JcrConstants.JCR_CONTENT)
                        .getProperty(JcrConstants.JCR_LASTMODIFIED).getDate().getTime());
                desc.setMimeType(
                        file.getNode(JcrConstants.JCR_CONTENT).getProperty(JcrConstants.JCR_MIMETYPE).getString());
                desc.setSize(file.getNode(JcrConstants.JCR_CONTENT).getProperty(JcrConstants.JCR_DATA).getLength());
                result.add(desc);
            }
        }

        return result;
    }

    private boolean isFile(Node file) {
        try {
            return JcrConstants.NT_FILE.equals(file.getPrimaryNodeType().getName());
        } catch (RepositoryException e) {
            throw new FileStorageException("Error while checking for a file", e);
        }
    }

    public void delete(String path) throws PathNotFoundException, RepositoryException {
        if (!org.apache.commons.lang.StringUtils.isEmpty(path)) {
            Session session = contentSessionFacade.getDefaultSession();
            Node nodeToRemove = session.getRootNode().getNode(path);

            if (nodeToRemove != null) {
                nodeToRemove.remove();
                session.save();
            }

        }
    }

    public boolean existsFile(String name) throws FileStorageException {
        try {
            Node root = contentSessionFacade.getDefaultSession().getRootNode();
            return root.hasNode(name)
                    && JcrConstants.NT_FILE.equalsIgnoreCase(root.getNode(name).getPrimaryNodeType().getName());
        } catch (Exception e) {
            throw new FileStorageException("Error while checking file", e);
        }
    }

    public List<String> searchFolders(String searchPath) throws FileStorageException {
        List<String> result = new ArrayList<String>();
        try {
            Session session = contentSessionFacade.getDefaultSession();
            if (!session.getRootNode().hasNode(searchPath)) {
                return result;
            }
            Node node = session.getRootNode().getNode(searchPath);
            NodeIterator ni = node.getNodes();
            while (ni.hasNext()) {
                Node item = ni.nextNode();
                if (!isFile(item)) {
                    result.add(item.getName());
                }
            }
        } catch (Exception e) {
            throw new FileStorageException("Error while searching files", e);
        }
        return result;
    }

    public void crateJcrWorkspace(String wsname)
            throws AccessDeniedException, UnsupportedRepositoryOperationException, RepositoryException {

        final WorkspaceImpl ws = (WorkspaceImpl) contentSessionFacade.getDefaultSession().getWorkspace();
        ws.createWorkspace(wsname);
    }

    public void createRepositoryNodes(String paths) throws Exception {
        final Session session = contentSessionFacade.getDefaultSession();
        final Node rootNode = contentSessionFacade.getDefaultSession().getRootNode();

        if (!rootNode.hasNode(paths)) {
            Node createNode = RepositoryHelper.createFolder(session, paths, rootNode);
            createNode.save();
        }
    }

    public void exportSystemView(String path, String exportFile)
            throws PathNotFoundException, IOException, RepositoryException {
        final File file = new File(exportFile);
        final FileOutputStream out = new FileOutputStream(file);
        contentSessionFacade.getDefaultSession().exportSystemView(path, out, true, false);
    }

    public void importXML(String importFile)
            throws PathNotFoundException, ItemExistsException, ConstraintViolationException, VersionException,
            InvalidSerializedDataException, LockException, IOException, RepositoryException, Exception

    {
        final FileInputStream file = new FileInputStream(importFile);
        Session session = contentSessionFacade.getDefaultSession();
        session.importXML("/", file, ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING);
        session.save();
    }

    public void importXML(InputStream fileStream)
            throws PathNotFoundException, ItemExistsException, ConstraintViolationException, VersionException,
            InvalidSerializedDataException, LockException, IOException, RepositoryException, Exception

    {
        Session session = contentSessionFacade.getDefaultSession();
        session.importXML("/", fileStream, ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING);
        session.save();
    }

    public void performGC() throws FileStorageException {
        try {
            SessionImpl si = (SessionImpl) contentSessionFacade.getDefaultSession();
            GarbageCollector gc = si.createDataStoreGarbageCollector();
            // optional (if you want to implement a progress bar / output):
            //gc.setScanEventListener(this);
            gc.scan();
            gc.stopScan();
            // delete old data
            gc.deleteUnused();
        } catch (RepositoryException e) {
            throw new FileStorageException("Error performing GC", e);
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ItemStateException e) {
            e.printStackTrace();
        }
    }

    public void renameNode(String path, String newName) throws FileStorageException, RepositoryException {
        Node rootnode = contentSessionFacade.getDefaultSession().getRootNode();
        if (rootnode.hasNode(path)) {
            throw new FileStorageException("Cannot find file path");
        }
        Node node = rootnode.getNode(path);
        renameNode(node, newName);
    }

    public void lockFileNode(String path) throws PathNotFoundException, RepositoryException {
        Node rootnode = contentSessionFacade.getDefaultSession().getRootNode();
        Node nodeToLock = rootnode.getNode(path);
        nodeToLock.checkout();
        nodeToLock.lock(true, true);
        nodeToLock.checkin();
    }

    public void unlockFileNode(String path) throws PathNotFoundException, RepositoryException {
        Node rootnode = contentSessionFacade.getDefaultSession().getRootNode();
        Node nodeToLock = rootnode.getNode(path);
        nodeToLock.checkout();
        nodeToLock.unlock();
        nodeToLock.checkin();
    }

    private void renameNode(Node node, String newName) throws RepositoryException {
        node.getSession().move(node.getPath(), node.getParent().getPath() + "/" + newName);
    }

    /**
     * Needed for xml base injection
     * @param contentSessionFacade
     */
    public void setContentSessionFacade(ContentSessionFacade contentSessionFacade) {
        this.contentSessionFacade = contentSessionFacade;
    }

}