Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package com.scantask.tms.mobile.flow;
- import com.google.inject.Inject;
- import com.scantask.proto.uie.MenuItem;
- import com.scantask.proto.uie.MenuScreen;
- import com.scantask.tms.auth.*;
- import com.scantask.tms.engine.IPropertyService;
- import com.scantask.tms.engine.entity.Entity;
- import com.scantask.tms.engine.entity.IEntityService;
- import com.scantask.tms.engine.flow.FlowBuilderFactory;
- import com.scantask.tms.engine.flow.FlowConstructionException;
- import com.scantask.tms.engine.location.ILocationService;
- import com.scantask.tms.engine.location.Location;
- import com.scantask.tms.engine.process.IProcessService;
- import com.scantask.tms.engine.rules.IRuleService;
- import org.scantask.proto.SimpleResourceProvider;
- import org.scantask.proto.common.Params;
- import org.scantask.proto.common.Point;
- import org.scantask.proto.common.Producer;
- import org.scantask.utils.jme.StringUtils;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import javax.persistence.Query;
- import java.util.*;
- import static com.scantask.tms.engine.entity.EntityConstants.MT_CROP;
- import static com.scantask.tms.engine.flow.Shortcuts.*;
- import static com.scantask.tms.engine.location.LocationConstants.MT_ARABLE_LAND;
- /**
- * The plotsByRegionLocationTree produces a location hierarchy as follows:
- * <ol>
- * <li> On the first level we have a list of regions </li>
- * <li> On the second level we have all plots associated with the chosen from the first level region </li>
- * <li> On the third level we will have a sensors and traps menu if a plot has such created plus the mobile configurations for the chosen plot </li>
- * <li> Side note: The sensors MUST always be linked to a plot in order for us to display them </li>
- * </ol>
- *
- * The hierarchy is completely based on the grower configuration: regions are linked to a grower.
- * Therefore a region can be seen in multiple growers, but in each grower it will contain a different set of regions.
- *
- * @author Svetlin Atchkov
- *
- */
- public class plotsByRegionLocationTree extends BaseAgriLocationTree {
- private MenuScreen tplLocList;
- /**
- * class logger
- */
- private final Logger logger = LoggerFactory.getLogger(plotsByRegionLocationTree.class);
- @Inject
- public plotsByRegionLocationTree(
- IAuthService authService,
- IPropertyService propertyService,
- ILocationService locationService,
- IEntityService entityService,
- IProcessService processService,
- IRuleService ruleService) {
- super(authService, propertyService, locationService, entityService, processService, ruleService);
- }
- private static final String PLOTS_QUERY =
- "SELECT max(r.id), f.id, max(c.id), p.id FROM location p " +
- "JOIN location_type pt ON p.type_id = pt.id " +
- "JOIN location f ON p.container_id = f.id " +
- "LEFT JOIN location r ON p.region_id = r.id " +
- "LEFT JOIN location c ON p.group_id = c.id " +
- "WHERE pt.main_type = " + MT_ARABLE_LAND + " AND f.id IN ";
- private static final String PLOTS_QUERY_END = " GROUP BY f.id, p.id";
- @Override
- protected List<MenuScreen> buildFarmScreens(LocationNode parentNode) throws FlowConstructionException {
- final List<MenuScreen> res = new ArrayList<MenuScreen>();
- MenuScreen scrMenu = null;
- final String plotPath = ".def." + parentNode.getScreenName();
- final Params prm = prm("plotPath", plotPath);
- prm.setId("plotPath");
- final SimpleResourceProvider srp = new SimpleResourceProvider();
- srp.addResource(prm);
- final FlowBuilderFactory factory = new FlowBuilderFactory();
- factory.getManager().setResourceProvider(srp);
- scrMenu = factory.cloneElement(tplPlots);
- res.add(scrMenu);
- scrMenu.setName(parentNode.getScreenName());
- scrMenu.setTitle(parentNode.getLabel(languageId));
- final Producer producer = (Producer) scrMenu.getElementByName("items");
- if (producer == null) {
- throw new FlowConstructionException("MenuScreen template must contain a placeholder element named 'items'.");
- }
- boolean addedToPlotScreens = false;
- for (final LocationNode node : parentNode.getSubLocations()) {
- final Location loc = node.getLocation();
- MenuItem mi = null;
- List<MenuScreen> nodeScreens = null;
- if (node.getSubLocations() != null && node.getSubLocations().size() > 0) {
- final String label = node.getLabel(languageId);
- mi = mi(loc.getCode(), label,
- call(label, gotos(".def." + node.getScreenName())));
- nodeScreens = buildPlotGroupOrTrapScreens(node);
- }
- if (mi != null) scrMenu.addElementAt(producer.getIndex(), mi);
- if (nodeScreens != null) {
- res.addAll(nodeScreens);
- }
- }
- scrMenu.removeElementByIndex(producer.getIndex());
- return res;
- }
- @Override
- protected List<MenuScreen> buildPlotGroupOrTrapScreens(LocationNode parentNode) throws FlowConstructionException {
- final List<MenuScreen> res = new ArrayList<MenuScreen>();
- MenuScreen scrMenu = null;
- final String plotPath = ".def." + parentNode.getScreenName();
- final Params prm = prm("plotPath", plotPath);
- prm.setId("plotPath");
- final SimpleResourceProvider srp = new SimpleResourceProvider();
- srp.addResource(prm);
- final FlowBuilderFactory factory = new FlowBuilderFactory();
- factory.getManager().setResourceProvider(srp);
- scrMenu = factory.cloneElement(tplLocList);
- res.add(scrMenu);
- scrMenu.setName(parentNode.getScreenName());
- scrMenu.setTitle(parentNode.getLabel(languageId));
- final Producer producer = (Producer) scrMenu.getElementByName("items");
- if (producer == null) {
- throw new FlowConstructionException("MenuScreen template must contain a placeholder element named 'items'.");
- }
- boolean addedToPlotScreens = false;
- for (final LocationNode node : parentNode.getSubLocations()) {
- final Location loc = node.getLocation();
- MenuItem mi = null;
- List<MenuScreen> nodeScreens = null;
- mi = mi(loc.getCode(), node.getLabel(languageId));
- Map<String, String> plotProperties = null;
- if (addPoints && loc.getLatitude() != null && loc.getLongitude() != null) {
- mi.setPoint(new Point(loc.getLongitude(), loc.getLatitude()));
- if (!addedToPlotScreens) {
- screensWithPlots.add(plotPath);
- addedToPlotScreens = true;
- }
- }
- scrMenu.addElementAt(producer.getIndex(), mi);
- if (nodeScreens != null) {
- res.addAll(nodeScreens);
- }
- }
- scrMenu.removeElementByIndex(producer.getIndex());
- return res;
- }
- protected Entity getActiveSeason(Location plot) {
- Entity res = null;
- try {
- List<Entity> crops =
- entityService.findActiveEntitiesForLocationAndMainType(session, plot.getId(), MT_CROP);
- if (crops != null && crops.size() > 0) {
- res = crops.get(0);
- }
- } catch (Exception e) {
- logger.warn("Failed to load crops for plot " + plot);
- }
- return res;
- }
- @Override
- public boolean initializeTree(
- IAuthSession session,
- AuthUser user,
- AuthDevice device,
- List<Location> growers,
- boolean useLocationsInSeasonOnly,
- boolean addPoints,
- Logger logger)
- {
- long exectime = System.currentTimeMillis();
- initializeTreeCommon(session, user, device, useLocationsInSeasonOnly, addPoints);
- int topFarms = 0;
- int topRegions = 0;
- // get personal role
- AuthRole personalRole = user.getPersonalRole();
- if ( personalRole == null ) {
- throw new IllegalStateException("User '"+user.getUsername()+"' does not have a personal role.");
- }
- Map<Long, LocationNode> farmNodeMap = new HashMap<Long, LocationNode>();
- Map<Long, LocationNode> regionNodeMap = new HashMap<Long, LocationNode>();
- Map<Long, LocationNode> topNodeMap = new HashMap<Long, LocationNode>();
- if ( growers == null ) {
- final List<Long> authRoleLocation = authService.getAuthRoleLocationIds(personalRole.getId(), null);
- growers = new ArrayList<>();
- for ( final Long locationId : authRoleLocation ) {
- growers.add(locationService.getLocation(locationId));
- }
- }
- logger.debug("Number of growers for user '{}' is {}", user.getUsername(), growers.size());
- StringBuilder query = new StringBuilder(PLOTS_QUERY);
- query.append("(");
- boolean hasGrowers = false;
- for ( final Location farm : growers ) {
- try
- {
- query.append(farm.getId()).append(",");
- String farmName = nameGen.buildScreenName(farm.getName());
- LocationNode farmNode = new LocationNode(farm, farmName);
- farmNodeMap.put(farm.getId(), farmNode);
- hasGrowers = true;
- }
- catch ( Exception e ) {
- logger.warn("Failed to load farm for " + farm, e);
- }
- }
- if( !hasGrowers ) {
- logger.warn( "User '{}' has no growers assigned", user.getUsername() );
- logger.debug( "Query incomplete: {}", query );
- }
- else {
- query.setCharAt(query.length()-1, ')');
- query.append(PLOTS_QUERY_END);
- // List<Long> farmIds = new ArrayList<Long>(farmNodeMap.keySet());
- Query q = em().createNativeQuery(query.toString());
- // q.setParameter("farmIds", farmIds);
- final Date now = new Date();
- List<?> res = q.getResultList();
- for ( int i = 0; i < res.size(); i++ ) {
- Object[] row = (Object[])res.get(i);
- Long[] ids = new Long[] {(Long)row[0],(Long)row[1],(Long)row[2],(Long)row[3]};
- if ( ids[1] == null || ids[3] == null ) {
- throw new IllegalStateException("Farm Id and Plot Id cannot be empty, row: "+i);
- }
- // failing here is unlikely, the plots table is the root of the query
- Location plot = locationService.getLocation(ids[3]);
- // exclude dormant plots
- if ( !plot.isActiveAt( now ) )
- continue;
- Entity season = getActiveSeason(plot);
- if ( season == null && useLocationsInSeasonOnly ) continue;
- if ( season != null ) {
- cropTypesInUse.add(season.getType());
- }
- LocationNode regionNode = null;
- if ( ids[0] != null ) {
- regionNode = regionNodeMap.get(ids[0]);
- if ( regionNode == null )
- {
- Location region = locationService.getLocation(ids[0]);
- String screenName = nameGen.buildScreenName(region.getName());
- regionNode = new LocationNode(region, screenName, new ArrayList<LocationNode>());
- regionNodeMap.put(region.getId(), regionNode);
- // we add only the new nodes to the top map
- topNodeMap.put(region.getId(), regionNode);
- }
- Location cluster = ids[2] != null ? locationService.getLocation(ids[2]) : null;
- if ( cluster != null ) {
- LocationNode clusterNode = regionNode.getSubLocationById(cluster.getId());
- if ( clusterNode == null ) {
- String screenName = nameGen.buildScreenName(regionNode.getLocation().getName(), cluster.getName());
- clusterNode = new LocationNode(cluster, screenName, regionNode);
- regionNode.addSubLocation(clusterNode);
- }
- LocationNode plotNode = new LocationNode(plot, clusterNode);
- plotNode.setSeason(season);
- clusterNode.addSubLocation(plotNode);
- }
- else {
- LocationNode plotNode = new LocationNode(plot, regionNode);
- plotNode.setSeason(season);
- regionNode.addSubLocation(plotNode);
- }
- }
- //LocationNode farmNode = farmNodeMap.get(ids[1]);
- /* if ( farmNode == null ) {
- Location farm = locationService.getLocation(ids[1]);
- farmNode = new LocationNode(farm, "");
- farmNodeMap.put(farm.getId(), farmNode);
- }
- if ( regionNode != null )
- {
- topRegions ++;
- LocationNode node = regionNode.getSubLocationById(farmNode.getLocation().getId());
- if ( node != null ) {
- farmNode = node;
- }
- else {
- // we must have a different instance of the farm node for every region
- // because they need to contain different set of plots (and clusters)
- farmNode = farmNode.clone();
- String screenName = nameGen.buildScreenName(
- regionNode.getLocation().getName(),
- farmNode.getLocation().getName());
- farmNode.setScreenName(screenName);
- regionNode.addSubLocation(farmNode);
- }
- }
- else
- {
- topFarms ++;
- LocationNode node = topNodeMap.get(farmNode.getLocation().getId());
- if ( node != null ) {
- farmNode = node;
- }
- else {
- farmNode = farmNode.clone();
- String screenName = nameGen.buildScreenName(
- farmNode.getLocation().getName());
- farmNode.setScreenName(screenName);
- topNodeMap.put(farmNode.getLocation().getId(), farmNode);
- }
- }
- Location cluster = ids[2] != null ? locationService.getLocation(ids[2]) : null;
- if ( cluster != null ) {
- LocationNode clusterNode = farmNode.getSubLocationById(cluster.getId());
- if ( clusterNode == null ) {
- String screenName = nameGen.buildScreenName(farmNode.getLocation().getName(), cluster.getName());
- clusterNode = new LocationNode(cluster, screenName, farmNode);
- farmNode.addSubLocation(clusterNode);
- }
- LocationNode plotNode = new LocationNode(plot, clusterNode);
- plotNode.setSeason(season);
- clusterNode.addSubLocation(plotNode);
- }
- else {
- LocationNode plotNode = new LocationNode(plot, farmNode);
- plotNode.setSeason(season);
- farmNode.addSubLocation(plotNode);
- }*/
- }
- }
- this.topNodes = new ArrayList<LocationNode>(topNodeMap.values()); // may be empty
- sortLocationNodes();
- exectime = System.currentTimeMillis() - exectime;
- if ( logger.isInfoEnabled() ) {
- logger.info("Time to initialize PlotBasedLocationTree for user {}: {}",
- user.getUsername(), StringUtils.formatInterval(exectime, true, true, true));
- }
- return topRegions > topFarms;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement