Skip to content

Package: Context

Context

nameinstructionbranchcomplexitylinemethod
Context()
M: 17 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 5 C: 0
0%
M: 1 C: 0
0%
addLifeCycleListener(IOEventLifeCycleListener)
M: 5 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 2 C: 0
0%
M: 1 C: 0
0%
complete(ProcessorResult)
M: 4 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 2 C: 0
0%
M: 1 C: 0
0%
create(Connection)
M: 15 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 5 C: 0
0%
M: 1 C: 0
0%
create(Connection, Processor, IOEvent, IOEventLifeCycleListener)
M: 21 C: 0
0%
M: 4 C: 0
0%
M: 3 C: 0
0%
M: 7 C: 0
0%
M: 1 C: 0
0%
getAttributes()
M: 3 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
getConnection()
M: 3 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
getIoEvent()
M: 3 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
getProcessor()
M: 3 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
hasLifeCycleListener(IOEventLifeCycleListener)
M: 5 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
isManualIOEventControl()
M: 3 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
recycle()
M: 7 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 3 C: 0
0%
M: 1 C: 0
0%
release()
M: 1 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
removeAllLifeCycleListeners()
M: 4 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 2 C: 0
0%
M: 1 C: 0
0%
removeLifeCycleListener(IOEventLifeCycleListener)
M: 5 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
reset()
M: 22 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 8 C: 0
0%
M: 1 C: 0
0%
resume()
M: 29 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 8 C: 0
0%
M: 1 C: 0
0%
setConnection(Connection)
M: 4 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 2 C: 0
0%
M: 1 C: 0
0%
setIoEvent(IOEvent)
M: 4 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 2 C: 0
0%
M: 1 C: 0
0%
setManualIOEventControl()
M: 32 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 9 C: 0
0%
M: 1 C: 0
0%
setProcessor(Processor)
M: 4 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 2 C: 0
0%
M: 1 C: 0
0%
static {...}
M: 12 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 3 C: 0
0%
M: 1 C: 0
0%
suspend()
M: 32 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 9 C: 0
0%
M: 1 C: 0
0%
wasSuspended()
M: 3 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%

Coverage

