net.sf.nmedit.jpatch.ModuleDescriptions.java Source code

Java tutorial

Introduction

Here is the source code for net.sf.nmedit.jpatch.ModuleDescriptions.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
 */

/*
 * Created on Dec 10, 2006
 */
package net.sf.nmedit.jpatch;

import java.awt.Image;
import java.awt.Toolkit;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.ref.SoftReference;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.xml.sax.InputSource;

import net.sf.nmedit.jpatch.impl.PBasicModuleDescriptor;
import net.sf.nmedit.jpatch.js.JSContext;
import net.sf.nmedit.jpatch.transform.PTTransformations;
import net.sf.nmedit.nmutils.PluginObjectInputStream;

public class ModuleDescriptions implements Iterable<PModuleDescriptor> {

    private PSignalTypes signalTypes;
    private Map<String, PTypes<PType>> types = new HashMap<String, PTypes<PType>>();
    private Map<Object, PModuleDescriptor> moduleMap = new HashMap<Object, PModuleDescriptor>(127);
    private ClassLoader loader;
    protected PTTransformations transformations;
    protected PModuleMetrics metrics;

    private SoftReference<Map<ImageSource, Image>> imageCacheReference;
    private JSContext jscontext;

    private DocumentationSrc documentationSrc;

    final class DocumentationSrc {
        private String lang;
        private String src;
        private Map<String, String> documentation = null;
        private boolean triedParsing = false;

        public DocumentationSrc(String lang, String src) {
            this.lang = lang;
            this.src = src;
        }

        void loadDocumentation() {
            if (triedParsing)
                return;

            triedParsing = true;
            ClassLoader loader = ModuleDescriptions.this.getModuleDescriptionsClassLoader();
            if (loader == null)
                loader = ModuleDescriptions.this.getClass().getClassLoader();

            try {
                InputStream is = loader.getResourceAsStream(src);
                documentation = PModuleDocumentationParser.build(new InputSource(is));
            } catch (Exception e) {
                Log log = LogFactory.getLog(DocumentationSrc.class);
                if (log.isErrorEnabled())
                    log.trace(e);
            }
        }

        public String getDocumentationForKey(Object componentId) {
            loadDocumentation();
            return documentation != null ? documentation.get(componentId) : null;
        }
    }

    public ModuleDescriptions(ClassLoader resourceClassLoader) {
        this.loader = resourceClassLoader;
        jscontext = new JSContext();
    }

    public String getDocumentationFor(PModuleDescriptor module) {
        if (documentationSrc == null)
            return null;
        return documentationSrc.getDocumentationForKey(module.getComponentId());
    }

    void setDocumentationSrc(String lang, String src) {
        this.documentationSrc = new DocumentationSrc(lang, src);
    }

    public JSContext getJSContext() {
        return jscontext;
    }

    private Map<ImageSource, Image> getImageCache() {
        Map<ImageSource, Image> cache = (imageCacheReference != null) ? imageCacheReference.get() : null;
        if (cache == null) {
            cache = new HashMap<ImageSource, Image>();
            imageCacheReference = new SoftReference<Map<ImageSource, Image>>(cache);
        }
        return cache;
    }

    protected ClassLoader getResourceClassLoader() {
        return loader == null ? getClass().getClassLoader() : loader;
    }

    public URL getImageURL(ImageSource source) {
        return getResourceClassLoader().getResource(source.getSource());
    }

    public Image getImage(ImageSource source) {
        Map<ImageSource, Image> cache = getImageCache();
        Image image = cache.get(source);
        if (image == null) {
            URL url = getResourceClassLoader().getResource(source.getSource());
            if (url != null) {
                image = Toolkit.getDefaultToolkit().getImage(url);
                cache.put(source, image);
            }
        }
        return image;
    }

    public void writeCache(ObjectOutputStream out) throws IOException {
        // signals
        out.writeObject(signalTypes);
        // types
        out.writeInt(types.size());
        for (Entry<String, PTypes<PType>> e : types.entrySet()) {
            out.writeObject(e.getKey());
            out.writeObject(e.getValue());
        }
        // modules
        out.writeInt(moduleMap.size());
        for (PModuleDescriptor m : moduleMap.values()) {
            out.writeObject(m);
        }
    }

    public void writeCache(File cache) throws FileNotFoundException, IOException {
        ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(cache)));
        try {
            writeCache(out);
        } finally {
            out.flush();
            out.close();
        }
    }

    @SuppressWarnings("unchecked")
    public void readCache(ObjectInputStream in) throws IOException, ClassNotFoundException {
        // signals
        signalTypes = (PSignalTypes) in.readObject();
        int size;
        // types
        size = in.readInt();
        for (int i = 0; i < size; i++) {
            String key = (String) in.readObject();
            PTypes<PType> t = (PTypes) in.readObject();
            types.put(key, t);
        }
        // modules
        size = in.readInt();
        for (int i = 0; i < size; i++) {
            PModuleDescriptor d = (PModuleDescriptor) in.readObject();
            ((PBasicModuleDescriptor) d).setModuleDescriptions(this);
            moduleMap.put(d.getComponentId(), d);
        }
    }

    public void readCache(File cache) throws FileNotFoundException, IOException, ClassNotFoundException {
        readCache(cache, getClass().getClassLoader());
    }

    public void readCache(File cache, ClassLoader loader)
            throws FileNotFoundException, IOException, ClassNotFoundException {
        ObjectInputStream in = new PluginObjectInputStream(loader,
                new BufferedInputStream(new FileInputStream(cache)));
        try {
            readCache(in);
        } finally {
            in.close();
        }
    }

    public PModuleMetrics getMetrics() {
        return metrics;
    }

    public PTTransformations getTransformations() {
        return transformations;
    }

    public ClassLoader getModuleDescriptionsClassLoader() {
        if (loader == null)
            return getClass().getClassLoader();

        return loader;
    }

    public PSignalTypes getDefinedSignals() {
        return signalTypes;
    }

    public int getModuleCount() {
        return moduleMap.size();
    }

    public void add(PModuleDescriptor module) {
        moduleMap.put(module.getComponentId(), module);
    }

    public PModuleDescriptor getModuleById(Object id) {
        return moduleMap.get(id);
    }

    public void setSignals(PSignalTypes signalTypes) {
        this.signalTypes = signalTypes;
    }

    public void addType(PTypes<PType> type) {
        types.put(type.getName(), type);
    }

    public PTypes<PType> getType(String name) {
        return types.get(name);
    }

    public PModuleDescriptor[] modulesByCategory(String categoryName) {
        List<PModuleDescriptor> modules = null;
        for (PModuleDescriptor mod : this) {
            if (categoryName.equals(mod.getCategory())) {
                if (modules == null)
                    modules = new LinkedList<PModuleDescriptor>();
                modules.add(mod);
            }
        }
        if (modules == null || modules.isEmpty())
            return new PModuleDescriptor[0];

        return modules.toArray(new PModuleDescriptor[modules.size()]);
    }

    public Iterator<PModuleDescriptor> iterator() {
        return moduleMap.values().iterator();
    }

    public void setTransformations(PTTransformations t) {
        this.transformations = t;
    }

}