com.sastix.cms.server.services.content.impl.ZipFileHandlerServiceImpl.java Source code

Java tutorial

Introduction

Here is the source code for com.sastix.cms.server.services.content.impl.ZipFileHandlerServiceImpl.java

Source

/*
 * Copyright(c) 2017 the original author or authors.
 *
 * 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 com.sastix.cms.server.services.content.impl;

import com.sastix.cms.server.dataobjects.DataMaps;
import com.sastix.cms.server.services.content.GeneralFileHandlerService;
import com.sastix.cms.server.services.content.ZipFileHandlerService;
import org.apache.tika.Tika;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.parser.Parser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.json.GsonJsonParser;
import org.springframework.stereotype.Service;

import java.io.*;
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

@Service
public class ZipFileHandlerServiceImpl implements ZipFileHandlerService {

    private Logger LOG = (Logger) LoggerFactory.getLogger(ZipFileHandlerServiceImpl.class);
    String acceptedExtensions = "html, htm, js, css";

    private final Tika tika = new Tika();
    GsonJsonParser gsonJsonParser = new GsonJsonParser();

    public static final String METADATA_XML_FILE = "imsmanifest.xml";
    public static final String METADATA_JSON_FILE = "info.json";
    public static final String METADATA_STARTPAGE = "startpage";
    public static final String METADATA_STARTPAGE_CAMEL = "startPage";

    @Autowired
    GeneralFileHandlerService generalFileHandlerService;

    @Override
    public DataMaps unzip(byte[] bytes) throws IOException {
        Map<String, String> foldersMap = new HashMap<>();

        Map<String, byte[]> extractedBytesMap = new HashMap<>();
        InputStream byteInputStream = new ByteArrayInputStream(bytes);
        //validate that it is a zip file
        if (isZipFile(bytes)) {
            try {
                //get the zip file content
                ZipInputStream zis = new ZipInputStream(byteInputStream);
                //get the zipped file list entry
                ZipEntry ze = zis.getNextEntry();

                while (ze != null) {
                    String fileName = ze.getName();
                    if (!ze.isDirectory()) {//if entry is a directory, we should not add it as a file
                        ByteArrayOutputStream baos = new ByteArrayOutputStream();
                        try {
                            ByteBuffer bufIn = ByteBuffer.allocate(1024);
                            int bytesRead;
                            while ((bytesRead = zis.read(bufIn.array())) > 0) {
                                baos.write(bufIn.array(), 0, bytesRead);
                                bufIn.rewind();
                            }
                            bufIn.clear();
                            extractedBytesMap.put(fileName, baos.toByteArray());
                        } finally {
                            baos.close();
                        }
                    } else {
                        foldersMap.put(fileName, fileName);
                    }
                    ze = zis.getNextEntry();
                }
                zis.closeEntry();
                zis.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        DataMaps dataMaps = new DataMaps();
        dataMaps.setBytesMap(extractedBytesMap);
        dataMaps.setFoldersMap(foldersMap);
        return dataMaps;
    }

    @Override
    public boolean isZipFile(byte[] bytes) throws IOException {
        String type = tika.detect(bytes);
        return type.toLowerCase().contains("zip");
    }

    @Override
    public boolean isScormType(Map<String, byte[]> bytesMap) {
        byte[] dataXml = bytesMap.get(METADATA_XML_FILE);
        if (dataXml == null) {
            return false;
        } else {
            String xml = "";
            String ret = "";
            try {
                xml = new String(dataXml, "UTF-8");
            } catch (UnsupportedEncodingException e) {
                LOG.error("Error in determining if it is a scorm type: {}", e.getLocalizedMessage());
            }
            Document doc = Jsoup.parse(xml, "", Parser.xmlParser());
            for (Element e : doc.select("resources")) {
                ret = e.select("resource").get(0).attr("adlcp:scormType");
            }
            return ret.equals("sco");
        }
    }

    @Override
    public String getResourceStartPage(Map<String, byte[]> bytesMap) {
        byte[] dataJson = bytesMap.get(METADATA_JSON_FILE);
        String json = "";
        if (dataJson == null) {
            return null;
        }
        try {
            json = new String(dataJson, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            LOG.error("Error in determining if it is a cms zip resource: {}", e.getLocalizedMessage());
            return null;
        }

        Map<String, Object> map = gsonJsonParser.parseMap(json);

        String ret = null;
        if (map.get(METADATA_STARTPAGE) != null) {
            ret = (String) map.get(METADATA_STARTPAGE);
        } else if (map.get(METADATA_STARTPAGE_CAMEL) != null) {
            ret = (String) map.get(METADATA_STARTPAGE_CAMEL);
        }

        return ret;
    }

    @Override
    public String findParentResource(Map<String, byte[]> bytesMap) {
        byte[] dataXml = bytesMap.get(METADATA_XML_FILE);
        if (dataXml == null) {
            return null;
        }
        String xml = "";
        String ret = "";
        try {
            xml = new String(dataXml, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            LOG.error("Error in finding parent resource name: {}", e.getLocalizedMessage());
        }
        Document doc = Jsoup.parse(xml, "", Parser.xmlParser());
        for (Element e : doc.select("resources")) {
            ret = e.select("resource").get(0).attr("href");
        }
        return ret;
    }

    @Override
    @Deprecated
    public DataMaps replaceRelativePaths(DataMaps dataMaps) throws IOException {
        /**
         * TODO: check performance...
         * */
        Map<String, byte[]> modifiedBytesMap = new HashMap<>();
        for (Map.Entry<String, byte[]> entry : dataMaps.getBytesMap().entrySet()) {
            String filename = entry.getKey();
            byte[] bytes = entry.getValue();

            if (acceptedExtensions.contains(filename.substring(filename.lastIndexOf(".") + 1))) {
                String content = new String(bytes, "UTF-8");
                dataMaps.getBytesMap();
                for (String key : dataMaps.getBytesMap().keySet()) {
                    String replace = dataMaps.getUidPathMap().get(key);
                    content = content.replaceAll(key, replace);
                    content = content.replaceAll("(\\.\\.\\/)", "");
                    content = content.replaceAll("(\\.\\/)", "");
                }
                byte[] modifiedData = content.getBytes("UTF-8");
                modifiedBytesMap.put(filename, modifiedData);
            }
        }
        dataMaps.setModifiedBytesMap(modifiedBytesMap);
        return dataMaps;
    }
}