Package javango.contrib.admin.views

Source Code of javango.contrib.admin.views.Main$ModelDefinition

package javango.contrib.admin.views;

import static javango.contrib.freemarker.Helper.renderToResponse;
import static javango.util.Humanize.humanize;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javango.api.Settings;
import javango.contrib.admin.FieldSet;
import javango.contrib.admin.MetaOptions;
import javango.contrib.admin.api.AdminAction;
import javango.contrib.admin.api.AdminOptions;
import javango.contrib.admin.api.ModelAdmin;
import javango.contrib.hibernate.HibernateUtil;
import javango.contrib.hibernate.ModelForm;
import javango.contrib.jquery.Helper;
import javango.db.Manager;
import javango.db.ManagerException;
import javango.db.Managers;
import javango.db.PaginatorWidget;
import javango.db.QuerySet;
import javango.db.QuerySetPage;
import javango.db.QuerySetPaginator;
import javango.forms.Form;
import javango.forms.fields.CharField;
import javango.forms.fields.DateField;
import javango.forms.fields.Field;
import javango.forms.fields.FieldFactory;
import javango.forms.fields.annotations.FieldProperties;
import javango.http.Http404;
import javango.http.Http500;
import javango.http.HttpException;
import javango.http.HttpRequest;
import javango.http.HttpResponse;
import javango.http.HttpResponseRedirect;
import javango.http.SimpleHttpResponse;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.tool.hbm2ddl.SchemaExport;

import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Provider;

public class Main {

  private final static Log log = LogFactory.getLog(Main.class);
 
  protected Injector injector;
  protected HibernateUtil hibernateUtil;
  protected FieldFactory fieldFactory;
  protected Provider<Helper> jqueryProvider;
  protected AdminOptions options;
  protected Managers managers;
  protected Settings settings;
 
  @Inject
  public Main(Injector injector, Settings settings, HibernateUtil hibernateUtil, FieldFactory fieldFactory, Provider<Helper> jqueryProvider, AdminOptions options, Managers managers) {
    super();
    this.hibernateUtil = hibernateUtil;
    this.fieldFactory = fieldFactory;
    this.jqueryProvider = jqueryProvider;
    this.options = options;
    this.managers = managers;
    this.settings = settings;
    this.injector = injector;
  }
 
  private String findVerboseName(Class clazz, ModelAdmin ma) {
    if (ma.getVerboseName() != null) {
      return ma.getVerboseName();
    }
   
    String className = clazz.getName();
    MetaOptions options = (MetaOptions)clazz.getAnnotation(MetaOptions.class);
    return options == null || "".equals(options.verboseName())
            ? className.substring(className.lastIndexOf(".")+1)
            : options.verboseName();
  }
  private Manager findManager(Class clazz, ModelAdmin ma) {
    Manager m = ma.getManager();
    if (m == null) {
      m = managers.forClass(clazz);
    }
    return m;
  }
 
  protected void updateContext(Map<String, Object> context , Class pc, ModelAdmin ma) {
    context.put("entity", new ModelDefinition(pc, ma));
    context.put("app_name", options.getAppName());
  }
 
  public class ModelDefinition {
    protected String className;
    protected String verboseName;
   
    public String getClassName() {
      return className;
    }

    public void setClassName(String className) {
      this.className = className;
    }

    public String getVerboseName() {
      return verboseName;
    }

    public void setVerboseName(String verboseName) {
      this.verboseName = verboseName;
    }

    public ModelDefinition(Class clazz, ModelAdmin ma) {
      super();
      this.className = clazz.getName();
      this.verboseName = findVerboseName(clazz, ma);
    }
   
    @Override
    public String toString() {
      return verboseName;
    }
   
  }
 
