OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [gnu/] [javax/] [print/] [ipp/] [IppPrintService.java] - Blame information for rev 769

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 769 jeremybenn
/* IppPrintService.java --
2
   Copyright (C) 2006 Free Software Foundation, Inc.
3
 
4
This file is part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2, or (at your option)
9
any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; see the file COPYING.  If not, write to the
18
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
02110-1301 USA.
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version. */
37
 
38
 
39
package gnu.javax.print.ipp;
40
 
41
import gnu.classpath.SystemProperties;
42
import gnu.classpath.debug.Component;
43
import gnu.classpath.debug.SystemLogger;
44
import gnu.javax.print.ipp.attribute.DefaultValueAttribute;
45
import gnu.javax.print.ipp.attribute.RequestedAttributes;
46
import gnu.javax.print.ipp.attribute.defaults.CopiesDefault;
47
import gnu.javax.print.ipp.attribute.defaults.FinishingsDefault;
48
import gnu.javax.print.ipp.attribute.defaults.JobHoldUntilDefault;
49
import gnu.javax.print.ipp.attribute.defaults.JobPriorityDefault;
50
import gnu.javax.print.ipp.attribute.defaults.JobSheetsDefault;
51
import gnu.javax.print.ipp.attribute.defaults.MediaDefault;
52
import gnu.javax.print.ipp.attribute.defaults.MultipleDocumentHandlingDefault;
53
import gnu.javax.print.ipp.attribute.defaults.NumberUpDefault;
54
import gnu.javax.print.ipp.attribute.defaults.OrientationRequestedDefault;
55
import gnu.javax.print.ipp.attribute.defaults.PrintQualityDefault;
56
import gnu.javax.print.ipp.attribute.defaults.PrinterResolutionDefault;
57
import gnu.javax.print.ipp.attribute.defaults.SidesDefault;
58
import gnu.javax.print.ipp.attribute.printer.DocumentFormat;
59
import gnu.javax.print.ipp.attribute.supported.CompressionSupported;
60
import gnu.javax.print.ipp.attribute.supported.DocumentFormatSupported;
61
import gnu.javax.print.ipp.attribute.supported.FinishingsSupported;
62
import gnu.javax.print.ipp.attribute.supported.JobHoldUntilSupported;
63
import gnu.javax.print.ipp.attribute.supported.JobSheetsSupported;
64
import gnu.javax.print.ipp.attribute.supported.MediaSupported;
65
import gnu.javax.print.ipp.attribute.supported.MultipleDocumentHandlingSupported;
66
import gnu.javax.print.ipp.attribute.supported.OperationsSupported;
67
import gnu.javax.print.ipp.attribute.supported.OrientationRequestedSupported;
68
import gnu.javax.print.ipp.attribute.supported.PageRangesSupported;
69
import gnu.javax.print.ipp.attribute.supported.PrintQualitySupported;
70
import gnu.javax.print.ipp.attribute.supported.PrinterResolutionSupported;
71
import gnu.javax.print.ipp.attribute.supported.PrinterUriSupported;
72
import gnu.javax.print.ipp.attribute.supported.SidesSupported;
73
 
74
import java.io.IOException;
75
import java.lang.reflect.Field;
76
import java.net.URI;
77
import java.util.ArrayList;
78
import java.util.Arrays;
79
import java.util.Date;
80
import java.util.HashSet;
81
import java.util.Iterator;
82
import java.util.List;
83
import java.util.Map;
84
import java.util.Set;
85
import java.util.logging.Logger;
86
 
87
import javax.print.DocFlavor;
88
import javax.print.DocPrintJob;
89
import javax.print.PrintService;
90
import javax.print.ServiceUIFactory;
91
import javax.print.attribute.Attribute;
92
import javax.print.attribute.AttributeSet;
93
import javax.print.attribute.AttributeSetUtilities;
94
import javax.print.attribute.HashAttributeSet;
95
import javax.print.attribute.HashPrintServiceAttributeSet;
96
import javax.print.attribute.IntegerSyntax;
97
import javax.print.attribute.PrintServiceAttribute;
98
import javax.print.attribute.PrintServiceAttributeSet;
99
import javax.print.attribute.standard.Compression;
100
import javax.print.attribute.standard.Copies;
101
import javax.print.attribute.standard.CopiesSupported;
102
import javax.print.attribute.standard.Fidelity;
103
import javax.print.attribute.standard.Finishings;
104
import javax.print.attribute.standard.JobHoldUntil;
105
import javax.print.attribute.standard.JobImpressions;
106
import javax.print.attribute.standard.JobImpressionsSupported;
107
import javax.print.attribute.standard.JobKOctets;
108
import javax.print.attribute.standard.JobKOctetsSupported;
109
import javax.print.attribute.standard.JobMediaSheets;
110
import javax.print.attribute.standard.JobMediaSheetsSupported;
111
import javax.print.attribute.standard.JobName;
112
import javax.print.attribute.standard.JobPriority;
113
import javax.print.attribute.standard.JobPrioritySupported;
114
import javax.print.attribute.standard.JobSheets;
115
import javax.print.attribute.standard.Media;
116
import javax.print.attribute.standard.MultipleDocumentHandling;
117
import javax.print.attribute.standard.NumberUp;
118
import javax.print.attribute.standard.NumberUpSupported;
119
import javax.print.attribute.standard.OrientationRequested;
120
import javax.print.attribute.standard.PageRanges;
121
import javax.print.attribute.standard.PrintQuality;
122
import javax.print.attribute.standard.PrinterName;
123
import javax.print.attribute.standard.PrinterResolution;
124
import javax.print.attribute.standard.PrinterURI;
125
import javax.print.attribute.standard.RequestingUserName;
126
import javax.print.attribute.standard.Sides;
127
import javax.print.event.PrintServiceAttributeListener;
128
 
