Advertisement
Guest User

Untitled

a guest
Jul 24th, 2019
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 16.43 KB | None | 0 0
  1. package com.scantask.tms.mobile.flow;
  2.  
  3. import com.google.inject.Inject;
  4. import com.scantask.proto.uie.MenuItem;
  5. import com.scantask.proto.uie.MenuScreen;
  6. import com.scantask.tms.auth.*;
  7. import com.scantask.tms.engine.IPropertyService;
  8. import com.scantask.tms.engine.entity.Entity;
  9. import com.scantask.tms.engine.entity.IEntityService;
  10. import com.scantask.tms.engine.flow.FlowBuilderFactory;
  11. import com.scantask.tms.engine.flow.FlowConstructionException;
  12. import com.scantask.tms.engine.location.ILocationService;
  13. import com.scantask.tms.engine.location.Location;
  14. import com.scantask.tms.engine.process.IProcessService;
  15. import com.scantask.tms.engine.rules.IRuleService;
  16. import org.scantask.proto.SimpleResourceProvider;
  17. import org.scantask.proto.common.Params;
  18. import org.scantask.proto.common.Point;
  19. import org.scantask.proto.common.Producer;
  20. import org.scantask.utils.jme.StringUtils;
  21. import org.slf4j.Logger;
  22. import org.slf4j.LoggerFactory;
  23.  
  24. import javax.persistence.Query;
  25. import java.util.*;
  26.  
  27. import static com.scantask.tms.engine.entity.EntityConstants.MT_CROP;
  28. import static com.scantask.tms.engine.flow.Shortcuts.*;
  29. import static com.scantask.tms.engine.location.LocationConstants.MT_ARABLE_LAND;
  30.  
  31. /**
  32. * The plotsByRegionLocationTree produces a location hierarchy as follows:
  33. * <ol>
  34. * <li> On the first level we have a list of regions </li>
  35. * <li> On the second level we have all plots associated with the chosen from the first level region </li>
  36. * <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>
  37. * <li> Side note: The sensors MUST always be linked to a plot in order for us to display them </li>
  38. * </ol>
  39. *
  40. * The hierarchy is completely based on the grower configuration: regions are linked to a grower.
  41. * Therefore a region can be seen in multiple growers, but in each grower it will contain a different set of regions.
  42. *
  43. * @author Svetlin Atchkov
  44. *
  45. */
  46.  
  47. public class plotsByRegionLocationTree extends BaseAgriLocationTree {
  48.  
  49. private MenuScreen tplLocList;
  50. /**
  51. * class logger
  52. */
  53. private final Logger logger = LoggerFactory.getLogger(plotsByRegionLocationTree.class);
  54.  
  55. @Inject
  56. public plotsByRegionLocationTree(
  57. IAuthService authService,
  58. IPropertyService propertyService,
  59. ILocationService locationService,
  60. IEntityService entityService,
  61. IProcessService processService,
  62. IRuleService ruleService) {
  63. super(authService, propertyService, locationService, entityService, processService, ruleService);
  64. }
  65.  
  66. private static final String PLOTS_QUERY =
  67. "SELECT max(r.id), f.id, max(c.id), p.id FROM location p " +
  68. "JOIN location_type pt ON p.type_id = pt.id " +
  69. "JOIN location f ON p.container_id = f.id " +
  70. "LEFT JOIN location r ON p.region_id = r.id " +
  71. "LEFT JOIN location c ON p.group_id = c.id " +
  72. "WHERE pt.main_type = " + MT_ARABLE_LAND + " AND f.id IN ";
  73.  
  74. private static final String PLOTS_QUERY_END = " GROUP BY f.id, p.id";
  75.  
  76. @Override
  77. protected List<MenuScreen> buildFarmScreens(LocationNode parentNode) throws FlowConstructionException {
  78. final List<MenuScreen> res = new ArrayList<MenuScreen>();
  79.  
  80. MenuScreen scrMenu = null;
  81.  
  82. final String plotPath = ".def." + parentNode.getScreenName();
  83. final Params prm = prm("plotPath", plotPath);
  84. prm.setId("plotPath");
  85.  
  86. final SimpleResourceProvider srp = new SimpleResourceProvider();
  87. srp.addResource(prm);
  88.  
  89. final FlowBuilderFactory factory = new FlowBuilderFactory();
  90. factory.getManager().setResourceProvider(srp);
  91.  
  92. scrMenu = factory.cloneElement(tplPlots);
  93.  
  94. res.add(scrMenu);
  95. scrMenu.setName(parentNode.getScreenName());
  96. scrMenu.setTitle(parentNode.getLabel(languageId));
  97.  
  98. final Producer producer = (Producer) scrMenu.getElementByName("items");
  99. if (producer == null) {
  100. throw new FlowConstructionException("MenuScreen template must contain a placeholder element named 'items'.");
  101. }
  102.  
  103. boolean addedToPlotScreens = false;
  104.  
  105. for (final LocationNode node : parentNode.getSubLocations()) {
  106. final Location loc = node.getLocation();
  107.  
  108. MenuItem mi = null;
  109.  
  110. List<MenuScreen> nodeScreens = null;
  111. if (node.getSubLocations() != null && node.getSubLocations().size() > 0) {
  112. final String label = node.getLabel(languageId);
  113. mi = mi(loc.getCode(), label,
  114. call(label, gotos(".def." + node.getScreenName())));
  115.  
  116. nodeScreens = buildPlotGroupOrTrapScreens(node);
  117. }
  118.  
  119.  
  120. if (mi != null) scrMenu.addElementAt(producer.getIndex(), mi);
  121.  
  122. if (nodeScreens != null) {
  123. res.addAll(nodeScreens);
  124. }
  125. }
  126.  
  127. scrMenu.removeElementByIndex(producer.getIndex());
  128.  
  129. return res;
  130. }
  131. @Override
  132. protected List<MenuScreen> buildPlotGroupOrTrapScreens(LocationNode parentNode) throws FlowConstructionException {
  133. final List<MenuScreen> res = new ArrayList<MenuScreen>();
  134.  
  135. MenuScreen scrMenu = null;
  136.  
  137. final String plotPath = ".def." + parentNode.getScreenName();
  138. final Params prm = prm("plotPath", plotPath);
  139. prm.setId("plotPath");
  140.  
  141. final SimpleResourceProvider srp = new SimpleResourceProvider();
  142. srp.addResource(prm);
  143.  
  144. final FlowBuilderFactory factory = new FlowBuilderFactory();
  145. factory.getManager().setResourceProvider(srp);
  146.  
  147. scrMenu = factory.cloneElement(tplLocList);
  148.  
  149. res.add(scrMenu);
  150. scrMenu.setName(parentNode.getScreenName());
  151. scrMenu.setTitle(parentNode.getLabel(languageId));
  152.  
  153. final Producer producer = (Producer) scrMenu.getElementByName("items");
  154. if (producer == null) {
  155. throw new FlowConstructionException("MenuScreen template must contain a placeholder element named 'items'.");
  156. }
  157.  
  158. boolean addedToPlotScreens = false;
  159.  
  160. for (final LocationNode node : parentNode.getSubLocations()) {
  161. final Location loc = node.getLocation();
  162.  
  163. MenuItem mi = null;
  164.  
  165. List<MenuScreen> nodeScreens = null;
  166.  
  167. mi = mi(loc.getCode(), node.getLabel(languageId));
  168.  
  169. Map<String, String> plotProperties = null;
  170.  
  171. if (addPoints && loc.getLatitude() != null && loc.getLongitude() != null) {
  172. mi.setPoint(new Point(loc.getLongitude(), loc.getLatitude()));
  173. if (!addedToPlotScreens) {
  174. screensWithPlots.add(plotPath);
  175. addedToPlotScreens = true;
  176. }
  177. }
  178.  
  179.  
  180. scrMenu.addElementAt(producer.getIndex(), mi);
  181.  
  182. if (nodeScreens != null) {
  183. res.addAll(nodeScreens);
  184. }
  185. }
  186.  
  187. scrMenu.removeElementByIndex(producer.getIndex());
  188.  
  189. return res;
  190. }
  191.  
  192.  
  193. protected Entity getActiveSeason(Location plot) {
  194. Entity res = null;
  195. try {
  196. List<Entity> crops =
  197. entityService.findActiveEntitiesForLocationAndMainType(session, plot.getId(), MT_CROP);
  198.  
  199. if (crops != null && crops.size() > 0) {
  200. res = crops.get(0);
  201. }
  202. } catch (Exception e) {
  203. logger.warn("Failed to load crops for plot " + plot);
  204. }
  205. return res;
  206. }
  207.  
  208. @Override
  209. public boolean initializeTree(
  210. IAuthSession session,
  211. AuthUser user,
  212. AuthDevice device,
  213. List<Location> growers,
  214. boolean useLocationsInSeasonOnly,
  215. boolean addPoints,
  216. Logger logger)
  217. {
  218. long exectime = System.currentTimeMillis();
  219.  
  220. initializeTreeCommon(session, user, device, useLocationsInSeasonOnly, addPoints);
  221.  
  222. int topFarms = 0;
  223. int topRegions = 0;
  224.  
  225. // get personal role
  226. AuthRole personalRole = user.getPersonalRole();
  227.  
  228. if ( personalRole == null ) {
  229. throw new IllegalStateException("User '"+user.getUsername()+"' does not have a personal role.");
  230. }
  231.  
  232. Map<Long, LocationNode> farmNodeMap = new HashMap<Long, LocationNode>();
  233. Map<Long, LocationNode> regionNodeMap = new HashMap<Long, LocationNode>();
  234.  
  235. Map<Long, LocationNode> topNodeMap = new HashMap<Long, LocationNode>();
  236.  
  237. if ( growers == null ) {
  238. final List<Long> authRoleLocation = authService.getAuthRoleLocationIds(personalRole.getId(), null);
  239. growers = new ArrayList<>();
  240. for ( final Long locationId : authRoleLocation ) {
  241. growers.add(locationService.getLocation(locationId));
  242. }
  243. }
  244.  
  245. logger.debug("Number of growers for user '{}' is {}", user.getUsername(), growers.size());
  246.  
  247. StringBuilder query = new StringBuilder(PLOTS_QUERY);
  248. query.append("(");
  249.  
  250. boolean hasGrowers = false;
  251. for ( final Location farm : growers ) {
  252. try
  253. {
  254. query.append(farm.getId()).append(",");
  255.  
  256. String farmName = nameGen.buildScreenName(farm.getName());
  257.  
  258. LocationNode farmNode = new LocationNode(farm, farmName);
  259.  
  260. farmNodeMap.put(farm.getId(), farmNode);
  261.  
  262. hasGrowers = true;
  263. }
  264. catch ( Exception e ) {
  265. logger.warn("Failed to load farm for " + farm, e);
  266. }
  267. }
  268.  
  269. if( !hasGrowers ) {
  270. logger.warn( "User '{}' has no growers assigned", user.getUsername() );
  271. logger.debug( "Query incomplete: {}", query );
  272. }
  273. else {
  274. query.setCharAt(query.length()-1, ')');
  275. query.append(PLOTS_QUERY_END);
  276.  
  277. // List<Long> farmIds = new ArrayList<Long>(farmNodeMap.keySet());
  278.  
  279. Query q = em().createNativeQuery(query.toString());
  280.  
  281. // q.setParameter("farmIds", farmIds);
  282.  
  283. final Date now = new Date();
  284.  
  285. List<?> res = q.getResultList();
  286. for ( int i = 0; i < res.size(); i++ ) {
  287. Object[] row = (Object[])res.get(i);
  288. Long[] ids = new Long[] {(Long)row[0],(Long)row[1],(Long)row[2],(Long)row[3]};
  289.  
  290. if ( ids[1] == null || ids[3] == null ) {
  291. throw new IllegalStateException("Farm Id and Plot Id cannot be empty, row: "+i);
  292. }
  293.  
  294. // failing here is unlikely, the plots table is the root of the query
  295. Location plot = locationService.getLocation(ids[3]);
  296.  
  297. // exclude dormant plots
  298. if ( !plot.isActiveAt( now ) )
  299. continue;
  300.  
  301. Entity season = getActiveSeason(plot);
  302.  
  303. if ( season == null && useLocationsInSeasonOnly ) continue;
  304.  
  305. if ( season != null ) {
  306. cropTypesInUse.add(season.getType());
  307. }
  308.  
  309. LocationNode regionNode = null;
  310. if ( ids[0] != null ) {
  311. regionNode = regionNodeMap.get(ids[0]);
  312. if ( regionNode == null )
  313. {
  314. Location region = locationService.getLocation(ids[0]);
  315.  
  316. String screenName = nameGen.buildScreenName(region.getName());
  317. regionNode = new LocationNode(region, screenName, new ArrayList<LocationNode>());
  318.  
  319. regionNodeMap.put(region.getId(), regionNode);
  320.  
  321. // we add only the new nodes to the top map
  322. topNodeMap.put(region.getId(), regionNode);
  323. }
  324. Location cluster = ids[2] != null ? locationService.getLocation(ids[2]) : null;
  325.  
  326. if ( cluster != null ) {
  327. LocationNode clusterNode = regionNode.getSubLocationById(cluster.getId());
  328. if ( clusterNode == null ) {
  329. String screenName = nameGen.buildScreenName(regionNode.getLocation().getName(), cluster.getName());
  330. clusterNode = new LocationNode(cluster, screenName, regionNode);
  331. regionNode.addSubLocation(clusterNode);
  332. }
  333.  
  334. LocationNode plotNode = new LocationNode(plot, clusterNode);
  335. plotNode.setSeason(season);
  336. clusterNode.addSubLocation(plotNode);
  337. }
  338. else {
  339. LocationNode plotNode = new LocationNode(plot, regionNode);
  340. plotNode.setSeason(season);
  341. regionNode.addSubLocation(plotNode);
  342. }
  343. }
  344.  
  345. //LocationNode farmNode = farmNodeMap.get(ids[1]);
  346. /* if ( farmNode == null ) {
  347. Location farm = locationService.getLocation(ids[1]);
  348. farmNode = new LocationNode(farm, "");
  349. farmNodeMap.put(farm.getId(), farmNode);
  350. }
  351.  
  352. if ( regionNode != null )
  353. {
  354. topRegions ++;
  355. LocationNode node = regionNode.getSubLocationById(farmNode.getLocation().getId());
  356.  
  357. if ( node != null ) {
  358. farmNode = node;
  359. }
  360. else {
  361. // we must have a different instance of the farm node for every region
  362. // because they need to contain different set of plots (and clusters)
  363. farmNode = farmNode.clone();
  364.  
  365. String screenName = nameGen.buildScreenName(
  366. regionNode.getLocation().getName(),
  367. farmNode.getLocation().getName());
  368.  
  369. farmNode.setScreenName(screenName);
  370.  
  371. regionNode.addSubLocation(farmNode);
  372. }
  373.  
  374. }
  375. else
  376. {
  377. topFarms ++;
  378.  
  379. LocationNode node = topNodeMap.get(farmNode.getLocation().getId());
  380.  
  381. if ( node != null ) {
  382. farmNode = node;
  383. }
  384. else {
  385. farmNode = farmNode.clone();
  386.  
  387. String screenName = nameGen.buildScreenName(
  388. farmNode.getLocation().getName());
  389.  
  390. farmNode.setScreenName(screenName);
  391.  
  392. topNodeMap.put(farmNode.getLocation().getId(), farmNode);
  393. }
  394. }
  395.  
  396. Location cluster = ids[2] != null ? locationService.getLocation(ids[2]) : null;
  397.  
  398. if ( cluster != null ) {
  399. LocationNode clusterNode = farmNode.getSubLocationById(cluster.getId());
  400. if ( clusterNode == null ) {
  401. String screenName = nameGen.buildScreenName(farmNode.getLocation().getName(), cluster.getName());
  402. clusterNode = new LocationNode(cluster, screenName, farmNode);
  403. farmNode.addSubLocation(clusterNode);
  404. }
  405.  
  406. LocationNode plotNode = new LocationNode(plot, clusterNode);
  407. plotNode.setSeason(season);
  408. clusterNode.addSubLocation(plotNode);
  409. }
  410. else {
  411. LocationNode plotNode = new LocationNode(plot, farmNode);
  412. plotNode.setSeason(season);
  413. farmNode.addSubLocation(plotNode);
  414. }*/
  415. }
  416. }
  417.  
  418. this.topNodes = new ArrayList<LocationNode>(topNodeMap.values()); // may be empty
  419.  
  420. sortLocationNodes();
  421.  
  422. exectime = System.currentTimeMillis() - exectime;
  423.  
  424. if ( logger.isInfoEnabled() ) {
  425. logger.info("Time to initialize PlotBasedLocationTree for user {}: {}",
  426. user.getUsername(), StringUtils.formatInterval(exectime, true, true, true));
  427. }
  428.  
  429. return topRegions > topFarms;
  430. }
  431. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement