001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: * The Original Software is NetBeans. The Initial Developer of the Original
026: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
027: * Microsystems, Inc. All Rights Reserved.
028: *
029: * If you wish your version of this file to be governed by only the CDDL
030: * or only the GPL Version 2, indicate your decision by adding
031: * "[Contributor] elects to include this software in this distribution
032: * under the [CDDL or GPL Version 2] license." If you do not indicate a
033: * single choice of license, a recipient has the option to distribute
034: * your version of this file under either the CDDL, the GPL Version 2 or
035: * to extend the choice of license to its licensees as provided above.
036: * However, if you add GPL Version 2 code and therefore, elected the GPL
037: * Version 2 license, then the option applies only if the new code is
038: * made subject to such option by the copyright holder.
039: */
040:
041: package org.netbeans.lib.profiler.results;
042:
043: import org.netbeans.lib.profiler.ProfilerClient;
044: import java.util.Collections;
045: import java.util.HashSet;
046: import java.util.Iterator;
047: import java.util.Set;
048: import java.util.concurrent.atomic.AtomicBoolean;
049: import java.util.logging.Level;
050: import java.util.logging.Logger;
051:
052: /**
053: *
054: * @author Jaroslav Bachorik
055: */
056: public abstract class AbstractDataFrameProcessor implements
057: DataFrameProcessor {
058: //~ Inner Interfaces ---------------------------------------------------------------------------------------------------------
059:
060: protected static interface ListenerFunctor {
061: //~ Methods --------------------------------------------------------------------------------------------------------------
062:
063: void execute(ProfilingResultListener listener);
064: }
065:
066: //~ Static fields/initializers -----------------------------------------------------------------------------------------------
067:
068: protected static final Logger LOGGER = Logger
069: .getLogger(DataFrameProcessor.class.getName());
070:
071: //~ Instance fields ----------------------------------------------------------------------------------------------------------
072:
073: protected volatile ProfilerClient client = null;
074: private final AtomicBoolean batchInProgress = new AtomicBoolean(
075: false);
076: private final Set listeners = Collections
077: .synchronizedSet(new HashSet());
078:
079: //~ Methods ------------------------------------------------------------------------------------------------------------------
080:
081: public boolean hasListeners() {
082: return !listeners.isEmpty();
083: }
084:
085: public void processDataFrame(byte[] buffer) {
086: try {
087: fireBatchStart();
088: doProcessDataFrame(buffer);
089: } catch (Exception e) {
090: LOGGER.log(Level.SEVERE,
091: "Error while processing data frame", e);
092: } finally {
093: fireBatchStop();
094: }
095: }
096:
097: public void removeAllListeners() {
098: Set tmpListeners = new HashSet(listeners);
099:
100: for (Iterator iter = tmpListeners.iterator(); iter.hasNext();) {
101: ((ProfilingResultListener) iter.next()).shutdown();
102: }
103:
104: listeners.clear();
105: }
106:
107: public void reset() {
108: fireReset();
109: }
110:
111: public void shutdown() {
112: // finalize the batch
113: fireBatchStop();
114: fireShutdown();
115: }
116:
117: public void startup(ProfilerClient client) {
118: this .client = client;
119: }
120:
121: protected void addListener(final ProfilingResultListener listener) {
122: listeners.add(listener);
123: }
124:
125: protected abstract void doProcessDataFrame(byte[] buffer);
126:
127: protected void fireProfilingPoint(final int threadId,
128: final int ppId, final long timeStamp) {
129: foreachListener(new ListenerFunctor() {
130: public void execute(ProfilingResultListener listener) {
131: listener.profilingPoint(threadId, ppId, timeStamp);
132: }
133: });
134: }
135:
136: protected void fireReset() {
137: foreachListener(new ListenerFunctor() {
138: public void execute(ProfilingResultListener listener) {
139: listener.reset();
140: }
141: });
142: }
143:
144: protected void foreachListener(ListenerFunctor functor) {
145: // Set tmpListeners = null;
146: // synchronized(listeners) {
147: // tmpListeners = new HashSet(listeners);
148: // }
149: for (Iterator iter = listeners.iterator(); iter.hasNext();) {
150: functor.execute((ProfilingResultListener) iter.next());
151: }
152: }
153:
154: protected void removeListener(final ProfilingResultListener listener) {
155: listener.shutdown();
156: listeners.remove(listener);
157: }
158:
159: private void fireBatchStart() {
160: batchInProgress.set(true);
161: foreachListener(new ListenerFunctor() {
162: public void execute(ProfilingResultListener listener) {
163: listener.onBatchStart();
164: }
165: });
166: }
167:
168: private void fireBatchStop() {
169: if (batchInProgress.compareAndSet(true, false)) {
170: foreachListener(new ListenerFunctor() {
171: public void execute(ProfilingResultListener listener) {
172: listener.onBatchStop();
173: }
174: });
175: }
176: }
177:
178: private void fireShutdown() {
179: foreachListener(new ListenerFunctor() {
180: public void execute(ProfilingResultListener listener) {
181: listener.shutdown();
182: }
183: });
184: }
185: }
|