--- /dev/null
+IntelliJ IDEA 8.0M1 - README
+
+Thank you for downloading IntelliJ IDEA!
+
+IntelliJ IDEA is a multi-platform Java IDE, which includes intelligent editor, rich-featured GUI designer,
+visual debugger, javac/jikes/rmic compiler integration, refactoring, enhanced project navigation,
+intelligent code inspection and analysis features, J2EE and JDK 1.5 support.
+
+
+Contents:
+=========
+ BUILD.TXT File containing the current build number
+ KnownIssues.TXT Known issues and workarounds
+ README.TXT This file
+ bin/ Startup scripts for launching IntelliJ IDEA
+ help/ Online help files
+ jre/ Bundled JRE
+ lib/ Library files
+ license/ License files for IntelliJ IDEA and bundled software
+ plugins/ Standard plugins
+ redist/ Contains libraries that need to be redistributed with your application if certain IDEA features are used:
+ - forms_rt.jar should be distributed with your applications that use GUI forms with
+ the "GridLayoutManager (IntelliJ)" layout manager
+ - javac2.jar is an Ant task for building applications that use IntelliJ IDEA's UI Designer
+ bytecode generation or @NotNull assertions generation
+ - annotations.jar contains JDK 1.5 annotation classes for 'Constant Conditions & Exceptions' inspection tool.
+
+ Install-Linux-tar.txt Installation instructions for Linux (included in Linux installation package only)
+ Install-Windows-zip.txt Installation instructions for Windows zip-file (included in Windows zip installation package only)
+
+ USER_HOME/.IntelliJIdea80/
+
+ config/ Configuration files (See INSTALLATION_HOME/bin/idea.properties to tweak location of the configs)
+ codestyles/ User's code style settings
+ colors/ User's colors and fonts settings
+ fileTemplates/ Custom file templates
+ filetypes/ Custom file types
+ ideTalk/ ideTalk settings
+ inspection/ Executable file and auxiliary data for running offline code inspections
+ keymaps/ Contains files with custom keymaps
+ migration/ API migration map
+ options/ IDE options configuration files
+ plugins/ Directory for custom plugins (it appears after the 1st plugin is installed)
+ shelf/ Shelved changes (in standard .patch file format)
+ templates/ Live templates, both built-in and custom
+ tools/ External tools
+ idea70.key File containing your license key (editing not recommended)
+
+ system/ Various IDEA internal caches including Local History data storage.
+ (See INSTALLATION_HOME/bin/idea.properties to tweak location of the caches).
+ Also log directory with IDEA log files is located there.
+
+
+Installing IntelliJ IDEA
+========================
+ For Linux and other Generic Unix users:
+ Please read the contents of the Install-Linux-tar.txt file.
+
+ Installing on Mac OS:
+ IntelliJ IDEA is distributed as a .dmg file. You only need to drag it to
+ the destination folder, from which you can start the application.
+
+Uninstalling IntelliJ IDEA
+==========================
+ If you installed IntelliJ IDEA with the help of Installation Wizard, then
+ just run the INSTALLATION_HOME/bin/Uninstall.exe file
+
+ To uninstall IntelliJ IDEA after manual installation, simply delete the
+ contents of the IntelliJ IDEA home installation directory.
+
+
+Licensing & pricing
+==========================
+ Licensing and pricing information can be found at http://www.jetbrains.com/idea/buy/index.html.
+
+
+IntelliJ IDEA Overview
+==========================
+ For general info and facts on IntelliJ IDEA, you can refer to IntelliJ IDEA Info Kit at
+ http://www.jetbrains.com/idea/documentation/product_info_kit.html.
+
+
+IDEA Development Package
+==========================
+ Contains:
+ - Source code for the OpenAPI classes;
+ - Documentation (JavaDocs for the OpenAPI and a number of additional components);
+ - Simple example plugins demonstrating usage of the OpenAPI;
+ - Source code for plugins shipped with IDEA:
+ * Plugin Development Kit
+ * IDEtalk plugin
+ * Images support plugin
+ * Inspection Gadgets
+ * Intention PowerPack
+ * J2ME development support plugin
+ * JavaScript support plugin
+ * JavaScript inspections plugin
+ * JavaScript Intention PowerPack
+ * GWTStudio plugin
+ * KlassMaster stacktrace unscramble plugin
+ * StrutsAssistant plugin
+ * StarTeam, Perforce, Subversion, Visual SourceSafe integration
+ * Tomcat, Weblogic, WebSphere, Geronimo, JBoss, GlassFish, JSR45 integration
+
+ Download page: http://www.jetbrains.com/idea/download/index.html
+
+ Source code of additional open source plugins shipped with IntelliJ IDEA is available in the Subversion
+ repository at:
+ http://svn.jetbrains.org/idea/Trunk/bundled/
+
+
+Using Plugins
+=============
+ IDEA now smartly integrates with the Community web-site which holds a repository of the third-party plugins to it.
+ This integration, supplied with a convenient UI, helps you incorporate any available plugins without switching from
+ IDEA settings dialog (Settings | Plugins).
+
+ You can browse the plugins Web site, rate and comment on plugins at:
+ http://plugins.intellij.net/
+
+
+Home Page:
+==========
+ http://www.jetbrains.com
+
+
+IntelliJ Technology Network
+===========================
+ http://www.intellij.net
+ Early Access to new products, internal builds and patches, Bug/Features database, Forums/newsgroups
+
+
+IntelliJ Community Site
+=======================
+ http://www.intellij.org
+ The community-driven Wiki site dedicated to IntelliJ products and technologies.
+
+
+Support
+=======
+ For technical support and assistance, you may find necessary information at the Support page
+ (http://www.jetbrains.com/support/index.html) or contact us at support@jetbrains.com.
+
+
+Bug Reporting:
+==============
+ Send emails to bugs@jetbrains.com
+
+
+Contacting us:
+==============
+ sales@jetbrains.com - Sales inquiries, billing, order processing questions
+ support@jetbrains.com - Technical support (all products)
+ sales.us@jetbrains.com - Sales inquiries in the United States
+ support.us@jetbrains.com - Technical support for US customers
+ suggestions@jetbrains.com - Feature suggestions
+ info@jetbrains.com - Product inquiries
+
+
+=============
+You are encouraged to visit our IntelliJ IDEA web site at http://www.jetbrains.com/idea/
+or to contact us via e-mail at feedback@jetbrains.com if you have any comments about
+this release. In particular, we are very interested in any ease-of-use, user
+interface suggestions that you may have. We will be posting regular updates
+of our progress to our online forums and newsgroups.
+=============
--- /dev/null
+@echo off
+
+::----------------------------------------------------------------------
+:: IntelliJ IDEA Startup Script
+::----------------------------------------------------------------------
+
+set JDK_HOME=c:/tools/jdk
+
+:: ---------------------------------------------------------------------
+:: Before you run IntelliJ IDEA specify the location of the
+:: JDK 1.5 installation directory which will be used for running IDEA
+:: ---------------------------------------------------------------------
+IF "%IDEA_JDK%" == "" SET IDEA_JDK=%JDK_HOME%
+IF "%IDEA_JDK%" == "" goto error
+
+:: ---------------------------------------------------------------------
+:: Before you run IntelliJ IDEA specify the location of the
+:: directory where IntelliJ IDEA is installed
+:: In most cases you do not need to change the settings below.
+:: ---------------------------------------------------------------------
+SET IDEA_HOME=..
+
+SET JAVA_EXE=%IDEA_JDK%\jre\bin\java.exe
+IF NOT EXIST "%JAVA_EXE%" goto error
+
+IF "%IDEA_MAIN_CLASS_NAME%" == "" SET IDEA_MAIN_CLASS_NAME=com.intellij.idea.Main
+
+IF NOT "%IDEA_PROPERTIES%" == "" set IDEA_PROPERTIES_PROPERTY=-Didea.properties.file=%IDEA_PROPERTIES%
+
+:: ---------------------------------------------------------------------
+:: You may specify your own JVM arguments in idea.exe.vmoptions file. Put one option per line there.
+:: ---------------------------------------------------------------------
+SET ACC=
+FOR /F "delims=" %%i in (%IDEA_HOME%\bin\idea.exe.vmoptions) DO call %IDEA_HOME%\bin\append.bat "%%i"
+
+set REQUIRED_IDEA_JVM_ARGS=-Xbootclasspath/p:%IDEA_HOME%/lib/boot.jar %IDEA_PROPERTIES_PROPERTY% %REQUIRED_IDEA_JVM_ARGS%
+SET JVM_ARGS=%ACC% %REQUIRED_IDEA_JVM_ARGS%
+
+SET OLD_PATH=%PATH%
+SET PATH=%IDEA_HOME%\bin;%PATH%
+
+SET CLASS_PATH=%IDEA_HOME%\lib\bootstrap.jar
+SET CLASS_PATH=%CLASS_PATH%;%IDEA_HOME%\lib\util.jar
+SET CLASS_PATH=%CLASS_PATH%;%IDEA_HOME%\lib\jdom.jar
+SET CLASS_PATH=%CLASS_PATH%;%IDEA_HOME%\lib\log4j.jar
+SET CLASS_PATH=%CLASS_PATH%;%IDEA_HOME%\lib\extensions.jar
+SET CLASS_PATH=%CLASS_PATH%;%IDEA_HOME%\lib\trove4j.jar
+SET CLASS_PATH=%CLASS_PATH%;%IDEA_JDK%\lib\tools.jar
+
+:: ---------------------------------------------------------------------
+:: You may specify additional class paths in IDEA_CLASS_PATH variable.
+:: It is a good idea to specify paths to your plugins in this variable.
+:: ---------------------------------------------------------------------
+IF NOT "%IDEA_CLASS_PATH%" == "" SET CLASS_PATH=%CLASS_PATH%;%IDEA_CLASS_PATH%
+
+"%JAVA_EXE%" %JVM_ARGS% -cp "%CLASS_PATH%" %IDEA_MAIN_CLASS_NAME% %*
+
+SET PATH=%OLD_PATH%
+goto end
+:error
+echo ---------------------------------------------------------------------
+echo ERROR: cannot start IntelliJ IDEA.
+echo No JDK found to run IDEA. Please validate either IDEA_JDK or JDK_HOME points to valid JDK installation
+echo ---------------------------------------------------------------------
+pause
+:end
--- /dev/null
+# Set up IDEA_PROPERTIES environment variable to specify custom location of this properties file like
+# SET IDEA_PROPERTIES=c:\ideaconfig\idea.properties
+# before launching idea.
+# If not specified it is searched according following sequence (first successful is used).
+# 1. ${user.home}
+# 2. ${idea.home}/bin
+
+# Use ${idea.home} macro to specify location relative to IDEA installation home
+# Also use ${xxx} where xxx is any java property (including defined in previous lines of this file) to refer to its value
+# Note for Windows users: please make sure you're using forward slashes. I.e. c:/idea/system
+
+#---------------------------------------------------------------------
+# Uncomment this option if you want to customize path to IDEA config folder. Make sure you're using forward slashes
+#---------------------------------------------------------------------
+idea.config.path=${idea.home}/config
+
+#---------------------------------------------------------------------
+# Uncomment this option if you want to customize path to IDEA system folder. Make sure you're using forward slashes
+#---------------------------------------------------------------------
+idea.system.path=${idea.home}/system
+
+#---------------------------------------------------------------------
+# Uncomment this option if you want to customize path to user installed plugins folder. Make sure you're using forward slashes
+#---------------------------------------------------------------------
+idea.plugins.path=${idea.home}/config/plugins
+
+#---------------------------------------------------------------------
+# Maximum file size (kilobytes) IDEA should provide intellisense for.
+# The larger file is the slower its editor works and higher overall system memory requirements are
+# if intellisense is enabled. Remove this property or set to very large number if you need
+# intellisense for any files available regardless their size.
+# Please note this option doesn't operate with Java files. Regardless of the option value intellisense will anyway stay there.
+#---------------------------------------------------------------------
+idea.max.intellisense.filesize=2048
+
+#---------------------------------------------------------------------
+# There are two possible values of idea.popup.weight property: "heavy" and "medium".
+# If you have WM configured as "Focus follows mouse with Auto Raise" then you have to
+# set this property to "medium". It prevents problems with popup menus on some
+# configurations.
+# ---------------------------------------------------------------------
+idea.popup.weight=heavy
+
+#----------------------------------------------------------------------
+# Disabling this property may lead to visual glitches like blinking and fail to repaint
+# on certain display adapter cards.
+#----------------------------------------------------------------------
+sun.java2d.noddraw=true
+
+#----------------------------------------------------------------------
+# Removing this property may lead to editor performance degradation under Windows.
+#----------------------------------------------------------------------
+sun.java2d.d3d=false
+
+#-----------------------------------------------------------------------
+# IDEA copies library jars to prevent their locking. If copying is not desirable, specify "true"
+#-----------------------------------------------------------------------
+idea.jars.nocopy=false
+
+#----------------------------------------------------------------------
+# Configure if a special launcher should be used when running processes from within IDEA.
+# Using Launcher enables "soft exit" and "thread dump" features
+#----------------------------------------------------------------------
+idea.no.launcher=false
+
+#-----------------------------------------------------------------------
+# The VM option value to be used start the JVM in debug mode.
+# Some environments define it in a different way (-XXdebug in Oracle VM)
+#-----------------------------------------------------------------------
+idea.xdebug.key=-Xdebug
+
+#-----------------------------------------------------------------------
+# Switch into JMX 1.0 compatible mode
+# Uncomment this option to be able to run IDEA using J2SDK 1.5 while working
+# with application servers (like WebLogic) running 1.4
+#-----------------------------------------------------------------------
+#jmx.serial.form=1.0
+
+#-----------------------------------------------------------------------
+# Uncomment this option if you don't like to receive notifications about
+# fatal errors that happen to IDEA or plugins installed.
+#-----------------------------------------------------------------------
+idea.fatal.error.notification=disabled
+
+# Workaround for slow scrolling in JDK6
+swing.bufferPerWindow=false
+
+#-----------------------------------------------------------------------
+# Uncomment this property to prevent IDEA from throwing ProcessCanceledException when user activity
+# detected. This option is only useful for plugin developers, while debugging PSI related activities
+# performed in background error analysis thread.
+# DO NOT UNCOMMENT THIS UNLESS YOU'RE DEBUGGING IDEA ITSELF. Significant slowdowns and lockups will happen otherwise.
+#-----------------------------------------------------------------------
+#idea.ProcessCanceledException=disabled
+
+#----------------------------------------------------------------------
+# Removing this property may lead to editor performance degradation under X-Windows.
+#----------------------------------------------------------------------
+sun.java2d.pmoffscreen=false
+
+#---------------------------------------------------------------------
+# Maximum size (kilobytes) IDEA will load for showing past file contents -
+# in Show Diff or when calculating Digest Diff
+#---------------------------------------------------------------------
+#idea.max.vcs.loaded.size.kb=20480
\ No newline at end of file
--- /dev/null
+package com.intellij.updater;
+
+import org.junit.Test;
+
+import java.util.Collections;
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+
+public class DigesterTest extends UpdaterTestCase {
+ @Test
+ public void testBasics() throws Exception {
+ Map<String, Long> checkSums = Digester.digestFiles(getDataDir(), Collections.<String>emptyList(), TEST_UI);
+ assertEquals(12, checkSums.size());
+
+ assertEquals(CHECKSUMS.README_TXT, (long)checkSums.get("Readme.txt"));
+ assertEquals(CHECKSUMS.FOCUSKILLER_DLL, (long)checkSums.get("bin/focuskiller.dll"));
+ assertEquals(CHECKSUMS.BOOTSTRAP_JAR, (long)checkSums.get("lib/bootstrap.jar"));
+ Runner.initLogger();
+ }
+}
\ No newline at end of file
--- /dev/null
+package com.intellij.updater;
+
+import com.intellij.openapi.util.io.FileUtil;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.*;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+import java.util.zip.ZipOutputStream;
+
+import static org.junit.Assert.*;
+
+@SuppressWarnings("ResultOfMethodCallIgnored")
+public class PatchFileCreatorTest extends PatchTestCase {
+ private File myFile;
+
+ @Override
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+ myFile = getTempFile("patch.zip");
+ }
+
+ @Test
+ public void testCreatingAndApplying() throws Exception {
+ createPatch();
+
+ assertAppliedAndRevertedCorrectly(PatchFileCreator.prepareAndValidate(myFile, myOlderDir, TEST_UI));
+ }
+
+ @Test
+ public void failOnEmptySourceJar() throws Exception {
+ final File sourceJar = new File(myOlderDir, "lib/empty.jar");
+ if (sourceJar.exists()) sourceJar.delete();
+ assertTrue(sourceJar.createNewFile());
+
+ try {
+ final File targetJar = new File(myNewerDir, "lib/empty.jar");
+ FileUtil.copy(new File(myNewerDir, "lib/annotations.jar"), targetJar);
+
+ try {
+ createPatch();
+ fail("Should have failed to create a patch from empty .jar");
+ }
+ catch (IOException e) {
+ final String reason = e.getMessage();
+ assertEquals("Corrupted source file: " + sourceJar, reason);
+ }
+ finally {
+ targetJar.delete();
+ }
+ }
+ finally {
+ sourceJar.delete();
+ }
+ }
+
+ @Test
+ public void failOnEmptyTargetJar() throws Exception {
+ final File sourceJar = new File(myOlderDir, "lib/empty.jar");
+ FileUtil.copy(new File(myOlderDir, "lib/annotations.jar"), sourceJar);
+
+ try {
+ final File targetJar = new File(myNewerDir, "lib/empty.jar");
+ if (targetJar.exists()) targetJar.delete();
+ assertTrue(targetJar.createNewFile());
+
+ try {
+ createPatch();
+ fail("Should have failed to create a patch against empty .jar");
+ }
+ catch (IOException e) {
+ final String reason = e.getMessage();
+ assertEquals("Corrupted target file: " + targetJar, reason);
+ }
+ finally {
+ targetJar.delete();
+ }
+ }
+ finally {
+ sourceJar.delete();
+ }
+ }
+
+ @Test
+ public void testReverting() throws Exception {
+ createPatch();
+
+ PatchFileCreator.PreparationResult preparationResult = PatchFileCreator.prepareAndValidate(myFile, myOlderDir, TEST_UI);
+ preparationResult.patch.getActions().add(new MyFailOnApplyPatchAction());
+ assertNothingHasChanged(preparationResult, new HashMap<String, ValidationResult.Option>());
+ }
+
+ @Test
+ public void testApplyingWithAbsentFileToDelete() throws Exception {
+ PatchFileCreator.create(myOlderDir, myNewerDir, myFile, Collections.<String>emptyList(), Collections.<String>emptyList(),
+ Collections.<String>emptyList(), TEST_UI);
+
+ new File(myOlderDir, "bin/idea.bat").delete();
+
+ assertAppliedAndRevertedCorrectly(PatchFileCreator.prepareAndValidate(myFile, myOlderDir, TEST_UI));
+ }
+
+ @Test
+ public void testApplyingWithAbsentOptionalFile() throws Exception {
+ FileUtil.writeToFile(new File(myNewerDir, "bin/idea.bat"), "new content".getBytes());
+
+ PatchFileCreator.create(myOlderDir, myNewerDir, myFile, Collections.<String>emptyList(), Collections.<String>emptyList(),
+ Collections.singletonList("bin/idea.bat"), TEST_UI);
+
+ new File(myOlderDir, "bin/idea.bat").delete();
+
+ PatchFileCreator.PreparationResult preparationResult = PatchFileCreator.prepareAndValidate(myFile, myOlderDir, TEST_UI);
+ assertTrue(preparationResult.validationResults.isEmpty());
+ assertAppliedAndRevertedCorrectly(preparationResult);
+ }
+
+ @Test
+ public void testRevertingWithAbsentFileToDelete() throws Exception {
+ PatchFileCreator.create(myOlderDir, myNewerDir, myFile, Collections.<String>emptyList(), Collections.<String>emptyList(),
+ Collections.<String>emptyList(), TEST_UI);
+
+ new File(myOlderDir, "bin/idea.bat").delete();
+
+ PatchFileCreator.PreparationResult preparationResult = PatchFileCreator.prepareAndValidate(myFile, myOlderDir, TEST_UI);
+ preparationResult.patch.getActions().add(new MyFailOnApplyPatchAction());
+ assertNothingHasChanged(preparationResult, new HashMap<String, ValidationResult.Option>());
+ }
+
+ @Test
+ public void testApplyingWithoutCriticalFiles() throws Exception {
+ PatchFileCreator.create(myOlderDir, myNewerDir, myFile, Collections.<String>emptyList(), Collections.<String>emptyList(),
+ Collections.<String>emptyList(), TEST_UI);
+ PatchFileCreator.PreparationResult preparationResult = PatchFileCreator.prepareAndValidate(myFile, myOlderDir, TEST_UI);
+
+ assertTrue(PatchFileCreator.apply(preparationResult, new HashMap<String, ValidationResult.Option>(), TEST_UI));
+ }
+
+ @Test
+ public void testApplyingWithCriticalFiles() throws Exception {
+ PatchFileCreator.create(myOlderDir, myNewerDir, myFile, Collections.<String>emptyList(), Arrays.asList("lib/annotations.jar"),
+ Collections.<String>emptyList(), TEST_UI);
+
+ PatchFileCreator.PreparationResult preparationResult = PatchFileCreator.prepareAndValidate(myFile, myOlderDir, TEST_UI);
+
+ assertTrue(PatchFileCreator.apply(preparationResult, new HashMap<String, ValidationResult.Option>(), TEST_UI));
+ assertAppliedCorrectly();
+ }
+
+ @Test
+ public void testApplyingWithCaseChangedNames() throws Exception {
+ FileUtil.rename(new File(myOlderDir, "Readme.txt"),
+ new File(myOlderDir, "README.txt"));
+
+ PatchFileCreator.create(myOlderDir, myNewerDir, myFile, Collections.<String>emptyList(), Collections.<String>emptyList(),
+ Collections.<String>emptyList(), TEST_UI);
+
+ assertAppliedAndRevertedCorrectly(PatchFileCreator.prepareAndValidate(myFile, myOlderDir, TEST_UI));
+ }
+
+ @Test
+ public void testCreatingAndApplyingWhenDirectoryBecomesFile() throws Exception {
+ File file = new File(myOlderDir, "Readme.txt");
+ file.delete();
+ file.mkdirs();
+
+ new File(file, "subFile.txt").createNewFile();
+ new File(file, "subDir").mkdir();
+ new File(file, "subDir/subFile.txt").createNewFile();
+
+ FileUtil.copy(new File(myOlderDir, "lib/boot.jar"),
+ new File(myOlderDir, "lib/boot_with_directory_becomes_file.jar"));
+
+ PatchFileCreator.create(myOlderDir, myNewerDir, myFile, Collections.<String>emptyList(), Collections.<String>emptyList(),
+ Collections.<String>emptyList(), TEST_UI);
+
+ assertAppliedAndRevertedCorrectly(PatchFileCreator.prepareAndValidate(myFile, myOlderDir, TEST_UI));
+ }
+
+ @Test
+ public void testCreatingAndApplyingWhenFileBecomesDirectory() throws Exception {
+ File file = new File(myOlderDir, "bin");
+ assertTrue(FileUtil.delete(file));
+ file.createNewFile();
+
+ FileUtil.copy(new File(myOlderDir, "lib/boot_with_directory_becomes_file.jar"),
+ new File(myOlderDir, "lib/boot.jar"));
+
+ PatchFileCreator.create(myOlderDir, myNewerDir, myFile, Collections.<String>emptyList(), Collections.<String>emptyList(),
+ Collections.<String>emptyList(), TEST_UI);
+
+ assertAppliedAndRevertedCorrectly(PatchFileCreator.prepareAndValidate(myFile, myOlderDir, TEST_UI));
+ }
+
+ @Test
+ public void testConsideringOptions() throws Exception {
+ createPatch();
+
+ PatchFileCreator.PreparationResult preparationResult = PatchFileCreator.prepareAndValidate(myFile, myOlderDir, TEST_UI);
+ Map<String, ValidationResult.Option> options = new HashMap<String, ValidationResult.Option>();
+ for (PatchAction each : preparationResult.patch.getActions()) {
+ options.put(each.getPath(), ValidationResult.Option.IGNORE);
+ }
+
+ assertNothingHasChanged(preparationResult, options);
+ }
+
+ private void createPatch() throws IOException, OperationCancelledException {
+ PatchFileCreator.create(myOlderDir, myNewerDir, myFile,
+ Collections.<String>emptyList(), Collections.<String>emptyList(), Collections.<String>emptyList(), TEST_UI);
+ assertTrue(myFile.exists());
+ }
+
+ private void assertNothingHasChanged(PatchFileCreator.PreparationResult preparationResult, Map<String, ValidationResult.Option> options)
+ throws Exception {
+ Map<String, Long> before = Digester.digestFiles(myOlderDir, Collections.<String>emptyList(), TEST_UI);
+ PatchFileCreator.apply(preparationResult, options, TEST_UI);
+ Map<String, Long> after = Digester.digestFiles(myOlderDir, Collections.<String>emptyList(), TEST_UI);
+
+ DiffCalculator.Result diff = DiffCalculator.calculate(before, after);
+ assertTrue(diff.filesToCreate.isEmpty());
+ assertTrue(diff.filesToDelete.isEmpty());
+ assertTrue(diff.filesToUpdate.isEmpty());
+ }
+
+ private void assertAppliedAndRevertedCorrectly(PatchFileCreator.PreparationResult preparationResult)
+ throws IOException, OperationCancelledException {
+
+ Map<String, Long> original = Digester.digestFiles(myOlderDir, Collections.<String>emptyList(), TEST_UI);
+
+ File backup = getTempFile("backup");
+
+ for (ValidationResult each : preparationResult.validationResults) {
+ assertTrue(each.toString(), each.kind != ValidationResult.Kind.ERROR);
+ }
+
+ List<PatchAction> appliedActions =
+ PatchFileCreator.apply(preparationResult, new HashMap<String, ValidationResult.Option>(), backup, TEST_UI).appliedActions;
+ assertAppliedCorrectly();
+
+ assertFalse(original.equals(Digester.digestFiles(myOlderDir, Collections.<String>emptyList(), TEST_UI)));
+
+ PatchFileCreator.revert(preparationResult, appliedActions, backup, TEST_UI);
+
+ assertEquals(original, Digester.digestFiles(myOlderDir, Collections.<String>emptyList(), TEST_UI));
+ }
+
+ protected void assertAppliedCorrectly() throws IOException {
+ File newFile = new File(myOlderDir, "newDir/newFile.txt");
+ assertTrue(newFile.exists());
+ assertEquals("hello", FileUtil.loadFile(newFile));
+
+ File changedFile = new File(myOlderDir, "Readme.txt");
+ assertTrue(changedFile.exists());
+ assertEquals("hello", FileUtil.loadFile(changedFile));
+
+ assertFalse(new File(myOlderDir, "bin/idea.bat").exists());
+
+ // do not remove unchanged
+ checkZipEntry("lib/annotations.jar", "org/jetbrains/annotations/Nls.class", 502);
+ // add new
+ checkZipEntry("lib/annotations.jar", "org/jetbrains/annotations/NewClass.class", 453);
+ // update changed
+ checkZipEntry("lib/annotations.jar", "org/jetbrains/annotations/Nullable.class", 546);
+ // remove obsolete
+ checkNoZipEntry("lib/annotations.jar", "org/jetbrains/annotations/TestOnly.class");
+
+ // test for archives with only deleted files
+ checkNoZipEntry("lib/bootstrap.jar", "com/intellij/ide/ClassloaderUtil.class");
+
+ // packing directories too
+ checkZipEntry("lib/annotations.jar", "org/", 0);
+ checkZipEntry("lib/annotations.jar", "org/jetbrains/", 0);
+ checkZipEntry("lib/annotations.jar", "org/jetbrains/annotations/", 0);
+ checkZipEntry("lib/bootstrap.jar", "com/", 0);
+ checkZipEntry("lib/bootstrap.jar", "com/intellij/", 0);
+ checkZipEntry("lib/bootstrap.jar", "com/intellij/ide/", 0);
+ }
+
+ private void checkZipEntry(String jar, String entryName, int expectedSize) throws IOException {
+ ZipFile zipFile = new ZipFile(new File(myOlderDir, jar));
+ try {
+ ZipEntry entry = zipFile.getEntry(entryName);
+ assertNotNull(entry);
+ assertEquals(expectedSize, entry.getSize());
+ }
+ finally {
+ zipFile.close();
+ }
+ }
+
+ private void checkNoZipEntry(String jar, String entryName) throws IOException {
+ ZipFile zipFile = new ZipFile(new File(myOlderDir, jar));
+ try {
+ assertNull(zipFile.getEntry(entryName));
+ }
+ finally {
+ zipFile.close();
+ }
+ }
+
+ private static class MyFailOnApplyPatchAction extends PatchAction {
+ public MyFailOnApplyPatchAction() {
+ super("_dummy_file_", -1);
+ }
+
+ @Override
+ protected void doBuildPatchFile(File olderFile, File newerFile, ZipOutputStream patchOutput) throws IOException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ protected ValidationResult doValidate(File toFile) throws IOException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ protected void doApply(ZipFile patchFile, File toFile) throws IOException {
+ throw new IOException("dummy exception");
+ }
+
+ @Override
+ protected void doBackup(File toFile, File backupFile) throws IOException {
+ }
+
+ @Override
+ protected void doRevert(File toFile, File backupFile) throws IOException {
+ }
+ }
+}
--- /dev/null
+package com.intellij.updater;
+
+import com.intellij.openapi.util.io.FileUtil;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.nio.channels.FileLock;
+import java.util.*;
+
+import static org.junit.Assert.assertEquals;
+
+@SuppressWarnings("ResultOfMethodCallIgnored")
+public class PatchTest extends PatchTestCase {
+ private Patch myPatch;
+
+ @Override
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+ myPatch = new Patch(myOlderDir, myNewerDir, Collections.<String>emptyList(), Collections.<String>emptyList(),
+ Collections.<String>emptyList(), TEST_UI);
+ }
+
+ @Test
+ public void testBasics() throws Exception {
+ List<PatchAction> expectedActions = Arrays.asList(
+ new CreateAction("newDir/newFile.txt"),
+ new UpdateAction("Readme.txt", CHECKSUMS.README_TXT),
+ new UpdateZipAction("lib/annotations.jar",
+ Arrays.asList("org/jetbrains/annotations/NewClass.class"),
+ Arrays.asList("org/jetbrains/annotations/Nullable.class"),
+ Arrays.asList("org/jetbrains/annotations/TestOnly.class"),
+ CHECKSUMS.ANNOTATIONS_JAR),
+ new UpdateZipAction("lib/bootstrap.jar",
+ Collections.<String>emptyList(),
+ Collections.<String>emptyList(),
+ Arrays.asList("com/intellij/ide/ClassloaderUtil.class"),
+ CHECKSUMS.BOOTSTRAP_JAR),
+ new DeleteAction("bin/idea.bat", CHECKSUMS.IDEA_BAT));
+ List<PatchAction> actualActions = new ArrayList<PatchAction>(myPatch.getActions());
+ Collections.sort(expectedActions, COMPARATOR);
+ Collections.sort(actualActions, COMPARATOR);
+ assertEquals(expectedActions, actualActions);
+ }
+
+ @Test
+ public void testCreatingWithIgnoredFiles() throws Exception {
+ myPatch = new Patch(myOlderDir,
+ myNewerDir,
+ Arrays.asList("Readme.txt", "bin/idea.bat"),
+ Collections.<String>emptyList(),
+ Collections.<String>emptyList(),
+ TEST_UI);
+
+ List<PatchAction> expectedActions = Arrays.asList(
+ new CreateAction("newDir/newFile.txt"),
+ new UpdateZipAction("lib/annotations.jar",
+ Arrays.asList("org/jetbrains/annotations/NewClass.class"),
+ Arrays.asList("org/jetbrains/annotations/Nullable.class"),
+ Arrays.asList("org/jetbrains/annotations/TestOnly.class"),
+ CHECKSUMS.ANNOTATIONS_JAR),
+ new UpdateZipAction("lib/bootstrap.jar",
+ Collections.<String>emptyList(),
+ Collections.<String>emptyList(),
+ Arrays.asList("com/intellij/ide/ClassloaderUtil.class"),
+ CHECKSUMS.BOOTSTRAP_JAR));
+ List<PatchAction> actualActions = new ArrayList<PatchAction>(myPatch.getActions());
+ Collections.sort(expectedActions, COMPARATOR);
+ Collections.sort(actualActions, COMPARATOR);
+ assertEquals(expectedActions, actualActions);
+ }
+
+ @Test
+ public void testValidation() throws Exception {
+ FileUtil.writeToFile(new File(myOlderDir, "bin/idea.bat"), "changed".getBytes());
+ new File(myOlderDir, "extraDir").mkdirs();
+ new File(myOlderDir, "extraDir/extraFile.txt").createNewFile();
+ new File(myOlderDir, "newDir").mkdirs();
+ new File(myOlderDir, "newDir/newFile.txt").createNewFile();
+ FileUtil.writeToFile(new File(myOlderDir, "Readme.txt"), "changed".getBytes());
+ FileUtil.writeToFile(new File(myOlderDir, "lib/annotations.jar"), "changed".getBytes());
+ FileUtil.delete(new File(myOlderDir, "lib/bootstrap.jar"));
+
+ assertEquals(
+ new HashSet<ValidationResult>(Arrays.asList(
+ new ValidationResult(ValidationResult.Kind.CONFLICT,
+ "newDir/newFile.txt",
+ ValidationResult.Action.CREATE,
+ ValidationResult.ALREADY_EXISTS_MESSAGE,
+ ValidationResult.Option.REPLACE, ValidationResult.Option.KEEP),
+ new ValidationResult(ValidationResult.Kind.ERROR,
+ "Readme.txt",
+ ValidationResult.Action.UPDATE,
+ ValidationResult.MODIFIED_MESSAGE,
+ ValidationResult.Option.IGNORE),
+ new ValidationResult(ValidationResult.Kind.ERROR,
+ "lib/annotations.jar",
+ ValidationResult.Action.UPDATE,
+ ValidationResult.MODIFIED_MESSAGE,
+ ValidationResult.Option.IGNORE),
+ new ValidationResult(ValidationResult.Kind.ERROR,
+ "lib/bootstrap.jar",
+ ValidationResult.Action.UPDATE,
+ ValidationResult.ABSENT_MESSAGE,
+ ValidationResult.Option.IGNORE),
+ new ValidationResult(ValidationResult.Kind.CONFLICT,
+ "bin/idea.bat",
+ ValidationResult.Action.DELETE,
+ ValidationResult.MODIFIED_MESSAGE,
+ ValidationResult.Option.DELETE, ValidationResult.Option.KEEP))),
+ new HashSet<ValidationResult>(myPatch.validate(myOlderDir, TEST_UI)));
+ }
+
+ @Test
+ public void testValidationWithOptionalFiles() throws Exception {
+ FileUtil.writeToFile(new File(myOlderDir, "lib/annotations.jar"), "changed".getBytes());
+ assertEquals(new HashSet<ValidationResult>(Arrays.asList(
+ new ValidationResult(ValidationResult.Kind.ERROR,
+ "lib/annotations.jar",
+ ValidationResult.Action.UPDATE,
+ ValidationResult.MODIFIED_MESSAGE,
+ ValidationResult.Option.IGNORE))),
+ new HashSet<ValidationResult>(myPatch.validate(myOlderDir, TEST_UI)));
+
+ myPatch = new Patch(myOlderDir, myNewerDir, Collections.<String>emptyList(), Collections.<String>emptyList(),
+ Arrays.asList("lib/annotations.jar"), TEST_UI);
+ FileUtil.delete(new File(myOlderDir, "lib/annotations.jar"));
+ assertEquals(Collections.<ValidationResult>emptyList(),
+ myPatch.validate(myOlderDir, TEST_UI));
+ }
+
+ @Test
+ public void testValidatingNonAccessibleFiles() throws Exception {
+ File f = new File(myOlderDir, "Readme.txt");
+ FileOutputStream s = new FileOutputStream(f, true);
+ try {
+ FileLock lock = s.getChannel().lock();
+ try {
+ List<ValidationResult> result = myPatch.validate(myOlderDir, TEST_UI);
+ assertEquals(
+ new HashSet<ValidationResult>(Arrays.asList(
+ new ValidationResult(ValidationResult.Kind.ERROR,
+ "Readme.txt",
+ ValidationResult.Action.UPDATE,
+ ValidationResult.ACCESS_DENIED_MESSAGE,
+ ValidationResult.Option.IGNORE))),
+ new HashSet<ValidationResult>(result));
+ }
+ finally {
+ lock.release();
+ }
+ }
+ finally {
+ s.close();
+ }
+ }
+
+ @Test
+ public void testSaveLoad() throws Exception {
+ File f = getTempFile("file");
+ try {
+ FileOutputStream out = new FileOutputStream(f);
+ try {
+ myPatch.write(out);
+ }
+ finally {
+ out.close();
+ }
+
+ FileInputStream in = new FileInputStream(f);
+ try {
+ assertEquals(myPatch.getActions(), new Patch(in).getActions());
+ }
+ finally {
+ in.close();
+ }
+ }
+ finally {
+ f.delete();
+ }
+ }
+
+ private static final Comparator<PatchAction> COMPARATOR = new Comparator<PatchAction>() {
+ @Override
+ public int compare(PatchAction o1, PatchAction o2) {
+ return o1.toString().compareTo(o2.toString());
+ }
+ };
+}
--- /dev/null
+package com.intellij.updater;
+
+import com.intellij.openapi.util.io.FileUtil;
+
+import java.io.File;
+
+@SuppressWarnings("ResultOfMethodCallIgnored")
+public abstract class PatchTestCase extends UpdaterTestCase {
+ protected File myNewerDir;
+ protected File myOlderDir;
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ myOlderDir = getDataDir();
+ myNewerDir = getTempFile("newDir");
+ FileUtil.copyDir(myOlderDir, myNewerDir);
+
+ FileUtil.delete(new File(myNewerDir, "bin/idea.bat"));
+ FileUtil.writeToFile(new File(myNewerDir, "Readme.txt"), "hello".getBytes());
+ File newFile = new File(myNewerDir, "newDir/newFile.txt");
+ newFile.getParentFile().mkdirs();
+ newFile.createNewFile();
+ FileUtil.writeToFile(newFile, "hello".getBytes());
+
+ FileUtil.delete(new File(myOlderDir, "lib/annotations_changed.jar"));
+ FileUtil.delete(new File(myNewerDir, "lib/annotations.jar"));
+ FileUtil.rename(new File(myNewerDir, "lib/annotations_changed.jar"),
+ new File(myNewerDir, "lib/annotations.jar"));
+
+ FileUtil.delete(new File(myOlderDir, "lib/bootstrap_deleted.jar"));
+ FileUtil.delete(new File(myNewerDir, "lib/bootstrap.jar"));
+ FileUtil.rename(new File(myNewerDir, "lib/bootstrap_deleted.jar"),
+ new File(myNewerDir, "lib/bootstrap.jar"));
+
+ FileUtil.delete(new File(myOlderDir, "lib/boot2_changed_with_unchanged_content.jar"));
+ FileUtil.delete(new File(myNewerDir, "lib/boot2.jar"));
+ FileUtil.rename(new File(myNewerDir, "lib/boot2_changed_with_unchanged_content.jar"),
+ new File(myNewerDir, "lib/boot2.jar"));
+ }
+}
\ No newline at end of file
--- /dev/null
+package com.intellij.updater;
+
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+import static org.junit.Assert.assertEquals;
+
+public class RunnerTest extends UpdaterTestCase {
+ @Test
+ public void testExtractingFiles() throws Exception {
+ String[] args = {"bar", "ignored=xxx;yyy;zzz/zzz", "critical=", "ignored=aaa", "baz", "critical=ccc"};
+ Runner.initLogger();
+
+ assertEquals(Arrays.asList("xxx", "yyy", "zzz/zzz", "aaa"),
+ Runner.extractFiles(args, "ignored"));
+
+ assertEquals(Arrays.asList("ccc"),
+ Runner.extractFiles(args, "critical"));
+
+ assertEquals(Collections.<String>emptyList(),
+ Runner.extractFiles(args, "unknown"));
+ }
+}
--- /dev/null
+package com.intellij.updater;
+
+import com.intellij.openapi.application.ex.PathManagerEx;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.testFramework.fixtures.IdeaTestFixtureFactory;
+import com.intellij.testFramework.fixtures.TempDirTestFixture;
+import org.junit.After;
+import org.junit.Before;
+
+import java.io.File;
+
+public abstract class UpdaterTestCase {
+ protected static final UpdaterUI TEST_UI = new ConsoleUpdaterUI(){
+ @Override
+ public void startProcess(String title) {
+ }
+
+ @Override
+ public void setStatus(String status) {
+ }
+ };
+
+ protected CheckSums CHECKSUMS;
+ private TempDirTestFixture myTempDirFixture;
+
+ @Before
+ public void setUp() throws Exception {
+ myTempDirFixture = IdeaTestFixtureFactory.getFixtureFactory().createTempDirTestFixture();
+ myTempDirFixture.setUp();
+
+ FileUtil.copyDir(PathManagerEx.findFileUnderCommunityHome("updater/testData"), getDataDir());
+
+ boolean windowsLineEnds = new File(getDataDir(), "Readme.txt").length() == 7132;
+ CHECKSUMS = new CheckSums(windowsLineEnds);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ myTempDirFixture.tearDown();
+ Utils.cleanup();
+ }
+
+ public File getDataDir() {
+ return getTempFile("data");
+ }
+
+ public File getTempFile(String fileName) {
+ return new File(myTempDirFixture.getTempDirPath(), fileName);
+ }
+
+ protected static class CheckSums {
+ public final long README_TXT;
+ public final long IDEA_BAT;
+ public final long ANNOTATIONS_JAR;
+ public final long BOOTSTRAP_JAR;
+ public final long FOCUSKILLER_DLL;
+
+ public CheckSums(boolean windowsLineEnds) {
+ if (windowsLineEnds) {
+ README_TXT = 1272723667L;
+ IDEA_BAT = 3088608749L;
+ }
+ else {
+ README_TXT = 7256327L;
+ IDEA_BAT = 1493936069L;
+ }
+ ANNOTATIONS_JAR = 2119442657L;
+ BOOTSTRAP_JAR = 2082851308L;
+ FOCUSKILLER_DLL = 1991212227L;
+ }
+ }
+}
\ No newline at end of file
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/testSrc" isTestSource="true" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Log4J" level="project" />
+ <orderEntry type="module" module-name="testFramework" scope="TEST" />
+ <orderEntry type="library" scope="TEST" name="JUnit4" level="project" />
</component>
</module>