net.enilink.komma.edit.ui.provider.ExtendedImageRegistry.java Source code

Java tutorial

Introduction

Here is the source code for net.enilink.komma.edit.ui.provider.ExtendedImageRegistry.java

Source

/**
 * <copyright> 
 *
 * Copyright (c) 2002, 2009 IBM Corporation and others.
 * All rights reserved.   This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors: 
 *   IBM - Initial API and implementation
 *
 * </copyright>
 *
 * $Id: ExtendedImageRegistry.java,v 1.6 2008/01/15 17:15:43 emerks Exp $
 */
package net.enilink.komma.edit.ui.provider;

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;

import org.eclipse.jface.resource.CompositeImageDescriptor;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.PlatformUI;

import net.enilink.komma.edit.KommaEditPlugin;
import net.enilink.komma.edit.provider.ComposedImage;
import net.enilink.komma.core.URI;

/**
 *
 */
public class ExtendedImageRegistry {
    private static final ExtendedImageRegistry INSTANCE = new ExtendedImageRegistry();

    public static ExtendedImageRegistry getInstance() {
        return INSTANCE;
    }

    protected Map<Display, Map<Object, Image>> images = Collections
            .synchronizedMap(new WeakHashMap<Display, Map<Object, Image>>());

    protected static String modelURLPrefix = KommaEditPlugin.INSTANCE.getImage("full/obj16/Model").toString() + "#";

    protected static String itemURLPrefix = KommaEditPlugin.INSTANCE.getImage("full/obj16/Item").toString() + "#";

    protected static String createChildURLPrefix = KommaEditPlugin.INSTANCE.getImage("full/ctool16/CreateChild")
            .toString() + "#";

    public Image getImage(Object object) {
        if (object instanceof Image) {
            return (Image) object;
        } else {
            Display display = Display.getCurrent();
            Image result = null;
            Map<Object, Image> cache = null;
            if (display != null) {
                synchronized (display) {
                    cache = images.get(display);
                    if (cache == null) {
                        hookDisplayDispose(display);
                        cache = new HashMap<Object, Image>();
                        images.put(display, cache);
                    }
                    result = cache.get(object);
                }
            }
            if (result == null) {
                if (object instanceof ImageDescriptor) {
                    ImageDescriptor imageDescriptor = (ImageDescriptor) object;
                    result = imageDescriptor.createImage();
                } else if (object instanceof URL || object instanceof URI) {
                    String urlString = object.toString();
                    ImageDescriptor imageDescriptor = null;
                    if (urlString.startsWith(modelURLPrefix)) {
                        imageDescriptor = PlatformUI.getWorkbench().getEditorRegistry()
                                .getImageDescriptor("dummy." + urlString.substring(modelURLPrefix.length()));
                    } else if (urlString.startsWith(itemURLPrefix)) {
                        try {
                            URL url = new URL(urlString.substring(0, itemURLPrefix.length()));
                            String key1 = urlString.substring(itemURLPrefix.length());
                            imageDescriptor = new URLImageDescriptor(url, key1, null);
                        } catch (IOException exception) {
                            // Ignore
                        }
                    } else if (urlString.startsWith(createChildURLPrefix)) {
                        try {
                            URL url = new URL(urlString.substring(0, createChildURLPrefix.length()));
                            String key1 = urlString.substring(createChildURLPrefix.length() + 1);
                            String key2 = null;
                            int index = key1.indexOf("/");
                            if (index != -1) {
                                key2 = key1.substring(index + 1);
                                key1 = key1.substring(0, index);
                            }
                            imageDescriptor = new URLImageDescriptor(url, key1, key2);
                        } catch (IOException exception) {
                            // Ignore
                        }
                    } else {
                        try {
                            imageDescriptor = ImageDescriptor.createFromURL(new URL(urlString));
                        } catch (IOException exception) {
                            // Ignore
                        }
                    }
                    if (imageDescriptor != null) {
                        result = imageDescriptor.createImage();
                    }
                } else if (object instanceof ComposedImage) {
                    ImageDescriptor composedImageDescriptor = new ComposedImageDescriptor((ComposedImage) object);
                    result = composedImageDescriptor.createImage();
                }

                if (result != null && display != null) {
                    synchronized (display) {
                        cache.put(object, result);
                    }
                }
            }
            return result;
        }
    }

    public ImageDescriptor getImageDescriptor(Object object) {
        if (object instanceof ImageDescriptor) {
            return (ImageDescriptor) object;
        } else {
            final Image image = getImage(object);
            if (image != null) {
                return new ImageWrapperImageDescriptor(image);
            } else {
                return null;
            }
        }
    }

