Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8314070: javax.print: Support IPP output-bin attribute extension #16166

Closed

Conversation

AlexanderScherbatiy
Copy link

@AlexanderScherbatiy AlexanderScherbatiy commented Oct 12, 2023

The fix adds new public OutputBin print attribute class which allow to set a printer output bin in a PrinterJob class. The corresponding internal CustomOutputBin class is added as well.

  • Constants used in OutputBin class are based on Internet Printing Protocol (IPP): “output-bin” attribute extension document.
  • CUPSPrinter.getOutputBins(String printer) method uses PPD ppdFindOption(..., "OutputBin") function to get supported output bins for the given printer on native level.
  • The fix propagates the OutputBin attribute from the printer job attributes to NSPrintInfo print settings with OutputBin key on macOS.

The fix was tested on Kyocera ECOSYS M8130cidn printer where ppdFindOption(..., "OutputBin") call returns 4 output bins (text, choice):

  • Printer settings, None
  • Inner tray, INNERTRAY
  • Separator tray, SEPARATORTRAY
  • Finisher (face-down), Main

if Printer settings, Inner tray, or Finisher (face-down) CustomOutputBins is set to PrinterJob.print(...) attributes a test page is printed to the Main tray of the Kyocera ECOSYS M8130cidn printer. If Separator tray is used a page is printed to the Separator tray. This is consistent with the printer behavior when a native print dialog is used from a native Preview app to print a document on macOS.


Progress

  • Change must not contain extraneous whitespace
  • Commit message must refer to an issue
  • Change requires CSR request JDK-8331601 to be approved
  • Change must be properly reviewed (2 reviews required, with at least 2 Reviewers)

Issues

  • JDK-8314070: javax.print: Support IPP output-bin attribute extension (Enhancement - P4)
  • JDK-8331601: javax.print: Support IPP output-bin attribute extension (CSR)

Reviewers

Reviewing

Using git

Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/16166/head:pull/16166
$ git checkout pull/16166

Update a local copy of the PR:
$ git checkout pull/16166
$ git pull https://git.openjdk.org/jdk.git pull/16166/head

Using Skara CLI tools

Checkout this PR locally:
$ git pr checkout 16166

View PR using the GUI difftool:
$ git pr show -t 16166

Using diff file

Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/16166.diff

Webrev

Link to Webrev Comment

@bridgekeeper
Copy link

bridgekeeper bot commented Oct 12, 2023

👋 Welcome back alexsch! A progress list of the required criteria for merging this PR into master will be added to the body of your pull request. There are additional pull request commands available for use with this pull request.

@openjdk openjdk bot added the rfr Pull request is ready for review label Oct 12, 2023
@openjdk
Copy link

openjdk bot commented Oct 12, 2023

@AlexanderScherbatiy The following label will be automatically applied to this pull request:

  • client

When this pull request is ready to be reviewed, an "RFR" email will be sent to the corresponding mailing list. If you would like to change these labels, use the /label pull request command.

@openjdk openjdk bot added the client client-libs-dev@openjdk.org label Oct 12, 2023
@mlbridge
Copy link

mlbridge bot commented Oct 12, 2023

@prrace
Copy link
Contributor

prrace commented Oct 17, 2023

Why did you file a new RFE when you know about the existing one ?
Close your new one as a dup. and redirect everything to the existing one.
Also I don't see any UI work to enhance the dialog so it can be selected.
And why restrict it to macOS ? Is it an issue of testing ?

* <p>
* <b>IPP Compatibility:</b> The category name returned by {@code getName()} is
* the IPP attribute name. The {@code toString()} method returns the IPP
* string representation of the attribute value.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this needs to mention that it is an IPP extension attribute, meaning not a standard one
For example like here
https://docs.oracle.com/en/java/javase/21/docs/api/java.desktop/javax/print/attribute/standard/PresentationDirection.html

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The javadoc is updated to

 * <b>IPP Compatibility:</b> This attribute is not an IPP 1.1 attribute; it is
 * an attribute in the "output-bin" attribute extension
 * (<a href="https://ftp.pwg.org/pub/pwg/candidates/cs-ippoutputbin10-20010207-5100.2.pdf">
 * PDF</a>) of IPP 1.1. The category name returned by {@code getName()} is the
 * IPP attribute name. The enumeration's integer value is the IPP enum value.
 * The {@code toString()} method returns the IPP string representation of the
 * attribute value.

