Merge remote-tracking branch 'origin/master'

This commit is contained in:
anna
2012-02-07 11:44:11 +01:00
43 changed files with 1279 additions and 263 deletions
-1
View File
@@ -4,7 +4,6 @@
<root id="archive" name="jps-plugins.jar">
<element id="module-output" name="jps-appLauncher" />
<element id="module-output" name="jps-gwt" />
<element id="module-output" name="jps-javaee" />
<element id="module-output" name="jps-jpa" />
<element id="module-output" name="jps-scala" />
</root>
-1
View File
@@ -6,7 +6,6 @@
<element id="dir-copy" path="$PROJECT_DIR$/jps/model/src" />
<element id="dir-copy" path="$PROJECT_DIR$/jps/plugins/appLauncher/src" />
<element id="dir-copy" path="$PROJECT_DIR$/jps/plugins/gwt/src" />
<element id="dir-copy" path="$PROJECT_DIR$/jps/plugins/javaee/src" />
<element id="dir-copy" path="$PROJECT_DIR$/jps/plugins/jpa/src" />
<element id="dir-copy" path="$PROJECT_DIR$/jps/plugins/scala/src" />
<element id="dir-copy" path="$PROJECT_DIR$/jps/src" />
-1
View File
@@ -60,7 +60,6 @@
<module fileurl="file://$PROJECT_DIR$/jps/plugins/appLauncher/jps-appLauncher.iml" filepath="$PROJECT_DIR$/jps/plugins/appLauncher/jps-appLauncher.iml" group="jps" />
<module fileurl="file://$PROJECT_DIR$/jps/jps-builders/jps-builders.iml" filepath="$PROJECT_DIR$/jps/jps-builders/jps-builders.iml" group="jps" />
<module fileurl="file://$PROJECT_DIR$/jps/plugins/gwt/jps-gwt.iml" filepath="$PROJECT_DIR$/jps/plugins/gwt/jps-gwt.iml" group="jps" />
<module fileurl="file://$PROJECT_DIR$/jps/plugins/javaee/jps-javaee.iml" filepath="$PROJECT_DIR$/jps/plugins/javaee/jps-javaee.iml" group="jps" />
<module fileurl="file://$PROJECT_DIR$/jps/plugins/jpa/jps-jpa.iml" filepath="$PROJECT_DIR$/jps/plugins/jpa/jps-jpa.iml" group="jps" />
<module fileurl="file://$PROJECT_DIR$/jps/model/jps-model.iml" filepath="$PROJECT_DIR$/jps/model/jps-model.iml" group="jps" />
<module fileurl="file://$PROJECT_DIR$/jps/plugins/scala/jps-scala.iml" filepath="$PROJECT_DIR$/jps/plugins/scala/jps-scala.iml" group="jps" />
@@ -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<RequestFuture, Project> myAutomakeFutures = new HashMap<RequestFuture, Project>();
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<File> cp = ClasspathBootstrap.getCompileServerApplicationClasspath();
cp.addAll(myClasspathManager.getCompileServerPluginsClasspath());
cmdLine.addParameter(classpathToString(cp));
@@ -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<CompileServerPlugin> 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;
}
}
@@ -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<File> myCompileServerPluginsClasspath;
public List<File> getCompileServerPluginsClasspath() {
if (myCompileServerPluginsClasspath == null) {
myCompileServerPluginsClasspath = computeCompileServerPluginsClasspath();
}
return myCompileServerPluginsClasspath;
}
private static List<File> computeCompileServerPluginsClasspath() {
final List<File> classpath = new ArrayList<File>();
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/<jar-name> 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;
}
}
@@ -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
-1
View File
@@ -10,7 +10,6 @@
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="jps" />
<orderEntry type="library" name="Groovy" level="project" />
<orderEntry type="module" module-name="jps-javaee" />
<orderEntry type="library" name="JUnit4" level="project" />
</component>
</module>
-14
View File
@@ -1,14 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="jps" />
<orderEntry type="library" name="Groovy" level="project" />
</component>
</module>
@@ -1,2 +0,0 @@
org.jetbrains.jps.javaee.JavaeeFacetResourcesElementType
org.jetbrains.jps.javaee.JavaeeFacetClassesElementType
@@ -1,3 +0,0 @@
org.jetbrains.jps.javaee.WebFacetType
org.jetbrains.jps.javaee.EjbFacetType
org.jetbrains.jps.javaee.JavaeeAppFacetType
@@ -1,10 +0,0 @@
package org.jetbrains.jps.javaee
/**
* @author nik
*/
class EjbFacetType extends JavaeeFacetTypeBase {
EjbFacetType() {
super("ejb")
}
}
@@ -1,10 +0,0 @@
package org.jetbrains.jps.javaee
/**
* @author nik
*/
public class JavaeeAppFacetType extends JavaeeFacetTypeBase {
JavaeeAppFacetType() {
super("javaeeApplication")
}
}
@@ -1,11 +0,0 @@
package org.jetbrains.jps.javaee
import org.jetbrains.jps.idea.Facet
/**
* @author nik
*/
class JavaeeFacet extends Facet {
final List<Map<String, String>> descriptors = []
final List<Map<String, String>> webRoots = []
}
@@ -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('/')))
}
}
@@ -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<LayoutElement> getSubstitution(Project project) {
Facet facet = IdeaProjectLoadingUtil.findFacetByIdWithAssertion(project, facetId, errorReporter)
if (!(facet instanceof JavaeeFacet)) {
errorReporter.error("$facetId facet is not JavaEE facet")
}
List<LayoutElement> result = []
facet.descriptors.each {Map<String, String> descriptor ->
result << LayoutElementFactory.createParentDirectories(descriptor.outputPath, new FileCopyElement(filePath: descriptor.path))
}
facet.webRoots.each {Map<String, String> webRoot ->
result << LayoutElementFactory.createParentDirectories(webRoot.outputPath, new DirectoryCopyElement(dirPath: webRoot.path))
}
return result
}
}
@@ -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)
}
}
@@ -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))
}
}
@@ -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"
}
}
@@ -83,10 +83,12 @@ public class CoreEnvironment {
myEncodingRegistry = new CoreEncodingRegistry();
myApplication = new MockApplication(parentDisposable);
ApplicationManager.setApplication(myApplication,
new StaticGetter<FileTypeRegistry>(myFileTypeRegistry),
new StaticGetter<EncodingRegistry>(myEncodingRegistry),
parentDisposable);
if (ApplicationManager.getApplication() == null) {
ApplicationManager.setApplication(myApplication,
new StaticGetter<FileTypeRegistry>(myFileTypeRegistry),
new StaticGetter<EncodingRegistry>(myEncodingRegistry),
parentDisposable);
}
myLocalFileSystem = new CoreLocalFileSystem();
myJarFileSystem = new CoreJarFileSystem();
@@ -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<VirtualFile> files = new HashSet<VirtualFile>();
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<Integer> keys = new THashSet<Integer>(30);
Set<PsiFile> resultFiles = new THashSet<PsiFile>();
@@ -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";
}
@@ -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<FoldingDescriptor> descriptors = new ArrayList<FoldingDescriptor>();
appendDescriptors(node.getPsi(), descriptors, new HashSet<PsiElement>());
return descriptors.toArray(new FoldingDescriptor[descriptors.size()]);
@Override
protected void buildLanguageFoldRegions(@NotNull List<FoldingDescriptor> descriptors,
@NotNull PsiElement root,
@NotNull Document document,
boolean quick) {
appendDescriptors(root, descriptors, new HashSet<PsiElement>());
}
private static void appendDescriptors(PsiElement element, List<FoldingDescriptor> descriptors, Set<PsiElement> usedComments) {
private void appendDescriptors(PsiElement element, List<FoldingDescriptor> descriptors, Set<PsiElement> 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;
}
}
@@ -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(),
@@ -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) {
@@ -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<Thread, String> 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;
}
}
}
@@ -178,7 +178,7 @@ public class SvnAuthenticationNotifier extends GenericNotifierImpl<SvnAuthentica
@Override
protected boolean onFirstNotification(AuthenticationRequest obj) {
if (ProgressManager.getInstance().hasProgressIndicator()) {
return ask(obj, null);
return ask(obj, null); // TODO
} else {
return false;
}
@@ -247,6 +247,7 @@ public class SvnAuthenticationNotifier extends GenericNotifierImpl<SvnAuthentica
private SVNURL myWcUrl;
private boolean myOutsideCopies;
private boolean myForceSaving;
public AuthenticationRequest(Project project, String kind, SVNURL url, String realm) {
myProject = project;
@@ -255,6 +256,14 @@ public class SvnAuthenticationNotifier extends GenericNotifierImpl<SvnAuthentica
myRealm = realm;
}
public boolean isForceSaving() {
return myForceSaving;
}
public void setForceSaving(boolean forceSaving) {
myForceSaving = forceSaving;
}
public boolean isOutsideCopies() {
return myOutsideCopies;
}
@@ -259,6 +259,20 @@ public class SvnConfiguration17 implements PersistentStateComponent<Element> {
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
@@ -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) {
@@ -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;
@@ -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);
}
@@ -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<StoreData> myData;
private final Set<Trinity<String, String, SVNURL>> myAuthRequested;
private StoreListener() {
myData = new HashSet<StoreData>();
myAuthRequested = new HashSet<Trinity<String, String, SVNURL>>();
}
@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<String, String, SVNURL> create(String kind, String realm, SVNURL url) {
return new Trinity<String, String, SVNURL>(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<String, String, SVNURL> 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;
}
}
}
@@ -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);
}
}
@@ -339,6 +339,12 @@ public class SvnStatusHandler extends DefaultHandler {
super(new String[]{"commit"}, new String[]{});
}
/*<wc-status
props="none"
wc-locked="true"
item="normal"
revision="120">*/
@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);
@@ -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<Character> ourActions = new HashSet<Character>(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);
}
}
@@ -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<Thread> ourForceInteractive = new HashSet<Thread>();
public SvnAuthenticationProvider(final SvnVcs17 svnVcs, final ISVNAuthenticationProvider provider,
final ISVNAuthenticationStorage authenticationStorage) {
mySvnVcs = svnVcs;
myAuthenticationStorage = authenticationStorage;
myProject = svnVcs.getProject();
myAuthenticationNotifier = svnVcs.getAuthNotifier();
@@ -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];
}
@@ -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<List<Fragment>>();
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<ChangesBunch> 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
@@ -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;
}
}
@@ -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);
}
@@ -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;
}
@@ -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<Pair<SVNURL, String>>();
}
@Override
public void acknowledge(boolean accepted, String kind, String realm, SVNErrorMessage message, SVNAuthentication authentication) {
}
public void reset() {
mySaved.clear();
myClientRequested.clear();
@@ -72,6 +72,7 @@
<extensionPoint name="compiler" area="IDEA_PROJECT" interface="com.intellij.openapi.compiler.Compiler"/>
<extensionPoint name="compilerFactory" area="IDEA_PROJECT" interface="com.intellij.openapi.compiler.CompilerFactory"/>
<extensionPoint name="compilerSettingsFactory" area="IDEA_PROJECT" interface="com.intellij.compiler.CompilerSettingsFactory"/>
<extensionPoint name="compileServer.plugin" beanClass="com.intellij.compiler.server.CompileServerPlugin"/>
<extensionPoint name="paletteItemProvider" area="IDEA_PROJECT" interface="com.intellij.ide.palette.PaletteItemProvider"/>