Source Code Cross Referenced for IPPPrintService.java in  » 6.0-JDK-Platform » solaris » sun » print » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » 6.0 JDK Platform » solaris » sun.print 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright 2003-2007 Sun Microsystems, Inc.  All Rights Reserved.
0003:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004:         *
0005:         * This code is free software; you can redistribute it and/or modify it
0006:         * under the terms of the GNU General Public License version 2 only, as
0007:         * published by the Free Software Foundation.  Sun designates this
0008:         * particular file as subject to the "Classpath" exception as provided
0009:         * by Sun in the LICENSE file that accompanied this code.
0010:         *
0011:         * This code is distributed in the hope that it will be useful, but WITHOUT
0012:         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013:         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
0014:         * version 2 for more details (a copy is included in the LICENSE file that
0015:         * accompanied this code).
0016:         *
0017:         * You should have received a copy of the GNU General Public License version
0018:         * 2 along with this work; if not, write to the Free Software Foundation,
0019:         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020:         *
0021:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022:         * CA 95054 USA or visit www.sun.com if you need additional information or
0023:         * have any questions.
0024:         */
0025:
0026:        package sun.print;
0027:
0028:        import javax.print.attribute.*;
0029:        import javax.print.attribute.standard.*;
0030:        import javax.print.DocFlavor;
0031:        import javax.print.DocPrintJob;
0032:        import javax.print.PrintService;
0033:        import javax.print.ServiceUIFactory;
0034:        import java.util.ArrayList;
0035:        import java.util.HashMap;
0036:        import java.util.Locale;
0037:        import java.util.Date;
0038:        import java.util.Arrays;
0039:        import java.security.AccessController;
0040:        import java.security.PrivilegedActionException;
0041:        import java.security.PrivilegedExceptionAction;
0042:        import javax.print.event.PrintServiceAttributeListener;
0043:
0044:        import java.net.URI;
0045:        import java.net.URISyntaxException;
0046:        import java.net.URL;
0047:        import java.net.HttpURLConnection;
0048:        import java.io.File;
0049:        import java.io.InputStream;
0050:        import java.io.OutputStream;
0051:        import java.io.OutputStreamWriter;
0052:        import java.io.DataInputStream;
0053:        import java.io.ByteArrayOutputStream;
0054:        import java.io.ByteArrayInputStream;
0055:        import java.io.BufferedReader;
0056:        import java.io.InputStreamReader;
0057:        import java.nio.charset.Charset;
0058:
0059:        import java.util.Iterator;
0060:
0061:        public class IPPPrintService implements  PrintService,
0062:                SunPrinterJobService {
0063:
0064:            public static boolean debugPrint = false;
0065:            private static String debugPrefix = "IPPPrintService>> ";
0066:
0067:            protected static void debug_println(String str) {
0068:                if (debugPrint) {
0069:                    System.out.println(str);
0070:                }
0071:            }
0072:
0073:            private String printer;
0074:            private URI myURI;
0075:            private URL myURL;
0076:            transient private ServiceNotifier notifier = null;
0077:
0078:            private static int MAXCOPIES = 1000;
0079:            private static short MAX_ATTRIBUTE_LENGTH = 255;
0080:
0081:            private CUPSPrinter cps;
0082:            private HttpURLConnection urlConnection = null;
0083:            private DocFlavor[] supportedDocFlavors;
0084:            private Class[] supportedCats;
0085:            private MediaTray[] mediaTrays;
0086:            private MediaSizeName[] mediaSizeNames;
0087:            private CustomMediaSizeName[] customMediaSizeNames;
0088:            private int defaultMediaIndex;
0089:            private boolean isCupsPrinter;
0090:            private boolean init;
0091:            private Boolean isPS;
0092:            private HashMap getAttMap;
0093:            private boolean pngImagesAdded = false;
0094:            private boolean gifImagesAdded = false;
0095:            private boolean jpgImagesAdded = false;
0096:
0097:            /**
0098:             * IPP Status Codes
0099:             */
0100:            private static final byte STATUSCODE_SUCCESS = 0x00;
0101:
0102:            /**
0103:             * IPP Group Tags.  Each tag is used once before the first attribute
0104:             * of that group.
0105:             */
0106:            // operation attributes group
0107:            private static final byte GRPTAG_OP_ATTRIBUTES = 0x01;
0108:            // job attributes group
0109:            private static final byte GRPTAG_JOB_ATTRIBUTES = 0x02;
0110:            // printer attributes group
0111:            private static final byte GRPTAG_PRINTER_ATTRIBUTES = 0x04;
0112:            // used as the last tag in an IPP message.
0113:            private static final byte GRPTAG_END_ATTRIBUTES = 0x03;
0114:
0115:            /**
0116:             * IPP Operation codes
0117:             */
0118:            // gets the attributes for a printer
0119:            public static final String OP_GET_ATTRIBUTES = "000B";
0120:            // gets the default printer
0121:            public static final String OP_CUPS_GET_DEFAULT = "4001";
0122:            // gets the list of printers
0123:            public static final String OP_CUPS_GET_PRINTERS = "4002";
0124:
0125:            /**
0126:             * List of all PrintRequestAttributes.  This is used
0127:             * for looping through all the IPP attribute name.
0128:             */
0129:            private static Object[] printReqAttribDefault = {
0130:                    Chromaticity.COLOR,
0131:                    new Copies(1),
0132:                    Fidelity.FIDELITY_FALSE,
0133:                    Finishings.NONE,
0134:                    //new JobHoldUntil(new Date()),
0135:                    //new JobImpressions(0),
0136:                    //JobImpressions,
0137:                    //JobKOctets,
0138:                    //JobMediaSheets,
0139:                    new JobName("", Locale.getDefault()),
0140:                    //JobPriority,
0141:                    JobSheets.NONE,
0142:                    (Media) MediaSizeName.NA_LETTER,
0143:                    //MediaPrintableArea.class, // not an IPP attribute
0144:                    //MultipleDocumentHandling.SINGLE_DOCUMENT,
0145:                    new NumberUp(1), OrientationRequested.PORTRAIT,
0146:                    new PageRanges(1),
0147:                    //PresentationDirection,
0148:                    // CUPS does not supply printer-resolution attribute
0149:                    //new PrinterResolution(300, 300, PrinterResolution.DPI), 
0150:                    //PrintQuality.NORMAL, 
0151:                    new RequestingUserName("", Locale.getDefault()),
0152:                    //SheetCollate.UNCOLLATED, //CUPS has no sheet collate?
0153:                    Sides.ONE_SIDED, };
0154:
0155:            /**
0156:             * List of all PrintServiceAttributes.  This is used
0157:             * for looping through all the IPP attribute name.
0158:             */
0159:            private static Object[][] serviceAttributes = {
0160:                    { ColorSupported.class, "color-supported" },
0161:                    { PagesPerMinute.class, "pages-per-minute" },
0162:                    { PagesPerMinuteColor.class, "pages-per-minute-color" },
0163:                    { PDLOverrideSupported.class, "pdl-override-supported" },
0164:                    { PrinterInfo.class, "printer-info" },
0165:                    { PrinterIsAcceptingJobs.class, "printer-is-accepting-jobs" },
0166:                    { PrinterLocation.class, "printer-location" },
0167:                    { PrinterMakeAndModel.class, "printer-make-and-model" },
0168:                    { PrinterMessageFromOperator.class,
0169:                            "printer-message-from-operator" },
0170:                    { PrinterMoreInfo.class, "printer-more-info" },
0171:                    { PrinterMoreInfoManufacturer.class,
0172:                            "printer-more-info-manufacturer" },
0173:                    { PrinterName.class, "printer-name" },
0174:                    { PrinterState.class, "printer-state" },
0175:                    { PrinterStateReasons.class, "printer-state-reasons" },
0176:                    { PrinterURI.class, "printer-uri" },
0177:                    { QueuedJobCount.class, "queued-job-count" } };
0178:
0179:            /**
0180:             * List of DocFlavors, grouped based on matching mime-type.
0181:             * NOTE: For any change in the predefined DocFlavors, it must be reflected
0182:             * here also.
0183:             */
0184:            // PDF DocFlavors
0185:            private static DocFlavor[] appPDF = { DocFlavor.BYTE_ARRAY.PDF,
0186:                    DocFlavor.INPUT_STREAM.PDF, DocFlavor.URL.PDF };
0187:
0188:            // Postscript DocFlavors
0189:            private static DocFlavor[] appPostScript = {
0190:                    DocFlavor.BYTE_ARRAY.POSTSCRIPT,
0191:                    DocFlavor.INPUT_STREAM.POSTSCRIPT, DocFlavor.URL.POSTSCRIPT };
0192:
0193:            // Autosense DocFlavors
0194:            private static DocFlavor[] appOctetStream = {
0195:                    DocFlavor.BYTE_ARRAY.AUTOSENSE,
0196:                    DocFlavor.INPUT_STREAM.AUTOSENSE, DocFlavor.URL.AUTOSENSE };
0197:
0198:            // Text DocFlavors
0199:            private static DocFlavor[] textPlain = {
0200:                    DocFlavor.BYTE_ARRAY.TEXT_PLAIN_UTF_8,
0201:                    DocFlavor.BYTE_ARRAY.TEXT_PLAIN_UTF_16,
0202:                    DocFlavor.BYTE_ARRAY.TEXT_PLAIN_UTF_16BE,
0203:                    DocFlavor.BYTE_ARRAY.TEXT_PLAIN_UTF_16LE,
0204:                    DocFlavor.BYTE_ARRAY.TEXT_PLAIN_US_ASCII,
0205:                    DocFlavor.INPUT_STREAM.TEXT_PLAIN_UTF_8,
0206:                    DocFlavor.INPUT_STREAM.TEXT_PLAIN_UTF_16,
0207:                    DocFlavor.INPUT_STREAM.TEXT_PLAIN_UTF_16BE,
0208:                    DocFlavor.INPUT_STREAM.TEXT_PLAIN_UTF_16LE,
0209:                    DocFlavor.INPUT_STREAM.TEXT_PLAIN_US_ASCII,
0210:                    DocFlavor.URL.TEXT_PLAIN_UTF_8,
0211:                    DocFlavor.URL.TEXT_PLAIN_UTF_16,
0212:                    DocFlavor.URL.TEXT_PLAIN_UTF_16BE,
0213:                    DocFlavor.URL.TEXT_PLAIN_UTF_16LE,
0214:                    DocFlavor.URL.TEXT_PLAIN_US_ASCII,
0215:                    DocFlavor.CHAR_ARRAY.TEXT_PLAIN,
0216:                    DocFlavor.STRING.TEXT_PLAIN, DocFlavor.READER.TEXT_PLAIN };
0217:
0218:            private static DocFlavor[] textPlainHost = {
0219:                    DocFlavor.BYTE_ARRAY.TEXT_PLAIN_HOST,
0220:                    DocFlavor.INPUT_STREAM.TEXT_PLAIN_HOST,
0221:                    DocFlavor.URL.TEXT_PLAIN_HOST };
0222:
0223:            // JPG DocFlavors
0224:            private static DocFlavor[] imageJPG = { DocFlavor.BYTE_ARRAY.JPEG,
0225:                    DocFlavor.INPUT_STREAM.JPEG, DocFlavor.URL.JPEG };
0226:
0227:            // GIF DocFlavors
0228:            private static DocFlavor[] imageGIF = { DocFlavor.BYTE_ARRAY.GIF,
0229:                    DocFlavor.INPUT_STREAM.GIF, DocFlavor.URL.GIF };
0230:
0231:            // PNG DocFlavors
0232:            private static DocFlavor[] imagePNG = { DocFlavor.BYTE_ARRAY.PNG,
0233:                    DocFlavor.INPUT_STREAM.PNG, DocFlavor.URL.PNG };
0234:
0235:            // HTML DocFlavors
0236:            private static DocFlavor[] textHtml = {
0237:                    DocFlavor.BYTE_ARRAY.TEXT_HTML_UTF_8,
0238:                    DocFlavor.BYTE_ARRAY.TEXT_HTML_UTF_16,
0239:                    DocFlavor.BYTE_ARRAY.TEXT_HTML_UTF_16BE,
0240:                    DocFlavor.BYTE_ARRAY.TEXT_HTML_UTF_16LE,
0241:                    DocFlavor.BYTE_ARRAY.TEXT_HTML_US_ASCII,
0242:                    DocFlavor.INPUT_STREAM.TEXT_HTML_UTF_8,
0243:                    DocFlavor.INPUT_STREAM.TEXT_HTML_UTF_16,
0244:                    DocFlavor.INPUT_STREAM.TEXT_HTML_UTF_16BE,
0245:                    DocFlavor.INPUT_STREAM.TEXT_HTML_UTF_16LE,
0246:                    DocFlavor.INPUT_STREAM.TEXT_HTML_US_ASCII,
0247:                    DocFlavor.URL.TEXT_HTML_UTF_8,
0248:                    DocFlavor.URL.TEXT_HTML_UTF_16,
0249:                    DocFlavor.URL.TEXT_HTML_UTF_16BE,
0250:                    DocFlavor.URL.TEXT_HTML_UTF_16LE,
0251:                    DocFlavor.URL.TEXT_HTML_US_ASCII,
0252:            // These are not handled in UnixPrintJob so commenting these
0253:            // for now.
0254:            /*
0255:            DocFlavor.CHAR_ARRAY.TEXT_HTML,
0256:            DocFlavor.STRING.TEXT_HTML,
0257:            DocFlavor.READER.TEXT_HTML,
0258:             */
0259:            };
0260:
0261:            private static DocFlavor[] textHtmlHost = {
0262:                    DocFlavor.BYTE_ARRAY.TEXT_HTML_HOST,
0263:                    DocFlavor.INPUT_STREAM.TEXT_HTML_HOST,
0264:                    DocFlavor.URL.TEXT_HTML_HOST, };
0265:
0266:            // PCL DocFlavors
0267:            private static DocFlavor[] appPCL = { DocFlavor.BYTE_ARRAY.PCL,
0268:                    DocFlavor.INPUT_STREAM.PCL, DocFlavor.URL.PCL };
0269:
0270:            // List of all DocFlavors, used in looping
0271:            // through all supported mime-types
0272:            private static Object[] allDocFlavors = { appPDF, appPostScript,
0273:                    appOctetStream, textPlain, imageJPG, imageGIF, imagePNG,
0274:                    textHtml, appPCL, };
0275:
0276:            IPPPrintService(String name, URL url) {
0277:                if ((name == null) || (url == null)) {
0278:                    throw new IllegalArgumentException(
0279:                            "null uri or printer name");
0280:                }
0281:                printer = name;
0282:                supportedDocFlavors = null;
0283:                supportedCats = null;
0284:                mediaSizeNames = null;
0285:                customMediaSizeNames = null;
0286:                mediaTrays = null;
0287:                myURL = url;
0288:                cps = null;
0289:                isCupsPrinter = false;
0290:                init = false;
0291:                defaultMediaIndex = -1;
0292:
0293:                String host = myURL.getHost();
0294:                if (host != null && host.equals(CUPSPrinter.getServer())) {
0295:                    isCupsPrinter = true;
0296:                    try {
0297:                        myURI = new URI("ipp://" + host + "/printers/"
0298:                                + printer);
0299:                        debug_println(debugPrefix + "IPPPrintService myURI : "
0300:                                + myURI);
0301:                    } catch (java.net.URISyntaxException e) {
0302:                        throw new IllegalArgumentException("invalid url");
0303:                    }
0304:                }
0305:            }
0306:
0307:            /*
0308:             * Initialize mediaSizeNames, mediaTrays and other attributes.
0309:             * Media size/trays are initialized to non-null values, may be 0-length
0310:             * array.
0311:             * NOTE: Must be called from a synchronized block only.
0312:             */
0313:            private void initAttributes() {
0314:                if (!init) {
0315:                    // init customMediaSizeNames
0316:                    customMediaSizeNames = new CustomMediaSizeName[0];
0317:
0318:                    if ((urlConnection = getIPPConnection(myURL)) == null) {
0319:                        mediaSizeNames = new MediaSizeName[0];
0320:                        mediaTrays = new MediaTray[0];
0321:                        debug_println("NULL urlConnection ");
0322:                        init = true;
0323:                        return;
0324:                    }
0325:
0326:                    // get all supported attributes through IPP
0327:                    opGetAttributes();
0328:
0329:                    if (isCupsPrinter) {
0330:                        // note, it is possible to query media in CUPS using IPP
0331:                        // right now we always get it from PPD.
0332:                        // maybe use "&& (usePPD)" later?
0333:                        // Another reason why we use PPD is because 
0334:                        // IPP currently does not support it but PPD does.
0335:
0336:                        try {
0337:                            cps = new CUPSPrinter(printer);
0338:                            mediaSizeNames = cps.getMediaSizeNames();
0339:                            mediaTrays = cps.getMediaTrays();
0340:                            customMediaSizeNames = cps
0341:                                    .getCustomMediaSizeNames();
0342:                            urlConnection.disconnect();
0343:                            init = true;
0344:                            return;
0345:                        } catch (Exception e) {
0346:                            IPPPrintService.debug_println(debugPrefix
0347:                                    + " error creating CUPSPrinter");
0348:                        }
0349:                    }
0350:
0351:                    // use IPP to get all media, 
0352:                    Media[] allMedia = (Media[]) getSupportedMedia();
0353:                    ArrayList sizeList = new ArrayList();
0354:                    ArrayList trayList = new ArrayList();
0355:                    for (int i = 0; i < allMedia.length; i++) {
0356:                        if (allMedia[i] instanceof  MediaSizeName) {
0357:                            sizeList.add(allMedia[i]);
0358:                        } else if (allMedia[i] instanceof  MediaTray) {
0359:                            trayList.add(allMedia[i]);
0360:                        }
0361:                    }
0362:
0363:                    if (sizeList != null) {
0364:                        mediaSizeNames = new MediaSizeName[sizeList.size()];
0365:                        mediaSizeNames = (MediaSizeName[]) sizeList
0366:                                .toArray(mediaSizeNames);
0367:                    }
0368:                    if (trayList != null) {
0369:                        mediaTrays = new MediaTray[trayList.size()];
0370:                        mediaTrays = (MediaTray[]) trayList.toArray(mediaTrays);
0371:                    }
0372:                    urlConnection.disconnect();
0373:
0374:                    init = true;
0375:                }
0376:            }
0377:
0378:            public DocPrintJob createPrintJob() {
0379:                SecurityManager security = System.getSecurityManager();
0380:                if (security != null) {
0381:                    security.checkPrintJobAccess();
0382:                }
0383:                // REMIND: create IPPPrintJob
0384:                return new UnixPrintJob(this );
0385:            }
0386:
0387:            public synchronized Object getSupportedAttributeValues(
0388:                    Class<? extends Attribute> category, DocFlavor flavor,
0389:                    AttributeSet attributes) {
0390:                if (category == null) {
0391:                    throw new NullPointerException("null category");
0392:                }
0393:                if (!Attribute.class.isAssignableFrom(category)) {
0394:                    throw new IllegalArgumentException(category
0395:                            + " does not implement Attribute");
0396:                }
0397:                if (flavor != null) {
0398:                    if (!isDocFlavorSupported(flavor)) {
0399:                        throw new IllegalArgumentException(flavor
0400:                                + " is an unsupported flavor");
0401:                    } else if (isAutoSense(flavor)) {
0402:                        return null;
0403:                    }
0404:
0405:                }
0406:
0407:                if (!isAttributeCategorySupported(category)) {
0408:                    return null;
0409:                }
0410:
0411:                /* Test if the flavor is compatible with the attributes */
0412:                if (!isDestinationSupported(flavor, attributes)) {
0413:                    return null;
0414:                }
0415:
0416:                initAttributes();
0417:
0418:                /* Test if the flavor is compatible with the category */
0419:                if ((category == Copies.class)
0420:                        || (category == CopiesSupported.class)) {
0421:                    CopiesSupported cs = new CopiesSupported(1, MAXCOPIES);
0422:                    AttributeClass attribClass = (getAttMap != null) ? (AttributeClass) getAttMap
0423:                            .get(cs.getName())
0424:                            : null;
0425:                    if (attribClass != null) {
0426:                        int[] range = attribClass.getIntRangeValue();
0427:                        cs = new CopiesSupported(range[0], range[1]);
0428:                    }
0429:                    return cs;
0430:                } else if (category == Chromaticity.class) {
0431:                    if (flavor == null
0432:                            || flavor
0433:                                    .equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE)
0434:                            || flavor
0435:                                    .equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE)
0436:                            || flavor.equals(DocFlavor.BYTE_ARRAY.GIF)
0437:                            || flavor.equals(DocFlavor.INPUT_STREAM.GIF)
0438:                            || flavor.equals(DocFlavor.URL.GIF)
0439:                            || flavor.equals(DocFlavor.BYTE_ARRAY.JPEG)
0440:                            || flavor.equals(DocFlavor.INPUT_STREAM.JPEG)
0441:                            || flavor.equals(DocFlavor.URL.JPEG)
0442:                            || flavor.equals(DocFlavor.BYTE_ARRAY.PNG)
0443:                            || flavor.equals(DocFlavor.INPUT_STREAM.PNG)
0444:                            || flavor.equals(DocFlavor.URL.PNG)) {
0445:
0446:                        Chromaticity[] arr = new Chromaticity[1];
0447:                        arr[0] = Chromaticity.COLOR;
0448:                        return (arr);
0449:                    } else {
0450:                        return null;
0451:                    }
0452:                } else if (category == Destination.class) {
0453:                    if (flavor == null
0454:                            || flavor
0455:                                    .equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE)
0456:                            || flavor
0457:                                    .equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE)) {
0458:                        try {
0459:                            return new Destination((new File("out.ps")).toURI());
0460:                        } catch (SecurityException se) {
0461:                            try {
0462:                                return new Destination(new URI("file:out.ps"));
0463:                            } catch (URISyntaxException e) {
0464:                                return null;
0465:                            }
0466:                        }
0467:                    }
0468:                    return null;
0469:                } else if (category == Fidelity.class) {
0470:                    Fidelity[] arr = new Fidelity[2];
0471:                    arr[0] = Fidelity.FIDELITY_FALSE;
0472:                    arr[1] = Fidelity.FIDELITY_TRUE;
0473:                    return arr;
0474:                } else if (category == Finishings.class) {
0475:                    AttributeClass attribClass = (getAttMap != null) ? (AttributeClass) getAttMap
0476:                            .get("finishings-supported")
0477:                            : null;
0478:                    if (attribClass != null) {
0479:                        int[] finArray = attribClass.getArrayOfIntValues();
0480:                        if ((finArray != null) && (finArray.length > 0)) {
0481:                            Finishings[] finSup = new Finishings[finArray.length];
0482:                            for (int i = 0; i < finArray.length; i++) {
0483:                                finSup[i] = Finishings.NONE;
0484:                                Finishings[] fAll = (Finishings[]) (new ExtFinishing(
0485:                                        100)).getAll();
0486:                                for (int j = 0; j < fAll.length; j++) {
0487:                                    if (finArray[i] == fAll[j].getValue()) {
0488:                                        finSup[i] = fAll[j];
0489:                                        break;
0490:                                    }
0491:                                }
0492:                            }
0493:                            return finSup;
0494:                        }
0495:                    }
0496:                } else if (category == JobName.class) {
0497:                    return new JobName("Java Printing", null);
0498:                } else if (category == JobSheets.class) {
0499:                    JobSheets arr[] = new JobSheets[2];
0500:                    arr[0] = JobSheets.NONE;
0501:                    arr[1] = JobSheets.STANDARD;
0502:                    return arr;
0503:
0504:                } else if (category == Media.class) {
0505:                    Media[] allMedia = new Media[mediaSizeNames.length
0506:                            + mediaTrays.length];
0507:
0508:                    for (int i = 0; i < mediaSizeNames.length; i++) {
0509:                        allMedia[i] = mediaSizeNames[i];
0510:                    }
0511:
0512:                    for (int i = 0; i < mediaTrays.length; i++) {
0513:                        allMedia[i + mediaSizeNames.length] = mediaTrays[i];
0514:                    }
0515:
0516:                    if (allMedia.length == 0) {
0517:                        allMedia = new Media[1];
0518:                        allMedia[0] = (Media) getDefaultAttributeValue(Media.class);
0519:                    }
0520:
0521:                    return allMedia;
0522:                } else if (category == MediaPrintableArea.class) {
0523:                    MediaPrintableArea[] mpas = null;
0524:                    if (cps != null) {
0525:                        mpas = cps.getMediaPrintableArea();
0526:                    }
0527:
0528:                    if (mpas == null) {
0529:                        mpas = new MediaPrintableArea[1];
0530:                        mpas[0] = (MediaPrintableArea) getDefaultAttributeValue(MediaPrintableArea.class);
0531:                    }
0532:
0533:                    if ((attributes == null) || (attributes.size() == 0)) {
0534:                        ArrayList<MediaPrintableArea> printableList = new ArrayList<MediaPrintableArea>();
0535:
0536:                        for (int i = 0; i < mpas.length; i++) {
0537:                            if (mpas[i] != null) {
0538:                                printableList.add(mpas[i]);
0539:                            }
0540:                        }
0541:                        if (printableList.size() > 0) {
0542:                            mpas = new MediaPrintableArea[printableList.size()];
0543:                            printableList.toArray(mpas);
0544:                        }
0545:                        return mpas;
0546:                    }
0547:
0548:                    int match = -1;
0549:                    Media media = (Media) attributes.get(Media.class);
0550:                    if (media != null && media instanceof  MediaSizeName) {
0551:                        MediaSizeName msn = (MediaSizeName) media;
0552:
0553:                        // case when no supported mediasizenames are reported
0554:                        // check given media against the default
0555:                        if (mediaSizeNames.length == 0
0556:                                && msn
0557:                                        .equals(getDefaultAttributeValue(Media.class))) {
0558:                            //default printable area is that of default mediasize
0559:                            return mpas;
0560:                        }
0561:
0562:                        for (int i = 0; i < mediaSizeNames.length; i++) {
0563:                            if (msn.equals(mediaSizeNames[i])) {
0564:                                match = i;
0565:                            }
0566:                        }
0567:                    }
0568:
0569:                    if (match == -1) {
0570:                        return null;
0571:                    } else {
0572:                        MediaPrintableArea[] arr = new MediaPrintableArea[1];
0573:                        arr[0] = mpas[match];
0574:                        return arr;
0575:                    }
0576:                } else if (category == NumberUp.class) {
0577:                    AttributeClass attribClass = (getAttMap != null) ? (AttributeClass) getAttMap
0578:                            .get("number-up-supported")
0579:                            : null;
0580:                    if (attribClass != null) {
0581:                        int[] values = attribClass.getArrayOfIntValues();
0582:                        if (values != null) {
0583:                            NumberUp[] nUp = new NumberUp[values.length];
0584:                            for (int i = 0; i < values.length; i++) {
0585:                                nUp[i] = new NumberUp(values[i]);
0586:                            }
0587:                            return nUp;
0588:                        } else {
0589:                            return null;
0590:                        }
0591:                    }
0592:                } else if (category == OrientationRequested.class) {
0593:                    if (flavor == null
0594:                            || flavor
0595:                                    .equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE)
0596:                            || flavor
0597:                                    .equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE)) {
0598:                        // Orientation is emulated in Pageable/Printable flavors
0599:                        // so we report the 3 orientations as supported.
0600:                        OrientationRequested[] orientSup = new OrientationRequested[3];
0601:                        orientSup[0] = OrientationRequested.PORTRAIT;
0602:                        orientSup[1] = OrientationRequested.LANDSCAPE;
0603:                        orientSup[2] = OrientationRequested.REVERSE_LANDSCAPE;
0604:                        return orientSup;
0605:                    }
0606:
0607:                    AttributeClass attribClass = (getAttMap != null) ? (AttributeClass) getAttMap
0608:                            .get("orientation-requested-supported")
0609:                            : null;
0610:                    if (attribClass != null) {
0611:                        int[] orientArray = attribClass.getArrayOfIntValues();
0612:                        if ((orientArray != null) && (orientArray.length > 0)) {
0613:                            OrientationRequested[] orientSup = new OrientationRequested[orientArray.length];
0614:                            for (int i = 0; i < orientArray.length; i++) {
0615:                                switch (orientArray[i]) {
0616:                                default:
0617:                                case 3:
0618:                                    orientSup[i] = OrientationRequested.PORTRAIT;
0619:                                    break;
0620:                                case 4:
0621:                                    orientSup[i] = OrientationRequested.LANDSCAPE;
0622:                                    break;
0623:                                case 5:
0624:                                    orientSup[i] = OrientationRequested.REVERSE_LANDSCAPE;
0625:                                    break;
0626:                                case 6:
0627:                                    orientSup[i] = OrientationRequested.REVERSE_PORTRAIT;
0628:                                    break;
0629:                                }
0630:                            }
0631:                            return orientSup;
0632:                        }
0633:                    }
0634:                } else if (category == PageRanges.class) {
0635:                    if (flavor == null
0636:                            || flavor
0637:                                    .equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE)
0638:                            || flavor
0639:                                    .equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE)) {
0640:                        PageRanges[] arr = new PageRanges[1];
0641:                        arr[0] = new PageRanges(1, Integer.MAX_VALUE);
0642:                        return arr;
0643:                    } else {
0644:                        // Returning null as this is not yet supported in UnixPrintJob.
0645:                        return null;
0646:                    }
0647:                } else if (category == RequestingUserName.class) {
0648:                    String userName = "";
0649:                    try {
0650:                        userName = System.getProperty("user.name", "");
0651:                    } catch (SecurityException se) {
0652:                    }
0653:                    return new RequestingUserName(userName, null);
0654:                } else if (category == Sides.class) {
0655:                    // The printer takes care of Sides so if short-edge 
0656:                    // is chosen in a job, the rotation is done by the printer.
0657:                    // Orientation is rotated by emulation if pageable
0658:                    // or printable so if the document is in Landscape, this may
0659:                    // result in double rotation.
0660:                    AttributeClass attribClass = (getAttMap != null) ? (AttributeClass) getAttMap
0661:                            .get("sides-supported")
0662:                            : null;
0663:                    if (attribClass != null) {
0664:                        String[] sidesArray = attribClass
0665:                                .getArrayOfStringValues();
0666:                        if ((sidesArray != null) && (sidesArray.length > 0)) {
0667:                            Sides[] sidesSup = new Sides[sidesArray.length];
0668:                            for (int i = 0; i < sidesArray.length; i++) {
0669:                                if (sidesArray[i].endsWith("long-edge")) {
0670:                                    sidesSup[i] = Sides.TWO_SIDED_LONG_EDGE;
0671:                                } else if (sidesArray[i].endsWith("short-edge")) {
0672:                                    sidesSup[i] = Sides.TWO_SIDED_SHORT_EDGE;
0673:                                } else {
0674:                                    sidesSup[i] = Sides.ONE_SIDED;
0675:                                }
0676:                            }
0677:                            return sidesSup;
0678:                        }
0679:                    }
0680:                }
0681:
0682:                return null;
0683:            }
0684:
0685:            //This class is for getting all pre-defined Finishings
0686:            private class ExtFinishing extends Finishings {
0687:                ExtFinishing(int value) {
0688:                    super (100); // 100 to avoid any conflicts with predefined values.
0689:                }
0690:
0691:                EnumSyntax[] getAll() {
0692:                    EnumSyntax[] es = super .getEnumValueTable();
0693:                    return es;
0694:                }
0695:            }
0696:
0697:            public AttributeSet getUnsupportedAttributes(DocFlavor flavor,
0698:                    AttributeSet attributes) {
0699:                if (flavor != null && !isDocFlavorSupported(flavor)) {
0700:                    throw new IllegalArgumentException("flavor " + flavor
0701:                            + "is not supported");
0702:                }
0703:
0704:                if (attributes == null) {
0705:                    return null;
0706:                }
0707:
0708:                Attribute attr;
0709:                AttributeSet unsupp = new HashAttributeSet();
0710:                Attribute[] attrs = attributes.toArray();
0711:                for (int i = 0; i < attrs.length; i++) {
0712:                    try {
0713:                        attr = attrs[i];
0714:                        if (!isAttributeCategorySupported(attr.getCategory())) {
0715:                            unsupp.add(attr);
0716:                        } else if (!isAttributeValueSupported(attr, flavor,
0717:                                attributes)) {
0718:                            unsupp.add(attr);
0719:                        }
0720:                    } catch (ClassCastException e) {
0721:                    }
0722:                }
0723:                if (unsupp.isEmpty()) {
0724:                    return null;
0725:                } else {
0726:                    return unsupp;
0727:                }
0728:            }
0729:
0730:            public synchronized DocFlavor[] getSupportedDocFlavors() {
0731:
0732:                if (supportedDocFlavors != null) {
0733:                    int len = supportedDocFlavors.length;
0734:                    DocFlavor[] copyflavors = new DocFlavor[len];
0735:                    System.arraycopy(supportedDocFlavors, 0, copyflavors, 0,
0736:                            len);
0737:                    return copyflavors;
0738:                }
0739:                initAttributes();
0740:
0741:                if ((getAttMap != null)
0742:                        && getAttMap.containsKey("document-format-supported")) {
0743:
0744:                    AttributeClass attribClass = (AttributeClass) getAttMap
0745:                            .get("document-format-supported");
0746:                    if (attribClass != null) {
0747:                        String mimeType;
0748:                        boolean psSupported = false;
0749:                        String[] docFlavors = attribClass
0750:                                .getArrayOfStringValues();
0751:                        DocFlavor[] flavors;
0752:                        ArrayList docList = new ArrayList();
0753:                        int j;
0754:                        String hostEnc = DocFlavor.hostEncoding
0755:                                .toLowerCase(Locale.ENGLISH);
0756:                        boolean addHostEncoding = !hostEnc.equals("utf-8")
0757:                                && !hostEnc.equals("utf-16")
0758:                                && !hostEnc.equals("utf-16be")
0759:                                && !hostEnc.equals("utf-16le")
0760:                                && !hostEnc.equals("us-ascii");
0761:
0762:                        for (int i = 0; i < docFlavors.length; i++) {
0763:                            for (j = 0; j < allDocFlavors.length; j++) {
0764:                                flavors = (DocFlavor[]) allDocFlavors[j];
0765:
0766:                                mimeType = flavors[0].getMimeType();
0767:                                if (mimeType.startsWith(docFlavors[i])) {
0768:
0769:                                    docList.addAll(Arrays.asList(flavors));
0770:
0771:                                    if (mimeType.equals("text/plain")
0772:                                            && addHostEncoding) {
0773:                                        docList.add(Arrays
0774:                                                .asList(textPlainHost));
0775:                                    } else if (mimeType.equals("text/html")
0776:                                            && addHostEncoding) {
0777:                                        docList
0778:                                                .add(Arrays
0779:                                                        .asList(textHtmlHost));
0780:                                    } else if (mimeType.equals("image/png")) {
0781:                                        pngImagesAdded = true;
0782:                                    } else if (mimeType.equals("image/gif")) {
0783:                                        gifImagesAdded = true;
0784:                                    } else if (mimeType.equals("image/jpeg")) {
0785:                                        jpgImagesAdded = true;
0786:                                    } else if (mimeType.indexOf("postscript") != -1) {
0787:                                        docList
0788:                                                .add(DocFlavor.SERVICE_FORMATTED.PAGEABLE);
0789:                                        docList
0790:                                                .add(DocFlavor.SERVICE_FORMATTED.PRINTABLE);
0791:
0792:                                        psSupported = true;
0793:                                    }
0794:                                    break;
0795:                                }
0796:                            }
0797:
0798:                            // Not added? Create new DocFlavors
0799:                            if (j == allDocFlavors.length) {
0800:                                //  make new DocFlavors
0801:                                docList.add(new DocFlavor.BYTE_ARRAY(
0802:                                        docFlavors[i]));
0803:                                docList.add(new DocFlavor.INPUT_STREAM(
0804:                                        docFlavors[i]));
0805:                                docList.add(new DocFlavor.URL(docFlavors[i]));
0806:                            }
0807:                        }
0808:
0809:                        // check if we need to add image DocFlavors
0810:                        if (psSupported) {
0811:                            if (!jpgImagesAdded) {
0812:                                docList.addAll(Arrays.asList(imageJPG));
0813:                            }
0814:                            if (!pngImagesAdded) {
0815:                                docList.addAll(Arrays.asList(imagePNG));
0816:                            }
0817:                            if (!gifImagesAdded) {
0818:                                docList.addAll(Arrays.asList(imageGIF));
0819:                            }
0820:                        }
0821:                        supportedDocFlavors = new DocFlavor[docList.size()];
0822:                        docList.toArray(supportedDocFlavors);
0823:                        int len = supportedDocFlavors.length;
0824:                        DocFlavor[] copyflavors = new DocFlavor[len];
0825:                        System.arraycopy(supportedDocFlavors, 0, copyflavors,
0826:                                0, len);
0827:                        return copyflavors;
0828:                    }
0829:                }
0830:                return null;
0831:            }
0832:
0833:            public boolean isDocFlavorSupported(DocFlavor flavor) {
0834:                if (supportedDocFlavors == null) {
0835:                    getSupportedDocFlavors();
0836:                }
0837:                if (supportedDocFlavors != null) {
0838:                    for (int f = 0; f < supportedDocFlavors.length; f++) {
0839:                        if (flavor.equals(supportedDocFlavors[f])) {
0840:                            return true;
0841:                        }
0842:                    }
0843:                }
0844:                return false;
0845:            }
0846:
0847:            /**
0848:             * Finds matching CustomMediaSizeName of given media.
0849:             */
0850:            public CustomMediaSizeName findCustomMedia(MediaSizeName media) {
0851:                for (int i = 0; i < customMediaSizeNames.length; i++) {
0852:                    CustomMediaSizeName custom = (CustomMediaSizeName) customMediaSizeNames[i];
0853:                    MediaSizeName msn = custom.getStandardMedia();
0854:                    if (media.equals(msn)) {
0855:                        return customMediaSizeNames[i];
0856:                    }
0857:                }
0858:                return null;
0859:            }
0860:
0861:            /**
0862:             * Returns the matching standard Media using string comparison of names.
0863:             */
0864:            private Media getIPPMedia(String mediaName) {
0865:                CustomMediaSizeName sampleSize = new CustomMediaSizeName(
0866:                        "sample", "", 0, 0);
0867:                Media[] sizes = sampleSize.getSuperEnumTable();
0868:                for (int i = 0; i < sizes.length; i++) {
0869:                    if (mediaName.equals("" + sizes[i])) {
0870:                        return sizes[i];
0871:                    }
0872:                }
0873:                CustomMediaTray sampleTray = new CustomMediaTray("sample", "");
0874:                Media[] trays = sampleTray.getSuperEnumTable();
0875:                for (int i = 0; i < trays.length; i++) {
0876:                    if (mediaName.equals("" + trays[i])) {
0877:                        return trays[i];
0878:                    }
0879:                }
0880:                return null;
0881:            }
0882:
0883:            private Media[] getSupportedMedia() {
0884:                if ((getAttMap != null)
0885:                        && getAttMap.containsKey("media-supported")) {
0886:
0887:                    AttributeClass attribClass = (AttributeClass) getAttMap
0888:                            .get("media-supported");
0889:
0890:                    if (attribClass != null) {
0891:                        String[] mediaVals = attribClass
0892:                                .getArrayOfStringValues();
0893:                        Media msn;
0894:                        Media[] mediaNames = new Media[mediaVals.length];
0895:                        for (int i = 0; i < mediaVals.length; i++) {
0896:                            msn = getIPPMedia(mediaVals[i]);
0897:                            //REMIND: if null, create custom?
0898:                            mediaNames[i] = msn;
0899:                        }
0900:                        return mediaNames;
0901:                    }
0902:                }
0903:                return new Media[0];
0904:            }
0905:
0906:            public synchronized Class[] getSupportedAttributeCategories() {
0907:                if (supportedCats != null) {
0908:                    return supportedCats;
0909:                }
0910:
0911:                initAttributes();
0912:
0913:                ArrayList catList = new ArrayList();
0914:                Class cl;
0915:
0916:                for (int i = 0; i < printReqAttribDefault.length; i++) {
0917:                    PrintRequestAttribute pra = (PrintRequestAttribute) printReqAttribDefault[i];
0918:                    if (getAttMap != null
0919:                            && getAttMap.containsKey(pra.getName()
0920:                                    + "-supported")) {
0921:                        cl = pra.getCategory();
0922:                        catList.add(cl);
0923:                    }
0924:                }
0925:
0926:                // Some IPP printers like lexc710 do not have list of supported media
0927:                // but CUPS can get the media from PPD, so we still report as 
0928:                // supported category.
0929:                if (isCupsPrinter) {
0930:                    if (!catList.contains(Media.class)) {
0931:                        catList.add(Media.class);
0932:                    }
0933:
0934:                    // Always add MediaPrintable for cups, 
0935:                    // because we can get it from PPD.
0936:                    catList.add(MediaPrintableArea.class);
0937:
0938:                    // this is already supported in UnixPrintJob
0939:                    catList.add(Destination.class);
0940:                }
0941:
0942:                // With the assumption that  Chromaticity is equivalent to
0943:                // ColorSupported.
0944:                if (getAttMap != null
0945:                        && getAttMap.containsKey("color-supported")) {
0946:                    catList.add(Chromaticity.class);
0947:                }
0948:                supportedCats = new Class[catList.size()];
0949:                catList.toArray(supportedCats);
0950:                return supportedCats;
0951:            }
0952:
0953:            public boolean isAttributeCategorySupported(
0954:                    Class<? extends Attribute> category) {
0955:                if (category == null) {
0956:                    throw new NullPointerException("null category");
0957:                }
0958:                if (!(Attribute.class.isAssignableFrom(category))) {
0959:                    throw new IllegalArgumentException(category
0960:                            + " is not an Attribute");
0961:                }
0962:
0963:                if (supportedCats == null) {
0964:                    getSupportedAttributeCategories();
0965:                }
0966:
0967:                for (int i = 0; i < supportedCats.length; i++) {
0968:                    if (category == supportedCats[i]) {
0969:                        return true;
0970:                    }
0971:                }
0972:
0973:                return false;
0974:            }
0975:
0976:            public synchronized <T extends PrintServiceAttribute> T getAttribute(
0977:                    Class<T> category) {
0978:                if (category == null) {
0979:                    throw new NullPointerException("category");
0980:                }
0981:                if (!(PrintServiceAttribute.class.isAssignableFrom(category))) {
0982:                    throw new IllegalArgumentException(
0983:                            "Not a PrintServiceAttribute");
0984:                }
0985:
0986:                initAttributes();
0987:
0988:                if (category == PrinterName.class) {
0989:                    return (T) (new PrinterName(printer, null));
0990:                } else if (category == QueuedJobCount.class) {
0991:                    QueuedJobCount qjc = new QueuedJobCount(0);
0992:                    AttributeClass ac = (getAttMap != null) ? (AttributeClass) getAttMap
0993:                            .get(qjc.getName())
0994:                            : null;
0995:                    if (ac != null) {
0996:                        qjc = new QueuedJobCount(ac.getIntValue());
0997:                    }
0998:                    return (T) qjc;
0999:                } else if (category == PrinterIsAcceptingJobs.class) {
1000:                    PrinterIsAcceptingJobs accJob = PrinterIsAcceptingJobs.ACCEPTING_JOBS;
1001:                    AttributeClass ac = (getAttMap != null) ? (AttributeClass) getAttMap
1002:                            .get(accJob.getName())
1003:                            : null;
1004:                    if ((ac != null) && (ac.getByteValue() == 0)) {
1005:                        accJob = PrinterIsAcceptingJobs.NOT_ACCEPTING_JOBS;
1006:                    }
1007:                    return (T) accJob;
1008:                } else if (category == ColorSupported.class) {
1009:                    ColorSupported cs = ColorSupported.SUPPORTED;
1010:                    AttributeClass ac = (getAttMap != null) ? (AttributeClass) getAttMap
1011:                            .get(cs.getName())
1012:                            : null;
1013:                    if ((ac != null) && (ac.getByteValue() == 0)) {
1014:                        cs = ColorSupported.NOT_SUPPORTED;
1015:                    }
1016:                    return (T) cs;
1017:                } else if (category == PDLOverrideSupported.class) {
1018:
1019:                    if (isCupsPrinter) {
1020:                        // Documented: For CUPS this will always be false
1021:                        return (T) PDLOverrideSupported.NOT_ATTEMPTED;
1022:                    } else {
1023:                        // REMIND: check attribute values
1024:                        return (T) PDLOverrideSupported.NOT_ATTEMPTED;
1025:                    }
1026:                } else {
1027:                    return null;
1028:                }
1029:            }
1030:
1031:            public synchronized PrintServiceAttributeSet getAttributes() {
1032:                // update getAttMap by sending again get-attributes IPP request
1033:                init = false;
1034:                initAttributes();
1035:
1036:                HashPrintServiceAttributeSet attrs = new HashPrintServiceAttributeSet();
1037:
1038:                for (int i = 0; i < serviceAttributes.length; i++) {
1039:                    String name = (String) serviceAttributes[i][1];
1040:                    if (getAttMap != null && getAttMap.containsKey(name)) {
1041:                        Class c = (Class) serviceAttributes[i][0];
1042:                        PrintServiceAttribute psa = getAttribute(c);
1043:                        if (psa != null) {
1044:                            attrs.add(psa);
1045:                        }
1046:                    }
1047:                }
1048:                return AttributeSetUtilities.unmodifiableView(attrs);
1049:            }
1050:
1051:            public boolean isIPPSupportedImages(String mimeType) {
1052:                if (supportedDocFlavors == null) {
1053:                    getSupportedDocFlavors();
1054:                }
1055:
1056:                if (mimeType.equals("image/png") && pngImagesAdded) {
1057:                    return true;
1058:                } else if (mimeType.equals("image/gif") && gifImagesAdded) {
1059:                    return true;
1060:                } else if (mimeType.equals("image/jpeg") && jpgImagesAdded) {
1061:                    return true;
1062:                }
1063:
1064:                return false;
1065:            }
1066:
1067:            private boolean isSupportedCopies(Copies copies) {
1068:                CopiesSupported cs = (CopiesSupported) getSupportedAttributeValues(
1069:                        Copies.class, null, null);
1070:                int[][] members = cs.getMembers();
1071:                int min, max;
1072:                if ((members.length > 0) && (members[0].length > 0)) {
1073:                    min = members[0][0];
1074:                    max = members[0][1];
1075:                } else {
1076:                    min = 1;
1077:                    max = MAXCOPIES;
1078:                }
1079:
1080:                int value = copies.getValue();
1081:                return (value >= min && value <= max);
1082:            }
1083:
1084:            private boolean isAutoSense(DocFlavor flavor) {
1085:                if (flavor.equals(DocFlavor.BYTE_ARRAY.AUTOSENSE)
1086:                        || flavor.equals(DocFlavor.INPUT_STREAM.AUTOSENSE)
1087:                        || flavor.equals(DocFlavor.URL.AUTOSENSE)) {
1088:                    return true;
1089:                } else {
1090:                    return false;
1091:                }
1092:            }
1093:
1094:            private synchronized boolean isSupportedMediaTray(MediaTray msn) {
1095:                initAttributes();
1096:
1097:                if (mediaTrays != null) {
1098:                    for (int i = 0; i < mediaTrays.length; i++) {
1099:                        if (msn.equals(mediaTrays[i])) {
1100:                            return true;
1101:                        }
1102:                    }
1103:                }
1104:                return false;
1105:            }
1106:
1107:            private synchronized boolean isSupportedMedia(MediaSizeName msn) {
1108:                initAttributes();
1109:
1110:                if (msn.equals((Media) getDefaultAttributeValue(Media.class))) {
1111:                    return true;
1112:                }
1113:                for (int i = 0; i < mediaSizeNames.length; i++) {
1114:                    debug_println("mediaSizeNames[i] " + mediaSizeNames[i]);
1115:                    if (msn.equals(mediaSizeNames[i])) {
1116:                        return true;
1117:                    }
1118:                }
1119:                return false;
1120:            }
1121:
1122:            /* Return false if flavor is not null, pageable, nor printable and
1123:             * Destination is part of attributes.
1124:             */
1125:            private boolean isDestinationSupported(DocFlavor flavor,
1126:                    AttributeSet attributes) {
1127:
1128:                if ((attributes != null)
1129:                        && (attributes.get(Destination.class) != null)
1130:                        && !(flavor == null
1131:                                || flavor
1132:                                        .equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) || flavor
1133:                                .equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE))) {
1134:                    return false;
1135:                }
1136:                return true;
1137:            }
1138:
1139:            public boolean isAttributeValueSupported(Attribute attr,
1140:                    DocFlavor flavor, AttributeSet attributes) {
1141:                if (attr == null) {
1142:                    throw new NullPointerException("null attribute");
1143:                }
1144:                if (flavor != null) {
1145:                    if (!isDocFlavorSupported(flavor)) {
1146:                        throw new IllegalArgumentException(flavor
1147:                                + " is an unsupported flavor");
1148:                    } else if (isAutoSense(flavor)) {
1149:                        return false;
1150:                    }
1151:                }
1152:                Class category = attr.getCategory();
1153:                if (!isAttributeCategorySupported(category)) {
1154:                    return false;
1155:                }
1156:
1157:                /* Test if the flavor is compatible with the attributes */
1158:                if (!isDestinationSupported(flavor, attributes)) {
1159:                    return false;
1160:                }
1161:
1162:                /* Test if the flavor is compatible with the category */
1163:                if (attr.getCategory() == Chromaticity.class) {
1164:                    if ((flavor == null)
1165:                            || flavor
1166:                                    .equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE)
1167:                            || flavor
1168:                                    .equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE)
1169:                            || flavor.equals(DocFlavor.BYTE_ARRAY.GIF)
1170:                            || flavor.equals(DocFlavor.INPUT_STREAM.GIF)
1171:                            || flavor.equals(DocFlavor.URL.GIF)
1172:                            || flavor.equals(DocFlavor.BYTE_ARRAY.JPEG)
1173:                            || flavor.equals(DocFlavor.INPUT_STREAM.JPEG)
1174:                            || flavor.equals(DocFlavor.URL.JPEG)
1175:                            || flavor.equals(DocFlavor.BYTE_ARRAY.PNG)
1176:                            || flavor.equals(DocFlavor.INPUT_STREAM.PNG)
1177:                            || flavor.equals(DocFlavor.URL.PNG)) {
1178:                        return attr == Chromaticity.COLOR;
1179:                    } else {
1180:                        return false;
1181:                    }
1182:                } else if (attr.getCategory() == Copies.class) {
1183:                    return isSupportedCopies((Copies) attr);
1184:                } else if (attr.getCategory() == Destination.class) {
1185:                    if (flavor == null
1186:                            || flavor
1187:                                    .equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE)
1188:                            || flavor
1189:                                    .equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE)) {
1190:                        URI uri = ((Destination) attr).getURI();
1191:                        if ("file".equals(uri.getScheme())
1192:                                && !(uri.getSchemeSpecificPart().equals(""))) {
1193:                            return true;
1194:                        }
1195:                    }
1196:                    return false;
1197:                } else if (attr.getCategory() == Media.class) {
1198:                    if (attr instanceof  MediaSizeName) {
1199:                        return isSupportedMedia((MediaSizeName) attr);
1200:                    }
1201:                    if (attr instanceof  MediaTray) {
1202:                        return isSupportedMediaTray((MediaTray) attr);
1203:                    }
1204:                } else if (attr.getCategory() == PageRanges.class) {
1205:                    if (flavor != null
1206:                            && !(flavor
1207:                                    .equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) || flavor
1208:                                    .equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE))) {
1209:                        return false;
1210:                    }
1211:                } else if (attr.getCategory() == SheetCollate.class) {
1212:                    if (flavor != null
1213:                            && !(flavor
1214:                                    .equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) || flavor
1215:                                    .equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE))) {
1216:                        return false;
1217:                    }
1218:                } else if (attr.getCategory() == Sides.class) {
1219:                    Sides[] sidesArray = (Sides[]) getSupportedAttributeValues(
1220:                            Sides.class, flavor, attributes);
1221:
1222:                    if (sidesArray != null) {
1223:                        for (int i = 0; i < sidesArray.length; i++) {
1224:                            if (sidesArray[i] == (Sides) attr) {
1225:                                return true;
1226:                            }
1227:                        }
1228:                    }
1229:                    return false;
1230:                } else if (attr.getCategory() == OrientationRequested.class) {
1231:                    OrientationRequested[] orientArray = (OrientationRequested[]) getSupportedAttributeValues(
1232:                            OrientationRequested.class, flavor, attributes);
1233:
1234:                    if (orientArray != null) {
1235:                        for (int i = 0; i < orientArray.length; i++) {
1236:                            if (orientArray[i] == (OrientationRequested) attr) {
1237:                                return true;
1238:                            }
1239:                        }
1240:                    }
1241:                    return false;
1242:                }
1243:                return true;
1244:            }
1245:
1246:            public synchronized Object getDefaultAttributeValue(
1247:                    Class<? extends Attribute> category) {
1248:                if (category == null) {
1249:                    throw new NullPointerException("null category");
1250:                }
1251:                if (!Attribute.class.isAssignableFrom(category)) {
1252:                    throw new IllegalArgumentException(category
1253:                            + " is not an Attribute");
1254:                }
1255:                if (!isAttributeCategorySupported(category)) {
1256:                    return null;
1257:                }
1258:
1259:                initAttributes();
1260:
1261:                String catName = null;
1262:                for (int i = 0; i < printReqAttribDefault.length; i++) {
1263:                    PrintRequestAttribute pra = (PrintRequestAttribute) printReqAttribDefault[i];
1264:                    if (pra.getCategory() == category) {
1265:                        catName = pra.getName();
1266:                        break;
1267:                    }
1268:                }
1269:                String attribName = catName + "-default";
1270:                AttributeClass attribClass = (getAttMap != null) ? (AttributeClass) getAttMap
1271:                        .get(attribName)
1272:                        : null;
1273:
1274:                if (category == Copies.class) {
1275:                    if (attribClass != null) {
1276:                        return new Copies(attribClass.getIntValue());
1277:                    } else {
1278:                        return new Copies(1);
1279:                    }
1280:                } else if (category == Chromaticity.class) {
1281:                    return Chromaticity.COLOR;
1282:                } else if (category == Destination.class) {
1283:                    try {
1284:                        return new Destination((new File("out.ps")).toURI());
1285:                    } catch (SecurityException se) {
1286:                        try {
1287:                            return new Destination(new URI("file:out.ps"));
1288:                        } catch (URISyntaxException e) {
1289:                            return null;
1290:                        }
1291:                    }
1292:                } else if (category == Fidelity.class) {
1293:                    return Fidelity.FIDELITY_FALSE;
1294:                } else if (category == Finishings.class) {
1295:                    return Finishings.NONE;
1296:                } else if (category == JobName.class) {
1297:                    return new JobName("Java Printing", null);
1298:                } else if (category == JobSheets.class) {
1299:                    if (attribClass != null
1300:                            && attribClass.getStringValue().equals("none")) {
1301:                        return JobSheets.NONE;
1302:                    } else {
1303:                        return JobSheets.STANDARD;
1304:                    }
1305:                } else if (category == Media.class) {
1306:                    defaultMediaIndex = 0;
1307:                    if (mediaSizeNames.length == 0) {
1308:                        String defaultCountry = Locale.getDefault()
1309:                                .getCountry();
1310:                        if (defaultCountry != null
1311:                                && (defaultCountry.equals("")
1312:                                        || defaultCountry.equals(Locale.US
1313:                                                .getCountry()) || defaultCountry
1314:                                        .equals(Locale.CANADA.getCountry()))) {
1315:                            return MediaSizeName.NA_LETTER;
1316:                        } else {
1317:                            return MediaSizeName.ISO_A4;
1318:                        }
1319:                    }
1320:
1321:                    if (attribClass != null) {
1322:                        String name = attribClass.getStringValue();
1323:                        if (isCupsPrinter) {
1324:                            for (int i = 0; i < customMediaSizeNames.length; i++) {
1325:                                //REMIND:  get default from PPD. In native _getMedia,
1326:                                // move default (ppd_option_t->defchoice) to index 0. 
1327:                                // In the meantime, use indexOf because PPD name 
1328:                                // may be different from the IPP attribute name.
1329:                                if (customMediaSizeNames[i].toString().indexOf(
1330:                                        name) != -1) {
1331:                                    defaultMediaIndex = i;
1332:                                    return mediaSizeNames[defaultMediaIndex];
1333:                                }
1334:                            }
1335:                        } else {
1336:                            for (int i = 0; i < mediaSizeNames.length; i++) {
1337:                                if (mediaSizeNames[i].toString().indexOf(name) != -1) {
1338:                                    defaultMediaIndex = i;
1339:                                    return mediaSizeNames[defaultMediaIndex];
1340:                                }
1341:                            }
1342:                        }
1343:                    }
1344:                    return mediaSizeNames[defaultMediaIndex];
1345:
1346:                } else if (category == MediaPrintableArea.class) {
1347:                    MediaPrintableArea[] mpas;
1348:                    if ((cps != null)
1349:                            && ((mpas = cps.getMediaPrintableArea()) != null)) {
1350:                        if (defaultMediaIndex == -1) {
1351:                            // initializes value of defaultMediaIndex
1352:                            getDefaultAttributeValue(Media.class);
1353:                        }
1354:                        return mpas[defaultMediaIndex];
1355:                    } else {
1356:                        String defaultCountry = Locale.getDefault()
1357:                                .getCountry();
1358:                        float iw, ih;
1359:                        if (defaultCountry != null
1360:                                && (defaultCountry.equals("")
1361:                                        || defaultCountry.equals(Locale.US
1362:                                                .getCountry()) || defaultCountry
1363:                                        .equals(Locale.CANADA.getCountry()))) {
1364:                            iw = MediaSize.NA.LETTER.getX(Size2DSyntax.INCH) - 0.5f;
1365:                            ih = MediaSize.NA.LETTER.getY(Size2DSyntax.INCH) - 0.5f;
1366:                        } else {
1367:                            iw = MediaSize.ISO.A4.getX(Size2DSyntax.INCH) - 0.5f;
1368:                            ih = MediaSize.ISO.A4.getY(Size2DSyntax.INCH) - 0.5f;
1369:                        }
1370:                        return new MediaPrintableArea(0.25f, 0.25f, iw, ih,
1371:                                MediaPrintableArea.INCH);
1372:                    }
1373:                } else if (category == NumberUp.class) {
1374:                    return new NumberUp(1); // for CUPS this is always 1
1375:                } else if (category == OrientationRequested.class) {
1376:                    if (attribClass != null) {
1377:                        switch (attribClass.getIntValue()) {
1378:                        default:
1379:                        case 3:
1380:                            return OrientationRequested.PORTRAIT;
1381:                        case 4:
1382:                            return OrientationRequested.LANDSCAPE;
1383:                        case 5:
1384:                            return OrientationRequested.REVERSE_LANDSCAPE;
1385:                        case 6:
1386:                            return OrientationRequested.REVERSE_PORTRAIT;
1387:                        }
1388:                    } else {
1389:                        return OrientationRequested.PORTRAIT;
1390:                    }
1391:                } else if (category == PageRanges.class) {
1392:                    if (attribClass != null) {
1393:                        int[] range = attribClass.getIntRangeValue();
1394:                        return new PageRanges(range[0], range[1]);
1395:                    } else {
1396:                        return new PageRanges(1, Integer.MAX_VALUE);
1397:                    }
1398:                } else if (category == RequestingUserName.class) {
1399:                    String userName = "";
1400:                    try {
1401:                        userName = System.getProperty("user.name", "");
1402:                    } catch (SecurityException se) {
1403:                    }
1404:                    return new RequestingUserName(userName, null);
1405:                } else if (category == SheetCollate.class) {
1406:                    return SheetCollate.UNCOLLATED;
1407:                } else if (category == Sides.class) {
1408:                    if (attribClass != null) {
1409:                        if (attribClass.getStringValue().endsWith("long-edge")) {
1410:                            return Sides.TWO_SIDED_LONG_EDGE;
1411:                        } else if (attribClass.getStringValue().endsWith(
1412:                                "short-edge")) {
1413:                            return Sides.TWO_SIDED_SHORT_EDGE;
1414:                        }
1415:                    }
1416:                    return Sides.ONE_SIDED;
1417:                }
1418:
1419:                return null;
1420:            }
1421:
1422:            public ServiceUIFactory getServiceUIFactory() {
1423:                return null;
1424:            }
1425:
1426:            public void wakeNotifier() {
1427:                synchronized (this ) {
1428:                    if (notifier != null) {
1429:                        notifier.wake();
1430:                    }
1431:                }
1432:            }
1433:
1434:            public void addPrintServiceAttributeListener(
1435:                    PrintServiceAttributeListener listener) {
1436:                synchronized (this ) {
1437:                    if (listener == null) {
1438:                        return;
1439:                    }
1440:                    if (notifier == null) {
1441:                        notifier = new ServiceNotifier(this );
1442:                    }
1443:                    notifier.addListener(listener);
1444:                }
1445:            }
1446:
1447:            public void removePrintServiceAttributeListener(
1448:                    PrintServiceAttributeListener listener) {
1449:                synchronized (this ) {
1450:                    if (listener == null || notifier == null) {
1451:                        return;
1452:                    }
1453:                    notifier.removeListener(listener);
1454:                    if (notifier.isEmpty()) {
1455:                        notifier.stopNotifier();
1456:                        notifier = null;
1457:                    }
1458:                }
1459:            }
1460:
1461:            public String getName() {
1462:                return printer;
1463:            }
1464:
1465:            public boolean usesClass(Class c) {
1466:                return (c == sun.print.PSPrinterJob.class);
1467:            }
1468:
1469:            public static HttpURLConnection getIPPConnection(URL url) {
1470:                HttpURLConnection connection;
1471:                try {
1472:                    connection = (HttpURLConnection) url.openConnection();
1473:                } catch (java.io.IOException ioe) {
1474:                    return null;
1475:                }
1476:                if (!(connection instanceof  HttpURLConnection)) {
1477:                    return null;
1478:                }
1479:                connection.setUseCaches(false);
1480:                connection.setDefaultUseCaches(false);
1481:                connection.setDoInput(true);
1482:                connection.setDoOutput(true);
1483:                connection
1484:                        .setRequestProperty("Content-type", "application/ipp");
1485:                return connection;
1486:            }
1487:
1488:            public synchronized boolean isPostscript() {
1489:                if (isPS == null) {
1490:                    isPS = Boolean.TRUE;
1491:                    if (isCupsPrinter) {
1492:                        try {
1493:                            urlConnection = getIPPConnection(new URL("http://"
1494:                                    + CUPSPrinter.getServer() + ":"
1495:                                    + CUPSPrinter.getPort() + "/printers/"
1496:                                    + printer + ".ppd"));
1497:
1498:                            InputStream is = urlConnection.getInputStream();
1499:                            if (is != null) {
1500:                                BufferedReader d = new BufferedReader(
1501:                                        new InputStreamReader(is, Charset
1502:                                                .forName("ISO-8859-1")));
1503:                                String lineStr;
1504:                                while ((lineStr = d.readLine()) != null) {
1505:                                    if (lineStr.startsWith("*cupsFilter:")) {
1506:                                        isPS = Boolean.FALSE;
1507:                                        break;
1508:                                    }
1509:                                }
1510:                            }
1511:                        } catch (java.io.IOException e) {
1512:                        }
1513:                    }
1514:                }
1515:                return isPS.booleanValue();
1516:            }
1517:
1518:            private void opGetAttributes() {
1519:                try {
1520:                    debug_println(debugPrefix + "opGetAttributes myURI "
1521:                            + myURI + " myURL " + myURL);
1522:
1523:                    AttributeClass attClNoUri[] = {
1524:                            AttributeClass.ATTRIBUTES_CHARSET,
1525:                            AttributeClass.ATTRIBUTES_NATURAL_LANGUAGE };
1526:
1527:                    AttributeClass attCl[] = {
1528:                            AttributeClass.ATTRIBUTES_CHARSET,
1529:                            AttributeClass.ATTRIBUTES_NATURAL_LANGUAGE,
1530:                            new AttributeClass("printer-uri",
1531:                                    AttributeClass.TAG_URI, "" + myURI) };
1532:
1533:                    OutputStream os = (OutputStream) java.security.AccessController
1534:                            .doPrivileged(new java.security.PrivilegedAction() {
1535:                                public Object run() {
1536:                                    try {
1537:                                        return urlConnection.getOutputStream();
1538:                                    } catch (Exception e) {
1539:                                    }
1540:                                    return null;
1541:                                }
1542:                            });
1543:
1544:                    if (os == null) {
1545:                        return;
1546:                    }
1547:
1548:                    boolean success = (myURI == null) ? writeIPPRequest(os,
1549:                            OP_GET_ATTRIBUTES, attClNoUri) : writeIPPRequest(
1550:                            os, OP_GET_ATTRIBUTES, attCl);
1551:                    if (success) {
1552:                        InputStream is = null;
1553:                        if ((is = urlConnection.getInputStream()) != null) {
1554:                            HashMap[] responseMap = readIPPResponse(is);
1555:
1556:                            if (responseMap != null && responseMap.length > 0) {
1557:                                getAttMap = responseMap[0];
1558:                            }
1559:                        } else {
1560:                            debug_println(debugPrefix
1561:                                    + "opGetAttributes - null input stream");
1562:                        }
1563:                        is.close();
1564:                    }
1565:                    os.close();
1566:                } catch (java.io.IOException e) {
1567:                    debug_println(debugPrefix
1568:                            + "opGetAttributes - input/output stream: " + e);
1569:                }
1570:            }
1571:
1572:            public static boolean writeIPPRequest(OutputStream os,
1573:                    String operCode, AttributeClass[] attCl) {
1574:                OutputStreamWriter osw = new OutputStreamWriter(os);
1575:                char[] opCode = new char[2];
1576:                opCode[0] = (char) Byte.parseByte(operCode.substring(0, 2), 16);
1577:                opCode[1] = (char) Byte.parseByte(operCode.substring(2, 4), 16);
1578:                char[] bytes = { 0x01, 0x01, 0x00, 0x01 };
1579:                try {
1580:                    osw.write(bytes, 0, 2); // version number
1581:                    osw.write(opCode, 0, 2); // operation code
1582:                    bytes[0] = 0x00;
1583:                    bytes[1] = 0x00;
1584:                    osw.write(bytes, 0, 4); // request ID #1
1585:
1586:                    bytes[0] = 0x01; // operation-group-tag
1587:                    osw.write(bytes[0]);
1588:
1589:                    String valStr;
1590:                    char[] lenStr;
1591:
1592:                    AttributeClass ac;
1593:                    for (int i = 0; i < attCl.length; i++) {
1594:                        ac = attCl[i];
1595:                        osw.write(ac.getType()); // value tag
1596:
1597:                        lenStr = ac.getLenChars();
1598:                        osw.write(lenStr, 0, 2); // length
1599:                        osw.write("" + ac, 0, ac.getName().length());
1600:
1601:                        // check if string range (0x35 -> 0x49)
1602:                        if (ac.getType() >= AttributeClass.TAG_TEXT_LANGUAGE
1603:                                && ac.getType() <= AttributeClass.TAG_MIME_MEDIATYPE) {
1604:                            valStr = (String) ac.getObjectValue();
1605:                            bytes[0] = 0;
1606:                            bytes[1] = (char) valStr.length();
1607:                            osw.write(bytes, 0, 2);
1608:                            osw.write(valStr, 0, valStr.length());
1609:                        } // REMIND: need to support other value tags but for CUPS
1610:                        // string is all we need.
1611:                    }
1612:
1613:                    osw.write(GRPTAG_END_ATTRIBUTES);
1614:                    osw.flush();
1615:                    osw.close();
1616:                } catch (java.io.IOException ioe) {
1617:                    debug_println(debugPrefix
1618:                            + "IPPPrintService Exception in writeIPPRequest: "
1619:                            + ioe);
1620:                    return false;
1621:                }
1622:                return true;
1623:            }
1624:
1625:            public static HashMap[] readIPPResponse(InputStream inputStream) {
1626:
1627:                if (inputStream == null) {
1628:                    return null;
1629:                }
1630:
1631:                byte response[] = new byte[MAX_ATTRIBUTE_LENGTH];
1632:                try {
1633:
1634:                    DataInputStream ois = new DataInputStream(inputStream);
1635:
1636:                    // read status and ID
1637:                    if ((ois.read(response, 0, 8) > -1)
1638:                            && (response[2] == STATUSCODE_SUCCESS)) {
1639:
1640:                        ByteArrayOutputStream outObj;
1641:                        int counter = 0;
1642:                        short len = 0;
1643:                        String attribStr = null;
1644:                        // assign default value
1645:                        byte valTagByte = AttributeClass.TAG_KEYWORD;
1646:                        ArrayList respList = new ArrayList();
1647:                        HashMap responseMap = new HashMap();
1648:
1649:                        response[0] = ois.readByte();
1650:
1651:                        // check for group tags
1652:                        while ((response[0] >= GRPTAG_OP_ATTRIBUTES)
1653:                                && (response[0] <= GRPTAG_PRINTER_ATTRIBUTES)
1654:                                && (response[0] != GRPTAG_END_ATTRIBUTES)) {
1655:                            debug_println(debugPrefix
1656:                                    + "checking group tag,  response[0]= "
1657:                                    + response[0]);
1658:
1659:                            outObj = new ByteArrayOutputStream();
1660:                            //make sure counter and attribStr are re-initialized
1661:                            counter = 0;
1662:                            attribStr = null;
1663:
1664:                            // read value tag
1665:                            response[0] = ois.readByte();
1666:                            while (response[0] >= AttributeClass.TAG_INT
1667:                                    && response[0] <= AttributeClass.TAG_MEMBER_ATTRNAME) {
1668:                                // read name length
1669:                                len = ois.readShort();
1670:
1671:                                // If current value is not part of previous attribute 
1672:                                // then close stream and add it to HashMap.
1673:                                // It is part of previous attribute if name length=0.
1674:                                if ((len != 0) && (attribStr != null)) {
1675:                                    //last byte is the total # of values
1676:                                    outObj.write(counter);
1677:                                    outObj.flush();
1678:                                    outObj.close();
1679:                                    byte outArray[] = outObj.toByteArray();
1680:
1681:                                    // if key exists, new HashMap
1682:                                    if (responseMap.containsKey(attribStr)) {
1683:                                        respList.add(responseMap);
1684:                                        responseMap = new HashMap();
1685:                                    }
1686:                                    AttributeClass ac = new AttributeClass(
1687:                                            attribStr, valTagByte, outArray);
1688:
1689:                                    responseMap.put(ac.getName(), ac);
1690:
1691:                                    outObj = new ByteArrayOutputStream();
1692:                                    counter = 0; //reset counter
1693:                                }
1694:                                //check if this is new value tag
1695:                                if (counter == 0) {
1696:                                    valTagByte = response[0];
1697:                                }
1698:                                // read attribute name
1699:                                if (len != 0) {
1700:                                    // read "len" characters 
1701:                                    // make sure it doesn't exceed the maximum 
1702:                                    if (len > MAX_ATTRIBUTE_LENGTH) {
1703:                                        response = new byte[len]; // expand as needed
1704:                                    }
1705:                                    ois.read(response, 0, len);
1706:                                    attribStr = new String(response, 0, len);
1707:                                }
1708:                                // read value length
1709:                                len = ois.readShort();
1710:                                // write name length
1711:                                outObj.write(len);
1712:                                // read value, make sure it doesn't exceed the maximum 
1713:                                if (len > MAX_ATTRIBUTE_LENGTH) {
1714:                                    response = new byte[len]; // expand as needed
1715:                                }
1716:                                ois.read(response, 0, len);
1717:                                // write value of "len" length
1718:                                outObj.write(response, 0, len);
1719:                                counter++;
1720:                                // read next byte
1721:                                response[0] = ois.readByte();
1722:                            }
1723:
1724:                            if (attribStr != null) {
1725:                                outObj.write(counter);
1726:                                outObj.flush();
1727:                                outObj.close();
1728:
1729:                                // if key exists in old HashMap, new HashMap
1730:                                if ((counter != 0)
1731:                                        && responseMap.containsKey(attribStr)) {
1732:                                    respList.add(responseMap);
1733:                                    responseMap = new HashMap();
1734:                                }
1735:
1736:                                byte outArray[] = outObj.toByteArray();
1737:
1738:                                AttributeClass ac = new AttributeClass(
1739:                                        attribStr, valTagByte, outArray);
1740:                                responseMap.put(ac.getName(), ac);
1741:                            }
1742:                        }
1743:                        ois.close();
1744:                        if ((responseMap != null) && (responseMap.size() > 0)) {
1745:                            respList.add(responseMap);
1746:                        }
1747:                        return (HashMap[]) respList
1748:                                .toArray(new HashMap[respList.size()]);
1749:                    } else {
1750:                        debug_println(debugPrefix
1751:                                + "readIPPResponse client error, IPP status code-"
1752:                                + Integer.toHexString(response[2]) + " & "
1753:                                + Integer.toHexString(response[3]));
1754:                        return null;
1755:                    }
1756:
1757:                } catch (java.io.IOException e) {
1758:                    debug_println(debugPrefix + "readIPPResponse: " + e);
1759:                    return null;
1760:                }
1761:            }
1762:
1763:            public String toString() {
1764:                return "IPP Printer : " + getName();
1765:            }
1766:
1767:            public boolean equals(Object obj) {
1768:                return (obj == this  || (obj instanceof  IPPPrintService && ((IPPPrintService) obj)
1769:                        .getName().equals(getName())));
1770:            }
1771:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.