Package org.richfaces.skin

Source Code of org.richfaces.skin.AbstractSkinFactory$SkinBuilder

/*
* JBoss, Home of Professional Open Source
* Copyright 2013, Red Hat, Inc. and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.richfaces.skin;

import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

import javax.el.ELContext;
import javax.el.ExpressionFactory;
import javax.faces.application.Application;
import javax.faces.context.FacesContext;

import org.ajax4jsf.Messages;
import org.richfaces.el.util.ELUtils;
import org.richfaces.util.PropertiesUtil;

/**
* @author Nick Belaevski
*
*/
public abstract class AbstractSkinFactory extends SkinFactory {
    private final class SkinBuilder implements Callable<Skin> {
        private String skinName;

        SkinBuilder(String skinName) {
            super();
            this.skinName = skinName;
        }

        public Skin call() throws Exception {
            return buildSkin(FacesContext.getCurrentInstance(), skinName);
        }
    }

    /**
     * Resource Uri for properties file with default values of skin parameters.
     */
    private static final String DEFAULT_SKIN_PATH = "META-INF/skins/%s.skin.properties";
    // private static final String[] DEFAULT_SKIN_PATHS = { DEFAULT_SKIN_PATH };
    private static final String USER_SKIN_PATH = "%s.skin.properties";
    /**
     * Path in jar to pre-defined vendor and custom user-defined skins definitions. in this realisation "META-INF/skins/" for
     * vendor , "" - user-defined.
     */
    private static final String[] SKINS_PATHS = { DEFAULT_SKIN_PATH, USER_SKIN_PATH };
    private ConcurrentMap<String, FutureTask<Skin>> skins = new ConcurrentHashMap<String, FutureTask<Skin>>();

    protected void processProperties(FacesContext context, Map<Object, Object> properties) {
        ELContext elContext = context.getELContext();

        // replace all EL-expressions by prepared ValueBinding ?
        Application app = context.getApplication();

        for (Entry<Object, Object> entry : properties.entrySet()) {
            Object propertyObject = entry.getValue();

            if (propertyObject instanceof String) {
                String property = (String) propertyObject;

                if (ELUtils.isValueReference(property)) {
                    ExpressionFactory expressionFactory = app.getExpressionFactory();

                    entry.setValue(expressionFactory.createValueExpression(elContext, property, Object.class));
                } else {
                    entry.setValue(property);
                }
            }
        }
    }

    /**
     * Factory method for build skin from properties files. for given skin name, search in classpath all resources with name
     * 'name'.skin.properties and append in content to default properties. First, get it from META-INF/skins/ , next - from root
     * package. for any place search order determined by {@link java.lang.ClassLoader } realisation.
     *
     * @param name name for builded skin.
     * @param context
     * @return skin instance for current name
     * @throws SkinNotFoundException - if no skin properies found for name.
     */
    protected Skin buildSkin(FacesContext context, String name) throws SkinNotFoundException {
        Properties skinParams = loadProperties(name, SKINS_PATHS);
        processProperties(context, skinParams);

        return new SkinImpl(skinParams, name);
    }

    /**
     * @param name
     * @param paths
     * @return properties
     * @throws SkinNotFoundException
     */
    protected Properties loadProperties(String name, String[] paths) throws SkinNotFoundException {
        // Get properties for concrete skin.
        Properties skinProperties = new Properties();
        int loadedPropertiesCount = 0;

        for (int i = 0; i < paths.length; i++) {
            String skinPropertiesLocation = paths[i].replaceAll("%s", name);

            if (PropertiesUtil.loadProperties(skinProperties, skinPropertiesLocation)) {
                loadedPropertiesCount++;
            }
        }

        if (loadedPropertiesCount == 0) {
            throw new SkinNotFoundException(Messages.getMessage(Messages.SKIN_NOT_FOUND_ERROR, name));
        }

        return skinProperties;
    }

    @Override
    public Skin getSkin(FacesContext context, String name) {
        if (null == name) {
            throw new SkinNotFoundException(Messages.getMessage(Messages.NULL_SKIN_NAME_ERROR));
        }

        FutureTask<Skin> skinFuture = skins.get(name);
        if (skinFuture == null) {
            FutureTask<Skin> newSkinFuture = new FutureTask<Skin>(new SkinBuilder(name));
            skinFuture = skins.putIfAbsent(name, newSkinFuture);

            if (skinFuture == null) {
                skinFuture = newSkinFuture;
            }
        }

        try {
            skinFuture.run();
            return skinFuture.get();
        } catch (InterruptedException e) {
            throw new SkinNotFoundException(Messages.getMessage(Messages.SKIN_NOT_FOUND_ERROR, name), e);
        } catch (ExecutionException e) {
            throw new SkinNotFoundException(Messages.getMessage(Messages.SKIN_NOT_FOUND_ERROR, name), e);
        }
    }
}
TOP

Related Classes of org.richfaces.skin.AbstractSkinFactory$SkinBuilder

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.