| <?php |
| /******************************************************************************* |
| * Copyright (c) 2017 Eclipse Foundation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| *******************************************************************************/ |
| |
| require_once(dirname(__FILE__) . '/../classes/Project.class.php'); |
| require_once(dirname(__FILE__) . '/../classes/SPDX.class.inc'); |
| require_once(dirname(__FILE__) . '/../classes/database.inc'); |
| |
| class IPZilla { |
| var $filePatternPath; |
| var $cqs = array(); |
| |
| public static function getInstance() { |
| $ipzilla = new IPZilla(); |
| $ipzilla->filePatternPath = dirname(__FILE__) . '/../ip-check/cq-map.txt'; |
| $ipzilla->load(); |
| |
| return $ipzilla; |
| } |
| |
| public function getCq($id) { |
| return $this->cqs[$id]; |
| } |
| |
| public function rootCqsDo($function) { |
| foreach($this->cqs as $cq) { |
| if ($cq->isRoot()) $function($cq); |
| } |
| } |
| |
| public function asArray() { |
| $data = array(); |
| $this->rootCqsDo(function($cq) use (&$data) { |
| $data[$cq->getId()] = $cq->asArray(); |
| }); |
| return $data; |
| } |
| |
| private function load() { |
| $sql = " |
| select |
| b.bug_id as id, |
| c.name as project, |
| b.short_desc as description, |
| b.bug_status as status, |
| b.resolution as resolution, |
| group_concat(kd.name) as keywords, |
| b.bug_severity as state, |
| b.cf_type as type, |
| b.cf_license as license |
| from bugs as b |
| join components as c on b.component_id = c.id |
| join keywords as k on b.bug_id=k.bug_id |
| join keyworddefs as kd on k.keywordid=kd.id |
| where b.bug_severity in ('approved', 'license_certified') |
| group by b.bug_id |
| "; |
| |
| query('ipzilla', $sql, array(), function($row) { |
| $this->cqs[$row['id']] = new CQ($this, $row); |
| }); |
| |
| $this->initialize(); |
| $this->loadFilePatterns(); |
| $this->loadMvnPatterns(); |
| } |
| |
| private function initialize() { |
| foreach($this->cqs as $cq) { |
| if ($cq->isRoot()) continue; |
| $cq->getRoot()->data['piggybacks'][$cq->getId()] = $cq->getProjectId() ; |
| } |
| } |
| |
| private function loadFilePatterns() { |
| foreach($this->cqs as &$cq) { |
| if (preg_match('/([a-zA-Z0-9\.\-\_]+)[_-]((?:\d+\.){3})(.*\.)?jar/', $cq->getDescription(), $matches)) { |
| $cq->getRoot()->addFilePattern($matches[0]); |
| } |
| } |
| |
| query('dashboard', 'select distinct cq, pattern from CQBundleMap', array(), function($row) { |
| if ($cq = $this->cqs[$row['cq']]) { |
| $cq->addFilePattern($row['pattern']); |
| $cq->data['bundle'][] = $row; |
| } |
| }); |
| |
| query('dashboard', 'select distinct cq, name, version, file from CQOrbit', array(), function($row) { |
| if ($cq = $this->cqs[$row['cq']]) { |
| $cq->addFilePattern($row['file']); |
| $cq->data['orbit'][] = $row; |
| } |
| }); |
| } |
| |
| private function loadMvnPatterns() { |
| $mvnRegex = '([\w\-\*\.]+):([\w\-\*\.]+):([\w\-\*\.]+):([\w\-\*\.]+)'; |
| foreach($this->cqs as &$cq) { |
| if (preg_match("/$mvnRegex/", $cq->getDescription(), $matches)) { |
| $cq->getRoot()->addMvnPattern("{$matches[1]}:{$matches[2]}:*:{$matches[4]}"); |
| } |
| } |
| |
| query('dashboard', 'select distinct cq, pattern from CQMavenMap', array(), function($row) { |
| if ($cq = $this->cqs[$row['cq']]) { |
| $cq->addMvnPattern($row['pattern']); |
| $cq->data['maven'][] = $row; |
| } |
| }); |
| } |
| } |
| |
| class CQ { |
| var $ipzilla; |
| var $data; |
| var $root; |
| var $keywords; |
| |
| public function __construct($ipzilla, $data) { |
| $this->ipzilla = $ipzilla; |
| $this->data = $data; |
| |
| // Compute some values. |
| $this->data['name'] = $this->computeName(); |
| $this->data['version'] = $this->computeVersion(); |
| $this->data['spdx'] = SPDX::asSpdx($this->data['license']); |
| |
| // Cache information |
| $this->keywords = preg_split('/\s*,\s*/',$this->data['keywords']); |
| } |
| |
| public function getId() { |
| return $this->data['id']; |
| } |
| |
| public function getName() { |
| return $this->data['name']; |
| } |
| |
| public function getVersion() { |
| return $this->data['version']; |
| } |
| |
| private function computeVersion() { |
| if (preg_match('/Version\:?\s+(\d+(\.\d+)*)/i', $this->getDescription(), $matches)) { |
| return $matches[1]; |
| } else if (preg_match('/(\d+(\.\d+)*)/', $this->getDescription(), $matches)) { |
| return $matches[1]; |
| } |
| return null; |
| } |
| |
| private function computeName() { |
| $name = $this->getDescription(); |
| $name = preg_replace('/Apache/i', '', $name); |
| $name = preg_replace('/Google/i', '', $name); |
| $name = preg_replace('/\[[^\]]*\]/', '', $name); |
| $name = preg_replace('/\([^\)]*\)/', '', $name); |
| $name = preg_replace('/\([^\)]*\)/', '', $name); |
| $name = preg_replace('/Version\:?.*$/i', '', $name); |
| $name = preg_replace('/\-?(\d+(\.\d+)*)/i', '', $name); |
| $name = preg_replace('/\.jar/i', '', $name); |
| $name = preg_replace('/\sjar/i', '', $name); |
| $name = preg_replace('/\sv(\s|$)/i', '', $name); // Remove a solitary 'v' (i.e. "version") |
| $name = preg_replace('/\W+/', ' ', $name); // Replace non-word characters with a single space. |
| $name = ucwords($name); |
| return trim($name); |
| } |
| |
| public function getDescription() { |
| return $this->data['description']; |
| } |
| |
| public function getLicense() { |
| return $this->data['license']; |
| } |
| |
| public function getSPDX() { |
| return $this->data['spdx']; |
| } |
| |
| public function getProject() { |
| return Project::getProject($this->getProjectId()); |
| } |
| |
| public function getProjectId() { |
| return $this->data['project']; |
| } |
| |
| public function getState() { |
| return $this->data['state']; |
| } |
| |
| public function getStatus() { |
| return $this->data['status']; |
| } |
| |
| public function getResolution() { |
| return $this->data['resolution']; |
| } |
| |
| public function getKeywords() { |
| return $this->data['keywords']; |
| } |
| |
| public function getFilePatterns() { |
| return @$this->data['filePatterns']; |
| } |
| |
| public function getMvnPatterns() { |
| return @$this->data['mvnPatterns']; |
| } |
| |
| public function getDueDiligenceType() { |
| return $this->data['type']; |
| } |
| |
| public function isRoot() { |
| return $this == $this->getRoot(); |
| } |
| |
| /** |
| * Answer the root CQ. The root is basically the first CQ |
| * created for a particular bit of content. A piggyback will, |
| * for example, refer to a root. It's possible that a piggyback |
| * may refer to another piggyback, so it's possible that we |
| * may be several layers deep. |
| * |
| * The parameter should not generally be provided by the sender. |
| * Because it is possible that there may be cycles in the dependency |
| * graph (there shouldn't be, but errors happen), we take an array |
| * with us through the recursion. It would be an exceptional state |
| * to find the receiver in recursion list; in this case, the only |
| * thing that we can do is to throw an exception. |
| * |
| * @param array $recursion_list |
| * @throws RecursiveAncestryException |
| * @return CQ |
| */ |
| public function getRoot($recursion_list = array()) { |
| if (!isset($this->root)) { |
| if (in_array($this, $recursion_list)) throw new RecursiveAncestryException(); |
| if (!$parent = $this->getParent()) return $this; |
| if ($parent == $this) return $this; |
| |
| $recursion_list[] = $this; |
| $this->root = $parent->getRoot($recursion_list); |
| } |
| return $this->root; |
| } |
| |
| public function getParent() { |
| if ($id = $this->getParentId()) { |
| return $this->ipzilla->getCq($id); |
| } |
| return null; |
| } |
| |
| private function getParentId() { |
| if (preg_match ( '/\W(?:\(ATO|PB|Orbit)[^\d\)]*([0-9]+)/i', $this->getDescription(), $matches)) { |
| return $matches [1]; |
| } |
| return null; |
| } |
| |
| |
| |
| public function isResolved() { |
| if (!$this->getStatus()) return false; |
| return in_array($this->getStatus(), array('RESOLVED', 'VERIFIED', 'CLOSED')); |
| } |
| |
| public function isFixed() { |
| if (!$this->isResolved()) return false; |
| return $this->getResolution() == 'FIXED'; |
| } |
| |
| public function isApproved() { |
| if (!$this->isResolved()) return false; |
| return $this->getState() == 'approved'; |
| } |
| |
| public function isProjectCode() { |
| return in_array('projectcode', $this->keywords); |
| } |
| |
| public function isThirdParty() { |
| return in_array('thirdparty', $this->keywords); |
| } |
| |
| function asArray() { |
| return $this->data; |
| } |
| |
| function addFilePattern($value) { |
| if (preg_match('/(\S*\/)?([\w\.\-]+)[_-]((?:\d+\.){3})(.*\.)?jar/', $value, $matches)) { |
| $pattern = $matches[1] . $matches[2] . '_' . $matches[3]; |
| $regex = $matches[1] . $matches[2] . '[_-]' . $matches[3]; |
| $regex = str_replace('.', '\.', $regex); |
| $regex = str_replace('/', '\/', $regex); |
| $regex = $regex . '(.*\.)?jar'; |
| $pattern = "$pattern*.jar"; |
| |
| $this->data['filePatterns'][$pattern] = $regex; |
| |
| // Only generate a source bundle mapping if this isn't a source bundle. |
| if (!preg_match('/\.source$/', $matches[2])) { |
| $sourcePattern = $matches[1] . $matches[2]. '.source_' . $matches[3]; |
| $sourceRegex = $matches[1] . $matches[2] . '.source[_-]' . $matches[3]; |
| $sourceRegex = str_replace('.', '\.', $sourceRegex); |
| $regex = str_replace('/', '\/', $regex); |
| $sourceRegex = $sourceRegex . '(.*\.)?jar'; |
| $sourcePattern = "$sourcePattern*.jar"; |
| |
| $this->data['filePatterns'][$pattern] = $regex; |
| } |
| } else { |
| $pattern = $value; |
| $regex = str_replace('.', '\.', $pattern); |
| $regex = str_replace('/', '\/', $regex); |
| |
| $this->data['filePatterns'][$pattern] = $regex; |
| } |
| } |
| |
| function addMvnPattern($value) { |
| if (isset($this->data['mvnPatterns']) && in_array($value, $this->data['mvnPatterns'])) return; |
| $this->data['mvnPatterns'][] = $value; |
| } |
| } |
| |
| class RecursiveAncestryException extends Exception {} |
| ?> |