  public HttpResponse index(HttpRequest request) {
    Map<String, List<ModelDefinition>> packageMap = new HashMap<String, List<ModelDefinition>>();   
   
    Iterator<Class> i = options.getClassMappings();
    while (i.hasNext()) {
      Class pc = i.next();
      ModelAdmin ma = options.getModelAdmin(pc);
      if (ma.isAuthorized(request.getUser())) {
        String className = pc.getName();
        String packageName =  className.substring(0,className.lastIndexOf("."));
        if (log.isDebugEnabled()) log.debug ("Adding class: " + className);
        if (packageMap.containsKey(packageName)) {
          List<ModelDefinition> appList = packageMap.get(packageName);
          appList.add(new ModelDefinition(pc, ma));
        } else {
          List<ModelDefinition> appList = new ArrayList<ModelDefinition>();
          appList.add(new ModelDefinition(pc, ma));
          packageMap.put(packageName, appList);
        }
      } else if (log.isDebugEnabled()){
        log.debug("Skipping " + pc.getName() + " due to authority.");
      }
    }
    log.debug("Complete parsing class mappings");
   
    Map<String, Object> context = new HashMap<String, Object>();
    context.put("package_map", packageMap);
   
    context.put("page_title", "Site administration");
    context.put("app_name", options.getAppName());
    return renderToResponse(options.getIndexTemplate(), context);
  }
 
  protected int getPageNumber(HttpRequest request) {
    String value = request.getParameter("p");
    try {
      return value == null ? 1 : Integer.valueOf(value);
    } catch (NumberFormatException e) {
      log.debug(e,e);
      return 1;
    }
  }
 
  protected String generateSearchParams(HttpRequest request, Map<String, String> map) {
    StringBuilder b = new StringBuilder();
    for (Map.Entry<String, String[]> entry : request.getParameterMap().entrySet()) {     
      if (entry.getKey().contains("__")) {
        String[] value = entry.getValue();
        if (value != null && value.length > 0 & StringUtils.isNotEmpty(value[0])) {
          // TODO Add AND ability,  chain the String[] somehow...
          String valueString = entry.getValue()[0];
          if (map != null)
            try {
              map.put(entry.getKey(), valueString);
              b.append(String.format("%s=%s&", entry.getKey(), URLEncoder.encode(valueString, settings.getDefaultCharset())));
            } catch (UnsupportedEncodingException e) {
              log.error(e,e);
            }
        }
      }
    }
    return b.toString();
  }
 
  public HttpResponse search(HttpRequest request, String model) throws HttpException {
    Class pc = options.getClassMapping(model);
    if (pc == null) {
      throw new Http404("Class not found");
    }
    ModelAdmin ma = options.getModelAdmin(pc);
   
    if (!ma.isReader(request.getUser())) {
      throw new Http404("Class not found, or not authorized");
    }
   
    String[] property_list = ma.getListSearchFields();     

    Form form = ma.getSearchForm();

    if (form == null) {
      String[] includeFields = property_list == null ? getIncludeFields(pc) : property_list;

      ModelForm<?> mForm = new ModelForm(fieldFactory, hibernateUtil, managers);
      mForm.setInclude(includeFields);
      mForm.setModel(pc);

      for (Field f : mForm.getFields().values()) {
        f.setRequired(false).setAllowNull(true);
        f.setEditable(true);
        if (f.getClass().equals(CharField.class)) {
          f.setName(f.getName() + "__ilike");
        } else if (f.getClass().equals(DateField.class)) {
          f.setName(f.getName() + "__date");
        } else {
          f.setName(f.getName() + "__eq");
        }
      }
     
      form = mForm;
    }
   

   
    if ("POST".equals(request.getMethod())) {
      form.bind(request.getParameterMap());
      if (form.isValid()) {
        // TODO better way to get the relative 'admin' part of the url
        Map<String, String> params = new HashMap<String, String>();
        generateSearchParams(request, params);
        return new HttpResponseRedirect("../", params);
      }
    }
   
    Map<String, Object> context = new HashMap<String, Object>();
    context.put("form", form);
    context.put("jquery", jqueryProvider.get().setBasePath(request.getContext()).forForm(form));

    updateContext(context, pc, ma);
   
    context.put("page_title", String.format("%s Search", findVerboseName(pc, ma)));
    return renderToResponse(ma.getSearchFormTemplate(), context);

  }
 
