EMMA Coverage Report (generated Tue Apr 17 08:51:20 BST 2007)
[all classes][org.jtoolkit.essence.app.net]

COVERAGE SUMMARY FOR SOURCE FILE [DataSocket.java]

nameclass, %method, %block, %line, %
DataSocket.java100% (3/3)81%  (21/26)78%  (368/471)88%  (100.7/115)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class DataSocket100% (1/1)80%  (12/15)70%  (190/272)87%  (50.7/58)
getOtherName (): String 0%   (0/1)0%   (0/3)0%   (0/1)
getOtherProperties (): Map 0%   (0/1)0%   (0/3)0%   (0/1)
getOtherProtocol (): String 0%   (0/1)0%   (0/3)0%   (0/1)
debugConnection (String, Map): void 100% (1/1)19%  (4/21)67%  (2/3)
getIn (): DataInputStream 100% (1/1)25%  (5/20)67%  (2/3)
getOut (): DataOutputStream 100% (1/1)35%  (8/23)75%  (3/4)
finalize (): void 100% (1/1)75%  (6/8)90%  (2.7/3)
DataSocket (String, String, Socket, Map): void 100% (1/1)84%  (130/154)96%  (27/28)
<static initializer> 100% (1/1)100% (4/4)100% (1/1)
close (): void 100% (1/1)100% (16/16)100% (6/6)
closing (): void 100% (1/1)100% (4/4)100% (2/2)
getName (): String 100% (1/1)100% (3/3)100% (1/1)
isClosed (): boolean 100% (1/1)100% (3/3)100% (1/1)
isClosing (): boolean 100% (1/1)100% (3/3)100% (1/1)
setObjectName (ObjectName): void 100% (1/1)100% (4/4)100% (2/2)
     
class DataSocket$BlockedInflatorInputStream100% (1/1)83%  (5/6)86%  (92/107)87%  (26/30)
read (byte []): int 0%   (0/1)0%   (0/15)0%   (0/4)
DataSocket$BlockedInflatorInputStream (DataInputStream): void 100% (1/1)100% (12/12)100% (5/5)
available (): int 100% (1/1)100% (3/3)100% (1/1)
checkIn2 (): void 100% (1/1)100% (48/48)100% (13/13)
read (): int 100% (1/1)100% (12/12)100% (3/3)
read (byte [], int, int): int 100% (1/1)100% (17/17)100% (4/4)
     
class DataSocket$BlockedDeflatorOutputStream100% (1/1)80%  (4/5)93%  (86/92)89%  (24/27)
close (): void 0%   (0/1)0%   (0/6)0%   (0/3)
DataSocket$BlockedDeflatorOutputStream (DataOutputStream): void 100% (1/1)100% (11/11)100% (4/4)
flush (): void 100% (1/1)100% (63/63)100% (16/16)
write (byte [], int, int): void 100% (1/1)100% (7/7)100% (2/2)
write (int): void 100% (1/1)100% (5/5)100% (2/2)

