Bug 577558: Add shared ImageDescriptorRegistry

  - Add ImageImageDescriptor

Change-Id: I74c7ecb37ca5c52741b243c5cc2a7dd5c91ce9a2
diff --git a/ecommons/org.eclipse.statet.ecommons.uimisc/META-INF/MANIFEST.MF b/ecommons/org.eclipse.statet.ecommons.uimisc/META-INF/MANIFEST.MF
index c810475..c12fa55 100644
--- a/ecommons/org.eclipse.statet.ecommons.uimisc/META-INF/MANIFEST.MF
+++ b/ecommons/org.eclipse.statet.ecommons.uimisc/META-INF/MANIFEST.MF
@@ -57,6 +57,7 @@
  org.eclipse.statet.ecommons.ui.components,
  org.eclipse.statet.ecommons.ui.content,
  org.eclipse.statet.ecommons.ui.dialogs,
+ org.eclipse.statet.ecommons.ui.jface.resource,
  org.eclipse.statet.ecommons.ui.mpbv,
  org.eclipse.statet.ecommons.ui.swt,
  org.eclipse.statet.ecommons.ui.swt.expandable,
diff --git a/ecommons/org.eclipse.statet.ecommons.uimisc/src/org/eclipse/statet/ecommons/ui/SharedUIResources.java b/ecommons/org.eclipse.statet.ecommons.uimisc/src/org/eclipse/statet/ecommons/ui/SharedUIResources.java
index ce847c4..eadf6dc 100644
--- a/ecommons/org.eclipse.statet.ecommons.uimisc/src/org/eclipse/statet/ecommons/ui/SharedUIResources.java
+++ b/ecommons/org.eclipse.statet.ecommons.uimisc/src/org/eclipse/statet/ecommons/ui/SharedUIResources.java
@@ -19,6 +19,7 @@
 
 import org.eclipse.statet.jcommons.lang.NonNullByDefault;
 
+import org.eclipse.statet.ecommons.ui.jface.resource.ImageDescriptorRegistry;
 import org.eclipse.statet.ecommons.ui.util.UIResources;
 import org.eclipse.statet.internal.ecommons.ui.UIMiscellanyPlugin;
 
@@ -120,6 +121,8 @@
 	
 	private final Point iconDefaultSize= new Point(16, 16);
 	
+	private final ImageDescriptorRegistry imageDescriptorRegistry= new ImageDescriptorRegistry();
+	
 	
 	private SharedUIResources() {
 		super(UIMiscellanyPlugin.getInstance().getImageRegistry());
@@ -130,4 +133,9 @@
 		return this.iconDefaultSize;
 	}
 	
+	
+	public ImageDescriptorRegistry getImageDescriptorRegistry() {
+		return this.imageDescriptorRegistry;
+	}
+	
 }
diff --git a/ecommons/org.eclipse.statet.ecommons.uimisc/src/org/eclipse/statet/ecommons/ui/components/DropDownButton.java b/ecommons/org.eclipse.statet.ecommons.uimisc/src/org/eclipse/statet/ecommons/ui/components/DropDownButton.java
index 6894534..8da38c3 100644
--- a/ecommons/org.eclipse.statet.ecommons.uimisc/src/org/eclipse/statet/ecommons/ui/components/DropDownButton.java
+++ b/ecommons/org.eclipse.statet.ecommons.uimisc/src/org/eclipse/statet/ecommons/ui/components/DropDownButton.java
@@ -33,9 +33,9 @@
 
 import org.eclipse.statet.jcommons.collections.CopyOnWriteIdentityListSet;
 
+import org.eclipse.statet.ecommons.ui.SharedUIResources;
 import org.eclipse.statet.ecommons.ui.swt.AccessibleArrowImage;
 import org.eclipse.statet.ecommons.ui.util.MenuUtils;
