2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package org
.jetbrains
.idea
.svn
;
18 import com
.intellij
.notification
.NotificationType
;
19 import com
.intellij
.openapi
.application
.ApplicationManager
;
20 import com
.intellij
.openapi
.application
.ModalityState
;
21 import com
.intellij
.openapi
.diagnostic
.Logger
;
22 import com
.intellij
.openapi
.progress
.ProgressManager
;
23 import com
.intellij
.openapi
.project
.Project
;
24 import com
.intellij
.openapi
.ui
.MessageType
;
25 import com
.intellij
.openapi
.util
.Ref
;
26 import com
.intellij
.openapi
.util
.text
.StringUtil
;
27 import com
.intellij
.openapi
.vcs
.changes
.ui
.ChangesViewBalloonProblemNotifier
;
28 import com
.intellij
.openapi
.vcs
.impl
.GenericNotifierImpl
;
29 import org
.jetbrains
.annotations
.NotNull
;
30 import org
.jetbrains
.annotations
.Nullable
;
31 import org
.jetbrains
.idea
.svn
.dialogs
.SvnInteractiveAuthenticationProvider
;
32 import org
.tmatesoft
.svn
.core
.SVNAuthenticationException
;
33 import org
.tmatesoft
.svn
.core
.SVNCancelException
;
34 import org
.tmatesoft
.svn
.core
.SVNException
;
35 import org
.tmatesoft
.svn
.core
.SVNURL
;
36 import org
.tmatesoft
.svn
.core
.auth
.ISVNAuthenticationManager
;
37 import org
.tmatesoft
.svn
.core
.auth
.SVNAuthentication
;
38 import org
.tmatesoft
.svn
.core
.internal
.util
.SVNURLUtil
;
39 import org
.tmatesoft
.svn
.core
.wc
.SVNRevision
;
40 import org
.tmatesoft
.svn
.core
.wc
.SVNWCClient
;
42 import java
.util
.Collection
;
43 import java
.util
.LinkedList
;
44 import java
.util
.List
;
46 public class SvnAuthenticationNotifier
extends GenericNotifierImpl
<SvnAuthenticationNotifier
.AuthenticationRequest
, SVNURL
> {
47 private static final Logger LOG
= Logger
.getInstance("#org.jetbrains.idea.svn.SvnAuthenticationNotifier");
49 private static final String ourGroupId
= "Subversion";
50 private final SvnVcs myVcs
;
51 private final RootsToWorkingCopies myRootsToWorkingCopies
;
53 public SvnAuthenticationNotifier(final SvnVcs svnVcs
) {
54 super(svnVcs
.getProject(), ourGroupId
, "Not Logged To Subversion", NotificationType
.ERROR
);
56 myRootsToWorkingCopies
= myVcs
.getRootsToWorkingCopies();
60 protected boolean ask(final AuthenticationRequest obj
) {
61 final Ref
<Boolean
> resultRef
= new Ref
<Boolean
>();
62 final boolean done
= ProgressManager
.getInstance().runProcessWithProgressSynchronously(new Runnable() {
64 final boolean result
= interactiveValidation(obj
.myProject
, obj
.getUrl(), obj
.getRealm(), obj
.getKind());
65 log("ask result for: " + obj
.getUrl() + " is: " + result
);
66 resultRef
.set(result
);
68 onStateChangedToSuccess(obj
);
71 }, "Checking authorization state", true, myVcs
.getProject());
72 return done
&& Boolean
.TRUE
.equals(resultRef
.get());
75 private void onStateChangedToSuccess(final AuthenticationRequest obj
) {
76 /*final List<SVNURL> outdatedRequests = new LinkedList<SVNURL>();
77 final Collection<SVNURL> keys = getAllCurrentKeys();
78 for (SVNURL key : keys) {
79 final SVNURL commonURLAncestor = SVNURLUtil.getCommonURLAncestor(key, obj.getUrl());
80 if ((! StringUtil.isEmptyOrSpaces(commonURLAncestor.getHost())) && (! StringUtil.isEmptyOrSpaces(commonURLAncestor.getPath()))) {
81 final AuthenticationRequest currObj = getObj(key);
82 if ((currObj != null) && passiveValidation(myVcs.getProject(), key, true, currObj.getRealm(), currObj.getKind())) {
83 outdatedRequests.add(key);
87 log("on state changed ");
88 ApplicationManager.getApplication().invokeLater(new Runnable() {
90 for (SVNURL key : outdatedRequests) {
91 removeLazyNotificationByKey(key);
94 }, ModalityState.NON_MODAL); */
98 public void ensureNotify(AuthenticationRequest obj
) {
99 ChangesViewBalloonProblemNotifier
.showMe(myVcs
.getProject(), "You are not authenticated to '" + obj
.getRealm() + "'." +
100 "To login, see pending notifications.", MessageType
.ERROR
);
101 super.ensureNotify(obj
);
106 public SVNURL
getKey(final AuthenticationRequest obj
) {
108 return obj
.getWcUrl();
112 public SVNURL
getWcUrl(final AuthenticationRequest obj
) {
113 if (obj
.isOutsideCopies()) return null;
114 if (obj
.getWcUrl() != null) return obj
.getWcUrl();
116 final WorkingCopy copy
= myRootsToWorkingCopies
.getMatchingCopy(obj
.getUrl());
118 obj
.setOutsideCopies(false);
119 obj
.setWcUrl(copy
.getUrl());
121 obj
.setOutsideCopies(true);
123 return copy
== null ?
null : copy
.getUrl();
128 protected String
getNotificationContent(AuthenticationRequest obj
) {
129 return "<a href=\"\">Click to fix.</a> Not logged to Subversion '" + obj
.getRealm() + "' (" + obj
.getUrl().toDecodedString() + ")";
132 public static class AuthenticationRequest
{
133 private final Project myProject
;
134 private final String myKind
;
135 private final SVNURL myUrl
;
136 private final String myRealm
;
138 private SVNURL myWcUrl
;
139 private boolean myOutsideCopies
;
141 public AuthenticationRequest(Project project
, String kind
, SVNURL url
, String realm
) {
148 public boolean isOutsideCopies() {
149 return myOutsideCopies
;
152 public void setOutsideCopies(boolean outsideCopies
) {
153 myOutsideCopies
= outsideCopies
;
156 public SVNURL
getWcUrl() {
160 public void setWcUrl(SVNURL wcUrl
) {
164 public String
getKind() {
168 public SVNURL
getUrl() {
172 public String
getRealm() {
177 static void log(final Throwable t
) {
181 static void log(final String s
) {
185 public static boolean passiveValidation(final Project project
, final SVNURL url
, final boolean checkWrite
,
186 final String realm
, final String kind
) {
187 final SvnConfiguration configuration
= SvnConfiguration
.getInstance(project
);
188 final ISVNAuthenticationManager passiveManager
= configuration
.getPassiveAuthenticationManager();
189 return validationImpl(project
, url
, configuration
, passiveManager
, checkWrite
, realm
, kind
);
192 public static boolean interactiveValidation(final Project project
, final SVNURL url
, final String realm
, final String kind
) {
193 final SvnConfiguration configuration
= SvnConfiguration
.getInstance(project
);
194 final ISVNAuthenticationManager passiveManager
= configuration
.getInteractiveManager(SvnVcs
.getInstance(project
));
195 return validationImpl(project
, url
, configuration
, passiveManager
, true, realm
, kind
);
198 private static boolean validationImpl(final Project project
, final SVNURL url
,
199 final SvnConfiguration configuration
, final ISVNAuthenticationManager manager
,
200 final boolean checkWrite
, final String realm
, final String kind
/*, final boolean passive*/) {
201 SvnInteractiveAuthenticationProvider
.clearCallState();
203 new SVNWCClient(manager
, configuration
.getOptions(project
)).doInfo(url
, SVNRevision
.UNDEFINED
, SVNRevision
.HEAD
);
204 } catch (SVNAuthenticationException e
) {
207 } catch (SVNCancelException e
) {
208 log(e
); // auth canceled
210 } catch (SVNException e
) {
211 if (e
.getErrorMessage().getErrorCode().isAuthentication()) {
215 LOG
.info("some other exc", e
);
221 return SvnInteractiveAuthenticationProvider.wasCalled();
224 if (SvnInteractiveAuthenticationProvider
.wasCalled() && SvnInteractiveAuthenticationProvider
.wasCancelled()) return false;
225 if (SvnInteractiveAuthenticationProvider
.wasCalled()) return true;
227 final SvnVcs svnVcs
= SvnVcs
.getInstance(project
);
229 final SvnInteractiveAuthenticationProvider provider
= new SvnInteractiveAuthenticationProvider(svnVcs
);
230 final SVNAuthentication svnAuthentication
= provider
.requestClientAuthentication(kind
, url
, realm
, null, null, true);
231 if (svnAuthentication
!= null) {
232 configuration
.acknowledge(kind
, realm
, svnAuthentication
);
234 configuration.getAuthenticationManager(svnVcs).acknowledgeAuthentication(true, kind, realm, null, svnAuthentication);
236 catch (SVNException e) {
238 // acknowledge at least in runtime
239 configuration.acknowledge(kind, realm, svnAuthentication);