  public HttpResponse changeList(HttpRequest request, String model) throws HttpException {
    try {
      Class pc = options.getClassMapping(model);
      if (pc == null) {
        throw new Http404("Class not found");
      }
      ModelAdmin ma = options.getModelAdmin(pc);
     
      if (!ma.isReader(request.getUser())) {
        throw new Http404("Class not found, or not authorized");
      }
     
      Manager<?> manager = findManager(pc, ma);

      String[] property_list = ma.getListDisplay();
      List<String> header_list = new ArrayList<String>();
      for(String property : property_list) {
        header_list.add(getChangeListLabel(pc, ma, property));
      }
     
      Map<String, String> searchParams = new HashMap<String, String>();
      for(Entry<String, String[]> e : request.getParameterMap().entrySet()) {
        if (e.getKey().contains("__")) {
          String value = e.getValue() == null ? null : e.getValue().length == 0 ? null : e.getValue()[0];
          searchParams.put(e.getKey(), value);
        }
      }
     
      QuerySet<?> qs = manager.filter(searchParams);
      String[] orderBy = ma.getOrderBy();
      if (orderBy == null) {
        qs = qs.orderBy(manager.getPkProperty());
      } else {
        qs = qs.orderBy();
      }
      String tool = request.getParameter("tool");
      // an action has been selected or clicked
      if (tool != null) {
        for (AdminAction action : ma.getListTools()) {
          if (tool.equals(action.getClass().getName())) {
            return action.execute(ma, request, qs);
          }
        }
      }
     
      QuerySetPaginator<?> paginator = new QuerySetPaginator(qs, 30);

      String query_string = generateSearchParams(request, searchParams);

      QuerySetPage<?> page = paginator.getPage(getPageNumber(request));
      List<?> object_list = page.getObjectList();
     
      Map<String, Object> context = new HashMap<String, Object>();
      context.put("header_list", header_list);
      context.put("property_list", property_list);
      context.put("object_list", object_list);
      context.put("key_property", manager.getPkProperty());
      context.put("link_property", ma.getListDisplayLinks() == null ? property_list[0] : ma.getListDisplayLinks());
      context.put("paginator", new PaginatorWidget(paginator, getPageNumber(request), query_string));
      context.put("query_string", query_string);
      context.put("list_tools", ma.getListTools());
      updateContext(context, pc, ma);
         
      context.put("page_title", String.format("Select %s to change", findVerboseName(pc, ma)));     
      return renderToResponse(ma.getChangeListTemplate(), context);
    } catch (ManagerException e) {
      throw new HttpException(e);
    }
  }
 
  /**
   * Given a class and property return the Label for the change list.
   * @param pc
   * @param ma
   * @param property
   * @return
   */
  private String getChangeListLabel(Class pc, ModelAdmin ma, String property) {
    // todo maybe add ability to add labels to modeladmin and add that here.
    FieldProperties properties = (FieldProperties)pc.getAnnotation(FieldProperties.class);
    String label = null;
    if (properties != null) {
      label = properties.label();
    }
    if (label == null) {
      String pieces[] = property.split(":");
      if (pieces.length > 1) { // includes a :
        label = pieces[0];
      } else { // does not include the :
        pieces = property.split("\\.");
        property = pieces[pieces.length-1];
        label = humanize(property);
      }
    }
    return label;
   
  }

  public HttpResponse add(HttpRequest request, String model) throws HttpException {   
    return change(request, model, null);
  }
 
  protected String[] getIncludeFields(Class pc) {
    FieldSet fieldSet = (FieldSet)pc.getAnnotation(FieldSet.class);
    if (fieldSet != null) {
      return fieldSet.fields();
    }
   
    return null;

  }
 