and @Override annotations are added to OutputBin and CustomOutputBin methods.

@AlexanderScherbatiy
Copy link
Author

Why did you file a new RFE when you know about the existing one ? Close your new one as a dup. and redirect everything to the existing one. Also I don't see any UI work to enhance the dialog so it can be selected. And why restrict it to macOS ? Is it an issue of testing ?

My idea was to use JDK-8314070 as an umbrella and provide fixes for macOS, Linux, and Windows separately. While the OutputBin public API is not fixed any change in it would require to re-test the fix on all 3 platforms.
The fix for the UI dialog requires an additional test with a printer dialog so there would be 2 tests for each platform for re-testing for each essential change in the fix.

@prrace
Copy link
Contributor

prrace commented Nov 2, 2023

Why did you file a new RFE when you know about the existing one ? Close your new one as a dup. and redirect everything to the existing one. Also I don't see any UI work to enhance the dialog so it can be selected. And why restrict it to macOS ? Is it an issue of testing ?

My idea was to use JDK-8314070 as an umbrella and provide fixes for macOS, Linux, and Windows separately. While the OutputBin public API is not fixed any change in it would require to re-test the fix on all 3 platforms. The fix for the UI dialog requires an additional test with a printer dialog so there would be 2 tests for each platform for re-testing for each essential change in the fix.

I'm struggling to follow the logic.
This change clearly contains the public API which is the first thing you need.
Burying it in the fix for one platform that happens to be the first one you coded isn't right.

If you really want to stagger it then proceed as follows

  1. Add just the new API class under the existing RFE
  2. Add this macOS support for it under this ID
  3. Add the Swing dialog UI support for selecting the bin - easier once you have one implementation
  4. Add Linux support (CUPS, so should be similar to macOS)
  5. Add Windows support, but SFAIK GDI has no support for this, so likely impossible to do.

@bridgekeeper
Copy link

bridgekeeper bot commented Dec 1, 2023

@AlexanderScherbatiy This pull request has been inactive for more than 4 weeks and will be automatically closed if another 4 weeks passes without any activity. To avoid this, simply add a new comment to the pull request. Feel free to ask for assistance if you need help with progressing this pull request towards integration!

@AlexanderScherbatiy
Copy link
Author

AlexanderScherbatiy commented Dec 7, 2023

This is some investigation which I did for output bin attribute extension support on Linux.

PostScript Language Reference manual third edition defines OutputType page device parameter with type string which represents special attributes of the output destination.

The example of OutputType usage I have found in CUPS PPD Extensions.
OutputType specifies the output type name, for example:

<</OutputType (Photo)>>setpagedevice

