diff --git a/org.archicontribs.modelrepository/src/org/archicontribs/modelrepository/actions/CloneModelAction.java b/org.archicontribs.modelrepository/src/org/archicontribs/modelrepository/actions/CloneModelAction.java
index 95c79e8c..99148147 100644
--- a/org.archicontribs.modelrepository/src/org/archicontribs/modelrepository/actions/CloneModelAction.java
+++ b/org.archicontribs.modelrepository/src/org/archicontribs/modelrepository/actions/CloneModelAction.java
@@ -6,6 +6,7 @@
package org.archicontribs.modelrepository.actions;
import java.io.File;
+import java.net.URI;
import java.security.GeneralSecurityException;
import org.archicontribs.modelrepository.IModelRepositoryImages;
@@ -22,6 +23,9 @@
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.window.Window;
+import org.eclipse.jgit.storage.file.FileBasedConfig;
+import org.eclipse.jgit.util.FS;
+import org.eclipse.jgit.util.SystemReader;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.progress.IProgressService;
@@ -36,126 +40,141 @@
* 1. Check Primary Key
* 2. Get user credentials
* 3. Clone from Remote
- * 4. If Grafico files exist load the model from the Grafico files and save it as temp file
- * 5. If Grafico files do not exist create a new temp model and save it
+ * 4. If Grafico files exist load the model from the Grafico files and save it as temp file
+ * 5. If Grafico files do not exist create a new temp model and save it
* 6. Store user credentials if prefs agree
*/
public class CloneModelAction extends AbstractModelAction {
-
- public CloneModelAction(IWorkbenchWindow window) {
- super(window);
- setImageDescriptor(IModelRepositoryImages.ImageFactory.getImageDescriptor(IModelRepositoryImages.ICON_CLONE));
- setText(Messages.CloneModelAction_0);
- setToolTipText(Messages.CloneModelAction_0);
- }
-
- @Override
- public void run() {
- // Check primary key set
- try {
- if(!EncryptedCredentialsStorage.checkPrimaryKeySet()) {
- return;
- }
- }
- catch(GeneralSecurityException ex) {
- displayCredentialsErrorDialog(ex);
- return;
- }
- catch(Exception ex) {
- displayErrorDialog(Messages.CloneModelAction_0, ex);
- return;
- }
-
- CloneInputDialog dialog = new CloneInputDialog(fWindow.getShell());
- if(dialog.open() != Window.OK) {
- return;
- }
-
- final String repoURL = dialog.getURL();
- final boolean storeCredentials = dialog.doStoreCredentials();
- final UsernamePassword npw = dialog.getUsernamePassword();
-
- if(!StringUtils.isSet(repoURL)) {
- return;
- }
-
- if(GraficoUtils.isHTTP(repoURL) && !StringUtils.isSet(npw.getUsername()) && npw.getPassword().length == 0) {
- MessageDialog.openError(fWindow.getShell(),
- Messages.CloneModelAction_0,
- Messages.CloneModelAction_1);
- return;
- }
-
- // Create a new local folder
- File localRepoFolder = GraficoUtils.getUniqueLocalFolder(ModelRepositoryPlugin.INSTANCE.getUserModelRepositoryFolder(), repoURL);
- setRepository(new ArchiRepository(localRepoFolder));
-
- try {
- // Clone
- Exception[] exception = new Exception[1];
- IProgressService ps = PlatformUI.getWorkbench().getProgressService();
- ps.busyCursorWhile(new IRunnableWithProgress() {
- @Override
- public void run(IProgressMonitor pm) {
- try {
- // Update Proxy
- ProxyAuthenticator.update();
-
- pm.beginTask(Messages.CloneModelAction_4, -1);
- getRepository().cloneModel(repoURL, npw, new ProgressMonitorWrapper(pm));
- }
- catch(Exception ex) {
- exception[0] = ex;
- }
- finally {
- // Clear Proxy
- ProxyAuthenticator.clear();
- }
- }
- });
-
- if(exception[0] != null) {
- throw exception[0];
- }
-
- // Load it from the Grafico files if we can
- IArchimateModel graficoModel = new GraficoModelLoader(getRepository()).loadModel();
-
- // We couldn't load it from Grafico so create a new blank model
- if(graficoModel == null) {
- // New one. This will open in the tree
- IArchimateModel model = IEditorModelManager.INSTANCE.createNewModel();
- model.setFile(getRepository().getTempModelFile());
-
- // And Save it
- IEditorModelManager.INSTANCE.saveModel(model);
-
- // Export to Grafico
- getRepository().exportModelToGraficoFiles();
-
- // And do a first commit
- getRepository().commitChanges(Messages.CloneModelAction_3, false);
-
- // Save the checksum
- getRepository().saveChecksum();
- }
-
- // Store repo credentials if HTTP and option is set
- if(GraficoUtils.isHTTP(repoURL) && storeCredentials) {
- EncryptedCredentialsStorage cs = EncryptedCredentialsStorage.forRepository(getRepository());
- cs.store(npw);
- }
-
- // Notify listeners
- notifyChangeListeners(IRepositoryListener.REPOSITORY_ADDED);
- }
- catch(Exception ex) {
- displayErrorDialog(Messages.CloneModelAction_0, ex);
- }
- }
-
- @Override
- protected boolean shouldBeEnabled() {
- return true;
- }
+
+ public CloneModelAction(IWorkbenchWindow window) {
+ super(window);
+ setImageDescriptor(IModelRepositoryImages.ImageFactory.getImageDescriptor(IModelRepositoryImages.ICON_CLONE));
+ setText(Messages.CloneModelAction_0);
+ setToolTipText(Messages.CloneModelAction_0);
+ }
+
+ @Override
+ public void run() {
+ // Check primary key set
+ try {
+ if (!EncryptedCredentialsStorage.checkPrimaryKeySet()) {
+ return;
+ }
+ } catch (GeneralSecurityException ex) {
+ displayCredentialsErrorDialog(ex);
+ return;
+ } catch (Exception ex) {
+ displayErrorDialog(Messages.CloneModelAction_0, ex);
+ return;
+ }
+
+ CloneInputDialog dialog = new CloneInputDialog(fWindow.getShell());
+ if (dialog.open() != Window.OK) {
+ return;
+ }
+
+ final String repoURL = dialog.getURL();
+ final boolean storeCredentials = dialog.doStoreCredentials();
+ final UsernamePassword npw = dialog.getUsernamePassword();
+ final boolean skipSSLVerification = dialog.skipSSLverification();
+
+ if (!StringUtils.isSet(repoURL)) {
+ return;
+ }
+
+ if (GraficoUtils.isHTTP(repoURL) && !StringUtils.isSet(npw.getUsername()) && npw.getPassword().length == 0) {
+ MessageDialog.openError(fWindow.getShell(), Messages.CloneModelAction_0, Messages.CloneModelAction_1);
+ return;
+ }
+
+ // Create a new local folder
+ File localRepoFolder = GraficoUtils
+ .getUniqueLocalFolder(ModelRepositoryPlugin.INSTANCE.getUserModelRepositoryFolder(), repoURL);
+ setRepository(new ArchiRepository(localRepoFolder));
+
+ if (skipSSLVerification)
+ disableSSLVerify(repoURL);
+ try {
+ // Clone
+ Exception[] exception = new Exception[1];
+ IProgressService ps = PlatformUI.getWorkbench().getProgressService();
+ ps.busyCursorWhile(new IRunnableWithProgress() {
+ @Override
+ public void run(IProgressMonitor pm) {
+ try {
+ // Update Proxy
+ ProxyAuthenticator.update();
+
+ pm.beginTask(Messages.CloneModelAction_4, -1);
+ getRepository().cloneModel(repoURL, npw, new ProgressMonitorWrapper(pm));
+ } catch (Exception ex) {
+ exception[0] = ex;
+ } finally {
+ // Clear Proxy
+ ProxyAuthenticator.clear();
+ }
+ }
+ });
+
+ if (exception[0] != null) {
+ throw exception[0];
+ }
+
+ // Load it from the Grafico files if we can
+ IArchimateModel graficoModel = new GraficoModelLoader(getRepository()).loadModel();
+
+ // We couldn't load it from Grafico so create a new blank model
+ if (graficoModel == null) {
+ // New one. This will open in the tree
+ IArchimateModel model = IEditorModelManager.INSTANCE.createNewModel();
+ model.setFile(getRepository().getTempModelFile());
+
+ // And Save it
+ IEditorModelManager.INSTANCE.saveModel(model);
+
+ // Export to Grafico
+ getRepository().exportModelToGraficoFiles();
+
+ // And do a first commit
+ getRepository().commitChanges(Messages.CloneModelAction_3, false);
+
+ // Save the checksum
+ getRepository().saveChecksum();
+ }
+
+ // Store repo credentials if HTTP and option is set
+ if (GraficoUtils.isHTTP(repoURL) && storeCredentials) {
+ EncryptedCredentialsStorage cs = EncryptedCredentialsStorage.forRepository(getRepository());
+ cs.store(npw);
+ }
+
+ // Notify listeners
+ notifyChangeListeners(IRepositoryListener.REPOSITORY_ADDED);
+ } catch (Exception ex) {
+ displayErrorDialog(Messages.CloneModelAction_0, ex);
+ }
+ }
+
+ private void disableSSLVerify(String repoURL) {
+ try {
+
+ URI gitServer = new URI(repoURL);
+ if (gitServer.getScheme().equals("https")) {
+ FileBasedConfig config = SystemReader.getInstance().openUserConfig(null, FS.DETECTED);
+ synchronized (config) {
+ config.load();
+ config.setBoolean("http", "https://" + gitServer.getHost() + ':'
+ + (gitServer.getPort() == -1 ? 443 : gitServer.getPort()), "sslVerify", false);
+ config.save();
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ protected boolean shouldBeEnabled() {
+ return true;
+ }
}
diff --git a/org.archicontribs.modelrepository/src/org/archicontribs/modelrepository/dialogs/CloneInputDialog.java b/org.archicontribs.modelrepository/src/org/archicontribs/modelrepository/dialogs/CloneInputDialog.java
index 7ec9666b..640bcb83 100644
--- a/org.archicontribs.modelrepository/src/org/archicontribs/modelrepository/dialogs/CloneInputDialog.java
+++ b/org.archicontribs.modelrepository/src/org/archicontribs/modelrepository/dialogs/CloneInputDialog.java
@@ -38,11 +38,13 @@ public class CloneInputDialog extends TitleAreaDialog {
private Text txtPassword;
private Button storeCredentialsButton;
+ private Button skipSSLButton;
private String URL;
private String username;
private char[] password;
private boolean doStoreCredentials;
+ private boolean skipSSLVerification;
public CloneInputDialog(Shell parentShell) {
super(parentShell);
@@ -82,6 +84,10 @@ public void modifyText(ModifyEvent e) {
txtPassword = createTextField(container, Messages.CloneInputDialog_4, SWT.PASSWORD);
createPreferenceButton(container);
+ skipSSLButton = new Button(container, SWT.CHECK);
+ skipSSLButton.setText(Messages.CloneInputDialog_btnCheckButton_text);
+ new Label(container, SWT.NONE);
+
return area;
}
@@ -116,6 +122,7 @@ protected void saveInput() {
password = txtPassword.getTextChars();
URL = txtURL.getText().trim();
doStoreCredentials = storeCredentialsButton.getSelection();
+ skipSSLVerification=skipSSLButton.getSelection();
}
@Override
@@ -123,6 +130,9 @@ protected void okPressed() {
saveInput();
super.okPressed();
}
+ public boolean skipSSLverification() {
+ return skipSSLVerification;
+ }
public UsernamePassword getUsernamePassword() {
return new UsernamePassword(username, password);
@@ -135,4 +145,5 @@ public String getURL() {
public boolean doStoreCredentials() {
return doStoreCredentials;
}
+
}
\ No newline at end of file
diff --git a/org.archicontribs.modelrepository/src/org/archicontribs/modelrepository/dialogs/Messages.java b/org.archicontribs.modelrepository/src/org/archicontribs/modelrepository/dialogs/Messages.java
index 70342eb6..742046be 100644
--- a/org.archicontribs.modelrepository/src/org/archicontribs/modelrepository/dialogs/Messages.java
+++ b/org.archicontribs.modelrepository/src/org/archicontribs/modelrepository/dialogs/Messages.java
@@ -115,6 +115,7 @@ public class Messages extends NLS {
public static String UserNamePasswordDialog_5;
public static String UserNamePasswordDialog_6;
+ public static String CloneInputDialog_btnCheckButton_text;
static {
// initialize resource bundle
NLS.initializeMessages(BUNDLE_NAME, Messages.class);
diff --git a/org.archicontribs.modelrepository/src/org/archicontribs/modelrepository/dialogs/messages.properties b/org.archicontribs.modelrepository/src/org/archicontribs/modelrepository/dialogs/messages.properties
index f27935e7..44230fa4 100644
--- a/org.archicontribs.modelrepository/src/org/archicontribs/modelrepository/dialogs/messages.properties
+++ b/org.archicontribs.modelrepository/src/org/archicontribs/modelrepository/dialogs/messages.properties
@@ -1,55 +1,58 @@
+#Eclipse modern messages class
+#Thu Mar 25 21:24:10 CET 2021
+UserNamePasswordDialog_6=There was an error\:
+NewPrimaryPasswordDialog_21=New password must have a minimum of
+SwitchBranchDialog_2=Branch\:
+NewPrimaryPasswordDialog_20={0} special characters,
+SwitchBranchDialog_1=Select the branch to switch to.
+SwitchBranchDialog_0=Switch Branch
+UserNamePasswordDialog_1=Enter user name and password
+UserNamePasswordDialog_0=Credentials
+UserNamePasswordDialog_3=Password\:
+NewPrimaryPasswordDialog_19={0} digits,
+UserNamePasswordDialog_2=User Name\:
+NewPrimaryPasswordDialog_18={0} upper case,
+UserNamePasswordDialog_5=Error saving credentials
+NewPrimaryPasswordDialog_17={0} lower case,
+UserNamePasswordDialog_4=Store user name and password
+NewPrimaryPasswordDialog_16={0} characters,
+NewPrimaryPasswordDialog_15=Must have a minimum of {0} special characters
+NewPrimaryPasswordDialog_14=Must have a minimum of {0} digits
+NewPrimaryPasswordDialog_13=Must have a minimum of {0} upper-case characters
+NewPrimaryPasswordDialog_12=Must have a minimum of {0} lower-case characters
+NewPrimaryPasswordDialog_11=Must be a minimum of {0} characters
+NewPrimaryPasswordDialog_10=Could not set password\:
+PrimaryPasswordDialog_1=Enter Primary Password
+PrimaryPasswordDialog_0=Primary Password
+AddBranchDialog_2=Enter the name of the local branch to create.
+AddBranchDialog_3=Branch\:
AddBranchDialog_0=Add Branch to current commit
AddBranchDialog_1=Add Branch
-AddBranchDialog_2=Enter the name of the local branch to create.
-AddBranchDialog_3=Branch:
-AddBranchDialog_4=The branch name must not end or start with a dot.
-AddBranchDialog_5=The branch name must not end or start with a slash.
+CommitDialog_3=User Email\:
+CommitDialog_2=User Name\:
+CommitDialog_1=Please enter user details and a commit message
+CommitDialog_0=Commit
+CommitDialog_6=Repository\:
+CommitDialog_5=Amend last commit instead of creating new one
+CommitDialog_4=Commit message\:
AddBranchDialog_6=Add Branch && Checkout
AddBranchDialog_7=Invalid character sequence in branch name.
+AddBranchDialog_4=The branch name must not end or start with a dot.
+AddBranchDialog_5=The branch name must not end or start with a slash.
+NewModelRepoDialog_0=New Model Repository
+CloneInputDialog_2=URL\:
+CloneInputDialog_3=User Name\:
+CloneInputDialog_4=Password\:
CloneInputDialog_0=Add Remote Model
CloneInputDialog_1=Please enter the URL of the remote model and user credentials (if using HTTP)
-CloneInputDialog_2=URL:
-CloneInputDialog_3=User Name:
-CloneInputDialog_4=Password:
-CommitDialog_0=Commit
-CommitDialog_1=Please enter user details and a commit message
-CommitDialog_2=User Name:
-CommitDialog_3=User Email:
-CommitDialog_4=Commit message:
-CommitDialog_5=Amend last commit instead of creating new one
-CommitDialog_6=Repository:
-NewModelRepoDialog_0=New Model Repository
-NewPrimaryPasswordDialog_0=Primary Password
-NewPrimaryPasswordDialog_1=Change or create a new primary password. This primary password is used to access an encryption key that secures repository credentials.
-NewPrimaryPasswordDialog_10=Could not set password:
-NewPrimaryPasswordDialog_11=Must be a minimum of {0} characters
-NewPrimaryPasswordDialog_12=Must have a minimum of {0} lower-case characters
-NewPrimaryPasswordDialog_13=Must have a minimum of {0} upper-case characters
-NewPrimaryPasswordDialog_14=Must have a minimum of {0} digits
-NewPrimaryPasswordDialog_15=Must have a minimum of {0} special characters
-NewPrimaryPasswordDialog_16={0} characters,
-NewPrimaryPasswordDialog_17={0} lower case,
-NewPrimaryPasswordDialog_18={0} upper case,
-NewPrimaryPasswordDialog_19={0} digits,
-NewPrimaryPasswordDialog_2=The passwords do not match
-NewPrimaryPasswordDialog_20={0} special characters,
-NewPrimaryPasswordDialog_21=New password must have a minimum of
-NewPrimaryPasswordDialog_3=New Primary Password:
-NewPrimaryPasswordDialog_4=Retype Primary Password:
-NewPrimaryPasswordDialog_5=Change primary password and keep current encryption key
+CloneInputDialog_btnCheckButton_text=Skip SSL Handshake verification
+NewPrimaryPasswordDialog_8=Current Primary Password\:
+NewPrimaryPasswordDialog_9=Could not set password. The current password may be incorrect.
NewPrimaryPasswordDialog_6=Set new primary password and generate new encryption key
NewPrimaryPasswordDialog_7=When setting a new primary password, all stored passwords will be lost and need to be re-entered for each repository\!
-NewPrimaryPasswordDialog_8=Current Primary Password:
-NewPrimaryPasswordDialog_9=Could not set password. The current password may be incorrect.
-PrimaryPasswordDialog_0=Primary Password
-PrimaryPasswordDialog_1=Enter Primary Password
-SwitchBranchDialog_0=Switch Branch
-SwitchBranchDialog_1=Select the branch to switch to.
-SwitchBranchDialog_2=Branch:
-UserNamePasswordDialog_0=Credentials
-UserNamePasswordDialog_1=Enter user name and password
-UserNamePasswordDialog_2=User Name:
-UserNamePasswordDialog_3=Password:
-UserNamePasswordDialog_4=Store user name and password
-UserNamePasswordDialog_5=Error saving credentials
-UserNamePasswordDialog_6=There was an error:
+NewPrimaryPasswordDialog_4=Retype Primary Password\:
+NewPrimaryPasswordDialog_5=Change primary password and keep current encryption key
+NewPrimaryPasswordDialog_2=The passwords do not match
+NewPrimaryPasswordDialog_3=New Primary Password\:
+NewPrimaryPasswordDialog_0=Primary Password
+NewPrimaryPasswordDialog_1=Change or create a new primary password. This primary password is used to access an encryption key that secures repository credentials.
diff --git a/org.archicontribs.modelrepository/src/org/archicontribs/modelrepository/grafico/ArchiRepository.java b/org.archicontribs.modelrepository/src/org/archicontribs/modelrepository/grafico/ArchiRepository.java
index ca002bb3..63e7259e 100644
--- a/org.archicontribs.modelrepository/src/org/archicontribs/modelrepository/grafico/ArchiRepository.java
+++ b/org.archicontribs.modelrepository/src/org/archicontribs/modelrepository/grafico/ArchiRepository.java
@@ -63,533 +63,546 @@
import com.archimatetool.model.IArchimateModel;
/**
- * Representation of a local repository
- * This is a wrapper class around a local repo folder
+ * Representation of a local repository This is a wrapper class around a local
+ * repo folder
*
* @author Phillip Beauvoir
*/
public class ArchiRepository implements IArchiRepository {
-
- /**
- * The folder location of the local repository
- */
- private File fLocalRepoFolder;
-
- public ArchiRepository(File localRepoFolder) {
- fLocalRepoFolder = localRepoFolder;
- }
-
- @Override
- public File getLocalRepositoryFolder() {
- return fLocalRepoFolder;
- }
-
- @Override
- public File getLocalGitFolder() {
- return new File(getLocalRepositoryFolder(), ".git"); //$NON-NLS-1$
- }
-
- @Override
- public String getName() {
- String[] result = new String[1];
-
- // Find the "folder.xml" file and read it from there
- File file = new File(getLocalRepositoryFolder(), IGraficoConstants.MODEL_FOLDER + "/" + IGraficoConstants.FOLDER_XML); //$NON-NLS-1$
- if(file.exists()) {
- try(Stream stream = Files.lines(Paths.get(file.getAbsolutePath()))) {
- stream.forEach(s -> {
- if(result[0] == null && s.indexOf("name=") != -1) { //$NON-NLS-1$
- String segments[] = s.split("\""); //$NON-NLS-1$
- if(segments.length == 2) {
- result[0] = segments[1];
- }
- }
- });
- }
- catch(IOException ex) {
- ex.printStackTrace();
- }
- }
-
- return result[0] != null ? result[0] : fLocalRepoFolder.getName();
- }
-
- @Override
- public File getTempModelFile() {
- return new File(getLocalRepositoryFolder(), "/.git/" + IGraficoConstants.LOCAL_ARCHI_FILENAME); //$NON-NLS-1$
- }
-
- @Override
- public String getOnlineRepositoryURL() throws IOException {
- try(Git git = Git.open(getLocalRepositoryFolder())) {
- return git.getRepository().getConfig().getString("remote", IGraficoConstants.ORIGIN, "url"); //$NON-NLS-1$ //$NON-NLS-2$
- }
- }
-
- @Override
- public IArchimateModel locateModel() {
- File tempFile = getTempModelFile();
-
- for(IArchimateModel model : IEditorModelManager.INSTANCE.getModels()) {
- if(tempFile.equals(model.getFile())) {
- return model;
- }
- }
-
- return null;
- }
-
- @Override
- public boolean hasChangesToCommit() throws IOException, GitAPIException {
- try(Git git = Git.open(getLocalRepositoryFolder())) {
- Status status = git.status().call();
- return !status.isClean();
- }
- }
-
- @Override
- public RevCommit commitChanges(String commitMessage, boolean amend) throws GitAPIException, IOException {
- try(Git git = Git.open(getLocalRepositoryFolder())) {
- Status status = git.status().call();
-
- // Nothing changed
- if(status.isClean()) {
- return null;
- }
-
- // Check lock file is deleted
- checkDeleteLockFile();
-
- // Add modified files to index
- AddCommand addCommand = git.add();
- addCommand.addFilepattern("."); //$NON-NLS-1$
- addCommand.setUpdate(false);
- addCommand.call();
-
- // Add missing files to index
- for(String s : status.getMissing()) {
- git.rm().addFilepattern(s).call();
- }
-
- // Commit
- CommitCommand commitCommand = git.commit();
- PersonIdent userDetails = getUserDetails();
- commitCommand.setAuthor(userDetails);
- commitCommand.setMessage(commitMessage);
- commitCommand.setAmend(amend);
- return commitCommand.call();
- }
- }
-
- @Override
- public void cloneModel(String repoURL, UsernamePassword npw, ProgressMonitor monitor) throws GitAPIException, IOException {
- CloneCommand cloneCommand = Git.cloneRepository();
- cloneCommand.setDirectory(getLocalRepositoryFolder());
- cloneCommand.setURI(repoURL);
- cloneCommand.setTransportConfigCallback(CredentialsAuthenticator.getTransportConfigCallback(repoURL, npw));
- cloneCommand.setProgressMonitor(monitor);
-
- try(Git git = cloneCommand.call()) {
- setDefaultConfigSettings(git.getRepository());
- }
- }
-
- @Override
- public Iterable pushToRemote(UsernamePassword npw, ProgressMonitor monitor) throws IOException, GitAPIException {
- try(Git git = Git.open(getLocalRepositoryFolder())) {
- PushCommand pushCommand = git.push();
- pushCommand.setTransportConfigCallback(CredentialsAuthenticator.getTransportConfigCallback(getOnlineRepositoryURL(), npw));
- pushCommand.setProgressMonitor(monitor);
-
- Iterable result = pushCommand.call();
-
- // After a successful push, ensure we are tracking the current branch
- setTrackedBranch(git.getRepository(), git.getRepository().getBranch());
-
- return result;
- }
- }
-
- @Override
- public PullResult pullFromRemote(UsernamePassword npw, ProgressMonitor monitor) throws IOException, GitAPIException {
- try(Git git = Git.open(getLocalRepositoryFolder())) {
- PullCommand pullCommand = git.pull();
- pullCommand.setTransportConfigCallback(CredentialsAuthenticator.getTransportConfigCallback(getOnlineRepositoryURL(), npw));
- pullCommand.setRebase(false); // Merge, not rebase
- pullCommand.setProgressMonitor(monitor);
- return pullCommand.call();
- }
- }
-
- @Override
- public FetchResult fetchFromRemote(UsernamePassword npw, ProgressMonitor monitor, boolean isDryrun) throws IOException, GitAPIException {
- try(Git git = Git.open(getLocalRepositoryFolder())) {
- // Check and set tracked master branch
- setTrackedBranch(git.getRepository(), IGraficoConstants.MASTER);
- FetchCommand fetchCommand = git.fetch();
- fetchCommand.setTransportConfigCallback(CredentialsAuthenticator.getTransportConfigCallback(getOnlineRepositoryURL(), npw));
- fetchCommand.setProgressMonitor(monitor);
- fetchCommand.setDryRun(isDryrun);
- return fetchCommand.call();
- }
- }
-
- @Override
- public Git createNewLocalGitRepository(String URL) throws GitAPIException, IOException, URISyntaxException {
- if(getLocalRepositoryFolder().exists() && getLocalRepositoryFolder().list().length > 0) {
- throw new IOException("Directory: " + getLocalRepositoryFolder().getAbsolutePath() + " is not empty."); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- InitCommand initCommand = Git.init();
- initCommand.setDirectory(getLocalRepositoryFolder());
- Git git = initCommand.call();
-
- RemoteAddCommand remoteAddCommand = git.remoteAdd();
- remoteAddCommand.setName(IGraficoConstants.ORIGIN);
- remoteAddCommand.setUri(new URIish(URL));
- remoteAddCommand.call();
-
- setDefaultConfigSettings(git.getRepository());
-
- // Set tracked master branch
- setTrackedBranch(git.getRepository(), IGraficoConstants.MASTER);
-
- return git;
- }
-
- @Override
- public byte[] getFileContents(String path, String ref) throws IOException {
- byte[] bytes = null;
-
- try(Repository repository = Git.open(getLocalRepositoryFolder()).getRepository()) {
- ObjectId lastCommitId = repository.resolve(ref);
-
- try(RevWalk revWalk = new RevWalk(repository)) {
- RevCommit commit = revWalk.parseCommit(lastCommitId);
- RevTree tree = commit.getTree();
-
- // now try to find a specific file
- try(TreeWalk treeWalk = new TreeWalk(repository)) {
- treeWalk.addTree(tree);
- treeWalk.setRecursive(true);
- treeWalk.setFilter(PathFilter.create(path));
-
- // Not found, return null
- if(!treeWalk.next()) {
- return null;
- }
-
- ObjectId objectId = treeWalk.getObjectId(0);
- ObjectLoader loader = repository.open(objectId);
-
- bytes = loader.getBytes();
- }
-
- revWalk.dispose();
- }
- }
-
- return bytes;
- }
-
- @Override
- public String getWorkingTreeFileContents(String path) throws IOException {
- String str = ""; //$NON-NLS-1$
-
- try(Git git = Git.open(getLocalRepositoryFolder())) {
- try(BufferedReader in = new BufferedReader(new FileReader(new File(getLocalRepositoryFolder(), path)))) {
- String line;
- while((line = in.readLine()) != null) {
- str += line + "\n"; //$NON-NLS-1$
- }
- }
- }
-
- return str;
- }
-
- @Override
- public void resetToRef(String ref) throws IOException, GitAPIException {
- // Check lock file is deleted
- checkDeleteLockFile();
-
- try(Git git = Git.open(getLocalRepositoryFolder())) {
- // Reset to master
- ResetCommand resetCommand = git.reset();
- resetCommand.setRef(ref);
- resetCommand.setMode(ResetType.HARD);
- resetCommand.call();
-
- // Clean extra files
- CleanCommand cleanCommand = git.clean();
- cleanCommand.setCleanDirectories(true);
- cleanCommand.call();
- }
- }
-
- @Override
- public boolean isHeadAndRemoteSame() throws IOException, GitAPIException {
- try(Repository repository = Git.open(getLocalRepositoryFolder()).getRepository()) {
- // Get remote branch ref
- BranchInfo currentRemoteBranch = getBranchStatus().getCurrentRemoteBranch();
- if(currentRemoteBranch == null) {
- return false;
- }
-
- // Remote
- Ref remoteRef = currentRemoteBranch.getRef();
-
- // Head
- Ref headRef = repository.findRef(HEAD);
-
- // In case of missing ref return false
- if(headRef == null || remoteRef == null) {
- return false;
- }
-
- return headRef.getObjectId().equals(remoteRef.getObjectId());
- }
- }
-
- @Override
- public void exportModelToGraficoFiles() throws IOException, GitAPIException {
- // Open the model before showing the progress monitor
- IArchimateModel model = IEditorModelManager.INSTANCE.openModel(getTempModelFile());
-
- if(model == null) {
- throw new IOException(Messages.ArchiRepository_0);
- }
-
- final Exception[] exception = new Exception[1];
-
- try {
- // When using this be careful that no UI operations are called as this could lead to an SWT Invalid thread access exception
- // This will show a Cancel button which will not cancel, but this progress monitor is the only one which does not freeze the UI
- PlatformUI.getWorkbench().getProgressService().busyCursorWhile(new IRunnableWithProgress() {
- @Override
- public void run(IProgressMonitor pm) {
- pm.beginTask(Messages.ArchiRepository_1, IProgressMonitor.UNKNOWN);
-
- try {
- // Export
- GraficoModelExporter exporter = new GraficoModelExporter(model, getLocalRepositoryFolder());
- exporter.exportModel();
-
- // Check lock file is deleted
- checkDeleteLockFile();
-
- // Stage modified files to index - this can take a long time!
- // This will clear any different line endings and calls to git.status() will be faster
- try(Git git = Git.open(getLocalRepositoryFolder())) {
- AddCommand addCommand = git.add();
- addCommand.addFilepattern("."); //$NON-NLS-1$
- addCommand.setUpdate(false);
- addCommand.call();
- }
- }
- catch(IOException | GitAPIException ex) {
- exception[0] = ex;
- }
- }
- });
- }
- catch(InvocationTargetException | InterruptedException ex) {
- throw new IOException(ex);
- }
-
- if(exception[0] instanceof IOException) {
- throw (IOException)exception[0];
- }
- if(exception[0] instanceof GitAPIException) {
- throw (GitAPIException)exception[0];
- }
- }
-
- @Override
- public PersonIdent getUserDetails() throws IOException {
- try(Git git = Git.open(getLocalRepositoryFolder())) {
- StoredConfig config = git.getRepository().getConfig();
- String name = StringUtils.safeString(config.getString(ConfigConstants.CONFIG_USER_SECTION, null, ConfigConstants.CONFIG_KEY_NAME));
- String email = StringUtils.safeString(config.getString(ConfigConstants.CONFIG_USER_SECTION, null, ConfigConstants.CONFIG_KEY_EMAIL));
- return new PersonIdent(name, email);
- }
- }
-
- @Override
- public void saveUserDetails(String name, String email) throws IOException {
- // Get global user details from .gitconfig for comparison
- PersonIdent global = new PersonIdent("", ""); //$NON-NLS-1$ //$NON-NLS-2$
-
- try {
- global = GraficoUtils.getGitConfigUserDetails();
- }
- catch(ConfigInvalidException ex) {
- ex.printStackTrace();
- }
-
- // Save to local config
- try(Git git = Git.open(getLocalRepositoryFolder())) {
- StoredConfig config = git.getRepository().getConfig();
-
- // If global name == local name or blank then unset
- if(!StringUtils.isSet(name) || global.getName().equals(name)) {
- config.unset(ConfigConstants.CONFIG_USER_SECTION, null, ConfigConstants.CONFIG_KEY_NAME);
- }
- // Set
- else {
- config.setString(ConfigConstants.CONFIG_USER_SECTION, null, ConfigConstants.CONFIG_KEY_NAME, name);
- }
-
- // If global email == local email or blank then unset
- if(!StringUtils.isSet(email) || global.getEmailAddress().equals(email)) {
- config.unset(ConfigConstants.CONFIG_USER_SECTION, null, ConfigConstants.CONFIG_KEY_EMAIL);
- }
- else {
- config.setString(ConfigConstants.CONFIG_USER_SECTION, null, ConfigConstants.CONFIG_KEY_EMAIL, email);
- }
-
- config.save();
- }
- }
-
- @Override
- public boolean equals(Object obj) {
- if((obj != null) && (obj instanceof ArchiRepository)) {
- return fLocalRepoFolder != null && fLocalRepoFolder.equals(((IArchiRepository)obj).getLocalRepositoryFolder());
- }
- return false;
- }
-
- /**
- * Set default settings in the config file
- * @param repository
- * @throws IOException
- */
- private void setDefaultConfigSettings(Repository repository) throws IOException {
- StoredConfig config = repository.getConfig();
-
- /*
- * Set Line endings in the config file to autocrlf=input
- * This ensures that files are not seen as different
- */
- config.setString(ConfigConstants.CONFIG_CORE_SECTION, null, ConfigConstants.CONFIG_KEY_AUTOCRLF, "input"); //$NON-NLS-1$
-
- /*
- * Set longpaths=true because garbage collection is not possible otherwise
- * See https://stackoverflow.com/questions/22575662/filename-too-long-in-git-for-windows
- */
- config.setString(ConfigConstants.CONFIG_CORE_SECTION, null, "longpaths", "true"); //$NON-NLS-1$ //$NON-NLS-2$
-
- config.save();
- }
-
- /**
- * Set the given branchName to track "origin"
- */
- private void setTrackedBranch(Repository repository, String branchName) throws IOException {
- if(branchName == null) {
- return;
- }
-
- StoredConfig config = repository.getConfig();
-
- if(!IGraficoConstants.ORIGIN.equals(config.getString(ConfigConstants.CONFIG_BRANCH_SECTION, branchName, ConfigConstants.CONFIG_KEY_REMOTE))) {
- config.setString(ConfigConstants.CONFIG_BRANCH_SECTION, branchName, ConfigConstants.CONFIG_KEY_REMOTE, IGraficoConstants.ORIGIN);
- config.setString(ConfigConstants.CONFIG_BRANCH_SECTION, branchName, ConfigConstants.CONFIG_KEY_MERGE, Constants.R_HEADS + branchName);
- config.save();
- }
- }
-
-
- @Override
- public boolean hasLocalChanges() throws IOException {
- String latestChecksum = getLatestChecksum();
- if(latestChecksum == null) {
- return false;
- }
-
- String currentChecksum = createChecksum();
- return !latestChecksum.equals(currentChecksum);
- }
-
- @Override
- public boolean saveChecksum() throws IOException {
- // Get the file's checksum as string
- String checksum = createChecksum();
- if(checksum == null) {
- return false;
- }
-
- File checksumFile = new File(getLocalGitFolder(), "checksum"); //$NON-NLS-1$
- Files.write(Paths.get(checksumFile.getAbsolutePath()), checksum.getBytes(), StandardOpenOption.CREATE);
-
- return true;
- }
-
- @Override
- public BranchStatus getBranchStatus() throws IOException, GitAPIException {
- return new BranchStatus(this);
- }
-
- private String getLatestChecksum() throws IOException {
- File checksumFile = new File(getLocalGitFolder(), "checksum"); //$NON-NLS-1$
- if(!checksumFile.exists()) {
- return null;
- }
-
- byte[] bytes = Files.readAllBytes(Paths.get(checksumFile.getAbsolutePath()));
- return new String(bytes);
- }
-
- private String createChecksum() throws IOException {
- File tempFile = getTempModelFile();
-
- if(tempFile == null) {
- return null;
- }
-
- MessageDigest digest = null;
- try {
- digest = MessageDigest.getInstance("MD5"); //$NON-NLS-1$
- }
- catch(NoSuchAlgorithmException ex) {
- throw new IOException("NoSuchAlgorithm Exception", ex); //$NON-NLS-1$
- }
-
- // Get file input stream for reading the file content
- FileInputStream fis = new FileInputStream(tempFile);
-
- // Create byte array to read data in chunks
- byte[] byteArray = new byte[1024];
- int bytesCount = 0;
-
- // Read file data and update in message digest
- while((bytesCount = fis.read(byteArray)) != -1) {
- digest.update(byteArray, 0, bytesCount);
- }
-
- fis.close();
-
- // Get the hash's bytes
- byte[] bytes = digest.digest();
-
- // This bytes[] has bytes in decimal format;
- // Convert it to hexadecimal format
- StringBuilder sb = new StringBuilder();
- for(int i = 0; i < bytes.length; i++) {
- sb.append(Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1));
- }
-
- return sb.toString();
- }
-
- /**
- * In some cases the lock file exists and leads to an error, so we delete it
- */
- private void checkDeleteLockFile() {
- File lockFile = new File(getLocalGitFolder(), "index.lock"); //$NON-NLS-1$
- if(lockFile.exists() && lockFile.canWrite()) {
- lockFile.delete();
- }
- }
+
+ /**
+ * The folder location of the local repository
+ */
+ private File fLocalRepoFolder;
+
+ public ArchiRepository(File localRepoFolder) {
+ fLocalRepoFolder = localRepoFolder;
+ }
+
+ @Override
+ public File getLocalRepositoryFolder() {
+ return fLocalRepoFolder;
+ }
+
+ @Override
+ public File getLocalGitFolder() {
+ return new File(getLocalRepositoryFolder(), ".git"); //$NON-NLS-1$
+ }
+
+ @Override
+ public String getName() {
+ String[] result = new String[1];
+
+ // Find the "folder.xml" file and read it from there
+ File file = new File(getLocalRepositoryFolder(),
+ IGraficoConstants.MODEL_FOLDER + "/" + IGraficoConstants.FOLDER_XML); //$NON-NLS-1$
+ if (file.exists()) {
+ try (Stream stream = Files.lines(Paths.get(file.getAbsolutePath()))) {
+ stream.forEach(s -> {
+ if (result[0] == null && s.indexOf("name=") != -1) { //$NON-NLS-1$
+ String segments[] = s.split("\""); //$NON-NLS-1$
+ if (segments.length == 2) {
+ result[0] = segments[1];
+ }
+ }
+ });
+ } catch (IOException ex) {
+ ex.printStackTrace();
+ }
+ }
+
+ return result[0] != null ? result[0] : fLocalRepoFolder.getName();
+ }
+
+ @Override
+ public File getTempModelFile() {
+ return new File(getLocalRepositoryFolder(), "/.git/" + IGraficoConstants.LOCAL_ARCHI_FILENAME); //$NON-NLS-1$
+ }
+
+ @Override
+ public String getOnlineRepositoryURL() throws IOException {
+ try (Git git = Git.open(getLocalRepositoryFolder())) {
+ return git.getRepository().getConfig().getString("remote", IGraficoConstants.ORIGIN, "url"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+
+ @Override
+ public IArchimateModel locateModel() {
+ File tempFile = getTempModelFile();
+
+ for (IArchimateModel model : IEditorModelManager.INSTANCE.getModels()) {
+ if (tempFile.equals(model.getFile())) {
+ return model;
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ public boolean hasChangesToCommit() throws IOException, GitAPIException {
+ try (Git git = Git.open(getLocalRepositoryFolder())) {
+ Status status = git.status().call();
+ return !status.isClean();
+ }
+ }
+
+ @Override
+ public RevCommit commitChanges(String commitMessage, boolean amend) throws GitAPIException, IOException {
+ try (Git git = Git.open(getLocalRepositoryFolder())) {
+ Status status = git.status().call();
+
+ // Nothing changed
+ if (status.isClean()) {
+ return null;
+ }
+
+ // Check lock file is deleted
+ checkDeleteLockFile();
+
+ // Add modified files to index
+ AddCommand addCommand = git.add();
+ addCommand.addFilepattern("."); //$NON-NLS-1$
+ addCommand.setUpdate(false);
+ addCommand.call();
+
+ // Add missing files to index
+ for (String s : status.getMissing()) {
+ git.rm().addFilepattern(s).call();
+ }
+
+ // Commit
+ CommitCommand commitCommand = git.commit();
+ PersonIdent userDetails = getUserDetails();
+ commitCommand.setAuthor(userDetails);
+ commitCommand.setMessage(commitMessage);
+ commitCommand.setAmend(amend);
+ return commitCommand.call();
+ }
+ }
+
+ @Override
+ public void cloneModel(String repoURL, UsernamePassword npw, ProgressMonitor monitor)
+ throws GitAPIException, IOException {
+
+ CloneCommand cloneCommand = Git.cloneRepository();
+ cloneCommand.setDirectory(getLocalRepositoryFolder());
+ cloneCommand.setURI(repoURL);
+ cloneCommand.setTransportConfigCallback(CredentialsAuthenticator.getTransportConfigCallback(repoURL, npw));
+ cloneCommand.setProgressMonitor(monitor);
+
+ try (Git git = cloneCommand.call()) {
+ setDefaultConfigSettings(git.getRepository());
+ }
+ }
+
+ @Override
+ public Iterable pushToRemote(UsernamePassword npw, ProgressMonitor monitor)
+ throws IOException, GitAPIException {
+ try (Git git = Git.open(getLocalRepositoryFolder())) {
+ PushCommand pushCommand = git.push();
+ pushCommand.setTransportConfigCallback(
+ CredentialsAuthenticator.getTransportConfigCallback(getOnlineRepositoryURL(), npw));
+ pushCommand.setProgressMonitor(monitor);
+
+ Iterable result = pushCommand.call();
+
+ // After a successful push, ensure we are tracking the current branch
+ setTrackedBranch(git.getRepository(), git.getRepository().getBranch());
+
+ return result;
+ }
+ }
+
+ @Override
+ public PullResult pullFromRemote(UsernamePassword npw, ProgressMonitor monitor)
+ throws IOException, GitAPIException {
+ try (Git git = Git.open(getLocalRepositoryFolder())) {
+ PullCommand pullCommand = git.pull();
+ pullCommand.setTransportConfigCallback(
+ CredentialsAuthenticator.getTransportConfigCallback(getOnlineRepositoryURL(), npw));
+ pullCommand.setRebase(false); // Merge, not rebase
+ pullCommand.setProgressMonitor(monitor);
+ return pullCommand.call();
+ }
+ }
+
+ @Override
+ public FetchResult fetchFromRemote(UsernamePassword npw, ProgressMonitor monitor, boolean isDryrun)
+ throws IOException, GitAPIException {
+ try (Git git = Git.open(getLocalRepositoryFolder())) {
+ // Check and set tracked master branch
+ setTrackedBranch(git.getRepository(), IGraficoConstants.MASTER);
+ FetchCommand fetchCommand = git.fetch();
+ fetchCommand.setTransportConfigCallback(
+ CredentialsAuthenticator.getTransportConfigCallback(getOnlineRepositoryURL(), npw));
+ fetchCommand.setProgressMonitor(monitor);
+ fetchCommand.setDryRun(isDryrun);
+ return fetchCommand.call();
+ }
+ }
+
+ @Override
+ public Git createNewLocalGitRepository(String URL) throws GitAPIException, IOException, URISyntaxException {
+ if (getLocalRepositoryFolder().exists() && getLocalRepositoryFolder().list().length > 0) {
+ throw new IOException("Directory: " + getLocalRepositoryFolder().getAbsolutePath() + " is not empty."); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ InitCommand initCommand = Git.init();
+ initCommand.setDirectory(getLocalRepositoryFolder());
+ Git git = initCommand.call();
+
+ RemoteAddCommand remoteAddCommand = git.remoteAdd();
+ remoteAddCommand.setName(IGraficoConstants.ORIGIN);
+ remoteAddCommand.setUri(new URIish(URL));
+ remoteAddCommand.call();
+
+ setDefaultConfigSettings(git.getRepository());
+
+ // Set tracked master branch
+ setTrackedBranch(git.getRepository(), IGraficoConstants.MASTER);
+
+ return git;
+ }
+
+ @Override
+ public byte[] getFileContents(String path, String ref) throws IOException {
+ byte[] bytes = null;
+
+ try (Repository repository = Git.open(getLocalRepositoryFolder()).getRepository()) {
+ ObjectId lastCommitId = repository.resolve(ref);
+
+ try (RevWalk revWalk = new RevWalk(repository)) {
+ RevCommit commit = revWalk.parseCommit(lastCommitId);
+ RevTree tree = commit.getTree();
+
+ // now try to find a specific file
+ try (TreeWalk treeWalk = new TreeWalk(repository)) {
+ treeWalk.addTree(tree);
+ treeWalk.setRecursive(true);
+ treeWalk.setFilter(PathFilter.create(path));
+
+ // Not found, return null
+ if (!treeWalk.next()) {
+ return null;
+ }
+
+ ObjectId objectId = treeWalk.getObjectId(0);
+ ObjectLoader loader = repository.open(objectId);
+
+ bytes = loader.getBytes();
+ }
+
+ revWalk.dispose();
+ }
+ }
+
+ return bytes;
+ }
+
+ @Override
+ public String getWorkingTreeFileContents(String path) throws IOException {
+ String str = ""; //$NON-NLS-1$
+
+ try (Git git = Git.open(getLocalRepositoryFolder())) {
+ try (BufferedReader in = new BufferedReader(new FileReader(new File(getLocalRepositoryFolder(), path)))) {
+ String line;
+ while ((line = in.readLine()) != null) {
+ str += line + "\n"; //$NON-NLS-1$
+ }
+ }
+ }
+
+ return str;
+ }
+
+ @Override
+ public void resetToRef(String ref) throws IOException, GitAPIException {
+ // Check lock file is deleted
+ checkDeleteLockFile();
+
+ try (Git git = Git.open(getLocalRepositoryFolder())) {
+ // Reset to master
+ ResetCommand resetCommand = git.reset();
+ resetCommand.setRef(ref);
+ resetCommand.setMode(ResetType.HARD);
+ resetCommand.call();
+
+ // Clean extra files
+ CleanCommand cleanCommand = git.clean();
+ cleanCommand.setCleanDirectories(true);
+ cleanCommand.call();
+ }
+ }
+
+ @Override
+ public boolean isHeadAndRemoteSame() throws IOException, GitAPIException {
+ try (Repository repository = Git.open(getLocalRepositoryFolder()).getRepository()) {
+ // Get remote branch ref
+ BranchInfo currentRemoteBranch = getBranchStatus().getCurrentRemoteBranch();
+ if (currentRemoteBranch == null) {
+ return false;
+ }
+
+ // Remote
+ Ref remoteRef = currentRemoteBranch.getRef();
+
+ // Head
+ Ref headRef = repository.findRef(HEAD);
+
+ // In case of missing ref return false
+ if (headRef == null || remoteRef == null) {
+ return false;
+ }
+
+ return headRef.getObjectId().equals(remoteRef.getObjectId());
+ }
+ }
+
+ @Override
+ public void exportModelToGraficoFiles() throws IOException, GitAPIException {
+ // Open the model before showing the progress monitor
+ IArchimateModel model = IEditorModelManager.INSTANCE.openModel(getTempModelFile());
+
+ if (model == null) {
+ throw new IOException(Messages.ArchiRepository_0);
+ }
+
+ final Exception[] exception = new Exception[1];
+
+ try {
+ // When using this be careful that no UI operations are called as this could
+ // lead to an SWT Invalid thread access exception
+ // This will show a Cancel button which will not cancel, but this progress
+ // monitor is the only one which does not freeze the UI
+ PlatformUI.getWorkbench().getProgressService().busyCursorWhile(new IRunnableWithProgress() {
+ @Override
+ public void run(IProgressMonitor pm) {
+ pm.beginTask(Messages.ArchiRepository_1, IProgressMonitor.UNKNOWN);
+
+ try {
+ // Export
+ GraficoModelExporter exporter = new GraficoModelExporter(model, getLocalRepositoryFolder());
+ exporter.exportModel();
+
+ // Check lock file is deleted
+ checkDeleteLockFile();
+
+ // Stage modified files to index - this can take a long time!
+ // This will clear any different line endings and calls to git.status() will be
+ // faster
+ try (Git git = Git.open(getLocalRepositoryFolder())) {
+ AddCommand addCommand = git.add();
+ addCommand.addFilepattern("."); //$NON-NLS-1$
+ addCommand.setUpdate(false);
+ addCommand.call();
+ }
+ } catch (IOException | GitAPIException ex) {
+ exception[0] = ex;
+ }
+ }
+ });
+ } catch (InvocationTargetException | InterruptedException ex) {
+ throw new IOException(ex);
+ }
+
+ if (exception[0] instanceof IOException) {
+ throw (IOException) exception[0];
+ }
+ if (exception[0] instanceof GitAPIException) {
+ throw (GitAPIException) exception[0];
+ }
+ }
+
+ @Override
+ public PersonIdent getUserDetails() throws IOException {
+ try (Git git = Git.open(getLocalRepositoryFolder())) {
+ StoredConfig config = git.getRepository().getConfig();
+ String name = StringUtils.safeString(
+ config.getString(ConfigConstants.CONFIG_USER_SECTION, null, ConfigConstants.CONFIG_KEY_NAME));
+ String email = StringUtils.safeString(
+ config.getString(ConfigConstants.CONFIG_USER_SECTION, null, ConfigConstants.CONFIG_KEY_EMAIL));
+ return new PersonIdent(name, email);
+ }
+ }
+
+ @Override
+ public void saveUserDetails(String name, String email) throws IOException {
+ // Get global user details from .gitconfig for comparison
+ PersonIdent global = new PersonIdent("", ""); //$NON-NLS-1$ //$NON-NLS-2$
+
+ try {
+ global = GraficoUtils.getGitConfigUserDetails();
+ } catch (ConfigInvalidException ex) {
+ ex.printStackTrace();
+ }
+
+ // Save to local config
+ try (Git git = Git.open(getLocalRepositoryFolder())) {
+ StoredConfig config = git.getRepository().getConfig();
+
+ // If global name == local name or blank then unset
+ if (!StringUtils.isSet(name) || global.getName().equals(name)) {
+ config.unset(ConfigConstants.CONFIG_USER_SECTION, null, ConfigConstants.CONFIG_KEY_NAME);
+ }
+ // Set
+ else {
+ config.setString(ConfigConstants.CONFIG_USER_SECTION, null, ConfigConstants.CONFIG_KEY_NAME, name);
+ }
+
+ // If global email == local email or blank then unset
+ if (!StringUtils.isSet(email) || global.getEmailAddress().equals(email)) {
+ config.unset(ConfigConstants.CONFIG_USER_SECTION, null, ConfigConstants.CONFIG_KEY_EMAIL);
+ } else {
+ config.setString(ConfigConstants.CONFIG_USER_SECTION, null, ConfigConstants.CONFIG_KEY_EMAIL, email);
+ }
+
+ config.save();
+ }
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if ((obj != null) && (obj instanceof ArchiRepository)) {
+ return fLocalRepoFolder != null
+ && fLocalRepoFolder.equals(((IArchiRepository) obj).getLocalRepositoryFolder());
+ }
+ return false;
+ }
+
+ /**
+ * Set default settings in the config file
+ *
+ * @param repository
+ * @throws IOException
+ */
+ private void setDefaultConfigSettings(Repository repository) throws IOException {
+ StoredConfig config = repository.getConfig();
+
+ /*
+ * Set Line endings in the config file to autocrlf=input This ensures that files
+ * are not seen as different
+ */
+ config.setString(ConfigConstants.CONFIG_CORE_SECTION, null, ConfigConstants.CONFIG_KEY_AUTOCRLF, "input"); //$NON-NLS-1$
+
+ /*
+ * Set longpaths=true because garbage collection is not possible otherwise See
+ * https://stackoverflow.com/questions/22575662/filename-too-long-in-git-for-
+ * windows
+ */
+ config.setString(ConfigConstants.CONFIG_CORE_SECTION, null, "longpaths", "true"); //$NON-NLS-1$ //$NON-NLS-2$
+
+ config.save();
+ }
+
+ /**
+ * Set the given branchName to track "origin"
+ */
+ private void setTrackedBranch(Repository repository, String branchName) throws IOException {
+ if (branchName == null) {
+ return;
+ }
+
+ StoredConfig config = repository.getConfig();
+
+ if (!IGraficoConstants.ORIGIN.equals(config.getString(ConfigConstants.CONFIG_BRANCH_SECTION, branchName,
+ ConfigConstants.CONFIG_KEY_REMOTE))) {
+ config.setString(ConfigConstants.CONFIG_BRANCH_SECTION, branchName, ConfigConstants.CONFIG_KEY_REMOTE,
+ IGraficoConstants.ORIGIN);
+ config.setString(ConfigConstants.CONFIG_BRANCH_SECTION, branchName, ConfigConstants.CONFIG_KEY_MERGE,
+ Constants.R_HEADS + branchName);
+ config.save();
+ }
+ }
+
+ @Override
+ public boolean hasLocalChanges() throws IOException {
+ String latestChecksum = getLatestChecksum();
+ if (latestChecksum == null) {
+ return false;
+ }
+
+ String currentChecksum = createChecksum();
+ return !latestChecksum.equals(currentChecksum);
+ }
+
+ @Override
+ public boolean saveChecksum() throws IOException {
+ // Get the file's checksum as string
+ String checksum = createChecksum();
+ if (checksum == null) {
+ return false;
+ }
+
+ File checksumFile = new File(getLocalGitFolder(), "checksum"); //$NON-NLS-1$
+ Files.write(Paths.get(checksumFile.getAbsolutePath()), checksum.getBytes(), StandardOpenOption.CREATE);
+
+ return true;
+ }
+
+ @Override
+ public BranchStatus getBranchStatus() throws IOException, GitAPIException {
+ return new BranchStatus(this);
+ }
+
+ private String getLatestChecksum() throws IOException {
+ File checksumFile = new File(getLocalGitFolder(), "checksum"); //$NON-NLS-1$
+ if (!checksumFile.exists()) {
+ return null;
+ }
+
+ byte[] bytes = Files.readAllBytes(Paths.get(checksumFile.getAbsolutePath()));
+ return new String(bytes);
+ }
+
+ private String createChecksum() throws IOException {
+ File tempFile = getTempModelFile();
+
+ if (tempFile == null) {
+ return null;
+ }
+
+ MessageDigest digest = null;
+ try {
+ digest = MessageDigest.getInstance("MD5"); //$NON-NLS-1$
+ } catch (NoSuchAlgorithmException ex) {
+ throw new IOException("NoSuchAlgorithm Exception", ex); //$NON-NLS-1$
+ }
+
+ // Get file input stream for reading the file content
+ FileInputStream fis = new FileInputStream(tempFile);
+
+ // Create byte array to read data in chunks
+ byte[] byteArray = new byte[1024];
+ int bytesCount = 0;
+
+ // Read file data and update in message digest
+ while ((bytesCount = fis.read(byteArray)) != -1) {
+ digest.update(byteArray, 0, bytesCount);
+ }
+
+ fis.close();
+
+ // Get the hash's bytes
+ byte[] bytes = digest.digest();
+
+ // This bytes[] has bytes in decimal format;
+ // Convert it to hexadecimal format
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < bytes.length; i++) {
+ sb.append(Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1));
+ }
+
+ return sb.toString();
+ }
+
+ /**
+ * In some cases the lock file exists and leads to an error, so we delete it
+ */
+ private void checkDeleteLockFile() {
+ File lockFile = new File(getLocalGitFolder(), "index.lock"); //$NON-NLS-1$
+ if (lockFile.exists() && lockFile.canWrite()) {
+ lockFile.delete();
+ }
+ }
}
diff --git a/org.archicontribs.modelrepository/src/org/archicontribs/modelrepository/preferences/ModelRepositoryPreferencePage.java b/org.archicontribs.modelrepository/src/org/archicontribs/modelrepository/preferences/ModelRepositoryPreferencePage.java
index 601a881a..cd819b26 100644
--- a/org.archicontribs.modelrepository/src/org/archicontribs/modelrepository/preferences/ModelRepositoryPreferencePage.java
+++ b/org.archicontribs.modelrepository/src/org/archicontribs/modelrepository/preferences/ModelRepositoryPreferencePage.java
@@ -228,6 +228,8 @@ public void widgetSelected(SelectionEvent e) {
gd = new GridData(GridData.FILL_HORIZONTAL);
fStoreCredentialsButton.setLayoutData(gd);
+ //HTTP Skip SSL verification
+
// Proxy Group