From e1a93aaae512e6791876c920481fbac99af3b2d0 Mon Sep 17 00:00:00 2001 From: emmanue1 Date: Fri, 26 Jun 2015 19:11:10 +0200 Subject: [PATCH] Closes #43, adds "Copy Qualified Name" contextual menu --- api/src/main/java/jd/gui/api/API.java | 2 + api/src/main/java/jd/gui/api/model/Type.java | 4 + .../jd/gui/spi/ContextualActionsFactory.java | 26 ++ .../main/java/jd/gui/spi/TreeNodeFactory.java | 3 +- .../jd/gui/controller/MainController.groovy | 7 + .../ContextualActionsFactoryService.groovy | 65 +++++ .../groovy/jd/gui/view/MainDescription.groovy | 2 +- .../main/groovy/jd/gui/view/MainView.groovy | 4 +- .../view/component/panel/TabbedPanel.groovy | 18 ++ .../component/panel/TreeTabbedPanel.groovy | 27 ++ ...alifiedNameContextualActionsFactory.groovy | 92 +++++++ ...ractTypeFileTreeNodeFactoryProvider.groovy | 251 +----------------- .../ClassFileTreeNodeFactoryProvider.groovy | 3 +- .../CssFileTreeNodeFactoryProvider.groovy | 3 +- .../DirectoryTreeNodeFactoryProvider.groovy | 8 +- .../DtdFileTreeNodeFactoryProvider.groovy | 3 +- .../EarFileTreeNodeFactoryProvider.groovy | 3 +- ...jbJarXmlFileTreeNodeFactoryProvider.groovy | 3 +- .../FileTreeNodeFactoryProvider.groovy | 8 +- .../HtmlFileTreeNodeFactoryProvider.groovy | 3 +- .../JarFileTreeNodeFactoryProvider.groovy | 3 +- .../JavaFileTreeNodeFactoryProvider.groovy | 3 +- ...vascriptFileTreeNodeFactoryProvider.groovy | 3 +- .../JsonFileTreeNodeFactoryProvider.groovy | 3 +- .../JspFileTreeNodeFactoryProvider.groovy | 3 +- ...ManifestFileTreeNodeFactoryProvider.groovy | 3 +- ...fServiceFileTreeNodeFactoryProvider.groovy | 3 +- .../PackageTreeNodeFactoryProvider.groovy | 3 +- ...opertiesFileTreeNodeFactoryProvider.groovy | 3 +- .../SqlFileTreeNodeFactoryProvider.groovy | 3 +- .../TextFileTreeNodeFactoryProvider.groovy | 3 +- .../WarFileTreeNodeFactoryProvider.groovy | 3 +- .../WebXmlFileTreeNodeFactoryProvider.groovy | 3 +- ...XmlBasedFileTreeNodeFactoryProvider.groovy | 3 +- .../XmlFileTreeNodeFactoryProvider.groovy | 3 +- .../ZipFileTreeNodeFactoryProvider.groovy | 3 +- .../type/AbstractTypeFactoryProvider.java | 196 +++++++++++++- .../type/ClassFileTypeFactoryProvider.java | 19 ++ .../type/JavaFileTypeFactoryProvider.java | 29 +- .../jd.gui.spi.ContextualActionsFactory | 1 + .../main/resources/images/cpyqual_menu.png | Bin 0 -> 526 bytes 41 files changed, 550 insertions(+), 278 deletions(-) create mode 100644 api/src/main/java/jd/gui/spi/ContextualActionsFactory.java create mode 100644 app/src/main/groovy/jd/gui/service/actions/ContextualActionsFactoryService.groovy create mode 100644 services/src/main/groovy/jd/gui/service/actions/CopyQualifiedNameContextualActionsFactory.groovy create mode 100644 services/src/main/resources/META-INF/services/jd.gui.spi.ContextualActionsFactory create mode 100644 services/src/main/resources/images/cpyqual_menu.png diff --git a/api/src/main/java/jd/gui/api/API.java b/api/src/main/java/jd/gui/api/API.java index 8648fc59..84072083 100644 --- a/api/src/main/java/jd/gui/api/API.java +++ b/api/src/main/java/jd/gui/api/API.java @@ -26,6 +26,8 @@ public interface API { public void addPanel(String title, Icon icon, String tip, T component); + public Collection getContextualActions(Container.Entry entry, String fragment); + public UriLoader getUriLoader(URI uri); public FileLoader getFileLoader(File file); diff --git a/api/src/main/java/jd/gui/api/model/Type.java b/api/src/main/java/jd/gui/api/model/Type.java index 4e275074..c8e3b9c4 100644 --- a/api/src/main/java/jd/gui/api/model/Type.java +++ b/api/src/main/java/jd/gui/api/model/Type.java @@ -49,6 +49,8 @@ public interface Field { public String getDescriptor(); + public String getDisplayName(); + public Icon getIcon(); } @@ -59,6 +61,8 @@ public interface Method { public String getDescriptor(); + public String getDisplayName(); + public Icon getIcon(); } } diff --git a/api/src/main/java/jd/gui/spi/ContextualActionsFactory.java b/api/src/main/java/jd/gui/spi/ContextualActionsFactory.java new file mode 100644 index 00000000..b113ec73 --- /dev/null +++ b/api/src/main/java/jd/gui/spi/ContextualActionsFactory.java @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2008-2015 Emmanuel Dupuy + * This program is made available under the terms of the GPLv3 License. + */ + +package jd.gui.spi; + +import jd.gui.api.API; +import jd.gui.api.model.Container; + +import javax.swing.*; +import java.util.Collection; + +public interface ContextualActionsFactory { + + public static final String GROUP_NAME = "GroupNameKey"; + + /** + * Build a collection of actions for 'entry' and 'fragment', grouped by GROUP_NAME and sorted by NAME. Null values + * are added for separators. + * + * @param fragment @see jd.gui.api.feature.UriOpenable + * @return a collection of actions + */ + public Collection make(API api, Container.Entry entry, String fragment); +} diff --git a/api/src/main/java/jd/gui/spi/TreeNodeFactory.java b/api/src/main/java/jd/gui/spi/TreeNodeFactory.java index 47b24f2f..69d74294 100644 --- a/api/src/main/java/jd/gui/spi/TreeNodeFactory.java +++ b/api/src/main/java/jd/gui/spi/TreeNodeFactory.java @@ -8,6 +8,7 @@ import javax.swing.tree.DefaultMutableTreeNode; import jd.gui.api.API; +import jd.gui.api.feature.ContainerEntryGettable; import jd.gui.api.feature.UriGettable; import jd.gui.api.model.Container; @@ -18,5 +19,5 @@ public interface TreeNodeFactory { public Pattern getPathPattern(); - public T make(API api, Container.Entry entry); + public T make(API api, Container.Entry entry); } diff --git a/app/src/main/groovy/jd/gui/controller/MainController.groovy b/app/src/main/groovy/jd/gui/controller/MainController.groovy index 48a2c898..d444c564 100644 --- a/app/src/main/groovy/jd/gui/controller/MainController.groovy +++ b/app/src/main/groovy/jd/gui/controller/MainController.groovy @@ -27,6 +27,7 @@ import jd.gui.service.fileloader.FileLoaderService import jd.gui.service.indexer.IndexerService import jd.gui.service.mainpanel.PanelFactoryService import jd.gui.service.pastehandler.PasteHandlerService +import jd.gui.service.actions.ContextualActionsFactoryService import jd.gui.service.preferencespanel.PreferencesPanelService import jd.gui.service.sourcesaver.SourceSaverService import jd.gui.service.treenode.TreeNodeFactoryService @@ -42,6 +43,7 @@ import jd.gui.spi.TypeFactory import jd.gui.spi.UriLoader import jd.gui.util.net.UriUtil +import javax.swing.Action import javax.swing.Icon import javax.swing.JComponent import javax.swing.JFileChooser @@ -92,6 +94,7 @@ class MainController implements API { mainView = new MainView( swing, configuration, + this, history, { panelClosed() }, // panelClosedClosure { page -> onCurrentPageChanged(page) }, // currentPageChangedClosure @@ -161,6 +164,7 @@ class MainController implements API { // Background controller creation selectLocationController = new SelectLocationController(swing, configuration, MainController.this) // Background service initialization + ContextualActionsFactoryService.instance ContainerFactoryService.instance FileLoaderService.instance IndexerService.instance @@ -515,6 +519,9 @@ class MainController implements API { checkIndexesChange(currentPage) } + @CompileStatic + Collection getContextualActions(Container.Entry entry, String fragment) { ContextualActionsFactoryService.instance.get(this, entry, fragment) } + @CompileStatic FileLoader getFileLoader(File file) { FileLoaderService.instance.get(this, file) } diff --git a/app/src/main/groovy/jd/gui/service/actions/ContextualActionsFactoryService.groovy b/app/src/main/groovy/jd/gui/service/actions/ContextualActionsFactoryService.groovy new file mode 100644 index 00000000..10699385 --- /dev/null +++ b/app/src/main/groovy/jd/gui/service/actions/ContextualActionsFactoryService.groovy @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2008-2015 Emmanuel Dupuy + * This program is made available under the terms of the GPLv3 License. + */ + +package jd.gui.service.actions + +import groovy.transform.CompileStatic +import jd.gui.api.API +import jd.gui.api.model.Container +import jd.gui.spi.ContextualActionsFactory + +import javax.swing.Action + +@Singleton(lazy = true) +class ContextualActionsFactoryService { + static final ActionNameComparator COMPARATOR = new ActionNameComparator() + + final List providers = ServiceLoader.load(ContextualActionsFactory).toList() + + @CompileStatic + Collection get(API api, Container.Entry entry, String fragment) { + Map> mapActions = [:].withDefault { [] } + + for (def provider : providers) { + def actions = provider.make(api, entry, fragment) + + for (def action : actions) { + mapActions.get(action.getValue(ContextualActionsFactory.GROUP_NAME)).add(action) + } + } + + if (mapActions) { + def result = new ArrayList() + + // Sort by group names + for (def groupName : mapActions.keySet().sort()) { + if (! result.isEmpty()) { + // Add 'null' to mark a separator + result.add(null) + } + + // Sort by names + def actions = mapActions.get(groupName) + Collections.sort(actions, COMPARATOR) + result.addAll(actions) + } + + return result + } else { + return Collections.emptyList() + } + } + + static class ActionNameComparator implements Comparator { + + int compare(Action a1, Action a2) { + String n1 = a1.getValue(Action.NAME) ?: '' + String n2 = a2.getValue(Action.NAME) ?: '' + return n1.compareTo(n2) + } + + boolean equals(Object other) { this == other } + } +} diff --git a/app/src/main/groovy/jd/gui/view/MainDescription.groovy b/app/src/main/groovy/jd/gui/view/MainDescription.groovy index 59bf152d..1179555c 100644 --- a/app/src/main/groovy/jd/gui/view/MainDescription.groovy +++ b/app/src/main/groovy/jd/gui/view/MainDescription.groovy @@ -217,7 +217,7 @@ frame( iconButton(action:backwardAction, text:null, icon:imageIcon(resource:'/images/backward_nav.png')) iconButton(action:forwardAction, text:null, icon:imageIcon(resource:'/images/forward_nav.png')) } - mainTabbedPanel(id:'mainTabbedPanel', constraints:CENTER) + mainTabbedPanel(id:'mainTabbedPanel', constraints:CENTER, api:api) hbox(id:'findPanel', constraints:PAGE_END, border:emptyBorder(2), visible:false) { label(text:'Find: ') comboBox(id:'findComboBox', editable: true) diff --git a/app/src/main/groovy/jd/gui/view/MainView.groovy b/app/src/main/groovy/jd/gui/view/MainView.groovy index e71ad7f2..68d5df78 100644 --- a/app/src/main/groovy/jd/gui/view/MainView.groovy +++ b/app/src/main/groovy/jd/gui/view/MainView.groovy @@ -7,6 +7,7 @@ package jd.gui.view import groovy.swing.SwingBuilder import jd.gui.Constants +import jd.gui.api.API import jd.gui.api.feature.ContentSearchable import jd.gui.api.feature.ContentSelectable import jd.gui.api.feature.LineNumberNavigable @@ -50,7 +51,7 @@ class MainView implements UriOpenable, PreferencesChangeListener { Color findErrorBackgroundColor MainView( - SwingBuilder swing, Configuration configuration, History history, + SwingBuilder swing, Configuration configuration, API api, History history, Closure panelClosedClosure, Closure currentPageChangedClosure, Closure openFilesClosure, @@ -63,6 +64,7 @@ class MainView implements UriOpenable, PreferencesChangeListener { // Setup registerBeanFactory('iconButton', IconButton.class) registerBeanFactory('mainTabbedPanel', MainTabbedPanel.class) + registerExplicitProperty('api', { api }, {}) // Used to init 'mainTabbedPanel.api' // Load GUI description build(MainDescription) // Add listeners diff --git a/app/src/main/groovy/jd/gui/view/component/panel/TabbedPanel.groovy b/app/src/main/groovy/jd/gui/view/component/panel/TabbedPanel.groovy index 6cfeb315..f7fe2564 100644 --- a/app/src/main/groovy/jd/gui/view/component/panel/TabbedPanel.groovy +++ b/app/src/main/groovy/jd/gui/view/component/panel/TabbedPanel.groovy @@ -5,6 +5,7 @@ package jd.gui.view.component.panel +import jd.gui.api.API import jd.gui.api.feature.PreferencesChangeListener import jd.gui.api.feature.UriGettable import jd.gui.service.platform.PlatformService @@ -37,6 +38,7 @@ class TabbedPanel extends JPanel implements PreferencesChangeListener { static final String TAB_LAYOUT = 'UITabsPreferencesProvider.singleLineTabs' + API api JTabbedPane tabbedPane Map preferences @@ -158,6 +160,7 @@ class TabbedPanel extends JPanel implements PreferencesChangeListener { class PopupTabMenu extends JPopupMenu { PopupTabMenu(Component component) { + // Add default popup menu entries def menuItem = new JMenuItem('Close', null) menuItem.addActionListener(new ActionListener() { void actionPerformed(ActionEvent e) { removeComponent(component) } @@ -175,6 +178,21 @@ class TabbedPanel extends JPanel implements PreferencesChangeListener { void actionPerformed(ActionEvent e) { removeAllComponents() } }) add(menuItem) + + // Add SPI popup menu entries + def actions = api.getContextualActions(component.entry, null) + + if (actions) { + addSeparator() + + for (def action : actions) { + if (action) { + add(action) + } else { + addSeparator() + } + } + } } } diff --git a/app/src/main/groovy/jd/gui/view/component/panel/TreeTabbedPanel.groovy b/app/src/main/groovy/jd/gui/view/component/panel/TreeTabbedPanel.groovy index d2d18935..c52e1fb4 100644 --- a/app/src/main/groovy/jd/gui/view/component/panel/TreeTabbedPanel.groovy +++ b/app/src/main/groovy/jd/gui/view/component/panel/TreeTabbedPanel.groovy @@ -27,6 +27,8 @@ import javax.swing.event.TreeSelectionEvent import javax.swing.event.TreeSelectionListener import javax.swing.tree.DefaultMutableTreeNode import java.awt.* +import java.awt.event.MouseAdapter +import java.awt.event.MouseEvent import java.util.List class TreeTabbedPanel extends JPanel implements UriGettable, UriOpenable, PageChangeable, PageClosable, PreferencesChangeListener { @@ -72,8 +74,33 @@ class TreeTabbedPanel extends JPanel implements UriGettable, UriOpenable, PageCh } void treeCollapsed(TreeExpansionEvent e) {} }) + tree.addMouseListener(new MouseAdapter() { + void mouseClicked(MouseEvent e) { + if (SwingUtilities.isRightMouseButton(e)) { + def path = tree.getClosestPathForLocation(e.x, e.y) + + if (path) { + def node = path.lastPathComponent + def actions = api.getContextualActions(node.entry, node.uri.fragment) + + if (actions) { + def popup = new JPopupMenu() + for (def action : actions) { + if (action) { + popup.add(action) + } else { + popup.addSeparator() + } + } + popup.show(e.component, e.x, e.y) + } + } + } + } + }) tabbedPanel = new TabbedPanel() + tabbedPanel.api = api tabbedPanel.setMinimumSize([150, 10] as Dimension) tabbedPanel.tabbedPane.addChangeListener(new ChangeListener() { void stateChanged(ChangeEvent e) { pageChanged() } diff --git a/services/src/main/groovy/jd/gui/service/actions/CopyQualifiedNameContextualActionsFactory.groovy b/services/src/main/groovy/jd/gui/service/actions/CopyQualifiedNameContextualActionsFactory.groovy new file mode 100644 index 00000000..f8e50f83 --- /dev/null +++ b/services/src/main/groovy/jd/gui/service/actions/CopyQualifiedNameContextualActionsFactory.groovy @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2008-2015 Emmanuel Dupuy + * This program is made available under the terms of the GPLv3 License. + */ + +package jd.gui.service.actions + +import com.sun.media.sound.InvalidFormatException +import jd.gui.api.API +import jd.gui.api.model.Container +import jd.gui.spi.ContextualActionsFactory + +import javax.swing.AbstractAction +import javax.swing.Action +import javax.swing.ImageIcon +import java.awt.Toolkit +import java.awt.datatransfer.StringSelection +import java.awt.event.ActionEvent + +class CopyQualifiedNameContextualActionsFactory implements ContextualActionsFactory { + + Collection make(API api, Container.Entry entry, String fragment) { + return Collections.singletonList(new CopyQualifiedNameAction(api, entry, fragment)) + } + + static class CopyQualifiedNameAction extends AbstractAction { + static final ImageIcon ICON = new ImageIcon(CopyQualifiedNameAction.class.classLoader.getResource('images/cpyqual_menu.png')) + + protected API api + protected Container.Entry entry + protected String fragment + + CopyQualifiedNameAction(API api, Container.Entry entry, String fragment) { + this.api = api + this.entry = entry + this.fragment = fragment + + putValue(GROUP_NAME, 'Edit > CutCopyPaste') + putValue(NAME, 'Copy Qualified Name') + putValue(SMALL_ICON, ICON) + } + + void actionPerformed(ActionEvent e) { + def type = api.getTypeFactory(entry)?.make(api, entry, fragment) + + if (type) { + def sb = new StringBuffer(type.displayPackageName) + int dashIndex = fragment.indexOf('-') + + if (sb.length() > 0) { + sb.append('.') + } + + sb.append(type.displayTypeName) + + if (dashIndex != -1) { + int lastDashIndex = fragment.lastIndexOf('-') + + if (dashIndex == lastDashIndex) { + // See jd.gui.api.feature.UriOpenable + throw new InvalidFormatException('fragment: ' + fragment) + } else { + def name = fragment.substring(dashIndex+1, lastDashIndex) + def descriptor = fragment.substring(lastDashIndex+1) + + if (descriptor.startsWith('(')) { + for (def method : type.methods) { + if (method.name.equals(name) && method.descriptor.equals(descriptor)) { + sb.append('.').append(method.displayName) + break + } + } + } else { + for (def field : type.fields) { + if (field.name.equals(name) && field.descriptor.equals(descriptor)) { + sb.append('.').append(field.displayName) + break + } + } + } + } + } + + Toolkit.defaultToolkit.systemClipboard.setContents(new StringSelection(sb.toString()), null) + } else { + // Copy path of entry + def path = new File(entry.uri).absolutePath + Toolkit.defaultToolkit.systemClipboard.setContents(new StringSelection(path), null) + } + } + } +} diff --git a/services/src/main/groovy/jd/gui/service/treenode/AbstractTypeFileTreeNodeFactoryProvider.groovy b/services/src/main/groovy/jd/gui/service/treenode/AbstractTypeFileTreeNodeFactoryProvider.groovy index c7ddab70..fea6f8ab 100644 --- a/services/src/main/groovy/jd/gui/service/treenode/AbstractTypeFileTreeNodeFactoryProvider.groovy +++ b/services/src/main/groovy/jd/gui/service/treenode/AbstractTypeFileTreeNodeFactoryProvider.groovy @@ -6,6 +6,7 @@ package jd.gui.service.treenode import jd.gui.api.API +import jd.gui.api.feature.ContainerEntryGettable import jd.gui.api.feature.PageCreator import jd.gui.api.feature.TreeNodeExpandable import jd.gui.api.feature.UriGettable @@ -18,7 +19,7 @@ import javax.swing.tree.DefaultMutableTreeNode abstract class AbstractTypeFileTreeNodeFactoryProvider extends AbstractTreeNodeFactoryProvider { - static class BaseTreeNode extends DefaultMutableTreeNode implements UriGettable, PageCreator { + static class BaseTreeNode extends DefaultMutableTreeNode implements ContainerEntryGettable, UriGettable, PageCreator { Container.Entry entry PageAndTipFactory factory; URI uri @@ -36,6 +37,9 @@ abstract class AbstractTypeFileTreeNodeFactoryProvider extends AbstractTreeNodeF } } + // --- ContainerEntryGettable --- // + Container.Entry getEntry() { entry } + // --- UriGettable --- // URI getUri() { uri } @@ -94,11 +98,7 @@ abstract class AbstractTypeFileTreeNodeFactoryProvider extends AbstractTreeNodeF if (!initialized) { removeAllChildren() - def sb = new StringBuffer() - def typeAccess = type.flags def typeName = type.name - def constructorName = type.displayInnerTypeName ?: type.displayTypeName - def isInnerClass = (type.displayInnerTypeName != null) // Create inner types type.innerTypes.sort { t1, t2 -> @@ -109,12 +109,8 @@ abstract class AbstractTypeFileTreeNodeFactoryProvider extends AbstractTreeNodeF // Create fields type.fields.collect { - sb.setLength(0) - sb.append(it.name).append(' : ') - writeSignature(sb, it.descriptor, it.descriptor.length(), 0, false) - def label = sb.toString() def fragment = typeName + '-' + it.name + '-' + it.descriptor - return new FieldOrMethodBean(fragment:fragment, label:label, icon:it.icon) + return new FieldOrMethodBean(fragment:fragment, label:it.displayName, icon:it.icon) }.sort { f1, f2 -> f1.label.compareTo(f2.label) }.each { @@ -123,11 +119,8 @@ abstract class AbstractTypeFileTreeNodeFactoryProvider extends AbstractTreeNodeF // Create methods type.methods.collect { - sb.setLength(0) - writeMethodSignature(sb, typeAccess, it.flags, isInnerClass, constructorName, it.name, it.descriptor) - def label = sb.toString() def fragment = typeName + '-' + it.name + '-' + it.descriptor - return new FieldOrMethodBean(fragment:fragment, label:label, icon:it.icon) + return new FieldOrMethodBean(fragment:fragment, label:it.displayName, icon:it.icon) }.sort { m1, m2 -> m1.label.compareTo(m2.label) }.each { @@ -137,236 +130,6 @@ abstract class AbstractTypeFileTreeNodeFactoryProvider extends AbstractTreeNodeF initialized = true } } - - int writeSignature(StringBuffer sb, String descriptor, int length, int index, boolean varargsFlag) { - while (true) { - // Print array : '[[?' ou '[L[?;' - int dimensionLength = 0 - - if (descriptor.charAt(index) == '[') { - dimensionLength++; - - while (++index < length) { - if ((descriptor.charAt(index) == 'L') && (index+1 < length) && (descriptor.charAt(index+1) == '[')) { - index++ - length-- - dimensionLength++; - } else if (descriptor.charAt(index) == '[') { - dimensionLength++ - } else { - break - } - } - } - - switch(descriptor.charAt(index)) { - case 'B': - sb.append('byte') - index++ - break - case 'C': - sb.append('char') - index++ - break - case 'D': - sb.append('double') - index++ - break - case 'F': - sb.append('float') - index++ - break - case 'I': - sb.append('int') - index++ - break - case 'J': - sb.append('long') - index++ - break - case 'L': case '.': - int beginIndex = ++index - char c = '.' - - // Search ; or de < - while (index < length) { - c = descriptor.charAt(index) - if ((c == ';') || (c == '<')) - break - index++ - } - - String internalClassName = descriptor.substring(beginIndex, index) - int lastPackageSeparatorIndex = internalClassName.lastIndexOf('/') - - if (lastPackageSeparatorIndex >= 0) { - // Cut package name - internalClassName = internalClassName.substring(lastPackageSeparatorIndex + 1) - } - - sb.append(internalClassName.replace('$', '.')) - - if (c == '<') { - sb.append('<') - index = writeSignature(sb, descriptor, length, index+1, false) - - while (descriptor.charAt(index) != '>') { - sb.append(', ') - index = writeSignature(sb, descriptor, length, index, false) - } - sb.append('>') - - // pass '>' - index++ - } - - // pass ';' - if (descriptor.charAt(index) == ';') - index++ - break - case 'S': - sb.append('short') - index++ - break - case 'T': - int beginIndex = ++index - index = descriptor.substring(beginIndex, length).indexOf(';') - sb.append(descriptor.substring(beginIndex, index)) - index++ - break; - case 'V': - sb.append('void') - index++ - break - case 'Z': - sb.append('boolean') - index++ - break - case '-': - sb.append('? ').append('super').append(' ') - index = writeSignature(sb, descriptor, length, index+1, false) - break; - case '+': - sb.append('? ').append('extends').append(' ') - index = writeSignature(sb, descriptor, length, index+1, false) - break; - case '*': - sb.append('?') - index++ - break - case 'X': case 'Y': - sb.append('int') - index++ - break - default: - throw new RuntimeException('SignatureWriter.WriteSignature: invalid signature "' + descriptor + '"') - } - - if (varargsFlag) - { - if (dimensionLength > 0) - { - while (--dimensionLength > 0) - sb.append('[]') - sb.append('...') - } - } - else - { - while (dimensionLength-- > 0) - sb.append('[]') - } - - - if ((index >= length) || (descriptor.charAt(index) != '.')) - break - - sb.append('.') - } - - return index - } - - void writeMethodSignature( - StringBuffer sb, int typeAccess, int methodAccess, boolean isInnerClass, - String constructorName, String methodName, String descriptor) { - if (methodName.equals('')) { - sb.append('{...}') - } else { - boolean isAConstructor = methodName.equals('') - - if (isAConstructor) { - sb.append(constructorName) - } else { - sb.append(methodName) - } - - // Skip generics - int length = descriptor.length() - int index = 0 - - while ((index < length) && (descriptor.charAt(index) != '(')) - index++ - - if (descriptor.charAt(index) != '(') { - throw RuntimeException('Signature format exception: "' + descriptor + '"'); - } - - sb.append('(') - - // pass '(' - index++ - - if (descriptor.charAt(index) != ')') { - if (isAConstructor && isInnerClass && ((typeAccess & Type.FLAG_STATIC) == 0)) { - // Skip first parameter - int lengthBackup = sb.length() - index = writeSignature(sb, descriptor, length, index, false) - sb.setLength(lengthBackup) - } - - if (descriptor.charAt(index) != ')') { - int varargsParameterIndex - - if ((methodAccess & Type.FLAG_VARARGS) == 0) { - varargsParameterIndex = Integer.MAX_VALUE - } else { - // Count parameters - int indexBackup = index - int lengthBackup = sb.length() - - varargsParameterIndex = -1 - - while (descriptor.charAt(index) != ')') { - index = writeSignature(sb, descriptor, length, index, false) - varargsParameterIndex++ - } - - index = indexBackup - sb.setLength(lengthBackup) - } - - // Write parameters - index = writeSignature(sb, descriptor, length, index, false) - - int parameterIndex = 1 - - while (descriptor.charAt(index) != ')') { - sb.append(', ') - index = writeSignature(sb, descriptor, length, index, (parameterIndex == varargsParameterIndex)) - parameterIndex++ - } - } - } - - if (isAConstructor) { - sb.append(')') - } else { - sb.append(') : ') - writeSignature(sb, descriptor, length, ++index, false) - } - } - } } static class FieldOrMethodTreeNode extends BaseTreeNode { diff --git a/services/src/main/groovy/jd/gui/service/treenode/ClassFileTreeNodeFactoryProvider.groovy b/services/src/main/groovy/jd/gui/service/treenode/ClassFileTreeNodeFactoryProvider.groovy index 195a79da..8a111a90 100644 --- a/services/src/main/groovy/jd/gui/service/treenode/ClassFileTreeNodeFactoryProvider.groovy +++ b/services/src/main/groovy/jd/gui/service/treenode/ClassFileTreeNodeFactoryProvider.groovy @@ -7,6 +7,7 @@ package jd.gui.service.treenode import groovy.transform.CompileStatic import jd.gui.api.API +import jd.gui.api.feature.ContainerEntryGettable import jd.gui.api.feature.UriGettable import jd.gui.api.model.Container import jd.gui.view.component.ClassFilePage @@ -32,7 +33,7 @@ class ClassFileTreeNodeFactoryProvider extends AbstractTypeFileTreeNodeFactoryPr */ String[] getSelectors() { ['*:file:*.class'] + externalSelectors } - public T make(API api, Container.Entry entry) { + public T make(API api, Container.Entry entry) { int lastSlashIndex = entry.path.lastIndexOf('/') def name = entry.path.substring(lastSlashIndex+1) diff --git a/services/src/main/groovy/jd/gui/service/treenode/CssFileTreeNodeFactoryProvider.groovy b/services/src/main/groovy/jd/gui/service/treenode/CssFileTreeNodeFactoryProvider.groovy index bf3effcd..6659d1c4 100644 --- a/services/src/main/groovy/jd/gui/service/treenode/CssFileTreeNodeFactoryProvider.groovy +++ b/services/src/main/groovy/jd/gui/service/treenode/CssFileTreeNodeFactoryProvider.groovy @@ -6,6 +6,7 @@ package jd.gui.service.treenode import jd.gui.api.API +import jd.gui.api.feature.ContainerEntryGettable import jd.gui.api.feature.UriGettable import jd.gui.api.model.Container import jd.gui.view.data.TreeNodeBean @@ -23,7 +24,7 @@ class CssFileTreeNodeFactoryProvider extends TextFileTreeNodeFactoryProvider { */ String[] getSelectors() { ['*:file:*.css'] + externalSelectors } - public T make(API api, Container.Entry entry) { + public T make(API api, Container.Entry entry) { int lastSlashIndex = entry.path.lastIndexOf('/') def name = entry.path.substring(lastSlashIndex+1) return new TreeNode(entry, new TreeNodeBean(label:name, icon:ICON, tip:"Location: $entry.uri.path")) diff --git a/services/src/main/groovy/jd/gui/service/treenode/DirectoryTreeNodeFactoryProvider.groovy b/services/src/main/groovy/jd/gui/service/treenode/DirectoryTreeNodeFactoryProvider.groovy index 632ad5d3..4d6b708b 100644 --- a/services/src/main/groovy/jd/gui/service/treenode/DirectoryTreeNodeFactoryProvider.groovy +++ b/services/src/main/groovy/jd/gui/service/treenode/DirectoryTreeNodeFactoryProvider.groovy @@ -6,6 +6,7 @@ package jd.gui.service.treenode import jd.gui.api.API +import jd.gui.api.feature.ContainerEntryGettable import jd.gui.api.feature.TreeNodeExpandable import jd.gui.api.feature.UriGettable import jd.gui.api.model.Container @@ -25,7 +26,7 @@ class DirectoryTreeNodeFactoryProvider extends AbstractTreeNodeFactoryProvider { */ String[] getSelectors() { ['*:dir:*'] + externalSelectors } - public T make(API api, Container.Entry entry) { + public T make(API api, Container.Entry entry) { int lastSlashIndex = entry.path.lastIndexOf('/') Collection entries = entry.children @@ -51,7 +52,7 @@ class DirectoryTreeNodeFactoryProvider extends AbstractTreeNodeFactoryProvider { ImageIcon getIcon() { ICON } ImageIcon getOpenIcon() { OPEN_ICON } - static class TreeNode extends DefaultMutableTreeNode implements UriGettable, TreeNodeExpandable { + static class TreeNode extends DefaultMutableTreeNode implements ContainerEntryGettable, UriGettable, TreeNodeExpandable { Container.Entry entry boolean initialized @@ -61,6 +62,9 @@ class DirectoryTreeNodeFactoryProvider extends AbstractTreeNodeFactoryProvider { this.initialized = false } + // --- ContainerEntryGettable --- // + Container.Entry getEntry() { entry } + // --- UriGettable --- // URI getUri() { entry.uri } diff --git a/services/src/main/groovy/jd/gui/service/treenode/DtdFileTreeNodeFactoryProvider.groovy b/services/src/main/groovy/jd/gui/service/treenode/DtdFileTreeNodeFactoryProvider.groovy index a498d662..0209c609 100644 --- a/services/src/main/groovy/jd/gui/service/treenode/DtdFileTreeNodeFactoryProvider.groovy +++ b/services/src/main/groovy/jd/gui/service/treenode/DtdFileTreeNodeFactoryProvider.groovy @@ -6,6 +6,7 @@ package jd.gui.service.treenode import jd.gui.api.API +import jd.gui.api.feature.ContainerEntryGettable import jd.gui.api.feature.UriGettable import jd.gui.api.model.Container import jd.gui.view.data.TreeNodeBean @@ -22,7 +23,7 @@ class DtdFileTreeNodeFactoryProvider extends TextFileTreeNodeFactoryProvider { */ String[] getSelectors() { ['*:file:*.dtd'] + externalSelectors } - public T make(API api, Container.Entry entry) { + public T make(API api, Container.Entry entry) { int lastSlashIndex = entry.path.lastIndexOf('/') def name = entry.path.substring(lastSlashIndex+1) return new TreeNode(entry, new TreeNodeBean(label:name, icon:ICON, tip:"Location: $entry.uri.path")) diff --git a/services/src/main/groovy/jd/gui/service/treenode/EarFileTreeNodeFactoryProvider.groovy b/services/src/main/groovy/jd/gui/service/treenode/EarFileTreeNodeFactoryProvider.groovy index 87de3d76..ae4ad28c 100644 --- a/services/src/main/groovy/jd/gui/service/treenode/EarFileTreeNodeFactoryProvider.groovy +++ b/services/src/main/groovy/jd/gui/service/treenode/EarFileTreeNodeFactoryProvider.groovy @@ -6,6 +6,7 @@ package jd.gui.service.treenode import jd.gui.api.API +import jd.gui.api.feature.ContainerEntryGettable import jd.gui.api.feature.UriGettable import jd.gui.api.model.Container import jd.gui.view.data.TreeNodeBean @@ -21,7 +22,7 @@ class EarFileTreeNodeFactoryProvider extends ZipFileTreeNodeFactoryProvider { */ String[] getSelectors() { ['*:file:*.ear'] + externalSelectors } - public T make(API api, Container.Entry entry) { + public T make(API api, Container.Entry entry) { int lastSlashIndex = entry.path.lastIndexOf('/') def name = entry.path.substring(lastSlashIndex+1) def node = new TreeNode(entry, 'ear', new TreeNodeBean(label:name, icon:ICON)) diff --git a/services/src/main/groovy/jd/gui/service/treenode/EjbJarXmlFileTreeNodeFactoryProvider.groovy b/services/src/main/groovy/jd/gui/service/treenode/EjbJarXmlFileTreeNodeFactoryProvider.groovy index 196654af..a3366efb 100644 --- a/services/src/main/groovy/jd/gui/service/treenode/EjbJarXmlFileTreeNodeFactoryProvider.groovy +++ b/services/src/main/groovy/jd/gui/service/treenode/EjbJarXmlFileTreeNodeFactoryProvider.groovy @@ -6,6 +6,7 @@ package jd.gui.service.treenode import jd.gui.api.API +import jd.gui.api.feature.ContainerEntryGettable import jd.gui.api.feature.PageCreator import jd.gui.api.feature.UriGettable import jd.gui.api.model.Container @@ -23,7 +24,7 @@ class EjbJarXmlFileTreeNodeFactoryProvider extends FileTreeNodeFactoryProvider { */ String[] getSelectors() { ['jar:file:META-INF/ejb-jar.xml'] + externalSelectors } - public T make(API api, Container.Entry entry) { + public T make(API api, Container.Entry entry) { return new TreeNode(entry, new TreeNodeBean(label:'ejb-jar.xml', icon:ICON, tip:"Location: $entry.uri.path")) } diff --git a/services/src/main/groovy/jd/gui/service/treenode/FileTreeNodeFactoryProvider.groovy b/services/src/main/groovy/jd/gui/service/treenode/FileTreeNodeFactoryProvider.groovy index 20d33552..f1ff998e 100644 --- a/services/src/main/groovy/jd/gui/service/treenode/FileTreeNodeFactoryProvider.groovy +++ b/services/src/main/groovy/jd/gui/service/treenode/FileTreeNodeFactoryProvider.groovy @@ -6,6 +6,7 @@ package jd.gui.service.treenode import jd.gui.api.API +import jd.gui.api.feature.ContainerEntryGettable import jd.gui.api.feature.UriGettable import jd.gui.api.model.Container import jd.gui.view.data.TreeNodeBean @@ -21,13 +22,13 @@ class FileTreeNodeFactoryProvider extends AbstractTreeNodeFactoryProvider { */ String[] getSelectors() { ['*:file:*'] + externalSelectors } - public T make(API api, Container.Entry entry) { + public T make(API api, Container.Entry entry) { int lastSlashIndex = entry.path.lastIndexOf('/') def name = entry.path.substring(lastSlashIndex+1) return new TreeNode(entry, new TreeNodeBean(label:name, icon:ICON)) } - static class TreeNode extends DefaultMutableTreeNode implements UriGettable { + static class TreeNode extends DefaultMutableTreeNode implements ContainerEntryGettable, UriGettable { Container.Entry entry TreeNode(Container.Entry entry, Object userObject) { @@ -35,6 +36,9 @@ class FileTreeNodeFactoryProvider extends AbstractTreeNodeFactoryProvider { this.entry = entry } + // --- ContainerEntryGettable --- // + Container.Entry getEntry() { entry } + // --- UriGettable --- // URI getUri() { entry.uri } } diff --git a/services/src/main/groovy/jd/gui/service/treenode/HtmlFileTreeNodeFactoryProvider.groovy b/services/src/main/groovy/jd/gui/service/treenode/HtmlFileTreeNodeFactoryProvider.groovy index a47b2cf5..213bfb78 100644 --- a/services/src/main/groovy/jd/gui/service/treenode/HtmlFileTreeNodeFactoryProvider.groovy +++ b/services/src/main/groovy/jd/gui/service/treenode/HtmlFileTreeNodeFactoryProvider.groovy @@ -6,6 +6,7 @@ package jd.gui.service.treenode import jd.gui.api.API +import jd.gui.api.feature.ContainerEntryGettable import jd.gui.api.feature.UriGettable import jd.gui.api.model.Container import jd.gui.view.data.TreeNodeBean @@ -22,7 +23,7 @@ class HtmlFileTreeNodeFactoryProvider extends TextFileTreeNodeFactoryProvider { */ String[] getSelectors() { ['*:file:*.html', '*:file:*.xhtml'] + externalSelectors } - public T make(API api, Container.Entry entry) { + public T make(API api, Container.Entry entry) { int lastSlashIndex = entry.path.lastIndexOf('/') def name = entry.path.substring(lastSlashIndex+1) return new TreeNode(entry, new TreeNodeBean(label:name, icon:ICON, tip:"Location: $entry.uri.path")) diff --git a/services/src/main/groovy/jd/gui/service/treenode/JarFileTreeNodeFactoryProvider.groovy b/services/src/main/groovy/jd/gui/service/treenode/JarFileTreeNodeFactoryProvider.groovy index 42c10bb0..9f33480a 100644 --- a/services/src/main/groovy/jd/gui/service/treenode/JarFileTreeNodeFactoryProvider.groovy +++ b/services/src/main/groovy/jd/gui/service/treenode/JarFileTreeNodeFactoryProvider.groovy @@ -6,6 +6,7 @@ package jd.gui.service.treenode import jd.gui.api.API +import jd.gui.api.feature.ContainerEntryGettable import jd.gui.api.feature.UriGettable import jd.gui.api.model.Container import jd.gui.util.JarContainerEntryUtil @@ -23,7 +24,7 @@ class JarFileTreeNodeFactoryProvider extends ZipFileTreeNodeFactoryProvider { */ String[] getSelectors() { ['*:file:*.jar'] + externalSelectors } - public T make(API api, Container.Entry entry) { + public T make(API api, Container.Entry entry) { int lastSlashIndex = entry.path.lastIndexOf('/') def name = entry.path.substring(lastSlashIndex+1) def icon = isAEjbModule(entry) ? EJB_FILE_ICON : JAR_FILE_ICON diff --git a/services/src/main/groovy/jd/gui/service/treenode/JavaFileTreeNodeFactoryProvider.groovy b/services/src/main/groovy/jd/gui/service/treenode/JavaFileTreeNodeFactoryProvider.groovy index 836533ed..dc5fbc56 100644 --- a/services/src/main/groovy/jd/gui/service/treenode/JavaFileTreeNodeFactoryProvider.groovy +++ b/services/src/main/groovy/jd/gui/service/treenode/JavaFileTreeNodeFactoryProvider.groovy @@ -6,6 +6,7 @@ package jd.gui.service.treenode import jd.gui.api.API +import jd.gui.api.feature.ContainerEntryGettable import jd.gui.api.feature.UriGettable import jd.gui.api.model.Container import jd.gui.view.component.JavaFilePage @@ -24,7 +25,7 @@ class JavaFileTreeNodeFactoryProvider extends AbstractTypeFileTreeNodeFactoryPro */ String[] getSelectors() { ['*:file:*.java'] + externalSelectors } - public T make(API api, Container.Entry entry) { + public T make(API api, Container.Entry entry) { int lastSlashIndex = entry.path.lastIndexOf('/') def name = entry.path.substring(lastSlashIndex+1) diff --git a/services/src/main/groovy/jd/gui/service/treenode/JavascriptFileTreeNodeFactoryProvider.groovy b/services/src/main/groovy/jd/gui/service/treenode/JavascriptFileTreeNodeFactoryProvider.groovy index b011495c..122e3e08 100644 --- a/services/src/main/groovy/jd/gui/service/treenode/JavascriptFileTreeNodeFactoryProvider.groovy +++ b/services/src/main/groovy/jd/gui/service/treenode/JavascriptFileTreeNodeFactoryProvider.groovy @@ -6,6 +6,7 @@ package jd.gui.service.treenode import jd.gui.api.API +import jd.gui.api.feature.ContainerEntryGettable import jd.gui.api.feature.UriGettable import jd.gui.api.model.Container import jd.gui.view.data.TreeNodeBean @@ -22,7 +23,7 @@ class JavascriptFileTreeNodeFactoryProvider extends TextFileTreeNodeFactoryProvi */ String[] getSelectors() { ['*:file:*.js'] + externalSelectors } - public T make(API api, Container.Entry entry) { + public T make(API api, Container.Entry entry) { int lastSlashIndex = entry.path.lastIndexOf('/') def name = entry.path.substring(lastSlashIndex+1) return new TreeNode(entry, new TreeNodeBean(label:name, icon:ICON, tip:"Location: $entry.uri.path")) diff --git a/services/src/main/groovy/jd/gui/service/treenode/JsonFileTreeNodeFactoryProvider.groovy b/services/src/main/groovy/jd/gui/service/treenode/JsonFileTreeNodeFactoryProvider.groovy index e5f431a8..8bdbb4bc 100644 --- a/services/src/main/groovy/jd/gui/service/treenode/JsonFileTreeNodeFactoryProvider.groovy +++ b/services/src/main/groovy/jd/gui/service/treenode/JsonFileTreeNodeFactoryProvider.groovy @@ -6,6 +6,7 @@ package jd.gui.service.treenode import jd.gui.api.API +import jd.gui.api.feature.ContainerEntryGettable import jd.gui.api.feature.UriGettable import jd.gui.api.model.Container import jd.gui.view.data.TreeNodeBean @@ -22,7 +23,7 @@ class JsonFileTreeNodeFactoryProvider extends TextFileTreeNodeFactoryProvider { */ String[] getSelectors() { ['*:file:*.json'] + externalSelectors } - public T make(API api, Container.Entry entry) { + public T make(API api, Container.Entry entry) { int lastSlashIndex = entry.path.lastIndexOf('/') def name = entry.path.substring(lastSlashIndex+1) return new TreeNode(entry, new TreeNodeBean(label:name, icon:ICON, tip:"Location: $entry.uri.path")) diff --git a/services/src/main/groovy/jd/gui/service/treenode/JspFileTreeNodeFactoryProvider.groovy b/services/src/main/groovy/jd/gui/service/treenode/JspFileTreeNodeFactoryProvider.groovy index 41e85e61..2eb5b707 100644 --- a/services/src/main/groovy/jd/gui/service/treenode/JspFileTreeNodeFactoryProvider.groovy +++ b/services/src/main/groovy/jd/gui/service/treenode/JspFileTreeNodeFactoryProvider.groovy @@ -6,6 +6,7 @@ package jd.gui.service.treenode import jd.gui.api.API +import jd.gui.api.feature.ContainerEntryGettable import jd.gui.api.feature.UriGettable import jd.gui.api.model.Container import jd.gui.view.data.TreeNodeBean @@ -23,7 +24,7 @@ class JspFileTreeNodeFactoryProvider extends TextFileTreeNodeFactoryProvider { */ String[] getSelectors() { ['*:file:*.jsp', '*:file:*.jspf'] + externalSelectors } - public T make(API api, Container.Entry entry) { + public T make(API api, Container.Entry entry) { int lastSlashIndex = entry.path.lastIndexOf('/') def name = entry.path.substring(lastSlashIndex+1) return new TreeNode(entry, new TreeNodeBean(label:name, icon:ICON, tip:"Location: $entry.uri.path")) diff --git a/services/src/main/groovy/jd/gui/service/treenode/ManifestFileTreeNodeFactoryProvider.groovy b/services/src/main/groovy/jd/gui/service/treenode/ManifestFileTreeNodeFactoryProvider.groovy index b3fecb9b..e38b9318 100644 --- a/services/src/main/groovy/jd/gui/service/treenode/ManifestFileTreeNodeFactoryProvider.groovy +++ b/services/src/main/groovy/jd/gui/service/treenode/ManifestFileTreeNodeFactoryProvider.groovy @@ -6,6 +6,7 @@ package jd.gui.service.treenode import jd.gui.api.API +import jd.gui.api.feature.ContainerEntryGettable import jd.gui.api.feature.PageCreator import jd.gui.api.feature.UriGettable import jd.gui.api.model.Container @@ -23,7 +24,7 @@ class ManifestFileTreeNodeFactoryProvider extends FileTreeNodeFactoryProvider { */ String[] getSelectors() { ['*:file:META-INF/MANIFEST.MF'] + externalSelectors } - public T make(API api, Container.Entry entry) { + public T make(API api, Container.Entry entry) { return new TreeNode(entry, new TreeNodeBean(label:'MANIFEST.MF', icon:ICON, tip:"Location: $entry.uri.path")) } diff --git a/services/src/main/groovy/jd/gui/service/treenode/MetainfServiceFileTreeNodeFactoryProvider.groovy b/services/src/main/groovy/jd/gui/service/treenode/MetainfServiceFileTreeNodeFactoryProvider.groovy index 2cd479a8..9eaad24e 100644 --- a/services/src/main/groovy/jd/gui/service/treenode/MetainfServiceFileTreeNodeFactoryProvider.groovy +++ b/services/src/main/groovy/jd/gui/service/treenode/MetainfServiceFileTreeNodeFactoryProvider.groovy @@ -6,6 +6,7 @@ package jd.gui.service.treenode import jd.gui.api.API +import jd.gui.api.feature.ContainerEntryGettable import jd.gui.api.feature.PageCreator import jd.gui.api.feature.UriGettable import jd.gui.api.model.Container @@ -30,7 +31,7 @@ class MetainfServiceFileTreeNodeFactoryProvider extends FileTreeNodeFactoryProvi */ Pattern getPathPattern() { externalPathPattern ?: ~/META-INF\/services\/[^\/]+/ } - public T make(API api, Container.Entry entry) { + public T make(API api, Container.Entry entry) { int lastSlashIndex = entry.path.lastIndexOf('/') def name = entry.path.substring(lastSlashIndex+1) return new TreeNode(entry, new TreeNodeBean(label:name, icon:ICON, tip:"Location: $entry.uri.path")) diff --git a/services/src/main/groovy/jd/gui/service/treenode/PackageTreeNodeFactoryProvider.groovy b/services/src/main/groovy/jd/gui/service/treenode/PackageTreeNodeFactoryProvider.groovy index 27e9f646..e0092657 100644 --- a/services/src/main/groovy/jd/gui/service/treenode/PackageTreeNodeFactoryProvider.groovy +++ b/services/src/main/groovy/jd/gui/service/treenode/PackageTreeNodeFactoryProvider.groovy @@ -6,6 +6,7 @@ package jd.gui.service.treenode import jd.gui.api.API +import jd.gui.api.feature.ContainerEntryGettable import jd.gui.api.feature.UriGettable import jd.gui.api.model.Container import jd.gui.util.JarContainerEntryUtil @@ -22,7 +23,7 @@ class PackageTreeNodeFactoryProvider extends DirectoryTreeNodeFactoryProvider { */ String[] getSelectors() { ['jar:dir:*'] + externalSelectors } - public T make(API api, Container.Entry entry) { + public T make(API api, Container.Entry entry) { int lastSlashIndex = entry.path.lastIndexOf('/') Collection entries = entry.children diff --git a/services/src/main/groovy/jd/gui/service/treenode/PropertiesFileTreeNodeFactoryProvider.groovy b/services/src/main/groovy/jd/gui/service/treenode/PropertiesFileTreeNodeFactoryProvider.groovy index 2b843e5f..cad255a6 100644 --- a/services/src/main/groovy/jd/gui/service/treenode/PropertiesFileTreeNodeFactoryProvider.groovy +++ b/services/src/main/groovy/jd/gui/service/treenode/PropertiesFileTreeNodeFactoryProvider.groovy @@ -6,6 +6,7 @@ package jd.gui.service.treenode import jd.gui.api.API +import jd.gui.api.feature.ContainerEntryGettable import jd.gui.api.feature.UriGettable import jd.gui.api.model.Container import jd.gui.view.data.TreeNodeBean @@ -22,7 +23,7 @@ class PropertiesFileTreeNodeFactoryProvider extends TextFileTreeNodeFactoryProvi */ String[] getSelectors() { ['*:file:*.properties'] + externalSelectors } - public T make(API api, Container.Entry entry) { + public T make(API api, Container.Entry entry) { int lastSlashIndex = entry.path.lastIndexOf('/') def name = entry.path.substring(lastSlashIndex+1) return new TreeNode(entry, new TreeNodeBean(label:name, icon:ICON, tip:"Location: $entry.uri.path")) diff --git a/services/src/main/groovy/jd/gui/service/treenode/SqlFileTreeNodeFactoryProvider.groovy b/services/src/main/groovy/jd/gui/service/treenode/SqlFileTreeNodeFactoryProvider.groovy index 3fa2659b..2a997ecb 100644 --- a/services/src/main/groovy/jd/gui/service/treenode/SqlFileTreeNodeFactoryProvider.groovy +++ b/services/src/main/groovy/jd/gui/service/treenode/SqlFileTreeNodeFactoryProvider.groovy @@ -6,6 +6,7 @@ package jd.gui.service.treenode import jd.gui.api.API +import jd.gui.api.feature.ContainerEntryGettable import jd.gui.api.feature.UriGettable import jd.gui.api.model.Container import jd.gui.view.data.TreeNodeBean @@ -22,7 +23,7 @@ class SqlFileTreeNodeFactoryProvider extends TextFileTreeNodeFactoryProvider { */ String[] getSelectors() { ['*:file:*.sql'] + externalSelectors } - public T make(API api, Container.Entry entry) { + public T make(API api, Container.Entry entry) { int lastSlashIndex = entry.path.lastIndexOf('/') def name = entry.path.substring(lastSlashIndex+1) return new TreeNode(entry, new TreeNodeBean(label:name, icon:ICON, tip:"Location: $entry.uri.path")) diff --git a/services/src/main/groovy/jd/gui/service/treenode/TextFileTreeNodeFactoryProvider.groovy b/services/src/main/groovy/jd/gui/service/treenode/TextFileTreeNodeFactoryProvider.groovy index 043e5873..eda8dc90 100644 --- a/services/src/main/groovy/jd/gui/service/treenode/TextFileTreeNodeFactoryProvider.groovy +++ b/services/src/main/groovy/jd/gui/service/treenode/TextFileTreeNodeFactoryProvider.groovy @@ -6,6 +6,7 @@ package jd.gui.service.treenode import jd.gui.api.API +import jd.gui.api.feature.ContainerEntryGettable import jd.gui.api.feature.PageCreator import jd.gui.api.feature.UriGettable import jd.gui.api.model.Container @@ -32,7 +33,7 @@ class TextFileTreeNodeFactoryProvider extends FileTreeNodeFactoryProvider { */ String[] getSelectors() { ['*:file:*.txt', '*:file:*.md', '*:file:*.SF', '*:file:*.policy', '*:file:*.yaml', '*:file:*.yml'] + externalSelectors } - public T make(API api, Container.Entry entry) { + public T make(API api, Container.Entry entry) { int lastSlashIndex = entry.path.lastIndexOf('/') def name = entry.path.substring(lastSlashIndex+1) return new TreeNode(entry, new TreeNodeBean(label:name, icon:ICON, tip:"Location: $entry.uri.path")) diff --git a/services/src/main/groovy/jd/gui/service/treenode/WarFileTreeNodeFactoryProvider.groovy b/services/src/main/groovy/jd/gui/service/treenode/WarFileTreeNodeFactoryProvider.groovy index fd1d9401..bc758576 100644 --- a/services/src/main/groovy/jd/gui/service/treenode/WarFileTreeNodeFactoryProvider.groovy +++ b/services/src/main/groovy/jd/gui/service/treenode/WarFileTreeNodeFactoryProvider.groovy @@ -6,6 +6,7 @@ package jd.gui.service.treenode import jd.gui.api.API +import jd.gui.api.feature.ContainerEntryGettable import jd.gui.api.feature.UriGettable import jd.gui.api.model.Container import jd.gui.view.data.TreeNodeBean @@ -21,7 +22,7 @@ class WarFileTreeNodeFactoryProvider extends ZipFileTreeNodeFactoryProvider { */ String[] getSelectors() { ['*:file:*.war'] + externalSelectors } - public T make(API api, Container.Entry entry) { + public T make(API api, Container.Entry entry) { int lastSlashIndex = entry.path.lastIndexOf('/') def name = entry.path.substring(lastSlashIndex+1) def node = new TreeNode(entry, 'war', new TreeNodeBean(label:name, icon:ICON)) diff --git a/services/src/main/groovy/jd/gui/service/treenode/WebXmlFileTreeNodeFactoryProvider.groovy b/services/src/main/groovy/jd/gui/service/treenode/WebXmlFileTreeNodeFactoryProvider.groovy index 5559f260..54167a4d 100644 --- a/services/src/main/groovy/jd/gui/service/treenode/WebXmlFileTreeNodeFactoryProvider.groovy +++ b/services/src/main/groovy/jd/gui/service/treenode/WebXmlFileTreeNodeFactoryProvider.groovy @@ -6,6 +6,7 @@ package jd.gui.service.treenode import jd.gui.api.API +import jd.gui.api.feature.ContainerEntryGettable import jd.gui.api.feature.PageCreator import jd.gui.api.feature.UriGettable import jd.gui.api.model.Container @@ -25,7 +26,7 @@ class WebXmlFileTreeNodeFactoryProvider extends FileTreeNodeFactoryProvider { */ String[] getSelectors() { ['war:file:WEB-INF/web.xml'] + externalSelectors } - public T make(API api, Container.Entry entry) { + public T make(API api, Container.Entry entry) { return new TreeNode(entry, new TreeNodeBean(label:'web.xml', icon:ICON, tip:"Location: $entry.uri.path")) } diff --git a/services/src/main/groovy/jd/gui/service/treenode/XmlBasedFileTreeNodeFactoryProvider.groovy b/services/src/main/groovy/jd/gui/service/treenode/XmlBasedFileTreeNodeFactoryProvider.groovy index c5769f56..aa4766d2 100644 --- a/services/src/main/groovy/jd/gui/service/treenode/XmlBasedFileTreeNodeFactoryProvider.groovy +++ b/services/src/main/groovy/jd/gui/service/treenode/XmlBasedFileTreeNodeFactoryProvider.groovy @@ -6,6 +6,7 @@ package jd.gui.service.treenode import jd.gui.api.API +import jd.gui.api.feature.ContainerEntryGettable import jd.gui.api.feature.UriGettable import jd.gui.api.model.Container import jd.gui.view.data.TreeNodeBean @@ -22,7 +23,7 @@ class XmlBasedFileTreeNodeFactoryProvider extends TextFileTreeNodeFactoryProvide */ String[] getSelectors() { ['*:file:*.xsl', '*:file:*.xslt', '*:file:*.xsd', '*:file:*.tld', '*:file:*.wsdl'] + externalSelectors } - public T make(API api, Container.Entry entry) { + public T make(API api, Container.Entry entry) { int lastSlashIndex = entry.path.lastIndexOf('/') def name = entry.path.substring(lastSlashIndex+1) return new TreeNode(entry, new TreeNodeBean(label:name, icon:ICON, tip:"Location: $entry.uri.path")) diff --git a/services/src/main/groovy/jd/gui/service/treenode/XmlFileTreeNodeFactoryProvider.groovy b/services/src/main/groovy/jd/gui/service/treenode/XmlFileTreeNodeFactoryProvider.groovy index 16af4377..d39464f9 100644 --- a/services/src/main/groovy/jd/gui/service/treenode/XmlFileTreeNodeFactoryProvider.groovy +++ b/services/src/main/groovy/jd/gui/service/treenode/XmlFileTreeNodeFactoryProvider.groovy @@ -6,6 +6,7 @@ package jd.gui.service.treenode import jd.gui.api.API +import jd.gui.api.feature.ContainerEntryGettable import jd.gui.api.feature.UriGettable import jd.gui.api.model.Container import jd.gui.view.component.XmlFilePage @@ -22,7 +23,7 @@ class XmlFileTreeNodeFactoryProvider extends TextFileTreeNodeFactoryProvider { */ String[] getSelectors() { ['*:file:*.xml'] + externalSelectors } - public T make(API api, Container.Entry entry) { + public T make(API api, Container.Entry entry) { int lastSlashIndex = entry.path.lastIndexOf('/') def name = entry.path.substring(lastSlashIndex+1) return new TreeNode(entry, new TreeNodeBean(label:name, icon:ICON, tip:"Location: $entry.uri.path")) diff --git a/services/src/main/groovy/jd/gui/service/treenode/ZipFileTreeNodeFactoryProvider.groovy b/services/src/main/groovy/jd/gui/service/treenode/ZipFileTreeNodeFactoryProvider.groovy index 2dcccb3f..cb0a39a9 100644 --- a/services/src/main/groovy/jd/gui/service/treenode/ZipFileTreeNodeFactoryProvider.groovy +++ b/services/src/main/groovy/jd/gui/service/treenode/ZipFileTreeNodeFactoryProvider.groovy @@ -6,6 +6,7 @@ package jd.gui.service.treenode import jd.gui.api.API +import jd.gui.api.feature.ContainerEntryGettable import jd.gui.api.feature.UriGettable import jd.gui.api.model.Container import jd.gui.spi.TreeNodeFactory @@ -22,7 +23,7 @@ class ZipFileTreeNodeFactoryProvider extends DirectoryTreeNodeFactoryProvider { */ String[] getSelectors() { ['*:file:*.zip'] + externalSelectors } - public T make(API api, Container.Entry entry) { + public T make(API api, Container.Entry entry) { int lastSlashIndex = entry.path.lastIndexOf('/') def name = entry.path.substring(lastSlashIndex+1) def node = new TreeNode(entry, 'generic', new TreeNodeBean(label:name, icon:ICON)) diff --git a/services/src/main/java/jd/gui/service/type/AbstractTypeFactoryProvider.java b/services/src/main/java/jd/gui/service/type/AbstractTypeFactoryProvider.java index 31ad791f..8dcae4d4 100644 --- a/services/src/main/java/jd/gui/service/type/AbstractTypeFactoryProvider.java +++ b/services/src/main/java/jd/gui/service/type/AbstractTypeFactoryProvider.java @@ -56,6 +56,200 @@ public String[] getSelectors() { } public Pattern getPathPattern() { return externalPathPattern; } + // Signature writers + protected static int writeSignature(StringBuffer sb, String descriptor, int length, int index, boolean varargsFlag) { + while (true) { + // Print array : '[[?' ou '[L[?;' + int dimensionLength = 0; + + if (descriptor.charAt(index) == '[') { + dimensionLength++; + + while (++index < length) { + if ((descriptor.charAt(index) == 'L') && (index+1 < length) && (descriptor.charAt(index+1) == '[')) { + index++; + length--; + dimensionLength++; + } else if (descriptor.charAt(index) == '[') { + dimensionLength++; + } else { + break; + } + } + } + + switch(descriptor.charAt(index)) { + case 'B': sb.append("byte"); index++; break; + case 'C': sb.append("char"); index++; break; + case 'D': sb.append("double"); index++; break; + case 'F': sb.append("float"); index++; break; + case 'I': sb.append("int"); index++; break; + case 'J': sb.append("long"); index++; break; + case 'L': case '.': + int beginIndex = ++index; + char c = '.'; + + // Search ; or de < + while (index < length) { + c = descriptor.charAt(index); + if ((c == ';') || (c == '<')) + break; + index++; + } + + String internalClassName = descriptor.substring(beginIndex, index); + int lastPackageSeparatorIndex = internalClassName.lastIndexOf('/'); + + if (lastPackageSeparatorIndex >= 0) { + // Cut package name + internalClassName = internalClassName.substring(lastPackageSeparatorIndex + 1); + } + + sb.append(internalClassName.replace('$', '.')); + + if (c == '<') { + sb.append('<'); + index = writeSignature(sb, descriptor, length, index+1, false); + + while (descriptor.charAt(index) != '>') { + sb.append(", "); + index = writeSignature(sb, descriptor, length, index, false); + } + sb.append('>'); + + // pass '>' + index++; + } + + // pass ';' + if (descriptor.charAt(index) == ';') + index++; + break; + case 'S': sb.append("short"); index++; break; + case 'T': + beginIndex = ++index; + index = descriptor.substring(beginIndex, length).indexOf(';'); + sb.append(descriptor.substring(beginIndex, index)); + index++; + break; + case 'V': sb.append("void"); index++; break; + case 'Z': sb.append("boolean"); index++; break; + case '-': + sb.append("? super "); + index = writeSignature(sb, descriptor, length, index+1, false); + break; + case '+': + sb.append("? extends "); + index = writeSignature(sb, descriptor, length, index+1, false); + break; + case '*': sb.append('?'); index++; break; + case 'X': case 'Y': sb.append("int"); index++; break; + default: + throw new RuntimeException("SignatureWriter.WriteSignature: invalid signature '" + descriptor + "'"); + } + + if (varargsFlag) { + if (dimensionLength > 0) { + while (--dimensionLength > 0) + sb.append("[]"); + sb.append("..."); + } + } else { + while (dimensionLength-- > 0) + sb.append("[]"); + } + + if ((index >= length) || (descriptor.charAt(index) != '.')) + break; + + sb.append('.'); + } + + return index; + } + + protected static void writeMethodSignature( + StringBuffer sb, int typeAccess, int methodAccess, boolean isInnerClass, + String constructorName, String methodName, String descriptor) { + if (methodName.equals("")) { + sb.append("{...}"); + } else { + boolean isAConstructor = methodName.equals(""); + + if (isAConstructor) { + sb.append(constructorName); + } else { + sb.append(methodName); + } + + // Skip generics + int length = descriptor.length(); + int index = 0; + + while ((index < length) && (descriptor.charAt(index) != '(')) + index++; + + if (descriptor.charAt(index) != '(') { + throw new RuntimeException("Signature format exception: '" + descriptor + "'"); + } + + sb.append('('); + + // pass '(' + index++; + + if (descriptor.charAt(index) != ')') { + if (isAConstructor && isInnerClass && ((typeAccess & Type.FLAG_STATIC) == 0)) { + // Skip first parameter + int lengthBackup = sb.length(); + index = writeSignature(sb, descriptor, length, index, false); + sb.setLength(lengthBackup); + } + + if (descriptor.charAt(index) != ')') { + int varargsParameterIndex; + + if ((methodAccess & Type.FLAG_VARARGS) == 0) { + varargsParameterIndex = Integer.MAX_VALUE; + } else { + // Count parameters + int indexBackup = index; + int lengthBackup = sb.length(); + + varargsParameterIndex = -1; + + while (descriptor.charAt(index) != ')') { + index = writeSignature(sb, descriptor, length, index, false); + varargsParameterIndex++; + } + + index = indexBackup; + sb.setLength(lengthBackup); + } + + // Write parameters + index = writeSignature(sb, descriptor, length, index, false); + + int parameterIndex = 1; + + while (descriptor.charAt(index) != ')') { + sb.append(", "); + index = writeSignature(sb, descriptor, length, index, (parameterIndex == varargsParameterIndex)); + parameterIndex++; + } + } + } + + if (isAConstructor) { + sb.append(')'); + } else { + sb.append(") : "); + writeSignature(sb, descriptor, length, ++index, false); + } + } + } + + // Icon getters protected static ImageIcon getTypeIcon(int access) { if ((access & Type.FLAG_ANNOTATION) != 0) return ANNOTATION_ICON; @@ -97,7 +291,7 @@ else if ((access & Type.FLAG_PRIVATE) != 0) return index; } - // Graphic stuff ... + // Internal graphic stuff ... protected static ImageIcon mergeIcons(ImageIcon background, ImageIcon overlay, int x, int y) { int w = background.getIconWidth(); int h = background.getIconHeight(); diff --git a/services/src/main/java/jd/gui/service/type/ClassFileTypeFactoryProvider.java b/services/src/main/java/jd/gui/service/type/ClassFileTypeFactoryProvider.java index e761903b..5982ec20 100644 --- a/services/src/main/java/jd/gui/service/type/ClassFileTypeFactoryProvider.java +++ b/services/src/main/java/jd/gui/service/type/ClassFileTypeFactoryProvider.java @@ -261,6 +261,13 @@ public List getFields() { public String getName() { return fieldNode.name; } public String getDescriptor() { return fieldNode.desc; } public Icon getIcon() { return getFieldIcon(fieldNode.access); } + + public String getDisplayName() { + StringBuffer sb = new StringBuffer(); + sb.append(fieldNode.name).append(" : "); + writeSignature(sb, fieldNode.desc, fieldNode.desc.length(), 0, false); + return sb.toString(); + } }); } } @@ -280,6 +287,18 @@ public List getMethods() { public String getName() { return methodNode.name; } public String getDescriptor() { return methodNode.desc; } public Icon getIcon() { return getMethodIcon(methodNode.access); } + + public String getDisplayName() { + String constructorName = displayInnerTypeName; + boolean isInnerClass = (constructorName != null); + + if (constructorName == null) + constructorName = getDisplayTypeName(); + + StringBuffer sb = new StringBuffer(); + writeMethodSignature(sb, access, methodNode.access, isInnerClass, constructorName, methodNode.name, methodNode.desc); + return sb.toString(); + } }); } } diff --git a/services/src/main/java/jd/gui/service/type/JavaFileTypeFactoryProvider.java b/services/src/main/java/jd/gui/service/type/JavaFileTypeFactoryProvider.java index cd3d7573..429dc16b 100644 --- a/services/src/main/java/jd/gui/service/type/JavaFileTypeFactoryProvider.java +++ b/services/src/main/java/jd/gui/service/type/JavaFileTypeFactoryProvider.java @@ -137,14 +137,23 @@ public JavaField(int access, String name, String descriptor) { public String getName() { return name; } public String getDescriptor() { return descriptor; } public Icon getIcon() { return getFieldIcon(access); } + + public String getDisplayName() { + StringBuffer sb = new StringBuffer(); + sb.append(name).append(" : "); + writeSignature(sb, descriptor, descriptor.length(), 0, false); + return sb.toString(); + } } protected static class JavaMethod implements Type.Method { + protected JavaType type; protected int access; protected String name; protected String descriptor; - public JavaMethod(int access, String name, String descriptor) { + public JavaMethod(JavaType type, int access, String name, String descriptor) { + this.type = type; this.access = access; this.name = name; this.descriptor = descriptor; @@ -154,6 +163,18 @@ public JavaMethod(int access, String name, String descriptor) { public String getName() { return name; } public String getDescriptor() { return descriptor; } public Icon getIcon() { return getMethodIcon(access); } + + public String getDisplayName() { + String constructorName = type.getDisplayInnerTypeName(); + boolean isInnerClass = (constructorName != null); + + if (constructorName == null) + constructorName = type.getDisplayTypeName(); + + StringBuffer sb = new StringBuffer(); + writeMethodSignature(sb, access, access, isInnerClass, constructorName, name, descriptor); + return sb.toString(); + } } protected static class Listener extends AbstractJavaListener { @@ -264,7 +285,7 @@ public void enterClassBodyDeclaration(JavaParser.ClassBodyDeclarationContext ctx if (first instanceof TerminalNode) { if (((TerminalNode)first).getSymbol().getType() == JavaParser.STATIC) { - currentType.getMethods().add(new JavaMethod(JavaType.FLAG_STATIC, "", "()V")); + currentType.getMethods().add(new JavaMethod(currentType, JavaType.FLAG_STATIC, "", "()V")); } } } @@ -317,7 +338,7 @@ public void enterMethodDeclaration( String returnDescriptor = createDescriptor(returnType, 0); String descriptor = paramDescriptors + returnDescriptor; - currentType.getMethods().add(new JavaMethod(access, name, descriptor)); + currentType.getMethods().add(new JavaMethod(currentType, access, name, descriptor)); } public void enterConstructorDeclaration(JavaParser.ConstructorDeclarationContext ctx) { @@ -325,7 +346,7 @@ public void enterConstructorDeclaration(JavaParser.ConstructorDeclarationContext String paramDescriptors = createParamDescriptors(ctx.formalParameters().formalParameterList()); String descriptor = paramDescriptors + "V"; - currentType.getMethods().add(new JavaMethod(access, "", descriptor)); + currentType.getMethods().add(new JavaMethod(currentType, access, "", descriptor)); } protected String createParamDescriptors(JavaParser.FormalParameterListContext formalParameterList) { diff --git a/services/src/main/resources/META-INF/services/jd.gui.spi.ContextualActionsFactory b/services/src/main/resources/META-INF/services/jd.gui.spi.ContextualActionsFactory new file mode 100644 index 00000000..6b943865 --- /dev/null +++ b/services/src/main/resources/META-INF/services/jd.gui.spi.ContextualActionsFactory @@ -0,0 +1 @@ +jd.gui.service.actions.CopyQualifiedNameContextualActionsFactory diff --git a/services/src/main/resources/images/cpyqual_menu.png b/services/src/main/resources/images/cpyqual_menu.png new file mode 100644 index 0000000000000000000000000000000000000000..fab58422497981ea9bbb5d52d9f2304a39212f41 GIT binary patch literal 526 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbMffdHQn*B?Lsq}Q%2@7en4>+i4M zfB*dT=f}_Ah3y+_C+%#Qy1RMC-mZCv%3Ef)&pD7%+>=t=J#p#r-0DeXEwjp7W;OIK zYV2M3;N_3c-+rf*^duK|r<8Q(R8J~zoz*sZ`Tdta?!EZ_{pX)#pj1isgI7Nuy!!s> z+wXT@etrG%`}XVad+&dlHEY7Gnf4j^S$666;Q6eJ%o?D}13 z1~iE=$=lt<-Y(go6v*K$@Q5r1(jH*!b~4)z$e8Qt;us=vIrjWXp(X&5%<&TsN07PBS)O z>d(q=Le1JM*L*#@IfQ570wdqWx7>LyW?U%NZV1zfNX+DWamMHF#nfwW%#?&bY*BCV zd3;Ig!yC?H=eG4;y>zdSQTUu*OzLa}1#=C#6+TwenokKGv-r*UEMD!`KBk+WfDUEw MboFyt=akR{0OGwNhX4Qo literal 0 HcmV?d00001