PackageNamer.java :  » Code-Analyzer » soot » soot » dava » toolkits » base » misc » Java Open Source

Java Open Source » Code Analyzer » soot 
soot » soot » dava » toolkits » base » misc » PackageNamer.java
/* Soot - a J*va Optimization Framework
 * Copyright (C) 2003 Jerome Miecznikowski
 *
 * This library 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 2.1 of the License, or (at your option) any later version.
 *
 * This library 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 this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

package soot.dava.toolkits.base.misc;

import soot.*;
import java.io.*;
import java.util.*;
import soot.util.*;
import soot.dava.*;
import java.util.jar.*;

public class PackageNamer
{
    public PackageNamer( Singletons.Global g ) {}
    public static PackageNamer v() { return G.v().soot_dava_toolkits_base_misc_PackageNamer(); }

    public boolean has_FixedNames(){  
      return fixed;
    }

    public boolean use_ShortName( String fixedPackageName, String fixedShortClassName){
      if (fixed == false)
        return false;

      if (fixedPackageName.equals( Dava.v().get_CurrentPackage()))
        return true;

      IterableSet packageContext = Dava.v().get_CurrentPackageContext();
      if (packageContext == null)
        return true;

      packageContext = patch_PackageContext( packageContext);

      int count = 0;
      StringTokenizer st = new StringTokenizer( classPath, pathSep);
      while (st.hasMoreTokens()) {
        String classpathDir = st.nextToken();
        
        Iterator packIt = packageContext.iterator();
        while (packIt.hasNext()) 
          if (package_ContainsClass( classpathDir, (String) packIt.next(), fixedShortClassName))
            if (++count > 1)
              return false;
      }

      return true;
    }

    public String get_FixedClassName( String originalFullClassName)
    {
  if (fixed == false)
      return originalFullClassName;

  Iterator<NameHolder> it = appRoots.iterator();
  while (it.hasNext()) {
      NameHolder h = it.next();
      if (h.contains_OriginalName( new StringTokenizer( originalFullClassName, "."), true))
    return h.get_FixedName( new StringTokenizer( originalFullClassName, "."), true);
  }
  
  return originalFullClassName.substring( originalFullClassName.lastIndexOf( ".") + 1);
    }

    public String get_FixedPackageName( String originalPackageName)
    {
  if (fixed == false)
      return originalPackageName;

  if (originalPackageName.equals( ""))
      return "";

  Iterator<NameHolder> it = appRoots.iterator();
  while (it.hasNext()) {
      NameHolder h = it.next();
      if (h.contains_OriginalName( new StringTokenizer( originalPackageName, "."), false))
    return h.get_FixedName( new StringTokenizer( originalPackageName, "."), false);
  }

  return originalPackageName;
    }


    private class NameHolder
    {
      private final String originalName;
    private String packageName, className;
      private final ArrayList<NameHolder> children;
      private NameHolder parent;
      private boolean isClass;
  

      public NameHolder( String name, NameHolder parent, boolean isClass)
      {
        originalName = name;
        className = name;
        packageName = name;
        
        this.parent = parent;
        this.isClass = isClass;

        children = new ArrayList<NameHolder>();
      }

      public NameHolder get_Parent() {
      return parent;
    }

    public void set_ClassAttr() {
      isClass = true;
    }

    public boolean is_Class() {
      if (children.isEmpty())
        return true;
      else
        return isClass;
    }

    public boolean is_Package() {
      return (children.isEmpty() == false);
    }

    public String get_PackageName() {
      return packageName;
    }

    public String get_ClassName() {
      return className;
    }

    public void set_PackageName(String packageName) {
      this.packageName = packageName;
    }

    public void set_ClassName(String className) {
      this.className = className;
    }

    public String get_OriginalName() {
      return originalName;
    }

    public ArrayList<NameHolder> get_Children() {
      return children;
    }

    public String get_FixedPackageName() {
      if (parent == null)
        return "";

      return parent.retrieve_FixedPackageName();
    }

  public String retrieve_FixedPackageName()
  {
      if (parent == null)
    return packageName;
      
      return parent.get_FixedPackageName() + "." + packageName;
  }

  public String get_FixedName( StringTokenizer st, boolean forClass)
  {
      if (st.nextToken().equals( originalName) == false)
    throw new RuntimeException( "Unable to resolve naming.");

      return retrieve_FixedName( st, forClass);
  }

  private String retrieve_FixedName( StringTokenizer st, boolean forClass)
  {
      if (st.hasMoreTokens() == false) {
    if (forClass)
        return className;
    else
        return packageName;
      }

      String subName = st.nextToken();
      Iterator<NameHolder> cit = children.iterator();
      while (cit.hasNext()) {
        NameHolder h = cit.next();

        if (h.get_OriginalName().equals( subName)) {
          if (forClass)
            return h.retrieve_FixedName( st, forClass);
          else 
            return packageName + "." + h.retrieve_FixedName( st, forClass);
        }
      }
      throw new RuntimeException( "Unable to resolve naming.");
  }

  public String get_OriginalPackageName( StringTokenizer st)
  {
      if (st.hasMoreTokens() == false)
    return get_OriginalName();

      String subName = st.nextToken();

      Iterator<NameHolder> cit = children.iterator();
      while (cit.hasNext()) {
    NameHolder h = cit.next();

    if (h.get_PackageName().equals( subName)) {
        String originalSubPackageName = h.get_OriginalPackageName( st);

        if (originalSubPackageName == null)
      return null;
        else
      return get_OriginalName() + "." + originalSubPackageName;
    }
      }

      return null;
  }

  public boolean contains_OriginalName( StringTokenizer st, boolean forClass)
  {
      if (get_OriginalName().equals( st.nextToken()) == false)
    return false;

      return finds_OriginalName( st, forClass);
  }

  private boolean finds_OriginalName( StringTokenizer st, boolean forClass)
  {
      if (st.hasMoreTokens() == false)
    return (((forClass) && (is_Class())) || ((!forClass) && (is_Package())));

      String subName = st.nextToken();
      Iterator<NameHolder> cit = children.iterator();
      while (cit.hasNext()) {
    NameHolder h = cit.next();

    if (h.get_OriginalName().equals( subName))
        return h.finds_OriginalName( st, forClass);
      }
      
      return false;
  }

  public void fix_ClassNames( String curPackName)
  {
      if ((is_Class()) && (keywords.contains( className))) {
    String tClassName = className;
    
    if (Character.isLowerCase( className.charAt( 0))) {
        tClassName = tClassName.substring( 0, 1).toUpperCase() + tClassName.substring( 1);
        className = tClassName;
    }
    
    for (int i=0; keywords.contains( className); i++)
        className = tClassName + "_c" + i;
      }

      Iterator<NameHolder> it = children.iterator();
      while (it.hasNext())
    it.next().fix_ClassNames( curPackName + "." + packageName);
  }

  public void fix_PackageNames()
  {
      if ((is_Package()) && (verify_PackageName() == false)) {
    String tPackageName = packageName;

    if (Character.isUpperCase( packageName.charAt( 0))) {
        tPackageName = tPackageName.substring( 0, 1).toLowerCase() + tPackageName.substring( 1);
        packageName = tPackageName;
    }
    
    for (int i=0; verify_PackageName() == false; i++)
        packageName = tPackageName + "_p" + i;
      }

      Iterator<NameHolder> it = children.iterator();
      while (it.hasNext())
    it.next().fix_PackageNames();
  }


  public boolean verify_PackageName()
  {
      return ((keywords.contains( packageName) == false) && 
        (siblingClashes( packageName) == false) &&
        ((is_Class() == false) || (className.equals( packageName) == false)));
  }

  public boolean siblingClashes( String name)
  {
      Iterator<NameHolder> it = null;

      if (parent == null) {

    if (appRoots.contains( this))
        it = appRoots.iterator();
    else
        throw new RuntimeException( "Unable to find package siblings.");
      }
      else 
    it = parent.get_Children().iterator();

      while (it.hasNext()) {
    NameHolder sibling = it.next();

    if (sibling == this)
        continue;

    if (((sibling.is_Package()) && (sibling.get_PackageName().equals( name))) ||
        ((sibling.is_Class()) && (sibling.get_ClassName().equals( name))))
        
        return true;
      }

      return false;
  }

  public void dump( String indentation)
  {
      G.v().out.print( indentation + "\"" + originalName + "\", \"" + packageName + "\", \"" + className + "\" (");
      if (is_Class())
    G.v().out.print("c");
      if (is_Package())
    G.v().out.print("p");
      G.v().out.println( ")");

      Iterator<NameHolder> it = children.iterator();
      while (it.hasNext())
        it.next().dump( indentation + "  ");
    }
    }

    private boolean fixed = false;
    private final ArrayList<NameHolder> appRoots = new ArrayList<NameHolder>();
    private final ArrayList<NameHolder> otherRoots = new ArrayList<NameHolder>();
    private final HashSet<String> keywords = new HashSet<String>();
    private char fileSep;
    private String classPath, pathSep;
    
    public void fixNames()
    {
  if (fixed)
      return;

  String[] keywordArray =
  {
      "abstract",      "default",      "if",            "private",      "this",      "boolean",
      "do",      "implements",      "protected",      "throw",      "break",
      "double",      "import",      "public",      "throws",      "byte",      "else",
      "instanceof",      "return",      "transient",      "case",      "extends",
      "int",      "short",      "try",      "catch",      "final",      "interface",
      "static",      "void",             "char",      "finally",      "long",      "strictfp",
      "volatile",      "class",      "float",      "native",      "super",      "while",
      "const",      "for",      "new",      "switch",      "continue",      "goto",
      "package",      "synchronized",      "true",      "false",      "null"
  };

  for (String element : keywordArray)
    keywords.add( element);

  Iterator classIt = Scene.v().getLibraryClasses().iterator();
  while (classIt.hasNext())
      add_ClassName( ((SootClass) classIt.next()).getName(), otherRoots);

  classIt = Scene.v().getApplicationClasses().iterator();
  while (classIt.hasNext())
      add_ClassName( ((SootClass) classIt.next()).getName(), appRoots);

  Iterator<NameHolder> arit = appRoots.iterator();
  while (arit.hasNext())
      arit.next().fix_ClassNames( "");

  arit = appRoots.iterator();
  while (arit.hasNext())
      arit.next().fix_PackageNames();
  
  fileSep = System.getProperty( "file.separator").charAt(0);
  pathSep = System.getProperty( "path.separator");
  classPath = System.getProperty( "java.class.path");
  
  fixed = true;
    }

    private void add_ClassName( String className, ArrayList<NameHolder> roots)
    {
  ArrayList<NameHolder> children = roots;
  NameHolder curNode = null;
  
  StringTokenizer st = new StringTokenizer( className, ".");
  while (st.hasMoreTokens()) {
      String curName = st.nextToken();

      NameHolder child = null;
      boolean found = false;
      Iterator<NameHolder> lit = children.iterator();
      
      while (lit.hasNext()) {
    child = lit.next();
    
    if (child.get_OriginalName().equals( curName)) {

        if (st.hasMoreTokens() == false)
      child.set_ClassAttr();

        found = true;
        break;
    }
      }
    
      if (!found) {
    child = new NameHolder( curName, curNode, st.hasMoreTokens() == false);
    children.add( child);
      }
      
      curNode = child;
      children = child.get_Children();
  }
    }

    public boolean package_ContainsClass( String classpathDir, String packageName, String className)
    {
  File p = new File( classpathDir);

  if (p.exists() == false)
      return false;

  packageName = packageName.replace( '.', fileSep);
  if ((packageName.length() > 0) && (packageName.charAt( packageName.length() - 1) != fileSep))
      packageName += fileSep;

  String name = packageName + className + ".class";

  if (p.isDirectory()) {
      if ((classpathDir.length() > 0) && (classpathDir.charAt( classpathDir.length() - 1) != fileSep))
    classpathDir += fileSep;
      
      return (new File( classpathDir + name)).exists();
  }

  else {
      JarFile jf = null;

      try {
    jf = new JarFile( p);
      }
      catch (IOException ioe) {
    return false;
      }

      return (jf.getJarEntry( name) != null);
  }
    }

    IterableSet patch_PackageContext( IterableSet currentContext) 
    {
  IterableSet newContext = new IterableSet();

  Iterator it = currentContext.iterator();
  while (it.hasNext()) {
      String 
    currentPackage = (String) it.next(),
    newPackage = null;

      StringTokenizer st = new StringTokenizer( currentPackage, ".");
      
      if (st.hasMoreTokens() == false) {
    newContext.add( currentPackage);
    continue;
      }

      String firstToken = st.nextToken();
      Iterator<NameHolder> arit = appRoots.iterator();
      while (arit.hasNext()) {
    NameHolder h = arit.next();

    if (h.get_PackageName().equals( firstToken)) {
        newPackage = h.get_OriginalPackageName( st);
        break;
    }
      }
      if (newPackage != null)
    newContext.add( newPackage);
      else
    newContext.add( currentPackage);
  }

  return newContext;
    }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.