webhooks.core.services.impl.DocumentServiceImp.java Source code

Java tutorial

Introduction

Here is the source code for webhooks.core.services.impl.DocumentServiceImp.java

Source

/**
 * Copyright 2015 Workfront, Inc.
 *
 * 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 webhooks.core.services.impl;

import org.apache.commons.io.*;
import org.apache.tika.*;
import org.springframework.beans.factory.annotation.*;
import org.springframework.stereotype.*;
import webhooks.config.*;
import webhooks.core.models.entities.*;
import webhooks.core.repositories.*;
import webhooks.core.services.*;
import webhooks.core.services.exceptions.*;
import webhooks.core.services.util.*;

import javax.transaction.*;
import java.io.*;
import java.nio.file.*;
import java.util.*;

/**
 * Document service implementation
 */
@Service
@Transactional
public class DocumentServiceImp implements IDocumentService {

    @Autowired
    private IDocumentRepo documentRepo;

    @Override
    public Document getMetaData(String documentID) {
        String path = DocumentUtil.getLocationFromDocId(documentID);
        File targetFile = new File(path);
        if (targetFile.exists()) {
            try {
                Document doc = new Document();
                doc.setId(documentID);
                doc.setMimeType(new Tika().detect(targetFile));
                doc.setLocation(path);
                doc.setKind(targetFile.isFile() ? Document.TYPE_FILE : Document.TYPE_FOLDER);
                doc.setSize(targetFile.length());
                doc.setLastModified(targetFile.lastModified());
                doc.setName(targetFile.getName());

                return doc;
            } catch (IOException e) {
                return null;
            }
        }
        return null;
    }

    @Override
    public Document uploadStart(String parentDocumentId, String documentName) throws DocumentExistsException {
        String path = DocumentUtil.getLocationFromDocId(parentDocumentId);

        // make the path for the new document
        path += File.separator + documentName;
        File file = new File(path);
        if (file.exists())
            throw new DocumentExistsException(path);

        Document doc = new Document();
        doc.setKind(Document.TYPE_FILE);
        //doc.getMimeType();
        doc.setId(DocumentUtil.GenerateDocId(path));

        return doc;
    }

    @Override
    public boolean uploadEnd(String documentID, InputStream stream) {
        boolean ret = false;
        String path = DocumentUtil.getLocationFromDocId(documentID);

        File targetFile = null;

        try {
            // check the path
            targetFile = new File(path);
            if (targetFile.exists()) {
                throw new DocumentExistsException();
            }

            if (targetFile.createNewFile()) {
                byte[] bytes = new byte[2048];
                int bytesRead = 0;
                BufferedOutputStream os = new BufferedOutputStream(new FileOutputStream(targetFile));
                while ((bytesRead = stream.read(bytes)) != -1) {
                    os.write(bytes, 0, bytesRead);
                }
                os.flush();
                os.close();

                ret = true;
            }
        } catch (Exception e) {
            if (targetFile != null && targetFile.exists()) {
                targetFile.delete();
            }
        }

        return ret;
    }

    @Override
    public DocumentList getFiles(String parentDocumentId, int max, int offset) {
        String path = DocumentUtil.getLocationFromDocId(parentDocumentId);
        return listFilesForFolder(new File(path), max, offset);
    }

    @Override
    public Document getDocumentByID(String documentId) {
        //return documentRepo.findDocumentByID(documentId);
        //implement without database for this case
        String path = DocumentUtil.getLocationFromDocId(documentId);
        File entry = new File(path);
        return convertToDocument(entry);
    }

    @Override
    public DocumentList findAllDocuments() {
        List<Document> documentList = documentRepo.findAllDocuments();
        return new DocumentList(documentList);
    }

