blob: e0bdc15f78b1a83a46e7ecd3d18819b584b6b040 [file] [log] [blame]
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.idea.svn.ignore;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.changes.VcsDirtyScopeManager;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.svn.SvnPropertyKeys;
import org.jetbrains.idea.svn.SvnVcs;
import org.jetbrains.idea.svn.api.Depth;
import org.jetbrains.idea.svn.properties.PropertyValue;
import org.tmatesoft.svn.core.wc.SVNRevision;
import org.tmatesoft.svn.core.wc2.SvnTarget;
import java.io.File;
import java.util.*;
public class SvnPropertyService {
private SvnPropertyService() {
}
public static void doAddToIgnoreProperty(final SvnVcs activeVcs, final Project project, final boolean useCommonExtension,
final VirtualFile[] file, final IgnoreInfoGetter getter) throws VcsException {
final IgnorePropertyAdder adder = new IgnorePropertyAdder(activeVcs, project, useCommonExtension);
adder.execute(file, getter);
}
public static void doRemoveFromIgnoreProperty(final SvnVcs activeVcs, final Project project, final boolean useCommonExtension,
final VirtualFile[] file, final IgnoreInfoGetter getter) throws VcsException{
final IgnorePropertyRemover remover = new IgnorePropertyRemover(activeVcs, project, useCommonExtension);
remover.execute(file, getter);
}
public static void doCheckIgnoreProperty(final SvnVcs activeVcs, final Project project, final VirtualFile[] file,
final IgnoreInfoGetter getter, final String extensionPattern, final Ref<Boolean> filesOk, final Ref<Boolean> extensionOk) {
final IgnorePropertyChecker checker = new IgnorePropertyChecker(activeVcs, project, extensionPattern);
try {
checker.execute(file, getter);
} catch (VcsException e) {
// ignore - actually never thrown inside
}
filesOk.set(checker.filesOk());
extensionOk.set(checker.extensionOk());
}
private static abstract class IgnorePropertyWorkTemplate {
protected final SvnVcs myVcs;
protected final Project myProject;
protected final boolean myUseCommonExtension;
protected final boolean myCanUseCachedProperty;
protected abstract void processFolder(final VirtualFile folder, final File folderDir, final Set<String> data,
final PropertyValue propertyValue) throws VcsException;
protected abstract void onAfterProcessing(final VirtualFile[] file) throws VcsException;
protected abstract void onSVNException(Exception e);
protected abstract boolean stopIteration();
private IgnorePropertyWorkTemplate(final SvnVcs activeVcs, final Project project, final boolean useCommonExtension,
final boolean canUseCachedProperty) {
myVcs = activeVcs;
myCanUseCachedProperty = canUseCachedProperty;
myProject = project;
myUseCommonExtension = useCommonExtension;
}
public void execute(final VirtualFile[] file, final IgnoreInfoGetter getter) throws VcsException {
final Map<VirtualFile, Set<String>> foldersInfo = getter.getInfo(myUseCommonExtension);
for (final Map.Entry<VirtualFile, Set<String>> entry : foldersInfo.entrySet()) {
if (stopIteration()) {
break;
}
final File dir = new File(entry.getKey().getPath());
try {
final PropertyValue value;
if (myCanUseCachedProperty) {
value = myVcs.getPropertyWithCaching(entry.getKey(), SvnPropertyKeys.SVN_IGNORE);
} else {
value = myVcs.getFactory(dir).createPropertyClient()
.getProperty(SvnTarget.fromFile(dir), SvnPropertyKeys.SVN_IGNORE, false, SVNRevision.WORKING);
}
processFolder(entry.getKey(), dir, entry.getValue(), value);
}
catch (VcsException e) {
onSVNException(e);
}
}
onAfterProcessing(file);
}
}
private static class IgnorePropertyChecker extends IgnorePropertyWorkTemplate {
private final String myExtensionPattern;
private boolean myFilesOk;
private boolean myExtensionOk;
private IgnorePropertyChecker(final SvnVcs activeVcs, final Project project, final String extensionPattern) {
super(activeVcs, project, false, true);
myExtensionPattern = extensionPattern;
myExtensionOk = true;
myFilesOk = true;
}
protected boolean stopIteration() {
return (! myFilesOk) && (! myExtensionOk);
}
protected void processFolder(final VirtualFile folder, final File folderDir, final Set<String> data, final PropertyValue propertyValue)
throws VcsException {
if (propertyValue == null) {
myFilesOk = false;
myExtensionOk = false;
return;
}
final Set<String> ignorePatterns = new HashSet<String>();
final StringTokenizer st = new StringTokenizer(PropertyValue.toString(propertyValue), "\r\n ");
while (st.hasMoreElements()) {
final String ignorePattern = (String)st.nextElement();
ignorePatterns.add(ignorePattern);
}
myExtensionOk &= ignorePatterns.contains(myExtensionPattern);
for (final String fileName : data) {
if (!ignorePatterns.contains(fileName)) {
myFilesOk = false;
}
}
}
protected void onAfterProcessing(final VirtualFile[] file) throws VcsException {
}
protected void onSVNException(final Exception e) {
myFilesOk = false;
myExtensionOk = false;
}
public boolean filesOk() {
return myFilesOk;
}
public boolean extensionOk() {
return myExtensionOk;
}
}
private abstract static class IgnorePropertyAddRemoveTemplate extends IgnorePropertyWorkTemplate {
private final Collection<String> exceptions;
private final VcsDirtyScopeManager dirtyScopeManager;
private IgnorePropertyAddRemoveTemplate(final SvnVcs activeVcs, final Project project, final boolean useCommonExtension) {
super(activeVcs, project, useCommonExtension, false);
exceptions = new ArrayList<String>();
dirtyScopeManager = VcsDirtyScopeManager.getInstance(project);
}
protected boolean stopIteration() {
return false;
}
protected abstract String getNewPropertyValue(final Set<String> data, final PropertyValue propertyValue);
protected void processFolder(final VirtualFile folder, final File folderDir, final Set<String> data, final PropertyValue propertyValue)
throws VcsException {
String newValue = getNewPropertyValue(data, propertyValue);
newValue = (newValue.trim().isEmpty()) ? null : newValue;
myVcs.getFactory(folderDir).createPropertyClient()
.setProperty(folderDir, SvnPropertyKeys.SVN_IGNORE, PropertyValue.create(newValue), Depth.EMPTY, false);
if (myUseCommonExtension) {
dirtyScopeManager.dirDirtyRecursively(folder);
}
}
protected void onAfterProcessing(final VirtualFile[] file) throws VcsException {
if (! myUseCommonExtension) {
for (VirtualFile virtualFile : file) {
VcsDirtyScopeManager.getInstance(myProject).fileDirty(virtualFile);
}
}
if (!exceptions.isEmpty()) {
throw new VcsException(exceptions);
}
}
protected void onSVNException(final Exception e) {
exceptions.add(e.getMessage());
}
}
private static class IgnorePropertyRemover extends IgnorePropertyAddRemoveTemplate {
private IgnorePropertyRemover(final SvnVcs activeVcs, final Project project, final boolean useCommonExtension) {
super(activeVcs, project, useCommonExtension);
}
protected String getNewPropertyValue(final Set<String> data, final PropertyValue propertyValue) {
if (propertyValue != null) {
return getNewPropertyValueForRemove(data, PropertyValue.toString(propertyValue));
}
return "";
}
}
private static String getNewPropertyValueForRemove(final Collection<String> data, @NotNull final String propertyValue) {
final StringBuilder sb = new StringBuilder();
final StringTokenizer st = new StringTokenizer(propertyValue, "\r\n ");
while (st.hasMoreElements()) {
final String ignorePattern = (String)st.nextElement();
if (! data.contains(ignorePattern)) {
sb.append(ignorePattern).append('\n');
}
}
return sb.toString();
}
private static class IgnorePropertyAdder extends IgnorePropertyAddRemoveTemplate {
private IgnorePropertyAdder(final SvnVcs activeVcs, final Project project, final boolean useCommonExtension) {
super(activeVcs, project, useCommonExtension);
}
protected String getNewPropertyValue(final Set<String> data, final PropertyValue propertyValue) {
final String ignoreString;
if (data.size() == 1) {
ignoreString = data.iterator().next();
} else {
final StringBuilder sb = new StringBuilder();
for (final String name : data) {
sb.append(name).append('\n');
}
ignoreString = sb.toString();
}
return (propertyValue == null) ? ignoreString : (PropertyValue.toString(propertyValue) + '\n' + ignoreString);
}
}
}