Skip to content

Commit

Permalink
[#31] Implement listHistoryLog method
Browse files Browse the repository at this point in the history
Fixes #31
  • Loading branch information
ruspl-afed committed Jan 1, 2025
1 parent ab120ee commit d653539
Show file tree
Hide file tree
Showing 7 changed files with 381 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright (c) ArSysOp 2020-2025
*
* ArSysOp and its affiliates make no warranty of any kind
* with regard to this material.
*
* ArSysOp expressly disclaims all warranties as to the material, express,
* and implied, including but not limited to the implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of third
* party rights.
*
* In no event shall ArSysOp be liable to you or any other person for any damages,
* including, without limitation, any direct, indirect, incidental or consequential
* damages, expenses, lost profits, lost data or other damages arising out of the use,
* misuse or inability to use the material and any derived software, even if ArSysOp,
* its affiliate or an authorized dealer has been advised of the possibility of such damages.
*
*/

package ru.arsysop.svn.connector.internal.adapt;

import java.util.Arrays;
import java.util.Objects;
import java.util.function.Function;
import java.util.function.IntFunction;

public final class SvnNullableArray<S, T> extends SvnNullableConstructor<S[], T[]> {

private final IntFunction<T[]> array;
private final Function<S, T> adapter;

public SvnNullableArray(S[] source, IntFunction<T[]> array, Function<S, T> adapter) {
super(source);
this.array = Objects.requireNonNull(array);
this.adapter = Objects.requireNonNull(adapter);
}

@Override
protected T[] adapt(S[] source) {
return Arrays.stream(source)//
.map(adapter)//
.toArray(array);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Copyright (c) ArSysOp 2020-2025
*
* ArSysOp and its affiliates make no warranty of any kind
* with regard to this material.
*
* ArSysOp expressly disclaims all warranties as to the material, express,
* and implied, including but not limited to the implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of third
* party rights.
*
* In no event shall ArSysOp be liable to you or any other person for any damages,
* including, without limitation, any direct, indirect, incidental or consequential
* damages, expenses, lost profits, lost data or other damages arising out of the use,
* misuse or inability to use the material and any derived software, even if ArSysOp,
* its affiliate or an authorized dealer has been advised of the possibility of such damages.
*
*/

package ru.arsysop.svn.connector.internal.adapt.jhlsv;

import org.apache.subversion.javahl.types.ChangePath;
import org.eclipse.team.svn.core.connector.SVNLogPath;

import ru.arsysop.svn.connector.internal.adapt.SvnNullableConstructor;

public final class ChangePathAdapter extends SvnNullableConstructor<ChangePath, SVNLogPath> {

public ChangePathAdapter(ChangePath source) {
super(source);
}

@Override
protected SVNLogPath adapt(ChangePath source) {
return new SVNLogPath(//
source.getPath(), //
changeType(source.getAction()), //
source.getCopySrcPath(), //
source.getCopySrcRevision(), //
new TristateAdapter(source.getTextMods()).adapt(), //
new TristateAdapter(source.getPropMods()).adapt()//
);
}

private SVNLogPath.ChangeType changeType(org.apache.subversion.javahl.types.ChangePath.Action tAction) {
switch (tAction) {
case delete:
return SVNLogPath.ChangeType.DELETED;
case modify:
return SVNLogPath.ChangeType.MODIFIED;
case replace:
return SVNLogPath.ChangeType.REPLACED;
default:
return SVNLogPath.ChangeType.ADDED;
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* Copyright (c) ArSysOp 2020-2025
*
* ArSysOp and its affiliates make no warranty of any kind
* with regard to this material.
*
* ArSysOp expressly disclaims all warranties as to the material, express,
* and implied, including but not limited to the implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of third
* party rights.
*
* In no event shall ArSysOp be liable to you or any other person for any damages,
* including, without limitation, any direct, indirect, incidental or consequential
* damages, expenses, lost profits, lost data or other damages arising out of the use,
* misuse or inability to use the material and any derived software, even if ArSysOp,
* its affiliate or an authorized dealer has been advised of the possibility of such damages.
*
*/

package ru.arsysop.svn.connector.internal.adapt.jhlsv;

import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.TimeZone;

import org.eclipse.team.svn.core.connector.SVNProperty;

import ru.arsysop.svn.connector.internal.adapt.SvnNullableConstructor;

public final class RevPropertyConverter extends SvnNullableConstructor<Map<String, byte[]>, Map<String, Object>> {

private final SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS z"); //$NON-NLS-1$

public RevPropertyConverter(Map<String, byte[]> source) {
super(source);
}

@Override
protected Map<String, Object> adapt(Map<String, byte[]> source) {
Map<String, Object> result = new HashMap<>();
for (Entry<String, byte[]> entry : source.entrySet()) {
if (entry.getKey().equals(SVNProperty.BuiltIn.REV_DATE)) {
String raw = new String(entry.getValue());
Optional<Date> parsed = parseDate(raw);
if (parsed.isPresent()) {
result.put(SVNProperty.BuiltIn.REV_DATE, parsed.get());
} else {
//FIXME: AF: log?
}
} else {
result.put(entry.getKey(), new String(entry.getValue(), StandardCharsets.UTF_8));
}
}
return result;
}

private Optional<Date> parseDate(String raw) {
if (raw.length() != 27 || raw.charAt(26) != 'Z') {
return Optional.empty();
}
try {
Calendar date = Calendar.getInstance(TimeZone.getTimeZone("UTC")); //$NON-NLS-1$
date.setTime(formatter.parse(raw.substring(0, 23) + " UTC")); //$NON-NLS-1$
return Optional.of(date.getTime());
} catch (ParseException | NumberFormatException e) {
// uninteresting in this context
return Optional.empty();
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright (c) ArSysOp 2020-2025
*
* ArSysOp and its affiliates make no warranty of any kind
* with regard to this material.
*
* ArSysOp expressly disclaims all warranties as to the material, express,
* and implied, including but not limited to the implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of third
* party rights.
*
* In no event shall ArSysOp be liable to you or any other person for any damages,
* including, without limitation, any direct, indirect, incidental or consequential
* damages, expenses, lost profits, lost data or other damages arising out of the use,
* misuse or inability to use the material and any derived software, even if ArSysOp,
* its affiliate or an authorized dealer has been advised of the possibility of such damages.
*
*/

package ru.arsysop.svn.connector.internal.adapt.jhlsv;

import org.apache.subversion.javahl.types.Tristate;

import ru.arsysop.svn.connector.internal.adapt.SvnNullableConstructor;

public final class TristateAdapter extends SvnNullableConstructor<Tristate, Boolean> {

public TristateAdapter(Tristate source) {
super(source);
}

@Override
protected Boolean adapt(Tristate source) {
switch (source) {
case True:
return Boolean.TRUE;
case False:
return Boolean.FALSE;
default:
return null;
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*
* Copyright (c) 2023, 2025 ArSysOp
*
* 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.
*
* SPDX-License-Identifier: Apache-2.0
*
* Contributors:
* ArSysOp - initial API and implementation
*/

package ru.arsysop.svn.connector.internal.adapt.svjhl;

import java.util.Date;
import java.util.Map;
import java.util.Set;

import org.apache.subversion.javahl.callback.LogMessageCallback;
import org.eclipse.team.svn.core.connector.ISVNLogEntryCallback;
import org.eclipse.team.svn.core.connector.SVNLogEntry;
import org.eclipse.team.svn.core.connector.SVNLogPath;
import org.eclipse.team.svn.core.connector.SVNProperty;

import ru.arsysop.svn.connector.internal.adapt.SvnNullableArray;
import ru.arsysop.svn.connector.internal.adapt.SvnNullableConstructor;
import ru.arsysop.svn.connector.internal.adapt.jhlsv.ChangePathAdapter;
import ru.arsysop.svn.connector.internal.adapt.jhlsv.RevPropertyConverter;

public final class LogMessageCallbackAdapter extends SvnNullableConstructor<ISVNLogEntryCallback, LogMessageCallback> {

public LogMessageCallbackAdapter(ISVNLogEntryCallback source) {
super(source);
}

@Override
protected LogMessageCallback adapt(ISVNLogEntryCallback source) {
return new org.apache.subversion.javahl.callback.LogMessageCallback() {

@Override
public void singleMessage(Set<org.apache.subversion.javahl.types.ChangePath> paths, long revision,
Map<String, byte[]> revprops, boolean hasChildren) {
SVNLogEntry entry = convert(//
paths == null ? null : paths.toArray(org.apache.subversion.javahl.types.ChangePath[]::new), //
revision, //
revprops, //
hasChildren//
);
source.next(entry);
}

private SVNLogEntry convert(org.apache.subversion.javahl.types.ChangePath[] paths, long revision,
Map<String, byte[]> revprops, boolean hasChildren) {
if (revprops == null) {
// no access rights
return new SVNLogEntry(//
revision, //
0l, //
null, //
null, //
new SvnNullableArray<>(//
paths, //
SVNLogPath[]::new, ///
p -> new ChangePathAdapter(p).adapt()).adapt(), //
hasChildren);
}
Map<String, Object> converted = new RevPropertyConverter(revprops).adapt();
Date date = converted == null ? null : (Date) converted.get(SVNProperty.BuiltIn.REV_DATE);
return new SVNLogEntry(//
revision, //
date == null ? 0 : date.getTime(), //
converted == null ? null : (String) converted.get(SVNProperty.BuiltIn.REV_AUTHOR), //
converted == null ? null : (String) converted.get(SVNProperty.BuiltIn.REV_LOG), //
new SvnNullableArray<>(paths, SVNLogPath[]::new, p -> new ChangePathAdapter(p).adapt()).adapt(), //
hasChildren);
}

};
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright (c) ArSysOp 2020-2025
*
* ArSysOp and its affiliates make no warranty of any kind
* with regard to this material.
*
* ArSysOp expressly disclaims all warranties as to the material, express,
* and implied, including but not limited to the implied warranties of
* merchantability, fitness for a particular purpose and non-infringement of third
* party rights.
*
* In no event shall ArSysOp be liable to you or any other person for any damages,
* including, without limitation, any direct, indirect, incidental or consequential
* damages, expenses, lost profits, lost data or other damages arising out of the use,
* misuse or inability to use the material and any derived software, even if ArSysOp,
* its affiliate or an authorized dealer has been advised of the possibility of such damages.
*
*/

package ru.arsysop.svn.connector.internal.adapt.svjhl;

import org.apache.subversion.javahl.types.RevisionRange;
import org.eclipse.team.svn.core.connector.SVNRevisionRange;

import ru.arsysop.svn.connector.internal.adapt.SvnNullableConstructor;

public final class RevisionRangeAdapter extends SvnNullableConstructor<SVNRevisionRange, RevisionRange> {

public RevisionRangeAdapter(SVNRevisionRange source) {
super(source);
}

@Override
protected RevisionRange adapt(SVNRevisionRange source) {
return new org.apache.subversion.javahl.types.RevisionRange(//
new RevisionAdapter(source.from).adapt(), //
new RevisionAdapter(source.to).adapt());
}

}
Loading

0 comments on commit d653539

Please sign in to comment.