1 21 package proguard.gui; 22 23 import proguard.*; 24 import proguard.classfile.util.ClassUtil; 25 import proguard.gui.splash.*; 26 import proguard.util.ListUtil; 27 28 import javax.swing.*; 29 import javax.swing.border.*; 30 import java.awt.*; 31 import java.awt.image.BufferedImage ; 32 import java.awt.event.*; 33 import java.io.*; 34 import java.net.URL ; 35 import java.util.*; 36 import java.util.List ; 37 38 39 44 public class ProGuardGUI extends JFrame 45 { 46 private static final String NO_SPLASH_OPTION = "-nosplash"; 47 48 private static final String TITLE_IMAGE_FILE = "vtitle.gif"; 49 private static final String BOILERPLATE_CONFIGURATION = "boilerplate.pro"; 50 private static final String DEFAULT_CONFIGURATION = "default.pro"; 51 52 private static final String KEEP_ATTRIBUTE_DEFAULT = "InnerClasses,SourceFile,ExceptionsLineNumberTable,Deprecated,Signature,*Annotation*,EnclosingMethod"; 53 private static final String SOURCE_FILE_ATTRIBUTE_DEFAULT = "SourceFile"; 54 private static final String ADAPT_RESOURCE_FILE_NAMES_DEFAULT = "**.properties"; 55 private static final String ADAPT_RESOURCE_FILE_CONTENTS_DEFAULT = "**.properties,META-INF/MANIFEST.MF"; 56 57 private static final Border BORDER = BorderFactory.createEtchedBorder(EtchedBorder.RAISED); 58 59 static boolean systemOutRedirected; 60 61 private JFileChooser configurationChooser = new JFileChooser(""); 62 private JFileChooser fileChooser = new JFileChooser(""); 63 64 private SplashPanel splashPanel; 65 66 private ClassPathPanel programPanel = new ClassPathPanel(this, true); 67 private ClassPathPanel libraryPanel = new ClassPathPanel(this, false); 68 69 private KeepSpecification[] boilerplateKeep; 70 private JCheckBox[] boilerplateKeepCheckBoxes; 71 private JTextField[] boilerplateKeepTextFields; 72 73 private KeepSpecificationsPanel additionalKeepPanel = new KeepSpecificationsPanel(this, true, false, false, false, false); 74 75 private KeepSpecification[] boilerplateKeepNames; 76 private JCheckBox[] boilerplateKeepNamesCheckBoxes; 77 private JTextField[] boilerplateKeepNamesTextFields; 78 79 private KeepSpecificationsPanel additionalKeepNamesPanel = new KeepSpecificationsPanel(this, true, false, true, false, false); 80 81 private ClassSpecification[] boilerplateNoSideEffectMethods; 82 private JCheckBox[] boilerplateNoSideEffectMethodCheckBoxes; 83 84 private ClassSpecificationsPanel additionalNoSideEffectsPanel = new ClassSpecificationsPanel(this, false); 85 86 private ClassSpecificationsPanel whyAreYouKeepingPanel = new ClassSpecificationsPanel(this, false); 87 88 private JCheckBox shrinkCheckBox = new JCheckBox(msg("shrink")); 89 private JCheckBox printUsageCheckBox = new JCheckBox(msg("printUsage")); 90 91 private JCheckBox optimizeCheckBox = new JCheckBox(msg("optimize")); 92 private JCheckBox allowAccessModificationCheckBox = new JCheckBox(msg("allowAccessModification")); 93 private JLabel optimizationPassesLabel = new JLabel(msg("optimizationPasses")); 94 private JSpinner optimizationPassesSpinner = new JSpinner(new SpinnerNumberModel(1, 1, 9, 1)); 95 96 private JCheckBox obfuscateCheckBox = new JCheckBox(msg("obfuscate")); 97 private JCheckBox printMappingCheckBox = new JCheckBox(msg("printMapping")); 98 private JCheckBox applyMappingCheckBox = new JCheckBox(msg("applyMapping")); 99 private JCheckBox obfuscationDictionaryCheckBox = new JCheckBox(msg("obfuscationDictionary")); 100 private JCheckBox overloadAggressivelyCheckBox = new JCheckBox(msg("overloadAggressively")); 101 private JCheckBox useUniqueClassMemberNamesCheckBox = new JCheckBox(msg("useUniqueClassMemberNames")); 102 private JCheckBox useMixedCaseClassNamesCheckBox = new JCheckBox(msg("useMixedCaseClassNames")); 103 private JCheckBox flattenPackageHierarchyCheckBox = new JCheckBox(msg("flattenPackageHierarchy")); 104 private JCheckBox repackageClassesCheckBox = new JCheckBox(msg("repackageClasses")); 105 private JCheckBox keepAttributesCheckBox = new JCheckBox(msg("keepAttributes")); 106 private JCheckBox newSourceFileAttributeCheckBox = new JCheckBox(msg("renameSourceFileAttribute")); 107 private JCheckBox adaptResourceFileNamesCheckBox = new JCheckBox(msg("adaptResourceFileNames")); 108 private JCheckBox adaptResourceFileContentsCheckBox = new JCheckBox(msg("adaptResourceFileContents")); 109 110 private JCheckBox preverifyCheckBox = new JCheckBox(msg("preverify")); 111 private JCheckBox microEditionCheckBox = new JCheckBox(msg("microEdition")); 112 private JCheckBox targetCheckBox = new JCheckBox(msg("target")); 113 114 private JComboBox targetComboBox = new JComboBox(ListUtil.commaSeparatedList(msg("targets")).toArray()); 115 116 private JCheckBox verboseCheckBox = new JCheckBox(msg("verbose")); 117 private JCheckBox ignoreWarningsCheckBox = new JCheckBox(msg("ignoreWarnings")); 118 private JCheckBox warnCheckBox = new JCheckBox(msg("warn")); 119 private JCheckBox noteCheckBox = new JCheckBox(msg("note")); 120 private JCheckBox skipNonPublicLibraryClassesCheckBox = new JCheckBox(msg("skipNonPublicLibraryClasses")); 121 private JCheckBox skipNonPublicLibraryClassMembersCheckBox = new JCheckBox(msg("skipNonPublicLibraryClassMembers")); 122 private JCheckBox forceProcessingCheckBox = new JCheckBox(msg("forceProcessing")); 123 private JCheckBox printSeedsCheckBox = new JCheckBox(msg("printSeeds")); 124 private JCheckBox printConfigurationCheckBox = new JCheckBox(msg("printConfiguration")); 125 private JCheckBox dumpCheckBox = new JCheckBox(msg("dump")); 126 127 private JTextField printUsageTextField = new JTextField(40); 128 private JTextField printMappingTextField = new JTextField(40); 129 private JTextField applyMappingTextField = new JTextField(40); 130 private JTextField obfuscationDictionaryTextField = new JTextField(40); 131 private JTextField flattenPackageHierarchyTextField = new JTextField(40); 132 private JTextField repackageClassesTextField = new JTextField(40); 133 private JTextField keepAttributesTextField = new JTextField(40); 134 private JTextField newSourceFileAttributeTextField = new JTextField(40); 135 private JTextField adaptResourceFileNamesTextField = new JTextField(40); 136 private JTextField adaptResourceFileContentsTextField = new JTextField(40); 137 private JTextField printSeedsTextField = new JTextField(40); 138 private JTextField printConfigurationTextField = new JTextField(40); 139 private JTextField dumpTextField = new JTextField(40); 140 141 private JTextArea consoleTextArea = new JTextArea(msg("processingInfo"), 3, 40); 142 143 private JCheckBox reTraceVerboseCheckBox = new JCheckBox(msg("verbose")); 144 private JTextField reTraceMappingTextField = new JTextField(40); 145 private JTextArea stackTraceTextArea = new JTextArea(3, 40); 146 private JTextArea reTraceTextArea = new JTextArea(msg("reTraceInfo"), 3, 40); 147 148 149 152 public ProGuardGUI() 153 { 154 setTitle("ProGuard"); 155 setDefaultCloseOperation(EXIT_ON_CLOSE); 156 157 GridBagConstraints constraints = new GridBagConstraints(); 159 constraints.anchor = GridBagConstraints.WEST; 160 constraints.insets = new Insets(0, 4, 0, 4); 161 162 GridBagConstraints constraintsStretch = new GridBagConstraints(); 163 constraintsStretch.fill = GridBagConstraints.HORIZONTAL; 164 constraintsStretch.weightx = 1.0; 165 constraintsStretch.anchor = GridBagConstraints.WEST; 166 constraintsStretch.insets = constraints.insets; 167 168 GridBagConstraints constraintsLast = new GridBagConstraints(); 169 constraintsLast.gridwidth = GridBagConstraints.REMAINDER; 170 constraintsLast.anchor = GridBagConstraints.WEST; 171 constraintsLast.insets = constraints.insets; 172 173 GridBagConstraints constraintsLastStretch = new GridBagConstraints(); 174 constraintsLastStretch.gridwidth = GridBagConstraints.REMAINDER; 175 constraintsLastStretch.fill = GridBagConstraints.HORIZONTAL; 176 constraintsLastStretch.weightx = 1.0; 177 constraintsLastStretch.anchor = GridBagConstraints.WEST; 178 constraintsLastStretch.insets = constraints.insets; 179 180 GridBagConstraints splashPanelConstraints = new GridBagConstraints(); 181 splashPanelConstraints.gridwidth = GridBagConstraints.REMAINDER; 182 splashPanelConstraints.fill = GridBagConstraints.BOTH; 183 splashPanelConstraints.weightx = 1.0; 184 splashPanelConstraints.weighty = 0.02; 185 splashPanelConstraints.anchor = GridBagConstraints.NORTHWEST; 186 188 GridBagConstraints welcomeTextAreaConstraints = new GridBagConstraints(); 189 welcomeTextAreaConstraints.gridwidth = GridBagConstraints.REMAINDER; 190 welcomeTextAreaConstraints.fill = GridBagConstraints.NONE; 191 welcomeTextAreaConstraints.weightx = 1.0; 192 welcomeTextAreaConstraints.weighty = 0.01; 193 welcomeTextAreaConstraints.anchor = GridBagConstraints.CENTER; welcomeTextAreaConstraints.insets = new Insets(20, 40, 20, 40); 195 196 GridBagConstraints panelConstraints = new GridBagConstraints(); 197 panelConstraints.gridwidth = GridBagConstraints.REMAINDER; 198 panelConstraints.fill = GridBagConstraints.HORIZONTAL; 199 panelConstraints.weightx = 1.0; 200 panelConstraints.anchor = GridBagConstraints.NORTHWEST; 201 panelConstraints.insets = constraints.insets; 202 203 GridBagConstraints stretchPanelConstraints = new GridBagConstraints(); 204 stretchPanelConstraints.gridwidth = GridBagConstraints.REMAINDER; 205 stretchPanelConstraints.fill = GridBagConstraints.BOTH; 206 stretchPanelConstraints.weightx = 1.0; 207 stretchPanelConstraints.weighty = 1.0; 208 stretchPanelConstraints.anchor = GridBagConstraints.NORTHWEST; 209 stretchPanelConstraints.insets = constraints.insets; 210 211 GridBagConstraints glueConstraints = new GridBagConstraints(); 212 glueConstraints.fill = GridBagConstraints.BOTH; 213 glueConstraints.weightx = 0.01; 214 glueConstraints.weighty = 0.01; 215 glueConstraints.anchor = GridBagConstraints.NORTHWEST; 216 glueConstraints.insets = constraints.insets; 217 218 GridBagConstraints bottomButtonConstraints = new GridBagConstraints(); 219 bottomButtonConstraints.anchor = GridBagConstraints.SOUTHEAST; 220 bottomButtonConstraints.insets = new Insets(2, 2, 4, 6); 221 bottomButtonConstraints.ipadx = 10; 222 bottomButtonConstraints.ipady = 2; 223 224 GridBagConstraints lastBottomButtonConstraints = new GridBagConstraints(); 225 lastBottomButtonConstraints.gridwidth = GridBagConstraints.REMAINDER; 226 lastBottomButtonConstraints.anchor = GridBagConstraints.SOUTHEAST; 227 lastBottomButtonConstraints.insets = bottomButtonConstraints.insets; 228 lastBottomButtonConstraints.ipadx = bottomButtonConstraints.ipadx; 229 lastBottomButtonConstraints.ipady = bottomButtonConstraints.ipady; 230 231 if (System.getProperty("os.name").toLowerCase().startsWith("mac os x")) 233 { 234 lastBottomButtonConstraints.insets = new Insets(2, 2, 4, 6 + 16); 235 } 236 237 GridBagLayout layout = new GridBagLayout(); 238 239 configurationChooser.addChoosableFileFilter( 240 new ExtensionFileFilter(msg("proExtension"), new String [] { ".pro" })); 241 242 Sprite splash = 244 new CompositeSprite(new Sprite[] 245 { 246 new ColorSprite(new ConstantColor(Color.gray), 247 new FontSprite(new ConstantFont(new Font("sansserif", Font.BOLD, 90)), 248 new TextSprite(new ConstantString("ProGuard"), 249 new ConstantInt(160), 250 new LinearInt(-10, 120, new SmoothTiming(500, 1000))))), 251 252 new ColorSprite(new ConstantColor(Color.white), 253 new FontSprite(new ConstantFont(new Font("sansserif", Font.BOLD, 45)), 254 new ShadowedSprite(new ConstantInt(3), 255 new ConstantInt(3), 256 new ConstantDouble(0.4), 257 new ConstantInt(1), 258 new CompositeSprite(new Sprite[] 259 { 260 new TextSprite(new ConstantString(msg("shrinking")), 261 new LinearInt(1000, 60, new SmoothTiming(1000, 2000)), 262 new ConstantInt(70)), 263 new TextSprite(new ConstantString(msg("optimization")), 264 new LinearInt(1000, 400, new SmoothTiming(1500, 2500)), 265 new ConstantInt(60)), 266 new TextSprite(new ConstantString(msg("obfuscation")), 267 new LinearInt(1000, 10, new SmoothTiming(2000, 3000)), 268 new ConstantInt(145)), 269 new TextSprite(new ConstantString(msg("preverification")), 270 new LinearInt(1000, 350, new SmoothTiming(2500, 3500)), 271 new ConstantInt(140)), 272 new FontSprite(new ConstantFont(new Font("sansserif", Font.BOLD, 30)), 273 new TextSprite(new TypeWriterString(msg("developed"), new LinearTiming(3500, 5500)), 274 new ConstantInt(250), 275 new ConstantInt(200))), 276 })))), 277 }); 278 splashPanel = new SplashPanel(splash, 0.5, 5500L); 279 splashPanel.setPreferredSize(new Dimension(0, 200)); 280 281 JTextArea welcomeTextArea = new JTextArea(msg("proGuardInfo"), 18, 50); 282 welcomeTextArea.setOpaque(false); 283 welcomeTextArea.setEditable(false); 284 welcomeTextArea.setLineWrap(true); 285 welcomeTextArea.setWrapStyleWord(true); 286 welcomeTextArea.setPreferredSize(new Dimension(0, 0)); 287 welcomeTextArea.setBorder(new EmptyBorder(20, 20, 20, 20)); 288 addBorder(welcomeTextArea, "welcome"); 289 290 JPanel proGuardPanel = new JPanel(layout); 291 proGuardPanel.add(splashPanel, splashPanelConstraints); 292 proGuardPanel.add(welcomeTextArea, welcomeTextAreaConstraints); 293 294 programPanel.addCopyToPanelButton(msg("moveToLibraries"), libraryPanel); 299 libraryPanel.addCopyToPanelButton(msg("moveToProgram"), programPanel); 300 301 List panelButtons = new ArrayList(); 304 panelButtons.addAll(programPanel.getButtons()); 305 panelButtons.addAll(libraryPanel.getButtons()); 306 setCommonPreferredSize(panelButtons); 307 panelButtons = null; 308 309 addBorder(programPanel, "programJars" ); 310 addBorder(libraryPanel, "libraryJars" ); 311 312 JPanel inputOutputPanel = new JPanel(layout); 313 inputOutputPanel.add(programPanel, stretchPanelConstraints); 314 inputOutputPanel.add(libraryPanel, stretchPanelConstraints); 315 316 loadBoilerplateConfiguration(); 318 319 boilerplateKeepCheckBoxes = new JCheckBox[boilerplateKeep.length]; 321 boilerplateKeepTextFields = new JTextField[boilerplateKeep.length]; 322 323 JButton printUsageBrowseButton = createBrowseButton(printUsageTextField, 324 msg("selectUsageFile")); 325 326 JPanel shrinkingOptionsPanel = new JPanel(layout); 327 addBorder(shrinkingOptionsPanel, "options"); 328 329 shrinkingOptionsPanel.add(shrinkCheckBox, constraintsLastStretch); 330 shrinkingOptionsPanel.add(printUsageCheckBox, constraints); 331 shrinkingOptionsPanel.add(printUsageTextField, constraintsStretch); 332 shrinkingOptionsPanel.add(printUsageBrowseButton, constraintsLast); 333 334 JPanel shrinkingPanel = new JPanel(layout); 335 336 shrinkingPanel.add(shrinkingOptionsPanel, panelConstraints); 337 addClassSpecifications(extractClassSpecifications(boilerplateKeep), 338 shrinkingPanel, 339 boilerplateKeepCheckBoxes, 340 boilerplateKeepTextFields); 341 342 addBorder(additionalKeepPanel, "keepAdditional"); 343 shrinkingPanel.add(additionalKeepPanel, stretchPanelConstraints); 344 345 boilerplateKeepNamesCheckBoxes = new JCheckBox[boilerplateKeepNames.length]; 347 boilerplateKeepNamesTextFields = new JTextField[boilerplateKeepNames.length]; 348 349 JButton printMappingBrowseButton = createBrowseButton(printMappingTextField, 350 msg("selectPrintMappingFile")); 351 JButton applyMappingBrowseButton = createBrowseButton(applyMappingTextField, 352 msg("selectApplyMappingFile")); 353 JButton obfucationDictionaryBrowseButton = createBrowseButton(obfuscationDictionaryTextField, 354 msg("selectObfuscationDictionaryFile")); 355 356 JPanel obfuscationOptionsPanel = new JPanel(layout); 357 addBorder(obfuscationOptionsPanel, "options"); 358 359 obfuscationOptionsPanel.add(obfuscateCheckBox, constraintsLastStretch); 360 obfuscationOptionsPanel.add(printMappingCheckBox, constraints); 361 obfuscationOptionsPanel.add(printMappingTextField, constraintsStretch); 362 obfuscationOptionsPanel.add(printMappingBrowseButton, constraintsLast); 363 obfuscationOptionsPanel.add(applyMappingCheckBox, constraints); 364 obfuscationOptionsPanel.add(applyMappingTextField, constraintsStretch); 365 obfuscationOptionsPanel.add(applyMappingBrowseButton, constraintsLast); 366 obfuscationOptionsPanel.add(obfuscationDictionaryCheckBox, constraints); 367 obfuscationOptionsPanel.add(obfuscationDictionaryTextField, constraintsStretch); 368 obfuscationOptionsPanel.add(obfucationDictionaryBrowseButton, constraintsLast); 369 obfuscationOptionsPanel.add(overloadAggressivelyCheckBox, constraintsLastStretch); 370 obfuscationOptionsPanel.add(useUniqueClassMemberNamesCheckBox, constraintsLastStretch); 371 obfuscationOptionsPanel.add(useMixedCaseClassNamesCheckBox, constraintsLastStretch); 372 obfuscationOptionsPanel.add(flattenPackageHierarchyCheckBox, constraints); 373 obfuscationOptionsPanel.add(flattenPackageHierarchyTextField, constraintsLastStretch); 374 obfuscationOptionsPanel.add(repackageClassesCheckBox, constraints); 375 obfuscationOptionsPanel.add(repackageClassesTextField, constraintsLastStretch); 376 obfuscationOptionsPanel.add(keepAttributesCheckBox, constraints); 377 obfuscationOptionsPanel.add(keepAttributesTextField, constraintsLastStretch); 378 obfuscationOptionsPanel.add(newSourceFileAttributeCheckBox, constraints); 379 obfuscationOptionsPanel.add(newSourceFileAttributeTextField, constraintsLastStretch); 380 obfuscationOptionsPanel.add(adaptResourceFileNamesCheckBox, constraints); 381 obfuscationOptionsPanel.add(adaptResourceFileNamesTextField, constraintsLastStretch); 382 obfuscationOptionsPanel.add(adaptResourceFileContentsCheckBox, constraints); 383 obfuscationOptionsPanel.add(adaptResourceFileContentsTextField, constraintsLastStretch); 384 385 JPanel obfuscationPanel = new JPanel(layout); 386 387 obfuscationPanel.add(obfuscationOptionsPanel, panelConstraints); 388 addClassSpecifications(extractClassSpecifications(boilerplateKeepNames), 389 obfuscationPanel, 390 boilerplateKeepNamesCheckBoxes, 391 boilerplateKeepNamesTextFields); 392 393 addBorder(additionalKeepNamesPanel, "keepNamesAdditional"); 394 obfuscationPanel.add(additionalKeepNamesPanel, stretchPanelConstraints); 395 396 boilerplateNoSideEffectMethodCheckBoxes = new JCheckBox[boilerplateNoSideEffectMethods.length]; 398 399 JPanel optimizationOptionsPanel = new JPanel(layout); 400 addBorder(optimizationOptionsPanel, "options"); 401 402 optimizationOptionsPanel.add(optimizeCheckBox, constraintsLastStretch); 403 optimizationOptionsPanel.add(allowAccessModificationCheckBox, constraintsLastStretch); 404 optimizationOptionsPanel.add(optimizationPassesLabel, constraints); 405 optimizationOptionsPanel.add(optimizationPassesSpinner, constraintsLast); 406 407 JPanel optimizationPanel = new JPanel(layout); 408 409 optimizationPanel.add(optimizationOptionsPanel, panelConstraints); 410 addClassSpecifications(boilerplateNoSideEffectMethods, 411 optimizationPanel, 412 boilerplateNoSideEffectMethodCheckBoxes, 413 null); 414 415 addBorder(additionalNoSideEffectsPanel, "assumeNoSideEffectsAdditional"); 416 optimizationPanel.add(additionalNoSideEffectsPanel, stretchPanelConstraints); 417 418 JPanel preverificationOptionsPanel = new JPanel(layout); 420 addBorder(preverificationOptionsPanel, "preverificationAndTargeting"); 421 422 preverificationOptionsPanel.add(preverifyCheckBox, constraintsLastStretch); 423 preverificationOptionsPanel.add(microEditionCheckBox, constraintsLastStretch); 424 preverificationOptionsPanel.add(targetCheckBox, constraints); 425 preverificationOptionsPanel.add(targetComboBox, constraintsLast); 426 427 JButton printSeedsBrowseButton = 428 createBrowseButton(printSeedsTextField, msg("selectSeedsFile")); 429 430 JButton printConfigurationBrowseButton = 431 createBrowseButton(printConfigurationTextField, msg( "selectConfigurationFile")); 432 433 JButton dumpBrowseButton = 434 createBrowseButton(dumpTextField, msg("selectDumpFile")); 435 436 targetComboBox.setSelectedIndex(targetComboBox.getItemCount() - 1); 438 439 JPanel consistencyPanel = new JPanel(layout); 440 addBorder(consistencyPanel, "consistencyAndCorrectness"); 441 442 consistencyPanel.add(verboseCheckBox, constraintsLastStretch); 443 consistencyPanel.add(noteCheckBox, constraintsLastStretch); 444 consistencyPanel.add(warnCheckBox, constraintsLastStretch); 445 consistencyPanel.add(ignoreWarningsCheckBox, constraintsLastStretch); 446 consistencyPanel.add(skipNonPublicLibraryClassesCheckBox, constraintsLastStretch); 447 consistencyPanel.add(skipNonPublicLibraryClassMembersCheckBox, constraintsLastStretch); 448 consistencyPanel.add(forceProcessingCheckBox, constraintsLastStretch); 449 consistencyPanel.add(printSeedsCheckBox, constraints); 450 consistencyPanel.add(printSeedsTextField, constraintsStretch); 451 consistencyPanel.add(printSeedsBrowseButton, constraintsLast); 452 consistencyPanel.add(printConfigurationCheckBox, constraints); 453 consistencyPanel.add(printConfigurationTextField, constraintsStretch); 454 consistencyPanel.add(printConfigurationBrowseButton, constraintsLast); 455 consistencyPanel.add(dumpCheckBox, constraints); 456 consistencyPanel.add(dumpTextField, constraintsStretch); 457 consistencyPanel.add(dumpBrowseButton, constraintsLast); 458 459 setCommonPreferredSize(Arrays.asList(new JComponent[] { 463 printMappingCheckBox, 464 applyMappingCheckBox, 465 flattenPackageHierarchyCheckBox, 466 repackageClassesCheckBox, 467 newSourceFileAttributeCheckBox, 468 })); 469 470 JPanel optionsPanel = new JPanel(layout); 471 472 optionsPanel.add(preverificationOptionsPanel, panelConstraints); 473 optionsPanel.add(consistencyPanel, panelConstraints); 474 475 addBorder(whyAreYouKeepingPanel, "whyAreYouKeeping"); 476 optionsPanel.add(whyAreYouKeepingPanel, stretchPanelConstraints); 477 478 consoleTextArea.setOpaque(false); 480 consoleTextArea.setEditable(false); 481 consoleTextArea.setLineWrap(false); 482 consoleTextArea.setWrapStyleWord(false); 483 JScrollPane consoleScrollPane = new JScrollPane(consoleTextArea); 484 consoleScrollPane.setBorder(new EmptyBorder(1, 1, 1, 1)); 485 addBorder(consoleScrollPane, "processingConsole"); 486 487 JPanel processPanel = new JPanel(layout); 488 processPanel.add(consoleScrollPane, stretchPanelConstraints); 489 490 JButton loadButton = new JButton(msg("loadConfiguration")); 492 loadButton.addActionListener(new MyLoadConfigurationActionListener()); 493 494 JButton viewButton = new JButton(msg("viewConfiguration")); 495 viewButton.addActionListener(new MyViewConfigurationActionListener()); 496 497 JButton saveButton = new JButton(msg("saveConfiguration")); 498 saveButton.addActionListener(new MySaveConfigurationActionListener()); 499 500 JButton processButton = new JButton(msg("process")); 501 processButton.addActionListener(new MyProcessActionListener()); 502 503 JPanel reTraceSettingsPanel = new JPanel(layout); 505 addBorder(reTraceSettingsPanel, "reTraceSettings"); 506 507 JButton reTraceMappingBrowseButton = createBrowseButton(reTraceMappingTextField, 508 msg("selectApplyMappingFile")); 509 510 JLabel reTraceMappingLabel = new JLabel(msg("mappingFile")); 511 reTraceMappingLabel.setForeground(reTraceVerboseCheckBox.getForeground()); 512 513 reTraceSettingsPanel.add(reTraceVerboseCheckBox, constraintsLastStretch); 514 reTraceSettingsPanel.add(reTraceMappingLabel, constraints); 515 reTraceSettingsPanel.add(reTraceMappingTextField, constraintsStretch); 516 reTraceSettingsPanel.add(reTraceMappingBrowseButton, constraintsLast); 517 518 stackTraceTextArea.setOpaque(true); 519 stackTraceTextArea.setEditable(true); 520 stackTraceTextArea.setLineWrap(false); 521 stackTraceTextArea.setWrapStyleWord(true); 522 JScrollPane stackTraceScrollPane = new JScrollPane(stackTraceTextArea); 523 addBorder(stackTraceScrollPane, "obfuscatedStackTrace"); 524 525 reTraceTextArea.setOpaque(false); 526 reTraceTextArea.setEditable(false); 527 reTraceTextArea.setLineWrap(true); 528 reTraceTextArea.setWrapStyleWord(true); 529 JScrollPane reTraceScrollPane = new JScrollPane(reTraceTextArea); 530 reTraceScrollPane.setBorder(new EmptyBorder(1, 1, 1, 1)); 531 addBorder(reTraceScrollPane, "deobfuscatedStackTrace"); 532 533 JPanel reTracePanel = new JPanel(layout); 534 reTracePanel.add(reTraceSettingsPanel, panelConstraints); 535 reTracePanel.add(stackTraceScrollPane, panelConstraints); 536 reTracePanel.add(reTraceScrollPane, stretchPanelConstraints); 537 538 JButton loadStackTraceButton = new JButton(msg("loadStackTrace")); 540 loadStackTraceButton.addActionListener(new MyLoadStackTraceActionListener()); 541 542 JButton reTraceButton = new JButton(msg("reTrace")); 543 reTraceButton.addActionListener(new MyReTraceActionListener()); 544 545 TabbedPane tabs = new TabbedPane(); 547 tabs.add(msg("proGuardTab"), proGuardPanel); 548 tabs.add(msg("inputOutputTab"), inputOutputPanel); 549 tabs.add(msg("shrinkingTab"), shrinkingPanel); 550 tabs.add(msg("obfuscationTab"), obfuscationPanel); 551 tabs.add(msg("optimizationTab"), optimizationPanel); 552 tabs.add(msg("informationTab"), optionsPanel); 553 tabs.add(msg("processTab"), processPanel); 554 tabs.add(msg("reTraceTab"), reTracePanel); 555 tabs.addImage(Toolkit.getDefaultToolkit().getImage( 556 this.getClass().getResource(TITLE_IMAGE_FILE))); 557 558 proGuardPanel .add(Box.createGlue(), glueConstraints); 560 proGuardPanel .add(loadButton, bottomButtonConstraints); 561 proGuardPanel .add(createNextButton(tabs), lastBottomButtonConstraints); 562 563 inputOutputPanel .add(Box.createGlue(), glueConstraints); 564 inputOutputPanel .add(createPreviousButton(tabs), bottomButtonConstraints); 565 inputOutputPanel .add(createNextButton(tabs), lastBottomButtonConstraints); 566 567 shrinkingPanel .add(Box.createGlue(), glueConstraints); 568 shrinkingPanel .add(createPreviousButton(tabs), bottomButtonConstraints); 569 shrinkingPanel .add(createNextButton(tabs), lastBottomButtonConstraints); 570 571 obfuscationPanel .add(Box.createGlue(), glueConstraints); 572 obfuscationPanel .add(createPreviousButton(tabs), bottomButtonConstraints); 573 obfuscationPanel .add(createNextButton(tabs), lastBottomButtonConstraints); 574 575 optimizationPanel .add(Box.createGlue(), glueConstraints); 576 optimizationPanel .add(createPreviousButton(tabs), bottomButtonConstraints); 577 optimizationPanel .add(createNextButton(tabs), lastBottomButtonConstraints); 578 579 optionsPanel .add(Box.createGlue(), glueConstraints); 580 optionsPanel .add(createPreviousButton(tabs), bottomButtonConstraints); 581 optionsPanel .add(createNextButton(tabs), lastBottomButtonConstraints); 582 583 processPanel .add(Box.createGlue(), glueConstraints); 584 processPanel .add(createPreviousButton(tabs), bottomButtonConstraints); 585 processPanel .add(viewButton, bottomButtonConstraints); 586 processPanel .add(saveButton, bottomButtonConstraints); 587 processPanel .add(processButton, lastBottomButtonConstraints); 588 589 reTracePanel .add(Box.createGlue(), glueConstraints); 590 reTracePanel .add(loadStackTraceButton, bottomButtonConstraints); 591 reTracePanel .add(reTraceButton, lastBottomButtonConstraints); 592 593 loadConfiguration(this.getClass().getResource(DEFAULT_CONFIGURATION)); 595 596 getContentPane().add(tabs); 598 } 599 600 601 public void startSplash() 602 { 603 splashPanel.start(); 604 } 605 606 607 public void skipSplash() 608 { 609 splashPanel.stop(); 610 } 611 612 613 617 private void loadBoilerplateConfiguration() 618 { 619 try 620 { 621 ConfigurationParser parser = new ConfigurationParser( 623 this.getClass().getResource(BOILERPLATE_CONFIGURATION)); 624 Configuration configuration = new Configuration(); 625 626 try 627 { 628 parser.parse(configuration); 629 630 boilerplateKeep = 632 extractKeepSpecifications(configuration.keep, false, false); 633 634 boilerplateKeepNames = 636 extractKeepSpecifications(configuration.keep, true, false); 637 638 boilerplateNoSideEffectMethods = new ClassSpecification[configuration.assumeNoSideEffects.size()]; 640 configuration.assumeNoSideEffects.toArray(boilerplateNoSideEffectMethods); 641 } 642 finally 643 { 644 parser.close(); 645 } 646 } 647 catch (Exception ex) 648 { 649 ex.printStackTrace(); 650 } 651 } 652 653 654 658 private KeepSpecification[] extractKeepSpecifications(List keepSpecifications, 659 boolean allowShrinking, 660 boolean allowObfuscation) 661 { 662 List matches = new ArrayList(); 663 664 for (int index = 0; index < keepSpecifications.size(); index++) 665 { 666 KeepSpecification keepSpecification = (KeepSpecification)keepSpecifications.get(index); 667 if (keepSpecification.allowShrinking == allowShrinking && 668 keepSpecification.allowObfuscation == allowObfuscation) 669 { 670 matches.add(keepSpecification); 671 } 672 } 673 674 KeepSpecification[] matchingKeepSpecifications = new KeepSpecification[matches.size()]; 675 matches.toArray(matchingKeepSpecifications); 676 677 return matchingKeepSpecifications; 678 } 679 680 681 685 private ClassSpecification[] extractClassSpecifications(KeepSpecification[] keepSpecifications) 686 { 687 ClassSpecification[] classSpecifications = new ClassSpecification[keepSpecifications.length]; 688 689 for (int index = 0; index < classSpecifications.length; index++) 690 { 691 classSpecifications[index] = keepSpecifications[index]; 692 } 693 694 return classSpecifications; 695 } 696 697 698 701 private void addClassSpecifications(ClassSpecification[] boilerplateClassSpecifications, 702 JPanel classSpecificationsPanel, 703 JCheckBox[] boilerplateCheckBoxes, 704 JTextField[] boilerplateTextFields) 705 { 706 GridBagConstraints constraints = new GridBagConstraints(); 708 constraints.anchor = GridBagConstraints.WEST; 709 constraints.insets = new Insets(0, 4, 0, 4); 710 711 GridBagConstraints constraintsLastStretch = new GridBagConstraints(); 712 constraintsLastStretch.gridwidth = GridBagConstraints.REMAINDER; 713 constraintsLastStretch.fill = GridBagConstraints.HORIZONTAL; 714 constraintsLastStretch.weightx = 1.0; 715 constraintsLastStretch.anchor = GridBagConstraints.WEST; 716 constraintsLastStretch.insets = constraints.insets; 717 718 GridBagConstraints panelConstraints = new GridBagConstraints(); 719 panelConstraints.gridwidth = GridBagConstraints.REMAINDER; 720 panelConstraints.fill = GridBagConstraints.HORIZONTAL; 721 panelConstraints.weightx = 1.0; 722 panelConstraints.anchor = GridBagConstraints.NORTHWEST; 723 panelConstraints.insets = constraints.insets; 724 725 GridBagLayout layout = new GridBagLayout(); 726 727 String lastPanelName = null; 728 JPanel keepSubpanel = null; 729 for (int index = 0; index < boilerplateClassSpecifications.length; index++) 730 { 731 String comments = boilerplateClassSpecifications[index].comments; 733 int dashIndex = comments.indexOf('-'); 734 int periodIndex = comments.indexOf('.', dashIndex); 735 String panelName = comments.substring(0, dashIndex).trim(); 736 String optionName = comments.substring(dashIndex + 1, periodIndex).trim(); 737 if (!panelName.equals(lastPanelName)) 738 { 739 keepSubpanel = new JPanel(layout); 741 String titleKey = "boilerplate_" + panelName.toLowerCase().replace(' ', '_'); 742 addBorder(keepSubpanel, titleKey); 743 classSpecificationsPanel.add(keepSubpanel, panelConstraints); 744 745 lastPanelName = panelName; 746 } 747 748 String messageKey = "boilerplate_" + optionName.toLowerCase().replace(' ', '_'); 750 boilerplateCheckBoxes[index] = new JCheckBox(msg(messageKey)); 751 keepSubpanel.add(boilerplateCheckBoxes[index], 752 boilerplateTextFields != null ? 753 constraints : 754 constraintsLastStretch); 755 756 if (boilerplateTextFields != null) 757 { 758 boilerplateTextFields[index] = new JTextField(40); 760 keepSubpanel.add(boilerplateTextFields[index], constraintsLastStretch); 761 } 762 } 763 } 764 765 766 770 private void addBorder(JComponent component, String titleKey) 771 { 772 Border oldBorder = component.getBorder(); 773 Border newBorder = BorderFactory.createTitledBorder(BORDER, msg(titleKey)); 774 775 component.setBorder(oldBorder == null ? 776 newBorder : 777 new CompoundBorder(newBorder, oldBorder)); 778 } 779 780 781 784 private JButton createPreviousButton(final TabbedPane tabbedPane) 785 { 786 JButton browseButton = new JButton(msg("previous")); 787 browseButton.addActionListener(new ActionListener() 788 { 789 public void actionPerformed(ActionEvent e) 790 { 791 tabbedPane.previous(); 792 } 793 }); 794 795 return browseButton; 796 } 797 798 799 802 private JButton createNextButton(final TabbedPane tabbedPane) 803 { 804 JButton browseButton = new JButton(msg("next")); 805 browseButton.addActionListener(new ActionListener() 806 { 807 public void actionPerformed(ActionEvent e) 808 { 809 tabbedPane.next(); 810 } 811 }); 812 813 return browseButton; 814 } 815 816 817 820 private JButton createBrowseButton(final JTextField textField, 821 final String title) 822 { 823 JButton browseButton = new JButton(msg("browse")); 824 browseButton.addActionListener(new ActionListener() 825 { 826 public void actionPerformed(ActionEvent e) 827 { 828 fileChooser.setDialogTitle(title); 829 fileChooser.setSelectedFile(new File(textField.getText())); 830 831 int returnVal = fileChooser.showDialog(ProGuardGUI.this, msg("ok")); 832 if (returnVal == JFileChooser.APPROVE_OPTION) 833 { 834 textField.setText(fileChooser.getSelectedFile().getPath()); 835 } 836 } 837 }); 838 839 return browseButton; 840 } 841 842 843 847 private void setCommonPreferredSize(List components) 848 { 849 Dimension maximumSize = null; 851 for (int index = 0; index < components.size(); index++) 852 { 853 JComponent component = (JComponent)components.get(index); 854 Dimension size = component.getPreferredSize(); 855 if (maximumSize == null || 856 size.getWidth() > maximumSize.getWidth()) 857 { 858 maximumSize = size; 859 } 860 } 861 862 for (int index = 0; index < components.size(); index++) 864 { 865 JComponent component = (JComponent)components.get(index); 866 component.setPreferredSize(maximumSize); 867 } 868 } 869 870 871 874 private void setProGuardConfiguration(Configuration configuration) 875 { 876 programPanel.setClassPath(configuration.programJars); 878 libraryPanel.setClassPath(configuration.libraryJars); 879 880 for (int index = 0; index < boilerplateKeep.length; index++) 882 { 883 String classNames = 884 findMatchingKeepSpecifications(boilerplateKeep[index], 885 configuration.keep); 886 887 boilerplateKeepCheckBoxes[index].setSelected(classNames != null); 888 boilerplateKeepTextFields[index].setText(classNames == null ? "*" : classNames); 889 } 890 891 892 for (int index = 0; index < boilerplateKeepNames.length; index++) 894 { 895 String classNames = 896 findMatchingKeepSpecifications(boilerplateKeepNames[index], 897 configuration.keep); 898 899 boilerplateKeepNamesCheckBoxes[index].setSelected(classNames != null); 900 boilerplateKeepNamesTextFields[index].setText(classNames == null ? "*" : classNames); 901 } 902 903 additionalKeepPanel.setClassSpecifications(filteredKeepSpecifications(configuration.keep, 906 false)); 907 908 additionalKeepNamesPanel.setClassSpecifications(filteredKeepSpecifications(configuration.keep, 911 true)); 912 913 914 for (int index = 0; index < boilerplateNoSideEffectMethods.length; index++) 916 { 917 boolean found = 918 findClassSpecification(boilerplateNoSideEffectMethods[index], 919 configuration.assumeNoSideEffects); 920 921 boilerplateNoSideEffectMethodCheckBoxes[index].setSelected(found); 922 } 923 924 additionalNoSideEffectsPanel.setClassSpecifications(configuration.assumeNoSideEffects); 927 928 whyAreYouKeepingPanel.setClassSpecifications(configuration.whyAreYouKeeping); 930 931 shrinkCheckBox .setSelected(configuration.shrink); 933 printUsageCheckBox .setSelected(configuration.printUsage != null); 934 935 optimizeCheckBox .setSelected(configuration.optimize); 936 optimizationPassesSpinner.getModel() .setValue(new Integer (configuration.optimizationPasses)); 937 allowAccessModificationCheckBox .setSelected(configuration.allowAccessModification); 938 939 obfuscateCheckBox .setSelected(configuration.obfuscate); 940 printMappingCheckBox .setSelected(configuration.printMapping != null); 941 applyMappingCheckBox .setSelected(configuration.applyMapping != null); 942 obfuscationDictionaryCheckBox .setSelected(configuration.obfuscationDictionary != null); 943 overloadAggressivelyCheckBox .setSelected(configuration.overloadAggressively); 944 useUniqueClassMemberNamesCheckBox .setSelected(configuration.useUniqueClassMemberNames); 945 useMixedCaseClassNamesCheckBox .setSelected(configuration.useMixedCaseClassNames); 946 flattenPackageHierarchyCheckBox .setSelected(configuration.flattenPackageHierarchy != null); 947 repackageClassesCheckBox .setSelected(configuration.repackageClasses != null); 948 keepAttributesCheckBox .setSelected(configuration.keepAttributes != null); 949 newSourceFileAttributeCheckBox .setSelected(configuration.newSourceFileAttribute != null); 950 adaptResourceFileNamesCheckBox .setSelected(configuration.adaptResourceFileNames != null); 951 adaptResourceFileContentsCheckBox .setSelected(configuration.adaptResourceFileContents != null); 952 953 preverifyCheckBox .setSelected(configuration.preverify); 954 microEditionCheckBox .setSelected(configuration.microEdition); 955 targetCheckBox .setSelected(configuration.targetClassVersion != 0); 956 957 verboseCheckBox .setSelected(configuration.verbose); 958 noteCheckBox .setSelected(configuration.note); 959 warnCheckBox .setSelected(configuration.warn); 960 ignoreWarningsCheckBox .setSelected(configuration.ignoreWarnings); 961 skipNonPublicLibraryClassesCheckBox .setSelected(configuration.skipNonPublicLibraryClasses); 962 skipNonPublicLibraryClassMembersCheckBox.setSelected(configuration.skipNonPublicLibraryClassMembers); 963 forceProcessingCheckBox .setSelected(configuration.lastModified == Long.MAX_VALUE); 964 printSeedsCheckBox .setSelected(configuration.printSeeds != null); 965 printConfigurationCheckBox .setSelected(configuration.printConfiguration != null); 966 dumpCheckBox .setSelected(configuration.dump != null); 967 968 printUsageTextField .setText(fileName(configuration.printUsage)); 969 printMappingTextField .setText(fileName(configuration.printMapping)); 970 applyMappingTextField .setText(fileName(configuration.applyMapping)); 971 obfuscationDictionaryTextField .setText(fileName(configuration.obfuscationDictionary)); 972 flattenPackageHierarchyTextField .setText(configuration.flattenPackageHierarchy); 973 repackageClassesTextField .setText(configuration.repackageClasses); 974 keepAttributesTextField .setText(configuration.keepAttributes == null ? KEEP_ATTRIBUTE_DEFAULT : ListUtil.commaSeparatedString(configuration.keepAttributes)); 975 newSourceFileAttributeTextField .setText(configuration.newSourceFileAttribute == null ? SOURCE_FILE_ATTRIBUTE_DEFAULT : configuration.newSourceFileAttribute); 976 adaptResourceFileNamesTextField .setText(configuration.adaptResourceFileNames == null ? ADAPT_RESOURCE_FILE_NAMES_DEFAULT : ListUtil.commaSeparatedString(configuration.adaptResourceFileNames)); 977 adaptResourceFileContentsTextField .setText(configuration.adaptResourceFileContents == null ? ADAPT_RESOURCE_FILE_CONTENTS_DEFAULT : ListUtil.commaSeparatedString(configuration.adaptResourceFileContents)); 978 printSeedsTextField .setText(fileName(configuration.printSeeds)); 979 printConfigurationTextField .setText(fileName(configuration.printConfiguration)); 980 dumpTextField .setText(fileName(configuration.dump)); 981 982 if (configuration.targetClassVersion != 0) 983 { 984 targetComboBox.setSelectedItem(ClassUtil.externalClassVersion(configuration.targetClassVersion)); 985 } 986 else 987 { 988 targetComboBox.setSelectedIndex(targetComboBox.getItemCount() - 1); 989 } 990 991 if (configuration.printMapping != null) 992 { 993 reTraceMappingTextField.setText(fileName(configuration.printMapping)); 994 } 995 } 996 997 998 1001 private Configuration getProGuardConfiguration() 1002 { 1003 Configuration configuration = new Configuration(); 1004 1005 configuration.programJars = programPanel.getClassPath(); 1007 configuration.libraryJars = libraryPanel.getClassPath(); 1008 1009 List keep = new ArrayList(); 1010 1011 List additionalKeep = additionalKeepPanel.getClassSpecifications(); 1013 if (additionalKeep != null) 1014 { 1015 keep.addAll(additionalKeep); 1016 } 1017 1018 List additionalKeepNames = additionalKeepNamesPanel.getClassSpecifications(); 1020 if (additionalKeepNames != null) 1021 { 1022 keep.addAll(additionalKeepNames); 1023 } 1024 1025 for (int index = 0; index < boilerplateKeep.length; index++) 1027 { 1028 if (boilerplateKeepCheckBoxes[index].isSelected()) 1029 { 1030 keep.add(classSpecification(boilerplateKeep[index], 1031 boilerplateKeepTextFields[index].getText())); 1032 } 1033 } 1034 1035 for (int index = 0; index < boilerplateKeepNames.length; index++) 1037 { 1038 if (boilerplateKeepNamesCheckBoxes[index].isSelected()) 1039 { 1040 keep.add(classSpecification(boilerplateKeepNames[index], 1041 boilerplateKeepNamesTextFields[index].getText())); 1042 } 1043 } 1044 1045 if (keep.size() > 0) 1047 { 1048 configuration.keep = keep; 1049 } 1050 1051 1052 List noSideEffectMethods = new ArrayList(); 1054 1055 for (int index = 0; index < boilerplateNoSideEffectMethods.length; index++) 1056 { 1057 if (boilerplateNoSideEffectMethodCheckBoxes[index].isSelected()) 1058 { 1059 noSideEffectMethods.add(boilerplateNoSideEffectMethods[index]); 1060 } 1061 } 1062 1063 List additionalNoSideEffectOptions = additionalNoSideEffectsPanel.getClassSpecifications(); 1065 if (additionalNoSideEffectOptions != null) 1066 { 1067 noSideEffectMethods.addAll(additionalNoSideEffectOptions); 1068 } 1069 1070 if (noSideEffectMethods.size() > 0) 1072 { 1073 configuration.assumeNoSideEffects = noSideEffectMethods; 1074 } 1075 1076 1077 configuration.whyAreYouKeeping = whyAreYouKeepingPanel.getClassSpecifications(); 1079 1080 1081 configuration.shrink = shrinkCheckBox .isSelected(); 1083 configuration.printUsage = printUsageCheckBox .isSelected() ? new File(printUsageTextField .getText()) : null; 1084 1085 configuration.optimize = optimizeCheckBox .isSelected(); 1086 configuration.optimizationPasses = ((SpinnerNumberModel)optimizationPassesSpinner.getModel()).getNumber().intValue(); 1087 configuration.allowAccessModification = allowAccessModificationCheckBox .isSelected(); 1088 1089 configuration.obfuscate = obfuscateCheckBox .isSelected(); 1090 configuration.printMapping = printMappingCheckBox .isSelected() ? new File(printMappingTextField .getText()) : null; 1091 configuration.applyMapping = applyMappingCheckBox .isSelected() ? new File(applyMappingTextField .getText()) : null; 1092 configuration.obfuscationDictionary = obfuscationDictionaryCheckBox .isSelected() ? new File(obfuscationDictionaryTextField .getText()) : null; 1093 configuration.overloadAggressively = overloadAggressivelyCheckBox .isSelected(); 1094 configuration.useUniqueClassMemberNames = useUniqueClassMemberNamesCheckBox .isSelected(); 1095 configuration.useMixedCaseClassNames = useMixedCaseClassNamesCheckBox .isSelected(); 1096 configuration.flattenPackageHierarchy = flattenPackageHierarchyCheckBox .isSelected() ? ClassUtil.externalClassName(flattenPackageHierarchyTextField .getText()) : null; 1097 configuration.repackageClasses = repackageClassesCheckBox .isSelected() ? ClassUtil.externalClassName(repackageClassesTextField .getText()) : null; 1098 configuration.keepAttributes = keepAttributesCheckBox .isSelected() ? ListUtil.commaSeparatedList(keepAttributesTextField .getText()) : null; 1099 configuration.newSourceFileAttribute = newSourceFileAttributeCheckBox .isSelected() ? newSourceFileAttributeTextField .getText() : null; 1100 configuration.adaptResourceFileNames = adaptResourceFileNamesCheckBox .isSelected() ? ListUtil.commaSeparatedList(adaptResourceFileNamesTextField .getText()) : null; 1101 configuration.adaptResourceFileContents = adaptResourceFileContentsCheckBox .isSelected() ? ListUtil.commaSeparatedList(adaptResourceFileContentsTextField.getText()) : null; 1102 1103 configuration.preverify = preverifyCheckBox .isSelected(); 1104 configuration.microEdition = microEditionCheckBox .isSelected(); 1105 configuration.targetClassVersion = targetCheckBox .isSelected() ? ClassUtil.internalClassVersion(targetComboBox.getSelectedItem().toString()) : 0; 1106 1107 configuration.verbose = verboseCheckBox .isSelected(); 1108 configuration.note = noteCheckBox .isSelected(); 1109 configuration.warn = warnCheckBox .isSelected(); 1110 configuration.ignoreWarnings = ignoreWarningsCheckBox .isSelected(); 1111 configuration.skipNonPublicLibraryClasses = skipNonPublicLibraryClassesCheckBox .isSelected(); 1112 configuration.skipNonPublicLibraryClassMembers = skipNonPublicLibraryClassMembersCheckBox.isSelected(); 1113 configuration.lastModified = forceProcessingCheckBox .isSelected() ? Long.MAX_VALUE : System.currentTimeMillis(); 1114 configuration.printSeeds = printSeedsCheckBox .isSelected() ? new File(printSeedsTextField .getText()) : null; 1115 configuration.printConfiguration = printConfigurationCheckBox .isSelected() ? new File(printConfigurationTextField .getText()) : null; 1116 configuration.dump = dumpCheckBox .isSelected() ? new File(dumpTextField .getText()) : null; 1117 1118 return configuration; 1119 } 1120 1121 1122 1127 private boolean findClassSpecification(ClassSpecification classSpecificationTemplate, 1128 List classSpecifications) 1129 { 1130 if (classSpecifications == null) 1131 { 1132 return false; 1133 } 1134 1135 for (int index = 0; index < classSpecifications.size(); index++) 1136 { 1137 if (classSpecificationTemplate.equals(classSpecifications.get(index))) 1138 { 1139 classSpecifications.remove(index); 1141 1142 return true; 1143 } 1144 } 1145 1146 return false; 1147 } 1148 1149 1150 1154 private List filteredKeepSpecifications(List keepSpecifications, 1155 boolean allowShrinking) 1156 { 1157 List filteredKeepSpecifications = new ArrayList(); 1158 1159 for (int index = 0; index < keepSpecifications.size(); index++) 1160 { 1161 KeepSpecification keepSpecification = 1162 (KeepSpecification)keepSpecifications.get(index); 1163 1164 if (keepSpecification.allowShrinking == allowShrinking) 1165 { 1166 filteredKeepSpecifications.add(keepSpecification); 1167 } 1168 } 1169 1170 return filteredKeepSpecifications; 1171 } 1172 1173 1174 1180 private String findMatchingKeepSpecifications(KeepSpecification keepSpecificationTemplate, 1181 List keepSpecifications) 1182 { 1183 if (keepSpecifications == null) 1184 { 1185 return null; 1186 } 1187 1188 StringBuffer buffer = null; 1189 1190 for (int index = 0; index < keepSpecifications.size(); index++) 1191 { 1192 KeepSpecification listedKeepSpecification = 1193 (KeepSpecification)keepSpecifications.get(index); 1194 String className = listedKeepSpecification.className; 1195 keepSpecificationTemplate.className = className; 1196 if (keepSpecificationTemplate.equals(listedKeepSpecification)) 1197 { 1198 if (buffer == null) 1199 { 1200 buffer = new StringBuffer (); 1201 } 1202 else 1203 { 1204 buffer.append(','); 1205 } 1206 buffer.append(className == null ? "*" : ClassUtil.externalClassName(className)); 1207 1208 keepSpecifications.remove(index--); 1210 } 1211 } 1212 1213 return buffer == null ? null : buffer.toString(); 1214 } 1215 1216 1217 1221 private ClassSpecification classSpecification(ClassSpecification classSpecificationTemplate, 1222 String className) 1223 { 1224 ClassSpecification classSpecification = 1226 (ClassSpecification)classSpecificationTemplate.clone(); 1227 1228 classSpecification.className = 1230 className.equals("") || 1231 className.equals("*") ? 1232 null : 1233 ClassUtil.internalClassName(className); 1234 1235 return classSpecification; 1237 } 1238 1239 1240 1242 1245 private void loadConfiguration(File file) 1246 { 1247 configurationChooser.setSelectedFile(file.getAbsoluteFile()); 1249 fileChooser.setCurrentDirectory(file.getAbsoluteFile().getParentFile()); 1250 1251 try 1252 { 1253 ConfigurationParser parser = new ConfigurationParser(file); 1255 Configuration configuration = new Configuration(); 1256 1257 try 1258 { 1259 parser.parse(configuration); 1260 1261 setProGuardConfiguration(configuration); 1263 } 1264 catch (ParseException ex) 1265 { 1266 JOptionPane.showMessageDialog(getContentPane(), 1267 msg("cantParseConfigurationFile", file.getPath()), 1268 msg("warning"), 1269 JOptionPane.ERROR_MESSAGE); 1270 } 1271 finally 1272 { 1273 parser.close(); 1274 } 1275 } 1276 catch (IOException ex) 1277 { 1278 JOptionPane.showMessageDialog(getContentPane(), 1279 msg("cantOpenConfigurationFile", file.getPath()), 1280 msg("warning"), 1281 JOptionPane.ERROR_MESSAGE); 1282 } 1283 } 1284 1285 1286 1289 private void loadConfiguration(URL url) 1290 { 1291 try 1292 { 1293 ConfigurationParser parser = new ConfigurationParser(url); 1295 Configuration configuration = new Configuration(); 1296 1297 try 1298 { 1299 parser.parse(configuration); 1300 1301 setProGuardConfiguration(configuration); 1303 } 1304 catch (ParseException ex) 1305 { 1306 JOptionPane.showMessageDialog(getContentPane(), 1307 msg("cantParseConfigurationFile", url), 1308 msg("warning"), 1309 JOptionPane.ERROR_MESSAGE); 1310 } 1311 finally 1312 { 1313 parser.close(); 1314 } 1315 } 1316 catch (IOException ex) 1317 { 1318 JOptionPane.showMessageDialog(getContentPane(), 1319 msg("cantOpenConfigurationFile", url), 1320 msg("warning"), 1321 JOptionPane.ERROR_MESSAGE); 1322 } 1323 } 1324 1325 1326 1329 private void saveConfiguration(File file) 1330 { 1331 try 1332 { 1333 ConfigurationWriter writer = new ConfigurationWriter(file); 1335 writer.write(getProGuardConfiguration()); 1336 writer.close(); 1337 } 1338 catch (Exception ex) 1339 { 1340 JOptionPane.showMessageDialog(getContentPane(), 1341 msg("cantSaveConfigurationFile", file.getPath()), 1342 msg("warning"), 1343 JOptionPane.ERROR_MESSAGE); 1344 } 1345 } 1346 1347 1348 1351 private void loadStackTrace(String fileName) 1352 { 1353 try 1354 { 1355 File file = new File(fileName); 1357 byte[] buffer = new byte[(int)file.length()]; 1358 InputStream inputStream = new FileInputStream(file); 1359 inputStream.read(buffer); 1360 inputStream.close(); 1361 1362 stackTraceTextArea.setText(new String (buffer)); 1364 } 1365 catch (IOException ex) 1366 { 1367 JOptionPane.showMessageDialog(getContentPane(), 1368 msg("cantOpenStackTraceFile", fileName), 1369 msg("warning"), 1370 JOptionPane.ERROR_MESSAGE); 1371 } 1372 } 1373 1374 1375 1379 private class MyLoadConfigurationActionListener implements ActionListener 1380 { 1381 public void actionPerformed(ActionEvent e) 1382 { 1383 configurationChooser.setDialogTitle(msg("selectConfigurationFile")); 1384 1385 int returnValue = configurationChooser.showOpenDialog(ProGuardGUI.this); 1386 if (returnValue == JFileChooser.APPROVE_OPTION) 1387 { 1388 loadConfiguration(configurationChooser.getSelectedFile()); 1389 } 1390 } 1391 } 1392 1393 1394 1398 private class MySaveConfigurationActionListener implements ActionListener 1399 { 1400 public void actionPerformed(ActionEvent e) 1401 { 1402 configurationChooser.setDialogTitle(msg("saveConfigurationFile")); 1403 1404 int returnVal = configurationChooser.showSaveDialog(ProGuardGUI.this); 1405 if (returnVal == JFileChooser.APPROVE_OPTION) 1406 { 1407 saveConfiguration(configurationChooser.getSelectedFile()); 1408 } 1409 } 1410 } 1411 1412 1413 1417 private class MyViewConfigurationActionListener implements ActionListener 1418 { 1419 public void actionPerformed(ActionEvent e) 1420 { 1421 if (!systemOutRedirected) 1423 { 1424 consoleTextArea.setText(""); 1425 1426 TextAreaOutputStream outputStream = 1427 new TextAreaOutputStream(consoleTextArea); 1428 1429 try 1430 { 1431 1433 ConfigurationWriter writer = new ConfigurationWriter(outputStream); 1435 writer.write(getProGuardConfiguration()); 1436 writer.close(); 1437 } 1438 catch (IOException ex) 1439 { 1440 } 1441 1442 consoleTextArea.setCaretPosition(0); 1444 } 1445 } 1446 } 1447 1448 1449 1452 private class MyProcessActionListener implements ActionListener 1453 { 1454 public void actionPerformed(ActionEvent e) 1455 { 1456 if (!systemOutRedirected) 1458 { 1459 systemOutRedirected = true; 1460 1461 File configurationFile = configurationChooser.getSelectedFile(); 1463 String configurationFileName = configurationFile != null ? 1464 configurationFile.getName() : 1465 msg("sampleConfigurationFileName"); 1466 1467 Thread proGuardThread = 1469 new Thread (new ProGuardRunnable(consoleTextArea, 1470 getProGuardConfiguration(), 1471 configurationFileName)); 1472 1473 proGuardThread.start(); 1475 } 1476 } 1477 } 1478 1479 1480 1484 private class MyLoadStackTraceActionListener implements ActionListener 1485 { 1486 public void actionPerformed(ActionEvent e) 1487 { 1488 fileChooser.setDialogTitle(msg("selectStackTraceFile")); 1489 fileChooser.setSelectedFile(null); 1490 1491 int returnValue = fileChooser.showOpenDialog(ProGuardGUI.this); 1492 if (returnValue == JFileChooser.APPROVE_OPTION) 1493 { 1494 File selectedFile = fileChooser.getSelectedFile(); 1495 String fileName = selectedFile.getPath(); 1496 1497 loadStackTrace(fileName); 1498 } 1499 } 1500 } 1501 1502 1503 1506 private class MyReTraceActionListener implements ActionListener 1507 { 1508 public void actionPerformed(ActionEvent e) 1509 { 1510 if (!systemOutRedirected) 1512 { 1513 systemOutRedirected = true; 1514 1515 boolean verbose = reTraceVerboseCheckBox.isSelected(); 1516 File retraceMappingFile = new File(reTraceMappingTextField.getText()); 1517 String stackTrace = stackTraceTextArea.getText(); 1518 1519 Runnable reTraceRunnable = new ReTraceRunnable(reTraceTextArea, 1521 verbose, 1522 retraceMappingFile, 1523 stackTrace); 1524 1525 reTraceRunnable.run(); 1527 } 1528 } 1529 } 1530 1531 1532 1534 1537 private String fileName(File file) 1538 { 1539 return file == null ? "" : file.getAbsolutePath(); 1540 } 1541 1542 1546 private String msg(String messageKey) 1547 { 1548 return GUIResources.getMessage(messageKey); 1549 } 1550 1551 1552 1556 private String msg(String messageKey, 1557 Object messageArgument) 1558 { 1559 return GUIResources.getMessage(messageKey, new Object [] {messageArgument}); 1560 } 1561 1562 1563 1566 public static void main(final String [] args) 1567 { 1568 { 1572 ProGuardGUI gui = new ProGuardGUI(); 1573 gui.pack(); 1574 1575 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); 1576 Dimension guiSize = gui.getSize(); 1577 gui.setLocation((screenSize.width - guiSize.width) / 2, 1578 (screenSize.height - guiSize.height) / 2); 1579 gui.show(); 1580 1581 int argIndex = 0; 1583 if (argIndex < args.length && 1584 NO_SPLASH_OPTION.startsWith(args[argIndex])) 1585 { 1586 gui.skipSplash(); 1587 argIndex++; 1588 } 1589 else 1590 { 1591 gui.startSplash(); 1592 } 1593 1594 if (argIndex < args.length) 1596 { 1597 gui.loadConfiguration(new File(args[argIndex])); 1598 argIndex++; 1599 } 1600 1601 if (argIndex < args.length) 1602 { 1603 System.out.println(gui.getClass().getName() + ": ignoring extra arguments [" + args[argIndex] + "...]"); 1604 } 1605 1606 } 1607 } 1609} 1610 | Popular Tags |