/** * eAdventure (formerly <e-Adventure> and <e-Game>) is a research project of the * <e-UCM> research group. * * Copyright 2005-2010 <e-UCM> research group. * * You can access a list of all the contributors to eAdventure at: * http://e-adventure.e-ucm.es/contributors * * <e-UCM> is a research group of the Department of Software Engineering * and Artificial Intelligence at the Complutense University of Madrid * (School of Computer Science). * * C Profesor Jose Garcia Santesmases sn, * 28040 Madrid (Madrid), Spain. * * For more info please visit: <http://e-adventure.e-ucm.es> or * <http://www.e-ucm.es> * * **************************************************************************** * * This file is part of eAdventure, version 2.0 * * eAdventure is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * eAdventure is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with eAdventure. If not, see <http://www.gnu.org/licenses/>. */ /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package es.eucm.ead.editor.model.nodes; import es.eucm.ead.editor.model.EditorModel; import es.eucm.ead.editor.model.visitor.ModelVisitorDriver; import es.eucm.ead.model.assets.AssetDescriptor; import es.eucm.ead.model.elements.BasicElement; import es.eucm.ead.model.elements.extra.EAdList; import es.eucm.ead.model.elements.extra.EAdMap; import es.eucm.ead.model.params.EAdParam; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.List; import java.util.Map; /** * An engine-model node. Used as a base for the dependency-tracking mechanism * for the editor model. * * @author mfreire */ public class EngineNode<T> extends DependencyNode<T> { private static Logger logger = LoggerFactory.getLogger(EngineNode.class); public static final int maxDependencies = 10; public EngineNode(int id, T content) { super(id, content); } /** * Generates a one-line description with as much information as possible. * * @param m model (required to resolve editor ids) * @return a human-readable description of this node */ @Override public String getTextualDescription(EditorModel m) { StringBuilder sb = new StringBuilder(); appendDescription(m, content, sb, 0, 3); return sb.toString(); } public String formatIds(List<DependencyNode> list) { StringBuilder sb = new StringBuilder(" "); int remaining = maxDependencies; for (DependencyNode n : list) { remaining--; sb.append("(").append(n.getId()).append(") "); if (remaining == 0) { sb.append("..."); break; } } return sb.toString(); } private void appendDependencies(DependencyNode n, EditorModel m, StringBuilder sb) { List<DependencyNode> incoming = m.incomingDependencies(this); sb.append("Used from ").append(formatIds(incoming)).append("\n"); } /** * Returns a descriptive string for a given object. * * @param o object to drive into. * @return */ @SuppressWarnings("unchecked") private void appendDescription(EditorModel m, Object o, StringBuilder sb, int depth, int maxDepth) { if (maxDepth == depth) { return; } String indent = new String(new char[depth * 2]).replace('\0', ' '); if (o == null) { sb.append("(null)"); return; } String id = "" + m.getEditorId(o); String cname = o.getClass().getSimpleName(); if (o instanceof BasicElement) { sb.append(indent + cname + " (" + id + ")" + "\n"); if (depth != maxDepth) { appendDependencies(this, m, sb); } appendParams(m, o, sb, depth, maxDepth); } else if (o instanceof EAdList) { EAdList target = (EAdList) o; sb.append(indent + cname + " (" + id + ")" + "\n"); if (target.size() == 0) { sb.append(indent + " (empty)\n"); } else if (depth == maxDepth - 1) { sb.append(indent + " (" + target.size() + " elements inside)\n"); } else { for (int i = 0; i < target.size(); i++) { // visit all children-values of this list Object inner = target.get(i); if (inner != null) { appendDescription(m, inner, sb, depth + 1, maxDepth); } } } } else if (o instanceof EAdMap) { EAdMap<?> target = (EAdMap<?>) o; sb.append(indent + cname + " (" + id + ")" + "\n"); int i = 0; if (target.size() == 0) { sb.append(indent + " (empty)\n"); } else if (depth == maxDepth - 1) { sb.append(indent + " (" + target.size() + " elements inside)\n"); } else { for (Map.Entry<?, ?> e : target.entrySet()) { if (e.getKey() != null) { appendDescription(m, e.getKey(), sb, depth + 1, maxDepth); } sb.append(indent + " -m->\n"); if (e.getValue() != null) { appendDescription(m, e.getValue(), sb, depth + 1, maxDepth); } i++; } } } else if (o instanceof EAdParam) { sb.append(indent + ((EAdParam) o).toStringData()); } else if (o instanceof AssetDescriptor) { sb.append(indent + "asset" + " (" + id + "): " + ((AssetDescriptor) o).getId() + "\n"); appendParams(m, o, sb, depth, maxDepth); if (depth != maxDepth) { appendDependencies(this, m, sb); } } else if (o instanceof Class) { sb.append(indent + ((Class<?>) o).getName() + "\n"); } else { sb.append(indent + " (" + cname + "~" + o.toString() + ")\n"); } } /** * Iterates through params, providing a glimpse of their contents. * * @param m model * @param o object from which to extract params, if any * @param sb output * @param depth current depth * @param maxDepth max depth to reach */ private void appendParams(EditorModel m, Object o, StringBuilder sb, int depth, int maxDepth) { if (maxDepth == depth + 1) { return; } String indent = new String(new char[depth * 2]).replace('\0', ' '); Class<?> clazz = o.getClass(); while (clazz != null) { Field[] fields = clazz.getDeclaredFields(); for (Field field : fields) { if (Modifier.isStatic(field.getModifiers())) { // ignore static fields continue; } Object v = ModelVisitorDriver.readProperty(o, field.getName()); if (!ModelVisitorDriver.isEmpty(v)) { sb.append(indent).append(field.getName()).append(" --> "); appendDescription(m, v, sb, depth + 1, maxDepth); sb.append("\n"); } } clazz = clazz.getSuperclass(); } } }