summaryrefslogtreecommitdiff
path: root/src/cuchaz/enigma/mapping/Ancestries.java
diff options
context:
space:
mode:
authorGravatar jeff2014-08-11 00:02:00 -0400
committerGravatar jeff2014-08-11 00:02:00 -0400
commitbba7c6a19c15bc82946176c79a4eba3612b25f17 (patch)
treef0b55befaa6e7e532e9728dfa6b1c9cb36660594 /src/cuchaz/enigma/mapping/Ancestries.java
parentadded backwards navigation (diff)
downloadenigma-fork-bba7c6a19c15bc82946176c79a4eba3612b25f17.tar.gz
enigma-fork-bba7c6a19c15bc82946176c79a4eba3612b25f17.tar.xz
enigma-fork-bba7c6a19c15bc82946176c79a4eba3612b25f17.zip
added method inheritance browsing
also finally fixed method renamer to rename all method implementations in the inheritance hierarchy.
Diffstat (limited to 'src/cuchaz/enigma/mapping/Ancestries.java')
-rw-r--r--src/cuchaz/enigma/mapping/Ancestries.java154
1 files changed, 0 insertions, 154 deletions
diff --git a/src/cuchaz/enigma/mapping/Ancestries.java b/src/cuchaz/enigma/mapping/Ancestries.java
deleted file mode 100644
index 894cf80..0000000
--- a/src/cuchaz/enigma/mapping/Ancestries.java
+++ /dev/null
@@ -1,154 +0,0 @@
1/*******************************************************************************
2 * Copyright (c) 2014 Jeff Martin.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the GNU Public License v3.0
5 * which accompanies this distribution, and is available at
6 * http://www.gnu.org/licenses/gpl.html
7 *
8 * Contributors:
9 * Jeff Martin - initial API and implementation
10 ******************************************************************************/
11package cuchaz.enigma.mapping;
12
13import java.io.ByteArrayOutputStream;
14import java.io.IOException;
15import java.io.InputStream;
16import java.io.Serializable;
17import java.util.ArrayList;
18import java.util.List;
19import java.util.Map;
20import java.util.zip.ZipEntry;
21import java.util.zip.ZipInputStream;
22
23import javassist.ByteArrayClassPath;
24import javassist.ClassPool;
25import javassist.CtClass;
26import javassist.NotFoundException;
27import javassist.bytecode.Descriptor;
28
29import com.google.common.collect.Lists;
30import com.google.common.collect.Maps;
31
32import cuchaz.enigma.Constants;
33
34public class Ancestries implements Serializable
35{
36 private static final long serialVersionUID = 738687982126844179L;
37
38 private Map<String,String> m_superclasses;
39
40 public Ancestries( )
41 {
42 m_superclasses = Maps.newHashMap();
43 }
44
45 public void readFromJar( InputStream in )
46 throws IOException
47 {
48 ClassPool classPool = new ClassPool();
49
50 ZipInputStream zin = new ZipInputStream( in );
51 ZipEntry entry;
52 while( ( entry = zin.getNextEntry() ) != null )
53 {
54 // filter out non-classes
55 if( entry.isDirectory() || !entry.getName().endsWith( ".class" ) )
56 {
57 continue;
58 }
59
60 // read the class into a buffer
61 ByteArrayOutputStream bos = new ByteArrayOutputStream();
62 byte[] buf = new byte[Constants.KiB];
63 int totalNumBytesRead = 0;
64 while( zin.available() > 0 )
65 {
66 int numBytesRead = zin.read( buf );
67 if( numBytesRead < 0 )
68 {
69 break;
70 }
71 bos.write( buf, 0, numBytesRead );
72
73 // sanity checking
74 totalNumBytesRead += numBytesRead;
75 if( totalNumBytesRead > Constants.MiB )
76 {
77 throw new Error( "Class file " + entry.getName() + " larger than 1 MiB! Something is wrong!" );
78 }
79 }
80
81 // determine the class name (ie chop off the ".class")
82 String className = Descriptor.toJavaName( entry.getName().substring( 0, entry.getName().length() - ".class".length() ) );
83
84 // get a javassist handle for the class
85 classPool.insertClassPath( new ByteArrayClassPath( className, bos.toByteArray() ) );
86 try
87 {
88 CtClass c = classPool.get( className );
89 addSuperclass( c.getName(), c.getClassFile().getSuperclass() );
90 }
91 catch( NotFoundException ex )
92 {
93 throw new Error( "Unable to load class: " + className );
94 }
95 }
96 }
97
98 public void addSuperclass( String className, String superclassName )
99 {
100 className = Descriptor.toJvmName( className );
101 superclassName = Descriptor.toJvmName( superclassName );
102
103 if( className.equals( superclassName ) )
104 {
105 throw new IllegalArgumentException( "Class cannot be its own superclass! " + className );
106 }
107
108 if( !isJre( className ) && !isJre( superclassName ) )
109 {
110 m_superclasses.put( className, superclassName );
111 }
112 }
113
114 public String getSuperclassName( String className )
115 {
116 return m_superclasses.get( className );
117 }
118
119 public List<String> getAncestry( String className )
120 {
121 List<String> ancestors = new ArrayList<String>();
122 while( className != null )
123 {
124 className = getSuperclassName( className );
125 if( className != null )
126 {
127 ancestors.add( className );
128 }
129 }
130 return ancestors;
131 }
132
133 public List<String> getSubclasses( String className )
134 {
135 // linear search is fast enough for now
136 List<String> subclasses = Lists.newArrayList();
137 for( Map.Entry<String,String> entry : m_superclasses.entrySet() )
138 {
139 String subclass = entry.getKey();
140 String superclass = entry.getValue();
141 if( className.equals( superclass ) )
142 {
143 subclasses.add( subclass );
144 }
145 }
146 return subclasses;
147 }
148
149 private boolean isJre( String className )
150 {
151 return className.startsWith( "java/" )
152 || className.startsWith( "javax/" );
153 }
154}