-import org.eclipse.statet.internal.ecommons.ui.UIMiscellanyPlugin;
 
 
 public class DropDownButton extends Composite {
@@ -81,7 +81,7 @@
 		
 		final AccessibleArrowImage imageDescriptor= new AccessibleArrowImage(SWT.DOWN, SWT.DEFAULT,
 				this.downButton.getForeground().getRGB(), this.downButton.getBackground().getRGB() );
-		this.image= UIMiscellanyPlugin.getInstance().getImageDescriptorRegistry().get(imageDescriptor);
+		this.image= SharedUIResources.getInstance().getImageDescriptorRegistry().get(imageDescriptor);
 		updateSizes();
 		
 		this.downButton.addSelectionListener(new SelectionAdapter() {
diff --git a/ecommons/org.eclipse.statet.ecommons.uimisc/src/org/eclipse/statet/ecommons/ui/components/WaCombo.java b/ecommons/org.eclipse.statet.ecommons.uimisc/src/org/eclipse/statet/ecommons/ui/components/WaCombo.java
index 6974b8d..df22862 100644
--- a/ecommons/org.eclipse.statet.ecommons.uimisc/src/org/eclipse/statet/ecommons/ui/components/WaCombo.java
+++ b/ecommons/org.eclipse.statet.ecommons.uimisc/src/org/eclipse/statet/ecommons/ui/components/WaCombo.java
@@ -51,6 +51,7 @@
 import org.eclipse.swt.widgets.TypedListener;
 import org.eclipse.swt.widgets.Widget;
 
+import org.eclipse.statet.ecommons.ui.SharedUIResources;
 import org.eclipse.statet.ecommons.ui.swt.AccessibleArrowImage;
 import org.eclipse.statet.internal.ecommons.ui.UIMiscellanyPlugin;
 
@@ -296,7 +297,7 @@
 			size = AccessibleArrowImage.DEFAULT_SIZE;
 		}
 		fArrowImageSize = size;
-		final Image image = UIMiscellanyPlugin.getInstance().getImageDescriptorRegistry().get(
+		final Image image = SharedUIResources.getInstance().getImageDescriptorRegistry().get(
 				new AccessibleArrowImage(SWT.DOWN, size,
 						fArrow.getForeground().getRGB(), fArrow.getBackground().getRGB() ));
 		fArrow.setImage(image);
diff --git a/ecommons/org.eclipse.statet.ecommons.uimisc/src/org/eclipse/statet/ecommons/ui/jface/resource/ImageDescriptorRegistry.java b/ecommons/org.eclipse.statet.ecommons.uimisc/src/org/eclipse/statet/ecommons/ui/jface/resource/ImageDescriptorRegistry.java
new file mode 100644
index 0000000..56586a3
--- /dev/null
+++ b/ecommons/org.eclipse.statet.ecommons.uimisc/src/org/eclipse/statet/ecommons/ui/jface/resource/ImageDescriptorRegistry.java
@@ -0,0 +1,108 @@
+/*=============================================================================#
+ # Copyright (c) 2000, 2021 IBM Corporation and others.
+ # 
+ # This program and the accompanying materials are made available under the
+ # terms of the Eclipse Public License 2.0 which is available at
+ # https://www.eclipse.org/legal/epl-2.0.
+ # 
+ # SPDX-License-Identifier: EPL-2.0
+ # 
+ # Contributors:
+ #     IBM Corporation - org.eclipse.jdt: initial API and implementation
+ #     Patrick Chuong (Texas Instruments) - org.eclipse.jdt: Bug 292411
+ #     Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
+ #=============================================================================*/
+
+package org.eclipse.statet.ecommons.ui.jface.resource;
+
+import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullAssert;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+
+import org.eclipse.statet.jcommons.lang.NonNullByDefault;
+import org.eclipse.statet.jcommons.lang.Nullable;
+
+import org.eclipse.statet.ecommons.ui.util.UIAccess;
+
+
+/**
+ * A registry that maps <code>ImageDescriptors</code> to <code>Image</code>.
+ */
+@NonNullByDefault
+public class ImageDescriptorRegistry {
+	
+	
+	private final Map<ImageDescriptor, Image> registry= new HashMap<>();
+	
+	private final Display display;
+	
+	private boolean disposed;
+	
+	
+	/**
+	 * Creates a new image descriptor registry for the given display.
+	 * 
+	 * <p>All images managed by this registry will be disposed when the display gets disposed.</p>
+	 * 
+	 * @param display the display the images managed by this registry are allocated for
+	 */
+	public ImageDescriptorRegistry(final Display display) {
+		this.display= nonNullAssert(display);
+		
+		this.display.asyncExec(() -> {
+			ImageDescriptorRegistry.this.display.disposeExec(
+					ImageDescriptorRegistry.this::dispose );
+		});
+	}
+	
+	/**
+	 * Creates a new image descriptor registry for the current or default display, respectively.
+	 */
+	public ImageDescriptorRegistry() {
+		this(UIAccess.getDisplay());
+	}
+	
+	protected void dispose() {
+		synchronized (this.registry) {
+			this.disposed= true;
+			try {
+				for (final Image image : this.registry.values()) {
+					image.dispose();
+				}
+			}
+			finally {
+				this.registry.clear();
+			}
+		}
+	}
+	
+	
+	/**
+	 * Returns the image associated with the given image descriptor.
+	 * 
+	 * @param descriptor the image descriptor for which the registry manages an image
+	 * @return the image associated with the image descriptor or <code>null</code>
+	 *    if the image descriptor can't create the requested image.
+	 */
+	public @Nullable Image get(ImageDescriptor descriptor) {
+		if (descriptor == null) {
+			descriptor= ImageDescriptor.getMissingImageDescriptor();
+		}
+		synchronized (this.registry) {
+			Image image= this.registry.get(descriptor);
+			if (image == null && !this.disposed) {
+				image= descriptor.createImage();
+				if (image != null) {
+					this.registry.put(descriptor, image);
+				}
+			}
+			return image;
+		}
+	}
+	
+}
diff --git a/ecommons/org.eclipse.statet.ecommons.uimisc/src/org/eclipse/statet/ecommons/ui/jface/resource/ImageImageDescriptor.java b/ecommons/org.eclipse.statet.ecommons.uimisc/src/org/eclipse/statet/ecommons/ui/jface/resource/ImageImageDescriptor.java
new file mode 100644
index 0000000..46f728d
--- /dev/null
+++ b/ecommons/org.eclipse.statet.ecommons.uimisc/src/org/eclipse/statet/ecommons/ui/jface/resource/ImageImageDescriptor.java
@@ -0,0 +1,60 @@
+/*=============================================================================#
+ # Copyright (c) 2021 Stephan Wahlbrink and others.
+ # 
+ # This program and the accompanying materials are made available under the
+ # terms of the Eclipse Public License 2.0 which is available at
+ # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
+ # which is available at https://www.apache.org/licenses/LICENSE-2.0.
+ # 
+ # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
+ # 
+ # Contributors:
+ #     Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
+ #=============================================================================*/
+
+package org.eclipse.statet.ecommons.ui.jface.resource;
+
+import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullAssert;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.ImageData;
+
+import org.eclipse.statet.jcommons.lang.NonNullByDefault;
+import org.eclipse.statet.jcommons.lang.Nullable;
+
+
+@NonNullByDefault
+public class ImageImageDescriptor extends ImageDescriptor {
+	
+	
+	private final Image image;
+	
+	
+	public ImageImageDescriptor(final Image image) {
+		this.image= nonNullAssert(image);
+	}
+	
+	@Override
+	public ImageData getImageData(final int zoom) {
+		return this.image.getImageData(zoom);
+	}
+	
+	
+	@Override
+	public int hashCode() {
+		return this.image.hashCode();
+	}
+	
+	@Override
+	public boolean equals(@Nullable final Object obj) {
+		if (this == obj) {
+			return true;
+		}
+		if (obj != null && getClass() == obj.getClass()) {
+			return this.image.equals(((ImageImageDescriptor)obj).image);
+		}
+		return false;
+	}
+	
+}
diff --git a/ecommons/org.eclipse.statet.ecommons.uimisc/src/org/eclipse/statet/ecommons/ui/util/ImageDescriptorRegistry.java b/ecommons/org.eclipse.statet.ecommons.uimisc/src/org/eclipse/statet/ecommons/ui/util/ImageDescriptorRegistry.java
deleted file mode 100644
index 83ca6cb..0000000
--- a/ecommons/org.eclipse.statet.ecommons.uimisc/src/org/eclipse/statet/ecommons/ui/util/ImageDescriptorRegistry.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*=============================================================================#
- # Copyright (c) 2000, 2021 IBM Corporation and others.
- # 
- # This program and the accompanying materials are made available under the
- # terms of the Eclipse Public License 2.0 which is available at
- # https://www.eclipse.org/legal/epl-2.0.
- # 
- # SPDX-License-Identifier: EPL-2.0
- # 
- # Contributors:
- #     IBM Corporation - org.eclipse.jdt: initial API and implementation
- #     Patrick Chuong (Texas Instruments) - org.eclipse.jdt: Bug 292411
- #     Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
- #=============================================================================*/
-
-package org.eclipse.statet.ecommons.ui.util;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.eclipse.jface.resource.ImageDescriptor;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.widgets.Display;
-
-import org.eclipse.statet.jcommons.lang.Disposable;
-
-
-/**
- * A registry that maps <code>ImageDescriptors</code> to <code>Image</code>.
- */
-public class ImageDescriptorRegistry implements Disposable {
-	
-	
-	private final Map<ImageDescriptor, Image> fRegistry= new HashMap<>();
-	
-	private final Display fDisplay;
-	
-	private boolean fDisposed;
-	
-	
-	/**
-	 * Creates a new image descriptor registry for the current or default display, respectively.
-	 */
-	public ImageDescriptorRegistry() {
-		this(UIAccess.getDisplay());
-	}
-	
-	/**
-	 * Creates a new image descriptor registry for the given display. All images
-	 * managed by this registry will be disposed when the display gets disposed.
-	 * 
-	 * @param display the display the images managed by this registry are allocated for 
-	 */
-	public ImageDescriptorRegistry(final Display display) {
-		if (display == null) {
-			throw new NullPointerException("display");
-		}
-		fDisplay = display;
-		hookDisplay();
-	}
-	
-	
-	/**
-	 * Returns the image associated with the given image descriptor.
-	 * 
-	 * @param descriptor the image descriptor for which the registry manages an image
-	 * @return the image associated with the image descriptor or <code>null</code>
-	 *  if the image descriptor can't create the requested image.
-	 */
-	public Image get(ImageDescriptor descriptor) {
-		if (descriptor == null) {
-			descriptor = ImageDescriptor.getMissingImageDescriptor();
-		}
-		synchronized (fRegistry) {
-			Image result = fRegistry.get(descriptor);
-			if (result == null && !fDisposed) {
-				result = descriptor.createImage();
-				if (result != null) {
-					fRegistry.put(descriptor, result);
-				}
-			}
-			return result;
-		}
-	}
-	
-	private void hookDisplay() {
-		fDisplay.asyncExec(new Runnable() {
-			@Override
-			public void run() {
-				fDisplay.disposeExec(new Runnable() {
-					@Override
-					public void run() {
-						dispose();
-					}
-				});
-			}
-		});
-	}
-	
-	/**
-	 * Disposes all images managed by this registry.
-	 */	
-	@Override
-	public void dispose() {
-		synchronized (fRegistry) {
-			fDisposed = true;
-			for (final Image image : fRegistry.values()) {
-				image.dispose();
-			}
-			fRegistry.clear();
-		}
-	}
-	
-}
diff --git a/ecommons/org.eclipse.statet.ecommons.uimisc/src/org/eclipse/statet/internal/ecommons/ui/UIMiscellanyPlugin.java b/ecommons/org.eclipse.statet.ecommons.uimisc/src/org/eclipse/statet/internal/ecommons/ui/UIMiscellanyPlugin.java
index 6dc20c8..caea3f2 100644
--- a/ecommons/org.eclipse.statet.ecommons.uimisc/src/org/eclipse/statet/internal/ecommons/ui/UIMiscellanyPlugin.java
+++ b/ecommons/org.eclipse.statet.ecommons.uimisc/src/org/eclipse/statet/internal/ecommons/ui/UIMiscellanyPlugin.java
@@ -35,7 +35,6 @@
 import org.eclipse.statet.jcommons.lang.Disposable;
 
 import org.eclipse.statet.ecommons.ui.SharedUIResources;
-import org.eclipse.statet.ecommons.ui.util.ImageDescriptorRegistry;
 import org.eclipse.statet.ecommons.ui.util.ImageRegistryUtil;
 import org.eclipse.statet.ecommons.ui.util.UIAccess;
 
@@ -73,8 +72,6 @@
 	
 	private final List<Disposable> disposables= new ArrayList<>();
 	
-	private ImageDescriptorRegistry imageDescriptorRegistry;
-	
 	
 	/**
 	 * The default constructor
@@ -97,7 +94,6 @@
 			synchronized (this) {
 				this.started = false;
 				
-				this.imageDescriptorRegistry = null;
 			}
 			
 			for (final Disposable listener : this.disposables) {
@@ -352,15 +348,4 @@
 		});
 	}
 	
-	public synchronized ImageDescriptorRegistry getImageDescriptorRegistry() {
-		if (this.imageDescriptorRegistry == null) {
-			if (!this.started) {
-				throw new IllegalStateException("Plug-in is not started.");
-			}
-			this.imageDescriptorRegistry = new ImageDescriptorRegistry();
-			this.disposables.add(this.imageDescriptorRegistry);
-		}
-		return this.imageDescriptorRegistry;
-	}
-	
 }