com.yeliu.Main.java Source code

Java tutorial

Introduction

Here is the source code for com.yeliu.Main.java

Source

package com.yeliu;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener;
import java.awt.event.FocusAdapter;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import javax.swing.ComboBoxModel;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.border.BevelBorder;
import javax.swing.border.SoftBevelBorder;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;

import com.keystore.util.KeystoreUtil;
import com.keystore.util.SignParams;
import com.sinaapp.msdxblog.apkUtil.entity.ApkInfo;
import com.sinaapp.msdxblog.apkUtil.utils.ApkUtil;
import com.sinaapp.msdxblog.apkUtil.utils.XmlUtil;
import com.view.ConfigViewHolder;
import com.view.MetaSelectDialog;
import com.view.MetaSelectDialog.OnSelectCallback;
import com.view.VFlowLayout;

/**
 * This code was edited or generated using CloudGarden's Jigloo SWT/Swing GUI Builder, which is free for non-commercial
 * use. If Jigloo is being used commercially (ie, by a corporation, company or business for any purpose whatever) then
 * you should purchase a license for each developer using Jigloo. Please visit www.cloudgarden.com for details. Use of
 * Jigloo implies acceptance of these licensing terms. A COMMERCIAL LICENSE HAS NOT BEEN PURCHASED FOR THIS MACHINE, SO
 * JIGLOO OR THIS CODE CANNOT BE USED LEGALLY FOR ANY CORPORATE OR COMMERCIAL PURPOSE.
 */
public class Main extends javax.swing.JFrame {
    private static final long serialVersionUID = 6341520019159072965L;

    private JPanel jPanelContent;

    // =====apk =====

    private JPanel jPanelApkSelect = new JPanel(new FlowLayout(FlowLayout.LEFT));
    private JLabel jLabelApkSelect;
    private JTextField jTextFieldApkSelect;
    private JButton jButtonApkSelect;
    private JButton jButtonMetaRefresh;

    // =====JDK===
    private JPanel jPanelJdk = new JPanel(new FlowLayout(FlowLayout.LEFT));
    private JComboBox jComboBoxJdk;
    // =====?=====
    private JPanel jPanelAddChannel = new JPanel(new FlowLayout(FlowLayout.LEFT));
    private JButton jButtonAddChannel;// ??

    //=== =======
    private JPanel jPanelOut = new JPanel(new FlowLayout(FlowLayout.LEFT));
    private JButton jButtonOutClear;
    private JTextField jTextFieldOut;
    private JButton jButtonOut;
    private JLabel jLabelOut;

    // =====??====
    private JPanel jPanelSign = new JPanel(new VFlowLayout());
    private JPanel jPanelKeyStore = new JPanel(new FlowLayout(FlowLayout.LEFT));
    private JCheckBox jCheckBoxSign;
    private JButton jButtonSign;
    private JTextField jTextFieldSignFile;
    private JPanel jPanelKeyStorePwd = new JPanel(new FlowLayout(FlowLayout.LEFT));
    private JTextField jTextFieldSignPwd;
    private JPanel jPanelAlias = new JPanel(new FlowLayout(FlowLayout.LEFT));
    private JComboBox jComboBoxAlias;//??
    private JPanel jPanelAliasPwd = new JPanel(new FlowLayout(FlowLayout.LEFT));
    private JTextField jTextFieldAliaPwd;//???

    //========
    private JPanel jPanelStart = new JPanel(new FlowLayout(FlowLayout.CENTER));
    private JButton jButtonStart;

    private static final String BAT = "start.bat";
    private static final String CONFIG_FILE = "/config.txt";

    private String rootDirPath = null;
    private String processDirPath = null; // ???
    String batPath; // bat
    String oriApkPath; // apk
    String keystoreFilePath; // ??
    String apkName; // apk????
    String rootDir; // 
    String outputDir; // apk
    String versionName;
    String packageName;
    String keystorePasswd;
    String apktoolPath;