    /**
     *   return all documents/folder from published paths
     * @param max
     * @param offset
     * @return
     */
    @Override
    public DocumentList getRootFiles(int max, int offset) {
        List<Document> finalList = new ArrayList<Document>();

        DocumentList ret = null;
        int oldMax = max;

        for (String path : ConfigBean.getInstance().getPaths()) {
            try {
                String normalize = FilenameUtils.normalize(path);
                if (normalize.startsWith("~/")) {
                    normalize = System.getProperty("user.home") + normalize.substring(1);
                } else if (normalize.startsWith("~")) {
                    normalize = System.getProperty("user.home") + File.separator + normalize.substring(1);
                }

                ret = listFilesForFolder(new File(normalize), max, offset);
                if (ret.getDocuments().size() > 0) {
                    finalList.addAll(finalList.size(), ret.getDocuments());
                    offset = 0;
                    max = max - ret.getDocuments().size();
                }

                if (finalList.size() == oldMax)
                    break;

            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return new DocumentList(finalList);
    }

    @Override
    public DocumentList findFiles(String query, int max, int offset) {
        List<Document> finalList = new ArrayList<Document>();

        List<Document> ret = null;
        int oldMax = max;

        for (String path : ConfigBean.getInstance().getPaths()) {
            try {
                String normalize = FilenameUtils.normalize(path);
                if (normalize.startsWith("~/")) {
                    normalize = System.getProperty("user.home") + normalize.substring(1);
                } else if (normalize.startsWith("~")) {
                    normalize = System.getProperty("user.home") + File.separator + normalize.substring(1);
                }

                ret = traverse(normalize, query, max, offset);
                if (ret.size() > 0) {
                    finalList.addAll(finalList.size(), ret);
                    offset = 0;
                    max = max - ret.size();
                }

                if (finalList.size() == oldMax)
                    break;

            } catch (Exception e) {

            }
        }

        return new DocumentList(finalList);
    }

    public List<Document> traverse(String path, String query, int max, int offset) {
        Path startingDir = Paths.get(path);
        List<Document> resList = new ArrayList<Document>();
        int skipped = 0;

        FileFinder fileFinder = new FileFinder(query, max, offset);
        try {
            Files.walkFileTree(startingDir, fileFinder);
            ArrayList<File> files = fileFinder.getMatched();
            for (final File fileEntry : files) {
                if (resList.size() == max)
                    break;

                if (skipped < offset) {
                    skipped++;
                    continue;
                }

                Document doc = convertToDocument(fileEntry);
                if (doc != null) {
                    resList.add(doc);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        return resList;
    }

    @Override
    public Document addDocument(Document data) {
        return documentRepo.createDocument(data);
    }

    private DocumentList listFilesForFolder(final File folder, int max, int offset) {
        List<Document> resList = new ArrayList<Document>();
        int skipped = 0;

        if (folder.exists()) {
            for (final File fileEntry : folder.listFiles()) {
                if (max > 0 && resList.size() == max)
                    break;

                if (skipped < offset) {
                    skipped++;
                    continue;
                }

                Document doc = convertToDocument(fileEntry);
                if (doc != null)
                    resList.add(doc);
            }
        }
        return new DocumentList(resList);
    }

    // use apache tika to detect mime type. the java implementation probContentType always returned null for OSX?????
    private String getMimeType(Path path) throws IOException {
        Tika tika = new Tika();
        return tika.detect(path.toFile());
    }

    private Document convertToDocument(File fileEntry) {
        Document doc = null;
        if (!fileEntry.isHidden()) {
            doc = new Document();
            doc.setName(fileEntry.getName());
            //doc.setLocation(fileEntry.getPath());
            String now = String.valueOf(new Date().getTime());
            // fullpath + # + timestamp(long)
            doc.setId(CipherUtil.encrypt(fileEntry.getPath() + "#" + now));
            // get mime type of a document
            if (fileEntry.isFile()) {
                try {
                    String mimeType = getMimeType(fileEntry.toPath());
                    doc.setMimeType(mimeType);
                } catch (IOException e) {
                    e.printStackTrace();
                }

                doc.setSize(fileEntry.length());
                doc.setKind(Document.TYPE_FILE);
            } else {
                doc.setKind(Document.TYPE_FOLDER);
            }
            doc.setLastModified(fileEntry.lastModified());
        }

        return doc;
    }
}