Skip to content
Snippets Groups Projects
Commit 03da4ee9 authored by Leonard Kupper's avatar Leonard Kupper
Browse files

Update from master.

parents 60cb6153 ac4c3c49
No related branches found
No related tags found
1 merge request!39App restructuring
......@@ -15,6 +15,7 @@ import de.tudresden.inf.mci.brailleplot.layout.RasterCanvas;
import de.tudresden.inf.mci.brailleplot.layout.Rectangle;
import de.tudresden.inf.mci.brailleplot.point.Point2DValued;
import de.tudresden.inf.mci.brailleplot.printabledata.FloatingPointData;
import de.tudresden.inf.mci.brailleplot.printabledata.PrintableData;
import de.tudresden.inf.mci.brailleplot.printerbackend.PrintDirector;
import de.tudresden.inf.mci.brailleplot.printerbackend.PrinterCapability;
......@@ -48,6 +49,7 @@ import javax.measure.Quantity;
import javax.measure.quantity.Length;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
......@@ -285,6 +287,8 @@ public final class App {
String printerConfigUpperCase = printer.getProperty("mode").toString().toUpperCase();
PrintDirector printD = new PrintDirector(PrinterCapability.valueOf(printerConfigUpperCase), printer);
printD.print(mat);
FileOutputStream textDumpOutput = new FileOutputStream("dump.txt");
textDumpOutput.write(printD.byteDump(mat));
} catch (final Exception e) {
terminateWithException(e);
......
package de.tudresden.inf.mci.brailleplot.printerbackend;
import de.tudresden.inf.mci.brailleplot.brailleparser.AbstractBrailleTableParser;
import de.tudresden.inf.mci.brailleplot.printabledata.MatrixData;
import de.tudresden.inf.mci.brailleplot.printabledata.PrintableData;
/**
* This class provides an extension point for further implementation
* and protocol building for documents that need to be send to the printer.
* The common Interface is the getDocument() and assemble() method.
* Its usable for all braille printers.
* @param <T> Type of MatrixData.
* @param <T> Type of Data.
* @author Andrey Ruzhanskiy
* @version 28.05.2019
*/
abstract class AbstractDocumentBuilder<T> {
abstract class AbstractDocumentBuilder<T extends PrintableData> {
MatrixData<T> mData;
T mData;
AbstractBrailleTableParser mParser;
......@@ -24,6 +25,6 @@ abstract class AbstractDocumentBuilder<T> {
* @param data Raw data to be printed without any escapes equences
* @return Fully build document as byte[]
*/
abstract byte[] assemble(MatrixData<T> data);
abstract byte[] assemble(T data);
}
package de.tudresden.inf.mci.brailleplot.printerbackend;
import de.tudresden.inf.mci.brailleplot.printabledata.PrintableData;
/**
* Abstract class for Documents, that need special escape sequences for the Index Everest-V4.
* All special documents (i.e. Floating Dot Area) should implement this class. All information taken
* from the Index PrinterCapability Interface Protocol V5_V4 2ß16-05-13. All the variables with the respective values have no
* particular order (except mStartTemporaryDoc, which must be at the beginning). All the variable names are set to
* final, these are PrinterCapability specific values that should not be changed.
* @param <T> Type of Data, must extend PrintableData.
* @author Andrey Ruzhanskiy
* @version 31.05.2019
*/
@SuppressWarnings("checkstyle:MagicNumber")
abstract class AbstractIndexV4Builder extends AbstractDocumentBuilder {
abstract class AbstractIndexV4Builder<T extends PrintableData> extends AbstractDocumentBuilder<T> {
......@@ -22,6 +25,10 @@ abstract class AbstractIndexV4Builder extends AbstractDocumentBuilder {
final byte[] mStartTemporaryDoc = new byte[] {0x1B, 0x44};
final byte[] mStartFloatingMode = new byte[] {0x1B, 0x46};
final byte[] mNewLine = new byte[] {0x0A};
/**
* Standard variable name for binding margin (BI).
*/
......
package de.tudresden.inf.mci.brailleplot.printerbackend;
import de.tudresden.inf.mci.brailleplot.printabledata.MatrixData;
import de.tudresden.inf.mci.brailleplot.point.Point2DValued;
import de.tudresden.inf.mci.brailleplot.printabledata.SimpleFloatingPointDataImpl;
import tec.units.ri.unit.MetricPrefix;
import javax.measure.Quantity;
import javax.measure.quantity.Length;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Iterator;
import java.util.Locale;
import java.util.Objects;
import static tec.units.ri.unit.Units.METRE;
/**
* Class representing the FloatingDotAre protocol for the braille Index Everest V4 for printing
* Class representing the FloatingDotArea protocol for the braille Index Everest V4 for printing
* variable areas on paper via coordinates.
* @author Andrey Ruzhanskiy, Leonard Kupper
* @version 29.05.2019
*/
class FloatingDotAreaBuilder extends AbstractIndexV4Builder {
class FloatingDotAreaBuilder extends AbstractIndexV4Builder<SimpleFloatingPointDataImpl<Boolean>> {
/**
* Constructor. Does not have any functionality. Should only be used in {@link PrintDirector}
......@@ -19,10 +31,38 @@ class FloatingDotAreaBuilder extends AbstractIndexV4Builder {
/**
* Currently not implemented.
* @param data Raw data to be printed without any escape sequences
* @param data Raw data to be printed via the FloatingDotArea
* @return Exception.
*/
byte[] assemble(final MatrixData data) {
throw new UnsupportedOperationException();
@Override
byte[] assemble(final SimpleFloatingPointDataImpl<Boolean> data) {
mData = Objects.requireNonNull(data);
Iterator<Point2DValued<Quantity<Length>, Boolean>> iter = mData.getIterator();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
try {
stream.write(mStartFloatingMode);
stream.write(mSemicolon);
stream.write(mNewLine);
// Start iteration over values
while (iter.hasNext()) {
Point2DValued<Quantity<Length>, Boolean> current = iter.next();
Quantity<Length> x = current.getX().to(MetricPrefix.MILLI(METRE));
Quantity<Length> y = current.getY().to(MetricPrefix.MILLI(METRE));
String xFormated = String.format(Locale.ENGLISH, "%.2f", x.getValue().doubleValue());
String yFormated = String.format(Locale.ENGLISH, "%.2f", x.getValue().doubleValue());
stream.write(xFormated.getBytes());
stream.write(mColon);
stream.write(yFormated.getBytes());
if (iter.hasNext()) {
stream.write(mNewLine);
}
}
// End with ;
stream.write(mSemicolon);
} catch (IOException e) {
e.printStackTrace();
}
return stream.toByteArray();
//return null;
}
}
......@@ -7,7 +7,7 @@ import de.tudresden.inf.mci.brailleplot.printabledata.MatrixData;
* Class representing the graphic mode protocol from braille Index Everest D4.
* @author Andrey Ruzhanskiy
*/
class GraphicPrintBuilder extends AbstractIndexV4Builder {
class GraphicPrintBuilder extends AbstractIndexV4Builder<MatrixData> {
/**
* Constructor. Does not have any functionality. Should only be used in {@link PrintDirector}
......
......@@ -16,7 +16,7 @@ import java.util.Objects;
* @version 12.07.2019
*/
@SuppressWarnings("checkstyle:MagicNumber")
class NormalBuilder extends AbstractDocumentBuilder<Boolean> {
class NormalBuilder extends AbstractDocumentBuilder<MatrixData<Boolean>> {
/**
......
......@@ -2,19 +2,23 @@ package de.tudresden.inf.mci.brailleplot.printerbackend;
import de.tudresden.inf.mci.brailleplot.configparser.Printer;
import de.tudresden.inf.mci.brailleplot.printabledata.MatrixData;
import de.tudresden.inf.mci.brailleplot.printabledata.PrintableData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.print.Doc;
import javax.print.DocFlavor;
import javax.print.DocPrintJob;
import javax.print.PrintException;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.Doc;
import javax.print.SimpleDoc;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.JobName;
import javax.print.attribute.standard.PrinterState;
import javax.print.event.PrintJobEvent;
import java.util.Objects;
/**
* Implements a variation of the GoF design pattern Builder. This class is used for setting the printer configuration and
......@@ -29,6 +33,7 @@ public class PrintDirector {
private PrintService mService;
private String mPrinterName;
private DocFlavor mDocflavor;
private final Logger mLogger = LoggerFactory.getLogger(PrintDirector.class);
private DocPrintJob mPrintJob;
......@@ -44,14 +49,20 @@ public class PrintDirector {
Objects.requireNonNull(printerConfig);
this.mPrinter = printerCap;
mPrinterName = printerConfig.getProperty("name").toString();
mLogger.trace("Using following printercapability {}", printerCap.toString(), " loaded");
mLogger.info("Using the following printer: {}", mPrinterName);
switch (mPrinter) {
case NORMALPRINTER:
mBuilder = new NormalBuilder(); break;
mBuilder = new NormalBuilder();
mLogger.trace("Using NormalBuilder as protocol");
break;
case INDEX_EVEREST_D_V4_GRAPHIC_PRINTER:
mBuilder = new GraphicPrintBuilder();
mLogger.trace("Using Index Everest-D V4 graphic print as protocol");
break;
case INDEX_EVEREST_D_V4_FLOATINGDOT_PRINTER:
mBuilder = new FloatingDotAreaBuilder();
mLogger.trace("Using Index Everest-D V4 floatingdot as protocol");
break;
default: throw new IllegalArgumentException();
}
......@@ -61,26 +72,48 @@ public class PrintDirector {
/**
* Public method for printing the given document with the given data.
* @param data {@link de.tudresden.inf.mci.brailleplot.printabledata.MatrixData} to be printed.
* @param <T> The type of {@link MatrixData}.
*/
// Needed if someone tries to use a normal builder with something that is not a boolean.
@SuppressWarnings("unchecked")
public <T> void print(final MatrixData<T> data) {
public void print(final PrintableData data) {
mLogger.info("Starting with print process");
Objects.requireNonNull(data);
mLogger.info("Setting up docflavour and service");
setUpDoc();
setUpService();
byte[] result;
mLogger.info("Finished setting up doc and service");
try {
mLogger.trace("Assembling the data according to protocol: {}", mBuilder.getClass().getCanonicalName());
result = mBuilder.assemble(data);
} catch (ClassCastException e) {
throw new IllegalArgumentException(e.getMessage(), e);
}
mLogger.info("Finished assembling data");
print(result);
}
/**
* Method for creating the byte array form the printing process.
* @param data Data to be later dumped.
* @return Byte array containing the sequence for the printer.
*/
@SuppressWarnings("unchecked")
public byte[] byteDump(final PrintableData data) {
mLogger.info("Starting with textdump process");
byte[] result;
try {
mLogger.trace("Assembling the data according to protocol: {}", mBuilder.getClass().getCanonicalName());
result = mBuilder.assemble(data);
} catch (ClassCastException e) {
throw new IllegalArgumentException(e.getMessage(), e);
}
mLogger.info("Finished with creating textdump");
return result;
}
/**
* Method for setting up the DocFlavor for printing. Currently, not parameterised because the printer can
* (hopefully) understand raw bytes with an octet stream.
......@@ -117,12 +150,24 @@ public class PrintDirector {
Objects.requireNonNull(data);
Objects.requireNonNull(mService);
Objects.requireNonNull(mDocflavor);
mLogger.info("Setting up doc, asset and job");
Doc doc = new SimpleDoc(data, mDocflavor, null);
PrintRequestAttributeSet asset = new HashPrintRequestAttributeSet();
DocPrintJob job = mService.createPrintJob();
mLogger.trace("Finished setting up doc, asset and job");
PrinterState state;
asset.add(new JobName("Braille Printing", null));
try {
mLogger.trace("Adding job to the PrintJobListener");
PrintJobListener listener = new PrintJobListener();
job.addPrintJobListener(listener);
mLogger.trace("Starting printing");
//PrinterIsAcceptingJobs set = mService.getAttribute(PrinterIsAcceptingJobs.class);
//PrinterStateReasons reasons = mService.getAttribute(PrinterStateReasons.class);
job.print(doc, asset);
//set = mService.getAttribute(PrinterIsAcceptingJobs.class);
//reasons = mService.getAttribute(PrinterStateReasons.class);
listener.waitForDone();
mPrintJob = job;
} catch (PrintException pe) {
throw new RuntimeException(pe);
......@@ -141,4 +186,69 @@ public class PrintDirector {
}
return true;
}
/**
* Eventlistener which receives updates regarding printing.
* Because of enormous shortcoming in the implementation of printing in java, some events are never received.
*/
private class PrintJobListener implements javax.print.event.PrintJobListener {
boolean done = false;
@Override
public void printDataTransferCompleted(final PrintJobEvent pje) {
mLogger.info("Data transfer to printer complete");
}
@Override
public void printJobCompleted(final PrintJobEvent pje) {
mLogger.info("Printjob completed");
synchronized (PrintJobListener.this) {
done = true;
PrintJobListener.this.notify();
}
}
@Override
public void printJobFailed(final PrintJobEvent pje) {
mLogger.info("Printjob failed");
synchronized (PrintJobListener.this) {
done = true;
PrintJobListener.this.notify();
}
}
@Override
public void printJobCanceled(final PrintJobEvent pje) {
mLogger.info("Printjob was canceled");
synchronized (PrintJobListener.this) {
done = true;
PrintJobListener.this.notify();
}
}
@Override
public void printJobNoMoreEvents(final PrintJobEvent pje) {
mLogger.info("Printjob has no more events");
synchronized (PrintJobListener.this) {
done = true;
}
}
@Override
public void printJobRequiresAttention(final PrintJobEvent pje) {
mLogger.info("Printjob requires attention");
PrintJobListener.this.notify();
}
public synchronized void waitForDone() {
try {
// Not busy waiting, sleeping as long as not notified.
while (!done) {
wait();
}
} catch (InterruptedException e) {
return;
}
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment