diff --git a/org.sf.feeling.decompiler/plugin.properties b/org.sf.feeling.decompiler/plugin.properties index aa77f7da..c9f757a2 100644 --- a/org.sf.feeling.decompiler/plugin.properties +++ b/org.sf.feeling.decompiler/plugin.properties @@ -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. \ No newline at end of file +Opcode.Hover.Description=Shows the document of the selected JVM opcode element. +NavigatorContent=Java Archive \ No newline at end of file diff --git a/org.sf.feeling.decompiler/plugin.xml b/org.sf.feeling.decompiler/plugin.xml index c518a321..df948333 100644 --- a/org.sf.feeling.decompiler/plugin.xml +++ b/org.sf.feeling.decompiler/plugin.xml @@ -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" @@ -357,5 +358,27 @@ - + + + + + + + + + + + + + + + + + diff --git a/org.sf.feeling.decompiler/src/org/sf/feeling/decompiler/JarContentProvider.java b/org.sf.feeling.decompiler/src/org/sf/feeling/decompiler/JarContentProvider.java new file mode 100644 index 00000000..b2d977f0 --- /dev/null +++ b/org.sf.feeling.decompiler/src/org/sf/feeling/decompiler/JarContentProvider.java @@ -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> nodes = new HashMap<>(); + private final Map 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( ) ); + 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 ); + } + +} diff --git a/org.sf.feeling.decompiler/src/org/sf/feeling/decompiler/JarLabelProvider.java b/org.sf.feeling.decompiler/src/org/sf/feeling/decompiler/JarLabelProvider.java new file mode 100644 index 00000000..1e6b7e33 --- /dev/null +++ b/org.sf.feeling.decompiler/src/org/sf/feeling/decompiler/JarLabelProvider.java @@ -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(); + } + +}