1616
1717import java .io .IOException ;
1818import java .io .InputStream ;
19+ import java .lang .ref .Cleaner ;
1920import java .util .Iterator ;
2021
2122import javax .imageio .ImageIO ;
2223import javax .imageio .ImageReader ;
2324import javax .imageio .stream .ImageInputStream ;
2425
26+ import org .htmlunit .WebClient ;
2527import org .htmlunit .platform .geom .IntDimension2D ;
2628
2729/**
@@ -47,7 +49,56 @@ public class ImageIOImageData implements ImageData {
4749
4850 // private static final Log LOG = LogFactory.getLog(ImageIOImageData.class);
4951
50- private final ImageReader imageReader_ ;
52+ private IntDimension2D dim_ ;
53+
54+ private final ImageIOImageDataCleaningAction cleaningAction_ ;
55+ private final Cleaner .Cleanable cleanable_ ;
56+
57+ private static final class ImageIOImageDataCleaningAction implements Runnable {
58+ private ImageReader imageReader_ ;
59+ private InputStream inputStream_ ;
60+
61+ ImageIOImageDataCleaningAction (final ImageReader imageReader , final InputStream inputStream ) {
62+ imageReader_ = imageReader ;
63+ inputStream_ = inputStream ;
64+ }
65+
66+ synchronized ImageReader getImageReader () {
67+ if (imageReader_ == null ) {
68+ throw new IllegalStateException ("ImageIOImageData is closed" );
69+ }
70+ return imageReader_ ;
71+ }
72+
73+ @ Override
74+ public synchronized void run () {
75+ if (imageReader_ == null ) {
76+ return ;
77+ }
78+
79+ try (ImageInputStream stream = (ImageInputStream ) imageReader_ .getInput ()) {
80+ // nothing
81+ }
82+ catch (final IOException e ) {
83+ // optionally log
84+ }
85+ finally {
86+ imageReader_ .setInput (null );
87+ imageReader_ .dispose ();
88+ imageReader_ = null ;
89+ }
90+
91+ try {
92+ inputStream_ .close ();
93+ }
94+ catch (final IOException e ) {
95+ // optionally log
96+ }
97+ finally {
98+ inputStream_ = null ;
99+ }
100+ }
101+ }
51102
52103 /**
53104 * Ctor.
@@ -59,12 +110,15 @@ public ImageIOImageData(final InputStream inputStream) throws IOException {
59110 final Iterator <ImageReader > iter = ImageIO .getImageReaders (iis );
60111 if (!iter .hasNext ()) {
61112 iis .close ();
113+ inputStream .close ();
62114 throw new IOException ("No image detected in response" );
63115 }
116+
64117 final ImageReader imageReader = iter .next ();
65118 imageReader .setInput (iis );
66119
67- imageReader_ = imageReader ;
120+ cleaningAction_ = new ImageIOImageDataCleaningAction (imageReader , inputStream );
121+ cleanable_ = WebClient .registerCleanerAction (this , cleaningAction_ );
68122
69123 // dispose all others
70124 while (iter .hasNext ()) {
@@ -78,37 +132,26 @@ public ImageIOImageData(final InputStream inputStream) throws IOException {
78132 * @return the {@link ImageReader}
79133 */
80134 public ImageReader getImageReader () {
81- return imageReader_ ;
135+ return cleaningAction_ . getImageReader () ;
82136 }
83137
84138 /**
85139 * {@inheritDoc}
86140 */
87141 @ Override
88142 public IntDimension2D getWidthHeight () throws IOException {
89- return new IntDimension2D (imageReader_ .getWidth (0 ), imageReader_ .getHeight (0 ));
143+ if (dim_ == null ) {
144+ final ImageReader imgReader = cleaningAction_ .getImageReader ();
145+ dim_ = new IntDimension2D (imgReader .getWidth (0 ), imgReader .getHeight (0 ));
146+ }
147+ return dim_ ;
90148 }
91149
92150 /**
93151 * {@inheritDoc}
94152 */
95153 @ Override
96- protected void finalize () throws Throwable {
97- close ();
98- super .finalize ();
99- }
100-
101- @ Override
102- @ SuppressWarnings ("PMD.UnusedLocalVariable" )
103- public void close () throws IOException {
104- if (imageReader_ != null ) {
105- try (ImageInputStream stream = (ImageInputStream ) imageReader_ .getInput ()) {
106- // nothing
107- }
108- finally {
109- imageReader_ .setInput (null );
110- imageReader_ .dispose ();
111- }
112- }
154+ public void close () {
155+ cleanable_ .clean ();
113156 }
114157}
0 commit comments