    protected void hookDisplayDispose(final Display display) {
        display.disposeExec(new Runnable() {
            public void run() {
                Map<Object, Image> cache = images.remove(display);
                if (cache != null) {
                    for (Image image : cache.values()) {
                        image.dispose();
                    }
                }
            }
        });
    }
}

class ImageWrapperImageDescriptor extends ImageDescriptor {
    protected Image image;

    public ImageWrapperImageDescriptor(Image image) {
        this.image = image;
    }

    @Override
    public boolean equals(Object that) {
        return that instanceof ImageWrapperImageDescriptor
                && ((ImageWrapperImageDescriptor) that).image.equals(image);
    }

    @Override
    public int hashCode() {
        return image.hashCode();
    }

    @Override
    public ImageData getImageData() {
        return image.getImageData();
    }
}

class ComposedImageDescriptor extends CompositeImageDescriptor {
    protected ComposedImage composedImage;
    protected List<ImageData> imageDatas;

    public ComposedImageDescriptor(ComposedImage composedImage) {
        this.composedImage = composedImage;
    }

    @Override
    public void drawCompositeImage(int width, int height) {
        ComposedImage.Size size = new ComposedImage.Size();
        size.width = width;
        size.height = height;
        Iterator<ImageData> images = imageDatas.iterator();
        for (Iterator<ComposedImage.Point> points = composedImage.getDrawPoints(size).iterator(); points
                .hasNext();) {
            ComposedImage.Point point = points.next();
            drawImage(images.next(), point.x, point.y);
        }
    }

    @Override
    public Point getSize() {
        List<Object> images = composedImage.getImages();
        imageDatas = new ArrayList<ImageData>(images.size());
        List<ComposedImage.Size> sizes = new ArrayList<ComposedImage.Size>(images.size());
        for (Object object : images) {
            Image image = ExtendedImageRegistry.getInstance().getImage(object);
            ImageData imageData = image.getImageData();
            imageDatas.add(imageData);

            ComposedImage.Size size = new ComposedImage.Size();
            size.width = imageData.width;
            size.height = imageData.height;
            sizes.add(size);
        }

        ComposedImage.Size result = composedImage.getSize(sizes);
        return new Point(result.width, result.height);
    }
}

class URLImageDescriptor extends ImageDescriptor {
    protected URL url;
    protected String key1;
    protected String key2;

    URLImageDescriptor(URL url, String key1, String key2) {
        this.url = url;
        this.key1 = key1;
        this.key2 = key2;
    }

    @Override
    public ImageData getImageData() {
        InputStream in = null;
        try {
            if (key1 != null) {
                ImageDataSynthesizer imageDataSynthesizer = new ImageDataSynthesizer(url);
                in = imageDataSynthesizer.generateGIF(key1, key2);
                return new ImageData(in);
            } else {
                in = url.openStream();
            }

            return new ImageData(in);
        } catch (IOException e) {
            return null;
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    return null;
                }
            }
        }
    }

    protected InputStream getStream() throws IOException {
        return url.openStream();
    }

    @Override
    public int hashCode() {
        return url.hashCode() | (key1 == null ? 0 : key1.hashCode()) | (key2 == null ? 0 : key2.hashCode());
    }

    @Override
    public boolean equals(Object that) {
        if (that instanceof URLImageDescriptor) {
            URLImageDescriptor otherURLImageDescriptor = (URLImageDescriptor) that;
            return url.equals(otherURLImageDescriptor.url)
                    && (key1 == null ? otherURLImageDescriptor.key1 == null
                            : key1.equals(otherURLImageDescriptor.key1))
                    && (key2 == null ? otherURLImageDescriptor.key2 == null
                            : key2.equals(otherURLImageDescriptor.key2));
        } else {
            return false;
        }
    }

    @Override
    public String toString() {
        return getClass().getName() + "(" + url + "#" + key1 + "/" + key2 + ")";
    }
}

class ImageDataSynthesizer {
    protected URL url;

    protected static final int tableOffset1 = 49;
    protected static final int tableOffset2 = 25;

    public ImageDataSynthesizer(URL url) {
        this.url = url;
    }

    protected int code(String code) {
        int result = 0;
        for (int i = 0; i < code.length(); ++i) {
            result += code.charAt(i) - 32;
        }
        return result;
    }

