/* * Copyright (C) 2012 Sony Mobile Communications AB * * This file is part of ApkAnalyser. * * 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 analyser.gui; import java.awt.Color; import java.awt.Component; import java.awt.Font; import java.awt.Graphics; import javax.swing.JTree; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeCellRenderer; import mereflect.JarClassContext; import mereflect.MEClass; import mereflect.MEClassContext; import mereflect.MEField; import mereflect.MEMethod; import mereflect.UnknownResContext; import analyser.logic.RefAndroidManifest; import analyser.logic.RefClass; import analyser.logic.RefContext; import analyser.logic.RefField; import analyser.logic.RefFieldAccess; import analyser.logic.RefFolder; import analyser.logic.RefInvokation; import analyser.logic.RefMethod; import analyser.logic.RefPackage; import analyser.logic.RefResReference; import analyser.logic.RefResSpec; import analyser.logic.RefXml; import analyser.logic.Reference; import andreflect.ApkClassContext; public class ClassTreeRenderer extends DefaultTreeCellRenderer { private static final long serialVersionUID = -931509497453027963L; public static FlagIcon ICON_CLASS = createImageIcon("class.png"); public static FlagIcon ICON_INTERFACE = createImageIcon("interface.png"); public static FlagIcon ICON_FOLDER = createImageIcon("folder.png"); public static FlagIcon ICON_INVOKATION = createImageIcon("invokation.png"); public static FlagIcon ICON_LOCAL_INVOKATION = createImageIcon("localinvokation.png"); public static FlagIcon ICON_JAR = createImageIcon("jar.png"); public static FlagIcon ICON_APK = createImageIcon("apk.png"); public static FlagIcon ICON_PUBLICMETHOD = createImageIcon("methpub_obj.gif"); public static FlagIcon ICON_PROTECTEDMETHOD = createImageIcon("methpro_obj.gif"); public static FlagIcon ICON_PACKAGEMETHOD = createImageIcon("packagemethod.png"); public static FlagIcon ICON_PRIVATEMETHOD = createImageIcon("methpri_obj.gif"); public static FlagIcon ICON_PACKAGE = createImageIcon("package.png"); public static FlagIcon ICON_PUBLICFIELD = createImageIcon("field_public_obj.gif"); public static FlagIcon ICON_PROTECTEDFIELD = createImageIcon("field_protected_obj.gif"); public static FlagIcon ICON_PACKAGEMFIELD = createImageIcon("field_default_obj.gif"); public static FlagIcon ICON_PRIVATEFIELD = createImageIcon("field_private_obj.gif"); public static FlagIcon ICON_XML = createImageIcon("XMLFile.gif"); public static FlagIcon ICON_ANDROID = createImageIcon("android_file.png"); public static FlagIcon ICON_PACKAGEFOLDER = createImageIcon("packagefolder_obj.gif"); public static FlagIcon ICON_FIELDREAD = createImageIcon("read_obj.png"); public static FlagIcon ICON_FIELDWRITE = createImageIcon("write_obj.png"); public static FlagIcon ICON_JAVAFILE = createImageIcon("jcu_obj.gif"); final static Color COLOR_MARKED = new Color(0, 0, 128); protected boolean m_drawCount = false; protected boolean m_drawCountGlobal = false; protected int m_count; static Font originalFont = null; static Font markedFont = null; public ClassTreeRenderer(boolean drawCount) { m_drawCountGlobal = drawCount; } @Override public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) { super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus); if (originalFont == null) { originalFont = getFont(); } if (originalFont != null && markedFont == null) { markedFont = originalFont.deriveFont(Font.BOLD); } Object val = ((DefaultMutableTreeNode) value).getUserObject(); String text = val.toString(); if (val instanceof Reference) { Reference ref = (Reference) val; FlagIcon fIcon = null; int flags = 0; m_drawCount = m_drawCountGlobal; m_count = ref.getCount(); if (ref instanceof RefContext) { MEClassContext ctx = ((RefContext) ref).getContext(); if (ctx.getContextDescription().equals(JarClassContext.DESCRIPTION)) { if (ctx.getDexReferenceCache().hasSpec()) { fIcon = ICON_APK; } else { fIcon = ICON_JAR; } } else if (ctx.getContextDescription().equals(ApkClassContext.DESCRIPTION)) { fIcon = ICON_APK; } else if (ctx.getContextDescription().equals(UnknownResContext.DESCRIPTION)) { fIcon = ICON_FOLDER; flags |= FlagIcon.FLAG_ANDROID; } else { fIcon = ICON_FOLDER; } setToolTipText("[" + m_count + "] " + ctx.getContextName()); } else if (ref instanceof RefPackage) { fIcon = ICON_PACKAGE; setToolTipText("[" + m_count + "] " + ((RefPackage) ref).getName()); } else if (ref instanceof RefClass) { MEClass c = ((RefClass) ref).getMEClass(); if (c.isInterface()) { fIcon = ICON_INTERFACE; } else { fIcon = ICON_CLASS; } setToolTipText("[" + m_count + "] " + ((RefClass) ref).getMEClass().getName()); } else if (ref instanceof RefMethod) { MEMethod method = ((RefMethod) ref).getMethod(); if (method.isPublic()) { fIcon = ICON_PUBLICMETHOD; } else if (method.isProtected()) { fIcon = ICON_PROTECTEDMETHOD; } else if (method.isPrivate()) { fIcon = ICON_PRIVATEMETHOD; } else { fIcon = ICON_PACKAGEMETHOD; } flags |= method.isNative() ? FlagIcon.FLAG_NATIVE : 0; flags |= method.isConstructor() ? FlagIcon.FLAG_CONSTRUCTOR : 0; flags |= method.isStatic() ? FlagIcon.FLAG_STATIC : 0; flags |= method.isFinal() ? FlagIcon.FLAG_FINAL : 0; setToolTipText("[" + m_count + "] " + method.toString()); } else if (ref instanceof RefInvokation) { fIcon = ((RefInvokation) ref).isLocal() ? ICON_LOCAL_INVOKATION : ICON_INVOKATION; if (((RefInvokation) ref).getOppositeInvokation() != null) { setToolTipText("[" + m_count + "] " + (((RefInvokation) ref).getOppositeInvokation().getResourceName())); } } else if (ref instanceof RefField) { MEField field = ((RefField) ref).getField(); if (field.isPublic()) { fIcon = ICON_PUBLICFIELD; } else if (field.isProtected()) { fIcon = ICON_PROTECTEDFIELD; } else if (field.isPrivate()) { fIcon = ICON_PRIVATEFIELD; } else { fIcon = ICON_PACKAGEMFIELD; } flags |= field.isStatic() ? FlagIcon.FLAG_STATIC : 0; flags |= field.isFinal() ? FlagIcon.FLAG_FINAL : 0; } else if (ref instanceof RefFolder) { int type = ((RefFolder) ref).getType(); switch (type) { case RefFolder.SRC: fIcon = ICON_PACKAGEFOLDER; break; case RefFolder.RES: fIcon = ICON_FOLDER; flags |= FlagIcon.FLAG_ANDROID; break; case RefFolder.XML: fIcon = ICON_XML; break; case RefFolder.RESTYPE: case RefFolder.UNKNOWN: fIcon = ICON_FOLDER; m_drawCount = true; break; } } else if (ref instanceof RefAndroidManifest) { fIcon = ICON_ANDROID; } else if (ref instanceof RefResSpec) { fIcon = ICON_ANDROID; setToolTipText("[" + m_count + "] " + ((RefResSpec) ref).getName()); m_drawCount = true; } else if (ref instanceof RefFieldAccess) { if (((RefFieldAccess) ref).getAccess().isRead) { fIcon = ICON_FIELDREAD; } else { fIcon = ICON_FIELDWRITE; } } else if (ref instanceof RefResReference) { if (((RefResReference) ref).isRes()) { fIcon = ICON_ANDROID; } else if (((RefResReference) ref).isXml()) { fIcon = ICON_XML; } else if (((RefResReference) ref).isCode()) { fIcon = ICON_JAVAFILE; } m_drawCount = true; } else if (ref instanceof RefXml) { fIcon = ICON_XML; } flags |= ((ref.getFlags() & Reference.FAILED) > 0) ? FlagIcon.FLAG_FAIL : 0; flags |= ((ref.getFlags() & Reference.NOTFOUND) > 0) ? FlagIcon.FLAG_UNKNOWN : 0; flags |= ((ref.getFlags() & Reference.MODIFIED) != 0) ? FlagIcon.FLAG_MODIFIED : 0; fIcon.setFlags(flags); setIcon(fIcon); } else { m_drawCount = false; } if (m_drawCount) { setText(" " + text); } else { setText(text); } if (((ClassTree) tree).isMarked((DefaultMutableTreeNode) value)) { setFont(markedFont); setForeground(COLOR_MARKED); } else { setFont(originalFont); setForeground(Color.black); } return this; } @Override public void paint(Graphics g) { super.paint(g); if (m_drawCount) { String cStr = "[" + m_count + "]"; g.setColor(Color.GRAY); g.drawString(cStr, getIcon().getIconWidth() + getIconTextGap(), getFont().getSize() + 1); } } protected static FlagIcon createImageIcon(String path) { java.net.URL imgURL = Thread.currentThread().getContextClassLoader().getResource(path); if (imgURL != null) { return new FlagIcon(imgURL, 0); } else { System.err.println("Couldn't find file: " + path); return null; } } }