    private Document xmlDoc;

    private String decompile_add;
    private String compile_add;
    private String sign_add;

    private List<ConfigViewHolder> configViews = new ArrayList<ConfigViewHolder>(); // ??

    private Map<String, Element> metaDataMap = new HashMap<String, Element>(); //metaData

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                Main inst = new Main();
                inst.setLocationRelativeTo(null);
                inst.setVisible(true);
            }
        });
    }

    public Main() {
        super();
        initGUI();
    }

    /**
     * ?UI
     */
    private void initGUI() {
        try {
            setTitle("??&??");
            jPanelContent = new JPanel(new VFlowLayout());
            JScrollPane jScrollPane = new JScrollPane();
            jScrollPane.setViewportView(jPanelContent);
            setContentPane(jScrollPane);
            // ========== JDK======
            {
                JLabel jLabelJdk = new JLabel();
                jLabelJdk.setText("JDK");
                jPanelJdk.add(jLabelJdk);
                ComboBoxModel jComboBox1Model = new DefaultComboBoxModel(new String[] { "1.7+", "1.6" });
                jComboBoxJdk = new JComboBox();
                jComboBoxJdk.setModel(jComboBox1Model);
                jPanelJdk.add(jComboBoxJdk);
                jPanelContent.add(jPanelJdk);
            }
            // ========== ??APK======
            {
                jLabelApkSelect = new JLabel();
                jPanelContent.add(jLabelApkSelect);
                jLabelApkSelect.setText("APKapk???");
                jLabelApkSelect.setForeground(Color.red);
            }
            {

                jTextFieldApkSelect = new JTextField();
                jButtonApkSelect = new JButton("?");
                jButtonMetaRefresh = new JButton("");
                jPanelContent.add(jPanelApkSelect);
                jPanelApkSelect.add(jTextFieldApkSelect);
                jPanelApkSelect.add(jButtonApkSelect);
                jPanelApkSelect.add(jButtonMetaRefresh);

                jTextFieldApkSelect.setPreferredSize(new Dimension(450, 30));
                jTextFieldApkSelect.setBorder(new SoftBevelBorder(BevelBorder.LOWERED, null, null, null, null));
                jTextFieldApkSelect.setEditable(false);

                jButtonApkSelect.addMouseListener(new MouseAdapter() {
                    public void mouseClicked(MouseEvent e) {
                        openApkFile();
                    }
                });

                jButtonMetaRefresh.addMouseListener(new MouseAdapter() {
                    public void mouseClicked(MouseEvent e) {
                        //                  jTextFieldApkSelect.setText(null);
                        // meta 
                        File file = new File(processDirPath + File.separator + apkName + "\\AndroidManifest.xml");
                        if (file.exists()) {
                            checkParams();
                            StringBuffer content = new StringBuffer();
                            content.append(rootDir).append("\n").append("cd ").append(rootDirPath).append("\n");//?
                            content.append("cmd /c mkdir ").append(processDirPath).append("\\tmp\n")//
                                    .append("cmd /c copy /y ").append(processDirPath + File.separator + apkName)
                                    .append("\\AndroidManifest.xml ").append(processDirPath)
                                    .append("\\tmp\\AndroidManifest.xml \n").append("del /q ")
                                    .append(processDirPath + File.separator + apkName)
                                    .append("\\AndroidManifest.xml ").append("\n")//??AndroidManifest
                                    .append("exit");//?
                            write(batPath, content.toString());
                            compile();
                            destroyBat();
                        }
                        File fileTemp = new File(processDirPath + "\\tmp\\AndroidManifest.xml ");
                        if (fileTemp.exists()) {
                            getMetaData();
                        }
                    }
                });

            }
            {
                jButtonAddChannel = new JButton();
                jPanelAddChannel.add(jButtonAddChannel);
                jPanelContent.add(jPanelAddChannel);
                jButtonAddChannel.setText("??");
                jButtonAddChannel.addMouseListener(new MouseAdapter() {
                    public void mouseClicked(MouseEvent e) {
                        if (metaDataMap.size() == 0) {
                            showErrorDialog("Apk,Manifestmeta-data");
                        } else {
                            addChannelPanel();
                        }
                    }
                });

            }

            // ========== APK======
            {
                jLabelOut = new JLabel();
                jPanelContent.add(jLabelOut);
                jLabelOut.setText("APK");
                jLabelOut.setForeground(Color.red);
            }

            {
                jTextFieldOut = new JTextField();
                jButtonOut = new JButton("?");
                jButtonOutClear = new JButton("");
                jPanelOut.add(jTextFieldOut);
                jPanelOut.add(jButtonOut);
                jPanelOut.add(jButtonOutClear);
                jPanelContent.add(jPanelOut);
                jTextFieldOut.setPreferredSize(new Dimension(450, 30));
                jTextFieldOut.setBorder(new SoftBevelBorder(BevelBorder.LOWERED, null, null, null, null));
                jTextFieldOut.setEditable(false);
                jButtonOut.addMouseListener(new MouseAdapter() {
                    public void mouseClicked(MouseEvent e) {
                        openOutputDir();
                    }
                });
                jButtonOutClear.addMouseListener(new MouseAdapter() {
                    public void mouseClicked(MouseEvent e) {
                        jTextFieldOut.setText(null);
                        outputDir = null;
                    }
                });
            }
            {
                jCheckBoxSign = new JCheckBox("??");
                jCheckBoxSign.setSelected(true);
                jPanelContent.add(jCheckBoxSign);
                jCheckBoxSign.addMouseListener(new MouseAdapter() {
                    public void mouseClicked(MouseEvent e) {
                        //                  jPanelSign.setVisible(jCheckBoxSign.isSelected());
                        boolean selected = jCheckBoxSign.isSelected();
                        jTextFieldSignPwd.setEnabled(selected);
                        jTextFieldAliaPwd.setEnabled(selected);
                        jComboBoxAlias.setEnabled(selected);
                        jButtonSign.setEnabled(selected);
                    }
                });

                jPanelContent.add(jPanelSign);
                jPanelKeyStore.setBorder(null);
                jPanelSign.add(jPanelKeyStore);
                jPanelSign.add(jPanelKeyStorePwd);
                jPanelSign.add(jPanelAlias);
                jPanelSign.add(jPanelAliasPwd);

                jTextFieldSignFile = new JTextField();
                jTextFieldSignFile.setEditable(false);
                jTextFieldSignFile.setPreferredSize(new Dimension(450, 30));
                jPanelKeyStore.add(jTextFieldSignFile);
                jButtonSign = new JButton("?");
                jPanelKeyStore.add(jButtonSign);
                jButtonSign.addMouseListener(new MouseAdapter() {
                    @Override
                    public void mouseClicked(MouseEvent e) {
                        openKeystoreFile();
                    }
                });
                jTextFieldSignPwd = new JTextField();
                jTextFieldSignPwd.setPreferredSize(new Dimension(450, 30));
                jPanelKeyStorePwd.add(jTextFieldSignPwd);
                jTextFieldSignPwd.setText("???(storepass)");
                jTextFieldSignPwd.addFocusListener(new FocusAdapter() {
                    public void focusGained(java.awt.event.FocusEvent e) {
                        if ("???(storepass)".equals(jTextFieldSignPwd.getText().trim())) {
                            jTextFieldSignPwd.setText("");
                        }
                    };

                    public void focusLost(java.awt.event.FocusEvent e) {
                        if ("".equals(jTextFieldSignPwd.getText().trim())) {
                            jTextFieldSignPwd.setText("???(storepass)");
                            return;
                        }
                        keystorePasswd = null;
                        if (keystoreFilePath != null && !"".equals(keystoreFilePath.trim())) {
                            try {
                                Enumeration<String> eAliases = KeystoreUtil.getAliases(keystoreFilePath,
                                        jTextFieldSignPwd.getText());
                                if (eAliases != null) {
                                    String[] aliases = Collections.list(eAliases).toArray(new String[0]);
                                    ComboBoxModel jComboBoxModel = new DefaultComboBoxModel<String>(aliases);
                                    jComboBoxAlias.setModel(jComboBoxModel);
                                    keystorePasswd = jTextFieldSignPwd.getText();
                                    return;
                                }
                            } catch (Exception e2) {
                                if (!"".equals(jTextFieldSignPwd.getText()) && !"".equals(keystoreFilePath)) {
                                    showErrorDialog(e2.getMessage());
                                }
                            }
                        }
                        ComboBoxModel jComboBoxModel = new DefaultComboBoxModel<String>();
                        jComboBoxAlias.setModel(jComboBoxModel);

                    };
                });
                jComboBoxAlias = new JComboBox();
                jComboBoxAlias.setPreferredSize(new Dimension(450, 30));
                jTextFieldAliaPwd = new JTextField();
                jTextFieldAliaPwd.setPreferredSize(new Dimension(450, 30));
                jPanelAlias.add(jComboBoxAlias);
                jPanelAliasPwd.add(jTextFieldAliaPwd);

                jTextFieldAliaPwd.setText("???(keypass)");
                jTextFieldAliaPwd.addFocusListener(new FocusAdapter() {
                    public void focusGained(java.awt.event.FocusEvent e) {
                        if ("???(keypass)".equals(jTextFieldAliaPwd.getText().trim())) {
                            jTextFieldAliaPwd.setText("");
                        }
                    };

                    public void focusLost(java.awt.event.FocusEvent e) {
                        if ("".equals(jTextFieldAliaPwd.getText().trim())) {
                            jTextFieldAliaPwd.setText("???(keypass)");
                            return;
                        }
                    };
                });

            }
            {
                jButtonStart = new JButton();
                jPanelStart.add(jButtonStart);
                jPanelContent.add(jPanelStart);
                jButtonStart.setText("");
                jButtonStart.addMouseListener(new MouseAdapter() {
                    public void mouseClicked(MouseEvent e) {
                        start();
                    }
                });
            }
            this.setSize(713, 550);
            // ??
            initConfigProperties();
            //         setDefaultCloseOperation(EXIT_ON_CLOSE);
            addWindowListener(new WindowAdapter() {
                public void windowClosing(WindowEvent e) {

                    deleteDir(processDirPath);
                    //               deleteDir(new File(processDirPath));
                    saveConfig();
                    System.exit(0);
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * ???
     */
    private void initConfigProperties() {
        if (rootDirPath == null) {
            //         apktoolPath = getClass().getResource("").getPath().substring(1);
            rootDirPath = getClass().getProtectionDomain().getCodeSource().getLocation().getPath().substring(1);
            File file = new File(rootDirPath);
            //         if (file.isFile()) {
            rootDirPath = file.getParent() + File.separator;
            rootDir = rootDirPath.substring(0, 2);
            // 
            processDirPath = rootDirPath + "temp" + File.separator + System.currentTimeMillis() + File.separator;
            File processDir = new File(processDirPath);
            if (!processDir.exists()) {
                processDir.mkdirs();
            }
            //         }
            batPath = processDirPath + "\\" + BAT;
        }
        Properties p = new Properties();
        try {
            p.load(new FileInputStream(rootDirPath + CONFIG_FILE));
            oriApkPath = p.getProperty("apkFile");
            outputDir = p.getProperty("outFile");
            keystoreFilePath = p.getProperty("keyFile");
            jTextFieldSignFile.setText(keystoreFilePath);
            jTextFieldApkSelect.setText("");
            jTextFieldOut.setText(outputDir);
        } catch (FileNotFoundException e) {
            //         e.printStackTrace();
        } catch (IOException e) {
            //         e.printStackTrace();
        }
    }

    /**
     * ?
     * @param dirPath
     */
    private void deleteDir(final String dirPath) {
        new Thread(new Runnable() {

            @Override
            public void run() {
                File file = new File(dirPath);
                if (file.exists()) {
                    String cmd = "cmd /c rd /s /q " + dirPath + " \n exit";
                    exeCmd(cmd);
                }
            }
        }).start();

    }

    /**
     * ??
     */
    private void saveConfig() {
        new Thread(new Runnable() {

            @Override
            public void run() {
                Properties p = new Properties();
                try {
                    File fOut = new File(rootDirPath + CONFIG_FILE);
                    if (!fOut.exists()) {
                        fOut.createNewFile();
                    }

                    p.load(new FileInputStream(rootDirPath + CONFIG_FILE));

                    if (oriApkPath != null) {
                        p.setProperty("apkFile", oriApkPath);
                    } else {
                        p.remove("apkFile");
                    }
                    if (outputDir != null) {
                        p.setProperty("outFile", outputDir);
                    } else {
                        p.remove("outFile");
                    }
                    if (keystoreFilePath != null) {
                        p.setProperty("keyFile", keystoreFilePath);
                    } else {
                        p.remove("keyFile");
                    }

                    p.store(new FileOutputStream(fOut), "");
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();

    }

    /**
     * ??
     */
    private void addChannelPanel() {
        // ?
        final ConfigViewHolder viewHolder = new ConfigViewHolder(configViews.size() + 1);
        viewHolder.jButtonMetaSelect.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                MetaSelectDialog dialog = new MetaSelectDialog(Main.this, metaDataMap, configViews, viewHolder,
                        new OnSelectCallback() {

                            @Override
                            public void onSelected(Set<String> metaDataSet) {
                                if (metaDataSet.size() > 0) {
                                    viewHolder.metaSet = metaDataSet;
                                    String metas = "";
                                    for (String string : metaDataSet) {
                                        metas += "," + string;
                                    }
                                    viewHolder.jTextFieldMates.setText(metas.substring(1));
                                } else {
                                    viewHolder.jTextFieldMates.setText("");
                                }
                            }
                        });
            }
        });
        viewHolder.jButtonDeleteConfig.addMouseListener(new MouseAdapter() {

            @Override
            public void mouseClicked(MouseEvent e) {
                viewHolder.removeAll();
                configViews.remove(viewHolder);
                for (int i = 0, count = configViews.size(); i < count; i++) {
                    ConfigViewHolder holder = configViews.get(i);
                    holder.updatePosition(i + 1);
                }
            }
        });
        viewHolder.setContainer(jPanelContent, configViews.size());
        configViews.add(viewHolder);
        // ?
        validate();
    }

    /**
     * APK
     */
    private void openApkFile() {
        JFileChooser jc = new JFileChooser(oriApkPath);
        jc.setFileSelectionMode(JFileChooser.FILES_ONLY);
        int value = jc.showOpenDialog(this);
        if (value == JFileChooser.APPROVE_OPTION) {
            File f = jc.getSelectedFile();
            if (f == null || !f.getName().endsWith("apk")) {
                return;
            }
            oriApkPath = f.getAbsolutePath();
            apkName = f.getName().replaceAll(".apk", "");
            jTextFieldApkSelect.setText(oriApkPath);
            resolveApk(f);
            getMetaData();
        }
    }

    /**
     * ??
     */
    private void openKeystoreFile() {
        JFileChooser jc = new JFileChooser(keystoreFilePath);
        jc.setFileSelectionMode(JFileChooser.FILES_ONLY);
        int value = jc.showOpenDialog(this);
        if (value == JFileChooser.APPROVE_OPTION) {
            File file = jc.getSelectedFile();
            if (file == null) {
                return;
            }
            keystoreFilePath = file.getAbsolutePath();
            jTextFieldSignFile.setText(keystoreFilePath);
        }
    }

    /**
     * ?Meta-data?
     */
    private void getMetaData() {
        metaDataMap.clear();
        xmlDoc = XmlUtil
                .getDocument(processDirPath + File.separator + "tmp" + File.separator + "AndroidManifest.xml");
        Element rootElement = xmlDoc.getRootElement();
        Element applicationElement = rootElement.element("application");
        List<Element> elements = XmlUtil.getChildElements(applicationElement, "meta-data");
        if (elements != null) {
            for (Element element : elements) {
                metaDataMap.put(XmlUtil.attrValue(element, "name"), element);
                System.out.println(element.getName() + ": " + XmlUtil.attrValue(element, "name") + " = "
                        + XmlUtil.attrValue(element, "value"));
            }
        }
    }

    /**
     * ?bat??
     */
    private void checkParams() {
        if (jComboBoxJdk.getSelectedIndex() == 1) {
            decompile_add = "";
            compile_add = "";
            sign_add = "";
        } else if (jComboBoxJdk.getSelectedIndex() == 0) {
            decompile_add = "-o ";
            compile_add = "-d ";
            sign_add = "-tsa https://timestamp.geotrust.com/tsa -digestalg SHA1 -sigalg MD5withRSA ";
        }
        apktoolPath = rootDirPath;
    }

    /**
     * ?apk,AndroidManifest.xml?tmp?AndroidManifest.xml
     * @param apkFile
     */
    private void resolveApk(File apkFile) {
        if (!apkFile.exists()) {
            return;
        }
        checkParams();

        StringBuffer content = new StringBuffer();
        content.append(rootDir).append("\n").append("cd ").append(rootDirPath).append("\n");//?
        content.append("cmd /c java -jar ").append(apktoolPath).append("apktool.jar d -f ")
                .append(apkFile.getAbsolutePath()).append(" ").append(decompile_add)
                .append(processDirPath + File.separator + apkName).append("\n")// ?apk
                .append("mkdir ").append(processDirPath).append("\\tmp\n")//
                .append("cmd /c copy /y ").append(processDirPath + File.separator + apkName)
                .append("\\AndroidManifest.xml ").append(processDirPath).append("\\tmp\\AndroidManifest.xml \n")
                .append("exit");//?
        write(batPath, content.toString());
        compile();
        destroyBat();
    }

    private void openOutputDir() {
        JFileChooser jc = new JFileChooser(outputDir);
        jc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
        int value = jc.showOpenDialog(this);
        if (value == JFileChooser.APPROVE_OPTION) {
            File f = jc.getSelectedFile();
            if (f == null) {
                return;
            }
            outputDir = f.getAbsolutePath();
            jTextFieldOut.setText(outputDir);
        }
    }

    private void start() {
        long time = System.currentTimeMillis();
        if (oriApkPath == null) {
            showErrorDialog("APK?!");
            return;
        }
        //      if (initKeystore()) {
        if (initApkInfo()) {
            multiChannelPackaging();
            showErrorDialog("" + (System.currentTimeMillis() - time) / 1000 + "s");
            openDir(outputDir);
        } else {
            showErrorDialog("apk?");
        }
    }

    /**
     * ??
     * @param dirPath
     */
    private void openDir(String dirPath) {
        try {
            String[] cmd = new String[7];
            cmd[0] = "cmd";
            cmd[1] = "/c";
            cmd[2] = "start";
            cmd[3] = " ";
            cmd[4] = dirPath;
            cmd[5] = "\n";
            cmd[6] = "exit";
            Runtime.getRuntime().exec(cmd);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * ?
     */
    private void multiChannelPackaging() {

        if (configViews.size() == 0) {
            // ??
            //         File file = new File(processDirPath + "\\tmp\\AndroidManifest.xml");
            File file = new File(
                    processDirPath + File.separator + apkName + File.separator + "AndroidManifest.xml");
            if (file.exists()) {
                String unSignApkPath = packagingOneChannel(file, "default");
                if (isSignChecked()) {
                    // ?
                    signApk(unSignApkPath);
                }
            }

            return;
        }
        // ??
        Map<String, Map<String, String>> allConfigs = new HashMap<String, Map<String, String>>();
        // ????key
        String[] allChannels = configViews.get(0).jTextFieldChannel.getText().split(",");
        // ????
        for (int i = 0; i < allChannels.length; i++) {
            Map<String, String> oneConfig = new HashMap<String, String>();
            for (int j = 0, count = configViews.size(); j < count; j++) {
                ConfigViewHolder viewHolder = configViews.get(j);
                String[] metas = viewHolder.jTextFieldMates.getText().split(",");
                String[] channels = viewHolder.jTextFieldChannel.getText().split(",");
                if (channels.length != allChannels.length) {
                    showErrorDialog(
                            "???????");
                    return;
                }
                for (String meta : metas) {
                    oneConfig.put(meta, channels[i]);
                }
            }
            allConfigs.put(allChannels[i], oneConfig);
        }
        // ?AndroidManifest.xml
        for (String channel : allConfigs.keySet()) {
            Map<String, String> map = allConfigs.get(channel);
            for (String key : map.keySet()) {
                metaDataMap.get(key).attribute("value").setValue(map.get(key));
            }
            // ??AndroidManifest.xml 
            String unSignApkPath = packagingOneChannel(saveChannelManifest(channel), channel);
            if (isSignChecked()) {
                // ?
                signApk(unSignApkPath);
            }
        }

    }

    /**
     * ?????
     * @return
     */
    private boolean isSignChecked() {
        if (jCheckBoxSign.isSelected()) {
            if ("".equals(jTextFieldSignFile.getText().trim())) {
                showErrorDialog("??");
            } else if ("".equals(jTextFieldSignPwd.getText().trim())) {
                showErrorDialog("???");
            } else if ("".equals(jTextFieldAliaPwd.getText().trim())) {
                showErrorDialog("???");
            } else {
                return true;
            }
        }
        return false;
    }

    /**
     * ??
     * @param unSignApkPath
     */
    private void signApk(String unSignApkPath) {
        SignParams signParams = new SignParams();
        signParams.setAlias(jComboBoxAlias.getSelectedItem().toString());
        signParams.setKeypass(jTextFieldAliaPwd.getText());
        signParams.setKeyStoreFilePath(jTextFieldSignFile.getText());
        signParams.setStorepass(keystorePasswd);
        signParams.setUnsignedApkFilePath(unSignApkPath);
        File unSignApk = new File(unSignApkPath);
        if (!unSignApk.exists()) {
            showErrorDialog("??");
            return;
        }
        signParams.setSignedApkFilePath(
                unSignApk.getParent() + File.separator + unSignApk.getName().replace("_unsign.apk", "_sign.apk"));
        try {
            KeystoreUtil.signApk(signParams);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            showErrorDialog(e.getMessage());
        }
    }

    /**
     * ?
     * @param xmlFile
     * @param channelId
     */
    private String packagingOneChannel(File xmlFile, String channelId) {
        // xml
        File destFile = new File(
                processDirPath + File.separator + apkName + File.separator + "AndroidManifest.xml");
        if (destFile.exists() && !destFile.getAbsolutePath().equals(xmlFile.getAbsolutePath())) {
            destFile.delete();
        }
        xmlFile.renameTo(destFile);
        File out;
        if (outputDir == null || "".equals(outputDir.trim())) {
            outputDir = rootDirPath + File.separator + "out" + File.separator + apkName;
        }
        out = new File(outputDir);
        if (!out.exists()) {
            out.mkdirs();
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        String newApkName = apkName + "_" + channelId + "_" + sdf.format(Long.valueOf(System.currentTimeMillis()))
                + "_" + versionName + "_unsign.apk";
        // 
        checkParams();
        StringBuffer content = new StringBuffer();
        content.append(rootDir).append("\n").append("cd ").append(rootDirPath).append("\n");//?
        content.append("cmd /c java -jar ").append(apktoolPath).append("apktool.jar b -f ").append(processDirPath)
                .append(File.separator + apkName).append(" ").append(decompile_add)
                .append(out.getPath() + File.separator + newApkName).append("\n")// ?apk
                .append("exit");//?
        //      // content = content + "@echo off\n";
        //      //       exec(content.toString());
        write(batPath, content.toString());
        compile();
        destroyBat();
        return out.getPath() + File.separator + newApkName;
    }

    /**
     * ??manifest
     * @param channel
     * @return
     */
    private File saveChannelManifest(String channel) {
        OutputFormat format = OutputFormat.createPrettyPrint();
        //      format.setEncoding("GBK");
        // ???XML  
        File out = new File(
                processDirPath + File.separator + "manifesttemp" + File.separator + "AndroidManifest.xml");
        File outDir = out.getParentFile();
        if (!outDir.exists()) {
            outDir.mkdirs();
        }
        XMLWriter writer = null;
        try {
            writer = new XMLWriter(new FileWriter(out), format);
            writer.write(xmlDoc); //  
            return out;
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return null;
        } finally {
            try {
                if (writer != null) {
                    writer.close();
                }

            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

    }

    private void destroyBat() {
        File f = new File(batPath);
        try {
            f.delete();
        } catch (Exception e) {
        }
    }

    /**
     * 
     * @param cmd
     */
    private void exeCmd(String cmd) {
        InputStream errIs = null;
        InputStream inIs = null;
        Process process = null;
        try {
            process = Runtime.getRuntime().exec(cmd);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            int read = -1;
            errIs = process.getErrorStream();
            while ((read = errIs.read()) != -1) {
                baos.write(read);
            }
            String errorString = baos.toString().toLowerCase();
            if (errorString.contains("fail")) {
                System.out.println("error!");
            }
            baos.write(10);
            inIs = process.getInputStream();
            while ((read = inIs.read()) != -1)
                baos.write(read);
        } catch (Exception e) {
            e.printStackTrace();
        } catch (Error e) {
            e.printStackTrace();
        } finally {
            try {
                if (errIs != null) {
                    errIs.close();
                }
                if (inIs != null)
                    inIs.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (process != null) {
                process.destroy();
            }
        }
    }

    private void compile() {
        exeCmd("cmd /c start " + batPath + "\n exit");
        System.out.println("finish!");
    }

    private boolean initApkInfo() {
        ApkInfo apkInfo = null;
        try {
            apkInfo = new ApkUtil().getApkInfo(oriApkPath);
            packageName = apkInfo.getPackageName();
            versionName = apkInfo.getVersionName();
            System.out.println(apkInfo.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return apkInfo != null;
    }

    public void write(String filePath, String content) {
        BufferedWriter bw = null;
        try {
            bw = new BufferedWriter(new FileWriter(filePath));

            bw.write(content);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (bw != null)
                try {
                    bw.close();
                } catch (IOException e) {
                    bw = null;
                }
        }
    }

    private void showErrorDialog(String msg) {
        JOptionPane.showMessageDialog(this, msg);
    }

    class MyDropTargetListener implements DropTargetListener {

        @Override
        public void dragEnter(DropTargetDragEvent arg0) {
            System.out.println("dragEnter:" + arg0.getSourceActions());
        }

        @Override
        public void dragExit(DropTargetEvent arg0) {
            System.out.println("dragExit");
        }

        @Override
        public void dragOver(DropTargetDragEvent arg0) {
            System.out.println("dragOver:" + arg0.getSourceActions());
        }

        @Override
        public void drop(DropTargetDropEvent arg0) {
            // JTextField field = (JTextField)arg0.getSource();
            // Transferable transferable = arg0.getTransferable();
            System.out.println("drop:" + arg0.getSourceActions());
        }

        @Override
        public void dropActionChanged(DropTargetDragEvent arg0) {
            System.out.println("dropActionChanged:" + arg0.getSourceActions());
        }

    }
}