mirror of
https://github.com/2003scape/deep-c-rsc.git
synced 2024-03-22 05:49:51 -04:00
477 lines
18 KiB
Java
477 lines
18 KiB
Java
/*
|
|
* This file is modified by Ivan Maidanski <ivmai@ivmaisoft.com>
|
|
* Project name: JCGO-SUNAWT (http://www.ivmaisoft.com/jcgo/)
|
|
**
|
|
* Comment: contains x11-specific fixes.
|
|
*/
|
|
|
|
/*
|
|
* @(#)PrintServiceLookup.java 1.13 03/01/23
|
|
*
|
|
* Copyright 2003 Sun Microsystems, Inc. All rights reserved.
|
|
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
|
*/
|
|
|
|
|
|
package javax.print;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.Iterator;
|
|
import java.util.List;
|
|
import javax.print.attribute.AttributeSet;
|
|
|
|
import sun.awt.AppContext;
|
|
import sun.misc.Service;
|
|
|
|
/** Implementations of this class provide lookup services for
|
|
* print services (typically equivalent to printers) of a particular type.
|
|
* <p>
|
|
* Multiple implementations may be installed concurrently.
|
|
* All implementations must be able to describe the located printers
|
|
* as instances of a PrintService.
|
|
* Typically implementations of this service class are located
|
|
* automatically in JAR files (see the SPI JAR file specification).
|
|
* These classes must be instantiable using a default constructor.
|
|
* Alternatively applications may explicitly register instances
|
|
* at runtime.
|
|
* <p>
|
|
* Applications use only the static methods of this abstract class.
|
|
* The instance methods are implemented by a service provider in a subclass
|
|
* and the unification of the results from all installed lookup classes
|
|
* are reported by the static methods of this class when called by
|
|
* the application.
|
|
* <p>
|
|
* A PrintServiceLookup implementor is recommended to check for the
|
|
* SecurityManager.checkPrintJobAccess() to deny access to untrusted code.
|
|
* Following this recommended policy means that untrusted code may not
|
|
* be able to locate any print services. Downloaded applets are the most
|
|
* common example of untrusted code.
|
|
* <p>
|
|
* This check is made on a per lookup service basis to allow flexibility in
|
|
* the policy to reflect the needs of different lookup services.
|
|
* <p>
|
|
* Services which are registered by registerService(PrintService)
|
|
* will not be included in lookup results if a security manager is
|
|
* installed and its checkPrintJobAccess() method denies access.
|
|
*/
|
|
|
|
public abstract class PrintServiceLookup {
|
|
|
|
static class Services {
|
|
private ArrayList listOfLookupServices = null;
|
|
private ArrayList registeredServices = null;
|
|
}
|
|
|
|
private static Services getServicesForContext() {
|
|
Services services =
|
|
(Services)AppContext.getAppContext().get(Services.class);
|
|
if (services == null) {
|
|
services = new Services();
|
|
AppContext.getAppContext().put(Services.class, services);
|
|
}
|
|
return services;
|
|
}
|
|
|
|
private static ArrayList getListOfLookupServices() {
|
|
return getServicesForContext().listOfLookupServices;
|
|
}
|
|
|
|
private static ArrayList initListOfLookupServices() {
|
|
ArrayList listOfLookupServices = new ArrayList();
|
|
getServicesForContext().listOfLookupServices = listOfLookupServices;
|
|
return listOfLookupServices;
|
|
}
|
|
|
|
|
|
private static ArrayList getRegisteredServices() {
|
|
return getServicesForContext().registeredServices;
|
|
}
|
|
|
|
private static ArrayList initRegisteredServices() {
|
|
ArrayList registeredServices = new ArrayList();
|
|
getServicesForContext().registeredServices = registeredServices;
|
|
return registeredServices;
|
|
}
|
|
|
|
/**
|
|
* Locates print services capable of printing the specified
|
|
* {@link DocFlavor}.
|
|
*
|
|
* @param flavor the flavor to print. If null, this constraint is not
|
|
* used.
|
|
* @param attributes attributes that the print service must support.
|
|
* If null this constraint is not used.
|
|
*
|
|
* @return array of matching <code>PrintService</code> objects
|
|
* representing print services that support the specified flavor
|
|
* attributes. If no services match, the array is zero-length.
|
|
*/
|
|
public static final PrintService[]
|
|
lookupPrintServices(DocFlavor flavor,
|
|
AttributeSet attributes) {
|
|
ArrayList list = getServices(flavor, attributes);
|
|
return (PrintService[])(list.toArray(new PrintService[list.size()]));
|
|
}
|
|
|
|
|
|
/**
|
|
* Locates MultiDoc print Services capable of printing MultiDocs
|
|
* containing all the specified doc flavors.
|
|
* <P> This method is useful to help locate a service that can print
|
|
* a <code>MultiDoc</code> in which the elements may be different
|
|
* flavors. An application could perform this itself by multiple lookups
|
|
* on each <code>DocFlavor</code> in turn and collating the results,
|
|
* but the lookup service may be able to do this more efficiently.
|
|
*
|
|
* @param flavors the flavors to print. If null or empty this
|
|
* constraint is not used.
|
|
* Otherwise return only multidoc print services that can print all
|
|
* specified doc flavors.
|
|
* @param attributes attributes that the print service must
|
|
* support. If null this constraint is not used.
|
|
*
|
|
* @return array of matching {@link MultiDocPrintService} objects.
|
|
* If no services match, the array is zero-length.
|
|
*
|
|
*/
|
|
public static final MultiDocPrintService[]
|
|
lookupMultiDocPrintServices(DocFlavor[] flavors,
|
|
AttributeSet attributes) {
|
|
ArrayList list = getMultiDocServices(flavors, attributes);
|
|
return (MultiDocPrintService[])
|
|
list.toArray(new MultiDocPrintService[list.size()]);
|
|
}
|
|
|
|
|
|
/**
|
|
* Locates the default print service for this environment.
|
|
* This may return null.
|
|
* If multiple lookup services each specify a default, the
|
|
* chosen service is not precisely defined, but a
|
|
* platform native service, rather than an installed service,
|
|
* is usually returned as the default. If there is no clearly
|
|
* identifiable
|
|
* platform native default print service, the default is the first
|
|
* to be located in an implementation-dependent manner.
|
|
* <p>
|
|
* This may include making use of any preferences API that is available
|
|
* as part of the Java or native platform.
|
|
* This algorithm may be overridden by a user setting the property
|
|
* javax.print.defaultPrinter.
|
|
* A service specified must be discovered to be valid and currently
|
|
* available to be returned as the default.
|
|
*
|
|
* @return the default PrintService.
|
|
*/
|
|
|
|
public static final PrintService lookupDefaultPrintService() {
|
|
|
|
Iterator psIterator = getAllLookupServices().iterator();
|
|
while (psIterator.hasNext()) {
|
|
try {
|
|
PrintServiceLookup lus = (PrintServiceLookup)psIterator.next();
|
|
PrintService service = lus.getDefaultPrintService();
|
|
if (service != null) {
|
|
return service;
|
|
}
|
|
} catch (Exception e) {
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
|
|
/**
|
|
* Allows an application to explicitly register a class that
|
|
* implements lookup services. The registration will not persist
|
|
* across VM invocations.
|
|
* This is useful if an application needs to make a new service
|
|
* available that is not part of the installation.
|
|
* If the lookup service is already registered, or cannot be registered,
|
|
* the method returns false.
|
|
* <p>
|
|
*
|
|
* @param sp an implementation of a lookup service.
|
|
* @return <code>true</code> if the new lookup service is newly
|
|
* registered; <code>false</code> otherwise.
|
|
*/
|
|
public static boolean registerServiceProvider(PrintServiceLookup sp) {
|
|
synchronized (PrintServiceLookup.class) {
|
|
Iterator psIterator = getAllLookupServices().iterator();
|
|
while (psIterator.hasNext()) {
|
|
try {
|
|
Object lus = psIterator.next();
|
|
if (lus.getClass() == sp.getClass()) {
|
|
return false;
|
|
}
|
|
} catch (Exception e) {
|
|
}
|
|
}
|
|
getListOfLookupServices().add(sp);
|
|
return true;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
* Allows an application to directly register an instance of a
|
|
* class which implements a print service.
|
|
* The lookup operations for this service will be
|
|
* performed by the PrintServiceLookup class using the attribute
|
|
* values and classes reported by the service.
|
|
* This may be less efficient than a lookup
|
|
* service tuned for that service.
|
|
* Therefore registering a <code>PrintServiceLookup</code> instance
|
|
* instead is recommended.
|
|
* The method returns true if this service is not previously
|
|
* registered and is now successfully registered.
|
|
* This method should not be called with StreamPrintService instances.
|
|
* They will always fail to register and the method will return false.
|
|
* @param service an implementation of a print service.
|
|
* @return <code>true</code> if the service is newly
|
|
* registered; <code>false</code> otherwise.
|
|
*/
|
|
|
|
public static boolean registerService(PrintService service) {
|
|
synchronized (PrintServiceLookup.class) {
|
|
if (service instanceof StreamPrintService) {
|
|
return false;
|
|
}
|
|
ArrayList registeredServices = getRegisteredServices();
|
|
if (registeredServices == null) {
|
|
registeredServices = initRegisteredServices();
|
|
}
|
|
else {
|
|
if (registeredServices.contains(service)) {
|
|
return false;
|
|
}
|
|
}
|
|
registeredServices.add(service);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Locates services that can be positively confirmed to support
|
|
* the combination of attributes and DocFlavors specified.
|
|
* This method is not called directly by applications.
|
|
* <p>
|
|
* Implemented by a service provider, used by the static methods
|
|
* of this class.
|
|
* <p>
|
|
* The results should be the same as obtaining all the PrintServices
|
|
* and querying each one individually on its support for the
|
|
* specified attributes and flavors, but the process can be more
|
|
* efficient by taking advantage of the capabilities of lookup services
|
|
* for the print services.
|
|
*
|
|
* @param flavor of document required. If null it is ignored.
|
|
* @param attributes required to be supported. If null this
|
|
* constraint is not used.
|
|
* @return array of matching PrintServices. If no services match, the
|
|
* array is zero-length.
|
|
*/
|
|
public abstract PrintService[] getPrintServices(DocFlavor flavor,
|
|
AttributeSet attributes);
|
|
|
|
/**
|
|
* Not called directly by applications.
|
|
* Implemented by a service provider, used by the static methods
|
|
* of this class.
|
|
* @return array of all PrintServices known to this lookup service
|
|
* class. If none are found, the array is zero-length.
|
|
*/
|
|
public abstract PrintService[] getPrintServices() ;
|
|
|
|
|
|
/**
|
|
* Not called directly by applications.
|
|
* <p>
|
|
* Implemented by a service provider, used by the static methods
|
|
* of this class.
|
|
* <p>
|
|
* Locates MultiDoc print services which can be positively confirmed
|
|
* to support the combination of attributes and DocFlavors specified.
|
|
* <p>
|
|
*
|
|
* @param flavors of documents required. If null or empty it is ignored.
|
|
* @param attributes required to be supported. If null this
|
|
* constraint is not used.
|
|
* @return array of matching PrintServices. If no services match, the
|
|
* array is zero-length.
|
|
*/
|
|
public abstract MultiDocPrintService[]
|
|
getMultiDocPrintServices(DocFlavor[] flavors,
|
|
AttributeSet attributes);
|
|
|
|
/**
|
|
* Not called directly by applications.
|
|
* Implemented by a service provider, and called by the print lookup
|
|
* service
|
|
* @return the default PrintService for this lookup service.
|
|
* If there is no default, returns null.
|
|
*/
|
|
public abstract PrintService getDefaultPrintService();
|
|
|
|
private static ArrayList getAllLookupServices() {
|
|
synchronized (PrintServiceLookup.class) {
|
|
ArrayList listOfLookupServices = getListOfLookupServices();
|
|
if (listOfLookupServices != null) {
|
|
return listOfLookupServices;
|
|
} else {
|
|
listOfLookupServices = initListOfLookupServices();
|
|
}
|
|
try {
|
|
java.security.AccessController.doPrivileged(
|
|
new java.security.PrivilegedExceptionAction() {
|
|
public Object run() {
|
|
Iterator iterator =
|
|
Service.providers(PrintServiceLookup.class);
|
|
ArrayList los = getListOfLookupServices();
|
|
while (iterator.hasNext()) {
|
|
try {
|
|
PrintServiceLookup lus =
|
|
(PrintServiceLookup)iterator.next();
|
|
los.add(lus);
|
|
} catch (Exception e) {
|
|
}
|
|
}
|
|
if (los.isEmpty())
|
|
los.add(new sun.print.UnixPrintServiceLookup());
|
|
return null;
|
|
}
|
|
});
|
|
} catch (java.security.PrivilegedActionException e) {
|
|
}
|
|
|
|
return listOfLookupServices;
|
|
}
|
|
}
|
|
|
|
private static ArrayList getServices(DocFlavor flavor,
|
|
AttributeSet attributes) {
|
|
|
|
ArrayList listOfServices = new ArrayList();
|
|
Iterator psIterator = getAllLookupServices().iterator();
|
|
while (psIterator.hasNext()) {
|
|
try {
|
|
PrintServiceLookup lus = (PrintServiceLookup)psIterator.next();
|
|
PrintService[] services=null;
|
|
if (flavor == null && attributes == null) {
|
|
try {
|
|
services = lus.getPrintServices();
|
|
} catch (ThreadDeath death) {
|
|
throw death;
|
|
} catch (Throwable tr) {
|
|
}
|
|
} else {
|
|
services = lus.getPrintServices(flavor, attributes);
|
|
}
|
|
if (services == null) {
|
|
continue;
|
|
}
|
|
for (int i=0; i<services.length; i++) {
|
|
listOfServices.add(services[i]);
|
|
}
|
|
} catch (Exception e) {
|
|
}
|
|
}
|
|
/* add any directly registered services */
|
|
ArrayList registeredServices = null;
|
|
try {
|
|
SecurityManager security = System.getSecurityManager();
|
|
if (security != null) {
|
|
security.checkPrintJobAccess();
|
|
}
|
|
registeredServices = getRegisteredServices();
|
|
} catch (SecurityException se) {
|
|
}
|
|
if (registeredServices != null) {
|
|
PrintService[] services = (PrintService[])
|
|
registeredServices.toArray(
|
|
new PrintService[registeredServices.size()]);
|
|
for (int i=0; i<services.length; i++) {
|
|
if (!listOfServices.contains(services[i])) {
|
|
if (flavor == null && attributes == null) {
|
|
listOfServices.add(services[i]);
|
|
} else if (((flavor != null &&
|
|
services[i].isDocFlavorSupported(flavor)) ||
|
|
flavor == null) &&
|
|
null == services[i].getUnsupportedAttributes(
|
|
flavor, attributes)) {
|
|
listOfServices.add(services[i]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return listOfServices;
|
|
}
|
|
|
|
private static ArrayList getMultiDocServices(DocFlavor[] flavors,
|
|
AttributeSet attributes) {
|
|
|
|
|
|
ArrayList listOfServices = new ArrayList();
|
|
Iterator psIterator = getAllLookupServices().iterator();
|
|
while (psIterator.hasNext()) {
|
|
try {
|
|
PrintServiceLookup lus = (PrintServiceLookup)psIterator.next();
|
|
MultiDocPrintService[] services =
|
|
lus.getMultiDocPrintServices(flavors, attributes);
|
|
if (services == null) {
|
|
continue;
|
|
}
|
|
for (int i=0; i<services.length; i++) {
|
|
listOfServices.add(services[i]);
|
|
}
|
|
} catch (Exception e) {
|
|
}
|
|
}
|
|
/* add any directly registered services */
|
|
ArrayList registeredServices = null;
|
|
try {
|
|
SecurityManager security = System.getSecurityManager();
|
|
if (security != null) {
|
|
security.checkPrintJobAccess();
|
|
}
|
|
registeredServices = getRegisteredServices();
|
|
} catch (Exception e) {
|
|
}
|
|
if (registeredServices != null) {
|
|
PrintService[] services = (PrintService[])
|
|
registeredServices.toArray(
|
|
new PrintService[registeredServices.size()]);
|
|
for (int i=0; i<services.length; i++) {
|
|
if (services[i] instanceof MultiDocPrintService &&
|
|
!listOfServices.contains(services[i])) {
|
|
if (flavors == null || flavors.length == 0) {
|
|
listOfServices.add(services[i]);
|
|
} else {
|
|
boolean supported = true;
|
|
for (int f=0; f<flavors.length; f++) {
|
|
if (services[i].isDocFlavorSupported(flavors[f])) {
|
|
|
|
if (services[i].getUnsupportedAttributes(
|
|
flavors[f], attributes) != null) {
|
|
supported = false;
|
|
break;
|
|
}
|
|
} else {
|
|
supported = false;
|
|
break;
|
|
}
|
|
}
|
|
if (supported) {
|
|
listOfServices.add(services[i]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return listOfServices;
|
|
}
|
|
|
|
}
|