  public HttpResponse change(HttpRequest request, String model, String object_id) throws HttpException {
    try {
      object_id = object_id == null ? null : URLDecoder.decode(object_id, settings.getDefaultCharset());
     
      // TODO Changet object_id to an Object and figure out the correct datatype from the dao. dont' think this is necessary
      Class pc = options.getClassMapping(model);
      if (pc == null) {
        throw new Http404("Class not found");
      }
      ModelAdmin ma = options.getModelAdmin(pc);
     
      if (object_id != null && !ma.isEditor(request.getUser())) {
        throw new Http404("Class not found, or not authorized");
      } else if (!ma.isAuthor(request.getUser())) {
        throw new Http404("Class not found, or not authorized");
      }
     
      Manager manager = findManager(pc, ma);
     
      Object object = null;

      if (object_id != null) {
        object = manager.get(object_id);
        if (object == null) {
          return new SimpleHttpResponse("Object not found");
        }
      }

      String[] property_list = ma.getFields();     

      Form form = ma.getForm();
     
      if (form == null) {
        String[] includeFields = property_list == null ? getIncludeFields(pc) : property_list;
 
        ModelForm mForm = new ModelForm(fieldFactory, hibernateUtil, managers);
        if (includeFields != null) mForm.setInclude(includeFields);
        mForm.setModel(pc);
        form = mForm;
      }
     
      if ("POST".equals(request.getMethod())) {
        // update the object
        if (object == null) object=injector.getInstance(pc);
       
        form.bind(request.getParameterMap());
        // form = modelFactory.form(pc.getMappedClass(), request.getParameterMap());
        if (form.isValid()) {
//          if (object_id == null) { // this is a new object
//            if (!bl.canCreate()) {
//              throw new HttpException("Unable to create");
//            }
//          } else {
//            if (!bl.canUpdate(object)) {
//              throw new HttpException("Unable to updte");
//            }
//          }
         
          form.clean(object);
          try {
            if (object_id == null) {
              manager.create(object);
            } else {
              manager.save(object);
            }
           
            if (request.getParameterMap().containsKey("_addanother")) {
              return new HttpResponseRedirect("../add");
            } else if (request.getParameterMap().containsKey("_continue")) {
              return new HttpResponseRedirect(String.format("../%s/", manager.getPk(object)));
            }
            return new HttpResponseRedirect("..");
          } catch (ManagerException e) {
            request.getSession().addError(e.getMessage());
          }
        }
      } else {
        // display the form
        if (object != null) form.setInitial(object);
      }
         
      Map<String, Object> context = new HashMap<String, Object>();
      context.put("property_list", property_list);
      context.put("object", object);
      context.put("form", form);
      context.put("object_id", object_id);
      context.put("jquery", jqueryProvider.get().setBasePath(request.getContext()).forForm(form));
      updateContext(context, pc, ma);
         
      context.put("page_title", String.format("Change %s", findVerboseName(pc, ma)));
      return renderToResponse(ma.getChangeFormTemplate(), context);
    } catch (Exception e) {
      log.error(e,e);
      throw new HttpException(e);
    }
  }
 
  public HttpResponse delete(HttpRequest request, String model, String object_id) throws HttpException {
    try {
      object_id = object_id == null ? null : URLDecoder.decode(object_id, settings.getDefaultCharset());

      Class pc = options.getClassMapping(model);
      if (pc == null) {
        throw new Http404("Class not found");
      }
      ModelAdmin ma = options.getModelAdmin(pc);
     
      Manager manager = findManager(pc, ma);

      Object object = manager.get(object_id);
      if (object == null) {
        throw new Http404("Not found"); // TODO 404
      }
 
//      if (!bl.canDelete(object)) {
//        throw new HttpException("Unauthorized to delete");
//      }
       
      if ("POST".equals(request.getMethod())) {
        try {
          manager.delete(object);
          return new HttpResponseRedirect("../..");
        } catch (ManagerException e) {
          request.getSession().addError(e.getMessage());
        }
      }
     
      Map<String, Object> context = new HashMap<String, Object>();
      context.put("object", object);
      updateContext(context, pc, ma);
     
      context.put("page_title", "Are you sure?");
      return renderToResponse(ma.getConfirmDeleteTemplate(), context);
    } catch (Exception e) {
      log.error(e,e);
      throw new HttpException(e);
    }
  }
 
  public HttpResponse resetdb(HttpRequest request) {
    if ("POST".equals(request.getMethod())) {
      Configuration cfg = hibernateUtil.getConfiguration();
      new SchemaExport(cfg).drop(false, true);
      new SchemaExport(cfg).create(false, true);
      request.getSession().addMessage("Tables created successfully");
      return new HttpResponseRedirect("..");
    }
   
    Map<String, Object> context = new HashMap<String, Object>();
    context.put("page_title", "Are you sure?");
    return renderToResponse("/javango/contrib/admin/templates/confirm_reset_db.ftl", context);
  }
}
TOP

Related Classes of javango.contrib.admin.views.Main$ModelDefinition

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.