/*
* Copyright 2002-2012 the original author or authors
*
* Licensed 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.springframework.integration.print.outbound;
import java.io.InputStream;
import java.util.Locale;
import javax.print.Doc;
import javax.print.DocFlavor;
import javax.print.DocPrintJob;
import javax.print.SimpleDoc;
import javax.print.attribute.DocAttributeSet;
import javax.print.attribute.HashDocAttributeSet;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.Chromaticity;
import javax.print.attribute.standard.Copies;
import javax.print.attribute.standard.JobName;
import javax.print.attribute.standard.MediaSizeName;
import javax.print.attribute.standard.MediaTray;
import javax.print.attribute.standard.Sides;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.integration.Message;
import org.springframework.integration.handler.AbstractMessageHandler;
import org.springframework.integration.print.core.PrintServiceExecutor;
import org.springframework.integration.print.support.PrintJobMonitor;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* Outbound Adapter that supports printing of payloads.
*
* @author Gunnar Hillert
* @since 1.0
*/
public class PrintMessageHandler extends AbstractMessageHandler {
private static final Log LOG = LogFactory.getLog(PrintMessageHandler.class);
private final PrintServiceExecutor printServiceExecutor;
private volatile String printJobName;
private volatile MediaSizeName mediaSizeName;
private volatile Sides sides;
private volatile Copies copies;
private volatile MediaTray mediaTray;
private volatile Chromaticity chromaticity;
private final DocFlavor docFlavor;
private volatile PrintRequestAttributeSet printRequestAttributeSet = new HashPrintRequestAttributeSet();
public PrintMessageHandler(PrintServiceExecutor printServiceExecutor, DocFlavor docFlavor) {
Assert.notNull(docFlavor, "'docFlavor' must not be null.");
this.docFlavor = docFlavor;
this.printServiceExecutor = printServiceExecutor;
}
public PrintMessageHandler(PrintServiceExecutor printServiceExecutor, String mimeType, String className) {
Assert.hasText(className, "'className' must be neither null nor empty.");
Assert.hasText(mimeType, "'mimeType' must be neither null nor empty.");
this.docFlavor = new DocFlavor(mimeType, className);
this.printServiceExecutor = printServiceExecutor;
}
public PrintMessageHandler(PrintServiceExecutor printServiceExecutor) {
this.docFlavor = DocFlavor.STRING.TEXT_PLAIN;
this.printServiceExecutor = printServiceExecutor;
}
@Override
protected void handleMessageInternal(Message<?> message) throws Exception {
if (LOG.isDebugEnabled()) {
LOG.debug("Printing using printer '" + this.printServiceExecutor.getPrintService().getName() + "'.");
}
DocAttributeSet das = new HashDocAttributeSet();
das.add(Chromaticity.MONOCHROME);
Object payload = message.getPayload();
final Doc doc = new SimpleDoc(message.getPayload(), docFlavor, das);
final DocPrintJob job = this.printServiceExecutor.getPrintService().createPrintJob();
PrintJobMonitor printJobMonitor = new PrintJobMonitor(job);
job.print(doc, this.printRequestAttributeSet);
printJobMonitor.waitForDone();
if (payload instanceof InputStream) {
((InputStream) payload).close();
}
}
@Override
protected void onInit() throws Exception {
if (this.copies != null) {
//Assert.isTrue(printService.isAttributeValueSupported(this.copies, this.docFlavor, this.printService.getAttributes()),
// "Attribute '" + this.copies.getName() + "' with value '" + this.copies.getValue() + "' is not supported.");
this.printRequestAttributeSet.add(this.copies);
}
if (this.chromaticity != null) {
Assert.isTrue(this.printServiceExecutor.getPrintService().isAttributeValueSupported(this.chromaticity, this.docFlavor, this.printServiceExecutor.getPrintService().getAttributes()),
"Attribute '" + this.chromaticity.getName() + "' with value '" + this.chromaticity.getValue() + "' is not supported.");
this.printRequestAttributeSet.add(this.chromaticity);
}
if (this.mediaSizeName != null) {
Assert.isTrue(this.printServiceExecutor.getPrintService().isAttributeValueSupported(this.mediaSizeName, null, null),
"Attribute '" + this.mediaSizeName.getName()
+ "' with value '" + this.mediaSizeName.getValue() + "' is not supported.");
this.printRequestAttributeSet.add(this.mediaSizeName);
}
if (this.mediaTray != null) {
Assert.isTrue(this.printServiceExecutor.getPrintService().isAttributeValueSupported(this.mediaTray, this.docFlavor, this.printServiceExecutor.getPrintService().getAttributes()),
"Attribute value '" + this.mediaTray + "' is not supported.");
this.printRequestAttributeSet.add(this.mediaTray);
}
if (this.sides!=null) {
Assert.isTrue(this.printServiceExecutor.getPrintService().isAttributeValueSupported(this.sides, this.docFlavor, this.printServiceExecutor.getPrintService().getAttributes()),
"Attribute value '" + this.sides + "' is not supported.");
this.printRequestAttributeSet.add(this.sides);
}
if (StringUtils.hasText(this.printJobName)) {
this.printRequestAttributeSet.add(new JobName(this.printJobName, Locale.getDefault()));
}
super.onInit();
}
/**
* Specifies how the pages are are printed to the selected medium,
* e.g. duplex or one-sided. Under the covers, this property will add the
* provided {@link Sides} instance to the respective {@link PrintRequestAttributeSet}.
*
* This property is not used, if not specified (No explicit default value).
*
* @param sides Must not be null
*/
public void setSides(Sides sides) {
Assert.notNull(sides, "'sides' must not be null.");
this.sides = sides;
}
/**
* Let's you specify an integer value that indicates how many time each
* print page shall be printed. Under the covers, this property will add a
*
* {@link Copies} instance to the respective {@link PrintRequestAttributeSet}.
* This property is not used, if not specified (No explicit default value).
*
* @param numberOfCopies Must be greater than 0
*/
public void setCopies(int numberOfCopies) {
Assert.isTrue(numberOfCopies > 0, "'copies' must be greater than 0.");
this.copies = new Copies(numberOfCopies);
}
/**
* Specifies the media tray/bin for the print job. This property can be used
* instead of providing the {@link #mediaSizeName} property. Under the covers,
* this property will add the provided {@link MediaTray} instance to the
* respective {@link PrintRequestAttributeSet}. This property is not used,
* if not specified (No explicit default value).
*
* @param mediaTray Must not be null
*/
public void setMediaTray(MediaTray mediaTray) {
Assert.notNull(mediaTray, "'mediaTray' must not be null.");
this.mediaTray = mediaTray;
}
/**
* Specifies whether you want to do monochrome or color printing. Under the
* covers, this property will add the provided {@link Chromaticity} instance
* to the respective {@link PrintRequestAttributeSet}. This property is not
* used, if not specified (No explicit default value).
*
* @param chromaticity Must not be null.
*/
public void setChromaticity(Chromaticity chromaticity) {
Assert.notNull(chromaticity, "'chromaticity' must not be null.");
this.chromaticity = chromaticity;
}
/**
* Sets the {@link MediaSizeName}. Under the covers, this property will add
* the provided {@link MediaSizeName} to the respective {@link PrintRequestAttributeSet}.
* This property is not used, if not specified (No explicit default value).
*
* @param mediaSizeName Must not be null.
*/
public void setMediaSizeName(MediaSizeName mediaSizeName) {
Assert.notNull(mediaSizeName, "'mediaSizeName' must not be null.");
this.mediaSizeName = mediaSizeName;
}
/**
* Optional property that let's you specify the name of the print job as it
* is added to the print queue. Under the covers, this property will create
* a {@link JobName} instance and add it to the respective {@link PrintRequestAttributeSet}.
* This property is not used, if not specified (No explicit default value).
*
* @param printJobName Must neither be null nor empty.
*/
public void setPrintJobName(String printJobName) {
Assert.hasText(printJobName, "'mediaSizeName' must neither be null nor empty.");
this.printJobName = printJobName;
}
}