diff --git a/build.gradle.kts b/build.gradle.kts index 55248f61..2fad1935 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -6,7 +6,7 @@ import org.jetbrains.dokka.gradle.DokkaTask plugins { id("org.jetbrains.kotlin.jvm") version "1.7.22" id("org.jetbrains.dokka") version "1.7.20" - id("org.sonarqube") version "4.3.1.3277" // https://plugins.gradle.org/plugin/org.sonarqube + id("org.sonarqube") version "4.4.1.3373" // https://plugins.gradle.org/plugin/org.sonarqube //id("org.sonarqube") version "3.5.0.2730" // supports java 8, dropped with 4.1 id("maven-publish") id("java-library") @@ -158,12 +158,17 @@ repo?.run { // tasks for publishing on maven repo val isRunningOnGithub = System.getenv("CI")?.toBoolean() ?: false println("isRunningOnGithub=$isRunningOnGithub") +// https://docs.gradle.org/current/userguide/jacoco_plugin.html +jacoco { + // https://mvnrepository.com/artifact/org.jacoco/jacoco-maven-plugin + toolVersion = "0.8.11" +} + // required for sonarqube code coverage // https://docs.sonarqube.org/latest/analysis/test-coverage/java-test-coverage tasks.jacocoTestReport { dependsOn(tasks.test) // https://stackoverflow.com/questions/67725347/jacoco-fails-on-gradle-7-0-2-and-kotlin-1-5-10 - //version = "0.8.7" reports { xml.required.set(true) csv.required.set(false) @@ -175,18 +180,19 @@ tasks.jacocoTestReport { // https://docs.sonarqube.org/latest/analysis/scan/sonarscanner-for-gradle/ // configure token with 'publish analysis' permission in file ~/.gradle/gradle.properties: // systemProp.sonar.login= -sonar { - properties { - property("sonar.host.url", "https://sonarcloud.io") - property("sonar.projectKey", "gmuth_ipp-client-kotlin") - property("sonar.organization", "gmuth") - //property("sonar.verbose", "true") - //property("sonar.junit.reportPaths", "build/test-results/test") - //property("sonar.jacoco.reportPaths", "build/jacoco/test.exec") - //property("sonar.coverage.jacoco.xmlReportPaths", "build/reports/jacoco/test/") - } -} - +//sonar { +// properties { +// property("sonar.host.url", "https://sonarcloud.io") +// property("sonar.projectKey", "gmuth_ipp-client-kotlin") +// property("sonar.organization", "gmuth") +// //property("sonar.verbose", "true") +// //property("sonar.junit.reportPaths", "build/test-results/test") +// //property("sonar.jacoco.reportPaths", "build/jacoco/test.exec") +// //property("sonar.coverage.jacoco.xmlReportPaths", "build/reports/jacoco/test/") +// } +//} + +// https://docs.sonarsource.com/sonarqube/latest/analyzing-source-code/scanners/sonarscanner-for-gradle/ tasks.sonar { dependsOn(tasks.jacocoTestReport) // for coverage } diff --git a/gradle.properties b/gradle.properties index c878a2c2..7fdb1fbf 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,4 +7,9 @@ org.gradle.jvmargs=-XX:MetaspaceSize=512M -XX:MaxMetaspaceSize=512M # java -XX:+PrintFlagsFinal -version|grep MaxHeapSize # Oracle-arm 11.0.5: MaxHeapSize = 2147483648 -#org.gradle.daemon=false \ No newline at end of file +#org.gradle.daemon=false + +# sonarcloud +systemProp.sonar.host.url=https://sonarcloud.io +systemProp.sonar.projectKey=gmuth_ipp-client-kotlin +systemProp.sonar.organization=gmuth diff --git a/src/main/kotlin/de/gmuth/ipp/attributes/ColorMode.kt b/src/main/kotlin/de/gmuth/ipp/attributes/ColorMode.kt index 1e2a21aa..fcdb2321 100644 --- a/src/main/kotlin/de/gmuth/ipp/attributes/ColorMode.kt +++ b/src/main/kotlin/de/gmuth/ipp/attributes/ColorMode.kt @@ -33,7 +33,6 @@ class ColorMode(private val keyword: String) : IppAttributeBuilder { else "Required attribute not found (print-color-mode-supported or output-mode-supported)" ) }, - Keyword, - keyword + Keyword, keyword ) } \ No newline at end of file diff --git a/src/main/kotlin/de/gmuth/ipp/attributes/CommunicationChannel.kt b/src/main/kotlin/de/gmuth/ipp/attributes/CommunicationChannel.kt index 2f57d458..fd276c3f 100644 --- a/src/main/kotlin/de/gmuth/ipp/attributes/CommunicationChannel.kt +++ b/src/main/kotlin/de/gmuth/ipp/attributes/CommunicationChannel.kt @@ -29,5 +29,4 @@ class CommunicationChannel( } } } - } \ No newline at end of file diff --git a/src/main/kotlin/de/gmuth/ipp/attributes/Marker.kt b/src/main/kotlin/de/gmuth/ipp/attributes/Marker.kt index a34fa5fd..52ee08b8 100644 --- a/src/main/kotlin/de/gmuth/ipp/attributes/Marker.kt +++ b/src/main/kotlin/de/gmuth/ipp/attributes/Marker.kt @@ -35,9 +35,9 @@ class Marker( UNKNOWN("#?"); companion object { - val log = getLogger(Color::class.java.name) + private val logger = getLogger(Color::class.java.name) fun fromString(code: String) = values().find { it.code == code.uppercase() } - ?: UNKNOWN.apply { log.warning { "Unknown color code: $code" } } + ?: UNKNOWN.apply { logger.warning { "Unknown color code: $code" } } } } diff --git a/src/main/kotlin/de/gmuth/ipp/attributes/MediaMargin.kt b/src/main/kotlin/de/gmuth/ipp/attributes/MediaMargin.kt index 5f1c4742..87edd91e 100644 --- a/src/main/kotlin/de/gmuth/ipp/attributes/MediaMargin.kt +++ b/src/main/kotlin/de/gmuth/ipp/attributes/MediaMargin.kt @@ -7,7 +7,7 @@ package de.gmuth.ipp.attributes import de.gmuth.ipp.core.IppAttribute import de.gmuth.ipp.core.IppTag.Integer -open class MediaMargin( +class MediaMargin( val left: Int? = null, val right: Int? = null, val top: Int? = null, diff --git a/src/main/kotlin/de/gmuth/ipp/attributes/MediaSize.kt b/src/main/kotlin/de/gmuth/ipp/attributes/MediaSize.kt index ff56ea8e..b3b4f8eb 100644 --- a/src/main/kotlin/de/gmuth/ipp/attributes/MediaSize.kt +++ b/src/main/kotlin/de/gmuth/ipp/attributes/MediaSize.kt @@ -13,11 +13,11 @@ import de.gmuth.ipp.core.IppTag.Integer // unit: 1/100 mm, e.g. 2540 = 1 inch class MediaSize(val xDimension: Int, val yDimension: Int) : IppAttributeBuilder { - override fun buildIppAttribute(printerAttributes: IppAttributesGroup) = - IppAttribute( - "media-size", BegCollection, IppCollection( - IppAttribute("x-dimension", Integer, xDimension), - IppAttribute("y-dimension", Integer, yDimension) - ) + override fun buildIppAttribute(printerAttributes: IppAttributesGroup) = IppAttribute( + "media-size", BegCollection, + IppCollection( + IppAttribute("x-dimension", Integer, xDimension), + IppAttribute("y-dimension", Integer, yDimension) ) + ) } \ No newline at end of file diff --git a/src/main/kotlin/de/gmuth/ipp/attributes/MediaSource.kt b/src/main/kotlin/de/gmuth/ipp/attributes/MediaSource.kt index 3a58a057..56f6db60 100644 --- a/src/main/kotlin/de/gmuth/ipp/attributes/MediaSource.kt +++ b/src/main/kotlin/de/gmuth/ipp/attributes/MediaSource.kt @@ -8,25 +8,33 @@ import de.gmuth.ipp.core.IppAttribute import de.gmuth.ipp.core.IppAttributeBuilder import de.gmuth.ipp.core.IppAttributesGroup import de.gmuth.ipp.core.IppTag.Keyword -import java.util.logging.Logger.getLogger -open class MediaSource(val keyword: String) : IppAttributeBuilder { +class MediaSource(val keyword: String) : IppAttributeBuilder { - val log = getLogger(javaClass.name) + companion object { + @JvmField + val Auto = MediaSource("auto") + + @JvmField + val Main = MediaSource("main") + + @JvmField + val Manual = MediaSource("manual") + + @JvmField + val Envelope = MediaSource("envelope") + + @JvmField + val Alternate = MediaSource("alternate") + + @JvmField + val ByPassTray = MediaSource("by-pass-tray") + + @JvmField + val LargeCapacity = MediaSource("large-capacity") + } override fun buildIppAttribute(printerAttributes: IppAttributesGroup) = IppAttribute("media-source", Keyword, keyword) - .apply { validateSource(printerAttributes) } - - private fun validateSource(printerAttributes: IppAttributesGroup) { - val mediaSourceSupported = printerAttributes["media-source-supported"] - if (mediaSourceSupported == null) { - log.fine { "printer does not provide attribute 'media-source-supported'" } - } else { - if (!mediaSourceSupported.values.contains(keyword)) { - log.warning { "media-source '$keyword' not supported by printer" } - log.warning { mediaSourceSupported.toString() } - } - } - } + } \ No newline at end of file diff --git a/src/main/kotlin/de/gmuth/ipp/attributes/PrinterState.kt b/src/main/kotlin/de/gmuth/ipp/attributes/PrinterState.kt index 79301679..bf06529d 100644 --- a/src/main/kotlin/de/gmuth/ipp/attributes/PrinterState.kt +++ b/src/main/kotlin/de/gmuth/ipp/attributes/PrinterState.kt @@ -22,7 +22,7 @@ enum class PrinterState(val code: Int) : IppAttributeBuilder { IppAttribute("printer-state", IppTag.Enum, code) companion object { - private fun fromInt(code: Int) = values().single { it.code == code } + fun fromInt(code: Int) = values().single { it.code == code } fun fromAttributes(attributes: IppAttributesGroup) = fromInt(attributes.getValue("printer-state")) } diff --git a/src/main/kotlin/de/gmuth/ipp/attributes/PrinterType.kt b/src/main/kotlin/de/gmuth/ipp/attributes/PrinterType.kt index a7ac2380..64a2b8aa 100644 --- a/src/main/kotlin/de/gmuth/ipp/attributes/PrinterType.kt +++ b/src/main/kotlin/de/gmuth/ipp/attributes/PrinterType.kt @@ -11,13 +11,10 @@ import de.gmuth.ipp.core.IppTag import java.util.logging.Level import java.util.logging.Level.INFO import java.util.logging.Logger -import java.util.logging.Logger.getLogger // https://www.cups.org/doc/spec-ipp.html class PrinterType(val value: Int) : IppAttributeBuilder { - val log = getLogger(javaClass.name) - enum class Capability(val bit: Int, val description: String) { IsAPrinterClass(0, "Is a printer class."), IsARemoteDestination(1, "Is a remote destination."), diff --git a/src/main/kotlin/de/gmuth/ipp/attributes/TemplateAttributes.kt b/src/main/kotlin/de/gmuth/ipp/attributes/TemplateAttributes.kt index eb1a16b4..485f72c9 100644 --- a/src/main/kotlin/de/gmuth/ipp/attributes/TemplateAttributes.kt +++ b/src/main/kotlin/de/gmuth/ipp/attributes/TemplateAttributes.kt @@ -52,9 +52,13 @@ object TemplateAttributes { fun mediaSource(keyword: String) = IppAttribute("media-source", Keyword, keyword) + @JvmStatic // input tray + fun mediaColWithSource(mediaSource: MediaSource) = + MediaCollection(source = mediaSource) + @JvmStatic // input tray fun mediaColWithSource(keyword: String) = - MediaCollection(source = MediaSource(keyword)) + mediaColWithSource(MediaSource(keyword)) @JvmStatic // unit: hundreds of mm fun mediaColWithSize(xDimension: Int, yDimension: Int) = diff --git a/src/main/kotlin/de/gmuth/ipp/client/CupsClient.kt b/src/main/kotlin/de/gmuth/ipp/client/CupsClient.kt index 20ce87b1..862ca218 100644 --- a/src/main/kotlin/de/gmuth/ipp/client/CupsClient.kt +++ b/src/main/kotlin/de/gmuth/ipp/client/CupsClient.kt @@ -25,7 +25,7 @@ class CupsClient( ) { constructor(host: String = "localhost") : this(URI.create("ipp://$host")) - private val log = getLogger(javaClass.name) + private val logger = getLogger(javaClass.name) val config: IppConfig by ippClient::config var userName: String? by config::userName var cupsClientWorkDirectory = File("CUPS/${cupsUri.host}") @@ -40,7 +40,7 @@ class CupsClient( private fun cupsPrinterUri(printerName: String) = cupsUri.run { URI("$scheme://$host${if (port > 0) ":$port" else ""}/printers/$printerName") } - .apply { log.finer { "cupsPrinterUri($printerName) = $this" } } + .apply { logger.finer { "cupsPrinterUri($printerName) = $this" } } val version: String by lazy { getPrinters().run { @@ -70,7 +70,7 @@ class CupsClient( .apply { workDirectory = cupsClientWorkDirectory } } catch (clientErrorNotFoundException: ClientErrorNotFoundException) { with(getPrinters()) { - if (isNotEmpty()) log.warning { "Available CUPS printers: ${map { it.name }}" } + if (isNotEmpty()) logger.warning { "Available CUPS printers: ${map { it.name }}" } } throw clientErrorNotFoundException } @@ -105,7 +105,7 @@ class CupsClient( fun deletePrinter(printerName: String) = exchange(cupsPrinterRequest(CupsDeletePrinter, printerName)) - .apply { log.info { "Printer deleted: $printerName" } } + .apply { logger.info { "Printer deleted: $printerName" } } // https://www.cups.org/doc/spec-ipp.html#CUPS_CREATE_LOCAL_PRINTER fun createLocalPrinter( @@ -126,7 +126,7 @@ class CupsClient( ppdName ) ).run { - log.info { "$statusMessage ${printerGroup.getValues("printer-uri-supported")}" } + logger.info { "$statusMessage ${printerGroup.getValues("printer-uri-supported")}" } return IppPrinter(printerGroup, ippClient) } } @@ -219,18 +219,18 @@ class CupsClient( ppdName = "everywhere" ).apply { updateAttributes("printer-name") - log.info(toString()) - log.info { "CUPS now generates IPP Everywhere PPD." } // https://github.com/apple/cups/issues/5919 + logger.info(toString()) + logger.info { "CUPS now generates IPP Everywhere PPD." } // https://github.com/apple/cups/issues/5919 do { updateAttributes("printer-make-and-model") Thread.sleep(500) } while (!makeAndModel.text.lowercase().contains("everywhere")) - log.info { "Make printer permanent." } + logger.info { "Make printer permanent." } exchange( cupsPrinterRequest(CupsAddModifyPrinter, printerName) .apply { printerGroup.attribute("printer-is-temporary", IppTag.Boolean, false) } ) - log.info { "Make printer operational." } + logger.info { "Make printer operational." } enable() resume() updateAttributes() @@ -263,7 +263,7 @@ class CupsClient( ) .onEach { job -> // update attributes and lookup job owners if (updateJobAttributes) job.updateAttributes() - log.info { job.toString() } + logger.info { job.toString() } job.getOriginatingUserNameOrAppleJobOwnerOrNull()?.let { jobOwners.add(it) } } .onEach { job -> // keep stats and save documents @@ -272,9 +272,9 @@ class CupsClient( .apply { numberOfSavedDocuments.addAndGet(size) } } .apply { - log.info { "Found ${jobOwners.size} job ${if (jobOwners.size == 1) "owner" else "owners"}: $jobOwners" } - log.info { "Found $size jobs (which=$whichJobs) where $numberOfJobsWithoutDocuments jobs have no documents" } - log.info { "Saved $numberOfSavedDocuments documents of ${size.minus(numberOfJobsWithoutDocuments.toInt())} jobs with documents to directory: ${cupsServer.workDirectory}" } + logger.info { "Found ${jobOwners.size} job ${if (jobOwners.size == 1) "owner" else "owners"}: $jobOwners" } + logger.info { "Found $size jobs (which=$whichJobs) where $numberOfJobsWithoutDocuments jobs have no documents" } + logger.info { "Saved $numberOfSavedDocuments documents of ${size.minus(numberOfJobsWithoutDocuments.toInt())} jobs with documents to directory: ${cupsServer.workDirectory}" } } } @@ -292,10 +292,10 @@ class CupsClient( ) { createSubscription(whichJobEvents, notifyLeaseDuration = leaseDuration) .pollAndHandleNotifications(pollEvery, autoRenewSubscription = autoRenewLease) { event -> - log.info { event.toString() } + logger.info { event.toString() } with(event.getJob()) { while (isIncoming()) { - log.info { toString() } + logger.info { toString() } Thread.sleep(1000) updateAttributes() } @@ -319,7 +319,7 @@ class CupsClient( if (documents.isNotEmpty() && onSuccessUpdateJobAttributes) job.updateAttributes() true } catch (ippExchangeException: IppExchangeException) { - log.info { "Get documents for job #${job.id} failed: ${ippExchangeException.message}" } + logger.info { "Get documents for job #${job.id} failed: ${ippExchangeException.message}" } ippExchangeException.httpStatus!! != 401 } @@ -327,7 +327,7 @@ class CupsClient( val configuredUserName = config.userName jobOwners.forEach { config.userName = it - log.fine { "set userName '${config.userName}'" } + logger.fine { "set userName '${config.userName}'" } if (getDocuments()) return@forEach } config.userName = configuredUserName diff --git a/src/main/kotlin/de/gmuth/ipp/client/IppClient.kt b/src/main/kotlin/de/gmuth/ipp/client/IppClient.kt index c75da00c..7db3b36c 100644 --- a/src/main/kotlin/de/gmuth/ipp/client/IppClient.kt +++ b/src/main/kotlin/de/gmuth/ipp/client/IppClient.kt @@ -27,7 +27,7 @@ import javax.net.ssl.HttpsURLConnection typealias IppResponseInterceptor = (request: IppRequest, response: IppResponse) -> Unit open class IppClient(val config: IppConfig = IppConfig()) : IppExchange { - protected val log: Logger = getLogger(javaClass.name) + protected val logger: Logger = getLogger(javaClass.name) var responseInterceptor: IppResponseInterceptor? = null var saveMessages: Boolean = false @@ -72,9 +72,9 @@ open class IppClient(val config: IppConfig = IppConfig()) : IppExchange { override fun exchange(request: IppRequest): IppResponse { val ippUri: URI = request.printerOrJobUri - log.finer { "send '${request.operation}' request to $ippUri" } + logger.finer { "Send '${request.operation}' request to $ippUri" } val response = httpPost(toHttpUri(ippUri), request) - log.fine { "$ippUri: $request => $response" } + logger.fine { "$ippUri: $request => $response" } if (saveMessages) { fun file(suffix: String) = File(saveMessagesDirectory, "${request.requestId}-${request.operation}.$suffix") request.saveBytes(file("request")) @@ -109,27 +109,25 @@ open class IppClient(val config: IppConfig = IppConfig()) : IppExchange { } } - protected fun validateResponse(request: IppRequest, response: IppResponse) { - with(response) { - if (status == ClientErrorBadRequest) request.log(log, SEVERE, prefix = "BAD-REQUEST: ") - if (containsGroup(Unsupported)) unsupportedGroup.values.forEach { log.warning() { "unsupported: $it" } } - if (!isSuccessful()) { - IppRegistrationsSection2.validate(request) - if (throwWhenNotSuccessful) { - throw if (status == ClientErrorNotFound) ClientErrorNotFoundException(request, response) - else IppExchangeException(request, response) - } + private fun validateResponse(request: IppRequest, response: IppResponse) = response.run { + if (status == ClientErrorBadRequest) request.log(logger, SEVERE, prefix = "BAD-REQUEST: ") + if (containsGroup(Unsupported)) unsupportedGroup.values.forEach { logger.warning() { "Unsupported: $it" } } + if (!isSuccessful()) { + IppRegistrationsSection2.validate(request) + if (throwWhenNotSuccessful) { + throw if (status == ClientErrorNotFound) ClientErrorNotFoundException(request, response) + else IppExchangeException(request, response) } } } - protected fun toHttpUri(ippUri: URI): URI = with(ippUri) { + private fun toHttpUri(ippUri: URI): URI = with(ippUri) { val scheme = scheme.replace("ipp", "http") val port = if (port == -1) 631 else port URI.create("$scheme://$host:$port$rawPath") } - protected fun HttpURLConnection.configure(chunked: Boolean) { + private fun HttpURLConnection.configure(chunked: Boolean) { config.run { connectTimeout = timeout.toMillis().toInt() readTimeout = timeout.toMillis().toInt() @@ -143,58 +141,42 @@ open class IppClient(val config: IppConfig = IppConfig()) : IppExchange { setRequestProperty("Accept-Encoding", "identity") // avoid 'gzip' with Androids OkHttp } - protected fun HttpURLConnection.validateResponse( + private fun HttpURLConnection.validateResponse( request: IppRequest, contentStream: InputStream?, cause: Exception? = null - ) = - when { - responseCode == 401 -> with(request) { - "User \"$requestingUserName\" is not authorized for operation $operation on $printerOrJobUri" - } - - responseCode == 426 -> { - "HTTP status $responseCode, $responseMessage, Try ipps://${request.printerOrJobUri.host}" - } - - responseCode != 200 -> { - "HTTP request failed: $responseCode, $responseMessage" - } - - contentType != null && !contentType.startsWith(APPLICATION_IPP) -> { - "Invalid Content-Type: $contentType" - } - - cause != null -> cause.message - - else -> null - }?.let { - throw IppExchangeException( - request, - response = null, - responseCode, // HTTP - httpHeaderFields = headerFields, - httpStream = contentStream, - message = it, - cause = cause - ) - } + ) = when { + responseCode == 401 -> with(request) { "User \"$requestingUserName\" is not authorized for operation $operation on $printerOrJobUri" } + responseCode == 426 -> "HTTP status $responseCode, $responseMessage, Try ipps://${request.printerOrJobUri.host}" + responseCode != 200 -> "HTTP request failed: $responseCode, $responseMessage" + contentType != null && !contentType.startsWith(APPLICATION_IPP) -> "Invalid Content-Type: $contentType" + cause != null -> cause.message + else -> null + }?.let { + throw IppExchangeException( + request, + response = null, + responseCode, // HTTP + httpHeaderFields = headerFields, + httpStream = contentStream, + message = it, + cause = cause + ) + } - protected fun decodeContentStream( + private fun decodeContentStream( request: IppRequest, httpStatus: Int, contentStream: InputStream ) = IppResponse().apply { - try { - read(contentStream) - } catch (throwable: Throwable) { + try { read(contentStream) } + catch (throwable: Throwable) { throw IppExchangeException( - request, this, httpStatus, message = "failed to decode ipp response", cause = throwable + request, this, httpStatus, message = "Failed to decode ipp response", cause = throwable ).apply { if (onExceptionSaveMessages) saveMessages("decoding_ipp_response_${request.requestId}_failed") } } } - } \ No newline at end of file diff --git a/src/main/kotlin/de/gmuth/ipp/client/IppDocument.kt b/src/main/kotlin/de/gmuth/ipp/client/IppDocument.kt index 139065ca..d656becd 100644 --- a/src/main/kotlin/de/gmuth/ipp/client/IppDocument.kt +++ b/src/main/kotlin/de/gmuth/ipp/client/IppDocument.kt @@ -21,7 +21,7 @@ class IppDocument( private val inputStream: InputStream ) { - private val log = getLogger(javaClass.name) + private val logger = getLogger(javaClass.name) val number: Int get() = attributes.getValue("document-number") @@ -35,9 +35,9 @@ class IppDocument( var file: File? = null fun readBytes() = inputStream.readBytes() - .also { log.fine { "Read ${it.size} bytes of $this" } } + .also { logger.fine { "Read ${it.size} bytes of $this" } } - fun filenameSuffix() = when (format) { + internal fun filenameSuffix() = when (format) { "application/pdf", "application/vnd.cups-pdf" -> "pdf" "application/octet-stream" -> "bin" "application/postscript" -> "ps" @@ -75,7 +75,7 @@ class IppDocument( if (file.isFile && !overwrite) throw IOException("File '$file' already exists") copyTo(file.outputStream()) this.file = file - log.info { "Saved $this" } + logger.info { "Saved $file" } } fun runCommand(commandToHandleFile: String) = diff --git a/src/main/kotlin/de/gmuth/ipp/client/IppExchangeException.kt b/src/main/kotlin/de/gmuth/ipp/client/IppExchangeException.kt index e5aabaa1..c1cdabe0 100644 --- a/src/main/kotlin/de/gmuth/ipp/client/IppExchangeException.kt +++ b/src/main/kotlin/de/gmuth/ipp/client/IppExchangeException.kt @@ -32,11 +32,11 @@ open class IppExchangeException( IppExchangeException(request, response) { init { require(response.status == ClientErrorNotFound) - { "ipp response status is not ClientErrorNotFound: ${response.status}" } + { "IPP response status is not ClientErrorNotFound: ${response.status}" } } } - val log = getLogger(javaClass.name) + private val logger = getLogger(javaClass.name) companion object { fun defaultMessage(request: IppRequest, response: IppResponse?) = StringBuilder().run { @@ -53,11 +53,11 @@ open class IppExchangeException( fun log(logger: Logger, level: Level = INFO) = logger.run { log(level) { message } - request.log(log, level, prefix = "REQUEST: ") - response?.log(log, level, prefix = "RESPONSE: ") + request.log(this@IppExchangeException.logger, level, prefix = "REQUEST: ") + response?.log(this@IppExchangeException.logger, level, prefix = "RESPONSE: ") httpStatus?.let { log(level) { "HTTP-Status: $it" } } httpHeaderFields?.let { for ((key: String?, value) in it) log(level) { "HTTP: $key = $value" } } - httpStream?.let { log.log(level) { "HTTP-Content:\n" + it.bufferedReader().use { it.readText() } } } + httpStream?.let { this@IppExchangeException.logger.log(level) { "HTTP-Content:\n" + it.bufferedReader().use { it.readText() } } } } fun saveMessages( diff --git a/src/main/kotlin/de/gmuth/ipp/client/IppInspector.kt b/src/main/kotlin/de/gmuth/ipp/client/IppInspector.kt index eff78037..4753c252 100644 --- a/src/main/kotlin/de/gmuth/ipp/client/IppInspector.kt +++ b/src/main/kotlin/de/gmuth/ipp/client/IppInspector.kt @@ -12,7 +12,7 @@ import java.net.URI import java.util.logging.Logger.getLogger object IppInspector { - private val log = getLogger(javaClass.name) + private val logger = getLogger(javaClass.name) var directory: String = "inspected-printers" const val pdfA4 = "blank_A4.pdf" @@ -28,14 +28,14 @@ object IppInspector { * - Hold-Job, Release-Job, Cancel-Job */ private fun IppPrinter.inspect(cancelJob: Boolean) { - log.info { "Inspect printer $printerUri" } + logger.info { "Inspect printer $printerUri" } val printerModel = with(StringBuilder()) { if (isCups()) append("CUPS-") append(makeAndModel.text.replace("\\s+".toRegex(), "_")) toString() } - log.info { "Printer model: $printerModel" } + logger.info { "Printer model: $printerModel" } ippClient.saveMessages = true ippClient.saveMessagesDirectory = File(directory, printerModel).createDirectoryIfNotExists() @@ -43,25 +43,25 @@ object IppInspector { attributes.run { // Media - if (containsKey("media-supported")) log.info { "Media supported: $mediaSupported" } - if (containsKey("media-ready")) log.info { "Media ready: $mediaReady" } - if (containsKey("media-default")) log.info { "Media default: $mediaDefault" } + if (containsKey("media-supported")) logger.info { "Media supported: $mediaSupported" } + if (containsKey("media-ready")) logger.info { "Media ready: $mediaReady" } + if (containsKey("media-default")) logger.info { "Media default: $mediaDefault" } // URIs - log.info { "Communication channels supported:" } - communicationChannelsSupported.forEach { log.info { " $it" } } - log.info { "Document formats: $documentFormatSupported" } + logger.info { "Communication channels supported:" } + communicationChannelsSupported.forEach { logger.info { " $it" } } + logger.info { "Document formats: $documentFormatSupported" } } val pdfResource = when { !attributes.containsKey("media-ready") -> { - log.warning { "media-ready not supported" } + logger.warning { "media-ready not supported" } pdfA4 } mediaReady.contains("iso-a4") || mediaReady.contains("iso_a4_210x297mm") -> pdfA4 mediaReady.contains("na_letter") || mediaReady.contains("na_letter_8.5x11in") -> "blank_USLetter.pdf" else -> { - log.warning { "No PDF available for media '$mediaReady', trying A4" } + logger.warning { "No PDF available for media '$mediaReady', trying A4" } pdfA4 } } @@ -72,21 +72,21 @@ object IppInspector { private fun IppPrinter.runInspectionWorkflow(pdfResource: String, cancelJob: Boolean) { - log.info { "> Get printer attributes" } + logger.info { "> Get printer attributes" } getPrinterAttributes() if (supportsOperations(CupsGetPPD)) { - log.info { "> CUPS Get PPD" } + logger.info { "> CUPS Get PPD" } savePPD(file = File(workDirectory, "0-${name.text}.ppd")) } if (supportsOperations(IdentifyPrinter)) { val action = with(identifyActionsSupported) { if (contains("sound")) "sound" else first() } - log.info { "> Identify by $action" } + logger.info { "> Identify by $action" } identify(action) } - log.info { "> Validate job" } + logger.info { "> Validate job" } val response = try { validateJob( jobName("Validation"), @@ -99,38 +99,38 @@ object IppInspector { } catch (ippExchangeException: IppExchangeException) { ippExchangeException.response } - log.info { response.toString() } + logger.info { response.toString() } - log.info { "> Print job $pdfResource" } + logger.info { "> Print job $pdfResource" } printJob( IppInspector::class.java.getResourceAsStream("/$pdfResource"), jobName(pdfResource), ).run { - log.info { toString() } + logger.info { toString() } - log.info { "> Get jobs" } + logger.info { "> Get jobs" } for (job in getJobs()) { - log.info { "$job" } + logger.info { "$job" } } if (supportsOperations(HoldJob, ReleaseJob)) { - log.info { "> Hold job" } + logger.info { "> Hold job" } hold() - log.info { "> Release job" } + logger.info { "> Release job" } release() } if (cancelJob) { - log.info { "> Cancel job" } + logger.info { "> Cancel job" } cancel() } - log.info { "> Update job attributes" } + logger.info { "> Update job attributes" } updateAttributes() ippClient.saveMessages = false - log.info { "> Wait for termination" } + logger.info { "> Wait for termination" } waitForTermination() } } diff --git a/src/main/kotlin/de/gmuth/ipp/client/IppJob.kt b/src/main/kotlin/de/gmuth/ipp/client/IppJob.kt index 31f70e0b..a2fbba4a 100644 --- a/src/main/kotlin/de/gmuth/ipp/client/IppJob.kt +++ b/src/main/kotlin/de/gmuth/ipp/client/IppJob.kt @@ -8,6 +8,7 @@ import de.gmuth.ipp.attributes.JobState import de.gmuth.ipp.attributes.JobState.* import de.gmuth.ipp.core.* import de.gmuth.ipp.core.IppOperation.* +import de.gmuth.ipp.core.IppStatus.SuccessfulOk import de.gmuth.ipp.core.IppTag.* import java.io.File import java.io.FileInputStream @@ -23,17 +24,21 @@ import java.util.logging.Logger.getLogger class IppJob( val printer: IppPrinter, val attributes: IppAttributesGroup, - subscriptionAttributes: IppAttributesGroup? = null ) : IppExchange by printer { + private val logger = getLogger(javaClass.name) + var subscription: IppSubscription? = null + + constructor(printer: IppPrinter, response: IppResponse) : this(printer, response.jobGroup) { + if (response.status != SuccessfulOk) logger.warning { "Job response status: ${response.status}" } + if (response.containsGroup(Subscription)) subscription = IppSubscription(printer, response.subscriptionGroup) + } + companion object { var defaultDelay: Duration = Duration.ofSeconds(1) var useJobOwnerAsUserName: Boolean = false } - private val log = getLogger(javaClass.name) - var subscription: IppSubscription? = subscriptionAttributes?.let { IppSubscription(printer, it) } - //-------------- // IppAttributes //-------------- @@ -147,16 +152,16 @@ class IppJob( @JvmOverloads fun waitForTermination(delay: Duration = defaultDelay) { - log.info { "Wait for termination of job #$id" } + logger.info { "Wait for termination of job #$id" } var lastPrinterString = "" var lastJobString = toString() - log.info { lastJobString } + logger.info { lastJobString } while (!isTerminated()) { - Thread.sleep(delay.toMillis()) + Thread.sleep(delay.toMillis()) // no coroutines (http, ssl and stream parsing also require JVM) updateAttributes() if (toString() != lastJobString) { lastJobString = toString() - log.info { lastJobString } + logger.info { lastJobString } } if (isProcessingStopped() || lastPrinterString.isNotEmpty()) { printer.updateAttributes( @@ -164,12 +169,12 @@ class IppJob( ) if (printer.toString() != lastPrinterString) { lastPrinterString = printer.toString() - log.info { lastPrinterString } + logger.info { lastPrinterString } } } if (isProcessing() && lastPrinterString.isNotEmpty()) lastPrinterString = "" } - if (isAborted()) log(log) + if (isAborted()) log(logger) } //------------------- @@ -182,12 +187,12 @@ class IppJob( @JvmOverloads fun cancel(messageForOperator: String? = null): IppResponse { // RFC 8011 4.3.3 - if (isCanceled()) log.warning { "Job #$id is already 'canceled'" } - if (isProcessingToStopPoint()) log.warning { "Job #$id is already 'processing-to-stop-point'" } + if (isCanceled()) logger.warning { "Job #$id is already 'canceled'" } + if (isProcessingToStopPoint()) logger.warning { "Job #$id is already 'processing-to-stop-point'" } val request = ippRequest(CancelJob).apply { messageForOperator?.let { operationGroup.attribute("message", TextWithoutLanguage, it) } } - log.info { "Cancel job #$id" } + logger.info { "Cancel $this" } return exchange(request) } @@ -202,9 +207,8 @@ class IppJob( documentName: String? = null, documentNaturalLanguage: String? = null ) { - val request = documentRequest(SendDocument, lastDocument, documentName, documentNaturalLanguage).apply { - documentInputStream = inputStream - } + val request = documentRequest(SendDocument, lastDocument, documentName, documentNaturalLanguage) + .apply { documentInputStream = inputStream } attributes.put(exchange(request).jobGroup) } @@ -227,9 +231,8 @@ class IppJob( documentName: String? = null, documentNaturalLanguage: String? = null ) { - val request = documentRequest(SendURI, lastDocument, documentName, documentNaturalLanguage).apply { - operationGroup.attribute("document-uri", Uri, documentUri) - } + val request = documentRequest(SendURI, lastDocument, documentName, documentNaturalLanguage) + .apply { operationGroup.attribute("document-uri", Uri, documentUri) } attributes.put(exchange(request).jobGroup) } @@ -274,7 +277,7 @@ class IppJob( return IppSubscription(printer, subscriptionAttributes).apply { subscription = this if (notifyEvents != null && !events.containsAll(notifyEvents)) { - log.warning { "Server ignored some notifyEvents $notifyEvents, subscribed events: $events" } + logger.warning { "Server ignored some notifyEvents $notifyEvents, subscribed events: $events" } } } } @@ -301,10 +304,9 @@ class IppJob( @JvmOverloads fun cupsGetDocument(documentNumber: Int = 1): IppDocument { - log.fine { "CupsGetDocument #$documentNumber for job #$id" } - val response = exchange(ippRequest(CupsGetDocument).apply { - operationGroup.attribute("document-number", Integer, documentNumber) - }) + logger.fine { "CupsGetDocument #$documentNumber for job #$id" } + val response = exchange(ippRequest(CupsGetDocument) + .apply { operationGroup.attribute("document-number", Integer, documentNumber) }) return IppDocument(this, response.jobGroup, response.documentInputStream!!) } @@ -327,7 +329,7 @@ class IppJob( //----------------------- fun printerDirectory() = - printer.printerDirectory(printerUri.toString().substringAfterLast("/")) + printer.printerDirectory(printerUri.toString().substringAfterLast(File.separator)) private fun ippRequest(operation: IppOperation, requestedAttributes: List? = null) = printer.ippRequest( diff --git a/src/main/kotlin/de/gmuth/ipp/client/IppPrinter.kt b/src/main/kotlin/de/gmuth/ipp/client/IppPrinter.kt index e870a81f..3cbf3730 100644 --- a/src/main/kotlin/de/gmuth/ipp/client/IppPrinter.kt +++ b/src/main/kotlin/de/gmuth/ipp/client/IppPrinter.kt @@ -11,7 +11,6 @@ import de.gmuth.ipp.attributes.PrinterState.* import de.gmuth.ipp.core.* import de.gmuth.ipp.core.IppOperation.* import de.gmuth.ipp.core.IppStatus.ClientErrorNotFound -import de.gmuth.ipp.core.IppStatus.SuccessfulOk import de.gmuth.ipp.core.IppTag.* import de.gmuth.ipp.iana.IppRegistrationsSection2 import java.io.* @@ -33,7 +32,7 @@ class IppPrinter( requestedAttributesOnInit: List? = null ) : IppExchange { - private val log = getLogger(javaClass.name) + private val logger = getLogger(javaClass.name) var workDirectory: File = createTempDirectory().toFile() companion object { @@ -60,27 +59,27 @@ class IppPrinter( } init { - log.fine { "create IppPrinter for $printerUri" } + logger.fine { "create IppPrinter for $printerUri" } require(printerUri.scheme.startsWith("ipp")) { "uri scheme unsupported: ${printerUri.scheme}" } if (printerUri.scheme == "ipps") ippConfig.trustAnyCertificateAndSSLHostname() if (!getPrinterAttributesOnInit) { - log.fine { "getPrinterAttributesOnInit disabled => no printer attributes available" } + logger.fine { "getPrinterAttributesOnInit disabled => no printer attributes available" } } else if (attributes.isEmpty()) { try { updateAttributes(requestedAttributesOnInit) if (isStopped()) { - log.fine { toString() } - alert?.let { log.info { "alert: $it" } } - alertDescription?.let { log.info { "alert-description: $it" } } + logger.fine { toString() } + alert?.let { logger.info { "alert: $it" } } + alertDescription?.let { logger.info { "alert-description: $it" } } } } catch (ippExchangeException: IppExchangeException) { if (ippExchangeException.statusIs(ClientErrorNotFound)) - log.severe { ippExchangeException.message } + logger.severe { ippExchangeException.message } else { - log.severe { "Failed to get printer attributes on init. Workaround: getPrinterAttributesOnInit=false" } + logger.severe { "Failed to get printer attributes on init. Workaround: getPrinterAttributesOnInit=false" } ippExchangeException.response?.let { - if (it.containsGroup(Printer)) log.info { "${it.printerGroup.size} attributes parsed" } - else log.warning { "RESPONSE: $it" } + if (it.containsGroup(Printer)) logger.info { "${it.printerGroup.size} attributes parsed" } + else logger.warning { "RESPONSE: $it" } } } throw ippExchangeException @@ -260,7 +259,7 @@ class IppPrinter( ) = file.also { cupsGetPPD(it.outputStream()) - log.info { "Saved PPD: $it" } + logger.info { "Saved PPD: $it" } } //------------------------------------------ @@ -364,7 +363,7 @@ class IppPrinter( // put attribute in operation or job group? val groupTag = IppRegistrationsSection2.selectGroupForAttribute(attribute.name) ?: Job if (!containsGroup(groupTag)) createAttributesGroup(groupTag) - log.finer { "$groupTag put $attribute" } + logger.finer { "$groupTag put $attribute" } getSingleAttributesGroup(groupTag).put(attribute) } } @@ -389,7 +388,7 @@ class IppPrinter( limit: Int? = null, requestedAttributes: List? = getJobsRequestedAttributes ): Collection { - log.fine { "getJobs(whichJobs=$whichJobs, requestedAttributes=$requestedAttributes)" } + logger.fine { "getJobs(whichJobs=$whichJobs, requestedAttributes=$requestedAttributes)" } val request = ippRequest(GetJobs, requestedAttributes = requestedAttributes).apply { operationGroup.run { whichJobs?.keyword?.let { @@ -408,6 +407,13 @@ class IppPrinter( fun getJobs(whichJobs: WhichJobs? = null, vararg requestedAttributes: String) = getJobs(whichJobs, requestedAttributes = requestedAttributes.toList()) + //------------ + // Cancel jobs + //------------ + + fun cancelJobs(whichJobs: WhichJobs) = + getJobs(whichJobs).forEach { it.cancel() } + //---------------------------- // Create-Printer-Subscription //---------------------------- @@ -484,19 +490,14 @@ class IppPrinter( checkIfValueIsSupported("charset-supported", attributesCharset) }) - private fun exchangeForIppJob(request: IppRequest): IppJob { - val response = exchange(request) - if (response.status != SuccessfulOk) log.warning { "Job response status: ${response.status}" } - if (request.containsGroup(Subscription) && !response.containsGroup(Subscription)) { - request.log(log, WARNING, prefix = "REQUEST: ") - val events: List = request.subscriptionGroup.getValues("notify-events") - throw IppException("printer/server did not create subscription for events: ${events.joinToString(",")}") - } - val subscriptionsAttributes = response.run { - if (containsGroup(Subscription)) subscriptionGroup else null + private fun exchangeForIppJob(request: IppRequest) = + IppJob(this, exchange(request)).apply { + if (request.containsGroup(Subscription) && subscription == null) { + request.log(logger, WARNING, prefix = "REQUEST: ") + val events: List = request.subscriptionGroup.getValues("notify-events") + throw IppException("printer/server did not create subscription for events: ${events.joinToString(",")}") + } } - return IppJob(this, response.jobGroup, subscriptionsAttributes) - } private fun checkIfValueIsSupported(supportedAttributeName: String, value: Any) = IppValueSupport.checkIfValueIsSupported(attributes, supportedAttributeName, value) diff --git a/src/main/kotlin/de/gmuth/ipp/client/IppSubscription.kt b/src/main/kotlin/de/gmuth/ipp/client/IppSubscription.kt index 6e6c728e..f62c978e 100644 --- a/src/main/kotlin/de/gmuth/ipp/client/IppSubscription.kt +++ b/src/main/kotlin/de/gmuth/ipp/client/IppSubscription.kt @@ -24,16 +24,12 @@ class IppSubscription( val attributes: IppAttributesGroup ) : IppExchange by printer { - private val log = getLogger(javaClass.name) - + private val logger = getLogger(javaClass.name) private var lastSequenceNumber: Int = 0 private var leaseStartedAt = now() init { - if (attributes.size <= 1) { - updateAttributes() - log.info { toString() } - } + if (attributes.size <= 1) updateAttributes() } val id: Int @@ -61,11 +57,12 @@ class IppSubscription( // RFC 3995 11.2.4.1.2: 'subscription-template', 'subscription-description' or 'all' (default) @JvmOverloads - fun getSubscriptionAttributes(requestedAttributes: List? = null) = - exchange(ippRequest(GetSubscriptionAttributes, requestedAttributes = requestedAttributes)).subscriptionGroup + fun getSubscriptionAttributes(requestedAttributes: List? = null) = exchange( + subscriptionRequest(GetSubscriptionAttributes, requestedAttributes = requestedAttributes) + ) fun updateAttributes() { - attributes.put(getSubscriptionAttributes()) + attributes.put(getSubscriptionAttributes().subscriptionGroup) } //------------------ @@ -73,7 +70,7 @@ class IppSubscription( //------------------ fun getNotifications(notifySequenceNumber: Int? = lastSequenceNumber + 1): List { - val request = ippRequest(GetNotifications).apply { + val request = subscriptionRequest(GetNotifications).apply { operationGroup.run { attribute("notify-subscription-ids", Integer, id) notifySequenceNumber?.let { attribute("notify-sequence-numbers", Integer, it) } @@ -89,27 +86,27 @@ class IppSubscription( // Cancel-Subscription //-------------------- - fun cancel() = - exchange(ippRequest(CancelSubscription)) + fun cancel() = exchange(subscriptionRequest(CancelSubscription)) //------------------- // Renew-Subscription //------------------- - fun renew(leaseDuration: Duration? = null) = - exchange(ippRequest(RenewSubscription).apply { + fun renew(leaseDuration: Duration? = null) = exchange( + subscriptionRequest(RenewSubscription).apply { createSubscriptionAttributesGroup(notifyLeaseDuration = leaseDuration) - }).also { - leaseStartedAt = now() - updateAttributes() - log.info { "renewed $this" } } + ).also { + leaseStartedAt = now() + updateAttributes() + logger.fine { "renewed $this" } + } //----------------------- // Delegate to IppPrinter //----------------------- - protected fun ippRequest(operation: IppOperation, requestedAttributes: List? = null) = + private fun subscriptionRequest(operation: IppOperation, requestedAttributes: List? = null) = printer.ippRequest(operation, requestedAttributes = requestedAttributes) .apply { operationGroup.attribute("notify-subscription-id", Integer, id) } @@ -127,19 +124,19 @@ class IppSubscription( fun pollAndHandleNotifications( pollEvery: Duration = ofSeconds(5), // should be larger than 1s autoRenewSubscription: Boolean = false, - handleNotification: (event: IppEventNotification) -> Unit = { log.info { it.toString() } } + handleNotification: (event: IppEventNotification) -> Unit = { logger.info { it.toString() } } ) { fun expiresAfterDelay() = !leaseDuration.isZero && now().plus(pollEvery).isAfter(expiresAt.minusSeconds(2)) try { pollHandlesNotifications = true while (pollHandlesNotifications) { - if (expired()) log.warning { "subscription #$id has expired" } + if (expired()) logger.warning { "subscription #$id has expired" } getNotifications().forEach { handleNotification(it) } if (expiresAfterDelay() && autoRenewSubscription) renew(leaseDuration) Thread.sleep(pollEvery.toMillis()) } } catch (clientErrorNotFoundException: ClientErrorNotFoundException) { - log.info { clientErrorNotFoundException.response!!.statusMessage.toString() } + logger.info { clientErrorNotFoundException.response!!.statusMessage.toString() } } } diff --git a/src/main/kotlin/de/gmuth/ipp/client/IppValueSupport.kt b/src/main/kotlin/de/gmuth/ipp/client/IppValueSupport.kt index 9d60e890..8563aa01 100644 --- a/src/main/kotlin/de/gmuth/ipp/client/IppValueSupport.kt +++ b/src/main/kotlin/de/gmuth/ipp/client/IppValueSupport.kt @@ -14,11 +14,12 @@ import java.util.logging.Logger.getLogger object IppValueSupport { - private val log = getLogger(javaClass.name) + private val logger = getLogger(javaClass.name) - fun checkIfValueIsSupported(printerAttributes: IppAttributesGroup, attribute: IppAttribute) { + fun checkIfValueIsSupported(printerAttributes: IppAttributesGroup, attribute: IppAttribute<*>) { val supportedAttribute = printerAttributes["${attribute.name}-supported"] - supportedAttribute?.let { checkIfValueIsSupported(printerAttributes, supportedAttribute.name, attribute.value) } + if (supportedAttribute == null) logger.warning { "${attribute.name}-supported not available in printer attributes" } + else checkIfValueIsSupported(printerAttributes, supportedAttribute.name, attribute.value as Any) } fun checkIfValueIsSupported( @@ -54,9 +55,10 @@ object IppValueSupport { IppTag.Enum, Charset, NaturalLanguage, MimeMediaType, Keyword, Resolution -> when (supportedAttributeName) { "media-col-supported" -> with(value as IppCollection) { - members.filter { !supportedAttribute.values.contains(it.name) } - .forEach { log.warning { "member unsupported: $it" } } - // all member names must be supported + members + .onEach { checkIfValueIsSupported(printerAttributes, it) } + .filter { !supportedAttribute.values.contains(it.name) } + .forEach { logger.warning { "media-col member unsupported: $it" } } supportedAttribute.values.containsAll(members.map { it.name }) } @@ -75,13 +77,14 @@ object IppValueSupport { else -> null } when (attributeValueIsSupported) { - null -> log.warning { "unable to check if value '$value' is supported by $supportedAttribute" } - true -> log.fine { "$supportedAttributeName: $value" } + null -> logger.warning { "Unable to check if value '$value' is supported by $supportedAttribute" } + true -> logger.finer { "$value is supported according to $supportedAttributeName" } false -> { - log.warning { "according to printer attributes value '${supportedAttribute.enumNameOrValue(value)}' is not supported." } - log.warning { "$supportedAttribute" } + logger.warning { "According to printer attributes value '${supportedAttribute.enumNameOrValue(value)}' is not supported." } + logger.warning { "$supportedAttribute" } } } return attributeValueIsSupported + .also { logger.finest { "is $supportedAttributeName(${supportedAttribute.tag})? $value -> $attributeValueIsSupported" } } } } \ No newline at end of file diff --git a/src/main/kotlin/de/gmuth/ipp/core/IppAttribute.kt b/src/main/kotlin/de/gmuth/ipp/core/IppAttribute.kt index b8c683d1..e2592363 100644 --- a/src/main/kotlin/de/gmuth/ipp/core/IppAttribute.kt +++ b/src/main/kotlin/de/gmuth/ipp/core/IppAttribute.kt @@ -15,7 +15,7 @@ import java.util.logging.Logger.getLogger data class IppAttribute(val name: String, val tag: IppTag) : IppAttributeBuilder { - private val log = getLogger(javaClass.name) + private val logger = getLogger(javaClass.name) val values: MutableCollection = mutableListOf() @@ -40,7 +40,7 @@ data class IppAttribute(val name: String, val tag: IppTag) : IppAttributeBuil when { attribute.name.isNotEmpty() -> throw IppException("For additional '$name' values attribute name must be empty") attribute.values.size != 1 -> throw IppException("Expected 1 additional value, not ${attribute.values.size}") - attribute.tag != tag -> log.warning { "$name: ignore additional value \"$attribute\" - tag is not '$tag'" } + attribute.tag != tag -> logger.warning { "$name: ignore additional value \"$attribute\" - tag is not '$tag'" } else -> { attribute.tag.validateValueClass(attribute.values.single() as Any) values.add(attribute.values.single() as T) @@ -85,5 +85,4 @@ data class IppAttribute(val name: String, val tag: IppTag) : IppAttributeBuil } } } - } \ No newline at end of file diff --git a/src/main/kotlin/de/gmuth/ipp/core/IppAttributesGroup.kt b/src/main/kotlin/de/gmuth/ipp/core/IppAttributesGroup.kt index e46e7112..1873282f 100644 --- a/src/main/kotlin/de/gmuth/ipp/core/IppAttributesGroup.kt +++ b/src/main/kotlin/de/gmuth/ipp/core/IppAttributesGroup.kt @@ -17,7 +17,7 @@ import java.util.logging.Logger.getLogger class IppAttributesGroup(val tag: IppTag) : LinkedHashMap>() { - private val log = getLogger(javaClass.name) + private val logger = getLogger(javaClass.name) var onReplaceWarn: Boolean = false init { @@ -26,7 +26,7 @@ class IppAttributesGroup(val tag: IppTag) : LinkedHashMap) = put(attribute.name, attribute).also { if (it != null && onReplaceWarn) { - log.warning { "replaced '$it' with '${attribute.values.joinToString(",")}' in group $tag" } + logger.warning { "replaced '$it' with '${attribute.values.joinToString(",")}' in group $tag" } } } @@ -83,7 +83,7 @@ class IppAttributesGroup(val tag: IppTag) : LinkedHashMap { val attribute = readAttribute(tag) - log.finest { attribute.toString() } + logger.finest { attribute.toString() } if (attribute.name.isNotEmpty()) { currentGroup.put(attribute) currentAttribute = attribute @@ -55,8 +55,8 @@ class IppInputStream(inputStream: BufferedInputStream) : DataInputStream(inputSt } catch (throwable: Throwable) { if (throwable !is EOFException) readBytes().apply { if (isNotEmpty()) { - log.warning { "Skipped $size unparsed bytes" } - hexdump { log.finest { it } } + logger.warning { "Skipped $size unparsed bytes" } + hexdump { logger.finest { it } } } } throw IppException("Failed to read ipp message", throwable) @@ -64,7 +64,7 @@ class IppInputStream(inputStream: BufferedInputStream) : DataInputStream(inputSt } internal fun readTag() = IppTag.fromByte(readByte()).apply { - if (isDelimiterTag()) log.finest { "--- $this ---" } + if (isDelimiterTag()) logger.finest { "--- $this ---" } } internal fun readAttribute(tag: IppTag) = IppAttribute(name = readString(), tag).apply { @@ -162,7 +162,7 @@ class IppInputStream(inputStream: BufferedInputStream) : DataInputStream(inputSt readCollection() } else { // Xerox B210: workaround for invalid 'media-col' without members - log.warning { "Invalid value length for IppCollection, trying to recover" } + logger.warning { "Invalid value length for IppCollection, trying to recover" } IppCollection() } } @@ -172,8 +172,8 @@ class IppInputStream(inputStream: BufferedInputStream) : DataInputStream(inputSt readLengthAndValue().apply { if (isNotEmpty()) { val level = if (tag == Unsupported_) Level.FINEST else Level.WARNING - log.log(level) { "Ignore $size value bytes tagged '$tag'" } - hexdump { log.log(level) { it } } + logger.log(level) { "Ignore $size value bytes tagged '$tag'" } + hexdump { logger.log(level) { it } } } } } @@ -217,7 +217,7 @@ class IppInputStream(inputStream: BufferedInputStream) : DataInputStream(inputSt if (!this) { // unexpected value length reset() // revert 'readShort()' with("Expected value length of $expected bytes but found $length") { - if (throwException) throw IppException(this) else log.warning { this } + if (throwException) throw IppException(this) else logger.warning { this } } } } diff --git a/src/main/kotlin/de/gmuth/ipp/core/IppMessage.kt b/src/main/kotlin/de/gmuth/ipp/core/IppMessage.kt index 1102159a..29a2ac85 100644 --- a/src/main/kotlin/de/gmuth/ipp/core/IppMessage.kt +++ b/src/main/kotlin/de/gmuth/ipp/core/IppMessage.kt @@ -13,7 +13,7 @@ import java.util.logging.Logger.getLogger abstract class IppMessage() { - private val log = getLogger(javaClass.name) + private val logger = getLogger(javaClass.name) var code: Int? = null // unsigned short (16 bits) var requestId: Int? = null var version: String? = null @@ -112,12 +112,12 @@ abstract class IppMessage() { } fun read(file: File) { - log.fine { "Read file ${file.absolutePath}: ${file.length()} bytes" } + logger.fine { "Read file ${file.absolutePath}: ${file.length()} bytes" } read(FileInputStream(file)) } fun decode(byteArray: ByteArray) { - log.fine { "Decode ${byteArray.size} bytes" } + logger.fine { "Decode ${byteArray.size} bytes" } read(ByteArrayInputStream(byteArray)) } @@ -126,16 +126,16 @@ abstract class IppMessage() { // ------------------------ protected fun copyDocumentStream(outputStream: OutputStream): Long { - if (documentInputStreamIsConsumed) log.warning { "documentInputStream is consumed" } + if (documentInputStreamIsConsumed) logger.warning { "documentInputStream is consumed" } return documentInputStream!!.copyTo(outputStream).apply { - log.fine { "consumed documentInputStream: $this bytes" } + logger.fine { "consumed documentInputStream: $this bytes" } documentInputStreamIsConsumed = true } } fun saveDocumentStream(file: File) { copyDocumentStream(file.outputStream()) - log.info { "saved ${file.length()} document bytes to file ${file.path}" } + logger.info { "saved ${file.length()} document bytes to file ${file.path}" } } fun saveBytes(file: File) = @@ -143,7 +143,7 @@ abstract class IppMessage() { throw IppException("No raw bytes to save. You must call read/decode or write/encode before.") } else { file.writeBytes(rawBytes!!) - log.info { "Saved ${file.path} (${file.length()} bytes)" } + logger.info { "Saved ${file.path} (${file.length()} bytes)" } } protected fun write(bufferedWriter: BufferedWriter, title: String) { @@ -161,7 +161,7 @@ abstract class IppMessage() { fun saveText(file: File) = file.apply { bufferedWriter().use { write(it, title = "# File: ${file.name}") } - log.info { "Saved $path (${length()} bytes)" } + logger.info { "Saved $path (${length()} bytes)" } } // ------- diff --git a/src/main/kotlin/de/gmuth/ipp/core/IppOutputStream.kt b/src/main/kotlin/de/gmuth/ipp/core/IppOutputStream.kt index 4094819a..b061729c 100644 --- a/src/main/kotlin/de/gmuth/ipp/core/IppOutputStream.kt +++ b/src/main/kotlin/de/gmuth/ipp/core/IppOutputStream.kt @@ -13,7 +13,7 @@ import java.util.logging.Logger.getLogger class IppOutputStream(outputStream: OutputStream) : DataOutputStream(outputStream) { - private val log = getLogger(javaClass.name) + private val logger = getLogger(javaClass.name) // Charset for text and name attributes, RFC 8011 4.1.4.1 internal lateinit var attributesCharset: Charset @@ -22,13 +22,13 @@ class IppOutputStream(outputStream: OutputStream) : DataOutputStream(outputStrea attributesCharset = operationGroup.getValue("attributes-charset") writeVersion(version ?: throw IppException("missing version")) - log.finest { "version = $version" } + logger.finest { "version = $version" } writeShort(code ?: throw IppException("missing operation or status code")) - log.finest { "code = $code ($codeDescription)" } + logger.finest { "code = $code ($codeDescription)" } writeInt(requestId ?: throw IppException("missing requestId")) - log.finest { "requestId = $requestId" } + logger.finest { "requestId = $requestId" } for (group in attributesGroups) { writeTag(group.tag) @@ -51,7 +51,7 @@ class IppOutputStream(outputStream: OutputStream) : DataOutputStream(outputStrea } internal fun writeTag(tag: IppTag) { - if (tag.isDelimiterTag()) log.finest { "--- $tag ---" } + if (tag.isDelimiterTag()) logger.finest { "--- $tag ---" } writeByte(tag.code.toInt()) } @@ -63,7 +63,7 @@ class IppOutputStream(outputStream: OutputStream) : DataOutputStream(outputStrea } internal fun writeAttribute(attribute: IppAttribute<*>) { - log.finest { "$attribute" } + logger.finest { "$attribute" } with(attribute) { if (values.isEmpty() || tag.isOutOfBandTag()) { writeTag(tag) diff --git a/src/main/kotlin/de/gmuth/ipp/core/IppRequest.kt b/src/main/kotlin/de/gmuth/ipp/core/IppRequest.kt index 729b7980..233b45ef 100644 --- a/src/main/kotlin/de/gmuth/ipp/core/IppRequest.kt +++ b/src/main/kotlin/de/gmuth/ipp/core/IppRequest.kt @@ -20,9 +20,8 @@ class IppRequest : IppMessage { when { containsKey("printer-uri") -> getUriValue("printer-uri") containsKey("job-uri") -> getUriValue("job-uri") - else -> throw IppException("Missing 'printer-uri' or 'job-uri' in IppRequest").also { - log(logger, Level.WARNING) - } + else -> throw IppException("Missing 'printer-uri' or 'job-uri' in IppRequest") + .also { log(logger, Level.WARNING) } } } diff --git a/src/main/kotlin/de/gmuth/ipp/core/IppResponse.kt b/src/main/kotlin/de/gmuth/ipp/core/IppResponse.kt index 43b857fa..f7dc41c3 100644 --- a/src/main/kotlin/de/gmuth/ipp/core/IppResponse.kt +++ b/src/main/kotlin/de/gmuth/ipp/core/IppResponse.kt @@ -4,7 +4,7 @@ package de.gmuth.ipp.core * Copyright (c) 2020-2023 Gerhard Muth */ -import de.gmuth.ipp.core.IppTag.* +import de.gmuth.ipp.core.IppTag.Unsupported import java.nio.charset.Charset class IppResponse : IppMessage { @@ -22,9 +22,6 @@ class IppResponse : IppMessage { val statusMessage: IppString get() = operationGroup.getValue("status-message") - val jobGroups: Collection - get() = getAttributesGroups(Job) - val unsupportedGroup: IppAttributesGroup get() = getSingleAttributesGroup(Unsupported) @@ -41,5 +38,4 @@ class IppResponse : IppMessage { ) : super(version, requestId, charset, naturalLanguage) { code = status.code } - } \ No newline at end of file diff --git a/src/main/kotlin/de/gmuth/ipp/core/IppTag.kt b/src/main/kotlin/de/gmuth/ipp/core/IppTag.kt index 4f6d7ecc..e640f6e0 100644 --- a/src/main/kotlin/de/gmuth/ipp/core/IppTag.kt +++ b/src/main/kotlin/de/gmuth/ipp/core/IppTag.kt @@ -70,7 +70,7 @@ enum class IppTag( override fun toString() = registeredName fun registeredSyntax() = when (this) { - // iana registered syntax doesn't care about language + // IANA registered syntax doesn't care about language NameWithoutLanguage, NameWithLanguage -> "name" TextWithoutLanguage, TextWithLanguage -> "text" else -> registeredName @@ -87,5 +87,4 @@ enum class IppTag( fun fromString(name: String): IppTag = values().singleOrNull { it.registeredName == name } ?: throw IppException("Unknown tag name '$name'") } - } \ No newline at end of file diff --git a/src/main/kotlin/de/gmuth/ipp/iana/IppRegistrationsSection2.kt b/src/main/kotlin/de/gmuth/ipp/iana/IppRegistrationsSection2.kt index 2a6b76b4..05623b74 100644 --- a/src/main/kotlin/de/gmuth/ipp/iana/IppRegistrationsSection2.kt +++ b/src/main/kotlin/de/gmuth/ipp/iana/IppRegistrationsSection2.kt @@ -14,7 +14,7 @@ import java.util.logging.Logger.getLogger // https://www.iana.org/assignments/ipp-registrations/ipp-registrations.xml#ipp-registrations-2 object IppRegistrationsSection2 { - val log = getLogger(javaClass.name) + private val logger = getLogger(javaClass.name) data class Attribute( val collection: String, @@ -103,7 +103,7 @@ object IppRegistrationsSection2 { } fun resolveAlias(name: String) = (aliasMap[name] ?: name).also { - if (aliasMap.containsKey(name)) log.finer { "'$name' resolves to '$it'" } + if (aliasMap.containsKey(name)) logger.finer { "'$name' resolves to '$it'" } } fun getAttribute(name: String, resolveAlias: Boolean = true) = @@ -126,10 +126,10 @@ object IppRegistrationsSection2 { if (tag.isOutOfBandTag()) return val syntax = syntaxForAttribute(name, true) if (syntax == null) { - log.fine { "no syntax found for '$name'" } + logger.fine { "no syntax found for '$name'" } unknownAttributes.add(name) } else if (!syntax.contains(tag.registeredSyntax())) { - log.warning { "$name ($tag) does not match iana registered syntax '$syntax'" } + logger.warning { "$name ($tag) does not match iana registered syntax '$syntax'" } } } @@ -145,16 +145,16 @@ object IppRegistrationsSection2 { fun validate(ippAttribute: IppAttribute<*>) = with(ippAttribute) { checkSyntaxOfAttribute(name, tag) if (isCollection()) validate(name, values as List) - if (!tag.isOutOfBandTag() && values.isEmpty()) log.warning { "'$name' ($tag) has no values" } - if (values.size > 1 && attributeIs1setOf(name) == false) log.warning { "'$name' is not registered as '1setOf'" } + if (!tag.isOutOfBandTag() && values.isEmpty()) logger.warning { "'$name' ($tag) has no values" } + if (values.size > 1 && attributeIs1setOf(name) == false) logger.warning { "'$name' is not registered as '1setOf'" } } @Suppress("UNCHECKED_CAST") fun validate(name: String, ippCollections: List) { - log.finer { "validate collection '$name'" } + logger.finer { "validate collection '$name'" } val resolvedName = resolveAlias(name) for (ippCollection in ippCollections) { - log.finer { " ${ippCollection.members.size} members" } + logger.finer { " ${ippCollection.members.size} members" } for (member in ippCollection.members) { if (member.isCollection()) { validate("$resolvedName/${member.name}", member.values as List) @@ -168,8 +168,8 @@ object IppRegistrationsSection2 { fun logUnknownAttributes() { with(unknownAttributes.toMutableList()) { sort() - log.info { "$size unknown attributes:" } - forEach { log.info { "- $it" } } + logger.info { "$size unknown attributes:" } + forEach { logger.info { "- $it" } } } } } \ No newline at end of file diff --git a/src/test/kotlin/de/gmuth/ipp/client/CupsClientTests.kt b/src/test/kotlin/de/gmuth/ipp/client/CupsClientTests.kt index 4b1a8dc2..7f27be39 100644 --- a/src/test/kotlin/de/gmuth/ipp/client/CupsClientTests.kt +++ b/src/test/kotlin/de/gmuth/ipp/client/CupsClientTests.kt @@ -15,7 +15,7 @@ import kotlin.test.assertFailsWith import kotlin.test.assertTrue class CupsClientTests { - val log = getLogger(javaClass.name) + private val logger = getLogger(javaClass.name) val ippClientMock = IppClientMock("printers/CUPS") val cupsClient = CupsClient(URI.create("ipps://cups"), ippClient = ippClientMock) @@ -29,7 +29,7 @@ class CupsClientTests { fun getPrinters() { ippClientMock.mockResponse("Cups-Get-Printers.ipp") cupsClient.getPrinters().run { - forEach { log.info { it.toString() } } + forEach { logger.info { it.toString() } } assertEquals(12, size) } } @@ -38,7 +38,7 @@ class CupsClientTests { fun getPrinter() { ippClientMock.mockResponse("Get-Printer-Attributes.ipp", "printers/CUPS_HP_LaserJet_100_color_MFP_M175") cupsClient.getPrinter("ColorJet_HP").run { - log(log) + log(logger) assertEquals("HP LaserJet 100 color MFP M175", makeAndModel.text) assertEquals(PrinterState.Idle, state) assertEquals(5, markers.size) diff --git a/src/test/kotlin/de/gmuth/ipp/client/IppClientMock.kt b/src/test/kotlin/de/gmuth/ipp/client/IppClientMock.kt index 7bce2f73..2531da7c 100644 --- a/src/test/kotlin/de/gmuth/ipp/client/IppClientMock.kt +++ b/src/test/kotlin/de/gmuth/ipp/client/IppClientMock.kt @@ -36,13 +36,13 @@ class IppClientMock(var directory: String = "printers") : IppClient() { // when used with real http, responses are frequently created and garbage collected // however references to attribute groups are kept in IPP objects // changes to an attribute group would affect other tests as well - // therefor it's important to produce a fresh response for each call + // therefor it's important to produce a fresh response for each mocked call override fun httpPost(httpUri: URI, request: IppRequest) = IppResponse().apply { ByteArrayOutputStream() .also { request.write(it) } .toByteArray() - .run { log.info { "post $size request bytes to $httpUri, ${rawResponse.size} response bytes" } } + .run { logger.info { "post $size request bytes to $httpUri, ${rawResponse.size} response bytes" } } decode(rawResponse) } } \ No newline at end of file diff --git a/src/test/kotlin/de/gmuth/ipp/client/IppExchangeExceptionTests.kt b/src/test/kotlin/de/gmuth/ipp/client/IppExchangeExceptionTests.kt index 96b9677c..1a78fd9e 100644 --- a/src/test/kotlin/de/gmuth/ipp/client/IppExchangeExceptionTests.kt +++ b/src/test/kotlin/de/gmuth/ipp/client/IppExchangeExceptionTests.kt @@ -12,7 +12,7 @@ import kotlin.test.assertEquals class IppExchangeExceptionTests { - val log = getLogger(javaClass.name) + private val logger = getLogger(javaClass.name) @Test fun constructor() { @@ -22,7 +22,7 @@ class IppExchangeExceptionTests { null, 400 ) ) { - log(log) + log(logger) assertEquals(11, request.code) assertEquals(400, httpStatus) assertEquals(message, "Get-Printer-Attributes failed") diff --git a/src/test/kotlin/de/gmuth/ipp/client/IppJobTests.kt b/src/test/kotlin/de/gmuth/ipp/client/IppJobTests.kt index 22c55168..e14aad68 100644 --- a/src/test/kotlin/de/gmuth/ipp/client/IppJobTests.kt +++ b/src/test/kotlin/de/gmuth/ipp/client/IppJobTests.kt @@ -22,7 +22,7 @@ import kotlin.test.assertTrue class IppJobTests { - val log = getLogger(javaClass.name) + private val logger = getLogger(javaClass.name) val blankPdf = File("tool/A4-blank.pdf") val ippClientMock = IppClientMock("printers/CUPS_HP_LaserJet_100_color_MFP_M175") @@ -42,8 +42,8 @@ class IppJobTests { @Test fun jobAttributes() { job.apply { - log.info { toString() } - log(log) + logger.info { toString() } + log(logger) assertEquals("ipp://localhost:631/jobs/2366", uri.toString()) assertEquals(0, mediaSheetsCompleted) assertEquals(2, kOctets) @@ -66,7 +66,7 @@ class IppJobTests { job.apply { attributes.onReplaceWarn = true updateAttributes() - log(log) + log(logger) assertEquals(32, attributes.size) } } @@ -172,8 +172,8 @@ class IppJobTests { fun cupsGetDocument1() { ippClientMock.mockResponse(cupsDocumentResponse("application/pdf")) job.cupsGetDocument().apply { - log.info { toString() } - log(log) + logger.info { toString() } + log(logger) save().delete() assertEquals("job-2366-gmuth-A4-blank.pdf", filename()) } @@ -194,10 +194,10 @@ class IppJobTests { jobGroup.remove("document-name") }) job.cupsGetDocument(2).apply { - log.info { toString() } - log.info { "${filename()} (${readBytes().size} bytes)" } + logger.info { toString() } + logger.info { "${filename()} (${readBytes().size} bytes)" } job.attributes.remove("document-name-supplied") - log.info { filename() } + logger.info { filename() } assertEquals("bin", filenameSuffix()) } } diff --git a/src/test/kotlin/de/gmuth/ipp/client/IppPrinterTests.kt b/src/test/kotlin/de/gmuth/ipp/client/IppPrinterTests.kt index 7f9d7a1e..8b885e27 100644 --- a/src/test/kotlin/de/gmuth/ipp/client/IppPrinterTests.kt +++ b/src/test/kotlin/de/gmuth/ipp/client/IppPrinterTests.kt @@ -31,7 +31,7 @@ import kotlin.test.assertTrue class IppPrinterTests { - val log = getLogger(javaClass.name) + private val logger = getLogger(javaClass.name) val blankPdf = File("tool/A4-blank.pdf") val ippClientMock = IppClientMock("printers/Simulated_Laser_Printer") val printer = IppPrinter( @@ -42,7 +42,7 @@ class IppPrinterTests { @Test fun printerAttributes() { printer.run { - log.info { toString() } + logger.info { toString() } assertTrue(isAcceptingJobs) assertTrue(documentFormatSupported.contains("application/pdf")) assertTrue(supportsOperations(GetPrinterAttributes)) @@ -64,7 +64,7 @@ class IppPrinterTests { assertEquals(80, levelPercent()) assertEquals("#000000", colorCode) assertFalse(levelIsLow()) - log.info { this.toString() } + logger.info { this.toString() } } assertTrue(isIdle()) assertFalse(isProcessing()) @@ -72,13 +72,13 @@ class IppPrinterTests { assertFalse(isMediaNeeded()) assertFalse(isCups()) printerType.apply { - log.info { toString() } - log(log) + logger.info { toString() } + log(logger) } communicationChannelsSupported.forEach { - log.info { "${it.uri}, ${it.security}, ${it.authentication}, $it" } + logger.info { "${it.uri}, ${it.security}, ${it.authentication}, $it" } } - ippConfig.log(log) + ippConfig.log(logger) } } @@ -93,7 +93,7 @@ class IppPrinterTests { ippClientMock.mockResponse("Get-Printer-Attributes.ipp") printer.run { updateAttributes() - log(log) + log(logger) assertEquals(122, attributes.size) } } @@ -142,7 +142,7 @@ class IppPrinterTests { fun printJobInputStream() { ippClientMock.mockResponse("Print-Job.ipp") printer.printJob(FileInputStream(blankPdf)).run { - log(log) + log(logger) assertEquals(461881017, id) assertEquals(JobState.Pending, state) assertEquals(listOf("none"), stateReasons) diff --git a/src/test/kotlin/de/gmuth/ipp/client/issueNo11.kt b/src/test/kotlin/de/gmuth/ipp/client/issueNo11.kt index bf2001f3..d6387fe9 100644 --- a/src/test/kotlin/de/gmuth/ipp/client/issueNo11.kt +++ b/src/test/kotlin/de/gmuth/ipp/client/issueNo11.kt @@ -5,17 +5,13 @@ import java.util.logging.Level.SEVERE import java.util.logging.Logger.getLogger fun main() { - //Logging.defaultLogLevel = Logging.LogLevel.DEBUG - //HttpURLConnectionClient.log.logLevel = Logging.LogLevel.TRACE - //IppClient.log.logLevel = Logging.LogLevel.DEBUG - - val log = getLogger("issueNo11") + val logger = getLogger("issueNo11") //val printerUri = URI.create("ipp://192.168.31.244:631/ipp/print") val printerUri = URI.create("ipp://xero.local/ipp/print") try { - log.info { "open ipp connection to $printerUri" } + logger.info { "open ipp connection to $printerUri" } with( IppPrinter( printerUri, @@ -23,11 +19,11 @@ fun main() { //getPrinterAttributesOnInit = false ) ) { - log.info { "successfully connected $printerUri" } - log.info { toString() } - markers.forEach { log.info { it.toString() } } + logger.info { "successfully connected $printerUri" } + logger.info { toString() } + markers.forEach { logger.info { it.toString() } } } } catch (exception: Exception) { - log.log(SEVERE, exception, { "failed to connect to $printerUri" }) + logger.log(SEVERE, exception, { "failed to connect to $printerUri" }) } } \ No newline at end of file diff --git a/src/test/kotlin/de/gmuth/ipp/client/issueNo3.kt b/src/test/kotlin/de/gmuth/ipp/client/issueNo3.kt index 043f1d5e..b97ffdc0 100644 --- a/src/test/kotlin/de/gmuth/ipp/client/issueNo3.kt +++ b/src/test/kotlin/de/gmuth/ipp/client/issueNo3.kt @@ -11,7 +11,7 @@ fun main() { //ConsoleLogger.defaultLogLevel = Logging.LogLevel.DEBUG //HttpURLConnectionClient.log.logLevel = Logging.LogLevel.TRACE - val log = getLogger("issueNo3") + val logger = getLogger("issueNo3") var ippPrinter: IppPrinter? = null // httpConnect(printerUri) @@ -19,30 +19,30 @@ fun main() { val ippConfig = IppConfig().apply { ippVersion = "1.1" - log(log) + log(logger) } try { - log.info { "open ipp connection to $printerUri" } + logger.info { "open ipp connection to $printerUri" } ippPrinter = IppPrinter(printerUri, ippConfig = ippConfig, getPrinterAttributesOnInit = true) - log.info { "successfully connected $printerUri" } + logger.info { "successfully connected $printerUri" } } catch (exception: Exception) { - log.log(SEVERE, exception, { "failed to connect to $printerUri" }) + logger.log(SEVERE, exception, { "failed to connect to $printerUri" }) } if (ippPrinter != null) ippPrinter.run { if (saveAttributes) { try { savePrinterAttributes() - log.info { "saved printer attributes" } + logger.info { "saved printer attributes" } } catch (exception: Exception) { - log.log(SEVERE, exception, { "failed to save printer attributes" }) + logger.log(SEVERE, exception, { "failed to save printer attributes" }) } } try { - log.info { "documentFormatSupported:" } - documentFormatSupported.forEach { log.info { " $it" } } + logger.info { "documentFormatSupported:" } + documentFormatSupported.forEach { logger.info { " $it" } } } catch (exception: Exception) { - log.log(SEVERE, exception, { "failed to read documentFormatSupported" }) + logger.log(SEVERE, exception, { "failed to read documentFormatSupported" }) } } } diff --git a/src/test/kotlin/de/gmuth/ipp/core/IppAttributeTests.kt b/src/test/kotlin/de/gmuth/ipp/core/IppAttributeTests.kt index 31e316a4..d845a794 100644 --- a/src/test/kotlin/de/gmuth/ipp/core/IppAttributeTests.kt +++ b/src/test/kotlin/de/gmuth/ipp/core/IppAttributeTests.kt @@ -16,7 +16,7 @@ class IppAttributeTests { Logging.configure() } - private val log = getLogger(javaClass.name) + private val logger = getLogger(javaClass.name) private val attribute = IppAttribute("printer-state-reasons", Keyword, "none") @Test @@ -98,7 +98,7 @@ class IppAttributeTests { @Test fun log() { // cover an output with more than 160 characters and a collection value - IppAttribute("media-col".padEnd(160, '-'), BegCollection, IppCollection()).log(log) + IppAttribute("media-col".padEnd(160, '-'), BegCollection, IppCollection()).log(logger) } @Test diff --git a/src/test/kotlin/de/gmuth/ipp/core/IppAttributesGroupTests.kt b/src/test/kotlin/de/gmuth/ipp/core/IppAttributesGroupTests.kt index de725e93..7087d0ab 100644 --- a/src/test/kotlin/de/gmuth/ipp/core/IppAttributesGroupTests.kt +++ b/src/test/kotlin/de/gmuth/ipp/core/IppAttributesGroupTests.kt @@ -14,7 +14,7 @@ import kotlin.test.assertTrue class IppAttributesGroupTests { - private val log = getLogger(javaClass.name) + private val logger = getLogger(javaClass.name) private val group = IppAttributesGroup(Operation) @Test @@ -121,7 +121,7 @@ class IppAttributesGroupTests { @Test fun log() { group.attribute("Commodore PET", Integer, 2001) - group.log(log, prefix = "|", title = "title") + group.log(logger, prefix = "|", title = "title") } @Test diff --git a/src/test/kotlin/de/gmuth/ipp/core/IppCollectionTests.kt b/src/test/kotlin/de/gmuth/ipp/core/IppCollectionTests.kt index d4d8f14c..a1c8c2f2 100644 --- a/src/test/kotlin/de/gmuth/ipp/core/IppCollectionTests.kt +++ b/src/test/kotlin/de/gmuth/ipp/core/IppCollectionTests.kt @@ -12,7 +12,7 @@ import kotlin.test.assertFailsWith class IppCollectionTests { - private val log = getLogger(javaClass.name) + private val logger = getLogger(javaClass.name) private val collection = IppCollection(IppAttribute("foo", IppTag.Keyword, "a", "b")) @Test @@ -41,13 +41,13 @@ class IppCollectionTests { @Test fun logNarrow() { - collection.log(log) + collection.log(logger) } @Test fun logWide() { collection.addAll(listOf(IppAttribute("bar", IppTag.Keyword, "c".repeat(160)))) - collection.log(log) + collection.log(logger) } } \ No newline at end of file diff --git a/src/test/kotlin/de/gmuth/ipp/core/IppInputStreamTests.kt b/src/test/kotlin/de/gmuth/ipp/core/IppInputStreamTests.kt index 79e1b89d..efa00c76 100644 --- a/src/test/kotlin/de/gmuth/ipp/core/IppInputStreamTests.kt +++ b/src/test/kotlin/de/gmuth/ipp/core/IppInputStreamTests.kt @@ -185,7 +185,7 @@ class IppInputStreamTest { "01 01 00 0B 00 00 00 08 01 47 00 01 61 00 01 66 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF AA" assertFailsWith { encoded.toIppInputStream().run { - log.level = ALL + logger.level = ALL readMessage(message) } } diff --git a/src/test/kotlin/de/gmuth/ipp/core/IppMessageTests.kt b/src/test/kotlin/de/gmuth/ipp/core/IppMessageTests.kt index 5fe106f8..ab64b456 100644 --- a/src/test/kotlin/de/gmuth/ipp/core/IppMessageTests.kt +++ b/src/test/kotlin/de/gmuth/ipp/core/IppMessageTests.kt @@ -12,7 +12,7 @@ import kotlin.test.* class IppMessageTests { - val log = getLogger(javaClass.name) + private val logger = getLogger(javaClass.name) private val message = object : IppMessage() { override val codeDescription: String @@ -57,7 +57,7 @@ class IppMessageTests { assertEquals(38, rawBytes!!.size) write(ByteArrayOutputStream()) // cover warning toString() // cover toString - log(log) // cover log + log(logger) // cover log } } @@ -89,7 +89,7 @@ class IppMessageTests { @Test fun withoutRawBytes() { assertEquals("codeDescription []", message.toString()) - message.log(log) + message.log(logger) assertFailsWith { // missing raw bytes message.saveBytes(createTempFile("test", null)) } diff --git a/src/test/kotlin/de/gmuth/ipp/core/IppOutputStreamTests.kt b/src/test/kotlin/de/gmuth/ipp/core/IppOutputStreamTests.kt index 753246d6..41d54f6c 100644 --- a/src/test/kotlin/de/gmuth/ipp/core/IppOutputStreamTests.kt +++ b/src/test/kotlin/de/gmuth/ipp/core/IppOutputStreamTests.kt @@ -18,7 +18,6 @@ import kotlin.test.assertFailsWith class IppOutputStreamTest { - private val log = Logger.getLogger(javaClass.name) private val byteArrayOutputStream = ByteArrayOutputStream() private val ippOutputStream = IppOutputStream(byteArrayOutputStream).apply { attributesCharset = Charsets.US_ASCII } diff --git a/src/test/kotlin/de/gmuth/ipp/core/IppRequestTests.kt b/src/test/kotlin/de/gmuth/ipp/core/IppRequestTests.kt index da9350eb..7c4905aa 100644 --- a/src/test/kotlin/de/gmuth/ipp/core/IppRequestTests.kt +++ b/src/test/kotlin/de/gmuth/ipp/core/IppRequestTests.kt @@ -15,14 +15,14 @@ import kotlin.test.assertNotNull class IppRequestTests { - val log = getLogger(javaClass.name) + private val logger = getLogger(javaClass.name) @Test fun requestConstructor1() { IppRequest().run { code = 5 - log.info { toString() } - log(log) + logger.info { toString() } + log(logger) assertEquals(null, version) assertEquals(IppOperation.CreateJob, operation) createAttributesGroup(IppTag.Operation) @@ -51,10 +51,10 @@ class IppRequestTests { listOf("one", "two"), "user" ) request.documentInputStream = "pdl-content".byteInputStream() - log.info { request.toString() } - request.log(log) + logger.info { request.toString() } + request.log(logger) val requestEncoded = request.encode() - log.info { "encoded ${requestEncoded.size} bytes" } + logger.info { "encoded ${requestEncoded.size} bytes" } val requestDecoded = IppRequest() requestDecoded.decode(requestEncoded) assertEquals("2.0", requestDecoded.version) diff --git a/src/test/kotlin/de/gmuth/ipp/core/IppResponseTests.kt b/src/test/kotlin/de/gmuth/ipp/core/IppResponseTests.kt index e1735f14..b770c918 100644 --- a/src/test/kotlin/de/gmuth/ipp/core/IppResponseTests.kt +++ b/src/test/kotlin/de/gmuth/ipp/core/IppResponseTests.kt @@ -18,7 +18,7 @@ class IppResponseTests { Logging.configure() } - val log = getLogger(javaClass.name) + private val logger = getLogger(javaClass.name) private val ippResponse = IppResponse() @Test @@ -43,7 +43,7 @@ class IppResponseTests { @Test fun invalidXeroxMediaColResponse() = ippResponse.run { read(File("src/test/resources/invalidXeroxMediaCol.response")) - log(log) + log(logger) jobGroup.run { assertEquals(598, getValue("job-id")) assertEquals(4, getValue("job-state")) // pending-held @@ -60,7 +60,7 @@ class IppResponseTests { // IppInputStream solution: first mark(2) then NameWithLanguage -> readShort().let { if (markSupported() && it < 6) reset() } // requestNaturalLanguage = "de" // triggers HP name with language bug ippResponse.read(File("src/test/resources/invalidHpNameWithLanguage.response")) - ippResponse.log(log) + ippResponse.log(logger) ippResponse.jobGroup.run { assertEquals(IppString("A4-blank.pdf", "de"), getValue("job-name")) assertEquals(993, getValue("job-id"))