Package ca.simplegames.micro.repositories

Source Code of ca.simplegames.micro.repositories.Repository

/*
* Copyright (c)2012. Florin T.PATRASCU
*
* 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 ca.simplegames.micro.repositories;

import ca.simplegames.micro.Globals;
import ca.simplegames.micro.MicroContext;
import ca.simplegames.micro.SiteContext;
import ca.simplegames.micro.View;
import ca.simplegames.micro.cache.MicroCache;
import ca.simplegames.micro.cache.MicroCacheException;
import ca.simplegames.micro.templates.TemplateEnginesManager;
import ca.simplegames.micro.utils.IO;
import ca.simplegames.micro.utils.PathUtilities;
import ca.simplegames.micro.viewers.ViewRenderer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.yaml.snakeyaml.Yaml;

import java.io.*;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;

/**
* A Repository is responsible for identifying resources in a given folder and it can be used
* as a context helper for accessing a specific resource, rendered or not
*
* @author <a href="mailto:florin.patrascu@gmail.com">Florin T.PATRASCU</a>
* @since $Revision$ (created: 2012-12-20 1:58 PM)
*/
public abstract class Repository {
    public static final String VIEW_CACHE_KEY_FORMAT = "%s::%s";
    private Logger log;

    private String name;
    private MicroCache cache;
    private SiteContext site;
    private String pathName;
    private File path;
    private ViewRenderer renderer;
    private File config;
    private boolean isDefault;
    private Map<String, ViewConfigElements> viewConfigPathMap = new HashMap<String, ViewConfigElements>();

    /**
     * creates a new Repository object
     *
     * @param name           the name of the repository
     * @param cache          a dedicated cache
     * @param site           the SiteContext of the app
     * @param pathName       the path to the root of the repository
     * @param configPathName the folder name of the config folder (if any)
     * @param engineName     the template engine name used by default when not specified by the user
     */
    protected Repository(String name, MicroCache cache, SiteContext site, String pathName, String configPathName, String engineName) {
        this.name = name;
        log = LoggerFactory.getLogger("Repository::" + name.toUpperCase());

        this.cache = cache;
        this.site = site;

        this.pathName = pathName;
        path = new File(pathName);
        if (!path.exists()) {
            path = new File(site.getWebInfPath(), pathName);
        }

        if (path.exists()) {

            if (configPathName != null) {
                config = new File(path, configPathName);
            }

            final TemplateEnginesManager templateEnginesManager = site.getTemplateEnginesManager();
            renderer = engineName != null ?
                    templateEnginesManager.getEngine(engineName) :
                    templateEnginesManager.getDefaultEngine();

            site.getLog().info(String.format(" ** '%s'", name));
            site.getLog().info(String.format("   - path....: '%s'", path.getAbsolutePath()));
            site.getLog().info(String.format("   - renderer: '%s'", renderer.getName()));

            if (cache != null) {
                site.getLog().info(String.format("   - cache...: '%s'", cache.getName()));
            }
            if (config != null && config.exists() && config.isDirectory()) {
                site.getLog().info(String.format("   - config..: '%s'", config.getAbsolutePath()));
            }


        } else {
            log.error(String.format("You defined a repository: '%s' on: %s, but there is no content at that path; %s",
                    name, pathName, path.getAbsolutePath()));
        }
        //
    }

    public File getPath() {
        return path;
    }

    public abstract InputStream getInputStream(String name) throws Exception;

    public MicroCache getCache() {
        return cache;
    }

    public void setRenderer(ViewRenderer renderer) {
        this.renderer = renderer;
    }

    public void setIsDefault(boolean isDefault) {
        this.isDefault = isDefault;
    }

    public boolean isDefault() {
        return isDefault;
    }

    public SiteContext getSite() {
        return site;
    }

    public Logger getLog() {
        return log;
    }

    public String getName() {
        return name;
    }

    public String getPathName() {
        return pathName;
    }

    public RepositoryWrapper getRepositoryWrapper(MicroContext context) {
        return new RepositoryWrapper(this, context);
    }

