FOSSology  4.4.0
Open Source License Compliance by Open Source Software
HighlightProcessor.php
1 <?php
2 /*
3  SPDX-FileCopyrightText: © 2014 Siemens AG
4  Authors: Andreas Würl, Steffen Weber
5 
6  SPDX-License-Identifier: GPL-2.0-only
7 */
8 
9 namespace Fossology\Lib\View;
10 
15 
17 {
18  const LEVEL = 'level';
19  const ACTION = 'action';
20  const ENTRY = 'entry';
21  const REF_TEXT_MAX_LENGTH = 100;
22 
24  private $licenseDao;
25 
26  public function __construct(LicenseDao $licenseDao)
27  {
28  $this->licenseDao = $licenseDao;
29  }
30 
35  public function addReferenceTexts(&$highlights, $groupId=null)
36  {
37  $licenses = array();
38  foreach ($highlights as &$highlight) {
39  if ($highlight->hasLicenseId()) {
40  $licenseId = $highlight->getLicenseId();
41 
42  if (!array_key_exists($licenseId, $licenses)) {
43  $licenses[$licenseId] = $this->licenseDao->getLicenseById($licenseId, $groupId);
44  }
48  $license = $licenses[$licenseId];
49  $licenseReferenceText = ": '" . $this->getReferenceText($license, $highlight) . "'";
50  $includeReferenceText = $highlight->getType() != Highlight::MATCH && $highlight->getRefLength() > 0;
51  $infoText = $license->getShortName() . ($includeReferenceText ? $licenseReferenceText : "");
52  $highlight->setInfoText($infoText);
53  }
54  }
55  }
56 
62  protected function getReferenceText(License $license, Highlight $highlight)
63  {
64  $referenceText = substr($license->getText(), $highlight->getRefStart(), min($highlight->getRefLength(), self::REF_TEXT_MAX_LENGTH));
65  return $referenceText . ($highlight->getRefLength() > self::REF_TEXT_MAX_LENGTH ? " ... " : "");
66  }
67 
68 
73  public function calculateSplitPositions($highlights)
74  {
75  if (empty($highlights)) {
76  return array();
77  }
78  $this->sortHighlights($highlights);
79 
80  $splitPositions = $this->getSplitPositions($highlights);
81 
82  $this->filterMultipleAtomEntries($splitPositions);
83 
84  $this->sortSplitPositionEntries($splitPositions);
85 
86  return $splitPositions;
87  }
88 
93  public function flattenHighlights(&$highlights, $excludedTypes=array())
94  {
95  $excludedTypesSet = array();
96  foreach ($excludedTypes as $type) {
97  $excludedTypesSet[$type] = $type;
98  }
99 
100  $highlights = array_unique($highlights, SORT_REGULAR);
101  $this->sortHighlights($highlights);
102 
103  $currentPosition = 0;
105  foreach ($highlights as $key => $highlight) {
106  $isExcludedType = array_key_exists($highlight->getType(), $excludedTypesSet);
107  if ($isExcludedType) {
108  continue;
109  }
110  if ($highlight->getEnd() > $currentPosition) {
111  $startPosition = max($highlight->getStart(), $currentPosition);
112  $highlights[$key] = new Highlight($startPosition, $highlight->getEnd(), "any", $highlight->getRefStart(), $highlight->getRefEnd(), $highlight->getInfoText());
113  $currentPosition = $highlight->getEnd();
114  } else {
115  unset($highlights[$key]);
116  }
117  }
118  }
119 
123  public function sortHighlights(&$highlights)
124  {
125  if (isset($highlights)) {
126  usort($highlights, array(get_class($this), 'startAndLengthFirstSorter'));
127  }
128  }
129 
134  private function getSplitPositions($highlightInfos)
135  {
136  $splitPositions = array();
137  $level = 0;
138  do {
139  $this->addHighlightingLayer($highlightInfos, $splitPositions, $level++);
140  } while (!empty($highlightInfos));
141 
142  return $splitPositions;
143  }
144 
151  private function addHighlightingLayer(&$highlightEntries, &$splitPositions, $level)
152  {
153  $currentPosition = 0;
154  foreach ($highlightEntries as $key => &$highlightEntry) {
155  $start = $highlightEntry->getStart();
156  $end = $highlightEntry->getEnd();
157 
158  if ($start >= $currentPosition) {
159  $this->addAllSplitPositions($splitPositions, $level, $highlightEntry);
160 
161  ksort($splitPositions);
162  $currentPosition = $end;
163 
164  unset($highlightEntries[$key]);
165  }
166  }
167  }
168 
169 
176  private function addAllSplitPositions(&$splitPositions, $level, $highlightEntry)
177  {
178  $start = $highlightEntry->getStart();
179  $end = $highlightEntry->getEnd();
180 
181  $splitStart = $start;
182  foreach ($splitPositions as $splitPosition => $dummy) {
183  if ($start < $splitPosition && $splitPosition < $end) {
184  $this->addSingleSectionSplitPositions($splitPositions, $splitStart, $splitPosition, $level, $highlightEntry);
185  $splitStart = $splitPosition;
186  }
187  }
188  $this->addSingleSectionSplitPositions($splitPositions, $splitStart, $end, $level, $highlightEntry);
189  }
190 
198  private function addSingleSectionSplitPositions(&$splitPositions, $start, $end,
199  $level, $highlightEntry)
200  {
201  if ($start == $end) {
202  $splitPositions[$start][] = new SplitPosition($level, SplitPosition::ATOM, $highlightEntry);
203  } else {
204  $splitPositions[$start][] = new SplitPosition($level, SplitPosition::START, $highlightEntry);
205  $splitPositions[$end][] = new SplitPosition($level, SplitPosition::END, $highlightEntry);
206  }
207  }
208 
213  {
214  if ($a->getStart() < $b->getStart()) {
215  return - 1;
216  } else if ($a->getStart() > $b->getStart()) {
217  return 1;
218  } else if ($a->getEnd() > $b->getEnd()) {
219  return -1;
220  }
221  return ($a->getEnd() == $b->getEnd()) ? 0 : 1;
222  }
223 
224  private function splitPositionEntrySorter(SplitPosition $a, SplitPosition $b)
225  {
226  $leftAction = $a->getAction();
227  $rightAction = $b->getAction();
228  $leftAction = $leftAction == SplitPosition::ATOM ? SplitPosition::START : $leftAction;
229  $rightAction = $rightAction == SplitPosition::ATOM ? SplitPosition::START : $rightAction;
230 
231  if ($leftAction != $rightAction) {
232  return strcasecmp($leftAction, $rightAction);
233  } else {
234  return ($leftAction == SplitPosition::START ? 1 : -1) * $this->compare($a->getLevel(), $b->getLevel());
235  }
236  }
237 
238  private function compare($a, $b)
239  {
240  if ($a == $b) {
241  return 0;
242  }
243  return ($a < $b) ? -1 : 1;
244  }
245 
249  private function filterMultipleAtomEntries(&$splitPositions)
250  {
251  foreach ($splitPositions as &$splitPositionEntries) {
252  $atomFound = false;
253 
254  foreach ($splitPositionEntries as $key => $entry) {
258  if ($entry->getAction() == SplitPosition::ATOM) {
259  if ($atomFound) {
260  unset($splitPositionEntries[$key]);
261  } else {
262  $atomFound = true;
263  }
264  }
265  }
266  }
267  unset($splitPositionEntries);
268  }
269 
274  private function sortSplitPositionEntries(&$splitPositions)
275  {
276  foreach ($splitPositions as &$splitPositionEntries) {
277  usort($splitPositionEntries, array(get_class($this), 'splitPositionEntrySorter'));
278  }
279  unset($splitPositionEntries);
280  }
281 }
addAllSplitPositions(&$splitPositions, $level, $highlightEntry)
startAndLengthFirstSorter(Highlight $a, Highlight $b)
getReferenceText(License $license, Highlight $highlight)
flattenHighlights(&$highlights, $excludedTypes=array())
addSingleSectionSplitPositions(&$splitPositions, $start, $end, $level, $highlightEntry)
addHighlightingLayer(&$highlightEntries, &$splitPositions, $level)
FUNCTION int max(int permGroup, int permPublic)
Get the maximum group privilege.
Definition: libfossagent.c:295
FUNCTION int min(int user_perm, int permExternal)
Get the minimum permission level required.
Definition: libfossagent.c:306