From 25f2995cb7e1bfcbf36e5c5ce14f4f755b4d76bb Mon Sep 17 00:00:00 2001 From: Sergey Evdokimov Date: Tue, 7 Feb 2012 12:52:46 +0400 Subject: [PATCH 01/12] Since 11.1 IDEA has idea66.vmoptions file. --- .../platform-impl/src/com/intellij/diagnostic/VMOptions.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/diagnostic/VMOptions.java b/platform/platform-impl/src/com/intellij/diagnostic/VMOptions.java index 21ffe2f297a1..03774ed51f10 100644 --- a/platform/platform-impl/src/com/intellij/diagnostic/VMOptions.java +++ b/platform/platform-impl/src/com/intellij/diagnostic/VMOptions.java @@ -226,7 +226,7 @@ public class VMOptions { } final String productName = ApplicationNamesInfo.getInstance().getProductName().toLowerCase(); - final String platformSuffix = (SystemInfo.is64Bit && !SystemInfo.isLinux) ? "64" : ""; + final String platformSuffix = SystemInfo.is64Bit ? "64" : ""; final String osSuffix = SystemInfo.isWindows ? ".exe" : ""; return PathManager.getBinPath() + File.separatorChar + productName + platformSuffix + osSuffix + ".vmoptions"; } From 8766496f26a0f6a1354e28ebbbcf1298e57b2246 Mon Sep 17 00:00:00 2001 From: irengrig Date: Mon, 6 Feb 2012 12:09:21 +0400 Subject: [PATCH 02/12] SVN 1.7: resolve conflict (as merged) - to work --- .../org/jetbrains/idea/svn17/actions/MarkResolvedAction.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn17/actions/MarkResolvedAction.java b/plugins/svn4idea/src/org/jetbrains/idea/svn17/actions/MarkResolvedAction.java index a8fb65a03d36..14c7e6ccd36a 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn17/actions/MarkResolvedAction.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn17/actions/MarkResolvedAction.java @@ -33,6 +33,7 @@ import org.jetbrains.idea.svn17.SvnBundle; import org.jetbrains.idea.svn17.SvnStatusUtil; import org.jetbrains.idea.svn17.SvnVcs17; import org.jetbrains.idea.svn17.dialogs.SelectFilesDialog; +import org.tmatesoft.svn.core.SVNDepth; import org.tmatesoft.svn.core.SVNException; import org.tmatesoft.svn.core.wc.*; @@ -90,7 +91,7 @@ public class MarkResolvedAction extends BasicAction { SVNWCClient wcClient = vcs.createWCClient(); for (String path : pathsArray) { File ioFile = new File(path); - wcClient.doResolve(ioFile, false); + wcClient.doResolve(ioFile, SVNDepth.EMPTY, SVNConflictChoice.MERGED); } } catch (SVNException e) { From 2d743657336c20294d0c16a4f0fc808a01c44031 Mon Sep 17 00:00:00 2001 From: irengrig Date: Mon, 6 Feb 2012 15:25:47 +0400 Subject: [PATCH 03/12] SVN: assertion in case there was no authentication and user tries to select revision to update to --- .../SvnRevisionsNavigationMediator.java | 47 +++++++++++++------ 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn17/history/SvnRevisionsNavigationMediator.java b/plugins/svn4idea/src/org/jetbrains/idea/svn17/history/SvnRevisionsNavigationMediator.java index 677ef50f7cc8..8f3d687be18a 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn17/history/SvnRevisionsNavigationMediator.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn17/history/SvnRevisionsNavigationMediator.java @@ -15,7 +15,10 @@ */ package org.jetbrains.idea.svn17.history; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.progress.ProcessCanceledException; +import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Ref; import com.intellij.openapi.vcs.RepositoryLocation; @@ -53,21 +56,35 @@ public class SvnRevisionsNavigationMediator implements CommittedChangesNavigatio myChunks = new LinkedList>(); - SVNRepository repository = null; - final SVNURL repositoryRoot; - final long youngRevision; - try { - repository = vcs.createRepository(location.getURL()); - youngRevision = repository.getLatestRevision(); - repositoryRoot = repository.getRepositoryRoot(false); - } - catch (SVNException e) { - throw new VcsException(e); - } - finally { - if (repository != null) { - repository.closeSession(); + final SVNURL[] repositoryRoot = new SVNURL[1]; + final long[] youngRevision = new long[1]; + final SVNException[] exception = new SVNException[1]; + + final boolean succeeded = ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() { + @Override + public void run() { + SVNRepository repository = null; + try { + repository = vcs.createRepository(location.getURL()); + youngRevision[0] = repository.getLatestRevision(); + repositoryRoot[0] = repository.getRepositoryRoot(false); + } + catch (SVNException e) { + exception[0] = e; + } + finally { + if (repository != null) { + repository.closeSession(); + } + } } + }, "Getting latest repository revision", true, myProject); + + if (exception[0] != null) { + throw new VcsException(exception[0]); + } + if (! succeeded) { + throw new ProcessCanceledException(); } final Iterator visualIterator = project.isDefault() ? null : @@ -78,7 +95,7 @@ public class SvnRevisionsNavigationMediator implements CommittedChangesNavigatio myVisuallyCached = (visualIterator == null) ? null : new VisuallyCachedProvider(visualIterator, myProject, location); myChunkFactory = new BunchFactory(myInternallyCached, myVisuallyCached, - new LiveProvider(vcs, location, youngRevision, new SvnLogUtil(myProject, vcs, location, repositoryRoot))); + new LiveProvider(vcs, location, youngRevision[0], new SvnLogUtil(myProject, vcs, location, repositoryRoot[0]))); myCurrentIdx = -1; // init first screen From e3ffc95c822ea7deb5118212d8a228ae27a2c017 Mon Sep 17 00:00:00 2001 From: irengrig Date: Mon, 6 Feb 2012 18:32:20 +0400 Subject: [PATCH 04/12] SVN 1.7: wc-locked attribute --- .../idea/svn17/commandLine/SvnStatusHandler.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn17/commandLine/SvnStatusHandler.java b/plugins/svn4idea/src/org/jetbrains/idea/svn17/commandLine/SvnStatusHandler.java index 3ff4c027b40c..65fe6819bae3 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn17/commandLine/SvnStatusHandler.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn17/commandLine/SvnStatusHandler.java @@ -339,6 +339,12 @@ public class SvnStatusHandler extends DefaultHandler { super(new String[]{"commit"}, new String[]{}); } + /**/ + @Override protected void updateStatus(Attributes attributes, PortableStatus status) throws SAXException { final String props = attributes.getValue("props"); @@ -355,6 +361,10 @@ public class SvnStatusHandler extends DefaultHandler { } // optional + final String locked = attributes.getValue("wc-locked"); + if (locked != null && Boolean.parseBoolean(locked)) { + status.setIsLocked(true); + } final String copied = attributes.getValue("copied"); if (copied != null && Boolean.parseBoolean(copied)) { status.setIsCopied(true); From 32a8880610b96b9035e377c6eddbf5a587606e66 Mon Sep 17 00:00:00 2001 From: irengrig Date: Mon, 6 Feb 2012 19:00:51 +0400 Subject: [PATCH 05/12] SVN: possible NPE fix --- .../src/org/jetbrains/idea/svn17/RootsToWorkingCopies.java | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn17/RootsToWorkingCopies.java b/plugins/svn4idea/src/org/jetbrains/idea/svn17/RootsToWorkingCopies.java index 6282ab342321..3a2ccdb3677d 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn17/RootsToWorkingCopies.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn17/RootsToWorkingCopies.java @@ -73,6 +73,7 @@ public class RootsToWorkingCopies implements VcsListener { @CalledInBackground public WorkingCopy getMatchingCopy(final SVNURL url) { assert ! ApplicationManager.getApplication().isDispatchThread(); + if (url == null) return null; final VirtualFile[] roots = ProjectLevelVcsManager.getInstance(myProject).getRootsUnderVcs(SvnVcs17.getInstance(myProject)); synchronized (myLock) { From aa82cbdb36e663429ae99d4a44d7f07522326533 Mon Sep 17 00:00:00 2001 From: irengrig Date: Tue, 7 Feb 2012 13:04:54 +0400 Subject: [PATCH 06/12] SVN+SSH: fingerprints: avoid deadlock (asked from background threadlead thread, but we might have ex update options dialog box showing modal simultaneously + auth progress) --- .../SvnInteractiveAuthenticationProvider.java | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn17/dialogs/SvnInteractiveAuthenticationProvider.java b/plugins/svn4idea/src/org/jetbrains/idea/svn17/dialogs/SvnInteractiveAuthenticationProvider.java index 7323a2ae2628..34cb4dff294c 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn17/dialogs/SvnInteractiveAuthenticationProvider.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn17/dialogs/SvnInteractiveAuthenticationProvider.java @@ -17,6 +17,8 @@ package org.jetbrains.idea.svn17.dialogs; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.MessageType; import com.intellij.openapi.vcs.ui.VcsBalloonProblemNotifier; @@ -31,7 +33,9 @@ import org.tmatesoft.svn.core.SVNErrorMessage; import org.tmatesoft.svn.core.SVNURL; import org.tmatesoft.svn.core.auth.*; +import javax.swing.*; import java.io.File; +import java.lang.reflect.InvocationTargetException; import java.security.cert.X509Certificate; public class SvnInteractiveAuthenticationProvider implements ISVNAuthenticationProvider { @@ -200,7 +204,20 @@ public class SvnInteractiveAuthenticationProvider implements ISVNAuthenticationP MessageType.ERROR); return REJECTED; } - WaitForProgressToShow.runOrInvokeAndWaitAboveProgress(command); + final ProgressIndicator pi = ProgressManager.getInstance().getProgressIndicator(); + if (pi != null) { + WaitForProgressToShow.runOrInvokeAndWaitAboveProgress(command, pi.getModalityState()); + } else { + try { + SwingUtilities.invokeAndWait(command); + } + catch (InterruptedException e) { + // + } + catch (InvocationTargetException e) { + // + } + } return result[0]; } From dc1b51d7ce25547cd146e19c8d182e7fc31875b5 Mon Sep 17 00:00:00 2001 From: irengrig Date: Tue, 7 Feb 2012 13:06:03 +0400 Subject: [PATCH 07/12] SVN 1.7: command line client - to be used for update (not switch) + http protocol --- .../idea/svn17/ProxySvnAuthentication.java | 10 +- .../idea/svn17/SvnAuthenticationManager.java | 34 ++- .../idea/svn17/SvnAuthenticationNotifier.java | 11 +- .../idea/svn17/SvnConfiguration17.java | 14 + .../auth/SvnAuthenticationInteraction.java | 2 + .../svn17/auth/SvnAuthenticationListener.java | 3 + .../commandLine/CommandLineAuthenticator.java | 200 +++++++++++++ .../SvnCommandLineUpdateClient.java | 270 ++++++++++++++++++ .../UpdateOutputLineConverter.java | 199 +++++++++++++ .../dialogs/SvnAuthenticationProvider.java | 5 + .../svn17/portable/SvnSvnkitUpdateClient.java | 206 +++++++++++++ .../idea/svn17/portable/SvnUpdateClientI.java | 75 +++++ .../svn17/update/SvnUpdateEnvironment17.java | 47 +-- .../idea/svn17/SvnAuthenticationTest.java | 8 + 14 files changed, 1057 insertions(+), 27 deletions(-) create mode 100644 plugins/svn4idea/src/org/jetbrains/idea/svn17/commandLine/CommandLineAuthenticator.java create mode 100644 plugins/svn4idea/src/org/jetbrains/idea/svn17/commandLine/SvnCommandLineUpdateClient.java create mode 100644 plugins/svn4idea/src/org/jetbrains/idea/svn17/commandLine/UpdateOutputLineConverter.java create mode 100644 plugins/svn4idea/src/org/jetbrains/idea/svn17/portable/SvnSvnkitUpdateClient.java create mode 100644 plugins/svn4idea/src/org/jetbrains/idea/svn17/portable/SvnUpdateClientI.java diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn17/ProxySvnAuthentication.java b/plugins/svn4idea/src/org/jetbrains/idea/svn17/ProxySvnAuthentication.java index 74b0a9e3bf31..25d49e231fa4 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn17/ProxySvnAuthentication.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn17/ProxySvnAuthentication.java @@ -26,9 +26,15 @@ public class ProxySvnAuthentication { private ProxySvnAuthentication() { } - public static SVNAuthentication proxy(final SVNAuthentication in, final boolean storeAuth) { - if (in.isStorageAllowed() == storeAuth || (! in.isStorageAllowed())) return in; + public static SVNAuthentication proxy(final SVNAuthentication in, final boolean storeAuth, boolean forceSaving) { + if (forceSaving && storeAuth) { + return putPassedValueAsSave(in, forceSaving); + } + if (in.isStorageAllowed() == storeAuth || ( ! in.isStorageAllowed())) return in; + return putPassedValueAsSave(in, storeAuth); + } + private static SVNAuthentication putPassedValueAsSave(SVNAuthentication in, boolean storeAuth) { final String userName = in.getUserName(); if (in instanceof SVNPasswordAuthentication) { return new SVNPasswordAuthentication(userName, ((SVNPasswordAuthentication)in).getPassword(), diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn17/SvnAuthenticationManager.java b/plugins/svn4idea/src/org/jetbrains/idea/svn17/SvnAuthenticationManager.java index f14dc7d2c1d0..71d7bd24a02d 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn17/SvnAuthenticationManager.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn17/SvnAuthenticationManager.java @@ -18,6 +18,7 @@ package org.jetbrains.idea.svn17; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.Project; @@ -67,6 +68,7 @@ public class SvnAuthenticationManager extends DefaultSVNAuthenticationManager im private IdeaSVNHostOptionsProvider myLocalHostOptionsProvider; private final ThreadLocalSavePermissions mySavePermissions; private final Map myKeyAlgorithm; + private boolean myArtificialSaving; public SvnAuthenticationManager(final Project project, final File configDirectory) { super(configDirectory, true, null, null); @@ -82,6 +84,10 @@ public class SvnAuthenticationManager extends DefaultSVNAuthenticationManager im myInteraction = new MySvnAuthenticationInteraction(myProject); } + public void setArtificialSaving(boolean artificialSaving) { + myArtificialSaving = artificialSaving; + } + private void ensureListenerCreated() { if (myListener == null) { myListener = EventDispatcher.create(SvnAuthenticationListener.class); @@ -115,6 +121,11 @@ public class SvnAuthenticationManager extends DefaultSVNAuthenticationManager im myListener.getMulticaster().saveAttemptFinished(type, url, realm, kind); } + @Override + public void acknowledge(boolean accepted, String kind, String realm, SVNErrorMessage message, SVNAuthentication authentication) { + myListener.getMulticaster().acknowledge(accepted, kind, realm, message, authentication); + } + @Override public void requested(ProviderType type, SVNURL url, String realm, String kind, boolean canceled) { if (ProviderType.interactive.equals(type) && (! canceled)) { @@ -137,12 +148,18 @@ public class SvnAuthenticationManager extends DefaultSVNAuthenticationManager im String realm, SVNErrorMessage errorMessage, SVNAuthentication authentication) throws SVNException { + boolean successSaving = false; + myListener.getMulticaster().acknowledge(accepted, kind, realm, errorMessage, authentication); try { final boolean authStorageEnabled = getHostOptionsProvider().getHostOptions(authentication.getURL()).isAuthStorageEnabled(); - final SVNAuthentication proxy = ProxySvnAuthentication.proxy(authentication, authStorageEnabled); + final SVNAuthentication proxy = ProxySvnAuthentication.proxy(authentication, authStorageEnabled, myArtificialSaving); super.acknowledgeAuthentication(accepted, kind, realm, errorMessage, proxy); + successSaving = true; } finally { mySavePermissions.remove(); + if (myArtificialSaving) { + throw new CredentialsSavedException(successSaving); + } } } @@ -229,11 +246,10 @@ public class SvnAuthenticationManager extends DefaultSVNAuthenticationManager im public void saveAuthentication(final SVNAuthentication auth, final String kind, final String realm) throws SVNException { final Boolean fromInteractive = ourJustEntered.get(); ourJustEntered.set(null); - if (! Boolean.TRUE.equals(fromInteractive)) { + if (! myArtificialSaving && ! Boolean.TRUE.equals(fromInteractive)) { // not what user entered return; } - myListener.getMulticaster().saveAttemptStarted(ProviderType.persistent, auth.getURL(), realm, auth.getKind()); ((ISVNPersistentAuthenticationProvider) myDelegate).saveAuthentication(auth, kind, realm); myListener.getMulticaster().saveAttemptFinished(ProviderType.persistent, auth.getURL(), realm, auth.getKind()); @@ -822,4 +838,16 @@ public class SvnAuthenticationManager extends DefaultSVNAuthenticationManager im return s[0]; } } + + public static class CredentialsSavedException extends RuntimeException { + private final boolean mySuccess; + + public CredentialsSavedException(boolean success) { + mySuccess = success; + } + + public boolean isSuccess() { + return mySuccess; + } + } } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn17/SvnAuthenticationNotifier.java b/plugins/svn4idea/src/org/jetbrains/idea/svn17/SvnAuthenticationNotifier.java index a494e24a237b..ffc2d4002b47 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn17/SvnAuthenticationNotifier.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn17/SvnAuthenticationNotifier.java @@ -178,7 +178,7 @@ public class SvnAuthenticationNotifier extends GenericNotifierImpl { return myOptions; } + public static SvnAuthenticationManager createForTmpDir(final Project project, final File dir) { + final SvnVcs17 vcs = SvnVcs17.getInstance(project); + //final SvnAuthenticationManager manager = new SvnAuthenticationManager(project, dir); + + final SvnAuthenticationManager interactive = new SvnAuthenticationManager(project, dir); + interactive.setRuntimeStorage(RUNTIME_AUTH_CACHE); + final SvnInteractiveAuthenticationProvider interactiveProvider = new SvnInteractiveAuthenticationProvider(vcs, interactive); + interactive.setAuthenticationProvider(interactiveProvider); + + //manager.setAuthenticationProvider(new SvnAuthenticationProvider(vcs, interactiveProvider, RUNTIME_AUTH_CACHE)); + //manager.setRuntimeStorage(RUNTIME_AUTH_CACHE); + return interactive; + } + public SvnAuthenticationManager getAuthenticationManager(final SvnVcs17 svnVcs) { if (myAuthManager == null) { // reloaded when configuration directory changes diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn17/auth/SvnAuthenticationInteraction.java b/plugins/svn4idea/src/org/jetbrains/idea/svn17/auth/SvnAuthenticationInteraction.java index 568a72ff41d9..2d43bddd06a8 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn17/auth/SvnAuthenticationInteraction.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn17/auth/SvnAuthenticationInteraction.java @@ -15,7 +15,9 @@ */ package org.jetbrains.idea.svn17.auth; +import org.tmatesoft.svn.core.SVNErrorMessage; import org.tmatesoft.svn.core.SVNURL; +import org.tmatesoft.svn.core.auth.SVNAuthentication; import java.io.File; diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn17/auth/SvnAuthenticationListener.java b/plugins/svn4idea/src/org/jetbrains/idea/svn17/auth/SvnAuthenticationListener.java index dc556ec452e1..7f3558494b91 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn17/auth/SvnAuthenticationListener.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn17/auth/SvnAuthenticationListener.java @@ -15,7 +15,9 @@ */ package org.jetbrains.idea.svn17.auth; +import org.tmatesoft.svn.core.SVNErrorMessage; import org.tmatesoft.svn.core.SVNURL; +import org.tmatesoft.svn.core.auth.SVNAuthentication; import java.util.EventListener; @@ -24,4 +26,5 @@ public interface SvnAuthenticationListener extends EventListener { void actualSaveWillBeTried(final ProviderType type, final SVNURL url, String realm, String kind); void saveAttemptStarted(final ProviderType type, final SVNURL url, String realm, String kind); void saveAttemptFinished(final ProviderType type, final SVNURL url, String realm, String kind); + void acknowledge(boolean accepted, String kind, String realm, SVNErrorMessage message, SVNAuthentication authentication); } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn17/commandLine/CommandLineAuthenticator.java b/plugins/svn4idea/src/org/jetbrains/idea/svn17/commandLine/CommandLineAuthenticator.java new file mode 100644 index 000000000000..1cffdfb64c79 --- /dev/null +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn17/commandLine/CommandLineAuthenticator.java @@ -0,0 +1,200 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.idea.svn17.commandLine; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.MessageType; +import com.intellij.openapi.util.Trinity; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.vcs.ui.VcsBalloonProblemNotifier; +import org.jetbrains.idea.svn17.SvnAuthenticationManager; +import org.jetbrains.idea.svn17.SvnConfiguration17; +import org.jetbrains.idea.svn17.SvnVcs17; +import org.jetbrains.idea.svn17.auth.ProviderType; +import org.jetbrains.idea.svn17.auth.SvnAuthenticationListener; +import org.tmatesoft.svn.core.SVNErrorCode; +import org.tmatesoft.svn.core.SVNErrorMessage; +import org.tmatesoft.svn.core.SVNException; +import org.tmatesoft.svn.core.SVNURL; +import org.tmatesoft.svn.core.auth.SVNAuthentication; +import org.tmatesoft.svn.core.wc.SVNRevision; +import org.tmatesoft.svn.core.wc.SVNWCClient; + +import java.io.File; +import java.io.IOException; +import java.util.HashSet; +import java.util.Set; + +/** + * Created with IntelliJ IDEA. + * User: Irina.Chernushina + * Date: 2/1/12 + * Time: 12:28 PM + */ +public class CommandLineAuthenticator { + private static final Logger LOG = Logger.getInstance("#org.jetbrains.idea.svn17.commandLine.CommandLineAuthenticator"); + private final Project myProject; + private final AuthenticationRequiringCommand myCommand; + private final SvnConfiguration17 myConfiguration17; + private final File myConfigDir; + + public CommandLineAuthenticator(Project project, AuthenticationRequiringCommand command) { + myProject = project; + myCommand = command; + myConfiguration17 = SvnConfiguration17.getInstance(project); + final String configurationDirectory = myConfiguration17.getConfigurationDirectory(); + myConfigDir = new File(configurationDirectory); + } + + public void doWithAuthentication() throws SVNException { + try { + myCommand.run(myConfigDir); + return; + } catch (SVNException e) { + if (! e.getErrorMessage().getErrorCode().isAuthentication()) throw e; + } + File tempDirectory = null; + try { + tempDirectory = FileUtil.createTempDirectory("tmp", "Subversion"); + final SvnAuthenticationManager authenticationManager = SvnConfiguration17.createForTmpDir(myProject, tempDirectory); + //authenticationManager.setAuthenticationForced(true); + authenticationManager.setArtificialSaving(true); + myCommand.cleanup(); + tryGetCredentials(authenticationManager, tempDirectory); + + myCommand.cleanup(); + myCommand.run(tempDirectory); + } + catch (IOException e) { + throw new SVNException(SVNErrorMessage.create(SVNErrorCode.IO_ERROR), e); + } finally { + if (tempDirectory != null) { + FileUtil.delete(tempDirectory); + } + } + } + + private void tryGetCredentials(SvnAuthenticationManager manager, final File tempDirectory) throws SVNException { + final StoreListener storeListener = new StoreListener(); + manager.addListener(storeListener); + final SVNURL svnurl = myCommand.sampleUrl(); + try { + myCommand.runWithSvnkitClient(tempDirectory, manager); + LOG.assertTrue(false, "Credentials not asked"); // todo? + } catch (SvnAuthenticationManager.CredentialsSavedException e) { + // ok, check result? + if (e.isSuccess()) { + final SvnAuthenticationManager realManager = myConfiguration17.getAuthenticationManager(SvnVcs17.getInstance(myProject)); + storeListener.reStore(myProject, realManager, svnurl); + } + } + //final SVNWCClient client = new SVNWCClient(manager, myConfiguration17.getOptions(myProject)); + //client.doInfo(svnurl, SVNRevision.UNDEFINED, SVNRevision.UNDEFINED); + } + + public interface AuthenticationRequiringCommand { + void run(final File configDir) throws SVNException; + void runWithSvnkitClient(final File configDir, SvnAuthenticationManager manager) throws SVNException; + SVNURL sampleUrl(); + void cleanup() throws SVNException; + } + + private static class StoreListener implements SvnAuthenticationListener { + private final Set myData; + private final Set> myAuthRequested; + + private StoreListener() { + myData = new HashSet(); + myAuthRequested = new HashSet>(); + } + + @Override + public void requested(ProviderType type, SVNURL url, String realm, String kind, boolean canceled) { + if (ProviderType.interactive.equals(type)) { + myAuthRequested.add(create(kind, realm, url)); + } + } + + private Trinity create(String kind, String realm, SVNURL url) { + return new Trinity(kind, realm, url); + } + + @Override + public void actualSaveWillBeTried(ProviderType type, SVNURL url, String realm, String kind) { + } + @Override + public void saveAttemptStarted(ProviderType type, SVNURL url, String realm, String kind) { + } + @Override + public void saveAttemptFinished(ProviderType type, SVNURL url, String realm, String kind) { + } + @Override + public void acknowledge(boolean accepted, String kind, String realm, SVNErrorMessage message, SVNAuthentication authentication) { + if (accepted && authentication.isStorageAllowed()) { + final Trinity trinity = create(kind, realm, authentication.getURL()); + if (myAuthRequested.contains(trinity)) { + myData.add(new StoreData(kind, realm, authentication)); + } + } + } + + public void reStore(final Project project, final SvnAuthenticationManager realManager, final SVNURL svnurl) { + for (StoreData data : myData) { + if (data.myAuthentication == null) continue; + realManager.requested(ProviderType.interactive, svnurl, data.myRealm, data.myKind, false); + try { + realManager.acknowledgeAuthentication(true, data.myKind, data.myRealm, null, data.myAuthentication); + } + catch (SVNException e) { + VcsBalloonProblemNotifier.showOverChangesView(project, "Wasn't able to store credentials: " + e.getMessage(), MessageType.ERROR); + } + } + } + } + + private static class StoreData { + public String myKind; + public String myRealm; + public SVNAuthentication myAuthentication; + + private StoreData(String kind, String realm, SVNAuthentication authentication) { + myKind = kind; + myRealm = realm; + myAuthentication = authentication; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + StoreData data = (StoreData)o; + + if (myKind != null ? !myKind.equals(data.myKind) : data.myKind != null) return false; + if (myRealm != null ? !myRealm.equals(data.myRealm) : data.myRealm != null) return false; + + return true; + } + + @Override + public int hashCode() { + int result = myKind != null ? myKind.hashCode() : 0; + result = 31 * result + (myRealm != null ? myRealm.hashCode() : 0); + return result; + } + } +} diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn17/commandLine/SvnCommandLineUpdateClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn17/commandLine/SvnCommandLineUpdateClient.java new file mode 100644 index 000000000000..87f54e9b53eb --- /dev/null +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn17/commandLine/SvnCommandLineUpdateClient.java @@ -0,0 +1,270 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.idea.svn17.commandLine; + +import com.intellij.execution.process.ProcessOutputTypes; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.vcs.LineProcessEventListener; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.util.concurrency.Semaphore; +import org.jetbrains.idea.svn17.SvnAuthenticationManager; +import org.jetbrains.idea.svn17.SvnConfiguration17; +import org.jetbrains.idea.svn17.SvnVcs17; +import org.jetbrains.idea.svn17.portable.SvnExceptionWrapper; +import org.jetbrains.idea.svn17.portable.SvnSvnkitUpdateClient; +import org.tmatesoft.svn.core.*; +import org.tmatesoft.svn.core.wc.*; + +import java.io.File; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Created with IntelliJ IDEA. + * User: Irina.Chernushina + * Date: 2/1/12 + * Time: 12:13 PM + */ +public class SvnCommandLineUpdateClient extends SvnSvnkitUpdateClient { + private static final Pattern ourExceptionPattern = Pattern.compile("svn: E(\\d{6}): .+"); + private static final String ourAuthenticationRealm = "Authentication realm:"; + private final Project myProject; + private final VirtualFile myCommonAncestor; + + public SvnCommandLineUpdateClient(final Project project, VirtualFile commonAncestor) { + super(SvnVcs17.getInstance(project).createUpdateClient()); + myProject = project; + myCommonAncestor = commonAncestor; + } + + @Override + public long doUpdate(File file, SVNRevision revision, boolean recursive) throws SVNException { + final long[] longs = doUpdate(new File[]{file}, revision, SVNDepth.fromRecurse(recursive), false, false, false); + return longs[0]; + } + + @Override + public long doUpdate(File file, SVNRevision revision, boolean recursive, boolean force) throws SVNException { + final long[] longs = doUpdate(new File[]{file}, revision, SVNDepth.fromRecurse(recursive), force, false, false); + return longs[0]; + } + + @Override + public long[] doUpdate(File[] paths, SVNRevision revision, SVNDepth depth, boolean allowUnversionedObstructions, boolean depthIsSticky) + throws SVNException { + return doUpdate(paths, revision, depth, allowUnversionedObstructions, depthIsSticky, false); + } + + @Override + public long[] doUpdate(final File[] paths, final SVNRevision revision, final SVNDepth depth, final boolean allowUnversionedObstructions, + final boolean depthIsSticky, final boolean makeParents) throws SVNException { + // since one revision is passed -> I assume same repository here + final SvnCommandLineInfoClient infoClient = new SvnCommandLineInfoClient(myProject); + final SVNInfo info = infoClient.doInfo(paths[0], SVNRevision.UNDEFINED); + if (info == null || info.getURL() == null) { + throw new SVNException(SVNErrorMessage.create(SVNErrorCode.WC_NOT_WORKING_COPY, paths[0].getPath())); + } + final long[] result = new long[paths.length]; + + new CommandLineAuthenticator(myProject, new CommandLineAuthenticator.AuthenticationRequiringCommand() { + @Override + public void run(File configDir) throws SVNException { + final File base = myCommonAncestor == null ? paths[0] : new File(myCommonAncestor.getPath()); + final SvnLineCommand command = new SvnLineCommand(myProject, base, SvnCommandName.up); + if (revision != null && ! SVNRevision.UNDEFINED.equals(revision) && ! SVNRevision.WORKING.equals(revision)) { + command.addParameters("-r", revision.toString()); + } + // unknown depth is not used any more for 1.7 -> why? + if (depth != null && ! SVNDepth.UNKNOWN.equals(depth)) { + command.addParameters("--depth", depth.toString()); + } + if (allowUnversionedObstructions) { + command.addParameters("--force"); + } + if (depthIsSticky && depth != null) {// !!! not sure, but not used + command.addParameters("--set-depth", depth.toString()); + } + if (makeParents) { + command.addParameters("--parents"); + } + command.addParameters("--accept", "postpone"); + command.addParameters("--config-dir", configDir.getPath()); + + for (File path : paths) { + command.addParameters(path.getPath()); + } + + final StringBuffer sbError = new StringBuffer(); + final Semaphore semaphore = new Semaphore(); + semaphore.down(); + final ISVNEventHandler handler = getEventHandler(); + final UpdateOutputLineConverter converter = new UpdateOutputLineConverter(base); + final SVNException[] innerException = new SVNException[1]; + command.addListener(new LineProcessEventListener() { + @Override + public void onLineAvailable(String line, Key outputType) { + if (ProcessOutputTypes.STDOUT.equals(outputType)) { + final SVNEvent event = converter.convert(line); + if (event != null) { + checkForUpdateCompleted(event); + try { + handler.handleEvent(event, 0.5); + } + catch (SVNException e) { + command.cancel(); + semaphore.up(); + innerException[0] = e; + } + } + } else if (ProcessOutputTypes.STDERR.equals(outputType)) { + sbError.append(line); + if (line.contains(ourAuthenticationRealm)) { + command.cancel(); + semaphore.up(); + } + } + } + + @Override + public void processTerminated(int exitCode) { + semaphore.up(); + } + + @Override + public void startFailed(Throwable exception) { + semaphore.up(); + } + }); + try { + command.start(); + semaphore.waitFor(); + + checkForException(sbError); + } catch (SvnExceptionWrapper e){ + throw (SVNException) e.getCause(); + } + } + + @Override + public void runWithSvnkitClient(File configDir, SvnAuthenticationManager manager) throws SVNException { + final SVNUpdateClient client = new SVNUpdateClient(manager, SvnConfiguration17.getInstance(myProject).getOptions(myProject)); + client.doUpdate(paths, revision, depth, allowUnversionedObstructions, depthIsSticky, makeParents); + } + + private void checkForUpdateCompleted(SVNEvent event) { + if (SVNEventAction.UPDATE_COMPLETED.equals(event.getAction())) { + final long eventRevision = event.getRevision(); + for (int i = 0; i < paths.length; i++) { + final File path = paths[i]; + if (path.equals(event.getFile())) { + result[i] = eventRevision; + break; + } + } + } + } + + @Override + public SVNURL sampleUrl() { + return info.getURL(); + } + + @Override + public void cleanup() throws SVNException { + final SvnVcs17 vcs17 = SvnVcs17.getInstance(myProject); + final SVNWCClient client = vcs17.createWCClient(); + for (File path : paths) { + client.doCleanup(path); + } + } + }).doWithAuthentication(); + return result; + } + + private void checkForException(final StringBuffer sbError) throws SVNException { + if (sbError.length() == 0) return; + final String message = sbError.toString(); + final Matcher matcher = ourExceptionPattern.matcher(message); + if (matcher.matches()) { + final String group = matcher.group(1); + if (group != null) { + try { + final int code = Integer.parseInt(group); + throw new SVNException(SVNErrorMessage.create(SVNErrorCode.getErrorCode(code), message)); + } catch (NumberFormatException e) { + // + } + } + } + if (message.contains(ourAuthenticationRealm)) { + throw new SVNException(SVNErrorMessage.create(SVNErrorCode.AUTHN_CREDS_UNAVAILABLE, message)); + } + throw new SVNException(SVNErrorMessage.create(SVNErrorCode.UNKNOWN, message)); + } + + @Override + public long doUpdate(File path, SVNRevision revision, SVNDepth depth, boolean allowUnversionedObstructions, boolean depthIsSticky) + throws SVNException { + final long[] longs = doUpdate(new File[]{path}, revision, depth, allowUnversionedObstructions, depthIsSticky, false); + return longs[0]; + } + + @Override + public long doSwitch(File file, SVNURL url, SVNRevision revision, boolean recursive) throws SVNException { + throw new UnsupportedOperationException(); + //return super.doSwitch(file, url, revision, recursive); + } + + @Override + public long doSwitch(File file, SVNURL url, SVNRevision pegRevision, SVNRevision revision, boolean recursive) throws SVNException { + throw new UnsupportedOperationException(); + //return super.doSwitch(file, url, pegRevision, revision, recursive); + } + + @Override + public long doSwitch(File file, SVNURL url, SVNRevision pegRevision, SVNRevision revision, boolean recursive, boolean force) + throws SVNException { + throw new UnsupportedOperationException(); + //return super.doSwitch(file, url, pegRevision, revision, recursive, force); + } + + @Override + public long doSwitch(File path, + SVNURL url, + SVNRevision pegRevision, + SVNRevision revision, + SVNDepth depth, + boolean allowUnversionedObstructions, + boolean depthIsSticky) throws SVNException { + throw new UnsupportedOperationException(); + //return super.doSwitch(path, url, pegRevision, revision, depth, allowUnversionedObstructions, depthIsSticky); + } + + @Override + public long doSwitch(File path, + SVNURL url, + SVNRevision pegRevision, + SVNRevision revision, + SVNDepth depth, + boolean allowUnversionedObstructions, + boolean depthIsSticky, + boolean ignoreAncestry) throws SVNException { + throw new UnsupportedOperationException(); + // todo MAIN + //return super.doSwitch(path, url, pegRevision, revision, depth, allowUnversionedObstructions, depthIsSticky, ignoreAncestry); + } +} diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn17/commandLine/UpdateOutputLineConverter.java b/plugins/svn4idea/src/org/jetbrains/idea/svn17/commandLine/UpdateOutputLineConverter.java new file mode 100644 index 000000000000..80c50ea9c7dc --- /dev/null +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn17/commandLine/UpdateOutputLineConverter.java @@ -0,0 +1,199 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.idea.svn17.commandLine; + +import com.intellij.openapi.util.text.StringUtil; +import org.jetbrains.annotations.Nullable; +import org.tmatesoft.svn.core.SVNErrorCode; +import org.tmatesoft.svn.core.SVNErrorMessage; +import org.tmatesoft.svn.core.SVNNodeKind; +import org.tmatesoft.svn.core.wc.SVNEvent; +import org.tmatesoft.svn.core.wc.SVNEventAction; +import org.tmatesoft.svn.core.wc.SVNStatusType; + +import java.io.File; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Created with IntelliJ IDEA. + * User: Irina.Chernushina + * Date: 2/1/12 + * Time: 5:13 PM + */ +public class UpdateOutputLineConverter { + private final static String UPDATING = "Updating"; + private final static String AT_REVISION = "At revision (\\d+)\\."; + private final static String UPDATED_TO_REVISION = "Updated to revision (\\d+)\\."; + private final static String SKIPPED = "Skipped"; + private final static String RESTORED = "Restored"; + + private final static String FETCHING_EXTERNAL = "Fetching external"; + private final static String EXTERNAL = "External at (\\d+)\\."; + private final static String UPDATED_EXTERNAL = "Updated external to revision (\\d+)\\."; + + private final static Pattern ourAtRevision = Pattern.compile(AT_REVISION); + private final static Pattern ourUpdatedToRevision = Pattern.compile(UPDATED_TO_REVISION); + + private final static Pattern ourExternal = Pattern.compile(EXTERNAL); + private final static Pattern ourUpdatedExternal = Pattern.compile(UPDATED_EXTERNAL); + + private final static Pattern[] ourCompletePatterns = new Pattern[] {ourAtRevision, ourUpdatedToRevision, ourExternal, ourUpdatedExternal}; + + private final File myBase; + private File myCurrentFile; + + public UpdateOutputLineConverter(File base) { + myBase = base; + } + + public SVNEvent convert(final String line) { + if (StringUtil.isEmptyOrSpaces(line)) return null; + + if (line.startsWith(UPDATING)) { + myCurrentFile = parseForPath(line); + return new SVNEvent(myCurrentFile, myCurrentFile == null ? null : (myCurrentFile.isDirectory() ? SVNNodeKind.DIR : SVNNodeKind.FILE), + null, -1, null, null, null, null, SVNEventAction.UPDATE_NONE, SVNEventAction.UPDATE_NONE, null, null, null, null, null); + } else if (line.startsWith(RESTORED)) { + myCurrentFile = parseForPath(line); + return new SVNEvent(myCurrentFile, myCurrentFile == null ? null : (myCurrentFile.isDirectory() ? SVNNodeKind.DIR : SVNNodeKind.FILE), + null, -1, null, null, null, null, SVNEventAction.RESTORE, SVNEventAction.RESTORE, null, null, null, null, null); + } else if (line.startsWith(SKIPPED)) { + myCurrentFile = parseForPath(line); + final String comment = parseComment(line); + return new SVNEvent(myCurrentFile, myCurrentFile == null ? null : (myCurrentFile.isDirectory() ? SVNNodeKind.DIR : SVNNodeKind.FILE), + null, -1, null, null, null, null, SVNEventAction.SKIP, SVNEventAction.SKIP, + comment == null ? null : SVNErrorMessage.create(SVNErrorCode.WC_OBSTRUCTED_UPDATE, comment), null, null, null, null); + } else if (line.startsWith(FETCHING_EXTERNAL)) { + myCurrentFile = parseForPath(line); + return new SVNEvent(myCurrentFile, myCurrentFile == null ? null : (myCurrentFile.isDirectory() ? SVNNodeKind.DIR : SVNNodeKind.FILE), + null, -1, null, null, null, null, SVNEventAction.UPDATE_EXTERNAL, SVNEventAction.UPDATE_EXTERNAL, null, null, null, null, null); + } + + for (int i = 0; i < ourCompletePatterns.length; i++) { + final Pattern pattern = ourCompletePatterns[i]; + final long revision = matchAndGetRevision(pattern, line); + if (revision != -1) { + return new SVNEvent(myCurrentFile, myCurrentFile == null ? null : (myCurrentFile.isDirectory() ? SVNNodeKind.DIR : SVNNodeKind.FILE), + null, revision, null, null, null, null, SVNEventAction.UPDATE_COMPLETED, SVNEventAction.UPDATE_COMPLETED, null, null, null, null, null); + } + } + + return parseNormalString(line); + } + + private final static Set ourActions = new HashSet(Arrays.asList(new Character[] {'A', 'D', 'U', 'C', 'G', 'E', 'R'})); + + @Nullable + private SVNEvent parseNormalString(final String line) { + 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 char second = line.charAt(1); + final SVNStatusType propertiesStatus = 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); + if (' ' != treeConflict && 'C' != treeConflict) return null; + final boolean haveTreeConflict = 'C' == treeConflict; + + final String path = line.substring(4).trim(); + if (StringUtil.isEmptyOrSpaces(path)) return null; + final File file = new File(myBase, path); + if (SVNStatusType.STATUS_OBSTRUCTED.equals(contentsStatus)) { + // obstructed + return new SVNEvent(file, file.isDirectory() ? SVNNodeKind.DIR : SVNNodeKind.FILE, + null, -1, contentsStatus, propertiesStatus, null, null, SVNEventAction.UPDATE_SKIP_OBSTRUCTION, SVNEventAction.UPDATE_ADD, + null, null, null, null, null); + } + + SVNEventAction action; + SVNEventAction expectedAction; + if (SVNStatusType.STATUS_ADDED.equals(contentsStatus)) { + expectedAction = SVNEventAction.UPDATE_ADD; + } else if (SVNStatusType.STATUS_DELETED.equals(contentsStatus)) { + expectedAction = SVNEventAction.UPDATE_DELETE; + } else { + expectedAction = SVNEventAction.UPDATE_UPDATE; + } + action = expectedAction; + if (haveTreeConflict) { + action = SVNEventAction.TREE_CONFLICT; + } + + return new SVNEvent(file, file.isDirectory() ? SVNNodeKind.DIR : SVNNodeKind.FILE, null, -1, contentsStatus, propertiesStatus, null, + 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); + if (matcher.matches()) { + final String group = matcher.group(1); + if (group == null) return -1; + try { + return Long.parseLong(group); + } catch (NumberFormatException e) { + // + } + } + return -1; + } + + @Nullable + private String parseComment(final String line) { + final int idx = line.lastIndexOf("--"); + if (idx != -1 && idx < (line.length() - 2)) { + return line.substring(idx + 2).trim(); + } + return null; + } + + @Nullable + private File parseForPath(final String line) { + final int idx1 = line.indexOf('\''); + if (idx1 == -1) return null; + final int idx2 = line.indexOf('\'', idx1 + 1); + if (idx2 == -1) return null; + final String substring = line.substring(idx1 + 1, idx2); + if (".".equals(substring)) return myBase; + return new File(myBase, substring); + } +} diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn17/dialogs/SvnAuthenticationProvider.java b/plugins/svn4idea/src/org/jetbrains/idea/svn17/dialogs/SvnAuthenticationProvider.java index 44a35487ccee..93a5383534d6 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn17/dialogs/SvnAuthenticationProvider.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn17/dialogs/SvnAuthenticationProvider.java @@ -17,11 +17,14 @@ package org.jetbrains.idea.svn17.dialogs; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.Project; import com.intellij.util.SystemProperties; import org.jetbrains.idea.svn17.SvnAuthenticationNotifier; +import org.jetbrains.idea.svn17.SvnConfiguration17; import org.jetbrains.idea.svn17.SvnVcs17; import org.tmatesoft.svn.core.SVNErrorMessage; +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.ISVNAuthenticationProvider; @@ -40,11 +43,13 @@ public class SvnAuthenticationProvider implements ISVNAuthenticationProvider { private final Project myProject; private final SvnAuthenticationNotifier myAuthenticationNotifier; private final ISVNAuthenticationProvider mySvnInteractiveAuthenticationProvider; + private final SvnVcs17 mySvnVcs; private final ISVNAuthenticationStorage myAuthenticationStorage; private static final Set ourForceInteractive = new HashSet(); public SvnAuthenticationProvider(final SvnVcs17 svnVcs, final ISVNAuthenticationProvider provider, final ISVNAuthenticationStorage authenticationStorage) { + mySvnVcs = svnVcs; myAuthenticationStorage = authenticationStorage; myProject = svnVcs.getProject(); myAuthenticationNotifier = svnVcs.getAuthNotifier(); diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn17/portable/SvnSvnkitUpdateClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn17/portable/SvnSvnkitUpdateClient.java new file mode 100644 index 000000000000..dfc26591277b --- /dev/null +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn17/portable/SvnSvnkitUpdateClient.java @@ -0,0 +1,206 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.idea.svn17.portable; + +import org.tmatesoft.svn.core.SVNDepth; +import org.tmatesoft.svn.core.SVNException; +import org.tmatesoft.svn.core.SVNURL; +import org.tmatesoft.svn.core.wc.ISVNEventHandler; +import org.tmatesoft.svn.core.wc.SVNRevision; +import org.tmatesoft.svn.core.wc.SVNUpdateClient; + +import java.io.File; + +/** + * Created with IntelliJ IDEA. + * User: Irina.Chernushina + * Date: 2/1/12 + * Time: 12:11 PM + */ +public class SvnSvnkitUpdateClient implements SvnUpdateClientI { + private final SVNUpdateClient myClient; + private ISVNEventHandler myDispatcher; + + public SvnSvnkitUpdateClient(SVNUpdateClient client) { + myClient = client; + } + + @Override + public long doUpdate(File file, SVNRevision revision, boolean recursive) throws SVNException { + return myClient.doUpdate(file, revision, recursive); + } + + @Override + public long doUpdate(File file, SVNRevision revision, boolean recursive, boolean force) throws SVNException { + return myClient.doUpdate(file, revision, recursive, force); + } + + @Override + public long[] doUpdate(File[] paths, + SVNRevision revision, + SVNDepth depth, + boolean allowUnversionedObstructions, + boolean depthIsSticky) throws SVNException { + return myClient.doUpdate(paths, revision, depth, allowUnversionedObstructions, depthIsSticky); + } + + @Override + public long[] doUpdate(File[] paths, + SVNRevision revision, + SVNDepth depth, + boolean allowUnversionedObstructions, + boolean depthIsSticky, + boolean makeParents) throws SVNException { + return myClient.doUpdate(paths, revision, depth, allowUnversionedObstructions, depthIsSticky, makeParents); + } + + @Override + public long doUpdate(File path, SVNRevision revision, SVNDepth depth, boolean allowUnversionedObstructions, boolean depthIsSticky) + throws SVNException { + return myClient.doUpdate(path, revision, depth, allowUnversionedObstructions, depthIsSticky); + } + + @Override + public void setUpdateLocksOnDemand(boolean locksOnDemand) { + myClient.setUpdateLocksOnDemand(locksOnDemand); + } + + @Override + public long doSwitch(File file, SVNURL url, SVNRevision revision, boolean recursive) throws SVNException { + return myClient.doSwitch(file, url, revision, recursive); + } + + @Override + public long doSwitch(File file, SVNURL url, SVNRevision pegRevision, SVNRevision revision, boolean recursive) throws SVNException { + return myClient.doSwitch(file, url, pegRevision, revision, recursive); + } + + @Override + public long doSwitch(File file, SVNURL url, SVNRevision pegRevision, SVNRevision revision, boolean recursive, boolean force) + throws SVNException { + return myClient.doSwitch(file, url, pegRevision, revision, recursive, force); + } + + @Override + public long doSwitch(File path, + SVNURL url, + SVNRevision pegRevision, + SVNRevision revision, + SVNDepth depth, + boolean allowUnversionedObstructions, boolean depthIsSticky) throws SVNException { + return myClient.doSwitch(path, url, pegRevision, revision, depth, allowUnversionedObstructions, depthIsSticky); + } + + @Override + public long doSwitch(File path, + SVNURL url, + SVNRevision pegRevision, + SVNRevision revision, + SVNDepth depth, + boolean allowUnversionedObstructions, boolean depthIsSticky, boolean ignoreAncestry) throws SVNException { + return myClient.doSwitch(path, url, pegRevision, revision, depth, allowUnversionedObstructions, depthIsSticky, ignoreAncestry); + } + + @Override + public long doCheckout(SVNURL url, File dstPath, SVNRevision pegRevision, SVNRevision revision, boolean recursive) throws SVNException { + return myClient.doCheckout(url, dstPath, pegRevision, revision, recursive); + } + + @Override + public long doCheckout(SVNURL url, File dstPath, SVNRevision pegRevision, SVNRevision revision, boolean recursive, boolean force) + throws SVNException { + return myClient.doCheckout(url, dstPath, pegRevision, revision, recursive, force); + } + + @Override + public long doCheckout(SVNURL url, + File dstPath, + SVNRevision pegRevision, + SVNRevision revision, + SVNDepth depth, + boolean allowUnversionedObstructions) throws SVNException { + return myClient.doCheckout(url, dstPath, pegRevision, revision, depth, allowUnversionedObstructions); + } + + @Override + public long doExport(SVNURL url, + File dstPath, + SVNRevision pegRevision, + SVNRevision revision, + String eolStyle, + boolean force, + boolean recursive) throws SVNException { + return myClient.doExport(url, dstPath, pegRevision, revision, eolStyle, force, recursive); + } + + @Override + public long doExport(SVNURL url, + File dstPath, + SVNRevision pegRevision, + SVNRevision revision, + String eolStyle, + boolean overwrite, + SVNDepth depth) throws SVNException { + return myClient.doExport(url, dstPath, pegRevision, revision, eolStyle, overwrite, depth); + } + + @Override + public long doExport(File srcPath, + File dstPath, + SVNRevision pegRevision, + SVNRevision revision, + String eolStyle, + boolean force, + boolean recursive) throws SVNException { + return myClient.doExport(srcPath, dstPath, pegRevision, revision, eolStyle, force, recursive); + } + + @Override + public long doExport(File srcPath, + File dstPath, + SVNRevision pegRevision, + SVNRevision revision, + String eolStyle, + boolean overwrite, + SVNDepth depth) throws SVNException { + return myClient.doExport(srcPath, dstPath, pegRevision, revision, eolStyle, overwrite, depth); + } + + @Override + public void doRelocate(File dst, SVNURL oldURL, SVNURL newURL, boolean recursive) throws SVNException { + myClient.doRelocate(dst, oldURL, newURL, recursive); + } + + @Override + public void doCanonicalizeURLs(File dst, boolean omitDefaultPort, boolean recursive) throws SVNException { + myClient.doCanonicalizeURLs(dst, omitDefaultPort, recursive); + } + + @Override + public void setExportExpandsKeywords(boolean expand) { + myClient.setExportExpandsKeywords(expand); + } + + @Override + public void setEventHandler(ISVNEventHandler dispatcher) { + myDispatcher = dispatcher; + myClient.setEventHandler(dispatcher); + } + + public ISVNEventHandler getEventHandler() { + return myDispatcher; + } +} diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn17/portable/SvnUpdateClientI.java b/plugins/svn4idea/src/org/jetbrains/idea/svn17/portable/SvnUpdateClientI.java new file mode 100644 index 000000000000..434f657d61b9 --- /dev/null +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn17/portable/SvnUpdateClientI.java @@ -0,0 +1,75 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.idea.svn17.portable; + +import org.tmatesoft.svn.core.SVNDepth; +import org.tmatesoft.svn.core.SVNException; +import org.tmatesoft.svn.core.SVNURL; +import org.tmatesoft.svn.core.wc.ISVNEventHandler; +import org.tmatesoft.svn.core.wc.SVNRevision; + +import java.io.File; + +/** + * Created with IntelliJ IDEA. + * User: Irina.Chernushina + * Date: 2/1/12 + * Time: 11:59 AM + */ +public interface SvnUpdateClientI { + long doUpdate(File file, SVNRevision revision, boolean recursive) throws SVNException; + + long doUpdate(File file, SVNRevision revision, boolean recursive, boolean force) throws SVNException; + + long[] doUpdate(File[] paths, SVNRevision revision, SVNDepth depth, boolean allowUnversionedObstructions, boolean depthIsSticky) throws SVNException; + + long[] doUpdate(File[] paths, SVNRevision revision, SVNDepth depth, boolean allowUnversionedObstructions, boolean depthIsSticky, boolean makeParents) throws SVNException; + + long doUpdate(File path, SVNRevision revision, SVNDepth depth, boolean allowUnversionedObstructions, boolean depthIsSticky) throws SVNException; + + void setUpdateLocksOnDemand(boolean locksOnDemand); + + long doSwitch(File file, SVNURL url, SVNRevision revision, boolean recursive) throws SVNException; + + long doSwitch(File file, SVNURL url, SVNRevision pegRevision, SVNRevision revision, boolean recursive) throws SVNException; + + long doSwitch(File file, SVNURL url, SVNRevision pegRevision, SVNRevision revision, boolean recursive, boolean force) throws SVNException; + + long doSwitch(File path, SVNURL url, SVNRevision pegRevision, SVNRevision revision, SVNDepth depth, boolean allowUnversionedObstructions, boolean depthIsSticky) throws SVNException; + + long doSwitch(File path, SVNURL url, SVNRevision pegRevision, SVNRevision revision, SVNDepth depth, boolean allowUnversionedObstructions, boolean depthIsSticky, boolean ignoreAncestry) throws SVNException; + + long doCheckout(SVNURL url, File dstPath, SVNRevision pegRevision, SVNRevision revision, boolean recursive) throws SVNException; + + long doCheckout(SVNURL url, File dstPath, SVNRevision pegRevision, SVNRevision revision, boolean recursive, boolean force) throws SVNException; + + long doCheckout(SVNURL url, File dstPath, SVNRevision pegRevision, SVNRevision revision, SVNDepth depth, boolean allowUnversionedObstructions) throws SVNException; + + long doExport(SVNURL url, File dstPath, SVNRevision pegRevision, SVNRevision revision, String eolStyle, boolean force, boolean recursive) throws SVNException; + + long doExport(SVNURL url, File dstPath, SVNRevision pegRevision, SVNRevision revision, String eolStyle, boolean overwrite, SVNDepth depth) throws SVNException; + + long doExport(File srcPath, File dstPath, SVNRevision pegRevision, SVNRevision revision, String eolStyle, boolean force, boolean recursive) throws SVNException; + + long doExport(File srcPath, File dstPath, SVNRevision pegRevision, SVNRevision revision, String eolStyle, boolean overwrite, SVNDepth depth) throws SVNException; + + void doRelocate(File dst, SVNURL oldURL, SVNURL newURL, boolean recursive) throws SVNException; + + void doCanonicalizeURLs(File dst, boolean omitDefaultPort, boolean recursive) throws SVNException; + + void setExportExpandsKeywords(boolean expand); + void setEventHandler(ISVNEventHandler dispatcher); +} diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn17/update/SvnUpdateEnvironment17.java b/plugins/svn4idea/src/org/jetbrains/idea/svn17/update/SvnUpdateEnvironment17.java index 1f9155c6719c..db44c0a19478 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn17/update/SvnUpdateEnvironment17.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn17/update/SvnUpdateEnvironment17.java @@ -23,10 +23,10 @@ import com.intellij.openapi.vcs.FilePath; import com.intellij.openapi.vcs.VcsException; import com.intellij.openapi.vcs.update.UpdatedFiles; import org.jetbrains.annotations.Nullable; -import org.jetbrains.idea.svn17.SvnBundle; -import org.jetbrains.idea.svn17.SvnConfiguration17; -import org.jetbrains.idea.svn17.SvnRevisionNumber; -import org.jetbrains.idea.svn17.SvnVcs17; +import org.jetbrains.idea.svn17.*; +import org.jetbrains.idea.svn17.commandLine.SvnCommandLineUpdateClient; +import org.jetbrains.idea.svn17.portable.SvnSvnkitUpdateClient; +import org.jetbrains.idea.svn17.portable.SvnUpdateClientI; import org.tmatesoft.svn.core.SVNException; import org.tmatesoft.svn.core.SVNURL; import org.tmatesoft.svn.core.io.SVNRepository; @@ -82,25 +82,16 @@ public class SvnUpdateEnvironment17 extends AbstractSvnUpdateIntegrateEnvironmen final SvnConfiguration17 configuration = SvnConfiguration17.getInstance(myVcs.getProject()); final UpdateRootInfo rootInfo = configuration.getUpdateRootInfo(root, myVcs); - final SVNUpdateClient updateClient = myVcs.createUpdateClient(); - updateClient.setEventHandler(myHandler); - updateClient.setUpdateLocksOnDemand(configuration.UPDATE_LOCK_ON_DEMAND); - if (rootInfo != null) { - final SVNURL url = rootInfo.getUrl(); - if (url != null && url.equals(getSourceUrl(myVcs, root))) { - if (rootInfo.isUpdateToRevision()) { - rev = updateClient.doUpdate(root, rootInfo.getRevision(), configuration.UPDATE_DEPTH, configuration.FORCE_UPDATE, false); - } else { - rev = updateClient.doUpdate(root, SVNRevision.HEAD, configuration.UPDATE_DEPTH, configuration.FORCE_UPDATE, false); - } + final SVNURL sourceUrl = getSourceUrl(myVcs, root); + final boolean isSwitch = rootInfo != null && rootInfo.getUrl() != null && ! rootInfo.getUrl().equals(sourceUrl); + final SVNRevision updateTo = rootInfo != null && rootInfo.isUpdateToRevision() ? rootInfo.getRevision() : SVNRevision.HEAD; - } else if (url != null) { - rev = updateClient.doSwitch(root, url, SVNRevision.UNDEFINED, rootInfo.getRevision(), configuration.UPDATE_DEPTH, configuration.FORCE_UPDATE, false); - } else { - rev = updateClient.doUpdate(root, SVNRevision.HEAD, configuration.UPDATE_DEPTH, configuration.FORCE_UPDATE, false); - } + if (isSwitch) { + final SvnUpdateClientI updateClient = createUpdateClient(configuration, root, true, sourceUrl); + rev = updateClient.doSwitch(root, rootInfo.getUrl(), SVNRevision.UNDEFINED, rootInfo.getRevision(), configuration.UPDATE_DEPTH, configuration.FORCE_UPDATE, false); } else { - rev = updateClient.doUpdate(root, SVNRevision.HEAD, configuration.UPDATE_DEPTH, configuration.FORCE_UPDATE, false); + final SvnUpdateClientI updateClient = createUpdateClient(configuration, root, false, sourceUrl); + rev = updateClient.doUpdate(root, updateTo, configuration.UPDATE_DEPTH, configuration.FORCE_UPDATE, false); } myPostUpdateFiles.setRevisions(root.getAbsolutePath(), myVcs, new SvnRevisionNumber(SVNRevision.create(rev))); @@ -108,6 +99,20 @@ public class SvnUpdateEnvironment17 extends AbstractSvnUpdateIntegrateEnvironmen return rev; } + private SvnUpdateClientI createUpdateClient(SvnConfiguration17 configuration, File root, boolean isSwitch, SVNURL sourceUrl) { + final SvnUpdateClientI updateClient; + // do not do from command line for switch now + if (! isSwitch && SvnConfiguration17.UseAcceleration.commandLine.equals(configuration.myUseAcceleration) && + Svn17Detector.is17(myVcs.getProject(), root) && SvnAuthenticationManager.HTTP.equals(sourceUrl.getProtocol())) { + updateClient = new SvnCommandLineUpdateClient(myVcs.getProject(), null); + } else { + updateClient = new SvnSvnkitUpdateClient(myVcs.createUpdateClient()); + } + updateClient.setEventHandler(myHandler); + updateClient.setUpdateLocksOnDemand(configuration.UPDATE_LOCK_ON_DEMAND); + return updateClient; + } + protected boolean isMerge() { return false; } diff --git a/plugins/svn4idea/testSource/org/jetbrains/idea/svn17/SvnAuthenticationTest.java b/plugins/svn4idea/testSource/org/jetbrains/idea/svn17/SvnAuthenticationTest.java index 86bc1b019921..3e4d91df96bf 100644 --- a/plugins/svn4idea/testSource/org/jetbrains/idea/svn17/SvnAuthenticationTest.java +++ b/plugins/svn4idea/testSource/org/jetbrains/idea/svn17/SvnAuthenticationTest.java @@ -1054,6 +1054,10 @@ public class SvnAuthenticationTest extends PlatformTestCase { return myCnt; } + @Override + public void acknowledge(boolean accepted, String kind, String realm, SVNErrorMessage message, SVNAuthentication authentication) { + } + @Override public void saveAttemptStarted(ProviderType type, SVNURL url, String realm, String kind) { mySaved = false; @@ -1119,6 +1123,10 @@ public class SvnAuthenticationTest extends PlatformTestCase { mySaved = new HashSet>(); } + @Override + public void acknowledge(boolean accepted, String kind, String realm, SVNErrorMessage message, SVNAuthentication authentication) { + } + public void reset() { mySaved.clear(); myClientRequested.clear(); From 7817391f730544f5ee3dbb0cc9a23d932293533f Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 7 Feb 2012 10:20:35 +0100 Subject: [PATCH 08/12] walk only the necessary files when searching for string in a custom scope --- .../com/intellij/find/impl/FindInProjectUtil.java | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/find/impl/FindInProjectUtil.java b/platform/lang-impl/src/com/intellij/find/impl/FindInProjectUtil.java index 14d7b9b9c5e5..1e5bdc1ddfd6 100644 --- a/platform/lang-impl/src/com/intellij/find/impl/FindInProjectUtil.java +++ b/platform/lang-impl/src/com/intellij/find/impl/FindInProjectUtil.java @@ -386,7 +386,7 @@ public class FindInProjectUtil { public boolean processFile(VirtualFile virtualFile) { if (!virtualFile.isDirectory() && (fileMaskRegExp == null || fileMaskRegExp.matcher(virtualFile.getName()).matches()) && - (customScope == null || customScope.contains(virtualFile))) { + customScope.contains(virtualFile)) { final PsiFile psiFile = psiManager.findFile(virtualFile); if (psiFile != null && !filesForFastWordSearch.contains(psiFile)) { myFiles.add(psiFile); @@ -403,10 +403,10 @@ public class FindInProjectUtil { if (psiDirectory == null) { boolean success = fileIndex.iterateContent(iterator); - if (success && customScope instanceof GlobalSearchScope && ((GlobalSearchScope)customScope).isSearchInLibraries()) { + if (success && customScope.isSearchInLibraries()) { OrderEnumerator enumerator = module == null ? OrderEnumerator.orderEntries(project) : OrderEnumerator.orderEntries(module); final VirtualFile[] librarySources = enumerator.withoutModuleSourceEntries().withoutDepModules().getSourceRoots(); - iterateAll(librarySources, (GlobalSearchScope)customScope, iterator); + iterateAll(librarySources, customScope, iterator); } } else { @@ -440,11 +440,14 @@ public class FindInProjectUtil { return true; } - @Nullable + @NotNull private static GlobalSearchScope toGlobal(Project project, @Nullable SearchScope scope) { - if (scope instanceof GlobalSearchScope || scope == null) { + if (scope instanceof GlobalSearchScope) { return (GlobalSearchScope)scope; } + if (scope == null) { + return GlobalSearchScope.projectScope(project); + } Set files = new HashSet(); for (PsiElement element : ((LocalSearchScope)scope).getScope()) { PsiFile file = element.getContainingFile(); @@ -472,7 +475,7 @@ public class FindInProjectUtil { ? moduleContentScope(module) : customScope instanceof GlobalSearchScope ? (GlobalSearchScope)customScope - : GlobalSearchScope.projectScope(project); + : toGlobal(project, customScope); Set keys = new THashSet(30); Set resultFiles = new THashSet(); From 622a36b4dade6e397a5c0943c767517a99e3b888 Mon Sep 17 00:00:00 2001 From: "Rustam.Vishnyakov" Date: Tue, 7 Feb 2012 13:21:15 +0400 Subject: [PATCH 09/12] Groovy custom folding regions --- .../lang/folding/GroovyFoldingBuilder.java | 40 +++++++++++++------ 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/folding/GroovyFoldingBuilder.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/folding/GroovyFoldingBuilder.java index ef7a8c26f90f..574c5c9d4e1b 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/folding/GroovyFoldingBuilder.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/folding/GroovyFoldingBuilder.java @@ -18,7 +18,7 @@ package org.jetbrains.plugins.groovy.lang.folding; import com.intellij.codeInsight.folding.JavaCodeFoldingSettings; import com.intellij.lang.ASTNode; -import com.intellij.lang.folding.FoldingBuilder; +import com.intellij.lang.folding.CustomFoldingBuilder; import com.intellij.lang.folding.FoldingDescriptor; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.FoldingGroup; @@ -33,6 +33,7 @@ import com.intellij.psi.tree.IElementType; import com.intellij.util.containers.hash.HashSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; import org.jetbrains.plugins.groovy.lang.lexer.TokenSets; import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes; import org.jetbrains.plugins.groovy.lang.psi.GroovyFile; @@ -43,23 +44,23 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefini import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.imports.GrImportStatement; import org.jetbrains.plugins.groovy.lang.psi.util.GrStringUtil; -import java.util.ArrayList; import java.util.List; import java.util.Set; /** * @author ilyas */ -public class GroovyFoldingBuilder implements FoldingBuilder, GroovyElementTypes, DumbAware { +public class GroovyFoldingBuilder extends CustomFoldingBuilder implements GroovyElementTypes, DumbAware { - @NotNull - public FoldingDescriptor[] buildFoldRegions(@NotNull ASTNode node, @NotNull Document document) { - List descriptors = new ArrayList(); - appendDescriptors(node.getPsi(), descriptors, new HashSet()); - return descriptors.toArray(new FoldingDescriptor[descriptors.size()]); + @Override + protected void buildLanguageFoldRegions(@NotNull List descriptors, + @NotNull PsiElement root, + @NotNull Document document, + boolean quick) { + appendDescriptors(root, descriptors, new HashSet()); } - private static void appendDescriptors(PsiElement element, List descriptors, Set usedComments) { + private void appendDescriptors(PsiElement element, List descriptors, Set usedComments) { ASTNode node = element.getNode(); if (node == null) return; IElementType type = node.getElementType(); @@ -70,13 +71,13 @@ public class GroovyFoldingBuilder implements FoldingBuilder, GroovyElementTypes, } } // comments - if ((type.equals(mML_COMMENT) || type.equals(GROOVY_DOC_COMMENT)) && + if (((type.equals(mML_COMMENT) && !isCustomRegionStart(node)) || type.equals(GROOVY_DOC_COMMENT)) && isMultiline(element) && isWellEndedComment(element)) { descriptors.add(new FoldingDescriptor(node, node.getTextRange())); } - if (type.equals(mSL_COMMENT) && !usedComments.contains(element)) { + if (type.equals(mSL_COMMENT) && !isCustomRegionStart(node) && !usedComments.contains(element)) { usedComments.add(element); PsiElement end = null; for (PsiElement current = element.getNextSibling(); current != null; current = current.getNextSibling()) { @@ -214,7 +215,8 @@ public class GroovyFoldingBuilder implements FoldingBuilder, GroovyElementTypes, return text.contains("\n") || text.contains("\r") || text.contains("\r\n"); } - public String getPlaceholderText(@NotNull ASTNode node) { + @Override + protected String getLanguagePlaceholderText(@NotNull ASTNode node, @NotNull TextRange range) { final IElementType elemType = node.getElementType(); if (BLOCK_SET.contains(elemType) || elemType == CLOSABLE_BLOCK) { return "{...}"; @@ -236,7 +238,8 @@ public class GroovyFoldingBuilder implements FoldingBuilder, GroovyElementTypes, return null; } - public boolean isCollapsedByDefault(@NotNull ASTNode node) { + @Override + protected boolean isRegionCollapsedByDefault(@NotNull ASTNode node) { final JavaCodeFoldingSettings settings = JavaCodeFoldingSettings.getInstance(); if ( node.getElementType() == IMPORT_STATEMENT ){ return settings.isCollapseImports(); @@ -280,4 +283,15 @@ public class GroovyFoldingBuilder implements FoldingBuilder, GroovyElementTypes, isMultiline(node.getPsi()) && GrStringUtil.isWellEndedString(node.getPsi()); } + + @Override + protected boolean isCustomFoldingCandidate(ASTNode node) { + return node.getElementType() == GroovyTokenTypes.mSL_COMMENT; + } + + @Override + protected boolean isCustomFoldingRoot(ASTNode node) { + IElementType nodeType = node.getElementType(); + return nodeType == GroovyElementTypes.CLASS_DEFINITION || nodeType == GroovyElementTypes.OPEN_BLOCK; + } } From df89e0c0f5096628dbc4caf41690608fa36473a4 Mon Sep 17 00:00:00 2001 From: nik Date: Tue, 7 Feb 2012 13:50:49 +0400 Subject: [PATCH 10/12] added extension to contribute to compile server classpath; jps-javaee plugin moved to JavaEE plugin --- .idea/modules.xml | 1 - .../compiler/CompileServerManager.java | 3 + .../compiler/server/CompileServerPlugin.java | 37 ++++++++++ .../impl/CompileServerClasspathManager.java | 74 +++++++++++++++++++ .../jps/server/ClasspathBootstrap.java | 6 +- jps/plugins/gwt/jps-gwt.iml | 1 - jps/plugins/javaee/jps-javaee.iml | 14 ---- ...ins.jps.artifacts.LayoutElementTypeService | 2 - .../org.jetbrains.jps.idea.FacetTypeService | 3 - .../jetbrains/jps/javaee/EjbFacetType.groovy | 10 --- .../jps/javaee/JavaeeAppFacetType.groovy | 10 --- .../jetbrains/jps/javaee/JavaeeFacet.groovy | 11 --- .../JavaeeFacetClassesElementType.groovy | 24 ------ .../javaee/JavaeeFacetResourcesElement.groovy | 32 -------- .../JavaeeFacetResourcesElementType.groovy | 22 ------ .../jps/javaee/JavaeeFacetTypeBase.groovy | 40 ---------- .../jetbrains/jps/javaee/WebFacetType.groovy | 18 ----- resources/src/idea/RichPlatformPlugin.xml | 1 + 18 files changed, 116 insertions(+), 193 deletions(-) create mode 100644 java/compiler/impl/src/com/intellij/compiler/server/CompileServerPlugin.java create mode 100644 java/compiler/impl/src/com/intellij/compiler/server/impl/CompileServerClasspathManager.java delete mode 100644 jps/plugins/javaee/jps-javaee.iml delete mode 100644 jps/plugins/javaee/src/META-INF/services/org.jetbrains.jps.artifacts.LayoutElementTypeService delete mode 100644 jps/plugins/javaee/src/META-INF/services/org.jetbrains.jps.idea.FacetTypeService delete mode 100644 jps/plugins/javaee/src/org/jetbrains/jps/javaee/EjbFacetType.groovy delete mode 100644 jps/plugins/javaee/src/org/jetbrains/jps/javaee/JavaeeAppFacetType.groovy delete mode 100644 jps/plugins/javaee/src/org/jetbrains/jps/javaee/JavaeeFacet.groovy delete mode 100644 jps/plugins/javaee/src/org/jetbrains/jps/javaee/JavaeeFacetClassesElementType.groovy delete mode 100644 jps/plugins/javaee/src/org/jetbrains/jps/javaee/JavaeeFacetResourcesElement.groovy delete mode 100644 jps/plugins/javaee/src/org/jetbrains/jps/javaee/JavaeeFacetResourcesElementType.groovy delete mode 100644 jps/plugins/javaee/src/org/jetbrains/jps/javaee/JavaeeFacetTypeBase.groovy delete mode 100644 jps/plugins/javaee/src/org/jetbrains/jps/javaee/WebFacetType.groovy diff --git a/.idea/modules.xml b/.idea/modules.xml index c95d45fbe908..9e15d0263725 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -60,7 +60,6 @@ - diff --git a/java/compiler/impl/src/com/intellij/compiler/CompileServerManager.java b/java/compiler/impl/src/com/intellij/compiler/CompileServerManager.java index 3681465f1778..ffbcdd9586d9 100644 --- a/java/compiler/impl/src/com/intellij/compiler/CompileServerManager.java +++ b/java/compiler/impl/src/com/intellij/compiler/CompileServerManager.java @@ -17,6 +17,7 @@ package com.intellij.compiler; import com.intellij.ProjectTopics; import com.intellij.application.options.PathMacrosImpl; +import com.intellij.compiler.server.impl.CompileServerClasspathManager; import com.intellij.execution.ExecutionException; import com.intellij.execution.configurations.GeneralCommandLine; import com.intellij.execution.process.OSProcessHandler; @@ -99,6 +100,7 @@ public class CompileServerManager implements ApplicationComponent{ private final ProjectManager myProjectManager; private static final int MAKE_TRIGGER_DELAY = 5 * 1000 /*5 seconds*/; private final Map myAutomakeFutures = new HashMap(); + private final CompileServerClasspathManager myClasspathManager = new CompileServerClasspathManager(); public CompileServerManager(final ProjectManager projectManager) { myProjectManager = projectManager; @@ -595,6 +597,7 @@ public class CompileServerManager implements ApplicationComponent{ cmdLine.addParameter("-classpath"); final List cp = ClasspathBootstrap.getCompileServerApplicationClasspath(); + cp.addAll(myClasspathManager.getCompileServerPluginsClasspath()); cmdLine.addParameter(classpathToString(cp)); diff --git a/java/compiler/impl/src/com/intellij/compiler/server/CompileServerPlugin.java b/java/compiler/impl/src/com/intellij/compiler/server/CompileServerPlugin.java new file mode 100644 index 000000000000..8a1775d27ab9 --- /dev/null +++ b/java/compiler/impl/src/com/intellij/compiler/server/CompileServerPlugin.java @@ -0,0 +1,37 @@ +package com.intellij.compiler.server; + +import com.intellij.openapi.extensions.ExtensionPointName; +import com.intellij.openapi.extensions.PluginAware; +import com.intellij.openapi.extensions.PluginDescriptor; +import com.intellij.util.xmlb.annotations.Attribute; + +/** + * @author nik + */ +public class CompileServerPlugin implements PluginAware { + public static final ExtensionPointName EP_NAME = ExtensionPointName.create("com.intellij.compileServer.plugin"); + private PluginDescriptor myPluginDescriptor; + private String myJarPath; + + /** + * Specifies path to a jar file which should be added to the classpath of the compile server. The path is relative to the plugin 'lib' directory. + * In the development node the name of this file without extension is treated as a module name and the output directory of the module is added to the classpath. + */ + @Attribute("jar-path") + public String getJarPath() { + return myJarPath; + } + + public void setJarPath(String jarPath) { + myJarPath = jarPath; + } + + @Override + public final void setPluginDescriptor(PluginDescriptor pluginDescriptor) { + myPluginDescriptor = pluginDescriptor; + } + + public PluginDescriptor getPluginDescriptor() { + return myPluginDescriptor; + } +} diff --git a/java/compiler/impl/src/com/intellij/compiler/server/impl/CompileServerClasspathManager.java b/java/compiler/impl/src/com/intellij/compiler/server/impl/CompileServerClasspathManager.java new file mode 100644 index 000000000000..f1bd0abfc030 --- /dev/null +++ b/java/compiler/impl/src/com/intellij/compiler/server/impl/CompileServerClasspathManager.java @@ -0,0 +1,74 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.compiler.server.impl; + +import com.intellij.compiler.server.CompileServerPlugin; +import com.intellij.ide.plugins.IdeaPluginDescriptor; +import com.intellij.ide.plugins.PluginManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.extensions.PluginId; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.util.PathUtil; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +/** + * @author nik + */ +public class CompileServerClasspathManager { + private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.server.impl.CompileServerClasspathManager"); + private List myCompileServerPluginsClasspath; + + public List getCompileServerPluginsClasspath() { + if (myCompileServerPluginsClasspath == null) { + myCompileServerPluginsClasspath = computeCompileServerPluginsClasspath(); + } + return myCompileServerPluginsClasspath; + } + + private static List computeCompileServerPluginsClasspath() { + final List classpath = new ArrayList(); + for (CompileServerPlugin serverPlugin : CompileServerPlugin.EP_NAME.getExtensions()) { + final PluginId pluginId = serverPlugin.getPluginDescriptor().getPluginId(); + final IdeaPluginDescriptor plugin = PluginManager.getPlugin(pluginId); + LOG.assertTrue(plugin != null, pluginId); + final File baseFile = plugin.getPath(); + if (baseFile.isFile()) { + classpath.add(baseFile); + } + else if (baseFile.isDirectory()) { + final String relativePath = serverPlugin.getJarPath(); + File jarFile = new File(new File(baseFile, "lib"), relativePath); + if (jarFile.exists()) { + classpath.add(jarFile); + } + else { + //development mode: add directory out/classes/production/ to classpath, assuming that jar-name is equal to module name + final String moduleName = FileUtil.getNameWithoutExtension(PathUtil.getFileName(relativePath)); + final File dir = new File(baseFile.getParentFile(), moduleName); + if (!dir.exists()) { + LOG.warn("Cannot add plugin " + pluginId + " to compile server classpath: " + jarFile.getAbsolutePath() + " and " + + dir.getAbsolutePath() + " don't exist"); + } + classpath.add(dir); + } + } + } + return classpath; + } +} diff --git a/jps/jps-builders/src/org/jetbrains/jps/server/ClasspathBootstrap.java b/jps/jps-builders/src/org/jetbrains/jps/server/ClasspathBootstrap.java index d95a41544503..f520c8128d28 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/server/ClasspathBootstrap.java +++ b/jps/jps-builders/src/org/jetbrains/jps/server/ClasspathBootstrap.java @@ -82,11 +82,7 @@ public class ClasspathBootstrap { cp.add(getResourcePath(FileMonitor.class)); // jna-utils.jar cp.add(getResourcePath(ClassWriter.class)); // asm cp.add(getResourcePath(org.objectweb.asm.commons.EmptyVisitor.class)); // asm-commons - final File jpsModel = getResourcePath(MacroExpander.class); - cp.add(jpsModel); // jps-model - cp.add(new File(jpsModel.getParentFile(), "jps-javaee")); - cp.add(new File(jpsModel.getParentFile(), "jps-gwt")); - cp.add(new File(jpsModel.getParentFile(), "jps-jpa")); + cp.add(getResourcePath(MacroExpander.class)); // jps-model cp.add(getResourcePath(AlienFormFileException.class)); // forms-compiler cp.add(getResourcePath(GroovyException.class)); // groovy cp.add(getResourcePath(org.jdom.input.SAXBuilder.class)); // jdom diff --git a/jps/plugins/gwt/jps-gwt.iml b/jps/plugins/gwt/jps-gwt.iml index 621daa2f0ea8..704ab03cf56b 100644 --- a/jps/plugins/gwt/jps-gwt.iml +++ b/jps/plugins/gwt/jps-gwt.iml @@ -10,7 +10,6 @@ - diff --git a/jps/plugins/javaee/jps-javaee.iml b/jps/plugins/javaee/jps-javaee.iml deleted file mode 100644 index d67aceeddab5..000000000000 --- a/jps/plugins/javaee/jps-javaee.iml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/jps/plugins/javaee/src/META-INF/services/org.jetbrains.jps.artifacts.LayoutElementTypeService b/jps/plugins/javaee/src/META-INF/services/org.jetbrains.jps.artifacts.LayoutElementTypeService deleted file mode 100644 index 45b2dc247bd9..000000000000 --- a/jps/plugins/javaee/src/META-INF/services/org.jetbrains.jps.artifacts.LayoutElementTypeService +++ /dev/null @@ -1,2 +0,0 @@ -org.jetbrains.jps.javaee.JavaeeFacetResourcesElementType -org.jetbrains.jps.javaee.JavaeeFacetClassesElementType \ No newline at end of file diff --git a/jps/plugins/javaee/src/META-INF/services/org.jetbrains.jps.idea.FacetTypeService b/jps/plugins/javaee/src/META-INF/services/org.jetbrains.jps.idea.FacetTypeService deleted file mode 100644 index 4b60ca861db8..000000000000 --- a/jps/plugins/javaee/src/META-INF/services/org.jetbrains.jps.idea.FacetTypeService +++ /dev/null @@ -1,3 +0,0 @@ -org.jetbrains.jps.javaee.WebFacetType -org.jetbrains.jps.javaee.EjbFacetType -org.jetbrains.jps.javaee.JavaeeAppFacetType \ No newline at end of file diff --git a/jps/plugins/javaee/src/org/jetbrains/jps/javaee/EjbFacetType.groovy b/jps/plugins/javaee/src/org/jetbrains/jps/javaee/EjbFacetType.groovy deleted file mode 100644 index 96fa9b90232e..000000000000 --- a/jps/plugins/javaee/src/org/jetbrains/jps/javaee/EjbFacetType.groovy +++ /dev/null @@ -1,10 +0,0 @@ -package org.jetbrains.jps.javaee - -/** - * @author nik - */ -class EjbFacetType extends JavaeeFacetTypeBase { - EjbFacetType() { - super("ejb") - } -} diff --git a/jps/plugins/javaee/src/org/jetbrains/jps/javaee/JavaeeAppFacetType.groovy b/jps/plugins/javaee/src/org/jetbrains/jps/javaee/JavaeeAppFacetType.groovy deleted file mode 100644 index 20dff7d7e44d..000000000000 --- a/jps/plugins/javaee/src/org/jetbrains/jps/javaee/JavaeeAppFacetType.groovy +++ /dev/null @@ -1,10 +0,0 @@ -package org.jetbrains.jps.javaee - -/** - * @author nik - */ -public class JavaeeAppFacetType extends JavaeeFacetTypeBase { - JavaeeAppFacetType() { - super("javaeeApplication") - } -} diff --git a/jps/plugins/javaee/src/org/jetbrains/jps/javaee/JavaeeFacet.groovy b/jps/plugins/javaee/src/org/jetbrains/jps/javaee/JavaeeFacet.groovy deleted file mode 100644 index 844d2108deda..000000000000 --- a/jps/plugins/javaee/src/org/jetbrains/jps/javaee/JavaeeFacet.groovy +++ /dev/null @@ -1,11 +0,0 @@ -package org.jetbrains.jps.javaee - -import org.jetbrains.jps.idea.Facet - -/** - * @author nik - */ -class JavaeeFacet extends Facet { - final List> descriptors = [] - final List> webRoots = [] -} diff --git a/jps/plugins/javaee/src/org/jetbrains/jps/javaee/JavaeeFacetClassesElementType.groovy b/jps/plugins/javaee/src/org/jetbrains/jps/javaee/JavaeeFacetClassesElementType.groovy deleted file mode 100644 index c63ff6f18e4d..000000000000 --- a/jps/plugins/javaee/src/org/jetbrains/jps/javaee/JavaeeFacetClassesElementType.groovy +++ /dev/null @@ -1,24 +0,0 @@ -package org.jetbrains.jps.javaee; - - -import org.jetbrains.jps.MacroExpander -import org.jetbrains.jps.Project -import org.jetbrains.jps.artifacts.LayoutElement -import org.jetbrains.jps.artifacts.LayoutElementTypeService -import org.jetbrains.jps.artifacts.ModuleOutputElement -import org.jetbrains.jps.idea.ProjectLoadingErrorReporter - -/** - * @author nik - */ -class JavaeeFacetClassesElementType extends LayoutElementTypeService { - JavaeeFacetClassesElementType() { - super("javaee-facet-classes") - } - - @Override - LayoutElement createElement(Project project, Node tag, MacroExpander macroExpander, ProjectLoadingErrorReporter errorReporter) { - String facetId = tag."@facet" - return new ModuleOutputElement(moduleName: facetId.substring(0, facetId.indexOf('/'))) - } -} diff --git a/jps/plugins/javaee/src/org/jetbrains/jps/javaee/JavaeeFacetResourcesElement.groovy b/jps/plugins/javaee/src/org/jetbrains/jps/javaee/JavaeeFacetResourcesElement.groovy deleted file mode 100644 index 7298d28c8ac1..000000000000 --- a/jps/plugins/javaee/src/org/jetbrains/jps/javaee/JavaeeFacetResourcesElement.groovy +++ /dev/null @@ -1,32 +0,0 @@ -package org.jetbrains.jps.javaee - -import org.jetbrains.jps.Project -import org.jetbrains.jps.idea.Facet -import org.jetbrains.jps.idea.IdeaProjectLoadingUtil -import org.jetbrains.jps.idea.ProjectLoadingErrorReporter -import org.jetbrains.jps.artifacts.* - -/** - * @author nik - */ -class JavaeeFacetResourcesElement extends ComplexLayoutElement { - String facetId - ProjectLoadingErrorReporter errorReporter - - List getSubstitution(Project project) { - Facet facet = IdeaProjectLoadingUtil.findFacetByIdWithAssertion(project, facetId, errorReporter) - - if (!(facet instanceof JavaeeFacet)) { - errorReporter.error("$facetId facet is not JavaEE facet") - } - - List result = [] - facet.descriptors.each {Map descriptor -> - result << LayoutElementFactory.createParentDirectories(descriptor.outputPath, new FileCopyElement(filePath: descriptor.path)) - } - facet.webRoots.each {Map webRoot -> - result << LayoutElementFactory.createParentDirectories(webRoot.outputPath, new DirectoryCopyElement(dirPath: webRoot.path)) - } - return result - } -} diff --git a/jps/plugins/javaee/src/org/jetbrains/jps/javaee/JavaeeFacetResourcesElementType.groovy b/jps/plugins/javaee/src/org/jetbrains/jps/javaee/JavaeeFacetResourcesElementType.groovy deleted file mode 100644 index 527c536a21f2..000000000000 --- a/jps/plugins/javaee/src/org/jetbrains/jps/javaee/JavaeeFacetResourcesElementType.groovy +++ /dev/null @@ -1,22 +0,0 @@ -package org.jetbrains.jps.javaee - -import org.jetbrains.jps.MacroExpander -import org.jetbrains.jps.Project -import org.jetbrains.jps.artifacts.LayoutElement -import org.jetbrains.jps.artifacts.LayoutElementTypeService -import org.jetbrains.jps.idea.ProjectLoadingErrorReporter - -/** - * @author nik - */ -class JavaeeFacetResourcesElementType extends LayoutElementTypeService { - JavaeeFacetResourcesElementType() { - super("javaee-facet-resources") - } - - @Override - LayoutElement createElement(Project project, Node tag, MacroExpander macroExpander, ProjectLoadingErrorReporter errorReporter) { - return new JavaeeFacetResourcesElement(facetId: tag."@facet", errorReporter: errorReporter) - } - -} diff --git a/jps/plugins/javaee/src/org/jetbrains/jps/javaee/JavaeeFacetTypeBase.groovy b/jps/plugins/javaee/src/org/jetbrains/jps/javaee/JavaeeFacetTypeBase.groovy deleted file mode 100644 index 657a6ed2b9f7..000000000000 --- a/jps/plugins/javaee/src/org/jetbrains/jps/javaee/JavaeeFacetTypeBase.groovy +++ /dev/null @@ -1,40 +0,0 @@ -package org.jetbrains.jps.javaee - -import org.jetbrains.jps.MacroExpander -import org.jetbrains.jps.Module -import org.jetbrains.jps.idea.Facet -import org.jetbrains.jps.idea.FacetTypeService - -import org.jetbrains.jps.idea.IdeaProjectLoadingUtil - -/** - * @author nik - */ -public abstract class JavaeeFacetTypeBase extends FacetTypeService { - protected JavaeeFacetTypeBase(String typeId) { - super(typeId) - } - - protected String getDescriptorOutputPath(String descriptorId) { - return "META-INF" - } - - @Override - public Facet createFacet(Module module, String name, Node facetConfiguration, MacroExpander macroExpander) { - def facet = new JavaeeFacet(name: name) - facetConfiguration?.descriptors?.deploymentDescriptor?.each {Node tag -> - def outputPath = getDescriptorOutputPath(tag."@name") - String path = urlToPath(tag."@url", macroExpander) - facet.descriptors << [path: path, outputPath: outputPath] - } - facetConfiguration?.webroots?.root?.each {Node tag -> - String path = urlToPath(tag."@url", macroExpander) - facet.webRoots << [path: path, outputPath: tag."@relative"] - } - return facet - } - - def urlToPath(String url, MacroExpander macroExpander) { - return macroExpander.expandMacros(IdeaProjectLoadingUtil.pathFromUrl(url)) - } -} diff --git a/jps/plugins/javaee/src/org/jetbrains/jps/javaee/WebFacetType.groovy b/jps/plugins/javaee/src/org/jetbrains/jps/javaee/WebFacetType.groovy deleted file mode 100644 index d6e7f972eb5a..000000000000 --- a/jps/plugins/javaee/src/org/jetbrains/jps/javaee/WebFacetType.groovy +++ /dev/null @@ -1,18 +0,0 @@ -package org.jetbrains.jps.javaee - -/** - * @author nik - */ -public class WebFacetType extends JavaeeFacetTypeBase { - public WebFacetType() { - super("web"); - } - - @Override - protected String getDescriptorOutputPath(String descriptorId) { - if (descriptorId == "context.xml") return "META-INF" - return "WEB-INF" - } - - -} diff --git a/resources/src/idea/RichPlatformPlugin.xml b/resources/src/idea/RichPlatformPlugin.xml index 86586c9f7d83..2d976d81609a 100644 --- a/resources/src/idea/RichPlatformPlugin.xml +++ b/resources/src/idea/RichPlatformPlugin.xml @@ -72,6 +72,7 @@ + From f6320a11c01ef3f079818607e36813763ea3225c Mon Sep 17 00:00:00 2001 From: Maxim Shafirov Date: Tue, 7 Feb 2012 14:26:00 +0400 Subject: [PATCH 11/12] Allow "core" and "normal" environments to co-exist --- .../src/com/intellij/core/CoreEnvironment.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/platform/core-impl/src/com/intellij/core/CoreEnvironment.java b/platform/core-impl/src/com/intellij/core/CoreEnvironment.java index e754d84607d6..8957f43309fe 100644 --- a/platform/core-impl/src/com/intellij/core/CoreEnvironment.java +++ b/platform/core-impl/src/com/intellij/core/CoreEnvironment.java @@ -83,10 +83,12 @@ public class CoreEnvironment { myEncodingRegistry = new CoreEncodingRegistry(); myApplication = new MockApplication(parentDisposable); - ApplicationManager.setApplication(myApplication, - new StaticGetter(myFileTypeRegistry), - new StaticGetter(myEncodingRegistry), - parentDisposable); + if (ApplicationManager.getApplication() == null) { + ApplicationManager.setApplication(myApplication, + new StaticGetter(myFileTypeRegistry), + new StaticGetter(myEncodingRegistry), + parentDisposable); + } myLocalFileSystem = new CoreLocalFileSystem(); myJarFileSystem = new CoreJarFileSystem(); From 2fff1209da8ade1626a7445f4a98871448fbc878 Mon Sep 17 00:00:00 2001 From: nik Date: Tue, 7 Feb 2012 14:29:46 +0400 Subject: [PATCH 12/12] removed obsolete modules from artifacts --- .idea/artifacts/jps_plugins.xml | 1 - .idea/artifacts/jps_sources.xml | 1 - 2 files changed, 2 deletions(-) diff --git a/.idea/artifacts/jps_plugins.xml b/.idea/artifacts/jps_plugins.xml index fee03eee74f7..ef658048f36c 100644 --- a/.idea/artifacts/jps_plugins.xml +++ b/.idea/artifacts/jps_plugins.xml @@ -4,7 +4,6 @@ - diff --git a/.idea/artifacts/jps_sources.xml b/.idea/artifacts/jps_sources.xml index 2cd42352db97..2b7c6fd1e0b7 100644 --- a/.idea/artifacts/jps_sources.xml +++ b/.idea/artifacts/jps_sources.xml @@ -6,7 +6,6 @@ -