1package org.jtoolkit.essence.app.net;
2 
3import org.apache.commons.logging.Log;
4import static org.apache.commons.logging.LogFactory.getLog;
5import org.jetbrains.annotations.NotNull;
6import static org.jtoolkit.essence.app.Main.unregisterComponent;
7import org.jtoolkit.essence.app.pojo.DatableUtils;
8import org.jtoolkit.essence.app.pojo.impl.DataValueClass;
9import org.jtoolkit.essence.app.Container;
10import org.jtoolkit.essence.concurrency.NotThreadSafe;
11import org.jtoolkit.essence.utils.Closeable;
12import org.jtoolkit.essence.utils.IOUtils;
13import org.jtoolkit.essence.utils.Named;
14import org.jtoolkit.essence.utils.RWLock;
15 
16import javax.management.ObjectName;
17import java.io.*;
18import java.net.Socket;
19import java.util.Map;
20import java.util.zip.DeflaterOutputStream;
21import java.util.zip.InflaterInputStream;
22 
23/*
24   Copyright 2006 Peter Lawrey
25 
26   Licensed under the Apache License, Version 2.0 (the "License");
27   you may not use this file except in compliance with the License.
28   You may obtain a copy of the License at
29 
30       http://www.apache.org/licenses/LICENSE-2.0
31 
32   Unless required by applicable law or agreed to in writing, software
33   distributed under the License is distributed on an &quot;AS IS&quot; BASIS,
34   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
35   See the License for the specific language governing permissions and
36   limitations under the License.
37*/
38 
39/**
40 * A Socket with DataInput and DataOutput streams.
41 *
42 * @author Peter Lawrey
43 */
44@NotThreadSafe
45public class DataSocket implements Named, Closeable {
46    private static final Log LOG = getLog(DataSocket.class);
47    private static final String PROTOCOL = "DataSocket v1.0";
48    private static final int BUFFER_SIZE = 32 * 1024;
49 
50    private static final String NAME = "name";
51    public static final String IS_COMPRESSED = "compressed";
52    public static final char BYE = (char) 0; // Good-bye.
53 
54    private final String name;
55    private final Socket socket;
56    private final DataInputStream in;
57    private final DataOutputStream out;
58    public final String otherName;
59    private final String otherProtocol;
60 
61    private final Map<String, String> otherProperties;
62 
63    private boolean closing = false;
64    private boolean closed = false;
65    @SuppressWarnings({"FieldHasSetterButNoGetter"})
66    private ObjectName objectName = null;
67 
68    /**
69     * Wrap a Socket as  DataSocket.
70     */
71    public DataSocket(@NotNull String containerName, @NotNull String name, @NotNull Socket socket, @NotNull Map<String, String> properties) throws IOException {
72        this.name = name;
73        this.socket = socket;
74 
75        socket.setSendBufferSize(BUFFER_SIZE);
76        socket.setReceiveBufferSize(BUFFER_SIZE);
77 
78        DataOutputStream out = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream(), BUFFER_SIZE));
79        out.writeUTF(PROTOCOL);
80        properties.put(Container.DEFAULT_CONTAINER_NAME, containerName);
81        properties.put(NAME, name);
82        out.writeUTF(properties.toString());
83        out.flush();
84 
85        DataInputStream in = new DataInputStream(new BufferedInputStream(socket.getInputStream(), BUFFER_SIZE));
86        otherProtocol = in.readUTF();
87        otherProperties = DataValueClass.parseMap(in.readUTF());
88        otherName = otherProperties.get(NAME);
89        if (!PROTOCOL.equals(otherProtocol))
90            LOG.warn(name + ": Connection " + otherName + " has protocol '" + otherProtocol + "' locally '" + PROTOCOL + '\'');
91 
92        if (Boolean.parseBoolean(properties.get(IS_COMPRESSED)) || Boolean.parseBoolean(otherProperties.get(IS_COMPRESSED))) {
93            debugConnection("Compressed", properties);
94            this.out = new DataOutputStream(new BlockedDeflatorOutputStream(out));
95            this.in = new DataInputStream(new BlockedInflatorInputStream(in));
96        } else {
97            debugConnection("Plain", properties);
98            this.out = out;
99            this.in = in;
100        }
101    }
102 
103    private void debugConnection(String type, Map<String, String> properties) {
104        if (LOG.isDebugEnabled())
105            LOG.debug(type+" connection, properties=" + properties + ", otherProperties=" + otherProperties);
106    }
107 
108    public DataInputStream getIn() {
109        if (RWLock.isDebug())
110            RWLock.checkUnlocked("read from " + name + ' ' + objectName);
111        return in;
112    }
113 
114    public DataOutputStream getOut() {
115        if (RWLock.isDebug())
116            RWLock.checkUnlocked("write to " + name + ' ' + objectName);
117        DatableUtils.prune(out);
118        return out;
119    }
120 
121    public boolean isClosing() {
122        return closing;
123    }
124 
125    public boolean isClosed() {
126        return closed;
127    }
128 
129    public void closing() {
130        closing = true;
131    }
132 
133    public void close() {
134        closed = true;
135        IOUtils.close(in);
136        IOUtils.close(socket);
137        IOUtils.close(out);
138        unregisterComponent(objectName);
139    }
140 
141    @Override protected void finalize() throws Throwable {
142        super.finalize();
143        if (!closed) close();
144    }
145 
146    @NotNull public String getName() {
147        return name;
148    }
149 
150    public String getOtherName() {
151        return otherName;
152    }
153 
154    public String getOtherProtocol() {
155        return otherProtocol;
156    }
157 
158    public Map<String, String> getOtherProperties() {
159        return otherProperties;
160    }
161 
162    /**
163     * @param objectName The JMX ObjectName so the component can be removed on a close.
164     */
165    public void setObjectName(ObjectName objectName) {
166        this.objectName = objectName;
167    }
168 
169    static class BlockedDeflatorOutputStream extends OutputStream {
170        private static final int MIN_LENGTH = 512;
171        private final DataOutputStream out;
172        private final ByteArrayOutputStream baos = new ByteArrayOutputStream();
173 
174        BlockedDeflatorOutputStream(DataOutputStream out) {
175            this.out = out;
176        }
177 
178        public void write(int b) throws IOException {
179            baos.write(b);
180        }
181 
182        public void write(byte[] bytes, int off, int len) throws IOException {
183            baos.write(bytes, off, len);
184        }
185 
186        public void flush() throws IOException {
187            byte[] bytes = baos.toByteArray();
188            if (bytes.length < MIN_LENGTH) {
189                // bytes to read.
190                out.writeInt(bytes.length);
191                out.writeInt(bytes.length);
192                out.write(bytes);
193            } else {
194                ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
195                DeflaterOutputStream dos = new DeflaterOutputStream(baos2);
196                dos.write(bytes);
197                dos.close();
198//                int count = bytes.length;
199                out.writeInt(bytes.length);
200                byte[] bytes1 = baos2.toByteArray();
201                // bytes to read.
202                out.writeInt(~bytes1.length);
203                out.write(bytes1);
204//                System.out.println("Flush " + bytes.length + " was " + count);
205            }
206            out.flush();
207            baos.reset();
208        }
209 
210        public void close() throws IOException {
211            flush();
212            IOUtils.close(out);
213        }
214    }
215 
216    static class BlockedInflatorInputStream extends InputStream {
217        private final DataInputStream in;
218        private InputStream in2 = null;
219        private int available = 0;
220 
221        BlockedInflatorInputStream(DataInputStream in) {
222            this.in = in;
223        }
224 
225        public int read(byte[] bytes, int off, int len) throws IOException {
226            checkIn2();
227            int len2 = in2.read(bytes, off, len);
228            available -= len2;
229            return len2;
230        }
231 
232        public int read(byte[] bytes) throws IOException {
233            checkIn2();
234            int len2 = in2.read(bytes);
235            available -= len2;
236            return len2;
237        }
238 
239        public int available() throws IOException {
240            return available;
241        }
242 
243        public int read() throws IOException {
244            checkIn2();
245            available--;
246            return in2.read();
247        }
248 
249        private void checkIn2() throws IOException {
250            if (available() > 0)
251                return;
252 
253            available = in.readInt();
254            int length = in.readInt();
255            if (length < 0) {
256                byte[] bytes = new byte[~length];
257                in.readFully(bytes);
258                in2 = new InflaterInputStream(new ByteArrayInputStream(bytes));
259            } else {
260                byte[] bytes = new byte[length];
261                in.readFully(bytes);
262                in2 = new ByteArrayInputStream(bytes);
263            }
264        }
265    }
266}

[all classes][org.jtoolkit.essence.app.net]
EMMA 2.0.5312 (C) Vladimir Roubtsov