hatch : extract and return job settings
authorBill Erickson <berick@esilibrary.com>
Tue, 22 Apr 2014 14:41:56 +0000 (10:41 -0400)
committerJeff Godin <jgodin@tadl.org>
Fri, 3 Jun 2016 20:38:47 +0000 (16:38 -0400)
Signed-off-by: Bill Erickson <berick@esilibrary.com>
src/org/evergreen_ils/hatch/Hatch.java
src/org/evergreen_ils/hatch/HatchWebSocketHandler.java
src/org/evergreen_ils/hatch/PrintManager.java

index d50e5b8..91e0fc0 100644 (file)
@@ -78,10 +78,10 @@ public class Hatch extends Application {
      * The code blocks on the concurrent queue, so it must be
      * run in a separate thread to avoid locking the main FX thread.
      */
-    private static class MsgListenService extends Service<Map<String,String>> {
-        protected Task<Map<String,String>> createTask() {
-            return new Task<Map<String,String>>() {
-                protected Map<String,String> call() {
+    private static class MsgListenService extends Service<Map<String,Object>> {
+        protected Task<Map<String,Object>> createTask() {
+            return new Task<Map<String,Object>>() {
+                protected Map<String,Object> call() {
                     while (true) {
                         try {
                             // take() blocks until a message is available
@@ -104,7 +104,7 @@ public class Hatch extends Application {
         startMsgTask();
     }
 
-    public static void enqueueMessage(Map<String,String> params) {
+    public static void enqueueMessage(Map<String,Object> params) {
         logger.debug("queueing print message");
         requestQueue.offer(params);
     }
@@ -113,10 +113,9 @@ public class Hatch extends Application {
      * Build a browser view from the print content, tell the
      * browser to print itself.
      */
-    private void handlePrint(Map<String,String> params) {
-        String printer = params.get("printer");
-        String content = params.get("content");
-        String contentType = params.get("contentType");
+    private void handlePrint(Map<String,Object> params) {
+        String content = (String) params.get("content");
+        String contentType = (String) params.get("contentType");
 
         browser = new BrowserView();
         Scene scene = new Scene(browser, 640, 480); // TODO: printer dimensions
@@ -127,7 +126,7 @@ public class Hatch extends Application {
             .addListener( (ChangeListener) (obsValue, oldState, newState) -> {
                 if (newState == State.SUCCEEDED) {
                     logger.debug("browser page loaded");
-                    new PrintManager().print(browser.webEngine);
+                    new PrintManager().print(browser.webEngine, params);
                 }
             });
 
@@ -150,8 +149,8 @@ public class Hatch extends Application {
 
             @Override
             public void handle(WorkerStateEvent t) {
-                Map<String,String> message =
-                    (Map<String,String>) t.getSource().getValue();
+                Map<String,Object> message =
+                    (Map<String,Object>) t.getSource().getValue();
 
                 if (message != null) handlePrint(message);
 
index 274411d..7e59b11 100644 (file)
@@ -122,11 +122,11 @@ public class HatchWebSocketHandler {
         this.session = null;
     }
 
-    private void reply(Object json, String msgid) {
+    protected void reply(Object json, String msgid) {
         reply(json, msgid, true);
     }
 
-    private void reply(Object json, String msgid, boolean success) {
+    protected void reply(Object json, String msgid, boolean success) {
 
         Map<String, Object> response = new HashMap<String, Object>();
         response.put("msgid", msgid);
@@ -153,20 +153,20 @@ public class HatchWebSocketHandler {
         if (session == null || !session.isOpen()) return;
         logger.info("onMessage() " + message);
 
-        HashMap<String,String> params = null;
+        HashMap<String,Object> params = null;
 
         try {
-            params = (HashMap<String,String>) JSON.parse(message);
+            params = (HashMap<String,Object>) JSON.parse(message);
         } catch (ClassCastException e) {
             reply("Invalid WebSockets JSON message " + message, "", false);
         }
 
         FileIO io;
-        String msgid = params.get("msgid");
-        String action = params.get("action");
-        String key = params.get("key");
-        String value = params.get("value");
-        String mime = params.get("mime");
+        String msgid = (String) params.get("msgid");
+        String action = (String) params.get("action");
+        String key = (String) params.get("key");
+        String value = (String) params.get("value");
+        String mime = (String) params.get("mime");
 
         logger.info("Received request for action " + action);
 
@@ -194,20 +194,27 @@ public class HatchWebSocketHandler {
         }
 
         if (action.equals("printers")) {
-            List printers = new PrintManager().getPrinters();
+            List printers = new PrintManager().getPrintersAsMaps();
             reply(printers, msgid);
             return;
         }
 
         if (action.equals("print")) {
-            // TODO: validate the print target first so we can respond
-            // with an error if the requested printer / attributes are
-            // not supported.  Printing occurs in a separate thread,
-            // so for now just assume it succeeded.  Maybe later add
-            // a response queue and see if this handler is capable of
-            // responding from an alternate thread.
+            // pass ourselves off to the print handler so it can reply
+            // for us after printing has completed.
+            params.put("socket", this);
             Hatch.enqueueMessage(params);
-            reply("print succeeded", msgid);
+            return;
+        }
+
+        if (action.equals("print-config")) {
+            // pass ourselves off to the print handler so it can reply
+            // for us after printing has completed.
+            String printer = (String) params.get("printer");
+            reply(
+                new PrintManager().configurePrinter(printer),
+                msgid
+            );
             return;
         }
 
index ae52aee..ded234a 100644 (file)
@@ -22,10 +22,17 @@ import org.eclipse.jetty.util.log.Logger;
 // printing
 import javafx.print.*;
 import javafx.scene.web.WebEngine;
+import javafx.collections.ObservableSet;
+import javafx.collections.SetChangeListener;
+
+import java.util.Set;
+import java.util.LinkedHashSet;
+
 import javax.print.PrintService;
 import javax.print.PrintServiceLookup;
 import javax.print.attribute.Attribute;
 import javax.print.attribute.AttributeSet;
+import javax.print.attribute.PrintRequestAttributeSet;
 import javax.print.attribute.standard.Media;
 import javax.print.attribute.standard.OrientationRequested;
 
@@ -40,16 +47,201 @@ public class PrintManager {
 
     static final Logger logger = Log.getLogger("PrintManager");
 
-    public void print(WebEngine engine) {
-        debugPrintService(null); // testing
+    public Attribute getAttribute(
+        PrintService service, Class attrClass, String name) {
+
+        Attribute[] attrs = (Attribute[])
+            service.getSupportedAttributeValues(attrClass, null, null);
+
+        for (Attribute a : attrs) {
+            if (a.toString().equals(name)) 
+                return a;
+        }
+        return null;
+    }
+
+    public Map<String,Object> configurePrinter(String name) {
+        Printer printer = getPrinterByName(name);
+        PrinterJob job = PrinterJob.createPrinterJob(printer);
+        job.showPrintDialog(null);
+        Map<String,Object> settings = printerSettingsToMap(job);
+        job.endJob();
+        return settings;
+    }
+
+    public void print(WebEngine engine, Map<String,Object>params) {
+        
+        //debugPrintService(null); // testing
+
+        /*
+        Map<String,String> attrs = 
+            (Map<String,String>) params.get("attributes");
+
+        String printerName = (String) attrs.get("printer-name");
+        PrintService service = getPrintServiceByName(printerName);
+
+        if (service == null) {
+            logger.warn("printer '" + printerName + "' not found!");
+            debugPrintService();
+            return;
+        }
 
-        Printer printer = Printer.getDefaultPrinter();
         PrinterJob job = PrinterJob.createPrinterJob();
+        Attribute mediaAttr = getAttribute(
+            service, Media.class, (String) attrs.get("media"));
+
+        Attribute orientationAttr = getAttribute(
+            service, RequestedOrientation.class, 
+            (String) attrs.get("orientation"));
+
+        PrintRequestAttributeSet attrSet = new PrintRequestAttributeSet();
+        if (mediaAttr != null) attrSet.add(mediaAttr);
+        if (orientationAttr != null) attrSet.add(orientationAttr);
+        */
+
+
+        //getPrinterByName(); ...
+        Printer printer = Printer.getDefaultPrinter(); // TODO
+        PageLayout firstLayout = printer.createPageLayout(
+            Paper.NA_LETTER,
+            PageOrientation.LANDSCAPE,
+            0.1 * 72, 0.2 * 72, 0.3 * 72, 0.4 * 72 
+        );
+
+        logger.info("orig job page layout " + firstLayout.toString());
+        PrinterJob job = PrinterJob.createPrinterJob(printer);
+
+        job.getJobSettings().setPageLayout(firstLayout);
         if (!job.showPrintDialog(null)) return; // print canceled by user
+
+        Map<String,Object> settings = printerSettingsToMap(job);
         engine.print(job);
         job.endJob();
+
+        HatchWebSocketHandler socket = 
+            (HatchWebSocketHandler) params.get("socket");
+
+        socket.reply(settings, (String) params.get("msgid"));
+    }
+
+    protected Map<String,Object> printerSettingsToMap(PrinterJob job) {
+        Map<String,Object> settings = new HashMap<String,Object>();
+        JobSettings jobSettings = job.getJobSettings();
+
+        settings.put(
+            jobSettings.collationProperty().getName(),
+            jobSettings.collationProperty().getValue()
+        );
+        settings.put(
+            jobSettings.copiesProperty().getName(),
+            jobSettings.copiesProperty().getValue()
+        );
+        settings.put(
+            jobSettings.paperSourceProperty().getName(),
+            jobSettings.paperSourceProperty().getValue()
+        );
+        settings.put(
+            jobSettings.printColorProperty().getName(),
+            jobSettings.printColorProperty().getValue()
+        );
+        settings.put(
+            jobSettings.printQualityProperty().getName(),
+            jobSettings.printQualityProperty().getValue()
+        );
+        settings.put(
+            jobSettings.printSidesProperty().getName(),
+            jobSettings.printSidesProperty().getValue()
+        );
+
+        // nested properties...
+        
+        // page layout --------------
+        PageLayout layout = jobSettings.getPageLayout();
+        Map<String,Object> layoutMap = new HashMap<String,Object>();
+        layoutMap.put("bottomMargin", layout.getBottomMargin());
+        layoutMap.put("leftMargin", layout.getLeftMargin());
+        layoutMap.put("topMargin", layout.getTopMargin());
+        layoutMap.put("rightMargin", layout.getRightMargin());
+        layoutMap.put("pageOrientation", layout.getPageOrientation().toString());
+        layoutMap.put("printableHeight", layout.getPrintableHeight());
+        layoutMap.put("printableWidth", layout.getPrintableWidth());
+
+        Paper paper = layout.getPaper();
+        Map<String,Object> paperMap = new HashMap<String,Object>();
+        paperMap.put("height", paper.getHeight());
+        paperMap.put("width", paper.getWidth());
+        paperMap.put("name", paper.getName());
+        layoutMap.put("paper", paperMap);
+
+        settings.put("pageLayout", layoutMap);
+
+        // page ranges --------------
+        PageRange[] ranges = jobSettings.getPageRanges();
+        if (ranges != null) {
+            List<Map<String,Integer>> pageRanges = 
+                new LinkedList<Map<String,Integer>>();
+
+            for (PageRange range : ranges) {
+                Map<String,Integer> oneRange = new HashMap<String,Integer>();
+                oneRange.put("startPage", range.getStartPage());
+                oneRange.put("startPage", range.getEndPage());
+                pageRanges.add(oneRange);
+            }
+            settings.put("pageRanges", pageRanges);
+        }
+
+
+        // resolution --------------
+        PrintResolution resolution = jobSettings.getPrintResolution();
+        Map<String,Integer> resolutionMap = new HashMap<String,Integer>();
+        resolutionMap.put("feedResolution", resolution.getFeedResolution());
+        resolutionMap.put("crossFeedResolution", resolution.getCrossFeedResolution());
+        settings.put("printResolution", resolutionMap);
+
+        logger.info("compiled printer properties: " + settings.toString());
+        return settings;
+    };
+
+    protected Printer[] getPrinters() {
+        ObservableSet<Printer> printerObserver = Printer.getAllPrinters();
+
+        if (printerObserver == null) return new Printer[0];
+
+        return (Printer[]) printerObserver.toArray(new Printer[0]);
     }
 
+    protected List<Map<String,Object>> getPrintersAsMaps() {
+        Printer[] printers = getPrinters();
+
+        List<Map<String,Object>> printerMaps = 
+            new LinkedList<Map<String,Object>>();
+
+        Printer defaultPrinter = Printer.getDefaultPrinter();
+
+        for (Printer printer : printers) {
+            HashMap<String, Object> printerMap = new HashMap<String, Object>();
+            printerMaps.add(printerMap);
+            printerMap.put("name", printer.getName());
+            if (printer.getName().equals(defaultPrinter.getName())) {
+                printerMap.put("is-default", new Boolean(true));
+            }
+            logger.info("found printer " + printer.getName());            
+        }
+
+        return printerMaps;
+    }
+
+
+    protected Printer getPrinterByName(String name) {
+        Printer[] printers = getPrinters();
+        for (Printer printer : printers) {
+            if (printer.getName().equals(name))
+                return printer;
+        }
+        return null;
+    }
+
+
     private void debugPrintService(PrintService printer) {
 
         PrintService[] printServices;
@@ -78,6 +270,17 @@ public class PrintManager {
         }
     }
 
+    public PrintService getPrintServiceByName(String name) {
+        PrintService[] printServices =
+            PrintServiceLookup.lookupPrintServices(null, null);
+        for (PrintService service : printServices) {
+            if (service.getName().equals(name))
+                return service;
+        }
+        return null;
+    }
+
+    /*
     public List<HashMap> getPrinters() {
 
         List<HashMap> printers = new LinkedList<HashMap>();
@@ -125,5 +328,6 @@ public class PrintManager {
 
         return printers;
     }
+    */
 }