/**
* This file is part of git-as-svn. It is subject to the license terms
* in the LICENSE file found in the top-level directory of this distribution
* and at http://www.gnu.org/licenses/gpl-2.0.html. No part of git-as-svn,
* including this file, may be copied, modified, propagated, or distributed
* except according to the terms contained in the LICENSE file.
*/
package svnserver.repository.git.prop;
import org.eclipse.jgit.errors.InvalidPatternException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.tmatesoft.svn.core.SVNProperty;
import org.tmatesoft.svn.core.internal.wc.SVNFileUtil;
import svnserver.repository.git.path.Wildcard;
import svnserver.repository.git.path.matcher.path.AlwaysMatcher;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.PatternSyntaxException;
/**
* Factory for properties, generated by .gitattributes.
*
* @author Artem V. Navrotskiy <bozaro@users.noreply.github.com>
*/
@SuppressWarnings("UnusedDeclaration")
public final class GitAttributesFactory implements GitPropertyFactory {
@NotNull
private static final Logger log = LoggerFactory.getLogger(GitAttributesFactory.class);
@NotNull
private static final String EOL_PREFIX = "eol=";
@NotNull
private static final String FILTER_PREFIX = "filter=";
@NotNull
@Override
public String getFileName() {
return ".gitattributes";
}
@NotNull
@Override
public GitProperty[] create(@NotNull String content) throws IOException {
final List<GitProperty> properties = new ArrayList<>();
for (String line : content.split("(?:#[^\n]*)?\n")) {
final String[] tokens = line.trim().split("\\s+");
try {
final Wildcard wildcard = new Wildcard(tokens[0]);
processProperty(properties, wildcard, SVNProperty.MIME_TYPE, getMimeType(tokens));
processProperty(properties, wildcard, SVNProperty.EOL_STYLE, getEol(tokens));
final String filter = getFilter(tokens);
if (filter != null) {
properties.add(new GitFilterProperty(wildcard.getMatcher(), filter));
}
} catch (InvalidPatternException | PatternSyntaxException e) {
log.warn("Found invalid git pattern: {}", line);
}
}
return properties.toArray(new GitProperty[properties.size()]);
}
@NotNull
@Override
public GitProperty[] rootDefaults() {
return new GitProperty[]{
new GitFileProperty(AlwaysMatcher.INSTANCE, SVNProperty.EOL_STYLE, SVNProperty.EOL_STYLE_NATIVE)
};
}
private static void processProperty(@NotNull List<GitProperty> properties, @NotNull Wildcard wildcard, @NotNull String property, @Nullable String value) {
if (value == null) {
return;
}
if (!value.isEmpty()) {
if (wildcard.isSvnCompatible()) {
properties.add(new GitAutoProperty(wildcard.getMatcher(), property, value));
}
properties.add(new GitFileProperty(wildcard.getMatcher(), property, value));
} else {
properties.add(new GitFileProperty(wildcard.getMatcher(), property, null));
}
}
@Nullable
private String getMimeType(String[] tokens) {
for (int i = 1; i < tokens.length; ++i) {
String token = tokens[i];
if (token.startsWith("binary")) {
return SVNFileUtil.BINARY_MIME_TYPE;
}
if (token.startsWith("-binary")) {
return "";
}
if (token.startsWith("text")) {
return "";
}
}
return null;
}
@Nullable
private String getEol(String[] tokens) {
for (int i = 1; i < tokens.length; ++i) {
final String token = tokens[i];
if (token.startsWith(EOL_PREFIX)) {
switch (token.substring(EOL_PREFIX.length())) {
case "lf":
return SVNProperty.EOL_STYLE_LF;
case "native":
return SVNProperty.EOL_STYLE_NATIVE;
case "cr":
return SVNProperty.EOL_STYLE_CR;
case "crlf":
return SVNProperty.EOL_STYLE_CRLF;
}
}
if (token.startsWith("binary")) {
return "";
}
if (token.startsWith("-text")) {
return "";
}
}
return null;
}
@Nullable
private String getFilter(String[] tokens) {
for (int i = 1; i < tokens.length; ++i) {
final String token = tokens[i];
if (token.startsWith(FILTER_PREFIX)) {
return token.substring(FILTER_PREFIX.length());
}
}
return null;
}
}