Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion org.sf.feeling.decompiler/plugin.properties
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,5 @@ ShowSourceCode=Show Source &Code
Decompiler.Filter.Description=Hides the Eclipse decompiler temporary project.
Decompiler.Filter=Eclipse decompiler temporary project
Opcode.Hover.Lable=JVM Opcode Doc
Opcode.Hover.Description=Shows the document of the selected JVM opcode element.
Opcode.Hover.Description=Shows the document of the selected JVM opcode element.
NavigatorContent=Java Archive
25 changes: 24 additions & 1 deletion org.sf.feeling.decompiler/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
name="%DecompilerView"
icon="icons/decompiler.png"
extensions="class"
default="true"
class="org.sf.feeling.decompiler.editor.JavaDecompilerClassFileEditor"
contributorClass="org.eclipse.jdt.internal.ui.javaeditor.ClassFileEditorActionContributor"
id="org.sf.feeling.decompiler.ClassFileEditor"
Expand Down Expand Up @@ -357,5 +358,27 @@
</extension>
<extension point="org.eclipse.help.toc">
<toc file="doc/toc.xml" primary="true" />
</extension>
</extension>
<extension
point="org.eclipse.ui.navigator.navigatorContent">
<navigatorContent
activeByDefault="true"
contentProvider="org.sf.feeling.decompiler.JarContentProvider"
id="org.sf.feeling.decompiler.navigatorContent"
labelProvider="org.sf.feeling.decompiler.JarLabelProvider"
name="%NavigatorContent">
<triggerPoints>
<or>
<instanceof value="org.eclipse.core.resources.IFile" />
<instanceof value="org.sf.feeling.decompiler.JarContentProvider.JarNode" />
</or>
</triggerPoints>
<possibleChildren>
<or>
<instanceof value="org.sf.feeling.decompiler.JarContentProvider.JarNode" />
<instanceof value="org.eclipse.core.resources.IFile" />
</or>
</possibleChildren>
</navigatorContent>
</extension>
</plugin>
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package org.sf.feeling.decompiler;

import java.io.File;
import java.net.JarURLConnection;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

import org.eclipse.core.resources.IFile;
import org.eclipse.ui.model.BaseWorkbenchContentProvider;



public class JarContentProvider extends BaseWorkbenchContentProvider
{
private static final String[] types = {"jar", "war"};
public class JarNode
{
private final URL url;
private final URL parent;
private final JarEntry entry;

public JarNode(URI jarfile, JarEntry entry) throws MalformedURLException {
this.url = new URL(String.format("jar:%s!/%s", jarfile, entry));
this.parent = new URL(String.format("jar:%s!/%s", jarfile,
entry.getName().substring(0, entry.getName()
.replaceAll("/$","").lastIndexOf("/")+1)));
this.entry = entry;
}
public JarNode(URL url, JarEntry entry) throws MalformedURLException {
this.url = url;
this.parent = new URL(url.toString( ).substring(0,
url.toString( ).replaceAll("/$","").lastIndexOf("/")+1));
this.entry = entry;
}

public URL toURL() {
return url;
}

public URL getParent() {
return parent;
}

public JarEntry getEntry() {
return entry;
}
}

private final Map<URL,List<JarNode>> nodes = new HashMap<>();
private final Map<String,IFile> files = new HashMap<>( );

private boolean isJavaArchive(IFile file) {
// return Arrays.binarySearch( types, file.getFileExtension() ) >= 0;
return true;
}

@Override
public Object[] getChildren( Object parentElement )
{
if ( parentElement instanceof IFile && isJavaArchive( (IFile) parentElement ) ) {
File f = ((IFile) parentElement).getLocation( ).toFile( );
try ( JarFile jf = new JarFile( f ) ) {
files.put( f.toURI( )+"!/", (IFile) parentElement );
for ( JarEntry je:Collections.list( jf.entries( ) ) ) {
JarNode node = new JarNode(f.toURI( ), je);
if (!nodes.containsKey( node.getParent( ) ))
nodes.put( node.getParent( ), new ArrayList<JarNode>( ) );
nodes.get( node.getParent( ) ).add( node );
}
return nodes.get( new URL( String.format( "jar:%s!/", f.toURI( ) ) ) ).toArray( );
} catch (Throwable t) {};
}
if (parentElement instanceof JarNode && ((JarNode) parentElement).getEntry( ).isDirectory( ))
return nodes.get( ((JarNode) parentElement).toURL( ) ).toArray( );
return new Object[0];
}

@Override
public Object getParent( Object element )
{
if (element instanceof JarNode) {
JarNode node = (JarNode) element;
try
{
return new JarNode(node.getParent( ),
((JarURLConnection) node.getParent( ).openConnection( )).getJarEntry( ));
} catch ( Throwable t ) {
try
{
return files.get( node.getParent( ).toURI( ).getSchemeSpecificPart( ) );
} catch ( URISyntaxException e ) {}
}
}
return super.getParent( element );
}

@Override
public boolean hasChildren( Object element )
{
if (element instanceof JarNode)
return nodes.containsKey( ((JarNode) element).toURL( ) );
return super.hasChildren( element );
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package org.sf.feeling.decompiler;

import org.eclipse.jface.viewers.LabelProvider;


public class JarLabelProvider extends LabelProvider
{
@Override
public String getText(Object element) {
if (null == element)
return "";
if (element instanceof JarContentProvider.JarNode) {
String n = ((JarContentProvider.JarNode) element)
.getEntry( ).getName( ).replaceAll( "/$", "" );
return n.substring( n.lastIndexOf( '/' ), n.length( ) );
}
return element.toString();
}

}