use of org.eclipse.openvsx.entities.Extension in project openvsx by eclipse.
the class ExtensionService method createExtensionVersion.
private ExtensionVersion createExtensionVersion(ExtensionProcessor processor, UserData user, PersonalAccessToken token) {
var namespaceName = processor.getNamespace();
var namespace = repositories.findNamespace(namespaceName);
if (namespace == null) {
throw new ErrorResultException("Unknown publisher: " + namespaceName + "\nUse the 'create-namespace' command to create a namespace corresponding to your publisher name.");
}
if (!users.hasPublishPermission(user, namespace)) {
throw new ErrorResultException("Insufficient access rights for publisher: " + namespace.getName());
}
var extensionName = processor.getExtensionName();
var nameIssue = validator.validateExtensionName(extensionName);
if (nameIssue.isPresent()) {
throw new ErrorResultException(nameIssue.get().toString());
}
var extVersion = processor.getMetadata();
if (extVersion.getDisplayName() != null && extVersion.getDisplayName().trim().isEmpty()) {
extVersion.setDisplayName(null);
}
extVersion.setTimestamp(TimeUtil.getCurrentUTC());
extVersion.setPublishedWith(token);
extVersion.setActive(true);
var extension = repositories.findExtension(extensionName, namespace);
if (extension == null) {
extension = new Extension();
extension.setName(extensionName);
extension.setNamespace(namespace);
vsCodeIdService.createPublicId(extension);
entityManager.persist(extension);
} else {
var existingVersion = repositories.findVersion(extVersion.getVersion(), extension);
if (existingVersion != null) {
throw new ErrorResultException("Extension " + namespace.getName() + "." + extension.getName() + " version " + extVersion.getVersion() + " is already published" + (existingVersion.isActive() ? "." : ", but is currently inactive and therefore not visible."));
}
}
extVersion.setExtension(extension);
entityManager.persist(extVersion);
var metadataIssues = validator.validateMetadata(extVersion);
if (!metadataIssues.isEmpty()) {
if (metadataIssues.size() == 1) {
throw new ErrorResultException(metadataIssues.get(0).toString());
}
throw new ErrorResultException("Multiple issues were found in the extension metadata:\n" + Joiner.on("\n").join(metadataIssues));
}
return extVersion;
}
use of org.eclipse.openvsx.entities.Extension in project openvsx by eclipse.
the class DatabaseSearchService method search.
@Cacheable("database.search")
public SearchHits<ExtensionSearch> search(ISearchService.Options options, Pageable pageRequest) {
// grab all extensions
var matchingExtensions = repositories.findAllActiveExtensions();
// no extensions in the database
if (matchingExtensions.isEmpty()) {
Aggregations aggregations = new Aggregations(Collections.emptyList());
return new SearchHitsImpl<ExtensionSearch>(0, TotalHitsRelation.OFF, 0f, "", Collections.emptyList(), aggregations);
}
// filter category
if (options.category != null) {
matchingExtensions = matchingExtensions.filter(extension -> extension.getLatest().getCategories().stream().anyMatch(category -> category.toLowerCase().equals(options.category.toLowerCase())));
}
// filter text
if (options.queryString != null) {
matchingExtensions = matchingExtensions.filter(extension -> extension.getName().toLowerCase().contains(options.queryString.toLowerCase()) || extension.getNamespace().getName().contains(options.queryString.toLowerCase()) || (extension.getLatest().getDescription() != null && extension.getLatest().getDescription().toLowerCase().contains(options.queryString.toLowerCase())) || (extension.getLatest().getDisplayName() != null && extension.getLatest().getDisplayName().toLowerCase().contains(options.queryString.toLowerCase())));
}
List<ExtensionSearch> sortedExtensions;
if ("relevance".equals(options.sortBy)) {
// for relevance we're using relevance service to get the relevance item
var searchStats = new SearchStats(repositories);
// needs to add relevance on extensions
sortedExtensions = new ArrayList<>(matchingExtensions.map(extension -> relevanceService.toSearchEntry(extension, searchStats)).toList());
// sort it
sortedExtensions.sort(new RelevanceComparator());
} else {
sortedExtensions = matchingExtensions.stream().map(extension -> extension.toSearch()).collect(Collectors.toList());
if ("downloadCount".equals(options.sortBy)) {
sortedExtensions.sort(new DownloadedCountComparator());
} else if ("averageRating".equals(options.sortBy)) {
sortedExtensions.sort(new AverageRatingComparator());
} else if ("timestamp".equals(options.sortBy)) {
sortedExtensions.sort(new TimestampComparator());
}
}
// 'asc' | 'desc';
if ("desc".equals(options.sortOrder)) {
// reverse the order
Collections.reverse(sortedExtensions);
}
// Paging
var totalHits = sortedExtensions.size();
if (pageRequest != null) {
var pageNumber = pageRequest.getPageNumber();
var pageSize = pageRequest.getPageSize();
var toSkip = 0;
if (pageNumber >= 1) {
// page is zero indexed
toSkip = pageNumber * (pageSize - 1) + pageNumber;
}
// if something to skip, remove the first elements
if (toSkip > 0 && toSkip < sortedExtensions.size()) {
sortedExtensions = sortedExtensions.subList(toSkip, sortedExtensions.size());
}
// keep only the pageSize elements
if (sortedExtensions.size() > pageSize) {
sortedExtensions = sortedExtensions.subList(0, pageSize);
}
}
List<SearchHit<ExtensionSearch>> searchHits;
if (sortedExtensions.isEmpty()) {
searchHits = Collections.emptyList();
} else {
// client is interested only in the extension IDs
searchHits = sortedExtensions.stream().map(extensionSearch -> {
return new SearchHit<ExtensionSearch>(null, null, 0.0f, Collections.emptyList().toArray(), Collections.emptyMap(), extensionSearch);
}).collect(Collectors.toList());
}
Aggregations aggregations = new Aggregations(Collections.emptyList());
SearchHits<ExtensionSearch> searchHitsResult = new SearchHitsImpl<ExtensionSearch>(totalHits, TotalHitsRelation.OFF, 0f, "", searchHits, aggregations);
return searchHitsResult;
}
use of org.eclipse.openvsx.entities.Extension in project openvsx by eclipse.
the class LocalRegistryService method toSearchEntry.
private SearchEntryJson toSearchEntry(SearchHit<ExtensionSearch> searchHit, String serverUrl, ISearchService.Options options) {
var searchItem = searchHit.getContent();
var extension = entityManager.find(Extension.class, searchItem.id);
if (extension == null || !extension.isActive()) {
extension = new Extension();
extension.setId(searchItem.id);
search.removeSearchEntry(extension);
return null;
}
var extVer = extension.getLatest();
var entry = extVer.toSearchEntryJson();
entry.url = createApiUrl(serverUrl, "api", entry.namespace, entry.name);
entry.files = Maps.newLinkedHashMapWithExpectedSize(2);
storageUtil.addFileUrls(extVer, serverUrl, entry.files, DOWNLOAD, ICON);
if (options.includeAllVersions) {
var allVersions = Lists.newArrayList(repositories.findActiveVersions(extension));
Collections.sort(allVersions, ExtensionVersion.SORT_COMPARATOR);
entry.allVersions = CollectionUtil.map(allVersions, ev -> toVersionReference(ev, entry, serverUrl));
}
return entry;
}
use of org.eclipse.openvsx.entities.Extension in project openvsx by eclipse.
the class AdminAPI method deleteExtension.
@PostMapping(path = "/admin/extension/{namespaceName}/{extensionName}/delete", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<ResultJson> deleteExtension(@PathVariable String namespaceName, @PathVariable String extensionName, @RequestBody(required = false) List<String> versions) {
try {
ResultJson result;
var adminUser = admins.checkAdminUser();
if (versions == null) {
result = admins.deleteExtension(namespaceName, extensionName, adminUser);
} else {
var results = new ArrayList<ResultJson>();
for (var version : versions) {
results.add(admins.deleteExtensionVersion(namespaceName, extensionName, version, adminUser));
}
result = new ResultJson();
result.error = results.stream().map(r -> r.error).filter(Objects::nonNull).collect(Collectors.joining("\n"));
result.success = results.stream().map(r -> r.success).filter(Objects::nonNull).collect(Collectors.joining("\n"));
}
return ResponseEntity.ok(result);
} catch (ErrorResultException exc) {
return exc.toResponseEntity();
}
}
use of org.eclipse.openvsx.entities.Extension in project openvsx by eclipse.
the class LocalRegistryService method query.
@Override
public QueryResultJson query(QueryParamJson param) {
if (!Strings.isNullOrEmpty(param.extensionId)) {
var split = param.extensionId.split("\\.");
if (split.length != 2 || split[0].isEmpty() || split[1].isEmpty())
throw new ErrorResultException("The 'extensionId' parameter must have the format 'namespace.extension'.");
if (!Strings.isNullOrEmpty(param.namespaceName) && !param.namespaceName.equals(split[0]))
throw new ErrorResultException("Conflicting parameters 'extensionId' and 'namespaceName'");
if (!Strings.isNullOrEmpty(param.extensionName) && !param.extensionName.equals(split[1]))
throw new ErrorResultException("Conflicting parameters 'extensionId' and 'extensionName'");
param.namespaceName = split[0];
param.extensionName = split[1];
}
List<ExtensionVersionDTO> extensionVersions = new ArrayList<>();
// Add extension by UUID (public_id)
if (!Strings.isNullOrEmpty(param.extensionUuid)) {
extensionVersions.addAll(repositories.findActiveExtensionVersionDTOsByExtensionPublicId(param.extensionUuid));
}
// Add extensions by namespace UUID (public_id)
if (!Strings.isNullOrEmpty(param.namespaceUuid)) {
extensionVersions.addAll(repositories.findActiveExtensionVersionDTOsByNamespacePublicId(param.namespaceUuid));
}
// Add a specific version of an extension
if (!Strings.isNullOrEmpty(param.namespaceName) && !Strings.isNullOrEmpty(param.extensionName) && !Strings.isNullOrEmpty(param.extensionVersion) && !param.includeAllVersions) {
var extensionVersion = repositories.findActiveExtensionVersionDTOByVersion(param.extensionVersion, param.extensionName, param.namespaceName);
if (extensionVersion != null) {
extensionVersions.add(extensionVersion);
}
// Add extension by namespace and name
} else if (!Strings.isNullOrEmpty(param.namespaceName) && !Strings.isNullOrEmpty(param.extensionName)) {
extensionVersions.addAll(repositories.findActiveExtensionVersionDTOsByExtensionName(param.extensionName, param.namespaceName));
// Add extensions by namespace
} else if (!Strings.isNullOrEmpty(param.namespaceName)) {
extensionVersions.addAll(repositories.findActiveExtensionVersionDTOsByNamespaceName(param.namespaceName));
// Add extensions by name
} else if (!Strings.isNullOrEmpty(param.extensionName)) {
extensionVersions.addAll(repositories.findActiveExtensionVersionDTOsByExtensionName(param.extensionName));
}
extensionVersions = extensionVersions.stream().collect(Collectors.groupingBy(ExtensionVersionDTO::getId)).values().stream().map(l -> l.get(0)).filter(ev -> addToResult(ev, param)).collect(Collectors.toList());
if (Strings.isNullOrEmpty(param.extensionVersion) && !param.includeAllVersions) {
var latestIds = extensionVersions.stream().map(ExtensionVersionDTO::getExtension).map(ExtensionDTO::getLatestId).filter(Objects::nonNull).collect(Collectors.toList());
extensionVersions = extensionVersions.stream().filter(ev -> latestIds.contains(ev.getId())).collect(Collectors.toList());
}
var extensionIds = extensionVersions.stream().map(ExtensionVersionDTO::getExtensionId).collect(Collectors.toSet());
var reviewCounts = getReviewCounts(extensionIds);
var versionStrings = getVersionStrings(extensionIds);
var previewsByExtensionId = getPreviews(extensionIds);
var fileResourcesByExtensionVersionId = getFileResources(extensionVersions);
var membershipsByNamespaceId = getMemberships(extensionVersions);
var result = new QueryResultJson();
result.extensions = extensionVersions.stream().sorted(getExtensionVersionComparator()).map(ev -> {
var reviewCount = reviewCounts.getOrDefault(ev.getExtensionId(), 0);
var preview = previewsByExtensionId.get(ev.getExtensionId());
var versions = versionStrings.get(ev.getExtensionId());
var fileResources = fileResourcesByExtensionVersionId.getOrDefault(ev.getId(), Collections.emptyList());
return toExtensionVersionJson(ev, reviewCount, preview, versions, fileResources, membershipsByNamespaceId);
}).collect(Collectors.toList());
return result;
}
Aggregations