1b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato/* 2b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * ProGuard -- shrinking, optimization, obfuscation, and preverification 3b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * of Java bytecode. 4b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 5b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) 6b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 7b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * This program is free software; you can redistribute it and/or modify it 8b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * under the terms of the GNU General Public License as published by the Free 9b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Software Foundation; either version 2 of the License, or (at your option) 10b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * any later version. 11b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 12b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * This program is distributed in the hope that it will be useful, but WITHOUT 13b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 15b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * more details. 16b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 17b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * You should have received a copy of the GNU General Public License along 18b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * with this program; if not, write to the Free Software Foundation, Inc., 19b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 21b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratopackage proguard.obfuscate; 22b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 23b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.*; 24b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.util.*; 25b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.visitor.MemberVisitor; 26b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 27b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport java.util.*; 28b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 29b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato/** 30b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * This MemberVisitor obfuscates all class members that it visits. 31b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * It uses names from the given name factory. At the same time, it avoids names 32b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * from the given descriptor map. 33b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * <p> 34b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * The class members must have been linked before applying this visitor. 35b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 36b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @see MethodLinker 37b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 38b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @author Eric Lafortune 39b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 40b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratopublic class MemberObfuscator 41b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoextends SimplifiedVisitor 42b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimplements MemberVisitor 43b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato{ 44b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private final boolean allowAggressiveOverloading; 45b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private final NameFactory nameFactory; 46b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private final Map descriptorMap; 47b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 48b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 49b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato /** 50b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Creates a new MemberObfuscator. 51b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @param allowAggressiveOverloading a flag that specifies whether class 52b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * members can be overloaded aggressively. 53b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @param nameFactory the factory that can produce 54b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * obfuscated member names. 55b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @param descriptorMap the map of descriptors to 56b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * [new name - old name] maps. 57b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 58b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public MemberObfuscator(boolean allowAggressiveOverloading, 59b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato NameFactory nameFactory, 60b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato Map descriptorMap) 61b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 62b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato this.allowAggressiveOverloading = allowAggressiveOverloading; 63b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato this.nameFactory = nameFactory; 64b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato this.descriptorMap = descriptorMap; 65b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 66b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 67b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 68b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Implementations for MemberVisitor. 69b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 70b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public void visitAnyMember(Clazz clazz, Member member) 71b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 72b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Special cases: <clinit> and <init> are always kept unchanged. 73b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // We can ignore them here. 74b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato String name = member.getName(clazz); 75b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (name.equals(ClassConstants.INTERNAL_METHOD_NAME_CLINIT) || 76b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato name.equals(ClassConstants.INTERNAL_METHOD_NAME_INIT)) 77b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 78b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato return; 79b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 80b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 81b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Get the member's descriptor. 82b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato String descriptor = member.getDescriptor(clazz); 83b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 84b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Check whether we're allowed to do aggressive overloading 85b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (!allowAggressiveOverloading) 86b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 87b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Trim the return argument from the descriptor if not. 88b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Works for fields and methods alike. 89b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato descriptor = descriptor.substring(0, descriptor.indexOf(')')+1); 90b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 91b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 92b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Get the name map, creating a new one if necessary. 93b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato Map nameMap = retrieveNameMap(descriptorMap, descriptor); 94b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 95b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Get the member's new name. 96b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato String newName = newMemberName(member); 97b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 98b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Assign a new one, if necessary. 99b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (newName == null) 100b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 101b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Find an acceptable new name. 102b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato nameFactory.reset(); 103b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 104b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato do 105b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 106b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato newName = nameFactory.nextName(); 107b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 108b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato while (nameMap.containsKey(newName)); 109b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 110b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Remember not to use the new name again in this name space. 111b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato nameMap.put(newName, name); 112b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 113b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Assign the new name. 114b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato setNewMemberName(member, newName); 115b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 116b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 117b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 118b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 119b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Small utility methods. 120b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 121b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato /** 122b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Gets the name map, based on the given map and a given descriptor. 123b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * A new empty map is created if necessary. 124b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @param descriptorMap the map of descriptors to [new name - old name] maps. 125b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @param descriptor the class member descriptor. 126b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @return the corresponding name map. 127b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 128b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato static Map retrieveNameMap(Map descriptorMap, String descriptor) 129b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 130b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // See if we can find the nested map with this descriptor key. 131b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato Map nameMap = (Map)descriptorMap.get(descriptor); 132b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 133b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Create a new one if not. 134b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (nameMap == null) 135b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 136b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato nameMap = new HashMap(); 137b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato descriptorMap.put(descriptor, nameMap); 138b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 139b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 140b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato return nameMap; 141b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 142b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 143b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 144b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato /** 145b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Assigns a fixed new name to the given class member. 146b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @param member the class member. 147b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @param name the new name. 148b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 149b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato static void setFixedNewMemberName(Member member, String name) 150b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 151b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato VisitorAccepter lastVisitorAccepter = MethodLinker.lastVisitorAccepter(member); 152b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 153b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (!(lastVisitorAccepter instanceof LibraryMember) && 154b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato !(lastVisitorAccepter instanceof MyFixedName)) 155b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 156b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato lastVisitorAccepter.setVisitorInfo(new MyFixedName(name)); 157b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 158b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato else 159b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 160b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato lastVisitorAccepter.setVisitorInfo(name); 161b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 162b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 163b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 164b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 165b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato /** 166b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Assigns a new name to the given class member. 167b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @param member the class member. 168b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @param name the new name. 169b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 170b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato static void setNewMemberName(Member member, String name) 171b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 172b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato MethodLinker.lastVisitorAccepter(member).setVisitorInfo(name); 173b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 174b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 175b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 176b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato /** 177b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Returns whether the new name of the given class member is fixed. 178b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @param member the class member. 179b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @return whether its new name is fixed. 180b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 181b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato static boolean hasFixedNewMemberName(Member member) 182b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 183b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato VisitorAccepter lastVisitorAccepter = MethodLinker.lastVisitorAccepter(member); 184b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 185b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato return lastVisitorAccepter instanceof LibraryMember || 186b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato lastVisitorAccepter instanceof MyFixedName; 187b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 188b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 189b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 190b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato /** 191b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Retrieves the new name of the given class member. 192b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @param member the class member. 193b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @return the class member's new name, or <code>null</code> if it doesn't 194b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * have one yet. 195b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 196b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato static String newMemberName(Member member) 197b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 198b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato return (String)MethodLinker.lastVisitorAccepter(member).getVisitorInfo(); 199b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 200b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 201b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 202b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato /** 203b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * This VisitorAccepter can be used to wrap a name string, to indicate that 204b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * the name is fixed. 205b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 206b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private static class MyFixedName implements VisitorAccepter 207b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 208b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private String newName; 209b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 210b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 211b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public MyFixedName(String newName) 212b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 213b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato this.newName = newName; 214b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 215b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 216b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 217b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Implementations for VisitorAccepter. 218b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 219b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public Object getVisitorInfo() 220b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 221b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato return newName; 222b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 223b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 224b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 225b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public void setVisitorInfo(Object visitorInfo) 226b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 227b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato newName = (String)visitorInfo; 228b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 229b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 230b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato} 231