blob: 4477e1e6f03e61883e5c2c429ca4a47da2f8459e [file] [log] [blame]
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.android.exportSignedPackage;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.ide.wizard.CommitStepException;
import com.intellij.openapi.compiler.CompileScope;
import com.intellij.openapi.compiler.CompilerManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.ArrayUtil;
import org.jetbrains.android.compiler.AndroidCompileUtil;
import org.jetbrains.android.compiler.artifact.ProGuardConfigFilesPanel;
import org.jetbrains.android.facet.AndroidFacet;
import org.jetbrains.android.facet.AndroidFacetConfiguration;
import org.jetbrains.android.util.AndroidBundle;
import org.jetbrains.android.util.AndroidCommonUtils;
import org.jetbrains.android.util.SaveFileListener;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.*;
import java.util.List;
/**
* @author Eugene.Kudelevsky
*/
class ApkStep extends ExportSignedPackageWizardStep {
public static final String APK_PATH_PROPERTY = "ExportedApkPath";
public static final String APK_PATH_PROPERTY_UNSIGNED = "ExportedUnsignedApkPath";
public static final String RUN_PROGUARD_PROPERTY = "AndroidRunProguardForReleaseBuild";
public static final String PROGUARD_CFG_PATHS_PROPERTY = "AndroidProguardConfigPaths";
private TextFieldWithBrowseButton myApkPathField;
private JPanel myContentPanel;
private JLabel myApkPathLabel;
private JCheckBox myProguardCheckBox;
private ProGuardConfigFilesPanel myProGuardConfigFilesPanel;
private final ExportSignedPackageWizard myWizard;
private boolean myInited;
@Nullable
private static String getContentRootPath(Module module) {
VirtualFile[] contentRoots = ModuleRootManager.getInstance(module).getContentRoots();
if (contentRoots.length != 0) {
VirtualFile contentRoot = contentRoots[0];
if (contentRoot != null) return contentRoot.getPath();
}
return null;
}
public ApkStep(ExportSignedPackageWizard wizard) {
myWizard = wizard;
myApkPathLabel.setLabelFor(myApkPathField);
myApkPathField.getButton().addActionListener(
new SaveFileListener(myContentPanel, myApkPathField, AndroidBundle.message("android.extract.package.choose.dest.apk"), "apk") {
@Override
protected String getDefaultLocation() {
Module module = myWizard.getFacet().getModule();
return getContentRootPath(module);
}
});
myProguardCheckBox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
myProGuardConfigFilesPanel.setEnabled(myProguardCheckBox.isSelected());
}
});
myContentPanel.setPreferredSize(new Dimension(myContentPanel.getPreferredSize().width, 250));
}
@Override
public void _init() {
if (myInited) return;
final AndroidFacet facet = myWizard.getFacet();
Module module = facet.getModule();
PropertiesComponent properties = PropertiesComponent.getInstance(module.getProject());
String lastModule = properties.getValue(ChooseModuleStep.MODULE_PROPERTY);
String lastApkPath = properties.getValue(getApkPathPropertyName());
if (lastApkPath != null && module.getName().equals(lastModule)) {
myApkPathField.setText(FileUtil.toSystemDependentName(lastApkPath));
}
else {
String contentRootPath = getContentRootPath(module);
if (contentRootPath != null) {
String defaultPath = FileUtil.toSystemDependentName(contentRootPath + "/" + module.getName() + ".apk");
myApkPathField.setText(defaultPath);
}
}
final String runProguardPropValue = properties.getValue(RUN_PROGUARD_PROPERTY);
boolean selected;
if (runProguardPropValue != null) {
selected = Boolean.parseBoolean(runProguardPropValue);
}
else {
selected = facet.getProperties().RUN_PROGUARD;
}
myProguardCheckBox.setSelected(selected);
myProGuardConfigFilesPanel.setEnabled(selected);
final String proguardCfgPathsStr = properties.getValue(PROGUARD_CFG_PATHS_PROPERTY);
final String[] proguardCfgPaths = proguardCfgPathsStr != null
? parseAndCheckProguardCfgPaths(proguardCfgPathsStr)
: null;
if (proguardCfgPaths != null && proguardCfgPaths.length > 0) {
myProGuardConfigFilesPanel.setOsPaths(Arrays.asList(proguardCfgPaths));
}
else {
final AndroidFacetConfiguration configuration = facet.getConfiguration();
if (configuration.getState().RUN_PROGUARD) {
myProGuardConfigFilesPanel.setUrls(facet.getProperties().myProGuardCfgFiles);
}
else {
final List<String> urls = new ArrayList<String>();
urls.add(AndroidCommonUtils.PROGUARD_SYSTEM_CFG_FILE_URL);
final Pair<VirtualFile, Boolean> pair = AndroidCompileUtil.getDefaultProguardConfigFile(facet);
if (pair != null) {
urls.add(pair.getFirst().getUrl());
}
myProGuardConfigFilesPanel.setUrls(urls);
}
}
myInited = true;
}
@NotNull
private static String[] parseAndCheckProguardCfgPaths(@NotNull String pathsStr) {
if (pathsStr.length() == 0) {
return ArrayUtil.EMPTY_STRING_ARRAY;
}
final String[] paths = pathsStr.split(File.pathSeparator);
if (paths.length == 0) {
return ArrayUtil.EMPTY_STRING_ARRAY;
}
for (String path : paths) {
if (LocalFileSystem.getInstance().refreshAndFindFileByPath(path) == null) {
return ArrayUtil.EMPTY_STRING_ARRAY;
}
}
return paths;
}
@NotNull
private static String mergeProguardCfgPathsToOneString(@NotNull Collection<String> paths) {
final StringBuilder builder = new StringBuilder();
for (Iterator<String> it = paths.iterator(); it.hasNext(); ) {
builder.append(it.next());
if (it.hasNext()) {
builder.append(File.pathSeparator);
}
}
return builder.toString();
}
private String getApkPathPropertyName() {
return myWizard.isSigned() ? APK_PATH_PROPERTY : APK_PATH_PROPERTY_UNSIGNED;
}
@Override
public JComponent getComponent() {
return myContentPanel;
}
@Override
protected boolean canFinish() {
return true;
}
@Override
public String getHelpId() {
return "reference.android.reference.extract.signed.package.specify.apk.location";
}
@Override
public void _commit(boolean finishChosen) throws CommitStepException {
final String apkPath = myApkPathField.getText().trim();
if (apkPath.length() == 0) {
throw new CommitStepException(AndroidBundle.message("android.extract.package.specify.apk.path.error"));
}
AndroidFacet facet = myWizard.getFacet();
PropertiesComponent properties = PropertiesComponent.getInstance(myWizard.getProject());
properties.setValue(ChooseModuleStep.MODULE_PROPERTY, facet != null ? facet.getModule().getName() : "");
properties.setValue(getApkPathPropertyName(), apkPath);
File folder = new File(apkPath).getParentFile();
if (folder == null) {
throw new CommitStepException(AndroidBundle.message("android.cannot.create.file.error", apkPath));
}
try {
if (!folder.exists()) {
folder.mkdirs();
}
}
catch (Exception e) {
throw new CommitStepException(e.getMessage());
}
final CompileScope compileScope = CompilerManager.getInstance(myWizard.getProject()).
createModuleCompileScope(facet.getModule(), true);
AndroidCompileUtil.setReleaseBuild(compileScope);
properties.setValue(RUN_PROGUARD_PROPERTY, Boolean.toString(myProguardCheckBox.isSelected()));
if (myProguardCheckBox.isSelected()) {
final List<String> proguardOsCfgPaths = myProGuardConfigFilesPanel.getOsPaths();
if (proguardOsCfgPaths.isEmpty()) {
throw new CommitStepException(AndroidBundle.message("android.extract.package.specify.proguard.cfg.path.error"));
}
final String proguardPathsStr = mergeProguardCfgPathsToOneString(proguardOsCfgPaths);
properties.setValue(PROGUARD_CFG_PATHS_PROPERTY, proguardPathsStr);
for (String path : proguardOsCfgPaths) {
if (!new File(path).isFile()) {
throw new CommitStepException("Cannot find file " + path);
}
}
compileScope.putUserData(AndroidCompileUtil.PROGUARD_CFG_PATHS_KEY, proguardPathsStr);
}
myWizard.setCompileScope(compileScope);
myWizard.setApkPath(apkPath);
}
@Override
protected void commitForNext() throws CommitStepException {
}
private void createUIComponents() {
myProGuardConfigFilesPanel = new ProGuardConfigFilesPanel() {
@Nullable
@Override
protected AndroidFacet getFacet() {
return myWizard.getFacet();
}
};
}
}