/******************************************************************************* * Copyright (c) 2010 Eric Bodden. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Eric Bodden - initial API and implementation ******************************************************************************/ package de.bodden.tamiflex.views; import java.util.HashMap; import java.util.Map; import java.util.regex.Pattern; public class ReflectionViewContentInserter { private final TreeParent root; private final ReflectionView reflectionView; private final Map<String,CategoryNode> nameToNode = new HashMap<String, CategoryNode>(); private final Pattern classNamePattern = Pattern.compile("^(([a-z0-9_])+.)*([A-Za-z0-9_\\$])+$"); private final Pattern arrayTypeNamePattern = Pattern.compile("^(([a-z0-9_])+.)*([A-Za-z0-9_\\$])+(\\[\\])+$"); public ReflectionViewContentInserter(TreeParent root, ReflectionView container) { this.reflectionView = container; this.root = root; } private CategoryNode insertNodeIfNecessary(String category) { CategoryNode node = nameToNode.get(category); if(node==null) { node = new CategoryNode(category); root.addChild(node); nameToNode.put(category, node); } return node; } public void insertFromTraceFileLine(String line) { try{ if(line.length()==0) return; String[] portions = line.split(";"); String kind = portions[0]; String target = portions[1]; String source = portions[2]; String classNameDotMethodName = source; String className= classNameDotMethodName.substring(0, classNameDotMethodName.lastIndexOf('.')); if(reflectionView.isHideJREMethods()) { if(className.startsWith("java.") || className.startsWith("sun.") || className.startsWith("com.sun.")) { return; } } String methodName= classNameDotMethodName.substring(classNameDotMethodName.lastIndexOf('.')+1); int lineNumber=-1; if(portions.length>3) { lineNumber = Integer.parseInt(portions[3]); } CategoryNode categoryNode = insertNodeIfNecessary(kind); TreeParent sourceMethodNode; MethodNode ambMethodNode = new AmbiguousMethodNode(className,methodName,lineNumber).tryResolve(root.getProject()); if((sourceMethodNode=(TreeParent) categoryNode.childFor(ambMethodNode.getName()))==null) { categoryNode.addChild(sourceMethodNode = ambMethodNode); } if(classNamePattern.matcher(target).matches()) { //target is class sourceMethodNode.addChild(new ClassNode(target)); } else if(arrayTypeNamePattern.matcher(target).matches()) { //target is array Type sourceMethodNode.addChild(new ArrayNode(target)); } else if(target.contains("(")) { //target is method String targetClassName= target.substring(1,target.indexOf(':')); String targetSignature= target.substring(target.indexOf('('),target.length()-1); String targetMethodName= target.substring(0,target.length()-targetSignature.length()-1); targetMethodName = targetMethodName.substring(targetMethodName.lastIndexOf(' ')+1); sourceMethodNode.addChild(new ResolvedMethodNode(targetClassName,targetMethodName,targetSignature)); } else { //target is field String targetClassName= target.substring(1,target.indexOf(':')); String targetFieldName= target.substring(target.lastIndexOf(' ')+1,target.lastIndexOf('>')); String targetType = target.substring(target.indexOf(' ')+1,target.lastIndexOf(' ')); sourceMethodNode.addChild(new FieldNode(targetClassName,targetFieldName,targetType)); } } catch(RuntimeException e) { System.err.println("Failed to read line: "+line); e.printStackTrace(); } } public void removeUnusedNodes() { for(TreeObject node: root.getChildren()) { if(!((TreeParent)node).hasChildren()) { root.removeChild(node); } } } }