diff options
Diffstat (limited to 'plugins/svn4idea/src/org/jetbrains/idea/svn/properties')
8 files changed, 405 insertions, 83 deletions
diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/CmdPropertyClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/CmdPropertyClient.java index e855abe1ec2e..e053776d14ce 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/CmdPropertyClient.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/CmdPropertyClient.java @@ -10,9 +10,8 @@ import org.jetbrains.idea.svn.commandLine.CommandExecutor; import org.jetbrains.idea.svn.commandLine.CommandUtil; import org.jetbrains.idea.svn.commandLine.SvnCommandName; import org.jetbrains.idea.svn.info.Info; -import org.tmatesoft.svn.core.*; -import org.tmatesoft.svn.core.wc.ISVNPropertyHandler; -import org.tmatesoft.svn.core.wc.SVNPropertyData; +import org.tmatesoft.svn.core.SVNException; +import org.tmatesoft.svn.core.SVNURL; import org.tmatesoft.svn.core.wc.SVNRevision; import org.tmatesoft.svn.core.wc2.SvnTarget; @@ -24,6 +23,7 @@ import javax.xml.bind.annotation.XmlValue; import java.io.File; import java.util.ArrayList; import java.util.List; +import java.util.Map; /** * @author Konstantin Kolosovsky. @@ -32,10 +32,10 @@ public class CmdPropertyClient extends BaseSvnClient implements PropertyClient { @Nullable @Override - public SVNPropertyData getProperty(@NotNull SvnTarget target, - @NotNull String property, - boolean revisionProperty, - @Nullable SVNRevision revision) + public PropertyValue getProperty(@NotNull SvnTarget target, + @NotNull String property, + boolean revisionProperty, + @Nullable SVNRevision revision) throws VcsException { List<String> parameters = new ArrayList<String>(); @@ -57,7 +57,9 @@ public class CmdPropertyClient extends BaseSvnClient implements PropertyClient { parameters.add("--xml"); CommandExecutor command = execute(myVcs, target, SvnCommandName.propget, parameters, null); - return parseSingleProperty(target, command.getOutput()); + PropertyData data = parseSingleProperty(target, command.getOutput()); + + return data != null ? data.getValue() : null; } @Override @@ -65,7 +67,7 @@ public class CmdPropertyClient extends BaseSvnClient implements PropertyClient { @NotNull String property, @Nullable SVNRevision revision, @Nullable Depth depth, - @Nullable ISVNPropertyHandler handler) throws VcsException { + @Nullable PropertyConsumer handler) throws VcsException { List<String> parameters = new ArrayList<String>(); parameters.add(property); @@ -79,7 +81,7 @@ public class CmdPropertyClient extends BaseSvnClient implements PropertyClient { public void list(@NotNull SvnTarget target, @Nullable SVNRevision revision, @Nullable Depth depth, - @Nullable ISVNPropertyHandler handler) throws VcsException { + @Nullable PropertyConsumer handler) throws VcsException { List<String> parameters = new ArrayList<String>(); fillListParameters(target, revision, depth, parameters, true); @@ -90,39 +92,39 @@ public class CmdPropertyClient extends BaseSvnClient implements PropertyClient { @Override public void setProperty(@NotNull File file, @NotNull String property, - @Nullable SVNPropertyValue value, + @Nullable PropertyValue value, @Nullable Depth depth, boolean force) throws VcsException { runSetProperty(SvnTarget.fromFile(file), property, null, depth, value, force); } @Override - public void setProperties(@NotNull File file, @NotNull SVNProperties properties) throws VcsException { - SVNProperties currentProperties = collectPropertiesToDelete(file); + public void setProperties(@NotNull File file, @NotNull PropertiesMap properties) throws VcsException { + PropertiesMap currentProperties = collectPropertiesToDelete(file); currentProperties.putAll(properties); - for (String propertyName : currentProperties.nameSet()) { - setProperty(file, propertyName, currentProperties.getSVNPropertyValue(propertyName), Depth.EMPTY, true); + for (Map.Entry<String, PropertyValue> entry : currentProperties.entrySet()) { + setProperty(file, entry.getKey(), entry.getValue(), Depth.EMPTY, true); } } @NotNull - private SVNProperties collectPropertiesToDelete(@NotNull File file) throws VcsException { - final SVNProperties result = new SVNProperties(); + private PropertiesMap collectPropertiesToDelete(@NotNull File file) throws VcsException { + final PropertiesMap result = new PropertiesMap(); - list(SvnTarget.fromFile(file), null, Depth.EMPTY, new ISVNPropertyHandler() { + list(SvnTarget.fromFile(file), null, Depth.EMPTY, new PropertyConsumer() { @Override - public void handleProperty(File path, SVNPropertyData property) throws SVNException { + public void handleProperty(File path, PropertyData property) throws SVNException { // null indicates property will be deleted - result.put(property.getName(), (SVNPropertyValue)null); + result.put(property.getName(), null); } @Override - public void handleProperty(SVNURL url, SVNPropertyData property) throws SVNException { + public void handleProperty(SVNURL url, PropertyData property) throws SVNException { } @Override - public void handleProperty(long revision, SVNPropertyData property) throws SVNException { + public void handleProperty(long revision, PropertyData property) throws SVNException { } }); @@ -133,7 +135,7 @@ public class CmdPropertyClient extends BaseSvnClient implements PropertyClient { public void setRevisionProperty(@NotNull SvnTarget target, @NotNull String property, @NotNull SVNRevision revision, - @Nullable SVNPropertyValue value, + @Nullable PropertyValue value, boolean force) throws VcsException { runSetProperty(target, property, revision, null, value, force); } @@ -142,7 +144,7 @@ public class CmdPropertyClient extends BaseSvnClient implements PropertyClient { @NotNull String property, @Nullable SVNRevision revision, @Nullable Depth depth, - @Nullable SVNPropertyValue value, + @Nullable PropertyValue value, boolean force) throws VcsException { List<String> parameters = new ArrayList<String>(); boolean isDelete = value == null; @@ -153,7 +155,7 @@ public class CmdPropertyClient extends BaseSvnClient implements PropertyClient { CommandUtil.put(parameters, revision); } if (!isDelete) { - parameters.add(SVNPropertyValue.getPropertyAsString(value)); + parameters.add(PropertyValue.toString(value)); // --force could only be used in "propset" command, but not in "propdel" command CommandUtil.put(parameters, force, "--force"); } @@ -180,21 +182,22 @@ public class CmdPropertyClient extends BaseSvnClient implements PropertyClient { CommandUtil.put(parameters, verbose, "--verbose"); } - private SVNPropertyData parseSingleProperty(SvnTarget target, String output) throws VcsException { - final SVNPropertyData[] data = new SVNPropertyData[1]; - ISVNPropertyHandler handler = new ISVNPropertyHandler() { + @Nullable + private PropertyData parseSingleProperty(SvnTarget target, String output) throws VcsException { + final PropertyData[] data = new PropertyData[1]; + PropertyConsumer handler = new PropertyConsumer() { @Override - public void handleProperty(File path, SVNPropertyData property) throws SVNException { + public void handleProperty(File path, PropertyData property) throws SVNException { data[0] = property; } @Override - public void handleProperty(SVNURL url, SVNPropertyData property) throws SVNException { + public void handleProperty(SVNURL url, PropertyData property) throws SVNException { data[0] = property; } @Override - public void handleProperty(long revision, SVNPropertyData property) throws SVNException { + public void handleProperty(long revision, PropertyData property) throws SVNException { data[0] = property; } }; @@ -204,7 +207,7 @@ public class CmdPropertyClient extends BaseSvnClient implements PropertyClient { return data[0]; } - private static void parseOutput(SvnTarget target, String output, ISVNPropertyHandler handler) throws VcsException { + private static void parseOutput(SvnTarget target, String output, PropertyConsumer handler) throws VcsException { try { Properties properties = CommandUtil.parse(output, Properties.class); @@ -231,7 +234,7 @@ public class CmdPropertyClient extends BaseSvnClient implements PropertyClient { } } - private static void invokeHandler(@NotNull SvnTarget target, @Nullable SVNPropertyData data, @Nullable ISVNPropertyHandler handler) + private static void invokeHandler(@NotNull SvnTarget target, @Nullable PropertyData data, @Nullable PropertyConsumer handler) throws SVNException { if (handler != null && data != null) { if (target.isFile()) { @@ -242,7 +245,7 @@ public class CmdPropertyClient extends BaseSvnClient implements PropertyClient { } } - private static void invokeHandler(long revision, @Nullable SVNPropertyData data, @Nullable ISVNPropertyHandler handler) + private static void invokeHandler(long revision, @Nullable PropertyData data, @Nullable PropertyConsumer handler) throws SVNException { if (handler != null && data != null) { handler.handleProperty(revision, data); @@ -250,13 +253,13 @@ public class CmdPropertyClient extends BaseSvnClient implements PropertyClient { } @Nullable - private static SVNPropertyData create(@NotNull String property, @Nullable String value) { - SVNPropertyData result = null; + private static PropertyData create(@NotNull String property, @Nullable String value) { + PropertyData result = null; // such behavior is required to compatibility with SVNKit as some logic in merge depends on // whether null property data or property data with empty string value is returned if (value != null) { - result = new SVNPropertyData(property, SVNPropertyValue.create(value.trim()), LF_SEPARATOR_OPTIONS); + result = new PropertyData(property, PropertyValue.create(value.trim())); } return result; diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/ExternalsDefinitionParser.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/ExternalsDefinitionParser.java new file mode 100644 index 000000000000..b3ec74e397cb --- /dev/null +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/ExternalsDefinitionParser.java @@ -0,0 +1,106 @@ +/* + * Copyright 2000-2014 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.properties; + +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.idea.svn.commandLine.SvnBindException; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author Konstantin Kolosovsky. + */ +public class ExternalsDefinitionParser { + + /** + * Parses "svn:externals" property in format starting from svn 1.5. + * + * @return map of externals definitions: key - relative directory, value - corresponding complete externals definition. + */ + @NotNull + public static Map<String, String> parseExternalsProperty(@NotNull String externals) throws SvnBindException { + HashMap<String, String> map = ContainerUtil.newHashMap(); + + for (String external : StringUtil.splitByLines(externals, true)) { + map.put(parseRelativeDirectory(external), external); + } + + return map; + } + + /** + * Parses relative directory from externals definition (in format starting from svn 1.5). Restrictions for relative directory: + * - is at the end of externals definition separated from other parameters by ' ' char + * - could be quoted with '"' char + * - certain chars could be escaped with '\' char + */ + @NotNull + public static String parseRelativeDirectory(@NotNull String s) throws SvnBindException { + s = s.trim(); + + int length = s.length(); + String result; + + if (isUnescapedQuote(s, length - 1)) { + int index = lastUnescapedIndexOf(s, length - 1, '"'); + assertIndex(s, index, "Could not find start quote"); + result = s.substring(index + 1, length - 1); + } + else { + int index = lastUnescapedIndexOf(s, length, ' '); + assertIndex(s, index, "Could not find separating space"); + result = s.substring(index + 1); + } + + return unescape(result); + } + + private static void assertIndex(@NotNull String s, int index, @NotNull String message) throws SvnBindException { + if (index < 0) { + throw new SvnBindException(message + " - " + s); + } + } + + @NotNull + private static String unescape(@NotNull String s) { + return s.replace("\\", ""); + } + + /** + * "from" index is excluded. + */ + private static int lastUnescapedIndexOf(@NotNull String s, int from, char c) { + int result = from; + + do { + result = s.lastIndexOf(c, result - 1); + } + while (result != -1 && !isUnescaped(s, result, c)); + + return result; + } + + private static boolean isUnescapedQuote(@NotNull String s, int index) { + return isUnescaped(s, index, '"'); + } + + private static boolean isUnescaped(@NotNull String s, int index, char c) { + return StringUtil.isChar(s, index, c) && !StringUtil.isChar(s, index - 1, '\\'); + } +} diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/PropertiesMap.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/PropertiesMap.java new file mode 100644 index 000000000000..c5857aa4b345 --- /dev/null +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/PropertiesMap.java @@ -0,0 +1,24 @@ +/* + * Copyright 2000-2014 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.properties; + +import com.intellij.util.containers.HashMap; + +/** + * @author Konstantin Kolosovsky. + */ +public class PropertiesMap extends HashMap<String, PropertyValue> { +} diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/PropertyClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/PropertyClient.java index 1b61d59c0e20..42acfc8109d7 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/PropertyClient.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/PropertyClient.java @@ -1,18 +1,10 @@ package org.jetbrains.idea.svn.properties; import com.intellij.openapi.vcs.VcsException; -import com.intellij.openapi.vfs.CharsetToolkit; -import com.intellij.util.LineSeparator; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.idea.svn.api.Depth; import org.jetbrains.idea.svn.api.SvnClient; -import org.tmatesoft.svn.core.SVNProperties; -import org.tmatesoft.svn.core.SVNPropertyValue; -import org.tmatesoft.svn.core.internal.wc.DefaultSVNOptions; -import org.tmatesoft.svn.core.wc.ISVNOptions; -import org.tmatesoft.svn.core.wc.ISVNPropertyHandler; -import org.tmatesoft.svn.core.wc.SVNPropertyData; import org.tmatesoft.svn.core.wc.SVNRevision; import org.tmatesoft.svn.core.wc2.SvnTarget; @@ -23,40 +15,33 @@ import java.io.File; */ public interface PropertyClient extends SvnClient { - ISVNOptions LF_SEPARATOR_OPTIONS = new DefaultSVNOptions() { - @Override - public byte[] getNativeEOL() { - return CharsetToolkit.getUtf8Bytes(LineSeparator.LF.getSeparatorString()); - } - }; - @Nullable - SVNPropertyData getProperty(@NotNull final SvnTarget target, - @NotNull final String property, - boolean revisionProperty, - @Nullable SVNRevision revision) throws VcsException; + PropertyValue getProperty(@NotNull final SvnTarget target, + @NotNull final String property, + boolean revisionProperty, + @Nullable SVNRevision revision) throws VcsException; void getProperty(@NotNull SvnTarget target, @NotNull String property, @Nullable SVNRevision revision, @Nullable Depth depth, - @Nullable ISVNPropertyHandler handler) throws VcsException; + @Nullable PropertyConsumer handler) throws VcsException; void list(@NotNull SvnTarget target, @Nullable SVNRevision revision, @Nullable Depth depth, - @Nullable ISVNPropertyHandler handler) throws VcsException; + @Nullable PropertyConsumer handler) throws VcsException; void setProperty(@NotNull File file, @NotNull String property, - @Nullable SVNPropertyValue value, + @Nullable PropertyValue value, @Nullable Depth depth, boolean force) throws VcsException; - void setProperties(@NotNull File file, @NotNull SVNProperties properties) throws VcsException; + void setProperties(@NotNull File file, @NotNull PropertiesMap properties) throws VcsException; void setRevisionProperty(@NotNull SvnTarget target, @NotNull String property, @NotNull SVNRevision revision, - @Nullable SVNPropertyValue value, + @Nullable PropertyValue value, boolean force) throws VcsException; } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/PropertyConsumer.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/PropertyConsumer.java new file mode 100644 index 000000000000..f45e09df39d5 --- /dev/null +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/PropertyConsumer.java @@ -0,0 +1,33 @@ +/* + * Copyright 2000-2014 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.properties; + +import org.tmatesoft.svn.core.SVNException; +import org.tmatesoft.svn.core.SVNURL; + +import java.io.File; + +/** + * @author Konstantin Kolosovsky. + */ +public interface PropertyConsumer { + + void handleProperty(File path, PropertyData property) throws SVNException; + + void handleProperty(SVNURL url, PropertyData property) throws SVNException; + + void handleProperty(long revision, PropertyData property) throws SVNException; +} diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/PropertyData.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/PropertyData.java new file mode 100644 index 000000000000..3953636d870c --- /dev/null +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/PropertyData.java @@ -0,0 +1,53 @@ +/* + * Copyright 2000-2014 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.properties; + +import org.jetbrains.annotations.Nullable; +import org.tmatesoft.svn.core.wc.SVNPropertyData; + +/** + * @author Konstantin Kolosovsky. + */ +public class PropertyData { + + private final PropertyValue myValue; + + private final String myName; + + public PropertyData(String name, PropertyValue value) { + myName = name; + myValue = value; + } + + public String getName() { + return myName; + } + + public PropertyValue getValue() { + return myValue; + } + + @Nullable + public static PropertyData create(@Nullable SVNPropertyData data) { + PropertyData result = null; + + if (data != null) { + result = new PropertyData(data.getName(), PropertyValue.create(data.getValue())); + } + + return result; + } +} diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/PropertyValue.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/PropertyValue.java new file mode 100644 index 000000000000..62cb7cbd0340 --- /dev/null +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/PropertyValue.java @@ -0,0 +1,53 @@ +/* + * Copyright 2000-2014 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.properties; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.tmatesoft.svn.core.SVNPropertyValue; + +/** + * TODO: Add correct support of binary properties - support in api, diff, etc. + * + * @author Konstantin Kolosovsky. + */ +public class PropertyValue { + + @NotNull private final String myValue; + + @Nullable + public static PropertyValue create(@Nullable SVNPropertyValue value) { + return create(SVNPropertyValue.getPropertyAsString(value)); + } + + private PropertyValue(@NotNull String propertyValue) { + myValue = propertyValue; + } + + @Nullable + public static PropertyValue create(@Nullable String propertyValue) { + return propertyValue == null ? null : new PropertyValue(propertyValue); + } + + @Nullable + public static String toString(@Nullable PropertyValue value) { + return value == null ? null : value.myValue; + } + + public String toString() { + return myValue; + } +} diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/SvnKitPropertyClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/SvnKitPropertyClient.java index 4ad3f10afccc..23fedd3c7ac8 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/SvnKitPropertyClient.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/properties/SvnKitPropertyClient.java @@ -1,42 +1,57 @@ package org.jetbrains.idea.svn.properties; import com.intellij.openapi.vcs.VcsException; +import com.intellij.openapi.vfs.CharsetToolkit; +import com.intellij.util.LineSeparator; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.idea.svn.api.BaseSvnClient; import org.jetbrains.idea.svn.api.Depth; import org.jetbrains.idea.svn.commandLine.SvnBindException; import org.tmatesoft.svn.core.*; +import org.tmatesoft.svn.core.internal.wc.DefaultSVNOptions; import org.tmatesoft.svn.core.wc.*; import org.tmatesoft.svn.core.wc2.SvnTarget; import java.io.File; +import java.util.Map; /** * @author Konstantin Kolosovsky. */ public class SvnKitPropertyClient extends BaseSvnClient implements PropertyClient { + public static final ISVNOptions LF_SEPARATOR_OPTIONS = new DefaultSVNOptions() { + @Override + public byte[] getNativeEOL() { + return CharsetToolkit.getUtf8Bytes(LineSeparator.LF.getSeparatorString()); + } + }; + @Nullable @Override - public SVNPropertyData getProperty(@NotNull SvnTarget target, - @NotNull String property, - boolean revisionProperty, - @Nullable SVNRevision revision) throws VcsException { + public PropertyValue getProperty(@NotNull SvnTarget target, + @NotNull String property, + boolean revisionProperty, + @Nullable SVNRevision revision) throws VcsException { + PropertyData resultData; + try { if (!revisionProperty) { if (target.isFile()) { - return createClient().doGetProperty(target.getFile(), property, target.getPegRevision(), revision); + resultData = PropertyData.create(createClient().doGetProperty(target.getFile(), property, target.getPegRevision(), revision)); } else { - return createClient().doGetProperty(target.getURL(), property, target.getPegRevision(), revision); + resultData = PropertyData.create(createClient().doGetProperty(target.getURL(), property, target.getPegRevision(), revision)); } } else { - return getRevisionProperty(target, property, revision); + resultData = getRevisionProperty(target, property, revision); } } catch (SVNException e) { throw new VcsException(e); } + + return resultData != null ? resultData.getValue() : null; } @NotNull @@ -52,7 +67,7 @@ public class SvnKitPropertyClient extends BaseSvnClient implements PropertyClien @NotNull String property, @Nullable SVNRevision revision, @Nullable Depth depth, - @Nullable ISVNPropertyHandler handler) throws VcsException { + @Nullable PropertyConsumer handler) throws VcsException { runGetProperty(target, property, revision, depth, handler); } @@ -60,18 +75,18 @@ public class SvnKitPropertyClient extends BaseSvnClient implements PropertyClien public void list(@NotNull SvnTarget target, @Nullable SVNRevision revision, @Nullable Depth depth, - @Nullable ISVNPropertyHandler handler) throws VcsException { + @Nullable PropertyConsumer handler) throws VcsException { runGetProperty(target, null, revision, depth, handler); } @Override public void setProperty(@NotNull File file, @NotNull String property, - @Nullable SVNPropertyValue value, + @Nullable PropertyValue value, @Nullable Depth depth, boolean force) throws VcsException { try { - createClient().doSetProperty(file, property, value, force, toDepth(depth), null, null); + createClient().doSetProperty(file, property, toPropertyValue(value), force, toDepth(depth), null, null); } catch (SVNException e) { throw new SvnBindException(e); @@ -79,12 +94,13 @@ public class SvnKitPropertyClient extends BaseSvnClient implements PropertyClien } @Override - public void setProperties(@NotNull File file, @NotNull SVNProperties properties) throws VcsException { + public void setProperties(@NotNull File file, @NotNull PropertiesMap properties) throws VcsException { + final SVNProperties propertiesToSet = toSvnProperties(properties); try { createClient().doSetProperty(file, new ISVNPropertyValueProvider() { @Override public SVNProperties providePropertyValues(File path, SVNProperties properties) throws SVNException { - return properties; + return propertiesToSet; } }, true, SVNDepth.EMPTY, null, null); } @@ -97,14 +113,14 @@ public class SvnKitPropertyClient extends BaseSvnClient implements PropertyClien public void setRevisionProperty(@NotNull SvnTarget target, @NotNull String property, @NotNull SVNRevision revision, - @Nullable SVNPropertyValue value, + @Nullable PropertyValue value, boolean force) throws VcsException { try { if (target.isFile()) { - createClient().doSetRevisionProperty(target.getFile(), revision, property, value, force, null); + createClient().doSetRevisionProperty(target.getFile(), revision, property, toPropertyValue(value), force, null); } else { - createClient().doSetRevisionProperty(target.getURL(), revision, property, value, force, null); + createClient().doSetRevisionProperty(target.getURL(), revision, property, toPropertyValue(value), force, null); } } catch (SVNException e) { @@ -112,27 +128,39 @@ public class SvnKitPropertyClient extends BaseSvnClient implements PropertyClien } } + @NotNull + private static SVNProperties toSvnProperties(@NotNull PropertiesMap properties) { + SVNProperties result = new SVNProperties(); + + for (Map.Entry<String, PropertyValue> entry : properties.entrySet()) { + result.put(entry.getKey(), toPropertyValue(entry.getValue())); + } + + return result; + } + private void runGetProperty(@NotNull SvnTarget target, @Nullable String property, @Nullable SVNRevision revision, @Nullable Depth depth, - @Nullable ISVNPropertyHandler handler) throws VcsException { + @Nullable PropertyConsumer handler) throws VcsException { SVNWCClient client = createClient(); try { if (target.isURL()) { - client.doGetProperty(target.getURL(), property, target.getPegRevision(), revision, toDepth(depth), handler); + client.doGetProperty(target.getURL(), property, target.getPegRevision(), revision, toDepth(depth), toHandler(handler)); } else { - client.doGetProperty(target.getFile(), property, target.getPegRevision(), revision, toDepth(depth), handler, null); + client.doGetProperty(target.getFile(), property, target.getPegRevision(), revision, toDepth(depth), toHandler(handler), null); } } catch (SVNException e) { throw new VcsException(e); } } - private SVNPropertyData getRevisionProperty(@NotNull SvnTarget target, @NotNull final String property, @Nullable SVNRevision revision) throws SVNException{ + private PropertyData getRevisionProperty(@NotNull SvnTarget target, @NotNull final String property, @Nullable SVNRevision revision) + throws SVNException { final SVNWCClient client = createClient(); - final SVNPropertyData[] result = new SVNPropertyData[1]; + final PropertyData[] result = new PropertyData[1]; ISVNPropertyHandler handler = new ISVNPropertyHandler() { @Override public void handleProperty(File path, SVNPropertyData property) throws SVNException { @@ -151,7 +179,7 @@ public class SvnKitPropertyClient extends BaseSvnClient implements PropertyClien private void handle(@NotNull SVNPropertyData data) { if (property.equals(data.getName())) { - result[0] = data; + result[0] = PropertyData.create(data); } } }; @@ -164,4 +192,41 @@ public class SvnKitPropertyClient extends BaseSvnClient implements PropertyClien return result[0]; } + + @Nullable + private static ISVNPropertyHandler toHandler(@Nullable final PropertyConsumer consumer) { + ISVNPropertyHandler result = null; + + if (consumer != null) { + result = new ISVNPropertyHandler() { + @Override + public void handleProperty(File path, SVNPropertyData property) throws SVNException { + consumer.handleProperty(path, PropertyData.create(property)); + } + + @Override + public void handleProperty(SVNURL url, SVNPropertyData property) throws SVNException { + consumer.handleProperty(url, PropertyData.create(property)); + } + + @Override + public void handleProperty(long revision, SVNPropertyData property) throws SVNException { + consumer.handleProperty(revision, PropertyData.create(property)); + } + }; + } + + return result; + } + + @Nullable + private static SVNPropertyValue toPropertyValue(@Nullable PropertyValue value) { + SVNPropertyValue result = null; + + if (value != null) { + result = SVNPropertyValue.create(value.toString()); + } + + return result; + } } |