001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: /**
018: * @author Aleksei V. Ivaschenko
019: * @version $Revision: 1.2 $
020: */package org.apache.harmony.x.print;
021:
022: import java.util.HashMap;
023: import java.util.ArrayList;
024:
025: import javax.print.PrintService;
026: import javax.print.attribute.Attribute;
027: import javax.print.attribute.HashPrintServiceAttributeSet;
028: import javax.print.attribute.PrintServiceAttributeSet;
029: import javax.print.event.PrintServiceAttributeEvent;
030: import javax.print.event.PrintServiceAttributeListener;
031:
032: /*
033: * Unified class EventNotifier is used for notifying attribute
034: * listeners of print services about attribute events. There is
035: * only one instance of EventNotifier which can be used by any
036: * number print services. Generally, it is used by instances of
037: * DefaultPrintService class.
038: */
039: public class EventNotifier extends Thread {
040:
041: private static ArrayList services = new ArrayList();
042: private static HashMap listeners = new HashMap();
043: private static HashMap attributes = new HashMap();
044: private static EventNotifier notifier = new EventNotifier();
045: private boolean running = false;
046:
047: private EventNotifier() {
048: setPriority(Thread.NORM_PRIORITY);
049: setDaemon(true);
050: }
051:
052: /*
053: * This method returns the only instance of this class.
054: */
055: public static EventNotifier getNotifier() {
056: return notifier;
057: }
058:
059: /*
060: * Adds pair service - listener to the map of listeners.
061: * Added listener is notified as soon as any attribute
062: * event occurs in service.
063: */
064: public void addListener(PrintService service,
065: PrintServiceAttributeListener listener) {
066: if (service == null || listener == null) {
067: return;
068: }
069:
070: if (services.contains(service)) {
071: ArrayList serviceListeners = (ArrayList) listeners
072: .get(service);
073: serviceListeners.add(listener);
074: } else {
075: services.add(service);
076: ArrayList serviceListeners = new ArrayList();
077: serviceListeners.add(listener);
078: listeners.put(service, serviceListeners);
079: PrintServiceAttributeSet serviceAttributes = service
080: .getAttributes();
081: attributes.put(service, serviceAttributes);
082: }
083:
084: if (!running) {
085: start();
086: }
087: }
088:
089: /*
090: * Removes pair service - listener from the map of listeners.
091: * Removed listener never receive notifications again, except
092: * it is not added again.
093: */
094: public void removeListener(PrintService service,
095: PrintServiceAttributeListener listener) {
096: if (service == null || listener == null) {
097: return;
098: }
099:
100: if (services.contains(service)) {
101: ArrayList serviceListeners = (ArrayList) listeners
102: .get(service);
103: serviceListeners.remove(listener);
104: if (serviceListeners.size() == 0) {
105: listeners.remove(service);
106: attributes.remove(service);
107: services.remove(service);
108: }
109: }
110:
111: if (services.size() == 0) {
112: running = false;
113: }
114: }
115:
116: /*
117: * Stops event notifier. While event notifier is stopped,
118: * all added listeners do not receive any notifications.
119: */
120: public void Finish() {
121: running = false;
122: }
123:
124: /*
125: * Starts event notifier. Event notifier starts automatically
126: * when at least one listener added, and stops when all
127: * listeners removed.
128: */
129: public void run() {
130: try {
131: running = true;
132: while (running) {
133: Thread.sleep(1000);
134:
135: for (int i = 0; i < services.size(); i++) {
136: PrintService service = (PrintService) services
137: .get(i);
138: PrintServiceAttributeSet lastSet = (PrintServiceAttributeSet) attributes
139: .get(service);
140: PrintServiceAttributeSet newSet = service
141: .getAttributes();
142: if (!lastSet.equals(newSet)) {
143: PrintServiceAttributeSet updated = getUpdatedAttributeSet(
144: lastSet, newSet);
145: if (updated.size() > 0) {
146: PrintServiceAttributeEvent event = new PrintServiceAttributeEvent(
147: service, updated);
148: ArrayList serviceListeners = (ArrayList) listeners
149: .get(service);
150: for (int j = 0; j < serviceListeners.size(); j++) {
151: PrintServiceAttributeListener listener = (PrintServiceAttributeListener) serviceListeners
152: .get(j);
153: listener.attributeUpdate(event);
154: }
155: }
156: }
157: }
158: }
159: } catch (InterruptedException ie) {
160: // EventNotifier interrupted.
161: running = false;
162: }
163: }
164:
165: private PrintServiceAttributeSet getUpdatedAttributeSet(
166: PrintServiceAttributeSet oldSet,
167: PrintServiceAttributeSet newSet) {
168: Attribute[] newAttributes = newSet.toArray();
169: PrintServiceAttributeSet updated = new HashPrintServiceAttributeSet();
170: for (int i = 0; i < newAttributes.length; i++) {
171: if (!oldSet.containsValue(newAttributes[i])) {
172: updated.add(newAttributes[i]);
173: }
174: }
175: return updated;
176: }
177: }
|