package org.molgenis.ui.menumanager;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.TreeTraverser;
import org.molgenis.data.settings.AppSettings;
import org.molgenis.file.FileStore;
import org.molgenis.framework.ui.MolgenisPlugin;
import org.molgenis.ui.*;
import org.molgenis.ui.menu.Menu;
import org.molgenis.util.FileUploadUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.Part;
import javax.validation.Valid;
import java.io.File;
import java.io.IOException;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import static org.molgenis.ui.menumanager.MenuManagerController.URI;
import static org.springframework.http.HttpStatus.OK;
import static org.springframework.web.bind.annotation.RequestMethod.GET;
import static org.springframework.web.bind.annotation.RequestMethod.POST;
/**
* Plugin to view and modify the app UI menu
*/
@Controller
@RequestMapping(URI)
public class MenuManagerController extends MolgenisPluginController
{
public static final String ID = "menumanager";
public static final String URI = MolgenisPluginController.PLUGIN_URI_PREFIX + ID;
private final MenuManagerService menuManagerService;
private final FileStore fileStore;
private final MolgenisUi molgenisUi;
private final AppSettings appSettings;
private static final String ERRORMESSAGE_LOGO = "The logo needs to be an image file like png or jpg.";
@Autowired
public MenuManagerController(MenuManagerService menuManagerService, FileStore fileStore, MolgenisUi molgenisUi,
AppSettings appSettings)
{
super(URI);
if (menuManagerService == null) throw new IllegalArgumentException("menuManagerService is null");
if (molgenisUi == null) throw new IllegalArgumentException("molgenisUi is null");
if (fileStore == null) throw new IllegalArgumentException("fileStore is null");
if (appSettings == null) throw new IllegalArgumentException("appSettings is null");
this.menuManagerService = menuManagerService;
this.molgenisUi = molgenisUi;
this.fileStore = fileStore;
this.appSettings = appSettings;
}
@RequestMapping(method = GET)
public String init(Model model)
{
List<MolgenisUiMenuItem> menus = new TreeTraverser<MolgenisUiMenuItem>()
{
@Override
public Iterable<MolgenisUiMenuItem> children(MolgenisUiMenuItem root)
{
if (root.getType() == MolgenisUiMenuItemType.MENU)
{
MolgenisUiMenu menu = (MolgenisUiMenu) root;
return Iterables.filter(menu.getItems(), new Predicate<MolgenisUiMenuItem>()
{
@Override
public boolean apply(MolgenisUiMenuItem molgenisUiMenuItem)
{
return molgenisUiMenuItem.getType() == MolgenisUiMenuItemType.MENU;
}
});
}
else return Collections.emptyList();
}
}.preOrderTraversal(molgenisUi.getMenu()).toList();
List<MolgenisPlugin> plugins = Lists.newArrayList(menuManagerService.getPlugins());
Collections.sort(plugins, new Comparator<MolgenisPlugin>()
{
@Override
public int compare(MolgenisPlugin molgenisPlugin1, MolgenisPlugin molgenisPlugin2)
{
return molgenisPlugin1.getId().compareTo(molgenisPlugin2.getId());
}
});
model.addAttribute("menus", menus);
model.addAttribute("plugins", plugins);
model.addAttribute("molgenis_ui", molgenisUi);
return "view-menumanager";
}
@RequestMapping(value = "/save", method = POST)
@ResponseStatus(OK)
public void save(@Valid @RequestBody Menu molgenisMenu)
{
menuManagerService.saveMenu(molgenisMenu);
}
@RequestMapping(value = "logo", method = POST)
public void uploadLogo(@Valid @RequestBody File newLogo)
{
System.out.println(newLogo.getName());
}
/**
* Upload a new molgenis logo
*
* @param part
* @param model
* @return model
* @throws IOException
*/
@PreAuthorize("hasAnyRole('ROLE_SU')")
@RequestMapping(value = "/upload-logo", method = RequestMethod.POST)
public String uploadLogo(@RequestParam("logo") Part part, Model model) throws IOException
{
String contentType = part.getContentType();
if ((contentType == null) || !contentType.startsWith("image"))
{
model.addAttribute("errorMessage", ERRORMESSAGE_LOGO);
}
else
{
// Create the logo subdir in the filestore if it doesn't exist
File logoDir = new File(fileStore.getStorageDir() + "/logo");
if (!logoDir.exists())
{
if (!logoDir.mkdir())
{
throw new IOException("Unable to create directory [" + logoDir.getAbsolutePath() + "]");
}
}
// Store the logo in the logo dir of the filestore
String file = "/logo/" + FileUploadUtils.getOriginalFileName(part);
fileStore.store(part.getInputStream(), file);
// Set logo
appSettings.setLogoNavBarHref(file);
}
return init(model);
}
}