Identifier.java :  » Development » jode » jode » obfuscator » Java Open Source

Java Open Source » Development » jode 
jode » jode » obfuscator » Identifier.java
/* Identifier Copyright (C) 1999-2002 Jochen Hoenicke.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; see the file COPYING.  If not, write to
 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * $Id: Identifier.java.in,v 1.4.2.2 2002/05/28 17:34:14 hoenicke Exp $
 */

package jode.obfuscator;
import jode.GlobalOptions;
import java.io.*;
import java.util.Map;
import java.util.Iterator;

public abstract class Identifier {
    /**
     * This is a doubly list of identifiers, that must have always
     * have the same names, and same preserved settings.
     */
    private Identifier right = null;
    private Identifier left  = null;

    private boolean reachable = false;
    private boolean preserved = false;

    private String alias = null;
    private boolean wasAliased = false;
    
    public Identifier(String alias) {
  this.alias = alias;
    }


    /**
     * Returns true, if this identifier is reachable in some way, false if it
     * is dead and can be removed.
     */
    public final boolean isReachable() {
  return reachable;
    }

    /**
     * true, if this identifier must preserve its name, false if the
     * name may be obfuscated.
     */
    public final boolean isPreserved() {
  return preserved;
    }

    /**
     * Marks this identifier as preserved. This will also make the
     * identifier reachable, if it isn't already.
     *
     * You shouldn't call this directly, but use setPreserved instead.
     */
    protected void setSinglePreserved() {
    }

    /**
     * Marks this identifier as reachable.  
     *
     * You should override this method for method identifier, which may
     * mark other methods as reachable.
     *
     * You shouldn't call this directly, but use setReachable instead.
     */
    protected void setSingleReachable() {
  if (getParent() != null)
      getParent().setReachable();
    }

    /**
     * Mark all shadows as reachable.
     */
    public void setReachable() {
  if (!reachable) {
      reachable = true;
      setSingleReachable();
  }
    }

    /**
     * Mark all shadows as preserved.
     */
    public void setPreserved() {
  if (!preserved) {
      preserved = true;
      Identifier ptr = this;
      while (ptr != null) {
    ptr.setSinglePreserved();
    ptr = ptr.left;
      }
      ptr = right;
      while (ptr != null) {
    ptr.setSinglePreserved();
    ptr = ptr.right;
      }
  }
    }

    public Identifier getRepresentative() {
  Identifier ptr = this;
  while (ptr.left != null)
      ptr = ptr.left;
  return ptr;
    }

    public final boolean isRepresentative() {
  return left == null;
    }

    public final boolean wasAliased() {
  return getRepresentative().wasAliased;
    }

    public final void setAlias(String name) {
  if (name != null) {
      Identifier rep = getRepresentative();
      rep.wasAliased = true;
      rep.alias = name;
  }
    }

    public final String getAlias() {
  return getRepresentative().alias;
    }

    /**
     * Mark that this identifier and the given identifier must always have
     * the same name.
     */
    public void addShadow(Identifier orig) {
  if (isPreserved() && !orig.isPreserved())
      orig.setPreserved();
  else if (!isPreserved() && orig.isPreserved())
      setPreserved();
  
  Identifier ptr = this;
  while (ptr.right != null)
      ptr = ptr.right;

  /* Check if orig is already on the ptr chain */
  Identifier check = orig;
  while (check.right != null)
      check = check.right;
  if (check == ptr)
      return;

  while (orig.left != null)
      orig = orig.left;
  ptr.right = orig;
  orig.left = ptr;
    }

    static int serialnr = 0;

    public void buildTable(Renamer renameRule) {
  if (!isReachable()
      && (Main.stripping & Main.STRIP_UNREACH) != 0) 
      return;

  if (isPreserved()) {
      if (GlobalOptions.verboseLevel > 4)
    GlobalOptions.err.println(toString() + " is preserved");
  } else {
      Identifier rep = getRepresentative();
      if (!rep.wasAliased) {
    rep.wasAliased = true;

    // set alias to empty string, so it won't conflict!
    rep.alias = "";
    Iterator aliases = renameRule.generateNames(this);
      next_alias:
    for (;;) {
        String newAlias = (String) aliases.next();
        Identifier ptr = rep;
        while (ptr != null) {
      if (ptr.conflicting(newAlias))
          continue next_alias;
      ptr = ptr.right;
        }
        setAlias(newAlias.toString());
        break;
    }
      }
  }
  for (Iterator i = getChilds(); i.hasNext(); )
      ((Identifier)i.next()).buildTable(renameRule);
    }

    public void writeTable(Map table, boolean reversed) {
  if (!isReachable() 
      && (Main.stripping & Main.STRIP_UNREACH) != 0) 
      return;

  if (getAlias().length() != 0) {
      String name = getName();
      Identifier outer = getParent();
      while (outer != null && outer.getAlias().length() == 0) {
    if (outer.getName().length() > 0)
        name = outer.getName() + "." + name;
    outer = outer.getParent();
      }
      if (reversed)
    table.put(getFullAlias(), name);
      else
    table.put(getFullName(), getAlias());
  }

  for (Iterator i = getChilds(); i.hasNext(); )
      ((Identifier)i.next()).writeTable(table, reversed);
    }

    public void readTable(Map table) {
  Identifier rep = getRepresentative();
  if (!rep.wasAliased) {
      String newAlias = (String) table.get(getFullName());
      if (newAlias != null) {
    rep.wasAliased = true;
    rep.setAlias(newAlias);
      }
  }
  for (Iterator i = getChilds(); i.hasNext(); )
      ((Identifier)i.next()).readTable(table);
    }

    public void applyPreserveRule(IdentifierMatcher preserveRule) {
  if (preserveRule.matches(this)) {
      System.err.println("preserving: "+this);
      setReachable();
      Identifier ident = this;
      while (ident != null) {
    ident.setPreserved();
    ident = ident.getParent();
      }
  }
  for (Iterator i = getChilds(); i.hasNext(); )
      ((Identifier)i.next()).applyPreserveRule(preserveRule);
    }
    public abstract Iterator getChilds();
    public abstract Identifier getParent();
    public abstract String getName();
    public abstract String getType();
    public abstract String getFullName();
    public abstract String getFullAlias();
    public abstract boolean conflicting(String newAlias);

    /**
     * This is called by ClassBundle when it a class is added with
     * ClassBundle.analyzeIdentifier().
     */
    public void analyze() {
    }
}
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.