net.sf.nmedit.jtheme.store.StorageContext.java Source code

Java tutorial

Introduction

Here is the source code for net.sf.nmedit.jtheme.store.StorageContext.java

Source

/* Copyright (C) 2006 Christian Schneider
 * 
 * This file is part of Nomad.
 * 
 * Nomad is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * Nomad 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 General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with Nomad; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */
package net.sf.nmedit.jtheme.store;

import java.awt.Image;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.SoftReference;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

import javax.imageio.ImageIO;

import net.sf.nmedit.jtheme.JTContext;
import net.sf.nmedit.jtheme.JTException;
import net.sf.nmedit.jtheme.css.FakeRule;
import net.sf.nmedit.jtheme.image.ImageCache;
import net.sf.nmedit.jtheme.image.ImageResource;
import net.sf.nmedit.jtheme.store2.ComponentElement;
import net.sf.nmedit.jtheme.store2.DefaultStore;
import net.sf.nmedit.jtheme.store2.ModuleElement;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jdom.Element;
import org.w3c.dom.css.CSSRule;
import org.w3c.dom.css.CSSRuleList;
import org.w3c.dom.css.CSSStyleRule;
import org.w3c.dom.css.CSSStyleSheet;

public abstract class StorageContext {

    private transient Log log;

    private Log getLog() {
        if (log == null)
            log = LogFactory.getLog(StorageContext.class);
        return log;
    }

    public abstract JTContext getContext();

    private Map<String, Class<? extends ComponentElement>> storeClassMap = new HashMap<String, Class<? extends ComponentElement>>();
    private SoftReference<Map<String, Method>> storeMethodMap = null;

    public abstract CSSStyleSheet getStyleSheet();

    public abstract ImageCache getImageCache();

    protected Map<String, CSSStyleRule> styleRuleMap = new HashMap<String, CSSStyleRule>();

    private int idCounter = 1;

    public String generateId() {
        return "#" + Integer.toHexString(idCounter++);
    }

    public abstract ImageResource getCachedImage(URL source);

    public abstract ImageResource getCachedImage(String source);

    public CSSStyleRule getStyleRule(String name) {
        CSSStyleRule rule = styleRuleMap.get(name);
        if (rule != null)
            return FakeRule.isFake(rule) ? null : rule;

        CSSStyleSheet css = getStyleSheet();
        CSSRuleList list = css.getCssRules();

        rule = null;

        for (int i = 0; i < list.getLength(); i++) {
            CSSRule arule = list.item(i);

            if (arule.getType() == CSSRule.STYLE_RULE) {
                CSSStyleRule srule = (CSSStyleRule) arule;

                if (name.equals(srule.getSelectorText())) {
                    // we found the rule
                    rule = srule;
                    break;
                }
            }
        }

        if (rule == null) {
            styleRuleMap.put(name, FakeRule.instance());
            return null;
        }

        styleRuleMap.put(name, rule);
        return rule;

    }

    public void installStore(String elementName, Class<? extends ComponentElement> storeClass) {
        storeClassMap.put(elementName, storeClass);
    }

    public Class<? extends ComponentElement> getStoreClass(String elementName) {
        Class<? extends ComponentElement> storeClass = storeClassMap.get(elementName);
        if (storeClass == null)
            storeClass = DefaultStore.class;
        return storeClass;
    }

    public abstract ModuleElement getModuleStoreById(Object id);

    public abstract ClassLoader getContextClassLoader();

    private Map<String, Image> imageMap = new HashMap<String, Image>();

    public Image getImage(String imageURL) {
        Image image = imageMap.get(imageURL);
        if (image != null) {
            return image;
        }

        URL url = getContextClassLoader().getResource(imageURL);
        return (url != null) ? getImage(url) : null;
    }

    protected Image getImage(URL imageURL) {
        String key = imageURL.toString();
        Image image = imageMap.get(key);
        if (image == null) {
            try {
                image = ImageIO.read(imageURL);
                imageMap.put(key, image);
            } catch (IOException e) {
                Log log = getLog();
                if (log.isWarnEnabled()) {
                    log.warn("getImage(" + imageURL + ") failed", e);
                }
            }
        }
        return image;
    }

    public URL getContextResource(String name) {
        return getContextClassLoader().getResource(name);
    }

    public InputStream getContextResourceAsStream(String name) {
        return getContextClassLoader().getResourceAsStream(name);
    }

    protected Method getStoreCreateMethod(String elementName) throws JTException {
        Map<String, Method> map = null;
        if (storeMethodMap != null) {
            map = storeMethodMap.get();
        }
        if (map == null) {
            map = new HashMap<String, Method>(160);
            storeMethodMap = new SoftReference<Map<String, Method>>(map);
        }

        Method create = map.get(elementName);
        if (create == null) {
            Class<? extends ComponentElement> storeClass = getStoreClass(elementName);
            if (storeClass == null)
                throw new JTException("No store for element: " + elementName);

            try {
                create = storeClass.getDeclaredMethod("createElement",
                        new Class<?>[] { StorageContext.class, Element.class });
            } catch (SecurityException e) {
                throw new JTException(e);
            } catch (NoSuchMethodException e) {
                throw new JTException("method createElement() not found in " + storeClass, e);
            }

            map.put(elementName, create);
        }
        return create;
    }

    public ComponentElement createStore(Element element) throws JTException {
        /*
        // fallback
        Class<? extends JTComponent> jtclass = storeClassMap2.get(element.getName());
            
        if (jtclass != null)
        {
        DefaultStore fb = new DefaultStore(this, element, jtclass);
        return fb;
        }*/

        Method create = getStoreCreateMethod(element.getName());
        try {
            ComponentElement store = (ComponentElement) create.invoke(null, new Object[] { this, element });
            return store;
        } catch (IllegalArgumentException e) {
            throw new JTException("element " + element.getName(), e);
        } catch (IllegalAccessException e) {
            throw new JTException("element " + element.getName(), e);
        } catch (InvocationTargetException e) {
            throw new JTException("element " + element.getName(), e);
        }
    }

}