diff --git a/bin/idea.properties b/bin/idea.properties index a9cd05389fd5..9e8524cd8523 100644 --- a/bin/idea.properties +++ b/bin/idea.properties @@ -1,4 +1,4 @@ -# Use ${idea.home} macro to specify location relative to IDE installation home. +# Use ${idea.home.path} macro to specify location relative to IDE installation home. # 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 (e.g. c:/idea/system). diff --git a/build/conf/ideaCE64-launcher.properties b/build/conf/ideaCE64-launcher.properties index 2277afab3863..0567cc288251 100644 --- a/build/conf/ideaCE64-launcher.properties +++ b/build/conf/ideaCE64-launcher.properties @@ -4,5 +4,5 @@ IDS_APP_TITLE=__IDE-NAME__ Launcher IDS_VM_OPTIONS_PATH=%USERPROFILE%\\.__PRODUCT_PATHS_SELECTOR__ IDC_WINLAUNCHER=__IDE-NAME___LAUNCHER IDS_PROPS_ENV_VAR=__IDE-NAME___PROPERTIES -IDS_VM_OPTIONS_ENV_VAR=__IDE-NAME___VM_OPTIONS +IDS_VM_OPTIONS_ENV_VAR=__IDE-NAME__64_VM_OPTIONS IDS_ERROR_LAUNCHING_APP=Error launching __IDE-NAME__ diff --git a/platform/diff-api/src/com/intellij/diff/util/Side.java b/platform/diff-api/src/com/intellij/diff/util/Side.java index f24d5d04dec9..6b23d409f484 100644 --- a/platform/diff-api/src/com/intellij/diff/util/Side.java +++ b/platform/diff-api/src/com/intellij/diff/util/Side.java @@ -70,7 +70,7 @@ public enum Side { } @NotNull - public T selectN(@NotNull T left, @NotNull T right) { + public T selectNotNull(@NotNull T left, @NotNull T right) { return isLeft() ? left : right; } @@ -86,7 +86,7 @@ public enum Side { } @NotNull - public T selectN(@NotNull T[] array) { + public T selectNotNull(@NotNull T[] array) { assert array.length == 2; return array[myIndex]; } @@ -98,7 +98,7 @@ public enum Side { } @NotNull - public T selectN(@NotNull List list) { + public T selectNotNull(@NotNull List list) { assert list.size() == 2; return list.get(myIndex); } @@ -109,7 +109,7 @@ public enum Side { } @NotNull - public T selectN(@NotNull Couple region) { + public T selectNotNull(@NotNull Couple region) { return isLeft() ? region.first : region.second; } diff --git a/platform/diff-api/src/com/intellij/diff/util/ThreeSide.java b/platform/diff-api/src/com/intellij/diff/util/ThreeSide.java index 4defc2458c4a..9ac735d67101 100644 --- a/platform/diff-api/src/com/intellij/diff/util/ThreeSide.java +++ b/platform/diff-api/src/com/intellij/diff/util/ThreeSide.java @@ -48,7 +48,7 @@ public enum ThreeSide { } @NotNull - public T selectN(@NotNull T left, @NotNull T base, @NotNull T right) { + public T selectNotNull(@NotNull T left, @NotNull T base, @NotNull T right) { if (myIndex == 0) return left; if (myIndex == 1) return base; if (myIndex == 2) return right; @@ -67,7 +67,7 @@ public enum ThreeSide { } @NotNull - public T selectN(@NotNull T[] array) { + public T selectNotNull(@NotNull T[] array) { assert array.length == 3; return array[myIndex]; } @@ -79,7 +79,7 @@ public enum ThreeSide { } @NotNull - public T selectN(@NotNull List list) { + public T selectNotNull(@NotNull List list) { assert list.size() == 3; return list.get(myIndex); } diff --git a/platform/diff-impl/src/com/intellij/diff/comparison/MergeUtil.java b/platform/diff-impl/src/com/intellij/diff/comparison/MergeUtil.java index 297345cf1f8b..88ea7ea4fabd 100644 --- a/platform/diff-impl/src/com/intellij/diff/comparison/MergeUtil.java +++ b/platform/diff-impl/src/com/intellij/diff/comparison/MergeUtil.java @@ -241,7 +241,7 @@ public class MergeUtil { @NotNull private Interval getRange(@NotNull ThreeSide side) { - return side.selectN(myLeft, myBase, myRight); + return side.selectNotNull(myLeft, myBase, myRight); } public int getStartLine(@NotNull ThreeSide side) { diff --git a/platform/diff-impl/src/com/intellij/diff/impl/DiffRequestProcessor.java b/platform/diff-impl/src/com/intellij/diff/impl/DiffRequestProcessor.java index bd28e91bb79a..8f3f8dbc9935 100644 --- a/platform/diff-impl/src/com/intellij/diff/impl/DiffRequestProcessor.java +++ b/platform/diff-impl/src/com/intellij/diff/impl/DiffRequestProcessor.java @@ -583,6 +583,11 @@ public abstract class DiffRequestProcessor implements Disposable { protected class MyNextDifferenceAction extends NextDifferenceAction { @Override public void update(@NotNull AnActionEvent e) { + if (!ActionPlaces.DIFF_TOOLBAR.equals(e.getPlace())) { + e.getPresentation().setEnabledAndVisible(true); + return; + } + PrevNextDifferenceIterable iterable = DiffDataKeys.PREV_NEXT_DIFFERENCE_ITERABLE.getData(e.getDataContext()); if (iterable != null && iterable.canGoNext()) { e.getPresentation().setEnabled(true); @@ -606,6 +611,8 @@ public abstract class DiffRequestProcessor implements Disposable { return; } + if (!isNavigationEnabled() || !hasNextChange()) return; + if (myIterationState != IterationState.NEXT) { // TODO: provide "change" word in chain UserData - for tests/etc if (iterable != null) iterable.notify("Press again to go to the next file"); @@ -620,6 +627,11 @@ public abstract class DiffRequestProcessor implements Disposable { protected class MyPrevDifferenceAction extends PrevDifferenceAction { @Override public void update(@NotNull AnActionEvent e) { + if (!ActionPlaces.DIFF_TOOLBAR.equals(e.getPlace())) { + e.getPresentation().setEnabledAndVisible(true); + return; + } + PrevNextDifferenceIterable iterable = DiffDataKeys.PREV_NEXT_DIFFERENCE_ITERABLE.getData(e.getDataContext()); if (iterable != null && iterable.canGoPrev()) { e.getPresentation().setEnabled(true); @@ -643,6 +655,8 @@ public abstract class DiffRequestProcessor implements Disposable { return; } + if (!isNavigationEnabled() || !hasNextChange()) return; + if (myIterationState != IterationState.PREV) { if (iterable != null) iterable.notify("Press again to go to the previous file"); myIterationState = IterationState.PREV; diff --git a/platform/diff-impl/src/com/intellij/diff/tools/binary/BinaryDiffViewer.java b/platform/diff-impl/src/com/intellij/diff/tools/binary/BinaryDiffViewer.java index 1212b1e98cb2..2c41f656e79c 100644 --- a/platform/diff-impl/src/com/intellij/diff/tools/binary/BinaryDiffViewer.java +++ b/platform/diff-impl/src/com/intellij/diff/tools/binary/BinaryDiffViewer.java @@ -388,7 +388,7 @@ public class BinaryDiffViewer extends ListenerDiffViewerBase { FileEditor editor = getCurrentEditor(); if (editor == null) return null; - DiffContent content = getCurrentSide().selectN(request.getContents()); + DiffContent content = getCurrentSide().selectNotNull(request.getContents()); return content.getOpenFileDescriptor(); } diff --git a/platform/diff-impl/src/com/intellij/diff/tools/fragmented/OnesideDiffViewer.java b/platform/diff-impl/src/com/intellij/diff/tools/fragmented/OnesideDiffViewer.java index 4d33882cdedc..f28c0624a14a 100644 --- a/platform/diff-impl/src/com/intellij/diff/tools/fragmented/OnesideDiffViewer.java +++ b/platform/diff-impl/src/com/intellij/diff/tools/fragmented/OnesideDiffViewer.java @@ -1009,7 +1009,7 @@ public class OnesideDiffViewer extends TextDiffViewerBase { myShouldScroll = !doScrollToContext(myNavigationContext); } if (myShouldScroll && myCaretPosition != null && myCaretPosition.length == 2) { - LogicalPosition twosidePosition = myMasterSide.selectN(myCaretPosition); + LogicalPosition twosidePosition = myMasterSide.selectNotNull(myCaretPosition); int onesideLine = transferLineToOneside(myMasterSide, twosidePosition.line); LogicalPosition position = new LogicalPosition(onesideLine, twosidePosition.column); diff --git a/platform/diff-impl/src/com/intellij/diff/tools/fragmented/OnesideEditorHighlighter.java b/platform/diff-impl/src/com/intellij/diff/tools/fragmented/OnesideEditorHighlighter.java index a35ddc59cb51..26e72197bad7 100644 --- a/platform/diff-impl/src/com/intellij/diff/tools/fragmented/OnesideEditorHighlighter.java +++ b/platform/diff-impl/src/com/intellij/diff/tools/fragmented/OnesideEditorHighlighter.java @@ -69,7 +69,7 @@ public class OnesideEditorHighlighter implements EditorHighlighter { offset = base.getStartOffset(); } - HighlighterIterator it = range.getSide().selectN(it1, it2); + HighlighterIterator it = range.getSide().selectNotNull(it1, it2); while (!it.atEnd() && changed.getStartOffset() >= it.getEnd()) { it.advance(); } diff --git a/platform/diff-impl/src/com/intellij/diff/tools/fragmented/OnesideFragmentBuilder.java b/platform/diff-impl/src/com/intellij/diff/tools/fragmented/OnesideFragmentBuilder.java index 3cd29271d342..07ba5cc7f2b7 100644 --- a/platform/diff-impl/src/com/intellij/diff/tools/fragmented/OnesideFragmentBuilder.java +++ b/platform/diff-impl/src/com/intellij/diff/tools/fragmented/OnesideFragmentBuilder.java @@ -145,7 +145,7 @@ public class OnesideFragmentBuilder { } private void appendText(@NotNull Side side, int offset1, int offset2, int lines, int startLine1, int startLine2) { - Document document = side.selectN(myDocument1, myDocument2); + Document document = side.selectNotNull(myDocument1, myDocument2); int newline = document.getTextLength() > offset2 + 1 ? 1 : 0; TextRange base = new TextRange(myBuilder.length(), myBuilder.length() + offset2 - offset1 + newline); diff --git a/platform/diff-impl/src/com/intellij/diff/tools/simple/SimpleDiffChange.java b/platform/diff-impl/src/com/intellij/diff/tools/simple/SimpleDiffChange.java index 3a0337f09a91..b70286d2e074 100644 --- a/platform/diff-impl/src/com/intellij/diff/tools/simple/SimpleDiffChange.java +++ b/platform/diff-impl/src/com/intellij/diff/tools/simple/SimpleDiffChange.java @@ -228,9 +228,9 @@ public class SimpleDiffChange { final Document document1 = myEditor1.getDocument(); final Document document2 = myEditor2.getDocument(); - DiffUtil.applyModification(sourceSide.other().selectN(document1, document2), + DiffUtil.applyModification(sourceSide.other().selectNotNull(document1, document2), getStartLine(sourceSide.other()), getEndLine(sourceSide.other()), - sourceSide.selectN(document1, document2), + sourceSide.selectNotNull(document1, document2), getStartLine(sourceSide), getEndLine(sourceSide)); destroyHighlighter(); @@ -246,9 +246,9 @@ public class SimpleDiffChange { final Document document1 = myEditor1.getDocument(); final Document document2 = myEditor2.getDocument(); - DiffUtil.applyModification(sourceSide.other().selectN(document1, document2), + DiffUtil.applyModification(sourceSide.other().selectNotNull(document1, document2), getEndLine(sourceSide.other()), getEndLine(sourceSide.other()), - sourceSide.selectN(document1, document2), + sourceSide.selectNotNull(document1, document2), getStartLine(sourceSide), getEndLine(sourceSide)); destroyHighlighter(); @@ -262,7 +262,7 @@ public class SimpleDiffChange { private MyGutterOperation createOperation(@NotNull Side side) { assert myEditor1 != null && myEditor2 != null; int offset = side.getStartOffset(myFragment); - EditorEx editor = side.selectN(myEditor1, myEditor2); + EditorEx editor = side.selectNotNull(myEditor1, myEditor2); RangeHighlighter highlighter = editor.getMarkupModel().addRangeHighlighter(offset, offset, HighlighterLayer.ADDITIONAL_SYNTAX, null, @@ -303,8 +303,8 @@ public class SimpleDiffChange { myCtrlPressed = myViewer.getModifierProvider().isCtrlPressed(); myShiftPressed = myViewer.getModifierProvider().isShiftPressed(); - boolean isEditable = DiffUtil.isEditable(mySide.selectN(myEditor1, myEditor2)); - boolean isOtherEditable = DiffUtil.isEditable(mySide.other().selectN(myEditor1, myEditor2)); + boolean isEditable = DiffUtil.isEditable(mySide.selectNotNull(myEditor1, myEditor2)); + boolean isOtherEditable = DiffUtil.isEditable(mySide.other().selectNotNull(myEditor1, myEditor2)); if (myCtrlPressed && myShiftPressed) return null; if ((myShiftPressed || !isOtherEditable) && isEditable) { @@ -350,7 +350,7 @@ public class SimpleDiffChange { @Nullable private GutterIconRenderer createIconRenderer(@NotNull final Side sourceSide, @NotNull final Icon icon, @NotNull final Runnable perform) { assert myEditor1 != null && myEditor2 != null; - if (!DiffUtil.isEditable(sourceSide.other().selectN(myEditor1, myEditor2))) return null; + if (!DiffUtil.isEditable(sourceSide.other().selectNotNull(myEditor1, myEditor2))) return null; return new GutterIconRenderer() { @NotNull @Override @@ -372,7 +372,7 @@ public class SimpleDiffChange { if (!myIsValid) return; - DiffUtil.executeWriteCommand(sourceSide.other().selectN(document1, document2), project, "Replace change", new Runnable() { + DiffUtil.executeWriteCommand(sourceSide.other().selectNotNull(document1, document2), project, "Replace change", new Runnable() { @Override public void run() { perform.run(); diff --git a/platform/diff-impl/src/com/intellij/diff/tools/simple/SimpleDiffViewer.java b/platform/diff-impl/src/com/intellij/diff/tools/simple/SimpleDiffViewer.java index 860745320afb..f8e35d04d250 100644 --- a/platform/diff-impl/src/com/intellij/diff/tools/simple/SimpleDiffViewer.java +++ b/platform/diff-impl/src/com/intellij/diff/tools/simple/SimpleDiffViewer.java @@ -608,7 +608,7 @@ public class SimpleDiffViewer extends TwosideTextDiffViewer { return; } - Editor modifiedEditor = side.other(myModifyOpposite).selectN(myEditor1, myEditor2); + Editor modifiedEditor = side.other(myModifyOpposite).selectNotNull(myEditor1, myEditor2); if (!DiffUtil.isEditable(modifiedEditor)) { e.getPresentation().setEnabledAndVisible(false); return; @@ -626,7 +626,7 @@ public class SimpleDiffViewer extends TwosideTextDiffViewer { final Side side = Side.fromLeft(editor == myEditor1); final List selectedChanges = getSelectedChanges(side); - Editor modifiedEditor = side.other(myModifyOpposite).selectN(myEditor1, myEditor2); + Editor modifiedEditor = side.other(myModifyOpposite).selectNotNull(myEditor1, myEditor2); String title = e.getPresentation().getText() + " selected changes"; DiffUtil.executeWriteCommand(modifiedEditor.getDocument(), e.getProject(), title, new Runnable() { @Override diff --git a/platform/diff-impl/src/com/intellij/diff/tools/simple/SimpleThreesideDiffChange.java b/platform/diff-impl/src/com/intellij/diff/tools/simple/SimpleThreesideDiffChange.java index 12cad991df6d..8bae87e66ec7 100644 --- a/platform/diff-impl/src/com/intellij/diff/tools/simple/SimpleThreesideDiffChange.java +++ b/platform/diff-impl/src/com/intellij/diff/tools/simple/SimpleThreesideDiffChange.java @@ -81,7 +81,7 @@ public class SimpleThreesideDiffChange { // private void createHighlighter(@NotNull ThreeSide side) { - Editor editor = side.selectN(myEditors); + Editor editor = side.selectNotNull(myEditors); Document document = editor.getDocument(); TextDiffType type = getDiffType(); @@ -208,7 +208,7 @@ public class SimpleThreesideDiffChange { private static CharSequence getRangeContent(@NotNull MergeLineFragment fragment, @NotNull List editors, @NotNull ThreeSide side) { - DocumentEx document = side.selectN(editors).getDocument(); + DocumentEx document = side.selectNotNull(editors).getDocument(); int line1 = fragment.getStartLine(side); int line2 = fragment.getEndLine(side); return DiffUtil.getLinesContent(document, line1, line2); diff --git a/platform/diff-impl/src/com/intellij/diff/tools/simple/SimpleThreesideDiffViewer.java b/platform/diff-impl/src/com/intellij/diff/tools/simple/SimpleThreesideDiffViewer.java index 2bd11c1f3351..2cc638633ee6 100644 --- a/platform/diff-impl/src/com/intellij/diff/tools/simple/SimpleThreesideDiffViewer.java +++ b/platform/diff-impl/src/com/intellij/diff/tools/simple/SimpleThreesideDiffViewer.java @@ -391,7 +391,7 @@ public class SimpleThreesideDiffViewer extends ThreesideTextDiffViewer { @NotNull @Override protected SyncScrollSupport.SyncScrollable getSyncScrollable(@NotNull Side side) { - return side.selectN(mySyncScrollable1, mySyncScrollable2); + return side.selectNotNull(mySyncScrollable1, mySyncScrollable2); } @NotNull @@ -548,15 +548,15 @@ public class SimpleThreesideDiffViewer extends ThreesideTextDiffViewer { @Override protected void processHelper(@NotNull ScrollHelper helper) { - ThreeSide left = mySide.selectN(ThreeSide.LEFT, ThreeSide.BASE); - ThreeSide right = mySide.selectN(ThreeSide.BASE, ThreeSide.RIGHT); + ThreeSide left = mySide.selectNotNull(ThreeSide.LEFT, ThreeSide.BASE); + ThreeSide right = mySide.selectNotNull(ThreeSide.BASE, ThreeSide.RIGHT); if (!helper.process(0, 0)) return; for (SimpleThreesideDiffChange diffChange : myDiffChanges) { if (!helper.process(diffChange.getStartLine(left), diffChange.getStartLine(right))) return; if (!helper.process(diffChange.getEndLine(left), diffChange.getEndLine(right))) return; } - helper.process(left.selectN(myEditors).getDocument().getLineCount(), right.selectN(myEditors).getDocument().getLineCount()); + helper.process(left.selectNotNull(myEditors).getDocument().getLineCount(), right.selectNotNull(myEditors).getDocument().getLineCount()); } } @@ -569,8 +569,8 @@ public class SimpleThreesideDiffViewer extends ThreesideTextDiffViewer { @Override public void process(@NotNull Handler handler) { - ThreeSide left = mySide.selectN(ThreeSide.LEFT, ThreeSide.BASE); - ThreeSide right = mySide.selectN(ThreeSide.BASE, ThreeSide.RIGHT); + ThreeSide left = mySide.selectNotNull(ThreeSide.LEFT, ThreeSide.BASE); + ThreeSide right = mySide.selectNotNull(ThreeSide.BASE, ThreeSide.RIGHT); for (SimpleThreesideDiffChange diffChange : myDiffChanges) { if (!diffChange.getType().isChange(mySide)) continue; @@ -596,8 +596,8 @@ public class SimpleThreesideDiffViewer extends ThreesideTextDiffViewer { public void paint(@NotNull Graphics g, @NotNull Component divider) { Graphics2D gg = getDividerGraphics(g, divider); - Editor editor1 = mySide.selectN(myEditors.get(0), myEditors.get(1)); - Editor editor2 = mySide.selectN(myEditors.get(1), myEditors.get(2)); + Editor editor1 = mySide.selectNotNull(myEditors.get(0), myEditors.get(1)); + Editor editor2 = mySide.selectNotNull(myEditors.get(1), myEditors.get(2)); //DividerPolygonUtil.paintSimplePolygons(gg, divider.getWidth(), editor1, editor2, myPaintable); DiffDividerDrawUtil.paintPolygons(gg, divider.getWidth(), editor1, editor2, myPaintable); diff --git a/platform/diff-impl/src/com/intellij/diff/tools/util/FoldingModelSupport.java b/platform/diff-impl/src/com/intellij/diff/tools/util/FoldingModelSupport.java index de41870c03b8..f6ee8536f745 100644 --- a/platform/diff-impl/src/com/intellij/diff/tools/util/FoldingModelSupport.java +++ b/platform/diff-impl/src/com/intellij/diff/tools/util/FoldingModelSupport.java @@ -264,7 +264,7 @@ public class FoldingModelSupport { } public void paintOnDivider(@NotNull Graphics2D gg, @NotNull Component divider, @NotNull Side side) { - MyPaintable paintable = side.selectN(myPaintable1, myPaintable2); + MyPaintable paintable = side.selectNotNull(myPaintable1, myPaintable2); paintable.paintOnDivider(gg, divider); } diff --git a/platform/diff-impl/src/com/intellij/diff/tools/util/threeside/ThreesideTextDiffViewer.java b/platform/diff-impl/src/com/intellij/diff/tools/util/threeside/ThreesideTextDiffViewer.java index 6762d3c5efbe..c4a89d7fc6e8 100644 --- a/platform/diff-impl/src/com/intellij/diff/tools/util/threeside/ThreesideTextDiffViewer.java +++ b/platform/diff-impl/src/com/intellij/diff/tools/util/threeside/ThreesideTextDiffViewer.java @@ -254,7 +254,7 @@ public abstract class ThreesideTextDiffViewer extends TextDiffViewerBase { @NotNull public EditorEx getCurrentEditor() { - return myCurrentSide.selectN(myEditors); + return myCurrentSide.selectNotNull(myEditors); } @NotNull @@ -274,7 +274,7 @@ public abstract class ThreesideTextDiffViewer extends TextDiffViewerBase { @CalledInAwt protected void scrollToLine(@NotNull ThreeSide side, int line) { - Editor editor = side.selectN(myEditors); + Editor editor = side.selectNotNull(myEditors); DiffUtil.scrollEditor(editor, line); myCurrentSide = side; } @@ -301,7 +301,7 @@ public abstract class ThreesideTextDiffViewer extends TextDiffViewerBase { protected OpenFileDescriptor getOpenFileDescriptor() { EditorEx editor = getCurrentEditor(); - DocumentContent content = getCurrentSide().selectN(myActualContents); + DocumentContent content = getCurrentSide().selectNotNull(myActualContents); int offset = editor.getCaretModel().getOffset(); return content.getOpenFileDescriptor(offset); @@ -363,8 +363,8 @@ public abstract class ThreesideTextDiffViewer extends TextDiffViewerBase { DiffContent[] contents = myRequest.getContents(); String[] titles = myRequest.getContentTitles(); - DiffRequest request = new SimpleDiffRequest(myRequest.getTitle(), mySide1.selectN(contents), mySide2.selectN(contents), - mySide1.selectN(titles), mySide1.selectN(titles)); + DiffRequest request = new SimpleDiffRequest(myRequest.getTitle(), mySide1.selectNotNull(contents), mySide2.selectNotNull(contents), + mySide1.selectNotNull(titles), mySide1.selectNotNull(titles)); DiffManager.getInstance().showDiff(myProject, request, new DiffDialogHints(null, myPanel)); } } diff --git a/platform/util/src/com/intellij/openapi/application/PathManager.java b/platform/util/src/com/intellij/openapi/application/PathManager.java index 5b855cb0137d..8b2e4eccd337 100644 --- a/platform/util/src/com/intellij/openapi/application/PathManager.java +++ b/platform/util/src/com/intellij/openapi/application/PathManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2015 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,39 +28,47 @@ import gnu.trove.THashSet; import org.apache.log4j.Appender; import org.apache.oro.text.regex.PatternMatcher; import org.jdom.Document; -import org.jetbrains.annotations.*; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.picocontainer.PicoContainer; import java.io.*; import java.net.URL; import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import static com.intellij.util.SystemProperties.getUserHome; public class PathManager { - @NonNls public static final String PROPERTIES_FILE = "idea.properties.file"; - @NonNls public static final String PROPERTY_SYSTEM_PATH = "idea.system.path"; - @NonNls public static final String PROPERTY_CONFIG_PATH = "idea.config.path"; - @NonNls public static final String PROPERTY_PLUGINS_PATH = "idea.plugins.path"; - @NonNls public static final String PROPERTY_HOME_PATH = "idea.home.path"; - @NonNls public static final String PROPERTY_LOG_PATH = "idea.log.path"; - @NonNls public static final String PROPERTY_PATHS_SELECTOR = "idea.paths.selector"; - @NonNls public static final String DEFAULT_OPTIONS_FILE_NAME = "other"; + public static final String PROPERTIES_FILE = "idea.properties.file"; + public static final String PROPERTY_HOME_PATH = "idea.home.path"; + public static final String PROPERTY_CONFIG_PATH = "idea.config.path"; + public static final String PROPERTY_SYSTEM_PATH = "idea.system.path"; + public static final String PROPERTY_PLUGINS_PATH = "idea.plugins.path"; + public static final String PROPERTY_LOG_PATH = "idea.log.path"; + public static final String PROPERTY_PATHS_SELECTOR = "idea.paths.selector"; + public static final String DEFAULT_OPTIONS_FILE_NAME = "other"; - @NonNls private static final String LIB_FOLDER = "lib"; - @NonNls private static final String PLUGINS_FOLDER = "plugins"; - @NonNls private static final String BIN_FOLDER = "bin"; - @NonNls private static final String LOG_DIRECTORY = "log"; - @NonNls private static final String CONFIG_FOLDER = "config"; - @NonNls private static final String OPTIONS_FOLDER = "options"; - @NonNls private static final String SYSTEM_FOLDER = "system"; - @NonNls private static final String PATHS_SELECTOR = System.getProperty(PROPERTY_PATHS_SELECTOR); + private static final String PROPERTY_HOME = "idea.home"; // reduced variant of PROPERTY_HOME_PATH, now deprecated - @NonNls private static String ourHomePath; - @NonNls private static String ourSystemPath; - @NonNls private static String ourConfigPath; - @NonNls private static String ourPluginsPath; - @NonNls private static String ourLogPath; + private static final String LIB_FOLDER = "lib"; + private static final String PLUGINS_FOLDER = "plugins"; + private static final String BIN_FOLDER = "bin"; + private static final String LOG_DIRECTORY = "log"; + private static final String CONFIG_FOLDER = "config"; + private static final String OPTIONS_FOLDER = "options"; + private static final String SYSTEM_FOLDER = "system"; + private static final String PATHS_SELECTOR = System.getProperty(PROPERTY_PATHS_SELECTOR); + + private static final Pattern PROPERTY_REF = Pattern.compile("\\$\\{(.+?)}"); + + private static String ourHomePath; + private static String ourConfigPath; + private static String ourSystemPath; + private static String ourPluginsPath; + private static String ourLogPath; // IDE installation paths @@ -68,7 +76,7 @@ public class PathManager { public static String getHomePath() { if (ourHomePath != null) return ourHomePath; - String fromProperty = System.getProperty(PROPERTY_HOME_PATH); + String fromProperty = System.getProperty(PROPERTY_HOME_PATH, System.getProperty(PROPERTY_HOME)); if (fromProperty != null) { ourHomePath = getAbsolutePath(fromProperty); if (!new File(ourHomePath).isDirectory()) { @@ -260,7 +268,7 @@ public class PathManager { * Attempts to detect classpath entry which contains given resource. */ @Nullable - public static String getResourceRoot(@NotNull Class context, @NonNls String path) { + public static String getResourceRoot(@NotNull Class context, String path) { URL url = context.getResource(path); if (url == null) { url = ClassLoader.getSystemResource(path.substring(1)); @@ -272,10 +280,9 @@ public class PathManager { * Attempts to extract classpath entry part from passed URL. */ @Nullable - @NonNls private static String extractRoot(URL resourceURL, String resourcePath) { if (!(StringUtil.startsWithChar(resourcePath, '/') || StringUtil.startsWithChar(resourcePath, '\\'))) { - //noinspection HardCodedStringLiteral,UseOfSystemOutOrSystemErr + //noinspection UseOfSystemOutOrSystemErr System.err.println("precondition failed: " + resourcePath); return null; } @@ -298,7 +305,7 @@ public class PathManager { } if (resultPath == null) { - //noinspection HardCodedStringLiteral,UseOfSystemOutOrSystemErr + //noinspection UseOfSystemOutOrSystemErr System.err.println("cannot extract: " + resourcePath + " from " + resourceURL); return null; } @@ -319,7 +326,7 @@ public class PathManager { } public static void loadProperties() { - String[] propFiles = new String[]{ + String[] propFiles = { System.getProperty(PROPERTIES_FILE), getUserPropertiesPath() + "/idea.properties", getHomePath() + "/bin/idea.properties", @@ -334,11 +341,6 @@ public class PathManager { try { Map properties = FileUtil.loadProperties(fis); - String home = properties.get("idea.home"); - if (home != null && ourHomePath == null) { - ourHomePath = getAbsolutePath(substituteVars(home)); - } - Properties sysProperties = System.getProperties(); for (String key : properties.keySet()) { if (sysProperties.getProperty(key, null) == null) { // load the property from the property file only if it is not defined yet @@ -352,7 +354,7 @@ public class PathManager { } } catch (IOException e) { - //noinspection HardCodedStringLiteral,UseOfSystemOutOrSystemErr + //noinspection UseOfSystemOutOrSystemErr System.err.println("Problem reading from property file: " + propFile.getPath()); } } @@ -362,24 +364,43 @@ public class PathManager { @Contract("null -> null") public static String substituteVars(String s) { - final String ideaHomePath = getHomePath(); - return substituteVars(s, ideaHomePath); + return substituteVars(s, getHomePath()); } @Contract("null, _ -> null") public static String substituteVars(String s, String ideaHomePath) { if (s == null) return null; + if (s.startsWith("..")) { s = ideaHomePath + File.separatorChar + BIN_FOLDER + File.separatorChar + s; } - s = StringUtil.replace(s, "${idea.home}", ideaHomePath); - final Properties props = System.getProperties(); - final Set keys = props.keySet(); - for (final Object key1 : keys) { - String key = (String)key1; - String value = props.getProperty(key); - s = StringUtil.replace(s, "${" + key + "}", value); + + Matcher m = PROPERTY_REF.matcher(s); + while (m.find()) { + String key = m.group(1); + String value = System.getProperty(key); + + if (value == null) { + if (PROPERTY_HOME_PATH.equals(key) || PROPERTY_HOME.equals(key)) { + value = ideaHomePath; + } + else if (PROPERTY_CONFIG_PATH.equals(key)) { + value = getConfigPath(); + } + else if (PROPERTY_SYSTEM_PATH.equals(key)) { + value = getSystemPath(); + } + } + + if (value == null) { + //noinspection UseOfSystemOutOrSystemErr + System.err.println("Unknown property: " + key); + value = ""; + } + + s = m.replaceAll(value); } + return s; } @@ -466,7 +487,7 @@ public class PathManager { // outdated stuff /** @deprecated use {@link #getPluginsPath()} (to remove in IDEA 14) */ - @SuppressWarnings("UnusedDeclaration") @NonNls public static final String PLUGINS_DIRECTORY = PLUGINS_FOLDER; + @SuppressWarnings("UnusedDeclaration") public static final String PLUGINS_DIRECTORY = PLUGINS_FOLDER; /** @deprecated use {@link #getPreInstalledPluginsPath()} (to remove in IDEA 14) */ @SuppressWarnings({"UnusedDeclaration", "MethodNamesDifferingOnlyByCase", "SpellCheckingInspection"}) diff --git a/platform/util/testSrc/com/intellij/openapi/application/PathManagerTest.java b/platform/util/testSrc/com/intellij/openapi/application/PathManagerTest.java new file mode 100644 index 000000000000..cf8aee5fab5b --- /dev/null +++ b/platform/util/testSrc/com/intellij/openapi/application/PathManagerTest.java @@ -0,0 +1,78 @@ +/* + * Copyright 2000-2015 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.openapi.application; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.io.File; +import java.util.Random; + +import static org.junit.Assert.assertEquals; + +public class PathManagerTest { + private static final String TEST_RPOP = "__ij_subst_test__"; + private static final String TEST_VALUE = "__" + new Random().nextInt(1000) + "__"; + + @Before + public void setUp() throws Exception { + System.setProperty(TEST_RPOP, TEST_VALUE); + } + + @After + public void tearDown() throws Exception { + System.clearProperty(TEST_RPOP); + } + + @Test + public void testVarSubstitution() { + assertEquals("", PathManager.substituteVars("")); + assertEquals("abc", PathManager.substituteVars("abc")); + assertEquals("a$b$c", PathManager.substituteVars("a$b$c")); + + assertEquals("/" + TEST_VALUE + "/" + TEST_VALUE + "/", PathManager.substituteVars("/${" + TEST_RPOP + "}/${" + TEST_RPOP + "}/")); + + assertEquals(PathManager.getHomePath() + "/build.txt", PathManager.substituteVars("${idea.home.path}/build.txt")); + assertEquals(PathManager.getHomePath() + "/build.txt", PathManager.substituteVars("${idea.home}/build.txt")); + + assertEquals("/opt/idea/build.txt", PathManager.substituteVars("${idea.home.path}/build.txt", "/opt/idea")); + + String config = System.clearProperty(PathManager.PROPERTY_CONFIG_PATH); + try { + assertEquals(PathManager.getConfigPath() + "/opts", PathManager.substituteVars("${idea.config.path}/opts")); + } + finally { + if (config != null) { + System.setProperty(PathManager.PROPERTY_CONFIG_PATH, config); + } + } + + String system = System.clearProperty(PathManager.PROPERTY_SYSTEM_PATH); + try { + assertEquals(PathManager.getSystemPath() + "/logs2", PathManager.substituteVars("${idea.system.path}/logs2")); + } + finally { + if (system != null) { + System.setProperty(PathManager.PROPERTY_CONFIG_PATH, system); + } + } + + assertEquals(PathManager.getBinPath() + File.separator + "../license", PathManager.substituteVars("../license")); + + assertEquals("//", PathManager.substituteVars("/${unknown_property_ignore_the_error}/")); + } +} diff --git a/python/build/pycharm64_community_launcher.properties b/python/build/pycharm64_community_launcher.properties index 7470a38aa539..11ca3241ed51 100644 --- a/python/build/pycharm64_community_launcher.properties +++ b/python/build/pycharm64_community_launcher.properties @@ -4,6 +4,6 @@ IDS_APP_TITLE=__IDE-NAME__ Launcher IDS_VM_OPTIONS_PATH=%USERPROFILE%\\.__PRODUCT_PATHS_SELECTOR__ IDC_WINLAUNCHER=__IDE-NAME___LAUNCHER IDS_PROPS_ENV_VAR=__IDE-NAME___PROPERTIES -IDS_VM_OPTIONS_ENV_VAR=__IDE-NAME___VM_OPTIONS +IDS_VM_OPTIONS_ENV_VAR=__IDE-NAME__64_VM_OPTIONS IDS_ERROR_LAUNCHING_APP=Error launching __IDE-NAME__ IDS_VM_OPTIONS=-Didea.platform.prefix=PyCharmCore -Didea.no.jre.check=true -Didea.paths.selector=__PRODUCT_PATHS_SELECTOR__