001/*
002 * (C) Copyright 2014 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     <a href="mailto:grenard@nuxeo.com">Guillaume</a>
018 */
019package org.nuxeo.ecm.platform.sessioninspector.jsf.model;
020
021import java.util.ArrayList;
022import java.util.Arrays;
023import java.util.List;
024import java.util.Map;
025
026import org.nuxeo.ecm.platform.sessioninspector.jsf.StateReferenceHelper;
027import org.nuxeo.runtime.javaagent.AgentLoader;
028
029/**
030 * @since 5.9.2
031 */
032public class MonitorNode {
033
034    protected MonitorNode parent = null;
035
036    protected String id = null;
037
038    protected Object stateReference = null;
039
040    protected final String type;
041
042    protected List<MonitorNode> children = null;
043
044    protected String path = null;
045
046    protected Integer depth = null;
047
048    protected Long size = null;
049
050    protected Map<String, ObjectStatistics> objMapStat;
051
052    public MonitorNode(MonitorNode parent, Object rawHierarchy, Object[] rawState) throws NoSuchFieldException,
053            SecurityException, IllegalArgumentException, IllegalAccessException {
054        super();
055        this.parent = parent;
056        this.id = StateReferenceHelper.getIdForNode(rawHierarchy);
057        this.stateReference = rawState[0];
058        this.type = StateReferenceHelper.getTypeForNode(rawHierarchy);
059        children = new ArrayList<MonitorNode>();
060        List<?> childrenOfCurrent = StateReferenceHelper.getChildrenForNode(rawHierarchy);
061
062        if (childrenOfCurrent == null) {
063
064        } else {
065            children = new ArrayList<MonitorNode>(childrenOfCurrent.size());
066            for (int i = 0; i < childrenOfCurrent.size(); i++) {
067                children.add(new MonitorNode(this, childrenOfCurrent.get(i), (Object[]) ((Object[]) rawState[1])[i]));
068            }
069        }
070
071    }
072
073    public MonitorNode(Object rawHierarchy, Object[] rawState) throws NoSuchFieldException, SecurityException,
074            IllegalArgumentException, IllegalAccessException {
075        this(null, rawHierarchy, rawState);
076    }
077
078    public MonitorNode getChild(String id) {
079        for (MonitorNode child : children) {
080            if (child.getId().equals(id)) {
081                return child;
082            }
083        }
084        return null;
085    }
086
087    public MonitorNode getChild(String[] path) {
088        if (path == null || path.length == 0 || !path[0].equals(id)) {
089            return null;
090        } else {
091            if (path.length == 1) {
092                return this;
093            } else {
094                MonitorNode result = null;
095                String[] subArray = Arrays.copyOfRange(path, 1, path.length);
096                for (MonitorNode n : children) {
097                    result = n.getChild(subArray);
098                    if (result != null) {
099                        break;
100                    }
101                }
102                return result;
103            }
104        }
105    }
106
107    public int getCumulatedDepth() {
108        int count = 1;
109        for (MonitorNode child : children) {
110            count += child.getCumulatedDepth();
111        }
112        return count;
113    }
114
115    @SuppressWarnings("boxing")
116    public Long getCumulatedSize() {
117        Long count = getSize();
118        for (MonitorNode child : children) {
119            count += child.getCumulatedSize();
120        }
121        return count;
122    }
123
124    @SuppressWarnings("boxing")
125    public int getDepth() {
126        if (depth == null) {
127            if (parent == null) {
128                depth = 1;
129            } else {
130                depth = parent.getDepth() + 1;
131            }
132        }
133        return depth;
134    }
135
136    public String getId() {
137        return id;
138    }
139
140    public int getMaxDepth() {
141        int max = 1;
142        for (MonitorNode child : children) {
143            int temp = 1 + child.getMaxDepth();
144            if (temp > max) {
145                max = temp;
146            }
147        }
148        return max;
149    }
150
151    public String getPath() {
152        if (path == null) {
153            if (parent == null) {
154                path = id;
155            } else {
156                path = parent.getPath() + ":" + id;
157            }
158        }
159        return path;
160    }
161
162    @SuppressWarnings("boxing")
163    public Long getSize() {
164        if (size == null) {
165            Long temp = AgentLoader.INSTANCE.getSizer().deepSizeOf(stateReference) / 8;
166            size = temp;
167        }
168        return size;
169    }
170
171    public Object getStateReference() {
172        return stateReference;
173    }
174
175    public String getType() {
176        return type;
177    }
178
179    public String getView() {
180        if (type != null && type.endsWith("UIAliasHolder")) {
181            return "uiAliasHolder";
182        }
183        return "uiComponent";
184    }
185
186    public List<MonitorNode> toList() {
187        List<MonitorNode> result = new ArrayList<MonitorNode>();
188        result.add(this);
189        for (MonitorNode child : children) {
190            result.addAll(child.toList());
191        }
192        return result;
193    }
194
195    public String toString() {
196        if (stateReference != null) {
197            return stateReference.toString();
198        }
199        return null;
200    }
201
202}