Skip to content

Commit db3ec47

Browse files
authored
Merge pull request #842 from Sloeber/issue/#679
Issue/#679
2 parents de657c1 + a7cbff8 commit db3ec47

13 files changed

+284
-18
lines changed

io.sloeber.core/src/io/sloeber/core/api/BoardDescriptor.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ private void ParseSection(Map<String, String> boardInfo) {
263263
String refArchitecture = valueSplit[1];
264264
String refVersion = valueSplit[2];
265265
String actualValue = valueSplit[3];
266-
this.myUploadTool = actualValue;
266+
this.myBoardsCore = actualValue;
267267
this.myReferencedCorePlatformPath = Manager.getPlatformInstallPath(refVendor, refArchitecture,
268268
refVersion);
269269
if (this.myReferencedCorePlatformPath == null) {
@@ -296,7 +296,7 @@ private void ParseSection(Map<String, String> boardInfo) {
296296
String refArchitecture = valueSplit[1];
297297
String refVersion = valueSplit[2];
298298
String actualValue = valueSplit[3];
299-
this.myUploadTool = actualValue;
299+
this.myBoardsVariant = actualValue;
300300
this.myReferencedBoardVariantPlatformPath = Manager.getPlatformInstallPath(refVendor, refArchitecture,
301301
refVersion);
302302
if (this.myReferencedBoardVariantPlatformPath == null) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package io.sloeber.core.api;
2+
3+
import java.util.Map;
4+
5+
/**
6+
* this interface is to allow the ui to handle the automatic installation
7+
* of libraries.
8+
* If you do not register your implementation of this interface there will be
9+
* no automatic install of libraries
10+
*
11+
* registering your inmplementation is done in the library manager
12+
*
13+
* @author jan
14+
*
15+
*/
16+
17+
public interface IInstallLibraryHandler {
18+
/**
19+
* The core will call this method to find out if you want to install
20+
* the libraries automatically or not
21+
*
22+
* @return true if you want libraries to beinstalled automatically
23+
*/
24+
abstract boolean autoInstall();
25+
/**
26+
* given the set of proposed libraries to install
27+
* let the user decide on what to install
28+
* @param proposedLibsToInstall the libraries Sloeber proposes to install
29+
*
30+
* @return The libraries the user wants to install
31+
*/
32+
abstract Map<String, LibraryDescriptor> selectLibrariesToInstall(Map<String, LibraryDescriptor> proposedLibsToInstall);
33+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package io.sloeber.core.api;
2+
3+
import io.sloeber.core.managers.Library;
4+
5+
public class LibraryDescriptor {
6+
private Library library=null;
7+
8+
public LibraryDescriptor(Library value) {
9+
this.library=value;
10+
}
11+
12+
public Library toLibrary() {
13+
// TODO Auto-generated method stub
14+
return this.library;
15+
}
16+
17+
}

io.sloeber.core/src/io/sloeber/core/api/LibraryManager.java

+50-4
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,25 @@
2626
import io.sloeber.core.common.Common;
2727
import io.sloeber.core.common.ConfigurationPreferences;
2828
import io.sloeber.core.common.InstancePreferences;
29+
import io.sloeber.core.core.DefaultInstallHandler;
2930
import io.sloeber.core.managers.Library;
3031
import io.sloeber.core.managers.LibraryIndex;
3132
import io.sloeber.core.managers.Manager;
3233
import io.sloeber.core.managers.Messages;
3334
import io.sloeber.core.tools.Version;
34-
35+
/**
36+
* This class is the main entry point for libraries.
37+
* It handles
38+
* private libraries
39+
* hardware libraries
40+
* installed libraries
41+
*
42+
* @author jan
43+
*
44+
*/
3545
public class LibraryManager {
3646
static private List<LibraryIndex> libraryIndices;
47+
private static IInstallLibraryHandler myInstallLibraryHandler = new DefaultInstallHandler();
3748

3849
static public List<LibraryIndex> getLibraryIndices() {
3950
if (libraryIndices == null) {
@@ -237,6 +248,7 @@ public static IStatus setLibraryTree(LibraryTree libs, IProgressMonitor monitor,
237248
public static String getPrivateLibraryPathsString() {
238249
return InstancePreferences.getPrivateLibraryPathsString();
239250
}
251+
240252
public static void setPrivateLibraryPaths(String[] libraryPaths) {
241253
InstancePreferences.setPrivateLibraryPaths(libraryPaths);
242254

@@ -296,9 +308,9 @@ static public void loadJson(File jsonFile) {
296308
}
297309

298310
/**
299-
* Install the latest version of all the libraries belonging to this
300-
* category If a earlier version is installed this version will be removed
301-
* before installation of the newer version
311+
* Install the latest version of all the libraries belonging to this category If
312+
* a earlier version is installed this version will be removed before
313+
* installation of the newer version
302314
*
303315
* @param category
304316
*/
@@ -351,6 +363,40 @@ public static void removeAllLibs() {
351363
}
352364
}
353365

366+
/**
367+
* Searches for all libraries that can be installed but are not yet installed. A
368+
* library is considered installed when 1 version of the library is installed.
369+
*
370+
* @return a map of all instalable libraries
371+
*/
372+
public static Map<String, LibraryDescriptor> getAllInstallableLibraries() {
373+
Map<String, LibraryDescriptor> ret = new HashMap<>();
374+
for (LibraryIndex libraryIndex : libraryIndices) {
375+
ret.putAll(libraryIndex.getLatestInstallableLibraries());
376+
}
377+
378+
return ret;
379+
}
380+
381+
public static Map<String, LibraryDescriptor> getLatestInstallableLibraries(Set<String> libnames) {
382+
Set<String> remainingLibNames = new TreeSet<>(libnames);
383+
Map<String, LibraryDescriptor> ret = new HashMap<>();
384+
for (LibraryIndex libraryIndex : libraryIndices) {
385+
ret.putAll(libraryIndex.getLatestInstallableLibraries(remainingLibNames));
386+
remainingLibNames.removeAll(ret.keySet());
387+
}
388+
389+
return ret;
390+
}
391+
392+
public static void registerInstallLibraryHandler(IInstallLibraryHandler installLibraryHandler) {
393+
myInstallLibraryHandler = installLibraryHandler;
394+
}
395+
396+
public static IInstallLibraryHandler getInstallLibraryHandler() {
397+
return myInstallLibraryHandler;
398+
}
399+
354400
/**
355401
* Check wether a library is installed.
356402
* The check looks at the library installation place at the disk.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package io.sloeber.core.core;
2+
3+
import java.util.Map;
4+
5+
import io.sloeber.core.api.IInstallLibraryHandler;
6+
import io.sloeber.core.api.LibraryDescriptor;
7+
8+
public class DefaultInstallHandler implements IInstallLibraryHandler {
9+
10+
@Override
11+
public boolean autoInstall() {
12+
return false;
13+
}
14+
15+
16+
@Override
17+
public Map<String, LibraryDescriptor> selectLibrariesToInstall(Map<String, LibraryDescriptor> proposedLibsToInstall) {
18+
19+
return proposedLibsToInstall;
20+
}
21+
22+
}

io.sloeber.core/src/io/sloeber/core/managers/Library.java

+30-3
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,16 @@
1717
import org.eclipse.core.runtime.Status;
1818

1919
import io.sloeber.core.Activator;
20+
import io.sloeber.core.common.Common;
2021
import io.sloeber.core.common.ConfigurationPreferences;
2122
import io.sloeber.core.tools.FileModifiers;
2223

24+
/**
25+
* This class represents an entry ina a library json file
26+
*
27+
* @author jan
28+
*
29+
*/
2330
public class Library implements Comparable<Library> {
2431

2532
private String name;
@@ -159,6 +166,26 @@ public boolean isInstalled() {
159166
return getInstallPath().toFile().exists();
160167
}
161168

169+
/**
170+
* checks if any version of this library is installed. Can popup a window if
171+
* there is something wrong with the folder structure
172+
*
173+
* @return false if any version is installed. true in case of error and in case
174+
* no version is installed
175+
*/
176+
public boolean isAVersionInstalled() {
177+
if (!getInstallPath().getParent().toFile().exists()) {
178+
return false;
179+
}
180+
if (getInstallPath().getParent().toFile().isFile()) {
181+
// something is wrong here
182+
Common.log(new Status(IStatus.ERROR, Activator.getId(),
183+
getInstallPath().getParent() + " is a file but it should be a directory.")); //$NON-NLS-1$
184+
return false;
185+
}
186+
return getInstallPath().getParent().toFile().list().length > 0;
187+
}
188+
162189
public IStatus install(IProgressMonitor monitor) {
163190
monitor.setTaskName("Downloading and installing " + getName() + " library."); //$NON-NLS-1$ //$NON-NLS-2$
164191
if (isInstalled()) {
@@ -215,9 +242,9 @@ public int compareTo(Library other) {
215242
}
216243

217244
/**
218-
* delete the library This will delete all installed versions of the
219-
* library. Normally only 1 version can be installed so deleting all
220-
* versions should be delete 1 version
245+
* delete the library This will delete all installed versions of the library.
246+
* Normally only 1 version can be installed so deleting all versions should be
247+
* delete 1 version
221248
*
222249
* @param monitor
223250
* @return Status.OK_STATUS if delete is successful otherwise IStatus.ERROR

io.sloeber.core/src/io/sloeber/core/managers/LibraryIndex.java

+47
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,20 @@
77
import java.util.HashSet;
88
import java.util.List;
99
import java.util.Map;
10+
import java.util.Map.Entry;
1011
import java.util.Set;
1112
import java.util.regex.Pattern;
1213

1314
import io.sloeber.core.api.Defaults;
15+
import io.sloeber.core.api.LibraryDescriptor;
1416
import io.sloeber.core.tools.Version;
1517

18+
/**
19+
* This class represents a json file that references libraries
20+
*
21+
* @author jan
22+
*
23+
*/
1624
public class LibraryIndex {
1725
private String jsonFileName;
1826
private List<Library> libraries;
@@ -93,6 +101,23 @@ public Map<String, Library> getLatestLibraries() {
93101
return this.latestLibs;
94102
}
95103

104+
/**
105+
* get all the latest versions of alll libraries that can be installed but are
106+
* not yet installed To do so I find all latest libraries and I remove the once
107+
* that are installed.
108+
*
109+
* @return
110+
*/
111+
public Map<String, LibraryDescriptor> getLatestInstallableLibraries() {
112+
Map<String, LibraryDescriptor> ret = new HashMap<>();
113+
for (Entry<String, Library> curLibrary : this.latestLibs.entrySet()) {
114+
if (!curLibrary.getValue().isAVersionInstalled()) {
115+
ret.put(curLibrary.getKey(),new LibraryDescriptor( curLibrary.getValue()));
116+
}
117+
}
118+
return ret;
119+
}
120+
96121
public Collection<Library> getLibraries(String category) {
97122
Set<String> categoryLibs = this.categories.get(category);
98123
if (categoryLibs == null) {
@@ -121,4 +146,26 @@ public void setJsonFile(File packageFile) {
121146
public String getName() {
122147
return this.jsonFileName;
123148
}
149+
150+
/**
151+
* get all the latest versions of alll the libraries provided that can be
152+
* installed but are not yet installed To do so I find all latest libraries and
153+
* I remove the once that are installed.
154+
*
155+
* @return
156+
*/
157+
public Map<String, LibraryDescriptor> getLatestInstallableLibraries(Set<String> libNames) {
158+
Map<String, LibraryDescriptor> ret = new HashMap<>();
159+
if (libNames.isEmpty()) {
160+
return ret;
161+
}
162+
for (Entry<String, Library> curLibrary : this.latestLibs.entrySet()) {
163+
if (libNames.contains(curLibrary.getKey())) {
164+
if (!curLibrary.getValue().isAVersionInstalled()) {
165+
ret.put(curLibrary.getKey(), new LibraryDescriptor(curLibrary.getValue()));
166+
}
167+
}
168+
}
169+
return ret;
170+
}
124171
}

io.sloeber.core/src/io/sloeber/core/tools/Libraries.java

+38-5
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,15 @@
3030
import org.eclipse.core.runtime.CoreException;
3131
import org.eclipse.core.runtime.IPath;
3232
import org.eclipse.core.runtime.IStatus;
33+
import org.eclipse.core.runtime.NullProgressMonitor;
3334
import org.eclipse.core.runtime.Path;
3435
import org.eclipse.core.runtime.Status;
3536

3637
import io.sloeber.core.InternalBoardDescriptor;
3738
import io.sloeber.core.api.BoardDescriptor;
39+
import io.sloeber.core.api.IInstallLibraryHandler;
40+
import io.sloeber.core.api.LibraryDescriptor;
41+
import io.sloeber.core.api.LibraryManager;
3842
import io.sloeber.core.common.Common;
3943
import io.sloeber.core.common.ConfigurationPreferences;
4044
import io.sloeber.core.common.Const;
@@ -390,17 +394,46 @@ public static void checkLibraries(IProject affectedProject) {
390394
UnresolvedIncludedHeaders.add(entry.getValue());
391395
}
392396
}
393-
Map<String, IPath> availableLibs = getAllInstalledLibraries(configurationDescription);
394397
UnresolvedIncludedHeaders.removeAll(alreadyAddedLibs);
395398

396-
availableLibs.keySet().retainAll(UnresolvedIncludedHeaders);
397-
if (!availableLibs.isEmpty()) {
399+
IInstallLibraryHandler installHandler =LibraryManager.getInstallLibraryHandler();
400+
if (installHandler.autoInstall()) {
401+
//Check if there are libraries that are not found in the installed libraries
402+
Map<String, IPath> installedLibs = getAllInstalledLibraries(configurationDescription);
403+
Set<String> uninstalledIncludedHeaders=new TreeSet<>(UnresolvedIncludedHeaders);
404+
uninstalledIncludedHeaders.removeAll(installedLibs.keySet());
405+
if(!uninstalledIncludedHeaders.isEmpty()) {
406+
//some libraries may need to be installed
407+
408+
Map<String, LibraryDescriptor> availableLibs=LibraryManager.getLatestInstallableLibraries(uninstalledIncludedHeaders);
409+
410+
if(!availableLibs.isEmpty()) {
411+
//We now know which libraries to install
412+
//TODO for now I just install but there should be some user
413+
//interaction
414+
availableLibs=installHandler.selectLibrariesToInstall(availableLibs);
415+
for (Entry<String, LibraryDescriptor> curLib : availableLibs.entrySet()) {
416+
curLib.getValue().toLibrary().install(new NullProgressMonitor());
417+
}
418+
}
419+
}
420+
}
421+
422+
Map<String, IPath> installedLibs = getAllInstalledLibraries(configurationDescription);
423+
installedLibs.keySet().retainAll(UnresolvedIncludedHeaders);
424+
if (!installedLibs.isEmpty()) {
398425
// there are possible libraries to add
399426
Common.log(new Status(IStatus.INFO, Const.CORE_PLUGIN_ID, "list of libraries to add to project " //$NON-NLS-1$
400-
+ affectedProject.getName() + ": " + availableLibs.keySet().toString())); //$NON-NLS-1$
401-
addLibrariesToProject(affectedProject, configurationDescription, availableLibs);
427+
+ affectedProject.getName() + ": " + installedLibs.keySet().toString())); //$NON-NLS-1$
428+
addLibrariesToProject(affectedProject, configurationDescription, installedLibs);
402429
try {
430+
//TODO remove this logging code if this code is not causing the disrupts
431+
long startTime = System.nanoTime();
403432
mngr.setProjectDescription(affectedProject, projectDescription, true, null);
433+
long duration = (System.nanoTime() - startTime)/ 1000000; //in miliseconds
434+
if (duration>45000) {
435+
Common.log(new Status(IStatus.WARNING, Const.CORE_PLUGIN_ID,"setProjectDescription took "+duration+" miliseconds!!!")); //$NON-NLS-1$ //$NON-NLS-2$
436+
}
404437
} catch (CoreException e) {
405438
// this can fail because the project may already
406439
// be

0 commit comments

Comments
 (0)