129
 
130
/**
131
 * Implementation of the PrintService interface
132
 * for IPP based printers.
133
 *
134
 * @author Wolfgang Baer (WBaer@gmx.de)
135
 */
136
public class IppPrintService implements PrintService
137
{
138
  /**
139
   * A Map with sets of attributes.
140
   * key: A attribute category
141
   * value: A set with values
142
   *
143
   * IPP may return sets of attributes e.g. for supported
144
   * compression methods so we need to map to sets here.
145
   */
146
  private Map<Class<? extends Attribute>, Set<Attribute>> printerAttr;
147
 
148
  /** The set of listeners.*/
149
  private HashSet<PrintServiceAttributeListener> printServiceAttributeListener;
150
 
151
  /** The username. */
152
  private transient String user;
153
 
154
  /** The password of the user. */
155
  private transient String passwd;
156
 
157
  /** The name of this print service. */
158
  private String name;
159
 
160
  /** The list of supported document flavors. */
161
  private List<DocFlavor> flavors;
162
 
163
  /** The standard printer URI. */
164
  private PrinterURI printerUri;
165
 
166
  /** The list of all supported printer URIs. */
167
  private ArrayList<PrinterURI> printerUris;
168
 
169
  /**
170
   * Logger for tracing - enable by passing
171
   * -Dgnu.classpath.debug.components=ipp to the vm.
172
   */
173
  static final Logger logger = SystemLogger.SYSTEM;
174
 
175
  /**
176
   * requesting-user-name defaults to the executing user.
177
   */
178
  public static final RequestingUserName REQUESTING_USER_NAME;
179
 
180
  /**
181
   * job-name defaults to "Java Printing".
182
   */
183
  public static final JobName JOB_NAME;
184
 
185
  static
186
  {
187
    JOB_NAME = new JobName("Java Printing", null);
188
    REQUESTING_USER_NAME = new RequestingUserName(
189
      SystemProperties.getProperty("user.name", ""), null);
190
  }
191
 
192
  // TODO Implement service listener notification and change detection.
193
 
194
  /**
195
   * Creates a <code>IppPrintService</code> object.
196
   *
197
   * @param uri the URI of the IPP printer.
198
   * @param username the user of this print service.
199
   * @param password the password of the user.
200
   *
201
   * @throws IppException if an error during connection occurs.
202
   */
203
  public IppPrintService(URI uri, String username, String password)
204
    throws IppException
205
  {
206
    printerUri = new PrinterURI(uri);
207
    user = username;
208
    passwd = password;
209
 
210
    printServiceAttributeListener =
211
      new HashSet<PrintServiceAttributeListener>();
212
 
213
    printerAttr = getPrinterAttributes();
214
    processResponse();
215
  }
216
 
217
  /**
218
   * Fetches all printer attributes from the IPP printer.
219
   *
220
   * @return The Map with the printer attributes.
221
   * @throws IppException if an error occurs.
222
   */
223
  private Map<Class<? extends Attribute>, Set<Attribute>> getPrinterAttributes()
224
    throws IppException
225
  {
226
    IppResponse response = null;
227
 
228
    try
229
      {
230
        IppRequest request = new IppRequest(printerUri.getURI(), user, passwd);
231
 
232
        int operation = OperationsSupported.GET_PRINTER_ATTRIBUTES.getValue();
233
        request.setOperationID((short) operation);
234
        request.setOperationAttributeDefaults();
235
        request.addOperationAttribute(printerUri);
236
 
237
        response = request.send();
238
      }
239
    catch (IOException e)
240
      {
241
        throw new IppException("IOException in IPP request/response.", e);
242
      }
243
 
244
    return response.getPrinterAttributes().get(0);
245
  }
246
 
247
  /**
248
   * Extracts the set of attribute values for a given
249
   * attribute category from the printer attributes map.
250
   *
251
   * @param attributeClass the category
252
   * @return The set of attributes of the category.
253
   */
254
  private <T extends Attribute> Set<T> getPrinterAttributeSet(Class<T> attributeClass)
255
  {
256
    Set<Attribute> set = printerAttr.get(attributeClass);
257
    Set<T> attSet = new HashSet<T>();
258
    for (Attribute att : set)
259
      attSet.add(attributeClass.cast(att));
260
    return attSet;
261
  }
262
 
263
  /**
264
   * Extracts the default attribute value for the given
265
   * default attribute category from the printer attributes map.
266
   *
267
   * @param attributeClass the category
268
   * @return The default attribute.
269
   *
270
   * @throws ClassCastException if attributClass is not an
271
   * instance of <code>DefaultValueAttribute</code>.
272
   */
273
  private Attribute getPrinterDefaultAttribute(Class<? extends Attribute> attributeClass)
274
  {
275
    Set<Attribute> set = printerAttr.get(attributeClass);
276
    return ((DefaultValueAttribute) set.toArray()[0]).getAssociatedAttribute();
277
  }
278
 
279
  /**
280
   * Processes the response, sorts and splits the attributes.
281
   */
282
  private void processResponse()
283
  {
284
    // printer name
285
    PrinterName[] tmp = getPrinterAttributeSet(PrinterName.class).toArray(new PrinterName[1]);
286
    name = tmp[0].getValue();
287
 
288
    // supported flavors
289
    // TODO Check if charsets-supported are charsets that are actually supported
290
    // for text doc flavors as cups doesn't send charset parameters
291
 
292
    // utf-8 is supported at least - so we go with this only for now
293
    flavors = new ArrayList<DocFlavor>();
294
    Set<DocumentFormatSupported> flavorAttributes = getPrinterAttributeSet(DocumentFormatSupported.class);
295
    if (flavorAttributes != null)
296
      {
297
        for (DocumentFormatSupported dfs : flavorAttributes)
298
          {
299
            String mimeType = dfs.getValue();
300
 
301
            if (mimeType.equals("text/plain"))
302
              {
303
                flavors.add(DocFlavor.CHAR_ARRAY.TEXT_PLAIN);
304
                flavors.add(DocFlavor.READER.TEXT_PLAIN);
305
                flavors.add(DocFlavor.STRING.TEXT_PLAIN);
306
 
307
                // add utf-8
308
                mimeType = mimeType + "; charset=utf-8";
309
              }
310
            else if (mimeType.equals("text/html"))
311
              {
312
                flavors.add(DocFlavor.CHAR_ARRAY.TEXT_HTML);
313
                flavors.add(DocFlavor.READER.TEXT_HTML);
314
                flavors.add(DocFlavor.STRING.TEXT_HTML);
315
 
316
                // add utf-8
317
                mimeType = mimeType + "; charset=utf-8";
318
              }
319
 
320
            // Process the predefined DocFlavors and if mimetype is
321
            // equal put them into the flavors array - otherwise
322
            // just build them as binarie class representation.
323
            boolean changed = false;
324
            try
325
              {
326
                Class<?>[] clazzes = new Class<?>[] { DocFlavor.BYTE_ARRAY.class,
327
                    DocFlavor.INPUT_STREAM.class,
328
                    DocFlavor.URL.class
329
                    };
330
 
331
                for (int j = 0; j < clazzes.length; j++)
332
                  {
333
                    Field[] fields = clazzes[j].getDeclaredFields();
334
                    for (int i = 0; i < fields.length; i++)
335
                      {
336
                        if (fields[i].getType().equals(clazzes[j]))
337
                          {
338
                            DocFlavor flavor = (DocFlavor) fields[i].get(null);
339
                            if (flavor.getMimeType().equals(mimeType))
340
                              changed = flavors.add(flavor);
341
                          }
342
                      }
343
                  }
344
                if (!changed) // not in predefined constants of DocFlavor
345
                  {
346
                    // everything should be supported as binary stuff
347
                    flavors.add(new DocFlavor(mimeType, "[B"));
348
                    flavors.add(new DocFlavor(mimeType, "java.io.InputStream"));
349
                    flavors.add(new DocFlavor(mimeType, "java.net.URL"));
350
                  }
351
              }
352
            catch (SecurityException e)
353
              {
354
                // should not happen
355
              }
356
            catch (IllegalArgumentException e)
357
              {
358
                // should not happen
359
              }
360
            catch (IllegalAccessException e)
361
              {
362
                // should not happen, all fields are public
363
              }
364
          }
365
 
366
        if (this.getClass()
367
            .isAssignableFrom(gnu.javax.print.CupsPrintService.class))
368
          {
369
//          CUPS always provides filters to convert from Postscript.
370
//          This logic looks odd, but it's what OpenJDK does.
371
            flavors.add(DocFlavor.SERVICE_FORMATTED.PAGEABLE);
372
            flavors.add(DocFlavor.SERVICE_FORMATTED.PRINTABLE);
373
          }
374
      }
375
 
376
    // printer uris
377
    Set<PrinterUriSupported> uris = getPrinterAttributeSet(PrinterUriSupported.class);
378
    printerUris = new ArrayList<PrinterURI>(uris.size());
379
    for (PrinterUriSupported uri : uris)
380
      {
381
        printerUris.add( new PrinterURI(uri.getURI()));
382
      }
383
  }
384
 
385
  /**
386
   * We always return a implementation implementing CancelablePrintJob.
387
   *
388
   * @see javax.print.PrintService#createPrintJob()
389
   */
390
  public DocPrintJob createPrintJob()
391
  {
392
    return new DocPrintJobImpl(this, user, passwd);
393
  }
394
 
395
 
396
  /**
397
   * @see javax.print.PrintService#getAttribute(java.lang.Class)
398
   */
399
  public <T extends PrintServiceAttribute> T getAttribute(Class<T> category)
400
  {
401
    if (category == null)
402
      throw new NullPointerException("category may not be null");
403
 
404
    if (! PrintServiceAttribute.class.isAssignableFrom(category))
405
      throw new IllegalArgumentException(
406
         "category must be of type PrintServiceAttribute");
407
 
408
    Set<T> set = getPrinterAttributeSet(category);
409
    if (set != null && set.size() > 0)
410
      return set.iterator().next();
411
 
412
    return null;
413
  }
414
 
415
  /**
416
   * @see javax.print.PrintService#getAttributes()
417
   */
418
  public PrintServiceAttributeSet getAttributes()
419
  {
420
    PrintServiceAttributeSet set = new HashPrintServiceAttributeSet();
421
 
422
    for (Set<Attribute> attrSet : printerAttr.values())
423
      {
424
        for (Attribute attr : attrSet)
425
          {
426
            if (attr instanceof PrintServiceAttribute)
427
              set.add(attr);
428
          }
429
      }
430
 
431
    return AttributeSetUtilities.unmodifiableView(set);
432
  }
433
 
434
  /**
435
   * @see javax.print.PrintService#getDefaultAttributeValue(java.lang.Class)
436
   */
437
  public Object getDefaultAttributeValue(Class<? extends Attribute> category)
438
  {
439
    // required attributes
440
    if (category.equals(Fidelity.class))
441
      return Fidelity.FIDELITY_FALSE;
442
    if (category.equals(JobName.class))
443
      return JOB_NAME;
444
    if (category.equals(RequestingUserName.class))
445
      return REQUESTING_USER_NAME;
446
 
447
    // optional attributes
448
    if (category.equals(JobPriority.class)
449
        && printerAttr.containsKey(JobPriorityDefault.class))
450
      return getPrinterDefaultAttribute(JobPriorityDefault.class);
451
    if (category.equals(JobHoldUntil.class)
452
        && printerAttr.containsKey(JobHoldUntilDefault.class))
453
      return getPrinterDefaultAttribute(JobHoldUntilDefault.class);
454
    if (category.equals(JobSheets.class)
455
        && printerAttr.containsKey(JobSheetsDefault.class))
456
      return getPrinterDefaultAttribute(JobSheetsDefault .class);
457
    if (category.equals(MultipleDocumentHandling.class)
458
        && printerAttr.containsKey(MultipleDocumentHandlingDefault.class))
459
      return getPrinterDefaultAttribute(MultipleDocumentHandlingDefault.class);
460
    if (category.equals(Copies.class)
461
        && printerAttr.containsKey(CopiesDefault.class))
462
      return getPrinterDefaultAttribute(CopiesDefault.class);
463
    if (category.equals(Finishings.class)
464
        && printerAttr.containsKey(FinishingsDefault.class))
465
      return getPrinterDefaultAttribute(FinishingsDefault.class);
466
    if (category.equals(Sides.class)
467
        && printerAttr.containsKey(SidesDefault.class))
468
      return getPrinterDefaultAttribute(SidesDefault.class);
469
    if (category.equals(NumberUp.class)
470
        && printerAttr.containsKey(NumberUpDefault.class))
471
      return getPrinterDefaultAttribute(NumberUpDefault.class);
472
    if (category.equals(OrientationRequested.class)
473
        && printerAttr.containsKey(OrientationRequestedDefault.class))
474
      return getPrinterDefaultAttribute(OrientationRequestedDefault.class);
475
    if (category.equals(Media.class)
476
        && printerAttr.containsKey(MediaDefault.class))
477
      return getPrinterDefaultAttribute(MediaDefault.class);
478
    if (category.equals(PrinterResolution.class)
479
        && printerAttr.containsKey(PrinterResolutionDefault.class))
480
      return getPrinterDefaultAttribute(PrinterResolutionDefault.class);
481
    if (category.equals(PrintQuality.class)
482
        && printerAttr.containsKey(PrintQualityDefault.class))
483
      return getPrinterDefaultAttribute(PrintQualityDefault.class);
484
    if (category.equals(Compression.class)
485
        && printerAttr.containsKey(CompressionSupported.class))
486
      return Compression.NONE;
487
    if (category.equals(PageRanges.class))
488
      return new PageRanges(1, Integer.MAX_VALUE);
489
 
490
    return null;
491
  }
492
 
493
  /**
494
   * We return the value of <code>PrinterName</code> here.
495
   * @see javax.print.PrintService#getName()
496
   */
497
  public String getName()
498
  {
499
    return name;
500
  }
501
 
502
  /**
503
   * We currently provide no factories - just returns null.
504
   * @see javax.print.PrintService#getServiceUIFactory()
505
   */
506
  public ServiceUIFactory getServiceUIFactory()
507
  {
508
    // SUN does not provide any service factory for
509
    // print services (tested on linux/windows)
510
 
511
    // for the moment we do the same - just return null
512
    // later on we could provide at least the about UI dialog
513
    return null;
514
  }
515
 
516
  /**
517
   * @see javax.print.PrintService#getSupportedAttributeCategories()
518
   */
519
  public Class<?>[] getSupportedAttributeCategories()
520
  {
521
    Set<Class<? extends Attribute>> categories =
522
      new HashSet<Class<? extends Attribute>>();
523
 
524
    // Should only be job template attributes as of section 4.2
525
    if (printerAttr.containsKey(JobPrioritySupported.class))
526
      categories.add(JobPriority.class);
527
    if (printerAttr.containsKey(JobHoldUntilSupported.class))
528
      categories.add(JobHoldUntil.class);
529
    if (printerAttr.containsKey(JobSheetsSupported.class))
530
      categories.add(JobSheets.class);
531
    if (printerAttr.containsKey(MultipleDocumentHandlingSupported.class))
532
      categories.add(MultipleDocumentHandling.class);
533
    if (printerAttr.containsKey(CopiesSupported.class))
534
      categories.add(Copies.class);
535
    if (printerAttr.containsKey(FinishingsSupported.class))
536
      {
537
        // if only none finishing is supported - it does not count as supported
538
        Set<FinishingsSupported> set = getPrinterAttributeSet(FinishingsSupported.class);
539
        if (! (set.size() == 1 && set.contains(FinishingsSupported.NONE)))
540
          categories.add(Finishings.class);
541
      }
542
    if (printerAttr.containsKey(PageRangesSupported.class))
543
      categories.add(PageRanges.class);
544
    if (printerAttr.containsKey(SidesSupported.class))
545
      categories.add(Sides.class);
546
    if (printerAttr.containsKey(NumberUpSupported.class))
547
      categories.add(NumberUp.class);
548
    if (printerAttr.containsKey(OrientationRequestedSupported.class))
549
      categories.add(OrientationRequested.class);
550
    if (printerAttr.containsKey(MediaSupported.class))
551
      categories.add(Media.class);
552
    if (printerAttr.containsKey(PrinterResolutionSupported.class))
553
      categories.add(PrinterResolution.class);
554
    if (printerAttr.containsKey(PrintQualitySupported.class))
555
      categories.add(PrintQuality.class);
556
 
557
    // Chromaticity, Destination, MediaPrintableArea,
558
    // SheetCollate, PresentationDirection - not IPP attributes
559
 
560
    // attributes outside section 4.2
561
    if (printerAttr.containsKey(CompressionSupported.class))
562
      categories.add(Compression.class);
563
    if (printerAttr.containsKey(JobImpressionsSupported.class))
564
      categories.add(JobImpressions.class);
565
    if (printerAttr.containsKey(JobKOctetsSupported.class))
566
      categories.add(JobKOctets.class);
567
    if (printerAttr.containsKey(JobMediaSheetsSupported.class))
568
      categories.add(JobMediaSheets.class);
569
 
570
    // always supported as required by IPP specification
571
    categories.add(Fidelity.class);
572
    categories.add(JobName.class);
573
    categories.add(RequestingUserName.class);
574
 
575
    return categories.toArray(new Class[categories.size()]);
576
  }
577
 
578
  /**
579
   * Implemented by a GetPrinterAttributes request. Subclasses providing supported
580
   * attribute values totally different may override this methods. Subclass only in
581
   * need of handling the response differently may override the method
582
   * <code>handleSupportedAttributeValuesResponse(IppResponse, Class)</code> only.
583
   *
584
   * @see PrintService#getSupportedAttributeValues(Class, DocFlavor, AttributeSet)
585
   * @see #handleSupportedAttributeValuesResponse(IppResponse, Class)
586
   */
587
  public Object getSupportedAttributeValues(Class<? extends Attribute> category,
588
                                            DocFlavor flavor, AttributeSet attributes)
589
  {
590
    // We currently ignore the attribute set - there is nothing in the IPP
591
    // specification which would come closer to what we do here.
592
 
593
    if (category == null)
594
      throw new NullPointerException("category may not be null");
595
 
596
    if (!Attribute.class.isAssignableFrom(category))
597
      throw new IllegalArgumentException("category must be of type Attribute");
598
 
599
    if (flavor != null && !isDocFlavorSupported(flavor))
600
      throw new IllegalArgumentException("flavor is not supported");
601
 
602
    if (!isAttributeCategorySupported(category))
603
      return null;
604
 
605
    // always supported
606
    if (category.equals(Fidelity.class))
607
      return new Fidelity[] { Fidelity.FIDELITY_FALSE, Fidelity.FIDELITY_TRUE };
608
    if (category.equals(JobName.class))
609
      return JOB_NAME;
610
    if (category.equals(RequestingUserName.class))
611
      return REQUESTING_USER_NAME;
612
 
613
    // map category to category-supported
614
    String categoryName = IppUtilities.getSupportedAttrName(category);
615
 
616
    IppResponse response = null;
617
    try
618
      {
619
        IppRequest request = new IppRequest(printerUri.getURI(), user, passwd);
620
        request.setOperationID(
621
          (short) OperationsSupported.GET_PRINTER_ATTRIBUTES.getValue());
622
        request.setOperationAttributeDefaults();
623
        request.addOperationAttribute(new RequestedAttributes(categoryName));
624
        request.addOperationAttribute(printerUri);
625
 
626
        if (flavor != null)
627
          {
628
            DocumentFormat f = DocumentFormat.createDocumentFormat(flavor);
629
            request.addOperationAttribute(f);
630
          }
631
 
632
        response = request.send();
633
 
634
        int status = response.getStatusCode();
635
        if (! (status == IppStatusCode.SUCCESSFUL_OK
636
             || status == IppStatusCode.SUCCESSFUL_OK_IGNORED_OR_SUBSTITUED_ATTRIBUTES
637
             || status == IppStatusCode.SUCCESSFUL_OK_CONFLICTING_ATTRIBUTES) )
638
          {
639
            logger.log(Component.IPP, "Statuscode not OK - got:" + status);
640
          }
641
      }
642
    catch (IOException e)
643
      {
644
        // method cannot throw exception - just log
645
        logger.log(Component.IPP, "IOException", e);
646
      }
647
    catch (IppException e)
648
      {
649
        // method cannot throw exception - just log
650
        logger.log(Component.IPP, "IPPException", e);
651
      }
652
 
653
    return handleSupportedAttributeValuesResponse(response, category);
654
  }
655
 
656
  /**
657
   * Called to handle the supported attribute values response for the given
658
   * category. This might be overridden by subclasses with different requirements
659
   * for parsing/handling the response from the GetPrinterAttributes.
660
   *
661
   * @param response the response of the GetPrinterAttributes IPP request
662
   * @param category the category for which the supported values are requested
663
   * @return A object indicating the supported values for the given attribute
664
   * category, or <code>null</code> if this print service doesn't support the
665
   * given attribute category at all.
666
   *
667
   * @see #getSupportedAttributeValues(Class, DocFlavor, AttributeSet)
668
   */
669
  protected Object handleSupportedAttributeValuesResponse(IppResponse response,
670
                                                          Class<? extends Attribute> category)
671
  {
672
    List<Map<Class<? extends Attribute>, Set<Attribute>>> printerAtts =
673
      response.getPrinterAttributes();
674
 
675
    // only one will be returned
676
    Map<Class<? extends Attribute>, Set<Attribute>> printerAttribute = printerAtts.get(0);
677
    Class<? extends Attribute> suppCategory = IppUtilities.getSupportedCategory(category);
678
    Set<Attribute> attr = printerAttribute.get(suppCategory);
679
 
680
    // We sometime assume its a single instance with arbritrary value just indicating
681
    // support or an array which is returned. This is because I sometimes just choosed
682
    // what sounds right to me - as I have yet to find a printer which supports every
683
    // special category in the SUN implementation to see what they return :-)
684
 
685
    //  Map whats in the JSP API
686
    if (suppCategory.equals(JobPrioritySupported.class))
687
      return (JobPrioritySupported) attr.iterator().next();
688
    if (suppCategory.equals(JobHoldUntilSupported.class))
689
      return new JobHoldUntil(new Date());
690
    if (suppCategory.equals(JobSheetsSupported.class))
691
      return JobSheetsSupported.getAssociatedAttributeArray(attr);
692
    if (suppCategory.equals(MultipleDocumentHandlingSupported.class))
693
      return MultipleDocumentHandlingSupported.getAssociatedAttributeArray(attr);
694
    if (suppCategory.equals(CopiesSupported.class))
695
      return (CopiesSupported) attr.iterator().next();
696
    if (suppCategory.equals(FinishingsSupported.class))
697
      return FinishingsSupported.getAssociatedAttributeArray(attr);
698
    if (suppCategory.equals(PageRangesSupported.class))
699
      return new PageRanges[] { new PageRanges(1, Integer.MAX_VALUE) };
700
    if (suppCategory.equals(OrientationRequestedSupported.class))
701
      return OrientationRequestedSupported.getAssociatedAttributeArray(attr);
702
    if (suppCategory.equals(MediaSupported.class))
703
      return MediaSupported.getAssociatedAttributeArray(attr);
704
    if (suppCategory.equals(PrinterResolutionSupported.class))
705
      return PrinterResolutionSupported.getAssociatedAttributeArray(attr);
706
    if (suppCategory.equals(PrintQualitySupported.class))
707
      return PrintQualitySupported.getAssociatedAttributeArray(attr);
708
    if (suppCategory.equals(CompressionSupported.class))
709
      return CompressionSupported.getAssociatedAttributeArray(attr);
710
    // Special handling as it might also be in range of integers
711
    if (suppCategory.equals(NumberUpSupported.class))
712
      {
713
        if (attr.size() == 1) // number-up maybe in rangeofintegers
714
          return attr.iterator().next();
715
 
716
        int[][] members = new int[attr.size()][2];
717
        Iterator<Attribute> it = attr.iterator();
718
        for (int j = 0; j < attr.size(); j++)
719
          {
720
            int value = ((NumberUpSupported) it.next()).getMembers()[0][0];
721
            members[j] = new int[] { value, value };
722
          }
723
 
724
        NumberUpSupported supported = new NumberUpSupported(members);
725
        return supported;
726
      }
727
 
728
    return null;
729
  }
730
 
731
  /**
732
   * @see javax.print.PrintService#getSupportedDocFlavors()
733
   */
734
  public DocFlavor[] getSupportedDocFlavors()
735
  {
736
    return flavors.toArray(new DocFlavor[flavors.size()]);
737
  }
738
 
739
  /**
740
   * This is done by a validate-job operation and actually implemented in
741
   * this generic IPP reference implementation. Subclasses which does
742
   * not correctly support Validate-Job operation might want to override this.
743
   *
744
   * @see PrintService#getUnsupportedAttributes(DocFlavor, AttributeSet)
745
   */
746
  public AttributeSet getUnsupportedAttributes(DocFlavor flavor,
747
                                               AttributeSet attributes)
748
  {
749
    if (flavor != null && !isDocFlavorSupported(flavor))
750
      throw new IllegalArgumentException("flavor is not supported");
751
 
752
    IppResponse response = null;
753
    try
754
      {
755
        IppRequest request = new IppRequest(printerUri.getURI(), user, passwd);
756
        short operationId = (short) OperationsSupported.VALIDATE_JOB.getValue();
757
        request.setOperationID(operationId);
758
        request.setOperationAttributeDefaults();
759
        request.addOperationAttribute(printerUri);
760
        request.addOperationAttribute(Fidelity.FIDELITY_TRUE);
761
 
762
        if (attributes != null && attributes.size() > 0)
763
          {
764
            request.addAndFilterJobOperationAttributes(attributes);
765
            request.addAndFilterJobTemplateAttributes(attributes);
766
          }
767
 
768
        if (flavor != null)
769
          {
770
            DocumentFormat f = DocumentFormat.createDocumentFormat(flavor);
771
            request.addOperationAttribute(f);
772
          }
773
 
774
        response = request.send();
775
 
776
        int status = response.getStatusCode();
777
        if (! (status == IppStatusCode.SUCCESSFUL_OK
778
             || status == IppStatusCode.SUCCESSFUL_OK_IGNORED_OR_SUBSTITUED_ATTRIBUTES
779
             || status == IppStatusCode.SUCCESSFUL_OK_CONFLICTING_ATTRIBUTES) )
780
          {
781
            logger.log(Component.IPP, "Statuscode not OK - got:" + status);
782
          }
783
      }
784
    catch (IOException e)
785
      {
786
        // method cannot throw exception - just log
787
        logger.log(Component.IPP, "IOException", e);
788
      }
789
    catch (IppException e)
790
      {
791
        // method cannot throw exception - just log
792
        logger.log(Component.IPP, "IPPException", e);
793
      }
794
 
795
    // Validate Jobs returns only Unsupported and Operation
796
    List<Map<Class<? extends Attribute>, Set<Attribute>>> unsupportedMaps =
797
      response.getUnsupportedAttributes();
798
    if (unsupportedMaps.size() == 0)
799
      return null;
800
 
801
    Map<Class<? extends Attribute>, Set<Attribute>> unsupportedAttr = unsupportedMaps.get(0);
802
    if (unsupportedAttr.size() == 0)
803
      return null;
804
 
805
    // Convert the return map with unsupported attributes
806
    // into an AttribueSet instance
807
    HashAttributeSet set = new HashAttributeSet();
808
    for (Set<Attribute> unsupported : unsupportedAttr.values())
809
      {
810
        for (Attribute att : unsupported)
811
          set.add(att);
812
      }
813
 
814
    return set;
815
  }
816
 
817
  /**
818
   * @see PrintService#isAttributeCategorySupported(Class)
819
   */
820
  public boolean isAttributeCategorySupported(Class<? extends Attribute> category)
821
  {
822
    if (category == null)
823
      throw new NullPointerException("category may not be null");
824
 
825
    if (! Attribute.class.isAssignableFrom(category))
826
      throw new IllegalArgumentException("category must be of type Attribute");
827
 
828
    return Arrays.asList(getSupportedAttributeCategories()).contains(category);
829
  }
830
 
831
  /**
832
   * @see PrintService#isAttributeValueSupported(Attribute, DocFlavor, AttributeSet)
833
   */
834
  public boolean isAttributeValueSupported(Attribute attrval, DocFlavor flavor,
835
                                           AttributeSet attributes)
836
  {
837
    // just redirect to getSupportedAttributeValues
838
    Object values = getSupportedAttributeValues(attrval.getCategory(),
839
                                                flavor, attributes);
840
    // null means none supported
841
    if (values == null)
842
      return false;
843
 
844
    // object may be an array
845
    if (values.getClass().isArray())
846
      return Arrays.asList((Object[]) values).contains(attrval);
847
 
848
    // may be a single instance of the category (value is irrelevant)
849
    if (values.getClass().equals(attrval.getCategory()))
850
      return true;
851
 
852
    // a single instance of another class to give the bounds
853
    // copies
854
    if (values.getClass().equals(CopiesSupported.class))
855
      return ((CopiesSupported) values).contains((IntegerSyntax) attrval);
856
    // number up
857
    if (values.getClass().equals(NumberUpSupported.class))
858
      return ((NumberUpSupported) values).contains((IntegerSyntax) attrval);
859
    // job priority
860
    if (values.getClass().equals(JobPrioritySupported.class))
861
      {
862
        JobPriority priority = (JobPriority) attrval;
863
        JobPrioritySupported maxSupported = (JobPrioritySupported) values;
864
        if (priority.getValue() < maxSupported.getValue())
865
          return true;
866
      }
867
 
868
    // I am unsure if these might also show up - not yet found a printer where
869
    // Suns implementation supports them:
870
    // JobImpressionsSupported, JobKOctetsSupported, JobMediaSheetsSupported
871
 
872
    return false;
873
  }
874
 
875
 
876
  /**
877
   * @see javax.print.PrintService#isDocFlavorSupported(DocFlavor)
878
   */
879
  public boolean isDocFlavorSupported(DocFlavor flavor)
880
  {
881
    if (flavor == null)
882
      throw new NullPointerException("DocFlavor may not be null.");
883
 
884
    return flavors.contains(flavor);
885
  }
886
 
887
 
888
  /**
889
   * @see PrintService#addPrintServiceAttributeListener(PrintServiceAttributeListener)
890
   */
891
  public void addPrintServiceAttributeListener(
892
    PrintServiceAttributeListener listener)
893
  {
894
    printServiceAttributeListener.add(listener);
895
  }
896
 
897
  /**
898
   * @see PrintService#removePrintServiceAttributeListener(PrintServiceAttributeListener)
899
   */
900
  public void removePrintServiceAttributeListener(
901
    PrintServiceAttributeListener listener)
902
  {
903
    printServiceAttributeListener.remove(listener);
904
  }
905
 
906
  /**
907
   * Returns "IppPrinter: " + <code>getName()</code>
908
   * @return The string representation.
909
   */
910
  public String toString()
911
  {
912
    return "IppPrinter: " + getName();
913
  }
914
 
915
  /**
916
   * Returns the printer-uri of this print service.
917
   *
918
   * @return The printer-uri attribute.
919
   */
920
  public PrinterURI getPrinterURI()
921
  {
922
    return printerUri;
923
  }
924
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.