diff --git a/.idea/inspectionProfiles/idea_default.xml b/.idea/inspectionProfiles/idea_default.xml
index 444a31a8b67c..c40eeae6772c 100644
--- a/.idea/inspectionProfiles/idea_default.xml
+++ b/.idea/inspectionProfiles/idea_default.xml
@@ -24,6 +24,8 @@
+
+
diff --git a/bin/linux/fsnotifier b/bin/linux/fsnotifier
index df7985a5bfc2..a34b7855db4f 100755
Binary files a/bin/linux/fsnotifier and b/bin/linux/fsnotifier differ
diff --git a/bin/linux/fsnotifier64 b/bin/linux/fsnotifier64
index 9f0b3a46d2f2..812e326cd6a1 100755
Binary files a/bin/linux/fsnotifier64 and b/bin/linux/fsnotifier64 differ
diff --git a/java/execution/impl/src/com/intellij/execution/RunConfigurationExtension.java b/java/execution/impl/src/com/intellij/execution/RunConfigurationExtension.java
index 2353f470ff43..77d2b2db429d 100644
--- a/java/execution/impl/src/com/intellij/execution/RunConfigurationExtension.java
+++ b/java/execution/impl/src/com/intellij/execution/RunConfigurationExtension.java
@@ -37,7 +37,7 @@ import org.jetbrains.annotations.Nullable;
public abstract class RunConfigurationExtension extends RunConfigurationExtensionBase{
public static final ExtensionPointName EP_NAME = new ExtensionPointName("com.intellij.runConfigurationExtension");
- public abstract void updateJavaParameters(final T configuration, final JavaParameters params, RunnerSettings runnerSettings);
+ public abstract void updateJavaParameters(final T configuration, final JavaParameters params, RunnerSettings runnerSettings) throws ExecutionException;
@Override
diff --git a/lib/jsr305.jar b/lib/jsr305.jar
new file mode 100644
index 000000000000..a9afc6619b4b
Binary files /dev/null and b/lib/jsr305.jar differ
diff --git a/native/fsNotifier/linux/fsnotifier.h b/native/fsNotifier/linux/fsnotifier.h
index 0b3e52705513..0140d6be8102 100644
--- a/native/fsNotifier/linux/fsnotifier.h
+++ b/native/fsNotifier/linux/fsnotifier.h
@@ -21,6 +21,14 @@
#include
+// messaging
+typedef enum {
+ MSG_INSTANCE_LIMIT, MSG_WATCH_LIMIT
+} MSG;
+
+void message(MSG id);
+
+
// logging
void userlog(int priority, const char* format, ...);
@@ -59,8 +67,6 @@ enum {
bool init_inotify();
void set_inotify_callback(void (* callback)(char*, int));
int get_inotify_fd();
-int get_watch_count();
-bool watch_limit_reached();
int watch(const char* root, array* mounts);
void unwatch(int id);
bool process_inotify_input();
diff --git a/native/fsNotifier/linux/inotify.c b/native/fsNotifier/linux/inotify.c
index 75a97abc1339..8570d032e782 100644
--- a/native/fsNotifier/linux/inotify.c
+++ b/native/fsNotifier/linux/inotify.c
@@ -49,30 +49,18 @@ static void (* callback)(char*, int) = NULL;
#define EVENT_BUF_LEN (2048 * (EVENT_SIZE + 16))
static char event_buf[EVENT_BUF_LEN];
-
-static void read_watch_descriptors_count() {
- FILE* f = fopen(WATCH_COUNT_NAME, "r");
- if (f == NULL) {
- userlog(LOG_ERR, "can't open %s: %s", WATCH_COUNT_NAME, strerror(errno));
- return;
- }
-
- char* str = read_line(f);
- if (str == NULL) {
- userlog(LOG_ERR, "can't read from %s", WATCH_COUNT_NAME);
- }
- else {
- watch_count = atoi(str);
- }
-
- fclose(f);
-}
+static void read_watch_descriptors_count();
+static void watch_limit_reached();
bool init_inotify() {
inotify_fd = inotify_init();
if (inotify_fd < 0) {
- userlog(LOG_ERR, "inotify_init: %s", strerror(errno));
+ int e = errno;
+ userlog(LOG_ERR, "inotify_init: %s", strerror(e));
+ if (e == EMFILE) {
+ message(MSG_INSTANCE_LIMIT);
+ }
return false;
}
userlog(LOG_DEBUG, "inotify fd: %d", get_inotify_fd());
@@ -96,6 +84,24 @@ bool init_inotify() {
return true;
}
+static void read_watch_descriptors_count() {
+ FILE* f = fopen(WATCH_COUNT_NAME, "r");
+ if (f == NULL) {
+ userlog(LOG_ERR, "can't open %s: %s", WATCH_COUNT_NAME, strerror(errno));
+ return;
+ }
+
+ char* str = read_line(f);
+ if (str == NULL) {
+ userlog(LOG_ERR, "can't read from %s", WATCH_COUNT_NAME);
+ }
+ else {
+ watch_count = atoi(str);
+ }
+
+ fclose(f);
+}
+
inline void set_inotify_callback(void (* _callback)(char*, int)) {
callback = _callback;
@@ -107,16 +113,6 @@ inline int get_inotify_fd() {
}
-inline int get_watch_count() {
- return watch_count;
-}
-
-
-inline bool watch_limit_reached() {
- return limit_reached;
-}
-
-
#define EVENT_MASK IN_MODIFY | IN_ATTRIB | IN_CREATE | IN_DELETE | IN_MOVE | IN_DELETE_SELF
static int add_watch(const char* path, watch_node* parent) {
@@ -128,7 +124,7 @@ static int add_watch(const char* path, watch_node* parent) {
}
else if (errno == ENOSPC) {
userlog(LOG_WARNING, "inotify_add_watch(%s): %s", path, strerror(errno));
- limit_reached = true;
+ watch_limit_reached();
return ERR_CONTINUE;
}
else {
@@ -188,6 +184,12 @@ static int add_watch(const char* path, watch_node* parent) {
return wd;
}
+static void watch_limit_reached() {
+ if (!limit_reached) {
+ limit_reached = true;
+ message(MSG_WATCH_LIMIT);
+ }
+}
static void rm_watch(int wd, bool update_parent) {
watch_node* node = table_get(watches, wd);
diff --git a/native/fsNotifier/linux/main.c b/native/fsNotifier/linux/main.c
index 87fcf26139b9..27372e35acc1 100644
--- a/native/fsNotifier/linux/main.c
+++ b/native/fsNotifier/linux/main.c
@@ -48,8 +48,12 @@
#define HELP_MSG \
"Try 'fsnotifier --help' for more information.\n"
-#define INOTIFY_LIMIT_MSG \
- "The current inotify(7) watch limit of %d is too low. " \
+#define INSTANCE_LIMIT_TEXT \
+ "The inotify(7) instances limit reached. " \
+ "More details.\n"
+
+#define WATCH_LIMIT_TEXT \
+ "The current inotify(7) watch limit is too low. " \
"More details.\n"
typedef struct {
@@ -59,7 +63,6 @@ typedef struct {
static array* roots = NULL;
-static bool show_warning = true;
static bool self_test = false;
static void init_log();
@@ -152,6 +155,19 @@ static void init_log() {
}
+void message(MSG id) {
+ if (id == MSG_INSTANCE_LIMIT) {
+ output("MESSAGE\n" INSTANCE_LIMIT_TEXT);
+ }
+ else if (id == MSG_WATCH_LIMIT) {
+ output("MESSAGE\n" WATCH_LIMIT_TEXT);
+ }
+ else {
+ userlog(LOG_ERR, "unknown message: %d", id);
+ }
+}
+
+
void userlog(int priority, const char* format, ...) {
va_list ap;
@@ -353,12 +369,6 @@ static bool register_roots(array* new_roots, array* unwatchable, array* mounts)
return false;
}
else if (id != ERR_IGNORE) {
- if (show_warning && watch_limit_reached()) {
- int limit = get_watch_count();
- userlog(LOG_WARNING, "watch limit (%d) reached", limit);
- output("MESSAGE\n" INOTIFY_LIMIT_MSG, limit);
- show_warning = false; // warn only once
- }
CHECK_NULL(array_push(unwatchable, strdup(unflattened)), false);
}
}
diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManager.java b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManager.java
index 4d156792a1ec..323f3b955020 100644
--- a/platform/platform-impl/src/com/intellij/ide/plugins/PluginManager.java
+++ b/platform/platform-impl/src/com/intellij/ide/plugins/PluginManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -28,6 +28,8 @@ import com.intellij.notification.Notifications;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.PathManager;
+import com.intellij.openapi.application.ex.ApplicationInfoEx;
+import com.intellij.openapi.application.impl.ApplicationInfoImpl;
import com.intellij.openapi.components.ExtensionAreas;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.Extensions;
@@ -831,7 +833,11 @@ public class PluginManager {
if (ourBuildNumber == null) {
ourBuildNumber = BuildNumber.fromString(System.getProperty("idea.plugins.compatible.build"));
if (ourBuildNumber == null) {
- ourBuildNumber = BuildNumber.fromFile();
+ ApplicationInfoEx appInfo = ApplicationInfoImpl.getShadowInstance();
+ ourBuildNumber = appInfo != null ? appInfo.getBuild() : null;
+ if (ourBuildNumber == null) {
+ ourBuildNumber = BuildNumber.fallback();
+ }
}
}
return ourBuildNumber;
diff --git a/platform/platform-impl/src/com/intellij/ide/ui/AppearanceConfigurable.java b/platform/platform-impl/src/com/intellij/ide/ui/AppearanceConfigurable.java
index 9a475c352139..e2b4ded22112 100644
--- a/platform/platform-impl/src/com/intellij/ide/ui/AppearanceConfigurable.java
+++ b/platform/platform-impl/src/com/intellij/ide/ui/AppearanceConfigurable.java
@@ -21,6 +21,7 @@ import com.intellij.openapi.options.BaseConfigurable;
import com.intellij.openapi.options.SearchableConfigurable;
import com.intellij.openapi.ui.ComboBox;
import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.wm.ex.WindowManagerEx;
import com.intellij.ui.components.JBCheckBox;
import com.intellij.util.ui.UIUtil;
@@ -66,6 +67,20 @@ public class AppearanceConfigurable extends BaseConfigurable implements Searchab
myComponent.myLafComboBox.setModel(new DefaultComboBoxModel(LafManager.getInstance().getInstalledLookAndFeels()));
myComponent.myLafComboBox.setRenderer(new LafComboBoxRenderer());
+ Dictionary delayDictionary = new Hashtable();
+ delayDictionary.put(new Integer(0), new JLabel("0"));
+ delayDictionary.put(new Integer(1200), new JLabel("1200"));
+ //delayDictionary.put(new Integer(2400), new JLabel("2400"));
+ myComponent.myInitialTooltipDelaySlider.setLabelTable(delayDictionary);
+ UIUtil.setSliderIsFilled(myComponent.myInitialTooltipDelaySlider, Boolean.TRUE);
+ myComponent.myInitialTooltipDelaySlider.setMinimum(0);
+ myComponent.myInitialTooltipDelaySlider.setMaximum(1200);
+ myComponent.myInitialTooltipDelaySlider.setPaintLabels(true);
+ myComponent.myInitialTooltipDelaySlider.setPaintTicks(true);
+ myComponent.myInitialTooltipDelaySlider.setPaintTrack(true);
+ myComponent.myInitialTooltipDelaySlider.setMajorTickSpacing(1200);
+ myComponent.myInitialTooltipDelaySlider.setMinorTickSpacing(100);
+
myComponent.myEnableAlphaModeCheckBox.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
boolean state = myComponent.myEnableAlphaModeCheckBox.isSelected();
@@ -196,6 +211,11 @@ public class AppearanceConfigurable extends BaseConfigurable implements Searchab
settings.ALPHA_MODE_RATIO = ratio;
}
}
+ int tooltipDelay = Math.min(myComponent.myInitialTooltipDelaySlider.getValue(), 5000);
+ if (tooltipDelay != Registry.intValue("ide.tooltip.initialDelay")) {
+ update = true;
+ Registry.get("ide.tooltip.initialDelay").setValue(tooltipDelay);
+ }
if (update) {
settings.fireUISettingsChanged();
@@ -240,6 +260,7 @@ public class AppearanceConfigurable extends BaseConfigurable implements Searchab
myComponent.myAlphaModeRatioSlider.setValue(ratio);
myComponent.myAlphaModeRatioSlider.setToolTipText(ratio + "%");
myComponent.myAlphaModeRatioSlider.setEnabled(alphaModeEnabled && settings.ENABLE_ALPHA_MODE);
+ myComponent.myInitialTooltipDelaySlider.setValue(Registry.intValue("ide.tooltip.initialDelay"));
myComponent.updateCombo();
}
@@ -284,6 +305,9 @@ public class AppearanceConfigurable extends BaseConfigurable implements Searchab
float ratio = myComponent.myAlphaModeRatioSlider.getValue() / 100f;
isModified |= ratio != settings.ALPHA_MODE_RATIO;
}
+ int tooltipDelay = -1;
+ tooltipDelay = myComponent.myInitialTooltipDelaySlider.getValue();
+ isModified |= tooltipDelay != Registry.intValue("ide.tooltip.initialDelay");
return isModified;
}
@@ -320,9 +344,10 @@ public class AppearanceConfigurable extends BaseConfigurable implements Searchab
private JCheckBox myCbDisplayIconsInMenu;
private JCheckBox myDisableMnemonics;
private JCheckBox myDisableMnemonicInControlsCheckBox;
- private JBCheckBox myHideNavigationPopupsCheckBox;
+ private JCheckBox myHideNavigationPopupsCheckBox;
private JCheckBox myAllowMergeButtons;
private JBCheckBox myUseSmallLabelsOnTabs;
+ private JSlider myInitialTooltipDelaySlider;
public MyComponent() {
myOverrideLAFFonts.addActionListener( new ActionListener() {
diff --git a/platform/platform-impl/src/com/intellij/ide/ui/AppearancePanel.form b/platform/platform-impl/src/com/intellij/ide/ui/AppearancePanel.form
index 5153fa2eaa2c..01a66b46b136 100644
--- a/platform/platform-impl/src/com/intellij/ide/ui/AppearancePanel.form
+++ b/platform/platform-impl/src/com/intellij/ide/ui/AppearancePanel.form
@@ -16,7 +16,7 @@
-
+
@@ -147,6 +147,7 @@
+
@@ -161,14 +162,42 @@
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableExtensionPointUtil.java b/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableExtensionPointUtil.java
index a3f859887f8c..c06dbee44c1a 100644
--- a/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableExtensionPointUtil.java
+++ b/platform/platform-impl/src/com/intellij/openapi/options/ex/ConfigurableExtensionPointUtil.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2010 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -67,8 +67,12 @@ public class ConfigurableExtensionPointUtil {
final String parentId = wrapper.getParentId();
if (parentId != null) {
final ConfigurableWrapper parent = idToConfigurable.get(parentId);
- LOG.assertTrue(parent != null, "Can't find parent for " + parentId + " (" + wrapper + ")");
- idToConfigurable.put(parentId, parent.addChild(wrapper));
+ if (parent != null) {
+ idToConfigurable.put(parentId, parent.addChild(wrapper));
+ }
+ else {
+ LOG.error("Can't find parent for " + parentId + " (" + wrapper + ")");
+ }
}
}
//leave only roots (i.e. configurables without parents)
diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/FileWatcher.java b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/FileWatcher.java
index 9e8750d079cc..20ee724be726 100644
--- a/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/FileWatcher.java
+++ b/platform/platform-impl/src/com/intellij/openapi/vfs/impl/local/FileWatcher.java
@@ -41,7 +41,6 @@ import java.io.File;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.*;
-import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import static com.intellij.util.containers.ContainerUtil.*;
@@ -81,44 +80,30 @@ public class FileWatcher {
private final ManagingFS myManagingFS;
private final File myExecutable;
- private final AtomicBoolean myInitialized = new AtomicBoolean(false);
private volatile MyProcessHandler myProcessHandler;
private volatile int myStartAttemptCount = 0;
private volatile boolean myIsShuttingDown = false;
private volatile boolean myFailureShownToTheUser = false;
private final AtomicInteger mySettingRoots = new AtomicInteger(0);
- private final ModalityState myDefaultModalityState;
/** @deprecated use {@linkplain com.intellij.openapi.vfs.impl.local.LocalFileSystemImpl#getFileWatcher()} (to remove in IDEA 13) */
public static FileWatcher getInstance() {
return ((LocalFileSystemImpl)LocalFileSystem.getInstance()).getFileWatcher();
}
- FileWatcher(@NotNull final ManagingFS managingFS) {
+ FileWatcher(@NotNull ManagingFS managingFS) {
myManagingFS = managingFS;
- // eager initialization to avoid deadlock during component initialization (PY-8724)
- myDefaultModalityState = ModalityState.defaultModalityState();
-
boolean disabled = Boolean.parseBoolean(System.getProperty(PROPERTY_WATCHER_DISABLED));
myExecutable = getExecutable();
if (disabled) {
- myInitialized.set(true);
LOG.info("Native file watcher is disabled");
}
else if (myExecutable == null) {
- myInitialized.set(true);
LOG.info("Native file watcher is not supported on this platform");
}
- }
-
- private void init() {
- if (!myInitialized.compareAndSet(false, true)) {
- return;
- }
-
- if (!myExecutable.exists()) {
+ else if (!myExecutable.exists()) {
notifyOnFailure(ApplicationBundle.message("watcher.exe.not.found"), null);
}
else if (!myExecutable.canExecute()) {
@@ -188,7 +173,7 @@ public class FileWatcher {
private static boolean isUpToDate(File executable) {
long length = SystemInfo.isWindows ? 70216 :
SystemInfo.isMac ? 13924 :
- SystemInfo.isLinux ? SystemInfo.isAMD64 ? 29308 : 22809 :
+ SystemInfo.isLinux ? SystemInfo.isAMD64 ? 29227 : 22734 :
-1;
return length < 0 || length == executable.length();
}
@@ -203,7 +188,7 @@ public class FileWatcher {
String title = ApplicationBundle.message("watcher.slow.sync");
Notifications.Bus.notify(NOTIFICATION_GROUP.getValue().createNotification(title, cause, NotificationType.WARNING, listener));
}
- }, myDefaultModalityState);
+ }, ModalityState.NON_MODAL);
}
}
@@ -256,7 +241,7 @@ public class FileWatcher {
}
public boolean isOperational() {
- return !myInitialized.get() || myProcessHandler != null;
+ return myProcessHandler != null;
}
public boolean isSettingRoots() {
@@ -292,7 +277,6 @@ public class FileWatcher {
}
public void setWatchRoots(final List recursive, final List flat) {
- init();
setWatchRoots(recursive, flat, false);
}
diff --git a/platform/platform-tests/testSrc/com/intellij/util/StringBuilderSpinAllocatorTest.java b/platform/platform-tests/testSrc/com/intellij/util/StringBuilderSpinAllocatorTest.java
index 499c55578e48..ac61b53a5717 100644
--- a/platform/platform-tests/testSrc/com/intellij/util/StringBuilderSpinAllocatorTest.java
+++ b/platform/platform-tests/testSrc/com/intellij/util/StringBuilderSpinAllocatorTest.java
@@ -1,12 +1,26 @@
+/*
+ * Copyright 2000-2013 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 com.intellij.util;
-import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
public class StringBuilderSpinAllocatorTest {
-
private final String[] myStrings = new String[]{
"First String is the smallest",
"Second String is definitely larger than the first one",
@@ -14,17 +28,20 @@ public class StringBuilderSpinAllocatorTest {
"Fourth String is the largest amongst all the myStrings. Congrats! It must be even larger than it is."
};
- @Before
- public void setUp() throws Exception {
- // warm-up
- new StringBuilder();
- StringBuilderSpinAllocator.dispose(StringBuilderSpinAllocator.alloc());
+ @Test
+ public void testPerformance() {
+ assumeTrue(!com.intellij.testFramework.PlatformTestUtil.COVERAGE_ENABLED_BUILD);
+ doTest(true);
+ doTest(false);
}
- @Test
- public void testPerformance() throws InterruptedException {
+ private void doTest(boolean warmUp) {
StringBuilder builder;
- final int count = 1000000;
+ int count = warmUp ? 1000 : 1000000;
+
+ System.gc();
+ System.runFinalization();
+ TimeoutUtil.sleep(1000);
long start = System.nanoTime();
for (int i = 0; i < count; ++i) {
@@ -32,12 +49,11 @@ public class StringBuilderSpinAllocatorTest {
builder.append(myStrings[i & 3]);
builder.append(builder.toString());
}
- final long regularTime = (System.nanoTime() - start)/1000;
- System.out.println("StringBuilder regular allocations took: " + regularTime);
+ long regularTime = (System.nanoTime() - start) / 1000;
System.gc();
System.runFinalization();
- Thread.sleep(2000);
+ TimeoutUtil.sleep(1000);
start = System.nanoTime();
for (int i = 0; i < count; ++i) {
@@ -46,10 +62,11 @@ public class StringBuilderSpinAllocatorTest {
builder.append(builder.toString());
StringBuilderSpinAllocator.dispose(builder);
}
- final long spinTime = (System.nanoTime() - start)/1000;
- System.out.println("StringBuilder spin allocations took: " + spinTime);
+ long spinTime = (System.nanoTime() - start) / 1000;
- if (!com.intellij.testFramework.PlatformTestUtil.COVERAGE_ENABLED_BUILD) {
+ if (!warmUp) {
+ System.out.println("StringBuilder regular allocations took: " + regularTime);
+ System.out.println("StringBuilder spin allocations took: " + spinTime);
assertTrue("regular:" + regularTime + "mks, spin:" + spinTime + "mks", spinTime < regularTime);
}
}
diff --git a/platform/util/src/com/intellij/openapi/util/BuildNumber.java b/platform/util/src/com/intellij/openapi/util/BuildNumber.java
index 4212c34484be..363771bb644a 100644
--- a/platform/util/src/com/intellij/openapi/util/BuildNumber.java
+++ b/platform/util/src/com/intellij/openapi/util/BuildNumber.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -13,10 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-/*
- * @author max
- */
package com.intellij.openapi.util;
import com.intellij.openapi.application.PathManager;
@@ -27,8 +23,14 @@ import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
+/**
+ * @author max
+ */
public class BuildNumber implements Comparable {
private static final String BUILD_NUMBER = "__BUILD_NUMBER__";
+ private static final String SNAPSHOT = "SNAPSHOT";
+ private static final String FALLBACK_VERSION = "999.SNAPSHOT";
+
private static final int TOP_BASELINE_VERSION = fromFile().getBaselineVersion();
private final String myProductCode;
@@ -42,7 +44,7 @@ public class BuildNumber implements Comparable {
}
public String asString() {
- return asString(true);
+ return asString(true);
}
public String asStringWithoutProductCode() {
@@ -51,10 +53,9 @@ public class BuildNumber implements Comparable {
private String asString(boolean includeProductCode) {
StringBuilder builder = new StringBuilder();
- if (includeProductCode) {
- if (!StringUtil.isEmpty(myProductCode)) {
- builder.append(myProductCode).append('-');
- }
+
+ if (includeProductCode && !StringUtil.isEmpty(myProductCode)) {
+ builder.append(myProductCode).append('-');
}
builder.append(myBaselineVersion).append('.');
@@ -63,7 +64,7 @@ public class BuildNumber implements Comparable {
builder.append(myBuildNumber);
}
else {
- builder.append("SNAPSHOT");
+ builder.append(SNAPSHOT);
}
return builder.toString();
@@ -103,7 +104,7 @@ public class BuildNumber implements Comparable {
code = code.substring(baselineVersionSeparator + 1);
}
catch (NumberFormatException e) {
- throw new RuntimeException("Unparseable version number: " + version + "; plugin name: " + name);
+ throw new RuntimeException("Invalid version number: " + version + "; plugin name: " + name);
}
buildNumber = parseBuildNumber(version, code, name);
@@ -123,29 +124,34 @@ public class BuildNumber implements Comparable {
}
private static int parseBuildNumber(String version, String code, String name) {
- if ("SNAPSHOT".equals(code) || BUILD_NUMBER.equals(code)) {
+ if (SNAPSHOT.equals(code) || BUILD_NUMBER.equals(code)) {
return Integer.MAX_VALUE;
}
try {
return Integer.parseInt(code);
}
catch (NumberFormatException e) {
- throw new RuntimeException("Unparseable version number: " + version +"; plugin name: " + name);
+ throw new RuntimeException("Invalid version number: " + version + "; plugin name: " + name);
}
}
- public static BuildNumber fromFile() {
- String text = "999.SNAPSHOT";
+ private static BuildNumber fromFile() {
try {
final String homePath = PathManager.getHomePath();
final File buildTxtFile = FileUtil.findFirstThatExist(homePath + "/build.txt", homePath + "/community/build.txt");
if (buildTxtFile != null) {
- text = FileUtil.loadFile(buildTxtFile).trim();
+ String text = FileUtil.loadFile(buildTxtFile).trim();
+ return fromString(text);
}
}
- catch (IOException ignored) { }
+ catch (IOException ignored) {
+ }
- return fromString(text);
+ return fallback();
+ }
+
+ public static BuildNumber fallback() {
+ return fromString(FALLBACK_VERSION);
}
@Override
@@ -197,6 +203,7 @@ public class BuildNumber implements Comparable {
if (bn == Integer.MAX_VALUE) {
return TOP_BASELINE_VERSION; // SNAPSHOTS
}
+
if (bn >= 10000) {
return 88; // Maia, 9x builds
}
diff --git a/platform/util/testSrc/com/intellij/openapi/util/BuildNumberTest.java b/platform/util/testSrc/com/intellij/openapi/util/BuildNumberTest.java
index ed5a3a0b16bd..445bb4180d04 100644
--- a/platform/util/testSrc/com/intellij/openapi/util/BuildNumberTest.java
+++ b/platform/util/testSrc/com/intellij/openapi/util/BuildNumberTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2013 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.
@@ -13,20 +13,24 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-/*
- * @author max
- */
package com.intellij.openapi.util;
-import junit.framework.TestCase;
+import org.junit.Test;
-public class BuildNumberTest extends TestCase {
- public void testHistoricBuild() {
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * @author max
+ */
+public class BuildNumberTest {
+ @Test
+ public void historicBuild() {
assertEquals(new BuildNumber("", 75, 7512), BuildNumber.fromString("7512"));
}
-
- public void testSnapshotDominates() {
+
+ @Test
+ public void snapshotDomination() {
assertTrue(BuildNumber.fromString("90.SNAPSHOT").compareTo(BuildNumber.fromString("90.12345")) > 0);
assertTrue(BuildNumber.fromString("IU-90.SNAPSHOT").compareTo(BuildNumber.fromString("RM-90.12345")) > 0);
}