Package org.beangle.struts2.view.freemarker

Source Code of org.beangle.struts2.view.freemarker.BeangleObjectWrapper$FriendlyMapModel

/* Copyright c 2005-2012.
* Licensed under GNU  LESSER General Public License, Version 3.
* http://www.gnu.org/licenses
*/
package org.beangle.struts2.view.freemarker;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;

import freemarker.core.CollectionAndSequence;
import freemarker.ext.beans.CollectionModel;
import freemarker.ext.beans.MapModel;
import freemarker.ext.util.ModelFactory;
import freemarker.template.AdapterTemplateModel;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.ObjectWrapper;
import freemarker.template.SimpleSequence;
import freemarker.template.TemplateCollectionModel;
import freemarker.template.TemplateHashModelEx;
import freemarker.template.TemplateMethodModelEx;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException;

/**
* BeangleObjectWrapper不同于StrutsBeanWrapper,他扩展了DefaultObjectWrapper。提供了<br>
* 1)缺省的对象包装<br>
* 2)可以在set等没有顺序的模型使用?seq_contains等方法
* 3)恢复了在Map上的get方法(被DefaultObjectWrapper覆盖掉的)<br>
* 4)提供了map上的values方法(等同于StrutsBeanWrapper的功能)
*/
public class BeangleObjectWrapper extends DefaultObjectWrapper {
  private boolean altMapWrapper;

  public BeangleObjectWrapper(boolean altMapWrapper) {
    this.altMapWrapper = altMapWrapper;
  }

  /**
   * 特殊包装set和map
   */
  public TemplateModel wrap(Object obj) throws TemplateModelException {
    if (obj == null) { return super.wrap(null); }
    if (obj instanceof List<?>) { return new CollectionModel((Collection<?>) obj, this); }
    // 使得set等集合可以排序
    if (obj instanceof Collection<?>) { return new SimpleSequence((Collection<?>) obj, this); }
    if (obj instanceof Map<?, ?>) {
      if (altMapWrapper) {
        return new FriendlyMapModel((Map<?, ?>) obj, this);
      } else {
        return new MapModel((Map<?, ?>) obj, this);
      }
    }
    return super.wrap(obj);
  }

  // attempt to get the best of both the SimpleMapModel and the MapModel
  // of FM.
  @SuppressWarnings("rawtypes")
  protected ModelFactory getModelFactory(Class clazz) {
    if (altMapWrapper && Map.class.isAssignableFrom(clazz)) { return FriendlyMapModel.FACTORY; }

    return super.getModelFactory(clazz);
  }

  /**
   * Attempting to get the best of both worlds of FM's MapModel and
   * simplemapmodel, by reimplementing the isEmpty(), keySet() and values()
   * methods. ?keys and ?values built-ins are thus available, just as well as
   * plain Map methods.
   */
  private final static class FriendlyMapModel extends MapModel implements TemplateHashModelEx,
      TemplateMethodModelEx, AdapterTemplateModel {
    static final ModelFactory FACTORY = new ModelFactory() {
      public TemplateModel create(Object object, ObjectWrapper wrapper) {
        return new FriendlyMapModel((Map<?, ?>) object, (BeangleObjectWrapper) wrapper);
      }
    };

    public FriendlyMapModel(Map<?, ?> map, BeangleObjectWrapper wrapper) {
      super(map, wrapper);
    }

    // 将父类的&& super.isEmpty()省去了,原因不知
    public boolean isEmpty() {
      return ((Map<?, ?>) object).isEmpty();
    }

    // 此处实现与MapModel不同,MapModel中复制了一个集合
    // 影响了?keySet,?size方法
    protected Set<?> keySet() {
      return ((Map<?, ?>) object).keySet();
    }

    // add feature
    public TemplateCollectionModel values() {
      return new CollectionAndSequence(new SimpleSequence(((Map<?, ?>) object).values(),
          wrapper));
    }
  }
}
TOP

Related Classes of org.beangle.struts2.view.freemarker.BeangleObjectWrapper$FriendlyMapModel

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.