blob: 3e8809eeb583ba0c47edb4961e771938267558b9 [file] [log] [blame]
<?php
/*******************************************************************************
* Copyright (c) 2021,2022 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 {
static $map;
static function init() {
// FIXME We should draw on a data source of some kind rather than hardcoding.
$map = array(
'*/*/p2.p2-installable-unit/org.eclipse.rcp_root/*' => '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.platform.*/*' => 'eclipse.platform',
'*/*/org.glassfish.hk2*/*/2.6+' => 'ee4j.glassfish',
'*/*/org.glassfish.main*/*/5.1+' => 'ee4j.glassfish',
'*/*/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.glassfish.grizzly/grizzly-npn*/2.0.0+' => 'ee4j.grizzly',
'*/*/org.glassfish.grizzly/grizzly-thrift/1.3.15+' => 'ee4j.grizzly',
'*/*/org.glassfish.grizzly/grizzly-memcached/1.3.19+' => 'ee4j.grizzly',
'*/*/org.glassfish.grizzly/*/2.4.4+' => 'ee4j.grizzly',
'p2/*/*/org.glassfish.hk2.external.jakarta.inject/*' => 'ee4j.glassfish',
'*/*/org.glassfish.mq/*/5.1.3+' => 'ee4j.openmq',
'*/*/org.glassfish.tyrus*/*/1.15+' => 'ee4j.tyrus',
'*/*/org.glassfish/jakarta.json/*' => 'ee4j.jsonp',
'*/*/org.eclipse.parsson/*/*' => 'ee4j.parsson',
'*/*/org.glassfish/jsonp-jaxrs/1.1.5+' => 'ee4j.jsonp',
'*/*/org.glassfish.jersey*/*/2.28+' => 'ee4j.jersey',
'*/*/jakarta.activation/*/*' => 'ee4j.jaf',
'*/*/jakarta.annotation/*/*' => 'ee4j.ca',
'*/*/jakarta.servlet/*/*' => 'ee4j.servlet',
'*/*/jakarta.ws.rs/*/*' => 'ee4j.jaxrs',
'*/*/jakarta.xml.bind/*/*' => 'ee4j.jaxb',
'*/*/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',
'*/*/com.sun.activation/jakarta.activation/*' => 'ee4j.jaf',
'*/*/org.eclipse.aether/*/*' => 'technology.aether',
'*/*/org.eclipse.dash/*/*' => 'technology.dash',
'*/*/org.eclipse.sisu/*/*' => 'technology.sisu',
'*/*/@eclipse-che/*/*' => 'ecd.che',
'*/*/@theia/*/*' => 'ecd.theia',
'*/*/-/sprotty*/*' => 'ecd.sprotty',
'*/*/org.eclipse.jdt.ls/*/*' => 'eclipse.jdt.ls',
'*/*/org.eclipse.jdt.ls.*/*/*' => 'eclipse.jdt.ls',
'p2/*/*/org.eclipse.osgi/*' => 'eclipse.equinox',
'p2/*/*/org.eclipse.osgi.*/*' => 'eclipse.equinox',
'*/*/p2.p2-installable-unit/org.eclipse.equinox*/*' => 'eclipse.equinox',
'p2/orbit/p2.eclipse-plugin/org.aspectj.*/*' => 'tools.aspectj',
'*/*/org.eclipse.jetty/*/*' => 'rt.jetty',
'*/*/org.eclipse.leshan/*/*' => 'iot.leshan',
'*/*/org.eclipse.californium/*/*' => 'science.californium',
'*/*/eu.arrowhead/*/*' => 'iot.arrowhead',
'*/*/p2.eclipse-plugin/org.eclipse.fx.*/*' => 'technology.efxclipse',
'*/*/p2.eclipse-plugin/org.eclipse.gmf.runtime.*/*' => 'modeling.gmf-runtime',
'*/*/p2.eclipse-plugin/org.eclipse.jetty.*/*' => 'rt.jetty',
'*/*/p2.eclipse-plugin/org.eclipse.pde.*/*' => 'eclipse.pde',
'*/*/p2.eclipse-plugin/org.eclipse.sirius/*' => 'modeling.sirius',
'*/*/p2.eclipse-plugin/org.eclipse.sirius.*/*' => 'modeling.sirius',
'*/*/p2.eclipse-plugin/org.eclipse.uml2.*/*' => 'modeling.mdt.uml2'
);
// This list is stable, I think. I believe that we can expand this out and
// just include it in whatever data source we end up choose to use to represent
// this information.
$platform = array('e4', 'platform', 'test', 'releng', 'webdav', 'externaltools', 'rcp', 'core', 'debug', 'help', 'ui', 'sdk', 'team', 'text', 'ltk', 'osgi', 'search', 'compare', 'update', 'ant', 'jface', 'swt', 'jsch', 'cvs', 'tomcat', 'target', 'ftp', 'license', 'urischeme');
foreach ($platform as $fragment) {
$map["p2/*/*/org.eclipse.{$fragment}/*"] = 'eclipse.platform';
$map["p2/*/*/org.eclipse.{$fragment}.*/*"] = 'eclipse.platform';
}
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) {
global $projectNameSegmentPattern;
$parts = explode('/', $id);
// Check with the overrides first. If we have a specific mapping
// from a content ID to a project, use that.
$project = self::getProjectId($parts[0], $parts[1], $parts[2], $parts[3], $parts[4]);
if ($project) {
return $project;
}
// If we don't find an override, try to determine the project ID from
// the namespace and name.
if ($parts[2] == 'p2.eclipse-plugin') {
// 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, $parts[3], $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, $parts[2], $matches)) {
$projects = Project::getAllWithShortname($matches[1]);
if (count($projects) == 1) {
$project = reset($projects);
return $project->getId();
}
}
}
return null;
}
private function getProjectId($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).
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;
}
}
ProjectContentIdMapper::init();