170c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll/*
270c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll * Copyright (C) 2009 The Android Open Source Project
370c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll *
470c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll * Licensed under the Apache License, Version 2.0 (the "License");
570c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll * you may not use this file except in compliance with the License.
670c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll * You may obtain a copy of the License at
770c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll *
870c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll *      http://www.apache.org/licenses/LICENSE-2.0
970c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll *
1070c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll * Unless required by applicable law or agreed to in writing, software
1170c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll * distributed under the License is distributed on an "AS IS" BASIS,
1270c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1370c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll * See the License for the specific language governing permissions and
1470c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll * limitations under the License.
1570c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll */
1670c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll
1770c222d49c0a75e30b05337dbbb8110a39635aafRaphael Mollpackage com.android.sdkuilib.internal.repository.icons;
1870c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll
1970c222d49c0a75e30b05337dbbb8110a39635aafRaphael Mollimport com.android.sdklib.internal.repository.archives.Archive;
2070c222d49c0a75e30b05337dbbb8110a39635aafRaphael Mollimport com.android.sdklib.internal.repository.packages.Package;
2170c222d49c0a75e30b05337dbbb8110a39635aafRaphael Mollimport com.android.sdklib.internal.repository.sources.SdkSource;
2270c222d49c0a75e30b05337dbbb8110a39635aafRaphael Mollimport com.android.sdklib.internal.repository.sources.SdkSourceCategory;
23e46e7023069558853aad42f569a4d3fe6249d099Raphael Mollimport com.android.sdkuilib.internal.repository.core.PkgContentProvider;
2470c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll
2570c222d49c0a75e30b05337dbbb8110a39635aafRaphael Mollimport org.eclipse.swt.SWTException;
2670c222d49c0a75e30b05337dbbb8110a39635aafRaphael Mollimport org.eclipse.swt.graphics.Image;
2770c222d49c0a75e30b05337dbbb8110a39635aafRaphael Mollimport org.eclipse.swt.widgets.Display;
2870c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll
2970c222d49c0a75e30b05337dbbb8110a39635aafRaphael Mollimport java.io.InputStream;
3070c222d49c0a75e30b05337dbbb8110a39635aafRaphael Mollimport java.util.HashMap;
3170c222d49c0a75e30b05337dbbb8110a39635aafRaphael Mollimport java.util.Iterator;
3270c222d49c0a75e30b05337dbbb8110a39635aafRaphael Mollimport java.util.Locale;
3370c222d49c0a75e30b05337dbbb8110a39635aafRaphael Mollimport java.util.Map;
3470c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll
3570c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll
3670c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll/**
3770c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll * An utility class to serve {@link Image} correspond to the various icons
3870c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll * present in this package and dispose of them correctly at the end.
3970c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll */
4070c222d49c0a75e30b05337dbbb8110a39635aafRaphael Mollpublic class ImageFactory {
4170c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll
4270c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll    private final Display mDisplay;
4370c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll    private final Map<String, Image> mImages = new HashMap<String, Image>();
4470c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll
4570c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll    public ImageFactory(Display display) {
4670c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll        mDisplay = display;
4770c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll    }
4870c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll
4970c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll    /**
5070c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll     * Loads an image given its filename (with its extension).
5170c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll     * Might return null if the image cannot be loaded.
5270c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll     * The image is cached. Successive calls will return the <em>same</em> object.
5370c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll     *
5470c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll     * @param imageName The filename (with extension) of the image to load.
5570c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll     * @return A new or existing {@link Image}. The caller must NOT dispose the image (the
5670c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll     *  image will disposed by {@link #dispose()}). The returned image can be null if the
5770c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll     *  expected file is missing.
5870c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll     */
5970c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll    public Image getImageByName(String imageName) {
6070c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll
6170c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll        Image image = mImages.get(imageName);
6270c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll        if (image != null) {
6370c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll            return image;
6470c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll        }
6570c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll
6670c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll        InputStream stream = getClass().getResourceAsStream(imageName);
6770c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll        if (stream != null) {
6870c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll            try {
6970c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll                image = new Image(mDisplay, stream);
7070c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll            } catch (SWTException e) {
7170c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll                // ignore
7270c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll            } catch (IllegalArgumentException e) {
7370c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll                // ignore
7470c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll            }
7570c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll        }
7670c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll
7770c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll        // Store the image in the hash, even if this failed. If it fails now, it will fail later.
7870c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll        mImages.put(imageName, image);
7970c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll
8070c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll        return image;
8170c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll    }
8270c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll
8370c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll    /**
8470c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll     * Loads and returns the appropriate image for a given package, archive or source object.
8570c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll     * The image is cached. Successive calls will return the <em>same</em> object.
8670c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll     *
8770c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll     * @param object A {@link SdkSource} or {@link Package} or {@link Archive}.
8870c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll     * @return A new or existing {@link Image}. The caller must NOT dispose the image (the
8970c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll     *  image will disposed by {@link #dispose()}). The returned image can be null if the
9070c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll     *  object is of an unknown type.
9170c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll     */
9270c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll    public Image getImageForObject(Object object) {
9370c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll
9470c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll        if (object == null) {
9570c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll            return null;
9670c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll        }
9770c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll
9870c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll        if (object instanceof Image) {
9970c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll            return (Image) object;
10070c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll        }
10170c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll
10270c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll        String clz = object.getClass().getSimpleName();
10370c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll        if (clz.endsWith(Package.class.getSimpleName())) {
10470c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll            String name = clz.replaceFirst(Package.class.getSimpleName(), "")   //$NON-NLS-1$
10570c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll                             .replace("SystemImage", "sysimg")    //$NON-NLS-1$ //$NON-NLS-2$
10670c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll                             .toLowerCase(Locale.US);
10770c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll            name += "_pkg_16.png";                                              //$NON-NLS-1$
10870c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll            return getImageByName(name);
10970c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll        }
11070c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll
11170c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll        if (object instanceof SdkSourceCategory) {
11270c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll            return getImageByName("source_cat_icon_16.png");                     //$NON-NLS-1$
11370c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll
11470c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll        } else if (object instanceof SdkSource) {
11570c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll            return getImageByName("source_icon_16.png");                         //$NON-NLS-1$
11670c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll
11770c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll        } else if (object instanceof PkgContentProvider.RepoSourceError) {
11870c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll            return getImageByName("error_icon_16.png");                       //$NON-NLS-1$
11970c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll
12070c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll        } else if (object instanceof PkgContentProvider.RepoSourceNotification) {
12170c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll            return getImageByName("nopkg_icon_16.png");                       //$NON-NLS-1$
12270c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll        }
12370c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll
12470c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll        if (object instanceof Archive) {
12570c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll            if (((Archive) object).isCompatible()) {
12670c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll                return getImageByName("archive_icon16.png");                    //$NON-NLS-1$
12770c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll            } else {
12870c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll                return getImageByName("incompat_icon16.png");                   //$NON-NLS-1$
12970c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll            }
13070c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll        }
13170c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll
13270c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll        if (object instanceof String) {
13370c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll            return getImageByName((String) object);
13470c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll        }
13570c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll
13670c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll
13770c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll        if (object != null) {
13870c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll            // For debugging
13970c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll            // System.out.println("No image for object " + object.getClass().getSimpleName());
14070c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll        }
14170c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll
14270c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll        return null;
14370c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll    }
14470c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll
14570c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll    /**
14670c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll     * Dispose all the images created by this factory so far.
14770c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll     */
14870c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll    public void dispose() {
14970c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll        Iterator<Image> it = mImages.values().iterator();
15070c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll        while(it.hasNext()) {
15170c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll            Image img = it.next();
15270c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll            if (img != null && img.isDisposed() == false) {
15370c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll                img.dispose();
15470c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll            }
15570c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll            it.remove();
15670c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll        }
15770c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll    }
15870c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll
15970c222d49c0a75e30b05337dbbb8110a39635aafRaphael Moll}
160