This is my implementation of adding OutputType parameter in PSPrinterJob AlexanderScherbatiy@92ce5b9 added to a separate branch

    protected void startDoc() throws PrinterException {
            ...
            String outputBin = getOutputBinValue(outputBinAttr);

            if (outputBin != null) {
                mPSStream.print(" /OutputType (" + outputBin + ") ");
            }

I tested it with Kyocera ECOSYS M8130cidn printer using Ubuntu 20.04.1 LTS.
The ppdFindOption(ppd, "OutputBin") function from CUPSfuncs returns two output bins for the Kyocera ECOSYS M8130cidn:

text: Top, choice: Top
text: Stacker 1, choice: Stacker1

The result was that a page is printed to the same output tray (Top) no matter Top or Stacker1 output bin is used for OutputType post script parameter.

First, I checked that printing a pdf file from the Unix PDF Viewer app using the system print dialog and choosing different output trays really prints pages to different output trays.

Second, I copied post script files sent by java program for printing from /var/spool/cups directory.
The post script file for Top output bin contains:

%!PS-Adobe-3.0
...
%%BeginSetup
<< /PageSize [595.2755737304688 841.8897705078125] /DeferredMediaSelection true /ImagingBBox null /ManualFeed false /NumCopies 1 /OutputType (Top)  >> setpagedevice
%%EndSetup

which /OutputType (Top) setting looks correct.
And for the Stacker1 output bin:

%%BeginSetup
<< /PageSize [595.2755737304688 841.8897705078125] /DeferredMediaSelection true /ImagingBBox null /ManualFeed false /NumCopies 1 /OutputType (Stacker1)  >> setpagedevice
%%EndSetup

the setting for output bin is /OutputType (Stacker1).

The file which sends the PDF Viewer for printing includes %PDF-1.5 version and I was not able to find the parameter corresponding to the selected output bin even if I convert the file from pdf to ps format using pdf2ps tool which generates file in %!PS-Adobe-3.0 fromat.

It is not clear for me why /OutputType (Stacker1) parameter does not work and is there a way to take the output bin parameter which Linux native printer dialog use to print a document to the Stacker 1 tray for the Kyocera ECOSYS M8130cidn printer.

One more question which I have relates to the java common print dialog. It needs to contain list of available output bins. Is it safe to assume that the first output bin retrieved by ppdFindOption(ppd, "OutputBin") is the default one? Or should there be added one more Default option for the default output bin selection?

@openjdk
Copy link

openjdk bot commented Dec 7, 2023

@AlexanderScherbatiy this pull request can not be integrated into master due to one or more merge conflicts. To resolve these merge conflicts and update this pull request you can run the following commands in the local repository for your personal fork:

git checkout JDK-8318023
git fetch https://git.openjdk.org/jdk.git master
git merge FETCH_HEAD
# resolve conflicts and follow the instructions given by git merge
git commit -m "Merge master"
git push

@openjdk openjdk bot added merge-conflict Pull request has merge conflict with target branch and removed rfr Pull request is ready for review labels Dec 7, 2023
@AlexanderScherbatiy
Copy link
Author

/issue add 8314070

@openjdk
Copy link

openjdk bot commented Dec 7, 2023

@AlexanderScherbatiy
Adding additional issue to issue list: 8314070: javax.print: Support IPP output-bin attribute extension.

@AlexanderScherbatiy AlexanderScherbatiy changed the title 8318023: Implement IPP output-bin attribute extension on macOS 8314070: javax.print: Support IPP output-bin attribute extension Dec 7, 2023
@openjdk openjdk bot added rfr Pull request is ready for review and removed merge-conflict Pull request has merge conflict with target branch labels Dec 12, 2023
@AlexanderScherbatiy
Copy link
Author

The common print dialog is updated to show supported output bins.

  • OutputPanel is added to the ServiceDialog to show list of supported output bins in the ComboBox.
  • order.output and label.outputbins properties are added to serviceui.properties.
  • CPrinterJob.nsPrintInfoToJavaPrinterJob() method is updated to add the selected output bin from the native print dialog to the printer job attributes.
  • OutputBinAttributePrintDialogTest manual test that checks only printing to the first and the last supported output bins with common and native print dialog is added.

Common print dialog with the fix which shows list of supported output bins on macOS:

The same dialog with disabled output trays when the list of output bins is empty:

The same dialog without the fix:

There is the comment on social.msdn.microsoft.com forum that wingdi does not support setting output bin attribute programmatically:

"'Output tray" is a printer-specific property (note that you will only see such an option
in the printing interface for certain printers).  There is no way to programmatically set 
an output tray, since there is no generic way of doing it via .NET (or even Win32 
via the DEVMODE structure).  The only way to set it is to allow the user
to choose it via the provided printer dialog for the few printers that provide this capability
(just as you must do via IE or Word).

It is sometimes possible to do this programmatically (without the dialog) for a specific
printer if you know exactly how that printer driver implements the change...but that
is unsupported  except possibly from the printer manufacturer.

https://social.msdn.microsoft.com/Forums/en-US/b15eda2f-5353-41fc-b935-078ed0960aee/printing-into-a-specific-output-bintray-net

That is why OutputPanel is excluded from the ServiceDialog on Windows.

@bridgekeeper
Copy link

bridgekeeper bot commented Jan 10, 2024

@AlexanderScherbatiy This pull request has been inactive for more than 4 weeks and will be automatically closed if another 4 weeks passes without any activity. To avoid this, simply add a new comment to the pull request. Feel free to ask for assistance if you need help with progressing this pull request towards integration!

@AlexanderScherbatiy
Copy link
Author

@AlexanderScherbatiy This pull request has been inactive for more than 4 weeks and will be automatically closed if another 4 weeks passes without any activity. To avoid this, simply add a new comment to the pull request. Feel free to ask for assistance if you need help with progressing this pull request towards integration!

@AlexanderScherbatiy
Copy link
Author

@prrace
The automated CheckSupportedOutputBinsTest is added which works on all platforms and checks that methods PrintService.isAttributeCategorySupported(OutputBin.class), PrintService.getDefaultAttributeValue(OutputBin.class), and PrintService..getSupportedAttributeValues(OutputBin.class,...) returns consistent results.

It has been tested on Linux, MacOS, and Windows with several installed printers.

@AlexanderScherbatiy
Copy link
Author

@prrace @prsadhuk
The OutputBinAttributePrintDialogTest tests both common and native dialogs now.

Actually the native dialog test works on MacOS only if the native print dialog includes Finishing Options with the list of output bins.
It may or may not work if the output bins are placed on the separate Print Panel or in another place.
It just because the native print dialog which includes Finishing Options stores the selected output bin with the OutputBin key in the NSPrintInfo print settings
while other native print dialogs may not store the selected output bin in the NSPrintInfo print settings.

May be it is better to split the OutputBinAttributePrintDialogTest test to common (OutputBinAttributeCommonPrintDialogTest) and native (OutputBinAttributeNativePrintDialogTest) tests
and ask to skip the native test if the native print dialog does not include Finishing Options with the list of the output bins?

@@ -46,6 +46,7 @@
import javax.print.attribute.standard.MediaSizeName;
import javax.print.attribute.standard.PageRanges;
import javax.print.attribute.standard.Sides;
import javax.print.attribute.standard.OutputBin;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sort the import...Guess OutputBin should come before PageRanges

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated.

@@ -90,6 +90,7 @@
import javax.print.attribute.standard.RequestingUserName;
import javax.print.attribute.standard.SheetCollate;
import javax.print.attribute.standard.Sides;
import javax.print.attribute.standard.OutputBin;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sort the import..OutputBin should be placed before PageRanges

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated.

outputBinAttr = (OutputBin)attributes.get(OutputBin.class);
if (!isSupportedValue(outputBinAttr, attributes)) {
outputBinAttr = null;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we set it to null if user-set output-bin attribute is not among supported values
or
should we set it to default
as is done for printer-resolution and others

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that setting the outputBinAttr to null should be fine as it means that no OutputBin value is provided by jdk and the printer will use the default one.

cbOutput.setEnabled(outputEnabled);
lblOutput.setEnabled(outputEnabled);

cbOutput.addItemListener(this);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If Attribute category is unsupported, the panel will be disabled, in that case, is there any need to add itemlistener? I guess we can make it conditional to category being supported

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fix is updated to add the itemListener only when the cbOutput JComboBox is enabled.

REAR,
FACE_UP,
FACE_DOWN,
LARGE_CAPACITY,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about this support?

@@ -1643,7 +1649,9 @@ private String[] printExecCmd(String printer, String options,
execCmd[n++] = "-o job-sheets=standard";
}
if ((pFlags & OPTIONS) != 0) {
execCmd[n++] = "-o" + options;
for(String option: options.trim().split(" ")) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

code formatting..space between for and (

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

code formatting is updated.

@@ -1666,7 +1674,9 @@ private String[] printExecCmd(String printer, String options,
execCmd[n++] = "-o job-sheets=standard";
}
if ((pFlags & OPTIONS) != 0) {
execCmd[n++] = "-o" + options;
for(String option: options.trim().split(" ")) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

space is needed for coding style guideline between for and {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated.

import javax.print.attribute.standard.Media;
import javax.print.attribute.standard.MediaSizeName;
import javax.print.attribute.standard.MediaSize;
import javax.print.attribute.standard.MediaTray;
import javax.print.attribute.standard.OutputBin;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Import sorting improper...Should be after MediaPrintableArea and before PrinterResolution

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The OutputBin import is updated.


/*
* @test
* @bug JDK-8314070
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be just bugid

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JDK- prefix is removed.


/*
* @test
* @bug JDK-8314070
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only bugid is needed

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated.


/*
* @test
* @bug JDK-8314070
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here only bugid needed

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated.

REAR,
FACE_UP,
FACE_DOWN,
LARGE_CAPACITY,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I understood is, it is acceptable to identify or get
tray-1, tray-2, tray-3 name
instead of descriptive names like
TOP, MIDDLE, BOTTOM respectively etc
so as such it can support upto 11 trays ie FROM TOP till LARGE_CAPACITY

but am not sure if it is to be added in addition or in-place of the descriptive names?

/*
* @test
* @bug 8314070
* @key printer
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DO you want to run this on all platforms? Other tests are for linux and mac only!! but guess it's not a problem..

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this test is intended to run on all platforms. On Windows it just checks that there are no unexpected exceptions if OutputBin category is passed to PrintService methods.

@AlexanderScherbatiy
Copy link
Author

The OutputBinAttributePrintDialogTest is updated for the native dialog to have the Skip Test button and description that if the native print dialog on MacOS does not contain Finishing Options then the test should be skipped.

Copy link
Contributor

@prsadhuk prsadhuk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall Looks good to me although I could not test it fully to my liking owing to non-support of output-bin in my printer..

@AlexanderScherbatiy
Copy link
Author

@AlexanderScherbatiy please note that if you get one approval and have resolved all issues and believe it just needs the 2nd reviewer to formally approve it that the integrate command has some useful options https://wiki.openjdk.org/display/SKARA/Pull+Request+Commands#PullRequestCommands-/integrate

@prrace
Should I use the integrate command with the auto or delegate parameter?

@prrace
Copy link
Contributor

prrace commented Jun 3, 2024

@prrace Should I use the integrate command with the auto or delegate parameter?

Academic now, since I just approved it.

@openjdk openjdk bot added the ready Pull request is ready to be integrated label Jun 3, 2024
@AlexanderScherbatiy
Copy link
Author

/integrate

@openjdk
Copy link

openjdk bot commented Jun 4, 2024

Going to push as commit c7d2a5c.
Since your change was applied there have been 441 commits pushed to the master branch:

  • d230b30: 8333398: Uncomment the commented test in test/jdk/java/util/jar/JarFile/mrjar/MultiReleaseJarAPI.java
  • 1512011: 8332123: [nmt] Move mallocLimit code to the nmt subdir
  • 6dac8d6: 8332424: Update IANA Language Subtag Registry to Version 2024-05-16
  • 9686e80: 8333103: Re-examine the console provider loading
  • 4de6207: 8333229: Parallel: Rename ParMarkBitMap::_region_start to _heap_start
  • 1f9e629: 8333434: IGV: Print loop node for PHASE_BEFORE/AFTER_CLOOPS
  • 27af19d: 8332586: Avoid cloning empty arrays in java.lang.reflect.{Method,Constructor}
  • 1c514b3: 8325435: [macos] Menu or JPopupMenu not closed when main window is resized
  • d07e530: 8333128: Linux x86_32 configure fail with --with-hsdis=binutils --with-binutils-src
  • f0bffbc: 8333301: Remove static builds using --enable-static-build
  • ... and 431 more: https://git.openjdk.org/jdk/compare/b96b38c2c9a310d5fe49b2eda3e113a71223c7d1...master

Your commit was automatically rebased without conflicts.

@openjdk openjdk bot added the integrated Pull request has been integrated label Jun 4, 2024
@openjdk openjdk bot closed this Jun 4, 2024
@openjdk openjdk bot removed ready Pull request is ready to be integrated rfr Pull request is ready for review labels Jun 4, 2024
@openjdk
Copy link

openjdk bot commented Jun 4, 2024

@AlexanderScherbatiy Pushed as commit c7d2a5c.

💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
client client-libs-dev@openjdk.org integrated Pull request has been integrated
Development

Successfully merging this pull request may close these issues.

4 participants