/* Copyright 2010 John L. Reilly
Licensed under the Apache License, Version 2.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://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */
package com.riq;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TimeZone;
import java.util.logging.Logger;
import javax.jdo.PersistenceManager;
import javax.jdo.Query;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.riq.entity.Alert;
import com.riq.entity.Department;
import com.riq.entity.Location;
import com.riq.entity.Member;
import com.riq.entity.Status;
import com.riq.entity.Tracking;
import com.riq.nonpersist.ReportDept;
import com.riq.nonpersist.ReportLocation;
//@SuppressWarnings("serial")
public class ReportingPrepServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private static final Logger log = Logger.getLogger(Tracking.class.getName());
private static final int MAX_COOKIE_AGE_MS = 60*60*24*1000; // for cookie age
private static final Long INIT_LONG = Long.valueOf("999999999");
private Long deptId = INIT_LONG;
private Long alertId = INIT_LONG;
private String formTimeStamp = System.currentTimeMillis()+"|"+deptId+"|"+alertId;
private List<Department> depts = new ArrayList<Department>();
private List<Long> allDeptIds = new ArrayList<Long>();
private List<Member> members = new ArrayList<Member>();
private Map<Long, List<Location>> mDeptLocations = new HashMap<Long, List<Location>>();
private Map<Long, List<String>> mDeptLocationTypes = new HashMap<Long, List<String>>();
private Map<Long, List<Status>> mDeptLocationStatuses = new HashMap<Long, List<Status>>();
private Map<Long, Long> mDeptLocationSelectedStatus = new HashMap<Long, Long>();
private Map<Long, List<Member>> mDeptMembers = new HashMap<Long, List<Member>>();
private Map<Long, List<String>> mDeptMemberTypes = new HashMap<Long, List<String>>();
private Map<Long, List<Member>> mDeptLocationMembers = new HashMap<Long, List<Member>>();
private Map<Long, Tracking> mMemberCurrentLocation = new HashMap<Long, Tracking>();
private List<Member> unassignedMembers = new ArrayList<Member>();
// private List<Member> dActivityMembers = new ArrayList<Member>();
// private List<Location> dActivityLocations = new ArrayList<Location>();
// private Map<Long, List<Member>> mDeptActivityMember = new HashMap<Long, List<Member>>();
private List<Member> allMembers = new ArrayList<Member>();
private List<Member> activeMembers = new ArrayList<Member>();
private List<Member> inactiveMembers = new ArrayList<Member>();
private Map<String, List<Member>> memberGroups = new HashMap<String, List<Member>>();
private Map<Long, Map<String, List<Member>>> alertMemberGroups =
new HashMap<Long, Map<String, List<Member>>>();
@Override
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String intent = request.getParameter("intent");
String path = request.getParameter("path");
System.out.println("path94: " + path);
int tempPrimaryDeptFlag = 0;
Cookie[] cookie = request.getCookies();
deptId = Long.valueOf(ServletUtilities.getCookieValue(cookie, "cvDeptId", "99999"));
System.out.println("deptId from cookie: " + deptId.toString());
// get alert and calculate elapsed time
alert(response, request);
// using cookie, determine primary dept and get it plus its mutual aid depts
List<Department> pamDepts = pamDepts(deptId);
// get the dept ids (primary dept and its mutual aid depts
List<Long> pamIds = aDeptIds(pamDepts);
// create the map for dept:locations
mDeptLocations(pamIds);
// create the map for location: statuses
mDeptLocationStatuses();
// get the members for the pam depts
mDeptMembers(pamIds);
// create the map for member: currerntLocation
mMemberLocation(alertId);
// create the map for location: members
mDeptLocationMembers();
// determine which members have been manually added and still unassigned to a location
unassignedMembers();
// create the various member groups
memberGroups(mDeptLocationMembers);
// create the map for location: statuses: selectedStatus
mDeptLocationSelectedStatuses();
// gather the location types for pamDepts (used in report grouping logic)
locationTypes(mDeptLocations);
// gather the member types for pamDepts (used in report grouping logic)
memberTypes(mDeptMembers);
List<ReportDept> reportDepts = new ArrayList<ReportDept>();
for (Department d: pamDepts) {
System.out.println("dept: " + d.getshortName());
// create ReportLocation record for each dept Location
List<ReportLocation> reportLocations = new ArrayList<ReportLocation>();
if (mDeptLocations.get(d.getid()) != null) {
for (Location l : mDeptLocations.get(d.getid())) {
System.out.println("ReportLocation loop: " + l.getshortName());
// set activeFlag for Location (any selected Status or any assigned Member)
String tempActiveLocation = "yes";
if (mDeptLocationMembers.get(l) == null && (mDeptLocationSelectedStatus.get(l) != null)) {
tempActiveLocation = "no";
}
ReportLocation reportLocationEntry = new ReportLocation(
tempActiveLocation,
l,
mDeptLocationStatuses.get(l.getid()),
mDeptLocationSelectedStatus.get(l.getid()),
mDeptLocationMembers.get(l.getid())
);
reportLocations.add(reportLocationEntry);
System.out.println("Added reportLocation for " + l.getshortName() + "|" + l.getid());
System.out.println("ReportLocations qty: " + reportLocations.size());
System.out.println("ReportLocations mDeptLocMember qty: " + mDeptLocationMembers.size());
}
}
// the primary dept is always listed first in the collection
String tempDeptType;
if (tempPrimaryDeptFlag == 0) {
tempDeptType = "primary";
} else {
tempDeptType = "mutual";
}
// create ReportDept record
ReportDept reportDept = new ReportDept(
tempDeptType,
d,
mDeptLocationTypes.get(d.getid()),
reportLocations,
mDeptMemberTypes.get(d.getid()),
unassignedMembers,
activeMembers,
inactiveMembers
);
reportDepts.add(reportDept);
System.out.println("reportDept added for: " + d.getid());
System.out.println("-----------------------------------------------");
// increment for mutual aid depts (if any) - primary dept always first in collection
tempPrimaryDeptFlag++;
Collections.sort(reportDept.locations());
}
// alert attribute set in alert method
request.setAttribute("path", path);
request.setAttribute("intent", intent);
request.setAttribute("reportDepts", reportDepts);
request.setAttribute("formTimestamp", formTimeStamp);
if ("addResources".equalsIgnoreCase(path)) {
System.out.println("addResouces passed");
RequestDispatcher dispatcher =
getServletContext().getRequestDispatcher("/parResourcesMulti.jsp?");
dispatcher.forward(request, response);
} else {
RequestDispatcher dispatcher =
getServletContext().getRequestDispatcher("/parCommandMulti.jsp?");
dispatcher.forward(request, response);
}
}
/**
* Find the department objects for the provided list of department ids.
* Result is a privately available list of pamIds of type long.
* @param list of pamIds
* @return none
*/
private List<Department> pamDepts(Long deptId) {
PersistenceManager pm = PMF.get().getPersistenceManager();
depts = new ArrayList<Department>();
// add primary dept
Department dPrimary = pm.getObjectById(Department.class, deptId);
depts.add(dPrimary);
// primary dept's mutual aid depts
String dMutualAid = dPrimary.getmutualAid();
if (dMutualAid.length() != 0) {
if (dMutualAid.contains(",")) {
String[] maDepts = dMutualAid.split(", ", -1);
for (int i=0; i< maDepts.length; i++) {
Long maDeptId = Long.valueOf(maDepts[i]);
Department dMAs = pm.getObjectById(Department.class, maDeptId);
if (dMAs != null) {
depts.add(dMAs);
}
}
} else {
Department dMAsolo = pm.getObjectById(Department.class, Long.valueOf((dMutualAid).trim()));
if (dMAsolo != null) {
depts.add(dMAsolo);
}
}
}
System.out.println("Depts Qty: " + depts.size());
System.out.println("Exit: pamDepts");
return depts;
}
/**
* Find the department objects for the provided list of department ids.
* Result is a privately available list of pamIds of type long.
* @param list of pamIds
* @return none
*/
private List<Long> aDeptIds(List<Department> pamDepts) {
allDeptIds = new ArrayList<Long>();
// add primary dept (always first in the collection)
allDeptIds.add(pamDepts.get(0).getid());
// add any and all mutual aid depts - note: i=1 (not zero) to pass over primary dept
for (int i = 1; i < pamDepts.size(); i++) {
allDeptIds.add(pamDepts.get(i).getid());
}
System.out.println("Exit: aDeptIds");
return allDeptIds;
}
/**
* Create a map of the owned location objects for the provided list of department ids.
* Result is a privately available map of dept:list<Location>.
* @param list of pamIds
* @return none
*/
private void mDeptLocations(List<Long> deptIds) {
PersistenceManager pm = PMF.get().getPersistenceManager(); // TODO necessary? common?
mDeptLocations.clear();
for (Long d : deptIds) {
List<Location> tempLocations = new ArrayList<Location>();
Query q = pm.newQuery(Location.class, "deptId == " + d );
q.setOrdering("deptId asc, key asc");
tempLocations.addAll((List<Location>) pm.newQuery(q).execute());
System.out.println("deptLocations ending qty: " + tempLocations.size());
mDeptLocations.put(d, tempLocations);
System.out.println("mDeptLocations running qty: " + mDeptLocations.size());
}
System.out.println("mDeptLocations ending qty: " + mDeptLocations.size());
System.out.println("Exit: mDeptLocations");
}
/**
* Find the owned status objects for the provided list of location ids.
* Result is a privately available map of dept:list<Location>.
* @param list of pamIds
* @return none
*/
public void mDeptLocationStatuses() {
System.out.println("Inside mDeptLocationStatuses");
PersistenceManager pm = PMF.get().getPersistenceManager();
mDeptLocationStatuses.clear();
for (int d=0; d<mDeptLocations.size(); d++) {
System.out.println("mDeptLocation qty: " + mDeptLocations.size());
// dLocationStatuses.clear();
if (mDeptLocations.get(d) != null) {
for (int l=0; l<mDeptLocations.get(d).size(); l++) {
List<Status> dLocationStatuses = new ArrayList<Status>();
List<Long> keys = new ArrayList<Long>();
keys.addAll(mDeptLocations.get(d).get(l).getstatusKeys());
Query q = pm.newQuery(Status.class, ":p.contains(id)");
dLocationStatuses.addAll((List<Status>) pm.newQuery(q).execute(keys));
mDeptLocationStatuses.put(mDeptLocations.get(d).get(l).getid(), dLocationStatuses);
System.out.println("dLocationStatuses in deptLocStat: " + dLocationStatuses.size());
}
}
}
System.out.println("mDeptLocationStatuses qty: " + mDeptLocationStatuses.size());
System.out.println("Exit: mDeptLocationStatuses");
}
/**
* Find the owned status objects for the provided list of location ids.
* Result is a privately available map of dept:list<Location>.
* Note: mDeptActivityStatus map must be created prior to calling this method.
* @param list of pamIds
* @return none
*/
public void mDeptLocationSelectedStatuses() {
PersistenceManager pm = PMF.get().getPersistenceManager();
Query q = pm.newQuery(Tracking.class, "alertId == " + alertId + " && type == 'locstat' ");
q.setOrdering("timeStamp desc");
List<Tracking> tracks = (List<Tracking>) pm.newQuery(q).execute();
Map<Long, Long> mDeptLocationSelectedStatuses = new HashMap<Long, Long>();
for (Tracking t : tracks) {
if (t.getlocationId() != null) {
if (!mDeptLocationSelectedStatuses.containsKey(t.getlocationId())) {
mDeptLocationSelectedStatuses.put(t.getlocationId(), t.gettypeId());
}
}
}
System.out.println("Exit: mDeptLocationSelectedStatuses");
}
/**
* Find the members currently at each of the primary dept's locations.
* Result is a public list of all members.
* @param list of pamIds
* @return none
*/
public void mDeptMembers(List<Long> pamDeptIds) {
PersistenceManager pm = PMF.get().getPersistenceManager(); // TODO necessary? common?
Query q = pm.newQuery(Member.class, ":p.contains(deptId)");
q.setOrdering("deptId asc, id asc");
members = (List<Member>)q.execute(pamDeptIds);
List<Member> tempDeptMembers = new ArrayList<Member>();
for (Long d : pamDeptIds){
for (Member m : members) {
if (m.getdeptId().equals(d)){
tempDeptMembers.add(m);
}
}
mDeptMembers.put(d, tempDeptMembers);
}
System.out.println("Members qty inside deptMembers: " + members.size());
System.out.println("Exit: deptMembers");
}
/**
* Find the members currently at each of the primary dept's locations.
* Result is a privately available map of dept:list<Location>.
* Note: mDeptActivityStatus map must be created prior to calling this method.
* @param list of pamIds
* @return none
*/
public void mMemberLocation(Long alertId) {
PersistenceManager pm = PMF.get().getPersistenceManager();
Query q = pm.newQuery(Tracking.class, "alertId == " + alertId + " && type == 'member' ");
q.setOrdering("typeId asc, timeStamp desc");
List<Tracking> tracks = (List<Tracking>) pm.newQuery(q).execute();
System.out.println("tracks where member has a location: " + tracks.size());
mMemberCurrentLocation.clear();
for (final Tracking t : tracks) {
if (!mMemberCurrentLocation.containsKey(t.gettypeId())) {
mMemberCurrentLocation.put(t.gettypeId(), t);
}
}
System.out.println("mMemberCurrentLocation qty: " + mMemberCurrentLocation.size());
System.out.println("Exit: mMemberCurrentLocation");
}
/**
* Find the members who have been manually added and not yet assigned a location
* Result is a privately available list of unassigned members for the provided alert
* Note: mDeptActivityStatus map must be created prior to calling this method.
* @param list of pamIds
* @return none
*/
public void unassignedMembers() {
unassignedMembers.clear();
PersistenceManager pm = PMF.get().getPersistenceManager();
Iterator iter = mMemberCurrentLocation.entrySet().iterator();
while (iter.hasNext()) {
Entry<Long, Tracking> pairs = (Entry<Long, Tracking>)iter.next();
if (pairs.getValue().getresponseType().equalsIgnoreCase("manuallyAddMember")) {
Member m = pm.getObjectById(Member.class, pairs.getKey());
unassignedMembers.add(m);
iter.remove();
}
}
System.out.println("unassigned members qty: " + unassignedMembers.size());
System.out.println("Exit: unassignedMembers");
}
/**
* Find the members currently at each of the primary dept's locations.
* Result is a privately available map of dept:list<Location>.
* Note: mDeptActivityStatus map must be created prior to calling this method.
* @param list of pamIds
* @return none
*/
public void mDeptLocationMembers() {
PersistenceManager pm = PMF.get().getPersistenceManager();
// dept iterator
System.out.println("111 mDeptLocations inside mDeptLocationMembers: " + mDeptLocations.size());
Iterator iterDept = mDeptLocations.entrySet().iterator();
while (iterDept.hasNext()) {
Entry<Long, List<Location>> pairsDept = (Entry<Long, List<Location>>)iterDept.next();
if (!pairsDept.getValue().isEmpty()) {
// location iterator
for (Location l : pairsDept.getValue()) {
// member iterator
List<Member> mLocationMembers = new ArrayList<Member>();
Iterator iterMember = mMemberCurrentLocation.entrySet().iterator();
while (iterMember.hasNext()) {
Entry<Long, Tracking> pairsMember = (Entry<Long, Tracking>)iterMember.next();
// determine members, regardless of dept, at this location
if (l.getid().equals(pairsMember.getValue().getlocationId())) {
Member m = pm.getObjectById(Member.class, pairsMember.getKey());
mLocationMembers.add(m);
System.out.println("m: " + m.getlastName());
System.out.println("mLocationMembers qty: " + mLocationMembers.size());
}
}
mDeptLocationMembers.put(l.getid(), mLocationMembers);
}
}
}
System.out.println("mDeptLocationMembers TOTAL qty: " + mDeptLocationMembers.size());
System.out.println("Exit: mDeptLocationMembers");
}
private void locationTypes(Map<Long, List<Location>> mDeptLocations) {
List<String> locationTypes = new ArrayList<String>();
mDeptLocationTypes.clear();
locationTypes = new ArrayList<String>();
for (Entry<Long, List<Location>> mDeptLoc : mDeptLocations.entrySet()) {
for (Location l : mDeptLoc.getValue()){
if (!locationTypes.contains(l.gettype())) {
locationTypes.add(l.gettype());
}
}
mDeptLocationTypes.put(mDeptLoc.getKey(), locationTypes);
}
System.out.println("Exit: locationTypes");
}
// create List of Member Types
private void memberTypes(Map<Long, List<Member>> mDeptMembers) {
List<String> memberTypes = new ArrayList<String>();
mDeptMemberTypes.clear();
memberTypes = new ArrayList<String>();
for (Entry<Long, List<Member>> entry : mDeptMembers.entrySet()) {
for (Member m : entry.getValue()){
if (!memberTypes.contains(m.gettype())) {
memberTypes.add(m.gettype());
}
}
mDeptMemberTypes.put(entry.getKey(), memberTypes);
}
System.out.println("Exit: memberTypes");
}
// determine which group each Member belongs to based on activity for this alert
private void memberGroups(Map<Long, List<Member>> mDeptLocationMembers) {
activeMembers.clear();
//TODO replace with MultiMap
Iterator iter = mDeptLocationMembers.entrySet().iterator();
while (iter.hasNext()) {
Entry<Long, List<Member>> pairs = (Entry<Long, List<Member>>)iter.next();
if (pairs.getValue() != null) {
activeMembers.addAll(pairs.getValue());
}
}
List<Member> temp = new ArrayList<Member>();
temp.addAll(members);
memberGroups.put("active", activeMembers);
System.out.println("active qty: " + activeMembers.size());
temp.removeAll(activeMembers);
inactiveMembers.clear();
inactiveMembers.addAll(temp);
System.out.println("inactive qty: " + inactiveMembers.size());
memberGroups.put("inactive", inactiveMembers);
alertMemberGroups.put(alertId, memberGroups);
System.out.println("allMembers qty: " + allMembers.size());
System.out.println("memberGroups qty: " + memberGroups.size());
System.out.println("alertMemberGroups qty: " + alertMemberGroups.size());
System.out.println("Exit: memberGroups");
}
// determine elapsed time between alert start and current system time
private void elapsedTime(HttpServletResponse response, ServletRequest request, Alert a) {
// format elapsed time
SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm");
SimpleDateFormat dateFormat2 = new SimpleDateFormat("HH:mm");
dateFormat.setTimeZone(TimeZone.getTimeZone("EST"));
dateFormat2.setTimeZone(TimeZone.getTimeZone("UTC"));
Long alertTime = Long.valueOf(a.gettimeStamp());
String alertElapsedTime =
dateFormat.format(new Date(System.currentTimeMillis() - alertTime - 19*3600000));
// for display in the header of the report
request.setAttribute("alertElapsedTime", alertElapsedTime);
return;
}
private void alert(HttpServletResponse response, ServletRequest request) {
// set alert cookie
Long tempAlertId = Long.valueOf(request.getParameter("alertId"));
if (tempAlertId != null) {
Cookie c1 = new Cookie("cvAlertId", tempAlertId.toString());
c1.setMaxAge(MAX_COOKIE_AGE_MS);
response.addCookie(c1);
alertId = tempAlertId;
}
// get alert object
PersistenceManager pm = PMF.get().getPersistenceManager();
Alert a = pm.getObjectById(Alert.class, alertId);
request.setAttribute("alert", a);
elapsedTime(response, request, a);
}
}
|