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.cpu.marking;
042:
043: import org.netbeans.lib.profiler.client.ClientUtils;
044: import org.netbeans.lib.profiler.global.ProfilingSessionStatus;
045: import java.util.HashSet;
046: import java.util.Iterator;
047: import java.util.LinkedHashSet;
048: import java.util.Set;
049:
050: /**
051: *
052: * @author Jaroslav Bachorik
053: */
054: public class MarkingEngine {
055: //~ Inner Interfaces ---------------------------------------------------------------------------------------------------------
056:
057: public static interface StateObserver {
058: //~ Methods --------------------------------------------------------------------------------------------------------------
059:
060: void stateChanged(MarkingEngine instance);
061: }
062:
063: //~ Static fields/initializers -----------------------------------------------------------------------------------------------
064:
065: private static MarkingEngine instance;
066:
067: //~ Instance fields ----------------------------------------------------------------------------------------------------------
068:
069: private final Object mapperGuard = new Object();
070: private final Object markGuard = new Object();
071: private Mark defaultMark = null;
072:
073: // @GuardedBy mapperGuard
074: private MarkMapper mapper = null;
075: private Set observers;
076:
077: // @GuardedBy markGuard
078: private String[] labels;
079:
080: // @GuardedBy markGuard
081: private Mark[] markBackMap;
082:
083: // @GuardedBy markGuard
084: private MarkMapping[] marks;
085:
086: //~ Constructors -------------------------------------------------------------------------------------------------------------
087:
088: /**
089: * Creates a new instance of MarkingEngine
090: */
091: private MarkingEngine() {
092: observers = new HashSet();
093:
094: // synchronized(filterGuard) {
095: // filter = new MarkFilter();
096: // CPUStatsCollector.getDefault().addListener(filter);
097: // }
098: synchronized (mapperGuard) {
099: mapper = new MarkMapper();
100: this .addStateObserver(mapper);
101: }
102: }
103:
104: //~ Methods ------------------------------------------------------------------------------------------------------------------
105:
106: public static synchronized MarkingEngine getDefault() {
107: if (instance == null) {
108: instance = new MarkingEngine();
109: }
110:
111: return instance;
112: }
113:
114: public static synchronized void configure(Mark rootMark,
115: MarkMapping[] marks) {
116: getDefault().defaultMark = rootMark;
117: getDefault().setMarks(marks);
118: }
119:
120: public String getLabelForId(char markId) {
121: synchronized (markGuard) {
122: if (marks == null) {
123: return null;
124: }
125:
126: if (((int) markId > 0) && ((int) markId <= labels.length)) {
127: return labels[(int) markId - 1];
128: } else {
129: return null;
130: }
131: }
132: }
133:
134: public Mark getMarkForId(char markId) {
135: synchronized (markGuard) {
136: if (marks == null) {
137: return null;
138: }
139:
140: if (((int) markId > 0) && ((int) markId <= labels.length)) {
141: return markBackMap[(int) markId - 1];
142: } else {
143: return (defaultMark != null) ? defaultMark
144: : Mark.DEFAULT;
145: }
146: }
147: }
148:
149: public int getMarkId(Mark mark) {
150: synchronized (markGuard) {
151: if (mark.isDefault) {
152: return 0;
153: }
154:
155: for (int i = 0; i < labels.length; i++) {
156: if (labels[i].equals(mark.label)) {
157: return (char) (i + 1);
158: }
159: }
160:
161: return -1;
162: }
163: }
164:
165: public MarkMapper getMarker() {
166: synchronized (mapperGuard) {
167: return mapper;
168: }
169: }
170:
171: public ClientUtils.SourceCodeSelection[] getMarkerMethods() {
172: synchronized (markGuard) {
173: if (marks == null) {
174: return new ClientUtils.SourceCodeSelection[0];
175: }
176:
177: ClientUtils.SourceCodeSelection[] methods = new ClientUtils.SourceCodeSelection[marks.length];
178:
179: for (int i = 0; i < marks.length; i++) {
180: methods[i] = marks[i].markMask;
181: }
182:
183: return methods;
184: }
185: }
186:
187: public int getNMarks() {
188: synchronized (markGuard) {
189: return (labels != null) ? labels.length : 0;
190: }
191: }
192:
193: public void addStateObserver(StateObserver observer) {
194: observers.add(observer);
195: }
196:
197: public void removeStateObserver(StateObserver observer) {
198: observers.remove(observer);
199: }
200:
201: Mark mark(int methodId, ProfilingSessionStatus status) {
202: ClientUtils.SourceCodeSelection method = null;
203:
204: synchronized (markGuard) {
205: if (marks == null) {
206: return Mark.DEFAULT;
207: }
208:
209: status.beginTrans(false);
210:
211: try {
212: method = new ClientUtils.SourceCodeSelection(status
213: .getInstrMethodClasses()[methodId], status
214: .getInstrMethodNames()[methodId], status
215: .getInstrMethodSignatures()[methodId]);
216: } finally {
217: status.endTrans();
218: }
219:
220: String methodSig = method.toFlattened();
221:
222: for (int i = 0; i < marks.length; i++) {
223: if (methodSig.startsWith(marks[i].markSig)) {
224: return marks[i].mark;
225:
226: // int supposedMark = getMarkId(marks[i].mark);
227: // return (char)(supposedMark >= 0 ? supposedMark : 0);
228: }
229: }
230:
231: return Mark.DEFAULT;
232: }
233: }
234:
235: private void setMarks(MarkMapping[] marks) {
236: boolean stateChange = false;
237:
238: synchronized (markGuard) {
239: stateChange = !((this .marks == null) && (marks == null))
240: && (((this .marks == null) && (marks != null))
241: || ((this .marks != null) && (marks == null)) || !this .marks
242: .equals(marks));
243: this .marks = marks;
244:
245: if (marks != null) {
246: Set labelSet = new LinkedHashSet();
247:
248: for (int i = 0; i < marks.length; i++) {
249: labelSet.addAll(marks[i].mark.getLabels());
250: }
251:
252: labels = new String[labelSet.size()];
253: labels = (String[]) labelSet.toArray(labels);
254:
255: markBackMap = new Mark[labels.length];
256:
257: for (int i = 0; i < labels.length; i++) {
258: for (int j = 0; j < marks.length; j++) {
259: if (marks[j].mark.getLabel().equals(labels[i])) {
260: markBackMap[i] = marks[j].mark;
261:
262: break;
263: }
264: }
265: }
266: }
267: }
268:
269: if (stateChange) {
270: fireStateChanged();
271: }
272: }
273:
274: private void fireStateChanged() {
275: for (Iterator iter = observers.iterator(); iter.hasNext();) {
276: ((StateObserver) iter.next()).stateChanged(this);
277: }
278: }
279: }
|