/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.camel.component.printer;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Map;
import javax.print.Doc;
import javax.print.DocFlavor;
import javax.print.DocPrintJob;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.attribute.Attribute;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.Media;
import javax.print.attribute.standard.MediaSizeName;
import javax.print.attribute.standard.MediaTray;
import javax.print.attribute.standard.OrientationRequested;
import javax.print.attribute.standard.Sides;
import org.apache.camel.Endpoint;
import org.apache.camel.Exchange;
import org.apache.camel.Message;
import org.apache.camel.Processor;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.test.junit4.CamelTestSupport;
import org.apache.camel.util.IOHelper;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
public class PrinterPrintTest extends CamelTestSupport {
@Before
public void setup() {
setupJavaPrint();
}
@Override
public boolean isUseRouteBuilder() {
return false;
}
// Check if there is an awt library
private boolean isAwtHeadless() {
return Boolean.getBoolean("java.awt.headless");
}
private void sendFile() throws Exception {
template.send("direct:start", new Processor() {
public void process(Exchange exchange) throws Exception {
// Read from an input stream
InputStream is = IOHelper.buffered(new FileInputStream("src/test/resources/test.txt"));
byte buffer[] = new byte[is.available()];
int n = is.available();
for (int i = 0; i < n; i++) {
buffer[i] = (byte) is.read();
}
is.close();
// Set the property of the charset encoding
exchange.setProperty(Exchange.CHARSET_NAME, "UTF-8");
Message in = exchange.getIn();
in.setBody(buffer);
}
});
}
private void sendGIF() throws Exception {
template.send("direct:start", new Processor() {
public void process(Exchange exchange) throws Exception {
// Read from an input stream
InputStream is = IOHelper.buffered(new FileInputStream("src/test/resources/asf-logo.gif"));
byte buffer[] = new byte[is.available()];
int n = is.available();
for (int i = 0; i < n; i++) {
buffer[i] = (byte) is.read();
}
is.close();
// Set the property of the charset encoding
exchange.setProperty(Exchange.CHARSET_NAME, "UTF-8");
Message in = exchange.getIn();
in.setBody(buffer);
}
});
}
private void sendJPEG() throws Exception {
template.send("direct:start", new Processor() {
public void process(Exchange exchange) throws Exception {
// Read from an input stream
InputStream is = IOHelper.buffered(new FileInputStream("src/test/resources/asf-logo.JPG"));
byte buffer[] = new byte[is.available()];
int n = is.available();
for (int i = 0; i < n; i++) {
buffer[i] = (byte) is.read();
}
is.close();
// Set the property of the charset encoding
exchange.setProperty(Exchange.CHARSET_NAME, "UTF-8");
Message in = exchange.getIn();
in.setBody(buffer);
}
});
}
@Test
@Ignore
public void testSendingFileToPrinter() throws Exception {
if (isAwtHeadless()) {
return;
}
context.addRoutes(new RouteBuilder() {
public void configure() {
from("direct:start").
to("lpr://localhost/default?copies=1&flavor=DocFlavor.BYTE_ARRAY&mimeType=AUTOSENSE&mediaSize=na-letter&sides=one-sided&sendToPrinter=false");
}
});
context.start();
sendFile();
}
@Test
@Ignore
public void testSendingGIFToPrinter() throws Exception {
if (isAwtHeadless()) {
return;
}
context.addRoutes(new RouteBuilder() {
public void configure() {
from("direct:start").
to("lpr://localhost/default?flavor=DocFlavor.INPUT_STREAM&mimeType=GIF&mediaSize=na-letter&sides=one-sided&sendToPrinter=false");
}
});
context.start();
sendGIF();
}
@Test
@Ignore
public void testSendingJPEGToPrinter() throws Exception {
if (isAwtHeadless()) {
return;
}
context.addRoutes(new RouteBuilder() {
public void configure() {
from("direct:start").to("lpr://localhost/default?copies=2&flavor=DocFlavor.INPUT_STREAM"
+ "&mimeType=JPEG&mediaSize=na-letter&sides=one-sided&sendToPrinter=false");
}
});
context.start();
sendJPEG();
}
@Test
@Ignore
public void testSendingJPEGToPrinterWithLandscapePageOrientation() throws Exception {
if (isAwtHeadless()) {
return;
}
context.addRoutes(new RouteBuilder() {
public void configure() {
from("direct:start").to("lpr://localhost/default?flavor=DocFlavor.INPUT_STREAM"
+ "&mimeType=JPEG&sendToPrinter=false&orientation=landscape");
}
});
context.start();
sendJPEG();
}
/**
* Test for resolution of bug CAMEL-3446.
* Not specifying mediaSize nor sides attributes make it use
* default values when starting the route.
*/
@Test
@Ignore
public void testDefaultPrinterConfiguration() throws Exception {
if (isAwtHeadless()) {
return;
}
context.addRoutes(new RouteBuilder() {
public void configure() {
from("direct:start").to("lpr://localhost/default?sendToPrinter=false");
}
});
context.start();
}
@Test
public void moreThanOneLprEndpoint() throws Exception {
if (isAwtHeadless()) {
return;
}
int numberOfPrintservicesBefore = PrintServiceLookup.lookupPrintServices(null, null).length;
// setup javax.print
PrintService ps1 = mock(PrintService.class);
when(ps1.getName()).thenReturn("printer1");
when(ps1.isDocFlavorSupported(any(DocFlavor.class))).thenReturn(Boolean.TRUE);
PrintService ps2 = mock(PrintService.class);
when(ps2.getName()).thenReturn("printer2");
boolean res1 = PrintServiceLookup.registerService(ps1);
assertTrue("PrintService #1 should be registered.", res1);
boolean res2 = PrintServiceLookup.registerService(ps2);
assertTrue("PrintService #2 should be registered.", res2);
PrintService[] pss = PrintServiceLookup.lookupPrintServices(null, null);
assertEquals("lookup should report two PrintServices.", numberOfPrintservicesBefore + 2, pss.length);
DocPrintJob job1 = mock(DocPrintJob.class);
when(ps1.createPrintJob()).thenReturn(job1);
context.addRoutes(new RouteBuilder() {
public void configure() {
from("direct:start1").to("lpr://localhost/printer1?sendToPrinter=true");
from("direct:start2").to("lpr://localhost/printer2?sendToPrinter=false");
}
});
context.start();
// Are there two different PrintConfigurations?
Map<String, Endpoint> epm = context().getEndpointMap();
assertEquals("Four endpoints", 4, epm.size());
Endpoint lp1 = null;
Endpoint lp2 = null;
for (Map.Entry<String, Endpoint> ep : epm.entrySet()) {
if (ep.getKey().contains("printer1")) {
lp1 = ep.getValue();
}
if (ep.getKey().contains("printer2")) {
lp2 = ep.getValue();
}
}
assertNotNull(lp1);
assertNotNull(lp2);
assertEquals("printer1", ((PrinterEndpoint) lp1).getConfig().getPrintername());
assertEquals("printer2", ((PrinterEndpoint) lp2).getConfig().getPrintername());
template.sendBody("direct:start1", "Hello Printer 1");
context.stop();
verify(job1, times(1)).print(any(Doc.class), any(PrintRequestAttributeSet.class));
}
@Test
public void printerNameTest() throws Exception {
if (isAwtHeadless()) {
return;
}
// setup javax.print
PrintService ps1 = mock(PrintService.class);
when(ps1.getName()).thenReturn("MyPrinter\\\\remote\\printer1");
when(ps1.isDocFlavorSupported(any(DocFlavor.class))).thenReturn(Boolean.TRUE);
boolean res1 = PrintServiceLookup.registerService(ps1);
assertTrue("The Remote PrintService #1 should be registered.", res1);
DocPrintJob job1 = mock(DocPrintJob.class);
when(ps1.createPrintJob()).thenReturn(job1);
context.addRoutes(new RouteBuilder() {
public void configure() {
from("direct:start1").to("lpr://remote/printer1?sendToPrinter=true");
}
});
context.start();
template.sendBody("direct:start1", "Hello Printer 1");
context.stop();
verify(job1, times(1)).print(any(Doc.class), any(PrintRequestAttributeSet.class));
}
@Test
public void setJobName() throws Exception {
if (isAwtHeadless()) {
return;
}
getMockEndpoint("mock:output").setExpectedMessageCount(1);
context.addRoutes(new RouteBuilder() {
public void configure() {
from("direct:start").to("lpr://localhost/default").to("mock:output");
}
});
context.start();
template.sendBodyAndHeader("direct:start", "Hello Printer", PrinterEndpoint.JOB_NAME, "Test-Job-Name");
context.stop();
assertMockEndpointsSatisfied();
}
@Test
public void printToMiddleTray() throws Exception {
PrinterEndpoint endpoint = new PrinterEndpoint();
PrinterConfiguration configuration = new PrinterConfiguration();
configuration.setHostname("localhost");
configuration.setPort(631);
configuration.setPrintername("DefaultPrinter");
configuration.setMediaSizeName(MediaSizeName.ISO_A4);
configuration.setInternalSides(Sides.ONE_SIDED);
configuration.setInternalOrientation(OrientationRequested.PORTRAIT);
configuration.setMediaTray("middle");
PrinterProducer producer = new PrinterProducer(endpoint, configuration);
producer.start();
PrinterOperations printerOperations = producer.getPrinterOperations();
PrintRequestAttributeSet attributeSet = printerOperations.getPrintRequestAttributeSet();
Attribute attribute = attributeSet.get(javax.print.attribute.standard.Media.class);
assertNotNull(attribute);
assertTrue(attribute instanceof MediaTray);
MediaTray mediaTray = (MediaTray) attribute;
assertEquals("middle", mediaTray.toString());
}
@Test
public void printsWithLandscapeOrientation() throws Exception {
PrinterEndpoint endpoint = new PrinterEndpoint();
PrinterConfiguration configuration = new PrinterConfiguration();
configuration.setHostname("localhost");
configuration.setPort(631);
configuration.setPrintername("DefaultPrinter");
configuration.setMediaSizeName(MediaSizeName.ISO_A4);
configuration.setInternalSides(Sides.ONE_SIDED);
configuration.setInternalOrientation(OrientationRequested.REVERSE_LANDSCAPE);
configuration.setMediaTray("middle");
configuration.setSendToPrinter(false);
PrinterProducer producer = new PrinterProducer(endpoint, configuration);
producer.start();
PrinterOperations printerOperations = producer.getPrinterOperations();
PrintRequestAttributeSet attributeSet = printerOperations.getPrintRequestAttributeSet();
Attribute attribute = attributeSet.get(OrientationRequested.class);
assertNotNull(attribute);
assertEquals("reverse-landscape", attribute.toString());
}
protected void setupJavaPrint() {
// "install" another default printer
PrintService psDefault = mock(PrintService.class);
when(psDefault.getName()).thenReturn("DefaultPrinter");
when(psDefault.isDocFlavorSupported(any(DocFlavor.class))).thenReturn(Boolean.TRUE);
PrintServiceLookup psLookup = mock(PrintServiceLookup.class);
when(psLookup.getPrintServices()).thenReturn(new PrintService[]{psDefault});
when(psLookup.getDefaultPrintService()).thenReturn(psDefault);
DocPrintJob docPrintJob = mock(DocPrintJob.class);
when(psDefault.createPrintJob()).thenReturn(docPrintJob);
MediaTray[] trays = new MediaTray[]{
MediaTray.TOP,
MediaTray.MIDDLE,
MediaTray.BOTTOM
};
when(psDefault.getSupportedAttributeValues(Media.class, null, null)).thenReturn(trays);
PrintServiceLookup.registerServiceProvider(psLookup);
}
}