%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page trimDirectiveWhitespaces="true" %>
<%@ page import="org.crosswire.community.projects.ntmss.data.ProjectManagement" %>
<%@ page import="org.crosswire.community.projects.ntmss.data.DocumentGroup" %>
<%@ page import="org.crosswire.community.projects.ntmss.data.Transcription" %>
<%@ page import="org.crosswire.sword.keys.VerseKey" %>
<%@ page import="org.crosswire.data.DataObject" %>
<%@ page import="java.util.Vector" %>
<%@ page import="java.text.SimpleDateFormat" %>
<%@ page import="java.util.List" %>
<%@ page import="java.util.Arrays" %>
<%@ page import="org.crosswire.xml.XMLDataElement" %>
<%@ page import="org.crosswire.webtools.RightsAndRoles" %>
<%@ page import="org.crosswire.utils.HTTPUtils" %>
<%@ page import="org.crosswire.utils.Utils" %>
<%@ page import="org.crosswire.xml.XMLBlock" %>
<%@ page import="org.crosswire.webtools.annotation.*" %>
<%@ page import="org.crosswire.webtools.*" %>
<%!
static public SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm");
@Description(value = "Retrieve projects.", name = "project/get")
public static class MyParameters extends Parameters {
protected Vector projects = new Vector();
@Description(value = "project id to retrieve, can be a list delimited by '|'", example = "1|2", defaultValue = "either projectID or projectName is required")
public String projectID;
@Description(value = "project name to retrieve, can be a list delimited by '|'", example = "ECM Matthew")
public String projectName;
@Description(value = "progressively more detail: [header,users,documents,tasks,scope,progress]", defaultValue = "header", example = "tasks")
public String detail;
@Description(value = "if reporting progress, use chapter intead of document for divisions", defaultValue = "false", example = "true")
public boolean statusChapter = false;
@Description(value = "if reporting chapter progress, report only for this chapter and expand verses", example = "Matt.3")
public String expandChapterVerses = null;
@Description(value = "'|' separated list of project roles to check for each user", example = "joe|charlie")
public String userProjectRolesCheck;
// TODO: pseudoAssign doesn't work yet
@Description(value = "internal use", defaultValue = "header", example = "tasks")
public String pseudoAssign = null;
@Override
protected void afterLoad() {
projectName = Transcription.assureUnicode(projectName);
userProjectRolesCheck = Transcription.assureUnicode(userProjectRolesCheck);
}
@Override
protected void customValidation() {
if (projectID == null && projectName == null) {
addError(-4, "Must supply either {projectID} or {projectName}.");
return;
}
if (projectID != null) {
for (String pID : projectID.split("\\|")) {
int id = -1; try {id = Integer.parseInt(pID);} catch (Exception e){}
ProjectManagement.Project pr = ProjectManagement.getProject(id);
if (pr != null) projects.add(pr);
}
}
if (projectName != null) {
for (String pName : projectName.split("\\|")) {
ProjectManagement.Project pr = ProjectManagement.getProject(pName);
if (pr != null) projects.add(pr);
}
}
}
}
%>
<%
MyParameters params = new MyParameters().loadFromRequest(request, response, false);
if (params.getErrors().size() == 0) {
if (params.projects.isEmpty()) {
params.addError(-7, "No specified projects were found.");
return;
}
// TODO: pseudoAssign doesn't work yet
params.pseudoAssign = null;
int detail = 1;
if ("users".equals(request.getParameter("detail"))) detail = 2;
else if ("documents".equals(params.detail)) detail = 3;
else if ("tasks".equals(params.detail)) detail = 4;
else if ("scope".equals(params.detail)) detail = 5;
else if ("progress".equals(params.detail)) detail = 6;
long start = System.nanoTime();
params.getLogger().debug("finish project query in "+ (System.nanoTime() - start)/1e6 + "ms");
// This is kindof a lame place to return this, but maybe we'll allow projects to specify their own
// to override the default set in sysconfig.properties
// so... it's not a completely lame place to return this
// but it does allow us to get this information with a project configuration and if no project is active
// it returns to sysconfig.properties default setting
String defaultCatalogBrowseChoicesString = Utils.getSysConfig(session).getProperty("CatalogBrowseChoices");
String defaultCatalogBrowseChoices[] = defaultCatalogBrowseChoicesString != null ? defaultCatalogBrowseChoicesString.split("\\|") : new String[0];
StringBuffer retVal = new StringBuffer();
retVal.append("");
retVal.append("");
for (String c : defaultCatalogBrowseChoices) {
int e = c.indexOf("=");
String label = (e > -1) ? c.substring(0,e) : c;
String query = (e > -1) ? c.substring(e+1) : "";
retVal.append("" + HTTPUtils.canonize(query) + "");
}
retVal.append("");
for (ProjectManagement.Project p : params.projects) {
if (detail == 1) {
retVal.append(p.toFormattedXML());
}
else {
XMLBlock project = XMLBlock.createXMLBlock(p.toFormattedXML());
params.getLogger().debug("project: " + project.toString());
if (detail > 1) {
String groupName = project.getAttribute("userGroup");
if (groupName == null || groupName.trim().length() < 1) groupName = project.getAttribute("name");
RightsAndRoles.UserGroup ug = RightsAndRoles.getInstance().getUserGroup(groupName);
XMLBlock perms = null;
if (params.userProjectRolesCheck != null) {
perms = XMLBlock.createXMLBlock("");
for (String r : params.userProjectRolesCheck.split("\\|")) {
XMLBlock role = perms.createBlock("role");
role.setAttribute("name", r);
for (XMLDataElement u : ug.getElements("user")) {
if (RightsAndRoles.getInstance().hasRole(RightsAndRoles.getInstance().getUser(u.getText()), r, ug)) {
role.createValue("user", u.getText());
}
}
}
}
if (ug != null) project.addBlock(XMLBlock.createXMLBlock(ug.formattedString()));
if (perms != null) project.addBlock(perms);
params.getLogger().debug("userGroup: " + ug.toString());
if (detail > 2) {
DocumentGroup dg = DocumentGroup.getDocumentGroup(Integer.parseInt(project.getAttribute("secondaryDocumentGroupID")));
if (dg != null) project.addBlock(XMLBlock.createXMLBlock(dg.toFormattedXML())).setAttribute("secondary", "true");
dg = DocumentGroup.getDocumentGroup(Integer.parseInt(project.getAttribute("documentGroupID")));
if (dg != null) project.addBlock(XMLBlock.createXMLBlock(dg.toFormattedXML())).setAttribute("primary", "true");;
if (dg != null && detail > 3 && !params.statusChapter) {
params.getLogger().debug("starting detail > 3 at "+ (System.nanoTime() - start)/1e6 + "ms");
XMLBlock docs = project.getBlock("documentGroup", "primary", "true").getBlock("documents");
int cc = 0;
List assignments = null;
params.getLogger().debug("Project Task Type ID: " + p.getTaskTypeID());
if (p.getTaskTypeID() != 3) {
assignments = Arrays.asList(ProjectManagement.getProjectAssignments(p.getProjectID(), false));
}
else assignments = ProjectManagement.getProjectTranscriptionAssignments(p.getProjectID(), params.pseudoAssign);
for (ProjectManagement.Task t : assignments) {
++cc;
XMLBlock b = docs.getBlock("document", "docID", Integer.toString(t.getObjectID()));
if (b != null) {
XMLBlock tb = b.createBlock("task");
tb.setAttribute("taskID", Integer.toString(t.getTaskID()));
tb.setAttribute("assignedTo", t.getAssignedTo());
tb.setAttribute("completedUnits", Integer.toString(t.getCompletedUnits()));
tb.setAttribute("objectID", Integer.toString(t.getObjectID()));
tb.setAttribute("objectName", t.getObjectName());
tb.setAttribute("objectPart", t.getObjectPart());
tb.setAttribute("percentageComplete", Integer.toString(t.getPercentageComplete()));
tb.setAttribute("projectID", Integer.toString(t.getProjectID()));
tb.setAttribute("taskTypeID", Integer.toString(t.getTaskTypeID()));
tb.setAttribute("totalUnits", Integer.toString(t.getTotalUnits()));
tb.setAttribute("stage", Integer.toString(t.getTaskStage()));
tb.setAttribute("completedUnitsMap", t.getCompletedUnitMap());
// too slow
// b.addBlock(XMLBlock.createXMLBlock(t.toFormattedXML()));
}
}
params.getLogger().debug("cc = " + cc+ " finished detail > 3 at "+ (System.nanoTime() - start)/1e6 + "ms");
if (detail > 4) {
for (XMLBlock d : docs.getBlocks("document")) {
ProjectManagement.Task t = new ProjectManagement.Task(-1, p.getProjectID(), Integer.parseInt(d.getAttribute("docID")), p.getTaskTypeID(), "", p.getObjectPart(), 0);
ProjectManagement.computeAssignment(t);
d.setAttribute("totalUnits", Integer.toString(t.getTotalUnits()));
}
}
}
}
}
if (params.statusChapter) {
DataObject query = new DataObject();
query.setIntValue("SEGMENTGROUPID", p.getProjectID());
VerseKey vk = new VerseKey();
vk.setIntros(true);
String sql = "";
if (params.expandChapterVerses == null) {
sql += " select SEGMENTGROUPID, CHAPTER, COUNT(1) VERSECOUNT, SUM(VERSESEGMENTCOUNT) TOTALSEGMENTS, ROUND(AVG(VERSESEGMENTCOUNT)) AVGSEGSPERVERSE, CAST(MAX(LASTUPDATEWITNESS) AS DATETIME) LASTUPDATEWITNESS, CAST(MAX(LASTUPDATEREADING) AS DATETIME) LASTUPDATEREADING, SUM(ASSIGNED) ASSIGNED, SUM(OFINTEREST) OFINTEREST, SUM(STARTED) STARTED, SUM(PROBLEMATIC) PROBLEMATIC, SUM(REVIEWED) REVIEWED, SUM(COMPLETED) COMPLETED, SUM(COMMENTSPRIVATE) COMMENTSPRIVATE, SUM(COMMENTSWITNESS) COMMENTSWITNESS, SUM(COMMENTSSEGMENT) COMMENTSSEGMENT FROM (";
sql += " select SEGMENTGROUPID, CHAPTER, COUNT(1) VERSESEGMENTCOUNT, MAX(LASTUPDATEWITNESS) LASTUPDATEWITNESS, MAX(LASTUPDATEREADING) LASTUPDATEREADING, SUM(ASSIGNED) ASSIGNED, SUM(OFINTEREST) OFINTEREST, SUM(STARTED) STARTED, SUM(PROBLEMATIC) PROBLEMATIC, SUM(REVIEWED) REVIEWED, SUM(COMPLETED) COMPLETED, SUM(COMMENTSPRIVATE) COMMENTSPRIVATE, SUM(COMMENTSWITNESS) COMMENTSWITNESS, SUM(COMMENTSSEGMENT) COMMENTSSEGMENT FROM (";
sql += " select SEGMENTGROUPID, CAST(VERSE/1000 AS INTEGER)*1000 CHAPTER, VERSE,";
sql += " CAST((SELECT MAX(CREATEDATE) FROM SEGMENTREADINGWITNESS SRW where SRW.PROJECTID=SEGMENTGROUPID AND SRW.SEGMENTID=S.SEGMENTID and DOCUMENTID<>-1) AS DATETIME) LASTUPDATEWITNESS,";
sql += " CAST((SELECT MAX(CREATEDATE) FROM SEGMENTREADING SR where SR.SEGMENTID=S.SEGMENTID) AS DATETIME) LASTUPDATEREADING,";
sql += " (SELECT 1 FROM SEGMENTREADINGWITNESS SRW where SRW.PROJECTID=SEGMENTGROUPID AND SRW.SEGMENTID=S.SEGMENTID and DOCUMENTID=-1 AND SEGMENTREADINGID<=0 GROUP BY SRW.SEGMENTID) STARTED,";
sql += " (SELECT 1 FROM SEGMENTREADINGWITNESS SRW where SRW.PROJECTID=SEGMENTGROUPID AND SRW.SEGMENTID=S.SEGMENTID and DOCUMENTID=-1 AND SEGMENTREADINGID=0 GROUP BY SRW.SEGMENTID) ASSIGNED,";
sql += " (SELECT 1 FROM SEGMENTREADINGWITNESS SRW where SRW.PROJECTID=SEGMENTGROUPID AND SRW.SEGMENTID=S.SEGMENTID and DOCUMENTID=-1 and SEGMENTREADINGID=-2 GROUP BY SRW.SEGMENTID) OFINTEREST,";
sql += " (SELECT 1 FROM SEGMENTREADINGWITNESS SRW where SRW.PROJECTID=SEGMENTGROUPID AND SRW.SEGMENTID=S.SEGMENTID and DOCUMENTID=-1 and SEGMENTREADINGID=-4 GROUP BY SRW.SEGMENTID) PROBLEMATIC,";
sql += " (SELECT 1 FROM SEGMENTREADINGWITNESS SRW where SRW.PROJECTID=SEGMENTGROUPID AND SRW.SEGMENTID=S.SEGMENTID and DOCUMENTID=-1 and SEGMENTREADINGID=-1 GROUP BY SRW.SEGMENTID) REVIEWED,";
sql += " (SELECT 1 FROM SEGMENTREADINGWITNESS SRW where SRW.PROJECTID=SEGMENTGROUPID AND SRW.SEGMENTID=S.SEGMENTID and DOCUMENTID=-1 and SEGMENTREADINGID=-3 GROUP BY SRW.SEGMENTID) COMPLETED,";
sql += " (SELECT COUNT(1) FROM SEGMENTREADINGWITNESS SRW where SRW.PROJECTID=SEGMENTGROUPID AND SRW.SEGMENTID=S.SEGMENTID and DOCUMENTID > 0 and COMMENTPRIVATE is not null and LENGTH(COMMENTPRIVATE) > 1) COMMENTSPRIVATE,";
sql += " (SELECT COUNT(1) FROM SEGMENTREADINGWITNESS SRW where SRW.PROJECTID=SEGMENTGROUPID AND SRW.SEGMENTID=S.SEGMENTID and DOCUMENTID > 0 and COMMENT is not null and LENGTH(COMMENT) > 1) COMMENTSWITNESS,";
sql += " (SELECT COUNT(1) FROM SEGMENTREADINGWITNESS SRW where SRW.PROJECTID=SEGMENTGROUPID AND SRW.SEGMENTID=S.SEGMENTID and DOCUMENTID > 0 and COMMENTSEGMENT is not null and LENGTH(COMMENTSEGMENT) > 1) COMMENTSSEGMENT";
sql += " FROM SEGMENT S left join SEGMENTGROUPSEGMENT SGS on SGS.SEGMENTID=S.SEGMENTID WHERE SEGMENTGROUPID={SEGMENTGROUPID}";
sql += " ) X GROUP BY SEGMENTGROUPID, VERSE";
sql += " ) Y GROUP BY SEGMENTGROUPID, CHAPTER;";
}
else {
sql += " select SEGMENTGROUPID, CHAPTER, VERSE, COUNT(1) TOTALSEGMENTS, CAST(MAX(LASTUPDATEWITNESS) AS DATETIME) LASTUPDATEWITNESS, CAST(MAX(LASTUPDATEREADING) AS DATETIME) LASTUPDATEREADING, SUM(ASSIGNED) ASSIGNED, SUM(OFINTEREST) OFINTEREST, SUM(STARTED) STARTED, SUM(PROBLEMATIC) PROBLEMATIC, SUM(REVIEWED) REVIEWED, SUM(COMPLETED) COMPLETED, SUM(COMMENTSPRIVATE) COMMENTSPRIVATE, SUM(COMMENTSWITNESS) COMMENTSWITNESS, SUM(COMMENTSSEGMENT) COMMENTSSEGMENT FROM (";
sql += " select SEGMENTGROUPID, CAST(VERSE/1000 AS INTEGER)*1000 CHAPTER, VERSE,";
sql += " CAST((SELECT MAX(CREATEDATE) FROM SEGMENTREADINGWITNESS SRW where SRW.PROJECTID=SEGMENTGROUPID AND SRW.SEGMENTID=S.SEGMENTID and DOCUMENTID<>-1) AS DATETIME) LASTUPDATEWITNESS,";
sql += " CAST((SELECT MAX(CREATEDATE) FROM SEGMENTREADING SR where SR.SEGMENTID=S.SEGMENTID) AS DATETIME) LASTUPDATEREADING,";
sql += " (SELECT 1 FROM SEGMENTREADINGWITNESS SRW where SRW.PROJECTID=SEGMENTGROUPID AND SRW.SEGMENTID=S.SEGMENTID and DOCUMENTID=-1 and SEGMENTREADINGID<=0 GROUP BY SRW.SEGMENTID) STARTED,";
sql += " (SELECT 1 FROM SEGMENTREADINGWITNESS SRW where SRW.PROJECTID=SEGMENTGROUPID AND SRW.SEGMENTID=S.SEGMENTID and DOCUMENTID=-1 AND SEGMENTREADINGID=0 GROUP BY SRW.SEGMENTID) ASSIGNED,";
sql += " (SELECT 1 FROM SEGMENTREADINGWITNESS SRW where SRW.PROJECTID=SEGMENTGROUPID AND SRW.SEGMENTID=S.SEGMENTID and DOCUMENTID=-1 and SEGMENTREADINGID=-2 GROUP BY SRW.SEGMENTID) OFINTEREST,";
sql += " (SELECT 1 FROM SEGMENTREADINGWITNESS SRW where SRW.PROJECTID=SEGMENTGROUPID AND SRW.SEGMENTID=S.SEGMENTID and DOCUMENTID=-1 and SEGMENTREADINGID=-4 GROUP BY SRW.SEGMENTID) PROBLEMATIC,";
sql += " (SELECT 1 FROM SEGMENTREADINGWITNESS SRW where SRW.PROJECTID=SEGMENTGROUPID AND SRW.SEGMENTID=S.SEGMENTID and DOCUMENTID=-1 and SEGMENTREADINGID<=-1 GROUP BY SRW.SEGMENTID) REVIEWED,";
sql += " (SELECT 1 FROM SEGMENTREADINGWITNESS SRW where SRW.PROJECTID=SEGMENTGROUPID AND SRW.SEGMENTID=S.SEGMENTID and DOCUMENTID=-1 and SEGMENTREADINGID=-3 GROUP BY SRW.SEGMENTID) COMPLETED,";
sql += " (SELECT COUNT(1) FROM SEGMENTREADINGWITNESS SRW where SRW.PROJECTID=SEGMENTGROUPID AND SRW.SEGMENTID=S.SEGMENTID and DOCUMENTID > 0 and COMMENTPRIVATE is not null and LENGTH(COMMENTPRIVATE) > 1) COMMENTSPRIVATE,";
sql += " (SELECT COUNT(1) FROM SEGMENTREADINGWITNESS SRW where SRW.PROJECTID=SEGMENTGROUPID AND SRW.SEGMENTID=S.SEGMENTID and DOCUMENTID > 0 and COMMENT is not null and LENGTH(COMMENT) > 1) COMMENTSWITNESS,";
sql += " (SELECT COUNT(1) FROM SEGMENTREADINGWITNESS SRW where SRW.PROJECTID=SEGMENTGROUPID AND SRW.SEGMENTID=S.SEGMENTID and DOCUMENTID > 0 and COMMENTSEGMENT is not null and LENGTH(COMMENTSEGMENT) > 1) COMMENTSSEGMENT";
sql += " FROM SEGMENT S left join SEGMENTGROUPSEGMENT SGS on SGS.SEGMENTID=S.SEGMENTID WHERE SEGMENTGROUPID={SEGMENTGROUPID} AND VERSE BETWEEN {VERSESTART} AND {VERSEEND}";
sql += " ) X GROUP BY SEGMENTGROUPID, VERSE";
vk.setText(params.expandChapterVerses);
int chapHash = vk.getHashNumber();
if (false /*single verse */) {
query.setIntValue("VERSESTART", chapHash);
query.setIntValue("VERSEEND", chapHash);
}
else { /* whole chapter */
chapHash = (int)Math.floor(((double) chapHash) / 1000) * 1000;
query.setIntValue("VERSESTART", chapHash);
query.setIntValue("VERSEEND", chapHash + 999);
}
}
params.getLogger().info("SQL: " +sql);
List results = query.getDataSet(sql);
params.getLogger().info("resultsCount: " + results.size());
XMLBlock chaps = project.createBlock(params.expandChapterVerses == null ? "chapters" : "verses");
String v11n = null; // fix this soon
if (v11n != null) vk.setVersificationSystem(v11n);
for (DataObject c : results) {
XMLBlock tb = chaps.createBlock(params.expandChapterVerses == null ? "chapter" : "verse");
int chapHash = c.getIntValue("CHAPTER");
int verseHash = c.getIntValue("VERSE");
vk.setHashNumber(verseHash > 0 ? verseHash : chapHash);
tb.setAttribute("chapterHash", c.getStringValue("CHAPTER"));
tb.setAttribute("verseHash", c.getStringValue("VERSE"));
tb.setAttribute("indexContent", vk.getOSISRef());
tb.setAttribute("totalVerses", c.getStringValue("VERSECOUNT"));
tb.setAttribute("avgSegmentsPerVerse", c.getStringValue("AVGSEGSPERVERSE"));
tb.setAttribute("totalUnits", c.getStringValue("TOTALSEGMENTS"));
tb.setAttribute("startedUnits", c.getStringValue("STARTED"));
tb.setAttribute("assignedUnits", c.getStringValue("ASSIGNED"));
tb.setAttribute("ofInterestUnits", c.getStringValue("OFINTEREST"));
tb.setAttribute("problematicUnits", c.getStringValue("PROBLEMATIC"));
tb.setAttribute("reviewedUnits", c.getStringValue("REVIEWED"));
tb.setAttribute("completedUnits", c.getStringValue("COMPLETED"));
tb.setAttribute("commentsPrivate", c.getStringValue("COMMENTSPRIVATE"));
tb.setAttribute("commentsWitness", c.getStringValue("COMMENTSWITNESS"));
tb.setAttribute("commentsSegment", c.getStringValue("COMMENTSSEGMENT"));
try { tb.setAttribute("lastUpdateReading", df.format(c.getDateValue("LASTUPDATEREADING"))); } catch (Exception e) {}
try { tb.setAttribute("lastUpdateWitness", df.format(c.getDateValue("LASTUPDATEWITNESS"))); } catch (Exception e) {}
}
}
retVal.append(project.formattedString());
}
}
retVal.append("");
params.getLogger().debug("finish get project in "+ (System.nanoTime() - start)/1e6 + "ms");
Serializer.output(response, out, params, XMLBlock.createXMLBlock(retVal.toString()));
return;
}
else params.format = "html";
Serializer.reportErrors(request, response, out, params, true);
%>