From 3ea135bb6f2d874cae958af400076d5faf9d7e26 Mon Sep 17 00:00:00 2001 From: mvirak Date: Tue, 23 Sep 2008 15:42:56 +0000 Subject: [PATCH] Initial import. git-svn-id: http://jspi.googlecode.com/svn/trunk@3 b34d1714-897f-11dd-9205-735403a6da14 --- .../com/google/code/jspi/AttributeParser.java | 398 +++++++++++++ .../google/code/jspi/IppResponseIppImpl.java | 151 +++++ .../java/com/google/code/jspi/IppServlet.java | 104 ++++ .../de/lohndirekt/print/CancelableJob.java | 73 +++ .../de/lohndirekt/print/IppConnection.java | 50 ++ .../lohndirekt/print/IppHttpConnection.java | 135 +++++ .../print/IppMultiDocPrintService.java | 48 ++ .../de/lohndirekt/print/IppPrintService.java | 536 ++++++++++++++++++ .../print/IppPrintServiceLookup.java | 199 +++++++ .../print/IppPrintServiceLookupTest.java | 68 +++ .../lohndirekt/print/IppPrintServiceTest.java | 120 ++++ .../java/de/lohndirekt/print/IppRequest.java | 39 ++ .../lohndirekt/print/IppRequestCupsImpl.java | 398 +++++++++++++ .../lohndirekt/print/IppRequestFactory.java | 73 +++ .../java/de/lohndirekt/print/IppResponse.java | 38 ++ .../java/de/lohndirekt/print/IppServer.java | 94 +++ .../main/java/de/lohndirekt/print/Job.java | 305 ++++++++++ .../de/lohndirekt/print/MediaMultiDoc.java | 51 ++ .../de/lohndirekt/print/MediaMultiDocJob.java | 33 ++ .../java/de/lohndirekt/print/Messages.java | 52 ++ .../de/lohndirekt/print/MultiDocEvent.java | 38 ++ .../java/de/lohndirekt/print/MultiDocJob.java | 177 ++++++ .../de/lohndirekt/print/MultiDocListener.java | 35 ++ .../de/lohndirekt/print/SimpleMultiDoc.java | 135 +++++ .../de/lohndirekt/print/TestJarLookup.java | 46 ++ .../print/attribute/AttributeHelper.java | 168 ++++++ .../print/attribute/AttributeParser.java | 488 ++++++++++++++++ .../print/attribute/AttributeWriter.java | 290 ++++++++++ .../print/attribute/AttributeWriterTest.java | 203 +++++++ .../print/attribute/DefaultAttribute.java | 26 + .../print/attribute/IppAttributeName.java | 531 +++++++++++++++++ .../print/attribute/IppAttributeNameTest.java | 60 ++ .../print/attribute/IppDelimiterTag.java | 52 ++ .../lohndirekt/print/attribute/IppStatus.java | 147 +++++ .../print/attribute/IppValueTag.java | 74 +++ .../auth/RequestingUserPassword.java | 56 ++ .../print/attribute/cups/DeviceClass.java | 65 +++ .../print/attribute/cups/DeviceUri.java | 56 ++ .../print/attribute/cups/JobKLimit.java | 59 ++ .../print/attribute/cups/JobPageLimit.java | 58 ++ .../print/attribute/cups/JobQuotaPeriod.java | 63 ++ .../print/attribute/cups/MemberNames.java | 61 ++ .../print/attribute/cups/MemberUris.java | 56 ++ .../print/attribute/cups/PrinterType.java | 141 +++++ .../print/attribute/ipp/Charset.java | 60 ++ .../attribute/ipp/DetailedStatusMessage.java | 56 ++ .../print/attribute/ipp/DocumentFormat.java | 55 ++ .../print/attribute/ipp/LastDocument.java | 78 +++ .../print/attribute/ipp/NaturalLanguage.java | 61 ++ .../attribute/ipp/RequestedAttributes.java | 55 ++ .../print/attribute/ipp/StatusMessage.java | 56 ++ .../print/attribute/ipp/UnknownAttribute.java | 59 ++ .../print/attribute/ipp/jobdesc/JobId.java | 53 ++ .../attribute/ipp/jobdesc/JobMoreInfo.java | 56 ++ .../ipp/jobdesc/JobOriginatingHostName.java | 55 ++ .../ipp/jobdesc/JobPrinterUpTime.java | 53 ++ .../attribute/ipp/jobdesc/JobPrinterUri.java | 56 ++ .../print/attribute/ipp/jobdesc/JobUri.java | 55 ++ .../ipp/jobdesc/LdJobStateReason.java | 41 ++ .../ipp/jobdesc/TimeAtCompleted.java | 54 ++ .../attribute/ipp/jobdesc/TimeAtCreation.java | 53 ++ .../ipp/jobdesc/TimeAtProcessing.java | 58 ++ .../ipp/jobtempl/LdJobHoldUntil.java | 70 +++ .../attribute/ipp/jobtempl/LdMediaTray.java | 45 ++ .../printerdesc/MultipleOperationTimeout.java | 52 ++ .../NaturalLanguageConfigured.java | 53 ++ .../ipp/printerdesc/PrinterCurrentTime.java | 59 ++ .../printerdesc/PrinterDriverInstaller.java | 51 ++ .../ipp/printerdesc/PrinterStateMessage.java | 62 ++ .../ipp/printerdesc/PrinterUpTime.java | 53 ++ .../defaults/CharsetConfigured.java | 56 ++ .../printerdesc/defaults/CopiesDefault.java | 54 ++ .../defaults/DocumentFormatDefault.java | 56 ++ .../defaults/FinishingsDefault.java | 54 ++ .../defaults/JobHoldUntilDefault.java | 56 ++ .../defaults/JobPriorityDefault.java | 54 ++ .../defaults/JobSheetsDefault.java | 61 ++ .../printerdesc/defaults/MediaDefault.java | 61 ++ .../MultipleDocumentHandlingDefault.java | 56 ++ .../printerdesc/defaults/NumberUpDefault.java | 54 ++ .../defaults/OrientationRequestedDefault.java | 54 ++ .../printerdesc/defaults/SidesDefault.java | 56 ++ .../supported/CharsetSupported.java | 55 ++ .../supported/CompressionSupported.java | 56 ++ .../supported/DocumentFormatSupported.java | 55 ++ .../supported/FinishingsSupported.java | 53 ++ .../GeneratedNaturalLanguageSupported.java | 55 ++ .../supported/IppVersionsSupported.java | 59 ++ .../supported/JobHoldUntilSupported.java | 55 ++ .../supported/JobSheetsSupported.java | 60 ++ .../printerdesc/supported/MediaSupported.java | 60 ++ .../MultipleDocumentHandlingSupported.java | 55 ++ .../MultipleDocumentJobsSupported.java | 91 +++ .../supported/OperationsSupported.java | 125 ++++ .../OrientationRequestedSupported.java | 53 ++ .../supported/OutputBinSupported.java | 56 ++ .../supported/PageRangesSupported.java | 90 +++ .../supported/PrinterUriSupported.java | 56 ++ .../printerdesc/supported/SidesSupported.java | 55 ++ .../supported/UriAuthenticationSupported.java | 66 +++ .../supported/UriSecuritySupported.java | 64 +++ .../undocumented/PrinterStateTime.java | 53 ++ .../lohndirekt/print/examples/Messages.java | 52 ++ .../print/examples/MultiDocExample.java | 108 ++++ .../print/examples/SimpleDocExample.java | 165 ++++++ .../print/examples/examples.properties | 7 + .../exception/AuthenticationException.java | 48 ++ .../exception/EndOfAttributesException.java | 26 + .../java/de/lohndirekt/print/test.properties | 3 + .../print/test/IppRequestTestImpl.java | 307 ++++++++++ .../print/test/IppRequestTestImplTest.java | 71 +++ jspi/src/main/webapp/META-INF/MANIFEST.MF | 3 + .../WEB-INF/lib/commons-httpclient-2.0.1.jar | Bin 0 -> 224754 bytes .../webapp/WEB-INF/lib/commons-logging.jar | Bin 0 -> 38015 bytes jspi/src/main/webapp/WEB-INF/lib/junit.jar | Bin 0 -> 121070 bytes jspi/src/main/webapp/WEB-INF/web.xml | 22 + 116 files changed, 10265 insertions(+) create mode 100644 jspi/src/main/java/com/google/code/jspi/AttributeParser.java create mode 100644 jspi/src/main/java/com/google/code/jspi/IppResponseIppImpl.java create mode 100644 jspi/src/main/java/com/google/code/jspi/IppServlet.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/CancelableJob.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/IppConnection.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/IppHttpConnection.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/IppMultiDocPrintService.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/IppPrintService.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/IppPrintServiceLookup.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/IppPrintServiceLookupTest.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/IppPrintServiceTest.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/IppRequest.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/IppRequestCupsImpl.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/IppRequestFactory.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/IppResponse.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/IppServer.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/Job.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/MediaMultiDoc.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/MediaMultiDocJob.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/Messages.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/MultiDocEvent.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/MultiDocJob.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/MultiDocListener.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/SimpleMultiDoc.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/TestJarLookup.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/AttributeHelper.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/AttributeParser.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/AttributeWriter.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/AttributeWriterTest.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/DefaultAttribute.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/IppAttributeName.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/IppAttributeNameTest.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/IppDelimiterTag.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/IppStatus.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/IppValueTag.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/auth/RequestingUserPassword.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/cups/DeviceClass.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/cups/DeviceUri.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/cups/JobKLimit.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/cups/JobPageLimit.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/cups/JobQuotaPeriod.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/cups/MemberNames.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/cups/MemberUris.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/cups/PrinterType.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/ipp/Charset.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/ipp/DetailedStatusMessage.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/ipp/DocumentFormat.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/ipp/LastDocument.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/ipp/NaturalLanguage.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/ipp/RequestedAttributes.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/ipp/StatusMessage.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/ipp/UnknownAttribute.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/ipp/jobdesc/JobId.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/ipp/jobdesc/JobMoreInfo.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/ipp/jobdesc/JobOriginatingHostName.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/ipp/jobdesc/JobPrinterUpTime.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/ipp/jobdesc/JobPrinterUri.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/ipp/jobdesc/JobUri.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/ipp/jobdesc/LdJobStateReason.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/ipp/jobdesc/TimeAtCompleted.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/ipp/jobdesc/TimeAtCreation.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/ipp/jobdesc/TimeAtProcessing.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/ipp/jobtempl/LdJobHoldUntil.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/ipp/jobtempl/LdMediaTray.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/MultipleOperationTimeout.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/NaturalLanguageConfigured.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/PrinterCurrentTime.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/PrinterDriverInstaller.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/PrinterStateMessage.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/PrinterUpTime.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/defaults/CharsetConfigured.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/defaults/CopiesDefault.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/defaults/DocumentFormatDefault.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/defaults/FinishingsDefault.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/defaults/JobHoldUntilDefault.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/defaults/JobPriorityDefault.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/defaults/JobSheetsDefault.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/defaults/MediaDefault.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/defaults/MultipleDocumentHandlingDefault.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/defaults/NumberUpDefault.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/defaults/OrientationRequestedDefault.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/defaults/SidesDefault.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/CharsetSupported.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/CompressionSupported.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/DocumentFormatSupported.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/FinishingsSupported.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/GeneratedNaturalLanguageSupported.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/IppVersionsSupported.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/JobHoldUntilSupported.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/JobSheetsSupported.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/MediaSupported.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/MultipleDocumentHandlingSupported.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/MultipleDocumentJobsSupported.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/OperationsSupported.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/OrientationRequestedSupported.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/OutputBinSupported.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/PageRangesSupported.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/PrinterUriSupported.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/SidesSupported.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/UriAuthenticationSupported.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/UriSecuritySupported.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/attribute/undocumented/PrinterStateTime.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/examples/Messages.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/examples/MultiDocExample.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/examples/SimpleDocExample.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/examples/examples.properties create mode 100644 jspi/src/main/java/de/lohndirekt/print/exception/AuthenticationException.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/exception/EndOfAttributesException.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/test.properties create mode 100644 jspi/src/main/java/de/lohndirekt/print/test/IppRequestTestImpl.java create mode 100644 jspi/src/main/java/de/lohndirekt/print/test/IppRequestTestImplTest.java create mode 100644 jspi/src/main/webapp/META-INF/MANIFEST.MF create mode 100644 jspi/src/main/webapp/WEB-INF/lib/commons-httpclient-2.0.1.jar create mode 100644 jspi/src/main/webapp/WEB-INF/lib/commons-logging.jar create mode 100644 jspi/src/main/webapp/WEB-INF/lib/junit.jar create mode 100644 jspi/src/main/webapp/WEB-INF/web.xml diff --git a/jspi/src/main/java/com/google/code/jspi/AttributeParser.java b/jspi/src/main/java/com/google/code/jspi/AttributeParser.java new file mode 100644 index 0000000..3af6575 --- /dev/null +++ b/jspi/src/main/java/com/google/code/jspi/AttributeParser.java @@ -0,0 +1,398 @@ +package com.google.code.jspi; + + +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.net.URI; +import java.net.URISyntaxException; +import java.text.DateFormat; +import java.text.DecimalFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Locale; +import java.util.Map; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.print.attribute.Attribute; +import javax.print.attribute.EnumSyntax; + +import de.lohndirekt.print.attribute.AttributeWriter; +import de.lohndirekt.print.attribute.IppAttributeName; +import de.lohndirekt.print.attribute.IppDelimiterTag; +import de.lohndirekt.print.attribute.IppValueTag; +import de.lohndirekt.print.attribute.ipp.Charset; +import de.lohndirekt.print.exception.EndOfAttributesException; + +/** + * @author bpusch + * + */ +public final class AttributeParser { + + private final static EndOfAttributesException END_OF_ATTRIBUTES_EXCEPTION = new EndOfAttributesException(); + + private final static Logger log = Logger.getLogger(AttributeParser.class.getName()); + + + + /** + * @param name + * @param values + * @return + */ + private static Attribute getAttribute(String name, Object[] values) { + Attribute attribute = null; + IppAttributeName attrName = IppAttributeName.get(name); + Class attrClass = attrName.getAttributeClass(); + Class superClass = attrClass.getSuperclass(); + if (superClass != null) { + if (superClass.equals(EnumSyntax.class)) { + try { + Field[] fields = attrClass.getDeclaredFields(); + for (int i = 0; i < fields.length; i++) { + Field field = fields[i]; + if (field.getType().equals(attrClass)) { + EnumSyntax attr = (EnumSyntax) field.get(null); + if (values[0] instanceof String) { + if (attr.toString().equals(values[0])) { + attribute = (Attribute) attr; + break; + } + } else { + if (attr.getValue() == ((Integer) values[0]).intValue()) { + attribute = (Attribute) attr; + break; + } + } + } + } + } catch (SecurityException e) { + log.log(Level.SEVERE, e.getMessage(), e); + } catch (IllegalArgumentException e) { + log.log(Level.SEVERE, e.getMessage(), e); + } catch (IllegalAccessException e) { + log.log(Level.SEVERE, e.getMessage(), e); + } + + } else { + Class[] parameters = toClassArray(values); + try { + Constructor constructor = attrClass.getDeclaredConstructor(parameters); + attribute = (Attribute) constructor.newInstance(values); + } catch (SecurityException e) { + log.log(Level.SEVERE, e.getMessage(), e); + } catch (NoSuchMethodException e) { + log.log(Level.SEVERE, e.getMessage(), e); + } catch (IllegalArgumentException e) { + log.log(Level.SEVERE, e.getMessage(), e); + } catch (InstantiationException e) { + log.log(Level.SEVERE, e.getMessage(), e); + } catch (IllegalAccessException e) { + log.log(Level.SEVERE, e.getMessage(), e); + } catch (InvocationTargetException e) { + log.log(Level.SEVERE, e.getMessage(), e); + } + } + } + + return attribute; + } + + /** + * @param byteArray + * @param byteCount + * @param lastAttribute + * @return + */ + private static Attribute parseAttribute(InputStream in, Attribute lastAttribute) + throws IOException, EndOfAttributesException { + + int valueTag; + while ((valueTag = in.read()) < IppValueTag.UNSUPPORTED_VALUE.getValue()) { + if (valueTag == IppDelimiterTag.END_ATTRIBUTES.getValue()) { + throw END_OF_ATTRIBUTES_EXCEPTION; + } + } + + int nameLength = parseInt2(in); + // parse the Attribute-Name + String name; + if (nameLength == 0) { + name = lastAttribute.getName(); + } else { + name = parseString(in, nameLength); + } + + + Object[] values = parseValues(valueTag, in); + + return getAttribute(name, values); + } + + private static String parseString(InputStream in, int nameLength) throws IOException{ + return parseString(in, nameLength, Charset.US_ASCII.getValue()); + } + + private static String parseNameAndTextString(InputStream in, int nameLength) throws IOException{ + return parseString(in, nameLength, AttributeWriter.DEFAULT_CHARSET.getValue()); + } + + /** + * @param in + * @param nameLength + */ + private static String parseString(InputStream in, int nameLength, String charsetName) throws IOException { + byte[] bytes = new byte[nameLength]; + in.read(bytes); + return new String(bytes, charsetName); + + } + + + + + /** + * @param byteArray + * @param valueOffset + * @return + */ + private static Date parseDate(InputStream in) throws IOException { + DecimalFormat twoDigits = new DecimalFormat("00"); + DecimalFormat threeDigits = new DecimalFormat("000"); + DecimalFormat fourDigits = new DecimalFormat("0000"); + //year is encoded in network-byte order + int year = parseInt2(in); + int month = in.read(); + int day = in.read(); + int hour = in.read(); + int minute = in.read(); + int second = in.read(); + int deci = in.read(); + int mili = deci * 100; + char direction = (char) in.read(); + int hoursFromUtc = in.read(); + int minutesFromUtc = in.read(); + + String yearString = fourDigits.format(year); + String monthString = twoDigits.format(month); + String dayString = twoDigits.format(day); + String hourString = twoDigits.format(hour); + String minuteString = twoDigits.format(minute); + String secondString = twoDigits.format(second); + String miliString = threeDigits.format(mili); + String timeZone = direction + twoDigits.format(hoursFromUtc) + twoDigits.format(minutesFromUtc); + String dateString = + yearString + + "-" + + monthString + + "-" + + dayString + + " " + + hourString + + ":" + + minuteString + + ":" + + secondString + + ":" + + miliString + + timeZone; + DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSSZ"); + Date date = null; + try { + date = dateFormat.parse(dateString); + } catch (ParseException e) { + log.log(Level.SEVERE, e.getMessage(), e); + } + return date; + } + + private static int parseInt4(InputStream in) throws IOException { + + //Same parsing as in java.io.DataInput readInt() + int a = in.read(); + int b = in.read(); + int c = in.read(); + int d = in.read(); + int value = (((a & 0xff) << 24) | ((b & 0xff) << 16) | ((c & 0xff) << 8) | (d & 0xff)); + return value; + } + + /** + * @param bytes + * @param offset + * @return + */ + private static int parseInt4(byte[] bytes, int offset) { + + //Same parsing as in java.io.DataInput readInt() + byte a = bytes[offset++]; + byte b = bytes[offset++]; + byte c = bytes[offset++]; + byte d = bytes[offset++]; + int value = (((a & 0xff) << 24) | ((b & 0xff) << 16) | ((c & 0xff) << 8) | (d & 0xff)); + return value; + } + + private static int parseInt2(InputStream in) throws IOException { + + //Same parsing as in java.io.DataInput readInt() + int a = in.read(); + int b = in.read(); + int value = ((a & 0xff) << 8) | ((b & 0xff)); + return value; + } + + /** + * @param bytes + * @return map of attributes (key -> category, value -> Set with attributes) + * + * + */ + public static Map parseRequest(InputStream response) throws IOException { + Map attributes = new HashMap(); + long start = System.currentTimeMillis(); + Attribute lastAttribute = null; + boolean finished = false; + response.read(); + + while (!finished) { + Attribute attribute = null; + try { + attribute = parseAttribute(response, lastAttribute); + if (attribute != null) { + lastAttribute = attribute; + attributes = put(attributes, attribute); + if (log.isLoggable(Level.FINEST)) { + log.finest("parsed attribute(" + attribute.getName() + "): " + attribute.toString()); + } + } else { + if (log.isLoggable(Level.FINEST)) { + + log.finest("Attribute was null"); + } + } + } catch (EndOfAttributesException e) { + + finished = true; + if (log.isLoggable(Level.INFO)) { + log.info("--- Attribute parsing finished ---"); + } + } + } + long end = System.currentTimeMillis(); + if (log.isLoggable(Level.INFO)) { + log.info("Parsing took " + (end - start) + "ms."); + } + return attributes; + } + + + /** + * @param byteArray + * @param valueOffset + * @param valueLength + * @return + */ + private static URI parseUri(InputStream in, int valueLength) throws IOException { + String uriString = parseString(in, valueLength); + URI uri = null; + try { + uri = new URI(uriString); + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } + return uri; + } + + + /** + * @param valueTag + * @param byteArray + * @param valueOffset + * @param valueLength + * @return + */ + private static Object[] parseValues(int valueTag, InputStream in) throws IOException { + int valueLength = parseInt2(in); + Object[] values = null; + if (valueTag == IppValueTag.INTEGER.getValue() || valueTag == IppValueTag.ENUM.getValue()) { + Integer number = new Integer(parseInt4(in)); + values = new Object[] { number }; + } else if ( + valueTag == IppValueTag.STRING.getValue() + || valueTag == IppValueTag.TEXT.getValue() + || valueTag == IppValueTag.NAME.getValue()){ + String word = parseNameAndTextString(in, valueLength); + values = new Object[] { word, Locale.getDefault()}; + } else if ( + valueTag == IppValueTag.CHARSET.getValue() + || valueTag == IppValueTag.LANGUAGE.getValue() + || valueTag == IppValueTag.MIMETYPE.getValue()) { + String word = parseString(in, valueLength); + values = new Object[] { word, Locale.getDefault()}; + } else if (valueTag == IppValueTag.URI.getValue()) { + URI uri = parseUri(in, valueLength); + values = new Object[] { uri }; + } else if (valueTag == IppValueTag.KEYWORD.getValue()) { + String word = parseString(in, valueLength); + values = new Object[] { word, Locale.getDefault()}; + } else if (valueTag == IppValueTag.BOOLEAN.getValue()) { + Integer bool = new Integer(in.read()); + values = new Object[] { bool }; + } else if (valueTag == IppValueTag.RANGE.getValue()) { + Integer lowerBound = new Integer(parseInt4(in)); + Integer upperBound = new Integer(parseInt4(in)); + values = new Object[] { lowerBound, upperBound }; + } else if (valueTag == IppValueTag.DATE.getValue()) { + + Date date = parseDate(in); + values = new Object[] { date }; + } else if (valueTag == IppValueTag.NOVALUE.getValue()) { + values = new Object[] { + }; + } else { + throw new IllegalArgumentException("\"" + Integer.toHexString(valueTag) + "\" is not a valid value-tag"); + } + return values; + } + + + /** + * @param attributes + * @param attribute + */ + private static Map put(Map attributes, Attribute attribute) { + Set values = (Set) attributes.get(attribute.getCategory()); + if (values == null) { + values = new HashSet(); + attributes.put(attribute.getCategory(), values); + } + values.add(attribute); + return attributes; + } + + /** + * @param values + * @return + */ + private static Class[] toClassArray(Object[] values) { + Class[] classes = new Class[values.length]; + for (int i = 0; i < values.length; i++) { + Class clazz = values[i].getClass(); + if (clazz.equals(Integer.class)) { + clazz = int.class; + } + classes[i] = clazz; + } + return classes; + } + +} diff --git a/jspi/src/main/java/com/google/code/jspi/IppResponseIppImpl.java b/jspi/src/main/java/com/google/code/jspi/IppResponseIppImpl.java new file mode 100644 index 0000000..5c489ff --- /dev/null +++ b/jspi/src/main/java/com/google/code/jspi/IppResponseIppImpl.java @@ -0,0 +1,151 @@ +package com.google.code.jspi; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; +import java.util.logging.Logger; + +import javax.print.attribute.Attribute; +import javax.print.attribute.AttributeSet; +import javax.print.attribute.HashAttributeSet; +import javax.print.attribute.HashPrintJobAttributeSet; +import javax.print.attribute.PrintJobAttributeSet; + +import de.lohndirekt.print.attribute.AttributeHelper; +import de.lohndirekt.print.attribute.AttributeWriter; +import de.lohndirekt.print.attribute.IppDelimiterTag; +import de.lohndirekt.print.attribute.IppStatus; +import de.lohndirekt.print.attribute.ipp.Charset; +import de.lohndirekt.print.attribute.ipp.NaturalLanguage; + +public class IppResponseIppImpl { + private final Logger log = Logger.getLogger(this.getClass().getName()); + + private final IppStatus status; + + // Id wird in der Cups-API zwar Uebergeben, ist aber auch immer 1. + private final int id = 1; + + private final PrintJobAttributeSet jobAttributes = new HashPrintJobAttributeSet(); + + private final AttributeSet operationAttributes = new HashAttributeSet(); + + private final AttributeSet printerAttributes = new HashAttributeSet(); + + private static final NaturalLanguage NATURAL_LANGUAGE_DEFAULT = NaturalLanguage.EN; + + private static final Charset CHARSET_DEFAULT = Charset.UTF_8; + + public IppResponseIppImpl(IppStatus status) { + super(); + this.status = status; + operationAttributes.add(CHARSET_DEFAULT); + operationAttributes.add(NATURAL_LANGUAGE_DEFAULT); + } + + /** + * @return + */ + public IppStatus getStatus() { + return status; + } + + private byte[] ippFooter() { + byte[] footer = new byte[1]; + footer[0] = (byte) IppDelimiterTag.END_ATTRIBUTES.getValue(); + return footer; + } + + private byte[] ippHeader() { + // Ipp header data according to http://www.ietf.org/rfc/rfc2910.txt + ByteArrayOutputStream out = new ByteArrayOutputStream(8); + // The first 2 bytes represent the IPP version number (1.1) + // major version-number + out.write((byte) 1); + // minor version-number + out.write((byte) 1); + // 2 byte status id + AttributeWriter.writeInt2(this.status.getStatus(), out); + // 4 byte request id + AttributeWriter.writeInt4(this.id, out); + return out.toByteArray(); + } + + private byte[] ippAttributes() throws UnsupportedEncodingException { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + operationAttributes(out); + printerAttributes(out); + jobAttributes(out); + byte[] body = out.toByteArray(); + return body; + } + + /** + * @param out + * @return + */ + private void jobAttributes(ByteArrayOutputStream out) + throws UnsupportedEncodingException { + if (!jobAttributes.isEmpty()) { + out.write((byte) IppDelimiterTag.BEGIN_JOB_ATTRIBUTES.getValue()); + for (int i = 0; i < jobAttributes.toArray().length; i++) { + Attribute attribute = jobAttributes.toArray()[i]; + AttributeWriter.attributeBytes(attribute, out); + } + } + } + + /** + * + * @param out + * @return + */ + private void printerAttributes(ByteArrayOutputStream out) + throws UnsupportedEncodingException { + if (!printerAttributes.isEmpty()) { + out.write((byte) IppDelimiterTag.BEGIN_PRINTER_ATTRIBUTES + .getValue()); + Attribute[] attributes = printerAttributes.toArray(); + for (int i = 0; i < attributes.length; i++) { + AttributeWriter.attributeBytes(attributes[i], out); + } + } + } + + /** + * + * @param out + * @return + */ + private void operationAttributes(ByteArrayOutputStream out) + throws UnsupportedEncodingException { + if (!operationAttributes.isEmpty()) { + out.write((byte) IppDelimiterTag.BEGIN_OPERATION_ATTRIBUTES + .getValue()); + Attribute[] attributes = AttributeHelper + .getOrderedOperationAttributeArray(operationAttributes); + for (int i = 0; i < attributes.length; i++) { + AttributeWriter.attributeBytes(attributes[i], out); + } + } + } + + public void write(OutputStream os) throws IOException { + os.write(this.ippHeader()); + os.write(this.ippAttributes()); + os.write(this.ippFooter()); + } + + public PrintJobAttributeSet getJobAttributes() { + return jobAttributes; + } + + public AttributeSet getOperationAttributes() { + return operationAttributes; + } + + public AttributeSet getPrinterAttributes() { + return printerAttributes; + } + +} diff --git a/jspi/src/main/java/com/google/code/jspi/IppServlet.java b/jspi/src/main/java/com/google/code/jspi/IppServlet.java new file mode 100644 index 0000000..5b876ed --- /dev/null +++ b/jspi/src/main/java/com/google/code/jspi/IppServlet.java @@ -0,0 +1,104 @@ +package com.google.code.jspi; + +import java.io.ByteArrayOutputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; + +import javax.servlet.ServletException; +import javax.servlet.ServletInputStream; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import de.lohndirekt.print.attribute.IppStatus; +import de.lohndirekt.print.attribute.ipp.printerdesc.supported.OperationsSupported; +import de.lohndirekt.print.attribute.ipp.printerdesc.supported.PrinterUriSupported; + +/** + * Servlet implementation class IppServlet + */ +public class IppServlet extends HttpServlet { + private static final long serialVersionUID = 1L; + + private Map attributes; + private OperationsSupported operationId; + private byte[] jobdata; + + /** + * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) + */ + @Override + protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + + System.out.println(""); + System.out.println("H E A D E R S"); + System.out.println(""); + Enumeration headerNames = request.getHeaderNames(); + while (headerNames.hasMoreElements()) { + String headerName = (String) headerNames.nextElement(); + System.out + .println(headerName + ":" + request.getHeader(headerName)); + } + System.out.println(""); + System.out.println("B O D Y"); + System.out.println(""); + ServletInputStream inputStream = request.getInputStream(); + parseRequest(inputStream); + System.out.println("Operazione richiesta : 0x" + + Integer.toHexString(this.operationId.getValue())); + if (this.operationId.getValue() == OperationsSupported.CUPS_GET_PRINTERS + .getValue()) { + IppResponseIppImpl ippresponse = new IppResponseIppImpl( + IppStatus.SUCCESSFUL_OK); + try { + ippresponse.getPrinterAttributes().add( + new PrinterUriSupported(new URI( + "http://127.0.0.1:9090/ipp/IppServlet"))); + } catch (URISyntaxException e) { + e.printStackTrace(); + } + ippresponse.write(response.getOutputStream()); + } + + if (this.operationId.getValue() == OperationsSupported.PRINT_JOB + .getValue()) { + IppResponseIppImpl ippresponse = new IppResponseIppImpl( + IppStatus.SUCCESSFUL_OK); + ippresponse.write(response.getOutputStream()); + java.io.File tempFile = java.io.File + .createTempFile("unijob", "tmp"); + FileOutputStream faos = new FileOutputStream(tempFile); + faos.write(this.jobdata); + faos.close(); + System.out.println("Scritti : [" + this.jobdata.length + + "] bytes in : [" + tempFile.getAbsolutePath() + "]"); + } + + response.getOutputStream().close(); + } + + private void parseRequest(InputStream request) throws IOException { + byte[] header = new byte[8]; + request.read(header); + this.operationId = new OperationsSupported((header[2] << 8) + header[3]); + if (request.available() != 0) { + this.attributes = AttributeParser.parseRequest(request); + } else { + this.attributes = new HashMap(); + } + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + while (request.available() != 0) { + baos.write(request.read()); + } + baos.close(); + this.jobdata = baos.toByteArray(); + request.close(); + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/CancelableJob.java b/jspi/src/main/java/de/lohndirekt/print/CancelableJob.java new file mode 100644 index 0000000..e60783b --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/CancelableJob.java @@ -0,0 +1,73 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */package de.lohndirekt.print; + +import java.io.IOException; +import java.util.logging.Level; + +import javax.print.CancelablePrintJob; +import javax.print.PrintException; +import javax.print.attribute.AttributeSet; +import javax.print.attribute.HashAttributeSet; +import javax.print.event.PrintJobEvent; + +import de.lohndirekt.print.attribute.IppStatus; +import de.lohndirekt.print.attribute.ipp.printerdesc.supported.OperationsSupported; + +/** + * @author bpusch + * + */ +class CancelableJob extends Job implements CancelablePrintJob{ + + + /** + * @param service + */ + public CancelableJob(IppPrintService service) { + super(service); + } + + public void cancel() throws PrintException { + if (!ok) { + throw new PrintException("Job has not been sent. Cannot be canceled"); + } + AttributeSet operationAttributes = new HashAttributeSet(); + operationAttributes.add(this.jobUri); + try { + IppResponse response = + sendRequest( + OperationsSupported.CANCEL_JOB, + operationAttributes); + if (response.getStatus().equals(IppStatus.SUCCESSFUL_OK) + || response.getStatus().equals( + IppStatus.SUCCESSFUL_OK_CONFLICTING_ATTRIBUTES) + || response.getStatus().equals( + IppStatus.SUCCESSFUL_OK_CONFLICTING_ATTRIBUTES)) { + notifyJobListeners(PrintJobEvent.JOB_CANCELED); + } + } catch (IOException e) { + log.log(Level.SEVERE, e.getMessage(), e); + throw new PrintException("Cannot be canceled: IOException", e); + } + } + + + + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/IppConnection.java b/jspi/src/main/java/de/lohndirekt/print/IppConnection.java new file mode 100644 index 0000000..44081c8 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/IppConnection.java @@ -0,0 +1,50 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print; + +import java.io.IOException; +import java.io.InputStream; + +import org.apache.commons.httpclient.HttpException; + +/** + * + * @author sefftinge + * + */ +interface IppConnection { + /** + * @return content of the response + * @throws IOException + */ + public abstract InputStream getIppResponse() throws IOException; + + /** + * @return the statuscode of last request + * @throws IOException + */ + public abstract int getStatusCode() throws IOException; + + /** + * @param stream + */ + public abstract void setIppRequest(InputStream stream); + + public abstract boolean execute() throws HttpException, IOException; +} \ No newline at end of file diff --git a/jspi/src/main/java/de/lohndirekt/print/IppHttpConnection.java b/jspi/src/main/java/de/lohndirekt/print/IppHttpConnection.java new file mode 100644 index 0000000..d0e4e24 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/IppHttpConnection.java @@ -0,0 +1,135 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print; + +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.apache.commons.httpclient.Credentials; +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.HttpException; +import org.apache.commons.httpclient.UsernamePasswordCredentials; +import org.apache.commons.httpclient.methods.EntityEnclosingMethod; +import org.apache.commons.httpclient.methods.PostMethod; + +import de.lohndirekt.print.exception.AuthenticationException; + + +/** + * simple facade / abstraction layer to "commons httpclient" + * + * @author sefftinge + * + */ +class IppHttpConnection implements IppConnection { + + private Logger log = Logger.getLogger(this.getClass().getName()); + + private HttpClient httpConn; + + private PostMethod method; + + /** + * @param uri + * @param user + * @param passwd + * @param useStream + */ + public IppHttpConnection(URI uri, String user, String passwd) { + try { + httpConn = new HttpClient(); + method = new PostMethod(toHttpURI(uri).toString()); + method.addRequestHeader("Content-type", "application/ipp"); + method.addRequestHeader("Accept", "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2"); + method.setRequestContentLength(EntityEnclosingMethod.CONTENT_LENGTH_AUTO); + // authentication + if (user != null && user.trim().length() > 0) { + if (log.isLoggable(Level.FINER)) { + log.log(Level.SEVERE, "Using username: "+user+" , passwd.length "+passwd.length()); + } + method.setDoAuthentication(true); + Credentials creds = new UsernamePasswordCredentials(user, + passwd); + httpConn.getState().setCredentials(null, + toHttpURI(uri).getHost(), creds); + + } + + } catch (Exception e) { + log.log(Level.SEVERE, e.getMessage(), e); + } + } + + + /** + * @return content of the response + * @throws IOException + */ + public InputStream getIppResponse() throws IOException { + return method.getResponseBodyAsStream(); + } + + /** + * @return the statuscode of last request + * @throws IOException + */ + public int getStatusCode() throws IOException { + return method.getStatusCode(); + } + + private static URI toHttpURI(URI uri) { + if (uri.getScheme().equals("ipp")) { + String uriString = uri.toString().replaceFirst("ipp", "http"); + // TODO remove this hack! +// uriString = uriString.replaceAll("(\\d{1,3}\\.){3}\\d{1,3}:\\d{1,}", "127.0.0.1:631"); + // endof hack + try { + uri = new URI(uriString); + } catch (URISyntaxException e) { + throw new RuntimeException("toHttpURI buggy? : uri was " + uri); + } + } + return uri; + } + + /** + * @param stream + */ + public void setIppRequest(InputStream stream) { + method.setRequestBody(stream); + } + + public boolean execute() throws HttpException, IOException { + if (this.method.validate()) { + httpConn.executeMethod(method); + if (this.getStatusCode()==HttpURLConnection.HTTP_UNAUTHORIZED) { + throw new AuthenticationException(method.getStatusText()); + } + return true; + } else { + return false; + } + } + +} \ No newline at end of file diff --git a/jspi/src/main/java/de/lohndirekt/print/IppMultiDocPrintService.java b/jspi/src/main/java/de/lohndirekt/print/IppMultiDocPrintService.java new file mode 100644 index 0000000..8c5a334 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/IppMultiDocPrintService.java @@ -0,0 +1,48 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print; + +import java.net.URI; + +import javax.print.MultiDocPrintJob; +import javax.print.MultiDocPrintService; +/** + * @author bpusch + * + * + */ +class IppMultiDocPrintService extends IppPrintService implements MultiDocPrintService { + + + /** + * @param uri + */ + public IppMultiDocPrintService(URI uri){ + super(uri); + } + + /* (non-Javadoc) + * @see javax.print.MultiDocPrintService#createMultiDocPrintJob() + */ + public MultiDocPrintJob createMultiDocPrintJob() { + return new MediaMultiDocJob(this); + } + + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/IppPrintService.java b/jspi/src/main/java/de/lohndirekt/print/IppPrintService.java new file mode 100644 index 0000000..e99b229 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/IppPrintService.java @@ -0,0 +1,536 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print; +import java.io.IOException; +import java.net.URI; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.print.DocFlavor; +import javax.print.DocPrintJob; +import javax.print.PrintException; +import javax.print.PrintService; +import javax.print.ServiceUIFactory; +import javax.print.attribute.*; +import javax.print.attribute.standard.PrinterURI; +import javax.print.attribute.standard.RequestingUserName; +import javax.print.event.PrintServiceAttributeListener; + +import de.lohndirekt.print.attribute.IppAttributeName; +import de.lohndirekt.print.attribute.IppStatus; +import de.lohndirekt.print.attribute.auth.RequestingUserPassword; +import de.lohndirekt.print.attribute.ipp.DocumentFormat; +import de.lohndirekt.print.attribute.ipp.jobdesc.JobId; +import de.lohndirekt.print.attribute.ipp.printerdesc.supported.DocumentFormatSupported; +import de.lohndirekt.print.attribute.ipp.printerdesc.supported.OperationsSupported; + +/** + * @author bpusch + * + * + */ +public class IppPrintService implements PrintService { + + private final Logger log = Logger.getLogger(this.getClass().getName()); + private DocFlavor[] supportedFlavors = null; + private URI uri; + private RequestingUserName requestingUserName = null; + private RequestingUserPassword requestingUserPassword = null; + private Map attributes = null; + + /** + * @param uri + */ + public IppPrintService(URI uri) { + this.uri = uri; + } + + + + /** + * @return + */ + URI getUri() { + return this.uri; + } + + /* (non-Javadoc) + * @see javax.print.PrintService#getName() + */ + public String getName() { + return uri.getPath().substring(uri.getPath().lastIndexOf("/") + 1); + } + + /** + * + */ + public void reset() { + supportedFlavors = null; + attributes = null; + } + + /* (non-Javadoc) + * @see javax.print.PrintService#createPrintJob() + */ + public DocPrintJob createPrintJob() { + return new CancelableJob(this); + } + + /* (non-Javadoc) + * @see javax.print.PrintService#getAttributes() + */ + public PrintServiceAttributeSet getAttributes() { + PrintServiceAttributeSet set = new HashPrintServiceAttributeSet(); + for (Iterator mapIter = getAllAttributes().values().iterator(); mapIter.hasNext();) { + Set values = (Set) mapIter.next(); + for (Iterator listIter = values.iterator(); listIter.hasNext();) { + Attribute attribute = (Attribute) listIter.next(); + if (attribute instanceof PrintServiceAttribute) { + set.add(attribute); + } + } + } + return set; + } + + /* (non-Javadoc) + * @see javax.print.PrintService#getAttribute(java.lang.Class) + */ + public PrintServiceAttribute getAttribute(Class category) { + if (category == null) { + throw new NullPointerException("category must not be null"); + } + //TODO As CUPS seems not to support this operation-tag (requested-attributes), we need to get all attributes + Set attributes = (Set) getAllAttributes().get(category); + if (attributes != null) { + try { + return (PrintServiceAttribute) attributes.iterator().next(); + } catch (ClassCastException e) { + throw new IllegalArgumentException("category must be a Class that implements interface PrintServiceAttribute"); + } + } + return null; + } + + /* (non-Javadoc) + * @see javax.print.PrintService#getSupportedDocFlavors() + */ + public DocFlavor[] getSupportedDocFlavors() { + if (supportedFlavors == null) { + List flavors = new ArrayList(); + Set flavorAttributes = + (Set) getAllAttributes().get(IppAttributeName.DOCUMENT_FORMAT_SUPORTED.getCategory()); + if (flavorAttributes != null) { + for (Iterator iter = flavorAttributes.iterator(); iter.hasNext();) { + Attribute attribute = (Attribute) iter.next(); + String mimeType = ((DocumentFormatSupported) attribute).getValue(); + if (mimeType.equals(DocFlavor.BYTE_ARRAY.AUTOSENSE.getMimeType())) { + flavors.add(DocFlavor.INPUT_STREAM.AUTOSENSE); + } else if (mimeType.equals(DocFlavor.BYTE_ARRAY.GIF.getMimeType())) { + flavors.add(DocFlavor.INPUT_STREAM.GIF); + } else if (mimeType.equals(DocFlavor.BYTE_ARRAY.JPEG.getMimeType())) { + flavors.add(DocFlavor.INPUT_STREAM.JPEG); + } else if (mimeType.equals(DocFlavor.BYTE_ARRAY.PCL.getMimeType())) { + flavors.add(DocFlavor.INPUT_STREAM.PCL); + } else if (mimeType.equals(DocFlavor.BYTE_ARRAY.PDF.getMimeType())) { + flavors.add(DocFlavor.INPUT_STREAM.PDF); + } else if (mimeType.equals(DocFlavor.BYTE_ARRAY.POSTSCRIPT.getMimeType())) { + flavors.add(DocFlavor.INPUT_STREAM.POSTSCRIPT); + } else if (mimeType.equals(DocFlavor.BYTE_ARRAY.PNG.getMimeType())) { + flavors.add(DocFlavor.INPUT_STREAM.PNG); + } else if (mimeType.equals(DocFlavor.BYTE_ARRAY.TEXT_HTML_HOST.getMimeType().substring(0, 9))) { + flavors.add(DocFlavor.INPUT_STREAM.TEXT_HTML_HOST); + } else if (mimeType.equals(DocFlavor.BYTE_ARRAY.TEXT_PLAIN_HOST.getMimeType().substring(0, 10))) { + flavors.add(DocFlavor.INPUT_STREAM.TEXT_PLAIN_HOST); + } + } + } + DocFlavor[] flavorArray = new DocFlavor[flavors.size()]; + flavorArray = (DocFlavor[]) flavors.toArray(flavorArray); + supportedFlavors = flavorArray; + } + return supportedFlavors; + } + + /* (non-Javadoc) + * @see javax.print.PrintService#isDocFlavorSupported(javax.print.DocFlavor) + */ + public boolean isDocFlavorSupported(DocFlavor flavor) { + List supportedFlavors = Arrays.asList(getSupportedDocFlavors()); + return supportedFlavors.contains(flavor); + } + + /* (non-Javadoc) + * @see javax.print.PrintService#getSupportedAttributeCategories() + */ + public Class[] getSupportedAttributeCategories() { + Set supportedCategories = new HashSet(); + //Attributes named in 4.2 of rfc2911 are optional + if (getAllAttributes().containsKey(IppAttributeName.JOB_PRIORIY_SUPPORTED.getCategory())) { + supportedCategories.add(IppAttributeName.JOB_PRIORIY.getCategory()); + } + if (getAllAttributes().containsKey(IppAttributeName.JOB_HOLD_UNTIL_SUPPORTED.getCategory())) { + supportedCategories.add(IppAttributeName.JOB_HOLD_UNTIL.getCategory()); + } + if (getAllAttributes().containsKey(IppAttributeName.JOB_SHEETS_SUPORTED.getCategory())) { + supportedCategories.add(IppAttributeName.JOB_SHEETS.getCategory()); + } + if (getAllAttributes().containsKey(IppAttributeName.MULTIPLE_DOCUMENT_HANDLING_SUPPORTED.getCategory())) { + supportedCategories.add(IppAttributeName.MULTIPLE_DOCUMENT_HANDLING.getCategory()); + } + if (getAllAttributes().containsKey(IppAttributeName.COPIES_SUPPORTED.getCategory())) { + supportedCategories.add(IppAttributeName.COPIES.getCategory()); + } + if (getAllAttributes().containsKey(IppAttributeName.FINISHINGS_SUPPORTED.getCategory())) { + supportedCategories.add(IppAttributeName.FINISHINGS.getCategory()); + } + if (getAllAttributes().containsKey(IppAttributeName.PAGE_RANGES_SUPPORTED.getCategory())) { + supportedCategories.add(IppAttributeName.PAGE_RANGES.getCategory()); + } + if (getAllAttributes().containsKey(IppAttributeName.SIDES_SUPPORTED.getCategory())) { + supportedCategories.add(IppAttributeName.SIDES.getCategory()); + } + if (getAllAttributes().containsKey(IppAttributeName.NUMBER_UP_SUPPORTED.getCategory())) { + supportedCategories.add(IppAttributeName.NUMBER_UP.getCategory()); + } + if (getAllAttributes().containsKey(IppAttributeName.ORIENTATION_REQUESTED_SUPPORTED.getCategory())) { + supportedCategories.add(IppAttributeName.ORIENTATION_REQUESTED.getCategory()); + } + if (getAllAttributes().containsKey(IppAttributeName.MEDIA_SUPPORTED.getCategory())) { + supportedCategories.add(IppAttributeName.MEDIA.getCategory()); + } + if (getAllAttributes().containsKey(IppAttributeName.PRINTER_RESOLUTION.getCategory())) { + //printer-resolution-supported attribute currently not implemented + } + if (getAllAttributes().containsKey(IppAttributeName.PRINT_QUALITY.getCategory())) { + //print-quality-supported attribute currently not implemented + } + if (getAllAttributes().containsKey(IppAttributeName.JOB_K_OCTETS_SUPPORTED.getCategory())) { + supportedCategories.add(IppAttributeName.JOB_K_OCTETS.getCategory()); + } + if (getAllAttributes().containsKey(IppAttributeName.JOB_IMPRESSIONS_SUPPORTED.getCategory())) { + supportedCategories.add(IppAttributeName.JOB_IMPRESSIONS.getCategory()); + } + if (getAllAttributes().containsKey(IppAttributeName.JOB_MEDIA_SHEETS_SUPPORTED.getCategory())) { + supportedCategories.add(IppAttributeName.JOB_MEDIA_SHEETS.getCategory()); + } + //Printer object MUST support compression attribute + supportedCategories.add(IppAttributeName.COMPRESSION.getCategory()); + Class[] categories = new Class[supportedCategories.size()]; + categories = (Class[]) supportedCategories.toArray(categories); + return categories; + } + + /* (non-Javadoc) + * @see javax.print.PrintService#isAttributeCategorySupported(java.lang.Class) + */ + public boolean isAttributeCategorySupported(Class category) { + return Arrays.asList(this.getSupportedAttributeCategories()).contains(category); + } + + /* (non-Javadoc) + * @see javax.print.PrintService#getDefaultAttributeValue(java.lang.Class) + */ + public Object getDefaultAttributeValue(Class category) { + //Only the attributes listed in rfc2911 4.2(Job Template Attributes) make sense here + Object value = null; + if (category.equals(IppAttributeName.JOB_PRIORIY.getCategory())) { + Attribute attr = getAttribute(IppAttributeName.JOB_PRIORITY_DEFAULT.getCategory()); + if (attr != null) { + value = new Integer(((IntegerSyntax) attr).getValue()); + } + } else if (category.equals(IppAttributeName.JOB_HOLD_UNTIL.getCategory())) { + Attribute attr = getAttribute(IppAttributeName.JOB_HOLD_UNTIL.getCategory()); + if (attr != null) { + value = new Integer(((TextSyntax) attr).getValue()); + } + } else if (category.equals(IppAttributeName.JOB_SHEETS_DEFAULT.getCategory())) { + Attribute attr = getAttribute(IppAttributeName.JOB_SHEETS_DEFAULT.getCategory()); + if (attr != null) { + value = new Integer(((TextSyntax) attr).getValue()); + } + } else if (category.equals(IppAttributeName.COPIES.getCategory())) { + Attribute attr = getAttribute(IppAttributeName.COPIES_DEFAULT.getCategory()); + if (attr != null) { + value = new Integer(((IntegerSyntax) attr).getValue()); + } + } else if (category.equals(IppAttributeName.FINISHINGS.getCategory())) { + Attribute attr = getAttribute(IppAttributeName.FINISHINGS_DEFAULT.getCategory()); + if (attr != null) { + value = new Integer(((IntegerSyntax) attr).toString()); + } + } else if (category.equals(IppAttributeName.SIDES.getCategory())) { + Attribute attr = getAttribute(IppAttributeName.SIDES_DEFAULT.getCategory()); + if (attr != null) { + value = new Integer(((TextSyntax) attr).getValue()); + } + } else if (category.equals(IppAttributeName.NUMBER_UP.getCategory())) { + Attribute attr = getAttribute(IppAttributeName.NUMBER_UP_DEFAULT.getCategory()); + if (attr != null) { + value = new Integer(((IntegerSyntax) attr).getValue()); + } + } else if (category.equals(IppAttributeName.ORIENTATION_REQUESTED.getCategory())) { + Attribute attr = getAttribute(IppAttributeName.ORIENTATION_REQUESTED_DEFAULT.getCategory()); + if (attr != null) { + value = ((TextSyntax) attr).getValue(); + } + } else if (category.equals(IppAttributeName.MEDIA.getCategory())) { + Attribute attr = getAttribute(IppAttributeName.MEDIA_DEFAULT.getCategory()); + if (attr != null) { + value = ((TextSyntax) attr).getValue(); + } + } else if (category.equals(IppAttributeName.PRINTER_RESOLUTION.getCategory())) { + //Cups does not support the printer-resolution-default attribute + } else if (category.equals(IppAttributeName.PRINT_QUALITY.getCategory())) { + //Cups does not support the print-quality-default attribute + } else if (category.equals(IppAttributeName.MULTIPLE_DOCUMENT_HANDLING.getCategory())) { + Attribute attr = getAttribute(IppAttributeName.MULTIPLE_DOCUMENT_HANDLING_DEFAULT.getCategory()); + if (attr != null) { + value = ((TextSyntax) attr).getValue(); + } + } + return value; + } + + /* (non-Javadoc) + * @see javax.print.PrintService#getSupportedAttributeValues(java.lang.Class, javax.print.DocFlavor, javax.print.attribute.AttributeSet) + */ + public Object getSupportedAttributeValues(Class category, DocFlavor flavor, AttributeSet attributes) { + Set supportedAttributes = new HashSet(); + // Only the attributes listed in rfc2911 4.2(Job Template Attributes) do make sense here + if (category.equals(IppAttributeName.JOB_PRIORIY.getCategory())) { + supportedAttributes = (Set) getAllAttributes().get(IppAttributeName.JOB_PRIORIY_SUPPORTED.getCategory()); + } else if (category.equals(IppAttributeName.JOB_HOLD_UNTIL.getCategory())) { + supportedAttributes = (Set) getAllAttributes().get(IppAttributeName.JOB_HOLD_UNTIL_SUPPORTED.getCategory()); + } else if (category.equals(IppAttributeName.JOB_SHEETS.getCategory())) { + supportedAttributes = (Set) getAllAttributes().get(IppAttributeName.JOB_SHEETS_SUPORTED.getCategory()); + } else if (category.equals(IppAttributeName.MULTIPLE_DOCUMENT_HANDLING.getCategory())) { + supportedAttributes = + (Set) getAllAttributes().get(IppAttributeName.MULTIPLE_DOCUMENT_HANDLING_SUPPORTED.getCategory()); + } else if (category.equals(IppAttributeName.COPIES.getCategory())) { + supportedAttributes = (Set) getAllAttributes().get(IppAttributeName.COPIES_SUPPORTED.getCategory()); + } else if (category.equals(IppAttributeName.FINISHINGS.getCategory())) { + supportedAttributes = (Set) getAllAttributes().get(IppAttributeName.FINISHINGS_SUPPORTED.getCategory()); + } else if (category.equals(IppAttributeName.SIDES.getCategory())) { + supportedAttributes = (Set) getAllAttributes().get(IppAttributeName.SIDES_SUPPORTED.getCategory()); + } + //TODO page-ranges + else if (category.equals(IppAttributeName.NUMBER_UP.getCategory())) { + supportedAttributes = (Set) getAllAttributes().get(IppAttributeName.NUMBER_UP_SUPPORTED.getCategory()); + } else if (category.equals(IppAttributeName.ORIENTATION_REQUESTED.getCategory())) { + supportedAttributes = + (Set) getAllAttributes().get(IppAttributeName.ORIENTATION_REQUESTED_SUPPORTED.getCategory()); + } else if (category.equals(IppAttributeName.MEDIA.getCategory())) { + supportedAttributes = (Set) getAllAttributes().get(IppAttributeName.MEDIA_SUPPORTED.getCategory()); + } else if (category.equals(IppAttributeName.PRINTER_RESOLUTION)) { + //printer-resolution-supported attribute currently not implemented + } else if (category.equals(IppAttributeName.PRINT_QUALITY.getCategory())) { + //printer-quality-supported attribute currently not implemented + } else if (category.equals(IppAttributeName.MULTIPLE_DOCUMENT_HANDLING.getCategory())) { + supportedAttributes = + (Set) getAllAttributes().get(IppAttributeName.MULTIPLE_DOCUMENT_HANDLING_SUPPORTED.getCategory()); + } else if (category.equals(IppAttributeName.JOB_IMPRESSIONS.getCategory())) { + supportedAttributes = + (Set) getAllAttributes().get(IppAttributeName.JOB_IMPRESSIONS_SUPPORTED.getCategory()); + } else if (category.equals(IppAttributeName.JOB_K_OCTETS.getCategory())) { + supportedAttributes = (Set) getAllAttributes().get(IppAttributeName.JOB_K_OCTETS_SUPPORTED.getCategory()); + } else if (category.equals(IppAttributeName.JOB_MEDIA_SHEETS.getCategory())) { + supportedAttributes = + (Set) getAllAttributes().get(IppAttributeName.JOB_MEDIA_SHEETS_SUPPORTED.getCategory()); + } else if (category.equals(IppAttributeName.COMPRESSION.getCategory())) { + supportedAttributes = (Set) getAllAttributes().get(IppAttributeName.COMPRESSION_SUPORTED.getCategory()); + } + if (supportedAttributes == null) { + supportedAttributes = new HashSet(); + } + return supportedAttributes.toArray(new Attribute[supportedAttributes.size()]); + } + + /* (non-Javadoc) + * @see javax.print.PrintService#isAttributeValueSupported(javax.print.attribute.Attribute, javax.print.DocFlavor, javax.print.attribute.AttributeSet) + */ + public boolean isAttributeValueSupported(Attribute attrVal, DocFlavor flavor, AttributeSet attributes) { + AttributeSet operationAttributes = new HashAttributeSet(); + if (flavor != null) { + operationAttributes.add(new DocumentFormat(flavor.getMimeType(), Locale.getDefault())); + } + IppRequest request = this.request(OperationsSupported.VALIDATE_JOB); + if (attributes == null) { + attributes = new HashAttributeSet(); + } + attributes.add(attrVal); + Object[] attributeArray = attributes.toArray(); + PrintJobAttributeSet jobAttributes = new HashPrintJobAttributeSet(); + for (int i = 0; i < attributeArray.length; i++) { + Attribute attribute = (Attribute) attributeArray[i]; + //attributes-charset, attributes-natural-language etc. are not set by the user + if (attribute instanceof PrintRequestAttribute && attribute instanceof PrintJobAttribute) { + if (attribute.getCategory().equals(IppAttributeName.JOB_NAME.getCategory()) + || attribute.getCategory().equals(IppAttributeName.FIDELITY.getCategory()) + || attribute.getCategory().equals(IppAttributeName.JOB_IMPRESSIONS.getCategory()) + || attribute.getCategory().equals(IppAttributeName.JOB_K_OCTETS.getCategory()) + || attribute.getCategory().equals(IppAttributeName.JOB_MEDIA_SHEETS.getCategory())) { + operationAttributes.add(attribute); + } else if ( + attribute.getCategory().equals(IppAttributeName.JOB_NAME.getCategory()) + || attribute.getCategory().equals(IppAttributeName.FIDELITY.getCategory())) { + //do nothing, Job Template Attributes can not be used in a Validate-Job operation + } else { + jobAttributes.add(attribute); + } + } + } + request.addOperationAttributes(operationAttributes); + request.setJobAttributes(jobAttributes); + IppResponse response = null; + try { + response = request.send(); + } catch (IOException e) { + log.log(Level.SEVERE, e.getMessage(), e); + } + boolean supported = false; + if (response != null) { + if (response.getStatus().equals(IppStatus.SUCCESSFUL_OK) + || response.getStatus().equals(IppStatus.SUCCESSFUL_OK_CONFLICTING_ATTRIBUTES) + || response.getStatus().equals(IppStatus.SUCCESSFUL_OK_CONFLICTING_ATTRIBUTES)) { + supported = true; + } + } + return supported; + } + + /* (non-Javadoc) + * @see javax.print.PrintService#getUnsupportedAttributes(javax.print.DocFlavor, javax.print.attribute.AttributeSet) + */ + public AttributeSet getUnsupportedAttributes(DocFlavor flavor, AttributeSet attributes) { + return null; + } + + /* (non-Javadoc) + * @see javax.print.PrintService#getServiceUIFactory() + */ + public ServiceUIFactory getServiceUIFactory() { + return null; + } + + /* (non-Javadoc) + * @see javax.print.PrintService#addPrintServiceAttributeListener(javax.print.event.PrintServiceAttributeListener) + */ + public void addPrintServiceAttributeListener(PrintServiceAttributeListener listener) { + } + + /* (non-Javadoc) + * @see javax.print.PrintService#removePrintServiceAttributeListener(javax.print.event.PrintServiceAttributeListener) + */ + public void removePrintServiceAttributeListener(PrintServiceAttributeListener listener) { + } + + /** + * @return + */ + private Map getAllAttributes() { + if (this.attributes == null) { + IppRequest request = this.request(OperationsSupported.GET_PRINTER_ATTRIBUTES); + IppResponse response = null; + try { + response = request.send(); + } catch (IOException e) { + log.log(Level.SEVERE, e.getMessage(), e); + } + if (response != null) { + this.attributes = response.getAttributes(); + } + } + return this.attributes; + } + + public String toString() { + return this.getName(); + } + + /** + * @param operation + * @return + */ + protected IppRequest request(OperationsSupported operation) { + IppRequest request = IppRequestFactory.createIppRequest(this.uri, operation, this.getRequestingUserName(), this.getRequestingUserPassword()); + AttributeSet operationAttributes = new HashAttributeSet(); + operationAttributes.add(new PrinterURI(this.uri)); + request.addOperationAttributes(operationAttributes); + return request; + } + + /** + * Returns a job with the given JobId, or null if no such + * Job exists. + *
+ * Use jobExists to check for a Job with this JobId. + *
+ * This method might return a Job which is not hold by this PrintService + * but the same CUPS server + * + * @param jobId + * @return the corresponding Job wihth the given JobId, or null if no such Job exists + * @throws PrintException + */ + //public Methods which are not part of the JPS API + public DocPrintJob getJob(JobId jobId) throws PrintException { + Job job = Job.getJob(this, jobId); + return job; + } + + /** + * + * Check for a Job with the given JobId. + *
+ * This method might return true, even if the printservice does not hold any + * job with the given JobId, but another PrintService on the same + * Cups server does. + * + * @param jobId + * @return true if a Job with the given JobId exists, false otherwise + * @throws PrintException + */ + public boolean jobExists(JobId jobId) throws PrintException { + return Job.getJob(this, jobId) != null; + } + + + public RequestingUserName getRequestingUserName() { + return requestingUserName; + } + public void setRequestingUserName(RequestingUserName requestingUserName) { + this.requestingUserName = requestingUserName; + } + public RequestingUserPassword getRequestingUserPassword() { + return requestingUserPassword; + } + public void setRequestingUserPassword( + RequestingUserPassword requestingUserPassword) { + this.requestingUserPassword = requestingUserPassword; + } +} diff --git a/jspi/src/main/java/de/lohndirekt/print/IppPrintServiceLookup.java b/jspi/src/main/java/de/lohndirekt/print/IppPrintServiceLookup.java new file mode 100644 index 0000000..c9117d4 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/IppPrintServiceLookup.java @@ -0,0 +1,199 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print; + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.print.DocFlavor; +import javax.print.MultiDocPrintService; +import javax.print.PrintService; +import javax.print.PrintServiceLookup; +import javax.print.attribute.Attribute; +import javax.print.attribute.AttributeSet; +import javax.print.attribute.standard.RequestingUserName; + +import de.lohndirekt.print.attribute.auth.RequestingUserPassword; + +/** + * + * @author bpusch + * + *

+ * This is an implementation of the Java Print Service API for IPP.

+ * To use this implementation do one of the following: + *

+ * 1. Set the system properties + *

+ * and use the default constructor + *

+ * 2. use the 3 parameter constructor + *

+ * then register the instance by invoking javax.print.PrintServiceLookup.registerServiceProvider
+ *
+ * @see javax.print.PrintServiceLookup#registerServiceProvider + */ +public class IppPrintServiceLookup extends PrintServiceLookup { + public final static String URI_KEY = "de.lohndirekt.print.IppPrintService.uri"; + public final static String USERNAME_KEY = "de.lohndirekt.print.IppPrintService.username"; + public final static String PASSWORD_KEY = "de.lohndirekt.print.IppPrintService.password"; + private List cupsServers = new ArrayList(); + private Logger log = Logger.getLogger(this.getClass().getName()); + + /** + *

+ * default constructor uses the values set in + *

+ * de.lohndirekt.print.IppPrintService.uri
+ * de.lohndirekt.print.IppPrintService.username
+ * de.lohndirekt.print.IppPrintService.password
+ */ + public IppPrintServiceLookup() { + String myUri = (String) System.getProperties().get(URI_KEY); + String user = (String) System.getProperties().get(USERNAME_KEY); + String password = (String) System.getProperties().get(PASSWORD_KEY); + URI uri = null; + if (myUri == null) { + throw new NullPointerException("System property " + URI_KEY + " not set!"); + } else if (user == null) { + throw new NullPointerException("System property " + USERNAME_KEY + " not set!"); + } else if (password == null) { + throw new NullPointerException("System property " + PASSWORD_KEY + " not set!"); + } + try { + uri = new URI(myUri); + } catch (URISyntaxException e) { + throw new NullPointerException("System property " + URI_KEY + " - " + myUri + " is not a valid Uri!"); + } + cupsServers.add(new IppServer(uri, new RequestingUserName(user,Locale.getDefault()), new RequestingUserPassword(password,Locale.getDefault()))); + } + + /** + * This constructor uses the given parameters to connect to an IPP service + * + * @param uri the uri of the ipp service + * @param username used for authentication + * @param password used for authentication + */ + public IppPrintServiceLookup(URI uri, String username, String password) { + cupsServers.add(new IppServer(uri, new RequestingUserName(username,Locale.getDefault()),new RequestingUserPassword(password,Locale.getDefault()))); + } + + /* (non-Javadoc) + * @see javax.print.PrintServiceLookup#getPrintServices(javax.print.DocFlavor, javax.print.attribute.AttributeSet) + */ + public PrintService[] getPrintServices(DocFlavor flavor, AttributeSet attributes) { + PrintService[] services = getPrintServices(); + List fittingServices = new ArrayList(); + for (int i = 0; i < services.length; i++) { + IppPrintService service = (IppPrintService) services[i]; + if (checkService(service, flavor, attributes)) { + fittingServices.add(service); + } + } + PrintService[] serviceArray = new PrintService[fittingServices.size()]; + return (PrintService[]) fittingServices.toArray(serviceArray); + } + + /* (non-Javadoc) + * @see javax.print.PrintServiceLookup#getPrintServices() + */ + public PrintService[] getPrintServices() { + List services = new ArrayList(); + try { + for (Iterator iter = cupsServers.iterator(); iter.hasNext();) { + IppServer server = (IppServer) iter.next(); + services.addAll(server.getPrintServices()); + } + } catch (RuntimeException e) { + log.log(Level.SEVERE, e.getMessage(), e); + } + PrintService[] serviceArray = new PrintService[services.size()]; + return (PrintService[]) services.toArray(serviceArray); + } + + /** + * @param service + * @param flavor + * @param attributes + * @return + */ + private boolean checkService(IppPrintService service, DocFlavor flavor, AttributeSet attributes) { + if (flavor == null || service.isDocFlavorSupported(flavor)) { + if (attributes != null) { + Attribute[] attrArray = attributes.toArray(); + for (int j = 0; j < attrArray.length; j++) { + Attribute attribute = attrArray[j]; + if (service.isAttributeValueSupported(attribute, flavor, null)) { + return true; + } + } + } else { + return true; + } + } + return false; + } + + /* (non-Javadoc) + * @see javax.print.PrintServiceLookup#getMultiDocPrintServices(javax.print.DocFlavor[], javax.print.attribute.AttributeSet) + */ + public MultiDocPrintService[] getMultiDocPrintServices(DocFlavor[] flavors, AttributeSet attributes) { + Set multiDocServices = new HashSet(); + PrintService[] services = getPrintServices(null, attributes); + for (int i = 0; i < services.length; i++) { + PrintService service = services[i]; + if (flavors != null) { + for (int j = 0; j < flavors.length; j++) { + DocFlavor flavor = flavors[j]; + if (!service.isDocFlavorSupported(flavor)) { + break; + } + } + } + multiDocServices.add(new IppMultiDocPrintService(((IppPrintService) service).getUri())); + } + return (MultiDocPrintService[]) multiDocServices.toArray(new MultiDocPrintService[multiDocServices.size()]); + + } + + /* (non-Javadoc) + * @see javax.print.PrintServiceLookup#getDefaultPrintService() + */ + public PrintService getDefaultPrintService() { + PrintService[] services = this.getPrintServices(); + if (services.length > 0) { + return services[0]; + } + return null; + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/IppPrintServiceLookupTest.java b/jspi/src/main/java/de/lohndirekt/print/IppPrintServiceLookupTest.java new file mode 100644 index 0000000..e0d7643 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/IppPrintServiceLookupTest.java @@ -0,0 +1,68 @@ +package de.lohndirekt.print; + +import java.util.Locale; + +import javax.print.DocFlavor; +import javax.print.PrintService; +import javax.print.attribute.AttributeSet; +import javax.print.attribute.HashAttributeSet; +import javax.print.attribute.standard.RequestingUserName; + +import de.lohndirekt.print.attribute.auth.RequestingUserPassword; + +import junit.framework.TestCase; + +/** + * @author bpusch + * + */ +public class IppPrintServiceLookupTest extends TestCase { + + /** + * Constructor for IppPrintServiceLookupTest. + * @param name + */ + public IppPrintServiceLookupTest(String name) { + super(name); + } + + /* + * @see TestCase#setUp() + */ + protected void setUp() throws Exception { + super.setUp(); + //setting cups properties + System.getProperties().setProperty(IppPrintServiceLookup.URI_KEY, Messages.getString("cups.uri")); //$NON-NLS-1$ + System.getProperties().setProperty(IppPrintServiceLookup.USERNAME_KEY, Messages.getString("cups.username")); //$NON-NLS-1$ + System.getProperties().setProperty(IppPrintServiceLookup.PASSWORD_KEY, Messages.getString("cups.password")); //$NON-NLS-1$ + System.getProperties().setProperty("org.apache.commons.logging.Log", "org.apache.commons.logging.impl.SimpleLog"); //$NON-NLS-1$ + System.getProperties().setProperty("org.apache.commons.logging.simplelog.showdatetime", "true"); + System.getProperties().setProperty("org.apache.commons.logging.simplelog.log.httpclient.wire", "debug"); + System.getProperties().setProperty("org.apache.commons.logging.simplelog.log.org.apache.commons.httpclient", "debug"); + } + +// public void testGetServices(){ +// PrintService[] services = new IppPrintServiceLookup().getPrintServices(DocFlavor.INPUT_STREAM.POSTSCRIPT ,null); +// assertTrue(services.length>0); +// +// //IppPrintServiceLookup must not return any pageable enabled services +// services = new IppPrintServiceLookup().getPrintServices(DocFlavor.SERVICE_FORMATTED.PAGEABLE, null); +// assertEquals(0,services.length); +// } + + + + public void testGetServicesAuthenticated(){ + RequestingUserName user = new RequestingUserName(Messages.getString("cups.username"), Locale.GERMANY); + RequestingUserPassword pass = new RequestingUserPassword(Messages.getString("cups.password"), Locale.GERMANY); + + AttributeSet set = new HashAttributeSet(); + set.add(user); + set.add(pass); + + PrintService[] services = new IppPrintServiceLookup().getPrintServices(DocFlavor.INPUT_STREAM.POSTSCRIPT ,null); + assertTrue(services.length>0); + + + } +} diff --git a/jspi/src/main/java/de/lohndirekt/print/IppPrintServiceTest.java b/jspi/src/main/java/de/lohndirekt/print/IppPrintServiceTest.java new file mode 100644 index 0000000..9d791e6 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/IppPrintServiceTest.java @@ -0,0 +1,120 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print; + +import java.net.URI; +import java.util.Arrays; +import java.util.List; +import java.util.logging.Logger; + +import javax.print.PrintService; +import javax.print.attribute.Attribute; + +import junit.framework.TestCase; +import de.lohndirekt.print.attribute.IppAttributeName; +import de.lohndirekt.print.test.IppRequestTestImpl; + +/** + * @author bpusch + * + */ +public class IppPrintServiceTest extends TestCase { + + PrintService service; + Logger log; + + /** + * Constructor for IppPrintServiceTest. + * @param arg0 + */ + public IppPrintServiceTest(String arg0) { + super(arg0); + } + + /* + * @see TestCase#setUp() + */ + protected void setUp() throws Exception { + super.setUp(); + System.setProperty(IppRequestFactory.IPP_REQUEST_IMPL_KEY, IppRequestTestImpl.class.getName()); + IppPrintServiceLookup lookup = new IppPrintServiceLookup(new URI("http://127.0.0.1"), "", ""); + PrintService[] services = lookup.getPrintServices(); + this.service = services[0]; + this.log = Logger.getLogger(this.getName()); + } + + public void testGetSupportedAttributeCategories() { + Class[] categories = this.service.getSupportedAttributeCategories(); + assertNotNull(categories); + List cats = Arrays.asList(categories); + assertTrue(cats.contains(IppAttributeName.JOB_PRIORIY.getCategory())); + assertTrue(cats.contains(IppAttributeName.JOB_HOLD_UNTIL.getCategory())); + assertTrue(cats.contains(IppAttributeName.JOB_SHEETS.getCategory())); + assertTrue(cats.contains(IppAttributeName.MULTIPLE_DOCUMENT_HANDLING.getCategory())); + assertTrue(cats.contains(IppAttributeName.COPIES.getCategory())); + assertTrue(cats.contains(IppAttributeName.FINISHINGS.getCategory())); + assertTrue(cats.contains(IppAttributeName.SIDES.getCategory())); + assertTrue(cats.contains(IppAttributeName.NUMBER_UP.getCategory())); + assertTrue(cats.contains(IppAttributeName.ORIENTATION_REQUESTED.getCategory())); + assertTrue(cats.contains(IppAttributeName.MEDIA.getCategory())); + assertTrue(cats.contains(IppAttributeName.COMPRESSION.getCategory())); + assertTrue(cats.contains(IppAttributeName.JOB_K_OCTETS.getCategory())); + assertTrue(cats.contains(IppAttributeName.JOB_IMPRESSIONS.getCategory())); + assertTrue(cats.contains(IppAttributeName.JOB_MEDIA_SHEETS.getCategory())); + } + + public void testIsAttributeCategorySupported() { + Class category = IppAttributeName.JOB_SHEETS.getCategory(); + boolean supported = this.service.isAttributeCategorySupported(category); + assertEquals(Arrays.asList(this.service.getSupportedAttributeCategories()).contains(category), supported); + + } + + public void testGetSupportedAttributeValues() { + Class category = IppAttributeName.MEDIA.getCategory(); + Attribute[] attrs = (Attribute[]) this.service.getSupportedAttributeValues(category, null, null); + assertEquals("Should be 2 media-supported attributes", 2, attrs.length); + for (int j = 0; j < attrs.length; j++) { + Attribute attribute = attrs[j]; + assertEquals(IppAttributeName.MEDIA_SUPPORTED.getCategory(), attribute.getCategory()); + } + category = IppAttributeName.COMPRESSION.getCategory(); + attrs = (Attribute[]) this.service.getSupportedAttributeValues(category, null, null); + for (int j = 0; j < attrs.length; j++) { + Attribute attribute = attrs[j]; + assertEquals(IppAttributeName.COMPRESSION_SUPORTED.getCategory(), attribute.getCategory()); + } + category = IppAttributeName.JOB_PRIORIY.getCategory(); + attrs = (Attribute[]) this.service.getSupportedAttributeValues(category, null, null); + assertEquals("Should be 1 job-priority-supported attribute", 1, attrs.length); + for (int j = 0; j < attrs.length; j++) { + Attribute attribute = attrs[j]; + assertEquals(IppAttributeName.JOB_PRIORIY_SUPPORTED.getCategory(), attribute.getCategory()); + } + category = IppAttributeName.SIDES.getCategory(); + attrs = (Attribute[]) this.service.getSupportedAttributeValues(category, null, null); + assertEquals("Should be 2 sides-supported attributes", 2, attrs.length); + for (int j = 0; j < attrs.length; j++) { + Attribute attribute = attrs[j]; + assertEquals(IppAttributeName.SIDES_SUPPORTED.getCategory(), attribute.getCategory()); + } + + } + +} \ No newline at end of file diff --git a/jspi/src/main/java/de/lohndirekt/print/IppRequest.java b/jspi/src/main/java/de/lohndirekt/print/IppRequest.java new file mode 100644 index 0000000..7e7d244 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/IppRequest.java @@ -0,0 +1,39 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print; + +import java.io.IOException; +import java.io.InputStream; + +import javax.print.attribute.AttributeSet; +import javax.print.attribute.PrintJobAttributeSet; + +/** + * @author sefftinge + * + */ +public interface IppRequest { + + IppResponse send() throws IOException; + void setData(byte[] data); + void setData(InputStream data); + void setJobAttributes(PrintJobAttributeSet attributes); + void addOperationAttributes(AttributeSet attributes); + void setPrinterAttributes(AttributeSet attributes); +} \ No newline at end of file diff --git a/jspi/src/main/java/de/lohndirekt/print/IppRequestCupsImpl.java b/jspi/src/main/java/de/lohndirekt/print/IppRequestCupsImpl.java new file mode 100644 index 0000000..4eeca85 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/IppRequestCupsImpl.java @@ -0,0 +1,398 @@ +/** + * Copyright (C) 2004 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.SequenceInputStream; +import java.io.UnsupportedEncodingException; +import java.net.HttpURLConnection; +import java.net.URI; +import java.util.HashMap; +import java.util.Map; +import java.util.Vector; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.print.attribute.Attribute; +import javax.print.attribute.AttributeSet; +import javax.print.attribute.HashAttributeSet; +import javax.print.attribute.HashPrintJobAttributeSet; +import javax.print.attribute.PrintJobAttributeSet; +import javax.print.attribute.TextSyntax; + +import de.lohndirekt.print.attribute.AttributeHelper; +import de.lohndirekt.print.attribute.AttributeParser; +import de.lohndirekt.print.attribute.AttributeWriter; +import de.lohndirekt.print.attribute.IppAttributeName; +import de.lohndirekt.print.attribute.IppDelimiterTag; +import de.lohndirekt.print.attribute.IppStatus; +import de.lohndirekt.print.attribute.ipp.Charset; +import de.lohndirekt.print.attribute.ipp.NaturalLanguage; +import de.lohndirekt.print.attribute.ipp.printerdesc.supported.OperationsSupported; + +/** + * @author bpusch, speters, sefftinge + * + */ +class IppRequestCupsImpl implements IppRequest { + class IppResponseIppImpl implements IppResponse { + private Logger log = Logger.getLogger(this.getClass().getName()); + + private IppStatus status; + + private Map attributes; + + IppResponseIppImpl(InputStream response) { + try{ + parseResponse(response); + } catch (IOException e) { + log.log(Level.SEVERE, e.getMessage(), e); + throw new RuntimeException(e); + } + + } + + private void parseResponse(InputStream response) throws IOException { + byte[] header = new byte[8]; + response.read(header); + this.status = IppStatus.get((int) (header[2] << 8) + + (int) header[3]); + if (response.available() != 0) { + this.attributes = AttributeParser.parseResponse(response); + } else { + this.attributes = new HashMap(); + } + if (log.isLoggable(Level.FINEST)) { + log.finest("Status: " + status.getText()); + } + } + + /** + * @return + */ + public Map getAttributes() { + return attributes; + } + + /** + * @return + */ + public IppStatus getStatus() { + return status; + } + + } + + private IppConnection conn; + + private boolean sent = false; + + private Object data; + + private URI path; + + private OperationsSupported operation; + + //Id wird in der Cups-API zwar übergeben, ist aber auch immer 1. + private int id = 1; + + private PrintJobAttributeSet jobAttributes = new HashPrintJobAttributeSet(); + + private AttributeSet operationAttributes = new HashAttributeSet(); + + private AttributeSet printerAttributes = new HashAttributeSet(); + + private Logger log = Logger.getLogger(this.getClass().getName()); + + private static final int SEND_REQUEST_COUNT = 3; + + private static final int SEND_REQUEST_TIMEOUT = 50; + + private static final NaturalLanguage NATURAL_LANGUAGE_DEFAULT = NaturalLanguage.EN; + + private static final Charset CHARSET_DEFAULT = Charset.UTF_8; + + + /** + * @param operation + */ + IppRequestCupsImpl(URI path, OperationsSupported operation) { + this.path = path; + this.operation = operation; + init(); + } + + /** + * @param printerAttributes + */ + public void setPrinterAttributes(AttributeSet attrs) { + this.printerAttributes = attrs; + } + + /** + * + */ + private void init() { + setStandardAttributes(); + } + + /** + * + */ + private void setStandardAttributes() { + operationAttributes.add(CHARSET_DEFAULT); + operationAttributes.add(NATURAL_LANGUAGE_DEFAULT); + } + + /** + * + */ + private byte[] ippFooter() { + byte[] footer = new byte[1]; + footer[0] = (byte) IppDelimiterTag.END_ATTRIBUTES.getValue(); + return footer; + } + + /** + * + */ + private byte[] ippAttributes() throws UnsupportedEncodingException { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + operationAttributes(out); + printerAttributes(out); + jobAttributes(out); + byte[] body = out.toByteArray(); + return body; + } + + /** + * @param out + * @return + */ + private void jobAttributes(ByteArrayOutputStream out) throws UnsupportedEncodingException { + if (!jobAttributes.isEmpty()) { + out.write((byte) IppDelimiterTag.BEGIN_JOB_ATTRIBUTES + .getValue()); + for (int i = 0; i < jobAttributes.toArray().length; i++) { + Attribute attribute = (Attribute) jobAttributes.toArray()[i]; + AttributeWriter.attributeBytes(attribute, out); + } + } + } + + /** + * + * @param out + * @return + */ + private void printerAttributes(ByteArrayOutputStream out) throws UnsupportedEncodingException { + if (!printerAttributes.isEmpty()) { + out.write((byte) IppDelimiterTag.BEGIN_PRINTER_ATTRIBUTES + .getValue()); + Attribute[] attributes = printerAttributes.toArray(); + for (int i = 0; i < attributes.length; i++) { + AttributeWriter.attributeBytes(attributes[i], out); + } + } + } + + /** + * + * @param out + * @return + */ + private void operationAttributes(ByteArrayOutputStream out) throws UnsupportedEncodingException { + if (!operationAttributes.isEmpty()) { + out.write((byte) IppDelimiterTag.BEGIN_OPERATION_ATTRIBUTES + .getValue()); + Attribute[] attributes = AttributeHelper.getOrderedOperationAttributeArray(operationAttributes); + for (int i = 0; i < attributes.length; i++) { + AttributeWriter.attributeBytes(attributes[i], out); + } + } + } + + /** + * + */ + private byte[] ippHeader() { + //Ipp header data according to http://www.ietf.org/rfc/rfc2910.txt + ByteArrayOutputStream out = new ByteArrayOutputStream(8); + //The first 2 bytes represent the IPP version number (1.1) + //major version-number + out.write((byte) 1); + //minor version-number + out.write((byte) 1); + //2 byte operation id + AttributeWriter.writeInt2(this.operation.getValue(), out); + //4 byte request id + AttributeWriter.writeInt4(this.id, out); + return out.toByteArray(); + } + + /** + * @param attributes + */ + public void addOperationAttributes(AttributeSet attributes) { + this.operationAttributes.addAll(attributes); + } + + /** + * @param stream + */ + public void setData(InputStream data) { + this.data = data; + } + + public void setData(byte[] data) { + this.data = data; + } + + /** + * @param attributes + */ + public void setJobAttributes(PrintJobAttributeSet attributes) { + this.jobAttributes = attributes; + } + + /** + * @see de.lohndirekt.print.IppRequest#send() + * @throws IllegalArgumentException + * when called twice + */ + public IppResponse send() throws IOException { + if (sent) { + throw new IllegalStateException("Send must not be called twice"); + } + + String username = findUserName(this.operationAttributes); + String password = findPassword(this.operationAttributes); + boolean ok = false; + int tries = 0; + while (!ok && tries < SEND_REQUEST_COUNT) { + tries++; + + this.conn = new IppHttpConnection(this.path, username, password); + + Vector v = new Vector(); + v.add(new ByteArrayInputStream(this.ippHeader())); + v.add(new ByteArrayInputStream(this.ippAttributes())); + v.add(new ByteArrayInputStream(this.ippFooter())); + if (this.data != null) { + v.add(this.getDataAsInputStream()); + } + SequenceInputStream stream = new SequenceInputStream(v.elements()); + conn.setIppRequest(stream); + conn.execute(); + + if (conn.getStatusCode() != HttpURLConnection.HTTP_OK) { + if (log.isLoggable(Level.INFO)) { + String msg = "Cups seems to be busy - STATUSCODE "+conn.getStatusCode(); + if (tries < SEND_REQUEST_COUNT) { + msg += " - going to retry in " + SEND_REQUEST_TIMEOUT + + " ms"; + } + log.warning(msg); + } + try { + Thread.sleep(50); + } catch (InterruptedException e) { + if (log.isLoggable(Level.INFO)) { + log.info(e.getMessage()); + } + } + } else { + ok = true; + } + + } + this.sent = true; + return getResponse(); + } + + /** + * @param list + * @return + */ + private String findUserName(AttributeSet list) { + if (list != null) { + TextSyntax attr = (TextSyntax) list.get(IppAttributeName.REQUESTING_USER_NAME + .getCategory()); + if (attr != null) { + return attr.getValue(); + } + } + return null; + } + + /** + * @param list + * @return + */ + private String findPassword(AttributeSet list) { + if (list != null) { + TextSyntax attr = (TextSyntax) list.get(IppAttributeName.REQUESTING_USER_PASSWD + .getCategory()); + if (attr != null) { + return attr.getValue(); + } + } + return null; + } + + /** + * @return + */ + private InputStream getDataAsInputStream() { + if (data == null) { + return null; +// } else if (data instanceof FileInputStream) { +// FileInputStream in = (FileInputStream) data; +// try { +// if (in.getFD().valid()){ +// //TODO remove this hack +// in=new FileInputStream("./testfiles/test.pdf"); +// } +// } catch (IOException e) { +// log.log(Level.WARNING, "", e); +// } +// return in; + } else if (data instanceof InputStream) { + InputStream in = (InputStream) data; + return in; + } else if (data instanceof byte[]) { + return new ByteArrayInputStream((byte[]) data); + } else { + throw new IllegalStateException("unknown data format : " + + data.getClass()); + } + } + + private IppResponse getResponse() throws IOException { + if (this.conn.getStatusCode()==HttpURLConnection.HTTP_OK) { + return new IppResponseIppImpl(conn.getIppResponse()); + } else { + return null; + } + } + +} \ No newline at end of file diff --git a/jspi/src/main/java/de/lohndirekt/print/IppRequestFactory.java b/jspi/src/main/java/de/lohndirekt/print/IppRequestFactory.java new file mode 100644 index 0000000..c9c8e8d --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/IppRequestFactory.java @@ -0,0 +1,73 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print; + +import java.lang.reflect.Constructor; +import java.net.URI; + +import javax.print.attribute.AttributeSet; +import javax.print.attribute.HashAttributeSet; +import javax.print.attribute.standard.RequestingUserName; + +import de.lohndirekt.print.attribute.auth.RequestingUserPassword; +import de.lohndirekt.print.attribute.ipp.printerdesc.supported.OperationsSupported; + +/** + * @author bpusch + * + */ +public final class IppRequestFactory { + + final static String IPP_REQUEST_IMPL_KEY = "de.lohndirekt.print.IppRequest.Impl"; + + final static IppRequest createIppRequest(URI uri, + OperationsSupported operation, RequestingUserName user, + RequestingUserPassword passwd) { + String requestClassName = System.getProperty(IPP_REQUEST_IMPL_KEY); + IppRequest request = null; + if (requestClassName == null) { + request = new IppRequestCupsImpl(uri, operation); + } else { + Class clazz = null; + try { + clazz = Class.forName(requestClassName); + } catch (ClassNotFoundException e) { + throw new IllegalArgumentException("Class " + requestClassName + + " does not exist."); + } + + try { + Constructor constructor = clazz + .getDeclaredConstructor(new Class[] { URI.class, + OperationsSupported.class }); + request = (IppRequest) constructor.newInstance(new Object[] { + uri, operation }); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + if (user != null && passwd != null) { + AttributeSet set = new HashAttributeSet(); + set.add(user); + set.add(passwd); + request.addOperationAttributes(set); + } + return request; + } +} \ No newline at end of file diff --git a/jspi/src/main/java/de/lohndirekt/print/IppResponse.java b/jspi/src/main/java/de/lohndirekt/print/IppResponse.java new file mode 100644 index 0000000..5a7b65a --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/IppResponse.java @@ -0,0 +1,38 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print; + +import java.util.Map; + +import de.lohndirekt.print.attribute.IppStatus; + +/** + * @author sefftinge + * + */ +public interface IppResponse { + /** + * @return attributes + */ + public abstract Map getAttributes(); + /** + * @return the IppStatus + */ + public abstract IppStatus getStatus(); +} \ No newline at end of file diff --git a/jspi/src/main/java/de/lohndirekt/print/IppServer.java b/jspi/src/main/java/de/lohndirekt/print/IppServer.java new file mode 100644 index 0000000..82ea7ff --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/IppServer.java @@ -0,0 +1,94 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print; + +import java.io.IOException; +import java.net.URI; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.print.attribute.Attribute; +import javax.print.attribute.URISyntax; +import javax.print.attribute.standard.RequestingUserName; + +import de.lohndirekt.print.attribute.IppAttributeName; +import de.lohndirekt.print.attribute.auth.RequestingUserPassword; +import de.lohndirekt.print.attribute.ipp.printerdesc.supported.OperationsSupported; + +/** + * @author bpusch + * + */ +class IppServer { + + private final Logger log = Logger.getLogger(this.getClass().getName()); + private URI uri; + private RequestingUserName user; + private RequestingUserPassword passwd; + + IppServer(URI uri, RequestingUserName user, RequestingUserPassword passwd) { + this.uri = uri; + this.user = user; + this.passwd = passwd; + } + + /** + * @return a list of all PrintServices (printers as well as classes) + * known to the CUPS server + */ + List getPrintServices() { + List services = new ArrayList(); + services.addAll(getServices(OperationsSupported.CUPS_GET_PRINTERS,user,passwd)); + services.addAll(getServices(OperationsSupported.CUPS_GET_CLASSES,user,passwd)); + return services; + } + + private List getServices(OperationsSupported operation,RequestingUserName user, RequestingUserPassword passwd){ + if (!(operation==OperationsSupported.CUPS_GET_CLASSES || operation == OperationsSupported.CUPS_GET_PRINTERS)){ + throw new IllegalArgumentException("Operation not applicable"); + } + IppResponse response = null; + IppRequest request = IppRequestFactory.createIppRequest(this.uri, operation,user,passwd); + try { + response = request.send(); + } catch (IOException e) { + log.log(Level.SEVERE, e.getMessage(),e); + } + List services = new ArrayList(); + if (response != null) { + Set uriAttributes = (Set)response.getAttributes().get(IppAttributeName.PRINTER_URI_SUPPORTED.getCategory()); + if (uriAttributes != null) { + for (Iterator iter = uriAttributes.iterator(); iter.hasNext();) { + Attribute attribute = (Attribute)iter.next(); + URI printerUri = ((URISyntax)attribute).getURI(); + IppPrintService service = new IppPrintService(printerUri); + service.setRequestingUserName(user); + service.setRequestingUserPassword(passwd); + services.add(service); + } + } + } + return services; + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/Job.java b/jspi/src/main/java/de/lohndirekt/print/Job.java new file mode 100644 index 0000000..a9b3188 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/Job.java @@ -0,0 +1,305 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print; + +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.print.Doc; +import javax.print.DocPrintJob; +import javax.print.PrintException; +import javax.print.PrintService; +import javax.print.attribute.Attribute; +import javax.print.attribute.AttributeSet; +import javax.print.attribute.HashAttributeSet; +import javax.print.attribute.HashPrintJobAttributeSet; +import javax.print.attribute.PrintJobAttribute; +import javax.print.attribute.PrintJobAttributeSet; +import javax.print.attribute.PrintRequestAttributeSet; +import javax.print.event.PrintJobAttributeListener; +import javax.print.event.PrintJobEvent; +import javax.print.event.PrintJobListener; + +import de.lohndirekt.print.attribute.AttributeHelper; +import de.lohndirekt.print.attribute.IppAttributeName; +import de.lohndirekt.print.attribute.IppStatus; +import de.lohndirekt.print.attribute.ipp.jobdesc.JobId; +import de.lohndirekt.print.attribute.ipp.jobdesc.JobUri; +import de.lohndirekt.print.attribute.ipp.printerdesc.supported.OperationsSupported; + +/** + * @author bpusch + * + */ +class Job implements DocPrintJob { + protected boolean ok = false; + protected Logger log = Logger.getLogger(this.getClass().getName()); + protected IppPrintService printService; + private PrintJobAttributeSet jobAttributes; + protected JobUri jobUri; + private List jobListeners; + private Map attributeListeners; + + /** + * @param service + */ + public Job(IppPrintService service) { + this.printService = service; + } + + /** + * + */ + public PrintService getPrintService() { + return this.printService; + } + + /** + * + */ + public PrintJobAttributeSet getAttributes() { + return this.jobAttributes; + } + + /** + * + */ + public void print(Doc doc, PrintRequestAttributeSet attributes) throws PrintException { + IppRequest request = null; + request = this.printService.request(OperationsSupported.PRINT_JOB); + try { + request.setData(doc.getStreamForBytes()); + } catch (IOException e) { + log.log(Level.SEVERE, e.getMessage(), e); + throw new PrintException("Error getting document data (" + description(attributes) + "): " + e.getMessage()); + } + //add the operation attributes + AttributeSet operationAttributes = new HashAttributeSet(); + operationAttributes.addAll(AttributeHelper.jobOperationAttributes(attributes)); + operationAttributes.addAll(AttributeHelper.docOperationAttributes(doc)); + request.addOperationAttributes(operationAttributes); + //set the job template attributes + request.setJobAttributes(AttributeHelper.jobAttributes(attributes)); + IppResponse response = null; + try { + response = request.send(); + notifyJobListeners(PrintJobEvent.DATA_TRANSFER_COMPLETE); + } catch (IOException e) { + log.log(Level.SEVERE, e.getMessage(), e); + throw new PrintException("Error sending " + description(attributes) + " to IPP service: " + e.getMessage()); + } + if (response != null && response.getStatus()!=null) { + Map responseAttributes = response.getAttributes(); + updateAttributes(responseAttributes); + if (response.getStatus().equals(IppStatus.SUCCESSFUL_OK) + || response.getStatus().equals(IppStatus.SUCCESSFUL_OK_CONFLICTING_ATTRIBUTES) + || response.getStatus().equals(IppStatus.SUCCESSFUL_OK_IGNORED_OR_SUBSTITUTED_ATTRIBUTES)) { + if (responseAttributes.containsKey(IppAttributeName.JOB_URI.getCategory())) { + Set jobUriList = (Set) responseAttributes.get(IppAttributeName.JOB_URI.getCategory()); + this.jobUri = (JobUri) jobUriList.iterator().next(); + } + notifyJobListeners(PrintJobEvent.JOB_COMPLETE); + this.ok = true; + } else { + notifyJobListeners(PrintJobEvent.JOB_FAILED); + this.ok = false; + } + } else { + notifyJobListeners(PrintJobEvent.JOB_FAILED); + this.ok = false; + } + notifyJobListeners(PrintJobEvent.NO_MORE_EVENTS); + if (!this.ok){ + String msg = "Printing " + description(attributes) + " failed"; + if (response != null && response.getStatus()!=null) { + msg+=": Server status was '"+response.getStatus().getStatus()+" - "+response.getStatus().getText()+"'!"; + } + throw new PrintException(msg); + } + } + + + + public void addPrintJobListener(PrintJobListener listener) { + if (listener != null) { + if (jobListeners == null) { + jobListeners = new ArrayList(); + } + jobListeners.add(listener); + } + } + + public void removePrintJobListener(PrintJobListener listener) { + if (listener != null) { + jobListeners.remove(listener); + } + } + + public void addPrintJobAttributeListener(PrintJobAttributeListener listener, PrintJobAttributeSet attributes) { + if (listener != null) { + if (attributeListeners == null) { + attributeListeners = new HashMap(); + } + attributeListeners.put(listener, attributes); + } + } + + public void removePrintJobAttributeListener(PrintJobAttributeListener listener) { + if (listener != null) { + attributeListeners.remove(listener); + } + } + + void notifyJobListeners(int eventType) { + if (jobListeners != null) { + PrintJobEvent event = new PrintJobEvent(this, eventType); + for (Iterator iter = jobListeners.iterator(); iter.hasNext();) { + PrintJobListener listener = (PrintJobListener) iter.next(); + if (eventType == PrintJobEvent.DATA_TRANSFER_COMPLETE) { + listener.printDataTransferCompleted(event); + } else if (eventType == PrintJobEvent.JOB_CANCELED) { + listener.printJobCanceled(event); + } else if (eventType == PrintJobEvent.JOB_COMPLETE) { + listener.printJobCompleted(event); + } else if (eventType == PrintJobEvent.JOB_FAILED) { + listener.printJobFailed(event); + } else if (eventType == PrintJobEvent.NO_MORE_EVENTS) { + listener.printJobNoMoreEvents(event); + } else if (eventType == PrintJobEvent.REQUIRES_ATTENTION) { + listener.printJobRequiresAttention(event); + } + } + } + } + + IppResponse sendRequest(OperationsSupported operation, AttributeSet operationAttributes) throws IOException { + IppRequest request = this.request(operation); + request.addOperationAttributes(operationAttributes); + IppResponse response = null; + response = request.send(); + return response; + } + + private IppRequest request(OperationsSupported operation) { + IppRequest request = IppRequestFactory.createIppRequest(this.jobUri.getURI(), operation, this.printService.getRequestingUserName(), this.printService.getRequestingUserPassword()); + AttributeSet operationAttributes = new HashAttributeSet(); + operationAttributes.add(this.jobUri); + request.addOperationAttributes(operationAttributes); + return request; + } + + // public methods which are not part of the JPS API + /** + * + * This method returns the Job with the given JobId that is held by + * the given PrintService. + *
+ * This method might return a Job which is not hold by this PrintService + * but the same CUPS server + * + * @param service + * @param id + * @return the corresponding Job wihth the given JobId, or null if no such + * Job exists + * @throws PrintException + */ + static Job getJob(IppPrintService service, JobId id) throws PrintException { + Job job = new Job(service); + job.printService = service; + URI jobUri; + try { + jobUri = + new URI( + service.getUri().getScheme(), + service.getUri().getAuthority(), + "/jobs/" + id.getValue(), + service.getUri().getQuery(), + service.getUri().getFragment()); + } catch (URISyntaxException e) { + throw new PrintException("Internal bug.", e); + } + job.jobUri = new JobUri(jobUri); + try { + job.updateAttributes(); + } catch (IllegalStateException e) { + job = null; + } + return job; + } + + /** + * @param responseAttributes + */ + private void updateAttributes(Map responseAttributes) { + this.jobAttributes = new HashPrintJobAttributeSet(); + for (Iterator iter = responseAttributes.values().iterator(); iter.hasNext();) { + Set values = (Set) iter.next(); + for (Iterator listIter = values.iterator(); listIter.hasNext();) { + Attribute attribute = (Attribute) listIter.next(); + if (attribute instanceof PrintJobAttribute) + this.jobAttributes.add(attribute); + } + } + } + + /** + * Updates the Job's attributes to the current values. + * + * @throws PrintException + */ + private void updateAttributes() throws PrintException { + try { + AttributeSet operationAttributes = new HashAttributeSet(); + IppResponse response = sendRequest(OperationsSupported.GET_JOB_ATTRIBUTES, operationAttributes); + if (!response.getStatus().equals(IppStatus.SUCCESSFUL_OK) + && !response.getStatus().equals(IppStatus.SUCCESSFUL_OK_CONFLICTING_ATTRIBUTES) + && !response.getStatus().equals(IppStatus.SUCCESSFUL_OK_IGNORED_OR_SUBSTITUTED_ATTRIBUTES)) { + if (response.getStatus().equals(IppStatus.CLIENT_ERROR_NOT_FOUND)) { + throw new IllegalStateException("Job with uri '" + this.jobUri.toString() + "does not exist."); + } + throw new PrintException("Request not successful."); + } + Map attribsMap = response.getAttributes(); + updateAttributes(attribsMap); + + } catch (IOException e) { + throw new PrintException("Update failed.", e); + } + } + + private String description(PrintRequestAttributeSet attributes){ + String description = "job"; + if (attributes != null){ + Attribute jobName = attributes.get(IppAttributeName.JOB_NAME.getCategory()); + if (jobName != null){ + description += " " + jobName.toString(); + } + } + return description; + } +} diff --git a/jspi/src/main/java/de/lohndirekt/print/MediaMultiDoc.java b/jspi/src/main/java/de/lohndirekt/print/MediaMultiDoc.java new file mode 100644 index 0000000..d476a3b --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/MediaMultiDoc.java @@ -0,0 +1,51 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print; + +import javax.print.Doc; +import javax.print.attribute.standard.Media; + + + +/** + * @author bpusch + * + */ +class MediaMultiDoc extends SimpleMultiDoc { + + Media media = null; + + public static MediaMultiDoc create(Doc doc, Media media) { + + return new MediaMultiDoc(doc, media, false); + } + + public static SimpleMultiDoc create(Doc doc, Media media, boolean lastDoc) { + return new MediaMultiDoc(doc, media, lastDoc); + } + + /** + * + */ + private MediaMultiDoc(Doc doc, Media media, boolean lastDoc) { + super(doc,lastDoc); + this.media = media; + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/MediaMultiDocJob.java b/jspi/src/main/java/de/lohndirekt/print/MediaMultiDocJob.java new file mode 100644 index 0000000..1c43253 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/MediaMultiDocJob.java @@ -0,0 +1,33 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print; + +/** + * @author bpusch + * + */ +class MediaMultiDocJob extends MultiDocJob { + + /** + * @param service + */ + public MediaMultiDocJob(IppMultiDocPrintService service) { + super(service); + } +} diff --git a/jspi/src/main/java/de/lohndirekt/print/Messages.java b/jspi/src/main/java/de/lohndirekt/print/Messages.java new file mode 100644 index 0000000..f13b181 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/Messages.java @@ -0,0 +1,52 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print; + +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +/** + * @author ld-development + * + * + */ +public class Messages { + + private static final String BUNDLE_NAME = "de.lohndirekt.print.test"; //$NON-NLS-1$ + + private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle(BUNDLE_NAME); + + /** + * + */ + private Messages() { + + } + /** + * @param key + * @return + */ + public static String getString(String key) { + try { + return RESOURCE_BUNDLE.getString(key); + } catch (MissingResourceException e) { + return '!' + key + '!'; + } + } +} diff --git a/jspi/src/main/java/de/lohndirekt/print/MultiDocEvent.java b/jspi/src/main/java/de/lohndirekt/print/MultiDocEvent.java new file mode 100644 index 0000000..33880b6 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/MultiDocEvent.java @@ -0,0 +1,38 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +package de.lohndirekt.print; + +import javax.print.MultiDoc; +import javax.print.event.PrintEvent; + +/** + * @author bpusch + * + */ +class MultiDocEvent extends PrintEvent { + + /** + * + */ + public MultiDocEvent(MultiDoc source) { + super(source); + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/MultiDocJob.java b/jspi/src/main/java/de/lohndirekt/print/MultiDocJob.java new file mode 100644 index 0000000..a16a655 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/MultiDocJob.java @@ -0,0 +1,177 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Map; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.print.DocFlavor; +import javax.print.MultiDoc; +import javax.print.MultiDocPrintJob; +import javax.print.PrintException; +import javax.print.attribute.AttributeSet; +import javax.print.attribute.DocAttributeSet; +import javax.print.attribute.HashAttributeSet; +import javax.print.attribute.PrintRequestAttributeSet; +import javax.print.event.PrintJobEvent; + +import de.lohndirekt.print.attribute.AttributeHelper; +import de.lohndirekt.print.attribute.IppAttributeName; +import de.lohndirekt.print.attribute.IppStatus; +import de.lohndirekt.print.attribute.ipp.jobdesc.JobUri; +import de.lohndirekt.print.attribute.ipp.printerdesc.supported.OperationsSupported; +/** + * @author bpusch + * + */ +class MultiDocJob extends Job implements MultiDocPrintJob { + + Logger log = Logger.getLogger(this.getClass().getName()); + + /** + * + */ + protected MultiDocJob(IppMultiDocPrintService service) { + super(service); + } + + void processMultiDocEvent(MultiDocEvent event) { + SimpleMultiDoc doc = (SimpleMultiDoc) event.getSource(); + sendDocument(doc); + } + + /** + * + */ + public void print(MultiDoc multiDoc, PrintRequestAttributeSet attributes) throws PrintException { + SimpleMultiDoc multi = (SimpleMultiDoc) multiDoc; + multi.addMultiDocListener(new MDListener()); + createJob(attributes); + sendDocument(multi); + } + + private void createJob(PrintRequestAttributeSet attributes) { + IppRequest request = null; + request = this.printService.request(OperationsSupported.CREATE_JOB); + //add the operationn attributes + request.addOperationAttributes(AttributeHelper.jobOperationAttributes(attributes)); + request.setJobAttributes(AttributeHelper.jobAttributes(attributes)); + IppResponse response = null; + try { + response = request.send(); + } catch (IOException e) { + log.log(Level.SEVERE, e.getMessage(), e); + } + if (response != null) { + Map responseAttributes = response.getAttributes(); + if (responseAttributes.containsKey(IppAttributeName.JOB_URI.getCategory())) { + Set jobUriSet = (Set) responseAttributes.get(IppAttributeName.JOB_URI.getCategory()); + this.jobUri = (JobUri) jobUriSet.iterator().next(); + } + if (response.getStatus().equals(IppStatus.SUCCESSFUL_OK) + || response.getStatus().equals(IppStatus.SUCCESSFUL_OK_CONFLICTING_ATTRIBUTES) + || response.getStatus().equals(IppStatus.SUCCESSFUL_OK_CONFLICTING_ATTRIBUTES)) { + } else { + notifyJobListeners(PrintJobEvent.JOB_FAILED); + } + } else { + notifyJobListeners(PrintJobEvent.JOB_FAILED); + } + } + + protected void sendDocument(SimpleMultiDoc multiDoc) { + IppRequest request = null; + AttributeSet operationAttributes = new HashAttributeSet(); + request = this.request(OperationsSupported.SEND_DOCUMENT); + IppResponse response = null; + try { + operationAttributes.addAll(AttributeHelper.docOperationAttributes(multiDoc)); + request.addOperationAttributes(operationAttributes); + if (multiDoc.getDoc().getDocFlavor() instanceof DocFlavor.INPUT_STREAM) { + DocAttributeSet set = multiDoc.getDoc().getAttributes(); + request.setData((InputStream) multiDoc.getDoc().getPrintData()); + } + response = request.send(); + } catch (IOException e) { + log.log(Level.SEVERE, e.getMessage(), e); + } + if (response != null) { + Map responseAttributes = response.getAttributes(); + if (responseAttributes.containsKey(IppAttributeName.JOB_URI.getCategory())) { + Set jobUriSet = (Set) responseAttributes.get(IppAttributeName.JOB_URI.getCategory()); + this.jobUri = (JobUri) jobUriSet.iterator().next(); + } + if (response.getStatus().equals(IppStatus.SUCCESSFUL_OK) + || response.getStatus().equals(IppStatus.SUCCESSFUL_OK_CONFLICTING_ATTRIBUTES) + || response.getStatus().equals(IppStatus.SUCCESSFUL_OK_CONFLICTING_ATTRIBUTES)) { + } else { + notifyJobListeners(PrintJobEvent.JOB_FAILED); + } + } else { + notifyJobListeners(PrintJobEvent.JOB_FAILED); + } + if (multiDoc.isLast()) { + releaseJob(); + } + } + + /** + * + */ + private void releaseJob() { + IppRequest request = this.request(OperationsSupported.RELEASE_JOB); + IppResponse response = null; + try { + response = request.send(); + + } catch (IOException e) { + log.log(Level.SEVERE, e.getMessage(), e); + } + if (response != null) { + if (response.getStatus().equals(IppStatus.SUCCESSFUL_OK) + || response.getStatus().equals(IppStatus.SUCCESSFUL_OK_CONFLICTING_ATTRIBUTES) + || response.getStatus().equals(IppStatus.SUCCESSFUL_OK_CONFLICTING_ATTRIBUTES)) { + notifyJobListeners(PrintJobEvent.JOB_COMPLETE); + } else { + notifyJobListeners(PrintJobEvent.JOB_FAILED); + } + } else { + notifyJobListeners(PrintJobEvent.JOB_FAILED); + } + } + + private IppRequest request(OperationsSupported operation) { + IppRequest request = IppRequestFactory.createIppRequest(this.jobUri.getURI(), operation, this.printService.getRequestingUserName(), this.printService.getRequestingUserPassword()); + AttributeSet operationAttributes = new HashAttributeSet(); + operationAttributes.add(new JobUri(this.jobUri.getURI())); + request.addOperationAttributes(operationAttributes); + return request; + } + + private class MDListener implements MultiDocListener { + public void processEvent(MultiDocEvent event) throws IOException { + log.log(Level.FINEST, "MultiDocevent"); + processMultiDocEvent(event); + } + } +} diff --git a/jspi/src/main/java/de/lohndirekt/print/MultiDocListener.java b/jspi/src/main/java/de/lohndirekt/print/MultiDocListener.java new file mode 100644 index 0000000..5372dee --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/MultiDocListener.java @@ -0,0 +1,35 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +package de.lohndirekt.print; + +import java.io.IOException; + + + +/** + * @author bpusch + * + */ +interface MultiDocListener { + + + public void processEvent(MultiDocEvent event) throws IOException; + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/SimpleMultiDoc.java b/jspi/src/main/java/de/lohndirekt/print/SimpleMultiDoc.java new file mode 100644 index 0000000..4146418 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/SimpleMultiDoc.java @@ -0,0 +1,135 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import javax.print.Doc; +import javax.print.MultiDoc; + +/** + * @author bpusch + * + */ +public class SimpleMultiDoc implements MultiDoc { + + private List listeners; + Doc doc = null; + boolean lastDoc = false; + SimpleMultiDoc next = null; + + public static SimpleMultiDoc create(Doc doc) { + return new SimpleMultiDoc(doc, false); + } + + public static SimpleMultiDoc create(Doc doc, boolean lastDoc) { + return new SimpleMultiDoc(doc, lastDoc); + } + + /** + * + */ + protected SimpleMultiDoc(Doc doc, boolean lastDoc) { + if (doc == null) { + throw new NullPointerException("Doc must not be null"); + } + this.doc = doc; + this.lastDoc = lastDoc; + } + + /** + * Adds a new MultiDoc. + * If the next MultiDoc has already been set, it tries to add it there + * + * @param doc + * @param lastDoc + * @throws IllegalStateException if this has already been the last Document + */ + public void setNext(Doc doc, boolean lastDoc) { + if (this.lastDoc) { + throw new IllegalStateException("Last Doc already sent"); + } + if (doc == null) { + throw new NullPointerException("Doc must not be null"); + } + if (next == null) { + this.next = new SimpleMultiDoc(doc, lastDoc); + } else { + this.next.setNext(doc, lastDoc); + } + this.notifyListeners(); + } + + public void setNext(Doc doc) { + setNext(doc, false); + } + + /** + * + */ + + public Doc getDoc() throws IOException { + return this.doc; + } + + /** + * + */ + public MultiDoc next() throws IOException { + if (!this.available()) { + throw new IllegalStateException("Next MultiDoc is not yet available"); + } + return this.next; + } + + public boolean available() { + return (!this.lastDoc && this.next != null); + } + + public boolean isLast() { + return lastDoc; + } + + public String toString() { + return this.getClass() + " - " + this.doc.toString(); + } + + public void addMultiDocListener(MultiDocListener listener) { + if (this.listeners == null) { + this.listeners = new ArrayList(); + } + this.listeners.add(listener); + } + + private void notifyListeners() { + if (this.listeners != null) { + for (Iterator iter = this.listeners.iterator(); iter.hasNext();) { + MultiDocListener listener = (MultiDocListener) iter.next(); + try { + listener.processEvent(new MultiDocEvent(this.next)); + } catch (IOException e) { + //TODO handle exception appropriatly + } + } + } + } +} diff --git a/jspi/src/main/java/de/lohndirekt/print/TestJarLookup.java b/jspi/src/main/java/de/lohndirekt/print/TestJarLookup.java new file mode 100644 index 0000000..5eb784a --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/TestJarLookup.java @@ -0,0 +1,46 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print; + +import java.net.URI; +import java.net.URISyntaxException; + +import javax.print.PrintService; + +import de.lohndirekt.print.IppPrintServiceLookup; + +/** + * @author sefftinge + * + */ +public class TestJarLookup { + + public static void main(String[] args) throws URISyntaxException { + System.getProperties().setProperty("de.lohndirekt.print.IppPrintService.uri", "192.168.0.60:631"); + testServices(); + } + + private static void testServices() throws URISyntaxException { + PrintService[] services = new IppPrintServiceLookup(new URI("ipp://192.168.0.60:631"),"username","password").getPrintServices(); + for (int i = 0; i < services.length; i++) { + PrintService service = services[i]; + System.out.println(service.getName()); + } + } +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/AttributeHelper.java b/jspi/src/main/java/de/lohndirekt/print/attribute/AttributeHelper.java new file mode 100644 index 0000000..96db01b --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/AttributeHelper.java @@ -0,0 +1,168 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute; + +import java.io.IOException; +import java.util.Locale; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.print.Doc; +import javax.print.attribute.Attribute; +import javax.print.attribute.AttributeSet; +import javax.print.attribute.HashAttributeSet; +import javax.print.attribute.HashPrintJobAttributeSet; +import javax.print.attribute.PrintJobAttribute; +import javax.print.attribute.PrintJobAttributeSet; +import javax.print.attribute.PrintRequestAttributeSet; +import javax.print.attribute.standard.DocumentName; + +import de.lohndirekt.print.SimpleMultiDoc; +import de.lohndirekt.print.attribute.ipp.DocumentFormat; +import de.lohndirekt.print.attribute.ipp.LastDocument; + +/** + * @author ld-development + * + * + */ +public final class AttributeHelper { + + private final static Logger log = Logger.getLogger(AttributeHelper.class.getName()); + /** + * filters the given attributes + * + * @param attributes + * @return only the attributes wich are of type PrintJobAttribute and not operation attributes + */ + public final static PrintJobAttributeSet jobAttributes(PrintRequestAttributeSet attributes) { + PrintJobAttributeSet jobAttributes = new HashPrintJobAttributeSet(); + if (attributes != null) { + AttributeSet invalidAttributes = jobOperationAttributes(attributes); + Object[] attributeArray = attributes.toArray(); + for (int i = 0; i < attributeArray.length; i++) { + Attribute attribute = (Attribute) attributeArray[i]; + //attributes-charset, attributes-natural-language etc. are not set by the user + if (attribute instanceof PrintJobAttribute && !(invalidAttributes.containsValue(attribute))) { + jobAttributes.add(attribute); + } + } + } + return jobAttributes; + } + + /** + * filters the given attributes + * + * @param attributes + * @return only job-operation attributes + */ + public final static AttributeSet jobOperationAttributes(PrintRequestAttributeSet attributes) { + AttributeSet operationAttributes = new HashAttributeSet(); + if (attributes != null) { + Object[] attributeArray = attributes.toArray(); + for (int i = 0; i < attributeArray.length; i++) { + Attribute attribute = (Attribute) attributeArray[i]; + //attributes-charset, attributes-natural-language etc. are not set by the user + if (attribute.getCategory().equals(IppAttributeName.JOB_NAME.getCategory()) + || attribute.getCategory().equals(IppAttributeName.FIDELITY.getCategory()) + || attribute.getCategory().equals(IppAttributeName.JOB_IMPRESSIONS.getCategory()) + || attribute.getCategory().equals(IppAttributeName.JOB_K_OCTETS.getCategory()) + || attribute.getCategory().equals(IppAttributeName.JOB_MEDIA_SHEETS.getCategory()) + || attribute.getCategory().equals(IppAttributeName.JOB_NAME.getCategory()) + || attribute.getCategory().equals(IppAttributeName.COMPRESSION.getCategory()) + || attribute.getCategory().equals(IppAttributeName.REQUESTING_USER_NAME.getCategory()) + || attribute.getCategory().equals(IppAttributeName.REQUESTING_USER_PASSWD.getCategory())) { + operationAttributes.add(attribute); + } + } + } + return operationAttributes; + } + + /** + * @param multiDoc + * @return a List with the document-format, document-name and last-document + */ + public final static AttributeSet docOperationAttributes(SimpleMultiDoc multiDoc) { + AttributeSet operationAttributes = new HashAttributeSet(); + try { + operationAttributes = docOperationAttributes(multiDoc.getDoc()); + } catch (IOException e) { + log.log(Level.SEVERE, "Could not get Doc from multiDoc", e); + } + LastDocument lastDocument; + if (multiDoc.isLast()) { + lastDocument = LastDocument.TRUE; + } else { + lastDocument = LastDocument.FALSE; + } + operationAttributes.add(lastDocument); + return operationAttributes; + } + + /** + * @param doc + * @return a List with the document-format and document-name + */ + public final static AttributeSet docOperationAttributes(Doc doc) { + AttributeSet operationAttributes = new HashAttributeSet(); + if (doc.getAttributes() != null) { + DocumentName docName = (DocumentName) doc.getAttributes().get(IppAttributeName.DOCUMENT_NAME.getCategory()); + if (docName != null) { + operationAttributes.add(docName); + } + } + operationAttributes.add(new DocumentFormat(doc.getDocFlavor().getMimeType(), Locale.getDefault())); + return operationAttributes; + } + + /** + * @param operationAttributes2 + * @return + */ + public final static Attribute[] getOrderedOperationAttributeArray(AttributeSet operationAttributes2) { + AttributeSet copy = new HashAttributeSet(operationAttributes2); + Attribute[] attributes = new Attribute[copy.size()]; + int i = 0; + // start with Charset + Class category = IppAttributeName.CHARSET.getCategory(); + if (copy.containsKey(category)) { + attributes[i] = copy.get(category); + copy.remove(category); + i++; + } + // start with Charset + category = IppAttributeName.NATURAL_LANGUAGE.getCategory(); + if (copy.containsKey(category)) { + attributes[i] = copy.get(category); + copy.remove(category); + i++; + } + // add the rest + Attribute[] remaining = copy.toArray(); + for (int j = 0; j < remaining.length; j++) { + attributes[i+j] = remaining[j]; + } + return attributes; + } + + + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/AttributeParser.java b/jspi/src/main/java/de/lohndirekt/print/attribute/AttributeParser.java new file mode 100644 index 0000000..203c6ab --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/AttributeParser.java @@ -0,0 +1,488 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute; + +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.net.URI; +import java.net.URISyntaxException; +import java.text.DateFormat; +import java.text.DecimalFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Locale; +import java.util.Map; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.print.attribute.Attribute; +import javax.print.attribute.EnumSyntax; +import javax.print.attribute.standard.JobStateReason; +import javax.print.attribute.standard.JobStateReasons; +import javax.print.attribute.standard.PrinterStateReason; +import javax.print.attribute.standard.PrinterStateReasons; +import javax.print.attribute.standard.Severity; + +import de.lohndirekt.print.attribute.ipp.Charset; +import de.lohndirekt.print.attribute.ipp.jobdesc.LdJobStateReason; +import de.lohndirekt.print.exception.EndOfAttributesException; + +/** + * @author bpusch + * + */ +public final class AttributeParser { + + private final static EndOfAttributesException END_OF_ATTRIBUTES_EXCEPTION = new EndOfAttributesException(); + + private final static Logger log = Logger.getLogger(AttributeParser.class.getName()); + + + + /** + * @param name + * @param values + * @return + */ + private static Attribute getAttribute(String name, Object[] values) { + Attribute attribute = null; + IppAttributeName attrName = IppAttributeName.get(name); + Class attrClass = attrName.getAttributeClass(); + Class superClass = attrClass.getSuperclass(); + if (superClass != null) { + if (superClass.equals(EnumSyntax.class)) { + try { + Field[] fields = attrClass.getDeclaredFields(); + for (int i = 0; i < fields.length; i++) { + Field field = fields[i]; + if (field.getType().equals(attrClass)) { + EnumSyntax attr = (EnumSyntax) field.get(null); + if (values[0] instanceof String) { + if (attr.toString().equals(values[0])) { + attribute = (Attribute) attr; + break; + } + } else { + if (attr.getValue() == ((Integer) values[0]).intValue()) { + attribute = (Attribute) attr; + break; + } + } + } + } + } catch (SecurityException e) { + log.log(Level.SEVERE, e.getMessage(), e); + } catch (IllegalArgumentException e) { + log.log(Level.SEVERE, e.getMessage(), e); + } catch (IllegalAccessException e) { + log.log(Level.SEVERE, e.getMessage(), e); + } + + } else { + Class[] parameters = toClassArray(values); + try { + Constructor constructor = attrClass.getDeclaredConstructor(parameters); + attribute = (Attribute) constructor.newInstance(values); + } catch (SecurityException e) { + log.log(Level.SEVERE, e.getMessage(), e); + } catch (NoSuchMethodException e) { + log.log(Level.SEVERE, e.getMessage(), e); + } catch (IllegalArgumentException e) { + log.log(Level.SEVERE, e.getMessage(), e); + } catch (InstantiationException e) { + log.log(Level.SEVERE, e.getMessage(), e); + } catch (IllegalAccessException e) { + log.log(Level.SEVERE, e.getMessage(), e); + } catch (InvocationTargetException e) { + log.log(Level.SEVERE, e.getMessage(), e); + } + } + } + + return attribute; + } + + /** + * @param byteArray + * @param byteCount + * @param lastAttribute + * @return + */ + private static Attribute parseAttribute(InputStream in, Attribute lastAttribute) + throws IOException, EndOfAttributesException { + + int valueTag; + while ((valueTag = in.read()) < IppValueTag.UNSUPPORTED_VALUE.getValue()) { + if (valueTag == IppDelimiterTag.END_ATTRIBUTES.getValue()) { + throw END_OF_ATTRIBUTES_EXCEPTION; + } + } + + int nameLength = parseInt2(in); + // parse the Attribute-Name + String name; + if (nameLength == 0) { + name = lastAttribute.getName(); + } else { + name = parseString(in, nameLength); + } + + + Object[] values = parseValues(valueTag, in); + + if (name.equals(IppAttributeName.PRINTER_STATE_REASONS.getName())) { + return parsePrinterStateReasons((String) values[0], lastAttribute); + } else if (name.equals(IppAttributeName.JOB_STATE_REASONS.getName())) { + return parseJobStateReasons(values, lastAttribute); + } else { + return getAttribute(name, values); + } + } + + private static String parseString(InputStream in, int nameLength) throws IOException{ + return parseString(in, nameLength, Charset.US_ASCII.getValue()); + } + + private static String parseNameAndTextString(InputStream in, int nameLength) throws IOException{ + return parseString(in, nameLength, AttributeWriter.DEFAULT_CHARSET.getValue()); + } + + /** + * @param in + * @param nameLength + */ + private static String parseString(InputStream in, int nameLength, String charsetName) throws IOException { + byte[] bytes = new byte[nameLength]; + in.read(bytes); + return new String(bytes, charsetName); + + } + + + + + /** + * @param byteArray + * @param valueOffset + * @return + */ + private static Date parseDate(InputStream in) throws IOException { + DecimalFormat twoDigits = new DecimalFormat("00"); + DecimalFormat threeDigits = new DecimalFormat("000"); + DecimalFormat fourDigits = new DecimalFormat("0000"); + //year is encoded in network-byte order + int year = parseInt2(in); + int month = in.read(); + int day = in.read(); + int hour = in.read(); + int minute = in.read(); + int second = in.read(); + int deci = in.read(); + int mili = deci * 100; + char direction = (char) in.read(); + int hoursFromUtc = (int) in.read(); + int minutesFromUtc = (int) in.read(); + + String yearString = fourDigits.format((long) year); + String monthString = twoDigits.format((long) month); + String dayString = twoDigits.format((long) day); + String hourString = twoDigits.format((long) hour); + String minuteString = twoDigits.format((long) minute); + String secondString = twoDigits.format((long) second); + String miliString = threeDigits.format((long) mili); + String timeZone = direction + twoDigits.format((long) hoursFromUtc) + twoDigits.format((long) minutesFromUtc); + String dateString = + yearString + + "-" + + monthString + + "-" + + dayString + + " " + + hourString + + ":" + + minuteString + + ":" + + secondString + + ":" + + miliString + + timeZone; + DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSSZ"); + Date date = null; + try { + date = dateFormat.parse(dateString); + } catch (ParseException e) { + log.log(Level.SEVERE, e.getMessage(), e); + } + return date; + } + + private static int parseInt4(InputStream in) throws IOException { + + //Same parsing as in java.io.DataInput readInt() + int a = in.read(); + int b = in.read(); + int c = in.read(); + int d = in.read(); + int value = (((a & 0xff) << 24) | ((b & 0xff) << 16) | ((c & 0xff) << 8) | (d & 0xff)); + return value; + } + + /** + * @param bytes + * @param offset + * @return + */ + private static int parseInt4(byte[] bytes, int offset) { + + //Same parsing as in java.io.DataInput readInt() + byte a = bytes[offset++]; + byte b = bytes[offset++]; + byte c = bytes[offset++]; + byte d = bytes[offset++]; + int value = (((a & 0xff) << 24) | ((b & 0xff) << 16) | ((c & 0xff) << 8) | (d & 0xff)); + return value; + } + + private static int parseInt2(InputStream in) throws IOException { + + //Same parsing as in java.io.DataInput readInt() + int a = in.read(); + int b = in.read(); + int value = ((a & 0xff) << 8) | ((b & 0xff)); + return value; + } + + + + /** + * @param string + * @param lastAttribute + * @return + */ + private static Attribute parseJobStateReasons(Object[] values, Attribute lastAttribute) { + JobStateReasons reasons; + if (lastAttribute instanceof JobStateReasons) { + reasons = (JobStateReasons) lastAttribute; + } else { + reasons = new JobStateReasons(); + } + JobStateReason reason = null; + if (values[0].equals(LdJobStateReason.NONE.toString())) { + reason = LdJobStateReason.NONE; + } else { + reason = (JobStateReason) getAttribute(IppAttributeName.JOB_STATE_REASON.getName(), values); + } + reasons.add(reason); + return reasons; + } + + /** + * @param reasonAndSeverity + * @param lastAttribute + * @return + */ + private static PrinterStateReasons parsePrinterStateReasons(String reasonAndSeverity, Attribute lastAttribute) { + Severity severity = null; + int severityOffset = 0; + if ((severityOffset = reasonAndSeverity.indexOf(Severity.ERROR.toString())) > 0) { + severity = Severity.ERROR; + } else if ((severityOffset = reasonAndSeverity.indexOf(Severity.REPORT.toString())) > 0) { + severity = Severity.REPORT; + } else if ((severityOffset = reasonAndSeverity.indexOf(Severity.WARNING.toString())) > 0) { + severity = Severity.WARNING; + } + String reasonString; + if (severityOffset != -1) { + //subtract 1 for the hyphen + severityOffset--; + reasonString = reasonAndSeverity.substring(0, severityOffset - 1); + } else { + reasonString = reasonAndSeverity; + } + Object[] values = new Object[] { reasonString }; + PrinterStateReason reason = + (PrinterStateReason) getAttribute(IppAttributeName.PRINTER_STATE_REASON.getName(), values); + PrinterStateReasons reasons; + if (lastAttribute instanceof PrinterStateReasons) { + reasons = (PrinterStateReasons) lastAttribute; + } else { + reasons = new PrinterStateReasons(); + } + if (reason != null) { + if (severity == null) { + severity = Severity.ERROR; + } + reasons.put(reason, severity); + } + return reasons; + } + + /** + * @param bytes + * @return map of attributes (key -> category, value -> Set with attributes) + * + * + */ + public static Map parseResponse(InputStream response) throws IOException { + Map attributes = new HashMap(); + long start = System.currentTimeMillis(); + Attribute lastAttribute = null; + boolean finished = false; + response.read(); + + while (!finished) { + Attribute attribute = null; + try { + attribute = parseAttribute(response, lastAttribute); + if (attribute != null) { + lastAttribute = attribute; + attributes = put(attributes, attribute); + if (log.isLoggable(Level.FINEST)) { + log.finest("parsed attribute(" + attribute.getName() + "): " + attribute.toString()); + } + } else { + if (log.isLoggable(Level.FINEST)) { + + log.finest("Attribute was null"); + } + } + } catch (EndOfAttributesException e) { + + finished = true; + if (log.isLoggable(Level.INFO)) { + log.info("--- Attribute parsing finished ---"); + } + } + } + long end = System.currentTimeMillis(); + if (log.isLoggable(Level.INFO)) { + log.info("Parsing took " + (end - start) + "ms."); + } + return attributes; + } + + + /** + * @param byteArray + * @param valueOffset + * @param valueLength + * @return + */ + private static URI parseUri(InputStream in, int valueLength) throws IOException { + String uriString = parseString(in, valueLength); + URI uri = null; + try { + uri = new URI(uriString); + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } + return uri; + } + + + /** + * @param valueTag + * @param byteArray + * @param valueOffset + * @param valueLength + * @return + */ + private static Object[] parseValues(int valueTag, InputStream in) throws IOException { + int valueLength = parseInt2(in); + Object[] values = null; + if (valueTag == IppValueTag.INTEGER.getValue() || valueTag == IppValueTag.ENUM.getValue()) { + Integer number = new Integer(parseInt4(in)); + values = new Object[] { number }; + } else if ( + valueTag == IppValueTag.STRING.getValue() + || valueTag == IppValueTag.TEXT.getValue() + || valueTag == IppValueTag.NAME.getValue()){ + String word = parseNameAndTextString(in, valueLength); + values = new Object[] { word, Locale.getDefault()}; + } else if ( + valueTag == IppValueTag.CHARSET.getValue() + || valueTag == IppValueTag.LANGUAGE.getValue() + || valueTag == IppValueTag.MIMETYPE.getValue()) { + String word = parseString(in, valueLength); + values = new Object[] { word, Locale.getDefault()}; + } else if (valueTag == IppValueTag.URI.getValue()) { + URI uri = parseUri(in, valueLength); + values = new Object[] { uri }; + } else if (valueTag == IppValueTag.KEYWORD.getValue()) { + String word = parseString(in, valueLength); + values = new Object[] { word, Locale.getDefault()}; + } else if (valueTag == IppValueTag.BOOLEAN.getValue()) { + Integer bool = new Integer(in.read()); + values = new Object[] { bool }; + } else if (valueTag == IppValueTag.RANGE.getValue()) { + Integer lowerBound = new Integer(parseInt4(in)); + Integer upperBound = new Integer(parseInt4(in)); + values = new Object[] { lowerBound, upperBound }; + } else if (valueTag == IppValueTag.DATE.getValue()) { + + Date date = parseDate(in); + values = new Object[] { date }; + } else if (valueTag == IppValueTag.NOVALUE.getValue()) { + values = new Object[] { + }; + } else { + throw new IllegalArgumentException("\"" + Integer.toHexString(valueTag) + "\" is not a valid value-tag"); + } + return values; + } + + + /** + * @param attributes + * @param attribute + */ + private static Map put(Map attributes, Attribute attribute) { + Set values = (Set) attributes.get(attribute.getCategory()); + if (values == null) { + values = new HashSet(); + attributes.put(attribute.getCategory(), values); + } + values.add(attribute); + return attributes; + } + + /** + * @param values + * @return + */ + private static Class[] toClassArray(Object[] values) { + Class[] classes = new Class[values.length]; + for (int i = 0; i < values.length; i++) { + Class clazz = values[i].getClass(); + if (clazz.equals(Integer.class)) { + clazz = int.class; + } + classes[i] = clazz; + } + return classes; + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/AttributeWriter.java b/jspi/src/main/java/de/lohndirekt/print/attribute/AttributeWriter.java new file mode 100644 index 0000000..163dfba --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/AttributeWriter.java @@ -0,0 +1,290 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute; + +import java.io.ByteArrayOutputStream; +import java.io.UnsupportedEncodingException; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.HashMap; +import java.util.Map; +import java.util.TimeZone; + +import javax.print.attribute.Attribute; +import javax.print.attribute.DateTimeSyntax; +import javax.print.attribute.EnumSyntax; +import javax.print.attribute.IntegerSyntax; +import javax.print.attribute.ResolutionSyntax; +import javax.print.attribute.SetOfIntegerSyntax; +import javax.print.attribute.TextSyntax; +import javax.print.attribute.URISyntax; + +import de.lohndirekt.print.attribute.ipp.Charset; +import de.lohndirekt.print.attribute.ipp.NaturalLanguage; + +public final class AttributeWriter { + + private final static int MILIS_IN_MINUTE = 1000*60; + private final static int MILIS_IN_HOUR =MILIS_IN_MINUTE*60; + private static Map encodings = new HashMap(); + + public final static Charset DEFAULT_CHARSET = Charset.ISO_8859_1; + + /** + * @param bytes + * @param byteNr + * @param attribute + * @return + */ + private static void fillName(ByteArrayOutputStream out, Attribute attribute) { + String name = attribute.getName(); + fillName(out, name); + } + + private static void fillName(ByteArrayOutputStream out, String name) { + //name length + writeInt2(name.length(), out); + //name of attribute + writeString(name, out); + + } + + /** + * @param attribute + * @param bytes + * @return + */ + private static void attributeBytes(IntegerSyntax attribute, ByteArrayOutputStream out) { + //value tag + out.write((byte) IppValueTag.INTEGER.getValue()); + //name + fillName(out, (Attribute) attribute); + //value length (always 4 bytes) + writeInt2(4, out); + //value + writeInt4(attribute.getValue(), out); + } + + /** + * @param attribute + * @param bytes + * @return + */ + private static void attributeBytes(SetOfIntegerSyntax attribute, ByteArrayOutputStream out) { + int[][] members = attribute.getMembers(); + for (int i = 0; i < members.length; i++) { + int[] range = members[i]; + int lowerBound = range[0]; + int upperBound = range[1]; + + //value tag + out.write((byte) IppValueTag.RANGE.getValue()); + //name + if (i == 0) { + fillName(out, (Attribute) attribute); + } else { + fillName(out, ""); + } + //value length (always 8 bytes) + writeInt2(8, out); + + //(Lower bound first)Integer in 4 bytes + writeInt4(lowerBound, out); + //(Upper bound)Integer in 4 bytes + writeInt4(upperBound, out); + } + } + /** + * @param attribute + * @param bytes + * @return + */ + private static void attributeBytes(TextSyntax attribute, ByteArrayOutputStream out) { + // value tag + if (attribute instanceof Charset) { + out.write((byte) IppValueTag.CHARSET.getValue()); + } else if (attribute instanceof NaturalLanguage) { + out.write((byte) IppValueTag.LANGUAGE.getValue()); + } else { + out.write((byte) IppValueTag.NAME.getValue()); + } + //name + fillName(out, (Attribute) attribute); + //value length + writeInt2(attribute.toString().length(), out); + writeNameAndTextString(attribute.toString(), out); + } + + /** + * @param attribute + * @param bytes + * @return + */ + private static void attributeBytes(EnumSyntax attribute, ByteArrayOutputStream out) { + // Value tag + out.write((byte) IppValueTag.TEXT.getValue()); + // Name + fillName(out, (Attribute) attribute); + // value length + writeInt2(attribute.toString().length(), out); + writeString(attribute.toString(), out); + } + + /** + * + * uses UTC time, not local time zone to encode the date + * + * @param attribute + * @param bytes + * @return + */ + private static void attributeBytes(DateTimeSyntax attribute, ByteArrayOutputStream out) { + + + //Value tag + out.write((byte) IppValueTag.DATE.getValue()); + //Name + fillName(out, (Attribute) attribute); + //Value length (always 11 bytes) + writeInt2(11, out); + + Date date = attribute.getValue(); + TimeZone zone = TimeZone.getTimeZone("UTC"); + Calendar cal = new GregorianCalendar(zone); + cal.setTime(date); + + int year = cal.get(GregorianCalendar.YEAR); + int month = cal.get(Calendar.MONTH) + 1; + int day = cal.get(Calendar.DAY_OF_MONTH); + int hour = cal.get(Calendar.HOUR_OF_DAY); + int minute = cal.get(Calendar.MINUTE); + int second = cal.get(Calendar.SECOND); + int deci = cal.get(Calendar.MILLISECOND) / 100; + int offset = zone.getOffset(cal.getTimeInMillis()); + int hoursFromUtc = offset / MILIS_IN_HOUR; + int minutesFromUtc = offset % MILIS_IN_HOUR / MILIS_IN_MINUTE; + char direction = '+'; + if (hoursFromUtc < 0) { + direction = '-'; + hoursFromUtc *= -1; + } + writeInt2(year, out); + out.write((byte) month); + out.write((byte) day); + out.write((byte) hour); + out.write((byte) minute); + out.write((byte) second); + out.write((byte) deci); + out.write((byte) direction); + out.write((byte) hoursFromUtc); + out.write((byte) minutesFromUtc); + } + /** + * @param attribute + * @param bytes + * @return + */ + private static void attributeBytes(URISyntax attribute, ByteArrayOutputStream out) { + //Value tag + out.write((byte) IppValueTag.URI.getValue()); + //Name + fillName(out, (Attribute) attribute); + //value length + writeInt2(attribute.toString().length(), out); + writeString(attribute.toString(), out); + } + + /** + * @param attribute + * @param bytes + * @return + */ + private static void attributeBytes(ResolutionSyntax attribute, ByteArrayOutputStream out) { + //Value tag + out.write((byte) IppValueTag.INTEGER.getValue()); + //Name + fillName(out, (Attribute) attribute); + //Value length (always 9) + out.write((byte) 0); + out.write((byte) 9); + int feedResolution = attribute.getFeedResolution(ResolutionSyntax.DPI); + int crossFeedResolution = attribute.getCrossFeedResolution(ResolutionSyntax.DPI); + //(Lower bound first)Integer in 4 bytes + writeInt4(crossFeedResolution, out); + //(Upper bound)Integer in 4 bytes + writeInt4(feedResolution, out); + out.write((byte) ResolutionSyntax.DPI); + } + + public static void writeInt4(int value, ByteArrayOutputStream out){ + out.write((byte) ((value & 0xff000000) >> 24)); + out.write((byte) ((value & 0xff0000) >> 16)); + out.write((byte) ((value & 0xff00) >> 8)); + out.write((byte) (value & 0xff)); + } + + public static void writeInt2(int value, ByteArrayOutputStream out){ + out.write((byte) ((value & 0xff00) >> 8)); + out.write((byte) (value & 0xff)); + } + + public static void writeString(String value, ByteArrayOutputStream out, String charsetName) { + byte[] bytes; + try { + bytes = value.getBytes(charsetName); + } catch (UnsupportedEncodingException e) { + throw new IllegalArgumentException(charsetName + " encoding not supported by JVM"); + } + out.write(bytes, 0, bytes.length); + } + + public static void writeString(String value, ByteArrayOutputStream out){ + writeString(value, out, Charset.US_ASCII.getValue()); + } + + public static void writeNameAndTextString(String value, ByteArrayOutputStream out) { + writeString(value, out, DEFAULT_CHARSET.getValue()); + } + + /** + * @param attribute + * @return + */ + public static void attributeBytes(Attribute attribute, ByteArrayOutputStream out) { + if (attribute instanceof IntegerSyntax) { + attributeBytes((IntegerSyntax) attribute, out); + } else if (attribute instanceof TextSyntax) { + attributeBytes((TextSyntax) attribute, out); + } else if (attribute instanceof DateTimeSyntax) { + attributeBytes((DateTimeSyntax) attribute, out); + } else if (attribute instanceof ResolutionSyntax) { + attributeBytes((ResolutionSyntax) attribute, out); + } else if (attribute instanceof SetOfIntegerSyntax) { + attributeBytes((SetOfIntegerSyntax) attribute, out); + } else if (attribute instanceof EnumSyntax) { + attributeBytes((EnumSyntax) attribute, out); + } else if (attribute instanceof URISyntax) { + attributeBytes((URISyntax) attribute, out); + } else { + throw new IllegalArgumentException("The given attribute is of an unknown SubType (only IntegerSyntax, TextSyntax, DateTimeSyntax, ResolutionSyntax, SetOfIntegerSyntax, EnumSyntax and URISyntax supported)"); + } + } + +} \ No newline at end of file diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/AttributeWriterTest.java b/jspi/src/main/java/de/lohndirekt/print/attribute/AttributeWriterTest.java new file mode 100644 index 0000000..52c5819 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/AttributeWriterTest.java @@ -0,0 +1,203 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.Calendar; +import java.util.Date; +import java.util.Locale; +import java.util.TimeZone; + +import javax.print.attribute.standard.CopiesSupported; +import javax.print.attribute.standard.JobHoldUntil; +import javax.print.attribute.standard.JobName; +import javax.print.attribute.standard.JobPriority; +import javax.print.attribute.standard.JobState; +import javax.print.attribute.standard.PrinterResolution; +import javax.print.attribute.standard.PrinterURI; + +import junit.framework.TestCase; +import de.lohndirekt.print.attribute.cups.JobPageLimit; +import de.lohndirekt.print.attribute.ipp.Charset; +import de.lohndirekt.print.attribute.ipp.jobdesc.JobUri; +import de.lohndirekt.print.attribute.ipp.printerdesc.PrinterCurrentTime; +import de.lohndirekt.print.attribute.ipp.printerdesc.supported.PageRangesSupported; + +/** + * @author ld-development + * + * + */ +public class AttributeWriterTest extends TestCase { + + ByteArrayOutputStream out; + + protected void setUp() throws Exception { + super.setUp(); + out = new ByteArrayOutputStream(); + } + + + private Date date(String timeZoneId){ + TimeZone zone = TimeZone.getTimeZone(timeZoneId); + Calendar cal = Calendar.getInstance(zone); + + cal.set(Calendar.YEAR, 2003); + cal.set(Calendar.MONTH, Calendar.JUNE); + cal.set(Calendar.DAY_OF_MONTH, 1); + cal.set(Calendar.MINUTE, 48); + cal.set(Calendar.SECOND, 9); + cal.set(Calendar.MILLISECOND, 47); + cal.set(Calendar.HOUR_OF_DAY, 13); + Date date = cal.getTime(); + + return date; + } + /** + * + */ + public void testAttributeWriterForDateTimeSyntax() throws IOException { + + //testing for TimeZone Asia/Omsk + //1:48:09 P.M. in Greenwich obviously means 1:48:09 P.M. in Greenwich + Date d = date("UTC"); + + // testing lohndirekt attribute + AttributeWriter.attributeBytes(new PrinterCurrentTime(d), out); + assertEquals(new byte[] { 49, 0, 20, 112, 114, 105, 110, 116, 101, 114, 45, 99, 117, 114, 114, 101, 110, 116, 45, 116, 105, 109, 101, 0, 11, 7, -45, 6, 1, 13, 48, 9, 0, 43, 0, 0 }, out.toByteArray()); + + //testing javax.print attribute + out.reset(); + AttributeWriter.attributeBytes(new JobHoldUntil(d), out); + assertEquals(new byte[] { 49, 0, 14, 106, 111, 98, 45, 104, 111, 108, 100, 45, 117, 110, 116, 105, 108, 0, 11, 7, -45, 6, 1, 13, 48, 9, 0, 43, 0, 0 }, out.toByteArray()); + + //testing for TimeZone Asia/Omsk + //1:48:09 P.M. in Omsk means 6:48:09 A.M. in Greenwich + d = date("Asia/Omsk"); + + // testing lohndirekt attribute + out.reset(); + AttributeWriter.attributeBytes(new PrinterCurrentTime(d), out); + assertEquals(new byte[] { 49, 0, 20, 112, 114, 105, 110, 116, 101, 114, 45, 99, 117, 114, 114, 101, 110, 116, 45, 116, 105, 109, 101, 0, 11, 7, -45, 6, 1, 6, 48, 9, 0, 43, 0, 0 }, out.toByteArray()); + + //testing javax.print attribute + out.reset(); + AttributeWriter.attributeBytes(new JobHoldUntil(d), out); + assertEquals(new byte[] { 49, 0, 14, 106, 111, 98, 45, 104, 111, 108, 100, 45, 117, 110, 116, 105, 108, 0, 11, 7, -45, 6, 1, 6, 48, 9, 0, 43, 0, 0 }, out.toByteArray()); + } + + /** + * + */ + public void testAttributeWriterForEnumSyntax() throws IOException { + // testing lohndirekt attribute + AttributeWriter.attributeBytes(PageRangesSupported.SUPPORTED, out); + assertEquals( + new byte[] { 65, 0, 21, 112, 97, 103, 101, 45, 114, 97, 110, 103, 101, 115, 45, 115, 117, 112, 112, 111, 114, 116, 101, 100, 0, 13, 110, 111, 116, 32, 115, 117, 112, 112, 111, 114, 116, 101, 100 }, + out.toByteArray()); + + // testing javax.print attribute + out.reset(); + AttributeWriter.attributeBytes(JobState.CANCELED, out); + assertEquals(new byte[] { 65, 0, 9, 106, 111, 98, 45, 115, 116, 97, 116, 101, 0, 8, 99, 97, 110, 99, 101, 108, 101, 100 }, out.toByteArray()); + + } + /** + * + */ + public void testAttributeWriterForIntegerSyntax() throws IOException { + // testing lohndirekt attribute + AttributeWriter.attributeBytes(new JobPageLimit(3), out); + assertEquals(new byte[] { 33, 0, 14, 106, 111, 98, 45, 112, 97, 103, 101, 45, 108, 105, 109, 105, 116, 0, 4, 0, 0, 0, 3 }, out.toByteArray()); + + // testing javax.print attribute + out.reset(); + AttributeWriter.attributeBytes(new JobPriority(3), out); + assertEquals(new byte[] { 33, 0, 12, 106, 111, 98, 45, 112, 114, 105, 111, 114, 105, 116, 121, 0, 4, 0, 0, 0, 3 }, out.toByteArray()); + } + /** + * + */ + public void testAttributeWriterForResolutionSyntax() throws IOException { + // testing javax.print attribute + AttributeWriter.attributeBytes(new PrinterResolution(800, 800, PrinterResolution.DPI), out); + assertEquals( + new byte[] { 33, 0, 18, 112, 114, 105, 110, 116, 101, 114, 45, 114, 101, 115, 111, 108, 117, 116, 105, 111, 110, 0, 9, 0, 0, 3, 32, 0, 0, 3, 32, 100}, + out.toByteArray()); + } + /** + * + */ + public void testAttributeWriterForSetOfIntegerSyntax() throws IOException { + // testing javax.print attribute + AttributeWriter.attributeBytes(new CopiesSupported(1,5), out); + assertEquals( + new byte[] { 51, 0, 16, 99, 111, 112, 105, 101, 115, 45, 115, 117, 112, 112, 111, 114, 116, 101, 100, 0, 8, 0, 0, 0, 1, 0, 0, 0, 5 }, + out.toByteArray()); + } + /** + * + */ + public void testAttributeWriterForTextSyntax() throws IOException { + // testing lohndirekt attribute + AttributeWriter.attributeBytes(Charset.ISO_8859_15, out); + assertEquals( + new byte[] { 71, 0, 18, 97, 116, 116, 114, 105, 98, 117, 116, 101, 115, 45, 99, 104, 97, 114, 115, 101, 116, 0, 11, 105, 115, 111, 45, 56, 56, 53, 57, 45, 49, 53 }, + out.toByteArray()); + + // testing javax.print attribute + out.reset(); + AttributeWriter.attributeBytes(new JobName("testJob",Locale.GERMANY), out); + assertEquals( + new byte[] { 66, 0, 8, 106, 111, 98, 45, 110, 97, 109, 101, 0, 7, 116, 101, 115, 116, 74, 111, 98 }, + out.toByteArray()); + } + /** + * + */ + public void testAttributeWriterForURISyntax() throws URISyntaxException, IOException { + URI uri = new URI("http://www.google.de/"); + // testing lohndirekt attribute + AttributeWriter.attributeBytes(new JobUri(uri), out); + assertEquals( + new byte[] { 69, 0, 7, 106, 111, 98, 45, 117, 114, 105, 0, 21, 104, 116, 116, 112, 58, 47, 47, 119, 119, 119, 46, 103, 111, 111, 103, 108, 101, 46, 100, 101, 47 }, + out.toByteArray()); + + // testing javax.print attribute + out.reset(); + AttributeWriter.attributeBytes(new PrinterURI(uri), out); + assertEquals( + new byte[] { 69, 0, 11, 112, 114, 105, 110, 116, 101, 114, 45, 117, 114, 105, 0, 21, 104, 116, 116, 112, 58, 47, 47, 119, 119, 119, 46, 103, 111, 111, 103, 108, 101, 46, 100, 101, 47 }, + out.toByteArray()); + } + + /** + * @param expected + * @param actual + */ + private void assertEquals(byte[] expected, byte[] actual) { + assertEquals(new String(expected), new String(actual)); + } + + + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/DefaultAttribute.java b/jspi/src/main/java/de/lohndirekt/print/attribute/DefaultAttribute.java new file mode 100644 index 0000000..f77cd1c --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/DefaultAttribute.java @@ -0,0 +1,26 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute; + +import javax.print.attribute.Attribute; + + +public interface DefaultAttribute extends Attribute{ + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/IppAttributeName.java b/jspi/src/main/java/de/lohndirekt/print/attribute/IppAttributeName.java new file mode 100644 index 0000000..742f2a5 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/IppAttributeName.java @@ -0,0 +1,531 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute; + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.Date; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; +import java.util.logging.Logger; + +import javax.print.attribute.Attribute; +import javax.print.attribute.standard.ColorSupported; +import javax.print.attribute.standard.Compression; +import javax.print.attribute.standard.Copies; +import javax.print.attribute.standard.CopiesSupported; +import javax.print.attribute.standard.DateTimeAtCompleted; +import javax.print.attribute.standard.DateTimeAtCreation; +import javax.print.attribute.standard.DateTimeAtProcessing; +import javax.print.attribute.standard.DocumentName; +import javax.print.attribute.standard.Fidelity; +import javax.print.attribute.standard.Finishings; +import javax.print.attribute.standard.JobImpressions; +import javax.print.attribute.standard.JobImpressionsCompleted; +import javax.print.attribute.standard.JobImpressionsSupported; +import javax.print.attribute.standard.JobKOctets; +import javax.print.attribute.standard.JobKOctetsProcessed; +import javax.print.attribute.standard.JobKOctetsSupported; +import javax.print.attribute.standard.JobMediaSheets; +import javax.print.attribute.standard.JobMediaSheetsCompleted; +import javax.print.attribute.standard.JobMediaSheetsSupported; +import javax.print.attribute.standard.JobMessageFromOperator; +import javax.print.attribute.standard.JobName; +import javax.print.attribute.standard.JobOriginatingUserName; +import javax.print.attribute.standard.JobPriority; +import javax.print.attribute.standard.JobPrioritySupported; +import javax.print.attribute.standard.JobSheets; +import javax.print.attribute.standard.JobState; +import javax.print.attribute.standard.JobStateReason; +import javax.print.attribute.standard.JobStateReasons; +import javax.print.attribute.standard.MediaSizeName; +import javax.print.attribute.standard.MultipleDocumentHandling; +import javax.print.attribute.standard.NumberOfDocuments; +import javax.print.attribute.standard.NumberOfInterveningJobs; +import javax.print.attribute.standard.NumberUp; +import javax.print.attribute.standard.NumberUpSupported; +import javax.print.attribute.standard.OrientationRequested; +import javax.print.attribute.standard.OutputDeviceAssigned; +import javax.print.attribute.standard.PDLOverrideSupported; +import javax.print.attribute.standard.PageRanges; +import javax.print.attribute.standard.PagesPerMinute; +import javax.print.attribute.standard.PagesPerMinuteColor; +import javax.print.attribute.standard.PresentationDirection; +import javax.print.attribute.standard.PrintQuality; +import javax.print.attribute.standard.PrinterInfo; +import javax.print.attribute.standard.PrinterIsAcceptingJobs; +import javax.print.attribute.standard.PrinterLocation; +import javax.print.attribute.standard.PrinterMakeAndModel; +import javax.print.attribute.standard.PrinterMessageFromOperator; +import javax.print.attribute.standard.PrinterMoreInfo; +import javax.print.attribute.standard.PrinterMoreInfoManufacturer; +import javax.print.attribute.standard.PrinterName; +import javax.print.attribute.standard.PrinterResolution; +import javax.print.attribute.standard.PrinterState; +import javax.print.attribute.standard.PrinterStateReason; +import javax.print.attribute.standard.PrinterStateReasons; +import javax.print.attribute.standard.PrinterURI; +import javax.print.attribute.standard.QueuedJobCount; +import javax.print.attribute.standard.ReferenceUriSchemesSupported; +import javax.print.attribute.standard.RequestingUserName; +import javax.print.attribute.standard.Severity; +import javax.print.attribute.standard.SheetCollate; +import javax.print.attribute.standard.Sides; + +import de.lohndirekt.print.attribute.auth.RequestingUserPassword; +import de.lohndirekt.print.attribute.cups.DeviceClass; +import de.lohndirekt.print.attribute.cups.DeviceUri; +import de.lohndirekt.print.attribute.cups.JobKLimit; +import de.lohndirekt.print.attribute.cups.JobPageLimit; +import de.lohndirekt.print.attribute.cups.JobQuotaPeriod; +import de.lohndirekt.print.attribute.cups.MemberNames; +import de.lohndirekt.print.attribute.cups.MemberUris; +import de.lohndirekt.print.attribute.cups.PrinterType; +import de.lohndirekt.print.attribute.ipp.Charset; +import de.lohndirekt.print.attribute.ipp.DetailedStatusMessage; +import de.lohndirekt.print.attribute.ipp.DocumentFormat; +import de.lohndirekt.print.attribute.ipp.NaturalLanguage; +import de.lohndirekt.print.attribute.ipp.StatusMessage; +import de.lohndirekt.print.attribute.ipp.UnknownAttribute; +import de.lohndirekt.print.attribute.ipp.jobdesc.JobId; +import de.lohndirekt.print.attribute.ipp.jobdesc.JobMoreInfo; +import de.lohndirekt.print.attribute.ipp.jobdesc.JobOriginatingHostName; +import de.lohndirekt.print.attribute.ipp.jobdesc.JobPrinterUpTime; +import de.lohndirekt.print.attribute.ipp.jobdesc.JobPrinterUri; +import de.lohndirekt.print.attribute.ipp.jobdesc.JobUri; +import de.lohndirekt.print.attribute.ipp.jobdesc.TimeAtCompleted; +import de.lohndirekt.print.attribute.ipp.jobdesc.TimeAtCreation; +import de.lohndirekt.print.attribute.ipp.jobdesc.TimeAtProcessing; +import de.lohndirekt.print.attribute.ipp.jobtempl.LdJobHoldUntil; +import de.lohndirekt.print.attribute.ipp.printerdesc.MultipleOperationTimeout; +import de.lohndirekt.print.attribute.ipp.printerdesc.NaturalLanguageConfigured; +import de.lohndirekt.print.attribute.ipp.printerdesc.PrinterCurrentTime; +import de.lohndirekt.print.attribute.ipp.printerdesc.PrinterDriverInstaller; +import de.lohndirekt.print.attribute.ipp.printerdesc.PrinterStateMessage; +import de.lohndirekt.print.attribute.ipp.printerdesc.PrinterUpTime; +import de.lohndirekt.print.attribute.ipp.printerdesc.defaults.CharsetConfigured; +import de.lohndirekt.print.attribute.ipp.printerdesc.defaults.CopiesDefault; +import de.lohndirekt.print.attribute.ipp.printerdesc.defaults.DocumentFormatDefault; +import de.lohndirekt.print.attribute.ipp.printerdesc.defaults.FinishingsDefault; +import de.lohndirekt.print.attribute.ipp.printerdesc.defaults.JobHoldUntilDefault; +import de.lohndirekt.print.attribute.ipp.printerdesc.defaults.JobPriorityDefault; +import de.lohndirekt.print.attribute.ipp.printerdesc.defaults.JobSheetsDefault; +import de.lohndirekt.print.attribute.ipp.printerdesc.defaults.MediaDefault; +import de.lohndirekt.print.attribute.ipp.printerdesc.defaults.MultipleDocumentHandlingDefault; +import de.lohndirekt.print.attribute.ipp.printerdesc.defaults.NumberUpDefault; +import de.lohndirekt.print.attribute.ipp.printerdesc.defaults.OrientationRequestedDefault; +import de.lohndirekt.print.attribute.ipp.printerdesc.defaults.SidesDefault; +import de.lohndirekt.print.attribute.ipp.printerdesc.supported.CharsetSupported; +import de.lohndirekt.print.attribute.ipp.printerdesc.supported.CompressionSupported; +import de.lohndirekt.print.attribute.ipp.printerdesc.supported.DocumentFormatSupported; +import de.lohndirekt.print.attribute.ipp.printerdesc.supported.FinishingsSupported; +import de.lohndirekt.print.attribute.ipp.printerdesc.supported.GeneratedNaturalLanguageSupported; +import de.lohndirekt.print.attribute.ipp.printerdesc.supported.IppVersionsSupported; +import de.lohndirekt.print.attribute.ipp.printerdesc.supported.JobHoldUntilSupported; +import de.lohndirekt.print.attribute.ipp.printerdesc.supported.JobSheetsSupported; +import de.lohndirekt.print.attribute.ipp.printerdesc.supported.MediaSupported; +import de.lohndirekt.print.attribute.ipp.printerdesc.supported.MultipleDocumentHandlingSupported; +import de.lohndirekt.print.attribute.ipp.printerdesc.supported.MultipleDocumentJobsSupported; +import de.lohndirekt.print.attribute.ipp.printerdesc.supported.OperationsSupported; +import de.lohndirekt.print.attribute.ipp.printerdesc.supported.OrientationRequestedSupported; +import de.lohndirekt.print.attribute.ipp.printerdesc.supported.OutputBinSupported; +import de.lohndirekt.print.attribute.ipp.printerdesc.supported.PageRangesSupported; +import de.lohndirekt.print.attribute.ipp.printerdesc.supported.PrinterUriSupported; +import de.lohndirekt.print.attribute.ipp.printerdesc.supported.SidesSupported; +import de.lohndirekt.print.attribute.ipp.printerdesc.supported.UriAuthenticationSupported; +import de.lohndirekt.print.attribute.ipp.printerdesc.supported.UriSecuritySupported; +import de.lohndirekt.print.attribute.undocumented.PrinterStateTime; + +/** + * @author bpusch + * + */ +public final class IppAttributeName { + private final static Logger log = Logger.getLogger(AttributeParser.class.getName()); + + /* + * Attributes defined in javax.print.attribute.standard + */ + public static final IppAttributeName COLOR_SUPPORTED = new IppAttributeName(ColorSupported.SUPPORTED); + public static final IppAttributeName COMPRESSION = new IppAttributeName(Compression.NONE); + public static final IppAttributeName COPIES = new IppAttributeName(new Copies(1)); + public static final IppAttributeName COPIES_SUPPORTED = new IppAttributeName(new CopiesSupported(1)); + public static final IppAttributeName DATE_TIME_AT_COMPLETION = new IppAttributeName(new DateTimeAtCompleted(new Date())); + public static final IppAttributeName DATE_TIME_AT_CREATION = new IppAttributeName(new DateTimeAtCreation(new Date())); + public static final IppAttributeName DATE_TIME_AT_PROCESSING = new IppAttributeName(new DateTimeAtProcessing(new Date())); + public static final IppAttributeName DOCUMENT_NAME = new IppAttributeName(new DocumentName("", Locale.CANADA)); + public static final IppAttributeName FIDELITY = new IppAttributeName(Fidelity.FIDELITY_TRUE); + public static final IppAttributeName FINISHINGS = new IppAttributeName(Finishings.BIND); + public static final IppAttributeName JOB_IMPRESSIONS = new IppAttributeName(new JobImpressions(1)); + public static final IppAttributeName JOB_IMPRESSIONS_COMPLETED = new IppAttributeName(new JobImpressionsCompleted(1)); + public static final IppAttributeName JOB_IMPRESSIONS_SUPPORTED = new IppAttributeName(new JobImpressionsSupported(1, 1)); + public static final IppAttributeName JOB_K_OCTETS = new IppAttributeName(new JobKOctets(1)); + public static final IppAttributeName JOB_K_OCTETS_PROCESSED = new IppAttributeName(new JobKOctetsProcessed(1)); + public static final IppAttributeName JOB_K_OCTETS_SUPPORTED = new IppAttributeName(new JobKOctetsSupported(1, 1)); + public static final IppAttributeName JOB_MEDIA_SHEETS = new IppAttributeName(new JobMediaSheets(1)); + public static final IppAttributeName JOB_MEDIA_SHEETS_COMPLETED = new IppAttributeName(new JobMediaSheetsCompleted(1)); + public static final IppAttributeName JOB_MEDIA_SHEETS_SUPPORTED = new IppAttributeName(new JobMediaSheetsSupported(1, 1)); + public static final IppAttributeName JOB_MESSAGE_FROM_OPERATOR = + new IppAttributeName(new JobMessageFromOperator("", Locale.CANADA)); + public static final IppAttributeName JOB_NAME = new IppAttributeName(new JobName("", Locale.CANADA)); + public static final IppAttributeName JOB_ORIGINATING_USER_NAME = + new IppAttributeName(new JobOriginatingUserName("", Locale.CANADA)); + public static final IppAttributeName JOB_PRIORIY = new IppAttributeName(new JobPriority(1)); + public static final IppAttributeName JOB_PRIORIY_SUPPORTED = new IppAttributeName(new JobPrioritySupported(1)); + public static final IppAttributeName JOB_SHEETS = new IppAttributeName(JobSheets.NONE); + public static final IppAttributeName JOB_STATE = new IppAttributeName(JobState.ABORTED); + public static final IppAttributeName JOB_STATE_REASON = new IppAttributeName(JobStateReason.ABORTED_BY_SYSTEM); + public static final IppAttributeName JOB_STATE_REASONS = new IppAttributeName(new JobStateReasons()); + //Could be MediaName,MediaSizeName or MediaTray + public static final IppAttributeName MEDIA = new IppAttributeName(MediaSizeName.A); + public static final IppAttributeName MULTIPLE_DOCUMENT_HANDLING = + new IppAttributeName(MultipleDocumentHandling.SEPARATE_DOCUMENTS_COLLATED_COPIES); + public static final IppAttributeName NUMBER_OF_DOCUMENTS = new IppAttributeName(new NumberOfDocuments(1)); + public static final IppAttributeName NUMBER_OF_INTERVENING_JOBS = new IppAttributeName(new NumberOfInterveningJobs(1)); + public static final IppAttributeName NUMBER_UP = new IppAttributeName(new NumberUp(1)); + public static final IppAttributeName NUMBER_UP_SUPPORTED = new IppAttributeName(new NumberUpSupported(1)); + public static final IppAttributeName ORIENTATION_REQUESTED = new IppAttributeName(OrientationRequested.LANDSCAPE); + public static final IppAttributeName OUTPUT_DEVICE_ASSIGNED = + new IppAttributeName(new OutputDeviceAssigned("", Locale.CANADA)); + public static final IppAttributeName PAGE_RANGES = new IppAttributeName(new PageRanges(1)); + public static final IppAttributeName PAGES_PER_MINUTE = new IppAttributeName(new PagesPerMinute(1)); + public static final IppAttributeName PAGES_PER_MINUTE_COLOR = new IppAttributeName(new PagesPerMinuteColor(1)); + public static final IppAttributeName PDL_OVERRIDE_SUPPORTED = new IppAttributeName(PDLOverrideSupported.ATTEMPTED); + public static final IppAttributeName PRESENTATION_DIRECTION = new IppAttributeName(PresentationDirection.TOBOTTOM_TOLEFT); + public static final IppAttributeName PRINTER_INFO = new IppAttributeName(new PrinterInfo("", Locale.CANADA)); + public static final IppAttributeName PRINTER_IS_ACCEPTING_JOBS = new IppAttributeName(PrinterIsAcceptingJobs.ACCEPTING_JOBS); + public static final IppAttributeName PRINTER_LOCATION = new IppAttributeName(new PrinterLocation("", Locale.CANADA)); + public static final IppAttributeName PRINTER_MAKE_AND_MODEL = + new IppAttributeName(new PrinterMakeAndModel("", Locale.CANADA)); + public static final IppAttributeName PRINTER_MESSAGE_FROM_OPERATOR = + new IppAttributeName(new PrinterMessageFromOperator("", Locale.CANADA)); + public static final IppAttributeName PRINTER_MORE_INFO = new IppAttributeName(new PrinterMoreInfo(IppAttributeName.getURI())); + public static final IppAttributeName PRINTER_MORE_INFO_MANUFACTURER = + new IppAttributeName(new PrinterMoreInfoManufacturer(IppAttributeName.getURI())); + public static final IppAttributeName PRINTER_NAME = new IppAttributeName(new PrinterName("", Locale.CANADA)); + public static final IppAttributeName PRINTER_RESOLUTION = new IppAttributeName(new PrinterResolution(1, 1, 1)); + public static final IppAttributeName PRINTER_STATE = new IppAttributeName(PrinterState.IDLE); + public static final IppAttributeName PRINTER_STATE_REASON = new IppAttributeName(PrinterStateReason.CONNECTING_TO_DEVICE); + public static final IppAttributeName PRINTER_STATE_REASONS = new IppAttributeName(new PrinterStateReasons()); + public static final IppAttributeName PRINTER_URI = new IppAttributeName(new PrinterURI(IppAttributeName.getURI())); + public static final IppAttributeName PRINT_QUALITY = new IppAttributeName(PrintQuality.DRAFT); + public static final IppAttributeName QUEUED_JOB_COUNT = new IppAttributeName(new QueuedJobCount(1)); + public static final IppAttributeName REFERENCE_URI_SCHEMES_SUPPORTED = + new IppAttributeName(ReferenceUriSchemesSupported.FILE); + public static final IppAttributeName REQUESTING_USER_NAME = new IppAttributeName(new RequestingUserName("", Locale.CANADA)); + public static final IppAttributeName REQUESTING_USER_PASSWD = new IppAttributeName(new RequestingUserPassword("", Locale.CANADA)); + public static final IppAttributeName SEVERITY = new IppAttributeName(Severity.ERROR); + public static final IppAttributeName SHEET_COLLATE = new IppAttributeName(SheetCollate.COLLATED); + public static final IppAttributeName SIDES = new IppAttributeName(Sides.DUPLEX); + + /* + * IPP standard attributes defined in de.lohndirekt.attribute.ipp + */ + public static final IppAttributeName CHARSET = new IppAttributeName(new Charset("x", Locale.getDefault())); + public static final IppAttributeName CHARSET_CONFIGURED = + new IppAttributeName(new CharsetConfigured("x", Locale.getDefault())); + public static final IppAttributeName CHARSET_SUPORTED = new IppAttributeName(new CharsetSupported("x", Locale.getDefault())); + public static final IppAttributeName COMPRESSION_SUPORTED = + new IppAttributeName(new CompressionSupported("x", Locale.getDefault())); + public static final IppAttributeName COPIES_DEFAULT = new IppAttributeName(new CopiesDefault(1)); + public static final IppAttributeName DETAILED_STATUS_MESSAGE = new IppAttributeName(new DetailedStatusMessage("x", Locale.getDefault())); + public static final IppAttributeName DOCUMENT_FORMAT = + new IppAttributeName(new DocumentFormat("x", Locale.getDefault())); + public static final IppAttributeName DOCUMENT_FORMAT_SUPORTED = + new IppAttributeName(new DocumentFormatSupported("x", Locale.getDefault())); + public static final IppAttributeName DOCUMENT_FORMAT_DEFAULT = + new IppAttributeName(new DocumentFormatDefault("x", Locale.getDefault())); + public static final IppAttributeName FINISHINGS_DEFAULT = new IppAttributeName(new FinishingsDefault(1)); + public static final IppAttributeName FINISHINGS_SUPPORTED = new IppAttributeName(new FinishingsSupported(1)); + public static final IppAttributeName IPP_VERSIONS_SUPPORTED = + new IppAttributeName(new IppVersionsSupported("x", Locale.getDefault())); + public static final IppAttributeName JOB_HOLD_UNTIL = new IppAttributeName(new LdJobHoldUntil("x", Locale.getDefault())); + public static final IppAttributeName JOB_HOLD_UNTIL_DEFAULT = new IppAttributeName(new JobHoldUntilDefault("x", Locale.getDefault())); + public static final IppAttributeName JOB_HOLD_UNTIL_SUPPORTED = new IppAttributeName(new JobHoldUntilSupported("x", Locale.getDefault())); + public static final IppAttributeName JOB_ID = new IppAttributeName(new JobId(1)); + public static final IppAttributeName JOB_MORE_INFO = new IppAttributeName(new JobMoreInfo(IppAttributeName.getURI())); + public static final IppAttributeName JOB_ORIGINATING_HOST_NAME = + new IppAttributeName(new JobOriginatingHostName("x", Locale.getDefault())); + public static final IppAttributeName JOB_PRINTER_UP_TIME = new IppAttributeName(new JobPrinterUpTime(1)); + public static final IppAttributeName JOB_PRINTER_URI = new IppAttributeName(new JobPrinterUri(getURI())); + public static final IppAttributeName JOB_PRIORITY_DEFAULT = new IppAttributeName(new JobPriorityDefault(1)); + public static final IppAttributeName JOB_SHEETS_DEFAULT = + new IppAttributeName(new JobSheetsDefault("x", Locale.getDefault())); + public static final IppAttributeName JOB_SHEETS_SUPORTED = + new IppAttributeName(new JobSheetsSupported("x", Locale.getDefault())); + public static final IppAttributeName JOB_URI = + new IppAttributeName(new JobUri(IppAttributeName.getURI())); + public static final IppAttributeName GENERATED_NATURAL_LANGUAGE_SUPPORTED = + new IppAttributeName(new GeneratedNaturalLanguageSupported("x", Locale.getDefault())); + public static final IppAttributeName MEDIA_DEFAULT = new IppAttributeName(new MediaDefault("x", Locale.getDefault())); + public static final IppAttributeName MEDIA_SUPPORTED = new IppAttributeName(new MediaSupported("x", Locale.getDefault())); + public static final IppAttributeName MULTIPLE_DOCUMENT_HANDLING_DEFAULT = + new IppAttributeName(new MultipleDocumentHandlingDefault("x", Locale.getDefault())); + public static final IppAttributeName MULTIPLE_DOCUMENT_HANDLING_SUPPORTED = + new IppAttributeName(new MultipleDocumentHandlingSupported("x", Locale.getDefault())); + public static final IppAttributeName MULTIPLE_DOCUMENT_JOBS_SUPPORTED = + new IppAttributeName(new MultipleDocumentJobsSupported(1)); + public static final IppAttributeName MULTIPLE_OPERATION_TIMEOUT = new IppAttributeName(new MultipleOperationTimeout(1)); + public static final IppAttributeName NATURAL_LANGUAGE = new IppAttributeName(new NaturalLanguage("x", Locale.getDefault())); + public static final IppAttributeName NATURAL_LANGUAGE_CONFIGURED = + new IppAttributeName(new NaturalLanguageConfigured("x", Locale.getDefault())); + public static final IppAttributeName NUMBER_UP_DEFAULT = new IppAttributeName(new NumberUpDefault(1)); + public static final IppAttributeName OPERATIONS_SUPPORTED = new IppAttributeName(new OperationsSupported(1)); + public static final IppAttributeName ORIENTATION_REQUESTED_DEFAULT = new IppAttributeName(new OrientationRequestedDefault(1)); + public static final IppAttributeName ORIENTATION_REQUESTED_SUPPORTED = + new IppAttributeName(new OrientationRequestedSupported(1)); + public static final IppAttributeName PAGE_RANGES_SUPPORTED = new IppAttributeName(new PageRangesSupported(1)); + public static final IppAttributeName PRINTER_CURRENT_TIME = new IppAttributeName(new PrinterCurrentTime(new Date())); + public static final IppAttributeName PRINTER_DRIVER_INSTALLER = + new IppAttributeName(new PrinterDriverInstaller(IppAttributeName.getURI())); + public static final IppAttributeName PRINTER_STATE_MESSAGE = + new IppAttributeName(new PrinterStateMessage("x", Locale.getDefault())); + public static final IppAttributeName PRINTER_TYPE = new IppAttributeName(new PrinterType(1)); + public static final IppAttributeName PRINTER_UP_TIME = new IppAttributeName(new PrinterUpTime(1)); + public static final IppAttributeName PRINTER_URI_SUPPORTED = + new IppAttributeName(new PrinterUriSupported(IppAttributeName.getURI())); + public static final IppAttributeName SIDES_DEFAULT = new IppAttributeName(new SidesDefault("x", Locale.getDefault())); + public static final IppAttributeName SIDES_SUPPORTED = new IppAttributeName(new SidesSupported("x", Locale.getDefault())); + public static final IppAttributeName STATUS_MESSAGE = new IppAttributeName(new StatusMessage("x", Locale.getDefault())); + public static final IppAttributeName TIME_AT_COMPLETED = new IppAttributeName(new TimeAtCompleted(1)); + public static final IppAttributeName TIME_AT_CREATION = new IppAttributeName(new TimeAtCreation(1)); + public static final IppAttributeName TIME_AT_PROCESSING = new IppAttributeName(new TimeAtProcessing(1)); + public static final IppAttributeName URI_AUTHENTICATION_SUPPORTED = + new IppAttributeName(new UriAuthenticationSupported("x", Locale.getDefault())); + public static final IppAttributeName URI_SECURITY_SUPPORTED = + new IppAttributeName(new UriSecuritySupported("x", Locale.getDefault())); + + + /* + * CUPS IPP extension attributes defined in de.lohndirekt.attribute.cups + */ + public static final IppAttributeName DEVICE_CLASS = new IppAttributeName(new DeviceClass("x", Locale.getDefault())); + public static final IppAttributeName DEVICE_URI = new IppAttributeName(new DeviceUri(IppAttributeName.getURI())); + public static final IppAttributeName Job_K_LIMIT = new IppAttributeName(new JobKLimit(1)); + public static final IppAttributeName JOB_PAGE_LIMIT = new IppAttributeName(new JobPageLimit(1)); + public static final IppAttributeName JOB_QUOTA_PERIOD = new IppAttributeName(new JobQuotaPeriod(1)); + public static final IppAttributeName MEMBER_NAMES = new IppAttributeName(new MemberNames("x", Locale.getDefault())); + public static final IppAttributeName MEMBER_URIS = new IppAttributeName(new MemberUris(IppAttributeName.getURI())); + public static final IppAttributeName PRINTER_STATE_TIME = new IppAttributeName(new PrinterStateTime(1)); + + /* + * undocumented IPP attributes used by CUPS + */ + public static final IppAttributeName OUTPUT_BIN_SUPPORTED = + new IppAttributeName(new OutputBinSupported("x", Locale.getDefault())); + + + private static Map attributesByName = new HashMap();; + private static Map attributesByCategory = new HashMap();; + + /** + * + */ + private static URI getURI() { + try { + return new URI("http://www.lohndirekt.de"); + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } + + } + + private static void put(IppAttributeName attr) { + attributesByName.put(attr.getName(), attr); + attributesByCategory.put(attr.getCategory(), attr); + } + + /** + * + */ + static { + put(IppAttributeName.CHARSET); + put(IppAttributeName.CHARSET_CONFIGURED); + put(IppAttributeName.CHARSET_SUPORTED); + put(IppAttributeName.COLOR_SUPPORTED); + put(IppAttributeName.COMPRESSION); + put(IppAttributeName.COMPRESSION_SUPORTED); + put(IppAttributeName.COPIES); + put(IppAttributeName.COPIES_DEFAULT); + put(IppAttributeName.COPIES_SUPPORTED); + put(IppAttributeName.DATE_TIME_AT_COMPLETION); + put(IppAttributeName.DATE_TIME_AT_CREATION); + put(IppAttributeName.DATE_TIME_AT_PROCESSING); + put(IppAttributeName.DEVICE_CLASS); + put(IppAttributeName.DEVICE_URI); + put(IppAttributeName.DETAILED_STATUS_MESSAGE); + put(IppAttributeName.DOCUMENT_NAME); + put(IppAttributeName.DOCUMENT_FORMAT); + put(IppAttributeName.DOCUMENT_FORMAT_DEFAULT); + put(IppAttributeName.DOCUMENT_FORMAT_SUPORTED); + put(IppAttributeName.FIDELITY); + put(IppAttributeName.FINISHINGS); + put(IppAttributeName.FINISHINGS_DEFAULT); + put(IppAttributeName.FINISHINGS_SUPPORTED); + put(IppAttributeName.GENERATED_NATURAL_LANGUAGE_SUPPORTED); + put(IppAttributeName.IPP_VERSIONS_SUPPORTED); + put(IppAttributeName.JOB_HOLD_UNTIL); + put(IppAttributeName.JOB_HOLD_UNTIL_DEFAULT); + put(IppAttributeName.JOB_HOLD_UNTIL_SUPPORTED); + put(IppAttributeName.JOB_ID); + put(IppAttributeName.JOB_IMPRESSIONS); + put(IppAttributeName.JOB_IMPRESSIONS_COMPLETED); + put(IppAttributeName.JOB_IMPRESSIONS_SUPPORTED); + put(IppAttributeName.Job_K_LIMIT); + put(IppAttributeName.JOB_K_OCTETS); + put(IppAttributeName.JOB_K_OCTETS_PROCESSED); + put(IppAttributeName.JOB_K_OCTETS_SUPPORTED); + put(IppAttributeName.JOB_MEDIA_SHEETS); + put(IppAttributeName.JOB_MEDIA_SHEETS_COMPLETED); + put(IppAttributeName.JOB_MEDIA_SHEETS_SUPPORTED); + put(IppAttributeName.JOB_MESSAGE_FROM_OPERATOR); + put(IppAttributeName.JOB_MORE_INFO); + put(IppAttributeName.JOB_NAME); + put(IppAttributeName.JOB_ORIGINATING_HOST_NAME); + put(IppAttributeName.JOB_ORIGINATING_USER_NAME); + put(IppAttributeName.JOB_PAGE_LIMIT); + put(IppAttributeName.JOB_PRINTER_UP_TIME); + put(IppAttributeName.JOB_PRINTER_URI); + put(IppAttributeName.JOB_PRIORIY); + put(IppAttributeName.JOB_PRIORITY_DEFAULT); + put(IppAttributeName.JOB_PRIORIY_SUPPORTED); + put(IppAttributeName.JOB_QUOTA_PERIOD); + put(IppAttributeName.JOB_SHEETS); + put(IppAttributeName.JOB_SHEETS_DEFAULT); + put(IppAttributeName.JOB_SHEETS_SUPORTED); + put(IppAttributeName.JOB_STATE); + put(IppAttributeName.JOB_STATE_REASON); + put(IppAttributeName.JOB_STATE_REASONS); + put(IppAttributeName.JOB_URI); + put(IppAttributeName.MEDIA); + put(IppAttributeName.MEDIA_DEFAULT); + put(IppAttributeName.MEDIA_SUPPORTED); + put(IppAttributeName.MEMBER_NAMES); + put(IppAttributeName.MEMBER_URIS); + put(IppAttributeName.MULTIPLE_DOCUMENT_HANDLING); + put(IppAttributeName.MULTIPLE_DOCUMENT_HANDLING_DEFAULT); + put(IppAttributeName.MULTIPLE_DOCUMENT_HANDLING_SUPPORTED); + put(IppAttributeName.MULTIPLE_DOCUMENT_JOBS_SUPPORTED); + put(IppAttributeName.MULTIPLE_OPERATION_TIMEOUT); + put(IppAttributeName.NATURAL_LANGUAGE); + put(IppAttributeName.NATURAL_LANGUAGE_CONFIGURED); + put(IppAttributeName.NUMBER_OF_DOCUMENTS); + put(IppAttributeName.NUMBER_OF_INTERVENING_JOBS); + put(IppAttributeName.NUMBER_UP); + put(IppAttributeName.NUMBER_UP_DEFAULT); + put(IppAttributeName.NUMBER_UP_SUPPORTED); + put(IppAttributeName.OPERATIONS_SUPPORTED); + put(IppAttributeName.ORIENTATION_REQUESTED); + put(IppAttributeName.ORIENTATION_REQUESTED_DEFAULT); + put(IppAttributeName.ORIENTATION_REQUESTED_SUPPORTED); + put(IppAttributeName.OUTPUT_BIN_SUPPORTED); + put(IppAttributeName.OUTPUT_DEVICE_ASSIGNED); + put(IppAttributeName.PAGE_RANGES); + put(IppAttributeName.PAGE_RANGES_SUPPORTED); + put(IppAttributeName.PAGES_PER_MINUTE); + put(IppAttributeName.PAGES_PER_MINUTE_COLOR); + put(IppAttributeName.PDL_OVERRIDE_SUPPORTED); + put(IppAttributeName.PRESENTATION_DIRECTION); + put(IppAttributeName.PRINT_QUALITY); + put(IppAttributeName.PRINTER_CURRENT_TIME); + put(IppAttributeName.PRINTER_DRIVER_INSTALLER); + put(IppAttributeName.PRINTER_INFO); + put(IppAttributeName.PRINTER_IS_ACCEPTING_JOBS); + put(IppAttributeName.PRINTER_LOCATION); + put(IppAttributeName.PRINTER_MAKE_AND_MODEL); + put(IppAttributeName.PRINTER_MESSAGE_FROM_OPERATOR); + put(IppAttributeName.PRINTER_MORE_INFO); + put(IppAttributeName.PRINTER_MORE_INFO_MANUFACTURER); + put(IppAttributeName.PRINTER_NAME); + put(IppAttributeName.PRINTER_RESOLUTION); + put(IppAttributeName.PRINTER_STATE); + put(IppAttributeName.PRINTER_STATE_MESSAGE); + put(IppAttributeName.PRINTER_STATE_REASON); + put(IppAttributeName.PRINTER_STATE_REASONS); + put(IppAttributeName.PRINTER_STATE_TIME); + put(IppAttributeName.PRINTER_TYPE); + put(IppAttributeName.PRINTER_UP_TIME); + put(IppAttributeName.PRINTER_URI); + put(IppAttributeName.PRINTER_URI_SUPPORTED); + put(IppAttributeName.QUEUED_JOB_COUNT); + put(IppAttributeName.REFERENCE_URI_SCHEMES_SUPPORTED); + put(IppAttributeName.REQUESTING_USER_NAME); + put(IppAttributeName.REQUESTING_USER_PASSWD); + put(IppAttributeName.SEVERITY); + put(IppAttributeName.SHEET_COLLATE); + put(IppAttributeName.SIDES); + put(IppAttributeName.SIDES_DEFAULT); + put(IppAttributeName.SIDES_SUPPORTED); + put(IppAttributeName.STATUS_MESSAGE); + put(IppAttributeName.TIME_AT_COMPLETED); + put(IppAttributeName.TIME_AT_CREATION); + put(IppAttributeName.TIME_AT_PROCESSING); + put(IppAttributeName.URI_AUTHENTICATION_SUPPORTED); + put(IppAttributeName.URI_SECURITY_SUPPORTED); + } + + public static IppAttributeName get(String attributeName) { + IppAttributeName attrib =(IppAttributeName)attributesByName.get(attributeName); + if (attrib == null) { + log.warning("Unknown Attribute " + attributeName + "."); + attrib = new IppAttributeName(new UnknownAttribute(attributeName, Locale.getDefault())); + } + return attrib; + } + + public static IppAttributeName get(Class category) { + IppAttributeName attrib =(IppAttributeName)attributesByCategory.get(category); + if (attrib == null) { + log.warning("Unknown Category " + category + "."); + attrib = new IppAttributeName(new UnknownAttribute(category.getName(), Locale.getDefault())); + } + return attrib; + } + // End of static part + + private String methodName; + private Class attributeClass; + private Class category; + + private IppAttributeName(Attribute attribute) { + this.methodName = attribute.getName(); + this.attributeClass = attribute.getClass(); + this.category = attribute.getCategory(); + } + + /** + * @return + */ + public Class getAttributeClass() { + return attributeClass; + } + + public String getName() { + return this.methodName; + } + + /** + * + */ + public Class getCategory() { + return this.category; + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/IppAttributeNameTest.java b/jspi/src/main/java/de/lohndirekt/print/attribute/IppAttributeNameTest.java new file mode 100644 index 0000000..a0d41c7 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/IppAttributeNameTest.java @@ -0,0 +1,60 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute; + +import java.util.Locale; + +import junit.framework.TestCase; +import de.lohndirekt.print.attribute.ipp.UnknownAttribute; + +/** + * @author bpusch + * + * + */ +public class IppAttributeNameTest extends TestCase { + + /** + * Constructor for IppAttributeNameTest. + * @param name + */ + public IppAttributeNameTest(String name) { + super(name); + } + + + /* + * Test for IppAttributeName get(String) + */ + public void testGetString() { + IppAttributeName attributeName = IppAttributeName.get("attribute-does-not-exist"); + assertNotNull("IppAttributeName is null",attributeName); + assertEquals("IppAttributeName should be UNKNOWN_ATTRIBUTE", attributeName.getCategory(), new UnknownAttribute("x",Locale.getDefault()).getCategory()); + } + + /* + * Test for IppAttributeName get(Class) + */ + public void testGetClass() { + IppAttributeName attributeName = IppAttributeName.get(String.class); + assertNotNull("IppAttributeName is null",attributeName); + assertEquals("IppAttributeName should be UNKNOWN_ATTRIBUTE", attributeName.getCategory(), new UnknownAttribute("x",Locale.getDefault()).getCategory()); + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/IppDelimiterTag.java b/jspi/src/main/java/de/lohndirekt/print/attribute/IppDelimiterTag.java new file mode 100644 index 0000000..908d906 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/IppDelimiterTag.java @@ -0,0 +1,52 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute; + +/** + *Bezeichnungen übernommen aus www.ietf.org/rfc/rfc2910.txt + *Tags ohne Bezeichnung sind dort nicht aufgeführt, werden aber in der Cups-API verwendet + */ +public class IppDelimiterTag { + + private String description = ""; + private int value = 0; + + public static final IppDelimiterTag ZERO = new IppDelimiterTag(0x00, ""); + public static final IppDelimiterTag BEGIN_OPERATION_ATTRIBUTES = new IppDelimiterTag(0x01, "operation-attributes-tag"); + public static final IppDelimiterTag BEGIN_JOB_ATTRIBUTES = new IppDelimiterTag(0x02, "job-attributes-tag"); + public static final IppDelimiterTag END_ATTRIBUTES = new IppDelimiterTag(0x03, "end-of-attributes-tag"); + public static final IppDelimiterTag BEGIN_PRINTER_ATTRIBUTES = new IppDelimiterTag(0x04, "printer-attributes-tag"); + public static final IppDelimiterTag UNSUPPORTED_GROUP = new IppDelimiterTag(0x05, "unsupported-attributes-tag"); + public static final IppDelimiterTag SUBSCRIPTION = new IppDelimiterTag(0x06, ""); + public static final IppDelimiterTag EVENT_NOTIFICATION = new IppDelimiterTag(0x07, ""); + + private IppDelimiterTag(int value, String description) { + this.value = value; + this.description = description; + } + + public int getValue(){ + return this.value; + } + + public String toString(){ + return this.description; + } + +} \ No newline at end of file diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/IppStatus.java b/jspi/src/main/java/de/lohndirekt/print/attribute/IppStatus.java new file mode 100644 index 0000000..54ef905 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/IppStatus.java @@ -0,0 +1,147 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute; + +import java.util.HashMap; +import java.util.Map; + +public final class IppStatus { + + public static final IppStatus SUCCESSFUL_OK = new IppStatus("successful-ok", 0x0000); + public static final IppStatus SUCCESSFUL_OK_IGNORED_OR_SUBSTITUTED_ATTRIBUTES = + new IppStatus("successful-ok-ignored-or-substituted-attributes", 0x0001); + public static final IppStatus SUCCESSFUL_OK_CONFLICTING_ATTRIBUTES = + new IppStatus("successful-ok-conflicting-attributes", 0x0002); + public static final IppStatus CLIENT_ERROR_BAD_REQUEST = new IppStatus("client-error-bad-request", 0x0400); + public static final IppStatus CLIENT_ERROR_FORBIDDEN = new IppStatus("client-error-forbidden", 0x0401); + public static final IppStatus CLIENT_ERROR_NOT_AUTHENTICATED = new IppStatus("client-error-not-authenticated", 0x0402); + public static final IppStatus CLIENT_ERROR_NOT_AUTHORIZED = new IppStatus("client-error-not-authorized", 0x0403); + public static final IppStatus CLIENT_ERROR_NOT_POSSIBLE = new IppStatus("client-error-not-possible", 0x0404); + public static final IppStatus CLIENT_ERROR_TIMEOUT = new IppStatus("client-error-timeout", 0x0405); + public static final IppStatus CLIENT_ERROR_NOT_FOUND = new IppStatus("client-error-not-found", 0x0406); + public static final IppStatus CLIENT_ERROR_GONE = new IppStatus("client-error-gone", 0x0407); + public static final IppStatus CLIENT_ERROR_REQUEST_ENTITY_TOO_LARGE = + new IppStatus("client-error-request-entity-too-large", 0x0408); + public static final IppStatus CLIENT_ERROR_REQUEST_VALUE_TOO_LONG = + new IppStatus("client-error-request-value-too-long", 0x0409); + public static final IppStatus CLIENT_ERROR_DOCUMENT_FORMAT_NOT_SUPPORTED = + new IppStatus("client-error-document-format-not-supported", 0x040A); + public static final IppStatus CLIENT_ERROR_ATTRIBUTES_OR_VALUES_NOT_SUPPORTED = + new IppStatus("client-error-attributes-or-values-not-supported", 0x040B); + public static final IppStatus CLIENT_ERROR_URI_SCHEME_NOT_SUPPORTED = + new IppStatus("client-error-uri-scheme-not-supported", 0x040C); + public static final IppStatus CLIENT_ERROR_CHARSET_NOT_SUPPORTED = + new IppStatus("client-error-charset-not-supported", 0x040D); + public static final IppStatus CLIENT_ERROR_CONFLICTING_ATTRIBUTES = + new IppStatus("client-error-conflicting-attributes", 0x040E); + public static final IppStatus CLIENT_ERROR_COMPRESSION_NOT_SUPPORTED = + new IppStatus("client-error-compression-not-supported", 0x040F); + public static final IppStatus CLIENT_ERROR_COMPRESSION_ERROR = new IppStatus("client-error-compression-error", 0x0410); + public static final IppStatus CLIENT_ERROR_DOCUMENT_FORMAT_ERROR = + new IppStatus("client-error-document-format-error", 0x0411); + public static final IppStatus CLIENT_ERROR_DOCUMENT_ACCESS_ERROR = + new IppStatus("client-error-document-access-error", 0x0412); + public static final IppStatus SERVER_ERROR_INTERNAL_ERROR = new IppStatus("server-error-internal-error", 0x0500); + public static final IppStatus SERVER_ERROR_OPERATION_NOT_SUPPORTED = + new IppStatus("server-error-operation-not-supported", 0x0501); + public static final IppStatus SERVER_ERROR_SERVICE_UNAVAILABLE = new IppStatus("server-error-service-unavailable", 0x0502); + public static final IppStatus SERVER_ERROR_VERSION_NOT_SUPPORTED = + new IppStatus("server-error-version-not-supported", 0x0503); + public static final IppStatus SERVER_ERROR_DEVICE_ERROR = new IppStatus("server-error-device-error", 0x0504); + public static final IppStatus SERVER_ERROR_TEMPORARY_ERROR = new IppStatus("server-error-temporary-error", 0x0505); + public static final IppStatus SERVER_ERROR_NOT_ACCEPTING_JOBS = new IppStatus("server-error-not-accepting-jobs", 0x0506); + public static final IppStatus SERVER_ERROR_BUSY = new IppStatus("server-error-busy", 0x0507); + public static final IppStatus SERVER_ERROR_JOB_CANCELED = new IppStatus("server-error-job-canceled", 0x0508); + public static final IppStatus SERVER_ERROR_MULTIPLE_DOCUMENT_JOBS_NOT_SUPPORTED = + new IppStatus("server-error-multiple-document-jobs-not-supported", 0x0509); + + private static Map stati; + + private static void init() { + stati = new HashMap(); + put(SUCCESSFUL_OK); + put(SUCCESSFUL_OK_IGNORED_OR_SUBSTITUTED_ATTRIBUTES); + put(SUCCESSFUL_OK_CONFLICTING_ATTRIBUTES); + put(CLIENT_ERROR_BAD_REQUEST); + put(CLIENT_ERROR_FORBIDDEN); + put(CLIENT_ERROR_NOT_AUTHENTICATED); + put(CLIENT_ERROR_NOT_AUTHORIZED); + put(CLIENT_ERROR_NOT_POSSIBLE); + put(CLIENT_ERROR_TIMEOUT); + put(CLIENT_ERROR_NOT_FOUND); + put(CLIENT_ERROR_GONE); + put(CLIENT_ERROR_REQUEST_ENTITY_TOO_LARGE); + put(CLIENT_ERROR_REQUEST_VALUE_TOO_LONG); + put(CLIENT_ERROR_DOCUMENT_FORMAT_NOT_SUPPORTED); + put(CLIENT_ERROR_ATTRIBUTES_OR_VALUES_NOT_SUPPORTED); + put(CLIENT_ERROR_URI_SCHEME_NOT_SUPPORTED); + put(CLIENT_ERROR_CHARSET_NOT_SUPPORTED); + put(CLIENT_ERROR_CONFLICTING_ATTRIBUTES); + put(CLIENT_ERROR_COMPRESSION_NOT_SUPPORTED); + put(CLIENT_ERROR_COMPRESSION_ERROR); + put(CLIENT_ERROR_DOCUMENT_FORMAT_ERROR); + put(CLIENT_ERROR_DOCUMENT_ACCESS_ERROR); + put(SERVER_ERROR_INTERNAL_ERROR); + put(SERVER_ERROR_OPERATION_NOT_SUPPORTED); + put(SERVER_ERROR_SERVICE_UNAVAILABLE); + put(SERVER_ERROR_VERSION_NOT_SUPPORTED); + put(SERVER_ERROR_DEVICE_ERROR); + put(SERVER_ERROR_TEMPORARY_ERROR); + put(SERVER_ERROR_NOT_ACCEPTING_JOBS); + put(SERVER_ERROR_BUSY); + put(SERVER_ERROR_JOB_CANCELED); + put(SERVER_ERROR_MULTIPLE_DOCUMENT_JOBS_NOT_SUPPORTED); + + } + + /** + * @param status2 + */ + private static void put(IppStatus status) { + stati.put(new Integer(status.getStatus()), status); + } + + public static IppStatus get(int statusCode) { + if (stati == null) { + init(); + } + return (IppStatus)stati.get(new Integer(statusCode)); + } + + /* + * End of static part + */ + + private String text; + private int status; + + private IppStatus(String statusText, int statusCode) { + this.status = statusCode; + this.text = statusText; + } + + public String getText() { + return this.text; + } + + public int getStatus() { + return this.status; + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/IppValueTag.java b/jspi/src/main/java/de/lohndirekt/print/attribute/IppValueTag.java new file mode 100644 index 0000000..8f95b7d --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/IppValueTag.java @@ -0,0 +1,74 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute; + +/** + *Bezeichnungen übernommen aus www.ietf.org/rfc/rfc2910.txt + *Tags ohne Bezeichnung sind dort nicht aufgeführt, werden aber in der Cups-API verwendet + */ +public class IppValueTag { + + private String description; + private int value = 0; + + public static final IppValueTag UNSUPPORTED_VALUE = new IppValueTag(0x10, "unsupported"); + public static final IppValueTag DEFAULT = new IppValueTag(0x11, "'default' "); + public static final IppValueTag UNKNOWN = new IppValueTag(0x12, "unknown"); + public static final IppValueTag NOVALUE = new IppValueTag(0x13, "no-value"); + public static final IppValueTag NOTSETTABLE = new IppValueTag(0x15, ""); + public static final IppValueTag DELETEATTR = new IppValueTag(0x16, ""); + public static final IppValueTag ADMINDEFINE = new IppValueTag(0x17, ""); + public static final IppValueTag INTEGER = new IppValueTag(0x21, "integer"); + public static final IppValueTag BOOLEAN = new IppValueTag(0x22, "boolean"); + public static final IppValueTag ENUM = new IppValueTag(0x23, "enum"); + public static final IppValueTag STRING = new IppValueTag(0x30, "octetString"); + public static final IppValueTag DATE = new IppValueTag(0x31, "dateTime"); + public static final IppValueTag RESOLUTION = new IppValueTag(0x32, "resolution"); + public static final IppValueTag RANGE = new IppValueTag(0x33, "rangeOfInteger"); + public static final IppValueTag BEGIN_COLLECTION = new IppValueTag(0x34, ""); + public static final IppValueTag TEXTLANG = new IppValueTag(0x35, "resolution"); + public static final IppValueTag NAMELANG = new IppValueTag(0x36, "nameWithLanguage"); + public static final IppValueTag END_COLLECTION = new IppValueTag(0x37, ""); + public static final IppValueTag TEXT = new IppValueTag(0x41, "textWithoutLanguage"); + public static final IppValueTag NAME = new IppValueTag(0x42, "nameWithoutLanguage"); + public static final IppValueTag KEYWORD = new IppValueTag(0x44, "keyword"); + public static final IppValueTag URI = new IppValueTag(0x45, "uri"); + public static final IppValueTag URISCHEME = new IppValueTag(0x46, "uriScheme"); + public static final IppValueTag CHARSET = new IppValueTag(0x47, "charset"); + public static final IppValueTag LANGUAGE = new IppValueTag(0x48, "naturalLanguage"); + public static final IppValueTag MIMETYPE = new IppValueTag(0x49, "mimeMediaType"); + public static final IppValueTag MEMBERNAME = new IppValueTag(0x4A, ""); + public static final IppValueTag MASK = new IppValueTag(0x7FFFFFFF, ""); + public static final IppValueTag COPY = new IppValueTag(0x80000001, ""); + + private IppValueTag(int value, String description) { + this.value = value; + this.description = description; + } + + public int getValue() { + return this.value; + } + + + public String toString() { + return this.description; + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/auth/RequestingUserPassword.java b/jspi/src/main/java/de/lohndirekt/print/attribute/auth/RequestingUserPassword.java new file mode 100644 index 0000000..b89289e --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/auth/RequestingUserPassword.java @@ -0,0 +1,56 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.auth; + +import java.util.Locale; + +import javax.print.attribute.PrintRequestAttribute; +import javax.print.attribute.TextSyntax; + +public class RequestingUserPassword extends TextSyntax implements PrintRequestAttribute{ + + + /** + * @param value + */ + public RequestingUserPassword(String name, Locale locale) { + super(name, locale); + } + + /** + * + */ + + public Class getCategory() { + return RequestingUserPassword.class; + } + + /** + * + */ + + public static String getIppName() { + return "requesting-user-password"; + } + + public String getName() { + return RequestingUserPassword.getIppName(); + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/cups/DeviceClass.java b/jspi/src/main/java/de/lohndirekt/print/attribute/cups/DeviceClass.java new file mode 100644 index 0000000..4607f1a --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/cups/DeviceClass.java @@ -0,0 +1,65 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.cups; + +import java.util.Locale; + +import javax.print.attribute.Attribute; +import javax.print.attribute.TextSyntax; + + +public class DeviceClass extends TextSyntax implements Attribute { + +public final static DeviceClass FILE = new DeviceClass("file", Locale.getDefault()); + public final static DeviceClass DIRECT = new DeviceClass("direct", Locale.getDefault()); + public final static DeviceClass SERIAL = new DeviceClass("serial", Locale.getDefault()); + public final static DeviceClass NETWORK = new DeviceClass("network", Locale.getDefault()); + + /** + * @param value + * @param locale + */ + public DeviceClass(String value, Locale locale) { + super(value, locale); + } + + /** + * + */ + + public Class getCategory() { + return this.getClass(); + } + + /** + * + */ + + public String getName() { + return DeviceClass.getIppName(); + } + + /** + * + */ + public static String getIppName() { + return "device-class"; + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/cups/DeviceUri.java b/jspi/src/main/java/de/lohndirekt/print/attribute/cups/DeviceUri.java new file mode 100644 index 0000000..1c626ce --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/cups/DeviceUri.java @@ -0,0 +1,56 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.cups; + +import java.net.URI; + +import javax.print.attribute.Attribute; +import javax.print.attribute.URISyntax; + + +public class DeviceUri extends URISyntax implements Attribute { + + /** + * @param uri + */ + public DeviceUri(URI uri) { + super(uri); + } + + /** + * + */ + + public Class getCategory() { + return this.getClass(); + } + + /** + * + */ + + public String getName() { + return DeviceUri.getIppName(); + } + + public static String getIppName(){ + return "device-uri"; + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/cups/JobKLimit.java b/jspi/src/main/java/de/lohndirekt/print/attribute/cups/JobKLimit.java new file mode 100644 index 0000000..17177dd --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/cups/JobKLimit.java @@ -0,0 +1,59 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.cups; + +import javax.print.attribute.IntegerSyntax; +import javax.print.attribute.PrintServiceAttribute; + + +public class JobKLimit extends IntegerSyntax implements PrintServiceAttribute { + + /** + * @param value + */ + public JobKLimit(int value) { + super(value); + } + + /** + * @param value + * @param lowerBound + * @param upperBound + */ + public JobKLimit(int value, int lowerBound, int upperBound) { + super(value, lowerBound, upperBound); + } + + /** + * + */ + + public Class getCategory() { + return this.getClass(); + } + + public String getName() { + return JobKLimit.getIppName(); + } + + public static String getIppName(){ + return "job-k-limit"; + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/cups/JobPageLimit.java b/jspi/src/main/java/de/lohndirekt/print/attribute/cups/JobPageLimit.java new file mode 100644 index 0000000..ed73339 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/cups/JobPageLimit.java @@ -0,0 +1,58 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.cups; + +import javax.print.attribute.IntegerSyntax; +import javax.print.attribute.PrintServiceAttribute; + + +public class JobPageLimit extends IntegerSyntax implements PrintServiceAttribute { + + /** + * @param value + */ + public JobPageLimit(int value) { + super(value); + } + + /** + * @param value + * @param lowerBound + * @param upperBound + */ + public JobPageLimit(int value, int lowerBound, int upperBound) { + super(value, lowerBound, upperBound); + } + + /** + * + */ + + public Class getCategory() { + return this.getClass(); + } + + public String getName() { + return JobPageLimit.getIppName(); + } + + public static String getIppName(){ + return "job-page-limit"; + } +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/cups/JobQuotaPeriod.java b/jspi/src/main/java/de/lohndirekt/print/attribute/cups/JobQuotaPeriod.java new file mode 100644 index 0000000..9e99693 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/cups/JobQuotaPeriod.java @@ -0,0 +1,63 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.cups; + +import javax.print.attribute.IntegerSyntax; +import javax.print.attribute.PrintServiceAttribute; + + +public class JobQuotaPeriod extends IntegerSyntax implements PrintServiceAttribute { + + /** + * @param value + */ + public JobQuotaPeriod(int value) { + super(value); + } + + /** + * @param value + * @param lowerBound + * @param upperBound + */ + public JobQuotaPeriod(int value, int lowerBound, int upperBound) { + super(value, lowerBound, upperBound); + } + + /** + * + */ + + public Class getCategory() { + return this.getClass(); + } + + /** + * + */ + + public String getName() { + return JobQuotaPeriod.getIppName(); + } + + public static String getIppName(){ + return "job-quota-period"; + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/cups/MemberNames.java b/jspi/src/main/java/de/lohndirekt/print/attribute/cups/MemberNames.java new file mode 100644 index 0000000..6feb9b7 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/cups/MemberNames.java @@ -0,0 +1,61 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.cups; + +import java.util.Locale; + +import javax.print.attribute.Attribute; +import javax.print.attribute.TextSyntax; + + +public class MemberNames extends TextSyntax implements Attribute { + + + /** + * @param value + * @param locale + */ + public MemberNames(String value, Locale locale) { + super(value, locale); + } + + /** + * + */ + + public Class getCategory() { + return this.getClass(); + } + + /** + * + */ + + public String getName() { + return MemberNames.getIppName(); + } + + /** + * + */ + public static String getIppName() { + return "member-names"; + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/cups/MemberUris.java b/jspi/src/main/java/de/lohndirekt/print/attribute/cups/MemberUris.java new file mode 100644 index 0000000..9baf580 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/cups/MemberUris.java @@ -0,0 +1,56 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.cups; + +import java.net.URI; + +import javax.print.attribute.Attribute; +import javax.print.attribute.URISyntax; + + +public class MemberUris extends URISyntax implements Attribute { + + /** + * @param uri + */ + public MemberUris(URI uri) { + super(uri); + } + + /** + * + */ + + public Class getCategory() { + return this.getClass(); + } + + /** + * + */ + + public String getName() { + return MemberUris.getIppName(); + } + + public static String getIppName(){ + return "member-uris"; + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/cups/PrinterType.java b/jspi/src/main/java/de/lohndirekt/print/attribute/cups/PrinterType.java new file mode 100644 index 0000000..a31a4d7 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/cups/PrinterType.java @@ -0,0 +1,141 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.cups; + +import javax.print.attribute.IntegerSyntax; +import javax.print.attribute.PrintServiceAttribute; + +public class PrinterType extends IntegerSyntax implements PrintServiceAttribute { + + public static final int IS_PRINTER_CLASS = 1 << 0; + public static final int IS_REMOTE_DESTINATION = 1 << 1; + public static final int CAN_BLACK = 1 << 2; + public static final int CAN_COLOR = 1 << 3; + public static final int CAN_DUPLEX = 1 << 4; + public static final int CAN_STAPLE = 1 << 5; + public static final int CAN_UNCOLLATED = 1 << 6; + public static final int CAN_COLLATED = 1 << 7; + public static final int CAN_PUNCH = 1 << 8; + public static final int CAN_COVER = 1 << 9; + public static final int CAN_BIND = 1 << 10; + public static final int CAN_SORT = 1 << 11; + public static final int CAN_A4 = 1 << 12; + public static final int CAN_A2 = 1 << 13; + public static final int CAN_LARGER_A2 = 1 << 14; + public static final int CAN_USER_DEFINED_MEDIA_SIZE = 1 << 15; + public static final int IS_IMPLICIT_CLASS = 1 << 16; + + public boolean isPrinterClass() { + return (getValue() & IS_PRINTER_CLASS) == 1; + } + + public boolean isRemoteDestination() { + return (getValue() & IS_REMOTE_DESTINATION) == 1; + } + + public boolean canPrintBlack() { + return (getValue() & CAN_BLACK) == 1; + } + + public boolean canPrintColor() { + return (getValue() & CAN_COLOR) == 1; + } + + public boolean canDuplex() { + return (getValue() & CAN_DUPLEX) == 1; + } + + public boolean canStaple() { + return (getValue() & CAN_STAPLE) == 1; + } + + public boolean canUncollated() { + return (getValue() & CAN_UNCOLLATED) == 1; + } + + public boolean canCollated() { + return (getValue() & CAN_COLLATED) == 1; + } + + public boolean canPunch() { + return (getValue() & CAN_PUNCH) == 1; + } + + public boolean canCover() { + return (getValue() & CAN_COVER) == 1; + } + + public boolean canBind() { + return (getValue() & CAN_BIND) == 1; + } + + public boolean canSort() { + return (getValue() & CAN_SORT) == 1; + } + + public boolean canA4() { + return (getValue() & CAN_A4) == 1; + } + + public boolean canA2() { + return (getValue() & CAN_A2) == 1; + } + public boolean canLargerA2() { + return (getValue() & CAN_LARGER_A2) == 1; + } + + public boolean canUserDefinedMediaSize() { + return (getValue() & CAN_USER_DEFINED_MEDIA_SIZE) == 1; + } + public boolean isImplicitClass() { + return (getValue() & IS_IMPLICIT_CLASS) == 1; + } + + + /** + * @param value + */ + public PrinterType(int value) { + super(value); + } + + /** + * + */ + + public Class getCategory() { + return this.getClass(); + } + + /** + * + */ + + public String getName() { + return PrinterType.getIppName(); + } + + /** + * + */ + public static final String getIppName() { + return "printer-type"; + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/Charset.java b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/Charset.java new file mode 100644 index 0000000..0897f68 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/Charset.java @@ -0,0 +1,60 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.ipp; + +import java.util.Locale; + +import javax.print.attribute.PrintRequestAttribute; +import javax.print.attribute.TextSyntax; + +public class Charset extends TextSyntax implements PrintRequestAttribute { + + public final static Charset ISO_8859_1 = new Charset("iso-8859-1", Locale.getDefault()); + public final static Charset ISO_8859_15 = new Charset("iso-8859-15", Locale.getDefault()); + public final static Charset UTF_8 = new Charset("utf-8", Locale.getDefault()); + public final static Charset US_ASCII = new Charset("us-ascii", Locale.getDefault()); + + /** + * @param value + */ + public Charset(String name, Locale locale) { + super(name, locale); + } + + /** + * + */ + + public Class getCategory() { + return Charset.class; + } + + /** + * + */ + + public static String getIppName() { + return "attributes-charset"; + } + + public String getName() { + return Charset.getIppName(); + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/DetailedStatusMessage.java b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/DetailedStatusMessage.java new file mode 100644 index 0000000..3c64978 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/DetailedStatusMessage.java @@ -0,0 +1,56 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.ipp; + +import java.util.Locale; + +import javax.print.attribute.Attribute; +import javax.print.attribute.TextSyntax; + +public class DetailedStatusMessage extends TextSyntax implements Attribute{ + + + /** + * @param value + */ + public DetailedStatusMessage(String name, Locale locale) { + super(name, locale); + } + + /** + * + */ + + public Class getCategory() { + return DetailedStatusMessage.class; + } + + /** + * + */ + + public static String getIppName() { + return "detailed-status-message"; + } + + public String getName() { + return DetailedStatusMessage.getIppName(); + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/DocumentFormat.java b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/DocumentFormat.java new file mode 100644 index 0000000..b117992 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/DocumentFormat.java @@ -0,0 +1,55 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.ipp; + +import java.util.Locale; + +import javax.print.attribute.DocAttribute; +import javax.print.attribute.TextSyntax; + +public class DocumentFormat extends TextSyntax implements DocAttribute { + + /** + * @param value + */ + public DocumentFormat(String name, Locale locale) { + super(name, locale); + } + + /** + * + */ + + public Class getCategory() { + return DocumentFormat.class; + } + + /** + * + */ + + public static String getIppName() { + return "document-format"; + } + + public String getName() { + return DocumentFormat.getIppName(); + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/LastDocument.java b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/LastDocument.java new file mode 100644 index 0000000..28fdd60 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/LastDocument.java @@ -0,0 +1,78 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.ipp; + +import javax.print.attribute.DocAttribute; +import javax.print.attribute.EnumSyntax; + +public class LastDocument extends EnumSyntax implements DocAttribute { + + public final static LastDocument FALSE = new LastDocument(0); + public final static LastDocument TRUE = new LastDocument(1); + + /** + * + */ + protected EnumSyntax[] getEnumValueTable() { + return new EnumSyntax[] { FALSE, TRUE}; + } + + /** + * + */ + protected int getOffset() { + return 0; + } + + /** + * + */ + protected String[] getStringTable() { + return new String[] { "false", "true" }; + } + + /** + * @param value + */ + public LastDocument(int value) { + super(value); + } + + /** + * + */ + public Class getCategory() { + return this.getClass(); + } + + /** + * + */ + public String getName() { + return LastDocument.getIppName(); + } + + /** + * @return + */ + public static String getIppName() { + return "last-document"; + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/NaturalLanguage.java b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/NaturalLanguage.java new file mode 100644 index 0000000..203662e --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/NaturalLanguage.java @@ -0,0 +1,61 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.ipp; + +import java.util.Locale; + +import javax.print.attribute.PrintRequestAttribute; +import javax.print.attribute.TextSyntax; + +public class NaturalLanguage extends TextSyntax implements PrintRequestAttribute { + + public final static NaturalLanguage EN = new NaturalLanguage("en", Locale.getDefault()); + public final static NaturalLanguage DE = new NaturalLanguage("de", Locale.getDefault()); + + + + + /** + * @param value + */ + public NaturalLanguage(String value, Locale locale) { + super(value, locale); + } + + /** + * + */ + + public Class getCategory() { + return NaturalLanguage.class; + } + + public String getName() { + return NaturalLanguage.getIppName(); + } + + /** + * + */ + + public final static String getIppName() { + return "attributes-natural-language"; + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/RequestedAttributes.java b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/RequestedAttributes.java new file mode 100644 index 0000000..72d872d --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/RequestedAttributes.java @@ -0,0 +1,55 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.ipp; + +import java.util.Locale; + +import javax.print.attribute.PrintRequestAttribute; +import javax.print.attribute.TextSyntax; + +public class RequestedAttributes extends TextSyntax implements PrintRequestAttribute { + + /** + * @param value + */ + public RequestedAttributes(String name, Locale locale) { + super(name, locale); + } + + /** + * + */ + + public Class getCategory() { + return RequestedAttributes.class; + } + + /** + * + */ + + public static String getIppName() { + return "requested-attributes"; + } + + public String getName() { + return RequestedAttributes.getIppName(); + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/StatusMessage.java b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/StatusMessage.java new file mode 100644 index 0000000..0053553 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/StatusMessage.java @@ -0,0 +1,56 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.ipp; + +import java.util.Locale; + +import javax.print.attribute.Attribute; +import javax.print.attribute.TextSyntax; + +public class StatusMessage extends TextSyntax implements Attribute{ + + + /** + * @param value + */ + public StatusMessage(String name, Locale locale) { + super(name, locale); + } + + /** + * + */ + + public Class getCategory() { + return StatusMessage.class; + } + + /** + * + */ + + public static String getIppName() { + return "status-message"; + } + + public String getName() { + return StatusMessage.getIppName(); + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/UnknownAttribute.java b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/UnknownAttribute.java new file mode 100644 index 0000000..fbdd37e --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/UnknownAttribute.java @@ -0,0 +1,59 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.ipp; + +import java.util.Locale; + +import javax.print.attribute.SupportedValuesAttribute; +import javax.print.attribute.TextSyntax; + +public class UnknownAttribute extends TextSyntax implements SupportedValuesAttribute { + + /** + * @param value + */ + public UnknownAttribute(String value, Locale locale) { + super(value, locale); + } + + public UnknownAttribute(int number) { + super(Integer.toString(number), Locale.getDefault()); + } + + /** + * + */ + + public Class getCategory() { + return UnknownAttribute.class; + } + + /** + * + */ + + public static String getIppName() { + return "unknown-attribute"; + } + + public String getName() { + return getIppName(); + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/jobdesc/JobId.java b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/jobdesc/JobId.java new file mode 100644 index 0000000..de38735 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/jobdesc/JobId.java @@ -0,0 +1,53 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.ipp.jobdesc; + +import javax.print.attribute.IntegerSyntax; +import javax.print.attribute.PrintJobAttribute; +import javax.print.attribute.PrintRequestAttribute; + + +public class JobId extends IntegerSyntax implements PrintRequestAttribute, PrintJobAttribute { + + /** + * @param value + */ + public JobId(int value) { + super(value); + } + + public Class getCategory() { + return this.getClass(); + } + + /** + * + */ + public String getName() { + return JobId.getIppName(); + } + + /** + * + */ + public static String getIppName() { + return "job-id"; + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/jobdesc/JobMoreInfo.java b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/jobdesc/JobMoreInfo.java new file mode 100644 index 0000000..d235051 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/jobdesc/JobMoreInfo.java @@ -0,0 +1,56 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.ipp.jobdesc; + +import java.net.URI; + +import javax.print.attribute.PrintJobAttribute; +import javax.print.attribute.URISyntax; + + +public class JobMoreInfo extends URISyntax implements PrintJobAttribute { + + /** + * @param uri + */ + public JobMoreInfo(URI uri) { + super(uri); + } + + /** + * + */ + + public Class getCategory() { + return this.getClass(); + } + + /** + * + */ + + public String getName() { + return JobMoreInfo.getIppName(); + } + + public static String getIppName(){ + return "job-more-info"; + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/jobdesc/JobOriginatingHostName.java b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/jobdesc/JobOriginatingHostName.java new file mode 100644 index 0000000..cdb805e --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/jobdesc/JobOriginatingHostName.java @@ -0,0 +1,55 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.ipp.jobdesc; + +import java.util.Locale; + +import javax.print.attribute.PrintJobAttribute; +import javax.print.attribute.TextSyntax; + +public class JobOriginatingHostName extends TextSyntax implements PrintJobAttribute{ + + /** + * @param value + */ + public JobOriginatingHostName(String name, Locale locale) { + super(name, locale); + } + + /** + * + */ + + public Class getCategory() { + return JobOriginatingHostName.class; + } + + /** + * + */ + + public static String getIppName() { + return "job-originating-host-name"; + } + + public String getName() { + return JobOriginatingHostName.getIppName(); + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/jobdesc/JobPrinterUpTime.java b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/jobdesc/JobPrinterUpTime.java new file mode 100644 index 0000000..2fea629 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/jobdesc/JobPrinterUpTime.java @@ -0,0 +1,53 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.ipp.jobdesc; + +import javax.print.attribute.IntegerSyntax; +import javax.print.attribute.PrintJobAttribute; + + +public class JobPrinterUpTime extends IntegerSyntax implements PrintJobAttribute { + + /** + * @param value + */ + public JobPrinterUpTime(int value) { + super(value); + } + + public Class getCategory() { + return this.getClass(); + } + + /** + * + */ + + public String getName() { + return JobPrinterUpTime.getIppName(); + } + + /** + * + */ + public static String getIppName() { + return "job-printer-up-time"; + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/jobdesc/JobPrinterUri.java b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/jobdesc/JobPrinterUri.java new file mode 100644 index 0000000..d27353a --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/jobdesc/JobPrinterUri.java @@ -0,0 +1,56 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.ipp.jobdesc; + +import java.net.URI; + +import javax.print.attribute.PrintJobAttribute; +import javax.print.attribute.URISyntax; + + +public class JobPrinterUri extends URISyntax implements PrintJobAttribute { + + /** + * @param uri + */ + public JobPrinterUri(URI uri) { + super(uri); + } + + /** + * + */ + + public Class getCategory() { + return this.getClass(); + } + + /** + * + */ + + public String getName() { + return JobPrinterUri.getIppName(); + } + + public static String getIppName(){ + return "job-printer-uri"; + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/jobdesc/JobUri.java b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/jobdesc/JobUri.java new file mode 100644 index 0000000..78be9e9 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/jobdesc/JobUri.java @@ -0,0 +1,55 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.ipp.jobdesc; + +import java.net.URI; + +import javax.print.attribute.PrintJobAttribute; +import javax.print.attribute.PrintRequestAttribute; +import javax.print.attribute.URISyntax; + + +public class JobUri extends URISyntax implements PrintRequestAttribute, PrintJobAttribute { + + /** + * @param uri + */ + public JobUri(URI uri) { + super(uri); + } + + /** + * + */ + public Class getCategory() { + return this.getClass(); + } + + /** + * + */ + public String getName() { + return JobUri.getIppName(); + } + + public static String getIppName(){ + return "job-uri"; + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/jobdesc/LdJobStateReason.java b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/jobdesc/LdJobStateReason.java new file mode 100644 index 0000000..4e1cffb --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/jobdesc/LdJobStateReason.java @@ -0,0 +1,41 @@ +/* + * Created on 22.01.2004 + * + * + */ +package de.lohndirekt.print.attribute.ipp.jobdesc; + +import java.util.Locale; + +import javax.print.attribute.standard.JobStateReason; + +/** + * @author bpusch + * + * + */ +public class LdJobStateReason extends JobStateReason { + + private String stringValue; + + public static LdJobStateReason NONE = new LdJobStateReason("none", Locale.getDefault(), -1); + + /** + * @param value + */ + private LdJobStateReason(String stringValue, Locale locale, int value) { + super(value); + this.stringValue = stringValue; + } + + public String toString(){ + if (this.stringValue != null){ + return this.stringValue; + } else { + return super.toString(); + } + } + + + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/jobdesc/TimeAtCompleted.java b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/jobdesc/TimeAtCompleted.java new file mode 100644 index 0000000..1abb6b6 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/jobdesc/TimeAtCompleted.java @@ -0,0 +1,54 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.ipp.jobdesc; + + +import javax.print.attribute.IntegerSyntax; +import javax.print.attribute.PrintJobAttribute; + + +public class TimeAtCompleted extends IntegerSyntax implements PrintJobAttribute { + + /** + * @param value + */ + public TimeAtCompleted(int value) { + super(value); + } + + public Class getCategory() { + return this.getClass(); + } + + /** + * + */ + + public String getName() { + return TimeAtCompleted.getIppName(); + } + + /** + * + */ + public static String getIppName() { + return "time-at-completed"; + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/jobdesc/TimeAtCreation.java b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/jobdesc/TimeAtCreation.java new file mode 100644 index 0000000..9c22915 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/jobdesc/TimeAtCreation.java @@ -0,0 +1,53 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.ipp.jobdesc; + +import javax.print.attribute.IntegerSyntax; +import javax.print.attribute.PrintJobAttribute; + + +public class TimeAtCreation extends IntegerSyntax implements PrintJobAttribute { + + /** + * @param value + */ + public TimeAtCreation(int value) { + super(value); + } + + public Class getCategory() { + return this.getClass(); + } + + /** + * + */ + + public String getName() { + return TimeAtCreation.getIppName(); + } + + /** + * + */ + public static String getIppName() { + return "time-at-creation"; + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/jobdesc/TimeAtProcessing.java b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/jobdesc/TimeAtProcessing.java new file mode 100644 index 0000000..aff98ca --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/jobdesc/TimeAtProcessing.java @@ -0,0 +1,58 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.ipp.jobdesc; + +import javax.print.attribute.IntegerSyntax; +import javax.print.attribute.PrintJobAttribute; + + +public class TimeAtProcessing extends IntegerSyntax implements PrintJobAttribute { + + /** + * @param value + */ + public TimeAtProcessing(int value) { + super(value); + } + + public TimeAtProcessing() { + super(-1); + } + + + public Class getCategory() { + return this.getClass(); + } + + /** + * + */ + + public String getName() { + return TimeAtProcessing.getIppName(); + } + + /** + * + */ + public static String getIppName() { + return "time-at-processing"; + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/jobtempl/LdJobHoldUntil.java b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/jobtempl/LdJobHoldUntil.java new file mode 100644 index 0000000..3ec0fc0 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/jobtempl/LdJobHoldUntil.java @@ -0,0 +1,70 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.ipp.jobtempl; + +import java.util.Locale; + +import javax.print.attribute.PrintJobAttribute; +import javax.print.attribute.PrintRequestAttribute; +import javax.print.attribute.TextSyntax; + +/** + * The job-hold-until attribute specifies a hold time. + * In addition to the standard IPP/1.1 keyword names, + * CUPS supports name values of the form "HH:MM" and "HH:MM:SS" + * that specify a hold time.
+ * The hold time is in Greenwich Mean Time (GMT) and not in the + * local time zone. If the specified time is less than the + * current time, the job is held until the next day. + * + * @author bpusch + */ +public class LdJobHoldUntil extends TextSyntax implements PrintRequestAttribute, PrintJobAttribute { + + public final static LdJobHoldUntil NO_HOLD = new LdJobHoldUntil("no-hold",Locale.getDefault()); + public final static LdJobHoldUntil INDEFINITE = new LdJobHoldUntil("indefinite",Locale.getDefault()); + public final static LdJobHoldUntil DAY_TIME = new LdJobHoldUntil("day-time",Locale.getDefault()); + public final static LdJobHoldUntil EVENING = new LdJobHoldUntil("evening",Locale.getDefault()); + public final static LdJobHoldUntil NIGHT = new LdJobHoldUntil("night",Locale.getDefault()); + public final static LdJobHoldUntil WEEKEND = new LdJobHoldUntil("weekend",Locale.getDefault()); + public final static LdJobHoldUntil SECOND_SHIFT = new LdJobHoldUntil("second-shift",Locale.getDefault()); + public final static LdJobHoldUntil THIRD_SHIFT = new LdJobHoldUntil("third-shift",Locale.getDefault()); + + /** + * @param value + * @param locale + */ + public LdJobHoldUntil(String value, Locale locale) { + super(value, locale); + } + + public Class getCategory() { + return LdJobHoldUntil.class; + } + + public String getName() { + return LdJobHoldUntil.getIppName(); + } + + + public final static String getIppName() { + return "job-hold-until"; + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/jobtempl/LdMediaTray.java b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/jobtempl/LdMediaTray.java new file mode 100644 index 0000000..1470a8e --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/jobtempl/LdMediaTray.java @@ -0,0 +1,45 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.ipp.jobtempl; + +import javax.print.attribute.PrintJobAttribute; +import javax.print.attribute.PrintRequestAttribute; +import javax.print.attribute.standard.Media; + +public class LdMediaTray extends Media implements PrintRequestAttribute, PrintJobAttribute { + + private String name; + + /** + * @param trayName + * @throws NullPointerException if trayName is null + */ + public LdMediaTray(String trayName) { + super(0); + if (trayName == null) { + throw new NullPointerException("TrayName must not be null"); + } + this.name = trayName; + } + + public String toString() { + return this.name; + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/MultipleOperationTimeout.java b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/MultipleOperationTimeout.java new file mode 100644 index 0000000..4132ec4 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/MultipleOperationTimeout.java @@ -0,0 +1,52 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.ipp.printerdesc; + +import javax.print.attribute.IntegerSyntax; +import javax.print.attribute.PrintServiceAttribute; + + +public class MultipleOperationTimeout extends IntegerSyntax implements PrintServiceAttribute { + + /** + * @param value + */ + public MultipleOperationTimeout(int value) { + super(value); + } + + public Class getCategory() { + return this.getClass(); + } + + /** + * + */ + public String getName() { + return MultipleOperationTimeout.getIppName(); + } + + /** + * + */ + public static String getIppName() { + return "multiple-operation-time-out"; + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/NaturalLanguageConfigured.java b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/NaturalLanguageConfigured.java new file mode 100644 index 0000000..03658d4 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/NaturalLanguageConfigured.java @@ -0,0 +1,53 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.ipp.printerdesc; + +import java.util.Locale; + +import javax.print.attribute.PrintServiceAttribute; +import javax.print.attribute.TextSyntax; + +public class NaturalLanguageConfigured extends TextSyntax implements PrintServiceAttribute { + + /** + * @param value + */ + public NaturalLanguageConfigured(String name, Locale locale) { + super(name, locale); + } + + /** + * + */ + public Class getCategory() { + return NaturalLanguageConfigured.class; + } + + /** + * + */ + public static String getIppName() { + return "natural-language-configured"; + } + + public String getName() { + return NaturalLanguageConfigured.getIppName(); + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/PrinterCurrentTime.java b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/PrinterCurrentTime.java new file mode 100644 index 0000000..c37cf60 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/PrinterCurrentTime.java @@ -0,0 +1,59 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.ipp.printerdesc; + +import java.util.Date; + +import javax.print.attribute.DateTimeSyntax; +import javax.print.attribute.PrintServiceAttribute; + + +public class PrinterCurrentTime extends DateTimeSyntax implements PrintServiceAttribute { + + /** + * @param value + */ + public PrinterCurrentTime(Date value) { + super(value); + } + + /** + * + */ + + public Class getCategory() { + return this.getClass(); + } + + /** + * + */ + + public String getName() { + return PrinterCurrentTime.getIppName(); + } + + /** + * @return + */ + public static String getIppName() { + return "printer-current-time"; + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/PrinterDriverInstaller.java b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/PrinterDriverInstaller.java new file mode 100644 index 0000000..6122f7e --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/PrinterDriverInstaller.java @@ -0,0 +1,51 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.ipp.printerdesc; + +import java.net.URI; + +import javax.print.attribute.PrintServiceAttribute; +import javax.print.attribute.URISyntax; + +public final class PrinterDriverInstaller extends URISyntax implements PrintServiceAttribute { + + public PrinterDriverInstaller(URI uri) { + super(uri); + } + + public boolean equals(Object object) { + return (super.equals(object) && object instanceof PrinterDriverInstaller); + } + + public final Class getCategory() { + return PrinterDriverInstaller.class; + } + + public final String getName() { + return PrinterDriverInstaller.getIppName(); + } + + /** + * + */ + public static String getIppName() { + return "printer-driver-installer"; + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/PrinterStateMessage.java b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/PrinterStateMessage.java new file mode 100644 index 0000000..c74b077 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/PrinterStateMessage.java @@ -0,0 +1,62 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.ipp.printerdesc; + +import java.util.Locale; + +import javax.print.attribute.PrintServiceAttribute; +import javax.print.attribute.TextSyntax; + + +public class PrinterStateMessage extends TextSyntax implements PrintServiceAttribute { + + + + /** + * @param value + * @param locale + */ + public PrinterStateMessage(String value, Locale locale) { + super(value, locale); + } + + /** + * + */ + + public Class getCategory() { + return this.getClass(); + } + + /** + * + */ + + public String getName() { + return PrinterStateMessage.getIppName(); + } + + /** + * + */ + public static String getIppName() { + return "printer-state-message"; + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/PrinterUpTime.java b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/PrinterUpTime.java new file mode 100644 index 0000000..c3f9e4a --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/PrinterUpTime.java @@ -0,0 +1,53 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.ipp.printerdesc; + +import javax.print.attribute.IntegerSyntax; +import javax.print.attribute.PrintServiceAttribute; + + +public class PrinterUpTime extends IntegerSyntax implements PrintServiceAttribute { + + /** + * @param value + */ + public PrinterUpTime(int value) { + super(value); + } + + public Class getCategory() { + return this.getClass(); + } + + /** + * + */ + + public String getName() { + return PrinterUpTime.getIppName(); + } + + /** + * + */ + public static String getIppName() { + return "printer-up-time"; + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/defaults/CharsetConfigured.java b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/defaults/CharsetConfigured.java new file mode 100644 index 0000000..a7c8048 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/defaults/CharsetConfigured.java @@ -0,0 +1,56 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.ipp.printerdesc.defaults; + +import java.util.Locale; + +import javax.print.attribute.TextSyntax; + +import de.lohndirekt.print.attribute.DefaultAttribute; + +public class CharsetConfigured extends TextSyntax implements DefaultAttribute { + + /** + * @param value + */ + public CharsetConfigured(String name, Locale locale) { + super(name, locale); + } + + /** + * + */ + + public Class getCategory() { + return CharsetConfigured.class; + } + + /** + * + */ + + public static String getIppName() { + return "charset-configured"; + } + + public String getName() { + return CharsetConfigured.getIppName(); + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/defaults/CopiesDefault.java b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/defaults/CopiesDefault.java new file mode 100644 index 0000000..a2847b5 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/defaults/CopiesDefault.java @@ -0,0 +1,54 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.ipp.printerdesc.defaults; + +import javax.print.attribute.IntegerSyntax; + +import de.lohndirekt.print.attribute.DefaultAttribute; + + +public class CopiesDefault extends IntegerSyntax implements DefaultAttribute { + + /** + * @param value + */ + public CopiesDefault(int value) { + super(value); + } + + public Class getCategory() { + return this.getClass(); + } + + /** + * + */ + + public String getName() { + return CopiesDefault.getIppName(); + } + + /** + * + */ + public static String getIppName() { + return "copies-default"; + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/defaults/DocumentFormatDefault.java b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/defaults/DocumentFormatDefault.java new file mode 100644 index 0000000..fa13939 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/defaults/DocumentFormatDefault.java @@ -0,0 +1,56 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.ipp.printerdesc.defaults; + +import java.util.Locale; + +import javax.print.attribute.TextSyntax; + +import de.lohndirekt.print.attribute.DefaultAttribute; + +public class DocumentFormatDefault extends TextSyntax implements DefaultAttribute { + + /** + * @param value + */ + public DocumentFormatDefault(String value, Locale locale) { + super(value, locale); + } + + /** + * + */ + + public Class getCategory() { + return DocumentFormatDefault.class; + } + + public String getName() { + return DocumentFormatDefault.getIppName(); + } + + /** + * + */ + + public final static String getIppName() { + return "document-format-default"; + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/defaults/FinishingsDefault.java b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/defaults/FinishingsDefault.java new file mode 100644 index 0000000..80cc29f --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/defaults/FinishingsDefault.java @@ -0,0 +1,54 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.ipp.printerdesc.defaults; + +import javax.print.attribute.IntegerSyntax; + +import de.lohndirekt.print.attribute.DefaultAttribute; + + +public class FinishingsDefault extends IntegerSyntax implements DefaultAttribute { + + /** + * @param value + */ + public FinishingsDefault(int value) { + super(value); + } + + public Class getCategory() { + return this.getClass(); + } + + /** + * + */ + + public String getName() { + return FinishingsDefault.getIppName(); + } + + /** + * + */ + public static String getIppName() { + return "finishings-default"; + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/defaults/JobHoldUntilDefault.java b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/defaults/JobHoldUntilDefault.java new file mode 100644 index 0000000..75bbad7 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/defaults/JobHoldUntilDefault.java @@ -0,0 +1,56 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.ipp.printerdesc.defaults; + +import java.util.Locale; + +import javax.print.attribute.TextSyntax; + +import de.lohndirekt.print.attribute.DefaultAttribute; + +public class JobHoldUntilDefault extends TextSyntax implements DefaultAttribute { + + /** + * @param value + */ + public JobHoldUntilDefault(String value, Locale locale) { + super(value, locale); + } + + /** + * + */ + + public Class getCategory() { + return JobHoldUntilDefault.class; + } + + public String getName() { + return JobHoldUntilDefault.getIppName(); + } + + /** + * + */ + + public final static String getIppName() { + return "job-hold-until-default"; + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/defaults/JobPriorityDefault.java b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/defaults/JobPriorityDefault.java new file mode 100644 index 0000000..23fe06e --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/defaults/JobPriorityDefault.java @@ -0,0 +1,54 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.ipp.printerdesc.defaults; + +import javax.print.attribute.IntegerSyntax; + +import de.lohndirekt.print.attribute.DefaultAttribute; + + +public class JobPriorityDefault extends IntegerSyntax implements DefaultAttribute { + + /** + * @param value + */ + public JobPriorityDefault(int value) { + super(value); + } + + public Class getCategory() { + return this.getClass(); + } + + /** + * + */ + + public String getName() { + return JobPriorityDefault.getIppName(); + } + + /** + * + */ + public static String getIppName() { + return "job-priority-default"; + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/defaults/JobSheetsDefault.java b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/defaults/JobSheetsDefault.java new file mode 100644 index 0000000..1a3576e --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/defaults/JobSheetsDefault.java @@ -0,0 +1,61 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.ipp.printerdesc.defaults; + +import java.util.Locale; + +import javax.print.attribute.TextSyntax; + +import de.lohndirekt.print.attribute.DefaultAttribute; + + +public class JobSheetsDefault extends TextSyntax implements DefaultAttribute { + + /** + * @param value + * @param locale + */ + public JobSheetsDefault(String value, Locale locale) { + super(value, locale); + } + + /** + * + */ + + public Class getCategory() { + return this.getClass(); + } + + /** + * + */ + + public String getName() { + return JobSheetsDefault.getIppName(); + } + + /** + * + */ + public static String getIppName() { + return "job-sheets-default"; + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/defaults/MediaDefault.java b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/defaults/MediaDefault.java new file mode 100644 index 0000000..ea71474 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/defaults/MediaDefault.java @@ -0,0 +1,61 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.ipp.printerdesc.defaults; + +import java.util.Locale; + +import javax.print.attribute.TextSyntax; + +import de.lohndirekt.print.attribute.DefaultAttribute; + + +public class MediaDefault extends TextSyntax implements DefaultAttribute { + + /** + * @param value + * @param locale + */ + public MediaDefault(String value, Locale locale) { + super(value, locale); + } + + /** + * + */ + + public Class getCategory() { + return this.getClass(); + } + + /** + * + */ + + public String getName() { + return MediaDefault.getIppName(); + } + + /** + * + */ + public static String getIppName() { + return "media-default"; + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/defaults/MultipleDocumentHandlingDefault.java b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/defaults/MultipleDocumentHandlingDefault.java new file mode 100644 index 0000000..3786dd8 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/defaults/MultipleDocumentHandlingDefault.java @@ -0,0 +1,56 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.ipp.printerdesc.defaults; + +import java.util.Locale; + +import javax.print.attribute.TextSyntax; + +import de.lohndirekt.print.attribute.DefaultAttribute; + +public class MultipleDocumentHandlingDefault extends TextSyntax implements DefaultAttribute { + + /** + * @param value + */ + public MultipleDocumentHandlingDefault(String value, Locale locale) { + super(value, locale); + } + + /** + * + */ + + public Class getCategory() { + return MultipleDocumentHandlingDefault.class; + } + + public String getName() { + return MultipleDocumentHandlingDefault.getIppName(); + } + + /** + * + */ + + public final static String getIppName() { + return "multiple-document-handling-default"; + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/defaults/NumberUpDefault.java b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/defaults/NumberUpDefault.java new file mode 100644 index 0000000..41e62c9 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/defaults/NumberUpDefault.java @@ -0,0 +1,54 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.ipp.printerdesc.defaults; + +import javax.print.attribute.IntegerSyntax; + +import de.lohndirekt.print.attribute.DefaultAttribute; + + +public class NumberUpDefault extends IntegerSyntax implements DefaultAttribute { + + /** + * @param value + */ + public NumberUpDefault(int value) { + super(value); + } + + public Class getCategory() { + return this.getClass(); + } + + /** + * + */ + + public String getName() { + return NumberUpDefault.getIppName(); + } + + /** + * + */ + public static String getIppName() { + return "number-up-default"; + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/defaults/OrientationRequestedDefault.java b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/defaults/OrientationRequestedDefault.java new file mode 100644 index 0000000..8f71a7f --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/defaults/OrientationRequestedDefault.java @@ -0,0 +1,54 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.ipp.printerdesc.defaults; + +import javax.print.attribute.IntegerSyntax; + +import de.lohndirekt.print.attribute.DefaultAttribute; + + +public class OrientationRequestedDefault extends IntegerSyntax implements DefaultAttribute { + + /** + * @param value + */ + public OrientationRequestedDefault(int value) { + super(value); + } + + public Class getCategory() { + return this.getClass(); + } + + /** + * + */ + + public String getName() { + return OrientationRequestedDefault.getIppName(); + } + + /** + * + */ + public static String getIppName() { + return "orientation-requested-default"; + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/defaults/SidesDefault.java b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/defaults/SidesDefault.java new file mode 100644 index 0000000..cb1221c --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/defaults/SidesDefault.java @@ -0,0 +1,56 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.ipp.printerdesc.defaults; + +import java.util.Locale; + +import javax.print.attribute.TextSyntax; + +import de.lohndirekt.print.attribute.DefaultAttribute; + +public class SidesDefault extends TextSyntax implements DefaultAttribute { + + /** + * @param value + */ + public SidesDefault(String name, Locale locale) { + super(name, locale); + } + + /** + * + */ + + public Class getCategory() { + return SidesDefault.class; + } + + /** + * + */ + + public static String getIppName() { + return "sides-default"; + } + + public String getName() { + return SidesDefault.getIppName(); + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/CharsetSupported.java b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/CharsetSupported.java new file mode 100644 index 0000000..d751cf8 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/CharsetSupported.java @@ -0,0 +1,55 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.ipp.printerdesc.supported; + +import java.util.Locale; + +import javax.print.attribute.SupportedValuesAttribute; +import javax.print.attribute.TextSyntax; + +public class CharsetSupported extends TextSyntax implements SupportedValuesAttribute { + + /** + * @param value + */ + public CharsetSupported(String name, Locale locale) { + super(name, locale); + } + + /** + * + */ + + public Class getCategory() { + return CharsetSupported.class; + } + + /** + * + */ + + public static String getIppName() { + return "charset-supported"; + } + + public String getName() { + return CharsetSupported.getIppName(); + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/CompressionSupported.java b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/CompressionSupported.java new file mode 100644 index 0000000..a1d943d --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/CompressionSupported.java @@ -0,0 +1,56 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.ipp.printerdesc.supported; + +import java.util.Locale; + +import javax.print.attribute.SupportedValuesAttribute; +import javax.print.attribute.TextSyntax; + +public class CompressionSupported extends TextSyntax implements SupportedValuesAttribute { + + + /** + * @param value + */ + public CompressionSupported(String value, Locale locale) { + super(value, locale); + } + + /** + * + */ + + public Class getCategory() { + return CompressionSupported.class; + } + + public String getName() { + return CompressionSupported.getIppName(); + } + + /** + * + */ + + public final static String getIppName() { + return "compression-supported"; + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/DocumentFormatSupported.java b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/DocumentFormatSupported.java new file mode 100644 index 0000000..d72efea --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/DocumentFormatSupported.java @@ -0,0 +1,55 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.ipp.printerdesc.supported; + +import java.util.Locale; + +import javax.print.attribute.SupportedValuesAttribute; +import javax.print.attribute.TextSyntax; + +public class DocumentFormatSupported extends TextSyntax implements SupportedValuesAttribute { + + /** + * @param value + */ + public DocumentFormatSupported(String value, Locale locale) { + super(value, locale); + } + + /** + * + */ + + public Class getCategory() { + return DocumentFormatSupported.class; + } + + public String getName() { + return DocumentFormatSupported.getIppName(); + } + + /** + * + */ + + public final static String getIppName() { + return "document-format-supported"; + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/FinishingsSupported.java b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/FinishingsSupported.java new file mode 100644 index 0000000..ca697cb --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/FinishingsSupported.java @@ -0,0 +1,53 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.ipp.printerdesc.supported; + +import javax.print.attribute.IntegerSyntax; +import javax.print.attribute.SupportedValuesAttribute; + + +public class FinishingsSupported extends IntegerSyntax implements SupportedValuesAttribute { + + /** + * @param value + */ + public FinishingsSupported(int value) { + super(value); + } + + public Class getCategory() { + return this.getClass(); + } + + /** + * + */ + + public String getName() { + return FinishingsSupported.getIppName(); + } + + /** + * + */ + public static String getIppName() { + return "finishings-supported"; + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/GeneratedNaturalLanguageSupported.java b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/GeneratedNaturalLanguageSupported.java new file mode 100644 index 0000000..a25f5e2 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/GeneratedNaturalLanguageSupported.java @@ -0,0 +1,55 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.ipp.printerdesc.supported; + +import java.util.Locale; + +import javax.print.attribute.SupportedValuesAttribute; +import javax.print.attribute.TextSyntax; + +public class GeneratedNaturalLanguageSupported extends TextSyntax implements SupportedValuesAttribute { + + /** + * @param value + */ + public GeneratedNaturalLanguageSupported(String name, Locale locale) { + super(name, locale); + } + + /** + * + */ + + public Class getCategory() { + return GeneratedNaturalLanguageSupported.class; + } + + /** + * + */ + + public static String getIppName() { + return "generated-natural-language-supported"; + } + + public String getName() { + return GeneratedNaturalLanguageSupported.getIppName(); + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/IppVersionsSupported.java b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/IppVersionsSupported.java new file mode 100644 index 0000000..b883052 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/IppVersionsSupported.java @@ -0,0 +1,59 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.ipp.printerdesc.supported; + +import java.util.Locale; + +import javax.print.attribute.SupportedValuesAttribute; +import javax.print.attribute.TextSyntax; + +public class IppVersionsSupported extends TextSyntax implements SupportedValuesAttribute { + + /** + * @param value + * @param locale + */ + public IppVersionsSupported(String value, Locale locale) { + super(value, locale); + } + + /** + * + */ + + public Class getCategory() { + return this.getClass(); + } + + /** + * + */ + + public String getName() { + return IppVersionsSupported.getIppName(); + } + + /** + * + */ + public static String getIppName() { + return "ipp-versions-supported"; + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/JobHoldUntilSupported.java b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/JobHoldUntilSupported.java new file mode 100644 index 0000000..47f5925 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/JobHoldUntilSupported.java @@ -0,0 +1,55 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.ipp.printerdesc.supported; + +import java.util.Locale; + +import javax.print.attribute.SupportedValuesAttribute; +import javax.print.attribute.TextSyntax; + +public class JobHoldUntilSupported extends TextSyntax implements SupportedValuesAttribute { + + /** + * @param value + */ + public JobHoldUntilSupported(String value, Locale locale) { + super(value, locale); + } + + /** + * + */ + + public Class getCategory() { + return JobHoldUntilSupported.class; + } + + public String getName() { + return JobHoldUntilSupported.getIppName(); + } + + /** + * + */ + + public final static String getIppName() { + return "job-hold-until-supported"; + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/JobSheetsSupported.java b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/JobSheetsSupported.java new file mode 100644 index 0000000..12f8b33 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/JobSheetsSupported.java @@ -0,0 +1,60 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.ipp.printerdesc.supported; + +import java.util.Locale; + +import javax.print.attribute.SupportedValuesAttribute; +import javax.print.attribute.TextSyntax; + + +public class JobSheetsSupported extends TextSyntax implements SupportedValuesAttribute { + + /** + * @param value + * @param locale + */ + public JobSheetsSupported(String value, Locale locale) { + super(value, locale); + } + + /** + * + */ + + public Class getCategory() { + return this.getClass(); + } + + /** + * + */ + + public String getName() { + return JobSheetsSupported.getIppName(); + } + + /** + * + */ + public static String getIppName() { + return "job-sheets-supported"; + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/MediaSupported.java b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/MediaSupported.java new file mode 100644 index 0000000..c82ce93 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/MediaSupported.java @@ -0,0 +1,60 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.ipp.printerdesc.supported; + +import java.util.Locale; + +import javax.print.attribute.SupportedValuesAttribute; +import javax.print.attribute.TextSyntax; + + +public class MediaSupported extends TextSyntax implements SupportedValuesAttribute { + + /** + * @param value + * @param locale + */ + public MediaSupported(String value, Locale locale) { + super(value, locale); + } + + /** + * + */ + + public Class getCategory() { + return this.getClass(); + } + + /** + * + */ + + public String getName() { + return MediaSupported.getIppName(); + } + + /** + * + */ + public static String getIppName() { + return "media-supported"; + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/MultipleDocumentHandlingSupported.java b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/MultipleDocumentHandlingSupported.java new file mode 100644 index 0000000..4addab1 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/MultipleDocumentHandlingSupported.java @@ -0,0 +1,55 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.ipp.printerdesc.supported; + +import java.util.Locale; + +import javax.print.attribute.SupportedValuesAttribute; +import javax.print.attribute.TextSyntax; + +public class MultipleDocumentHandlingSupported extends TextSyntax implements SupportedValuesAttribute { + + /** + * @param value + */ + public MultipleDocumentHandlingSupported(String value, Locale locale) { + super(value, locale); + } + + /** + * + */ + + public Class getCategory() { + return MultipleDocumentHandlingSupported.class; + } + + public String getName() { + return MultipleDocumentHandlingSupported.getIppName(); + } + + /** + * + */ + + public final static String getIppName() { + return "multiple-document-handling-supported"; + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/MultipleDocumentJobsSupported.java b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/MultipleDocumentJobsSupported.java new file mode 100644 index 0000000..193d7c0 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/MultipleDocumentJobsSupported.java @@ -0,0 +1,91 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.ipp.printerdesc.supported; + +import javax.print.attribute.EnumSyntax; +import javax.print.attribute.SupportedValuesAttribute; + + +public class MultipleDocumentJobsSupported extends EnumSyntax implements SupportedValuesAttribute { + + public final static MultipleDocumentJobsSupported NOT_SUPPORTED = new MultipleDocumentJobsSupported(0); + public final static MultipleDocumentJobsSupported SUPPORTED = new MultipleDocumentJobsSupported(1); + + + /** + * + */ + + protected EnumSyntax[] getEnumValueTable() { + return new EnumSyntax[]{ + NOT_SUPPORTED, + SUPPORTED + }; + } + + /** + * + */ + + protected int getOffset() { + return 0; + } + + /** + * + */ + + protected String[] getStringTable() { + return new String[]{ + "not supported", + "supported" + }; + } + + /** + * @param value + */ + public MultipleDocumentJobsSupported(int value) { + super(value); + } + + /** + * + */ + + public Class getCategory() { + return this.getClass(); + } + + /** + * + */ + + public String getName() { + return MultipleDocumentJobsSupported.getIppName(); + } + + /** + * @return + */ + public static String getIppName() { + return "multiple-document-jobs-supported"; + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/OperationsSupported.java b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/OperationsSupported.java new file mode 100644 index 0000000..5f8d689 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/OperationsSupported.java @@ -0,0 +1,125 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.ipp.printerdesc.supported; + +import javax.print.attribute.EnumSyntax; +import javax.print.attribute.SupportedValuesAttribute; + +public class OperationsSupported extends EnumSyntax implements SupportedValuesAttribute { + + public static final OperationsSupported CREATE_PRINTER_SUBSCRIPTION = new OperationsSupported(0x16); + public static final OperationsSupported CREATE_JOB_SUBSCRIPTION = new OperationsSupported(0x17); + + public static final OperationsSupported CANCEL_SUBSCRIPTION = new OperationsSupported(0x1B); + public static final OperationsSupported ACTIVATE_PRINTER = new OperationsSupported(0x28); + + /* + * IPP operations... as defined in section 4.4.15 in rfc 2911 + */ + public static final OperationsSupported PRINT_JOB = new OperationsSupported(0x02); + public static final OperationsSupported PRINT_URI = new OperationsSupported(0x03); + public static final OperationsSupported VALIDATE_JOB = new OperationsSupported(0x04); + public static final OperationsSupported CREATE_JOB = new OperationsSupported(0x05); + public static final OperationsSupported SEND_DOCUMENT = new OperationsSupported(0x06); + public static final OperationsSupported SEND_URI = new OperationsSupported(0x07); + public static final OperationsSupported CANCEL_JOB = new OperationsSupported(0x08); + public static final OperationsSupported GET_JOB_ATTRIBUTES = new OperationsSupported(0x09); + public static final OperationsSupported PAUSE_PRINTER = new OperationsSupported(0x10); + public static final OperationsSupported GET_JOBS = new OperationsSupported(0x0A); + public static final OperationsSupported GET_PRINTER_ATTRIBUTES = new OperationsSupported(0x0B); + public static final OperationsSupported HOLD_JOB = new OperationsSupported(0x0C); + public static final OperationsSupported RELEASE_JOB = new OperationsSupported(0x0D); + public static final OperationsSupported RESTART_JOB = new OperationsSupported(0x0E); + public static final OperationsSupported RESUME_PRINTER = new OperationsSupported(0x11); + public static final OperationsSupported PURGE_JOBS = new OperationsSupported(0x12); + + /* + * More standard IPP operations? + */ + public static final OperationsSupported SET_PRINTER_ATTRIBUTES = new OperationsSupported(0x13); + public static final OperationsSupported SET_JOB_ATTRIBUTES = new OperationsSupported(0x14); + public static final OperationsSupported GET_PRINTER_SUPPORTED_VALUES = new OperationsSupported(0x15); + public static final OperationsSupported GET_SUBSCRIPTION_ATTRIBUTES = new OperationsSupported(0x18); + public static final OperationsSupported GET_SUBSCRIPTIONS = new OperationsSupported(0x19); + public static final OperationsSupported RENEW_SUBSCRIPTION = new OperationsSupported(0x1A); + public static final OperationsSupported GET_NOTIFICATIONS = new OperationsSupported(0x1C); + public static final OperationsSupported SEND_NOTIFICATIONS = new OperationsSupported(0x1D); + public static final OperationsSupported GET_PRINT_SUPPORT_FILES = new OperationsSupported(0x21); + public static final OperationsSupported ENABLE_PRINTER = new OperationsSupported(0x22); + public static final OperationsSupported DISABLE_PRINTER = new OperationsSupported(0x23); + public static final OperationsSupported PAUSE_PRINTER_AFTER_CURRENT_JOB = new OperationsSupported(0x24); + public static final OperationsSupported HOLD_NEW_JOBS = new OperationsSupported(0x25); + public static final OperationsSupported RELEASE_HELD_NEW_JOBS = new OperationsSupported(0x26); + public static final OperationsSupported DEACTIVATE_PRINTER = new OperationsSupported(0x27); + public static final OperationsSupported SHUTDOWN_PRINTER = new OperationsSupported(0x2A); + public static final OperationsSupported STARTUP_PRINTER = new OperationsSupported(0x2B); + public static final OperationsSupported REPROCESS_JOB = new OperationsSupported(0x2C); + public static final OperationsSupported CANCEL_CURRENT_JOB = new OperationsSupported(0x2D); + public static final OperationsSupported SUSPEND_CURRENT_JOB = new OperationsSupported(0x2E); + public static final OperationsSupported RESTART_PRINTER = new OperationsSupported(0x29); + public static final OperationsSupported RESUME_JOB = new OperationsSupported(0x2F); + public static final OperationsSupported PROMOTE_JOB = new OperationsSupported(0x30); + public static final OperationsSupported SCHEDULE_JOB_AFTER = new OperationsSupported(0x31); + + //Cups-specific values + public static final OperationsSupported PRIVATE = new OperationsSupported(0x4000); + public static final OperationsSupported CUPS_GET_DEFAULT = new OperationsSupported(0x4001); + public static final OperationsSupported CUPS_GET_PRINTERS = new OperationsSupported(0x4002); + public static final OperationsSupported CUPS_ADD_PRINTER = new OperationsSupported(0x4003); + public static final OperationsSupported CUPS_DELETE_PRINTER = new OperationsSupported(0x4004); + public static final OperationsSupported CUPS_GET_CLASSES = new OperationsSupported(0x4005); + public static final OperationsSupported CUPS_ADD_CLASS = new OperationsSupported(0x4006); + public static final OperationsSupported CUPS_DELETE_CLASS = new OperationsSupported(0x4007); + public static final OperationsSupported CUPS_ACCEPT_JOBS = new OperationsSupported(0x4008); + public static final OperationsSupported CUPS_REJECT_JOBS = new OperationsSupported(0x4009); + public static final OperationsSupported CUPS_SET_DEFAULT = new OperationsSupported(0x400A); + public static final OperationsSupported CUPS_GET_DEVICES = new OperationsSupported(0x400B); + public static final OperationsSupported CUPS_GET_PPDS = new OperationsSupported(0x400C); + public static final OperationsSupported CUPS_MOVE_JOB = new OperationsSupported(0x400D); + public static final OperationsSupported CUPS_ADD_DEVICE = new OperationsSupported(0x400E); + public static final OperationsSupported CUPS_DELETE_DEVICE = new OperationsSupported(0x400F); + + /** + * @param value + */ + public OperationsSupported(int value) { + super(value); + } + + /** + * + */ + + public Class getCategory() { + return this.getClass(); + } + + /** + * + */ + + public String getName() { + return OperationsSupported.getIppName(); + } + + public final static String getIppName() { + return "operations-supported"; + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/OrientationRequestedSupported.java b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/OrientationRequestedSupported.java new file mode 100644 index 0000000..5cec288 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/OrientationRequestedSupported.java @@ -0,0 +1,53 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.ipp.printerdesc.supported; + +import javax.print.attribute.IntegerSyntax; +import javax.print.attribute.SupportedValuesAttribute; + + +public class OrientationRequestedSupported extends IntegerSyntax implements SupportedValuesAttribute { + + /** + * @param value + */ + public OrientationRequestedSupported(int value) { + super(value); + } + + public Class getCategory() { + return this.getClass(); + } + + /** + * + */ + + public String getName() { + return OrientationRequestedSupported.getIppName(); + } + + /** + * + */ + public static String getIppName() { + return "orientation-requested-supported"; + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/OutputBinSupported.java b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/OutputBinSupported.java new file mode 100644 index 0000000..3b133ac --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/OutputBinSupported.java @@ -0,0 +1,56 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.ipp.printerdesc.supported; + +import java.util.Locale; + +import javax.print.attribute.SupportedValuesAttribute; +import javax.print.attribute.TextSyntax; + +public class OutputBinSupported extends TextSyntax implements +SupportedValuesAttribute { + + /** + * @param value + */ + public OutputBinSupported(String name, Locale locale) { + super(name, locale); + } + + /** + * + */ + + public Class getCategory() { + return OutputBinSupported.class; + } + + /** + * + */ + + public static String getIppName() { + return "output-bin-supported"; + } + + public String getName() { + return OutputBinSupported.getIppName(); + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/PageRangesSupported.java b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/PageRangesSupported.java new file mode 100644 index 0000000..21df5bc --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/PageRangesSupported.java @@ -0,0 +1,90 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */package de.lohndirekt.print.attribute.ipp.printerdesc.supported; + +import javax.print.attribute.EnumSyntax; +import javax.print.attribute.SupportedValuesAttribute; + + +public class PageRangesSupported extends EnumSyntax implements SupportedValuesAttribute { + + public static final PageRangesSupported NOT_SUPPORTED = new PageRangesSupported(0); + public static final PageRangesSupported SUPPORTED = new PageRangesSupported(1); + + /** + * + */ + + protected EnumSyntax[] getEnumValueTable() { + return new EnumSyntax[]{ + NOT_SUPPORTED, + SUPPORTED + + }; + } + + /** + * + */ + + protected int getOffset() { + return 0; + } + + /** + * + */ + + protected String[] getStringTable() { + return new String[]{ + "supported" , + "not supported" + }; + } + + /** + * @param value + */ + public PageRangesSupported(int value) { + super(value); + } + + /** + * + */ + + public Class getCategory() { + return this.getClass(); + } + + /** + * + */ + + public String getName() { + return PageRangesSupported.getIppName(); + } + + /** + * + */ + public static String getIppName() { + return "page-ranges-supported"; + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/PrinterUriSupported.java b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/PrinterUriSupported.java new file mode 100644 index 0000000..2b553ef --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/PrinterUriSupported.java @@ -0,0 +1,56 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.ipp.printerdesc.supported; + +import java.net.URI; + +import javax.print.attribute.SupportedValuesAttribute; +import javax.print.attribute.URISyntax; + + +public class PrinterUriSupported extends URISyntax implements SupportedValuesAttribute { + + /** + * @param uri + */ + public PrinterUriSupported(URI uri) { + super(uri); + } + + /** + * + */ + + public Class getCategory() { + return this.getClass(); + } + + /** + * + */ + + public String getName() { + return PrinterUriSupported.getIppName(); + } + + public static String getIppName(){ + return "printer-uri-supported"; + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/SidesSupported.java b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/SidesSupported.java new file mode 100644 index 0000000..e7fda6d --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/SidesSupported.java @@ -0,0 +1,55 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.ipp.printerdesc.supported; + +import java.util.Locale; + +import javax.print.attribute.SupportedValuesAttribute; +import javax.print.attribute.TextSyntax; + +public class SidesSupported extends TextSyntax implements SupportedValuesAttribute { + + /** + * @param value + */ + public SidesSupported(String name, Locale locale) { + super(name, locale); + } + + /** + * + */ + + public Class getCategory() { + return SidesSupported.class; + } + + /** + * + */ + + public static String getIppName() { + return "sides-supported"; + } + + public String getName() { + return SidesSupported.getIppName(); + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/UriAuthenticationSupported.java b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/UriAuthenticationSupported.java new file mode 100644 index 0000000..ea9f610 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/UriAuthenticationSupported.java @@ -0,0 +1,66 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.ipp.printerdesc.supported; + +import java.util.Locale; + +import javax.print.attribute.SupportedValuesAttribute; +import javax.print.attribute.TextSyntax; + +public class UriAuthenticationSupported extends TextSyntax implements SupportedValuesAttribute { + + public static UriAuthenticationSupported NONE = new UriAuthenticationSupported("none", Locale.getDefault()); + public static UriAuthenticationSupported REQUESTING_USER_NAME = + new UriAuthenticationSupported("requesting-user-name", Locale.getDefault()); + public static UriAuthenticationSupported BASIC = new UriAuthenticationSupported("basic", Locale.getDefault()); + public static UriAuthenticationSupported DIGEST = new UriAuthenticationSupported("digest", Locale.getDefault()); + public static UriAuthenticationSupported CERTIFICATION = new UriAuthenticationSupported("certification", Locale.getDefault()); + + /** + * @param value + * @param locale + */ + public UriAuthenticationSupported(String value, Locale locale) { + super(value, locale); + } + + /** + * + */ + + public Class getCategory() { + return this.getClass(); + } + + /** + * + */ + + public String getName() { + return UriAuthenticationSupported.getIppName(); + } + + /** + * @return + */ + public static String getIppName() { + return "uri-authentication-supported"; + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/UriSecuritySupported.java b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/UriSecuritySupported.java new file mode 100644 index 0000000..0a5ca10 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/ipp/printerdesc/supported/UriSecuritySupported.java @@ -0,0 +1,64 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.ipp.printerdesc.supported; + +import java.util.Locale; + +import javax.print.attribute.SupportedValuesAttribute; +import javax.print.attribute.TextSyntax; + +public class UriSecuritySupported extends TextSyntax implements SupportedValuesAttribute { + + public static UriSecuritySupported NONE = new UriSecuritySupported("none", Locale.getDefault()); + public static UriSecuritySupported SSl3 = + new UriSecuritySupported("ssl3", Locale.getDefault()); + public static UriSecuritySupported TSL = new UriSecuritySupported("tsl", Locale.getDefault()); + + /** + * @param value + * @param locale + */ + public UriSecuritySupported(String value, Locale locale) { + super(value, locale); + } + + /** + * + */ + + public Class getCategory() { + return this.getClass(); + } + + /** + * + */ + + public String getName() { + return UriSecuritySupported.getIppName(); + } + + /** + * @return + */ + public static String getIppName() { + return "uri-security-supported"; + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/attribute/undocumented/PrinterStateTime.java b/jspi/src/main/java/de/lohndirekt/print/attribute/undocumented/PrinterStateTime.java new file mode 100644 index 0000000..4de0c0f --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/attribute/undocumented/PrinterStateTime.java @@ -0,0 +1,53 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.attribute.undocumented; + +import javax.print.attribute.IntegerSyntax; +import javax.print.attribute.PrintServiceAttribute; + + +public class PrinterStateTime extends IntegerSyntax implements PrintServiceAttribute { + + /** + * @param value + */ + public PrinterStateTime(int value) { + super(value); + } + + public Class getCategory() { + return this.getClass(); + } + + /** + * + */ + + public String getName() { + return PrinterStateTime.getIppName(); + } + + /** + * + */ + public static String getIppName() { + return "printer-state-time"; + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/examples/Messages.java b/jspi/src/main/java/de/lohndirekt/print/examples/Messages.java new file mode 100644 index 0000000..18601b4 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/examples/Messages.java @@ -0,0 +1,52 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.examples; + +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +/** + * @author ld-development + * + * + */ +public class Messages { + + private static final String BUNDLE_NAME = "de.lohndirekt.print.examples.examples"; //$NON-NLS-1$ + + private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle(BUNDLE_NAME); + + /** + * + */ + private Messages() { + + } + /** + * @param key + * @return + */ + public static String getString(String key) { + try { + return RESOURCE_BUNDLE.getString(key); + } catch (MissingResourceException e) { + return '!' + key + '!'; + } + } +} diff --git a/jspi/src/main/java/de/lohndirekt/print/examples/MultiDocExample.java b/jspi/src/main/java/de/lohndirekt/print/examples/MultiDocExample.java new file mode 100644 index 0000000..3404ab6 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/examples/MultiDocExample.java @@ -0,0 +1,108 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.examples; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URISyntaxException; + +import javax.print.Doc; +import javax.print.DocFlavor; +import javax.print.MultiDocPrintJob; +import javax.print.MultiDocPrintService; +import javax.print.PrintException; +import javax.print.SimpleDoc; +import javax.print.attribute.HashDocAttributeSet; +import javax.print.attribute.HashPrintRequestAttributeSet; +import javax.print.attribute.PrintRequestAttributeSet; +import javax.print.attribute.standard.Copies; +import javax.print.attribute.standard.Media; +import javax.print.attribute.standard.MediaTray; +import javax.print.attribute.standard.Sides; + +import de.lohndirekt.print.IppPrintServiceLookup; +import de.lohndirekt.print.SimpleMultiDoc; + +public class MultiDocExample { + + public static void main(String[] args) + throws URISyntaxException, FileNotFoundException, PrintException, MalformedURLException { + // setting cups properties + System.getProperties().setProperty(IppPrintServiceLookup.URI_KEY, Messages.getString("cups.uri")); //$NON-NLS-1$ + System.getProperties().setProperty(IppPrintServiceLookup.USERNAME_KEY, Messages.getString("cups.username")); //$NON-NLS-1$ + System.getProperties().setProperty(IppPrintServiceLookup.PASSWORD_KEY, Messages.getString("cups.password")); //$NON-NLS-1$ + + // get the PrintServices + MultiDocPrintService[] services = new IppPrintServiceLookup().getMultiDocPrintServices(null, null); + + // get the first Printer + if (services.length > 0) { + MultiDocPrintService service = services[0]; + System.out.println("Printing on: " + service.getName()); + // create a job + MultiDocPrintJob job = service.createMultiDocPrintJob(); + + // set the job attributes + PrintRequestAttributeSet attributes = new HashPrintRequestAttributeSet(); + // we just want one copy + Copies copies = new Copies(1); + attributes.add(copies); + // we want duplex printing + Sides sides = Sides.DUPLEX; + attributes.add(sides); + // print it on the main media tray + Media media = MediaTray.MAIN; + // If you have special Mediatrays (like most printers) + // you can use the class LdMediaTray and give a String to the constructor like + // new LdMediaTray("Optional2"); + attributes.add(media); + + // Now create some documents + File testFile = new File(Messages.getString("pdfdocument.1")); + InputStream stream = new FileInputStream(testFile); + Doc doc = new SimpleDoc(stream, DocFlavor.INPUT_STREAM.PDF, new HashDocAttributeSet()); + File testFile2 = new File(Messages.getString("pdfdocument.2")); + InputStream stream2 = new FileInputStream(testFile2); + Doc doc2 = new SimpleDoc(stream2, DocFlavor.INPUT_STREAM.PDF, new HashDocAttributeSet()); + // now we need a MultiDoc + SimpleMultiDoc multiDoc = SimpleMultiDoc.create(doc); + // finally the print action + try { + // we are setting the doc and the job attributes + job.print(multiDoc, attributes); + + // now add several docs to your mutliDoc + // cups waits for the document with the attribute last-document = true + // wich you can set like this: + boolean lastDocument = true; + multiDoc.setNext(doc2, lastDocument); + + System.out.println("printing successfull..."); + } catch (PrintException e) { + e.printStackTrace(); + } + + } else { + System.out.println("no Services found!"); + } + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/examples/SimpleDocExample.java b/jspi/src/main/java/de/lohndirekt/print/examples/SimpleDocExample.java new file mode 100644 index 0000000..0e37c32 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/examples/SimpleDocExample.java @@ -0,0 +1,165 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.examples; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URISyntaxException; +import java.util.Locale; + +import javax.print.CancelablePrintJob; +import javax.print.Doc; +import javax.print.DocFlavor; +import javax.print.PrintException; +import javax.print.PrintService; +import javax.print.SimpleDoc; +import javax.print.attribute.HashDocAttributeSet; +import javax.print.attribute.HashPrintRequestAttributeSet; +import javax.print.attribute.PrintRequestAttributeSet; +import javax.print.attribute.standard.Copies; +import javax.print.attribute.standard.RequestingUserName; +import javax.print.attribute.standard.Sides; + +import de.lohndirekt.print.IppPrintServiceLookup; +import de.lohndirekt.print.attribute.auth.RequestingUserPassword; + +/** + * @author sefftinge + * + * + */ +public class SimpleDocExample { + + /** + * @param args + * @throws URISyntaxException + * @throws PrintException + * @throws IOException + */ + public static void main(String[] args) throws URISyntaxException, + PrintException, IOException { + + // setting cups properties + System.getProperties().setProperty(IppPrintServiceLookup.URI_KEY, + Messages.getString("cups.uri")); //$NON-NLS-1$ + System.getProperties().setProperty(IppPrintServiceLookup.USERNAME_KEY, + Messages.getString("cups.username")); //$NON-NLS-1$ + System.getProperties().setProperty(IppPrintServiceLookup.PASSWORD_KEY, + Messages.getString("cups.password")); //$NON-NLS-1$ + + // get the PrintServices + PrintService[] services = new IppPrintServiceLookup().getPrintServices(); + + // get the first Printer + if (services.length > 0) { + PrintService service = null; + System.out.println("Please choose a print service:"); + for (int i = 0; i < services.length; i++) { + PrintService service2 = services[i]; + System.out.println("[" + i + "] : " + service2.getName()); + } + // let the user choose a service + while (true) { + int serviceToUse = Integer.valueOf(readStdIn()).intValue(); + if (serviceToUse < 0 || serviceToUse >= services.length) { + System.out.println("Bitte eine Zahl zwischen 0 und " + + (services.length - 1) + " eingeben."); + } else { + service = services[serviceToUse]; + break; + } + } + + // ask for username + System.out.print("Username : "); + String username = readStdIn().trim(); + String password = null; + if (username != null && username.trim().length() > 0) { + System.out.print("Password : "); + password = readStdIn().trim(); + } + + System.out.println("Printing on: " + service.getName()); + // create a job + CancelablePrintJob job = (CancelablePrintJob) service + .createPrintJob(); + + // set the job attributes + PrintRequestAttributeSet attributes = new HashPrintRequestAttributeSet(); + + if (username != null && username.trim().length() > 0) { + RequestingUserName usernameAttr = new RequestingUserName( + username, Locale.GERMANY); + RequestingUserPassword userpassAttr = new RequestingUserPassword( + password, Locale.GERMANY); + attributes.add(usernameAttr); + attributes.add(userpassAttr); + } + // we just want one copy + Copies copies = new Copies(1); + attributes.add(copies); + // we want duplex printing + Sides sides = Sides.DUPLEX; + attributes.add(sides); + // print it on the main media tray + // Media media = MediaTray.MAIN; + // If you have special Mediatrays (like most printers) + // you can use the class LdMediaTray and give a String to the + // constructor like + // new LdMediaTray("Optional2"); + // attributes.add(media); + + // Now create a document + File testFile = new File(Messages.getString("pdfdocument.1")); + InputStream stream = new FileInputStream(testFile); + Doc doc = new SimpleDoc(stream, DocFlavor.INPUT_STREAM.PDF, + new HashDocAttributeSet()); + + // finally the print action + try { + // we are setting the doc and the job attributes + job.print(doc, attributes); + System.out.println("printing successfull..."); + } catch (PrintException e) { + e.printStackTrace(); + } + + } else { + System.out.println("no Services found!"); + } + } + + /** + * @return + */ + private static String readStdIn() { + StringBuffer sb = new StringBuffer(); + int ch; + try { + while ((ch = System.in.read()) != 10) { + sb.append((char) ch); + } + } catch (IOException e) { + e.printStackTrace(); + } + return sb.toString(); + } +} \ No newline at end of file diff --git a/jspi/src/main/java/de/lohndirekt/print/examples/examples.properties b/jspi/src/main/java/de/lohndirekt/print/examples/examples.properties new file mode 100644 index 0000000..26b3786 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/examples/examples.properties @@ -0,0 +1,7 @@ +#cups.uri=http://192.168.0.58:631 +#cups.uri=http://127.0.0.1:631 +cups.uri=http://127.0.0.1:9090/ipp/IppServlet +cups.username=root +cups.password=test +pdfdocument.1=./testfiles/test.pdf +pdfdocument.2=./testfiles/test.pdf \ No newline at end of file diff --git a/jspi/src/main/java/de/lohndirekt/print/exception/AuthenticationException.java b/jspi/src/main/java/de/lohndirekt/print/exception/AuthenticationException.java new file mode 100644 index 0000000..596be4e --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/exception/AuthenticationException.java @@ -0,0 +1,48 @@ +/* + * Created on 10.09.2004 + * + * + */ +package de.lohndirekt.print.exception; + +/** + * @author sefftinge + * + * + */ +public class AuthenticationException extends RuntimeException { + + /** + * + */ + public AuthenticationException() { + super(); + // TODO Auto-generated constructor stub + } + + /** + * @param message + */ + public AuthenticationException(String message) { + super(message); + // TODO Auto-generated constructor stub + } + + /** + * @param message + * @param cause + */ + public AuthenticationException(String message, Throwable cause) { + super(message, cause); + // TODO Auto-generated constructor stub + } + + /** + * @param cause + */ + public AuthenticationException(Throwable cause) { + super(cause); + // TODO Auto-generated constructor stub + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/exception/EndOfAttributesException.java b/jspi/src/main/java/de/lohndirekt/print/exception/EndOfAttributesException.java new file mode 100644 index 0000000..300ac1f --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/exception/EndOfAttributesException.java @@ -0,0 +1,26 @@ +package de.lohndirekt.print.exception; + +/** + * + * Exception used to signal that the EndAttributes tag has been + * reached while parsing an IppResponse + * + * @author bpusch + * + */ +public class EndOfAttributesException extends Exception { + + + + + + + + /* (Kein Javadoc) + * @see java.lang.Throwable#fillInStackTrace() + */ + public synchronized Throwable fillInStackTrace() { + return this; + } + +} diff --git a/jspi/src/main/java/de/lohndirekt/print/test.properties b/jspi/src/main/java/de/lohndirekt/print/test.properties new file mode 100644 index 0000000..251b59b --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/test.properties @@ -0,0 +1,3 @@ +cups.uri=http://192.168.0.58:631 +cups.username=horst +cups.password=test diff --git a/jspi/src/main/java/de/lohndirekt/print/test/IppRequestTestImpl.java b/jspi/src/main/java/de/lohndirekt/print/test/IppRequestTestImpl.java new file mode 100644 index 0000000..bdf17b9 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/test/IppRequestTestImpl.java @@ -0,0 +1,307 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.test; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Locale; +import java.util.Map; +import java.util.Set; +import java.util.logging.Logger; + +import javax.print.attribute.AttributeSet; +import javax.print.attribute.HashAttributeSet; +import javax.print.attribute.HashPrintJobAttributeSet; +import javax.print.attribute.PrintJobAttributeSet; +import javax.print.attribute.standard.ColorSupported; +import javax.print.attribute.standard.Compression; +import javax.print.attribute.standard.CopiesSupported; +import javax.print.attribute.standard.JobImpressionsSupported; +import javax.print.attribute.standard.JobKOctetsSupported; +import javax.print.attribute.standard.JobMediaSheetsSupported; +import javax.print.attribute.standard.JobPrioritySupported; +import javax.print.attribute.standard.JobSheets; +import javax.print.attribute.standard.MultipleDocumentHandling; +import javax.print.attribute.standard.NumberUpSupported; +import javax.print.attribute.standard.OrientationRequested; +import javax.print.attribute.standard.PDLOverrideSupported; +import javax.print.attribute.standard.ReferenceUriSchemesSupported; +import javax.print.attribute.standard.Sides; + +import de.lohndirekt.print.IppRequest; +import de.lohndirekt.print.IppResponse; +import de.lohndirekt.print.attribute.IppAttributeName; +import de.lohndirekt.print.attribute.IppStatus; +import de.lohndirekt.print.attribute.ipp.Charset; +import de.lohndirekt.print.attribute.ipp.NaturalLanguage; +import de.lohndirekt.print.attribute.ipp.jobtempl.LdJobHoldUntil; +import de.lohndirekt.print.attribute.ipp.printerdesc.PrinterDriverInstaller; +import de.lohndirekt.print.attribute.ipp.printerdesc.supported.CompressionSupported; +import de.lohndirekt.print.attribute.ipp.printerdesc.supported.FinishingsSupported; +import de.lohndirekt.print.attribute.ipp.printerdesc.supported.JobHoldUntilSupported; +import de.lohndirekt.print.attribute.ipp.printerdesc.supported.JobSheetsSupported; +import de.lohndirekt.print.attribute.ipp.printerdesc.supported.MediaSupported; +import de.lohndirekt.print.attribute.ipp.printerdesc.supported.MultipleDocumentHandlingSupported; +import de.lohndirekt.print.attribute.ipp.printerdesc.supported.OperationsSupported; +import de.lohndirekt.print.attribute.ipp.printerdesc.supported.OrientationRequestedSupported; +import de.lohndirekt.print.attribute.ipp.printerdesc.supported.PageRangesSupported; +import de.lohndirekt.print.attribute.ipp.printerdesc.supported.PrinterUriSupported; +import de.lohndirekt.print.attribute.ipp.printerdesc.supported.SidesSupported; + +public class IppRequestTestImpl implements IppRequest { + private Logger log = Logger.getLogger(this.getClass().getName()); + + class IppResponseTestImpl implements IppResponse { + + IppStatus status; + Map attributes; + + IppResponseTestImpl() { + + } + + /** + * @return + */ + public Map getAttributes() { + return attributes; + } + + /** + * @return + */ + public IppStatus getStatus() { + return status; + } + + } + + private IppResponseTestImpl response; + private Object data; + private OperationsSupported operation; + //Id wird in der Cups-API zwar übergeben, ist aber auch immer 1. + private PrintJobAttributeSet jobAttributes = new HashPrintJobAttributeSet(); + private AttributeSet operationAttributes = new HashAttributeSet(); + private AttributeSet printerAttributes = new HashAttributeSet(); + + /** + * @param printerAttributes + */ + public void setPrinterAttributes(AttributeSet attrs) { + this.printerAttributes = attrs; + } + + /** + * @param operation + */ + public IppRequestTestImpl(URI path, OperationsSupported operation) { + this.operation = operation; + init(); + } + + /** + * + */ + private void init() { + setStandardAttributes(); + } + + /** + * + */ + private void setStandardAttributes() { + operationAttributes.add(Charset.ISO_8859_1); + operationAttributes.add(NaturalLanguage.EN); + } + + /** + * @param attributes + */ + public void addOperationAttributes(AttributeSet attributes) { + this.operationAttributes.addAll(attributes); + } + + /** + * @param data the data as input stream + * @param the size of the data + */ + public void setData(InputStream data) { + this.data = data; + } + /** + * @param data + */ + public void setData(byte[] data) { + this.data = data; + } + + /** + * @param attributes + */ + public void setJobAttributes(PrintJobAttributeSet attributes) { + this.jobAttributes = attributes; + } + + public IppResponse send() throws IOException { + try { + this.response = new IppResponseTestImpl(); + this.send(this.operation); + } catch (Exception e){ + throw new RuntimeException(e); + } + return response; + } + + /** + * @param supported + */ + private void send(OperationsSupported operation) throws URISyntaxException { + if (operation.equals(OperationsSupported.GET_PRINTER_ATTRIBUTES)) { + sendGetPrinterAttributes(); + } else if (operation.equals(OperationsSupported.CUPS_GET_PRINTERS)) { + sendCupsGetPrinter(); + } else{ + log.warning("Call to request " + operation.toString() + " not implemented"); + this.response.attributes = new HashMap(); + } + response.status = IppStatus.SUCCESSFUL_OK; + } + + /** + * + */ + private void sendCupsGetPrinter() throws URISyntaxException { + Map attributes = new HashMap(); + Set printerUris = new HashSet(); + printerUris.add(new PrinterUriSupported(new URI("http://127.0.0.1"))); + attributes.put(IppAttributeName.PRINTER_URI_SUPPORTED.getCategory(),printerUris); + this.response.attributes = attributes; + } + + /** + * + */ + private void sendGetPrinterAttributes() throws URISyntaxException { + // + // - Printer attributes that are Job Template attributes ("xxx- + // default" "xxx-supported", and "xxx-ready" in the Table in + // Section 4.2), + // - "pdl-override-supported", + // - "compression-supported", + // - "job-k-octets-supported", + // - "job-impressions-supported", + // - "job-media-sheets-supported", + // - "printer-driver-installer", + // - "color-supported", and + // - "reference-uri-schemes-supported" + + Map attributes = new HashMap(); + Set pdlOverride = new HashSet(); + pdlOverride.add(PDLOverrideSupported.ATTEMPTED); + pdlOverride.add(PDLOverrideSupported.NOT_ATTEMPTED); + attributes.put(IppAttributeName.PDL_OVERRIDE_SUPPORTED.getCategory(), pdlOverride); + Set compression = new HashSet(); + compression.add(new CompressionSupported(Compression.GZIP.toString(), Locale.getDefault())); + compression.add(new CompressionSupported(Compression.NONE.toString(), Locale.getDefault())); + attributes.put(IppAttributeName.COMPRESSION_SUPORTED.getCategory(), compression); + Set jobKOctets = new HashSet(); + jobKOctets.add(new JobKOctetsSupported(1, 10)); + attributes.put(IppAttributeName.JOB_K_OCTETS_SUPPORTED.getCategory(), jobKOctets); + Set jobImpressions = new HashSet(); + jobImpressions.add(new JobImpressionsSupported(1, 10)); + attributes.put(IppAttributeName.JOB_IMPRESSIONS_SUPPORTED.getCategory(), jobImpressions); + Set jobMediaSheets = new HashSet(); + jobMediaSheets.add(new JobMediaSheetsSupported(1, 10)); + attributes.put(IppAttributeName.JOB_MEDIA_SHEETS_SUPPORTED.getCategory(), jobMediaSheets); + Set printerDriverInst = new HashSet(); + printerDriverInst.add(new PrinterDriverInstaller(new URI("http://127.0.0.1"))); + attributes.put(IppAttributeName.PRINTER_DRIVER_INSTALLER.getCategory(), printerDriverInst); + Set color = new HashSet(); + color.add(ColorSupported.SUPPORTED); + attributes.put(IppAttributeName.COLOR_SUPPORTED.getCategory(), color); + Set refUriScheme = new HashSet(); + refUriScheme.add(ReferenceUriSchemesSupported.HTTP); + refUriScheme.add(ReferenceUriSchemesSupported.FTP); + attributes.put(IppAttributeName.REFERENCE_URI_SCHEMES_SUPPORTED.getCategory(), refUriScheme); + + //Attributes named in 4.2 of rfc2911 + Set jobPrio = new HashSet(); + jobPrio.add(new JobPrioritySupported(99)); + attributes.put(IppAttributeName.JOB_PRIORIY_SUPPORTED.getCategory(), jobPrio); + Set jobHoldUntil = new HashSet(); + jobHoldUntil.add(new JobHoldUntilSupported(new LdJobHoldUntil("12:00:00",Locale.getDefault()).toString(),Locale.getDefault())); + jobHoldUntil.add(new JobHoldUntilSupported(LdJobHoldUntil.THIRD_SHIFT.toString(),Locale.getDefault())); + attributes.put(IppAttributeName.JOB_HOLD_UNTIL_SUPPORTED.getCategory(), jobHoldUntil); + Set jobSheets = new HashSet(); + jobSheets.add(new JobSheetsSupported(JobSheets.NONE.toString(), Locale.getDefault())); + jobSheets.add(new JobSheetsSupported(JobSheets.STANDARD.toString(), Locale.getDefault())); + attributes.put(IppAttributeName.JOB_SHEETS_SUPORTED.getCategory(), jobSheets); + Set multipleDocumentHandling = new HashSet(); + multipleDocumentHandling.add( + new MultipleDocumentHandlingSupported( + MultipleDocumentHandling.SEPARATE_DOCUMENTS_COLLATED_COPIES.toString(), + Locale.getDefault())); + multipleDocumentHandling.add( + new MultipleDocumentHandlingSupported( + MultipleDocumentHandling.SINGLE_DOCUMENT.toString(), + Locale.getDefault())); + attributes.put( + IppAttributeName.MULTIPLE_DOCUMENT_HANDLING_SUPPORTED.getCategory(), + multipleDocumentHandling); + Set copies = new HashSet(); + copies.add(new CopiesSupported(1, 100)); + attributes.put(IppAttributeName.COPIES_SUPPORTED.getCategory(), copies); + Set finishings = new HashSet(); + finishings.add(new FinishingsSupported(1)); + finishings.add(new FinishingsSupported(2)); + attributes.put(IppAttributeName.FINISHINGS_SUPPORTED.getCategory(), finishings); + Set pageRanges = new HashSet(); + pageRanges.add(PageRangesSupported.SUPPORTED); + attributes.put(IppAttributeName.PAGE_RANGES_SUPPORTED.getCategory(), pageRanges); + Set sides = new HashSet(); + sides.add(new SidesSupported(Sides.DUPLEX.toString(), Locale.getDefault())); + sides.add(new SidesSupported(Sides.TWO_SIDED_SHORT_EDGE.toString(), Locale.getDefault())); + attributes.put(IppAttributeName.SIDES_SUPPORTED.getCategory(), sides); + Set numberUp = new HashSet(); + numberUp.add(new NumberUpSupported(1, 10)); + numberUp.add(new NumberUpSupported(100)); + attributes.put(IppAttributeName.NUMBER_UP_SUPPORTED.getCategory(), numberUp); + Set orientationReq = new HashSet(); + orientationReq.add(new OrientationRequestedSupported(OrientationRequested.LANDSCAPE.getValue())); + orientationReq.add(new OrientationRequestedSupported(OrientationRequested.PORTRAIT.getValue())); + attributes.put(IppAttributeName.ORIENTATION_REQUESTED_SUPPORTED.getCategory(), orientationReq); + Set media = new HashSet(); + media.add(new MediaSupported("test", Locale.getDefault())); + media.add(new MediaSupported("test2", Locale.getDefault())); + attributes.put(IppAttributeName.MEDIA_SUPPORTED.getCategory(), media); + //media-ready not implemented + //printer-resolution-supported not implemented + //print-quality-supported not implemented + response.attributes = attributes; + + } + + private IppResponse getResponse() throws IOException { + return this.response; + } +} diff --git a/jspi/src/main/java/de/lohndirekt/print/test/IppRequestTestImplTest.java b/jspi/src/main/java/de/lohndirekt/print/test/IppRequestTestImplTest.java new file mode 100644 index 0000000..9f081a9 --- /dev/null +++ b/jspi/src/main/java/de/lohndirekt/print/test/IppRequestTestImplTest.java @@ -0,0 +1,71 @@ +/** + * Copyright (C) 2003 lohndirekt.de + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package de.lohndirekt.print.test; + +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.Iterator; +import java.util.Locale; +import java.util.Map; +import java.util.Set; + +import javax.print.attribute.Attribute; + +import junit.framework.TestCase; +import de.lohndirekt.print.IppRequest; +import de.lohndirekt.print.attribute.IppAttributeName; +import de.lohndirekt.print.attribute.ipp.UnknownAttribute; +import de.lohndirekt.print.attribute.ipp.printerdesc.supported.OperationsSupported; + +/** + * @author bpusch + * + * + */ +public class IppRequestTestImplTest extends TestCase { + + public void testSendGetPrinterAttributes() throws URISyntaxException, IOException { + Class unknownAttributeCategory = new UnknownAttribute("x", Locale.getDefault()).getCategory(); + IppRequest request = new IppRequestTestImpl(new URI("http://127.0.0.1"), OperationsSupported.GET_PRINTER_ATTRIBUTES); + Map attributes = request.send().getAttributes(); + for (Iterator iter = attributes.keySet().iterator(); iter.hasNext();) { + Class category = (Class) iter.next(); + //Should not return any unknown Attributes + assertFalse(category.equals(unknownAttributeCategory)); + Set attrs = (Set) attributes.get(category); + assertNotNull(attrs); + for (Iterator iterator = attrs.iterator(); iterator.hasNext();) { + Attribute element = (Attribute) iterator.next(); + assertEquals(category, element.getCategory()); + } + } + } + + public void testSendCupsGetPrinter() throws URISyntaxException, IOException { + IppRequest request = new IppRequestTestImpl(new URI("http://127.0.0.1"), OperationsSupported.CUPS_GET_PRINTERS); + Map attributes = request.send().getAttributes(); + assertTrue("Response must contain an attribute of category printer-uri-spported",attributes.containsKey(IppAttributeName.PRINTER_URI_SUPPORTED.getCategory())); + } + + public void testGetResponse() throws URISyntaxException, IOException { + //response is now returned by send() + } + +} diff --git a/jspi/src/main/webapp/META-INF/MANIFEST.MF b/jspi/src/main/webapp/META-INF/MANIFEST.MF new file mode 100644 index 0000000..5e94951 --- /dev/null +++ b/jspi/src/main/webapp/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Class-Path: + diff --git a/jspi/src/main/webapp/WEB-INF/lib/commons-httpclient-2.0.1.jar b/jspi/src/main/webapp/WEB-INF/lib/commons-httpclient-2.0.1.jar new file mode 100644 index 0000000000000000000000000000000000000000..65f9e3b2d9f71e4ade07dee88eaff7e8854c63b8 GIT binary patch literal 224754 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


9@bGT030d0QE`tTy zuHBx&DouQVzMk&pGXWx9R*Xz)6eF{+*6^mTA-S{435UgQ%7#Ta*WI&7H;8f}_aoJNQ>qQ`5NJY((lt9i^3(=t#aH)!1vO7_+n9 z#zpeG>@L3YL}Wpi$Sa8pD!#U@qP}s=t+*ek1xg5(ywbD(L`U=1J^czS%^8QWSM8hNGWHJ z?wFP;^(uGgaE~k;ozki%?2pmo|608}q+8`~{^p1oSi%2g!+zI`xBk7wzQsvllGnUNKT&I=o57i|EM!{T9H#JOZiJ5y!2 zp8B-8Ook1>+S#?%G1jm9j9#-Bx(6^zQA7wPC;)Lfdv3-75dD^*EfD=yzpd28GY-Vs zpr8=9V3{i_Qrzi?dkL0}@3v!5>V^Luf*@nlLywomtp%h zJ@^7J__(<=kg$})%cFM+y$yE`_+Hmcn7fOVRc-k$NA_AuFQ=%H-iI3g1ma@a9+lIvR)wjR;=HTCSt{S)jXVhX6g!39N97#;5j+;> zi$ge#vya1el`W~z0YQx8S(FYyaN1r}DSB(oPm~iiS)e^$`@9AB<=L(Ie2wr(`YF+# ze)`v)Wf(<~hRjn^gto9EgB7&W@hpm+-#&f(&l?UYB_%0{#8EQxeVAeMef;=3=OojJ zo2my~tP&v2QIHgXKm7Jz4kzunA}7h8;)eG>iW@xtv$7}o87Qu%Ec=69Dw{YL=5_>xDNPFzM{PVu~ z`RRMPpSOreD8?>tGB4yqU;woh0kVeOmvXgFhJe7I}>@g)7lK+RDB3AHxR z-(Rk0k#ZY%i5t4TMyH1W+#CH&rN*EK1RN3_Z-+Dl9dG-*6Q*l;wE!mi`k{-cD;Ox` zgS)xy@JQ<+*yH{@6e#3_xT$d!`!fXn)BF??hCuBq^(P_CQ`}EN+NZFeIW$jcKXYh3 zbbC-?{PMP>z!j)Hw0l@#{7SbpGWY6XvSF29Pl@~jHzBUtzxYimuD9Qi03550DDqEI zad7AJnMspaX4KiN$WXj^kk8ps^xzt)#|hYX;Lb^wl~xHN$ld7eBvNK=a!6&g=doFb znTp&C+O(pI*?HT{-5A{%Bgxf9t%-9nFn{%fSr3CXn%eR&_fAWetV)(NrdHxw0ZJLP zmC5bb@j|{(B1D#)D~&Ih^tr}mFPz_EwUG=eG{zdOB8kW~BQIi|c-=QFp`BQpIOW#T=#UoonIGw3IbYvW*%fvrJy2oUdz|l2Q z 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 X=~0665C-!FKm1_5uVgPMQepoC@N6KI literal 0 HcmV?d00001 diff --git a/jspi/src/main/webapp/WEB-INF/lib/commons-logging.jar b/jspi/src/main/webapp/WEB-INF/lib/commons-logging.jar new file mode 100644 index 0000000000000000000000000000000000000000..b73a80fab641131e6fbe3ae833549efb3c540d17 GIT binary patch literal 38015 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 F`9DH82$KK+ literal 0 HcmV?d00001 diff --git a/jspi/src/main/webapp/WEB-INF/web.xml b/jspi/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000..166fa5f --- /dev/null +++ b/jspi/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,22 @@ + + + jspi + + index.html + index.htm + index.jsp + default.html + default.htm + default.jsp + + + + IppServlet + IppServlet + IppServlet + + + IppServlet + /IppServlet + + \ No newline at end of file -- 2.20.1