    public InputStream generateGIF(String key1, String key2) {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        try {
            byte[] content = new byte[5000];
            int result = getContents(content, url);

            // generateColor();
            ColorInformation info1 = ColorInformation.getColor(code(key1));
            ColorInformation info2 = key2 == null ? null : ColorInformation.getColor(code(key2));

            for (int j = 0; j < result; ++j) {
                if (j == tableOffset1 || j == tableOffset1 + 3 || j == tableOffset1 + 6 || j == tableOffset1 + 9) {
                    int index = (j - tableOffset1) / 3;
                    if (!info1.rainbow || info1.which == index - 1) {
                        content[j] = info1.scale(info1.red, info1.factor[index]);
                    }
                } else if (j == tableOffset1 + 1 || j == tableOffset1 + 4 || j == tableOffset1 + 7
                        || j == tableOffset1 + 10) {
                    int index = (j - tableOffset1 - 1) / 3;
                    if (!info1.rainbow || info1.which == index - 1) {
                        content[j] = info1.scale(info1.green, info1.factor[index]);
                    }
                } else if (j == tableOffset1 + 2 || j == tableOffset1 + 5 || j == tableOffset1 + 8
                        || j == tableOffset1 + 11) {
                    int index = (j - tableOffset1 - 2) / 3;
                    if (!info1.rainbow || info1.which == index - 1) {
                        content[j] = info1.scale(info1.blue, info1.factor[index]);
                    }
                }

                if (info2 != null) {
                    if (j == tableOffset2 || j == tableOffset2 + 3 || j == tableOffset2 + 6
                            || j == tableOffset2 + 9) {
                        int index = (j - tableOffset2) / 3;
                        if (!info2.rainbow || info2.which == index - 1) {
                            content[j] = info2.scale(info2.red, info2.factor[index]);
                        }
                    } else if (j == tableOffset2 + 1 || j == tableOffset2 + 4 || j == tableOffset2 + 7
                            || j == tableOffset2 + 10) {
                        int index = (j - tableOffset2 - 1) / 3;
                        if (!info2.rainbow || info2.which == index - 1) {
                            content[j] = info2.scale(info2.green, info2.factor[index]);
                        }
                    } else if (j == tableOffset2 + 2 || j == tableOffset2 + 5 || j == tableOffset2 + 8
                            || j == tableOffset2 + 11) {
                        int index = (j - tableOffset2 - 2) / 3;
                        if (!info2.rainbow || info2.which == index - 1) {
                            content[j] = info2.scale(info2.blue, info2.factor[index]);
                        }
                    }
                }
            }

            DataOutputStream writer = new DataOutputStream(outputStream);
            writer.write(content, 0, result);
            writer.close();
        } catch (Exception exception) {
            exception.printStackTrace();
        }

        return new ByteArrayInputStream(outputStream.toByteArray());
    }

    protected int getContents(byte[] content, URL gifURL) throws IOException {
        BufferedInputStream bufferedInputStream = new BufferedInputStream(gifURL.openStream());
        DataInputStream reader = new DataInputStream(bufferedInputStream);
        int result = reader.read(content, 0, content.length);
        reader.close();
        return result;
    }

    protected static class ColorInformation {
        public static ColorInformation getColor(int index) {
            index = Math.abs(index) % 61;
            while (entries.size() <= index) {
                instance.generateColor();

                ColorInformation entry = new ColorInformation();
                entry.red = instance.red;
                entry.green = instance.green;
                entry.blue = instance.blue;
                entry.which = instance.which;
                entry.factor = new double[] { instance.factor[0], instance.factor[1], instance.factor[2],
                        instance.factor[3] };
                entry.rainbow = instance.rainbow;
                entries.add(entry);
                instance.fixFactor();
            }
            return entries.get(index);
        }

        protected static ColorInformation instance = new ColorInformation();

        protected static List<ColorInformation> entries = new ArrayList<ColorInformation>(1000);

        public int red = 192;
        public int green = 64;
        public int blue = 64;

        public int which = 2;
        public int change = 64;

        public double[] factor = { 0.35, 0.1, -0.1, -0.3 };
        public boolean rainbow;

        public byte scale(int value, double factor) {
            if (factor > 0.0) {
                return (byte) (value + (255 - value) * factor);
            } else {
                return (byte) (value + value * factor);
            }
        }

        protected void generateColor() {
            switch (which) {
            case 0: {
                red += change;
                if (red <= 64) {
                    which = 1;
                    change = -change;
                } else if (red >= 192) {
                    which = 1;
                    change = -change;
                }
                break;
            }
            case 1: {
                green += change;
                if (green >= 192) {
                    which = 2;
                    change = -change;
                } else if (green <= 64) {
                    which = 2;
                    change = -change;
                }
                break;
            }
            case 2: {
                blue += change;
                if (blue >= 192) {
                    which = 0;
                    change = -change;
                } else if (blue <= 64) {
                    which = 0;
                    change = -change;
                }
                break;
            }
            }
        }

        protected void fixFactor() {
            if (red == 192 && green == 64 && blue == 64) {
                for (int j = 0; j < factor.length; ++j) {
                    factor[j] += 0.3;
                }
                if (factor[0] >= 1.0) {
                    rainbow = true;
                    for (int j = 0; j < factor.length; ++j) {
                        factor[j] -= 0.8;
                    }
                }
            }
        }
    }
}