Coverage Report - org.seasar.eclipse.common.util.ImageManager
 
Classes in this File Line Coverage Branch Coverage Complexity
ImageManager
86%
63/73
93%
26/28
0
 
 1  
 /*
 2  
  * Copyright 2004-2008 the Seasar Foundation and the Others.
 3  
  *
 4  
  * Licensed under the Apache License, Version 2.0 (the "License");
 5  
  * you may not use this file except in compliance with the License.
 6  
  * You may obtain a copy of the License at
 7  
  *
 8  
  *     http://www.apache.org/licenses/LICENSE-2.0
 9  
  *
 10  
  * Unless required by applicable law or agreed to in writing, software
 11  
  * distributed under the License is distributed on an "AS IS" BASIS,
 12  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 13  
  * either express or implied. See the License for the specific language
 14  
  * governing permissions and limitations under the License.
 15  
  */
 16  
 package org.seasar.eclipse.common.util;
 17  
 
 18  
 import java.io.InputStream;
 19  
 import java.lang.reflect.Field;
 20  
 import java.lang.reflect.Modifier;
 21  
 import java.net.URL;
 22  
 import java.util.Enumeration;
 23  
 import java.util.Locale;
 24  
 import java.util.ResourceBundle;
 25  
 
 26  
 import org.eclipse.jface.resource.ImageDescriptor;
 27  
 import org.eclipse.jface.resource.ImageRegistry;
 28  
 import org.eclipse.swt.graphics.Image;
 29  
 import org.eclipse.swt.graphics.ImageData;
 30  
 import org.eclipse.swt.widgets.Display;
 31  
 import org.seasar.framework.beans.BeanDesc;
 32  
 import org.seasar.framework.beans.factory.BeanDescFactory;
 33  
 import org.seasar.framework.exception.ResourceNotFoundRuntimeException;
 34  
 import org.seasar.framework.log.Logger;
 35  
 import org.seasar.framework.util.FieldUtil;
 36  
 import org.seasar.framework.util.ResourceUtil;
 37  
 
 38  
 /**
 39  
  * {@link Image} オブジェクトを管理するためのユーティリティクラスです。<br />
 40  
  * <p>
 41  
  * 本クラスは、クラスパス上のリソースとして存在するイメージファイルを読み込み、管理する機能を提供します。</br>
 42  
  * また、本クラスのメソッドに対してリソースのパスを指定する場合、先頭にスラッシュ(/)がついていてもいなくても同じパスとして扱います。</br>
 43  
  * たとえば、<code>&quot;org/seasar/uruma/images/xxxImage.png&quot;</code> と
 44  
  * <code>&quot;/org/seasar/uruma/images/xxxImage.png&quot;</code>
 45  
  * は同じものとして扱います。
 46  
  * </p>
 47  
  * 
 48  
  * @author y-komori
 49  
  */
 50  
 public class ImageManager {
 51  4
     private static ImageRegistry imageRegistry = new ImageRegistry();
 52  
 
 53  4
     protected static final Logger logger = Logger.getLogger(ImageManager.class);
 54  
 
 55  0
     private ImageManager() {
 56  0
     }
 57  
 
 58  
     /**
 59  
      * {@link ImageManager} を初期化します。<br />
 60  
      * 
 61  
      * @param display
 62  
      *            本クラスを使用する前に呼び出してください。
 63  
      */
 64  
     public static void init(final Display display) {
 65  164
         imageRegistry = new ImageRegistry(display);
 66  164
     }
 67  
 
 68  
     /**
 69  
      * 指定されたキーで登録された画像の {@link Image} オブジェクトを返します。<br />
 70  
      * 
 71  
      * @param key
 72  
      *            キー
 73  
      * @return 見つかった {@link Image} オブジェクト。見つからない場合は <code>null</code>。
 74  
      */
 75  
     public static Image getImage(final String key) {
 76  256
         return imageRegistry.get(key);
 77  
     }
 78  
 
 79  
     /**
 80  
      * 指定されたキーで登録された画像の {@link ImageDescriptor} オブジェクトを返します。<br />
 81  
      * 
 82  
      * @param key
 83  
      *            キー
 84  
      * @return 見つかった {@link ImageDescriptor} オブジェクト。見つからない場合は <code>null</code>。
 85  
      */
 86  
     public static ImageDescriptor getImageDescriptor(final String key) {
 87  32
         return imageRegistry.getDescriptor(key);
 88  
     }
 89  
 
 90  
     /**
 91  
      * <code>path</code> で指定された {@link Image} オブジェクトを検索し、存在しなければクラスパスからロードします。<br />
 92  
      * <p>
 93  
      * 本メソッドでは、まず <code>path</code> をキーと見なしてレジストリから {@link Image}
 94  
      * オブジェクトを検索します。 {@link Image} オブジェクトが見つからない場合、<code>path</code>
 95  
      * で示されるリソースをクラスパスからロードして <code>path</code> をキーとしてレジストリに登録します。<br />
 96  
      * この際、<code>path</code> は <code>/</code>(スラッシュ)で始まっていてもいなくても構いません。</br>
 97  
      * </p>
 98  
      * <dl>
 99  
      * <dt>【例】
 100  
      * <dd> loadImage("icons/app.png");
 101  
      * </dl>
 102  
      * <ul>
 103  
      * <li>まず、レジストリに対して <code>icons/app.png</code> というキーで <code>Image</code>
 104  
      * オブジェクトを検索します。
 105  
      * <li>見つからない場合、クラスパスから <code>icons/app.png</code> というリソースをロードします。
 106  
      * <li>ロードに成功すれば、<code>icons/app.png</code> というキーでレジストリに登録します。
 107  
      * <li>ここで見つからない場合は、{@link ResourceNotFoundRuntimeException} をスローします。
 108  
      * </ul>
 109  
      * 
 110  
      * @param path
 111  
      *            イメージのパス/キー
 112  
      * @return 見つかった {@link Image} オブジェクト
 113  
      * @throws ResourceNotFoundRuntimeException
 114  
      *             指定されたリソースが見つからなかった場合
 115  
      */
 116  
     public static Image loadImage(final String path) {
 117  76
         Image image = getImage(path);
 118  76
         if (image == null) {
 119  72
             image = putImage(path, path);
 120  
         }
 121  72
         return image;
 122  
     }
 123  
 
 124  
     /**
 125  
      * <code>path</code> で指定された {@link ImageDescriptor}
 126  
      * オブジェクトを検索し、存在しなければクラスパスからロードします。<br />
 127  
      * <p>
 128  
      * {@link Image} オブジェクトではなく {@link ImageDescriptor} オブジェクトを返すという点を除き、本メソッドは
 129  
      * {@link #loadImage(String)} メソッドと同じです。<br />
 130  
      * 詳細は {@link #loadImage(String)} メソッドの説明をご覧ください。
 131  
      * </p>
 132  
      * 
 133  
      * @param path
 134  
      *            イメージのパス/キー
 135  
      * @return 見つかった {@link ImageDescriptor} オブジェクト
 136  
      * @throws ResourceNotFoundRuntimeException
 137  
      *             指定されたリソースが見つからなかった場合
 138  
      */
 139  
     public static ImageDescriptor loadImageDescriptor(final String path) {
 140  16
         ImageDescriptor descriptor = getImageDescriptor(path);
 141  16
         if (descriptor == null) {
 142  12
             descriptor = putImageDescriptor(path, path);
 143  
         }
 144  16
         return descriptor;
 145  
     }
 146  
 
 147  
     /**
 148  
      * {@link Image} オブジェクトを登録します。<br />
 149  
      * <p>
 150  
      * <code>path</code> で示されるリソースをクラスパス上から読み込み、<code>key</code>
 151  
      * で示されるキーでレジストリに登録します。<br />
 152  
      * 既に同じキーで {@link Image} オブジェクトが登録されている場合、上書きします。</br>
 153  
      * </p>
 154  
      * 
 155  
      * @param key
 156  
      *            キー
 157  
      * @param path
 158  
      *            イメージのパス
 159  
      * @return 登録した {@link Image} オブジェクト
 160  
      * @throws ResourceNotFoundRuntimeException
 161  
      *             指定されたリソースが見つからなかった場合
 162  
      */
 163  
     public static Image putImage(final String key, final String path) {
 164  84
         checkKey(key);
 165  
 
 166  84
         InputStream is = ResourceUtil.getResourceAsStream(normalizePath(path));
 167  76
         Image image = new Image(Display.getCurrent(), is);
 168  76
         imageRegistry.put(key, image);
 169  76
         return image;
 170  
     }
 171  
 
 172  
     /**
 173  
      * {@link ImageData} から生成した {@link Image} オブジェクトを登録します。<br />
 174  
      * <p>
 175  
      * 既に同じキーで {@link Image} オブジェクトが登録されている場合、上書きします。</br>
 176  
      * </p>
 177  
      * 
 178  
      * @param key
 179  
      *            キー
 180  
      * @param imageData
 181  
      *            {@link ImageData} オブジェクト
 182  
      * @return 登録した {@link Image} オブジェクト
 183  
      */
 184  
     public static Image putImage(final String key, final ImageData imageData) {
 185  0
         checkKey(key);
 186  0
         Image image = new Image(Display.getCurrent(), imageData);
 187  0
         imageRegistry.put(key, image);
 188  0
         return image;
 189  
     }
 190  
 
 191  
     /**
 192  
      * <code>ImageDescriptor</code> オブジェクトを登録します。<br />
 193  
      * <p>
 194  
      * <code>path</code> で示されるリソースをクラスパス上から読み込み、{@link ImageDescriptor}
 195  
      * オブジェクトとして <code>key</code> で示されるキーでレジストリに登録します。<br />
 196  
      * 既に同じキーで {@link ImageDescriptor} オブジェクトが登録されている場合、上書きします。<br />
 197  
      * </p>
 198  
      * 
 199  
      * @param key
 200  
      *            キー
 201  
      * @param path
 202  
      *            リソースのパス
 203  
      * @return 登録した {@link ImageDescriptor} オブジェクト
 204  
      * @throws ResourceNotFoundRuntimeException
 205  
      *             指定されたリソースが見つからなかった場合
 206  
      */
 207  
     public static ImageDescriptor putImageDescriptor(final String key,
 208  
             final String path) {
 209  304
         checkKey(key);
 210  
 
 211  304
         URL url = ResourceUtil.getResource(normalizePath(path));
 212  300
         ImageDescriptor descriptor = ImageDescriptor.createFromURL(url);
 213  300
         imageRegistry.put(key, descriptor);
 214  300
         return descriptor;
 215  
     }
 216  
 
 217  
     /**
 218  
      * {@link ResourceBundle} からイメージを読み込み、一括登録します。<br />
 219  
      * <p>
 220  
      * 「key=path」の形式で記述されたプロパティファイルを元にした {@link ResourceBundle} から {@link Image}
 221  
      * オブジェクトを一括して読み込みます。
 222  
      * </p>
 223  
      * <p>
 224  
      * 本メソッドではイメージを {@link ImageDescriptor} として登録します。
 225  
      * </p>
 226  
      * 
 227  
      * <p>
 228  
      * コーディング例
 229  
      * </p>
 230  
      * 
 231  
      * <pre>
 232  
      * ResourceBundle imageResources = ResourceBundle.getBundle(&quot;urumaImages&quot;);
 233  
      * ImageManager.loadImages(imageResources);
 234  
      * </pre>
 235  
      * 
 236  
      * @param bundle
 237  
      *            リソースバンドルの参照
 238  
      */
 239  
     public static void loadImages(final ResourceBundle bundle) {
 240  124
         Enumeration keys = bundle.getKeys();
 241  408
         while (keys.hasMoreElements()) {
 242  284
             String key = (String) keys.nextElement();
 243  284
             String path = bundle.getString(key);
 244  284
             putImageDescriptor(key, path);
 245  284
         }
 246  124
     }
 247  
 
 248  
     /**
 249  
      * 指定したクラスローダの {@link ResourceBundle} からイメージを読み込み、一括登録します。<br />
 250  
      * <p>
 251  
      * 「key=path」の形式で記述されたプロパティファイルを元にした {@link ResourceBundle} から {@link Image}
 252  
      * オブジェクトを一括して読み込みます。
 253  
      * </p>
 254  
      * <p>
 255  
      * 本メソッドではイメージを {@link ImageDescriptor} として登録します。
 256  
      * </p>
 257  
      * 
 258  
      * @param baseName
 259  
      *            リソースバンドルの基底名
 260  
      * @param loader
 261  
      *            リソースバンドルを読み込むクラスローダ
 262  
      */
 263  
     public static void loadImages(final String baseName,
 264  
             final ClassLoader loader) {
 265  0
         ResourceBundle imageResources = ResourceBundle.getBundle(baseName,
 266  
                 Locale.getDefault(), loader);
 267  0
         loadImages(imageResources);
 268  0
     }
 269  
 
 270  
     /**
 271  
      * {@link ResourceBundle} からイメージを読み込み、一括登録します。<br />
 272  
      * <p>
 273  
      * 「key=path」の形式で記述されたプロパティファイルを元にした {@link ResourceBundle} から {@link Image}
 274  
      * オブジェクトを一括して読み込みます。
 275  
      * </p>
 276  
      * <p>
 277  
      * 本メソッドではイメージを {@link ImageDescriptor} として登録します。
 278  
      * </p>
 279  
      * 
 280  
      * @param baseName
 281  
      *            リソースバンドルの基底名
 282  
      */
 283  
     public static void loadImages(final String baseName) {
 284  124
         ResourceBundle imageResources = ResourceBundle.getBundle(baseName);
 285  124
         loadImages(imageResources);
 286  124
     }
 287  
 
 288  
     /**
 289  
      * 指定されたクラスの定数フィールドに対して、 {@link ImageManager} が 管理するオブジェクトをインジェクションします。</br>
 290  
      * インジェクション対象となるのは、以下の条件を満たすフィールドです。<br />
 291  
      * <p>
 292  
      * <ol>
 293  
      * <li><code>public static</code> な定数フィールドであること
 294  
      * <li>{@link Image} または {@link ImageDescriptor} 型のフィールドであること
 295  
      * </ol>
 296  
      * </p>
 297  
      * 以上の条件を満たすフィールドに対して、フィールド名をキーとして {@link ImageManager} が登録する {@link Image}
 298  
      * または {@link ImageDescriptor} を検索し、見つかればインジェクションを行います。<br />
 299  
      * 見つからなかった場合は、Warning ログを出力します。
 300  
      * <p>
 301  
      * <b>【例】</b><br />
 302  
      * 以下の例では、<code>ImageHolder</code> クラスの フィールド、<code>IMAGE_A</code> と
 303  
      * <code>IMAGE_B</code> に対して、 {@link ImageManager} が管理するオブジェクトの中から、<code>IMAGE_A</code>、<code>IMAGE_B</code>
 304  
      * という名前のキーで登録されたオブジェクトをインジェクションします。
 305  
      * 
 306  
      * <pre>
 307  
      *                           public class ImageHolder() {
 308  
      *                               public static Image IMAGE_A;
 309  
      *                               public static ImageDescriptor IMAGE_B;
 310  
      *                           }
 311  
      * </pre>
 312  
      * <pre>
 313  
      * ImageManager.injectImages(ImageHolder.class);
 314  
      * </pre>
 315  
      * 
 316  
      * </p>
 317  
      * 
 318  
      * @param clazz
 319  
      *            対象クラス
 320  
      */
 321  
     public static void injectImages(final Class clazz) {
 322  4
         BeanDesc beanDesc = BeanDescFactory.getBeanDesc(clazz);
 323  56
         for (int i = 0; i < beanDesc.getFieldSize(); i++) {
 324  52
             Field field = beanDesc.getField(i);
 325  52
             String key = field.getName();
 326  52
             if (!validateMask(field)) {
 327  28
                 continue;
 328  
             }
 329  
 
 330  24
             if (isAssignableFrom(Image.class, field)) {
 331  12
                 injectField(clazz, field, imageRegistry.get(key));
 332  12
             } else if (isAssignableFrom(ImageDescriptor.class, field)) {
 333  12
                 injectField(clazz, field, imageRegistry.getDescriptor(key));
 334  
             }
 335  
         }
 336  4
     }
 337  
 
 338  
     /**
 339  
      * {@link ImageManager} が管理する {@link ImageRegistry} を破棄します。<br />
 340  
      * <p>
 341  
      * 再び {@link ImageManager} を使用したい場合、{@link #init(Display)} メソッドを呼び出してください。<br />
 342  
      * </p>
 343  
      */
 344  
     public static void dispose() {
 345  280
         if (imageRegistry != null) {
 346  164
             imageRegistry.dispose();
 347  
         }
 348  280
         imageRegistry = null;
 349  280
     }
 350  
 
 351  
     protected static void injectField(final Class clazz, final Field field,
 352  
             final Object o) {
 353  24
         if (o != null) {
 354  16
             FieldUtil.set(field, null, o);
 355  
         }
 356  24
     }
 357  
 
 358  
     protected static boolean validateMask(final Field field) {
 359  52
         final int MOD_EXPECTED = Modifier.PUBLIC | Modifier.STATIC;
 360  52
         final int MOD_MASK = MOD_EXPECTED | Modifier.FINAL;
 361  52
         return (field.getModifiers() & MOD_MASK) == MOD_EXPECTED;
 362  
     }
 363  
 
 364  
     protected static boolean isAssignableFrom(final Class<?> clazz,
 365  
             final Field target) {
 366  36
         return clazz.isAssignableFrom(target.getType());
 367  
     }
 368  
 
 369  
     protected static void checkKey(final String key) {
 370  388
         if (imageRegistry.get(key) != null) {
 371  0
             imageRegistry.remove(key);
 372  
         }
 373  388
     }
 374  
 
 375  
     protected static String normalizePath(final String path) {
 376  404
         if ((path != null) && (path.startsWith("/"))) {
 377  320
             if (path.length() > 1) {
 378  316
                 return path.substring(1);
 379  
             }
 380  4
                         return "";
 381  
         }
 382  84
                 return path;
 383  
     }
 384  
 }