BrowseProjectController.java

package info.textgrid.rep.browseproject;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.SessionAttribute;
import info.textgrid.namespaces.middleware.tgsearch.Response;
import info.textgrid.namespaces.middleware.tgsearch.portal.Project;
import info.textgrid.rep.i18n.I18N;
import info.textgrid.rep.i18n.I18NProvider;
import info.textgrid.rep.markdown.MarkdownRenderService;
import info.textgrid.rep.service.TgcrudClientService;
import info.textgrid.rep.service.TgrepConfigurationService;
import info.textgrid.rep.service.TgsearchClientService;
import info.textgrid.rep.shared.Pager;
import info.textgrid.rep.shared.ToolLink;

@Controller
public class BrowseProjectController {

  private TgsearchClientService tgsearchClient;
  private MarkdownRenderService mds;
  private TgrepConfigurationService tgrepConfig;
  private I18NProvider i18nProvider;

  @Value("${tgsearch.query.maxhits}")
  private int maxhits;

  private static final Log log = LogFactory.getLog(BrowseProjectController.class);

  @Autowired
  public BrowseProjectController(
      TgsearchClientService tgsearchClient,
      TgcrudClientService tgcrudClient,
      MarkdownRenderService mds,
      TgrepConfigurationService tgrepConfig,
      I18NProvider i18nProvider) {
    this.tgsearchClient = tgsearchClient;
    this.mds = mds;
    this.tgrepConfig = tgrepConfig;
    this.i18nProvider = i18nProvider;
  }

  @GetMapping("/projects")
  public String projects(
      Locale locale,
      Model model,
      @RequestParam(value = "mode", defaultValue = "list") String mode,
      @RequestParam(value="limit", required=false, defaultValue="0") int limit,
      @RequestParam(value="order", required=false, defaultValue="count.desc") String order) throws IOException {

    boolean sandbox = this.tgrepConfig.getSandboxEnabled();

    I18N i18n = i18nProvider.getI18N(locale);

    // common variables for browse-root aggregations and browse single items
    model.addAttribute("mode", mode);

    List<Project> projects = this.tgsearchClient.getProjects(sandbox).getProjects();

    // sort by existance of portalconfig. object count otherwise.
    // list is pre-sorted by object count from tgsearch, so we do not sort all by count in a first comparision step
    projects.sort(new ProjectComparator());

    List<ToolLink> viewmodes = new ArrayList<ToolLink>();
    viewmodes
        .add(new ToolLink(i18n.get("list"), "/projects?mode=list", mode.equals("list")));
    viewmodes.add(new ToolLink(i18n.get("gallery"), "/projects?mode=gallery",
        mode.equals("gallery")));
    model.addAttribute("viewmodes", viewmodes);

    model.addAttribute("projects", projects);
    return "browseprojects";
  }

  @GetMapping("/project/{id}")
  public String projectById(
      Locale locale,
      Model model,
      @PathVariable("id") String id,
      @RequestParam(value = "mode", defaultValue = "list") String mode,
      @RequestParam(name="start", required=false, defaultValue="0") int start,
      @RequestParam(name="limit", required=false, defaultValue="20") int limit) {

    I18N i18n = i18nProvider.getI18N(locale);

    boolean sandbox = this.tgrepConfig.getSandboxEnabled();

    // common variables for browse-root aggregations and browse single items
    model.addAttribute("mode", mode);

    Response res = tgsearchClient.listProjectsToplevelObjects(id, start, limit, sandbox);

    Project project = tgsearchClient.getProjectConfig(id, sandbox);

    Pager pager = new Pager()
        .setHits(Integer.parseInt(res.getHits()))
        .setLimit(limit)
        .setStart(start)
        .setMaxHits(maxhits);

    pager.calculatePages();

    model.addAttribute("pager", pager);
    model.addAttribute("start", start);
    model.addAttribute("limit", limit);
    model.addAttribute("results", res.getResult());
    model.addAttribute("isProject", true);
    model.addAttribute("project", project);

    if(project.getReadme() != null) {
      try {
        String readme = mds.renderHtml(project.getReadme());
        model.addAttribute("readme", readme);
      } catch (IOException e) {
         log.error("error renderning markdown from string", e);
      }
    }

    List<ToolLink> viewmodes = new ArrayList<ToolLink>();
    viewmodes
        .add(new ToolLink(i18n.get("list"), "/project/"+id+"?mode=list", mode.equals("list")));
    viewmodes.add(new ToolLink(i18n.get("gallery"), "/project/"+id+"?mode=gallery",
        mode.equals("gallery")));
    model.addAttribute("viewmodes", viewmodes);

    List<ToolLink> tools = new ArrayList<ToolLink>();
    tools.add(new ToolLink(i18n.get("search-project"), "/search/?filter=project.id:" + id, false));
    tools.add(new ToolLink(i18n.get("search-project-fulltext"), "/search/?filter=format:text/xml&filter=project.id:" + id, false));
    model.addAttribute("tools", tools);

    return "browse";
  }

  /**
   * Comparator, which prefers Projects with a portalconfig (portalconfig not null)
   * and sorts by object count otherwise
   */
  public class ProjectComparator implements Comparator<Project> {

    @Override
    public int compare(Project p1, Project p2) {

      Object value1 = p1.getPortalconfig();
      Object value2 = p2.getPortalconfig();

      if (value1 == null && value2 == null) {
        return 0;
      } else if(value1 == null) {
        return 1;
      } else if (value2 == null) {
        return -1;
      } else {
        return p1.getCount() >= p2.getCount() ? -1 : 1;
      }
    }
  }



}