Package org.jboss.dashboard.profiler

Source Code of org.jboss.dashboard.profiler.CodeBlockTrace

/**
* Copyright (C) 2012 JBoss Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*       http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.dashboard.profiler;

import org.apache.commons.lang.builder.HashCodeBuilder;

import java.text.DateFormat;
import java.util.*;

/**
* A code block trace is the way that the platform has to register the execution of a given portion of code (code block).
* Such registry contains:
* <ul>
* <li>A reference to the belonging thread.
* <li>The begin/end times of the code block.
* <li>A map of variables representing the execution context.
* <li>A parent trace.
* <li>A set of child traces.  
* </ul>
*/
public abstract class CodeBlockTrace {

    protected static DateFormat dateFormat = DateFormat.getDateTimeInstance();

    public static boolean RUNTIME_CONTRAINTS_ENABLED = true;

    ThreadProfile threadProfile;
    protected CodeBlockTrace parent;
    protected CodeBlockTraces children;
    protected String id;
    protected long beginTimeMillis;
    protected long endTimeMillis;
    protected long childrenElapsedTimeMillis;
    protected Set<CodeBlockType> ancestorTypes;
    protected List<RuntimeConstraint> runtimeConstraints;

    public CodeBlockTrace(String id) {
        this.threadProfile = null;
        this.parent = null;
        this.id = id;
        this.beginTimeMillis = -1;
        this.endTimeMillis = -1;
        this.childrenElapsedTimeMillis = 0;
        this.children = null;
        this.ancestorTypes = null;
    }

    public abstract CodeBlockType getType();
    public abstract String getDescription();
    public abstract Map<String,Object> getContext();

    public int hashCode() {
        return new HashCodeBuilder().append(getId()).toHashCode();
    }

    public boolean equals(Object obj) {
        try {
            if (obj == null) return false;
            if (obj == this) return true;
            if (id == null) return false;

            CodeBlockTrace other = (CodeBlockTrace) obj;
            return id.equals(other.id);
        }
        catch (ClassCastException e) {
            return false;
        }
    }

    public ThreadProfile getThreadProfile() {
        return threadProfile;
    }

    public void setThreadProfile(ThreadProfile threadProfile) {
        this.threadProfile = threadProfile;
    }

    public CodeBlockTrace getParent() {
        return parent;
    }

    public void setParent(CodeBlockTrace parent) {
        this.parent = parent;
    }

    public CodeBlockTraces getChildren() {
        return children;
    }

    public void setChildren(CodeBlockTraces children) {
        this.children = children;
    }

    public Set<CodeBlockType> getAncestorTypes() {
        return ancestorTypes;
    }

    public void setAncestorTypes(Set<CodeBlockType> ancestorTypes) {
        this.ancestorTypes = ancestorTypes;
    }

    public boolean isDescendantOfType(CodeBlockType type) {
        return ancestorTypes !=  null && ancestorTypes.contains(type);
    }

    public void addChild(CodeBlockTrace child) {
        // Avoid memory problems
        if (children != null && children.size() > 10000) return;

        Set<CodeBlockType> childAncestorTypes = new HashSet<CodeBlockType>();
        childAncestorTypes.add(this.getType());
        if (ancestorTypes != null) childAncestorTypes.addAll(ancestorTypes);
        child.setAncestorTypes(childAncestorTypes);

        child.setParent(this);
        if (children == null) children = new CodeBlockTraces();
        children.add(child);
    }

    public void removeChild(CodeBlockTrace child) {
        if (children != null) {
            child.setParent(null);
            children.remove(child);
        }
    }

    public CodeBlockTraces getDescendants() {
        if (children == null) return null;
        CodeBlockTraces result = new CodeBlockTraces();
        for (int i=0; i<children.size(); i++) {
            CodeBlockTrace child = children.get(i);
            CodeBlockTraces descendants = child.getDescendants();
            result.add(child);
            result.addAll(descendants);
        }
        return result;
    }

    public int getLevel() {
        if (parent == null) return 0;
        return parent.getLevel() + 1;
    }
   
