commit aa997cff75987a02661c2f5a8a362aad10a0dc9c
Author: Cherian Mathew <c.mathew@bgbm.org>
Date:   Tue Oct 14 08:19:29 2014 +0000

    pom.xml : comment for the file permissions problem
    eu.etaxonomy.taxeditor.application/META-INF/MANIFEST.MF : removed version numbers and added plugin for repository metadata
    ApplicationWorkbenchWindowAdvisor : added saving of repositories to post window close
    P2Util, PreferencesUtil, PreferencesUtil  : added loading / saving of repositories from / to preference store
    eu.etaxonomy.taxeditor.store/META-INF/MANIFEST.MF : added plugin for repository metadata

diff --git a/eu.etaxonomy.taxeditor.application/META-INF/MANIFEST.MF b/eu.etaxonomy.taxeditor.application/META-INF/MANIFEST.MF
index 0c9d0d78d..d4c616a67 100644
--- a/eu.etaxonomy.taxeditor.application/META-INF/MANIFEST.MF
+++ b/eu.etaxonomy.taxeditor.application/META-INF/MANIFEST.MF
@@ -11,6 +11,7 @@ Bundle-ActivationPolicy: lazy
 Bundle-RequiredExecutionEnvironment: JavaSE-1.6
 Import-Package: org.apache.log4j,
  org.eclipse.equinox.app,
+ org.eclipse.equinox.p2.repository.metadata,
  org.osgi.framework,
  org.osgi.service.packageadmin
 Require-Bundle: org.eclipse.ui,
@@ -29,5 +30,7 @@ Require-Bundle: org.eclipse.ui,
  org.eclipse.equinox.p2.updatechecker,
  org.eclipse.equinox.p2.operations,
  org.eclipse.help.ui,
- org.eclipse.equinox.p2.metadata;bundle-version="2.1.0",
- org.eclipse.equinox.p2.engine;bundle-version="2.1.1"
+ org.eclipse.equinox.p2.metadata,
+ org.eclipse.equinox.p2.engine,
+ org.eclipse.equinox.p2.metadata.repository,
+ org.eclipse.equinox.p2.repository
diff --git a/eu.etaxonomy.taxeditor.application/src/main/java/eu/etaxonomy/taxeditor/ApplicationWorkbenchWindowAdvisor.java b/eu.etaxonomy.taxeditor.application/src/main/java/eu/etaxonomy/taxeditor/ApplicationWorkbenchWindowAdvisor.java
index 99f3432ff..5e597395a 100644
--- a/eu.etaxonomy.taxeditor.application/src/main/java/eu/etaxonomy/taxeditor/ApplicationWorkbenchWindowAdvisor.java
+++ b/eu.etaxonomy.taxeditor.application/src/main/java/eu/etaxonomy/taxeditor/ApplicationWorkbenchWindowAdvisor.java
@@ -61,10 +61,18 @@ public class ApplicationWorkbenchWindowAdvisor extends WorkbenchWindowAdvisor {
             CdmStore.connect();
         }
 
-		P2Util.setDefaultUpdateRepositories();
+		P2Util.setP2UpdateRepositories();
 
 	}
 
