/**
* The contents of this file are subject to the OpenMRS Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://license.openmrs.org
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
* License for the specific language governing rights and limitations
* under the License.
*
* Copyright (C) OpenMRS, LLC. All Rights Reserved.
*/
package org.openmrs.web.controller.encounter;
import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.codehaus.jackson.map.ObjectMapper;
import org.openmrs.GlobalProperty;
import org.openmrs.Location;
import org.openmrs.LocationTag;
import org.openmrs.api.context.Context;
import org.openmrs.util.OpenmrsConstants;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
/**
* Shows the location hierarchy, in tree form
*/
@Controller
public class HierarchyController {
@RequestMapping("/admin/locations/hierarchy")
public void showHierarchy(ModelMap model) throws IOException {
model.addAttribute("json", getHierarchyAsJson());
model.addAttribute("locationWidgetType",
Context.getAdministrationService().getGlobalProperty(
OpenmrsConstants.GLOBAL_PROPERTY_LOCATION_WIDGET_TYPE, "default"));
}
@RequestMapping("/admin/locations/changeLocationWidgetType")
public String setWidgetType(@RequestParam("locationWidgetType") String widgetType) {
Context.getAdministrationService().saveGlobalProperty(
new GlobalProperty(OpenmrsConstants.GLOBAL_PROPERTY_LOCATION_WIDGET_TYPE, widgetType));
return "redirect:hierarchy.list";
}
/**
* Gets JSON formatted for jstree jquery plugin
* [
* { data: ..., children: ...},
* ...
* ]
*
* @return
* @throws IOException
*/
private String getHierarchyAsJson() throws IOException {
// TODO fetch all locations at once to avoid n+1 lazy-loads
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
for (Location loc : Context.getLocationService().getAllLocations()) {
if (loc.getParentLocation() == null) {
list.add(toJsonHelper(loc));
}
}
// If this gets slow with lots of locations then switch out ObjectMapper for the
// stream-based version. (But the TODO above is more likely to be a performance hit.)
StringWriter w = new StringWriter();
ObjectMapper mapper = new ObjectMapper();
mapper.writeValue(w, list);
return w.toString();
}
/**
* { data: "Location's name (tags)",
* children: [ recursive calls to this method, ... ] }
*
* @param loc
* @return
*/
private Map<String, Object> toJsonHelper(Location loc) {
Map<String, Object> ret = new LinkedHashMap<String, Object>();
StringBuilder sb = new StringBuilder(loc.getName());
if (loc.getTags() != null && loc.getTags().size() > 0) {
sb.append(" (");
for (Iterator<LocationTag> i = loc.getTags().iterator(); i.hasNext();) {
LocationTag t = i.next();
sb.append(t.getName());
if (i.hasNext())
sb.append(", ");
}
sb.append(")");
}
ret.put("data", sb.toString());
if (loc.getChildLocations() != null && loc.getChildLocations().size() > 0) {
List<Map<String, Object>> children = new ArrayList<Map<String, Object>>();
for (Location child : loc.getChildLocations())
children.add(toJsonHelper(child));
ret.put("children", children);
}
return ret;
}
}