blob: f7dcd7dc1df4c26d2ef8695f71e54fe346eb75bf [file]
<?php
/*******************************************************************************
* Copyright (c) 2021 Eclipse Foundation and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
require_once dirname(__FILE__) . '/Project.class.php';
require_once dirname(__FILE__) . '/common.php';
class ProjectContentIdMapper {
// Hardcoding while we sort out a better solution
static $map = array(
'*/*/@eclipse-che/*/*' => 'ecd.che',
'*/*/-/sprotty*/*' => 'ecd.sprotty',
'*/*/@theia/*/*' => 'ecd.theia',
'p2/*/*/org.eclipse.equinox*/*' => 'eclipse.equinox',
'p2/*/*/org.eclipse.osgi.*/*' => 'eclipse.equinox',
'p2/*/*/org.eclipse.osgi/*' => 'eclipse.equinox',
'*/*/p2.p2-installable-unit/org.eclipse.equinox*/*' => 'eclipse.equinox',
'*/*/org.eclipse.jdt.ls.*/*/*' => 'eclipse.jdt.ls',
'*/*/org.eclipse.jdt.ls/*/*' => 'eclipse.jdt.ls',
'*/*/p2.eclipse-plugin/org.eclipse.pde.*/*' => 'eclipse.pde',
'*/*/*/org.eclipse.ant.*/*' => 'eclipse.platform',
'*/*/*/org.eclipse.ant/*' => 'eclipse.platform',
'*/*/*/org.eclipse.compare.*/*' => 'eclipse.platform',
'*/*/*/org.eclipse.compare/*' => 'eclipse.platform',
'*/*/*/org.eclipse.core.*/*' => 'eclipse.platform',
'*/*/*/org.eclipse.core/*' => 'eclipse.platform',
'*/*/*/org.eclipse.cvs.*/*' => 'eclipse.platform',
'*/*/*/org.eclipse.cvs/*' => 'eclipse.platform',
'*/*/*/org.eclipse.debug.*/*' => 'eclipse.platform',
'*/*/*/org.eclipse.debug/*' => 'eclipse.platform',
'*/*/*/org.eclipse.e4.*/*' => 'eclipse.platform',
'*/*/*/org.eclipse.e4/*' => 'eclipse.platform',
'*/*/*/org.eclipse.externaltools.*/*' => 'eclipse.platform',
'*/*/*/org.eclipse.externaltools/*' => 'eclipse.platform',
'*/*/*/org.eclipse.ftp.*/*' => 'eclipse.platform',
'*/*/*/org.eclipse.ftp/*' => 'eclipse.platform',
'*/*/*/org.eclipse.help.*/*' => 'eclipse.platform',
'*/*/*/org.eclipse.help/*' => 'eclipse.platform',
'*/*/*/org.eclipse.jface.*/*' => 'eclipse.platform',
'*/*/*/org.eclipse.jface/*' => 'eclipse.platform',
'*/*/*/org.eclipse.jsch.*/*' => 'eclipse.platform',
'*/*/*/org.eclipse.jsch/*' => 'eclipse.platform',
'*/*/*/org.eclipse.license.*/*' => 'eclipse.platform',
'*/*/*/org.eclipse.license/*' => 'eclipse.platform',
'*/*/*/org.eclipse.ltk.*/*' => 'eclipse.platform',
'*/*/*/org.eclipse.ltk/*' => 'eclipse.platform',
'*/*/*/org.eclipse.osgi.*/*' => 'eclipse.platform',
'*/*/*/org.eclipse.osgi/*' => 'eclipse.platform',
'*/*/*/org.eclipse.platform.*/*' => 'eclipse.platform',
'*/*/*/org.eclipse.platform/*' => 'eclipse.platform',
'*/*/*/org.eclipse.platform_root.*/*' => 'eclipse.platform',
'*/*/*/org.eclipse.platform_root/*' => 'eclipse.platform',
'*/*/*/org.eclipse.rcp.*/*' => 'eclipse.platform',
'*/*/*/org.eclipse.rcp/*' => 'eclipse.platform',
'*/*/*/org.eclipse.rcp_root.*/*' => 'eclipse.platform',
'*/*/*/org.eclipse.rcp_root/*' => 'eclipse.platform',
'*/*/*/org.eclipse.releng.*/*' => 'eclipse.platform',
'*/*/*/org.eclipse.releng/*' => 'eclipse.platform',
'*/*/*/org.eclipse.sdk.*/*' => 'eclipse.platform',
'*/*/*/org.eclipse.sdk/*' => 'eclipse.platform',
'*/*/*/org.eclipse.search.*/*' => 'eclipse.platform',
'*/*/*/org.eclipse.search/*' => 'eclipse.platform',
'*/*/*/org.eclipse.swt.*/*' => 'eclipse.platform',
'*/*/*/org.eclipse.swt/*' => 'eclipse.platform',
'*/*/org.eclipse.swt.*/*/*' => 'eclipse.platform',
'*/*/*/org.eclipse.target.*/*' => 'eclipse.platform',
'*/*/*/org.eclipse.target/*' => 'eclipse.platform',
'*/*/*/org.eclipse.team.*/*' => 'eclipse.platform',
'*/*/*/org.eclipse.team/*' => 'eclipse.platform',
'*/*/*/org.eclipse.test.*/*' => 'eclipse.platform',
'*/*/*/org.eclipse.tests.*/*' => 'eclipse.platform',
'*/*/*/org.eclipse.test/*' => 'eclipse.platform',
'*/*/*/org.eclipse.text.*/*' => 'eclipse.platform',
'*/*/*/org.eclipse.text/*' => 'eclipse.platform',
'*/*/*/org.eclipse.tips.*/*' => 'eclipse.platform',
'*/*/*/org.eclipse.tips/*' => 'eclipse.platform',
'*/*/*/org.eclipse.tomcat.*/*' => 'eclipse.platform',
'*/*/*/org.eclipse.tomcat/*' => 'eclipse.platform',
'*/*/*/org.eclipse.ui.*/*' => 'eclipse.platform',
'*/*/*/org.eclipse.ui/*' => 'eclipse.platform',
'*/*/*/org.eclipse.update.*/*' => 'eclipse.platform',
'*/*/*/org.eclipse.update/*' => 'eclipse.platform',
'*/*/*/org.eclipse.urischeme.*/*' => 'eclipse.platform',
'*/*/*/org.eclipse.urischeme/*' => 'eclipse.platform',
'*/*/*/org.eclipse.webdav.*/*' => 'eclipse.platform',
'*/*/*/org.eclipse.webdav/*' => 'eclipse.platform',
'*/*/p2.p2-installable-unit/org.eclipse.platform.*/*' => 'eclipse.platform',
'*/*/p2.p2-installable-unit/org.eclipse.platform_root/*' => 'eclipse.platform',
'*/*/p2.p2-installable-unit/org.eclipse.rcp.*/*' => 'eclipse.platform',
'*/*/p2.p2-installable-unit/org.eclipse.rcp_root/*' => 'eclipse.platform',
'*/*/jakarta.annotation/*/*' => 'ee4j.ca',
'p2/*/*/javax.annotation/1.3.3+' => 'ee4j.ca',
'*/*/org.eclipse.persistence/eclipselink/*' => 'ee4j.eclipselink',
'*/*/org.eclipse.persistence/org.eclipse.persistence.*/*' => 'ee4j.eclipselink',
'*/*/p2.eclipse-plugin/org.eclipse.persistence.*/*' => 'ee4j.eclipselink',
'*/*/org.glassfish.hk2*/*/2.6+' => 'ee4j.glassfish',
'*/*/org.glassfish.main*/*/5.1+' => 'ee4j.glassfish',
'p2/*/*/org.glassfish.hk2.external.jakarta.inject/*' => 'ee4j.glassfish',
'*/*/org.glassfish.grizzly/*/2.4.4+' => 'ee4j.grizzly',
'*/*/org.glassfish.grizzly/grizzly-memcached/1.3.19+' => 'ee4j.grizzly',
'*/*/org.glassfish.grizzly/grizzly-npn*/2.0.0+' => 'ee4j.grizzly',
'*/*/org.glassfish.grizzly/grizzly-thrift/1.3.15+' => 'ee4j.grizzly',
'*/*/com.sun.activation/jakarta.activation/*' => 'ee4j.jaf',
'*/*/jakarta.activation/*/*' => 'ee4j.jaf',
'*/*/com.sun.xml.bind*/*/2.3.2+' => 'ee4j.jaxb-impl',
'p2/orbit/p2.eclipse-plugin/com.sun.xml.bind.jaxb-osgi/2.3.2+' => 'ee4j.jaxb-impl',
'*/*/jakarta.xml.bind/*/*' => 'ee4j.jaxb',
'*/*/org.glassfish.jersey*/*/2.28+' => 'ee4j.jersey',
'*/*/org.glassfish/jakarta.json/*' => 'ee4j.jsonp',
'*/*/org.glassfish/jsonp-jaxrs/1.1.5+' => 'ee4j.jsonp',
'*/*/com.sun.xml.ws*/*/2.3.2+' => 'ee4j.metro',
'*/*/org.glassfish.mq/*/5.1.3+' => 'ee4j.openmq',
'*/*/org.glassfish.corba*/*/4.0.0+' => 'ee4j.orb',
'*/*/org.glassfish.gmbal*/*/4.0.0+' => 'ee4j.orb',
'*/*/org.glassfish.pfl*/*/4.0.0+' => 'ee4j.orb',
'*/*/org.eclipse.parsson/*/*' => 'ee4j.parsson',
'*/*/jakarta.ws.rs/*/*' => 'ee4j.rest',
'*/*/jakarta.servlet/*/*' => 'ee4j.servlet',
'*/*/p2.eclipse-plugin/jakarta.servlet/*' => 'ee4j.servlet',
'*/*/p2.eclipse-plugin/jakarta.servlet-api/*' => 'ee4j.servlet',
'*/*/org.glassfish.tyrus*/*/1.15+' => 'ee4j.tyrus',
'*/*/eu.arrowhead/*/*' => 'iot.arrowhead',
'*/*/org.eclipse.leshan/*/*' => 'iot.leshan',
'*/*/p2.eclipse-plugin/org.eclipse.emf.ecore/*' => 'modeling.emf.emf',
'*/*/p2.eclipse-plugin/org.eclipse.gmf.runtime.*/*' => 'modeling.gmf-runtime',
'*/*/p2.eclipse-plugin/org.eclipse.uml2.*/*' => 'modeling.mdt.uml2',
'*/*/p2.eclipse-plugin/org.eclipse.sirius.*/*' => 'modeling.sirius',
'*/*/p2.eclipse-plugin/org.eclipse.sirius/*' => 'modeling.sirius',
'*/*/org.eclipse.jetty/*/*' => 'rt.jetty',
'*/*/p2.eclipse-plugin/org.eclipse.jetty.*/*' => 'rt.jetty',
'*/*/org.eclipse.californium/*/*' => 'science.californium',
'*/*/org.eclipse.aether/*/*' => 'technology.aether',
'*/*/org.eclipse.dash/*/*' => 'technology.dash',
'*/*/p2.eclipse-plugin/org.eclipse.fx.*/*' => 'technology.efxclipse',
'p2/*/*/org.osgi*/*' => 'technology.osgi',
'*/*/org.eclipse.sisu/*/*' => 'technology.sisu',
'p2/orbit/p2.eclipse-plugin/org.aspectj.*/*' => 'tools.aspectj',
'*/*/net.catenax.edc.extensions/business-partner-validation/0.1.6+' => 'automotive.catenax',
'*/*/net.catenax.edc.extensions/control-plane-adapter/0.1.6+' => 'automotive.catenax',
'*/*/net.catenax.edc.extensions/cx-oauth2/0.1.6+' => 'automotive.catenax',
'*/*/net.catenax.edc.extensions/data-encryption/0.1.6+' => 'automotive.catenax',
'*/*/net.catenax.edc.extensions/dataplane-selector-configuration/0.1.6+' => 'automotive.catenax',
'*/*/net.catenax.edc.extensions/hashicorp-vault/0.1.6+' => 'automotive.catenax',
'*/*/net.catenax.edc.extensions/postgresql-migration/0.1.6+' => 'automotive.catenax',
'*/*/net.catenax.edc.extensions/provision-additional-headers/0.1.6+' => 'automotive.catenax',
'*/*/net.catenax.edc.extensions/transferprocess-sftp-client/0.1.6+' => 'automotive.catenax',
'*/*/net.catenax.edc.extensions/transferprocess-sftp-common/0.1.6+' => 'automotive.catenax',
'*/*/net.catenax.edc.extensions/transferprocess-sftp-provisioner/0.1.6+' => 'automotive.catenax',
'*/*/net.catenax.edc/edc-controlplane-base/0.1.6+' => 'automotive.catenax',
'*/*/net.catenax.edc/edc-runtime-memory/0.1.6+' => 'automotive.catenax',
'*/*/net.catenax.edc/edc-controlplane-memory-hashicorp-vault/0.1.6+' => 'automotive.catenax',
'*/*/net.catenax.edc/edc-controlplane-postgresql/0.1.6+' => 'automotive.catenax',
'*/*/net.catenax.edc/edc-controlplane-postgresql-hashicorp-vault/0.1.6+' => 'automotive.catenax',
'*/*/net.catenax.edc/edc-dataplane-base/0.1.6+' => 'automotive.catenax',
'*/*/net.catenax.edc/edc-dataplane-azure-vault/0.1.6+' => 'automotive.catenax',
'*/*/net.catenax.edc/edc-dataplane-hashicorp-vault/0.1.6+' => 'automotive.catenax',
'*/*/org.eclipse/org.eclipse.tm4e.*/*' => 'technology.tm4e',
'*/*/p2.p2.installable.unit/org.eclipse.dltk.*/*' => 'technology.dltk',
'maven/*/org.eclipse.php/*/*' => 'tools.pdt',
'maven/mavencentral/org.eclipse.wb/*/*' => 'tools.windowbuilder',
'*/*/p2.eclipse-plugin/org.eclipse.ptp.*/*' => 'tools.ptp'
);
static function init() {
// $map = array();
// $fp = fopen('https://gitlab.eclipse.org/eclipsefdn/emo-team/iplab/-/raw/master/projects/namespace.hints','r');
// while ($row = fgetcsv($fp)) {
// if (count($row) == 2)
// $map[$row[1]] = $row[0];
// }
// fclose($fp);
// self::$map = $map;
}
/**
* This function answers the id of the Eclipse project that produces the bits
* with the provided ClearlyDefined coordinates.
*/
static function getEclipseProjectFor($id) {
$parts = explode('/', $id);
if (count($parts) != 5) return null;
list($type, $source, $namespace, $name, $revision) = $parts;
$namespace = preg_replace('/^p2\.eclipse\.(plugin|feature)$/', 'p2.eclipse-$1', $namespace);
if ($type == 'p2') {
// Normalize the "p2" package namespace.
$name = preg_replace('/\.source$/','',$name);
}
if ($project = self::getProjectFromHints($type, $source, $namespace, $name, $revision)) {
return $project;
}
if ($project = self::getProjectByNamespaceLookup($type, $source, $namespace, $name, $revision)) {
return $project;
}
if ($project = self::getProjectByMakingAReallyGoodGuess($type, $source, $namespace, $name, $revision)) {
return $project;
}
return null;
}
private static function getProjectFromHints($type, $source, $namespace, $name, $revision) {
foreach(self::$map as $pattern => $project) {
$bits = explode('/', $pattern);
if (count($bits) < 5) continue;
if (!fnmatch($bits[0], $type)) continue;
if (!fnmatch($bits[1], $source)) continue;
if (!fnmatch($bits[2], $namespace)) continue;
if (!fnmatch($bits[3], $name)) continue;
if ($bits[4] == '*') return $project;
// If the version information ends with a plus (+), then we look for
// matches that are the specified version and greater. Otherwise,
// we look for straight up matches (exact isn't the right word here,
// since the compareSemanticVersion function compares equivalence, so, e.g.,
// "1.0" and "1.0.0" are considered to match).
//
// Note that we don't do wildcard/glob matches within versions (i.e.,
// we do match '*' to mean "any version", but something like '1.*.8' isn't supported).
$matches = null;
if (preg_match('/^(?<version>.*)\+$/', $bits[4], $matches)) {
if (compareSemanticVersion($matches['version'], $revision) <= 0) return $project;
} elseif (compareSemanticVersion($bits[4], $revision) == 0) return $project;
}
return null;
}
/**
* Identify the project that produces an artifact with a specific identifier.
*
* This uses the ProjectNamespaces table which is generated by the POMVisitor
* class as it walks through project repositories. That visitor identifies build
* scripts and pulls namespace and name information out of them (e.g., when it
* encounters a Maven pom.xml file, it pulls the groupid and artifactid as a
* namespace and name associated with the corresponding project.
*
* There's a wrinkle. Some projects include third-party libraries in their
* repositories in source form, and sometimes those libraries include build scripts
* which the script has difficultly distinguishing from project build scripts.
*
* While we try to improve the overall quality of the scripts that harvest the
* information, we tweak our queries to be conservative when deciding whether or
* not a namespace and name is valid.
*/
private static function getProjectByNamespaceLookup($type, $source, $namespace, $name, $revision) {
$project = null;
/*
* There are some inefficiencies in this query that I'm leaving in favour
* of legibility. Specifically, we can probably do better with the redundancy
* in where clause.
*
* The substring_index bits are extracting the project's short name from the
* project id. The gist is that--at least temporarily--we only consider a
* namespace to be a project name space if it includes the actual project's
* name. This likely excludes a number of completely reasonable project
* namespaces...
*/
$sql = "
select distinct /* ProjectContentIdMapper::getProjectByNamespaceLookup */
p.id,
p.license
from Project as p
join ProjectNamespaces as pn on p.id=pn.project
where
(pn.namespace=':namespace:' and pn.name=':name:'
and pn.namespace in ('p2.eclipse-plugin', 'p2.eclipse-feature') and pn.name like 'org.eclipse.%')
or
(pn.namespace=':namespace:' and pn.name=':name:' and instr(pn.namespace, 'org.eclipse') = 1)
or
(pn.namespace=':namespace:'
and (instr(pn.namespace, substring_index(pn.project, '.', -1)) != 0)
and pn.namespace like 'org.eclipse.%')
limit 1";
$args = array(':namespace:' => $namespace, ':name:' => $name);
query('dashboard', $sql, $args, function($row) use (&$project) {
$project = $row['id'];
});
return $project;
}
private static function getProjectByMakingAReallyGoodGuess($type, $source, $namespace, $name, $revision) {
global $projectNameSegmentPattern;
// If we don't find an override, try to determine the project ID from
// the namespace and name.
if ("p2" == $type && preg_match('/p2\.eclipse\-(?:plugin|feature)/',$namespace)) {
// When the third segment (namespace) is "p2.eclipse-plugin", we assume that
// the next bit is the shortname for the project and we do a search based on that.
$matches = null;
$pattern = "/^org\\.eclipse\\.({$projectNameSegmentPattern})\\b/";
if (preg_match($pattern, $name, $matches)) {
$projects = Project::getAllWithShortname($matches[1]);
if (count($projects) == 1) {
$project = reset($projects);
return $project->getId();
}
}
} else {
// When the third segment (namespace) starts with "org.eclipse", "org.glassfish",
// or "jakarta" we assume/hope that the next bit is the shortname for the project
// and we do a search based on that.
$matches = null;
$pattern = "/^(?:org\\.eclipse|org\\.glassfish|jakarta)\\.({$projectNameSegmentPattern})\\b/";
if (preg_match($pattern, $namespace, $matches)) {
$projects = Project::getAllWithShortname($matches[1]);
if (count($projects) == 1) {
$project = reset($projects);
return $project->getId();
}
}
}
return null;
}
}
ProjectContentIdMapper::init();