47 Commits
Author SHA1 Message Date
lukasgol d5a42235fb status synchronizacji 2015-07-01 00:55:42 +02:00
Mariusz Pacek 40f955cdf2 update 2015-06-30 23:45:08 +02:00
Mariusz Pacek 76087834f9 update 2015-06-30 18:58:07 +02:00
Mariusz Pacek 3e599e889d update 2015-06-30 06:38:09 +02:00
Mariusz Pacek 142c16b272 Add
- sending configuration file
- get detailed info about repo
- tests
2015-06-26 20:01:19 +02:00
Marcin Michałek 29638dcf8d Refresh synchronization status component 2015-06-24 21:04:33 +02:00
Mariusz Pacek b4b90593c1 Add
- generating configuration file
- checking on remote server is svn installed
- test
2015-06-20 19:42:30 +02:00
Mariusz Pacek 70c22c517c Add
- file transfer
- some usefull class
- and some tests
2015-06-20 12:35:55 +02:00
Marcin Michałek 776061e077 Refactor 2015-06-19 12:30:07 +02:00
Marcin Michałek 3166e9ea51 Merge branch 'feature/Refresh_status_every_second' into develop 2015-06-19 12:27:35 +02:00
Marcin Michałek 49bfb1eab3 Start automatic updates after mirroring creation 2015-06-19 12:12:35 +02:00
Marcin Michałek 0ec0b75d94 Start updating status every 3 second after button click 2015-06-19 12:09:26 +02:00
Marcin Michałek cf790af560 Colors, add tooltip, layout improvements 2015-06-19 10:56:42 +02:00
Marcin Michałek 6f58bf9f3c Merge branch 'feature/Display_revision_list_and_details' into develop 2015-06-17 21:27:46 +02:00
Marcin Michałek 0dbe010964 Display revision details 2015-06-17 21:27:02 +02:00
Marcin Michałek 6c71843b2a Create abstract class for TextPane loggers 2015-06-17 21:26:48 +02:00
lukasgol 6a528d2435 status synchronizacji 2015-06-17 19:59:13 +02:00
lukasgol af2bc9ad0c podpiecie pod gui 2015-06-17 19:49:56 +02:00
lukasgol 290754e4ac Merge remote-tracking branch 'origin/develop' into develop 2015-06-17 19:26:37 +02:00
lukasgol a89817dc7b pobieranie listy rewizji 2015-06-17 19:26:24 +02:00
Marcin Michałek cc9dafc57f Merge branch 'feature/Enhanced_details_view' into develop 2015-06-17 19:20:32 +02:00
Marcin Michałek f595272065 Change layout manager, add dummy revisions to list 2015-06-17 19:19:47 +02:00
Marcin Michałek 3a49ca75a0 Add commit list component 2015-06-17 18:25:58 +02:00
lukasgol 700d553b11 pobieranie inf z repo 2015-06-17 00:46:21 +02:00
lukasgol 5339934d9d poprawki 2015-06-16 22:35:31 +02:00
lukasgol 33fa7bcf37 Merge remote-tracking branch 'origin/develop' into develop
Conflicts:
	src/main/java/com/svn/utils/mirror/SvnMirror.java
	src/main/java/com/svn/utils/mirror/app/Mirror.java
	src/main/java/com/svn/utils/mirror/gui/main/MainWindow.java
2015-06-16 21:19:24 +02:00
lukasgol 9345d91627 hooki 2015-06-16 21:16:59 +02:00
Marcin Michałek cb7ed3ed68 Graphics & layout improvements 2015-06-16 18:26:30 +02:00
Marcin Michałek 7031544ce5 Change text for attaching to exisitng repository, add repos/to gitignore 2015-06-16 18:06:12 +02:00
Marcin Michałek 6f4b3e56d4 Refactor 2015-06-16 18:01:52 +02:00
Marcin Michałek b438f52dec Merge branch 'feature/Connect_or_create_screen' into develop
Conflicts:
	src/main/java/com/svn/utils/mirror/gui/main/MainWindow.java
2015-06-16 17:54:58 +02:00
Marcin Michałek b10b495fa6 Fill data for combobox, adjust sizes 2015-06-16 17:53:01 +02:00
Marcin Michałek 752ba245a9 Add light symbol for synchronization status 2015-06-16 17:52:38 +02:00
Marcin Michałek 3ad019f44b Switch to english in GUI 2015-06-16 17:52:02 +02:00
Marcin Michałek 727b562e21 Create first screen - connect to existing or create repo mirroring 2015-06-16 15:22:17 +02:00
Mariusz Pacek ce3fe12e45 Add ssh command execution 2015-06-15 19:06:42 +02:00
Mariusz Pacek f548329a4a Add ssh command execution 2015-06-14 20:09:08 +02:00
lukasgol d94db5c55f inicjalizowanie synchronizacji 2015-06-14 18:12:50 +02:00
lukasgol 1413d28e74 Merge remote-tracking branch 'origin/develop' into develop
Conflicts:
	README.md
2015-06-14 15:19:34 +02:00
Marcin Michałek 479f5e6875 Merge branch 'feature/Create_local_repo' into develop 2015-06-12 15:52:30 +02:00
Marcin Michałek cfa1273c11 Extract logging messages to StatusLogger class 2015-06-12 15:52:01 +02:00
Marcin Michałek b60fe9359b Add j goodies, create local repository 2015-06-12 15:44:11 +02:00
marcin-michalek 4f18eb6858 Create README.md 2015-06-12 13:42:47 +02:00
Marcin Michałek e2be1f8b04 Merge branch 'feature/Main_application_GUI' into develop 2015-06-12 13:38:40 +02:00
Marcin Michałek fae7ad6a0a Fullscreen mode, refactor 2015-06-12 13:38:08 +02:00
Marcin Michałek d263013d4c Replace text area with text pane, add method which colors logs 2015-06-12 13:35:19 +02:00
Marcin Michałek c2de9f0340 Basic gui action 2015-06-12 13:28:36 +02:00
36 changed files with 2094 additions and 66 deletions

No files matched your search

