1d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/**
2d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * $RCSfile$
3d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * $Revision$
4d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * $Date$
5d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen *
6d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Copyright 2003-2007 Jive Software.
7d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen *
8d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
9d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * you may not use this file except in compliance with the License.
10d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * You may obtain a copy of the License at
11d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen *
12d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen *     http://www.apache.org/licenses/LICENSE-2.0
13d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen *
14d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Unless required by applicable law or agreed to in writing, software
15d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * distributed under the License is distributed on an "AS IS" BASIS,
16d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * See the License for the specific language governing permissions and
18d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * limitations under the License.
19d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */
20d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
21d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpackage org.jivesoftware.smack.util;
22d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
23d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.io.*;
24d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.util.*;
25d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
26d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/**
27d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * An ObservableReader is a wrapper on a Reader that notifies to its listeners when
28d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * reading character streams.
29d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen *
30d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @author Gaston Dombiak
31d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */
32d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic class ObservableReader extends Reader {
33d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
34d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    Reader wrappedReader = null;
35d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    List<ReaderListener> listeners = new ArrayList<ReaderListener>();
36d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
37d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public ObservableReader(Reader wrappedReader) {
38d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        this.wrappedReader = wrappedReader;
39d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
40d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
41d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public int read(char[] cbuf, int off, int len) throws IOException {
42d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        int count = wrappedReader.read(cbuf, off, len);
43d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        if (count > 0) {
44d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            String str = new String(cbuf, off, count);
45d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            // Notify that a new string has been read
46d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            ReaderListener[] readerListeners = null;
47d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            synchronized (listeners) {
48d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                readerListeners = new ReaderListener[listeners.size()];
49d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                listeners.toArray(readerListeners);
50d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            }
51d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            for (int i = 0; i < readerListeners.length; i++) {
52d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                readerListeners[i].read(str);
53d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            }
54d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
55d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        return count;
56d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
57d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
58d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public void close() throws IOException {
59d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        wrappedReader.close();
60d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
61d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
62d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public int read() throws IOException {
63d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        return wrappedReader.read();
64d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
65d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
66d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public int read(char cbuf[]) throws IOException {
67d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        return wrappedReader.read(cbuf);
68d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
69d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
70d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public long skip(long n) throws IOException {
71d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        return wrappedReader.skip(n);
72d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
73d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
74d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public boolean ready() throws IOException {
75d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        return wrappedReader.ready();
76d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
77d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
78d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public boolean markSupported() {
79d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        return wrappedReader.markSupported();
80d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
81d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
82d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public void mark(int readAheadLimit) throws IOException {
83d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        wrappedReader.mark(readAheadLimit);
84d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
85d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
86d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public void reset() throws IOException {
87d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        wrappedReader.reset();
88d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
89d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
90d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
91d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Adds a reader listener to this reader that will be notified when
92d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * new strings are read.
93d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
94d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @param readerListener a reader listener.
95d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
96d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public void addReaderListener(ReaderListener readerListener) {
97d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        if (readerListener == null) {
98d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            return;
99d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
100d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        synchronized (listeners) {
101d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            if (!listeners.contains(readerListener)) {
102d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen                listeners.add(readerListener);
103d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            }
104d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
105d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
106d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
107d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    /**
108d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * Removes a reader listener from this reader.
109d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     *
110d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     * @param readerListener a reader listener.
111d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen     */
112d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    public void removeReaderListener(ReaderListener readerListener) {
113d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        synchronized (listeners) {
114d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen            listeners.remove(readerListener);
115d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen        }
116d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen    }
117d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
118d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen}
119