    public ViewRenderer getRenderer() {
        return renderer;
    }

    public long getLastModified(String name) {
        return pathToFile(name).lastModified();
    }

    public File pathToFile(String name) {
        return new File(getPath(), name);
    }

    public String read(String path) throws Exception {
        String content = null;

        if (path != null) {
            final File file = pathToFile(path);

            if (cache != null) {
                content = (String) cache.get(file.getAbsolutePath());
            }

            if (content == null) {
                if (file.exists()) {
                    final Reader reader = getReader(path);

                    content = IO.getString(reader);
                    if (cache != null) {
                        cache.put(file.getAbsolutePath(), content);
                    }
                } else {
                    throw new FileNotFoundException(file.getAbsolutePath());
                }
            }
        }
        return content;
    }

    /**
     * obtain a Reader from the path.
     * Mr. Developer - please don't forget to close it if you're using it.
     * You can use {@link IO}.close, for example
     *
     * @param path the path to a resource in this repository
     * @return the Reader or null if the path is null
     * @throws Exception a File not found exception if there is no such a resource
     */
    public Reader getReader(String path, Charset encoding) throws Exception {

        if (path != null) {
            final File file = pathToFile(path);
            if (file.exists()) {
                return new InputStreamReader(new FileInputStream(file), encoding);
            } else {
                throw new FileNotFoundException(file.getAbsolutePath());
            }
        }
        return null;
    }

    public Reader getReader(String path) throws Exception {
        return getReader(path, Charset.forName(Globals.UTF8));
    }

    /**
     * @param name a resource name; a view template name
     * @return a {@link View} instance
     */
    @SuppressWarnings("unchecked")
    public View getView(String name) {
        if (config != null) {
            ViewConfigElements viewConfigElements = viewConfigPathMap.get(name);

            if (viewConfigElements == null) {
                File viewConfig = new File(config, PathUtilities.extractViewPath(name) + Globals.YML_EXTENSION);
                viewConfigElements = new ViewConfigElements(viewConfig.getAbsolutePath(), viewConfig.exists());
                viewConfigPathMap.put(name, viewConfigElements);
            }

            String key = String.format(VIEW_CACHE_KEY_FORMAT, getName(), name);
            Map viewModel = null;

            // don't hit the cache unnecessarily if the config was never there!
            if (cache != null && viewConfigElements.isConfigFileExists()) {
                try {
                    viewModel = (Map) cache.get(key);
                } catch (MicroCacheException e) {
                    log.error(String.format("Cannot cache the view: %s", viewConfigElements.getConfigFullPath()));
                    e.printStackTrace();
                }
            }

            // there is no ViewModel if the config file doesn't exist
            if (viewModel == null && viewConfigElements.isConfigFileExists()) {
                try {
                    viewModel = (Map) new Yaml().load(
                            new FileInputStream(new File(viewConfigElements.getConfigFullPath())));
                    if (cache != null) {
                        try {
                            cache.put(key, viewModel);
                        } catch (MicroCacheException e) {
                            log.error(String.format("Cannot use the cache for retrieving this view: %s",
                                    viewConfigElements.getConfigFullPath()));
                            e.printStackTrace();
                        }
                    }
                } catch (FileNotFoundException e) {
                    log.error("cannot load the configuration from: " + name);
                    e.printStackTrace();
                }
            }

            if (viewModel != null) {
                return new View(viewModel);
            }
        }
        return null;
    }

    /**
     * internal class used as a shortcut to avoid File name calculations; a performance optimization
     */
    class ViewConfigElements {
        private String configFullPath;
        private boolean configFileExists = false;

        ViewConfigElements(String configFullPath, boolean configFileExists) {
            this.configFullPath = configFullPath;
            this.configFileExists = configFileExists;
        }

        public String getConfigFullPath() {
            return configFullPath;
        }

        public boolean isConfigFileExists() {
            return configFileExists;
        }
    }
}
TOP

Related Classes of ca.simplegames.micro.repositories.Repository

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.