001/*
002 * (C) Copyright 2014 Nuxeo SA (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl-2.1.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 *     <a href="mailto:grenard@nuxeo.com">Guillaume</a>
016 */
017package org.nuxeo.ecm.platform.sessioninspector.jsf.model;
018
019import java.util.ArrayList;
020import java.util.Arrays;
021import java.util.List;
022import java.util.Map;
023
024import org.nuxeo.ecm.platform.sessioninspector.jsf.StateReferenceHelper;
025import org.nuxeo.runtime.javaagent.AgentLoader;
026
027/**
028 * @since 5.9.2
029 */
030public class MonitorNode {
031
032    protected MonitorNode parent = null;
033
034    protected String id = null;
035
036    protected Object stateReference = null;
037
038    protected final String type;
039
040    protected List<MonitorNode> children = null;
041
042    protected String path = null;
043
044    protected Integer depth = null;
045
046    protected Long size = null;
047
048    protected Map<String, ObjectStatistics> objMapStat;
049
050    public MonitorNode(MonitorNode parent, Object rawHierarchy, Object[] rawState) throws NoSuchFieldException,
051            SecurityException, IllegalArgumentException, IllegalAccessException {
052        super();
053        this.parent = parent;
054        this.id = StateReferenceHelper.getIdForNode(rawHierarchy);
055        this.stateReference = rawState[0];
056        this.type = StateReferenceHelper.getTypeForNode(rawHierarchy);
057        children = new ArrayList<MonitorNode>();
058        List<?> childrenOfCurrent = StateReferenceHelper.getChildrenForNode(rawHierarchy);
059
060        if (childrenOfCurrent == null) {
061
062        } else {
063            children = new ArrayList<MonitorNode>(childrenOfCurrent.size());
064            for (int i = 0; i < childrenOfCurrent.size(); i++) {
065                children.add(new MonitorNode(this, childrenOfCurrent.get(i), (Object[]) ((Object[]) rawState[1])[i]));
066            }
067        }
068
069    }
070
071    public MonitorNode(Object rawHierarchy, Object[] rawState) throws NoSuchFieldException, SecurityException,
072            IllegalArgumentException, IllegalAccessException {
073        this(null, rawHierarchy, rawState);
074    }
075
076    public MonitorNode getChild(String id) {
077        for (MonitorNode child : children) {
078            if (child.getId().equals(id)) {
079                return child;
080            }
081        }
082        return null;
083    }
084
085    public MonitorNode getChild(String[] path) {
086        if (path == null || path.length == 0 || !path[0].equals(id)) {
087            return null;
088        } else {
089            if (path.length == 1) {
090                return this;
091            } else {
092                MonitorNode result = null;
093                String[] subArray = Arrays.copyOfRange(path, 1, path.length);
094                for (MonitorNode n : children) {
095                    result = n.getChild(subArray);
096                    if (result != null) {
097                        break;
098                    }
099                }
100                return result;
101            }
102        }
103    }
104
105    public int getCumulatedDepth() {
106        int count = 1;
107        for (MonitorNode child : children) {
108            count += child.getCumulatedDepth();
109        }
110        return count;
111    }
112
113    @SuppressWarnings("boxing")
114    public Long getCumulatedSize() {
115        Long count = getSize();
116        for (MonitorNode child : children) {
117            count += child.getCumulatedSize();
118        }
119        return count;
120    }
121
122    @SuppressWarnings("boxing")
123    public int getDepth() {
124        if (depth == null) {
125            if (parent == null) {
126                depth = 1;
127            } else {
128                depth = parent.getDepth() + 1;
129            }
130        }
131        return depth;
132    }
133
134    public String getId() {
135        return id;
136    }
137
138    public int getMaxDepth() {
139        int max = 1;
140        for (MonitorNode child : children) {
141            int temp = 1 + child.getMaxDepth();
142            if (temp > max) {
143                max = temp;
144            }
145        }
146        return max;
147    }
148
149    public String getPath() {
150        if (path == null) {
151            if (parent == null) {
152                path = id;
153            } else {
154                path = parent.getPath() + ":" + id;
155            }
156        }
157        return path;
158    }
159
160    @SuppressWarnings("boxing")
161    public Long getSize() {
162        if (size == null) {
163            Long temp = AgentLoader.INSTANCE.getSizer().deepSizeOf(stateReference) / 8;
164            size = temp;
165        }
166        return size;
167    }
168
169    public Object getStateReference() {
170        return stateReference;
171    }
172
173    public String getType() {
174        return type;
175    }
176
177    public String getView() {
178        if (type != null && type.endsWith("UIAliasHolder")) {
179            return "uiAliasHolder";
180        }
181        return "uiComponent";
182    }
183
184    public List<MonitorNode> toList() {
185        List<MonitorNode> result = new ArrayList<MonitorNode>();
186        result.add(this);
187        for (MonitorNode child : children) {
188            result.addAll(child.toList());
189        }
190        return result;
191    }
192
193    public String toString() {
194        if (stateReference != null) {
195            return stateReference.toString();
196        }
197        return null;
198    }
199
200}