    public CodeBlockTraces toPlainList() {
        CodeBlockTraces results = new CodeBlockTraces();
        results.add(this);
        results.addAll(getDescendants());
        return results;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public long getBeginTimeMillis() {
        return beginTimeMillis;
    }

    public void setBeginTimeMillis(long beginTimeMillis) {
        this.beginTimeMillis = beginTimeMillis;
    }

    public long getEndTimeMillis() {
        return endTimeMillis;
    }

    public void setEndTimeMillis(long endTimeMillis) {
        this.endTimeMillis = endTimeMillis;
    }

    public long getElapsedTimeMillis() {
        if (isRunning()) return System.currentTimeMillis()-beginTimeMillis;
        return endTimeMillis-beginTimeMillis;
    }

    public long getSelfTimeMillis() {
        if (isRunning()) return 0;
        long total = getElapsedTimeMillis();
        long self = total - childrenElapsedTimeMillis;
        return self > 0 ? self : 0;
    }

    public long getChildrenElapsedTimeMillis() {
        return childrenElapsedTimeMillis;
    }

    public boolean isRunning() {
        return endTimeMillis == -1;
    }

    public CodeBlockTrace begin() {
        if (beginTimeMillis == -1) {
            beginTimeMillis = System.currentTimeMillis();
            ThreadProfile threadExec = Profiler.lookup().getCurrentThreadProfile();
            if (threadExec != null) {
                this.threadProfile = threadExec;
                CodeBlockTrace currentTrace = threadExec.codeBlockInProgress;
                if (currentTrace != null) currentTrace.addChild(this);
                threadExec.codeBlockInProgress = this;
            }
        }
        return this;
    }

    public void end() {
        if (endTimeMillis == -1) {
            endTimeMillis = System.currentTimeMillis();
            if (parent != null) parent.childrenElapsedTimeMillis += getElapsedTimeMillis();
            ThreadProfile threadExec = Profiler.lookup().getCurrentThreadProfile();
            if (threadExec != null) {
                // When a trace ends set as current the last running parent.
                CodeBlockTrace runningParent = parent;
                while (runningParent != null && !runningParent.isRunning()) runningParent = runningParent.parent;
                threadExec.codeBlockInProgress = runningParent;
            }
        }
    }

    public String toString() {
        StringBuffer buf = new StringBuffer();
        buf.append(getType().getId()).append("=").append(getDescription()).append("\n");
        if (beginTimeMillis > 0) buf.append("Begin date").append("=").append(dateFormat.format(new Date(getBeginTimeMillis()))).append("\n");
        if (endTimeMillis > 0) buf.append("End date").append("=").append(dateFormat.format(new Date(getEndTimeMillis()))).append("\n");
        buf.append(printContext(false, "=", "\n"));
        return buf.toString();
    }

    // Context manipulation

    public String printContext(boolean includeParent) {
        return printContext(includeParent, "=", "\n", 0);
    }

    public String printContext(boolean includeParent, String valueSeparator, String rowSeparator) {
        return printContext(includeParent, valueSeparator, rowSeparator, 0);
    }

    public String printContext(boolean includeParent, String valueSeparator, String rowSeparator, int indent) {
        if (includeParent && parent != null) {
            StringBuffer buf = new StringBuffer();
            buf.append(parent.printContext(true, valueSeparator, rowSeparator, indent));
            buf.append(rowSeparator);
            buf.append(printMap(getContext(), valueSeparator, rowSeparator, indent));
            return buf.toString();
        } else {
            return printMap(getContext(), valueSeparator, rowSeparator, indent);
        }
    }

    public void printIndent(StringBuffer buf, int indent) {
        for (int i=0; i<indent; i++) {
            buf.append("    ");
        }
    }

    public String printMap(Map m, String valueSeparator, String rowSeparator) {
        return printMap(m, valueSeparator, rowSeparator, 0);
    }

    public String printMap(Map m, String valueSeparator, String rowSeparator, int indent) {
        StringBuffer buf = new StringBuffer();
        Iterator mit = m.keySet().iterator();
        while (mit.hasNext()) {
            Object key = mit.next();
            Object value = m.get(key);
            if (buf.length() > 0) buf.append(rowSeparator);
            printIndent(buf, indent);
            buf.append(key != null ? key.toString() : "null");
            buf.append(valueSeparator);
            buf.append(value != null ? value.toString() : "null");
        }
        return buf.toString();
    }

    // Runtime constraints handling

    public void addRuntimeConstraint(RuntimeConstraint runtimeConstraint) {
        if (runtimeConstraints == null) runtimeConstraints = new ArrayList<RuntimeConstraint>();
        runtimeConstraints.add(runtimeConstraint);
    }

    public void checkRuntimeConstraints() throws Exception {
        if (!RUNTIME_CONTRAINTS_ENABLED) return;

        CodeBlockTrace _trace = this;
        while (_trace != null) {
            if (_trace.runtimeConstraints != null) {
                for (RuntimeConstraint runtimeConstraint : _trace.runtimeConstraints) {
                    runtimeConstraint.validate();
                }
            }
            _trace = _trace.parent;
        }
    }
}
TOP

Related Classes of org.jboss.dashboard.profiler.CodeBlockTrace

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.