GWT polymorphic lists with @ExtraTypes

最后都变了- 提交于 2019-12-04 20:04:41

I do the exact same thing for quite a few classes but it will always return me the base type which I can iterate through and test for instanceof if needed. You will probably have to cast the object to the subclass. If you do not add the @ExtraTypes you will know because on the server side you will get a message stating that MoreSpecificChildBean cannot be sent to the client.

I only annotate the service and not the proxy, I ran into some quirks with 2.4 adding @ExtraTypes to the proxy.

/**
 * Base proxy that all other metric proxies extend. It is used mainly for it's
 * inheritence with the RequestFactory. It's concrete implementation is
 * {@link MetricNumber}.
 * 
 * @author chinshaw
 */
@ProxyFor(value = Metric.class, locator = IMetricEntityLocator.class)
public interface MetricProxy extends DatastoreObjectProxy {


    /**
     * Name of this object in the ui. This will commonly be extended by
     * subclasses.
     */
    public String NAME = "Generic Metric";

    /**
     * This is a list of types of outputs that the ui can support. This is
     * typically used for listing types of supported Metrics in the operation
     * output screen.
     * 
     * @author chinshaw
     */
    public enum MetricOutputType {
        MetricNumber, MetricString, MetricCollection, MetricStaticChart, MetricDynamicChart
    }

    /**
     * See {@link MetricNumber#setName(String)}
     * 
     * @param name
     */
    public void setName(String name);

    /**
     * See {@link MetricNumber#setContext(String)}
     * 
     * @return name of the metric.
     */
    public String getName();


    /**
     * Get the list of violations attached to this metric.
     * 
     * @return
     */
    public List<ViolationProxy> getViolations();
}

@ProxyFor(value = MetricNumber.class, locator = IMetricEntityLocator.class)
public interface MetricNumberProxy extends MetricProxy {

    public List<NumberRangeProxy> getRanges();

    public void setRanges(List<NumberRangeProxy> ranges);
}

...

@ProxyFor(value = MetricDouble.class, locator = IMetricEntityLocator.class)
public interface MetricDoubleProxy extends MetricNumberProxy {

    /* Properties when fetching the object for with clause */
    public static String[] PROPERTIES = {"ranges"};

    public Double getValue();
}

...

@ProxyFor(value = MetricPlot.class, locator = IMetricEntityLocator.class)
public interface MetricPlotProxy extends MetricProxy {

    /**
     * UI Name of the object.
     */
    public String NAME = "Static Plot";

    public String getPlotUrl();
}

This is a made up method from because I usually always return composite classes that may contain a list of metrics. That being said this will return me the base type of metrics, and then I can cast them.

@ExtraTypes({ MetricProxy.class, MetricNumberProxy.class, MetricDoubleProxy.class, MetricIntegerProxy.class})
@Service(value = AnalyticsOperationDao.class, locator = DaoServiceLocator.class)
public interface AnalyticsOperationRequest extends DaoRequest<AnalyticsOperationProxy> {

    Request<List<<MetricProxy>> getSomeMetrics();

}

Not an exact method I use but will work for getting a proxy of type.

context.getSomeMetrics().with(MetricNumber.PROPERTIES).fire(new Receiver<List<MetricProxy>>() {

  public void onSuccess(List<MetricProxy> metrics) {
      for (MetricProxy metric : metrics) {
          if (metric instanceof MetricDoubleProxy) {
              logger.info("Got a class of double " + metric.getValue());
          }
      }          
  }
}

You will know if you are missing an @ExtraTypes annotation when you get the error stated above.

Hope that helps

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!