All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.astamuse.asta4d.template.TemplateResolver Maven / Gradle / Ivy

Go to download

core functionalities of asta4d framework, including template and snippt implemention

There is a newer version: 1.2-M2
Show newest version
/*
 * Copyright 2012 astamuse company,Ltd.
 * 
 * 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.astamuse.asta4d.template;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.astamuse.asta4d.Configuration;
import com.astamuse.asta4d.Context;
import com.astamuse.asta4d.template.TemplateResolver.TemplateInfo;
import com.astamuse.asta4d.util.MultiSearchPathResourceLoader;
import com.astamuse.asta4d.util.i18n.LocalizeUtil;

//TODO internationalization
public abstract class TemplateResolver extends MultiSearchPathResourceLoader {

    private final static ConcurrentHashMap defaultCachedTemplateMap = new ConcurrentHashMap();

    private static Template NotFoundHolder;

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    private Map getCachedTemplateMap() {
        Context context = Context.getCurrentThreadContext();
        Configuration conf = Configuration.getConfiguration();
        if (conf.isCacheEnable()) {
            return defaultCachedTemplateMap;
        } else {
            // for debug, if we do not cache it in context, some templates will
            // be probably initialized for hundreds times
            // thus there will be hundreds logs of template initializing in info
            // level.
            String key = TemplateResolver.class.getName() + "##template-cache-map";
            Map contextCachedMap = context.getData(key);
            if (contextCachedMap == null) {
                contextCachedMap = new ConcurrentHashMap<>();
                context.setData(key, contextCachedMap);
            }
            return contextCachedMap;
        }
    }

    private static Template getNotFoundHolder() throws TemplateException, TemplateNotFoundException {
        if (NotFoundHolder == null) {
            String dummyHolderContent = "##NOT-FOUND-HOLDER##";
            NotFoundHolder = new Template(dummyHolderContent, new ByteArrayInputStream(dummyHolderContent.getBytes()));
        }
        return NotFoundHolder;
    }

    /**
     * 
     * @param path
     * @return
     * @throws TemplateException
     *             error occurs when parsing template file
     * @throws TemplateNotFoundException
     *             template file does not exist
     */
    public Template findTemplate(String path) throws TemplateException, TemplateNotFoundException {
        try {

            Map cachedTemplateMap = getCachedTemplateMap();

            Locale locale = Context.getCurrentThreadContext().getCurrentLocale();
            String cacheKey = LocalizeUtil.createLocalizedKey(path, locale);
            Template t = cachedTemplateMap.get(cacheKey);
            if (t != null) {
                if (t == NotFoundHolder) {
                    throw new TemplateNotFoundException(path);
                } else {
                    return t;
                }
            }
            logger.info("Initializing template " + path);
            TemplateInfo info = searchResource("/", LocalizeUtil.getCandidatePaths(path, locale));
            if (info == null) {
                cachedTemplateMap.put(cacheKey, getNotFoundHolder());
                throw new TemplateNotFoundException(path);
            }
            InputStream input = info.getInput();
            if (input == null) {
                cachedTemplateMap.put(cacheKey, getNotFoundHolder());
                throw new TemplateNotFoundException(path);
            }
            try {
                t = new Template(info.getPath(), input);
            } finally {
                // we have to close the input stream to avoid file lock
                try {
                    input.close();
                } catch (Exception ex) {
                    logger.error("Error occured when close input stream of " + info.getPath(), ex);
                }
            }
            cachedTemplateMap.put(cacheKey, t);
            return t;
        } catch (TemplateNotFoundException e) {
            throw e;
        } catch (Exception e) {
            throw new TemplateException(path + " resolve error", e);
        }
    }

    protected TemplateInfo createTemplateInfo(String path, InputStream input) {
        if (input == null) {
            return null;
        }
        return new TemplateInfo(path, input);
    }

    public static class TemplateInfo {

        private final String path;

        private final InputStream input;

        private TemplateInfo(String path, InputStream input) {
            this.path = path;
            this.input = input;
        }

        private String getPath() {
            return path;
        }

        private InputStream getInput() {
            return input;
        }

    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy