2013-10-28 5 views
1

특정 메서드를 호출하는 것과 관련된 String 속성이 있습니다. (GWT ClientBundle)문자열을 사용하여 GWT ClientBundle 인터페이스의 메서드를 호출하는 방법은 무엇입니까?

public interface MyClientBundle extends ClientBundle 
{ 
    @Source("icon_first.jpg") 
    ImageResource icon_first(); 

    @Source("logo_second.jpg") 
    ImageResource icon_second(); 

    @Source("icon_third.jpg") 
    ImageResource icon_third(); 
} 

나는 현재 선택 문에 비효율적 인 조회를 사용하고 있습니다 :

는 나는 이러한 방법을 내 인터페이스에서 아이콘 속성

public class MyDto 
{ 
    String icon; // "first", "second", "third" etc 

    public String getIcon() 
    { 
     return icon; 
    } 
} 

으로,이 DTO를 대신 문자열을 작성하여 올바른 메소드를 선택하려고합니다.

public ImageResource getValue(MyDto object) 
{ 
    return getIconFromCode(object.getIcon()); 
} 

private ImageResource getIconFromCode(String code) 
{ 
    if(code.equalsIgnoreCase("first")) 
    { 
     return resources.icon_first(); 
    } 
    else if(code.equalsIgnoreCase("second")) 
    { 
     return resources.icon_second(); 
    } 
    else if(code.equalsIgnoreCase("third")) 
    { 
     return resources.icon_third(); 
    } 
    else 
    { 
     return resources.icon_default(); 
    } 
} 

위 대신 올바른 방법을 선택하는 문자열을 만들려면 "icon_" + object.getIcon()+ "()"

나는 리플렉션을 사용해야한다는 것을 알고 있습니까? 어떻게 완성 될까요?

+0

무엇을이 용도로 사용하십니까? 반사는 다소 복잡하고 아마 당신이 원하는 것이 아니며, 나는 추측하고 있습니다. 빠른 액세스를 위해 배열, ArrayList 또는 HashMap을 사용할 수 있습니다. 배열과 ArrayList는 int 인덱스를 통해 조회 할 것이고, HashMap은 int 인덱스를 포함한 모든 키를 통해 인덱스 할 수있게 해줄 것입니다. 그런 다음 MyClientBundle 내부에서 키/인덱스 매개 변수를 사용하고 연관된 ImageResource를 반환하는 getter 메서드를 만들 수 있습니다. – stoooops

+0

ClientBundle은 각 메서드가 특정 이미지에 매핑되는 구체적인 클래스를 만드는 GWT 인터페이스입니다. 매번 올바른 이미지를 렌더링하고 싶지만 20 개 정도의 요소가있는 스위치 (또는 if-elses)는 원하지 않습니다. – slugmandrew

+0

MyClientBundle에 인터페이스를 추가하고 코드 생성기에서 실제 클래스를 생성하므로 메서드를 추가 할 수 없다고 생각합니다. 반사가 GWT 에뮬레이터에서 지원되지 않기 때문에 어쨌든 바보가되고 있습니다. 어떤 제안을 환영합니다 :) – slugmandrew

답변

4

대신 ClientBundle의 ClientBundleWithLookup을 연장한다.

ClientBundleWithLookup에는 리소스 이름 (메서드 이름)에서 리소스를 검색 할 수있는 getResource (String name) 메서드가 있습니다.

2

주석에서 아이콘 이름으로 getter 메소드를 캐시하고 해당 캐시를 사용하여 getter를 호출하십시오.

아래 코드는 한 수준 위의 인터페이스에서만 주석을 가져옵니다. 어떤 이유로 높은 값으로 가야 할 필요가 있다면 cacheGettersFor() 메서드를 재귀 적으로 호출하면됩니다.

아이콘 getter 메소드에 올바른 서명 (인수를 사용하지 않고 반환, ImageResource)이 있는지 확인하려면 여기에 체크하지 않아도됩니다.이 코드를 사용하는 경우 추가해야합니다. 인터페이스 MyClientBundle 정상적으로

public class IconGetterCache { 
    class IconGetterCacheForBundleType { 
     private Map<String, Method> _iconGetters = new HashMap<>(); 
     private Class<?> _runtimeClass; 

     private void cacheGettersFor(Class<?> forClazz) { 
      for (Method method : forClazz.getMethods()) { 
       Source iconSourceAnnotation = method.getAnnotation(Source.class); 
       if (iconSourceAnnotation != null) { 
        _iconGetters.put(iconSourceAnnotation.value(), method); 
       } 
      } 
     } 

     IconGetterCacheForBundleType(final Class<?> runtimeClass) { 
      _runtimeClass = runtimeClass; 
      for (Class<?> iface : _runtimeClass.getInterfaces()) { 
       cacheGettersFor(iface); 
      } 
      cacheGettersFor(_runtimeClass); 
     } 

     public ImageResource getIconFromBundle(ClientBundle bundle, String iconName) { 

      if (!_runtimeClass.isAssignableFrom(bundle.getClass())) { 
       throw new IllegalArgumentException("Mismatched bundle type"); 
      } 

      Method getter = _iconGetters.get(iconName); 
      if (getter == null) { return null; } 
      try { 
       return (ImageResource) getter.invoke(bundle); 
      } 
      catch (Throwable t) { 
       throw new RuntimeException("Could not get icon", t); 
      } 
     } 
    } 

    private Map<Class<?>, IconGetterCacheForBundleType> _getterCaches = new HashMap<>(); 

    //main entry point, use this to get your icons 
    public ImageResource getIconFromBundle(ClientBundle bundle, String iconName) { 
     final Class<? extends ClientBundle> getterClass = bundle.getClass(); 
     IconGetterCacheForBundleType getterCache = _getterCaches.get(getterClass); 
     if (getterCache == null) { 
      _getterCaches.put(getterClass, getterCache = new IconGetterCacheForBundleType(getterClass)); 
     } 
     return getterCache.getIconFromBundle(bundle, iconName); 
    } 
} 


//Here's how I tested 
IconGetterCache gc = new IconGetterCache(); 
MyClientBundle concreteClientBundle = new MyClientBundle() { 
    @Override 
    public ImageResource icon_first() { 
     //return correct icon 
    } 

    @Override 
    public ImageResource icon_second() { 
     //return correct icon 
    } 

    @Override 
    public ImageResource icon_third() { 
     //return correct icon 
    } 
}; 
gc.getIconFromBundle(concreteClientBundle, "icon_first.jpg"); 
+0

리플렉션은 GWT에서 작동합니까? – Fedy2

+0

@ Fedy2 - 아니요, GWT에서 리플렉션을 사용할 수 없습니다 – otonglet

+0

리플렉션을 사용하는 솔루션입니까? – Fedy2