From c120ffed220ea4ec85d90095e8b939e57dd3f588 Mon Sep 17 00:00:00 2001 From: Raphael Date: Thu, 25 Jun 2009 17:13:57 -0700 Subject: [PATCH] SDK Updater: logic to load/save user sources and to delete them. --- .../sdklib/internal/repository/RepoSource.java | 20 +++- .../sdklib/internal/repository/RepoSources.java | 122 ++++++++++++++++++++- .../internal/repository/RemotePackagesPage.java | 35 +++++- .../internal/repository/RepoSourcesAdapter.java | 2 +- .../sdkuilib/internal/repository/UpdaterData.java | 6 +- .../internal/repository/UpdaterWindowImpl.java | 20 +++- 6 files changed, 185 insertions(+), 20 deletions(-) diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/RepoSource.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/RepoSource.java index b72e7a9d8..498cfab09 100755 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/RepoSource.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/RepoSource.java @@ -47,7 +47,7 @@ import javax.xml.validation.Validator; public class RepoSource implements IDescription { private final String mUrl; - private final boolean mAddonOnly; + private final boolean mUserSource; private Package[] mPackages; private String mDescription; @@ -55,12 +55,18 @@ public class RepoSource implements IDescription { /** * Constructs a new source for the given repository URL. */ - public RepoSource(String url, boolean addonOnly) { + public RepoSource(String url, boolean userSource) { mUrl = url; - mAddonOnly = addonOnly; + mUserSource = userSource; setDefaultDescription(); } + /** Returns true if this is a user source. We only load addon and extra packages + * from a user source and ignore the rest. */ + public boolean isUserSource() { + return mUserSource; + } + /** Returns the URL of the repository.xml file for this source. */ public String getUrl() { return mUrl; @@ -138,7 +144,7 @@ public class RepoSource implements IDescription { } private void setDefaultDescription() { - if (mAddonOnly) { + if (mUserSource) { mDescription = String.format("Add-on Source: %1$s", mUrl); } else { mDescription = String.format("SDK Source: %1$s", mUrl); @@ -274,13 +280,17 @@ public class RepoSource implements IDescription { Package p = null; try { + // We can load addon and extra packages from all sources, either + // internal or user sources. if (SdkRepository.NODE_ADD_ON.equals(name)) { p = new AddonPackage(this, child, licenses); } else if (SdkRepository.NODE_EXTRA.equals(name)) { p = new ExtraPackage(this, child, licenses); - } else if (!mAddonOnly) { + } else if (!mUserSource) { + // We only load platform, doc and tool packages from internal + // sources, never from user sources. if (SdkRepository.NODE_PLATFORM.equals(name)) { p = new PlatformPackage(this, child, licenses); } else if (SdkRepository.NODE_DOC.equals(name)) { diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/RepoSources.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/RepoSources.java index 42462d90b..7a024c464 100755 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/RepoSources.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/repository/RepoSources.java @@ -16,13 +16,28 @@ package com.android.sdklib.internal.repository; +import com.android.prefs.AndroidLocation; +import com.android.prefs.AndroidLocation.AndroidLocationException; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; import java.util.ArrayList; +import java.util.Iterator; +import java.util.Properties; /** * A list of sdk-repository sources. */ public class RepoSources { + private static final String KEY_COUNT = "count"; + + private static final String KEY_SRC = "src"; + + private static final String SRC_FILENAME = "repositories.cfg"; //$NON-NLS-1$ + private ArrayList mSources = new ArrayList(); public RepoSources() { @@ -36,9 +51,112 @@ public class RepoSources { } /** + * Removes a source from the Sources list. + */ + public void remove(RepoSource source) { + mSources.remove(source); + } + + /** * Returns the sources list array. This is never null. */ - public ArrayList getSources() { - return mSources; + public RepoSource[] getSources() { + return mSources.toArray(new RepoSource[mSources.size()]); + } + + /** + * Loads all user sources. This replaces all existing user sources + * by the ones from the property file. + */ + public void loadUserSources() { + + // Remove all existing user sources + for (Iterator it = mSources.iterator(); it.hasNext(); ) { + RepoSource s = it.next(); + if (s.isUserSource()) { + it.remove(); + } + } + + // Load new user sources from property file + FileInputStream fis = null; + try { + String folder = AndroidLocation.getFolder(); + File f = new File(folder, SRC_FILENAME); + if (f.exists()) { + fis = new FileInputStream(f); + + Properties props = new Properties(); + props.load(fis); + + int count = Integer.parseInt(props.getProperty(KEY_COUNT, "0")); + + for (int i = 0; i < count; i++) { + String url = props.getProperty(String.format("%s%02d", KEY_SRC, count)); //$NON-NLS-1$ + if (url != null) { + mSources.add(new RepoSource(url, true /*userSource*/)); + } + } + } + + } catch (NumberFormatException e) { + // TODO print to log + e.printStackTrace(); + } catch (AndroidLocationException e) { + // TODO print to log + e.printStackTrace(); + } catch (IOException e) { + // TODO print to log + e.printStackTrace(); + } finally { + if (fis != null) { + try { + fis.close(); + } catch (IOException e) { + } + } + } + + } + + /** + * Saves all the user sources. + */ + public void saveUserSources() { + FileOutputStream fos = null; + try { + String folder = AndroidLocation.getFolder(); + File f = new File(folder, SRC_FILENAME); + + fos = new FileOutputStream(f); + + Properties props = new Properties(); + + int count = 0; + for (RepoSource s : mSources) { + if (s.isUserSource()) { + count++; + props.setProperty(String.format("%s%02d", KEY_SRC, count), s.getUrl()); //$NON-NLS-1$ + } + } + props.setProperty(KEY_COUNT, Integer.toString(count)); + + props.store( fos, "## User Sources for Android tool"); //$NON-NLS-1$ + + } catch (AndroidLocationException e) { + // TODO print to log + e.printStackTrace(); + } catch (IOException e) { + // TODO print to log + e.printStackTrace(); + } finally { + if (fos != null) { + try { + fos.close(); + } catch (IOException e) { + } + } + } + } } diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/RemotePackagesPage.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/RemotePackagesPage.java index 108ddddf4..5e32c5a7c 100755 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/RemotePackagesPage.java +++ b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/RemotePackagesPage.java @@ -23,6 +23,7 @@ import com.android.sdklib.internal.repository.Package; import com.android.sdklib.internal.repository.RepoSource; import com.android.sdkuilib.internal.repository.UpdaterData.ISdkListener; +import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.viewers.CheckStateChangedEvent; import org.eclipse.jface.viewers.CheckboxTreeViewer; import org.eclipse.jface.viewers.ICheckStateListener; @@ -288,7 +289,30 @@ public class RemotePackagesPage extends Composite implements ISdkListener { } private void onRemoveSiteSelected() { - // TODO prompt for removing addon site URL, store, refresh + boolean changed = false; + + ISelection sel = mTreeViewerSources.getSelection(); + if (sel instanceof ITreeSelection) { + for (Object c : ((ITreeSelection) sel).toList()) { + if (c instanceof RepoSource && ((RepoSource) c).isUserSource()) { + RepoSource source = (RepoSource) c; + + String title = "Delete Site?"; + + String msg = String.format("Are you sure you want to delete the site '%1$s'?", + source.getUrl()); + + if (MessageDialog.openQuestion(getShell(), title, msg)) { + mUpdaterData.getSources().remove(source); + changed = true; + } + } + } + } + + if (changed) { + onRefreshSelected(); + } } private void onRefreshSelected() { @@ -321,19 +345,20 @@ public class RemotePackagesPage extends Composite implements ISdkListener { } // Is there a selected site Source? - boolean hasSelectedSource = false; + boolean hasSelectedUserSource = false; ISelection sel = mTreeViewerSources.getSelection(); if (sel instanceof ITreeSelection) { for (Object c : ((ITreeSelection) sel).toList()) { - if (c instanceof RepoSource) { - hasSelectedSource = true; + if (c instanceof RepoSource && + ((RepoSource) c).isUserSource()) { + hasSelectedUserSource = true; break; } } } mAddSiteButton.setEnabled(true); - mDeleteSiteButton.setEnabled(hasSelectedSource); + mDeleteSiteButton.setEnabled(hasSelectedUserSource); mRefreshButton.setEnabled(true); mInstallSelectedButton.setEnabled(hasCheckedArchive); } diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/RepoSourcesAdapter.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/RepoSourcesAdapter.java index 4932a5b37..c22f4564f 100755 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/RepoSourcesAdapter.java +++ b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/RepoSourcesAdapter.java @@ -113,7 +113,7 @@ class RepoSourcesAdapter { */ public Object[] getChildren(Object parentElement) { if (parentElement == RepoSourcesAdapter.this) { - return mUpdaterData.getSources().getSources().toArray(); + return mUpdaterData.getSources().getSources(); } else if (parentElement instanceof RepoSource) { final RepoSource source = (RepoSource) parentElement; diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterData.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterData.java index 455abcf65..a0b591ee7 100755 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterData.java +++ b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterData.java @@ -356,8 +356,8 @@ class UpdaterData { mTaskFactory.start("Refresh Sources",new ITask() { public void run(ITaskMonitor monitor) { - ArrayList sources = mSources.getSources(); - monitor.setProgressMax(sources.size()); + RepoSource[] sources = mSources.getSources(); + monitor.setProgressMax(sources.length); for (RepoSource source : sources) { if (forceFetching || source.getPackages() != null) { source.load(monitor.createSubMonitor(1), forceHttp); @@ -406,7 +406,7 @@ class UpdaterData { } else { // Get all the available archives from all loaded sources - ArrayList remoteSources = getSources().getSources(); + RepoSource[] remoteSources = getSources().getSources(); for (RepoSource remoteSrc : remoteSources) { Package[] remotePkgs = remoteSrc.getPackages(); diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterWindowImpl.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterWindowImpl.java index 10cadacf0..8534b96f7 100755 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterWindowImpl.java +++ b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/internal/repository/UpdaterWindowImpl.java @@ -20,6 +20,7 @@ package com.android.sdkuilib.internal.repository; import com.android.sdklib.ISdkLog; import com.android.sdklib.SdkConstants; import com.android.sdklib.internal.repository.RepoSource; +import com.android.sdklib.internal.repository.RepoSources; import com.android.sdklib.repository.SdkRepository; import com.android.sdkuilib.internal.repository.icons.ImageFactory; @@ -93,6 +94,8 @@ public class UpdaterWindowImpl { display.sleep(); } } + + dispose(); //$hide$ } /** @@ -215,12 +218,18 @@ public class UpdaterWindowImpl { displayPage(0); mPageList.setSelection(0); - // TODO read add-on sources from some file setupSources(); initializeSettings(); mUpdaterData.notifyListeners(); } + /** + * Called by the main loop when the window has been disposed. + */ + private void dispose() { + mUpdaterData.getSources().saveUserSources(); + } + // --- page switching --- /** @@ -304,17 +313,20 @@ public class UpdaterWindowImpl { * Used to initialize the sources. */ private void setupSources() { - mUpdaterData.getSources().add( - new RepoSource(SdkRepository.URL_GOOGLE_SDK_REPO_SITE, false /* addonOnly */)); + RepoSources sources = mUpdaterData.getSources(); + sources.add(new RepoSource(SdkRepository.URL_GOOGLE_SDK_REPO_SITE, false /*userSource*/)); String str = System.getenv("TEMP_SDK_URL"); // TODO STOPSHIP temporary remove before shipping if (str != null) { String[] urls = str.split(";"); for (String url : urls) { - mUpdaterData.getSources().add(new RepoSource(url, false /* addonOnly */)); + sources.add(new RepoSource(url, false /*userSource*/)); } } + // Load user sources + sources.loadUserSources(); + mRemotePackagesPage.onSdkChange(); } -- 2.11.0