1: /*
2: * Copyright (c) 2008, 2020 Oracle and/or its affiliates. All rights reserved.
3: *
4: * This program and the accompanying materials are made available under the
5: * terms of the Eclipse Public License v. 2.0, which is available at
6: * http://www.eclipse.org/legal/epl-2.0.
7: *
8: * This Source Code may also be made available under the following Secondary
9: * Licenses when the conditions for such availability set forth in the
10: * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
11: * version 2 with the GNU Classpath Exception, which is available at
12: * https://www.gnu.org/software/classpath/license.html.
13: *
14: * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15: */
16:
17: package org.glassfish.grizzly;
18:
19: import java.io.IOException;
20: import java.lang.reflect.Array;
21: import java.util.Arrays;
22: import java.util.logging.Logger;
23:
24: import org.glassfish.grizzly.asyncqueue.MessageCloner;
25: import org.glassfish.grizzly.attributes.AttributeHolder;
26: import org.glassfish.grizzly.attributes.AttributeStorage;
27:
28: /**
29: * Object, which is responsible for holding context during I/O event processing.
30: *
31: * @author Alexey Stashok
32: */
33: @SuppressWarnings("deprecation")
34: public class Context implements AttributeStorage, Cacheable {
35:
36: private static final Logger LOGGER = Grizzly.logger(Context.class);
37: private static final Processor NULL_PROCESSOR = new NullProcessor();
38: private static final ThreadCache.CachedTypeIndex<Context> CACHE_IDX = ThreadCache.obtainIndex(Context.class, 4);
39:
40: public static Context create(final Connection connection) {
41: Context context = ThreadCache.takeFromCache(CACHE_IDX);
42:• if (context == null) {
43: context = new Context();
44: }
45:
46: context.setConnection(connection);
47: return context;
48: }
49:
50: public static Context create(final Connection connection, final Processor processor, final IOEvent ioEvent,
51: final IOEventLifeCycleListener lifeCycleListener) {
52: final Context context;
53:
54:• if (processor != null) {
55: context = processor.obtainContext(connection);
56: } else {
57: context = NULL_PROCESSOR.obtainContext(connection);
58: }
59:
60: context.setIoEvent(ioEvent);
61:• if (lifeCycleListener != null) {
62: context.addLifeCycleListener(lifeCycleListener);
63: }
64:
65: return context;
66: }
67:
68: /**
69: * Processing Connection
70: */
71: private Connection connection;
72: /**
73: * Processing IOEvent
74: */
75: protected IOEvent ioEvent = IOEvent.NONE;
76: /**
77: * Processor, responsible for I/O event processing
78: */
79: private Processor processor;
80: /**
81: * Attributes, associated with the processing Context
82: */
83: private final AttributeHolder attributes;
84: /**
85: * IOEventProcessingHandler is called to notify about IOEvent processing life-cycle events like suspend, resume,
86: * complete.
87: */
88: protected final MinimalisticArrayList<IOEventLifeCycleListener> lifeCycleListeners = new MinimalisticArrayList<>(
89: IOEventLifeCycleListener.class, 2);
90: /**
91: * <tt>true</tt> if this IOEvent processing was suspended during its processing, or <tt>false</tt> otherwise.
92: */
93: protected boolean wasSuspended;
94:
95: protected boolean isManualIOEventControl;
96:
97: public Context() {
98: attributes = Grizzly.DEFAULT_ATTRIBUTE_BUILDER.createUnsafeAttributeHolder();
99: }
100:
101: /**
102: * Notify Context its processing will be suspended in the current thread.
103: */
104: public void suspend() {
105: try {
106: final int sz = lifeCycleListeners.size;
107: final IOEventLifeCycleListener[] array = lifeCycleListeners.array;
108:• for (int i = 0; i < sz; i++) {
109: array[i].onContextSuspend(this);
110: }
111: } catch (IOException e) {
112: throw new IllegalStateException(e);
113: }
114:
115: wasSuspended = true;
116: }
117:
118: /**
119: * Notify Context its processing will be resumed in the current thread.
120: */
121: public void resume() {
122: try {
123: final int sz = lifeCycleListeners.size;
124: final IOEventLifeCycleListener[] array = lifeCycleListeners.array;
125:• for (int i = 0; i < sz; i++) {
126: array[i].onContextResume(this);
127: }
128: } catch (IOException e) {
129: throw new IllegalStateException(e);
130: }
131: }
132:
133: public void complete(final ProcessorResult result) {
134: ProcessorExecutor.complete(this, result);
135: }
136:
137: /**
138: * @return <tt>true</tt> if this IOEvent processing was suspended during its processing, or <tt>false</tt> otherwise.
139: */
140: public boolean wasSuspended() {
141: return wasSuspended;
142: }
143:
144: /**
145: * Switches processing to the manual IOEvent control. {@link Connection#enableIOEvent(org.glassfish.grizzly.IOEvent)} or
146: * {@link Connection#disableIOEvent(org.glassfish.grizzly.IOEvent)} might be explicitly called.
147: */
148: public void setManualIOEventControl() {
149: try {
150: final int sz = lifeCycleListeners.size;
151: final IOEventLifeCycleListener[] array = lifeCycleListeners.array;
152:• for (int i = 0; i < sz; i++) {
153: array[i].onContextManualIOEventControl(this);
154: }
155: } catch (IOException e) {
156: throw new IllegalStateException(e);
157: }
158:
159: isManualIOEventControl = true;
160: }
161:
162: /**
163: * @return <tt>true</tt>, if processing was switched to the manual IOEvent control, or <tt>false</tt> otherwise.
164: */
165: public boolean isManualIOEventControl() {
166: return isManualIOEventControl;
167: }
168:
169: /**
170: * Get the processing {@link IOEvent}.
171: *
172: * @return the processing {@link IOEvent}.
173: */
174: public IOEvent getIoEvent() {
175: return ioEvent;
176: }
177:
178: /**
179: * Set the processing {@link IOEvent}.
180: *
181: * @param ioEvent the processing {@link IOEvent}.
182: */
183: public void setIoEvent(final IOEvent ioEvent) {
184: this.ioEvent = ioEvent;
185: }
186:
187: /**
188: * Get the processing {@link Connection}.
189: *
190: * @return the processing {@link Connection}.
191: */
192: public Connection getConnection() {
193: return connection;
194: }
195:
196: /**
197: * Set the processing {@link Connection}.
198: *
199: * @param connection the processing {@link Connection}.
200: */
201: public void setConnection(final Connection connection) {
202: this.connection = connection;
203: }
204:
205: /**
206: * Get the {@link Processor}, which is responsible to process the {@link IOEvent}.
207: *
208: * @return the {@link Processor}, which is responsible to process the {@link IOEvent}.
209: */
210: public Processor getProcessor() {
211: return processor;
212: }
213:
214: /**
215: * Set the {@link Processor}, which is responsible to process the {@link IOEvent}.
216: *
217: * @param processor the {@link Processor}, which is responsible to process the {@link IOEvent}.
218: */
219: public void setProcessor(final Processor processor) {
220: this.processor = processor;
221: }
222:
223: public boolean hasLifeCycleListener(final IOEventLifeCycleListener listener) {
224: return lifeCycleListeners.contains(listener);
225: }
226:
227: public void addLifeCycleListener(final IOEventLifeCycleListener listener) {
228: lifeCycleListeners.add(listener);
229: }
230:
231: public boolean removeLifeCycleListener(final IOEventLifeCycleListener listener) {
232: return lifeCycleListeners.remove(listener);
233: }
234:
235: public void removeAllLifeCycleListeners() {
236: lifeCycleListeners.clear();
237: }
238:
239: /**
240: * Get attributes ({@link AttributeHolder}), associated with the processing {@link Context}. {@link AttributeHolder} is
241: * cleared after each I/O event processing. Method may return <tt>null</tt>, if there were no attributes added before.
242: *
243: * @return attributes ({@link AttributeHolder}), associated with the processing {@link Context}.
244: */
245: @Override
246: public AttributeHolder getAttributes() {
247: return attributes;
248: }
249:
250: /**
251: * If implementation uses {@link org.glassfish.grizzly.utils.ObjectPool} to store and reuse {@link Context} instances -
252: * this method will be called before {@link Context} will be offered to pool.
253: */
254: public void reset() {
255: attributes.recycle();
256:
257: processor = null;
258: lifeCycleListeners.clear();
259: connection = null;
260: ioEvent = IOEvent.NONE;
261: wasSuspended = false;
262: isManualIOEventControl = false;
263: }
264:
265: /**
266: * Recycle this {@link Context}
267: */
268: @Override
269: public void recycle() {
270: reset();
271: ThreadCache.putToCache(CACHE_IDX, this);
272: }
273:
274: /**
275: * Alternative to {@link #recycle()} that allows cleanup actions to be performed without returning this instance to the
276: * cache.
277: *
278: * By default, this is a no-op.
279: *
280: * @since 2.3.29
281: */
282: protected void release() {
283: // no-op
284: }
285:
286: private final static class NullProcessor implements Processor {
287:
288: @Override
289: public Context obtainContext(Connection connection) {
290: final Context context = Context.create(connection);
291: context.setProcessor(this);
292:
293: return context;
294: }
295:
296: @Override
297: public ProcessorResult process(Context context) {
298: return ProcessorResult.createNotRun();
299: }
300:
301: @Override
302: public void read(Connection connection, CompletionHandler completionHandler) {
303: throw new UnsupportedOperationException("Not supported.");
304: }
305:
306: @Override
307: public void write(Connection connection, Object dstAddress, Object message, CompletionHandler completionHandler) {
308: throw new UnsupportedOperationException("Not supported.");
309: }
310:
311: @Override
312: public void write(Connection connection, Object dstAddress, Object message, CompletionHandler completionHandler, MessageCloner messageCloner) {
313: throw new UnsupportedOperationException("Not supported yet.");
314: }
315:
316: @Override
317: @Deprecated
318: public void write(Connection connection, Object dstAddress, Object message, CompletionHandler completionHandler,
319: org.glassfish.grizzly.asyncqueue.PushBackHandler pushBackHandler) {
320: throw new UnsupportedOperationException("Not supported.");
321: }
322:
323: @Override
324: public boolean isInterested(IOEvent ioEvent) {
325: return true;
326: }
327:
328: @Override
329: public void setInterested(IOEvent ioEvent, boolean isInterested) {
330: }
331: }
332:
333: protected static final class MinimalisticArrayList<E> {
334:
335: private E[] array;
336: private int size;
337:
338: @SuppressWarnings("unchecked")
339: private MinimalisticArrayList(final Class<E> clazz, final int initialCapacity) {
340: array = (E[]) Array.newInstance(clazz, initialCapacity);
341: }
342:
343: public void add(final E listener) {
344: ensureCapacity();
345: array[size++] = listener;
346: }
347:
348: public boolean contains(final E listener) {
349: return indexOf(listener) != -1;
350: }
351:
352: private boolean remove(final E listener) {
353: final int idx = indexOf(listener);
354: if (idx == -1) {
355: return false;
356: }
357:
358: if (idx < size - 1) {
359: System.arraycopy(array, idx + 1, array, idx, size - idx - 1);
360: }
361:
362: array[--size] = null;
363: return true;
364: }
365:
366: public void copyFrom(final MinimalisticArrayList<E> list) {
367: if (list.size > array.length) {
368: array = Arrays.copyOf(list.array, list.size);
369: size = list.size;
370: } else {
371: System.arraycopy(list.array, 0, array, 0, list.size);
372: for (int i = list.size; i < size; i++) {
373: array[i] = null;
374: }
375:
376: size = list.size;
377: }
378: }
379:
380: public int size() {
381: return size;
382: }
383:
384: public E[] array() {
385: return array;
386: }
387:
388: public void clear() {
389: for (int i = 0; i < size; i++) {
390: array[i] = null;
391: }
392:
393: size = 0;
394: }
395:
396: private int indexOf(final E listener) {
397: for (int i = 0; i < size; i++) {
398: if (array[i].equals(listener)) {
399: return i;
400: }
401: }
402: return -1;
403: }
404:
405: private void ensureCapacity() {
406: if (size == array.length) {
407: array = Arrays.copyOf(array, size + 2);
408: }
409: }
410: }
411: }