Package org.apache.marmotta.platform.core.services.content

Source Code of org.apache.marmotta.platform.core.services.content.FileSystemContentWriter

/**
* 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.apache.marmotta.platform.core.services.content;

import static org.apache.marmotta.commons.sesame.repository.ExceptionUtils.handleRepositoryException;

import com.google.common.io.ByteStreams;
import com.google.common.io.Files;
import org.apache.marmotta.platform.core.api.config.ConfigurationService;
import org.apache.marmotta.platform.core.api.content.ContentWriter;
import org.apache.marmotta.platform.core.api.triplestore.SesameService;
import org.apache.marmotta.platform.core.model.content.MediaContentItem;

import org.apache.marmotta.commons.sesame.facading.FacadingFactory;
import org.apache.marmotta.kiwi.model.rdf.KiWiUriResource;
import org.openrdf.model.Resource;
import org.openrdf.repository.RepositoryConnection;
import org.openrdf.repository.RepositoryException;
import org.slf4j.Logger;
import sun.net.www.MimeEntry;
import sun.net.www.MimeTable;

import javax.annotation.PostConstruct;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.util.UUID;

/**
* A content writer that writes the content of a resource to the file system.
* It uses the kiwi:hasContentPath property to determine the destination path of the content to write to.
* <p/>
* Author: Sebastian Schaffert
*/
@ApplicationScoped
public class FileSystemContentWriter implements ContentWriter {

    @Inject
    private Logger log;


    @Inject
    private ConfigurationService configurationService;

    @Inject
    private SesameService sesameService;

    private String defaultDir;

    public FileSystemContentWriter() {
    }

    @PostConstruct
    public void initialise() {
        defaultDir = configurationService.getWorkDir()+File.separator+"resources";

        log.debug("FileSystem Content Writer started (default file location: {})",defaultDir);

        File dir = new File(defaultDir);
        if(!dir.exists() && !dir.mkdirs()) {
            log.warn("could not create default directory for file system storage of content (directory: {})",defaultDir);
        }
    }

    /**
     * Delete the content of the speficied mime type for the specified resource.
     *
     * @param resource the resource for which to delete the content
     * @param mimetype the mime type of the content to delete (optional)
     */
    @Override
    public void deleteContent(Resource resource, String mimetype) throws IOException {
        try {
            RepositoryConnection conn = sesameService.getConnection();
            try {
                MediaContentItem mci = FacadingFactory.createFacading(conn).createFacade(resource, MediaContentItem.class);

                String path = mci.getContentPath();
                if(path != null) {
                    if(!path.startsWith(defaultDir)) {
                        if(!configurationService.getBooleanConfiguration("content.filesystem.secure")) {
                            log.warn("accessing file {}, which is outside the default directory; this is a potential security risk; " +
                                    "enable the option content.filesystem.secure in the configuration",path);
                        } else {
                            throw new FileNotFoundException("the file "+path+" is outside the Apache Marmotta default directory location; access denied");
                        }
                    }

                    File file = new File(path);
                    if(file.exists() && file.canWrite()) {
                        log.info("deleting file {} for resource {} ...", file.getPath(), resource);
                        file.delete();
                    } else {
                        throw new FileNotFoundException("could not delete file "+path+"; it does not exist or is not writable");
                    }
                } else {
                    throw new FileNotFoundException("could not delete file content for resource "+resource+"; no content path has been specified for the resource");
                }
            } finally {
                conn.commit();
                conn.close();
            }
        } catch (RepositoryException ex) {
            handleRepositoryException(ex,FileSystemContentReader.class);
        }
    }

    /**
     * Return the name of the content reader. Used to identify and display the content reader to admin users.
     *
     * @return
     */
    @Override
    public String getName() {
        return "FileSystem Content Writer";
    }

    /**
     * Store the content of the specified mime type for the specified resource. Accepts a byte array containing
     * the byte data of the content that is then written to the destination configured for this writer.
     * <p/>
     *
     * @param resource the resource for which to store the content
     * @param mimetype the mime type of the content
     * @param data     a byte array containing the content of the resource
     */
    @Override
    public void setContentData(Resource resource, byte[] data, String mimetype) throws IOException {
        setContentStream(resource, new ByteArrayInputStream(data),mimetype);
    }

    /**
     * Store the content of the specified mime type for the specified resource. Accepts an input stream containing
     * the byte data of the content that is read and written to the destination configured for this writer.
     * <p/>
     * This method is preferrable for resources with large amounts of data.
     *
     * @param resource the resource for which to return the content
     * @param mimetype the mime type to retrieve of the content
     * @param in       a InputStream containing the content of the resource
     */
    @Override
    public void setContentStream(Resource resource, InputStream in, String mimetype) throws IOException {
        try {
            RepositoryConnection conn = sesameService.getConnection();
            try {
                MediaContentItem mci = FacadingFactory.createFacading(conn).createFacade(resource, MediaContentItem.class);

                String path = mci.getContentPath();

                if(path == null) {
                    if(resource instanceof KiWiUriResource && ((KiWiUriResource)resource).stringValue().startsWith("file:")) {
                        try {
                            URI uri = new URI(((KiWiUriResource)resource).stringValue());
                            path = uri.getPath();
                        } catch(Exception ex) {}
                    } else {
                        // we store all other resources in the default directory; create a random file name and store it in the hasContentLocation
                        // property
                        String extension = null;
                        MimeEntry entry = MimeTable.getDefaultTable().find(mimetype);
                        if(entry != null && entry.getExtensions().length > 0) {
                            extension = entry.getExtensions()[0];
                        }

                        String fileName = UUID.randomUUID().toString();
                        path = defaultDir + File.separator +
                                fileName.substring(0,2) + File.separator +
                                fileName.substring(2,4) + File.separator +
                                fileName.substring(4,6) + File.separator +
                                fileName + (extension != null ? extension : "");
                        mci.setContentPath(path);
                    }
                }

                if(path != null) {
                    if(!path.startsWith(defaultDir)) {
                        if(!configurationService.getBooleanConfiguration("content.filesystem.secure")) {
                            log.warn("accessing file {}, which is outside the default directory; this is a potential security risk; " +
                                    "enable the option content.filesystem.secure in the configuration",path);
                        } else {
                            throw new FileNotFoundException("the file "+path+" is outside the Apache Marmotta default directory location; access denied");
                        }
                    }

                    File file = new File(path);
                    if(!file.exists()) {
                        try {
                            file.getParentFile().mkdirs();
                            file.createNewFile();
                        } catch(IOException ex) {
                            throw new FileNotFoundException("could not create file "+path+"; it is not writable");
                        }
                    }
                    if(file.exists() && file.canWrite()) {
                        log.debug("writing file content to file {} for resource {} ...", file, resource);
                        ByteStreams.copy(in, Files.newOutputStreamSupplier(file));
                    } else {
                        throw new FileNotFoundException("could not write to file "+path+"; it does not exist or is not writable");
                    }



                } else {
                    throw new FileNotFoundException("could not write file content for resource "+resource+"; no content path has been specified for the resource");
                }
            } finally {
                conn.commit();
                conn.close();
            }
        } catch (RepositoryException ex) {
            handleRepositoryException(ex,FileSystemContentReader.class);
        }
    }
}
TOP

Related Classes of org.apache.marmotta.platform.core.services.content.FileSystemContentWriter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.