OSDN Git Service

Imported GNU Classpath 0.90
[pf3gnuchains/gcc-fork.git] / libjava / classpath / gnu / javax / print / ipp / IppUtilities.java
1 /* IppUtilities.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.javax.print.ipp.attribute.DetailedStatusMessage;
42 import gnu.javax.print.ipp.attribute.DocumentAccessError;
43 import gnu.javax.print.ipp.attribute.StatusMessage;
44 import gnu.javax.print.ipp.attribute.defaults.CopiesDefault;
45 import gnu.javax.print.ipp.attribute.defaults.FinishingsDefault;
46 import gnu.javax.print.ipp.attribute.defaults.JobHoldUntilDefault;
47 import gnu.javax.print.ipp.attribute.defaults.JobPriorityDefault;
48 import gnu.javax.print.ipp.attribute.defaults.JobSheetsDefault;
49 import gnu.javax.print.ipp.attribute.defaults.MediaDefault;
50 import gnu.javax.print.ipp.attribute.defaults.MultipleDocumentHandlingDefault;
51 import gnu.javax.print.ipp.attribute.defaults.NumberUpDefault;
52 import gnu.javax.print.ipp.attribute.defaults.OrientationRequestedDefault;
53 import gnu.javax.print.ipp.attribute.defaults.PrintQualityDefault;
54 import gnu.javax.print.ipp.attribute.defaults.SidesDefault;
55 import gnu.javax.print.ipp.attribute.job.JobDetailedStatusMessages;
56 import gnu.javax.print.ipp.attribute.job.JobDocumentAccessErrors;
57 import gnu.javax.print.ipp.attribute.job.JobId;
58 import gnu.javax.print.ipp.attribute.job.JobStateMessage;
59 import gnu.javax.print.ipp.attribute.printer.MultipleOperationTimeOut;
60 import gnu.javax.print.ipp.attribute.printer.PrinterStateMessage;
61 import gnu.javax.print.ipp.attribute.printer.PrinterUpTime;
62 import gnu.javax.print.ipp.attribute.supported.CompressionSupported;
63 import gnu.javax.print.ipp.attribute.supported.FinishingsSupported;
64 import gnu.javax.print.ipp.attribute.supported.IppVersionsSupported;
65 import gnu.javax.print.ipp.attribute.supported.JobHoldUntilSupported;
66 import gnu.javax.print.ipp.attribute.supported.JobSheetsSupported;
67 import gnu.javax.print.ipp.attribute.supported.MediaSupported;
68 import gnu.javax.print.ipp.attribute.supported.MultipleDocumentHandlingSupported;
69 import gnu.javax.print.ipp.attribute.supported.MultipleDocumentJobsSupported;
70 import gnu.javax.print.ipp.attribute.supported.OperationsSupported;
71 import gnu.javax.print.ipp.attribute.supported.OrientationRequestedSupported;
72 import gnu.javax.print.ipp.attribute.supported.PageRangesSupported;
73 import gnu.javax.print.ipp.attribute.supported.PrintQualitySupported;
74 import gnu.javax.print.ipp.attribute.supported.PrinterResolutionSupported;
75 import gnu.javax.print.ipp.attribute.supported.SidesSupported;
76 import gnu.javax.print.ipp.attribute.supported.UriAuthenticationSupported;
77 import gnu.javax.print.ipp.attribute.supported.UriSecuritySupported;
78
79 import java.lang.reflect.Constructor;
80 import java.lang.reflect.Field;
81 import java.lang.reflect.InvocationTargetException;
82 import java.util.HashMap;
83 import java.util.Locale;
84
85 import javax.print.attribute.Attribute;
86 import javax.print.attribute.EnumSyntax;
87 import javax.print.attribute.SupportedValuesAttribute;
88 import javax.print.attribute.standard.Chromaticity;
89 import javax.print.attribute.standard.ColorSupported;
90 import javax.print.attribute.standard.Compression;
91 import javax.print.attribute.standard.Copies;
92 import javax.print.attribute.standard.CopiesSupported;
93 import javax.print.attribute.standard.Fidelity;
94 import javax.print.attribute.standard.Finishings;
95 import javax.print.attribute.standard.JobHoldUntil;
96 import javax.print.attribute.standard.JobImpressionsCompleted;
97 import javax.print.attribute.standard.JobKOctetsProcessed;
98 import javax.print.attribute.standard.JobMediaSheetsCompleted;
99 import javax.print.attribute.standard.JobMessageFromOperator;
100 import javax.print.attribute.standard.JobName;
101 import javax.print.attribute.standard.JobOriginatingUserName;
102 import javax.print.attribute.standard.JobPriority;
103 import javax.print.attribute.standard.JobPrioritySupported;
104 import javax.print.attribute.standard.JobSheets;
105 import javax.print.attribute.standard.JobState;
106 import javax.print.attribute.standard.JobStateReason;
107 import javax.print.attribute.standard.Media;
108 import javax.print.attribute.standard.MediaSizeName;
109 import javax.print.attribute.standard.MultipleDocumentHandling;
110 import javax.print.attribute.standard.NumberOfInterveningJobs;
111 import javax.print.attribute.standard.NumberUp;
112 import javax.print.attribute.standard.NumberUpSupported;
113 import javax.print.attribute.standard.OrientationRequested;
114 import javax.print.attribute.standard.OutputDeviceAssigned;
115 import javax.print.attribute.standard.PDLOverrideSupported;
116 import javax.print.attribute.standard.PageRanges;
117 import javax.print.attribute.standard.PagesPerMinute;
118 import javax.print.attribute.standard.PagesPerMinuteColor;
119 import javax.print.attribute.standard.PresentationDirection;
120 import javax.print.attribute.standard.PrintQuality;
121 import javax.print.attribute.standard.PrinterInfo;
122 import javax.print.attribute.standard.PrinterIsAcceptingJobs;
123 import javax.print.attribute.standard.PrinterLocation;
124 import javax.print.attribute.standard.PrinterMakeAndModel;
125 import javax.print.attribute.standard.PrinterMessageFromOperator;
126 import javax.print.attribute.standard.PrinterName;
127 import javax.print.attribute.standard.PrinterResolution;
128 import javax.print.attribute.standard.PrinterState;
129 import javax.print.attribute.standard.PrinterStateReason;
130 import javax.print.attribute.standard.QueuedJobCount;
131 import javax.print.attribute.standard.ReferenceUriSchemesSupported;
132 import javax.print.attribute.standard.Severity;
133 import javax.print.attribute.standard.SheetCollate;
134 import javax.print.attribute.standard.Sides;
135
136 /**
137  * Collection of static utilities methods used in
138  * IPP response parsing and all over the place.
139  * <p>
140  * Also provides mapping from the attribute name values to
141  * the actual class object. Used to construct objects via reflection.
142  * </p>
143  * 
144  * @author Wolfgang Baer (WBaer@gmx.de)
145  */
146 public final class IppUtilities
147 {
148   // These are reused in the reflection code to not instantiate an array everytime
149   private static Object[] INTEGER_ATT_VALUE = new Object[1];
150   private static Class[] INTEGER_CLASS_ARRAY = new Class[] {int.class};
151   private static Object[] TEXT_ATT_VALUE = new Object[2];
152   private static Class[] TEXT_CLASS_ARRAY = new Class[] {String.class, Locale.class};
153   
154   // The map -> Attribute name to Attribute class
155   private static HashMap classesByName = new HashMap();
156   // The map -> StandardAttribute class to SupportedAttribute category name
157   private static HashMap instanceByClass = new HashMap();
158
159   /**
160    * All the currently needed attributes
161    */
162   static
163     {
164       // enums      
165       classesByName.put(JobState.ABORTED.getName(), JobState.class);
166       classesByName.put(Sides.DUPLEX.getName(), Sides.class);
167       classesByName.put(SheetCollate.COLLATED.getName(), SheetCollate.class);
168       classesByName.put(Severity.ERROR.getName(), Severity.class);
169       classesByName.put(JobSheets.NONE.getName(), JobSheets.class);
170       classesByName.put(Finishings.BIND.getName(), Finishings.class);
171       classesByName.put(Fidelity.FIDELITY_FALSE.getName(), Fidelity.class);
172       classesByName.put(Compression.GZIP.getName(), Compression.class);
173       classesByName.put(Chromaticity.COLOR.getName(), Chromaticity.class);
174       classesByName.put(PrintQuality.DRAFT.getName(), PrintQuality.class);
175       classesByName.put(PrinterState.IDLE.getName(), PrinterState.class);
176       classesByName.put(SidesDefault.ONE_SIDED.getName(), SidesDefault.class);
177       classesByName.put(ReferenceUriSchemesSupported.FILE.getName(), 
178                         ReferenceUriSchemesSupported.class);           
179       classesByName.put(PrinterStateReason.DOOR_OPEN.getName(),
180                         PrinterStateReason.class);            
181       classesByName.put(PresentationDirection.TOLEFT_TOTOP.getName(), 
182                         PresentationDirection.class);
183       classesByName.put(PDLOverrideSupported.ATTEMPTED.getName(), 
184                         PDLOverrideSupported.class);
185       classesByName.put(OrientationRequested.PORTRAIT.getName(), 
186                         OrientationRequested.class);
187       classesByName.put(MultipleDocumentHandling.SINGLE_DOCUMENT.getName(), 
188                         MultipleDocumentHandling.class);
189       classesByName.put(JobStateReason.JOB_QUEUED.getName(), 
190                         JobStateReason.class);
191       classesByName.put(UriAuthenticationSupported.NONE.getName(), 
192                         UriAuthenticationSupported.class);      
193       classesByName.put(OperationsSupported.GET_JOBS.getName(), 
194                         OperationsSupported.class);      
195       classesByName.put(UriSecuritySupported.NONE.getName(), 
196                         UriSecuritySupported.class);          
197       classesByName.put(FinishingsSupported.NONE.getName(), 
198                         FinishingsSupported.class);      
199       classesByName.put(FinishingsDefault.NONE.getName(), 
200                         FinishingsDefault.class);      
201       classesByName.put(IppVersionsSupported.V_1_0.getName(), 
202                         IppVersionsSupported.class);      
203       classesByName.put(MultipleDocumentHandlingSupported.SINGLE_DOCUMENT.getName(), 
204                         MultipleDocumentHandlingSupported.class);      
205       classesByName.put(MultipleDocumentHandlingDefault.SINGLE_DOCUMENT.getName(), 
206                         MultipleDocumentHandlingDefault.class);      
207       classesByName.put(CompressionSupported.NONE.getName(), 
208                         CompressionSupported.class);      
209       classesByName.put(OrientationRequestedSupported.PORTRAIT.getName(), 
210                         OrientationRequestedSupported.class);      
211       classesByName.put(OrientationRequestedDefault.PORTRAIT.getName(), 
212                         OrientationRequestedDefault.class);        
213       classesByName.put(SidesSupported.ONE_SIDED.getName(), 
214                         SidesSupported.class);     
215       classesByName.put(PrintQualityDefault.DRAFT.getName(), 
216                         PrintQualityDefault.class);      
217       classesByName.put(PrintQualitySupported.DRAFT.getName(), 
218                         PrintQualitySupported.class);      
219       classesByName.put(ReferenceUriSchemesSupported.FTP.getName(), 
220                         ReferenceUriSchemesSupported.class);
221       
222       // the boolean types 
223       classesByName.put(ColorSupported.SUPPORTED.getName(), ColorSupported.class);      
224       classesByName.put(PrinterIsAcceptingJobs.ACCEPTING_JOBS.getName(), 
225                         PrinterIsAcceptingJobs.class);
226       classesByName.put(MultipleDocumentJobsSupported.SUPPORTED.getName(), 
227                         MultipleDocumentJobsSupported.class);
228       classesByName.put(PageRangesSupported.SUPPORTED.getName(), 
229                         PageRangesSupported.class);
230                  
231       // TextSyntax derived attributes
232       classesByName.put("media-default", MediaDefault.class); 
233       classesByName.put("media-supported", MediaSupported.class);
234       classesByName.put("media", MediaSizeName.class); 
235       classesByName.put("printer-location", PrinterLocation.class); 
236       classesByName.put("printer-info", PrinterInfo.class); 
237       classesByName.put("printer-make-and-model", PrinterMakeAndModel.class); 
238       classesByName.put("printer-state-message", PrinterStateMessage.class);
239       classesByName.put("job-state-message", JobStateMessage.class);         
240       classesByName.put("job-sheets-default", JobSheetsDefault.class); 
241       classesByName.put("job-sheets-supported", JobSheetsSupported.class); 
242       classesByName.put("job-name", JobName.class); 
243       classesByName.put("printer-name", PrinterName.class); 
244       classesByName.put("status-message", StatusMessage.class); 
245       classesByName.put("detailed-status-message", DetailedStatusMessage.class); 
246       classesByName.put("document-access-error", DocumentAccessError.class); 
247       classesByName.put("output-device-assigned", OutputDeviceAssigned.class); 
248       classesByName.put("job-hold-until-default", JobHoldUntilDefault.class);       
249       classesByName.put("job-originating-user-name", 
250                         JobOriginatingUserName.class); 
251       classesByName.put("job-hold-until-supported", 
252                         JobHoldUntilSupported.class);
253       classesByName.put("job-message-from-operator", 
254                         JobMessageFromOperator.class); 
255       classesByName.put("printer-message-from-operator", 
256                         PrinterMessageFromOperator.class); 
257       classesByName.put("job-detailed-status-messages", 
258                         JobDetailedStatusMessages.class);
259       classesByName.put("job-document-access-errors", 
260                         JobDocumentAccessErrors.class);    
261       
262       // IntegerSyntax derived Attributes
263       classesByName.put("copies-default", CopiesDefault.class); 
264       classesByName.put("job-id", JobId.class); 
265       classesByName.put("job-priority-supported", JobPrioritySupported.class);
266       classesByName.put("job-priority-default", JobPriorityDefault.class);
267       classesByName.put("number-up-supported", NumberUpSupported.class);
268       classesByName.put("number-up-default", NumberUpDefault.class);
269       classesByName.put("queued-job-count", QueuedJobCount.class);
270       classesByName.put("printer-up-time", PrinterUpTime.class);      
271       classesByName.put("pages-per-minute", PagesPerMinute.class);
272       classesByName.put("pages-per-minute-color", PagesPerMinuteColor.class);       
273       classesByName.put("job-k-octets-processed", JobKOctetsProcessed.class);
274       classesByName.put("number-of-intervening-jobs", 
275                         NumberOfInterveningJobs.class);
276       classesByName.put("job-impressions-completed", 
277                         JobImpressionsCompleted.class); 
278       classesByName.put("job-media-sheets-completed", 
279                         JobMediaSheetsCompleted.class);
280       classesByName.put("multiple-operation-time-out", 
281                         MultipleOperationTimeOut.class);
282       
283       
284       // 4.2 job template attributes
285       instanceByClass.put(JobPriority.class, new JobPrioritySupported(1));
286       instanceByClass.put(JobHoldUntil.class, new JobHoldUntilSupported("", null));
287       instanceByClass.put(JobSheets.class, new JobSheetsSupported("", null));
288       instanceByClass.put(MultipleDocumentHandling.class, MultipleDocumentHandlingSupported.SINGLE_DOCUMENT);
289       instanceByClass.put(Copies.class, new CopiesSupported(1));
290       instanceByClass.put(Finishings.class, FinishingsSupported.BIND);
291       instanceByClass.put(PageRanges.class, PageRangesSupported.SUPPORTED);
292       instanceByClass.put(Sides.class, SidesSupported.DUPLEX);
293       instanceByClass.put(NumberUp.class, new NumberUpSupported(1));
294       instanceByClass.put(OrientationRequested.class, OrientationRequestedSupported.LANDSCAPE);
295       instanceByClass.put(Media.class, new MediaSupported("", null));
296       instanceByClass.put(PrinterResolution.class, new PrinterResolutionSupported(1,1,1));
297       instanceByClass.put(PrintQuality.class, PrintQualitySupported.DRAFT);
298
299       // 4.4 printer attributes
300       instanceByClass.put(Compression.class, CompressionSupported.COMPRESS);
301     }
302   
303   private IppUtilities()
304   {
305     // not to be instantiated
306   }
307
308   /**
309    * Returns the implementing class object for given
310    * attribute name objects.
311    * 
312    * @param name the attribute name
313    * @return The <code>Class</code> object.
314    */
315   public static Class getClass(String name)
316   {
317     return (Class) classesByName.get(name);
318   }
319   
320   /**
321    * Returns the name of the supported attribute 
322    * based on the given standard attribute category.
323    * 
324    * @param clazz the standard attribute category
325    * @return The name of the supported attribute category.
326    */
327   public static String getSupportedAttrName(Class clazz)
328   {
329     return ((SupportedValuesAttribute) instanceByClass.get(clazz)).getName();
330   }
331   
332   /**
333    * Returns the category of the supported attribute 
334    * based on the given standard attribute category.
335    * 
336    * @param clazz the standard attribute category
337    * @return The supported attribute category.
338    */
339   public static Class getSupportedCategory(Class clazz)
340   {
341     return ((SupportedValuesAttribute) instanceByClass.get(clazz)).getCategory();
342   }  
343
344   /**
345    * Helper method to convert to an int.
346    * @param b the byte array
347    * @return The converted int.
348    */
349   public static int convertToInt(byte[] b)
350   {
351     return (((b[0] & 0xff) << 24) | ((b[1] & 0xff) << 16)
352             | ((b[2] & 0xff) << 8) | (b[3] & 0xff));
353   }
354   
355   /**
356    * Helper method to convert to an int.
357    * @param b1 the 1th byte
358    * @param b2 the 2th byte
359    * @param b3 the 3th byte
360    * @param b4 the 4th byte
361    * @return The converted int.
362    */
363   public static int convertToInt(byte b1, byte b2, byte b3, byte b4)
364   {
365     return (((b1 & 0xff) << 24) | ((b2 & 0xff) << 16)
366             | ((b3 & 0xff) << 8) | (b4 & 0xff));
367   }
368
369   /**
370    * Helper method to convert to a short.
371    * @param b1 the 1th byte
372    * @param b2 the 2th byte
373    * @return The converted short.
374    */
375   public static short convertToShort(byte b1, byte b2)
376   {
377     return (short) ((b1 << 8) | (b2 & 0xff));
378   }
379   
380   /**
381    * Instantiates an <code>EnumSyntax</code> based attribute with the given IPP
382    * name and the given value (Enums maybe int or String based).
383    * 
384    * @param name the attribute name of the subclass.
385    * @param value the integer value of the specific enum.
386    * @return The Attribute (a subclass of EnumSyntax)
387    */
388   public static Attribute getEnumAttribute(String name, Object value)
389   {
390     Class attrClass = getClass(name);
391     
392     // There might be unknown enums we have no mapped class for
393     if (attrClass ==  null)
394       return null;    
395
396     try
397       {
398         Field[] fields = attrClass.getDeclaredFields();
399         for (int i = 0; i < fields.length; i++)
400           {
401             Field field = fields[i];
402             if (field.getType().equals(attrClass))
403               {
404                 EnumSyntax attr = (EnumSyntax) field.get(null);
405                 if (value instanceof Integer
406                     && attr.getValue() == ((Integer) value).intValue())
407                   return (Attribute) attr;
408                 else if (value instanceof String
409                          && attr.toString().equals(value))
410                   return (Attribute) attr;
411               }
412           }
413       }
414     catch (SecurityException e)
415       {
416         // should not happen
417       }
418     catch (IllegalArgumentException e)
419       {
420         // should not happen
421       }
422     catch (IllegalAccessException e)
423       {
424         // should not happen, all fields are public
425       }
426     
427     return null;
428   }
429   
430   
431   
432   /**
433    * Instantiates an <code>IntegerSyntax</code> based attribute with the 
434    * given IPP name for the given int value.
435    * 
436    * @param name the attribute name of the subclass.
437    * @param value the integer value
438    * @return The Attribute (a subclass of IntegerSyntax)
439    */
440   public static Attribute getIntegerAttribute(String name, int value)
441   {    
442     Class attrClass = getClass(name);
443     
444     // There might be unknown attributes we have no mapped class for
445     if (attrClass ==  null)
446       return null;
447
448     try
449       {
450         INTEGER_ATT_VALUE[0] = new Integer(value);
451         Constructor c = attrClass.getDeclaredConstructor(INTEGER_CLASS_ARRAY);       
452         return (Attribute) c.newInstance(INTEGER_ATT_VALUE);         
453       }
454     catch (SecurityException e)
455       {
456         // should not happen
457       }
458     catch (NoSuchMethodException e)
459       {
460         // should not happen
461       }
462     catch (IllegalAccessException e)
463       {
464         // should not happen, all fields are public
465       }
466     catch (InstantiationException e)
467     {
468       // should not happen, all fields are public
469     }
470     catch (InvocationTargetException e)
471     {
472       // should not happen, all fields are public
473     }
474     
475     return null;
476   }  
477   
478   /**
479    * Instantiates an <code>TextSyntax</code> based attribute with the given
480    * IPP name for the given text value (will be decoded).
481    * 
482    * @param name the attribute name of the subclass.
483    * @param tag the tag defined in {@link IppValueTag}
484    * @param value the byte[] value to be decoded based on the tag value.
485    * @return The Attribute (a subclass of TextSyntax)
486    */
487   public static Attribute getTextAttribute(String name, byte tag, byte[] value)
488   { 
489     // without language tag is rather easy - default locale
490     if (tag == IppValueTag.NAME_WITHOUT_LANGUAGE
491         || tag == IppValueTag.TEXT_WITHOUT_LANGUAGE)
492       {
493         TEXT_ATT_VALUE[0] = new String(value);
494         TEXT_ATT_VALUE[1] = Locale.getDefault();
495       }
496     else
497       {
498         short langLength = convertToShort(value[0], value[1]);
499         byte[] tmp = new byte[langLength];
500         byte[] tmp2 = new byte[value.length - 4 - langLength];
501         System.arraycopy(value, 2, tmp, 0, langLength);
502
503         // parse into language/region
504         String language = new String(tmp);
505         String text = new String(tmp2);
506         Locale locale = null;
507         
508         if (language.length() > 2)
509           locale = new Locale(language.substring(0, 2), language.substring(3));
510         else
511           locale = new Locale(language);
512
513         TEXT_ATT_VALUE[0] = text;
514         TEXT_ATT_VALUE[1] = locale;
515       }    
516     
517     Class attrClass = getClass(name);
518     
519     // There might be unknown attributes we have no mapped class for
520     if (attrClass ==  null)
521       return null;
522
523     try
524       {
525         Constructor c = attrClass.getDeclaredConstructor(TEXT_CLASS_ARRAY);       
526         return (Attribute) c.newInstance(TEXT_ATT_VALUE);         
527       }
528     catch (SecurityException e)
529       {
530         // should not happen
531       }
532     catch (NoSuchMethodException e)
533       {
534         // should not happen
535       }
536     catch (IllegalAccessException e)
537       {
538         // should not happen, all fields are public
539       }
540     catch (InstantiationException e)
541       {
542         // should not happen, all fields are public
543       }
544     catch (InvocationTargetException e)
545       {
546         // should not happen, all fields are public
547       }
548     
549     return null;
550   }
551 }