Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d5a42235fb | ||
|
|
40f955cdf2 | ||
|
|
76087834f9 | ||
|
|
3e599e889d | ||
|
|
142c16b272 | ||
|
|
29638dcf8d | ||
|
|
b4b90593c1 | ||
|
|
70c22c517c | ||
|
|
776061e077 | ||
|
|
3166e9ea51 | ||
|
|
49bfb1eab3 | ||
|
|
0ec0b75d94 | ||
|
|
cf790af560 | ||
|
|
6f58bf9f3c | ||
|
|
0dbe010964 | ||
|
|
6c71843b2a | ||
|
|
6a528d2435 | ||
|
|
af2bc9ad0c | ||
|
|
290754e4ac | ||
|
|
a89817dc7b | ||
|
|
cc9dafc57f | ||
|
|
f595272065 | ||
|
|
3a49ca75a0 | ||
|
|
700d553b11 | ||
|
|
5339934d9d | ||
|
|
33fa7bcf37 | ||
|
|
9345d91627 | ||
|
|
cb7ed3ed68 | ||
|
|
7031544ce5 | ||
|
|
6f4b3e56d4 | ||
|
|
b438f52dec | ||
|
|
b10b495fa6 | ||
|
|
752ba245a9 | ||
|
|
3ad019f44b | ||
|
|
727b562e21 | ||
|
|
ce3fe12e45 | ||
|
|
f548329a4a | ||
|
|
d94db5c55f | ||
|
|
1413d28e74 | ||
|
|
479f5e6875 | ||
|
|
cfa1273c11 | ||
|
|
b60fe9359b | ||
|
|
4f18eb6858 | ||
|
|
e2be1f8b04 | ||
|
|
fae7ad6a0a | ||
|
|
d263013d4c | ||
|
|
c2de9f0340 |
No files matched your search
+2
-1
@@ -1,4 +1,5 @@
|
||||
.idea/
|
||||
build/
|
||||
*.iml
|
||||
.gradle
|
||||
.gradle
|
||||
/repos
|
||||
@@ -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.
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user