FOSSology  3.2.0rc1
Open Source License Compliance by Open Source Software
HighlightProcessor.php
1 <?php
2 /*
3 Copyright (C) 2014, Siemens AG
4 Authors: Andreas Würl, Steffen Weber
5 
6 This program is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License
8 version 2 as published by the Free Software Foundation.
9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
19 
20 namespace Fossology\Lib\View;
21 
26 
28 {
29  const LEVEL = 'level';
30  const ACTION = 'action';
31  const ENTRY = 'entry';
32  const REF_TEXT_MAX_LENGTH = 100;
33 
35  private $licenseDao;
36 
37  public function __construct(LicenseDao $licenseDao)
38  {
39  $this->licenseDao = $licenseDao;
40  }
41 
46  public function addReferenceTexts(&$highlights, $groupId=null)
47  {
48  $licenses = array();
49  foreach ($highlights as &$highlight) {
50  if ($highlight->hasLicenseId()) {
51  $licenseId = $highlight->getLicenseId();
52 
53  if (!array_key_exists($licenseId, $licenses)) {
54  $licenses[$licenseId] = $this->licenseDao->getLicenseById($licenseId, $groupId);
55  }
59  $license = $licenses[$licenseId];
60  $licenseReferenceText = ": '" . $this->getReferenceText($license, $highlight) . "'";
61  $includeReferenceText = $highlight->getType() != Highlight::MATCH && $highlight->getRefLength() > 0;
62  $infoText = $license->getShortName() . ($includeReferenceText ? $licenseReferenceText : "");
63  $highlight->setInfoText($infoText);
64  }
65  }
66  }
67 
73  protected function getReferenceText(License $license, Highlight $highlight)
74  {
75  $referenceText = substr($license->getText(), $highlight->getRefStart(), min($highlight->getRefLength(), self::REF_TEXT_MAX_LENGTH));
76  return $referenceText . ($highlight->getRefLength() > self::REF_TEXT_MAX_LENGTH ? " ... " : "");
77  }
78 
79 
84  public function calculateSplitPositions($highlights)
85  {
86  if (empty($highlights)) {
87  return array();
88  }
89  $this->sortHighlights($highlights);
90 
91  $splitPositions = $this->getSplitPositions($highlights);
92 
93  $this->filterMultipleAtomEntries($splitPositions);
94 
95  $this->sortSplitPositionEntries($splitPositions);
96 
97  return $splitPositions;
98  }
99 
104  public function flattenHighlights(&$highlights, $excludedTypes=array())
105  {
106  $excludedTypesSet = array();
107  foreach ($excludedTypes as $type) {
108  $excludedTypesSet[$type] = $type;
109  }
110 
111  $highlights = array_unique($highlights, SORT_REGULAR);
112  $this->sortHighlights($highlights);
113 
114  $currentPosition = 0;
116  foreach ($highlights as $key => $highlight) {
117  $isExcludedType = array_key_exists($highlight->getType(), $excludedTypesSet);
118  if ($isExcludedType) {
119  continue;
120  }
121  if ($highlight->getEnd() > $currentPosition) {
122  $startPosition = max($highlight->getStart(), $currentPosition);
123  $highlights[$key] = new Highlight($startPosition, $highlight->getEnd(), "any", $highlight->getRefStart(), $highlight->getRefEnd(), $highlight->getInfoText());
124  $currentPosition = $highlight->getEnd();
125  } else {
126  unset($highlights[$key]);
127  }
128  }
129  }
130 
134  public function sortHighlights(&$highlights)
135  {
136  if (isset($highlights)) {
137  usort($highlights, array(get_class($this), 'startAndLengthFirstSorter'));
138  }
139  }
140 
145  private function getSplitPositions($highlightInfos)
146  {
147  $splitPositions = array();
148  $level = 0;
149  do {
150  $this->addHighlightingLayer($highlightInfos, $splitPositions, $level++);
151  } while (!empty($highlightInfos));
152 
153  return $splitPositions;
154  }
155 
162  private function addHighlightingLayer(&$highlightEntries, &$splitPositions, $level)
163  {
164  $currentPosition = 0;
165  foreach ($highlightEntries as $key => &$highlightEntry) {
166  $start = $highlightEntry->getStart();
167  $end = $highlightEntry->getEnd();
168 
169  if ($start >= $currentPosition) {
170  $this->addAllSplitPositions($splitPositions, $level, $highlightEntry);
171 
172  ksort($splitPositions);
173  $currentPosition = $end;
174 
175  unset($highlightEntries[$key]);
176  }
177  }
178  }
179 
180 
187  private function addAllSplitPositions(&$splitPositions, $level, $highlightEntry)
188  {
189  $start = $highlightEntry->getStart();
190  $end = $highlightEntry->getEnd();
191 
192  $splitStart = $start;
193  foreach ($splitPositions as $splitPosition => $dummy) {
194  if ($start < $splitPosition && $splitPosition < $end) {
195  $this->addSingleSectionSplitPositions($splitPositions, $splitStart, $splitPosition, $level, $highlightEntry);
196  $splitStart = $splitPosition;
197  }
198  }
199  $this->addSingleSectionSplitPositions($splitPositions, $splitStart, $end, $level, $highlightEntry);
200  }
201 
209  private function addSingleSectionSplitPositions(&$splitPositions, $start, $end,
210  $level, $highlightEntry)
211  {
212  if ($start == $end) {
213  $splitPositions[$start][] = new SplitPosition($level, SplitPosition::ATOM, $highlightEntry);
214  } else {
215  $splitPositions[$start][] = new SplitPosition($level, SplitPosition::START, $highlightEntry);
216  $splitPositions[$end][] = new SplitPosition($level, SplitPosition::END, $highlightEntry);
217  }
218  }
219 
224  {
225  if ($a->getStart() < $b->getStart()) {
226  return - 1;
227  } else if ($a->getStart() > $b->getStart()) {
228  return 1;
229  } else if ($a->getEnd() > $b->getEnd()) {
230  return -1;
231  }
232  return ($a->getEnd() == $b->getEnd()) ? 0 : 1;
233  }
234 
235  private function splitPositionEntrySorter(SplitPosition $a, SplitPosition $b)
236  {
237  $leftAction = $a->getAction();
238  $rightAction = $b->getAction();
239  $leftAction = $leftAction == SplitPosition::ATOM ? SplitPosition::START : $leftAction;
240  $rightAction = $rightAction == SplitPosition::ATOM ? SplitPosition::START : $rightAction;
241 
242  if ($leftAction != $rightAction) {
243  return strcasecmp($leftAction, $rightAction);
244  } else {
245  return ($leftAction == SplitPosition::START ? 1 : -1) * $this->compare($a->getLevel(), $b->getLevel());
246  }
247  }
248 
249  private function compare($a, $b)
250  {
251  if ($a == $b) {
252  return 0;
253  }
254  return ($a < $b) ? -1 : 1;
255  }
256 
260  private function filterMultipleAtomEntries(&$splitPositions)
261  {
262  foreach ($splitPositions as &$splitPositionEntries) {
263  $atomFound = false;
264 
265  foreach ($splitPositionEntries as $key => $entry) {
269  if ($entry->getAction() == SplitPosition::ATOM) {
270  if ($atomFound) {
271  unset($splitPositionEntries[$key]);
272  } else {
273  $atomFound = true;
274  }
275  }
276  }
277  }
278  unset($splitPositionEntries);
279  }
280 
285  private function sortSplitPositionEntries(&$splitPositions)
286  {
287  foreach ($splitPositions as &$splitPositionEntries) {
288  usort($splitPositionEntries, array(get_class($this), 'splitPositionEntrySorter'));
289  }
290  unset($splitPositionEntries);
291  }
292 }
flattenHighlights(&$highlights, $excludedTypes=array())
addAllSplitPositions(&$splitPositions, $level, $highlightEntry)
FUNCTION int min(int user_perm, int permExternal)
Get the minimum permission level required.
Definition: libfossagent.c:320
getReferenceText(License $license, Highlight $highlight)
addHighlightingLayer(&$highlightEntries, &$splitPositions, $level)
startAndLengthFirstSorter(Highlight $a, Highlight $b)
addSingleSectionSplitPositions(&$splitPositions, $start, $end, $level, $highlightEntry)
FUNCTION int max(int permGroup, int permPublic)
Get the maximum group privilege.
Definition: libfossagent.c:309