+2 -1
View File
@@ -1,4 +1,5 @@
.idea/
build/
*.iml
.gradle
.gradle
/repos
+1 -1
View File
@@ -1,3 +1,3 @@
# SvnMirror
Using git-flow. Go to develop branch.
Java application which creates two svn repositories and sets up mirroring between them.
+3
View File
@@ -10,5 +10,8 @@ repositories {
}
dependencies {
compile 'org.tmatesoft.svnkit:svnkit:1.8.10'
compile 'com.jgoodies:forms:1.2.1'
compile 'com.jcraft:jsch:0.1.53'
testCompile group: 'junit', name: 'junit', version: '4.11'
}
@@ -1,6 +1,6 @@
package com.svn.utils.mirror;
import com.svn.utils.mirror.gui.MainWindow;
import com.svn.utils.mirror.gui.main.ConnectOrCreateWindow;
/**
* SvnMirror
@@ -8,6 +8,6 @@ import com.svn.utils.mirror.gui.MainWindow;
*/
public class SvnMirror {
public static void main(String[] args) {
new MainWindow("HelloWorldSwing");
new ConnectOrCreateWindow("SvnMirror");
}
}
@@ -0,0 +1,23 @@
package com.svn.utils.mirror.app;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNURL;
import java.io.IOException;
/**
* SvnMirror
* Created by Marcin on 2015-06-12.
*/
public interface CreateRepoInt {
void onRepoCreated(SVNURL svnurl);
void onRepoCreationException(SVNException e);
void onInitialization(Boolean b);
void onInitializationException(SVNException e);
void onSynchronization(Boolean b);
void onSynchronizationException(SVNException e);
void onHooksCreated(Boolean b);
void onHooksCreatedException(IOException e);
void onIsSyncedException(SVNException e);
void onException(Exception e);
}
@@ -0,0 +1,315 @@
package com.svn.utils.mirror.app;
import org.tmatesoft.svn.core.*;
import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
import org.tmatesoft.svn.core.io.SVNRepository;
import org.tmatesoft.svn.core.io.SVNRepositoryFactory;
import org.tmatesoft.svn.core.wc.SVNClientManager;
import org.tmatesoft.svn.core.wc.SVNWCUtil;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.*;
/**
* SvnMirror
* Created by Marcin on 2015-06-12.
*/
public final class Mirror {
private SVNRepository baseRepository;
private SVNURL baseRepositoryURL;
private SVNRepository mirrorRepository;
private SVNURL mirrorRepositoryURL;
private SVNClientManager svnClientManager;
private static Mirror mirror;
public static Mirror getInstance() {
if (mirror == null) {
mirror = new Mirror();
mirror.init();
}
return mirror;
}
private Mirror() {
}
public void init() {
svnClientManager = SVNClientManager.newInstance();
}
public void initializeAndCreateRepoMirroring(String sourceRepoPath, String destinationRepoPath,
CreateRepoInt createRepoInt) {
mirror.createBaseRepo(sourceRepoPath, createRepoInt);
mirror.createMirrorRepo(destinationRepoPath, createRepoInt);
mirror.initializeRepository(createRepoInt);
mirror.synchronize(createRepoInt);
mirror.createHooks(createRepoInt);
}
public SVNURL createRepo(String name) throws SVNException {
SVNURL url = SVNRepositoryFactory.createLocalRepository(new File("repos/" + name), true, true);
return url;
}
public SVNURL createBaseRepo(String name) throws SVNException {
baseRepositoryURL = createRepo(name);
baseRepository = SVNRepositoryFactory.create(baseRepositoryURL);
return baseRepositoryURL;
}
public SVNURL createMirrorRepo(String name) throws SVNException {
mirrorRepositoryURL = createRepo(name);
mirrorRepository = SVNRepositoryFactory.create(mirrorRepositoryURL);
return mirrorRepositoryURL;
}
public void loadBaseRepository(SVNURL url) throws SVNException {
baseRepository = SVNRepositoryFactory.create(url);
//authenticate(mirrorRepository, name, password);
}
public void loadMirrorRepository(SVNURL url) throws SVNException {
mirrorRepository = SVNRepositoryFactory.create(url);
//authenticate(mirrorRepository, name, password);
}
public void loadBaseRepositoryURL(String url) throws SVNException {
baseRepositoryURL = SVNURL.fromFile(new File(url));
loadBaseRepository(baseRepositoryURL);
}
public void loadMirrorRepositoryURL(String url) throws SVNException {
mirrorRepositoryURL = SVNURL.fromFile(new File(url));
loadMirrorRepository(mirrorRepositoryURL);
}
public void authenticate(SVNRepository repository, String name, String password) {
ISVNAuthenticationManager authManager =
SVNWCUtil.createDefaultAuthenticationManager(name, password);
repository.setAuthenticationManager(authManager);
}
private void initializeRepository(SVNURL fromRepos, SVNURL toRepos) throws SVNException {
svnClientManager.getAdminClient().doInitialize(baseRepositoryURL, mirrorRepositoryURL);
}
public void initializeRepository(CreateRepoInt createRepoInt) {
try {
initializeRepository(baseRepositoryURL, mirrorRepositoryURL);
createRepoInt.onInitialization(true);
} catch (SVNException e) {
createRepoInt.onInitializationException(e);
}
}
public void initializeRepository() throws SVNException {
initializeRepository(baseRepositoryURL, mirrorRepositoryURL);
}
public void synchronize(SVNURL fromRepos, SVNURL toRepos) throws SVNException {
svnClientManager.getAdminClient().doSynchronize(toRepos);
}
public void synchronize() throws SVNException {
synchronize(baseRepositoryURL, mirrorRepositoryURL);
}
public void synchronize(CreateRepoInt createRepoInt) {
try {
synchronize(baseRepositoryURL, mirrorRepositoryURL);
createRepoInt.onSynchronization(true);
} catch (SVNException e) {
createRepoInt.onSynchronizationException(e);
}
}
public void createHooks() throws IOException {
String text = "#!/bin/sh \n" +
"svnsync --non-interactive sync " +
"file://" + mirrorRepositoryURL.getURIEncodedPath()+"\n"+
"REPOS=\"$1\"\n" +
"REV=\"$2\"\n" +
"AUTHOR=\"$(svnlook author $REPOS -r $REV)\"\n" +
"MESSAGE=\"$(svnlook propget --revprop -r $REV $REPOS svn:log)\"\n" +
"cat \"$AUTHOR\"\n" +
"cat \"$MESSAGE\"\n" +
"DATA=`date +%s000`\n" +
"STATUS=\"$(svnlook changed -r $REV $REPOS)\"\n" +
"echo \"dupa\"\n" +
"cat $(curl --header \"Authorization: key=AIzaSyB6Zy10TbyLBxGsv5lhBQr7KbfA5s_Jq8g\" --header Content-Type:\"application/json\" https://android.googleapis.com/gcm/send -d '{\"registration_ids\":[\"APA91bFZ7yy2qSGGsTve-Op0hDjP7ZrgOI71kvOOVuzvw6xRYGWe2YasOKRKjrCxTh0YhPjYXIFqxungZUKTHxbRfrUZZ4CSJ_PdBFa7TjnA-oUKJGCrwIuHnfl1E0HUMMTcJszQT9UbxPk9lOAfWQVnzlT4Cgc3ZQ\"], \"data\":{\"author\":\"'\"$AUTHOR\"'\",\"name\":\"'\"$MESSAGE\"'\",\"date\":\"'\"$DATA\"'\",\"status\":\"'\"$STATUS\"'\"}}')\n" +
"exit 0;";
File file = new File(baseRepositoryURL.getURIEncodedPath() + "/hooks/post-commit");
BufferedWriter output = null;
try {
file.createNewFile();
file.setExecutable(true);
output = new BufferedWriter(new FileWriter(file));
output.write(text);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (output != null) output.close();
}
}
public void createHooks(CreateRepoInt createRepoInt) {
try {
createHooks();
createRepoInt.onHooksCreated(true);
} catch (IOException e) {
createRepoInt.onHooksCreatedException(e);
}
}
public void createBaseRepo(String name, CreateRepoInt createRepoInt) {
try {
SVNURL svnURL = createBaseRepo(name);
createRepoInt.onRepoCreated(svnURL);
} catch (SVNException e) {
createRepoInt.onRepoCreationException(e);
}
}
public void createMirrorRepo(String name, CreateRepoInt createRepoInt) {
try {
SVNURL svnURL = createMirrorRepo(name);
createRepoInt.onRepoCreated(svnURL);
} catch (SVNException e) {
createRepoInt.onRepoCreationException(e);
}
}
long getRevison(SVNRepository repository) throws SVNException {
return repository.getLatestRevision();
}
long getMirrorRevison() throws SVNException {
return mirrorRepository.getLatestRevision();
}
long getBaseRevison() throws SVNException {
return baseRepository.getLatestRevision();
}
public boolean isSynced() throws SVNException {
return getBaseRevison() == getMirrorRevison();
}
public boolean isSynced(CreateRepoInt createRepoInt) {
boolean b = false;
try {
b = getBaseRevison() == getMirrorRevison();
} catch (SVNException e) {
createRepoInt.onIsSyncedException(e);
}
return b;
}
public String listEntries(String path) throws SVNException {
Collection entries = baseRepository.getDir(path, -1, null, (Collection) null);
Iterator iterator = entries.iterator();
String output = "";
while (iterator.hasNext()) {
SVNDirEntry entry = (SVNDirEntry) iterator.next();
output += ("/" + (path.equals("") ? "" : path + "/") + entry.getName() +
" ( author: '" + entry.getAuthor() + "'; revision: " + entry.getRevision() +
"; date: " + entry.getDate() + ")\n");
if (entry.getKind() == SVNNodeKind.DIR) {
listEntries((path.equals("")) ? entry.getName() : path + "/" + entry.getName());
}
}
return output;
}
String getHistory(long startRevision, long endRevision) throws SVNException {
String history = "";
Collection logEntries = null;
logEntries = baseRepository.log(new String[]{""}, null, startRevision, endRevision, true, true);
for (Iterator entries = logEntries.iterator(); entries.hasNext(); ) {
SVNLogEntry logEntry = (SVNLogEntry) entries.next();
history += "\n---------------------------------------------\n";
history += "\nrevision: " + logEntry.getRevision();
history += "\nauthor: " + logEntry.getAuthor();
history += "\ndate: " + logEntry.getDate();
history += "\nlog message: " + logEntry.getMessage();
if (logEntry.getChangedPaths().size() > 0) {
history += "\nchanged paths:";
Set changedPathsSet = logEntry.getChangedPaths().keySet();
for (Iterator changedPaths = changedPathsSet.iterator(); changedPaths.hasNext(); ) {
SVNLogEntryPath entryPath = (SVNLogEntryPath) logEntry.getChangedPaths().get(changedPaths.next());
String a = " "
+ entryPath.getType()
+ " "
+ entryPath.getPath()
+ ((entryPath.getCopyPath() != null) ? " (from "
+ entryPath.getCopyPath() + " revision "
+ entryPath.getCopyRevision() + ")" : "");
history += a;
}
}
}
return history;
}
public Revision getRevision(int i) throws SVNException {
return getRevisions().get(i);
}
public List<Revision> getRevisions() throws SVNException {
List<Revision> list = new ArrayList<>();
Collection logEntries = null;
logEntries = baseRepository.log(new String[]{""}, null, 0, -1, true, true);
for (Iterator entries = logEntries.iterator(); entries.hasNext(); ) {
Revision revision = new Revision();
SVNLogEntry logEntry = (SVNLogEntry) entries.next();
revision.setId(logEntry.getRevision());
revision.setAuthor(logEntry.getAuthor());
revision.setDate(logEntry.getDate());
revision.setMessage(logEntry.getMessage());
if (logEntry.getChangedPaths().size() > 0) {
String info = "";
Set changedPathsSet = logEntry.getChangedPaths().keySet();
for (Iterator changedPaths = changedPathsSet.iterator(); changedPaths.hasNext(); ) {
SVNLogEntryPath entryPath = (SVNLogEntryPath) logEntry.getChangedPaths().get(changedPaths.next());
String a = " "
+ entryPath.getType()
+ " "
+ entryPath.getPath()
+ ((entryPath.getCopyPath() != null) ? " (from "
+ entryPath.getCopyPath() + " revision "
+ entryPath.getCopyRevision() + ")" : "");
info += a;
}
revision.setChanges(info);
}
list.add(revision);
}
return list;
}
String getHistory() throws SVNException {
return getHistory(0, -1);
}
public static void main(String[] args) throws SVNException {
Mirror mirror = Mirror.getInstance();
mirror.loadBaseRepositoryURL("repos/base/");
mirror.loadMirrorRepositoryURL("repos/mirror");
for (Revision r : mirror.getRevisions()) {
System.out.println(r);
}
System.out.println(mirror.getRevision(3));
}
}
@@ -0,0 +1,71 @@
package com.svn.utils.mirror.app;
import java.util.Date;
/**
* Created by lukasgol on 17.06.15.
*/
public class Revision {
long id;
String author;
Date date;
String message;
String changes;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getChanges() {
return changes;
}
public void setChanges(String changes) {
this.changes = changes;
}
@Override
public String toString() {
return id + " - " + message;
}
public String getInfo() {
String info = "";
info += "\n---------------------------------------------\n";
info += "\nrevision: " + getId();
info += "\nauthor: " + getAuthor();
info += "\ndate: " + getDate();
info += "\nlog message: " + getMessage();
info += "\nchanged paths:" + getChanges();
return info;
}
}
@@ -0,0 +1,99 @@
package com.svn.utils.mirror.app.remote;
import javax.naming.ConfigurationException;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.util.HashMap;
import java.util.Map;
/**
* Created by mar on 19.06.15.
*/
public class Configuration {
private static final String FINAL_CONFIGURATION_FILE =
"#!/bin/bash\n" +
"\n" +
"\n" +
"svnadmin create @REPO_NAME\n" +
"\n" +
"\n";
private static final String FILE_NAME = "./conf.sh";
private static final String REPO_NAME = "@REPO_NAME";
private static final String SVN_SERVER_PATH = "@SVN_SERVER_PATH";
private static final String HOOK_NAME = "@HOOK_NAME";
private static final String HOOK_CONF = "@HOOK_CONF";
private Map<String, String> properties;
private Map<String, String> hookConfiguration;
public Configuration() {
properties = new HashMap<>();
hookConfiguration = new HashMap<>();
}
public Configuration addRepoName(String name) {
if (properties.containsKey(REPO_NAME))
properties.replace(REPO_NAME, name);
else
properties.put(REPO_NAME, name);
return this;
}
public Configuration addSVNServerPath(String path) {
if (properties.containsKey(SVN_SERVER_PATH))
properties.replace(SVN_SERVER_PATH, path);
else
properties.put(SVN_SERVER_PATH, path);
return this;
}
public Configuration addHookConfig(String hookBody, String name) {
hookConfiguration.put(name, hookBody);
return this;
}
public void clearHooks() {
hookConfiguration.clear();
}
public void clearProperties() {
properties.clear();
}
public File build() throws ConfigurationException {
File configurationFile = new File(FILE_NAME);
String configurationBody = FINAL_CONFIGURATION_FILE;
for (Map.Entry<String, String> entry : properties.entrySet()) {
configurationBody = configurationBody.replace(entry.getKey(), entry.getValue());
}
String names = "";
String confs = "";
for (Map.Entry<String, String> entry : hookConfiguration.entrySet()) {
names += entry.getKey() + ";";
confs += entry.getValue() + ";";
}
configurationBody = configurationBody.replace(HOOK_NAME, names);
configurationBody = configurationBody.replace(HOOK_CONF, confs);
try (PrintStream out = new PrintStream(new FileOutputStream(FILE_NAME))) {
out.print(configurationBody);
} catch (FileNotFoundException e) {
throw new ConfigurationException("Cannot find file " + FILE_NAME);
}
return configurationFile;
}
public String getRepoName(){
return properties.get(REPO_NAME);
}
}
@@ -0,0 +1,16 @@
package com.svn.utils.mirror.app.remote;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.wc.ISVNDiffStatusHandler;
import org.tmatesoft.svn.core.wc.ISVNStatusHandler;
import org.tmatesoft.svn.core.wc.SVNStatus;
/**
* Created by mar on 19.06.15.
*/
public class HandleSvnStatus implements ISVNStatusHandler {
@Override
public void handleStatus(SVNStatus status) throws SVNException {
//to do get info
}
}
@@ -0,0 +1,308 @@
package com.svn.utils.mirror.app.remote;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.SftpException;
import com.svn.utils.mirror.app.CreateRepoInt;
import com.svn.utils.mirror.app.Revision;
import com.svn.utils.mirror.app.remote.ssh.CommandNotFoundException;
import com.svn.utils.mirror.app.remote.ssh.SshConnect;
import org.tmatesoft.svn.core.*;
import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
import org.tmatesoft.svn.core.io.SVNRepository;
import org.tmatesoft.svn.core.io.SVNRepositoryFactory;
import org.tmatesoft.svn.core.wc.SVNClientManager;
import org.tmatesoft.svn.core.wc.SVNWCUtil;
import javax.naming.ConfigurationException;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.*;
/**
* Created by mar on 29.06.15.
*/
public final class RemoteMirror {
private SVNRepository baseRepository;
private SVNRepository mirrorRepository;
private SVNURL baseRepositoryURL;
private SVNURL mirrorRepositoryURL;
private SVNClientManager svnClientManager;
private static RemoteMirror remoteMirror;
public static RemoteMirror getInstance(){
if(remoteMirror==null){
remoteMirror=new RemoteMirror();
remoteMirror.init();
}
return remoteMirror;
}
public void init() {
svnClientManager = SVNClientManager.newInstance();
}
public void initializeAndCreateRepoMirroring(String user,String password,String host,String sourceRepoPath, String destinationRepoPath,
CreateRepoInt createRepoInt) {
setUpRemoteMirrorRepo(user,password,host,destinationRepoPath,createRepoInt);
remoteMirror.createBaseRepo(sourceRepoPath, createRepoInt);
remoteMirror.initializeRepository(createRepoInt);
remoteMirror.synchronize(createRepoInt);
remoteMirror.createHooks(createRepoInt);
}
public void setUpRemoteMirrorRepo(String user, String password, String host, String name, CreateRepoInt createRepoInt){
Configuration conf = new Configuration();
conf.addRepoName(name);
try {
SshConnect connect = new SshConnect(user,password,host);
connect.sendFile(conf.build());
List<String> result = connect.executeCommands(new ArrayList<String>(){
{
add("sh conf.sh");
add("rm conf.sh");
}
});
mirrorRepositoryURL = SVNURL.parseURIDecoded("svn://"+host+"/"+name);
mirrorRepository = SVNRepositoryFactory.create(mirrorRepositoryURL);
ISVNAuthenticationManager authManager = SVNWCUtil.createDefaultAuthenticationManager(user,password);
mirrorRepository.setAuthenticationManager(authManager);
createRepoInt.onRepoCreated(mirrorRepositoryURL);
} catch (Exception e) {
createRepoInt.onException(e);
}
}
public void loadMirrorRepository(SVNURL url) throws SVNException {
mirrorRepository = SVNRepositoryFactory.create(url);
}
public SVNURL createBaseRepo(String name) throws SVNException {
SVNURL url = SVNRepositoryFactory.createLocalRepository(new File("repos/" + name), true, true);
baseRepositoryURL = url;
baseRepository = SVNRepositoryFactory.create(baseRepositoryURL);
return baseRepositoryURL;
}
public void loadBaseRepository(SVNURL url) throws SVNException {
baseRepository = SVNRepositoryFactory.create(url);
//authenticate(mirrorRepository, name, password);
}
public void loadBaseRepositoryURL(String url) throws SVNException {
baseRepositoryURL = SVNURL.fromFile(new File(url));
loadBaseRepository(baseRepositoryURL);
}
public void loadMirrorRepositoryURL(String host, String user,String password,String repoName) throws SVNException {
mirrorRepositoryURL = SVNURL.parseURIDecoded("svn://" + host + "/" + repoName);
loadMirrorRepository(mirrorRepositoryURL);
}
public void authenticate(SVNRepository repository, String name, String password) {
ISVNAuthenticationManager authManager =
SVNWCUtil.createDefaultAuthenticationManager(name, password);
repository.setAuthenticationManager(authManager);
}
private void initializeRepository(SVNURL fromRepos, SVNURL toRepos) throws SVNException {
svnClientManager = svnClientManager.newInstance(null,"svn","svn");
svnClientManager.getAdminClient().doInitialize(baseRepositoryURL, mirrorRepositoryURL);
}
public void initializeRepository(CreateRepoInt createRepoInt) {
try {
initializeRepository(baseRepositoryURL, mirrorRepositoryURL);
createRepoInt.onInitialization(true);
} catch (SVNException e) {
createRepoInt.onInitializationException(e);
}
}
public void initializeRepository() throws SVNException {
initializeRepository(baseRepositoryURL, mirrorRepositoryURL);
}
public void synchronize(SVNURL fromRepos, SVNURL toRepos) throws SVNException {
svnClientManager.getAdminClient().doSynchronize(toRepos);
}
public void synchronize() throws SVNException {
synchronize(baseRepositoryURL, mirrorRepositoryURL);
}
public void synchronize(CreateRepoInt createRepoInt) {
try {
synchronize(baseRepositoryURL, mirrorRepositoryURL);
createRepoInt.onSynchronization(true);
} catch (SVNException e) {
createRepoInt.onSynchronizationException(e);
}
}
public void createBaseRepo(String name, CreateRepoInt createRepoInt) {
try {
SVNURL svnURL = createBaseRepo(name);
createRepoInt.onRepoCreated(svnURL);
} catch (SVNException e) {
createRepoInt.onRepoCreationException(e);
}
}
public void createHooks() throws IOException {
String text = "#!/bin/sh \n" +
"svnsync --non-interactive sync " +
"file://" + mirrorRepositoryURL.getURIEncodedPath();
File file = new File(baseRepositoryURL.getURIEncodedPath() + "/hooks/post-commit");
BufferedWriter output = null;
try {
file.createNewFile();
file.setExecutable(true);
output = new BufferedWriter(new FileWriter(file));
output.write(text);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (output != null) output.close();
}
}
public void createHooks(CreateRepoInt createRepoInt) {
try {
createHooks();
createRepoInt.onHooksCreated(true);
} catch (IOException e) {
createRepoInt.onHooksCreatedException(e);
}
}
long getRevison(SVNRepository repository) throws SVNException {
return repository.getLatestRevision();
}
long getMirrorRevison() throws SVNException {
return mirrorRepository.getLatestRevision();
}
long getBaseRevison() throws SVNException {
return baseRepository.getLatestRevision();
}
public boolean isSynced() throws SVNException {
return getBaseRevison() == getMirrorRevison();
}
public boolean isSynced(CreateRepoInt createRepoInt) {
boolean b = false;
try {
b = getBaseRevison() == getMirrorRevison();
} catch (SVNException e) {
createRepoInt.onIsSyncedException(e);
}
return b;
}
public String listEntries(String path) throws SVNException {
Collection entries = baseRepository.getDir(path, -1, null, (Collection) null);
Iterator iterator = entries.iterator();
String output = "";
while (iterator.hasNext()) {
SVNDirEntry entry = (SVNDirEntry) iterator.next();
output += ("/" + (path.equals("") ? "" : path + "/") + entry.getName() +
" ( author: '" + entry.getAuthor() + "'; revision: " + entry.getRevision() +
"; date: " + entry.getDate() + ")\n");
if (entry.getKind() == SVNNodeKind.DIR) {
listEntries((path.equals("")) ? entry.getName() : path + "/" + entry.getName());
}
}
return output;
}
String getHistory(long startRevision, long endRevision) throws SVNException {
String history = "";
Collection logEntries = null;
logEntries = baseRepository.log(new String[]{""}, null, startRevision, endRevision, true, true);
for (Iterator entries = logEntries.iterator(); entries.hasNext(); ) {
SVNLogEntry logEntry = (SVNLogEntry) entries.next();
history += "\n---------------------------------------------\n";
history += "\nrevision: " + logEntry.getRevision();
history += "\nauthor: " + logEntry.getAuthor();
history += "\ndate: " + logEntry.getDate();
history += "\nlog message: " + logEntry.getMessage();
if (logEntry.getChangedPaths().size() > 0) {
history += "\nchanged paths:";
Set changedPathsSet = logEntry.getChangedPaths().keySet();
for (Iterator changedPaths = changedPathsSet.iterator(); changedPaths.hasNext(); ) {
SVNLogEntryPath entryPath = (SVNLogEntryPath) logEntry.getChangedPaths().get(changedPaths.next());
String a = " "
+ entryPath.getType()
+ " "
+ entryPath.getPath()
+ ((entryPath.getCopyPath() != null) ? " (from "
+ entryPath.getCopyPath() + " revision "
+ entryPath.getCopyRevision() + ")" : "");
history += a;
}
}
}
return history;
}
public Revision getRevision(int i) throws SVNException {
return getRevisions().get(i);
}
public List<Revision> getRevisions() throws SVNException {
List<Revision> list = new ArrayList<>();
Collection logEntries = null;
logEntries = baseRepository.log(new String[]{""}, null, 0, -1, true, true);
for (Iterator entries = logEntries.iterator(); entries.hasNext(); ) {
Revision revision = new Revision();
SVNLogEntry logEntry = (SVNLogEntry) entries.next();
revision.setId(logEntry.getRevision());
revision.setAuthor(logEntry.getAuthor());
revision.setDate(logEntry.getDate());
revision.setMessage(logEntry.getMessage());
if (logEntry.getChangedPaths().size() > 0) {
String info = "";
Set changedPathsSet = logEntry.getChangedPaths().keySet();
for (Iterator changedPaths = changedPathsSet.iterator(); changedPaths.hasNext(); ) {
SVNLogEntryPath entryPath = (SVNLogEntryPath) logEntry.getChangedPaths().get(changedPaths.next());
String a = " "
+ entryPath.getType()
+ " "
+ entryPath.getPath()
+ ((entryPath.getCopyPath() != null) ? " (from "
+ entryPath.getCopyPath() + " revision "
+ entryPath.getCopyRevision() + ")" : "");
info += a;
}
revision.setChanges(info);
}
list.add(revision);
}
return list;
}
String getHistory() throws SVNException {
return getHistory(0, -1);
}
}
@@ -0,0 +1,11 @@
package com.svn.utils.mirror.app.remote.ssh;
/**
* Created by mar on 20.06.15.
*/
public class CommandNotFoundException extends Exception {
public CommandNotFoundException(String msg){
super(msg);
}
}
@@ -0,0 +1,67 @@
package com.svn.utils.mirror.app.remote.ssh;
import com.svn.utils.mirror.app.Revision;
import org.tmatesoft.svn.core.*;
import org.tmatesoft.svn.core.auth.BasicAuthenticationManager;
import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
import org.tmatesoft.svn.core.io.SVNRepository;
import org.tmatesoft.svn.core.io.SVNRepositoryFactory;
import org.tmatesoft.svn.core.wc.SVNStatus;
import org.tmatesoft.svn.core.wc.SVNStatusClient;
import org.tmatesoft.svn.core.wc.SVNWCUtil;
import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.*;
/**
* Created by mar on 19.06.15.
*/
public class ConnectToRemoteSVN {
private SVNRepository repository;
public ConnectToRemoteSVN(String user, String password, String url) throws URISyntaxException, SVNException {
repository = SVNRepositoryFactory.create(SVNURL.parseURIDecoded(url));
ISVNAuthenticationManager authManager = SVNWCUtil.createDefaultAuthenticationManager(user,password);
repository.setAuthenticationManager(authManager);
}
public List<Revision> getRevisions() throws SVNException {
List<Revision> list = new ArrayList<>();
Collection logEntries = null;
logEntries = repository.log(new String[]{""}, null, 0, -1, true, true);
for (Iterator entries = logEntries.iterator(); entries.hasNext(); ) {
Revision revision = new Revision();
SVNLogEntry logEntry = (SVNLogEntry) entries.next();
revision.setId(logEntry.getRevision());
revision.setAuthor(logEntry.getAuthor());
revision.setDate(logEntry.getDate());
revision.setMessage(logEntry.getMessage());
if (logEntry.getChangedPaths().size() > 0) {
String info = "";
Set changedPathsSet = logEntry.getChangedPaths().keySet();
for (Iterator changedPaths = changedPathsSet.iterator(); changedPaths.hasNext(); ) {
SVNLogEntryPath entryPath = (SVNLogEntryPath) logEntry.getChangedPaths().get(changedPaths.next());
String a = " "
+ entryPath.getType()
+ " "
+ entryPath.getPath()
+ ((entryPath.getCopyPath() != null) ? " (from "
+ entryPath.getCopyPath() + " revision "
+ entryPath.getCopyRevision() + ")" : "");
info += a;
}
revision.setChanges(info);
}
list.add(revision);
}
return list;
}
}
@@ -0,0 +1,114 @@
package com.svn.utils.mirror.app.remote.ssh;
import com.jcraft.jsch.*;
import com.svn.utils.mirror.app.remote.Configuration;
import javax.naming.ConfigurationException;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
/**
* Created by mar on 14.06.15.
*/
public class SshConnect {
private Session session;
private static final String CAN_CREATE_REPO = "svnadmin --version";
private final String user;
private final String host;
private final String password;
public SshConnect(String user, String password, String host) throws JSchException {
this.password = password;
this.host = host;
this.user = user;
}
private void createSession() throws JSchException {
if(session!=null)
session.disconnect();
JSch jSch = new JSch();
session = jSch.getSession(user, host);
session.setPassword(password);
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
}
public void sendFile(File configuration) throws JSchException, IOException, SftpException, CommandNotFoundException, ConfigurationException {
createSession();
session.connect();
Channel channel = session.openChannel("exec");
channel.connect();
execute(channel,CAN_CREATE_REPO);
channel.disconnect();
channel = session.openChannel("sftp");
channel.connect();
ChannelSftp channelSftp = (ChannelSftp)channel;
File configurationFile = configuration;
channelSftp.put(new FileInputStream(configurationFile),configuration.getName());
channel.disconnect();
session.disconnect();
}
public List<String> executeCommands(List<String> commands) throws CommandNotFoundException {
List<String> result = new ArrayList<>(commands.size());
try {
createSession();
session.connect();
for (String command : commands) {
Channel channel = session.openChannel("exec");
result.add(execute(channel, command));
}
session.disconnect();
} catch (JSchException e) {
e.printStackTrace();
System.out.println(e.getCause().getMessage());
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
public boolean isConnected() {
return session.isConnected();
}
private String execute(Channel channel, String command) throws JSchException, IOException, CommandNotFoundException {
((ChannelExec) channel).setCommand(command);
channel.setInputStream(null);
((ChannelExec) channel).setErrStream(System.err);
InputStream in = channel.getInputStream();
channel.connect();
byte[] tmp = new byte[1024];
String returnMessage = null;
while (true) {
while (in.available() > 0) {
int i = in.read(tmp, 0, 1024);
if (i < 0) break;
returnMessage += new String(tmp, 0, i);
}
if (channel.isClosed()) {
if (in.available() > 0) continue;
System.out.println("exit-status: " + channel.getExitStatus());
if(channel.getExitStatus() != 0)
throw new CommandNotFoundException("Command " + command + " on remote host");
break;
}
}
channel.disconnect();
return returnMessage;
}
public void close() {
session.disconnect();
}
public Session getSession() {
return session;
}
}
@@ -0,0 +1,50 @@
package com.svn.utils.mirror.app.util;
import org.tmatesoft.svn.core.*;
import org.tmatesoft.svn.core.wc.SVNClientManager;
import org.tmatesoft.svn.core.wc.SVNDiffClient;
import org.tmatesoft.svn.core.wc.SVNRevision;
import org.tmatesoft.svn.core.wc.SVNWCClient;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
/**
* Created by mar on 19.06.15.
*/
public class Diff {
private SVNClientManager manager;
public Diff(File repoRoot){
manager = SVNClientManager.newInstance();
}
public String getDiff(File repo) throws SVNException {
File baseDirectory = new File("/home/mar");
File wcRoot = new File(baseDirectory, "exampleWC/iota");
SVNClientManager clientManager = SVNClientManager.newInstance();
//SVNWCClient wcClient = SVNClientManager.newInstance().getWCClient();
//wcClient.doSetProperty(new File(wcRoot, "A/B"), "spam", SVNPropertyValue.create("egg"), false,
// SVNDepth.EMPTY, null, null);
//now run diff the working copy against the repository
SVNDiffClient diffClient = clientManager.getDiffClient();
/*
* This corresponds to 'svn diff -rHEAD'.
*/
diffClient.doDiff(wcRoot, SVNRevision.WORKING, SVNRevision.PREVIOUS, SVNRevision.HEAD,
SVNDepth.INFINITY, true, System.out, null);
return null;
}
}
@@ -1,39 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.svn.utils.mirror.gui.MainWindow">
<grid id="27dc6" binding="rootPanel" layout-manager="GridLayoutManager" row-count="3" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="20" y="20" width="500" height="400"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<hspacer id="24bb7">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
</hspacer>
<vspacer id="5dae">
<constraints>
<grid row="1" column="0" row-span="2" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
<component id="2b3b0" class="javax.swing.JButton" binding="helloButton" default-binding="true">
<constraints>
<grid row="2" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Hello"/>
</properties>
</component>
<component id="a2a37" class="javax.swing.JButton" binding="button1" default-binding="true">
<constraints>
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Button"/>
</properties>
</component>
</children>
</grid>
</form>
@@ -1,23 +0,0 @@
package com.svn.utils.mirror.gui;
import javax.swing.*;
import java.awt.*;
/**
* SvnMirror
* Created by Marcin on 2015-06-12.
*/
public class MainWindow extends JFrame {
private JButton helloButton;
private JButton button1;
private JPanel rootPanel;
public MainWindow(String title) throws HeadlessException {
super(title);
setContentPane(rootPanel);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
pack();
setVisible(true);
}
}
@@ -0,0 +1,10 @@
package com.svn.utils.mirror.gui.enums;
/**
* SvnMirror
* Created by Marcin on 2015-06-16.
*/
public enum RepoAction {
CONNECT_TO_EXISTING_REPO_MIRROR,
CREATE_NEW_REPO_MIRROR
}
@@ -0,0 +1,10 @@
package com.svn.utils.mirror.gui.enums;
/**
* SvnMirror
* Created by Marcin on 2015-06-16.
*/
public enum RepositoryType {
LOCAL,
REMOTE
}
@@ -0,0 +1,21 @@
package com.svn.utils.mirror.gui.enums;
/**
* SvnMirror
* Created by Marcin on 2015-06-16.
*/
public enum SynchronizationStatus {
SYNCHRONIZED,
NOT_SYNCHRONIZED,
WAITING_FOR_FEEDBACK;
@Override
public String toString() {
if (this == WAITING_FOR_FEEDBACK) {
return "WAITING";
} else {
return super.toString();
}
}
}
@@ -0,0 +1,31 @@
package com.svn.utils.mirror.gui.logger;
import javax.swing.*;
import javax.swing.text.AttributeSet;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;
import java.awt.*;
/**
* SvnMirror
* Created by Marcin on 2015-06-17.
*/
public abstract class AbstractTextPaneLogger {
protected JTextPane logContainer;
protected void appendToPane(String message, Color color) {
StyleContext styleContext = StyleContext.getDefaultStyleContext();
AttributeSet attributeSet = styleContext.addAttribute(SimpleAttributeSet.EMPTY, StyleConstants.Foreground, color);
attributeSet = styleContext.addAttribute(attributeSet, StyleConstants.FontFamily, "Lucida Console");
attributeSet = styleContext.addAttribute(attributeSet, StyleConstants.Alignment, StyleConstants.ALIGN_JUSTIFIED);
int len = logContainer.getDocument().getLength();
logContainer.setCaretPosition(len);
logContainer.setCharacterAttributes(attributeSet, false);
logContainer.replaceSelection(message);
}
public AbstractTextPaneLogger(JTextPane logContainer) {
this.logContainer = logContainer;
}
}
@@ -0,0 +1,28 @@
package com.svn.utils.mirror.gui.logger;
import com.svn.utils.mirror.app.Revision;
import javax.swing.*;
import java.awt.*;
/**
* SvnMirror
* Created by Marcin on 2015-06-12.
*/
public class DetailsLogger extends AbstractTextPaneLogger {
public DetailsLogger(JTextPane logContainer) {
super(logContainer);
}
public void logRevisionDetails(Revision revision) {
logContainer.setText("");
appendToPane("\nMESSAGE:", Color.BLACK);
appendToPane(revision.getMessage(), Color.GREEN);
appendToPane("\nAUTHOR:", Color.BLACK);
appendToPane(revision.getAuthor(), Color.GREEN);
appendToPane("\nDATE:", Color.BLACK);
appendToPane(revision.getDate().toString(), Color.BLUE);
appendToPane("\nCHANGES:", Color.BLACK);
appendToPane(revision.getChanges(), Color.MAGENTA);
}
}
@@ -0,0 +1,23 @@
package com.svn.utils.mirror.gui.logger;
import javax.swing.*;
import java.awt.*;
/**
* SvnMirror
* Created by Marcin on 2015-06-12.
*/
public class StatusLogger extends AbstractTextPaneLogger {
public StatusLogger(JTextPane logContainer) {
super(logContainer);
}
public void logError(String message) {
appendToPane(message + "\n", Color.RED);
}
public void logSuccess(String message) {
appendToPane(message + "\n", Color.GREEN);
}
}
@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.svn.utils.mirror.gui.main.ConnectOrCreateWindow">
<grid id="27dc6" binding="rootPanel" layout-manager="GridLayoutManager" row-count="5" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="15" left="15" bottom="15" right="15"/>
<constraints>
<xy x="20" y="20" width="500" height="400"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<vspacer id="ee3e2">
<constraints>
<grid row="2" column="1" row-span="3" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
<component id="c6306" class="javax.swing.JButton" binding="connectWithExistingButton">
<constraints>
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Attach to existing configuration"/>
</properties>
</component>
<component id="a94e1" class="javax.swing.JButton" binding="createMirrorButton">
<constraints>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Create mirroring"/>
</properties>
</component>
<component id="97acd" class="javax.swing.JLabel">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<horizontalAlignment value="0"/>
<horizontalTextPosition value="0"/>
<text value="SvnMirror - tool for establishing SVN repo mirroring"/>
</properties>
</component>
<component id="cde67" class="javax.swing.JCheckBox" binding="isRemote">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Remote"/>
</properties>
</component>
</children>
</grid>
</form>
@@ -0,0 +1,50 @@
package com.svn.utils.mirror.gui.main;
import com.svn.utils.mirror.gui.enums.RepoAction;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/**
* SvnMirror
* Created by Marcin on 2015-06-16.
*/
public class ConnectOrCreateWindow extends JFrame {
private JButton connectWithExistingButton;
private JButton createMirrorButton;
private JPanel rootPanel;
private JCheckBox isRemote;
public ConnectOrCreateWindow(String title) throws HeadlessException {
super(title);
initAndShowMainWindow();
addListeners();
}
private void addListeners() {
createMirrorButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
new MainWindow("Create mirroring", RepoAction.CREATE_NEW_REPO_MIRROR,isRemote.isSelected());
setVisible(false);
}
});
connectWithExistingButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
new MainWindow("Attach to existing configuration", RepoAction.CONNECT_TO_EXISTING_REPO_MIRROR,isRemote.isSelected());
setVisible(false);
}
});
}
private void initAndShowMainWindow() {
setContentPane(rootPanel);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
pack();
setVisible(true);
}
}
@@ -0,0 +1,175 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.svn.utils.mirror.gui.main.MainWindow">
<grid id="27dc6" binding="rootPanel" layout-manager="GridLayoutManager" row-count="12" column-count="5" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="20" y="20" width="754" height="524"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<scrollpane id="b8f99">
<constraints>
<grid row="4" column="0" row-span="2" col-span="1" vsize-policy="7" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false">
<preferred-size width="255" height="23"/>
</grid>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="4f73b" class="javax.swing.JTextPane" binding="logTextPane">
<constraints/>
<properties>
<text value=""/>
<toolTipText value="logs from aapilcation"/>
</properties>
</component>
</children>
</scrollpane>
<grid id="c9d20" binding="rootServerLoginPanel" layout-manager="GridLayoutManager" row-count="3" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="15" left="15" bottom="15" right="15"/>
<constraints>
<grid row="1" column="0" row-span="1" col-span="4" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false">
<preferred-size width="150" height="-1"/>
</grid>
</constraints>
<properties/>
<border type="bevel-raised" title="Login Data">
<title-color color="-4503485"/>
</border>
<children>
<component id="f3976" class="javax.swing.JTextField" binding="loginTextFields">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="150" height="-1"/>
</grid>
</constraints>
<properties>
<text value="SVN user login"/>
<toolTipText value="login"/>
</properties>
</component>
<component id="ae73" class="javax.swing.JPasswordField" binding="passwordField">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="150" height="-1"/>
</grid>
</constraints>
<properties>
<text value="password"/>
<toolTipText value="password"/>
</properties>
</component>
<component id="7b2cc" class="javax.swing.JTextField" binding="hostField">
<constraints>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="150" height="-1"/>
</grid>
</constraints>
<properties>
<text value="Host"/>
<toolTipText value="login"/>
</properties>
</component>
</children>
</grid>
<scrollpane id="19c4a">
<constraints>
<grid row="6" column="0" row-span="6" col-span="4" vsize-policy="7" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="7aca2" class="javax.swing.JTextPane" binding="detailsPane">
<constraints/>
<properties>
<toolTipText value="details about selected revision"/>
</properties>
<clientProperties>
<html.disable class="java.lang.Boolean" value="true"/>
</clientProperties>
</component>
</children>
</scrollpane>
<grid id="2412b" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="15" left="15" bottom="15" right="15"/>
<constraints>
<grid row="2" column="0" row-span="1" col-span="4" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false">
<preferred-size width="150" height="-1"/>
</grid>
</constraints>
<properties/>
<border type="bevel-raised" title="Repository paths">
<title-color color="-4503485"/>
</border>
<children>
<component id="ddc3e" class="javax.swing.JTextField" binding="sourceRepositoryPathTextField">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="150" height="-1"/>
</grid>
</constraints>
<properties>
<text value="Source repository path"/>
<toolTipText value="repository from create mirroring"/>
</properties>
</component>
<component id="703e0" class="javax.swing.JTextField" binding="destinationRepositoryPathTextField" default-binding="true">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="150" height="-1"/>
</grid>
</constraints>
<properties>
<text value="Destination repository path"/>
<toolTipText value="repository which mirrors"/>
</properties>
</component>
</children>
</grid>
<component id="ada03" class="javax.swing.JButton" binding="mirrorButton">
<constraints>
<grid row="3" column="0" row-span="1" col-span="3" vsize-policy="0" hsize-policy="1" anchor="0" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="150" height="-1"/>
</grid>
</constraints>
<properties>
<text value="Mirror"/>
<toolTipText value="start"/>
</properties>
</component>
<scrollpane id="61c1a">
<constraints>
<grid row="4" column="1" row-span="2" col-span="3" vsize-policy="7" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false">
<preferred-size width="222" height="144"/>
</grid>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="4738" class="javax.swing.JList" binding="revisionsList">
<constraints/>
<properties>
<model/>
<toolTipText value="list of revisions"/>
</properties>
</component>
</children>
</scrollpane>
<grid id="7dd0b" binding="synchronizationStatusPanel" layout-manager="CardLayout" hgap="0" vgap="0">
<constraints>
<grid row="1" column="4" row-span="2" col-span="1" vsize-policy="3" hsize-policy="1" anchor="0" fill="3" indent="0" use-parent-layout="false">
<preferred-size width="150" height="0"/>
</grid>
</constraints>
<properties>
<toolTipText value="green:synchronized, yellow:waiting for user oraz server, red:not synchronized"/>
</properties>
<border type="bevel-raised" title="Synchronization status">
<title-color color="-4503485"/>
</border>
<children/>
</grid>
</children>
</grid>
</form>
@@ -0,0 +1,235 @@
package com.svn.utils.mirror.gui.main;
import com.svn.utils.mirror.app.CreateRepoInt;
import com.svn.utils.mirror.app.Mirror;
import com.svn.utils.mirror.app.Revision;
import com.svn.utils.mirror.app.remote.Configuration;
import com.svn.utils.mirror.app.remote.RemoteMirror;
import com.svn.utils.mirror.gui.enums.RepoAction;
import com.svn.utils.mirror.gui.enums.RepositoryType;
import com.svn.utils.mirror.gui.enums.SynchronizationStatus;
import com.svn.utils.mirror.gui.logger.DetailsLogger;
import com.svn.utils.mirror.gui.logger.StatusLogger;
import com.svn.utils.mirror.gui.model.RepositoryModel;
import com.svn.utils.mirror.gui.model.RevisionModel;
import com.svn.utils.mirror.gui.view.SynchronizationStatusComponent;
import com.svn.utils.mirror.gui.worker.RefreshRepoStatusWorker;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNURL;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.io.IOException;
import java.util.List;
/**
* SvnMirror
* Created by Marcin on 2015-06-12.
*/
public class MainWindow extends JFrame implements CreateRepoInt, RevisionListSetter {
private JPanel rootPanel;
private JButton mirrorButton;
private JTextPane logTextPane;
private JTextField sourceRepositoryPathTextField;
private JTextField destinationRepositoryPathTextField;
private JComboBox repositoryTypeComboBox;
private JTextField loginTextFields;
private JPasswordField passwordField;
private JPanel rootServerLoginPanel;
private JTextPane detailsPane;
private JPanel synchronizationStatusPanel;
private JList revisionsList;
private JTextField hostField;
private StatusLogger statusLogger;
private RepoAction repoAction;
private SynchronizationStatusComponent synchronizationStatusComponent;
private Mirror mirror;
private RemoteMirror remoteMirror;
private RevisionModel revisionModel;
private DetailsLogger detailsLogger;
private RefreshRepoStatusWorker refreshRepoStatusWorker;
private final boolean isRemote;
public MainWindow(String title, RepoAction repoAction, boolean isRemote) throws HeadlessException {
super(title);
this.isRemote = isRemote;
statusLogger = new StatusLogger(logTextPane);
detailsLogger = new DetailsLogger(detailsPane);
this.repoAction = repoAction;
initView();
initFormBasedOnRepoAction();
addListeners();
if (isRemote) {
remoteMirror = RemoteMirror.getInstance();
refreshRepoStatusWorker = new RefreshRepoStatusWorker(this, remoteMirror);
destinationRepositoryPathTextField.setText("Repository name");
sourceRepositoryPathTextField.setText("Source repository path");
} else {
mirror = Mirror.getInstance();
refreshRepoStatusWorker = new RefreshRepoStatusWorker(this, mirror);
rootServerLoginPanel.setVisible(false);
}
}
private void initView() {
setExtendedState(JFrame.MAXIMIZED_BOTH);
setContentPane(rootPanel);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
pack();
setVisible(true);
initSynchronizationStatusComponent();
if(!isRemote){
rootServerLoginPanel.setVisible(false);
}
}
public void setRevisionList(List<Revision> revisionList) {
DefaultListModel<Revision> revisionDefaultListModel = new DefaultListModel<>();
for (Revision revision : revisionList) {
revisionDefaultListModel.addElement(revision);
}
revisionsList.setModel(revisionDefaultListModel);
updateSynchronizationStatusComponent();
}
private void initSynchronizationStatusComponent() {
synchronizationStatusComponent = new SynchronizationStatusComponent();
synchronizationStatusComponent.setSynchronizationStatus(SynchronizationStatus.WAITING_FOR_FEEDBACK);
synchronizationStatusPanel.add(synchronizationStatusComponent);
}
private void initFormBasedOnRepoAction() {
// @TODO hide & show GUI parts
switch (repoAction) {
case CONNECT_TO_EXISTING_REPO_MIRROR:
mirrorButton.setText("Attach");
break;
case CREATE_NEW_REPO_MIRROR:
break;
}
setVisible(true);
}
private void addListeners() {
addMirrorButtonClickListener();
addRevisionListSelectionListener();
}
private void addRevisionListSelectionListener() {
revisionsList.addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
if (!e.getValueIsAdjusting()) {
detailsLogger.logRevisionDetails((Revision) revisionsList.getSelectedValue());
}
}
});
}
private void addMirrorButtonClickListener() {
mirrorButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (isRemote) {
remoteMirror.initializeAndCreateRepoMirroring(loginTextFields.getText(), passwordField.getText(),
hostField.getText(), sourceRepositoryPathTextField.getText(), destinationRepositoryPathTextField.getText(),
MainWindow.this);
} else {
mirror.initializeAndCreateRepoMirroring(sourceRepositoryPathTextField.getText(),
destinationRepositoryPathTextField.getText(),
MainWindow.this);
}
updateSynchronizationStatusComponent();
}
});
}
private void updateSynchronizationStatusComponent() {
if (isRemote) {
if (remoteMirror.isSynced(MainWindow.this)) {
synchronizationStatusComponent.setSynchronizationStatus(SynchronizationStatus.SYNCHRONIZED);
} else {
synchronizationStatusComponent.setSynchronizationStatus(SynchronizationStatus.NOT_SYNCHRONIZED);
}
} else {
if (mirror.isSynced(MainWindow.this)) {
synchronizationStatusComponent.setSynchronizationStatus(SynchronizationStatus.SYNCHRONIZED);
} else {
synchronizationStatusComponent.setSynchronizationStatus(SynchronizationStatus.NOT_SYNCHRONIZED);
}
}
}
private void startRefreshingStatusWorker() {
new Thread(refreshRepoStatusWorker).start();
}
@Override
public void onRepoCreated(SVNURL svnurl) {
statusLogger.logSuccess("Repo created: " + svnurl.getPath());
}
@Override
public void onRepoCreationException(SVNException e) {
statusLogger.logError("Repo creation failed: " + e.getMessage());
}
@Override
public void onInitialization(Boolean b) {
statusLogger.logSuccess("Mirror initialized");
}
@Override
public void onInitializationException(SVNException e) {
statusLogger.logError("Mirror initialization failed: " + e.getMessage());
}
@Override
public void onSynchronization(Boolean b) {
statusLogger.logSuccess("Repos synchronized");
}
@Override
public void onSynchronizationException(SVNException e) {
statusLogger.logError("Repo synchronization failed: " + e.getMessage());
}
@Override
public void onHooksCreated(Boolean b) {
statusLogger.logSuccess("Hooks created");
startRefreshingStatusWorker();
}
@Override
public void onHooksCreatedException(IOException e) {
statusLogger.logError("Hooks creation failed" + e.getMessage());
}
@Override
public void onIsSyncedException(SVNException e) {
statusLogger.logError("Hooks creation failed" + e.getMessage());
}
@Override
public void onException(Exception e) {
statusLogger.logError("Error : " + e.getMessage());
}
}
@@ -0,0 +1,13 @@
package com.svn.utils.mirror.gui.main;
import com.svn.utils.mirror.app.Revision;
import java.util.List;
/**
* SvnMirror
* Created by Marcin on 2015-06-19.
*/
public interface RevisionListSetter {
void setRevisionList(List<Revision> revisionList);
}
@@ -0,0 +1,24 @@
package com.svn.utils.mirror.gui.model;
import com.svn.utils.mirror.gui.enums.RepositoryType;
/**
* SvnMirror
* Created by Marcin on 2015-06-16.
*/
public class RepositoryModel {
private RepositoryType repositoryType;
public RepositoryModel(RepositoryType repositoryType) {
this.repositoryType = repositoryType;
}
public RepositoryType getRepositoryType() {
return repositoryType;
}
@Override
public String toString() {
return repositoryType.toString();
}
}
@@ -0,0 +1,21 @@
package com.svn.utils.mirror.gui.model;
import com.svn.utils.mirror.app.Revision;
import java.util.List;
/**
* SvnMirror
* Created by Marcin on 2015-06-17.
*/
public class RevisionModel {
private List<Revision> revisions;
public RevisionModel(List<Revision> revisions) {
this.revisions = revisions;
}
public List<Revision> getRevisions() {
return revisions;
}
}
@@ -0,0 +1,46 @@
package com.svn.utils.mirror.gui.view;
import com.svn.utils.mirror.gui.enums.SynchronizationStatus;
import javax.swing.*;
import java.awt.*;
import java.awt.geom.Rectangle2D;
/**
* SvnMirror
* Created by Marcin on 2015-06-16.
*/
public class SynchronizationStatusComponent extends JComponent {
private SynchronizationStatus synchronizationStatus;
public void setSynchronizationStatus(SynchronizationStatus synchronizationStatus) {
this.synchronizationStatus = synchronizationStatus;
repaint();
setVisible(true);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
switch (synchronizationStatus) {
case SYNCHRONIZED:
g.setColor(Color.GREEN);
break;
case NOT_SYNCHRONIZED:
g.setColor(Color.RED);
break;
case WAITING_FOR_FEEDBACK:
g.setColor(Color.YELLOW);
break;
}
Graphics2D g2d = (Graphics2D) g;
Rectangle2D.Double circle = new Rectangle2D.Double(getX(),
getY(),
getWidth(),
getHeight());
g2d.fill(circle);
g2d.setColor(Color.BLACK);
g2d.drawString(synchronizationStatus.toString(), getX(), getY() + getHeight() / 2);
}
}
@@ -0,0 +1,98 @@
package com.svn.utils.mirror.gui.worker;
import com.svn.utils.mirror.app.Mirror;
import com.svn.utils.mirror.app.Revision;
import com.svn.utils.mirror.app.remote.RemoteMirror;
import com.svn.utils.mirror.gui.main.RevisionListSetter;
import org.tmatesoft.svn.core.SVNException;
import javax.swing.*;
import java.util.ArrayList;
import java.util.List;
/**
* SvnMirror
* Created by Marcin on 2015-06-19.
*/
public class RefreshRepoStatusWorker extends SwingWorker<List<Revision>, List<Revision>> {
private RevisionListSetter revisionListSetter;
private Mirror mirror;
private RemoteMirror remoteMirror;
private boolean shouldWork;
private List<Revision> currentRevisionList;
public RefreshRepoStatusWorker(RevisionListSetter revisionListSetter, Mirror mirror) {
this.revisionListSetter = revisionListSetter;
this.mirror = mirror;
this.shouldWork = true;
this.currentRevisionList = new ArrayList<>();
}
public RefreshRepoStatusWorker(RevisionListSetter revisionListSetter, RemoteMirror mirror) {
this.revisionListSetter = revisionListSetter;
this.remoteMirror = mirror;
this.shouldWork = true;
this.currentRevisionList = new ArrayList<>();
}
@Override
protected List<Revision> doInBackground() throws Exception {
while (shouldWork) {
sleep(3000);
if (newRevisionsAdded()) {
if(mirror != null)
publish(mirror.getRevisions());
else
publish(remoteMirror.getRevisions());
}
}
if(mirror != null)
return mirror.getRevisions();
else
return remoteMirror.getRevisions();
}
private void sleep(int i) {
try {
synchronized (this) {
this.wait(i);
}
} catch (Exception ignored) {
}
}
@Override
protected void process(List<List<Revision>> chunks) {
try {
publishCurrentRevisionList();
} catch (SVNException e) {
e.printStackTrace();
}
}
private void publishCurrentRevisionList() throws SVNException {
if(mirror != null) {
currentRevisionList = mirror.getRevisions();
revisionListSetter.setRevisionList(currentRevisionList);
}
else {
currentRevisionList = remoteMirror.getRevisions();
revisionListSetter.setRevisionList(currentRevisionList);
}
}
private boolean newRevisionsAdded() throws SVNException {
if(mirror != null) {
return currentRevisionList.size() != mirror.getRevisions().size();
}
else {
return currentRevisionList.size() != remoteMirror.getRevisions().size();
}
}
public void setShouldWork(boolean shouldWork) {
this.shouldWork = shouldWork;
}
}
@@ -0,0 +1,36 @@
package com.svn.utils.mirror.app.util;
import com.svn.utils.mirror.app.remote.Configuration;
import org.junit.Test;
import javax.naming.ConfigurationException;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
/**
* Created by mar on 20.06.15.
*/
public class ConfigurationTest {
@Test
public void generatedAndCheckConfigurationFile() throws FileNotFoundException {
Configuration configuration = new Configuration();
configuration.addRepoName("Test");
configuration.addSVNServerPath("/home/mar/exampleRepository");
configuration.addHookConfig(
"#!/bin/sh" +
"svnsync --non-interactive sync " +
"file://","post-commit"
);
try {
File file = configuration.build();
String content = new Scanner(file).useDelimiter("\\Z").next();
System.out.println(content);
} catch (ConfigurationException e) {
e.printStackTrace();
}
}
}
@@ -0,0 +1,55 @@
package com.svn.utils.mirror.app.util;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.SftpException;
import com.svn.utils.mirror.app.remote.Configuration;
import com.svn.utils.mirror.app.remote.ssh.CommandNotFoundException;
import com.svn.utils.mirror.app.remote.ssh.SshConnect;
import org.junit.Assert;
import org.junit.Test;
import javax.naming.ConfigurationException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* Created by mar on 20.06.15.
*/
public class SshConnectTest {
private static final String USERNAME = "mar";
private static final String PASSWORD = "***";
private static final String HOST = "127.0.0.1";
@Test
public void executeCommandInSshTest() throws JSchException, CommandNotFoundException {
SshConnect connect = new SshConnect(USERNAME,PASSWORD,HOST);
List<String> result = connect.executeCommands(new ArrayList<String>(){
{
add("ls");
}
});
result.forEach((System.out::println));
Assert.assertTrue("List should be greather than 0", result.size() > 0);
}
@Test
public void fileTransferTest() throws JSchException, IOException, SftpException, CommandNotFoundException, ConfigurationException {
SshConnect connect = new SshConnect(USERNAME,PASSWORD,HOST);
connect.sendFile(new Configuration().build());
}
@Test(expected = CommandNotFoundException.class)
public void commandNotFound() throws JSchException, CommandNotFoundException {
SshConnect connect = new SshConnect(USERNAME,PASSWORD,HOST);
List<String> result = connect.executeCommands(new ArrayList<String>(){
{
add("lsfff");
}
});
result.forEach((System.out::println));
Assert.assertTrue("List should be greather than 0", result.size() > 0);
}
}
@@ -0,0 +1,39 @@
package com.svn.utils.mirror.app.util;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.SftpException;
import com.svn.utils.mirror.app.remote.Configuration;
import com.svn.utils.mirror.app.remote.ssh.CommandNotFoundException;
import com.svn.utils.mirror.app.remote.ssh.SshConnect;
import org.junit.Test;
import javax.naming.ConfigurationException;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* Created by mar on 25.06.15.
*/
public class SvnCreateRepoTest {
@Test
public void svnCreateRepoTest() throws ConfigurationException, JSchException, CommandNotFoundException, SftpException, IOException {
File configuration = new Configuration().addRepoName("mojaNazwaZajebistegoRepo").addSVNServerPath("/home/mar/exampleRepository").addHookConfig(
"\"#!bin/bash\n" +
"echo \"działam\"\"","pre-commit").build();
SshConnect connect = new SshConnect("mar","***","127.0.0.1");
connect.sendFile(configuration);
List<String> result = connect.executeCommands(new ArrayList<String>(){
{
add("sh conf.sh");
add("rm conf.sh");
}
});
result.forEach(System.out::println);
}
}
@@ -0,0 +1,20 @@
package com.svn.utils.mirror.app.util;
import org.junit.Test;
import org.tmatesoft.svn.core.SVNException;
import java.io.File;
/**
* Created by mar on 19.06.15.
*/
public class diffTest {
private static final String REPO_PATH = "/home/mar/stosowana";
@Test
public void checkDiffOfRepo() throws SVNException {
Diff diff = new Diff(new File(REPO_PATH));
System.out.println(diff.getDiff(new File(REPO_PATH)));
}
}
@@ -0,0 +1,25 @@
package com.svn.utils.mirror.app.util;
import com.svn.utils.mirror.app.remote.ssh.ConnectToRemoteSVN;
import org.junit.Test;
import org.tmatesoft.svn.core.SVNException;
import java.net.URISyntaxException;
/**
* Created by mar on 24.06.15.
*/
public class statusRepoTest {
@Test
public void repoTest() {
try {
ConnectToRemoteSVN connectToRemoteSVN = new ConnectToRemoteSVN("svn", "svn", "svn://192.168.2.111/asdfasdf/");
System.out.println(connectToRemoteSVN.getRevisions());
} catch (URISyntaxException e) {
e.printStackTrace();
} catch (SVNException e) {
e.printStackTrace();
}
}
}