[HER-1764] H3 needs in-UI quit/shutdown option

* EngineResource.java
    add 'exit' control area at bottom of page
    allow JVM-exit if confirm-box checked and either no jobs built/running or extra confirm boxes for each built job checked
* Flash.java
    fix to allow multiple flashes per page load
* JobResource.java, CrawlJob.java
    move useful status string method to CrawlJob
This commit is contained in:
gojomo
2010-06-16 00:51:58 +00:00
parent 4c1a4f2e12
commit 2e03aa8cb7
4 changed files with 93 additions and 25 deletions
@@ -214,19 +214,22 @@ public class CrawlJob implements Comparable<CrawlJob>, ApplicationListener {
}
public void writeHtmlTo(PrintWriter pw, String uriPrefix) {
pw.println("<span class='job'>");
if(isRunning()) {
pw.println("ACTIVE; "+getCrawlController().getState()+":");
}
// if(isRunning()) {
// pw.println("ACTIVE; "+getCrawlController().getState()+":");
// }
pw.println("<a href='"+uriPrefix+TextUtils.urlEscape(getShortName())+"'>"+getShortName()+"</a>");
if(isProfile()) {
pw.println("(profile)");
}
if(hasApplicationContext()) {
pw.println("&laquo;"+getJobStatusDescription()+"&raquo;");
}
if (true == isLaunchInfoPartial) {
pw.print(" at least ");
} else {
pw.print(" ");
}
pw.println(getLaunchCount() + " launches");
pw.println(getLaunchCount() + " launches");
pw.println("<br/><span style='color:#666'>");
pw.println(getPrimaryConfig());
pw.println("</span><br/>");
@@ -897,4 +900,16 @@ public class CrawlJob implements Comparable<CrawlJob>, ApplicationListener {
return null;
}
}
public String getJobStatusDescription() {
if(!hasApplicationContext()) {
return "Unbuilt";
} else if(isRunning()) {
return "Active: "+getCrawlController().getState();
} else if(isLaunchable()){
return "Ready";
} else {
return "Finished: "+getCrawlController().getCrawlExitStatus();
}
}
}//EOC
@@ -26,6 +26,7 @@ import java.io.Writer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
@@ -142,12 +143,45 @@ public class EngineResource extends BaseResource {
}
}
}
} else if ("Exit Java Process".equals(action)) {
boolean cancel = false;
if(!"on".equals(form.getFirstValue("I'm sure"))) {
Flash.addFlash(
getResponse(),
"You must tick \"I'm sure\" to trigger exit",
Flash.Kind.NACK);
cancel = true;
}
for(Map.Entry<String,CrawlJob> entry : getBuiltJobs().entrySet()) {
if(!"on".equals(form.getFirstValue("ignore__"+entry.getKey()))) {
Flash.addFlash(
getResponse(),
"Job '"+entry.getKey()+"' still &laquo;"
+entry.getValue().getJobStatusDescription()
+"&raquo;",
Flash.Kind.NACK);
cancel = true;
}
}
if(!cancel) {
System.exit(0);
}
}
// default: redirect to GET self
getResponse().redirectSeeOther(getRequest().getOriginalRef());
}
protected HashMap<String, CrawlJob> getBuiltJobs() {
HashMap<String,CrawlJob> builtJobs = new HashMap<String,CrawlJob>();
for(Map.Entry<String,CrawlJob> entry : getEngine().getJobConfigs().entrySet()) {
if(entry.getValue().hasApplicationContext()) {
builtJobs.put(entry.getKey(),entry.getValue());
}
}
return builtJobs;
}
protected List<String> getAvailableActions() {
List<String> actions = new LinkedList<String>();
actions.add("rescan");
@@ -268,6 +302,26 @@ public class EngineResource extends BaseResource {
"'rescan' button above to make it appear in this interface. Or, " +
"use the 'copy' functionality at the botton of any existing " +
"job's detail page.");
pw.println("<h2>Exit Java</h2>");
pw.println(
"This exits the Java process running Heritrix. To restart " +
"will then require access to the hosting machine. You should " +
"cleanly terminate and teardown any jobs in progress first.<br/>");
pw.println("<form method=\'POST\'>");
for(Map.Entry<String,CrawlJob> entry : getBuiltJobs().entrySet()) {
pw.println("<br/>Job '"+entry.getKey()+"' still &laquo;"
+entry.getValue().getJobStatusDescription()
+"&raquo;<br>");
String checkName = "ignore__"+entry.getKey();
pw.println("<input type='checkbox' id='"+checkName+"' name='"
+checkName+"'><label for='"+checkName+"'> Ignore job '"
+entry.getKey()+"' and exit anyway</label><br/>");
}
pw.println("<br/><input type='submit' name='action' value='Exit Java Process'>");
pw.println("<input type='checkbox' name=\"I'm sure\" id=\"I'm sure\"><label for=\"I'm sure\"> I'm sure</label>");
pw.println("</form>");
pw.println("</body>");
pw.flush();
}
@@ -62,18 +62,29 @@ public class Flash {
public static void addFlash(Response response, String message, Kind kind) {
dropboxes.put(nextdrop,new Flash(message, kind));
Series<CookieSetting> cookies = response.getCookieSettings();
cookies.add(new CookieSetting("flashdrop",Long.toString(nextdrop)));
CookieSetting flashdrop = null;
for(CookieSetting cs : cookies) {
if(cs.getName().equals("flashdrop")) {
flashdrop = cs;
}
}
if(flashdrop == null) {
cookies.add(new CookieSetting("flashdrop",Long.toString(nextdrop)));
} else {
flashdrop.setValue(flashdrop.getValue()+","+Long.toString(nextdrop));
}
nextdrop++;
}
public static List<Flash> getFlashes(Request request) {
List<Flash> flashes = new LinkedList<Flash>();
Series<Cookie> cookies = request.getCookies();
String dropbox = cookies.getFirstValue("flashdrop");
if(dropbox!=null) {
Flash flash = dropboxes.remove(Long.parseLong(dropbox));
if(flash!=null) {
flashes.add(flash);
for (String dropbox : cookies.getFirstValue("flashdrop").split(",")) {
if(dropbox!=null) {
Flash flash = dropboxes.remove(Long.parseLong(dropbox));
if(flash!=null) {
flashes.add(flash);
}
}
}
return flashes;
@@ -132,7 +132,7 @@ public class JobResource extends BaseResource {
info.put("crawlExitStatus", cj.getCrawlController().getCrawlExitStatus());
}
}
info.put("statusDescription", getJobStatusDescription());
info.put("statusDescription", cj.getJobStatusDescription());
info.put("availableActions", getAvailableActions());
info.put("launchCount", cj.getLaunchCount());
@@ -220,7 +220,7 @@ public class JobResource extends BaseResource {
protected void writeHtml(Writer writer) {
PrintWriter pw = new PrintWriter(writer);
String jobTitle = cj.getShortName() + " - "
+ getJobStatusDescription()
+ cj.getJobStatusDescription()
+ " - Job main page";
String baseRef = getRequest().getResourceRef().getBaseRef().toString();
if(!baseRef.endsWith("/")) {
@@ -360,7 +360,7 @@ public class JobResource extends BaseResource {
}
pw.println("</div>");
pw.println("<h2>Job is "+getJobStatusDescription()+"</h2>");
pw.println("<h2>Job is "+cj.getJobStatusDescription()+"</h2>");
if(cj.hasApplicationContext()) {
pw.println("<b>Totals</b><br/>&nbsp;&nbsp;");
@@ -480,18 +480,6 @@ public class JobResource extends BaseResource {
"<label for='asProfile'>as profile</label></form>");
pw.println("<hr/>");
}
public String getJobStatusDescription() {
if(!cj.hasApplicationContext()) {
return "Unbuilt";
} else if(cj.isRunning()) {
return "Active: "+cj.getCrawlController().getState();
} else if(cj.isLaunchable()){
return "Ready";
} else {
return "Finished: "+cj.getCrawlController().getCrawlExitStatus();
}
}
/**
* Print a link to the given File