2323import java .io .InputStream ;
2424import java .net .URL ;
2525import java .util .Objects ;
26+ import java .util .function .BiFunction ;
27+ import java .util .function .Function ;
2628import java .util .regex .Matcher ;
2729import java .util .regex .Pattern ;
2830
4446 */
4547class FileImageDescriptor extends ImageDescriptor implements IAdaptable {
4648
47- private class ImageProvider implements ImageFileNameProvider {
48-
49- @ Override
50- public String getImagePath (int zoom ) {
51- final boolean logIOException = zoom == 100 ;
52- if (zoom == 100 ) {
53- return getFilePath (name , logIOException );
54- }
55- String xName = getxName (name , zoom );
56- if (xName != null ) {
57- String xResult = getFilePath (xName , logIOException );
58- if (xResult != null ) {
59- return xResult ;
60- }
61- }
62- String xPath = getxPath (name , zoom );
63- if (xPath != null ) {
64- String xResult = getFilePath (xPath , logIOException );
65- if (xResult != null ) {
66- return xResult ;
67- }
68- }
69- return null ;
70- }
71-
49+ private ImageFileNameProvider createImageFileNameProvider () {
50+ return zoom -> {
51+ boolean logException = zoom == 100 ;
52+ return getImageSource (name , n -> n , FileImageDescriptor ::getxName , n -> getFilePath (n , logException ), zoom );
53+ };
7254 }
7355
7456 private static final Pattern XPATH_PATTERN = Pattern .compile ("(\\ d+)x(\\ d+)" ); //$NON-NLS-1$
@@ -106,10 +88,9 @@ public String getImagePath(int zoom) {
10688
10789 @ Override
10890 public boolean equals (Object o ) {
109- if (!(o instanceof FileImageDescriptor )) {
91+ if (!(o instanceof FileImageDescriptor other )) {
11092 return false ;
11193 }
112- FileImageDescriptor other = (FileImageDescriptor ) o ;
11394 return Objects .equals (location , other .location ) && Objects .equals (name , other .name );
11495 }
11596
@@ -122,9 +103,9 @@ public boolean equals(Object o) {
122103 */
123104 @ Override
124105 public ImageData getImageData (int zoom ) {
125- InputStream in = getStream ( zoom );
126- if (in != null ) {
127- try (BufferedInputStream stream = new BufferedInputStream (in )) {
106+ InputStream inputStream = getImageSource ( name , n -> n , FileImageDescriptor :: getxName , this :: getStream , zoom );
107+ if (inputStream != null ) {
108+ try (InputStream stream = new BufferedInputStream (inputStream )) {
128109 return new ImageData (stream );
129110 } catch (SWTException e ) {
130111 if (e .code != SWT .ERROR_INVALID_IMAGE ) {
@@ -139,28 +120,35 @@ public ImageData getImageData(int zoom) {
139120 }
140121
141122 /**
142- * Returns a stream on the image contents. Returns null if a stream could
143- * not be opened.
123+ * Returns a the image contents in the form returned by the given image-source
124+ * factory. Returns null if the content could not be found or accessed
144125 *
145126 * @param zoom the zoom factor
146- * @return the buffered stream on the file or <code>null</code> if the
147- * file cannot be found
127+ * @return the the file content or {@code null} if the file cannot be found
148128 */
149- private InputStream getStream (int zoom ) {
150- if (zoom == 100 ) {
151- return getStream (name );
152- }
153-
154- InputStream xstream = getStream (getxName (name , zoom ));
155- if (xstream != null ) {
156- return xstream ;
157- }
158-
159- InputStream xpath = getStream (getxPath (name , zoom ));
160- if (xpath != null ) {
161- return xpath ;
129+ static <E , R > R getImageSource (String root , Function <String , E > elementParser ,
130+ BiFunction <E , Integer , E > getXElement , Function <E , R > getImageSource , int zoom ) {
131+ E element = elementParser .apply (root );
132+ if (element != null ) {
133+ if (zoom == 100 ) {
134+ return getImageSource .apply (element );
135+ }
136+ @ SuppressWarnings ("boxing" )
137+ E xName = getXElement .apply (element , zoom );
138+ if (xName != null ) {
139+ R xResult = getImageSource .apply (xName );
140+ if (xResult != null ) {
141+ return xResult ;
142+ }
143+ }
144+ String xPath = getxPath (root , zoom );
145+ if (xPath != null ) {
146+ E xPathElement = elementParser .apply (xPath );
147+ if (xPathElement != null ) {
148+ return getImageSource .apply (xPathElement );
149+ }
150+ }
162151 }
163-
164152 return null ;
165153 }
166154
@@ -173,20 +161,17 @@ private InputStream getStream(int zoom) {
173161 * does not denotes an existing resource
174162 */
175163 private InputStream getStream (String fileName ) {
176- if (fileName != null ) {
177- if (location != null ) {
178- return location .getResourceAsStream (fileName );
179- }
180- try {
181- return new FileInputStream (fileName );
182- } catch (FileNotFoundException e ) {
183- return null ;
184- }
164+ if (location != null ) {
165+ return location .getResourceAsStream (fileName );
166+ }
167+ try {
168+ return new FileInputStream (fileName );
169+ } catch (FileNotFoundException e ) {
170+ return null ;
185171 }
186- return null ;
187172 }
188173
189- static String getxPath (String name , int zoom ) {
174+ private static String getxPath (String name , int zoom ) {
190175 Matcher matcher = XPATH_PATTERN .matcher (name );
191176 if (matcher .find ()) {
192177 try {
@@ -244,7 +229,7 @@ public Image createImage(boolean returnMissingImageOnError, Device device) {
244229 // We really want a fresh ImageFileNameProvider instance to make
245230 // sure the code that uses created images can use equals(),
246231 // see Image#equals
247- return new Image (device , new ImageProvider ());
232+ return new Image (device , createImageFileNameProvider ());
248233 } catch (SWTException | IllegalArgumentException exception ) {
249234 // If we fail, fall back to the old 1x implementation.
250235 }
@@ -283,7 +268,7 @@ private Image createDefaultImage(boolean returnMissingImageOnError,
283268 * @param name the file name
284269 * @return {@link String} or <code>null</code> if the file cannot be found
285270 */
286- String getFilePath (String name , boolean logIOException ) {
271+ private String getFilePath (String name , boolean logIOException ) {
287272 if (location == null )
288273 return IPath .fromOSString (name ).toOSString ();
289274
@@ -317,7 +302,7 @@ public <T> T getAdapter(Class<T> adapter) {
317302 }
318303 }
319304 if (adapter == ImageFileNameProvider .class ) {
320- return adapter .cast (new ImageProvider ());
305+ return adapter .cast (createImageFileNameProvider ());
321306 }
322307 return null ;
323308 }
0 commit comments