summaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authorTor Norbye <tnorbye@google.com>2013-08-29 10:40:28 -0700
committerTor Norbye <tnorbye@google.com>2013-08-29 10:40:35 -0700
commit932259520ebaedeb2ccf4b7594bad50c700963d7 (patch)
tree2b52334b8a019d9652625b1432deac11a7c4b31e /plugins
parente47d04f1f804b9e725b768725da436af6788f19b (diff)
downloadidea-932259520ebaedeb2ccf4b7594bad50c700963d7.tar.gz
Snapshot 1c7917945d4706cdbb32b599f81abd05c0251e32 from idea/132.27 branch of git://git.jetbrains.org/idea/community.git
1c79179: 2013-08-29 Yann Cébron - DevKit: smart EP "implementation" highlighting/completion f3a83bc: 2013-08-29 Roman Shevchenko - IDEA-112827 (NPE in error reporter) 464a45b: 2013-08-29 Anna Kozlova - move pin button to the right side of popup (IDEA-112435) 1635be8: 2013-08-29 Yann Cébron - Dom EPs: add some <with> tags 6bcac42: 2013-08-29 Roman Shevchenko - IDEA-112824 (suppress SVN logging for normal use) 16d0ba4: 2013-08-29 Anna Kozlova - NPE 285509c4c: 2013-08-28 Max Medvedev - IDEA-111110 Groovy: Introduce Field Refactoring doesn't suggest to choose destination class 5415af1: 2013-08-28 Yann Cébron - Merge remote-tracking branch 'origin/master' 8462f3b: 2013-08-28 Dmitry Jemerov - cleanup 2ad6100: 2013-08-28 Yann Cébron - Merge remote-tracking branch 'origin/master' 9de8bfc: 2013-08-28 Dmitry Jemerov - Merge branch 'master' of git://github.com/niktrop/intellij-community into pull92 6315415: 2013-08-28 Dmitry Jemerov - cleanup 7281b73: 2013-08-28 Dmitry Jemerov - Merge branch 'cjfm3' of git://github.com/max-kammerer/intellij-community into pull87 6e31350: 2013-08-28 Dmitry Jemerov - fix couple of issues with https://github.com/JetBrains/intellij-community/pull/94 3695aa0: 2013-08-28 Dmitry Jemerov - Merge branch 'master' of git://github.com/asedunov/intellij-community into pull94 ce2c15f: 2013-08-28 Yann Cébron - fix javadoc @see link 6794ead: 2013-08-28 Anna Kozlova - skip adverts when server doesn't accept provided info 851da00: 2013-08-28 Anna Kozlova - skip advs in tests and headless mode cddbc28: 2013-08-28 Anna Kozlova - EA-48802 - assert: JavaFileManagerBase.findClass 1eafaae: 2013-08-28 Anna Kozlova - EA-49147 - NPE: UnusedDeclarationInspection.isReadObjectMethod f1a2040: 2013-08-28 Anna Kozlova - EA-49155 - NPE: JavaChangeSignatureDialog.doCalculateSignature 2684709: 2013-08-28 Dmitry Jemerov - MalformedFormatStringInspectionTest fixed ce8088e: 2013-08-28 Evgeny Gerashchenko - Removed extra checking for duplicate annotations in one file. It is performed when reading file anyway. 9d4c7ca: 2013-08-28 Dmitry Trofimov - Merge remote-tracking branch 'origin/master' 2fd8641: 2013-08-28 Eugene Kudelevsky - add possibility to setup lookup element for XML attribute values; IDEA-102167 layout_* attributes should go first 3b065b1: 2013-08-28 Dmitry Trofimov - Merge remote-tracking branch 'origin/master' d8d9168: 2013-08-28 Dmitry Trofimov - Libs update. 28a95a6: 2013-08-28 Alexey Kudravtsev - compilation d4a0d69: 2013-08-28 Alexey Kudravtsev - notnull f9f8006: 2013-08-28 Alexey Kudravtsev - moved to appropriate package 4d058f8: 2013-08-28 Alexey Kudravtsev - cleanup 111301a: 2013-08-28 Alexey Kudravtsev - extra method 01e59b0: 2013-08-28 Alexey Kudravtsev - doc da966ae: 2013-08-28 Alexey Kudravtsev - cleanup 7503616: 2013-08-28 Alexey Kudravtsev - add method to javaversionservice 7d6de4f: 2013-08-28 Alexey Kudravtsev - notnull dee081f: 2013-08-27 Alexey Kudravtsev - statistics dd327c0: 2013-08-28 Dmitry Trofimov - Focus fixes. 7231931: 2013-08-28 Vladimir Krivosheev - WEB-8988 Return "open in browser" in context menu 2102255: 2013-08-28 Roman Shevchenko - app: install-over range extended for next EAPs ddad3bb: 2013-08-28 Dmitry Avdeev - IDEA-112728 Can't create new task from tasks menu in toolbar: no need to fix lost typing for Go To Task a8160c2: 2013-08-28 Dmitry Avdeev - typo 7328cbd: 2013-08-28 Dmitry Avdeev - cleanup abbdb5a: 2013-08-28 Dmitry Avdeev - cleanup a5c8503: 2013-08-28 Dmitry Avdeev - do not allow empty task name e8daf37: 2013-08-28 Dmitry Avdeev - simplified dff28d3: 2013-08-28 Dmitry Avdeev - simplified 38513a8: 2013-08-28 Dmitry Avdeev - cleanup c09dd55: 2013-08-28 Vladimir Krivosheev - VariablesGroup — avoid array copy 8f3c91f: 2013-08-28 Roman Shevchenko - java: correct character escaping in decompiler 9a19e30: 2013-08-28 Dmitry Trofimov - Fixed hiding and activating of the terminal (PY-10669). df672ba: 2013-08-28 Dmitry Trofimov - Terminal system settings refactored. 4653b54: 2013-08-28 Anna Kozlova - unknown features equality fixed 2896270: 2013-08-28 Anna Kozlova - ensure read access ccff3af: 2013-08-28 Anna Kozlova - suggest to download plugins by unknown run configurations 9c8a3d2: 2013-08-28 Konstantin Bulenkov - include os.arch and jdk build number in about 861984c: 2013-08-28 Denis Fokin - IDEA-108265. We should not do anything if an empty array is passed. a6b3441: 2013-08-28 Sergey Simonchik - EA-49063 - AIOOBE: ScriptRunnerUtil$ScriptOutput.onTextAvailable 845ee5c: 2013-08-28 Vladimir Krivosheev - value nullability 36121a2: 2013-08-28 Konstantin Kolosovsky - Merge branch 'svn1_8_new' 1515b70: 2013-08-28 Mikhail Golubev - Merge remote-tracking branch 'origin/master' 33d684e0: 2013-08-28 Mikhail Golubev - IDEA-110012 Not all Redmine Issues Available on "Open Task" (Limited to 100?) 39899b1: 2013-08-28 Bas Leijdekkers - IDEA-112782 (Change signature dialog shows unexpected 'cannot resolve symbol' message) e469928: 2013-08-28 Anna Kozlova - accept test config methods in non-test classes (IDEA-112537) b53abed: 2013-08-27 Anna Kozlova - fix typo 3074f49: 2013-08-28 Dmitry Avdeev - IDEA-112781 Open YouTrack task: Create changelist doesn't work with SVN ? 43c8897: 2013-08-27 Dmitry Avdeev - cleanup ff6217a: 2013-08-28 Kirill Likhodedov - Annotate overriding methods 8e2d0e1: 2013-08-28 Roman Shevchenko - terminal: platform's Guava should be good enough for the plugin 2055780: 2013-08-27 Roman Shevchenko - EA-49123 (do not load extensions from static initializer) 116dc30: 2013-08-27 Roman Shevchenko - EA-49235 (check proxy port) 2b4f96f: 2013-08-27 Roman Shevchenko - EA-49235 (code readability) ed03bca: 2013-08-27 Roman Shevchenko - EA-49142 (NPE, cleanup) e6053d0: 2013-08-27 Roman Shevchenko - EA-49102 (face user with printing errors) a748474: 2013-08-28 Vladimir Krivosheev - 4.1.0. update netty (now it is not patched build, https://github.com/netty/netty/pull/1762) 3c60901: 2013-08-28 Konstantin Bulenkov - better selection for mixed languages 20decc3: 2013-08-28 Konstantin Bulenkov - fix selection for files with multiple languages 878ad26: 2013-08-27 Max Medvedev - IDEA-111100 Groovy: Introduce Variable/Parameter Refactorings don't suggest to replace occurrences if applied to expressions inside code blocks 8a60662: 2013-08-27 Max Medvedev - IDEA-110981 Groovy: "Split into declaration and assignment" intention leaves unnecessary "=" if applied to closures 77912c1: 2013-08-27 Max Medvedev - IDEA-111101 Groovy: In-Place Introduce Field: Alt+I mnemonic doesn't work in the refactoring preview 088f68e: 2013-08-27 Max Medvedev - IDEA-111027 Groovy: In-Place Introduce Variable: PIEAE at GrInplaceIntroducer.<init> on introducing a variable within one-line method/closure a2210a4: 2013-08-27 Aleksei Sedunov - Extract inheritor candidate check into separate InheritanceChecker interface f40be5e: 2013-08-27 Alexander Zolotov - Filter moduleAwareConfigurables by module cf7704f: 2013-08-26 Alexander Zolotov - WEB-6452 SASS suggests functions at the top, instead of property values 165ccf7: 2013-08-27 Konstantin Kolosovsky - IDEA-94942 Fixed diff, annotate errors in history view after rename/move 7b6396a: 2013-08-27 Dmitry Jemerov - branch number 132 e176d25: 2013-08-27 Sergey Evdokimov - IDEA-112754 Maven import: NCDFE for org/jetbrains/plugins/groovy/util/ClassInstanceCache 43c49f6: 2013-08-27 Sergey Evdokimov - IDEA-112754 Maven import: NCDFE for org/jetbrains/plugins/groovy/util/ClassInstanceCache 377dd45: 2013-08-27 Konstantin Bulenkov - fix memory leak 203fb69: 2013-08-27 Sergey Simonchik - WEB-9011 Karma plugin ignored tests 3b896f2: 2013-08-27 Sergey Evdokimov - Make project unignored when new module is created by ignored project 9ae29c6: 2013-08-27 Sergey Evdokimov - Remove maven project from project tree when user deletes module. +review CR-IC-2084 0f0f39e: 2013-08-27 Vladimir Krivosheev - cleanup, Overrides 3dddec4: 2013-08-27 Vladimir Krivosheev - cleanup a2fff55: 2013-08-27 Aleksey Pivovarov - Github: Add API function for loading Commit Comments 9bd1660: 2013-08-27 Aleksey Pivovarov - fix IndexOutOfBoundsException on inserting empty collection to empty model 46b8998: 2013-08-27 Nadya Zabrodina - exception during annotate copied file fixed 66640b2: 2013-08-27 Dmitry Trofimov - Merge remote-tracking branch 'origin/master' c597bcc: 2013-08-27 Sergey Evdokimov - Remove maven project from project tree when user deletes module. +review CR-IC-2084 33e932a: 2013-08-27 Dmitry Trofimov - Merge remote-tracking branch 'origin/master' 7cc9cca: 2013-08-27 Vladislav.Soroka - IDEA-79466 gradle support should generate web module configuration 42e649d: 2013-08-27 Dmitry Jemerov - better names for couple of new classes added to API 5c70eaf: 2013-08-27 Dmitry Trofimov - Merge remote-tracking branch 'origin/master' 2e0f1fa: 2013-08-27 Dmitry Trofimov - Update lib. dcc2c4b: 2013-08-27 Dmitry Trofimov - Override isRetina. 05b716b: 2013-08-27 nik - processing dependencies in JPS: @NotNull annotations and javadoc added 6314b6e: 2013-08-27 Dmitry Trofimov - Fixed for Retina. 9d1886c: 2013-08-27 Dmitry Avdeev - navigatable xsd documentation 0f389c5: 2013-08-27 Vladimir Krivosheev - hide internal class XValuePresenterAdapter a0386eb: 2013-08-27 Mikhail Golubev - Merge remote-tracking branch 'origin/master' 53248dc: 2013-08-27 Vladimir Krivosheev - fix createPresenter d0355b3: 2013-08-27 Sergey Evdokimov - Remove maven project from project tree when user deletes module. +review CR-IC @Anton.Makeev fb48f62: 2013-08-27 Sergey Evdokimov - Optimization of MavenProjectsTree.isManagedFile() 6b123aa: 2013-08-27 nik - JPS dependencies enumerator: convenient method added d4579e1: 2013-08-27 Dmitry Avdeev - UrlPsiReference promoted 3b1feea: 2013-08-27 Dmitry Avdeev - cleanup ee18443: 2013-08-27 Dmitry Avdeev - cleanup ca2484e: 2013-08-27 Dmitry Avdeev - cleanup c9e045b: 2013-08-27 Vladimir Krivosheev - 1) methods "void setPresentation(@NonNls String name, @Nullable Icon icon, @NonNls @Nullable String type, @NonNls @NotNull String separator, @NonNls @NotNull String value, boolean hasChildren);" and "void setPresentation(@NonNls String name, @Nullable Icon icon, @NonNls @Nullable String type, @NonNls @NotNull String value, boolean hasChildren);" b38d58a: 2013-08-27 Konstantin Kolosovsky - IDEA-94942 Fixed treating svn client warnings as errors 8cab12c: 2013-08-27 Dmitry Jemerov - separate UI and non-UI parts of MalformedFormatStringInspection 93e3fa6: 2013-08-20 Jason Holmes - Custom "Malformed format string" inspection b9f6fde: 2013-08-27 nik - actions to mark/unmark roots in Project View refactored to support custom root types 0455e46: 2013-08-27 Aleksey Pivovarov - Github: remove useless listener 7f40613: 2013-08-27 Aleksey Pivovarov - Github: reset User on token change c8a5402: 2013-08-27 Aleksey Pivovarov - Github: change layout 89769be: 2013-08-27 Aleksey Pivovarov - Github: add test 0d8ab04: 2013-08-27 Aleksey Pivovarov - Github: comment cba103c: 2013-08-27 Dmitry Trofimov - Merge remote-tracking branch 'origin/master' d6ca049: 2013-08-27 Anna Kozlova - allow autoPopup after custom symbols (IDEA-112571) a70c338: 2013-08-27 Konstantin Bulenkov - IDEA-110846 File Structure pop-up doesn't work properly for template languages 4896775: 2013-08-27 Konstantin Bulenkov - recent files duplicates 05835fa: 2013-08-27 Fedor Korotkov - WEB-6328 Add support for HTML5 <main> element 2407d7b: 2013-08-27 Anna Kozlova - allow to call getValue without readAction as it was before 29cb25d: 2013-08-27 Dmitry Avdeev - fixing the leak 7d3932a: 2013-08-27 Dmitry Avdeev - IDEA-112708 Static classes in JSP class block are considered an error f6dbce2: 2013-08-26 Mikhail Golubev - IDEA-112605 Task management: can't add Generic server: NoClassDefFoundError: XPathFileType 82c1dc1: 2013-08-27 Konstantin Kolosovsky - Merge branch 'svn1_8_new' 08d46f1: 2013-08-27 Alexey Kudravtsev - highlightVisitor moves and cleanup e0fec9d: 2013-08-27 Alexey Kudravtsev - Merge remote-tracking branch 'origin/master' e9b1dfc: 2013-08-27 Anna Kozlova - dumb smart lambda completion (IDEA-112553) 6da30a4: 2013-08-26 Alexey Kudravtsev - calculate column/offset: optimisation of the no-tabs case c0990c4: 2013-08-26 Alexey Kudravtsev - race conditions? 135e250: 2013-08-26 Alexey Kudravtsev - notnull, cleanup 75b28ba: 2013-08-26 Alexey Kudravtsev - file was not rehighlighted on some changes 5647d35: 2013-08-26 Sergey Evdokimov - Make myManagedFilesPaths a Set to avoid duplication. 680dd76: 2013-08-27 Aleksey Pivovarov - Github: fix memory leak on Exception in setUp(); e3092b7: 2013-08-27 Dmitry Avdeev - IDEA-112611 Task management: DVCS: closing a task fails: "Cannot delete the branch master" d12d4fe: 2013-08-27 Anna Kozlova - logging for EA-49099 - PIEAE: PsiAnchor$StubIndexReference.getStartOffset 3cc53fe: 2013-08-27 Anna Kozlova - revert changes in api 10fbef9: 2013-08-27 Roman Shevchenko - Test data updated a5455ba: 2013-08-27 Dmitry Trofimov - Merge remote-tracking branch 'origin/master' 8ed3ae8: 2013-08-27 Dmitry Trofimov - Updated lib. e6df583: 2013-08-27 Dmitry Trofimov - Added guava lib to terminal. 1853090: 2013-08-27 Dmitry Trofimov - Draw image Retina support. a7ebcaf: 2013-08-27 Dmitry Trofimov - Open session action moved to constructor. 5176bfa: 2013-08-26 Sergey Evdokimov - Fix maven tests 291f740: 2013-08-26 Vladimir Krivosheev - we must check if any port free too 18d4be6: 2013-08-26 Vassiliy Kudryashov - IDEA-70769 Settings panel: increase speed of scrollbars 0c76aca: 2013-08-26 Vassiliy Kudryashov - IDEA-112524 Working directory for default rake tasks is changed to $MODULE_DIR$ after project's reopening e2b7f6b: 2013-08-26 Konstantin Bulenkov - pattern dependent delay 1916142: 2013-08-26 Vladimir Krivosheev - cleanup 3da9dcd: 2013-08-26 Vladimir Krivosheev - done: custom binary request handler e02eba9: 2013-08-26 Aleksey Pivovarov - Github: do not produce dozens of notifications 8e41d59: 2013-08-26 Aleksey Pivovarov - Simplify 78c800d: 2013-08-26 Aleksey Pivovarov - Github: respect 'max' parameter 3afb19f: 2013-08-26 Maxim.Mossienko - proper versioning of stub index when persistent enumerator version changes c853e9e: 2013-08-26 Eugene Kudelevsky - IDEA-112376 add "importFilter" extension point to force using FQN when importing class 31281a9: 2013-08-26 Kirill Likhodedov - [git] Don't write empty lines to LOG.debug. 493b9fb: 2013-08-26 Dmitry Trofimov - Merge remote-tracking branch 'origin/master' 60384ba: 2013-08-26 Dmitry Trofimov - Enable Run local terminal action for Windows. bfa8e61: 2013-08-26 Dmitry Jemerov - stupid typo fixed 04a76c3: 2013-08-26 Anna Kozlova - IDEA-112555 Bad code is green with method references on instance 8f5139d: 2013-08-26 Denis Fokin - IDEA-108265. Now user is asked whether the project should be opened in a new frame. da958ab: 2013-08-26 Natalia Ukhorskaya - Decompile chars, bytes and shorts correctly 8008709: 2013-08-26 Roman Shevchenko - java: incorrect annotation decoding fixed 9f07ea5: 2013-08-26 Roman Shevchenko - logging e07c905: 2013-08-26 Dmitry Trofimov - Merge remote-tracking branch 'origin/master' e81832d: 2013-08-26 Dmitry Trofimov - This update fixes pty on windows. e36607b: 2013-08-26 Konstantin Bulenkov - new renderer 9ea47a5: 2013-08-26 nik - source roots editors: obtain icons for content tree from extension d52dfb8: 2013-08-26 nik - constants moved 710d3ba: 2013-08-26 niktrop - Code style fixed aa8832d: 2013-08-26 Sergey Simonchik - code style: two subsequent ifs merged to reduce inner indent ed88487: 2013-08-26 Konstantin Kolosovsky - IDEA-94942 Provide detailed error messages to user instead of general ones e0df7a3: 2013-08-26 Vassiliy Kudryashov - IDEA-112524 Working directory for default rake tasks is changed to $MODULE_DIR$ after project's reopening e60a55b: 2013-08-26 nik - source roots editors refactored: root type specific UI moved to extension 928ea20: 2013-08-26 Mikhail Golubev - Merge remote-tracking branch 'origin/master' 70d526d: 2013-08-26 Anna Kozlova - guardedBy itself support (IDEA-112565) 2e23cb8: 2013-08-26 Anna Kozlova - restore bytecode viewer for java classes 89dffc9: 2013-08-26 Anna Kozlova - cal property name: accept without any other checks non-letter prefixes (IDEA-112585) bab044f: 2013-08-26 Vladimir Krivosheev - restore Alarm.cancelRequest dd817dc: 2013-08-26 Sergey Simonchik - simplification 7046dc4: 2013-08-26 niktrop - Some refactoring for reusing GenerateEquals UI in scala plugin 44e4219: 2013-08-26 Sergey Evdokimov - IDEA-112529 Maven: code completion could work in file path value with property references 867be29: 2013-08-26 Denis Fokin - Jumplist libraries changes. This is a release version of dll with eliminated MSVCRT dependencies. 7b0029d: 2013-08-26 Anton Makeev - CIDR: language tests in windows +review CR-OC @micha 9bef3a2: 2013-08-26 Konstantin Kolosovsky - IDEA-94942 Updated cleanup behavior after previous command failed 8447776: 2013-08-26 Mikhail Golubev - Remove SelectorBasedResponseHandler#getSelectorFileType, delegate to #getResponseType instead. Add missing @NotNull annotation, update doc comments. d7ecb44: 2013-08-26 Anna Kozlova - treat classes with before/after methods as test classes for bad declared exceptions (IDEA-112537) 4be2bcf: 2013-08-26 Anna Kozlova - restore suggestion to remove 'abstract' when method has body c57c308: 2013-08-26 Anna Kozlova - local can be final inside lambda body (IDEA-112630) b8170a6: 2013-08-26 Vladimir Krivosheev - isValuesCustomSorted, add or not SortValuesAction (alphabetically sort) TODO: this action should be moved to "Variables" as gear action b56b744: 2013-08-26 Mikhail Golubev - Merge remote-tracking branch 'origin/master' ba7e194: 2013-08-23 Mikhail Golubev - Migrate Assembla to new GenericRepository dd0885d: 2013-08-23 Mikhail Golubev - Refactor TemplateVariable aa94a3c: 2013-08-23 Mikhail Golubev - Add several tests of date parsing 0e7e61e: 2013-08-23 Mikhail Golubev - Reflective PsiElements creation in JqlParserDefinition a5f3011: 2013-08-26 Konstantin Kolosovsky - IDEA-94942 Short refactoring (removed duplication) 01cd38b: 2013-08-26 Sergey Simonchik - unnecessary line removed 7c34a2a: 2013-08-26 Dmitry Avdeev - IDEA-60895 No completion for enumerated and boolean values of xml tags 8b83a30: 2013-08-26 Vladislav.Soroka - gradle: cosmetic UI fix 8ee6a76: 2013-08-26 Roman Shevchenko - Convenient debug logging cde5373: 2013-08-26 Dmitry Avdeev - IDEA-60895 No completion for enumerated and boolean values of xml tags 75d9b47: 2013-08-24 Max Medvedev - IDEA-112621 Groovy: Remove explicit type declaration intention d1c29fb: 2013-08-23 Max Medvedev - separate visit methods for all types of classes, enums, interfaces, annotation types, and anonymous classes 5eca3d0: 2013-08-23 Max Medvedev - Byte code viewer shows byte code for groovy scripts c96d27f: 2013-08-23 Max Medvedev - Convert anonymous class to closure: don't insert 'as Runnable' if groovy version is at least 2.2 7e993a0: 2013-08-23 Max Medvedev - IDEA-112560 process only applicable mixins to a ref c33dc4a: 2013-08-26 Roman Shevchenko - platform: unified loading of system libraries (done right) d492a6f: 2013-08-25 Roman Shevchenko - logging 2f2b546: 2013-08-25 Roman Shevchenko - IDEA-112462 (allow plugins to extend lib search path) 2a39bf2: 2013-08-25 Maxim.Mossienko - restart lexer from 0 offset when searching from start a0858dbf: 2013-08-25 Maxim.Mossienko - 20% more compact compiler caches (-50M for IDEA project) 5ce3373: 2013-08-25 Maxim.Mossienko - IDEA-111918 Find: comments / string literals only: just 1 entry is found in each comment or literal 68ffc65: 2013-08-25 Maxim.Mossienko - faster contol + shift + N / control + N by default eb67af1: 2013-08-24 Vassiliy Kudryashov - IDEA-107413 Cannot drag'n'drop more than one item in Changes View d5ed7b5: 2013-08-24 nik - store properties of source folder in JPS element b3dd357: 2013-08-24 nik - typo 5b8b1ff: 2013-08-24 Kirill Likhodedov - Merge remote-tracking branch 'origin/master' 0dd284a: 2013-08-24 Kirill Likhodedov - Better assertion error in the DefaultLogger 3146c0b: 2013-08-23 Bas Leijdekkers - foreach can also initialize field 6356a11: 2013-08-23 Konstantin Bulenkov - completely refacrored 6ad3452: 2013-08-23 Anna Kozlova - show conflict on invert boolean and method references (IDEA-112572) 4726276: 2013-08-23 Anna Kozlova - extract method from lambda body: accept parameters of parent method (IDEA-112570) 16a5e32: 2013-08-23 Gregory.Shrago - EditorEx: permanent header API edc3497: 2013-08-23 Konstantin Kolosovsky - IDEA-94942 Content retrieval from svn refactored to ClientFactory model 0f40312: 2013-08-23 Mikhail Golubev - Change JqlQuery methods, JqlTerminalClause should extend JqlClause c335f2b: 2013-08-23 Mikhail Golubev - IDEA-111811 Task management: JIRA: JQL: code completion suggests nothing after closing parenthesis 6e6972a: 2013-08-23 Konstantin Kolosovsky - IDEA-94942 Annotate action e9d5412: 2013-08-23 Mikhail Golubev - Update description of NATIVE_SEARCH feature in TaskRepository 3c948a8: 2013-08-22 Konstantin Kolosovsky - IDEA-94942 Code cleanup - unused parameters removed 64706df: 2013-08-22 Konstantin Kolosovsky - IDEA-112184 0e41cad: 2013-08-22 Konstantin Kolosovsky - IDEA-94942 Simple property client to fix SvnMergeProvider.isBinary implementation 8091bb0: 2013-08-22 Konstantin Kolosovsky - IDEA-94942 Implemented file conflicts resolving Updated "svn info" result parsing 040f405: 2013-08-21 Konstantin Kolosovsky - IDEA-94942 SvnBindClient - unsupported methods removed cef0440: 2013-08-21 Konstantin Kolosovsky - IDEA-94942 "bindSvn" module classes moved to "svn4idea" SvnBindClient unsupported methods will be removed in next commit (to track change like "rename" instead of "delete" + "add" to preserve history) 6c36a93: 2013-08-20 Konstantin Kolosovsky - IDEA-112184 Added logging to detect authentication issues 928c01e: 2013-08-07 Konstantin Kolosovsky - IDEA-94942 - Basic svn 1.8 test support d880599: 2013-08-20 Konstantin Kolosovsky - IDEA-94942 Small text fixes Ignoring tests for old/not used functionality 71384c1: 2013-08-19 Konstantin Kolosovsky - IDEA-94942 Copy and move actions a5f7e7c: 2013-08-19 Konstantin Kolosovsky - IDEA-94942 Delete action e197c08: 2013-08-19 Konstantin Kolosovsky - IDEA-94942 Fixed authentication for svn protocol c28c127: 2013-08-19 Konstantin Kolosovsky - IDEA-94942 Short add, revert commands refactoring e06a346: 2013-08-19 Konstantin Kolosovsky - IDEA-94942 Revert action Fixed status command for single file Fixed status result parsing for normal (non-modified versioned) file 0f66f9d: 2013-08-19 Konstantin Kolosovsky - IDEA-94942 Logging and comments for some commands c928fe5: 2013-08-16 Konstantin Kolosovsky - IDEA-94942 Force command line client usage if working copy of svn 1.8 format detected d6e4e38: 2013-08-16 Konstantin Kolosovsky - IDEA-94942 Fixed "add" action output parsing for binary files 1236be5: 2013-08-15 Konstantin Kolosovsky - IDEA-94942 Small refactoring and fixes after review e05b576: 2013-08-15 Konstantin Kolosovsky - IDEA-94942 "Add" action for files and directories ccf6085: 2013-08-15 Konstantin Kolosovsky - IDEA-94942 "Subversion" -> "Show History" for files and folders aba7390: 2013-08-14 Konstantin Kolosovsky - IDEA-94942 Add command refactored 555d597: 2013-08-14 Konstantin Kolosovsky - IDEA-94942 Fixing status, info commands to use correct arguments b083f31: 2013-08-14 Konstantin Kolosovsky - IDEA-94942 Diff provider (without revision properties) Small command refactoring f657dc8: 2013-08-13 Konstantin Kolosovsky - IDEA-94942 Authentication updates Authentication for remote status command Result parsing for remote info command 2 way SSL support (could be issues with ordinary password entering after 2 way SSL) 2785122: 2013-07-29 Konstantin Kolosovsky - IDEA-94942 initial svn 1.8 support with already existing command line functionality 857bfd5: 2013-08-12 max-kammerer - Update CoreJavaFileManagerTest.java 13539bc: 2013-08-09 Mikhael Bogdanov - CoreJavaFileManager.findClass: properly resolve $ in inner class names Change-Id: Ica3d3d647183983bcd88ce2fb3450deb86343cdb
Diffstat (limited to 'plugins')
-rw-r--r--plugins/ByteCodeViewer/src/META-INF/plugin.xml3
-rw-r--r--plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/ByteCodeViewerManager.java17
-rw-r--r--plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/ClassSearcher.java14
-rw-r--r--plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/ShowByteCodeAction.java3
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties3
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/InspectionGadgetsFix.java2
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/EmptyStatementBodyInspection.java2
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/MalformedFormatStringInspectionBase.java (renamed from plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/MalformedFormatStringInspection.java)46
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/UnnecessaryContinueInspection.java2
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/UnnecessaryReturnInspection.java2
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/dataflow/TooBroadScopeInspectionBase.java2
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/EmptyCatchBlockInspection.java2
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/EmptyFinallyBlockInspection.java2
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/EmptyTryBlockInspection.java2
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/JavaLangImportInspection.java2
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/OnDemandImportInspection.java2
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/SamePackageImportInspection.java2
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/SingleClassImportInspection.java2
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/UnusedImportInspection.java2
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/j2me/PrivateMemberAccessBetweenOuterAndInnerClassInspection.java2
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/javabeans/ClassWithoutConstructorInspection.java2
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/FileTypeUtils.java26
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/FormatUtils.java10
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/InitializationUtils.java368
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/security/DesignForExtensionInspection.java2
-rw-r--r--plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/EmptySynchronizedStatementInspection.java2
-rw-r--r--plugins/InspectionGadgets/src/com/siyeh/ig/bugs/MalformedFormatStringInspection.java45
-rw-r--r--plugins/InspectionGadgets/src/com/siyeh/ig/classlayout/ClassInTopLevelPackageInspection.java2
-rw-r--r--plugins/InspectionGadgets/src/com/siyeh/ig/classlayout/ClassNameDiffersFromFileNameInspection.java2
-rw-r--r--plugins/InspectionGadgets/src/com/siyeh/ig/classlayout/EmptyClassInspection.java2
-rw-r--r--plugins/InspectionGadgets/src/com/siyeh/ig/errorhandling/BadExceptionDeclaredInspection.java6
-rw-r--r--plugins/InspectionGadgets/src/com/siyeh/ig/imports/StaticImportInspection.java2
-rw-r--r--plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/malformed_format_string/MalformedFormatString.java11
-rw-r--r--plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/malformed_format_string/expected.xml19
-rw-r--r--plugins/InspectionGadgets/test/com/siyeh/igtest/initialization/field/InstanceVariableInitialization.java6
-rw-r--r--plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/MalformedFormatStringInspectionTest.java7
-rw-r--r--plugins/IntentionPowerPak/src/com/siyeh/ipp/braces/RemoveBracesIntention.java2
-rw-r--r--plugins/IntentionPowerPak/src/com/siyeh/ipp/conditional/ReplaceConditionalWithIfPredicate.java2
-rw-r--r--plugins/devkit/src/dom/impl/ExtensionDomExtender.java59
-rw-r--r--plugins/devkit/src/projectRoots/IdeaJdk.java12
-rw-r--r--plugins/devkit/testData/codeInsight/ExtensionQualifiedName.xml7
-rw-r--r--plugins/devkit/testSources/codeInsight/PluginXmlFunctionalTest.groovy1
-rw-r--r--plugins/git4idea/src/git4idea/commands/GitSimpleHandler.java23
-rw-r--r--plugins/github/src/org/jetbrains/plugins/github/api/GithubApiUtil.java48
-rw-r--r--plugins/github/src/org/jetbrains/plugins/github/api/GithubCommitComment.java102
-rw-r--r--plugins/github/src/org/jetbrains/plugins/github/api/GithubCommitCommentRaw.java59
-rw-r--r--plugins/github/src/org/jetbrains/plugins/github/exceptions/GithubRateLimitExceededException.java (renamed from plugins/svn4idea/src/org/jetbrains/idea/svn/properties/SvnPropDetailsProvider.java)16
-rw-r--r--plugins/github/src/org/jetbrains/plugins/github/tasks/GithubRepository.java11
-rw-r--r--plugins/github/src/org/jetbrains/plugins/github/tasks/GithubRepositoryEditor.java1
-rw-r--r--plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsPanel.form6
-rw-r--r--plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsPanel.java6
-rw-r--r--plugins/github/test/org/jetbrains/plugins/github/GithubCreateGistContentTest.java4
-rw-r--r--plugins/github/test/org/jetbrains/plugins/github/GithubCreateGistTestBase.java12
-rw-r--r--plugins/github/test/org/jetbrains/plugins/github/GithubCreatePullRequestTestBase.java13
-rw-r--r--plugins/github/test/org/jetbrains/plugins/github/GithubIssuesTest.java103
-rw-r--r--plugins/github/test/org/jetbrains/plugins/github/GithubRequestPagingTest.java4
-rw-r--r--plugins/github/test/org/jetbrains/plugins/github/GithubShareProjectTestBase.java13
-rw-r--r--plugins/github/test/org/jetbrains/plugins/github/test/GithubTest.java54
-rw-r--r--plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleProjectSettingsControl.java2
-rw-r--r--plugins/groovy/jetgroovy.iml1
-rw-r--r--plugins/groovy/resources/intentionDescriptions/GrRemoveExplicitTypeDeclarationIntention/after.groovy.template1
-rw-r--r--plugins/groovy/resources/intentionDescriptions/GrRemoveExplicitTypeDeclarationIntention/before.groovy.template1
-rw-r--r--plugins/groovy/resources/intentionDescriptions/GrRemoveExplicitTypeDeclarationIntention/description.html5
-rw-r--r--plugins/groovy/src/META-INF/plugin.xml10
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/byteCodeViewer/GroovyScriptClassSearcher.java50
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/confusing/ClashingGettersInspection.java3
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/naming/GroovyAnnotationNamingConventionInspection.java14
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/naming/GroovyClassNamingConventionInspection.java18
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/naming/GroovyEnumerationNamingConventionInspection.java30
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/naming/GroovyInterfaceNamingConventionInspection.java15
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/untypedUnresolvedAccess/GrUnresolvedAccessInspection.java2
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/utils/ControlFlowUtils.java12
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/extensions/GroovyMethodInfo.java8
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/GroovyIntentionsBundle.properties4
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/declaration/GrRemoveExplicitTypeDeclarationIntention.java77
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/style/ReplaceAbstractClassInstanceByMapIntention.java7
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GroovyElementVisitor.java20
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/GrVariableDeclarationImpl.java4
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/blocks/GrBlockImpl.java13
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrAnnotationTypeDefinitionImpl.java10
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrAnonymousClassDefinitionImpl.java9
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrClassDefinitionImpl.java8
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrEnumTypeDefinitionImpl.java8
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrInterfaceDefinitionImpl.java11
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GdkMethodUtil.java3
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/LocalVarAnalyzer.java2
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/GrIntroduceHandlerBase.java145
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/constant/GrIntroduceConstantHandler.java13
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/field/GrInplaceIntroduceFieldPanel.form1
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/field/GrIntroduceFieldHandler.java39
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/variable/GrIntroduceLocalVariableProcessor.java9
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/variable/GrIntroduceVariableHandler.java25
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/testIntegration/GroovyTestFramework.java6
-rw-r--r--plugins/groovy/src/org/jetbrains/plugins/groovy/util/ClassInstanceCache.java35
-rw-r--r--plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyUnwrapTest.groovy21
-rw-r--r--plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/GroovyResolveTestCase.groovy2
-rw-r--r--plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolveMethodTest.groovy24
-rw-r--r--plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/IntroduceConstantTest.java4
-rw-r--r--plugins/groovy/testdata/groovy/refactoring/introduceVariable/f2.test2
-rw-r--r--plugins/groovy/testdata/groovy/refactoring/introduceVariable/loop7.test2
-rw-r--r--plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgChangeProvider.java3
-rw-r--r--plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/descriptors/JavaFxPropertyAttributeDescriptor.java6
-rw-r--r--plugins/junit/src/com/intellij/execution/junit/JUnit3Framework.java6
-rw-r--r--plugins/junit/src/com/intellij/execution/junit/JUnitConfiguration.java4
-rw-r--r--plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/converters/MavenDependencySystemPathConverter.java69
-rw-r--r--plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/converters/MavenUrlConverter.java4
-rw-r--r--plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/converters/repositories/MavenRepositoryConverter.java8
-rw-r--r--plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/references/MavenPathReferenceConverter.java49
-rw-r--r--plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/references/MavenUrlPsiReference.java51
-rw-r--r--plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/MavenProjectsNavigatorPanel.java2
-rw-r--r--plugins/maven/src/main/java/org/jetbrains/idea/maven/plugins/api/MavenModelPropertiesPatcher.java5
-rw-r--r--plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManager.java10
-rw-r--r--plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManagerWatcher.java11
-rw-r--r--plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsTree.java22
-rw-r--r--plugins/maven/src/main/java/org/jetbrains/idea/maven/project/actions/AddFileAsMavenProjectAction.java2
-rw-r--r--plugins/maven/src/main/java/org/jetbrains/idea/maven/project/actions/AddManagedFilesAction.java2
-rw-r--r--plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenFrameworkSupportProvider.java2
-rw-r--r--plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenModuleBuilderHelper.java2
-rw-r--r--plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenProjectBuilder.java3
-rw-r--r--plugins/maven/src/test/java/org/jetbrains/idea/maven/dom/MavenDependencyCompletionAndResolutionTest.java25
-rw-r--r--plugins/svn4idea/bindSvn/bindSvn.iml25
-rw-r--r--plugins/svn4idea/bindSvn/lib/javahl.jarbin168896 -> 0 bytes
-rw-r--r--plugins/svn4idea/bindSvn/lib/javahlsrc.zipbin210516 -> 0 bytes
-rw-r--r--plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/SvnBindClient.java925
-rw-r--r--plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/status/LockWrapper.java121
-rw-r--r--plugins/svn4idea/bindSvn/src/org/tigris/subversion/javahl/BindClientException.java47
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/ForNestedRootChecker.java2
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/RootsToWorkingCopies.java51
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/SvnAbstractWriteOperationLocks.java1
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/SvnAuthenticationNotifier.java2
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/SvnBundle.properties1
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/SvnChangeProvider.java4
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/SvnChangeProviderContext.java24
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/SvnChangelistListener.java6
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfigurable.form27
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/SvnContentRevision.java4
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/SvnDiffProvider.java159
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFileSystemListener.java171
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFileUrlMappingImpl.java9
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFormatSelector.java16
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/SvnProxies.java1
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/SvnRecursiveStatusWalker.java45
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/SvnTestWriteOperationLocks.java1
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/SvnUtil.java265
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/SvnVcs.java170
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/SvnWriteOperationLocks.java1
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/WorkingCopyFormat.java14
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/actions/AddAction.java10
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/actions/MarkResolvedAction.java22
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/actions/SvnMergeProvider.java83
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/add/AddClient.java23
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/add/CmdAddClient.java69
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/add/SvnKitAddClient.java39
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/AnnotateClient.java24
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/CmdAnnotateClient.java126
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/SvnAnnotationProvider.java117
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/SvnKitAnnotateClient.java42
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/api/BaseSvnClient.java22
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/api/ClientFactory.java99
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/api/CmdClientFactory.java38
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/api/FileStatusResultParser.java68
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/api/SvnClient.java15
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/api/SvnKitClientFactory.java38
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/DefaultConfigLoader.java2
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/SvnBranchConfigurationNew.java5
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/IdeaCommitHandler.java4
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/IdeaSvnkitBasedAuthenticationCallback.java17
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/SvnCheckinEnvironment.java100
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/AuthenticationCallback.java (renamed from plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/AuthenticationCallback.java)15
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandUtil.java218
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommitEventHandler.java (renamed from plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/CommitEventHandler.java)2
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommitEventType.java (renamed from plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/CommitEventType.java)2
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/LineCommandListener.java (renamed from plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/commandLine/LineCommandListener.java)0
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnBindClient.java67
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnBindException.java (renamed from plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/config/SvnBindException.java)20
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnBindUtil.java (renamed from plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/SvnBindUtil.java)26
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommand.java (renamed from plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/commandLine/SvnCommand.java)53
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineInfoClient.java107
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineStatusClient.java89
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineUpdateClient.java62
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandName.java (renamed from plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/commandLine/SvnCommandName.java)16
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommitRunner.java (renamed from plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/SvnCommitRunner.java)30
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnInfoHandler.java130
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnInfoStructure.java1
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnLineCommand.java (renamed from plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/commandLine/SvnLineCommand.java)237
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnSimpleCommand.java (renamed from plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/commandLine/SvnSimpleCommand.java)6
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/UpdateOutputLineConverter.java28
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/conflict/CmdConflictClient.java33
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/conflict/ConflictClient.java15
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/conflict/SvnKitConflictClient.java25
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/content/CmdContentClient.java39
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/content/ContentClient.java17
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/content/FileTooBigRuntimeException.java7
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/content/SvnKitContentClient.java61
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/copy/CmdCopyMoveClient.java30
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/copy/CopyMoveClient.java15
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/copy/SvnKitCopyMoveClient.java28
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/delete/CmdDeleteClient.java29
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/delete/DeleteClient.java15
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/delete/SvnKitDeleteClient.java24
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/CreateBranchOrTagDialog.java27
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/history/CmdHistoryClient.java223
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/history/HistoryClient.java28
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnCommittedChangesProvider.java5
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnEditCommitMessageAction.java2
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnFileRevision.java3
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnHistoryProvider.java70
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnHistorySession.java32
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnKitHistoryClient.java40
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnRepositoryContentRevision.java29
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/IntegratedSelectedOptionsDialog.java15
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/mergeinfo/BranchInfo.java7
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/portable/PortableStatus.java25
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/properties/CmdPropertyClient.java65
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/properties/PropertyClient.java23
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/properties/SvnKitPropertyClient.java68
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/revert/CmdRevertClient.java79
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/revert/RevertClient.java18
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/revert/SvnKitRevertClient.java31
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/rollback/SvnRollbackEnvironment.java49
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/update/AbstractSvnUpdatePanel.java13
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/update/AbstractUpdateIntegrateCrawler.java6
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/update/MergeRootInfo.java15
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnIntegrateEnvironment.java5
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnUpdateEnvironment.java33
-rw-r--r--plugins/svn4idea/src/org/jetbrains/idea/svn/update/UpdateRootInfo.java15
-rw-r--r--plugins/svn4idea/svn4idea-tests.iml1
-rw-r--r--plugins/svn4idea/svn4idea.iml10
-rw-r--r--plugins/svn4idea/testData18/svn/bin/windows/svn.exebin0 -> 228864 bytes
-rw-r--r--plugins/svn4idea/testData18/svn/newrepo.zipbin0 -> 20570 bytes
-rw-r--r--plugins/svn4idea/testSource/org/jetbrains/idea/SvnTestCase.java40
-rw-r--r--plugins/svn4idea/testSource/org/jetbrains/idea/svn/IgnoredFilesTest.java1
-rw-r--r--plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnChangesCorrectlyRefreshedNativeTest.java2
-rw-r--r--plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnCommitTest.java3
-rw-r--r--plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnExternalTests.java17
-rw-r--r--plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnLockingTest.java3
-rw-r--r--plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnNativeClientAuthTest.java2
-rw-r--r--plugins/svn4idea/testSource/org/jetbrains/idea/svn16/SvnChangesCorrectlyRefreshedNativeTest.java2
-rw-r--r--plugins/svn4idea/testSource/org/jetbrains/idea/svn18/Svn18TestSuite.java33
-rw-r--r--plugins/tasks/tasks-api/src/com/intellij/tasks/TaskRepository.java14
-rw-r--r--plugins/tasks/tasks-core/src/META-INF/plugin.xml2
-rw-r--r--plugins/tasks/tasks-core/src/com/intellij/tasks/actions/GotoTaskAction.java52
-rw-r--r--plugins/tasks/tasks-core/src/com/intellij/tasks/actions/OpenTaskDialog.java8
-rw-r--r--plugins/tasks/tasks-core/src/com/intellij/tasks/actions/TaskCellRenderer.java5
-rw-r--r--plugins/tasks/tasks-core/src/com/intellij/tasks/actions/TaskSearchSupport.java7
-rw-r--r--plugins/tasks/tasks-core/src/com/intellij/tasks/context/WorkingContextManager.java3
-rw-r--r--plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepository.java16
-rw-r--r--plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepositoryEditor.java6
-rw-r--r--plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepositoryType.java9
-rw-r--r--plugins/tasks/tasks-core/src/com/intellij/tasks/generic/JsonPathResponseHandler.java10
-rw-r--r--plugins/tasks/tasks-core/src/com/intellij/tasks/generic/ManageTemplateVariablesDialog.java22
-rw-r--r--plugins/tasks/tasks-core/src/com/intellij/tasks/generic/RegExResponseHandler.java8
-rw-r--r--plugins/tasks/tasks-core/src/com/intellij/tasks/generic/ResponseHandler.java20
-rw-r--r--plugins/tasks/tasks-core/src/com/intellij/tasks/generic/ResponseType.java60
-rw-r--r--plugins/tasks/tasks-core/src/com/intellij/tasks/generic/SelectorBasedResponseHandler.java17
-rw-r--r--plugins/tasks/tasks-core/src/com/intellij/tasks/generic/TemplateVariable.java165
-rw-r--r--plugins/tasks/tasks-core/src/com/intellij/tasks/generic/XPathResponseHandler.java8
-rw-r--r--plugins/tasks/tasks-core/src/com/intellij/tasks/generic/connectors/asana.xml4
-rw-r--r--plugins/tasks/tasks-core/src/com/intellij/tasks/generic/connectors/assembla.xml64
-rw-r--r--plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/JqlElementType.java31
-rw-r--r--plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/JqlElementTypes.java43
-rw-r--r--plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/JqlParser.java16
-rw-r--r--plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/JqlParserDefinition.java52
-rw-r--r--plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/JqlTokenTypes.java6
-rw-r--r--plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/codeinsight/JqlCompletionContributor.java14
-rw-r--r--plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/psi/JqlElementVisitor.java3
-rw-r--r--plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/psi/JqlQuery.java6
-rw-r--r--plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/psi/JqlSubClause.java11
-rw-r--r--plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/psi/JqlTerminalClause.java2
-rw-r--r--plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/psi/impl/JqlQueryImpl.java16
-rw-r--r--plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/psi/impl/JqlSubClauseImpl.java28
-rw-r--r--plugins/tasks/tasks-core/src/com/intellij/tasks/redmine/RedmineRepository.java4
-rw-r--r--plugins/tasks/tasks-core/tasks-core.iml1
-rw-r--r--plugins/tasks/tasks-tests/test/com/intellij/tasks/TaskUtilTest.java51
-rw-r--r--plugins/tasks/tasks-tests/test/com/intellij/tasks/context/ContextTest.java13
-rw-r--r--plugins/tasks/tasks-tests/test/com/intellij/tasks/jira/jql/CompletionTest.java6
-rw-r--r--plugins/tasks/tasks-tests/test/com/intellij/tasks/vcs/TaskBranchesTest.java56
-rw-r--r--plugins/tasks/tasks-tests/testData/jira/jql/completion/AfterLeftParenthesisInSubClause.jql (renamed from plugins/tasks/tasks-tests/testData/jira/jql/completion/AfterParenthesisInSubClause.jql)0
-rw-r--r--plugins/tasks/tasks-tests/testData/jira/jql/completion/AfterSubClause.jql1
-rw-r--r--plugins/tasks/tasks-tests/testData/jira/jql/psi/Subclauses.txt84
-rw-r--r--plugins/terminal/lib/jediterm-pty-0.08.jarbin155224 -> 157061 bytes
-rw-r--r--plugins/terminal/lib/pty4j-0.3.jarbin32668 -> 32843 bytes
-rw-r--r--plugins/terminal/src/org/jetbrains/plugins/terminal/AbstractTerminalRunner.java82
-rw-r--r--plugins/terminal/src/org/jetbrains/plugins/terminal/JBTabbedTerminalWidget.java20
-rw-r--r--plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalPanel.java100
-rw-r--r--plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalSystemSettingsProvider.java367
-rw-r--r--plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalWidget.java241
-rw-r--r--plugins/terminal/src/org/jetbrains/plugins/terminal/OpenLocalTerminalAction.java5
-rw-r--r--plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalToolWindowFactory.java2
-rw-r--r--plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalView.java54
-rw-r--r--plugins/terminal/terminal.iml1
-rw-r--r--plugins/testng/src/com/theoryinpractice/testng/model/TestData.java4
292 files changed, 5841 insertions, 3667 deletions
diff --git a/plugins/ByteCodeViewer/src/META-INF/plugin.xml b/plugins/ByteCodeViewer/src/META-INF/plugin.xml
index 9a0135ae9121..e9c6e32b977d 100644
--- a/plugins/ByteCodeViewer/src/META-INF/plugin.xml
+++ b/plugins/ByteCodeViewer/src/META-INF/plugin.xml
@@ -5,6 +5,9 @@
<description>Viewing java bytecode inside IntelliJ IDEA.</description>
<vendor>JetBrains</vendor>
+ <extensionPoints>
+ <extensionPoint name="classSearcher" interface="com.intellij.byteCodeViewer.ClassSearcher"/>
+ </extensionPoints>
<extensions defaultExtensionNs="com.intellij">
<errorHandler implementation="com.intellij.diagnostic.ITNReporter"/>
<projectService serviceInterface="com.intellij.byteCodeViewer.ByteCodeViewerManager"
diff --git a/plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/ByteCodeViewerManager.java b/plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/ByteCodeViewerManager.java
index a5fc96c7198b..7d958bb61b32 100644
--- a/plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/ByteCodeViewerManager.java
+++ b/plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/ByteCodeViewerManager.java
@@ -5,6 +5,7 @@ import com.intellij.ide.util.JavaAnonymousClassesHelper;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtilCore;
import com.intellij.openapi.project.Project;
@@ -35,6 +36,8 @@ import java.io.StringWriter;
* Date: 5/7/12
*/
public class ByteCodeViewerManager extends DockablePopupManager<ByteCodeViewerComponent> {
+ private static final ExtensionPointName<ClassSearcher> CLASS_SEARCHER_EP = ExtensionPointName.create("ByteCodeViewer.classSearcher");
+
private static final Logger LOG = Logger.getInstance("#" + ByteCodeViewerManager.class.getName());
public static final String TOOLWINDOW_ID = "Byte Code Viewer";
@@ -232,10 +235,20 @@ public class ByteCodeViewerManager extends DockablePopupManager<ByteCodeViewerCo
return ClassUtil.getJVMClassName(containingClass);
}
- private static PsiClass getContainingClass(PsiElement psiElement) {
+ public static PsiClass getContainingClass(PsiElement psiElement) {
+ for (ClassSearcher searcher : CLASS_SEARCHER_EP.getExtensions()) {
+ PsiClass aClass = searcher.findClass(psiElement);
+ if (aClass != null) {
+ return aClass;
+ }
+ }
+ return findClass(psiElement);
+ }
+
+ public static PsiClass findClass(@NotNull PsiElement psiElement) {
PsiClass containingClass = PsiTreeUtil.getParentOfType(psiElement, PsiClass.class, false);
while (containingClass instanceof PsiTypeParameter) {
- containingClass = PsiTreeUtil.getParentOfType(containingClass, PsiClass.class);
+ containingClass = PsiTreeUtil.getParentOfType(containingClass, PsiClass.class);
}
if (containingClass == null) return null;
diff --git a/plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/ClassSearcher.java b/plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/ClassSearcher.java
new file mode 100644
index 000000000000..9a778d1470c2
--- /dev/null
+++ b/plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/ClassSearcher.java
@@ -0,0 +1,14 @@
+package com.intellij.byteCodeViewer;
+
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiElement;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Created by Max Medvedev on 8/23/13
+ */
+public interface ClassSearcher {
+ @Nullable
+ PsiClass findClass(@NotNull PsiElement place);
+}
diff --git a/plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/ShowByteCodeAction.java b/plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/ShowByteCodeAction.java
index 34b5d446e3ba..76cf133e7a33 100644
--- a/plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/ShowByteCodeAction.java
+++ b/plugins/ByteCodeViewer/src/com/intellij/byteCodeViewer/ShowByteCodeAction.java
@@ -20,7 +20,6 @@ import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
-import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtilBase;
import com.intellij.psi.util.PsiUtilCore;
import com.intellij.ui.popup.NotLookupOrSearchCondition;
@@ -43,7 +42,7 @@ public class ShowByteCodeAction extends AnAction {
final PsiElement psiElement = getPsiElement(e.getDataContext(), project, e.getData(PlatformDataKeys.EDITOR));
if (psiElement != null) {
if (psiElement.getContainingFile() instanceof PsiClassOwner &&
- PsiTreeUtil.getParentOfType(psiElement, PsiClass.class, false) != null) {
+ ByteCodeViewerManager.getContainingClass(psiElement) != null) {
e.getPresentation().setEnabled(true);
}
}
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties
index f62b033c85c8..8bb0e6803a02 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/InspectionGadgetsBundle.properties
@@ -1228,6 +1228,9 @@ synchronized.method.ignore.synchronized.super.option=Ignore methods overriding a
synchronized.method.move.quickfix=Move synchronization into method
thread.run.replace.quickfix=Replace with 'start()'
volatile.field.problem.descriptor=Volatile field <code>#ref</code> of type ''{0}'' #loc
+string.format.choose.class=Choose Formatter class
+string.format.class.column.name=Additional formatter classes
+string.format.class.method.name=Additional formatter methods
exception.class.column.name=Exception class
bad.exception.thrown.problem.descriptor=Prohibited exception ''{0}'' thrown #loc
empty.catch.block.comments.option=Comments count as content
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/InspectionGadgetsFix.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/InspectionGadgetsFix.java
index 7cd60f3b9c56..d0feec6766b3 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/InspectionGadgetsFix.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/InspectionGadgetsFix.java
@@ -29,7 +29,7 @@ import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.util.PsiUtilCore;
import com.intellij.util.IncorrectOperationException;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/EmptyStatementBodyInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/EmptyStatementBodyInspection.java
index 5e3b4c4d185c..afea6ecabdc6 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/EmptyStatementBodyInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/EmptyStatementBodyInspection.java
@@ -21,7 +21,7 @@ import com.intellij.psi.*;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/MalformedFormatStringInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/MalformedFormatStringInspectionBase.java
index 1cf19734a67e..052e7424ec31 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/MalformedFormatStringInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/MalformedFormatStringInspectionBase.java
@@ -15,6 +15,8 @@
*/
package com.siyeh.ig.bugs;
+import com.intellij.openapi.util.InvalidDataException;
+import com.intellij.openapi.util.WriteExternalException;
import com.intellij.psi.*;
import com.intellij.psi.util.ConstantExpressionUtil;
import com.intellij.psi.util.PsiUtil;
@@ -23,9 +25,47 @@ import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.psiutils.ExpressionUtils;
import com.siyeh.ig.psiutils.FormatUtils;
+import org.jdom.Element;
+import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
-public class MalformedFormatStringInspection extends BaseInspection {
+import java.util.ArrayList;
+import java.util.List;
+
+public class MalformedFormatStringInspectionBase extends BaseInspection {
+ /**
+ * @noinspection PublicField
+ */
+ @NonNls public String additionalClasses = "";
+
+ /**
+ * @noinspection PublicField
+ */
+ @NonNls public String additionalMethods = "";
+
+ final List<String> classNames;
+ final List<String> methodNames;
+
+ public MalformedFormatStringInspectionBase() {
+ classNames = new ArrayList<String>();
+ methodNames = new ArrayList<String>();
+ parseString(additionalClasses, classNames);
+ parseString(additionalMethods, methodNames);
+ }
+
+ @Override
+ public void readSettings(@NotNull Element node) throws InvalidDataException {
+ super.readSettings(node);
+ parseString(additionalClasses, classNames);
+ parseString(additionalMethods, methodNames);
+ }
+
+ @Override
+ public void writeSettings(@NotNull Element node) throws WriteExternalException {
+ additionalClasses = formatString(classNames);
+ additionalMethods = formatString(methodNames);
+ super.writeSettings(node);
+ }
@Override
@NotNull
@@ -61,12 +101,12 @@ public class MalformedFormatStringInspection extends BaseInspection {
return new MalformedFormatStringVisitor();
}
- private static class MalformedFormatStringVisitor extends BaseInspectionVisitor {
+ private class MalformedFormatStringVisitor extends BaseInspectionVisitor {
@Override
public void visitMethodCallExpression(@NotNull PsiMethodCallExpression expression) {
super.visitMethodCallExpression(expression);
- if (!FormatUtils.isFormatCall(expression)) {
+ if (!FormatUtils.isFormatCall(expression, methodNames, classNames)) {
return;
}
final PsiExpressionList argumentList = expression.getArgumentList();
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/UnnecessaryContinueInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/UnnecessaryContinueInspection.java
index 36a0dc906022..77a3ab33f26a 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/UnnecessaryContinueInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/UnnecessaryContinueInspection.java
@@ -24,7 +24,7 @@ import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.ig.fixes.DeleteUnnecessaryStatementFix;
import com.siyeh.ig.psiutils.ControlFlowUtils;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/UnnecessaryReturnInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/UnnecessaryReturnInspection.java
index 5c8f1df3857b..48c10184cb54 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/UnnecessaryReturnInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/controlflow/UnnecessaryReturnInspection.java
@@ -24,7 +24,7 @@ import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.ig.fixes.DeleteUnnecessaryStatementFix;
import com.siyeh.ig.psiutils.ControlFlowUtils;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/dataflow/TooBroadScopeInspectionBase.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/dataflow/TooBroadScopeInspectionBase.java
index 07b77868fcce..435dd24cb0cd 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/dataflow/TooBroadScopeInspectionBase.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/dataflow/TooBroadScopeInspectionBase.java
@@ -27,7 +27,7 @@ import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.psiutils.ClassUtils;
import com.siyeh.ig.psiutils.ExpressionUtils;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
import com.siyeh.ig.psiutils.VariableAccessUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/EmptyCatchBlockInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/EmptyCatchBlockInspection.java
index 4a9b58bd75aa..fa50fb44cc21 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/EmptyCatchBlockInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/EmptyCatchBlockInspection.java
@@ -24,7 +24,7 @@ import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.InspectionGadgetsFix;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
import com.siyeh.ig.psiutils.TestUtils;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/EmptyFinallyBlockInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/EmptyFinallyBlockInspection.java
index 8e3fbeb5c4c9..741d7cfb8b4e 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/EmptyFinallyBlockInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/EmptyFinallyBlockInspection.java
@@ -25,7 +25,7 @@ import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.InspectionGadgetsFix;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
import org.jetbrains.annotations.NotNull;
public class EmptyFinallyBlockInspection extends BaseInspection {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/EmptyTryBlockInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/EmptyTryBlockInspection.java
index 57003f5f4a0a..04f50afdaa2d 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/EmptyTryBlockInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/EmptyTryBlockInspection.java
@@ -20,7 +20,7 @@ import com.intellij.psi.PsiTryStatement;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
import org.jetbrains.annotations.NotNull;
public class EmptyTryBlockInspection extends BaseInspection {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/JavaLangImportInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/JavaLangImportInspection.java
index 36c31ac74792..f0d521d3ed9c 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/JavaLangImportInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/JavaLangImportInspection.java
@@ -22,7 +22,7 @@ import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.ig.fixes.DeleteImportFix;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
import com.siyeh.ig.psiutils.ImportUtils;
import org.jetbrains.annotations.NotNull;
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/OnDemandImportInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/OnDemandImportInspection.java
index d9d9dd9445c2..f9d5aea7344d 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/OnDemandImportInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/OnDemandImportInspection.java
@@ -19,7 +19,7 @@ import com.intellij.psi.*;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
import org.jetbrains.annotations.NotNull;
public class OnDemandImportInspection extends BaseInspection {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/SamePackageImportInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/SamePackageImportInspection.java
index 579a20bd8861..3d9ee1148ab9 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/SamePackageImportInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/SamePackageImportInspection.java
@@ -21,7 +21,7 @@ import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.ig.fixes.DeleteImportFix;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
import org.jetbrains.annotations.NotNull;
public class SamePackageImportInspection extends BaseInspection {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/SingleClassImportInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/SingleClassImportInspection.java
index 91692ab21eb2..9bcad8fc0a95 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/SingleClassImportInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/SingleClassImportInspection.java
@@ -22,7 +22,7 @@ import com.intellij.psi.PsiJavaFile;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
import org.jetbrains.annotations.NotNull;
public class SingleClassImportInspection extends BaseInspection {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/UnusedImportInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/UnusedImportInspection.java
index 49c58d15ba56..7b6b72a2e2e8 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/UnusedImportInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/imports/UnusedImportInspection.java
@@ -21,7 +21,7 @@ import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.ig.fixes.DeleteImportFix;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/j2me/PrivateMemberAccessBetweenOuterAndInnerClassInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/j2me/PrivateMemberAccessBetweenOuterAndInnerClassInspection.java
index bc1fbe0bec87..a1952f0c747e 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/j2me/PrivateMemberAccessBetweenOuterAndInnerClassInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/j2me/PrivateMemberAccessBetweenOuterAndInnerClassInspection.java
@@ -25,7 +25,7 @@ import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.ig.psiutils.ClassUtils;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/javabeans/ClassWithoutConstructorInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/javabeans/ClassWithoutConstructorInspection.java
index 2aa3c07bf0f1..d1bd35e9e508 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/javabeans/ClassWithoutConstructorInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/javabeans/ClassWithoutConstructorInspection.java
@@ -24,7 +24,7 @@ import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.InspectionGadgetsFix;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
import org.jetbrains.annotations.NotNull;
public class ClassWithoutConstructorInspection extends BaseInspection {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/FileTypeUtils.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/FileTypeUtils.java
deleted file mode 100644
index 788812176db3..000000000000
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/FileTypeUtils.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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.siyeh.ig.psiutils;
-
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.ServerPageFile;
-import com.intellij.psi.util.PsiUtilCore;
-
-public class FileTypeUtils {
- public static boolean isInServerPageFile(PsiElement file) {
- return PsiUtilCore.getTemplateLanguageFile(file) instanceof ServerPageFile;
- }
-}
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/FormatUtils.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/FormatUtils.java
index 68e431e5652f..9be61bc1302d 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/FormatUtils.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/FormatUtils.java
@@ -20,7 +20,9 @@ import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.Nullable;
+import java.util.Collections;
import java.util.HashSet;
+import java.util.List;
import java.util.Set;
public class FormatUtils {
@@ -48,9 +50,13 @@ public class FormatUtils {
private FormatUtils() {}
public static boolean isFormatCall(PsiMethodCallExpression expression) {
+ return isFormatCall(expression, Collections.<String>emptyList(), Collections.<String>emptyList());
+ }
+
+ public static boolean isFormatCall(PsiMethodCallExpression expression, List<String> optionalMethods, List<String> optionalClasses) {
final PsiReferenceExpression methodExpression = expression.getMethodExpression();
final String name = methodExpression.getReferenceName();
- if (!formatMethodNames.contains(name)) {
+ if (!formatMethodNames.contains(name) && !optionalMethods.contains(name)) {
return false;
}
final PsiMethod method = expression.resolveMethod();
@@ -62,7 +68,7 @@ public class FormatUtils {
return false;
}
final String className = containingClass.getQualifiedName();
- return formatClassNames.contains(className);
+ return formatClassNames.contains(className) || optionalClasses.contains(className);
}
public static boolean isFormatCallArgument(PsiElement element) {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/InitializationUtils.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/InitializationUtils.java
index 29c8b46b8b44..67c6a32a60f1 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/InitializationUtils.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/InitializationUtils.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2012 Dave Griffith, Bas Leijdekkers
+ * Copyright 2003-2013 Dave Griffith, Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,58 +21,43 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.HashSet;
-import java.util.List;
import java.util.Set;
public class InitializationUtils {
private InitializationUtils() {}
- public static boolean methodAssignsVariableOrFails(
- @Nullable PsiMethod method, @NotNull PsiVariable variable) {
+ public static boolean methodAssignsVariableOrFails(@Nullable PsiMethod method, @NotNull PsiVariable variable) {
return methodAssignsVariableOrFails(method, variable, false);
}
- public static boolean expressionAssignsVariableOrFails(
- @Nullable PsiExpression expression, @NotNull PsiVariable variable) {
- return expressionAssignsVariableOrFails(expression, variable,
- new HashSet(), true);
+ public static boolean expressionAssignsVariableOrFails(@Nullable PsiExpression expression, @NotNull PsiVariable variable) {
+ return expressionAssignsVariableOrFails(expression, variable, new HashSet(), true);
}
- public static boolean methodAssignsVariableOrFails(
- @Nullable PsiMethod method, @NotNull PsiVariable variable,
- boolean strict) {
+ public static boolean methodAssignsVariableOrFails(@Nullable PsiMethod method, @NotNull PsiVariable variable, boolean strict) {
if (method == null) {
return false;
}
- final PsiCodeBlock body = method.getBody();
- return body != null && blockAssignsVariableOrFails(body, variable,
- strict);
+ return blockAssignsVariableOrFails(method.getBody(), variable, strict);
}
- public static boolean blockAssignsVariableOrFails(
- @Nullable PsiCodeBlock block, @NotNull PsiVariable variable) {
+ public static boolean blockAssignsVariableOrFails(@Nullable PsiCodeBlock block, @NotNull PsiVariable variable) {
return blockAssignsVariableOrFails(block, variable, false);
}
- public static boolean blockAssignsVariableOrFails(
- @Nullable PsiCodeBlock block, @NotNull PsiVariable variable,
- boolean strict) {
- return blockAssignsVariableOrFails(block, variable,
- new HashSet<MethodSignature>(), strict);
+ public static boolean blockAssignsVariableOrFails(@Nullable PsiCodeBlock block, @NotNull PsiVariable variable, boolean strict) {
+ return blockAssignsVariableOrFails(block, variable, new HashSet<MethodSignature>(), strict);
}
- private static boolean blockAssignsVariableOrFails(
- @Nullable PsiCodeBlock block, @NotNull PsiVariable variable,
- @NotNull Set<MethodSignature> checkedMethods, boolean strict) {
+ private static boolean blockAssignsVariableOrFails(@Nullable PsiCodeBlock block, @NotNull PsiVariable variable,
+ @NotNull Set<MethodSignature> checkedMethods, boolean strict) {
if (block == null) {
return false;
}
- final PsiStatement[] statements = block.getStatements();
int assignmentCount = 0;
- for (final PsiStatement statement : statements) {
- if (statementAssignsVariableOrFails(statement, variable,
- checkedMethods, strict)) {
+ for (final PsiStatement statement : block.getStatements()) {
+ if (statementAssignsVariableOrFails(statement, variable, checkedMethods, strict)) {
if (strict) {
assignmentCount++;
}
@@ -84,9 +69,8 @@ public class InitializationUtils {
return assignmentCount == 1;
}
- private static boolean statementAssignsVariableOrFails(
- @Nullable PsiStatement statement, PsiVariable variable,
- @NotNull Set<MethodSignature> checkedMethods, boolean strict) {
+ private static boolean statementAssignsVariableOrFails(@Nullable PsiStatement statement, PsiVariable variable,
+ @NotNull Set<MethodSignature> checkedMethods, boolean strict) {
if (statement == null) {
return false;
}
@@ -101,107 +85,70 @@ public class InitializationUtils {
return false;
}
else if (statement instanceof PsiReturnStatement) {
- final PsiReturnStatement returnStatement =
- (PsiReturnStatement)statement;
- final PsiExpression returnValue = returnStatement.getReturnValue();
- return expressionAssignsVariableOrFails(returnValue, variable,
- checkedMethods, strict);
+ final PsiReturnStatement returnStatement = (PsiReturnStatement)statement;
+ return expressionAssignsVariableOrFails(returnStatement.getReturnValue(), variable, checkedMethods, strict);
}
else if (statement instanceof PsiThrowStatement) {
- final PsiThrowStatement throwStatement =
- (PsiThrowStatement)statement;
- final PsiExpression exception = throwStatement.getException();
- return expressionAssignsVariableOrFails(exception, variable,
- checkedMethods, strict);
+ final PsiThrowStatement throwStatement = (PsiThrowStatement)statement;
+ return expressionAssignsVariableOrFails(throwStatement.getException(), variable, checkedMethods, strict);
}
else if (statement instanceof PsiExpressionListStatement) {
- final PsiExpressionListStatement list =
- (PsiExpressionListStatement)statement;
+ final PsiExpressionListStatement list = (PsiExpressionListStatement)statement;
final PsiExpressionList expressionList = list.getExpressionList();
- final PsiExpression[] expressions = expressionList.getExpressions();
- for (final PsiExpression expression : expressions) {
- if (expressionAssignsVariableOrFails(expression, variable,
- checkedMethods, strict)) {
+ for (final PsiExpression expression : expressionList.getExpressions()) {
+ if (expressionAssignsVariableOrFails(expression, variable, checkedMethods, strict)) {
return true;
}
}
return false;
}
else if (statement instanceof PsiExpressionStatement) {
- final PsiExpressionStatement expressionStatement =
- (PsiExpressionStatement)statement;
- final PsiExpression expression =
- expressionStatement.getExpression();
- return expressionAssignsVariableOrFails(expression, variable,
- checkedMethods, strict);
+ final PsiExpressionStatement expressionStatement = (PsiExpressionStatement)statement;
+ return expressionAssignsVariableOrFails(expressionStatement.getExpression(), variable, checkedMethods, strict);
}
else if (statement instanceof PsiDeclarationStatement) {
- final PsiDeclarationStatement declarationStatement =
- (PsiDeclarationStatement)statement;
- return declarationStatementAssignsVariableOrFails(
- declarationStatement, variable, checkedMethods, strict);
+ final PsiDeclarationStatement declarationStatement = (PsiDeclarationStatement)statement;
+ return declarationStatementAssignsVariableOrFails(declarationStatement, variable, checkedMethods, strict);
}
else if (statement instanceof PsiForStatement) {
final PsiForStatement forStatement = (PsiForStatement)statement;
- return forStatementAssignsVariableOrFails(forStatement,
- variable,
- checkedMethods, strict);
+ return forStatementAssignsVariableOrFails(forStatement, variable, checkedMethods, strict);
}
else if (statement instanceof PsiForeachStatement) {
- final PsiForeachStatement foreachStatement =
- (PsiForeachStatement)statement;
- return foreachStatementAssignsVariableOrFails(variable,
- foreachStatement);
+ final PsiForeachStatement foreachStatement = (PsiForeachStatement)statement;
+ return foreachStatementAssignsVariableOrFails(foreachStatement, variable, checkedMethods, strict);
}
else if (statement instanceof PsiWhileStatement) {
- final PsiWhileStatement whileStatement =
- (PsiWhileStatement)statement;
- return whileStatementAssignsVariableOrFails(whileStatement,
- variable, checkedMethods, strict);
+ final PsiWhileStatement whileStatement = (PsiWhileStatement)statement;
+ return whileStatementAssignsVariableOrFails(whileStatement, variable, checkedMethods, strict);
}
else if (statement instanceof PsiDoWhileStatement) {
- final PsiDoWhileStatement doWhileStatement =
- (PsiDoWhileStatement)statement;
- return doWhileAssignsVariableOrFails(doWhileStatement, variable,
- checkedMethods, strict);
+ final PsiDoWhileStatement doWhileStatement = (PsiDoWhileStatement)statement;
+ return doWhileAssignsVariableOrFails(doWhileStatement, variable, checkedMethods, strict);
}
else if (statement instanceof PsiSynchronizedStatement) {
- final PsiSynchronizedStatement synchronizedStatement =
- (PsiSynchronizedStatement)statement;
- final PsiCodeBlock body = synchronizedStatement.getBody();
- return blockAssignsVariableOrFails(body, variable,
- checkedMethods, strict);
+ final PsiSynchronizedStatement synchronizedStatement = (PsiSynchronizedStatement)statement;
+ return blockAssignsVariableOrFails(synchronizedStatement.getBody(), variable, checkedMethods, strict);
}
else if (statement instanceof PsiBlockStatement) {
- final PsiBlockStatement blockStatement =
- (PsiBlockStatement)statement;
- final PsiCodeBlock codeBlock = blockStatement.getCodeBlock();
- return blockAssignsVariableOrFails(codeBlock, variable,
- checkedMethods, strict);
+ final PsiBlockStatement blockStatement = (PsiBlockStatement)statement;
+ return blockAssignsVariableOrFails(blockStatement.getCodeBlock(), variable, checkedMethods, strict);
}
else if (statement instanceof PsiLabeledStatement) {
- final PsiLabeledStatement labeledStatement =
- (PsiLabeledStatement)statement;
- final PsiStatement statementLabeled =
- labeledStatement.getStatement();
- return statementAssignsVariableOrFails(statementLabeled, variable,
- checkedMethods, strict);
+ final PsiLabeledStatement labeledStatement = (PsiLabeledStatement)statement;
+ return statementAssignsVariableOrFails(labeledStatement.getStatement(), variable, checkedMethods, strict);
}
else if (statement instanceof PsiIfStatement) {
final PsiIfStatement ifStatement = (PsiIfStatement)statement;
- return ifStatementAssignsVariableOrFails(ifStatement, variable,
- checkedMethods, strict);
+ return ifStatementAssignsVariableOrFails(ifStatement, variable, checkedMethods, strict);
}
else if (statement instanceof PsiTryStatement) {
final PsiTryStatement tryStatement = (PsiTryStatement)statement;
- return tryStatementAssignsVariableOrFails(tryStatement, variable,
- checkedMethods, strict);
+ return tryStatementAssignsVariableOrFails(tryStatement, variable, checkedMethods, strict);
}
else if (statement instanceof PsiSwitchStatement) {
- final PsiSwitchStatement switchStatement =
- (PsiSwitchStatement)statement;
- return switchStatementAssignsVariableOrFails(switchStatement,
- variable, checkedMethods, strict);
+ final PsiSwitchStatement switchStatement = (PsiSwitchStatement)statement;
+ return switchStatementAssignsVariableOrFails(switchStatement, variable, checkedMethods, strict);
}
else {
// unknown statement type
@@ -209,21 +156,15 @@ public class InitializationUtils {
}
}
- public static boolean switchStatementAssignsVariableOrFails(
- @NotNull PsiSwitchStatement switchStatement,
- @NotNull PsiVariable variable,
- boolean strict) {
- return switchStatementAssignsVariableOrFails(switchStatement, variable,
- new HashSet(), strict);
+ public static boolean switchStatementAssignsVariableOrFails(@NotNull PsiSwitchStatement switchStatement, @NotNull PsiVariable variable,
+ boolean strict) {
+ return switchStatementAssignsVariableOrFails(switchStatement, variable, new HashSet(), strict);
}
- private static boolean switchStatementAssignsVariableOrFails(
- @NotNull PsiSwitchStatement switchStatement,
- @NotNull PsiVariable variable,
- @NotNull Set<MethodSignature> checkedMethods, boolean strict) {
+ private static boolean switchStatementAssignsVariableOrFails(@NotNull PsiSwitchStatement switchStatement, @NotNull PsiVariable variable,
+ @NotNull Set<MethodSignature> checkedMethods, boolean strict) {
final PsiExpression expression = switchStatement.getExpression();
- if (expressionAssignsVariableOrFails(expression, variable,
- checkedMethods, strict)) {
+ if (expressionAssignsVariableOrFails(expression, variable, checkedMethods, strict)) {
return true;
}
final PsiCodeBlock body = switchStatement.getBody();
@@ -236,8 +177,7 @@ public class InitializationUtils {
for (int i = 0; i < statements.length; i++) {
final PsiStatement statement = statements[i];
if (statement instanceof PsiSwitchLabelStatement) {
- final PsiSwitchLabelStatement labelStatement
- = (PsiSwitchLabelStatement)statement;
+ final PsiSwitchLabelStatement labelStatement = (PsiSwitchLabelStatement)statement;
if (i == statements.length - 1) {
return false;
}
@@ -247,8 +187,7 @@ public class InitializationUtils {
assigns = false;
}
else if (statement instanceof PsiBreakStatement) {
- final PsiBreakStatement breakStatement
- = (PsiBreakStatement)statement;
+ final PsiBreakStatement breakStatement = (PsiBreakStatement)statement;
if (breakStatement.getLabelIdentifier() != null) {
return false;
}
@@ -258,8 +197,7 @@ public class InitializationUtils {
assigns = false;
}
else {
- assigns |= statementAssignsVariableOrFails(statement, variable,
- checkedMethods, strict);
+ assigns |= statementAssignsVariableOrFails(statement, variable, checkedMethods, strict);
if (i == statements.length - 1 && !assigns) {
return false;
}
@@ -268,18 +206,13 @@ public class InitializationUtils {
return containsDefault;
}
- private static boolean declarationStatementAssignsVariableOrFails(
- PsiDeclarationStatement declarationStatement, PsiVariable variable,
- Set<MethodSignature> checkedMethods, boolean strict) {
- final PsiElement[] elements =
- declarationStatement.getDeclaredElements();
+ private static boolean declarationStatementAssignsVariableOrFails(PsiDeclarationStatement declarationStatement, PsiVariable variable,
+ Set<MethodSignature> checkedMethods, boolean strict) {
+ final PsiElement[] elements = declarationStatement.getDeclaredElements();
for (PsiElement element : elements) {
if (element instanceof PsiVariable) {
final PsiVariable declaredVariable = (PsiVariable)element;
- final PsiExpression initializer =
- declaredVariable.getInitializer();
- if (expressionAssignsVariableOrFails(initializer, variable,
- checkedMethods, strict)) {
+ if (expressionAssignsVariableOrFails(declaredVariable.getInitializer(), variable, checkedMethods, strict)) {
return true;
}
}
@@ -291,16 +224,14 @@ public class InitializationUtils {
@NotNull Set<MethodSignature> checkedMethods, boolean strict) {
final PsiResourceList resourceList = tryStatement.getResourceList();
if (resourceList != null) {
- final List<PsiResourceVariable> resourceVariables = resourceList.getResourceVariables();
- for (PsiResourceVariable resourceVariable : resourceVariables) {
+ for (PsiResourceVariable resourceVariable : resourceList.getResourceVariables()) {
final PsiExpression initializer = resourceVariable.getInitializer();
if (expressionAssignsVariableOrFails(initializer, variable, checkedMethods, strict)) {
return true;
}
}
}
- final PsiCodeBlock tryBlock = tryStatement.getTryBlock();
- boolean initializedInTryAndCatch = blockAssignsVariableOrFails(tryBlock, variable, checkedMethods, strict);
+ boolean initializedInTryAndCatch = blockAssignsVariableOrFails(tryStatement.getTryBlock(), variable, checkedMethods, strict);
final PsiCodeBlock[] catchBlocks = tryStatement.getCatchBlocks();
for (final PsiCodeBlock catchBlock : catchBlocks) {
if (strict) {
@@ -310,101 +241,71 @@ public class InitializationUtils {
initializedInTryAndCatch &= blockAssignsVariableOrFails(catchBlock, variable, checkedMethods, strict);
}
}
- if (initializedInTryAndCatch) {
- return true;
- }
- final PsiCodeBlock finallyBlock = tryStatement.getFinallyBlock();
- return blockAssignsVariableOrFails(finallyBlock, variable, checkedMethods, strict);
+ return initializedInTryAndCatch || blockAssignsVariableOrFails(tryStatement.getFinallyBlock(), variable, checkedMethods, strict);
}
- private static boolean ifStatementAssignsVariableOrFails(
- @NotNull PsiIfStatement ifStatement,
- PsiVariable variable,
- @NotNull Set<MethodSignature> checkedMethods,
- boolean strict) {
+ private static boolean ifStatementAssignsVariableOrFails(@NotNull PsiIfStatement ifStatement, PsiVariable variable,
+ @NotNull Set<MethodSignature> checkedMethods, boolean strict) {
final PsiExpression condition = ifStatement.getCondition();
- if (expressionAssignsVariableOrFails(condition, variable,
- checkedMethods, strict)) {
+ if (expressionAssignsVariableOrFails(condition, variable, checkedMethods, strict)) {
return true;
}
final PsiStatement thenBranch = ifStatement.getThenBranch();
- final PsiStatement elseBranch = ifStatement.getElseBranch();
if (BoolUtils.isTrue(condition)) {
- return statementAssignsVariableOrFails(thenBranch, variable,
- checkedMethods, strict);
+ return statementAssignsVariableOrFails(thenBranch, variable, checkedMethods, strict);
}
- else if (BoolUtils.isFalse(condition)) {
- return statementAssignsVariableOrFails(elseBranch, variable,
- checkedMethods, strict);
+ final PsiStatement elseBranch = ifStatement.getElseBranch();
+ if (BoolUtils.isFalse(condition)) {
+ return statementAssignsVariableOrFails(elseBranch, variable, checkedMethods, strict);
}
- return statementAssignsVariableOrFails(thenBranch, variable,
- checkedMethods, strict) &&
- statementAssignsVariableOrFails(elseBranch, variable,
- checkedMethods, strict);
+ return statementAssignsVariableOrFails(thenBranch, variable, checkedMethods, strict) &&
+ statementAssignsVariableOrFails(elseBranch, variable, checkedMethods, strict);
}
- private static boolean doWhileAssignsVariableOrFails(
- @NotNull PsiDoWhileStatement doWhileStatement,
- PsiVariable variable,
- @NotNull Set<MethodSignature> checkedMethods,
- boolean strict) {
- final PsiExpression condition = doWhileStatement.getCondition();
- final PsiStatement body = doWhileStatement.getBody();
- return expressionAssignsVariableOrFails(condition, variable,
- checkedMethods, strict) ||
- statementAssignsVariableOrFails(body, variable, checkedMethods,
- strict);
+ private static boolean doWhileAssignsVariableOrFails(@NotNull PsiDoWhileStatement doWhileStatement, PsiVariable variable,
+ @NotNull Set<MethodSignature> checkedMethods, boolean strict) {
+ return statementAssignsVariableOrFails(doWhileStatement.getBody(), variable, checkedMethods, strict) ||
+ expressionAssignsVariableOrFails(doWhileStatement.getCondition(), variable, checkedMethods, strict);
}
- private static boolean whileStatementAssignsVariableOrFails(
- @NotNull PsiWhileStatement whileStatement, PsiVariable variable,
- @NotNull Set<MethodSignature> checkedMethods,
- boolean strict) {
+ private static boolean whileStatementAssignsVariableOrFails(@NotNull PsiWhileStatement whileStatement, PsiVariable variable,
+ @NotNull Set<MethodSignature> checkedMethods, boolean strict) {
final PsiExpression condition = whileStatement.getCondition();
- if (expressionAssignsVariableOrFails(condition, variable,
- checkedMethods, strict)) {
+ if (expressionAssignsVariableOrFails(condition, variable, checkedMethods, strict)) {
return true;
}
if (BoolUtils.isTrue(condition)) {
final PsiStatement body = whileStatement.getBody();
- if (statementAssignsVariableOrFails(body, variable, checkedMethods,
- strict)) {
+ if (statementAssignsVariableOrFails(body, variable, checkedMethods, strict)) {
return true;
}
}
return false;
}
- private static boolean forStatementAssignsVariableOrFails(
- @NotNull PsiForStatement forStatement, PsiVariable variable,
- @NotNull Set<MethodSignature> checkedMethods, boolean strict) {
- final PsiStatement initialization = forStatement.getInitialization();
- if (statementAssignsVariableOrFails(initialization, variable,
- checkedMethods, strict)) {
+ private static boolean forStatementAssignsVariableOrFails(@NotNull PsiForStatement forStatement, PsiVariable variable,
+ @NotNull Set<MethodSignature> checkedMethods, boolean strict) {
+ if (statementAssignsVariableOrFails(forStatement.getInitialization(), variable, checkedMethods, strict)) {
return true;
}
- final PsiExpression test = forStatement.getCondition();
- if (expressionAssignsVariableOrFails(test, variable, checkedMethods,
- strict)) {
+ final PsiExpression condition = forStatement.getCondition();
+ if (expressionAssignsVariableOrFails(condition, variable, checkedMethods, strict)) {
return true;
}
- if (BoolUtils.isTrue(test)) {
- final PsiStatement body = forStatement.getBody();
- if (statementAssignsVariableOrFails(body, variable, checkedMethods,
- strict)) {
+ if (BoolUtils.isTrue(condition)) {
+ if (statementAssignsVariableOrFails(forStatement.getBody(), variable, checkedMethods, strict)) {
return true;
}
- final PsiStatement update = forStatement.getUpdate();
- if (statementAssignsVariableOrFails(update, variable,
- checkedMethods, strict)) {
+ if (statementAssignsVariableOrFails(forStatement.getUpdate(), variable, checkedMethods, strict)) {
return true;
}
}
return false;
}
- private static boolean foreachStatementAssignsVariableOrFails(PsiVariable field, PsiForeachStatement forStatement) {
- return false;
+ private static boolean foreachStatementAssignsVariableOrFails(@NotNull PsiForeachStatement foreachStatement, PsiVariable field,
+ @NotNull Set<MethodSignature> checkedMethods, boolean strict) {
+ return expressionAssignsVariableOrFails(foreachStatement.getIteratedValue(), field, checkedMethods, strict);
}
private static boolean expressionAssignsVariableOrFails(@Nullable PsiExpression expression, PsiVariable variable,
@@ -421,8 +322,7 @@ public class InitializationUtils {
}
else if (expression instanceof PsiParenthesizedExpression) {
final PsiParenthesizedExpression parenthesizedExpression = (PsiParenthesizedExpression)expression;
- final PsiExpression unparenthesizedExpression = parenthesizedExpression.getExpression();
- return expressionAssignsVariableOrFails(unparenthesizedExpression, variable, checkedMethods, strict);
+ return expressionAssignsVariableOrFails(parenthesizedExpression.getExpression(), variable, checkedMethods, strict);
}
else if (expression instanceof PsiMethodCallExpression) {
final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)expression;
@@ -434,8 +334,7 @@ public class InitializationUtils {
}
else if (expression instanceof PsiArrayInitializerExpression) {
final PsiArrayInitializerExpression array = (PsiArrayInitializerExpression)expression;
- final PsiExpression[] initializers = array.getInitializers();
- for (final PsiExpression initializer : initializers) {
+ for (final PsiExpression initializer : array.getInitializers()) {
if (expressionAssignsVariableOrFails(initializer, variable, checkedMethods, strict)) {
return true;
}
@@ -444,30 +343,24 @@ public class InitializationUtils {
}
else if (expression instanceof PsiTypeCastExpression) {
final PsiTypeCastExpression typeCast = (PsiTypeCastExpression)expression;
- final PsiExpression operand = typeCast.getOperand();
- return expressionAssignsVariableOrFails(operand, variable, checkedMethods, strict);
+ return expressionAssignsVariableOrFails(typeCast.getOperand(), variable, checkedMethods, strict);
}
else if (expression instanceof PsiArrayAccessExpression) {
final PsiArrayAccessExpression accessExpression = (PsiArrayAccessExpression)expression;
- final PsiExpression arrayExpression = accessExpression.getArrayExpression();
- final PsiExpression indexExpression = accessExpression.getIndexExpression();
- return expressionAssignsVariableOrFails(arrayExpression, variable, checkedMethods, strict) ||
- expressionAssignsVariableOrFails(indexExpression, variable, checkedMethods, strict);
+ return expressionAssignsVariableOrFails(accessExpression.getArrayExpression(), variable, checkedMethods, strict) ||
+ expressionAssignsVariableOrFails(accessExpression.getIndexExpression(), variable, checkedMethods, strict);
}
else if (expression instanceof PsiPrefixExpression) {
final PsiPrefixExpression prefixExpression = (PsiPrefixExpression)expression;
- final PsiExpression operand = prefixExpression.getOperand();
- return expressionAssignsVariableOrFails(operand, variable, checkedMethods, strict);
+ return expressionAssignsVariableOrFails(prefixExpression.getOperand(), variable, checkedMethods, strict);
}
else if (expression instanceof PsiPostfixExpression) {
final PsiPostfixExpression postfixExpression = (PsiPostfixExpression)expression;
- final PsiExpression operand = postfixExpression.getOperand();
- return expressionAssignsVariableOrFails(operand, variable, checkedMethods, strict);
+ return expressionAssignsVariableOrFails(postfixExpression.getOperand(), variable, checkedMethods, strict);
}
else if (expression instanceof PsiPolyadicExpression) {
final PsiPolyadicExpression polyadicExpression = (PsiPolyadicExpression)expression;
- final PsiExpression[] operands = polyadicExpression.getOperands();
- for (PsiExpression operand : operands) {
+ for (PsiExpression operand : polyadicExpression.getOperands()) {
if (expressionAssignsVariableOrFails(operand, variable, checkedMethods, strict)) {
return true;
}
@@ -476,14 +369,11 @@ public class InitializationUtils {
}
else if (expression instanceof PsiConditionalExpression) {
final PsiConditionalExpression conditional = (PsiConditionalExpression)expression;
- final PsiExpression condition = conditional.getCondition();
- if (expressionAssignsVariableOrFails(condition, variable, checkedMethods, strict)) {
+ if (expressionAssignsVariableOrFails(conditional.getCondition(), variable, checkedMethods, strict)) {
return true;
}
- final PsiExpression thenExpression = conditional.getThenExpression();
- final PsiExpression elseExpression = conditional.getElseExpression();
- return expressionAssignsVariableOrFails(thenExpression, variable, checkedMethods, strict) &&
- expressionAssignsVariableOrFails(elseExpression, variable, checkedMethods, strict);
+ return expressionAssignsVariableOrFails(conditional.getThenExpression(), variable, checkedMethods, strict) &&
+ expressionAssignsVariableOrFails(conditional.getElseExpression(), variable, checkedMethods, strict);
}
else if (expression instanceof PsiAssignmentExpression) {
final PsiAssignmentExpression assignment = (PsiAssignmentExpression)expression;
@@ -491,13 +381,12 @@ public class InitializationUtils {
if (expressionAssignsVariableOrFails(lhs, variable, checkedMethods, strict)) {
return true;
}
- final PsiExpression rhs = assignment.getRExpression();
- if (expressionAssignsVariableOrFails(rhs, variable, checkedMethods, strict)) {
+ if (expressionAssignsVariableOrFails(assignment.getRExpression(), variable, checkedMethods, strict)) {
return true;
}
if (lhs instanceof PsiReferenceExpression) {
final PsiElement element = ((PsiReference)lhs).resolve();
- if (element != null && element.equals(variable)) {
+ if (variable.equals(element)) {
return true;
}
}
@@ -505,85 +394,64 @@ public class InitializationUtils {
}
else if (expression instanceof PsiInstanceOfExpression) {
final PsiInstanceOfExpression instanceOfExpression = (PsiInstanceOfExpression)expression;
- final PsiExpression operand = instanceOfExpression.getOperand();
- return expressionAssignsVariableOrFails(operand, variable, checkedMethods, strict);
+ return expressionAssignsVariableOrFails(instanceOfExpression.getOperand(), variable, checkedMethods, strict);
}
else {
return false;
}
}
- private static boolean newExpressionAssignsVariableOrFails(
- @NotNull PsiNewExpression newExpression, PsiVariable variable,
- @NotNull Set<MethodSignature> checkedMethods, boolean strict) {
+ private static boolean newExpressionAssignsVariableOrFails(@NotNull PsiNewExpression newExpression, PsiVariable variable,
+ @NotNull Set<MethodSignature> checkedMethods, boolean strict) {
final PsiExpressionList argumentList = newExpression.getArgumentList();
if (argumentList != null) {
- final PsiExpression[] args = argumentList.getExpressions();
- for (final PsiExpression arg : args) {
- if (expressionAssignsVariableOrFails(arg, variable,
- checkedMethods, strict)) {
+ for (final PsiExpression argument : argumentList.getExpressions()) {
+ if (expressionAssignsVariableOrFails(argument, variable, checkedMethods, strict)) {
return true;
}
}
}
- final PsiArrayInitializerExpression arrayInitializer =
- newExpression.getArrayInitializer();
- if (expressionAssignsVariableOrFails(arrayInitializer, variable,
- checkedMethods, strict)) {
+ if (expressionAssignsVariableOrFails(newExpression.getArrayInitializer(), variable, checkedMethods, strict)) {
return true;
}
- final PsiExpression[] arrayDimensions =
- newExpression.getArrayDimensions();
- for (final PsiExpression dim : arrayDimensions) {
- if (expressionAssignsVariableOrFails(dim, variable,
- checkedMethods, strict)) {
+ for (final PsiExpression dimension : newExpression.getArrayDimensions()) {
+ if (expressionAssignsVariableOrFails(dimension, variable, checkedMethods, strict)) {
return true;
}
}
return false;
}
- private static boolean methodCallAssignsVariableOrFails(
- @NotNull PsiMethodCallExpression callExpression,
- PsiVariable variable,
- @NotNull Set<MethodSignature> checkedMethods, boolean strict) {
- final PsiExpressionList argList = callExpression.getArgumentList();
- final PsiExpression[] args = argList.getExpressions();
- for (final PsiExpression arg : args) {
- if (expressionAssignsVariableOrFails(arg, variable, checkedMethods,
- strict)) {
+ private static boolean methodCallAssignsVariableOrFails(@NotNull PsiMethodCallExpression callExpression, PsiVariable variable,
+ @NotNull Set<MethodSignature> checkedMethods, boolean strict) {
+ final PsiExpressionList argumentList = callExpression.getArgumentList();
+ for (final PsiExpression argument : argumentList.getExpressions()) {
+ if (expressionAssignsVariableOrFails(argument, variable, checkedMethods, strict)) {
return true;
}
}
- final PsiReferenceExpression methodExpression =
- callExpression.getMethodExpression();
- if (expressionAssignsVariableOrFails(methodExpression, variable,
- checkedMethods, strict)) {
+ if (expressionAssignsVariableOrFails(callExpression.getMethodExpression(), variable, checkedMethods, strict)) {
return true;
}
final PsiMethod method = callExpression.resolveMethod();
if (method == null) {
return false;
}
- final MethodSignature methodSignature =
- method.getSignature(PsiSubstitutor.EMPTY);
+ final MethodSignature methodSignature = method.getSignature(PsiSubstitutor.EMPTY);
if (!checkedMethods.add(methodSignature)) {
return false;
}
- final PsiClass containingClass =
- ClassUtils.getContainingClass(callExpression);
+ final PsiClass containingClass = ClassUtils.getContainingClass(callExpression);
final PsiClass calledClass = method.getContainingClass();
if (calledClass == null || !calledClass.equals(containingClass)) {
return false;
}
if (method.hasModifierProperty(PsiModifier.STATIC)
- || method.isConstructor()
|| method.hasModifierProperty(PsiModifier.PRIVATE)
|| method.hasModifierProperty(PsiModifier.FINAL)
+ || method.isConstructor()
|| calledClass.hasModifierProperty(PsiModifier.FINAL)) {
- final PsiCodeBlock body = method.getBody();
- return blockAssignsVariableOrFails(body, variable,
- checkedMethods, strict);
+ return blockAssignsVariableOrFails(method.getBody(), variable, checkedMethods, strict);
}
return false;
}
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/security/DesignForExtensionInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/security/DesignForExtensionInspection.java
index 7df6ad23aacd..5a90d4b3fad8 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/security/DesignForExtensionInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/security/DesignForExtensionInspection.java
@@ -20,7 +20,7 @@ import com.intellij.psi.*;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
import org.jetbrains.annotations.NotNull;
public class DesignForExtensionInspection extends BaseInspection {
diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/EmptySynchronizedStatementInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/EmptySynchronizedStatementInspection.java
index 43060f727079..4a9e0f1dddac 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/EmptySynchronizedStatementInspection.java
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/threading/EmptySynchronizedStatementInspection.java
@@ -21,7 +21,7 @@ import com.intellij.psi.PsiSynchronizedStatement;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
import org.jetbrains.annotations.NotNull;
public class EmptySynchronizedStatementInspection extends BaseInspection {
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/MalformedFormatStringInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/MalformedFormatStringInspection.java
new file mode 100644
index 000000000000..4f657fd6bfc9
--- /dev/null
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/MalformedFormatStringInspection.java
@@ -0,0 +1,45 @@
+/*
+ * 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.siyeh.ig.bugs;
+
+import com.intellij.codeInspection.ui.ListTable;
+import com.intellij.codeInspection.ui.ListWrappingTableModel;
+import com.siyeh.InspectionGadgetsBundle;
+import com.siyeh.ig.ui.UiUtils;
+
+import javax.swing.*;
+
+public class MalformedFormatStringInspection extends MalformedFormatStringInspectionBase {
+ @Override
+ public JComponent createOptionsPanel() {
+ ListWrappingTableModel classTableModel =
+ new ListWrappingTableModel(classNames, InspectionGadgetsBundle.message("string.format.class.column.name"));
+ JPanel classChooserPanel = UiUtils
+ .createAddRemoveTreeClassChooserPanel(new ListTable(classTableModel), InspectionGadgetsBundle.message("string.format.choose.class"));
+
+ ListWrappingTableModel methodTableModel =
+ new ListWrappingTableModel(methodNames, InspectionGadgetsBundle.message("string.format.class.method.name"));
+ JPanel methodPanel = UiUtils.createAddRemovePanel(new ListTable(methodTableModel));
+
+ final JPanel panel = new JPanel();
+ BoxLayout boxLayout = new BoxLayout(panel, BoxLayout.Y_AXIS);
+ panel.setLayout(boxLayout);
+
+ panel.add(classChooserPanel);
+ panel.add(methodPanel);
+ return panel;
+ }
+}
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/classlayout/ClassInTopLevelPackageInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/classlayout/ClassInTopLevelPackageInspection.java
index 9b5861c3b660..9b520199f90c 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/classlayout/ClassInTopLevelPackageInspection.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/classlayout/ClassInTopLevelPackageInspection.java
@@ -24,7 +24,7 @@ import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.ig.fixes.MoveClassFix;
import com.siyeh.ig.psiutils.ClassUtils;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
import org.jetbrains.annotations.NotNull;
public class ClassInTopLevelPackageInspection extends BaseInspection {
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/classlayout/ClassNameDiffersFromFileNameInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/classlayout/ClassNameDiffersFromFileNameInspection.java
index cd7c3c0f7a26..9866dc66e421 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/classlayout/ClassNameDiffersFromFileNameInspection.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/classlayout/ClassNameDiffersFromFileNameInspection.java
@@ -23,7 +23,7 @@ import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.ig.fixes.RenameFix;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/classlayout/EmptyClassInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/classlayout/EmptyClassInspection.java
index 85b42f1ebd4b..85a6dff51fde 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/classlayout/EmptyClassInspection.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/classlayout/EmptyClassInspection.java
@@ -25,7 +25,7 @@ import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.ig.fixes.AddToIgnoreIfAnnotatedByListQuickFix;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
import com.siyeh.ig.ui.ExternalizableStringSet;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/errorhandling/BadExceptionDeclaredInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/errorhandling/BadExceptionDeclaredInspection.java
index 98357a2e5020..5ce1f400d165 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/errorhandling/BadExceptionDeclaredInspection.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/errorhandling/BadExceptionDeclaredInspection.java
@@ -133,10 +133,8 @@ public class BadExceptionDeclaredInspection extends BaseInspection {
super.visitMethod(method);
if (ignoreTestCases) {
final PsiClass containingClass = method.getContainingClass();
- if (containingClass != null && TestFrameworks.getInstance().isTestClass(containingClass)) {
- return;
- }
- if (TestUtils.isJUnitTestMethod(method)) {
+ final TestFrameworks testFrameworks = TestFrameworks.getInstance();
+ if (containingClass != null && testFrameworks.isTestOrConfig(containingClass)) {
return;
}
}
diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/imports/StaticImportInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/imports/StaticImportInspection.java
index 5defb344a335..e2a88f311c75 100644
--- a/plugins/InspectionGadgets/src/com/siyeh/ig/imports/StaticImportInspection.java
+++ b/plugins/InspectionGadgets/src/com/siyeh/ig/imports/StaticImportInspection.java
@@ -28,7 +28,7 @@ import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.InspectionGadgetsFix;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
import com.siyeh.ig.psiutils.StringUtils;
import com.siyeh.ig.psiutils.TestUtils;
import com.siyeh.ig.ui.UiUtils;
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/malformed_format_string/MalformedFormatString.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/malformed_format_string/MalformedFormatString.java
index 4835464100b7..dc5802943dd8 100644
--- a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/malformed_format_string/MalformedFormatString.java
+++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/malformed_format_string/MalformedFormatString.java
@@ -27,4 +27,15 @@ public class MalformedFormatString {
public void outOfMemory() {
String.format("%2147483640$s", "s");
}
+
+ public void optionalSettings() {
+ SomeOtherLogger logger = new SomeOtherLogger();
+ logger.d("%s %s", 1); // this is invalid according to the inspector (correct)
+ }
+
+ public class SomeOtherLogger {
+ public void d(String message, Object...args) {
+ // Do some logging.
+ }
+ }
}
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/malformed_format_string/expected.xml b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/malformed_format_string/expected.xml
index 7d528e94ae26..494e16062a4a 100644
--- a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/malformed_format_string/expected.xml
+++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/malformed_format_string/expected.xml
@@ -56,10 +56,17 @@
<description>Too few arguments for format string &quot;%s %s&quot; + &quot;hmm&quot; #loc</description>
</problem>
- <problem>
- <file>MalformedFormatString.java</file>
- <line>28</line>
- <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Malformed format string</problem_class>
- <description>Too few arguments for format string &quot;%2147483640$s&quot; #loc</description>
- </problem>
+ <problem>
+ <file>MalformedFormatString.java</file>
+ <line>28</line>
+ <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Malformed format string</problem_class>
+ <description>Too few arguments for format string &quot;%2147483640$s&quot; #loc</description>
+ </problem>
+
+ <problem>
+ <file>MalformedFormatString.java</file>
+ <line>33</line>
+ <problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Malformed format string</problem_class>
+ <description>Too few arguments for format string &quot;%s %s&quot; #loc</description>
+ </problem>
</problems> \ No newline at end of file
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/initialization/field/InstanceVariableInitialization.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/initialization/field/InstanceVariableInitialization.java
index 7973f523ecf5..e5ce63603346 100644
--- a/plugins/InspectionGadgets/test/com/siyeh/igtest/initialization/field/InstanceVariableInitialization.java
+++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/initialization/field/InstanceVariableInitialization.java
@@ -93,4 +93,10 @@ class C {
C() {
boolean b = (o = "") instanceof String;
}
+}
+class D {
+ private java.util.List l;
+ D() {
+ for (Object o : l = new java.util.ArrayList()) {}
+ }
} \ No newline at end of file
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/MalformedFormatStringInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/MalformedFormatStringInspectionTest.java
index 769a5fd94cab..6d0149c9d8f1 100644
--- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/MalformedFormatStringInspectionTest.java
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/MalformedFormatStringInspectionTest.java
@@ -5,7 +5,10 @@ import com.siyeh.ig.IGInspectionTestCase;
public class MalformedFormatStringInspectionTest extends IGInspectionTestCase {
public void test() throws Exception {
- doTest("com/siyeh/igtest/bugs/malformed_format_string",
- new MalformedFormatStringInspection());
+ MalformedFormatStringInspection inspection = new MalformedFormatStringInspection();
+ inspection.classNames.add("com.siyeh.igtest.bugs.malformed_format_string.MalformedFormatString.SomeOtherLogger");
+ inspection.methodNames.add("d");
+
+ doTest("com/siyeh/igtest/bugs/malformed_format_string", inspection);
}
} \ No newline at end of file
diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/braces/RemoveBracesIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/braces/RemoveBracesIntention.java
index b977e1c43cfd..e07e0dfe9108 100644
--- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/braces/RemoveBracesIntention.java
+++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/braces/RemoveBracesIntention.java
@@ -17,7 +17,7 @@ package com.siyeh.ipp.braces;
import com.intellij.psi.*;
import com.intellij.util.IncorrectOperationException;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
import com.siyeh.ipp.base.PsiElementPredicate;
import org.jetbrains.annotations.NotNull;
diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/conditional/ReplaceConditionalWithIfPredicate.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/conditional/ReplaceConditionalWithIfPredicate.java
index 5fe305e286cc..597d95c422d9 100644
--- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/conditional/ReplaceConditionalWithIfPredicate.java
+++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/conditional/ReplaceConditionalWithIfPredicate.java
@@ -17,7 +17,7 @@ package com.siyeh.ipp.conditional;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
-import com.siyeh.ig.psiutils.FileTypeUtils;
+import com.intellij.psi.util.FileTypeUtils;
import com.siyeh.ipp.base.PsiElementPredicate;
class ReplaceConditionalWithIfPredicate implements PsiElementPredicate {
diff --git a/plugins/devkit/src/dom/impl/ExtensionDomExtender.java b/plugins/devkit/src/dom/impl/ExtensionDomExtender.java
index eec055f3cc46..a76c166f43f8 100644
--- a/plugins/devkit/src/dom/impl/ExtensionDomExtender.java
+++ b/plugins/devkit/src/dom/impl/ExtensionDomExtender.java
@@ -41,6 +41,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.devkit.dom.*;
+import java.lang.annotation.Annotation;
import java.util.*;
/**
@@ -48,16 +49,70 @@ import java.util.*;
*/
public class ExtensionDomExtender extends DomExtender<Extensions> {
private static final PsiClassConverter CLASS_CONVERTER = new PluginPsiClassConverter();
+
+ private static class MyRequired implements Required {
+ @Override
+ public boolean value() {
+ return true;
+ }
+
+ @Override
+ public boolean nonEmpty() {
+ return true;
+ }
+
+ @Override
+ public boolean identifier() {
+ return false;
+ }
+
+ @Override
+ public Class<? extends Annotation> annotationType() {
+ return Required.class;
+ }
+ }
+
+ private static class MyExtendClass extends ExtendClassImpl {
+ private final String myInterfaceName;
+
+ private MyExtendClass(String interfaceName) {
+ myInterfaceName = interfaceName;
+ }
+
+ @Override
+ public boolean allowAbstract() {
+ return false;
+ }
+
+ @Override
+ public boolean allowInterface() {
+ return false;
+ }
+
+ @Override
+ public boolean allowEnum() {
+ return false;
+ }
+
+ @Override
+ public String value() {
+ return myInterfaceName;
+ }
+ }
+
private static final DomExtender EXTENSION_EXTENDER = new DomExtender() {
public void registerExtensions(@NotNull final DomElement domElement, @NotNull final DomExtensionsRegistrar registrar) {
final ExtensionPoint extensionPoint = (ExtensionPoint)domElement.getChildDescription().getDomDeclaration();
assert extensionPoint != null;
- String interfaceName = extensionPoint.getInterface().getStringValue();
+ final String interfaceName = extensionPoint.getInterface().getStringValue();
final Project project = extensionPoint.getManager().getProject();
if (interfaceName != null) {
- registrar.registerGenericAttributeValueChildExtension(new XmlName("implementation"), PsiClass.class).setConverter(CLASS_CONVERTER);
+ registrar.registerGenericAttributeValueChildExtension(new XmlName("implementation"), PsiClass.class)
+ .setConverter(CLASS_CONVERTER)
+ .addCustomAnnotation(new MyExtendClass(interfaceName))
+ .addCustomAnnotation(new MyRequired());
registerXmlb(registrar, JavaPsiFacade.getInstance(project).findClass(interfaceName, GlobalSearchScope.allScope(project)),
Collections.<With>emptyList());
}
diff --git a/plugins/devkit/src/projectRoots/IdeaJdk.java b/plugins/devkit/src/projectRoots/IdeaJdk.java
index 6b40ced49796..a958af18d949 100644
--- a/plugins/devkit/src/projectRoots/IdeaJdk.java
+++ b/plugins/devkit/src/projectRoots/IdeaJdk.java
@@ -121,7 +121,7 @@ public class IdeaJdk extends JavaDependentSdkType implements JavaSdkType {
}
@Nullable
- public final String getVersionString(final Sdk sdk) {
+ public final String getVersionString(@NotNull final Sdk sdk) {
final Sdk internalJavaSdk = getInternalJavaSdk(sdk);
return internalJavaSdk != null ? internalJavaSdk.getVersionString() : null;
}
@@ -401,13 +401,13 @@ public class IdeaJdk extends JavaDependentSdkType implements JavaSdkType {
}
@Nullable
- public String getBinPath(Sdk sdk) {
+ public String getBinPath(@NotNull Sdk sdk) {
final Sdk internalJavaSdk = getInternalJavaSdk(sdk);
return internalJavaSdk == null ? null : JavaSdk.getInstance().getBinPath(internalJavaSdk);
}
@Nullable
- public String getToolsPath(Sdk sdk) {
+ public String getToolsPath(@NotNull Sdk sdk) {
final Sdk jdk = getInternalJavaSdk(sdk);
if (jdk != null && jdk.getVersionString() != null){
return JavaSdk.getInstance().getToolsPath(jdk);
@@ -416,12 +416,12 @@ public class IdeaJdk extends JavaDependentSdkType implements JavaSdkType {
}
@Nullable
- public String getVMExecutablePath(Sdk sdk) {
+ public String getVMExecutablePath(@NotNull Sdk sdk) {
final Sdk internalJavaSdk = getInternalJavaSdk(sdk);
return internalJavaSdk == null ? null : JavaSdk.getInstance().getVMExecutablePath(internalJavaSdk);
}
- public void saveAdditionalData(SdkAdditionalData additionalData, Element additional) {
+ public void saveAdditionalData(@NotNull SdkAdditionalData additionalData, @NotNull Element additional) {
if (additionalData instanceof Sandbox) {
try {
((Sandbox)additionalData).writeExternal(additional);
@@ -432,7 +432,7 @@ public class IdeaJdk extends JavaDependentSdkType implements JavaSdkType {
}
}
- public SdkAdditionalData loadAdditionalData(Sdk sdk, Element additional) {
+ public SdkAdditionalData loadAdditionalData(@NotNull Sdk sdk, Element additional) {
Sandbox sandbox = new Sandbox(sdk);
try {
sandbox.readExternal(additional);
diff --git a/plugins/devkit/testData/codeInsight/ExtensionQualifiedName.xml b/plugins/devkit/testData/codeInsight/ExtensionQualifiedName.xml
index e74bde491efe..d5b03f845235 100644
--- a/plugins/devkit/testData/codeInsight/ExtensionQualifiedName.xml
+++ b/plugins/devkit/testData/codeInsight/ExtensionQualifiedName.xml
@@ -6,7 +6,12 @@
</extensionPoints>
<extensions defaultExtensionNs="com.intellij.myPlugin">
- <ext implementation="java.lang.Runnable"/>
+ <<error descr="'implementation' attribute should be defined">ext</error>/>
+ <ext implementation="<error descr="Interface not allowed">java.lang.Runnable</error>"/>
+ <ext implementation="<error descr="'java.util.concurrent.TimeUnit' is not assignable to 'java.lang.Runnable'"><error descr="Enum not allowed">java.util.concurrent.TimeUnit</error></error>"/>
+ <ext implementation="<error descr="'java.lang.String' is not assignable to 'java.lang.Runnable'">java.lang.String</error>"/>
+
+ <ext implementation="foo.MyRunnable"/>
</extensions>
</idea-plugin> \ No newline at end of file
diff --git a/plugins/devkit/testSources/codeInsight/PluginXmlFunctionalTest.groovy b/plugins/devkit/testSources/codeInsight/PluginXmlFunctionalTest.groovy
index 52c78570200c..1ba75d4622e6 100644
--- a/plugins/devkit/testSources/codeInsight/PluginXmlFunctionalTest.groovy
+++ b/plugins/devkit/testSources/codeInsight/PluginXmlFunctionalTest.groovy
@@ -117,6 +117,7 @@ public class PluginXmlFunctionalTest extends JavaCodeInsightFixtureTestCase {
}
public void testExtensionQualifiedName() throws Throwable {
+ myFixture.addClass("package foo; public class MyRunnable implements java.lang.Runnable {}");
configureByFile();
myFixture.checkHighlighting(false, false, false);
}
diff --git a/plugins/git4idea/src/git4idea/commands/GitSimpleHandler.java b/plugins/git4idea/src/git4idea/commands/GitSimpleHandler.java
index 6cef328bfa2a..873b395e34ea 100644
--- a/plugins/git4idea/src/git4idea/commands/GitSimpleHandler.java
+++ b/plugins/git4idea/src/git4idea/commands/GitSimpleHandler.java
@@ -133,8 +133,7 @@ public class GitSimpleHandler extends GitTextHandler {
return;
}
entire.append(text);
- if (suppressed || myVcs == null) {
- LOG.debug(text);
+ if (myVcs == null || (suppressed && !LOG.isDebugEnabled())) {
return;
}
int last = lineRest.length() > 0 ? lineRest.charAt(lineRest.length() - 1) : -1;
@@ -158,13 +157,19 @@ public class GitSimpleHandler extends GitTextHandler {
else {
line = text.substring(start, savedPos);
}
- if (ProcessOutputTypes.STDOUT == outputType && !StringUtil.isEmptyOrSpaces(line)) {
- myVcs.showMessages(line);
- LOG.info(line.trim());
- }
- else if (ProcessOutputTypes.STDERR == outputType && !StringUtil.isEmptyOrSpaces(line)) {
- myVcs.showErrorMessages(line);
- LOG.info(line.trim());
+ if (!StringUtil.isEmptyOrSpaces(line)) {
+ if (!suppressed) {
+ LOG.info(line.trim());
+ if (ProcessOutputTypes.STDOUT == outputType) {
+ myVcs.showMessages(line);
+ }
+ else if (ProcessOutputTypes.STDERR == outputType) {
+ myVcs.showErrorMessages(line);
+ }
+ }
+ else {
+ LOG.debug(line.trim());
+ }
}
}
start = savedPos;
diff --git a/plugins/github/src/org/jetbrains/plugins/github/api/GithubApiUtil.java b/plugins/github/src/org/jetbrains/plugins/github/api/GithubApiUtil.java
index 2f634d08b939..98540470aadc 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/api/GithubApiUtil.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/api/GithubApiUtil.java
@@ -28,6 +28,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.github.exceptions.GithubAuthenticationException;
import org.jetbrains.plugins.github.exceptions.GithubJsonException;
+import org.jetbrains.plugins.github.exceptions.GithubRateLimitExceededException;
import org.jetbrains.plugins.github.exceptions.GithubStatusCodeException;
import org.jetbrains.plugins.github.util.GithubAuthData;
import org.jetbrains.plugins.github.util.GithubSslSupport;
@@ -209,7 +210,11 @@ public class GithubApiUtil {
case HttpStatus.SC_UNAUTHORIZED:
case HttpStatus.SC_PAYMENT_REQUIRED:
case HttpStatus.SC_FORBIDDEN:
- throw new GithubAuthenticationException("Request response: " + getErrorMessage(method));
+ String message = getErrorMessage(method);
+ if (message.contains("API rate limit exceeded")) {
+ throw new GithubRateLimitExceededException(message);
+ }
+ throw new GithubAuthenticationException("Request response: " + message);
default:
throw new GithubStatusCodeException(code + ": " + getErrorMessage(method), code);
}
@@ -535,11 +540,15 @@ public class GithubApiUtil {
return createDataFromRaw(fromJson(postRequest(auth, path, gson.toJson(request)), GithubRepoRaw.class), GithubRepo.class);
}
+ /*
+ * Open issues only
+ */
@NotNull
public static List<GithubIssue> getIssuesAssigned(@NotNull GithubAuthData auth,
@NotNull String user,
@NotNull String repo,
- @Nullable String assigned) throws IOException {
+ @Nullable String assigned,
+ int max) throws IOException {
String path;
if (StringUtil.isEmptyOrSpaces(assigned)) {
path = "/repos/" + user + "/" + repo + "/issues?" + PER_PAGE;
@@ -550,10 +559,17 @@ public class GithubApiUtil {
PagedRequest<GithubIssue> request = new PagedRequest<GithubIssue>(path, GithubIssue.class, GithubIssueRaw[].class);
- return request.getAll(auth);
+ List<GithubIssue> result = new ArrayList<GithubIssue>();
+ while (request.hasNext() && max > result.size()) {
+ result.addAll(request.next(auth));
+ }
+ return result;
}
@NotNull
+ /*
+ * All issues - open and closed
+ */
public static List<GithubIssue> getIssuesQueried(@NotNull GithubAuthData auth,
@NotNull String user,
@NotNull String repo,
@@ -601,6 +617,32 @@ public class GithubApiUtil {
}
@NotNull
+ public static List<GithubCommitComment> getCommitComments(@NotNull GithubAuthData auth,
+ @NotNull String user,
+ @NotNull String repo,
+ @NotNull String sha) throws IOException {
+ String path = "/repos/" + user + "/" + repo + "/commits/" + sha + "/comments";
+
+ PagedRequest<GithubCommitComment> request =
+ new PagedRequest<GithubCommitComment>(path, GithubCommitComment.class, GithubCommitCommentRaw[].class, ACCEPT_HTML_BODY_MARKUP);
+
+ return request.getAll(auth);
+ }
+
+ @NotNull
+ public static List<GithubCommitComment> getPullRequestComments(@NotNull GithubAuthData auth,
+ @NotNull String user,
+ @NotNull String repo,
+ long id) throws IOException {
+ String path = "/repos/" + user + "/" + repo + "/pulls/" + id + "/comments";
+
+ PagedRequest<GithubCommitComment> request =
+ new PagedRequest<GithubCommitComment>(path, GithubCommitComment.class, GithubCommitCommentRaw[].class, ACCEPT_HTML_BODY_MARKUP);
+
+ return request.getAll(auth);
+ }
+
+ @NotNull
public static GithubPullRequest getPullRequest(@NotNull GithubAuthData auth, @NotNull String user, @NotNull String repo, int id)
throws IOException {
String path = "/repos/" + user + "/" + repo + "/pulls/" + id;
diff --git a/plugins/github/src/org/jetbrains/plugins/github/api/GithubCommitComment.java b/plugins/github/src/org/jetbrains/plugins/github/api/GithubCommitComment.java
new file mode 100644
index 000000000000..1f13de7bb57f
--- /dev/null
+++ b/plugins/github/src/org/jetbrains/plugins/github/api/GithubCommitComment.java
@@ -0,0 +1,102 @@
+/*
+ * 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 org.jetbrains.plugins.github.api;
+
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Date;
+
+/**
+ * @author Aleksey Pivovarov
+ */
+@SuppressWarnings("UnusedDeclaration")
+public class GithubCommitComment {
+ @NotNull private final String myHtmlUrl;
+
+ private final long myId;
+ @NotNull private final String mySha;
+ @NotNull private final String myPath;
+ private final long myPosition; // line number in diff
+ @NotNull private final String myBodyHtml;
+
+ @NotNull private final GithubUser myUser;
+
+ @NotNull private final Date myCreatedAt;
+ @NotNull private final Date myUpdatedAt;
+
+ public GithubCommitComment(@NotNull String htmlUrl,
+ long id,
+ @NotNull String sha,
+ @NotNull String path,
+ long position,
+ @NotNull String bodyHtml,
+ @NotNull GithubUser user,
+ @NotNull Date createdAt,
+ @NotNull Date updatedAt) {
+ myHtmlUrl = htmlUrl;
+ myId = id;
+ mySha = sha;
+ myPath = path;
+ myPosition = position;
+ myBodyHtml = bodyHtml;
+ myUser = user;
+ myCreatedAt = createdAt;
+ myUpdatedAt = updatedAt;
+ }
+
+ @NotNull
+ public String getHtmlUrl() {
+ return myHtmlUrl;
+ }
+
+ public long getId() {
+ return myId;
+ }
+
+ @NotNull
+ public String getSha() {
+ return mySha;
+ }
+
+ @NotNull
+ public String getPath() {
+ return myPath;
+ }
+
+ public long getPosition() {
+ return myPosition;
+ }
+
+ @NotNull
+ public String getBodyHtml() {
+ return myBodyHtml;
+ }
+
+ @NotNull
+ public GithubUser getUser() {
+ return myUser;
+ }
+
+ @NotNull
+ public Date getCreatedAt() {
+ return myCreatedAt;
+ }
+
+ @NotNull
+ public Date getUpdatedAt() {
+ return myUpdatedAt;
+ }
+}
diff --git a/plugins/github/src/org/jetbrains/plugins/github/api/GithubCommitCommentRaw.java b/plugins/github/src/org/jetbrains/plugins/github/api/GithubCommitCommentRaw.java
new file mode 100644
index 000000000000..229b31ab92eb
--- /dev/null
+++ b/plugins/github/src/org/jetbrains/plugins/github/api/GithubCommitCommentRaw.java
@@ -0,0 +1,59 @@
+/*
+ * 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 org.jetbrains.plugins.github.api;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Date;
+
+/**
+ * @author Aleksey Pivovarov
+ */
+class GithubCommitCommentRaw implements DataConstructor {
+ @Nullable public String htmlUrl;
+ @Nullable public String url;
+
+ @Nullable public Long id;
+ @Nullable public String commitId;
+ @Nullable public String path;
+ @Nullable public Long position;
+ @Nullable public Long line;
+ @Nullable public String body;
+ @Nullable public String bodyHtml;
+
+ @Nullable public GithubUserRaw user;
+
+ @Nullable public Date createdAt;
+ @Nullable public Date updatedAt;
+
+ @SuppressWarnings("ConstantConditions")
+ @NotNull
+ public GithubCommitComment createCommitComment() {
+ return new GithubCommitComment(htmlUrl, id, commitId, path, position, bodyHtml, user.createUser(), createdAt, updatedAt);
+ }
+
+ @SuppressWarnings("unchecked")
+ @NotNull
+ @Override
+ public <T> T create(@NotNull Class<T> resultClass) {
+ if (resultClass.isAssignableFrom(GithubCommitComment.class)) {
+ return (T)createCommitComment();
+ }
+
+ throw new ClassCastException(this.getClass().getName() + ": bad class type: " + resultClass.getName());
+ }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/SvnPropDetailsProvider.java b/plugins/github/src/org/jetbrains/plugins/github/exceptions/GithubRateLimitExceededException.java
index 683024679277..66272f466e69 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/SvnPropDetailsProvider.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/exceptions/GithubRateLimitExceededException.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.
@@ -13,13 +13,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.jetbrains.idea.svn.properties;
+package org.jetbrains.plugins.github.exceptions;
+
+import java.io.IOException;
/**
- * Created with IntelliJ IDEA.
- * User: Irina.Chernushina
- * Date: 2/12/12
- * Time: 8:40 PM
+ * @author Aleksey Pivovarov
*/
-public class SvnPropDetailsProvider {
+public class GithubRateLimitExceededException extends IOException {
+ public GithubRateLimitExceededException(String message) {
+ super(message);
+ }
}
diff --git a/plugins/github/src/org/jetbrains/plugins/github/tasks/GithubRepository.java b/plugins/github/src/org/jetbrains/plugins/github/tasks/GithubRepository.java
index f4e45544dd8e..b975956e3eea 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/tasks/GithubRepository.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/tasks/GithubRepository.java
@@ -20,6 +20,7 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.github.api.GithubApiUtil;
import org.jetbrains.plugins.github.exceptions.GithubAuthenticationException;
import org.jetbrains.plugins.github.exceptions.GithubJsonException;
+import org.jetbrains.plugins.github.exceptions.GithubRateLimitExceededException;
import org.jetbrains.plugins.github.exceptions.GithubStatusCodeException;
import org.jetbrains.plugins.github.util.GithubAuthData;
import org.jetbrains.plugins.github.util.GithubUtil;
@@ -85,7 +86,10 @@ public class GithubRepository extends BaseRepositoryImpl {
@Override
public Task[] getIssues(@Nullable String query, int max, long since) throws Exception {
try {
- return getIssues(query);
+ return getIssues(query, max);
+ }
+ catch (GithubRateLimitExceededException e) {
+ return new Task[0];
}
catch (GithubAuthenticationException e) {
throw new Exception(e.getMessage(), e);
@@ -99,13 +103,13 @@ public class GithubRepository extends BaseRepositoryImpl {
}
@NotNull
- private Task[] getIssues(@Nullable String query) throws Exception {
+ private Task[] getIssues(@Nullable String query, int max) throws Exception {
List<GithubIssue> issues;
if (StringUtil.isEmptyOrSpaces(query)) {
if (StringUtil.isEmptyOrSpaces(myUser)) {
myUser = GithubApiUtil.getCurrentUser(getAuthData()).getLogin();
}
- issues = GithubApiUtil.getIssuesAssigned(getAuthData(), getRepoAuthor(), getRepoName(), myUser);
+ issues = GithubApiUtil.getIssuesAssigned(getAuthData(), getRepoAuthor(), getRepoName(), myUser, max);
}
else {
issues = GithubApiUtil.getIssuesQueried(getAuthData(), getRepoAuthor(), getRepoName(), query);
@@ -266,6 +270,7 @@ public class GithubRepository extends BaseRepositoryImpl {
public void setToken(@NotNull String token) {
myToken = token;
+ setUser("");
}
@Tag("token")
diff --git a/plugins/github/src/org/jetbrains/plugins/github/tasks/GithubRepositoryEditor.java b/plugins/github/src/org/jetbrains/plugins/github/tasks/GithubRepositoryEditor.java
index 2a83c85a2d1f..c9269436b738 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/tasks/GithubRepositoryEditor.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/tasks/GithubRepositoryEditor.java
@@ -65,7 +65,6 @@ public class GithubRepositoryEditor extends BaseRepositoryEditor<GithubRepositor
myHost.getDocument().addDocumentListener(buttonUpdater);
myRepoAuthor.getDocument().addDocumentListener(buttonUpdater);
myRepoName.getDocument().addDocumentListener(buttonUpdater);
- myURLText.getDocument().addDocumentListener(buttonUpdater);
}
@Nullable
diff --git a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsPanel.form b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsPanel.form
index b540bd9c3ea5..b166fce1ef38 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsPanel.form
+++ b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsPanel.form
@@ -47,7 +47,9 @@
</component>
<component id="5a680" class="com.intellij.openapi.ui.ComboBox" binding="myAuthTypeComboBox">
<constraints>
- <grid row="0" column="3" row-span="1" col-span="2" vsize-policy="0" hsize-policy="0" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+ <grid row="0" column="3" row-span="1" col-span="2" vsize-policy="0" hsize-policy="0" anchor="0" fill="1" indent="0" use-parent-layout="false">
+ <preferred-size width="120" height="-1"/>
+ </grid>
</constraints>
<properties/>
</component>
@@ -143,7 +145,7 @@
<text value="Test"/>
</properties>
</component>
- <component id="b276a" class="com.intellij.ui.components.JBLabel">
+ <component id="b276a" class="com.intellij.ui.components.JBLabel" binding="myAuthTypeLabel">
<constraints>
<grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
diff --git a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsPanel.java b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsPanel.java
index 365fa2f36b2b..26cbbf6f539a 100644
--- a/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsPanel.java
+++ b/plugins/github/src/org/jetbrains/plugins/github/ui/GithubSettingsPanel.java
@@ -33,6 +33,7 @@ import org.jetbrains.plugins.github.util.GithubUtil;
import org.jetbrains.plugins.github.api.GithubUser;
import javax.swing.*;
+import javax.swing.border.EmptyBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.HyperlinkEvent;
@@ -64,6 +65,7 @@ public class GithubSettingsPanel {
private JTextField myHostTextField;
private ComboBox myAuthTypeComboBox;
private JPanel myCardPanel;
+ private JBLabel myAuthTypeLabel;
private boolean myCredentialsModified;
@@ -75,10 +77,10 @@ public class GithubSettingsPanel {
BrowserUtil.browse(e.getURL());
}
});
- mySignupTextField.setText(
- "<html>Do not have an account at github.com? <a href=\"https://github.com\">" + "Sign up" + "</a></html>");
+ mySignupTextField.setText("<html>Do not have an account at github.com? <a href=\"https://github.com\">" + "Sign up" + "</a></html>");
mySignupTextField.setBackground(myPane.getBackground());
mySignupTextField.setCursor(new Cursor(Cursor.HAND_CURSOR));
+ myAuthTypeLabel.setBorder(new EmptyBorder(0, 10, 0, 0));
myAuthTypeComboBox.addItem(AUTH_PASSWORD);
myAuthTypeComboBox.addItem(AUTH_TOKEN);
diff --git a/plugins/github/test/org/jetbrains/plugins/github/GithubCreateGistContentTest.java b/plugins/github/test/org/jetbrains/plugins/github/GithubCreateGistContentTest.java
index e5bc04b2f975..f5cae2a1a241 100644
--- a/plugins/github/test/org/jetbrains/plugins/github/GithubCreateGistContentTest.java
+++ b/plugins/github/test/org/jetbrains/plugins/github/GithubCreateGistContentTest.java
@@ -30,9 +30,9 @@ import static org.jetbrains.plugins.github.api.GithubGist.FileContent;
* @author Aleksey Pivovarov
*/
public class GithubCreateGistContentTest extends GithubCreateGistTestBase {
+
@Override
- public void setUp() throws Exception {
- super.setUp();
+ protected void beforeTest() throws Exception {
createProjectFiles();
}
diff --git a/plugins/github/test/org/jetbrains/plugins/github/GithubCreateGistTestBase.java b/plugins/github/test/org/jetbrains/plugins/github/GithubCreateGistTestBase.java
index b564267f91a8..150e7e89d85d 100644
--- a/plugins/github/test/org/jetbrains/plugins/github/GithubCreateGistTestBase.java
+++ b/plugins/github/test/org/jetbrains/plugins/github/GithubCreateGistTestBase.java
@@ -38,20 +38,14 @@ public abstract class GithubCreateGistTestBase extends GithubTest {
protected String GIST_DESCRIPTION;
@Override
- public void setUp() throws Exception {
- super.setUp();
+ protected void beforeTest() throws Exception {
long time = Clock.getTime();
GIST_DESCRIPTION = getTestName(false) + "_" + DateFormatUtil.formatDate(time);
}
@Override
- public void tearDown() throws Exception {
- try {
- deleteGist();
- }
- finally {
- super.tearDown();
- }
+ protected void afterTest() throws Exception {
+ deleteGist();
}
protected void deleteGist() throws IOException {
diff --git a/plugins/github/test/org/jetbrains/plugins/github/GithubCreatePullRequestTestBase.java b/plugins/github/test/org/jetbrains/plugins/github/GithubCreatePullRequestTestBase.java
index 24bb7800447c..9db5ba8a0b1d 100644
--- a/plugins/github/test/org/jetbrains/plugins/github/GithubCreatePullRequestTestBase.java
+++ b/plugins/github/test/org/jetbrains/plugins/github/GithubCreatePullRequestTestBase.java
@@ -41,9 +41,7 @@ public abstract class GithubCreatePullRequestTestBase extends GithubTest {
protected String BRANCH_NAME;
@Override
- public void setUp() throws Exception {
- super.setUp();
-
+ protected void beforeTest() throws Exception {
Random rnd = new Random();
long time = Clock.getTime();
BRANCH_NAME = "branch_" + getTestName(false) + "_" + DateFormatUtil.formatDate(time).replace('/', '-') + "_" + rnd.nextLong();
@@ -58,13 +56,8 @@ public abstract class GithubCreatePullRequestTestBase extends GithubTest {
}
@Override
- public void tearDown() throws Exception {
- try {
- deleteRemoteBranch();
- }
- finally {
- super.tearDown();
- }
+ protected void afterTest() throws Exception {
+ deleteRemoteBranch();
}
protected void deleteRemoteBranch() {
diff --git a/plugins/github/test/org/jetbrains/plugins/github/GithubIssuesTest.java b/plugins/github/test/org/jetbrains/plugins/github/GithubIssuesTest.java
new file mode 100644
index 000000000000..1b471691107d
--- /dev/null
+++ b/plugins/github/test/org/jetbrains/plugins/github/GithubIssuesTest.java
@@ -0,0 +1,103 @@
+/*
+ * 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 org.jetbrains.plugins.github;
+
+import com.intellij.openapi.util.Comparing;
+import com.intellij.util.Function;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.plugins.github.api.GithubApiUtil;
+import org.jetbrains.plugins.github.api.GithubIssue;
+import org.jetbrains.plugins.github.test.GithubTest;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * @author Aleksey Pivovarov
+ */
+public class GithubIssuesTest extends GithubTest {
+ private static final String REPO_NAME = "IssuesTest";
+
+ public void testAssigneeIssues1() throws Exception {
+ List<GithubIssue> result = GithubApiUtil.getIssuesAssigned(myAuth, myLogin2, REPO_NAME, myLogin1, 100);
+ List<Long> issues = ContainerUtil.map(result, new Function<GithubIssue, Long>() {
+ @Override
+ public Long fun(GithubIssue githubIssue) {
+ return githubIssue.getNumber();
+ }
+ });
+
+ List<Long> expected = Arrays.asList(6L, 7L, 8L);
+
+ assertTrue(Comparing.haveEqualElements(issues, expected));
+ }
+
+ public void testAssigneeIssues2() throws Exception {
+ List<GithubIssue> result = GithubApiUtil.getIssuesAssigned(myAuth, myLogin2, REPO_NAME, myLogin2, 100);
+ List<Long> issues = ContainerUtil.map(result, new Function<GithubIssue, Long>() {
+ @Override
+ public Long fun(GithubIssue githubIssue) {
+ return githubIssue.getNumber();
+ }
+ });
+
+ List<Long> expected = Arrays.asList(1L, 2L);
+
+ assertTrue(Comparing.haveEqualElements(issues, expected));
+ }
+
+ public void testAssigneeIssues3() throws Exception {
+ List<GithubIssue> result = GithubApiUtil.getIssuesAssigned(myAuth, myLogin2, REPO_NAME, "", 100);
+ List<Long> issues = ContainerUtil.map(result, new Function<GithubIssue, Long>() {
+ @Override
+ public Long fun(GithubIssue githubIssue) {
+ return githubIssue.getNumber();
+ }
+ });
+
+ List<Long> expected = Arrays.asList(1L, 2L, 5L, 6L, 7L, 8L, 9L, 10L, 11L);
+
+ assertTrue(Comparing.haveEqualElements(issues, expected));
+ }
+
+ public void testQueriedIssues1() throws Exception {
+ List<GithubIssue> result = GithubApiUtil.getIssuesQueried(myAuth, myLogin2, REPO_NAME, "abracadabra");
+ List<Long> issues = ContainerUtil.map(result, new Function<GithubIssue, Long>() {
+ @Override
+ public Long fun(GithubIssue githubIssue) {
+ return githubIssue.getNumber();
+ }
+ });
+
+ List<Long> expected = Arrays.asList(10L, 12L);
+
+ assertContainsElements(issues, expected);
+ }
+
+ public void testQueriedIssues2() throws Exception {
+ List<GithubIssue> result = GithubApiUtil.getIssuesQueried(myAuth, myLogin2, REPO_NAME, "commentary");
+ List<Long> issues = ContainerUtil.map(result, new Function<GithubIssue, Long>() {
+ @Override
+ public Long fun(GithubIssue githubIssue) {
+ return githubIssue.getNumber();
+ }
+ });
+
+ List<Long> expected = Arrays.asList(11L);
+
+ assertContainsElements(issues, expected);
+ }
+}
diff --git a/plugins/github/test/org/jetbrains/plugins/github/GithubRequestPagingTest.java b/plugins/github/test/org/jetbrains/plugins/github/GithubRequestPagingTest.java
index c72cbc3c2b4a..4fec0d1c7a5c 100644
--- a/plugins/github/test/org/jetbrains/plugins/github/GithubRequestPagingTest.java
+++ b/plugins/github/test/org/jetbrains/plugins/github/GithubRequestPagingTest.java
@@ -28,9 +28,9 @@ import static org.junit.Assume.assumeNotNull;
* @author Aleksey Pivovarov
*/
public class GithubRequestPagingTest extends GithubTest {
+
@Override
- protected void setUp() throws Exception {
- super.setUp();
+ protected void beforeTest() throws Exception {
assumeNotNull(myLogin2);
}
diff --git a/plugins/github/test/org/jetbrains/plugins/github/GithubShareProjectTestBase.java b/plugins/github/test/org/jetbrains/plugins/github/GithubShareProjectTestBase.java
index 4eee8e1439f4..5dd9b218dfed 100644
--- a/plugins/github/test/org/jetbrains/plugins/github/GithubShareProjectTestBase.java
+++ b/plugins/github/test/org/jetbrains/plugins/github/GithubShareProjectTestBase.java
@@ -35,9 +35,7 @@ public abstract class GithubShareProjectTestBase extends GithubTest {
protected String PROJECT_NAME;
@Override
- public void setUp() throws Exception {
- super.setUp();
-
+ protected void beforeTest() throws Exception {
Random rnd = new Random();
long time = Clock.getTime();
PROJECT_NAME = "new_project_from_" + getTestName(false) + "_" + DateFormatUtil.formatDate(time).replace('/', '-') + "_" + rnd.nextLong();
@@ -45,13 +43,8 @@ public abstract class GithubShareProjectTestBase extends GithubTest {
}
@Override
- public void tearDown() throws Exception {
- try {
- deleteGithubRepo();
- }
- finally {
- super.tearDown();
- }
+ protected void afterTest() throws Exception {
+ deleteGithubRepo();
}
protected void deleteGithubRepo() throws IOException {
diff --git a/plugins/github/test/org/jetbrains/plugins/github/test/GithubTest.java b/plugins/github/test/org/jetbrains/plugins/github/test/GithubTest.java
index 0f2da3848c38..2c9496e9a27e 100644
--- a/plugins/github/test/org/jetbrains/plugins/github/test/GithubTest.java
+++ b/plugins/github/test/org/jetbrains/plugins/github/test/GithubTest.java
@@ -56,9 +56,11 @@ import static org.junit.Assume.assumeNotNull;
* <li>Project base directory is the root of everything. </li>
* </ul></p>
* <p>All tests inherited from this class are required to have a login and a password to access the Github server.
- * They are set up in System properties: <br/>
- * <code>-Dtest.github.login=mylogin<br/>
- * -Dtest.github.password=mypassword</code>
+ * They are set up in Environment variables: <br/>
+ * <code>idea.test.github.host=myHost<br/>
+ * idea.test.github.login1=mylogin1<br/> // test user
+ * idea.test.github.login2=mylogin2<br/> // user with configured test repositories
+ * idea.test.github.password=mypassword</code> // password for test user
* </p>
*
* @author Kirill Likhodedov
@@ -173,7 +175,7 @@ public abstract class GithubTest extends UsefulTestCase {
}
@Override
- protected void setUp() throws Exception {
+ protected final void setUp() throws Exception {
final String host = System.getenv("idea.test.github.host");
final String login1 = System.getenv("idea.test.github.login1");
final String login2 = System.getenv("idea.test.github.login2");
@@ -186,8 +188,14 @@ public abstract class GithubTest extends UsefulTestCase {
super.setUp();
- myProjectFixture = IdeaTestFixtureFactory.getFixtureFactory().createFixtureBuilder(getTestName(true)).getFixture();
- myProjectFixture.setUp();
+ try {
+ myProjectFixture = IdeaTestFixtureFactory.getFixtureFactory().createFixtureBuilder(getTestName(true)).getFixture();
+ myProjectFixture.setUp();
+ }
+ catch (Exception e) {
+ super.tearDown();
+ throw e;
+ }
myProject = myProjectFixture.getProject();
myProjectRoot = myProject.getBaseDir();
@@ -209,17 +217,39 @@ public abstract class GithubTest extends UsefulTestCase {
myHttpAuthService = (GitHttpAuthTestService)ServiceManager.getService(GitHttpAuthService.class);
myGitRepositoryManager = GitUtil.getRepositoryManager(myProject);
+
+ try {
+ beforeTest();
+ }
+ catch (Exception e) {
+ try {
+ tearDown();
+ }
+ catch (Exception e2) {
+ e2.printStackTrace();
+ }
+ throw e;
+ }
}
@Override
- protected void tearDown() throws Exception {
- myHttpAuthService.cleanup();
- myDialogManager.cleanup();
- myNotificator.cleanup();
+ protected final void tearDown() throws Exception {
+ try {
+ afterTest();
+ }
+ finally {
+ myHttpAuthService.cleanup();
+ myDialogManager.cleanup();
+ myNotificator.cleanup();
- myProjectFixture.tearDown();
- super.tearDown();
+ myProjectFixture.tearDown();
+ super.tearDown();
+ }
}
+ protected void beforeTest() throws Exception {
+ }
+ protected void afterTest() throws Exception {
+ }
}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleProjectSettingsControl.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleProjectSettingsControl.java
index 669bc3a5317b..53675561a5bc 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleProjectSettingsControl.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/settings/GradleProjectSettingsControl.java
@@ -111,8 +111,8 @@ public class GradleProjectSettingsControl extends AbstractExternalProjectSetting
initControls();
content.add(myUseWrapperButton, ExternalSystemUiUtil.getFillLineConstraints(indentLevel));
- content.add(myUseLocalDistributionButton, ExternalSystemUiUtil.getFillLineConstraints(indentLevel));
content.add(myUseBundledDistributionButton, ExternalSystemUiUtil.getFillLineConstraints(indentLevel));
+ content.add(myUseLocalDistributionButton, ExternalSystemUiUtil.getFillLineConstraints(indentLevel));
content.add(myGradleHomeLabel, ExternalSystemUiUtil.getLabelConstraints(indentLevel));
content.add(myGradleHomePathField, ExternalSystemUiUtil.getFillLineConstraints(0));
diff --git a/plugins/groovy/jetgroovy.iml b/plugins/groovy/jetgroovy.iml
index d8531aeafeda..bd8506caffbb 100644
--- a/plugins/groovy/jetgroovy.iml
+++ b/plugins/groovy/jetgroovy.iml
@@ -34,6 +34,7 @@
<orderEntry type="module" module-name="junit" scope="TEST" />
<orderEntry type="module" module-name="java-indexing-api" />
<orderEntry type="module" module-name="groovy-jps-plugin" />
+ <orderEntry type="module" module-name="ByteCodeViewer" />
</component>
</module>
diff --git a/plugins/groovy/resources/intentionDescriptions/GrRemoveExplicitTypeDeclarationIntention/after.groovy.template b/plugins/groovy/resources/intentionDescriptions/GrRemoveExplicitTypeDeclarationIntention/after.groovy.template
new file mode 100644
index 000000000000..1862911cef6e
--- /dev/null
+++ b/plugins/groovy/resources/intentionDescriptions/GrRemoveExplicitTypeDeclarationIntention/after.groovy.template
@@ -0,0 +1 @@
+<spot>def</spot> list = ['a', 'b', 'c'] \ No newline at end of file
diff --git a/plugins/groovy/resources/intentionDescriptions/GrRemoveExplicitTypeDeclarationIntention/before.groovy.template b/plugins/groovy/resources/intentionDescriptions/GrRemoveExplicitTypeDeclarationIntention/before.groovy.template
new file mode 100644
index 000000000000..9cc469cab515
--- /dev/null
+++ b/plugins/groovy/resources/intentionDescriptions/GrRemoveExplicitTypeDeclarationIntention/before.groovy.template
@@ -0,0 +1 @@
+<spot>ArrayList<String></spot> list = ['a', 'b', 'c'] \ No newline at end of file
diff --git a/plugins/groovy/resources/intentionDescriptions/GrRemoveExplicitTypeDeclarationIntention/description.html b/plugins/groovy/resources/intentionDescriptions/GrRemoveExplicitTypeDeclarationIntention/description.html
new file mode 100644
index 000000000000..f3c976cc242d
--- /dev/null
+++ b/plugins/groovy/resources/intentionDescriptions/GrRemoveExplicitTypeDeclarationIntention/description.html
@@ -0,0 +1,5 @@
+<html>
+<body>
+This intention removes explicit type elements from variables and methods
+</body>
+</html> \ No newline at end of file
diff --git a/plugins/groovy/src/META-INF/plugin.xml b/plugins/groovy/src/META-INF/plugin.xml
index fa0fffb25f13..143c787d4c0e 100644
--- a/plugins/groovy/src/META-INF/plugin.xml
+++ b/plugins/groovy/src/META-INF/plugin.xml
@@ -26,6 +26,7 @@
<depends optional="true" config-file="intellilang-groovy-support.xml">org.intellij.intelliLang</depends>
<depends optional="true">AntSupport</depends>
<depends optional="true">cucumber</depends>
+ <depends optional="true">ByteCodeViewer</depends>
<extensionPoints>
<extensionPoint name="methodComparator" interface="org.jetbrains.plugins.groovy.lang.resolve.GrMethodComparator"/>
@@ -1391,6 +1392,11 @@
<categoryKey>intention.category.groovy/intention.category.groovy.other</categoryKey>
<className>org.jetbrains.plugins.groovy.intentions.other.GrCopyStringConcatenationContentIntention</className>
</intentionAction>
+ <intentionAction>
+ <bundleName>org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle</bundleName>
+ <categoryKey>intention.category.groovy/intention.category.groovy.declaration</categoryKey>
+ <className>org.jetbrains.plugins.groovy.intentions.declaration.GrRemoveExplicitTypeDeclarationIntention</className>
+ </intentionAction>
<projectService serviceInterface="org.jetbrains.plugins.groovy.annotator.intentions.dynamic.DynamicToolWindowWrapper"
serviceImplementation="org.jetbrains.plugins.groovy.annotator.intentions.dynamic.DynamicToolWindowWrapper"/>
@@ -1429,6 +1435,10 @@
<codeFragmentFactory implementation="org.jetbrains.plugins.groovy.debugger.GroovyCodeFragmentFactory"/>
</extensions>
+ <extensions defaultExtensionNs="ByteCodeViewer">
+ <classSearcher implementation="org.jetbrains.plugins.groovy.byteCodeViewer.GroovyScriptClassSearcher"/>
+ </extensions>
+
<actions>
<action id="Groovy.Shell.Execute" class="com.intellij.openapi.actionSystem.EmptyAction" text="Execute Groovy Code"
description="Execute Groovy code in console">
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/byteCodeViewer/GroovyScriptClassSearcher.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/byteCodeViewer/GroovyScriptClassSearcher.java
new file mode 100644
index 000000000000..3365dc54f5c5
--- /dev/null
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/byteCodeViewer/GroovyScriptClassSearcher.java
@@ -0,0 +1,50 @@
+/*
+ * 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 org.jetbrains.plugins.groovy.byteCodeViewer;
+
+import com.intellij.byteCodeViewer.ClassSearcher;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiTypeParameter;
+import com.intellij.psi.util.PsiTreeUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.plugins.groovy.GroovyFileType;
+import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
+
+/**
+ * Created by Max Medvedev on 8/23/13
+ */
+public class GroovyScriptClassSearcher implements ClassSearcher {
+ @Nullable
+ @Override
+ public PsiClass findClass(@NotNull PsiElement place) {
+ if (place.getLanguage() == GroovyFileType.GROOVY_LANGUAGE) {
+ PsiClass containingClass = PsiTreeUtil.getParentOfType(place, PsiClass.class, false);
+ while (containingClass instanceof PsiTypeParameter) {
+ containingClass = PsiTreeUtil.getParentOfType(containingClass, PsiClass.class);
+ }
+ if (containingClass != null) return containingClass;
+
+ PsiFile file = place.getContainingFile();
+ if (file instanceof GroovyFile && ((GroovyFile)file).isScript()) {
+ return ((GroovyFile)file).getScriptClass();
+ }
+ }
+ return null;
+ }
+}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/confusing/ClashingGettersInspection.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/confusing/ClashingGettersInspection.java
index 9570fb633f74..c66b9673dde8 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/confusing/ClashingGettersInspection.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/confusing/ClashingGettersInspection.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.
@@ -57,6 +57,7 @@ public class ClashingGettersInspection extends BaseInspection {
return GroovyInspectionBundle.message("getter.0.clashes.with.getter.1", args);
}
+ @NotNull
@Override
protected BaseInspectionVisitor buildVisitor() {
return new BaseInspectionVisitor() {
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/naming/GroovyAnnotationNamingConventionInspection.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/naming/GroovyAnnotationNamingConventionInspection.java
index 62b21ed08d85..dfaca8f5081c 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/naming/GroovyAnnotationNamingConventionInspection.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/naming/GroovyAnnotationNamingConventionInspection.java
@@ -20,7 +20,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.groovy.codeInspection.BaseInspectionVisitor;
import org.jetbrains.plugins.groovy.codeInspection.GroovyFix;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrAnnotationTypeDefinition;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
public class GroovyAnnotationNamingConventionInspection extends ConventionInspection {
@@ -32,7 +31,7 @@ public class GroovyAnnotationNamingConventionInspection extends ConventionInspec
return "Annotation naming convention";
}
- protected GroovyFix buildFix(PsiElement location) {
+ protected GroovyFix buildFix(@NotNull PsiElement location) {
return new RenameFix();
}
@@ -63,18 +62,15 @@ public class GroovyAnnotationNamingConventionInspection extends ConventionInspec
return DEFAULT_MAX_LENGTH;
}
+ @NotNull
public BaseInspectionVisitor buildVisitor() {
return new NamingConventionsVisitor();
}
private class NamingConventionsVisitor extends BaseInspectionVisitor {
-
- public void visitTypeDefinition(GrTypeDefinition grTypeDefinition) {
- super.visitTypeDefinition(grTypeDefinition);
- if (!(grTypeDefinition instanceof GrAnnotationTypeDefinition)) {
- return;
- }
- final GrAnnotationTypeDefinition aClass = (GrAnnotationTypeDefinition) grTypeDefinition;
+ @Override
+ public void visitAnnotationTypeDefinition(GrAnnotationTypeDefinition aClass) {
+ super.visitAnnotationTypeDefinition(aClass);
final String name = aClass.getName();
if (name == null) {
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/naming/GroovyClassNamingConventionInspection.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/naming/GroovyClassNamingConventionInspection.java
index 66937b0ed39c..cc48722ff817 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/naming/GroovyClassNamingConventionInspection.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/naming/GroovyClassNamingConventionInspection.java
@@ -20,7 +20,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.groovy.codeInspection.BaseInspectionVisitor;
import org.jetbrains.plugins.groovy.codeInspection.GroovyFix;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrClassDefinition;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
public class GroovyClassNamingConventionInspection extends ConventionInspection {
@@ -32,7 +31,7 @@ public class GroovyClassNamingConventionInspection extends ConventionInspection
return "Class naming convention";
}
- protected GroovyFix buildFix(PsiElement location) {
+ protected GroovyFix buildFix(@NotNull PsiElement location) {
return new RenameFix();
}
@@ -63,26 +62,23 @@ public class GroovyClassNamingConventionInspection extends ConventionInspection
return DEFAULT_MAX_LENGTH;
}
+ @NotNull
public BaseInspectionVisitor buildVisitor() {
return new NamingConventionsVisitor();
}
private class NamingConventionsVisitor extends BaseInspectionVisitor {
-
- public void visitTypeDefinition(GrTypeDefinition grTypeDefinition) {
- super.visitTypeDefinition(grTypeDefinition);
- if (!(grTypeDefinition instanceof GrClassDefinition)) {
- return;
- }
- GrClassDefinition aClass = (GrClassDefinition) grTypeDefinition;
- final String name = aClass.getName();
+ @Override
+ public void visitClassDefinition(GrClassDefinition classDefinition) {
+ super.visitClassDefinition(classDefinition);
+ final String name = classDefinition.getName();
if (name == null) {
return;
}
if (isValid(name)) {
return;
}
- registerClassError(aClass, name);
+ registerClassError(classDefinition, name);
}
}
} \ No newline at end of file
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/naming/GroovyEnumerationNamingConventionInspection.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/naming/GroovyEnumerationNamingConventionInspection.java
index a53d2ed40bad..15aa51b20b1c 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/naming/GroovyEnumerationNamingConventionInspection.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/naming/GroovyEnumerationNamingConventionInspection.java
@@ -20,7 +20,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.groovy.codeInspection.BaseInspectionVisitor;
import org.jetbrains.plugins.groovy.codeInspection.GroovyFix;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrEnumTypeDefinition;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
public class GroovyEnumerationNamingConventionInspection extends ConventionInspection {
@@ -32,7 +31,7 @@ public class GroovyEnumerationNamingConventionInspection extends ConventionInspe
return "Enumeration naming convention";
}
- protected GroovyFix buildFix(PsiElement location) {
+ protected GroovyFix buildFix(@NotNull PsiElement location) {
return new RenameFix();
}
@@ -63,27 +62,24 @@ public class GroovyEnumerationNamingConventionInspection extends ConventionInspe
return DEFAULT_MAX_LENGTH;
}
+ @NotNull
public BaseInspectionVisitor buildVisitor() {
return new NamingConventionsVisitor();
}
private class NamingConventionsVisitor extends BaseInspectionVisitor {
+ @Override
+ public void visitEnumDefinition(GrEnumTypeDefinition aClass) {
+ super.visitEnumDefinition(aClass);
- public void visitTypeDefinition(GrTypeDefinition grTypeDefinition) {
- super.visitTypeDefinition(grTypeDefinition);
- if (!(grTypeDefinition instanceof GrEnumTypeDefinition)) {
- return;
- }
- final GrEnumTypeDefinition aClass = (GrEnumTypeDefinition) grTypeDefinition;
-
- final String name = aClass.getName();
- if (name == null) {
- return;
- }
- if (isValid(name)) {
- return;
- }
- registerClassError(aClass, name);
+ final String name = aClass.getName();
+ if (name == null) {
+ return;
+ }
+ if (isValid(name)) {
+ return;
}
+ registerClassError(aClass, name);
+ }
}
} \ No newline at end of file
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/naming/GroovyInterfaceNamingConventionInspection.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/naming/GroovyInterfaceNamingConventionInspection.java
index 832a8882c048..188995a7b9dd 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/naming/GroovyInterfaceNamingConventionInspection.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/naming/GroovyInterfaceNamingConventionInspection.java
@@ -20,7 +20,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.groovy.codeInspection.BaseInspectionVisitor;
import org.jetbrains.plugins.groovy.codeInspection.GroovyFix;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrInterfaceDefinition;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
public class GroovyInterfaceNamingConventionInspection extends ConventionInspection {
@@ -32,7 +31,7 @@ public class GroovyInterfaceNamingConventionInspection extends ConventionInspect
return "Interface naming convention";
}
- protected GroovyFix buildFix(PsiElement location) {
+ protected GroovyFix buildFix(@NotNull PsiElement location) {
return new RenameFix();
}
@@ -63,18 +62,15 @@ public class GroovyInterfaceNamingConventionInspection extends ConventionInspect
return DEFAULT_MAX_LENGTH;
}
+ @NotNull
public BaseInspectionVisitor buildVisitor() {
return new NamingConventionsVisitor();
}
private class NamingConventionsVisitor extends BaseInspectionVisitor {
-
- public void visitTypeDefinition(GrTypeDefinition grTypeDefinition) {
- super.visitTypeDefinition(grTypeDefinition);
- if (!(grTypeDefinition instanceof GrInterfaceDefinition)) {
- return;
- }
- final GrInterfaceDefinition aClass = (GrInterfaceDefinition) grTypeDefinition;
+ @Override
+ public void visitInterfaceDefinition(GrInterfaceDefinition aClass) {
+ super.visitInterfaceDefinition(aClass);
final String name = aClass.getName();
if (name == null) {
@@ -85,5 +81,6 @@ public class GroovyInterfaceNamingConventionInspection extends ConventionInspect
}
registerClassError(aClass, name);
}
+
}
} \ No newline at end of file
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/untypedUnresolvedAccess/GrUnresolvedAccessInspection.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/untypedUnresolvedAccess/GrUnresolvedAccessInspection.java
index 985632ad27fb..3bc8412fad48 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/untypedUnresolvedAccess/GrUnresolvedAccessInspection.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/untypedUnresolvedAccess/GrUnresolvedAccessInspection.java
@@ -695,7 +695,7 @@ public class GrUnresolvedAccessInspection extends GroovySuppressableInspectionTo
@Override
public void unregister(@NotNull Condition<IntentionAction> condition) {
if (myInfo != null) {
- QuickFixAction.unregisterQuickFixAction(myInfo, condition);
+ myInfo.unregisterQuickFix(condition);
}
}
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/utils/ControlFlowUtils.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/utils/ControlFlowUtils.java
index fa4aaf30261e..f499eb12bac9 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/utils/ControlFlowUtils.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/utils/ControlFlowUtils.java
@@ -691,17 +691,15 @@ public class ControlFlowUtils {
@Nullable
public static GrControlFlowOwner findControlFlowOwner(PsiElement place) {
- if (place instanceof GrCodeBlock) {
- place = place.getContext();
- }
- while (true) {
- assert place != null;
- place = place.getContext();
- if (place == null) return null;
+ place = place.getContext();
+ while (place != null) {
if (place instanceof GrControlFlowOwner && ((GrControlFlowOwner)place).isTopControlFlowOwner()) return (GrControlFlowOwner)place;
if (place instanceof GrMethod) return ((GrMethod)place).getBlock();
if (place instanceof GrClassInitializer) return ((GrClassInitializer)place).getBlock();
+
+ place = place.getContext();
}
+ return null;
}
/**
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/extensions/GroovyMethodInfo.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/extensions/GroovyMethodInfo.java
index ae2972ea1433..3d3f6e416837 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/extensions/GroovyMethodInfo.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/extensions/GroovyMethodInfo.java
@@ -4,6 +4,7 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.psi.*;
import com.intellij.util.ArrayUtil;
import com.intellij.util.PairFunction;
+import com.intellij.util.SingletonInstancesCache;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -11,7 +12,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethod
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightMethodBuilder;
import org.jetbrains.plugins.groovy.refactoring.GroovyNamesUtil;
-import org.jetbrains.plugins.groovy.util.ClassInstanceCache;
import org.jetbrains.plugins.groovy.util.FixedValuesReferenceProvider;
import java.lang.reflect.Modifier;
@@ -253,7 +253,7 @@ public class GroovyMethodInfo {
@NotNull
public PairFunction<GrMethodCall, PsiMethod, PsiType> getReturnTypeCalculator() {
if (myReturnTypeCalculatorInstance == null) {
- myReturnTypeCalculatorInstance = ClassInstanceCache.getInstance(myReturnTypeCalculatorClassName, myClassLoader);
+ myReturnTypeCalculatorInstance = SingletonInstancesCache.getInstance(myReturnTypeCalculatorClassName, myClassLoader);
}
return myReturnTypeCalculatorInstance;
}
@@ -286,7 +286,7 @@ public class GroovyMethodInfo {
public GroovyNamedArgumentProvider getNamedArgProvider() {
if (myNamedArgProviderInstance == null) {
- myNamedArgProviderInstance = ClassInstanceCache.getInstance(myNamedArgProviderClassName, myClassLoader);
+ myNamedArgProviderInstance = SingletonInstancesCache.getInstance(myNamedArgProviderClassName, myClassLoader);
}
return myNamedArgProviderInstance;
}
@@ -328,7 +328,7 @@ public class GroovyMethodInfo {
private Object doGetProvider(ClassLoader classLoader) {
if (myProviderClassName != null) {
- return ClassInstanceCache.getInstance(myProviderClassName, classLoader);
+ return SingletonInstancesCache.getInstance(myProviderClassName, classLoader);
}
return new FixedValuesReferenceProvider(myValues);
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/GroovyIntentionsBundle.properties b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/GroovyIntentionsBundle.properties
index 49f772d85a2f..fc19f64b9c1f 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/GroovyIntentionsBundle.properties
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/GroovyIntentionsBundle.properties
@@ -202,4 +202,6 @@ flip.if.intention.family.name=Flip if statements
replace.if.with.ternary.intention.name=Replace with ?:
replace.if.with.ternary.intention.family.name=Replace if-statement with ternary operator
gr.redundant.else.intention.name=Remove redundant 'else' keyword
-gr.redundant.else.intention.family.name=Remove redundant 'else' keyword \ No newline at end of file
+gr.redundant.else.intention.family.name=Remove redundant 'else' keyword
+gr.remove.explicit.type.declaration.intention.name=Remove explicit type
+gr.remove.explicit.type.declaration.intention.family.name=Remove explicit type declaration \ No newline at end of file
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/declaration/GrRemoveExplicitTypeDeclarationIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/declaration/GrRemoveExplicitTypeDeclarationIntention.java
new file mode 100644
index 000000000000..5f53070507ea
--- /dev/null
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/declaration/GrRemoveExplicitTypeDeclarationIntention.java
@@ -0,0 +1,77 @@
+/*
+ * 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 org.jetbrains.plugins.groovy.intentions.declaration;
+
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiElement;
+import com.intellij.util.IncorrectOperationException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.plugins.groovy.intentions.base.Intention;
+import org.jetbrains.plugins.groovy.intentions.base.PsiElementPredicate;
+import org.jetbrains.plugins.groovy.lang.psi.GrNamedElement;
+import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifierList;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariableDeclaration;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
+import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement;
+
+/**
+ * Created by Max Medvedev on 8/24/13
+ */
+public class GrRemoveExplicitTypeDeclarationIntention extends Intention {
+ @Override
+ protected void processIntention(@NotNull PsiElement element, Project project, Editor editor) throws IncorrectOperationException {
+ PsiElement parent = element.getParent();
+
+ if (parent instanceof GrVariable) {
+ ((GrVariable)parent).setType(null);
+ }
+ else if (parent instanceof GrVariableDeclaration) {
+ ((GrVariableDeclaration)parent).setType(null);
+ }
+ else if (parent instanceof GrMethod) {
+ ((GrMethod)parent).setReturnType(null);
+ }
+ }
+
+ @NotNull
+ @Override
+ protected PsiElementPredicate getElementPredicate() {
+ return new PsiElementPredicate() {
+ @Override
+ public boolean satisfiedBy(PsiElement element) {
+ PsiElement parent = element.getParent();
+ if (element instanceof GrTypeElement || element instanceof GrModifierList) {
+ return parent instanceof GrVariableDeclaration && ((GrVariableDeclaration)parent).getTypeElementGroovy() != null ||
+ parent instanceof GrMethod && ((GrMethod)parent).getReturnTypeElementGroovy() != null;
+ }
+
+ if (parent instanceof GrNamedElement && ((GrNamedElement)parent).getNameIdentifierGroovy().equals(element)) {
+ if (parent instanceof GrVariable) {
+ return ((GrVariable)parent).getTypeElementGroovy() != null;
+ }
+
+ if (parent instanceof GrMethod) {
+ return ((GrMethod)parent).getReturnTypeElementGroovy() != null;
+ }
+ }
+
+ return false;
+ }
+ };
+ }
+}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/style/ReplaceAbstractClassInstanceByMapIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/style/ReplaceAbstractClassInstanceByMapIntention.java
index a145b1710246..642b64663469 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/style/ReplaceAbstractClassInstanceByMapIntention.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/style/ReplaceAbstractClassInstanceByMapIntention.java
@@ -26,6 +26,7 @@ import com.intellij.psi.infos.CandidateInfo;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.jetbrains.plugins.groovy.config.GroovyConfigUtils;
import org.jetbrains.plugins.groovy.intentions.base.Intention;
import org.jetbrains.plugins.groovy.intentions.base.PsiElementPredicate;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
@@ -81,6 +82,9 @@ public class ReplaceAbstractClassInstanceByMapIntention extends Intention {
if (methods.size() == 1) {
final Pair<PsiMethod, GrOpenBlock> pair = methods.get(0);
appendClosureTextByMethod(pair.getFirst(), buffer, pair.getSecond(), newExpr);
+ if (!GroovyConfigUtils.getInstance().isVersionAtLeast(psiElement, GroovyConfigUtils.GROOVY2_2)) {
+ buffer.append(" as ").append(iface.getQualifiedName());
+ }
}
else {
buffer.append("[");
@@ -97,8 +101,9 @@ public class ReplaceAbstractClassInstanceByMapIntention extends Intention {
buffer.append('\n');
}
buffer.append("]");
+ buffer.append(" as ").append(iface.getQualifiedName());
}
- buffer.append(" as ").append(iface.getQualifiedName());
+
createAndAdjustNewExpression(project, newExpr, buffer);
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GroovyElementVisitor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GroovyElementVisitor.java
index e362cba389ec..06b53a45d492 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GroovyElementVisitor.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GroovyElementVisitor.java
@@ -255,6 +255,26 @@ public abstract class GroovyElementVisitor {
visitElement(typeDefinition);
}
+ public void visitClassDefinition(GrClassDefinition classDefinition) {
+ visitTypeDefinition(classDefinition);
+ }
+
+ public void visitEnumDefinition(GrEnumTypeDefinition enumDefinition) {
+ visitTypeDefinition(enumDefinition);
+ }
+
+ public void visitInterfaceDefinition(GrInterfaceDefinition interfaceDefinition) {
+ visitTypeDefinition(interfaceDefinition);
+ }
+
+ public void visitAnonymousClassDefinition(GrAnonymousClassDefinition anonymousClassDefinition) {
+ visitTypeDefinition(anonymousClassDefinition);
+ }
+
+ public void visitAnnotationTypeDefinition(GrAnnotationTypeDefinition annotationTypeDefinition) {
+ visitTypeDefinition(annotationTypeDefinition);
+ }
+
public void visitExtendsClause(GrExtendsClause extendsClause) {
visitElement(extendsClause);
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/GrVariableDeclarationImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/GrVariableDeclarationImpl.java
index 28dfd6da4506..b9a3a272d9cd 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/GrVariableDeclarationImpl.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/GrVariableDeclarationImpl.java
@@ -96,7 +96,9 @@ public class GrVariableDeclarationImpl extends GrStubElementBase<EmptyStub> impl
final GrTypeElement typeElement = getTypeElementGroovy();
if (type == null) {
if (typeElement == null) return;
- getModifierList().setModifierProperty(GrModifier.DEF, true);
+ if (getModifierList().getModifiers().length == 0) {
+ getModifierList().setModifierProperty(GrModifier.DEF, true);
+ }
typeElement.delete();
return;
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/blocks/GrBlockImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/blocks/GrBlockImpl.java
index 74df20613b99..4331046b3ae2 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/blocks/GrBlockImpl.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/blocks/GrBlockImpl.java
@@ -16,10 +16,12 @@
package org.jetbrains.plugins.groovy.lang.psi.impl.statements.blocks;
+import com.intellij.extapi.psi.ASTDelegatePsiElement;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.util.Key;
import com.intellij.psi.PsiElement;
import com.intellij.psi.ResolveState;
+import com.intellij.psi.impl.CheckUtil;
import com.intellij.psi.impl.source.tree.Factory;
import com.intellij.psi.impl.source.tree.LazyParseablePsiElement;
import com.intellij.psi.impl.source.tree.LeafElement;
@@ -60,6 +62,17 @@ public abstract class GrBlockImpl extends LazyParseablePsiElement implements GrC
}
@Override
+ public void delete() throws IncorrectOperationException {
+ if (getParent() instanceof ASTDelegatePsiElement) {
+ CheckUtil.checkWritable(this);
+ ((ASTDelegatePsiElement)getParent()).deleteChildInternal(getNode());
+ }
+ else {
+ getParent().deleteChildRange(this, this);
+ }
+ }
+
+ @Override
public void removeElements(PsiElement[] elements) throws IncorrectOperationException {
GroovyPsiElementImpl.removeElements(this, elements);
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrAnnotationTypeDefinitionImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrAnnotationTypeDefinitionImpl.java
index 47d849fb9cf0..16d52d00b414 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrAnnotationTypeDefinitionImpl.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrAnnotationTypeDefinitionImpl.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.
@@ -19,10 +19,11 @@ package org.jetbrains.plugins.groovy.lang.psi.impl.statements.typedef;
import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiClassType;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes;
+import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrAnnotationTypeDefinition;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
import org.jetbrains.plugins.groovy.lang.psi.stubs.GrTypeDefinitionStub;
-import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes;
/**
* @author Dmitry.Krasilschikov
@@ -61,4 +62,9 @@ public class GrAnnotationTypeDefinitionImpl extends GrTypeDefinitionImpl impleme
private PsiClassType createAnnotationType() {
return TypesUtil.createTypeByFQClassName("java.lang.annotation.Annotation", this);
}
+
+ @Override
+ public void accept(GroovyElementVisitor visitor) {
+ visitor.visitAnnotationTypeDefinition(this);
+ }
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrAnonymousClassDefinitionImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrAnonymousClassDefinitionImpl.java
index 495603bccbb3..aa7876a19db6 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrAnonymousClassDefinitionImpl.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrAnonymousClassDefinitionImpl.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.
@@ -26,6 +26,7 @@ import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes;
+import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrNewExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrAnonymousClassDefinition;
@@ -250,4 +251,10 @@ public class GrAnonymousClassDefinitionImpl extends GrTypeDefinitionImpl impleme
public PsiIdentifier getNameIdentifier() {
return null;
}
+
+ @Override
+ public void accept(GroovyElementVisitor visitor) {
+ visitor.visitAnonymousClassDefinition(this);
+ }
+
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrClassDefinitionImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrClassDefinitionImpl.java
index cafc77953e33..2e0b3d969606 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrClassDefinitionImpl.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrClassDefinitionImpl.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.
@@ -19,6 +19,7 @@ package org.jetbrains.plugins.groovy.lang.psi.impl.statements.typedef;
import com.intellij.lang.ASTNode;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes;
+import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrClassDefinition;
import org.jetbrains.plugins.groovy.lang.psi.stubs.GrTypeDefinitionStub;
@@ -39,4 +40,9 @@ public class GrClassDefinitionImpl extends GrTypeDefinitionImpl implements GrCla
public String toString() {
return "Class definition";
}
+
+ @Override
+ public void accept(GroovyElementVisitor visitor) {
+ visitor.visitClassDefinition(this);
+ }
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrEnumTypeDefinitionImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrEnumTypeDefinitionImpl.java
index 42308ec1959b..56f4ffdedb38 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrEnumTypeDefinitionImpl.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrEnumTypeDefinitionImpl.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 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.
@@ -31,6 +31,7 @@ import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes;
+import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrEnumDefinitionBody;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrEnumTypeDefinition;
@@ -175,4 +176,9 @@ public class GrEnumTypeDefinitionImpl extends GrTypeDefinitionImpl implements Gr
if (enumDefinitionBody != null) return enumDefinitionBody.getEnumConstantList();
return null;
}
+
+ @Override
+ public void accept(GroovyElementVisitor visitor) {
+ visitor.visitEnumDefinition(this);
+ }
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrInterfaceDefinitionImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrInterfaceDefinitionImpl.java
index d4fa5a864f22..d093babb670b 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrInterfaceDefinitionImpl.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/typedef/GrInterfaceDefinitionImpl.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.
@@ -17,11 +17,11 @@
package org.jetbrains.plugins.groovy.lang.psi.impl.statements.typedef;
import com.intellij.lang.ASTNode;
-import com.intellij.psi.stubs.IStubElementType;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes;
+import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrInterfaceDefinition;
import org.jetbrains.plugins.groovy.lang.psi.stubs.GrTypeDefinitionStub;
-import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes;
/**
* @author Dmitry.Krasilschikov
@@ -44,4 +44,9 @@ public class GrInterfaceDefinitionImpl extends GrTypeDefinitionImpl implements G
public boolean isInterface() {
return true;
}
+
+ @Override
+ public void accept(GroovyElementVisitor visitor) {
+ visitor.visitInterfaceDefinition(this);
+ }
} \ No newline at end of file
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GdkMethodUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GdkMethodUtil.java
index 74443e44012d..2f757a89ebf4 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GdkMethodUtil.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/GdkMethodUtil.java
@@ -55,6 +55,7 @@ import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.GrRefer
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrGdkMethodImpl;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightMethodBuilder;
+import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
import org.jetbrains.plugins.groovy.lang.resolve.noncode.MixinMemberContributor;
import org.jetbrains.plugins.groovy.lang.resolve.processors.ClassHint;
import org.jetbrains.plugins.groovy.lang.resolve.processors.ResolverProcessor;
@@ -226,7 +227,7 @@ public class GdkMethodUtil {
final DelegatingScopeProcessor delegate = new MixinMemberContributor.MixinProcessor(processor, subjectType, qualifier);
for (GrMethod method : methods) {
- delegate.execute(method, ResolveState.initial());
+ ResolveUtil.processElement(delegate, method, state);
}
}
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/LocalVarAnalyzer.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/LocalVarAnalyzer.java
index c130ec26f8fd..edb9c901c095 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/LocalVarAnalyzer.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/LocalVarAnalyzer.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2011 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.
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/GrIntroduceHandlerBase.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/GrIntroduceHandlerBase.java
index bed860551f03..83713e9ddb0c 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/GrIntroduceHandlerBase.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/GrIntroduceHandlerBase.java
@@ -77,7 +77,7 @@ import static org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil.skipParentheses
/**
* @author Maxim.Medvedev
*/
-public abstract class GrIntroduceHandlerBase<Settings extends GrIntroduceSettings> implements RefactoringActionHandler {
+public abstract class GrIntroduceHandlerBase<Settings extends GrIntroduceSettings, Scope extends PsiElement> implements RefactoringActionHandler {
public static final Function<GrExpression, String> GR_EXPRESSION_RENDERER = new Function<GrExpression, String>() {
@Override
public String fun(@NotNull GrExpression expr) {
@@ -124,7 +124,7 @@ public abstract class GrIntroduceHandlerBase<Settings extends GrIntroduceSetting
protected abstract String getHelpID();
@NotNull
- protected abstract PsiElement findScope(GrExpression expression, GrVariable variable, StringPartInfo stringPart);
+ protected abstract Scope[] findPossibleScopes(GrExpression expression, GrVariable variable, StringPartInfo stringPart, Editor editor);
protected abstract void checkExpression(@NotNull GrExpression selectedExpr) throws GrRefactoringError;
@@ -276,14 +276,41 @@ public abstract class GrIntroduceHandlerBase<Settings extends GrIntroduceSetting
// Does nothing
}
- @NotNull
- public GrIntroduceContext getContext(@NotNull Project project,
- @NotNull Editor editor,
- @Nullable GrExpression expression,
- @Nullable GrVariable variable,
- @Nullable StringPartInfo stringPart) {
- final PsiElement scope = findScope(expression, variable, stringPart);
+ public void getContextAndInvoke(@NotNull final Project project,
+ @NotNull final Editor editor,
+ @Nullable final GrExpression expression,
+ @Nullable final GrVariable variable,
+ @Nullable final StringPartInfo stringPart) {
+ final Scope[] scopes = findPossibleScopes(expression, variable, stringPart, editor);
+
+ Pass<Scope> callback = new Pass<Scope>() {
+ @Override
+ public void pass(Scope scope) {
+ GrIntroduceContext context = getContext(project, editor, expression, variable, stringPart, scope);
+ invokeImpl(project, context, editor);
+ }
+ };
+
+ if (scopes.length == 0) {
+ CommonRefactoringUtil.showErrorHint(project, editor, RefactoringBundle.getCannotRefactorMessage( getRefactoringName() + "is not available in current scope"),
+ getRefactoringName(), getHelpID());
+ }
+ else if (scopes.length == 1) {
+ callback.pass(scopes[0]);
+ }
+ else {
+ showScopeChooser(scopes, callback, editor);
+ }
+ }
+ protected abstract void showScopeChooser(Scope[] scopes, Pass<Scope> callback, Editor editor);
+
+ public GrIntroduceContext getContext(@NotNull Project project,
+ @NotNull Editor editor,
+ @Nullable GrExpression expression,
+ @Nullable GrVariable variable,
+ @Nullable StringPartInfo stringPart,
+ @NotNull PsiElement scope) {
if (variable != null) {
final List<PsiElement> list = Collections.synchronizedList(new ArrayList<PsiElement>());
ReferencesSearch.search(variable, new LocalSearchScope(scope)).forEach(new Processor<PsiReference>() {
@@ -309,42 +336,8 @@ public abstract class GrIntroduceHandlerBase<Settings extends GrIntroduceSetting
}
}
- @NotNull
- protected PsiElement[] findOccurrences(@NotNull GrExpression expression, @NotNull PsiElement scope) {
- final PsiElement[] occurrences = GroovyRefactoringUtil.getExpressionOccurrences(PsiUtil.skipParentheses(expression, false), scope);
- if (occurrences == null || occurrences.length == 0) {
- throw new GrRefactoringError(GroovyRefactoringBundle.message("no.occurrences.found"));
- }
- return occurrences;
- }
-
- private boolean invoke(@NotNull final Project project, @NotNull final Editor editor, @NotNull PsiFile file, int startOffset, int endOffset) {
+ private boolean invokeImpl(final Project project, final GrIntroduceContext context, final Editor editor) {
try {
- PsiDocumentManager.getInstance(project).commitAllDocuments();
- if (!(file instanceof GroovyFileBase)) {
- throw new GrRefactoringError(GroovyRefactoringBundle.message("only.in.groovy.files"));
- }
- if (!CommonRefactoringUtil.checkReadOnlyStatus(project, file)) {
- throw new GrRefactoringError(RefactoringBundle.message("readonly.occurences.found"));
- }
-
- GrExpression selectedExpr = findExpression(file, startOffset, endOffset);
- final GrVariable variable = findVariable(file, startOffset, endOffset);
- final StringPartInfo stringPart = StringPartInfo.findStringPart(file, startOffset, endOffset);
- if (variable != null) {
- checkVariable(variable);
- }
- else if (selectedExpr != null) {
- checkExpression(selectedExpr);
- }
- else if (stringPart != null) {
- checkStringLiteral(stringPart);
- }
- else {
- throw new GrRefactoringError(null);
- }
-
- final GrIntroduceContext context = getContext(project, editor, selectedExpr, variable, stringPart);
if (!CommonRefactoringUtil.checkReadOnlyStatus(project, context.getOccurrences())) {
return false;
}
@@ -370,15 +363,21 @@ public abstract class GrIntroduceHandlerBase<Settings extends GrIntroduceSetting
RangeMarker stringPartRangeMarker = createRange(document, context.getStringPart());
RangeMarker varRangeMarker = createRange(document, context.getVar());
- GrVariable var = ApplicationManager.getApplication().runWriteAction(new Computable<GrVariable>() {
- @Override
- public GrVariable compute() {
- return runRefactoring(context, settings);
- }
- });
+ SmartPsiElementPointer<GrVariable> pointer =
+ ApplicationManager.getApplication().runWriteAction(new Computable<SmartPsiElementPointer<GrVariable>>() {
+ @Override
+ public SmartPsiElementPointer<GrVariable> compute() {
+ GrVariable var = runRefactoring(context, settings);
+ return var != null
+ ? SmartPointerManager.getInstance(context.getProject()).createSmartPsiElementPointer(var)
+ : null;
+ }
+ });
+ GrVariable var = pointer != null ? pointer.getElement() : null;
if (isInplace && var != null) {
- GrInplaceIntroducer introducer = getIntroducer(var, context, settings, occurrences, varRangeMarker, expressionRangeMarker, stringPartRangeMarker);
+ GrInplaceIntroducer introducer =
+ getIntroducer(var, context, settings, occurrences, varRangeMarker, expressionRangeMarker, stringPartRangeMarker);
PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(editor.getDocument());
introducer.performInplaceRefactoring(introducer.suggestNames(context));
}
@@ -411,11 +410,53 @@ public abstract class GrIntroduceHandlerBase<Settings extends GrIntroduceSetting
return true;
}
catch (GrRefactoringError e) {
- CommonRefactoringUtil.showErrorHint(project, editor, RefactoringBundle.getCannotRefactorMessage(e.getMessage()), getRefactoringName(), getHelpID());
+ CommonRefactoringUtil
+ .showErrorHint(project, editor, RefactoringBundle.getCannotRefactorMessage(e.getMessage()), getRefactoringName(), getHelpID());
return false;
}
}
+ @NotNull
+ protected PsiElement[] findOccurrences(@NotNull GrExpression expression, @NotNull PsiElement scope) {
+ final PsiElement[] occurrences = GroovyRefactoringUtil.getExpressionOccurrences(skipParentheses(expression, false), scope);
+ if (occurrences == null || occurrences.length == 0) {
+ throw new GrRefactoringError(GroovyRefactoringBundle.message("no.occurrences.found"));
+ }
+ return occurrences;
+ }
+
+ private void invoke(@NotNull final Project project,
+ @NotNull final Editor editor,
+ @NotNull PsiFile file,
+ int startOffset,
+ int endOffset) {
+ PsiDocumentManager.getInstance(project).commitAllDocuments();
+ if (!(file instanceof GroovyFileBase)) {
+ throw new GrRefactoringError(GroovyRefactoringBundle.message("only.in.groovy.files"));
+ }
+ if (!CommonRefactoringUtil.checkReadOnlyStatus(project, file)) {
+ throw new GrRefactoringError(RefactoringBundle.message("readonly.occurences.found"));
+ }
+
+ GrExpression selectedExpr = findExpression(file, startOffset, endOffset);
+ final GrVariable variable = findVariable(file, startOffset, endOffset);
+ final StringPartInfo stringPart = StringPartInfo.findStringPart(file, startOffset, endOffset);
+ if (variable != null) {
+ checkVariable(variable);
+ }
+ else if (selectedExpr != null) {
+ checkExpression(selectedExpr);
+ }
+ else if (stringPart != null) {
+ checkStringLiteral(stringPart);
+ }
+ else {
+ throw new GrRefactoringError(null);
+ }
+
+ getContextAndInvoke(project, editor, selectedExpr, variable, stringPart);
+ }
+
private static RangeMarker createRange(Document document, StringPartInfo part) {
if (part == null) {
return null;
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/constant/GrIntroduceConstantHandler.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/constant/GrIntroduceConstantHandler.java
index 357fa871c063..05bd5566edb9 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/constant/GrIntroduceConstantHandler.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/constant/GrIntroduceConstantHandler.java
@@ -15,7 +15,9 @@
*/
package org.jetbrains.plugins.groovy.refactoring.introduce.constant;
+import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.RangeMarker;
+import com.intellij.openapi.util.Pass;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.refactoring.HelpID;
@@ -41,7 +43,7 @@ import java.util.Map;
/**
* @author Maxim.Medvedev
*/
-public class GrIntroduceConstantHandler extends GrIntroduceHandlerBase<GrIntroduceConstantSettings> {
+public class GrIntroduceConstantHandler extends GrIntroduceHandlerBase<GrIntroduceConstantSettings, PsiElement> {
public static final String REFACTORING_NAME = "Introduce Constant";
@NotNull
@@ -58,9 +60,9 @@ public class GrIntroduceConstantHandler extends GrIntroduceHandlerBase<GrIntrodu
@NotNull
@Override
- protected PsiElement findScope(GrExpression expression, GrVariable variable, StringPartInfo stringPart) {
+ public PsiElement[] findPossibleScopes(GrExpression expression, GrVariable variable, StringPartInfo stringPart, Editor editor) {
final PsiElement place = getCurrentPlace(expression, variable, stringPart);
- return place.getContainingFile();
+ return new PsiFile[]{place.getContainingFile()};
}
@Override
@@ -135,6 +137,11 @@ public class GrIntroduceConstantHandler extends GrIntroduceHandlerBase<GrIntrodu
}
@Override
+ protected void showScopeChooser(PsiElement[] scopes, Pass<PsiElement> callback, Editor editor) {
+ //todo do nothing right now
+ }
+
+ @Override
protected boolean isInplace(GrIntroduceContext context) {
return false;
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/field/GrInplaceIntroduceFieldPanel.form b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/field/GrInplaceIntroduceFieldPanel.form
index 3ad6c01fffa4..96f32e533680 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/field/GrInplaceIntroduceFieldPanel.form
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/field/GrInplaceIntroduceFieldPanel.form
@@ -21,6 +21,7 @@
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
+ <labelFor value="58f26"/>
<text value="&amp;Initialize in:"/>
</properties>
</component>
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/field/GrIntroduceFieldHandler.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/field/GrIntroduceFieldHandler.java
index 1081b611b717..27878e97cecf 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/field/GrIntroduceFieldHandler.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/field/GrIntroduceFieldHandler.java
@@ -16,17 +16,21 @@
package org.jetbrains.plugins.groovy.refactoring.introduce.field;
import com.intellij.codeInsight.TestFrameworks;
+import com.intellij.codeInsight.navigation.NavigationUtil;
+import com.intellij.ide.util.PsiClassListCellRenderer;
import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.RangeMarker;
+import com.intellij.openapi.util.Pass;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiModifier;
import com.intellij.psi.PsiType;
+import com.intellij.psi.search.PsiElementProcessor;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.refactoring.HelpID;
import com.intellij.refactoring.introduce.inplace.OccurrencesChooser;
import com.intellij.refactoring.introduceField.IntroduceFieldHandler;
-import com.intellij.util.ObjectUtils;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -51,7 +55,7 @@ import java.util.List;
/**
* @author Maxim.Medvedev
*/
-public class GrIntroduceFieldHandler extends GrIntroduceHandlerBase<GrIntroduceFieldSettings> {
+public class GrIntroduceFieldHandler extends GrIntroduceHandlerBase<GrIntroduceFieldSettings, PsiClass> {
@NotNull
@Override
@@ -67,9 +71,23 @@ public class GrIntroduceFieldHandler extends GrIntroduceHandlerBase<GrIntroduceF
@NotNull
@Override
- protected PsiClass findScope(GrExpression expression, GrVariable variable, StringPartInfo partInfo) {
+ protected PsiClass[] findPossibleScopes(GrExpression expression,
+ GrVariable variable,
+ StringPartInfo partInfo,
+ Editor editor) {
PsiElement place = getCurrentPlace(expression, variable, partInfo);
- return ObjectUtils.assertNotNull(PsiUtil.getContextClass(place));
+ PsiClass aClass = PsiUtil.getContextClass(place);
+ if (aClass instanceof GroovyScriptClass) {
+ return new PsiClass[]{aClass};
+ }
+ else {
+ List<PsiClass> result = ContainerUtil.newArrayList(aClass);
+ while (aClass != null) {
+ aClass = PsiTreeUtil.getParentOfType(aClass, PsiClass.class);
+ ContainerUtil.addIfNotNull(result, aClass);
+ }
+ return result.toArray(new PsiClass[result.size()]);
+ }
}
@Override
@@ -233,6 +251,19 @@ public class GrIntroduceFieldHandler extends GrIntroduceHandlerBase<GrIntroduceF
};
}
+ @Override
+ protected void showScopeChooser(PsiClass[] scopes, final Pass<PsiClass> callback, Editor editor) {
+ PsiElementProcessor<PsiClass> processor = new PsiElementProcessor<PsiClass>() {
+ @Override
+ public boolean execute(@NotNull PsiClass element) {
+ callback.pass(element);
+ return false;
+ }
+ };
+
+ NavigationUtil.getPsiElementPopup(scopes, new PsiClassListCellRenderer(), "Choose class to introduce field", processor).showInBestPositionFor(editor);
+ }
+
@NotNull
@Override
protected PsiElement[] findOccurrences(@NotNull GrExpression expression, @NotNull PsiElement scope) {
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/variable/GrIntroduceLocalVariableProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/variable/GrIntroduceLocalVariableProcessor.java
index ff941bec3e06..3e3f6888d339 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/variable/GrIntroduceLocalVariableProcessor.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/variable/GrIntroduceLocalVariableProcessor.java
@@ -75,11 +75,12 @@ public class GrIntroduceLocalVariableProcessor {
int expressionIndex = ArrayUtilRt.find(myOccurrences, myExpression);
final PsiElement[] replaced = processOccurrences();
- GrStatement anchor = getAnchor(replaced);
+ PsiElement replacedExpression = replaced[expressionIndex];
+ GrStatement anchor = getAnchor(replaced, replacedExpression);
RefactoringUtil.highlightAllOccurrences(myContext.getProject(), replaced, myContext.getEditor());
- return insertVariableDefinition(declaration, anchor, replaced[expressionIndex]);
+ return insertVariableDefinition(declaration, anchor, replacedExpression);
}
private void refreshPositionMarker(PsiElement e) {
@@ -206,8 +207,8 @@ public class GrIntroduceLocalVariableProcessor {
}
@NotNull
- private GrStatement getAnchor(PsiElement[] replaced) {
- PsiElement anchor = GrIntroduceHandlerBase.findAnchor(replaced, myContext.getScope());
+ private GrStatement getAnchor(PsiElement[] replaced, PsiElement replacedExpression) {
+ PsiElement anchor = GrIntroduceHandlerBase.findAnchor(replaced, GroovyRefactoringUtil.getEnclosingContainer(replacedExpression));
if (!(anchor instanceof GrStatement)) {
StringBuilder error = new StringBuilder("scope:");
error.append(myContext.getScope());
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/variable/GrIntroduceVariableHandler.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/variable/GrIntroduceVariableHandler.java
index 5ce7a0985305..c27df0697130 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/variable/GrIntroduceVariableHandler.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/variable/GrIntroduceVariableHandler.java
@@ -16,7 +16,9 @@
package org.jetbrains.plugins.groovy.refactoring.introduce.variable;
+import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.RangeMarker;
+import com.intellij.openapi.util.Pass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiModifier;
import com.intellij.psi.PsiType;
@@ -25,8 +27,9 @@ import com.intellij.refactoring.introduce.inplace.OccurrencesChooser;
import com.intellij.refactoring.util.CanonicalTypes;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.jetbrains.plugins.groovy.codeInspection.utils.ControlFlowUtils;
+import org.jetbrains.plugins.groovy.lang.psi.GrControlFlowOwner;
import org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase;
-import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
@@ -46,19 +49,20 @@ import java.util.List;
/**
* @author ilyas
*/
-public class GrIntroduceVariableHandler extends GrIntroduceHandlerBase<GroovyIntroduceVariableSettings> {
+public class GrIntroduceVariableHandler extends GrIntroduceHandlerBase<GroovyIntroduceVariableSettings, GrControlFlowOwner> {
public static final String DUMMY_NAME = "________________xxx_________________";
protected static final String REFACTORING_NAME = GroovyRefactoringBundle.message("introduce.variable.title");
private RangeMarker myPosition = null;
@NotNull
@Override
- protected PsiElement findScope(GrExpression selectedExpr, GrVariable variable, StringPartInfo stringPartInfo) {
+ protected GrControlFlowOwner[] findPossibleScopes(GrExpression selectedExpr,
+ GrVariable variable,
+ StringPartInfo stringPartInfo,
+ Editor editor) {
// Get container element
- final PsiElement scope = stringPartInfo != null
- ? GroovyRefactoringUtil.getEnclosingContainer(stringPartInfo.getLiteral())
- : GroovyRefactoringUtil.getEnclosingContainer(selectedExpr);
- if (scope == null || !(scope instanceof GroovyPsiElement)) {
+ final GrControlFlowOwner scope = ControlFlowUtils.findControlFlowOwner(stringPartInfo != null ? stringPartInfo.getLiteral() : selectedExpr);
+ if (scope == null) {
throw new GrRefactoringError(
GroovyRefactoringBundle.message("refactoring.is.not.supported.in.the.current.context", REFACTORING_NAME));
}
@@ -66,7 +70,7 @@ public class GrIntroduceVariableHandler extends GrIntroduceHandlerBase<GroovyInt
throw new GrRefactoringError(
GroovyRefactoringBundle.message("refactoring.is.not.supported.in.the.current.context", REFACTORING_NAME));
}
- return scope;
+ return new GrControlFlowOwner[]{scope};
}
protected void checkExpression(@NotNull GrExpression selectedExpr) {
@@ -187,6 +191,11 @@ public class GrIntroduceVariableHandler extends GrIntroduceHandlerBase<GroovyInt
};
}
+ @Override
+ protected void showScopeChooser(GrControlFlowOwner[] scopes, Pass<GrControlFlowOwner> callback, Editor editor) {
+ //todo do nothing right now
+ }
+
@NotNull
private static GrVariableDeclaration generateDeclaration(@NotNull GrIntroduceContext context,
@NotNull GroovyIntroduceVariableSettings settings) {
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/testIntegration/GroovyTestFramework.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/testIntegration/GroovyTestFramework.java
index 3cdabe38a8e0..acac929bf281 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/testIntegration/GroovyTestFramework.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/testIntegration/GroovyTestFramework.java
@@ -51,12 +51,14 @@ public class GroovyTestFramework extends JavaTestFramework {
@Override
protected boolean isTestClass(PsiClass clazz, boolean canBePotential) {
return clazz.getLanguage() == GroovyFileType.GROOVY_LANGUAGE &&
- JUnitUtil.isTestClass(clazz) &&
+ //JUnitUtil.isTestClass(clazz) &&
InheritanceUtil.isInheritor(clazz, GroovyCommonClassNames.GROOVY_UTIL_TEST_CASE);
}
@Override
protected PsiMethod findSetUpMethod(@NotNull PsiClass clazz) {
+ if (!isTestClass(clazz, false)) return null;
+
for (PsiMethod method : clazz.getMethods()) {
if (method.getName().equals("setUp")) return method;
}
@@ -65,6 +67,8 @@ public class GroovyTestFramework extends JavaTestFramework {
@Override
protected PsiMethod findTearDownMethod(@NotNull PsiClass clazz) {
+ if (!isTestClass(clazz, false)) return null;
+
for (PsiMethod method : clazz.getMethods()) {
if (method.getName().equals("tearDown")) return method;
}
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/util/ClassInstanceCache.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/util/ClassInstanceCache.java
deleted file mode 100644
index 7a9f0554e661..000000000000
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/util/ClassInstanceCache.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package org.jetbrains.plugins.groovy.util;
-
-import com.intellij.util.containers.ConcurrentHashMap;
-import org.jetbrains.annotations.NotNull;
-
-/**
- * @author Sergey Evdokimov
- */
-public class ClassInstanceCache {
-
- private static final ConcurrentHashMap<String, Object> CACHE = new ConcurrentHashMap<String, Object>();
-
- private ClassInstanceCache() {
- }
-
- @SuppressWarnings("unchecked")
- public static <T> T getInstance(@NotNull String className, ClassLoader classLoader) {
- Object res = CACHE.get(className);
- if (res == null) {
- try {
- res = classLoader.loadClass(className).newInstance();
- }
- catch (Exception e) {
- throw new RuntimeException(e);
- }
-
- Object oldValue = CACHE.putIfAbsent(className, res);
- if (oldValue != null) {
- res = oldValue;
- }
- }
-
- return (T)res;
- }
-}
diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyUnwrapTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyUnwrapTest.groovy
index 867c34341749..a69992207dc9 100644
--- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyUnwrapTest.groovy
+++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyUnwrapTest.groovy
@@ -1,3 +1,18 @@
+/*
+ * 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 org.jetbrains.plugins.groovy.lang
import com.intellij.codeInsight.unwrap.UnwrapHandler
@@ -51,13 +66,11 @@ for(int i = 0; i < 10; i++) {
}
public void testBraces() throws Exception {
- assertUnwrapped("""
+ assertUnwrapped("""\
<caret>{
def x = 1
}
-""", """
-def x = 1
-""");
+""", "def x = 1");
}
public void testUnwrapParameterUnderArgumentList() throws Exception {
diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/GroovyResolveTestCase.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/GroovyResolveTestCase.groovy
index 6407c317daae..c481df10fa97 100644
--- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/GroovyResolveTestCase.groovy
+++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/GroovyResolveTestCase.groovy
@@ -95,7 +95,7 @@ public abstract class GroovyResolveTestCase extends LightGroovyTestCase {
final ref = configureByText(text)
assertNotNull(ref)
final resolved = ref.resolve()
- assertInstanceOf(resolved, type)
+ if (type != null) assertInstanceOf(resolved, type)
return resolved
}
diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolveMethodTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolveMethodTest.groovy
index 8dc669709410..f6ee5f0a471d 100644
--- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolveMethodTest.groovy
+++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/ResolveMethodTest.groovy
@@ -1431,6 +1431,30 @@ class _a {
''', PsiMethod)
}
+ void testRuntimeMixin22() {
+ assertNull resolveByText('''\
+class ReentrantLock {}
+
+ReentrantLock.metaClass.withLock = { nestedCode -> }
+
+new ReentrantLock().withLock {
+ fo<caret>o(3)
+}
+''')
+ }
+
+ void testRuntimeMixin23() {
+ assertNotNull resolveByText('''\
+class ReentrantLock {}
+
+ReentrantLock.metaClass.withLock = { nestedCode -> }
+
+new ReentrantLock().withLock {
+ withL<caret>ock(2)
+}
+''')
+ }
+
void testRunnableVsCallable() {
final PsiMethod method = resolveByText('''\
import java.util.concurrent.Callable
diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/IntroduceConstantTest.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/IntroduceConstantTest.java
index f51e02a507bd..77bc4a185ac8 100644
--- a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/IntroduceConstantTest.java
+++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/IntroduceConstantTest.java
@@ -18,6 +18,7 @@ package org.jetbrains.plugins.groovy.refactoring;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Editor;
import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiModifier;
import com.intellij.psi.PsiType;
import com.intellij.psi.impl.source.PostprocessReformattingAspect;
@@ -86,7 +87,8 @@ public class IntroduceConstantTest extends LightCodeInsightFixtureTestCase {
final GrExpression expression = findExpression();
final GrVariable variable = findVariable();
final StringPartInfo stringPart = findStringPart();
- final GrIntroduceContext context = handler.getContext(getProject(), editor, expression, variable, stringPart);
+ PsiElement[] scopes = handler.findPossibleScopes(expression, variable, stringPart, editor);
+ final GrIntroduceContext context = handler.getContext(getProject(), editor, expression, variable, stringPart, scopes[0]);
PsiClass targetClass;
if (targetClassName == null) {
diff --git a/plugins/groovy/testdata/groovy/refactoring/introduceVariable/f2.test b/plugins/groovy/testdata/groovy/refactoring/introduceVariable/f2.test
index 7e89dbf873c8..f1a15b464d1e 100644
--- a/plugins/groovy/testdata/groovy/refactoring/introduceVariable/f2.test
+++ b/plugins/groovy/testdata/groovy/refactoring/introduceVariable/f2.test
@@ -4,5 +4,5 @@ for (i in 1..<all>boo<end>){
-----
def preved = boo
for (i in 1..preved<caret>){
- def foo = boo
+ def foo = preved
} \ No newline at end of file
diff --git a/plugins/groovy/testdata/groovy/refactoring/introduceVariable/loop7.test b/plugins/groovy/testdata/groovy/refactoring/introduceVariable/loop7.test
index ca3771e36a0c..e8869c67abf5 100644
--- a/plugins/groovy/testdata/groovy/refactoring/introduceVariable/loop7.test
+++ b/plugins/groovy/testdata/groovy/refactoring/introduceVariable/loop7.test
@@ -4,5 +4,5 @@ while (<all>true<end>) {
-----
def preved = true
while (preved<caret>) {
- true
+ preved
} \ No newline at end of file
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgChangeProvider.java b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgChangeProvider.java
index 371fc70979b5..9c686055db6b 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgChangeProvider.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/HgChangeProvider.java
@@ -221,10 +221,11 @@ public class HgChangeProvider implements ChangeProvider {
// The original file exists so this is a duplication of the file.
// Don't create the before ContentRevision or IDEA will think
// this was a rename.
+ //todo: fix this unexpected status behavior (sometimes added status instead of copied, and copied instead of renamed )
processChange(
null,
HgCurrentContentRevision.create(afterFile, currentNumber),
- HgChangeProvider.COPIED,
+ FileStatus.ADDED,
builder,
vcsKey
);
diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/descriptors/JavaFxPropertyAttributeDescriptor.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/descriptors/JavaFxPropertyAttributeDescriptor.java
index 60d7a433d421..37488f345330 100644
--- a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/descriptors/JavaFxPropertyAttributeDescriptor.java
+++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/descriptors/JavaFxPropertyAttributeDescriptor.java
@@ -8,6 +8,7 @@ import com.intellij.util.ArrayUtil;
import com.intellij.xml.XmlAttributeDescriptor;
import com.intellij.xml.XmlElementDescriptor;
import com.intellij.xml.impl.BasicXmlAttributeDescriptor;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.javaFX.fxml.FxmlConstants;
import org.jetbrains.plugins.javaFX.fxml.JavaFxCommonClassNames;
@@ -209,9 +210,8 @@ public class JavaFxPropertyAttributeDescriptor extends BasicXmlAttributeDescript
}
@Override
- public PsiReference[] getValueReferences(XmlAttributeValue value) {
- String s = value.getValue();
- return s != null && !s.startsWith("${") ? super.getValueReferences(value) : PsiReference.EMPTY_ARRAY;
+ public PsiReference[] getValueReferences(XmlElement element, @NotNull String text) {
+ return !text.startsWith("${") ? super.getValueReferences(element, text) : PsiReference.EMPTY_ARRAY;
}
@Override
diff --git a/plugins/junit/src/com/intellij/execution/junit/JUnit3Framework.java b/plugins/junit/src/com/intellij/execution/junit/JUnit3Framework.java
index 2bebb05b5cff..21828ecb2afb 100644
--- a/plugins/junit/src/com/intellij/execution/junit/JUnit3Framework.java
+++ b/plugins/junit/src/com/intellij/execution/junit/JUnit3Framework.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.
@@ -63,6 +63,8 @@ public class JUnit3Framework extends JavaTestFramework {
@Override
@Nullable
protected PsiMethod findSetUpMethod(@NotNull PsiClass clazz) {
+ if (!JUnitUtil.isJUnit3TestClass(clazz)) return null;
+
for (PsiMethod each : clazz.getMethods()) {
if (each.getName().equals("setUp")) return each;
}
@@ -72,6 +74,8 @@ public class JUnit3Framework extends JavaTestFramework {
@Override
@Nullable
protected PsiMethod findTearDownMethod(@NotNull PsiClass clazz) {
+ if (!JUnitUtil.isJUnit3TestClass(clazz)) return null;
+
for (PsiMethod each : clazz.getMethods()) {
if (each.getName().equals("tearDown")) return each;
}
diff --git a/plugins/junit/src/com/intellij/execution/junit/JUnitConfiguration.java b/plugins/junit/src/com/intellij/execution/junit/JUnitConfiguration.java
index 569d4b12152a..422e567f8949 100644
--- a/plugins/junit/src/com/intellij/execution/junit/JUnitConfiguration.java
+++ b/plugins/junit/src/com/intellij/execution/junit/JUnitConfiguration.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.
@@ -492,7 +492,7 @@ public class JUnitConfiguration extends ModuleBasedConfiguration<JavaRunConfigur
final String fqName = myPattern.iterator().next();
return (fqName.contains("*") ? fqName : StringUtil.getShortName(fqName)) + (size > 1 ? " and " + (size - 1) + " more" : "");
}
- final String className = JavaExecutionUtil.getPresentableClassName(getMainClassName(), configurationModule);
+ final String className = JavaExecutionUtil.getPresentableClassName(getMainClassName());
if (TEST_METHOD.equals(TEST_OBJECT)) {
return className + '.' + getMethodName();
}
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/converters/MavenDependencySystemPathConverter.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/converters/MavenDependencySystemPathConverter.java
index ae91be9749ef..2641d4130a45 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/converters/MavenDependencySystemPathConverter.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/converters/MavenDependencySystemPathConverter.java
@@ -15,20 +15,18 @@
*/
package org.jetbrains.idea.maven.dom.converters;
-import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.util.Condition;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
-import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReferenceSet;
-import com.intellij.psi.xml.XmlElement;
import com.intellij.util.xml.ConvertContext;
import com.intellij.util.xml.CustomReferenceConverter;
import com.intellij.util.xml.GenericDomValue;
import com.intellij.util.xml.ResolvingConverter;
-import gnu.trove.THashSet;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.maven.dom.references.MavenPathReferenceConverter;
import java.util.Collection;
import java.util.Collections;
@@ -54,63 +52,12 @@ public class MavenDependencySystemPathConverter extends ResolvingConverter<PsiFi
@NotNull
public PsiReference[] createReferences(final GenericDomValue genericDomValue, final PsiElement element, final ConvertContext context) {
- XmlElement xmlElement = genericDomValue.getXmlElement();
-
- if (xmlElement != null && xmlElement.getText().contains("${")) return PsiReference.EMPTY_ARRAY;
-
- return createReferences(element, true);
- }
-
- @NotNull
- public static PsiReference[] createReferences(@NotNull final PsiElement psiElement, final boolean soft) {
- FileReferenceSet set = new MyFileReferenceSet(psiElement, soft);
-
- return set.getAllReferences();
- }
-
- private static class MyFileReferenceSet extends FileReferenceSet {
- private final boolean mySoft;
-
- public MyFileReferenceSet(PsiElement psiElement, boolean soft) {
- super(psiElement);
- mySoft = soft;
- }
-
- @Override
- public boolean isAbsolutePathReference() {
- return true;
- }
-
- @Override
- protected boolean isSoft() {
- return mySoft;
- }
-
- @NotNull
- @Override
- public Collection<PsiFileSystemItem> getDefaultContexts() {
- Collection<PsiFileSystemItem> systemItemCollection = super.getDefaultContexts();
- if (isAbsolutePathReference()) {
- VirtualFile vFile = LocalFileSystem.getInstance().getRoot();
-
- if (ApplicationManager.getApplication().isUnitTestMode()) {
- assert vFile != null : ""; //
- }
-
- if (vFile != null) {
- final PsiDirectory directory = getElement().getManager().findDirectory(vFile);
-
- if (ApplicationManager.getApplication().isUnitTestMode()) {
- assert directory != null : "for element: " + getElement().getText(); //
- }
-
- if (directory != null) {
- systemItemCollection = new THashSet<PsiFileSystemItem>(systemItemCollection);
- systemItemCollection.add(directory);
- }
- }
+ return MavenPathReferenceConverter.createReferences(genericDomValue, element, new Condition<PsiFileSystemItem>() {
+ @Override
+ public boolean value(PsiFileSystemItem item) {
+ return (item instanceof PsiDirectory) || item.getName().endsWith(".jar");
}
- return systemItemCollection;
- }
+ }, true);
}
}
+
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/converters/MavenUrlConverter.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/converters/MavenUrlConverter.java
index c4f864a642ec..d7a4ca4bae4f 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/converters/MavenUrlConverter.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/converters/MavenUrlConverter.java
@@ -18,10 +18,10 @@ package org.jetbrains.idea.maven.dom.converters;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
+import com.intellij.psi.impl.UrlPsiReference;
import com.intellij.util.xml.ConvertContext;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.Nullable;
-import org.jetbrains.idea.maven.dom.references.MavenUrlPsiReference;
public class MavenUrlConverter extends MavenReferenceConverter<String> {
@Override
@@ -35,6 +35,6 @@ public class MavenUrlConverter extends MavenReferenceConverter<String> {
}
protected PsiReference createReference(PsiElement element, String text, TextRange range) {
- return new MavenUrlPsiReference(element, text, range);
+ return new UrlPsiReference(element);
}
} \ No newline at end of file
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/converters/repositories/MavenRepositoryConverter.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/converters/repositories/MavenRepositoryConverter.java
index 4b08baf40d1d..46fa023da939 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/converters/repositories/MavenRepositoryConverter.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/converters/repositories/MavenRepositoryConverter.java
@@ -18,11 +18,10 @@ package org.jetbrains.idea.maven.dom.converters.repositories;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupElementBuilder;
import com.intellij.openapi.module.Module;
-import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.psi.ElementManipulators;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
+import com.intellij.psi.impl.UrlPsiReference;
import com.intellij.util.xml.ConvertContext;
import com.intellij.util.xml.GenericDomValue;
import com.intellij.util.xml.ResolvingConverter;
@@ -31,7 +30,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.maven.dom.converters.MavenUrlConverter;
import org.jetbrains.idea.maven.dom.model.MavenDomRepositoryBase;
-import org.jetbrains.idea.maven.dom.references.MavenUrlPsiReference;
import java.util.Collection;
import java.util.Collections;
@@ -77,9 +75,7 @@ public abstract class MavenRepositoryConverter extends ResolvingConverter<String
@NotNull
@Override
public PsiReference[] createReferences(GenericDomValue value, final PsiElement element, final ConvertContext context) {
- String text = value.getStringValue();
- TextRange range = ElementManipulators.getValueTextRange(element);
- return new PsiReference[]{new MavenUrlPsiReference(element, text, range) {
+ return new PsiReference[]{new UrlPsiReference(element) {
@NotNull
@Override
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/references/MavenPathReferenceConverter.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/references/MavenPathReferenceConverter.java
index 56672d738b10..b136cf440f59 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/references/MavenPathReferenceConverter.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/references/MavenPathReferenceConverter.java
@@ -23,6 +23,7 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReference;
import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReferenceSet;
+import com.intellij.util.Function;
import com.intellij.util.xml.ConvertContext;
import com.intellij.util.xml.DomElement;
import com.intellij.util.xml.DomUtil;
@@ -33,6 +34,7 @@ import org.jetbrains.idea.maven.dom.MavenPropertyResolver;
import org.jetbrains.idea.maven.dom.model.MavenDomProjectModel;
import java.util.Collection;
+import java.util.Collections;
/**
* @author Sergey Evdokimov
@@ -52,6 +54,12 @@ public class MavenPathReferenceConverter extends PathReferenceConverter {
public static PsiReference[] createReferences(final DomElement genericDomValue,
PsiElement element,
@NotNull final Condition<PsiFileSystemItem> fileFilter) {
+ return createReferences(genericDomValue, element, fileFilter, false);
+ }
+
+ public static PsiReference[] createReferences(final DomElement genericDomValue,
+ PsiElement element,
+ @NotNull final Condition<PsiFileSystemItem> fileFilter, boolean isAbsolutePath) {
ElementManipulator<PsiElement> manipulator = ElementManipulators.getManipulator(element);
TextRange range = manipulator.getRangeInElement(element);
String text = range.substring(element.getText());
@@ -88,7 +96,19 @@ public class MavenPathReferenceConverter extends PathReferenceConverter {
String resolvedText = model == null ? text : MavenPropertyResolver.resolve(text, model);
if (resolvedText.equals(text)) {
- super.innerResolveInContext(resolvedText, context, result, caseSensitive);
+ if (getIndex() == 0 && resolvedText.length() == 2 && resolvedText.charAt(1) == ':') {
+ // it's root on windows, e.g. "C:"
+ VirtualFile file = LocalFileSystem.getInstance().findFileByPath(resolvedText + '/');
+ if (file != null) {
+ PsiDirectory psiDirectory = context.getManager().findDirectory(file);
+ if (psiDirectory != null) {
+ result.add(new PsiElementResolveResult(psiDirectory));
+ }
+ }
+ }
+ else {
+ super.innerResolveInContext(resolvedText, context, result, caseSensitive);
+ }
}
else {
VirtualFile contextFile = context.getVirtualFile();
@@ -117,6 +137,33 @@ public class MavenPathReferenceConverter extends PathReferenceConverter {
}
};
+ if (isAbsolutePath) {
+ set.addCustomization(FileReferenceSet.DEFAULT_PATH_EVALUATOR_OPTION, new Function<PsiFile, Collection<PsiFileSystemItem>>() {
+ @Override
+ public Collection<PsiFileSystemItem> fun(PsiFile file) {
+ VirtualFile virtualFile = file.getVirtualFile();
+
+ if (virtualFile == null) {
+ return FileReferenceSet.ABSOLUTE_TOP_LEVEL.fun(file);
+ }
+
+ while (true) {
+ VirtualFile parent = virtualFile.getParent();
+ if (parent == null) break;
+ virtualFile = parent;
+ }
+
+ PsiDirectory root = file.getManager().findDirectory(virtualFile);
+
+ if (root == null) {
+ return FileReferenceSet.ABSOLUTE_TOP_LEVEL.fun(file);
+ }
+
+ return Collections.<PsiFileSystemItem>singletonList(root);
+ }
+ });
+ }
+
return set.getAllReferences();
}
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/references/MavenUrlPsiReference.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/references/MavenUrlPsiReference.java
deleted file mode 100644
index 12fd29d00798..000000000000
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/references/MavenUrlPsiReference.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright 2000-2009 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jetbrains.idea.maven.dom.references;
-
-import com.intellij.ide.BrowserUtil;
-import com.intellij.openapi.util.TextRange;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.impl.FakePsiElement;
-import org.jetbrains.annotations.NotNull;
-
-public class MavenUrlPsiReference extends MavenPsiReference {
- public MavenUrlPsiReference(PsiElement element, String text, TextRange range) {
- super(element, text, range);
- }
-
- public PsiElement resolve() {
- return new FakePsiElement() {
- public PsiElement getParent() {
- return myElement;
- }
-
- @Override
- public String getName() {
- return myText;
- }
-
- @Override
- public void navigate(boolean requestFocus) {
- BrowserUtil.launchBrowser(myText);
- }
- };
- }
-
- @NotNull
- public Object[] getVariants() {
- return EMPTY_ARRAY;
- }
-} \ No newline at end of file
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/MavenProjectsNavigatorPanel.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/MavenProjectsNavigatorPanel.java
index 31380d2c4b01..69cd93efab2a 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/MavenProjectsNavigatorPanel.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/navigator/MavenProjectsNavigatorPanel.java
@@ -298,7 +298,7 @@ public class MavenProjectsNavigatorPanel extends SimpleToolWindowPanel implement
return false;
}
- manager.addManagedFiles(pomFiles);
+ manager.addManagedFilesOrUnignore(pomFiles);
return true;
}
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/plugins/api/MavenModelPropertiesPatcher.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/plugins/api/MavenModelPropertiesPatcher.java
index defe2bf99d6c..047fc823199b 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/plugins/api/MavenModelPropertiesPatcher.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/plugins/api/MavenModelPropertiesPatcher.java
@@ -1,10 +1,10 @@
package org.jetbrains.idea.maven.plugins.api;
import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.util.SingletonInstancesCache;
import org.jdom.Element;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.maven.model.MavenPlugin;
-import org.jetbrains.plugins.groovy.util.ClassInstanceCache;
import java.util.Collection;
import java.util.List;
@@ -54,7 +54,8 @@ public class MavenModelPropertiesPatcher {
}
if (descriptor.propertyGenerator != null) {
- MavenPropertiesGenerator generator = ClassInstanceCache.getInstance(descriptor.propertyGenerator, descriptor.getLoaderForClass());
+ MavenPropertiesGenerator generator = SingletonInstancesCache
+ .getInstance(descriptor.propertyGenerator, descriptor.getLoaderForClass());
generator.generate(modelProperties, goal, plugin, cfgElement);
}
}
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManager.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManager.java
index 5564984a835d..678f811b0c34 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManager.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManager.java
@@ -484,6 +484,11 @@ public class MavenProjectsManager extends MavenSimpleProjectComponent
addManagedFilesWithProfiles(files, Collections.<String>emptyList());
}
+ public void addManagedFilesOrUnignore(@NotNull List<VirtualFile> files) {
+ removeIgnoredFilesPaths(MavenUtil.collectPaths(files));
+ addManagedFiles(files);
+ }
+
public void removeManagedFiles(@NotNull List<VirtualFile> files) {
myWatcher.removeManagedFiles(files);
}
@@ -629,6 +634,11 @@ public class MavenProjectsManager extends MavenSimpleProjectComponent
myProjectsTree.setIgnoredFilesPaths(paths);
}
+ public void removeIgnoredFilesPaths(final Collection<String> paths) {
+ if (!isInitialized()) return;
+ myProjectsTree.removeIgnoredFilesPaths(paths);
+ }
+
public boolean getIgnoredState(@NotNull MavenProject project) {
if (!isInitialized()) return false;
return myProjectsTree.getIgnoredState(project);
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManagerWatcher.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManagerWatcher.java
index 721908c4870b..81eb778b2466 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManagerWatcher.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsManagerWatcher.java
@@ -112,7 +112,16 @@ public class MavenProjectsManagerWatcher {
@Override
public void moduleRemoved(Project project, Module module) {
MavenProject mavenProject = myManager.findProject(module);
- if (mavenProject != null) myManager.setIgnoredState(Collections.singletonList(mavenProject), true);
+ if (mavenProject != null && !myManager.isIgnored(mavenProject)) {
+ VirtualFile file = mavenProject.getFile();
+
+ if (myManager.isManagedFile(file) && myManager.getModules(mavenProject).isEmpty()) {
+ myManager.removeManagedFiles(Collections.singletonList(file));
+ }
+ else {
+ myManager.setIgnoredState(Collections.singletonList(mavenProject), true);
+ }
+ }
}
@Override
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsTree.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsTree.java
index 3a39929978f0..a11d9cb13459 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsTree.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsTree.java
@@ -57,7 +57,7 @@ public class MavenProjectsTree {
private final Lock myStructureWriteLock = myStructureLock.writeLock();
// TODO replace with sets
- private volatile List<String> myManagedFilesPaths = new ArrayList<String>();
+ private volatile Set<String> myManagedFilesPaths = new LinkedHashSet<String>();
private volatile List<String> myIgnoredFilesPaths = new ArrayList<String>();
private volatile List<String> myIgnoredFilesPatterns = new ArrayList<String>();
private volatile Pattern myIgnoredFilesPatternsCache;
@@ -91,7 +91,7 @@ public class MavenProjectsTree {
try {
try {
if (!STORAGE_VERSION.equals(in.readUTF())) return null;
- result.myManagedFilesPaths = readCollection(in, new ArrayList<String>());
+ result.myManagedFilesPaths = readCollection(in, new LinkedHashSet<String>());
result.myIgnoredFilesPaths = readCollection(in, new ArrayList<String>());
result.myIgnoredFilesPatterns = readCollection(in, new ArrayList<String>());
result.myExplicitProfiles = readCollection(in, new THashSet<String>());
@@ -190,7 +190,7 @@ public class MavenProjectsTree {
public void resetManagedFilesPathsAndProfiles(List<String> paths, Collection<String> profiles) {
synchronized (myStateLock) {
- myManagedFilesPaths = new ArrayList<String>(paths);
+ myManagedFilesPaths = new LinkedHashSet<String>(paths);
}
setExplicitProfiles(profiles);
}
@@ -243,6 +243,14 @@ public class MavenProjectsTree {
});
}
+ public void removeIgnoredFilesPaths(final Collection<String> paths) {
+ doChangeIgnoreStatus(new Runnable() {
+ public void run() {
+ myIgnoredFilesPaths.removeAll(paths);
+ }
+ });
+ }
+
public boolean getIgnoredState(MavenProject project) {
synchronized (myStateLock) {
return myIgnoredFilesPaths.contains(project.getPath());
@@ -672,10 +680,12 @@ public class MavenProjectsTree {
}
public boolean isManagedFile(String path) {
- for (String each : getManagedFilesPaths()) {
- if (FileUtil.pathsEqual(each, path)) return true;
+ synchronized (myStateLock) {
+ for (String each : myManagedFilesPaths) {
+ if (FileUtil.pathsEqual(each, path)) return true;
+ }
+ return false;
}
- return false;
}
public boolean isPotentialProject(String path) {
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/actions/AddFileAsMavenProjectAction.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/actions/AddFileAsMavenProjectAction.java
index a7d686344e36..c2980a0bfc15 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/actions/AddFileAsMavenProjectAction.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/actions/AddFileAsMavenProjectAction.java
@@ -31,7 +31,7 @@ public class AddFileAsMavenProjectAction extends MavenAction {
public void actionPerformed(AnActionEvent e) {
final DataContext context = e.getDataContext();
MavenProjectsManager manager = MavenActionUtil.getProjectsManager(context);
- manager.addManagedFiles(Collections.singletonList(getSelectedFile(context)));
+ manager.addManagedFilesOrUnignore(Collections.singletonList(getSelectedFile(context)));
}
@Override
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/actions/AddManagedFilesAction.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/actions/AddManagedFilesAction.java
index f4b12b8337f4..4ebf81b1aaca 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/actions/AddManagedFilesAction.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/actions/AddManagedFilesAction.java
@@ -50,6 +50,6 @@ public class AddManagedFilesAction extends MavenAction {
VirtualFile[] files = FileChooser.chooseFiles(singlePomSelection, project, fileToSelect);
if (files.length == 0) return;
- manager.addManagedFiles(Arrays.asList(files));
+ manager.addManagedFilesOrUnignore(Arrays.asList(files));
}
}
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenFrameworkSupportProvider.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenFrameworkSupportProvider.java
index 01ea1fe3f5de..ec8b82c1bb42 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenFrameworkSupportProvider.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenFrameworkSupportProvider.java
@@ -66,7 +66,7 @@ public class MavenFrameworkSupportProvider extends FrameworkSupportProvider {
VirtualFile existingPom = root.findChild(MavenConstants.POM_XML);
if (existingPom != null) {
- MavenProjectsManager.getInstance(module.getProject()).addManagedFiles(Collections.singletonList(existingPom));
+ MavenProjectsManager.getInstance(module.getProject()).addManagedFilesOrUnignore(Collections.singletonList(existingPom));
}
else {
prepareProjectStructure(model, root);
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenModuleBuilderHelper.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenModuleBuilderHelper.java
index f951597aefaf..7494babcb7b7 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenModuleBuilderHelper.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenModuleBuilderHelper.java
@@ -117,7 +117,7 @@ public class MavenModuleBuilderHelper {
if (myAggregatorProject == null) {
MavenProjectsManager manager = MavenProjectsManager.getInstance(project);
- manager.addManagedFiles(Collections.singletonList(pom));
+ manager.addManagedFilesOrUnignore(Collections.singletonList(pom));
}
if (myArchetype == null) {
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenProjectBuilder.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenProjectBuilder.java
index a516632a38ca..53a486fb47ba 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenProjectBuilder.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/wizards/MavenProjectBuilder.java
@@ -126,6 +126,9 @@ public class MavenProjectBuilder extends ProjectImportBuilder<MavenProject> {
}
MavenProjectsManager manager = MavenProjectsManager.getInstance(project);
+
+ manager.setIgnoredState(getParameters().mySelectedProjects, false);
+
manager.addManagedFilesWithProfiles(MavenUtil.collectFiles(getParameters().mySelectedProjects), selectedProfiles);
manager.waitForReadingCompletion();
diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/dom/MavenDependencyCompletionAndResolutionTest.java b/plugins/maven/src/test/java/org/jetbrains/idea/maven/dom/MavenDependencyCompletionAndResolutionTest.java
index 61858813c2ee..2b257d97e00a 100644
--- a/plugins/maven/src/test/java/org/jetbrains/idea/maven/dom/MavenDependencyCompletionAndResolutionTest.java
+++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/dom/MavenDependencyCompletionAndResolutionTest.java
@@ -31,6 +31,7 @@ import org.jetbrains.idea.maven.dom.intentions.ChooseFileIntentionAction;
import org.jetbrains.idea.maven.dom.model.MavenDomDependency;
import org.jetbrains.idea.maven.dom.model.MavenDomProjectModel;
+import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -661,6 +662,30 @@ public class MavenDependencyCompletionAndResolutionTest extends MavenDomWithIndi
checkHighlighting();
}
+ public void testCompletionSystemScopeDependenciesWithProperties() throws Throwable {
+ String libPath = myIndicesFixture.getRepositoryHelper().getTestDataPath("local1/junit/junit/4.0/junit-4.0.jar");
+
+ createProjectPom("<groupId>test</groupId>" +
+ "<artifactId>project</artifactId>" +
+ "<version>1</version>" +
+
+ "<properties>" +
+ " <depDir>" + new File(libPath).getParent() + "</depDir>" +
+ "</properties>" +
+
+ "<dependencies>" +
+ " <dependency>" +
+ " <groupId>xxx</groupId>" +
+ " <artifactId>xxx</artifactId>" +
+ " <version>xxx</version>" +
+ " <scope>system</scope>" +
+ " <systemPath>${depDir}/<caret></systemPath>" +
+ " </dependency>" +
+ "</dependencies>");
+
+ assertCompletionVariants(myProjectPom, "junit-4.0.jar");
+ }
+
public void testResolvingSystemScopeDependenciesFromSystemPath() throws Throwable {
String libPath = myIndicesFixture.getRepositoryHelper().getTestDataPath("local1/junit/junit/4.0/junit-4.0.jar");
diff --git a/plugins/svn4idea/bindSvn/bindSvn.iml b/plugins/svn4idea/bindSvn/bindSvn.iml
deleted file mode 100644
index 846587cef36f..000000000000
--- a/plugins/svn4idea/bindSvn/bindSvn.iml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module type="JAVA_MODULE" version="4">
- <component name="NewModuleRootManager" inherit-compiler-output="true">
- <exclude-output />
- <content url="file://$MODULE_DIR$">
- <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
- </content>
- <orderEntry type="inheritedJdk" />
- <orderEntry type="sourceFolder" forTests="false" />
- <orderEntry type="module" module-name="platform-api" />
- <orderEntry type="module" module-name="vcs-api" />
- <orderEntry type="module-library">
- <library>
- <CLASSES>
- <root url="jar://$MODULE_DIR$/lib/javahl.jar!/" />
- </CLASSES>
- <JAVADOC />
- <SOURCES>
- <root url="jar://$MODULE_DIR$/lib/javahlsrc.zip!/src" />
- </SOURCES>
- </library>
- </orderEntry>
- </component>
-</module>
-
diff --git a/plugins/svn4idea/bindSvn/lib/javahl.jar b/plugins/svn4idea/bindSvn/lib/javahl.jar
deleted file mode 100644
index a0c5370065af..000000000000
--- a/plugins/svn4idea/bindSvn/lib/javahl.jar
+++ /dev/null
Binary files differ
diff --git a/plugins/svn4idea/bindSvn/lib/javahlsrc.zip b/plugins/svn4idea/bindSvn/lib/javahlsrc.zip
deleted file mode 100644
index 9c50118203b7..000000000000
--- a/plugins/svn4idea/bindSvn/lib/javahlsrc.zip
+++ /dev/null
Binary files differ
diff --git a/plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/SvnBindClient.java b/plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/SvnBindClient.java
deleted file mode 100644
index c155b78ddc53..000000000000
--- a/plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/SvnBindClient.java
+++ /dev/null
@@ -1,925 +0,0 @@
-/*
- * 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 org.jetbrains.idea.svn;
-
-import org.tigris.subversion.javahl.*;
-
-import java.io.OutputStream;
-import java.util.Map;
-
-/**
- * Created with IntelliJ IDEA.
- * User: Irina.Chernushina
- * Date: 2/5/13
- * Time: 3:08 PM
- */
-public class SvnBindClient implements SVNClientInterface {
- private final String myExecutablePath;
- private CommitEventHandler myHandler;
- private AuthenticationCallback myAuthenticationCallback;
-
- public SvnBindClient(String path) {
- myExecutablePath = path;
- }
-
- @Override
- public void dispose() {
- }
-
- @Override
- public Version getVersion() {
- // todo real version
- throw new UnsupportedOperationException();
- }
-
- @Override
- public String getAdminDirectoryName() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public boolean isAdminDirectory(String name) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public String getLastPath() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public Status singleStatus(String path, boolean onServer) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public Status[] status(String path, boolean descend, boolean onServer, boolean getAll) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public Status[] status(String path, boolean descend, boolean onServer, boolean getAll, boolean noIgnore) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public Status[] status(String path, boolean descend, boolean onServer, boolean getAll, boolean noIgnore, boolean ignoreExternals)
- throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void status(String path,
- int depth,
- boolean onServer,
- boolean getAll,
- boolean noIgnore,
- boolean ignoreExternals,
- String[] changelists,
- StatusCallback callback) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public DirEntry[] list(String url, Revision revision, boolean recurse) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public DirEntry[] list(String url, Revision revision, Revision pegRevision, boolean recurse) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void list(String url,
- Revision revision,
- Revision pegRevision,
- int depth,
- int direntFields,
- boolean fetchLocks,
- ListCallback callback) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void username(String username) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void password(String password) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void setPrompt(PromptUserPassword prompt) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public LogMessage[] logMessages(String path, Revision revisionStart, Revision revisionEnd) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public LogMessage[] logMessages(String path, Revision revisionStart, Revision revisionEnd, boolean stopOnCopy) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public LogMessage[] logMessages(String path, Revision revisionStart, Revision revisionEnd, boolean stopOnCopy, boolean discoverPath)
- throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public LogMessage[] logMessages(String path,
- Revision revisionStart,
- Revision revisionEnd,
- boolean stopOnCopy,
- boolean discoverPath,
- long limit) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void logMessages(String path,
- Revision pegRevision,
- Revision revisionStart,
- Revision revisionEnd,
- boolean stopOnCopy,
- boolean discoverPath,
- boolean includeMergedRevisions,
- String[] revProps,
- long limit,
- LogMessageCallback callback) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void logMessages(String path,
- Revision pegRevision,
- RevisionRange[] ranges,
- boolean stopOnCopy,
- boolean discoverPath,
- boolean includeMergedRevisions,
- String[] revProps,
- long limit,
- LogMessageCallback callback) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public long checkout(String moduleName, String destPath, Revision revision, boolean recurse) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public long checkout(String moduleName,
- String destPath,
- Revision revision,
- Revision pegRevision,
- boolean recurse,
- boolean ignoreExternals) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public long checkout(String moduleName,
- String destPath,
- Revision revision,
- Revision pegRevision,
- int depth,
- boolean ignoreExternals,
- boolean allowUnverObstructions) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void notification(Notify notify) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void notification2(Notify2 notify) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void setConflictResolver(ConflictResolverCallback listener) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void setProgressListener(ProgressListener listener) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void commitMessageHandler(CommitMessage messageHandler) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void remove(String[] path, String message, boolean force) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void remove(String[] path, String message, boolean force, boolean keepLocal, Map revpropTable) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void revert(String path, boolean recurse) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void revert(String path, int depth, String[] changelists) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void add(String path, boolean recurse) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void add(String path, boolean recurse, boolean force) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void add(String path, int depth, boolean force, boolean noIgnores, boolean addParents) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public long update(String path, Revision revision, boolean recurse) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public long[] update(String[] path, Revision revision, boolean recurse, boolean ignoreExternals) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public long update(String path,
- Revision revision,
- int depth,
- boolean depthIsSticky,
- boolean ignoreExternals,
- boolean allowUnverObstructions) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public long[] update(String[] path,
- Revision revision,
- int depth,
- boolean depthIsSticky,
- boolean ignoreExternals,
- boolean allowUnverObstructions) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public long commit(String[] path, String message, boolean recurse) throws ClientException {
- return commit(path, message, recurse? 3 : 0, false, false, null, null);
- }
-
- @Override
- public long commit(String[] path, String message, boolean recurse, boolean noUnlock) throws ClientException {
- return commit(path, message, recurse? 3 : 0, noUnlock, false, null, null);
- }
-
- @Override
- public long commit(String[] path,
- String message,
- int depth,
- boolean noUnlock,
- boolean keepChangelist,
- String[] changelists,
- Map revpropTable) throws ClientException {
- final long commit = new SvnCommitRunner(myExecutablePath, myHandler, myAuthenticationCallback).
- commit(path, message, depth, noUnlock, keepChangelist, changelists, revpropTable);
- if (commit < 0) {
- throw new BindClientException("Wrong committed revision number: " + commit, null, -1);
- }
- return commit;
- }
-
- @Override
- public void copy(CopySource[] sources,
- String destPath,
- String message,
- boolean copyAsChild,
- boolean makeParents,
- boolean ignoreExternals,
- Map revpropTable) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void copy(CopySource[] sources, String destPath, String message, boolean copyAsChild, boolean makeParents, Map revpropTable)
- throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void copy(String srcPath, String destPath, String message, Revision revision) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void move(String[] srcPaths,
- String destPath,
- String message,
- boolean force,
- boolean moveAsChild,
- boolean makeParents,
- Map revpropTable) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void move(String srcPath, String destPath, String message, Revision ignored, boolean force) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void move(String srcPath, String destPath, String message, boolean force) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void mkdir(String[] path, String message, boolean makeParents, Map revpropTable) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void mkdir(String[] path, String message) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void cleanup(String path) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void resolve(String path, int depth, int conflictResult) throws SubversionException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void resolved(String path, boolean recurse) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public long doExport(String srcPath, String destPath, Revision revision, boolean force) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public long doExport(String srcPath,
- String destPath,
- Revision revision,
- Revision pegRevision,
- boolean force,
- boolean ignoreExternals,
- boolean recurse,
- String nativeEOL) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public long doExport(String srcPath,
- String destPath,
- Revision revision,
- Revision pegRevision,
- boolean force,
- boolean ignoreExternals,
- int depth,
- String nativeEOL) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public long doSwitch(String path, String url, Revision revision, boolean recurse) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public long doSwitch(String path,
- String url,
- Revision revision,
- Revision pegRevision,
- int depth,
- boolean depthIsSticky,
- boolean ignoreExternals,
- boolean allowUnverObstructions) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void doImport(String path, String url, String message, boolean recurse) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void doImport(String path,
- String url,
- String message,
- int depth,
- boolean noIgnore,
- boolean ignoreUnknownNodeTypes,
- Map revpropTable) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public String[] suggestMergeSources(String path, Revision pegRevision) throws SubversionException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void merge(String path1, Revision revision1, String path2, Revision revision2, String localPath, boolean force, boolean recurse)
- throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void merge(String path1,
- Revision revision1,
- String path2,
- Revision revision2,
- String localPath,
- boolean force,
- boolean recurse,
- boolean ignoreAncestry,
- boolean dryRun) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void merge(String path1,
- Revision revision1,
- String path2,
- Revision revision2,
- String localPath,
- boolean force,
- int depth,
- boolean ignoreAncestry,
- boolean dryRun,
- boolean recordOnly) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void merge(String path,
- Revision pegRevision,
- Revision revision1,
- Revision revision2,
- String localPath,
- boolean force,
- boolean recurse,
- boolean ignoreAncestry,
- boolean dryRun) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void merge(String path,
- Revision pegRevision,
- RevisionRange[] revisions,
- String localPath,
- boolean force,
- int depth,
- boolean ignoreAncestry,
- boolean dryRun,
- boolean recordOnly) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void mergeReintegrate(String path, Revision pegRevision, String localPath, boolean dryRun) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public Mergeinfo getMergeinfo(String path, Revision pegRevision) throws SubversionException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void getMergeinfoLog(int kind,
- String pathOrUrl,
- Revision pegRevision,
- String mergeSourceUrl,
- Revision srcPegRevision,
- boolean discoverChangedPaths,
- int depth,
- String[] revProps,
- LogMessageCallback callback) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void getMergeinfoLog(int kind,
- String pathOrUrl,
- Revision pegRevision,
- String mergeSourceUrl,
- Revision srcPegRevision,
- boolean discoverChangedPaths,
- String[] revProps,
- LogMessageCallback callback) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void diff(String target1, Revision revision1, String target2, Revision revision2, String outFileName, boolean recurse)
- throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void diff(String target1,
- Revision revision1,
- String target2,
- Revision revision2,
- String outFileName,
- boolean recurse,
- boolean ignoreAncestry,
- boolean noDiffDeleted,
- boolean force) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void diff(String target1,
- Revision revision1,
- String target2,
- Revision revision2,
- String relativeToDir,
- String outFileName,
- int depth,
- String[] changelists,
- boolean ignoreAncestry,
- boolean noDiffDeleted,
- boolean force,
- boolean copiesAsAdds) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void diff(String target1,
- Revision revision1,
- String target2,
- Revision revision2,
- String relativeToDir,
- String outFileName,
- int depth,
- String[] changelists,
- boolean ignoreAncestry,
- boolean noDiffDeleted,
- boolean force) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void diff(String target,
- Revision pegRevision,
- Revision startRevision,
- Revision endRevision,
- String outFileName,
- boolean recurse,
- boolean ignoreAncestry,
- boolean noDiffDeleted,
- boolean force) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void diff(String target,
- Revision pegRevision,
- Revision startRevision,
- Revision endRevision,
- String relativeToDir,
- String outFileName,
- int depth,
- String[] changelists,
- boolean ignoreAncestry,
- boolean noDiffDeleted,
- boolean force,
- boolean copiesAsAdds) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void diff(String target,
- Revision pegRevision,
- Revision startRevision,
- Revision endRevision,
- String relativeToDir,
- String outFileName,
- int depth,
- String[] changelists,
- boolean ignoreAncestry,
- boolean noDiffDeleted,
- boolean force) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void diffSummarize(String target1,
- Revision revision1,
- String target2,
- Revision revision2,
- int depth,
- String[] changelists,
- boolean ignoreAncestry,
- DiffSummaryReceiver receiver) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void diffSummarize(String target,
- Revision pegRevision,
- Revision startRevision,
- Revision endRevision,
- int depth,
- String[] changelists,
- boolean ignoreAncestry,
- DiffSummaryReceiver receiver) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public PropertyData[] properties(String path) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public PropertyData[] properties(String path, Revision revision) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public PropertyData[] properties(String path, Revision revision, Revision pegRevision) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void properties(String path, Revision revision, Revision pegRevision, int depth, String[] changelists, ProplistCallback callback)
- throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void propertySet(String path, String name, String value, boolean recurse) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void propertySet(String path, String name, String value, boolean recurse, boolean force) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void propertySet(String path, String name, byte[] value, boolean recurse) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void propertySet(String path, String name, byte[] value, boolean recurse, boolean force) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void propertySet(String path, String name, String value, int depth, String[] changelists, boolean force, Map revpropTable)
- throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void propertyRemove(String path, String name, boolean recurse) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void propertyRemove(String path, String name, int depth, String[] changelists) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void propertyCreate(String path, String name, String value, boolean recurse) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void propertyCreate(String path, String name, String value, boolean recurse, boolean force) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void propertyCreate(String path, String name, byte[] value, boolean recurse) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void propertyCreate(String path, String name, byte[] value, boolean recurse, boolean force) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void propertyCreate(String path, String name, String value, int depth, String[] changelists, boolean force)
- throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public PropertyData revProperty(String path, String name, Revision rev) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public PropertyData[] revProperties(String path, Revision rev) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void setRevProperty(String path, String name, Revision rev, String value, boolean force) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void setRevProperty(String path, String name, Revision rev, String value, String originalValue, boolean force)
- throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public PropertyData propertyGet(String path, String name) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public PropertyData propertyGet(String path, String name, Revision revision) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public PropertyData propertyGet(String path, String name, Revision revision, Revision pegRevision) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public byte[] fileContent(String path, Revision revision) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public byte[] fileContent(String path, Revision revision, Revision pegRevision) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void streamFileContent(String path, Revision revision, Revision pegRevision, int bufferSize, OutputStream stream)
- throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void relocate(String from, String to, String path, boolean recurse) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public byte[] blame(String path, Revision revisionStart, Revision revisionEnd) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void blame(String path, Revision revisionStart, Revision revisionEnd, BlameCallback callback) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void blame(String path, Revision pegRevision, Revision revisionStart, Revision revisionEnd, BlameCallback callback)
- throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void blame(String path,
- Revision pegRevision,
- Revision revisionStart,
- Revision revisionEnd,
- boolean ignoreMimeType,
- boolean includeMergedRevisions,
- BlameCallback2 callback) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void blame(String path,
- Revision pegRevision,
- Revision revisionStart,
- Revision revisionEnd,
- boolean ignoreMimeType,
- boolean includeMergedRevisions,
- BlameCallback3 callback) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void setConfigDirectory(String configDir) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public String getConfigDirectory() throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void cancelOperation() throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public Info info(String path) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void addToChangelist(String[] paths, String changelist, int depth, String[] changelists) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void removeFromChangelists(String[] paths, int depth, String[] changelists) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void getChangelists(String rootPath, String[] changelists, int depth, ChangelistCallback callback) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void lock(String[] path, String comment, boolean force) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void unlock(String[] path, boolean force) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public Info2[] info2(String pathOrUrl, Revision revision, Revision pegRevision, boolean recurse) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void info2(String pathOrUrl, Revision revision, Revision pegRevision, int depth, String[] changelists, InfoCallback callback)
- throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public String getVersionInfo(String path, String trailUrl, boolean lastChanged) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void upgrade(String path) throws ClientException {
- throw new UnsupportedOperationException();
- }
-
- public void setHandler(CommitEventHandler handler) {
- myHandler = handler;
- }
-
- public void setAuthenticationCallback(AuthenticationCallback authenticationCallback) {
- myAuthenticationCallback = authenticationCallback;
- }
-}
diff --git a/plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/status/LockWrapper.java b/plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/status/LockWrapper.java
deleted file mode 100644
index f4e0f4cf2269..000000000000
--- a/plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/status/LockWrapper.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * 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 org.jetbrains.idea.svn.status;
-
-import org.apache.subversion.javahl.types.Lock;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.util.Date;
-
-/**
- * Created with IntelliJ IDEA.
- * User: Irina.Chernushina
- * Date: 2/21/12
- * Time: 2:33 PM
- */
-public class LockWrapper {
- private String myPath;
- private String myID;
- private String myOwner;
- private String myComment;
- private Date myCreationDate;
- private Date myExpirationDate;
-
- public LockWrapper(String path, String ID, String owner, String comment, Date creationDate, Date expirationDate) {
- myPath = path;
- myID = ID;
- myOwner = owner;
- myComment = comment;
- myCreationDate = creationDate;
- myExpirationDate = expirationDate;
- }
-
- public LockWrapper() {
- }
-
- public String getPath() {
- return myPath;
- }
-
- public void setPath(String path) {
- myPath = path;
- }
-
- public String getID() {
- return myID;
- }
-
- public void setID(String ID) {
- myID = ID;
- }
-
- public String getOwner() {
- return myOwner;
- }
-
- public void setOwner(String owner) {
- myOwner = owner;
- }
-
- public String getComment() {
- return myComment;
- }
-
- public void setComment(String comment) {
- myComment = comment;
- }
-
- public Date getCreationDate() {
- return myCreationDate;
- }
-
- public void setCreationDate(Date creationDate) {
- myCreationDate = creationDate;
- }
-
- public Date getExpirationDate() {
- return myExpirationDate;
- }
-
- public void setExpirationDate(Date expirationDate) {
- myExpirationDate = expirationDate;
- }
-
- public org.tigris.subversion.javahl.Lock create() {
- final Date creation = getCreationDate();
- final Date expiration = getExpirationDate();
- final Lock newLock = new Lock(getOwner(), getPath(), getID(), getComment(), creation == null ? 0 : creation.getTime(),
- expiration == null ? 0 : expiration.getTime());
- try {
- final Constructor<org.tigris.subversion.javahl.Lock> constructor = org.tigris.subversion.javahl.Lock.class.getConstructor(Lock.class);
- constructor.setAccessible(true);
- return constructor.newInstance(newLock);
- }
- catch (NoSuchMethodException e) {
- throw new RuntimeException(e);
- }
- catch (InvocationTargetException e) {
- throw new RuntimeException(e);
- }
- catch (InstantiationException e) {
- throw new RuntimeException(e);
- }
- catch (IllegalAccessException e) {
- throw new RuntimeException(e);
- }
- }
-}
diff --git a/plugins/svn4idea/bindSvn/src/org/tigris/subversion/javahl/BindClientException.java b/plugins/svn4idea/bindSvn/src/org/tigris/subversion/javahl/BindClientException.java
deleted file mode 100644
index f8acc17d0558..000000000000
--- a/plugins/svn4idea/bindSvn/src/org/tigris/subversion/javahl/BindClientException.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 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 org.tigris.subversion.javahl;
-
-import org.jetbrains.annotations.NotNull;
-
-/**
- * Created with IntelliJ IDEA.
- * User: Irina.Chernushina
- * Date: 2/25/13
- * Time: 6:29 PM
- */
-public class BindClientException extends ClientException {
- private Throwable myCause;
-
- public BindClientException(String message, String source, int aprError) {
- super(message, source, aprError);
- }
-
- public BindClientException(org.apache.subversion.javahl.ClientException ex) {
- super(ex);
- }
-
- public static BindClientException create(@NotNull final Throwable t, final int code) {
- final BindClientException exception = new BindClientException(t.getMessage(), null, code);
- exception.myCause = t;
- return exception;
- }
-
- @Override
- public Throwable getCause() {
- return myCause;
- }
-}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/ForNestedRootChecker.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/ForNestedRootChecker.java
index 4559a3e603e2..6a62276b3a1a 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/ForNestedRootChecker.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/ForNestedRootChecker.java
@@ -49,11 +49,9 @@ public class ForNestedRootChecker {
private static class UrlConstructor {
final SvnVcs myVcs;
- final SVNWCClient myClient;
private UrlConstructor(final SvnVcs vcs) {
myVcs = vcs;
- myClient = myVcs.createWCClient();
}
@Nullable
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/RootsToWorkingCopies.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/RootsToWorkingCopies.java
index 6cd0df2744d1..5ca7f9eaa39b 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/RootsToWorkingCopies.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/RootsToWorkingCopies.java
@@ -123,52 +123,31 @@ public class RootsToWorkingCopies implements VcsListener {
@Nullable
private WorkingCopy calculateRoot(final VirtualFile root) {
+ File workingCopyRoot = SvnUtil.getWorkingCopyRootNew(new File(root.getPath()));
WorkingCopy workingCopy = null;
- final File ioFile = new File(root.getPath());
- File workingCopyRoot = null;
- try {
- workingCopyRoot = SVNWCUtil.getWorkingCopyRoot(ioFile, true);
- if (workingCopyRoot != null) {
- // ok to use low-level 1.6 API, 1.7 is checked below
- SVNWCAccess wcAccess = SVNWCAccess.newInstance(null);
- try {
- wcAccess.probeOpen(workingCopyRoot, false, 0);
- SVNEntry entry = wcAccess.getVersionedEntry(workingCopyRoot, false);
- final SVNURL url = entry.getSVNURL();
- if (url != null) {
- workingCopy = new WorkingCopy(workingCopyRoot, url, false);
- }
- } finally {
- wcAccess.close();
- }
- }
- }
- catch (SVNException e) {
- //
- }
- if (workingCopy == null) {
- workingCopyRoot = SvnUtil.getWcCopyRootIf17(ioFile, null);
- if (workingCopyRoot != null) {
- final SVNInfo svnInfo;
- try {
- svnInfo = SvnVcs.getInstance(myProject).createWCClient().doInfo(workingCopyRoot, SVNRevision.UNDEFINED);
- workingCopy = new WorkingCopy(workingCopyRoot, svnInfo.getURL(), true);
- }
- catch (SVNException e) {
- //
- }
+
+ if (workingCopyRoot != null) {
+ final SVNInfo svnInfo = myVcs.getInfo(workingCopyRoot);
+
+ if (svnInfo != null && svnInfo.getURL() != null) {
+ workingCopy = new WorkingCopy(workingCopyRoot, svnInfo.getURL(), true);
}
}
+
+ return registerWorkingCopy(root, workingCopy);
+ }
+
+ private WorkingCopy registerWorkingCopy(@NotNull VirtualFile root, @Nullable WorkingCopy resolvedWorkingCopy) {
synchronized (myLock) {
- if (workingCopy == null) {
+ if (resolvedWorkingCopy == null) {
myRootMapping.remove(root);
myUnversioned.add(root);
} else {
myUnversioned.remove(root);
- myRootMapping.put(root, workingCopy);
+ myRootMapping.put(root, resolvedWorkingCopy);
}
}
- return workingCopy;
+ return resolvedWorkingCopy;
}
public void clear() {
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnAbstractWriteOperationLocks.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnAbstractWriteOperationLocks.java
index b4fd10492dfb..29e87422bb53 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnAbstractWriteOperationLocks.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnAbstractWriteOperationLocks.java
@@ -36,6 +36,7 @@ import java.util.concurrent.locks.ReentrantLock;
* Date: 10/19/12
* Time: 12:09 PM
*/
+// TODO: Such locking functionality is not required anymore. Likely to be removed (together with SvnProxies).
public abstract class SvnAbstractWriteOperationLocks {
private final long myTimeout;
private final static Map<String, Lock> myLockMap = new HashMap<String, Lock>();
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnAuthenticationNotifier.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnAuthenticationNotifier.java
index 8a94f0076acf..4efcce6f0db6 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnAuthenticationNotifier.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnAuthenticationNotifier.java
@@ -350,7 +350,9 @@ public class SvnAuthenticationNotifier extends GenericNotifierImpl<SvnAuthentica
}
SvnInteractiveAuthenticationProvider.clearCallState();
try {
+ // start svnkit authentication cycle
SvnVcs.getInstance(project).createWCClient(manager).doInfo(url, SVNRevision.UNDEFINED, SVNRevision.HEAD);
+ //SvnVcs.getInstance(project).getInfo(url, SVNRevision.HEAD, manager);
} catch (SVNAuthenticationException e) {
log(e);
return false;
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnBundle.properties b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnBundle.properties
index c306386eb0f8..61a5bb26f663 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnBundle.properties
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnBundle.properties
@@ -537,6 +537,7 @@ dialog.show.svn.map.table.version14.text=1.4
dialog.show.svn.map.table.version15.text=1.5
dialog.show.svn.map.table.version16.text=1.6
dialog.show.svn.map.table.version17.text=1.7
+dialog.show.svn.map.table.version18.text=1.8
action.change.wcopy.format.task.title=Convert working copy format
action.change.wcopy.format.task.progress.text=Converting working copy at {0} format from {1} to {2}
action.change.wcopy.format.after.change.settings=Selected working copy format ({0}) is older than upgrade mode selected in Project Settings ({1}).\
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnChangeProvider.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnChangeProvider.java
index dc8cbb1cce8b..b28ebd53dde2 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnChangeProvider.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnChangeProvider.java
@@ -85,7 +85,7 @@ public class SvnChangeProvider implements ChangeProvider {
statusReceiver.addListener(context);
statusReceiver.addListener(nestedCopiesBuilder);
- final SvnRecursiveStatusWalker walker = new SvnRecursiveStatusWalker(myVcs.getProject(), statusReceiver.getMulticaster(), partner);
+ final SvnRecursiveStatusWalker walker = new SvnRecursiveStatusWalker(myVcs, statusReceiver.getMulticaster(), partner);
for (FilePath path : zipper.getRecursiveDirs()) {
walker.go(path, SVNDepth.INFINITY);
@@ -180,7 +180,7 @@ public class SvnChangeProvider implements ChangeProvider {
public void getChanges(final FilePath path, final boolean recursive, final ChangelistBuilder builder) throws SVNException {
final SvnChangeProviderContext context = new SvnChangeProviderContext(myVcs, builder, null);
final StatusWalkerPartnerImpl partner = new StatusWalkerPartnerImpl(myVcs, ProgressManager.getInstance().getProgressIndicator());
- final SvnRecursiveStatusWalker walker = new SvnRecursiveStatusWalker(myVcs.getProject(), context, partner);
+ final SvnRecursiveStatusWalker walker = new SvnRecursiveStatusWalker(myVcs, context, partner);
walker.go(path, recursive ? SVNDepth.INFINITY : SVNDepth.IMMEDIATES);
processCopiedAndDeleted(context, null);
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnChangeProviderContext.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnChangeProviderContext.java
index 40c34d394590..9689dcee4a71 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnChangeProviderContext.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnChangeProviderContext.java
@@ -259,23 +259,15 @@ class SvnChangeProviderContext implements StatusReceiver {
public void addModifiedNotSavedChange(final VirtualFile file) throws SVNException {
final FilePath filePath = new FilePathImpl(file);
- final SVNInfo svnInfo;
- try {
- svnInfo = myVcs.createWCClient().doInfo(new File(file.getPath()), SVNRevision.UNDEFINED);
+ final SVNInfo svnInfo = myVcs.getInfo(file);
+
+ if (svnInfo != null) {
+ final SVNStatus svnStatus = new SVNStatus();
+ svnStatus.setRevision(svnInfo.getRevision());
+ myChangelistBuilder.processChangeInList(
+ createChange(SvnContentRevision.createBaseRevision(myVcs, filePath, svnInfo.getRevision()), CurrentContentRevision.create(filePath),
+ FileStatus.MODIFIED, svnStatus), (String)null, SvnVcs.getKey());
}
- catch (SVNException e) {
- final SVNErrorCode errorCode = e.getErrorMessage().getErrorCode();
- if (SVNErrorCode.WC_PATH_NOT_FOUND.equals(errorCode) ||
- SVNErrorCode.UNVERSIONED_RESOURCE.equals(errorCode) || SVNErrorCode.WC_NOT_WORKING_COPY.equals(errorCode)) {
- return;
- }
- throw e;
- }
- final SVNStatus svnStatus = new SVNStatus();
- svnStatus.setRevision(svnInfo.getRevision());
- myChangelistBuilder.processChangeInList(createChange(SvnContentRevision.createBaseRevision(myVcs, filePath, svnInfo.getRevision()),
- CurrentContentRevision.create(filePath), FileStatus.MODIFIED, svnStatus), (String) null,
- SvnVcs.getKey());
}
private void checkSwitched(final FilePath filePath, final ChangelistBuilder builder, final SVNStatus status,
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnChangelistListener.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnChangelistListener.java
index ee326a42afb2..51d5dc486c51 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnChangelistListener.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnChangelistListener.java
@@ -176,11 +176,9 @@ public class SvnChangelistListener implements ChangeListListener {
}
@Nullable
- public static String getCurrentMapping(final Project project, final File file) {
- final SvnVcs vcs = SvnVcs.getInstance(project);
- final SVNStatusClient statusClient = vcs.createStatusClient();
+ public static String getCurrentMapping(final SvnVcs vcs, final File file) {
try {
- final SVNStatus status = statusClient.doStatus(file, false);
+ final SVNStatus status = vcs.getFactory(file).createStatusClient().doStatus(file, false);
return status == null ? null : status.getChangelistName();
}
catch (SVNException e) {
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfigurable.form b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfigurable.form
index e4f0e7c8ae7e..55f7512fbb81 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfigurable.form
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfigurable.form
@@ -18,7 +18,7 @@
<properties/>
<border type="none"/>
<children>
- <grid id="2ae3a" layout-manager="GridLayoutManager" row-count="6" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <grid id="2ae3a" layout-manager="GridLayoutManager" row-count="5" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<tabbedpane title="General"/>
@@ -29,7 +29,7 @@
<grid id="a4729" layout-manager="GridLayoutManager" row-count="3" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
- <grid row="3" column="0" row-span="1" col-span="3" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+ <grid row="2" column="0" row-span="1" col-span="3" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
@@ -87,7 +87,7 @@
</grid>
<component id="df054" class="javax.swing.JCheckBox" binding="myUseDefaultCheckBox">
<constraints>
- <grid row="2" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ <grid row="1" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="org/jetbrains/idea/svn/SvnBundle" key="checkbox.configure.use.system.default.configuration.directory"/>
@@ -96,7 +96,7 @@
<grid id="137aa" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
- <grid row="5" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+ <grid row="4" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
@@ -123,36 +123,29 @@
</grid>
<hspacer id="e8f24">
<constraints>
- <grid row="5" column="2" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+ <grid row="4" column="2" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
</hspacer>
<vspacer id="aa6b2">
<constraints>
- <grid row="4" column="0" row-span="1" col-span="2" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
+ <grid row="3" column="0" row-span="1" col-span="2" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
- <component id="300b5" class="javax.swing.JLabel">
- <constraints>
- <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
- </constraints>
- <properties>
- <text value="Subversion 1.7 Acceleration"/>
- </properties>
- </component>
<grid id="12735" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
- <grid row="1" column="0" row-span="1" col-span="3" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+ <grid row="0" column="0" row-span="1" col-span="3" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="3ecd1" class="com.intellij.ui.components.JBCheckBox" binding="myWithCommandLineClient">
<constraints>
- <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="2" use-parent-layout="false"/>
+ <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
- <text value="with command line client:"/>
+ <margin top="2" left="3" bottom="2" right="3"/>
+ <text value="Use command line client:"/>
</properties>
</component>
<component id="44a8" class="com.intellij.openapi.ui.TextFieldWithBrowseButton" binding="myCommandLineClient">
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnContentRevision.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnContentRevision.java
index 38c099ba4136..cff64beea8b2 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnContentRevision.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnContentRevision.java
@@ -31,6 +31,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.tmatesoft.svn.core.wc.SVNRevision;
import org.tmatesoft.svn.core.wc.SVNStatus;
+import org.tmatesoft.svn.core.wc2.SvnTarget;
import java.io.File;
import java.io.IOException;
@@ -113,7 +114,8 @@ public class SvnContentRevision implements ContentRevision, MarkerVcsContentRevi
if (lock.exists()) {
throw new VcsException("Can not access file base revision contents: administrative area is locked");
}
- return SvnUtil.getFileContents(myVcs, file.getPath(), false, myUseBaseRevision ? SVNRevision.BASE : myRevision, SVNRevision.UNDEFINED);
+ return SvnUtil.getFileContents(myVcs, SvnTarget.fromFile(file), myUseBaseRevision ? SVNRevision.BASE : myRevision,
+ SVNRevision.UNDEFINED);
}
@NotNull
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnDiffProvider.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnDiffProvider.java
index 2a8a00aa1ae6..813d41c48e24 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnDiffProvider.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnDiffProvider.java
@@ -17,6 +17,7 @@ package org.jetbrains.idea.svn;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.vcs.FilePath;
+import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.actions.VcsContextFactory;
import com.intellij.openapi.vcs.changes.ContentRevision;
import com.intellij.openapi.vcs.diff.DiffMixin;
@@ -26,8 +27,10 @@ import com.intellij.openapi.vcs.history.VcsRevisionDescription;
import com.intellij.openapi.vcs.history.VcsRevisionDescriptionImpl;
import com.intellij.openapi.vcs.history.VcsRevisionNumber;
import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.idea.svn.commandLine.SvnCommandLineStatusClient;
import org.jetbrains.idea.svn.history.LatestExistentSearcher;
import org.tmatesoft.svn.core.SVNException;
+import org.tmatesoft.svn.core.SVNPropertyValue;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.wc.*;
@@ -43,19 +46,12 @@ public class SvnDiffProvider implements DiffProvider, DiffMixin {
}
public VcsRevisionNumber getCurrentRevision(VirtualFile file) {
- final SVNWCClient client = myVcs.createWCClient();
- try {
- final SVNInfo svnInfo = client.doInfo(new File(file.getPresentableUrl()), SVNRevision.UNDEFINED);
- if (svnInfo == null) return null;
- if (SVNRevision.UNDEFINED.equals(svnInfo.getCommittedRevision()) && svnInfo.getCopyFromRevision() != null) {
- return new SvnRevisionNumber(svnInfo.getCopyFromRevision());
- }
- return new SvnRevisionNumber(svnInfo.getRevision());
- }
- catch (SVNException e) {
- LOG.debug(e); // most likely the file is unversioned
- return null;
+ final SVNInfo svnInfo = myVcs.getInfo(new File(file.getPresentableUrl()));
+ if (svnInfo == null) return null;
+ if (SVNRevision.UNDEFINED.equals(svnInfo.getCommittedRevision()) && svnInfo.getCopyFromRevision() != null) {
+ return new SvnRevisionNumber(svnInfo.getCopyFromRevision());
}
+ return new SvnRevisionNumber(svnInfo.getRevision());
}
@Override
@@ -65,53 +61,36 @@ public class SvnDiffProvider implements DiffProvider, DiffMixin {
}
private VcsRevisionDescription getCurrentRevisionDescription(File path) {
- final SVNWCClient client = myVcs.createWCClient();
- try {
- final SVNInfo svnInfo = client.doInfo(path, SVNRevision.UNDEFINED);
-
- if (svnInfo.getCommittedRevision().equals(SVNRevision.UNDEFINED) && ! svnInfo.getCopyFromRevision().equals(SVNRevision.UNDEFINED) &&
+ final SVNInfo svnInfo = myVcs.getInfo(path);
+ if (svnInfo == null) {
+ return null;
+ }
+
+ if (svnInfo.getCommittedRevision().equals(SVNRevision.UNDEFINED) && !svnInfo.getCopyFromRevision().equals(SVNRevision.UNDEFINED) &&
svnInfo.getCopyFromURL() != null) {
- SVNURL copyUrl = svnInfo.getCopyFromURL();
- String localPath = myVcs.getSvnFileUrlMapping().getLocalPath(copyUrl.toString());
- if (localPath != null) {
- return getCurrentRevisionDescription(new File(localPath));
- }
+ SVNURL copyUrl = svnInfo.getCopyFromURL();
+ String localPath = myVcs.getSvnFileUrlMapping().getLocalPath(copyUrl.toString());
+ if (localPath != null) {
+ return getCurrentRevisionDescription(new File(localPath));
}
- final String message = getProperties(client, path);
+ }
+
+ try {
+ final String message = getCommitMessage(path);
return new VcsRevisionDescriptionImpl(new SvnRevisionNumber(svnInfo.getCommittedRevision()), svnInfo.getCommittedDate(),
svnInfo.getAuthor(), message);
}
- catch (SVNException e) {
+ catch (VcsException e) {
LOG.debug(e); // most likely the file is unversioned
return null;
}
}
- private String getProperties(SVNWCClient client, File path) throws SVNException {
- final String[] message = new String[1];
- client.doGetRevisionProperty(path, null, SVNRevision.BASE, new ISVNPropertyHandler() {
- @Override
- public void handleProperty(File path, SVNPropertyData property) throws SVNException {
- handle(property);
- }
-
- @Override
- public void handleProperty(SVNURL url, SVNPropertyData property) throws SVNException {
- handle(property);
- }
-
- @Override
- public void handleProperty(long revision, SVNPropertyData property) throws SVNException {
- handle(property);
- }
+ private String getCommitMessage(File path) throws VcsException {
+ SVNPropertyData property =
+ myVcs.getFactory(path).createPropertyClient().getProperty(path, COMMIT_MESSAGE, true, null, SVNRevision.BASE);
- private void handle(SVNPropertyData data) {
- if (COMMIT_MESSAGE.equals(data.getName())) {
- message[0] = data.getValue().getString();
- }
- }
- });
- return message[0];
+ return property != null ? SVNPropertyValue.getPropertyAsString(property.getValue()) : null;
}
private static ItemLatestState defaultResult() {
@@ -135,18 +114,45 @@ public class SvnDiffProvider implements DiffProvider, DiffMixin {
return SvnContentRevision.createBaseRevision(myVcs, filePath, svnRevision);
}
}
+
// not clear why we need it, with remote check..
- final SVNStatusClient client = myVcs.createStatusClient();
- try {
- final SVNStatus svnStatus = client.doStatus(new File(selectedFile.getPresentableUrl()), false, false);
- if (svnRevision.equals(svnStatus.getRevision())) {
+ SVNStatus svnStatus = getFileStatus(new File(selectedFile.getPresentableUrl()), false);
+ if (svnStatus != null && svnRevision.equals(svnStatus.getRevision())) {
return SvnContentRevision.createBaseRevision(myVcs, filePath, svnRevision);
- }
+ }
+ return SvnContentRevision.createRemote(myVcs, filePath, svnRevision);
+ }
+
+ private SVNStatus getFileStatus(File file, boolean remote) {
+ WorkingCopyFormat format = myVcs.getWorkingCopyFormat(file);
+
+ return WorkingCopyFormat.ONE_DOT_EIGHT.equals(format) ? getStatusCommandLine(file, remote) : getStatusWithSvnKit(file, remote);
+ }
+
+ private SVNStatus getStatusWithSvnKit(File file, boolean remote) {
+ SVNStatus result = null;
+
+ try {
+ result = myVcs.createStatusClient().doStatus(file, remote, false);
}
catch (SVNException e) {
LOG.debug(e); // most likely the file is unversioned
}
- return SvnContentRevision.createRemote(myVcs, filePath, svnRevision);
+
+ return result;
+ }
+
+ private SVNStatus getStatusCommandLine(File file, boolean remote) {
+ SVNStatus result = null;
+
+ try {
+ result = new SvnCommandLineStatusClient(myVcs.getProject()).doStatus(file, remote, false);
+ }
+ catch (SVNException e) {
+ LOG.debug(e);
+ }
+
+ return result;
}
public ItemLatestState getLastRevision(FilePath filePath) {
@@ -159,36 +165,29 @@ public class SvnDiffProvider implements DiffProvider, DiffMixin {
}
private ItemLatestState getLastRevision(final File file) {
- final SVNStatusClient client = myVcs.createStatusClient();
- try {
- final SVNStatus svnStatus = client.doStatus(file, true);
- if (svnStatus == null || itemExists(svnStatus) && SVNRevision.UNDEFINED.equals(svnStatus.getRemoteRevision())) {
- // IDEADEV-21785 (no idea why this can happen)
- final SVNInfo info = myVcs.createWCClient().doInfo(file, SVNRevision.HEAD);
- if (info == null || info.getURL() == null) {
- LOG.info("No SVN status returned for " + file.getPath());
- return defaultResult();
- }
- return createResult(info.getCommittedRevision(), true, false);
+ final SVNStatus svnStatus = getFileStatus(file, true);
+ if (svnStatus == null || itemExists(svnStatus) && SVNRevision.UNDEFINED.equals(svnStatus.getRemoteRevision())) {
+ // IDEADEV-21785 (no idea why this can happen)
+ final SVNInfo info = myVcs.getInfo(file, SVNRevision.HEAD);
+ if (info == null || info.getURL() == null) {
+ LOG.info("No SVN status returned for " + file.getPath());
+ return defaultResult();
}
- final boolean exists = itemExists(svnStatus);
- if (! exists) {
- // get really latest revision
- final LatestExistentSearcher searcher = new LatestExistentSearcher(myVcs, svnStatus.getURL());
- final long revision = searcher.getDeletionRevision();
+ return createResult(info.getCommittedRevision(), true, false);
+ }
+ final boolean exists = itemExists(svnStatus);
+ if (! exists) {
+ // get really latest revision
+ final LatestExistentSearcher searcher = new LatestExistentSearcher(myVcs, svnStatus.getURL());
+ final long revision = searcher.getDeletionRevision();
- return createResult(SVNRevision.create(revision), exists, false);
- }
- final SVNRevision remoteRevision = svnStatus.getRemoteRevision();
- if (remoteRevision != null) {
- return createResult(remoteRevision, exists, false);
- }
- return createResult(svnStatus.getRevision(), exists, false);
+ return createResult(SVNRevision.create(revision), exists, false);
}
- catch (SVNException e) {
- LOG.debug(e); // most likely the file is unversioned
- return defaultResult();
+ final SVNRevision remoteRevision = svnStatus.getRemoteRevision();
+ if (remoteRevision != null) {
+ return createResult(remoteRevision, exists, false);
}
+ return createResult(svnStatus.getRevision(), exists, false);
}
private boolean itemExists(SVNStatus svnStatus) {
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFileSystemListener.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFileSystemListener.java
index 062c412f2336..da1adc60327c 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFileSystemListener.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFileSystemListener.java
@@ -44,10 +44,7 @@ import com.intellij.util.containers.MultiMap;
import com.intellij.vcsUtil.ActionWithTempFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import org.tmatesoft.svn.core.SVNErrorCode;
-import org.tmatesoft.svn.core.SVNErrorMessage;
-import org.tmatesoft.svn.core.SVNException;
-import org.tmatesoft.svn.core.SVNNodeKind;
+import org.tmatesoft.svn.core.*;
import org.tmatesoft.svn.core.internal.wc.SVNFileUtil;
import org.tmatesoft.svn.core.wc.*;
@@ -160,10 +157,10 @@ public class SvnFileSystemListener extends CommandAdapter implements LocalFileOp
}
private class UUIDHelper {
- private final SVNWCClient myWcClient;
+ private final SvnVcs myVcs;
private UUIDHelper(final SvnVcs vcs) {
- myWcClient = vcs.createWCClient();
+ myVcs = vcs;
}
/**
@@ -175,7 +172,7 @@ public class SvnFileSystemListener extends CommandAdapter implements LocalFileOp
final SVNInfo info1 = new RepeatSvnActionThroughBusy() {
@Override
protected void executeImpl() throws SVNException {
- myT = myWcClient.doInfo(new File(dir.getPath()), SVNRevision.UNDEFINED);
+ myT = myVcs.getInfo(new File(dir.getPath()));
}
}.compute();
if (info1 == null || info1.getRepositoryUUID() == null) {
@@ -244,10 +241,11 @@ public class SvnFileSystemListener extends CommandAdapter implements LocalFileOp
long srcTime = src.lastModified();
try {
final boolean isUndo = isUndo(vcs);
- final String list = isUndo ? null : SvnChangelistListener.getCurrentMapping(vcs.getProject(), src);
+ final String list = isUndo ? null : SvnChangelistListener.getCurrentMapping(vcs, src);
- final boolean is17 = SvnUtil.is17CopyPart(src);
- if (is17) {
+ WorkingCopyFormat format = vcs.getWorkingCopyFormat(src);
+ final boolean is17OrLater = WorkingCopyFormat.ONE_DOT_EIGHT.equals(format) || WorkingCopyFormat.ONE_DOT_SEVEN.equals(format);
+ if (is17OrLater) {
SVNStatus srcStatus = getFileStatus(vcs, src);
final File toDir = dst.getParentFile();
SVNStatus dstStatus = getFileStatus(vcs, toDir);
@@ -283,29 +281,18 @@ public class SvnFileSystemListener extends CommandAdapter implements LocalFileOp
ourStatusesForUndoMove.add(SVNStatusType.STATUS_ADDED);
}
- private boolean for17move(SvnVcs vcs, final File src, final File dst, boolean undo, SVNStatus srcStatus) throws SVNException {
+ private boolean for17move(final SvnVcs vcs, final File src, final File dst, boolean undo, SVNStatus srcStatus) throws SVNException {
if (srcStatus != null && srcStatus.getCopyFromURL() == null) {
undo = false;
}
if (undo) {
myUndoingMove = true;
- final SVNWCClient wcClient = vcs.createWCClient();
- new RepeatSvnActionThroughBusy() {
- @Override
- protected void executeImpl() throws SVNException {
- wcClient.doRevert(dst, true);
- }
- }.execute();
+ createRevertAction(vcs, dst, true).execute();
copyUnversionedMembersOfDirectory(src, dst);
if (srcStatus == null || SvnVcs.svnStatusIsUnversioned(srcStatus)) {
FileUtil.delete(src);
} else {
- new RepeatSvnActionThroughBusy() {
- @Override
- protected void executeImpl() throws SVNException {
- wcClient.doRevert(src, true);
- }
- }.execute();
+ createRevertAction(vcs, src, true).execute();
}
restoreFromUndoStorage(dst);
} else {
@@ -317,15 +304,9 @@ public class SvnFileSystemListener extends CommandAdapter implements LocalFileOp
copyFileOrDir(src, dst);
}
catch (IOException e) {
- throw new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_ERROR), e);
+ throw new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_ERROR, e), e);
}
- final SVNWCClient wcClient = vcs.createWCClient();
- new RepeatSvnActionThroughBusy() {
- @Override
- protected void executeImpl() throws SVNException {
- wcClient.doDelete(src, true, false);
- }
- }.execute();
+ createDeleteAction(vcs, src, true).execute();
return false;
}
moveFileWithSvn(vcs, src, dst);
@@ -333,13 +314,16 @@ public class SvnFileSystemListener extends CommandAdapter implements LocalFileOp
return false;
}
- public static void moveFileWithSvn(SvnVcs vcs, File src, final File dst) throws SVNException {
- final SVNCopyClient copyClient = vcs.createCopyClient();
- final SVNCopySource svnCopySource = new SVNCopySource(SVNRevision.UNDEFINED, SVNRevision.WORKING, src);
+ public static void moveFileWithSvn(final SvnVcs vcs, final File src, final File dst) throws SVNException {
new RepeatSvnActionThroughBusy() {
@Override
protected void executeImpl() throws SVNException {
- copyClient.doCopy(new SVNCopySource[]{svnCopySource}, dst, true, false, true);
+ try {
+ vcs.getFactory(src).createCopyMoveClient().copy(src, dst, false, true);
+ }
+ catch (VcsException e) {
+ wrapAndThrow(e);
+ }
}
}.execute();
}
@@ -357,7 +341,7 @@ public class SvnFileSystemListener extends CommandAdapter implements LocalFileOp
copyFileOrDir(src, dst);
}
catch (IOException e) {
- exc[0] = new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_ERROR), e);
+ exc[0] = new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_ERROR, e), e);
return false;
}
}
@@ -464,7 +448,7 @@ public class SvnFileSystemListener extends CommandAdapter implements LocalFileOp
* deleted: do nothing, return true (strange)
*/
public boolean delete(VirtualFile file) throws IOException {
- SvnVcs vcs = getVCS(file);
+ final SvnVcs vcs = getVCS(file);
if (vcs != null && SvnUtil.isAdminDirectory(file)) {
return true;
}
@@ -476,12 +460,8 @@ public class SvnFileSystemListener extends CommandAdapter implements LocalFileOp
if (! SvnUtil.isSvnVersioned(vcs.getProject(), ioFile.getParentFile())) {
return false;
}
- try {
- if (SVNWCUtil.isWorkingCopyRoot(ioFile)) {
- return false;
- }
- } catch (SVNException e) {
- //
+ if (SvnUtil.isWorkingCopyRoot(ioFile)) {
+ return false;
}
SVNStatus status = getFileStatus(vcs, ioFile);
@@ -507,13 +487,7 @@ public class SvnFileSystemListener extends CommandAdapter implements LocalFileOp
}
if (SvnVcs.svnStatusIs(status, SVNStatusType.STATUS_ADDED)) {
try {
- final SVNWCClient wcClient = vcs.createWCClient();
- new RepeatSvnActionThroughBusy() {
- @Override
- protected void executeImpl() throws SVNException {
- wcClient.doRevert(ioFile, false);
- }
- }.execute();
+ createRevertAction(vcs, ioFile, false).execute();
}
catch (SVNException e) {
// ignore
@@ -529,6 +503,41 @@ public class SvnFileSystemListener extends CommandAdapter implements LocalFileOp
}
}
+ @NotNull
+ private RepeatSvnActionThroughBusy createRevertAction(@NotNull final SvnVcs vcs, @NotNull final File file, final boolean recursive) {
+ return new RepeatSvnActionThroughBusy() {
+ @Override
+ protected void executeImpl() throws SVNException {
+ try {
+ vcs.getFactory(file).createRevertClient().revert(new File[]{file}, SVNDepth.fromRecurse(recursive), null);
+ }
+ catch (VcsException e) {
+ wrapAndThrow(e);
+ }
+ }
+ };
+ }
+
+ @NotNull
+ private RepeatSvnActionThroughBusy createDeleteAction(@NotNull final SvnVcs vcs, @NotNull final File file, final boolean force) {
+ return new RepeatSvnActionThroughBusy() {
+ @Override
+ protected void executeImpl() throws SVNException {
+ try {
+ vcs.getFactory(file).createDeleteClient().delete(file, force);
+ }
+ catch (VcsException e) {
+ wrapAndThrow(e);
+ }
+ }
+ };
+ }
+
+ private static void wrapAndThrow(VcsException e) throws SVNException {
+ // TODO: probably we should wrap into new exception only if e.getCause is not SVNException
+ throw new SVNException(SVNErrorMessage.create(SVNErrorCode.FS_GENERAL, e), e);
+ }
+
private boolean isAboveSourceOfCopyOrMove(final Project p, File ioFile) {
for (MovedFileInfo file : myMovedFiles) {
if (FileUtil.isAncestor(ioFile, file.mySrc, false)) return true;
@@ -583,7 +592,6 @@ public class SvnFileSystemListener extends CommandAdapter implements LocalFileOp
if (! SvnUtil.isSvnVersioned(vcs.getProject(), ioDir) && ! pendingAdd) {
return false;
}
- final SVNWCClient wcClient = vcs.createWCClient();
final File targetFile = new File(ioDir, name);
SVNStatus status = getFileStatus(vcs, targetFile);
@@ -603,12 +611,7 @@ public class SvnFileSystemListener extends CommandAdapter implements LocalFileOp
}
try {
if (isUndo(vcs)) {
- new RepeatSvnActionThroughBusy() {
- @Override
- protected void executeImpl() throws SVNException {
- wcClient.doRevert(targetFile, false);
- }
- }.execute();
+ createRevertAction(vcs, targetFile, false).execute();
return true;
}
myAddedFiles.putValue(vcs.getProject(), new AddedFileInfo(dir, name, null, recursive));
@@ -759,8 +762,6 @@ public class SvnFileSystemListener extends CommandAdapter implements LocalFileOp
return new Runnable() {
@Override
public void run() {
- final SVNWCClient wcClient = vcs.createWCClient();
- final SVNCopyClient copyClient = vcs.createCopyClient();
for(VirtualFile file: filesToProcess) {
final File ioFile = new File(file.getPath());
try {
@@ -771,11 +772,15 @@ public class SvnFileSystemListener extends CommandAdapter implements LocalFileOp
protected void executeInternal() throws VcsException {
try {
// not recursive
- final SVNCopySource[] copySource = {new SVNCopySource(SVNRevision.WORKING, SVNRevision.WORKING, copyFrom)};
new RepeatSvnActionThroughBusy() {
@Override
protected void executeImpl() throws SVNException {
- copyClient.doCopy(copySource, ioFile, false, true, true);
+ try {
+ vcs.getFactory(copyFrom).createCopyMoveClient().copy(copyFrom, ioFile, true, false);
+ }
+ catch (VcsException e) {
+ wrapAndThrow(e);
+ }
}
}.execute();
}
@@ -793,7 +798,12 @@ public class SvnFileSystemListener extends CommandAdapter implements LocalFileOp
new RepeatSvnActionThroughBusy() {
@Override
protected void executeImpl() throws SVNException {
- wcClient.doAdd(ioFile, true, false, false, true);
+ try {
+ vcs.getFactory(ioFile).createAddClient().add(ioFile, null, false, false, true, null);
+ }
+ catch (VcsException e) {
+ wrapAndThrow(e);
+ }
}
}.execute();
}
@@ -915,17 +925,11 @@ public class SvnFileSystemListener extends CommandAdapter implements LocalFileOp
final List<VcsException> exceptions) {
return new Runnable() {
public void run() {
- final SVNWCClient wcClient = vcs.createWCClient();
for(FilePath file: filesToProcess) {
VirtualFile vFile = file.getVirtualFile(); // for deleted directories
final File ioFile = new File(file.getPath());
try {
- new RepeatSvnActionThroughBusy() {
- @Override
- protected void executeImpl() throws SVNException {
- wcClient.doDelete(ioFile, true, false);
- }
- }.execute();
+ createDeleteAction(vcs, ioFile, true).execute();
if (vFile != null && vFile.isValid() && vFile.isDirectory()) {
vFile.refresh(true, true);
VcsDirtyScopeManager.getInstance(project).dirDirtyRecursively(vFile);
@@ -978,18 +982,15 @@ public class SvnFileSystemListener extends CommandAdapter implements LocalFileOp
private void fillDeletedFiles(Project project, List<Pair<FilePath, WorkingCopyFormat>> deletedFiles, Collection<FilePath> deleteAnyway)
throws SVNException {
final SvnVcs vcs = SvnVcs.getInstance(project);
- final SVNStatusClient sc = vcs.createStatusClient();
final Collection<File> files = myDeletedFiles.remove(project);
for (final File file : files) {
- boolean isAdded = false;
- final SVNStatus status;
- status = new RepeatSvnActionThroughBusy() {
- @Override
- protected void executeImpl() throws SVNException {
- myT = sc.doStatus(file, false);
- }
- }.compute();
- isAdded = SVNStatusType.STATUS_ADDED.equals(status.getNodeStatus());
+ final SVNStatus status = new RepeatSvnActionThroughBusy() {
+ @Override
+ protected void executeImpl() throws SVNException {
+ myT = vcs.getFactory(file).createStatusClient().doStatus(file, false);
+ }
+ }.compute();
+ boolean isAdded = SVNStatusType.STATUS_ADDED.equals(status.getNodeStatus());
final FilePath filePath = VcsContextFactory.SERVICE.getInstance().createFilePathOn(file);
if (isAdded) {
deleteAnyway.add(filePath);
@@ -1034,18 +1035,12 @@ public class SvnFileSystemListener extends CommandAdapter implements LocalFileOp
}
@Nullable
- private static SVNStatus getFileStatus(SvnVcs vcs, File file) {
- SVNStatusClient stClient = vcs.createStatusClient();
- return getFileStatus(file, stClient);
- }
-
- @Nullable
- private static SVNStatus getFileStatus(final File file, final SVNStatusClient stClient) {
+ private static SVNStatus getFileStatus(@NotNull final SvnVcs vcs, @NotNull final File file) {
try {
return new RepeatSvnActionThroughBusy() {
@Override
protected void executeImpl() throws SVNException {
- myT = stClient.doStatus(file, false);
+ myT = vcs.getFactory(file).createStatusClient().doStatus(file, false);
}
}.compute();
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFileUrlMappingImpl.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFileUrlMappingImpl.java
index 46545c43a4cc..68e7c07848c2 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFileUrlMappingImpl.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFileUrlMappingImpl.java
@@ -312,8 +312,8 @@ public class SvnFileUrlMappingImpl implements SvnFileUrlMapping, PersistentState
LOG.info("Error: cannot find repository URL for versioned folder: " + foundRoot.getFile().getPath());
} else {
myRepositoryRoots.register(repoRoot);
- myTopRoots.add(new RootUrlInfo(repoRoot, foundRoot.getInfo().getURL(),
- SvnFormatSelector.getWorkingCopyFormat(new File(foundRoot.getFile().getPath())), foundRoot.getFile(), vcsRoot));
+ myTopRoots.add(new RootUrlInfo(repoRoot, foundRoot.getInfo().getURL(), SvnFormatSelector.findRootAndGetFormat(
+ new File(foundRoot.getFile().getPath())), foundRoot.getFile(), vcsRoot));
}
}
}
@@ -541,8 +541,9 @@ public class SvnFileUrlMappingImpl implements SvnFileUrlMapping, PersistentState
final SVNInfo svnInfo = vcs.getInfo(copyRoot);
if ((svnInfo == null) || (svnInfo.getRepositoryRootURL() == null)) continue;
- final RootUrlInfo info = new RootUrlInfo(svnInfo.getRepositoryRootURL(), svnInfo.getURL(),
- SvnFormatSelector.getWorkingCopyFormat(svnInfo.getFile()), copyRoot, vcsRoot);
+ final RootUrlInfo info =
+ new RootUrlInfo(svnInfo.getRepositoryRootURL(), svnInfo.getURL(), SvnFormatSelector.findRootAndGetFormat(svnInfo.getFile()),
+ copyRoot, vcsRoot);
mapping.add(info);
}
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFormatSelector.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFormatSelector.java
index 94d21dbbbd9d..77783badc2f8 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFormatSelector.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnFormatSelector.java
@@ -16,6 +16,7 @@
package org.jetbrains.idea.svn;
import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Ref;
import com.intellij.util.WaitForProgressToShow;
@@ -37,6 +38,9 @@ import java.util.Collections;
import java.util.Iterator;
public class SvnFormatSelector implements ISVNAdminAreaFactorySelector {
+
+ private static final Logger LOG = Logger.getInstance("#org.jetbrains.idea.svn.SvnFormatSelector");
+
public Collection getEnabledFactories(File path, Collection factories, boolean writeAccess) throws SVNException {
if (ApplicationManager.getApplication().isUnitTestMode()) {
return factories;
@@ -145,7 +149,19 @@ public class SvnFormatSelector implements ISVNAdminAreaFactorySelector {
return newMode[0];
}
+ public static WorkingCopyFormat findRootAndGetFormat(final File path) {
+ File root = SvnUtil.getWorkingCopyRootNew(path);
+
+ return root != null ? getWorkingCopyFormat(root) : WorkingCopyFormat.UNKNOWN;
+ }
+
public static WorkingCopyFormat getWorkingCopyFormat(final File path) {
+ WorkingCopyFormat format = SvnUtil.getFormat(path);
+
+ return WorkingCopyFormat.UNKNOWN.equals(format) ? detectWithSvnKit(path) : format;
+ }
+
+ private static WorkingCopyFormat detectWithSvnKit(File path) {
try {
final SvnWcGeneration svnWcGeneration = SvnOperationFactory.detectWcGeneration(path, true);
if (SvnWcGeneration.V17.equals(svnWcGeneration)) return WorkingCopyFormat.ONE_DOT_SEVEN;
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnProxies.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnProxies.java
index 97b87efaa7f9..fcac3966c2d6 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnProxies.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnProxies.java
@@ -29,6 +29,7 @@ import java.util.concurrent.atomic.AtomicReference;
* Date: 10/19/12
* Time: 4:22 PM
*/
+// TODO: Likely to be removed (together with SvnAbstractWriteOperationLocks).
public class SvnProxies {
private final SvnAbstractWriteOperationLocks myLocks;
private final AtomicReference<LearningProxy<SVNChangelistClientI, SVNException>> myChangelist;
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnRecursiveStatusWalker.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnRecursiveStatusWalker.java
index 4a49dc16a153..8b518199f5be 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnRecursiveStatusWalker.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnRecursiveStatusWalker.java
@@ -47,13 +47,15 @@ import java.util.LinkedList;
public class SvnRecursiveStatusWalker {
private static final Logger LOG = Logger.getInstance("#org.jetbrains.idea.svn.SvnRecursiveStatusWalker");
private final StatusWalkerPartner myPartner;
+ private final SvnVcs myVcs;
private final Project myProject;
private final StatusReceiver myReceiver;
private final LinkedList<MyItem> myQueue;
private final MyHandler myHandler;
- public SvnRecursiveStatusWalker(final Project project, final StatusReceiver receiver, final StatusWalkerPartner partner) {
- myProject = project;
+ public SvnRecursiveStatusWalker(final SvnVcs vcs, final StatusReceiver receiver, final StatusWalkerPartner partner) {
+ myVcs = vcs;
+ myProject = vcs.getProject();
myReceiver = receiver;
myPartner = partner;
myQueue = new LinkedList<MyItem>();
@@ -61,7 +63,7 @@ public class SvnRecursiveStatusWalker {
}
public void go(final FilePath rootPath, final SVNDepth depth) throws SVNException {
- final MyItem root = new MyItem(myProject, rootPath, depth, myPartner.createStatusClient(), false);
+ final MyItem root = new MyItem(myVcs, rootPath, depth, myPartner.createStatusClient(), false);
myQueue.add(root);
while (! myQueue.isEmpty()) {
@@ -83,7 +85,7 @@ public class SvnRecursiveStatusWalker {
}
} else {
try {
- final SVNStatus status = item.getClient().doStatus(ioFile, false, false);
+ final SVNStatus status = item.getClient(ioFile).doStatus(ioFile, false, false);
myReceiver.process(path, status);
} catch (SVNException e) {
handleStatusException(item, path, e);
@@ -115,18 +117,20 @@ public class SvnRecursiveStatusWalker {
private final Project myProject;
private final FilePath myPath;
private final SVNDepth myDepth;
- private final SVNStatusClient myClient;
private final SvnStatusClientI mySvnClient;
+ private final SvnStatusClientI myCommandLineClient;
private final boolean myIsInnerCopyRoot;
private final SvnConfiguration myConfiguration17;
+ private final SvnVcs myVcs;
- private MyItem(Project project, FilePath path, SVNDepth depth, SVNStatusClient client, boolean isInnerCopyRoot) {
- myProject = project;
+ private MyItem(SvnVcs vcs, FilePath path, SVNDepth depth, SVNStatusClient client, boolean isInnerCopyRoot) {
+ myVcs = vcs;
+ myProject = vcs.getProject();
myConfiguration17 = SvnConfiguration.getInstance(myProject);
myPath = path;
myDepth = depth;
- myClient = client;
mySvnClient = new SvnkitSvnStatusClient(client);
+ myCommandLineClient = new SvnCommandLineStatusClient(myProject);
myIsInnerCopyRoot = isInnerCopyRoot;
}
@@ -138,20 +142,20 @@ public class SvnRecursiveStatusWalker {
return myDepth;
}
- public SvnStatusClientI getClient() {
- return mySvnClient;
- }
-
public SvnStatusClientI getClient(final File file) {
- if (! SVNDepth.INFINITY.equals(myDepth)) {
- return mySvnClient;
+ WorkingCopyFormat format = myVcs.getWorkingCopyFormat(file);
+
+ if (format == WorkingCopyFormat.ONE_DOT_EIGHT) {
+ return myCommandLineClient;
}
+
// check format
if (CheckJavaHL.isPresent() && SvnConfiguration.UseAcceleration.javaHL.equals(myConfiguration17.myUseAcceleration) &&
Svn17Detector.is17(myProject, file)) {
return new JavaHLSvnStatusClient(myProject);
- } else if (SvnConfiguration.UseAcceleration.commandLine.equals(myConfiguration17.myUseAcceleration) && Svn17Detector.is17(myProject, file)) {
- return new SvnCommandLineStatusClient(myProject);
+ } else if (SvnConfiguration.UseAcceleration.commandLine.equals(myConfiguration17.myUseAcceleration)) {
+ // apply command line disregarding working copy format
+ return myCommandLineClient;
}
return mySvnClient;
}
@@ -186,7 +190,7 @@ public class SvnRecursiveStatusWalker {
return true;
}
if (file.isDirectory() && new File(file, SVNFileUtil.getAdminDirectoryName()).exists()) {
- final MyItem childItem = new MyItem(myProject, path, newDepth, myPartner.createStatusClient(), true);
+ final MyItem childItem = new MyItem(myVcs, path, newDepth, myPartner.createStatusClient(), true);
myQueue.add(childItem);
} else if (vf != null) {
myReceiver.processUnversioned(vf);
@@ -228,12 +232,13 @@ public class SvnRecursiveStatusWalker {
}
public void checkIfCopyRootWasReported(@Nullable final SVNStatus ioFileStatus, final File ioFile) {
- if (! myMetCurrentItem && FileUtil.filesEqual(ioFile, myCurrentItem.getPath().getIOFile())) {
+ File itemFile = myCurrentItem.getPath().getIOFile();
+ if (! myMetCurrentItem && FileUtil.filesEqual(ioFile, itemFile)) {
myMetCurrentItem = true;
SVNStatus statusInner;
try {
statusInner = ioFileStatus != null ? ioFileStatus :
- myCurrentItem.getClient().doStatus(myCurrentItem.getPath().getIOFile(), false);
+ myCurrentItem.getClient(itemFile).doStatus(itemFile, false);
}
catch (SVNException e) {
LOG.info(e);
@@ -294,7 +299,7 @@ public class SvnRecursiveStatusWalker {
//myReceiver.processUnversioned(vFile);
//processRecursively(vFile, myCurrentItem.getDepth());
} else {
- final MyItem childItem = new MyItem(myProject, new FilePathImpl(vFile), SVNDepth.INFINITY,
+ final MyItem childItem = new MyItem(myVcs, new FilePathImpl(vFile), SVNDepth.INFINITY,
myPartner.createStatusClient(), true);
myQueue.add(childItem);
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnTestWriteOperationLocks.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnTestWriteOperationLocks.java
index 853e995ca219..efea2f93de08 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnTestWriteOperationLocks.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnTestWriteOperationLocks.java
@@ -25,6 +25,7 @@ import java.io.File;
* Date: 10/23/12
* Time: 2:31 PM
*/
+// TODO: Used only in SvnLockingTest which is not required anymore. Likely to be removed.
public class SvnTestWriteOperationLocks extends SvnAbstractWriteOperationLocks {
private final WorkingCopy myWorkingCopy;
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnUtil.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnUtil.java
index 0c049ac4671d..7cd6bdd91d3f 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnUtil.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnUtil.java
@@ -30,21 +30,19 @@ import com.intellij.openapi.vcs.AbstractVcsHelper;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.changes.Change;
import com.intellij.openapi.vcs.changes.ChangesUtil;
-import com.intellij.openapi.vcs.impl.ContentRevisionCache;
-import com.intellij.openapi.vfs.LocalFileSystem;
-import com.intellij.openapi.vfs.VfsUtilCore;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.openapi.vfs.VirtualFileManager;
+import com.intellij.openapi.vfs.*;
import com.intellij.openapi.wm.impl.status.StatusBarUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.containers.Convertor;
import com.intellij.util.containers.MultiMap;
-import com.intellij.vcsUtil.VcsUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.api.ClientFactory;
import org.jetbrains.idea.svn.branchConfig.SvnBranchConfigurationNew;
import org.jetbrains.idea.svn.dialogs.LockDialog;
+import org.tmatesoft.sqljet.core.SqlJetException;
+import org.tmatesoft.sqljet.core.table.SqlJetDb;
import org.tmatesoft.svn.core.*;
import org.tmatesoft.svn.core.internal.util.SVNPathUtil;
import org.tmatesoft.svn.core.internal.wc.SVNFileUtil;
@@ -53,14 +51,14 @@ import org.tmatesoft.svn.core.io.SVNCapability;
import org.tmatesoft.svn.core.io.SVNRepository;
import org.tmatesoft.svn.core.wc.*;
import org.tmatesoft.svn.core.wc2.SvnOperationFactory;
+import org.tmatesoft.svn.core.wc2.SvnTarget;
-import java.io.ByteArrayOutputStream;
import java.io.File;
-import java.io.IOException;
-import java.io.OutputStream;
import java.util.*;
public class SvnUtil {
+ // TODO: ASP.NET hack behavior should be supported - http://svn.apache.org/repos/asf/subversion/trunk/notes/asp-dot-net-hack.txt
+ // TODO: Remember this when moving out SVNKit classes.
@NonNls public static final String SVN_ADMIN_DIR_NAME = SVNFileUtil.getAdminDirectoryName();
@NonNls public static final String ENTRIES_FILE_NAME = "entries";
@NonNls public static final String WC_DB_FILE_NAME = "wc.db";
@@ -71,13 +69,9 @@ public class SvnUtil {
private SvnUtil() { }
public static boolean isSvnVersioned(final Project project, File parent) {
- try {
- final SVNInfo info = SvnVcs.getInstance(project).createWCClient().doInfo(parent, SVNRevision.UNDEFINED);
- return info != null;
- }
- catch (SVNException e) {
- return false;
- }
+ final SVNInfo info = SvnVcs.getInstance(project).getInfo(parent);
+
+ return info != null;
}
public static Collection<VirtualFile> crawlWCRoots(final Project project, File path, SvnWCRootCrawler callback, ProgressIndicator progress) {
@@ -123,15 +117,8 @@ public class SvnUtil {
@Nullable
public static String getExactLocation(final SvnVcs vcs, File path) {
- try {
- SVNWCClient wcClient = vcs.createWCClient();
- SVNInfo info = wcClient.doInfo(path, SVNRevision.UNDEFINED);
- if (info != null && info.getURL() != null) {
- return info.getURL().toString();
- }
- }
- catch (SVNException ignored) { }
- return null;
+ SVNInfo info = vcs.getInfo(path);
+ return info != null && info.getURL() != null ? info.getURL().toString() : null;
}
public static Map<String, File> getLocationInfoForModule(final SvnVcs vcs, File path, ProgressIndicator progress) {
@@ -288,7 +275,9 @@ public class SvnUtil {
}
public static String formatRepresentation(final WorkingCopyFormat format) {
- if (WorkingCopyFormat.ONE_DOT_SEVEN.equals(format)) {
+ if (WorkingCopyFormat.ONE_DOT_EIGHT.equals(format)) {
+ return SvnBundle.message("dialog.show.svn.map.table.version18.text");
+ } else if (WorkingCopyFormat.ONE_DOT_SEVEN.equals(format)) {
return SvnBundle.message("dialog.show.svn.map.table.version17.text");
} else if (WorkingCopyFormat.ONE_DOT_SIX.equals(format)) {
return SvnBundle.message("dialog.show.svn.map.table.version16.text");
@@ -352,6 +341,54 @@ public class SvnUtil {
return result;
}
+ /**
+ * Gets working copy internal format. Works for 1.7 and 1.8.
+ *
+ * @param path
+ * @return
+ */
+ public static WorkingCopyFormat getFormat(final File path) {
+ int format = 0;
+ File dbFile = resolveDatabase(path);
+
+ if (dbFile != null) {
+ SqlJetDb db = null;
+ try {
+ db = SqlJetDb.open(dbFile, false);
+ format = db.getOptions().getUserVersion();
+ }
+ catch (SqlJetException e) {
+ LOG.error(e);
+ } finally {
+ if (db != null) {
+ try {
+ db.close();
+ }
+ catch (SqlJetException e) {
+ LOG.error(e);
+ }
+ }
+ }
+ }
+
+ return WorkingCopyFormat.getInstance(format);
+ }
+
+ private static File resolveDatabase(final File path) {
+ File dbFile = getWcDb(path);
+ File result = null;
+
+ try {
+ if (dbFile.exists() && dbFile.isFile()) {
+ result = dbFile;
+ }
+ } catch (SecurityException e) {
+ LOG.error("Failed to access working copy database", e);
+ }
+
+ return result;
+ }
+
private static class LocationsCrawler implements SvnWCRootCrawler {
private final SvnVcs myVcs;
private final Map<String, File> myLocations;
@@ -371,15 +408,9 @@ public class SvnUtil {
oldText = progress.getText();
progress.setText(SvnBundle.message("progress.text.discovering.location", root.getAbsolutePath()));
}
- try {
- SVNWCClient wcClient = myVcs.createWCClient();
- SVNInfo info = wcClient.doInfo(root, SVNRevision.UNDEFINED);
- if (info != null && info.getURL() != null) {
- myLocations.put(info.getURL().toString(), info.getFile());
- }
- }
- catch (SVNException e) {
- //
+ SVNInfo info = myVcs.getInfo(root);
+ if (info != null && info.getURL() != null) {
+ myLocations.put(info.getURL().toString(), info.getFile());
}
if (progress != null) {
progress.setText(oldText);
@@ -389,20 +420,15 @@ public class SvnUtil {
@Nullable
public static String getRepositoryUUID(final SvnVcs vcs, final File file) {
- final SVNWCClient client = vcs.createWCClient();
- try {
- final SVNInfo info = client.doInfo(file, SVNRevision.UNDEFINED);
- return (info == null) ? null : info.getRepositoryUUID();
- } catch (SVNException e) {
- return null;
- }
+ final SVNInfo info = vcs.getInfo(file);
+ return info != null ? info.getRepositoryUUID() : null;
}
@Nullable
public static String getRepositoryUUID(final SvnVcs vcs, final SVNURL url) {
- final SVNWCClient client = vcs.createWCClient();
try {
- final SVNInfo info = client.doInfo(url, SVNRevision.UNDEFINED, SVNRevision.UNDEFINED);
+ final SVNInfo info = vcs.getInfo(url, SVNRevision.UNDEFINED);
+
return (info == null) ? null : info.getRepositoryUUID();
} catch (SVNException e) {
return null;
@@ -411,19 +437,14 @@ public class SvnUtil {
@Nullable
public static SVNURL getRepositoryRoot(final SvnVcs vcs, final File file) {
- final SVNWCClient client = vcs.createWCClient();
- try {
- final SVNInfo info = client.doInfo(file, SVNRevision.UNDEFINED);
- return (info == null) ? null : info.getRepositoryRootURL();
- } catch (SVNException e) {
- return null;
- }
+ final SVNInfo info = vcs.getInfo(file);
+ return info != null ? info.getRepositoryRootURL() : null;
}
@Nullable
public static SVNURL getRepositoryRoot(final SvnVcs vcs, final String url) {
try {
- return getRepositoryRoot(vcs, SVNURL.parseURIEncoded(url), true);
+ return getRepositoryRoot(vcs, SVNURL.parseURIEncoded(url));
}
catch (SVNException e) {
return null;
@@ -431,18 +452,14 @@ public class SvnUtil {
}
@Nullable
- public static SVNURL getRepositoryRoot(final SvnVcs vcs, final SVNURL url, boolean allowRemote) throws SVNException {
- final SVNWCClient client = vcs.createWCClient();
- SVNInfo info = client.doInfo(url, SVNRevision.UNDEFINED, SVNRevision.HEAD);
+ public static SVNURL getRepositoryRoot(final SvnVcs vcs, final SVNURL url) throws SVNException {
+ SVNInfo info = vcs.getInfo(url, SVNRevision.HEAD);
+
return (info == null) ? null : info.getRepositoryRootURL();
}
public static boolean isWorkingCopyRoot(final File file) {
- try {
- return SVNWCUtil.isWorkingCopyRoot(file);
- } catch (SVNException e) {
- return false;
- }
+ return FileUtil.filesEqual(file, getWorkingCopyRootNew(file));
}
@Nullable
@@ -548,17 +565,9 @@ public class SvnUtil {
}
public static SVNDepth getDepth(final SvnVcs vcs, final File file) {
- final SVNWCClient client = vcs.createWCClient();
- try {
- final SVNInfo svnInfo = client.doInfo(file, SVNRevision.UNDEFINED);
- if (svnInfo != null) {
- return svnInfo.getDepth();
- }
- }
- catch (SVNException e) {
- //
- }
- return SVNDepth.UNKNOWN;
+ SVNInfo info = vcs.getInfo(file);
+
+ return info != null && info.getDepth() != null ? info.getDepth() : SVNDepth.UNKNOWN;
}
public static boolean seemsLikeVersionedDir(final VirtualFile file) {
@@ -590,21 +599,17 @@ public class SvnUtil {
}
public static SVNURL getCommittedURL(final SvnVcs vcs, final File file) {
- final File root = getWorkingCopyRoot(file);
- if (root == null) return null;
- return getUrl(vcs, root);
+ final File root = getWorkingCopyRootNew(file);
+
+ return root == null ? null : getUrl(vcs, root);
}
@Nullable
public static SVNURL getUrl(final SvnVcs vcs, final File file) {
- try {
- final SVNInfo info = vcs.createWCClient().doInfo(file, SVNRevision.UNDEFINED);
- return info == null ? null : info.getURL(); // todo for moved items?
- }
- catch (SVNException e) {
- LOG.debug(e);
- return null;
- }
+ // todo for moved items?
+ final SVNInfo info = vcs.getInfo(file);
+
+ return info == null ? null : info.getURL();
}
public static boolean doesRepositorySupportMergeInfo(final SvnVcs vcs, final SVNURL url) {
@@ -648,17 +653,9 @@ public class SvnUtil {
@Nullable
public static File getWcCopyRootIf17(final File file, @Nullable final File upperBound) {
- File current = file;
- boolean wcDbFound = false;
- while (current != null) {
- File wcDb;
- if ((wcDb = getWcDb(current)).exists() && ! wcDb.isDirectory()) {
- wcDbFound = true;
- break;
- }
- current = current.getParentFile();
- }
- if (! wcDbFound) return null;
+ File current = getParentWithDb(file);
+ if (current == null) return null;
+
while (current != null) {
try {
final SvnWcGeneration svnWcGeneration = SvnOperationFactory.detectWcGeneration(current, false);
@@ -674,6 +671,40 @@ public class SvnUtil {
return null;
}
+ /**
+ * Utility method that deals also with 1.8 working copies.
+ * TODO: Should be renamed when all parts updated for 1.8.
+ *
+ * @param file
+ * @return
+ */
+ @Nullable
+ public static File getWorkingCopyRootNew(final File file) {
+ File current = getParentWithDb(file);
+ if (current == null) return getWorkingCopyRoot(file);
+
+ WorkingCopyFormat format = getFormat(current);
+
+ return WorkingCopyFormat.ONE_DOT_EIGHT.equals(format) || WorkingCopyFormat.ONE_DOT_SEVEN.equals(format)
+ ? current
+ : getWorkingCopyRoot(file);
+ }
+
+ private static File getParentWithDb(File file) {
+ File current = file;
+ boolean wcDbFound = false;
+ while (current != null) {
+ File wcDb;
+ if ((wcDb = getWcDb(current)).exists() && ! wcDb.isDirectory()) {
+ wcDbFound = true;
+ break;
+ }
+ current = current.getParentFile();
+ }
+ if (! wcDbFound) return null;
+ return current;
+ }
+
public static boolean is17CopyPart(final File file) {
try {
return SvnWcGeneration.V17.equals(SvnOperationFactory.detectWcGeneration(file, true));
@@ -703,44 +734,24 @@ public class SvnUtil {
return result;
}
- public static byte[] getFileContents(final SvnVcs vcs, final String path, final boolean isUrl, final SVNRevision revision,
- final SVNRevision pegRevision)
+ public static byte[] getFileContents(@NotNull final SvnVcs vcs,
+ @NotNull final SvnTarget target,
+ @Nullable final SVNRevision revision,
+ @Nullable final SVNRevision pegRevision)
throws VcsException {
- final int maxSize = VcsUtil.getMaxVcsLoadedFileSize();
- ByteArrayOutputStream buffer = new ByteArrayOutputStream() {
- @Override
- public synchronized void write(int b) {
- if (size() > maxSize) throw new FileTooBigRuntimeException();
- super.write(b);
- }
+ ClientFactory factory = target.isFile() ? vcs.getFactory(target.getFile()) : vcs.getFactory();
- @Override
- public synchronized void write(byte[] b, int off, int len) {
- if (size() > maxSize) throw new FileTooBigRuntimeException();
- super.write(b, off, len);
- }
+ return factory.createContentClient().getContent(target, revision, pegRevision);
+ }
- @Override
- public synchronized void writeTo(OutputStream out) throws IOException {
- if (size() > maxSize) throw new FileTooBigRuntimeException();
- super.writeTo(out);
- }
- };
- SVNWCClient wcClient = vcs.createWCClient();
+ public static SVNURL parseUrl(@NotNull String url) {
try {
- if (isUrl) {
- wcClient.doGetFileContents(SVNURL.parseURIEncoded(path), pegRevision, revision, true, buffer);
- } else {
- wcClient.doGetFileContents(new File(path), pegRevision, revision, true, buffer);
- }
- ContentRevisionCache.checkContentsSize(path, buffer.size());
- } catch (FileTooBigRuntimeException e) {
- ContentRevisionCache.checkContentsSize(path, buffer.size());
- } catch (SVNException e) {
- throw new VcsException(e);
+ return SVNURL.parseURIEncoded(url);
+ }
+ catch (SVNException e) {
+ IllegalArgumentException runtimeException = new IllegalArgumentException();
+ runtimeException.initCause(e);
+ throw runtimeException;
}
- return buffer.toByteArray();
}
-
- private static class FileTooBigRuntimeException extends RuntimeException {}
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnVcs.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnVcs.java
index 748fc86c694c..1a5a0f8b8af7 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnVcs.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnVcs.java
@@ -13,8 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-
package org.jetbrains.idea.svn;
import com.intellij.ide.FrameStateListener;
@@ -68,8 +66,12 @@ import org.jetbrains.idea.svn.actions.CleanupWorker;
import org.jetbrains.idea.svn.actions.ShowPropertiesDiffWithLocalAction;
import org.jetbrains.idea.svn.actions.SvnMergeProvider;
import org.jetbrains.idea.svn.annotate.SvnAnnotationProvider;
+import org.jetbrains.idea.svn.api.ClientFactory;
+import org.jetbrains.idea.svn.api.CmdClientFactory;
+import org.jetbrains.idea.svn.api.SvnKitClientFactory;
import org.jetbrains.idea.svn.checkin.SvnCheckinEnvironment;
import org.jetbrains.idea.svn.checkout.SvnCheckoutProvider;
+import org.jetbrains.idea.svn.commandLine.SvnCommandLineInfoClient;
import org.jetbrains.idea.svn.commandLine.SvnExecutableChecker;
import org.jetbrains.idea.svn.dialogs.SvnBranchPointsCalculator;
import org.jetbrains.idea.svn.dialogs.WCInfo;
@@ -79,6 +81,7 @@ import org.jetbrains.idea.svn.history.SvnCommittedChangesProvider;
import org.jetbrains.idea.svn.history.SvnHistoryProvider;
import org.jetbrains.idea.svn.lowLevel.PrimitivePool;
import org.jetbrains.idea.svn.networking.SSLProtocolExceptionParser;
+import org.jetbrains.idea.svn.portable.SvnWcClientI;
import org.jetbrains.idea.svn.rollback.SvnRollbackEnvironment;
import org.jetbrains.idea.svn.update.SvnIntegrateEnvironment;
import org.jetbrains.idea.svn.update.SvnUpdateEnvironment;
@@ -195,9 +198,10 @@ public class SvnVcs extends AbstractVcs<CommittedChangeList> {
};
private SvnCheckoutProvider myCheckoutProvider;
- public void checkCommandLineVersion() {
- myChecker.checkExecutableAndNotifyIfNeeded();
- }
+ private ClientFactory cmdClientFactory;
+ private ClientFactory svnKitClientFactory;
+
+ private final boolean myLogExceptions;
static {
System.setProperty("svnkit.log.native.calls", "true");
@@ -235,8 +239,8 @@ public class SvnVcs extends AbstractVcs<CommittedChangeList> {
public SvnVcs(final Project project, MessageBus bus, SvnConfiguration svnConfiguration, final SvnLoadedBrachesStorage storage) {
super(project, VCS_NAME);
+
myLoadedBranchesStorage = storage;
- LOG.debug("ct");
myRootsToWorkingCopies = new RootsToWorkingCopies(this);
myConfiguration = svnConfiguration;
myAuthNotifier = new SvnAuthenticationNotifier(this);
@@ -284,6 +288,9 @@ public class SvnVcs extends AbstractVcs<CommittedChangeList> {
// remove used some time before old notification group ids
correctNotificationIds();
myChecker = new SvnExecutableChecker(myProject);
+
+ Application app = ApplicationManager.getApplication();
+ myLogExceptions = app != null && (app.isInternal() || app.isUnitTestMode());
}
private void correctNotificationIds() {
@@ -348,6 +355,10 @@ public class SvnVcs extends AbstractVcs<CommittedChangeList> {
});
}
+ public void checkCommandLineVersion() {
+ myChecker.checkExecutableAndNotifyIfNeeded();
+ }
+
public void invokeRefreshSvnRoots() {
if (REFRESH_LOG.isDebugEnabled()) {
REFRESH_LOG.debug("refresh: ", new Throwable());
@@ -481,6 +492,9 @@ public class SvnVcs extends AbstractVcs<CommittedChangeList> {
myChecker.checkExecutableAndNotifyIfNeeded();
}
+ cmdClientFactory = new CmdClientFactory(this);
+ svnKitClientFactory = new SvnKitClientFactory(this);
+
// do one time after project loaded
StartupManager.getInstance(myProject).runWhenProjectIsInitialized(new DumbAwareRunnable() {
@Override
@@ -911,24 +925,127 @@ public class SvnVcs extends AbstractVcs<CommittedChangeList> {
return new File(file, pathToDirProps);
}
+ /**
+ * Provides info either with command line or SvnKit based on project settings.
+ * Call this method only if failed to detect working copy format by any other means.
+ *
+ * @param file
+ * @return
+ */
+ private SVNInfo runInfoCommand(@NotNull final File file) {
+ SVNInfo result = null;
+
+ try {
+ result = SvnConfiguration.UseAcceleration.commandLine.equals(myConfiguration.myUseAcceleration)
+ ? getInfoCommandLine(file, SVNRevision.UNDEFINED)
+ : getInfoSvnKit(file);
+ }
+ catch (SVNException e) {
+ handleInfoException(e);
+ }
+
+ return result;
+ }
+
+ public SVNInfo getInfo(@NotNull SVNURL url,
+ SVNRevision pegRevision,
+ SVNRevision revision,
+ ISVNAuthenticationManager manager) throws SVNException {
+ if (SvnConfiguration.UseAcceleration.commandLine.equals(myConfiguration.myUseAcceleration)) {
+ return createInfoClient().doInfo(url, pegRevision, revision);
+ } else {
+ return (manager != null ? createWCClient(manager) : createWCClient()).doInfo(url, pegRevision, revision);
+ }
+ }
+
+ public SVNInfo getInfo(@NotNull SVNURL url, SVNRevision revision) throws SVNException {
+ return getInfo(url, SVNRevision.UNDEFINED, revision, null);
+ }
+
@Nullable
- public SVNInfo getInfo(final VirtualFile file) {
+ public SVNInfo getInfo(@NotNull final VirtualFile file) {
final File ioFile = new File(file.getPath());
return getInfo(ioFile);
}
- public SVNInfo getInfo(File ioFile) {
+ @Nullable
+ public SVNInfo getInfo(@NotNull String path) {
+ return getInfo(new File(path));
+ }
+
+ @Nullable
+ public SVNInfo getInfo(@NotNull File ioFile) {
+ WorkingCopyFormat format = getWorkingCopyFormat(ioFile);
+ SVNInfo result = null;
+
try {
- SVNWCClient wcClient = createWCClient();
- SVNInfo info = wcClient.doInfo(ioFile, SVNRevision.UNDEFINED);
- if (info == null || info.getRepositoryRootURL() == null) {
- info = wcClient.doInfo(ioFile, SVNRevision.HEAD);
- }
- return info;
+ result = format == WorkingCopyFormat.ONE_DOT_EIGHT ? getInfoCommandLine(ioFile, SVNRevision.UNDEFINED) : runInfoCommand(ioFile);
}
catch (SVNException e) {
- return null;
+ handleInfoException(e);
}
+
+ return result;
+ }
+
+ @Nullable
+ public SVNInfo getInfo(@NotNull File ioFile, @NotNull SVNRevision revision) {
+ WorkingCopyFormat format = getWorkingCopyFormat(ioFile);
+ SVNInfo result = null;
+
+ try {
+ result = format == WorkingCopyFormat.ONE_DOT_EIGHT ? getInfoCommandLine(ioFile, revision) : getInfoSvnKit(ioFile, revision);
+ }
+ catch (SVNException e) {
+ handleInfoException(e);
+ }
+
+ return result;
+ }
+
+ private void handleInfoException(SVNException e) {
+ final SVNErrorCode errorCode = e.getErrorMessage().getErrorCode();
+ if (!myLogExceptions ||
+ SVNErrorCode.WC_PATH_NOT_FOUND.equals(errorCode) ||
+ SVNErrorCode.UNVERSIONED_RESOURCE.equals(errorCode) ||
+ SVNErrorCode.WC_NOT_WORKING_COPY.equals(errorCode)) {
+ LOG.debug(e);
+ }
+ else {
+ LOG.error(e);
+ }
+ }
+
+ private SVNInfo getInfoSvnKit(@NotNull File ioFile) throws SVNException {
+ SVNInfo info = getInfoSvnKit(ioFile, SVNRevision.UNDEFINED);
+ if (info == null || info.getRepositoryRootURL() == null) {
+ info = getInfoSvnKit(ioFile, SVNRevision.HEAD);
+ }
+ return info;
+ }
+
+ private SVNInfo getInfoSvnKit(@NotNull File ioFile, SVNRevision revision) throws SVNException {
+ return createWCClient().doInfo(ioFile, revision);
+ }
+
+ private SVNInfo getInfoCommandLine(@NotNull File ioFile, SVNRevision revision) throws SVNException {
+ SvnCommandLineInfoClient client = new SvnCommandLineInfoClient(myProject);
+ return client.doInfo(ioFile, revision);
+ }
+
+ private SvnWcClientI createInfoClient() {
+ return new SvnCommandLineInfoClient(myProject);
+ }
+
+ public WorkingCopyFormat getWorkingCopyFormat(@NotNull File ioFile) {
+ RootUrlInfo rootInfo = getSvnFileUrlMapping().getWcRootForFilePath(ioFile);
+ WorkingCopyFormat format = rootInfo != null ? rootInfo.getFormat() : WorkingCopyFormat.UNKNOWN;
+
+ if (WorkingCopyFormat.UNKNOWN.equals(format)) {
+ format = SvnFormatSelector.findRootAndGetFormat(ioFile);
+ }
+
+ return format;
}
public void refreshSSLProperty() {
@@ -1245,4 +1362,27 @@ public class SvnVcs extends AbstractVcs<CommittedChangeList> {
}
return myCheckoutProvider;
}
+
+ /**
+ * Try to avoid usages of this method (for now) as it could not correctly for all cases
+ * detect svn 1.8 working copy format to guarantee command line client.
+ *
+ * For instance, when working copies of several formats are presented in project
+ * (though it seems to be rather unlikely case).
+ *
+ * @return
+ */
+ public ClientFactory getFactory() {
+ // check working copy format of project directory
+ WorkingCopyFormat format = getWorkingCopyFormat(new File(getProject().getBaseDir().getPath()));
+
+ return WorkingCopyFormat.ONE_DOT_EIGHT.equals(format) ||
+ myConfiguration.myUseAcceleration.equals(SvnConfiguration.UseAcceleration.commandLine) ? cmdClientFactory : svnKitClientFactory;
+ }
+
+ public ClientFactory getFactory(@NotNull File file) {
+ WorkingCopyFormat format = getWorkingCopyFormat(file);
+
+ return WorkingCopyFormat.ONE_DOT_EIGHT.equals(format) ? cmdClientFactory : getFactory();
+ }
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnWriteOperationLocks.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnWriteOperationLocks.java
index 36e0b08c5a86..ca97edb1c228 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnWriteOperationLocks.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnWriteOperationLocks.java
@@ -30,6 +30,7 @@ import java.io.File;
* Date: 10/23/12
* Time: 2:29 PM
*/
+// TODO: Such locking functionality is not required anymore. Likely to be removed.
public class SvnWriteOperationLocks extends SvnAbstractWriteOperationLocks {
private final RootsToWorkingCopies myRootsToWorkingCopies;
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/WorkingCopyFormat.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/WorkingCopyFormat.java
index d40f947a71ee..c007541816c5 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/WorkingCopyFormat.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/WorkingCopyFormat.java
@@ -15,19 +15,22 @@
*/
package org.jetbrains.idea.svn;
-import org.tmatesoft.svn.core.internal.wc17.db.ISVNWCDb;
-
/**
* since not all constants are available from svnkit & constants are fixed
*/
public enum WorkingCopyFormat {
+
ONE_DOT_THREE(4, false, false, false, SvnBundle.message("dialog.show.svn.map.table.version13.text")),
ONE_DOT_FOUR(8, false, false, false, SvnBundle.message("dialog.show.svn.map.table.version14.text")),
ONE_DOT_FIVE(9, true, true, false, SvnBundle.message("dialog.show.svn.map.table.version15.text")),
ONE_DOT_SIX(10, true, true, true, SvnBundle.message("dialog.show.svn.map.table.version16.text")),
ONE_DOT_SEVEN(12, true, true, true, SvnBundle.message("dialog.show.svn.map.table.version17.text")),
+ ONE_DOT_EIGHT(12, true, true, true, SvnBundle.message("dialog.show.svn.map.table.version18.text")),
UNKNOWN(0, false, false, false, "unknown");
+ public static final int INTERNAL_FORMAT_17 = 29;
+ public static final int INTERNAL_FORMAT_18 = 31;
+
private final int myFormat;
private final boolean myChangelistSupport;
private final boolean myMergeInfoSupport;
@@ -60,10 +63,11 @@ public enum WorkingCopyFormat {
public static WorkingCopyFormat getInstance(final int value) {
// somewhy 1.7 wc format can also be 29
- if (ISVNWCDb.WC_FORMAT_17 == value) {
+ if (INTERNAL_FORMAT_17 == value) {
return ONE_DOT_SEVEN;
- }
- if (ONE_DOT_FIVE.getFormat() == value) {
+ } else if (INTERNAL_FORMAT_18 == value) {
+ return ONE_DOT_EIGHT;
+ } else if (ONE_DOT_FIVE.getFormat() == value) {
return ONE_DOT_FIVE;
} else if (ONE_DOT_FOUR.getFormat() == value) {
return ONE_DOT_FOUR;
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/AddAction.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/AddAction.java
index 06c255b6ed38..7558a483fcd7 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/AddAction.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/AddAction.java
@@ -30,8 +30,6 @@ import org.jetbrains.idea.svn.SvnBundle;
import org.jetbrains.idea.svn.SvnStatusUtil;
import org.jetbrains.idea.svn.SvnVcs;
import org.jetbrains.idea.svn.checkin.SvnCheckinEnvironment;
-import org.tmatesoft.svn.core.SVNException;
-import org.tmatesoft.svn.core.wc.SVNWCClient;
import java.util.*;
@@ -68,8 +66,6 @@ public class AddAction extends BasicAction {
ProjectLevelVcsManager manager = ProjectLevelVcsManager.getInstance(project);
manager.startBackgroundVcsOperation();
try {
-
- SVNWCClient wcClient = activeVcs.createWCClient();
final Set<VirtualFile> additionallyDirty = new HashSet<VirtualFile>();
final FileStatusManager fileStatusManager = FileStatusManager.getInstance(project);
for (VirtualFile item : items) {
@@ -84,13 +80,13 @@ public class AddAction extends BasicAction {
}
}
}
- Collection<SVNException> exceptions =
- SvnCheckinEnvironment.scheduleUnversionedFilesForAddition(wcClient, Arrays.asList(items), true);
+ Collection<VcsException> exceptions =
+ SvnCheckinEnvironment.scheduleUnversionedFilesForAddition(activeVcs, Arrays.asList(items), true);
additionallyDirty.addAll(Arrays.asList(items));
markDirty(project, additionallyDirty);
if (!exceptions.isEmpty()) {
final Collection<String> messages = new ArrayList<String>(exceptions.size());
- for (SVNException exception : exceptions) {
+ for (VcsException exception : exceptions) {
messages.add(exception.getMessage());
}
throw new VcsException(messages);
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/MarkResolvedAction.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/MarkResolvedAction.java
index 87b36970228b..d65c6d3c9c20 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/MarkResolvedAction.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/MarkResolvedAction.java
@@ -19,6 +19,7 @@ package org.jetbrains.idea.svn.actions;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.vcs.AbstractVcs;
@@ -32,8 +33,9 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.svn.SvnBundle;
import org.jetbrains.idea.svn.SvnStatusUtil;
import org.jetbrains.idea.svn.SvnVcs;
+import org.jetbrains.idea.svn.conflict.ConflictClient;
import org.jetbrains.idea.svn.dialogs.SelectFilesDialog;
-import org.tmatesoft.svn.core.SVNDepth;
+import org.jetbrains.idea.svn.portable.SvnStatusClientI;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.wc.*;
@@ -42,6 +44,8 @@ import java.util.Collection;
import java.util.TreeSet;
public class MarkResolvedAction extends BasicAction {
+ private static final Logger LOG = Logger.getInstance("#org.jetbrains.idea.svn.actions.MarkResolvedAction");
+
protected String getActionName(AbstractVcs vcs) {
return SvnBundle.message("action.name.mark.resolved");
}
@@ -88,15 +92,13 @@ public class MarkResolvedAction extends BasicAction {
}
pathsArray = dialog.getSelectedPaths();
try {
- SVNWCClient wcClient = vcs.createWCClient();
for (String path : pathsArray) {
File ioFile = new File(path);
- wcClient.doResolve(ioFile, SVNDepth.EMPTY, SVNConflictChoice.MERGED);
+ ConflictClient client = vcs.getFactory(ioFile).createConflictClient();
+
+ client.resolve(ioFile, true);
}
}
- catch (SVNException e) {
- throw new VcsException(e);
- }
finally {
for (VirtualFile file : files) {
VcsDirtyScopeManager.getInstance(project).fileDirty(file);
@@ -115,10 +117,12 @@ public class MarkResolvedAction extends BasicAction {
private static Collection<String> collectResolvablePaths(final SvnVcs vcs, VirtualFile[] files) {
final Collection<String> target = new TreeSet<String>();
- SVNStatusClient stClient = vcs.createStatusClient();
for (VirtualFile file : files) {
try {
- stClient.doStatus(new File(file.getPath()), true, false, false, false, new ISVNStatusHandler() {
+ File path = new File(file.getPath());
+ SvnStatusClientI client = vcs.getFactory(path).createStatusClient();
+
+ client.doStatus(path, true, false, false, false, new ISVNStatusHandler() {
public void handleStatus(SVNStatus status) {
if (status.getContentsStatus() == SVNStatusType.STATUS_CONFLICTED ||
status.getPropertiesStatus() == SVNStatusType.STATUS_CONFLICTED) {
@@ -128,7 +132,7 @@ public class MarkResolvedAction extends BasicAction {
});
}
catch (SVNException e) {
- //
+ LOG.warn(e);
}
}
return target;
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/SvnMergeProvider.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/SvnMergeProvider.java
index 4c582d01557d..3130dc948c13 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/SvnMergeProvider.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/actions/SvnMergeProvider.java
@@ -27,12 +27,13 @@ import com.intellij.vcsUtil.VcsRunnable;
import com.intellij.vcsUtil.VcsUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.svn.SvnRevisionNumber;
+import org.jetbrains.idea.svn.SvnUtil;
import org.jetbrains.idea.svn.SvnVcs;
-import org.tmatesoft.svn.core.SVNDepth;
-import org.tmatesoft.svn.core.SVNException;
+import org.jetbrains.idea.svn.properties.PropertyClient;
import org.tmatesoft.svn.core.SVNProperty;
import org.tmatesoft.svn.core.SVNPropertyValue;
import org.tmatesoft.svn.core.wc.*;
+import org.tmatesoft.svn.core.wc2.SvnTarget;
import java.io.ByteArrayOutputStream;
import java.io.File;
@@ -57,38 +58,34 @@ public class SvnMergeProvider implements MergeProvider {
final MergeData data = new MergeData();
VcsRunnable runnable = new VcsRunnable() {
public void run() throws VcsException {
- SvnVcs vcs = SvnVcs.getInstance(myProject);
File oldFile = null;
File newFile = null;
File workingFile = null;
- SVNWCClient client;
boolean mergeCase = false;
- try {
- client = vcs.createWCClient();
- SVNInfo info = client.doInfo(new File(file.getPath()), SVNRevision.UNDEFINED);
- if (info != null) {
- oldFile = info.getConflictOldFile();
- newFile = info.getConflictNewFile();
+ SvnVcs vcs = SvnVcs.getInstance(myProject);
+ SVNInfo info = vcs.getInfo(file);
+
+ if (info != null) {
+ oldFile = info.getConflictOldFile();
+ newFile = info.getConflictNewFile();
+ workingFile = info.getConflictWrkFile();
+ mergeCase = workingFile == null || workingFile.getName().contains("working");
+ // for debug
+ if (workingFile == null) {
+ LOG.info("Null working file when merging text conflict for " + file.getPath() + " old file: " + oldFile + " new file: " + newFile);
+ }
+ if (mergeCase) {
+ // this is merge case
+ oldFile = info.getConflictNewFile();
+ newFile = info.getConflictOldFile();
workingFile = info.getConflictWrkFile();
- mergeCase = workingFile == null || workingFile.getName().contains("working");
- // for debug
- if (workingFile == null) {
- LOG.info("Null working file when merging text conflict for " + file.getPath() + " old file: " + oldFile + " new file: " + newFile);
- }
- if (mergeCase) {
- // this is merge case
- oldFile = info.getConflictNewFile();
- newFile = info.getConflictOldFile();
- workingFile = info.getConflictWrkFile();
- }
- data.LAST_REVISION_NUMBER = new SvnRevisionNumber(info.getRevision());
}
- }
- catch (SVNException e) {
- throw new VcsException(e);
+ data.LAST_REVISION_NUMBER = new SvnRevisionNumber(info.getRevision());
+ } else {
+ throw new VcsException("Could not get info for " + file.getPath());
}
if (oldFile == null || newFile == null || workingFile == null) {
- ByteArrayOutputStream bos = getBaseRevisionContents(client, file);
+ ByteArrayOutputStream bos = getBaseRevisionContents(vcs, file);
data.ORIGINAL = bos.toByteArray();
data.LAST = bos.toByteArray();
data.CURRENT = readFile(new File(file.getPath()));
@@ -99,7 +96,7 @@ public class SvnMergeProvider implements MergeProvider {
data.CURRENT = readFile(workingFile);
}
if (mergeCase) {
- final ByteArrayOutputStream contents = getBaseRevisionContents(vcs.createWCClient(), file);
+ final ByteArrayOutputStream contents = getBaseRevisionContents(vcs, file);
if (! Arrays.equals(contents.toByteArray(), data.ORIGINAL)) {
// swap base and server: another order of merge arguments
byte[] original = data.ORIGINAL;
@@ -114,13 +111,17 @@ public class SvnMergeProvider implements MergeProvider {
return data;
}
- private ByteArrayOutputStream getBaseRevisionContents(SVNWCClient client, VirtualFile file) {
+ private ByteArrayOutputStream getBaseRevisionContents(@NotNull SvnVcs vcs, @NotNull VirtualFile file) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
- client.doGetFileContents(new File(file.getPath()), SVNRevision.UNDEFINED, SVNRevision.BASE, true, bos);
+ byte[] contents = SvnUtil.getFileContents(vcs, SvnTarget.fromFile(new File(file.getPath())), SVNRevision.BASE, SVNRevision.UNDEFINED);
+ bos.write(contents);
}
- catch (SVNException e) {
- //
+ catch (VcsException e) {
+ LOG.warn(e);
+ }
+ catch (IOException e) {
+ LOG.warn(e);
}
return bos;
}
@@ -135,13 +136,14 @@ public class SvnMergeProvider implements MergeProvider {
}
public void conflictResolvedForFile(VirtualFile file) {
+ // TODO: Add possibility to resolve content conflicts separately from property conflicts.
SvnVcs vcs = SvnVcs.getInstance(myProject);
+ File path = new File(file.getPath());
try {
- SVNWCClient client = vcs.createWCClient();
- client.doResolve(new File(file.getPath()), SVNDepth.EMPTY, true, false, SVNConflictChoice.MERGED);
+ vcs.getFactory(path).createConflictClient().resolve(path, false);
}
- catch (SVNException e) {
- //
+ catch (VcsException e) {
+ LOG.warn(e);
}
// the .mine/.r## files have been deleted
final VirtualFile parent = file.getParent();
@@ -152,17 +154,20 @@ public class SvnMergeProvider implements MergeProvider {
public boolean isBinary(@NotNull final VirtualFile file) {
SvnVcs vcs = SvnVcs.getInstance(myProject);
+
try {
- SVNWCClient client = vcs.createWCClient();
File ioFile = new File(file.getPath());
- SVNPropertyData svnPropertyData = client.doGetProperty(ioFile, SVNProperty.MIME_TYPE, SVNRevision.UNDEFINED, SVNRevision.WORKING);
+ PropertyClient client = vcs.getFactory(ioFile).createPropertyClient();
+
+ SVNPropertyData svnPropertyData = client.getProperty(ioFile, SVNProperty.MIME_TYPE, false, SVNRevision.UNDEFINED, SVNRevision.WORKING);
if (svnPropertyData != null && SVNProperty.isBinaryMimeType(SVNPropertyValue.getPropertyAsString(svnPropertyData.getValue()))) {
return true;
}
}
- catch (SVNException e) {
- //
+ catch (VcsException e) {
+ LOG.warn(e);
}
+
return false;
}
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/add/AddClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/add/AddClient.java
new file mode 100644
index 000000000000..718a56dea9af
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/add/AddClient.java
@@ -0,0 +1,23 @@
+package org.jetbrains.idea.svn.add;
+
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.api.SvnClient;
+import org.tmatesoft.svn.core.SVNDepth;
+import org.tmatesoft.svn.core.wc.ISVNEventHandler;
+
+import java.io.File;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public interface AddClient extends SvnClient {
+
+ void add(@NotNull File file,
+ @Nullable SVNDepth depth,
+ boolean makeParents,
+ boolean includeIgnored,
+ boolean force,
+ @Nullable ISVNEventHandler handler) throws VcsException;
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/add/CmdAddClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/add/CmdAddClient.java
new file mode 100644
index 000000000000..c7866713c9c1
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/add/CmdAddClient.java
@@ -0,0 +1,69 @@
+package org.jetbrains.idea.svn.add;
+
+import com.intellij.openapi.vcs.VcsException;
+import com.intellij.util.containers.Convertor;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.api.BaseSvnClient;
+import org.jetbrains.idea.svn.api.FileStatusResultParser;
+import org.jetbrains.idea.svn.commandLine.CommandUtil;
+import org.jetbrains.idea.svn.commandLine.SvnCommandName;
+import org.tmatesoft.svn.core.SVNDepth;
+import org.tmatesoft.svn.core.wc.ISVNEventHandler;
+import org.tmatesoft.svn.core.wc.SVNEvent;
+import org.tmatesoft.svn.core.wc.SVNStatusType;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class CmdAddClient extends BaseSvnClient implements AddClient {
+
+ private static final String STATUS = "\\s*(\\w)\\s*";
+ private static final String OPTIONAL_FILE_TYPE = "(\\(.*\\))?";
+ private static final String PATH = "\\s*(.*?)\\s*";
+ private static final Pattern CHANGED_PATH = Pattern.compile(STATUS + OPTIONAL_FILE_TYPE + PATH);
+
+ @Override
+ public void add(@NotNull File file,
+ @Nullable SVNDepth depth,
+ boolean makeParents,
+ boolean includeIgnored,
+ boolean force,
+ @Nullable ISVNEventHandler handler) throws VcsException {
+ List<String> parameters = prepareParameters(file, depth, makeParents, includeIgnored, force);
+
+ // TODO: handler should be called in parallel with command execution, but this will be in other thread
+ // TODO: check if that is ok for current handler implementation
+ // TODO: add possibility to invoke "handler.checkCancelled" - process should be killed
+ CommandUtil.execute(myVcs, SvnCommandName.add, parameters, new FileStatusResultParser(CHANGED_PATH, handler, new AddStatusConvertor()));
+ }
+
+ private static List<String> prepareParameters(File file, SVNDepth depth, boolean makeParents, boolean includeIgnored, boolean force) {
+ List<String> parameters = new ArrayList<String>();
+
+ CommandUtil.put(parameters, file);
+ CommandUtil.put(parameters, depth);
+ CommandUtil.put(parameters, makeParents, "--parents");
+ CommandUtil.put(parameters, includeIgnored, "--no-ignore");
+ CommandUtil.put(parameters, force, "--force");
+
+ return parameters;
+ }
+
+ private static class AddStatusConvertor implements Convertor<Matcher, SVNEvent> {
+ @Override
+ public SVNEvent convert(Matcher o) {
+ SVNStatusType contentStatus = CommandUtil.getStatusType(o.group(1));
+ String path = o.group(3);
+
+ return new SVNEvent(new File(path), null, null, 0, contentStatus, null, null, null, null, null, null, null,
+ null, null, null);
+ }
+ }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/add/SvnKitAddClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/add/SvnKitAddClient.java
new file mode 100644
index 000000000000..d6250c71f073
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/add/SvnKitAddClient.java
@@ -0,0 +1,39 @@
+package org.jetbrains.idea.svn.add;
+
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.api.BaseSvnClient;
+import org.tmatesoft.svn.core.SVNDepth;
+import org.tmatesoft.svn.core.SVNException;
+import org.tmatesoft.svn.core.wc.ISVNEventHandler;
+import org.tmatesoft.svn.core.wc.SVNWCClient;
+
+import java.io.File;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class SvnKitAddClient extends BaseSvnClient implements AddClient {
+
+ @Override
+ public void add(@NotNull File file,
+ @Nullable SVNDepth depth,
+ boolean makeParents,
+ boolean includeIgnored,
+ boolean force,
+ @Nullable ISVNEventHandler handler) throws VcsException {
+ try {
+ SVNWCClient client = myVcs.createWCClient();
+
+ client.setEventHandler(handler);
+ client.doAdd(file, force,
+ false, // directory should already be created
+ makeParents, // not used but will be passed as makeParents value
+ SVNDepth.recurseFromDepth(depth));
+ }
+ catch (SVNException e) {
+ throw new VcsException(e);
+ }
+ }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/AnnotateClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/AnnotateClient.java
new file mode 100644
index 000000000000..df30cfd89ae2
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/AnnotateClient.java
@@ -0,0 +1,24 @@
+package org.jetbrains.idea.svn.annotate;
+
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.api.SvnClient;
+import org.tmatesoft.svn.core.wc.ISVNAnnotateHandler;
+import org.tmatesoft.svn.core.wc.SVNDiffOptions;
+import org.tmatesoft.svn.core.wc.SVNRevision;
+import org.tmatesoft.svn.core.wc2.SvnTarget;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public interface AnnotateClient extends SvnClient {
+
+ void annotate(@NotNull SvnTarget target,
+ @NotNull SVNRevision startRevision,
+ @NotNull SVNRevision endRevision,
+ @Nullable SVNRevision pegRevision,
+ boolean includeMergedRevisions,
+ @Nullable SVNDiffOptions diffOptions,
+ @Nullable ISVNAnnotateHandler handler) throws VcsException;
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/CmdAnnotateClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/CmdAnnotateClient.java
new file mode 100644
index 000000000000..d29d40eca84a
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/CmdAnnotateClient.java
@@ -0,0 +1,126 @@
+package org.jetbrains.idea.svn.annotate;
+
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.api.BaseSvnClient;
+import org.jetbrains.idea.svn.commandLine.CommandUtil;
+import org.jetbrains.idea.svn.commandLine.SvnCommand;
+import org.jetbrains.idea.svn.commandLine.SvnCommandName;
+import org.tmatesoft.svn.core.SVNException;
+import org.tmatesoft.svn.core.wc.ISVNAnnotateHandler;
+import org.tmatesoft.svn.core.wc.SVNDiffOptions;
+import org.tmatesoft.svn.core.wc.SVNRevision;
+import org.tmatesoft.svn.core.wc2.SvnTarget;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class CmdAnnotateClient extends BaseSvnClient implements AnnotateClient {
+
+ @Override
+ public void annotate(@NotNull SvnTarget target,
+ @NotNull SVNRevision startRevision,
+ @NotNull SVNRevision endRevision,
+ @Nullable SVNRevision pegRevision,
+ boolean includeMergedRevisions,
+ @Nullable SVNDiffOptions diffOptions,
+ @Nullable final ISVNAnnotateHandler handler) throws VcsException {
+ // TODO: after merge remove setting includeMergedRevisions to false and update parsing
+ includeMergedRevisions = false;
+
+ List<String> parameters = new ArrayList<String>();
+ CommandUtil.put(parameters, target.getPathOrUrlString(), pegRevision);
+ parameters.add("--revision");
+ parameters.add(startRevision + ":" + endRevision);
+ CommandUtil.put(parameters, includeMergedRevisions, "--use-merge-history");
+ CommandUtil.put(parameters, diffOptions);
+ parameters.add("--xml");
+
+ SvnCommand command = CommandUtil.execute(myVcs, SvnCommandName.blame, parameters, null);
+
+ parseOutput(command.getOutput(), handler);
+ }
+
+ public void parseOutput(@NotNull String output, @Nullable ISVNAnnotateHandler handler) throws VcsException {
+ try {
+ JAXBContext context = JAXBContext.newInstance(BlameInfo.class);
+ Unmarshaller unmarshaller = context.createUnmarshaller();
+ BlameInfo info = (BlameInfo)unmarshaller.unmarshal(new StringReader(output));
+
+ if (handler != null && info != null && info.target != null && info.target.lineEntries != null) {
+ for (LineEntry entry : info.target.lineEntries) {
+ invokeHandler(handler, entry);
+ }
+ }
+ }
+ catch (JAXBException e) {
+ throw new VcsException(e);
+ }
+ catch (SVNException e) {
+ throw new VcsException(e);
+ }
+ }
+
+ private static void invokeHandler(ISVNAnnotateHandler handler, LineEntry entry) throws SVNException {
+ // line numbers in our api start from 0 - not from 1 like in svn output
+ handler.handleLine(entry.date(), entry.revision(), entry.author(), null, null, 0, null, null, entry.lineNumber - 1);
+ }
+
+ @XmlRootElement(name = "blame")
+ public static class BlameInfo {
+
+ @XmlElement(name = "target")
+ public TargetEntry target;
+ }
+
+ public static class TargetEntry {
+
+ @XmlElement(name = "entry")
+ List<LineEntry> lineEntries;
+ }
+
+ public static class LineEntry {
+
+ @XmlAttribute(name = "line-number")
+ public int lineNumber;
+
+ @XmlElement(name = "commit")
+ public CommitEntry commit;
+
+ public long revision() {
+ return commit != null ? commit.revision : 0;
+ }
+
+ public String author() {
+ return commit != null ? commit.author : null;
+ }
+
+ public Date date() {
+ return commit != null ? commit.date : null;
+ }
+ }
+
+ public static class CommitEntry {
+
+ @XmlAttribute(name = "revision")
+ public long revision;
+
+ @XmlElement(name = "author")
+ public String author;
+
+ @XmlElement(name = "date")
+ public Date date;
+ }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/SvnAnnotationProvider.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/SvnAnnotationProvider.java
index d0885c8a293e..88adf25e401c 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/SvnAnnotationProvider.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/SvnAnnotationProvider.java
@@ -32,14 +32,16 @@ import com.intellij.openapi.vcs.history.*;
import com.intellij.openapi.vcs.versionBrowser.ChangeBrowserSettings;
import com.intellij.openapi.vfs.CharsetToolkit;
import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.*;
+import org.jetbrains.idea.svn.history.HistoryClient;
import org.jetbrains.idea.svn.history.SvnChangeList;
import org.jetbrains.idea.svn.history.SvnFileRevision;
import org.tmatesoft.svn.core.*;
import org.tmatesoft.svn.core.wc.*;
+import org.tmatesoft.svn.core.wc2.SvnTarget;
-import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
@@ -89,9 +91,8 @@ public class SvnAnnotationProvider implements AnnotationProvider, VcsCacheableAn
final String contents;
if (loadExternally) {
- final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
- myVcs.createWCClient().doGetFileContents(ioFile, SVNRevision.UNDEFINED, SVNRevision.BASE, true, buffer);
- contents = LoadTextUtil.getTextByBinaryPresentation(buffer.toByteArray(), file, false, false).toString();
+ byte[] data = SvnUtil.getFileContents(myVcs, SvnTarget.fromFile(ioFile), SVNRevision.BASE, SVNRevision.UNDEFINED);
+ contents = LoadTextUtil.getTextByBinaryPresentation(data, file, false, false).toString();
} else {
final byte[] bytes = VcsHistoryUtil.loadRevisionContent(revision);
contents = LoadTextUtil.getTextByBinaryPresentation(bytes, file, false, false).toString();
@@ -99,16 +100,13 @@ public class SvnAnnotationProvider implements AnnotationProvider, VcsCacheableAn
final SvnFileAnnotation result = new SvnFileAnnotation(myVcs, file, contents, lastChangedRevision);
- SVNWCClient wcClient = myVcs.createWCClient();
- info = wcClient.doInfo(ioFile, SVNRevision.UNDEFINED);
+ info = myVcs.getInfo(ioFile);
if (info == null) {
exception[0] = new VcsException(new SVNException(SVNErrorMessage.create(SVNErrorCode.UNKNOWN, "File ''{0}'' is not under version control", ioFile)));
return;
}
final String url = info.getURL() == null ? null : info.getURL().toString();
- SVNLogClient client = myVcs.createLogClient();
- setLogClientOptions(client);
SVNRevision endRevision = ((SvnFileRevision) revision).getRevision();
if (SVNRevision.WORKING.equals(endRevision)) {
endRevision = info.getRevision();
@@ -122,14 +120,20 @@ public class SvnAnnotationProvider implements AnnotationProvider, VcsCacheableAn
final boolean calculateMergeinfo = SvnConfiguration.getInstance(myVcs.getProject()).SHOW_MERGE_SOURCES_IN_ANNOTATE &&
SvnUtil.checkRepositoryVersion15(myVcs, url);
- final SVNRevision svnRevision = ((SvnRevisionNumber)revision.getRevisionNumber()).getRevision();
+ final MySteppedLogGetter logGetter = new MySteppedLogGetter(
+ myVcs, ioFile, progress,
+ myVcs.getFactory(ioFile).createHistoryClient(), endRevision, result,
+ url, calculateMergeinfo, file.getCharset());
- final MySteppedLogGetter logGetter = new MySteppedLogGetter(myVcs, ioFile, progress, client, endRevision, result, url, calculateMergeinfo, file.getCharset());
logGetter.go();
final LinkedList<SVNRevision> rp = logGetter.getRevisionPoints();
+ // TODO: only 2 elements will be in rp and for loop will be executed only once - probably rewrite with Pair
+ AnnotateClient annotateClient = myVcs.getFactory(ioFile).createAnnotateClient();
for (int i = 0; i < rp.size() - 1; i++) {
- client.doAnnotate(ioFile, svnRevision, rp.get(i + 1), rp.get(i), true, calculateMergeinfo, annotateHandler, null);
+ annotateClient.annotate(SvnTarget.fromFile(ioFile), rp.get(i + 1), rp.get(i), ((SvnFileRevision)revision).getPegRevision(),
+ calculateMergeinfo,
+ getLogClientOptions(myVcs), annotateHandler);
}
if (rp.get(1).getNumber() > 0) {
@@ -137,31 +141,15 @@ public class SvnAnnotationProvider implements AnnotationProvider, VcsCacheableAn
}
annotation[0] = result;
}
- catch (SVNException e) {
- if (SVNErrorCode.FS_NOT_FOUND.equals(e.getErrorMessage().getErrorCode())) {
- final CommittedChangesProvider<SvnChangeList,ChangeBrowserSettings> provider = myVcs.getCommittedChangesProvider();
- try {
- final Pair<SvnChangeList, FilePath> pair = provider.getOneList(file, revision.getRevisionNumber());
- if (pair != null && info != null && pair.getSecond() != null && ! Comparing.equal(pair.getSecond().getIOFile(), ioFile)) {
- annotation[0] = annotateNonExisting(pair, revision, info, file.getCharset(), file);
- return;
- }
- }
- catch (VcsException e1) {
- exception[0] = e1;
- }
- catch (SVNException e1) {
- exception[0] = new VcsException(e);
- }
- catch (IOException e1) {
- exception[0] = new VcsException(e);
- }
- }
- exception[0] = new VcsException(e);
- } catch (IOException e) {
+ catch (IOException e) {
exception[0] = new VcsException(e);
} catch (VcsException e) {
- exception[0] = e;
+ if (e.getCause() instanceof SVNException) {
+ handleSvnException(ioFile, info, (SVNException)e.getCause(), file, revision, annotation, exception);
+ }
+ else {
+ exception[0] = e;
+ }
}
}
};
@@ -177,6 +165,35 @@ public class SvnAnnotationProvider implements AnnotationProvider, VcsCacheableAn
return annotation[0];
}
+ private void handleSvnException(File ioFile,
+ SVNInfo info,
+ SVNException e,
+ VirtualFile file,
+ VcsFileRevision revision,
+ FileAnnotation[] annotation, VcsException[] exception) {
+ // TODO: Check how this scenario could be reproduced by user and what changes needs to be done for command line client
+ if (SVNErrorCode.FS_NOT_FOUND.equals(e.getErrorMessage().getErrorCode())) {
+ final CommittedChangesProvider<SvnChangeList,ChangeBrowserSettings> provider = myVcs.getCommittedChangesProvider();
+ try {
+ final Pair<SvnChangeList, FilePath> pair = provider.getOneList(file, revision.getRevisionNumber());
+ if (pair != null && info != null && pair.getSecond() != null && ! Comparing.equal(pair.getSecond().getIOFile(), ioFile)) {
+ annotation[0] = annotateNonExisting(pair, revision, info, file.getCharset(), file);
+ return;
+ }
+ }
+ catch (VcsException e1) {
+ exception[0] = e1;
+ }
+ catch (SVNException e1) {
+ exception[0] = new VcsException(e);
+ }
+ catch (IOException e1) {
+ exception[0] = new VcsException(e);
+ }
+ }
+ exception[0] = new VcsException(e);
+ }
+
public static File getCommonAncestor(final File file1, final File file2) throws IOException {
if (FileUtil.filesEqual(file1, file2)) return file1;
final File can1 = file1.getCanonicalFile();
@@ -214,8 +231,7 @@ public class SvnAnnotationProvider implements AnnotationProvider, VcsCacheableAn
final String relativePath = FileUtil.getRelativePath(root.getPath(), wasFile.getPath(), File.separatorChar);
if (relativePath == null) throw new VcsException("Can not find relative path for " + wasFile.getPath() + "@" + revision.getRevisionNumber().asString());
- SVNWCClient wcClient = myVcs.createWCClient();
- SVNInfo wcRootInfo = wcClient.doInfo(root, SVNRevision.UNDEFINED);
+ SVNInfo wcRootInfo = myVcs.getInfo(root);
if (wcRootInfo == null || wcRootInfo.getURL() == null) {
throw new VcsException("Can not find relative path for " + wasFile.getPath() + "@" + revision.getRevisionNumber().asString());
}
@@ -225,21 +241,18 @@ public class SvnAnnotationProvider implements AnnotationProvider, VcsCacheableAn
wasUrl = wasUrl.appendPath(string, true);
}
- final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
final SVNRevision svnRevision = ((SvnRevisionNumber)revision.getRevisionNumber()).getRevision();
- myVcs.createWCClient().doGetFileContents(wasUrl, svnRevision, svnRevision, true, buffer);
- final String contents = LoadTextUtil.getTextByBinaryPresentation(buffer.toByteArray(),
- charset == null ? CharsetToolkit.UTF8_CHARSET : charset).toString();
- SVNLogClient client = myVcs.createLogClient();
- setLogClientOptions(client);
+ byte[] data = SvnUtil.getFileContents(myVcs, SvnTarget.fromURL(wasUrl), svnRevision, svnRevision);
+ final String contents = LoadTextUtil.getTextByBinaryPresentation(data, charset == null ? CharsetToolkit.UTF8_CHARSET : charset).toString();
final SvnRemoteFileAnnotation result = new SvnRemoteFileAnnotation(myVcs, contents, revision.getRevisionNumber(), pair.getFirst(),
pair.getSecond().getPath(), current);
final ISVNAnnotateHandler annotateHandler = createAnnotationHandler(ProgressManager.getInstance().getProgressIndicator(), result);
final boolean calculateMergeinfo = SvnConfiguration.getInstance(myVcs.getProject()).SHOW_MERGE_SOURCES_IN_ANNOTATE &&
SvnUtil.checkRepositoryVersion15(myVcs, wasUrl.toString());
- client.doAnnotate(wasUrl, svnRevision, SVNRevision.create(1), svnRevision, true, calculateMergeinfo, annotateHandler, null);
-
+ AnnotateClient client = myVcs.getFactory().createAnnotateClient();
+ client.annotate(SvnTarget.fromURL(wasUrl), SVNRevision.create(1), svnRevision, svnRevision, calculateMergeinfo,
+ getLogClientOptions(myVcs), annotateHandler);
return result;
}
@@ -370,14 +383,14 @@ public class SvnAnnotationProvider implements AnnotationProvider, VcsCacheableAn
private final SvnVcs myVcs;
private final File myIoFile;
private final ProgressIndicator myProgress;
- private final SVNLogClient myClient;
+ private final HistoryClient myClient;
private final SVNRevision myEndRevision;
private final boolean myCalculateMergeinfo;
private final SvnFileAnnotation myResult;
private final String myUrl;
private final Charset myCharset;
- private MySteppedLogGetter(final SvnVcs vcs, final File ioFile, final ProgressIndicator progress, final SVNLogClient client,
+ private MySteppedLogGetter(final SvnVcs vcs, final File ioFile, final ProgressIndicator progress, final HistoryClient client,
final SVNRevision endRevision,
final SvnFileAnnotation result,
final String url,
@@ -395,7 +408,7 @@ public class SvnAnnotationProvider implements AnnotationProvider, VcsCacheableAn
myRevisionPoints = new LinkedList<SVNRevision>();
}
- public void go() throws SVNException {
+ public void go() throws VcsException {
final int maxAnnotateRevisions = SvnConfiguration.getInstance(myVcs.getProject()).getMaxAnnotateRevisions();
boolean longHistory = true;
if (maxAnnotateRevisions == -1) {
@@ -437,8 +450,8 @@ public class SvnAnnotationProvider implements AnnotationProvider, VcsCacheableAn
myRevisionPoints.add(SVNRevision.create(0));
}
- private void doLog(final boolean includeMerged, final SVNRevision truncateTo, final int max) throws SVNException {
- myClient.doLog(new File[]{myIoFile}, myEndRevision, truncateTo == null ? SVNRevision.create(1L) : truncateTo,
+ private void doLog(final boolean includeMerged, final SVNRevision truncateTo, final int max) throws VcsException {
+ myClient.doLog(myIoFile, myEndRevision, truncateTo == null ? SVNRevision.create(1L) : truncateTo,
SVNRevision.UNDEFINED, false, false, includeMerged, max, null,
new ISVNLogEntryHandler() {
public void handleLogEntry(SVNLogEntry logEntry) {
@@ -464,9 +477,7 @@ public class SvnAnnotationProvider implements AnnotationProvider, VcsCacheableAn
return true;
}
- private void setLogClientOptions(final SVNLogClient client) {
- if (SvnConfiguration.getInstance(myVcs.getProject()).IGNORE_SPACES_IN_ANNOTATE) {
- client.setDiffOptions(new SVNDiffOptions(true, true, true));
- }
+ private static SVNDiffOptions getLogClientOptions(@NotNull SvnVcs vcs) {
+ return SvnConfiguration.getInstance(vcs.getProject()).IGNORE_SPACES_IN_ANNOTATE ? new SVNDiffOptions(true, true, true) : null;
}
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/SvnKitAnnotateClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/SvnKitAnnotateClient.java
new file mode 100644
index 000000000000..315178c9079e
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/annotate/SvnKitAnnotateClient.java
@@ -0,0 +1,42 @@
+package org.jetbrains.idea.svn.annotate;
+
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.api.BaseSvnClient;
+import org.tmatesoft.svn.core.SVNException;
+import org.tmatesoft.svn.core.wc.ISVNAnnotateHandler;
+import org.tmatesoft.svn.core.wc.SVNDiffOptions;
+import org.tmatesoft.svn.core.wc.SVNLogClient;
+import org.tmatesoft.svn.core.wc.SVNRevision;
+import org.tmatesoft.svn.core.wc2.SvnTarget;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class SvnKitAnnotateClient extends BaseSvnClient implements AnnotateClient {
+
+ @Override
+ public void annotate(@NotNull SvnTarget target,
+ @NotNull SVNRevision startRevision,
+ @NotNull SVNRevision endRevision,
+ @Nullable SVNRevision pegRevision,
+ boolean includeMergedRevisions,
+ @Nullable SVNDiffOptions diffOptions,
+ @Nullable ISVNAnnotateHandler handler) throws VcsException {
+ try {
+ SVNLogClient client = myVcs.createLogClient();
+
+ client.setDiffOptions(diffOptions);
+ if (target.isFile()) {
+ client.doAnnotate(target.getFile(), pegRevision, startRevision, endRevision, true, includeMergedRevisions, handler, null);
+ }
+ else {
+ client.doAnnotate(target.getURL(), pegRevision, startRevision, endRevision, true, includeMergedRevisions, handler, null);
+ }
+ }
+ catch (SVNException e) {
+ throw new VcsException(e);
+ }
+ }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/BaseSvnClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/BaseSvnClient.java
new file mode 100644
index 000000000000..54401cff68b1
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/BaseSvnClient.java
@@ -0,0 +1,22 @@
+package org.jetbrains.idea.svn.api;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.idea.svn.SvnVcs;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public abstract class BaseSvnClient implements SvnClient {
+ protected SvnVcs myVcs;
+
+ @NotNull
+ @Override
+ public SvnVcs getVcs() {
+ return myVcs;
+ }
+
+ @Override
+ public void setVcs(@NotNull SvnVcs vcs) {
+ myVcs = vcs;
+ }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/ClientFactory.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/ClientFactory.java
new file mode 100644
index 000000000000..b85121637e6a
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/ClientFactory.java
@@ -0,0 +1,99 @@
+package org.jetbrains.idea.svn.api;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.idea.svn.SvnVcs;
+import org.jetbrains.idea.svn.add.AddClient;
+import org.jetbrains.idea.svn.annotate.AnnotateClient;
+import org.jetbrains.idea.svn.conflict.ConflictClient;
+import org.jetbrains.idea.svn.content.ContentClient;
+import org.jetbrains.idea.svn.copy.CopyMoveClient;
+import org.jetbrains.idea.svn.delete.DeleteClient;
+import org.jetbrains.idea.svn.history.HistoryClient;
+import org.jetbrains.idea.svn.portable.SvnStatusClientI;
+import org.jetbrains.idea.svn.properties.PropertyClient;
+import org.jetbrains.idea.svn.revert.RevertClient;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public abstract class ClientFactory {
+
+ @NotNull
+ protected SvnVcs myVcs;
+
+ protected AddClient addClient;
+ protected AnnotateClient annotateClient;
+ protected ContentClient contentClient;
+ protected HistoryClient historyClient;
+ protected RevertClient revertClient;
+ protected DeleteClient deleteClient;
+ protected SvnStatusClientI statusClient;
+ protected CopyMoveClient copyMoveClient;
+ protected ConflictClient conflictClient;
+ protected PropertyClient propertyClient;
+
+ protected ClientFactory(@NotNull SvnVcs vcs) {
+ myVcs = vcs;
+ setup();
+ }
+
+ protected abstract void setup();
+
+ @NotNull
+ public AddClient createAddClient() {
+ return prepare(addClient);
+ }
+
+ @NotNull
+ public AnnotateClient createAnnotateClient() {
+ return prepare(annotateClient);
+ }
+
+ @NotNull
+ public ContentClient createContentClient() {
+ return prepare(contentClient);
+ }
+
+ @NotNull
+ public HistoryClient createHistoryClient() {
+ return prepare(historyClient);
+ }
+
+ @NotNull
+ public RevertClient createRevertClient() {
+ return prepare(revertClient);
+ }
+
+ @NotNull
+ public SvnStatusClientI createStatusClient() {
+ // TODO: Update this in same like other clients - move to corresponding package, rename clients
+ return statusClient;
+ }
+
+ @NotNull
+ public DeleteClient createDeleteClient() {
+ return prepare(deleteClient);
+ }
+
+ @NotNull
+ public CopyMoveClient createCopyMoveClient() {
+ return prepare(copyMoveClient);
+ }
+
+ @NotNull
+ public ConflictClient createConflictClient() {
+ return prepare(conflictClient);
+ }
+
+ @NotNull
+ public PropertyClient createPropertyClient() {
+ return prepare(propertyClient);
+ }
+
+ @NotNull
+ protected <T extends SvnClient> T prepare(@NotNull T client) {
+ client.setVcs(myVcs);
+
+ return client;
+ }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/CmdClientFactory.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/CmdClientFactory.java
new file mode 100644
index 000000000000..ca4088b6a733
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/CmdClientFactory.java
@@ -0,0 +1,38 @@
+package org.jetbrains.idea.svn.api;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.idea.svn.SvnVcs;
+import org.jetbrains.idea.svn.add.CmdAddClient;
+import org.jetbrains.idea.svn.annotate.CmdAnnotateClient;
+import org.jetbrains.idea.svn.commandLine.SvnCommandLineStatusClient;
+import org.jetbrains.idea.svn.conflict.CmdConflictClient;
+import org.jetbrains.idea.svn.content.CmdContentClient;
+import org.jetbrains.idea.svn.copy.CmdCopyMoveClient;
+import org.jetbrains.idea.svn.delete.CmdDeleteClient;
+import org.jetbrains.idea.svn.history.CmdHistoryClient;
+import org.jetbrains.idea.svn.properties.CmdPropertyClient;
+import org.jetbrains.idea.svn.revert.CmdRevertClient;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class CmdClientFactory extends ClientFactory {
+
+ public CmdClientFactory(@NotNull SvnVcs vcs) {
+ super(vcs);
+ }
+
+ @Override
+ protected void setup() {
+ addClient = new CmdAddClient();
+ annotateClient = new CmdAnnotateClient();
+ contentClient = new CmdContentClient();
+ historyClient = new CmdHistoryClient();
+ revertClient = new CmdRevertClient();
+ deleteClient = new CmdDeleteClient();
+ copyMoveClient = new CmdCopyMoveClient();
+ conflictClient = new CmdConflictClient();
+ propertyClient = new CmdPropertyClient();
+ statusClient = new SvnCommandLineStatusClient(myVcs.getProject());
+ }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/FileStatusResultParser.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/FileStatusResultParser.java
new file mode 100644
index 000000000000..fc202c265a6a
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/FileStatusResultParser.java
@@ -0,0 +1,68 @@
+package org.jetbrains.idea.svn.api;
+
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vcs.VcsException;
+import com.intellij.util.containers.Convertor;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.tmatesoft.svn.core.SVNException;
+import org.tmatesoft.svn.core.wc.ISVNEventHandler;
+import org.tmatesoft.svn.core.wc.SVNEvent;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class FileStatusResultParser {
+
+ private static final double DEFAULT_PROGRESS = 0.0;
+
+ @NotNull
+ private Pattern myLinePattern;
+
+ @Nullable
+ private ISVNEventHandler handler;
+
+ @NotNull
+ private Convertor<Matcher, SVNEvent> myConvertor;
+
+ public FileStatusResultParser(@NotNull Pattern linePattern,
+ @Nullable ISVNEventHandler handler,
+ @NotNull Convertor<Matcher, SVNEvent> convertor) {
+ myLinePattern = linePattern;
+ this.handler = handler;
+ myConvertor = convertor;
+ }
+
+ public void parse(@NotNull String output) throws VcsException {
+ if (StringUtil.isEmpty(output)) {
+ return;
+ }
+
+ for (String line : StringUtil.splitByLines(output)) {
+ onLine(line);
+ }
+ }
+
+ public void onLine(@NotNull String line) throws VcsException {
+ Matcher matcher = myLinePattern.matcher(line);
+ if (matcher.matches()) {
+ process(matcher);
+ }
+ else {
+ throw new VcsException("unknown state on line " + line);
+ }
+ }
+
+ public void process(@NotNull Matcher matcher) throws VcsException {
+ if (handler != null) {
+ try {
+ handler.handleEvent(myConvertor.convert(matcher), DEFAULT_PROGRESS);
+ } catch (SVNException e) {
+ throw new VcsException(e);
+ }
+ }
+ }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/SvnClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/SvnClient.java
new file mode 100644
index 000000000000..90124f1cccb6
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/SvnClient.java
@@ -0,0 +1,15 @@
+package org.jetbrains.idea.svn.api;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.idea.svn.SvnVcs;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public interface SvnClient {
+
+ @NotNull
+ SvnVcs getVcs();
+
+ void setVcs(@NotNull SvnVcs vcs);
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/SvnKitClientFactory.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/SvnKitClientFactory.java
new file mode 100644
index 000000000000..7e1951893969
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/SvnKitClientFactory.java
@@ -0,0 +1,38 @@
+package org.jetbrains.idea.svn.api;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.idea.svn.SvnVcs;
+import org.jetbrains.idea.svn.add.SvnKitAddClient;
+import org.jetbrains.idea.svn.annotate.SvnKitAnnotateClient;
+import org.jetbrains.idea.svn.conflict.SvnKitConflictClient;
+import org.jetbrains.idea.svn.content.SvnKitContentClient;
+import org.jetbrains.idea.svn.copy.SvnKitCopyMoveClient;
+import org.jetbrains.idea.svn.delete.SvnKitDeleteClient;
+import org.jetbrains.idea.svn.history.SvnKitHistoryClient;
+import org.jetbrains.idea.svn.portable.SvnkitSvnStatusClient;
+import org.jetbrains.idea.svn.properties.SvnKitPropertyClient;
+import org.jetbrains.idea.svn.revert.SvnKitRevertClient;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class SvnKitClientFactory extends ClientFactory {
+
+ public SvnKitClientFactory(@NotNull SvnVcs vcs) {
+ super(vcs);
+ }
+
+ @Override
+ protected void setup() {
+ addClient = new SvnKitAddClient();
+ annotateClient = new SvnKitAnnotateClient();
+ contentClient = new SvnKitContentClient();
+ historyClient = new SvnKitHistoryClient();
+ revertClient = new SvnKitRevertClient();
+ deleteClient = new SvnKitDeleteClient();
+ copyMoveClient = new SvnKitCopyMoveClient();
+ conflictClient = new SvnKitConflictClient();
+ propertyClient = new SvnKitPropertyClient();
+ statusClient = new SvnkitSvnStatusClient(myVcs.createStatusClient());
+ }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/DefaultConfigLoader.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/DefaultConfigLoader.java
index 021568aac806..2b779fd0de70 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/DefaultConfigLoader.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/DefaultConfigLoader.java
@@ -49,7 +49,7 @@ public class DefaultConfigLoader {
final SvnVcs vcs = SvnVcs.getInstance(project);
File rootFile = new File(vcsRoot.getPath());
- final SVNInfo info = vcs.createWCClient().doInfo(rootFile, SVNRevision.UNDEFINED);
+ final SVNInfo info = vcs.getInfo(rootFile);
if (info == null || info.getURL() == null) {
LOG.info("Directory is not a working copy: " + vcsRoot.getPresentableUrl());
return null;
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/SvnBranchConfigurationNew.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/SvnBranchConfigurationNew.java
index 28e74e7c395e..483bfda7cfd3 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/SvnBranchConfigurationNew.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/branchConfig/SvnBranchConfigurationNew.java
@@ -223,9 +223,8 @@ public class SvnBranchConfigurationNew {
private BranchRootSearcher(final SvnVcs vcs, final VirtualFile root) throws SVNException {
myRoot = root;
myBranchesUnder = new HashMap<String, String>();
- final SVNWCClient client = vcs.createWCClient();
- final SVNInfo info = client.doInfo(new File(myRoot.getPath()), SVNRevision.UNDEFINED);
- myRootUrl = info.getURL();
+ final SVNInfo info = vcs.getInfo(myRoot.getPath());
+ myRootUrl = info != null ? info.getURL() : null;
}
public boolean accept(final String url) throws SVNException {
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/IdeaCommitHandler.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/IdeaCommitHandler.java
index 3bd8256e7b02..5ac6b967777e 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/IdeaCommitHandler.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/IdeaCommitHandler.java
@@ -16,8 +16,8 @@
package org.jetbrains.idea.svn.checkin;
import com.intellij.openapi.progress.ProgressIndicator;
-import org.jetbrains.idea.svn.CommitEventHandler;
-import org.jetbrains.idea.svn.CommitEventType;
+import org.jetbrains.idea.svn.commandLine.CommitEventHandler;
+import org.jetbrains.idea.svn.commandLine.CommitEventType;
import org.jetbrains.idea.svn.SvnBundle;
import java.io.File;
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/IdeaSvnkitBasedAuthenticationCallback.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/IdeaSvnkitBasedAuthenticationCallback.java
index 995646f50d45..f765595745b3 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/IdeaSvnkitBasedAuthenticationCallback.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/IdeaSvnkitBasedAuthenticationCallback.java
@@ -28,6 +28,7 @@ import com.intellij.util.net.HttpConfigurable;
import com.intellij.util.proxy.CommonProxy;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.*;
+import org.jetbrains.idea.svn.commandLine.AuthenticationCallback;
import org.tmatesoft.svn.core.*;
import org.tmatesoft.svn.core.auth.*;
import org.tmatesoft.svn.core.internal.util.SVNBase64;
@@ -77,6 +78,20 @@ public class IdeaSvnkitBasedAuthenticationCallback implements AuthenticationCall
return new CredentialsAuthenticator(myVcs).tryAuthenticate(realm, url, file, previousFailed, passwordRequest);
}
+ @Nullable
+ @Override
+ public SVNAuthentication requestCredentials(@Nullable SVNURL url, String type) {
+ SVNAuthentication authentication =
+ url != null ? myVcs.getSvnConfiguration().getInteractiveManager(myVcs).getProvider().requestClientAuthentication(
+ type, url, url.toDecodedString(), null, null, true) : null;
+
+ if (authentication == null) {
+ LOG.warn("Could not get authentication. Type - " + type + ", Url - " + url);
+ }
+
+ return authentication;
+ }
+
@Override
public boolean acceptSSLServerCertificate(final File file, final String realm) {
final File base = getExistingParent(file);
@@ -354,7 +369,9 @@ public class IdeaSvnkitBasedAuthenticationCallback implements AuthenticationCall
}, new ThrowableRunnable<SVNException>() {
@Override
public void run() throws SVNException {
+ // NOTE: DO NOT replace this call - SSL authentication highly tied to SVNKit
myVcs.createWCClient(active).doInfo(myUrl, SVNRevision.UNDEFINED, SVNRevision.HEAD);
+ //myVcs.getInfo(myUrl, SVNRevision.HEAD, active);
}
}
);
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/SvnCheckinEnvironment.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/SvnCheckinEnvironment.java
index 433e4063e02c..c7d2d4b41bf2 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/SvnCheckinEnvironment.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/SvnCheckinEnvironment.java
@@ -48,8 +48,8 @@ import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.*;
+import org.jetbrains.idea.svn.commandLine.SvnBindClient;
import org.jetbrains.idea.svn.commandLine.SvnCommandLineStatusClient;
-import org.tigris.subversion.javahl.ClientException;
import org.tmatesoft.svn.core.*;
import org.tmatesoft.svn.core.wc.*;
@@ -177,7 +177,7 @@ public class SvnCheckinEnvironment implements CheckinEnvironment {
if (committables.isEmpty()) {
return;
}
- if (WorkingCopyFormat.ONE_DOT_SEVEN.equals(format) &&
+ if (WorkingCopyFormat.ONE_DOT_EIGHT.equals(format) || WorkingCopyFormat.ONE_DOT_SEVEN.equals(format) &&
SvnConfiguration.UseAcceleration.commandLine.equals(SvnConfiguration.getInstance(mySvnVcs.getProject()).myUseAcceleration) &&
(SvnAuthenticationManager.HTTP.equals(url.getProtocol()) || SvnAuthenticationManager.HTTPS.equals(url.getProtocol()))) {
doWithCommandLine(committables, comment, exception, feedback);
@@ -256,14 +256,25 @@ public class SvnCheckinEnvironment implements CheckinEnvironment {
});
final IdeaSvnkitBasedAuthenticationCallback authenticationCallback = new IdeaSvnkitBasedAuthenticationCallback(mySvnVcs);
try {
- final SvnBindClient client = new SvnBindClient(SvnApplicationSettings.getInstance().getCommandLinePath());
+ final SvnBindClient client = new SvnBindClient(SvnApplicationSettings.getInstance().getCommandLinePath(), new Convertor<String[], SVNURL>() {
+ @Override
+ public SVNURL convert(String[] o) {
+ SVNInfo info = o.length > 0 ? mySvnVcs.getInfo(o[0]) : null;
+
+ if (info == null || info.getURL() == null) {
+ LOG.warn("Could not resolve repository url for commit. Paths - " + Arrays.toString(o));
+ }
+
+ return info != null ? info.getURL() : null;
+ }
+ });
client.setAuthenticationCallback(authenticationCallback);
client.setHandler(new IdeaCommitHandler(ProgressManager.getInstance().getProgressIndicator()));
final long revision = client.commit(ArrayUtil.toStringArray(paths), comment, false, false);
reportCommittedRevisions(feedback, String.valueOf(revision));
}
- catch (ClientException e) {
- exception.add(new VcsException(e));
+ catch (VcsException e) {
+ exception.add(e);
} finally {
authenticationCallback.reset();
}
@@ -348,25 +359,19 @@ public class SvnCheckinEnvironment implements CheckinEnvironment {
private List<File> getCommitables(List<File> paths) {
final Adder adder = new Adder();
- SVNStatusClient statusClient = mySvnVcs.createStatusClient();
for (File path : paths) {
File file = path.getAbsoluteFile();
adder.add(file);
if (file.getParentFile() != null) {
- addParents(statusClient, file.getParentFile(), adder);
+ addParents(file.getParentFile(), adder);
}
}
return adder.getResult();
}
- private static void addParents(SVNStatusClient statusClient, File file, final Adder adder) {
- SVNStatus status;
- try {
- status = statusClient.doStatus(file, false);
- }
- catch (SVNException e) {
- return;
- }
+ private void addParents(File file, final Adder adder) {
+ SVNStatus status = getStatus(file);
+
if (status != null &&
(SvnVcs.svnStatusIs(status, SVNStatusType.STATUS_ADDED) ||
SvnVcs.svnStatusIs(status, SVNStatusType.STATUS_REPLACED))) {
@@ -374,11 +379,33 @@ public class SvnCheckinEnvironment implements CheckinEnvironment {
adder.add(file);
file = file.getParentFile();
if (file != null) {
- addParents(statusClient, file, adder);
+ addParents(file, adder);
}
}
}
+ private SVNStatus getStatus(File file) {
+ SVNStatus result = null;
+ WorkingCopyFormat format = mySvnVcs.getWorkingCopyFormat(file);
+
+ try {
+ result = WorkingCopyFormat.ONE_DOT_EIGHT.equals(format) ? getStatusCommandLine(file) : getStatusSvnKit(file);
+ }
+ catch (SVNException e) {
+ // do nothing
+ }
+
+ return result;
+ }
+
+ private SVNStatus getStatusSvnKit(File file) throws SVNException {
+ return mySvnVcs.createStatusClient().doStatus(file, false);
+ }
+
+ private SVNStatus getStatusCommandLine(File file) throws SVNException {
+ return new SvnCommandLineStatusClient(mySvnVcs.getProject()).doStatus(file, false);
+ }
+
private static List<File> collectPaths(final List<Change> changes) {
// case sensitive..
ArrayList<File> result = new ArrayList<File>();
@@ -418,15 +445,14 @@ public class SvnCheckinEnvironment implements CheckinEnvironment {
public List<VcsException> scheduleMissingFileForDeletion(List<FilePath> filePaths) {
List<VcsException> exceptions = new ArrayList<VcsException>();
- final SVNWCClient wcClient = mySvnVcs.createWCClient();
-
List<File> files = ChangesUtil.filePathsToFiles(filePaths);
+
for (File file : files) {
try {
- wcClient.doDelete(file, true, false);
+ mySvnVcs.getFactory(file).createDeleteClient().delete(file, true);
}
- catch (SVNException e) {
- exceptions.add(new VcsException(e));
+ catch (VcsException e) {
+ exceptions.add(e);
}
}
@@ -434,30 +460,22 @@ public class SvnCheckinEnvironment implements CheckinEnvironment {
}
public List<VcsException> scheduleUnversionedFilesForAddition(List<VirtualFile> files) {
- final List<VcsException> result = new ArrayList<VcsException>();
- final SVNWCClient wcClient = mySvnVcs.createWCClient();
-
- final List<SVNException> exceptionList = scheduleUnversionedFilesForAddition(wcClient, files);
- for (SVNException svnException : exceptionList) {
- result.add(new VcsException(svnException));
- }
- return result;
+ return scheduleUnversionedFilesForAddition(mySvnVcs, files);
}
- public static List<SVNException> scheduleUnversionedFilesForAddition(SVNWCClient wcClient, List<VirtualFile> files) {
- return scheduleUnversionedFilesForAddition(wcClient, files, false);
+ public static List<VcsException> scheduleUnversionedFilesForAddition(@NotNull SvnVcs vcs, List<VirtualFile> files) {
+ return scheduleUnversionedFilesForAddition(vcs, files, false);
}
- public static List<SVNException> scheduleUnversionedFilesForAddition(SVNWCClient wcClient, List<VirtualFile> files, final boolean recursive) {
- List<SVNException> exceptions = new ArrayList<SVNException>();
-
+ public static List<VcsException> scheduleUnversionedFilesForAddition(@NotNull SvnVcs vcs, List<VirtualFile> files, final boolean recursive) {
Collections.sort(files, FilePathComparator.getInstance());
- wcClient.setEventHandler(new ISVNEventHandler() {
+ ISVNEventHandler eventHandler = new ISVNEventHandler() {
@Override
public void handleEvent(SVNEvent event, double progress) throws SVNException {
final ProgressManager pm = ProgressManager.getInstance();
final ProgressIndicator pi = pm.getProgressIndicator();
+ // TODO: pi is null here when invoking "Add" action
if (pi != null && event.getFile() != null) {
File file = event.getFile();
pi.setText(SvnBundle.message("progress.text2.adding", file.getName() + " (" + file.getParent() + ")"));
@@ -472,12 +490,18 @@ public class SvnCheckinEnvironment implements CheckinEnvironment {
if (pi.isCanceled()) throw new SVNCancelException();
}
}
- });
+ };
+
+ List<VcsException> exceptions = new ArrayList<VcsException>();
+
for (VirtualFile file : files) {
try {
- wcClient.doAdd(new File(FileUtil.toSystemDependentName(file.getPath())), true, false, true, recursive);
+ File convertedFile = new File(FileUtil.toSystemDependentName(file.getPath()));
+ SVNDepth depth = recursive ? SVNDepth.INFINITY : SVNDepth.EMPTY;
+
+ vcs.getFactory(convertedFile).createAddClient().add(convertedFile, depth, true, false, true, eventHandler);
}
- catch (SVNException e) {
+ catch (VcsException e) {
exceptions.add(e);
}
}
diff --git a/plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/AuthenticationCallback.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/AuthenticationCallback.java
index bdc9c2deb03c..1944749f3608 100644
--- a/plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/AuthenticationCallback.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/AuthenticationCallback.java
@@ -13,9 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.jetbrains.idea.svn;
+package org.jetbrains.idea.svn.commandLine;
import org.jetbrains.annotations.Nullable;
+import org.tmatesoft.svn.core.SVNURL;
+import org.tmatesoft.svn.core.auth.SVNAuthentication;
import java.io.File;
import java.io.IOException;
@@ -51,6 +53,17 @@ public interface AuthenticationCallback {
boolean authenticateFor(@Nullable String realm, File base, boolean previousFailed, boolean passwordRequest);
/**
+ * Provides authentication information to access given url by authentication protocol identified by type.
+ * For instance, username/password for http/svn protocols. SSL client certificate for two way SSL protocol.
+ *
+ * @param url url to item in repository
+ * @param type authentication protocol type with svn specific values, like "svn.simple" for http.
+ * @return
+ */
+ @Nullable
+ SVNAuthentication requestCredentials(@Nullable SVNURL url, String type);
+
+ /**
* @return config directory if TMP was created
*/
@Nullable
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandUtil.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandUtil.java
new file mode 100644
index 000000000000..737d8a85b60b
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandUtil.java
@@ -0,0 +1,218 @@
+package org.jetbrains.idea.svn.commandLine;
+
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vcs.VcsException;
+import com.intellij.util.ArrayUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.SvnApplicationSettings;
+import org.jetbrains.idea.svn.SvnVcs;
+import org.jetbrains.idea.svn.api.FileStatusResultParser;
+import org.jetbrains.idea.svn.checkin.IdeaSvnkitBasedAuthenticationCallback;
+import org.tmatesoft.svn.core.*;
+import org.tmatesoft.svn.core.wc.SVNDiffOptions;
+import org.tmatesoft.svn.core.wc.SVNInfo;
+import org.tmatesoft.svn.core.wc.SVNRevision;
+import org.tmatesoft.svn.core.wc.SVNStatusType;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class CommandUtil {
+ public static SvnLineCommand runSimple(@NotNull SvnCommandName name,
+ @NotNull SvnVcs vcs,
+ @Nullable File base,
+ @Nullable SVNURL url,
+ List<String> parameters)
+ throws SVNException {
+ String exe = resolveExePath();
+ base = resolveBaseDirectory(base, exe);
+ url = resolveRepositoryUrl(vcs, url);
+
+ try {
+ return SvnLineCommand
+ .runWithAuthenticationAttempt(exe, base, url, name, new SvnCommitRunner.CommandListener(null),
+ new IdeaSvnkitBasedAuthenticationCallback(vcs), ArrayUtil.toStringArray(parameters));
+ }
+ catch (SvnBindException e) {
+ throw new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_ERROR, e), e);
+ }
+ }
+
+ @Nullable
+ private static SVNURL resolveRepositoryUrl(@NotNull SvnVcs vcs, @Nullable SVNURL url) {
+ if (url == null) {
+ // TODO: or take it from RootUrlInfo
+ SVNInfo info = vcs.getInfo(vcs.getProject().getBaseDir());
+
+ url = info != null ? info.getURL() : null;
+ }
+ return url;
+ }
+
+ @NotNull
+ private static File resolveBaseDirectory(@Nullable File base, @NotNull String defaultBase) {
+ return base == null ? new File(defaultBase) : base;
+ }
+
+ @NotNull
+ private static String resolveExePath() {
+ return SvnApplicationSettings.getInstance().getCommandLinePath();
+ }
+
+ public static SvnLineCommand runSimple(@NotNull SvnSimpleCommand command, @NotNull SvnVcs vcs, @Nullable File base, @Nullable SVNURL url)
+ throws SVNException {
+ // empty command name passed, as command name is already in command.getParameters()
+ return runSimple(SvnCommandName.empty, vcs, base, url, new ArrayList<String>(Arrays.asList(command.getParameters())));
+ }
+
+ /**
+ * Puts given value to parameters if condition is satisfied
+ *
+ * @param parameters
+ * @param condition
+ * @param value
+ */
+ public static void put(@NotNull List<String> parameters, boolean condition, @NotNull String value) {
+ if (condition) {
+ parameters.add(value);
+ }
+ }
+
+ public static void put(@NotNull List<String> parameters, @NotNull File path) {
+ parameters.add(path.getAbsolutePath());
+ }
+
+ public static void put(@NotNull List<String> parameters, @NotNull File path, @Nullable SVNRevision pegRevision) {
+ put(parameters, path.getAbsolutePath(), pegRevision);
+ }
+
+ public static void put(@NotNull List<String> parameters, @NotNull String path, @Nullable SVNRevision pegRevision) {
+ StringBuilder builder = new StringBuilder(path);
+
+ if (pegRevision != null && !SVNRevision.UNDEFINED.equals(pegRevision) && !SVNRevision.WORKING.equals(pegRevision) &&
+ pegRevision.getNumber() > 0) {
+ builder.append("@");
+ builder.append(pegRevision);
+ }
+
+ parameters.add(builder.toString());
+ }
+
+ public static void put(@NotNull List<String> parameters, @NotNull File... paths) {
+ for (File path : paths) {
+ put(parameters, path);
+ }
+ }
+
+ public static void put(@NotNull List<String> parameters, @Nullable SVNDepth depth) {
+ if (depth != null && !SVNDepth.UNKNOWN.equals(depth)) {
+ parameters.add("--depth");
+ parameters.add(depth.getName());
+ }
+ }
+
+ public static void put(@NotNull List<String> parameters, @Nullable SVNRevision revision) {
+ if (revision != null && !SVNRevision.UNDEFINED.equals(revision) && !SVNRevision.WORKING.equals(revision) && revision.getNumber() >= 0) {
+ parameters.add("--revision");
+ parameters.add(revision.toString());
+ }
+ }
+
+ public static void put(@NotNull List<String> parameters, @Nullable SVNDiffOptions diffOptions) {
+ if (diffOptions != null) {
+ StringBuilder builder = new StringBuilder();
+
+ if (diffOptions.isIgnoreAllWhitespace()) {
+ builder.append(" --ignore-space-change");
+ }
+ if (diffOptions.isIgnoreAmountOfWhitespace()) {
+ builder.append(" --ignore-all-space");
+ }
+ if (diffOptions.isIgnoreEOLStyle()) {
+ builder.append(" --ignore-eol-style");
+ }
+
+ String value = builder.toString().trim();
+
+ if (!StringUtil.isEmpty(value)) {
+ parameters.add("--extensions");
+ parameters.add(value);
+ }
+ }
+ }
+
+ /**
+ * Utility method for running commands changing certain file status information.
+ * // TODO: Should be replaced with non-static analogue.
+ *
+ * @param vcs
+ * @param name
+ * @param parameters
+ * @param parser
+ * @throws VcsException
+ */
+ public static SvnCommand execute(@NotNull SvnVcs vcs,
+ @NotNull SvnCommandName name,
+ @NotNull List<String> parameters,
+ @Nullable FileStatusResultParser parser)
+ throws VcsException {
+ String exe = resolveExePath();
+ File base = resolveBaseDirectory(null, exe);
+ SVNURL url = resolveRepositoryUrl(vcs, null);
+
+ SvnLineCommand command = SvnLineCommand.runWithAuthenticationAttempt(
+ exe, base, url, name, new SvnCommitRunner.CommandListener(null),
+ new IdeaSvnkitBasedAuthenticationCallback(vcs),
+ ArrayUtil.toStringArray(parameters));
+
+ if (parser != null) {
+ parser.parse(command.getOutput());
+ }
+
+ return command;
+ }
+
+ /**
+ * Gets svn status represented by single character.
+ *
+ * @param type
+ * @return
+ */
+ public static char getStatusChar(@Nullable String type) {
+ return !StringUtil.isEmpty(type) ? type.charAt(0) : ' ';
+ }
+
+ @NotNull
+ public static SVNStatusType getStatusType(@Nullable String type) {
+ return getStatusType(getStatusChar(type));
+ }
+
+ @NotNull
+ public static SVNStatusType getStatusType(char first) {
+ final SVNStatusType contentsStatus;
+ if ('A' == first) {
+ contentsStatus = SVNStatusType.STATUS_ADDED;
+ } else if ('D' == first) {
+ contentsStatus = SVNStatusType.STATUS_DELETED;
+ } else if ('U' == first) {
+ contentsStatus = SVNStatusType.CHANGED;
+ } else if ('C' == first) {
+ contentsStatus = SVNStatusType.CONFLICTED;
+ } else if ('G' == first) {
+ contentsStatus = SVNStatusType.MERGED;
+ } else if ('R' == first) {
+ contentsStatus = SVNStatusType.STATUS_REPLACED;
+ } else if ('E' == first) {
+ contentsStatus = SVNStatusType.STATUS_OBSTRUCTED;
+ } else {
+ contentsStatus = SVNStatusType.STATUS_NORMAL;
+ }
+ return contentsStatus;
+ }
+}
diff --git a/plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/CommitEventHandler.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommitEventHandler.java
index 7f3bcf3bf4a5..d74884073863 100644
--- a/plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/CommitEventHandler.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommitEventHandler.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.jetbrains.idea.svn;
+package org.jetbrains.idea.svn.commandLine;
import java.io.File;
diff --git a/plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/CommitEventType.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommitEventType.java
index 46609e40532c..87dc212d0341 100644
--- a/plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/CommitEventType.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommitEventType.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.jetbrains.idea.svn;
+package org.jetbrains.idea.svn.commandLine;
/**
* Created with IntelliJ IDEA.
diff --git a/plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/commandLine/LineCommandListener.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/LineCommandListener.java
index ccbc5c37db61..ccbc5c37db61 100644
--- a/plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/commandLine/LineCommandListener.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/LineCommandListener.java
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnBindClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnBindClient.java
new file mode 100644
index 000000000000..8f14cb269179
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnBindClient.java
@@ -0,0 +1,67 @@
+/*
+ * 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 org.jetbrains.idea.svn.commandLine;
+
+import com.intellij.openapi.vcs.VcsException;
+import com.intellij.util.containers.Convertor;
+import org.tmatesoft.svn.core.SVNURL;
+
+import java.util.Map;
+
+/**
+ * Created with IntelliJ IDEA.
+ * User: Irina.Chernushina
+ * Date: 2/5/13
+ * Time: 3:08 PM
+ */
+public class SvnBindClient {
+ private final String myExecutablePath;
+ private CommitEventHandler myHandler;
+ private AuthenticationCallback myAuthenticationCallback;
+ private Convertor<String[], SVNURL> myUrlProvider;
+
+ public SvnBindClient(String path, Convertor<String[], SVNURL> urlProvider) {
+ myExecutablePath = path;
+ myUrlProvider = urlProvider;
+ }
+
+ public long commit(String[] path, String message, boolean recurse, boolean noUnlock) throws VcsException {
+ return commit(path, message, recurse? 3 : 0, noUnlock, false, null, null);
+ }
+
+ public long commit(String[] path,
+ String message,
+ int depth,
+ boolean noUnlock,
+ boolean keepChangelist,
+ String[] changelists,
+ Map revpropTable) throws VcsException {
+ final long commit = new SvnCommitRunner(myExecutablePath, myHandler, myAuthenticationCallback).
+ commit(path, message, depth, noUnlock, keepChangelist, changelists, revpropTable, myUrlProvider);
+ if (commit < 0) {
+ throw new VcsException("Wrong committed revision number: " + commit);
+ }
+ return commit;
+ }
+
+ public void setHandler(CommitEventHandler handler) {
+ myHandler = handler;
+ }
+
+ public void setAuthenticationCallback(AuthenticationCallback authenticationCallback) {
+ myAuthenticationCallback = authenticationCallback;
+ }
+}
diff --git a/plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/config/SvnBindException.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnBindException.java
index 8957843e911c..524b928eae92 100644
--- a/plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/config/SvnBindException.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnBindException.java
@@ -13,12 +13,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.jetbrains.idea.svn.config;
+package org.jetbrains.idea.svn.commandLine;
import com.intellij.openapi.vcs.VcsException;
-import java.util.Collection;
-
/**
* Created with IntelliJ IDEA.
* User: Irina.Chernushina
@@ -32,23 +30,7 @@ public class SvnBindException extends VcsException {
super(message);
}
- public SvnBindException(Throwable throwable, boolean isWarning) {
- super(throwable, isWarning);
- }
-
public SvnBindException(Throwable throwable) {
super(throwable);
}
-
- public SvnBindException(String message, Throwable cause) {
- super(message, cause);
- }
-
- public SvnBindException(String message, boolean isWarning) {
- super(message, isWarning);
- }
-
- public SvnBindException(Collection<String> messages) {
- super(messages);
- }
}
diff --git a/plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/SvnBindUtil.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnBindUtil.java
index 1fec6b3bf865..7d663bae65b5 100644
--- a/plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/SvnBindUtil.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnBindUtil.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.jetbrains.idea.svn;
+package org.jetbrains.idea.svn.commandLine;
import java.io.File;
import java.text.DateFormat;
@@ -31,16 +31,7 @@ import java.util.Locale;
* Time: 4:56 PM
*/
public class SvnBindUtil {
- /**
- * SVN_ASP_DOT_NET_HACK allows use of an alternate name for Subversion working copy
- * administrative directories on Windows (which were formerly always
- * named ".svn"), by setting the SVN_ASP_DOT_NET_HACK environment variable.
- * When the variable is set (to any value), the administrative directory
- * will be "_svn" instead of ".svn".
- *
- * http://svn.apache.org/repos/asf/subversion/trunk/notes/asp-dot-net-hack.txt
- */
- public static final String ADM_NAME = System.getenv("SVN_ASP_DOT_NET_HACK") != null ? "_svn" : ".svn";
+
private final static List<DateFormat> ourFormats = new ArrayList<DateFormat>();
static {
@@ -88,17 +79,4 @@ public class SvnBindUtil {
}
return null;
}
-
- public static File getWcRoot(File base) {
- File current = base;
- while (current != null) {
- if (getWcDbUnder(current).exists()) return current;
- current = current.getParentFile();
- }
- return null;
- }
-
- public static File getWcDbUnder(final File file) {
- return new File(file, ADM_NAME + File.separator + "wc.db");
- }
}
diff --git a/plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/commandLine/SvnCommand.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommand.java
index d6df6bae947e..9e355e56f4d6 100644
--- a/plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/commandLine/SvnCommand.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommand.java
@@ -16,6 +16,7 @@
package org.jetbrains.idea.svn.commandLine;
import com.intellij.execution.configurations.GeneralCommandLine;
+import com.intellij.execution.process.CapturingProcessAdapter;
import com.intellij.execution.process.OSProcessHandler;
import com.intellij.execution.process.ProcessEvent;
import com.intellij.execution.process.ProcessListener;
@@ -38,6 +39,7 @@ import java.util.List;
*/
public abstract class SvnCommand {
static final Logger LOG = Logger.getInstance(SvnCommand.class.getName());
+ private final File myConfigDir;
private boolean myIsDestroyed;
private int myExitCode;
@@ -45,13 +47,13 @@ public abstract class SvnCommand {
private final File myWorkingDirectory;
private Process myProcess;
private OSProcessHandler myHandler;
+ // TODO: Try to implement commands in a way that they manually indicate if they need full output - to prevent situations
+ // TODO: when large amount of data needs to be stored instead of just sequential processing.
+ private CapturingProcessAdapter outputAdapter;
private final Object myLock;
private final EventDispatcher<ProcessEventListener> myListeners = EventDispatcher.create(ProcessEventListener.class);
-
- // todo check version
- /*c:\Program Files (x86)\CollabNet\Subversion Client17>svn --version --quiet
- 1.7.2*/
+ private final SvnCommandName myCommandName;
public SvnCommand(File workingDirectory, @NotNull SvnCommandName commandName, @NotNull @NonNls String exePath) {
this(workingDirectory, commandName, exePath, null);
@@ -59,15 +61,34 @@ public abstract class SvnCommand {
public SvnCommand(File workingDirectory, @NotNull SvnCommandName commandName, @NotNull @NonNls String exePath,
@Nullable File configDir) {
+ myCommandName = commandName;
myLock = new Object();
myCommandLine = new GeneralCommandLine();
myWorkingDirectory = workingDirectory;
myCommandLine.setExePath(exePath);
myCommandLine.setWorkDirectory(workingDirectory);
+ myConfigDir = configDir;
if (configDir != null) {
myCommandLine.addParameters("--config-dir", configDir.getPath());
}
- myCommandLine.addParameter(commandName.getName());
+ if (!SvnCommandName.empty.equals(commandName)) {
+ myCommandLine.addParameter(commandName.getName());
+ }
+ }
+
+ public String[] getParameters() {
+ synchronized (myLock) {
+ return myCommandLine.getParametersList().getArray();
+ }
+ }
+
+ /**
+ * Indicates if process was destroyed "manually" by command execution logic.
+ *
+ * @return
+ */
+ public boolean isManuallyDestroyed() {
+ return myIsDestroyed;
}
public void start() {
@@ -112,10 +133,16 @@ public abstract class SvnCommand {
}
};
+ outputAdapter = new CapturingProcessAdapter();
+ myHandler.addProcessListener(outputAdapter);
myHandler.addProcessListener(processListener);
myHandler.startNotify();
}
+ public String getOutput() {
+ return outputAdapter.getOutput().getStdout();
+ }
+
/**
* Wait for process termination
* @param timeout
@@ -186,6 +213,18 @@ public abstract class SvnCommand {
}
}
+ public String getCommandText() {
+ synchronized (myLock) {
+ return myCommandLine.getCommandLineString();
+ }
+ }
+
+ public String getExePath() {
+ synchronized (myLock) {
+ return myCommandLine.getExePath();
+ }
+ }
+
/**
* check that process is not started yet
*
@@ -226,4 +265,8 @@ public abstract class SvnCommand {
protected File getWorkingDirectory() {
return myWorkingDirectory;
}
+
+ public SvnCommandName getCommandName() {
+ return myCommandName;
+ }
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineInfoClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineInfoClient.java
index 0d2f4d00bd39..47b6b5234396 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineInfoClient.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineInfoClient.java
@@ -15,12 +15,13 @@
*/
package org.jetbrains.idea.svn.commandLine;
+import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vfs.CharsetToolkit;
import com.intellij.util.Consumer;
-import org.jetbrains.idea.svn.SvnBindUtil;
+import org.jetbrains.idea.svn.SvnApplicationSettings;
import org.jetbrains.idea.svn.SvnVcs;
import org.jetbrains.idea.svn.portable.SvnExceptionWrapper;
import org.jetbrains.idea.svn.portable.SvnkitSvnWcClient;
@@ -36,7 +37,9 @@ import javax.xml.parsers.SAXParserFactory;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.Collection;
+import java.util.List;
/**
* Created with IntelliJ IDEA.
@@ -45,9 +48,12 @@ import java.util.Collection;
* Time: 12:59 PM
*/
public class SvnCommandLineInfoClient extends SvnkitSvnWcClient {
+
+ private static final Logger LOG = Logger.getInstance("#org.jetbrains.idea.svn.commandLine.SvnCommandLineInfoClient");
private final Project myProject;
public SvnCommandLineInfoClient(final Project project) {
+ // TODO: Remove svn kit client instantiation
super(SvnVcs.getInstance(project).createWCClient());
myProject = project;
}
@@ -74,22 +80,56 @@ public class SvnCommandLineInfoClient extends SvnkitSvnWcClient {
base = SvnBindUtil.correctUpToExistingParent(base);
if (base == null) {
// very unrealistic
- throw new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_ERROR), new RuntimeException("Can not find existing parent file"));
+ throw new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_ERROR, "Can not find existing parent file"));
}
+ issueCommand(path.getAbsolutePath(), pegRevision, revision, depth, changeLists, handler, base);
+ }
+
+ private void issueCommand(String path, SVNRevision pegRevision,
+ SVNRevision revision,
+ SVNDepth depth,
+ Collection changeLists,
+ final ISVNInfoHandler handler, File base) throws SVNException {
final SvnSimpleCommand command = SvnCommandFactory.createSimpleCommand(myProject, base, SvnCommandName.info);
+ List<String> parameters = new ArrayList<String>();
+
+ fillParameters(path, pegRevision, revision, depth, parameters);
+ command.addParameters(parameters);
+ SvnCommandLineStatusClient.changelistsToCommand(changeLists, command);
- if (depth != null) {
- command.addParameters("--depth", depth.getName());
+ parseResult(handler, base, execute(command));
+ }
+
+ private String execute(SvnSimpleCommand command) throws SVNException {
+ try {
+ return command.run();
}
- if (revision != null && ! SVNRevision.UNDEFINED.equals(revision) && ! SVNRevision.WORKING.equals(revision)) {
- command.addParameters("-r", revision.toString());
+ catch (VcsException e) {
+ final String text = e.getMessage();
+ final boolean notEmpty = !StringUtil.isEmptyOrSpaces(text);
+ if (notEmpty && text.contains("W155010")) {
+ // just null
+ return null;
+ }
+ // not a working copy exception
+ // "E155007: '' is not a working copy"
+ if (notEmpty && text.contains("is not a working copy")) {
+ if (StringUtil.isNotEmpty(command.getOutput())) {
+ // workaround: as in subversion 1.8 "svn info" on a working copy root outputs such error for parent folder,
+ // if there are files with conflicts.
+ // but the requested info is still in the output except root closing tag
+ return command.getOutput() + "</info>";
+ } else {
+ throw new SVNException(SVNErrorMessage.create(SVNErrorCode.WC_NOT_WORKING_COPY, e), e);
+ }
+ }
+ throw new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_ERROR, e), e);
}
- command.addParameters("--xml");
- SvnCommandLineStatusClient.changelistsToCommand(changeLists, command);
- if (pegRevision != null && ! SVNRevision.UNDEFINED.equals(pegRevision) && ! SVNRevision.WORKING.equals(pegRevision)) {
- command.addParameters(path.getPath() + "@" + pegRevision.toString());
- } else {
- command.addParameters(path.getPath());
+ }
+
+ private void parseResult(final ISVNInfoHandler handler, File base, String result) throws SVNException {
+ if (StringUtil.isEmpty(result)) {
+ return;
}
final SvnInfoHandler[] infoHandler = new SvnInfoHandler[1];
@@ -106,38 +146,34 @@ public class SvnCommandLineInfoClient extends SvnkitSvnWcClient {
});
try {
- final String result = command.run();
SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
- parser.parse(new ByteArrayInputStream(result.getBytes(CharsetToolkit.UTF8_CHARSET)), infoHandler[0]);
+ parser.parse(new ByteArrayInputStream(result.getBytes(CharsetToolkit.UTF8_CHARSET)), infoHandler[0]);
}
catch (SvnExceptionWrapper e) {
+ LOG.info("info output " + result);
throw (SVNException) e.getCause();
} catch (IOException e) {
- throw new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_ERROR), e);
+ LOG.info("info output " + result);
+ throw new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_ERROR, e), e);
}
catch (ParserConfigurationException e) {
- throw new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_ERROR), e);
+ LOG.info("info output " + result);
+ throw new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_ERROR, e), e);
}
catch (SAXException e) {
- throw new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_ERROR), e);
- }
- catch (VcsException e) {
- final String text = e.getMessage();
- final boolean notEmpty = !StringUtil.isEmptyOrSpaces(text);
- if (notEmpty && text.contains("W155010")) {
- // just null
- return;
- }
- // not a working copy exception
- // "E155007: '' is not a working copy"
- if (notEmpty && text.contains("is not a working copy")) {
- throw new SVNException(SVNErrorMessage.create(SVNErrorCode.WC_NOT_WORKING_COPY), e);
- }
- throw new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_ERROR), e);
+ LOG.info("info output " + result);
+ throw new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_ERROR, e), e);
}
}
+ private void fillParameters(String path, SVNRevision pegRevision, SVNRevision revision, SVNDepth depth, List<String> parameters) {
+ CommandUtil.put(parameters, depth);
+ CommandUtil.put(parameters, revision);
+ CommandUtil.put(parameters, path, pegRevision);
+ parameters.add("--xml");
+ }
+
@Override
public void doInfo(SVNURL url, SVNRevision pegRevision, SVNRevision revision, boolean recursive, ISVNInfoHandler handler)
throws SVNException {
@@ -147,7 +183,14 @@ public class SvnCommandLineInfoClient extends SvnkitSvnWcClient {
@Override
public void doInfo(SVNURL url, SVNRevision pegRevision, SVNRevision revision, SVNDepth depth, ISVNInfoHandler handler)
throws SVNException {
- throw new UnsupportedOperationException();
+ String path = url.toDecodedString();
+ List<String> parameters = new ArrayList<String>();
+
+ fillParameters(path, pegRevision, revision, depth, parameters);
+ File base = new File(SvnApplicationSettings.getInstance().getCommandLinePath());
+ String result = CommandUtil.runSimple(SvnCommandName.info, SvnVcs.getInstance(myProject), base, url, parameters).getOutput();
+
+ parseResult(handler, base, result);
}
@Override
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineStatusClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineStatusClient.java
index a1a31536c8a9..c1429be699af 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineStatusClient.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineStatusClient.java
@@ -15,14 +15,16 @@
*/
package org.jetbrains.idea.svn.commandLine;
+import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Getter;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vfs.CharsetToolkit;
import com.intellij.util.containers.Convertor;
-import org.jetbrains.idea.svn.SvnBindUtil;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.svn.SvnUtil;
+import org.jetbrains.idea.svn.SvnVcs;
import org.jetbrains.idea.svn.portable.PortableStatus;
import org.jetbrains.idea.svn.portable.SvnExceptionWrapper;
import org.jetbrains.idea.svn.portable.SvnStatusClientI;
@@ -48,6 +50,8 @@ import java.util.Map;
* Time: 5:21 PM
*/
public class SvnCommandLineStatusClient implements SvnStatusClientI {
+ private static final Logger LOG = Logger.getInstance("#org.jetbrains.idea.svn.commandLine.SvnCommandLineStatusClient");
+
private final Project myProject;
private final SvnCommandLineInfoClient myInfoClient;
@@ -102,47 +106,84 @@ public class SvnCommandLineStatusClient implements SvnStatusClientI {
final SVNInfo infoBase = myInfoClient.doInfo(base, revision);
final SvnSimpleCommand command = SvnCommandFactory.createSimpleCommand(myProject, base, SvnCommandName.st);
- putParameters(depth, remote, reportAll, includeIgnored, changeLists, command);
+ putParameters(path, depth, remote, reportAll, includeIgnored, changeLists, command);
+
+ parseResult(path, revision, handler, base, infoBase, command, execute(command, base));
+ return 0;
+ }
+
+ private String execute(SvnSimpleCommand command, File base) throws SVNException {
+ String result = CommandUtil.runSimple(command, SvnVcs.getInstance(myProject), base, null).getOutput();
- final SvnStatusHandler[] svnHandl = new SvnStatusHandler[1];
- svnHandl[0] = createStatusHandler(revision, handler, base, infoBase, svnHandl);
+ if (StringUtil.isEmptyOrSpaces(result)) {
+ throw new SVNException(SVNErrorMessage.create(SVNErrorCode.FS_GENERAL, "Status request returned nothing for command: " +
+ command.myCommandLine.getCommandLineString()));
+ }
+
+ return result;
+ }
+
+ private void parseResult(final File path,
+ SVNRevision revision,
+ ISVNStatusHandler handler,
+ File base,
+ SVNInfo infoBase,
+ SvnSimpleCommand command, String result) throws SVNException {
+
+ if (StringUtil.isEmpty(result)) {
+ return;
+ }
try {
- final String result = command.run();
- if (StringUtil.isEmptyOrSpaces(result)) {
- throw new VcsException("Status request returned nothing for command: " + command.myCommandLine.getCommandLineString());
- }
+ final SvnStatusHandler[] svnHandl = new SvnStatusHandler[1];
+ svnHandl[0] = createStatusHandler(revision, handler, base, infoBase, svnHandl);
SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
parser.parse(new ByteArrayInputStream(result.getBytes(CharsetToolkit.UTF8_CHARSET)), svnHandl[0]);
- if (! svnHandl[0].isAnythingReported()) {
- if (! SvnUtil.isSvnVersioned(myProject, path)) {
- throw new SVNException(SVNErrorMessage.create(SVNErrorCode.WC_NOT_DIRECTORY));
+ if (!svnHandl[0].isAnythingReported()) {
+ if (!SvnUtil.isSvnVersioned(myProject, path)) {
+ throw new SVNException(
+ SVNErrorMessage.create(SVNErrorCode.WC_NOT_DIRECTORY, "Command - " + command.getCommandText() + ". Result - " + result));
+ } else {
+ // return status indicating "NORMAL" state
+ // typical output would be like
+ // <status>
+ // <target path="1.txt"></target>
+ // </status>
+ // so it does not contain any <entry> element and current parsing logic returns null
+
+ PortableStatus status = new PortableStatus();
+ status.setPath(path.getAbsolutePath());
+ status.setContentsStatus(SVNStatusType.STATUS_NORMAL);
+ status.setInfoGetter(new Getter<SVNInfo>() {
+ @Override
+ public SVNInfo get() {
+ return createInfoGetter(null).convert(path);
+ }
+ });
+ handler.handleStatus(status);
}
}
}
catch (SvnExceptionWrapper e) {
throw (SVNException) e.getCause();
} catch (IOException e) {
- throw new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_ERROR), e);
+ throw new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_ERROR, e), e);
}
catch (ParserConfigurationException e) {
- throw new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_ERROR), e);
+ throw new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_ERROR, e), e);
}
catch (SAXException e) {
- throw new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_ERROR), e);
- }
- catch (VcsException e) {
- throw new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_ERROR), e);
+ throw new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_ERROR, e), e);
}
- return 0;
}
- private void putParameters(SVNDepth depth,
+ private void putParameters(@NotNull File path, SVNDepth depth,
boolean remote,
boolean reportAll,
boolean includeIgnored,
Collection changeLists,
SvnSimpleCommand command) {
+ command.addParameters(path.getAbsolutePath());
if (depth != null) {
command.addParameters("--depth", depth.getName());
}
@@ -171,7 +212,11 @@ public class SvnCommandLineStatusClient implements SvnStatusClientI {
final SVNInfo infoBase, final SvnStatusHandler[] svnHandl) {
final SvnStatusHandler.ExternalDataCallback callback = createStatusCallback(handler, base, infoBase, svnHandl);
- return new SvnStatusHandler(callback, base, new Convertor<File, SVNInfo>() {
+ return new SvnStatusHandler(callback, base, createInfoGetter(revision));
+ }
+
+ private Convertor<File, SVNInfo> createInfoGetter(final SVNRevision revision) {
+ return new Convertor<File, SVNInfo>() {
@Override
public SVNInfo convert(File o) {
try {
@@ -181,7 +226,7 @@ public class SvnCommandLineStatusClient implements SvnStatusClientI {
throw new SvnExceptionWrapper(e);
}
}
- });
+ };
}
public static SvnStatusHandler.ExternalDataCallback createStatusCallback(final ISVNStatusHandler handler,
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineUpdateClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineUpdateClient.java
index c0e9c8e79fa2..e0834c2f116f 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineUpdateClient.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandLineUpdateClient.java
@@ -24,7 +24,6 @@ import com.intellij.util.ArrayUtil;
import org.jetbrains.idea.svn.SvnApplicationSettings;
import org.jetbrains.idea.svn.SvnVcs;
import org.jetbrains.idea.svn.checkin.IdeaSvnkitBasedAuthenticationCallback;
-import org.jetbrains.idea.svn.config.SvnBindException;
import org.jetbrains.idea.svn.portable.SvnSvnkitUpdateClient;
import org.tmatesoft.svn.core.*;
import org.tmatesoft.svn.core.wc.*;
@@ -49,9 +48,9 @@ public class SvnCommandLineUpdateClient extends SvnSvnkitUpdateClient {
private final VirtualFile myCommonAncestor;
private boolean myIgnoreExternals;
- public SvnCommandLineUpdateClient(final Project project, VirtualFile commonAncestor) {
- super(SvnVcs.getInstance(project).createUpdateClient());
- myProject = project;
+ public SvnCommandLineUpdateClient(final SvnVcs vcs, VirtualFile commonAncestor) {
+ super(vcs.createUpdateClient());
+ myProject = vcs.getProject();
myCommonAncestor = commonAncestor;
}
@@ -88,35 +87,7 @@ public class SvnCommandLineUpdateClient extends SvnSvnkitUpdateClient {
File base = myCommonAncestor == null ? paths[0] : new File(myCommonAncestor.getPath());
base = base.isDirectory() ? base : base.getParentFile();
- final List<String> parameters = new ArrayList<String>();
- if (revision != null && ! SVNRevision.UNDEFINED.equals(revision) && ! SVNRevision.WORKING.equals(revision)) {
- parameters.add("-r");
- parameters.add(revision.toString());
- }
- // unknown depth is not used any more for 1.7 -> why?
- if (depth != null && ! SVNDepth.UNKNOWN.equals(depth)) {
- parameters.add("--depth");
- parameters.add(depth.toString());
- }
- if (allowUnversionedObstructions) {
- parameters.add("--force");
- }
- if (depthIsSticky && depth != null) {// !!! not sure, but not used
- parameters.add("--set-depth");
- parameters.add(depth.toString());
- }
- if (makeParents) {
- parameters.add("--parents");
- }
- if (myIgnoreExternals) {
- parameters.add("--ignore-externals");
- }
- parameters.add("--accept");
- parameters.add("postpone");
-
- for (File path : paths) {
- parameters.add(path.getPath());
- }
+ final List<String> parameters = prepareParameters(paths, revision, depth, allowUnversionedObstructions, depthIsSticky, makeParents);
final AtomicReference<SVNException> excRef = new AtomicReference<SVNException>();
final ISVNEventHandler handler = getEventHandler();
@@ -166,7 +137,7 @@ public class SvnCommandLineUpdateClient extends SvnSvnkitUpdateClient {
}
};
SvnLineCommand.runWithAuthenticationAttempt(SvnApplicationSettings.getInstance().getCommandLinePath(),
- base, SvnCommandName.up, listener,
+ base, info.getURL(), SvnCommandName.up, listener,
new IdeaSvnkitBasedAuthenticationCallback(SvnVcs.getInstance(myProject)),
ArrayUtil.toStringArray(parameters));
}
@@ -180,6 +151,29 @@ public class SvnCommandLineUpdateClient extends SvnSvnkitUpdateClient {
return updatedToRevision.get();
}
+ private List<String> prepareParameters(File[] paths,
+ SVNRevision revision,
+ SVNDepth depth,
+ boolean allowUnversionedObstructions,
+ boolean depthIsSticky, boolean makeParents) {
+ List<String> parameters = new ArrayList<String>();
+
+ CommandUtil.put(parameters, revision);
+ CommandUtil.put(parameters, depth);
+ CommandUtil.put(parameters, allowUnversionedObstructions, "--force");
+ if (depthIsSticky && depth != null) {// !!! not sure, but not used
+ parameters.add("--set-depth");
+ parameters.add(depth.toString());
+ }
+ CommandUtil.put(parameters, makeParents, "--parents");
+ CommandUtil.put(parameters, myIgnoreExternals, "--ignore-externals");
+ parameters.add("--accept");
+ parameters.add("postpone");
+ CommandUtil.put(parameters, paths);
+
+ return parameters;
+ }
+
private void checkForException(final StringBuffer sbError) throws SVNException {
if (sbError.length() == 0) return;
diff --git a/plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/commandLine/SvnCommandName.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandName.java
index 58c2ff2ab308..c19ea283bbd1 100644
--- a/plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/commandLine/SvnCommandName.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommandName.java
@@ -22,13 +22,25 @@ package org.jetbrains.idea.svn.commandLine;
* Time: 1:49 PM
*/
public enum SvnCommandName {
+ // TODO: temporary command for "more smooth" converting between simple commands and line commands
+ empty("", false),
version("--version", false),
info("info", false),
st("st", false),
up("up", true),
ci("commit", true),
- cleanup("cleanup", true);
-
+ cleanup("cleanup", true),
+ cat("cat", false),
+ add("add", true),
+ log("log", false),
+ revert("revert", true),
+ delete("delete", true),
+ copy("copy", true),
+ move("move", true),
+ resolve("resolve", true),
+ propget("propget", false),
+ blame("blame", false);
+
private final String myName;
private final boolean myWriteable;
diff --git a/plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/SvnCommitRunner.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommitRunner.java
index 525d675303fc..83f6ec156cf1 100644
--- a/plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/SvnCommitRunner.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnCommitRunner.java
@@ -13,22 +13,19 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.jetbrains.idea.svn;
+package org.jetbrains.idea.svn.commandLine;
import com.intellij.execution.process.ProcessOutputTypes;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vcs.VcsException;
import com.intellij.util.ArrayUtil;
+import com.intellij.util.containers.Convertor;
import org.apache.subversion.javahl.types.Revision;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import org.jetbrains.idea.svn.commandLine.LineCommandListener;
-import org.jetbrains.idea.svn.commandLine.SvnCommandName;
-import org.jetbrains.idea.svn.commandLine.SvnLineCommand;
-import org.jetbrains.idea.svn.config.SvnBindException;
-import org.tigris.subversion.javahl.BindClientException;
-import org.tigris.subversion.javahl.ClientException;
+import org.tmatesoft.svn.core.SVNURL;
import java.io.File;
import java.util.*;
@@ -42,7 +39,7 @@ import java.util.*;
public class SvnCommitRunner {
private final String myExePath;
@Nullable private final AuthenticationCallback myAuthenticationCallback;
- private static final Logger LOG = Logger.getInstance("org.jetbrains.idea.svn.SvnCommitRunner");
+ private static final Logger LOG = Logger.getInstance("org.jetbrains.idea.svn.commandLine.SvnCommitRunner");
private SvnCommitRunner.CommandListener myCommandListener;
public SvnCommitRunner(@NotNull String path, @Nullable CommitEventHandler handler, @Nullable AuthenticationCallback authenticationCallback) {
@@ -57,7 +54,7 @@ public class SvnCommitRunner {
boolean noUnlock,
boolean keepChangelist,
String[] changelists,
- Map revpropTable) throws ClientException {
+ Map revpropTable, Convertor<String[], SVNURL> urlProvider) throws VcsException {
if (paths.length == 0) return Revision.SVN_INVALID_REVNUM;
final List<String> parameters = new ArrayList<String>();
@@ -84,19 +81,14 @@ public class SvnCommitRunner {
Arrays.sort(paths);
parameters.addAll(Arrays.asList(paths));
- try {
- SvnLineCommand.runWithAuthenticationAttempt(myExePath, new File(paths[0]), SvnCommandName.ci,
- myCommandListener, myAuthenticationCallback, ArrayUtil.toStringArray(parameters));
- }
- catch (SvnBindException e) {
- throw BindClientException.create(e, Revision.SVN_INVALID_REVNUM);
- }
+ SvnLineCommand.runWithAuthenticationAttempt(myExePath, new File(paths[0]), urlProvider.convert(paths), SvnCommandName.ci,
+ myCommandListener, myAuthenticationCallback, ArrayUtil.toStringArray(parameters));
myCommandListener.throwExceptionIfOccurred();
return myCommandListener.getCommittedRevision();
}
- private static class CommandListener extends LineCommandListener {
+ public static class CommandListener extends LineCommandListener {
@Nullable private final CommitEventHandler myHandler;
private SvnBindException myException;
private long myCommittedRevision = Revision.SVN_INVALID_REVNUM;
@@ -106,9 +98,9 @@ public class SvnCommitRunner {
myHandler = handler;
}
- public void throwExceptionIfOccurred() throws BindClientException {
+ public void throwExceptionIfOccurred() throws VcsException {
if (myException != null) {
- throw BindClientException.create(myException, Revision.SVN_INVALID_REVNUM);
+ throw myException;
}
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnInfoHandler.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnInfoHandler.java
index 022130e4a9f6..d8dbb6c19f67 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnInfoHandler.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnInfoHandler.java
@@ -18,6 +18,7 @@ package org.jetbrains.idea.svn.commandLine;
import com.intellij.openapi.util.Getter;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.Consumer;
+import org.jetbrains.annotations.NotNull;
import org.tmatesoft.svn.core.SVNDepth;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNNodeKind;
@@ -49,7 +50,7 @@ public class SvnInfoHandler extends DefaultHandler {
public SvnInfoHandler(File base, final Consumer<SVNInfo> infoConsumer) {
myBase = base;
myInfoConsumer = infoConsumer;
- myPending = new SvnInfoStructure();
+ myPending = createPending();
myElementsMap = new HashMap<String, Getter<ElementHandlerBase>>();
fillElements();
myParseStack = new ArrayList<ElementHandlerBase>();
@@ -70,7 +71,14 @@ public class SvnInfoHandler extends DefaultHandler {
myInfoConsumer.consume(info);
}
myResultsMap.put(info.getFile(), info);
- myPending = new SvnInfoStructure();
+ myPending = createPending();
+ }
+
+ private SvnInfoStructure createPending() {
+ SvnInfoStructure pending = new SvnInfoStructure();
+ pending.myDepth = SVNDepth.INFINITY;
+
+ return pending;
}
@Override
@@ -90,16 +98,13 @@ public class SvnInfoHandler extends DefaultHandler {
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
assertSAX(! myParseStack.isEmpty());
ElementHandlerBase current = myParseStack.get(myParseStack.size() - 1);
- if (mySb.length() > 0) {
- current.characters(mySb.toString().trim(), myPending);
- mySb.setLength(0);
- }
while (true) {
final boolean createNewChild = current.startElement(uri, localName, qName, attributes);
if (createNewChild) {
assertSAX(myElementsMap.containsKey(qName));
final ElementHandlerBase newChild = myElementsMap.get(qName).get();
+ newChild.setParent(current);
newChild.updateInfo(attributes, myPending);
myParseStack.add(newChild);
return;
@@ -116,6 +121,18 @@ public class SvnInfoHandler extends DefaultHandler {
}
@Override
+ public void endElement(String uri, String localName, String qName) throws SAXException {
+ ElementHandlerBase current = myParseStack.get(myParseStack.size() - 1);
+ String value = mySb.toString().trim();
+
+ if (!StringUtil.isEmpty(value)) {
+ current.characters(value, myPending);
+ }
+
+ mySb.setLength(0);
+ }
+
+ @Override
public void characters(char[] ch, int start, int length) throws SAXException {
assertSAX(! myParseStack.isEmpty());
mySb.append(ch, start, length);
@@ -252,6 +269,24 @@ public class SvnInfoHandler extends DefaultHandler {
return new Url();
}
});
+ myElementsMap.put("relative-url", new Getter<ElementHandlerBase>() {
+ @Override
+ public ElementHandlerBase get() {
+ return new RelativeUrl();
+ }
+ });
+ myElementsMap.put("lock", new Getter<ElementHandlerBase>() {
+ @Override
+ public ElementHandlerBase get() {
+ return new Lock();
+ }
+ });
+ myElementsMap.put("created", new Getter<ElementHandlerBase>() {
+ @Override
+ public ElementHandlerBase get() {
+ return new Date();
+ }
+ });
myElementsMap.put("uuid", new Getter<ElementHandlerBase>() {
@Override
public ElementHandlerBase get() {
@@ -270,6 +305,18 @@ public class SvnInfoHandler extends DefaultHandler {
return new WcInfo();
}
});
+ myElementsMap.put("moved-to", new Getter<ElementHandlerBase>() {
+ @Override
+ public ElementHandlerBase get() {
+ return new MovedPath();
+ }
+ });
+ myElementsMap.put("moved-from", new Getter<ElementHandlerBase>() {
+ @Override
+ public ElementHandlerBase get() {
+ return new MovedPath();
+ }
+ });
myElementsMap.put("wcroot-abspath", new Getter<ElementHandlerBase>() {
@Override
public ElementHandlerBase get() {
@@ -295,6 +342,12 @@ public class SvnInfoHandler extends DefaultHandler {
@Override
protected void updateInfo(Attributes attributes, SvnInfoStructure structure) throws SAXException {
+ // TODO: Currently information for conflict (not tree-conflict) available in svn 1.8 is not used
+ // TODO: And it also not suite well for SVNKit api
+ if (getParent() instanceof Conflict) {
+ return;
+ }
+
final String side = attributes.getValue("side");
if ("source-left".equals(side)) {
final SvnInfoStructure.ConflictVersion conflictVersion = new SvnInfoStructure.ConflictVersion();
@@ -382,7 +435,7 @@ public class SvnInfoHandler extends DefaultHandler {
@Override
public void characters(String s, SvnInfoStructure structure) throws SAXException {
- structure.myConflictWorking = s;
+ structure.myConflictNew = new File(s).getName();
}
}
@@ -397,7 +450,7 @@ public class SvnInfoHandler extends DefaultHandler {
@Override
public void characters(String s, SvnInfoStructure structure) throws SAXException {
- structure.myConflictNew = s;
+ structure.myConflictWorking = new File(s).getName();
}
}
@@ -412,14 +465,13 @@ public class SvnInfoHandler extends DefaultHandler {
@Override
public void characters(String s, SvnInfoStructure structure) throws SAXException {
- // todo path? or plus base
- structure.myConflictOld = s;
+ structure.myConflictOld = new File(s).getName();
}
}
private static class Conflict extends ElementHandlerBase {
private Conflict() {
- super(new String[]{"prev-base-file","prev-wc-file","cur-base-file","prop-file"}, new String[]{});
+ super(new String[]{"prev-base-file","prev-wc-file","cur-base-file","prop-file"}, new String[]{"version"});
}
@Override
@@ -498,6 +550,25 @@ public class SvnInfoHandler extends DefaultHandler {
}
}
+ /**
+ * "moved-from" and "moved-to" elements are represented by this class.
+ */
+ private static class MovedPath extends ElementHandlerBase {
+
+ private MovedPath() {
+ super(new String[]{}, new String[]{});
+ }
+
+ @Override
+ protected void updateInfo(Attributes attributes, SvnInfoStructure structure) throws SAXException {
+ }
+
+ @Override
+ public void characters(String s, SvnInfoStructure structure) throws SAXException {
+ // TODO: is there some field to initialize from this value?
+ }
+ }
+
private static class TextUpdated extends ElementHandlerBase {
private TextUpdated() {
super(new String[]{}, new String[]{});
@@ -617,7 +688,7 @@ public class SvnInfoHandler extends DefaultHandler {
private static class WcInfo extends ElementHandlerBase {
private WcInfo() {
super(new String[]{"wcroot-abspath", "schedule", "depth", "text-updated", "checksum", "changelist", "copy-from-url",
- "copy-from-rev"}, new String[]{});
+ "copy-from-rev", "moved-to", "moved-from"}, new String[]{});
}
@Override
@@ -698,11 +769,34 @@ public class SvnInfoHandler extends DefaultHandler {
}
}
+ private static class RelativeUrl extends Url{
+ @Override
+ public void characters(String s, SvnInfoStructure structure) throws SAXException {
+ structure.relativeUrl = s;
+ }
+ }
+
+ private static class Lock extends ElementHandlerBase {
+ private Lock() {
+ super(new String[]{"created"}, new String[]{});
+ }
+
+ @Override
+ protected void updateInfo(Attributes attributes, SvnInfoStructure structure) throws SAXException {
+ // TODO:
+ }
+
+ @Override
+ public void characters(String s, SvnInfoStructure structure) throws SAXException {
+ // TODO:
+ }
+ }
+
private static class Entry extends ElementHandlerBase {
private final File myBase;
private Entry(final File base) {
- super(new String[]{"url","repository","wc-info","commit","conflict","tree-conflict"}, new String[]{});
+ super(new String[]{"url", "relative-url", "lock", "repository","wc-info","commit","conflict","tree-conflict"}, new String[]{});
myBase = base;
}
@@ -763,12 +857,22 @@ public class SvnInfoHandler extends DefaultHandler {
private abstract static class ElementHandlerBase {
private final Set<String> myAwaitedChildren;
private final Set<String> myAwaitedChildrenMultiple;
+ private ElementHandlerBase parent;
ElementHandlerBase(String[] awaitedChildren, String[] awaitedChildrenMultiple) {
myAwaitedChildren = new HashSet<String>(Arrays.asList(awaitedChildren));
myAwaitedChildrenMultiple = new HashSet<String>(Arrays.asList(awaitedChildrenMultiple));
}
+ @NotNull
+ public ElementHandlerBase getParent() {
+ return parent;
+ }
+
+ public void setParent(@NotNull ElementHandlerBase parent) {
+ this.parent = parent;
+ }
+
protected abstract void updateInfo(Attributes attributes, SvnInfoStructure structure) throws SAXException;
public boolean startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnInfoStructure.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnInfoStructure.java
index 0292b7d93614..1aa5248c1939 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnInfoStructure.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnInfoStructure.java
@@ -34,6 +34,7 @@ import java.util.Date;
*/
public class SvnInfoStructure {
public File myFile;
+ public String relativeUrl;
public SVNURL myUrl;
public SVNURL myRootURL;
public long myRevision;
diff --git a/plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/commandLine/SvnLineCommand.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnLineCommand.java
index 5821d7a5fb18..c5e3b9e6861c 100644
--- a/plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/commandLine/SvnLineCommand.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnLineCommand.java
@@ -23,20 +23,30 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.LineHandlerHelper;
import com.intellij.openapi.vcs.LineProcessEventListener;
import com.intellij.openapi.vcs.VcsException;
+import com.intellij.util.ArrayUtil;
import com.intellij.util.EventDispatcher;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import org.jetbrains.idea.svn.AuthenticationCallback;
-import org.jetbrains.idea.svn.SvnBindUtil;
-import org.jetbrains.idea.svn.config.SvnBindException;
+import org.jetbrains.idea.svn.SvnUtil;
+import org.tmatesoft.svn.core.SVNException;
+import org.tmatesoft.svn.core.SVNURL;
+import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
+import org.tmatesoft.svn.core.auth.SVNAuthentication;
+import org.tmatesoft.svn.core.auth.SVNPasswordAuthentication;
+import org.tmatesoft.svn.core.auth.SVNSSLAuthentication;
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Iterator;
+import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
/**
* Created with IntelliJ IDEA.
@@ -47,11 +57,21 @@ import java.util.concurrent.atomic.AtomicReference;
* honestly stolen from GitLineHandler
*/
public class SvnLineCommand extends SvnCommand {
+
public static final String AUTHENTICATION_REALM = "Authentication realm:";
public static final String CERTIFICATE_ERROR = "Error validating server certificate for";
public static final String PASSPHRASE_FOR = "Passphrase for";
public static final String UNABLE_TO_CONNECT = "svn: E170001:";
public static final String CANNOT_AUTHENTICATE_TO_PROXY = "Could not authenticate to proxy server";
+ public static final String AUTHENTICATION_FAILED_MESSAGE = "Authentication failed";
+
+ private static final String INVALID_CREDENTIALS_FOR_SVN_PROTOCOL = "svn: E170001: Can't get";
+ private static final String UNTRUSTED_SERVER_CERTIFICATE = "Server SSL certificate untrusted";
+ private static final String ACCESS_TO_PREFIX = "Access to ";
+ private static final String FORBIDDEN_STATUS = "forbidden";
+ private static final String PASSWORD_STRING = "password";
+
+ private static final Pattern UNABLE_TO_CONNECT_TO_URL_PATTERN = Pattern.compile("Unable to connect to a repository at URL '(.*)'");
// kept for exact text
//public static final String CLIENT_CERTIFICATE_FILENAME = "Client certificate filename:";
@@ -66,6 +86,7 @@ public class SvnLineCommand extends SvnCommand {
private final EventDispatcher<LineProcessEventListener> myLineListeners;
private final AtomicReference<Integer> myExitCode;
private final StringBuffer myErr;
+ private final StringBuffer myStdOut;
public SvnLineCommand(File workingDirectory, @NotNull SvnCommandName commandName, @NotNull @NonNls String exePath) {
this(workingDirectory, commandName, exePath, null);
@@ -76,6 +97,7 @@ public class SvnLineCommand extends SvnCommand {
myLineListeners = EventDispatcher.create(LineProcessEventListener.class);
myExitCode = new AtomicReference<Integer>();
myErr = new StringBuffer();
+ myStdOut = new StringBuffer();
}
@Override
@@ -89,13 +111,14 @@ public class SvnLineCommand extends SvnCommand {
}
}
- public static void runWithAuthenticationAttempt(final String exePath,
- final File firstFile,
- SvnCommandName commandName,
- final LineCommandListener listener,
- @Nullable AuthenticationCallback authenticationCallback,
- final String... parameters) throws SvnBindException {
- File base = firstFile.isDirectory() ? firstFile : firstFile.getParentFile();
+ public static SvnLineCommand runWithAuthenticationAttempt(final String exePath,
+ final File firstFile,
+ final SVNURL url,
+ SvnCommandName commandName,
+ final LineCommandListener listener,
+ @Nullable AuthenticationCallback authenticationCallback,
+ String... parameters) throws SvnBindException {
+ File base = firstFile != null ? (firstFile.isDirectory() ? firstFile : firstFile.getParentFile()) : null;
base = SvnBindUtil.correctUpToExistingParent(base);
listener.baseDirectory(base);
@@ -111,27 +134,35 @@ public class SvnLineCommand extends SvnCommand {
while (true) {
final SvnLineCommand command = runCommand(exePath, commandName, listener, base, configDir, parameters);
- if (command.myErr.length() > 0) {
- final String errText = command.myErr.toString().trim();
- if (authenticationCallback != null) {
- final AuthCallbackCase callback = createCallback(errText, authenticationCallback, base);
- if (callback != null) {
- cleanup(exePath, commandName, base);
- if (callback.getCredentials(errText)) {
- if (authenticationCallback.getSpecialConfigDir() != null) {
- configDir = authenticationCallback.getSpecialConfigDir();
+ final Integer exitCode = command.myExitCode.get();
+
+ // could be situations when exit code = 0, but there is info "warning" in error stream
+ // for instance, for "svn status" on non-working copy folder
+ if (exitCode != 0) {
+ if (command.myErr.length() > 0) {
+ // handle authentication
+ final String errText = command.myErr.toString().trim();
+ if (authenticationCallback != null) {
+ final AuthCallbackCase callback = createCallback(errText, authenticationCallback, base, url);
+ if (callback != null) {
+ cleanup(exePath, command, base);
+ if (callback.getCredentials(errText)) {
+ if (authenticationCallback.getSpecialConfigDir() != null) {
+ configDir = authenticationCallback.getSpecialConfigDir();
+ }
+ parameters = updateParameters(callback, parameters);
+ continue;
}
- continue;
}
}
+ throw new SvnBindException(errText);
+ } else {
+ throw new SvnBindException("Svn process exited with error code: " + exitCode);
}
- throw new SvnBindException(errText);
+ } else if (command.myErr.length() > 0) {
+ LOG.info("Detected warning - " + command.myErr);
}
- final Integer exitCode = command.myExitCode.get();
- if (exitCode != 0) {
- throw new SvnBindException("Svn process exited with error code: " + exitCode);
- }
- return;
+ return command;
}
} finally {
if (authenticationCallback != null) {
@@ -140,6 +171,13 @@ public class SvnLineCommand extends SvnCommand {
}
}
+ private static String[] updateParameters(AuthCallbackCase callback, String[] parameters) {
+ List<String> p = new ArrayList<String>(Arrays.asList(parameters));
+
+ callback.updateParameters(p);
+ return ArrayUtil.toStringArray(p);
+ }
+
private static void writeIdeaConfig2SubversionConfig(@NotNull AuthenticationCallback authenticationCallback, @NotNull File base) throws SvnBindException {
if (authenticationCallback.haveDataForTmpConfig()) {
try {
@@ -158,7 +196,7 @@ public class SvnLineCommand extends SvnCommand {
}
}
- private static AuthCallbackCase createCallback(final String errText, final AuthenticationCallback callback, final File base) {
+ private static AuthCallbackCase createCallback(final String errText, final AuthenticationCallback callback, final File base, final SVNURL url) {
if (errText.startsWith(CERTIFICATE_ERROR)) {
return new CertificateCallbackCase(callback, base);
}
@@ -171,9 +209,85 @@ public class SvnLineCommand extends SvnCommand {
if (errText.startsWith(UNABLE_TO_CONNECT) && errText.contains(CANNOT_AUTHENTICATE_TO_PROXY)) {
return new ProxyCallback(callback, base);
}
+ // http/https protocol invalid credentials
+ if (errText.contains(AUTHENTICATION_FAILED_MESSAGE)) {
+ return new UsernamePasswordCallback(callback, base, url);
+ }
+ // messages could be "Can't get password", "Can't get username or password"
+ if (errText.contains(INVALID_CREDENTIALS_FOR_SVN_PROTOCOL) && errText.contains(PASSWORD_STRING)) {
+ // svn protocol invalid credentials
+ return new UsernamePasswordCallback(callback, base, url);
+ }
+ // https one-way protocol untrusted server certificate
+ if (errText.contains(UNTRUSTED_SERVER_CERTIFICATE)) {
+ return new CertificateCallbackCase(callback, base);
+ }
+ // https two-way protocol invalid client certificate
+ if (errText.contains(ACCESS_TO_PREFIX) && errText.contains(FORBIDDEN_STATUS)) {
+ return new TwoWaySslCallback(callback, base, url);
+ }
return null;
}
+ // Special callback for svn 1.8 credentials request as --non-interactive does not return
+ // authentication realm (just url) - so we could not create temp cache
+ private static class UsernamePasswordCallback extends AuthCallbackCase {
+ protected SVNAuthentication myAuthentication;
+ protected SVNURL myUrl;
+
+ protected UsernamePasswordCallback(AuthenticationCallback callback, File base, SVNURL url) {
+ super(callback, base);
+ myUrl = url;
+ }
+
+ @Override
+ boolean getCredentials(String errText) throws SvnBindException {
+ myAuthentication = myAuthenticationCallback.requestCredentials(myUrl != null ? myUrl : parseUrlFromError(errText),
+ getType());
+
+ return myAuthentication != null;
+ }
+
+ public String getType() {
+ return ISVNAuthenticationManager.PASSWORD;
+ }
+
+ @Override
+ public void updateParameters(List<String> parameters) {
+ if (myAuthentication instanceof SVNPasswordAuthentication) {
+ SVNPasswordAuthentication auth = (SVNPasswordAuthentication)myAuthentication;
+
+ parameters.add("--username");
+ parameters.add(auth.getUserName());
+ parameters.add("--password");
+ parameters.add(auth.getPassword());
+ if (!auth.isStorageAllowed()) {
+ parameters.add("--no-auth-cache");
+ }
+ }
+ }
+
+ private SVNURL parseUrlFromError(String errorText) {
+ Matcher matcher = UNABLE_TO_CONNECT_TO_URL_PATTERN.matcher(errorText);
+ String urlValue = null;
+
+ if (matcher.find()) {
+ urlValue = matcher.group(1);
+ }
+
+ return urlValue != null ? parseUrl(urlValue) : null;
+ }
+
+ private SVNURL parseUrl(String urlValue) {
+ try {
+ return SVNURL.parseURIEncoded(urlValue);
+ }
+ catch (SVNException e) {
+ return null;
+ }
+ }
+ }
+
private static class ProxyCallback extends AuthCallbackCase {
protected ProxyCallback(AuthenticationCallback callback, File base) {
super(callback, base);
@@ -192,7 +306,8 @@ public class SvnLineCommand extends SvnCommand {
@Override
boolean getCredentials(String errText) throws SvnBindException {
- final String realm = cutFirstLine(errText).substring(AUTHENTICATION_REALM.length()).trim();
+ final String realm =
+ errText.startsWith(AUTHENTICATION_REALM) ? cutFirstLine(errText).substring(AUTHENTICATION_REALM.length()).trim() : null;
final boolean isPassword = StringUtil.containsIgnoreCase(errText, "password");
if (myTried) {
myAuthenticationCallback.clearPassiveCredentials(realm, myBase, isPassword);
@@ -212,13 +327,16 @@ public class SvnLineCommand extends SvnCommand {
}
private static class CertificateCallbackCase extends AuthCallbackCase {
+ private boolean accepted;
+
private CertificateCallbackCase(AuthenticationCallback callback, File base) {
super(callback, base);
}
@Override
public boolean getCredentials(final String errText) throws SvnBindException {
- String realm = cutFirstLine(errText).substring(CERTIFICATE_ERROR.length());
+ // parse realm from error text
+ String realm = errText;
final int idx1 = realm.indexOf('\'');
if (idx1 == -1) {
throw new SvnBindException("Can not detect authentication realm name: " + errText);
@@ -229,11 +347,48 @@ public class SvnLineCommand extends SvnCommand {
}
realm = realm.substring(idx1 + 1, idx2);
if (! myTried && myAuthenticationCallback.acceptSSLServerCertificate(myBase, realm)) {
+ accepted = true;
myTried = true;
return true;
}
throw new SvnBindException("Server SSL certificate rejected");
}
+
+ @Override
+ public void updateParameters(List<String> parameters) {
+ if (accepted) {
+ parameters.add("--trust-server-cert");
+ }
+ }
+ }
+
+ private static class TwoWaySslCallback extends UsernamePasswordCallback {
+
+ protected TwoWaySslCallback(AuthenticationCallback callback, File base, SVNURL url) {
+ super(callback, base, url);
+ }
+
+ @Override
+ public String getType() {
+ return ISVNAuthenticationManager.SSL;
+ }
+
+ @Override
+ public void updateParameters(List<String> parameters) {
+ if (myAuthentication instanceof SVNSSLAuthentication) {
+ SVNSSLAuthentication auth = (SVNSSLAuthentication)myAuthentication;
+
+ // TODO: Seems that config option should be specified for concrete server and not for global group.
+ // as in that case it could be overriden by settings in config file
+ parameters.add("--config-option");
+ parameters.add("servers:global:ssl-client-cert-file=" + auth.getCertificatePath());
+ parameters.add("--config-option");
+ parameters.add("servers:global:ssl-client-cert-password=" + auth.getPassword());
+ if (!auth.isStorageAllowed()) {
+ parameters.add("--no-auth-cache");
+ }
+ }
+ }
}
private static abstract class AuthCallbackCase {
@@ -247,17 +402,23 @@ public class SvnLineCommand extends SvnCommand {
}
abstract boolean getCredentials(final String errText) throws SvnBindException;
+
+ public void updateParameters(List<String> parameters) {
+ }
}
- private static void cleanup(String exePath, SvnCommandName commandName, File base) throws SvnBindException {
- File wcRoot = SvnBindUtil.getWcRoot(base);
- if (wcRoot == null) throw new SvnBindException("Can not find working copy root for: " + base.getPath());
+ private static void cleanup(String exePath, SvnCommand command, File base) throws SvnBindException {
+ // TODO: could be issues with fake "empty" command as it is not writable - but only read commands currently use "empty" command
+ // TODO: and "empty" command will be removed shortly
+ if (command.isManuallyDestroyed() && command.getCommandName().isWriteable()) {
+ File wcRoot = SvnUtil.getWorkingCopyRootNew(base);
+ if (wcRoot == null) {
+ throw new SvnBindException("Can not find working copy root for: " + base.getPath());
+ }
- //cleanup -> check command type
- if (commandName.isWriteable()) {
- final SvnSimpleCommand command = new SvnSimpleCommand(wcRoot, SvnCommandName.cleanup, exePath);
+ final SvnSimpleCommand cleanupCommand = new SvnSimpleCommand(wcRoot, SvnCommandName.cleanup, exePath);
try {
- command.run();
+ cleanupCommand.run();
}
catch (VcsException e) {
throw new SvnBindException(e);
@@ -320,6 +481,10 @@ public class SvnLineCommand extends SvnCommand {
command.addLineListener(new LineProcessEventListener() {
@Override
public void onLineAvailable(String line, Key outputType) {
+ if (ProcessOutputTypes.STDOUT.equals(outputType)) {
+ command.myStdOut.append(line);
+ }
+
if (SvnCommand.LOG.isDebugEnabled()) {
SvnCommand.LOG.debug("==> " + line);
}
diff --git a/plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/commandLine/SvnSimpleCommand.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnSimpleCommand.java
index 75c43befb6cb..a088da0334a3 100644
--- a/plugins/svn4idea/bindSvn/src/org/jetbrains/idea/svn/commandLine/SvnSimpleCommand.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/SvnSimpleCommand.java
@@ -94,7 +94,11 @@ public class SvnSimpleCommand extends SvnCommand {
if (myException != null) throw myException;
final int code = getExitCode();
if (code == 0) {
- return myStdout.toString();
+ String result = myStdout.toString();
+
+ LOG.debug(result);
+
+ return result;
} else {
final String msg = new StringBuilder("Svn process exited with error code: ").append(code).append("\n")
.append("stderr: ").append(myStderr.toString()).append("\nstdout: ").append(getStdout().toString())
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/UpdateOutputLineConverter.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/UpdateOutputLineConverter.java
index 6536646374bd..8700c363f460 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/UpdateOutputLineConverter.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/UpdateOutputLineConverter.java
@@ -62,6 +62,8 @@ public class UpdateOutputLineConverter {
}
public SVNEvent convert(final String line) {
+ // TODO: Add direct processing of "Summary of conflicts" lines at the end of "svn update" output (if there are conflicts).
+ // TODO: Now it works ok because parseNormalLine could not determine necessary statuses from that and further lines
if (StringUtil.isEmptyOrSpaces(line)) return null;
if (line.startsWith(UPDATING)) {
@@ -103,9 +105,9 @@ public class UpdateOutputLineConverter {
if (line.length() < 5) return null;
final char first = line.charAt(0);
if (' ' != first && ! ourActions.contains(first)) return null;
- final SVNStatusType contentsStatus = getStatusType(first);
+ final SVNStatusType contentsStatus = CommandUtil.getStatusType(first);
final char second = line.charAt(1);
- final SVNStatusType propertiesStatus = getStatusType(second);
+ final SVNStatusType propertiesStatus = CommandUtil.getStatusType(second);
final char lock = line.charAt(2); // dont know what to do with stolen lock info
if (' ' != lock && 'B' != lock) return null;
final char treeConflict = line.charAt(3);
@@ -140,28 +142,6 @@ public class UpdateOutputLineConverter {
null, action, expectedAction, null, null, null, null, null);
}
- private SVNStatusType getStatusType(char first) {
- final SVNStatusType contentsStatus;
- if ('A' == first) {
- contentsStatus = SVNStatusType.STATUS_ADDED;
- } else if ('D' == first) {
- contentsStatus = SVNStatusType.STATUS_DELETED;
- } else if ('U' == first) {
- contentsStatus = SVNStatusType.CHANGED;
- } else if ('C' == first) {
- contentsStatus = SVNStatusType.CONFLICTED;
- } else if ('G' == first) {
- contentsStatus = SVNStatusType.MERGED;
- } else if ('R' == first) {
- contentsStatus = SVNStatusType.STATUS_REPLACED;
- } else if ('E' == first) {
- contentsStatus = SVNStatusType.STATUS_OBSTRUCTED;
- } else {
- contentsStatus = SVNStatusType.STATUS_NORMAL;
- }
- return contentsStatus;
- }
-
@Nullable
private long matchAndGetRevision(final Pattern pattern, final String line) {
final Matcher matcher = pattern.matcher(line);
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/conflict/CmdConflictClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/conflict/CmdConflictClient.java
new file mode 100644
index 000000000000..79614a24f554
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/conflict/CmdConflictClient.java
@@ -0,0 +1,33 @@
+package org.jetbrains.idea.svn.conflict;
+
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.idea.svn.api.BaseSvnClient;
+import org.jetbrains.idea.svn.commandLine.CommandUtil;
+import org.jetbrains.idea.svn.commandLine.SvnCommandName;
+import org.tmatesoft.svn.core.SVNDepth;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class CmdConflictClient extends BaseSvnClient implements ConflictClient {
+
+ // TODO: Add possibility to resolve content conflicts separately from property conflicts.
+ @Override
+ public void resolve(@NotNull File path, boolean resolvePropertyConflicts) throws VcsException {
+ List<String> parameters = new ArrayList<String>();
+
+ CommandUtil.put(parameters, path);
+ CommandUtil.put(parameters, SVNDepth.EMPTY);
+ parameters.add("--accept");
+ parameters.add("working");
+
+ // for now parsing of the output is not required as command is executed only for one file
+ // and will be either successful or exception will be thrown
+ CommandUtil.execute(myVcs, SvnCommandName.resolve, parameters, null);
+ }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/conflict/ConflictClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/conflict/ConflictClient.java
new file mode 100644
index 000000000000..812fdef5621b
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/conflict/ConflictClient.java
@@ -0,0 +1,15 @@
+package org.jetbrains.idea.svn.conflict;
+
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.idea.svn.api.SvnClient;
+
+import java.io.File;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public interface ConflictClient extends SvnClient {
+
+ void resolve(@NotNull File path, boolean resolvePropertyConflicts) throws VcsException;
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/conflict/SvnKitConflictClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/conflict/SvnKitConflictClient.java
new file mode 100644
index 000000000000..33ee0f870c95
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/conflict/SvnKitConflictClient.java
@@ -0,0 +1,25 @@
+package org.jetbrains.idea.svn.conflict;
+
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.idea.svn.api.BaseSvnClient;
+import org.tmatesoft.svn.core.SVNDepth;
+import org.tmatesoft.svn.core.SVNException;
+import org.tmatesoft.svn.core.wc.SVNConflictChoice;
+
+import java.io.File;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class SvnKitConflictClient extends BaseSvnClient implements ConflictClient {
+ @Override
+ public void resolve(@NotNull File path, boolean resolvePropertyConflicts) throws VcsException {
+ try {
+ myVcs.createWCClient().doResolve(path, SVNDepth.EMPTY, true, resolvePropertyConflicts, SVNConflictChoice.MERGED);
+ }
+ catch (SVNException e) {
+ throw new VcsException(e);
+ }
+ }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/content/CmdContentClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/content/CmdContentClient.java
new file mode 100644
index 000000000000..c822fe0a1f48
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/content/CmdContentClient.java
@@ -0,0 +1,39 @@
+package org.jetbrains.idea.svn.content;
+
+import com.intellij.openapi.vcs.VcsException;
+import com.intellij.openapi.vcs.impl.ContentRevisionCache;
+import com.intellij.openapi.vfs.CharsetToolkit;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.api.BaseSvnClient;
+import org.jetbrains.idea.svn.commandLine.*;
+import org.tmatesoft.svn.core.wc.SVNRevision;
+import org.tmatesoft.svn.core.wc2.SvnTarget;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class CmdContentClient extends BaseSvnClient implements ContentClient {
+
+ @Override
+ public byte[] getContent(@NotNull SvnTarget target, @Nullable SVNRevision revision, @Nullable SVNRevision pegRevision)
+ throws VcsException, FileTooBigRuntimeException {
+ // TODO: rewrite this to provide output as Stream
+ // TODO: rewrite without conversion from String to byte[]
+ // TODO: Also implement max size constraint like in SvnKitContentClient
+ List<String> parameters = new ArrayList<String>();
+ CommandUtil.put(parameters, target.getPathOrUrlString(), pegRevision);
+ CommandUtil.put(parameters, revision);
+
+ SvnCommand command = CommandUtil.execute(myVcs, SvnCommandName.cat, parameters, null);
+
+ byte[] bytes = CharsetToolkit.getUtf8Bytes(command.getOutput());
+
+ ContentRevisionCache.checkContentsSize(target.getPathOrUrlString(), bytes.length);
+
+ return bytes;
+ }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/content/ContentClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/content/ContentClient.java
new file mode 100644
index 000000000000..3654d09c88bc
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/content/ContentClient.java
@@ -0,0 +1,17 @@
+package org.jetbrains.idea.svn.content;
+
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.api.SvnClient;
+import org.tmatesoft.svn.core.wc.SVNRevision;
+import org.tmatesoft.svn.core.wc2.SvnTarget;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public interface ContentClient extends SvnClient {
+
+ byte[] getContent(@NotNull SvnTarget target, @Nullable SVNRevision revision, @Nullable SVNRevision pegRevision)
+ throws VcsException, FileTooBigRuntimeException;
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/content/FileTooBigRuntimeException.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/content/FileTooBigRuntimeException.java
new file mode 100644
index 000000000000..0a0e585069a6
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/content/FileTooBigRuntimeException.java
@@ -0,0 +1,7 @@
+package org.jetbrains.idea.svn.content;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class FileTooBigRuntimeException extends RuntimeException {
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/content/SvnKitContentClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/content/SvnKitContentClient.java
new file mode 100644
index 000000000000..d5916970e320
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/content/SvnKitContentClient.java
@@ -0,0 +1,61 @@
+package org.jetbrains.idea.svn.content;
+
+import com.intellij.openapi.vcs.VcsException;
+import com.intellij.openapi.vcs.impl.ContentRevisionCache;
+import com.intellij.vcsUtil.VcsUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.api.BaseSvnClient;
+import org.tmatesoft.svn.core.SVNException;
+import org.tmatesoft.svn.core.wc.SVNRevision;
+import org.tmatesoft.svn.core.wc.SVNWCClient;
+import org.tmatesoft.svn.core.wc2.SvnTarget;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class SvnKitContentClient extends BaseSvnClient implements ContentClient {
+
+ @Override
+ public byte[] getContent(@NotNull SvnTarget target, @Nullable SVNRevision revision, @Nullable SVNRevision pegRevision)
+ throws VcsException, FileTooBigRuntimeException {
+ final int maxSize = VcsUtil.getMaxVcsLoadedFileSize();
+ ByteArrayOutputStream buffer = new ByteArrayOutputStream() {
+ @Override
+ public synchronized void write(int b) {
+ if (size() > maxSize) throw new FileTooBigRuntimeException();
+ super.write(b);
+ }
+
+ @Override
+ public synchronized void write(byte[] b, int off, int len) {
+ if (size() > maxSize) throw new FileTooBigRuntimeException();
+ super.write(b, off, len);
+ }
+
+ @Override
+ public synchronized void writeTo(OutputStream out) throws IOException {
+ if (size() > maxSize) throw new FileTooBigRuntimeException();
+ super.writeTo(out);
+ }
+ };
+ SVNWCClient wcClient = myVcs.createWCClient();
+ try {
+ if (target.isURL()) {
+ wcClient.doGetFileContents(target.getURL(), pegRevision, revision, true, buffer);
+ } else {
+ wcClient.doGetFileContents(target.getFile(), pegRevision, revision, true, buffer);
+ }
+ ContentRevisionCache.checkContentsSize(target.getPathOrUrlString(), buffer.size());
+ } catch (FileTooBigRuntimeException e) {
+ ContentRevisionCache.checkContentsSize(target.getPathOrUrlString(), buffer.size());
+ } catch (SVNException e) {
+ throw new VcsException(e);
+ }
+ return buffer.toByteArray();
+ }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/copy/CmdCopyMoveClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/copy/CmdCopyMoveClient.java
new file mode 100644
index 000000000000..eceef14d994d
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/copy/CmdCopyMoveClient.java
@@ -0,0 +1,30 @@
+package org.jetbrains.idea.svn.copy;
+
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.idea.svn.api.BaseSvnClient;
+import org.jetbrains.idea.svn.commandLine.CommandUtil;
+import org.jetbrains.idea.svn.commandLine.SvnCommandName;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class CmdCopyMoveClient extends BaseSvnClient implements CopyMoveClient {
+
+ @Override
+ public void copy(@NotNull File src, @NotNull File dst, boolean makeParents, boolean isMove) throws VcsException {
+ List<String> parameters = new ArrayList<String>();
+
+ CommandUtil.put(parameters, src);
+ CommandUtil.put(parameters, dst);
+ CommandUtil.put(parameters, makeParents, "--parents");
+
+ // for now parsing of the output is not required as command is executed only for one file
+ // and will be either successful or exception will be thrown
+ CommandUtil.execute(myVcs, isMove ? SvnCommandName.move : SvnCommandName.copy, parameters, null);
+ }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/copy/CopyMoveClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/copy/CopyMoveClient.java
new file mode 100644
index 000000000000..ec48107c8223
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/copy/CopyMoveClient.java
@@ -0,0 +1,15 @@
+package org.jetbrains.idea.svn.copy;
+
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.idea.svn.api.SvnClient;
+
+import java.io.File;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public interface CopyMoveClient extends SvnClient {
+
+ void copy(@NotNull File src, @NotNull File dst, boolean makeParents, boolean isMove) throws VcsException;
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/copy/SvnKitCopyMoveClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/copy/SvnKitCopyMoveClient.java
new file mode 100644
index 000000000000..ea84bc6f0816
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/copy/SvnKitCopyMoveClient.java
@@ -0,0 +1,28 @@
+package org.jetbrains.idea.svn.copy;
+
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.idea.svn.api.BaseSvnClient;
+import org.tmatesoft.svn.core.SVNException;
+import org.tmatesoft.svn.core.wc.SVNCopySource;
+import org.tmatesoft.svn.core.wc.SVNRevision;
+
+import java.io.File;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class SvnKitCopyMoveClient extends BaseSvnClient implements CopyMoveClient {
+
+ @Override
+ public void copy(@NotNull File src, @NotNull File dst, boolean makeParents, boolean isMove) throws VcsException {
+ final SVNCopySource copySource = new SVNCopySource(isMove ? SVNRevision.UNDEFINED : SVNRevision.WORKING, SVNRevision.WORKING, src);
+
+ try {
+ myVcs.createCopyClient().doCopy(new SVNCopySource[]{copySource}, dst, isMove, makeParents, true);
+ }
+ catch (SVNException e) {
+ throw new VcsException(e);
+ }
+ }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/delete/CmdDeleteClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/delete/CmdDeleteClient.java
new file mode 100644
index 000000000000..5fc26acfb1d3
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/delete/CmdDeleteClient.java
@@ -0,0 +1,29 @@
+package org.jetbrains.idea.svn.delete;
+
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.idea.svn.api.BaseSvnClient;
+import org.jetbrains.idea.svn.commandLine.CommandUtil;
+import org.jetbrains.idea.svn.commandLine.SvnCommandName;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class CmdDeleteClient extends BaseSvnClient implements DeleteClient {
+
+ @Override
+ public void delete(@NotNull File path, boolean force) throws VcsException {
+ List<String> parameters = new ArrayList<String>();
+
+ CommandUtil.put(parameters, path);
+ CommandUtil.put(parameters, force, "--force");
+
+ // for now parsing of the output is not required as command is executed only for one file
+ // and will be either successful or exception will be thrown
+ CommandUtil.execute(myVcs, SvnCommandName.delete, parameters, null);
+ }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/delete/DeleteClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/delete/DeleteClient.java
new file mode 100644
index 000000000000..23a1cf97cb31
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/delete/DeleteClient.java
@@ -0,0 +1,15 @@
+package org.jetbrains.idea.svn.delete;
+
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.idea.svn.api.SvnClient;
+
+import java.io.File;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public interface DeleteClient extends SvnClient {
+
+ void delete(@NotNull File path, boolean force) throws VcsException;
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/delete/SvnKitDeleteClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/delete/SvnKitDeleteClient.java
new file mode 100644
index 000000000000..c97cfd2a44bb
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/delete/SvnKitDeleteClient.java
@@ -0,0 +1,24 @@
+package org.jetbrains.idea.svn.delete;
+
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.idea.svn.api.BaseSvnClient;
+import org.tmatesoft.svn.core.SVNException;
+
+import java.io.File;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class SvnKitDeleteClient extends BaseSvnClient implements DeleteClient {
+
+ @Override
+ public void delete(@NotNull File path, boolean force) throws VcsException {
+ try {
+ myVcs.createWCClient().doDelete(path, force, false);
+ }
+ catch (SVNException e) {
+ throw new VcsException(e);
+ }
+ }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/CreateBranchOrTagDialog.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/CreateBranchOrTagDialog.java
index 62fc918d8a92..e1ad9157ce7b 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/CreateBranchOrTagDialog.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/CreateBranchOrTagDialog.java
@@ -263,17 +263,11 @@ public class CreateBranchOrTagDialog extends DialogWrapper {
super.init();
SvnVcs vcs = SvnVcs.getInstance(myProject);
String revStr = "";
- try {
- SVNWCClient client = vcs.createWCClient();
- SVNInfo info = client.doInfo(mySrcFile, SVNRevision.UNDEFINED);
- if (info != null) {
- mySrcURL = info.getURL() == null ? null : info.getURL().toString();
- revStr = String.valueOf(info.getRevision());
- myURL = mySrcURL;
- }
- }
- catch (SVNException e) {
- //
+ SVNInfo info = vcs.getInfo(mySrcFile);
+ if (info != null) {
+ mySrcURL = info.getURL() == null ? null : info.getURL().toString();
+ revStr = String.valueOf(info.getRevision());
+ myURL = mySrcURL;
}
if (myURL == null) {
return;
@@ -354,15 +348,8 @@ public class CreateBranchOrTagDialog extends DialogWrapper {
return true;
}
else if (myWorkingCopyRadioButton.isSelected()) {
- String srcUrl;
- try {
- SVNWCClient client = SvnVcs.getInstance(myProject).createWCClient();
- SVNInfo info = client.doInfo(mySrcFile, SVNRevision.UNDEFINED);
- srcUrl = info != null && info.getURL() != null ? info.getURL().toString() : null;
- }
- catch (SVNException e) {
- srcUrl = null;
- }
+ SVNInfo info = SvnVcs.getInstance(myProject).getInfo(mySrcFile);
+ String srcUrl = info != null && info.getURL() != null ? info.getURL().toString() : null;
if (srcUrl == null) {
myErrorLabel.setText(SvnBundle.message("create.branch.no.working.copy.error", myWorkingCopyField.getText()));
return false;
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/CmdHistoryClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/CmdHistoryClient.java
new file mode 100644
index 000000000000..3948ddee57b7
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/CmdHistoryClient.java
@@ -0,0 +1,223 @@
+package org.jetbrains.idea.svn.history;
+
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vcs.VcsException;
+import com.intellij.util.LineSeparator;
+import com.intellij.util.containers.hash.HashMap;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.api.BaseSvnClient;
+import org.jetbrains.idea.svn.commandLine.CommandUtil;
+import org.jetbrains.idea.svn.commandLine.SvnCommandName;
+import org.jetbrains.idea.svn.commandLine.SvnLineCommand;
+import org.tmatesoft.svn.core.ISVNLogEntryHandler;
+import org.tmatesoft.svn.core.SVNException;
+import org.tmatesoft.svn.core.SVNLogEntry;
+import org.tmatesoft.svn.core.SVNLogEntryPath;
+import org.tmatesoft.svn.core.wc.SVNRevision;
+
+import java.io.File;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class CmdHistoryClient extends BaseSvnClient implements HistoryClient {
+
+ private static final Logger LOG = Logger.getInstance("#org.jetbrains.idea.svn.history.CmdHistoryClient");
+
+ @Override
+ public void doLog(@NotNull File path,
+ @NotNull SVNRevision startRevision,
+ @NotNull SVNRevision endRevision,
+ @Nullable SVNRevision pegRevision,
+ boolean stopOnCopy,
+ boolean discoverChangedPaths,
+ boolean includeMergedRevisions,
+ long limit,
+ @Nullable String[] revisionProperties,
+ @Nullable ISVNLogEntryHandler handler) throws VcsException {
+ // TODO: add revision properties parameter if necessary
+ // TODO: svn log command supports --xml option - could update parsing to use xml format
+
+ // TODO: after merge remove setting includeMergedRevisions to false and update parsing
+ includeMergedRevisions = false;
+
+ List<String> parameters =
+ prepareCommand(path, startRevision, endRevision, pegRevision, stopOnCopy, discoverChangedPaths, includeMergedRevisions, limit);
+
+ try {
+ SvnLineCommand command = CommandUtil.runSimple(SvnCommandName.log, myVcs, path, null, parameters);
+ // TODO: handler should be called in parallel with command execution, but this will be in other thread
+ // TODO: check if that is ok for current handler implementation
+ parseOutput(handler, command);
+ }
+ catch (SVNException e) {
+ throw new VcsException(e);
+ }
+ }
+
+ private static void parseOutput(@Nullable ISVNLogEntryHandler handler, @NotNull SvnLineCommand command)
+ throws VcsException, SVNException {
+ Parser parser = new Parser(handler);
+ for (String line : StringUtil.splitByLines(command.getOutput(), false)) {
+ parser.onLine(line);
+ }
+ }
+
+ private static List<String> prepareCommand(@NotNull File path,
+ @NotNull SVNRevision startRevision,
+ @NotNull SVNRevision endRevision,
+ @Nullable SVNRevision pegRevision,
+ boolean stopOnCopy, boolean discoverChangedPaths, boolean includeMergedRevisions, long limit) {
+ List<String> parameters = new ArrayList<String>();
+
+ CommandUtil.put(parameters, path, pegRevision);
+ parameters.add("--revision");
+ parameters.add(startRevision + ":" + endRevision);
+
+ CommandUtil.put(parameters, stopOnCopy, "--stop-on-copy");
+ CommandUtil.put(parameters, discoverChangedPaths, "--verbose");
+ CommandUtil.put(parameters, includeMergedRevisions, "--use-merge-history");
+ if (limit > 0) {
+ parameters.add("--limit");
+ parameters.add(String.valueOf(limit));
+ }
+
+ return parameters;
+ }
+
+ private static class Parser {
+ private static final String REVISION = "\\s*r(\\d+)\\s*";
+ private static final String AUTHOR = "\\s*([^|]*)\\s*";
+ private static final String DATE = "\\s*([^|]*)\\s*";
+ private static final String MESSAGE_LINES = "\\s*(\\d+).*";
+
+ private static final Pattern ENTRY_START = Pattern.compile("-+");
+ private static final Pattern DETAILS = Pattern.compile(REVISION + "\\|" + AUTHOR + "\\|" + DATE + "\\|" + MESSAGE_LINES);
+
+ private static final String STATUS = "\\s*(\\w)";
+ private static final String PATH = "\\s*(.*?)\\s*";
+ private static final String COPY_FROM_PATH = "(/[^:]*)";
+ private static final String COPY_FROM_REVISION = "(\\d+)\\))\\s*";
+ private static final String COPY_FROM_INFO = "((\\(from " + COPY_FROM_PATH + ":" + COPY_FROM_REVISION + ")?";
+ private static final Pattern CHANGED_PATH = Pattern.compile(STATUS + PATH + COPY_FROM_INFO);
+
+ private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z");
+
+ ISVNLogEntryHandler handler;
+
+ Entry entry;
+ boolean waitDetails;
+ boolean waitChangedPath;
+ boolean waitMessage;
+
+ public Parser(@Nullable ISVNLogEntryHandler handler) {
+ this.handler = handler;
+ }
+
+ public void onLine(@NotNull String line) throws VcsException, SVNException {
+ if (ENTRY_START.matcher(line).matches()) {
+ processEntryStart();
+ }
+ else if (waitDetails) {
+ processDetails(line);
+ }
+ else if (waitMessage) {
+ processMessage(line);
+ }
+ else if (StringUtil.isEmpty(line.trim())) {
+ processChangedPathsFinished();
+ }
+ else if (line.startsWith("Changed paths:")) {
+ processChangedPathsStarted();
+ }
+ else if (waitChangedPath) {
+ processChangedPath(line);
+ }
+ else {
+ throw new VcsException("unknown state on line " + line);
+ }
+ }
+
+ private void processChangedPath(@NotNull String line) throws VcsException {
+ Matcher matcher = CHANGED_PATH.matcher(line);
+ if (!matcher.matches()) {
+ throw new VcsException("changed path not found in " + line);
+ }
+
+ String path = matcher.group(2);
+ char type = CommandUtil.getStatusChar(matcher.group(1));
+ String copyPath = matcher.group(5);
+ long copyRevision = !StringUtil.isEmpty(matcher.group(6)) ? Long.valueOf(matcher.group(6)) : 0;
+
+ entry.changedPaths.put(path, new SVNLogEntryPath(path, type, copyPath, copyRevision));
+ }
+
+ private void processChangedPathsStarted() {
+ waitChangedPath = true;
+ }
+
+ private void processChangedPathsFinished() {
+ waitChangedPath = false;
+ waitMessage = true;
+ }
+
+ private void processMessage(@NotNull String line) {
+ entry.message.append(line);
+ entry.message.append(LineSeparator.LF.getSeparatorString());
+ }
+
+ private void processDetails(@NotNull String line) throws VcsException {
+ Matcher matcher = DETAILS.matcher(line);
+ if (!matcher.matches()) {
+ throw new VcsException("details not found in " + line);
+ }
+ entry.revision = Long.valueOf(matcher.group(1));
+ entry.author = matcher.group(2).trim();
+ entry.date = tryGetDate(matcher.group(3));
+
+ waitDetails = false;
+ }
+
+ private void processEntryStart() throws SVNException {
+ if (entry != null) {
+ handler.handleLogEntry(entry.toLogEntry());
+ }
+ entry = new Entry();
+ waitDetails = true;
+ waitMessage = false;
+ }
+
+ private static Date tryGetDate(@NotNull String value) {
+ Date result = null;
+ try {
+ result = DATE_FORMAT.parse(value);
+ }
+ catch (ParseException e) {
+ LOG.debug(e);
+ }
+ return result;
+ }
+
+ private static class Entry {
+ Map<String, SVNLogEntryPath> changedPaths = new HashMap<String, SVNLogEntryPath>();
+ long revision;
+ String author;
+ Date date;
+ StringBuilder message = new StringBuilder();
+
+ private SVNLogEntry toLogEntry() {
+ return new SVNLogEntry(changedPaths, revision, author, date, message.toString());
+ }
+ }
+ }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/HistoryClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/HistoryClient.java
new file mode 100644
index 000000000000..87e5e76556fa
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/HistoryClient.java
@@ -0,0 +1,28 @@
+package org.jetbrains.idea.svn.history;
+
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.api.SvnClient;
+import org.tmatesoft.svn.core.ISVNLogEntryHandler;
+import org.tmatesoft.svn.core.wc.SVNRevision;
+
+import java.io.File;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public interface HistoryClient extends SvnClient {
+
+ // TODO: Url is also supported as parameter in cmd - use Target class
+ void doLog(@NotNull File path,
+ @NotNull SVNRevision startRevision,
+ @NotNull SVNRevision endRevision,
+ @Nullable SVNRevision pegRevision,
+ boolean stopOnCopy,
+ boolean discoverChangedPaths,
+ boolean includeMergedRevisions,
+ long limit,
+ @Nullable String[] revisionProperties,
+ @Nullable ISVNLogEntryHandler handler) throws VcsException;
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnCommittedChangesProvider.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnCommittedChangesProvider.java
index 7ef0b2f3d0b6..3552853a8479 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnCommittedChangesProvider.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnCommittedChangesProvider.java
@@ -518,9 +518,8 @@ public class SvnCommittedChangesProvider implements CachingCommittedChangesProvi
revisionBefore = SVNRevision.create(revision);
svnurl = SVNURL.parseURIEncoded(url);
- final SVNWCClient client = myVcs.createWCClient();
- final SVNInfo info = client.doInfo(svnurl, SVNRevision.UNDEFINED, SVNRevision.HEAD);
- targetInfo = client.doInfo(new File(file.getPath()), SVNRevision.UNDEFINED);
+ final SVNInfo info = myVcs.getInfo(svnurl, SVNRevision.HEAD);
+ targetInfo = myVcs.getInfo(new File(file.getPath()));
if (info == null) {
throw new VcsException("Can not get repository URL");
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnEditCommitMessageAction.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnEditCommitMessageAction.java
index 5ca1150869ae..d67e29b598a0 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnEditCommitMessageAction.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnEditCommitMessageAction.java
@@ -137,7 +137,7 @@ public class SvnEditCommitMessageAction extends AnAction {
final String url = myLocation.getURL();
final SVNURL root;
try {
- root = SvnUtil.getRepositoryRoot(myVcs, SVNURL.parseURIEncoded(url), true);
+ root = SvnUtil.getRepositoryRoot(myVcs, SVNURL.parseURIEncoded(url));
if (root == null) {
myException = new VcsException("Can not determine repository root for URL: " + url);
return;
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnFileRevision.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnFileRevision.java
index bcb40a034ac9..046e16c148a4 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnFileRevision.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnFileRevision.java
@@ -33,6 +33,7 @@ import org.jetbrains.idea.svn.SvnUtil;
import org.jetbrains.idea.svn.SvnVcs;
import org.tmatesoft.svn.core.SVNLogEntry;
import org.tmatesoft.svn.core.wc.SVNRevision;
+import org.tmatesoft.svn.core.wc2.SvnTarget;
import java.io.IOException;
import java.nio.charset.Charset;
@@ -211,7 +212,7 @@ public class SvnFileRevision implements VcsFileRevision {
}
try {
- myContents = SvnUtil.getFileContents(myVCS, myURL, true, myRevision, myPegRevision);
+ myContents = SvnUtil.getFileContents(myVCS, SvnTarget.fromURL(SvnUtil.parseUrl(myURL)), myRevision, myPegRevision);
}
catch (VcsException e) {
myException = e;
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnHistoryProvider.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnHistoryProvider.java
index 4a2c8725a898..860b646947f5 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnHistoryProvider.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnHistoryProvider.java
@@ -42,7 +42,6 @@ import org.jetbrains.idea.svn.*;
import org.tmatesoft.svn.core.*;
import org.tmatesoft.svn.core.internal.util.SVNPathUtil;
import org.tmatesoft.svn.core.internal.wc.SVNErrorManager;
-import org.tmatesoft.svn.core.io.SVNRepository;
import org.tmatesoft.svn.core.wc.*;
import org.tmatesoft.svn.util.SVNLogType;
@@ -50,7 +49,6 @@ import javax.swing.*;
import javax.swing.table.TableCellRenderer;
import java.awt.*;
import java.awt.event.MouseEvent;
-import java.io.File;
import java.nio.charset.Charset;
import java.util.Collections;
import java.util.Date;
@@ -285,18 +283,9 @@ public class SvnHistoryProvider
@Override
protected void preliminary() throws SVNException {
- SVNWCClient wcClient = myVcs.createWCClient();
- myInfo = wcClient.doInfo(new File(myFile.getIOFile().getAbsolutePath()), SVNRevision.UNDEFINED);
- wcClient.setEventHandler(new ISVNEventHandler() {
- public void handleEvent(SVNEvent event, double progress) throws SVNException {
- }
-
- public void checkCancelled() throws SVNCancelException {
- myPI.checkCanceled();
- }
- });
+ myInfo = myVcs.getInfo(myFile.getIOFile());
if (myInfo == null || myInfo.getRepositoryRootURL() == null) {
- myException = new VcsException("File ''{0}'' is not under version control" + myFile.getIOFile());
+ myException = new VcsException("File " + myFile.getPath() + " is not under version control");
return;
}
if (myInfo.getURL() == null) {
@@ -319,14 +308,15 @@ public class SvnHistoryProvider
myPI.setText2(SvnBundle.message("progress.text2.changes.establishing.connection", myUrl));
}
final SVNRevision pegRevision = myInfo.getRevision();
- SVNLogClient client = myVcs.createLogClient();
try {
- // a bug noticed when testing: we should pass "limit + 1" to get "limit" rows
- client
- .doLog(new File[]{new File(myFile.getIOFile().getAbsolutePath())},
- myFrom == null ? SVNRevision.HEAD : myFrom, myTo == null ? SVNRevision.create(1) : myTo, myPeg,
- false, true, myShowMergeSources && mySupport15, myLimit + 1, null,
- new MyLogEntryHandler(myVcs, myUrl, pegRevision, relativeUrl, createConsumerAdapter(myConsumer), repoRootURL, myFile.getCharset()));
+ myVcs.getFactory(myFile.getIOFile()).createHistoryClient().doLog(
+ myFile.getIOFile(),
+ myFrom == null ? SVNRevision.HEAD : myFrom,
+ myTo == null ? SVNRevision.create(1) : myTo, myPeg,
+ false, true, myShowMergeSources && mySupport15, myLimit + 1, null,
+ new MyLogEntryHandler(myVcs, myUrl, pegRevision, relativeUrl,
+ createConsumerAdapter(myConsumer),
+ repoRootURL, myFile.getCharset()));
}
catch (SVNCancelException e) {
//
@@ -383,7 +373,6 @@ public class SvnHistoryProvider
}
}
- SVNWCClient wcClient = myVcs.createWCClient();
final SVNURL svnurl = SVNURL.parseURIEncoded(myUrl);
SVNRevision operationalFrom = myFrom == null ? SVNRevision.HEAD : myFrom;
final SVNURL rootURL = getRepositoryRoot(svnurl, myFrom);
@@ -395,6 +384,7 @@ public class SvnHistoryProvider
if (myUrl.startsWith(root)) {
relativeUrl = myUrl.substring(root.length());
}
+ // TODO: Update this call to myVcs.getFactory.createHistoryClient
SVNLogClient client = myVcs.createLogClient();
// a bug noticed when testing: we should pass "limit + 1" to get "limit" rows
client.doLog(svnurl, new String[]{}, myPeg == null ? myFrom : myPeg,
@@ -420,6 +410,7 @@ public class SvnHistoryProvider
relativeUrl = myUrl.substring(root.length());
}
+ // TODO: Update this call to myVcs.getFactory.createHistoryClient
SVNLogClient client = myVcs.createLogClient();
final RepositoryLogEntryHandler repositoryLogEntryHandler =
@@ -437,36 +428,15 @@ public class SvnHistoryProvider
}
private SVNURL getRepositoryRoot(SVNURL svnurl, SVNRevision operationalFrom) throws SVNException {
- final SVNRepository repository = myVcs.createRepository(svnurl);
- final SVNURL root = repository.getRepositoryRoot(false);
- if (root == null) {
- return repository.getRepositoryRoot(true);
- }
- return root;
- /*final SVNWCClient wcClient = myVcs.createWCClient();
- try {
- final SVNInfo info;
- info = wcClient.doInfo(svnurl, myPeg, operationalFrom);
- return info.getRepositoryRootURL();
- }
- catch (SVNException e) {
- try {
- final SVNInfo info;
- info = wcClient.doInfo(svnurl, SVNRevision.UNDEFINED, SVNRevision.UNDEFINED);
- return info.getRepositoryRootURL();
- } catch (SVNException e1) {
- final SVNInfo info;
- info = wcClient.doInfo(svnurl, SVNRevision.UNDEFINED, SVNRevision.HEAD);
- return info.getRepositoryRootURL();
- }
- }*/
+ SVNInfo info = myVcs.getInfo(svnurl, SVNRevision.HEAD);
+
+ return info != null ? info.getRepositoryRootURL() : null;
}
private boolean existsNow(SVNURL svnurl) {
- final SVNWCClient wcClient = myVcs.createWCClient();
final SVNInfo info;
try {
- info = wcClient.doInfo(svnurl, SVNRevision.HEAD, SVNRevision.HEAD);
+ info = myVcs.getInfo(svnurl, SVNRevision.HEAD, SVNRevision.HEAD, null);
}
catch (SVNException e) {
return false;
@@ -493,6 +463,7 @@ public class SvnHistoryProvider
protected final SvnPathThroughHistoryCorrection myLastPathCorrector;
private final Charset myCharset;
protected final ThrowableConsumer<VcsFileRevision, SVNException> myResult;
+ private final String myLastPath;
private VcsFileRevision myPrevious;
private final SVNRevision myPegRevision;
protected final String myUrl;
@@ -512,6 +483,7 @@ public class SvnHistoryProvider
throws SVNException, VcsException {
myVcs = vcs;
myLastPathCorrector = new SvnPathThroughHistoryCorrection(lastPath);
+ myLastPath = lastPath;
myCharset = charset;
myIndicator = ProgressManager.getInstance().getProgressIndicator();
myResult = result;
@@ -610,9 +582,9 @@ public class SvnHistoryProvider
String author = logEntry.getAuthor();
String message = logEntry.getMessage();
SVNRevision rev = SVNRevision.create(logEntry.getRevision());
-// final SVNURL url = myRepositoryRoot.appendPath(myLastPath, true);
- final SVNURL url = entryPath != null ? myRepositoryRoot.appendPath(entryPath.getPath(), true) :
- myRepositoryRoot.appendPath(myLastPathCorrector.getBefore(), false);
+ final SVNURL url = myRepositoryRoot.appendPath(myLastPath, true);
+// final SVNURL url = entryPath != null ? myRepositoryRoot.appendPath(entryPath.getPath(), true) :
+// myRepositoryRoot.appendPath(myLastPathCorrector.getBefore(), false);
return new SvnFileRevision(myVcs, myPegRevision, rev, url.toString(), author, date, message, copyPath, myCharset);
}
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnHistorySession.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnHistorySession.java
index e30f8ca216cb..171b39cad623 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnHistorySession.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnHistorySession.java
@@ -20,21 +20,19 @@ import com.intellij.openapi.vcs.history.*;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.SvnRevisionNumber;
import org.jetbrains.idea.svn.SvnVcs;
-import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.wc.SVNInfo;
import org.tmatesoft.svn.core.wc.SVNRevision;
-import org.tmatesoft.svn.core.wc.SVNWCClient;
import java.io.File;
import java.util.List;
/**
-* Created with IntelliJ IDEA.
-* User: Irina.Chernushina
-* Date: 4/27/12
-* Time: 12:24 PM
-* To change this template use File | Settings | File Templates.
-*/
+ * Created with IntelliJ IDEA.
+ * User: Irina.Chernushina
+ * Date: 4/27/12
+ * Time: 12:24 PM
+ * To change this template use File | Settings | File Templates.
+ */
public class SvnHistorySession extends VcsAbstractHistorySession {
private final SvnVcs myVcs;
private final FilePath myCommittedPath;
@@ -71,19 +69,8 @@ public class SvnHistorySession extends VcsAbstractHistorySession {
}
public static VcsRevisionNumber getCurrentCommittedRevision(final SvnVcs vcs, final File file) {
- try {
- SVNWCClient wcClient = vcs.createWCClient();
- SVNInfo info = wcClient.doInfo(file, SVNRevision.UNDEFINED);
- if (info != null) {
- return new SvnRevisionNumber(info.getCommittedRevision());
- }
- else {
- return null;
- }
- }
- catch (SVNException e) {
- return null;
- }
+ SVNInfo info = vcs.getInfo(file);
+ return info != null ? new SvnRevisionNumber(info.getCommittedRevision()) : null;
}
public FilePath getCommittedPath() {
@@ -101,7 +88,8 @@ public class SvnHistorySession extends VcsAbstractHistorySession {
@Override
public VcsHistorySession copy() {
- return new SvnHistorySession(myVcs, getRevisionList(), myCommittedPath, myHaveMergeSources, getCurrentRevisionNumber(), true, myHasLocalSource);
+ return new SvnHistorySession(myVcs, getRevisionList(), myCommittedPath, myHaveMergeSources, getCurrentRevisionNumber(), true,
+ myHasLocalSource);
}
@Override
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnKitHistoryClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnKitHistoryClient.java
new file mode 100644
index 000000000000..6d412853400e
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnKitHistoryClient.java
@@ -0,0 +1,40 @@
+package org.jetbrains.idea.svn.history;
+
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.api.BaseSvnClient;
+import org.tmatesoft.svn.core.ISVNLogEntryHandler;
+import org.tmatesoft.svn.core.SVNException;
+import org.tmatesoft.svn.core.wc.SVNLogClient;
+import org.tmatesoft.svn.core.wc.SVNRevision;
+
+import java.io.File;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class SvnKitHistoryClient extends BaseSvnClient implements HistoryClient {
+ @Override
+ public void doLog(@NotNull File path,
+ @NotNull SVNRevision startRevision,
+ @NotNull SVNRevision endRevision,
+ @Nullable SVNRevision pegRevision,
+ boolean stopOnCopy,
+ boolean discoverChangedPaths,
+ boolean includeMergedRevisions,
+ long limit,
+ @Nullable String[] revisionProperties,
+ @Nullable ISVNLogEntryHandler handler) throws VcsException {
+ try {
+ // TODO: a bug noticed when testing: we should pass "limit + 1" to get "limit" rows
+ SVNLogClient client = myVcs.createLogClient();
+
+ client.doLog(new File[]{path}, startRevision, endRevision, pegRevision, stopOnCopy, discoverChangedPaths, includeMergedRevisions,
+ limit, revisionProperties, handler);
+ }
+ catch (SVNException e) {
+ throw new VcsException(e);
+ }
+ }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnRepositoryContentRevision.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnRepositoryContentRevision.java
index a668a54f953a..b01308f76c13 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnRepositoryContentRevision.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/history/SvnRepositoryContentRevision.java
@@ -38,13 +38,10 @@ import com.intellij.openapi.vcs.history.VcsRevisionNumber;
import com.intellij.openapi.vcs.impl.ContentRevisionCache;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import org.jetbrains.idea.svn.SvnBundle;
-import org.jetbrains.idea.svn.SvnRevisionNumber;
-import org.jetbrains.idea.svn.SvnUtil;
-import org.jetbrains.idea.svn.SvnVcs;
+import org.jetbrains.idea.svn.*;
import org.tmatesoft.svn.core.SVNException;
-import org.tmatesoft.svn.core.io.SVNRepository;
import org.tmatesoft.svn.core.wc.SVNRevision;
+import org.tmatesoft.svn.core.wc2.SvnTarget;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@@ -108,7 +105,7 @@ public class SvnRepositoryContentRevision implements ContentRevision, MarkerVcsC
else {
loader.run();
}
- final SVNException exception = loader.getException();
+ final Exception exception = loader.getException();
if (exception != null) {
throw new VcsException(exception);
}
@@ -148,7 +145,7 @@ public class SvnRepositoryContentRevision implements ContentRevision, MarkerVcsC
private final String myPath;
private final long myRevision;
private final OutputStream myDst;
- private SVNException myException;
+ private Exception myException;
public ContentLoader(String path, OutputStream dst, long revision) {
myPath = path;
@@ -156,7 +153,7 @@ public class SvnRepositoryContentRevision implements ContentRevision, MarkerVcsC
myRevision = revision;
}
- public SVNException getException() {
+ public Exception getException() {
return myException;
}
@@ -166,16 +163,16 @@ public class SvnRepositoryContentRevision implements ContentRevision, MarkerVcsC
progress.setText(SvnBundle.message("progress.text.loading.contents", myPath));
progress.setText2(SvnBundle.message("progress.text2.revision.information", myRevision));
}
+
try {
- SVNRepository repository = myVcs.createRepository(getFullPath());
- try {
- repository.getFile("", myRevision, null, myDst);
- }
- finally {
- repository.closeSession();
- }
+ byte[] contents = SvnUtil.getFileContents(myVcs, SvnTarget.fromURL(SvnUtil.parseUrl(getFullPath())), SVNRevision.create(myRevision),
+ SVNRevision.UNDEFINED);
+ myDst.write(contents);
}
- catch (SVNException e) {
+ catch (VcsException e) {
+ myException = e;
+ }
+ catch (IOException e) {
myException = e;
}
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/IntegratedSelectedOptionsDialog.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/IntegratedSelectedOptionsDialog.java
index 78718a7a0264..bfb9f1ff22c3 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/IntegratedSelectedOptionsDialog.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/integrate/IntegratedSelectedOptionsDialog.java
@@ -251,19 +251,10 @@ public class IntegratedSelectedOptionsDialog extends DialogWrapper {
@Nullable
private static SVNURL realTargetUrl(final SvnVcs vcs, final WorkingCopyInfo info, final String targetBranchUrl) {
- final SVNWCClient client = vcs.createWCClient();
- try {
- final SVNInfo svnInfo = client.doInfo(new File(info.getLocalPath()), SVNRevision.UNDEFINED);
- final SVNURL svnurl = svnInfo.getURL();
+ final SVNInfo svnInfo = vcs.getInfo(info.getLocalPath());
+ final SVNURL svnurl = svnInfo != null ? svnInfo.getURL() : null;
- if ((svnurl != null) && (svnurl.toString().startsWith(targetBranchUrl))) {
- return svnurl;
- }
- }
- catch (SVNException e) {
- // tracked by return value
- }
- return null;
+ return (svnurl != null) && (svnurl.toString().startsWith(targetBranchUrl)) ? svnurl : null;
}
@Nullable
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/mergeinfo/BranchInfo.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/mergeinfo/BranchInfo.java
index b6c6a898b85a..bc08fff144dc 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/mergeinfo/BranchInfo.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/mergeinfo/BranchInfo.java
@@ -238,12 +238,7 @@ public class BranchInfo {
}
private SVNInfo getInfo(final File pathFile) {
- try {
- return myClient.doInfo(pathFile, SVNRevision.UNDEFINED);
- } catch (SVNException e) {
- //
- }
- return null;
+ return myVcs.getInfo(pathFile);
}
private SvnMergeInfoCache.MergeCheckResult checkPathGoingUp(final long revisionAsked, final long targetRevision, final String branchRootPath,
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/PortableStatus.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/PortableStatus.java
index 184d5598f9fe..9799cf7ae4a4 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/PortableStatus.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/portable/PortableStatus.java
@@ -117,6 +117,7 @@ public class PortableStatus extends SVNStatus {
return null;
}
};
+ // TODO: Update working copy format detection
setWorkingCopyFormat(WorkingCopyFormat.ONE_DOT_SEVEN.getFormat());
}
@@ -242,6 +243,30 @@ public class PortableStatus extends SVNStatus {
}
@Override
+ public SVNURL getURL() {
+ SVNURL url = super.getURL();
+
+ if (url == null) {
+ SVNInfo info = initInfo();
+ url = info != null ? info.getURL() : url;
+ }
+
+ return url;
+ }
+
+ @Override
+ public File getFile() {
+ File file = super.getFile();
+
+ if (file == null) {
+ SVNInfo info = initInfo();
+ file = info != null ? info.getFile() : file;
+ }
+
+ return file;
+ }
+
+ @Override
public SVNRevision getRevision() {
final SVNRevision revision = super.getRevision();
if (revision != null && revision.isValid()) return revision;
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/CmdPropertyClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/CmdPropertyClient.java
new file mode 100644
index 000000000000..4720b33d9d37
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/CmdPropertyClient.java
@@ -0,0 +1,65 @@
+package org.jetbrains.idea.svn.properties;
+
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.api.BaseSvnClient;
+import org.jetbrains.idea.svn.commandLine.CommandUtil;
+import org.jetbrains.idea.svn.commandLine.SvnCommand;
+import org.jetbrains.idea.svn.commandLine.SvnCommandName;
+import org.tmatesoft.svn.core.SVNPropertyValue;
+import org.tmatesoft.svn.core.wc.SVNInfo;
+import org.tmatesoft.svn.core.wc.SVNPropertyData;
+import org.tmatesoft.svn.core.wc.SVNRevision;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class CmdPropertyClient extends BaseSvnClient implements PropertyClient {
+
+ @Nullable
+ @Override
+ public SVNPropertyData getProperty(@NotNull File path,
+ @NotNull String property,
+ boolean revisionProperty,
+ @Nullable SVNRevision pegRevision,
+ @Nullable SVNRevision revision)
+ throws VcsException {
+ List<String> parameters = new ArrayList<String>();
+
+ parameters.add(property);
+ CommandUtil.put(parameters, path, pegRevision);
+ if (!revisionProperty) {
+ CommandUtil.put(parameters, revision);
+ } else {
+ parameters.add("--revprop");
+ CommandUtil.put(parameters, resolveRevisionNumber(path, revision));
+ }
+
+ SvnCommand command = CommandUtil.execute(myVcs, SvnCommandName.propget, parameters, null);
+
+ return new SVNPropertyData(property, SVNPropertyValue.create(StringUtil.nullize(command.getOutput())), null);
+ }
+
+ private SVNRevision resolveRevisionNumber(@NotNull File path, @Nullable SVNRevision revision) throws VcsException {
+ long result = revision != null ? revision.getNumber() : -1;
+
+ // base should be resolved manually - could not set revision to BASE to get revision property
+ if (SVNRevision.BASE.equals(revision)) {
+ SVNInfo info = myVcs.getInfo(path, SVNRevision.BASE);
+
+ result = info != null ? info.getRevision().getNumber() : -1;
+ }
+
+ if (result == -1) {
+ throw new VcsException("Could not determine revision number for file " + path + " and revision " + revision);
+ }
+
+ return SVNRevision.create(result);
+ }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/PropertyClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/PropertyClient.java
new file mode 100644
index 000000000000..118a397eb23e
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/PropertyClient.java
@@ -0,0 +1,23 @@
+package org.jetbrains.idea.svn.properties;
+
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.api.SvnClient;
+import org.tmatesoft.svn.core.wc.SVNPropertyData;
+import org.tmatesoft.svn.core.wc.SVNRevision;
+
+import java.io.File;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public interface PropertyClient extends SvnClient {
+
+ @Nullable
+ SVNPropertyData getProperty(@NotNull final File path,
+ @NotNull final String property,
+ boolean revisionProperty,
+ @Nullable SVNRevision pegRevision,
+ @Nullable SVNRevision revision) throws VcsException;
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/SvnKitPropertyClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/SvnKitPropertyClient.java
new file mode 100644
index 000000000000..1c3c23619074
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/SvnKitPropertyClient.java
@@ -0,0 +1,68 @@
+package org.jetbrains.idea.svn.properties;
+
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.api.BaseSvnClient;
+import org.tmatesoft.svn.core.SVNException;
+import org.tmatesoft.svn.core.SVNURL;
+import org.tmatesoft.svn.core.wc.ISVNPropertyHandler;
+import org.tmatesoft.svn.core.wc.SVNPropertyData;
+import org.tmatesoft.svn.core.wc.SVNRevision;
+import org.tmatesoft.svn.core.wc.SVNWCClient;
+
+import java.io.File;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class SvnKitPropertyClient extends BaseSvnClient implements PropertyClient {
+
+ @Nullable
+ @Override
+ public SVNPropertyData getProperty(@NotNull File path,
+ @NotNull String property,
+ boolean revisionProperty,
+ @Nullable SVNRevision pegRevision,
+ @Nullable SVNRevision revision) throws VcsException {
+ try {
+ if (!revisionProperty) {
+ return myVcs.createWCClient().doGetProperty(path, property, pegRevision, revision);
+ } else {
+ return getRevisionProperty(path, property, revision);
+ }
+ }
+ catch (SVNException e) {
+ throw new VcsException(e);
+ }
+ }
+
+ private SVNPropertyData getRevisionProperty(@NotNull File path, @NotNull final String property, @Nullable SVNRevision revision) throws SVNException{
+ final SVNWCClient client = myVcs.createWCClient();
+ final SVNPropertyData[] result = new SVNPropertyData[1];
+
+ client.doGetRevisionProperty(path, null, revision, new ISVNPropertyHandler() {
+ @Override
+ public void handleProperty(File path, SVNPropertyData property) throws SVNException {
+ handle(property);
+ }
+
+ @Override
+ public void handleProperty(SVNURL url, SVNPropertyData property) throws SVNException {
+ handle(property);
+ }
+
+ @Override
+ public void handleProperty(long revision, SVNPropertyData property) throws SVNException {
+ handle(property);
+ }
+
+ private void handle(@NotNull SVNPropertyData data) {
+ if (property.equals(data.getName())) {
+ result[0] = data;
+ }
+ }
+ });
+ return result[0];
+ }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/revert/CmdRevertClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/revert/CmdRevertClient.java
new file mode 100644
index 000000000000..53c998f001a6
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/revert/CmdRevertClient.java
@@ -0,0 +1,79 @@
+package org.jetbrains.idea.svn.revert;
+
+import com.intellij.openapi.vcs.VcsException;
+import com.intellij.util.containers.Convertor;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.api.BaseSvnClient;
+import org.jetbrains.idea.svn.api.FileStatusResultParser;
+import org.jetbrains.idea.svn.commandLine.CommandUtil;
+import org.jetbrains.idea.svn.commandLine.SvnCommandName;
+import org.tmatesoft.svn.core.SVNDepth;
+import org.tmatesoft.svn.core.wc.ISVNEventHandler;
+import org.tmatesoft.svn.core.wc.SVNEvent;
+import org.tmatesoft.svn.core.wc.SVNEventAction;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class CmdRevertClient extends BaseSvnClient implements RevertClient {
+
+ private static final String STATUS = "\\s*(.+?)\\s*";
+ private static final String PATH = "\\s*\'(.*?)\'\\s*";
+ private static final String OPTIONAL_COMMENT = "(.*)";
+ private static final Pattern CHANGED_PATH = Pattern.compile(STATUS + PATH + OPTIONAL_COMMENT);
+
+ @Override
+ public void revert(@NotNull File[] paths, @Nullable SVNDepth depth, @Nullable ISVNEventHandler handler) throws VcsException {
+ List<String> parameters = prepareParameters(paths, depth);
+
+ // TODO: handler should be called in parallel with command execution, but this will be in other thread
+ // TODO: check if that is ok for current handler implementation
+ // TODO: add possibility to invoke "handler.checkCancelled" - process should be killed
+ CommandUtil
+ .execute(myVcs, SvnCommandName.revert, parameters, new FileStatusResultParser(CHANGED_PATH, handler, new RevertStatusConvertor()));
+ }
+
+ private static List<String> prepareParameters(File[] paths, SVNDepth depth) {
+ ArrayList<String> parameters = new ArrayList<String>();
+
+ CommandUtil.put(parameters, paths);
+ CommandUtil.put(parameters, depth);
+
+ return parameters;
+ }
+
+ private static class RevertStatusConvertor implements Convertor<Matcher, SVNEvent> {
+
+ public SVNEvent convert(@NotNull Matcher matcher) {
+ String statusMessage = matcher.group(1);
+ String path = matcher.group(2);
+
+ return new SVNEvent(new File(path), null, null, 0, null, null, null, null, createAction(statusMessage), null, null, null, null, null,
+ null);
+ }
+
+ @Nullable
+ public static SVNEventAction createAction(@NotNull String code) {
+ SVNEventAction result = null;
+
+ if ("Reverted".equals(code)) {
+ result = SVNEventAction.REVERT;
+ }
+ else if ("Failed to revert".equals(code)) {
+ result = SVNEventAction.FAILED_REVERT;
+ }
+ else if ("Skipped".equals(code)) {
+ result = SVNEventAction.SKIP;
+ }
+
+ return result;
+ }
+ }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/revert/RevertClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/revert/RevertClient.java
new file mode 100644
index 000000000000..053de373bc0a
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/revert/RevertClient.java
@@ -0,0 +1,18 @@
+package org.jetbrains.idea.svn.revert;
+
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.api.SvnClient;
+import org.tmatesoft.svn.core.SVNDepth;
+import org.tmatesoft.svn.core.wc.ISVNEventHandler;
+
+import java.io.File;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public interface RevertClient extends SvnClient {
+
+ void revert(@NotNull File[] paths, @Nullable SVNDepth depth, @Nullable ISVNEventHandler handler) throws VcsException;
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/revert/SvnKitRevertClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/revert/SvnKitRevertClient.java
new file mode 100644
index 000000000000..17c725cf58f6
--- /dev/null
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/revert/SvnKitRevertClient.java
@@ -0,0 +1,31 @@
+package org.jetbrains.idea.svn.revert;
+
+import com.intellij.openapi.vcs.VcsException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.idea.svn.api.BaseSvnClient;
+import org.tmatesoft.svn.core.SVNDepth;
+import org.tmatesoft.svn.core.SVNException;
+import org.tmatesoft.svn.core.wc.ISVNEventHandler;
+import org.tmatesoft.svn.core.wc.SVNWCClient;
+
+import java.io.File;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+public class SvnKitRevertClient extends BaseSvnClient implements RevertClient {
+
+ @Override
+ public void revert(@NotNull File[] paths, @Nullable SVNDepth depth, @Nullable ISVNEventHandler handler) throws VcsException {
+ SVNWCClient client = myVcs.createWCClient();
+
+ client.setEventHandler(handler);
+ try {
+ client.doRevert(paths, depth, null);
+ }
+ catch (SVNException e) {
+ throw new VcsException(e);
+ }
+ }
+}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/rollback/SvnRollbackEnvironment.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/rollback/SvnRollbackEnvironment.java
index 265d4ca5b9e5..4140ca75a717 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/rollback/SvnRollbackEnvironment.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/rollback/SvnRollbackEnvironment.java
@@ -28,6 +28,7 @@ import com.intellij.util.containers.MultiMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.idea.svn.*;
+import org.jetbrains.idea.svn.revert.RevertClient;
import org.tmatesoft.svn.core.*;
import org.tmatesoft.svn.core.wc.*;
@@ -74,8 +75,7 @@ public class SvnRollbackEnvironment extends DefaultRollbackEnvironment {
checker.gather(changes);
exceptions.addAll(checker.getExceptions());
- final SVNWCClient client = mySvnVcs.createWCClient();
- client.setEventHandler(new ISVNEventHandler() {
+ ISVNEventHandler revertHandler = new ISVNEventHandler() {
public void handleEvent(SVNEvent event, double progress) {
if (event.getAction() == SVNEventAction.REVERT) {
final File file = event.getFile();
@@ -91,7 +91,7 @@ public class SvnRollbackEnvironment extends DefaultRollbackEnvironment {
public void checkCancelled() {
listener.checkCanceled();
}
- });
+ };
final List<CopiedAsideInfo> fromToModified = new ArrayList<CopiedAsideInfo>();
final MultiMap<File, SVNPropertyData> properties = new MultiMap<File, SVNPropertyData>();
@@ -99,7 +99,7 @@ public class SvnRollbackEnvironment extends DefaultRollbackEnvironment {
// adds (deletes)
// deletes (adds)
// modifications
- final Reverter reverter = new Reverter(client, exceptions);
+ final Reverter reverter = new Reverter(mySvnVcs.getFactory().createRevertClient(), revertHandler, exceptions);
reverter.revert(checker.getForAdds(), true);
reverter.revert(checker.getForDeletes(), true);
final List<File> edits = checker.getForEdits();
@@ -256,24 +256,36 @@ public class SvnRollbackEnvironment extends DefaultRollbackEnvironment {
}
private static class Reverter {
- private final SVNWCClient myClient;
+ private final RevertClient myClient;
+ private ISVNEventHandler myHandler;
private final List<VcsException> myExceptions;
- private Reverter(SVNWCClient client, List<VcsException> exceptions) {
+ private Reverter(RevertClient client, ISVNEventHandler handler, List<VcsException> exceptions) {
myClient = client;
+ myHandler = handler;
myExceptions = exceptions;
}
public void revert(final File[] files, final boolean recursive) {
if (files.length == 0) return;
try {
- myClient.doRevert(files, recursive ? SVNDepth.INFINITY : SVNDepth.EMPTY, null);
+ myClient.revert(files, recursive ? SVNDepth.INFINITY : SVNDepth.EMPTY, myHandler);
}
- catch (SVNException e) {
- if (e.getErrorMessage().getErrorCode() != SVNErrorCode.WC_NOT_DIRECTORY) {
- // skip errors on unversioned resources.
- myExceptions.add(new VcsException(e));
+ catch (VcsException e) {
+ processRevertError(e);
+ }
+ }
+
+ private void processRevertError(@NotNull VcsException e) {
+ if (e.getCause() instanceof SVNException) {
+ SVNException cause = (SVNException)e.getCause();
+
+ // skip errors on unversioned resources.
+ if (cause.getErrorMessage().getErrorCode() != SVNErrorCode.WC_NOT_DIRECTORY) {
+ myExceptions.add(e);
}
+ } else {
+ myExceptions.add(e);
}
}
}
@@ -294,18 +306,17 @@ public class SvnRollbackEnvironment extends DefaultRollbackEnvironment {
}
private void revertFileOrDir(File file) throws SVNException, VcsException {
- final SVNWCClient wcClient = mySvnVcs.createWCClient();
- SVNInfo info = wcClient.doInfo(file, SVNRevision.UNDEFINED);
+ SVNInfo info = mySvnVcs.getInfo(file);
if (info != null) {
if (info.getKind() == SVNNodeKind.FILE) {
- wcClient.doRevert(file, false);
+ doRevert(file, false);
} else {
if (SVNProperty.SCHEDULE_ADD.equals(info.getSchedule())) {
- wcClient.doRevert(file, true);
+ doRevert(file, true);
} else {
boolean under17Copy = isUnder17Copy(file, info);
if (under17Copy) {
- wcClient.doRevert(file, true);
+ doRevert(file, true);
} else {
// do update to restore missing directory.
mySvnVcs.createUpdateClient().doUpdate(file, SVNRevision.HEAD, true);
@@ -317,10 +328,16 @@ public class SvnRollbackEnvironment extends DefaultRollbackEnvironment {
}
}
+ private void doRevert(@NotNull File path, boolean recursive) throws VcsException {
+ mySvnVcs.getFactory(path).createRevertClient().revert(new File[]{path}, SVNDepth.fromRecurse(recursive), null);
+ }
+
private boolean isUnder17Copy(final File file, final SVNInfo info) throws VcsException {
final RootsToWorkingCopies copies = mySvnVcs.getRootsToWorkingCopies();
WorkingCopy copy = copies.getMatchingCopy(info.getURL());
if (copy == null) {
+ // TODO: Why null could be here?
+ // TODO: Think we could just rewrite it with mySvnVcs.getWorkingCopyFormat(file)
SVNStatus status = null;
try {
status = mySvnVcs.createStatusClient().doStatus(file, false);
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/update/AbstractSvnUpdatePanel.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/AbstractSvnUpdatePanel.java
index ecc3fa6b5204..d6bdf63cafc8 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/update/AbstractSvnUpdatePanel.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/AbstractSvnUpdatePanel.java
@@ -109,17 +109,8 @@ public abstract class AbstractSvnUpdatePanel {
@Nullable
private SVNURL getUrlFor(@NotNull final FilePath root) {
- try {
- SVNWCClient wcClient = myVCS.createWCClient();
- final SVNInfo info = wcClient.doInfo(root.getIOFile(), SVNRevision.UNDEFINED);
- if (info != null) {
- return info.getURL();
- }
- return null;
- }
- catch (SVNException e) {
- return null;
- }
+ final SVNInfo info = myVCS.getInfo(root.getIOFile());
+ return info != null ? info.getURL() : null;
}
protected abstract JComponent getPanel();
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/update/AbstractUpdateIntegrateCrawler.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/AbstractUpdateIntegrateCrawler.java
index e9e7b0b5f897..826f7532b3a0 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/update/AbstractUpdateIntegrateCrawler.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/AbstractUpdateIntegrateCrawler.java
@@ -59,7 +59,7 @@ public abstract class AbstractUpdateIntegrateCrawler implements SvnWCRootCrawler
SVNUpdateClient client = myVcs.createUpdateClient();
client.setEventHandler(myHandler);
- long rev = doUpdate(root, client);
+ long rev = doUpdate(root);
if (rev < 0 && !isMerge()) {
throw new SVNException(SVNErrorMessage.create(SVNErrorCode.UNKNOWN, SvnBundle.message("exception.text.root.was.not.properly.updated", root)));
@@ -73,9 +73,7 @@ public abstract class AbstractUpdateIntegrateCrawler implements SvnWCRootCrawler
protected abstract void showProgressMessage(ProgressIndicator progress, File root);
- protected abstract long doUpdate(
- File root,
- SVNUpdateClient client) throws SVNException;
+ protected abstract long doUpdate(File root) throws SVNException;
protected abstract boolean isMerge();
}
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/update/MergeRootInfo.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/MergeRootInfo.java
index b8ea0520ebc2..96701b519111 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/update/MergeRootInfo.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/MergeRootInfo.java
@@ -18,6 +18,7 @@ package org.jetbrains.idea.svn.update;
import org.jetbrains.idea.svn.SvnVcs;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNURL;
+import org.tmatesoft.svn.core.wc.SVNInfo;
import org.tmatesoft.svn.core.wc.SVNRevision;
import org.tmatesoft.svn.core.wc.SVNWCClient;
@@ -33,17 +34,9 @@ public class MergeRootInfo {
myRevision1 = SVNRevision.HEAD;
myRevision2 = SVNRevision.HEAD;
- try {
- SVNWCClient wcClient = vcs.createWCClient();
- final SVNURL url = wcClient.doInfo(file, SVNRevision.UNDEFINED).getURL();
- myUrl1 = url.toString();
- myUrl2 = url.toString();
- }
- catch (SVNException e) {
- myUrl1 = "";
- myUrl2 = "";
- }
-
+ SVNInfo info = vcs.getInfo(file);
+ myUrl1 = info != null && info.getURL() != null ? info.getURL().toString() : "";
+ myUrl2 = myUrl1;
}
public SVNURL getUrl1() {
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnIntegrateEnvironment.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnIntegrateEnvironment.java
index 9e8a5991f41c..9f4a95f7016f 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnIntegrateEnvironment.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnIntegrateEnvironment.java
@@ -91,10 +91,7 @@ public class SvnIntegrateEnvironment extends AbstractSvnUpdateIntegrateEnvironme
}
}
- protected long doUpdate(
- final File root,
- final SVNUpdateClient client) throws
- SVNException {
+ protected long doUpdate(final File root) throws SVNException {
final SvnConfiguration svnConfig = SvnConfiguration.getInstance(myVcs.getProject());
MergeRootInfo info = svnConfig.getMergeRootInfo(root, myVcs);
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnUpdateEnvironment.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnUpdateEnvironment.java
index 80e43aaf7828..5d2d4153be50 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnUpdateEnvironment.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/SvnUpdateEnvironment.java
@@ -33,7 +33,6 @@ import org.tmatesoft.svn.core.io.SVNRepository;
import org.tmatesoft.svn.core.wc.SVNInfo;
import org.tmatesoft.svn.core.wc.SVNRevision;
import org.tmatesoft.svn.core.wc.SVNUpdateClient;
-import org.tmatesoft.svn.core.wc.SVNWCClient;
import java.io.File;
import java.util.ArrayList;
@@ -76,10 +75,7 @@ public class SvnUpdateEnvironment extends AbstractSvnUpdateIntegrateEnvironment
progress.setText(SvnBundle.message("progress.text.updating", root.getAbsolutePath()));
}
- protected long doUpdate(
- final File root,
- final SVNUpdateClient client) throws
- SVNException {
+ protected long doUpdate(final File root) throws SVNException {
final long rev;
final SvnConfiguration configuration = SvnConfiguration.getInstance(myVcs.getProject());
@@ -104,13 +100,15 @@ public class SvnUpdateEnvironment extends AbstractSvnUpdateIntegrateEnvironment
private SvnUpdateClientI createUpdateClient(SvnConfiguration configuration, File root, boolean isSwitch, SVNURL sourceUrl) {
final SvnUpdateClientI updateClient;
+ boolean is18Format = myVcs.getWorkingCopyFormat(root) == WorkingCopyFormat.ONE_DOT_EIGHT;
+
// do not do from command line for switch now
- if (! isSwitch && SvnConfiguration.UseAcceleration.commandLine.equals(configuration.myUseAcceleration) &&
+ if (! isSwitch && (is18Format || SvnConfiguration.UseAcceleration.commandLine.equals(configuration.myUseAcceleration) &&
Svn17Detector.is17(myVcs.getProject(), root) && (
SvnAuthenticationManager.HTTP.equals(sourceUrl.getProtocol()) ||
SvnAuthenticationManager.HTTPS.equals(sourceUrl.getProtocol())
- )) {
- updateClient = new SvnCommandLineUpdateClient(myVcs.getProject(), null);
+ ))) {
+ updateClient = new SvnCommandLineUpdateClient(myVcs, null);
} else {
updateClient = new SvnSvnkitUpdateClient(myVcs.createUpdateClient());
}
@@ -129,18 +127,8 @@ public class SvnUpdateEnvironment extends AbstractSvnUpdateIntegrateEnvironment
@Nullable
private static SVNURL getSourceUrl(final SvnVcs vcs, final File root) {
- try {
- SVNWCClient wcClient = vcs.createWCClient();
- final SVNInfo svnInfo = wcClient.doInfo(root, SVNRevision.UNDEFINED);
- if (svnInfo != null) {
- return svnInfo.getURL();
- } else {
- return null;
- }
- }
- catch (SVNException e) {
- return null;
- }
+ final SVNInfo svnInfo = vcs.getInfo(root);
+ return svnInfo != null ? svnInfo.getURL() : null;
}
public boolean validateOptions(final Collection<FilePath> roots) {
@@ -193,9 +181,8 @@ public class SvnUpdateEnvironment extends AbstractSvnUpdateIntegrateEnvironment
// false - do not do update
private boolean checkAncestry(final File sourceFile, final SVNURL targetUrl, final SVNRevision targetRevision) throws SVNException {
- final SVNWCClient client = myVcs.createWCClient();
- final SVNInfo sourceSvnInfo = client.doInfo(sourceFile, SVNRevision.UNDEFINED);
- final SVNInfo targetSvnInfo = client.doInfo(targetUrl, SVNRevision.UNDEFINED, targetRevision);
+ final SVNInfo sourceSvnInfo = myVcs.getInfo(sourceFile);
+ final SVNInfo targetSvnInfo = myVcs.getInfo(targetUrl, targetRevision);
if (sourceSvnInfo == null || targetSvnInfo == null) {
// cannot check
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/update/UpdateRootInfo.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/UpdateRootInfo.java
index 4852e9f6b95f..201260e232f2 100644
--- a/plugins/svn4idea/src/org/jetbrains/idea/svn/update/UpdateRootInfo.java
+++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/update/UpdateRootInfo.java
@@ -31,20 +31,9 @@ public class UpdateRootInfo {
public UpdateRootInfo(File file, SvnVcs vcs) {
myRevision = SVNRevision.HEAD;
- try {
- SVNWCClient wcClient = vcs.createWCClient();
- SVNInfo info = wcClient.doInfo(file, SVNRevision.UNDEFINED);
- if (info != null) {
- final SVNURL url = info.getURL();
- myUrl = url.toString();
- } else {
- myUrl = "";
- }
- }
- catch (SVNException e) {
- myUrl = "";
- }
+ SVNInfo info = vcs.getInfo(file);
+ myUrl = info != null && info.getURL() != null ? info.getDepth().toString() : "";
}
public SVNURL getUrl() {
diff --git a/plugins/svn4idea/svn4idea-tests.iml b/plugins/svn4idea/svn4idea-tests.iml
index 9a537c253abf..0b826ed87489 100644
--- a/plugins/svn4idea/svn4idea-tests.iml
+++ b/plugins/svn4idea/svn4idea-tests.iml
@@ -38,7 +38,6 @@
</SOURCES>
</library>
</orderEntry>
- <orderEntry type="module" module-name="bindSvn" />
</component>
</module>
diff --git a/plugins/svn4idea/svn4idea.iml b/plugins/svn4idea/svn4idea.iml
index 4f0d931cd13f..53dd66166d64 100644
--- a/plugins/svn4idea/svn4idea.iml
+++ b/plugins/svn4idea/svn4idea.iml
@@ -76,16 +76,6 @@
</SOURCES>
</library>
</orderEntry>
- <orderEntry type="module" module-name="bindSvn" />
- <orderEntry type="module-library">
- <library>
- <CLASSES>
- <root url="jar://$MODULE_DIR$/bindSvn/lib/javahl.jar!/" />
- </CLASSES>
- <JAVADOC />
- <SOURCES />
- </library>
- </orderEntry>
</component>
</module>
diff --git a/plugins/svn4idea/testData18/svn/bin/windows/svn.exe b/plugins/svn4idea/testData18/svn/bin/windows/svn.exe
new file mode 100644
index 000000000000..827753f442aa
--- /dev/null
+++ b/plugins/svn4idea/testData18/svn/bin/windows/svn.exe
Binary files differ
diff --git a/plugins/svn4idea/testData18/svn/newrepo.zip b/plugins/svn4idea/testData18/svn/newrepo.zip
new file mode 100644
index 000000000000..fd9a577a39a0
--- /dev/null
+++ b/plugins/svn4idea/testData18/svn/newrepo.zip
Binary files differ
diff --git a/plugins/svn4idea/testSource/org/jetbrains/idea/SvnTestCase.java b/plugins/svn4idea/testSource/org/jetbrains/idea/SvnTestCase.java
index 14d1b4c42897..d5a55520adae 100644
--- a/plugins/svn4idea/testSource/org/jetbrains/idea/SvnTestCase.java
+++ b/plugins/svn4idea/testSource/org/jetbrains/idea/SvnTestCase.java
@@ -78,13 +78,19 @@ import static org.junit.Assert.assertTrue;
* @author yole
*/
public abstract class SvnTestCase extends AbstractJunitVcsTestCase {
+
+ public static String ourGlobalTestDataDir;
+ public static Boolean ourGlobalUseNativeAcceleration;
+
protected TempDirTestFixture myTempDirFixture;
protected String myRepoUrl;
protected TestClientRunner myRunner;
protected String myWcRootName;
- protected boolean myUseNativeAcceleration = new GregorianCalendar().get(Calendar.HOUR_OF_DAY) % 2 == 0;
+ // TODO: Change this to explicitly run either with native acceleration or not.
+ // properties set through run configurations or different runners (like Suite) could be used
+ private boolean myUseNativeAcceleration = new GregorianCalendar().get(Calendar.HOUR_OF_DAY) % 2 == 0;
- protected final String myTestDataDir;
+ private String myTestDataDir;
private File myRepoRoot;
private File myWcRoot;
private ChangeListManagerGate myGate;
@@ -118,7 +124,13 @@ public abstract class SvnTestCase extends AbstractJunitVcsTestCase {
@Before
public void setUp() throws Exception {
- System.out.println("Native client for status: " + myUseNativeAcceleration);
+ System.out.println("Native client for status: " + isUseNativeAcceleration());
+
+ String property = System.getProperty("svn.test.data.directory");
+ if (!StringUtil.isEmpty(property)) {
+ myTestDataDir = property;
+ }
+
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
@Override
public void run() {
@@ -138,7 +150,7 @@ public abstract class SvnTestCase extends AbstractJunitVcsTestCase {
myPluginRoot = new File(rootPath).getParentFile().getParentFile().getParentFile();
}
- File svnBinDir = new File(myPluginRoot, myTestDataDir + "/svn/bin");
+ File svnBinDir = new File(myPluginRoot, getTestDataDir() + "/svn/bin");
File svnExecutable = null;
if (SystemInfo.isWindows) {
svnExecutable = new File(svnBinDir, "windows/svn.exe");
@@ -156,7 +168,7 @@ public abstract class SvnTestCase extends AbstractJunitVcsTestCase {
? createClientRunner(Collections.singletonMap("DYLD_LIBRARY_PATH", myClientBinaryPath.getPath()))
: createClientRunner();
- ZipUtil.extract(new File(myPluginRoot, myTestDataDir + "/svn/newrepo.zip"), myRepoRoot, null);
+ ZipUtil.extract(new File(myPluginRoot, getTestDataDir() + "/svn/newrepo.zip"), myRepoRoot, null);
myWcRoot = new File(myTempDirFixture.getTempDirPath(), myWcRootName);
assert myWcRoot.mkdir() || myWcRoot.isDirectory() : myWcRoot;
@@ -205,7 +217,7 @@ public abstract class SvnTestCase extends AbstractJunitVcsTestCase {
@Override
protected void projectCreated() {
- if (myUseNativeAcceleration) {
+ if (isUseNativeAcceleration()) {
SvnConfiguration.getInstance(myProject).myUseAcceleration = SvnConfiguration.UseAcceleration.commandLine;
SvnApplicationSettings.getInstance().setCommandLinePath(myClientBinaryPath + File.separator + "svn");
}
@@ -319,6 +331,22 @@ public abstract class SvnTestCase extends AbstractJunitVcsTestCase {
//clManager.ensureUpToDate(false);
}
+ public String getTestDataDir() {
+ return StringUtil.isEmpty(ourGlobalTestDataDir) ? myTestDataDir : ourGlobalTestDataDir;
+ }
+
+ public void setTestDataDir(String testDataDir) {
+ myTestDataDir = testDataDir;
+ }
+
+ public boolean isUseNativeAcceleration() {
+ return ourGlobalUseNativeAcceleration != null ? ourGlobalUseNativeAcceleration : myUseNativeAcceleration;
+ }
+
+ public void setUseNativeAcceleration(boolean useNativeAcceleration) {
+ myUseNativeAcceleration = useNativeAcceleration;
+ }
+
protected class SubTree {
public VirtualFile myRootDir;
public VirtualFile mySourceDir;
diff --git a/plugins/svn4idea/testSource/org/jetbrains/idea/svn/IgnoredFilesTest.java b/plugins/svn4idea/testSource/org/jetbrains/idea/svn/IgnoredFilesTest.java
index 270e6d49c607..bded7affdf2c 100644
--- a/plugins/svn4idea/testSource/org/jetbrains/idea/svn/IgnoredFilesTest.java
+++ b/plugins/svn4idea/testSource/org/jetbrains/idea/svn/IgnoredFilesTest.java
@@ -54,6 +54,7 @@ public class IgnoredFilesTest extends Svn17TestCase {
@Before
public void setUp() throws Exception {
+ super.setUp();
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
@Override
public void run() {
diff --git a/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnChangesCorrectlyRefreshedNativeTest.java b/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnChangesCorrectlyRefreshedNativeTest.java
index a9c1074a3d94..6153d658767b 100644
--- a/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnChangesCorrectlyRefreshedNativeTest.java
+++ b/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnChangesCorrectlyRefreshedNativeTest.java
@@ -34,7 +34,7 @@ public class SvnChangesCorrectlyRefreshedNativeTest extends Svn17TestCase {
@Override
public void setUp() throws Exception {
- myUseNativeAcceleration = true;
+ setUseNativeAcceleration(true);
super.setUp();
clManager = ChangeListManager.getInstance(myProject);
diff --git a/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnCommitTest.java b/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnCommitTest.java
index f4da04ea201a..f18b6a578ecb 100644
--- a/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnCommitTest.java
+++ b/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnCommitTest.java
@@ -465,7 +465,7 @@ public class SvnCommitTest extends Svn17TestCase {
return feedback;
}
- private void checkinFile(VirtualFile file, FileStatus status) {
+ protected void checkinFile(VirtualFile file, FileStatus status) {
final Change change = myChangeListManager.getChange(file);
Assert.assertNotNull(change);
Assert.assertEquals(status, change.getFileStatus());
@@ -478,6 +478,7 @@ public class SvnCommitTest extends Svn17TestCase {
}
protected void run2variants(final MyRunner runner) throws Exception {
+ // TODO: Change this to run different variants separately. See SvnTestCase.myUseAcceleration.
setNativeAcceleration(false);
runner.run();
runner.cleanup();
diff --git a/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnExternalTests.java b/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnExternalTests.java
index 500acbdff4c9..3e3b2fda1665 100644
--- a/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnExternalTests.java
+++ b/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnExternalTests.java
@@ -27,6 +27,7 @@ import com.intellij.openapi.vcs.changes.ChangeListManagerImpl;
import com.intellij.openapi.vcs.changes.VcsDirtyScopeManager;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.ui.UIUtil;
import junit.framework.Assert;
import org.junit.Test;
@@ -171,8 +172,7 @@ public class SvnExternalTests extends Svn17TestCase {
private void updatedCreatedExternalFromIDEAImpl() {
final File sourceDir = new File(myWorkingCopyDir.getPath(), "source");
- ProjectLevelVcsManager.getInstance(myProject).setDirectoryMappings(
- Arrays.asList(new VcsDirectoryMapping(FileUtil.toSystemIndependentName(sourceDir.getPath()), myVcs.getName())));
+ setNewDirectoryMappings(sourceDir);
imitUpdate(myProject);
final File externalFile = new File(sourceDir, "external/t11.txt");
@@ -180,6 +180,16 @@ public class SvnExternalTests extends Svn17TestCase {
Assert.assertNotNull(externalVf);
}
+ private void setNewDirectoryMappings(final File sourceDir) {
+ UIUtil.invokeAndWaitIfNeeded(new Runnable() {
+ @Override
+ public void run() {
+ ProjectLevelVcsManager.getInstance(myProject).setDirectoryMappings(
+ Arrays.asList(new VcsDirectoryMapping(FileUtil.toSystemIndependentName(sourceDir.getPath()), myVcs.getName())));
+ }
+ });
+ }
+
@Test
public void testUncommittedExternalStatus() throws Exception {
prepareExternal(false, true, false);
@@ -221,8 +231,7 @@ public class SvnExternalTests extends Svn17TestCase {
private void uncommittedExternalCopyIsDetectedImpl() {
final File sourceDir = new File(myWorkingCopyDir.getPath(), "source");
- ProjectLevelVcsManager.getInstance(myProject).setDirectoryMappings(
- Arrays.asList(new VcsDirectoryMapping(FileUtil.toSystemIndependentName(sourceDir.getPath()), myVcs.getName())));
+ setNewDirectoryMappings(sourceDir);
imitUpdate(myProject);
refreshSvnMappingsSynchronously();
diff --git a/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnLockingTest.java b/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnLockingTest.java
index 171bb1c35cb8..7c32af921f56 100644
--- a/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnLockingTest.java
+++ b/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnLockingTest.java
@@ -22,6 +22,7 @@ import com.intellij.util.concurrency.Semaphore;
import junit.framework.Assert;
import junit.framework.TestCase;
import org.junit.Before;
+import org.junit.Ignore;
import org.tmatesoft.sqljet.core.SqlJetException;
import org.tmatesoft.sqljet.core.table.ISqlJetBusyHandler;
import org.tmatesoft.sqljet.core.table.ISqlJetTransaction;
@@ -42,6 +43,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
* Date: 10/23/12
* Time: 2:27 PM
*/
+// TODO: Locking functionality which is tested by this test is not required anymore. Likely test needs to be removed.
+@Ignore
public class SvnLockingTest extends TestCase {
private File myWorkingCopyRoot;
private SvnTestWriteOperationLocks myLocks;
diff --git a/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnNativeClientAuthTest.java b/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnNativeClientAuthTest.java
index 61aca5670867..b6d6ae104bbc 100644
--- a/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnNativeClientAuthTest.java
+++ b/plugins/svn4idea/testSource/org/jetbrains/idea/svn/SvnNativeClientAuthTest.java
@@ -72,7 +72,7 @@ public class SvnNativeClientAuthTest extends Svn17TestCase {
@Before
public void setUp() throws Exception {
super.setUp();
- final File certFile = new File(myPluginRoot, myTestDataDir + "/svn/____.pfx");
+ final File certFile = new File(myPluginRoot, getTestDataDir() + "/svn/____.pfx");
setNativeAcceleration(true);
myVcs = SvnVcs.getInstance(myProject);
// replace authentication provider so that pass credentials without dialogs
diff --git a/plugins/svn4idea/testSource/org/jetbrains/idea/svn16/SvnChangesCorrectlyRefreshedNativeTest.java b/plugins/svn4idea/testSource/org/jetbrains/idea/svn16/SvnChangesCorrectlyRefreshedNativeTest.java
index 205733657075..8939f1cbf164 100644
--- a/plugins/svn4idea/testSource/org/jetbrains/idea/svn16/SvnChangesCorrectlyRefreshedNativeTest.java
+++ b/plugins/svn4idea/testSource/org/jetbrains/idea/svn16/SvnChangesCorrectlyRefreshedNativeTest.java
@@ -49,7 +49,7 @@ public class SvnChangesCorrectlyRefreshedNativeTest extends Svn17TestCase {
@Override
public void setUp() throws Exception {
- myUseNativeAcceleration = true;
+ setUseNativeAcceleration(true);
super.setUp();
clManager = ChangeListManager.getInstance(myProject);
diff --git a/plugins/svn4idea/testSource/org/jetbrains/idea/svn18/Svn18TestSuite.java b/plugins/svn4idea/testSource/org/jetbrains/idea/svn18/Svn18TestSuite.java
new file mode 100644
index 000000000000..a7019738b9b5
--- /dev/null
+++ b/plugins/svn4idea/testSource/org/jetbrains/idea/svn18/Svn18TestSuite.java
@@ -0,0 +1,33 @@
+package org.jetbrains.idea.svn18;
+
+import org.jetbrains.idea.SvnTestCase;
+import org.jetbrains.idea.svn.*;
+import org.junit.ClassRule;
+import org.junit.rules.ExternalResource;
+import org.junit.rules.TestRule;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+/**
+ * @author Konstantin Kolosovsky.
+ */
+// TODO: Add svn clients for mac and linux
+@RunWith(Suite.class)
+@Suite.SuiteClasses({SvnAddTest.class, SvnDeleteTest.class})
+public class Svn18TestSuite {
+
+ @ClassRule
+ public static TestRule configuration = new ExternalResource() {
+ @Override
+ protected void before() throws Throwable {
+ SvnTestCase.ourGlobalTestDataDir = "testData18";
+ SvnTestCase.ourGlobalUseNativeAcceleration = true;
+ }
+
+ @Override
+ protected void after() {
+ SvnTestCase.ourGlobalTestDataDir = null;
+ SvnTestCase.ourGlobalUseNativeAcceleration = null;
+ }
+ };
+}
diff --git a/plugins/tasks/tasks-api/src/com/intellij/tasks/TaskRepository.java b/plugins/tasks/tasks-api/src/com/intellij/tasks/TaskRepository.java
index 13b8e7df6823..ffa911826be8 100644
--- a/plugins/tasks/tasks-api/src/com/intellij/tasks/TaskRepository.java
+++ b/plugins/tasks/tasks-api/src/com/intellij/tasks/TaskRepository.java
@@ -46,14 +46,12 @@ public abstract class TaskRepository {
public static final int STATE_UPDATING = 0x0008;
/**
* Supporting this feature means that server implements some kind of issues filtering.
- * It may be special query language like the one used in Youtrack or mere plain
+ * It may be special query language like the one used in YouTrack or mere plain
* text search.
- * If server supports this feature it MUST return tasks already
- * filtered according to {@code query} parameter from {@code getIssues} method.
- * Otherwise they will be filtered using {@code TaskSearchSupport#filterTasks}
- *
- * @see com.intellij.tasks.impl.TaskManagerImpl
- * @see com.intellij.tasks.actions.TaskSearchSupport
+ * <p>
+ * If server supports this feature it MUST return tasks already filtered according
+ * to {@code query} parameter from {@link #getIssues}} method, otherwise they will
+ * be filtered internally in {@link TaskManager#getIssues}
*/
public static final int NATIVE_SEARCH = 0x0010;
@@ -106,7 +104,7 @@ public abstract class TaskRepository {
/**
* Get issues from the repository. If query is null, return issues should assigned to current user only.
- * If server supports {@code NATIVE_SEARCH} feature, tasks returned MUST be filtered by specified query.
+ * If server supports {@link #NATIVE_SEARCH} feature, tasks returned MUST be filtered by specified query.
*
* @param query repository specific.
* @param max maximum issues number to return
diff --git a/plugins/tasks/tasks-core/src/META-INF/plugin.xml b/plugins/tasks/tasks-core/src/META-INF/plugin.xml
index 3573bb180bb9..dd42d52a770e 100644
--- a/plugins/tasks/tasks-core/src/META-INF/plugin.xml
+++ b/plugins/tasks/tasks-core/src/META-INF/plugin.xml
@@ -8,6 +8,8 @@
<!--fake dependency for Web IDE-->
<depends>com.intellij.modules.xml</depends>
<depends optional="true" config-file="java-contexts.xml">com.intellij.modules.java</depends>
+ <!-- Optional dependency on XPath plugin for syntax highlighting in GenericRepository configuration dialog -->
+ <depends optional="true">XPathView</depends>
<project-components>
<component>
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/GotoTaskAction.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/GotoTaskAction.java
index cdc20c5e5625..756abdeb526e 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/GotoTaskAction.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/GotoTaskAction.java
@@ -14,7 +14,6 @@ import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.openapi.util.Ref;
-import com.intellij.psi.PsiManager;
import com.intellij.tasks.LocalTask;
import com.intellij.tasks.Task;
import com.intellij.tasks.TaskManager;
@@ -22,7 +21,6 @@ import com.intellij.tasks.doc.TaskPsiElement;
import com.intellij.tasks.impl.TaskManagerImpl;
import com.intellij.tasks.impl.TaskUtil;
import com.intellij.util.ArrayUtil;
-import com.intellij.util.Function;
import com.intellij.util.IconUtil;
import com.intellij.util.Processor;
import com.intellij.util.containers.ContainerUtil;
@@ -67,53 +65,25 @@ public class GotoTaskAction extends GotoActionBase implements DumbAware {
boolean everywhere,
@NotNull ProgressIndicator cancelled,
@NotNull Processor<Object> consumer) {
- List<Task> cachedAndLocalTasks = TaskSearchSupport.getLocalAndCachedTasks(TaskManager.getManager(project), pattern, everywhere);
- List<TaskPsiElement> taskPsiElements = ContainerUtil.map(cachedAndLocalTasks, new Function<Task, TaskPsiElement>() {
- @Override
- public TaskPsiElement fun(Task task) {
- return new TaskPsiElement(PsiManager.getInstance(project), task);
- }
- });
CREATE_NEW_TASK_ACTION.setTaskName(pattern);
- cancelled.checkCanceled();
if (!consumer.process(CREATE_NEW_TASK_ACTION)) return false;
- boolean cachedTasksFound = taskPsiElements.size() != 0;
- if (cachedTasksFound) {
- cancelled.checkCanceled();
- if (!consumer.process(ChooseByNameBase.NON_PREFIX_SEPARATOR)) return false;
- }
-
- for (Object element : taskPsiElements) {
- cancelled.checkCanceled();
- if (!consumer.process(element)) return false;
- }
+ List<Task> cachedAndLocalTasks = TaskSearchSupport.getLocalAndCachedTasks(TaskManager.getManager(project), pattern, everywhere);
+ boolean cachedTasksFound = !cachedAndLocalTasks.isEmpty();
+ if (!processTasks(cachedAndLocalTasks, consumer, cachedTasksFound, cancelled)) return false;
List<Task> tasks = TaskSearchSupport
.getRepositoriesTasks(TaskManager.getManager(project), pattern, base.getMaximumListSizeLimit(), 0, true, everywhere, cancelled);
tasks.removeAll(cachedAndLocalTasks);
- taskPsiElements = ContainerUtil.map(tasks, new Function<Task, TaskPsiElement>() {
- @Override
- public TaskPsiElement fun(Task task) {
- return new TaskPsiElement(PsiManager.getInstance(project), task);
- }
- });
- if (!cachedTasksFound && taskPsiElements.size() != 0) {
- cancelled.checkCanceled();
- if (!consumer.process(ChooseByNameBase.NON_PREFIX_SEPARATOR)) return false;
- }
-
- for (Object element : taskPsiElements) {
- cancelled.checkCanceled();
- if (!consumer.process(element)) return false;
- }
- return true;
+ return processTasks(tasks, consumer, cachedTasksFound, cancelled);
}
}, null, false, 0);
+
popup.setShowListForEmptyPattern(true);
popup.setSearchInAnyPlace(true);
+ popup.setFixLostTyping(false);
popup.setAdText("<html>Press SHIFT to merge with current context<br/>" +
"Pressing " +
KeymapUtil.getFirstKeyboardShortcutText(ActionManager.getInstance().getAction(IdeActions.ACTION_QUICK_JAVADOC)) +
@@ -166,6 +136,16 @@ public class GotoTaskAction extends GotoActionBase implements DumbAware {
}, null, popup);
}
+ private static boolean processTasks(List<Task> tasks, Processor<Object> consumer, boolean cachedTasksFound, ProgressIndicator cancelled) {
+ if (!cachedTasksFound && !tasks.isEmpty() && !consumer.process(ChooseByNameBase.NON_PREFIX_SEPARATOR)) return false;
+
+ for (Object element : tasks) {
+ cancelled.checkCanceled();
+ if (!consumer.process(element)) return false;
+ }
+ return true;
+ }
+
private static void showOpenTaskDialog(final Project project, final Task task) {
JBPopup hint = DocumentationManager.getInstance(project).getDocInfoHint();
if (hint != null) hint.cancel();
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/OpenTaskDialog.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/OpenTaskDialog.java
index 489afb921af2..3eeea41976ec 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/OpenTaskDialog.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/OpenTaskDialog.java
@@ -117,6 +117,11 @@ public class OpenTaskDialog extends DialogWrapper {
@Override
protected void doOKAction() {
+ createTask();
+ super.doOKAction();
+ }
+
+ public void createTask() {
TaskManagerImpl taskManager = (TaskManagerImpl)TaskManager.getManager(myProject);
taskManager.getState().markAsInProgress = isMarkAsInProgress();
@@ -133,18 +138,17 @@ public class OpenTaskDialog extends DialogWrapper {
LOG.warn(ex);
}
}
+ LocalTask activeTask = taskManager.getActiveTask();
LocalTask localTask = taskManager.activateTask(myTask, isClearContext());
if (myCreateChangelist.isSelected()) {
taskManager.createChangeList(localTask, myChangelistName.getText());
}
if (myCreateBranch.isSelected()) {
- LocalTask activeTask = taskManager.getActiveTask();
taskManager.createBranch(localTask, activeTask, myBranchName.getText());
}
if (myTask.getType() == TaskType.EXCEPTION && AnalyzeTaskStacktraceAction.hasTexts(myTask)) {
AnalyzeTaskStacktraceAction.analyzeStacktrace(myTask, myProject);
}
- super.doOKAction();
}
@Nullable
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/TaskCellRenderer.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/TaskCellRenderer.java
index 65a4d454e864..bb8f458d7f0e 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/TaskCellRenderer.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/TaskCellRenderer.java
@@ -7,7 +7,6 @@ import com.intellij.openapi.util.IconLoader;
import com.intellij.tasks.LocalTask;
import com.intellij.tasks.Task;
import com.intellij.tasks.TaskManager;
-import com.intellij.tasks.doc.TaskPsiElement;
import com.intellij.ui.LayeredIcon;
import com.intellij.ui.SimpleColoredComponent;
import com.intellij.ui.SimpleTextAttributes;
@@ -39,8 +38,8 @@ public class TaskCellRenderer extends DefaultListCellRenderer implements Matcher
final JPanel panel = new JPanel(new BorderLayout());
panel.setBackground(UIUtil.getListBackground(sel));
panel.setForeground(UIUtil.getListForeground(sel));
- if (value instanceof TaskPsiElement) {
- final Task task = ((TaskPsiElement)value).getTask();
+ if (value instanceof Task) {
+ final Task task = ((Task)value);
final SimpleColoredComponent c = new SimpleColoredComponent();
final TaskManager taskManager = TaskManager.getManager(myProject);
final boolean isLocalTask = taskManager.findTask(task.getId()) != null;
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/TaskSearchSupport.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/TaskSearchSupport.java
index c2c6306207e2..98704b7c1429 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/TaskSearchSupport.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/actions/TaskSearchSupport.java
@@ -77,12 +77,7 @@ public class TaskSearchSupport {
String pattern,
boolean cached,
boolean autopopup) {
- final Matcher matcher = getMatcher(pattern);
- return ContainerUtil.mapNotNull(getTasks(pattern, cached, autopopup, myManager), new NullableFunction<Task, Task>() {
- public Task fun(Task task) {
- return matcher.matches(task.getId()) || matcher.matches(task.getSummary()) ? task : null;
- }
- });
+ return filterTasks(pattern, getTasks(pattern, cached, autopopup, myManager));
}
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/context/WorkingContextManager.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/context/WorkingContextManager.java
index 5c4733b4d4ca..f437897dcb7b 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/context/WorkingContextManager.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/context/WorkingContextManager.java
@@ -27,6 +27,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.JDOMUtil;
import com.intellij.openapi.util.WriteExternalException;
+import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.tasks.Task;
import com.intellij.util.NullableFunction;
@@ -170,7 +171,7 @@ public class WorkingContextManager {
//noinspection ResultOfMethodCallIgnored
tasksFolder.mkdir();
}
- String projectName = myProject.getName();
+ String projectName = FileUtil.sanitizeFileName(myProject.getName());
return new File(tasksFolder, projectName + postfix);
}
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepository.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepository.java
index f3ed0f92b411..c4c5869fbab4 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepository.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepository.java
@@ -16,6 +16,7 @@ import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.GetMethod;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -31,19 +32,22 @@ import static com.intellij.tasks.generic.TemplateVariable.*;
public class GenericRepository extends BaseRepositoryImpl {
private static final Logger LOG = Logger.getInstance(GenericRepository.class);
- public final PredefinedFactoryVariable SERVER_URL_TEMPLATE_VARIABLE = new PredefinedFactoryVariable("serverUrl") {
+ public final FactoryVariable SERVER_URL_TEMPLATE_VARIABLE = new FactoryVariable("serverUrl") {
+ @NotNull
@Override
public String getValue() {
return GenericRepository.this.getUrl();
}
};
- public final PredefinedFactoryVariable USERNAME_TEMPLATE_VARIABLE = new PredefinedFactoryVariable("username") {
+ public final FactoryVariable USERNAME_TEMPLATE_VARIABLE = new FactoryVariable("username") {
+ @NotNull
@Override
public String getValue() {
return GenericRepository.this.getUsername();
}
};
- public final PredefinedFactoryVariable PASSWORD_TEMPLATE_VARIABLE = new PredefinedFactoryVariable("password", true) {
+ public final FactoryVariable PASSWORD_TEMPLATE_VARIABLE = new FactoryVariable("password", true) {
+ @NotNull
@Override
public String getValue() {
return GenericRepository.this.getPassword();
@@ -155,7 +159,7 @@ public class GenericRepository extends BaseRepositoryImpl {
public boolean isConfigured() {
if (!super.isConfigured()) return false;
for (TemplateVariable variable : getTemplateVariables()) {
- if (variable.getIsShownOnFirstTab() && StringUtil.isEmpty(variable.getValue())) {
+ if (variable.isShownOnFirstTab() && StringUtil.isEmpty(variable.getValue())) {
return false;
}
}
@@ -171,8 +175,8 @@ public class GenericRepository extends BaseRepositoryImpl {
executeMethod(getLoginMethod());
}
List<TemplateVariable> variables = concat(getAllTemplateVariables(),
- new TemplateVariable("max", max),
- new TemplateVariable("since", since));
+ new TemplateVariable("max", String.valueOf(max)),
+ new TemplateVariable("since", String.valueOf(since)));
String requestUrl = GenericRepositoryUtil.substituteTemplateVariables(getTasksListUrl(), variables);
String responseBody = executeMethod(getHttpMethod(requestUrl, myTasksListMethodType));
Task[] tasks = getActiveResponseHandler().parseIssues(responseBody, max);
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepositoryEditor.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepositoryEditor.java
index 6ddb8da103b5..c677744fe958 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepositoryEditor.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepositoryEditor.java
@@ -131,7 +131,7 @@ public class GenericRepositoryEditor<T extends GenericRepository> extends BaseRe
myRepository.setTemplateVariables(ContainerUtil.filter(dialog.getTemplateVariables(), new Condition<TemplateVariable>() {
@Override
public boolean value(TemplateVariable variable) {
- return !variable.getIsPredefined();
+ return !variable.isReadOnly();
}
}));
myCustomPanel.removeAll();
@@ -186,8 +186,8 @@ public class GenericRepositoryEditor<T extends GenericRepository> extends BaseRe
myField2Variable = new IdentityHashMap<JTextField, TemplateVariable>();
FormBuilder builder = FormBuilder.createFormBuilder();
for (final TemplateVariable variable : myRepository.getTemplateVariables()) {
- if (variable.getIsShownOnFirstTab()) {
- JTextField field = variable.getIsHidden() ? new JPasswordField(variable.getValue()) : new JTextField(variable.getValue());
+ if (variable.isShownOnFirstTab()) {
+ JTextField field = variable.isHidden() ? new JPasswordField(variable.getValue()) : new JTextField(variable.getValue());
myField2Variable.put(field, variable);
installListener(field);
JBLabel label = new JBLabel(prettifyVariableName(variable.getName()) + ":", SwingConstants.RIGHT);
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepositoryType.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepositoryType.java
index 1a9bb42ca461..95f865b846c1 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepositoryType.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepositoryType.java
@@ -59,7 +59,8 @@ public class GenericRepositoryType extends BaseRepositoryType<GenericRepository>
public List<TaskRepositorySubtype> getAvailableSubtypes() {
return Arrays.asList(
this,
- new AsanaRepository()
+ new AsanaRepository(),
+ new AssemblaRepository()
);
}
@@ -111,4 +112,10 @@ public class GenericRepositoryType extends BaseRepositoryType<GenericRepository>
super("Asana", TasksIcons.Asana);
}
}
+
+ public class AssemblaRepository extends GenericSubtype {
+ public AssemblaRepository() {
+ super("Assembla", TasksIcons.Assembla);
+ }
+ }
}
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/JsonPathResponseHandler.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/JsonPathResponseHandler.java
index cc80ed29e5ba..c97a77fcf6fd 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/JsonPathResponseHandler.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/JsonPathResponseHandler.java
@@ -1,7 +1,5 @@
package com.intellij.tasks.generic;
-import com.intellij.openapi.fileTypes.FileType;
-import com.intellij.openapi.fileTypes.PlainTextFileType;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.Function;
@@ -17,7 +15,7 @@ import java.util.List;
import java.util.Map;
/**
- * Author: Mikhail Golubev
+ * @author Mikhail Golubev
*/
@Tag("JsonResponseHandler")
public final class JsonPathResponseHandler extends SelectorBasedResponseHandler {
@@ -44,11 +42,6 @@ public final class JsonPathResponseHandler extends SelectorBasedResponseHandler
super(repository);
}
- @Override
- public FileType getSelectorFileType() {
- return PlainTextFileType.INSTANCE;
- }
-
@Nullable
private Object extractRawValue(@NotNull Selector selector, @NotNull String source) throws Exception {
if (StringUtil.isEmpty(selector.getPath())) {
@@ -140,6 +133,7 @@ public final class JsonPathResponseHandler extends SelectorBasedResponseHandler
return myCompiledCache.get(path);
}
+ @NotNull
@Override
public ResponseType getResponseType() {
return ResponseType.JSON;
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/ManageTemplateVariablesDialog.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/ManageTemplateVariablesDialog.java
index e9e6d5e8460f..3c3ed235454a 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/ManageTemplateVariablesDialog.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/ManageTemplateVariablesDialog.java
@@ -60,7 +60,7 @@ public class ManageTemplateVariablesDialog extends DialogWrapper {
@Override
public boolean isCellEditable(TemplateVariable templateVariable) {
- return !templateVariable.getIsPredefined();
+ return !templateVariable.isReadOnly();
}
@Override
@@ -82,7 +82,7 @@ public class ManageTemplateVariablesDialog extends DialogWrapper {
@Override
public boolean isCellEditable(TemplateVariable templateVariable) {
- return !templateVariable.getIsPredefined();
+ return !templateVariable.isReadOnly();
}
@Override
@@ -93,7 +93,7 @@ public class ManageTemplateVariablesDialog extends DialogWrapper {
@Override
public TableCellRenderer getRenderer(TemplateVariable variable) {
- if (variable.getIsHidden()) {
+ if (variable.isHidden()) {
return new TableCellRenderer() {
@Override
public Component getTableCellRendererComponent(JTable table,
@@ -112,7 +112,7 @@ public class ManageTemplateVariablesDialog extends DialogWrapper {
@Nullable
@Override
public TableCellEditor getEditor(final TemplateVariable variable) {
- if (variable.getIsHidden()) {
+ if (variable.isHidden()) {
return new AbstractTableCellEditor() {
private JPasswordField myPasswordField;
@Override
@@ -141,12 +141,12 @@ public class ManageTemplateVariablesDialog extends DialogWrapper {
@Nullable
@Override
public Boolean valueOf(TemplateVariable o) {
- return o.getIsShownOnFirstTab();
+ return o.isShownOnFirstTab();
}
@Override
public void setValue(TemplateVariable variable, Boolean value) {
- variable.setIsShownOnFirstTab(value);
+ variable.setShownOnFirstTab(value);
setModified();
}
@@ -157,7 +157,7 @@ public class ManageTemplateVariablesDialog extends DialogWrapper {
@Override
public boolean isCellEditable(TemplateVariable variable) {
- return !variable.getIsPredefined();
+ return !variable.isReadOnly();
}
@Nullable
@@ -171,12 +171,12 @@ public class ManageTemplateVariablesDialog extends DialogWrapper {
@Nullable
@Override
public Boolean valueOf(TemplateVariable o) {
- return o.getIsHidden();
+ return o.isHidden();
}
@Override
public void setValue(TemplateVariable variable, Boolean value) {
- variable.setIsHidden(value);
+ variable.setHidden(value);
setModified();
// value column editor may be changed
TemplateVariablesTable.this.refreshValues();
@@ -189,7 +189,7 @@ public class ManageTemplateVariablesDialog extends DialogWrapper {
@Override
public boolean isCellEditable(TemplateVariable variable) {
- return !variable.getIsPredefined();
+ return !variable.isReadOnly();
}
@Nullable
@@ -203,7 +203,7 @@ public class ManageTemplateVariablesDialog extends DialogWrapper {
@Override
protected TemplateVariable createElement() {
- return new TemplateVariable("", "", false, null);
+ return new TemplateVariable("", "");
}
@Override
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/RegExResponseHandler.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/RegExResponseHandler.java
index c08085194712..4d7f5a50dab2 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/RegExResponseHandler.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/RegExResponseHandler.java
@@ -68,8 +68,9 @@ public final class RegExResponseHandler extends ResponseHandler {
return myTaskRegex.hashCode();
}
+ @NotNull
@Override
- public JComponent getConfigurationComponent(Project project) {
+ public JComponent getConfigurationComponent(@NotNull Project project) {
FormBuilder builder = FormBuilder.createFormBuilder();
final EditorTextField taskPatternText;
taskPatternText = new LanguageTextField(RegExpLanguage.INSTANCE, project, myTaskRegex, false);
@@ -86,7 +87,7 @@ public final class RegExResponseHandler extends ResponseHandler {
@NotNull
@Override
- public Task[] parseIssues(String response, int max) throws Exception {
+ public Task[] parseIssues(@NotNull String response, int max) throws Exception {
final List<String> placeholders = getPlaceholders(myTaskRegex);
if (!placeholders.contains(ID_PLACEHOLDER) || !placeholders.contains(SUMMARY_PLACEHOLDER)) {
throw new Exception("Incorrect Task Pattern");
@@ -120,7 +121,7 @@ public final class RegExResponseHandler extends ResponseHandler {
@Nullable
@Override
- public Task parseIssue(String response) throws Exception {
+ public Task parseIssue(@NotNull String response) throws Exception {
return null;
}
@@ -150,6 +151,7 @@ public final class RegExResponseHandler extends ResponseHandler {
return !StringUtil.isEmpty(myTaskRegex);
}
+ @NotNull
@Override
public ResponseType getResponseType() {
return ResponseType.TEXT;
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/ResponseHandler.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/ResponseHandler.java
index d51c38ac1bf7..cb8830b6f7cf 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/ResponseHandler.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/ResponseHandler.java
@@ -10,7 +10,7 @@ import javax.swing.*;
/**
* ResponseHandler subclasses represent different strategies of extracting tasks from
- * task server responses (e.g. using regular expressions, XPath, JSONPath, CSS selector etc.).
+ * task server responses (e.g. using regular expressions, XPath, JSONPath, CSS selector etc.)
*
* @see XPathResponseHandler
* @see JsonPathResponseHandler
@@ -19,36 +19,40 @@ import javax.swing.*;
*/
public abstract class ResponseHandler implements Cloneable {
- // XXX: what about serialization of circular dependencies?
protected GenericRepository myRepository;
- // Serialization constructor
+ /**
+ * Serialization constructor
+ */
public ResponseHandler() {
// empty
}
- public ResponseHandler(GenericRepository repository) {
+ public ResponseHandler(@NotNull GenericRepository repository) {
myRepository = repository;
}
- public void setRepository(GenericRepository repository) {
+ public void setRepository(@NotNull GenericRepository repository) {
myRepository = repository;
}
+ @NotNull
@Transient
public GenericRepository getRepository() {
return myRepository;
}
- public abstract JComponent getConfigurationComponent(Project project);
+ @NotNull
+ public abstract JComponent getConfigurationComponent(@NotNull Project project);
+ @NotNull
public abstract ResponseType getResponseType();
@NotNull
- public abstract Task[] parseIssues(String response, int max) throws Exception;
+ public abstract Task[] parseIssues(@NotNull String response, int max) throws Exception;
@Nullable
- public abstract Task parseIssue(String response) throws Exception;
+ public abstract Task parseIssue(@NotNull String response) throws Exception;
public abstract boolean isConfigured();
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/ResponseType.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/ResponseType.java
index aa4bd782b35c..8889e26babfc 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/ResponseType.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/ResponseType.java
@@ -2,40 +2,82 @@ package com.intellij.tasks.generic;
import com.intellij.ide.highlighter.HtmlFileType;
import com.intellij.ide.highlighter.XmlFileType;
+import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.fileTypes.PlainTextFileType;
import org.intellij.lang.regexp.RegExpFileType;
-import org.intellij.lang.xpath.XPathFileType;
+import org.jetbrains.annotations.NotNull;
+
/**
- * User: evgeny.zakrevsky
- * Date: 10/25/12
+ * ResponseType contains information about what selector types used
+ * to extract information from server responses with specific content-type.
+ *
+ * @author evgeny.zakrevsky
+ * @author Mikhail Golubev
*/
public enum ResponseType {
- XML("application/xml", XmlFileType.INSTANCE, XPathFileType.XPATH2),
- JSON("application/json", PlainTextFileType.INSTANCE, PlainTextFileType.INSTANCE),
+
+ XML("application/xml", XmlFileType.INSTANCE, findXPathFileType()),
+ JSON("application/json", findFileTypePlainDefault("JSON"), PlainTextFileType.INSTANCE),
// TODO: think about possible selector type if it needed at all (e.g. CSS selector)
HTML("text/html", HtmlFileType.INSTANCE, PlainTextFileType.INSTANCE),
TEXT("text/plain", PlainTextFileType.INSTANCE, RegExpFileType.INSTANCE);
- private String myMimeType;
- private FileType myContentFileType;
- private FileType mySelectorFileType;
+ private final String myMimeType;
+ private final FileType myContentFileType;
+ private final FileType mySelectorFileType;
+
+ private static Logger LOG = Logger.getInstance(ResponseType.class);
+
- ResponseType(final String s, final FileType contentFileType, final FileType selectorFileType) {
+ ResponseType(@NotNull String s, @NotNull FileType contentFileType, @NotNull FileType selectorFileType) {
myMimeType = s;
myContentFileType = contentFileType;
mySelectorFileType = selectorFileType;
}
+ /**
+ * Unfortunately XPATH instance can't be received this way, because XPathSupportLoader
+ * registers XPathFileType in FileTypeManager only in unit test and debug modes
+ */
+ @NotNull
+ private static FileType findFileTypePlainDefault(@NotNull final String name) {
+ FileType fileType = FileTypeManager.getInstance().findFileTypeByName(name);
+ return fileType == null ? PlainTextFileType.INSTANCE : fileType;
+ }
+
+ /**
+ * Temporary workaround for IDEA-112605
+ */
+ @NotNull
+ private static FileType findXPathFileType() {
+ if (LOG == null) {
+ LOG = Logger.getInstance(ResponseType.class);
+ }
+ try {
+ Class<?> xPathClass = Class.forName("org.intellij.lang.xpath.XPathFileType");
+ LOG.debug("XPathFileType class loaded successfully");
+ return (FileType)xPathClass.getField("XPATH").get(null);
+ }
+ catch (Exception e) {
+ LOG.debug("XPathFileType class not found. Using PlainText.INSTANCE instead");
+ return PlainTextFileType.INSTANCE;
+ }
+ }
+
+ @NotNull
public String getMimeType() {
return myMimeType;
}
+ @NotNull
public FileType getContentFileType() {
return myContentFileType;
}
+ @NotNull
public FileType getSelectorFileType() {
return mySelectorFileType;
}
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/SelectorBasedResponseHandler.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/SelectorBasedResponseHandler.java
index 865e43db81a2..0394cc57094e 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/SelectorBasedResponseHandler.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/SelectorBasedResponseHandler.java
@@ -1,5 +1,6 @@
package com.intellij.tasks.generic;
+import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
@@ -24,6 +25,7 @@ import java.util.List;
* @author Mikhail Golubev
*/
public abstract class SelectorBasedResponseHandler extends ResponseHandler {
+ private static final Logger LOG = Logger.getInstance(SelectorBasedResponseHandler.class);
// Supported selector names
@NonNls protected static final String TASKS = "tasks";
@@ -81,8 +83,6 @@ public abstract class SelectorBasedResponseHandler extends ResponseHandler {
));
}
- public abstract FileType getSelectorFileType();
-
@Tag("selectors")
@Property(surroundWithTag = false)
@AbstractCollection(surroundWithTag = false)
@@ -112,11 +112,11 @@ public abstract class SelectorBasedResponseHandler extends ResponseHandler {
return s.getPath();
}
+ @NotNull
@Override
- public JComponent getConfigurationComponent(Project project) {
- HighlightedSelectorsTable table = new HighlightedSelectorsTable(getSelectorFileType(),
- project,
- getSelectors());
+ public JComponent getConfigurationComponent(@NotNull Project project) {
+ FileType fileType = getResponseType().getSelectorFileType();
+ HighlightedSelectorsTable table = new HighlightedSelectorsTable(fileType, project, getSelectors());
return new JBScrollPane(table);
}
@@ -158,13 +158,14 @@ public abstract class SelectorBasedResponseHandler extends ResponseHandler {
@NotNull
@Override
- public final Task[] parseIssues(String response, int max) throws Exception {
+ public final Task[] parseIssues(@NotNull String response, int max) throws Exception {
if (StringUtil.isEmpty(getSelectorPath(TASKS)) ||
StringUtil.isEmpty(getSelectorPath(ID)) ||
StringUtil.isEmpty(getSelectorPath(SUMMARY))) {
throw new Exception("Selectors 'tasks', 'id' and 'summary' are mandatory");
}
List<Object> tasks = selectTasksList(response, max);
+ LOG.debug(String.format("Total %d tasks extracted from response", tasks.size()));
List<Task> result = new ArrayList<Task>(tasks.size());
for (Object context : tasks) {
String id = selectString(getSelector(ID), context);
@@ -232,7 +233,7 @@ public abstract class SelectorBasedResponseHandler extends ResponseHandler {
@Nullable
@Override
- public final Task parseIssue(String response) throws Exception {
+ public final Task parseIssue(@NotNull String response) throws Exception {
if (StringUtil.isEmpty(getSelectorPath(SINGLE_TASK_ID)) ||
StringUtil.isEmpty(getSelectorPath(SINGLE_TASK_SUMMARY))) {
throw new Exception("Selectors 'singleTask-id' and 'singleTask-summary' are mandatory");
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/TemplateVariable.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/TemplateVariable.java
index d8377bb49f59..f3b59fe2738a 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/TemplateVariable.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/TemplateVariable.java
@@ -3,51 +3,42 @@ package com.intellij.tasks.generic;
import com.intellij.util.xmlb.annotations.Attribute;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
/**
- * User: evgeny.zakrevsky
- * Date: 10/26/12
+ * Editable variable which name can be used as placeholder and auto completed in EditorFields of
+ * {@link GenericRepositoryEditor}. Variables is editable via {@link ManageTemplateVariablesDialog},
+ * but if {@code shownOnFirstTab} property was set, it will also be shown on "General" tab among
+ * standard fields like "Server URL", "Username" and "Password".
+ *
+ * @see GenericRepositoryEditor
+ * @see ManageTemplateVariablesDialog
+ *
+ * @author evgeny.zakrevsky
+ * @author Mikhail Golubev
*/
public class TemplateVariable {
private String myName;
private String myValue = "";
- private String myDescription;
- private boolean myIsPredefined;
- private boolean myIsHidden;
- private boolean myIsShownOnFirstTab;
+ private String myDescription = "";
+ private boolean myReadOnly;
+ private boolean myHidden;
+ private boolean myShownOnFirstTab;
- public static TemplateVariableBuilder builder(String name) {
- return new TemplateVariableBuilder(name);
- }
-
- private TemplateVariable(TemplateVariableBuilder builder) {
- myName = builder.myName;
- myValue = builder.myValue;
- myDescription = builder.myDescription;
- myIsHidden = builder.myIsHidden;
- myIsShownOnFirstTab = builder.myIsShowOnFirstTab;
- myIsPredefined = builder.myIsPredefined;
- }
-
- public TemplateVariable(String name, Object value) {
- this(name, value, false, "");
- }
-
- public TemplateVariable(@NotNull @NonNls String name, @NotNull @NonNls Object value, boolean isPredefined, @Nullable String description) {
+ public TemplateVariable(@NotNull @NonNls String name, @NotNull @NonNls String value) {
myName = name;
myValue = String.valueOf(value);
- myIsPredefined = isPredefined;
- myDescription = description;
+ myReadOnly = false;
+ myDescription = "";
}
/**
* Serialization constructor
*/
+ @SuppressWarnings("unusedDesclaration")
public TemplateVariable() {
+ // empty
}
-
/**
* Cloning constructor
*/
@@ -55,157 +46,119 @@ public class TemplateVariable {
myName = other.getName();
myValue = other.getValue();
myDescription = other.getDescription();
- myIsHidden = other.getIsHidden();
- myIsPredefined = other.getIsPredefined();
- myIsShownOnFirstTab = other.getIsShownOnFirstTab();
+ myHidden = other.isHidden();
+ myReadOnly = other.isReadOnly();
+ myShownOnFirstTab = other.isShownOnFirstTab();
}
- public void setName(String name) {
+ public void setName(@NotNull @NonNls String name) {
myName = name;
}
- public void setValue(String value) {
+ public void setValue(@NotNull @NonNls String value) {
myValue = value;
}
+ @NotNull
public String getName() {
return myName;
}
+ @NotNull
public String getValue() {
return myValue;
}
- @Nullable
+ // TODO: actually not used in UI
+ @NotNull
public String getDescription() {
return myDescription;
}
- @Attribute("isPredefined")
- public boolean getIsPredefined() {
- return myIsPredefined;
+ public void setDescription(@NotNull @NonNls String description) {
+ myDescription = description;
+ }
+
+ @Attribute("readOnly")
+ public boolean isReadOnly() {
+ return myReadOnly;
}
- public void setIsPredefined(boolean isPredefined) {
- myIsPredefined = isPredefined;
+ public void setReadOnly(boolean readOnly) {
+ myReadOnly = readOnly;
}
- @Attribute("isHidden")
- public boolean getIsHidden() {
- return myIsHidden;
+ @Attribute("hidden")
+ public boolean isHidden() {
+ return myHidden;
}
- public void setIsHidden(boolean isHidden) {
- myIsHidden = isHidden;
+ public void setHidden(boolean hidden) {
+ myHidden = hidden;
}
@Attribute("shownOnFirstTab")
- public boolean getIsShownOnFirstTab() {
- return myIsShownOnFirstTab;
+ public boolean isShownOnFirstTab() {
+ return myShownOnFirstTab;
}
- public void setIsShownOnFirstTab(boolean isShownOnFirstTab) {
- myIsShownOnFirstTab = isShownOnFirstTab;
+ public void setShownOnFirstTab(boolean shownOnFirstTab) {
+ myShownOnFirstTab = shownOnFirstTab;
}
public TemplateVariable clone() {
return new TemplateVariable(this);
}
- public void setDescription(final String description) {
- myDescription = description;
- }
-
@Override
public String toString() {
return String.format("TemplateVariable(name='%s', value='%s')", getName(), getValue());
}
- public static class TemplateVariableBuilder {
- private String myName;
- private String myValue = "";
- private String myDescription;
- private boolean myIsHidden;
- private boolean myIsPredefined;
- private boolean myIsShowOnFirstTab;
-
- private TemplateVariableBuilder(String name) {
- myName = name;
- }
-
- public TemplateVariableBuilder value(Object value) {
- myValue = String.valueOf(value);
- return this;
- }
-
- public TemplateVariableBuilder description(String description) {
- myDescription = description;
- return this;
- }
-
- public TemplateVariableBuilder isHidden(boolean isHidden) {
- myIsHidden = isHidden;
- return this;
- }
-
- public TemplateVariableBuilder isPredefined(boolean isPredefined) {
- myIsPredefined = isPredefined;
- return this;
- }
-
- public TemplateVariableBuilder isShownOnFirstTab(boolean isShowOnFirstTab) {
- myIsShowOnFirstTab = isShowOnFirstTab;
- return this;
- }
-
- public TemplateVariable build() {
- return new TemplateVariable(this);
- }
- }
-
/**
* Represents predefined template variable such as "serverUrl", "login" or "password" which are not
* set explicitly by user but instead taken from repository itself.
+ *
+ * @see GenericRepository
*/
- public abstract static class PredefinedFactoryVariable extends TemplateVariable {
+ public abstract static class FactoryVariable extends TemplateVariable {
- protected PredefinedFactoryVariable(String name) {
+ protected FactoryVariable(@NotNull @NonNls String name) {
this(name, false);
}
- public PredefinedFactoryVariable(String name, boolean isHidden) {
- this(name, name, isHidden);
+ public FactoryVariable(@NotNull @NonNls String name, boolean hidden) {
+ super(name, "");
+ setHidden(hidden);
}
- public PredefinedFactoryVariable(String name, String description, boolean isHidden) {
- super(builder(name).description(description).isHidden(isHidden));
- }
+ @NotNull
@Override
public abstract String getValue();
@Override
- public final void setName(String name) {
+ public final void setName(@NotNull String name) {
throw new UnsupportedOperationException("Name of predefined variable can't be changed");
}
@Override
- public final void setValue(String value) {
+ public final void setValue(@NotNull String value) {
throw new UnsupportedOperationException("Value of predefined variable can't be changed explicitly");
}
@Override
- public final void setIsShownOnFirstTab(boolean isShownOnFirstTab) {
+ public final void setShownOnFirstTab(boolean shownOnFirstTab) {
throw new UnsupportedOperationException("This parameter can't be changed for predefined variable");
}
@Override
- public void setIsPredefined(boolean isPredefined) {
+ public void setReadOnly(boolean readOnly) {
throw new UnsupportedOperationException("This parameter can't be changed for predefined variable");
}
@Override
- public boolean getIsPredefined() {
+ public boolean isReadOnly() {
return true;
}
}
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/XPathResponseHandler.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/XPathResponseHandler.java
index f768258d817d..8d82ac189f50 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/XPathResponseHandler.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/XPathResponseHandler.java
@@ -1,10 +1,8 @@
package com.intellij.tasks.generic;
-import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.containers.HashMap;
import com.intellij.util.xmlb.annotations.Tag;
-import org.intellij.lang.xpath.XPathFileType;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
@@ -79,11 +77,7 @@ public final class XPathResponseHandler extends SelectorBasedResponseHandler {
return myCompiledCache.get(path);
}
- @Override
- public FileType getSelectorFileType() {
- return XPathFileType.XPATH;
- }
-
+ @NotNull
@Override
public ResponseType getResponseType() {
return ResponseType.XML;
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/connectors/asana.xml b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/connectors/asana.xml
index 942ca6f7f68a..94d69c153be1 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/connectors/asana.xml
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/connectors/asana.xml
@@ -55,8 +55,8 @@
<option name="tasksListUrl" value="{serverUrl}/projects/{project_ID}/tasks?assignee=me"/>
<option name="templateVariables">
<list>
- <TemplateVariable isHidden="false" isPredefined="false" shownOnFirstTab="true">
- <option name="description"/>
+ <TemplateVariable hidden="false" readOnly="false" shownOnFirstTab="true">
+ <option name="description" value=""/>
<option name="name" value="project_ID"/>
<option name="value" value=""/>
</TemplateVariable>
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/connectors/assembla.xml b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/connectors/assembla.xml
new file mode 100644
index 000000000000..da466a6014c8
--- /dev/null
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/connectors/assembla.xml
@@ -0,0 +1,64 @@
+<Assembla shared="false" url="http://www.assembla.com">
+ <commitMessageFormat>{id} {summary}</commitMessageFormat>
+ <option name="downloadTasksInSeparateRequests" value="false" />
+ <password/>
+ <option name="loginAnonymously" value="false" />
+ <option name="loginMethodType" value="GET" />
+ <option name="loginUrl" value="" />
+ <option name="responseHandlers">
+ <XPathResponseHandler>
+ <selectors>
+ <selector name="tasks" path="/tickets/ticket" />
+ <selector name="id" path="id" />
+ <selector name="summary" path="summary" />
+ <selector name="description" path="description" />
+ <selector name="updated" path="updated-at" />
+ <selector name="created" path="created-on" />
+ <selector name="closed" path="" />
+ <selector name="issueUrl" path="" />
+ <selector name="singleTask-id" path="" />
+ <selector name="singleTask-summary" path="" />
+ <selector name="singleTask-description" path="" />
+ <selector name="singleTask-updated" path="" />
+ <selector name="singleTask-created" path="" />
+ <selector name="singleTask-closed" path="" />
+ <selector name="singleTask-issueUrl" path="" />
+ </selectors>
+ </XPathResponseHandler>
+ <JsonResponseHandler>
+ <selectors>
+ <selector name="tasks" path="" />
+ <selector name="id" path="" />
+ <selector name="summary" path="" />
+ <selector name="description" path="" />
+ <selector name="updated" path="" />
+ <selector name="created" path="" />
+ <selector name="closed" path="" />
+ <selector name="issueUrl" path="" />
+ <selector name="singleTask-id" path="" />
+ <selector name="singleTask-summary" path="" />
+ <selector name="singleTask-description" path="" />
+ <selector name="singleTask-updated" path="" />
+ <selector name="singleTask-created" path="" />
+ <selector name="singleTask-closed" path="" />
+ <selector name="singleTask-issueUrl" path="" />
+ </selectors>
+ </JsonResponseHandler>
+ <RegExResponseHandler>
+ <option name="taskRegex" value=""/>
+ </RegExResponseHandler>
+ </option>
+ <option name="responseType" value="XML" />
+ <option name="shouldFormatCommitMessage" value="false" />
+ <option name="singleTaskMethodType" value="GET" />
+ <option name="singleTaskUrl" value="" />
+ <option name="subtypeName" />
+ <option name="tasksListMethodType" value="GET" />
+ <option name="tasksListUrl" value="http://www.assembla.com/tickets.xml" />
+ <option name="templateVariables">
+ <list />
+ </option>
+ <option name="useHttpAuthentication" value="true" />
+ <option name="useProxy" value="false" />
+ <username/>
+</Assembla>
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/JqlElementType.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/JqlElementType.java
index fde826e4a62c..9d9dc9118997 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/JqlElementType.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/JqlElementType.java
@@ -15,22 +15,49 @@
*/
package com.intellij.tasks.jira.jql;
+import com.intellij.extapi.psi.ASTWrapperPsiElement;
+import com.intellij.lang.ASTNode;
+import com.intellij.psi.PsiElement;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
+import java.lang.reflect.Constructor;
+
/**
* @author Mikhail Golubev
*/
public class JqlElementType extends IElementType {
- private String myName;
+ private static final Class<?>[] PARAMETER_TYPES = {ASTNode.class};
+
+ private final Class<? extends PsiElement> myClass;
+ private Constructor<? extends PsiElement> myConstructor;
+
public JqlElementType(@NotNull @NonNls String debugName) {
+ this(debugName, ASTWrapperPsiElement.class);
+ }
+
+ public JqlElementType(@NotNull @NonNls String debugName, @NotNull Class<? extends PsiElement> cls) {
super(debugName, JqlLanguage.INSTANCE);
- myName = debugName;
+ myClass = cls;
}
@Override
public String toString() {
return "JQL: " + super.toString();
}
+
+ @NotNull
+ public PsiElement createElement(@NotNull ASTNode node) {
+ try {
+ if (myConstructor == null) {
+ myConstructor = myClass.getConstructor(PARAMETER_TYPES);
+ }
+ return myConstructor.newInstance(node);
+ }
+ catch (Exception e) {
+ throw new AssertionError(
+ String.format("Class %s must have constructor accepting single ASTNode parameter", myClass.getName()));
+ }
+ }
}
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/JqlElementTypes.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/JqlElementTypes.java
index 68a989335cb4..9919eb6d1d85 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/JqlElementTypes.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/JqlElementTypes.java
@@ -3,6 +3,7 @@ package com.intellij.tasks.jira.jql;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.IFileElementType;
import com.intellij.psi.tree.TokenSet;
+import com.intellij.tasks.jira.jql.psi.impl.*;
/**
* @author Mikhail Golubev
@@ -14,8 +15,9 @@ import com.intellij.psi.tree.TokenSet;
* or_clause ::= and_clause {or_op and_clause}
* and_clause ::= not_expr {and_op not_expr}
* not_expr ::= not_op not_expr
- * | "(" or_clause ")"
+ * | subclause
* | terminal_clause
+ * subclause ::= "(" or_clause ")"
* terminal_clause ::= simple_clause
* | was_clause
* | changed_clause
@@ -46,11 +48,12 @@ import com.intellij.psi.tree.TokenSet;
* field ::= string
* | NUMBER
* | CUSTOM_FIELD
- * operand ::= ("empty" | "null")
+ * operand ::= empty
* | string
* | NUMBER
* | func
* | list
+ * empty ::= "empty" | "null"
* list ::= "(" operand {"," operand} ")"
* func ::= fname "(" arg_list ")"
* # function name can be even number (!)
@@ -58,7 +61,7 @@ import com.intellij.psi.tree.TokenSet;
* arg_list ::= argument {"," argument}
* argument ::= string | NUMBER
* string ::= SQUOTED_STRING
- * | QUOTED_STRIN
+ * | QUOTED_STRING
* | UNQOUTED_STRING
* order_by ::= "order" "by" sort_key {sort_key}
* sort_key ::= field ("asc" | "desc")
@@ -66,26 +69,28 @@ import com.intellij.psi.tree.TokenSet;
*/
public interface JqlElementTypes {
IFileElementType FILE = new IFileElementType(JqlLanguage.INSTANCE);
- IElementType QUERY = new JqlElementType("QUERY");
- IElementType OR_CLAUSE = new JqlElementType("OR_CLAUSE");
- IElementType AND_CLAUSE = new JqlElementType("AND_CLAUSE");
- IElementType NOT_CLAUSE = new JqlElementType("NOT_CLAUSE");
+ IElementType QUERY = new JqlElementType("QUERY", JqlQueryImpl.class);
+ IElementType OR_CLAUSE = new JqlElementType("OR_CLAUSE", JqlOrClauseImpl.class);
+ IElementType AND_CLAUSE = new JqlElementType("AND_CLAUSE", JqlAndClauseImpl.class);
+ IElementType NOT_CLAUSE = new JqlElementType("NOT_CLAUSE", JqlNotClauseImpl.class);
+ // actually parenthesized clause, named so to be consistent with official grammar
+ IElementType SUB_CLAUSE = new JqlElementType("SUB_CLAUSE", JqlSubClauseImpl.class);
//IElementType TERMINAL_CLAUSE = new JqlElementType("TERMINAL_CLAUSE");
// field (= | != | ~ | !~ | < | > | <= | >= | is [not] | [not] in) value
- IElementType SIMPLE_CLAUSE = new JqlElementType("SIMPLE_CLAUSE");
+ IElementType SIMPLE_CLAUSE = new JqlElementType("SIMPLE_CLAUSE", JqlSimpleClauseImpl.class);
// field was [not] [in] value {history_predicate}
- IElementType WAS_CLAUSE = new JqlElementType("WAS_CLAUSE");
+ IElementType WAS_CLAUSE = new JqlElementType("WAS_CLAUSE", JqlWasClauseImpl.class);
// field changed {history_predicate}
- IElementType CHANGED_CLAUSE = new JqlElementType("CHANGED_CLAUSE");
- IElementType LIST = new JqlElementType("LIST");
- IElementType ORDER_BY = new JqlElementType("ORDER_BY");
- IElementType IDENTIFIER = new JqlElementType("IDENTIFIER");
- IElementType LITERAL = new JqlElementType("LITERAL");
- IElementType FUNCTION_CALL = new JqlElementType("FUNCTION_CALL");
- IElementType ARGUMENT_LIST = new JqlElementType("ARGUMENT_LIST");
- IElementType SORT_KEY = new JqlElementType("SORT_KEY");
- IElementType EMPTY = new JqlElementType("EMPTY");
- IElementType HISTORY_PREDICATE = new JqlElementType("HISTORY_PREDICATE");
+ IElementType CHANGED_CLAUSE = new JqlElementType("CHANGED_CLAUSE", JqlChangedClauseImpl.class);
+ IElementType LIST = new JqlElementType("LIST", JqlListImpl.class);
+ IElementType ORDER_BY = new JqlElementType("ORDER_BY", JqlOrderByImpl.class);
+ IElementType IDENTIFIER = new JqlElementType("IDENTIFIER", JqlIdentifierImpl.class);
+ IElementType LITERAL = new JqlElementType("LITERAL", JqlLiteralImpl.class);
+ IElementType FUNCTION_CALL = new JqlElementType("FUNCTION_CALL", JqlFunctionCallImpl.class);
+ IElementType ARGUMENT_LIST = new JqlElementType("ARGUMENT_LIST", JqlArgumentListImpl.class);
+ IElementType SORT_KEY = new JqlElementType("SORT_KEY", JqlSortKeyImpl.class);
+ IElementType EMPTY = new JqlElementType("EMPTY", JqlEmptyValueImpl.class);
+ IElementType HISTORY_PREDICATE = new JqlElementType("HISTORY_PREDICATE", JqlHistoryPredicateImpl.class);
TokenSet OPERAND_NODES = TokenSet.create(
JqlTokenTypes.NUMBER_LITERAL, JqlTokenTypes.STRING_LITERAL, LIST, FUNCTION_CALL
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/JqlParser.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/JqlParser.java
index 1dcac3633cd1..2021bc943ae0 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/JqlParser.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/JqlParser.java
@@ -12,7 +12,7 @@ import org.jetbrains.annotations.NotNull;
* @author Mikhail Golubev
*/
public class JqlParser implements PsiParser {
- private static final Logger LOG = Logger.getInstance("#com.intellij.tasks.jira.jql.JqlParser");
+ private static final Logger LOG = Logger.getInstance(JqlParser.class);
@NotNull
@Override
@@ -92,16 +92,17 @@ public class JqlParser implements PsiParser {
}
private boolean parseSubClause(PsiBuilder builder) {
+ LOG.assertTrue(builder.getTokenType() == JqlTokenTypes.LPAR);
+ PsiBuilder.Marker marker = builder.mark();
if (!advanceIfMatches(builder, JqlTokenTypes.LPAR)) {
+ marker.drop();
return false;
}
- if (!parseORClause(builder)) {
- return false;
- }
+ parseORClause(builder);
if (!advanceIfMatches(builder, JqlTokenTypes.RPAR)) {
builder.error("Expecting ')'");
- return false;
}
+ marker.done(JqlElementTypes.SUB_CLAUSE);
return true;
}
@@ -142,6 +143,7 @@ public class JqlParser implements PsiParser {
}
private void parseCHANGEDClause(PsiBuilder builder) {
+ LOG.assertTrue(builder.getTokenType() == JqlTokenTypes.CHANGED_KEYWORD);
if (!advanceIfMatches(builder, JqlTokenTypes.CHANGED_KEYWORD)) {
return;
}
@@ -151,6 +153,7 @@ public class JqlParser implements PsiParser {
}
private void parseWASClause(PsiBuilder builder) {
+ LOG.assertTrue(builder.getTokenType() == JqlTokenTypes.WAS_KEYWORD);
if (!advanceIfMatches(builder, JqlTokenTypes.WAS_KEYWORD)) {
return;
}
@@ -163,6 +166,7 @@ public class JqlParser implements PsiParser {
}
private void parseHistoryPredicate(PsiBuilder builder) {
+ LOG.assertTrue(JqlTokenTypes.HISTORY_PREDICATES.contains(builder.getTokenType()));
PsiBuilder.Marker marker = builder.mark();
if (!advanceIfMatches(builder, JqlTokenTypes.HISTORY_PREDICATES)) {
marker.drop();
@@ -204,6 +208,7 @@ public class JqlParser implements PsiParser {
}
private boolean parseList(PsiBuilder builder) {
+ LOG.assertTrue(builder.getTokenType() == JqlTokenTypes.LPAR);
PsiBuilder.Marker marker = builder.mark();
if (!advanceIfMatches(builder, JqlTokenTypes.LPAR)) {
marker.drop();
@@ -235,6 +240,7 @@ public class JqlParser implements PsiParser {
}
private void parseArgumentList(PsiBuilder builder) {
+ LOG.assertTrue(builder.getTokenType() == JqlTokenTypes.LPAR);
PsiBuilder.Marker marker = builder.mark();
if (!advanceIfMatches(builder, JqlTokenTypes.LPAR)) {
marker.drop();
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/JqlParserDefinition.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/JqlParserDefinition.java
index 7e3eb55dffbf..a8269625fcfd 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/JqlParserDefinition.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/JqlParserDefinition.java
@@ -13,7 +13,6 @@ import com.intellij.psi.PsiFile;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.IFileElementType;
import com.intellij.psi.tree.TokenSet;
-import com.intellij.tasks.jira.jql.psi.impl.*;
import org.jetbrains.annotations.NotNull;
/**
@@ -59,54 +58,9 @@ public class JqlParserDefinition implements ParserDefinition {
@NotNull
@Override
public PsiElement createElement(ASTNode node) {
- IElementType type = node.getElementType();
- if (type == JqlElementTypes.QUERY) {
- return new JqlQueryImpl(node);
- }
- if (type == JqlElementTypes.AND_CLAUSE) {
- return new JqlAndClauseImpl(node);
- }
- if (type == JqlElementTypes.OR_CLAUSE) {
- return new JqlOrClauseImpl(node);
- }
- if (type == JqlElementTypes.NOT_CLAUSE) {
- return new JqlNotClauseImpl(node);
- }
- if (type == JqlElementTypes.SIMPLE_CLAUSE) {
- return new JqlSimpleClauseImpl(node);
- }
- if (type == JqlElementTypes.WAS_CLAUSE) {
- return new JqlWasClauseImpl(node);
- }
- if (type == JqlElementTypes.CHANGED_CLAUSE) {
- return new JqlChangedClauseImpl(node);
- }
- if (type == JqlElementTypes.FUNCTION_CALL) {
- return new JqlFunctionCallImpl(node);
- }
- if (type == JqlElementTypes.IDENTIFIER) {
- return new JqlIdentifierImpl(node);
- }
- if (type == JqlElementTypes.HISTORY_PREDICATE) {
- return new JqlHistoryPredicateImpl(node);
- }
- if (type == JqlElementTypes.ARGUMENT_LIST) {
- return new JqlArgumentListImpl(node);
- }
- if (type == JqlElementTypes.LITERAL) {
- return new JqlLiteralImpl(node);
- }
- if (type == JqlElementTypes.EMPTY) {
- return new JqlEmptyValueImpl(node);
- }
- if (type == JqlElementTypes.LIST) {
- return new JqlListImpl(node);
- }
- if (type == JqlElementTypes.SORT_KEY) {
- return new JqlSortKeyImpl(node);
- }
- if (type == JqlElementTypes.ORDER_BY) {
- return new JqlOrderByImpl(node);
+ final IElementType type = node.getElementType();
+ if (type instanceof JqlElementType) {
+ return ((JqlElementType)type).createElement(node);
}
return new ASTWrapperPsiElement(node);
}
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/JqlTokenTypes.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/JqlTokenTypes.java
index 1d0c6f1c6a0e..ddb8bdf577a6 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/JqlTokenTypes.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/JqlTokenTypes.java
@@ -104,12 +104,6 @@ public interface JqlTokenTypes {
TokenSet HISTORY_PREDICATES = TokenSet.create(
ON_KEYWORD, BEFORE_KEYWORD, AFTER_KEYWORD, DURING_KEYWORD, FROM_KEYWORD, TO_KEYWORD, BY_KEYWORD
);
- TokenSet WAS_CONSTRAINTS = TokenSet.create(
- ON_KEYWORD, BEFORE_KEYWORD, AFTER_KEYWORD, DURING_KEYWORD, BY_KEYWORD
- );
- TokenSet CHANGED_CONSTRAINTS = TokenSet.create(
- ON_KEYWORD, BEFORE_KEYWORD, AFTER_KEYWORD, DURING_KEYWORD, FROM_KEYWORD, TO_KEYWORD, BY_KEYWORD
- );
TokenSet SORT_ORDERS = TokenSet.create(ASC_KEYWORD, DESC_KEYWORD);
TokenSet EMPTY_VALUES = TokenSet.create(EMPTY_KEYWORD, NULL_KEYWORD);
TokenSet LITERALS = TokenSet.create(NUMBER_LITERAL, STRING_LITERAL);
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/codeinsight/JqlCompletionContributor.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/codeinsight/JqlCompletionContributor.java
index 484a357bc0c1..e243402b14c0 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/codeinsight/JqlCompletionContributor.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/codeinsight/JqlCompletionContributor.java
@@ -55,15 +55,15 @@ public class JqlCompletionContributor extends CompletionContributor {
if (!(element instanceof PsiElement)) return false;
PsiElement prevLeaf = PsiTreeUtil.prevVisibleLeaf((PsiElement)element);
if (prevLeaf == null) return false;
- PsiElement enclosingClause = PsiTreeUtil.findFirstParent(prevLeaf, new Condition<PsiElement>() {
+ PsiElement parent = PsiTreeUtil.findFirstParent(prevLeaf, new Condition<PsiElement>() {
@Override
public boolean value(PsiElement element) {
return pattern.accepts(element);
}
});
- if (enclosingClause == null) return false;
- if (PsiTreeUtil.hasErrorElements(enclosingClause)) return false;
- return prevLeaf.getTextRange().getEndOffset() == enclosingClause.getTextRange().getEndOffset();
+ if (parent == null) return false;
+ if (PsiTreeUtil.hasErrorElements(parent)) return false;
+ return prevLeaf.getTextRange().getEndOffset() == parent.getTextRange().getEndOffset();
}
@Override
@@ -83,7 +83,10 @@ public class JqlCompletionContributor extends CompletionContributor {
psiElement().and(rightAfterElement(JqlClauseWithHistoryPredicates.class));
private static final PsiElementPattern.Capture<PsiElement> AFTER_ANY_CLAUSE =
- psiElement().and(rightAfterElement(JqlTerminalClause.class));
+ psiElement().andOr(
+ rightAfterElement(JqlTerminalClause.class),
+ // in other words after closing parenthesis
+ rightAfterElement(JqlSubClause.class));
private static final PsiElementPattern.Capture<PsiElement> AFTER_ORDER_KEYWORD =
psiElement().afterLeaf(psiElement(JqlTokenTypes.ORDER_KEYWORD));
@@ -263,7 +266,6 @@ public class JqlCompletionContributor extends CompletionContributor {
JqlFieldType operandType;
boolean listFunctionExpected;
PsiElement curElem = parameters.getPosition();
- PsiElement origElem = parameters.getOriginalPosition();
JqlHistoryPredicate predicate = PsiTreeUtil.getParentOfType(curElem, JqlHistoryPredicate.class);
if (predicate != null) {
listFunctionExpected = false;
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/psi/JqlElementVisitor.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/psi/JqlElementVisitor.java
index e0dc6895cb44..bbf71debe8c0 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/psi/JqlElementVisitor.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/psi/JqlElementVisitor.java
@@ -3,6 +3,7 @@ package com.intellij.tasks.jira.jql.psi;
import com.intellij.psi.PsiElementVisitor;
import com.intellij.tasks.jira.jql.psi.impl.JqlArgumentListImpl;
import com.intellij.tasks.jira.jql.psi.impl.JqlHistoryPredicateImpl;
+import com.intellij.tasks.jira.jql.psi.impl.JqlSubClauseImpl;
/**
* @author Mikhail Golubev
@@ -40,4 +41,6 @@ public abstract class JqlElementVisitor extends PsiElementVisitor {
public abstract void visitJqlArgumentList(JqlArgumentListImpl list);
public abstract void visitJqlHistoryPredicate(JqlHistoryPredicateImpl predicate);
+
+ public abstract void visitJqlSubClause(JqlSubClauseImpl subClause);
}
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/psi/JqlQuery.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/psi/JqlQuery.java
index b832b9d684c3..79bb3bfee8f8 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/psi/JqlQuery.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/psi/JqlQuery.java
@@ -9,7 +9,7 @@ import org.jetbrains.annotations.Nullable;
public interface JqlQuery extends JqlElement {
@Nullable
JqlClause getClause();
- boolean isOrdered();
- @NotNull
- JqlSortKey[] getOrderKeys();
+
+ @Nullable
+ JqlOrderBy getOrderBy();
}
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/psi/JqlSubClause.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/psi/JqlSubClause.java
new file mode 100644
index 000000000000..c28de2880d57
--- /dev/null
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/psi/JqlSubClause.java
@@ -0,0 +1,11 @@
+package com.intellij.tasks.jira.jql.psi;
+
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Mikhail Golubev
+ */
+public interface JqlSubClause extends JqlClause {
+ @Nullable
+ JqlClause getInnerClause();
+}
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/psi/JqlTerminalClause.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/psi/JqlTerminalClause.java
index d16a1064e404..f44016189fb1 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/psi/JqlTerminalClause.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/psi/JqlTerminalClause.java
@@ -10,7 +10,7 @@ import java.util.IdentityHashMap;
/**
* @author Mikhail Golubev
*/
-public interface JqlTerminalClause extends JqlElement {
+public interface JqlTerminalClause extends JqlClause {
enum Type {
EQ(false),
NE(false),
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/psi/impl/JqlQueryImpl.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/psi/impl/JqlQueryImpl.java
index c9ed11a745f1..0565800e8e1a 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/psi/impl/JqlQueryImpl.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/psi/impl/JqlQueryImpl.java
@@ -1,11 +1,9 @@
package com.intellij.tasks.jira.jql.psi.impl;
import com.intellij.lang.ASTNode;
-import com.intellij.tasks.jira.jql.psi.JqlClause;
-import com.intellij.tasks.jira.jql.psi.JqlElementVisitor;
-import com.intellij.tasks.jira.jql.psi.JqlSortKey;
-import com.intellij.tasks.jira.jql.psi.JqlQuery;
+import com.intellij.tasks.jira.jql.psi.*;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
/**
* @author Mikhail Golubev
@@ -25,13 +23,9 @@ public class JqlQueryImpl extends JqlElementImpl implements JqlQuery {
return findChildByClass(JqlClause.class);
}
+ @Nullable
@Override
- public boolean isOrdered() {
- return getOrderKeys().length != 0;
- }
-
- @Override
- public JqlSortKey[] getOrderKeys() {
- return findChildrenByClass(JqlSortKey.class);
+ public JqlOrderBy getOrderBy() {
+ return findChildByClass(JqlOrderBy.class);
}
}
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/psi/impl/JqlSubClauseImpl.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/psi/impl/JqlSubClauseImpl.java
new file mode 100644
index 000000000000..05f959a17e09
--- /dev/null
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/jira/jql/psi/impl/JqlSubClauseImpl.java
@@ -0,0 +1,28 @@
+package com.intellij.tasks.jira.jql.psi.impl;
+
+import com.intellij.lang.ASTNode;
+import com.intellij.tasks.jira.jql.psi.JqlClause;
+import com.intellij.tasks.jira.jql.psi.JqlElementVisitor;
+import com.intellij.tasks.jira.jql.psi.JqlSubClause;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Mikhail Golubev
+ */
+public class JqlSubClauseImpl extends JqlElementImpl implements JqlSubClause {
+ public JqlSubClauseImpl(@NotNull ASTNode node) {
+ super(node);
+ }
+
+ @Override
+ public void accept(JqlElementVisitor visitor) {
+ visitor.visitJqlSubClause(this);
+ }
+
+ @Nullable
+ @Override
+ public JqlClause getInnerClause() {
+ return findChildByClass(JqlClause.class);
+ }
+}
diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/redmine/RedmineRepository.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/redmine/RedmineRepository.java
index f1571fb61447..697e71be7a02 100644
--- a/plugins/tasks/tasks-core/src/com/intellij/tasks/redmine/RedmineRepository.java
+++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/redmine/RedmineRepository.java
@@ -185,10 +185,10 @@ public class RedmineRepository extends BaseRepositoryImpl {
// Ad-hoc fix for IDEA-110012
Date parsed;
try {
- parsed = (new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy", Locale.US)).parse(date);
+ parsed = new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy", Locale.US).parse(date);
}
catch (ParseException e) {
- LOG.warn("Unparseable date: " + date, e);
+ LOG.warn("Unparseable date: '" + date + "'. Trying ISO-8601 format instead.");
parsed = TaskUtil.parseDate(date);
}
return parsed;
diff --git a/plugins/tasks/tasks-core/tasks-core.iml b/plugins/tasks/tasks-core/tasks-core.iml
index 11c3bc9c626a..460f43fcfe5c 100644
--- a/plugins/tasks/tasks-core/tasks-core.iml
+++ b/plugins/tasks/tasks-core/tasks-core.iml
@@ -39,7 +39,6 @@
<orderEntry type="library" name="gson" level="project" />
<orderEntry type="module" module-name="xml" />
<orderEntry type="module" module-name="core-api" />
- <orderEntry type="module" module-name="xpath" />
<orderEntry type="module" module-name="RegExpSupport" />
<orderEntry type="module-library">
<library>
diff --git a/plugins/tasks/tasks-tests/test/com/intellij/tasks/TaskUtilTest.java b/plugins/tasks/tasks-tests/test/com/intellij/tasks/TaskUtilTest.java
new file mode 100644
index 000000000000..def2a678f2da
--- /dev/null
+++ b/plugins/tasks/tasks-tests/test/com/intellij/tasks/TaskUtilTest.java
@@ -0,0 +1,51 @@
+package com.intellij.tasks;
+
+import com.intellij.tasks.impl.TaskUtil;
+import org.jetbrains.annotations.NotNull;
+import org.junit.Test;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.TimeZone;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+/**
+ * @author Mikhail Golubev
+ */
+public class TaskUtilTest {
+ private static final SimpleDateFormat FORMATTER = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
+ static {
+ FORMATTER.setTimeZone(TimeZone.getTimeZone("GMT"));
+ }
+
+ private static void compareDates(@NotNull Date expected, @NotNull String formattedDate) {
+ Date parsed = TaskUtil.parseDate(formattedDate);
+ assertEquals(expected, parsed);
+ }
+
+ /**
+ * Test ISO8601 date parsing
+ */
+ @Test
+ public void testDateParsings() throws Exception {
+ final Date expected = FORMATTER.parse("2013-08-23 10:11:12.000");
+ final Date expectedWithMillis = FORMATTER.parse("2013-08-23 10:11:12.100");
+ // JIRA, Redmine and Pivotal
+ compareDates(expectedWithMillis, "2013-08-23T14:11:12.100+0400");
+ // Trello
+ compareDates(expectedWithMillis, "2013-08-23T10:11:12.100Z");
+ // Assmbla
+ compareDates(expectedWithMillis, "2013-08-23T14:11:12.100+04:00");
+
+ // Formatting variations
+ compareDates(expected, "2013/08/23 10:11:12");
+ compareDates(expectedWithMillis, "2013-08-23 14:11:12.100123+04");
+
+ // Malformed date
+ assertNull(TaskUtil.parseDate("Fri Aug 23 14:11:12 MSK 2013"));
+ assertNull(TaskUtil.parseDate("2013/00/23"));
+ assertNull(TaskUtil.parseDate("2013/08/23 10:11:12 GMT+04:00"));
+ }
+} \ No newline at end of file
diff --git a/plugins/tasks/tasks-tests/test/com/intellij/tasks/context/ContextTest.java b/plugins/tasks/tasks-tests/test/com/intellij/tasks/context/ContextTest.java
index 98a3dd05944e..029b9a7d208e 100644
--- a/plugins/tasks/tasks-tests/test/com/intellij/tasks/context/ContextTest.java
+++ b/plugins/tasks/tasks-tests/test/com/intellij/tasks/context/ContextTest.java
@@ -17,6 +17,7 @@
package com.intellij.tasks.context;
import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.project.impl.ProjectImpl;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.tasks.TaskManagerTestCase;
import com.intellij.xdebugger.XDebuggerManager;
@@ -93,6 +94,18 @@ public class ContextTest extends TaskManagerTestCase {
manager.clearContext();
}
+ public void testContextFileName() throws Exception {
+ ProjectImpl project = (ProjectImpl)getProject();
+ String name = project.getName();
+ try {
+ project.setProjectName("invalid | name");
+ getContextManager().saveContext("foo", "bar");
+ }
+ finally {
+ project.setProjectName(name);
+ }
+ }
+
private WorkingContextManager getContextManager() {
return WorkingContextManager.getInstance(getProject());
}
diff --git a/plugins/tasks/tasks-tests/test/com/intellij/tasks/jira/jql/CompletionTest.java b/plugins/tasks/tasks-tests/test/com/intellij/tasks/jira/jql/CompletionTest.java
index d3ee5b12c5f6..6269e48deb8e 100644
--- a/plugins/tasks/tasks-tests/test/com/intellij/tasks/jira/jql/CompletionTest.java
+++ b/plugins/tasks/tasks-tests/test/com/intellij/tasks/jira/jql/CompletionTest.java
@@ -104,10 +104,14 @@ public class CompletionTest extends CodeInsightFixtureTestCase {
checkCompletionVariants(JqlStandardFunction.allOfType(JqlFieldType.DATE, false));
}
- public void testAfterParenthesisInSubClause() throws Exception {
+ public void testAfterLeftParenthesisInSubClause() throws Exception {
checkCompletionVariants(ALL_FIELD_NAMES, "not");
}
+ public void testAfterSubClause() throws Exception {
+ checkCompletionVariants("and", "or", "order by");
+ }
+
public void testFunctionArguments() throws Exception {
// only literals accepted so we can't assume anything
checkCompletionVariants(ContainerUtil.<String>emptyList());
diff --git a/plugins/tasks/tasks-tests/test/com/intellij/tasks/vcs/TaskBranchesTest.java b/plugins/tasks/tasks-tests/test/com/intellij/tasks/vcs/TaskBranchesTest.java
index 1261d1239180..36cc584ba1a4 100644
--- a/plugins/tasks/tasks-tests/test/com/intellij/tasks/vcs/TaskBranchesTest.java
+++ b/plugins/tasks/tasks-tests/test/com/intellij/tasks/vcs/TaskBranchesTest.java
@@ -15,10 +15,17 @@
*/
package com.intellij.tasks.vcs;
+import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vcs.ProjectLevelVcsManager;
import com.intellij.openapi.vcs.VcsTaskHandler;
+import com.intellij.openapi.vcs.changes.*;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.tasks.BranchInfo;
import com.intellij.tasks.LocalTask;
import com.intellij.tasks.TaskManager;
+import com.intellij.tasks.actions.OpenTaskDialog;
import com.intellij.tasks.impl.LocalTaskImpl;
import com.intellij.tasks.impl.TaskManagerImpl;
import com.intellij.testFramework.PlatformTestCase;
@@ -29,8 +36,10 @@ import git4idea.config.GitVcsSettings;
import git4idea.repo.GitRepository;
import git4idea.test.GitExecutor;
import git4idea.test.GitTestUtil;
+import git4idea.util.GitFileUtils;
import java.io.File;
+import java.util.Collections;
import java.util.List;
/**
@@ -41,6 +50,8 @@ import java.util.List;
public class TaskBranchesTest extends PlatformTestCase {
private TaskManagerImpl myTaskManager;
+ private ChangeListManagerImpl myChangeListManager;
+ private VcsDirtyScopeManagerImpl myDirtyScopeManager;
public void testGitTaskHandler() throws Exception {
@@ -104,6 +115,46 @@ public class TaskBranchesTest extends PlatformTestCase {
myTaskManager.activateTask(foo, false);
}
+ public void testCommit() throws Exception {
+ GitRepository repository = initRepository("foo");
+ LocalTask defaultTask = myTaskManager.getActiveTask();
+ LocalTaskImpl foo = myTaskManager.createLocalTask("foo");
+ final LocalTask localTask = myTaskManager.activateTask(foo, false);
+ myTaskManager.createBranch(localTask, defaultTask, myTaskManager.suggestBranchName(localTask));
+
+ VirtualFile root = repository.getRoot();
+ File file = new File(root.getPath(), "foo.txt");
+ assertTrue(file.createNewFile());
+ final VirtualFile virtualFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(file);
+ GitFileUtils.addFiles(getProject(), root, virtualFile);
+ myDirtyScopeManager.fileDirty(virtualFile);
+ myChangeListManager.ensureUpToDate(false);
+ Change change = myChangeListManager.getChange(virtualFile);
+ assertNotNull(change);
+ ProjectLevelVcsManager.getInstance(getProject()).getAllActiveVcss()[0].getCheckinEnvironment()
+ .commit(Collections.singletonList(change), "foo");
+ myTaskManager.mergeBranch(localTask);
+
+ repository.update();
+ assertEquals("master", repository.getCurrentBranch().getName());
+ assertEquals(1, repository.getBranches().getLocalBranches().size());
+ }
+
+ public void testOpenTaskDialog() throws Exception {
+ initRepository("foo");
+ LocalTaskImpl task = myTaskManager.createLocalTask("foo");
+ OpenTaskDialog dialog = new OpenTaskDialog(getProject(), task);
+ Disposer.register(myTestRootDisposable, dialog.getDisposable());
+ dialog.createTask();
+ assertEquals("foo", myTaskManager.getActiveTask().getSummary());
+ List<BranchInfo> branches = task.getBranches(true);
+ assertEquals(1, branches.size());
+ assertEquals("master", branches.get(0).name);
+ branches = task.getBranches(false);
+ assertEquals(1, branches.size());
+ assertEquals("foo", branches.get(0).name);
+ }
+
private List<GitRepository> initRepositories(String... names) {
return ContainerUtil.map(names, new Function<String, GitRepository>() {
@Override
@@ -128,5 +179,10 @@ public class TaskBranchesTest extends PlatformTestCase {
super.setUp();
myTaskManager = (TaskManagerImpl)TaskManager.getManager(getProject());
GitVcsSettings.getInstance(myProject).getAppSettings().setPathToGit(GitExecutor.GIT_EXECUTABLE);
+
+ myChangeListManager = (ChangeListManagerImpl)ChangeListManager.getInstance(getProject());
+ myChangeListManager.projectOpened();
+ myDirtyScopeManager = ((VcsDirtyScopeManagerImpl)VcsDirtyScopeManager.getInstance(getProject()));
+ myDirtyScopeManager.projectOpened();
}
}
diff --git a/plugins/tasks/tasks-tests/testData/jira/jql/completion/AfterParenthesisInSubClause.jql b/plugins/tasks/tasks-tests/testData/jira/jql/completion/AfterLeftParenthesisInSubClause.jql
index 66abe15b5913..66abe15b5913 100644
--- a/plugins/tasks/tasks-tests/testData/jira/jql/completion/AfterParenthesisInSubClause.jql
+++ b/plugins/tasks/tasks-tests/testData/jira/jql/completion/AfterLeftParenthesisInSubClause.jql
diff --git a/plugins/tasks/tasks-tests/testData/jira/jql/completion/AfterSubClause.jql b/plugins/tasks/tasks-tests/testData/jira/jql/completion/AfterSubClause.jql
new file mode 100644
index 000000000000..d2ce0ae79af5
--- /dev/null
+++ b/plugins/tasks/tasks-tests/testData/jira/jql/completion/AfterSubClause.jql
@@ -0,0 +1 @@
+(reporter was in (bob, mark)) <caret> \ No newline at end of file
diff --git a/plugins/tasks/tasks-tests/testData/jira/jql/psi/Subclauses.txt b/plugins/tasks/tasks-tests/testData/jira/jql/psi/Subclauses.txt
index d004bc4a6360..3ec6387b3293 100644
--- a/plugins/tasks/tasks-tests/testData/jira/jql/psi/Subclauses.txt
+++ b/plugins/tasks/tasks-tests/testData/jira/jql/psi/Subclauses.txt
@@ -1,46 +1,50 @@
FILE(0,50)
JqlQuery((a = foo or (b > 12 and ((c < 40)))) and d ~ 'foo')(0,50)
JqlAndClause((a = foo or (b > 12 and ((c < 40)))) and d ~ 'foo')(0,50)
- PsiElement(JQL: LPAR)('(')(0,1)
- JqlOrClause(a = foo or (b > 12 and ((c < 40))))(1,35)
- JqlSimpleClause(a = foo)(1,8)
- JqlIdentifier(a)(1,2)
- PsiElement(JQL: STRING_LITERAL)('a')(1,2)
- PsiWhiteSpace(' ')(2,3)
- PsiElement(JQL: EQ)('=')(3,4)
- PsiWhiteSpace(' ')(4,5)
- JqlLiteral(foo)(5,8)
- PsiElement(JQL: STRING_LITERAL)('foo')(5,8)
- PsiWhiteSpace(' ')(8,9)
- PsiElement(JQL: OR_KEYWORD)('or')(9,11)
- PsiWhiteSpace(' ')(11,12)
- PsiElement(JQL: LPAR)('(')(12,13)
- JqlAndClause(b > 12 and ((c < 40)))(13,34)
- JqlSimpleClause(b > 12)(13,19)
- JqlIdentifier(b)(13,14)
- PsiElement(JQL: STRING_LITERAL)('b')(13,14)
- PsiWhiteSpace(' ')(14,15)
- PsiElement(JQL: GT)('>')(15,16)
- PsiWhiteSpace(' ')(16,17)
- JqlLiteral(12)(17,19)
- PsiElement(JQL: NUMBER_LITERAL)('12')(17,19)
- PsiWhiteSpace(' ')(19,20)
- PsiElement(JQL: AND_KEYWORD)('and')(20,23)
- PsiWhiteSpace(' ')(23,24)
- PsiElement(JQL: LPAR)('(')(24,25)
- PsiElement(JQL: LPAR)('(')(25,26)
- JqlSimpleClause(c < 40)(26,32)
- JqlIdentifier(c)(26,27)
- PsiElement(JQL: STRING_LITERAL)('c')(26,27)
- PsiWhiteSpace(' ')(27,28)
- PsiElement(JQL: LT)('<')(28,29)
- PsiWhiteSpace(' ')(29,30)
- JqlLiteral(40)(30,32)
- PsiElement(JQL: NUMBER_LITERAL)('40')(30,32)
- PsiElement(JQL: RPAR)(')')(32,33)
- PsiElement(JQL: RPAR)(')')(33,34)
- PsiElement(JQL: RPAR)(')')(34,35)
- PsiElement(JQL: RPAR)(')')(35,36)
+ JqlSubClause((a = foo or (b > 12 and ((c < 40)))))(0,36)
+ PsiElement(JQL: LPAR)('(')(0,1)
+ JqlOrClause(a = foo or (b > 12 and ((c < 40))))(1,35)
+ JqlSimpleClause(a = foo)(1,8)
+ JqlIdentifier(a)(1,2)
+ PsiElement(JQL: STRING_LITERAL)('a')(1,2)
+ PsiWhiteSpace(' ')(2,3)
+ PsiElement(JQL: EQ)('=')(3,4)
+ PsiWhiteSpace(' ')(4,5)
+ JqlLiteral(foo)(5,8)
+ PsiElement(JQL: STRING_LITERAL)('foo')(5,8)
+ PsiWhiteSpace(' ')(8,9)
+ PsiElement(JQL: OR_KEYWORD)('or')(9,11)
+ PsiWhiteSpace(' ')(11,12)
+ JqlSubClause((b > 12 and ((c < 40))))(12,35)
+ PsiElement(JQL: LPAR)('(')(12,13)
+ JqlAndClause(b > 12 and ((c < 40)))(13,34)
+ JqlSimpleClause(b > 12)(13,19)
+ JqlIdentifier(b)(13,14)
+ PsiElement(JQL: STRING_LITERAL)('b')(13,14)
+ PsiWhiteSpace(' ')(14,15)
+ PsiElement(JQL: GT)('>')(15,16)
+ PsiWhiteSpace(' ')(16,17)
+ JqlLiteral(12)(17,19)
+ PsiElement(JQL: NUMBER_LITERAL)('12')(17,19)
+ PsiWhiteSpace(' ')(19,20)
+ PsiElement(JQL: AND_KEYWORD)('and')(20,23)
+ PsiWhiteSpace(' ')(23,24)
+ JqlSubClause(((c < 40)))(24,34)
+ PsiElement(JQL: LPAR)('(')(24,25)
+ JqlSubClause((c < 40))(25,33)
+ PsiElement(JQL: LPAR)('(')(25,26)
+ JqlSimpleClause(c < 40)(26,32)
+ JqlIdentifier(c)(26,27)
+ PsiElement(JQL: STRING_LITERAL)('c')(26,27)
+ PsiWhiteSpace(' ')(27,28)
+ PsiElement(JQL: LT)('<')(28,29)
+ PsiWhiteSpace(' ')(29,30)
+ JqlLiteral(40)(30,32)
+ PsiElement(JQL: NUMBER_LITERAL)('40')(30,32)
+ PsiElement(JQL: RPAR)(')')(32,33)
+ PsiElement(JQL: RPAR)(')')(33,34)
+ PsiElement(JQL: RPAR)(')')(34,35)
+ PsiElement(JQL: RPAR)(')')(35,36)
PsiWhiteSpace(' ')(36,37)
PsiElement(JQL: AND_KEYWORD)('and')(37,40)
PsiWhiteSpace(' ')(40,41)
diff --git a/plugins/terminal/lib/jediterm-pty-0.08.jar b/plugins/terminal/lib/jediterm-pty-0.08.jar
index 0e3c22395e8e..f4bd38697dc2 100644
--- a/plugins/terminal/lib/jediterm-pty-0.08.jar
+++ b/plugins/terminal/lib/jediterm-pty-0.08.jar
Binary files differ
diff --git a/plugins/terminal/lib/pty4j-0.3.jar b/plugins/terminal/lib/pty4j-0.3.jar
index 67200e1203af..3c7f3db9811a 100644
--- a/plugins/terminal/lib/pty4j-0.3.jar
+++ b/plugins/terminal/lib/pty4j-0.3.jar
Binary files differ
diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/AbstractTerminalRunner.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/AbstractTerminalRunner.java
index c1ceb923a569..fcf06272b26c 100644
--- a/plugins/terminal/src/org/jetbrains/plugins/terminal/AbstractTerminalRunner.java
+++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/AbstractTerminalRunner.java
@@ -1,5 +1,6 @@
package org.jetbrains.plugins.terminal;
+import com.google.common.base.Predicate;
import com.intellij.execution.ExecutionManager;
import com.intellij.execution.Executor;
import com.intellij.execution.executors.DefaultRunExecutor;
@@ -8,30 +9,22 @@ import com.intellij.execution.ui.RunContentDescriptor;
import com.intellij.execution.ui.actions.CloseAction;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.keymap.KeymapManager;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
-import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowManager;
import com.intellij.util.ui.UIUtil;
-import com.jediterm.pty.PtyProcessTtyConnector;
import com.jediterm.terminal.TtyConnector;
-import com.jediterm.terminal.emulator.ColorPalette;
-import com.jediterm.terminal.ui.AbstractSystemSettingsProvider;
import com.jediterm.terminal.ui.TerminalSession;
import com.jediterm.terminal.ui.TerminalWidget;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
-import java.awt.event.ActionEvent;
-import java.util.ArrayList;
-import java.util.List;
import java.util.concurrent.ExecutionException;
/**
@@ -90,9 +83,14 @@ public abstract class AbstractTerminalRunner<T extends Process> {
protected abstract ProcessHandler createProcessHandler(T process);
public JBTabbedTerminalWidget createTerminalWidget() {
- JBTerminalSystemSettingsProvider provider = new JBTerminalSystemSettingsProvider();
- JBTabbedTerminalWidget terminalWidget = new JBTabbedTerminalWidget(provider);
- provider.setTerminalWidget(terminalWidget);
+ final JBTerminalSystemSettingsProvider provider = new JBTerminalSystemSettingsProvider();
+ JBTabbedTerminalWidget terminalWidget = new JBTabbedTerminalWidget(provider, new Predicate<TerminalWidget>() {
+ @Override
+ public boolean apply(TerminalWidget widget) {
+ openSession(widget);
+ return true;
+ }
+ });
openSession(terminalWidget);
return terminalWidget;
}
@@ -102,9 +100,14 @@ public abstract class AbstractTerminalRunner<T extends Process> {
final DefaultActionGroup toolbarActions = new DefaultActionGroup();
final ActionToolbar actionToolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, toolbarActions, false);
- JBTerminalSystemSettingsProvider provider = new JBTerminalSystemSettingsProvider();
- TerminalWidget widget = new JBTabbedTerminalWidget(provider);
- provider.setTerminalWidget(widget);
+ final JBTerminalSystemSettingsProvider provider = new JBTerminalSystemSettingsProvider();
+ TerminalWidget widget = new JBTabbedTerminalWidget(provider, new Predicate<TerminalWidget>() {
+ @Override
+ public boolean apply(TerminalWidget widget) {
+ openSession(widget);
+ return true;
+ }
+ });
openSession(widget, createTtyConnector(process));
@@ -160,57 +163,6 @@ public abstract class AbstractTerminalRunner<T extends Process> {
return myProject;
}
- private class JBTerminalSystemSettingsProvider extends AbstractSystemSettingsProvider {
- private TerminalWidget myTerminalWidget;
-
- public void setTerminalWidget(TerminalWidget terminalWidget) {
- myTerminalWidget = terminalWidget;
- }
-
- @Override
- public AbstractAction getNewSessionAction() {
- return new AbstractAction("New Session") {
- @Override
- public void actionPerformed(ActionEvent event) {
- openSession(myTerminalWidget);
- }
- };
- }
-
- @Override
- public KeyStroke[] getCopyKeyStrokes() {
- return getKeyStrokesByActionId("$Copy");
- }
-
- @Override
- public KeyStroke[] getPasteKeyStrokes() {
- return getKeyStrokesByActionId("$Paste");
- }
-
- @Override
- public ColorPalette getPalette() {
- return SystemInfo.isWindows ? ColorPalette.WINDOWS_PALETTE : ColorPalette.XTERM_PALETTE;
- }
-
- private KeyStroke[] getKeyStrokesByActionId(String actionId) {
- List<KeyStroke> keyStrokes = new ArrayList<KeyStroke>();
- Shortcut[] shortcuts = KeymapManager.getInstance().getActiveKeymap().getShortcuts(actionId);
- for (Shortcut sc : shortcuts) {
- if (sc instanceof KeyboardShortcut) {
- KeyStroke ks = ((KeyboardShortcut)sc).getFirstKeyStroke();
- keyStrokes.add(ks);
- }
- }
-
- return keyStrokes.toArray(new KeyStroke[keyStrokes.size()]);
- }
-
- @Override
- public boolean shouldCloseTabOnLogout(TtyConnector ttyConnector) {
- return ttyConnector instanceof PtyProcessTtyConnector; //close tab only on logout of local pty, not remote
- }
- }
-
public void openSession(TerminalWidget terminalWidget) {
// Create Server process
try {
diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTabbedTerminalWidget.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTabbedTerminalWidget.java
index 051a5a54359d..50a7e41ceb71 100644
--- a/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTabbedTerminalWidget.java
+++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTabbedTerminalWidget.java
@@ -1,12 +1,14 @@
package org.jetbrains.plugins.terminal;
+import com.google.common.base.Predicate;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.project.DumbAwareAction;
import com.jediterm.terminal.ui.JediTermWidget;
-import com.jediterm.terminal.ui.SystemSettingsProvider;
import com.jediterm.terminal.ui.TabbedTerminalWidget;
import com.jediterm.terminal.ui.TerminalAction;
+import com.jediterm.terminal.ui.TerminalWidget;
+import com.jediterm.terminal.ui.settings.SettingsProvider;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
@@ -17,8 +19,9 @@ import java.util.List;
* @author traff
*/
public class JBTabbedTerminalWidget extends TabbedTerminalWidget {
- public JBTabbedTerminalWidget(@NotNull SystemSettingsProvider settingsProvider) {
- super(settingsProvider);
+
+ public JBTabbedTerminalWidget(@NotNull SettingsProvider settingsProvider, @NotNull Predicate<TerminalWidget> createNewSessionAction) {
+ super(settingsProvider, createNewSessionAction);
convertActions(this, getActions());
}
@@ -28,12 +31,7 @@ public class JBTabbedTerminalWidget extends TabbedTerminalWidget {
AnAction a = new DumbAwareAction() {
@Override
public void actionPerformed(AnActionEvent e) {
- if (e.getInputEvent() instanceof KeyEvent) {
- action.perform((KeyEvent)e.getInputEvent());
- }
- else {
- action.perform(null);
- }
+ action.perform(e.getInputEvent() instanceof KeyEvent? (KeyEvent)e.getInputEvent() : null);
}
};
a.registerCustomShortcutSet(action.getKeyCode(), action.getModifiers(), component);
@@ -41,7 +39,7 @@ public class JBTabbedTerminalWidget extends TabbedTerminalWidget {
}
@Override
- protected JediTermWidget createInnerTerminalWidget() {
- return new JBTerminalWidget(getSystemSettingsProvider());
+ protected JediTermWidget createInnerTerminalWidget(SettingsProvider settingsProvider) {
+ return new JBTerminalWidget(settingsProvider);
}
}
diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalPanel.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalPanel.java
index e5b6e533e705..788a4f960e85 100644
--- a/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalPanel.java
+++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalPanel.java
@@ -22,17 +22,14 @@
package org.jetbrains.plugins.terminal;
-import com.intellij.openapi.editor.colors.EditorColors;
-import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.ide.CopyPasteManager;
+import com.intellij.util.JBHiDPIScaledImage;
import com.intellij.util.ui.GraphicsUtil;
import com.intellij.util.ui.UIUtil;
-import com.jediterm.terminal.TerminalColor;
-import com.jediterm.terminal.TextStyle;
import com.jediterm.terminal.display.BackBuffer;
import com.jediterm.terminal.display.StyleState;
-import com.jediterm.terminal.ui.SystemSettingsProvider;
import com.jediterm.terminal.ui.TerminalPanel;
+import com.jediterm.terminal.ui.settings.SettingsProvider;
import org.jetbrains.annotations.NotNull;
import java.awt.*;
@@ -41,69 +38,57 @@ import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.image.BufferedImage;
+import java.awt.image.ImageObserver;
import java.io.IOException;
-import java.util.List;
public class JBTerminalPanel extends TerminalPanel {
- private final EditorColorsScheme myColorScheme;
-
- public JBTerminalPanel(@NotNull SystemSettingsProvider settingsProvider,
+ public JBTerminalPanel(@NotNull SettingsProvider settingsProvider,
@NotNull BackBuffer backBuffer,
- @NotNull StyleState styleState,
- @NotNull EditorColorsScheme scheme) {
+ @NotNull StyleState styleState) {
super(settingsProvider, backBuffer, styleState);
- myColorScheme = scheme;
-
-
- styleState.setDefaultStyle(new TextStyle(TerminalColor.awt(myColorScheme.getDefaultForeground()), TerminalColor.awt(
- myColorScheme.getDefaultBackground())));
-
- setSelectionColor(new TextStyle(TerminalColor.awt(myColorScheme.getColor(EditorColors.SELECTION_FOREGROUND_COLOR)),
- TerminalColor.awt(myColorScheme.getColor(EditorColors.SELECTION_BACKGROUND_COLOR))));
- setLineSpace(myColorScheme.getConsoleLineSpacing());
-
JBTabbedTerminalWidget.convertActions(this, getActions());
}
- protected Font createFont() {
-
- Font normalFont = Font.decode(getFontName());
-
- if (normalFont == null) {
- normalFont = super.createFont();
- }
-
- normalFont = normalFont.deriveFont((float)myColorScheme.getConsoleFontSize());
-
- return normalFont;
- }
-
protected void setupAntialiasing(Graphics graphics, boolean antialiasing) {
GraphicsUtil.setupAntialiasing(graphics, antialiasing, false);
}
@Override
- public Color getBackground() {
- if (myColorScheme != null) {
- return myColorScheme.getDefaultBackground();
- }
- return super.getBackground();
+ protected void setCopyContents(StringSelection selection) {
+ CopyPasteManager.getInstance().setContents(selection);
}
@Override
- public Color getForeground() {
- if (myColorScheme != null) {
- return myColorScheme.getDefaultForeground();
- }
- return super.getBackground();
+ protected void drawImage(Graphics2D gfx, BufferedImage image, int x, int y, ImageObserver observer) {
+ UIUtil.drawImage(gfx, image, x, y, observer);
}
@Override
- protected void setCopyContents(StringSelection selection) {
- CopyPasteManager.getInstance().setContents(selection);
+ protected void drawImage(Graphics2D g, BufferedImage image, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2) {
+ drawImage(g, image, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, null);
+ }
+
+ public static void drawImage(Graphics g, Image image, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, ImageObserver observer) {
+ if (image instanceof JBHiDPIScaledImage) {
+ final Graphics2D newG = (Graphics2D)g.create(0, 0, image.getWidth(observer), image.getHeight(observer));
+ newG.scale(0.5, 0.5);
+ Image img = ((JBHiDPIScaledImage)image).getDelegate();
+ if (img == null) {
+ img = image;
+ }
+ newG.drawImage(img, 2*dx1, 2*dy1, 2*dx2, 2*dy2, sx1, sy1, sx2, sy2, observer);
+ newG.scale(1, 1);
+ newG.dispose();
+ } else {
+ g.drawImage(image, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, observer);
+ }
}
+ @Override
+ protected boolean isRetina() {
+ return UIUtil.isRetina();
+ }
@Override
protected String getClipboardContent() throws IOException, UnsupportedFlavorException {
@@ -118,28 +103,5 @@ public class JBTerminalPanel extends TerminalPanel {
protected BufferedImage createBufferedImage(int width, int height) {
return UIUtil.createImage(width, height, BufferedImage.TYPE_INT_ARGB);
}
-
- @Override
- protected void drawImage(Graphics2D g, BufferedImage image) {
- UIUtil.drawImage(g, image, null, 0, 0);
- }
-
- public String getFontName() {
- List<String> fonts = myColorScheme.getConsoleFontPreferences().getEffectiveFontFamilies();
-
- for (String font : fonts) {
- if (isApplicable(font)) {
- return font;
- }
- }
- return super.getFontName();
- }
-
- private static boolean isApplicable(String font) {
- if ("Source Code Pro".equals(font)) {
- return false;
- }
- return true;
- }
}
diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalSystemSettingsProvider.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalSystemSettingsProvider.java
new file mode 100644
index 000000000000..3b983e21410f
--- /dev/null
+++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalSystemSettingsProvider.java
@@ -0,0 +1,367 @@
+package org.jetbrains.plugins.terminal;
+
+import com.intellij.application.options.OptionsConstants;
+import com.intellij.openapi.actionSystem.KeyboardShortcut;
+import com.intellij.openapi.actionSystem.Shortcut;
+import com.intellij.openapi.editor.colors.*;
+import com.intellij.openapi.editor.markup.TextAttributes;
+import com.intellij.openapi.keymap.KeymapManager;
+import com.intellij.openapi.options.FontSize;
+import com.intellij.openapi.util.InvalidDataException;
+import com.intellij.openapi.util.SystemInfo;
+import com.intellij.openapi.util.WriteExternalException;
+import com.intellij.util.containers.HashMap;
+import com.jediterm.pty.PtyProcessTtyConnector;
+import com.jediterm.terminal.TerminalColor;
+import com.jediterm.terminal.TextStyle;
+import com.jediterm.terminal.TtyConnector;
+import com.jediterm.terminal.emulator.ColorPalette;
+import com.jediterm.terminal.ui.settings.DefaultSettingsProvider;
+import org.jdom.Element;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.awt.*;
+import java.util.ArrayList;
+import java.util.EnumMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author traff
+ */
+class JBTerminalSystemSettingsProvider extends DefaultSettingsProvider {
+
+ private final EditorColorsScheme myColorScheme;
+
+ JBTerminalSystemSettingsProvider() {
+ myColorScheme = getColorScheme();
+ }
+
+ @Override
+ public KeyStroke[] getCopyKeyStrokes() {
+ return getKeyStrokesByActionId("$Copy");
+ }
+
+ @Override
+ public KeyStroke[] getPasteKeyStrokes() {
+ return getKeyStrokesByActionId("$Paste");
+ }
+
+ @Override
+ public ColorPalette getTerminalColorPalette() {
+ return SystemInfo.isWindows ? ColorPalette.WINDOWS_PALETTE : ColorPalette.XTERM_PALETTE;
+ }
+
+ private KeyStroke[] getKeyStrokesByActionId(String actionId) {
+ List<KeyStroke> keyStrokes = new ArrayList<KeyStroke>();
+ Shortcut[] shortcuts = KeymapManager.getInstance().getActiveKeymap().getShortcuts(actionId);
+ for (Shortcut sc : shortcuts) {
+ if (sc instanceof KeyboardShortcut) {
+ KeyStroke ks = ((KeyboardShortcut)sc).getFirstKeyStroke();
+ keyStrokes.add(ks);
+ }
+ }
+
+ return keyStrokes.toArray(new KeyStroke[keyStrokes.size()]);
+ }
+
+ @Override
+ public boolean shouldCloseTabOnLogout(TtyConnector ttyConnector) {
+ return ttyConnector instanceof PtyProcessTtyConnector; //close tab only on logout of local pty, not remote
+ }
+
+ @Override
+ public float getLineSpace() {
+ return myColorScheme.getConsoleLineSpacing();
+ }
+
+ @Override
+ public boolean useInverseSelectionColor() {
+ return false;
+ }
+
+ @Override
+ public TextStyle getSelectionColor() {
+ return new TextStyle(TerminalColor.awt(myColorScheme.getColor(EditorColors.SELECTION_FOREGROUND_COLOR)),
+ TerminalColor.awt(myColorScheme.getColor(EditorColors.SELECTION_BACKGROUND_COLOR)));
+ }
+
+ @Override
+ public TextStyle getDefaultStyle() {
+ return new TextStyle(TerminalColor.awt(myColorScheme.getDefaultForeground()), TerminalColor.awt(
+ myColorScheme.getDefaultBackground()));
+ }
+
+ @Override
+ public Font getTerminalFont() {
+ Font normalFont = Font.decode(getFontName());
+
+ if (normalFont == null) {
+ normalFont = super.getTerminalFont();
+ }
+
+ normalFont = normalFont.deriveFont(getTerminalFontSize());
+
+ return normalFont;
+ }
+
+ public String getFontName() {
+ List<String> fonts = myColorScheme.getConsoleFontPreferences().getEffectiveFontFamilies();
+
+ for (String font : fonts) {
+ if (isApplicable(font)) {
+ return font;
+ }
+ }
+ return "Monospaced-14";
+ }
+
+ private static boolean isApplicable(String font) {
+ if ("Source Code Pro".equals(font)) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public float getTerminalFontSize() {
+ return (float)myColorScheme.getConsoleFontSize();
+ }
+
+ public EditorColorsScheme getColorScheme() {
+ return createBoundColorSchemeDelegate(null);
+ }
+
+ @NotNull
+ public EditorColorsScheme createBoundColorSchemeDelegate(@Nullable final EditorColorsScheme customGlobalScheme) {
+ return new MyColorSchemeDelegate(customGlobalScheme);
+ }
+
+ private static class MyColorSchemeDelegate implements EditorColorsScheme {
+
+ private final FontPreferences myFontPreferences = new FontPreferences();
+ private final HashMap<TextAttributesKey, TextAttributes> myOwnAttributes = new HashMap<TextAttributesKey, TextAttributes>();
+ private final HashMap<ColorKey, Color> myOwnColors = new HashMap<ColorKey, Color>();
+ private final EditorColorsScheme myCustomGlobalScheme;
+ private Map<EditorFontType, Font> myFontsMap = null;
+ private int myMaxFontSize = OptionsConstants.MAX_EDITOR_FONT_SIZE;
+ private int myFontSize = -1;
+ private String myFaceName = null;
+ private EditorColorsScheme myGlobalScheme;
+
+ private MyColorSchemeDelegate(@Nullable final EditorColorsScheme globalScheme) {
+ myCustomGlobalScheme = globalScheme;
+ updateGlobalScheme();
+ }
+
+ private EditorColorsScheme getGlobal() {
+ return myGlobalScheme;
+ }
+
+ @Override
+ public String getName() {
+ return getGlobal().getName();
+ }
+
+
+ protected void initFonts() {
+ String editorFontName = getEditorFontName();
+ int editorFontSize = getEditorFontSize();
+ myFontPreferences.clear();
+ myFontPreferences.register(editorFontName, editorFontSize);
+
+ myFontsMap = new EnumMap<EditorFontType, Font>(EditorFontType.class);
+
+ Font plainFont = new Font(editorFontName, Font.PLAIN, editorFontSize);
+ Font boldFont = new Font(editorFontName, Font.BOLD, editorFontSize);
+ Font italicFont = new Font(editorFontName, Font.ITALIC, editorFontSize);
+ Font boldItalicFont = new Font(editorFontName, Font.BOLD | Font.ITALIC, editorFontSize);
+
+ myFontsMap.put(EditorFontType.PLAIN, plainFont);
+ myFontsMap.put(EditorFontType.BOLD, boldFont);
+ myFontsMap.put(EditorFontType.ITALIC, italicFont);
+ myFontsMap.put(EditorFontType.BOLD_ITALIC, boldItalicFont);
+ }
+
+ @Override
+ public void setName(String name) {
+ getGlobal().setName(name);
+ }
+
+ @Override
+ public TextAttributes getAttributes(TextAttributesKey key) {
+ if (myOwnAttributes.containsKey(key)) return myOwnAttributes.get(key);
+ return getGlobal().getAttributes(key);
+ }
+
+ @Override
+ public void setAttributes(TextAttributesKey key, TextAttributes attributes) {
+ myOwnAttributes.put(key, attributes);
+ }
+
+ @NotNull
+ @Override
+ public Color getDefaultBackground() {
+ return getGlobal().getDefaultBackground();
+ }
+
+ @NotNull
+ @Override
+ public Color getDefaultForeground() {
+ return getGlobal().getDefaultForeground();
+ }
+
+ @Override
+ public Color getColor(ColorKey key) {
+ if (myOwnColors.containsKey(key)) return myOwnColors.get(key);
+ return getGlobal().getColor(key);
+ }
+
+ @Override
+ public void setColor(ColorKey key, Color color) {
+ myOwnColors.put(key, color);
+ }
+
+ @NotNull
+ @Override
+ public FontPreferences getFontPreferences() {
+ return myFontPreferences;
+ }
+
+ @Override
+ public void setFontPreferences(@NotNull FontPreferences preferences) {
+ preferences.copyTo(myFontPreferences);
+ initFonts();
+ }
+
+ @Override
+ public int getEditorFontSize() {
+ if (myFontSize == -1) {
+ return getGlobal().getEditorFontSize();
+ }
+ return myFontSize;
+ }
+
+ @Override
+ public void setEditorFontSize(int fontSize) {
+ if (fontSize < 8) fontSize = 8;
+ if (fontSize > myMaxFontSize) fontSize = myMaxFontSize;
+ myFontSize = fontSize;
+ initFonts();
+ }
+
+ @Override
+ public FontSize getQuickDocFontSize() {
+ return myGlobalScheme.getQuickDocFontSize();
+ }
+
+ @Override
+ public void setQuickDocFontSize(@NotNull FontSize fontSize) {
+ myGlobalScheme.setQuickDocFontSize(fontSize);
+ }
+
+ @Override
+ public String getEditorFontName() {
+ if (myFaceName == null) {
+ return getGlobal().getEditorFontName();
+ }
+ return myFaceName;
+ }
+
+ @Override
+ public void setEditorFontName(String fontName) {
+ myFaceName = fontName;
+ initFonts();
+ }
+
+ @Override
+ public Font getFont(EditorFontType key) {
+ if (myFontsMap != null) {
+ Font font = myFontsMap.get(key);
+ if (font != null) return font;
+ }
+ return getGlobal().getFont(key);
+ }
+
+ @Override
+ public void setFont(EditorFontType key, Font font) {
+ if (myFontsMap == null) {
+ initFonts();
+ }
+ myFontsMap.put(key, font);
+ }
+
+ @Override
+ public float getLineSpacing() {
+ return getGlobal().getLineSpacing();
+ }
+
+ @Override
+ public void setLineSpacing(float lineSpacing) {
+ getGlobal().setLineSpacing(lineSpacing);
+ }
+
+ @Override
+ @Nullable
+ public Object clone() {
+ return null;
+ }
+
+ @Override
+ public void readExternal(Element element) throws InvalidDataException {
+ }
+
+ @Override
+ public void writeExternal(Element element) throws WriteExternalException {
+ }
+
+ public void updateGlobalScheme() {
+ myGlobalScheme = myCustomGlobalScheme == null ? EditorColorsManager.getInstance().getGlobalScheme() : myCustomGlobalScheme;
+ int globalFontSize = getGlobal().getEditorFontSize();
+ myMaxFontSize = Math.max(OptionsConstants.MAX_EDITOR_FONT_SIZE, globalFontSize);
+ }
+
+ @NotNull
+ @Override
+ public FontPreferences getConsoleFontPreferences() {
+ return getGlobal().getConsoleFontPreferences();
+ }
+
+ @Override
+ public void setConsoleFontPreferences(@NotNull FontPreferences preferences) {
+ getGlobal().setConsoleFontPreferences(preferences);
+ }
+
+ @Override
+ public String getConsoleFontName() {
+ return getGlobal().getConsoleFontName();
+ }
+
+ @Override
+ public void setConsoleFontName(String fontName) {
+ getGlobal().setConsoleFontName(fontName);
+ }
+
+ @Override
+ public int getConsoleFontSize() {
+ return getGlobal().getConsoleFontSize();
+ }
+
+ @Override
+ public void setConsoleFontSize(int fontSize) {
+ getGlobal().setConsoleFontSize(fontSize);
+ }
+
+ @Override
+ public float getConsoleLineSpacing() {
+ return getGlobal().getConsoleLineSpacing();
+ }
+
+ @Override
+ public void setConsoleLineSpacing(float lineSpacing) {
+ getGlobal().setConsoleLineSpacing(lineSpacing);
+ }
+ }
+}
diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalWidget.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalWidget.java
index 6f2e49da3f27..99a21e868034 100644
--- a/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalWidget.java
+++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/JBTerminalWidget.java
@@ -14,7 +14,7 @@ import com.jediterm.terminal.display.BackBuffer;
import com.jediterm.terminal.display.JediTerminal;
import com.jediterm.terminal.display.StyleState;
import com.jediterm.terminal.ui.JediTermWidget;
-import com.jediterm.terminal.ui.SystemSettingsProvider;
+import com.jediterm.terminal.ui.settings.SettingsProvider;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -26,17 +26,17 @@ import java.util.Map;
public class JBTerminalWidget extends JediTermWidget {
- public JBTerminalWidget(SystemSettingsProvider settingsProvider) {
+ public JBTerminalWidget(SettingsProvider settingsProvider) {
super(settingsProvider);
JBTabbedTerminalWidget.convertActions(this, getActions());
}
@Override
- protected JBTerminalPanel createTerminalPanel(@NotNull SystemSettingsProvider settingsProvider,
+ protected JBTerminalPanel createTerminalPanel(@NotNull SettingsProvider settingsProvider,
@NotNull StyleState styleState,
@NotNull BackBuffer backBuffer) {
- return new JBTerminalPanel(settingsProvider, backBuffer, styleState, getColorScheme());
+ return new JBTerminalPanel(settingsProvider, backBuffer, styleState);
}
@Override
@@ -44,243 +44,10 @@ public class JBTerminalWidget extends JediTermWidget {
return new JBTerminalStarter(terminal, connector);
}
- public EditorColorsScheme getColorScheme() {
- return createBoundColorSchemeDelegate(null);
- }
-
@Override
protected JScrollBar createScrollBar() {
return new JBScrollBar();
}
- @NotNull
- public EditorColorsScheme createBoundColorSchemeDelegate(@Nullable final EditorColorsScheme customGlobalScheme) {
- return new MyColorSchemeDelegate(customGlobalScheme);
- }
-
- private static class MyColorSchemeDelegate implements EditorColorsScheme {
-
- private final FontPreferences myFontPreferences = new FontPreferences();
- private final HashMap<TextAttributesKey, TextAttributes> myOwnAttributes = new HashMap<TextAttributesKey, TextAttributes>();
- private final HashMap<ColorKey, Color> myOwnColors = new HashMap<ColorKey, Color>();
- private final EditorColorsScheme myCustomGlobalScheme;
- private Map<EditorFontType, Font> myFontsMap = null;
- private int myMaxFontSize = OptionsConstants.MAX_EDITOR_FONT_SIZE;
- private int myFontSize = -1;
- private String myFaceName = null;
- private EditorColorsScheme myGlobalScheme;
-
- private MyColorSchemeDelegate(@Nullable final EditorColorsScheme globalScheme) {
- myCustomGlobalScheme = globalScheme;
- updateGlobalScheme();
- }
-
- private EditorColorsScheme getGlobal() {
- return myGlobalScheme;
- }
-
- @Override
- public String getName() {
- return getGlobal().getName();
- }
-
-
- protected void initFonts() {
- String editorFontName = getEditorFontName();
- int editorFontSize = getEditorFontSize();
- myFontPreferences.clear();
- myFontPreferences.register(editorFontName, editorFontSize);
-
- myFontsMap = new EnumMap<EditorFontType, Font>(EditorFontType.class);
-
- Font plainFont = new Font(editorFontName, Font.PLAIN, editorFontSize);
- Font boldFont = new Font(editorFontName, Font.BOLD, editorFontSize);
- Font italicFont = new Font(editorFontName, Font.ITALIC, editorFontSize);
- Font boldItalicFont = new Font(editorFontName, Font.BOLD | Font.ITALIC, editorFontSize);
-
- myFontsMap.put(EditorFontType.PLAIN, plainFont);
- myFontsMap.put(EditorFontType.BOLD, boldFont);
- myFontsMap.put(EditorFontType.ITALIC, italicFont);
- myFontsMap.put(EditorFontType.BOLD_ITALIC, boldItalicFont);
- }
-
- @Override
- public void setName(String name) {
- getGlobal().setName(name);
- }
-
- @Override
- public TextAttributes getAttributes(TextAttributesKey key) {
- if (myOwnAttributes.containsKey(key)) return myOwnAttributes.get(key);
- return getGlobal().getAttributes(key);
- }
-
- @Override
- public void setAttributes(TextAttributesKey key, TextAttributes attributes) {
- myOwnAttributes.put(key, attributes);
- }
-
- @NotNull
- @Override
- public Color getDefaultBackground() {
- return getGlobal().getDefaultBackground();
- }
-
- @NotNull
- @Override
- public Color getDefaultForeground() {
- return getGlobal().getDefaultForeground();
- }
-
- @Override
- public Color getColor(ColorKey key) {
- if (myOwnColors.containsKey(key)) return myOwnColors.get(key);
- return getGlobal().getColor(key);
- }
-
- @Override
- public void setColor(ColorKey key, Color color) {
- myOwnColors.put(key, color);
- }
-
- @NotNull
- @Override
- public FontPreferences getFontPreferences() {
- return myFontPreferences;
- }
-
- @Override
- public void setFontPreferences(@NotNull FontPreferences preferences) {
- preferences.copyTo(myFontPreferences);
- initFonts();
- }
- @Override
- public int getEditorFontSize() {
- if (myFontSize == -1) {
- return getGlobal().getEditorFontSize();
- }
- return myFontSize;
- }
-
- @Override
- public void setEditorFontSize(int fontSize) {
- if (fontSize < 8) fontSize = 8;
- if (fontSize > myMaxFontSize) fontSize = myMaxFontSize;
- myFontSize = fontSize;
- initFonts();
- }
-
- @Override
- public FontSize getQuickDocFontSize() {
- return myGlobalScheme.getQuickDocFontSize();
- }
-
- @Override
- public void setQuickDocFontSize(@NotNull FontSize fontSize) {
- myGlobalScheme.setQuickDocFontSize(fontSize);
- }
-
- @Override
- public String getEditorFontName() {
- if (myFaceName == null) {
- return getGlobal().getEditorFontName();
- }
- return myFaceName;
- }
-
- @Override
- public void setEditorFontName(String fontName) {
- myFaceName = fontName;
- initFonts();
- }
-
- @Override
- public Font getFont(EditorFontType key) {
- if (myFontsMap != null) {
- Font font = myFontsMap.get(key);
- if (font != null) return font;
- }
- return getGlobal().getFont(key);
- }
-
- @Override
- public void setFont(EditorFontType key, Font font) {
- if (myFontsMap == null) {
- initFonts();
- }
- myFontsMap.put(key, font);
- }
-
- @Override
- public float getLineSpacing() {
- return getGlobal().getLineSpacing();
- }
-
- @Override
- public void setLineSpacing(float lineSpacing) {
- getGlobal().setLineSpacing(lineSpacing);
- }
-
- @Override
- @Nullable
- public Object clone() {
- return null;
- }
-
- @Override
- public void readExternal(Element element) throws InvalidDataException {
- }
-
- @Override
- public void writeExternal(Element element) throws WriteExternalException {
- }
-
- public void updateGlobalScheme() {
- myGlobalScheme = myCustomGlobalScheme == null ? EditorColorsManager.getInstance().getGlobalScheme() : myCustomGlobalScheme;
- int globalFontSize = getGlobal().getEditorFontSize();
- myMaxFontSize = Math.max(OptionsConstants.MAX_EDITOR_FONT_SIZE, globalFontSize);
- }
-
- @NotNull
- @Override
- public FontPreferences getConsoleFontPreferences() {
- return getGlobal().getConsoleFontPreferences();
- }
-
- @Override
- public void setConsoleFontPreferences(@NotNull FontPreferences preferences) {
- getGlobal().setConsoleFontPreferences(preferences);
- }
-
- @Override
- public String getConsoleFontName() {
- return getGlobal().getConsoleFontName();
- }
-
- @Override
- public void setConsoleFontName(String fontName) {
- getGlobal().setConsoleFontName(fontName);
- }
-
- @Override
- public int getConsoleFontSize() {
- return getGlobal().getConsoleFontSize();
- }
-
- @Override
- public void setConsoleFontSize(int fontSize) {
- getGlobal().setConsoleFontSize(fontSize);
- }
-
- @Override
- public float getConsoleLineSpacing() {
- return getGlobal().getConsoleLineSpacing();
- }
-
- @Override
- public void setConsoleLineSpacing(float lineSpacing) {
- getGlobal().setConsoleLineSpacing(lineSpacing);
- }
- }
}
diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/OpenLocalTerminalAction.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/OpenLocalTerminalAction.java
index 203de242cb6e..8cb28eaa74f3 100644
--- a/plugins/terminal/src/org/jetbrains/plugins/terminal/OpenLocalTerminalAction.java
+++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/OpenLocalTerminalAction.java
@@ -21,9 +21,8 @@ public class OpenLocalTerminalAction extends AnAction implements DumbAware {
@Override
public void update(final AnActionEvent e) {
- boolean enabled = SystemInfo.isUnix;
- e.getPresentation().setVisible(enabled);
- e.getPresentation().setEnabled(enabled);
+ e.getPresentation().setVisible(true);
+ e.getPresentation().setEnabled(true);
}
public void actionPerformed(final AnActionEvent e) {
diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalToolWindowFactory.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalToolWindowFactory.java
index 7d57aacd75bb..271c8dcb42fc 100644
--- a/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalToolWindowFactory.java
+++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalToolWindowFactory.java
@@ -9,6 +9,8 @@ import com.intellij.openapi.wm.ToolWindowFactory;
* @author traff
*/
public class TerminalToolWindowFactory implements ToolWindowFactory, DumbAware {
+ public static final String TOOL_WINDOW_ID = "Terminal";
+
@Override
public void createToolWindowContent(Project project, ToolWindow toolWindow) {
TerminalView terminalView = TerminalView.getInstance();
diff --git a/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalView.java b/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalView.java
index bd7cfd23675e..188be8f15d48 100644
--- a/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalView.java
+++ b/plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalView.java
@@ -9,15 +9,20 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.SimpleToolWindowPanel;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowManager;
+import com.intellij.openapi.wm.ex.ToolWindowManagerEx;
+import com.intellij.openapi.wm.ex.ToolWindowManagerListener;
import com.intellij.ui.content.Content;
import com.intellij.ui.content.ContentFactory;
+import com.intellij.util.ui.UIUtil;
import com.jediterm.terminal.ui.JediTermWidget;
import com.jediterm.terminal.ui.TabbedTerminalWidget;
import com.jediterm.terminal.ui.TerminalWidget;
import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
+import java.awt.*;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
@@ -29,25 +34,47 @@ public class TerminalView {
private JBTabbedTerminalWidget myTerminalWidget;
private Project myProject;
- public void initTerminal(Project project, final ToolWindow toolWindow) {
+ public void initTerminal(final Project project, final ToolWindow toolWindow) {
myProject = project;
LocalTerminalDirectRunner terminalRunner = OpenLocalTerminalAction.createTerminalRunner(project);
-
+
toolWindow.setToHideOnEmptyContent(true);
-
+
if (terminalRunner != null) {
myTerminalWidget = terminalRunner.createTerminalWidget();
myTerminalWidget.addTabListener(new TabbedTerminalWidget.TabListener() {
@Override
public void tabClosed(JediTermWidget terminal) {
- hideIfNoActiveSessions(toolWindow, myTerminalWidget);
+ UIUtil.invokeLaterIfNeeded(new Runnable() {
+ @Override
+ public void run() {
+ hideIfNoActiveSessions(toolWindow, myTerminalWidget);
+ }
+ });
}
});
}
Content content = createToolWindowContentPanel(terminalRunner, myTerminalWidget, toolWindow);
-
+
toolWindow.getContentManager().addContent(content);
+
+ ((ToolWindowManagerEx)ToolWindowManager.getInstance(myProject)).addToolWindowManagerListener(new ToolWindowManagerListener() {
+ @Override
+ public void toolWindowRegistered(@NotNull String id) {
+ }
+
+ @Override
+ public void stateChanged() {
+ ToolWindow window = ToolWindowManager.getInstance(project).getToolWindow(TerminalToolWindowFactory.TOOL_WINDOW_ID);
+ if (window != null) {
+ boolean visible = window.isVisible();
+ if (visible && toolWindow.getContentManager().getContentCount() == 0) {
+ initTerminal(project, window);
+ }
+ }
+ }
+ });
}
private Content createToolWindowContentPanel(@Nullable LocalTerminalDirectRunner terminalRunner,
@@ -59,6 +86,7 @@ public class TerminalView {
return PlatformDataKeys.HELP_ID.is(dataId) ? EventLog.HELP_ID : super.getData(dataId);
}
};
+
if (terminalWidget != null) {
panel.setContent(terminalWidget.getComponent());
@@ -73,9 +101,8 @@ public class TerminalView {
final Content content = ContentFactory.SERVICE.getInstance().createContent(panel, "", false);
content.setCloseable(true);
- if (getComponentToFocus() != null) {
- content.setPreferredFocusableComponent(getComponentToFocus());
- }
+ content.setPreferredFocusableComponent(terminalWidget.getComponent());
+
return content;
}
@@ -129,7 +156,7 @@ public class TerminalView {
}
private ActionToolbar createToolbar(@Nullable final LocalTerminalDirectRunner terminalRunner,
- final JBTabbedTerminalWidget terminal, ToolWindow toolWindow) {
+ final JBTabbedTerminalWidget terminal, ToolWindow toolWindow) {
DefaultActionGroup group = new DefaultActionGroup();
if (terminalRunner != null) {
@@ -151,16 +178,9 @@ public class TerminalView {
}, true);
}
- private void hideIfNoActiveSessions(final ToolWindow toolWindow, JBTabbedTerminalWidget terminal) {
+ private static void hideIfNoActiveSessions(final ToolWindow toolWindow, JBTabbedTerminalWidget terminal) {
if (terminal.isNoActiveSessions()) {
toolWindow.getContentManager().removeAllContents(true);
-
- toolWindow.getActivation().doWhenDone(new Runnable() {
- @Override
- public void run() {
- initTerminal(myProject, toolWindow);
- }
- });
}
}
diff --git a/plugins/terminal/terminal.iml b/plugins/terminal/terminal.iml
index 86f90598c51f..59daabb61b81 100644
--- a/plugins/terminal/terminal.iml
+++ b/plugins/terminal/terminal.iml
@@ -48,6 +48,7 @@
<SOURCES />
</library>
</orderEntry>
+ <orderEntry type="library" name="Guava" level="project" />
</component>
</module>
diff --git a/plugins/testng/src/com/theoryinpractice/testng/model/TestData.java b/plugins/testng/src/com/theoryinpractice/testng/model/TestData.java
index f88daee3e06b..55a6a3db11b5 100644
--- a/plugins/testng/src/com/theoryinpractice/testng/model/TestData.java
+++ b/plugins/testng/src/com/theoryinpractice/testng/model/TestData.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.
@@ -177,7 +177,7 @@ public class TestData implements Cloneable
public String getGeneratedName(JavaRunConfigurationModule runconfigurationmodule) {
if (TestType.PACKAGE.getType().equals(TEST_OBJECT)) if (getPackageName().length() == 0) return "<default>";
else return getPackageName();
- String name = JavaExecutionUtil.getPresentableClassName(getMainClassName(), runconfigurationmodule);
+ String name = JavaExecutionUtil.getPresentableClassName(getMainClassName());
if (TestType.METHOD.getType().equals(TEST_OBJECT)) {
return name + '.' + getMethodName();
}