1 package edu.jiangxin.apktoolbox.reverse;
2
3 import edu.jiangxin.apktoolbox.swing.extend.listener.SelectDirectoryListener;
4 import edu.jiangxin.apktoolbox.swing.extend.plugin.PluginPanel;
5 import edu.jiangxin.apktoolbox.utils.Constants;
6 import edu.jiangxin.apktoolbox.utils.ProcessLogOutputStream;
7 import org.apache.commons.exec.CommandLine;
8 import org.apache.commons.exec.DefaultExecutor;
9 import org.apache.commons.exec.PumpStreamHandler;
10 import org.apache.commons.io.IOUtils;
11 import org.apache.logging.log4j.Level;
12
13 import javax.swing.*;
14 import java.awt.*;
15 import java.awt.event.ActionEvent;
16 import java.awt.event.ActionListener;
17 import java.io.*;
18 import java.util.Enumeration;
19 import java.util.zip.ZipEntry;
20 import java.util.zip.ZipFile;
21
22
23
24
25
26
27 public class AxmlPrinterPanel extends PluginPanel {
28 private static final long serialVersionUID = 1L;
29
30 private JTextField srcTextField;
31
32 private JTextField targetTextField;
33
34 public AxmlPrinterPanel() throws HeadlessException {
35 super();
36 }
37
38 @Override
39 public String getPluginFilename() {
40 return "AXMLPrinter3.jar";
41 }
42
43 @Override
44 public void initUI() {
45 BoxLayout boxLayout = new BoxLayout(this, BoxLayout.Y_AXIS);
46 setLayout(boxLayout);
47
48 createSrcPanel();
49 add(Box.createVerticalStrut(Constants.DEFAULT_Y_BORDER));
50
51 createTargetPanel();
52 add(Box.createVerticalStrut(Constants.DEFAULT_Y_BORDER));
53
54 createOperationPanel();
55 }
56
57 private void createOperationPanel() {
58 JPanel operationPanel = new JPanel();
59 operationPanel.setLayout(new BoxLayout(operationPanel, BoxLayout.X_AXIS));
60 add(operationPanel);
61
62 JButton getFileButton = new JButton("Get File");
63 getFileButton.addActionListener(new GetFileButtonActionListener());
64
65 operationPanel.add(getFileButton);
66 }
67
68 private void createTargetPanel() {
69 JPanel targetPanel = new JPanel();
70 targetPanel.setLayout(new BoxLayout(targetPanel, BoxLayout.X_AXIS));
71 add(targetPanel);
72
73 targetTextField = new JTextField();
74 targetTextField.setText(conf.getString("axmlprinter.target.dir"));
75
76 JButton targetButton = new JButton("Save Dir");
77 targetButton.addActionListener(new SelectDirectoryListener("Save To", targetTextField));
78
79 targetPanel.add(targetTextField);
80 targetPanel.add(Box.createHorizontalStrut(Constants.DEFAULT_X_BORDER));
81 targetPanel.add(targetButton);
82 }
83
84 private void createSrcPanel() {
85 JPanel srcPanel = new JPanel();
86 srcPanel.setLayout(new BoxLayout(srcPanel, BoxLayout.X_AXIS));
87 add(srcPanel);
88
89 srcTextField = new JTextField();
90 srcTextField.setText(conf.getString("axmlprinter.src.file"));
91
92 JButton srcButton = new JButton("Source File");
93 srcButton.addActionListener(new SrcButtonActionListener());
94
95 srcPanel.add(srcTextField);
96 srcPanel.add(Box.createHorizontalStrut(Constants.DEFAULT_X_BORDER));
97 srcPanel.add(srcButton);
98 }
99
100 private final class SrcButtonActionListener implements ActionListener {
101 @Override
102 public void actionPerformed(ActionEvent e) {
103 JFileChooser jfc = new JFileChooser();
104 jfc.setFileSelectionMode(JFileChooser.FILES_ONLY);
105 jfc.setDialogTitle("select a file");
106 int ret = jfc.showDialog(new JLabel(), null);
107 switch (ret) {
108 case JFileChooser.APPROVE_OPTION:
109 File file = jfc.getSelectedFile();
110 srcTextField.setText(file.getAbsolutePath());
111 break;
112 default:
113 break;
114 }
115
116 }
117 }
118
119 private final class GetFileButtonActionListener implements ActionListener {
120 @Override
121 public void actionPerformed(ActionEvent e) {
122 String srcPath = checkAndGetFileContent(srcTextField, "axmlprinter.src.file", "Source file is invalid");
123 if (srcPath == null) {
124 return;
125 }
126
127 String targetPath = checkAndGetDirContent(targetTextField, "axmlprinter.target.dir", "Target dir is invalid");
128 if (targetPath == null) {
129 return;
130 }
131
132 try (ZipFile zip = new ZipFile(srcPath)) {
133 Enumeration<?> entries = zip.entries();
134 while (entries.hasMoreElements()) {
135 ZipEntry entry = (ZipEntry) entries.nextElement();
136 if ("AndroidManifest.xml".equals(entry.getName())) {
137 try (InputStream inputStream = zip.getInputStream(entry);
138 OutputStream outputSteam = new FileOutputStream(new File(targetPath, "AndroidManifest.xml.orig"))) {
139 IOUtils.copy(inputStream,outputSteam);
140 } catch (IOException e2) {
141 logger.error("axmlprinter fail", e2);
142 }
143 break;
144 }
145 }
146
147 StringBuilder sb = new StringBuilder();
148 sb.append(getPluginStartupCmd()).append(" ").append(new File(targetPath, "AndroidManifest.xml.orig").getCanonicalPath());
149 String cmd = sb.toString();
150 logger.info(cmd);
151 File outputFile = new File(new File(targetPath), "AndroidManifest.xml");
152 try (FileOutputStream outStream = new FileOutputStream(outputFile);
153 ProcessLogOutputStream errStream = new ProcessLogOutputStream(logger, Level.ERROR)
154 ) {
155 CommandLine commandLine = CommandLine.parse(cmd);
156 DefaultExecutor exec = new DefaultExecutor();
157 PumpStreamHandler streamHandler = new PumpStreamHandler(outStream, errStream);
158 exec.setStreamHandler(streamHandler);
159 int exitValue = exec.execute(commandLine);
160 logger.info("exitValue: [" + exitValue + "]");
161 }
162 } catch (IOException e1) {
163 logger.error("axmlprinter fail", e1);
164 }
165 }
166 }
167 }