+	/* (non-Javadoc)
+	 * @see org.eclipse.ui.application.WorkbenchWindowAdvisor#postWindowClose()
+	 */
+	@Override
+    public void postWindowClose() {
+        P2Util.saveP2RepositoryPreferences();
+    }
+
 	private int authenticate(){
 		Shell shell = TaxonomicEditorPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getShell();
 
diff --git a/eu.etaxonomy.taxeditor.application/src/main/java/eu/etaxonomy/taxeditor/update/P2Util.java b/eu.etaxonomy.taxeditor.application/src/main/java/eu/etaxonomy/taxeditor/update/P2Util.java
index e666929ac..9e1731c4c 100644
--- a/eu.etaxonomy.taxeditor.application/src/main/java/eu/etaxonomy/taxeditor/update/P2Util.java
+++ b/eu.etaxonomy.taxeditor.application/src/main/java/eu/etaxonomy/taxeditor/update/P2Util.java
@@ -2,19 +2,29 @@ package eu.etaxonomy.taxeditor.update;
 
 import java.net.URI;
 import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.List;
 
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
 import org.eclipse.core.runtime.OperationCanceledException;
 import org.eclipse.core.runtime.Status;
 import org.eclipse.core.runtime.jobs.IJobChangeEvent;
 import org.eclipse.core.runtime.jobs.Job;
 import org.eclipse.core.runtime.jobs.JobChangeAdapter;
+import org.eclipse.equinox.internal.p2.ui.ProvUI;
 import org.eclipse.equinox.internal.p2.ui.model.ElementUtils;
 import org.eclipse.equinox.internal.p2.ui.model.MetadataRepositoryElement;
+import org.eclipse.equinox.p2.repository.IRepository;
+import org.eclipse.equinox.p2.repository.IRepositoryManager;
+import org.eclipse.equinox.p2.repository.metadata.IMetadataRepository;
+import org.eclipse.equinox.p2.repository.metadata.IMetadataRepositoryManager;
 import org.eclipse.equinox.p2.core.IProvisioningAgent;
+import org.eclipse.equinox.p2.core.ProvisionException;
 import org.eclipse.equinox.p2.operations.ProvisioningJob;
 import org.eclipse.equinox.p2.operations.ProvisioningSession;
+import org.eclipse.equinox.p2.operations.RepositoryTracker;
 import org.eclipse.equinox.p2.operations.Update;
 import org.eclipse.equinox.p2.operations.UpdateOperation;
 import org.eclipse.equinox.p2.ui.ProvisioningUI;
@@ -26,6 +36,7 @@ import org.osgi.framework.ServiceReference;
 import eu.etaxonomy.taxeditor.ApplicationUtil;
 import eu.etaxonomy.taxeditor.TaxonomicEditorPlugin;
 import eu.etaxonomy.taxeditor.model.MessagingUtils;
+import eu.etaxonomy.taxeditor.preference.PreferencesUtil;
 
 /**
  * This class is a utility class for updating the editor from a p2 update site,
@@ -36,10 +47,7 @@ import eu.etaxonomy.taxeditor.model.MessagingUtils;
  * - Allow configurable update sites
  *
  * Notes :
- * - tried to get rid of the popup dialog which warns about unsigned jars using
- *   -Declipse.p2.unsignedPolicy=allow but this does not work due to
- *   https://bugs.eclipse.org/bugs/show_bug.cgi?id=391399, so the only solution
- *   is to sign the jars with an official certificate.
+ *
  *
  * @see http://wiki.eclipse.org/Equinox/p2/Adding_Self-Update_to_an_RCP_Application
  * @see http://bugs.eclipse.org/281226
@@ -48,6 +56,7 @@ import eu.etaxonomy.taxeditor.model.MessagingUtils;
 public class P2Util {
 
     //private static String LOCAL_UPDATE_SITE = "file:///path/.../to/Development/EDIT/taxeditor/eu.etaxonomy.taxeditor/target/repository/";
+
     private static String EDIT_NIGHTLY_UPDATE_SITE = "http://cybertaxonomy.eu/download/taxeditor/update/nightly/";
     private static String EDIT_NIGHTLY_UPDATE_SITE_NAME = "Taxonomic Editor Nightly";
 
@@ -57,8 +66,12 @@ public class P2Util {
     private static String EDIT_STABLE_UPDATE_SITE = "http://cybertaxonomy.eu/download/taxeditor/update/stable/";
     private static String EDIT_STABLE_UPDATE_SITE_NAME = "Taxonomic Editor Stable";
 
+    /**
+     * Retrieve and load the saved list of repositories from the preference store,
+     * making sure that at least the default repository is always loaded.
+     */
     @SuppressWarnings("restriction")
-    public static void setDefaultUpdateRepositories() {
+    public static void setP2UpdateRepositories() {
         String updateSite = EDIT_NIGHTLY_UPDATE_SITE;
         String updateSiteName = EDIT_NIGHTLY_UPDATE_SITE_NAME;
 
@@ -66,19 +79,67 @@ public class P2Util {
             updateSite = EDIT_STABLE_UPDATE_SITE;
             updateSiteName = EDIT_STABLE_UPDATE_SITE_NAME;
         }
-        try {
-          final MetadataRepositoryElement element = new MetadataRepositoryElement(null, new URI(updateSite), true);
-          element.setNickname(updateSiteName);
-          ElementUtils.updateRepositoryUsingElements(ProvisioningUI.getDefaultUI(),new MetadataRepositoryElement[] {element}, null);
-        } catch (URISyntaxException e) {
-            MessagingUtils.errorDialog("Invalid update site URI",
-                    P2Util.class,
-                    "The update site URI has an invalid syntax",
-                    TaxonomicEditorPlugin.PLUGIN_ID,
-                    e,
-                    false);
+        List<MetadataRepositoryElement> repoElements = new ArrayList<MetadataRepositoryElement>();
+        List<MetadataRepositoryElement> savedRepoElements = PreferencesUtil.getP2Repositories();
+        if(savedRepoElements.isEmpty()) {
+            // we always need an update site, so we add the default one
+            try {
+                MetadataRepositoryElement element = new MetadataRepositoryElement(null, new URI(updateSite), true);
+                element.setNickname(updateSiteName);
+                repoElements.add(element);
+            } catch (URISyntaxException e) {
+                MessagingUtils.errorDialog("Invalid update site URI",
+                        P2Util.class,
+                        "The update site URI has an invalid syntax",
+                        TaxonomicEditorPlugin.PLUGIN_ID,
+                        e,
+                        false);
+            }
+        }
+        repoElements.addAll(savedRepoElements);
+
+        ElementUtils.updateRepositoryUsingElements(ProvisioningUI.getDefaultUI(),repoElements
+                .toArray(new MetadataRepositoryElement[]{} ), null);
+
+    }
+
+    /**
+     * {@link org.eclipse.equinox.p2.ui.RepositoryManipulationPage} which handles the repsitory site list
+     * in preferences does not create a preference store and hence the changes are not saved. This means
+     * that we need to save it ourselves.
+     *
+     * This method saves the list of current repositories in the preference store as a string with
+     * specific delimiters.
+     */
+
+    public static void saveP2RepositoryPreferences() {
+
+        IMetadataRepositoryManager metaManager = ProvUI.getMetadataRepositoryManager(ProvisioningUI.getDefaultUI().getSession());
+
+        URI[] currentlyEnabled = metaManager.getKnownRepositories(IRepositoryManager.REPOSITORIES_ALL);
+        URI[] currentlyDisabled = metaManager.getKnownRepositories(IRepositoryManager.REPOSITORIES_DISABLED);
+
+        List<MetadataRepositoryElement> repoElements = new ArrayList<MetadataRepositoryElement>();
+
+        for(URI repo : currentlyEnabled) {
+            boolean enabled = true;
+            String nickname = metaManager.getRepositoryProperty(repo, IRepository.PROP_NICKNAME);
+            MetadataRepositoryElement element = new MetadataRepositoryElement(null, repo, true);
+            element.setNickname(nickname);
+            element.setEnabled(enabled);
+            repoElements.add(element);
         }
-      }
+
+        for(URI repo : currentlyDisabled) {
+            boolean enabled = false;
+            String nickname = metaManager.getRepositoryProperty(repo, IRepository.PROP_NICKNAME);
+            MetadataRepositoryElement element = new MetadataRepositoryElement(null, repo, true);
+            element.setNickname(nickname);
+            element.setEnabled(enabled);
+            repoElements.add(element);
+        }
+        PreferencesUtil.setP2Repositories(repoElements);
+    }
 
     /**
      *
diff --git a/eu.etaxonomy.taxeditor.store/META-INF/MANIFEST.MF b/eu.etaxonomy.taxeditor.store/META-INF/MANIFEST.MF
index b3d3d3c49..ca6afae05 100644
--- a/eu.etaxonomy.taxeditor.store/META-INF/MANIFEST.MF
+++ b/eu.etaxonomy.taxeditor.store/META-INF/MANIFEST.MF
@@ -64,7 +64,8 @@ Import-Package: org.eclipse.core.commands,
  org.eclipse.core.expressions,
  org.eclipse.core.runtime,
  org.eclipse.core.runtime.jobs,
- org.eclipse.core.runtime.preferences;
+ org.eclipse.core.runtime.preferences,
+ org.eclipse.equinox.internal.p2.ui.model,
  org.eclipse.jface.action,
  org.eclipse.jface.dialogs,
  org.eclipse.jface.preference,
diff --git a/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/preference/IPreferenceKeys.java b/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/preference/IPreferenceKeys.java
index 213624293..08bc4d825 100644
--- a/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/preference/IPreferenceKeys.java
+++ b/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/preference/IPreferenceKeys.java
@@ -133,4 +133,9 @@ public interface IPreferenceKeys {
 
     public static final String DEFAULT_LANGUAGE_EDITOR = "eu.etaxonomy.taxeditor.default.language";
 
+    /**
+     * Key for the saved P2 repositories
+     */
+    public static final String P2_REPOSITORY_LIST = "eu.etaxonomy.taxeditor.p2.repositories";
+
 }
diff --git a/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/preference/PreferencesUtil.java b/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/preference/PreferencesUtil.java
index a2df5b140..dbf17e601 100644
--- a/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/preference/PreferencesUtil.java
+++ b/eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/preference/PreferencesUtil.java
@@ -13,15 +13,20 @@ import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Properties;
 import java.util.Set;
+import java.util.StringTokenizer;
 import java.util.UUID;
 
 import org.apache.commons.lang.StringUtils;
+import org.eclipse.equinox.internal.p2.ui.model.MetadataRepositoryElement;
 import org.eclipse.jface.preference.IPreferenceStore;
 import org.eclipse.swt.widgets.Shell;
 import org.eclipse.ui.PlatformUI;
@@ -69,6 +74,9 @@ public class PreferencesUtil implements IPreferenceKeys {
 	 */
 	public static final String PREFERRED_TERMS_CHANGE = "preferred_terms";
 
+	public static final String P2_REPOSITORIES_DELIM = ",";
+	public static final String P2_REPOSITORY_FIELDS_DELIM = ";";
+
 	/**
 	 * <p>
 	 * getPreferenceStore
@@ -653,4 +661,53 @@ public class PreferencesUtil implements IPreferenceKeys {
         fos.close();
     }
 
+    /**
+     * Saves a list of P2 Metadata Repositories as string with specified delimiters
+     *
+     * @param p2Repos
+     */
+    public static void setP2Repositories(List<MetadataRepositoryElement> p2Repos) {
+        StringBuilder sb = new StringBuilder();
+        for(MetadataRepositoryElement p2Repo : p2Repos) {
+            sb.append(P2_REPOSITORIES_DELIM);
+            sb.append(p2Repo.getName());
+            sb.append(P2_REPOSITORY_FIELDS_DELIM);
+            sb.append(p2Repo.getLocation().toString());
+            sb.append(P2_REPOSITORY_FIELDS_DELIM);
+            sb.append(String.valueOf(p2Repo.isEnabled()));
+        }
+        getPreferenceStore().setValue(P2_REPOSITORY_LIST, sb.toString());
+    }
+
+
+    /**
+     * Retrieves a list of previously saved P2 repositories
+     *
+     * @return
+     */
+    public static List<MetadataRepositoryElement> getP2Repositories() {
+        List<MetadataRepositoryElement> p2Repos = new ArrayList<MetadataRepositoryElement>();
+        String p2ReposPref =  getPreferenceStore().getString(P2_REPOSITORY_LIST);
+        if(p2ReposPref != null && !p2ReposPref.isEmpty()) {
+            StringTokenizer p2ReposPrefST = new StringTokenizer(p2ReposPref,P2_REPOSITORIES_DELIM);
+            while(p2ReposPrefST.hasMoreTokens()) {
+                String p2RepoStr = p2ReposPrefST.nextToken();
+                StringTokenizer p2ReposStrST = new StringTokenizer(p2RepoStr,P2_REPOSITORY_FIELDS_DELIM);
+                String nickname = p2ReposStrST.nextToken();
+                URI uri = null;
+                try {
+                    uri = new URI(p2ReposStrST.nextToken());
+                } catch (URISyntaxException e) {
+                    continue;
+                }
+                boolean enabled = Boolean.parseBoolean(p2ReposStrST.nextToken());
+                MetadataRepositoryElement mre = new MetadataRepositoryElement(null, uri, true);
+                mre.setNickname(nickname);
+                mre.setEnabled(enabled);
+                p2Repos.add(mre);
+            }
+        }
+
+        return p2Repos;
+    }
 }
diff --git a/eu.etaxonomy.taxeditor/pom.xml b/eu.etaxonomy.taxeditor/pom.xml
index 18f4117a3..22a6e9d99 100644
--- a/eu.etaxonomy.taxeditor/pom.xml
+++ b/eu.etaxonomy.taxeditor/pom.xml
@@ -95,6 +95,8 @@
     </profile>
     <profile>
       <!-- Upload the repo to the server -->
+      <!-- ATTENTION : This does not work well currently since the file permissions
+           are set with read permission set to off after upload -->
       <id>uploadRepo</id>
       <build>
         <plugins>
