Native Messaging WIP -- printing
authorBill Erickson <berickxx@gmail.com>
Wed, 9 Nov 2016 20:02:46 +0000 (15:02 -0500)
committerBill Erickson <berickxx@gmail.com>
Wed, 9 Nov 2016 20:02:46 +0000 (15:02 -0500)
Signed-off-by: Bill Erickson <berickxx@gmail.com>
src/org/evergreen_ils/hatch/Hatch.java
src/org/evergreen_ils/hatch/PrintManager.java
src/org/evergreen_ils/hatch/RequestHandler.java
src/org/evergreen_ils/hatch/TestHatch.java

index d674af6..eff340e 100644 (file)
@@ -120,11 +120,9 @@ public class Hatch extends Application {
             .stateProperty()
             .addListener( (ChangeListener<State>) (obsValue, oldState, newState) -> {
                 logger.finest("browser load state " + newState);
-                if (newState == State.SUCCEEDED) {
-                    logger.finer("Print browser page load completed");
 
-                    // Avoid nested UI event loops
-                    Platform.runLater(new Runnable() {
+                if (newState == State.SUCCEEDED) {
+                    Platform.runLater(new Runnable() { // Avoid nested events
                         @Override public void run() {
                             new PrintManager().print(browser.webEngine, request);
                         }
@@ -133,6 +131,7 @@ public class Hatch extends Application {
             });
 
         try {
+
             String content = request.getString("content");
             String contentType = request.getString("contentType");
     
index c82baeb..09e7aa4 100644 (file)
@@ -57,12 +57,10 @@ public class PrintManager {
      * the Printer configuration options (if any are already set).
      * @return A Map of printer settings extracted from the print dialog.
      */
-    public Map<String,Object> configurePrinter(
-        Map<String,Object> params) throws IllegalArgumentException {
+    public JSONObject configurePrinter(
+        JSONObject params) throws IllegalArgumentException {
 
-        @SuppressWarnings("unchecked")
-        Map<String,Object> settings = 
-            (Map<String,Object>) params.get("config");
+        JSONObject settings = params.getJSONObject("config");
 
         PrinterJob job = buildPrinterJob(settings);
         
@@ -94,52 +92,43 @@ public class PrintManager {
             long msgid = request.getLong("msgid");
             response.put("msgid", msgid);
 
-        /*
-        Long msgid = (Long) params.get("msgid");
-        Boolean showDialog = (Boolean) params.get("showDialog");
+            boolean showDialog = request.optBoolean("showDialog");
 
-        @SuppressWarnings("unchecked")
-        Map<String,Object> settings = 
-            (Map<String,Object>) params.get("config");
+            // if no "settings" are applied, use defaults.
+            JSONObject settings = request.optJSONObject("settings");
+            if (settings == null) settings = new JSONObject();
 
+            PrinterJob job = buildPrinterJob(settings);
 
-        PrinterJob job = null;
-
-        try {
-            job = buildPrinterJob(settings);
-        } catch(IllegalArgumentException e) {
-            //socket.reply(e.toString(), msgid, false);
-            return;
-        }
-
-        if (showDialog != null && showDialog.booleanValue()) {
-            //logger.info("Print dialog requested");
-
-            if (!job.showPrintDialog(null)) {
-                // job canceled by user
-                //logger.info("after dialog");
-                job.endJob();
-                //socket.reply("Print job canceled", msgid);
-                return;
+            if (showDialog) {
+                if (!job.showPrintDialog(null)) {
+                    job.endJob(); // canceled by user
+                    response.put("error", "Print job canceled by user");
+                    RequestHandler.reply(response);
+                    return;
+                }
             }
-        } else {
-            //logger.info("No print dialog requested");
-        }
-
-        engine.print(job);
-
-        job.endJob();
 
-        //socket.reply("Print job succeeded", msgid);
-        
-        */
+            engine.print(job);
+            job.endJob();
+            response.put("message", "Print job queued");
+            // TODO: support watching the print job until it completes
 
         } catch (JSONException je) {
+
             String error = "JSON request protocol error: " 
                 + je.toString() + " : " + request.toString();
 
             logger.warning(error);
             response.put("error", error);
+
+        } catch(IllegalArgumentException iae) {
+
+            String error = "Illegal argument in print request: "
+                + iae.toString() + " : " + request.toString();
+
+            logger.warning(error);
+            response.put("error", error);
         }
 
         RequestHandler.reply(response);
@@ -152,13 +141,21 @@ public class PrintManager {
      * @return The newly created printer job.
      */
     public PrinterJob buildPrinterJob(
-        Map<String,Object> settings) throws IllegalArgumentException {
+        JSONObject settings) throws IllegalArgumentException {
 
-        String name = (String) settings.get("printer");
-        Printer printer = getPrinterByName(name);
+        Printer printer;
+        if (settings.has("printer")) {
+            String name = settings.getString("printer");
+            printer = getPrinterByName(name);
+            if (printer == null) 
+                throw new IllegalArgumentException("No such printer: " + name);
 
-        if (printer == null) 
-            throw new IllegalArgumentException("No such printer: " + name);
+        } else {
+            printer = Printer.getDefaultPrinter();
+            if (printer == null) 
+                throw new IllegalArgumentException(
+                    "No printer specified; no default printer is set");
+        }
 
         PageLayout layout = buildPageLayout(settings, printer);
         PrinterJob job = PrinterJob.createPrinterJob(printer);
@@ -180,16 +177,12 @@ public class PrintManager {
      * @return The newly constructed PageLayout object.
      */
     protected PageLayout buildPageLayout(
-            Map<String,Object> settings, Printer printer) {
+        JSONObject settings, Printer printer) {
 
-        // modify the default page layout with our settings
-        @SuppressWarnings("unchecked")
-        Map<String,Object> layoutMap = 
-            (Map<String,Object>) settings.get("pageLayout");
+        JSONObject layoutMap = settings.optJSONObject("pageLayout");
 
         if (layoutMap == null) {
-            // Start with a sane default.
-            // The Java default is wonky
+            // Start with a sane default. The Java default is wonky.
             return printer.createPageLayout(
                 Paper.NA_LETTER,
                 PageOrientation.PORTRAIT,
@@ -230,65 +223,67 @@ public class PrintManager {
      * @param settings The printer configuration settings map.
      * @param job A PrinterJob, constructed from buildPrinterJob()
      */
-    protected void applySettingsToJob(
-            Map<String,Object> settings, PrinterJob job) {
+    protected void applySettingsToJob(JSONObject settings, PrinterJob job) {
 
         JobSettings jobSettings = job.getJobSettings();
 
         PrinterAttributes printerAttrs = 
             job.getPrinter().getPrinterAttributes();
 
-        String collation = (String) settings.get("collation");
-        Long copies = (Long) settings.get("copies");
-        String printColor = (String) settings.get("printColor");
-        String printQuality = (String) settings.get("printQuality");
-        String printSides = (String) settings.get("printSides");
-        String paperSource = (String) settings.get("paperSource");
-        Object[] pageRanges = (Object[]) settings.get("pageRanges");
+        if (settings.has("collation")) {
+            jobSettings.setCollation(
+                Collation.valueOf(settings.getString("collation")));
+        }
 
-        if (collation != null) 
-            jobSettings.setCollation(Collation.valueOf(collation));
+        if (settings.has("copies")) {
+            jobSettings.setCopies(settings.getInt("copies"));
+        }
+
+        if (settings.has("printColor")) {
+            jobSettings.setPrintColor(
+                PrintColor.valueOf(settings.getString("printColor")));
+        }
 
-        if (copies != null) 
-            jobSettings.setCopies(((Long) settings.get("copies")).intValue());
+        if (settings.has("printQuality")) {
+            jobSettings.setPrintQuality(
+                PrintQuality.valueOf(settings.getString("printQuality")));
+        }
 
-        if (printColor != null) 
-            jobSettings.setPrintColor(PrintColor.valueOf(printColor));
+        if (settings.has("printSides")) {
+            jobSettings.setPrintSides(
+                PrintSides.valueOf(settings.getString("printSides")));
 
-        if (printQuality != null) 
-            jobSettings.setPrintQuality(PrintQuality.valueOf(printQuality));
+        }
 
-        if (printSides != null) 
-            jobSettings.setPrintSides(PrintSides.valueOf(printSides));
+        String paperSource = settings.optString("paperSource");
 
-        // find the paperSource by name
         if (paperSource != null) {
+            // find the paperSource by name
+
             Set<PaperSource> paperSources = 
                 printerAttrs.getSupportedPaperSources();
 
-            // note: "Automatic" appears to be a virtual source,
-            // meaning no source.. meaning let the printer decide.
             for (PaperSource source : paperSources) {
                 if (source.getName().equals(paperSource)) {
-                    //logger.info("matched paper source for " + paperSource);
+                    logger.fine("Found paper source: " + paperSource);
                     jobSettings.setPaperSource(source);
                     break;
                 }
             }
         }
 
+        JSONArray pageRanges = settings.optJSONArray("pageRanges");
 
         if (pageRanges != null) {
-            //logger.info("pageRanges = " + pageRanges.toString());
             List<PageRange> builtRanges = new LinkedList<PageRange>();
             int i = 0, start = 0, end = 0;
             do {
                 if (i % 2 == 0 && i > 0)
                     builtRanges.add(new PageRange(start, end));
 
-                if (i == pageRanges.length) break;
+                if (i == pageRanges.length()) break;
 
-                int current = ((Long) pageRanges[i]).intValue();
+                int current = pageRanges.getInt(i);
                 if (i % 2 == 0) start = current; else end = current;
 
             } while (++i > 0);
@@ -304,8 +299,8 @@ public class PrintManager {
      * @param job The PrinterJob whose attributes are to be extracted.
      * @return The extracted printer settings map.
      */
-    protected Map<String,Object> extractSettingsFromJob(PrinterJob job) {
-        Map<String,Object> settings = new HashMap<String,Object>();
+    protected JSONObject extractSettingsFromJob(PrinterJob job) {
+        JSONObject settings = new JSONObject();
         JobSettings jobSettings = job.getJobSettings();
 
         //logger.info("Extracting print job settings from " + job);
@@ -339,7 +334,7 @@ public class PrintManager {
         
         // page layout --------------
         PageLayout layout = jobSettings.getPageLayout();
-        Map<String,Object> layoutMap = new HashMap<String,Object>();
+        JSONObject layoutMap = new JSONObject();
         layoutMap.put("bottomMargin", layout.getBottomMargin());
         layoutMap.put("leftMargin", layout.getLeftMargin());
         layoutMap.put("topMargin", layout.getTopMargin());
@@ -354,7 +349,7 @@ public class PrintManager {
         // page ranges --------------
         PageRange[] ranges = jobSettings.getPageRanges();
         if (ranges != null) {
-            List<Integer> pageRanges = new LinkedList<Integer>();
+            JSONArray pageRanges = new JSONArray();
 
             if (ranges.length == 1 &&
                 ranges[0].getStartPage() == 1 && 
@@ -363,14 +358,13 @@ public class PrintManager {
 
             } else {
                 for (PageRange range : ranges) {
-                    pageRanges.add(range.getStartPage());
-                    pageRanges.add(range.getEndPage());
+                    pageRanges.put(range.getStartPage());
+                    pageRanges.put(range.getEndPage());
                 }
                 settings.put("pageRanges", pageRanges);
             }
         }
 
-        //logger.info("compiled printer properties: " + settings.toString());
         return settings;
     }
 
index f74b137..72224e1 100644 (file)
@@ -8,7 +8,10 @@ import java.util.logging.*;
  * via MessageIO.
  */
 public class RequestHandler extends Thread {
+
+    /** STDIN/STDOUT handler */
     private static MessageIO io = new MessageIO();
+
     static final Logger logger = Hatch.getLogger();
 
     /**
@@ -18,14 +21,8 @@ public class RequestHandler extends Thread {
     
         long msgid = request.getLong("msgid");
         String action = request.getString("action");
-        /*
-        String key = request.getString("key");
-        String content = request.getString("content");
-        String contentType = request.getString("contentType");
-        */
-        boolean showDialog = request.optBoolean("showDialog");
 
-        logger.info("Received message action: " + action);
+        logger.info("Received message id=" + msgid + " action=" + action);
 
         JSONObject response = new JSONObject();
 
@@ -37,12 +34,20 @@ public class RequestHandler extends Thread {
                 break;
 
             case "print":
+                // Confirm a minimal data set to enqueue print requests.
                 String content = request.getString("content");
                 String contentType = request.getString("contentType");
-                Hatch.enqueuePrintRequest(request);
-                // print response is delivered from the FX print
-                // thread via reply().
-                return;    
+
+                if (content == null || "".equals(content)) {
+                    response.put("error", "Empty print message");
+
+                } else {
+
+                    Hatch.enqueuePrintRequest(request);
+                    // Responses to print requests are generated asynchronously 
+                    // and delivered from the FX print thread via reply().
+                    return;    
+                }
 
             default:
                 response.put("error", "Unknown action: " + action);
index 73c1cf9..3e172a3 100644 (file)
@@ -23,11 +23,26 @@ public class TestHatch {
 
         rest();
 
+        /*
         obj = new JSONObject();
         obj.put("msgid", msgId++);
         obj.put("action", "print");
         obj.put("contentType", "text/plain");
         obj.put("content", "Hello, World!");
+        obj.put("showDialog", true);
+        io.sendMessage(obj);
+
+        rest();
+        */
+
+        obj = new JSONObject();
+        obj.put("msgid", msgId++);
+        obj.put("action", "print");
+        obj.put("contentType", "text/html");
+        obj.put("content", "<html><body><b>HELLO WORLD</b><img src='" +
+            "http://evergreen-ils.org/wp-content/uploads/2013/09/copy-Evergreen_Logo_sm072.jpg"
+            + "'/></body></html>");
+        obj.put("showDialog", true);
         io.sendMessage(obj);
 
         rest();