1 /* CupsServer.java --
2    Copyright (C) 2006 Free Software Foundation, Inc.
3 
4 This file is part of GNU Classpath.
5 
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10 
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING.  If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
20 
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library.  Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
25 
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module.  An independent module is a module which is not derived from
33 or based on this library.  If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so.  If you do not wish to do so, delete this
36 exception statement from your version. */
37 
38 
39 package gnu.javax.print;
40 
41 import gnu.javax.print.ipp.IppException;
42 import gnu.javax.print.ipp.IppPrintService;
43 import gnu.javax.print.ipp.IppRequest;
44 import gnu.javax.print.ipp.IppResponse;
45 import gnu.javax.print.ipp.attribute.RequestedAttributes;
46 import gnu.javax.print.ipp.attribute.supported.PrinterUriSupported;
47 
48 import java.io.IOException;
49 import java.net.URI;
50 import java.net.URISyntaxException;
51 import java.util.ArrayList;
52 import java.util.List;
53 import java.util.Map;
54 import java.util.Set;
55 
56 /**
57  * <code>CupsServer</code> represents a host running a cups
58  * compatible server. It mainly consists of its URI and optional
59  * user and password combination if access is restricted.
60  * <p>
61  * It provides methods for retrival of valid CUPS printer uris
62  * that are used to construct IppPrintService objects.
63  * </p>
64  *
65  * @author Wolfgang Baer (WBaer@gmx.de)
66  */
67 public class CupsServer
68 {
69   /**
70    * The URI of the CUPS server.
71    * This is something like: http://localhost:631
72    */
73   private transient URI uri;
74 
75   /**
76    * The optional username.
77    */
78   private transient String username;
79 
80   /**
81    * The optional password for the user.
82    */
83   private transient String password;
84 
85   /**
86    * Creates a <code>CupsServer</code> object which
87    * tries to connect to a cups server.
88    *
89    * If <code>gnu.javax.print.server</code> is explicitly set, then
90    * that hostname will be used. Otherwise it will default to localhost.
91    *
92    * @param username the username
93    * @param password the password for the username.
94    */
CupsServer(String username, String password)95   public CupsServer(String username, String password)
96   {
97     this.username = username;
98     this.password = password;
99 
100     this.uri = null;
101     try
102       {
103         String serv = System.getProperty("gnu.javax.print.server");
104         if( serv != null )
105           this.uri = new URI("http://"+serv+":631");
106       }
107     catch(URISyntaxException use)
108       {
109         throw new RuntimeException("gnu.javax.print.CupsServer value is not a valid hostname.");
110       }
111     catch(SecurityException se)
112       {
113       }
114 
115     try
116       {
117         if( this.uri == null )
118           this.uri = new URI("http://localhost:631");
119       }
120     catch (URISyntaxException e)
121       {
122         // does not happen
123       }
124   }
125 
126   /**
127    * Creates a <code>CupsServer</code> object which
128    * tries to connect to a running cups server on the
129    * given URI.
130    *
131    * @param uri the URI of the server.
132    * @param username the username
133    * @param password the password for the username.
134    */
CupsServer(URI uri, String username, String password)135   public CupsServer(URI uri, String username, String password)
136   {
137     this.uri = uri;
138     this.username = username;
139     this.password = password;
140   }
141 
142   /**
143    * Requests the default printer from this CUPS server.
144    * This is always returned as IppPrintService.
145    *
146    * @return The default printer.
147    * @throws IppException if problems during request/response processing occur.
148    */
getDefaultPrinter()149   public IppPrintService getDefaultPrinter() throws IppException
150   {
151     IppResponse response = null;
152 
153     try
154       {
155         IppRequest request = new IppRequest(uri, username, password);
156         request.setOperationID((short)CupsIppOperation.CUPS_GET_DEFAULT);
157         request.setOperationAttributeDefaults();
158 
159         RequestedAttributes requestedAttrs
160          = new RequestedAttributes("printer-uri-supported");
161         request.addOperationAttribute(requestedAttrs);
162 
163         response = request.send();
164       }
165     catch (IOException e)
166       {
167         throw new IppException("IOException in IPP request/response.", e);
168       }
169 
170     Map printerAttributes = (Map) response.getPrinterAttributes().get(0);
171     Set uris = (Set) printerAttributes.get(PrinterUriSupported.class);
172     PrinterUriSupported uri = (PrinterUriSupported) uris.toArray()[0];
173 
174     IppPrintService service
175       = new CupsPrintService(uri.getURI(), username, password);
176 
177     return service;
178   }
179 
180   /**
181    * Requests all printers from this CUPS server.
182    *
183    * @return The list of available printers.
184    * @throws IppException if problems during request/response processing occur.
185    */
getAllPrinters()186   public List getAllPrinters() throws IppException
187   {
188     IppResponse response = null;
189 
190     try
191       {
192         IppRequest request = new IppRequest(uri, username, password);
193         request.setOperationID((short)CupsIppOperation.CUPS_GET_PRINTERS);
194         request.setOperationAttributeDefaults();
195 
196         RequestedAttributes requestedAttrs
197           = new RequestedAttributes("printer-uri-supported");
198         request.addOperationAttribute(requestedAttrs);
199 
200         response = request.send();
201       }
202     catch (IOException e)
203       {
204         throw new IppException("IOException in IPP request/response.", e);
205       }
206 
207     List prAttr = response.getPrinterAttributes();
208     List services = new ArrayList();
209 
210     for (int i=0; i < prAttr.size(); i++)
211       {
212         Map printerAttributes = (Map) prAttr.get(i);
213         Set uris = (Set) printerAttributes.get(PrinterUriSupported.class);
214         PrinterUriSupported uri = (PrinterUriSupported) uris.toArray()[0];
215 
216         try
217           {
218             CupsPrintService cups = new CupsPrintService(uri.getURI(),
219                                                          username, password);
220             services.add(cups);
221           }
222         catch (IppException e)
223           {
224             // do nothing, we only catch the IppException which could be
225             // thrown during instantiation as single printers may be discovered
226             // correctly but not usable due to other security restrictions
227           }
228       }
229 
230     return services;
231   }
232 
233   /**
234    * Requests all classes from this CUPS server. Classes in cups are
235    * collections of printers. This means jobs directed to a class
236    * are forwarded to the first available printer of the collection.
237    *
238    * @return The list of available classes.
239    * @throws IppException if problems during request/response processing occur.
240    */
getAllClasses()241   public List getAllClasses() throws IppException
242   {
243     IppResponse response = null;
244 
245     try
246       {
247         IppRequest request = new IppRequest(uri, username, password);
248         request.setOperationID((short)CupsIppOperation.CUPS_GET_CLASSES);
249         request.setOperationAttributeDefaults();
250 
251         RequestedAttributes requestedAttrs
252           = new RequestedAttributes("printer-uri-supported");
253         request.addOperationAttribute(requestedAttrs);
254 
255         response = request.send();
256       }
257     catch (IOException e)
258       {
259         throw new IppException("IOException in IPP request/response.", e);
260       }
261 
262     List prAttr = response.getPrinterAttributes();
263     List services = new ArrayList();
264 
265     for (int i=0; i < prAttr.size(); i++)
266       {
267         Map printerAttributes = (Map) prAttr.get(i);
268         Set uris = (Set) printerAttributes.get(PrinterUriSupported.class);
269         PrinterUriSupported uri = (PrinterUriSupported) uris.toArray()[0];
270 
271         try
272           {
273             CupsPrintService cups = new CupsPrintService(uri.getURI(),
274                                                          username, password);
275             services.add(cups);
276           }
277         catch (IppException e)
278           {
279             // do nothing, we only catch the IppException which could be
280             // thrown during instantiation as single printers may be discovered
281             // correctly but not usable due to other security restrictions
282           }
283       }
284 
285     return services;
286   }
287 
288 }
289